| 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 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 void LCodeGen::DoConstantI(LConstantI* instr) { | 881 void LCodeGen::DoConstantI(LConstantI* instr) { |
| 882 ASSERT(instr->result()->IsRegister()); | 882 ASSERT(instr->result()->IsRegister()); |
| 883 __ movl(ToRegister(instr->result()), Immediate(instr->value())); | 883 __ movl(ToRegister(instr->result()), Immediate(instr->value())); |
| 884 } | 884 } |
| 885 | 885 |
| 886 | 886 |
| 887 void LCodeGen::DoConstantD(LConstantD* instr) { | 887 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 888 ASSERT(instr->result()->IsDoubleRegister()); | 888 ASSERT(instr->result()->IsDoubleRegister()); |
| 889 XMMRegister res = ToDoubleRegister(instr->result()); | 889 XMMRegister res = ToDoubleRegister(instr->result()); |
| 890 double v = instr->value(); | 890 double v = instr->value(); |
| 891 uint64_t int_val = BitCast<uint64_t, double>(v); |
| 891 // Use xor to produce +0.0 in a fast and compact way, but avoid to | 892 // Use xor to produce +0.0 in a fast and compact way, but avoid to |
| 892 // do so if the constant is -0.0. | 893 // do so if the constant is -0.0. |
| 893 if (BitCast<uint64_t, double>(v) == 0) { | 894 if (int_val == 0) { |
| 894 __ xorpd(res, res); | 895 __ xorpd(res, res); |
| 895 } else { | 896 } else { |
| 896 Register tmp = ToRegister(instr->TempAt(0)); | 897 Register tmp = ToRegister(instr->TempAt(0)); |
| 897 int32_t v_int32 = static_cast<int32_t>(v); | 898 __ Set(tmp, int_val); |
| 898 if (static_cast<double>(v_int32) == v) { | 899 __ movq(res, tmp); |
| 899 __ movl(tmp, Immediate(v_int32)); | |
| 900 __ cvtlsi2sd(res, tmp); | |
| 901 } else { | |
| 902 uint64_t int_val = BitCast<uint64_t, double>(v); | |
| 903 __ Set(tmp, int_val); | |
| 904 __ movd(res, tmp); | |
| 905 } | |
| 906 } | 900 } |
| 907 } | 901 } |
| 908 | 902 |
| 909 | 903 |
| 910 void LCodeGen::DoConstantT(LConstantT* instr) { | 904 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 911 ASSERT(instr->result()->IsRegister()); | 905 ASSERT(instr->result()->IsRegister()); |
| 912 __ Move(ToRegister(instr->result()), instr->value()); | 906 __ Move(ToRegister(instr->result()), instr->value()); |
| 913 } | 907 } |
| 914 | 908 |
| 915 | 909 |
| (...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1790 | 1784 |
| 1791 void LCodeGen::DoLoadPixelArrayExternalPointer( | 1785 void LCodeGen::DoLoadPixelArrayExternalPointer( |
| 1792 LLoadPixelArrayExternalPointer* instr) { | 1786 LLoadPixelArrayExternalPointer* instr) { |
| 1793 Register result = ToRegister(instr->result()); | 1787 Register result = ToRegister(instr->result()); |
| 1794 Register input = ToRegister(instr->InputAt(0)); | 1788 Register input = ToRegister(instr->InputAt(0)); |
| 1795 __ movq(result, FieldOperand(input, PixelArray::kExternalPointerOffset)); | 1789 __ movq(result, FieldOperand(input, PixelArray::kExternalPointerOffset)); |
| 1796 } | 1790 } |
| 1797 | 1791 |
| 1798 | 1792 |
| 1799 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 1793 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
| 1800 Abort("Unimplemented: %s", "DoAccessArgumentsAt"); | 1794 Register arguments = ToRegister(instr->arguments()); |
| 1795 Register length = ToRegister(instr->length()); |
| 1796 Register result = ToRegister(instr->result()); |
| 1797 |
| 1798 if (instr->index()->IsRegister()) { |
| 1799 __ subl(length, ToRegister(instr->index())); |
| 1800 } else { |
| 1801 __ subl(length, ToOperand(instr->index())); |
| 1802 } |
| 1803 DeoptimizeIf(below_equal, instr->environment()); |
| 1804 |
| 1805 // There are two words between the frame pointer and the last argument. |
| 1806 // Subtracting from length accounts for one of them add one more. |
| 1807 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); |
| 1801 } | 1808 } |
| 1802 | 1809 |
| 1803 | 1810 |
| 1804 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 1811 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
| 1805 Register elements = ToRegister(instr->elements()); | 1812 Register elements = ToRegister(instr->elements()); |
| 1806 Register key = ToRegister(instr->key()); | 1813 Register key = ToRegister(instr->key()); |
| 1807 Register result = ToRegister(instr->result()); | 1814 Register result = ToRegister(instr->result()); |
| 1808 ASSERT(result.is(elements)); | 1815 ASSERT(result.is(elements)); |
| 1809 | 1816 |
| 1810 // Load the result. | 1817 // Load the result. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1829 __ movzxbq(result, Operand(external_elements, key, times_1, 0)); | 1836 __ movzxbq(result, Operand(external_elements, key, times_1, 0)); |
| 1830 } | 1837 } |
| 1831 | 1838 |
| 1832 | 1839 |
| 1833 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 1840 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 1834 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); | 1841 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); |
| 1835 } | 1842 } |
| 1836 | 1843 |
| 1837 | 1844 |
| 1838 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 1845 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
| 1839 Abort("Unimplemented: %s", "DoArgumentsElements"); | 1846 Register result = ToRegister(instr->result()); |
| 1847 |
| 1848 // Check for arguments adapter frame. |
| 1849 NearLabel done, adapted; |
| 1850 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 1851 __ SmiCompare(Operand(result, StandardFrameConstants::kContextOffset), |
| 1852 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 1853 __ j(equal, &adapted); |
| 1854 |
| 1855 // No arguments adaptor frame. |
| 1856 __ movq(result, rbp); |
| 1857 __ jmp(&done); |
| 1858 |
| 1859 // Arguments adaptor frame present. |
| 1860 __ bind(&adapted); |
| 1861 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 1862 |
| 1863 // Result is the frame pointer for the frame if not adapted and for the real |
| 1864 // frame below the adaptor frame if adapted. |
| 1865 __ bind(&done); |
| 1840 } | 1866 } |
| 1841 | 1867 |
| 1842 | 1868 |
| 1843 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { | 1869 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { |
| 1844 Abort("Unimplemented: %s", "DoArgumentsLength"); | 1870 Register result = ToRegister(instr->result()); |
| 1871 |
| 1872 NearLabel done; |
| 1873 |
| 1874 // If no arguments adaptor frame the number of arguments is fixed. |
| 1875 if (instr->InputAt(0)->IsRegister()) { |
| 1876 __ cmpq(rbp, ToRegister(instr->InputAt(0))); |
| 1877 } else { |
| 1878 __ cmpq(rbp, ToOperand(instr->InputAt(0))); |
| 1879 } |
| 1880 __ movq(result, Immediate(scope()->num_parameters())); |
| 1881 __ j(equal, &done); |
| 1882 |
| 1883 // Arguments adaptor frame present. Get argument length from there. |
| 1884 __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 1885 __ movq(result, Operand(result, |
| 1886 ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 1887 __ SmiToInteger32(result, result); |
| 1888 |
| 1889 // Argument length is in result register. |
| 1890 __ bind(&done); |
| 1845 } | 1891 } |
| 1846 | 1892 |
| 1847 | 1893 |
| 1848 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 1894 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
| 1849 Abort("Unimplemented: %s", "DoApplyArguments"); | 1895 Abort("Unimplemented: %s", "DoApplyArguments"); |
| 1850 } | 1896 } |
| 1851 | 1897 |
| 1852 | 1898 |
| 1853 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 1899 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
| 1854 LOperand* argument = instr->InputAt(0); | 1900 LOperand* argument = instr->InputAt(0); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 __ RecordWrite(elements, key, value); | 2164 __ RecordWrite(elements, key, value); |
| 2119 } | 2165 } |
| 2120 } | 2166 } |
| 2121 | 2167 |
| 2122 | 2168 |
| 2123 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 2169 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 2124 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); | 2170 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); |
| 2125 } | 2171 } |
| 2126 | 2172 |
| 2127 | 2173 |
| 2174 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 2175 Register string = ToRegister(instr->string()); |
| 2176 Register result = ToRegister(instr->result()); |
| 2177 __ movq(result, FieldOperand(string, String::kLengthOffset)); |
| 2178 } |
| 2179 |
| 2180 |
| 2128 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 2181 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 2129 LOperand* input = instr->InputAt(0); | 2182 LOperand* input = instr->InputAt(0); |
| 2130 ASSERT(input->IsRegister() || input->IsStackSlot()); | 2183 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 2131 LOperand* output = instr->result(); | 2184 LOperand* output = instr->result(); |
| 2132 ASSERT(output->IsDoubleRegister()); | 2185 ASSERT(output->IsDoubleRegister()); |
| 2133 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); | 2186 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); |
| 2134 } | 2187 } |
| 2135 | 2188 |
| 2136 | 2189 |
| 2137 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 2190 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 __ divsd(result_reg, result_reg); | 2279 __ divsd(result_reg, result_reg); |
| 2227 __ jmp(&done); | 2280 __ jmp(&done); |
| 2228 | 2281 |
| 2229 // Heap number to XMM conversion. | 2282 // Heap number to XMM conversion. |
| 2230 __ bind(&heap_number); | 2283 __ bind(&heap_number); |
| 2231 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 2284 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 2232 __ jmp(&done); | 2285 __ jmp(&done); |
| 2233 | 2286 |
| 2234 // Smi to XMM conversion | 2287 // Smi to XMM conversion |
| 2235 __ bind(&load_smi); | 2288 __ bind(&load_smi); |
| 2236 __ SmiToInteger32(kScratchRegister, input_reg); // Untag smi first. | 2289 __ SmiToInteger32(kScratchRegister, input_reg); |
| 2237 __ cvtlsi2sd(result_reg, kScratchRegister); | 2290 __ cvtlsi2sd(result_reg, kScratchRegister); |
| 2238 __ bind(&done); | 2291 __ bind(&done); |
| 2239 } | 2292 } |
| 2240 | 2293 |
| 2241 | 2294 |
| 2242 class DeferredTaggedToI: public LDeferredCode { | 2295 class DeferredTaggedToI: public LDeferredCode { |
| 2243 public: | 2296 public: |
| 2244 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 2297 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
| 2245 : LDeferredCode(codegen), instr_(instr) { } | 2298 : LDeferredCode(codegen), instr_(instr) { } |
| 2246 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } | 2299 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 | 2356 |
| 2304 Register input_reg = ToRegister(input); | 2357 Register input_reg = ToRegister(input); |
| 2305 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); | 2358 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); |
| 2306 __ JumpIfNotSmi(input_reg, deferred->entry()); | 2359 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 2307 __ SmiToInteger32(input_reg, input_reg); | 2360 __ SmiToInteger32(input_reg, input_reg); |
| 2308 __ bind(deferred->exit()); | 2361 __ bind(deferred->exit()); |
| 2309 } | 2362 } |
| 2310 | 2363 |
| 2311 | 2364 |
| 2312 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { | 2365 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
| 2313 Abort("Unimplemented: %s", "DoNumberUntagD"); | 2366 LOperand* input = instr->InputAt(0); |
| 2367 ASSERT(input->IsRegister()); |
| 2368 LOperand* result = instr->result(); |
| 2369 ASSERT(result->IsDoubleRegister()); |
| 2370 |
| 2371 Register input_reg = ToRegister(input); |
| 2372 XMMRegister result_reg = ToDoubleRegister(result); |
| 2373 |
| 2374 EmitNumberUntagD(input_reg, result_reg, instr->environment()); |
| 2314 } | 2375 } |
| 2315 | 2376 |
| 2316 | 2377 |
| 2317 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 2378 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
| 2318 Abort("Unimplemented: %s", "DoDoubleToI"); | 2379 Abort("Unimplemented: %s", "DoDoubleToI"); |
| 2319 } | 2380 } |
| 2320 | 2381 |
| 2321 | 2382 |
| 2322 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 2383 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 2323 LOperand* input = instr->InputAt(0); | 2384 LOperand* input = instr->InputAt(0); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2654 | 2715 |
| 2655 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 2716 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
| 2656 Abort("Unimplemented: %s", "DoOsrEntry"); | 2717 Abort("Unimplemented: %s", "DoOsrEntry"); |
| 2657 } | 2718 } |
| 2658 | 2719 |
| 2659 #undef __ | 2720 #undef __ |
| 2660 | 2721 |
| 2661 } } // namespace v8::internal | 2722 } } // namespace v8::internal |
| 2662 | 2723 |
| 2663 #endif // V8_TARGET_ARCH_X64 | 2724 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |