diff options
author | Serban Constantinescu <serban.constantinescu@arm.com> | 2013-06-17 16:54:53 +0100 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2014-02-02 02:03:34 -0800 |
commit | eadd85e3c0eceb448f4afb55ab6ef4b5f3b7736a (patch) | |
tree | 784f592f12ec619853eb37457aeb397bd39e85dd | |
parent | bccafaba53f33e5abb36b1f18891dbc5aba228f2 (diff) | |
download | android_dalvik-eadd85e3c0eceb448f4afb55ab6ef4b5f3b7736a.tar.gz android_dalvik-eadd85e3c0eceb448f4afb55ab6ef4b5f3b7736a.tar.bz2 android_dalvik-eadd85e3c0eceb448f4afb55ab6ef4b5f3b7736a.zip |
Dalvik: Add hardware vfp support for OP_LONG_TO_DOUBLE in JIT
The following patch adds hardware vfp support for OP_LONG_TO_DOUBLE
in the JIT. Previously this opcode was implemented using one of gcc's
builtin helpers.
Change-Id: I3c88b2a527dea99dcefdb34be6695e75993da73e
Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
-rw-r--r-- | vm/compiler/codegen/arm/ArmLIR.h | 6 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Assemble.cpp | 12 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/FP/Thumb2VFP.cpp | 25 |
3 files changed, 43 insertions, 0 deletions
diff --git a/vm/compiler/codegen/arm/ArmLIR.h b/vm/compiler/codegen/arm/ArmLIR.h index 96c0ab9e8..9b404af6a 100644 --- a/vm/compiler/codegen/arm/ArmLIR.h +++ b/vm/compiler/codegen/arm/ArmLIR.h @@ -433,6 +433,8 @@ typedef enum ArmOpcode { rd[15-12] [10100000] rm[3..0] */ kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16] rd[15-12] [10110000] rm[3..0] */ + kThumb2VmlaF64, /* vmla.F64 vd, vn, vm [111011100000] vn[19..16] + vd[15..12] [10110000] vm[3..0] */ kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12] [10101100] vm[3..0] */ kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12] @@ -445,6 +447,10 @@ typedef enum ArmOpcode { [10101100] vm[3..0] */ kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12] [10111100] vm[3..0] */ + kThumb2VcvtF64S32, /* vcvt.F64.S32 vd, vm [1110111010111000] vd[15..12] + [10111100] vm[3..0] */ + kThumb2VcvtF64U32, /* vcvt.F64.U32 vd, vm [1110111010111000] vd[15..12] + [10110100] vm[3..0] */ kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12] [10101100] vm[3..0] */ kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12] diff --git a/vm/compiler/codegen/arm/Assemble.cpp b/vm/compiler/codegen/arm/Assemble.cpp index 9dfc1ffec..5cc35cc79 100644 --- a/vm/compiler/codegen/arm/Assemble.cpp +++ b/vm/compiler/codegen/arm/Assemble.cpp @@ -447,6 +447,10 @@ ArmEncodingMap EncodingMap[kArmLast] = { kFmtDfp, 22, 12, kFmtDfp, 7, 16, kFmtDfp, 5, 0, kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12, "vdivd", "!0S, !1S, !2S", 2), + ENCODING_MAP(kThumb2VmlaF64, 0xee000b00, + kFmtDfp, 22, 12, kFmtDfp, 7, 16, kFmtDfp, 5, 0, + kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0 | REG_USE012, + "vmla", "!0S, !1S, !2S", 2), ENCODING_MAP(kThumb2VcvtIF, 0xeeb80ac0, kFmtSfp, 22, 12, kFmtSfp, 5, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE1, @@ -471,6 +475,14 @@ ArmEncodingMap EncodingMap[kArmLast] = { kFmtSfp, 22, 12, kFmtDfp, 5, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE1, "vcvt.f32.f64 ", "!0s, !1S", 2), + ENCODING_MAP(kThumb2VcvtF64S32, 0xeeb80bc0, + kFmtDfp, 22, 12, kFmtSfp, 5, 0, kFmtUnused, -1, -1, + kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE1, + "vcvt.f64.s32 ", "!0S, !1s", 2), + ENCODING_MAP(kThumb2VcvtF64U32, 0xeeb80b40, + kFmtDfp, 22, 12, kFmtSfp, 5, 0, kFmtUnused, -1, -1, + kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE1, + "vcvt.f64.u32 ", "!0S, !1s", 2), ENCODING_MAP(kThumb2Vsqrts, 0xeeb10ac0, kFmtSfp, 22, 12, kFmtSfp, 5, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0_USE1, diff --git a/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp b/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp index 750cbdc19..0ee1b8fb5 100644 --- a/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp +++ b/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp @@ -108,6 +108,30 @@ static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, return false; } +static bool genConversionL2D(CompilationUnit *cUnit, MIR *mir) +{ + int srcReg, tmp1, tmp2; + RegLocation rlSrc; + RegLocation rlDest; + RegLocation rlResult; + + rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); + rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); + srcReg = S2D(rlSrc.lowReg, rlSrc.highReg); + rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1); + rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true); + tmp1 = dvmCompilerAllocTypedTempPair(cUnit, true, kFPReg); + tmp2 = dvmCompilerAllocTypedTempPair(cUnit, true, kFPReg); + newLIR2(cUnit, (ArmOpcode)kThumb2VcvtF64S32, tmp1, ((srcReg & 0xff)+1)); + newLIR2(cUnit, (ArmOpcode)kThumb2VcvtF64U32, S2D(rlResult.lowReg, rlResult.highReg), + (srcReg & 0xff)); + loadConstantValueWide(cUnit, (tmp2 & 0xff), ((tmp2 >> 8) & 0xff), 0x0, 0x41f00000); + newLIR3(cUnit, (ArmOpcode)kThumb2VmlaF64, S2D(rlResult.lowReg, rlResult.highReg), + tmp1, tmp2); + storeValueWide(cUnit, rlDest, rlResult); + return false; +} + static bool genConversion(CompilationUnit *cUnit, MIR *mir) { Opcode opcode = mir->dalvikInsn.opcode; @@ -151,6 +175,7 @@ static bool genConversion(CompilationUnit *cUnit, MIR *mir) op = kThumb2VcvtDI; break; case OP_LONG_TO_DOUBLE: + return genConversionL2D(cUnit, mir); case OP_FLOAT_TO_LONG: case OP_LONG_TO_FLOAT: case OP_DOUBLE_TO_LONG: |