Remove all TARGET_[ARM|X86|MIPS] #ifdefs
Two steps forward, one step back towards elimination of the
"#include" build model for target-specific compilers. This CL
does some restructuring to eliminate all of the TARGET_xxx #ifdefs
and convert them to run-time tests.
Considerable work is still required to fully eliminate the multiple
builds. In particular, much of the "common" codegen code relies on
macros defined by the target-specific [Arm|X86|Mips]Lir.h include file.
Next step is more restructuring to better isolate target-independent
code generation code.
Change-Id: If6efbde65c48031a48423344d8dc3e2ff2c4ad9d
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index ba49277..f85bd2f 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 @@
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 @@
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 @@
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 cdb8486..820f64e 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 1da567e..407ad79 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -258,6 +258,7 @@
#define rRET0 r0
#define rRET1 r1
#define rINVOKE_TGT rLR
+#define rCOUNT INVALID_REG
/* Shift encodings */
enum ArmShiftEncodings {
@@ -267,26 +268,6 @@
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 @@
* 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 ede3f61..759ffd3 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -1070,7 +1070,7 @@
// 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 @@
/* 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 @@
}
}
lir->operands[0] = reg;
- oatSetupResourceMasks(lir);
+ oatSetupResourceMasks(cUnit, lir);
res = kRetryAll;
}
} else if (lir->opcode == kThumbBCond || lir->opcode == kThumb2BCond) {
@@ -1138,7 +1138,7 @@
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 @@
// 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 @@
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 22f6157..0890c15 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 @@
#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 c6cb220..c373e35 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 @@
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 3584a52..cbe6b14 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 @@
}
}
+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* 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 @@
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 98a110c..894488a 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 @@
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 ba1e7ab..c398b8e 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"