diff options
Diffstat (limited to 'src/compiler/codegen/arm')
| -rw-r--r-- | src/compiler/codegen/arm/ArchFactory.cc | 57 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArchUtility.cc | 68 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 42 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Assemble.cc | 12 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Codegen.h | 21 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Factory.cc | 43 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 213 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Ralloc.cc | 11 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/armv7-a/Codegen.cc | 1 |
9 files changed, 370 insertions, 98 deletions
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc index ba49277a3f..f85bd2fff5 100644 --- a/src/compiler/codegen/arm/ArchFactory.cc +++ b/src/compiler/codegen/arm/ArchFactory.cc @@ -14,20 +14,12 @@ * limitations under the License. */ -/* - * This file contains arm-specific codegen factory support. - * It is included by - * - * Codegen-$(TARGET_ARCH_VARIANT).c - * - */ +/* This file contains arm-specific codegen factory support. */ #include "oat/runtime/oat_support_entrypoints.h" namespace art { -void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset); - bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc) { @@ -104,13 +96,6 @@ void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs, flushIns(cUnit, argLocs, rlMethod); - if (cUnit->genDebugger) { - // Refresh update debugger callout - loadWordDisp(cUnit, rSELF, - ENTRYPOINT_OFFSET(pUpdateDebuggerFromCode), rSUSPEND); - genDebuggerUpdate(cUnit, DEBUGGER_METHOD_ENTRY); - } - oatFreeTemp(cUnit, r0); oatFreeTemp(cUnit, r1); oatFreeTemp(cUnit, r2); @@ -128,10 +113,6 @@ void genExitSequence(CompilationUnit* cUnit) oatLockTemp(cUnit, r1); newLIR0(cUnit, kPseudoMethodExit); - /* If we're compiling for the debugger, generate an update callout */ - if (cUnit->genDebugger) { - genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT); - } opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize - (spillCount * 4)); /* Need to restore any FP callee saves? */ if (cUnit->numFPSpills) { @@ -207,4 +188,40 @@ bool oatArchInit() return oatArchVariantInit(); } + +bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) +{ + LOG(FATAL) << "Unexpected use of genAddLong for Arm"; + return false; +} + +bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) +{ + LOG(FATAL) << "Unexpected use of genSubLong for Arm"; + return false; +} + +bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) +{ + LOG(FATAL) << "Unexpected use of genAndLong for Arm"; + return false; +} + +bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) +{ + LOG(FATAL) << "Unexpected use of genOrLong for Arm"; + return false; +} + +bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) +{ + LOG(FATAL) << "Unexpected use of genXoLong for Arm"; + return false; +} + } // namespace art diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc index cdb8486f50..820f64e643 100644 --- a/src/compiler/codegen/arm/ArchUtility.cc +++ b/src/compiler/codegen/arm/ArchUtility.cc @@ -22,6 +22,74 @@ namespace art { +void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) +{ + DCHECK_EQ(cUnit->instructionSet, kThumb2); + + // Thumb2 specific setup + int flags = EncodingMap[lir->opcode].flags; + int opcode = lir->opcode; + + if (flags & REG_DEF_LIST0) { + lir->defMask |= ENCODE_REG_LIST(lir->operands[0]); + } + + if (flags & REG_DEF_LIST1) { + lir->defMask |= ENCODE_REG_LIST(lir->operands[1]); + } + + if (flags & REG_DEF_FPCS_LIST0) { + lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]); + } + + if (flags & REG_DEF_FPCS_LIST2) { + for (int i = 0; i < lir->operands[2]; i++) { + oatSetupRegMask(cUnit, &lir->defMask, lir->operands[1] + i); + } + } + + if (flags & REG_USE_PC) { + lir->useMask |= ENCODE_REG_PC; + } + + /* Conservatively treat the IT block */ + if (flags & IS_IT) { + lir->defMask = ENCODE_ALL; + } + + if (flags & REG_USE_LIST0) { + lir->useMask |= ENCODE_REG_LIST(lir->operands[0]); + } + + if (flags & REG_USE_LIST1) { + lir->useMask |= ENCODE_REG_LIST(lir->operands[1]); + } + + if (flags & REG_USE_FPCS_LIST0) { + lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]); + } + + if (flags & REG_USE_FPCS_LIST2) { + for (int i = 0; i < lir->operands[2]; i++) { + oatSetupRegMask(cUnit, &lir->useMask, lir->operands[1] + i); + } + } + /* Fixup for kThumbPush/lr and kThumbPop/pc */ + if (opcode == kThumbPush || opcode == kThumbPop) { + u8 r8Mask = oatGetRegMaskCommon(cUnit, r8); + if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) { + lir->useMask &= ~r8Mask; + lir->useMask |= ENCODE_REG_LR; + } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) { + lir->defMask &= ~r8Mask; + lir->defMask |= ENCODE_REG_PC; + } + } + if (flags & REG_DEF_LR) { + lir->defMask |= ENCODE_REG_LR; + } +} + ArmConditionCode oatArmConditionEncoding(ConditionCode code) { ArmConditionCode res; diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h index 1da567e177..407ad793c0 100644 --- a/src/compiler/codegen/arm/ArmLIR.h +++ b/src/compiler/codegen/arm/ArmLIR.h @@ -258,6 +258,7 @@ enum NativeRegisterPool { #define rRET0 r0 #define rRET1 r1 #define rINVOKE_TGT rLR +#define rCOUNT INVALID_REG /* Shift encodings */ enum ArmShiftEncodings { @@ -267,26 +268,6 @@ enum ArmShiftEncodings { kArmRor = 0x3 }; -/* Thumb condition encodings */ -enum ArmConditionCode { - kArmCondEq = 0x0, /* 0000 */ - kArmCondNe = 0x1, /* 0001 */ - kArmCondCs = 0x2, /* 0010 */ - kArmCondCc = 0x3, /* 0011 */ - kArmCondMi = 0x4, /* 0100 */ - kArmCondPl = 0x5, /* 0101 */ - kArmCondVs = 0x6, /* 0110 */ - kArmCondVc = 0x7, /* 0111 */ - kArmCondHi = 0x8, /* 1000 */ - kArmCondLs = 0x9, /* 1001 */ - kArmCondGe = 0xa, /* 1010 */ - kArmCondLt = 0xb, /* 1011 */ - kArmCondGt = 0xc, /* 1100 */ - kArmCondLe = 0xd, /* 1101 */ - kArmCondAl = 0xe, /* 1110 */ - kArmCondNv = 0xf, /* 1111 */ -}; - #define isPseudoOpcode(opcode) ((int)(opcode) < 0) /* @@ -295,26 +276,9 @@ enum ArmConditionCode { * Assemble.cc. */ enum ArmOpcode { - kPseudoExportedPC = -18, - kPseudoSafepointPC = -17, - kPseudoIntrinsicRetry = -16, - kPseudoSuspendTarget = -15, - kPseudoThrowTarget = -14, - kPseudoCaseLabel = -13, - kPseudoMethodEntry = -12, - kPseudoMethodExit = -11, - kPseudoBarrier = -10, - kPseudoExtended = -9, - kPseudoSSARep = -8, - kPseudoEntryBlock = -7, - kPseudoExitBlock = -6, - kPseudoTargetLabel = -5, - kPseudoDalvikByteCodeBoundary = -4, - kPseudoPseudoAlign4 = -3, - kPseudoEHBlockLabel = -2, - kPseudoNormalBlockLabel = -1, /************************************************************************/ - kArm16BitData, /* DATA [0] rd[15..0] */ + kArmFirst = 0, + kArm16BitData = kArmFirst, /* DATA [0] rd[15..0] */ kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */ kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/ kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */ diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc index ede3f6152c..759ffd3bd2 100644 --- a/src/compiler/codegen/arm/Assemble.cc +++ b/src/compiler/codegen/arm/Assemble.cc @@ -1070,7 +1070,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, // Change the load to be relative to the new Adr base lir->operands[1] = baseReg; lir->operands[2] = 0; - oatSetupResourceMasks(lir); + oatSetupResourceMasks(cUnit, lir); res = kRetryAll; } else { if ((lir->opcode == kThumb2Vldrs) || @@ -1101,7 +1101,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, /* operand[0] is src1 in both cb[n]z & CmpRI8 */ lir->operands[1] = 0; lir->target = 0; - oatSetupResourceMasks(lir); + oatSetupResourceMasks(cUnit, lir); res = kRetryAll; } else { lir->operands[1] = delta >> 1; @@ -1126,7 +1126,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, } } lir->operands[0] = reg; - oatSetupResourceMasks(lir); + oatSetupResourceMasks(cUnit, lir); res = kRetryAll; } } else if (lir->opcode == kThumbBCond || lir->opcode == kThumb2BCond) { @@ -1138,7 +1138,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, delta = target - pc; if ((lir->opcode == kThumbBCond) && (delta > 254 || delta < -256)) { lir->opcode = kThumb2BCond; - oatSetupResourceMasks(lir); + oatSetupResourceMasks(cUnit, lir); res = kRetryAll; } lir->operands[0] = delta >> 1; @@ -1162,7 +1162,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, // Convert to Thumb2BCond w/ kArmCondAl lir->opcode = kThumb2BUncond; lir->operands[0] = 0; - oatSetupResourceMasks(lir); + oatSetupResourceMasks(cUnit, lir); res = kRetryAll; } else { lir->operands[0] = delta >> 1; @@ -1221,7 +1221,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, lir->opcode = kThumb2AddRRR; lir->operands[1] = rPC; lir->operands[2] = lir->operands[0]; - oatSetupResourceMasks(lir); + oatSetupResourceMasks(cUnit, lir); res = kRetryAll; } } else if (lir->opcode == kThumb2MovImm16LST) { diff --git a/src/compiler/codegen/arm/Codegen.h b/src/compiler/codegen/arm/Codegen.h index 22f6157228..0890c15bab 100644 --- a/src/compiler/codegen/arm/Codegen.h +++ b/src/compiler/codegen/arm/Codegen.h @@ -14,13 +14,7 @@ * limitations under the License. */ -/* - * This file contains register alloction support and is intended to be - * included by: - * - * Codegen-$(TARGET_ARCH_VARIANT).c - * - */ +/* This file contains register alloction support. */ #include "../../CompilerIR.h" @@ -91,8 +85,19 @@ inline s4 s4FromSwitchData(const void* switchData) { #endif -extern void oatSetupResourceMasks(LIR* lir); +extern void oatSetupResourceMasks(CompilationUnit* cUnit, LIR* lir); extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); +bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); +bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2); + } // namespace art diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc index c6cb220107..c373e35286 100644 --- a/src/compiler/codegen/arm/Thumb2/Factory.cc +++ b/src/compiler/codegen/arm/Thumb2/Factory.cc @@ -16,13 +16,7 @@ namespace art { -/* - * This file contains codegen for the Thumb ISA and is intended to be - * includes by: - * - * Codegen-$(TARGET_ARCH_VARIANT).c - * - */ +/* This file contains codegen for the Thumb ISA. */ static int coreRegs[] = {r0, r1, r2, r3, rSUSPEND, r5, r6, r7, r8, rSELF, r10, r11, r12, rSP, rLR, rPC}; @@ -1035,6 +1029,41 @@ LIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc) return res; } +LIR* opThreadMem(CompilationUnit* cUnit, OpKind op, int threadOffset) +{ + LOG(FATAL) << "Unexpected use of opThreadMem for Arm"; + return NULL; +} + +LIR* opMem(CompilationUnit* cUnit, OpKind op, int rBase, int disp) +{ + LOG(FATAL) << "Unexpected use of opMem for Arm"; + return NULL; +} +LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, + int rBase, int rIndex, int scale, int displacement, + int rSrc, int rSrcHi, + OpSize size, int sReg) +{ + LOG(FATAL) << "Unexpected use of storeBaseIndexedDisp for Arm"; + return NULL; +} + +LIR* opRegMem(CompilationUnit *cUnit, OpKind op, int rDest, int rBase, + int offset) +{ + LOG(FATAL) << "Unexpected use of opRegMem for Arm"; + return NULL; +} + +LIR* loadBaseIndexedDisp(CompilationUnit *cUnit, + int rBase, int rIndex, int scale, int displacement, + int rDest, int rDestHi, + OpSize size, int sReg) +{ + LOG(FATAL) << "Unexpected use of loadBaseIndexedDisp for Arm"; + return NULL; +} } // namespace art diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index 3584a52e36..cbe6b14b0e 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -14,13 +14,7 @@ * limitations under the License. */ -/* - * This file contains codegen for the Thumb2 ISA and is intended to be - * includes by: - * - * Codegen-$(TARGET_ARCH_VARIANT).c - * - */ +/* This file contains codegen for the Thumb2 ISA. */ #include "oat_compilation_unit.h" #include "oat/runtime/oat_support_entrypoints.h" @@ -308,6 +302,13 @@ void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, } } +LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, + int src2, LIR* target) +{ + opRegReg(cUnit, kOpCmp, src1, src2); + return opCondBranch(cUnit, cond, target); +} + /* * Generate a Thumb2 IT instruction, which can nullify up to * four subsequent instructions based on a condition and its @@ -730,7 +731,7 @@ LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc) { LIR* res; - ArmOpcode opcode; + int opcode; if (FPREG(rDest) || FPREG(rSrc)) return fpRegCopy(cUnit, rDest, rSrc); if (LOWREG(rDest) && LOWREG(rSrc)) @@ -863,4 +864,200 @@ bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode, return true; } +/* + * Mark garbage collection card. Skip if the value we're storing is null. + */ +void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg) +{ + int regCardBase = oatAllocTemp(cUnit); + int regCardNo = oatAllocTemp(cUnit); + LIR* branchOver = opCmpImmBranch(cUnit, kCondEq, valReg, 0, NULL); + loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(), regCardBase); + opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, CardTable::kCardShift); + storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0, + kUnsignedByte); + LIR* target = newLIR0(cUnit, kPseudoTargetLabel); + branchOver->target = (LIR*)target; + oatFreeTemp(cUnit, regCardBase); + oatFreeTemp(cUnit, regCardNo); +} + +LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode, + int reg1, int base, int offset, ThrowKind kind) +{ + LOG(FATAL) << "Unexpected use of genRegMemCheck for Arm"; + return NULL; +} + +RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int lit, bool isDiv) +{ + LOG(FATAL) << "Unexpected use of genDivRemLit for Arm"; + return rlDest; +} + +RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int reg2, bool isDiv) +{ + LOG(FATAL) << "Unexpected use of genDivRem for Arm"; + return rlDest; +} + +bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin) +{ + DCHECK_EQ(cUnit->instructionSet, kThumb2); + RegLocation rlSrc1 = info->args[0]; + RegLocation rlSrc2 = info->args[1]; + rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg); + rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg); + RegLocation rlDest = inlineTarget(cUnit, info); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg); + opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E"); + opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg); + opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg); + genBarrier(cUnit); + storeValue(cUnit, rlDest, rlResult); + return true; +} + +void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset) +{ + LOG(FATAL) << "Unexpected use of opLea for Arm"; +} + +void opTlsCmp(CompilationUnit* cUnit, int offset, int val) +{ + LOG(FATAL) << "Unexpected use of opTlsCmp for Arm"; +} + +bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier) { + DCHECK_EQ(cUnit->instructionSet, kThumb2); + // Unused - RegLocation rlSrcUnsafe = info->args[0]; + RegLocation rlSrcObj= info->args[1]; // Object - known non-null + RegLocation rlSrcOffset= info->args[2]; // long low + rlSrcOffset.wide = 0; // ignore high half in info->args[3] + RegLocation rlSrcExpected= info->args[4]; // int or Object + RegLocation rlSrcNewValue= info->args[5]; // int or Object + RegLocation rlDest = inlineTarget(cUnit, info); // boolean place for result + + + // Release store semantics, get the barrier out of the way. + oatGenMemBarrier(cUnit, kSY); + + RegLocation rlObject = loadValue(cUnit, rlSrcObj, kCoreReg); + RegLocation rlNewValue = loadValue(cUnit, rlSrcNewValue, kCoreReg); + + if (need_write_barrier) { + // Mark card for object assuming new value is stored. + markGCCard(cUnit, rlNewValue.lowReg, rlObject.lowReg); + } + + RegLocation rlOffset = loadValue(cUnit, rlSrcOffset, kCoreReg); + + int rPtr = oatAllocTemp(cUnit); + opRegRegReg(cUnit, kOpAdd, rPtr, rlObject.lowReg, rlOffset.lowReg); + + // Free now unneeded rlObject and rlOffset to give more temps. + oatClobberSReg(cUnit, rlObject.sRegLow); + oatFreeTemp(cUnit, rlObject.lowReg); + oatClobberSReg(cUnit, rlOffset.sRegLow); + oatFreeTemp(cUnit, rlOffset.lowReg); + + int rOldValue = oatAllocTemp(cUnit); + newLIR3(cUnit, kThumb2Ldrex, rOldValue, rPtr, 0); // rOldValue := [rPtr] + + RegLocation rlExpected = loadValue(cUnit, rlSrcExpected, kCoreReg); + + // if (rOldValue == rExpected) { + // [rPtr] <- rNewValue && rResult := success ? 0 : 1 + // rResult ^= 1 + // } else { + // rResult := 0 + // } + opRegReg(cUnit, kOpCmp, rOldValue, rlExpected.lowReg); + oatFreeTemp(cUnit, rOldValue); // Now unneeded. + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + opIT(cUnit, kArmCondEq, "TE"); + newLIR4(cUnit, kThumb2Strex, rlResult.lowReg, rlNewValue.lowReg, rPtr, 0); + oatFreeTemp(cUnit, rPtr); // Now unneeded. + opRegImm(cUnit, kOpXor, rlResult.lowReg, 1); + opRegReg(cUnit, kOpXor, rlResult.lowReg, rlResult.lowReg); + + storeValue(cUnit, rlDest, rlResult); + + return true; +} + +bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) { + DCHECK_EQ(cUnit->instructionSet, kThumb2); + LIR *branch; + RegLocation rlSrc = info->args[0]; + RegLocation rlDest = inlineTargetWide(cUnit, info); // double place for result + rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); + newLIR2(cUnit, kThumb2Vsqrtd, S2D(rlResult.lowReg, rlResult.highReg), + S2D(rlSrc.lowReg, rlSrc.highReg)); + newLIR2(cUnit, kThumb2Vcmpd, S2D(rlResult.lowReg, rlResult.highReg), + S2D(rlResult.lowReg, rlResult.highReg)); + newLIR0(cUnit, kThumb2Fmstat); + branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq); + oatClobberCalleeSave(cUnit); + oatLockCallTemps(cUnit); // Using fixed registers + int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pSqrt)); + newLIR3(cUnit, kThumb2Fmrrd, r0, r1, S2D(rlSrc.lowReg, rlSrc.highReg)); + newLIR1(cUnit, kThumbBlxR, rTgt); + newLIR3(cUnit, kThumb2Fmdrr, S2D(rlResult.lowReg, rlResult.highReg), r0, r1); + branch->target = newLIR0(cUnit, kPseudoTargetLabel); + storeValueWide(cUnit, rlDest, rlResult); + return true; +} + +LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target) +{ + return rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2LdrPcRel12, reg, 0, 0, 0, 0, target); +} + +LIR* opVldm(CompilationUnit* cUnit, int rBase, int count) +{ + return newLIR3(cUnit, kThumb2Vldms, rBase, fr0, count); +} + +LIR* opVstm(CompilationUnit* cUnit, int rBase, int count) +{ + return newLIR3(cUnit, kThumb2Vstms, rBase, fr0, count); +} + +void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc, + RegLocation rlResult, int lit, + int firstBit, int secondBit) +{ + opRegRegRegShift(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg, + encodeShift(kArmLsl, secondBit - firstBit)); + if (firstBit != 0) { + opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit); + } +} + +void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi) +{ + int tReg = oatAllocTemp(cUnit); + newLIR4(cUnit, kThumb2OrrRRRs, tReg, regLo, regHi, 0); + oatFreeTemp(cUnit, tReg); + genCheck(cUnit, kCondEq, kThrowDivZero); +} + +// Test suspend flag, return target of taken suspend branch +LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target) +{ + newLIR2(cUnit, kThumbSubRI8, rSUSPEND, 1); + return opCondBranch(cUnit, (target == NULL) ? kCondEq : kCondNe, target); +} + +// Decrement register and branch on condition +LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target) +{ + // Combine sub & test using sub setflags encoding here + newLIR3(cUnit, kThumb2SubsRRI12, reg, reg, 1); + return opCondBranch(cUnit, cCode, target); +} + } // namespace art diff --git a/src/compiler/codegen/arm/Thumb2/Ralloc.cc b/src/compiler/codegen/arm/Thumb2/Ralloc.cc index 98a110cb2b..894488a073 100644 --- a/src/compiler/codegen/arm/Thumb2/Ralloc.cc +++ b/src/compiler/codegen/arm/Thumb2/Ralloc.cc @@ -16,13 +16,7 @@ namespace art { -/* - * This file contains codegen for the Thumb ISA and is intended to be - * includes by: - * - * Codegen-$(TARGET_ARCH_VARIANT).c - * - */ +/* This file contains codegen for the Thumb ISA. */ /* * Alloc a pair of core registers, or a double. Low reg in low byte, @@ -74,8 +68,7 @@ void oatInitializeRegAlloc(CompilationUnit* cUnit) oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs); // Keep special registers from being allocated for (int i = 0; i < numReserved; i++) { - if (NO_SUSPEND && !cUnit->genDebugger && - (reservedRegs[i] == rSUSPEND)) { + if (NO_SUSPEND && (reservedRegs[i] == rSUSPEND)) { //To measure cost of suspend check continue; } diff --git a/src/compiler/codegen/arm/armv7-a/Codegen.cc b/src/compiler/codegen/arm/armv7-a/Codegen.cc index ba1e7ab121..c398b8ebfc 100644 --- a/src/compiler/codegen/arm/armv7-a/Codegen.cc +++ b/src/compiler/codegen/arm/armv7-a/Codegen.cc @@ -15,7 +15,6 @@ */ #define _CODEGEN_C #define _ARMV7_A -#define TARGET_ARM #include "../../../Dalvik.h" #include "../../../CompilerInternals.h" |