Fix x86 type conversions. test-art-host-oat passes.

- test-art-host-oat enabled in test builds.

- Created inline versions of float-to-int and double-to-int.

- Fixed calls to helper functions for long-to-float/double and
  float/double-to-long.

- Removed storePair and replaced its use with storeBaseDispWide (fixes
  iput-wide and aput-wide with doubles).

- Renamed helper functions to have art_ prefix.

- Fixed move-exception to store the result back.

- Fixed floating point comparison when the destination reg is the same as
  a source. The typing would get confused since the source is floating
  point, but the result is int, and a clobber is needed to overwrite the
  expected result type. A similar thing happens in float/double-to-int.

Change-Id: I0a876072254411aa42d6acadb8723be030727219
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 14eaf1d..c9ba285 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -1060,7 +1060,7 @@
       if (isVolatile) {
         oatGenMemBarrier(cUnit, kST);
       }
-      storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
+      storeBaseDispWide(cUnit, regPtr, 0, rlSrc.lowReg, rlSrc.highReg);
       if (isVolatile) {
         oatGenMemBarrier(cUnit, kSY);
       }
@@ -1642,7 +1642,7 @@
       oatFreeTemp(cUnit, regLen);
     }
 
-    storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
+    storeBaseDispWide(cUnit, regPtr, 0, rlSrc.lowReg, rlSrc.highReg);
 
     oatFreeTemp(cUnit, regPtr);
   } else {
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index b75b9a8..01ac436 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -225,9 +225,9 @@
       loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
       loadConstant(cUnit, resetReg, 0);
       storeWordDisp(cUnit, rSELF, exOffset, resetReg);
-      storeValue(cUnit, rlDest, rlResult);
       oatFreeTemp(cUnit, resetReg);
 #endif
+      storeValue(cUnit, rlDest, rlResult);
       break;
     }
     case Instruction::RETURN_VOID:
diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc
index 533f8b4..67f7938 100644
--- a/src/compiler/codegen/arm/Thumb2/Factory.cc
+++ b/src/compiler/codegen/arm/Thumb2/Factory.cc
@@ -1009,11 +1009,6 @@
   return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
 }
 
-void storePair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
-{
-  storeBaseDispWide(cUnit, base, 0, lowReg, highReg);
-}
-
 void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
 {
   loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc
index 0a7dd9d..8b6f185 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/Mips32/Factory.cc
@@ -40,8 +40,6 @@
 #endif
 
 void genBarrier(CompilationUnit *cUnit);
-void storePair(CompilationUnit *cUnit, int base, int lowReg,
-               int highReg);
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
 LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
                       int rDest);
@@ -742,12 +740,6 @@
   return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
 }
 
-void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
-{
-  storeWordDisp(cUnit, base, LOWORD_OFFSET, lowReg);
-  storeWordDisp(cUnit, base, HIWORD_OFFSET, highReg);
-}
-
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
 {
   loadWordDisp(cUnit, base, LOWORD_OFFSET , lowReg);
diff --git a/src/compiler/codegen/x86/FP/X86FP.cc b/src/compiler/codegen/x86/FP/X86FP.cc
index 7c27eae..24cd7d3 100644
--- a/src/compiler/codegen/x86/FP/X86FP.cc
+++ b/src/compiler/codegen/x86/FP/X86FP.cc
@@ -124,7 +124,9 @@
   RegLocation rlDest;
   X86OpCode op = kX86Nop;
   int srcReg;
+  int tempReg;
   RegLocation rlResult;
+  LIR* branch = NULL;
   switch (opcode) {
     case Instruction::INT_TO_FLOAT:
       longSrc = false;
@@ -151,14 +153,45 @@
       op = kX86Cvtsi2sdRR;
       break;
     case Instruction::FLOAT_TO_INT:
+      rlSrc = oatGetSrc(cUnit, mir, 0);
+      rlSrc = loadValue(cUnit, rlSrc, kFPReg);
+      srcReg = rlSrc.lowReg;
+      rlDest = oatGetDest(cUnit, mir, 0);
+      oatClobberSReg(cUnit, rlDest.sRegLow);
+      rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+      tempReg = oatAllocTempFloat(cUnit);
+
+      loadConstant(cUnit, rlResult.lowReg, 0x7fffffff);
+      newLIR2(cUnit, kX86Cvtsi2ssRR, tempReg, rlResult.lowReg);
+      newLIR2(cUnit, kX86ComissRR, srcReg, tempReg);
+      branch = newLIR2(cUnit, kX86Jcc8, 0, kX86CondA);
+      newLIR2(cUnit, kX86Cvtss2siRR, rlResult.lowReg, srcReg);
+      branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+      storeValue(cUnit, rlDest, rlResult);
+      return false;
     case Instruction::DOUBLE_TO_INT:
-      // These are easy to implement inline except when the src is > MAX_INT/LONG the result
-      // needs to be changed from 0x80000000 to 0x7FFFFFF (requires an in memory float/double
-      // literal constant to compare against).
-      UNIMPLEMENTED(WARNING) << "inline [df]2i " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
+      rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+      rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
+      srcReg = rlSrc.lowReg;
+      rlDest = oatGetDest(cUnit, mir, 0);
+      oatClobberSReg(cUnit, rlDest.sRegLow);
+      rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+      tempReg = oatAllocTempDouble(cUnit);
+
+      loadConstant(cUnit, rlResult.lowReg, 0x7fffffff);
+      newLIR2(cUnit, kX86Cvtsi2sdRR, tempReg, rlResult.lowReg);
+      newLIR2(cUnit, kX86ComisdRR, srcReg, tempReg);
+      branch = newLIR2(cUnit, kX86Jcc8, 0, kX86CondA);
+      newLIR2(cUnit, kX86Cvtsd2siRR, rlResult.lowReg, srcReg);
+      branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+      storeValue(cUnit, rlDest, rlResult);
+      return false;
     case Instruction::LONG_TO_DOUBLE:
-    case Instruction::FLOAT_TO_LONG:
     case Instruction::LONG_TO_FLOAT:
+      // These can be implemented inline by using memory as a 64-bit source.
+      // However, this can't be done easily if the register has been promoted.
+      UNIMPLEMENTED(WARNING) << "inline l2[df] " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
+    case Instruction::FLOAT_TO_LONG:
     case Instruction::DOUBLE_TO_LONG:
       return genConversionPortable(cUnit, mir);
     default:
@@ -205,6 +238,7 @@
     rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
     srcReg2 = S2D(rlSrc2.lowReg, rlSrc2.highReg);
   }
+  oatClobberSReg(cUnit, rlDest.sRegLow);
   RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
   loadConstantNoClobber(cUnit, rlResult.lowReg, unorderedGt ? 1 : 0);
   if (single) {
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc
index c3fb6a6..3698d2d 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -47,8 +47,6 @@
 };
 
 void genBarrier(CompilationUnit *cUnit);
-void storePair(CompilationUnit *cUnit, int base, int lowReg,
-               int highReg);
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
 LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
                       int rDest);
@@ -676,12 +674,6 @@
                               rSrcLo, rSrcHi, kLong, INVALID_SREG);
 }
 
-void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
-{
-  storeWordDisp(cUnit, base, 0, lowReg);
-  storeWordDisp(cUnit, base, 4, highReg);
-}
-
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
 {
   loadWordDisp(cUnit, base, 0, lowReg);