Restructure to reduce MIR references
This CL eliminates most of the MIR references in the lower-level
code generator. This allows a higher level of code sharing with
the MIR->LIR and GreenlandIR->LIR lowering passes.
The invoke, launchpads and new array support will need some more
extensive refactoring (future CL).
Change-Id: I75f249268c8ac18da1dd9180ff855d5176d6c4fe
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 0d2cf00..2bd9333 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -325,11 +325,11 @@
// FIXME: need to do some work to split out targets with
// condition codes and those without
#if defined(TARGET_ARM) || defined(TARGET_X86)
-LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir,
+LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode,
ThrowKind kind)
{
LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
- mir ? mir->offset : 0);
+ cUnit->currentDalvikOffset);
LIR* branch = opCondBranch(cUnit, cCode, tgt);
// Remember branch target - will process later
oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
@@ -338,9 +338,10 @@
#endif
LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode,
- int reg, int immVal, MIR* mir, ThrowKind kind)
+ int reg, int immVal, ThrowKind kind)
{
- LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind, mir->offset);
+ LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
+ cUnit->currentDalvikOffset);
LIR* branch;
if (cCode == kCondAl) {
branch = opUnconditionalBranch(cUnit, tgt);
@@ -353,21 +354,21 @@
}
/* Perform null-check on a register. */
-LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, MIR* mir)
+LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, int optFlags)
{
if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
- mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
+ optFlags & MIR_IGNORE_NULL_CHECK) {
return NULL;
}
- return genImmedCheck(cUnit, kCondEq, mReg, 0, mir, kThrowNullPointer);
+ return genImmedCheck(cUnit, kCondEq, mReg, 0, kThrowNullPointer);
}
/* Perform check on two registers */
LIR* genRegRegCheck(CompilationUnit* cUnit, ConditionCode cCode,
- int reg1, int reg2, MIR* mir, ThrowKind kind)
+ int reg1, int reg2, ThrowKind kind)
{
LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
- mir ? mir->offset : 0, reg1, reg2);
+ cUnit->currentDalvikOffset, reg1, reg2);
#if defined(TARGET_MIPS)
LIR* branch = opCmpBranch(cUnit, cCode, reg1, reg2, tgt);
#else
@@ -379,13 +380,13 @@
return branch;
}
-void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- RegLocation rlSrc1, RegLocation rlSrc2, LIR* labelList)
+void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
+ Instruction::Code opcode, RegLocation rlSrc1,
+ RegLocation rlSrc2, LIR* labelList)
{
ConditionCode cond;
rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
- Instruction::Code opcode = mir->dalvikInsn.opcode;
switch (opcode) {
case Instruction::IF_EQ:
cond = kCondEq;
@@ -419,12 +420,12 @@
opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
}
-void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- RegLocation rlSrc, LIR* labelList)
+void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
+ Instruction::Code opcode, RegLocation rlSrc,
+ LIR* labelList)
{
ConditionCode cond;
rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- Instruction::Code opcode = mir->dalvikInsn.opcode;
switch (opcode) {
case Instruction::IF_EQZ:
cond = kCondEq;
@@ -457,7 +458,7 @@
opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
}
-void genIntToLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
RegLocation rlSrc)
{
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -470,13 +471,13 @@
storeValueWide(cUnit, rlDest, rlResult);
}
-void genIntNarrowing(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
- RegLocation rlSrc)
+void genIntNarrowing(CompilationUnit* cUnit, Instruction::Code opcode,
+ RegLocation rlDest, RegLocation rlSrc)
{
rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
OpKind op = kOpInvalid;
- switch (mir->dalvikInsn.opcode) {
+ switch (opcode) {
case Instruction::INT_TO_BYTE:
op = kOp2Byte;
break;
@@ -498,11 +499,10 @@
* Array::AllocFromCode(type_idx, method, count);
* Note: AllocFromCode will handle checks for errNegativeArraySize.
*/
-void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genNewArray(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest,
RegLocation rlSrc)
{
oatFlushAllRegs(cUnit); /* Everything to home location */
- uint32_t type_idx = mir->dalvikInsn.vC;
int funcOffset;
if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
cUnit->dex_cache,
@@ -630,14 +630,13 @@
}
}
-void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
+void genSput(CompilationUnit* cUnit, uint32_t fieldIdx, RegLocation rlSrc,
bool isLongOrDouble, bool isObject)
{
int fieldOffset;
int ssbIndex;
bool isVolatile;
bool isReferrersClass;
- uint32_t fieldIdx = mir->dalvikInsn.vB;
OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
*cUnit->dex_file, *cUnit->dex_cache,
@@ -698,10 +697,8 @@
}
// rBase now holds static storage base
if (isLongOrDouble) {
- rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
} else {
- rlSrc = oatGetSrc(cUnit, mir, 0);
rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
}
//FIXME: need to generalize the barrier call
@@ -730,14 +727,13 @@
}
}
-void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genSget(CompilationUnit* cUnit, uint32_t fieldIdx, RegLocation rlDest,
bool isLongOrDouble, bool isObject)
{
int fieldOffset;
int ssbIndex;
bool isVolatile;
bool isReferrersClass;
- uint32_t fieldIdx = mir->dalvikInsn.vB;
OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
*cUnit->dex_file, *cUnit->dex_cache,
@@ -792,14 +788,12 @@
oatFreeTemp(cUnit, rMethod);
}
// rBase now holds static storage base
- rlDest = isLongOrDouble ? oatGetDestWide(cUnit, mir, 0, 1)
- : oatGetDest(cUnit, mir, 0);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
if (isVolatile) {
oatGenMemBarrier(cUnit, kSY);
}
if (isLongOrDouble) {
- loadBaseDispWide(cUnit, NULL, rBase, fieldOffset, rlResult.lowReg,
+ loadBaseDispWide(cUnit, rBase, fieldOffset, rlResult.lowReg,
rlResult.highReg, INVALID_SREG);
} else {
loadWordDisp(cUnit, rBase, fieldOffset, rlResult.lowReg);
@@ -840,11 +834,11 @@
#endif
}
-void genThrowVerificationError(CompilationUnit* cUnit, MIR* mir)
+void genThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
{
callRuntimeHelperImmImm(cUnit,
ENTRYPOINT_OFFSET(pThrowVerificationErrorFromCode),
- mir->dalvikInsn.vA, mir->dalvikInsn.vB);
+ info1, info2);
}
void handleSuspendLaunchpads(CompilationUnit *cUnit)
@@ -982,13 +976,12 @@
fieldOffset, isVolatile, isPut);
}
-void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
+void genIGet(CompilationUnit* cUnit, uint32_t fieldIdx, int optFlags, OpSize size,
RegLocation rlDest, RegLocation rlObj,
bool isLongOrDouble, bool isObject)
{
int fieldOffset;
bool isVolatile;
- uint32_t fieldIdx = mir->dalvikInsn.vC;
bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
@@ -999,11 +992,11 @@
rlObj = loadValue(cUnit, rlObj, kCoreReg);
if (isLongOrDouble) {
DCHECK(rlDest.wide);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
#if defined(TARGET_X86)
rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
- loadBaseDispWide(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
+ loadBaseDispWide(cUnit, rlObj.lowReg, fieldOffset, rlResult.lowReg,
rlResult.highReg, rlObj.sRegLow);
if (isVolatile) {
oatGenMemBarrier(cUnit, kSY);
@@ -1021,8 +1014,8 @@
storeValueWide(cUnit, rlDest, rlResult);
} else {
rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
- loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
+ loadBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlResult.lowReg,
kWord, rlObj.sRegLow);
if (isVolatile) {
oatGenMemBarrier(cUnit, kSY);
@@ -1044,12 +1037,11 @@
}
}
-void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, RegLocation rlSrc,
- RegLocation rlObj, bool isLongOrDouble, bool isObject)
+void genIPut(CompilationUnit* cUnit, uint32_t fieldIdx, int optFlags, OpSize size,
+ RegLocation rlSrc, RegLocation rlObj, bool isLongOrDouble, bool isObject)
{
int fieldOffset;
bool isVolatile;
- uint32_t fieldIdx = mir->dalvikInsn.vC;
bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile,
true);
@@ -1060,7 +1052,7 @@
if (isLongOrDouble) {
int regPtr;
rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
regPtr = oatAllocTemp(cUnit);
opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
if (isVolatile) {
@@ -1073,7 +1065,7 @@
oatFreeTemp(cUnit, regPtr);
} else {
rlSrc = loadValue(cUnit, rlSrc, regClass);
- genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+ genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
if (isVolatile) {
oatGenMemBarrier(cUnit, kST);
}
@@ -1094,10 +1086,9 @@
}
}
-void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genConstClass(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest,
RegLocation rlSrc)
{
- uint32_t type_idx = mir->dalvikInsn.vB;
RegLocation rlMethod = loadCurrMethod(cUnit);
int resReg = oatAllocTemp(cUnit);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -1157,11 +1148,10 @@
}
}
-void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genConstString(CompilationUnit* cUnit, uint32_t string_idx, RegLocation rlDest,
RegLocation rlSrc)
{
/* NOTE: Most strings should be available at compile time */
- uint32_t string_idx = mir->dalvikInsn.vB;
int32_t offset_of_string = Array::DataOffset(sizeof(String*)).Int32Value() +
(sizeof(String*) * string_idx);
if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(
@@ -1216,10 +1206,9 @@
* Let helper function take care of everything. Will
* call Class::NewInstanceFromCode(type_idx, method);
*/
-void genNewInstance(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest)
+void genNewInstance(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest)
{
oatFlushAllRegs(cUnit); /* Everything to home location */
- uint32_t type_idx = mir->dalvikInsn.vB;
// alloc will always check for resolution, do we also need to verify
// access because the verifier was unable to?
int funcOffset;
@@ -1234,20 +1223,19 @@
storeValue(cUnit, rlDest, rlResult);
}
-void genThrow(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genThrow(CompilationUnit* cUnit, RegLocation rlSrc)
{
oatFlushAllRegs(cUnit);
callRuntimeHelperRegLocation(cUnit, ENTRYPOINT_OFFSET(pDeliverException),
rlSrc);
}
-void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genInstanceof(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest,
RegLocation rlSrc)
{
oatFlushAllRegs(cUnit);
// May generate a call - use explicit registers
oatLockCallTemps(cUnit);
- uint32_t type_idx = mir->dalvikInsn.vC;
loadCurrMethodDirect(cUnit, rARG1); // rARG1 <= current Method*
int classReg = rARG2; // rARG2 will hold the Class*
if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
@@ -1328,12 +1316,11 @@
#endif
}
-void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genCheckCast(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlSrc)
{
oatFlushAllRegs(cUnit);
// May generate a call - use explicit registers
oatLockCallTemps(cUnit);
- uint32_t type_idx = mir->dalvikInsn.vB;
loadCurrMethodDirect(cUnit, rARG1); // rARG1 <= current Method*
int classReg = rARG2; // rARG2 will hold the Class*
if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
@@ -1403,7 +1390,7 @@
* Generate array store
*
*/
-void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, RegLocation rlArray,
+void genArrayObjPut(CompilationUnit* cUnit, int optFlags, RegLocation rlArray,
RegLocation rlIndex, RegLocation rlSrc, int scale)
{
int lenOffset = Array::LengthOffset().Int32Value();
@@ -1421,7 +1408,7 @@
loadValueDirectFixed(cUnit, rlSrc, rValue); // Grab value
loadValueDirectFixed(cUnit, rlIndex, rIndex); // Grab index
- genNullCheck(cUnit, rlArray.sRegLow, rArray, mir); // NPE?
+ genNullCheck(cUnit, rlArray.sRegLow, rArray, optFlags); // NPE?
// Store of null?
LIR* null_value_check = opCmpImmBranch(cUnit, kCondEq, rValue, 0, NULL);
@@ -1443,15 +1430,14 @@
#if defined(TARGET_X86)
// make an extra temp available for card mark below
oatFreeTemp(cUnit, rARG1);
- if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+ if (!(optFlags & MIR_IGNORE_RANGE_CHECK)) {
/* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
- genRegMemCheck(cUnit, kCondUge, rIndex, rArray,
- lenOffset, mir, kThrowArrayBounds);
+ genRegMemCheck(cUnit, kCondUge, rIndex, rArray, lenOffset, kThrowArrayBounds);
}
- storeBaseIndexedDisp(cUnit, NULL, rArray, rIndex, scale,
+ storeBaseIndexedDisp(cUnit, rArray, rIndex, scale,
dataOffset, rValue, INVALID_REG, kWord, INVALID_SREG);
#else
- bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+ bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK));
int regLen = INVALID_REG;
if (needsRangeCheck) {
regLen = rARG1;
@@ -1461,8 +1447,7 @@
int rPtr = oatAllocTemp(cUnit);
opRegRegImm(cUnit, kOpAdd, rPtr, rArray, dataOffset);
if (needsRangeCheck) {
- genRegRegCheck(cUnit, kCondCs, rIndex, regLen, mir,
- kThrowArrayBounds);
+ genRegRegCheck(cUnit, kCondCs, rIndex, regLen, kThrowArrayBounds);
}
storeBaseIndexed(cUnit, rPtr, rIndex, rValue, scale, kWord);
oatFreeTemp(cUnit, rPtr);
@@ -1474,7 +1459,7 @@
/*
* Generate array load
*/
-void genArrayGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
+void genArrayGet(CompilationUnit* cUnit, int optFlags, OpSize size,
RegLocation rlArray, RegLocation rlIndex,
RegLocation rlDest, int scale)
{
@@ -1492,13 +1477,13 @@
}
/* null object? */
- genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
+ genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, optFlags);
#if defined(TARGET_X86)
- if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+ if (!(optFlags & MIR_IGNORE_RANGE_CHECK)) {
/* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
genRegMemCheck(cUnit, kCondUge, rlIndex.lowReg, rlArray.lowReg,
- lenOffset, mir, kThrowArrayBounds);
+ lenOffset, kThrowArrayBounds);
}
if ((size == kLong) || (size == kDouble)) {
int regAddr = oatAllocTemp(cUnit);
@@ -1506,13 +1491,13 @@
oatFreeTemp(cUnit, rlArray.lowReg);
oatFreeTemp(cUnit, rlIndex.lowReg);
rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
- loadBaseIndexedDisp(cUnit, NULL, regAddr, INVALID_REG, 0, 0, rlResult.lowReg,
+ loadBaseIndexedDisp(cUnit, regAddr, INVALID_REG, 0, 0, rlResult.lowReg,
rlResult.highReg, size, INVALID_SREG);
storeValueWide(cUnit, rlDest, rlResult);
} else {
rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
- loadBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale,
+ loadBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale,
dataOffset, rlResult.lowReg, INVALID_REG, size,
INVALID_SREG);
@@ -1520,7 +1505,7 @@
}
#else
int regPtr = oatAllocTemp(cUnit);
- bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+ bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK));
int regLen = INVALID_REG;
if (needsRangeCheck) {
regLen = oatAllocTemp(cUnit);
@@ -1545,8 +1530,7 @@
if (needsRangeCheck) {
// TODO: change kCondCS to a more meaningful name, is the sense of
// carry-set/clear flipped?
- genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
- kThrowArrayBounds);
+ genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
}
loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
@@ -1559,8 +1543,7 @@
if (needsRangeCheck) {
// TODO: change kCondCS to a more meaningful name, is the sense of
// carry-set/clear flipped?
- genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
- kThrowArrayBounds);
+ genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
}
loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg,
@@ -1576,7 +1559,7 @@
* Generate array store
*
*/
-void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
+void genArrayPut(CompilationUnit* cUnit, int optFlags, OpSize size,
RegLocation rlArray, RegLocation rlIndex,
RegLocation rlSrc, int scale)
{
@@ -1604,24 +1587,24 @@
#endif
/* null object? */
- genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
+ genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, optFlags);
#if defined(TARGET_X86)
- if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+ if (!(optFlags & MIR_IGNORE_RANGE_CHECK)) {
/* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
genRegMemCheck(cUnit, kCondUge, rlIndex.lowReg, rlArray.lowReg,
- lenOffset, mir, kThrowArrayBounds);
+ lenOffset, kThrowArrayBounds);
}
if ((size == kLong) || (size == kDouble)) {
rlSrc = loadValueWide(cUnit, rlSrc, regClass);
} else {
rlSrc = loadValue(cUnit, rlSrc, regClass);
}
- storeBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale,
+ storeBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale,
dataOffset, rlSrc.lowReg, rlSrc.highReg, size,
INVALID_SREG);
#else
- bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+ bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK));
int regLen = INVALID_REG;
if (needsRangeCheck) {
regLen = oatAllocTemp(cUnit);
@@ -1645,8 +1628,7 @@
rlSrc = loadValueWide(cUnit, rlSrc, regClass);
if (needsRangeCheck) {
- genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
- kThrowArrayBounds);
+ genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
}
@@ -1656,8 +1638,7 @@
} else {
rlSrc = loadValue(cUnit, rlSrc, regClass);
if (needsRangeCheck) {
- genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
- kThrowArrayBounds);
+ genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
}
storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
@@ -1666,7 +1647,7 @@
#endif
}
-void genLong3Addr(CompilationUnit* cUnit, MIR* mir, OpKind firstOp,
+void genLong3Addr(CompilationUnit* cUnit, OpKind firstOp,
OpKind secondOp, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlSrc2)
{
@@ -1715,12 +1696,12 @@
}
-bool genShiftOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genShiftOpLong(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlShift)
{
int funcOffset;
- switch (mir->dalvikInsn.opcode) {
+ switch (opcode) {
case Instruction::SHL_LONG:
case Instruction::SHL_LONG_2ADDR:
funcOffset = ENTRYPOINT_OFFSET(pShlLong);
@@ -1745,7 +1726,7 @@
}
-bool genArithOpInt(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlSrc2)
{
OpKind op = kOpBkpt;
@@ -1756,7 +1737,7 @@
bool shiftOp = false;
int funcOffset;
int retReg = rRET0;
- switch (mir->dalvikInsn.opcode) {
+ switch (opcode) {
case Instruction::NEG_INT:
op = kOpNeg;
unary = true;
@@ -1823,7 +1804,7 @@
break;
default:
LOG(FATAL) << "Invalid word arith op: " <<
- (int)mir->dalvikInsn.opcode;
+ (int)opcode;
}
if (!callOut) {
if (unary) {
@@ -1862,7 +1843,7 @@
#endif
loadValueDirectFixed(cUnit, rlSrc1, rARG0);
if (checkZero) {
- genImmedCheck(cUnit, kCondEq, rARG1, 0, mir, kThrowDivZero);
+ genImmedCheck(cUnit, kCondEq, rARG1, 0, kThrowDivZero);
}
#if !defined(TARGET_X86)
opReg(cUnit, kOpBlx, rTgt);
@@ -2034,17 +2015,16 @@
return true;
}
-bool genArithOpIntLit(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
- RegLocation rlSrc, int lit)
+bool genArithOpIntLit(CompilationUnit* cUnit, Instruction::Code opcode,
+ RegLocation rlDest, RegLocation rlSrc, int lit)
{
- Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
RegLocation rlResult;
OpKind op = (OpKind)0; /* Make gcc happy */
int shiftOp = false;
bool isDiv = false;
int funcOffset;
- switch (dalvikOpcode) {
+ switch (opcode) {
case Instruction::RSUB_INT_LIT8:
case Instruction::RSUB_INT: {
int tReg;
@@ -2104,18 +2084,18 @@
case Instruction::REM_INT_LIT8:
case Instruction::REM_INT_LIT16:
if (lit == 0) {
- genImmedCheck(cUnit, kCondAl, 0, 0, mir, kThrowDivZero);
+ genImmedCheck(cUnit, kCondAl, 0, 0, kThrowDivZero);
return false;
}
- if (handleEasyDivide(cUnit, dalvikOpcode, rlSrc, rlDest, lit)) {
+ if (handleEasyDivide(cUnit, opcode, rlSrc, rlDest, lit)) {
return false;
}
oatFlushAllRegs(cUnit); /* Everything to home location */
loadValueDirectFixed(cUnit, rlSrc, rARG0);
oatClobber(cUnit, rARG0);
funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
- if ((dalvikOpcode == Instruction::DIV_INT_LIT8) ||
- (dalvikOpcode == Instruction::DIV_INT_LIT16)) {
+ if ((opcode == Instruction::DIV_INT_LIT8) ||
+ (opcode == Instruction::DIV_INT_LIT16)) {
isDiv = true;
} else {
isDiv = false;
@@ -2143,7 +2123,7 @@
return false;
}
-bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genArithOpLong(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlSrc2)
{
RegLocation rlResult;
@@ -2154,7 +2134,7 @@
int funcOffset;
int retReg = rRET0;
- switch (mir->dalvikInsn.opcode) {
+ switch (opcode) {
case Instruction::NOT_LONG:
rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -2175,7 +2155,7 @@
case Instruction::ADD_LONG:
case Instruction::ADD_LONG_2ADDR:
#if defined(TARGET_MIPS) || defined(TARGET_X86)
- return genAddLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+ return genAddLong(cUnit, rlDest, rlSrc1, rlSrc2);
#else
firstOp = kOpAdd;
secondOp = kOpAdc;
@@ -2184,7 +2164,7 @@
case Instruction::SUB_LONG:
case Instruction::SUB_LONG_2ADDR:
#if defined(TARGET_MIPS) || defined(TARGET_X86)
- return genSubLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+ return genSubLong(cUnit, rlDest, rlSrc1, rlSrc2);
#else
firstOp = kOpSub;
secondOp = kOpSbc;
@@ -2218,7 +2198,7 @@
case Instruction::AND_LONG_2ADDR:
case Instruction::AND_LONG:
#if defined(TARGET_X86)
- return genAndLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+ return genAndLong(cUnit, rlDest, rlSrc1, rlSrc2);
#else
firstOp = kOpAnd;
secondOp = kOpAnd;
@@ -2227,7 +2207,7 @@
case Instruction::OR_LONG:
case Instruction::OR_LONG_2ADDR:
#if defined(TARGET_X86)
- return genOrLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+ return genOrLong(cUnit, rlDest, rlSrc1, rlSrc2);
#else
firstOp = kOpOr;
secondOp = kOpOr;
@@ -2236,20 +2216,20 @@
case Instruction::XOR_LONG:
case Instruction::XOR_LONG_2ADDR:
#if defined(TARGET_X86)
- return genXorLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+ return genXorLong(cUnit, rlDest, rlSrc1, rlSrc2);
#else
firstOp = kOpXor;
secondOp = kOpXor;
break;
#endif
case Instruction::NEG_LONG: {
- return genNegLong(cUnit, mir, rlDest, rlSrc2);
+ return genNegLong(cUnit, rlDest, rlSrc2);
}
default:
LOG(FATAL) << "Invalid long arith op";
}
if (!callOut) {
- genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
+ genLong3Addr(cUnit, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
} else {
oatFlushAllRegs(cUnit); /* Send everything to home location */
if (checkZero) {
@@ -2261,11 +2241,11 @@
#if defined(TARGET_ARM)
newLIR4(cUnit, kThumb2OrrRRRs, tReg, rARG2, rARG3, 0);
oatFreeTemp(cUnit, tReg);
- genCheck(cUnit, kCondEq, mir, kThrowDivZero);
+ genCheck(cUnit, kCondEq, kThrowDivZero);
#else
opRegRegReg(cUnit, kOpOr, tReg, rARG2, rARG3);
#endif
- genImmedCheck(cUnit, kCondEq, tReg, 0, mir, kThrowDivZero);
+ genImmedCheck(cUnit, kCondEq, tReg, 0, kThrowDivZero);
oatFreeTemp(cUnit, tReg);
loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
#if !defined(TARGET_X86)
@@ -2288,47 +2268,41 @@
return false;
}
-bool genConversionCall(CompilationUnit* cUnit, MIR* mir, int funcOffset,
- int srcSize, int tgtSize)
+bool genConversionCall(CompilationUnit* cUnit, int funcOffset,
+ RegLocation rlDest, RegLocation rlSrc)
{
/*
* Don't optimize the register usage since it calls out to support
* functions
*/
- RegLocation rlSrc;
- RegLocation rlDest;
oatFlushAllRegs(cUnit); /* Send everything to home location */
- if (srcSize == 1) {
- rlSrc = oatGetSrc(cUnit, mir, 0);
- loadValueDirectFixed(cUnit, rlSrc, rARG0);
- } else {
- rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ if (rlSrc.wide) {
loadValueDirectWideFixed(cUnit, rlSrc, rARG0, rARG1);
+ } else {
+ loadValueDirectFixed(cUnit, rlSrc, rARG0);
}
callRuntimeHelperRegLocation(cUnit, funcOffset, rlSrc);
- if (tgtSize == 1) {
+ if (rlDest.wide) {
RegLocation rlResult;
- rlDest = oatGetDest(cUnit, mir, 0);
- rlResult = oatGetReturn(cUnit, rlDest.fp);
- storeValue(cUnit, rlDest, rlResult);
- } else {
- RegLocation rlResult;
- rlDest = oatGetDestWide(cUnit, mir, 0, 1);
rlResult = oatGetReturnWide(cUnit, rlDest.fp);
storeValueWide(cUnit, rlDest, rlResult);
+ } else {
+ RegLocation rlResult;
+ rlResult = oatGetReturn(cUnit, rlDest.fp);
+ storeValue(cUnit, rlDest, rlResult);
}
return false;
}
void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc);
-bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode,
RegLocation rlDest, RegLocation rlSrc1,
RegLocation rlSrc2)
{
RegLocation rlResult;
int funcOffset;
- switch (mir->dalvikInsn.opcode) {
+ switch (opcode) {
case Instruction::ADD_FLOAT_2ADDR:
case Instruction::ADD_FLOAT:
funcOffset = ENTRYPOINT_OFFSET(pFadd);
@@ -2364,14 +2338,14 @@
}
void genNegDouble(CompilationUnit* cUnit, RegLocation rlDst, RegLocation rlSrc);
-bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode,
RegLocation rlDest, RegLocation rlSrc1,
RegLocation rlSrc2)
{
RegLocation rlResult;
int funcOffset;
- switch (mir->dalvikInsn.opcode) {
+ switch (opcode) {
case Instruction::ADD_DOUBLE_2ADDR:
case Instruction::ADD_DOUBLE:
funcOffset = ENTRYPOINT_OFFSET(pDadd);
@@ -2406,41 +2380,41 @@
return false;
}
-bool genConversionPortable(CompilationUnit* cUnit, MIR* mir)
+bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode,
+ RegLocation rlDest, RegLocation rlSrc)
{
- Instruction::Code opcode = mir->dalvikInsn.opcode;
switch (opcode) {
case Instruction::INT_TO_FLOAT:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pI2f),
- 1, 1);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pI2f),
+ rlDest, rlSrc);
case Instruction::FLOAT_TO_INT:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pF2iz),
- 1, 1);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pF2iz),
+ rlDest, rlSrc);
case Instruction::DOUBLE_TO_FLOAT:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pD2f),
- 2, 1);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pD2f),
+ rlDest, rlSrc);
case Instruction::FLOAT_TO_DOUBLE:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pF2d),
- 1, 2);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pF2d),
+ rlDest, rlSrc);
case Instruction::INT_TO_DOUBLE:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pI2d),
- 1, 2);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pI2d),
+ rlDest, rlSrc);
case Instruction::DOUBLE_TO_INT:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pD2iz),
- 2, 1);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pD2iz),
+ rlDest, rlSrc);
case Instruction::FLOAT_TO_LONG:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pF2l),
- 1, 2);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pF2l),
+ rlDest, rlSrc);
case Instruction::LONG_TO_FLOAT:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pL2f),
- 2, 1);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pL2f),
+ rlDest, rlSrc);
case Instruction::DOUBLE_TO_LONG:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pD2l),
- 2, 2);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pD2l),
+ rlDest, rlSrc);
case Instruction::LONG_TO_DOUBLE:
- return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pL2d),
- 2, 2);
+ return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pL2d),
+ rlDest, rlSrc);
default:
return true;
}
@@ -2480,9 +2454,9 @@
}
/* Check if we need to check for pending suspend request */
-void genSuspendTest(CompilationUnit* cUnit, MIR* mir)
+void genSuspendTest(CompilationUnit* cUnit, int optFlags)
{
- if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
+ if (NO_SUSPEND || (optFlags & MIR_IGNORE_SUSPEND_CHECK)) {
return;
}
oatFlushAllRegs(cUnit);
@@ -2513,21 +2487,21 @@
#endif
LIR* retLab = newLIR0(cUnit, kPseudoTargetLabel);
LIR* target = rawLIR(cUnit, cUnit->currentDalvikOffset,
- kPseudoSuspendTarget, (intptr_t)retLab, mir->offset);
+ kPseudoSuspendTarget, (intptr_t)retLab, cUnit->currentDalvikOffset);
branch->target = (LIR*)target;
oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads, (intptr_t)target);
}
}
/* Check if we need to check for pending suspend request */
-void genSuspendTestAndBranch(CompilationUnit* cUnit, MIR* mir, LIR* target)
+void genSuspendTestAndBranch(CompilationUnit* cUnit, int optFlags, LIR* target)
{
- if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
+ if (NO_SUSPEND || (optFlags & MIR_IGNORE_SUSPEND_CHECK)) {
opUnconditionalBranch(cUnit, target);
return;
}
if (cUnit->genDebugger) {
- genSuspendTest(cUnit, mir);
+ genSuspendTest(cUnit, optFlags);
opUnconditionalBranch(cUnit, target);
} else {
#if defined(TARGET_ARM)
@@ -2542,7 +2516,7 @@
opCmpImmBranch(cUnit, kCondNe, rSUSPEND, 0, target);
#endif
LIR* launchPad = rawLIR(cUnit, cUnit->currentDalvikOffset,
- kPseudoSuspendTarget, (intptr_t)target, mir->offset);
+ kPseudoSuspendTarget, (intptr_t)target, cUnit->currentDalvikOffset);
oatFlushAllRegs(cUnit);
opUnconditionalBranch(cUnit, launchPad);
oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads,