diff options
author | buzbee <buzbee@google.com> | 2012-03-02 08:20:26 -0800 |
---|---|---|
committer | buzbee <buzbee@google.com> | 2012-03-02 13:02:52 -0800 |
commit | 82488f563e7f72f8c626052893c1792d76ab3faf (patch) | |
tree | e17e3bc62adf8b57bfeb86a3a879dfb099d3d1d7 /src/compiler/codegen/mips | |
parent | 013b6f296ff7c0cb6aa5aeb6868df05995eeadb7 (diff) | |
download | art-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.cc | 2 | ||||
-rw-r--r-- | src/compiler/codegen/mips/ArchUtility.cc | 62 | ||||
-rw-r--r-- | src/compiler/codegen/mips/Assemble.cc | 42 | ||||
-rw-r--r-- | src/compiler/codegen/mips/Codegen.h | 14 | ||||
-rw-r--r-- | src/compiler/codegen/mips/FP/MipsFP.cc | 2 | ||||
-rw-r--r-- | src/compiler/codegen/mips/Mips32/Factory.cc | 48 | ||||
-rw-r--r-- | src/compiler/codegen/mips/Mips32/Gen.cc | 115 | ||||
-rw-r--r-- | src/compiler/codegen/mips/MipsLIR.h | 20 | ||||
-rw-r--r-- | src/compiler/codegen/mips/MipsRallocUtil.cc | 2 |
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); |