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/Android.mk b/Android.mk
index cd96c52..fe70b0c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,7 +76,7 @@
 	@echo test-art-gtest PASSED
 
 .PHONY: test-art-oat
-test-art-oat: test-art-target-oat # test-art-host-oat
+test-art-oat: test-art-target-oat test-art-host-oat
 	@echo test-art-oat PASSED
 
 ########################################################################
@@ -84,7 +84,7 @@
 
 # "mm test-art-host" to build and run all host tests
 .PHONY: test-art-host
-test-art-host: test-art-host-gtest # test-art-host-oat # test-art-host-run-test
+test-art-host: test-art-host-gtest test-art-host-oat # test-art-host-run-test
 	@echo test-art-host PASSED
 
 .PHONY: test-art-host-dependencies
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);
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index a2da2b6..caef683 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -160,10 +160,10 @@
 ; Math
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-declare i64 @D2L(double)
-declare i32 @D2I(double)
-declare i64 @F2L(float)
-declare i32 @F2I(float)
+declare i64 @art_d2l(double)
+declare i32 @art_d2i(double)
+declare i64 @art_f2l(float)
+declare i32 @art_f2i(float)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary runtime support, will be removed in the future
diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc
index b3963ef..cd93542 100644
--- a/src/compiler_llvm/generated/art_module.cc
+++ b/src/compiler_llvm/generated/art_module.cc
@@ -911,49 +911,49 @@
 AttrListPtr func_art_check_put_array_element_from_code_PAL;
 func_art_check_put_array_element_from_code->setAttributes(func_art_check_put_array_element_from_code_PAL);
 
-Function* func_D2L = mod->getFunction("D2L");
-if (!func_D2L) {
-func_D2L = Function::Create(
+Function* func_art_d2l = mod->getFunction("art_d2l");
+if (!func_art_d2l) {
+func_art_d2l = Function::Create(
  /*Type=*/FuncTy_31,
  /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"D2L", mod); // (external, no body)
-func_D2L->setCallingConv(CallingConv::C);
+ /*Name=*/"art_d2l", mod); // (external, no body)
+func_art_d2l->setCallingConv(CallingConv::C);
 }
-AttrListPtr func_D2L_PAL;
-func_D2L->setAttributes(func_D2L_PAL);
+AttrListPtr func_art_d2l_PAL;
+func_art_d2l->setAttributes(func_art_d2l_PAL);
 
-Function* func_D2I = mod->getFunction("D2I");
-if (!func_D2I) {
-func_D2I = Function::Create(
+Function* func_art_d2i = mod->getFunction("art_d2i");
+if (!func_art_d2i) {
+func_art_d2i = Function::Create(
  /*Type=*/FuncTy_32,
  /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"D2I", mod); // (external, no body)
-func_D2I->setCallingConv(CallingConv::C);
+ /*Name=*/"art_d2i", mod); // (external, no body)
+func_art_d2i->setCallingConv(CallingConv::C);
 }
-AttrListPtr func_D2I_PAL;
-func_D2I->setAttributes(func_D2I_PAL);
+AttrListPtr func_art_d2i_PAL;
+func_art_d2i->setAttributes(func_art_d2i_PAL);
 
-Function* func_F2L = mod->getFunction("F2L");
-if (!func_F2L) {
-func_F2L = Function::Create(
+Function* func_art_f2l = mod->getFunction("art_f2l");
+if (!func_art_f2l) {
+func_art_f2l = Function::Create(
  /*Type=*/FuncTy_33,
  /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"F2L", mod); // (external, no body)
-func_F2L->setCallingConv(CallingConv::C);
+ /*Name=*/"art_f2l", mod); // (external, no body)
+func_art_f2l->setCallingConv(CallingConv::C);
 }
-AttrListPtr func_F2L_PAL;
-func_F2L->setAttributes(func_F2L_PAL);
+AttrListPtr func_art_f2l_PAL;
+func_art_f2l->setAttributes(func_art_f2l_PAL);
 
-Function* func_F2I = mod->getFunction("F2I");
-if (!func_F2I) {
-func_F2I = Function::Create(
+Function* func_art_f2i = mod->getFunction("art_f2i");
+if (!func_art_f2i) {
+func_art_f2i = Function::Create(
  /*Type=*/FuncTy_34,
  /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"F2I", mod); // (external, no body)
-func_F2I->setCallingConv(CallingConv::C);
+ /*Name=*/"art_f2i", mod); // (external, no body)
+func_art_f2i->setCallingConv(CallingConv::C);
 }
-AttrListPtr func_F2I_PAL;
-func_F2I->setAttributes(func_F2I_PAL);
+AttrListPtr func_art_f2i_PAL;
+func_art_f2i->setAttributes(func_art_f2i_PAL);
 
 Function* func_art_mark_gc_card_from_code = mod->getFunction("art_mark_gc_card_from_code");
 if (!func_art_mark_gc_card_from_code) {
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 3f3e0ad..3f640ee 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -801,11 +801,11 @@
     break;
 
   case Instruction::FLOAT_TO_INT:
-    EmitInsn_FPToInt(ARGS, kFloat, kInt, F2I);
+    EmitInsn_FPToInt(ARGS, kFloat, kInt, art_f2i);
     break;
 
   case Instruction::FLOAT_TO_LONG:
-    EmitInsn_FPToInt(ARGS, kFloat, kLong, F2L);
+    EmitInsn_FPToInt(ARGS, kFloat, kLong, art_f2l);
     break;
 
   case Instruction::FLOAT_TO_DOUBLE:
@@ -813,11 +813,11 @@
     break;
 
   case Instruction::DOUBLE_TO_INT:
-    EmitInsn_FPToInt(ARGS, kDouble, kInt, D2I);
+    EmitInsn_FPToInt(ARGS, kDouble, kInt, art_d2i);
     break;
 
   case Instruction::DOUBLE_TO_LONG:
-    EmitInsn_FPToInt(ARGS, kDouble, kLong, D2L);
+    EmitInsn_FPToInt(ARGS, kDouble, kLong, art_d2l);
     break;
 
   case Instruction::DOUBLE_TO_FLOAT:
diff --git a/src/compiler_llvm/runtime_support_func_list.h b/src/compiler_llvm/runtime_support_func_list.h
index 5cf2374..62729c6 100644
--- a/src/compiler_llvm/runtime_support_func_list.h
+++ b/src/compiler_llvm/runtime_support_func_list.h
@@ -66,7 +66,7 @@
   V(FixStub, art_fix_stub_from_code) \
   V(ProxyInvokeHandler, art_proxy_invoke_handler_from_code) \
   V(DecodeJObjectInThread, art_decode_jobject_in_thread) \
-  V(D2L, D2L) \
-  V(D2I, D2I) \
-  V(F2L, F2L) \
-  V(F2I, F2I)
+  V(art_d2l, art_d2l) \
+  V(art_d2i, art_d2i) \
+  V(art_f2l, art_f2l) \
+  V(art_f2i, art_f2i)
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index b0d59ea..a31c27e 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -595,7 +595,7 @@
 #undef EXTERNAL_LINKAGE
 
 static void* art_find_compiler_runtime_func(char const* name) {
-// TODO: If target support some math func, use the target's version. (e.g. D2I -> __aeabi_d2iz)
+// TODO: If target support some math func, use the target's version. (e.g. art_d2i -> __aeabi_d2iz)
   static const char* const names[] = {
 #define DEFINE_ENTRY(NAME) #NAME ,
 #include "compiler_runtime_func_list.h"
diff --git a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
index be390e9..d26a11d 100644
--- a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
+++ b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "runtime_support.h"
 #include "oat/runtime/oat_support_entrypoints.h"
 
 namespace art {
@@ -81,8 +82,6 @@
 extern "C" int32_t __aeabi_d2iz(double op1);       // DOUBLE_TO_INT
 extern "C" float __aeabi_l2f(int64_t op1);         // LONG_TO_FLOAT
 extern "C" double __aeabi_l2d(int64_t op1);        // LONG_TO_DOUBLE
-extern int64_t D2L(double d);
-extern int64_t F2L(float f);
 
 // Single-precision FP arithmetics.
 extern "C" float __aeabi_fadd(float a, float b);   // ADD_FLOAT[_2ADDR]
@@ -214,8 +213,8 @@
   points->pD2iz = __aeabi_d2iz;
   points->pF2iz = __aeabi_f2iz;
   points->pIdivmod = __aeabi_idivmod;
-  points->pD2l = D2L;
-  points->pF2l = F2L;
+  points->pD2l = art_d2l;
+  points->pF2l = art_f2l;
   points->pLdiv = __aeabi_ldivmod;
   points->pLdivmod = __aeabi_ldivmod;  // result returned in r2:r3
   points->pLmul = __aeabi_lmul;
diff --git a/src/oat/runtime/mips/oat_support_entrypoints_mips.cc b/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
index d791632..9b4a46f 100644
--- a/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
+++ b/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "runtime_support.h"
 #include "oat/runtime/oat_support_entrypoints.h"
 
 namespace art {
@@ -83,8 +84,6 @@
 extern "C" double __floatdidf(int64_t op1);   // LONG_TO_DOUBLE
 extern "C" int64_t __fixsfdi(float op1);      // FLOAT_TO_LONG
 extern "C" int64_t __fixdfdi(double op1);     // DOUBLE_TO_LONG
-extern int64_t D2L(double d);
-extern int64_t F2L(float f);
 
 // Single-precision FP arithmetics.
 extern "C" float __addsf3(float a, float b);   // ADD_FLOAT[_2ADDR]
@@ -213,8 +212,8 @@
   points->pD2iz = __fixdfsi;
   points->pF2iz = __fixsfi;
   points->pIdivmod = NULL;
-  points->pD2l = D2L;
-  points->pF2l = F2L;
+  points->pD2l = art_d2l;
+  points->pF2l = art_f2l;
   points->pLdiv = NULL;
   points->pLdivmod = NULL;
   points->pLmul = NULL;
diff --git a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
index 95b479b..605024e 100644
--- a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
+++ b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
@@ -67,10 +67,10 @@
 extern "C" void art_unlock_object_from_code(void*);
 
 // Math entrypoints.
-extern int32_t CmpgDouble(double a, double b);
-extern int32_t CmplDouble(double a, double b);
-extern int32_t CmpgFloat(float a, float b);
-extern int32_t CmplFloat(float a, float b);
+extern "C" double art_l2d_from_code(int64_t);
+extern "C" float art_l2f_from_code(int64_t);
+extern "C" int64_t art_d2l_from_code(double);
+extern "C" int64_t art_f2l_from_code(float);
 extern "C" int32_t art_idivmod_from_code(int32_t, int32_t);
 extern "C" int64_t art_ldiv_from_code(int64_t, int64_t);
 extern "C" int64_t art_ldivmod_from_code(int64_t, int64_t);
@@ -159,10 +159,10 @@
   points->pUnlockObjectFromCode = art_unlock_object_from_code;
 
   // Math
-  points->pCmpgDouble = CmpgDouble;
-  points->pCmpgFloat = CmpgFloat;
-  points->pCmplDouble = CmplDouble;
-  points->pCmplFloat = CmplFloat;
+  //points->pCmpgDouble = NULL; // Not needed on x86.
+  //points->pCmpgFloat = NULL; // Not needed on x86.
+  //points->pCmplDouble = NULL; // Not needed on x86.
+  //points->pCmplFloat = NULL; // Not needed on x86.
   //points->pDadd = NULL; // Not needed on x86.
   //points->pDdiv = NULL; // Not needed on x86.
   //points->pDmul = NULL; // Not needed on x86.
@@ -170,7 +170,7 @@
   //points->pF2d = NULL;
   //points->pFmod = NULL;
   //points->pI2d = NULL;
-  //points->pL2d = NULL;
+  points->pL2d = art_l2d_from_code;
   //points->pD2f = NULL;
   //points->pFadd = NULL; // Not needed on x86.
   //points->pFdiv = NULL; // Not needed on x86.
@@ -178,12 +178,12 @@
   //points->pFmul = NULL; // Not needed on x86.
   //points->pFsub = NULL; // Not needed on x86.
   //points->pI2f = NULL;
-  //points->pL2f = NULL;
-  points->pD2iz = D2I;
-  points->pF2iz = F2I;
+  points->pL2f = art_l2f_from_code;
+  //points->pD2iz = NULL; // Not needed on x86.
+  //points->pF2iz = NULL; // Not needed on x86.
   points->pIdivmod = art_idivmod_from_code;
-  points->pD2l = D2L;
-  points->pF2l = F2L;
+  points->pD2l = art_d2l_from_code;
+  points->pF2l = art_f2l_from_code;
   points->pLdiv = art_ldiv_from_code;
   points->pLdivmod = art_ldivmod_from_code;
   points->pLmul = art_lmul_from_code;
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index 9164800..028d7ec 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -395,6 +395,41 @@
 
 NO_ARG_DOWNCALL art_test_suspend, artTestSuspendFromCode, ret
 
+DEFINE_FUNCTION art_l2d_from_code
+    pushl %eax                    // alignment padding
+    pushl %ecx                    // pass arg2
+    pushl %eax                    // pass arg1
+    call SYMBOL(art_l2d) // (jlong a, Thread*, SP)
+    fstpl (%esp)                  // get return value
+    movsd (%esp), %xmm0           // place into %xmm0
+    addl LITERAL(12), %esp        // pop arguments
+    ret
+
+DEFINE_FUNCTION art_l2f_from_code
+    pushl %eax                    // alignment padding
+    pushl %ecx                    // pass arg2
+    pushl %eax                    // pass arg1
+    call SYMBOL(art_l2f) // (jlong a, Thread*, SP)
+    fstp  (%esp)                  // get return value
+    movss (%esp), %xmm0           // place into %xmm0
+    addl LITERAL(12), %esp        // pop arguments
+    ret
+
+DEFINE_FUNCTION art_d2l_from_code
+    pushl %eax                    // alignment padding
+    pushl %ecx                    // pass arg2
+    pushl %eax                    // pass arg1
+    call SYMBOL(art_d2l) // (jdouble a, Thread*, SP)
+    addl LITERAL(12), %esp        // pop arguments
+    ret
+
+DEFINE_FUNCTION art_f2l_from_code
+    subl LITERAL(8), %esp         // alignment padding
+    pushl %eax                    // pass arg1
+    call SYMBOL(art_f2l) // (jfloat a, Thread*, SP)
+    addl LITERAL(12), %esp        // pop arguments
+    ret
+
 DEFINE_FUNCTION art_idivmod_from_code
     cmpl LITERAL(0x80000000), %eax
     je check_arg2  // special case
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 1152c79..f8b40a2 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -18,13 +18,19 @@
 
 #include "ScopedLocalRef.h"
 
-namespace art {
+double art_l2d(int64_t l) {
+  return (double) l;
+}
+
+float art_l2f(int64_t l) {
+  return (float) l;
+}
 
 /*
  * Float/double conversion requires clamping to min and max of integer form.  If
  * target doesn't support this normally, use these.
  */
-int64_t D2L(double d) {
+int64_t art_d2l(double d) {
   static const double kMaxLong = (double) (int64_t) 0x7fffffffffffffffULL;
   static const double kMinLong = (double) (int64_t) 0x8000000000000000ULL;
   if (d >= kMaxLong) {
@@ -38,7 +44,7 @@
   }
 }
 
-int64_t F2L(float f) {
+int64_t art_f2l(float f) {
   static const float kMaxLong = (float) (int64_t) 0x7fffffffffffffffULL;
   static const float kMinLong = (float) (int64_t) 0x8000000000000000ULL;
   if (f >= kMaxLong) {
@@ -52,7 +58,7 @@
   }
 }
 
-int32_t D2I(double d) {
+int32_t art_d2i(double d) {
   static const double kMaxInt = (double) (int32_t) 0x7fffffffUL;
   static const double kMinInt = (double) (int32_t) 0x80000000UL;
   if (d >= kMaxInt) {
@@ -66,7 +72,7 @@
   }
 }
 
-int32_t F2I(float f) {
+int32_t art_f2i(float f) {
   static const float kMaxInt = (float) (int32_t) 0x7fffffffUL;
   static const float kMinInt = (float) (int32_t) 0x80000000UL;
   if (f >= kMaxInt) {
@@ -80,6 +86,8 @@
   }
 }
 
+namespace art {
+
 void ThrowNewIllegalAccessErrorClass(Thread* self,
                                      Class* referrer,
                                      Class* accessed) {
diff --git a/src/runtime_support.h b/src/runtime_support.h
index 0fb1b2b..50b6735 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -28,6 +28,13 @@
 extern "C" void art_proxy_invoke_handler();
 extern "C" void art_work_around_app_jni_bugs();
 
+extern "C" double art_l2d(int64_t l);
+extern "C" float art_l2f(int64_t l);
+extern "C" int64_t art_d2l(double d);
+extern "C" int32_t art_d2i(double d);
+extern "C" int64_t art_f2l(float f);
+extern "C" int32_t art_f2i(float f);
+
 namespace art {
 
 class Array;
@@ -36,11 +43,6 @@
 class Method;
 class Object;
 
-int64_t D2L(double d);
-int32_t D2I(double d);
-int64_t F2L(float f);
-int32_t F2I(float f);
-
 // Helpers to give consistent descriptive exception messages
 void ThrowNewIllegalAccessErrorClass(Thread* self, Class* referrer, Class* accessed);
 void ThrowNewIllegalAccessErrorClassForMethodDispatch(Thread* self, Class* referrer,