diff options
Diffstat (limited to 'src/compiler/codegen/GenCommon.cc')
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 89 |
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); |