extern RegLocation dvmCompilerGetReturnWide(CompilationUnit *cUnit) { RegLocation res = LOC_C_RETURN_WIDE; dvmCompilerClobber(cUnit, r0); dvmCompilerClobber(cUnit, r1); dvmCompilerMarkInUse(cUnit, r0); dvmCompilerMarkInUse(cUnit, r1); dvmCompilerMarkPair(cUnit, res.lowReg, res.highReg); return res; }
static void storeValueWide(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc) { LIR *defStart; LIR *defEnd; assert(FPREG(rlSrc.lowReg)==FPREG(rlSrc.highReg)); assert(rlDest.wide); assert(rlSrc.wide); // dvmCompilerKillNullCheckedLoc(cUnit, rlDest); if (rlSrc.location == kLocPhysReg) { if (dvmCompilerIsLive(cUnit, rlSrc.lowReg) || dvmCompilerIsLive(cUnit, rlSrc.highReg) || (rlDest.location == kLocPhysReg)) { // Src is live or Dest has assigned reg. rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false); genRegCopyWide(cUnit, rlDest.lowReg, rlDest.highReg, rlSrc.lowReg, rlSrc.highReg); } else { // Just re-assign the registers. Dest gets Src's regs rlDest.lowReg = rlSrc.lowReg; rlDest.highReg = rlSrc.highReg; dvmCompilerClobber(cUnit, rlSrc.lowReg); dvmCompilerClobber(cUnit, rlSrc.highReg); } } else { // Load Src either into promoted Dest or temps allocated for Dest rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false); loadValueDirectWide(cUnit, rlSrc, rlDest.lowReg, rlDest.highReg); } // Dest is now live and dirty (until/if we flush it to home location) dvmCompilerMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow); dvmCompilerMarkLive(cUnit, rlDest.highReg, dvmCompilerSRegHi(rlDest.sRegLow)); dvmCompilerMarkDirty(cUnit, rlDest.lowReg); dvmCompilerMarkDirty(cUnit, rlDest.highReg); dvmCompilerMarkPair(cUnit, rlDest.lowReg, rlDest.highReg); if (rlDest.location == kLocRetval) { //storeBaseDispWide(cUnit, rGLUE, offsetof(InterpState, retval), // rlDest.lowReg, rlDest.highReg); storeBaseDispWide(cUnit, rGLUE, 8, rlDest.lowReg, rlDest.highReg); dvmCompilerClobber(cUnit, rlDest.lowReg); dvmCompilerClobber(cUnit, rlDest.highReg); } else { dvmCompilerResetDefLocWide(cUnit, rlDest); if (dvmCompilerLiveOut(cUnit, rlDest.sRegLow) || dvmCompilerLiveOut(cUnit, dvmCompilerSRegHi(rlDest.sRegLow))) { //defStart = (LIR *)cUnit->lastLIRInsn; int vReg = dvmCompilerS2VReg(cUnit, rlDest.sRegLow); assert((vReg+1) == dvmCompilerS2VReg(cUnit, dvmCompilerSRegHi(rlDest.sRegLow))); storeBaseDispWide(cUnit, rFP, vReg << 2, rlDest.lowReg, rlDest.highReg); dvmCompilerMarkClean(cUnit, rlDest.lowReg); dvmCompilerMarkClean(cUnit, rlDest.highReg); //defEnd = (LIR *)cUnit->lastLIRInsn; //dvmCompilerMarkDefWide(cUnit, rlDest, defStart, defEnd); } } }