Allow X86 QBE to be extended
Enhancements and updates to allow X86Mir2LIR Backend to be subclassed
for experimentation. Add virtual in a whole bunch of places, and make
some other changes to get this to work.
Change-Id: I0980a19bc5d5725f91660f98c95f1f51c17ee9b6
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 71a3962..a6ccc99 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -1292,8 +1292,12 @@
case Instruction::AND_LONG_2ADDR:
case Instruction::OR_LONG_2ADDR:
case Instruction::XOR_LONG_2ADDR:
- GenLongArith(rl_dest, rl_src2, op);
- return;
+ if (GenerateTwoOperandInstructions()) {
+ GenLongArith(rl_dest, rl_src2, op);
+ return;
+ }
+ break;
+
default:
break;
}
@@ -1532,7 +1536,7 @@
RegLocation X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src, int shift_amount) {
- RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
+ RegLocation rl_result = EvalLocWide(rl_dest, kCoreReg, true);
switch (opcode) {
case Instruction::SHL_LONG:
case Instruction::SHL_LONG_2ADDR:
@@ -1641,7 +1645,11 @@
case Instruction::XOR_LONG_2ADDR:
case Instruction::AND_LONG_2ADDR:
if (rl_src2.is_const) {
- GenLongImm(rl_dest, rl_src2, opcode);
+ if (GenerateTwoOperandInstructions()) {
+ GenLongImm(rl_dest, rl_src2, opcode);
+ } else {
+ GenLongLongImm(rl_dest, rl_src1, rl_src2, opcode);
+ }
} else {
DCHECK(rl_src1.is_const);
GenLongLongImm(rl_dest, rl_src2, rl_src1, opcode);
@@ -1869,7 +1877,7 @@
// SETcc only works with EAX..EDX.
if (result_reg == object.reg || result_reg.GetRegNum() >= rs_rX86_SP.GetRegNum()) {
- result_reg = AllocTypedTemp(false, kCoreReg);
+ result_reg = AllocateByteRegister();
DCHECK_LT(result_reg.GetRegNum(), rs_rX86_SP.GetRegNum());
}
@@ -2110,12 +2118,16 @@
LOG(FATAL) << "Invalid word arith op: " << opcode;
}
- // Can we convert to a two address instruction?
+ // Can we convert to a two address instruction?
if (!is_two_addr &&
(mir_graph_->SRegToVReg(rl_dest.s_reg_low) ==
mir_graph_->SRegToVReg(rl_lhs.s_reg_low))) {
- is_two_addr = true;
- }
+ is_two_addr = true;
+ }
+
+ if (!GenerateTwoOperandInstructions()) {
+ is_two_addr = false;
+ }
// Get the div/rem stuff out of the way.
if (is_div_rem) {
@@ -2212,6 +2224,8 @@
if (mir_graph_->SRegToVReg(rl_dest.s_reg_low) == mir_graph_->SRegToVReg(rl_lhs.s_reg_low)) {
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
+ // No-op if these are the same.
+ OpRegCopy(rl_result.reg, rl_lhs.reg);
} else {
rl_result = EvalLoc(rl_dest, kCoreReg, true);
LoadValueDirect(rl_lhs, rl_result.reg);