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/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc
index 3cb6fd0..3c49756 100644
--- a/compiler/dex/quick/ralloc_util.cc
+++ b/compiler/dex/quick/ralloc_util.cc
@@ -81,6 +81,15 @@
DumpRegPool(reg_pool_->FPRegs, reg_pool_->num_fp_regs);
}
+void Mir2Lir::Clobber(RegStorage reg) {
+ if (reg.IsPair()) {
+ ClobberBody(GetRegInfo(reg.GetLowReg()));
+ ClobberBody(GetRegInfo(reg.GetHighReg()));
+ } else {
+ ClobberBody(GetRegInfo(reg.GetReg()));
+ }
+}
+
void Mir2Lir::ClobberSRegBody(RegisterInfo* p, int num_regs, int s_reg) {
for (int i = 0; i< num_regs; i++) {
if (p[i].s_reg == s_reg) {
@@ -144,25 +153,26 @@
}
}
-void Mir2Lir::RecordCorePromotion(int reg, int s_reg) {
+void Mir2Lir::RecordCorePromotion(RegStorage reg, int s_reg) {
int p_map_idx = SRegToPMap(s_reg);
int v_reg = mir_graph_->SRegToVReg(s_reg);
- GetRegInfo(reg)->in_use = true;
- core_spill_mask_ |= (1 << reg);
+ int reg_num = reg.GetReg();
+ GetRegInfo(reg_num)->in_use = true;
+ core_spill_mask_ |= (1 << reg_num);
// Include reg for later sort
- core_vmap_table_.push_back(reg << VREG_NUM_WIDTH | (v_reg & ((1 << VREG_NUM_WIDTH) - 1)));
+ core_vmap_table_.push_back(reg_num << VREG_NUM_WIDTH | (v_reg & ((1 << VREG_NUM_WIDTH) - 1)));
num_core_spills_++;
promotion_map_[p_map_idx].core_location = kLocPhysReg;
- promotion_map_[p_map_idx].core_reg = reg;
+ promotion_map_[p_map_idx].core_reg = reg_num;
}
/* Reserve a callee-save register. Return -1 if none available */
-int Mir2Lir::AllocPreservedCoreReg(int s_reg) {
- int res = -1;
+RegStorage Mir2Lir::AllocPreservedCoreReg(int s_reg) {
+ RegStorage res;
RegisterInfo* core_regs = reg_pool_->core_regs;
for (int i = 0; i < reg_pool_->num_core_regs; i++) {
if (!core_regs[i].is_temp && !core_regs[i].in_use) {
- res = core_regs[i].reg;
+ res = RegStorage::Solo32(core_regs[i].reg);
RecordCorePromotion(res, s_reg);
break;
}
@@ -170,22 +180,23 @@
return res;
}
-void Mir2Lir::RecordFpPromotion(int reg, int s_reg) {
+void Mir2Lir::RecordFpPromotion(RegStorage reg, int s_reg) {
int p_map_idx = SRegToPMap(s_reg);
int v_reg = mir_graph_->SRegToVReg(s_reg);
- GetRegInfo(reg)->in_use = true;
- MarkPreservedSingle(v_reg, reg);
+ int reg_num = reg.GetReg();
+ GetRegInfo(reg_num)->in_use = true;
+ MarkPreservedSingle(v_reg, reg_num);
promotion_map_[p_map_idx].fp_location = kLocPhysReg;
- promotion_map_[p_map_idx].FpReg = reg;
+ promotion_map_[p_map_idx].FpReg = reg_num;
}
// Reserve a callee-save fp single register.
-int Mir2Lir::AllocPreservedSingle(int s_reg) {
- int res = -1; // Return code if none available.
+RegStorage Mir2Lir::AllocPreservedSingle(int s_reg) {
+ RegStorage res;
RegisterInfo* FPRegs = reg_pool_->FPRegs;
for (int i = 0; i < reg_pool_->num_fp_regs; i++) {
if (!FPRegs[i].is_temp && !FPRegs[i].in_use) {
- res = FPRegs[i].reg;
+ res = RegStorage::Solo32(FPRegs[i].reg);
RecordFpPromotion(res, s_reg);
break;
}
@@ -201,8 +212,9 @@
* allocate if we can't meet the requirements for the pair of
* s_reg<=sX[even] & (s_reg+1)<= sX+1.
*/
-int Mir2Lir::AllocPreservedDouble(int s_reg) {
- int res = -1; // Assume failure
+// TODO: needs rewrite to support non-backed 64-bit float regs.
+RegStorage Mir2Lir::AllocPreservedDouble(int s_reg) {
+ RegStorage res;
int v_reg = mir_graph_->SRegToVReg(s_reg);
int p_map_idx = SRegToPMap(s_reg);
if (promotion_map_[p_map_idx+1].fp_location == kLocPhysReg) {
@@ -210,19 +222,19 @@
int high_reg = promotion_map_[p_map_idx+1].FpReg;
if ((high_reg & 1) == 0) {
// High reg is even - fail.
- return res;
+ return res; // Invalid.
}
// Is the low reg of the pair free?
RegisterInfo* p = GetRegInfo(high_reg-1);
if (p->in_use || p->is_temp) {
// Already allocated or not preserved - fail.
- return res;
+ return res; // Invalid.
}
// OK - good to go.
- res = p->reg;
+ res = RegStorage(RegStorage::k64BitPair, p->reg, p->reg + 1);
p->in_use = true;
- DCHECK_EQ((res & 1), 0);
- MarkPreservedSingle(v_reg, res);
+ DCHECK_EQ((res.GetReg() & 1), 0);
+ MarkPreservedSingle(v_reg, res.GetReg());
} else {
RegisterInfo* FPRegs = reg_pool_->FPRegs;
for (int i = 0; i < reg_pool_->num_fp_regs; i++) {
@@ -231,27 +243,27 @@
!FPRegs[i+1].is_temp && !FPRegs[i+1].in_use &&
((FPRegs[i+1].reg & 0x1) == 0x1) &&
(FPRegs[i].reg + 1) == FPRegs[i+1].reg) {
- res = FPRegs[i].reg;
+ res = RegStorage(RegStorage::k64BitPair, FPRegs[i].reg, FPRegs[i].reg+1);
FPRegs[i].in_use = true;
- MarkPreservedSingle(v_reg, res);
+ MarkPreservedSingle(v_reg, res.GetLowReg());
FPRegs[i+1].in_use = true;
- DCHECK_EQ(res + 1, FPRegs[i+1].reg);
- MarkPreservedSingle(v_reg+1, res+1);
+ DCHECK_EQ(res.GetLowReg() + 1, FPRegs[i+1].reg);
+ MarkPreservedSingle(v_reg+1, res.GetLowReg() + 1);
break;
}
}
}
- if (res != -1) {
+ if (res.Valid()) {
promotion_map_[p_map_idx].fp_location = kLocPhysReg;
- promotion_map_[p_map_idx].FpReg = res;
+ promotion_map_[p_map_idx].FpReg = res.GetLowReg();
promotion_map_[p_map_idx+1].fp_location = kLocPhysReg;
- promotion_map_[p_map_idx+1].FpReg = res + 1;
+ promotion_map_[p_map_idx+1].FpReg = res.GetLowReg() + 1;
}
return res;
}
-int Mir2Lir::AllocTempBody(RegisterInfo* p, int num_regs, int* next_temp,
- bool required) {
+RegStorage Mir2Lir::AllocTempBody(RegisterInfo* p, int num_regs, int* next_temp,
+ bool required) {
int next = *next_temp;
for (int i = 0; i< num_regs; i++) {
if (next >= num_regs)
@@ -261,7 +273,7 @@
p[next].in_use = true;
p[next].pair = false;
*next_temp = next + 1;
- return p[next].reg;
+ return RegStorage::Solo32(p[next].reg);
}
next++;
}
@@ -274,7 +286,7 @@
p[next].in_use = true;
p[next].pair = false;
*next_temp = next + 1;
- return p[next].reg;
+ return RegStorage::Solo32(p[next].reg);
}
next++;
}
@@ -284,11 +296,12 @@
reg_pool_->num_core_regs);
LOG(FATAL) << "No free temp registers";
}
- return -1; // No register available
+ return RegStorage::InvalidReg(); // No register available
}
// REDO: too many assumptions.
-int Mir2Lir::AllocTempDouble() {
+// Virtualize - this is target dependent.
+RegStorage Mir2Lir::AllocTempDouble() {
RegisterInfo* p = reg_pool_->FPRegs;
int num_regs = reg_pool_->num_fp_regs;
/* Start looking at an even reg */
@@ -310,7 +323,8 @@
if (reg_pool_->next_fp_reg >= num_regs) {
reg_pool_->next_fp_reg = 0;
}
- return p[next].reg;
+ // FIXME: should return k64BitSolo.
+ return RegStorage(RegStorage::k64BitPair, p[next].reg, p[next+1].reg);
}
next += 2;
}
@@ -332,28 +346,28 @@
if (reg_pool_->next_fp_reg >= num_regs) {
reg_pool_->next_fp_reg = 0;
}
- return p[next].reg;
+ return RegStorage(RegStorage::k64BitPair, p[next].reg, p[next+1].reg);
}
next += 2;
}
LOG(FATAL) << "No free temp registers (pair)";
- return -1;
+ return RegStorage::InvalidReg();
}
/* Return a temp if one is available, -1 otherwise */
-int Mir2Lir::AllocFreeTemp() {
+RegStorage Mir2Lir::AllocFreeTemp() {
return AllocTempBody(reg_pool_->core_regs,
reg_pool_->num_core_regs,
®_pool_->next_core_reg, false);
}
-int Mir2Lir::AllocTemp() {
+RegStorage Mir2Lir::AllocTemp() {
return AllocTempBody(reg_pool_->core_regs,
reg_pool_->num_core_regs,
®_pool_->next_core_reg, true);
}
-int Mir2Lir::AllocTempFloat() {
+RegStorage Mir2Lir::AllocTempFloat() {
return AllocTempBody(reg_pool_->FPRegs,
reg_pool_->num_fp_regs,
®_pool_->next_fp_reg, true);
@@ -403,26 +417,71 @@
p->pair = false;
}
+void Mir2Lir::FreeTemp(RegStorage reg) {
+ if (reg.IsPair()) {
+ FreeTemp(reg.GetLowReg());
+ FreeTemp(reg.GetHighReg());
+ } else {
+ FreeTemp(reg.GetReg());
+ }
+}
+
Mir2Lir::RegisterInfo* Mir2Lir::IsLive(int reg) {
RegisterInfo* p = GetRegInfo(reg);
return p->live ? p : NULL;
}
+Mir2Lir::RegisterInfo* Mir2Lir::IsLive(RegStorage reg) {
+ if (reg.IsPair()) {
+ DCHECK_EQ(IsLive(reg.GetLowReg()) == nullptr, IsLive(reg.GetHighReg()) == nullptr);
+ return IsLive(reg.GetLowReg());
+ } else {
+ return IsLive(reg.GetReg());
+ }
+}
+
Mir2Lir::RegisterInfo* Mir2Lir::IsTemp(int reg) {
RegisterInfo* p = GetRegInfo(reg);
return (p->is_temp) ? p : NULL;
}
+Mir2Lir::RegisterInfo* Mir2Lir::IsTemp(RegStorage reg) {
+ if (reg.IsPair()) {
+ DCHECK_EQ(IsTemp(reg.GetLowReg()) == nullptr, IsTemp(reg.GetHighReg()) == nullptr);
+ return IsTemp(reg.GetLowReg());
+ } else {
+ return IsTemp(reg.GetReg());
+ }
+}
+
Mir2Lir::RegisterInfo* Mir2Lir::IsPromoted(int reg) {
RegisterInfo* p = GetRegInfo(reg);
return (p->is_temp) ? NULL : p;
}
+Mir2Lir::RegisterInfo* Mir2Lir::IsPromoted(RegStorage reg) {
+ if (reg.IsPair()) {
+ DCHECK_EQ(IsPromoted(reg.GetLowReg()) == nullptr, IsPromoted(reg.GetHighReg()) == nullptr);
+ return IsPromoted(reg.GetLowReg());
+ } else {
+ return IsPromoted(reg.GetReg());
+ }
+}
+
bool Mir2Lir::IsDirty(int reg) {
RegisterInfo* p = GetRegInfo(reg);
return p->dirty;
}
+bool Mir2Lir::IsDirty(RegStorage reg) {
+ if (reg.IsPair()) {
+ DCHECK_EQ(IsDirty(reg.GetLowReg()), IsDirty(reg.GetHighReg()));
+ return IsDirty(reg.GetLowReg());
+ } else {
+ return IsDirty(reg.GetReg());
+ }
+}
+
/*
* Similar to AllocTemp(), but forces the allocation of a specific
* register. No check is made to see if the register was previously
@@ -435,10 +494,20 @@
p->live = false;
}
+void Mir2Lir::LockTemp(RegStorage reg) {
+ DCHECK(!reg.IsPair());
+ LockTemp(reg.GetReg());
+}
+
void Mir2Lir::ResetDef(int reg) {
ResetDefBody(GetRegInfo(reg));
}
+void Mir2Lir::ResetDef(RegStorage reg) {
+ DCHECK(!reg.IsPair()); // Is this done? If so, do on both low and high.
+ ResetDef(reg.GetReg());
+}
+
void Mir2Lir::NullifyRange(LIR *start, LIR *finish, int s_reg1, int s_reg2) {
if (start && finish) {
LIR *p;
@@ -474,7 +543,7 @@
DCHECK(rl.wide);
DCHECK(start && start->next);
DCHECK(finish);
- RegisterInfo* p = GetRegInfo(rl.reg.GetReg());
+ RegisterInfo* p = GetRegInfo(rl.reg.GetLowReg());
ResetDef(rl.reg.GetHighReg()); // Only track low of pair
p->def_start = start->next;
p->def_end = finish;
@@ -483,7 +552,7 @@
RegLocation Mir2Lir::WideToNarrow(RegLocation rl) {
DCHECK(rl.wide);
if (rl.location == kLocPhysReg) {
- RegisterInfo* info_lo = GetRegInfo(rl.reg.GetReg());
+ RegisterInfo* info_lo = GetRegInfo(rl.reg.GetLowReg());
RegisterInfo* info_hi = GetRegInfo(rl.reg.GetHighReg());
if (info_lo->is_temp) {
info_lo->pair = false;
@@ -495,6 +564,7 @@
info_hi->def_start = NULL;
info_hi->def_end = NULL;
}
+ rl.reg = RegStorage::Solo32(rl.reg.GetLowReg());
}
rl.wide = false;
return rl;
@@ -512,7 +582,7 @@
void Mir2Lir::ResetDefLocWide(RegLocation rl) {
DCHECK(rl.wide);
- RegisterInfo* p_low = IsTemp(rl.reg.GetReg());
+ RegisterInfo* p_low = IsTemp(rl.reg.GetLowReg());
RegisterInfo* p_high = IsTemp(rl.reg.GetHighReg());
if (p_low && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_low->pair);
@@ -521,7 +591,7 @@
if (p_high && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_high->pair);
}
- ResetDef(rl.reg.GetReg());
+ ResetDef(rl.reg.GetLowReg());
ResetDef(rl.reg.GetHighReg());
}
@@ -547,9 +617,9 @@
void Mir2Lir::FlushSpecificReg(RegisterInfo* info) {
if (info->pair) {
- FlushRegWide(info->reg, info->partner);
+ FlushRegWide(RegStorage(RegStorage::k64BitPair, info->reg, info->partner));
} else {
- FlushReg(info->reg);
+ FlushReg(RegStorage::Solo32(info->reg));
}
}
@@ -572,19 +642,21 @@
// TUNING: rewrite all of this reg stuff. Probably use an attribute table
-bool Mir2Lir::RegClassMatches(int reg_class, int reg) {
+bool Mir2Lir::RegClassMatches(int reg_class, RegStorage reg) {
+ int reg_num = reg.IsPair() ? reg.GetLowReg() : reg.GetReg();
if (reg_class == kAnyReg) {
return true;
} else if (reg_class == kCoreReg) {
- return !IsFpReg(reg);
+ return !IsFpReg(reg_num);
} else {
- return IsFpReg(reg);
+ return IsFpReg(reg_num);
}
}
-void Mir2Lir::MarkLive(int reg, int s_reg) {
- RegisterInfo* info = GetRegInfo(reg);
- if ((info->reg == reg) && (info->s_reg == s_reg) && info->live) {
+void Mir2Lir::MarkLive(RegStorage reg, int s_reg) {
+ DCHECK(!reg.IsPair()); // Could be done - but would that be meaningful?
+ RegisterInfo* info = GetRegInfo(reg.GetReg());
+ if ((info->s_reg == s_reg) && info->live) {
return; /* already live */
} else if (s_reg != INVALID_SREG) {
ClobberSReg(s_reg);
@@ -605,12 +677,22 @@
info->is_temp = true;
}
+void Mir2Lir::MarkTemp(RegStorage reg) {
+ DCHECK(!reg.IsPair());
+ MarkTemp(reg.GetReg());
+}
+
void Mir2Lir::UnmarkTemp(int reg) {
RegisterInfo* info = GetRegInfo(reg);
tempreg_info_.Delete(info);
info->is_temp = false;
}
+void Mir2Lir::UnmarkTemp(RegStorage reg) {
+ DCHECK(!reg.IsPair());
+ UnmarkTemp(reg.GetReg());
+}
+
void Mir2Lir::MarkPair(int low_reg, int high_reg) {
DCHECK_NE(low_reg, high_reg);
RegisterInfo* info_lo = GetRegInfo(low_reg);
@@ -621,11 +703,14 @@
}
void Mir2Lir::MarkClean(RegLocation loc) {
- RegisterInfo* info = GetRegInfo(loc.reg.GetReg());
- info->dirty = false;
if (loc.wide) {
+ RegisterInfo* info = GetRegInfo(loc.reg.GetLowReg());
+ info->dirty = false;
info = GetRegInfo(loc.reg.GetHighReg());
info->dirty = false;
+ } else {
+ RegisterInfo* info = GetRegInfo(loc.reg.GetReg());
+ info->dirty = false;
}
}
@@ -634,11 +719,14 @@
// If already home, can't be dirty
return;
}
- RegisterInfo* info = GetRegInfo(loc.reg.GetReg());
- info->dirty = true;
if (loc.wide) {
+ RegisterInfo* info = GetRegInfo(loc.reg.GetLowReg());
+ info->dirty = true;
info = GetRegInfo(loc.reg.GetHighReg());
info->dirty = true;
+ } else {
+ RegisterInfo* info = GetRegInfo(loc.reg.GetReg());
+ info->dirty = true;
}
}
@@ -647,6 +735,15 @@
info->in_use = true;
}
+void Mir2Lir::MarkInUse(RegStorage reg) {
+ if (reg.IsPair()) {
+ MarkInUse(reg.GetLowReg());
+ MarkInUse(reg.GetHighReg());
+ } else {
+ MarkInUse(reg.GetReg());
+ }
+}
+
void Mir2Lir::CopyRegInfo(int new_reg, int old_reg) {
RegisterInfo* new_info = GetRegInfo(new_reg);
RegisterInfo* old_info = GetRegInfo(old_reg);
@@ -658,6 +755,12 @@
new_info->reg = new_reg;
}
+void Mir2Lir::CopyRegInfo(RegStorage new_reg, RegStorage old_reg) {
+ DCHECK(!new_reg.IsPair());
+ DCHECK(!old_reg.IsPair());
+ CopyRegInfo(new_reg.GetReg(), old_reg.GetReg());
+}
+
bool Mir2Lir::CheckCorePoolSanity() {
for (static int i = 0; i < reg_pool_->num_core_regs; i++) {
if (reg_pool_->core_regs[i].pair) {
@@ -707,12 +810,11 @@
Clobber(info_lo->partner);
FreeTemp(info_lo->reg);
} else {
- loc.reg = RegStorage(RegStorage::k32BitSolo, info_lo->reg);
+ loc.reg = RegStorage::Solo32(info_lo->reg);
loc.location = kLocPhysReg;
}
}
}
-
return loc;
}
@@ -746,8 +848,8 @@
// Can reuse - update the register usage info
loc.location = kLocPhysReg;
loc.reg = RegStorage(RegStorage::k64BitPair, info_lo->reg, info_hi->reg);
- MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
- DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
+ MarkPair(loc.reg.GetLowReg(), loc.reg.GetHighReg());
+ DCHECK(!IsFpReg(loc.reg.GetLowReg()) || ((loc.reg.GetLowReg() & 0x1) == 0));
return loc;
}
// Can't easily reuse - clobber and free any overlaps
@@ -778,28 +880,23 @@
RegLocation Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update) {
DCHECK(loc.wide);
- int32_t low_reg;
- int32_t high_reg;
loc = UpdateLocWide(loc);
/* If already in registers, we can assume proper form. Right reg class? */
if (loc.location == kLocPhysReg) {
- DCHECK_EQ(IsFpReg(loc.reg.GetReg()), IsFpReg(loc.reg.GetHighReg()));
- DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
- if (!RegClassMatches(reg_class, loc.reg.GetReg())) {
+ DCHECK_EQ(IsFpReg(loc.reg.GetLowReg()), IsFpReg(loc.reg.GetHighReg()));
+ DCHECK(!IsFpReg(loc.reg.GetLowReg()) || ((loc.reg.GetLowReg() & 0x1) == 0));
+ if (!RegClassMatches(reg_class, loc.reg)) {
/* Wrong register class. Reallocate and copy */
RegStorage new_regs = AllocTypedTempWide(loc.fp, reg_class);
- low_reg = new_regs.GetReg();
- high_reg = new_regs.GetHighReg();
- OpRegCopyWide(low_reg, high_reg, loc.reg.GetReg(), loc.reg.GetHighReg());
- CopyRegInfo(low_reg, loc.reg.GetReg());
- CopyRegInfo(high_reg, loc.reg.GetHighReg());
- Clobber(loc.reg.GetReg());
- Clobber(loc.reg.GetHighReg());
+ OpRegCopyWide(new_regs, loc.reg);
+ CopyRegInfo(new_regs.GetLowReg(), loc.reg.GetLowReg());
+ CopyRegInfo(new_regs.GetHighReg(), loc.reg.GetHighReg());
+ Clobber(loc.reg);
loc.reg = new_regs;
- MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
- DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
+ MarkPair(loc.reg.GetLowReg(), loc.reg.GetHighReg());
+ DCHECK(!IsFpReg(loc.reg.GetLowReg()) || ((loc.reg.GetLowReg() & 0x1) == 0));
}
return loc;
}
@@ -809,47 +906,44 @@
loc.reg = AllocTypedTempWide(loc.fp, reg_class);
- MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
+ MarkPair(loc.reg.GetLowReg(), loc.reg.GetHighReg());
if (update) {
loc.location = kLocPhysReg;
- MarkLive(loc.reg.GetReg(), loc.s_reg_low);
+ MarkLive(loc.reg.GetLow(), loc.s_reg_low);
// Does this wide value live in two registers or one vector register?
- if (loc.reg.GetReg() != loc.reg.GetHighReg()) {
- MarkLive(loc.reg.GetHighReg(), GetSRegHi(loc.s_reg_low));
+ if (loc.reg.GetLowReg() != loc.reg.GetHighReg()) {
+ MarkLive(loc.reg.GetHigh(), GetSRegHi(loc.s_reg_low));
}
}
- DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
+ DCHECK(!IsFpReg(loc.reg.GetLowReg()) || ((loc.reg.GetLowReg() & 0x1) == 0));
return loc;
}
RegLocation Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update) {
- int new_reg;
-
if (loc.wide)
return EvalLocWide(loc, reg_class, update);
loc = UpdateLoc(loc);
if (loc.location == kLocPhysReg) {
- if (!RegClassMatches(reg_class, loc.reg.GetReg())) {
+ if (!RegClassMatches(reg_class, loc.reg)) {
/* Wrong register class. Realloc, copy and transfer ownership */
- new_reg = AllocTypedTemp(loc.fp, reg_class);
- OpRegCopy(new_reg, loc.reg.GetReg());
- CopyRegInfo(new_reg, loc.reg.GetReg());
- Clobber(loc.reg.GetReg());
- loc.reg = RegStorage(RegStorage::k32BitSolo, new_reg);
+ RegStorage new_reg = AllocTypedTemp(loc.fp, reg_class);
+ OpRegCopy(new_reg, loc.reg);
+ CopyRegInfo(new_reg, loc.reg);
+ Clobber(loc.reg);
+ loc.reg = new_reg;
}
return loc;
}
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
- new_reg = AllocTypedTemp(loc.fp, reg_class);
- loc.reg = RegStorage(RegStorage::k32BitSolo, new_reg);
+ loc.reg = AllocTypedTemp(loc.fp, reg_class);
if (update) {
loc.location = kLocPhysReg;
- MarkLive(loc.reg.GetReg(), loc.s_reg_low);
+ MarkLive(loc.reg, loc.s_reg_low);
}
return loc;
}
@@ -972,8 +1066,8 @@
AllocPreservedDouble(low_sreg);
}
} else if (promotion_map_[p_map_idx].fp_location != kLocPhysReg) {
- int reg = AllocPreservedSingle(FpRegs[i].s_reg);
- if (reg < 0) {
+ RegStorage reg = AllocPreservedSingle(FpRegs[i].s_reg);
+ if (!reg.Valid()) {
break; // No more left.
}
}
@@ -985,8 +1079,8 @@
int p_map_idx = SRegToPMap(core_regs[i].s_reg);
if (promotion_map_[p_map_idx].core_location !=
kLocPhysReg) {
- int reg = AllocPreservedCoreReg(core_regs[i].s_reg);
- if (reg < 0) {
+ RegStorage reg = AllocPreservedCoreReg(core_regs[i].s_reg);
+ if (!reg.Valid()) {
break; // No more left
}
}
@@ -1001,13 +1095,13 @@
if (curr->fp) {
if (promotion_map_[p_map_idx].fp_location == kLocPhysReg) {
curr->location = kLocPhysReg;
- curr->reg = RegStorage(RegStorage::k32BitSolo, promotion_map_[p_map_idx].FpReg);
+ curr->reg = RegStorage::Solo32(promotion_map_[p_map_idx].FpReg);
curr->home = true;
}
} else {
if (promotion_map_[p_map_idx].core_location == kLocPhysReg) {
curr->location = kLocPhysReg;
- curr->reg = RegStorage(RegStorage::k32BitSolo, promotion_map_[p_map_idx].core_reg);
+ curr->reg = RegStorage::Solo32(promotion_map_[p_map_idx].core_reg);
curr->home = true;
}
}
@@ -1060,13 +1154,13 @@
RegLocation gpr_res = LocCReturnWide();
RegLocation fpr_res = LocCReturnDouble();
RegLocation res = is_double ? fpr_res : gpr_res;
- Clobber(res.reg.GetReg());
+ Clobber(res.reg.GetLowReg());
Clobber(res.reg.GetHighReg());
- LockTemp(res.reg.GetReg());
+ LockTemp(res.reg.GetLowReg());
LockTemp(res.reg.GetHighReg());
// Does this wide value live in two registers or one vector register?
- if (res.reg.GetReg() != res.reg.GetHighReg()) {
- MarkPair(res.reg.GetReg(), res.reg.GetHighReg());
+ if (res.reg.GetLowReg() != res.reg.GetHighReg()) {
+ MarkPair(res.reg.GetLowReg(), res.reg.GetHighReg());
}
return res;
}