diff options
Diffstat (limited to 'compiler/dex/quick/mips')
-rw-r--r-- | compiler/dex/quick/mips/README.mips | 2 | ||||
-rw-r--r-- | compiler/dex/quick/mips/assemble_mips.cc | 9 | ||||
-rw-r--r-- | compiler/dex/quick/mips/call_mips.cc | 20 | ||||
-rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 16 | ||||
-rw-r--r-- | compiler/dex/quick/mips/fp_mips.cc | 12 | ||||
-rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 58 | ||||
-rw-r--r-- | compiler/dex/quick/mips/mips_lir.h | 293 | ||||
-rw-r--r-- | compiler/dex/quick/mips/target_mips.cc | 342 | ||||
-rw-r--r-- | compiler/dex/quick/mips/utility_mips.cc | 62 |
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(®_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; } |