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