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 |