OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2368 | 2368 |
2369 // There are two words between the frame pointer and the last argument. | 2369 // There are two words between the frame pointer and the last argument. |
2370 // Subtracting from length accounts for one of them add one more. | 2370 // Subtracting from length accounts for one of them add one more. |
2371 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); | 2371 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); |
2372 } | 2372 } |
2373 | 2373 |
2374 | 2374 |
2375 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 2375 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
2376 Register result = ToRegister(instr->result()); | 2376 Register result = ToRegister(instr->result()); |
2377 | 2377 |
| 2378 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
| 2379 // Sign extend key because it could be a 32 bit negative value |
| 2380 // and the dehoisted address computation happens in 64 bits. |
| 2381 Register key_reg = ToRegister(instr->key()); |
| 2382 __ movsxlq(key_reg, key_reg); |
| 2383 } |
| 2384 |
2378 // Load the result. | 2385 // Load the result. |
2379 __ movq(result, | 2386 __ movq(result, |
2380 BuildFastArrayOperand(instr->elements(), instr->key(), | 2387 BuildFastArrayOperand(instr->elements(), |
| 2388 instr->key(), |
2381 FAST_ELEMENTS, | 2389 FAST_ELEMENTS, |
2382 FixedArray::kHeaderSize - kHeapObjectTag)); | 2390 FixedArray::kHeaderSize - kHeapObjectTag, |
| 2391 instr->additional_index())); |
2383 | 2392 |
2384 // Check for the hole value. | 2393 // Check for the hole value. |
2385 if (instr->hydrogen()->RequiresHoleCheck()) { | 2394 if (instr->hydrogen()->RequiresHoleCheck()) { |
2386 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 2395 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
2387 DeoptimizeIf(equal, instr->environment()); | 2396 DeoptimizeIf(equal, instr->environment()); |
2388 } | 2397 } |
2389 } | 2398 } |
2390 | 2399 |
2391 | 2400 |
2392 void LCodeGen::DoLoadKeyedFastDoubleElement( | 2401 void LCodeGen::DoLoadKeyedFastDoubleElement( |
2393 LLoadKeyedFastDoubleElement* instr) { | 2402 LLoadKeyedFastDoubleElement* instr) { |
2394 XMMRegister result(ToDoubleRegister(instr->result())); | 2403 XMMRegister result(ToDoubleRegister(instr->result())); |
2395 | 2404 |
| 2405 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
| 2406 // Sign extend key because it could be a 32 bit negative value |
| 2407 // and the dehoisted address computation happens in 64 bits |
| 2408 Register key_reg = ToRegister(instr->key()); |
| 2409 __ movsxlq(key_reg, key_reg); |
| 2410 } |
| 2411 |
2396 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 2412 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
2397 sizeof(kHoleNanLower32); | 2413 sizeof(kHoleNanLower32); |
2398 Operand hole_check_operand = BuildFastArrayOperand( | 2414 Operand hole_check_operand = BuildFastArrayOperand( |
2399 instr->elements(), | 2415 instr->elements(), |
2400 instr->key(), | 2416 instr->key(), |
2401 FAST_DOUBLE_ELEMENTS, | 2417 FAST_DOUBLE_ELEMENTS, |
2402 offset); | 2418 offset, |
| 2419 instr->additional_index()); |
2403 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 2420 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
2404 DeoptimizeIf(equal, instr->environment()); | 2421 DeoptimizeIf(equal, instr->environment()); |
2405 | 2422 |
2406 Operand double_load_operand = BuildFastArrayOperand( | 2423 Operand double_load_operand = BuildFastArrayOperand( |
2407 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, | 2424 instr->elements(), |
2408 FixedDoubleArray::kHeaderSize - kHeapObjectTag); | 2425 instr->key(), |
| 2426 FAST_DOUBLE_ELEMENTS, |
| 2427 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 2428 instr->additional_index()); |
2409 __ movsd(result, double_load_operand); | 2429 __ movsd(result, double_load_operand); |
2410 } | 2430 } |
2411 | 2431 |
2412 | 2432 |
2413 Operand LCodeGen::BuildFastArrayOperand( | 2433 Operand LCodeGen::BuildFastArrayOperand( |
2414 LOperand* elements_pointer, | 2434 LOperand* elements_pointer, |
2415 LOperand* key, | 2435 LOperand* key, |
2416 ElementsKind elements_kind, | 2436 ElementsKind elements_kind, |
2417 uint32_t offset) { | 2437 uint32_t offset, |
| 2438 uint32_t additional_index) { |
2418 Register elements_pointer_reg = ToRegister(elements_pointer); | 2439 Register elements_pointer_reg = ToRegister(elements_pointer); |
2419 int shift_size = ElementsKindToShiftSize(elements_kind); | 2440 int shift_size = ElementsKindToShiftSize(elements_kind); |
2420 if (key->IsConstantOperand()) { | 2441 if (key->IsConstantOperand()) { |
2421 int constant_value = ToInteger32(LConstantOperand::cast(key)); | 2442 int constant_value = ToInteger32(LConstantOperand::cast(key)); |
2422 if (constant_value & 0xF0000000) { | 2443 if (constant_value & 0xF0000000) { |
2423 Abort("array index constant value too big"); | 2444 Abort("array index constant value too big"); |
2424 } | 2445 } |
2425 return Operand(elements_pointer_reg, | 2446 return Operand(elements_pointer_reg, |
2426 constant_value * (1 << shift_size) + offset); | 2447 ((constant_value + additional_index) << shift_size) |
| 2448 + offset); |
2427 } else { | 2449 } else { |
2428 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 2450 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
2429 return Operand(elements_pointer_reg, ToRegister(key), | 2451 return Operand(elements_pointer_reg, |
2430 scale_factor, offset); | 2452 ToRegister(key), |
| 2453 scale_factor, |
| 2454 offset + (additional_index << shift_size)); |
2431 } | 2455 } |
2432 } | 2456 } |
2433 | 2457 |
2434 | 2458 |
2435 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2459 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2436 LLoadKeyedSpecializedArrayElement* instr) { | 2460 LLoadKeyedSpecializedArrayElement* instr) { |
2437 ElementsKind elements_kind = instr->elements_kind(); | 2461 ElementsKind elements_kind = instr->elements_kind(); |
2438 Operand operand(BuildFastArrayOperand(instr->external_pointer(), | 2462 Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
2439 instr->key(), elements_kind, 0)); | 2463 instr->key(), |
| 2464 elements_kind, |
| 2465 0, |
| 2466 instr->additional_index())); |
| 2467 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
| 2468 // Sign extend key because it could be a 32 bit negative value |
| 2469 // and the dehoisted address computation happens in 64 bits |
| 2470 Register key_reg = ToRegister(instr->key()); |
| 2471 __ movsxlq(key_reg, key_reg); |
| 2472 } |
| 2473 |
2440 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2474 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2441 XMMRegister result(ToDoubleRegister(instr->result())); | 2475 XMMRegister result(ToDoubleRegister(instr->result())); |
2442 __ movss(result, operand); | 2476 __ movss(result, operand); |
2443 __ cvtss2sd(result, result); | 2477 __ cvtss2sd(result, result); |
2444 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 2478 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2445 __ movsd(ToDoubleRegister(instr->result()), operand); | 2479 __ movsd(ToDoubleRegister(instr->result()), operand); |
2446 } else { | 2480 } else { |
2447 Register result(ToRegister(instr->result())); | 2481 Register result(ToRegister(instr->result())); |
2448 switch (elements_kind) { | 2482 switch (elements_kind) { |
2449 case EXTERNAL_BYTE_ELEMENTS: | 2483 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3331 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3365 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
3332 : isolate()->builtins()->StoreIC_Initialize(); | 3366 : isolate()->builtins()->StoreIC_Initialize(); |
3333 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3367 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3334 } | 3368 } |
3335 | 3369 |
3336 | 3370 |
3337 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3371 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
3338 LStoreKeyedSpecializedArrayElement* instr) { | 3372 LStoreKeyedSpecializedArrayElement* instr) { |
3339 ElementsKind elements_kind = instr->elements_kind(); | 3373 ElementsKind elements_kind = instr->elements_kind(); |
3340 Operand operand(BuildFastArrayOperand(instr->external_pointer(), | 3374 Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
3341 instr->key(), elements_kind, 0)); | 3375 instr->key(), |
| 3376 elements_kind, |
| 3377 0, |
| 3378 instr->additional_index())); |
| 3379 |
| 3380 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
| 3381 // Sign extend key because it could be a 32 bit negative value |
| 3382 // and the dehoisted address computation happens in 64 bits |
| 3383 Register key_reg = ToRegister(instr->key()); |
| 3384 __ movsxlq(key_reg, key_reg); |
| 3385 } |
| 3386 |
3342 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3387 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3343 XMMRegister value(ToDoubleRegister(instr->value())); | 3388 XMMRegister value(ToDoubleRegister(instr->value())); |
3344 __ cvtsd2ss(value, value); | 3389 __ cvtsd2ss(value, value); |
3345 __ movss(operand, value); | 3390 __ movss(operand, value); |
3346 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3391 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3347 __ movsd(operand, ToDoubleRegister(instr->value())); | 3392 __ movsd(operand, ToDoubleRegister(instr->value())); |
3348 } else { | 3393 } else { |
3349 Register value(ToRegister(instr->value())); | 3394 Register value(ToRegister(instr->value())); |
3350 switch (elements_kind) { | 3395 switch (elements_kind) { |
3351 case EXTERNAL_PIXEL_ELEMENTS: | 3396 case EXTERNAL_PIXEL_ELEMENTS: |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3401 } | 3446 } |
3402 DeoptimizeIf(below_equal, instr->environment()); | 3447 DeoptimizeIf(below_equal, instr->environment()); |
3403 } | 3448 } |
3404 | 3449 |
3405 | 3450 |
3406 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { | 3451 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
3407 Register value = ToRegister(instr->value()); | 3452 Register value = ToRegister(instr->value()); |
3408 Register elements = ToRegister(instr->object()); | 3453 Register elements = ToRegister(instr->object()); |
3409 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 3454 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
3410 | 3455 |
3411 // Do the store. | 3456 Operand operand = |
3412 if (instr->key()->IsConstantOperand()) { | 3457 BuildFastArrayOperand(instr->object(), |
3413 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3458 instr->key(), |
3414 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3459 FAST_ELEMENTS, |
3415 int offset = | 3460 FixedArray::kHeaderSize - kHeapObjectTag, |
3416 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; | 3461 instr->additional_index()); |
3417 __ movq(FieldOperand(elements, offset), value); | 3462 |
3418 } else { | 3463 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
3419 __ movq(FieldOperand(elements, | 3464 // Sign extend key because it could be a 32 bit negative value |
3420 key, | 3465 // and the dehoisted address computation happens in 64 bits |
3421 times_pointer_size, | 3466 Register key_reg = ToRegister(instr->key()); |
3422 FixedArray::kHeaderSize), | 3467 __ movsxlq(key_reg, key_reg); |
3423 value); | |
3424 } | 3468 } |
3425 | 3469 |
| 3470 __ movq(operand, value); |
| 3471 |
3426 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3472 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3473 ASSERT(!instr->key()->IsConstantOperand()); |
3427 HType type = instr->hydrogen()->value()->type(); | 3474 HType type = instr->hydrogen()->value()->type(); |
3428 SmiCheck check_needed = | 3475 SmiCheck check_needed = |
3429 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 3476 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
3430 // Compute address of modified element and store it into key register. | 3477 // Compute address of modified element and store it into key register. |
3431 __ lea(key, FieldOperand(elements, | 3478 __ lea(key, operand); |
3432 key, | |
3433 times_pointer_size, | |
3434 FixedArray::kHeaderSize)); | |
3435 __ RecordWrite(elements, | 3479 __ RecordWrite(elements, |
3436 key, | 3480 key, |
3437 value, | 3481 value, |
3438 kSaveFPRegs, | 3482 kSaveFPRegs, |
3439 EMIT_REMEMBERED_SET, | 3483 EMIT_REMEMBERED_SET, |
3440 check_needed); | 3484 check_needed); |
3441 } | 3485 } |
3442 } | 3486 } |
3443 | 3487 |
3444 | 3488 |
3445 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3489 void LCodeGen::DoStoreKeyedFastDoubleElement( |
3446 LStoreKeyedFastDoubleElement* instr) { | 3490 LStoreKeyedFastDoubleElement* instr) { |
3447 XMMRegister value = ToDoubleRegister(instr->value()); | 3491 XMMRegister value = ToDoubleRegister(instr->value()); |
3448 | 3492 |
3449 if (instr->NeedsCanonicalization()) { | 3493 if (instr->NeedsCanonicalization()) { |
3450 Label have_value; | 3494 Label have_value; |
3451 | 3495 |
3452 __ ucomisd(value, value); | 3496 __ ucomisd(value, value); |
3453 __ j(parity_odd, &have_value); // NaN. | 3497 __ j(parity_odd, &have_value); // NaN. |
3454 | 3498 |
3455 __ Set(kScratchRegister, BitCast<uint64_t>( | 3499 __ Set(kScratchRegister, BitCast<uint64_t>( |
3456 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 3500 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
3457 __ movq(value, kScratchRegister); | 3501 __ movq(value, kScratchRegister); |
3458 | 3502 |
3459 __ bind(&have_value); | 3503 __ bind(&have_value); |
3460 } | 3504 } |
3461 | 3505 |
3462 Operand double_store_operand = BuildFastArrayOperand( | 3506 Operand double_store_operand = BuildFastArrayOperand( |
3463 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, | 3507 instr->elements(), |
3464 FixedDoubleArray::kHeaderSize - kHeapObjectTag); | 3508 instr->key(), |
| 3509 FAST_DOUBLE_ELEMENTS, |
| 3510 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3511 instr->additional_index()); |
| 3512 |
| 3513 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
| 3514 // Sign extend key because it could be a 32 bit negative value |
| 3515 // and the dehoisted address computation happens in 64 bits |
| 3516 Register key_reg = ToRegister(instr->key()); |
| 3517 __ movsxlq(key_reg, key_reg); |
| 3518 } |
| 3519 |
3465 __ movsd(double_store_operand, value); | 3520 __ movsd(double_store_operand, value); |
3466 } | 3521 } |
3467 | 3522 |
3468 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 3523 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
3469 ASSERT(ToRegister(instr->object()).is(rdx)); | 3524 ASSERT(ToRegister(instr->object()).is(rdx)); |
3470 ASSERT(ToRegister(instr->key()).is(rcx)); | 3525 ASSERT(ToRegister(instr->key()).is(rcx)); |
3471 ASSERT(ToRegister(instr->value()).is(rax)); | 3526 ASSERT(ToRegister(instr->value()).is(rax)); |
3472 | 3527 |
3473 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 3528 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
3474 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3529 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4817 FixedArray::kHeaderSize - kPointerSize)); | 4872 FixedArray::kHeaderSize - kPointerSize)); |
4818 __ bind(&done); | 4873 __ bind(&done); |
4819 } | 4874 } |
4820 | 4875 |
4821 | 4876 |
4822 #undef __ | 4877 #undef __ |
4823 | 4878 |
4824 } } // namespace v8::internal | 4879 } } // namespace v8::internal |
4825 | 4880 |
4826 #endif // V8_TARGET_ARCH_X64 | 4881 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |