Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 889 XMMRegister res = ToDoubleRegister(instr->result()); | 889 XMMRegister res = ToDoubleRegister(instr->result()); |
| 890 double v = instr->value(); | 890 double v = instr->value(); |
| 891 // Use xor to produce +0.0 in a fast and compact way, but avoid to | 891 // Use xor to produce +0.0 in a fast and compact way, but avoid to |
| 892 // do so if the constant is -0.0. | 892 // do so if the constant is -0.0. |
| 893 if (BitCast<uint64_t, double>(v) == 0) { | 893 if (BitCast<uint64_t, double>(v) == 0) { |
| 894 __ xorpd(res, res); | 894 __ xorpd(res, res); |
| 895 } else { | 895 } else { |
| 896 Register tmp = ToRegister(instr->TempAt(0)); | 896 Register tmp = ToRegister(instr->TempAt(0)); |
| 897 int32_t v_int32 = static_cast<int32_t>(v); | 897 int32_t v_int32 = static_cast<int32_t>(v); |
| 898 if (static_cast<double>(v_int32) == v) { | 898 if (static_cast<double>(v_int32) == v) { |
| 899 __ movl(tmp, Immediate(v_int32)); | 899 __ movl(tmp, Immediate(v_int32)); |
|
William Hesse
2011/02/14 11:39:25
This integer-to-double conversion is slower than j
Mads Ager (chromium)
2011/02/14 12:07:14
Done.
| |
| 900 __ cvtlsi2sd(res, tmp); | 900 __ cvtlsi2sd(res, tmp); |
| 901 } else { | 901 } else { |
| 902 uint64_t int_val = BitCast<uint64_t, double>(v); | 902 uint64_t int_val = BitCast<uint64_t, double>(v); |
| 903 __ Set(tmp, int_val); | 903 __ Set(tmp, int_val); |
| 904 __ movd(res, tmp); | 904 __ movq(res, tmp); |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 } | 907 } |
| 908 | 908 |
| 909 | 909 |
| 910 void LCodeGen::DoConstantT(LConstantT* instr) { | 910 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 911 ASSERT(instr->result()->IsRegister()); | 911 ASSERT(instr->result()->IsRegister()); |
| 912 __ Move(ToRegister(instr->result()), instr->value()); | 912 __ Move(ToRegister(instr->result()), instr->value()); |
| 913 } | 913 } |
| 914 | 914 |
| (...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1790 | 1790 |
| 1791 void LCodeGen::DoLoadPixelArrayExternalPointer( | 1791 void LCodeGen::DoLoadPixelArrayExternalPointer( |
| 1792 LLoadPixelArrayExternalPointer* instr) { | 1792 LLoadPixelArrayExternalPointer* instr) { |
| 1793 Register result = ToRegister(instr->result()); | 1793 Register result = ToRegister(instr->result()); |
| 1794 Register input = ToRegister(instr->InputAt(0)); | 1794 Register input = ToRegister(instr->InputAt(0)); |
| 1795 __ movq(result, FieldOperand(input, PixelArray::kExternalPointerOffset)); | 1795 __ movq(result, FieldOperand(input, PixelArray::kExternalPointerOffset)); |
| 1796 } | 1796 } |
| 1797 | 1797 |
| 1798 | 1798 |
| 1799 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 1799 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
| 1800 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); | 1800 Register arguments = ToRegister(instr->arguments()); |
| 1801 Register length = ToRegister(instr->length()); | |
| 1802 Register result = ToRegister(instr->result()); | |
| 1803 | |
| 1804 if (instr->index()->IsRegister()) { | |
| 1805 __ subl(length, ToRegister(instr->index())); | |
| 1806 } else { | |
| 1807 __ subl(length, ToOperand(instr->index())); | |
| 1808 } | |
| 1809 DeoptimizeIf(below_equal, instr->environment()); | |
| 1810 | |
| 1811 // There are two words between the frame pointer and the last argument. | |
| 1812 // Subtracting from length accounts for one of them add one more. | |
| 1813 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); | |
| 1801 } | 1814 } |
| 1802 | 1815 |
| 1803 | 1816 |
| 1804 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 1817 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
| 1805 Register elements = ToRegister(instr->elements()); | 1818 Register elements = ToRegister(instr->elements()); |
| 1806 Register key = ToRegister(instr->key()); | 1819 Register key = ToRegister(instr->key()); |
| 1807 Register result = ToRegister(instr->result()); | 1820 Register result = ToRegister(instr->result()); |
| 1808 ASSERT(result.is(elements)); | 1821 ASSERT(result.is(elements)); |
| 1809 | 1822 |
| 1810 // Load the result. | 1823 // Load the result. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1829 __ movzxbq(result, Operand(external_elements, key, times_1, 0)); | 1842 __ movzxbq(result, Operand(external_elements, key, times_1, 0)); |
| 1830 } | 1843 } |
| 1831 | 1844 |
| 1832 | 1845 |
| 1833 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 1846 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 1834 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); | 1847 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); |
| 1835 } | 1848 } |
| 1836 | 1849 |
| 1837 | 1850 |
| 1838 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 1851 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
| 1839 Abort("Unimplemented: %s", "DoArgumentsElements"); | 1852 Register result = ToRegister(instr->result()); |
| 1853 | |
| 1854 // Check for arguments adapter frame. | |
| 1855 NearLabel done, adapted; | |
| 1856 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | |
| 1857 __ SmiCompare(Operand(result, StandardFrameConstants::kContextOffset), | |
| 1858 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | |
| 1859 __ j(equal, &adapted); | |
| 1860 | |
| 1861 // No arguments adaptor frame. | |
| 1862 __ movq(result, rbp); | |
| 1863 __ jmp(&done); | |
| 1864 | |
| 1865 // Arguments adaptor frame present. | |
| 1866 __ bind(&adapted); | |
| 1867 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | |
| 1868 | |
| 1869 // Result is the frame pointer for the frame if not adapted and for the real | |
| 1870 // frame below the adaptor frame if adapted. | |
| 1871 __ bind(&done); | |
| 1840 } | 1872 } |
| 1841 | 1873 |
| 1842 | 1874 |
| 1843 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { | 1875 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { |
| 1844 Abort("Unimplemented: %s", "DoArgumentsLength"); | 1876 Register result = ToRegister(instr->result()); |
| 1877 | |
| 1878 NearLabel done; | |
| 1879 | |
| 1880 // If no arguments adaptor frame the number of arguments is fixed. | |
| 1881 if (instr->InputAt(0)->IsRegister()) { | |
| 1882 __ cmpq(rbp, ToRegister(instr->InputAt(0))); | |
| 1883 } else { | |
| 1884 __ cmpq(rbp, ToOperand(instr->InputAt(0))); | |
| 1885 } | |
| 1886 __ movq(result, Immediate(scope()->num_parameters())); | |
| 1887 __ j(equal, &done); | |
| 1888 | |
| 1889 // Arguments adaptor frame present. Get argument length from there. | |
| 1890 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | |
| 1891 __ movq(result, Operand(result, | |
| 1892 ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
| 1893 __ SmiToInteger32(result, result); | |
| 1894 | |
| 1895 // Argument length is in result register. | |
| 1896 __ bind(&done); | |
| 1845 } | 1897 } |
| 1846 | 1898 |
| 1847 | 1899 |
| 1848 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 1900 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
| 1849 Abort("Unimplemented: %s", "DoApplyArguments"); | 1901 Abort("Unimplemented: %s", "DoApplyArguments"); |
| 1850 } | 1902 } |
| 1851 | 1903 |
| 1852 | 1904 |
| 1853 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 1905 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
| 1854 LOperand* argument = instr->InputAt(0); | 1906 LOperand* argument = instr->InputAt(0); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2118 __ RecordWrite(elements, key, value); | 2170 __ RecordWrite(elements, key, value); |
| 2119 } | 2171 } |
| 2120 } | 2172 } |
| 2121 | 2173 |
| 2122 | 2174 |
| 2123 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 2175 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 2124 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); | 2176 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); |
| 2125 } | 2177 } |
| 2126 | 2178 |
| 2127 | 2179 |
| 2180 void LCodeGen::DoStringLength(LStringLength* instr) { | |
| 2181 Register string = ToRegister(instr->string()); | |
| 2182 Register result = ToRegister(instr->result()); | |
| 2183 __ movq(result, FieldOperand(string, String::kLengthOffset)); | |
| 2184 } | |
| 2185 | |
| 2186 | |
| 2128 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 2187 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 2129 LOperand* input = instr->InputAt(0); | 2188 LOperand* input = instr->InputAt(0); |
| 2130 ASSERT(input->IsRegister() || input->IsStackSlot()); | 2189 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 2131 LOperand* output = instr->result(); | 2190 LOperand* output = instr->result(); |
| 2132 ASSERT(output->IsDoubleRegister()); | 2191 ASSERT(output->IsDoubleRegister()); |
| 2133 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); | 2192 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); |
| 2134 } | 2193 } |
| 2135 | 2194 |
| 2136 | 2195 |
| 2137 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 2196 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2226 __ divsd(result_reg, result_reg); | 2285 __ divsd(result_reg, result_reg); |
| 2227 __ jmp(&done); | 2286 __ jmp(&done); |
| 2228 | 2287 |
| 2229 // Heap number to XMM conversion. | 2288 // Heap number to XMM conversion. |
| 2230 __ bind(&heap_number); | 2289 __ bind(&heap_number); |
| 2231 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 2290 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 2232 __ jmp(&done); | 2291 __ jmp(&done); |
| 2233 | 2292 |
| 2234 // Smi to XMM conversion | 2293 // Smi to XMM conversion |
| 2235 __ bind(&load_smi); | 2294 __ bind(&load_smi); |
| 2236 __ SmiToInteger32(kScratchRegister, input_reg); // Untag smi first. | 2295 __ SmiToInteger32(kScratchRegister, input_reg); |
| 2237 __ cvtlsi2sd(result_reg, kScratchRegister); | 2296 __ cvtlsi2sd(result_reg, kScratchRegister); |
| 2238 __ bind(&done); | 2297 __ bind(&done); |
| 2239 } | 2298 } |
| 2240 | 2299 |
| 2241 | 2300 |
| 2242 class DeferredTaggedToI: public LDeferredCode { | 2301 class DeferredTaggedToI: public LDeferredCode { |
| 2243 public: | 2302 public: |
| 2244 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 2303 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
| 2245 : LDeferredCode(codegen), instr_(instr) { } | 2304 : LDeferredCode(codegen), instr_(instr) { } |
| 2246 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } | 2305 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2303 | 2362 |
| 2304 Register input_reg = ToRegister(input); | 2363 Register input_reg = ToRegister(input); |
| 2305 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); | 2364 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); |
| 2306 __ JumpIfNotSmi(input_reg, deferred->entry()); | 2365 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 2307 __ SmiToInteger32(input_reg, input_reg); | 2366 __ SmiToInteger32(input_reg, input_reg); |
| 2308 __ bind(deferred->exit()); | 2367 __ bind(deferred->exit()); |
| 2309 } | 2368 } |
| 2310 | 2369 |
| 2311 | 2370 |
| 2312 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { | 2371 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
| 2313 Abort("Unimplemented: %s", "DoNumberUntagD"); | 2372 LOperand* input = instr->InputAt(0); |
| 2373 ASSERT(input->IsRegister()); | |
| 2374 LOperand* result = instr->result(); | |
| 2375 ASSERT(result->IsDoubleRegister()); | |
| 2376 | |
| 2377 Register input_reg = ToRegister(input); | |
| 2378 XMMRegister result_reg = ToDoubleRegister(result); | |
| 2379 | |
| 2380 EmitNumberUntagD(input_reg, result_reg, instr->environment()); | |
| 2314 } | 2381 } |
| 2315 | 2382 |
| 2316 | 2383 |
| 2317 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 2384 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
| 2318 Abort("Unimplemented: %s", "DoDoubleToI"); | 2385 Abort("Unimplemented: %s", "DoDoubleToI"); |
| 2319 } | 2386 } |
| 2320 | 2387 |
| 2321 | 2388 |
| 2322 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 2389 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 2323 LOperand* input = instr->InputAt(0); | 2390 LOperand* input = instr->InputAt(0); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2654 | 2721 |
| 2655 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 2722 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
| 2656 Abort("Unimplemented: %s", "DoOsrEntry"); | 2723 Abort("Unimplemented: %s", "DoOsrEntry"); |
| 2657 } | 2724 } |
| 2658 | 2725 |
| 2659 #undef __ | 2726 #undef __ |
| 2660 | 2727 |
| 2661 } } // namespace v8::internal | 2728 } } // namespace v8::internal |
| 2662 | 2729 |
| 2663 #endif // V8_TARGET_ARCH_X64 | 2730 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |