ART: Add 16-bit Thumb2 ROR, NEGS and CMP for high registers.
Also clean up the usage of set_cc flag. Define a SetCc
enumeration that specifies whether to set or keep condition
codes or whether we don't care and a 16-bit instruction
should be selected if one exists.
This reduces the size of Nexus 5 boot.oat by 44KiB (when
compiled with Optimizing which is not the default yet).
Change-Id: I047072dc197ea678bf2019c01bcb28943fa9b604
diff --git a/compiler/utils/arm/assembler_arm32.cc b/compiler/utils/arm/assembler_arm32.cc
index 6e60ddc..d91ddee 100644
--- a/compiler/utils/arm/assembler_arm32.cc
+++ b/compiler/utils/arm/assembler_arm32.cc
@@ -57,126 +57,94 @@
}
void Arm32Assembler::and_(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), AND, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), AND, set_cc, rn, rd, so);
}
void Arm32Assembler::eor(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), EOR, set_cc, rn, rd, so);
}
void Arm32Assembler::sub(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), SUB, set_cc, rn, rd, so);
}
void Arm32Assembler::rsb(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), RSB, set_cc, rn, rd, so);
}
-void Arm32Assembler::rsbs(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
-}
-
-
void Arm32Assembler::add(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
-}
-
-
-void Arm32Assembler::adds(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
-}
-
-
-void Arm32Assembler::subs(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), ADD, set_cc, rn, rd, so);
}
void Arm32Assembler::adc(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), ADC, set_cc, rn, rd, so);
}
void Arm32Assembler::sbc(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), SBC, set_cc, rn, rd, so);
}
void Arm32Assembler::rsc(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), RSC, set_cc, rn, rd, so);
}
void Arm32Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) {
CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker.
- EmitType01(cond, so.type(), TST, 1, rn, R0, so);
+ EmitType01(cond, so.type(), TST, kCcSet, rn, R0, so);
}
void Arm32Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) {
CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker.
- EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
+ EmitType01(cond, so.type(), TEQ, kCcSet, rn, R0, so);
}
void Arm32Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
+ EmitType01(cond, so.type(), CMP, kCcSet, rn, R0, so);
}
void Arm32Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
+ EmitType01(cond, so.type(), CMN, kCcSet, rn, R0, so);
}
-void Arm32Assembler::orr(Register rd, Register rn,
- const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
+void Arm32Assembler::orr(Register rd, Register rn, const ShifterOperand& so,
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), ORR, set_cc, rn, rd, so);
}
-void Arm32Assembler::orrs(Register rd, Register rn,
- const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
-}
-
-
-void Arm32Assembler::mov(Register rd, const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
-}
-
-
-void Arm32Assembler::movs(Register rd, const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
+void Arm32Assembler::mov(Register rd, const ShifterOperand& so,
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), MOV, set_cc, R0, rd, so);
}
void Arm32Assembler::bic(Register rd, Register rn, const ShifterOperand& so,
- Condition cond) {
- EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), BIC, set_cc, rn, rd, so);
}
-void Arm32Assembler::mvn(Register rd, const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
-}
-
-
-void Arm32Assembler::mvns(Register rd, const ShifterOperand& so, Condition cond) {
- EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
+void Arm32Assembler::mvn(Register rd, const ShifterOperand& so,
+ Condition cond, SetCc set_cc) {
+ EmitType01(cond, so.type(), MVN, set_cc, R0, rd, so);
}
@@ -573,7 +541,7 @@
void Arm32Assembler::MarkExceptionHandler(Label* label) {
- EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
+ EmitType01(AL, 1, TST, kCcSet, PC, R0, ShifterOperand(0));
Label l;
b(&l);
EmitBranch(AL, label, false);
@@ -590,7 +558,7 @@
void Arm32Assembler::EmitType01(Condition cond,
int type,
Opcode opcode,
- int set_cc,
+ SetCc set_cc,
Register rn,
Register rd,
const ShifterOperand& so) {
@@ -599,7 +567,7 @@
int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
type << kTypeShift |
static_cast<int32_t>(opcode) << kOpcodeShift |
- set_cc << kSShift |
+ (set_cc == kCcSet ? 1 : 0) << kSShift |
static_cast<int32_t>(rn) << kRnShift |
static_cast<int32_t>(rd) << kRdShift |
so.encodingArm();
@@ -1158,96 +1126,60 @@
void Arm32Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
- bool setcc, Condition cond) {
+ Condition cond, SetCc set_cc) {
CHECK_LE(shift_imm, 31u);
- if (setcc) {
- movs(rd, ShifterOperand(rm, LSL, shift_imm), cond);
- } else {
- mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
- }
+ mov(rd, ShifterOperand(rm, LSL, shift_imm), cond, set_cc);
}
void Arm32Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
- bool setcc, Condition cond) {
+ Condition cond, SetCc set_cc) {
CHECK(1u <= shift_imm && shift_imm <= 32u);
if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
- if (setcc) {
- movs(rd, ShifterOperand(rm, LSR, shift_imm), cond);
- } else {
- mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
- }
+ mov(rd, ShifterOperand(rm, LSR, shift_imm), cond, set_cc);
}
void Arm32Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
- bool setcc, Condition cond) {
+ Condition cond, SetCc set_cc) {
CHECK(1u <= shift_imm && shift_imm <= 32u);
if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
- if (setcc) {
- movs(rd, ShifterOperand(rm, ASR, shift_imm), cond);
- } else {
- mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
- }
+ mov(rd, ShifterOperand(rm, ASR, shift_imm), cond, set_cc);
}
void Arm32Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
- bool setcc, Condition cond) {
+ Condition cond, SetCc set_cc) {
CHECK(1u <= shift_imm && shift_imm <= 31u);
- if (setcc) {
- movs(rd, ShifterOperand(rm, ROR, shift_imm), cond);
- } else {
- mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
- }
+ mov(rd, ShifterOperand(rm, ROR, shift_imm), cond, set_cc);
}
-void Arm32Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) {
- if (setcc) {
- movs(rd, ShifterOperand(rm, ROR, 0), cond);
- } else {
- mov(rd, ShifterOperand(rm, ROR, 0), cond);
- }
+void Arm32Assembler::Rrx(Register rd, Register rm, Condition cond, SetCc set_cc) {
+ mov(rd, ShifterOperand(rm, ROR, 0), cond, set_cc);
}
void Arm32Assembler::Lsl(Register rd, Register rm, Register rn,
- bool setcc, Condition cond) {
- if (setcc) {
- movs(rd, ShifterOperand(rm, LSL, rn), cond);
- } else {
- mov(rd, ShifterOperand(rm, LSL, rn), cond);
- }
+ Condition cond, SetCc set_cc) {
+ mov(rd, ShifterOperand(rm, LSL, rn), cond, set_cc);
}
void Arm32Assembler::Lsr(Register rd, Register rm, Register rn,
- bool setcc, Condition cond) {
- if (setcc) {
- movs(rd, ShifterOperand(rm, LSR, rn), cond);
- } else {
- mov(rd, ShifterOperand(rm, LSR, rn), cond);
- }
+ Condition cond, SetCc set_cc) {
+ mov(rd, ShifterOperand(rm, LSR, rn), cond, set_cc);
}
void Arm32Assembler::Asr(Register rd, Register rm, Register rn,
- bool setcc, Condition cond) {
- if (setcc) {
- movs(rd, ShifterOperand(rm, ASR, rn), cond);
- } else {
- mov(rd, ShifterOperand(rm, ASR, rn), cond);
- }
+ Condition cond, SetCc set_cc) {
+ mov(rd, ShifterOperand(rm, ASR, rn), cond, set_cc);
}
void Arm32Assembler::Ror(Register rd, Register rm, Register rn,
- bool setcc, Condition cond) {
- if (setcc) {
- movs(rd, ShifterOperand(rm, ROR, rn), cond);
- } else {
- mov(rd, ShifterOperand(rm, ROR, rn), cond);
- }
+ Condition cond, SetCc set_cc) {
+ mov(rd, ShifterOperand(rm, ROR, rn), cond, set_cc);
}
void Arm32Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR
@@ -1434,24 +1366,24 @@
Condition cond) {
ShifterOperand shifter_op;
if (ShifterOperandCanHoldArm32(value, &shifter_op)) {
- adds(rd, rn, shifter_op, cond);
+ add(rd, rn, shifter_op, cond, kCcSet);
} else if (ShifterOperandCanHoldArm32(-value, &shifter_op)) {
- subs(rd, rn, shifter_op, cond);
+ sub(rd, rn, shifter_op, cond, kCcSet);
} else {
CHECK(rn != IP);
if (ShifterOperandCanHoldArm32(~value, &shifter_op)) {
mvn(IP, shifter_op, cond);
- adds(rd, rn, ShifterOperand(IP), cond);
+ add(rd, rn, ShifterOperand(IP), cond, kCcSet);
} else if (ShifterOperandCanHoldArm32(~(-value), &shifter_op)) {
mvn(IP, shifter_op, cond);
- subs(rd, rn, ShifterOperand(IP), cond);
+ sub(rd, rn, ShifterOperand(IP), cond, kCcSet);
} else {
movw(IP, Low16Bits(value), cond);
uint16_t value_high = High16Bits(value);
if (value_high != 0) {
movt(IP, value_high, cond);
}
- adds(rd, rn, ShifterOperand(IP), cond);
+ add(rd, rn, ShifterOperand(IP), cond, kCcSet);
}
}
}