summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/mips
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/quick/mips')
-rw-r--r--compiler/dex/quick/mips/README.mips2
-rw-r--r--compiler/dex/quick/mips/assemble_mips.cc9
-rw-r--r--compiler/dex/quick/mips/call_mips.cc20
-rw-r--r--compiler/dex/quick/mips/codegen_mips.h16
-rw-r--r--compiler/dex/quick/mips/fp_mips.cc12
-rw-r--r--compiler/dex/quick/mips/int_mips.cc58
-rw-r--r--compiler/dex/quick/mips/mips_lir.h293
-rw-r--r--compiler/dex/quick/mips/target_mips.cc342
-rw-r--r--compiler/dex/quick/mips/utility_mips.cc62
9 files changed, 390 insertions, 424 deletions
diff --git a/compiler/dex/quick/mips/README.mips b/compiler/dex/quick/mips/README.mips
index 061c157256..ff561fa935 100644
--- a/compiler/dex/quick/mips/README.mips
+++ b/compiler/dex/quick/mips/README.mips
@@ -17,7 +17,7 @@ problems that need to be addressed:
code generation for switch tables, fill array data, 64-bit
data handling and the register usage conventions.
- o The memory model. Verify that oatGenMemoryBarrier() generates the
+ o The memory model. Verify that GenMemoryBarrier() generates the
appropriate flavor of sync.
Register promotion
diff --git a/compiler/dex/quick/mips/assemble_mips.cc b/compiler/dex/quick/mips/assemble_mips.cc
index a5792549ca..baae31915e 100644
--- a/compiler/dex/quick/mips/assemble_mips.cc
+++ b/compiler/dex/quick/mips/assemble_mips.cc
@@ -672,16 +672,17 @@ AssemblerStatus MipsMir2Lir::AssembleInstructions(CodeOffset start_addr) {
bits |= (value << encoder->field_loc[i].end);
break;
case kFmtDfp: {
- DCHECK(MIPS_DOUBLEREG(operand));
+ // TODO: do we need to adjust now that we're using 64BitSolo?
+ DCHECK(RegStorage::IsDouble(operand)) << ", Operand = 0x" << std::hex << operand;
DCHECK_EQ((operand & 0x1), 0U);
- value = ((operand & MIPS_FP_REG_MASK) << encoder->field_loc[i].start) &
+ value = (RegStorage::RegNum(operand) << encoder->field_loc[i].start) &
((1 << (encoder->field_loc[i].end + 1)) - 1);
bits |= value;
break;
}
case kFmtSfp:
- DCHECK(MIPS_SINGLEREG(operand));
- value = ((operand & MIPS_FP_REG_MASK) << encoder->field_loc[i].start) &
+ DCHECK(RegStorage::IsSingle(operand)) << ", Operand = 0x" << std::hex << operand;
+ value = (RegStorage::RegNum(operand) << encoder->field_loc[i].start) &
((1 << (encoder->field_loc[i].end + 1)) - 1);
bits |= value;
break;
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index df13882cf5..3af3715f47 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -295,10 +295,10 @@ void MipsMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
* expanding the frame or flushing. This leaves the utility
* code with a single temp: r12. This should be enough.
*/
- LockTemp(rMIPS_ARG0);
- LockTemp(rMIPS_ARG1);
- LockTemp(rMIPS_ARG2);
- LockTemp(rMIPS_ARG3);
+ LockTemp(rs_rMIPS_ARG0);
+ LockTemp(rs_rMIPS_ARG1);
+ LockTemp(rs_rMIPS_ARG2);
+ LockTemp(rs_rMIPS_ARG3);
/*
* We can safely skip the stack overflow check if we're
@@ -351,10 +351,10 @@ void MipsMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
FlushIns(ArgLocs, rl_method);
- FreeTemp(rMIPS_ARG0);
- FreeTemp(rMIPS_ARG1);
- FreeTemp(rMIPS_ARG2);
- FreeTemp(rMIPS_ARG3);
+ FreeTemp(rs_rMIPS_ARG0);
+ FreeTemp(rs_rMIPS_ARG1);
+ FreeTemp(rs_rMIPS_ARG2);
+ FreeTemp(rs_rMIPS_ARG3);
}
void MipsMir2Lir::GenExitSequence() {
@@ -362,8 +362,8 @@ void MipsMir2Lir::GenExitSequence() {
* In the exit path, rMIPS_RET0/rMIPS_RET1 are live - make sure they aren't
* allocated by the register utilities as temps.
*/
- LockTemp(rMIPS_RET0);
- LockTemp(rMIPS_RET1);
+ LockTemp(rs_rMIPS_RET0);
+ LockTemp(rs_rMIPS_RET1);
NewLIR0(kPseudoMethodExit);
UnSpillCoreRegs();
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index 81d6782288..7a8376e8b1 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -39,7 +39,7 @@ class MipsMir2Lir FINAL : public Mir2Lir {
LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale,
OpSize size);
LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_dest, RegStorage r_dest_hi, OpSize size, int s_reg);
+ RegStorage r_dest, OpSize size, int s_reg);
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
LIR* LoadConstantWide(RegStorage r_dest, int64_t value);
LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, OpSize size);
@@ -47,16 +47,12 @@ class MipsMir2Lir FINAL : public Mir2Lir {
LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
OpSize size);
LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_src, RegStorage r_src_hi, OpSize size, int s_reg);
+ RegStorage r_src, OpSize size, int s_reg);
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
// Required for target - register utilities.
- bool IsFpReg(int reg);
- bool IsFpReg(RegStorage reg);
- bool SameRegType(int reg1, int reg2);
RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
- int S2d(int low_reg, int high_reg);
RegStorage TargetReg(SpecialTargetRegister reg);
RegStorage GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
@@ -65,16 +61,14 @@ class MipsMir2Lir FINAL : public Mir2Lir {
RegLocation LocCReturnDouble();
RegLocation LocCReturnFloat();
RegLocation LocCReturnWide();
- uint32_t FpRegMask();
- uint64_t GetRegMaskCommon(int reg);
+ uint64_t GetRegMaskCommon(RegStorage reg);
void AdjustSpillMask();
void ClobberCallerSave();
- void FlushReg(RegStorage reg);
- void FlushRegWide(RegStorage reg);
void FreeCallTemps();
void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free);
void LockCallTemps();
- void MarkPreservedSingle(int v_reg, int reg);
+ void MarkPreservedSingle(int v_reg, RegStorage reg);
+ void MarkPreservedDouble(int v_reg, RegStorage reg);
void CompilerInitializeRegAlloc();
// Required for target - miscellaneous.
diff --git a/compiler/dex/quick/mips/fp_mips.cc b/compiler/dex/quick/mips/fp_mips.cc
index a479dc787a..9fffb2fd1d 100644
--- a/compiler/dex/quick/mips/fp_mips.cc
+++ b/compiler/dex/quick/mips/fp_mips.cc
@@ -111,15 +111,13 @@ void MipsMir2Lir::GenArithOpDouble(Instruction::Code opcode,
rl_result = EvalLoc(rl_dest, kFPReg, true);
DCHECK(rl_dest.wide);
DCHECK(rl_result.wide);
- NewLIR3(op, S2d(rl_result.reg.GetLowReg(), rl_result.reg.GetHighReg()), S2d(rl_src1.reg.GetLowReg(), rl_src1.reg.GetHighReg()),
- S2d(rl_src2.reg.GetLowReg(), rl_src2.reg.GetHighReg()));
+ NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
StoreValueWide(rl_dest, rl_result);
}
void MipsMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src) {
int op = kMipsNop;
- int src_reg;
RegLocation rl_result;
switch (opcode) {
case Instruction::INT_TO_FLOAT:
@@ -157,18 +155,14 @@ void MipsMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
}
if (rl_src.wide) {
rl_src = LoadValueWide(rl_src, kFPReg);
- src_reg = S2d(rl_src.reg.GetLowReg(), rl_src.reg.GetHighReg());
} else {
rl_src = LoadValue(rl_src, kFPReg);
- src_reg = rl_src.reg.GetReg();
}
+ rl_result = EvalLoc(rl_dest, kFPReg, true);
+ NewLIR2(op, rl_result.reg.GetReg(), rl_src.reg.GetReg());
if (rl_dest.wide) {
- rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, S2d(rl_result.reg.GetLowReg(), rl_result.reg.GetHighReg()), src_reg);
StoreValueWide(rl_dest, rl_result);
} else {
- rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, rl_result.reg.GetReg(), src_reg);
StoreValue(rl_dest, rl_result);
}
}
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 7c0becd41a..1410e14925 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -44,16 +44,16 @@ void MipsMir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_src2) {
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
- int t0 = AllocTemp().GetReg();
- int t1 = AllocTemp().GetReg();
+ RegStorage t0 = AllocTemp();
+ RegStorage t1 = AllocTemp();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- NewLIR3(kMipsSlt, t0, rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
- NewLIR3(kMipsSlt, t1, rl_src2.reg.GetHighReg(), rl_src1.reg.GetHighReg());
- NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1, t0);
+ NewLIR3(kMipsSlt, t0.GetReg(), rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
+ NewLIR3(kMipsSlt, t1.GetReg(), rl_src2.reg.GetHighReg(), rl_src1.reg.GetHighReg());
+ NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1.GetReg(), t0.GetReg());
LIR* branch = OpCmpImmBranch(kCondNe, rl_result.reg, 0, NULL);
- NewLIR3(kMipsSltu, t0, rl_src1.reg.GetLowReg(), rl_src2.reg.GetLowReg());
- NewLIR3(kMipsSltu, t1, rl_src2.reg.GetLowReg(), rl_src1.reg.GetLowReg());
- NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1, t0);
+ NewLIR3(kMipsSltu, t0.GetReg(), rl_src1.reg.GetLowReg(), rl_src2.reg.GetLowReg());
+ NewLIR3(kMipsSltu, t1.GetReg(), rl_src2.reg.GetLowReg(), rl_src1.reg.GetLowReg());
+ NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1.GetReg(), t0.GetReg());
FreeTemp(t0);
FreeTemp(t1);
LIR* target = NewLIR0(kPseudoTargetLabel);
@@ -114,13 +114,13 @@ LIR* MipsMir2Lir::OpCmpBranch(ConditionCode cond, RegStorage src1, RegStorage sr
if (cmp_zero) {
branch = NewLIR2(br_op, src1.GetReg(), src2.GetReg());
} else {
- int t_reg = AllocTemp().GetReg();
+ RegStorage t_reg = AllocTemp();
if (swapped) {
- NewLIR3(slt_op, t_reg, src2.GetReg(), src1.GetReg());
+ NewLIR3(slt_op, t_reg.GetReg(), src2.GetReg(), src1.GetReg());
} else {
- NewLIR3(slt_op, t_reg, src1.GetReg(), src2.GetReg());
+ NewLIR3(slt_op, t_reg.GetReg(), src1.GetReg(), src2.GetReg());
}
- branch = NewLIR1(br_op, t_reg);
+ branch = NewLIR1(br_op, t_reg.GetReg());
FreeTemp(t_reg);
}
branch->target = target;
@@ -167,7 +167,7 @@ LIR* MipsMir2Lir::OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) {
if (r_src.IsPair()) {
r_src = r_src.GetLow();
}
- if (MIPS_FPREG(r_dest.GetReg()) || MIPS_FPREG(r_src.GetReg()))
+ if (r_dest.IsFloat() || r_src.IsFloat())
return OpFpRegCopy(r_dest, r_src);
LIR* res = RawLIR(current_dalvik_offset_, kMipsMove,
r_dest.GetReg(), r_src.GetReg());
@@ -186,17 +186,15 @@ void MipsMir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) {
void MipsMir2Lir::OpRegCopyWide(RegStorage r_dest, RegStorage r_src) {
if (r_dest != r_src) {
- bool dest_fp = MIPS_FPREG(r_dest.GetLowReg());
- bool src_fp = MIPS_FPREG(r_src.GetLowReg());
+ bool dest_fp = r_dest.IsFloat();
+ bool src_fp = r_src.IsFloat();
if (dest_fp) {
if (src_fp) {
- // FIXME: handle this here - reserve OpRegCopy for 32-bit copies.
- OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())),
- RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg())));
- } else {
- /* note the operands are swapped for the mtc1 instr */
- NewLIR2(kMipsMtc1, r_src.GetLowReg(), r_dest.GetLowReg());
- NewLIR2(kMipsMtc1, r_src.GetHighReg(), r_dest.GetHighReg());
+ OpRegCopy(r_dest, r_src);
+ } else {
+ /* note the operands are swapped for the mtc1 instr */
+ NewLIR2(kMipsMtc1, r_src.GetLowReg(), r_dest.GetLowReg());
+ NewLIR2(kMipsMtc1, r_src.GetHighReg(), r_dest.GetHighReg());
}
} else {
if (src_fp) {
@@ -238,9 +236,9 @@ RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, RegStorage reg1, RegStor
RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, RegStorage reg1, int lit,
bool is_div) {
- int t_reg = AllocTemp().GetReg();
- NewLIR3(kMipsAddiu, t_reg, rZERO, lit);
- NewLIR2(kMipsDiv, reg1.GetReg(), t_reg);
+ RegStorage t_reg = AllocTemp();
+ NewLIR3(kMipsAddiu, t_reg.GetReg(), rZERO, lit);
+ NewLIR2(kMipsDiv, reg1.GetReg(), t_reg.GetReg());
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_div) {
NewLIR1(kMipsMflo, rl_result.reg.GetReg());
@@ -470,7 +468,7 @@ void MipsMir2Lir::GenXorLong(Instruction::Code opcode, RegLocation rl_dest,
*/
void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_dest, int scale) {
- RegisterClass reg_class = oat_reg_class_by_size(size);
+ RegisterClass reg_class = RegClassBySize(size);
int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
RegLocation rl_result;
@@ -496,7 +494,7 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
}
/* reg_ptr -> array data */
OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg, data_offset);
- FreeTemp(rl_array.reg.GetReg());
+ FreeTemp(rl_array.reg);
if ((size == k64) || (size == kDouble)) {
if (scale) {
RegStorage r_new_index = AllocTemp();
@@ -537,7 +535,7 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
*/
void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark) {
- RegisterClass reg_class = oat_reg_class_by_size(size);
+ RegisterClass reg_class = RegClassBySize(size);
int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
@@ -551,8 +549,8 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
rl_index = LoadValue(rl_index, kCoreReg);
RegStorage reg_ptr;
bool allocated_reg_ptr_temp = false;
- if (IsTemp(rl_array.reg.GetReg()) && !card_mark) {
- Clobber(rl_array.reg.GetReg());
+ if (IsTemp(rl_array.reg) && !card_mark) {
+ Clobber(rl_array.reg);
reg_ptr = rl_array.reg;
} else {
reg_ptr = AllocTemp();
diff --git a/compiler/dex/quick/mips/mips_lir.h b/compiler/dex/quick/mips/mips_lir.h
index c5150eec31..5b2cb9d85e 100644
--- a/compiler/dex/quick/mips/mips_lir.h
+++ b/compiler/dex/quick/mips/mips_lir.h
@@ -86,26 +86,6 @@ namespace art {
* +========================+
*/
-// Offset to distingish FP regs.
-#define MIPS_FP_REG_OFFSET 32
-// Offset to distinguish DP FP regs.
-#define MIPS_FP_DOUBLE 64
-// Reg types.
-#define MIPS_REGTYPE(x) (x & (MIPS_FP_REG_OFFSET | MIPS_FP_DOUBLE))
-#define MIPS_FPREG(x) ((x & MIPS_FP_REG_OFFSET) == MIPS_FP_REG_OFFSET)
-#define MIPS_DOUBLEREG(x) ((x & MIPS_FP_DOUBLE) == MIPS_FP_DOUBLE)
-#define MIPS_SINGLEREG(x) (MIPS_FPREG(x) && !MIPS_DOUBLEREG(x))
-// FIXME: out of date comment.
-/*
- * Note: the low register of a floating point pair is sufficient to
- * create the name of a double, but require both names to be passed to
- * allow for asserts to verify that the pair is consecutive if significant
- * rework is done in this area. Also, it is a good reminder in the calling
- * code that reg locations always describe doubles as a pair of singles.
- */
-#define MIPS_S2D(x, y) ((x) | MIPS_FP_DOUBLE)
-// Mask to strip off fp flags.
-#define MIPS_FP_REG_MASK (MIPS_FP_REG_OFFSET-1)
#define LOWORD_OFFSET 0
#define HIWORD_OFFSET 4
@@ -159,135 +139,159 @@ enum MipsResourceEncodingPos {
#define ENCODE_MIPS_REG_LO (1ULL << kMipsRegLO)
enum MipsNativeRegisterPool {
- rZERO = 0,
- rAT = 1,
- rV0 = 2,
- rV1 = 3,
- rA0 = 4,
- rA1 = 5,
- rA2 = 6,
- rA3 = 7,
- rT0 = 8,
- rT1 = 9,
- rT2 = 10,
- rT3 = 11,
- rT4 = 12,
- rT5 = 13,
- rT6 = 14,
- rT7 = 15,
- rS0 = 16,
- rS1 = 17,
- rS2 = 18,
- rS3 = 19,
- rS4 = 20,
- rS5 = 21,
- rS6 = 22,
- rS7 = 23,
- rT8 = 24,
- rT9 = 25,
- rK0 = 26,
- rK1 = 27,
- rGP = 28,
- rSP = 29,
- rFP = 30,
- rRA = 31,
+ rZERO = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0,
+ rAT = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 1,
+ rV0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 2,
+ rV1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 3,
+ rA0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 4,
+ rA1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 5,
+ rA2 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 6,
+ rA3 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 7,
+ rT0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
+ rT1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 9,
+ rT2 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
+ rT3 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
+ rT4 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
+ rT5 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
+ rT6 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
+ rT7 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
+ rS0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
+ rS1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 17,
+ rS2 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 18,
+ rS3 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 19,
+ rS4 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 20,
+ rS5 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 21,
+ rS6 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 22,
+ rS7 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 23,
+ rT8 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 24,
+ rT9 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 25,
+ rK0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 26,
+ rK1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 27,
+ rGP = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 28,
+ rSP = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 29,
+ rFP = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 30,
+ rRA = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 31,
- rF0 = 0 + MIPS_FP_REG_OFFSET,
- rF1,
- rF2,
- rF3,
- rF4,
- rF5,
- rF6,
- rF7,
- rF8,
- rF9,
- rF10,
- rF11,
- rF12,
- rF13,
- rF14,
- rF15,
+ rF0 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 0,
+ rF1 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 1,
+ rF2 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 2,
+ rF3 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 3,
+ rF4 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 4,
+ rF5 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 5,
+ rF6 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 6,
+ rF7 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 7,
+ rF8 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 8,
+ rF9 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 9,
+ rF10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
+ rF11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
+ rF12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
+ rF13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
+ rF14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
+ rF15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
#if 0
/*
* TODO: The shared resource mask doesn't have enough bit positions to describe all
* MIPS registers. Expand it and enable use of fp registers 16 through 31.
*/
- rF16,
- rF17,
- rF18,
- rF19,
- rF20,
- rF21,
- rF22,
- rF23,
- rF24,
- rF25,
- rF26,
- rF27,
- rF28,
- rF29,
- rF30,
- rF31,
+ rF16 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 16,
+ rF17 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 17,
+ rF18 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 18,
+ rF19 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 19,
+ rF20 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 20,
+ rF21 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 21,
+ rF22 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 22,
+ rF23 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 23,
+ rF24 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 24,
+ rF25 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 25,
+ rF26 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 26,
+ rF27 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 27,
+ rF28 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 28,
+ rF29 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 29,
+ rF30 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 30,
+ rF31 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 31,
#endif
- rDF0 = rF0 + MIPS_FP_DOUBLE,
- rDF1 = rF2 + MIPS_FP_DOUBLE,
- rDF2 = rF4 + MIPS_FP_DOUBLE,
- rDF3 = rF6 + MIPS_FP_DOUBLE,
- rDF4 = rF8 + MIPS_FP_DOUBLE,
- rDF5 = rF10 + MIPS_FP_DOUBLE,
- rDF6 = rF12 + MIPS_FP_DOUBLE,
- rDF7 = rF14 + MIPS_FP_DOUBLE,
+ rD0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 0,
+ rD1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 1,
+ rD2 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 2,
+ rD3 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 3,
+ rD4 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 4,
+ rD5 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 5,
+ rD6 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 6,
+ rD7 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 7,
#if 0 // TODO: expand resource mask to enable use of all MIPS fp registers.
- rDF8 = rF16 + MIPS_FP_DOUBLE,
- rDF9 = rF18 + MIPS_FP_DOUBLE,
- rDF10 = rF20 + MIPS_FP_DOUBLE,
- rDF11 = rF22 + MIPS_FP_DOUBLE,
- rDF12 = rF24 + MIPS_FP_DOUBLE,
- rDF13 = rF26 + MIPS_FP_DOUBLE,
- rDF14 = rF28 + MIPS_FP_DOUBLE,
- rDF15 = rF30 + MIPS_FP_DOUBLE,
+ rD8 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 8,
+ rD9 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 9,
+ rD10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
+ rD11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
+ rD12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
+ rD13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
+ rD14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
+ rD15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
#endif
};
-const RegStorage rs_rZERO(RegStorage::k32BitSolo, rZERO);
-const RegStorage rs_rAT(RegStorage::k32BitSolo, rAT);
-const RegStorage rs_rV0(RegStorage::k32BitSolo, rV0);
-const RegStorage rs_rV1(RegStorage::k32BitSolo, rV1);
-const RegStorage rs_rA0(RegStorage::k32BitSolo, rA0);
-const RegStorage rs_rA1(RegStorage::k32BitSolo, rA1);
-const RegStorage rs_rA2(RegStorage::k32BitSolo, rA2);
-const RegStorage rs_rA3(RegStorage::k32BitSolo, rA3);
-const RegStorage rs_rT0(RegStorage::k32BitSolo, rT0);
-const RegStorage rs_rT1(RegStorage::k32BitSolo, rT1);
-const RegStorage rs_rT2(RegStorage::k32BitSolo, rT2);
-const RegStorage rs_rT3(RegStorage::k32BitSolo, rT3);
-const RegStorage rs_rT4(RegStorage::k32BitSolo, rT4);
-const RegStorage rs_rT5(RegStorage::k32BitSolo, rT5);
-const RegStorage rs_rT6(RegStorage::k32BitSolo, rT6);
-const RegStorage rs_rT7(RegStorage::k32BitSolo, rT7);
-const RegStorage rs_rS0(RegStorage::k32BitSolo, rS0);
-const RegStorage rs_rS1(RegStorage::k32BitSolo, rS1);
-const RegStorage rs_rS2(RegStorage::k32BitSolo, rS2);
-const RegStorage rs_rS3(RegStorage::k32BitSolo, rS3);
-const RegStorage rs_rS4(RegStorage::k32BitSolo, rS4);
-const RegStorage rs_rS5(RegStorage::k32BitSolo, rS5);
-const RegStorage rs_rS6(RegStorage::k32BitSolo, rS6);
-const RegStorage rs_rS7(RegStorage::k32BitSolo, rS7);
-const RegStorage rs_rT8(RegStorage::k32BitSolo, rT8);
-const RegStorage rs_rT9(RegStorage::k32BitSolo, rT9);
-const RegStorage rs_rK0(RegStorage::k32BitSolo, rK0);
-const RegStorage rs_rK1(RegStorage::k32BitSolo, rK1);
-const RegStorage rs_rGP(RegStorage::k32BitSolo, rGP);
-const RegStorage rs_rSP(RegStorage::k32BitSolo, rSP);
-const RegStorage rs_rFP(RegStorage::k32BitSolo, rFP);
-const RegStorage rs_rRA(RegStorage::k32BitSolo, rRA);
-const RegStorage rs_rF12(RegStorage::k32BitSolo, rF12);
-const RegStorage rs_rF13(RegStorage::k32BitSolo, rF13);
-const RegStorage rs_rF14(RegStorage::k32BitSolo, rF14);
-const RegStorage rs_rF15(RegStorage::k32BitSolo, rF15);
-const RegStorage rs_rF0(RegStorage::k32BitSolo, rF0);
-const RegStorage rs_rF1(RegStorage::k32BitSolo, rF1);
+constexpr RegStorage rs_rZERO(RegStorage::kValid | rZERO);
+constexpr RegStorage rs_rAT(RegStorage::kValid | rAT);
+constexpr RegStorage rs_rV0(RegStorage::kValid | rV0);
+constexpr RegStorage rs_rV1(RegStorage::kValid | rV1);
+constexpr RegStorage rs_rA0(RegStorage::kValid | rA0);
+constexpr RegStorage rs_rA1(RegStorage::kValid | rA1);
+constexpr RegStorage rs_rA2(RegStorage::kValid | rA2);
+constexpr RegStorage rs_rA3(RegStorage::kValid | rA3);
+constexpr RegStorage rs_rT0(RegStorage::kValid | rT0);
+constexpr RegStorage rs_rT1(RegStorage::kValid | rT1);
+constexpr RegStorage rs_rT2(RegStorage::kValid | rT2);
+constexpr RegStorage rs_rT3(RegStorage::kValid | rT3);
+constexpr RegStorage rs_rT4(RegStorage::kValid | rT4);
+constexpr RegStorage rs_rT5(RegStorage::kValid | rT5);
+constexpr RegStorage rs_rT6(RegStorage::kValid | rT6);
+constexpr RegStorage rs_rT7(RegStorage::kValid | rT7);
+constexpr RegStorage rs_rS0(RegStorage::kValid | rS0);
+constexpr RegStorage rs_rS1(RegStorage::kValid | rS1);
+constexpr RegStorage rs_rS2(RegStorage::kValid | rS2);
+constexpr RegStorage rs_rS3(RegStorage::kValid | rS3);
+constexpr RegStorage rs_rS4(RegStorage::kValid | rS4);
+constexpr RegStorage rs_rS5(RegStorage::kValid | rS5);
+constexpr RegStorage rs_rS6(RegStorage::kValid | rS6);
+constexpr RegStorage rs_rS7(RegStorage::kValid | rS7);
+constexpr RegStorage rs_rT8(RegStorage::kValid | rT8);
+constexpr RegStorage rs_rT9(RegStorage::kValid | rT9);
+constexpr RegStorage rs_rK0(RegStorage::kValid | rK0);
+constexpr RegStorage rs_rK1(RegStorage::kValid | rK1);
+constexpr RegStorage rs_rGP(RegStorage::kValid | rGP);
+constexpr RegStorage rs_rSP(RegStorage::kValid | rSP);
+constexpr RegStorage rs_rFP(RegStorage::kValid | rFP);
+constexpr RegStorage rs_rRA(RegStorage::kValid | rRA);
+
+constexpr RegStorage rs_rMIPS_LR(RegStorage::kInvalid); // Not used for MIPS.
+constexpr RegStorage rs_rMIPS_PC(RegStorage::kInvalid); // Not used for MIPS.
+constexpr RegStorage rs_rMIPS_COUNT(RegStorage::kInvalid); // Not used for MIPS.
+
+constexpr RegStorage rs_rF0(RegStorage::kValid | rF0);
+constexpr RegStorage rs_rF1(RegStorage::kValid | rF1);
+constexpr RegStorage rs_rF2(RegStorage::kValid | rF2);
+constexpr RegStorage rs_rF3(RegStorage::kValid | rF3);
+constexpr RegStorage rs_rF4(RegStorage::kValid | rF4);
+constexpr RegStorage rs_rF5(RegStorage::kValid | rF5);
+constexpr RegStorage rs_rF6(RegStorage::kValid | rF6);
+constexpr RegStorage rs_rF7(RegStorage::kValid | rF7);
+constexpr RegStorage rs_rF8(RegStorage::kValid | rF8);
+constexpr RegStorage rs_rF9(RegStorage::kValid | rF9);
+constexpr RegStorage rs_rF10(RegStorage::kValid | rF10);
+constexpr RegStorage rs_rF11(RegStorage::kValid | rF11);
+constexpr RegStorage rs_rF12(RegStorage::kValid | rF12);
+constexpr RegStorage rs_rF13(RegStorage::kValid | rF13);
+constexpr RegStorage rs_rF14(RegStorage::kValid | rF14);
+constexpr RegStorage rs_rF15(RegStorage::kValid | rF15);
+
+constexpr RegStorage rs_rD0(RegStorage::kValid | rD0);
+constexpr RegStorage rs_rD1(RegStorage::kValid | rD1);
+constexpr RegStorage rs_rD2(RegStorage::kValid | rD2);
+constexpr RegStorage rs_rD3(RegStorage::kValid | rD3);
+constexpr RegStorage rs_rD4(RegStorage::kValid | rD4);
+constexpr RegStorage rs_rD5(RegStorage::kValid | rD5);
+constexpr RegStorage rs_rD6(RegStorage::kValid | rD6);
+constexpr RegStorage rs_rD7(RegStorage::kValid | rD7);
// TODO: reduce/eliminate use of these.
#define rMIPS_SUSPEND rS0
@@ -311,9 +315,9 @@ const RegStorage rs_rF1(RegStorage::k32BitSolo, rF1);
#define rMIPS_FARG2 rFARG2
#define rs_rMIPS_FARG2 rs_rFARG2
#define rMIPS_FARG3 rFARG3
-#define rs_MIPS_FARG3 rs_rFARG3
+#define rs_rMIPS_FARG3 rs_rFARG3
#define rMIPS_RET0 rRESULT0
-#define rs_MIPS_RET0 rs_rRESULT0
+#define rs_rMIPS_RET0 rs_rRESULT0
#define rMIPS_RET1 rRESULT1
#define rs_rMIPS_RET1 rs_rRESULT1
#define rMIPS_INVOKE_TGT rT9
@@ -322,16 +326,17 @@ const RegStorage rs_rF1(RegStorage::k32BitSolo, rF1);
// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
const RegLocation mips_loc_c_return
- {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
const RegLocation mips_loc_c_return_wide
- {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
RegStorage(RegStorage::k64BitPair, rV0, rV1), INVALID_SREG, INVALID_SREG};
const RegLocation mips_loc_c_return_float
- {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
+ {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
+// FIXME: move MIPS to k64Bitsolo for doubles
const RegLocation mips_loc_c_return_double
- {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
+ {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
enum MipsShiftEncodings {
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index 7f4cd5e242..8d91abac3a 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -26,18 +26,40 @@
namespace art {
-static int core_regs[] = {rZERO, rAT, rV0, rV1, rA0, rA1, rA2, rA3,
- rT0, rT1, rT2, rT3, rT4, rT5, rT6, rT7,
- rS0, rS1, rS2, rS3, rS4, rS5, rS6, rS7, rT8,
- rT9, rK0, rK1, rGP, rSP, rFP, rRA};
-static int ReservedRegs[] = {rZERO, rAT, rS0, rS1, rK0, rK1, rGP, rSP,
- rRA};
-static int core_temps[] = {rV0, rV1, rA0, rA1, rA2, rA3, rT0, rT1, rT2,
- rT3, rT4, rT5, rT6, rT7, rT8};
-static int FpRegs[] = {rF0, rF1, rF2, rF3, rF4, rF5, rF6, rF7,
- rF8, rF9, rF10, rF11, rF12, rF13, rF14, rF15};
-static int fp_temps[] = {rF0, rF1, rF2, rF3, rF4, rF5, rF6, rF7,
- rF8, rF9, rF10, rF11, rF12, rF13, rF14, rF15};
+static const RegStorage core_regs_arr[] =
+ {rs_rZERO, rs_rAT, rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2,
+ rs_rT3, rs_rT4, rs_rT5, rs_rT6, rs_rT7, rs_rS0, rs_rS1, rs_rS2, rs_rS3, rs_rS4, rs_rS5,
+ rs_rS6, rs_rS7, rs_rT8, rs_rT9, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rFP, rs_rRA};
+static RegStorage sp_regs_arr[] =
+ {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
+ rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
+static RegStorage dp_regs_arr[] =
+ {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
+static const RegStorage reserved_regs_arr[] =
+ {rs_rZERO, rs_rAT, rs_rS0, rs_rS1, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rRA};
+static RegStorage core_temps_arr[] =
+ {rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2, rs_rT3, rs_rT4,
+ rs_rT5, rs_rT6, rs_rT7, rs_rT8};
+static RegStorage sp_temps_arr[] =
+ {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
+ rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
+static RegStorage dp_temps_arr[] =
+ {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
+
+static const std::vector<RegStorage> core_regs(core_regs_arr,
+ core_regs_arr + sizeof(core_regs_arr) / sizeof(core_regs_arr[0]));
+static const std::vector<RegStorage> sp_regs(sp_regs_arr,
+ sp_regs_arr + sizeof(sp_regs_arr) / sizeof(sp_regs_arr[0]));
+static const std::vector<RegStorage> dp_regs(dp_regs_arr,
+ dp_regs_arr + sizeof(dp_regs_arr) / sizeof(dp_regs_arr[0]));
+static const std::vector<RegStorage> reserved_regs(reserved_regs_arr,
+ reserved_regs_arr + sizeof(reserved_regs_arr) / sizeof(reserved_regs_arr[0]));
+static const std::vector<RegStorage> core_temps(core_temps_arr,
+ core_temps_arr + sizeof(core_temps_arr) / sizeof(core_temps_arr[0]));
+static const std::vector<RegStorage> sp_temps(sp_temps_arr,
+ sp_temps_arr + sizeof(sp_temps_arr) / sizeof(sp_temps_arr[0]));
+static const std::vector<RegStorage> dp_temps(dp_temps_arr,
+ dp_temps_arr + sizeof(dp_temps_arr) / sizeof(dp_temps_arr[0]));
RegLocation MipsMir2Lir::LocCReturn() {
return mips_loc_c_return;
@@ -57,29 +79,29 @@ RegLocation MipsMir2Lir::LocCReturnDouble() {
// Return a target-dependent special register.
RegStorage MipsMir2Lir::TargetReg(SpecialTargetRegister reg) {
- int res_reg = RegStorage::kInvalidRegVal;
+ RegStorage res_reg;
switch (reg) {
- case kSelf: res_reg = rMIPS_SELF; break;
- case kSuspend: res_reg = rMIPS_SUSPEND; break;
- case kLr: res_reg = rMIPS_LR; break;
- case kPc: res_reg = rMIPS_PC; break;
- case kSp: res_reg = rMIPS_SP; break;
- case kArg0: res_reg = rMIPS_ARG0; break;
- case kArg1: res_reg = rMIPS_ARG1; break;
- case kArg2: res_reg = rMIPS_ARG2; break;
- case kArg3: res_reg = rMIPS_ARG3; break;
- case kFArg0: res_reg = rMIPS_FARG0; break;
- case kFArg1: res_reg = rMIPS_FARG1; break;
- case kFArg2: res_reg = rMIPS_FARG2; break;
- case kFArg3: res_reg = rMIPS_FARG3; break;
- case kRet0: res_reg = rMIPS_RET0; break;
- case kRet1: res_reg = rMIPS_RET1; break;
- case kInvokeTgt: res_reg = rMIPS_INVOKE_TGT; break;
- case kHiddenArg: res_reg = rT0; break;
- case kHiddenFpArg: res_reg = RegStorage::kInvalidRegVal; break;
- case kCount: res_reg = rMIPS_COUNT; break;
+ case kSelf: res_reg = rs_rMIPS_SELF; break;
+ case kSuspend: res_reg = rs_rMIPS_SUSPEND; break;
+ case kLr: res_reg = rs_rMIPS_LR; break;
+ case kPc: res_reg = rs_rMIPS_PC; break;
+ case kSp: res_reg = rs_rMIPS_SP; break;
+ case kArg0: res_reg = rs_rMIPS_ARG0; break;
+ case kArg1: res_reg = rs_rMIPS_ARG1; break;
+ case kArg2: res_reg = rs_rMIPS_ARG2; break;
+ case kArg3: res_reg = rs_rMIPS_ARG3; break;
+ case kFArg0: res_reg = rs_rMIPS_FARG0; break;
+ case kFArg1: res_reg = rs_rMIPS_FARG1; break;
+ case kFArg2: res_reg = rs_rMIPS_FARG2; break;
+ case kFArg3: res_reg = rs_rMIPS_FARG3; break;
+ case kRet0: res_reg = rs_rMIPS_RET0; break;
+ case kRet1: res_reg = rs_rMIPS_RET1; break;
+ case kInvokeTgt: res_reg = rs_rMIPS_INVOKE_TGT; break;
+ case kHiddenArg: res_reg = rs_rT0; break;
+ case kHiddenFpArg: res_reg = RegStorage::InvalidReg(); break;
+ case kCount: res_reg = rs_rMIPS_COUNT; break;
}
- return RegStorage::Solo32(res_reg);
+ return res_reg;
}
RegStorage MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) {
@@ -96,35 +118,22 @@ RegStorage MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) {
}
}
-// Create a double from a pair of singles.
-int MipsMir2Lir::S2d(int low_reg, int high_reg) {
- return MIPS_S2D(low_reg, high_reg);
-}
-
-// Return mask to strip off fp reg flags and bias.
-uint32_t MipsMir2Lir::FpRegMask() {
- return MIPS_FP_REG_MASK;
-}
-
-// True if both regs single, both core or both double.
-bool MipsMir2Lir::SameRegType(int reg1, int reg2) {
- return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2));
-}
-
/*
* Decode the register id.
*/
-uint64_t MipsMir2Lir::GetRegMaskCommon(int reg) {
+uint64_t MipsMir2Lir::GetRegMaskCommon(RegStorage reg) {
uint64_t seed;
int shift;
- int reg_id;
-
-
- reg_id = reg & 0x1f;
+ int reg_id = reg.GetRegNum();
/* Each double register is equal to a pair of single-precision FP registers */
- seed = MIPS_DOUBLEREG(reg) ? 3 : 1;
- /* FP register starts at bit position 16 */
- shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0;
+ if (reg.IsDouble()) {
+ seed = 0x3;
+ reg_id = reg_id << 1;
+ } else {
+ seed = 1;
+ }
+ /* FP register starts at bit position 32 */
+ shift = reg.IsFloat() ? kMipsFPReg0 : 0;
/* Expand the double register id into single offset */
shift += reg_id;
return (seed << shift);
@@ -209,11 +218,11 @@ std::string MipsMir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned cha
}
break;
case 's':
- snprintf(tbuf, arraysize(tbuf), "$f%d", operand & MIPS_FP_REG_MASK);
+ snprintf(tbuf, arraysize(tbuf), "$f%d", RegStorage::RegNum(operand));
break;
case 'S':
- DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0);
- snprintf(tbuf, arraysize(tbuf), "$f%d", operand & MIPS_FP_REG_MASK);
+ DCHECK_EQ(RegStorage::RegNum(operand) & 1, 0);
+ snprintf(tbuf, arraysize(tbuf), "$f%d", RegStorage::RegNum(operand));
break;
case 'h':
snprintf(tbuf, arraysize(tbuf), "%04x", operand);
@@ -327,7 +336,7 @@ void MipsMir2Lir::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *pre
*/
void MipsMir2Lir::AdjustSpillMask() {
- core_spill_mask_ |= (1 << rRA);
+ core_spill_mask_ |= (1 << rs_rRA.GetRegNum());
num_core_spills_++;
}
@@ -337,92 +346,63 @@ void MipsMir2Lir::AdjustSpillMask() {
* include any holes in the mask. Associate holes with
* Dalvik register INVALID_VREG (0xFFFFU).
*/
-void MipsMir2Lir::MarkPreservedSingle(int s_reg, int reg) {
+void MipsMir2Lir::MarkPreservedSingle(int s_reg, RegStorage reg) {
LOG(FATAL) << "No support yet for promoted FP regs";
}
-void MipsMir2Lir::FlushRegWide(RegStorage reg) {
- RegisterInfo* info1 = GetRegInfo(reg.GetLowReg());
- RegisterInfo* info2 = GetRegInfo(reg.GetHighReg());
- DCHECK(info1 && info2 && info1->pair && info2->pair &&
- (info1->partner == info2->reg) &&
- (info2->partner == info1->reg));
- if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
- if (!(info1->is_temp && info2->is_temp)) {
- /* Should not happen. If it does, there's a problem in eval_loc */
- LOG(FATAL) << "Long half-temp, half-promoted";
- }
-
- info1->dirty = false;
- info2->dirty = false;
- if (mir_graph_->SRegToVReg(info2->s_reg) < mir_graph_->SRegToVReg(info1->s_reg))
- info1 = info2;
- int v_reg = mir_graph_->SRegToVReg(info1->s_reg);
- StoreBaseDispWide(rs_rMIPS_SP, VRegOffset(v_reg),
- RegStorage(RegStorage::k64BitPair, info1->reg, info1->partner));
- }
-}
-
-void MipsMir2Lir::FlushReg(RegStorage reg) {
- DCHECK(!reg.IsPair());
- RegisterInfo* info = GetRegInfo(reg.GetReg());
- if (info->live && info->dirty) {
- info->dirty = false;
- int v_reg = mir_graph_->SRegToVReg(info->s_reg);
- Store32Disp(rs_rMIPS_SP, VRegOffset(v_reg), reg);
- }
-}
-
-/* Give access to the target-dependent FP register encoding to common code */
-bool MipsMir2Lir::IsFpReg(int reg) {
- return MIPS_FPREG(reg);
-}
-
-bool MipsMir2Lir::IsFpReg(RegStorage reg) {
- return IsFpReg(reg.IsPair() ? reg.GetLowReg() : reg.GetReg());
+void MipsMir2Lir::MarkPreservedDouble(int s_reg, RegStorage reg) {
+ LOG(FATAL) << "No support yet for promoted FP regs";
}
/* Clobber all regs that might be used by an external C call */
void MipsMir2Lir::ClobberCallerSave() {
- Clobber(rZERO);
- Clobber(rAT);
- Clobber(rV0);
- Clobber(rV1);
- Clobber(rA0);
- Clobber(rA1);
- Clobber(rA2);
- Clobber(rA3);
- Clobber(rT0);
- Clobber(rT1);
- Clobber(rT2);
- Clobber(rT3);
- Clobber(rT4);
- Clobber(rT5);
- Clobber(rT6);
- Clobber(rT7);
- Clobber(rT8);
- Clobber(rT9);
- Clobber(rK0);
- Clobber(rK1);
- Clobber(rGP);
- Clobber(rFP);
- Clobber(rRA);
- Clobber(rF0);
- Clobber(rF1);
- Clobber(rF2);
- Clobber(rF3);
- Clobber(rF4);
- Clobber(rF5);
- Clobber(rF6);
- Clobber(rF7);
- Clobber(rF8);
- Clobber(rF9);
- Clobber(rF10);
- Clobber(rF11);
- Clobber(rF12);
- Clobber(rF13);
- Clobber(rF14);
- Clobber(rF15);
+ Clobber(rs_rZERO);
+ Clobber(rs_rAT);
+ Clobber(rs_rV0);
+ Clobber(rs_rV1);
+ Clobber(rs_rA0);
+ Clobber(rs_rA1);
+ Clobber(rs_rA2);
+ Clobber(rs_rA3);
+ Clobber(rs_rT0);
+ Clobber(rs_rT1);
+ Clobber(rs_rT2);
+ Clobber(rs_rT3);
+ Clobber(rs_rT4);
+ Clobber(rs_rT5);
+ Clobber(rs_rT6);
+ Clobber(rs_rT7);
+ Clobber(rs_rT8);
+ Clobber(rs_rT9);
+ Clobber(rs_rK0);
+ Clobber(rs_rK1);
+ Clobber(rs_rGP);
+ Clobber(rs_rFP);
+ Clobber(rs_rRA);
+ Clobber(rs_rF0);
+ Clobber(rs_rF1);
+ Clobber(rs_rF2);
+ Clobber(rs_rF3);
+ Clobber(rs_rF4);
+ Clobber(rs_rF5);
+ Clobber(rs_rF6);
+ Clobber(rs_rF7);
+ Clobber(rs_rF8);
+ Clobber(rs_rF9);
+ Clobber(rs_rF10);
+ Clobber(rs_rF11);
+ Clobber(rs_rF12);
+ Clobber(rs_rF13);
+ Clobber(rs_rF14);
+ Clobber(rs_rF15);
+ Clobber(rs_rD0);
+ Clobber(rs_rD1);
+ Clobber(rs_rD2);
+ Clobber(rs_rD3);
+ Clobber(rs_rD4);
+ Clobber(rs_rD5);
+ Clobber(rs_rD6);
+ Clobber(rs_rD7);
}
RegLocation MipsMir2Lir::GetReturnWideAlt() {
@@ -439,18 +419,18 @@ RegLocation MipsMir2Lir::GetReturnAlt() {
/* To be used when explicitly managing register use */
void MipsMir2Lir::LockCallTemps() {
- LockTemp(rMIPS_ARG0);
- LockTemp(rMIPS_ARG1);
- LockTemp(rMIPS_ARG2);
- LockTemp(rMIPS_ARG3);
+ LockTemp(rs_rMIPS_ARG0);
+ LockTemp(rs_rMIPS_ARG1);
+ LockTemp(rs_rMIPS_ARG2);
+ LockTemp(rs_rMIPS_ARG3);
}
/* To be used when explicitly managing register use */
void MipsMir2Lir::FreeCallTemps() {
- FreeTemp(rMIPS_ARG0);
- FreeTemp(rMIPS_ARG1);
- FreeTemp(rMIPS_ARG2);
- FreeTemp(rMIPS_ARG3);
+ FreeTemp(rs_rMIPS_ARG0);
+ FreeTemp(rs_rMIPS_ARG1);
+ FreeTemp(rs_rMIPS_ARG2);
+ FreeTemp(rs_rMIPS_ARG3);
}
void MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) {
@@ -461,56 +441,52 @@ void MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) {
// Alloc a pair of core registers, or a double.
RegStorage MipsMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
- int high_reg;
- int low_reg;
-
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
return AllocTempDouble();
}
- low_reg = AllocTemp().GetReg();
- high_reg = AllocTemp().GetReg();
- return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
+ RegStorage low_reg = AllocTemp();
+ RegStorage high_reg = AllocTemp();
+ return RegStorage::MakeRegPair(low_reg, high_reg);
}
RegStorage MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempFloat();
-}
+ return AllocTempSingle();
+ }
return AllocTemp();
}
void MipsMir2Lir::CompilerInitializeRegAlloc() {
- int num_regs = sizeof(core_regs)/sizeof(*core_regs);
- int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs);
- int num_temps = sizeof(core_temps)/sizeof(*core_temps);
- int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs);
- int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps);
- reg_pool_ = static_cast<RegisterPool*>(arena_->Alloc(sizeof(*reg_pool_),
- kArenaAllocRegAlloc));
- reg_pool_->num_core_regs = num_regs;
- reg_pool_->core_regs = static_cast<RegisterInfo*>
- (arena_->Alloc(num_regs * sizeof(*reg_pool_->core_regs), kArenaAllocRegAlloc));
- reg_pool_->num_fp_regs = num_fp_regs;
- reg_pool_->FPRegs = static_cast<RegisterInfo*>
- (arena_->Alloc(num_fp_regs * sizeof(*reg_pool_->FPRegs), kArenaAllocRegAlloc));
- CompilerInitPool(reg_pool_->core_regs, core_regs, reg_pool_->num_core_regs);
- CompilerInitPool(reg_pool_->FPRegs, FpRegs, reg_pool_->num_fp_regs);
- // Keep special registers from being allocated
- for (int i = 0; i < num_reserved; i++) {
- if (NO_SUSPEND && (ReservedRegs[i] == rMIPS_SUSPEND)) {
- // To measure cost of suspend check
- continue;
+ reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, sp_regs, dp_regs, reserved_regs,
+ core_temps, sp_temps, dp_temps);
+
+ // Target-specific adjustments.
+
+ // Alias single precision floats to appropriate half of overlapping double.
+ GrowableArray<RegisterInfo*>::Iterator it(&reg_pool_->sp_regs_);
+ for (RegisterInfo* info = it.Next(); info != nullptr; info = it.Next()) {
+ int sp_reg_num = info->GetReg().GetRegNum();
+ int dp_reg_num = sp_reg_num >> 1;
+ RegStorage dp_reg = RegStorage::Solo64(RegStorage::kFloatingPoint | dp_reg_num);
+ RegisterInfo* dp_reg_info = GetRegInfo(dp_reg);
+ // Double precision register's master storage should refer to itself.
+ DCHECK_EQ(dp_reg_info, dp_reg_info->Master());
+ // Redirect single precision's master storage to master.
+ info->SetMaster(dp_reg_info);
+ // Singles should show a single 32-bit mask bit, at first referring to the low half.
+ DCHECK_EQ(info->StorageMask(), 0x1U);
+ if (sp_reg_num & 1) {
+ // For odd singles, change to user the high word of the backing double.
+ info->SetStorageMask(0x2);
}
- MarkInUse(ReservedRegs[i]);
- }
- // Mark temp regs - all others not in use can be used for promotion
- for (int i = 0; i < num_temps; i++) {
- MarkTemp(core_temps[i]);
- }
- for (int i = 0; i < num_fp_temps; i++) {
- MarkTemp(fp_temps[i]);
}
+
+ // Don't start allocating temps at r0/s0/d0 or you may clobber return regs in early-exit methods.
+ // TODO: adjust when we roll to hard float calling convention.
+ reg_pool_->next_core_reg_ = 2;
+ reg_pool_->next_sp_reg_ = 2;
+ reg_pool_->next_dp_reg_ = 1;
}
void MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free) {
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc
index a865430d6c..50b945a956 100644
--- a/compiler/dex/quick/mips/utility_mips.cc
+++ b/compiler/dex/quick/mips/utility_mips.cc
@@ -24,12 +24,12 @@ namespace art {
LIR* MipsMir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) {
int opcode;
/* must be both DOUBLE or both not DOUBLE */
- DCHECK_EQ(MIPS_DOUBLEREG(r_dest.GetReg()), MIPS_DOUBLEREG(r_src.GetReg()));
- if (MIPS_DOUBLEREG(r_dest.GetReg())) {
+ DCHECK_EQ(r_dest.IsDouble(), r_src.IsDouble());
+ if (r_dest.IsDouble()) {
opcode = kMipsFmovd;
} else {
- if (MIPS_SINGLEREG(r_dest.GetReg())) {
- if (MIPS_SINGLEREG(r_src.GetReg())) {
+ if (r_dest.IsSingle()) {
+ if (r_src.IsSingle()) {
opcode = kMipsFmovs;
} else {
/* note the operands are swapped for the mtc1 instr */
@@ -39,7 +39,7 @@ LIR* MipsMir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) {
opcode = kMipsMtc1;
}
} else {
- DCHECK(MIPS_SINGLEREG(r_src.GetReg()));
+ DCHECK(r_src.IsSingle());
opcode = kMipsMfc1;
}
}
@@ -79,9 +79,9 @@ LIR* MipsMir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) {
LIR *res;
RegStorage r_dest_save = r_dest;
- int is_fp_reg = MIPS_FPREG(r_dest.GetReg());
+ int is_fp_reg = r_dest.IsFloat();
if (is_fp_reg) {
- DCHECK(MIPS_SINGLEREG(r_dest.GetReg()));
+ DCHECK(r_dest.IsSingle());
r_dest = AllocTemp();
}
@@ -355,8 +355,8 @@ LIR* MipsMir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStor
MipsOpCode opcode = kMipsNop;
RegStorage t_reg = AllocTemp();
- if (MIPS_FPREG(r_dest.GetReg())) {
- DCHECK(MIPS_SINGLEREG(r_dest.GetReg()));
+ if (r_dest.IsFloat()) {
+ DCHECK(r_dest.IsSingle());
DCHECK((size == k32) || (size == kSingle) || (size == kReference));
size = kSingle;
} else {
@@ -407,8 +407,8 @@ LIR* MipsMir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegSto
MipsOpCode opcode = kMipsNop;
RegStorage t_reg = AllocTemp();
- if (MIPS_FPREG(r_src.GetReg())) {
- DCHECK(MIPS_SINGLEREG(r_src.GetReg()));
+ if (r_src.IsFloat()) {
+ DCHECK(r_src.IsSingle());
DCHECK((size == k32) || (size == kSingle) || (size == kReference));
size = kSingle;
} else {
@@ -469,16 +469,16 @@ LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStora
case kDouble:
pair = true;
opcode = kMipsLw;
- if (MIPS_FPREG(r_dest.GetReg())) {
+ if (r_dest.IsFloat()) {
opcode = kMipsFlwc1;
- if (MIPS_DOUBLEREG(r_dest.GetReg())) {
- // TODO: rework to use k64BitSolo
- r_dest.SetReg(r_dest.GetReg() - MIPS_FP_DOUBLE);
+ if (r_dest.IsDouble()) {
+ int reg_num = (r_dest.GetRegNum() << 1) | RegStorage::kFloatingPoint;
+ r_dest = RegStorage(RegStorage::k64BitSolo, reg_num, reg_num + 1);
} else {
- DCHECK(MIPS_FPREG(r_dest_hi.GetReg()));
+ DCHECK(r_dest_hi.IsFloat());
DCHECK_EQ(r_dest.GetReg(), r_dest_hi.GetReg() - 1);
+ r_dest_hi.SetReg(r_dest.GetReg() + 1);
}
- r_dest_hi.SetReg(r_dest.GetReg() + 1);
}
short_form = IS_SIMM16_2WORD(displacement);
DCHECK_EQ((displacement & 0x3), 0);
@@ -487,9 +487,9 @@ LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStora
case kSingle:
case kReference:
opcode = kMipsLw;
- if (MIPS_FPREG(r_dest.GetReg())) {
+ if (r_dest.IsFloat()) {
opcode = kMipsFlwc1;
- DCHECK(MIPS_SINGLEREG(r_dest.GetReg()));
+ DCHECK(r_dest.IsSingle());
}
DCHECK_EQ((displacement & 0x3), 0);
break;
@@ -567,22 +567,22 @@ LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement,
LIR *store2 = NULL;
MipsOpCode opcode = kMipsNop;
bool short_form = IS_SIMM16(displacement);
- bool pair = false;
+ bool pair = r_src.IsPair();
switch (size) {
case k64:
case kDouble:
- pair = true;
opcode = kMipsSw;
- if (MIPS_FPREG(r_src.GetReg())) {
+ if (r_src.IsFloat()) {
opcode = kMipsFswc1;
- if (MIPS_DOUBLEREG(r_src.GetReg())) {
- r_src.SetReg(r_src.GetReg() - MIPS_FP_DOUBLE);
+ if (r_src.IsDouble()) {
+ int reg_num = (r_src.GetRegNum() << 1) | RegStorage::kFloatingPoint;
+ r_src = RegStorage(RegStorage::k64BitPair, reg_num, reg_num + 1);
} else {
- DCHECK(MIPS_FPREG(r_src_hi.GetReg()));
+ DCHECK(r_src_hi.IsFloat());
DCHECK_EQ(r_src.GetReg(), (r_src_hi.GetReg() - 1));
+ r_src_hi.SetReg(r_src.GetReg() + 1);
}
- r_src_hi.SetReg(r_src.GetReg() + 1);
}
short_form = IS_SIMM16_2WORD(displacement);
DCHECK_EQ((displacement & 0x3), 0);
@@ -591,9 +591,9 @@ LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement,
case kSingle:
case kReference:
opcode = kMipsSw;
- if (MIPS_FPREG(r_src.GetReg())) {
+ if (r_src.IsFloat()) {
opcode = kMipsFswc1;
- DCHECK(MIPS_SINGLEREG(r_src.GetReg()));
+ DCHECK(r_src.IsSingle());
}
DCHECK_EQ((displacement & 0x3), 0);
break;
@@ -665,8 +665,7 @@ LIR* MipsMir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
}
LIR* MipsMir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_src, RegStorage r_src_hi,
- OpSize size, int s_reg) {
+ int displacement, RegStorage r_src, OpSize size, int s_reg) {
LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for MIPS";
return NULL;
}
@@ -677,8 +676,7 @@ LIR* MipsMir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int
}
LIR* MipsMir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_dest, RegStorage r_dest_hi,
- OpSize size, int s_reg) {
+ int displacement, RegStorage r_dest, OpSize size, int s_reg) {
LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for MIPS";
return NULL;
}