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 2486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2497 | 2497 |
2498 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 2498 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
2499 Register elements = ToRegister(instr->elements()); | 2499 Register elements = ToRegister(instr->elements()); |
2500 Register key = EmitLoadRegister(instr->key(), scratch0()); | 2500 Register key = EmitLoadRegister(instr->key(), scratch0()); |
2501 Register result = ToRegister(instr->result()); | 2501 Register result = ToRegister(instr->result()); |
2502 Register scratch = scratch0(); | 2502 Register scratch = scratch0(); |
2503 | 2503 |
2504 // Load the result. | 2504 // Load the result. |
2505 __ sll(scratch, key, kPointerSizeLog2); // Key indexes words. | 2505 __ sll(scratch, key, kPointerSizeLog2); // Key indexes words. |
2506 __ addu(scratch, elements, scratch); | 2506 __ addu(scratch, elements, scratch); |
2507 __ lw(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 2507 uint32_t offset = FixedArray::kHeaderSize + |
2508 (instr->additional_index() << kPointerSizeLog2); | |
2509 __ lw(result, FieldMemOperand(scratch, offset)); | |
2508 | 2510 |
2509 // Check for the hole value. | 2511 // Check for the hole value. |
2510 if (instr->hydrogen()->RequiresHoleCheck()) { | 2512 if (instr->hydrogen()->RequiresHoleCheck()) { |
2511 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 2513 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
2512 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); | 2514 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); |
2513 } | 2515 } |
2514 } | 2516 } |
2515 | 2517 |
2516 | 2518 |
2517 void LCodeGen::DoLoadKeyedFastDoubleElement( | 2519 void LCodeGen::DoLoadKeyedFastDoubleElement( |
(...skipping 10 matching lines...) Expand all Loading... | |
2528 if (key_is_constant) { | 2530 if (key_is_constant) { |
2529 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2531 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
2530 if (constant_key & 0xF0000000) { | 2532 if (constant_key & 0xF0000000) { |
2531 Abort("array index constant value too big."); | 2533 Abort("array index constant value too big."); |
2532 } | 2534 } |
2533 } else { | 2535 } else { |
2534 key = ToRegister(instr->key()); | 2536 key = ToRegister(instr->key()); |
2535 } | 2537 } |
2536 | 2538 |
2537 if (key_is_constant) { | 2539 if (key_is_constant) { |
2538 __ Addu(elements, elements, Operand(constant_key * (1 << shift_size) + | 2540 __ Addu(elements, elements, |
2539 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 2541 Operand(((constant_key + instr->additional_index()) << shift_size) + |
2542 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
2540 } else { | 2543 } else { |
2541 __ sll(scratch, key, shift_size); | 2544 __ sll(scratch, key, shift_size); |
2542 __ Addu(elements, elements, Operand(scratch)); | 2545 __ Addu(elements, elements, Operand(scratch)); |
2543 __ Addu(elements, elements, | 2546 __ Addu(elements, elements, |
2544 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 2547 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
2548 (instr->additional_index() << shift_size))); | |
2545 } | 2549 } |
2546 | 2550 |
2547 if (instr->hydrogen()->RequiresHoleCheck()) { | 2551 if (instr->hydrogen()->RequiresHoleCheck()) { |
2548 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 2552 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
2549 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); | 2553 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); |
2550 } | 2554 } |
2551 | 2555 |
2552 __ ldc1(result, MemOperand(elements)); | 2556 __ ldc1(result, MemOperand(elements)); |
2553 } | 2557 } |
2554 | 2558 |
2555 | 2559 |
2556 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2560 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2557 LLoadKeyedSpecializedArrayElement* instr) { | 2561 LLoadKeyedSpecializedArrayElement* instr) { |
2558 Register external_pointer = ToRegister(instr->external_pointer()); | 2562 Register external_pointer = ToRegister(instr->external_pointer()); |
2559 Register key = no_reg; | 2563 Register key = no_reg; |
2560 ElementsKind elements_kind = instr->elements_kind(); | 2564 ElementsKind elements_kind = instr->elements_kind(); |
2561 bool key_is_constant = instr->key()->IsConstantOperand(); | 2565 bool key_is_constant = instr->key()->IsConstantOperand(); |
2562 int constant_key = 0; | 2566 int constant_key = 0; |
2563 if (key_is_constant) { | 2567 if (key_is_constant) { |
2564 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2568 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
2565 if (constant_key & 0xF0000000) { | 2569 if (constant_key & 0xF0000000) { |
2566 Abort("array index constant value too big."); | 2570 Abort("array index constant value too big."); |
2567 } | 2571 } |
2568 } else { | 2572 } else { |
2569 key = ToRegister(instr->key()); | 2573 key = ToRegister(instr->key()); |
2570 } | 2574 } |
2571 int shift_size = ElementsKindToShiftSize(elements_kind); | 2575 int shift_size = ElementsKindToShiftSize(elements_kind); |
2576 int additional_offset = instr->additional_index() << shift_size; | |
2572 | 2577 |
2573 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 2578 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
2574 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 2579 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2575 FPURegister result = ToDoubleRegister(instr->result()); | 2580 FPURegister result = ToDoubleRegister(instr->result()); |
2576 if (key_is_constant) { | 2581 if (key_is_constant) { |
2577 __ Addu(scratch0(), external_pointer, constant_key * (1 << shift_size)); | 2582 __ Addu(scratch0(), external_pointer, constant_key << shift_size); |
2578 } else { | 2583 } else { |
2579 __ sll(scratch0(), key, shift_size); | 2584 __ sll(scratch0(), key, shift_size); |
2580 __ Addu(scratch0(), scratch0(), external_pointer); | 2585 __ Addu(scratch0(), scratch0(), external_pointer); |
2581 } | 2586 } |
2582 | 2587 |
2583 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2588 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2584 __ lwc1(result, MemOperand(scratch0())); | 2589 __ lwc1(result, MemOperand(scratch0(), additional_offset)); |
2585 __ cvt_d_s(result, result); | 2590 __ cvt_d_s(result, result); |
2586 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 2591 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
2587 __ ldc1(result, MemOperand(scratch0())); | 2592 __ ldc1(result, MemOperand(scratch0(), additional_offset)); |
2588 } | 2593 } |
2589 } else { | 2594 } else { |
2590 Register result = ToRegister(instr->result()); | 2595 Register result = ToRegister(instr->result()); |
2591 Register scratch = scratch0(); | 2596 Register scratch = scratch0(); |
2597 if (instr->additional_index() != 0 && !key_is_constant) { | |
2598 __ Addu(scratch, key, instr->additional_index()); | |
2599 } | |
2592 MemOperand mem_operand(zero_reg); | 2600 MemOperand mem_operand(zero_reg); |
2593 if (key_is_constant) { | 2601 if (key_is_constant) { |
2594 mem_operand = MemOperand(external_pointer, | 2602 mem_operand = MemOperand(external_pointer, |
2595 constant_key * (1 << shift_size)); | 2603 (constant_key << shift_size) + additional_offset) ; |
Massi
2012/05/24 09:01:31
Nit: the line exceeds 80 chars.
| |
2596 } else { | 2604 } else { |
2597 __ sll(scratch, key, shift_size); | 2605 if (instr->additional_index() == 0) { |
2606 __ sll(scratch, key, shift_size); | |
2607 } else { | |
2608 __ sll(scratch, scratch, shift_size); | |
2609 } | |
2598 __ Addu(scratch, scratch, external_pointer); | 2610 __ Addu(scratch, scratch, external_pointer); |
2599 mem_operand = MemOperand(scratch); | 2611 mem_operand = MemOperand(scratch); |
2600 } | 2612 } |
2601 switch (elements_kind) { | 2613 switch (elements_kind) { |
2602 case EXTERNAL_BYTE_ELEMENTS: | 2614 case EXTERNAL_BYTE_ELEMENTS: |
2603 __ lb(result, mem_operand); | 2615 __ lb(result, mem_operand); |
2604 break; | 2616 break; |
2605 case EXTERNAL_PIXEL_ELEMENTS: | 2617 case EXTERNAL_PIXEL_ELEMENTS: |
2606 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2618 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
2607 __ lbu(result, mem_operand); | 2619 __ lbu(result, mem_operand); |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3505 Register value = ToRegister(instr->value()); | 3517 Register value = ToRegister(instr->value()); |
3506 Register elements = ToRegister(instr->object()); | 3518 Register elements = ToRegister(instr->object()); |
3507 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 3519 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
3508 Register scratch = scratch0(); | 3520 Register scratch = scratch0(); |
3509 | 3521 |
3510 // Do the store. | 3522 // Do the store. |
3511 if (instr->key()->IsConstantOperand()) { | 3523 if (instr->key()->IsConstantOperand()) { |
3512 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3524 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
3513 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3525 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
3514 int offset = | 3526 int offset = |
3515 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; | 3527 (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize |
3528 + FixedArray::kHeaderSize; | |
3516 __ sw(value, FieldMemOperand(elements, offset)); | 3529 __ sw(value, FieldMemOperand(elements, offset)); |
3517 } else { | 3530 } else { |
3518 __ sll(scratch, key, kPointerSizeLog2); | 3531 __ sll(scratch, key, kPointerSizeLog2); |
3519 __ addu(scratch, elements, scratch); | 3532 __ addu(scratch, elements, scratch); |
3533 if (instr->additional_index() != 0) { | |
3534 __ Addu(scratch, | |
3535 scratch, | |
3536 instr->additional_index() << kPointerSizeLog2); | |
3537 } | |
3520 __ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 3538 __ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
3521 } | 3539 } |
3522 | 3540 |
3523 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3541 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3524 HType type = instr->hydrogen()->value()->type(); | 3542 HType type = instr->hydrogen()->value()->type(); |
3525 SmiCheck check_needed = | 3543 SmiCheck check_needed = |
3526 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 3544 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
3527 // Compute address of modified element and store it into key register. | 3545 // Compute address of modified element and store it into key register. |
3528 __ Addu(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3546 __ Addu(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
3529 __ RecordWrite(elements, | 3547 __ RecordWrite(elements, |
(...skipping 22 matching lines...) Expand all Loading... | |
3552 if (key_is_constant) { | 3570 if (key_is_constant) { |
3553 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3571 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3554 if (constant_key & 0xF0000000) { | 3572 if (constant_key & 0xF0000000) { |
3555 Abort("array index constant value too big."); | 3573 Abort("array index constant value too big."); |
3556 } | 3574 } |
3557 } else { | 3575 } else { |
3558 key = ToRegister(instr->key()); | 3576 key = ToRegister(instr->key()); |
3559 } | 3577 } |
3560 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 3578 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
3561 if (key_is_constant) { | 3579 if (key_is_constant) { |
3562 __ Addu(scratch, elements, Operand(constant_key * (1 << shift_size) + | 3580 __ Addu(scratch, elements, Operand((constant_key << shift_size) + |
3563 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 3581 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
3564 } else { | 3582 } else { |
3565 __ sll(scratch, key, shift_size); | 3583 __ sll(scratch, key, shift_size); |
3566 __ Addu(scratch, elements, Operand(scratch)); | 3584 __ Addu(scratch, elements, Operand(scratch)); |
3567 __ Addu(scratch, scratch, | 3585 __ Addu(scratch, scratch, |
3568 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 3586 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
3569 } | 3587 } |
3570 | 3588 |
3571 if (instr->NeedsCanonicalization()) { | 3589 if (instr->NeedsCanonicalization()) { |
3572 Label is_nan; | 3590 Label is_nan; |
3573 // Check for NaN. All NaNs must be canonicalized. | 3591 // Check for NaN. All NaNs must be canonicalized. |
3574 __ BranchF(NULL, &is_nan, eq, value, value); | 3592 __ BranchF(NULL, &is_nan, eq, value, value); |
3575 __ Branch(¬_nan); | 3593 __ Branch(¬_nan); |
3576 | 3594 |
3577 // Only load canonical NaN if the comparison above set the overflow. | 3595 // Only load canonical NaN if the comparison above set the overflow. |
3578 __ bind(&is_nan); | 3596 __ bind(&is_nan); |
3579 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | 3597 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
3580 } | 3598 } |
3581 | 3599 |
3582 __ bind(¬_nan); | 3600 __ bind(¬_nan); |
3583 __ sdc1(value, MemOperand(scratch)); | 3601 __ sdc1(value, MemOperand(scratch, instr->additional_index() << shift_size)); |
3584 } | 3602 } |
3585 | 3603 |
3586 | 3604 |
3587 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3605 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
3588 LStoreKeyedSpecializedArrayElement* instr) { | 3606 LStoreKeyedSpecializedArrayElement* instr) { |
3589 | 3607 |
3590 Register external_pointer = ToRegister(instr->external_pointer()); | 3608 Register external_pointer = ToRegister(instr->external_pointer()); |
3591 Register key = no_reg; | 3609 Register key = no_reg; |
3592 ElementsKind elements_kind = instr->elements_kind(); | 3610 ElementsKind elements_kind = instr->elements_kind(); |
3593 bool key_is_constant = instr->key()->IsConstantOperand(); | 3611 bool key_is_constant = instr->key()->IsConstantOperand(); |
3594 int constant_key = 0; | 3612 int constant_key = 0; |
3595 if (key_is_constant) { | 3613 if (key_is_constant) { |
3596 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3614 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3597 if (constant_key & 0xF0000000) { | 3615 if (constant_key & 0xF0000000) { |
3598 Abort("array index constant value too big."); | 3616 Abort("array index constant value too big."); |
3599 } | 3617 } |
3600 } else { | 3618 } else { |
3601 key = ToRegister(instr->key()); | 3619 key = ToRegister(instr->key()); |
3602 } | 3620 } |
3603 int shift_size = ElementsKindToShiftSize(elements_kind); | 3621 int shift_size = ElementsKindToShiftSize(elements_kind); |
3622 int additional_offset = instr->additional_index() << shift_size; | |
3604 | 3623 |
3605 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3624 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
3606 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3625 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3607 FPURegister value(ToDoubleRegister(instr->value())); | 3626 FPURegister value(ToDoubleRegister(instr->value())); |
3608 if (key_is_constant) { | 3627 if (key_is_constant) { |
3609 __ Addu(scratch0(), external_pointer, constant_key * (1 << shift_size)); | 3628 __ Addu(scratch0(), external_pointer, constant_key << shift_size); |
3610 } else { | 3629 } else { |
3611 __ sll(scratch0(), key, shift_size); | 3630 __ sll(scratch0(), key, shift_size); |
3612 __ Addu(scratch0(), scratch0(), external_pointer); | 3631 __ Addu(scratch0(), scratch0(), external_pointer); |
3613 } | 3632 } |
3614 | 3633 |
3615 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3634 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3616 __ cvt_s_d(double_scratch0(), value); | 3635 __ cvt_s_d(double_scratch0(), value); |
3617 __ swc1(double_scratch0(), MemOperand(scratch0())); | 3636 __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset)); |
3618 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3637 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
3619 __ sdc1(value, MemOperand(scratch0())); | 3638 __ sdc1(value, MemOperand(scratch0(), additional_offset)); |
3620 } | 3639 } |
3621 } else { | 3640 } else { |
3622 Register value(ToRegister(instr->value())); | 3641 Register value(ToRegister(instr->value())); |
3642 Register scratch = scratch0(); | |
3643 if (instr->additional_index() != 0 && !key_is_constant) { | |
3644 __ Addu(scratch0(), key, instr->additional_index()); | |
Massi
2012/05/24 09:01:31
You moved the declaration "Register scratch = scra
palfia
2012/05/24 16:16:33
Yes, it is much cleaner.
| |
3645 } | |
3623 MemOperand mem_operand(zero_reg); | 3646 MemOperand mem_operand(zero_reg); |
3624 Register scratch = scratch0(); | |
3625 if (key_is_constant) { | 3647 if (key_is_constant) { |
3626 mem_operand = MemOperand(external_pointer, | 3648 mem_operand = MemOperand(external_pointer, |
3627 constant_key * (1 << shift_size)); | 3649 ((constant_key + instr->additional_index()) |
3650 << shift_size)); | |
3628 } else { | 3651 } else { |
3629 __ sll(scratch, key, shift_size); | 3652 if (instr->additional_index() == 0) { |
3653 __ sll(scratch, key, shift_size); | |
3654 } else { | |
3655 __ sll(scratch, scratch, shift_size); | |
3656 } | |
3630 __ Addu(scratch, scratch, external_pointer); | 3657 __ Addu(scratch, scratch, external_pointer); |
3631 mem_operand = MemOperand(scratch); | 3658 mem_operand = MemOperand(scratch); |
3632 } | 3659 } |
3633 switch (elements_kind) { | 3660 switch (elements_kind) { |
3634 case EXTERNAL_PIXEL_ELEMENTS: | 3661 case EXTERNAL_PIXEL_ELEMENTS: |
3635 case EXTERNAL_BYTE_ELEMENTS: | 3662 case EXTERNAL_BYTE_ELEMENTS: |
3636 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3663 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3637 __ sb(value, mem_operand); | 3664 __ sb(value, mem_operand); |
3638 break; | 3665 break; |
3639 case EXTERNAL_SHORT_ELEMENTS: | 3666 case EXTERNAL_SHORT_ELEMENTS: |
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5135 __ Subu(scratch, result, scratch); | 5162 __ Subu(scratch, result, scratch); |
5136 __ lw(result, FieldMemOperand(scratch, | 5163 __ lw(result, FieldMemOperand(scratch, |
5137 FixedArray::kHeaderSize - kPointerSize)); | 5164 FixedArray::kHeaderSize - kPointerSize)); |
5138 __ bind(&done); | 5165 __ bind(&done); |
5139 } | 5166 } |
5140 | 5167 |
5141 | 5168 |
5142 #undef __ | 5169 #undef __ |
5143 | 5170 |
5144 } } // namespace v8::internal | 5171 } } // namespace v8::internal |
OLD | NEW |