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);