summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2012-03-02 15:40:30 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2012-03-02 15:40:30 -0800
commit41f05df8aeba13e853a22820a0f4bf094233e2d9 (patch)
tree0f107dd37b06d85ee3cf4261b855d836f1f4ba6a /src
parentbe00364d260ea96323a070723af0bd61e3ea703a (diff)
parent0398c42cd64682d18120a26c6c39b193fdf97658 (diff)
Merge "More MIPS support" into dalvik-dev
Diffstat (limited to 'src')
-rw-r--r--src/compiler/codegen/GenCommon.cc38
-rw-r--r--src/compiler/codegen/GenInvoke.cc46
-rw-r--r--src/compiler/codegen/MethodCodegenDriver.cc6
-rw-r--r--src/compiler/codegen/arm/ArmLIR.h2
-rw-r--r--src/compiler/codegen/mips/ArchFactory.cc2
-rw-r--r--src/compiler/codegen/mips/Assemble.cc1
-rw-r--r--src/compiler/codegen/mips/Mips32/Gen.cc88
-rw-r--r--src/compiler/codegen/mips/MipsLIR.h2
8 files changed, 100 insertions, 85 deletions
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 66950d2dc0..4d80a690a9 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -584,9 +584,9 @@ void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
// Debugging routine - if null target, branch to DebugMe
void genShowTarget(CompilationUnit* cUnit)
{
- LIR* branchOver = opCmpImmBranch(cUnit, kCondNe, rLINK, 0, NULL);
+ LIR* branchOver = opCmpImmBranch(cUnit, kCondNe, rINVOKE_TGT, 0, NULL);
loadWordDisp(cUnit, rSELF,
- OFFSETOF_MEMBER(Thread, pDebugMe), rLINK);
+ OFFSETOF_MEMBER(Thread, pDebugMe), rINVOKE_TGT);
LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
target->defMask = -1;
branchOver->target = (LIR*)target;
@@ -703,6 +703,7 @@ void handleThrowLaunchpads(CompilationUnit *cUnit)
}
int rTgt = loadHelper(cUnit, funcOffset);
callRuntimeHelper(cUnit, rTgt);
+ oatFreeTemp(cUnit, rTgt);
}
}
@@ -1022,28 +1023,34 @@ void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
loadWordDisp(cUnit, rARG0, Object::ClassOffset().Int32Value(), rARG1);
/* rARG0 is ref, rARG1 is ref->clazz, rARG2 is class */
+#if defined(TARGET_ARM)
+ /* Uses conditional nullification */
int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
pInstanceofNonTrivialFromCode));
-#if defined(TARGET_ARM)
opRegReg(cUnit, kOpCmp, rARG1, rARG2); // Same?
- genBarrier(cUnit);
opIT(cUnit, kArmCondEq, "EE"); // if-convert the test
loadConstant(cUnit, rARG0, 1); // .eq case - load true
opRegCopy(cUnit, rARG0, rARG2); // .ne case - arg0 <= class
opReg(cUnit, kOpBlx, rTgt); // .ne case: helper(class, ref->class)
- genBarrier(cUnit);
- oatClobberCalleeSave(cUnit);
#else
- (void)rTgt;
- // Perhaps a general-purpose kOpSelect operator?
- UNIMPLEMENTED(FATAL) << "Need non IT implementation";
+ /* Uses branchovers */
+ loadConstant(cUnit, rARG0, 1); // assume true
+ LIR* branchover = opCmpBranch(cUnit, kCondEq, rARG1, rARG2, NULL);
+ int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+ pInstanceofNonTrivialFromCode));
+ opRegCopy(cUnit, rARG0, rARG2); // .ne case - arg0 <= class
+ opReg(cUnit, kOpBlx, rTgt); // .ne case: helper(class, ref->class)
#endif
- /* branch target here */
+ oatClobberCalleeSave(cUnit);
+ /* branch targets here */
LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
target->defMask = ENCODE_ALL;
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
- branch1->target = (LIR*)target;
+ branch1->target = target;
+#if !defined(TARGET_ARM)
+ branchover->target = target;
+#endif
}
void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
@@ -1616,11 +1623,14 @@ void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
RegLocation rlResult, int lit,
int firstBit, int secondBit)
{
-#if defined(TARGET_MIPS)
- UNIMPLEMENTED(FATAL) << "Need shift & add primative";
-#else
+#if defined(TARGET_ARM)
opRegRegRegShift(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg,
encodeShift(kArmLsl, secondBit - firstBit));
+#else
+ int tReg = oatAllocTemp(cUnit);
+ opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, secondBit - firstBit);
+ opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, tReg);
+ oatFreeTemp(cUnit, tReg);
#endif
if (firstBit != 0) {
opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
index 69df8fc609..4698868ad2 100644
--- a/src/compiler/codegen/GenInvoke.cc
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -103,7 +103,7 @@ int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
break;
case 3: // Grab the code from the method*
loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
- rLINK);
+ rINVOKE_TGT);
break;
default:
return -1;
@@ -133,22 +133,22 @@ int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
break;
case 1: // Is "this" null? [use rARG1]
genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
- // get this->klass_ [use rARG1, set rLINK]
+ // get this->klass_ [use rARG1, set rINVOKE_TGT]
loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(),
- rLINK);
+ rINVOKE_TGT);
break;
- case 2: // Get this->klass_->vtable [usr rLINK, set rLINK]
- loadWordDisp(cUnit, rLINK, Class::VTableOffset().Int32Value(),
- rLINK);
+ case 2: // Get this->klass_->vtable [usr rINVOKE_TGT, set rINVOKE_TGT]
+ loadWordDisp(cUnit, rINVOKE_TGT, Class::VTableOffset().Int32Value(),
+ rINVOKE_TGT);
break;
- case 3: // Get target method [use rLINK, set rARG0]
- loadWordDisp(cUnit, rLINK, (methodIdx * 4) +
+ case 3: // Get target method [use rINVOKE_TGT, set rARG0]
+ loadWordDisp(cUnit, rINVOKE_TGT, (methodIdx * 4) +
Array::DataOffset(sizeof(Object*)).Int32Value(),
rARG0);
break;
- case 4: // Get the target compiled code address [uses rARG0, sets rLINK]
+ case 4: // Get the compiled code address [uses rARG0, sets rINVOKE_TGT]
loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
- rLINK);
+ rINVOKE_TGT);
break;
default:
return -1;
@@ -176,29 +176,29 @@ int nextSuperCallInsn(CompilationUnit* cUnit, MIR* mir,
// Load "this" [set rARG1]
rlArg = oatGetSrc(cUnit, mir, 0);
loadValueDirectFixed(cUnit, rlArg, rARG1);
- // Get method->declaring_class_ [use rARG0, set rLINK]
+ // Get method->declaring_class_ [use rARG0, set rINVOKE_TGT]
loadWordDisp(cUnit, rARG0,
Method::DeclaringClassOffset().Int32Value(),
- rLINK);
+ rINVOKE_TGT);
// Is "this" null? [use rARG1]
genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
break;
- case 1: // Get method->declaring_class_->super_class [use/set rLINK]
- loadWordDisp(cUnit, rLINK,
- Class::SuperClassOffset().Int32Value(), rLINK);
+ case 1: // method->declaring_class_->super_class [use/set rINVOKE_TGT]
+ loadWordDisp(cUnit, rINVOKE_TGT,
+ Class::SuperClassOffset().Int32Value(), rINVOKE_TGT);
break;
- case 2: // Get ...->super_class_->vtable [u/s rLINK]
- loadWordDisp(cUnit, rLINK,
- Class::VTableOffset().Int32Value(), rLINK);
+ case 2: // Get ...->super_class_->vtable [u/s rINVOKE_TGT]
+ loadWordDisp(cUnit, rINVOKE_TGT,
+ Class::VTableOffset().Int32Value(), rINVOKE_TGT);
break;
- case 3: // Get target method [use rLINK, set rARG0]
- loadWordDisp(cUnit, rLINK, (methodIdx * 4) +
+ case 3: // Get target method [use rINVOKE_TGT, set rARG0]
+ loadWordDisp(cUnit, rINVOKE_TGT, (methodIdx * 4) +
Array::DataOffset(sizeof(Object*)).Int32Value(),
rARG0);
break;
- case 4: // Get the target compiled code address [uses rARG0, sets rLINK]
+ case 4: // target compiled code address [uses rARG0, sets rINVOKE_TGT]
loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
- rLINK);
+ rINVOKE_TGT);
break;
default:
return -1;
@@ -215,7 +215,7 @@ int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
*/
if (state == 0) {
// Load trampoline target
- loadWordDisp(cUnit, rSELF, trampoline, rLINK);
+ loadWordDisp(cUnit, rSELF, trampoline, rINVOKE_TGT);
// Load rARG0 with method index
loadConstant(cUnit, rARG0, dexIdx);
return 1;
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index a1eeeaee6e..42dae0f113 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -102,11 +102,7 @@ void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
if (DISPLAY_MISSING_TARGETS) {
genShowTarget(cUnit);
}
-#if defined(TARGET_MIPS)
- UNIMPLEMENTED(WARNING) << "Need to handle common target register";
-#else
- opReg(cUnit, kOpBlx, rLR);
-#endif
+ opReg(cUnit, kOpBlx, rINVOKE_TGT);
oatClobberCalleeSave(cUnit);
}
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index cafc9934c2..db2d6e8590 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -251,7 +251,7 @@ typedef enum NativeRegisterPool {
#define rARG3 r3
#define rRET0 r0
#define rRET1 r1
-#define rLINK rLR
+#define rINVOKE_TGT rLR
/* Shift encodings */
typedef enum ArmShiftEncodings {
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
index aaaa50f6ac..963427ddce 100644
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ b/src/compiler/codegen/mips/ArchFactory.cc
@@ -145,7 +145,7 @@ void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb)
genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT);
}
unSpillCoreRegs(cUnit);
- opReg(cUnit, kOpBx, rLINK);
+ opReg(cUnit, kOpBx, r_RA);
}
/*
diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc
index 4deb8f5f31..0021318c6d 100644
--- a/src/compiler/codegen/mips/Assemble.cc
+++ b/src/compiler/codegen/mips/Assemble.cc
@@ -527,7 +527,6 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit,
<< (int)encoder->fieldLoc[i].kind;
}
}
- DCHECK_EQ(encoder->size, 4);
// FIXME: need multi-endian handling here
cUnit->codeBuffer.push_back((bits >> 16) & 0xffff);
cUnit->codeBuffer.push_back(bits & 0xffff);
diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
index db34ce35bb..155675c700 100644
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ b/src/compiler/codegen/mips/Mips32/Gen.cc
@@ -274,45 +274,54 @@ void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
int src2, LIR* target)
{
- LIR* branch;
- if (cond == kCondEq) {
- branch = newLIR2(cUnit, kMipsBeq, src1, src2);
- } else if (cond == kCondNe) {
- branch = newLIR2(cUnit, kMipsBne, 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;
+ default:
+ UNIMPLEMENTED(FATAL) << "No support for ConditionCode: "
+ << (int) cond;
+ return NULL;
+ }
+ if (cmpZero) {
+ branch = newLIR2(cUnit, brOp, src1, src2);
} else {
- MipsOpCode sltOp;
- MipsOpCode brOp;
- bool swapped = false;
- switch(cond) {
- case kCondEq: return newLIR2(cUnit, kMipsBeq, src1, src2);
- case kCondNe: return newLIR2(cUnit, kMipsBne, src1, src2);
- case kCondCc:
- sltOp = kMipsSltu;
- brOp = kMipsBnez;
- 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;
- default:
- UNIMPLEMENTED(FATAL) << "No support for ConditionCode: "
- << (int) cond;
- return NULL;
- }
int tReg = oatAllocTemp(cUnit);
if (swapped) {
newLIR3(cUnit, sltOp, tReg, src2, src1);
@@ -320,8 +329,9 @@ LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
newLIR3(cUnit, sltOp, tReg, src1, src2);
}
branch = newLIR1(cUnit, brOp, tReg);
- branch->target = target;
+ oatFreeTemp(cUnit, tReg);
}
+ branch->target = target;
return branch;
}
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index 67f3131a70..b2cfdbed59 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -301,7 +301,7 @@ typedef enum NativeRegisterPool {
#define rARG3 r_ARG3
#define rRET0 r_RESULT0
#define rRET1 r_RESULT1
-#define rLINK r_RA
+#define rINVOKE_TGT r_V0
/* Shift encodings */
typedef enum MipsShiftEncodings {