/* * Load a Dalvik register pair into a physical register[s]. Take care when * using this routine, as it doesn't perform any bookkeeping regarding * register liveness. That is the responsibility of the caller. */ static void loadValueDirectWide(CompilationUnit *cUnit, RegLocation rlSrc, int regLo, int regHi) { rlSrc = dvmCompilerUpdateLocWide(cUnit, rlSrc); if (rlSrc.location == kLocPhysReg) { genRegCopyWide(cUnit, regLo, regHi, rlSrc.lowReg, rlSrc.highReg); } else if (rlSrc.location == kLocRetval) { loadBaseDispWide(cUnit, NULL, rGLUE, 8, regLo, regHi, INVALID_SREG); } else { assert(rlSrc.location == kLocDalvikFrame); loadBaseDispWide(cUnit, NULL, rFP, dvmCompilerS2VReg(cUnit, rlSrc.sRegLow) << 2, regLo, regHi, INVALID_SREG); } }
/* * 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) { dvmCompilerFlushRegWideForV5TEVFP(cUnit, rlSrc.lowReg, rlSrc.highReg); } else { dvmCompilerFlushRegForV5TEVFP(cUnit, rlSrc.lowReg); } } dvmCompilerClobber(cUnit, rDest); dvmCompilerLockTemp(cUnit, rDest); opRegRegImm(cUnit, kOpAdd, rDest, rFP, dvmCompilerS2VReg(cUnit, rlSrc.sRegLow) << 2); }
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; }