summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/GenCommon.cc
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2012-03-01 14:51:57 -0800
committer buzbee <buzbee@google.com> 2012-03-01 16:43:54 -0800
commit5de3494e4297c0d480409da3fecee39173f1d4e1 (patch)
tree269cd3447925d0b474d47fb056da4730f288ee12 /src/compiler/codegen/GenCommon.cc
parent6edfde4ae89f3a16d22ca82c928a5dd420e9fce9 (diff)
Another step towards a Mips target
Updating the MIPS target to use the now common codegen routines. Still much to do, but the general structure is sufficient to allow work to begin on the other target. Change-Id: I0d288fdfb59c8e76fad73185fdd56b345e87b604
Diffstat (limited to 'src/compiler/codegen/GenCommon.cc')
-rw-r--r--src/compiler/codegen/GenCommon.cc89
1 files changed, 61 insertions, 28 deletions
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 7af1aa033c..511c47bdae 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -43,19 +43,23 @@ void genBarrier(CompilationUnit* cUnit)
barrier->defMask = -1;
}
-/* Generate conditional branch instructions */
-LIR* genConditionalBranch(CompilationUnit* cUnit, ConditionCode cond,
- LIR* target)
+
+/* Generate unconditional branch instructions */
+LIR* genUnconditionalBranch(CompilationUnit* cUnit, LIR* target)
{
- LIR* branch = opCondBranch(cUnit, cond);
+ LIR* branch = opNone(cUnit, kOpUncondBr);
branch->target = (LIR*) target;
return branch;
}
-/* Generate unconditional branch instructions */
-LIR* genUnconditionalBranch(CompilationUnit* cUnit, LIR* target)
+// FIXME: need to do some work to split out targets with
+// condition codes and those without
+#if defined(TARGET_ARM) || defined(TARGET_X86)
+/* Generate conditional branch instructions */
+LIR* genConditionalBranch(CompilationUnit* cUnit, ConditionCode cond,
+ LIR* target)
{
- LIR* branch = opNone(cUnit, kOpUncondBr);
+ LIR* branch = opCondBranch(cUnit, cond);
branch->target = (LIR*) target;
return branch;
}
@@ -72,6 +76,7 @@ LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir,
oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
return branch;
}
+#endif
LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode,
int reg, int immVal, MIR* mir, ThrowKind kind)
@@ -112,8 +117,12 @@ LIR* genRegRegCheck(CompilationUnit* cUnit, ConditionCode cCode,
tgt->operands[1] = mir ? mir->offset : 0;
tgt->operands[2] = reg1;
tgt->operands[3] = reg2;
+#if defined(TARGET_MIPS)
+ LIR* branch = genCompareBranch(cUnit, cCode, reg1, reg2);
+#else
opRegReg(cUnit, kOpCmp, reg1, reg2);
LIR* branch = genConditionalBranch(cUnit, cCode, tgt);
+#endif
// Remember branch target - will process later
oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
return branch;
@@ -125,7 +134,6 @@ void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
ConditionCode cond;
rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
- opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
Opcode opcode = mir->dalvikInsn.opcode;
switch(opcode) {
case OP_IF_EQ:
@@ -150,7 +158,13 @@ void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
cond = (ConditionCode)0;
LOG(FATAL) << "Unexpected opcode " << (int)opcode;
}
+#if defined(TARGET_MIPS)
+ LIR* branch = genCompareBranch(cUnit, cond, rlSrc1.lowReg, rlSrc2.lowReg);
+ branch->target = &labelList[bb->taken->id];
+#else
+ opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
+#endif
genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
}
@@ -159,7 +173,6 @@ void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
{
ConditionCode cond;
rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
Opcode opcode = mir->dalvikInsn.opcode;
switch(opcode) {
case OP_IF_EQZ:
@@ -184,7 +197,13 @@ void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
cond = (ConditionCode)0;
LOG(FATAL) << "Unexpected opcode " << (int)opcode;
}
+#if defined(TARGET_MIPS)
+ LIR* branch = genCmpImmBranch(cUnit, cond, rlSrc.lowReg, 0);
+ branch->target = &labelList[bb->taken->id];
+#else
+ opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
+#endif
genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
}
@@ -319,7 +338,11 @@ void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
int rSrc = oatAllocTemp(cUnit);
int rDst = oatAllocTemp(cUnit);
int rIdx = oatAllocTemp(cUnit);
+#if defined(TARGET_ARM)
int rVal = rLR; // Using a lot of temps, rLR is known free here
+#else
+ int rVal = oatAllocTemp(cUnit);
+#endif
// Set up source pointer
RegLocation rlFirst = oatGetSrc(cUnit, mir, 0);
opRegRegImm(cUnit, kOpAdd, rSrc, rSP,
@@ -340,8 +363,9 @@ void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
LIR* branch = opCondBranch(cUnit, kCondGe);
#else
+ oatFreeTemp(cUnit, rVal);
opRegImm(cUnit, kOpSub, rIdx, 1);
- LIR* branch = opCompareBranchImm(cUnit, kCondGe, rIdx, 0);
+ LIR* branch = genCmpImmBranch(cUnit, kCondGe, rIdx, 0);
#endif
branch->target = (LIR*)target;
} else if (!isRange) {
@@ -637,11 +661,11 @@ void handleThrowLaunchpads(CompilationUnit *cUnit)
funcOffset = OFFSETOF_MEMBER(Thread, pThrowNullPointerFromCode);
break;
case kThrowArrayBounds:
- if (v2 != r0) {
+ if (v2 != rARG0) {
genRegCopy(cUnit, rARG0, v1);
genRegCopy(cUnit, rARG1, v2);
} else {
- if (v1 == r1) {
+ if (v1 == rARG1) {
#if defined(TARGET_ARM)
int rTmp = r12;
#else
@@ -860,7 +884,7 @@ void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
// TUNING: move slow path to end & remove unconditional branch
LIR* target1 = newLIR0(cUnit, kPseudoTargetLabel);
target1->defMask = ENCODE_ALL;
- // Call out to helper, which will return resolved type in r0
+ // Call out to helper, which will return resolved type in rARG0
int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pInitializeTypeFromCode));
genRegCopy(cUnit, rARG1, mReg);
@@ -909,7 +933,7 @@ void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
genRegCopy(cUnit, rARG0, rARG2); // .eq
opReg(cUnit, kOpBlx, rTgt); // .eq, helper(Method*, string_idx)
#else
- LIR* branch = genCmpImmBranch(cUnit, kCondNe, 0);
+ LIR* branch = genCmpImmBranch(cUnit, kCondNe, rRET0, 0);
genRegCopy(cUnit, rARG0, rARG2); // .eq
opReg(cUnit, kOpBlx, rTgt);
LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
@@ -961,22 +985,22 @@ void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
// May generate a call - use explicit registers
oatLockCallTemps(cUnit);
uint32_t type_idx = mir->dalvikInsn.vC;
- loadCurrMethodDirect(cUnit, rARG1); // r1 <= current Method*
+ loadCurrMethodDirect(cUnit, rARG1); // rARG1 <= current Method*
int classReg = rARG2; // rARG2 will hold the Class*
if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
cUnit->dex_cache,
*cUnit->dex_file,
type_idx)) {
// Check we have access to type_idx and if not throw IllegalAccessError,
- // returns Class* in r0
+ // returns Class* in rARG0
int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pInitializeTypeAndVerifyAccessFromCode));
loadConstant(cUnit, rARG0, type_idx);
callRuntimeHelper(cUnit, rTgt); // InitializeTypeAndVerifyAccess(idx, method)
genRegCopy(cUnit, classReg, rRET0); // Align usage with fast path
- loadValueDirectFixed(cUnit, rlSrc, rARG0); // r0 <= ref
+ loadValueDirectFixed(cUnit, rlSrc, rARG0); // rARG0 <= ref
} else {
- // Load dex cache entry into classReg (r2)
+ // Load dex cache entry into classReg (rARG2)
loadValueDirectFixed(cUnit, rlSrc, rARG0); // rARG0 <= ref
loadWordDisp(cUnit, rARG1,
Method::DexCacheResolvedTypesOffset().Int32Value(),
@@ -995,7 +1019,7 @@ void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
pInitializeTypeFromCode));
loadConstant(cUnit, rARG0, type_idx);
callRuntimeHelper(cUnit, rTgt); // InitializeTypeFromCode(idx, method)
- genRegCopy(cUnit, r2, rRET0); // Align usage with fast path
+ genRegCopy(cUnit, rARG2, rRET0); // Align usage with fast path
loadValueDirectFixed(cUnit, rlSrc, rARG0); /* reload Ref */
// Rejoin code paths
LIR* hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
@@ -1021,6 +1045,7 @@ void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
genBarrier(cUnit);
oatClobberCalleeSave(cUnit);
#else
+ (void)rTgt;
// Perhaps a general-purpose kOpSelect operator?
UNIMPLEMENTED(FATAL) << "Need non IT implementation";
#endif
@@ -1065,18 +1090,18 @@ void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
// Need to test presence of type in dex cache at runtime
LIR* hopBranch = genCmpImmBranch(cUnit, kCondNe, classReg, 0);
// Not resolved
- // Call out to helper, which will return resolved type in r0
- loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
- loadConstant(cUnit, r0, type_idx);
- callRuntimeHelper(cUnit, rLR); // InitializeTypeFromCode(idx, method)
- genRegCopy(cUnit, classReg, r0); // Align usage with fast path
+ // Call out to helper, which will return resolved type in rARG0
+ int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode));
+ loadConstant(cUnit, rARG0, type_idx);
+ callRuntimeHelper(cUnit, rTgt); // InitializeTypeFromCode(idx, method)
+ genRegCopy(cUnit, classReg, rARG0); // Align usage with fast path
// Rejoin code paths
LIR* hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
hopTarget->defMask = ENCODE_ALL;
hopBranch->target = (LIR*)hopTarget;
}
}
- // At this point, classReg (r2) has class
+ // At this point, classReg (rARG2) has class
loadValueDirectFixed(cUnit, rlSrc, rARG0); // rARG0 <= ref
/* Null is OK - continue */
LIR* branch1 = genCmpImmBranch(cUnit, kCondEq, rARG0, 0);
@@ -1086,8 +1111,12 @@ void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
/* rARG1 now contains object->clazz */
int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pCheckCastFromCode));
+#if defined(TARGET_MIPS)
+ LIR* branch2 = genCompareBranch(cUnit, kCondEq, rARG1, classReg);
+#else
opRegReg(cUnit, kOpCmp, rARG1, classReg);
LIR* branch2 = opCondBranch(cUnit, kCondEq); /* If equal, trivial yes */
+#endif
genRegCopy(cUnit, rARG0, rARG1);
genRegCopy(cUnit, rARG1, rARG2);
callRuntimeHelper(cUnit, rTgt);
@@ -1430,7 +1459,7 @@ bool genArithOpInt(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
funcOffset = OFFSETOF_MEMBER(Thread, pIdiv);
retReg = rRET0;
break;
- /* NOTE: returns in r1 */
+ /* NOTE: returns in rARG1 */
case OP_REM_INT:
case OP_REM_INT_2ADDR:
callOut = true;
@@ -1598,8 +1627,12 @@ void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
RegLocation rlResult, int lit,
int firstBit, int secondBit)
{
+#if defined(TARGET_MIPS)
+ UNIMPLEMENTED(FATAL) << "Need shift & add primative";
+#else
opRegRegRegShift(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg,
encodeShift(kArmLsl, secondBit - firstBit));
+#endif
if (firstBit != 0) {
opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
}
@@ -1882,7 +1915,7 @@ bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
genCheck(cUnit, kCondEq, mir, kThrowDivZero);
#else
opRegRegReg(cUnit, kOpOr, tReg, rARG2, rARG3);
- genImmedCheck(cUnit, kCondEq, mir, tReg, 0, mir, kThrowDivZero);
+ genImmedCheck(cUnit, kCondEq, tReg, 0, mir, kThrowDivZero);
oatFreeTemp(cUnit, tReg);
#endif
} else {
@@ -2116,7 +2149,7 @@ void genSuspendTest(CompilationUnit* cUnit, MIR* mir)
branch = opCondBranch(cUnit, kCondEq);
#else
opRegImm(cUnit, kOpSub, rSUSPEND, 1);
- branch = opCompareBranchImm(cUnit, kCondEq, rSUSPEND, 0);
+ branch = genCmpImmBranch(cUnit, kCondEq, rSUSPEND, 0);
#endif
}
LIR* retLab = newLIR0(cUnit, kPseudoTargetLabel);