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 2228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2239 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 2239 void LCodeGen::DoLoadElements(LLoadElements* instr) { |
2240 Register result = ToRegister(instr->result()); | 2240 Register result = ToRegister(instr->result()); |
2241 Register input = ToRegister(instr->InputAt(0)); | 2241 Register input = ToRegister(instr->InputAt(0)); |
2242 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); | 2242 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); |
2243 if (FLAG_debug_code) { | 2243 if (FLAG_debug_code) { |
2244 NearLabel done; | 2244 NearLabel done; |
2245 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2245 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
2246 Immediate(factory()->fixed_array_map())); | 2246 Immediate(factory()->fixed_array_map())); |
2247 __ j(equal, &done); | 2247 __ j(equal, &done); |
2248 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2248 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
2249 Immediate(factory()->external_pixel_array_map())); | 2249 Immediate(factory()->fixed_cow_array_map())); |
2250 __ j(equal, &done); | 2250 __ j(equal, &done); |
2251 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2251 Register temp((result.is(eax)) ? ebx : eax); |
2252 Immediate(factory()->fixed_cow_array_map())); | 2252 __ push(temp); |
2253 __ Check(equal, "Check for fast elements or pixel array failed."); | 2253 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); |
| 2254 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); |
| 2255 __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE)); |
| 2256 __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount)); |
| 2257 __ pop(temp); |
| 2258 __ Check(below, "Check for fast elements or pixel array failed."); |
2254 __ bind(&done); | 2259 __ bind(&done); |
2255 } | 2260 } |
2256 } | 2261 } |
2257 | 2262 |
2258 | 2263 |
2259 void LCodeGen::DoLoadExternalArrayPointer( | 2264 void LCodeGen::DoLoadExternalArrayPointer( |
2260 LLoadExternalArrayPointer* instr) { | 2265 LLoadExternalArrayPointer* instr) { |
2261 Register result = ToRegister(instr->result()); | 2266 Register result = ToRegister(instr->result()); |
2262 Register input = ToRegister(instr->InputAt(0)); | 2267 Register input = ToRegister(instr->InputAt(0)); |
2263 __ mov(result, FieldOperand(input, | 2268 __ mov(result, FieldOperand(input, |
(...skipping 27 matching lines...) Expand all Loading... |
2291 key, | 2296 key, |
2292 times_pointer_size, | 2297 times_pointer_size, |
2293 FixedArray::kHeaderSize)); | 2298 FixedArray::kHeaderSize)); |
2294 | 2299 |
2295 // Check for the hole value. | 2300 // Check for the hole value. |
2296 __ cmp(result, factory()->the_hole_value()); | 2301 __ cmp(result, factory()->the_hole_value()); |
2297 DeoptimizeIf(equal, instr->environment()); | 2302 DeoptimizeIf(equal, instr->environment()); |
2298 } | 2303 } |
2299 | 2304 |
2300 | 2305 |
2301 void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { | 2306 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
| 2307 LLoadKeyedSpecializedArrayElement* instr) { |
2302 Register external_pointer = ToRegister(instr->external_pointer()); | 2308 Register external_pointer = ToRegister(instr->external_pointer()); |
2303 Register key = ToRegister(instr->key()); | 2309 Register key = ToRegister(instr->key()); |
2304 Register result = ToRegister(instr->result()); | 2310 ExternalArrayType array_type = instr->array_type(); |
2305 ASSERT(result.is(external_pointer)); | 2311 if (array_type == kExternalFloatArray) { |
2306 | 2312 XMMRegister result(ToDoubleRegister(instr->result())); |
2307 // Load the result. | 2313 __ movss(result, Operand(external_pointer, key, times_4, 0)); |
2308 __ movzx_b(result, Operand(external_pointer, key, times_1, 0)); | 2314 __ cvtss2sd(result, result); |
| 2315 } else { |
| 2316 Register result(ToRegister(instr->result())); |
| 2317 switch (array_type) { |
| 2318 case kExternalByteArray: |
| 2319 __ movsx_b(result, Operand(external_pointer, key, times_1, 0)); |
| 2320 break; |
| 2321 case kExternalUnsignedByteArray: |
| 2322 case kExternalPixelArray: |
| 2323 __ movzx_b(result, Operand(external_pointer, key, times_1, 0)); |
| 2324 break; |
| 2325 case kExternalShortArray: |
| 2326 __ movsx_w(result, Operand(external_pointer, key, times_2, 0)); |
| 2327 break; |
| 2328 case kExternalUnsignedShortArray: |
| 2329 __ movzx_w(result, Operand(external_pointer, key, times_2, 0)); |
| 2330 break; |
| 2331 case kExternalIntArray: |
| 2332 __ mov(result, Operand(external_pointer, key, times_4, 0)); |
| 2333 break; |
| 2334 case kExternalUnsignedIntArray: |
| 2335 __ mov(result, Operand(external_pointer, key, times_4, 0)); |
| 2336 __ test(Operand(result), Immediate(0x80000000)); |
| 2337 // TODO(danno): we could be more clever here, perhaps having a special |
| 2338 // version of the stub that detects if the overflow case actually |
| 2339 // happens, and generate code that returns a double rather than int. |
| 2340 DeoptimizeIf(not_zero, instr->environment()); |
| 2341 break; |
| 2342 case kExternalFloatArray: |
| 2343 UNREACHABLE(); |
| 2344 break; |
| 2345 } |
| 2346 } |
2309 } | 2347 } |
2310 | 2348 |
2311 | 2349 |
2312 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2350 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
2313 ASSERT(ToRegister(instr->context()).is(esi)); | 2351 ASSERT(ToRegister(instr->context()).is(esi)); |
2314 ASSERT(ToRegister(instr->object()).is(edx)); | 2352 ASSERT(ToRegister(instr->object()).is(edx)); |
2315 ASSERT(ToRegister(instr->key()).is(eax)); | 2353 ASSERT(ToRegister(instr->key()).is(eax)); |
2316 | 2354 |
2317 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2355 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2318 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2356 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2923 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2961 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
2924 } | 2962 } |
2925 | 2963 |
2926 | 2964 |
2927 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 2965 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
2928 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); | 2966 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); |
2929 DeoptimizeIf(above_equal, instr->environment()); | 2967 DeoptimizeIf(above_equal, instr->environment()); |
2930 } | 2968 } |
2931 | 2969 |
2932 | 2970 |
2933 void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) { | 2971 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
| 2972 LStoreKeyedSpecializedArrayElement* instr) { |
2934 Register external_pointer = ToRegister(instr->external_pointer()); | 2973 Register external_pointer = ToRegister(instr->external_pointer()); |
2935 Register key = ToRegister(instr->key()); | 2974 Register key = ToRegister(instr->key()); |
2936 Register value = ToRegister(instr->value()); | 2975 ExternalArrayType array_type = instr->array_type(); |
2937 ASSERT(ToRegister(instr->TempAt(0)).is(eax)); | 2976 if (array_type == kExternalFloatArray) { |
2938 | 2977 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); |
2939 __ mov(eax, value); | 2978 __ movss(Operand(external_pointer, key, times_4, 0), xmm0); |
2940 { // Clamp the value to [0..255]. | 2979 } else { |
2941 NearLabel done; | 2980 Register value = ToRegister(instr->value()); |
2942 __ test(eax, Immediate(0xFFFFFF00)); | 2981 switch (array_type) { |
2943 __ j(zero, &done); | 2982 case kExternalPixelArray: { |
2944 __ setcc(negative, eax); // 1 if negative, 0 if positive. | 2983 // Clamp the value to [0..255]. |
2945 __ dec_b(eax); // 0 if negative, 255 if positive. | 2984 Register temp = ToRegister(instr->TempAt(0)); |
2946 __ bind(&done); | 2985 // The dec_b below requires that the clamped value is in a byte |
| 2986 // register. eax is an arbitrary choice to satisfy this requirement, we |
| 2987 // hinted the register allocator to give us eax when building the |
| 2988 // instruction. |
| 2989 ASSERT(temp.is(eax)); |
| 2990 __ mov(temp, ToRegister(instr->value())); |
| 2991 NearLabel done; |
| 2992 __ test(temp, Immediate(0xFFFFFF00)); |
| 2993 __ j(zero, &done); |
| 2994 __ setcc(negative, temp); // 1 if negative, 0 if positive. |
| 2995 __ dec_b(temp); // 0 if negative, 255 if positive. |
| 2996 __ bind(&done); |
| 2997 __ mov_b(Operand(external_pointer, key, times_1, 0), temp); |
| 2998 break; |
| 2999 } |
| 3000 case kExternalByteArray: |
| 3001 case kExternalUnsignedByteArray: |
| 3002 __ mov_b(Operand(external_pointer, key, times_1, 0), value); |
| 3003 break; |
| 3004 case kExternalShortArray: |
| 3005 case kExternalUnsignedShortArray: |
| 3006 __ mov_w(Operand(external_pointer, key, times_2, 0), value); |
| 3007 break; |
| 3008 case kExternalIntArray: |
| 3009 case kExternalUnsignedIntArray: |
| 3010 __ mov(Operand(external_pointer, key, times_4, 0), value); |
| 3011 break; |
| 3012 case kExternalFloatArray: |
| 3013 UNREACHABLE(); |
| 3014 break; |
| 3015 } |
2947 } | 3016 } |
2948 __ mov_b(Operand(external_pointer, key, times_1, 0), eax); | |
2949 } | 3017 } |
2950 | 3018 |
2951 | 3019 |
2952 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { | 3020 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
2953 Register value = ToRegister(instr->value()); | 3021 Register value = ToRegister(instr->value()); |
2954 Register elements = ToRegister(instr->object()); | 3022 Register elements = ToRegister(instr->object()); |
2955 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 3023 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
2956 | 3024 |
2957 // Do the store. | 3025 // Do the store. |
2958 if (instr->key()->IsConstantOperand()) { | 3026 if (instr->key()->IsConstantOperand()) { |
(...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4065 ASSERT(osr_pc_offset_ == -1); | 4133 ASSERT(osr_pc_offset_ == -1); |
4066 osr_pc_offset_ = masm()->pc_offset(); | 4134 osr_pc_offset_ = masm()->pc_offset(); |
4067 } | 4135 } |
4068 | 4136 |
4069 | 4137 |
4070 #undef __ | 4138 #undef __ |
4071 | 4139 |
4072 } } // namespace v8::internal | 4140 } } // namespace v8::internal |
4073 | 4141 |
4074 #endif // V8_TARGET_ARCH_IA32 | 4142 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |