Continuing register cleanup
Ready for review.
Continue the process of using RegStorage rather than
ints to hold register value in the top layers of codegen.
Given the huge number of changes in this CL, I've attempted
to minimize the number of actual logic changes. With this
CL, the use of ints for registers has largely been eliminated
except in the lowest utility levels. "Wide" utility routines
have been updated to take a single RegStorage rather than
a pair of ints representing low and high registers.
Upcoming CLs will be smaller and more targeted. My expectations:
o Allocate float double registers as a single double rather than
a pair of float single registers.
o Refactor to push code which assumes long and double Dalvik
values are held in a pair of register to the target dependent
layer.
o Clean-up of the xxx_mir.h files to reduce the amount of #defines
for registers. May also do a register renumbering to bring all
of our targets' register naming more consistent. Possibly
introduce a target-independent float/non-float test at the
RegStorage level.
Change-Id: I646de7392bdec94595dd2c6f76e0f1c4331096ff
diff --git a/compiler/dex/quick/mips/assemble_mips.cc b/compiler/dex/quick/mips/assemble_mips.cc
index bd3355f..ee142e5 100644
--- a/compiler/dex/quick/mips/assemble_mips.cc
+++ b/compiler/dex/quick/mips/assemble_mips.cc
@@ -432,12 +432,12 @@
* Long conditional branch
* -----------------------
* bne rs,rt,hop
- * bal .+8 ; r_RA <- anchor
- * lui r_AT, ((target-anchor) >> 16)
+ * bal .+8 ; rRA <- anchor
+ * lui rAT, ((target-anchor) >> 16)
* anchor:
- * ori r_AT, r_AT, ((target-anchor) & 0xffff)
- * addu r_AT, r_AT, r_RA
- * jr r_AT
+ * ori rAT, rAT, ((target-anchor) & 0xffff)
+ * addu rAT, rAT, rRA
+ * jr rAT
* hop:
*
* Orig unconditional branch
@@ -446,12 +446,12 @@
*
* Long unconditional branch
* -----------------------
- * bal .+8 ; r_RA <- anchor
- * lui r_AT, ((target-anchor) >> 16)
+ * bal .+8 ; rRA <- anchor
+ * lui rAT, ((target-anchor) >> 16)
* anchor:
- * ori r_AT, r_AT, ((target-anchor) & 0xffff)
- * addu r_AT, r_AT, r_RA
- * jr r_AT
+ * ori rAT, rAT, ((target-anchor) & 0xffff)
+ * addu rAT, rAT, rRA
+ * jr rAT
*
*
* NOTE: An out-of-range bal isn't supported because it should
@@ -489,16 +489,16 @@
LIR* curr_pc = RawLIR(dalvik_offset, kMipsCurrPC);
InsertLIRBefore(lir, curr_pc);
LIR* anchor = RawLIR(dalvik_offset, kPseudoTargetLabel);
- LIR* delta_hi = RawLIR(dalvik_offset, kMipsDeltaHi, r_AT, 0, WrapPointer(anchor), 0, 0,
+ LIR* delta_hi = RawLIR(dalvik_offset, kMipsDeltaHi, rAT, 0, WrapPointer(anchor), 0, 0,
lir->target);
InsertLIRBefore(lir, delta_hi);
InsertLIRBefore(lir, anchor);
- LIR* delta_lo = RawLIR(dalvik_offset, kMipsDeltaLo, r_AT, 0, WrapPointer(anchor), 0, 0,
+ LIR* delta_lo = RawLIR(dalvik_offset, kMipsDeltaLo, rAT, 0, WrapPointer(anchor), 0, 0,
lir->target);
InsertLIRBefore(lir, delta_lo);
- LIR* addu = RawLIR(dalvik_offset, kMipsAddu, r_AT, r_AT, r_RA);
+ LIR* addu = RawLIR(dalvik_offset, kMipsAddu, rAT, rAT, rRA);
InsertLIRBefore(lir, addu);
- LIR* jr = RawLIR(dalvik_offset, kMipsJr, r_AT);
+ LIR* jr = RawLIR(dalvik_offset, kMipsJr, rAT);
InsertLIRBefore(lir, jr);
if (!unconditional) {
InsertLIRBefore(lir, hop_target);
@@ -559,7 +559,7 @@
InsertLIRBefore(lir, new_delta_lo);
LIR *new_addu =
RawLIR(lir->dalvik_offset, kMipsAddu,
- lir->operands[0], lir->operands[0], r_RA);
+ lir->operands[0], lir->operands[0], rRA);
InsertLIRBefore(lir, new_addu);
NopLIR(lir);
res = kRetryAll;
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index 95fd6e7..972457a 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -32,8 +32,8 @@
/*
* The lack of pc-relative loads on Mips presents somewhat of a challenge
* for our PIC switch table strategy. To materialize the current location
- * we'll do a dummy JAL and reference our tables using r_RA as the
- * base register. Note that r_RA will be used both as the base to
+ * we'll do a dummy JAL and reference our tables using rRA as the
+ * base register. Note that rRA will be used both as the base to
* locate the switch table data and as the reference base for the switch
* target offsets stored in the table. We'll use a special pseudo-instruction
* to represent the jal and trigger the construction of the
@@ -42,21 +42,21 @@
*
* The test loop will look something like:
*
- * ori rEnd, r_ZERO, #table_size ; size in bytes
- * jal BaseLabel ; stores "return address" (BaseLabel) in r_RA
+ * ori r_end, rZERO, #table_size ; size in bytes
+ * jal BaseLabel ; stores "return address" (BaseLabel) in rRA
* nop ; opportunistically fill
* BaseLabel:
- * addiu rBase, r_RA, <table> - <BaseLabel> ; table relative to BaseLabel
- addu rEnd, rEnd, rBase ; end of table
+ * addiu r_base, rRA, <table> - <BaseLabel> ; table relative to BaseLabel
+ addu r_end, r_end, r_base ; end of table
* lw r_val, [rSP, v_reg_off] ; Test Value
* loop:
- * beq rBase, rEnd, done
- * lw r_key, 0(rBase)
- * addu rBase, 8
+ * beq r_base, r_end, done
+ * lw r_key, 0(r_base)
+ * addu r_base, 8
* bne r_val, r_key, loop
- * lw r_disp, -4(rBase)
- * addu r_RA, r_disp
- * jr r_RA
+ * lw r_disp, -4(r_base)
+ * addu rRA, r_disp
+ * jr rRA
* done:
*
*/
@@ -82,18 +82,18 @@
int size_hi = byte_size >> 16;
int size_lo = byte_size & 0xffff;
- int rEnd = AllocTemp();
+ RegStorage r_end = AllocTemp();
if (size_hi) {
- NewLIR2(kMipsLui, rEnd, size_hi);
+ NewLIR2(kMipsLui, r_end.GetReg(), size_hi);
}
// Must prevent code motion for the curr pc pair
GenBarrier(); // Scheduling barrier
NewLIR0(kMipsCurrPC); // Really a jal to .+8
// Now, fill the branch delay slot
if (size_hi) {
- NewLIR3(kMipsOri, rEnd, rEnd, size_lo);
+ NewLIR3(kMipsOri, r_end.GetReg(), r_end.GetReg(), size_lo);
} else {
- NewLIR3(kMipsOri, rEnd, r_ZERO, size_lo);
+ NewLIR3(kMipsOri, r_end.GetReg(), rZERO, size_lo);
}
GenBarrier(); // Scheduling barrier
@@ -101,24 +101,24 @@
LIR* base_label = NewLIR0(kPseudoTargetLabel);
// Remember base label so offsets can be computed later
tab_rec->anchor = base_label;
- int rBase = AllocTemp();
- NewLIR4(kMipsDelta, rBase, 0, WrapPointer(base_label), WrapPointer(tab_rec));
- OpRegRegReg(kOpAdd, rEnd, rEnd, rBase);
+ RegStorage r_base = AllocTemp();
+ NewLIR4(kMipsDelta, r_base.GetReg(), 0, WrapPointer(base_label), WrapPointer(tab_rec));
+ OpRegRegReg(kOpAdd, r_end, r_end, r_base);
// Grab switch test value
rl_src = LoadValue(rl_src, kCoreReg);
// Test loop
- int r_key = AllocTemp();
+ RegStorage r_key = AllocTemp();
LIR* loop_label = NewLIR0(kPseudoTargetLabel);
- LIR* exit_branch = OpCmpBranch(kCondEq, rBase, rEnd, NULL);
- LoadWordDisp(rBase, 0, r_key);
- OpRegImm(kOpAdd, rBase, 8);
- OpCmpBranch(kCondNe, rl_src.reg.GetReg(), r_key, loop_label);
- int r_disp = AllocTemp();
- LoadWordDisp(rBase, -4, r_disp);
- OpRegRegReg(kOpAdd, r_RA, r_RA, r_disp);
- OpReg(kOpBx, r_RA);
+ LIR* exit_branch = OpCmpBranch(kCondEq, r_base, r_end, NULL);
+ LoadWordDisp(r_base, 0, r_key);
+ OpRegImm(kOpAdd, r_base, 8);
+ OpCmpBranch(kCondNe, rl_src.reg, r_key, loop_label);
+ RegStorage r_disp = AllocTemp();
+ LoadWordDisp(r_base, -4, r_disp);
+ OpRegRegReg(kOpAdd, rs_rRA, rs_rRA, r_disp);
+ OpReg(kOpBx, rs_rRA);
// Loop exit
LIR* exit_label = NewLIR0(kPseudoTargetLabel);
@@ -129,13 +129,13 @@
* Code pattern will look something like:
*
* lw r_val
- * jal BaseLabel ; stores "return address" (BaseLabel) in r_RA
+ * jal BaseLabel ; stores "return address" (BaseLabel) in rRA
* nop ; opportunistically fill
* [subiu r_val, bias] ; Remove bias if low_val != 0
* bound check -> done
- * lw r_disp, [r_RA, r_val]
- * addu r_RA, r_disp
- * jr r_RA
+ * lw r_disp, [rRA, r_val]
+ * addu rRA, r_disp
+ * jr rRA
* done:
*/
void MipsMir2Lir::GenPackedSwitch(MIR* mir, DexOffset table_offset,
@@ -160,9 +160,9 @@
// Prepare the bias. If too big, handle 1st stage here
int low_key = s4FromSwitchData(&table[2]);
bool large_bias = false;
- int r_key;
+ RegStorage r_key;
if (low_key == 0) {
- r_key = rl_src.reg.GetReg();
+ r_key = rl_src.reg;
} else if ((low_key & 0xffff) != low_key) {
r_key = AllocTemp();
LoadConstant(r_key, low_key);
@@ -179,9 +179,9 @@
NewLIR0(kMipsNop);
} else {
if (large_bias) {
- OpRegRegReg(kOpSub, r_key, rl_src.reg.GetReg(), r_key);
+ OpRegRegReg(kOpSub, r_key, rl_src.reg, r_key);
} else {
- OpRegRegImm(kOpSub, r_key, rl_src.reg.GetReg(), low_key);
+ OpRegRegImm(kOpSub, r_key, rl_src.reg, low_key);
}
}
GenBarrier(); // Scheduling barrier
@@ -195,16 +195,16 @@
LIR* branch_over = OpCmpImmBranch(kCondHi, r_key, size-1, NULL);
// Materialize the table base pointer
- int rBase = AllocTemp();
- NewLIR4(kMipsDelta, rBase, 0, WrapPointer(base_label), WrapPointer(tab_rec));
+ RegStorage r_base = AllocTemp();
+ NewLIR4(kMipsDelta, r_base.GetReg(), 0, WrapPointer(base_label), WrapPointer(tab_rec));
// Load the displacement from the switch table
- int r_disp = AllocTemp();
- LoadBaseIndexed(rBase, r_key, r_disp, 2, kWord);
+ RegStorage r_disp = AllocTemp();
+ LoadBaseIndexed(r_base, r_key, r_disp, 2, kWord);
- // Add to r_AP and go
- OpRegRegReg(kOpAdd, r_RA, r_RA, r_disp);
- OpReg(kOpBx, r_RA);
+ // Add to rAP and go
+ OpRegRegReg(kOpAdd, rs_rRA, rs_rRA, r_disp);
+ OpReg(kOpBx, rs_rRA);
/* branch_over target here */
LIR* target = NewLIR0(kPseudoTargetLabel);
@@ -238,13 +238,13 @@
// Making a call - use explicit registers
FlushAllRegs(); /* Everything to home location */
LockCallTemps();
- LoadValueDirectFixed(rl_src, rMIPS_ARG0);
+ LoadValueDirectFixed(rl_src, rs_rMIPS_ARG0);
// Must prevent code motion for the curr pc pair
GenBarrier();
NewLIR0(kMipsCurrPC); // Really a jal to .+8
// Now, fill the branch delay slot with the helper load
- int r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(pHandleFillArrayData));
+ RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(pHandleFillArrayData));
GenBarrier(); // Scheduling barrier
// Construct BaseLabel and set up table base register
@@ -262,10 +262,10 @@
void MipsMir2Lir::GenMoveException(RegLocation rl_dest) {
int ex_offset = Thread::ExceptionOffset().Int32Value();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- int reset_reg = AllocTemp();
- LoadWordDisp(rMIPS_SELF, ex_offset, rl_result.reg.GetReg());
+ RegStorage reset_reg = AllocTemp();
+ LoadWordDisp(rs_rMIPS_SELF, ex_offset, rl_result.reg);
LoadConstant(reset_reg, 0);
- StoreWordDisp(rMIPS_SELF, ex_offset, reset_reg);
+ StoreWordDisp(rs_rMIPS_SELF, ex_offset, reset_reg);
FreeTemp(reset_reg);
StoreValue(rl_dest, rl_result);
}
@@ -273,14 +273,13 @@
/*
* Mark garbage collection card. Skip if the value we're storing is null.
*/
-void MipsMir2Lir::MarkGCCard(int val_reg, int tgt_addr_reg) {
- int reg_card_base = AllocTemp();
- int reg_card_no = AllocTemp();
+void MipsMir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) {
+ RegStorage reg_card_base = AllocTemp();
+ RegStorage reg_card_no = AllocTemp();
LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL);
- LoadWordDisp(rMIPS_SELF, Thread::CardTableOffset().Int32Value(), reg_card_base);
+ LoadWordDisp(rs_rMIPS_SELF, Thread::CardTableOffset().Int32Value(), reg_card_base);
OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift);
- StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0,
- kUnsignedByte);
+ StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0, kUnsignedByte);
LIR* target = NewLIR0(kPseudoTargetLabel);
branch_over->target = target;
FreeTemp(reg_card_base);
@@ -307,11 +306,11 @@
bool skip_overflow_check = (mir_graph_->MethodIsLeaf() &&
(static_cast<size_t>(frame_size_) < Thread::kStackOverflowReservedBytes));
NewLIR0(kPseudoMethodEntry);
- int check_reg = AllocTemp();
- int new_sp = AllocTemp();
+ RegStorage check_reg = AllocTemp();
+ RegStorage new_sp = AllocTemp();
if (!skip_overflow_check) {
/* Load stack limit */
- LoadWordDisp(rMIPS_SELF, Thread::StackEndOffset().Int32Value(), check_reg);
+ LoadWordDisp(rs_rMIPS_SELF, Thread::StackEndOffset().Int32Value(), check_reg);
}
/* Spill core callee saves */
SpillCoreRegs();
@@ -329,24 +328,24 @@
m2l_->ResetDefTracking();
GenerateTargetLabel();
// LR is offset 0 since we push in reverse order.
- m2l_->LoadWordDisp(kMipsRegSP, 0, kMipsRegLR);
- m2l_->OpRegImm(kOpAdd, kMipsRegSP, sp_displace_);
+ m2l_->LoadWordDisp(rs_rMIPS_SP, 0, rs_rRA);
+ m2l_->OpRegImm(kOpAdd, rs_rMIPS_SP, sp_displace_);
m2l_->ClobberCallerSave();
ThreadOffset func_offset = QUICK_ENTRYPOINT_OFFSET(pThrowStackOverflow);
- int r_tgt = m2l_->CallHelperSetup(func_offset); // Doesn't clobber LR.
+ RegStorage r_tgt = m2l_->CallHelperSetup(func_offset); // Doesn't clobber LR.
m2l_->CallHelper(r_tgt, func_offset, false /* MarkSafepointPC */, false /* UseLink */);
}
private:
const size_t sp_displace_;
};
- OpRegRegImm(kOpSub, new_sp, rMIPS_SP, frame_sub);
+ OpRegRegImm(kOpSub, new_sp, rs_rMIPS_SP, frame_sub);
LIR* branch = OpCmpBranch(kCondUlt, new_sp, check_reg, nullptr);
AddSlowPath(new(arena_)StackOverflowSlowPath(this, branch, spill_count * 4));
// TODO: avoid copy for small frame sizes.
- OpRegCopy(rMIPS_SP, new_sp); // Establish stack
+ OpRegCopy(rs_rMIPS_SP, new_sp); // Establish stack
} else {
- OpRegImm(kOpSub, rMIPS_SP, frame_sub);
+ OpRegImm(kOpSub, rs_rMIPS_SP, frame_sub);
}
FlushIns(ArgLocs, rl_method);
@@ -367,11 +366,11 @@
NewLIR0(kPseudoMethodExit);
UnSpillCoreRegs();
- OpReg(kOpBx, r_RA);
+ OpReg(kOpBx, rs_rRA);
}
void MipsMir2Lir::GenSpecialExitSequence() {
- OpReg(kOpBx, r_RA);
+ OpReg(kOpBx, rs_rRA);
}
} // namespace art
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index 28ebe0e..bc1ad02 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -28,32 +28,36 @@
// Required for target - codegen utilities.
bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src,
- RegLocation rl_dest, int lit);
- int LoadHelper(ThreadOffset offset);
+ RegLocation rl_dest, int lit);
LIR* CheckSuspendUsingLoad() OVERRIDE;
- LIR* LoadBaseDisp(int rBase, int displacement, int r_dest, OpSize size, int s_reg);
- LIR* LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, int r_dest_hi,
- int s_reg);
- LIR* LoadBaseIndexed(int rBase, int r_index, int r_dest, int scale, OpSize size);
- LIR* LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement,
- int r_dest, int r_dest_hi, OpSize size, int s_reg);
- LIR* LoadConstantNoClobber(int r_dest, int value);
- LIR* LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value);
- LIR* StoreBaseDisp(int rBase, int displacement, int r_src, OpSize size);
- LIR* StoreBaseDispWide(int rBase, int displacement, int r_src_lo, int r_src_hi);
- LIR* StoreBaseIndexed(int rBase, int r_index, int r_src, int scale, OpSize size);
- LIR* StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement,
- int r_src, int r_src_hi, OpSize size, int s_reg);
- void MarkGCCard(int val_reg, int tgt_addr_reg);
+ RegStorage LoadHelper(ThreadOffset offset);
+ LIR* LoadBaseDisp(int r_base, int displacement, int r_dest, OpSize size, int s_reg);
+ LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size,
+ int s_reg);
+ LIR* LoadBaseDispWide(RegStorage r_base, int displacement, RegStorage r_dest, int s_reg);
+ 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);
+ 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);
+ LIR* StoreBaseDispWide(RegStorage r_base, int displacement, RegStorage r_src);
+ 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);
+ 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);
- int AllocTypedTemp(bool fp_hint, int reg_class);
+ RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
int S2d(int low_reg, int high_reg);
- int TargetReg(SpecialTargetRegister reg);
- int GetArgMappingToPhysicalReg(int arg_num);
+ RegStorage TargetReg(SpecialTargetRegister reg);
+ RegStorage GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
RegLocation GetReturnWideAlt();
RegLocation LocCReturn();
@@ -64,8 +68,8 @@
uint64_t GetRegMaskCommon(int reg);
void AdjustSpillMask();
void ClobberCallerSave();
- void FlushReg(int reg);
- void FlushRegWide(int reg1, int reg2);
+ void FlushReg(RegStorage reg);
+ void FlushRegWide(RegStorage reg);
void FreeCallTemps();
void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free);
void LockCallTemps();
@@ -89,22 +93,25 @@
// Required for target - Dalvik-level generators.
void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
+ RegLocation rl_src1, RegLocation rl_src2);
void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_dest, int scale);
void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark);
- void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_shift);
- void GenMulLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenAddLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenAndLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
- void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2);
- void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_shift);
+ void GenMulLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ void GenAddLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ void GenAndLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_src2);
+ void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ void GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src);
bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object);
bool GenInlinedMinMaxInt(CallInfo* info, bool is_min);
@@ -112,15 +119,18 @@
bool GenInlinedPeek(CallInfo* info, OpSize size);
bool GenInlinedPoke(CallInfo* info, OpSize size);
void GenNegLong(RegLocation rl_dest, RegLocation rl_src);
- void GenOrLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenSubLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenXorLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- LIR* GenRegMemCheck(ConditionCode c_code, int reg1, int base, int offset,
- ThrowKind kind);
- RegLocation GenDivRem(RegLocation rl_dest, int reg_lo, int reg_hi, bool is_div);
- RegLocation GenDivRemLit(RegLocation rl_dest, int reg_lo, int lit, bool is_div);
+ void GenOrLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ void GenSubLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ void GenXorLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ LIR* GenRegMemCheck(ConditionCode c_code, RegStorage reg1, RegStorage base, int offset,
+ ThrowKind kind);
+ RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div);
+ RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div);
void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenDivZeroCheck(int reg_lo, int reg_hi);
+ void GenDivZeroCheck(RegStorage reg);
void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method);
void GenExitSequence();
void GenSpecialExitSequence();
@@ -131,7 +141,7 @@
void GenMemBarrier(MemBarrierKind barrier_kind);
void GenMoveException(RegLocation rl_dest);
void GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit,
- int first_bit, int second_bit);
+ int first_bit, int second_bit);
void GenNegDouble(RegLocation rl_dest, RegLocation rl_src);
void GenNegFloat(RegLocation rl_dest, RegLocation rl_src);
void GenPackedSwitch(MIR* mir, uint32_t table_offset, RegLocation rl_src);
@@ -140,36 +150,39 @@
// Required for target - single operation generators.
LIR* OpUnconditionalBranch(LIR* target);
- LIR* OpCmpBranch(ConditionCode cond, int src1, int src2, LIR* target);
- LIR* OpCmpImmBranch(ConditionCode cond, int reg, int check_value, LIR* target);
+ LIR* OpCmpBranch(ConditionCode cond, RegStorage src1, RegStorage src2, LIR* target);
+ LIR* OpCmpImmBranch(ConditionCode cond, RegStorage reg, int check_value, LIR* target);
LIR* OpCondBranch(ConditionCode cc, LIR* target);
- LIR* OpDecAndBranch(ConditionCode c_code, int reg, LIR* target);
- LIR* OpFpRegCopy(int r_dest, int r_src);
+ LIR* OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target);
+ LIR* OpFpRegCopy(RegStorage r_dest, RegStorage r_src);
LIR* OpIT(ConditionCode cond, const char* guide);
- LIR* OpMem(OpKind op, int rBase, int disp);
- LIR* OpPcRelLoad(int reg, LIR* target);
- LIR* OpReg(OpKind op, int r_dest_src);
- LIR* OpRegCopy(int r_dest, int r_src);
- LIR* OpRegCopyNoInsert(int r_dest, int r_src);
- LIR* OpRegImm(OpKind op, int r_dest_src1, int value);
- LIR* OpRegMem(OpKind op, int r_dest, int rBase, int offset);
- LIR* OpRegReg(OpKind op, int r_dest_src1, int r_src2);
- LIR* OpMovRegMem(int r_dest, int r_base, int offset, MoveType move_type);
- LIR* OpMovMemReg(int r_base, int offset, int r_src, MoveType move_type);
- LIR* OpCondRegReg(OpKind op, ConditionCode cc, int r_dest, int r_src);
- LIR* OpRegRegImm(OpKind op, int r_dest, int r_src1, int value);
- LIR* OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2);
+ LIR* OpMem(OpKind op, RegStorage r_base, int disp);
+ LIR* OpPcRelLoad(RegStorage reg, LIR* target);
+ LIR* OpReg(OpKind op, RegStorage r_dest_src);
+ LIR* OpRegCopy(RegStorage r_dest, RegStorage r_src);
+ LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src);
+ LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value);
+ LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset);
+ LIR* OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2);
+ LIR* OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type);
+ LIR* OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type);
+ LIR* OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src);
+ LIR* OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value);
+ LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2);
LIR* OpTestSuspend(LIR* target);
LIR* OpThreadMem(OpKind op, ThreadOffset thread_offset);
- LIR* OpVldm(int rBase, int count);
- LIR* OpVstm(int rBase, int count);
- void OpLea(int rBase, int reg1, int reg2, int scale, int offset);
- void OpRegCopyWide(int dest_lo, int dest_hi, int src_lo, int src_hi);
+ LIR* OpVldm(RegStorage r_base, int count);
+ LIR* OpVstm(RegStorage r_base, int count);
+ void OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset);
+ void OpRegCopyWide(RegStorage dest, RegStorage src);
void OpTlsCmp(ThreadOffset offset, int val);
- LIR* LoadBaseDispBody(int rBase, int displacement, int r_dest, int r_dest_hi, OpSize size,
- int s_reg);
- LIR* StoreBaseDispBody(int rBase, int displacement, int r_src, int r_src_hi, OpSize size);
+ // TODO: collapse r_dest.
+ LIR* LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest,
+ RegStorage r_dest_hi, OpSize size, int s_reg);
+ // TODO: collapse r_src.
+ LIR* StoreBaseDispBody(RegStorage r_base, int displacement, RegStorage r_src,
+ RegStorage r_src_hi, OpSize size);
void SpillCoreRegs();
void UnSpillCoreRegs();
static const MipsEncodingMap EncodingMap[kMipsLast];
diff --git a/compiler/dex/quick/mips/fp_mips.cc b/compiler/dex/quick/mips/fp_mips.cc
index cf4f19f..2bc5540 100644
--- a/compiler/dex/quick/mips/fp_mips.cc
+++ b/compiler/dex/quick/mips/fp_mips.cc
@@ -111,8 +111,8 @@
rl_result = EvalLoc(rl_dest, kFPReg, true);
DCHECK(rl_dest.wide);
DCHECK(rl_result.wide);
- NewLIR3(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), S2d(rl_src1.reg.GetReg(), rl_src1.reg.GetHighReg()),
- S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg()));
+ 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()));
StoreValueWide(rl_dest, rl_result);
}
@@ -157,14 +157,14 @@
}
if (rl_src.wide) {
rl_src = LoadValueWide(rl_src, kFPReg);
- src_reg = S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
+ src_reg = S2d(rl_src.reg.GetLowReg(), rl_src.reg.GetHighReg());
} else {
rl_src = LoadValue(rl_src, kFPReg);
src_reg = rl_src.reg.GetReg();
}
if (rl_dest.wide) {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), src_reg);
+ 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);
@@ -199,13 +199,15 @@
FlushAllRegs();
LockCallTemps();
if (wide) {
- LoadValueDirectWideFixed(rl_src1, rMIPS_FARG0, rMIPS_FARG1);
- LoadValueDirectWideFixed(rl_src2, rMIPS_FARG2, rMIPS_FARG3);
+ RegStorage r_tmp1(RegStorage::k64BitPair, rMIPS_FARG0, rMIPS_FARG1);
+ RegStorage r_tmp2(RegStorage::k64BitPair, rMIPS_FARG2, rMIPS_FARG3);
+ LoadValueDirectWideFixed(rl_src1, r_tmp1);
+ LoadValueDirectWideFixed(rl_src2, r_tmp2);
} else {
- LoadValueDirectFixed(rl_src1, rMIPS_FARG0);
- LoadValueDirectFixed(rl_src2, rMIPS_FARG2);
+ LoadValueDirectFixed(rl_src1, rs_rMIPS_FARG0);
+ LoadValueDirectFixed(rl_src2, rs_rMIPS_FARG2);
}
- int r_tgt = LoadHelper(offset);
+ RegStorage r_tgt = LoadHelper(offset);
// NOTE: not a safepoint
OpReg(kOpBlx, r_tgt);
RegLocation rl_result = GetReturn(false);
@@ -221,7 +223,7 @@
RegLocation rl_result;
rl_src = LoadValue(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0x80000000);
+ OpRegRegImm(kOpAdd, rl_result.reg, rl_src.reg, 0x80000000);
StoreValue(rl_dest, rl_result);
}
@@ -229,8 +231,8 @@
RegLocation rl_result;
rl_src = LoadValueWide(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpAdd, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), 0x80000000);
- OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
+ OpRegRegImm(kOpAdd, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), 0x80000000);
+ OpRegCopy(rl_result.reg, rl_src.reg);
StoreValueWide(rl_dest, rl_result);
}
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 9fcc8bb..dfe8b35 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -44,15 +44,15 @@
RegLocation rl_src2) {
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
- int t0 = AllocTemp();
- int t1 = AllocTemp();
+ int t0 = AllocTemp().GetReg();
+ int t1 = AllocTemp().GetReg();
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);
- LIR* branch = OpCmpImmBranch(kCondNe, rl_result.reg.GetReg(), 0, NULL);
- NewLIR3(kMipsSltu, t0, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
- NewLIR3(kMipsSltu, t1, rl_src2.reg.GetReg(), rl_src1.reg.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);
FreeTemp(t0);
FreeTemp(t1);
@@ -61,8 +61,7 @@
StoreValue(rl_dest, rl_result);
}
-LIR* MipsMir2Lir::OpCmpBranch(ConditionCode cond, int src1, int src2,
- LIR* target) {
+LIR* MipsMir2Lir::OpCmpBranch(ConditionCode cond, RegStorage src1, RegStorage src2, LIR* target) {
LIR* branch;
MipsOpCode slt_op;
MipsOpCode br_op;
@@ -113,13 +112,13 @@
return NULL;
}
if (cmp_zero) {
- branch = NewLIR2(br_op, src1, src2);
+ branch = NewLIR2(br_op, src1.GetReg(), src2.GetReg());
} else {
- int t_reg = AllocTemp();
+ int t_reg = AllocTemp().GetReg();
if (swapped) {
- NewLIR3(slt_op, t_reg, src2, src1);
+ NewLIR3(slt_op, t_reg, src2.GetReg(), src1.GetReg());
} else {
- NewLIR3(slt_op, t_reg, src1, src2);
+ NewLIR3(slt_op, t_reg, src1.GetReg(), src2.GetReg());
}
branch = NewLIR1(br_op, t_reg);
FreeTemp(t_reg);
@@ -128,12 +127,11 @@
return branch;
}
-LIR* MipsMir2Lir::OpCmpImmBranch(ConditionCode cond, int reg,
- int check_value, LIR* target) {
+LIR* MipsMir2Lir::OpCmpImmBranch(ConditionCode cond, RegStorage reg, int check_value, LIR* target) {
LIR* branch;
if (check_value != 0) {
// TUNING: handle s16 & kCondLt/Mi case using slti
- int t_reg = AllocTemp();
+ RegStorage t_reg = AllocTemp();
LoadConstant(t_reg, check_value);
branch = OpCmpBranch(cond, reg, t_reg, target);
FreeTemp(t_reg);
@@ -150,60 +148,66 @@
case kCondNe: opc = kMipsBnez; break;
default:
// Tuning: use slti when applicable
- int t_reg = AllocTemp();
+ RegStorage t_reg = AllocTemp();
LoadConstant(t_reg, check_value);
branch = OpCmpBranch(cond, reg, t_reg, target);
FreeTemp(t_reg);
return branch;
}
- branch = NewLIR1(opc, reg);
+ branch = NewLIR1(opc, reg.GetReg());
branch->target = target;
return branch;
}
-LIR* MipsMir2Lir::OpRegCopyNoInsert(int r_dest, int r_src) {
- if (MIPS_FPREG(r_dest) || MIPS_FPREG(r_src))
+LIR* MipsMir2Lir::OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) {
+ // If src or dest is a pair, we'll be using low reg.
+ if (r_dest.IsPair()) {
+ r_dest = r_dest.GetLow();
+ }
+ if (r_src.IsPair()) {
+ r_src = r_src.GetLow();
+ }
+ if (MIPS_FPREG(r_dest.GetReg()) || MIPS_FPREG(r_src.GetReg()))
return OpFpRegCopy(r_dest, r_src);
LIR* res = RawLIR(current_dalvik_offset_, kMipsMove,
- r_dest, r_src);
+ r_dest.GetReg(), r_src.GetReg());
if (!(cu_->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) {
res->flags.is_nop = true;
}
return res;
}
-LIR* MipsMir2Lir::OpRegCopy(int r_dest, int r_src) {
+LIR* MipsMir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) {
LIR *res = OpRegCopyNoInsert(r_dest, r_src);
AppendLIR(res);
return res;
}
-void MipsMir2Lir::OpRegCopyWide(int dest_lo, int dest_hi, int src_lo,
- int src_hi) {
- bool dest_fp = MIPS_FPREG(dest_lo) && MIPS_FPREG(dest_hi);
- bool src_fp = MIPS_FPREG(src_lo) && MIPS_FPREG(src_hi);
- assert(MIPS_FPREG(src_lo) == MIPS_FPREG(src_hi));
- assert(MIPS_FPREG(dest_lo) == MIPS_FPREG(dest_hi));
+void MipsMir2Lir::OpRegCopyWide(RegStorage r_dest, RegStorage r_src) {
+ bool dest_fp = MIPS_FPREG(r_dest.GetLowReg());
+ bool src_fp = MIPS_FPREG(r_src.GetLowReg());
if (dest_fp) {
if (src_fp) {
- OpRegCopy(S2d(dest_lo, dest_hi), S2d(src_lo, src_hi));
+ // 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, src_lo, dest_lo);
- NewLIR2(kMipsMtc1, src_hi, dest_hi);
+ NewLIR2(kMipsMtc1, r_src.GetLowReg(), r_dest.GetLowReg());
+ NewLIR2(kMipsMtc1, r_src.GetHighReg(), r_dest.GetHighReg());
}
} else {
if (src_fp) {
- NewLIR2(kMipsMfc1, dest_lo, src_lo);
- NewLIR2(kMipsMfc1, dest_hi, src_hi);
+ NewLIR2(kMipsMfc1, r_dest.GetLowReg(), r_src.GetLowReg());
+ NewLIR2(kMipsMfc1, r_dest.GetHighReg(), r_src.GetHighReg());
} else {
// Handle overlap
- if (src_hi == dest_lo) {
- OpRegCopy(dest_hi, src_hi);
- OpRegCopy(dest_lo, src_lo);
+ if (r_src.GetHighReg() == r_dest.GetLowReg()) {
+ OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
+ OpRegCopy(r_dest.GetLow(), r_src.GetLow());
} else {
- OpRegCopy(dest_lo, src_lo);
- OpRegCopy(dest_hi, src_hi);
+ OpRegCopy(r_dest.GetLow(), r_src.GetLow());
+ OpRegCopy(r_dest.GetHigh(), r_src.GetHigh());
}
}
}
@@ -217,34 +221,34 @@
UNIMPLEMENTED(FATAL) << "Need codegen for fused long cmp branch";
}
-LIR* MipsMir2Lir::GenRegMemCheck(ConditionCode c_code,
- int reg1, int base, int offset, ThrowKind kind) {
+LIR* MipsMir2Lir::GenRegMemCheck(ConditionCode c_code, RegStorage reg1, RegStorage base,
+ int offset, ThrowKind kind) {
LOG(FATAL) << "Unexpected use of GenRegMemCheck for Arm";
return NULL;
}
-RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, int reg1, int reg2,
+RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, RegStorage reg1, RegStorage reg2,
bool is_div) {
- NewLIR4(kMipsDiv, r_HI, r_LO, reg1, reg2);
+ NewLIR4(kMipsDiv, rHI, rLO, reg1.GetReg(), reg2.GetReg());
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_div) {
- NewLIR2(kMipsMflo, rl_result.reg.GetReg(), r_LO);
+ NewLIR2(kMipsMflo, rl_result.reg.GetReg(), rLO);
} else {
- NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), r_HI);
+ NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), rHI);
}
return rl_result;
}
-RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, int reg1, int lit,
+RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, RegStorage reg1, int lit,
bool is_div) {
- int t_reg = AllocTemp();
- NewLIR3(kMipsAddiu, t_reg, r_ZERO, lit);
- NewLIR4(kMipsDiv, r_HI, r_LO, reg1, t_reg);
+ int t_reg = AllocTemp().GetReg();
+ NewLIR3(kMipsAddiu, t_reg, rZERO, lit);
+ NewLIR4(kMipsDiv, rHI, rLO, reg1.GetReg(), t_reg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_div) {
- NewLIR2(kMipsMflo, rl_result.reg.GetReg(), r_LO);
+ NewLIR2(kMipsMflo, rl_result.reg.GetReg(), rLO);
} else {
- NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), r_HI);
+ NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), rHI);
}
FreeTemp(t_reg);
return rl_result;
@@ -261,7 +265,8 @@
return rl_dest;
}
-void MipsMir2Lir::OpLea(int rBase, int reg1, int reg2, int scale, int offset) {
+void MipsMir2Lir::OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale,
+ int offset) {
LOG(FATAL) << "Unexpected use of OpLea for Arm";
}
@@ -285,12 +290,12 @@
return false;
}
RegLocation rl_src_address = info->args[0]; // long address
- rl_src_address.wide = 0; // ignore high half in info->args[1]
+ rl_src_address = NarrowRegLoc(rl_src_address); // ignore high half in info->args[1]
RegLocation rl_dest = InlineTarget(info);
RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
DCHECK(size == kSignedByte);
- LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), size, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg, 0, rl_result.reg, size, INVALID_SREG);
StoreValue(rl_dest, rl_result);
return true;
}
@@ -301,26 +306,26 @@
return false;
}
RegLocation rl_src_address = info->args[0]; // long address
- rl_src_address.wide = 0; // ignore high half in info->args[1]
+ rl_src_address = NarrowRegLoc(rl_src_address); // ignore high half in info->args[1]
RegLocation rl_src_value = info->args[2]; // [size] value
RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
DCHECK(size == kSignedByte);
RegLocation rl_value = LoadValue(rl_src_value, kCoreReg);
- StoreBaseDisp(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), size);
+ StoreBaseDisp(rl_address.reg, 0, rl_value.reg, size);
return true;
}
-LIR* MipsMir2Lir::OpPcRelLoad(int reg, LIR* target) {
+LIR* MipsMir2Lir::OpPcRelLoad(RegStorage reg, LIR* target) {
LOG(FATAL) << "Unexpected use of OpPcRelLoad for Mips";
return NULL;
}
-LIR* MipsMir2Lir::OpVldm(int rBase, int count) {
+LIR* MipsMir2Lir::OpVldm(RegStorage r_base, int count) {
LOG(FATAL) << "Unexpected use of OpVldm for Mips";
return NULL;
}
-LIR* MipsMir2Lir::OpVstm(int rBase, int count) {
+LIR* MipsMir2Lir::OpVstm(RegStorage r_base, int count) {
LOG(FATAL) << "Unexpected use of OpVstm for Mips";
return NULL;
}
@@ -328,30 +333,31 @@
void MipsMir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src,
RegLocation rl_result, int lit,
int first_bit, int second_bit) {
- int t_reg = AllocTemp();
- OpRegRegImm(kOpLsl, t_reg, rl_src.reg.GetReg(), second_bit - first_bit);
- OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), t_reg);
+ RegStorage t_reg = AllocTemp();
+ OpRegRegImm(kOpLsl, t_reg, rl_src.reg, second_bit - first_bit);
+ OpRegRegReg(kOpAdd, rl_result.reg, rl_src.reg, t_reg);
FreeTemp(t_reg);
if (first_bit != 0) {
- OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_result.reg.GetReg(), first_bit);
+ OpRegRegImm(kOpLsl, rl_result.reg, rl_result.reg, first_bit);
}
}
-void MipsMir2Lir::GenDivZeroCheck(int reg_lo, int reg_hi) {
- int t_reg = AllocTemp();
- OpRegRegReg(kOpOr, t_reg, reg_lo, reg_hi);
+void MipsMir2Lir::GenDivZeroCheck(RegStorage reg) {
+ DCHECK(reg.IsPair()); // TODO: support k64BitSolo.
+ RegStorage t_reg = AllocTemp();
+ OpRegRegReg(kOpOr, t_reg, reg.GetLow(), reg.GetHigh());
GenImmedCheck(kCondEq, t_reg, 0, kThrowDivZero);
FreeTemp(t_reg);
}
// Test suspend flag, return target of taken suspend branch
LIR* MipsMir2Lir::OpTestSuspend(LIR* target) {
- OpRegImm(kOpSub, rMIPS_SUSPEND, 1);
- return OpCmpImmBranch((target == NULL) ? kCondEq : kCondNe, rMIPS_SUSPEND, 0, target);
+ OpRegImm(kOpSub, rs_rMIPS_SUSPEND, 1);
+ return OpCmpImmBranch((target == NULL) ? kCondEq : kCondNe, rs_rMIPS_SUSPEND, 0, target);
}
// Decrement register and branch on condition
-LIR* MipsMir2Lir::OpDecAndBranch(ConditionCode c_code, int reg, LIR* target) {
+LIR* MipsMir2Lir::OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target) {
OpRegImm(kOpSub, reg, 1);
return OpCmpImmBranch(c_code, reg, 0, target);
}
@@ -385,11 +391,11 @@
* addu v1,v1,t1
*/
- OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src2.reg.GetReg(), rl_src1.reg.GetReg());
- int t_reg = AllocTemp();
- OpRegRegReg(kOpAdd, t_reg, rl_src2.reg.GetHighReg(), rl_src1.reg.GetHighReg());
- NewLIR3(kMipsSltu, rl_result.reg.GetHighReg(), rl_result.reg.GetReg(), rl_src2.reg.GetReg());
- OpRegRegReg(kOpAdd, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetLow(), rl_src2.reg.GetLow(), rl_src1.reg.GetLow());
+ RegStorage t_reg = AllocTemp();
+ OpRegRegReg(kOpAdd, t_reg, rl_src2.reg.GetHigh(), rl_src1.reg.GetHigh());
+ NewLIR3(kMipsSltu, rl_result.reg.GetHighReg(), rl_result.reg.GetLowReg(), rl_src2.reg.GetLowReg());
+ OpRegRegReg(kOpAdd, rl_result.reg.GetHigh(), rl_result.reg.GetHigh(), t_reg);
FreeTemp(t_reg);
StoreValueWide(rl_dest, rl_result);
}
@@ -407,11 +413,11 @@
* subu v1,v1,t1
*/
- int t_reg = AllocTemp();
- NewLIR3(kMipsSltu, t_reg, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
- OpRegRegReg(kOpSub, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
- OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
- OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
+ RegStorage t_reg = AllocTemp();
+ NewLIR3(kMipsSltu, t_reg.GetReg(), rl_src1.reg.GetLowReg(), rl_src2.reg.GetLowReg());
+ OpRegRegReg(kOpSub, rl_result.reg.GetLow(), rl_src1.reg.GetLow(), rl_src2.reg.GetLow());
+ OpRegRegReg(kOpSub, rl_result.reg.GetHigh(), rl_src1.reg.GetHigh(), rl_src2.reg.GetHigh());
+ OpRegRegReg(kOpSub, rl_result.reg.GetHigh(), rl_result.reg.GetHigh(), t_reg);
FreeTemp(t_reg);
StoreValueWide(rl_dest, rl_result);
}
@@ -427,11 +433,11 @@
* subu v1,v1,t1
*/
- OpRegReg(kOpNeg, rl_result.reg.GetReg(), rl_src.reg.GetReg());
- OpRegReg(kOpNeg, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
- int t_reg = AllocTemp();
- NewLIR3(kMipsSltu, t_reg, r_ZERO, rl_result.reg.GetReg());
- OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
+ OpRegReg(kOpNeg, rl_result.reg.GetLow(), rl_src.reg.GetLow());
+ OpRegReg(kOpNeg, rl_result.reg.GetHigh(), rl_src.reg.GetHigh());
+ RegStorage t_reg = AllocTemp();
+ NewLIR3(kMipsSltu, t_reg.GetReg(), rZERO, rl_result.reg.GetLowReg());
+ OpRegRegReg(kOpSub, rl_result.reg.GetHigh(), rl_result.reg.GetHigh(), t_reg);
FreeTemp(t_reg);
StoreValueWide(rl_dest, rl_result);
}
@@ -471,36 +477,36 @@
}
/* null object? */
- GenNullCheck(rl_array.reg.GetReg(), opt_flags);
+ GenNullCheck(rl_array.reg, opt_flags);
- int reg_ptr = AllocTemp();
+ RegStorage reg_ptr = AllocTemp();
bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
- int reg_len = INVALID_REG;
+ RegStorage reg_len;
if (needs_range_check) {
reg_len = AllocTemp();
/* Get len */
- LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
+ LoadWordDisp(rl_array.reg, len_offset, reg_len);
}
/* reg_ptr -> array data */
- OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg.GetReg(), data_offset);
+ OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg, data_offset);
FreeTemp(rl_array.reg.GetReg());
if ((size == kLong) || (size == kDouble)) {
if (scale) {
- int r_new_index = AllocTemp();
- OpRegRegImm(kOpLsl, r_new_index, rl_index.reg.GetReg(), scale);
+ RegStorage r_new_index = AllocTemp();
+ OpRegRegImm(kOpLsl, r_new_index, rl_index.reg, scale);
OpRegReg(kOpAdd, reg_ptr, r_new_index);
FreeTemp(r_new_index);
} else {
- OpRegReg(kOpAdd, reg_ptr, rl_index.reg.GetReg());
+ OpRegReg(kOpAdd, reg_ptr, rl_index.reg);
}
- FreeTemp(rl_index.reg.GetReg());
+ FreeTemp(rl_index.reg);
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- LoadBaseDispWide(reg_ptr, 0, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
+ LoadBaseDispWide(reg_ptr, 0, rl_result.reg, INVALID_SREG);
FreeTemp(reg_ptr);
StoreValueWide(rl_dest, rl_result);
@@ -508,10 +514,10 @@
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- LoadBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_result.reg.GetReg(), scale, size);
+ LoadBaseIndexed(reg_ptr, rl_index.reg, rl_result.reg, scale, size);
FreeTemp(reg_ptr);
StoreValue(rl_dest, rl_result);
@@ -536,27 +542,27 @@
rl_array = LoadValue(rl_array, kCoreReg);
rl_index = LoadValue(rl_index, kCoreReg);
- int reg_ptr = INVALID_REG;
+ RegStorage reg_ptr;
bool allocated_reg_ptr_temp = false;
if (IsTemp(rl_array.reg.GetReg()) && !card_mark) {
Clobber(rl_array.reg.GetReg());
- reg_ptr = rl_array.reg.GetReg();
+ reg_ptr = rl_array.reg;
} else {
reg_ptr = AllocTemp();
- OpRegCopy(reg_ptr, rl_array.reg.GetReg());
+ OpRegCopy(reg_ptr, rl_array.reg);
allocated_reg_ptr_temp = true;
}
/* null object? */
- GenNullCheck(rl_array.reg.GetReg(), opt_flags);
+ GenNullCheck(rl_array.reg, opt_flags);
bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
- int reg_len = INVALID_REG;
+ RegStorage reg_len;
if (needs_range_check) {
reg_len = AllocTemp();
// NOTE: max live temps(4) here.
/* Get len */
- LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
+ LoadWordDisp(rl_array.reg, len_offset, reg_len);
}
/* reg_ptr -> array data */
OpRegImm(kOpAdd, reg_ptr, data_offset);
@@ -564,35 +570,34 @@
if ((size == kLong) || (size == kDouble)) {
// TUNING: specific wide routine that can handle fp regs
if (scale) {
- int r_new_index = AllocTemp();
- OpRegRegImm(kOpLsl, r_new_index, rl_index.reg.GetReg(), scale);
+ RegStorage r_new_index = AllocTemp();
+ OpRegRegImm(kOpLsl, r_new_index, rl_index.reg, scale);
OpRegReg(kOpAdd, reg_ptr, r_new_index);
FreeTemp(r_new_index);
} else {
- OpRegReg(kOpAdd, reg_ptr, rl_index.reg.GetReg());
+ OpRegReg(kOpAdd, reg_ptr, rl_index.reg);
}
rl_src = LoadValueWide(rl_src, reg_class);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- StoreBaseDispWide(reg_ptr, 0, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
+ StoreBaseDispWide(reg_ptr, 0, rl_src.reg);
} else {
rl_src = LoadValue(rl_src, reg_class);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- StoreBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_src.reg.GetReg(),
- scale, size);
+ StoreBaseIndexed(reg_ptr, rl_index.reg, rl_src.reg, scale, size);
}
if (allocated_reg_ptr_temp) {
FreeTemp(reg_ptr);
}
if (card_mark) {
- MarkGCCard(rl_src.reg.GetReg(), rl_array.reg.GetReg());
+ MarkGCCard(rl_src.reg, rl_array.reg);
}
}
diff --git a/compiler/dex/quick/mips/mips_lir.h b/compiler/dex/quick/mips/mips_lir.h
index 77ae337..96cd3d8 100644
--- a/compiler/dex/quick/mips/mips_lir.h
+++ b/compiler/dex/quick/mips/mips_lir.h
@@ -109,36 +109,37 @@
// Mask to strip off fp flags.
#define MIPS_FP_REG_MASK (MIPS_FP_REG_OFFSET-1)
-#ifdef HAVE_LITTLE_ENDIAN
#define LOWORD_OFFSET 0
#define HIWORD_OFFSET 4
-#define r_ARG0 r_A0
-#define r_ARG1 r_A1
-#define r_ARG2 r_A2
-#define r_ARG3 r_A3
-#define r_RESULT0 r_V0
-#define r_RESULT1 r_V1
-#else
-#define LOWORD_OFFSET 4
-#define HIWORD_OFFSET 0
-#define r_ARG0 r_A1
-#define r_ARG1 r_A0
-#define r_ARG2 r_A3
-#define r_ARG3 r_A2
-#define r_RESULT0 r_V1
-#define r_RESULT1 r_V0
-#endif
+#define rARG0 rA0
+#define rs_rARG0 rs_rA0
+#define rARG1 rA1
+#define rs_rARG1 rs_rA1
+#define rARG2 rA2
+#define rs_rARG2 rs_rA2
+#define rARG3 rA3
+#define rs_rARG3 rs_rA3
+#define rRESULT0 rV0
+#define rs_rRESULT0 rs_rV0
+#define rRESULT1 rV1
+#define rs_rRESULT1 rs_rV1
-// These are the same for both big and little endian.
-#define r_FARG0 r_F12
-#define r_FARG1 r_F13
-#define r_FARG2 r_F14
-#define r_FARG3 r_F15
-#define r_FRESULT0 r_F0
-#define r_FRESULT1 r_F1
+#define rFARG0 rF12
+#define rs_rFARG0 rs_rF12
+#define rFARG1 rF13
+#define rs_rFARG1 rs_rF13
+#define rFARG2 rF14
+#define rs_rFARG2 rs_rF14
+#define rFARG3 rF15
+#define rs_rFARG3 rs_rF15
+#define rFRESULT0 rF0
+#define rs_rFRESULT0 rs_rF0
+#define rFRESULT1 rF1
+#define rs_rFRESULT1 rs_rF1
// Regs not used for Mips.
-#define rMIPS_PC INVALID_REG
+#define rMIPS_LR RegStorage::kInvalidRegVal
+#define rMIPS_PC RegStorage::kInvalidRegVal
enum MipsResourceEncodingPos {
kMipsGPReg0 = 0,
@@ -158,130 +159,183 @@
#define ENCODE_MIPS_REG_PC (1ULL << kMipsRegPC)
enum MipsNativeRegisterPool {
- r_ZERO = 0,
- r_AT = 1,
- r_V0 = 2,
- r_V1 = 3,
- r_A0 = 4,
- r_A1 = 5,
- r_A2 = 6,
- r_A3 = 7,
- r_T0 = 8,
- r_T1 = 9,
- r_T2 = 10,
- r_T3 = 11,
- r_T4 = 12,
- r_T5 = 13,
- r_T6 = 14,
- r_T7 = 15,
- r_S0 = 16,
- r_S1 = 17,
- r_S2 = 18,
- r_S3 = 19,
- r_S4 = 20,
- r_S5 = 21,
- r_S6 = 22,
- r_S7 = 23,
- r_T8 = 24,
- r_T9 = 25,
- r_K0 = 26,
- r_K1 = 27,
- r_GP = 28,
- r_SP = 29,
- r_FP = 30,
- r_RA = 31,
+ 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,
- r_F0 = 0 + MIPS_FP_REG_OFFSET,
- r_F1,
- r_F2,
- r_F3,
- r_F4,
- r_F5,
- r_F6,
- r_F7,
- r_F8,
- r_F9,
- r_F10,
- r_F11,
- r_F12,
- r_F13,
- r_F14,
- r_F15,
+ rF0 = 0 + MIPS_FP_REG_OFFSET,
+ rF1,
+ rF2,
+ rF3,
+ rF4,
+ rF5,
+ rF6,
+ rF7,
+ rF8,
+ rF9,
+ rF10,
+ rF11,
+ rF12,
+ rF13,
+ rF14,
+ rF15,
#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.
*/
- r_F16,
- r_F17,
- r_F18,
- r_F19,
- r_F20,
- r_F21,
- r_F22,
- r_F23,
- r_F24,
- r_F25,
- r_F26,
- r_F27,
- r_F28,
- r_F29,
- r_F30,
- r_F31,
+ rF16,
+ rF17,
+ rF18,
+ rF19,
+ rF20,
+ rF21,
+ rF22,
+ rF23,
+ rF24,
+ rF25,
+ rF26,
+ rF27,
+ rF28,
+ rF29,
+ rF30,
+ rF31,
#endif
- r_DF0 = r_F0 + MIPS_FP_DOUBLE,
- r_DF1 = r_F2 + MIPS_FP_DOUBLE,
- r_DF2 = r_F4 + MIPS_FP_DOUBLE,
- r_DF3 = r_F6 + MIPS_FP_DOUBLE,
- r_DF4 = r_F8 + MIPS_FP_DOUBLE,
- r_DF5 = r_F10 + MIPS_FP_DOUBLE,
- r_DF6 = r_F12 + MIPS_FP_DOUBLE,
- r_DF7 = r_F14 + MIPS_FP_DOUBLE,
+ 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,
#if 0 // TODO: expand resource mask to enable use of all MIPS fp registers.
- r_DF8 = r_F16 + MIPS_FP_DOUBLE,
- r_DF9 = r_F18 + MIPS_FP_DOUBLE,
- r_DF10 = r_F20 + MIPS_FP_DOUBLE,
- r_DF11 = r_F22 + MIPS_FP_DOUBLE,
- r_DF12 = r_F24 + MIPS_FP_DOUBLE,
- r_DF13 = r_F26 + MIPS_FP_DOUBLE,
- r_DF14 = r_F28 + MIPS_FP_DOUBLE,
- r_DF15 = r_F30 + MIPS_FP_DOUBLE,
+ 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,
#endif
- r_HI = MIPS_EXTRA_REG_OFFSET,
- r_LO,
- r_PC,
+ rHI = MIPS_EXTRA_REG_OFFSET,
+ rLO,
+ rPC,
};
-#define rMIPS_SUSPEND r_S0
-#define rMIPS_SELF r_S1
-#define rMIPS_SP r_SP
-#define rMIPS_ARG0 r_ARG0
-#define rMIPS_ARG1 r_ARG1
-#define rMIPS_ARG2 r_ARG2
-#define rMIPS_ARG3 r_ARG3
-#define rMIPS_FARG0 r_FARG0
-#define rMIPS_FARG1 r_FARG1
-#define rMIPS_FARG2 r_FARG2
-#define rMIPS_FARG3 r_FARG3
-#define rMIPS_RET0 r_RESULT0
-#define rMIPS_RET1 r_RESULT1
-#define rMIPS_INVOKE_TGT r_T9
-#define rMIPS_COUNT INVALID_REG
-#define rMIPS_LR r_RA
+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);
+
+// TODO: reduce/eliminate use of these.
+#define rMIPS_SUSPEND rS0
+#define rs_rMIPS_SUSPEND rs_rS0
+#define rMIPS_SELF rS1
+#define rs_rMIPS_SELF rs_rS1
+#define rMIPS_SP rSP
+#define rs_rMIPS_SP rs_rSP
+#define rMIPS_ARG0 rARG0
+#define rs_rMIPS_ARG0 rs_rARG0
+#define rMIPS_ARG1 rARG1
+#define rs_rMIPS_ARG1 rs_rARG1
+#define rMIPS_ARG2 rARG2
+#define rs_rMIPS_ARG2 rs_rARG2
+#define rMIPS_ARG3 rARG3
+#define rs_rMIPS_ARG3 rs_rARG3
+#define rMIPS_FARG0 rFARG0
+#define rs_rMIPS_FARG0 rs_rFARG0
+#define rMIPS_FARG1 rFARG1
+#define rs_rMIPS_FARG1 rs_rFARG1
+#define rMIPS_FARG2 rFARG2
+#define rs_rMIPS_FARG2 rs_rFARG2
+#define rMIPS_FARG3 rFARG3
+#define rs_MIPS_FARG3 rs_rFARG3
+#define rMIPS_RET0 rRESULT0
+#define rs_MIPS_RET0 rs_rRESULT0
+#define rMIPS_RET1 rRESULT1
+#define rs_rMIPS_RET1 rs_rRESULT1
+#define rMIPS_INVOKE_TGT rT9
+#define rs_rMIPS_INVOKE_TGT rs_rT9
+#define rMIPS_COUNT RegStorage::kInvalidRegVal
// 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,
- RegStorage(RegStorage::k32BitSolo, r_V0), INVALID_SREG, INVALID_SREG};
+ 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,
- RegStorage(RegStorage::k64BitPair, r_V0, r_V1), INVALID_SREG, INVALID_SREG};
+ 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,
- RegStorage(RegStorage::k32BitSolo, r_F0), INVALID_SREG, INVALID_SREG};
+ RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
const RegLocation mips_loc_c_return_double
{kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorNotUsed,
- RegStorage(RegStorage::k64BitPair, r_F0, r_F1), INVALID_SREG, INVALID_SREG};
+ RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
enum MipsShiftEncodings {
kMipsLsl = 0x0,
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index b7fb2f4..67a44fa 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -26,18 +26,18 @@
namespace art {
-static int core_regs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3,
- r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7,
- r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8,
- r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA};
-static int ReservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP,
- r_RA};
-static int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
- r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
-static int FpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
- r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
-static int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
- r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
+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};
RegLocation MipsMir2Lir::LocCReturn() {
return mips_loc_c_return;
@@ -56,43 +56,43 @@
}
// Return a target-dependent special register.
-int MipsMir2Lir::TargetReg(SpecialTargetRegister reg) {
- int res = INVALID_REG;
+RegStorage MipsMir2Lir::TargetReg(SpecialTargetRegister reg) {
+ int res_reg = RegStorage::kInvalidRegVal;
switch (reg) {
- case kSelf: res = rMIPS_SELF; break;
- case kSuspend: res = rMIPS_SUSPEND; break;
- case kLr: res = rMIPS_LR; break;
- case kPc: res = rMIPS_PC; break;
- case kSp: res = rMIPS_SP; break;
- case kArg0: res = rMIPS_ARG0; break;
- case kArg1: res = rMIPS_ARG1; break;
- case kArg2: res = rMIPS_ARG2; break;
- case kArg3: res = rMIPS_ARG3; break;
- case kFArg0: res = rMIPS_FARG0; break;
- case kFArg1: res = rMIPS_FARG1; break;
- case kFArg2: res = rMIPS_FARG2; break;
- case kFArg3: res = rMIPS_FARG3; break;
- case kRet0: res = rMIPS_RET0; break;
- case kRet1: res = rMIPS_RET1; break;
- case kInvokeTgt: res = rMIPS_INVOKE_TGT; break;
- case kHiddenArg: res = r_T0; break;
- case kHiddenFpArg: res = INVALID_REG; break;
- case kCount: res = rMIPS_COUNT; break;
+ 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;
}
- return res;
+ return RegStorage::Solo32(res_reg);
}
-int MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) {
+RegStorage MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) {
// For the 32-bit internal ABI, the first 3 arguments are passed in registers.
switch (arg_num) {
case 0:
- return rMIPS_ARG1;
+ return rs_rMIPS_ARG1;
case 1:
- return rMIPS_ARG2;
+ return rs_rMIPS_ARG2;
case 2:
- return rMIPS_ARG3;
+ return rs_rMIPS_ARG3;
default:
- return INVALID_REG;
+ return RegStorage::InvalidReg();
}
}
@@ -311,7 +311,7 @@
*/
void MipsMir2Lir::AdjustSpillMask() {
- core_spill_mask_ |= (1 << r_RA);
+ core_spill_mask_ |= (1 << rRA);
num_core_spills_++;
}
@@ -325,9 +325,9 @@
LOG(FATAL) << "No support yet for promoted FP regs";
}
-void MipsMir2Lir::FlushRegWide(int reg1, int reg2) {
- RegisterInfo* info1 = GetRegInfo(reg1);
- RegisterInfo* info2 = GetRegInfo(reg2);
+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));
@@ -342,16 +342,18 @@
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(rMIPS_SP, VRegOffset(v_reg), info1->reg, info1->partner);
+ StoreBaseDispWide(rs_rMIPS_SP, VRegOffset(v_reg),
+ RegStorage(RegStorage::k64BitPair, info1->reg, info1->partner));
}
}
-void MipsMir2Lir::FlushReg(int reg) {
- RegisterInfo* info = GetRegInfo(reg);
+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);
- StoreBaseDisp(rMIPS_SP, VRegOffset(v_reg), reg, kWord);
+ StoreBaseDisp(rs_rMIPS_SP, VRegOffset(v_reg), reg, kWord);
}
}
@@ -360,47 +362,51 @@
return MIPS_FPREG(reg);
}
+bool MipsMir2Lir::IsFpReg(RegStorage reg) {
+ return IsFpReg(reg.IsPair() ? reg.GetLowReg() : reg.GetReg());
+}
+
/* Clobber all regs that might be used by an external C call */
void MipsMir2Lir::ClobberCallerSave() {
- Clobber(r_ZERO);
- Clobber(r_AT);
- Clobber(r_V0);
- Clobber(r_V1);
- Clobber(r_A0);
- Clobber(r_A1);
- Clobber(r_A2);
- Clobber(r_A3);
- Clobber(r_T0);
- Clobber(r_T1);
- Clobber(r_T2);
- Clobber(r_T3);
- Clobber(r_T4);
- Clobber(r_T5);
- Clobber(r_T6);
- Clobber(r_T7);
- Clobber(r_T8);
- Clobber(r_T9);
- Clobber(r_K0);
- Clobber(r_K1);
- Clobber(r_GP);
- Clobber(r_FP);
- Clobber(r_RA);
- Clobber(r_F0);
- Clobber(r_F1);
- Clobber(r_F2);
- Clobber(r_F3);
- Clobber(r_F4);
- Clobber(r_F5);
- Clobber(r_F6);
- Clobber(r_F7);
- Clobber(r_F8);
- Clobber(r_F9);
- Clobber(r_F10);
- Clobber(r_F11);
- Clobber(r_F12);
- Clobber(r_F13);
- Clobber(r_F14);
- Clobber(r_F15);
+ 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);
}
RegLocation MipsMir2Lir::GetReturnWideAlt() {
@@ -443,17 +449,15 @@
int low_reg;
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- low_reg = AllocTempDouble();
- high_reg = low_reg + 1;
- return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
+ return AllocTempDouble();
}
- low_reg = AllocTemp();
- high_reg = AllocTemp();
+ low_reg = AllocTemp().GetReg();
+ high_reg = AllocTemp().GetReg();
return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
}
-int MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
+RegStorage MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
return AllocTempFloat();
}
@@ -494,11 +498,14 @@
}
void MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free) {
- if ((rl_free.reg.GetReg() != rl_keep.reg.GetReg()) && (rl_free.reg.GetReg() != rl_keep.reg.GetHighReg()) &&
- (rl_free.reg.GetHighReg() != rl_keep.reg.GetReg()) && (rl_free.reg.GetHighReg() != rl_keep.reg.GetHighReg())) {
- // No overlap, free both
- FreeTemp(rl_free.reg.GetReg());
- FreeTemp(rl_free.reg.GetHighReg());
+ DCHECK(rl_keep.wide);
+ DCHECK(rl_free.wide);
+ if ((rl_free.reg.GetLowReg() != rl_keep.reg.GetLowReg()) &&
+ (rl_free.reg.GetLowReg() != rl_keep.reg.GetHighReg()) &&
+ (rl_free.reg.GetHighReg() != rl_keep.reg.GetLowReg()) &&
+ (rl_free.reg.GetHighReg() != rl_keep.reg.GetHighReg())) {
+ // No overlap, free.
+ FreeTemp(rl_free.reg);
}
}
/*
@@ -507,14 +514,14 @@
* ensure that all branch instructions can be restarted if
* there is a trap in the shadow. Allocate a temp register.
*/
-int MipsMir2Lir::LoadHelper(ThreadOffset offset) {
- LoadWordDisp(rMIPS_SELF, offset.Int32Value(), r_T9);
- return r_T9;
+RegStorage MipsMir2Lir::LoadHelper(ThreadOffset offset) {
+ LoadWordDisp(rs_rMIPS_SELF, offset.Int32Value(), rs_rT9);
+ return rs_rT9;
}
LIR* MipsMir2Lir::CheckSuspendUsingLoad() {
- int tmp = AllocTemp();
- LoadWordDisp(rMIPS_SELF, Thread::ThreadSuspendTriggerOffset().Int32Value(), tmp);
+ RegStorage tmp = AllocTemp();
+ LoadWordDisp(rs_rMIPS_SELF, Thread::ThreadSuspendTriggerOffset().Int32Value(), tmp);
LIR *inst = LoadWordDisp(tmp, 0, tmp);
FreeTemp(tmp);
return inst;
@@ -526,11 +533,11 @@
}
uint32_t mask = core_spill_mask_;
int offset = num_core_spills_ * 4;
- OpRegImm(kOpSub, rMIPS_SP, offset);
+ OpRegImm(kOpSub, rs_rSP, offset);
for (int reg = 0; mask; mask >>= 1, reg++) {
if (mask & 0x1) {
offset -= 4;
- StoreWordDisp(rMIPS_SP, offset, reg);
+ StoreWordDisp(rs_rMIPS_SP, offset, RegStorage::Solo32(reg));
}
}
}
@@ -544,10 +551,10 @@
for (int reg = 0; mask; mask >>= 1, reg++) {
if (mask & 0x1) {
offset -= 4;
- LoadWordDisp(rMIPS_SP, offset, reg);
+ LoadWordDisp(rs_rMIPS_SP, offset, RegStorage::Solo32(reg));
}
}
- OpRegImm(kOpAdd, rMIPS_SP, frame_size_);
+ OpRegImm(kOpAdd, rs_rSP, frame_size_);
}
bool MipsMir2Lir::IsUnconditionalBranch(LIR* lir) {
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc
index 21c971c..4f31341 100644
--- a/compiler/dex/quick/mips/utility_mips.cc
+++ b/compiler/dex/quick/mips/utility_mips.cc
@@ -21,29 +21,29 @@
namespace art {
/* This file contains codegen for the MIPS32 ISA. */
-LIR* MipsMir2Lir::OpFpRegCopy(int r_dest, int r_src) {
+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), MIPS_DOUBLEREG(r_src));
- if (MIPS_DOUBLEREG(r_dest)) {
+ DCHECK_EQ(MIPS_DOUBLEREG(r_dest.GetReg()), MIPS_DOUBLEREG(r_src.GetReg()));
+ if (MIPS_DOUBLEREG(r_dest.GetReg())) {
opcode = kMipsFmovd;
} else {
- if (MIPS_SINGLEREG(r_dest)) {
- if (MIPS_SINGLEREG(r_src)) {
+ if (MIPS_SINGLEREG(r_dest.GetReg())) {
+ if (MIPS_SINGLEREG(r_src.GetReg())) {
opcode = kMipsFmovs;
} else {
/* note the operands are swapped for the mtc1 instr */
- int t_opnd = r_src;
+ RegStorage t_opnd = r_src;
r_src = r_dest;
r_dest = t_opnd;
opcode = kMipsMtc1;
}
} else {
- DCHECK(MIPS_SINGLEREG(r_src));
+ DCHECK(MIPS_SINGLEREG(r_src.GetReg()));
opcode = kMipsMfc1;
}
}
- LIR* res = RawLIR(current_dalvik_offset_, opcode, r_src, r_dest);
+ LIR* res = RawLIR(current_dalvik_offset_, opcode, r_src.GetReg(), r_dest.GetReg());
if (!(cu_->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) {
res->flags.is_nop = true;
}
@@ -75,31 +75,31 @@
* 1) r_dest is freshly returned from AllocTemp or
* 2) The codegen is under fixed register usage
*/
-LIR* MipsMir2Lir::LoadConstantNoClobber(int r_dest, int value) {
+LIR* MipsMir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) {
LIR *res;
- int r_dest_save = r_dest;
- int is_fp_reg = MIPS_FPREG(r_dest);
+ RegStorage r_dest_save = r_dest;
+ int is_fp_reg = MIPS_FPREG(r_dest.GetReg());
if (is_fp_reg) {
- DCHECK(MIPS_SINGLEREG(r_dest));
+ DCHECK(MIPS_SINGLEREG(r_dest.GetReg()));
r_dest = AllocTemp();
}
/* See if the value can be constructed cheaply */
if (value == 0) {
- res = NewLIR2(kMipsMove, r_dest, r_ZERO);
+ res = NewLIR2(kMipsMove, r_dest.GetReg(), rZERO);
} else if ((value > 0) && (value <= 65535)) {
- res = NewLIR3(kMipsOri, r_dest, r_ZERO, value);
+ res = NewLIR3(kMipsOri, r_dest.GetReg(), rZERO, value);
} else if ((value < 0) && (value >= -32768)) {
- res = NewLIR3(kMipsAddiu, r_dest, r_ZERO, value);
+ res = NewLIR3(kMipsAddiu, r_dest.GetReg(), rZERO, value);
} else {
- res = NewLIR2(kMipsLui, r_dest, value >> 16);
+ res = NewLIR2(kMipsLui, r_dest.GetReg(), value >> 16);
if (value & 0xffff)
- NewLIR3(kMipsOri, r_dest, r_dest, value);
+ NewLIR3(kMipsOri, r_dest.GetReg(), r_dest.GetReg(), value);
}
if (is_fp_reg) {
- NewLIR2(kMipsMtc1, r_dest, r_dest_save);
+ NewLIR2(kMipsMtc1, r_dest.GetReg(), r_dest_save.GetReg());
FreeTemp(r_dest);
}
@@ -112,23 +112,22 @@
return res;
}
-LIR* MipsMir2Lir::OpReg(OpKind op, int r_dest_src) {
+LIR* MipsMir2Lir::OpReg(OpKind op, RegStorage r_dest_src) {
MipsOpCode opcode = kMipsNop;
switch (op) {
case kOpBlx:
opcode = kMipsJalr;
break;
case kOpBx:
- return NewLIR1(kMipsJr, r_dest_src);
+ return NewLIR1(kMipsJr, r_dest_src.GetReg());
break;
default:
LOG(FATAL) << "Bad case in OpReg";
}
- return NewLIR2(opcode, r_RA, r_dest_src);
+ return NewLIR2(opcode, rRA, r_dest_src.GetReg());
}
-LIR* MipsMir2Lir::OpRegImm(OpKind op, int r_dest_src1,
- int value) {
+LIR* MipsMir2Lir::OpRegImm(OpKind op, RegStorage r_dest_src1, int value) {
LIR *res;
bool neg = (value < 0);
int abs_value = (neg) ? -value : value;
@@ -146,19 +145,19 @@
break;
}
if (short_form) {
- res = NewLIR2(opcode, r_dest_src1, abs_value);
+ res = NewLIR2(opcode, r_dest_src1.GetReg(), abs_value);
} else {
- int r_scratch = AllocTemp();
+ RegStorage r_scratch = AllocTemp();
res = LoadConstant(r_scratch, value);
if (op == kOpCmp)
- NewLIR2(opcode, r_dest_src1, r_scratch);
+ NewLIR2(opcode, r_dest_src1.GetReg(), r_scratch.GetReg());
else
- NewLIR3(opcode, r_dest_src1, r_dest_src1, r_scratch);
+ NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), r_scratch.GetReg());
}
return res;
}
-LIR* MipsMir2Lir::OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2) {
+LIR* MipsMir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2) {
MipsOpCode opcode = kMipsNop;
switch (op) {
case kOpAdd:
@@ -196,10 +195,10 @@
LOG(FATAL) << "bad case in OpRegRegReg";
break;
}
- return NewLIR3(opcode, r_dest, r_src1, r_src2);
+ return NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg());
}
-LIR* MipsMir2Lir::OpRegRegImm(OpKind op, int r_dest, int r_src1, int value) {
+LIR* MipsMir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value) {
LIR *res;
MipsOpCode opcode = kMipsNop;
bool short_form = true;
@@ -268,21 +267,21 @@
}
if (short_form) {
- res = NewLIR3(opcode, r_dest, r_src1, value);
+ res = NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), value);
} else {
if (r_dest != r_src1) {
res = LoadConstant(r_dest, value);
- NewLIR3(opcode, r_dest, r_src1, r_dest);
+ NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_dest.GetReg());
} else {
- int r_scratch = AllocTemp();
+ RegStorage r_scratch = AllocTemp();
res = LoadConstant(r_scratch, value);
- NewLIR3(opcode, r_dest, r_src1, r_scratch);
+ NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_scratch.GetReg());
}
}
return res;
}
-LIR* MipsMir2Lir::OpRegReg(OpKind op, int r_dest_src1, int r_src2) {
+LIR* MipsMir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) {
MipsOpCode opcode = kMipsNop;
LIR *res;
switch (op) {
@@ -290,9 +289,9 @@
opcode = kMipsMove;
break;
case kOpMvn:
- return NewLIR3(kMipsNor, r_dest_src1, r_src2, r_ZERO);
+ return NewLIR3(kMipsNor, r_dest_src1.GetReg(), r_src2.GetReg(), rZERO);
case kOpNeg:
- return NewLIR3(kMipsSubu, r_dest_src1, r_ZERO, r_src2);
+ return NewLIR3(kMipsSubu, r_dest_src1.GetReg(), rZERO, r_src2.GetReg());
case kOpAdd:
case kOpAnd:
case kOpMul:
@@ -302,7 +301,7 @@
return OpRegRegReg(op, r_dest_src1, r_dest_src1, r_src2);
case kOp2Byte:
#if __mips_isa_rev >= 2
- res = NewLIR2(kMipsSeb, r_dest_src1, r_src2);
+ res = NewLIR2(kMipsSeb, r_dest_src1.GetReg(), r_src2.GetReg());
#else
res = OpRegRegImm(kOpLsl, r_dest_src1, r_src2, 24);
OpRegRegImm(kOpAsr, r_dest_src1, r_dest_src1, 24);
@@ -310,53 +309,54 @@
return res;
case kOp2Short:
#if __mips_isa_rev >= 2
- res = NewLIR2(kMipsSeh, r_dest_src1, r_src2);
+ res = NewLIR2(kMipsSeh, r_dest_src1.GetReg(), r_src2.GetReg());
#else
res = OpRegRegImm(kOpLsl, r_dest_src1, r_src2, 16);
OpRegRegImm(kOpAsr, r_dest_src1, r_dest_src1, 16);
#endif
return res;
case kOp2Char:
- return NewLIR3(kMipsAndi, r_dest_src1, r_src2, 0xFFFF);
+ return NewLIR3(kMipsAndi, r_dest_src1.GetReg(), r_src2.GetReg(), 0xFFFF);
default:
LOG(FATAL) << "Bad case in OpRegReg";
break;
}
- return NewLIR2(opcode, r_dest_src1, r_src2);
+ return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg());
}
-LIR* MipsMir2Lir::OpMovRegMem(int r_dest, int r_base, int offset, MoveType move_type) {
+LIR* MipsMir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset,
+ MoveType move_type) {
UNIMPLEMENTED(FATAL);
return nullptr;
}
-LIR* MipsMir2Lir::OpMovMemReg(int r_base, int offset, int r_src, MoveType move_type) {
+LIR* MipsMir2Lir::OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) {
UNIMPLEMENTED(FATAL);
return nullptr;
}
-LIR* MipsMir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, int r_dest, int r_src) {
+LIR* MipsMir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) {
LOG(FATAL) << "Unexpected use of OpCondRegReg for MIPS";
return NULL;
}
-LIR* MipsMir2Lir::LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value) {
+LIR* MipsMir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) {
LIR *res;
- res = LoadConstantNoClobber(r_dest_lo, Low32Bits(value));
- LoadConstantNoClobber(r_dest_hi, High32Bits(value));
+ res = LoadConstantNoClobber(r_dest.GetLow(), Low32Bits(value));
+ LoadConstantNoClobber(r_dest.GetHigh(), High32Bits(value));
return res;
}
/* Load value from base + scaled index. */
-LIR* MipsMir2Lir::LoadBaseIndexed(int rBase, int r_index, int r_dest,
+LIR* MipsMir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
int scale, OpSize size) {
LIR *first = NULL;
LIR *res;
MipsOpCode opcode = kMipsNop;
- int t_reg = AllocTemp();
+ RegStorage t_reg = AllocTemp();
- if (MIPS_FPREG(r_dest)) {
- DCHECK(MIPS_SINGLEREG(r_dest));
+ if (MIPS_FPREG(r_dest.GetReg())) {
+ DCHECK(MIPS_SINGLEREG(r_dest.GetReg()));
DCHECK((size == kWord) || (size == kSingle));
size = kSingle;
} else {
@@ -365,10 +365,10 @@
}
if (!scale) {
- first = NewLIR3(kMipsAddu, t_reg , rBase, r_index);
+ first = NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), r_index.GetReg());
} else {
first = OpRegRegImm(kOpLsl, t_reg, r_index, scale);
- NewLIR3(kMipsAddu, t_reg , rBase, t_reg);
+ NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), t_reg.GetReg());
}
switch (size) {
@@ -394,21 +394,20 @@
LOG(FATAL) << "Bad case in LoadBaseIndexed";
}
- res = NewLIR3(opcode, r_dest, 0, t_reg);
+ res = NewLIR3(opcode, r_dest.GetReg(), 0, t_reg.GetReg());
FreeTemp(t_reg);
return (first) ? first : res;
}
/* store value base base + scaled index. */
-LIR* MipsMir2Lir::StoreBaseIndexed(int rBase, int r_index, int r_src,
+LIR* MipsMir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
int scale, OpSize size) {
LIR *first = NULL;
MipsOpCode opcode = kMipsNop;
- int r_new_index = r_index;
- int t_reg = AllocTemp();
+ RegStorage t_reg = AllocTemp();
- if (MIPS_FPREG(r_src)) {
- DCHECK(MIPS_SINGLEREG(r_src));
+ if (MIPS_FPREG(r_src.GetReg())) {
+ DCHECK(MIPS_SINGLEREG(r_src.GetReg()));
DCHECK((size == kWord) || (size == kSingle));
size = kSingle;
} else {
@@ -417,10 +416,10 @@
}
if (!scale) {
- first = NewLIR3(kMipsAddu, t_reg , rBase, r_index);
+ first = NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), r_index.GetReg());
} else {
first = OpRegRegImm(kOpLsl, t_reg, r_index, scale);
- NewLIR3(kMipsAddu, t_reg , rBase, t_reg);
+ NewLIR3(kMipsAddu, t_reg.GetReg() , r_base.GetReg(), t_reg.GetReg());
}
switch (size) {
@@ -441,13 +440,13 @@
default:
LOG(FATAL) << "Bad case in StoreBaseIndexed";
}
- NewLIR3(opcode, r_src, 0, t_reg);
- FreeTemp(r_new_index);
+ NewLIR3(opcode, r_src.GetReg(), 0, t_reg.GetReg());
return first;
}
-LIR* MipsMir2Lir::LoadBaseDispBody(int rBase, int displacement, int r_dest,
- int r_dest_hi, OpSize size, int s_reg) {
+// FIXME: don't split r_dest into 2 containers.
+LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest,
+ RegStorage r_dest_hi, OpSize size, int s_reg) {
/*
* Load value from base + displacement. Optionally perform null check
* on base (which must have an associated s_reg and MIR). If not
@@ -468,15 +467,16 @@
case kDouble:
pair = true;
opcode = kMipsLw;
- if (MIPS_FPREG(r_dest)) {
+ if (MIPS_FPREG(r_dest.GetReg())) {
opcode = kMipsFlwc1;
- if (MIPS_DOUBLEREG(r_dest)) {
- r_dest = r_dest - MIPS_FP_DOUBLE;
+ if (MIPS_DOUBLEREG(r_dest.GetReg())) {
+ // TODO: rework to use k64BitSolo
+ r_dest.SetReg(r_dest.GetReg() - MIPS_FP_DOUBLE);
} else {
- DCHECK(MIPS_FPREG(r_dest_hi));
- DCHECK(r_dest == (r_dest_hi - 1));
+ DCHECK(MIPS_FPREG(r_dest_hi.GetReg()));
+ DCHECK_EQ(r_dest.GetReg(), r_dest_hi.GetReg() - 1);
}
- r_dest_hi = r_dest + 1;
+ r_dest_hi.SetReg(r_dest.GetReg() + 1);
}
short_form = IS_SIMM16_2WORD(displacement);
DCHECK_EQ((displacement & 0x3), 0);
@@ -484,9 +484,9 @@
case kWord:
case kSingle:
opcode = kMipsLw;
- if (MIPS_FPREG(r_dest)) {
+ if (MIPS_FPREG(r_dest.GetReg())) {
opcode = kMipsFlwc1;
- DCHECK(MIPS_SINGLEREG(r_dest));
+ DCHECK(MIPS_SINGLEREG(r_dest.GetReg()));
}
DCHECK_EQ((displacement & 0x3), 0);
break;
@@ -510,30 +510,28 @@
if (short_form) {
if (!pair) {
- load = res = NewLIR3(opcode, r_dest, displacement, rBase);
+ load = res = NewLIR3(opcode, r_dest.GetReg(), displacement, r_base.GetReg());
} else {
- load = res = NewLIR3(opcode, r_dest,
- displacement + LOWORD_OFFSET, rBase);
- load2 = NewLIR3(opcode, r_dest_hi,
- displacement + HIWORD_OFFSET, rBase);
+ load = res = NewLIR3(opcode, r_dest.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+ load2 = NewLIR3(opcode, r_dest_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
}
} else {
if (pair) {
- int r_tmp = AllocTemp();
- res = OpRegRegImm(kOpAdd, r_tmp, rBase, displacement);
- load = NewLIR3(opcode, r_dest, LOWORD_OFFSET, r_tmp);
- load2 = NewLIR3(opcode, r_dest_hi, HIWORD_OFFSET, r_tmp);
+ RegStorage r_tmp = AllocTemp();
+ res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement);
+ load = NewLIR3(opcode, r_dest.GetReg(), LOWORD_OFFSET, r_tmp.GetReg());
+ load2 = NewLIR3(opcode, r_dest_hi.GetReg(), HIWORD_OFFSET, r_tmp.GetReg());
FreeTemp(r_tmp);
} else {
- int r_tmp = (rBase == r_dest) ? AllocTemp() : r_dest;
- res = OpRegRegImm(kOpAdd, r_tmp, rBase, displacement);
- load = NewLIR3(opcode, r_dest, 0, r_tmp);
+ RegStorage r_tmp = (r_base == r_dest) ? AllocTemp() : r_dest;
+ res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement);
+ load = NewLIR3(opcode, r_dest.GetReg(), 0, r_tmp.GetReg());
if (r_tmp != r_dest)
FreeTemp(r_tmp);
}
}
- if (rBase == rMIPS_SP) {
+ if (r_base == rs_rMIPS_SP) {
AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
true /* is_load */, pair /* is64bit */);
if (pair) {
@@ -544,19 +542,19 @@
return load;
}
-LIR* MipsMir2Lir::LoadBaseDisp(int rBase, int displacement, int r_dest,
+LIR* MipsMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
OpSize size, int s_reg) {
- return LoadBaseDispBody(rBase, displacement, r_dest, -1,
- size, s_reg);
+ return LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size,
+ s_reg);
}
-LIR* MipsMir2Lir::LoadBaseDispWide(int rBase, int displacement,
- int r_dest_lo, int r_dest_hi, int s_reg) {
- return LoadBaseDispBody(rBase, displacement, r_dest_lo, r_dest_hi, kLong, s_reg);
+LIR* MipsMir2Lir::LoadBaseDispWide(RegStorage r_base, int displacement, RegStorage r_dest,
+ int s_reg) {
+ return LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), kLong, s_reg);
}
-LIR* MipsMir2Lir::StoreBaseDispBody(int rBase, int displacement,
- int r_src, int r_src_hi, OpSize size) {
+LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement,
+ RegStorage r_src, RegStorage r_src_hi, OpSize size) {
LIR *res;
LIR *store = NULL;
LIR *store2 = NULL;
@@ -569,15 +567,15 @@
case kDouble:
pair = true;
opcode = kMipsSw;
- if (MIPS_FPREG(r_src)) {
+ if (MIPS_FPREG(r_src.GetReg())) {
opcode = kMipsFswc1;
- if (MIPS_DOUBLEREG(r_src)) {
- r_src = r_src - MIPS_FP_DOUBLE;
+ if (MIPS_DOUBLEREG(r_src.GetReg())) {
+ r_src.SetReg(r_src.GetReg() - MIPS_FP_DOUBLE);
} else {
- DCHECK(MIPS_FPREG(r_src_hi));
- DCHECK_EQ(r_src, (r_src_hi - 1));
+ DCHECK(MIPS_FPREG(r_src_hi.GetReg()));
+ DCHECK_EQ(r_src.GetReg(), (r_src_hi.GetReg() - 1));
}
- r_src_hi = r_src + 1;
+ r_src_hi.SetReg(r_src.GetReg() + 1);
}
short_form = IS_SIMM16_2WORD(displacement);
DCHECK_EQ((displacement & 0x3), 0);
@@ -585,9 +583,9 @@
case kWord:
case kSingle:
opcode = kMipsSw;
- if (MIPS_FPREG(r_src)) {
+ if (MIPS_FPREG(r_src.GetReg())) {
opcode = kMipsFswc1;
- DCHECK(MIPS_SINGLEREG(r_src));
+ DCHECK(MIPS_SINGLEREG(r_src.GetReg()));
}
DCHECK_EQ((displacement & 0x3), 0);
break;
@@ -601,31 +599,29 @@
opcode = kMipsSb;
break;
default:
- LOG(FATAL) << "Bad case in StoreBaseIndexedBody";
+ LOG(FATAL) << "Bad case in StoreBaseDispBody";
}
if (short_form) {
if (!pair) {
- store = res = NewLIR3(opcode, r_src, displacement, rBase);
+ store = res = NewLIR3(opcode, r_src.GetReg(), displacement, r_base.GetReg());
} else {
- store = res = NewLIR3(opcode, r_src, displacement + LOWORD_OFFSET,
- rBase);
- store2 = NewLIR3(opcode, r_src_hi, displacement + HIWORD_OFFSET,
- rBase);
+ store = res = NewLIR3(opcode, r_src.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg());
+ store2 = NewLIR3(opcode, r_src_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg());
}
} else {
- int r_scratch = AllocTemp();
- res = OpRegRegImm(kOpAdd, r_scratch, rBase, displacement);
+ RegStorage r_scratch = AllocTemp();
+ res = OpRegRegImm(kOpAdd, r_scratch, r_base, displacement);
if (!pair) {
- store = NewLIR3(opcode, r_src, 0, r_scratch);
+ store = NewLIR3(opcode, r_src.GetReg(), 0, r_scratch.GetReg());
} else {
- store = NewLIR3(opcode, r_src, LOWORD_OFFSET, r_scratch);
- store2 = NewLIR3(opcode, r_src_hi, HIWORD_OFFSET, r_scratch);
+ store = NewLIR3(opcode, r_src.GetReg(), LOWORD_OFFSET, r_scratch.GetReg());
+ store2 = NewLIR3(opcode, r_src_hi.GetReg(), HIWORD_OFFSET, r_scratch.GetReg());
}
FreeTemp(r_scratch);
}
- if (rBase == rMIPS_SP) {
+ if (r_base == rs_rMIPS_SP) {
AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
false /* is_load */, pair /* is64bit */);
if (pair) {
@@ -637,14 +633,13 @@
return res;
}
-LIR* MipsMir2Lir::StoreBaseDisp(int rBase, int displacement, int r_src,
+LIR* MipsMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
OpSize size) {
- return StoreBaseDispBody(rBase, displacement, r_src, -1, size);
+ return StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size);
}
-LIR* MipsMir2Lir::StoreBaseDispWide(int rBase, int displacement,
- int r_src_lo, int r_src_hi) {
- return StoreBaseDispBody(rBase, displacement, r_src_lo, r_src_hi, kLong);
+LIR* MipsMir2Lir::StoreBaseDispWide(RegStorage r_base, int displacement, RegStorage r_src) {
+ return StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), kLong);
}
LIR* MipsMir2Lir::OpThreadMem(OpKind op, ThreadOffset thread_offset) {
@@ -652,25 +647,26 @@
return NULL;
}
-LIR* MipsMir2Lir::OpMem(OpKind op, int rBase, int disp) {
+LIR* MipsMir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
LOG(FATAL) << "Unexpected use of OpMem for MIPS";
return NULL;
}
-LIR* MipsMir2Lir::StoreBaseIndexedDisp(int rBase, int r_index, int scale, int displacement,
- int r_src, int r_src_hi, OpSize size, int s_reg) {
+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) {
LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for MIPS";
return NULL;
}
-LIR* MipsMir2Lir::OpRegMem(OpKind op, int r_dest, int rBase,
- int offset) {
+LIR* MipsMir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) {
LOG(FATAL) << "Unexpected use of OpRegMem for MIPS";
return NULL;
}
-LIR* MipsMir2Lir::LoadBaseIndexedDisp(int rBase, int r_index, int scale, int displacement,
- int r_dest, int r_dest_hi, OpSize size, int s_reg) {
+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) {
LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for MIPS";
return NULL;
}