Add switch and comparison tests. Fix ralloc bug
We normally have 5 registers in our temp pool, but up to 6 may be
needed for long 3-operand operations. Added a workaround to temporarily
add lr to the temp pool in that specific case.
Moved the bulk of the compiler_test code out of common_test.h into
compiler_test.h. Added switch and compare unit tests.
Change-Id: Ib449c49861acb5aaef716e8538e5818ba74522cb
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h
index 12e5f13..b1e14ec 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/Ralloc.h
@@ -97,6 +97,8 @@
extern void oatMarkTemp(CompilationUnit* cUnit, int reg);
+extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg);
+
extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc);
extern void oatMarkPair(CompilationUnit* cUnit, int lowReg,
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index 30b5280..3b222f6 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -783,6 +783,12 @@
info->isTemp = true;
}
+extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg)
+{
+ RegisterInfo* info = getRegInfo(cUnit, reg);
+ info->isTemp = false;
+}
+
extern void oatMarkPair(CompilationUnit* cUnit, int lowReg, int highReg)
{
RegisterInfo* infoLo = getRegInfo(cUnit, lowReg);
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc
index 9a5bd40..19b9445 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -967,8 +967,8 @@
#define PADDING_MOV_R5_R5 0x1C2D
static void pushWord(std::vector<short>&buf, int data) {
- buf.push_back( (data >> 16) & 0xffff);
buf.push_back( data & 0xffff);
+ buf.push_back( (data >> 16) & 0xffff);
}
void alignBuffer(std::vector<short>&buf, size_t offset) {
@@ -999,7 +999,7 @@
alignBuffer(cUnit->codeBuffer, tabRec->offset);
int bxOffset = tabRec->bxInst->generic.offset + 4;
if (cUnit->printMe) {
- LOG(INFO) << "Switch table for offset 0x" /*<< hex*/ << bxOffset;
+ LOG(INFO) << "Switch table for offset 0x" << std::hex << bxOffset;
}
if (tabRec->table[0] == kSparseSwitchSignature) {
int* keys = (int*)&(tabRec->table[2]);
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 4a2bdb3..934a303 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -710,7 +710,17 @@
OpKind secondOp, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlSrc2)
{
+ /*
+ * NOTE: This is the one place in the code in which we might have
+ * as many as six live temporary registers. There are 5 in the normal
+ * set for Arm. Until we have spill capabilities, temporarily add
+ * lr to the temp set. It is safe to do this locally, but note that
+ * lr is used explicitly elsewhere in the code generator and cannot
+ * normally be used as a general temp register.
+ */
RegLocation rlResult;
+ oatMarkTemp(cUnit, rLR); // Add lr to the temp pool
+ oatFreeTemp(cUnit, rLR); // and make it available
rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -718,6 +728,8 @@
opRegRegReg(cUnit, secondOp, rlResult.highReg, rlSrc1.highReg,
rlSrc2.highReg);
storeValueWide(cUnit, rlDest, rlResult);
+ oatClobber(cUnit, rLR);
+ oatUnmarkTemp(cUnit, rLR); // Remove lr from the temp pool
}
void oatInitializeRegAlloc(CompilationUnit* cUnit)