From a114add0300b95eeaae7465493f39144e07324e8 Mon Sep 17 00:00:00 2001 From: Bill Buzbee Date: Thu, 3 May 2012 15:00:40 -0700 Subject: [Compiler] use Art indentation standard First of several CLs to bring code closer to alignment with Art and LLVM standards. Move to 2-space indenting. Sticking with 80-col line length (which LLVM apparently also wants). LLVM also prefers camel case names, so keeping Dalvik convention there as well (for now). Change-Id: I351ab234e640678d97747377cccdd6df0a770f4a --- src/compiler/codegen/mips/ArchFactory.cc | 349 ++++---- src/compiler/codegen/mips/ArchUtility.cc | 256 +++--- src/compiler/codegen/mips/Assemble.cc | 492 +++++------ src/compiler/codegen/mips/Codegen.h | 17 +- src/compiler/codegen/mips/FP/MipsFP.cc | 345 ++++---- src/compiler/codegen/mips/Mips32/Factory.cc | 1091 ++++++++++++------------- src/compiler/codegen/mips/Mips32/Gen.cc | 668 ++++++++------- src/compiler/codegen/mips/Mips32/Ralloc.cc | 150 ++-- src/compiler/codegen/mips/MipsLIR.h | 517 ++++++------ src/compiler/codegen/mips/MipsRallocUtil.cc | 182 ++--- src/compiler/codegen/mips/mips/ArchVariant.cc | 24 +- 11 files changed, 2037 insertions(+), 2054 deletions(-) (limited to 'src/compiler/codegen/mips') diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc index 5e41400b4c..83172157bd 100644 --- a/src/compiler/codegen/mips/ArchFactory.cc +++ b/src/compiler/codegen/mips/ArchFactory.cc @@ -29,72 +29,72 @@ namespace art { bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { - rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); - rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - /* - * [v1 v0] = [a1 a0] + [a3 a2]; - * addu v0,a2,a0 - * addu t1,a3,a1 - * sltu v1,v0,a2 - * addu v1,v1,t1 - */ + rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); + rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + /* + * [v1 v0] = [a1 a0] + [a3 a2]; + * addu v0,a2,a0 + * addu t1,a3,a1 + * sltu v1,v0,a2 + * addu v1,v1,t1 + */ - opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg); - int tReg = oatAllocTemp(cUnit); - opRegRegReg(cUnit, kOpAdd, tReg, rlSrc2.highReg, rlSrc1.highReg); - newLIR3(cUnit, kMipsSltu, rlResult.highReg, rlResult.lowReg, rlSrc2.lowReg); - opRegRegReg(cUnit, kOpAdd, rlResult.highReg, rlResult.highReg, tReg); - oatFreeTemp(cUnit, tReg); - storeValueWide(cUnit, rlDest, rlResult); - return false; + opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg); + int tReg = oatAllocTemp(cUnit); + opRegRegReg(cUnit, kOpAdd, tReg, rlSrc2.highReg, rlSrc1.highReg); + newLIR3(cUnit, kMipsSltu, rlResult.highReg, rlResult.lowReg, rlSrc2.lowReg); + opRegRegReg(cUnit, kOpAdd, rlResult.highReg, rlResult.highReg, tReg); + oatFreeTemp(cUnit, tReg); + storeValueWide(cUnit, rlDest, rlResult); + return false; } bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2) + RegLocation rlSrc1, RegLocation rlSrc2) { - rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); - rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - /* - * [v1 v0] = [a1 a0] - [a3 a2]; - * subu v0,a0,a2 - * subu v1,a1,a3 - * sltu t1,a0,v0 - * subu v1,v1,t1 - */ + rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); + rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + /* + * [v1 v0] = [a1 a0] - [a3 a2]; + * subu v0,a0,a2 + * subu v1,a1,a3 + * sltu t1,a0,v0 + * subu v1,v1,t1 + */ - opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg); - opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg); - int tReg = oatAllocTemp(cUnit); - newLIR3(cUnit, kMipsSltu, tReg, rlSrc1.lowReg, rlResult.lowReg); - opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg); - oatFreeTemp(cUnit, tReg); - storeValueWide(cUnit, rlDest, rlResult); - return false; + opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg); + opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg); + int tReg = oatAllocTemp(cUnit); + newLIR3(cUnit, kMipsSltu, tReg, rlSrc1.lowReg, rlResult.lowReg); + opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg); + oatFreeTemp(cUnit, tReg); + storeValueWide(cUnit, rlDest, rlResult); + return false; } bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, RegLocation rlSrc) { - rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - /* - * [v1 v0] = -[a1 a0] - * negu v0,a0 - * negu v1,a1 - * sltu t1,r_zero - * subu v1,v1,t1 - */ + rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + /* + * [v1 v0] = -[a1 a0] + * negu v0,a0 + * negu v1,a1 + * sltu t1,r_zero + * subu v1,v1,t1 + */ - opRegReg(cUnit, kOpNeg, rlResult.lowReg, rlSrc.lowReg); - opRegReg(cUnit, kOpNeg, rlResult.highReg, rlSrc.highReg); - int tReg = oatAllocTemp(cUnit); - newLIR3(cUnit, kMipsSltu, tReg, r_ZERO, rlResult.lowReg); - opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg); - oatFreeTemp(cUnit, tReg); - storeValueWide(cUnit, rlDest, rlResult); - return false; + opRegReg(cUnit, kOpNeg, rlResult.lowReg, rlSrc.lowReg); + opRegReg(cUnit, kOpNeg, rlResult.highReg, rlSrc.highReg); + int tReg = oatAllocTemp(cUnit); + newLIR3(cUnit, kMipsSltu, tReg, r_ZERO, rlResult.lowReg); + opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg); + oatFreeTemp(cUnit, tReg); + storeValueWide(cUnit, rlDest, rlResult); + return false; } void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset); @@ -107,118 +107,113 @@ void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset); */ int loadHelper(CompilationUnit* cUnit, int offset) { - int tReg = oatAllocTemp(cUnit); - loadWordDisp(cUnit, rSELF, offset, tReg); - return tReg; + int tReg = oatAllocTemp(cUnit); + loadWordDisp(cUnit, rSELF, offset, tReg); + return tReg; } void spillCoreRegs(CompilationUnit* cUnit) { - if (cUnit->numCoreSpills == 0) { - return; - } - uint32_t mask = cUnit->coreSpillMask; - int offset = cUnit->numCoreSpills * 4; - opRegImm(cUnit, kOpSub, rSP, offset); - for (int reg = 0; mask; mask >>= 1, reg++) { - if (mask & 0x1) { - offset -= 4; - storeWordDisp(cUnit, rSP, offset, reg); - } + if (cUnit->numCoreSpills == 0) { + return; + } + uint32_t mask = cUnit->coreSpillMask; + int offset = cUnit->numCoreSpills * 4; + opRegImm(cUnit, kOpSub, rSP, offset); + for (int reg = 0; mask; mask >>= 1, reg++) { + if (mask & 0x1) { + offset -= 4; + storeWordDisp(cUnit, rSP, offset, reg); } + } } void unSpillCoreRegs(CompilationUnit* cUnit) { - if (cUnit->numCoreSpills == 0) { - return; + if (cUnit->numCoreSpills == 0) { + return; + } + uint32_t mask = cUnit->coreSpillMask; + int offset = cUnit->frameSize; + for (int reg = 0; mask; mask >>= 1, reg++) { + if (mask & 0x1) { + offset -= 4; + loadWordDisp(cUnit, rSP, offset, reg); } - uint32_t mask = cUnit->coreSpillMask; - int offset = cUnit->frameSize; - for (int reg = 0; mask; mask >>= 1, reg++) { - if (mask & 0x1) { - offset -= 4; - loadWordDisp(cUnit, rSP, offset, reg); - } - } - opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize); + } + opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize); } void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb) { - int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills; - /* - * On entry, rARG0, rARG1, rARG2 & rARG3 are live. Let the register - * allocation mechanism know so it doesn't try to use any of them when - * expanding the frame or flushing. This leaves the utility - * code with a single temp: r12. This should be enough. - */ - oatLockTemp(cUnit, rARG0); - oatLockTemp(cUnit, rARG1); - oatLockTemp(cUnit, rARG2); - oatLockTemp(cUnit, rARG3); + int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills; + /* + * On entry, rARG0, rARG1, rARG2 & rARG3 are live. Let the register + * allocation mechanism know so it doesn't try to use any of them when + * expanding the frame or flushing. This leaves the utility + * code with a single temp: r12. This should be enough. + */ + oatLockTemp(cUnit, rARG0); + oatLockTemp(cUnit, rARG1); + oatLockTemp(cUnit, rARG2); + oatLockTemp(cUnit, rARG3); - /* - * We can safely skip the stack overflow check if we're - * a leaf *and* our frame size < fudge factor. - */ - bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) && - ((size_t)cUnit->frameSize < - Thread::kStackOverflowReservedBytes)); - newLIR0(cUnit, kPseudoMethodEntry); - int checkReg = oatAllocTemp(cUnit); - int newSP = oatAllocTemp(cUnit); - if (!skipOverflowCheck) { - /* Load stack limit */ - loadWordDisp(cUnit, rSELF, - Thread::StackEndOffset().Int32Value(), checkReg); - } - /* Spill core callee saves */ - spillCoreRegs(cUnit); - /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */ - DCHECK_EQ(cUnit->numFPSpills, 0); - if (!skipOverflowCheck) { - opRegRegImm(cUnit, kOpSub, newSP, rSP, - cUnit->frameSize - (spillCount * 4)); - genRegRegCheck(cUnit, kCondCc, newSP, checkReg, NULL, - kThrowStackOverflow); - opRegCopy(cUnit, rSP, newSP); // Establish stack - } else { - opRegImm(cUnit, kOpSub, rSP, - cUnit->frameSize - (spillCount * 4)); - } + /* + * We can safely skip the stack overflow check if we're + * a leaf *and* our frame size < fudge factor. + */ + bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) && + ((size_t)cUnit->frameSize < Thread::kStackOverflowReservedBytes)); + newLIR0(cUnit, kPseudoMethodEntry); + int checkReg = oatAllocTemp(cUnit); + int newSP = oatAllocTemp(cUnit); + if (!skipOverflowCheck) { + /* Load stack limit */ + loadWordDisp(cUnit, rSELF, Thread::StackEndOffset().Int32Value(), checkReg); + } + /* Spill core callee saves */ + spillCoreRegs(cUnit); + /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */ + DCHECK_EQ(cUnit->numFPSpills, 0); + if (!skipOverflowCheck) { + opRegRegImm(cUnit, kOpSub, newSP, rSP, cUnit->frameSize - (spillCount * 4)); + genRegRegCheck(cUnit, kCondCc, newSP, checkReg, NULL, kThrowStackOverflow); + opRegCopy(cUnit, rSP, newSP); // Establish stack + } else { + opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - (spillCount * 4)); + } - flushIns(cUnit); + flushIns(cUnit); - if (cUnit->genDebugger) { - // Refresh update debugger callout - loadWordDisp(cUnit, rSELF, - ENTRYPOINT_OFFSET(pUpdateDebuggerFromCode), rSUSPEND); - genDebuggerUpdate(cUnit, DEBUGGER_METHOD_ENTRY); - } + if (cUnit->genDebugger) { + // Refresh update debugger callout + loadWordDisp(cUnit, rSELF, + ENTRYPOINT_OFFSET(pUpdateDebuggerFromCode), rSUSPEND); + genDebuggerUpdate(cUnit, DEBUGGER_METHOD_ENTRY); + } - oatFreeTemp(cUnit, rARG0); - oatFreeTemp(cUnit, rARG1); - oatFreeTemp(cUnit, rARG2); - oatFreeTemp(cUnit, rARG3); + oatFreeTemp(cUnit, rARG0); + oatFreeTemp(cUnit, rARG1); + oatFreeTemp(cUnit, rARG2); + oatFreeTemp(cUnit, rARG3); } void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb) { - /* - * In the exit path, rRET0/rRET1 are live - make sure they aren't - * allocated by the register utilities as temps. - */ - oatLockTemp(cUnit, rRET0); - oatLockTemp(cUnit, rRET1); + /* + * In the exit path, rRET0/rRET1 are live - make sure they aren't + * allocated by the register utilities as temps. + */ + oatLockTemp(cUnit, rRET0); + oatLockTemp(cUnit, rRET1); - newLIR0(cUnit, kPseudoMethodExit); - /* If we're compiling for the debugger, generate an update callout */ - if (cUnit->genDebugger) { - genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT); - } - unSpillCoreRegs(cUnit); - opReg(cUnit, kOpBx, r_RA); + newLIR0(cUnit, kPseudoMethodExit); + /* If we're compiling for the debugger, generate an update callout */ + if (cUnit->genDebugger) { + genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT); + } + unSpillCoreRegs(cUnit); + opReg(cUnit, kOpBx, r_RA); } /* @@ -228,55 +223,55 @@ void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb) */ void removeRedundantBranches(CompilationUnit* cUnit) { - LIR* thisLIR; + LIR* thisLIR; - for (thisLIR = (LIR*) cUnit->firstLIRInsn; - thisLIR != (LIR*) cUnit->lastLIRInsn; - thisLIR = NEXT_LIR(thisLIR)) { + for (thisLIR = (LIR*) cUnit->firstLIRInsn; + thisLIR != (LIR*) cUnit->lastLIRInsn; + thisLIR = NEXT_LIR(thisLIR)) { - /* Branch to the next instruction */ - if (thisLIR->opcode == kMipsB) { - LIR* nextLIR = thisLIR; + /* Branch to the next instruction */ + if (thisLIR->opcode == kMipsB) { + LIR* nextLIR = thisLIR; - while (true) { - nextLIR = NEXT_LIR(nextLIR); + while (true) { + nextLIR = NEXT_LIR(nextLIR); - /* - * Is the branch target the next instruction? - */ - if (nextLIR == (LIR*) thisLIR->target) { - thisLIR->flags.isNop = true; - break; - } - - /* - * Found real useful stuff between the branch and the target. - * Need to explicitly check the lastLIRInsn here because it - * might be the last real instruction. - */ - if (!isPseudoOpcode(nextLIR->opcode) || - (nextLIR = (LIR*) cUnit->lastLIRInsn)) - break; - } + /* + * Is the branch target the next instruction? + */ + if (nextLIR == (LIR*) thisLIR->target) { + thisLIR->flags.isNop = true; + break; } + + /* + * Found real useful stuff between the branch and the target. + * Need to explicitly check the lastLIRInsn here because it + * might be the last real instruction. + */ + if (!isPseudoOpcode(nextLIR->opcode) || + (nextLIR = (LIR*) cUnit->lastLIRInsn)) + break; + } } + } } /* Common initialization routine for an architecture family */ bool oatArchInit() { - int i; + int i; - for (i = 0; i < kMipsLast; i++) { - if (EncodingMap[i].opcode != i) { - LOG(FATAL) << "Encoding order for " << EncodingMap[i].name << - " is wrong: expecting " << i << ", seeing " << - (int)EncodingMap[i].opcode; - } + for (i = 0; i < kMipsLast; i++) { + if (EncodingMap[i].opcode != i) { + LOG(FATAL) << "Encoding order for " << EncodingMap[i].name << + " is wrong: expecting " << i << ", seeing " << + (int)EncodingMap[i].opcode; } + } - return oatArchVariantInit(); + return oatArchVariantInit(); } } // namespace art diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc index 4252d508f9..f1afa78844 100644 --- a/src/compiler/codegen/mips/ArchUtility.cc +++ b/src/compiler/codegen/mips/ArchUtility.cc @@ -25,10 +25,10 @@ namespace art { /* For dumping instructions */ #define MIPS_REG_COUNT 32 static const char *mipsRegName[MIPS_REG_COUNT] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" }; /* @@ -37,145 +37,141 @@ static const char *mipsRegName[MIPS_REG_COUNT] = { */ std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) { - std::string buf; - int i; - const char *fmtEnd = &fmt[strlen(fmt)]; - char tbuf[256]; - char nc; - while (fmt < fmtEnd) { - int operand; - if (*fmt == '!') { - fmt++; - DCHECK_LT(fmt, fmtEnd); - nc = *fmt++; - if (nc=='!') { - strcpy(tbuf, "!"); - } else { - DCHECK_LT(fmt, fmtEnd); - DCHECK_LT((unsigned)(nc-'0'), 4u); - operand = lir->operands[nc-'0']; - switch (*fmt++) { - case 'b': - strcpy(tbuf,"0000"); - for (i=3; i>= 0; i--) { - tbuf[i] += operand & 1; - operand >>= 1; - } - break; - case 's': - sprintf(tbuf,"$f%d",operand & FP_REG_MASK); - break; - case 'S': - DCHECK_EQ(((operand & FP_REG_MASK) & 1), 0); - sprintf(tbuf,"$f%d",operand & FP_REG_MASK); - break; - case 'h': - sprintf(tbuf,"%04x", operand); - break; - case 'M': - case 'd': - sprintf(tbuf,"%d", operand); - break; - case 'D': - sprintf(tbuf,"%d", operand+1); - break; - case 'E': - sprintf(tbuf,"%d", operand*4); - break; - case 'F': - sprintf(tbuf,"%d", operand*2); - break; - case 't': - sprintf(tbuf,"0x%08x (L%p)", - (int) baseAddr + lir->offset + 4 + - (operand << 2), - lir->target); - break; - case 'T': - sprintf(tbuf,"0x%08x", - (int) (operand << 2)); - break; - case 'u': { - int offset_1 = lir->operands[0]; - int offset_2 = NEXT_LIR(lir)->operands[0]; - intptr_t target = - ((((intptr_t) baseAddr + lir->offset + 4) & - ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) & - 0xfffffffc; - sprintf(tbuf, "%p", (void *) target); - break; - } + std::string buf; + int i; + const char *fmtEnd = &fmt[strlen(fmt)]; + char tbuf[256]; + char nc; + while (fmt < fmtEnd) { + int operand; + if (*fmt == '!') { + fmt++; + DCHECK_LT(fmt, fmtEnd); + nc = *fmt++; + if (nc=='!') { + strcpy(tbuf, "!"); + } else { + DCHECK_LT(fmt, fmtEnd); + DCHECK_LT((unsigned)(nc-'0'), 4u); + operand = lir->operands[nc-'0']; + switch (*fmt++) { + case 'b': + strcpy(tbuf,"0000"); + for (i=3; i>= 0; i--) { + tbuf[i] += operand & 1; + operand >>= 1; + } + break; + case 's': + sprintf(tbuf,"$f%d",operand & FP_REG_MASK); + break; + case 'S': + DCHECK_EQ(((operand & FP_REG_MASK) & 1), 0); + sprintf(tbuf,"$f%d",operand & FP_REG_MASK); + break; + case 'h': + sprintf(tbuf,"%04x", operand); + break; + case 'M': + case 'd': + sprintf(tbuf,"%d", operand); + break; + case 'D': + sprintf(tbuf,"%d", operand+1); + break; + case 'E': + sprintf(tbuf,"%d", operand*4); + break; + case 'F': + sprintf(tbuf,"%d", operand*2); + break; + case 't': + sprintf(tbuf,"0x%08x (L%p)", (int) baseAddr + lir->offset + 4 + + (operand << 2), lir->target); + break; + case 'T': + sprintf(tbuf,"0x%08x", (int) (operand << 2)); + break; + case 'u': { + int offset_1 = lir->operands[0]; + int offset_2 = NEXT_LIR(lir)->operands[0]; + intptr_t target = + ((((intptr_t) baseAddr + lir->offset + 4) & ~3) + + (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; + sprintf(tbuf, "%p", (void *) target); + break; + } - /* Nothing to print for BLX_2 */ - case 'v': - strcpy(tbuf, "see above"); - break; - case 'r': - 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; - } - buf += tbuf; - } - } else { - buf += *fmt++; - } + /* Nothing to print for BLX_2 */ + case 'v': + strcpy(tbuf, "see above"); + break; + case 'r': + 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; + } + buf += tbuf; + } + } else { + buf += *fmt++; } - return buf; + } + return buf; } // FIXME: need to redo resourse maps for MIPS - fix this at that time void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix) { - char buf[256]; - buf[0] = 0; - LIR *mipsLIR = (LIR *) lir; + char buf[256]; + buf[0] = 0; + LIR *mipsLIR = (LIR *) lir; - if (mask == ENCODE_ALL) { - strcpy(buf, "all"); - } else { - char num[8]; - int i; + if (mask == ENCODE_ALL) { + strcpy(buf, "all"); + } else { + char num[8]; + int i; - for (i = 0; i < kRegEnd; i++) { - if (mask & (1ULL << i)) { - sprintf(num, "%d ", i); - strcat(buf, num); - } - } + for (i = 0; i < kRegEnd; i++) { + if (mask & (1ULL << i)) { + sprintf(num, "%d ", i); + strcat(buf, num); + } + } - if (mask & ENCODE_CCODE) { - strcat(buf, "cc "); - } - if (mask & ENCODE_FP_STATUS) { - strcat(buf, "fpcc "); - } - /* Memory bits */ - if (mipsLIR && (mask & ENCODE_DALVIK_REG)) { - sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff, - (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : ""); - } - if (mask & ENCODE_LITERAL) { - strcat(buf, "lit "); - } + if (mask & ENCODE_CCODE) { + strcat(buf, "cc "); + } + if (mask & ENCODE_FP_STATUS) { + strcat(buf, "fpcc "); + } + /* Memory bits */ + if (mipsLIR && (mask & ENCODE_DALVIK_REG)) { + sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff, + (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : ""); + } + if (mask & ENCODE_LITERAL) { + strcat(buf, "lit "); + } - if (mask & ENCODE_HEAP_REF) { - strcat(buf, "heap "); - } - if (mask & ENCODE_MUST_NOT_ALIAS) { - strcat(buf, "noalias "); - } + if (mask & ENCODE_HEAP_REF) { + strcat(buf, "heap "); } - if (buf[0]) { - LOG(INFO) << prefix << ": " << buf; + if (mask & ENCODE_MUST_NOT_ALIAS) { + strcat(buf, "noalias "); } + } + if (buf[0]) { + LOG(INFO) << prefix << ": " << buf; + } } } // namespace art diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc index 1d629be541..c19effe2f3 100644 --- a/src/compiler/codegen/mips/Assemble.cc +++ b/src/compiler/codegen/mips/Assemble.cc @@ -463,52 +463,52 @@ MipsEncodingMap EncodingMap[kMipsLast] = { */ void convertShortToLongBranch(CompilationUnit* cUnit, LIR* lir) { - // For conditional branches we'll need to reverse the sense - bool unconditional = false; - int opcode = lir->opcode; - int dalvikOffset = lir->dalvikOffset; - switch (opcode) { - case kMipsBal: - LOG(FATAL) << "long branch and link unsupported"; - case kMipsB: - unconditional = true; - break; - case kMipsBeq: opcode = kMipsBne; break; - case kMipsBne: opcode = kMipsBeq; break; - case kMipsBeqz: opcode = kMipsBnez; break; - case kMipsBgez: opcode = kMipsBltz; break; - case kMipsBgtz: opcode = kMipsBlez; break; - case kMipsBlez: opcode = kMipsBgtz; break; - case kMipsBltz: opcode = kMipsBgez; break; - case kMipsBnez: opcode = kMipsBeqz; break; - default: - LOG(FATAL) << "Unexpected branch kind " << (int)opcode; - } - LIR* hopTarget = NULL; - if (!unconditional) { - hopTarget = rawLIR(cUnit, dalvikOffset, kPseudoTargetLabel); - LIR* hopBranch = rawLIR(cUnit, dalvikOffset, opcode, lir->operands[0], - lir->operands[1], 0, 0, 0, hopTarget); - oatInsertLIRBefore(lir, hopBranch); - } - LIR* currPC = rawLIR(cUnit, dalvikOffset, kMipsCurrPC); - oatInsertLIRBefore(lir, currPC); - LIR* anchor = rawLIR(cUnit, dalvikOffset, kPseudoTargetLabel); - LIR* deltaHi = rawLIR(cUnit, dalvikOffset, kMipsDeltaHi, r_AT, 0, - (uintptr_t)anchor, 0, 0, lir->target); - oatInsertLIRBefore(lir, deltaHi); - oatInsertLIRBefore(lir, anchor); - LIR* deltaLo = rawLIR(cUnit, dalvikOffset, kMipsDeltaLo, r_AT, 0, - (uintptr_t)anchor, 0, 0, lir->target); - oatInsertLIRBefore(lir, deltaLo); - LIR* addu = rawLIR(cUnit, dalvikOffset, kMipsAddu, r_AT, r_AT, r_RA); - oatInsertLIRBefore(lir, addu); - LIR* jr = rawLIR(cUnit, dalvikOffset, kMipsJr, r_AT); - oatInsertLIRBefore(lir, jr); - if (!unconditional) { - oatInsertLIRBefore(lir, hopTarget); - } - lir->flags.isNop = true; + // For conditional branches we'll need to reverse the sense + bool unconditional = false; + int opcode = lir->opcode; + int dalvikOffset = lir->dalvikOffset; + switch (opcode) { + case kMipsBal: + LOG(FATAL) << "long branch and link unsupported"; + case kMipsB: + unconditional = true; + break; + case kMipsBeq: opcode = kMipsBne; break; + case kMipsBne: opcode = kMipsBeq; break; + case kMipsBeqz: opcode = kMipsBnez; break; + case kMipsBgez: opcode = kMipsBltz; break; + case kMipsBgtz: opcode = kMipsBlez; break; + case kMipsBlez: opcode = kMipsBgtz; break; + case kMipsBltz: opcode = kMipsBgez; break; + case kMipsBnez: opcode = kMipsBeqz; break; + default: + LOG(FATAL) << "Unexpected branch kind " << (int)opcode; + } + LIR* hopTarget = NULL; + if (!unconditional) { + hopTarget = rawLIR(cUnit, dalvikOffset, kPseudoTargetLabel); + LIR* hopBranch = rawLIR(cUnit, dalvikOffset, opcode, lir->operands[0], + lir->operands[1], 0, 0, 0, hopTarget); + oatInsertLIRBefore(lir, hopBranch); + } + LIR* currPC = rawLIR(cUnit, dalvikOffset, kMipsCurrPC); + oatInsertLIRBefore(lir, currPC); + LIR* anchor = rawLIR(cUnit, dalvikOffset, kPseudoTargetLabel); + LIR* deltaHi = rawLIR(cUnit, dalvikOffset, kMipsDeltaHi, r_AT, 0, + (uintptr_t)anchor, 0, 0, lir->target); + oatInsertLIRBefore(lir, deltaHi); + oatInsertLIRBefore(lir, anchor); + LIR* deltaLo = rawLIR(cUnit, dalvikOffset, kMipsDeltaLo, r_AT, 0, + (uintptr_t)anchor, 0, 0, lir->target); + oatInsertLIRBefore(lir, deltaLo); + LIR* addu = rawLIR(cUnit, dalvikOffset, kMipsAddu, r_AT, r_AT, r_RA); + oatInsertLIRBefore(lir, addu); + LIR* jr = rawLIR(cUnit, dalvikOffset, kMipsJr, r_AT); + oatInsertLIRBefore(lir, jr); + if (!unconditional) { + oatInsertLIRBefore(lir, hopTarget); + } + lir->flags.isNop = true; } /* @@ -518,201 +518,201 @@ void convertShortToLongBranch(CompilationUnit* cUnit, LIR* lir) * sequence or request that the trace be shortened and retried. */ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, - intptr_t startAddr) + intptr_t startAddr) { - LIR *lir; - AssemblerStatus res = kSuccess; // Assume success - - for (lir = (LIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) { - if (lir->opcode < 0) { - continue; - } + LIR *lir; + AssemblerStatus res = kSuccess; // Assume success + for (lir = (LIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) { + if (lir->opcode < 0) { + continue; + } - if (lir->flags.isNop) { - continue; - } - if (lir->flags.pcRelFixup) { - if (lir->opcode == kMipsDelta) { - /* - * The "Delta" pseudo-ops load the difference between - * two pc-relative locations into a the target register - * found in operands[0]. The delta is determined by - * (label2 - label1), where label1 is a standard - * kPseudoTargetLabel and is stored in operands[2]. - * If operands[3] is null, then label2 is a kPseudoTargetLabel - * and is found in lir->target. If operands[3] is non-NULL, - * then it is a Switch/Data table. - */ - int offset1 = ((LIR*)lir->operands[2])->offset; - SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; - int offset2 = tabRec ? tabRec->offset : lir->target->offset; - int delta = offset2 - offset1; - if ((delta & 0xffff) == delta) { - // Fits - lir->operands[1] = delta; - } else { - // Doesn't fit - must expand to kMipsDelta[Hi|Lo] pair - LIR *newDeltaHi = - rawLIR(cUnit, lir->dalvikOffset, kMipsDeltaHi, - lir->operands[0], 0, lir->operands[2], - lir->operands[3], 0, lir->target); - oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaHi); - LIR *newDeltaLo = - rawLIR(cUnit, lir->dalvikOffset, kMipsDeltaLo, - lir->operands[0], 0, lir->operands[2], - lir->operands[3], 0, lir->target); - oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaLo); - lir->flags.isNop = true; - res = kRetryAll; - } - } else if (lir->opcode == kMipsDeltaLo) { - int offset1 = ((LIR*)lir->operands[2])->offset; - SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; - int offset2 = tabRec ? tabRec->offset : lir->target->offset; - int delta = offset2 - offset1; - lir->operands[1] = delta & 0xffff; - } else if (lir->opcode == kMipsDeltaHi) { - int offset1 = ((LIR*)lir->operands[2])->offset; - SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; - int offset2 = tabRec ? tabRec->offset : lir->target->offset; - int delta = offset2 - offset1; - lir->operands[1] = (delta >> 16) & 0xffff; - } else if (lir->opcode == kMipsB || lir->opcode == kMipsBal) { - LIR *targetLIR = (LIR *) lir->target; - intptr_t pc = lir->offset + 4; - intptr_t target = targetLIR->offset; - int delta = target - pc; - if (delta & 0x3) { - LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; - } - if (delta > 131068 || delta < -131069) { - res = kRetryAll; - convertShortToLongBranch(cUnit, lir); - } else { - lir->operands[0] = delta >> 2; - } - } else if (lir->opcode >= kMipsBeqz && lir->opcode <= kMipsBnez) { - LIR *targetLIR = (LIR *) lir->target; - intptr_t pc = lir->offset + 4; - intptr_t target = targetLIR->offset; - int delta = target - pc; - if (delta & 0x3) { - LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; - } - if (delta > 131068 || delta < -131069) { - res = kRetryAll; - convertShortToLongBranch(cUnit, lir); - } else { - lir->operands[1] = delta >> 2; - } - } else if (lir->opcode == kMipsBeq || lir->opcode == kMipsBne) { - LIR *targetLIR = (LIR *) lir->target; - intptr_t pc = lir->offset + 4; - intptr_t target = targetLIR->offset; - int delta = target - pc; - if (delta & 0x3) { - LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; - } - if (delta > 131068 || delta < -131069) { - res = kRetryAll; - convertShortToLongBranch(cUnit, lir); - } else { - lir->operands[2] = delta >> 2; - } - } else if (lir->opcode == kMipsJal) { - intptr_t curPC = (startAddr + lir->offset + 4) & ~3; - intptr_t target = lir->operands[0]; - /* ensure PC-region branch can be used */ - DCHECK_EQ((curPC & 0xF0000000), (target & 0xF0000000)); - if (target & 0x3) { - LOG(FATAL) << "Jump target not multiple of 4: " << target; - } - lir->operands[0] = target >> 2; - } else if (lir->opcode == kMipsLahi) { /* ld address hi (via lui) */ - LIR *targetLIR = (LIR *) lir->target; - intptr_t target = startAddr + targetLIR->offset; - lir->operands[1] = target >> 16; - } else if (lir->opcode == kMipsLalo) { /* ld address lo (via ori) */ - LIR *targetLIR = (LIR *) lir->target; - intptr_t target = startAddr + targetLIR->offset; - lir->operands[2] = lir->operands[2] + target; - } - } + if (lir->flags.isNop) { + continue; + } + if (lir->flags.pcRelFixup) { + if (lir->opcode == kMipsDelta) { /* - * If one of the pc-relative instructions expanded we'll have - * to make another pass. Don't bother to fully assemble the - * instruction. + * The "Delta" pseudo-ops load the difference between + * two pc-relative locations into a the target register + * found in operands[0]. The delta is determined by + * (label2 - label1), where label1 is a standard + * kPseudoTargetLabel and is stored in operands[2]. + * If operands[3] is null, then label2 is a kPseudoTargetLabel + * and is found in lir->target. If operands[3] is non-NULL, + * then it is a Switch/Data table. */ - if (res != kSuccess) { - continue; + int offset1 = ((LIR*)lir->operands[2])->offset; + SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; + int offset2 = tabRec ? tabRec->offset : lir->target->offset; + int delta = offset2 - offset1; + if ((delta & 0xffff) == delta) { + // Fits + lir->operands[1] = delta; + } else { + // Doesn't fit - must expand to kMipsDelta[Hi|Lo] pair + LIR *newDeltaHi = + rawLIR(cUnit, lir->dalvikOffset, kMipsDeltaHi, + lir->operands[0], 0, lir->operands[2], + lir->operands[3], 0, lir->target); + oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaHi); + LIR *newDeltaLo = + rawLIR(cUnit, lir->dalvikOffset, kMipsDeltaLo, + lir->operands[0], 0, lir->operands[2], + lir->operands[3], 0, lir->target); + oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaLo); + lir->flags.isNop = true; + res = kRetryAll; + } + } else if (lir->opcode == kMipsDeltaLo) { + int offset1 = ((LIR*)lir->operands[2])->offset; + SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; + int offset2 = tabRec ? tabRec->offset : lir->target->offset; + int delta = offset2 - offset1; + lir->operands[1] = delta & 0xffff; + } else if (lir->opcode == kMipsDeltaHi) { + int offset1 = ((LIR*)lir->operands[2])->offset; + SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; + int offset2 = tabRec ? tabRec->offset : lir->target->offset; + int delta = offset2 - offset1; + lir->operands[1] = (delta >> 16) & 0xffff; + } else if (lir->opcode == kMipsB || lir->opcode == kMipsBal) { + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; + int delta = target - pc; + if (delta & 0x3) { + LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; } - const MipsEncodingMap *encoder = &EncodingMap[lir->opcode]; - u4 bits = encoder->skeleton; - int i; - for (i = 0; i < 4; i++) { - u4 operand; - u4 value; - operand = lir->operands[i]; - switch (encoder->fieldLoc[i].kind) { - case kFmtUnused: - break; - case kFmtBitBlt: - if (encoder->fieldLoc[i].start == 0 && encoder->fieldLoc[i].end == 31) { - value = operand; - } else { - value = (operand << encoder->fieldLoc[i].start) & - ((1 << (encoder->fieldLoc[i].end + 1)) - 1); - } - bits |= value; - break; - case kFmtBlt5_2: - value = (operand & 0x1f); - bits |= (value << encoder->fieldLoc[i].start); - bits |= (value << encoder->fieldLoc[i].end); - break; - case kFmtDfp: { - DCHECK(DOUBLEREG(operand)); - DCHECK((operand & 0x1) == 0); - value = ((operand & FP_REG_MASK) << encoder->fieldLoc[i].start) & - ((1 << (encoder->fieldLoc[i].end + 1)) - 1); - bits |= value; - break; - } - case kFmtSfp: - DCHECK(SINGLEREG(operand)); - value = ((operand & FP_REG_MASK) << encoder->fieldLoc[i].start) & - ((1 << (encoder->fieldLoc[i].end + 1)) - 1); - bits |= value; - break; - default: - LOG(FATAL) << "Bad encoder format: " - << (int)encoder->fieldLoc[i].kind; - } + if (delta > 131068 || delta < -131069) { + res = kRetryAll; + convertShortToLongBranch(cUnit, lir); + } else { + lir->operands[0] = delta >> 2; } - // FIXME: need multi-endian handling here - cUnit->codeBuffer.push_back((bits >> 24) & 0xff); - cUnit->codeBuffer.push_back((bits >> 16) & 0xff); - cUnit->codeBuffer.push_back((bits >> 8) & 0xff); - cUnit->codeBuffer.push_back(bits & 0xff); - // 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 >> 24) & 0xff); - cUnit->codeBuffer.push_back((bits >> 16) & 0xff); - cUnit->codeBuffer.push_back((bits >> 8) & 0xff); - cUnit->codeBuffer.push_back(bits & 0xff); + } else if (lir->opcode >= kMipsBeqz && lir->opcode <= kMipsBnez) { + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; + int delta = target - pc; + if (delta & 0x3) { + LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; } + if (delta > 131068 || delta < -131069) { + res = kRetryAll; + convertShortToLongBranch(cUnit, lir); + } else { + lir->operands[1] = delta >> 2; + } + } else if (lir->opcode == kMipsBeq || lir->opcode == kMipsBne) { + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; + int delta = target - pc; + if (delta & 0x3) { + LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; + } + if (delta > 131068 || delta < -131069) { + res = kRetryAll; + convertShortToLongBranch(cUnit, lir); + } else { + lir->operands[2] = delta >> 2; + } + } else if (lir->opcode == kMipsJal) { + intptr_t curPC = (startAddr + lir->offset + 4) & ~3; + intptr_t target = lir->operands[0]; + /* ensure PC-region branch can be used */ + DCHECK_EQ((curPC & 0xF0000000), (target & 0xF0000000)); + if (target & 0x3) { + LOG(FATAL) << "Jump target not multiple of 4: " << target; + } + lir->operands[0] = target >> 2; + } else if (lir->opcode == kMipsLahi) { /* ld address hi (via lui) */ + LIR *targetLIR = (LIR *) lir->target; + intptr_t target = startAddr + targetLIR->offset; + lir->operands[1] = target >> 16; + } else if (lir->opcode == kMipsLalo) { /* ld address lo (via ori) */ + LIR *targetLIR = (LIR *) lir->target; + intptr_t target = startAddr + targetLIR->offset; + lir->operands[2] = lir->operands[2] + target; + } + } + + /* + * If one of the pc-relative instructions expanded we'll have + * to make another pass. Don't bother to fully assemble the + * instruction. + */ + if (res != kSuccess) { + continue; } - return res; + const MipsEncodingMap *encoder = &EncodingMap[lir->opcode]; + u4 bits = encoder->skeleton; + int i; + for (i = 0; i < 4; i++) { + u4 operand; + u4 value; + operand = lir->operands[i]; + switch (encoder->fieldLoc[i].kind) { + case kFmtUnused: + break; + case kFmtBitBlt: + if (encoder->fieldLoc[i].start == 0 && encoder->fieldLoc[i].end == 31) { + value = operand; + } else { + value = (operand << encoder->fieldLoc[i].start) & + ((1 << (encoder->fieldLoc[i].end + 1)) - 1); + } + bits |= value; + break; + case kFmtBlt5_2: + value = (operand & 0x1f); + bits |= (value << encoder->fieldLoc[i].start); + bits |= (value << encoder->fieldLoc[i].end); + break; + case kFmtDfp: { + DCHECK(DOUBLEREG(operand)); + DCHECK((operand & 0x1) == 0); + value = ((operand & FP_REG_MASK) << encoder->fieldLoc[i].start) & + ((1 << (encoder->fieldLoc[i].end + 1)) - 1); + bits |= value; + break; + } + case kFmtSfp: + DCHECK(SINGLEREG(operand)); + value = ((operand & FP_REG_MASK) << encoder->fieldLoc[i].start) & + ((1 << (encoder->fieldLoc[i].end + 1)) - 1); + bits |= value; + break; + default: + LOG(FATAL) << "Bad encoder format: " + << (int)encoder->fieldLoc[i].kind; + } + } + // FIXME: need multi-endian handling here + cUnit->codeBuffer.push_back((bits >> 24) & 0xff); + cUnit->codeBuffer.push_back((bits >> 16) & 0xff); + cUnit->codeBuffer.push_back((bits >> 8) & 0xff); + cUnit->codeBuffer.push_back(bits & 0xff); + // 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 >> 24) & 0xff); + cUnit->codeBuffer.push_back((bits >> 16) & 0xff); + cUnit->codeBuffer.push_back((bits >> 8) & 0xff); + cUnit->codeBuffer.push_back(bits & 0xff); + } + } + return res; } int oatGetInsnSize(LIR* lir) { - return EncodingMap[lir->opcode].size; + return EncodingMap[lir->opcode].size; } /* * Target-dependent offset assignment. @@ -720,29 +720,29 @@ int oatGetInsnSize(LIR* lir) */ int oatAssignInsnOffsets(CompilationUnit* cUnit) { - LIR* mipsLIR; - int offset = 0; + LIR* mipsLIR; + int offset = 0; - for (mipsLIR = (LIR *) cUnit->firstLIRInsn; - mipsLIR; - mipsLIR = NEXT_LIR(mipsLIR)) { - mipsLIR->offset = offset; - if (mipsLIR->opcode >= 0) { - if (!mipsLIR->flags.isNop) { - offset += mipsLIR->flags.size; - } - } else if (mipsLIR->opcode == kPseudoPseudoAlign4) { - if (offset & 0x2) { - offset += 2; - mipsLIR->operands[0] = 1; - } else { - mipsLIR->operands[0] = 0; - } - } - /* Pseudo opcodes don't consume space */ + for (mipsLIR = (LIR *) cUnit->firstLIRInsn; + mipsLIR; + mipsLIR = NEXT_LIR(mipsLIR)) { + mipsLIR->offset = offset; + if (mipsLIR->opcode >= 0) { + if (!mipsLIR->flags.isNop) { + offset += mipsLIR->flags.size; + } + } else if (mipsLIR->opcode == kPseudoPseudoAlign4) { + if (offset & 0x2) { + offset += 2; + mipsLIR->operands[0] = 1; + } else { + mipsLIR->operands[0] = 0; + } } + /* Pseudo opcodes don't consume space */ + } - return offset; + return offset; } } // namespace art diff --git a/src/compiler/codegen/mips/Codegen.h b/src/compiler/codegen/mips/Codegen.h index e11119f3dd..6ddc5ac210 100644 --- a/src/compiler/codegen/mips/Codegen.h +++ b/src/compiler/codegen/mips/Codegen.h @@ -68,10 +68,10 @@ void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, */ inline RegisterClass oatRegClassBySize(OpSize size) { - return (size == kUnsignedHalf || - size == kSignedHalf || - size == kUnsignedByte || - size == kSignedByte ) ? kCoreReg : kAnyReg; + return (size == kUnsignedHalf || + size == kSignedHalf || + size == kUnsignedByte || + size == kSignedByte ) ? kCoreReg : kAnyReg; } /* @@ -83,12 +83,12 @@ inline RegisterClass oatRegClassBySize(OpSize size) */ #if __BYTE_ORDER == __LITTLE_ENDIAN inline s4 s4FromSwitchData(const void* switchData) { - return *(s4*) switchData; + return *(s4*) switchData; } #else inline s4 s4FromSwitchData(const void* switchData) { - u2* data = switchData; - return data[0] | (((s4) data[1]) << 16); + u2* data = switchData; + return data[0] | (((s4) data[1]) << 16); } #endif @@ -96,7 +96,6 @@ inline s4 s4FromSwitchData(const void* switchData) { extern void oatSetupResourceMasks(LIR* lir); -extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, - int rSrc); +extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); } // namespace art diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc index 948ded61a8..c101039be7 100644 --- a/src/compiler/codegen/mips/FP/MipsFP.cc +++ b/src/compiler/codegen/mips/FP/MipsFP.cc @@ -22,48 +22,48 @@ bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { #ifdef __mips_hard_float - int op = kMipsNop; - RegLocation rlResult; + int op = kMipsNop; + RegLocation rlResult; - /* - * Don't attempt to optimize register usage since these opcodes call out to - * the handlers. - */ - switch (mir->dalvikInsn.opcode) { - case Instruction::ADD_FLOAT_2ADDR: - case Instruction::ADD_FLOAT: - op = kMipsFadds; - break; - case Instruction::SUB_FLOAT_2ADDR: - case Instruction::SUB_FLOAT: - op = kMipsFsubs; - break; - case Instruction::DIV_FLOAT_2ADDR: - case Instruction::DIV_FLOAT: - op = kMipsFdivs; - break; - case Instruction::MUL_FLOAT_2ADDR: - case Instruction::MUL_FLOAT: - op = kMipsFmuls; - break; - case Instruction::REM_FLOAT_2ADDR: - case Instruction::REM_FLOAT: - case Instruction::NEG_FLOAT: { - return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); - } - default: - return true; + /* + * Don't attempt to optimize register usage since these opcodes call out to + * the handlers. + */ + switch (mir->dalvikInsn.opcode) { + case Instruction::ADD_FLOAT_2ADDR: + case Instruction::ADD_FLOAT: + op = kMipsFadds; + break; + case Instruction::SUB_FLOAT_2ADDR: + case Instruction::SUB_FLOAT: + op = kMipsFsubs; + break; + case Instruction::DIV_FLOAT_2ADDR: + case Instruction::DIV_FLOAT: + op = kMipsFdivs; + break; + case Instruction::MUL_FLOAT_2ADDR: + case Instruction::MUL_FLOAT: + op = kMipsFmuls; + break; + case Instruction::REM_FLOAT_2ADDR: + case Instruction::REM_FLOAT: + case Instruction::NEG_FLOAT: { + return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); } - rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); - rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); - rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); - newLIR3(cUnit, (MipsOpCode)op, rlResult.lowReg, rlSrc1.lowReg, - rlSrc2.lowReg); - storeValue(cUnit, rlDest, rlResult); + default: + return true; + } + rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); + rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); + rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); + newLIR3(cUnit, (MipsOpCode)op, rlResult.lowReg, rlSrc1.lowReg, + rlSrc2.lowReg); + storeValue(cUnit, rlDest, rlResult); - return false; + return false; #else - return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); + return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); #endif } @@ -72,157 +72,158 @@ static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, RegLocation rlSrc2) { #ifdef __mips_hard_float - int op = kMipsNop; - RegLocation rlResult; + int op = kMipsNop; + RegLocation rlResult; - switch (mir->dalvikInsn.opcode) { - case Instruction::ADD_DOUBLE_2ADDR: - case Instruction::ADD_DOUBLE: - op = kMipsFaddd; - break; - case Instruction::SUB_DOUBLE_2ADDR: - case Instruction::SUB_DOUBLE: - op = kMipsFsubd; - break; - case Instruction::DIV_DOUBLE_2ADDR: - case Instruction::DIV_DOUBLE: - op = kMipsFdivd; - break; - case Instruction::MUL_DOUBLE_2ADDR: - case Instruction::MUL_DOUBLE: - op = kMipsFmuld; - break; - case Instruction::REM_DOUBLE_2ADDR: - case Instruction::REM_DOUBLE: - case Instruction::NEG_DOUBLE: { - return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); - } - default: - return true; + switch (mir->dalvikInsn.opcode) { + case Instruction::ADD_DOUBLE_2ADDR: + case Instruction::ADD_DOUBLE: + op = kMipsFaddd; + break; + case Instruction::SUB_DOUBLE_2ADDR: + case Instruction::SUB_DOUBLE: + op = kMipsFsubd; + break; + case Instruction::DIV_DOUBLE_2ADDR: + case Instruction::DIV_DOUBLE: + op = kMipsFdivd; + break; + case Instruction::MUL_DOUBLE_2ADDR: + case Instruction::MUL_DOUBLE: + op = kMipsFmuld; + break; + case Instruction::REM_DOUBLE_2ADDR: + case Instruction::REM_DOUBLE: + case Instruction::NEG_DOUBLE: { + return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); } - rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); - DCHECK(rlSrc1.wide); - rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); - DCHECK(rlSrc2.wide); - rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); - DCHECK(rlDest.wide); - DCHECK(rlResult.wide); - newLIR3(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg), - S2D(rlSrc1.lowReg, rlSrc1.highReg), - S2D(rlSrc2.lowReg, rlSrc2.highReg)); - storeValueWide(cUnit, rlDest, rlResult); - return false; + default: + return true; + } + rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); + DCHECK(rlSrc1.wide); + rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); + DCHECK(rlSrc2.wide); + rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); + DCHECK(rlDest.wide); + DCHECK(rlResult.wide); + newLIR3(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg), + S2D(rlSrc1.lowReg, rlSrc1.highReg), + S2D(rlSrc2.lowReg, rlSrc2.highReg)); + storeValueWide(cUnit, rlDest, rlResult); + return false; #else - return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); + return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2); #endif } static bool genConversion(CompilationUnit *cUnit, MIR *mir) { #ifdef __mips_hard_float - Instruction::Code opcode = mir->dalvikInsn.opcode; - bool longSrc = false; - bool longDest = false; - RegLocation rlSrc; - RegLocation rlDest; - int op = kMipsNop; - int srcReg; - RegLocation rlResult; - switch (opcode) { - case Instruction::INT_TO_FLOAT: - longSrc = false; - longDest = false; - op = kMipsFcvtsw; - break; - case Instruction::DOUBLE_TO_FLOAT: - longSrc = true; - longDest = false; - op = kMipsFcvtsd; - break; - case Instruction::FLOAT_TO_DOUBLE: - longSrc = false; - longDest = true; - op = kMipsFcvtds; - break; - case Instruction::INT_TO_DOUBLE: - longSrc = false; - longDest = true; - op = kMipsFcvtdw; - break; - case Instruction::FLOAT_TO_INT: - case Instruction::DOUBLE_TO_INT: - case Instruction::LONG_TO_DOUBLE: - case Instruction::FLOAT_TO_LONG: - case Instruction::LONG_TO_FLOAT: - case Instruction::DOUBLE_TO_LONG: - return genConversionPortable(cUnit, mir); - default: - return true; - } - if (longSrc) { - rlSrc = oatGetSrcWide(cUnit, mir, 0, 1); - rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); - srcReg = S2D(rlSrc.lowReg, rlSrc.highReg); - } else { - rlSrc = oatGetSrc(cUnit, mir, 0); - rlSrc = loadValue(cUnit, rlSrc, kFPReg); - srcReg = rlSrc.lowReg; - } - if (longDest) { - rlDest = oatGetDestWide(cUnit, mir, 0, 1); - rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); - newLIR2(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg), srcReg); - storeValueWide(cUnit, rlDest, rlResult); - } else { - rlDest = oatGetDest(cUnit, mir, 0); - rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); - newLIR2(cUnit, (MipsOpCode)op, rlResult.lowReg, srcReg); - storeValue(cUnit, rlDest, rlResult); - } - return false; + Instruction::Code opcode = mir->dalvikInsn.opcode; + bool longSrc = false; + bool longDest = false; + RegLocation rlSrc; + RegLocation rlDest; + int op = kMipsNop; + int srcReg; + RegLocation rlResult; + switch (opcode) { + case Instruction::INT_TO_FLOAT: + longSrc = false; + longDest = false; + op = kMipsFcvtsw; + break; + case Instruction::DOUBLE_TO_FLOAT: + longSrc = true; + longDest = false; + op = kMipsFcvtsd; + break; + case Instruction::FLOAT_TO_DOUBLE: + longSrc = false; + longDest = true; + op = kMipsFcvtds; + break; + case Instruction::INT_TO_DOUBLE: + longSrc = false; + longDest = true; + op = kMipsFcvtdw; + break; + case Instruction::FLOAT_TO_INT: + case Instruction::DOUBLE_TO_INT: + case Instruction::LONG_TO_DOUBLE: + case Instruction::FLOAT_TO_LONG: + case Instruction::LONG_TO_FLOAT: + case Instruction::DOUBLE_TO_LONG: + return genConversionPortable(cUnit, mir); + default: + return true; + } + if (longSrc) { + rlSrc = oatGetSrcWide(cUnit, mir, 0, 1); + rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); + srcReg = S2D(rlSrc.lowReg, rlSrc.highReg); + } else { + rlSrc = oatGetSrc(cUnit, mir, 0); + rlSrc = loadValue(cUnit, rlSrc, kFPReg); + srcReg = rlSrc.lowReg; + } + if (longDest) { + rlDest = oatGetDestWide(cUnit, mir, 0, 1); + rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); + newLIR2(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg), + srcReg); + storeValueWide(cUnit, rlDest, rlResult); + } else { + rlDest = oatGetDest(cUnit, mir, 0); + rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); + newLIR2(cUnit, (MipsOpCode)op, rlResult.lowReg, srcReg); + storeValue(cUnit, rlDest, rlResult); + } + return false; #else - return genConversionPortable(cUnit, mir); + return genConversionPortable(cUnit, mir); #endif } static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { - bool wide = true; - int offset; + bool wide = true; + int offset; - switch (mir->dalvikInsn.opcode) { - case Instruction::CMPL_FLOAT: - offset = ENTRYPOINT_OFFSET(pCmplFloat); - wide = false; - break; - case Instruction::CMPG_FLOAT: - offset = ENTRYPOINT_OFFSET(pCmpgFloat); - wide = false; - break; - case Instruction::CMPL_DOUBLE: - offset = ENTRYPOINT_OFFSET(pCmplDouble); - break; - case Instruction::CMPG_DOUBLE: - offset = ENTRYPOINT_OFFSET(pCmpgDouble); - break; - default: - return true; - } - oatFlushAllRegs(cUnit); - oatLockCallTemps(cUnit); - if (wide) { - loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1); - loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3); - } else { - loadValueDirectFixed(cUnit, rlSrc1, rARG0); - loadValueDirectFixed(cUnit, rlSrc2, rARG1); - } - int rTgt = loadHelper(cUnit, offset); - opReg(cUnit, kOpBlx, rTgt); - RegLocation rlResult = oatGetReturn(cUnit, false); - storeValue(cUnit, rlDest, rlResult); - return false; + switch (mir->dalvikInsn.opcode) { + case Instruction::CMPL_FLOAT: + offset = ENTRYPOINT_OFFSET(pCmplFloat); + wide = false; + break; + case Instruction::CMPG_FLOAT: + offset = ENTRYPOINT_OFFSET(pCmpgFloat); + wide = false; + break; + case Instruction::CMPL_DOUBLE: + offset = ENTRYPOINT_OFFSET(pCmplDouble); + break; + case Instruction::CMPG_DOUBLE: + offset = ENTRYPOINT_OFFSET(pCmpgDouble); + break; + default: + return true; + } + oatFlushAllRegs(cUnit); + oatLockCallTemps(cUnit); + if (wide) { + loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1); + loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3); + } else { + loadValueDirectFixed(cUnit, rlSrc1, rARG0); + loadValueDirectFixed(cUnit, rlSrc2, rARG1); + } + int rTgt = loadHelper(cUnit, offset); + opReg(cUnit, kOpBlx, rTgt); + RegLocation rlResult = oatGetReturn(cUnit, false); + storeValue(cUnit, rlDest, rlResult); + return false; } } // namespace art diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc index 1162702f68..0a7dd9d3ad 100644 --- a/src/compiler/codegen/mips/Mips32/Factory.cc +++ b/src/compiler/codegen/mips/Mips32/Factory.cc @@ -52,32 +52,32 @@ LIR *loadConstant(CompilationUnit *cUnit, int rDest, int value); #ifdef __mips_hard_float LIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) { - int opcode; - /* must be both DOUBLE or both not DOUBLE */ - DCHECK_EQ(DOUBLEREG(rDest),DOUBLEREG(rSrc)); - if (DOUBLEREG(rDest)) { - opcode = kMipsFmovd; + int opcode; + /* must be both DOUBLE or both not DOUBLE */ + DCHECK_EQ(DOUBLEREG(rDest),DOUBLEREG(rSrc)); + if (DOUBLEREG(rDest)) { + opcode = kMipsFmovd; + } else { + if (SINGLEREG(rDest)) { + if (SINGLEREG(rSrc)) { + opcode = kMipsFmovs; + } else { + /* note the operands are swapped for the mtc1 instr */ + int tOpnd = rSrc; + rSrc = rDest; + rDest = tOpnd; + opcode = kMipsMtc1; + } } else { - if (SINGLEREG(rDest)) { - if (SINGLEREG(rSrc)) { - opcode = kMipsFmovs; - } else { - /* note the operands are swapped for the mtc1 instr */ - int tOpnd = rSrc; - rSrc = rDest; - rDest = tOpnd; - opcode = kMipsMtc1; - } - } else { - DCHECK(SINGLEREG(rSrc)); - opcode = kMipsMfc1; - } + DCHECK(SINGLEREG(rSrc)); + opcode = kMipsMfc1; } - LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rSrc, rDest); - if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) { - res->flags.isNop = true; - } - return res; + } + LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rSrc, rDest); + if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) { + res->flags.isNop = true; + } + return res; } #endif @@ -90,445 +90,443 @@ LIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) * 1) rDest is freshly returned from oatAllocTemp or * 2) The codegen is under fixed register usage */ -LIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, - int value) +LIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, int value) { - LIR *res; + LIR *res; #ifdef __mips_hard_float - int rDestSave = rDest; - int isFpReg = FPREG(rDest); - if (isFpReg) { - DCHECK(SINGLEREG(rDest)); - rDest = oatAllocTemp(cUnit); - } + int rDestSave = rDest; + int isFpReg = FPREG(rDest); + if (isFpReg) { + DCHECK(SINGLEREG(rDest)); + rDest = oatAllocTemp(cUnit); + } #endif - /* See if the value can be constructed cheaply */ - if (value == 0) { - res = newLIR2(cUnit, kMipsMove, rDest, r_ZERO); - } else if ((value > 0) && (value <= 65535)) { - res = newLIR3(cUnit, kMipsOri, rDest, r_ZERO, value); - } else if ((value < 0) && (value >= -32768)) { - res = newLIR3(cUnit, kMipsAddiu, rDest, r_ZERO, value); - } else { - res = newLIR2(cUnit, kMipsLui, rDest, value>>16); - if (value & 0xffff) - newLIR3(cUnit, kMipsOri, rDest, rDest, value); - } + /* See if the value can be constructed cheaply */ + if (value == 0) { + res = newLIR2(cUnit, kMipsMove, rDest, r_ZERO); + } else if ((value > 0) && (value <= 65535)) { + res = newLIR3(cUnit, kMipsOri, rDest, r_ZERO, value); + } else if ((value < 0) && (value >= -32768)) { + res = newLIR3(cUnit, kMipsAddiu, rDest, r_ZERO, value); + } else { + res = newLIR2(cUnit, kMipsLui, rDest, value>>16); + if (value & 0xffff) + newLIR3(cUnit, kMipsOri, rDest, rDest, value); + } #ifdef __mips_hard_float - if (isFpReg) { - newLIR2(cUnit, kMipsMtc1, rDest, rDestSave); - oatFreeTemp(cUnit, rDest); - } + if (isFpReg) { + newLIR2(cUnit, kMipsMtc1, rDest, rDestSave); + oatFreeTemp(cUnit, rDest); + } #endif - return res; + return res; } LIR *opBranchUnconditional(CompilationUnit *cUnit, OpKind op) { - DCHECK_EQ(op, kOpUncondBr); - return newLIR1(cUnit, kMipsB, 0 /* offset to be patched */ ); + DCHECK_EQ(op, kOpUncondBr); + return newLIR1(cUnit, kMipsB, 0 /* offset to be patched */ ); } LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask); LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) { - MipsOpCode opcode = kMipsNop; - switch (op) { - case kOpBlx: - opcode = kMipsJalr; - break; - case kOpBx: - return newLIR1(cUnit, kMipsJr, rDestSrc); - break; - default: - LOG(FATAL) << "Bad case in opReg"; - } - return newLIR2(cUnit, opcode, r_RA, rDestSrc); + MipsOpCode opcode = kMipsNop; + switch (op) { + case kOpBlx: + opcode = kMipsJalr; + break; + case kOpBx: + return newLIR1(cUnit, kMipsJr, rDestSrc); + break; + default: + LOG(FATAL) << "Bad case in opReg"; + } + return newLIR2(cUnit, opcode, r_RA, rDestSrc); } LIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, - int rSrc1, int value); + int rSrc1, int value); LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, - int value) + int value) { - LIR *res; - bool neg = (value < 0); - int absValue = (neg) ? -value : value; - bool shortForm = (absValue & 0xff) == absValue; - MipsOpCode opcode = kMipsNop; - switch (op) { - case kOpAdd: - return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); - break; - case kOpSub: - return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); - break; - default: - LOG(FATAL) << "Bad case in opRegImm"; - break; - } - if (shortForm) - res = newLIR2(cUnit, opcode, rDestSrc1, absValue); - else { - int rScratch = oatAllocTemp(cUnit); - res = loadConstant(cUnit, rScratch, value); - if (op == kOpCmp) - newLIR2(cUnit, opcode, rDestSrc1, rScratch); - else - newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rScratch); - } - return res; + LIR *res; + bool neg = (value < 0); + int absValue = (neg) ? -value : value; + bool shortForm = (absValue & 0xff) == absValue; + MipsOpCode opcode = kMipsNop; + switch (op) { + case kOpAdd: + return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); + break; + case kOpSub: + return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); + break; + default: + LOG(FATAL) << "Bad case in opRegImm"; + break; + } + if (shortForm) + res = newLIR2(cUnit, opcode, rDestSrc1, absValue); + else { + int rScratch = oatAllocTemp(cUnit); + res = loadConstant(cUnit, rScratch, value); + if (op == kOpCmp) + newLIR2(cUnit, opcode, rDestSrc1, rScratch); + else + newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rScratch); + } + return res; } LIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest, - int rSrc1, int rSrc2) + int rSrc1, int rSrc2) { - MipsOpCode opcode = kMipsNop; - switch (op) { - case kOpAdd: - opcode = kMipsAddu; - break; - case kOpSub: - opcode = kMipsSubu; - break; - case kOpAnd: - opcode = kMipsAnd; - break; - case kOpMul: - opcode = kMipsMul; - break; - case kOpOr: - opcode = kMipsOr; - break; - case kOpXor: - opcode = kMipsXor; - break; - case kOpLsl: - opcode = kMipsSllv; - break; - case kOpLsr: - opcode = kMipsSrlv; - break; - case kOpAsr: - opcode = kMipsSrav; - break; - case kOpAdc: - case kOpSbc: - LOG(FATAL) << "No carry bit on MIPS"; - break; - default: - LOG(FATAL) << "bad case in opRegRegReg"; - break; - } - return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2); + MipsOpCode opcode = kMipsNop; + switch (op) { + case kOpAdd: + opcode = kMipsAddu; + break; + case kOpSub: + opcode = kMipsSubu; + break; + case kOpAnd: + opcode = kMipsAnd; + break; + case kOpMul: + opcode = kMipsMul; + break; + case kOpOr: + opcode = kMipsOr; + break; + case kOpXor: + opcode = kMipsXor; + break; + case kOpLsl: + opcode = kMipsSllv; + break; + case kOpLsr: + opcode = kMipsSrlv; + break; + case kOpAsr: + opcode = kMipsSrav; + break; + case kOpAdc: + case kOpSbc: + LOG(FATAL) << "No carry bit on MIPS"; + break; + default: + LOG(FATAL) << "bad case in opRegRegReg"; + break; + } + return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2); } LIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, - int rSrc1, int value) + int rSrc1, int value) { - LIR *res; - MipsOpCode opcode = kMipsNop; - bool shortForm = true; - - switch (op) { - case kOpAdd: - if (IS_SIMM16(value)) { - opcode = kMipsAddiu; - } - else { - shortForm = false; - opcode = kMipsAddu; - } - break; - case kOpSub: - if (IS_SIMM16((-value))) { - value = -value; - opcode = kMipsAddiu; - } - else { - shortForm = false; - opcode = kMipsSubu; - } - break; - case kOpLsl: - DCHECK(value >= 0 && value <= 31); - opcode = kMipsSll; - break; - case kOpLsr: - DCHECK(value >= 0 && value <= 31); - opcode = kMipsSrl; - break; - case kOpAsr: - DCHECK(value >= 0 && value <= 31); - opcode = kMipsSra; - break; - case kOpAnd: - if (IS_UIMM16((value))) { - opcode = kMipsAndi; - } - else { - shortForm = false; - opcode = kMipsAnd; - } - break; - case kOpOr: - if (IS_UIMM16((value))) { - opcode = kMipsOri; - } - else { - shortForm = false; - opcode = kMipsOr; - } - break; - case kOpXor: - if (IS_UIMM16((value))) { - opcode = kMipsXori; - } - else { - shortForm = false; - opcode = kMipsXor; - } - break; - case kOpMul: - shortForm = false; - opcode = kMipsMul; - break; - default: - LOG(FATAL) << "Bad case in opRegRegImm"; - break; - } - - if (shortForm) - res = newLIR3(cUnit, opcode, rDest, rSrc1, value); - else { - if (rDest != rSrc1) { - res = loadConstant(cUnit, rDest, value); - newLIR3(cUnit, opcode, rDest, rSrc1, rDest); - } else { - int rScratch = oatAllocTemp(cUnit); - res = loadConstant(cUnit, rScratch, value); - newLIR3(cUnit, opcode, rDest, rSrc1, rScratch); - } + LIR *res; + MipsOpCode opcode = kMipsNop; + bool shortForm = true; + + switch (op) { + case kOpAdd: + if (IS_SIMM16(value)) { + opcode = kMipsAddiu; + } + else { + shortForm = false; + opcode = kMipsAddu; + } + break; + case kOpSub: + if (IS_SIMM16((-value))) { + value = -value; + opcode = kMipsAddiu; + } + else { + shortForm = false; + opcode = kMipsSubu; + } + break; + case kOpLsl: + DCHECK(value >= 0 && value <= 31); + opcode = kMipsSll; + break; + case kOpLsr: + DCHECK(value >= 0 && value <= 31); + opcode = kMipsSrl; + break; + case kOpAsr: + DCHECK(value >= 0 && value <= 31); + opcode = kMipsSra; + break; + case kOpAnd: + if (IS_UIMM16((value))) { + opcode = kMipsAndi; + } + else { + shortForm = false; + opcode = kMipsAnd; + } + break; + case kOpOr: + if (IS_UIMM16((value))) { + opcode = kMipsOri; + } + else { + shortForm = false; + opcode = kMipsOr; + } + break; + case kOpXor: + if (IS_UIMM16((value))) { + opcode = kMipsXori; + } + else { + shortForm = false; + opcode = kMipsXor; + } + break; + case kOpMul: + shortForm = false; + opcode = kMipsMul; + break; + default: + LOG(FATAL) << "Bad case in opRegRegImm"; + break; + } + + if (shortForm) + res = newLIR3(cUnit, opcode, rDest, rSrc1, value); + else { + if (rDest != rSrc1) { + res = loadConstant(cUnit, rDest, value); + newLIR3(cUnit, opcode, rDest, rSrc1, rDest); + } else { + int rScratch = oatAllocTemp(cUnit); + res = loadConstant(cUnit, rScratch, value); + newLIR3(cUnit, opcode, rDest, rSrc1, rScratch); } - return res; + } + return res; } -LIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, - int rSrc2) +LIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int rSrc2) { - MipsOpCode opcode = kMipsNop; - LIR *res; - switch (op) { - case kOpMov: - opcode = kMipsMove; - break; - case kOpMvn: - return newLIR3(cUnit, kMipsNor, rDestSrc1, rSrc2, r_ZERO); - case kOpNeg: - return newLIR3(cUnit, kMipsSubu, rDestSrc1, r_ZERO, rSrc2); - case kOpAdd: - case kOpAnd: - case kOpMul: - case kOpOr: - case kOpSub: - case kOpXor: - return opRegRegReg(cUnit, op, rDestSrc1, rDestSrc1, rSrc2); - case kOp2Byte: + MipsOpCode opcode = kMipsNop; + LIR *res; + switch (op) { + case kOpMov: + opcode = kMipsMove; + break; + case kOpMvn: + return newLIR3(cUnit, kMipsNor, rDestSrc1, rSrc2, r_ZERO); + case kOpNeg: + return newLIR3(cUnit, kMipsSubu, rDestSrc1, r_ZERO, rSrc2); + case kOpAdd: + case kOpAnd: + case kOpMul: + case kOpOr: + case kOpSub: + case kOpXor: + return opRegRegReg(cUnit, op, rDestSrc1, rDestSrc1, rSrc2); + case kOp2Byte: #if __mips_isa_rev>=2 - res = newLIR2(cUnit, kMipsSeb, rDestSrc1, rSrc2); + res = newLIR2(cUnit, kMipsSeb, rDestSrc1, rSrc2); #else - res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 24); - opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 24); + res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 24); + opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 24); #endif - return res; - case kOp2Short: + return res; + case kOp2Short: #if __mips_isa_rev>=2 - res = newLIR2(cUnit, kMipsSeh, rDestSrc1, rSrc2); + res = newLIR2(cUnit, kMipsSeh, rDestSrc1, rSrc2); #else - res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 16); - opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 16); + res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 16); + opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 16); #endif - return res; - case kOp2Char: - return newLIR3(cUnit, kMipsAndi, rDestSrc1, rSrc2, 0xFFFF); - default: - LOG(FATAL) << "Bad case in opRegReg"; - break; - } - return newLIR2(cUnit, opcode, rDestSrc1, rSrc2); + return res; + case kOp2Char: + return newLIR3(cUnit, kMipsAndi, rDestSrc1, rSrc2, 0xFFFF); + default: + LOG(FATAL) << "Bad case in opRegReg"; + break; + } + return newLIR2(cUnit, opcode, rDestSrc1, rSrc2); } LIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo, - int rDestHi, int valLo, int valHi) + int rDestHi, int valLo, int valHi) { - LIR *res; - res = loadConstantNoClobber(cUnit, rDestLo, valLo); - loadConstantNoClobber(cUnit, rDestHi, valHi); - return res; + LIR *res; + res = loadConstantNoClobber(cUnit, rDestLo, valLo); + loadConstantNoClobber(cUnit, rDestHi, valHi); + return res; } /* Load value from base + scaled index. */ LIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, - int rIndex, int rDest, int scale, OpSize size) + int rIndex, int rDest, int scale, OpSize size) { - LIR *first = NULL; - LIR *res; - MipsOpCode opcode = kMipsNop; - int tReg = oatAllocTemp(cUnit); + LIR *first = NULL; + LIR *res; + MipsOpCode opcode = kMipsNop; + int tReg = oatAllocTemp(cUnit); #ifdef __mips_hard_float - if (FPREG(rDest)) { - DCHECK(SINGLEREG(rDest)); - DCHECK((size == kWord) || (size == kSingle)); - size = kSingle; - } else { - if (size == kSingle) - size = kWord; - } + if (FPREG(rDest)) { + DCHECK(SINGLEREG(rDest)); + DCHECK((size == kWord) || (size == kSingle)); + size = kSingle; + } else { + if (size == kSingle) + size = kWord; + } #endif - if (!scale) { - first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex); - } else { - first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); - newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg); - } + if (!scale) { + first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex); + } else { + first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); + newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg); + } - switch (size) { + switch (size) { #ifdef __mips_hard_float - case kSingle: - opcode = kMipsFlwc1; - break; + case kSingle: + opcode = kMipsFlwc1; + break; #endif - case kWord: - opcode = kMipsLw; - break; - case kUnsignedHalf: - opcode = kMipsLhu; - break; - case kSignedHalf: - opcode = kMipsLh; - break; - case kUnsignedByte: - opcode = kMipsLbu; - break; - case kSignedByte: - opcode = kMipsLb; - break; - default: - LOG(FATAL) << "Bad case in loadBaseIndexed"; - } - - res = newLIR3(cUnit, opcode, rDest, 0, tReg); - oatFreeTemp(cUnit, tReg); - return (first) ? first : res; + case kWord: + opcode = kMipsLw; + break; + case kUnsignedHalf: + opcode = kMipsLhu; + break; + case kSignedHalf: + opcode = kMipsLh; + break; + case kUnsignedByte: + opcode = kMipsLbu; + break; + case kSignedByte: + opcode = kMipsLb; + break; + default: + LOG(FATAL) << "Bad case in loadBaseIndexed"; + } + + res = newLIR3(cUnit, opcode, rDest, 0, tReg); + oatFreeTemp(cUnit, tReg); + return (first) ? first : res; } /* store value base base + scaled index. */ LIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, - int rIndex, int rSrc, int scale, OpSize size) + int rIndex, int rSrc, int scale, OpSize size) { - LIR *first = NULL; - LIR *res; - MipsOpCode opcode = kMipsNop; - int rNewIndex = rIndex; - int tReg = oatAllocTemp(cUnit); + LIR *first = NULL; + LIR *res; + MipsOpCode opcode = kMipsNop; + int rNewIndex = rIndex; + int tReg = oatAllocTemp(cUnit); #ifdef __mips_hard_float - if (FPREG(rSrc)) { - DCHECK(SINGLEREG(rSrc)); - DCHECK((size == kWord) || (size == kSingle)); - size = kSingle; - } else { - if (size == kSingle) - size = kWord; - } + if (FPREG(rSrc)) { + DCHECK(SINGLEREG(rSrc)); + DCHECK((size == kWord) || (size == kSingle)); + size = kSingle; + } else { + if (size == kSingle) + size = kWord; + } #endif - if (!scale) { - first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex); - } else { - first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); - newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg); - } + if (!scale) { + first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex); + } else { + first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); + newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg); + } - switch (size) { + switch (size) { #ifdef __mips_hard_float - case kSingle: - opcode = kMipsFswc1; - break; + case kSingle: + opcode = kMipsFswc1; + break; #endif - case kWord: - opcode = kMipsSw; - break; - case kUnsignedHalf: - case kSignedHalf: - opcode = kMipsSh; - break; - case kUnsignedByte: - case kSignedByte: - opcode = kMipsSb; - break; - default: - LOG(FATAL) << "Bad case in storeBaseIndexed"; - } - res = newLIR3(cUnit, opcode, rSrc, 0, tReg); - oatFreeTemp(cUnit, rNewIndex); - return first; + case kWord: + opcode = kMipsSw; + break; + case kUnsignedHalf: + case kSignedHalf: + opcode = kMipsSh; + break; + case kUnsignedByte: + case kSignedByte: + opcode = kMipsSb; + break; + default: + LOG(FATAL) << "Bad case in storeBaseIndexed"; + } + res = newLIR3(cUnit, opcode, rSrc, 0, tReg); + oatFreeTemp(cUnit, rNewIndex); + return first; } LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) { - int i; - int loadCnt = 0; - LIR *res = NULL ; - genBarrier(cUnit); - - for (i = 0; i < 8; i++, rMask >>= 1) { - if (rMask & 0x1) { /* map r0 to MIPS r_A0 */ - newLIR3(cUnit, kMipsLw, i+r_A0, loadCnt*4, rBase); - loadCnt++; - } + int i; + int loadCnt = 0; + LIR *res = NULL ; + genBarrier(cUnit); + + for (i = 0; i < 8; i++, rMask >>= 1) { + if (rMask & 0x1) { /* map r0 to MIPS r_A0 */ + newLIR3(cUnit, kMipsLw, i+r_A0, loadCnt*4, rBase); + loadCnt++; } + } - if (loadCnt) {/* increment after */ - newLIR3(cUnit, kMipsAddiu, rBase, rBase, loadCnt*4); - } + if (loadCnt) {/* increment after */ + newLIR3(cUnit, kMipsAddiu, rBase, rBase, loadCnt*4); + } - genBarrier(cUnit); - return res; /* NULL always returned which should be ok since no callers use it */ + genBarrier(cUnit); + return res; /* NULL always returned which should be ok since no callers use it */ } LIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask) { - int i; - int storeCnt = 0; - LIR *res = NULL ; - genBarrier(cUnit); - - for (i = 0; i < 8; i++, rMask >>= 1) { - if (rMask & 0x1) { /* map r0 to MIPS r_A0 */ - newLIR3(cUnit, kMipsSw, i+r_A0, storeCnt*4, rBase); - storeCnt++; - } + int i; + int storeCnt = 0; + LIR *res = NULL ; + genBarrier(cUnit); + + for (i = 0; i < 8; i++, rMask >>= 1) { + if (rMask & 0x1) { /* map r0 to MIPS r_A0 */ + newLIR3(cUnit, kMipsSw, i+r_A0, storeCnt*4, rBase); + storeCnt++; } + } - if (storeCnt) { /* increment after */ - newLIR3(cUnit, kMipsAddiu, rBase, rBase, storeCnt*4); - } + if (storeCnt) { /* increment after */ + newLIR3(cUnit, kMipsAddiu, rBase, rBase, storeCnt*4); + } - genBarrier(cUnit); - return res; /* NULL always returned which should be ok since no callers use it */ + genBarrier(cUnit); + return res; /* NULL always returned which should be ok since no callers use it */ } LIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, - int displacement, int rDest, int rDestHi, - OpSize size, int sReg) + int displacement, int rDest, int rDestHi, + OpSize size, int sReg) /* * Load value from base + displacement. Optionally perform null check * on base (which must have an associated sReg and MIR). If not @@ -538,221 +536,222 @@ LIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, * rlp and then restore. */ { - LIR *res; - LIR *load = NULL; - LIR *load2 = NULL; - MipsOpCode opcode = kMipsNop; - bool shortForm = IS_SIMM16(displacement); - bool pair = false; - - switch (size) { - case kLong: - case kDouble: - pair = true; - opcode = kMipsLw; + LIR *res; + LIR *load = NULL; + LIR *load2 = NULL; + MipsOpCode opcode = kMipsNop; + bool shortForm = IS_SIMM16(displacement); + bool pair = false; + + switch (size) { + case kLong: + case kDouble: + pair = true; + opcode = kMipsLw; #ifdef __mips_hard_float - if (FPREG(rDest)) { - opcode = kMipsFlwc1; - if (DOUBLEREG(rDest)) { - rDest = rDest - FP_DOUBLE; - } else { - DCHECK(FPREG(rDestHi)); - DCHECK(rDest == (rDestHi - 1)); - } - rDestHi = rDest + 1; - } + if (FPREG(rDest)) { + opcode = kMipsFlwc1; + if (DOUBLEREG(rDest)) { + rDest = rDest - FP_DOUBLE; + } else { + DCHECK(FPREG(rDestHi)); + DCHECK(rDest == (rDestHi - 1)); + } + rDestHi = rDest + 1; + } #endif - shortForm = IS_SIMM16_2WORD(displacement); - DCHECK_EQ((displacement & 0x3), 0); - break; - case kWord: - case kSingle: - opcode = kMipsLw; + shortForm = IS_SIMM16_2WORD(displacement); + DCHECK_EQ((displacement & 0x3), 0); + break; + case kWord: + case kSingle: + opcode = kMipsLw; #ifdef __mips_hard_float - if (FPREG(rDest)) { - opcode = kMipsFlwc1; - DCHECK(SINGLEREG(rDest)); - } + if (FPREG(rDest)) { + opcode = kMipsFlwc1; + DCHECK(SINGLEREG(rDest)); + } #endif - DCHECK_EQ((displacement & 0x3), 0); - break; - case kUnsignedHalf: - opcode = kMipsLhu; - DCHECK_EQ((displacement & 0x1), 0); - break; - case kSignedHalf: - opcode = kMipsLh; - DCHECK_EQ((displacement & 0x1), 0); - break; - case kUnsignedByte: - opcode = kMipsLbu; - break; - case kSignedByte: - opcode = kMipsLb; - break; - default: - LOG(FATAL) << "Bad case in loadBaseIndexedBody"; + DCHECK_EQ((displacement & 0x3), 0); + break; + case kUnsignedHalf: + opcode = kMipsLhu; + DCHECK_EQ((displacement & 0x1), 0); + break; + case kSignedHalf: + opcode = kMipsLh; + DCHECK_EQ((displacement & 0x1), 0); + break; + case kUnsignedByte: + opcode = kMipsLbu; + break; + case kSignedByte: + opcode = kMipsLb; + break; + default: + LOG(FATAL) << "Bad case in loadBaseIndexedBody"; + } + + if (shortForm) { + if (!pair) { + load = res = newLIR3(cUnit, opcode, rDest, displacement, rBase); + } else { + load = res = newLIR3(cUnit, opcode, rDest, + displacement + LOWORD_OFFSET, rBase); + load2 = newLIR3(cUnit, opcode, rDestHi, + displacement + HIWORD_OFFSET, rBase); } - - if (shortForm) { - if (!pair) { - load = res = newLIR3(cUnit, opcode, rDest, displacement, rBase); - } else { - load = res = newLIR3(cUnit, opcode, rDest, displacement + LOWORD_OFFSET, rBase); - load2 = newLIR3(cUnit, opcode, rDestHi, displacement + HIWORD_OFFSET, rBase); - } + } else { + if (pair) { + int rTmp = oatAllocFreeTemp(cUnit); + res = opRegRegImm(cUnit, kOpAdd, rTmp, rBase, displacement); + load = newLIR3(cUnit, opcode, rDest, LOWORD_OFFSET, rTmp); + load2 = newLIR3(cUnit, opcode, rDestHi, HIWORD_OFFSET, rTmp); + oatFreeTemp(cUnit, rTmp); } else { - if (pair) { - int rTmp = oatAllocFreeTemp(cUnit); - res = opRegRegImm(cUnit, kOpAdd, rTmp, rBase, displacement); - load = newLIR3(cUnit, opcode, rDest, LOWORD_OFFSET, rTmp); - load2 = newLIR3(cUnit, opcode, rDestHi, HIWORD_OFFSET, rTmp); - oatFreeTemp(cUnit, rTmp); - } else { - int rTmp = (rBase == rDest) ? oatAllocFreeTemp(cUnit) - : rDest; - res = loadConstant(cUnit, rTmp, displacement); - load = newLIR3(cUnit, opcode, rDest, rBase, rTmp); - if (rTmp != rDest) - oatFreeTemp(cUnit, rTmp); - } + int rTmp = (rBase == rDest) ? oatAllocFreeTemp(cUnit) : rDest; + res = loadConstant(cUnit, rTmp, displacement); + load = newLIR3(cUnit, opcode, rDest, rBase, rTmp); + if (rTmp != rDest) + oatFreeTemp(cUnit, rTmp); } - - if (rBase == rSP) { - annotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, - true /* isLoad */, pair /* is64bit */); - if (pair) { - annotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, - true /* isLoad */, pair /* is64bit */); - } + } + + if (rBase == rSP) { + annotateDalvikRegAccess(load, + (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, + true /* isLoad */, pair /* is64bit */); + if (pair) { + annotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, + true /* isLoad */, pair /* is64bit */); } - return load; + } + return load; } LIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase, - int displacement, int rDest, OpSize size, - int sReg) + int displacement, int rDest, OpSize size, int sReg) { - return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, - size, sReg); + return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, + size, sReg); } LIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase, - int displacement, int rDestLo, int rDestHi, - int sReg) + int displacement, int rDestLo, int rDestHi, int sReg) { - return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, - kLong, sReg); + return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, + kLong, sReg); } LIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, - int displacement, int rSrc, int rSrcHi, - OpSize size) + int displacement, int rSrc, int rSrcHi, OpSize size) { - LIR *res; - LIR *store = NULL; - LIR *store2 = NULL; - MipsOpCode opcode = kMipsNop; - bool shortForm = IS_SIMM16(displacement); - bool pair = false; - - switch (size) { - case kLong: - case kDouble: - pair = true; - opcode = kMipsSw; + LIR *res; + LIR *store = NULL; + LIR *store2 = NULL; + MipsOpCode opcode = kMipsNop; + bool shortForm = IS_SIMM16(displacement); + bool pair = false; + + switch (size) { + case kLong: + case kDouble: + pair = true; + opcode = kMipsSw; #ifdef __mips_hard_float - if (FPREG(rSrc)) { - opcode = kMipsFswc1; - if (DOUBLEREG(rSrc)) { - rSrc = rSrc - FP_DOUBLE; - } else { - DCHECK(FPREG(rSrcHi)); - DCHECK_EQ(rSrc, (rSrcHi - 1)); - } - rSrcHi = rSrc + 1; - } + if (FPREG(rSrc)) { + opcode = kMipsFswc1; + if (DOUBLEREG(rSrc)) { + rSrc = rSrc - FP_DOUBLE; + } else { + DCHECK(FPREG(rSrcHi)); + DCHECK_EQ(rSrc, (rSrcHi - 1)); + } + rSrcHi = rSrc + 1; + } #endif - shortForm = IS_SIMM16_2WORD(displacement); - DCHECK_EQ((displacement & 0x3), 0); - break; - case kWord: - case kSingle: - opcode = kMipsSw; + shortForm = IS_SIMM16_2WORD(displacement); + DCHECK_EQ((displacement & 0x3), 0); + break; + case kWord: + case kSingle: + opcode = kMipsSw; #ifdef __mips_hard_float - if (FPREG(rSrc)) { - opcode = kMipsFswc1; - DCHECK(SINGLEREG(rSrc)); - } + if (FPREG(rSrc)) { + opcode = kMipsFswc1; + DCHECK(SINGLEREG(rSrc)); + } #endif - DCHECK_EQ((displacement & 0x3), 0); - break; - case kUnsignedHalf: - case kSignedHalf: - opcode = kMipsSh; - DCHECK_EQ((displacement & 0x1), 0); - break; - case kUnsignedByte: - case kSignedByte: - opcode = kMipsSb; - break; - default: - LOG(FATAL) << "Bad case in storeBaseIndexedBody"; + DCHECK_EQ((displacement & 0x3), 0); + break; + case kUnsignedHalf: + case kSignedHalf: + opcode = kMipsSh; + DCHECK_EQ((displacement & 0x1), 0); + break; + case kUnsignedByte: + case kSignedByte: + opcode = kMipsSb; + break; + default: + LOG(FATAL) << "Bad case in storeBaseIndexedBody"; + } + + if (shortForm) { + if (!pair) { + store = res = newLIR3(cUnit, opcode, rSrc, displacement, rBase); + } else { + store = res = newLIR3(cUnit, opcode, rSrc, displacement + LOWORD_OFFSET, + rBase); + store2 = newLIR3(cUnit, opcode, rSrcHi, displacement + HIWORD_OFFSET, + rBase); } - - if (shortForm) { - if (!pair) { - store = res = newLIR3(cUnit, opcode, rSrc, displacement, rBase); - } else { - store = res = newLIR3(cUnit, opcode, rSrc, displacement + LOWORD_OFFSET, rBase); - store2 = newLIR3(cUnit, opcode, rSrcHi, displacement + HIWORD_OFFSET, rBase); - } + } else { + int rScratch = oatAllocTemp(cUnit); + res = opRegRegImm(cUnit, kOpAdd, rScratch, rBase, displacement); + if (!pair) { + store = newLIR3(cUnit, opcode, rSrc, 0, rScratch); } else { - int rScratch = oatAllocTemp(cUnit); - res = opRegRegImm(cUnit, kOpAdd, rScratch, rBase, displacement); - if (!pair) { - store = newLIR3(cUnit, opcode, rSrc, 0, rScratch); - } else { - store = newLIR3(cUnit, opcode, rSrc, LOWORD_OFFSET, rScratch); - store2 = newLIR3(cUnit, opcode, rSrcHi, HIWORD_OFFSET, rScratch); - } - oatFreeTemp(cUnit, rScratch); + store = newLIR3(cUnit, opcode, rSrc, LOWORD_OFFSET, rScratch); + store2 = newLIR3(cUnit, opcode, rSrcHi, HIWORD_OFFSET, rScratch); } - - if (rBase == rSP) { - annotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, - false /* isLoad */, pair /* is64bit */); - if (pair) { - annotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, - false /* isLoad */, pair /* is64bit */); - } + oatFreeTemp(cUnit, rScratch); + } + + if (rBase == rSP) { + annotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) + >> 2, false /* isLoad */, pair /* is64bit */); + if (pair) { + annotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, + false /* isLoad */, pair /* is64bit */); } + } - return res; + return res; } LIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, - int displacement, int rSrc, OpSize size) + int displacement, int rSrc, OpSize size) { - return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); + return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); } LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, - int displacement, int rSrcLo, int rSrcHi) + int displacement, int rSrcLo, int rSrcHi) { - return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); + return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); } void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg) { - storeWordDisp(cUnit, base, LOWORD_OFFSET, lowReg); - storeWordDisp(cUnit, base, HIWORD_OFFSET, highReg); + storeWordDisp(cUnit, base, LOWORD_OFFSET, lowReg); + storeWordDisp(cUnit, base, HIWORD_OFFSET, highReg); } void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg) { - loadWordDisp(cUnit, base, LOWORD_OFFSET , lowReg); - loadWordDisp(cUnit, base, HIWORD_OFFSET , highReg); + loadWordDisp(cUnit, base, LOWORD_OFFSET , lowReg); + loadWordDisp(cUnit, base, HIWORD_OFFSET , highReg); } } // namespace art diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc index ade2fd8453..46c90f89ac 100644 --- a/src/compiler/codegen/mips/Mips32/Gen.cc +++ b/src/compiler/codegen/mips/Mips32/Gen.cc @@ -64,69 +64,69 @@ void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, * */ void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc, - LIR* labelList) + LIR* labelList) { - const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB; - if (cUnit->printMe) { - dumpSparseSwitchTable(table); - } - // Add the table to the list - we'll process it later - SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable), - true, kAllocData); - tabRec->table = table; - tabRec->vaddr = mir->offset; - int elements = table[1]; - tabRec->targets = (LIR* *)oatNew(cUnit, elements * sizeof(LIR*), true, - kAllocLIR); - oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec); - - // The table is composed of 8-byte key/disp pairs - int byteSize = elements * 8; - - int sizeHi = byteSize >> 16; - int sizeLo = byteSize & 0xffff; - - int rEnd = oatAllocTemp(cUnit); - if (sizeHi) { - newLIR2(cUnit, kMipsLui, rEnd, sizeHi); - } - // Must prevent code motion for the curr pc pair - genBarrier(cUnit); // Scheduling barrier - newLIR0(cUnit, kMipsCurrPC); // Really a jal to .+8 - // Now, fill the branch delay slot - if (sizeHi) { - newLIR3(cUnit, kMipsOri, rEnd, rEnd, sizeLo); - } else { - newLIR3(cUnit, kMipsOri, rEnd, r_ZERO, sizeLo); - } - genBarrier(cUnit); // Scheduling barrier - - // Construct BaseLabel and set up table base register - LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel); - // Remember base label so offsets can be computed later - tabRec->anchor = baseLabel; - int rBase = oatAllocTemp(cUnit); - newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec); - opRegRegReg(cUnit, kOpAdd, rEnd, rEnd, rBase); - - // Grab switch test value - rlSrc = loadValue(cUnit, rlSrc, kCoreReg); - - // Test loop - int rKey = oatAllocTemp(cUnit); - LIR* loopLabel = newLIR0(cUnit, kPseudoTargetLabel); - LIR* exitBranch = opCmpBranch(cUnit , kCondEq, rBase, rEnd, NULL); - loadWordDisp(cUnit, rBase, 0, rKey); - opRegImm(cUnit, kOpAdd, rBase, 8); - opCmpBranch(cUnit, kCondNe, rlSrc.lowReg, rKey, loopLabel); - int rDisp = oatAllocTemp(cUnit); - loadWordDisp(cUnit, rBase, -4, rDisp); - opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp); - opReg(cUnit, kOpBx, r_RA); - - // Loop exit - LIR* exitLabel = newLIR0(cUnit, kPseudoTargetLabel); - exitBranch->target = exitLabel; + const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB; + if (cUnit->printMe) { + dumpSparseSwitchTable(table); + } + // Add the table to the list - we'll process it later + SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable), + true, kAllocData); + tabRec->table = table; + tabRec->vaddr = mir->offset; + int elements = table[1]; + tabRec->targets = (LIR* *)oatNew(cUnit, elements * sizeof(LIR*), true, + kAllocLIR); + oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec); + + // The table is composed of 8-byte key/disp pairs + int byteSize = elements * 8; + + int sizeHi = byteSize >> 16; + int sizeLo = byteSize & 0xffff; + + int rEnd = oatAllocTemp(cUnit); + if (sizeHi) { + newLIR2(cUnit, kMipsLui, rEnd, sizeHi); + } + // Must prevent code motion for the curr pc pair + genBarrier(cUnit); // Scheduling barrier + newLIR0(cUnit, kMipsCurrPC); // Really a jal to .+8 + // Now, fill the branch delay slot + if (sizeHi) { + newLIR3(cUnit, kMipsOri, rEnd, rEnd, sizeLo); + } else { + newLIR3(cUnit, kMipsOri, rEnd, r_ZERO, sizeLo); + } + genBarrier(cUnit); // Scheduling barrier + + // Construct BaseLabel and set up table base register + LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel); + // Remember base label so offsets can be computed later + tabRec->anchor = baseLabel; + int rBase = oatAllocTemp(cUnit); + newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec); + opRegRegReg(cUnit, kOpAdd, rEnd, rEnd, rBase); + + // Grab switch test value + rlSrc = loadValue(cUnit, rlSrc, kCoreReg); + + // Test loop + int rKey = oatAllocTemp(cUnit); + LIR* loopLabel = newLIR0(cUnit, kPseudoTargetLabel); + LIR* exitBranch = opCmpBranch(cUnit , kCondEq, rBase, rEnd, NULL); + loadWordDisp(cUnit, rBase, 0, rKey); + opRegImm(cUnit, kOpAdd, rBase, 8); + opCmpBranch(cUnit, kCondNe, rlSrc.lowReg, rKey, loopLabel); + int rDisp = oatAllocTemp(cUnit); + loadWordDisp(cUnit, rBase, -4, rDisp); + opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp); + opReg(cUnit, kOpBx, r_RA); + + // Loop exit + LIR* exitLabel = newLIR0(cUnit, kPseudoTargetLabel); + exitBranch->target = exitLabel; } /* @@ -144,75 +144,75 @@ void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc, */ void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) { - const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB; - if (cUnit->printMe) { - dumpPackedSwitchTable(table); - } - // Add the table to the list - we'll process it later - SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable), - true, kAllocData); - tabRec->table = table; - tabRec->vaddr = mir->offset; - int size = table[1]; - tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, - kAllocLIR); - oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec); - - // Get the switch value - rlSrc = loadValue(cUnit, rlSrc, kCoreReg); - - // Prepare the bias. If too big, handle 1st stage here - int lowKey = s4FromSwitchData(&table[2]); - bool largeBias = false; - int rKey; - if (lowKey == 0) { - rKey = rlSrc.lowReg; - } else if ((lowKey & 0xffff) != lowKey) { - rKey = oatAllocTemp(cUnit); - loadConstant(cUnit, rKey, lowKey); - largeBias = true; + const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB; + if (cUnit->printMe) { + dumpPackedSwitchTable(table); + } + // Add the table to the list - we'll process it later + SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable), + true, kAllocData); + tabRec->table = table; + tabRec->vaddr = mir->offset; + int size = table[1]; + tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, + kAllocLIR); + oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec); + + // Get the switch value + rlSrc = loadValue(cUnit, rlSrc, kCoreReg); + + // Prepare the bias. If too big, handle 1st stage here + int lowKey = s4FromSwitchData(&table[2]); + bool largeBias = false; + int rKey; + if (lowKey == 0) { + rKey = rlSrc.lowReg; + } else if ((lowKey & 0xffff) != lowKey) { + rKey = oatAllocTemp(cUnit); + loadConstant(cUnit, rKey, lowKey); + largeBias = true; + } else { + rKey = oatAllocTemp(cUnit); + } + + // Must prevent code motion for the curr pc pair + genBarrier(cUnit); + newLIR0(cUnit, kMipsCurrPC); // Really a jal to .+8 + // Now, fill the branch delay slot with bias strip + if (lowKey == 0) { + newLIR0(cUnit, kMipsNop); + } else { + if (largeBias) { + opRegRegReg(cUnit, kOpSub, rKey, rlSrc.lowReg, rKey); } else { - rKey = oatAllocTemp(cUnit); + opRegRegImm(cUnit, kOpSub, rKey, rlSrc.lowReg, lowKey); } + } + genBarrier(cUnit); // Scheduling barrier - // Must prevent code motion for the curr pc pair - genBarrier(cUnit); - newLIR0(cUnit, kMipsCurrPC); // Really a jal to .+8 - // Now, fill the branch delay slot with bias strip - if (lowKey == 0) { - newLIR0(cUnit, kMipsNop); - } else { - if (largeBias) { - opRegRegReg(cUnit, kOpSub, rKey, rlSrc.lowReg, rKey); - } else { - opRegRegImm(cUnit, kOpSub, rKey, rlSrc.lowReg, lowKey); - } - } - genBarrier(cUnit); // Scheduling barrier + // Construct BaseLabel and set up table base register + LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel); + // Remember base label so offsets can be computed later + tabRec->anchor = baseLabel; - // Construct BaseLabel and set up table base register - LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel); - // Remember base label so offsets can be computed later - tabRec->anchor = baseLabel; + // Bounds check - if < 0 or >= size continue following switch + LIR* branchOver = opCmpImmBranch(cUnit, kCondHi, rKey, size-1, NULL); - // Bounds check - if < 0 or >= size continue following switch - LIR* branchOver = opCmpImmBranch(cUnit, kCondHi, rKey, size-1, NULL); + // Materialize the table base pointer + int rBase = oatAllocTemp(cUnit); + newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec); - // Materialize the table base pointer - int rBase = oatAllocTemp(cUnit); - newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec); + // Load the displacement from the switch table + int rDisp = oatAllocTemp(cUnit); + loadBaseIndexed(cUnit, rBase, rKey, rDisp, 2, kWord); - // Load the displacement from the switch table - int rDisp = oatAllocTemp(cUnit); - loadBaseIndexed(cUnit, rBase, rKey, rDisp, 2, kWord); + // Add to r_AP and go + opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp); + opReg(cUnit, kOpBx, r_RA); - // Add to r_AP and go - opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp); - opReg(cUnit, kOpBx, r_RA); - - /* branchOver target here */ - LIR* target = newLIR0(cUnit, kPseudoTargetLabel); - branchOver->target = (LIR*)target; + /* branchOver target here */ + LIR* target = newLIR0(cUnit, kPseudoTargetLabel); + branchOver->target = (LIR*)target; } /* @@ -227,60 +227,58 @@ void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) */ void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) { - const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB; - // Add the table to the list - we'll process it later - FillArrayData *tabRec = (FillArrayData *) - oatNew(cUnit, sizeof(FillArrayData), true, kAllocData); - tabRec->table = table; - tabRec->vaddr = mir->offset; - u2 width = tabRec->table[1]; - u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16); - tabRec->size = (size * width) + 8; - - oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec); - - // Making a call - use explicit registers - oatFlushAllRegs(cUnit); /* Everything to home location */ - oatLockCallTemps(cUnit); - loadValueDirectFixed(cUnit, rlSrc, rARG0); - - // Must prevent code motion for the curr pc pair - genBarrier(cUnit); - newLIR0(cUnit, kMipsCurrPC); // Really a jal to .+8 - // Now, fill the branch delay slot with the helper load - int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode)); - genBarrier(cUnit); // Scheduling barrier - - // Construct BaseLabel and set up table base register - LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel); - - // Materialize a pointer to the fill data image - newLIR4(cUnit, kMipsDelta, rARG1, 0, (intptr_t)baseLabel, (intptr_t)tabRec); - - // And go... - oatClobberCalleeSave(cUnit); - opReg(cUnit, kOpBlx, rTgt); // ( array*, fill_data* ) + const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB; + // Add the table to the list - we'll process it later + FillArrayData *tabRec = (FillArrayData *) + oatNew(cUnit, sizeof(FillArrayData), true, kAllocData); + tabRec->table = table; + tabRec->vaddr = mir->offset; + u2 width = tabRec->table[1]; + u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16); + tabRec->size = (size * width) + 8; + + oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec); + + // Making a call - use explicit registers + oatFlushAllRegs(cUnit); /* Everything to home location */ + oatLockCallTemps(cUnit); + loadValueDirectFixed(cUnit, rlSrc, rARG0); + + // Must prevent code motion for the curr pc pair + genBarrier(cUnit); + newLIR0(cUnit, kMipsCurrPC); // Really a jal to .+8 + // Now, fill the branch delay slot with the helper load + int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode)); + genBarrier(cUnit); // Scheduling barrier + + // Construct BaseLabel and set up table base register + LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel); + + // Materialize a pointer to the fill data image + newLIR4(cUnit, kMipsDelta, rARG1, 0, (intptr_t)baseLabel, (intptr_t)tabRec); + + // And go... + oatClobberCalleeSave(cUnit); + opReg(cUnit, kOpBlx, rTgt); // ( array*, fill_data* ) } void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc) { - RegLocation rlResult; - rlSrc = loadValue(cUnit, rlSrc, kCoreReg); - rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, - rlSrc.lowReg, 0x80000000); - storeValue(cUnit, rlDest, rlResult); + RegLocation rlResult; + rlSrc = loadValue(cUnit, rlSrc, kCoreReg); + rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, 0x80000000); + storeValue(cUnit, rlDest, rlResult); } void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc) { - RegLocation rlResult; - rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg); - rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, - 0x80000000); - opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg); - storeValueWide(cUnit, rlDest, rlResult); + RegLocation rlResult; + rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg); + rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, 0x80000000); + opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg); + storeValueWide(cUnit, rlDest, rlResult); } /* @@ -288,14 +286,14 @@ void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc) */ void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) { - oatFlushAllRegs(cUnit); - loadValueDirectFixed(cUnit, rlSrc, rARG0); // Get obj - oatLockCallTemps(cUnit); // Prepare for explicit register usage - genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir); - // Go expensive route - artLockObjectFromCode(self, obj); - int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode)); - oatClobberCalleeSave(cUnit); - opReg(cUnit, kOpBlx, rTgt); + oatFlushAllRegs(cUnit); + loadValueDirectFixed(cUnit, rlSrc, rARG0); // Get obj + oatLockCallTemps(cUnit); // Prepare for explicit register usage + genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir); + // Go expensive route - artLockObjectFromCode(self, obj); + int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode)); + oatClobberCalleeSave(cUnit); + opReg(cUnit, kOpBlx, rTgt); } /* @@ -303,14 +301,14 @@ void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) */ void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) { - oatFlushAllRegs(cUnit); - loadValueDirectFixed(cUnit, rlSrc, rARG0); // Get obj - oatLockCallTemps(cUnit); // Prepare for explicit register usage - genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir); - // Go expensive route - UnlockObjectFromCode(obj); - int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode)); - oatClobberCalleeSave(cUnit); - opReg(cUnit, kOpBlx, rTgt); + oatFlushAllRegs(cUnit); + loadValueDirectFixed(cUnit, rlSrc, rARG0); // Get obj + oatLockCallTemps(cUnit); // Prepare for explicit register usage + genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir); + // Go expensive route - UnlockObjectFromCode(obj); + int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode)); + oatClobberCalleeSave(cUnit); + opReg(cUnit, kOpBlx, rTgt); } /* @@ -330,190 +328,190 @@ void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) * */ void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2) + RegLocation rlSrc1, RegLocation rlSrc2) { - rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); - rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); - int t0 = oatAllocTemp(cUnit); - int t1 = oatAllocTemp(cUnit); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - 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 = 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); - oatFreeTemp(cUnit, t0); - oatFreeTemp(cUnit, t1); - LIR* target = newLIR0(cUnit, kPseudoTargetLabel); - branch->target = (LIR*)target; - storeValue(cUnit, rlDest, rlResult); + rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); + rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); + int t0 = oatAllocTemp(cUnit); + int t1 = oatAllocTemp(cUnit); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + 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 = 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); + oatFreeTemp(cUnit, t0); + oatFreeTemp(cUnit, t1); + LIR* target = newLIR0(cUnit, kPseudoTargetLabel); + branch->target = (LIR*)target; + storeValue(cUnit, rlDest, rlResult); } LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, - int src2, LIR* target) + int src2, LIR* target) { - LIR* branch; - MipsOpCode sltOp; - MipsOpCode brOp; - bool cmpZero = false; - bool swapped = false; - switch (cond) { - case kCondEq: - brOp = kMipsBeq; - cmpZero = true; - break; - case kCondNe: - brOp = kMipsBne; - cmpZero = true; - break; - case kCondCc: - sltOp = kMipsSltu; - brOp = kMipsBnez; - break; - case kCondCs: - sltOp = kMipsSltu; - brOp = kMipsBeqz; - 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; - case kCondHi: // Gtu - sltOp = kMipsSltu; - brOp = kMipsBnez; - swapped = true; - break; - default: - LOG(FATAL) << "No support for ConditionCode: " << (int) cond; - return NULL; - } - if (cmpZero) { - branch = newLIR2(cUnit, brOp, src1, src2); + LIR* branch; + MipsOpCode sltOp; + MipsOpCode brOp; + bool cmpZero = false; + bool swapped = false; + switch (cond) { + case kCondEq: + brOp = kMipsBeq; + cmpZero = true; + break; + case kCondNe: + brOp = kMipsBne; + cmpZero = true; + break; + case kCondCc: + sltOp = kMipsSltu; + brOp = kMipsBnez; + break; + case kCondCs: + sltOp = kMipsSltu; + brOp = kMipsBeqz; + 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; + case kCondHi: // Gtu + sltOp = kMipsSltu; + brOp = kMipsBnez; + swapped = true; + break; + default: + LOG(FATAL) << "No support for ConditionCode: " << (int) cond; + return NULL; + } + if (cmpZero) { + branch = newLIR2(cUnit, brOp, src1, src2); + } else { + int tReg = oatAllocTemp(cUnit); + if (swapped) { + newLIR3(cUnit, sltOp, tReg, src2, src1); } else { - int tReg = oatAllocTemp(cUnit); - if (swapped) { - newLIR3(cUnit, sltOp, tReg, src2, src1); - } else { - newLIR3(cUnit, sltOp, tReg, src1, src2); - } - branch = newLIR1(cUnit, brOp, tReg); - oatFreeTemp(cUnit, tReg); + newLIR3(cUnit, sltOp, tReg, src1, src2); } - branch->target = target; - return branch; + branch = newLIR1(cUnit, brOp, tReg); + oatFreeTemp(cUnit, tReg); + } + branch->target = target; + return branch; } LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, - int checkValue, LIR* target) + 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); - branch = opCmpBranch(cUnit, cond, reg, tReg, target); - oatFreeTemp(cUnit, tReg); - return branch; - } - MipsOpCode opc; - switch (cond) { - case kCondEq: opc = kMipsBeqz; break; - case kCondGe: opc = kMipsBgez; break; - case kCondGt: opc = kMipsBgtz; break; - case kCondLe: opc = kMipsBlez; break; - //case KCondMi: - case kCondLt: opc = kMipsBltz; break; - case kCondNe: opc = kMipsBnez; break; - default: - // Tuning: use slti when applicable - int tReg = oatAllocTemp(cUnit); - loadConstant(cUnit, tReg, checkValue); - branch = opCmpBranch(cUnit, cond, reg, tReg, target); - oatFreeTemp(cUnit, tReg); - return branch; - } - branch = newLIR1(cUnit, opc, reg); - branch->target = target; + LIR* branch; + if (checkValue != 0) { + // TUNING: handle s16 & kCondLt/Mi case using slti + int tReg = oatAllocTemp(cUnit); + loadConstant(cUnit, tReg, checkValue); + branch = opCmpBranch(cUnit, cond, reg, tReg, target); + oatFreeTemp(cUnit, tReg); return branch; + } + MipsOpCode opc; + switch (cond) { + case kCondEq: opc = kMipsBeqz; break; + case kCondGe: opc = kMipsBgez; break; + case kCondGt: opc = kMipsBgtz; break; + case kCondLe: opc = kMipsBlez; break; + //case KCondMi: + case kCondLt: opc = kMipsBltz; break; + case kCondNe: opc = kMipsBnez; break; + default: + // Tuning: use slti when applicable + int tReg = oatAllocTemp(cUnit); + loadConstant(cUnit, tReg, checkValue); + branch = opCmpBranch(cUnit, cond, reg, tReg, target); + oatFreeTemp(cUnit, tReg); + return branch; + } + branch = newLIR1(cUnit, opc, reg); + branch->target = target; + return branch; } LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) { #ifdef __mips_hard_float - if (FPREG(rDest) || FPREG(rSrc)) - return fpRegCopy(cUnit, rDest, rSrc); + if (FPREG(rDest) || FPREG(rSrc)) + return fpRegCopy(cUnit, rDest, rSrc); #endif - LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kMipsMove, - rDest, rSrc); - if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) { - res->flags.isNop = true; - } - return res; + LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kMipsMove, + rDest, rSrc); + if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) { + res->flags.isNop = true; + } + return res; } LIR* opRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) { - LIR *res = opRegCopyNoInsert(cUnit, rDest, rSrc); - oatAppendLIR(cUnit, (LIR*)res); - return res; + LIR *res = opRegCopyNoInsert(cUnit, rDest, rSrc); + oatAppendLIR(cUnit, (LIR*)res); + return res; } void opRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi, - int srcLo, int srcHi) + int srcLo, int srcHi) { #ifdef __mips_hard_float - bool destFP = FPREG(destLo) && FPREG(destHi); - bool srcFP = FPREG(srcLo) && FPREG(srcHi); - assert(FPREG(srcLo) == FPREG(srcHi)); - assert(FPREG(destLo) == FPREG(destHi)); - if (destFP) { - if (srcFP) { - opRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); - } else { - /* note the operands are swapped for the mtc1 instr */ - newLIR2(cUnit, kMipsMtc1, srcLo, destLo); - newLIR2(cUnit, kMipsMtc1, srcHi, destHi); - } + bool destFP = FPREG(destLo) && FPREG(destHi); + bool srcFP = FPREG(srcLo) && FPREG(srcHi); + assert(FPREG(srcLo) == FPREG(srcHi)); + assert(FPREG(destLo) == FPREG(destHi)); + if (destFP) { + if (srcFP) { + opRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); } else { - if (srcFP) { - newLIR2(cUnit, kMipsMfc1, destLo, srcLo); - newLIR2(cUnit, kMipsMfc1, destHi, srcHi); - } else { - // Handle overlap - if (srcHi == destLo) { - opRegCopy(cUnit, destHi, srcHi); - opRegCopy(cUnit, destLo, srcLo); - } else { - opRegCopy(cUnit, destLo, srcLo); - opRegCopy(cUnit, destHi, srcHi); - } - } + /* note the operands are swapped for the mtc1 instr */ + newLIR2(cUnit, kMipsMtc1, srcLo, destLo); + newLIR2(cUnit, kMipsMtc1, srcHi, destHi); } -#else - // Handle overlap - if (srcHi == destLo) { + } else { + if (srcFP) { + newLIR2(cUnit, kMipsMfc1, destLo, srcLo); + newLIR2(cUnit, kMipsMfc1, destHi, srcHi); + } else { + // Handle overlap + if (srcHi == destLo) { opRegCopy(cUnit, destHi, srcHi); opRegCopy(cUnit, destLo, srcLo); - } else { + } else { opRegCopy(cUnit, destLo, srcLo); opRegCopy(cUnit, destHi, srcHi); + } } + } +#else + // Handle overlap + if (srcHi == destLo) { + opRegCopy(cUnit, destHi, srcHi); + opRegCopy(cUnit, destLo, srcLo); + } else { + opRegCopy(cUnit, destLo, srcLo); + opRegCopy(cUnit, destHi, srcHi); + } #endif } diff --git a/src/compiler/codegen/mips/Mips32/Ralloc.cc b/src/compiler/codegen/mips/Mips32/Ralloc.cc index f8440a45da..9f392124ee 100644 --- a/src/compiler/codegen/mips/Mips32/Ralloc.cc +++ b/src/compiler/codegen/mips/Mips32/Ralloc.cc @@ -29,107 +29,107 @@ namespace art { * high reg in next byte. */ int oatAllocTypedTempPair(CompilationUnit *cUnit, bool fpHint, - int regClass) + int regClass) { - int highReg; - int lowReg; - int res = 0; + int highReg; + int lowReg; + int res = 0; #ifdef __mips_hard_float - if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) { - lowReg = oatAllocTempDouble(cUnit); - highReg = lowReg + 1; - res = (lowReg & 0xff) | ((highReg & 0xff) << 8); - return res; - } -#endif - - lowReg = oatAllocTemp(cUnit); - highReg = oatAllocTemp(cUnit); + if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) { + lowReg = oatAllocTempDouble(cUnit); + highReg = lowReg + 1; res = (lowReg & 0xff) | ((highReg & 0xff) << 8); return res; + } +#endif + + lowReg = oatAllocTemp(cUnit); + highReg = oatAllocTemp(cUnit); + res = (lowReg & 0xff) | ((highReg & 0xff) << 8); + return res; } int oatAllocTypedTemp(CompilationUnit *cUnit, bool fpHint, int regClass) { #ifdef __mips_hard_float - if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) + if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) { - return oatAllocTempFloat(cUnit); + return oatAllocTempFloat(cUnit); } #endif - return oatAllocTemp(cUnit); + return oatAllocTemp(cUnit); } void oatInitializeRegAlloc(CompilationUnit* cUnit) { - int numRegs = sizeof(coreRegs)/sizeof(*coreRegs); - int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs); - int numTemps = sizeof(coreTemps)/sizeof(*coreTemps); + int numRegs = sizeof(coreRegs)/sizeof(*coreRegs); + int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs); + int numTemps = sizeof(coreTemps)/sizeof(*coreTemps); #ifdef __mips_hard_float - int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs); - int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps); + int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs); + int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps); #else - int numFPRegs = 0; - int numFPTemps = 0; + int numFPRegs = 0; + int numFPTemps = 0; #endif - RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true, - kAllocRegAlloc); - cUnit->regPool = pool; - pool->numCoreRegs = numRegs; - pool->coreRegs = (RegisterInfo *) - oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs), - true, kAllocRegAlloc); - pool->numFPRegs = numFPRegs; - pool->FPRegs = (RegisterInfo *) - oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true, - kAllocRegAlloc); - oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs); - 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)) { - //To measure cost of suspend check - continue; - } - oatMarkInUse(cUnit, reservedRegs[i]); + RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true, + kAllocRegAlloc); + cUnit->regPool = pool; + pool->numCoreRegs = numRegs; + pool->coreRegs = (RegisterInfo *) + oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs), + true, kAllocRegAlloc); + pool->numFPRegs = numFPRegs; + pool->FPRegs = (RegisterInfo *) + oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true, + kAllocRegAlloc); + oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs); + 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)) { + //To measure cost of suspend check + continue; } - // Mark temp regs - all others not in use can be used for promotion - for (int i = 0; i < numTemps; i++) { - oatMarkTemp(cUnit, coreTemps[i]); - } - for (int i = 0; i < numFPTemps; i++) { - oatMarkTemp(cUnit, fpTemps[i]); - } - // Construct the alias map. - cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs * - sizeof(cUnit->phiAliasMap[0]), false, - kAllocDFInfo); - for (int i = 0; i < cUnit->numSSARegs; i++) { - cUnit->phiAliasMap[i] = i; - } - for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) { - int defReg = phi->ssaRep->defs[0]; - for (int i = 0; i < phi->ssaRep->numUses; i++) { - for (int j = 0; j < cUnit->numSSARegs; j++) { - if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) { - cUnit->phiAliasMap[j] = defReg; - } - } - } + oatMarkInUse(cUnit, reservedRegs[i]); + } + // Mark temp regs - all others not in use can be used for promotion + for (int i = 0; i < numTemps; i++) { + oatMarkTemp(cUnit, coreTemps[i]); + } + for (int i = 0; i < numFPTemps; i++) { + oatMarkTemp(cUnit, fpTemps[i]); + } + // Construct the alias map. + cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs * + sizeof(cUnit->phiAliasMap[0]), false, + kAllocDFInfo); + for (int i = 0; i < cUnit->numSSARegs; i++) { + cUnit->phiAliasMap[i] = i; + } + for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) { + int defReg = phi->ssaRep->defs[0]; + for (int i = 0; i < phi->ssaRep->numUses; i++) { + for (int j = 0; j < cUnit->numSSARegs; j++) { + if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) { + cUnit->phiAliasMap[j] = defReg; + } + } } + } } void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, - RegLocation rlFree) + RegLocation rlFree) { - if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) && - (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) { - // No overlap, free both - oatFreeTemp(cUnit, rlFree.lowReg); - oatFreeTemp(cUnit, rlFree.highReg); - } + if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) && + (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) { + // No overlap, free both + oatFreeTemp(cUnit, rlFree.lowReg); + oatFreeTemp(cUnit, rlFree.highReg); + } } diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h index c0ff298326..ac222c456f 100644 --- a/src/compiler/codegen/mips/MipsLIR.h +++ b/src/compiler/codegen/mips/MipsLIR.h @@ -146,33 +146,33 @@ namespace art { /* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */ #define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, r_V0, INVALID_REG, \ - INVALID_SREG} + INVALID_SREG} #define LOC_C_RETURN_FLOAT LOC_C_RETURN #define LOC_C_RETURN_ALT {kLocPhysReg, 0, 0, 0, 0, 0, 1, r_F0, INVALID_REG, \ - INVALID_SREG} + INVALID_SREG} #define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_RESULT0, r_RESULT1,\ - INVALID_SREG} + INVALID_SREG} #define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE #define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_FRESULT0,\ - r_FRESULT1, INVALID_SREG} + r_FRESULT1, INVALID_SREG} enum ResourceEncodingPos { - kGPReg0 = 0, - kRegSP = 29, - kRegLR = 31, - kFPReg0 = 32, /* only 16 fp regs supported currently */ - kFPRegEnd = 48, - kRegHI = kFPRegEnd, - kRegLO, - kRegPC, - kRegEnd = 51, - kCCode = kRegEnd, - kFPStatus, // FP status word - // The following four bits are for memory disambiguation - kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) - kLiteral, // 2 Literal pool (can be fully disambiguated) - kHeapRef, // 3 Somewhere on the heap (alias with any other heap) - kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) + kGPReg0 = 0, + kRegSP = 29, + kRegLR = 31, + kFPReg0 = 32, /* only 16 fp regs supported currently */ + kFPRegEnd = 48, + kRegHI = kFPRegEnd, + kRegLO, + kRegPC, + kRegEnd = 51, + kCCode = kRegEnd, + kFPStatus, // FP status word + // The following four bits are for memory disambiguation + kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated) + kLiteral, // 2 Literal pool (can be fully disambiguated) + kHeapRef, // 3 Somewhere on the heap (alias with any other heap) + kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x)) }; #define ENCODE_REG_LIST(N) ((u8) N) @@ -190,7 +190,7 @@ enum ResourceEncodingPos { #define ENCODE_ALL (~0ULL) #define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \ - ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) + ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS) #define DECODE_ALIAS_INFO_REG(X) (X & 0xffff) #define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0) @@ -200,94 +200,94 @@ enum ResourceEncodingPos { */ enum NativeRegisterPool { - r_ZERO = 0, - r_AT = 1, - r_V0 = 2, - r_V1 = 3, - r_A0 = 4, - r_A1 = 5, - r_A2 = 6, - r_A3 = 7, - r_T0 = 8, - r_T1 = 9, - r_T2 = 10, - r_T3 = 11, - r_T4 = 12, - r_T5 = 13, - r_T6 = 14, - r_T7 = 15, - r_S0 = 16, - r_S1 = 17, - r_S2 = 18, - r_S3 = 19, - r_S4 = 20, - r_S5 = 21, - r_S6 = 22, - r_S7 = 23, - r_T8 = 24, - r_T9 = 25, - r_K0 = 26, - r_K1 = 27, - r_GP = 28, - r_SP = 29, - r_FP = 30, - r_RA = 31, - - r_F0 = 0 + FP_REG_OFFSET, - r_F1, - r_F2, - r_F3, - r_F4, - r_F5, - r_F6, - r_F7, - r_F8, - r_F9, - r_F10, - r_F11, - r_F12, - r_F13, - r_F14, - r_F15, + r_ZERO = 0, + r_AT = 1, + r_V0 = 2, + r_V1 = 3, + r_A0 = 4, + r_A1 = 5, + r_A2 = 6, + r_A3 = 7, + r_T0 = 8, + r_T1 = 9, + r_T2 = 10, + r_T3 = 11, + r_T4 = 12, + r_T5 = 13, + r_T6 = 14, + r_T7 = 15, + r_S0 = 16, + r_S1 = 17, + r_S2 = 18, + r_S3 = 19, + r_S4 = 20, + r_S5 = 21, + r_S6 = 22, + r_S7 = 23, + r_T8 = 24, + r_T9 = 25, + r_K0 = 26, + r_K1 = 27, + r_GP = 28, + r_SP = 29, + r_FP = 30, + r_RA = 31, + + r_F0 = 0 + FP_REG_OFFSET, + r_F1, + r_F2, + r_F3, + r_F4, + r_F5, + r_F6, + r_F7, + r_F8, + r_F9, + r_F10, + r_F11, + r_F12, + r_F13, + r_F14, + r_F15, #if 0 /* only 16 fp regs supported currently */ - r_F16, - r_F17, - r_F18, - r_F19, - r_F20, - r_F21, - r_F22, - r_F23, - r_F24, - r_F25, - r_F26, - r_F27, - r_F28, - r_F29, - r_F30, - r_F31, + r_F16, + r_F17, + r_F18, + r_F19, + r_F20, + r_F21, + r_F22, + r_F23, + r_F24, + r_F25, + r_F26, + r_F27, + r_F28, + r_F29, + r_F30, + r_F31, #endif - r_DF0 = r_F0 + FP_DOUBLE, - r_DF1 = r_F2 + FP_DOUBLE, - r_DF2 = r_F4 + FP_DOUBLE, - r_DF3 = r_F6 + FP_DOUBLE, - r_DF4 = r_F8 + FP_DOUBLE, - r_DF5 = r_F10 + FP_DOUBLE, - r_DF6 = r_F12 + FP_DOUBLE, - r_DF7 = r_F14 + FP_DOUBLE, + r_DF0 = r_F0 + FP_DOUBLE, + r_DF1 = r_F2 + FP_DOUBLE, + r_DF2 = r_F4 + FP_DOUBLE, + r_DF3 = r_F6 + FP_DOUBLE, + r_DF4 = r_F8 + FP_DOUBLE, + r_DF5 = r_F10 + FP_DOUBLE, + r_DF6 = r_F12 + FP_DOUBLE, + r_DF7 = r_F14 + FP_DOUBLE, #if 0 /* only 16 fp regs supported currently */ - r_DF8 = r_F16 + FP_DOUBLE, - r_DF9 = r_F18 + FP_DOUBLE, - r_DF10 = r_F20 + FP_DOUBLE, - r_DF11 = r_F22 + FP_DOUBLE, - r_DF12 = r_F24 + FP_DOUBLE, - r_DF13 = r_F26 + FP_DOUBLE, - r_DF14 = r_F28 + FP_DOUBLE, - r_DF15 = r_F30 + FP_DOUBLE, + r_DF8 = r_F16 + FP_DOUBLE, + r_DF9 = r_F18 + FP_DOUBLE, + r_DF10 = r_F20 + FP_DOUBLE, + r_DF11 = r_F22 + FP_DOUBLE, + r_DF12 = r_F24 + FP_DOUBLE, + r_DF13 = r_F26 + FP_DOUBLE, + r_DF14 = r_F28 + FP_DOUBLE, + r_DF15 = r_F30 + FP_DOUBLE, #endif - r_HI = EXTRA_REG_OFFSET, - r_LO, - r_PC, + r_HI = EXTRA_REG_OFFSET, + r_LO, + r_PC, }; /* @@ -307,10 +307,10 @@ enum NativeRegisterPool { /* Shift encodings */ enum MipsShiftEncodings { - kMipsLsl = 0x0, - kMipsLsr = 0x1, - kMipsAsr = 0x2, - kMipsRor = 0x3 + kMipsLsl = 0x0, + kMipsLsr = 0x1, + kMipsAsr = 0x2, + kMipsRor = 0x3 }; // MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist) @@ -333,148 +333,148 @@ enum MipsShiftEncodings { * Assemble.cc. */ enum MipsOpCode { - 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, - - kMipsFirst, - kMips32BitData = kMipsFirst, /* data [31..0] */ - kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */ - kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */ - kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */ - kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */ - kMipsB, /* b o [0001000000000000] o[15..0] */ - kMipsBal, /* bal o [0000010000010001] o[15..0] */ - /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so - adding an instruction in this range may require updates */ - kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */ - kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */ - kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */ - kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */ - kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */ - kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */ - kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */ - kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */ - kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */ + 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, + + kMipsFirst, + kMips32BitData = kMipsFirst, /* data [31..0] */ + kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */ + kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */ + kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */ + kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */ + kMipsB, /* b o [0001000000000000] o[15..0] */ + kMipsBal, /* bal o [0000010000010001] o[15..0] */ + /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so + adding an instruction in this range may require updates */ + kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */ + kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */ + kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */ + kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */ + kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */ + kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */ + kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */ + kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */ + kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */ #if __mips_isa_rev>=2 - kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */ + kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */ #endif - kMipsJal, /* jal t [000011] t[25..0] */ - kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11] - hint[10..6] [001001] */ - kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */ - kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */ - kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */ - kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */ - kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */ - kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */ - kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */ - kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */ - kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */ - kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */ - kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */ - kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */ - kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */ - kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */ - kMipsNop, /* nop [00000000000000000000000000000000] */ - kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */ - kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */ - kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */ - kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */ - kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */ + kMipsJal, /* jal t [000011] t[25..0] */ + kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11] + hint[10..6] [001001] */ + kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */ + kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */ + kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */ + kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */ + kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */ + kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */ + kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */ + kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */ + kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */ + kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */ + kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */ + kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */ + kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */ + kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */ + kMipsNop, /* nop [00000000000000000000000000000000] */ + kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */ + kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */ + kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */ + kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */ + kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */ #if __mips_isa_rev>=2 - kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */ - kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */ + kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */ + kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */ #endif - kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */ - kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */ - kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */ - kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */ - kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */ - kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */ - kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */ - kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */ - kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */ - kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */ - kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */ - kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */ - kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */ - kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */ + kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */ + kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */ + kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */ + kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */ + kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */ + kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */ + kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */ + kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */ + kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */ + kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */ + kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */ + kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */ + kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */ + kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */ #ifdef __mips_hard_float - kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */ - kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */ - kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */ - kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */ - kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */ - kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */ - kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */ - kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */ - kMipsFcvtsd, /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */ - kMipsFcvtsw, /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */ - kMipsFcvtds, /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */ - kMipsFcvtdw, /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */ - kMipsFcvtws, /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */ - kMipsFcvtwd, /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */ - kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */ - kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */ - kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */ - kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */ - kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */ - kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */ - kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */ - kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */ + kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */ + kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */ + kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */ + kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */ + kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */ + kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */ + kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */ + kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */ + kMipsFcvtsd,/* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */ + kMipsFcvtsw,/* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */ + kMipsFcvtds,/* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */ + kMipsFcvtdw,/* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */ + kMipsFcvtws,/* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */ + kMipsFcvtwd,/* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */ + kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */ + kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */ + kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */ + kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */ + kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */ + kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */ + kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */ + kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */ #endif - kMipsDelta, /* Psuedo for ori t, s,