Enable all JNI internal compiler tests on the host.
(cherry picked from commit abda43c90f70963909128c1cc495190d60fd8372)
Change-Id: I0a7fc96e84dacf34108551271760aae13d5ee010
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 72a596a..aee5b50 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -248,7 +248,7 @@
loadConstant(cUnit, rARG0, type_idx); // arg0 <- type_id
loadValueDirectFixed(cUnit, rlSrc, rARG2); // arg2 <- count
callRuntimeHelper(cUnit, rTgt);
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
}
@@ -567,10 +567,10 @@
loadConstant(cUnit, rARG0, fieldIdx);
callRuntimeHelper(cUnit, rTgt);
if (isLongOrDouble) {
- RegLocation rlResult = oatGetReturnWide(cUnit);
+ RegLocation rlResult = oatGetReturnWide(cUnit, rlDest.fp);
storeValueWide(cUnit, rlDest, rlResult);
} else {
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, rlDest.fp);
storeValue(cUnit, rlDest, rlResult);
}
}
@@ -761,10 +761,10 @@
loadConstant(cUnit, rARG0, fieldIdx);
callRuntimeHelper(cUnit, rTgt);
if (isLongOrDouble) {
- RegLocation rlResult = oatGetReturnWide(cUnit);
+ RegLocation rlResult = oatGetReturnWide(cUnit, rlDest.fp);
storeValueWide(cUnit, rlDest, rlResult);
} else {
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, rlDest.fp);
storeValue(cUnit, rlDest, rlResult);
}
}
@@ -851,7 +851,7 @@
opRegCopy(cUnit, rARG1, rlMethod.lowReg);
loadConstant(cUnit, rARG0, type_idx);
callRuntimeHelper(cUnit, rTgt);
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
} else {
// We're don't need access checks, load type from dex cache
@@ -884,7 +884,7 @@
opRegCopy(cUnit, rARG1, rlMethod.lowReg);
loadConstant(cUnit, rARG0, type_idx);
callRuntimeHelper(cUnit, rTgt);
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
/*
* Because we have stores of the target value on two paths,
@@ -938,7 +938,7 @@
branch->target = target;
#endif
genBarrier(cUnit);
- storeValue(cUnit, rlDest, oatGetReturn(cUnit));
+ storeValue(cUnit, rlDest, oatGetReturn(cUnit, false));
} else {
RegLocation rlMethod = loadCurrMethod(cUnit);
int resReg = oatAllocTemp(cUnit);
@@ -971,7 +971,7 @@
loadCurrMethodDirect(cUnit, rARG1); // arg1 <= Method*
loadConstant(cUnit, rARG0, type_idx); // arg0 <- type_idx
callRuntimeHelper(cUnit, rTgt);
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
}
@@ -1050,7 +1050,7 @@
oatClobberCalleeSave(cUnit);
/* branch targets here */
LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
branch1->target = target;
#if !defined(TARGET_ARM)
@@ -1434,7 +1434,7 @@
loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
loadValueDirect(cUnit, rlShift, rARG2);
callRuntimeHelper(cUnit, rTgt);
- RegLocation rlResult = oatGetReturnWide(cUnit);
+ RegLocation rlResult = oatGetReturnWide(cUnit, false);
storeValueWide(cUnit, rlDest, rlResult);
return false;
}
@@ -1559,7 +1559,7 @@
}
callRuntimeHelper(cUnit, rTgt);
if (retReg == rRET0)
- rlResult = oatGetReturn(cUnit);
+ rlResult = oatGetReturn(cUnit, false);
else
rlResult = oatGetReturnAlt(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -1807,7 +1807,7 @@
loadConstant(cUnit, rARG1, lit);
callRuntimeHelper(cUnit, rTgt);
if (isDiv)
- rlResult = oatGetReturn(cUnit);
+ rlResult = oatGetReturn(cUnit, false);
else
rlResult = oatGetReturnAlt(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -1957,7 +1957,7 @@
callRuntimeHelper(cUnit, rTgt);
// Adjust return regs in to handle case of rem returning rARG2/rARG3
if (retReg == rRET0)
- rlResult = oatGetReturnWide(cUnit);
+ rlResult = oatGetReturnWide(cUnit, false);
else
rlResult = oatGetReturnWideAlt(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
@@ -1987,12 +1987,12 @@
if (tgtSize == 1) {
RegLocation rlResult;
rlDest = oatGetDest(cUnit, mir, 0);
- rlResult = oatGetReturn(cUnit);
+ rlResult = oatGetReturn(cUnit, rlDest.fp);
storeValue(cUnit, rlDest, rlResult);
} else {
RegLocation rlResult;
rlDest = oatGetDestWide(cUnit, mir, 0, 1);
- rlResult = oatGetReturnWide(cUnit);
+ rlResult = oatGetReturnWide(cUnit, rlDest.fp);
storeValueWide(cUnit, rlDest, rlResult);
}
return false;
@@ -2039,7 +2039,7 @@
loadValueDirectFixed(cUnit, rlSrc1, rARG0);
loadValueDirectFixed(cUnit, rlSrc2, rARG1);
callRuntimeHelper(cUnit, rTgt);
- rlResult = oatGetReturn(cUnit);
+ rlResult = oatGetReturn(cUnit, true);
storeValue(cUnit, rlDest, rlResult);
return false;
}
@@ -2089,7 +2089,7 @@
loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3);
#endif
callRuntimeHelper(cUnit, rTgt);
- rlResult = oatGetReturnWide(cUnit);
+ rlResult = oatGetReturnWide(cUnit, true);
storeValueWide(cUnit, rlDest, rlResult);
return false;
}
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 6aa6366..eff4199 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -25,9 +25,11 @@
INVALID_REG, INVALID_REG, INVALID_SREG};
/* Mark register usage state and return long retloc */
-RegLocation oatGetReturnWide(CompilationUnit* cUnit)
+RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble)
{
- RegLocation res = LOC_C_RETURN_WIDE;
+ RegLocation gpr_res = LOC_C_RETURN_WIDE;
+ RegLocation fpr_res = LOC_C_RETURN_WIDE_DOUBLE;
+ RegLocation res = isDouble ? fpr_res : gpr_res;
oatClobber(cUnit, res.lowReg);
oatClobber(cUnit, res.highReg);
oatLockTemp(cUnit, res.lowReg);
@@ -36,9 +38,11 @@
return res;
}
-RegLocation oatGetReturn(CompilationUnit* cUnit)
+RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
{
- RegLocation res = LOC_C_RETURN;
+ RegLocation gpr_res = LOC_C_RETURN;
+ RegLocation fpr_res = LOC_C_RETURN_FLOAT;
+ RegLocation res = isFloat ? fpr_res : gpr_res;
oatClobber(cUnit, res.lowReg);
if (cUnit->instructionSet == kMips) {
oatMarkInUse(cUnit, res.lowReg);
@@ -195,27 +199,29 @@
if (!cUnit->attrs & METHOD_IS_LEAF) {
genSuspendTest(cUnit, mir);
}
- storeValue(cUnit, oatGetReturn(cUnit), rlSrc[0]);
+ storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'),
+ rlSrc[0]);
break;
case Instruction::RETURN_WIDE:
if (!cUnit->attrs & METHOD_IS_LEAF) {
genSuspendTest(cUnit, mir);
}
- storeValueWide(cUnit, oatGetReturnWide(cUnit), rlSrc[0]);
+ storeValueWide(cUnit, oatGetReturnWide(cUnit,
+ cUnit->shorty[0] == 'D'), rlSrc[0]);
break;
case Instruction::MOVE_RESULT_WIDE:
if (mir->optimizationFlags & MIR_INLINED)
break; // Nop - combined w/ previous invoke
- storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit));
+ storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
break;
case Instruction::MOVE_RESULT:
case Instruction::MOVE_RESULT_OBJECT:
if (mir->optimizationFlags & MIR_INLINED)
break; // Nop - combined w/ previous invoke
- storeValue(cUnit, rlDest, oatGetReturn(cUnit));
+ storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
break;
case Instruction::MOVE:
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h
index d32545c..aa5439a 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/Ralloc.h
@@ -124,7 +124,7 @@
// Get the LocRecord associated with an SSA name def.
extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num);
-extern RegLocation oatGetReturnWide(CompilationUnit* cUnit);
+extern RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble);
/* Clobber all regs that might be used by an external C call */
extern void oatClobberCalleeSave(CompilationUnit* cUnit);
@@ -161,7 +161,7 @@
extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
-extern RegLocation oatGetReturn(CompilationUnit* cUnit);
+extern RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat);
extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit);
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index e3370df..a43702c 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -128,6 +128,8 @@
#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, r0, INVALID_REG,\
INVALID_SREG}
#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r0, r1, INVALID_SREG}
+#define LOC_C_RETURN_FLOAT LOC_C_RETURN
+#define LOC_C_RETURN_WIDE_DOUBLE LOC_C_RETURN_WIDE
enum ResourceEncodingPos {
kGPReg0 = 0,
diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc
index 3bbb3d7..d8ca0a1 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/FP/MipsFP.cc
@@ -218,7 +218,7 @@
}
int rTgt = loadHelper(cUnit, offset);
opReg(cUnit, kOpBlx, rTgt);
- RegLocation rlResult = oatGetReturn(cUnit);
+ RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
return false;
}
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index 8fdfe59..5c8fc34 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -147,10 +147,12 @@
/* 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}
+#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}
+#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}
diff --git a/src/compiler/codegen/x86/ArchFactory.cc b/src/compiler/codegen/x86/ArchFactory.cc
index 2d15318..f2c9c71 100644
--- a/src/compiler/codegen/x86/ArchFactory.cc
+++ b/src/compiler/codegen/x86/ArchFactory.cc
@@ -27,54 +27,36 @@
bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlSrc2)
{
- UNIMPLEMENTED(WARNING) << "genAddLong";
-#if 0
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
+ * add v0,a2,a0
+ * adc v1,a3,a1
*/
opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg);
- int tReg = oatAllocTemp(cUnit);
- opRegRegReg(cUnit, kOpAdd, tReg, rlSrc2.highReg, rlSrc1.highReg);
- newLIR3(cUnit, kX86Sltu, rlResult.highReg, rlResult.lowReg, rlSrc2.lowReg);
- opRegRegReg(cUnit, kOpAdd, rlResult.highReg, rlResult.highReg, tReg);
- oatFreeTemp(cUnit, tReg);
+ opRegRegReg(cUnit, kOpAdc, rlResult.highReg, rlSrc2.highReg, rlSrc1.highReg);
storeValueWide(cUnit, rlDest, rlResult);
-#endif
return false;
}
bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
RegLocation rlSrc1, RegLocation rlSrc2)
{
- UNIMPLEMENTED(WARNING) << "genSubLong";
-#if 0
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
+ * sub v0,a0,a2
+ * sbb v1,a1,a3
*/
opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
- opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg);
- int tReg = oatAllocTemp(cUnit);
- newLIR3(cUnit, kX86Sltu, tReg, rlSrc1.lowReg, rlResult.lowReg);
- opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
- oatFreeTemp(cUnit, tReg);
+ opRegRegReg(cUnit, kOpSbc, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg);
storeValueWide(cUnit, rlDest, rlResult);
-#endif
return false;
}
@@ -123,34 +105,34 @@
#endif
}
-void spillCoreRegs(CompilationUnit* cUnit)
-{
- if (cUnit->numCoreSpills == 0) {
- return;
+void spillCoreRegs(CompilationUnit* cUnit) {
+ if (cUnit->numCoreSpills == 0) {
+ return;
+ }
+ // Spill mask not including fake return address register
+ uint32_t mask = cUnit->coreSpillMask & ~(1 << rRET);
+ int offset = cUnit->frameSize - 4;
+ for (int reg = 0; mask; mask >>= 1, reg++) {
+ if (mask & 0x1) {
+ offset -= 4;
+ storeWordDisp(cUnit, rSP, offset, reg);
}
- uint32_t mask = cUnit->coreSpillMask;
- int offset = cUnit->frameSize - 4;
- 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;
+void unSpillCoreRegs(CompilationUnit* cUnit) {
+ if (cUnit->numCoreSpills == 0) {
+ return;
+ }
+ // Spill mask not including fake return address register
+ uint32_t mask = cUnit->coreSpillMask & ~(1 << rRET);
+ int offset = cUnit->frameSize - 4;
+ 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 - 4;
- for (int reg = 0; mask; mask >>= 1, reg++) {
- if (mask & 0x1) {
- offset -= 4;
- loadWordDisp(cUnit, rSP, offset, reg);
- }
- }
+ }
}
void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset) {
@@ -280,19 +262,17 @@
/* Common initialization routine for an architecture family */
-bool oatArchInit()
-{
- int i;
+bool oatArchInit() {
+ int i;
- for (i = 0; i < kX86Last; 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 < kX86Last; 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/x86/Assemble.cc b/src/compiler/codegen/x86/Assemble.cc
index cb06776..3d2b0e5 100644
--- a/src/compiler/codegen/x86/Assemble.cc
+++ b/src/compiler/codegen/x86/Assemble.cc
@@ -468,6 +468,9 @@
DCHECK_EQ(0, entry->skeleton.extra_opcode1);
DCHECK_EQ(0, entry->skeleton.extra_opcode2);
}
+ if (FPREG(reg)) {
+ reg = reg & FP_REG_MASK;
+ }
DCHECK_LT(reg, 8);
uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | reg;
cUnit->codeBuffer.push_back(modrm);
@@ -518,6 +521,9 @@
DCHECK_EQ(0, entry->skeleton.extra_opcode1);
DCHECK_EQ(0, entry->skeleton.extra_opcode2);
}
+ if (FPREG(reg)) {
+ reg = reg & FP_REG_MASK;
+ }
DCHECK_LT(reg, 8);
DCHECK_LT(base, 8);
uint8_t modrm = (modrmForDisp(disp) << 6) | (reg << 3) | base;
@@ -560,6 +566,9 @@
DCHECK_EQ(0, entry->skeleton.extra_opcode1);
DCHECK_EQ(0, entry->skeleton.extra_opcode2);
}
+ if (FPREG(reg)) {
+ reg = reg & FP_REG_MASK;
+ }
DCHECK_LT(reg, 8);
uint8_t modrm = (modrmForDisp(disp) << 6) | (reg << 3) | rSP;
cUnit->codeBuffer.push_back(modrm);
@@ -596,6 +605,14 @@
DCHECK_EQ(0, entry->skeleton.extra_opcode1);
DCHECK_EQ(0, entry->skeleton.extra_opcode2);
}
+ if (FPREG(reg1)) {
+ reg1 = reg1 & FP_REG_MASK;
+ }
+ if (FPREG(reg2)) {
+ reg2 = reg2 & FP_REG_MASK;
+ }
+ DCHECK_LT(reg1, 8);
+ DCHECK_LT(reg2, 8);
uint8_t modrm = (3 << 6) | (reg1 << 3) | reg2;
cUnit->codeBuffer.push_back(modrm);
DCHECK_EQ(0, entry->skeleton.modrm_opcode);
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc
index c28bae9..f3fc84a 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -76,7 +76,7 @@
}
}
DCHECK((EncodingMap[opcode].flags & IS_BINARY_OP) != 0);
- LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rSrc, rDest);
+ LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
if (rDest == rSrc) {
res->flags.isNop = true;
}
@@ -502,7 +502,7 @@
rDest = rDest - FP_DOUBLE;
} else {
DCHECK(FPREG(rDestHi));
- DCHECK(rDest == (rDestHi - 1));
+ DCHECK_EQ(rDest, (rDestHi - 1));
}
rDestHi = rDest + 1;
} else {
@@ -549,7 +549,7 @@
if (rBase == rSP) {
annotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
true /* isLoad */, is64bit);
- if (is64bit) {
+ if (pair) {
annotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
true /* isLoad */, is64bit);
}
diff --git a/src/compiler/codegen/x86/X86/Gen.cc b/src/compiler/codegen/x86/X86/Gen.cc
index f3b8aa0..e7f18ca 100644
--- a/src/compiler/codegen/x86/X86/Gen.cc
+++ b/src/compiler/codegen/x86/X86/Gen.cc
@@ -437,51 +437,39 @@
LIR* opRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
{
LIR *res = opRegCopyNoInsert(cUnit, rDest, rSrc);
- oatAppendLIR(cUnit, (LIR*)res);
+ oatAppendLIR(cUnit, res);
return res;
}
void opRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
- int srcLo, int srcHi)
-{
- UNIMPLEMENTED(WARNING) << "opRegCopyWide";
-#if 0
- 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, kX86Mtc1, srcLo, destLo);
- newLIR2(cUnit, kX86Mtc1, srcHi, destHi);
- }
+ int srcLo, int srcHi) {
+ bool destFP = FPREG(destLo) && FPREG(destHi);
+ bool srcFP = FPREG(srcLo) && FPREG(srcHi);
+ assert(FPREG(srcLo) == FPREG(srcHi));
+ assert(FPREG(destLo) == FPREG(destHi));
+ LOG(INFO) << "RegCopyWide: destLo=" << destLo << " destHi=" << destHi
+ << " srcLo=" << srcLo << " srcHi=" << srcHi
+ << " dFP=" << destFP << " sFP=" << srcFP;
+ if (destFP) {
+ if (srcFP) {
+ opRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
} else {
- if (srcFP) {
- newLIR2(cUnit, kX86Mfc1, destLo, srcLo);
- newLIR2(cUnit, kX86Mfc1, 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);
- }
- }
+ UNIMPLEMENTED(WARNING);
}
- // Handle overlap
- if (srcHi == destLo) {
+ } else {
+ if (srcFP) {
+ UNIMPLEMENTED(WARNING);
+ } else {
+ // Handle overlap
+ if (srcHi == destLo) {
opRegCopy(cUnit, destHi, srcHi);
opRegCopy(cUnit, destLo, srcLo);
- } else {
+ } else {
opRegCopy(cUnit, destLo, srcLo);
opRegCopy(cUnit, destHi, srcHi);
+ }
}
-#endif
+ }
}
} // namespace art
diff --git a/src/compiler/codegen/x86/X86/Ralloc.cc b/src/compiler/codegen/x86/X86/Ralloc.cc
index c7985e5..38b9df8 100644
--- a/src/compiler/codegen/x86/X86/Ralloc.cc
+++ b/src/compiler/codegen/x86/X86/Ralloc.cc
@@ -29,97 +29,88 @@
* high reg in next byte.
*/
int oatAllocTypedTempPair(CompilationUnit *cUnit, bool fpHint,
- int regClass)
-{
- UNIMPLEMENTED(WARNING) << "oatAllocTypedTemp";
- return 0;
-#if 0
- int highReg;
- int lowReg;
- int res = 0;
+ int regClass) {
+ int highReg;
+ int lowReg;
+ int res = 0;
- if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
- lowReg = oatAllocTempDouble(cUnit);
- highReg = lowReg + 1;
- res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
- return res;
- }
-
- 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)
-{
- if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
-{
- return oatAllocTempFloat(cUnit);
-}
- return oatAllocTemp(cUnit);
+int oatAllocTypedTemp(CompilationUnit *cUnit, bool fpHint, int regClass) {
+ if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
+ return oatAllocTempFloat(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 numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
- int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
- 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++) {
- 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 oatInitializeRegAlloc(CompilationUnit* cUnit) {
+ int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
+ int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
+ int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
+ int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
+ int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
+ 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++) {
+ 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)
-{
- 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);
- }
+ 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);
+ }
}
diff --git a/src/compiler/codegen/x86/X86LIR.h b/src/compiler/codegen/x86/X86LIR.h
index 65f07cf..c805333 100644
--- a/src/compiler/codegen/x86/X86LIR.h
+++ b/src/compiler/codegen/x86/X86LIR.h
@@ -106,11 +106,11 @@
*/
/* Offset to distingish FP regs */
-#define FP_REG_OFFSET 16
+#define FP_REG_OFFSET 32
/* Offset to distinguish DP FP regs */
-#define FP_DOUBLE 32
+#define FP_DOUBLE (FP_REG_OFFSET + 16)
/* Offset to distingish the extra regs */
-#define EXTRA_REG_OFFSET 64
+#define EXTRA_REG_OFFSET (FP_DOUBLE + 16)
/* Reg types */
#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
@@ -128,15 +128,18 @@
*/
#define S2D(x,y) ((x) | FP_DOUBLE)
/* Mask to strip off fp flags */
-#define FP_REG_MASK (FP_REG_OFFSET-1)
+#define FP_REG_MASK 0xF
/* non-existent Dalvik register */
#define vNone (-1)
/* non-existant physical register */
#define rNone (-1)
-/* RegisterLocation templates return values (rAX, or rAX/rDX) */
-#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, rAX, INVALID_REG, INVALID_SREG}
-#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, rAX, rDX, INVALID_SREG}
+/* RegisterLocation templates return values (rAX, rAX/rDX or XMM0) */
+// location, wide, defined, fp, core, highWord, home, lowReg, highReg, sRegLow
+#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, rAX, INVALID_REG, INVALID_SREG}
+#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, rAX, rDX, INVALID_SREG}
+#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 1, 0, 0, 1, fr0, INVALID_REG, INVALID_SREG}
+#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 1, 0, 0, 1, fr0, fr1, INVALID_SREG}
enum ResourceEncodingPos {
kGPReg0 = 0,
@@ -201,6 +204,7 @@
r13 = 13,
r14 = 14,
r15 = 15,
+ rRET = 16, // fake return address register for core spill mask
fr0 = 0 + FP_REG_OFFSET,
fr1 = 1 + FP_REG_OFFSET,
fr2 = 2 + FP_REG_OFFSET,
diff --git a/src/compiler/codegen/x86/X86RallocUtil.cc b/src/compiler/codegen/x86/X86RallocUtil.cc
index 1b4eca4..ff5391d 100644
--- a/src/compiler/codegen/x86/X86RallocUtil.cc
+++ b/src/compiler/codegen/x86/X86RallocUtil.cc
@@ -29,6 +29,8 @@
void oatAdjustSpillMask(CompilationUnit* cUnit) {
// Adjustment for LR spilling, x86 has no LR so nothing to do here
+ cUnit->coreSpillMask |= (1 << rRET);
+ cUnit->numCoreSpills++;
}
/*
@@ -138,17 +140,16 @@
#endif
}
-extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
-{
- RegLocation res = LOC_C_RETURN_WIDE;
- res.lowReg = rAX;
- res.highReg = rDX;
- oatClobber(cUnit, rAX);
- oatClobber(cUnit, rDX);
- oatMarkInUse(cUnit, rAX);
- oatMarkInUse(cUnit, rDX);
- oatMarkPair(cUnit, res.lowReg, res.highReg);
- return res;
+extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit) {
+ RegLocation res = LOC_C_RETURN_WIDE;
+ CHECK(res.lowReg == rAX);
+ CHECK(res.highReg == rDX);
+ oatClobber(cUnit, rAX);
+ oatClobber(cUnit, rDX);
+ oatMarkInUse(cUnit, rAX);
+ oatMarkInUse(cUnit, rDX);
+ oatMarkPair(cUnit, res.lowReg, res.highReg);
+ return res;
}
extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)