summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/arm/FP
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2014-08-05 12:46:17 -0700
committerBrian Carlstrom <bdc@google.com>2014-08-05 12:51:13 -0700
commit870b4f2d70d67d6dbb7d0881d101c61bed8caad2 (patch)
tree7487dad3970556a040f88a49852a3dc9ed19bebd /vm/compiler/codegen/arm/FP
parent76e15e367ae1189b6f641ba8d16ca92bd179dac0 (diff)
downloadandroid_dalvik-870b4f2d70d67d6dbb7d0881d101c61bed8caad2.tar.gz
android_dalvik-870b4f2d70d67d6dbb7d0881d101c61bed8caad2.tar.bz2
android_dalvik-870b4f2d70d67d6dbb7d0881d101c61bed8caad2.zip
Dalvik is dead, long live Dalvik!
croot cd dalvik repo start dalvik-is-dead-long-live-dalvik . repo sync -c . git rm -r README.txt git rm -r dexopt git rm -r tools/deadcode.py git rm -r tools/dex-preopt git rm -r tools/dexcheck git rm -r tools/gdbjithelper git rm -r unit-tests git rm -r vm git checkout HEAD vm/Common.h (needed by libdex) git checkout HEAD vm/DalvikVersion.h (needed by libdex) git checkout HEAD vm/Profile.h (needed by dmtracedump) git add Android.mk (after removing vm, dexopt, and unit-tests references) git commit -a -m 'Dalvik is dead, long live Dalvik!' Bug: 14298175 Change-Id: I9dd13053677629d13496d4238af4374452cda415
Diffstat (limited to 'vm/compiler/codegen/arm/FP')
-rw-r--r--vm/compiler/codegen/arm/FP/Thumb2VFP.cpp293
-rw-r--r--vm/compiler/codegen/arm/FP/ThumbPortableFP.cpp91
-rw-r--r--vm/compiler/codegen/arm/FP/ThumbVFP.cpp256
3 files changed, 0 insertions, 640 deletions
diff --git a/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp b/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp
deleted file mode 100644
index 3ecb38114..000000000
--- a/vm/compiler/codegen/arm/FP/Thumb2VFP.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2)
-{
- int op = kThumbBkpt;
- RegLocation rlResult;
-
- /*
- * Don't attempt to optimize register usage since these opcodes call out to
- * the handlers.
- */
- switch (mir->dalvikInsn.opcode) {
- case OP_ADD_FLOAT_2ADDR:
- case OP_ADD_FLOAT:
- op = kThumb2Vadds;
- break;
- case OP_SUB_FLOAT_2ADDR:
- case OP_SUB_FLOAT:
- op = kThumb2Vsubs;
- break;
- case OP_DIV_FLOAT_2ADDR:
- case OP_DIV_FLOAT:
- op = kThumb2Vdivs;
- break;
- case OP_MUL_FLOAT_2ADDR:
- case OP_MUL_FLOAT:
- op = kThumb2Vmuls;
- break;
- case OP_REM_FLOAT_2ADDR:
- case OP_REM_FLOAT:
- case OP_NEG_FLOAT: {
- return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1,
- rlSrc2);
- }
- default:
- return true;
- }
- rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
- rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
- rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true);
- newLIR3(cUnit, (ArmOpcode)op, rlResult.lowReg, rlSrc1.lowReg,
- rlSrc2.lowReg);
- storeValue(cUnit, rlDest, rlResult);
- return false;
-}
-
-static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2)
-{
- int op = kThumbBkpt;
- RegLocation rlResult;
-
- switch (mir->dalvikInsn.opcode) {
- case OP_ADD_DOUBLE_2ADDR:
- case OP_ADD_DOUBLE:
- op = kThumb2Vaddd;
- break;
- case OP_SUB_DOUBLE_2ADDR:
- case OP_SUB_DOUBLE:
- op = kThumb2Vsubd;
- break;
- case OP_DIV_DOUBLE_2ADDR:
- case OP_DIV_DOUBLE:
- op = kThumb2Vdivd;
- break;
- case OP_MUL_DOUBLE_2ADDR:
- case OP_MUL_DOUBLE:
- op = kThumb2Vmuld;
- break;
- case OP_REM_DOUBLE_2ADDR:
- case OP_REM_DOUBLE:
- case OP_NEG_DOUBLE: {
- return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1,
- rlSrc2);
- }
- default:
- return true;
- }
-
- rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
- assert(rlSrc1.wide);
- rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
- assert(rlSrc2.wide);
- rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true);
- assert(rlDest.wide);
- assert(rlResult.wide);
- newLIR3(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg),
- S2D(rlSrc1.lowReg, rlSrc1.highReg),
- S2D(rlSrc2.lowReg, rlSrc2.highReg));
- storeValueWide(cUnit, rlDest, rlResult);
- 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;
- int op = kThumbBkpt;
- bool longSrc = false;
- bool longDest = false;
- int srcReg;
- RegLocation rlSrc;
- RegLocation rlDest;
- RegLocation rlResult;
-
- switch (opcode) {
- case OP_INT_TO_FLOAT:
- longSrc = false;
- longDest = false;
- op = kThumb2VcvtIF;
- break;
- case OP_FLOAT_TO_INT:
- longSrc = false;
- longDest = false;
- op = kThumb2VcvtFI;
- break;
- case OP_DOUBLE_TO_FLOAT:
- longSrc = true;
- longDest = false;
- op = kThumb2VcvtDF;
- break;
- case OP_FLOAT_TO_DOUBLE:
- longSrc = false;
- longDest = true;
- op = kThumb2VcvtFd;
- break;
- case OP_INT_TO_DOUBLE:
- longSrc = false;
- longDest = true;
- op = kThumb2VcvtID;
- break;
- case OP_DOUBLE_TO_INT:
- longSrc = true;
- longDest = false;
- 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:
- return genConversionPortable(cUnit, mir);
- default:
- return true;
- }
- if (longSrc) {
- rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
- rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
- srcReg = S2D(rlSrc.lowReg, rlSrc.highReg);
- } else {
- rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
- rlSrc = loadValue(cUnit, rlSrc, kFPReg);
- srcReg = rlSrc.lowReg;
- }
- if (longDest) {
- rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
- rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true);
- newLIR2(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg),
- srcReg);
- storeValueWide(cUnit, rlDest, rlResult);
- } else {
- rlDest = dvmCompilerGetDest(cUnit, mir, 0);
- rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true);
- newLIR2(cUnit, (ArmOpcode)op, rlResult.lowReg, srcReg);
- storeValue(cUnit, rlDest, rlResult);
- }
- return false;
-}
-
-static bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir)
-{
- ArmLIR *branch;
- RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
- RegLocation rlDest = inlinedTargetWide(cUnit, mir, true);
- rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
- RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kFPReg, true);
- newLIR2(cUnit, kThumb2Vsqrtd, S2D(rlResult.lowReg, rlResult.highReg),
- S2D(rlSrc.lowReg, rlSrc.highReg));
- newLIR2(cUnit, kThumb2Vcmpd, S2D(rlResult.lowReg, rlResult.highReg),
- S2D(rlResult.lowReg, rlResult.highReg));
- newLIR0(cUnit, kThumb2Fmstat);
- branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq);
- dvmCompilerClobberCallRegs(cUnit);
- LOAD_FUNC_ADDR(cUnit, r2, (int) (double (*)(double)) sqrt);
- newLIR3(cUnit, kThumb2Fmrrd, r0, r1, S2D(rlSrc.lowReg, rlSrc.highReg));
- newLIR1(cUnit, kThumbBlxR, r2);
- newLIR3(cUnit, kThumb2Fmdrr, S2D(rlResult.lowReg, rlResult.highReg),
- r0, r1);
- ArmLIR *label = newLIR0(cUnit, kArmPseudoTargetLabel);
- label->defMask = ENCODE_ALL;
- branch->generic.target = (LIR *)label;
- storeValueWide(cUnit, rlDest, rlResult);
- return false;
-}
-
-static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
- RegLocation rlSrc1, RegLocation rlSrc2)
-{
- bool isDouble;
- int defaultResult;
- RegLocation rlResult;
-
- switch(mir->dalvikInsn.opcode) {
- case OP_CMPL_FLOAT:
- isDouble = false;
- defaultResult = -1;
- break;
- case OP_CMPG_FLOAT:
- isDouble = false;
- defaultResult = 1;
- break;
- case OP_CMPL_DOUBLE:
- isDouble = true;
- defaultResult = -1;
- break;
- case OP_CMPG_DOUBLE:
- isDouble = true;
- defaultResult = 1;
- break;
- default:
- return true;
- }
- if (isDouble) {
- rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
- rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
- dvmCompilerClobberSReg(cUnit, rlDest.sRegLow);
- rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
- loadConstant(cUnit, rlResult.lowReg, defaultResult);
- newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg),
- S2D(rlSrc2.lowReg, rlSrc2.highReg));
- } else {
- rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
- rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
- dvmCompilerClobberSReg(cUnit, rlDest.sRegLow);
- rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
- loadConstant(cUnit, rlResult.lowReg, defaultResult);
- newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg);
- }
- assert(!FPREG(rlResult.lowReg));
- newLIR0(cUnit, kThumb2Fmstat);
-
- genIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, "");
- newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg,
- modifiedImmediate(-defaultResult)); // Must not alter ccodes
- genBarrier(cUnit);
-
- genIT(cUnit, kArmCondEq, "");
- loadConstant(cUnit, rlResult.lowReg, 0);
- genBarrier(cUnit);
-
- storeValue(cUnit, rlDest, rlResult);
- return false;
-}
diff --git a/vm/compiler/codegen/arm/FP/ThumbPortableFP.cpp b/vm/compiler/codegen/arm/FP/ThumbPortableFP.cpp
deleted file mode 100644
index 7aac8e6d5..000000000
--- a/vm/compiler/codegen/arm/FP/ThumbPortableFP.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Forward-declare the portable versions due to circular dependency */
-static bool genArithOpFloatPortable(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2);
-
-static bool genArithOpDoublePortable(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2);
-
-static bool genConversionPortable(CompilationUnit *cUnit, MIR *mir);
-
-static bool handleExecuteInlineC(CompilationUnit *cUnit, MIR *mir);
-
-static bool genConversion(CompilationUnit *cUnit, MIR *mir)
-{
- return genConversionPortable(cUnit, mir);
-}
-
-static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2)
-{
- return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
-}
-
-static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2)
-{
- return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
-}
-
-static bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir)
-{
- return handleExecuteInlineC(cUnit, mir);
-}
-
-static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
- RegLocation rlSrc1, RegLocation rlSrc2)
-{
- RegLocation rlResult = LOC_C_RETURN;
- /*
- * Don't attempt to optimize register usage since these opcodes call out to
- * the handlers.
- */
- switch (mir->dalvikInsn.opcode) {
- case OP_CMPL_FLOAT:
- loadValueDirectFixed(cUnit, rlSrc1, r0);
- loadValueDirectFixed(cUnit, rlSrc2, r1);
- genDispatchToHandler(cUnit, TEMPLATE_CMPL_FLOAT);
- storeValue(cUnit, rlDest, rlResult);
- break;
- case OP_CMPG_FLOAT:
- loadValueDirectFixed(cUnit, rlSrc1, r0);
- loadValueDirectFixed(cUnit, rlSrc2, r1);
- genDispatchToHandler(cUnit, TEMPLATE_CMPG_FLOAT);
- storeValue(cUnit, rlDest, rlResult);
- break;
- case OP_CMPL_DOUBLE:
- loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
- loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
- genDispatchToHandler(cUnit, TEMPLATE_CMPL_DOUBLE);
- storeValue(cUnit, rlDest, rlResult);
- break;
- case OP_CMPG_DOUBLE:
- loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
- loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
- genDispatchToHandler(cUnit, TEMPLATE_CMPG_DOUBLE);
- storeValue(cUnit, rlDest, rlResult);
- break;
- default:
- return true;
- }
- return false;
-}
diff --git a/vm/compiler/codegen/arm/FP/ThumbVFP.cpp b/vm/compiler/codegen/arm/FP/ThumbVFP.cpp
deleted file mode 100644
index f685f2469..000000000
--- a/vm/compiler/codegen/arm/FP/ThumbVFP.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file is included by Codegen-armv5te-vfp.c, and implements architecture
- * variant-specific code.
- */
-
-/*
- * Take the address of a Dalvik register and store it into rDest.
- * Clobber any live values associated either with the Dalvik value
- * or the target register and lock the target fixed register.
- */
-static void loadValueAddressDirect(CompilationUnit *cUnit, RegLocation rlSrc,
- int rDest)
-{
- rlSrc = rlSrc.wide ? dvmCompilerUpdateLocWide(cUnit, rlSrc) :
- dvmCompilerUpdateLoc(cUnit, rlSrc);
- if (rlSrc.location == kLocPhysReg) {
- if (rlSrc.wide) {
- dvmCompilerFlushRegWide(cUnit, rlSrc.lowReg, rlSrc.highReg);
- } else {
- dvmCompilerFlushReg(cUnit, rlSrc.lowReg);
- }
- }
- dvmCompilerClobber(cUnit, rDest);
- dvmCompilerLockTemp(cUnit, rDest);
- opRegRegImm(cUnit, kOpAdd, rDest, r5FP,
- dvmCompilerS2VReg(cUnit, rlSrc.sRegLow) << 2);
-}
-
-static bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir)
-{
- RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
- RegLocation rlResult = LOC_C_RETURN_WIDE;
- RegLocation rlDest = LOC_DALVIK_RETURN_VAL_WIDE;
- loadValueAddressDirect(cUnit, rlSrc, r2);
- genDispatchToHandler(cUnit, TEMPLATE_SQRT_DOUBLE_VFP);
- storeValueWide(cUnit, rlDest, rlResult);
- return false;
-}
-
-/*
- * TUNING: On some implementations, it is quicker to pass addresses
- * to the handlers rather than load the operands into core registers
- * and then move the values to FP regs in the handlers. Other implementations
- * may prefer passing data in registers (and the latter approach would
- * yield cleaner register handling - avoiding the requirement that operands
- * be flushed to memory prior to the call).
- */
-static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2)
-{
- TemplateOpcode opcode;
-
- /*
- * Don't attempt to optimize register usage since these opcodes call out to
- * the handlers.
- */
- switch (mir->dalvikInsn.opcode) {
- case OP_ADD_FLOAT_2ADDR:
- case OP_ADD_FLOAT:
- opcode = TEMPLATE_ADD_FLOAT_VFP;
- break;
- case OP_SUB_FLOAT_2ADDR:
- case OP_SUB_FLOAT:
- opcode = TEMPLATE_SUB_FLOAT_VFP;
- break;
- case OP_DIV_FLOAT_2ADDR:
- case OP_DIV_FLOAT:
- opcode = TEMPLATE_DIV_FLOAT_VFP;
- break;
- case OP_MUL_FLOAT_2ADDR:
- case OP_MUL_FLOAT:
- opcode = TEMPLATE_MUL_FLOAT_VFP;
- break;
- case OP_REM_FLOAT_2ADDR:
- case OP_REM_FLOAT:
- case OP_NEG_FLOAT: {
- return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
- }
- default:
- return true;
- }
- loadValueAddressDirect(cUnit, rlDest, r0);
- loadValueAddressDirect(cUnit, rlSrc1, r1);
- loadValueAddressDirect(cUnit, rlSrc2, r2);
- genDispatchToHandler(cUnit, opcode);
- rlDest = dvmCompilerUpdateLoc(cUnit, rlDest);
- if (rlDest.location == kLocPhysReg) {
- dvmCompilerClobber(cUnit, rlDest.lowReg);
- }
- return false;
-}
-
-static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
- RegLocation rlDest, RegLocation rlSrc1,
- RegLocation rlSrc2)
-{
- TemplateOpcode opcode;
-
- switch (mir->dalvikInsn.opcode) {
- case OP_ADD_DOUBLE_2ADDR:
- case OP_ADD_DOUBLE:
- opcode = TEMPLATE_ADD_DOUBLE_VFP;
- break;
- case OP_SUB_DOUBLE_2ADDR:
- case OP_SUB_DOUBLE:
- opcode = TEMPLATE_SUB_DOUBLE_VFP;
- break;
- case OP_DIV_DOUBLE_2ADDR:
- case OP_DIV_DOUBLE:
- opcode = TEMPLATE_DIV_DOUBLE_VFP;
- break;
- case OP_MUL_DOUBLE_2ADDR:
- case OP_MUL_DOUBLE:
- opcode = TEMPLATE_MUL_DOUBLE_VFP;
- break;
- case OP_REM_DOUBLE_2ADDR:
- case OP_REM_DOUBLE:
- case OP_NEG_DOUBLE: {
- return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1,
- rlSrc2);
- }
- default:
- return true;
- }
- loadValueAddressDirect(cUnit, rlDest, r0);
- loadValueAddressDirect(cUnit, rlSrc1, r1);
- loadValueAddressDirect(cUnit, rlSrc2, r2);
- genDispatchToHandler(cUnit, opcode);
- rlDest = dvmCompilerUpdateLocWide(cUnit, rlDest);
- if (rlDest.location == kLocPhysReg) {
- dvmCompilerClobber(cUnit, rlDest.lowReg);
- dvmCompilerClobber(cUnit, rlDest.highReg);
- }
- return false;
-}
-
-static bool genConversion(CompilationUnit *cUnit, MIR *mir)
-{
- Opcode opcode = mir->dalvikInsn.opcode;
- bool longSrc = false;
- bool longDest = false;
- RegLocation rlSrc;
- RegLocation rlDest;
- TemplateOpcode templateOpcode;
- switch (opcode) {
- case OP_INT_TO_FLOAT:
- longSrc = false;
- longDest = false;
- templateOpcode = TEMPLATE_INT_TO_FLOAT_VFP;
- break;
- case OP_FLOAT_TO_INT:
- longSrc = false;
- longDest = false;
- templateOpcode = TEMPLATE_FLOAT_TO_INT_VFP;
- break;
- case OP_DOUBLE_TO_FLOAT:
- longSrc = true;
- longDest = false;
- templateOpcode = TEMPLATE_DOUBLE_TO_FLOAT_VFP;
- break;
- case OP_FLOAT_TO_DOUBLE:
- longSrc = false;
- longDest = true;
- templateOpcode = TEMPLATE_FLOAT_TO_DOUBLE_VFP;
- break;
- case OP_INT_TO_DOUBLE:
- longSrc = false;
- longDest = true;
- templateOpcode = TEMPLATE_INT_TO_DOUBLE_VFP;
- break;
- case OP_DOUBLE_TO_INT:
- longSrc = true;
- longDest = false;
- templateOpcode = TEMPLATE_DOUBLE_TO_INT_VFP;
- break;
- case OP_LONG_TO_DOUBLE:
- case OP_FLOAT_TO_LONG:
- case OP_LONG_TO_FLOAT:
- case OP_DOUBLE_TO_LONG:
- return genConversionPortable(cUnit, mir);
- default:
- return true;
- }
-
- if (longSrc) {
- rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
- } else {
- rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
- }
-
- if (longDest) {
- rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
- } else {
- rlDest = dvmCompilerGetDest(cUnit, mir, 0);
- }
- loadValueAddressDirect(cUnit, rlDest, r0);
- loadValueAddressDirect(cUnit, rlSrc, r1);
- genDispatchToHandler(cUnit, templateOpcode);
- if (rlDest.wide) {
- rlDest = dvmCompilerUpdateLocWide(cUnit, rlDest);
- dvmCompilerClobber(cUnit, rlDest.highReg);
- } else {
- rlDest = dvmCompilerUpdateLoc(cUnit, rlDest);
- }
- dvmCompilerClobber(cUnit, rlDest.lowReg);
- return false;
-}
-
-static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
- RegLocation rlSrc1, RegLocation rlSrc2)
-{
- TemplateOpcode templateOpcode;
- RegLocation rlResult = dvmCompilerGetReturn(cUnit);
- bool wide = true;
-
- switch(mir->dalvikInsn.opcode) {
- case OP_CMPL_FLOAT:
- templateOpcode = TEMPLATE_CMPL_FLOAT_VFP;
- wide = false;
- break;
- case OP_CMPG_FLOAT:
- templateOpcode = TEMPLATE_CMPG_FLOAT_VFP;
- wide = false;
- break;
- case OP_CMPL_DOUBLE:
- templateOpcode = TEMPLATE_CMPL_DOUBLE_VFP;
- break;
- case OP_CMPG_DOUBLE:
- templateOpcode = TEMPLATE_CMPG_DOUBLE_VFP;
- break;
- default:
- return true;
- }
- loadValueAddressDirect(cUnit, rlSrc1, r0);
- loadValueAddressDirect(cUnit, rlSrc2, r1);
- genDispatchToHandler(cUnit, templateOpcode);
- storeValue(cUnit, rlDest, rlResult);
- return false;
-}