diff options
| author | 2012-05-15 15:50:29 -0700 | |
|---|---|---|
| committer | 2012-05-15 15:50:29 -0700 | |
| commit | bab4283a7a5fa8f739258d6ba4e109f42c31a6a3 (patch) | |
| tree | 24c537ea7b57bbfe7cfb65be2c70ac6c70d3c278 | |
| parent | ce9c317b806aabd7d460a52e1c46f04f7e2c9bb6 (diff) | |
| parent | 41005ddb5576b8630a1084fbb3979ffa602c0599 (diff) | |
Merge "Fix x86 type conversions. test-art-host-oat passes." into ics-mr1-plus-art
| -rw-r--r-- | Android.mk | 4 | ||||
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 4 | ||||
| -rw-r--r-- | src/compiler/codegen/MethodCodegenDriver.cc | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Factory.cc | 5 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/Mips32/Factory.cc | 8 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/FP/X86FP.cc | 44 | ||||
| -rw-r--r-- | src/compiler/codegen/x86/X86/Factory.cc | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/art_module.ll | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/generated/art_module.cc | 56 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_func_list.h | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_llvm.cc | 2 | ||||
| -rw-r--r-- | src/oat/runtime/arm/oat_support_entrypoints_arm.cc | 7 | ||||
| -rw-r--r-- | src/oat/runtime/mips/oat_support_entrypoints_mips.cc | 7 | ||||
| -rw-r--r-- | src/oat/runtime/x86/oat_support_entrypoints_x86.cc | 28 | ||||
| -rw-r--r-- | src/oat/runtime/x86/runtime_support_x86.S | 35 | ||||
| -rw-r--r-- | src/runtime_support.cc | 18 | ||||
| -rw-r--r-- | src/runtime_support.h | 12 |
18 files changed, 160 insertions, 104 deletions
diff --git a/Android.mk b/Android.mk index cd96c5245d..fe70b0c3ba 100644 --- a/Android.mk +++ b/Android.mk @@ -76,7 +76,7 @@ test-art-gtest: test-art-host-gtest test-art-target-gtest @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 @@ test-art-oat: test-art-target-oat # test-art-host-oat # "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 14eaf1db6d..c9ba285c5f 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -1060,7 +1060,7 @@ void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, RegLocation rlSrc, 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 @@ void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size, 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 b75b9a88b9..01ac4361dc 100644 --- a/src/compiler/codegen/MethodCodegenDriver.cc +++ b/src/compiler/codegen/MethodCodegenDriver.cc @@ -225,9 +225,9 @@ bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, 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 533f8b4bcf..67f79387ad 100644 --- a/src/compiler/codegen/arm/Thumb2/Factory.cc +++ b/src/compiler/codegen/arm/Thumb2/Factory.cc @@ -1009,11 +1009,6 @@ LIR* storeBaseDispWide(CompilationUnit* cUnit, int rBase, int displacement, 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 0a7dd9d3ad..8b6f1854da 100644 --- a/src/compiler/codegen/mips/Mips32/Factory.cc +++ b/src/compiler/codegen/mips/Mips32/Factory.cc @@ -40,8 +40,6 @@ static int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, #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 @@ LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, 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 7c27eae0f8..24cd7d31e3 100644 --- a/src/compiler/codegen/x86/FP/X86FP.cc +++ b/src/compiler/codegen/x86/FP/X86FP.cc @@ -124,7 +124,9 @@ static bool genConversion(CompilationUnit *cUnit, MIR *mir) { 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 @@ static bool genConversion(CompilationUnit *cUnit, MIR *mir) { 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 @@ static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, 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 c3fb6a6b4a..3698d2d724 100644 --- a/src/compiler/codegen/x86/X86/Factory.cc +++ b/src/compiler/codegen/x86/X86/Factory.cc @@ -47,8 +47,6 @@ namespace art { }; 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 @@ LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, int displacement, 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 a2da2b6376..caef683d80 100644 --- a/src/compiler_llvm/art_module.ll +++ b/src/compiler_llvm/art_module.ll @@ -160,10 +160,10 @@ declare void @art_check_put_array_element_from_code(%JavaObject*, %JavaObject*) ; 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 b3963ef8dd..cd93542a0b 100644 --- a/src/compiler_llvm/generated/art_module.cc +++ b/src/compiler_llvm/generated/art_module.cc @@ -911,49 +911,49 @@ func_art_check_put_array_element_from_code->setCallingConv(CallingConv::C); 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 3f3e0ad581..3f640eedbe 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -801,11 +801,11 @@ void MethodCompiler::EmitInstruction(uint32_t dex_pc, 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 @@ void MethodCompiler::EmitInstruction(uint32_t dex_pc, 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 5cf237401d..62729c6f92 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 b0d59ea84b..a31c27eefa 100644 --- a/src/compiler_llvm/runtime_support_llvm.cc +++ b/src/compiler_llvm/runtime_support_llvm.cc @@ -595,7 +595,7 @@ COMPILER_RUNTIME_FUNC_LIST(EXTERNAL_LINKAGE) #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 be390e9ac4..d26a11df08 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" double __aeabi_i2d(int32_t op1); // INT_TO_DOUBLE 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 @@ void InitEntryPoints(EntryPoints* points) { 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 d7916329e4..9b4a46fee3 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" float __floatdisf(int64_t op1); // LONG_TO_FLOAT 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 @@ void InitEntryPoints(EntryPoints* points) { 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 95b479b22f..605024e303 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_lock_object_from_code(void*); 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 @@ void InitEntryPoints(EntryPoints* points) { 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 @@ void InitEntryPoints(EntryPoints* points) { //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 @@ void InitEntryPoints(EntryPoints* points) { //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 9164800e79..028d7ec442 100644 --- a/src/oat/runtime/x86/runtime_support_x86.S +++ b/src/oat/runtime/x86/runtime_support_x86.S @@ -395,6 +395,41 @@ TWO_ARG_DOWNCALL art_can_put_array_element_from_code, artCanPutArrayElementFromC 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 1152c79ff1..f8b40a258a 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 D2L(double d) { } } -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 @@ int64_t F2L(float f) { } } -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 D2I(double d) { } } -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 @@ int32_t F2I(float f) { } } +namespace art { + void ThrowNewIllegalAccessErrorClass(Thread* self, Class* referrer, Class* accessed) { diff --git a/src/runtime_support.h b/src/runtime_support.h index 0fb1b2b3bd..50b6735bfe 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 Field; 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, |