diff options
Diffstat (limited to 'vm/compiler/codegen/arm/FP/Thumb2VFP.cpp')
-rw-r--r-- | vm/compiler/codegen/arm/FP/Thumb2VFP.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp b/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp index abbf2c9b4..3ecb38114 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: |