GenSpecialCase support for x86

Moved GenSpecialCase from being ARM specific to common code to allow
it to be used by x86 quick as well.

Change-Id: I728733e8f4c4da99af6091ef77e5c76ae0fee850
Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com>
diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc
index 7f646e0..0613cdf 100644
--- a/compiler/dex/quick/x86/call_x86.cc
+++ b/compiler/dex/quick/x86/call_x86.cc
@@ -22,11 +22,6 @@
 
 namespace art {
 
-void X86Mir2Lir::GenSpecialCase(BasicBlock* bb, MIR* mir,
-                                const InlineMethod& special) {
-  // TODO
-}
-
 /*
  * The sparse table in the literal pool is an array of <key,displacement>
  * pairs.
@@ -255,4 +250,8 @@
   NewLIR0(kX86Ret);
 }
 
+void X86Mir2Lir::GenSpecialExitSequence() {
+  NewLIR0(kX86Ret);
+}
+
 }  // namespace art
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 70263d8..6100a1d 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -52,6 +52,7 @@
     int AllocTypedTempPair(bool fp_hint, int reg_class);
     int S2d(int low_reg, int high_reg);
     int TargetReg(SpecialTargetRegister reg);
+    int GetArgMappingToPhysicalReg(int arg_num);
     RegLocation GetReturnAlt();
     RegLocation GetReturnWideAlt();
     RegLocation LocCReturn();
@@ -123,6 +124,7 @@
     void GenDivZeroCheck(int reg_lo, int reg_hi);
     void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method);
     void GenExitSequence();
+    void GenSpecialExitSequence();
     void GenFillArrayData(DexOffset table_offset, RegLocation rl_src);
     void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double);
     void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir);
@@ -135,7 +137,7 @@
     void GenNegFloat(RegLocation rl_dest, RegLocation rl_src);
     void GenPackedSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src);
     void GenSparseSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src);
-    void GenSpecialCase(BasicBlock* bb, MIR* mir, const InlineMethod& special);
+
     /*
      * @brief Generate a two address long operation with a constant value
      * @param rl_dest location of result
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 9dd6116..9eb112b 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -167,7 +167,14 @@
       NewLIR2(kX86MovdrxRR, dest_hi, src_lo);
     } else {
       // Handle overlap
-      if (src_hi == dest_lo) {
+      if (src_hi == dest_lo && src_lo == dest_hi) {
+        // Deal with cycles.
+        int temp_reg = AllocTemp();
+        OpRegCopy(temp_reg, dest_hi);
+        OpRegCopy(dest_hi, dest_lo);
+        OpRegCopy(dest_lo, temp_reg);
+        FreeTemp(temp_reg);
+      } else if (src_hi == dest_lo) {
         OpRegCopy(dest_hi, src_hi);
         OpRegCopy(dest_lo, src_lo);
       } else {
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 1893ffc..8e04e64 100644
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -92,6 +92,21 @@
   return res;
 }
 
+int X86Mir2Lir::GetArgMappingToPhysicalReg(int arg_num) {
+  // For the 32-bit internal ABI, the first 3 arguments are passed in registers.
+  // TODO: This is not 64-bit compliant and depends on new internal ABI.
+  switch (arg_num) {
+    case 0:
+      return rX86_ARG1;
+    case 1:
+      return rX86_ARG2;
+    case 2:
+      return rX86_ARG3;
+    default:
+      return INVALID_REG;
+  }
+}
+
 // Create a double from a pair of singles.
 int X86Mir2Lir::S2d(int low_reg, int high_reg) {
   return X86_S2D(low_reg, high_reg);