diff options
author | 2012-10-02 18:10:35 -0700 | |
---|---|---|
committer | 2012-10-03 13:34:43 -0700 | |
commit | 4f8f04ad94e68d2307a955d6bd72415fc0852725 (patch) | |
tree | f4c7f58a5149667b5f8e3376064faa81f5b9842e | |
parent | 3e96a16c27c986275f60afe682d0b2a3064f45c9 (diff) |
Fix endianness of compiled code and stacks of stubs for MIPS.
The gtests now all work on MIPS.
Change-Id: I2883ce002f23d75e700366014517c863fb626d09
-rw-r--r-- | src/compiler/codegen/GenCommon.cc | 61 | ||||
-rw-r--r-- | src/compiler/codegen/mips/Assemble.cc | 14 | ||||
-rw-r--r-- | src/compiler/codegen/mips/MipsLIR.h | 10 | ||||
-rw-r--r-- | src/compiler/codegen/mips/MipsRallocUtil.cc | 13 | ||||
-rw-r--r-- | src/disassembler_mips.cc | 5 | ||||
-rw-r--r-- | src/oat/runtime/mips/stub_mips.cc | 63 |
6 files changed, 86 insertions, 80 deletions
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc index 6868d0bc9a..d948d2d8f2 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -1784,13 +1784,11 @@ bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation RegLocation rlSrc1, RegLocation rlSrc2) { OpKind op = kOpBkpt; - bool callOut = false; + bool isDivRem = false; bool checkZero = false; bool unary = false; RegLocation rlResult; bool shiftOp = false; - int funcOffset; - int retReg = rRET0; switch (opcode) { case Instruction::NEG_INT: op = kOpNeg; @@ -1816,18 +1814,14 @@ bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation case Instruction::DIV_INT_2ADDR: checkZero = true; op = kOpDiv; - callOut = true; - funcOffset = ENTRYPOINT_OFFSET(pIdivmod); - retReg = rRET0; + isDivRem = true; break; /* NOTE: returns in rARG1 */ case Instruction::REM_INT: case Instruction::REM_INT_2ADDR: checkZero = true; op = kOpRem; - callOut = true; - funcOffset = ENTRYPOINT_OFFSET(pIdivmod); - retReg = rRET1; + isDivRem = true; break; case Instruction::AND_INT: case Instruction::AND_INT_2ADDR: @@ -1860,7 +1854,7 @@ bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation LOG(FATAL) << "Invalid word arith op: " << (int)opcode; } - if (!callOut) { + if (!isDivRem) { if (unary) { rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg); rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); @@ -1889,10 +1883,24 @@ bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation } storeValue(cUnit, rlDest, rlResult); } else { +#if defined(TARGET_MIPS) + rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg); + if (checkZero) { + genNullCheck(cUnit, rlSrc2.sRegLow, rlSrc2.lowReg, 0); + } + newLIR4(cUnit, kMipsDiv, r_HI, r_LO, rlSrc1.lowReg, rlSrc2.lowReg); + rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + if (op == kOpDiv) { + newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO); + } else { + newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI); + } +#else + int funcOffset = ENTRYPOINT_OFFSET(pIdivmod); RegLocation rlResult; oatFlushAllRegs(cUnit); /* Send everything to home location */ loadValueDirectFixed(cUnit, rlSrc2, rARG1); -#if !defined(TARGET_X86) +#if defined(TARGET_ARM) int rTgt = loadHelper(cUnit, funcOffset); #endif loadValueDirectFixed(cUnit, rlSrc1, rARG0); @@ -1900,17 +1908,18 @@ bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation genImmedCheck(cUnit, kCondEq, rARG1, 0, kThrowDivZero); } // NOTE: callout here is not a safepoint -#if !defined(TARGET_X86) +#if defined(TARGET_ARM) opReg(cUnit, kOpBlx, rTgt); oatFreeTemp(cUnit, rTgt); #else opThreadMem(cUnit, kOpBlx, funcOffset); #endif - if (retReg == rRET0) + if (op == kOpDiv) rlResult = oatGetReturn(cUnit, false); else rlResult = oatGetReturnAlt(cUnit); storeValue(cUnit, rlDest, rlResult); +#endif } return false; } @@ -2077,7 +2086,6 @@ bool genArithOpIntLit(CompilationUnit* cUnit, Instruction::Code opcode, OpKind op = (OpKind)0; /* Make gcc happy */ int shiftOp = false; bool isDiv = false; - int funcOffset; switch (opcode) { case Instruction::RSUB_INT_LIT8: @@ -2140,7 +2148,7 @@ bool genArithOpIntLit(CompilationUnit* cUnit, Instruction::Code opcode, case Instruction::DIV_INT_LIT8: case Instruction::DIV_INT_LIT16: case Instruction::REM_INT_LIT8: - case Instruction::REM_INT_LIT16: + case Instruction::REM_INT_LIT16: { if (lit == 0) { genImmedCheck(cUnit, kCondAl, 0, 0, kThrowDivZero); return false; @@ -2148,24 +2156,39 @@ bool genArithOpIntLit(CompilationUnit* cUnit, Instruction::Code opcode, if (handleEasyDivide(cUnit, opcode, rlSrc, rlDest, lit)) { return false; } - oatFlushAllRegs(cUnit); /* Everything to home location */ - loadValueDirectFixed(cUnit, rlSrc, rARG0); - oatClobber(cUnit, rARG0); - funcOffset = ENTRYPOINT_OFFSET(pIdivmod); if ((opcode == Instruction::DIV_INT_LIT8) || (opcode == Instruction::DIV_INT_LIT16)) { isDiv = true; } else { isDiv = false; } +#if defined(TARGET_MIPS) + rlSrc = loadValue(cUnit, rlSrc, kCoreReg); + int tReg = oatAllocTemp(cUnit); + newLIR3(cUnit, kMipsAddiu, tReg, r_ZERO, lit); + newLIR4(cUnit, kMipsDiv, r_HI, r_LO, rlSrc.lowReg, tReg); + rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + if (isDiv) { + newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO); + } else { + newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI); + } + oatFreeTemp(cUnit, tReg); +#else + oatFlushAllRegs(cUnit); /* Everything to home location */ + loadValueDirectFixed(cUnit, rlSrc, rARG0); + oatClobber(cUnit, rARG0); + int funcOffset = ENTRYPOINT_OFFSET(pIdivmod); callRuntimeHelperRegImm(cUnit, funcOffset, rARG0, lit, false); if (isDiv) rlResult = oatGetReturn(cUnit, false); else rlResult = oatGetReturnAlt(cUnit); +#endif storeValue(cUnit, rlDest, rlResult); return false; break; + } default: return true; } diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc index 25e13d7d8f..8c906ccdb3 100644 --- a/src/compiler/codegen/mips/Assemble.cc +++ b/src/compiler/codegen/mips/Assemble.cc @@ -691,19 +691,19 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, << (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); + // We only support little-endian MIPS. cUnit->codeBuffer.push_back(bits & 0xff); + cUnit->codeBuffer.push_back((bits >> 8) & 0xff); + cUnit->codeBuffer.push_back((bits >> 16) & 0xff); + cUnit->codeBuffer.push_back((bits >> 24) & 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); + cUnit->codeBuffer.push_back((bits >> 8) & 0xff); + cUnit->codeBuffer.push_back((bits >> 16) & 0xff); + cUnit->codeBuffer.push_back((bits >> 24) & 0xff); } } return res; diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h index 0f6226f963..ab4f844dba 100644 --- a/src/compiler/codegen/mips/MipsLIR.h +++ b/src/compiler/codegen/mips/MipsLIR.h @@ -147,14 +147,12 @@ namespace art { /* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */ #define LOC_C_RETURN {kLocPhysReg, 0, 0, 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, 0, 0, 1, r_V1, \ - INVALID_REG, INVALID_SREG, INVALID_SREG} +#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0, \ + INVALID_REG, INVALID_SREG, INVALID_SREG} #define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 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, 0, 0, 1, r_FRESULT0,\ - r_FRESULT1, INVALID_SREG, INVALID_SREG} +#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0,\ + r_FRESULT1, INVALID_SREG, INVALID_SREG} enum ResourceEncodingPos { kGPReg0 = 0, diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc index 43fcc071d9..bd9f97eb6f 100644 --- a/src/compiler/codegen/mips/MipsRallocUtil.cc +++ b/src/compiler/codegen/mips/MipsRallocUtil.cc @@ -138,20 +138,15 @@ extern void oatClobberCalleeSave(CompilationUnit *cUnit) extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit) { - RegLocation res = LOC_C_RETURN_WIDE_ALT; - oatClobber(cUnit, res.lowReg); - oatClobber(cUnit, res.highReg); - oatMarkInUse(cUnit, res.lowReg); - oatMarkInUse(cUnit, res.highReg); - oatMarkPair(cUnit, res.lowReg, res.highReg); + UNIMPLEMENTED(FATAL) << "No oatGetReturnWideAlt for MIPS"; + RegLocation res = LOC_C_RETURN_WIDE; return res; } extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit) { - RegLocation res = LOC_C_RETURN_ALT; - oatClobber(cUnit, res.lowReg); - oatMarkInUse(cUnit, res.lowReg); + UNIMPLEMENTED(FATAL) << "No oatGetReturnAlt for MIPS"; + RegLocation res = LOC_C_RETURN; return res; } diff --git a/src/disassembler_mips.cc b/src/disassembler_mips.cc index f7d755a8de..ca9f6d7ca7 100644 --- a/src/disassembler_mips.cc +++ b/src/disassembler_mips.cc @@ -164,9 +164,8 @@ static const MipsInstruction gMipsInstructions[] = { }; static uint32_t ReadU32(const uint8_t* ptr) { - // TODO: MIPS is bi. how do we handle that? - return ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); - //return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); + // We only support little-endian MIPS. + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); } static void DumpMips(std::ostream& os, const uint8_t* instr_ptr) { diff --git a/src/oat/runtime/mips/stub_mips.cc b/src/oat/runtime/mips/stub_mips.cc index 4865c5912e..7b4c85ee80 100644 --- a/src/oat/runtime/mips/stub_mips.cc +++ b/src/oat/runtime/mips/stub_mips.cc @@ -41,19 +41,16 @@ ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) { // Save callee saves and ready frame for exception delivery __ AddConstant(SP, SP, -64); __ StoreToOffset(kStoreWord, RA, SP, 60); - __ StoreToOffset(kStoreWord, T9, SP, 56); - __ StoreToOffset(kStoreWord, T8, SP, 52); - __ StoreToOffset(kStoreWord, T7, SP, 48); - __ StoreToOffset(kStoreWord, T6, SP, 44); - __ StoreToOffset(kStoreWord, T5, SP, 40); - __ StoreToOffset(kStoreWord, T4, SP, 36); - __ StoreToOffset(kStoreWord, T3, SP, 32); - __ StoreToOffset(kStoreWord, T2, SP, 28); - __ StoreToOffset(kStoreWord, T1, SP, 24); - __ StoreToOffset(kStoreWord, T0, SP, 20); - __ StoreToOffset(kStoreWord, A3, SP, 16); - __ StoreToOffset(kStoreWord, A2, SP, 12); - __ StoreToOffset(kStoreWord, A1, SP, 8); + __ StoreToOffset(kStoreWord, FP, SP, 56); + __ StoreToOffset(kStoreWord, S7, SP, 52); + __ StoreToOffset(kStoreWord, S6, SP, 48); + __ StoreToOffset(kStoreWord, S5, SP, 44); + __ StoreToOffset(kStoreWord, S4, SP, 40); + __ StoreToOffset(kStoreWord, S3, SP, 36); + __ StoreToOffset(kStoreWord, S2, SP, 32); + __ StoreToOffset(kStoreWord, A3, SP, 28); + __ StoreToOffset(kStoreWord, A2, SP, 24); + __ StoreToOffset(kStoreWord, A1, SP, 20); __ LoadFromOffset(kLoadWord, T9, S1, ENTRYPOINT_OFFSET(pUnresolvedDirectMethodTrampolineFromCode)); @@ -63,19 +60,16 @@ ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) { __ Jalr(T9); // Call to unresolved direct method trampoline (method_idx, sp, Thread*, is_static) // Restore registers which may have been modified by GC - __ LoadFromOffset(kLoadWord, A1, SP, 8); - __ LoadFromOffset(kLoadWord, A2, SP, 12); - __ LoadFromOffset(kLoadWord, A3, SP, 16); - __ LoadFromOffset(kLoadWord, T0, SP, 20); - __ LoadFromOffset(kLoadWord, T1, SP, 24); - __ LoadFromOffset(kLoadWord, T2, SP, 28); - __ LoadFromOffset(kLoadWord, T3, SP, 32); - __ LoadFromOffset(kLoadWord, T4, SP, 36); - __ LoadFromOffset(kLoadWord, T5, SP, 40); - __ LoadFromOffset(kLoadWord, T6, SP, 44); - __ LoadFromOffset(kLoadWord, T7, SP, 48); - __ LoadFromOffset(kLoadWord, T8, SP, 52); - __ LoadFromOffset(kLoadWord, T9, SP, 56); + __ LoadFromOffset(kLoadWord, A1, SP, 20); + __ LoadFromOffset(kLoadWord, A2, SP, 24); + __ LoadFromOffset(kLoadWord, A3, SP, 28); + __ LoadFromOffset(kLoadWord, S2, SP, 32); + __ LoadFromOffset(kLoadWord, S3, SP, 36); + __ LoadFromOffset(kLoadWord, S4, SP, 40); + __ LoadFromOffset(kLoadWord, S5, SP, 44); + __ LoadFromOffset(kLoadWord, S6, SP, 48); + __ LoadFromOffset(kLoadWord, S7, SP, 52); + __ LoadFromOffset(kLoadWord, FP, SP, 56); __ LoadFromOffset(kLoadWord, RA, SP, 60); __ AddConstant(SP, SP, 64); @@ -133,16 +127,13 @@ ByteArray* CreateAbstractMethodErrorStub() { // Save callee saves and ready frame for exception delivery __ AddConstant(SP, SP, -48); __ StoreToOffset(kStoreWord, RA, SP, 44); - __ StoreToOffset(kStoreWord, T9, SP, 40); - __ StoreToOffset(kStoreWord, T8, SP, 36); - __ StoreToOffset(kStoreWord, T7, SP, 32); - __ StoreToOffset(kStoreWord, T6, SP, 28); - __ StoreToOffset(kStoreWord, T5, SP, 24); - __ StoreToOffset(kStoreWord, T4, SP, 20); - __ StoreToOffset(kStoreWord, T3, SP, 16); - __ StoreToOffset(kStoreWord, T2, SP, 12); - __ StoreToOffset(kStoreWord, T1, SP, 8); - __ StoreToOffset(kStoreWord, T0, SP, 4); + __ StoreToOffset(kStoreWord, FP, SP, 40); + __ StoreToOffset(kStoreWord, S7, SP, 36); + __ StoreToOffset(kStoreWord, S6, SP, 32); + __ StoreToOffset(kStoreWord, S5, SP, 28); + __ StoreToOffset(kStoreWord, S4, SP, 24); + __ StoreToOffset(kStoreWord, S3, SP, 20); + __ StoreToOffset(kStoreWord, S2, SP, 16); // A0 is the Method* already __ Move(A1, S1); // Pass Thread::Current() in A1 |