summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerban Constantinescu <serban.constantinescu@arm.com>2013-06-17 16:54:53 +0100
committerSteve Kondik <shade@chemlab.org>2014-02-02 02:03:34 -0800
commiteadd85e3c0eceb448f4afb55ab6ef4b5f3b7736a (patch)
tree784f592f12ec619853eb37457aeb397bd39e85dd
parentbccafaba53f33e5abb36b1f18891dbc5aba228f2 (diff)
downloadandroid_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.h6
-rw-r--r--vm/compiler/codegen/arm/Assemble.cpp12
-rw-r--r--vm/compiler/codegen/arm/FP/Thumb2VFP.cpp25
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: