| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 } | 742 } |
| 743 } | 743 } |
| 744 return false; | 744 return false; |
| 745 } | 745 } |
| 746 | 746 |
| 747 | 747 |
| 748 // We have to use the temporary register for things that can be relocated even | 748 // We have to use the temporary register for things that can be relocated even |
| 749 // if they can be encoded in the ARM's 12 bits of immediate-offset instruction | 749 // if they can be encoded in the ARM's 12 bits of immediate-offset instruction |
| 750 // space. There is no guarantee that the relocated location can be similarly | 750 // space. There is no guarantee that the relocated location can be similarly |
| 751 // encoded. | 751 // encoded. |
| 752 static bool MustUseConstantPool(RelocInfo::Mode rmode) { | 752 bool Operand::must_use_constant_pool() const { |
| 753 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { | 753 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) { |
| 754 #ifdef DEBUG | 754 #ifdef DEBUG |
| 755 if (!Serializer::enabled()) { | 755 if (!Serializer::enabled()) { |
| 756 Serializer::TooLateToEnableNow(); | 756 Serializer::TooLateToEnableNow(); |
| 757 } | 757 } |
| 758 #endif // def DEBUG | 758 #endif // def DEBUG |
| 759 return Serializer::enabled(); | 759 return Serializer::enabled(); |
| 760 } else if (rmode == RelocInfo::NONE) { | 760 } else if (rmode_ == RelocInfo::NONE) { |
| 761 return false; | 761 return false; |
| 762 } | 762 } |
| 763 return true; | 763 return true; |
| 764 } | 764 } |
| 765 | 765 |
| 766 | 766 |
| 767 bool Operand::is_single_instruction() const { | 767 bool Operand::is_single_instruction() const { |
| 768 if (rm_.is_valid()) return true; | 768 if (rm_.is_valid()) return true; |
| 769 if (MustUseConstantPool(rmode_)) return false; | 769 if (must_use_constant_pool()) return false; |
| 770 uint32_t dummy1, dummy2; | 770 uint32_t dummy1, dummy2; |
| 771 return fits_shifter(imm32_, &dummy1, &dummy2, NULL); | 771 return fits_shifter(imm32_, &dummy1, &dummy2, NULL); |
| 772 } | 772 } |
| 773 | 773 |
| 774 | 774 |
| 775 void Assembler::addrmod1(Instr instr, | 775 void Assembler::addrmod1(Instr instr, |
| 776 Register rn, | 776 Register rn, |
| 777 Register rd, | 777 Register rd, |
| 778 const Operand& x) { | 778 const Operand& x) { |
| 779 CheckBuffer(); | 779 CheckBuffer(); |
| 780 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); | 780 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); |
| 781 if (!x.rm_.is_valid()) { | 781 if (!x.rm_.is_valid()) { |
| 782 // Immediate. | 782 // Immediate. |
| 783 uint32_t rotate_imm; | 783 uint32_t rotate_imm; |
| 784 uint32_t immed_8; | 784 uint32_t immed_8; |
| 785 if (MustUseConstantPool(x.rmode_) || | 785 if (x.must_use_constant_pool() || |
| 786 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { | 786 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { |
| 787 // The immediate operand cannot be encoded as a shifter operand, so load | 787 // The immediate operand cannot be encoded as a shifter operand, so load |
| 788 // it first to register ip and change the original instruction to use ip. | 788 // it first to register ip and change the original instruction to use ip. |
| 789 // However, if the original instruction is a 'mov rd, x' (not setting the | 789 // However, if the original instruction is a 'mov rd, x' (not setting the |
| 790 // condition code), then replace it with a 'ldr rd, [pc]'. | 790 // condition code), then replace it with a 'ldr rd, [pc]'. |
| 791 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed | 791 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed |
| 792 Condition cond = static_cast<Condition>(instr & CondMask); | 792 Condition cond = static_cast<Condition>(instr & CondMask); |
| 793 if ((instr & ~CondMask) == 13*B21) { // mov, S not set | 793 if ((instr & ~CondMask) == 13*B21) { // mov, S not set |
| 794 if (MustUseConstantPool(x.rmode_) || | 794 if (x.must_use_constant_pool() || !CpuFeatures::IsSupported(ARMv7)) { |
| 795 !CpuFeatures::IsSupported(ARMv7)) { | |
| 796 RecordRelocInfo(x.rmode_, x.imm32_); | 795 RecordRelocInfo(x.rmode_, x.imm32_); |
| 797 ldr(rd, MemOperand(pc, 0), cond); | 796 ldr(rd, MemOperand(pc, 0), cond); |
| 798 } else { | 797 } else { |
| 799 // Will probably use movw, will certainly not use constant pool. | 798 // Will probably use movw, will certainly not use constant pool. |
| 800 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); | 799 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); |
| 801 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); | 800 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); |
| 802 } | 801 } |
| 803 } else { | 802 } else { |
| 804 // If this is not a mov or mvn instruction we may still be able to avoid | 803 // If this is not a mov or mvn instruction we may still be able to avoid |
| 805 // a constant pool entry by using mvn or movw. | 804 // a constant pool entry by using mvn or movw. |
| 806 if (!MustUseConstantPool(x.rmode_) && | 805 if (!x.must_use_constant_pool() && |
| 807 (instr & kMovMvnMask) != kMovMvnPattern) { | 806 (instr & kMovMvnMask) != kMovMvnPattern) { |
| 808 mov(ip, x, LeaveCC, cond); | 807 mov(ip, x, LeaveCC, cond); |
| 809 } else { | 808 } else { |
| 810 RecordRelocInfo(x.rmode_, x.imm32_); | 809 RecordRelocInfo(x.rmode_, x.imm32_); |
| 811 ldr(ip, MemOperand(pc, 0), cond); | 810 ldr(ip, MemOperand(pc, 0), cond); |
| 812 } | 811 } |
| 813 addrmod1(instr, rn, rd, Operand(ip)); | 812 addrmod1(instr, rn, rd, Operand(ip)); |
| 814 } | 813 } |
| 815 return; | 814 return; |
| 816 } | 815 } |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 | 1328 |
| 1330 | 1329 |
| 1331 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, | 1330 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, |
| 1332 Condition cond) { | 1331 Condition cond) { |
| 1333 ASSERT(fields >= B16 && fields < B20); // at least one field set | 1332 ASSERT(fields >= B16 && fields < B20); // at least one field set |
| 1334 Instr instr; | 1333 Instr instr; |
| 1335 if (!src.rm_.is_valid()) { | 1334 if (!src.rm_.is_valid()) { |
| 1336 // Immediate. | 1335 // Immediate. |
| 1337 uint32_t rotate_imm; | 1336 uint32_t rotate_imm; |
| 1338 uint32_t immed_8; | 1337 uint32_t immed_8; |
| 1339 if (MustUseConstantPool(src.rmode_) || | 1338 if (src.must_use_constant_pool() || |
| 1340 !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { | 1339 !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { |
| 1341 // Immediate operand cannot be encoded, load it first to register ip. | 1340 // Immediate operand cannot be encoded, load it first to register ip. |
| 1342 RecordRelocInfo(src.rmode_, src.imm32_); | 1341 RecordRelocInfo(src.rmode_, src.imm32_); |
| 1343 ldr(ip, MemOperand(pc, 0), cond); | 1342 ldr(ip, MemOperand(pc, 0), cond); |
| 1344 msr(fields, Operand(ip), cond); | 1343 msr(fields, Operand(ip), cond); |
| 1345 return; | 1344 return; |
| 1346 } | 1345 } |
| 1347 instr = I | rotate_imm*B8 | immed_8; | 1346 instr = I | rotate_imm*B8 | immed_8; |
| 1348 } else { | 1347 } else { |
| 1349 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed | 1348 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed |
| (...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2584 | 2583 |
| 2585 // Since a constant pool was just emitted, move the check offset forward by | 2584 // Since a constant pool was just emitted, move the check offset forward by |
| 2586 // the standard interval. | 2585 // the standard interval. |
| 2587 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 2586 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
| 2588 } | 2587 } |
| 2589 | 2588 |
| 2590 | 2589 |
| 2591 } } // namespace v8::internal | 2590 } } // namespace v8::internal |
| 2592 | 2591 |
| 2593 #endif // V8_TARGET_ARCH_ARM | 2592 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |