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 2201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2212 __ j(equal, &done, Label::kNear); | 2212 __ j(equal, &done, Label::kNear); |
2213 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2213 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
2214 Immediate(factory()->fixed_cow_array_map())); | 2214 Immediate(factory()->fixed_cow_array_map())); |
2215 __ j(equal, &done, Label::kNear); | 2215 __ j(equal, &done, Label::kNear); |
2216 Register temp((result.is(eax)) ? ebx : eax); | 2216 Register temp((result.is(eax)) ? ebx : eax); |
2217 __ push(temp); | 2217 __ push(temp); |
2218 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); | 2218 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); |
2219 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); | 2219 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); |
2220 __ and_(temp, Map::kElementsKindMask); | 2220 __ and_(temp, Map::kElementsKindMask); |
2221 __ shr(temp, Map::kElementsKindShift); | 2221 __ shr(temp, Map::kElementsKindShift); |
2222 __ cmp(temp, JSObject::FAST_ELEMENTS); | 2222 __ cmp(temp, FAST_ELEMENTS); |
2223 __ j(equal, &ok, Label::kNear); | 2223 __ j(equal, &ok, Label::kNear); |
2224 __ cmp(temp, JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 2224 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
2225 __ j(less, &fail, Label::kNear); | 2225 __ j(less, &fail, Label::kNear); |
2226 __ cmp(temp, JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 2226 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
2227 __ j(less_equal, &ok, Label::kNear); | 2227 __ j(less_equal, &ok, Label::kNear); |
2228 __ bind(&fail); | 2228 __ bind(&fail); |
2229 __ Abort("Check for fast or external elements failed."); | 2229 __ Abort("Check for fast or external elements failed."); |
2230 __ bind(&ok); | 2230 __ bind(&ok); |
2231 __ pop(temp); | 2231 __ pop(temp); |
2232 __ bind(&done); | 2232 __ bind(&done); |
2233 } | 2233 } |
2234 } | 2234 } |
2235 | 2235 |
2236 | 2236 |
(...skipping 20 matching lines...) Expand all Loading... |
2257 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); | 2257 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); |
2258 } | 2258 } |
2259 | 2259 |
2260 | 2260 |
2261 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 2261 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
2262 Register result = ToRegister(instr->result()); | 2262 Register result = ToRegister(instr->result()); |
2263 | 2263 |
2264 // Load the result. | 2264 // Load the result. |
2265 __ mov(result, | 2265 __ mov(result, |
2266 BuildFastArrayOperand(instr->elements(), instr->key(), | 2266 BuildFastArrayOperand(instr->elements(), instr->key(), |
2267 JSObject::FAST_ELEMENTS, | 2267 FAST_ELEMENTS, |
2268 FixedArray::kHeaderSize - kHeapObjectTag)); | 2268 FixedArray::kHeaderSize - kHeapObjectTag)); |
2269 | 2269 |
2270 // Check for the hole value. | 2270 // Check for the hole value. |
2271 if (instr->hydrogen()->RequiresHoleCheck()) { | 2271 if (instr->hydrogen()->RequiresHoleCheck()) { |
2272 __ cmp(result, factory()->the_hole_value()); | 2272 __ cmp(result, factory()->the_hole_value()); |
2273 DeoptimizeIf(equal, instr->environment()); | 2273 DeoptimizeIf(equal, instr->environment()); |
2274 } | 2274 } |
2275 } | 2275 } |
2276 | 2276 |
2277 | 2277 |
2278 void LCodeGen::DoLoadKeyedFastDoubleElement( | 2278 void LCodeGen::DoLoadKeyedFastDoubleElement( |
2279 LLoadKeyedFastDoubleElement* instr) { | 2279 LLoadKeyedFastDoubleElement* instr) { |
2280 XMMRegister result = ToDoubleRegister(instr->result()); | 2280 XMMRegister result = ToDoubleRegister(instr->result()); |
2281 | 2281 |
2282 if (instr->hydrogen()->RequiresHoleCheck()) { | 2282 if (instr->hydrogen()->RequiresHoleCheck()) { |
2283 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 2283 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
2284 sizeof(kHoleNanLower32); | 2284 sizeof(kHoleNanLower32); |
2285 Operand hole_check_operand = BuildFastArrayOperand( | 2285 Operand hole_check_operand = BuildFastArrayOperand( |
2286 instr->elements(), instr->key(), | 2286 instr->elements(), instr->key(), |
2287 JSObject::FAST_DOUBLE_ELEMENTS, | 2287 FAST_DOUBLE_ELEMENTS, |
2288 offset); | 2288 offset); |
2289 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); | 2289 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); |
2290 DeoptimizeIf(equal, instr->environment()); | 2290 DeoptimizeIf(equal, instr->environment()); |
2291 } | 2291 } |
2292 | 2292 |
2293 Operand double_load_operand = BuildFastArrayOperand( | 2293 Operand double_load_operand = BuildFastArrayOperand( |
2294 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, | 2294 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, |
2295 FixedDoubleArray::kHeaderSize - kHeapObjectTag); | 2295 FixedDoubleArray::kHeaderSize - kHeapObjectTag); |
2296 __ movdbl(result, double_load_operand); | 2296 __ movdbl(result, double_load_operand); |
2297 } | 2297 } |
2298 | 2298 |
2299 | 2299 |
2300 Operand LCodeGen::BuildFastArrayOperand( | 2300 Operand LCodeGen::BuildFastArrayOperand( |
2301 LOperand* elements_pointer, | 2301 LOperand* elements_pointer, |
2302 LOperand* key, | 2302 LOperand* key, |
2303 JSObject::ElementsKind elements_kind, | 2303 ElementsKind elements_kind, |
2304 uint32_t offset) { | 2304 uint32_t offset) { |
2305 Register elements_pointer_reg = ToRegister(elements_pointer); | 2305 Register elements_pointer_reg = ToRegister(elements_pointer); |
2306 int shift_size = ElementsKindToShiftSize(elements_kind); | 2306 int shift_size = ElementsKindToShiftSize(elements_kind); |
2307 if (key->IsConstantOperand()) { | 2307 if (key->IsConstantOperand()) { |
2308 int constant_value = ToInteger32(LConstantOperand::cast(key)); | 2308 int constant_value = ToInteger32(LConstantOperand::cast(key)); |
2309 if (constant_value & 0xF0000000) { | 2309 if (constant_value & 0xF0000000) { |
2310 Abort("array index constant value too big"); | 2310 Abort("array index constant value too big"); |
2311 } | 2311 } |
2312 return Operand(elements_pointer_reg, | 2312 return Operand(elements_pointer_reg, |
2313 constant_value * (1 << shift_size) + offset); | 2313 constant_value * (1 << shift_size) + offset); |
2314 } else { | 2314 } else { |
2315 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 2315 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
2316 return Operand(elements_pointer_reg, ToRegister(key), scale_factor, offset); | 2316 return Operand(elements_pointer_reg, ToRegister(key), scale_factor, offset); |
2317 } | 2317 } |
2318 } | 2318 } |
2319 | 2319 |
2320 | 2320 |
2321 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2321 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2322 LLoadKeyedSpecializedArrayElement* instr) { | 2322 LLoadKeyedSpecializedArrayElement* instr) { |
2323 JSObject::ElementsKind elements_kind = instr->elements_kind(); | 2323 ElementsKind elements_kind = instr->elements_kind(); |
2324 Operand operand(BuildFastArrayOperand(instr->external_pointer(), | 2324 Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
2325 instr->key(), elements_kind, 0)); | 2325 instr->key(), elements_kind, 0)); |
2326 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { | 2326 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2327 XMMRegister result(ToDoubleRegister(instr->result())); | 2327 XMMRegister result(ToDoubleRegister(instr->result())); |
2328 __ movss(result, operand); | 2328 __ movss(result, operand); |
2329 __ cvtss2sd(result, result); | 2329 __ cvtss2sd(result, result); |
2330 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { | 2330 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2331 __ movdbl(ToDoubleRegister(instr->result()), operand); | 2331 __ movdbl(ToDoubleRegister(instr->result()), operand); |
2332 } else { | 2332 } else { |
2333 Register result(ToRegister(instr->result())); | 2333 Register result(ToRegister(instr->result())); |
2334 switch (elements_kind) { | 2334 switch (elements_kind) { |
2335 case JSObject::EXTERNAL_BYTE_ELEMENTS: | 2335 case EXTERNAL_BYTE_ELEMENTS: |
2336 __ movsx_b(result, operand); | 2336 __ movsx_b(result, operand); |
2337 break; | 2337 break; |
2338 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | 2338 case EXTERNAL_PIXEL_ELEMENTS: |
2339 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2339 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
2340 __ movzx_b(result, operand); | 2340 __ movzx_b(result, operand); |
2341 break; | 2341 break; |
2342 case JSObject::EXTERNAL_SHORT_ELEMENTS: | 2342 case EXTERNAL_SHORT_ELEMENTS: |
2343 __ movsx_w(result, operand); | 2343 __ movsx_w(result, operand); |
2344 break; | 2344 break; |
2345 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2345 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
2346 __ movzx_w(result, operand); | 2346 __ movzx_w(result, operand); |
2347 break; | 2347 break; |
2348 case JSObject::EXTERNAL_INT_ELEMENTS: | 2348 case EXTERNAL_INT_ELEMENTS: |
2349 __ mov(result, operand); | 2349 __ mov(result, operand); |
2350 break; | 2350 break; |
2351 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2351 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
2352 __ mov(result, operand); | 2352 __ mov(result, operand); |
2353 __ test(result, Operand(result)); | 2353 __ test(result, Operand(result)); |
2354 // TODO(danno): we could be more clever here, perhaps having a special | 2354 // TODO(danno): we could be more clever here, perhaps having a special |
2355 // version of the stub that detects if the overflow case actually | 2355 // version of the stub that detects if the overflow case actually |
2356 // happens, and generate code that returns a double rather than int. | 2356 // happens, and generate code that returns a double rather than int. |
2357 DeoptimizeIf(negative, instr->environment()); | 2357 DeoptimizeIf(negative, instr->environment()); |
2358 break; | 2358 break; |
2359 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 2359 case EXTERNAL_FLOAT_ELEMENTS: |
2360 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | 2360 case EXTERNAL_DOUBLE_ELEMENTS: |
2361 case JSObject::FAST_ELEMENTS: | 2361 case FAST_ELEMENTS: |
2362 case JSObject::FAST_DOUBLE_ELEMENTS: | 2362 case FAST_DOUBLE_ELEMENTS: |
2363 case JSObject::DICTIONARY_ELEMENTS: | 2363 case DICTIONARY_ELEMENTS: |
2364 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: | 2364 case NON_STRICT_ARGUMENTS_ELEMENTS: |
2365 UNREACHABLE(); | 2365 UNREACHABLE(); |
2366 break; | 2366 break; |
2367 } | 2367 } |
2368 } | 2368 } |
2369 } | 2369 } |
2370 | 2370 |
2371 | 2371 |
2372 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2372 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
2373 ASSERT(ToRegister(instr->context()).is(esi)); | 2373 ASSERT(ToRegister(instr->context()).is(esi)); |
2374 ASSERT(ToRegister(instr->object()).is(edx)); | 2374 ASSERT(ToRegister(instr->object()).is(edx)); |
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3096 DeoptimizeIf(below_equal, instr->environment()); | 3096 DeoptimizeIf(below_equal, instr->environment()); |
3097 } else { | 3097 } else { |
3098 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); | 3098 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); |
3099 DeoptimizeIf(above_equal, instr->environment()); | 3099 DeoptimizeIf(above_equal, instr->environment()); |
3100 } | 3100 } |
3101 } | 3101 } |
3102 | 3102 |
3103 | 3103 |
3104 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3104 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
3105 LStoreKeyedSpecializedArrayElement* instr) { | 3105 LStoreKeyedSpecializedArrayElement* instr) { |
3106 JSObject::ElementsKind elements_kind = instr->elements_kind(); | 3106 ElementsKind elements_kind = instr->elements_kind(); |
3107 Operand operand(BuildFastArrayOperand(instr->external_pointer(), | 3107 Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
3108 instr->key(), elements_kind, 0)); | 3108 instr->key(), elements_kind, 0)); |
3109 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { | 3109 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3110 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); | 3110 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); |
3111 __ movss(operand, xmm0); | 3111 __ movss(operand, xmm0); |
3112 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { | 3112 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3113 __ movdbl(operand, ToDoubleRegister(instr->value())); | 3113 __ movdbl(operand, ToDoubleRegister(instr->value())); |
3114 } else { | 3114 } else { |
3115 Register value = ToRegister(instr->value()); | 3115 Register value = ToRegister(instr->value()); |
3116 switch (elements_kind) { | 3116 switch (elements_kind) { |
3117 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | 3117 case EXTERNAL_PIXEL_ELEMENTS: |
3118 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3118 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3119 case JSObject::EXTERNAL_BYTE_ELEMENTS: | 3119 case EXTERNAL_BYTE_ELEMENTS: |
3120 __ mov_b(operand, value); | 3120 __ mov_b(operand, value); |
3121 break; | 3121 break; |
3122 case JSObject::EXTERNAL_SHORT_ELEMENTS: | 3122 case EXTERNAL_SHORT_ELEMENTS: |
3123 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3123 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3124 __ mov_w(operand, value); | 3124 __ mov_w(operand, value); |
3125 break; | 3125 break; |
3126 case JSObject::EXTERNAL_INT_ELEMENTS: | 3126 case EXTERNAL_INT_ELEMENTS: |
3127 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3127 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3128 __ mov(operand, value); | 3128 __ mov(operand, value); |
3129 break; | 3129 break; |
3130 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 3130 case EXTERNAL_FLOAT_ELEMENTS: |
3131 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | 3131 case EXTERNAL_DOUBLE_ELEMENTS: |
3132 case JSObject::FAST_ELEMENTS: | 3132 case FAST_ELEMENTS: |
3133 case JSObject::FAST_DOUBLE_ELEMENTS: | 3133 case FAST_DOUBLE_ELEMENTS: |
3134 case JSObject::DICTIONARY_ELEMENTS: | 3134 case DICTIONARY_ELEMENTS: |
3135 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: | 3135 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3136 UNREACHABLE(); | 3136 UNREACHABLE(); |
3137 break; | 3137 break; |
3138 } | 3138 } |
3139 } | 3139 } |
3140 } | 3140 } |
3141 | 3141 |
3142 | 3142 |
3143 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { | 3143 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
3144 Register value = ToRegister(instr->value()); | 3144 Register value = ToRegister(instr->value()); |
3145 Register elements = ToRegister(instr->object()); | 3145 Register elements = ToRegister(instr->object()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3179 | 3179 |
3180 __ ucomisd(value, value); | 3180 __ ucomisd(value, value); |
3181 __ j(parity_odd, &have_value); // NaN. | 3181 __ j(parity_odd, &have_value); // NaN. |
3182 | 3182 |
3183 ExternalReference canonical_nan_reference = | 3183 ExternalReference canonical_nan_reference = |
3184 ExternalReference::address_of_canonical_non_hole_nan(); | 3184 ExternalReference::address_of_canonical_non_hole_nan(); |
3185 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); | 3185 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); |
3186 __ bind(&have_value); | 3186 __ bind(&have_value); |
3187 | 3187 |
3188 Operand double_store_operand = BuildFastArrayOperand( | 3188 Operand double_store_operand = BuildFastArrayOperand( |
3189 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, | 3189 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, |
3190 FixedDoubleArray::kHeaderSize - kHeapObjectTag); | 3190 FixedDoubleArray::kHeaderSize - kHeapObjectTag); |
3191 __ movdbl(double_store_operand, value); | 3191 __ movdbl(double_store_operand, value); |
3192 } | 3192 } |
3193 | 3193 |
3194 | 3194 |
3195 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 3195 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
3196 ASSERT(ToRegister(instr->context()).is(esi)); | 3196 ASSERT(ToRegister(instr->context()).is(esi)); |
3197 ASSERT(ToRegister(instr->object()).is(edx)); | 3197 ASSERT(ToRegister(instr->object()).is(edx)); |
3198 ASSERT(ToRegister(instr->key()).is(ecx)); | 3198 ASSERT(ToRegister(instr->key()).is(ecx)); |
3199 ASSERT(ToRegister(instr->value()).is(eax)); | 3199 ASSERT(ToRegister(instr->value()).is(eax)); |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4377 env->deoptimization_index()); | 4377 env->deoptimization_index()); |
4378 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4378 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
4379 } | 4379 } |
4380 | 4380 |
4381 | 4381 |
4382 #undef __ | 4382 #undef __ |
4383 | 4383 |
4384 } } // namespace v8::internal | 4384 } } // namespace v8::internal |
4385 | 4385 |
4386 #endif // V8_TARGET_ARCH_IA32 | 4386 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |