Add 3rd argument register to X86.
Implement more instructions.
Change-Id: I3af7bbaf18eedc6537f1cfc2d57c4f6106fb5164
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc
index 96fa08a..aef5879 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -32,7 +32,7 @@
#endif
};
/*static*/ int reservedRegs[] = {rSP};
-/*static*/ int coreTemps[] = {rAX, rCX, rDX};
+/*static*/ int coreTemps[] = {rAX, rCX, rDX, rBX};
/*static*/ int fpRegs[] = {
fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
#ifdef TARGET_REX_SUPPORT
@@ -93,25 +93,24 @@
* 2) The codegen is under fixed register usage
*/
LIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, int value) {
- LIR *res;
-
int rDestSave = rDest;
- int isFpReg = FPREG(rDest);
- if (isFpReg) {
+ if (FPREG(rDest)) {
+ if (value == 0) {
+ return newLIR2(cUnit, kX86XorpsRR, rDest, rDest);
+ }
DCHECK(SINGLEREG(rDest));
rDest = oatAllocTemp(cUnit);
}
- /* See if the value can be constructed cheaply */
+ LIR *res;
if (value == 0) {
res = newLIR2(cUnit, kX86Xor32RR, rDest, rDest);
} else {
res = newLIR2(cUnit, kX86Mov32RI, rDest, value);
}
- if (isFpReg) {
- UNIMPLEMENTED(FATAL);
- newLIR2(cUnit, kX86Mov32RR, rDest, rDestSave);
+ if (FPREG(rDestSave)) {
+ newLIR2(cUnit, kX86MovdxrRR, rDestSave, rDest);
oatFreeTemp(cUnit, rDest);
}
@@ -120,7 +119,7 @@
LIR* opBranchUnconditional(CompilationUnit *cUnit, OpKind op) {
CHECK_EQ(op, kOpUncondBr);
- return newLIR1(cUnit, kX86Jmp, 0 /* offset to be patched */ );
+ return newLIR1(cUnit, kX86Jmp8, 0 /* offset to be patched */ );
}
LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
@@ -128,7 +127,7 @@
X86ConditionCode oatX86ConditionEncoding(ConditionCode cond);
LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target)
{
- LIR* branch = newLIR2(cUnit, kX86Jcc, 0 /* offset to be patched */,
+ LIR* branch = newLIR2(cUnit, kX86Jcc8, 0 /* offset to be patched */,
oatX86ConditionEncoding(cc));
branch->target = target;
return branch;
@@ -285,13 +284,18 @@
if (op == kOpMul) {
X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI;
return newLIR3(cUnit, opcode, rDest, rSrc, value);
- }
- if (op == kOpLsl && value >= 0 && value <= 3) { // lea shift special case
- return newLIR5(cUnit, kX86Lea32RA, rDest, rSrc /* base */,
- r4sib_no_index /* index */, value /* scale */, value /* disp */);
+ } else if (op == kOpAnd) {
+ if (value == 0xFF) {
+ return newLIR2(cUnit, kX86Movzx8RR, rDest, rSrc);
+ } else if (value == 0xFFFF) {
+ return newLIR2(cUnit, kX86Movzx16RR, rDest, rSrc);
+ }
}
if (rDest != rSrc) {
- if (op == kOpAdd) { // lea add special case
+ if (op == kOpLsl && value >= 0 && value <= 3) { // lea shift special case
+ return newLIR5(cUnit, kX86Lea32RA, rDest, rSrc /* base */,
+ r4sib_no_index /* index */, value /* scale */, value /* disp */);
+ } else if (op == kOpAdd) { // lea add special case
return newLIR5(cUnit, kX86Lea32RA, rDest, rSrc /* base */,
r4sib_no_index /* index */, 0 /* scale */, value /* disp */);
}
@@ -326,8 +330,26 @@
int rDestHi, int valLo, int valHi)
{
LIR *res;
- res = loadConstantNoClobber(cUnit, rDestLo, valLo);
- loadConstantNoClobber(cUnit, rDestHi, valHi);
+ if (FPREG(rDestLo)) {
+ DCHECK(FPREG(rDestHi)); // ignore rDestHi
+ if (valLo == 0 && valHi == 0) {
+ return newLIR2(cUnit, kX86XorpsRR, rDestLo, rDestLo);
+ } else {
+ if (valLo == 0) {
+ res = newLIR2(cUnit, kX86XorpsRR, rDestLo, rDestLo);
+ } else {
+ res = loadConstantNoClobber(cUnit, rDestLo, valLo);
+ }
+ if (valHi != 0) {
+ loadConstantNoClobber(cUnit, rDestHi, valHi);
+ newLIR2(cUnit, kX86PsllqRI, rDestHi, 32);
+ newLIR2(cUnit, kX86OrpsRR, rDestLo, rDestHi);
+ }
+ }
+ } else {
+ res = loadConstantNoClobber(cUnit, rDestLo, valLo);
+ loadConstantNoClobber(cUnit, rDestHi, valHi);
+ }
return res;
}
@@ -593,23 +615,22 @@
rDestLo, rDestHi, kLong, sReg);
}
-LIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
- int displacement, int rSrc, int rSrcHi,
- OpSize size)
-{
- LIR *res = NULL;
+LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, MIR *mir,
+ int rBase, int rIndex, int scale, int displacement,
+ int rSrc, int rSrcHi,
+ OpSize size, int sReg) {
LIR *store = NULL;
LIR *store2 = NULL;
- X86OpCode opcode = kX86Bkpt;
+ bool isArray = rIndex != INVALID_REG;
bool pair = false;
bool is64bit = false;
+ X86OpCode opcode = kX86Nop;
switch (size) {
case kLong:
case kDouble:
is64bit = true;
if (FPREG(rSrc)) {
- pair = false;
- opcode = kX86MovsdMR;
+ opcode = isArray ? kX86MovsdAR : kX86MovsdMR;
if (DOUBLEREG(rSrc)) {
rSrc = rSrc - FP_DOUBLE;
} else {
@@ -619,61 +640,61 @@
rSrcHi = rSrc + 1;
} else {
pair = true;
- opcode = kX86Mov32MR;
+ opcode = isArray ? kX86Mov32AR : kX86Mov32MR;
}
// TODO: double store is to unaligned address
DCHECK_EQ((displacement & 0x3), 0);
break;
case kWord:
case kSingle:
- opcode = kX86Mov32MR;
+ opcode = isArray ? kX86Mov32AR : kX86Mov32MR;
if (FPREG(rSrc)) {
- opcode = kX86MovssMR;
+ opcode = isArray ? kX86MovssAR : kX86MovssMR;
DCHECK(SINGLEREG(rSrc));
}
DCHECK_EQ((displacement & 0x3), 0);
break;
case kUnsignedHalf:
case kSignedHalf:
- opcode = kX86Mov16MR;
+ opcode = isArray ? kX86Mov16AR : kX86Mov16MR;
DCHECK_EQ((displacement & 0x1), 0);
break;
case kUnsignedByte:
case kSignedByte:
- opcode = kX86Mov8MR;
+ opcode = isArray ? kX86Mov8AR : kX86Mov8MR;
break;
default:
- LOG(FATAL) << "Bad case in storeBaseIndexedBody";
+ LOG(FATAL) << "Bad case in loadBaseIndexedDispBody";
}
- if (!pair) {
- store = res = newLIR3(cUnit, opcode, rBase, displacement, rSrc);
+ if (!isArray) {
+ if (!pair) {
+ store = newLIR3(cUnit, opcode, rBase, displacement + LOWORD_OFFSET, rSrc);
+ } else {
+ store = newLIR3(cUnit, opcode, rBase, displacement + LOWORD_OFFSET, rSrc);
+ store2 = newLIR3(cUnit, opcode, rBase, displacement + HIWORD_OFFSET, rSrcHi);
+ }
} else {
- store = res = newLIR3(cUnit, opcode, rBase, displacement + LOWORD_OFFSET, rSrc);
- store2 = newLIR3(cUnit, opcode, rBase, displacement + HIWORD_OFFSET, rSrcHi);
- }
-
- if (rBase == rSP) {
- annotateDalvikRegAccess(store, (displacement + LOWORD_OFFSET) >> 2,
- false /* isLoad */, is64bit);
- if (pair) {
- annotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
- false /* isLoad */, is64bit);
+ if (!pair) {
+ store = newLIR5(cUnit, opcode, rBase, rIndex, scale, displacement + LOWORD_OFFSET, rSrc);
+ } else {
+ store = newLIR5(cUnit, opcode, rBase, rIndex, scale, displacement + LOWORD_OFFSET, rSrc);
+ store2 = newLIR5(cUnit, opcode, rBase, rIndex, scale, displacement + HIWORD_OFFSET, rSrcHi);
}
}
- return res;
+
+ return store;
}
-LIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
- int displacement, int rSrc, OpSize size)
-{
- return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
+LIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, int displacement, int rSrc, OpSize size) {
+ return storeBaseIndexedDisp(cUnit, NULL, rBase, INVALID_REG, 0, displacement,
+ rSrc, INVALID_REG, size, INVALID_SREG);
}
-LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
- int displacement, int rSrcLo, int rSrcHi)
-{
- return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
+LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, int displacement,
+ int rSrcLo, int rSrcHi) {
+ return storeBaseIndexedDisp(cUnit, NULL, rBase, INVALID_REG, 0, displacement,
+ rSrcLo, rSrcHi, kLong, INVALID_SREG);
}
void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)