Commit fadc74ec authored by rmcilroy@chromium.org's avatar rmcilroy@chromium.org

Clean up ARM mov 32bit immediate code in preparation for out of line constant pool.

R=rodolph.perfetta@arm.com, ulan@chromium.org

Review URL: https://codereview.chromium.org/138503002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19823 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5d473db1
......@@ -1059,14 +1059,19 @@ 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_embedded_pointer_loads(assembler)) {
static bool use_mov_immediate_load(const Operand& x,
const Assembler* assembler) {
if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
(assembler == NULL || !assembler->predictable_code_size())) {
// Prefer movw / movt to constant pool if it is more efficient on the CPU.
return true;
}
if (x.must_output_reloc_info(assembler)) {
} else if (x.must_output_reloc_info(assembler)) {
// Prefer constant pool if data is likely to be patched.
return false;
} else {
// Otherwise, use immediate load if movw / movt is available.
return CpuFeatures::IsSupported(ARMv7);
}
return CpuFeatures::IsSupported(ARMv7);
}
......@@ -1080,7 +1085,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
return !use_movw_movt(*this, assembler);
return !use_mov_immediate_load(*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
......@@ -1096,12 +1101,11 @@ bool Operand::is_single_instruction(const Assembler* assembler,
}
void Assembler::move_32_bit_immediate(Condition cond,
Register rd,
SBit s,
const Operand& x) {
if (rd.code() != pc.code() && s == LeaveCC) {
if (use_movw_movt(x, this)) {
void Assembler::move_32_bit_immediate(Register rd,
const Operand& x,
Condition cond) {
if (rd.code() != pc.code()) {
if (use_mov_immediate_load(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.
......@@ -1138,20 +1142,9 @@ void Assembler::addrmod1(Instr instr,
CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
Condition cond = Instruction::ConditionField(instr);
if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
move_32_bit_immediate(cond, rd, LeaveCC, x);
move_32_bit_immediate(rd, x, cond);
} else {
if ((instr & kMovMvnMask) == kMovMvnPattern) {
// Moves need to use a constant pool entry.
RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
ldr(ip, MemOperand(pc, 0), cond);
} else if (x.must_output_reloc_info(this)) {
// Otherwise, use most efficient form of fetching from constant pool.
move_32_bit_immediate(cond, ip, LeaveCC, x);
} else {
// If this is not a mov or mvn instruction we may still be able to
// avoid a constant pool entry by using mvn or movw.
mov(ip, x, LeaveCC, cond);
}
mov(ip, x, LeaveCC, cond);
addrmod1(instr, rn, rd, Operand(ip));
}
return;
......@@ -1819,8 +1812,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
if (src.must_output_reloc_info(this) ||
!fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
// Immediate operand cannot be encoded, load it first to register ip.
RecordRelocInfo(src.rmode_, src.imm32_);
ldr(ip, MemOperand(pc, 0), cond);
move_32_bit_immediate(ip, src);
msr(fields, Operand(ip), cond);
return;
}
......
......@@ -1292,12 +1292,6 @@ class Assembler : public AssemblerBase {
// Jump unconditionally to given label.
void jmp(Label* L) { b(L, al); }
static bool use_immediate_embedded_pointer_loads(
const Assembler* assembler) {
return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
(assembler == NULL || !assembler->predictable_code_size());
}
// Check the code size generated from label to here.
int SizeOfCodeGeneratedSince(Label* label) {
return pc_offset() - label->pos();
......@@ -1565,10 +1559,9 @@ class Assembler : public AssemblerBase {
inline void emit(Instr x);
// 32-bit immediate values
void move_32_bit_immediate(Condition cond,
Register rd,
SBit s,
const Operand& x);
void move_32_bit_immediate(Register rd,
const Operand& x,
Condition cond = al);
// Instruction generation
void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
......
......@@ -272,10 +272,10 @@ TEST(Type0) {
// We only disassemble one instruction so the eor instruction is not here.
COMPARE(eor(r5, r4, Operand(0x1234), LeaveCC, ne),
"1301c234 movwne ip, #4660");
// Movw can't do setcc so we don't get that here. Mov immediate with setcc
// is pretty strange anyway.
// Movw can't do setcc, so first move to ip, then the following instruction
// moves to r5. Mov immediate with setcc is pretty strange anyway.
COMPARE(mov(r5, Operand(0x01234), SetCC, ne),
"159fc000 ldrne ip, [pc, #+0]");
"1301c234 movwne ip, #4660");
// Emit a literal pool now, otherwise this could be dumped later, in the
// middle of a different test.
EMIT_PENDING_LITERALS();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment