Index: src/arm/assembler-arm.cc |
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc |
index cc3d5b11a323801f69ecdbc630b37a54a932c74e..416367ff45a3f55b07da2780781f591f87c75791 100644 |
--- a/src/arm/assembler-arm.cc |
+++ b/src/arm/assembler-arm.cc |
@@ -819,6 +819,17 @@ bool Operand::must_output_reloc_info(const Assembler* assembler) const { |
} |
+static bool use_movw_movt(const Operand& x, const Assembler* assembler) { |
+ if (Assembler::use_immediate_constant_pool_loads(assembler)) { |
+ return true; |
+ } |
+ if (x.must_output_reloc_info(assembler)) { |
+ return false; |
+ } |
+ return CpuFeatures::IsSupported(ARMv7); |
+} |
+ |
+ |
bool Operand::is_single_instruction(const Assembler* assembler, |
Instr instr) const { |
if (rm_.is_valid()) return true; |
@@ -829,23 +840,7 @@ bool Operand::is_single_instruction(const Assembler* assembler, |
// constant pool is required. For a mov instruction not setting the |
// condition code additional instruction conventions can be used. |
if ((instr & ~kCondMask) == 13*B21) { // mov, S not set |
-#ifdef USE_BLX |
- // When using BLX, there are two things that must be true for the address |
- // load to be longer than a single instruction. First, immediate loads |
- // using movw/movt must be supported (and fast) on the target ARM |
- // architecture. Second, the reloc mode must be something other than NONE, |
- // since NONE is a used whenever the constant pool cannot be used for |
- // technical reasons, e.g. back-patching calls site in optimized code with |
- // a call to a lazy deopt routine. |
- return !Assembler::allow_immediate_constant_pool_loads(assembler) && |
- rmode_ != RelocInfo::NONE; |
-#else |
- // It's not possible to use immediate loads to the pc to do a call, (the |
- // pc would be inconsistent half-way through the load), so loading the |
- // destination address without USE_BLX is always a single instruction of |
- // the form ldr pc, [pc + #xxx]. |
- return true; |
-#endif |
+ return !use_movw_movt(*this, assembler); |
} else { |
// If this is not a mov or mvn instruction there will always an additional |
// instructions - either mov or ldr. The mov might actually be two |
@@ -866,26 +861,21 @@ void Assembler::move_32_bit_immediate(Condition cond, |
SBit s, |
const Operand& x) { |
if (rd.code() != pc.code() && s == LeaveCC) { |
- // Candidate for immediate load. |
- if (x.must_output_reloc_info(this)) { |
- if (!Assembler::allow_immediate_constant_pool_loads(this)) { |
- RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL); |
- ldr(rd, MemOperand(pc, 0), cond); |
- return; |
+ if (use_movw_movt(x, this)) { |
+ if (x.must_output_reloc_info(this)) { |
+ RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL); |
+ // Make sure the movw/movt doesn't get separated. |
+ BlockConstPoolFor(2); |
} |
- RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL); |
- // Make sure the movw/movt doesn't get separated. |
- BlockConstPoolFor(2); |
+ emit(cond | 0x30*B20 | rd.code()*B12 | |
+ EncodeMovwImmediate(x.imm32_ & 0xffff)); |
+ movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); |
+ return; |
} |
- |
- // Emit a real movw/movt pair. |
- emit(cond | 0x30*B20 | rd.code()*B12 | |
- EncodeMovwImmediate(x.imm32_ & 0xffff)); |
- movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); |
- } else { |
- RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL); |
- ldr(rd, MemOperand(pc, 0), cond); |
} |
+ |
+ RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL); |
+ ldr(rd, MemOperand(pc, 0), cond); |
} |
@@ -916,8 +906,7 @@ void Assembler::addrmod1(Instr instr, |
(instr & kMovMvnMask) != kMovMvnPattern) { |
mov(ip, x, LeaveCC, cond); |
} else { |
- move_32_bit_immediate(cond, ip, |
- static_cast<SBit>(instr & (1 << 20)), x); |
+ move_32_bit_immediate(cond, ip, LeaveCC, x); |
} |
addrmod1(instr, rn, rd, Operand(ip)); |
} |