diff options
| author | 2012-03-02 15:40:30 -0800 | |
|---|---|---|
| committer | 2012-03-02 15:40:30 -0800 | |
| commit | 41f05df8aeba13e853a22820a0f4bf094233e2d9 (patch) | |
| tree | 0f107dd37b06d85ee3cf4261b855d836f1f4ba6a /src | |
| parent | be00364d260ea96323a070723af0bd61e3ea703a (diff) | |
| parent | 0398c42cd64682d18120a26c6c39b193fdf97658 (diff) | |
Merge "More MIPS support" into dalvik-dev
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 38 | ||||
| -rw-r--r-- | src/compiler/codegen/GenInvoke.cc | 46 | ||||
| -rw-r--r-- | src/compiler/codegen/MethodCodegenDriver.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/ArchFactory.cc | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/Assemble.cc | 1 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/Mips32/Gen.cc | 88 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/MipsLIR.h | 2 |
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 { |