[Compiler] use Art indentation standard
First of several CLs to bring code closer to alignment with Art and LLVM
standards. Move to 2-space indenting. Sticking with 80-col line
length (which LLVM apparently also wants). LLVM also prefers camel
case names, so keeping Dalvik convention there as well (for now).
Change-Id: I351ab234e640678d97747377cccdd6df0a770f4a
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 5451d57..5252b49 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -31,8 +31,8 @@
/* Return the position of an ssa name within the argument list */
int inPosition(CompilationUnit* cUnit, int sReg)
{
- int vReg = SRegToVReg(cUnit, sReg);
- return vReg - cUnit->numRegs;
+ int vReg = SRegToVReg(cUnit, sReg);
+ return vReg - cUnit->numRegs;
}
/*
@@ -42,27 +42,27 @@
*/
RegLocation argLoc(CompilationUnit* cUnit, RegLocation loc)
{
- int argNum = inPosition(cUnit, loc.sRegLow);
- if (loc.wide) {
- if (argNum == 2) {
- // Bad case - half in register, half in frame. Just punt
- loc.location = kLocInvalid;
- } else if (argNum < 2) {
- loc.lowReg = rARG1 + argNum;
- loc.highReg = loc.lowReg + 1;
- loc.location = kLocPhysReg;
- } else {
- loc.location = kLocDalvikFrame;
- }
+ int argNum = inPosition(cUnit, loc.sRegLow);
+ if (loc.wide) {
+ if (argNum == 2) {
+ // Bad case - half in register, half in frame. Just punt
+ loc.location = kLocInvalid;
+ } else if (argNum < 2) {
+ loc.lowReg = rARG1 + argNum;
+ loc.highReg = loc.lowReg + 1;
+ loc.location = kLocPhysReg;
} else {
- if (argNum < 3) {
- loc.lowReg = rARG1 + argNum;
- loc.location = kLocPhysReg;
- } else {
- loc.location = kLocDalvikFrame;
- }
+ loc.location = kLocDalvikFrame;
}
- return loc;
+ } else {
+ if (argNum < 3) {
+ loc.lowReg = rARG1 + argNum;
+ loc.location = kLocPhysReg;
+ } else {
+ loc.location = kLocDalvikFrame;
+ }
+ }
+ return loc;
}
/*
@@ -72,243 +72,241 @@
*/
RegLocation loadArg(CompilationUnit* cUnit, RegLocation loc)
{
- if (loc.location == kLocDalvikFrame) {
- int start = (inPosition(cUnit, loc.sRegLow) + 1) * sizeof(uint32_t);
- loc.lowReg = oatAllocTemp(cUnit);
- loadWordDisp(cUnit, rSP, start, loc.lowReg);
- if (loc.wide) {
- loc.highReg = oatAllocTemp(cUnit);
- loadWordDisp(cUnit, rSP, start + sizeof(uint32_t), loc.highReg);
- }
- loc.location = kLocPhysReg;
+ if (loc.location == kLocDalvikFrame) {
+ int start = (inPosition(cUnit, loc.sRegLow) + 1) * sizeof(uint32_t);
+ loc.lowReg = oatAllocTemp(cUnit);
+ loadWordDisp(cUnit, rSP, start, loc.lowReg);
+ if (loc.wide) {
+ loc.highReg = oatAllocTemp(cUnit);
+ loadWordDisp(cUnit, rSP, start + sizeof(uint32_t), loc.highReg);
}
- return loc;
+ loc.location = kLocPhysReg;
+ }
+ return loc;
}
/* Lock any referenced arguments that arrive in registers */
void lockLiveArgs(CompilationUnit* cUnit, MIR* mir)
{
- int firstIn = cUnit->numRegs;
- const int numArgRegs = 3; // TODO: generalize & move to RegUtil.cc
- for (int i = 0; i < mir->ssaRep->numUses; i++) {
- int vReg = SRegToVReg(cUnit, mir->ssaRep->uses[i]);
- int inPosition = vReg - firstIn;
- if (inPosition < numArgRegs) {
- oatLockTemp(cUnit, rARG1 + inPosition);
- }
+ int firstIn = cUnit->numRegs;
+ const int numArgRegs = 3; // TODO: generalize & move to RegUtil.cc
+ for (int i = 0; i < mir->ssaRep->numUses; i++) {
+ int vReg = SRegToVReg(cUnit, mir->ssaRep->uses[i]);
+ int inPosition = vReg - firstIn;
+ if (inPosition < numArgRegs) {
+ oatLockTemp(cUnit, rARG1 + inPosition);
}
+ }
}
/* Find the next MIR, which may be in a following basic block */
MIR* getNextMir(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir)
{
- BasicBlock* bb = *pBb;
- MIR* origMir = mir;
- while (bb != NULL) {
- if (mir != NULL) {
- mir = mir->next;
- }
- if (mir != NULL) {
- return mir;
- } else {
- bb = bb->fallThrough;
- *pBb = bb;
- if (bb) {
- mir = bb->firstMIRInsn;
- if (mir != NULL) {
- return mir;
- }
- }
- }
+ BasicBlock* bb = *pBb;
+ MIR* origMir = mir;
+ while (bb != NULL) {
+ if (mir != NULL) {
+ mir = mir->next;
}
- return origMir;
+ if (mir != NULL) {
+ return mir;
+ } else {
+ bb = bb->fallThrough;
+ *pBb = bb;
+ if (bb) {
+ mir = bb->firstMIRInsn;
+ if (mir != NULL) {
+ return mir;
+ }
+ }
+ }
+ }
+ return origMir;
}
/* Used for the "printMe" listing */
void genPrintLabel(CompilationUnit *cUnit, MIR* mir)
{
- LIR* boundaryLIR;
- /* Mark the beginning of a Dalvik instruction for line tracking */
- char* instStr = cUnit->printMe ?
- oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
- boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
- (intptr_t) instStr);
- cUnit->boundaryMap.Put(mir->offset, boundaryLIR);
- /* Don't generate the SSA annotation unless verbose mode is on */
- if (cUnit->printMe && mir->ssaRep) {
- char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
- newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
- }
+ LIR* boundaryLIR;
+ /* Mark the beginning of a Dalvik instruction for line tracking */
+ char* instStr = cUnit->printMe ?
+ oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
+ boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
+ (intptr_t) instStr);
+ cUnit->boundaryMap.Put(mir->offset, boundaryLIR);
+ /* Don't generate the SSA annotation unless verbose mode is on */
+ if (cUnit->printMe && mir->ssaRep) {
+ char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
+ newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
+ }
}
MIR* specialIGet(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
OpSize size, bool longOrDouble, bool isObject)
{
- int fieldOffset;
- bool isVolatile;
- uint32_t fieldIdx = mir->dalvikInsn.vC;
- bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile,
- false);
- if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
- return NULL;
- }
- RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
- lockLiveArgs(cUnit, mir);
- rlObj = argLoc(cUnit, rlObj);
- RegLocation rlDest;
- if (longOrDouble) {
- rlDest = oatGetReturnWide(cUnit, false);
- } else {
- rlDest = oatGetReturn(cUnit, false);
- }
- // Point of no return - no aborts after this
- genPrintLabel(cUnit, mir);
- rlObj = loadArg(cUnit, rlObj);
- genIGet(cUnit, mir, size, rlDest, rlObj, longOrDouble, isObject);
- return getNextMir(cUnit, bb, mir);
+ int fieldOffset;
+ bool isVolatile;
+ uint32_t fieldIdx = mir->dalvikInsn.vC;
+ bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
+ if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+ return NULL;
+ }
+ RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
+ lockLiveArgs(cUnit, mir);
+ rlObj = argLoc(cUnit, rlObj);
+ RegLocation rlDest;
+ if (longOrDouble) {
+ rlDest = oatGetReturnWide(cUnit, false);
+ } else {
+ rlDest = oatGetReturn(cUnit, false);
+ }
+ // Point of no return - no aborts after this
+ genPrintLabel(cUnit, mir);
+ rlObj = loadArg(cUnit, rlObj);
+ genIGet(cUnit, mir, size, rlDest, rlObj, longOrDouble, isObject);
+ return getNextMir(cUnit, bb, mir);
}
MIR* specialIPut(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
OpSize size, bool longOrDouble, bool isObject)
{
- int fieldOffset;
- bool isVolatile;
- uint32_t fieldIdx = mir->dalvikInsn.vC;
- bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile,
- false);
- if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
- return NULL;
- }
- RegLocation rlSrc;
- RegLocation rlObj;
- lockLiveArgs(cUnit, mir);
- if (longOrDouble) {
- rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
- rlObj = oatGetSrc(cUnit, mir, 2);
- } else {
- rlSrc = oatGetSrc(cUnit, mir, 0);
- rlObj = oatGetSrc(cUnit, mir, 1);
- }
- rlSrc = argLoc(cUnit, rlSrc);
- rlObj = argLoc(cUnit, rlObj);
- // Reject if source is split across registers & frame
- if (rlObj.location == kLocInvalid) {
- oatResetRegPool(cUnit);
- return NULL;
- }
- // Point of no return - no aborts after this
- genPrintLabel(cUnit, mir);
- rlObj = loadArg(cUnit, rlObj);
- rlSrc = loadArg(cUnit, rlSrc);
- genIPut(cUnit, mir, size, rlSrc, rlObj, longOrDouble, isObject);
- return getNextMir(cUnit, bb, mir);
+ int fieldOffset;
+ bool isVolatile;
+ uint32_t fieldIdx = mir->dalvikInsn.vC;
+ bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
+ if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+ return NULL;
+ }
+ RegLocation rlSrc;
+ RegLocation rlObj;
+ lockLiveArgs(cUnit, mir);
+ if (longOrDouble) {
+ rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ rlObj = oatGetSrc(cUnit, mir, 2);
+ } else {
+ rlSrc = oatGetSrc(cUnit, mir, 0);
+ rlObj = oatGetSrc(cUnit, mir, 1);
+ }
+ rlSrc = argLoc(cUnit, rlSrc);
+ rlObj = argLoc(cUnit, rlObj);
+ // Reject if source is split across registers & frame
+ if (rlObj.location == kLocInvalid) {
+ oatResetRegPool(cUnit);
+ return NULL;
+ }
+ // Point of no return - no aborts after this
+ genPrintLabel(cUnit, mir);
+ rlObj = loadArg(cUnit, rlObj);
+ rlSrc = loadArg(cUnit, rlSrc);
+ genIPut(cUnit, mir, size, rlSrc, rlObj, longOrDouble, isObject);
+ return getNextMir(cUnit, bb, mir);
}
MIR* specialIdentity(CompilationUnit* cUnit, MIR* mir)
{
- RegLocation rlSrc;
- RegLocation rlDest;
- bool wide = (mir->ssaRep->numUses == 2);
- if (wide) {
- rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
- rlDest = oatGetReturnWide(cUnit, false);
- } else {
- rlSrc = oatGetSrc(cUnit, mir, 0);
- rlDest = oatGetReturn(cUnit, false);
- }
- lockLiveArgs(cUnit, mir);
- rlSrc = argLoc(cUnit, rlSrc);
- if (rlSrc.location == kLocInvalid) {
- oatResetRegPool(cUnit);
- return NULL;
- }
- // Point of no return - no aborts after this
- genPrintLabel(cUnit, mir);
- rlSrc = loadArg(cUnit, rlSrc);
- if (wide) {
- storeValueWide(cUnit, rlDest, rlSrc);
- } else {
- storeValue(cUnit, rlDest, rlSrc);
- }
- return mir;
+ RegLocation rlSrc;
+ RegLocation rlDest;
+ bool wide = (mir->ssaRep->numUses == 2);
+ if (wide) {
+ rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+ rlDest = oatGetReturnWide(cUnit, false);
+ } else {
+ rlSrc = oatGetSrc(cUnit, mir, 0);
+ rlDest = oatGetReturn(cUnit, false);
+ }
+ lockLiveArgs(cUnit, mir);
+ rlSrc = argLoc(cUnit, rlSrc);
+ if (rlSrc.location == kLocInvalid) {
+ oatResetRegPool(cUnit);
+ return NULL;
+ }
+ // Point of no return - no aborts after this
+ genPrintLabel(cUnit, mir);
+ rlSrc = loadArg(cUnit, rlSrc);
+ if (wide) {
+ storeValueWide(cUnit, rlDest, rlSrc);
+ } else {
+ storeValue(cUnit, rlDest, rlSrc);
+ }
+ return mir;
}
/*
* Special-case code genration for simple non-throwing leaf methods.
*/
void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
- SpecialCaseHandler specialCase)
+ SpecialCaseHandler specialCase)
{
cUnit->currentDalvikOffset = mir->offset;
MIR* nextMir = NULL;
switch (specialCase) {
- case kNullMethod:
- DCHECK(mir->dalvikInsn.opcode == Instruction::RETURN_VOID);
- nextMir = mir;
- break;
- case kConstFunction:
- genPrintLabel(cUnit, mir);
- loadConstant(cUnit, rRET0, mir->dalvikInsn.vB);
- nextMir = getNextMir(cUnit, &bb, mir);
- break;
- case kIGet:
- nextMir = specialIGet(cUnit, &bb, mir, kWord, false, false);
- break;
- case kIGetBoolean:
- case kIGetByte:
- nextMir = specialIGet(cUnit, &bb, mir, kUnsignedByte, false, false);
- break;
- case kIGetObject:
- nextMir = specialIGet(cUnit, &bb, mir, kWord, false, true);
- break;
- case kIGetChar:
- nextMir = specialIGet(cUnit, &bb, mir, kUnsignedHalf, false, false);
- break;
- case kIGetShort:
- nextMir = specialIGet(cUnit, &bb, mir, kSignedHalf, false, false);
- break;
- case kIGetWide:
- nextMir = specialIGet(cUnit, &bb, mir, kLong, true, false);
- break;
- case kIPut:
- nextMir = specialIPut(cUnit, &bb, mir, kWord, false, false);
- break;
- case kIPutBoolean:
- case kIPutByte:
- nextMir = specialIPut(cUnit, &bb, mir, kUnsignedByte, false, false);
- break;
- case kIPutObject:
- nextMir = specialIPut(cUnit, &bb, mir, kWord, false, true);
- break;
- case kIPutChar:
- nextMir = specialIPut(cUnit, &bb, mir, kUnsignedHalf, false, false);
- break;
- case kIPutShort:
- nextMir = specialIPut(cUnit, &bb, mir, kSignedHalf, false, false);
- break;
- case kIPutWide:
- nextMir = specialIPut(cUnit, &bb, mir, kLong, true, false);
- break;
- case kIdentity:
- nextMir = specialIdentity(cUnit, mir);
- break;
- default:
- return;
+ case kNullMethod:
+ DCHECK(mir->dalvikInsn.opcode == Instruction::RETURN_VOID);
+ nextMir = mir;
+ break;
+ case kConstFunction:
+ genPrintLabel(cUnit, mir);
+ loadConstant(cUnit, rRET0, mir->dalvikInsn.vB);
+ nextMir = getNextMir(cUnit, &bb, mir);
+ break;
+ case kIGet:
+ nextMir = specialIGet(cUnit, &bb, mir, kWord, false, false);
+ break;
+ case kIGetBoolean:
+ case kIGetByte:
+ nextMir = specialIGet(cUnit, &bb, mir, kUnsignedByte, false, false);
+ break;
+ case kIGetObject:
+ nextMir = specialIGet(cUnit, &bb, mir, kWord, false, true);
+ break;
+ case kIGetChar:
+ nextMir = specialIGet(cUnit, &bb, mir, kUnsignedHalf, false, false);
+ break;
+ case kIGetShort:
+ nextMir = specialIGet(cUnit, &bb, mir, kSignedHalf, false, false);
+ break;
+ case kIGetWide:
+ nextMir = specialIGet(cUnit, &bb, mir, kLong, true, false);
+ break;
+ case kIPut:
+ nextMir = specialIPut(cUnit, &bb, mir, kWord, false, false);
+ break;
+ case kIPutBoolean:
+ case kIPutByte:
+ nextMir = specialIPut(cUnit, &bb, mir, kUnsignedByte, false, false);
+ break;
+ case kIPutObject:
+ nextMir = specialIPut(cUnit, &bb, mir, kWord, false, true);
+ break;
+ case kIPutChar:
+ nextMir = specialIPut(cUnit, &bb, mir, kUnsignedHalf, false, false);
+ break;
+ case kIPutShort:
+ nextMir = specialIPut(cUnit, &bb, mir, kSignedHalf, false, false);
+ break;
+ case kIPutWide:
+ nextMir = specialIPut(cUnit, &bb, mir, kLong, true, false);
+ break;
+ case kIdentity:
+ nextMir = specialIdentity(cUnit, mir);
+ break;
+ default:
+ return;
}
if (nextMir != NULL) {
- cUnit->currentDalvikOffset = nextMir->offset;
- if (specialCase != kIdentity) {
- genPrintLabel(cUnit, nextMir);
- }
- newLIR1(cUnit, kThumbBx, rLR);
- cUnit->coreSpillMask = 0;
- cUnit->numCoreSpills = 0;
- cUnit->fpSpillMask = 0;
- cUnit->numFPSpills = 0;
- cUnit->frameSize = 0;
- cUnit->coreVmapTable.clear();
- cUnit->fpVmapTable.clear();
+ cUnit->currentDalvikOffset = nextMir->offset;
+ if (specialCase != kIdentity) {
+ genPrintLabel(cUnit, nextMir);
}
+ newLIR1(cUnit, kThumbBx, rLR);
+ cUnit->coreSpillMask = 0;
+ cUnit->numCoreSpills = 0;
+ cUnit->fpSpillMask = 0;
+ cUnit->numFPSpills = 0;
+ cUnit->frameSize = 0;
+ cUnit->coreVmapTable.clear();
+ cUnit->fpVmapTable.clear();
+ }
}
/*
@@ -323,30 +321,30 @@
*/
LIR* opIT(CompilationUnit* cUnit, ArmConditionCode code, const char* guide)
{
- int mask;
- int condBit = code & 1;
- int altBit = condBit ^ 1;
- int mask3 = 0;
- int mask2 = 0;
- int mask1 = 0;
+ int mask;
+ int condBit = code & 1;
+ int altBit = condBit ^ 1;
+ int mask3 = 0;
+ int mask2 = 0;
+ int mask1 = 0;
- //Note: case fallthroughs intentional
- switch (strlen(guide)) {
- case 3:
- mask1 = (guide[2] == 'T') ? condBit : altBit;
- case 2:
- mask2 = (guide[1] == 'T') ? condBit : altBit;
- case 1:
- mask3 = (guide[0] == 'T') ? condBit : altBit;
- break;
- case 0:
- break;
- default:
- LOG(FATAL) << "OAT: bad case in opIT";
- }
- mask = (mask3 << 3) | (mask2 << 2) | (mask1 << 1) |
- (1 << (3 - strlen(guide)));
- return newLIR2(cUnit, kThumb2It, code, mask);
+ //Note: case fallthroughs intentional
+ switch (strlen(guide)) {
+ case 3:
+ mask1 = (guide[2] == 'T') ? condBit : altBit;
+ case 2:
+ mask2 = (guide[1] == 'T') ? condBit : altBit;
+ case 1:
+ mask3 = (guide[0] == 'T') ? condBit : altBit;
+ break;
+ case 0:
+ break;
+ default:
+ LOG(FATAL) << "OAT: bad case in opIT";
+ }
+ mask = (mask3 << 3) | (mask2 << 2) | (mask1 << 1) |
+ (1 << (3 - strlen(guide)));
+ return newLIR2(cUnit, kThumb2It, code, mask);
}
/*
@@ -371,97 +369,95 @@
void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
LIR* labelList)
{
- const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
- if (cUnit->printMe) {
- dumpSparseSwitchTable(table);
- }
- // Add the table to the list - we'll process it later
- SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
- true, kAllocData);
- tabRec->table = table;
- tabRec->vaddr = mir->offset;
- int size = table[1];
- tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
- kAllocLIR);
- oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
+ const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+ if (cUnit->printMe) {
+ dumpSparseSwitchTable(table);
+ }
+ // Add the table to the list - we'll process it later
+ SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
+ true, kAllocData);
+ tabRec->table = table;
+ tabRec->vaddr = mir->offset;
+ int size = table[1];
+ tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
+ oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
- // Get the switch value
- rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- int rBase = oatAllocTemp(cUnit);
- /* Allocate key and disp temps */
- int rKey = oatAllocTemp(cUnit);
- int rDisp = oatAllocTemp(cUnit);
- // Make sure rKey's register number is less than rDisp's number for ldmia
- if (rKey > rDisp) {
- int tmp = rDisp;
- rDisp = rKey;
- rKey = tmp;
- }
- // Materialize a pointer to the switch table
- newLIR3(cUnit, kThumb2Adr, rBase, 0, (intptr_t)tabRec);
- // Set up rIdx
- int rIdx = oatAllocTemp(cUnit);
- loadConstant(cUnit, rIdx, size);
- // Establish loop branch target
- LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
- // Load next key/disp
- newLIR2(cUnit, kThumb2LdmiaWB, rBase, (1 << rKey) | (1 << rDisp));
- opRegReg(cUnit, kOpCmp, rKey, rlSrc.lowReg);
- // Go if match. NOTE: No instruction set switch here - must stay Thumb2
- opIT(cUnit, kArmCondEq, "");
- LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
- tabRec->anchor = switchBranch;
- // Needs to use setflags encoding here
- newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
- opCondBranch(cUnit, kCondNe, target);
+ // Get the switch value
+ rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+ int rBase = oatAllocTemp(cUnit);
+ /* Allocate key and disp temps */
+ int rKey = oatAllocTemp(cUnit);
+ int rDisp = oatAllocTemp(cUnit);
+ // Make sure rKey's register number is less than rDisp's number for ldmia
+ if (rKey > rDisp) {
+ int tmp = rDisp;
+ rDisp = rKey;
+ rKey = tmp;
+ }
+ // Materialize a pointer to the switch table
+ newLIR3(cUnit, kThumb2Adr, rBase, 0, (intptr_t)tabRec);
+ // Set up rIdx
+ int rIdx = oatAllocTemp(cUnit);
+ loadConstant(cUnit, rIdx, size);
+ // Establish loop branch target
+ LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+ // Load next key/disp
+ newLIR2(cUnit, kThumb2LdmiaWB, rBase, (1 << rKey) | (1 << rDisp));
+ opRegReg(cUnit, kOpCmp, rKey, rlSrc.lowReg);
+ // Go if match. NOTE: No instruction set switch here - must stay Thumb2
+ opIT(cUnit, kArmCondEq, "");
+ LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
+ tabRec->anchor = switchBranch;
+ // Needs to use setflags encoding here
+ newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
+ opCondBranch(cUnit, kCondNe, target);
}
void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
- const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
- if (cUnit->printMe) {
- dumpPackedSwitchTable(table);
- }
- // Add the table to the list - we'll process it later
- SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
- true, kAllocData);
- tabRec->table = table;
- tabRec->vaddr = mir->offset;
- int size = table[1];
- tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
- kAllocLIR);
- oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
+ const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+ if (cUnit->printMe) {
+ dumpPackedSwitchTable(table);
+ }
+ // Add the table to the list - we'll process it later
+ SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
+ true, kAllocData);
+ tabRec->table = table;
+ tabRec->vaddr = mir->offset;
+ int size = table[1];
+ tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
+ oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
- // Get the switch value
- rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- int tableBase = oatAllocTemp(cUnit);
- // Materialize a pointer to the switch table
- newLIR3(cUnit, kThumb2Adr, tableBase, 0, (intptr_t)tabRec);
- int lowKey = s4FromSwitchData(&table[2]);
- int keyReg;
- // Remove the bias, if necessary
- if (lowKey == 0) {
- keyReg = rlSrc.lowReg;
- } else {
- keyReg = oatAllocTemp(cUnit);
- opRegRegImm(cUnit, kOpSub, keyReg, rlSrc.lowReg, lowKey);
- }
- // Bounds check - if < 0 or >= size continue following switch
- opRegImm(cUnit, kOpCmp, keyReg, size-1);
- LIR* branchOver = opCondBranch(cUnit, kCondHi, NULL);
+ // Get the switch value
+ rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+ int tableBase = oatAllocTemp(cUnit);
+ // Materialize a pointer to the switch table
+ newLIR3(cUnit, kThumb2Adr, tableBase, 0, (intptr_t)tabRec);
+ int lowKey = s4FromSwitchData(&table[2]);
+ int keyReg;
+ // Remove the bias, if necessary
+ if (lowKey == 0) {
+ keyReg = rlSrc.lowReg;
+ } else {
+ keyReg = oatAllocTemp(cUnit);
+ opRegRegImm(cUnit, kOpSub, keyReg, rlSrc.lowReg, lowKey);
+ }
+ // Bounds check - if < 0 or >= size continue following switch
+ opRegImm(cUnit, kOpCmp, keyReg, size-1);
+ LIR* branchOver = opCondBranch(cUnit, kCondHi, NULL);
- // Load the displacement from the switch table
- int dispReg = oatAllocTemp(cUnit);
- loadBaseIndexed(cUnit, tableBase, keyReg, dispReg, 2, kWord);
+ // Load the displacement from the switch table
+ int dispReg = oatAllocTemp(cUnit);
+ loadBaseIndexed(cUnit, tableBase, keyReg, dispReg, 2, kWord);
- // ..and go! NOTE: No instruction set switch here - must stay Thumb2
- LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
- tabRec->anchor = switchBranch;
+ // ..and go! NOTE: No instruction set switch here - must stay Thumb2
+ LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
+ tabRec->anchor = switchBranch;
- /* branchOver target here */
- LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
- branchOver->target = (LIR*)target;
+ /* branchOver target here */
+ LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+ branchOver->target = (LIR*)target;
}
/*
@@ -476,46 +472,46 @@
*/
void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
- const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
- // Add the table to the list - we'll process it later
- FillArrayData *tabRec = (FillArrayData *)
- oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
- tabRec->table = table;
- tabRec->vaddr = mir->offset;
- u2 width = tabRec->table[1];
- u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
- tabRec->size = (size * width) + 8;
+ const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+ // Add the table to the list - we'll process it later
+ FillArrayData *tabRec = (FillArrayData *)
+ oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
+ tabRec->table = table;
+ tabRec->vaddr = mir->offset;
+ u2 width = tabRec->table[1];
+ u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
+ tabRec->size = (size * width) + 8;
- oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec);
+ oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec);
- // Making a call - use explicit registers
- oatFlushAllRegs(cUnit); /* Everything to home location */
- loadValueDirectFixed(cUnit, rlSrc, r0);
- loadWordDisp(cUnit, rSELF,
- ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode), rLR);
- // Materialize a pointer to the fill data image
- newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
- oatClobberCalleeSave(cUnit);
- opReg(cUnit, kOpBlx, rLR);
+ // Making a call - use explicit registers
+ oatFlushAllRegs(cUnit); /* Everything to home location */
+ loadValueDirectFixed(cUnit, rlSrc, r0);
+ loadWordDisp(cUnit, rSELF, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode),
+ rLR);
+ // Materialize a pointer to the fill data image
+ newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
+ oatClobberCalleeSave(cUnit);
+ opReg(cUnit, kOpBlx, rLR);
}
void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
{
- RegLocation rlResult;
- rlSrc = loadValue(cUnit, rlSrc, kFPReg);
- rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
- newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg);
- storeValue(cUnit, rlDest, rlResult);
+ RegLocation rlResult;
+ rlSrc = loadValue(cUnit, rlSrc, kFPReg);
+ rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
+ newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg);
+ storeValue(cUnit, rlDest, rlResult);
}
void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
{
- RegLocation rlResult;
- rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
- rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
- newLIR2(cUnit, kThumb2Vnegd, S2D(rlResult.lowReg, rlResult.highReg),
- S2D(rlSrc.lowReg, rlSrc.highReg));
- storeValueWide(cUnit, rlDest, rlResult);
+ RegLocation rlResult;
+ rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
+ rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
+ newLIR2(cUnit, kThumb2Vnegd, S2D(rlResult.lowReg, rlResult.highReg),
+ S2D(rlSrc.lowReg, rlSrc.highReg));
+ storeValueWide(cUnit, rlDest, rlResult);
}
/*
@@ -546,31 +542,30 @@
*/
void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
- oatFlushAllRegs(cUnit);
- DCHECK_EQ(LW_SHAPE_THIN, 0);
- loadValueDirectFixed(cUnit, rlSrc, r0); // Get obj
- oatLockCallTemps(cUnit); // Prepare for explicit register usage
- genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
- loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
- newLIR3(cUnit, kThumb2Ldrex, r1, r0,
- Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
- // Align owner
- opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
- // Is lock unheld on lock or held by us (==threadId) on unlock?
- newLIR4(cUnit, kThumb2Bfi, r2, r1, 0, LW_LOCK_OWNER_SHIFT - 1);
- newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
- opRegImm(cUnit, kOpCmp, r1, 0);
- opIT(cUnit, kArmCondEq, "");
- newLIR4(cUnit, kThumb2Strex, r1, r2, r0,
- Object::MonitorOffset().Int32Value() >> 2);
- opRegImm(cUnit, kOpCmp, r1, 0);
- opIT(cUnit, kArmCondNe, "T");
- // Go expensive route - artLockObjectFromCode(self, obj);
- loadWordDisp(cUnit, rSELF, ENTRYPOINT_OFFSET(pLockObjectFromCode),
- rLR);
- oatClobberCalleeSave(cUnit);
- opReg(cUnit, kOpBlx, rLR);
- oatGenMemBarrier(cUnit, kSY);
+ oatFlushAllRegs(cUnit);
+ DCHECK_EQ(LW_SHAPE_THIN, 0);
+ loadValueDirectFixed(cUnit, rlSrc, r0); // Get obj
+ oatLockCallTemps(cUnit); // Prepare for explicit register usage
+ genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
+ loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
+ newLIR3(cUnit, kThumb2Ldrex, r1, r0,
+ Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
+ // Align owner
+ opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
+ // Is lock unheld on lock or held by us (==threadId) on unlock?
+ newLIR4(cUnit, kThumb2Bfi, r2, r1, 0, LW_LOCK_OWNER_SHIFT - 1);
+ newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
+ opRegImm(cUnit, kOpCmp, r1, 0);
+ opIT(cUnit, kArmCondEq, "");
+ newLIR4(cUnit, kThumb2Strex, r1, r2, r0,
+ Object::MonitorOffset().Int32Value() >> 2);
+ opRegImm(cUnit, kOpCmp, r1, 0);
+ opIT(cUnit, kArmCondNe, "T");
+ // Go expensive route - artLockObjectFromCode(self, obj);
+ loadWordDisp(cUnit, rSELF, ENTRYPOINT_OFFSET(pLockObjectFromCode), rLR);
+ oatClobberCalleeSave(cUnit);
+ opReg(cUnit, kOpBlx, rLR);
+ oatGenMemBarrier(cUnit, kSY);
}
/*
@@ -581,27 +576,27 @@
*/
void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
- DCHECK_EQ(LW_SHAPE_THIN, 0);
- oatFlushAllRegs(cUnit);
- loadValueDirectFixed(cUnit, rlSrc, r0); // Get obj
- oatLockCallTemps(cUnit); // Prepare for explicit register usage
- genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
- loadWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
- loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
- // Is lock unheld on lock or held by us (==threadId) on unlock?
- opRegRegImm(cUnit, kOpAnd, r3, r1, (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
- // Align owner
- opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
- newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
- opRegReg(cUnit, kOpSub, r1, r2);
- opIT(cUnit, kArmCondEq, "EE");
- storeWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r3);
- // Go expensive route - UnlockObjectFromCode(obj);
- loadWordDisp(cUnit, rSELF, ENTRYPOINT_OFFSET(pUnlockObjectFromCode),
- rLR);
- oatClobberCalleeSave(cUnit);
- opReg(cUnit, kOpBlx, rLR);
- oatGenMemBarrier(cUnit, kSY);
+ DCHECK_EQ(LW_SHAPE_THIN, 0);
+ oatFlushAllRegs(cUnit);
+ loadValueDirectFixed(cUnit, rlSrc, r0); // Get obj
+ oatLockCallTemps(cUnit); // Prepare for explicit register usage
+ genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
+ loadWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
+ loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
+ // Is lock unheld on lock or held by us (==threadId) on unlock?
+ opRegRegImm(cUnit, kOpAnd, r3, r1,
+ (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
+ // Align owner
+ opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
+ newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
+ opRegReg(cUnit, kOpSub, r1, r2);
+ opIT(cUnit, kArmCondEq, "EE");
+ storeWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r3);
+ // Go expensive route - UnlockObjectFromCode(obj);
+ loadWordDisp(cUnit, rSELF, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rLR);
+ oatClobberCalleeSave(cUnit);
+ opReg(cUnit, kOpBlx, rLR);
+ oatGenMemBarrier(cUnit, kSY);
}
/*
@@ -620,83 +615,83 @@
* done:
*/
void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
- RegLocation rlSrc1, RegLocation rlSrc2)
+ RegLocation rlSrc1, RegLocation rlSrc2)
{
- LIR* target1;
- LIR* target2;
- rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
- rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
- int tReg = oatAllocTemp(cUnit);
- loadConstant(cUnit, tReg, -1);
- opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
- LIR* branch1 = opCondBranch(cUnit, kCondLt, NULL);
- LIR* branch2 = opCondBranch(cUnit, kCondGt, NULL);
- opRegRegReg(cUnit, kOpSub, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
- LIR* branch3 = opCondBranch(cUnit, kCondEq, NULL);
+ LIR* target1;
+ LIR* target2;
+ rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+ rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+ int tReg = oatAllocTemp(cUnit);
+ loadConstant(cUnit, tReg, -1);
+ opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
+ LIR* branch1 = opCondBranch(cUnit, kCondLt, NULL);
+ LIR* branch2 = opCondBranch(cUnit, kCondGt, NULL);
+ opRegRegReg(cUnit, kOpSub, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
+ LIR* branch3 = opCondBranch(cUnit, kCondEq, NULL);
- opIT(cUnit, kArmCondHi, "E");
- newLIR2(cUnit, kThumb2MovImmShift, tReg, modifiedImmediate(-1));
- loadConstant(cUnit, tReg, 1);
- genBarrier(cUnit);
+ opIT(cUnit, kArmCondHi, "E");
+ newLIR2(cUnit, kThumb2MovImmShift, tReg, modifiedImmediate(-1));
+ loadConstant(cUnit, tReg, 1);
+ genBarrier(cUnit);
- target2 = newLIR0(cUnit, kPseudoTargetLabel);
- opRegReg(cUnit, kOpNeg, tReg, tReg);
+ target2 = newLIR0(cUnit, kPseudoTargetLabel);
+ opRegReg(cUnit, kOpNeg, tReg, tReg);
- target1 = newLIR0(cUnit, kPseudoTargetLabel);
+ target1 = newLIR0(cUnit, kPseudoTargetLabel);
- RegLocation rlTemp = LOC_C_RETURN; // Just using as template, will change
- rlTemp.lowReg = tReg;
- storeValue(cUnit, rlDest, rlTemp);
- oatFreeTemp(cUnit, tReg);
+ RegLocation rlTemp = LOC_C_RETURN; // Just using as template, will change
+ rlTemp.lowReg = tReg;
+ storeValue(cUnit, rlDest, rlTemp);
+ oatFreeTemp(cUnit, tReg);
- branch1->target = (LIR*)target1;
- branch2->target = (LIR*)target2;
- branch3->target = branch1->target;
+ branch1->target = (LIR*)target1;
+ branch2->target = (LIR*)target2;
+ branch3->target = branch1->target;
}
void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
{
- LIR* labelList = (LIR*)cUnit->blockLabelList;
- LIR* taken = &labelList[bb->taken->id];
- LIR* notTaken = &labelList[bb->fallThrough->id];
- RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0, 1);
- RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2, 3);
- rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
- rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
- ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
- opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
- switch(ccode) {
- case kCondEq:
- opCondBranch(cUnit, kCondNe, notTaken);
- break;
- case kCondNe:
- opCondBranch(cUnit, kCondNe, taken);
- break;
- case kCondLt:
- opCondBranch(cUnit, kCondLt, taken);
- opCondBranch(cUnit, kCondGt, notTaken);
- ccode = kCondCc;
- break;
- case kCondLe:
- opCondBranch(cUnit, kCondLt, taken);
- opCondBranch(cUnit, kCondGt, notTaken);
- ccode = kCondLs;
- break;
- case kCondGt:
- opCondBranch(cUnit, kCondGt, taken);
- opCondBranch(cUnit, kCondLt, notTaken);
- ccode = kCondHi;
- break;
- case kCondGe:
- opCondBranch(cUnit, kCondGt, taken);
- opCondBranch(cUnit, kCondLt, notTaken);
- ccode = kCondCs;
- break;
- default:
- LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
- }
- opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
- opCondBranch(cUnit, ccode, taken);
+ LIR* labelList = (LIR*)cUnit->blockLabelList;
+ LIR* taken = &labelList[bb->taken->id];
+ LIR* notTaken = &labelList[bb->fallThrough->id];
+ RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0, 1);
+ RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2, 3);
+ rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+ rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+ ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
+ opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
+ switch(ccode) {
+ case kCondEq:
+ opCondBranch(cUnit, kCondNe, notTaken);
+ break;
+ case kCondNe:
+ opCondBranch(cUnit, kCondNe, taken);
+ break;
+ case kCondLt:
+ opCondBranch(cUnit, kCondLt, taken);
+ opCondBranch(cUnit, kCondGt, notTaken);
+ ccode = kCondCc;
+ break;
+ case kCondLe:
+ opCondBranch(cUnit, kCondLt, taken);
+ opCondBranch(cUnit, kCondGt, notTaken);
+ ccode = kCondLs;
+ break;
+ case kCondGt:
+ opCondBranch(cUnit, kCondGt, taken);
+ opCondBranch(cUnit, kCondLt, notTaken);
+ ccode = kCondHi;
+ break;
+ case kCondGe:
+ opCondBranch(cUnit, kCondGt, taken);
+ opCondBranch(cUnit, kCondLt, notTaken);
+ ccode = kCondCs;
+ break;
+ default:
+ LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
+ }
+ opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
+ opCondBranch(cUnit, ccode, taken);
}
/*
@@ -704,166 +699,165 @@
* is responsible for setting branch target field.
*/
LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
- int checkValue, LIR* target)
+ int checkValue, LIR* target)
{
- LIR* branch;
- int modImm;
- ArmConditionCode armCond = oatArmConditionEncoding(cond);
- if ((LOWREG(reg)) && (checkValue == 0) &&
- ((armCond == kArmCondEq) || (armCond == kArmCondNe))) {
- branch = newLIR2(cUnit,
- (armCond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
- reg, 0);
+ LIR* branch;
+ int modImm;
+ ArmConditionCode armCond = oatArmConditionEncoding(cond);
+ if ((LOWREG(reg)) && (checkValue == 0) &&
+ ((armCond == kArmCondEq) || (armCond == kArmCondNe))) {
+ branch = newLIR2(cUnit, (armCond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
+ reg, 0);
+ } else {
+ modImm = modifiedImmediate(checkValue);
+ if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) {
+ newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
+ } else if (modImm >= 0) {
+ newLIR2(cUnit, kThumb2CmpRI8, reg, modImm);
} else {
- modImm = modifiedImmediate(checkValue);
- if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) {
- newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
- } else if (modImm >= 0) {
- newLIR2(cUnit, kThumb2CmpRI8, reg, modImm);
- } else {
- int tReg = oatAllocTemp(cUnit);
- loadConstant(cUnit, tReg, checkValue);
- opRegReg(cUnit, kOpCmp, reg, tReg);
- }
- branch = newLIR2(cUnit, kThumbBCond, 0, armCond);
+ int tReg = oatAllocTemp(cUnit);
+ loadConstant(cUnit, tReg, checkValue);
+ opRegReg(cUnit, kOpCmp, reg, tReg);
}
- branch->target = target;
- return branch;
+ branch = newLIR2(cUnit, kThumbBCond, 0, armCond);
+ }
+ branch->target = target;
+ return branch;
}
LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
{
- LIR* res;
- ArmOpcode opcode;
- if (FPREG(rDest) || FPREG(rSrc))
- return fpRegCopy(cUnit, rDest, rSrc);
- if (LOWREG(rDest) && LOWREG(rSrc))
- opcode = kThumbMovRR;
- else if (!LOWREG(rDest) && !LOWREG(rSrc))
- opcode = kThumbMovRR_H2H;
- else if (LOWREG(rDest))
- opcode = kThumbMovRR_H2L;
- else
- opcode = kThumbMovRR_L2H;
- res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
- if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
- res->flags.isNop = true;
- }
- return res;
+ LIR* res;
+ ArmOpcode opcode;
+ if (FPREG(rDest) || FPREG(rSrc))
+ return fpRegCopy(cUnit, rDest, rSrc);
+ if (LOWREG(rDest) && LOWREG(rSrc))
+ opcode = kThumbMovRR;
+ else if (!LOWREG(rDest) && !LOWREG(rSrc))
+ opcode = kThumbMovRR_H2H;
+ else if (LOWREG(rDest))
+ opcode = kThumbMovRR_H2L;
+ else
+ opcode = kThumbMovRR_L2H;
+ res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
+ if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
+ res->flags.isNop = true;
+ }
+ return res;
}
LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
{
- LIR* res = opRegCopyNoInsert(cUnit, rDest, rSrc);
- oatAppendLIR(cUnit, (LIR*)res);
- return res;
+ LIR* res = opRegCopyNoInsert(cUnit, rDest, rSrc);
+ oatAppendLIR(cUnit, (LIR*)res);
+ return res;
}
void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
- int srcLo, int srcHi)
+ int srcLo, int srcHi)
{
- bool destFP = FPREG(destLo) && FPREG(destHi);
- bool srcFP = FPREG(srcLo) && FPREG(srcHi);
- DCHECK_EQ(FPREG(srcLo), FPREG(srcHi));
- DCHECK_EQ(FPREG(destLo), FPREG(destHi));
- if (destFP) {
- if (srcFP) {
- opRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
- } else {
- newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi);
- }
+ bool destFP = FPREG(destLo) && FPREG(destHi);
+ bool srcFP = FPREG(srcLo) && FPREG(srcHi);
+ DCHECK_EQ(FPREG(srcLo), FPREG(srcHi));
+ DCHECK_EQ(FPREG(destLo), FPREG(destHi));
+ if (destFP) {
+ if (srcFP) {
+ opRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
} else {
- if (srcFP) {
- newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi));
- } else {
- // Handle overlap
- if (srcHi == destLo) {
- opRegCopy(cUnit, destHi, srcHi);
- opRegCopy(cUnit, destLo, srcLo);
- } else {
- opRegCopy(cUnit, destLo, srcLo);
- opRegCopy(cUnit, destHi, srcHi);
- }
- }
+ newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi);
}
+ } else {
+ if (srcFP) {
+ newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi));
+ } else {
+ // Handle overlap
+ if (srcHi == destLo) {
+ opRegCopy(cUnit, destHi, srcHi);
+ opRegCopy(cUnit, destLo, srcLo);
+ } else {
+ opRegCopy(cUnit, destLo, srcLo);
+ opRegCopy(cUnit, destHi, srcHi);
+ }
+ }
+ }
}
// Table of magic divisors
enum DividePattern {
- DivideNone,
- Divide3,
- Divide5,
- Divide7,
+ DivideNone,
+ Divide3,
+ Divide5,
+ Divide7,
};
struct MagicTable {
- uint32_t magic;
- uint32_t shift;
- DividePattern pattern;
+ uint32_t magic;
+ uint32_t shift;
+ DividePattern pattern;
};
static const MagicTable magicTable[] = {
- {0, 0, DivideNone}, // 0
- {0, 0, DivideNone}, // 1
- {0, 0, DivideNone}, // 2
- {0x55555556, 0, Divide3}, // 3
- {0, 0, DivideNone}, // 4
- {0x66666667, 1, Divide5}, // 5
- {0x2AAAAAAB, 0, Divide3}, // 6
- {0x92492493, 2, Divide7}, // 7
- {0, 0, DivideNone}, // 8
- {0x38E38E39, 1, Divide5}, // 9
- {0x66666667, 2, Divide5}, // 10
- {0x2E8BA2E9, 1, Divide5}, // 11
- {0x2AAAAAAB, 1, Divide5}, // 12
- {0x4EC4EC4F, 2, Divide5}, // 13
- {0x92492493, 3, Divide7}, // 14
- {0x88888889, 3, Divide7}, // 15
+ {0, 0, DivideNone}, // 0
+ {0, 0, DivideNone}, // 1
+ {0, 0, DivideNone}, // 2
+ {0x55555556, 0, Divide3}, // 3
+ {0, 0, DivideNone}, // 4
+ {0x66666667, 1, Divide5}, // 5
+ {0x2AAAAAAB, 0, Divide3}, // 6
+ {0x92492493, 2, Divide7}, // 7
+ {0, 0, DivideNone}, // 8
+ {0x38E38E39, 1, Divide5}, // 9
+ {0x66666667, 2, Divide5}, // 10
+ {0x2E8BA2E9, 1, Divide5}, // 11
+ {0x2AAAAAAB, 1, Divide5}, // 12
+ {0x4EC4EC4F, 2, Divide5}, // 13
+ {0x92492493, 3, Divide7}, // 14
+ {0x88888889, 3, Divide7}, // 15
};
// Integer division by constant via reciprocal multiply (Hacker's Delight, 10-4)
bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
RegLocation rlSrc, RegLocation rlDest, int lit)
{
- if ((lit < 0) || (lit >= (int)(sizeof(magicTable)/sizeof(magicTable[0])))) {
- return false;
- }
- DividePattern pattern = magicTable[lit].pattern;
- if (pattern == DivideNone) {
- return false;
- }
- // Tuning: add rem patterns
- if (dalvikOpcode != Instruction::DIV_INT_LIT8) {
- return false;
- }
+ if ((lit < 0) || (lit >= (int)(sizeof(magicTable)/sizeof(magicTable[0])))) {
+ return false;
+ }
+ DividePattern pattern = magicTable[lit].pattern;
+ if (pattern == DivideNone) {
+ return false;
+ }
+ // Tuning: add rem patterns
+ if (dalvikOpcode != Instruction::DIV_INT_LIT8) {
+ return false;
+ }
- int rMagic = oatAllocTemp(cUnit);
- loadConstant(cUnit, rMagic, magicTable[lit].magic);
- rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
- int rHi = oatAllocTemp(cUnit);
- int rLo = oatAllocTemp(cUnit);
- newLIR4(cUnit, kThumb2Smull, rLo, rHi, rMagic, rlSrc.lowReg);
- switch(pattern) {
- case Divide3:
- opRegRegRegShift(cUnit, kOpSub, rlResult.lowReg, rHi,
- rlSrc.lowReg, encodeShift(kArmAsr, 31));
- break;
- case Divide5:
- opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
- opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
- encodeShift(kArmAsr, magicTable[lit].shift));
- break;
- case Divide7:
- opRegReg(cUnit, kOpAdd, rHi, rlSrc.lowReg);
- opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
- opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
- encodeShift(kArmAsr, magicTable[lit].shift));
- break;
- default:
- LOG(FATAL) << "Unexpected pattern: " << (int)pattern;
- }
- storeValue(cUnit, rlDest, rlResult);
- return true;
+ int rMagic = oatAllocTemp(cUnit);
+ loadConstant(cUnit, rMagic, magicTable[lit].magic);
+ rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ int rHi = oatAllocTemp(cUnit);
+ int rLo = oatAllocTemp(cUnit);
+ newLIR4(cUnit, kThumb2Smull, rLo, rHi, rMagic, rlSrc.lowReg);
+ switch(pattern) {
+ case Divide3:
+ opRegRegRegShift(cUnit, kOpSub, rlResult.lowReg, rHi,
+ rlSrc.lowReg, encodeShift(kArmAsr, 31));
+ break;
+ case Divide5:
+ opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
+ opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
+ encodeShift(kArmAsr, magicTable[lit].shift));
+ break;
+ case Divide7:
+ opRegReg(cUnit, kOpAdd, rHi, rlSrc.lowReg);
+ opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
+ opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
+ encodeShift(kArmAsr, magicTable[lit].shift));
+ break;
+ default:
+ LOG(FATAL) << "Unexpected pattern: " << (int)pattern;
+ }
+ storeValue(cUnit, rlDest, rlResult);
+ return true;
}
} // namespace art