summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/arm/MethodCodegenDriver.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/codegen/arm/MethodCodegenDriver.cc')
-rw-r--r--src/compiler/codegen/arm/MethodCodegenDriver.cc107
1 files changed, 46 insertions, 61 deletions
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 633125443b..4a657718fd 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -17,10 +17,8 @@
#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
(1 << kDebugDisplayMissingTargets))
-STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, INVALID_REG,
- INVALID_REG, INVALID_SREG, 0,
- kLocDalvikFrame, INVALID_REG, INVALID_REG,
- INVALID_OFFSET};
+STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, INVALID_REG,
+ INVALID_REG, INVALID_SREG};
/* Mark register usage state and return long retloc */
STATIC RegLocation getRetLocWide(CompilationUnit* cUnit)
@@ -99,7 +97,8 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
RegLocation loc = oatUpdateLoc(cUnit,
oatGetSrc(cUnit, mir, i));
if (loc.location == kLocPhysReg) {
- storeBaseDisp(cUnit, rSP, loc.spOffset, loc.lowReg, kWord);
+ storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
+ loc.lowReg, kWord);
}
}
/*
@@ -113,7 +112,8 @@ STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
int rVal = rLR; // Using a lot of temps, rLR is known free here
// Set up source pointer
RegLocation rlFirst = oatGetSrc(cUnit, mir, 0);
- opRegRegImm(cUnit, kOpAdd, rSrc, rSP, rlFirst.spOffset);
+ opRegRegImm(cUnit, kOpAdd, rSrc, rSP,
+ oatSRegOffset(cUnit, rlFirst.sRegLow));
// Set up the target pointer
opRegRegImm(cUnit, kOpAdd, rDst, r0,
Array::DataOffset().Int32Value());
@@ -773,7 +773,8 @@ STATIC int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
} else {
// r2 & r3 can safely be used here
reg = r3;
- loadWordDisp(cUnit, rSP, rlArg.spOffset + 4, reg);
+ loadWordDisp(cUnit, rSP,
+ oatSRegOffset(cUnit, rlArg.sRegLow) + 4, reg);
callState = nextCallInsn(cUnit, mir, dInsn, callState,
rollback);
}
@@ -872,20 +873,23 @@ STATIC int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
if (loc.wide) {
loc = oatUpdateLocWide(cUnit, loc);
if ((nextArg >= 2) && (loc.location == kLocPhysReg)) {
- storeBaseDispWide(cUnit, rSP, loc.spOffset, loc.lowReg,
- loc.highReg);
+ storeBaseDispWide(cUnit, rSP,
+ oatSRegOffset(cUnit, loc.sRegLow),
+ loc.lowReg, loc.highReg);
}
nextArg += 2;
} else {
loc = oatUpdateLoc(cUnit, loc);
if ((nextArg >= 3) && (loc.location == kLocPhysReg)) {
- storeBaseDisp(cUnit, rSP, loc.spOffset, loc.lowReg, kWord);
+ storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
+ loc.lowReg, kWord);
}
nextArg++;
}
}
- int startOffset = cUnit->regLocation[mir->ssaRep->uses[3]].spOffset;
+ int startOffset = oatSRegOffset(cUnit,
+ cUnit->regLocation[mir->ssaRep->uses[3]].sRegLow);
int outsOffset = 4 /* Method* */ + (3 * 4);
if (numArgs >= 20) {
// Generate memcpy
@@ -1790,63 +1794,44 @@ STATIC void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
}
}
-/* If there are any ins passed in registers that have not been promoted
- * to a callee-save register, flush them to the frame.
- * Note: at this pointCopy any ins that are passed in register to their
- * home location */
+/*
+ * If there are any ins passed in registers that have not been promoted
+ * to a callee-save register, flush them to the frame. Perform intial
+ * assignment of promoted arguments.
+ */
STATIC void flushIns(CompilationUnit* cUnit)
{
if (cUnit->method->NumIns() == 0)
return;
- int inRegs = (cUnit->method->NumIns() > 2) ? 3
- : cUnit->method->NumIns();
- int startReg = r1;
- int startLoc = cUnit->method->NumRegisters() -
+ int firstArgReg = r1;
+ int lastArgReg = r3;
+ int startVReg = cUnit->method->NumRegisters() -
cUnit->method->NumIns();
- for (int i = 0; i < inRegs; i++) {
- RegLocation loc = cUnit->regLocation[startLoc + i];
- //TUNING: be smarter about flushing ins to frame
- storeBaseDisp(cUnit, rSP, loc.spOffset, startReg + i, kWord);
- if (loc.location == kLocPhysReg) {
- genRegCopy(cUnit, loc.lowReg, startReg + i);
- }
- }
-
- // Handle special case of wide argument half in regs, half in frame
- if (inRegs == 3) {
- RegLocation loc = cUnit->regLocation[startLoc + 2];
- if (loc.wide && loc.location == kLocPhysReg) {
- // Load the other half of the arg into the promoted pair
- loadWordDisp(cUnit, rSP, loc.spOffset + 4, loc.highReg);
- inRegs++;
- }
- }
-
- // Now, do initial assignment of all promoted arguments passed in frame
- for (int i = inRegs; i < cUnit->method->NumIns();) {
- RegLocation loc = cUnit->regLocation[startLoc + i];
- if (loc.fpLocation == kLocPhysReg) {
- loc.location = kLocPhysReg;
- loc.fp = true;
- loc.lowReg = loc.fpLowReg;
- loc.highReg = loc.fpHighReg;
- }
- if (loc.location == kLocPhysReg) {
- if (loc.wide) {
- if (loc.fp && (loc.lowReg & 1) != 0) {
- // Misaligned - need to load as a pair of singles
- loadWordDisp(cUnit, rSP, loc.spOffset, loc.lowReg);
- loadWordDisp(cUnit, rSP, loc.spOffset + 4, loc.highReg);
- } else {
- loadBaseDispWide(cUnit, NULL, rSP, loc.spOffset,
- loc.lowReg, loc.highReg, INVALID_SREG);
- }
- i++;
- } else {
- loadWordDisp(cUnit, rSP, loc.spOffset, loc.lowReg);
+ for (int i = 0; i < cUnit->method->NumIns(); i++) {
+ PromotionMap vMap = cUnit->promotionMap[startVReg + i];
+ // For arguments only, should have at most one promotion kind
+ DCHECK(!((vMap.coreLocation == kLocPhysReg) &&
+ (vMap.fpLocation == kLocPhysReg)));
+ if (i <= (lastArgReg - firstArgReg)) {
+ // If arriving in register, copy or flush
+ if (vMap.coreLocation == kLocPhysReg) {
+ genRegCopy(cUnit, vMap.coreReg, firstArgReg + i);
+ } else if (vMap.fpLocation == kLocPhysReg) {
+ genRegCopy(cUnit, vMap.fpReg, firstArgReg + i);
+ }
+ // Also put a copy in memory in case we're partially promoted
+ storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
+ firstArgReg + i, kWord);
+ } else {
+ // If arriving in frame, initialize promoted target regs
+ if (vMap.coreLocation == kLocPhysReg) {
+ loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
+ vMap.coreReg);
+ } else if (vMap.fpLocation == kLocPhysReg) {
+ loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
+ vMap.fpReg);
}
}
- i++;
}
}