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 2134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2145 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 2145 void LCodeGen::DoLoadElements(LLoadElements* instr) { |
2146 Register result = ToRegister(instr->result()); | 2146 Register result = ToRegister(instr->result()); |
2147 Register input = ToRegister(instr->InputAt(0)); | 2147 Register input = ToRegister(instr->InputAt(0)); |
2148 __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); | 2148 __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); |
2149 if (FLAG_debug_code) { | 2149 if (FLAG_debug_code) { |
2150 NearLabel done; | 2150 NearLabel done; |
2151 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), | 2151 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), |
2152 Heap::kFixedArrayMapRootIndex); | 2152 Heap::kFixedArrayMapRootIndex); |
2153 __ j(equal, &done); | 2153 __ j(equal, &done); |
2154 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), | 2154 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), |
2155 Heap::kExternalPixelArrayMapRootIndex); | 2155 Heap::kFixedCOWArrayMapRootIndex); |
2156 __ j(equal, &done); | 2156 __ j(equal, &done); |
2157 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), | 2157 Register temp((result.is(rax)) ? rbx : rax); |
2158 Heap::kFixedCOWArrayMapRootIndex); | 2158 __ push(temp); |
2159 __ Check(equal, "Check for fast elements failed."); | 2159 __ movq(temp, FieldOperand(result, HeapObject::kMapOffset)); |
| 2160 __ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); |
| 2161 __ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE)); |
| 2162 __ cmpq(temp, Immediate(kExternalArrayTypeCount)); |
| 2163 __ pop(temp); |
| 2164 __ Check(below, "Check for fast elements failed."); |
2160 __ bind(&done); | 2165 __ bind(&done); |
2161 } | 2166 } |
2162 } | 2167 } |
2163 | 2168 |
2164 | 2169 |
2165 void LCodeGen::DoLoadExternalArrayPointer( | 2170 void LCodeGen::DoLoadExternalArrayPointer( |
2166 LLoadExternalArrayPointer* instr) { | 2171 LLoadExternalArrayPointer* instr) { |
2167 Register result = ToRegister(instr->result()); | 2172 Register result = ToRegister(instr->result()); |
2168 Register input = ToRegister(instr->InputAt(0)); | 2173 Register input = ToRegister(instr->InputAt(0)); |
2169 __ movq(result, FieldOperand(input, | 2174 __ movq(result, FieldOperand(input, |
(...skipping 30 matching lines...) Expand all Loading... |
2200 key, | 2205 key, |
2201 times_pointer_size, | 2206 times_pointer_size, |
2202 FixedArray::kHeaderSize)); | 2207 FixedArray::kHeaderSize)); |
2203 | 2208 |
2204 // Check for the hole value. | 2209 // Check for the hole value. |
2205 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 2210 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
2206 DeoptimizeIf(equal, instr->environment()); | 2211 DeoptimizeIf(equal, instr->environment()); |
2207 } | 2212 } |
2208 | 2213 |
2209 | 2214 |
2210 void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { | 2215 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2211 Register external_elements = ToRegister(instr->external_pointer()); | 2216 LLoadKeyedSpecializedArrayElement* instr) { |
| 2217 Register external_pointer = ToRegister(instr->external_pointer()); |
2212 Register key = ToRegister(instr->key()); | 2218 Register key = ToRegister(instr->key()); |
2213 Register result = ToRegister(instr->result()); | 2219 ExternalArrayType array_type = instr->array_type(); |
2214 ASSERT(result.is(external_elements)); | 2220 switch (array_type) { |
2215 | 2221 case kExternalByteArray: |
2216 // Load the result. | 2222 __ movsxbq(ToRegister(instr->result()), |
2217 __ movzxbq(result, Operand(external_elements, key, times_1, 0)); | 2223 Operand(external_pointer, key, times_1, 0)); |
| 2224 break; |
| 2225 case kExternalUnsignedByteArray: |
| 2226 case kExternalPixelArray: |
| 2227 __ movzxbq(ToRegister(instr->result()), |
| 2228 Operand(external_pointer, key, times_1, 0)); |
| 2229 break; |
| 2230 case kExternalShortArray: |
| 2231 __ movsxwq(ToRegister(instr->result()), |
| 2232 Operand(external_pointer, key, times_2, 0)); |
| 2233 break; |
| 2234 case kExternalUnsignedShortArray: |
| 2235 __ movzxwq(ToRegister(instr->result()), |
| 2236 Operand(external_pointer, key, times_2, 0)); |
| 2237 break; |
| 2238 case kExternalIntArray: |
| 2239 __ movsxlq(ToRegister(instr->result()), |
| 2240 Operand(external_pointer, key, times_4, 0)); |
| 2241 break; |
| 2242 case kExternalUnsignedIntArray: { |
| 2243 Register result(ToRegister(instr->result())); |
| 2244 __ movl(result, Operand(external_pointer, key, times_4, 0)); |
| 2245 __ testl(result, result); |
| 2246 // TODO(danno): we could be more clever here, perhaps having a special |
| 2247 // version of the stub that detects if the overflow case actually happens, |
| 2248 // and generate code that returns a double rather than int. |
| 2249 DeoptimizeIf(negative, instr->environment()); |
| 2250 break; |
| 2251 } |
| 2252 case kExternalFloatArray: { |
| 2253 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2254 __ movss(result, Operand(external_pointer, key, times_4, 0)); |
| 2255 __ cvtss2sd(result, result); |
| 2256 break; |
| 2257 } |
| 2258 } |
2218 } | 2259 } |
2219 | 2260 |
2220 | 2261 |
2221 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2262 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
2222 ASSERT(ToRegister(instr->object()).is(rdx)); | 2263 ASSERT(ToRegister(instr->object()).is(rdx)); |
2223 ASSERT(ToRegister(instr->key()).is(rax)); | 2264 ASSERT(ToRegister(instr->key()).is(rax)); |
2224 | 2265 |
2225 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2266 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2226 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2267 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
2227 } | 2268 } |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2821 ASSERT(ToRegister(instr->value()).is(rax)); | 2862 ASSERT(ToRegister(instr->value()).is(rax)); |
2822 | 2863 |
2823 __ Move(rcx, instr->hydrogen()->name()); | 2864 __ Move(rcx, instr->hydrogen()->name()); |
2824 Handle<Code> ic = info_->is_strict() | 2865 Handle<Code> ic = info_->is_strict() |
2825 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2866 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
2826 : isolate()->builtins()->StoreIC_Initialize(); | 2867 : isolate()->builtins()->StoreIC_Initialize(); |
2827 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2868 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
2828 } | 2869 } |
2829 | 2870 |
2830 | 2871 |
2831 void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) { | 2872 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
| 2873 LStoreKeyedSpecializedArrayElement* instr) { |
2832 Register external_pointer = ToRegister(instr->external_pointer()); | 2874 Register external_pointer = ToRegister(instr->external_pointer()); |
2833 Register key = ToRegister(instr->key()); | 2875 Register key = ToRegister(instr->key()); |
2834 Register value = ToRegister(instr->value()); | |
2835 | 2876 |
2836 { // Clamp the value to [0..255]. | 2877 switch (instr->array_type()) { |
2837 NearLabel done; | 2878 case kExternalPixelArray: |
2838 __ testl(value, Immediate(0xFFFFFF00)); | 2879 { // Clamp the value to [0..255]. |
2839 __ j(zero, &done); | 2880 NearLabel done; |
2840 __ setcc(negative, value); // 1 if negative, 0 if positive. | 2881 Register value(ToRegister(instr->value())); |
2841 __ decb(value); // 0 if negative, 255 if positive. | 2882 __ testl(value, Immediate(0xFFFFFF00)); |
2842 __ bind(&done); | 2883 __ j(zero, &done); |
| 2884 __ setcc(negative, value); // 1 if negative, 0 if positive. |
| 2885 __ decb(value); // 0 if negative, 255 if positive. |
| 2886 __ bind(&done); |
| 2887 __ movb(Operand(external_pointer, key, times_1, 0), value); |
| 2888 } |
| 2889 break; |
| 2890 case kExternalByteArray: |
| 2891 case kExternalUnsignedByteArray: |
| 2892 __ movb(Operand(external_pointer, key, times_1, 0), |
| 2893 ToRegister(instr->value())); |
| 2894 break; |
| 2895 case kExternalShortArray: |
| 2896 case kExternalUnsignedShortArray: |
| 2897 __ movw(Operand(external_pointer, key, times_2, 0), |
| 2898 ToRegister(instr->value())); |
| 2899 break; |
| 2900 case kExternalIntArray: |
| 2901 case kExternalUnsignedIntArray: |
| 2902 __ movl(Operand(external_pointer, key, times_4, 0), |
| 2903 ToRegister(instr->value())); |
| 2904 break; |
| 2905 case kExternalFloatArray: { |
| 2906 XMMRegister value(ToDoubleRegister(instr->value())); |
| 2907 __ cvtsd2ss(value, value); |
| 2908 __ movss(Operand(external_pointer, key, times_4, 0), value); |
| 2909 break; |
| 2910 } |
2843 } | 2911 } |
2844 | |
2845 __ movb(Operand(external_pointer, key, times_1, 0), value); | |
2846 } | 2912 } |
2847 | 2913 |
2848 | 2914 |
2849 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 2915 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
2850 if (instr->length()->IsRegister()) { | 2916 if (instr->length()->IsRegister()) { |
2851 __ cmpq(ToRegister(instr->index()), ToRegister(instr->length())); | 2917 __ cmpq(ToRegister(instr->index()), ToRegister(instr->length())); |
2852 } else { | 2918 } else { |
2853 __ cmpq(ToRegister(instr->index()), ToOperand(instr->length())); | 2919 __ cmpq(ToRegister(instr->index()), ToOperand(instr->length())); |
2854 } | 2920 } |
2855 DeoptimizeIf(above_equal, instr->environment()); | 2921 DeoptimizeIf(above_equal, instr->environment()); |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3815 RegisterEnvironmentForDeoptimization(environment); | 3881 RegisterEnvironmentForDeoptimization(environment); |
3816 ASSERT(osr_pc_offset_ == -1); | 3882 ASSERT(osr_pc_offset_ == -1); |
3817 osr_pc_offset_ = masm()->pc_offset(); | 3883 osr_pc_offset_ = masm()->pc_offset(); |
3818 } | 3884 } |
3819 | 3885 |
3820 #undef __ | 3886 #undef __ |
3821 | 3887 |
3822 } } // namespace v8::internal | 3888 } } // namespace v8::internal |
3823 | 3889 |
3824 #endif // V8_TARGET_ARCH_X64 | 3890 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |