Fix endianness of compiled code and stacks of stubs for MIPS.
The gtests now all work on MIPS.
Change-Id: I2883ce002f23d75e700366014517c863fb626d09
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 6868d0b..d948d2d 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -1784,13 +1784,11 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 25e13d7..8c906cc 100644
--- a/src/compiler/codegen/mips/Assemble.cc
+++ b/src/compiler/codegen/mips/Assemble.cc
@@ -691,19 +691,19 @@
<< (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 0f6226f..ab4f844 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -147,14 +147,12 @@
/* 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 43fcc07..bd9f97e 100644
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ b/src/compiler/codegen/mips/MipsRallocUtil.cc
@@ -138,20 +138,15 @@
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;
}