ART: Add Mips32r6 backend support
Add Mips32r6 compiler support.
Don't use deprecated Mips32r2 instructions if running in Mips32r6
mode.
Change-Id: I54e689aa8c026ccb75c4af515aa2794f471c9f67
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc
index 2d26922..3b7e0ed 100644
--- a/compiler/dex/quick/mips/utility_mips.cc
+++ b/compiler/dex/quick/mips/utility_mips.cc
@@ -182,7 +182,11 @@
opcode = kMipsAnd;
break;
case kOpMul:
- opcode = kMipsMul;
+ if (isaIsR6_) {
+ opcode = kMipsR6Mul;
+ } else {
+ opcode = kMipsMul;
+ }
break;
case kOpOr:
opcode = kMipsOr;
@@ -271,7 +275,11 @@
break;
case kOpMul:
short_form = false;
- opcode = kMipsMul;
+ if (isaIsR6_) {
+ opcode = kMipsR6Mul;
+ } else {
+ opcode = kMipsMul;
+ }
break;
default:
LOG(FATAL) << "Bad case in OpRegRegImm";
@@ -359,12 +367,23 @@
LIR* MipsMir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) {
LIR *res;
- if (!r_dest.IsPair()) {
- // Form 64-bit pair
- r_dest = Solo64ToPair64(r_dest);
+ if (fpuIs32Bit_ || !r_dest.IsFloat()) {
+ // 32bit FPU (pairs) or loading into GPR.
+ if (!r_dest.IsPair()) {
+ // Form 64-bit pair
+ r_dest = Solo64ToPair64(r_dest);
+ }
+ res = LoadConstantNoClobber(r_dest.GetLow(), Low32Bits(value));
+ LoadConstantNoClobber(r_dest.GetHigh(), High32Bits(value));
+ } else {
+ // Here if we have a 64bit FPU and loading into FPR.
+ RegStorage r_temp = AllocTemp();
+ r_dest = Fp64ToSolo32(r_dest);
+ res = LoadConstantNoClobber(r_dest, Low32Bits(value));
+ LoadConstantNoClobber(r_temp, High32Bits(value));
+ NewLIR2(kMipsMthc1, r_temp.GetReg(), r_dest.GetReg());
+ FreeTemp(r_temp);
}
- res = LoadConstantNoClobber(r_dest.GetLow(), Low32Bits(value));
- LoadConstantNoClobber(r_dest.GetHigh(), High32Bits(value));
return res;
}
@@ -483,32 +502,29 @@
LIR *load2 = NULL;
MipsOpCode opcode = kMipsNop;
bool short_form = IS_SIMM16(displacement);
- bool pair = r_dest.IsPair();
+ bool is64bit = false;
switch (size) {
case k64:
case kDouble:
- if (!pair) {
+ is64bit = true;
+ if (fpuIs32Bit_ && !r_dest.IsPair()) {
// Form 64-bit pair
r_dest = Solo64ToPair64(r_dest);
- pair = 1;
- }
- if (r_dest.IsFloat()) {
- DCHECK_EQ(r_dest.GetLowReg(), r_dest.GetHighReg() - 1);
- opcode = kMipsFlwc1;
- } else {
- opcode = kMipsLw;
}
short_form = IS_SIMM16_2WORD(displacement);
- DCHECK_EQ((displacement & 0x3), 0);
- break;
+ FALLTHROUGH_INTENDED;
case k32:
case kSingle:
case kReference:
opcode = kMipsLw;
if (r_dest.IsFloat()) {
opcode = kMipsFlwc1;
- DCHECK(r_dest.IsSingle());
+ if (!is64bit) {
+ DCHECK(r_dest.IsSingle());
+ } else {
+ DCHECK(r_dest.IsDouble());
+ }
}
DCHECK_EQ((displacement & 0x3), 0);
break;
@@ -531,35 +547,56 @@
}
if (short_form) {
- if (!pair) {
+ if (!is64bit) {
load = res = NewLIR3(opcode, r_dest.GetReg(), displacement, r_base.GetReg());
} else {
- load = res = NewLIR3(opcode, r_dest.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
- load2 = NewLIR3(opcode, r_dest.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+ if (fpuIs32Bit_ || !r_dest.IsFloat()) {
+ DCHECK(r_dest.IsPair());
+ load = res = NewLIR3(opcode, r_dest.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+ load2 = NewLIR3(opcode, r_dest.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+ } else {
+ // Here if 64bit fpu and r_dest is a 64bit fp register.
+ RegStorage r_tmp = AllocTemp();
+ // FIXME: why is r_dest a 64BitPair here???
+ r_dest = Fp64ToSolo32(r_dest);
+ load = res = NewLIR3(kMipsFlwc1, r_dest.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+ load2 = NewLIR3(kMipsLw, r_tmp.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+ NewLIR2(kMipsMthc1, r_tmp.GetReg(), r_dest.GetReg());
+ FreeTemp(r_tmp);
+ }
}
} else {
- if (pair) {
- RegStorage r_tmp = AllocTemp();
- res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement);
- load = NewLIR3(opcode, r_dest.GetLowReg(), LOWORD_OFFSET, r_tmp.GetReg());
- load2 = NewLIR3(opcode, r_dest.GetHighReg(), HIWORD_OFFSET, r_tmp.GetReg());
- FreeTemp(r_tmp);
- } else {
- RegStorage r_tmp = (r_base == r_dest) ? AllocTemp() : r_dest;
+ if (!is64bit) {
+ RegStorage r_tmp = (r_base == r_dest || r_dest.IsFloat()) ? AllocTemp() : r_dest;
res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement);
load = NewLIR3(opcode, r_dest.GetReg(), 0, r_tmp.GetReg());
if (r_tmp != r_dest)
FreeTemp(r_tmp);
+ } else {
+ RegStorage r_tmp = AllocTemp();
+ res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement);
+ if (fpuIs32Bit_ || !r_dest.IsFloat()) {
+ DCHECK(r_dest.IsPair());
+ load = NewLIR3(opcode, r_dest.GetLowReg(), LOWORD_OFFSET, r_tmp.GetReg());
+ load2 = NewLIR3(opcode, r_dest.GetHighReg(), HIWORD_OFFSET, r_tmp.GetReg());
+ } else {
+ // Here if 64bit fpu and r_dest is a 64bit fp register
+ r_dest = Fp64ToSolo32(r_dest);
+ load = res = NewLIR3(kMipsFlwc1, r_dest.GetReg(), LOWORD_OFFSET, r_tmp.GetReg());
+ load2 = NewLIR3(kMipsLw, r_tmp.GetReg(), HIWORD_OFFSET, r_tmp.GetReg());
+ NewLIR2(kMipsMthc1, r_tmp.GetReg(), r_dest.GetReg());
+ }
+ FreeTemp(r_tmp);
}
}
if (mem_ref_type_ == ResourceMask::kDalvikReg) {
DCHECK_EQ(r_base, rs_rMIPS_SP);
- AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
- true /* is_load */, pair /* is64bit */);
- if (pair) {
+ AnnotateDalvikRegAccess(load, (displacement + (is64bit ? LOWORD_OFFSET : 0)) >> 2,
+ true /* is_load */, is64bit /* is64bit */);
+ if (is64bit) {
AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
- true /* is_load */, pair /* is64bit */);
+ true /* is_load */, is64bit /* is64bit */);
}
}
return load;
@@ -594,32 +631,29 @@
LIR *store2 = NULL;
MipsOpCode opcode = kMipsNop;
bool short_form = IS_SIMM16(displacement);
- bool pair = r_src.IsPair();
+ bool is64bit = false;
switch (size) {
case k64:
case kDouble:
- if (!pair) {
+ is64bit = true;
+ if (fpuIs32Bit_ && !r_src.IsPair()) {
// Form 64-bit pair
r_src = Solo64ToPair64(r_src);
- pair = 1;
- }
- if (r_src.IsFloat()) {
- DCHECK_EQ(r_src.GetLowReg(), r_src.GetHighReg() - 1);
- opcode = kMipsFswc1;
- } else {
- opcode = kMipsSw;
}
short_form = IS_SIMM16_2WORD(displacement);
- DCHECK_EQ((displacement & 0x3), 0);
- break;
+ FALLTHROUGH_INTENDED;
case k32:
case kSingle:
case kReference:
opcode = kMipsSw;
if (r_src.IsFloat()) {
opcode = kMipsFswc1;
- DCHECK(r_src.IsSingle());
+ if (!is64bit) {
+ DCHECK(r_src.IsSingle());
+ } else {
+ DCHECK(r_src.IsDouble());
+ }
}
DCHECK_EQ((displacement & 0x3), 0);
break;
@@ -637,31 +671,53 @@
}
if (short_form) {
- if (!pair) {
+ if (!is64bit) {
store = res = NewLIR3(opcode, r_src.GetReg(), displacement, r_base.GetReg());
} else {
- store = res = NewLIR3(opcode, r_src.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
- store2 = NewLIR3(opcode, r_src.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+ if (fpuIs32Bit_ || !r_src.IsFloat()) {
+ DCHECK(r_src.IsPair());
+ store = res = NewLIR3(opcode, r_src.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+ store2 = NewLIR3(opcode, r_src.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+ } else {
+ // Here if 64bit fpu and r_src is a 64bit fp register
+ RegStorage r_tmp = AllocTemp();
+ r_src = Fp64ToSolo32(r_src);
+ store = res = NewLIR3(kMipsFswc1, r_src.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+ NewLIR2(kMipsMfhc1, r_tmp.GetReg(), r_src.GetReg());
+ store2 = NewLIR3(kMipsSw, r_tmp.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
+ FreeTemp(r_tmp);
+ }
}
} else {
RegStorage r_scratch = AllocTemp();
res = OpRegRegImm(kOpAdd, r_scratch, r_base, displacement);
- if (!pair) {
+ if (!is64bit) {
store = NewLIR3(opcode, r_src.GetReg(), 0, r_scratch.GetReg());
} else {
- store = NewLIR3(opcode, r_src.GetLowReg(), LOWORD_OFFSET, r_scratch.GetReg());
- store2 = NewLIR3(opcode, r_src.GetHighReg(), HIWORD_OFFSET, r_scratch.GetReg());
+ if (fpuIs32Bit_ || !r_src.IsFloat()) {
+ DCHECK(r_src.IsPair());
+ store = NewLIR3(opcode, r_src.GetLowReg(), LOWORD_OFFSET, r_scratch.GetReg());
+ store2 = NewLIR3(opcode, r_src.GetHighReg(), HIWORD_OFFSET, r_scratch.GetReg());
+ } else {
+ // Here if 64bit fpu and r_src is a 64bit fp register
+ RegStorage r_tmp = AllocTemp();
+ r_src = Fp64ToSolo32(r_src);
+ store = NewLIR3(kMipsFswc1, r_src.GetReg(), LOWORD_OFFSET, r_scratch.GetReg());
+ NewLIR2(kMipsMfhc1, r_tmp.GetReg(), r_src.GetReg());
+ store2 = NewLIR3(kMipsSw, r_tmp.GetReg(), HIWORD_OFFSET, r_scratch.GetReg());
+ FreeTemp(r_tmp);
+ }
}
FreeTemp(r_scratch);
}
if (mem_ref_type_ == ResourceMask::kDalvikReg) {
DCHECK_EQ(r_base, rs_rMIPS_SP);
- AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
- false /* is_load */, pair /* is64bit */);
- if (pair) {
+ AnnotateDalvikRegAccess(store, (displacement + (is64bit ? LOWORD_OFFSET : 0)) >> 2,
+ false /* is_load */, is64bit /* is64bit */);
+ if (is64bit) {
AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
- false /* is_load */, pair /* is64bit */);
+ false /* is_load */, is64bit /* is64bit */);
}
}