summaryrefslogtreecommitdiff
path: root/src/compiler/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/codegen')
-rw-r--r--src/compiler/codegen/GenCommon.cc93
-rw-r--r--src/compiler/codegen/x86/X86/Factory.cc8
-rw-r--r--src/compiler/codegen/x86/X86RallocUtil.cc2
3 files changed, 52 insertions, 51 deletions
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index aeacab8514..d2628bb19c 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -1392,8 +1392,8 @@ void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
#endif
/* branch target here */
LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
- branch1->target = (LIR*)target;
- branch2->target = (LIR*)target;
+ branch1->target = target;
+ branch2->target = target;
}
/*
@@ -1403,73 +1403,70 @@ void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, RegLocation rlArray,
RegLocation rlIndex, RegLocation rlSrc, int scale)
{
- RegisterClass regClass = oatRegClassBySize(kWord);
int lenOffset = Array::LengthOffset().Int32Value();
int dataOffset = Array::DataOffset(sizeof(Object*)).Int32Value();
- oatFlushAllRegs(cUnit);
- /* Make sure it's a legal object Put. Use direct regs at first */
- loadValueDirectFixed(cUnit, rlArray, rARG1);
- loadValueDirectFixed(cUnit, rlSrc, rARG0);
-
- /* null array object? */
- genNullCheck(cUnit, rlArray.sRegLow, rARG1, mir);
- /* Get the array's class */
- loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(), rARG1);
- callRuntimeHelperRegReg(cUnit, ENTRYPOINT_OFFSET(pCanPutArrayElementFromCode),
- rARG0, rARG1);
- oatFreeTemp(cUnit, rARG0);
- oatFreeTemp(cUnit, rARG1);
+ oatFlushAllRegs(cUnit); // Use explicit registers
+ oatLockCallTemps(cUnit);
- // Now, redo loadValues in case they didn't survive the call
+ int rValue = rARG0; // Register holding value
+ int rArrayClass = rARG1; // Register holding array's Class
+ int rArray = rARG2; // Register holding array
+ int rIndex = rARG3; // Register holding index into array
- rlArray = loadValue(cUnit, rlArray, kCoreReg);
- rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
+ loadValueDirectFixed(cUnit, rlArray, rArray); // Grab array
+ loadValueDirectFixed(cUnit, rlSrc, rValue); // Grab value
+ loadValueDirectFixed(cUnit, rlIndex, rIndex); // Grab index
+
+ genNullCheck(cUnit, rlArray.sRegLow, rArray, mir); // NPE?
+
+ // Store of null?
+ LIR* null_value_check = opCmpImmBranch(cUnit, kCondEq, rValue, 0, NULL);
+
+ // Get the array's class.
+ loadWordDisp(cUnit, rArray, Object::ClassOffset().Int32Value(), rArrayClass);
+ callRuntimeHelperRegReg(cUnit, ENTRYPOINT_OFFSET(pCanPutArrayElementFromCode),
+ rValue, rArrayClass);
+ // Redo loadValues in case they didn't survive the call.
+ loadValueDirectFixed(cUnit, rlArray, rArray); // Reload array
+ loadValueDirectFixed(cUnit, rlIndex, rIndex); // Reload index
+ loadValueDirectFixed(cUnit, rlSrc, rValue); // Reload value
+ rArrayClass = INVALID_REG;
+
+ // Branch here if value to be stored == null
+ LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+ null_value_check->target = target;
#if defined(TARGET_X86)
+ // make an extra temp available for card mark below
+ oatFreeTemp(cUnit, rARG1);
if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
/* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
- genRegMemCheck(cUnit, kCondUge, rlIndex.lowReg, rlArray.lowReg,
+ genRegMemCheck(cUnit, kCondUge, rIndex, rArray,
lenOffset, mir, kThrowArrayBounds);
}
- rlSrc = loadValue(cUnit, rlSrc, regClass);
- storeBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale,
- dataOffset, rlSrc.lowReg, INVALID_REG, kWord,
+ storeBaseIndexedDisp(cUnit, NULL, rArray, rIndex, scale,
+ dataOffset, rValue, INVALID_REG, kWord,
INVALID_SREG);
- if (oatIsTemp(cUnit, rlIndex.lowReg)) {
- oatFreeTemp(cUnit, rlIndex.lowReg);
- }
#else
- int regPtr;
- if (oatIsTemp(cUnit, rlArray.lowReg)) {
- oatClobber(cUnit, rlArray.lowReg);
- regPtr = rlArray.lowReg;
- } else {
- regPtr = oatAllocTemp(cUnit);
- opRegCopy(cUnit, regPtr, rlArray.lowReg);
- }
-
bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
int regLen = INVALID_REG;
if (needsRangeCheck) {
- regLen = oatAllocTemp(cUnit);
- //NOTE: max live temps(4) here.
- /* Get len */
- loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
+ regLen = rARG1;
+ loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen); // Get len
}
- /* regPtr -> array data */
- opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
- /* at this point, regPtr points to array, 2 live temps */
- rlSrc = loadValue(cUnit, rlSrc, regClass);
+ /* rPtr -> array data */
+ int rPtr = oatAllocTemp(cUnit);
+ opRegRegImm(cUnit, kOpAdd, rPtr, rArray, dataOffset);
if (needsRangeCheck) {
- genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
+ genRegRegCheck(cUnit, kCondCs, rIndex, regLen, mir,
kThrowArrayBounds);
- oatFreeTemp(cUnit, regLen);
}
- storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
- scale, kWord);
+ storeBaseIndexed(cUnit, rPtr, rIndex, rValue, scale, kWord);
+ oatFreeTemp(cUnit, rPtr);
#endif
- markGCCard(cUnit, rlSrc.lowReg, rlArray.lowReg);
+ oatFreeTemp(cUnit, rIndex);
+ markGCCard(cUnit, rValue, rArray);
}
/*
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc
index 9421744f69..2bd5b42458 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -173,6 +173,7 @@ LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int value) {
LIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int rSrc2)
{
X86OpCode opcode = kX86Nop;
+ bool src2_must_be_cx = false;
switch (op) {
// X86 unary opcodes
case kOpMvn:
@@ -184,9 +185,9 @@ LIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int rSrc2)
// X86 binary opcodes
case kOpSub: opcode = kX86Sub32RR; break;
case kOpSbc: opcode = kX86Sbb32RR; break;
- case kOpLsl: opcode = kX86Sal32RC; break;
- case kOpLsr: opcode = kX86Shr32RC; break;
- case kOpAsr: opcode = kX86Sar32RC; break;
+ case kOpLsl: opcode = kX86Sal32RC; src2_must_be_cx = true; break;
+ case kOpLsr: opcode = kX86Shr32RC; src2_must_be_cx = true; break;
+ case kOpAsr: opcode = kX86Sar32RC; src2_must_be_cx = true; break;
case kOpMov: opcode = kX86Mov32RR; break;
case kOpCmp: opcode = kX86Cmp32RR; break;
case kOpAdd: opcode = kX86Add32RR; break;
@@ -202,6 +203,7 @@ LIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int rSrc2)
LOG(FATAL) << "Bad case in opRegReg " << op;
break;
}
+ CHECK(!src2_must_be_cx || rSrc2 == rCX);
return newLIR2(cUnit, opcode, rDestSrc1, rSrc2);
}
diff --git a/src/compiler/codegen/x86/X86RallocUtil.cc b/src/compiler/codegen/x86/X86RallocUtil.cc
index 297163250b..a85cb8af63 100644
--- a/src/compiler/codegen/x86/X86RallocUtil.cc
+++ b/src/compiler/codegen/x86/X86RallocUtil.cc
@@ -134,6 +134,7 @@ extern void oatLockCallTemps(CompilationUnit* cUnit)
oatLockTemp(cUnit, rARG0);
oatLockTemp(cUnit, rARG1);
oatLockTemp(cUnit, rARG2);
+ oatLockTemp(cUnit, rARG3);
}
/* To be used when explicitly managing register use */
@@ -142,6 +143,7 @@ extern void oatFreeCallTemps(CompilationUnit* cUnit)
oatFreeTemp(cUnit, rARG0);
oatFreeTemp(cUnit, rARG1);
oatFreeTemp(cUnit, rARG2);
+ oatFreeTemp(cUnit, rARG3);
}
/* Convert an instruction to a NOP */