summaryrefslogtreecommitdiffstats
path: root/src/compiler/codegen/mips
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2012-03-02 08:20:26 -0800
committerbuzbee <buzbee@google.com>2012-03-02 13:02:52 -0800
commit82488f563e7f72f8c626052893c1792d76ab3faf (patch)
treee17e3bc62adf8b57bfeb86a3a879dfb099d3d1d7 /src/compiler/codegen/mips
parent013b6f296ff7c0cb6aa5aeb6868df05995eeadb7 (diff)
downloadart-82488f563e7f72f8c626052893c1792d76ab3faf.zip
art-82488f563e7f72f8c626052893c1792d76ab3faf.tar.gz
art-82488f563e7f72f8c626052893c1792d76ab3faf.tar.bz2
Multi-target Codegen cleanup
Trying to get a bit more consistent in the abstraction layer naming: genXXX -> high-level codegen, for ex: genIGet() opXXX -> instruction-level output, for ex: opRegImm() Also more fleshing out of the Mips codegen support. Change-Id: Iafdf397cbb5015bfe3aa2c38680d96c7c05f8bc4
Diffstat (limited to 'src/compiler/codegen/mips')
-rw-r--r--src/compiler/codegen/mips/ArchFactory.cc2
-rw-r--r--src/compiler/codegen/mips/ArchUtility.cc62
-rw-r--r--src/compiler/codegen/mips/Assemble.cc42
-rw-r--r--src/compiler/codegen/mips/Codegen.h14
-rw-r--r--src/compiler/codegen/mips/FP/MipsFP.cc2
-rw-r--r--src/compiler/codegen/mips/Mips32/Factory.cc48
-rw-r--r--src/compiler/codegen/mips/Mips32/Gen.cc115
-rw-r--r--src/compiler/codegen/mips/MipsLIR.h20
-rw-r--r--src/compiler/codegen/mips/MipsRallocUtil.cc2
9 files changed, 125 insertions, 182 deletions
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
index 2cb0731..aaaa50f 100644
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ b/src/compiler/codegen/mips/ArchFactory.cc
@@ -109,7 +109,7 @@ void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
cUnit->frameSize - (spillCount * 4));
genRegRegCheck(cUnit, kCondCc, newSP, checkReg, NULL,
kThrowStackOverflow);
- genRegCopy(cUnit, rSP, newSP); // Establish stack
+ opRegCopy(cUnit, rSP, newSP); // Establish stack
} else {
opRegImm(cUnit, kOpSub, rSP,
cUnit->frameSize - (spillCount * 4));
diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc
index 7f7aeb3..40188ce 100644
--- a/src/compiler/codegen/mips/ArchUtility.cc
+++ b/src/compiler/codegen/mips/ArchUtility.cc
@@ -22,33 +22,6 @@
namespace art {
-MipsConditionCode oatMipsConditionEncoding(ConditionCode code)
-{
- MipsConditionCode res;
- switch(code) {
- case kCondEq: res = kMipsCondEq; break;
- case kCondNe: res = kMipsCondNe; break;
- case kCondCs: res = kMipsCondCs; break;
- case kCondCc: res = kMipsCondCc; break;
- case kCondMi: res = kMipsCondMi; break;
- case kCondPl: res = kMipsCondPl; break;
- case kCondVs: res = kMipsCondVs; break;
- case kCondVc: res = kMipsCondVc; break;
- case kCondHi: res = kMipsCondHi; break;
- case kCondLs: res = kMipsCondLs; break;
- case kCondGe: res = kMipsCondGe; break;
- case kCondLt: res = kMipsCondLt; break;
- case kCondGt: res = kMipsCondGt; break;
- case kCondLe: res = kMipsCondLe; break;
- case kCondAl: res = kMipsCondAl; break;
- case kCondNv: res = kMipsCondNv; break;
- default:
- LOG(FATAL) << "Bad condition code" << (int)code;
- res = (MipsConditionCode)0; // Quiet gcc
- }
- return res;
-}
-
/* For dumping instructions */
#define MIPS_REG_COUNT 32
static const char *mipsRegName[MIPS_REG_COUNT] = {
@@ -112,37 +85,6 @@ std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
case 'F':
sprintf(tbuf,"%d", operand*2);
break;
- case 'c':
- switch (operand) {
- case kMipsCondEq:
- strcpy(tbuf, "eq");
- break;
- case kMipsCondNe:
- strcpy(tbuf, "ne");
- break;
- case kMipsCondLt:
- strcpy(tbuf, "lt");
- break;
- case kMipsCondGe:
- strcpy(tbuf, "ge");
- break;
- case kMipsCondGt:
- strcpy(tbuf, "gt");
- break;
- case kMipsCondLe:
- strcpy(tbuf, "le");
- break;
- case kMipsCondCs:
- strcpy(tbuf, "cs");
- break;
- case kMipsCondMi:
- strcpy(tbuf, "mi");
- break;
- default:
- strcpy(tbuf, "");
- break;
- }
- break;
case 't':
sprintf(tbuf,"0x%08x (L%p)",
(int) baseAddr + lir->offset + 4 +
@@ -172,6 +114,10 @@ std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
strcpy(tbuf, mipsRegName[operand]);
break;
+ case 'N':
+ // Placeholder for delay slot handling
+ strcpy(tbuf, "; nop");
+ break;
default:
strcpy(tbuf,"DecodeError");
break;
diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc
index bf54d23..4deb8f5 100644
--- a/src/compiler/codegen/mips/Assemble.cc
+++ b/src/compiler/codegen/mips/Assemble.cc
@@ -72,10 +72,17 @@ namespace art {
* n -> complimented Thumb2 modified immediate
* M -> Thumb2 16-bit zero-extended immediate
* b -> 4-digit binary
+ * N -> append a NOP
*
* [!] escape. To insert "!", use "!!"
*/
/* NOTE: must be kept in sync with enum MipsOpcode from LIR.h */
+/*
+ * TUNING: We're currently punting on the branch delay slots. All branch
+ * instructions in this map are given a size of 8, which during assembly
+ * is expanded to include a nop. This scheme should be replaced with
+ * an assembler pass to fill those slots when possible.
+ */
MipsEncodingMap EncodingMap[kMipsLast] = {
ENCODING_MAP(kMips32BitData, 0x00000000,
kFmtBitBlt, 31, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
@@ -100,43 +107,43 @@ MipsEncodingMap EncodingMap[kMipsLast] = {
ENCODING_MAP(kMipsB, 0x10000000,
kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH,
- "b", "!0t", 4),
+ "b", "!0t!0N", 8),
ENCODING_MAP(kMipsBal, 0x04110000,
kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH | REG_DEF_LR,
- "bal", "!0t", 4),
+ "bal", "!0t!0N", 8),
ENCODING_MAP(kMipsBeq, 0x10000000,
kFmtBitBlt, 25, 21, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0,
kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_USE01,
- "beq", "!0r,!1r,!2t", 4),
+ "beq", "!0r,!1r,!2t!0N", 8),
ENCODING_MAP(kMipsBeqz, 0x10000000, /* same as beq above with t = $zero */
kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "beqz", "!0r,!1t", 4),
+ "beqz", "!0r,!1t!0N", 8),
ENCODING_MAP(kMipsBgez, 0x04010000,
kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "bgez", "!0r,!1t", 4),
+ "bgez", "!0r,!1t!0N", 8),
ENCODING_MAP(kMipsBgtz, 0x1C000000,
kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "bgtz", "!0r,!1t", 4),
+ "bgtz", "!0r,!1t!0N", 8),
ENCODING_MAP(kMipsBlez, 0x18000000,
kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "blez", "!0r,!1t", 4),
+ "blez", "!0r,!1t!0N", 8),
ENCODING_MAP(kMipsBltz, 0x04000000,
kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "bltz", "!0r,!1t", 4),
+ "bltz", "!0r,!1t!0N", 8),
ENCODING_MAP(kMipsBnez, 0x14000000, /* same as bne below with t = $zero */
kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "bnez", "!0r,!1t", 4),
+ "bnez", "!0r,!1t!0N", 8),
ENCODING_MAP(kMipsBne, 0x14000000,
kFmtBitBlt, 25, 21, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0,
kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_USE01,
- "bne", "!0r,!1r,!2t", 4),
+ "bne", "!0r,!1r,!2t!0N", 8),
ENCODING_MAP(kMipsDiv, 0x0000001a,
kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtBitBlt, 25, 21,
kFmtBitBlt, 20, 16, IS_QUAD_OP | REG_DEF01 | REG_USE23,
@@ -150,15 +157,15 @@ MipsEncodingMap EncodingMap[kMipsLast] = {
ENCODING_MAP(kMipsJal, 0x0c000000,
kFmtBitBlt, 25, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_DEF_LR,
- "jal", "!0T(!0E)", 4),
+ "jal", "!0T(!0E)!0N", 8),
ENCODING_MAP(kMipsJalr, 0x00000009,
kFmtBitBlt, 15, 11, kFmtBitBlt, 25, 21, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_DEF0_USE1,
- "jalr", "!0r,!1r", 4),
+ "jalr", "!0r,!1r!0N", 8),
ENCODING_MAP(kMipsJr, 0x00000008,
kFmtBitBlt, 25, 21, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0,
- "jr", "!0r", 4),
+ "jr", "!0r!0N", 8),
ENCODING_MAP(kMipsLahi, 0x3C000000,
kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0,
@@ -520,10 +527,17 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit,
<< (int)encoder->fieldLoc[i].kind;
}
}
- DCHECK_EQ(encoder->size, 2);
+ DCHECK_EQ(encoder->size, 4);
// FIXME: need multi-endian handling here
cUnit->codeBuffer.push_back((bits >> 16) & 0xffff);
cUnit->codeBuffer.push_back(bits & 0xffff);
+ // TUNING: replace with proper delay slot handling
+ if (encoder->size == 8) {
+ const MipsEncodingMap *encoder = &EncodingMap[kMipsNop];
+ u4 bits = encoder->skeleton;
+ cUnit->codeBuffer.push_back((bits >> 16) & 0xffff);
+ cUnit->codeBuffer.push_back(bits & 0xffff);
+ }
}
return res;
}
diff --git a/src/compiler/codegen/mips/Codegen.h b/src/compiler/codegen/mips/Codegen.h
index 355693c..c6f1d98 100644
--- a/src/compiler/codegen/mips/Codegen.h
+++ b/src/compiler/codegen/mips/Codegen.h
@@ -29,6 +29,10 @@ namespace art {
#if defined(_CODEGEN_C)
LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value);
LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2);
+LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+ int src2, LIR* target);
+LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+ int checkValue, LIR* target);
/* Forward declaraton the portable versions due to circular dependency */
bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
@@ -41,17 +45,13 @@ bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
bool genConversionPortable(CompilationUnit* cUnit, MIR* mir);
-MipsConditionCode oatMipsConditionEncoding(ConditionCode code);
-
int loadHelper(CompilationUnit* cUnit, int offset);
LIR* callRuntimeHelper(CompilationUnit* cUnit, int reg);
RegLocation getRetLoc(CompilationUnit* cUnit);
LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal);
-void genRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
- int srcLo, int srcHi);
-LIR* genRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
-LIR* genCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
- int checkValue);
+void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
+ int srcLo, int srcHi);
+LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
RegLocation rlFree);
diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc
index acbac7f..4501210 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/FP/MipsFP.cc
@@ -217,7 +217,7 @@ static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
loadValueAddress(cUnit, rlSrc1, r_A0);
oatClobber(cUnit, r_A0);
loadValueAddress(cUnit, rlSrc2, r_A1);
- UNIMP(FATAL) << "Need callout to handler";
+ UNIMPLEMENTED(FATAL) << "Need callout to handler";
#if 0
genDispatchToHandler(cUnit, templateOpcode);
#endif
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc
index 2613f2c..46987d3 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/Mips32/Factory.cc
@@ -39,8 +39,6 @@ static int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
#endif
void genBarrier(CompilationUnit *cUnit);
-LIR* genCompareBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
- int src2);
void storePair(CompilationUnit *cUnit, int base, int lowReg,
int highReg);
void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
@@ -145,39 +143,6 @@ LIR *opNone(CompilationUnit *cUnit, OpKind op)
return res;
}
-
-LIR *opCmpBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
- int rs, int rt)
-{
- UNIMPLEMENTED(FATAL);
- return 0;
-}
-LIR *opCmpImmBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
- int rs, int immVal)
-{
- UNIMPLEMENTED(FATAL);
- return 0;
-}
-LIR *opCmpImmBranch(CompilationUnit *cUnit, MipsOpCode cc,
- int rs, int immVal)
-{
- UNIMPLEMENTED(FATAL);
- return 0;
-}
-
-LIR *opCmpBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt)
-{
- LIR *res;
- if (rt < 0) {
- DCHECK(opc >= kMipsBeqz && opc <= kMipsBnez);
- res = newLIR1(cUnit, opc, rs);
- } else {
- DCHECK(opc == kMipsBeq || opc == kMipsBne);
- res = newLIR2(cUnit, opc, rs, rt);
- }
- return res;
-}
-
LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
@@ -187,6 +152,9 @@ LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
case kOpBlx:
opcode = kMipsJalr;
break;
+ case kOpBx:
+ return newLIR1(cUnit, kMipsJr, rDestSrc);
+ break;
default:
LOG(FATAL) << "Bad case in opReg";
}
@@ -656,9 +624,7 @@ LIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
}
}
- UNIMPLEMENTED(FATAL) << "Needs art conversion";
-#if 0
- if (rBase == rFP) {
+ if (rBase == rSP) {
if (load != NULL)
annotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
true /* isLoad */);
@@ -666,7 +632,6 @@ LIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
annotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
true /* isLoad */);
}
-#endif
return load;
}
@@ -760,9 +725,7 @@ LIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
oatFreeTemp(cUnit, rScratch);
}
- UNIMPLEMENTED(FATAL) << "Needs art conversion";
-#if 0
- if (rBase == rFP) {
+ if (rBase == rSP) {
if (store != NULL)
annotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
false /* isLoad */);
@@ -770,7 +733,6 @@ LIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
annotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
false /* isLoad */);
}
-#endif
return res;
}
diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
index 942dbc5..db34ce3 100644
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ b/src/compiler/codegen/mips/Mips32/Gen.cc
@@ -85,13 +85,12 @@ void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
newLIR2(cUnit, kThumb2LdmiaWB, rBase, (1 << rKey) | (1 << rDisp));
opRegReg(cUnit, kOpCmp, rKey, rlSrc.lowReg);
// Go if match. NOTE: No instruction set switch here - must stay Thumb2
- genIT(cUnit, kArmCondEq, "");
+ opIT(cUnit, kArmCondEq, "");
LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
tabRec->bxInst = switchBranch;
// Needs to use setflags encoding here
newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
- LIR* branch = opCondBranch(cUnit, kCondNe);
- branch->target = (LIR*)target;
+ LIR* branch = opCondBranch(cUnit, kCondNe, target);
#endif
}
@@ -130,7 +129,7 @@ void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
}
// Bounds check - if < 0 or >= size continue following switch
opRegImm(cUnit, kOpCmp, keyReg, size-1);
- LIR* branchOver = opCondBranch(cUnit, kCondHi);
+ LIR* branchOver = opCondBranch(cUnit, kCondHi, NULL);
// Load the displacement from the switch table
int dispReg = oatAllocTemp(cUnit);
@@ -201,7 +200,7 @@ void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg,
0x80000000);
- genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
+ opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
storeValueWide(cUnit, rlDest, rlResult);
}
@@ -260,7 +259,7 @@ void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
newLIR3(cUnit, kMipsSlt, t0, rlSrc1.highReg, rlSrc2.highReg);
newLIR3(cUnit, kMipsSlt, t1, rlSrc2.highReg, rlSrc1.highReg);
newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
- LIR* branch = genCmpImmBranch(cUnit, kCondNe, rlResult.lowReg, 0);
+ LIR* branch = opCmpImmBranch(cUnit, kCondNe, rlResult.lowReg, 0, NULL);
newLIR3(cUnit, kMipsSltu, t0, rlSrc1.lowReg, rlSrc2.lowReg);
newLIR3(cUnit, kMipsSltu, t1, rlSrc2.lowReg, rlSrc1.lowReg);
newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
@@ -272,32 +271,71 @@ void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
storeValue(cUnit, rlDest, rlResult);
}
-LIR* genCompareBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
- int src2)
+LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+ int src2, LIR* target)
{
+ LIR* branch;
if (cond == kCondEq) {
- return newLIR2(cUnit, kMipsBeq, src1, src2);
+ branch = newLIR2(cUnit, kMipsBeq, src1, src2);
} else if (cond == kCondNe) {
- return newLIR2(cUnit, kMipsBne, src1, src2);
- }
- //int rRes = oatAllocTemp(cUnit);
- switch(cond) {
- case kCondEq: return newLIR2(cUnit, kMipsBeq, src1, src2);
- case kCondNe: return newLIR2(cUnit, kMipsBne, src1, src2);
- default:
- UNIMPLEMENTED(FATAL) << "Need to flesh out genCompareBranch";
- return NULL;
+ branch = newLIR2(cUnit, kMipsBne, src1, src2);
+ } else {
+ MipsOpCode sltOp;
+ MipsOpCode brOp;
+ bool swapped = false;
+ switch(cond) {
+ case kCondEq: return newLIR2(cUnit, kMipsBeq, src1, src2);
+ case kCondNe: return newLIR2(cUnit, kMipsBne, src1, src2);
+ case kCondCc:
+ sltOp = kMipsSltu;
+ brOp = kMipsBnez;
+ break;
+ case kCondGe:
+ sltOp = kMipsSlt;
+ brOp = kMipsBeqz;
+ break;
+ case kCondGt:
+ sltOp = kMipsSlt;
+ brOp = kMipsBnez;
+ swapped = true;
+ break;
+ case kCondLe:
+ sltOp = kMipsSlt;
+ brOp = kMipsBeqz;
+ swapped = true;
+ break;
+ case kCondLt:
+ sltOp = kMipsSlt;
+ brOp = kMipsBnez;
+ break;
+ default:
+ UNIMPLEMENTED(FATAL) << "No support for ConditionCode: "
+ << (int) cond;
+ return NULL;
+ }
+ int tReg = oatAllocTemp(cUnit);
+ if (swapped) {
+ newLIR3(cUnit, sltOp, tReg, src2, src1);
+ } else {
+ newLIR3(cUnit, sltOp, tReg, src1, src2);
+ }
+ branch = newLIR1(cUnit, brOp, tReg);
+ branch->target = target;
}
+ return branch;
}
-LIR* genCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
- int checkValue)
+LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+ int checkValue, LIR* target)
{
+ LIR* branch;
if (checkValue != 0) {
// TUNING: handle s16 & kCondLt/Mi case using slti
int tReg = oatAllocTemp(cUnit);
loadConstant(cUnit, tReg, checkValue);
- return genCompareBranch(cUnit, cond, reg, tReg);
+ branch = opCmpBranch(cUnit, cond, reg, tReg, target);
+ oatFreeTemp(cUnit, tReg);
+ return branch;
}
MipsOpCode opc;
switch(cond) {
@@ -309,14 +347,19 @@ LIR* genCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
case kCondLt: opc = kMipsBltz; break;
case kCondNe: opc = kMipsBnez; break;
default:
+ // Tuning: use slti when applicable
int tReg = oatAllocTemp(cUnit);
loadConstant(cUnit, tReg, checkValue);
- return genCompareBranch(cUnit, cond, reg, tReg);
+ branch = opCmpBranch(cUnit, cond, reg, tReg, target);
+ oatFreeTemp(cUnit, tReg);
+ return branch;
}
- return newLIR1(cUnit, opc, reg);
+ branch = newLIR1(cUnit, opc, reg);
+ branch->target = target;
+ return branch;
}
-LIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
+LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
{
LIR* res;
MipsOpCode opcode;
@@ -337,14 +380,14 @@ LIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
return res;
}
-LIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
+LIR* opRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
{
- LIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
+ LIR *res = opRegCopyNoInsert(cUnit, rDest, rSrc);
oatAppendLIR(cUnit, (LIR*)res);
return res;
}
-void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
+void opRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
int srcLo, int srcHi)
{
#ifdef __mips_hard_float
@@ -354,7 +397,7 @@ void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
assert(FPREG(destLo) == FPREG(destHi));
if (destFP) {
if (srcFP) {
- genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
+ opRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
} else {
/* note the operands are swapped for the mtc1 instr */
newLIR2(cUnit, kMipsMtc1, srcLo, destLo);
@@ -367,22 +410,22 @@ void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
} else {
// Handle overlap
if (srcHi == destLo) {
- genRegCopy(cUnit, destHi, srcHi);
- genRegCopy(cUnit, destLo, srcLo);
+ opRegCopy(cUnit, destHi, srcHi);
+ opRegCopy(cUnit, destLo, srcLo);
} else {
- genRegCopy(cUnit, destLo, srcLo);
- genRegCopy(cUnit, destHi, srcHi);
+ opRegCopy(cUnit, destLo, srcLo);
+ opRegCopy(cUnit, destHi, srcHi);
}
}
}
#else
// Handle overlap
if (srcHi == destLo) {
- genRegCopy(cUnit, destHi, srcHi);
- genRegCopy(cUnit, destLo, srcLo);
+ opRegCopy(cUnit, destHi, srcHi);
+ opRegCopy(cUnit, destLo, srcLo);
} else {
- genRegCopy(cUnit, destLo, srcLo);
- genRegCopy(cUnit, destHi, srcHi);
+ opRegCopy(cUnit, destLo, srcLo);
+ opRegCopy(cUnit, destHi, srcHi);
}
#endif
}
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index 9baa3c0..67f3131 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -311,26 +311,6 @@ typedef enum MipsShiftEncodings {
kMipsRor = 0x3
} MipsShiftEncodings;
-/* condition encodings */
-typedef enum MipsConditionCode {
- kMipsCondEq = 0x0, /* 0000 */
- kMipsCondNe = 0x1, /* 0001 */
- kMipsCondCs = 0x2, /* 0010 */
- kMipsCondCc = 0x3, /* 0011 */
- kMipsCondMi = 0x4, /* 0100 */
- kMipsCondPl = 0x5, /* 0101 */
- kMipsCondVs = 0x6, /* 0110 */
- kMipsCondVc = 0x7, /* 0111 */
- kMipsCondHi = 0x8, /* 1000 */
- kMipsCondLs = 0x9, /* 1001 */
- kMipsCondGe = 0xa, /* 1010 */
- kMipsCondLt = 0xb, /* 1011 */
- kMipsCondGt = 0xc, /* 1100 */
- kMipsCondLe = 0xd, /* 1101 */
- kMipsCondAl = 0xe, /* 1110 */
- kMipsCondNv = 0xf, /* 1111 */
-} MipsConditionCode;
-
// FIXME: Need support for barriers. Adding these defines to allow compile
#define kST 0
#define kSY 1
diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc
index 504375b..774dffc 100644
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ b/src/compiler/codegen/mips/MipsRallocUtil.cc
@@ -122,8 +122,6 @@ extern void oatClobberCalleeSave(CompilationUnit *cUnit)
oatClobber(cUnit, r_GP);
oatClobber(cUnit, r_FP);
oatClobber(cUnit, r_RA);
- oatClobber(cUnit, r_HI);
- oatClobber(cUnit, r_LO);
oatClobber(cUnit, r_F0);
oatClobber(cUnit, r_F1);
oatClobber(cUnit, r_F2);