diff options
| -rw-r--r-- | src/compiler/codegen/RallocUtil.cc | 5 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArchFactory.cc | 13 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 4 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Assemble.cc | 10 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Factory.cc | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 29 |
6 files changed, 49 insertions, 14 deletions
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc index 47d5ac0919..9df80bd49b 100644 --- a/src/compiler/codegen/RallocUtil.cc +++ b/src/compiler/codegen/RallocUtil.cc @@ -884,6 +884,7 @@ extern RegLocation oatUpdateLoc(CompilationUnit* cUnit, RegLocation loc) if (infoLo->pair) { oatClobber(cUnit, infoLo->reg); oatClobber(cUnit, infoLo->partner); + oatFreeTemp(cUnit, infoLo->reg); } else { loc.lowReg = infoLo->reg; loc.location = kLocPhysReg; @@ -957,14 +958,16 @@ extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit, DCHECK(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0)); return loc; } - // Can't easily reuse - clobber any overlaps + // Can't easily reuse - clobber and free any overlaps if (infoLo) { oatClobber(cUnit, infoLo->reg); + oatFreeTemp(cUnit, infoLo->reg); if (infoLo->pair) oatClobber(cUnit, infoLo->partner); } if (infoHi) { oatClobber(cUnit, infoHi->reg); + oatFreeTemp(cUnit, infoHi->reg); if (infoHi->pair) oatClobber(cUnit, infoHi->partner); } diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc index ec378763c0..a68727fc34 100644 --- a/src/compiler/codegen/arm/ArchFactory.cc +++ b/src/compiler/codegen/arm/ArchFactory.cc @@ -51,6 +51,19 @@ STATIC int loadCurrMethod(CompilationUnit *cUnit) #endif } +STATIC ArmLIR* genCheck(CompilationUnit* cUnit, ArmConditionCode cCode, + MIR* mir, ArmThrowKind kind) +{ + ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true); + tgt->opcode = kArmPseudoThrowTarget; + tgt->operands[0] = kind; + tgt->operands[1] = mir ? mir->offset : 0; + ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt); + // Remember branch target - will process later + oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt); + return branch; +} + STATIC ArmLIR* genImmedCheck(CompilationUnit* cUnit, ArmConditionCode cCode, int reg, int immVal, MIR* mir, ArmThrowKind kind) { diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h index 8f715719ee..3b2e986acb 100644 --- a/src/compiler/codegen/arm/ArmLIR.h +++ b/src/compiler/codegen/arm/ArmLIR.h @@ -534,7 +534,7 @@ typedef enum ArmOpcode { [0000] rm[3..0] */ kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16] [0] imm3[14..12] rd[11..8] imm8[7..0] */ - kThumb2MvnImmShift, /* mov(T2) rd, #<const> [11110] i [00011011110] + kThumb2MvnImm12, /* mov(T2) rd, #<const> [11110] i [00011011110] imm3 rd[11..8] imm8 */ kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8] rm[3-0] */ @@ -691,6 +691,8 @@ typedef enum ArmOpcode { kThumb2MovImm16HST, /* Special purpose version for switch table use */ kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */ kThumb2SubsRRI12, /* setflags encoding */ + kThumb2OrrRRRs, /* orrx [111010100101] rn[19..16] [0000] rd[11..8] + [0000] rm[3..0] */ kArmLast, } ArmOpcode; diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc index dff9ddd83f..c42b4b8b93 100644 --- a/src/compiler/codegen/arm/Assemble.cc +++ b/src/compiler/codegen/arm/Assemble.cc @@ -571,8 +571,8 @@ ArmEncodingMap EncodingMap[kArmLast] = { kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE1,/* Note: doesn't affect flags */ "sub", "!0C,!1C,#!2d", 2), - ENCODING_MAP(kThumb2MvnImmShift, 0xf06f0000, /* no setflags encoding */ - kFmtBitBlt, 11, 8, kFmtModImm, -1, -1, kFmtUnused, -1, -1, + ENCODING_MAP(kThumb2MvnImm12, 0xf06f0000, /* no setflags encoding */ + kFmtBitBlt, 11, 8, kFmtImm12, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0, "mvn", "!0C, #!1n", 2), ENCODING_MAP(kThumb2Sel, 0xfaa0f080, @@ -955,6 +955,10 @@ ArmEncodingMap EncodingMap[kArmLast] = { kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE1 | SETS_CCODES, "subs", "!0C,!1C,#!2d", 2), + ENCODING_MAP(kThumb2OrrRRRs, 0xea500000, + kFmtBitBlt, 11, 8, kFmtBitBlt, 19, 16, kFmtBitBlt, 3, 0, + kFmtShift, -1, -1, IS_QUAD_OP | REG_DEF0_USE12 | SETS_CCODES, + "orrs", "!0C, !1C, !2C!3H", 2), }; @@ -1039,7 +1043,7 @@ STATIC void installFillArrayData(CompilationUnit* cUnit) &iterator); if (tabRec == NULL) break; alignBuffer(cUnit->codeBuffer, tabRec->offset); - for (int i = 0; i < (tabRec->size / 2) ; i++) { + for (int i = 0; i < ((tabRec->size + 1) / 2) ; i++) { cUnit->codeBuffer.push_back( tabRec->table[i]); } } diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc index c8e428fb62..3ee23eaf1f 100644 --- a/src/compiler/codegen/arm/Thumb2/Factory.cc +++ b/src/compiler/codegen/arm/Thumb2/Factory.cc @@ -163,7 +163,7 @@ STATIC ArmLIR* loadConstantNoClobber(CompilationUnit* cUnit, int rDest, } modImm = modifiedImmediate(~value); if (modImm >= 0) { - res = newLIR2(cUnit, kThumb2MvnImmShift, rDest, modImm); + res = newLIR2(cUnit, kThumb2MvnImm12, rDest, modImm); return res; } /* 16-bit immediate? */ diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index 5ef768776a..3f7a7aef53 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -460,7 +460,7 @@ STATIC void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size, rlObj = loadValue(cUnit, rlObj, kCoreReg); rlResult = oatEvalLoc(cUnit, rlDest, regClass, true); genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */ - loadBaseIndexed(cUnit, rlObj.lowReg, r0, rlResult.lowReg, 0, size); + loadBaseIndexed(cUnit, rlObj.lowReg, r0, rlResult.lowReg, 0, kWord); oatGenMemBarrier(cUnit, kSY); storeValue(cUnit, rlDest, rlResult); } else { @@ -474,7 +474,7 @@ STATIC void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size, rlResult = oatEvalLoc(cUnit, rlDest, regClass, true); genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */ loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg, - size, rlObj.sRegLow); + kWord, rlObj.sRegLow); if (isVolatile) { oatGenMemBarrier(cUnit, kSY); } @@ -495,7 +495,7 @@ STATIC void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, rlSrc = loadValue(cUnit, rlSrc, regClass); genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */ oatGenMemBarrier(cUnit, kSY); - storeBaseIndexed(cUnit, rlObj.lowReg, r0, rlSrc.lowReg, 0, size); + storeBaseIndexed(cUnit, rlObj.lowReg, r0, rlSrc.lowReg, 0, kWord); } else { #if ANDROID_SMP != 0 bool isVolatile = fieldPtr->IsVolatile(); @@ -510,7 +510,7 @@ STATIC void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, if (isVolatile) { oatGenMemBarrier(cUnit, kST); } - storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, size); + storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, kWord); if (isVolatile) { oatGenMemBarrier(cUnit, kSY); } @@ -1498,6 +1498,7 @@ STATIC bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, OpKind firstOp = kOpBkpt; OpKind secondOp = kOpBkpt; bool callOut = false; + bool checkZero = false; int funcOffset; int retReg = r0; @@ -1538,6 +1539,7 @@ STATIC bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, case OP_DIV_LONG: case OP_DIV_LONG_2ADDR: callOut = true; + checkZero = true; retReg = r0; funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod); break; @@ -1545,6 +1547,7 @@ STATIC bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, case OP_REM_LONG: case OP_REM_LONG_2ADDR: callOut = true; + checkZero = true; funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod); retReg = r2; break; @@ -1592,12 +1595,22 @@ STATIC bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, if (!callOut) { genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2); } else { - // Adjust return regs in to handle case of rem returning r2/r3 oatFlushAllRegs(cUnit); /* Send everything to home location */ - loadWordDisp(cUnit, rSELF, funcOffset, rLR); - loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1); - loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3); + if (checkZero) { + loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3); + loadWordDisp(cUnit, rSELF, funcOffset, rLR); + loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1); + int tReg = oatAllocTemp(cUnit); + newLIR4(cUnit, kThumb2OrrRRRs, tReg, r2, r3, 0); + oatFreeTemp(cUnit, tReg); + genCheck(cUnit, kArmCondEq, mir, kArmThrowDivZero); + } else { + loadWordDisp(cUnit, rSELF, funcOffset, rLR); + loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1); + loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3); + } callRuntimeHelper(cUnit, rLR); + // Adjust return regs in to handle case of rem returning r2/r3 if (retReg == r0) rlResult = oatGetReturnWide(cUnit); else |