[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/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc
index 0fe937a..533f8b4 100644
--- a/src/compiler/codegen/arm/Thumb2/Factory.cc
+++ b/src/compiler/codegen/arm/Thumb2/Factory.cc
@@ -37,62 +37,62 @@
int encodeImmSingle(int value)
{
- int res;
- int bitA = (value & 0x80000000) >> 31;
- int notBitB = (value & 0x40000000) >> 30;
- int bitB = (value & 0x20000000) >> 29;
- int bSmear = (value & 0x3e000000) >> 25;
- int slice = (value & 0x01f80000) >> 19;
- int zeroes = (value & 0x0007ffff);
- if (zeroes != 0)
- return -1;
- if (bitB) {
- if ((notBitB != 0) || (bSmear != 0x1f))
- return -1;
- } else {
- if ((notBitB != 1) || (bSmear != 0x0))
- return -1;
- }
- res = (bitA << 7) | (bitB << 6) | slice;
- return res;
+ int res;
+ int bitA = (value & 0x80000000) >> 31;
+ int notBitB = (value & 0x40000000) >> 30;
+ int bitB = (value & 0x20000000) >> 29;
+ int bSmear = (value & 0x3e000000) >> 25;
+ int slice = (value & 0x01f80000) >> 19;
+ int zeroes = (value & 0x0007ffff);
+ if (zeroes != 0)
+ return -1;
+ if (bitB) {
+ if ((notBitB != 0) || (bSmear != 0x1f))
+ return -1;
+ } else {
+ if ((notBitB != 1) || (bSmear != 0x0))
+ return -1;
+ }
+ res = (bitA << 7) | (bitB << 6) | slice;
+ return res;
}
LIR* loadFPConstantValue(CompilationUnit* cUnit, int rDest, int value)
{
- int encodedImm = encodeImmSingle(value);
- DCHECK(SINGLEREG(rDest));
- if (encodedImm >= 0) {
- return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm);
- }
- LIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
- if (dataTarget == NULL) {
- dataTarget = addWordData(cUnit, &cUnit->literalList, value);
- }
- LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2Vldrs,
- rDest, r15pc, 0, 0, 0, dataTarget);
- setMemRefType(loadPcRel, true, kLiteral);
- loadPcRel->aliasInfo = (intptr_t)dataTarget;
- oatAppendLIR(cUnit, (LIR* ) loadPcRel);
- return loadPcRel;
+ int encodedImm = encodeImmSingle(value);
+ DCHECK(SINGLEREG(rDest));
+ if (encodedImm >= 0) {
+ return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm);
+ }
+ LIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
+ if (dataTarget == NULL) {
+ dataTarget = addWordData(cUnit, &cUnit->literalList, value);
+ }
+ LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2Vldrs,
+ rDest, r15pc, 0, 0, 0, dataTarget);
+ setMemRefType(loadPcRel, true, kLiteral);
+ loadPcRel->aliasInfo = (intptr_t)dataTarget;
+ oatAppendLIR(cUnit, (LIR* ) loadPcRel);
+ return loadPcRel;
}
int leadingZeros(u4 val)
{
- u4 alt;
- int n;
- int count;
+ u4 alt;
+ int n;
+ int count;
- count = 16;
- n = 32;
- do {
- alt = val >> count;
- if (alt != 0) {
- n = n - count;
- val = alt;
- }
- count >>= 1;
- } while (count);
- return n - val;
+ count = 16;
+ n = 32;
+ do {
+ alt = val >> count;
+ if (alt != 0) {
+ n = n - count;
+ val = alt;
+ }
+ count >>= 1;
+ } while (count);
+ return n - val;
}
/*
@@ -107,20 +107,20 @@
/* Note: case of value==0 must use 0:000:0:0000000 encoding */
if (value <= 0xFF)
- return b0; // 0:000:a:bcdefgh
+ return b0; // 0:000:a:bcdefgh
if (value == ((b0 << 16) | b0))
- return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */
+ return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */
if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0))
- return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */
+ return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */
b0 = (value >> 8) & 0xff;
if (value == ((b0 << 24) | (b0 << 8)))
- return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */
+ return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */
/* Can we do it with rotation? */
zLeading = leadingZeros(value);
zTrailing = 32 - leadingZeros(~value & (value - 1));
/* A run of eight or fewer active bits? */
if ((zLeading + zTrailing) < 24)
- return -1; /* No - bail */
+ return -1; /* No - bail */
/* left-justify the constant, discarding msb (known to be 1) */
value <<= zLeading + 1;
/* Create bcdefgh */
@@ -139,443 +139,441 @@
*/
LIR* loadConstantNoClobber(CompilationUnit* cUnit, int rDest, int value)
{
- LIR* res;
- int modImm;
+ LIR* res;
+ int modImm;
- if (FPREG(rDest)) {
- return loadFPConstantValue(cUnit, rDest, value);
- }
+ if (FPREG(rDest)) {
+ return loadFPConstantValue(cUnit, rDest, value);
+ }
- /* See if the value can be constructed cheaply */
- if (LOWREG(rDest) && (value >= 0) && (value <= 255)) {
- return newLIR2(cUnit, kThumbMovImm, rDest, value);
- }
- /* Check Modified immediate special cases */
- modImm = modifiedImmediate(value);
- if (modImm >= 0) {
- res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm);
- return res;
- }
- modImm = modifiedImmediate(~value);
- if (modImm >= 0) {
- res = newLIR2(cUnit, kThumb2MvnImm12, rDest, modImm);
- return res;
- }
- /* 16-bit immediate? */
- if ((value & 0xffff) == value) {
- res = newLIR2(cUnit, kThumb2MovImm16, rDest, value);
- return res;
- }
- /* No shortcut - go ahead and use literal pool */
- LIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
- if (dataTarget == NULL) {
- dataTarget = addWordData(cUnit, &cUnit->literalList, value);
- }
- LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset,
- kThumb2LdrPcRel12, rDest, 0, 0, 0, 0, dataTarget);
- setMemRefType(loadPcRel, true, kLiteral);
- loadPcRel->aliasInfo = (intptr_t)dataTarget;
- res = loadPcRel;
- oatAppendLIR(cUnit, (LIR* ) loadPcRel);
-
- /*
- * To save space in the constant pool, we use the ADD_RRI8 instruction to
- * add up to 255 to an existing constant value.
- */
- if (dataTarget->operands[0] != value) {
- opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]);
- }
+ /* See if the value can be constructed cheaply */
+ if (LOWREG(rDest) && (value >= 0) && (value <= 255)) {
+ return newLIR2(cUnit, kThumbMovImm, rDest, value);
+ }
+ /* Check Modified immediate special cases */
+ modImm = modifiedImmediate(value);
+ if (modImm >= 0) {
+ res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm);
return res;
+ }
+ modImm = modifiedImmediate(~value);
+ if (modImm >= 0) {
+ res = newLIR2(cUnit, kThumb2MvnImm12, rDest, modImm);
+ return res;
+ }
+ /* 16-bit immediate? */
+ if ((value & 0xffff) == value) {
+ res = newLIR2(cUnit, kThumb2MovImm16, rDest, value);
+ return res;
+ }
+ /* No shortcut - go ahead and use literal pool */
+ LIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
+ if (dataTarget == NULL) {
+ dataTarget = addWordData(cUnit, &cUnit->literalList, value);
+ }
+ LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset,
+ kThumb2LdrPcRel12, rDest, 0, 0, 0, 0, dataTarget);
+ setMemRefType(loadPcRel, true, kLiteral);
+ loadPcRel->aliasInfo = (intptr_t)dataTarget;
+ res = loadPcRel;
+ oatAppendLIR(cUnit, (LIR* ) loadPcRel);
+
+ /*
+ * To save space in the constant pool, we use the ADD_RRI8 instruction to
+ * add up to 255 to an existing constant value.
+ */
+ if (dataTarget->operands[0] != value) {
+ opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]);
+ }
+ return res;
}
LIR* opBranchUnconditional(CompilationUnit* cUnit, OpKind op)
{
- DCHECK_EQ(op, kOpUncondBr);
- return newLIR1(cUnit, kThumbBUncond, 0 /* offset to be patched */);
+ DCHECK_EQ(op, kOpUncondBr);
+ return newLIR1(cUnit, kThumbBUncond, 0 /* offset to be patched */);
}
LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target)
{
- LIR* branch = newLIR2(cUnit, kThumb2BCond, 0 /* offset to be patched */,
- oatArmConditionEncoding(cc));
- branch->target = target;
- return branch;
+ LIR* branch = newLIR2(cUnit, kThumb2BCond, 0 /* offset to be patched */,
+ oatArmConditionEncoding(cc));
+ branch->target = target;
+ return branch;
}
LIR* opReg(CompilationUnit* cUnit, OpKind op, int rDestSrc)
{
- ArmOpcode opcode = kThumbBkpt;
- switch (op) {
- case kOpBlx:
- opcode = kThumbBlxR;
- break;
- default:
- LOG(FATAL) << "Bad opcode " << (int)op;
- }
- return newLIR1(cUnit, opcode, rDestSrc);
+ ArmOpcode opcode = kThumbBkpt;
+ switch (op) {
+ case kOpBlx:
+ opcode = kThumbBlxR;
+ break;
+ default:
+ LOG(FATAL) << "Bad opcode " << (int)op;
+ }
+ return newLIR1(cUnit, opcode, rDestSrc);
}
LIR* opRegRegShift(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
int rSrc2, int shift)
{
- bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2));
- ArmOpcode opcode = kThumbBkpt;
- switch (op) {
- case kOpAdc:
- opcode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR;
- break;
- case kOpAnd:
- opcode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR;
- break;
- case kOpBic:
- opcode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR;
- break;
- case kOpCmn:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR;
- break;
- case kOpCmp:
- if (thumbForm)
- opcode = kThumbCmpRR;
- else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2))
- opcode = kThumbCmpHH;
- else if ((shift == 0) && LOWREG(rDestSrc1))
- opcode = kThumbCmpLH;
- else if (shift == 0)
- opcode = kThumbCmpHL;
- else
- opcode = kThumb2CmpRR;
- break;
- case kOpXor:
- opcode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR;
- break;
- case kOpMov:
- DCHECK_EQ(shift, 0);
- if (LOWREG(rDestSrc1) && LOWREG(rSrc2))
- opcode = kThumbMovRR;
- else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2))
- opcode = kThumbMovRR_H2H;
- else if (LOWREG(rDestSrc1))
- opcode = kThumbMovRR_H2L;
- else
- opcode = kThumbMovRR_L2H;
- break;
- case kOpMul:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbMul : kThumb2MulRRR;
- break;
- case kOpMvn:
- opcode = (thumbForm) ? kThumbMvn : kThumb2MnvRR;
- break;
- case kOpNeg:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbNeg : kThumb2NegRR;
- break;
- case kOpOr:
- opcode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR;
- break;
- case kOpSbc:
- opcode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR;
- break;
- case kOpTst:
- opcode = (thumbForm) ? kThumbTst : kThumb2TstRR;
- break;
- case kOpLsl:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR;
- break;
- case kOpLsr:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR;
- break;
- case kOpAsr:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR;
- break;
- case kOpRor:
- DCHECK_EQ(shift, 0);
- opcode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR;
- break;
- case kOpAdd:
- opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
- break;
- case kOpSub:
- opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
- break;
- case kOp2Byte:
- DCHECK_EQ(shift, 0);
- return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8);
- case kOp2Short:
- DCHECK_EQ(shift, 0);
- return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16);
- case kOp2Char:
- DCHECK_EQ(shift, 0);
- return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16);
- default:
- LOG(FATAL) << "Bad opcode: " << (int)op;
- break;
- }
- DCHECK_GE(static_cast<int>(opcode), 0);
- if (EncodingMap[opcode].flags & IS_BINARY_OP)
- return newLIR2(cUnit, opcode, rDestSrc1, rSrc2);
- else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) {
- if (EncodingMap[opcode].fieldLoc[2].kind == kFmtShift)
- return newLIR3(cUnit, opcode, rDestSrc1, rSrc2, shift);
- else
- return newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2);
- } else if (EncodingMap[opcode].flags & IS_QUAD_OP)
- return newLIR4(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2, shift);
- else {
- LOG(FATAL) << "Unexpected encoding operand count";
- return NULL;
- }
+ bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2));
+ ArmOpcode opcode = kThumbBkpt;
+ switch (op) {
+ case kOpAdc:
+ opcode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR;
+ break;
+ case kOpAnd:
+ opcode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR;
+ break;
+ case kOpBic:
+ opcode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR;
+ break;
+ case kOpCmn:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR;
+ break;
+ case kOpCmp:
+ if (thumbForm)
+ opcode = kThumbCmpRR;
+ else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2))
+ opcode = kThumbCmpHH;
+ else if ((shift == 0) && LOWREG(rDestSrc1))
+ opcode = kThumbCmpLH;
+ else if (shift == 0)
+ opcode = kThumbCmpHL;
+ else
+ opcode = kThumb2CmpRR;
+ break;
+ case kOpXor:
+ opcode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR;
+ break;
+ case kOpMov:
+ DCHECK_EQ(shift, 0);
+ if (LOWREG(rDestSrc1) && LOWREG(rSrc2))
+ opcode = kThumbMovRR;
+ else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2))
+ opcode = kThumbMovRR_H2H;
+ else if (LOWREG(rDestSrc1))
+ opcode = kThumbMovRR_H2L;
+ else
+ opcode = kThumbMovRR_L2H;
+ break;
+ case kOpMul:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbMul : kThumb2MulRRR;
+ break;
+ case kOpMvn:
+ opcode = (thumbForm) ? kThumbMvn : kThumb2MnvRR;
+ break;
+ case kOpNeg:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbNeg : kThumb2NegRR;
+ break;
+ case kOpOr:
+ opcode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR;
+ break;
+ case kOpSbc:
+ opcode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR;
+ break;
+ case kOpTst:
+ opcode = (thumbForm) ? kThumbTst : kThumb2TstRR;
+ break;
+ case kOpLsl:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR;
+ break;
+ case kOpLsr:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR;
+ break;
+ case kOpAsr:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR;
+ break;
+ case kOpRor:
+ DCHECK_EQ(shift, 0);
+ opcode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR;
+ break;
+ case kOpAdd:
+ opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
+ break;
+ case kOpSub:
+ opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
+ break;
+ case kOp2Byte:
+ DCHECK_EQ(shift, 0);
+ return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8);
+ case kOp2Short:
+ DCHECK_EQ(shift, 0);
+ return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16);
+ case kOp2Char:
+ DCHECK_EQ(shift, 0);
+ return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16);
+ default:
+ LOG(FATAL) << "Bad opcode: " << (int)op;
+ break;
+ }
+ DCHECK_GE(static_cast<int>(opcode), 0);
+ if (EncodingMap[opcode].flags & IS_BINARY_OP)
+ return newLIR2(cUnit, opcode, rDestSrc1, rSrc2);
+ else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) {
+ if (EncodingMap[opcode].fieldLoc[2].kind == kFmtShift)
+ return newLIR3(cUnit, opcode, rDestSrc1, rSrc2, shift);
+ else
+ return newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2);
+ } else if (EncodingMap[opcode].flags & IS_QUAD_OP)
+ return newLIR4(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2, shift);
+ else {
+ LOG(FATAL) << "Unexpected encoding operand count";
+ return NULL;
+ }
}
LIR* opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2)
{
- return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0);
+ return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0);
}
LIR* opRegRegRegShift(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1,
- int rSrc2, int shift)
+ int rSrc2, int shift)
{
- ArmOpcode opcode = kThumbBkpt;
- bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) &&
- LOWREG(rSrc2);
- switch (op) {
- case kOpAdd:
- opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
- break;
- case kOpSub:
- opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
- break;
- case kOpRsub:
- opcode = kThumb2RsubRRR;
- break;
- case kOpAdc:
- opcode = kThumb2AdcRRR;
- break;
- case kOpAnd:
- opcode = kThumb2AndRRR;
- break;
- case kOpBic:
- opcode = kThumb2BicRRR;
- break;
- case kOpXor:
- opcode = kThumb2EorRRR;
- break;
- case kOpMul:
- DCHECK_EQ(shift, 0);
- opcode = kThumb2MulRRR;
- break;
- case kOpOr:
- opcode = kThumb2OrrRRR;
- break;
- case kOpSbc:
- opcode = kThumb2SbcRRR;
- break;
- case kOpLsl:
- DCHECK_EQ(shift, 0);
- opcode = kThumb2LslRRR;
- break;
- case kOpLsr:
- DCHECK_EQ(shift, 0);
- opcode = kThumb2LsrRRR;
- break;
- case kOpAsr:
- DCHECK_EQ(shift, 0);
- opcode = kThumb2AsrRRR;
- break;
- case kOpRor:
- DCHECK_EQ(shift, 0);
- opcode = kThumb2RorRRR;
- break;
- default:
- LOG(FATAL) << "Bad opcode: " << (int)op;
- break;
- }
- DCHECK_GE(static_cast<int>(opcode), 0);
- if (EncodingMap[opcode].flags & IS_QUAD_OP)
- return newLIR4(cUnit, opcode, rDest, rSrc1, rSrc2, shift);
- else {
- DCHECK(EncodingMap[opcode].flags & IS_TERTIARY_OP);
- return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2);
- }
+ ArmOpcode opcode = kThumbBkpt;
+ bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) &&
+ LOWREG(rSrc2);
+ switch (op) {
+ case kOpAdd:
+ opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
+ break;
+ case kOpSub:
+ opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
+ break;
+ case kOpRsub:
+ opcode = kThumb2RsubRRR;
+ break;
+ case kOpAdc:
+ opcode = kThumb2AdcRRR;
+ break;
+ case kOpAnd:
+ opcode = kThumb2AndRRR;
+ break;
+ case kOpBic:
+ opcode = kThumb2BicRRR;
+ break;
+ case kOpXor:
+ opcode = kThumb2EorRRR;
+ break;
+ case kOpMul:
+ DCHECK_EQ(shift, 0);
+ opcode = kThumb2MulRRR;
+ break;
+ case kOpOr:
+ opcode = kThumb2OrrRRR;
+ break;
+ case kOpSbc:
+ opcode = kThumb2SbcRRR;
+ break;
+ case kOpLsl:
+ DCHECK_EQ(shift, 0);
+ opcode = kThumb2LslRRR;
+ break;
+ case kOpLsr:
+ DCHECK_EQ(shift, 0);
+ opcode = kThumb2LsrRRR;
+ break;
+ case kOpAsr:
+ DCHECK_EQ(shift, 0);
+ opcode = kThumb2AsrRRR;
+ break;
+ case kOpRor:
+ DCHECK_EQ(shift, 0);
+ opcode = kThumb2RorRRR;
+ break;
+ default:
+ LOG(FATAL) << "Bad opcode: " << (int)op;
+ break;
+ }
+ DCHECK_GE(static_cast<int>(opcode), 0);
+ if (EncodingMap[opcode].flags & IS_QUAD_OP)
+ return newLIR4(cUnit, opcode, rDest, rSrc1, rSrc2, shift);
+ else {
+ DCHECK(EncodingMap[opcode].flags & IS_TERTIARY_OP);
+ return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2);
+ }
}
LIR* opRegRegReg(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1,
int rSrc2)
{
- return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0);
+ return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0);
}
LIR* opRegRegImm(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1,
int value)
{
- LIR* res;
- bool neg = (value < 0);
- int absValue = (neg) ? -value : value;
- ArmOpcode opcode = kThumbBkpt;
- ArmOpcode altOpcode = kThumbBkpt;
- bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1));
- int modImm = modifiedImmediate(value);
- int modImmNeg = modifiedImmediate(-value);
+ LIR* res;
+ bool neg = (value < 0);
+ int absValue = (neg) ? -value : value;
+ ArmOpcode opcode = kThumbBkpt;
+ ArmOpcode altOpcode = kThumbBkpt;
+ bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1));
+ int modImm = modifiedImmediate(value);
+ int modImmNeg = modifiedImmediate(-value);
- switch (op) {
- case kOpLsl:
- if (allLowRegs)
- return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value);
- else
- return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value);
- case kOpLsr:
- if (allLowRegs)
- return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value);
- else
- return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value);
- case kOpAsr:
- if (allLowRegs)
- return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value);
- else
- return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value);
- case kOpRor:
- return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value);
- case kOpAdd:
- if (LOWREG(rDest) && (rSrc1 == r13sp) &&
- (value <= 1020) && ((value & 0x3)==0)) {
- return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1,
- value >> 2);
- } else if (LOWREG(rDest) && (rSrc1 == r15pc) &&
- (value <= 1020) && ((value & 0x3)==0)) {
- return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1,
- value >> 2);
- }
- // Note: intentional fallthrough
- case kOpSub:
- if (allLowRegs && ((absValue & 0x7) == absValue)) {
- if (op == kOpAdd)
- opcode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3;
- else
- opcode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3;
- return newLIR3(cUnit, opcode, rDest, rSrc1, absValue);
- } else if ((absValue & 0xff) == absValue) {
- if (op == kOpAdd)
- opcode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12;
- else
- opcode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12;
- return newLIR3(cUnit, opcode, rDest, rSrc1, absValue);
- }
- if (modImmNeg >= 0) {
- op = (op == kOpAdd) ? kOpSub : kOpAdd;
- modImm = modImmNeg;
- }
- if (op == kOpSub) {
- opcode = kThumb2SubRRI8;
- altOpcode = kThumb2SubRRR;
- } else {
- opcode = kThumb2AddRRI8;
- altOpcode = kThumb2AddRRR;
- }
- break;
- case kOpAdc:
- opcode = kThumb2AdcRRI8;
- altOpcode = kThumb2AdcRRR;
- break;
- case kOpSbc:
- opcode = kThumb2SbcRRI8;
- altOpcode = kThumb2SbcRRR;
- break;
- case kOpOr:
- opcode = kThumb2OrrRRI8;
- altOpcode = kThumb2OrrRRR;
- break;
- case kOpAnd:
- opcode = kThumb2AndRRI8;
- altOpcode = kThumb2AndRRR;
- break;
- case kOpXor:
- opcode = kThumb2EorRRI8;
- altOpcode = kThumb2EorRRR;
- break;
- case kOpMul:
- //TUNING: power of 2, shift & add
- modImm = -1;
- altOpcode = kThumb2MulRRR;
- break;
- case kOpCmp: {
- int modImm = modifiedImmediate(value);
- LIR* res;
- if (modImm >= 0) {
- res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm);
- } else {
- int rTmp = oatAllocTemp(cUnit);
- res = loadConstant(cUnit, rTmp, value);
- opRegReg(cUnit, kOpCmp, rSrc1, rTmp);
- oatFreeTemp(cUnit, rTmp);
- }
- return res;
- }
- default:
- LOG(FATAL) << "Bad opcode: " << (int)op;
- }
-
- if (modImm >= 0) {
- return newLIR3(cUnit, opcode, rDest, rSrc1, modImm);
- } else {
- int rScratch = oatAllocTemp(cUnit);
- loadConstant(cUnit, rScratch, value);
- if (EncodingMap[altOpcode].flags & IS_QUAD_OP)
- res = newLIR4(cUnit, altOpcode, rDest, rSrc1, rScratch, 0);
+ switch (op) {
+ case kOpLsl:
+ if (allLowRegs)
+ return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value);
+ else
+ return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value);
+ case kOpLsr:
+ if (allLowRegs)
+ return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value);
+ else
+ return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value);
+ case kOpAsr:
+ if (allLowRegs)
+ return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value);
+ else
+ return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value);
+ case kOpRor:
+ return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value);
+ case kOpAdd:
+ if (LOWREG(rDest) && (rSrc1 == r13sp) &&
+ (value <= 1020) && ((value & 0x3)==0)) {
+ return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1, value >> 2);
+ } else if (LOWREG(rDest) && (rSrc1 == r15pc) &&
+ (value <= 1020) && ((value & 0x3)==0)) {
+ return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1, value >> 2);
+ }
+ // Note: intentional fallthrough
+ case kOpSub:
+ if (allLowRegs && ((absValue & 0x7) == absValue)) {
+ if (op == kOpAdd)
+ opcode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3;
else
- res = newLIR3(cUnit, altOpcode, rDest, rSrc1, rScratch);
- oatFreeTemp(cUnit, rScratch);
- return res;
+ opcode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3;
+ return newLIR3(cUnit, opcode, rDest, rSrc1, absValue);
+ } else if ((absValue & 0xff) == absValue) {
+ if (op == kOpAdd)
+ opcode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12;
+ else
+ opcode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12;
+ return newLIR3(cUnit, opcode, rDest, rSrc1, absValue);
+ }
+ if (modImmNeg >= 0) {
+ op = (op == kOpAdd) ? kOpSub : kOpAdd;
+ modImm = modImmNeg;
+ }
+ if (op == kOpSub) {
+ opcode = kThumb2SubRRI8;
+ altOpcode = kThumb2SubRRR;
+ } else {
+ opcode = kThumb2AddRRI8;
+ altOpcode = kThumb2AddRRR;
+ }
+ break;
+ case kOpAdc:
+ opcode = kThumb2AdcRRI8;
+ altOpcode = kThumb2AdcRRR;
+ break;
+ case kOpSbc:
+ opcode = kThumb2SbcRRI8;
+ altOpcode = kThumb2SbcRRR;
+ break;
+ case kOpOr:
+ opcode = kThumb2OrrRRI8;
+ altOpcode = kThumb2OrrRRR;
+ break;
+ case kOpAnd:
+ opcode = kThumb2AndRRI8;
+ altOpcode = kThumb2AndRRR;
+ break;
+ case kOpXor:
+ opcode = kThumb2EorRRI8;
+ altOpcode = kThumb2EorRRR;
+ break;
+ case kOpMul:
+ //TUNING: power of 2, shift & add
+ modImm = -1;
+ altOpcode = kThumb2MulRRR;
+ break;
+ case kOpCmp: {
+ int modImm = modifiedImmediate(value);
+ LIR* res;
+ if (modImm >= 0) {
+ res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm);
+ } else {
+ int rTmp = oatAllocTemp(cUnit);
+ res = loadConstant(cUnit, rTmp, value);
+ opRegReg(cUnit, kOpCmp, rSrc1, rTmp);
+ oatFreeTemp(cUnit, rTmp);
+ }
+ return res;
}
+ default:
+ LOG(FATAL) << "Bad opcode: " << (int)op;
+ }
+
+ if (modImm >= 0) {
+ return newLIR3(cUnit, opcode, rDest, rSrc1, modImm);
+ } else {
+ int rScratch = oatAllocTemp(cUnit);
+ loadConstant(cUnit, rScratch, value);
+ if (EncodingMap[altOpcode].flags & IS_QUAD_OP)
+ res = newLIR4(cUnit, altOpcode, rDest, rSrc1, rScratch, 0);
+ else
+ res = newLIR3(cUnit, altOpcode, rDest, rSrc1, rScratch);
+ oatFreeTemp(cUnit, rScratch);
+ return res;
+ }
}
/* Handle Thumb-only variants here - otherwise punt to opRegRegImm */
LIR* opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value)
{
- bool neg = (value < 0);
- int absValue = (neg) ? -value : value;
- bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1));
- ArmOpcode opcode = kThumbBkpt;
- switch (op) {
- case kOpAdd:
- if ( !neg && (rDestSrc1 == r13sp) && (value <= 508)) { /* sp */
- DCHECK_EQ((value & 0x3), 0);
- return newLIR1(cUnit, kThumbAddSpI7, value >> 2);
- } else if (shortForm) {
- opcode = (neg) ? kThumbSubRI8 : kThumbAddRI8;
- }
- break;
- case kOpSub:
- if (!neg && (rDestSrc1 == r13sp) && (value <= 508)) { /* sp */
- DCHECK_EQ((value & 0x3), 0);
- return newLIR1(cUnit, kThumbSubSpI7, value >> 2);
- } else if (shortForm) {
- opcode = (neg) ? kThumbAddRI8 : kThumbSubRI8;
- }
- break;
- case kOpCmp:
- if (LOWREG(rDestSrc1) && shortForm)
- opcode = (shortForm) ? kThumbCmpRI8 : kThumbCmpRR;
- else if (LOWREG(rDestSrc1))
- opcode = kThumbCmpRR;
- else {
- shortForm = false;
- opcode = kThumbCmpHL;
- }
- break;
- default:
- /* Punt to opRegRegImm - if bad case catch it there */
- shortForm = false;
- break;
- }
- if (shortForm)
- return newLIR2(cUnit, opcode, rDestSrc1, absValue);
- else {
- return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value);
- }
+ bool neg = (value < 0);
+ int absValue = (neg) ? -value : value;
+ bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1));
+ ArmOpcode opcode = kThumbBkpt;
+ switch (op) {
+ case kOpAdd:
+ if ( !neg && (rDestSrc1 == r13sp) && (value <= 508)) { /* sp */
+ DCHECK_EQ((value & 0x3), 0);
+ return newLIR1(cUnit, kThumbAddSpI7, value >> 2);
+ } else if (shortForm) {
+ opcode = (neg) ? kThumbSubRI8 : kThumbAddRI8;
+ }
+ break;
+ case kOpSub:
+ if (!neg && (rDestSrc1 == r13sp) && (value <= 508)) { /* sp */
+ DCHECK_EQ((value & 0x3), 0);
+ return newLIR1(cUnit, kThumbSubSpI7, value >> 2);
+ } else if (shortForm) {
+ opcode = (neg) ? kThumbAddRI8 : kThumbSubRI8;
+ }
+ break;
+ case kOpCmp:
+ if (LOWREG(rDestSrc1) && shortForm)
+ opcode = (shortForm) ? kThumbCmpRI8 : kThumbCmpRR;
+ else if (LOWREG(rDestSrc1))
+ opcode = kThumbCmpRR;
+ else {
+ shortForm = false;
+ opcode = kThumbCmpHL;
+ }
+ break;
+ default:
+ /* Punt to opRegRegImm - if bad case catch it there */
+ shortForm = false;
+ break;
+ }
+ if (shortForm)
+ return newLIR2(cUnit, opcode, rDestSrc1, absValue);
+ else {
+ return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value);
+ }
}
/*
@@ -584,193 +582,191 @@
*/
int encodeImmDoubleHigh(int value)
{
- int res;
- int bitA = (value & 0x80000000) >> 31;
- int notBitB = (value & 0x40000000) >> 30;
- int bitB = (value & 0x20000000) >> 29;
- int bSmear = (value & 0x3fc00000) >> 22;
- int slice = (value & 0x003f0000) >> 16;
- int zeroes = (value & 0x0000ffff);
- if (zeroes != 0)
- return -1;
- if (bitB) {
- if ((notBitB != 0) || (bSmear != 0xff))
- return -1;
- } else {
- if ((notBitB != 1) || (bSmear != 0x0))
- return -1;
- }
- res = (bitA << 7) | (bitB << 6) | slice;
- return res;
+ int res;
+ int bitA = (value & 0x80000000) >> 31;
+ int notBitB = (value & 0x40000000) >> 30;
+ int bitB = (value & 0x20000000) >> 29;
+ int bSmear = (value & 0x3fc00000) >> 22;
+ int slice = (value & 0x003f0000) >> 16;
+ int zeroes = (value & 0x0000ffff);
+ if (zeroes != 0)
+ return -1;
+ if (bitB) {
+ if ((notBitB != 0) || (bSmear != 0xff))
+ return -1;
+ } else {
+ if ((notBitB != 1) || (bSmear != 0x0))
+ return -1;
+ }
+ res = (bitA << 7) | (bitB << 6) | slice;
+ return res;
}
int encodeImmDouble(int valLo, int valHi)
{
- int res = -1;
- if (valLo == 0)
- res = encodeImmDoubleHigh(valHi);
- return res;
+ int res = -1;
+ if (valLo == 0)
+ res = encodeImmDoubleHigh(valHi);
+ return res;
}
LIR* loadConstantValueWide(CompilationUnit* cUnit, int rDestLo, int rDestHi,
- int valLo, int valHi)
+ int valLo, int valHi)
{
- int encodedImm = encodeImmDouble(valLo, valHi);
- LIR* res;
- if (FPREG(rDestLo)) {
- if (encodedImm >= 0) {
- res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi),
- encodedImm);
- } else {
- LIR* dataTarget = scanLiteralPoolWide(cUnit->literalList, valLo,
- valHi);
- if (dataTarget == NULL) {
- dataTarget = addWideData(cUnit, &cUnit->literalList, valLo,
- valHi);
- }
- LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset,
- kThumb2Vldrd, S2D(rDestLo, rDestHi),
- r15pc, 0, 0, 0, dataTarget);
- setMemRefType(loadPcRel, true, kLiteral);
- loadPcRel->aliasInfo = (intptr_t)dataTarget;
- oatAppendLIR(cUnit, (LIR* ) loadPcRel);
- res = loadPcRel;
- }
+ int encodedImm = encodeImmDouble(valLo, valHi);
+ LIR* res;
+ if (FPREG(rDestLo)) {
+ if (encodedImm >= 0) {
+ res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi),
+ encodedImm);
} else {
- res = loadConstantNoClobber(cUnit, rDestLo, valLo);
- loadConstantNoClobber(cUnit, rDestHi, valHi);
+ LIR* dataTarget = scanLiteralPoolWide(cUnit->literalList, valLo, valHi);
+ if (dataTarget == NULL) {
+ dataTarget = addWideData(cUnit, &cUnit->literalList, valLo, valHi);
+ }
+ LIR* loadPcRel =
+ rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2Vldrd,
+ S2D(rDestLo, rDestHi), r15pc, 0, 0, 0, dataTarget);
+ setMemRefType(loadPcRel, true, kLiteral);
+ loadPcRel->aliasInfo = (intptr_t)dataTarget;
+ oatAppendLIR(cUnit, (LIR* ) loadPcRel);
+ res = loadPcRel;
}
- return res;
+ } else {
+ res = loadConstantNoClobber(cUnit, rDestLo, valLo);
+ loadConstantNoClobber(cUnit, rDestHi, valHi);
+ }
+ return res;
}
int encodeShift(int code, int amount) {
- return ((amount & 0x1f) << 2) | code;
+ return ((amount & 0x1f) << 2) | code;
}
LIR* loadBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rDest,
int scale, OpSize size)
{
- bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest);
- LIR* load;
- ArmOpcode opcode = kThumbBkpt;
- bool thumbForm = (allLowRegs && (scale == 0));
- int regPtr;
+ bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest);
+ LIR* load;
+ ArmOpcode opcode = kThumbBkpt;
+ bool thumbForm = (allLowRegs && (scale == 0));
+ int regPtr;
- if (FPREG(rDest)) {
- if (SINGLEREG(rDest)) {
- DCHECK((size == kWord) || (size == kSingle));
- opcode = kThumb2Vldrs;
- size = kSingle;
- } else {
- DCHECK(DOUBLEREG(rDest));
- DCHECK((size == kLong) || (size == kDouble));
- DCHECK((rDest & 0x1) == 0);
- opcode = kThumb2Vldrd;
- size = kDouble;
- }
+ if (FPREG(rDest)) {
+ if (SINGLEREG(rDest)) {
+ DCHECK((size == kWord) || (size == kSingle));
+ opcode = kThumb2Vldrs;
+ size = kSingle;
} else {
- if (size == kSingle)
- size = kWord;
+ DCHECK(DOUBLEREG(rDest));
+ DCHECK((size == kLong) || (size == kDouble));
+ DCHECK((rDest & 0x1) == 0);
+ opcode = kThumb2Vldrd;
+ size = kDouble;
}
+ } else {
+ if (size == kSingle)
+ size = kWord;
+ }
- switch (size) {
- case kDouble: // fall-through
- case kSingle:
- regPtr = oatAllocTemp(cUnit);
- if (scale) {
- newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
- encodeShift(kArmLsl, scale));
- } else {
- opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
- }
- load = newLIR3(cUnit, opcode, rDest, regPtr, 0);
- oatFreeTemp(cUnit, regPtr);
- return load;
- case kWord:
- opcode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR;
- break;
- case kUnsignedHalf:
- opcode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR;
- break;
- case kSignedHalf:
- opcode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR;
- break;
- case kUnsignedByte:
- opcode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR;
- break;
- case kSignedByte:
- opcode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR;
- break;
- default:
- LOG(FATAL) << "Bad size: " << (int)size;
- }
- if (thumbForm)
- load = newLIR3(cUnit, opcode, rDest, rBase, rIndex);
- else
- load = newLIR4(cUnit, opcode, rDest, rBase, rIndex, scale);
+ switch (size) {
+ case kDouble: // fall-through
+ case kSingle:
+ regPtr = oatAllocTemp(cUnit);
+ if (scale) {
+ newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
+ encodeShift(kArmLsl, scale));
+ } else {
+ opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
+ }
+ load = newLIR3(cUnit, opcode, rDest, regPtr, 0);
+ oatFreeTemp(cUnit, regPtr);
+ return load;
+ case kWord:
+ opcode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR;
+ break;
+ case kUnsignedHalf:
+ opcode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR;
+ break;
+ case kSignedHalf:
+ opcode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR;
+ break;
+ case kUnsignedByte:
+ opcode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR;
+ break;
+ case kSignedByte:
+ opcode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR;
+ break;
+ default:
+ LOG(FATAL) << "Bad size: " << (int)size;
+ }
+ if (thumbForm)
+ load = newLIR3(cUnit, opcode, rDest, rBase, rIndex);
+ else
+ load = newLIR4(cUnit, opcode, rDest, rBase, rIndex, scale);
- return load;
+ return load;
}
LIR* storeBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rSrc,
int scale, OpSize size)
{
- bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc);
- LIR* store;
- ArmOpcode opcode = kThumbBkpt;
- bool thumbForm = (allLowRegs && (scale == 0));
- int regPtr;
+ bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc);
+ LIR* store;
+ ArmOpcode opcode = kThumbBkpt;
+ bool thumbForm = (allLowRegs && (scale == 0));
+ int regPtr;
- if (FPREG(rSrc)) {
- if (SINGLEREG(rSrc)) {
- DCHECK((size == kWord) || (size == kSingle));
- opcode = kThumb2Vstrs;
- size = kSingle;
- } else {
- DCHECK(DOUBLEREG(rSrc));
- DCHECK((size == kLong) || (size == kDouble));
- DCHECK((rSrc & 0x1) == 0);
- opcode = kThumb2Vstrd;
- size = kDouble;
- }
+ if (FPREG(rSrc)) {
+ if (SINGLEREG(rSrc)) {
+ DCHECK((size == kWord) || (size == kSingle));
+ opcode = kThumb2Vstrs;
+ size = kSingle;
} else {
- if (size == kSingle)
- size = kWord;
+ DCHECK(DOUBLEREG(rSrc));
+ DCHECK((size == kLong) || (size == kDouble));
+ DCHECK((rSrc & 0x1) == 0);
+ opcode = kThumb2Vstrd;
+ size = kDouble;
}
+ } else {
+ if (size == kSingle)
+ size = kWord;
+ }
- switch (size) {
- case kDouble: // fall-through
- case kSingle:
- regPtr = oatAllocTemp(cUnit);
- if (scale) {
- newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
- encodeShift(kArmLsl, scale));
- } else {
- opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
- }
- store = newLIR3(cUnit, opcode, rSrc, regPtr, 0);
- oatFreeTemp(cUnit, regPtr);
- return store;
- case kWord:
- opcode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR;
- break;
- case kUnsignedHalf:
- case kSignedHalf:
- opcode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR;
- break;
- case kUnsignedByte:
- case kSignedByte:
- opcode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR;
- break;
- default:
- LOG(FATAL) << "Bad size: " << (int)size;
- }
- if (thumbForm)
- store = newLIR3(cUnit, opcode, rSrc, rBase, rIndex);
- else
- store = newLIR4(cUnit, opcode, rSrc, rBase, rIndex, scale);
+ switch (size) {
+ case kDouble: // fall-through
+ case kSingle:
+ regPtr = oatAllocTemp(cUnit);
+ if (scale) {
+ newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
+ encodeShift(kArmLsl, scale));
+ } else {
+ opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
+ }
+ store = newLIR3(cUnit, opcode, rSrc, regPtr, 0);
+ oatFreeTemp(cUnit, regPtr);
+ return store;
+ case kWord:
+ opcode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR;
+ break;
+ case kUnsignedHalf:
+ case kSignedHalf:
+ opcode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR;
+ break;
+ case kUnsignedByte:
+ case kSignedByte:
+ opcode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR;
+ break;
+ default:
+ LOG(FATAL) << "Bad size: " << (int)size;
+ }
+ if (thumbForm)
+ store = newLIR3(cUnit, opcode, rSrc, rBase, rIndex);
+ else
+ store = newLIR4(cUnit, opcode, rSrc, rBase, rIndex, scale);
- return store;
+ return store;
}
/*
@@ -782,267 +778,266 @@
int displacement, int rDest, int rDestHi, OpSize size,
int sReg)
{
- LIR* res;
- LIR* load;
- ArmOpcode opcode = kThumbBkpt;
- bool shortForm = false;
- bool thumb2Form = (displacement < 4092 && displacement >= 0);
- bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest));
- int encodedDisp = displacement;
- bool is64bit = false;
- switch (size) {
- case kDouble:
- case kLong:
- is64bit = true;
- if (FPREG(rDest)) {
- if (SINGLEREG(rDest)) {
- DCHECK(FPREG(rDestHi));
- rDest = S2D(rDest, rDestHi);
- }
- opcode = kThumb2Vldrd;
- if (displacement <= 1020) {
- shortForm = true;
- encodedDisp >>= 2;
- }
- break;
- } else {
- res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest,
- -1, kWord, sReg);
- loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi,
- -1, kWord, INVALID_SREG);
- return res;
- }
- case kSingle:
- case kWord:
- if (FPREG(rDest)) {
- opcode = kThumb2Vldrs;
- if (displacement <= 1020) {
- shortForm = true;
- encodedDisp >>= 2;
- }
- break;
- }
- if (LOWREG(rDest) && (rBase == r15pc) &&
- (displacement <= 1020) && (displacement >= 0)) {
- shortForm = true;
- encodedDisp >>= 2;
- opcode = kThumbLdrPcRel;
- } else if (LOWREG(rDest) && (rBase == r13sp) &&
- (displacement <= 1020) && (displacement >= 0)) {
- shortForm = true;
- encodedDisp >>= 2;
- opcode = kThumbLdrSpRel;
- } else if (allLowRegs && displacement < 128 && displacement >= 0) {
- DCHECK_EQ((displacement & 0x3), 0);
- shortForm = true;
- encodedDisp >>= 2;
- opcode = kThumbLdrRRI5;
- } else if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2LdrRRI12;
- }
- break;
- case kUnsignedHalf:
- if (allLowRegs && displacement < 64 && displacement >= 0) {
- DCHECK_EQ((displacement & 0x1), 0);
- shortForm = true;
- encodedDisp >>= 1;
- opcode = kThumbLdrhRRI5;
- } else if (displacement < 4092 && displacement >= 0) {
- shortForm = true;
- opcode = kThumb2LdrhRRI12;
- }
- break;
- case kSignedHalf:
- if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2LdrshRRI12;
- }
- break;
- case kUnsignedByte:
- if (allLowRegs && displacement < 32 && displacement >= 0) {
- shortForm = true;
- opcode = kThumbLdrbRRI5;
- } else if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2LdrbRRI12;
- }
- break;
- case kSignedByte:
- if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2LdrsbRRI12;
- }
- break;
- default:
- LOG(FATAL) << "Bad size: " << (int)size;
- }
+ LIR* res;
+ LIR* load;
+ ArmOpcode opcode = kThumbBkpt;
+ bool shortForm = false;
+ bool thumb2Form = (displacement < 4092 && displacement >= 0);
+ bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest));
+ int encodedDisp = displacement;
+ bool is64bit = false;
+ switch (size) {
+ case kDouble:
+ case kLong:
+ is64bit = true;
+ if (FPREG(rDest)) {
+ if (SINGLEREG(rDest)) {
+ DCHECK(FPREG(rDestHi));
+ rDest = S2D(rDest, rDestHi);
+ }
+ opcode = kThumb2Vldrd;
+ if (displacement <= 1020) {
+ shortForm = true;
+ encodedDisp >>= 2;
+ }
+ break;
+ } else {
+ res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest,
+ -1, kWord, sReg);
+ loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi,
+ -1, kWord, INVALID_SREG);
+ return res;
+ }
+ case kSingle:
+ case kWord:
+ if (FPREG(rDest)) {
+ opcode = kThumb2Vldrs;
+ if (displacement <= 1020) {
+ shortForm = true;
+ encodedDisp >>= 2;
+ }
+ break;
+ }
+ if (LOWREG(rDest) && (rBase == r15pc) &&
+ (displacement <= 1020) && (displacement >= 0)) {
+ shortForm = true;
+ encodedDisp >>= 2;
+ opcode = kThumbLdrPcRel;
+ } else if (LOWREG(rDest) && (rBase == r13sp) &&
+ (displacement <= 1020) && (displacement >= 0)) {
+ shortForm = true;
+ encodedDisp >>= 2;
+ opcode = kThumbLdrSpRel;
+ } else if (allLowRegs && displacement < 128 && displacement >= 0) {
+ DCHECK_EQ((displacement & 0x3), 0);
+ shortForm = true;
+ encodedDisp >>= 2;
+ opcode = kThumbLdrRRI5;
+ } else if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2LdrRRI12;
+ }
+ break;
+ case kUnsignedHalf:
+ if (allLowRegs && displacement < 64 && displacement >= 0) {
+ DCHECK_EQ((displacement & 0x1), 0);
+ shortForm = true;
+ encodedDisp >>= 1;
+ opcode = kThumbLdrhRRI5;
+ } else if (displacement < 4092 && displacement >= 0) {
+ shortForm = true;
+ opcode = kThumb2LdrhRRI12;
+ }
+ break;
+ case kSignedHalf:
+ if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2LdrshRRI12;
+ }
+ break;
+ case kUnsignedByte:
+ if (allLowRegs && displacement < 32 && displacement >= 0) {
+ shortForm = true;
+ opcode = kThumbLdrbRRI5;
+ } else if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2LdrbRRI12;
+ }
+ break;
+ case kSignedByte:
+ if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2LdrsbRRI12;
+ }
+ break;
+ default:
+ LOG(FATAL) << "Bad size: " << (int)size;
+ }
- if (shortForm) {
- load = res = newLIR3(cUnit, opcode, rDest, rBase, encodedDisp);
- } else {
- int regOffset = oatAllocTemp(cUnit);
- res = loadConstant(cUnit, regOffset, encodedDisp);
- load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size);
- oatFreeTemp(cUnit, regOffset);
- }
+ if (shortForm) {
+ load = res = newLIR3(cUnit, opcode, rDest, rBase, encodedDisp);
+ } else {
+ int regOffset = oatAllocTemp(cUnit);
+ res = loadConstant(cUnit, regOffset, encodedDisp);
+ load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size);
+ oatFreeTemp(cUnit, regOffset);
+ }
- // TODO: in future may need to differentiate Dalvik accesses w/ spills
- if (rBase == rSP) {
- annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */, is64bit);
- }
- return load;
+ // TODO: in future may need to differentiate Dalvik accesses w/ spills
+ if (rBase == rSP) {
+ annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */, is64bit);
+ }
+ return load;
}
LIR* loadBaseDisp(CompilationUnit* cUnit, MIR* mir, int rBase,
int displacement, int rDest, OpSize size, int sReg)
{
- return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1,
- size, sReg);
+ return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, size,
+ sReg);
}
LIR* loadBaseDispWide(CompilationUnit* cUnit, MIR* mir, int rBase,
int displacement, int rDestLo, int rDestHi, int sReg)
{
- return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
- kLong, sReg);
+ return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
+ kLong, sReg);
}
LIR* storeBaseDispBody(CompilationUnit* cUnit, int rBase, int displacement,
int rSrc, int rSrcHi, OpSize size)
{
- LIR* res, *store;
- ArmOpcode opcode = kThumbBkpt;
- bool shortForm = false;
- bool thumb2Form = (displacement < 4092 && displacement >= 0);
- bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc));
- int encodedDisp = displacement;
- bool is64bit = false;
- switch (size) {
- case kLong:
- case kDouble:
- is64bit = true;
- if (!FPREG(rSrc)) {
- res = storeBaseDispBody(cUnit, rBase, displacement, rSrc,
- -1, kWord);
- storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi,
- -1, kWord);
- return res;
- }
- if (SINGLEREG(rSrc)) {
- DCHECK(FPREG(rSrcHi));
- rSrc = S2D(rSrc, rSrcHi);
- }
- opcode = kThumb2Vstrd;
- if (displacement <= 1020) {
- shortForm = true;
- encodedDisp >>= 2;
- }
- break;
- case kSingle:
- case kWord:
- if (FPREG(rSrc)) {
- DCHECK(SINGLEREG(rSrc));
- opcode = kThumb2Vstrs;
- if (displacement <= 1020) {
- shortForm = true;
- encodedDisp >>= 2;
- }
- break;
- }
- if (allLowRegs && displacement < 128 && displacement >= 0) {
- DCHECK_EQ((displacement & 0x3), 0);
- shortForm = true;
- encodedDisp >>= 2;
- opcode = kThumbStrRRI5;
- } else if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2StrRRI12;
- }
- break;
- case kUnsignedHalf:
- case kSignedHalf:
- if (allLowRegs && displacement < 64 && displacement >= 0) {
- DCHECK_EQ((displacement & 0x1), 0);
- shortForm = true;
- encodedDisp >>= 1;
- opcode = kThumbStrhRRI5;
- } else if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2StrhRRI12;
- }
- break;
- case kUnsignedByte:
- case kSignedByte:
- if (allLowRegs && displacement < 32 && displacement >= 0) {
- shortForm = true;
- opcode = kThumbStrbRRI5;
- } else if (thumb2Form) {
- shortForm = true;
- opcode = kThumb2StrbRRI12;
- }
- break;
- default:
- LOG(FATAL) << "Bad size: " << (int)size;
- }
- if (shortForm) {
- store = res = newLIR3(cUnit, opcode, rSrc, rBase, encodedDisp);
- } else {
- int rScratch = oatAllocTemp(cUnit);
- res = loadConstant(cUnit, rScratch, encodedDisp);
- store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size);
- oatFreeTemp(cUnit, rScratch);
- }
+ LIR* res, *store;
+ ArmOpcode opcode = kThumbBkpt;
+ bool shortForm = false;
+ bool thumb2Form = (displacement < 4092 && displacement >= 0);
+ bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc));
+ int encodedDisp = displacement;
+ bool is64bit = false;
+ switch (size) {
+ case kLong:
+ case kDouble:
+ is64bit = true;
+ if (!FPREG(rSrc)) {
+ res = storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, kWord);
+ storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi, -1, kWord);
+ return res;
+ }
+ if (SINGLEREG(rSrc)) {
+ DCHECK(FPREG(rSrcHi));
+ rSrc = S2D(rSrc, rSrcHi);
+ }
+ opcode = kThumb2Vstrd;
+ if (displacement <= 1020) {
+ shortForm = true;
+ encodedDisp >>= 2;
+ }
+ break;
+ case kSingle:
+ case kWord:
+ if (FPREG(rSrc)) {
+ DCHECK(SINGLEREG(rSrc));
+ opcode = kThumb2Vstrs;
+ if (displacement <= 1020) {
+ shortForm = true;
+ encodedDisp >>= 2;
+ }
+ break;
+ }
+ if (allLowRegs && displacement < 128 && displacement >= 0) {
+ DCHECK_EQ((displacement & 0x3), 0);
+ shortForm = true;
+ encodedDisp >>= 2;
+ opcode = kThumbStrRRI5;
+ } else if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2StrRRI12;
+ }
+ break;
+ case kUnsignedHalf:
+ case kSignedHalf:
+ if (allLowRegs && displacement < 64 && displacement >= 0) {
+ DCHECK_EQ((displacement & 0x1), 0);
+ shortForm = true;
+ encodedDisp >>= 1;
+ opcode = kThumbStrhRRI5;
+ } else if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2StrhRRI12;
+ }
+ break;
+ case kUnsignedByte:
+ case kSignedByte:
+ if (allLowRegs && displacement < 32 && displacement >= 0) {
+ shortForm = true;
+ opcode = kThumbStrbRRI5;
+ } else if (thumb2Form) {
+ shortForm = true;
+ opcode = kThumb2StrbRRI12;
+ }
+ break;
+ default:
+ LOG(FATAL) << "Bad size: " << (int)size;
+ }
+ if (shortForm) {
+ store = res = newLIR3(cUnit, opcode, rSrc, rBase, encodedDisp);
+ } else {
+ int rScratch = oatAllocTemp(cUnit);
+ res = loadConstant(cUnit, rScratch, encodedDisp);
+ store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size);
+ oatFreeTemp(cUnit, rScratch);
+ }
- // TODO: In future, may need to differentiate Dalvik & spill accesses
- if (rBase == rSP) {
- annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */, is64bit);
- }
- return res;
+ // TODO: In future, may need to differentiate Dalvik & spill accesses
+ if (rBase == rSP) {
+ annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */,
+ is64bit);
+ }
+ return res;
}
LIR* storeBaseDisp(CompilationUnit* cUnit, int rBase, int displacement,
int rSrc, OpSize size)
{
- return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
+ return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
}
LIR* storeBaseDispWide(CompilationUnit* cUnit, int rBase, int displacement,
int rSrcLo, int rSrcHi)
{
- return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
+ return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
}
void storePair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
{
- storeBaseDispWide(cUnit, base, 0, lowReg, highReg);
+ storeBaseDispWide(cUnit, base, 0, lowReg, highReg);
}
void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
{
- loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
+ loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
}
LIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
{
- int opcode;
- DCHECK_EQ(DOUBLEREG(rDest), DOUBLEREG(rSrc));
- if (DOUBLEREG(rDest)) {
- opcode = kThumb2Vmovd;
+ int opcode;
+ DCHECK_EQ(DOUBLEREG(rDest), DOUBLEREG(rSrc));
+ if (DOUBLEREG(rDest)) {
+ opcode = kThumb2Vmovd;
+ } else {
+ if (SINGLEREG(rDest)) {
+ opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr;
} else {
- if (SINGLEREG(rDest)) {
- opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr;
- } else {
- DCHECK(SINGLEREG(rSrc));
- opcode = kThumb2Fmrs;
- }
+ DCHECK(SINGLEREG(rSrc));
+ opcode = kThumb2Fmrs;
}
- LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
- if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
- res->flags.isNop = true;
- }
- return res;
+ }
+ LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
+ if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
+ res->flags.isNop = true;
+ }
+ return res;
}
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
diff --git a/src/compiler/codegen/arm/Thumb2/Ralloc.cc b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
index 7858318..98a110c 100644
--- a/src/compiler/codegen/arm/Thumb2/Ralloc.cc
+++ b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
@@ -30,96 +30,96 @@
*/
int oatAllocTypedTempPair(CompilationUnit* cUnit, bool fpHint, int regClass)
{
- int highReg;
- int lowReg;
- int res = 0;
+ int highReg;
+ int lowReg;
+ int res = 0;
- if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
- lowReg = oatAllocTempDouble(cUnit);
- highReg = lowReg + 1;
- } else {
- lowReg = oatAllocTemp(cUnit);
- highReg = oatAllocTemp(cUnit);
- }
- res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
- return res;
+ if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
+ lowReg = oatAllocTempDouble(cUnit);
+ highReg = lowReg + 1;
+ } else {
+ lowReg = oatAllocTemp(cUnit);
+ highReg = oatAllocTemp(cUnit);
+ }
+ res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
+ return res;
}
int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass)
{
- if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
- return oatAllocTempFloat(cUnit);
- return oatAllocTemp(cUnit);
+ if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
+ return oatAllocTempFloat(cUnit);
+ return oatAllocTemp(cUnit);
}
void oatInitializeRegAlloc(CompilationUnit* cUnit)
{
- int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
- int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
- int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
- int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
- int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
- RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true,
- kAllocRegAlloc);
- cUnit->regPool = pool;
- pool->numCoreRegs = numRegs;
- pool->coreRegs = (RegisterInfo *)
- oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs),
- true, kAllocRegAlloc);
- pool->numFPRegs = numFPRegs;
- pool->FPRegs = (RegisterInfo *)
- oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true,
- kAllocRegAlloc);
- oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
- oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
- // Keep special registers from being allocated
- for (int i = 0; i < numReserved; i++) {
- if (NO_SUSPEND && !cUnit->genDebugger &&
- (reservedRegs[i] == rSUSPEND)) {
- //To measure cost of suspend check
- continue;
- }
- oatMarkInUse(cUnit, reservedRegs[i]);
+ int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
+ int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
+ int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
+ int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
+ int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
+ RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true,
+ kAllocRegAlloc);
+ cUnit->regPool = pool;
+ pool->numCoreRegs = numRegs;
+ pool->coreRegs = (RegisterInfo *)
+ oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs),
+ true, kAllocRegAlloc);
+ pool->numFPRegs = numFPRegs;
+ pool->FPRegs = (RegisterInfo *)
+ oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true,
+ kAllocRegAlloc);
+ oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
+ oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
+ // Keep special registers from being allocated
+ for (int i = 0; i < numReserved; i++) {
+ if (NO_SUSPEND && !cUnit->genDebugger &&
+ (reservedRegs[i] == rSUSPEND)) {
+ //To measure cost of suspend check
+ continue;
}
- // Mark temp regs - all others not in use can be used for promotion
- for (int i = 0; i < numTemps; i++) {
- oatMarkTemp(cUnit, coreTemps[i]);
- }
- for (int i = 0; i < numFPTemps; i++) {
- oatMarkTemp(cUnit, fpTemps[i]);
- }
+ oatMarkInUse(cUnit, reservedRegs[i]);
+ }
+ // Mark temp regs - all others not in use can be used for promotion
+ for (int i = 0; i < numTemps; i++) {
+ oatMarkTemp(cUnit, coreTemps[i]);
+ }
+ for (int i = 0; i < numFPTemps; i++) {
+ oatMarkTemp(cUnit, fpTemps[i]);
+ }
- // Start allocation at r2 in an attempt to avoid clobbering return values
- pool->nextCoreReg = r2;
+ // Start allocation at r2 in an attempt to avoid clobbering return values
+ pool->nextCoreReg = r2;
- // Construct the alias map.
- cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
- sizeof(cUnit->phiAliasMap[0]), false,
- kAllocDFInfo);
- for (int i = 0; i < cUnit->numSSARegs; i++) {
- cUnit->phiAliasMap[i] = i;
+ // Construct the alias map.
+ cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
+ sizeof(cUnit->phiAliasMap[0]), false,
+ kAllocDFInfo);
+ for (int i = 0; i < cUnit->numSSARegs; i++) {
+ cUnit->phiAliasMap[i] = i;
+ }
+ for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
+ int defReg = phi->ssaRep->defs[0];
+ for (int i = 0; i < phi->ssaRep->numUses; i++) {
+ for (int j = 0; j < cUnit->numSSARegs; j++) {
+ if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
+ cUnit->phiAliasMap[j] = defReg;
+ }
+ }
}
- for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
- int defReg = phi->ssaRep->defs[0];
- for (int i = 0; i < phi->ssaRep->numUses; i++) {
- for (int j = 0; j < cUnit->numSSARegs; j++) {
- if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
- cUnit->phiAliasMap[j] = defReg;
- }
- }
- }
- }
+ }
}
void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
RegLocation rlFree)
{
- if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
- (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
- // No overlap, free both
- oatFreeTemp(cUnit, rlFree.lowReg);
- oatFreeTemp(cUnit, rlFree.highReg);
- }
+ if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
+ (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
+ // No overlap, free both
+ oatFreeTemp(cUnit, rlFree.lowReg);
+ oatFreeTemp(cUnit, rlFree.highReg);
+ }
}