| 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 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | | 617 ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | |
| 618 cp.bit() | | 618 cp.bit() | |
| 619 (FLAG_enable_ool_constant_pool ? pp.bit() : 0) | | 619 (FLAG_enable_ool_constant_pool ? pp.bit() : 0) | |
| 620 fp.bit() | | 620 fp.bit() | |
| 621 lr.bit()); | 621 lr.bit()); |
| 622 } | 622 } |
| 623 | 623 |
| 624 | 624 |
| 625 // Push and pop all registers that can hold pointers. | 625 // Push and pop all registers that can hold pointers. |
| 626 void MacroAssembler::PushSafepointRegisters() { | 626 void MacroAssembler::PushSafepointRegisters() { |
| 627 // Safepoints expect a block of contiguous register values starting with r0: | 627 // This function must be called from LCodeGen::GenerateCode where |
| 628 ASSERT(((1 << kNumSafepointSavedRegisters) - 1) == kSafepointSavedRegisters); | 628 // registers_mask and double_registers_mask are set. |
| 629 // Safepoints expect a block of kNumSafepointRegisters values on the | 629 ASSERT(registers_mask() != kRegListEmpty); |
| 630 // stack, so adjust the stack for unsaved registers. | 630 stm(db_w, sp, registers_mask()); |
| 631 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; | |
| 632 ASSERT(num_unsaved >= 0); | |
| 633 sub(sp, sp, Operand(num_unsaved * kPointerSize)); | |
| 634 stm(db_w, sp, kSafepointSavedRegisters); | |
| 635 } | 631 } |
| 636 | 632 |
| 637 | 633 |
| 638 void MacroAssembler::PopSafepointRegisters() { | 634 void MacroAssembler::PopSafepointRegisters() { |
| 639 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; | 635 // This function must be called from LCodeGen::GenerateCode where |
| 640 ldm(ia_w, sp, kSafepointSavedRegisters); | 636 // registers_mask and double_registers_mask are set. |
| 641 add(sp, sp, Operand(num_unsaved * kPointerSize)); | 637 ASSERT(registers_mask() != kRegListEmpty); |
| 638 ldm(ia_w, sp, registers_mask()); |
| 642 } | 639 } |
| 643 | 640 |
| 644 | 641 |
| 645 void MacroAssembler::PushSafepointRegistersAndDoubles() { | 642 void MacroAssembler::PushSafepointRegistersAndDoubles() { |
| 646 // Number of d-regs not known at snapshot time. | |
| 647 ASSERT(!Serializer::enabled()); | |
| 648 PushSafepointRegisters(); | 643 PushSafepointRegisters(); |
| 649 // Only save allocatable registers. | 644 // The vstm instruction can only save up to 16 doubles. So we save all the |
| 650 ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14)); | 645 // doubles registers with up to 2 instructions. |
| 651 ASSERT(DwVfpRegister::NumReservedRegisters() == 2); | 646 RegList high_mask = double_registers_mask() & 0xffff0000; |
| 652 if (CpuFeatures::IsSupported(VFP32DREGS)) { | 647 if (high_mask != 0) { |
| 653 vstm(db_w, sp, d16, d31); | 648 for (int i = LowDwVfpRegister::kMaxNumLowRegisters; |
| 649 i < DoubleRegister::NumRegisters(); |
| 650 i++) { |
| 651 if ((high_mask & (1 << i)) != 0) { |
| 652 int last = i + CompilerIntrinsics::CountSetBits(high_mask) - 1; |
| 653 // When double_registers_mask has been initialized, we ensured that |
| 654 // there is no holes between the first and the last high registers. |
| 655 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) == |
| 656 high_mask); |
| 657 vstm(db_w, sp, DwVfpRegister::from_code(i), |
| 658 DwVfpRegister::from_code(last)); |
| 659 break; |
| 660 } |
| 661 } |
| 654 } | 662 } |
| 655 vstm(db_w, sp, d0, d13); | 663 RegList low_mask = double_registers_mask() & 0xffff; |
| 664 if (low_mask != 0) { |
| 665 for (int i = 0; i < LowDwVfpRegister::kMaxNumLowRegisters; i++) { |
| 666 if ((low_mask & (1 << i)) != 0) { |
| 667 int last = i + CompilerIntrinsics::CountSetBits(low_mask) - 1; |
| 668 // When double_registers_mask has been initialized, we ensured that |
| 669 // there is no holes between the first and the last low registers. |
| 670 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) == |
| 671 low_mask); |
| 672 vstm(db_w, sp, LowDwVfpRegister::from_code(i), |
| 673 LowDwVfpRegister::from_code(last)); |
| 674 break; |
| 675 } |
| 676 } |
| 677 } |
| 656 } | 678 } |
| 657 | 679 |
| 658 | 680 |
| 659 void MacroAssembler::PopSafepointRegistersAndDoubles() { | 681 void MacroAssembler::PopSafepointRegistersAndDoubles() { |
| 660 // Number of d-regs not known at snapshot time. | 682 // The vldm instruction can only restore up to 16 doubles. So we save all the |
| 661 ASSERT(!Serializer::enabled()); | 683 // doubles registers with up to 2 instructions. |
| 662 // Only save allocatable registers. | 684 RegList low_mask = double_registers_mask() & 0xffff; |
| 663 ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14)); | 685 if (low_mask != 0) { |
| 664 ASSERT(DwVfpRegister::NumReservedRegisters() == 2); | 686 for (int i = 0; i < LowDwVfpRegister::kMaxNumLowRegisters; i++) { |
| 665 vldm(ia_w, sp, d0, d13); | 687 if ((low_mask & (1 << i)) != 0) { |
| 666 if (CpuFeatures::IsSupported(VFP32DREGS)) { | 688 int last = i + CompilerIntrinsics::CountSetBits(low_mask) - 1; |
| 667 vldm(ia_w, sp, d16, d31); | 689 // When double_registers_mask has been initialized, we ensured that |
| 690 // there is no holes between the first and the last low registers. |
| 691 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) == |
| 692 low_mask); |
| 693 vldm(ia_w, sp, LowDwVfpRegister::from_code(i), |
| 694 LowDwVfpRegister::from_code(last)); |
| 695 break; |
| 696 } |
| 697 } |
| 698 } |
| 699 RegList high_mask = double_registers_mask() & 0xffff0000; |
| 700 if (high_mask != 0) { |
| 701 for (int i = LowDwVfpRegister::kMaxNumLowRegisters; |
| 702 i < DoubleRegister::NumRegisters(); |
| 703 i++) { |
| 704 if ((high_mask & (1 << i)) != 0) { |
| 705 int last = i + CompilerIntrinsics::CountSetBits(high_mask) - 1; |
| 706 // When double_registers_mask has been initialized, we ensured that |
| 707 // there is no holes between the first and the last high registers. |
| 708 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) == |
| 709 high_mask); |
| 710 vldm(ia_w, sp, DwVfpRegister::from_code(i), |
| 711 DwVfpRegister::from_code(last)); |
| 712 break; |
| 713 } |
| 714 } |
| 668 } | 715 } |
| 669 PopSafepointRegisters(); | 716 PopSafepointRegisters(); |
| 670 } | 717 } |
| 671 | 718 |
| 672 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src, | 719 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src, |
| 673 Register dst) { | 720 Register dst) { |
| 721 // This function must be called from LCodeGen::GenerateCode where |
| 722 // registers_mask and double_registers_mask are set. |
| 723 ASSERT((registers_mask() & dst.bit()) != kRegListEmpty); |
| 674 str(src, SafepointRegistersAndDoublesSlot(dst)); | 724 str(src, SafepointRegistersAndDoublesSlot(dst)); |
| 675 } | 725 } |
| 676 | 726 |
| 677 | 727 |
| 678 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) { | 728 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) { |
| 729 // This function must be called from LCodeGen::GenerateCode where |
| 730 // registers_mask and double_registers_mask are set. |
| 731 ASSERT((registers_mask() & dst.bit()) != kRegListEmpty); |
| 679 str(src, SafepointRegisterSlot(dst)); | 732 str(src, SafepointRegisterSlot(dst)); |
| 680 } | 733 } |
| 681 | 734 |
| 682 | 735 |
| 683 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { | 736 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { |
| 737 // This function must be called from LCodeGen::GenerateCode where |
| 738 // registers_mask and double_registers_mask are set. |
| 739 ASSERT((registers_mask() & dst.bit()) != kRegListEmpty); |
| 684 ldr(dst, SafepointRegisterSlot(src)); | 740 ldr(dst, SafepointRegisterSlot(src)); |
| 685 } | 741 } |
| 686 | 742 |
| 687 | 743 |
| 688 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) { | 744 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) { |
| 745 // This function must be called from LCodeGen::GenerateCode where |
| 746 // registers_mask and double_registers_mask are set. |
| 747 ASSERT((registers_mask() & (1 << reg_code)) != kRegListEmpty); |
| 689 // The registers are pushed starting with the highest encoding, | 748 // The registers are pushed starting with the highest encoding, |
| 690 // which means that lowest encodings are closest to the stack pointer. | 749 // which means that lowest encodings are closest to the stack pointer. |
| 691 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); | 750 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); |
| 692 return reg_code; | 751 ASSERT((registers_mask() & (1 << reg_code)) != 0); |
| 752 // Only count registers below reg_code. |
| 753 return |
| 754 CompilerIntrinsics::CountSetBits(registers_mask() & ((1 << reg_code) - 1)); |
| 693 } | 755 } |
| 694 | 756 |
| 695 | 757 |
| 696 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { | 758 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { |
| 697 return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); | 759 return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); |
| 698 } | 760 } |
| 699 | 761 |
| 700 | 762 |
| 701 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { | 763 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { |
| 702 // Number of d-regs not known at snapshot time. | |
| 703 ASSERT(!Serializer::enabled()); | |
| 704 // General purpose registers are pushed last on the stack. | 764 // General purpose registers are pushed last on the stack. |
| 705 int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize; | 765 int doubles_size = |
| 766 CompilerIntrinsics::CountSetBits(double_registers_mask()) * kDoubleSize; |
| 706 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; | 767 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; |
| 707 return MemOperand(sp, doubles_size + register_offset); | 768 return MemOperand(sp, doubles_size + register_offset); |
| 708 } | 769 } |
| 709 | 770 |
| 710 | 771 |
| 711 void MacroAssembler::Ldrd(Register dst1, Register dst2, | 772 void MacroAssembler::Ldrd(Register dst1, Register dst2, |
| 712 const MemOperand& src, Condition cond) { | 773 const MemOperand& src, Condition cond) { |
| 713 ASSERT(src.rm().is(no_reg)); | 774 ASSERT(src.rm().is(no_reg)); |
| 714 ASSERT(!dst1.is(lr)); // r14. | 775 ASSERT(!dst1.is(lr)); // r14. |
| 715 | 776 |
| (...skipping 3331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4047 if (divisor < 0 && ms.multiplier() > 0) { | 4108 if (divisor < 0 && ms.multiplier() > 0) { |
| 4048 sub(result, result, Operand(dividend)); | 4109 sub(result, result, Operand(dividend)); |
| 4049 } | 4110 } |
| 4050 if (ms.shift() > 0) mov(result, Operand(result, ASR, ms.shift())); | 4111 if (ms.shift() > 0) mov(result, Operand(result, ASR, ms.shift())); |
| 4051 } | 4112 } |
| 4052 | 4113 |
| 4053 | 4114 |
| 4054 } } // namespace v8::internal | 4115 } } // namespace v8::internal |
| 4055 | 4116 |
| 4056 #endif // V8_TARGET_ARCH_ARM | 4117 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |