summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/mir_graph.h10
-rw-r--r--compiler/dex/mir_optimization.cc7
-rw-r--r--compiler/dex/quick/arm/arm_lir.h22
-rw-r--r--compiler/dex/quick/arm/call_arm.cc8
-rw-r--r--compiler/dex/quick/arm/codegen_arm.h2
-rw-r--r--compiler/dex/quick/arm/fp_arm.cc60
-rw-r--r--compiler/dex/quick/arm/int_arm.cc309
-rw-r--r--compiler/dex/quick/arm/target_arm.cc39
-rw-r--r--compiler/dex/quick/gen_common.cc204
-rw-r--r--compiler/dex/quick/gen_invoke.cc136
-rw-r--r--compiler/dex/quick/gen_loadstore.cc142
-rw-r--r--compiler/dex/quick/mips/call_mips.cc10
-rw-r--r--compiler/dex/quick/mips/codegen_mips.h2
-rw-r--r--compiler/dex/quick/mips/fp_mips.cc20
-rw-r--r--compiler/dex/quick/mips/int_mips.cc104
-rw-r--r--compiler/dex/quick/mips/mips_lir.h24
-rw-r--r--compiler/dex/quick/mips/target_mips.cc35
-rw-r--r--compiler/dex/quick/mir_to_lir.cc42
-rw-r--r--compiler/dex/quick/mir_to_lir.h3
-rw-r--r--compiler/dex/quick/ralloc_util.cc130
-rw-r--r--compiler/dex/quick/x86/call_x86.cc10
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h3
-rw-r--r--compiler/dex/quick/x86/fp_x86.cc84
-rw-r--r--compiler/dex/quick/x86/int_x86.cc330
-rw-r--r--compiler/dex/quick/x86/target_x86.cc167
-rw-r--r--compiler/dex/quick/x86/utility_x86.cc4
-rw-r--r--compiler/dex/quick/x86/x86_lir.h23
-rw-r--r--compiler/dex/reg_storage.h158
-rw-r--r--compiler/dex/vreg_analysis.cc14
29 files changed, 1122 insertions, 980 deletions
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 2174f679bf..ee602b0290 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -22,6 +22,7 @@
#include "compiler_ir.h"
#include "arena_bit_vector.h"
#include "utils/growable_array.h"
+#include "reg_storage.h"
namespace art {
@@ -165,7 +166,7 @@ enum OatMethodAttributes {
#define INVALID_SREG (-1)
#define INVALID_VREG (0xFFFFU)
-#define INVALID_REG (0xFF)
+#define INVALID_REG (0x7F)
#define INVALID_OFFSET (0xDEADF00FU)
#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
@@ -328,9 +329,8 @@ struct RegLocation {
unsigned ref:1; // Something GC cares about.
unsigned high_word:1; // High word of pair?
unsigned home:1; // Does this represent the home location?
- VectorLengthType vec_len:3; // Is this value in a vector register, and how big is it?
- uint8_t low_reg; // First physical register.
- uint8_t high_reg; // 2nd physical register (if wide).
+ VectorLengthType vec_len:3; // TODO: remove. Is this value in a vector register, and how big is it?
+ RegStorage reg; // Encoded physical registers.
int16_t s_reg_low; // SSA name for low Dalvik word.
int16_t orig_sreg; // TODO: remove after Bitcode gen complete
// and consolidate usage w/ s_reg_low.
@@ -361,7 +361,7 @@ struct CallInfo {
const RegLocation bad_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, kVectorNotUsed,
- INVALID_REG, INVALID_REG, INVALID_SREG, INVALID_SREG};
+ RegStorage(RegStorage::kInvalid), INVALID_SREG, INVALID_SREG};
class MIRGraph {
public:
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 67d476929e..14d03a518c 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -207,10 +207,11 @@ size_t MIRGraph::GetNumAvailableNonSpecialCompilerTemps() {
}
}
+
+// FIXME - will probably need to revisit all uses of this, as type not defined.
static const RegLocation temp_loc = {kLocCompilerTemp,
- 0, 1 /*defined*/, 0, 0, 0, 0, 0, 1 /*home*/,
- kVectorNotUsed, INVALID_REG, INVALID_REG, INVALID_SREG,
- INVALID_SREG};
+ 0, 1 /*defined*/, 0, 0, 0, 0, 0, 1 /*home*/, kVectorNotUsed,
+ RegStorage(), INVALID_SREG, INVALID_SREG};
CompilerTemp* MIRGraph::GetNewCompilerTemp(CompilerTempType ct_type, bool wide) {
// There is a limit to the number of non-special temps so check to make sure it wasn't exceeded.
diff --git a/compiler/dex/quick/arm/arm_lir.h b/compiler/dex/quick/arm/arm_lir.h
index 37b4ec6dc7..bb0335234c 100644
--- a/compiler/dex/quick/arm/arm_lir.h
+++ b/compiler/dex/quick/arm/arm_lir.h
@@ -117,14 +117,6 @@ namespace art {
// Mask to strip off fp flags.
#define ARM_FP_REG_MASK (ARM_FP_REG_OFFSET-1)
-// RegisterLocation templates return values (r0, or r0/r1).
-#define ARM_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r0, INVALID_REG, \
- INVALID_SREG, INVALID_SREG}
-#define ARM_LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r0, r1, \
- INVALID_SREG, INVALID_SREG}
-#define ARM_LOC_C_RETURN_FLOAT ARM_LOC_C_RETURN
-#define ARM_LOC_C_RETURN_DOUBLE ARM_LOC_C_RETURN_WIDE
-
enum ArmResourceEncodingPos {
kArmGPReg0 = 0,
kArmRegSP = 13,
@@ -225,6 +217,20 @@ enum ArmNativeRegisterPool {
#define rARM_INVOKE_TGT rARM_LR
#define rARM_COUNT INVALID_REG
+// RegisterLocation templates return values (r0, or r0/r1).
+const RegLocation arm_loc_c_return
+ {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k32BitSolo, r0), INVALID_SREG, INVALID_SREG};
+const RegLocation arm_loc_c_return_wide
+ {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k64BitPair, r0, r1), INVALID_SREG, INVALID_SREG};
+const RegLocation arm_loc_c_return_float
+ {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k32BitSolo, r0), INVALID_SREG, INVALID_SREG};
+const RegLocation arm_loc_c_return_double
+ {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k64BitPair, r0, r1), INVALID_SREG, INVALID_SREG};
+
enum ArmShiftEncodings {
kArmLsl = 0x0,
kArmLsr = 0x1,
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc
index b36dde98b2..264bdedf86 100644
--- a/compiler/dex/quick/arm/call_arm.cc
+++ b/compiler/dex/quick/arm/call_arm.cc
@@ -79,7 +79,7 @@ void ArmMir2Lir::GenSparseSwitch(MIR* mir, uint32_t table_offset,
LIR* target = NewLIR0(kPseudoTargetLabel);
// Load next key/disp
NewLIR2(kThumb2LdmiaWB, rBase, (1 << r_key) | (1 << r_disp));
- OpRegReg(kOpCmp, r_key, rl_src.low_reg);
+ OpRegReg(kOpCmp, r_key, rl_src.reg.GetReg());
// Go if match. NOTE: No instruction set switch here - must stay Thumb2
OpIT(kCondEq, "");
LIR* switch_branch = NewLIR1(kThumb2AddPCR, r_disp);
@@ -115,10 +115,10 @@ void ArmMir2Lir::GenPackedSwitch(MIR* mir, uint32_t table_offset,
int keyReg;
// Remove the bias, if necessary
if (low_key == 0) {
- keyReg = rl_src.low_reg;
+ keyReg = rl_src.reg.GetReg();
} else {
keyReg = AllocTemp();
- OpRegRegImm(kOpSub, keyReg, rl_src.low_reg, low_key);
+ OpRegRegImm(kOpSub, keyReg, rl_src.reg.GetReg(), low_key);
}
// Bounds check - if < 0 or >= size continue following switch
OpRegImm(kOpCmp, keyReg, size-1);
@@ -293,7 +293,7 @@ void ArmMir2Lir::GenMoveException(RegLocation rl_dest) {
int ex_offset = Thread::ExceptionOffset().Int32Value();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
int reset_reg = AllocTemp();
- LoadWordDisp(rARM_SELF, ex_offset, rl_result.low_reg);
+ LoadWordDisp(rARM_SELF, ex_offset, rl_result.reg.GetReg());
LoadConstant(reset_reg, 0);
StoreWordDisp(rARM_SELF, ex_offset, reset_reg);
FreeTemp(reset_reg);
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index 65dee807a1..2c0cead6ca 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -49,7 +49,7 @@ class ArmMir2Lir : public Mir2Lir {
bool IsFpReg(int reg);
bool SameRegType(int reg1, int reg2);
int AllocTypedTemp(bool fp_hint, int reg_class);
- int AllocTypedTempPair(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);
diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc
index 46542e118c..dd0a429a85 100644
--- a/compiler/dex/quick/arm/fp_arm.cc
+++ b/compiler/dex/quick/arm/fp_arm.cc
@@ -63,7 +63,7 @@ void ArmMir2Lir::GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest,
rl_src1 = LoadValue(rl_src1, kFPReg);
rl_src2 = LoadValue(rl_src2, kFPReg);
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR3(op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
+ NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
@@ -111,8 +111,8 @@ void ArmMir2Lir::GenArithOpDouble(Instruction::Code opcode,
rl_result = EvalLoc(rl_dest, kFPReg, true);
DCHECK(rl_dest.wide);
DCHECK(rl_result.wide);
- NewLIR3(op, S2d(rl_result.low_reg, rl_result.high_reg), S2d(rl_src1.low_reg, rl_src1.high_reg),
- S2d(rl_src2.low_reg, rl_src2.high_reg));
+ 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()));
StoreValueWide(rl_dest, rl_result);
}
@@ -143,16 +143,16 @@ void ArmMir2Lir::GenConversion(Instruction::Code opcode,
break;
case Instruction::LONG_TO_DOUBLE: {
rl_src = LoadValueWide(rl_src, kFPReg);
- src_reg = S2d(rl_src.low_reg, rl_src.high_reg);
+ src_reg = S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
rl_result = EvalLoc(rl_dest, kFPReg, true);
// TODO: clean up AllocTempDouble so that its result has the double bits set.
int tmp1 = AllocTempDouble();
int tmp2 = AllocTempDouble();
NewLIR2(kThumb2VcvtF64S32, tmp1 | ARM_FP_DOUBLE, (src_reg & ~ARM_FP_DOUBLE) + 1);
- NewLIR2(kThumb2VcvtF64U32, S2d(rl_result.low_reg, rl_result.high_reg), (src_reg & ~ARM_FP_DOUBLE));
+ NewLIR2(kThumb2VcvtF64U32, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), (src_reg & ~ARM_FP_DOUBLE));
LoadConstantWide(tmp2, tmp2 + 1, 0x41f0000000000000LL);
- NewLIR3(kThumb2VmlaF64, S2d(rl_result.low_reg, rl_result.high_reg), tmp1 | ARM_FP_DOUBLE,
+ NewLIR3(kThumb2VmlaF64, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), tmp1 | ARM_FP_DOUBLE,
tmp2 | ARM_FP_DOUBLE);
FreeTemp(tmp1);
FreeTemp(tmp2);
@@ -173,18 +173,18 @@ void ArmMir2Lir::GenConversion(Instruction::Code opcode,
}
if (rl_src.wide) {
rl_src = LoadValueWide(rl_src, kFPReg);
- src_reg = S2d(rl_src.low_reg, rl_src.high_reg);
+ src_reg = S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
rl_src = LoadValue(rl_src, kFPReg);
- src_reg = rl_src.low_reg;
+ src_reg = rl_src.reg.GetReg();
}
if (rl_dest.wide) {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg);
+ NewLIR2(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), src_reg);
StoreValueWide(rl_dest, rl_result);
} else {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, rl_result.low_reg, src_reg);
+ NewLIR2(op, rl_result.reg.GetReg(), src_reg);
StoreValue(rl_dest, rl_result);
}
}
@@ -199,14 +199,14 @@ void ArmMir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias,
rl_src2 = mir_graph_->GetSrcWide(mir, 2);
rl_src1 = LoadValueWide(rl_src1, kFPReg);
rl_src2 = LoadValueWide(rl_src2, kFPReg);
- NewLIR2(kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg),
- S2d(rl_src2.low_reg, rl_src2.high_reg));
+ NewLIR2(kThumb2Vcmpd, S2d(rl_src1.reg.GetReg(), rl_src2.reg.GetHighReg()),
+ S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg()));
} else {
rl_src1 = mir_graph_->GetSrc(mir, 0);
rl_src2 = mir_graph_->GetSrc(mir, 1);
rl_src1 = LoadValue(rl_src1, kFPReg);
rl_src2 = LoadValue(rl_src2, kFPReg);
- NewLIR2(kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg);
+ NewLIR2(kThumb2Vcmps, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
}
NewLIR0(kThumb2Fmstat);
ConditionCode ccode = mir->meta.ccode;
@@ -273,28 +273,28 @@ void ArmMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest,
// In case result vreg is also a src vreg, break association to avoid useless copy by EvalLoc()
ClobberSReg(rl_dest.s_reg_low);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- LoadConstant(rl_result.low_reg, default_result);
- NewLIR2(kThumb2Vcmpd, S2d(rl_src1.low_reg, rl_src2.high_reg),
- S2d(rl_src2.low_reg, rl_src2.high_reg));
+ LoadConstant(rl_result.reg.GetReg(), default_result);
+ NewLIR2(kThumb2Vcmpd, S2d(rl_src1.reg.GetReg(), rl_src2.reg.GetHighReg()),
+ S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg()));
} else {
rl_src1 = LoadValue(rl_src1, kFPReg);
rl_src2 = LoadValue(rl_src2, kFPReg);
// In case result vreg is also a srcvreg, break association to avoid useless copy by EvalLoc()
ClobberSReg(rl_dest.s_reg_low);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- LoadConstant(rl_result.low_reg, default_result);
- NewLIR2(kThumb2Vcmps, rl_src1.low_reg, rl_src2.low_reg);
+ LoadConstant(rl_result.reg.GetReg(), default_result);
+ NewLIR2(kThumb2Vcmps, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
}
- DCHECK(!ARM_FPREG(rl_result.low_reg));
+ DCHECK(!ARM_FPREG(rl_result.reg.GetReg()));
NewLIR0(kThumb2Fmstat);
OpIT((default_result == -1) ? kCondGt : kCondMi, "");
- NewLIR2(kThumb2MovI8M, rl_result.low_reg,
+ NewLIR2(kThumb2MovI8M, rl_result.reg.GetReg(),
ModifiedImmediate(-default_result)); // Must not alter ccodes
GenBarrier();
OpIT(kCondEq, "");
- LoadConstant(rl_result.low_reg, 0);
+ LoadConstant(rl_result.reg.GetReg(), 0);
GenBarrier();
StoreValue(rl_dest, rl_result);
@@ -304,7 +304,7 @@ void ArmMir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValue(rl_src, kFPReg);
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(kThumb2Vnegs, rl_result.low_reg, rl_src.low_reg);
+ NewLIR2(kThumb2Vnegs, rl_result.reg.GetReg(), rl_src.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
@@ -312,8 +312,8 @@ void ArmMir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValueWide(rl_src, kFPReg);
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(kThumb2Vnegd, S2d(rl_result.low_reg, rl_result.high_reg),
- S2d(rl_src.low_reg, rl_src.high_reg));
+ NewLIR2(kThumb2Vnegd, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()),
+ S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg()));
StoreValueWide(rl_dest, rl_result);
}
@@ -324,18 +324,18 @@ bool ArmMir2Lir::GenInlinedSqrt(CallInfo* info) {
RegLocation rl_dest = InlineTargetWide(info); // double place for result
rl_src = LoadValueWide(rl_src, kFPReg);
RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(kThumb2Vsqrtd, S2d(rl_result.low_reg, rl_result.high_reg),
- S2d(rl_src.low_reg, rl_src.high_reg));
- NewLIR2(kThumb2Vcmpd, S2d(rl_result.low_reg, rl_result.high_reg),
- S2d(rl_result.low_reg, rl_result.high_reg));
+ NewLIR2(kThumb2Vsqrtd, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()),
+ S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg()));
+ NewLIR2(kThumb2Vcmpd, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()),
+ S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()));
NewLIR0(kThumb2Fmstat);
branch = NewLIR2(kThumbBCond, 0, kArmCondEq);
ClobberCallerSave();
LockCallTemps(); // Using fixed registers
int r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(pSqrt));
- NewLIR3(kThumb2Fmrrd, r0, r1, S2d(rl_src.low_reg, rl_src.high_reg));
+ NewLIR3(kThumb2Fmrrd, r0, r1, S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg()));
NewLIR1(kThumbBlxR, r_tgt);
- NewLIR3(kThumb2Fmdrr, S2d(rl_result.low_reg, rl_result.high_reg), r0, r1);
+ NewLIR3(kThumb2Fmdrr, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), r0, r1);
branch->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
return true;
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 43928fc5e2..7aff89e8b4 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -90,10 +90,10 @@ void ArmMir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1,
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
int t_reg = AllocTemp();
LoadConstant(t_reg, -1);
- OpRegReg(kOpCmp, rl_src1.high_reg, rl_src2.high_reg);
+ OpRegReg(kOpCmp, rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
LIR* branch1 = OpCondBranch(kCondLt, NULL);
LIR* branch2 = OpCondBranch(kCondGt, NULL);
- OpRegRegReg(kOpSub, t_reg, rl_src1.low_reg, rl_src2.low_reg);
+ OpRegRegReg(kOpSub, t_reg, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
LIR* branch3 = OpCondBranch(kCondEq, NULL);
OpIT(kCondHi, "E");
@@ -107,7 +107,7 @@ void ArmMir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1,
target1 = NewLIR0(kPseudoTargetLabel);
RegLocation rl_temp = LocCReturn(); // Just using as template, will change
- rl_temp.low_reg = t_reg;
+ rl_temp.reg.SetReg(t_reg);
StoreValue(rl_dest, rl_temp);
FreeTemp(t_reg);
@@ -125,8 +125,8 @@ void ArmMir2Lir::GenFusedLongCmpImmBranch(BasicBlock* bb, RegLocation rl_src1,
LIR* taken = &block_label_list_[bb->taken];
LIR* not_taken = &block_label_list_[bb->fall_through];
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
- int32_t low_reg = rl_src1.low_reg;
- int32_t high_reg = rl_src1.high_reg;
+ int32_t low_reg = rl_src1.reg.GetReg();
+ int32_t high_reg = rl_src1.reg.GetHighReg();
if (val == 0 && (ccode == kCondEq || ccode == kCondNe)) {
int t_reg = AllocTemp();
@@ -178,15 +178,15 @@ void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
int false_val = mir->dalvikInsn.vC;
rl_result = EvalLoc(rl_dest, kCoreReg, true);
if ((true_val == 1) && (false_val == 0)) {
- OpRegRegImm(kOpRsub, rl_result.low_reg, rl_src.low_reg, 1);
+ OpRegRegImm(kOpRsub, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 1);
OpIT(kCondUlt, "");
- LoadConstant(rl_result.low_reg, 0);
+ LoadConstant(rl_result.reg.GetReg(), 0);
GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact
} else if (InexpensiveConstantInt(true_val) && InexpensiveConstantInt(false_val)) {
- OpRegImm(kOpCmp, rl_src.low_reg, 0);
+ OpRegImm(kOpCmp, rl_src.reg.GetReg(), 0);
OpIT(kCondEq, "E");
- LoadConstant(rl_result.low_reg, true_val);
- LoadConstant(rl_result.low_reg, false_val);
+ LoadConstant(rl_result.reg.GetReg(), true_val);
+ LoadConstant(rl_result.reg.GetReg(), false_val);
GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact
} else {
// Unlikely case - could be tuned.
@@ -194,10 +194,10 @@ void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
int t_reg2 = AllocTemp();
LoadConstant(t_reg1, true_val);
LoadConstant(t_reg2, false_val);
- OpRegImm(kOpCmp, rl_src.low_reg, 0);
+ OpRegImm(kOpCmp, rl_src.reg.GetReg(), 0);
OpIT(kCondEq, "E");
- OpRegCopy(rl_result.low_reg, t_reg1);
- OpRegCopy(rl_result.low_reg, t_reg2);
+ OpRegCopy(rl_result.reg.GetReg(), t_reg1);
+ OpRegCopy(rl_result.reg.GetReg(), t_reg2);
GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact
}
} else {
@@ -207,17 +207,17 @@ void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
rl_true = LoadValue(rl_true, kCoreReg);
rl_false = LoadValue(rl_false, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegImm(kOpCmp, rl_src.low_reg, 0);
- if (rl_result.low_reg == rl_true.low_reg) { // Is the "true" case already in place?
+ OpRegImm(kOpCmp, rl_src.reg.GetReg(), 0);
+ if (rl_result.reg.GetReg() == rl_true.reg.GetReg()) { // Is the "true" case already in place?
OpIT(kCondNe, "");
- OpRegCopy(rl_result.low_reg, rl_false.low_reg);
- } else if (rl_result.low_reg == rl_false.low_reg) { // False case in place?
+ OpRegCopy(rl_result.reg.GetReg(), rl_false.reg.GetReg());
+ } else if (rl_result.reg.GetReg() == rl_false.reg.GetReg()) { // False case in place?
OpIT(kCondEq, "");
- OpRegCopy(rl_result.low_reg, rl_true.low_reg);
+ OpRegCopy(rl_result.reg.GetReg(), rl_true.reg.GetReg());
} else { // Normal - select between the two.
OpIT(kCondEq, "E");
- OpRegCopy(rl_result.low_reg, rl_true.low_reg);
- OpRegCopy(rl_result.low_reg, rl_false.low_reg);
+ OpRegCopy(rl_result.reg.GetReg(), rl_true.reg.GetReg());
+ OpRegCopy(rl_result.reg.GetReg(), rl_false.reg.GetReg());
}
GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact
}
@@ -247,7 +247,7 @@ void ArmMir2Lir::GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir) {
LIR* not_taken = &block_label_list_[bb->fall_through];
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
- OpRegReg(kOpCmp, rl_src1.high_reg, rl_src2.high_reg);
+ OpRegReg(kOpCmp, rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
switch (ccode) {
case kCondEq:
OpCondBranch(kCondNe, not_taken);
@@ -278,7 +278,7 @@ void ArmMir2Lir::GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir) {
default:
LOG(FATAL) << "Unexpected ccode: " << ccode;
}
- OpRegReg(kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
+ OpRegReg(kOpCmp, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
OpCondBranch(ccode, taken);
}
@@ -415,21 +415,21 @@ bool ArmMir2Lir::SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
int r_hi = AllocTemp();
int r_lo = AllocTemp();
- NewLIR4(kThumb2Smull, r_lo, r_hi, r_magic, rl_src.low_reg);
+ NewLIR4(kThumb2Smull, r_lo, r_hi, r_magic, rl_src.reg.GetReg());
switch (pattern) {
case Divide3:
- OpRegRegRegShift(kOpSub, rl_result.low_reg, r_hi,
- rl_src.low_reg, EncodeShift(kArmAsr, 31));
+ OpRegRegRegShift(kOpSub, rl_result.reg.GetReg(), r_hi,
+ rl_src.reg.GetReg(), EncodeShift(kArmAsr, 31));
break;
case Divide5:
- OpRegRegImm(kOpAsr, r_lo, rl_src.low_reg, 31);
- OpRegRegRegShift(kOpRsub, rl_result.low_reg, r_lo, r_hi,
+ OpRegRegImm(kOpAsr, r_lo, rl_src.reg.GetReg(), 31);
+ OpRegRegRegShift(kOpRsub, rl_result.reg.GetReg(), r_lo, r_hi,
EncodeShift(kArmAsr, magic_table[lit].shift));
break;
case Divide7:
- OpRegReg(kOpAdd, r_hi, rl_src.low_reg);
- OpRegRegImm(kOpAsr, r_lo, rl_src.low_reg, 31);
- OpRegRegRegShift(kOpRsub, rl_result.low_reg, r_lo, r_hi,
+ OpRegReg(kOpAdd, r_hi, rl_src.reg.GetReg());
+ OpRegRegImm(kOpAsr, r_lo, rl_src.reg.GetReg(), 31);
+ OpRegRegRegShift(kOpRsub, rl_result.reg.GetReg(), r_lo, r_hi,
EncodeShift(kArmAsr, magic_table[lit].shift));
break;
default:
@@ -476,7 +476,7 @@ RegLocation ArmMir2Lir::GenDivRem(RegLocation rl_dest, int reg1, int reg2,
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_div) {
// Simple case, use sdiv instruction.
- OpRegRegReg(kOpDiv, rl_result.low_reg, reg1, reg2);
+ OpRegRegReg(kOpDiv, rl_result.reg.GetReg(), reg1, reg2);
} else {
// Remainder case, use the following code:
// temp = reg1 / reg2 - integer division
@@ -486,7 +486,7 @@ RegLocation ArmMir2Lir::GenDivRem(RegLocation rl_dest, int reg1, int reg2,
int temp = AllocTemp();
OpRegRegReg(kOpDiv, temp, reg1, reg2);
OpRegReg(kOpMul, temp, reg2);
- OpRegRegReg(kOpSub, rl_result.low_reg, reg1, temp);
+ OpRegRegReg(kOpSub, rl_result.reg.GetReg(), reg1, temp);
FreeTemp(temp);
}
@@ -501,10 +501,10 @@ bool ArmMir2Lir::GenInlinedMinMaxInt(CallInfo* info, bool is_min) {
rl_src2 = LoadValue(rl_src2, kCoreReg);
RegLocation rl_dest = InlineTarget(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegReg(kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
+ OpRegReg(kOpCmp, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
OpIT((is_min) ? kCondGt : kCondLt, "E");
- OpRegReg(kOpMov, rl_result.low_reg, rl_src2.low_reg);
- OpRegReg(kOpMov, rl_result.low_reg, rl_src1.low_reg);
+ OpRegReg(kOpMov, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ OpRegReg(kOpMov, rl_result.reg.GetReg(), rl_src1.reg.GetReg());
GenBarrier();
StoreValue(rl_dest, rl_result);
return true;
@@ -518,18 +518,18 @@ bool ArmMir2Lir::GenInlinedPeek(CallInfo* info, OpSize size) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (size == kLong) {
// Fake unaligned LDRD by two unaligned LDR instructions on ARMv7 with SCTLR.A set to 0.
- if (rl_address.low_reg != rl_result.low_reg) {
- LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, kWord, INVALID_SREG);
- LoadBaseDisp(rl_address.low_reg, 4, rl_result.high_reg, kWord, INVALID_SREG);
+ if (rl_address.reg.GetReg() != rl_result.reg.GetReg()) {
+ LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), kWord, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg.GetReg(), 4, rl_result.reg.GetHighReg(), kWord, INVALID_SREG);
} else {
- LoadBaseDisp(rl_address.low_reg, 4, rl_result.high_reg, kWord, INVALID_SREG);
- LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, kWord, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg.GetReg(), 4, rl_result.reg.GetHighReg(), kWord, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), kWord, INVALID_SREG);
}
StoreValueWide(rl_dest, rl_result);
} else {
DCHECK(size == kSignedByte || size == kSignedHalf || size == kWord);
// Unaligned load with LDR and LDRSH is allowed on ARMv7 with SCTLR.A set to 0.
- LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, size, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), size, INVALID_SREG);
StoreValue(rl_dest, rl_result);
}
return true;
@@ -543,13 +543,13 @@ bool ArmMir2Lir::GenInlinedPoke(CallInfo* info, OpSize size) {
if (size == kLong) {
// Fake unaligned STRD by two unaligned STR instructions on ARMv7 with SCTLR.A set to 0.
RegLocation rl_value = LoadValueWide(rl_src_value, kCoreReg);
- StoreBaseDisp(rl_address.low_reg, 0, rl_value.low_reg, kWord);
- StoreBaseDisp(rl_address.low_reg, 4, rl_value.high_reg, kWord);
+ StoreBaseDisp(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), kWord);
+ StoreBaseDisp(rl_address.reg.GetReg(), 4, rl_value.reg.GetHighReg(), kWord);
} else {
DCHECK(size == kSignedByte || size == kSignedHalf || size == kWord);
// Unaligned store with STR and STRSH is allowed on ARMv7 with SCTLR.A set to 0.
RegLocation rl_value = LoadValue(rl_src_value, kCoreReg);
- StoreBaseDisp(rl_address.low_reg, 0, rl_value.low_reg, size);
+ StoreBaseDisp(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), size);
}
return true;
}
@@ -589,24 +589,24 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
bool load_early = true;
if (is_long) {
bool expected_is_core_reg =
- rl_src_expected.location == kLocPhysReg && !IsFpReg(rl_src_expected.low_reg);
+ rl_src_expected.location == kLocPhysReg && !IsFpReg(rl_src_expected.reg.GetReg());
bool new_value_is_core_reg =
- rl_src_new_value.location == kLocPhysReg && !IsFpReg(rl_src_new_value.low_reg);
- bool expected_is_good_reg = expected_is_core_reg && !IsTemp(rl_src_expected.low_reg);
- bool new_value_is_good_reg = new_value_is_core_reg && !IsTemp(rl_src_new_value.low_reg);
+ rl_src_new_value.location == kLocPhysReg && !IsFpReg(rl_src_new_value.reg.GetReg());
+ bool expected_is_good_reg = expected_is_core_reg && !IsTemp(rl_src_expected.reg.GetReg());
+ bool new_value_is_good_reg = new_value_is_core_reg && !IsTemp(rl_src_new_value.reg.GetReg());
if (!expected_is_good_reg && !new_value_is_good_reg) {
// None of expected/new_value is non-temp reg, need to load both late
load_early = false;
// Make sure they are not in the temp regs and the load will not be skipped.
if (expected_is_core_reg) {
- FlushRegWide(rl_src_expected.low_reg, rl_src_expected.high_reg);
+ FlushRegWide(rl_src_expected.reg.GetReg(), rl_src_expected.reg.GetHighReg());
ClobberSReg(rl_src_expected.s_reg_low);
ClobberSReg(GetSRegHi(rl_src_expected.s_reg_low));
rl_src_expected.location = kLocDalvikFrame;
}
if (new_value_is_core_reg) {
- FlushRegWide(rl_src_new_value.low_reg, rl_src_new_value.high_reg);
+ FlushRegWide(rl_src_new_value.reg.GetReg(), rl_src_new_value.reg.GetHighReg());
ClobberSReg(rl_src_new_value.s_reg_low);
ClobberSReg(GetSRegHi(rl_src_new_value.s_reg_low));
rl_src_new_value.location = kLocDalvikFrame;
@@ -627,19 +627,19 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
// Mark card for object assuming new value is stored.
- MarkGCCard(rl_new_value.low_reg, rl_object.low_reg);
+ MarkGCCard(rl_new_value.reg.GetReg(), rl_object.reg.GetReg());
}
RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
int r_ptr = rARM_LR;
- OpRegRegReg(kOpAdd, r_ptr, rl_object.low_reg, rl_offset.low_reg);
+ OpRegRegReg(kOpAdd, r_ptr, rl_object.reg.GetReg(), rl_offset.reg.GetReg());
// Free now unneeded rl_object and rl_offset to give more temps.
ClobberSReg(rl_object.s_reg_low);
- FreeTemp(rl_object.low_reg);
+ FreeTemp(rl_object.reg.GetReg());
ClobberSReg(rl_offset.s_reg_low);
- FreeTemp(rl_offset.low_reg);
+ FreeTemp(rl_offset.reg.GetReg());
RegLocation rl_expected;
if (!is_long) {
@@ -647,8 +647,11 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
} else if (load_early) {
rl_expected = LoadValueWide(rl_src_expected, kCoreReg);
} else {
- rl_new_value.low_reg = rl_expected.low_reg = AllocTemp();
- rl_new_value.high_reg = rl_expected.high_reg = AllocTemp();
+ // NOTE: partially defined rl_expected & rl_new_value - but we just want the regs.
+ int low_reg = AllocTemp();
+ int high_reg = AllocTemp();
+ rl_new_value.reg = RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
+ rl_expected = rl_new_value;
}
// do {
@@ -662,13 +665,13 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
if (is_long) {
int r_tmp_high = AllocTemp();
if (!load_early) {
- LoadValueDirectWide(rl_src_expected, rl_expected.low_reg, rl_expected.high_reg);
+ LoadValueDirectWide(rl_src_expected, rl_expected.reg.GetReg(), rl_expected.reg.GetHighReg());
}
NewLIR3(kThumb2Ldrexd, r_tmp, r_tmp_high, r_ptr);
- OpRegReg(kOpSub, r_tmp, rl_expected.low_reg);
- OpRegReg(kOpSub, r_tmp_high, rl_expected.high_reg);
+ OpRegReg(kOpSub, r_tmp, rl_expected.reg.GetReg());
+ OpRegReg(kOpSub, r_tmp_high, rl_expected.reg.GetHighReg());
if (!load_early) {
- LoadValueDirectWide(rl_src_new_value, rl_new_value.low_reg, rl_new_value.high_reg);
+ LoadValueDirectWide(rl_src_new_value, rl_new_value.reg.GetReg(), rl_new_value.reg.GetHighReg());
}
// Make sure we use ORR that sets the ccode
if (ARM_LOWREG(r_tmp) && ARM_LOWREG(r_tmp_high)) {
@@ -680,14 +683,14 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE);
OpIT(kCondEq, "T");
- NewLIR4(kThumb2Strexd /* eq */, r_tmp, rl_new_value.low_reg, rl_new_value.high_reg, r_ptr);
+ NewLIR4(kThumb2Strexd /* eq */, r_tmp, rl_new_value.reg.GetReg(), rl_new_value.reg.GetHighReg(), r_ptr);
} else {
NewLIR3(kThumb2Ldrex, r_tmp, r_ptr, 0);
- OpRegReg(kOpSub, r_tmp, rl_expected.low_reg);
+ OpRegReg(kOpSub, r_tmp, rl_expected.reg.GetReg());
DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE);
OpIT(kCondEq, "T");
- NewLIR4(kThumb2Strex /* eq */, r_tmp, rl_new_value.low_reg, r_ptr, 0);
+ NewLIR4(kThumb2Strex /* eq */, r_tmp, rl_new_value.reg.GetReg(), r_ptr, 0);
}
// Still one conditional left from OpIT(kCondEq, "T") from either branch
@@ -695,16 +698,16 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
OpCondBranch(kCondEq, target);
if (!load_early) {
- FreeTemp(rl_expected.low_reg); // Now unneeded.
- FreeTemp(rl_expected.high_reg); // Now unneeded.
+ FreeTemp(rl_expected.reg.GetReg()); // Now unneeded.
+ FreeTemp(rl_expected.reg.GetHighReg()); // Now unneeded.
}
// result := (tmp1 != 0) ? 0 : 1;
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpRsub, rl_result.low_reg, r_tmp, 1);
+ OpRegRegImm(kOpRsub, rl_result.reg.GetReg(), r_tmp, 1);
DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE);
OpIT(kCondUlt, "");
- LoadConstant(rl_result.low_reg, 0); /* cc */
+ LoadConstant(rl_result.reg.GetReg(), 0); /* cc */
FreeTemp(r_tmp); // Now unneeded.
StoreValue(rl_dest, rl_result);
@@ -730,10 +733,10 @@ LIR* ArmMir2Lir::OpVstm(int rBase, int count) {
void ArmMir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src,
RegLocation rl_result, int lit,
int first_bit, int second_bit) {
- OpRegRegRegShift(kOpAdd, rl_result.low_reg, rl_src.low_reg, rl_src.low_reg,
+ OpRegRegRegShift(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), rl_src.reg.GetReg(),
EncodeShift(kArmLsl, second_bit - first_bit));
if (first_bit != 0) {
- OpRegRegImm(kOpLsl, rl_result.low_reg, rl_result.low_reg, first_bit);
+ OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_result.reg.GetReg(), first_bit);
}
}
@@ -782,14 +785,14 @@ void ArmMir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) {
int z_reg = AllocTemp();
LoadConstantNoClobber(z_reg, 0);
// Check for destructive overlap
- if (rl_result.low_reg == rl_src.high_reg) {
+ if (rl_result.reg.GetReg() == rl_src.reg.GetHighReg()) {
int t_reg = AllocTemp();
- OpRegRegReg(kOpSub, rl_result.low_reg, z_reg, rl_src.low_reg);
- OpRegRegReg(kOpSbc, rl_result.high_reg, z_reg, t_reg);
+ OpRegRegReg(kOpSub, rl_result.reg.GetReg(), z_reg, rl_src.reg.GetReg());
+ OpRegRegReg(kOpSbc, rl_result.reg.GetHighReg(), z_reg, t_reg);
FreeTemp(t_reg);
} else {
- OpRegRegReg(kOpSub, rl_result.low_reg, z_reg, rl_src.low_reg);
- OpRegRegReg(kOpSbc, rl_result.high_reg, z_reg, rl_src.high_reg);
+ OpRegRegReg(kOpSub, rl_result.reg.GetReg(), z_reg, rl_src.reg.GetReg());
+ OpRegRegReg(kOpSbc, rl_result.reg.GetHighReg(), z_reg, rl_src.reg.GetHighReg());
}
FreeTemp(z_reg);
StoreValueWide(rl_dest, rl_result);
@@ -827,41 +830,41 @@ void ArmMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest,
bool special_case = true;
// If operands are the same, or any pair has been promoted we're not the special case.
if ((rl_src1.s_reg_low == rl_src2.s_reg_low) ||
- (!IsTemp(rl_src1.low_reg) && !IsTemp(rl_src1.high_reg)) ||
- (!IsTemp(rl_src2.low_reg) && !IsTemp(rl_src2.high_reg))) {
+ (!IsTemp(rl_src1.reg.GetReg()) && !IsTemp(rl_src1.reg.GetHighReg())) ||
+ (!IsTemp(rl_src2.reg.GetReg()) && !IsTemp(rl_src2.reg.GetHighReg()))) {
special_case = false;
}
// Tuning: if rl_dest has been promoted and is *not* either operand, could use directly.
int res_lo = AllocTemp();
int res_hi;
- if (rl_src1.low_reg == rl_src2.low_reg) {
+ if (rl_src1.reg.GetReg() == rl_src2.reg.GetReg()) {
res_hi = AllocTemp();
- NewLIR3(kThumb2MulRRR, tmp1, rl_src1.low_reg, rl_src1.high_reg);
- NewLIR4(kThumb2Umull, res_lo, res_hi, rl_src1.low_reg, rl_src1.low_reg);
+ NewLIR3(kThumb2MulRRR, tmp1, rl_src1.reg.GetReg(), rl_src1.reg.GetHighReg());
+ NewLIR4(kThumb2Umull, res_lo, res_hi, rl_src1.reg.GetReg(), rl_src1.reg.GetReg());
OpRegRegRegShift(kOpAdd, res_hi, res_hi, tmp1, EncodeShift(kArmLsl, 1));
} else {
// In the special case, all temps are now allocated
- NewLIR3(kThumb2MulRRR, tmp1, rl_src2.low_reg, rl_src1.high_reg);
+ NewLIR3(kThumb2MulRRR, tmp1, rl_src2.reg.GetReg(), rl_src1.reg.GetHighReg());
if (special_case) {
- DCHECK_NE(rl_src1.low_reg, rl_src2.low_reg);
- DCHECK_NE(rl_src1.high_reg, rl_src2.high_reg);
- FreeTemp(rl_src1.high_reg);
+ DCHECK_NE(rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
+ DCHECK_NE(rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
+ FreeTemp(rl_src1.reg.GetHighReg());
}
res_hi = AllocTemp();
- NewLIR4(kThumb2Umull, res_lo, res_hi, rl_src2.low_reg, rl_src1.low_reg);
- NewLIR4(kThumb2Mla, tmp1, rl_src1.low_reg, rl_src2.high_reg, tmp1);
+ NewLIR4(kThumb2Umull, res_lo, res_hi, rl_src2.reg.GetReg(), rl_src1.reg.GetReg());
+ NewLIR4(kThumb2Mla, tmp1, rl_src1.reg.GetReg(), rl_src2.reg.GetHighReg(), tmp1);
NewLIR4(kThumb2AddRRR, res_hi, tmp1, res_hi, 0);
if (special_case) {
- FreeTemp(rl_src1.low_reg);
- Clobber(rl_src1.low_reg);
- Clobber(rl_src1.high_reg);
+ FreeTemp(rl_src1.reg.GetReg());
+ Clobber(rl_src1.reg.GetReg());
+ Clobber(rl_src1.reg.GetHighReg());
}
}
FreeTemp(tmp1);
rl_result = GetReturnWide(false); // Just using as a template.
- rl_result.low_reg = res_lo;
- rl_result.high_reg = res_hi;
+ rl_result.reg.SetReg(res_lo);
+ rl_result.reg.SetHighReg(res_hi);
StoreValueWide(rl_dest, rl_result);
// Now, restore lr to its non-temp status.
Clobber(rARM_LR);
@@ -920,25 +923,25 @@ void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
}
/* null object? */
- GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+ GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
int reg_len = INVALID_REG;
if (needs_range_check) {
reg_len = AllocTemp();
/* Get len */
- LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
+ LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
}
if (rl_dest.wide || rl_dest.fp || constant_index) {
int reg_ptr;
if (constant_index) {
- reg_ptr = rl_array.low_reg; // NOTE: must not alter reg_ptr in constant case.
+ reg_ptr = rl_array.reg.GetReg(); // NOTE: must not alter reg_ptr in constant case.
} else {
// No special indexed operation, lea + load w/ displacement
reg_ptr = AllocTemp();
- OpRegRegRegShift(kOpAdd, reg_ptr, rl_array.low_reg, rl_index.low_reg,
+ OpRegRegRegShift(kOpAdd, reg_ptr, rl_array.reg.GetReg(), rl_index.reg.GetReg(),
EncodeShift(kArmLsl, scale));
- FreeTemp(rl_index.low_reg);
+ FreeTemp(rl_index.reg.GetReg());
}
rl_result = EvalLoc(rl_dest, reg_class, true);
@@ -946,18 +949,18 @@ void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
if (constant_index) {
GenImmedCheck(kCondLs, reg_len, mir_graph_->ConstantValue(rl_index), kThrowConstantArrayBounds);
} else {
- GenRegRegCheck(kCondLs, reg_len, rl_index.low_reg, kThrowArrayBounds);
+ GenRegRegCheck(kCondLs, reg_len, rl_index.reg.GetReg(), kThrowArrayBounds);
}
FreeTemp(reg_len);
}
if (rl_dest.wide) {
- LoadBaseDispWide(reg_ptr, data_offset, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+ LoadBaseDispWide(reg_ptr, data_offset, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
if (!constant_index) {
FreeTemp(reg_ptr);
}
StoreValueWide(rl_dest, rl_result);
} else {
- LoadBaseDisp(reg_ptr, data_offset, rl_result.low_reg, size, INVALID_SREG);
+ LoadBaseDisp(reg_ptr, data_offset, rl_result.reg.GetReg(), size, INVALID_SREG);
if (!constant_index) {
FreeTemp(reg_ptr);
}
@@ -966,15 +969,15 @@ void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
} else {
// Offset base, then use indexed load
int reg_ptr = AllocTemp();
- OpRegRegImm(kOpAdd, reg_ptr, rl_array.low_reg, data_offset);
- FreeTemp(rl_array.low_reg);
+ OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg.GetReg(), data_offset);
+ FreeTemp(rl_array.reg.GetReg());
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- LoadBaseIndexed(reg_ptr, rl_index.low_reg, rl_result.low_reg, scale, size);
+ LoadBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_result.reg.GetReg(), scale, size);
FreeTemp(reg_ptr);
StoreValue(rl_dest, rl_result);
}
@@ -1010,17 +1013,17 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
int reg_ptr;
bool allocated_reg_ptr_temp = false;
if (constant_index) {
- reg_ptr = rl_array.low_reg;
- } else if (IsTemp(rl_array.low_reg) && !card_mark) {
- Clobber(rl_array.low_reg);
- reg_ptr = rl_array.low_reg;
+ reg_ptr = rl_array.reg.GetReg();
+ } else if (IsTemp(rl_array.reg.GetReg()) && !card_mark) {
+ Clobber(rl_array.reg.GetReg());
+ reg_ptr = rl_array.reg.GetReg();
} else {
allocated_reg_ptr_temp = true;
reg_ptr = AllocTemp();
}
/* null object? */
- GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+ GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
int reg_len = INVALID_REG;
@@ -1028,7 +1031,7 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
reg_len = AllocTemp();
// NOTE: max live temps(4) here.
/* Get len */
- LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
+ LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
}
/* at this point, reg_ptr points to array, 2 live temps */
if (rl_src.wide || rl_src.fp || constant_index) {
@@ -1038,39 +1041,39 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
rl_src = LoadValue(rl_src, reg_class);
}
if (!constant_index) {
- OpRegRegRegShift(kOpAdd, reg_ptr, rl_array.low_reg, rl_index.low_reg,
+ OpRegRegRegShift(kOpAdd, reg_ptr, rl_array.reg.GetReg(), rl_index.reg.GetReg(),
EncodeShift(kArmLsl, scale));
}
if (needs_range_check) {
if (constant_index) {
GenImmedCheck(kCondLs, reg_len, mir_graph_->ConstantValue(rl_index), kThrowConstantArrayBounds);
} else {
- GenRegRegCheck(kCondLs, reg_len, rl_index.low_reg, kThrowArrayBounds);
+ GenRegRegCheck(kCondLs, reg_len, rl_index.reg.GetReg(), kThrowArrayBounds);
}
FreeTemp(reg_len);
}
if (rl_src.wide) {
- StoreBaseDispWide(reg_ptr, data_offset, rl_src.low_reg, rl_src.high_reg);
+ StoreBaseDispWide(reg_ptr, data_offset, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
- StoreBaseDisp(reg_ptr, data_offset, rl_src.low_reg, size);
+ StoreBaseDisp(reg_ptr, data_offset, rl_src.reg.GetReg(), size);
}
} else {
/* reg_ptr -> array data */
- OpRegRegImm(kOpAdd, reg_ptr, rl_array.low_reg, data_offset);
+ OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg.GetReg(), data_offset);
rl_src = LoadValue(rl_src, reg_class);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- StoreBaseIndexed(reg_ptr, rl_index.low_reg, rl_src.low_reg,
+ StoreBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_src.reg.GetReg(),
scale, size);
}
if (allocated_reg_ptr_temp) {
FreeTemp(reg_ptr);
}
if (card_mark) {
- MarkGCCard(rl_src.low_reg, rl_array.low_reg);
+ MarkGCCard(rl_src.reg.GetReg(), rl_array.reg.GetReg());
}
}
@@ -1093,53 +1096,53 @@ void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode,
case Instruction::SHL_LONG:
case Instruction::SHL_LONG_2ADDR:
if (shift_amount == 1) {
- OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, rl_src.low_reg);
- OpRegRegReg(kOpAdc, rl_result.high_reg, rl_src.high_reg, rl_src.high_reg);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), rl_src.reg.GetReg());
+ OpRegRegReg(kOpAdc, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), rl_src.reg.GetHighReg());
} else if (shift_amount == 32) {
- OpRegCopy(rl_result.high_reg, rl_src.low_reg);
- LoadConstant(rl_result.low_reg, 0);
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetReg());
+ LoadConstant(rl_result.reg.GetReg(), 0);
} else if (shift_amount > 31) {
- OpRegRegImm(kOpLsl, rl_result.high_reg, rl_src.low_reg, shift_amount - 32);
- LoadConstant(rl_result.low_reg, 0);
+ OpRegRegImm(kOpLsl, rl_result.reg.GetHighReg(), rl_src.reg.GetReg(), shift_amount - 32);
+ LoadConstant(rl_result.reg.GetReg(), 0);
} else {
- OpRegRegImm(kOpLsl, rl_result.high_reg, rl_src.high_reg, shift_amount);
- OpRegRegRegShift(kOpOr, rl_result.high_reg, rl_result.high_reg, rl_src.low_reg,
+ OpRegRegImm(kOpLsl, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), shift_amount);
+ OpRegRegRegShift(kOpOr, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), rl_src.reg.GetReg(),
EncodeShift(kArmLsr, 32 - shift_amount));
- OpRegRegImm(kOpLsl, rl_result.low_reg, rl_src.low_reg, shift_amount);
+ OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_src.reg.GetReg(), shift_amount);
}
break;
case Instruction::SHR_LONG:
case Instruction::SHR_LONG_2ADDR:
if (shift_amount == 32) {
- OpRegCopy(rl_result.low_reg, rl_src.high_reg);
- OpRegRegImm(kOpAsr, rl_result.high_reg, rl_src.high_reg, 31);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetHighReg());
+ OpRegRegImm(kOpAsr, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), 31);
} else if (shift_amount > 31) {
- OpRegRegImm(kOpAsr, rl_result.low_reg, rl_src.high_reg, shift_amount - 32);
- OpRegRegImm(kOpAsr, rl_result.high_reg, rl_src.high_reg, 31);
+ OpRegRegImm(kOpAsr, rl_result.reg.GetReg(), rl_src.reg.GetHighReg(), shift_amount - 32);
+ OpRegRegImm(kOpAsr, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), 31);
} else {
int t_reg = AllocTemp();
- OpRegRegImm(kOpLsr, t_reg, rl_src.low_reg, shift_amount);
- OpRegRegRegShift(kOpOr, rl_result.low_reg, t_reg, rl_src.high_reg,
+ OpRegRegImm(kOpLsr, t_reg, rl_src.reg.GetReg(), shift_amount);
+ OpRegRegRegShift(kOpOr, rl_result.reg.GetReg(), t_reg, rl_src.reg.GetHighReg(),
EncodeShift(kArmLsl, 32 - shift_amount));
FreeTemp(t_reg);
- OpRegRegImm(kOpAsr, rl_result.high_reg, rl_src.high_reg, shift_amount);
+ OpRegRegImm(kOpAsr, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), shift_amount);
}
break;
case Instruction::USHR_LONG:
case Instruction::USHR_LONG_2ADDR:
if (shift_amount == 32) {
- OpRegCopy(rl_result.low_reg, rl_src.high_reg);
- LoadConstant(rl_result.high_reg, 0);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetHighReg());
+ LoadConstant(rl_result.reg.GetHighReg(), 0);
} else if (shift_amount > 31) {
- OpRegRegImm(kOpLsr, rl_result.low_reg, rl_src.high_reg, shift_amount - 32);
- LoadConstant(rl_result.high_reg, 0);
+ OpRegRegImm(kOpLsr, rl_result.reg.GetReg(), rl_src.reg.GetHighReg(), shift_amount - 32);
+ LoadConstant(rl_result.reg.GetHighReg(), 0);
} else {
int t_reg = AllocTemp();
- OpRegRegImm(kOpLsr, t_reg, rl_src.low_reg, shift_amount);
- OpRegRegRegShift(kOpOr, rl_result.low_reg, t_reg, rl_src.high_reg,
+ OpRegRegImm(kOpLsr, t_reg, rl_src.reg.GetReg(), shift_amount);
+ OpRegRegRegShift(kOpOr, rl_result.reg.GetReg(), t_reg, rl_src.reg.GetHighReg(),
EncodeShift(kArmLsl, 32 - shift_amount));
FreeTemp(t_reg);
- OpRegRegImm(kOpLsr, rl_result.high_reg, rl_src.high_reg, shift_amount);
+ OpRegRegImm(kOpLsr, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), shift_amount);
}
break;
default:
@@ -1194,36 +1197,36 @@ void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode,
switch (opcode) {
case Instruction::ADD_LONG:
case Instruction::ADD_LONG_2ADDR:
- NewLIR3(kThumb2AddRRI8M, rl_result.low_reg, rl_src1.low_reg, mod_imm_lo);
- NewLIR3(kThumb2AdcRRI8M, rl_result.high_reg, rl_src1.high_reg, mod_imm_hi);
+ NewLIR3(kThumb2AddRRI8M, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), mod_imm_lo);
+ NewLIR3(kThumb2AdcRRI8M, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), mod_imm_hi);
break;
case Instruction::OR_LONG:
case Instruction::OR_LONG_2ADDR:
- if ((val_lo != 0) || (rl_result.low_reg != rl_src1.low_reg)) {
- OpRegRegImm(kOpOr, rl_result.low_reg, rl_src1.low_reg, val_lo);
+ if ((val_lo != 0) || (rl_result.reg.GetReg() != rl_src1.reg.GetReg())) {
+ OpRegRegImm(kOpOr, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), val_lo);
}
- if ((val_hi != 0) || (rl_result.high_reg != rl_src1.high_reg)) {
- OpRegRegImm(kOpOr, rl_result.high_reg, rl_src1.high_reg, val_hi);
+ if ((val_hi != 0) || (rl_result.reg.GetHighReg() != rl_src1.reg.GetHighReg())) {
+ OpRegRegImm(kOpOr, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), val_hi);
}
break;
case Instruction::XOR_LONG:
case Instruction::XOR_LONG_2ADDR:
- OpRegRegImm(kOpXor, rl_result.low_reg, rl_src1.low_reg, val_lo);
- OpRegRegImm(kOpXor, rl_result.high_reg, rl_src1.high_reg, val_hi);
+ OpRegRegImm(kOpXor, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), val_lo);
+ OpRegRegImm(kOpXor, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), val_hi);
break;
case Instruction::AND_LONG:
case Instruction::AND_LONG_2ADDR:
- if ((val_lo != 0xffffffff) || (rl_result.low_reg != rl_src1.low_reg)) {
- OpRegRegImm(kOpAnd, rl_result.low_reg, rl_src1.low_reg, val_lo);
+ if ((val_lo != 0xffffffff) || (rl_result.reg.GetReg() != rl_src1.reg.GetReg())) {
+ OpRegRegImm(kOpAnd, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), val_lo);
}
- if ((val_hi != 0xffffffff) || (rl_result.high_reg != rl_src1.high_reg)) {
- OpRegRegImm(kOpAnd, rl_result.high_reg, rl_src1.high_reg, val_hi);
+ if ((val_hi != 0xffffffff) || (rl_result.reg.GetHighReg() != rl_src1.reg.GetHighReg())) {
+ OpRegRegImm(kOpAnd, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), val_hi);
}
break;
case Instruction::SUB_LONG_2ADDR:
case Instruction::SUB_LONG:
- NewLIR3(kThumb2SubRRI8M, rl_result.low_reg, rl_src1.low_reg, mod_imm_lo);
- NewLIR3(kThumb2SbcRRI8M, rl_result.high_reg, rl_src1.high_reg, mod_imm_hi);
+ NewLIR3(kThumb2SubRRI8M, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), mod_imm_lo);
+ NewLIR3(kThumb2SbcRRI8M, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), mod_imm_hi);
break;
default:
LOG(FATAL) << "Unexpected opcode " << opcode;
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index 83431ad235..ab1a053489 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -37,23 +37,19 @@ static int fp_temps[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15};
RegLocation ArmMir2Lir::LocCReturn() {
- RegLocation res = ARM_LOC_C_RETURN;
- return res;
+ return arm_loc_c_return;
}
RegLocation ArmMir2Lir::LocCReturnWide() {
- RegLocation res = ARM_LOC_C_RETURN_WIDE;
- return res;
+ return arm_loc_c_return_wide;
}
RegLocation ArmMir2Lir::LocCReturnFloat() {
- RegLocation res = ARM_LOC_C_RETURN_FLOAT;
- return res;
+ return arm_loc_c_return_float;
}
RegLocation ArmMir2Lir::LocCReturnDouble() {
- RegLocation res = ARM_LOC_C_RETURN_DOUBLE;
- return res;
+ return arm_loc_c_return_double;
}
// Return a target-dependent special register.
@@ -530,14 +526,10 @@ Mir2Lir* ArmCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
return new ArmMir2Lir(cu, mir_graph, arena);
}
-/*
- * Alloc a pair of core registers, or a double. Low reg in low byte,
- * high reg in next byte.
- */
-int ArmMir2Lir::AllocTypedTempPair(bool fp_hint, int reg_class) {
+// Alloc a pair of core registers, or a double.
+RegStorage ArmMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
int high_reg;
int low_reg;
- int res = 0;
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
low_reg = AllocTempDouble();
@@ -546,8 +538,7 @@ int ArmMir2Lir::AllocTypedTempPair(bool fp_hint, int reg_class) {
low_reg = AllocTemp();
high_reg = AllocTemp();
}
- res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
- return res;
+ return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
}
int ArmMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
@@ -594,11 +585,11 @@ void ArmMir2Lir::CompilerInitializeRegAlloc() {
void ArmMir2Lir::FreeRegLocTemps(RegLocation rl_keep,
RegLocation rl_free) {
- if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
- (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
+ 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.low_reg);
- FreeTemp(rl_free.high_reg);
+ FreeTemp(rl_free.reg.GetReg());
+ FreeTemp(rl_free.reg.GetHighReg());
}
}
/*
@@ -697,19 +688,19 @@ void ArmMir2Lir::ClobberCallerSave() {
RegLocation ArmMir2Lir::GetReturnWideAlt() {
RegLocation res = LocCReturnWide();
- res.low_reg = r2;
- res.high_reg = r3;
+ res.reg.SetReg(r2);
+ res.reg.SetHighReg(r3);
Clobber(r2);
Clobber(r3);
MarkInUse(r2);
MarkInUse(r3);
- MarkPair(res.low_reg, res.high_reg);
+ MarkPair(res.reg.GetReg(), res.reg.GetHighReg());
return res;
}
RegLocation ArmMir2Lir::GetReturnAlt() {
RegLocation res = LocCReturn();
- res.low_reg = r1;
+ res.reg.SetReg(r1);
Clobber(r1);
MarkInUse(r1);
return res;
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index 0533fbfcd7..06f2010396 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -128,12 +128,12 @@ void Mir2Lir::GenCompareAndBranch(Instruction::Code opcode, RegLocation rl_src1,
if ((rl_temp.location == kLocDalvikFrame) &&
InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src2))) {
// OK - convert this to a compare immediate and branch
- OpCmpImmBranch(cond, rl_src1.low_reg, mir_graph_->ConstantValue(rl_src2), taken);
+ OpCmpImmBranch(cond, rl_src1.reg.GetReg(), mir_graph_->ConstantValue(rl_src2), taken);
return;
}
}
rl_src2 = LoadValue(rl_src2, kCoreReg);
- OpCmpBranch(cond, rl_src1.low_reg, rl_src2.low_reg, taken);
+ OpCmpBranch(cond, rl_src1.reg.GetReg(), rl_src2.reg.GetReg(), taken);
}
void Mir2Lir::GenCompareZeroAndBranch(Instruction::Code opcode, RegLocation rl_src, LIR* taken,
@@ -163,17 +163,17 @@ void Mir2Lir::GenCompareZeroAndBranch(Instruction::Code opcode, RegLocation rl_s
cond = static_cast<ConditionCode>(0);
LOG(FATAL) << "Unexpected opcode " << opcode;
}
- OpCmpImmBranch(cond, rl_src.low_reg, 0, taken);
+ OpCmpImmBranch(cond, rl_src.reg.GetReg(), 0, taken);
}
void Mir2Lir::GenIntToLong(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (rl_src.location == kLocPhysReg) {
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
} else {
- LoadValueDirect(rl_src, rl_result.low_reg);
+ LoadValueDirect(rl_src, rl_result.reg.GetReg());
}
- OpRegRegImm(kOpAsr, rl_result.high_reg, rl_result.low_reg, 31);
+ OpRegRegImm(kOpAsr, rl_result.reg.GetHighReg(), rl_result.reg.GetReg(), 31);
StoreValueWide(rl_dest, rl_result);
}
@@ -195,7 +195,7 @@ void Mir2Lir::GenIntNarrowing(Instruction::Code opcode, RegLocation rl_dest,
default:
LOG(ERROR) << "Bad int conversion type";
}
- OpRegReg(op, rl_result.low_reg, rl_src.low_reg);
+ OpRegReg(op, rl_result.reg.GetReg(), rl_src.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
@@ -290,7 +290,7 @@ void Mir2Lir::GenFilledNewArray(CallInfo* info) {
RegLocation loc = UpdateLoc(info->args[i]);
if (loc.location == kLocPhysReg) {
StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low),
- loc.low_reg, kWord);
+ loc.reg.GetReg(), kWord);
}
}
/*
@@ -341,10 +341,10 @@ void Mir2Lir::GenFilledNewArray(CallInfo* info) {
RegLocation rl_arg = LoadValue(info->args[i], kCoreReg);
StoreBaseDisp(TargetReg(kRet0),
mirror::Array::DataOffset(component_size).Int32Value() +
- i * 4, rl_arg.low_reg, kWord);
+ i * 4, rl_arg.reg.GetReg(), kWord);
// If the LoadValue caused a temp to be allocated, free it
- if (IsTemp(rl_arg.low_reg)) {
- FreeTemp(rl_arg.low_reg);
+ if (IsTemp(rl_arg.reg.GetReg())) {
+ FreeTemp(rl_arg.reg.GetReg());
}
}
}
@@ -398,10 +398,10 @@ void Mir2Lir::GenSput(uint32_t field_idx, RegLocation rl_src, bool is_long_or_do
// Fast path, static storage base is this method's class
RegLocation rl_method = LoadCurrMethod();
r_base = AllocTemp();
- LoadWordDisp(rl_method.low_reg,
+ LoadWordDisp(rl_method.reg.GetReg(),
mirror::ArtMethod::DeclaringClassOffset().Int32Value(), r_base);
- if (IsTemp(rl_method.low_reg)) {
- FreeTemp(rl_method.low_reg);
+ if (IsTemp(rl_method.reg.GetReg())) {
+ FreeTemp(rl_method.reg.GetReg());
}
} else {
// Medium path, static storage base in a different class which requires checks that the other
@@ -453,16 +453,16 @@ void Mir2Lir::GenSput(uint32_t field_idx, RegLocation rl_src, bool is_long_or_do
GenMemBarrier(kStoreStore);
}
if (is_long_or_double) {
- StoreBaseDispWide(r_base, field_offset, rl_src.low_reg,
- rl_src.high_reg);
+ StoreBaseDispWide(r_base, field_offset, rl_src.reg.GetReg(),
+ rl_src.reg.GetHighReg());
} else {
- StoreWordDisp(r_base, field_offset, rl_src.low_reg);
+ StoreWordDisp(r_base, field_offset, rl_src.reg.GetReg());
}
if (is_volatile) {
GenMemBarrier(kStoreLoad);
}
if (is_object && !mir_graph_->IsConstantNullRef(rl_src)) {
- MarkGCCard(rl_src.low_reg, r_base);
+ MarkGCCard(rl_src.reg.GetReg(), r_base);
}
FreeTemp(r_base);
} else {
@@ -492,7 +492,7 @@ void Mir2Lir::GenSget(uint32_t field_idx, RegLocation rl_dest,
// Fast path, static storage base is this method's class
RegLocation rl_method = LoadCurrMethod();
r_base = AllocTemp();
- LoadWordDisp(rl_method.low_reg,
+ LoadWordDisp(rl_method.reg.GetReg(),
mirror::ArtMethod::DeclaringClassOffset().Int32Value(), r_base);
} else {
// Medium path, static storage base in a different class which requires checks that the other
@@ -539,10 +539,10 @@ void Mir2Lir::GenSget(uint32_t field_idx, RegLocation rl_dest,
GenMemBarrier(kLoadLoad);
}
if (is_long_or_double) {
- LoadBaseDispWide(r_base, field_offset, rl_result.low_reg,
- rl_result.high_reg, INVALID_SREG);
+ LoadBaseDispWide(r_base, field_offset, rl_result.reg.GetReg(),
+ rl_result.reg.GetHighReg(), INVALID_SREG);
} else {
- LoadWordDisp(r_base, field_offset, rl_result.low_reg);
+ LoadWordDisp(r_base, field_offset, rl_result.reg.GetReg());
}
FreeTemp(r_base);
if (is_long_or_double) {
@@ -713,20 +713,20 @@ void Mir2Lir::GenIGet(uint32_t field_idx, int opt_flags, OpSize size,
rl_obj = LoadValue(rl_obj, kCoreReg);
if (is_long_or_double) {
DCHECK(rl_dest.wide);
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, opt_flags);
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), opt_flags);
if (cu_->instruction_set == kX86) {
rl_result = EvalLoc(rl_dest, reg_class, true);
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, opt_flags);
- LoadBaseDispWide(rl_obj.low_reg, field_offset, rl_result.low_reg,
- rl_result.high_reg, rl_obj.s_reg_low);
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), opt_flags);
+ LoadBaseDispWide(rl_obj.reg.GetReg(), field_offset, rl_result.reg.GetReg(),
+ rl_result.reg.GetHighReg(), rl_obj.s_reg_low);
if (is_volatile) {
GenMemBarrier(kLoadLoad);
}
} else {
int reg_ptr = AllocTemp();
- OpRegRegImm(kOpAdd, reg_ptr, rl_obj.low_reg, field_offset);
+ OpRegRegImm(kOpAdd, reg_ptr, rl_obj.reg.GetReg(), field_offset);
rl_result = EvalLoc(rl_dest, reg_class, true);
- LoadBaseDispWide(reg_ptr, 0, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+ LoadBaseDispWide(reg_ptr, 0, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
if (is_volatile) {
GenMemBarrier(kLoadLoad);
}
@@ -735,8 +735,8 @@ void Mir2Lir::GenIGet(uint32_t field_idx, int opt_flags, OpSize size,
StoreValueWide(rl_dest, rl_result);
} else {
rl_result = EvalLoc(rl_dest, reg_class, true);
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, opt_flags);
- LoadBaseDisp(rl_obj.low_reg, field_offset, rl_result.low_reg,
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), opt_flags);
+ LoadBaseDisp(rl_obj.reg.GetReg(), field_offset, rl_result.reg.GetReg(),
kWord, rl_obj.s_reg_low);
if (is_volatile) {
GenMemBarrier(kLoadLoad);
@@ -773,29 +773,29 @@ void Mir2Lir::GenIPut(uint32_t field_idx, int opt_flags, OpSize size,
if (is_long_or_double) {
int reg_ptr;
rl_src = LoadValueWide(rl_src, kAnyReg);
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, opt_flags);
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), opt_flags);
reg_ptr = AllocTemp();
- OpRegRegImm(kOpAdd, reg_ptr, rl_obj.low_reg, field_offset);
+ OpRegRegImm(kOpAdd, reg_ptr, rl_obj.reg.GetReg(), field_offset);
if (is_volatile) {
GenMemBarrier(kStoreStore);
}
- StoreBaseDispWide(reg_ptr, 0, rl_src.low_reg, rl_src.high_reg);
+ StoreBaseDispWide(reg_ptr, 0, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
if (is_volatile) {
GenMemBarrier(kLoadLoad);
}
FreeTemp(reg_ptr);
} else {
rl_src = LoadValue(rl_src, reg_class);
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, opt_flags);
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), opt_flags);
if (is_volatile) {
GenMemBarrier(kStoreStore);
}
- StoreBaseDisp(rl_obj.low_reg, field_offset, rl_src.low_reg, kWord);
+ StoreBaseDisp(rl_obj.reg.GetReg(), field_offset, rl_src.reg.GetReg(), kWord);
if (is_volatile) {
GenMemBarrier(kLoadLoad);
}
if (is_object && !mir_graph_->IsConstantNullRef(rl_src)) {
- MarkGCCard(rl_src.low_reg, rl_obj.low_reg);
+ MarkGCCard(rl_src.reg.GetReg(), rl_obj.reg.GetReg());
}
}
} else {
@@ -829,23 +829,23 @@ void Mir2Lir::GenConstClass(uint32_t type_idx, RegLocation rl_dest) {
// Call out to helper which resolves type and verifies access.
// Resolved type returned in kRet0.
CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(pInitializeTypeAndVerifyAccess),
- type_idx, rl_method.low_reg, true);
+ type_idx, rl_method.reg.GetReg(), true);
RegLocation rl_result = GetReturn(false);
StoreValue(rl_dest, rl_result);
} else {
// We're don't need access checks, load type from dex cache
int32_t dex_cache_offset =
mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value();
- LoadWordDisp(rl_method.low_reg, dex_cache_offset, res_reg);
+ LoadWordDisp(rl_method.reg.GetReg(), dex_cache_offset, res_reg);
int32_t offset_of_type =
mirror::Array::DataOffset(sizeof(mirror::Class*)).Int32Value() + (sizeof(mirror::Class*)
* type_idx);
- LoadWordDisp(res_reg, offset_of_type, rl_result.low_reg);
+ LoadWordDisp(res_reg, offset_of_type, rl_result.reg.GetReg());
if (!cu_->compiler_driver->CanAssumeTypeIsPresentInDexCache(*cu_->dex_file,
type_idx) || SLOW_TYPE_PATH) {
// Slow path, at runtime test if type is null and if so initialize
FlushAllRegs();
- LIR* branch = OpCmpImmBranch(kCondEq, rl_result.low_reg, 0, NULL);
+ LIR* branch = OpCmpImmBranch(kCondEq, rl_result.reg.GetReg(), 0, NULL);
LIR* cont = NewLIR0(kPseudoTargetLabel);
// Object to generate the slow path for class resolution.
@@ -861,8 +861,8 @@ void Mir2Lir::GenConstClass(uint32_t type_idx, RegLocation rl_dest) {
GenerateTargetLabel();
m2l_->CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(pInitializeType), type_idx_,
- rl_method_.low_reg, true);
- m2l_->OpRegCopy(rl_result_.low_reg, m2l_->TargetReg(kRet0));
+ rl_method_.reg.GetReg(), true);
+ m2l_->OpRegCopy(rl_result_.reg.GetReg(), m2l_->TargetReg(kRet0));
m2l_->OpUnconditionalBranch(cont_);
}
@@ -900,8 +900,8 @@ void Mir2Lir::GenConstString(uint32_t string_idx, RegLocation rl_dest) {
int r_method;
if (rl_method.location == kLocPhysReg) {
// A temp would conflict with register use below.
- DCHECK(!IsTemp(rl_method.low_reg));
- r_method = rl_method.low_reg;
+ DCHECK(!IsTemp(rl_method.reg.GetReg()));
+ r_method = rl_method.reg.GetReg();
} else {
r_method = TargetReg(kArg2);
LoadCurrMethodDirect(r_method);
@@ -960,9 +960,9 @@ void Mir2Lir::GenConstString(uint32_t string_idx, RegLocation rl_dest) {
RegLocation rl_method = LoadCurrMethod();
int res_reg = AllocTemp();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- LoadWordDisp(rl_method.low_reg,
+ LoadWordDisp(rl_method.reg.GetReg(),
mirror::ArtMethod::DexCacheStringsOffset().Int32Value(), res_reg);
- LoadWordDisp(res_reg, offset_of_string, rl_result.low_reg);
+ LoadWordDisp(res_reg, offset_of_string, rl_result.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
}
@@ -1035,12 +1035,12 @@ void Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, Re
RegLocation object = LoadValue(rl_src, kCoreReg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- int result_reg = rl_result.low_reg;
- if (result_reg == object.low_reg) {
+ int result_reg = rl_result.reg.GetReg();
+ if (result_reg == object.reg.GetReg()) {
result_reg = AllocTypedTemp(false, kCoreReg);
}
LoadConstant(result_reg, 0); // assume false
- LIR* null_branchover = OpCmpImmBranch(kCondEq, object.low_reg, 0, NULL);
+ LIR* null_branchover = OpCmpImmBranch(kCondEq, object.reg.GetReg(), 0, NULL);
int check_class = AllocTypedTemp(false, kCoreReg);
int object_class = AllocTypedTemp(false, kCoreReg);
@@ -1049,11 +1049,11 @@ void Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, Re
if (use_declaring_class) {
LoadWordDisp(check_class, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
check_class);
- LoadWordDisp(object.low_reg, mirror::Object::ClassOffset().Int32Value(), object_class);
+ LoadWordDisp(object.reg.GetReg(), mirror::Object::ClassOffset().Int32Value(), object_class);
} else {
LoadWordDisp(check_class, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
check_class);
- LoadWordDisp(object.low_reg, mirror::Object::ClassOffset().Int32Value(), object_class);
+ LoadWordDisp(object.reg.GetReg(), mirror::Object::ClassOffset().Int32Value(), object_class);
int32_t offset_of_type =
mirror::Array::DataOffset(sizeof(mirror::Class*)).Int32Value() +
(sizeof(mirror::Class*) * type_idx);
@@ -1077,7 +1077,7 @@ void Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, Re
FreeTemp(object_class);
FreeTemp(check_class);
if (IsTemp(result_reg)) {
- OpRegCopy(rl_result.low_reg, result_reg);
+ OpRegCopy(rl_result.reg.GetReg(), result_reg);
FreeTemp(result_reg);
}
StoreValue(rl_dest, rl_result);
@@ -1133,7 +1133,7 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know
RegLocation rl_result = GetReturn(false);
if (cu_->instruction_set == kMips) {
// On MIPS rArg0 != rl_result, place false in result if branch is taken.
- LoadConstant(rl_result.low_reg, 0);
+ LoadConstant(rl_result.reg.GetReg(), 0);
}
LIR* branch1 = OpCmpImmBranch(kCondEq, TargetReg(kArg0), 0, NULL);
@@ -1147,12 +1147,12 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know
if (cu_->instruction_set == kThumb2) {
OpRegReg(kOpCmp, TargetReg(kArg1), TargetReg(kArg2)); // Same?
OpIT(kCondEq, "E"); // if-convert the test
- LoadConstant(rl_result.low_reg, 1); // .eq case - load true
- LoadConstant(rl_result.low_reg, 0); // .ne case - load false
+ LoadConstant(rl_result.reg.GetReg(), 1); // .eq case - load true
+ LoadConstant(rl_result.reg.GetReg(), 0); // .ne case - load false
} else {
- LoadConstant(rl_result.low_reg, 0); // ne case - load false
+ LoadConstant(rl_result.reg.GetReg(), 0); // ne case - load false
branchover = OpCmpBranch(kCondNe, TargetReg(kArg1), TargetReg(kArg2), NULL);
- LoadConstant(rl_result.low_reg, 1); // eq case - load true
+ LoadConstant(rl_result.reg.GetReg(), 1); // eq case - load true
}
} else {
if (cu_->instruction_set == kThumb2) {
@@ -1169,7 +1169,7 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know
} else {
if (!type_known_abstract) {
/* Uses branchovers */
- LoadConstant(rl_result.low_reg, 1); // assume true
+ LoadConstant(rl_result.reg.GetReg(), 1); // assume true
branchover = OpCmpBranch(kCondEq, TargetReg(kArg1), TargetReg(kArg2), NULL);
}
int r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(pInstanceofNonTrivial));
@@ -1355,16 +1355,16 @@ void Mir2Lir::GenLong3Addr(OpKind first_op, OpKind second_op, RegLocation rl_des
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
// The longs may overlap - use intermediate temp if so
- if ((rl_result.low_reg == rl_src1.high_reg) || (rl_result.low_reg == rl_src2.high_reg)) {
+ if ((rl_result.reg.GetReg() == rl_src1.reg.GetHighReg()) || (rl_result.reg.GetReg() == rl_src2.reg.GetHighReg())) {
int t_reg = AllocTemp();
- OpRegRegReg(first_op, t_reg, rl_src1.low_reg, rl_src2.low_reg);
- OpRegRegReg(second_op, rl_result.high_reg, rl_src1.high_reg, rl_src2.high_reg);
- OpRegCopy(rl_result.low_reg, t_reg);
+ OpRegRegReg(first_op, t_reg, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
+ OpRegRegReg(second_op, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(), rl_src2.reg.GetHighReg());
+ OpRegCopy(rl_result.reg.GetReg(), t_reg);
FreeTemp(t_reg);
} else {
- OpRegRegReg(first_op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
- OpRegRegReg(second_op, rl_result.high_reg, rl_src1.high_reg,
- rl_src2.high_reg);
+ OpRegRegReg(first_op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
+ OpRegRegReg(second_op, rl_result.reg.GetHighReg(), rl_src1.reg.GetHighReg(),
+ rl_src2.reg.GetHighReg());
}
/*
* NOTE: If rl_dest refers to a frame variable in a large frame, the
@@ -1487,22 +1487,22 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
if (unary) {
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegReg(op, rl_result.low_reg, rl_src1.low_reg);
+ OpRegReg(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg());
} else {
if (shift_op) {
int t_reg = INVALID_REG;
rl_src2 = LoadValue(rl_src2, kCoreReg);
t_reg = AllocTemp();
- OpRegRegImm(kOpAnd, t_reg, rl_src2.low_reg, 31);
+ OpRegRegImm(kOpAnd, t_reg, rl_src2.reg.GetReg(), 31);
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_src1.low_reg, t_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), t_reg);
FreeTemp(t_reg);
} else {
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
}
}
StoreValue(rl_dest, rl_result);
@@ -1512,9 +1512,9 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
if (check_zero) {
- GenImmedCheck(kCondEq, rl_src2.low_reg, 0, kThrowDivZero);
+ GenImmedCheck(kCondEq, rl_src2.reg.GetReg(), 0, kThrowDivZero);
}
- rl_result = GenDivRem(rl_dest, rl_src1.low_reg, rl_src2.low_reg, op == kOpDiv);
+ rl_result = GenDivRem(rl_dest, rl_src1.reg.GetReg(), rl_src2.reg.GetReg(), op == kOpDiv);
done = true;
} else if (cu_->instruction_set == kThumb2) {
if (cu_->GetInstructionSetFeatures().HasDivideInstruction()) {
@@ -1523,9 +1523,9 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
if (check_zero) {
- GenImmedCheck(kCondEq, rl_src2.low_reg, 0, kThrowDivZero);
+ GenImmedCheck(kCondEq, rl_src2.reg.GetReg(), 0, kThrowDivZero);
}
- rl_result = GenDivRem(rl_dest, rl_src1.low_reg, rl_src2.low_reg, op == kOpDiv);
+ rl_result = GenDivRem(rl_dest, rl_src1.reg.GetReg(), rl_src2.reg.GetReg(), op == kOpDiv);
done = true;
}
}
@@ -1585,29 +1585,29 @@ bool Mir2Lir::HandleEasyDivRem(Instruction::Code dalvik_opcode, bool is_div,
int t_reg = AllocTemp();
if (lit == 2) {
// Division by 2 is by far the most common division by constant.
- OpRegRegImm(kOpLsr, t_reg, rl_src.low_reg, 32 - k);
- OpRegRegReg(kOpAdd, t_reg, t_reg, rl_src.low_reg);
- OpRegRegImm(kOpAsr, rl_result.low_reg, t_reg, k);
+ OpRegRegImm(kOpLsr, t_reg, rl_src.reg.GetReg(), 32 - k);
+ OpRegRegReg(kOpAdd, t_reg, t_reg, rl_src.reg.GetReg());
+ OpRegRegImm(kOpAsr, rl_result.reg.GetReg(), t_reg, k);
} else {
- OpRegRegImm(kOpAsr, t_reg, rl_src.low_reg, 31);
+ OpRegRegImm(kOpAsr, t_reg, rl_src.reg.GetReg(), 31);
OpRegRegImm(kOpLsr, t_reg, t_reg, 32 - k);
- OpRegRegReg(kOpAdd, t_reg, t_reg, rl_src.low_reg);
- OpRegRegImm(kOpAsr, rl_result.low_reg, t_reg, k);
+ OpRegRegReg(kOpAdd, t_reg, t_reg, rl_src.reg.GetReg());
+ OpRegRegImm(kOpAsr, rl_result.reg.GetReg(), t_reg, k);
}
} else {
int t_reg1 = AllocTemp();
int t_reg2 = AllocTemp();
if (lit == 2) {
- OpRegRegImm(kOpLsr, t_reg1, rl_src.low_reg, 32 - k);
- OpRegRegReg(kOpAdd, t_reg2, t_reg1, rl_src.low_reg);
+ OpRegRegImm(kOpLsr, t_reg1, rl_src.reg.GetReg(), 32 - k);
+ OpRegRegReg(kOpAdd, t_reg2, t_reg1, rl_src.reg.GetReg());
OpRegRegImm(kOpAnd, t_reg2, t_reg2, lit -1);
- OpRegRegReg(kOpSub, rl_result.low_reg, t_reg2, t_reg1);
+ OpRegRegReg(kOpSub, rl_result.reg.GetReg(), t_reg2, t_reg1);
} else {
- OpRegRegImm(kOpAsr, t_reg1, rl_src.low_reg, 31);
+ OpRegRegImm(kOpAsr, t_reg1, rl_src.reg.GetReg(), 31);
OpRegRegImm(kOpLsr, t_reg1, t_reg1, 32 - k);
- OpRegRegReg(kOpAdd, t_reg2, t_reg1, rl_src.low_reg);
+ OpRegRegReg(kOpAdd, t_reg2, t_reg1, rl_src.reg.GetReg());
OpRegRegImm(kOpAnd, t_reg2, t_reg2, lit - 1);
- OpRegRegReg(kOpSub, rl_result.low_reg, t_reg2, t_reg1);
+ OpRegRegReg(kOpSub, rl_result.reg.GetReg(), t_reg2, t_reg1);
}
}
StoreValue(rl_dest, rl_result);
@@ -1637,7 +1637,7 @@ bool Mir2Lir::HandleEasyMultiply(RegLocation rl_src, RegLocation rl_dest, int li
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (power_of_two) {
// Shift.
- OpRegRegImm(kOpLsl, rl_result.low_reg, rl_src.low_reg, LowestSetBit(lit));
+ OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_src.reg.GetReg(), LowestSetBit(lit));
} else if (pop_count_le2) {
// Shift and add and shift.
int first_bit = LowestSetBit(lit);
@@ -1648,8 +1648,8 @@ bool Mir2Lir::HandleEasyMultiply(RegLocation rl_src, RegLocation rl_dest, int li
DCHECK(power_of_two_minus_one);
// TUNING: rsb dst, src, src lsl#LowestSetBit(lit + 1)
int t_reg = AllocTemp();
- OpRegRegImm(kOpLsl, t_reg, rl_src.low_reg, LowestSetBit(lit + 1));
- OpRegRegReg(kOpSub, rl_result.low_reg, t_reg, rl_src.low_reg);
+ OpRegRegImm(kOpLsl, t_reg, rl_src.reg.GetReg(), LowestSetBit(lit + 1));
+ OpRegRegReg(kOpSub, rl_result.reg.GetReg(), t_reg, rl_src.reg.GetReg());
}
StoreValue(rl_dest, rl_result);
return true;
@@ -1668,10 +1668,10 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re
rl_src = LoadValue(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (cu_->instruction_set == kThumb2) {
- OpRegRegImm(kOpRsub, rl_result.low_reg, rl_src.low_reg, lit);
+ OpRegRegImm(kOpRsub, rl_result.reg.GetReg(), rl_src.reg.GetReg(), lit);
} else {
- OpRegReg(kOpNeg, rl_result.low_reg, rl_src.low_reg);
- OpRegImm(kOpAdd, rl_result.low_reg, lit);
+ OpRegReg(kOpNeg, rl_result.reg.GetReg(), rl_src.reg.GetReg());
+ OpRegImm(kOpAdd, rl_result.reg.GetReg(), lit);
}
StoreValue(rl_dest, rl_result);
return;
@@ -1764,7 +1764,7 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re
bool done = false;
if (cu_->instruction_set == kMips) {
rl_src = LoadValue(rl_src, kCoreReg);
- rl_result = GenDivRemLit(rl_dest, rl_src.low_reg, lit, is_div);
+ rl_result = GenDivRemLit(rl_dest, rl_src.reg.GetReg(), lit, is_div);
done = true;
} else if (cu_->instruction_set == kX86) {
rl_result = GenDivRemLit(rl_dest, rl_src, lit, is_div);
@@ -1774,7 +1774,7 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re
// Use ARM SDIV instruction for division. For remainder we also need to
// calculate using a MUL and subtract.
rl_src = LoadValue(rl_src, kCoreReg);
- rl_result = GenDivRemLit(rl_dest, rl_src.low_reg, lit, is_div);
+ rl_result = GenDivRemLit(rl_dest, rl_src.reg.GetReg(), lit, is_div);
done = true;
}
}
@@ -1800,9 +1800,9 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re
rl_result = EvalLoc(rl_dest, kCoreReg, true);
// Avoid shifts by literal 0 - no support in Thumb. Change to copy.
if (shift_op && (lit == 0)) {
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
} else {
- OpRegRegImm(op, rl_result.low_reg, rl_src.low_reg, lit);
+ OpRegRegImm(op, rl_result.reg.GetReg(), rl_src.reg.GetReg(), lit);
}
StoreValue(rl_dest, rl_result);
}
@@ -1822,15 +1822,15 @@ void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
// Check for destructive overlap
- if (rl_result.low_reg == rl_src2.high_reg) {
+ if (rl_result.reg.GetReg() == rl_src2.reg.GetHighReg()) {
int t_reg = AllocTemp();
- OpRegCopy(t_reg, rl_src2.high_reg);
- OpRegReg(kOpMvn, rl_result.low_reg, rl_src2.low_reg);
- OpRegReg(kOpMvn, rl_result.high_reg, t_reg);
+ OpRegCopy(t_reg, rl_src2.reg.GetHighReg());
+ OpRegReg(kOpMvn, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ OpRegReg(kOpMvn, rl_result.reg.GetHighReg(), t_reg);
FreeTemp(t_reg);
} else {
- OpRegReg(kOpMvn, rl_result.low_reg, rl_src2.low_reg);
- OpRegReg(kOpMvn, rl_result.high_reg, rl_src2.high_reg);
+ OpRegReg(kOpMvn, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ OpRegReg(kOpMvn, rl_result.reg.GetHighReg(), rl_src2.reg.GetHighReg());
}
StoreValueWide(rl_dest, rl_result);
return;
@@ -2003,7 +2003,7 @@ void Mir2Lir::GenMonitorExit(int opt_flags, RegLocation rl_src) {
/* Generic code for generating a wide constant into a VR. */
void Mir2Lir::GenConstWide(RegLocation rl_dest, int64_t value) {
RegLocation rl_result = EvalLoc(rl_dest, kAnyReg, true);
- LoadConstantWide(rl_result.low_reg, rl_result.high_reg, value);
+ LoadConstantWide(rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), value);
StoreValueWide(rl_dest, rl_result);
}
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 35d193c65c..dd3d466d94 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -284,9 +284,9 @@ void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) {
*/
RegLocation rl_src = rl_method;
rl_src.location = kLocPhysReg;
- rl_src.low_reg = TargetReg(kArg0);
+ rl_src.reg = RegStorage(RegStorage::k32BitSolo, TargetReg(kArg0));
rl_src.home = false;
- MarkLive(rl_src.low_reg, rl_src.s_reg_low);
+ MarkLive(rl_src.reg.GetReg(), rl_src.s_reg_low);
StoreValue(rl_method, rl_src);
// If Method* has been promoted, explicitly flush
if (rl_method.location == kLocPhysReg) {
@@ -680,7 +680,7 @@ int Mir2Lir::GenDalvikArgsNoRange(CallInfo* info,
// Wide spans, we need the 2nd half of uses[2].
rl_arg = UpdateLocWide(rl_use2);
if (rl_arg.location == kLocPhysReg) {
- reg = rl_arg.high_reg;
+ reg = rl_arg.reg.GetHighReg();
} else {
// kArg2 & rArg3 can safely be used here
reg = TargetReg(kArg3);
@@ -701,8 +701,10 @@ int Mir2Lir::GenDalvikArgsNoRange(CallInfo* info,
rl_arg = info->args[next_use];
rl_arg = UpdateRawLoc(rl_arg);
if (rl_arg.location == kLocPhysReg) {
- low_reg = rl_arg.low_reg;
- high_reg = rl_arg.high_reg;
+ low_reg = rl_arg.reg.GetReg();
+ if (rl_arg.wide) {
+ high_reg = rl_arg.reg.GetHighReg();
+ }
} else {
low_reg = TargetReg(kArg2);
if (rl_arg.wide) {
@@ -775,14 +777,14 @@ int Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state,
loc = UpdateLocWide(loc);
if ((next_arg >= 2) && (loc.location == kLocPhysReg)) {
StoreBaseDispWide(TargetReg(kSp), SRegOffset(loc.s_reg_low),
- loc.low_reg, loc.high_reg);
+ loc.reg.GetReg(), loc.reg.GetHighReg());
}
next_arg += 2;
} else {
loc = UpdateLoc(loc);
if ((next_arg >= 3) && (loc.location == kLocPhysReg)) {
StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low),
- loc.low_reg, kWord);
+ loc.reg.GetReg(), kWord);
}
next_arg++;
}
@@ -983,7 +985,7 @@ bool Mir2Lir::GenInlinedCharAt(CallInfo* info) {
rl_idx = LoadValue(rl_idx, kCoreReg);
}
int reg_max;
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, info->opt_flags);
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), info->opt_flags);
bool range_check = (!(info->opt_flags & MIR_IGNORE_RANGE_CHECK));
LIR* launch_pad = NULL;
int reg_off = INVALID_REG;
@@ -993,15 +995,15 @@ bool Mir2Lir::GenInlinedCharAt(CallInfo* info) {
reg_ptr = AllocTemp();
if (range_check) {
reg_max = AllocTemp();
- LoadWordDisp(rl_obj.low_reg, count_offset, reg_max);
+ LoadWordDisp(rl_obj.reg.GetReg(), count_offset, reg_max);
}
- LoadWordDisp(rl_obj.low_reg, offset_offset, reg_off);
- LoadWordDisp(rl_obj.low_reg, value_offset, reg_ptr);
+ LoadWordDisp(rl_obj.reg.GetReg(), offset_offset, reg_off);
+ LoadWordDisp(rl_obj.reg.GetReg(), value_offset, reg_ptr);
if (range_check) {
// Set up a launch pad to allow retry in case of bounds violation */
launch_pad = RawLIR(0, kPseudoIntrinsicRetry, WrapPointer(info));
intrinsic_launchpads_.Insert(launch_pad);
- OpRegReg(kOpCmp, rl_idx.low_reg, reg_max);
+ OpRegReg(kOpCmp, rl_idx.reg.GetReg(), reg_max);
FreeTemp(reg_max);
OpCondBranch(kCondUge, launch_pad);
}
@@ -1013,33 +1015,33 @@ bool Mir2Lir::GenInlinedCharAt(CallInfo* info) {
launch_pad = RawLIR(0, kPseudoIntrinsicRetry, WrapPointer(info));
intrinsic_launchpads_.Insert(launch_pad);
if (rl_idx.is_const) {
- OpCmpMemImmBranch(kCondUlt, INVALID_REG, rl_obj.low_reg, count_offset,
+ OpCmpMemImmBranch(kCondUlt, INVALID_REG, rl_obj.reg.GetReg(), count_offset,
mir_graph_->ConstantValue(rl_idx.orig_sreg), launch_pad);
} else {
- OpRegMem(kOpCmp, rl_idx.low_reg, rl_obj.low_reg, count_offset);
+ OpRegMem(kOpCmp, rl_idx.reg.GetReg(), rl_obj.reg.GetReg(), count_offset);
OpCondBranch(kCondUge, launch_pad);
}
}
reg_off = AllocTemp();
reg_ptr = AllocTemp();
- LoadWordDisp(rl_obj.low_reg, offset_offset, reg_off);
- LoadWordDisp(rl_obj.low_reg, value_offset, reg_ptr);
+ LoadWordDisp(rl_obj.reg.GetReg(), offset_offset, reg_off);
+ LoadWordDisp(rl_obj.reg.GetReg(), value_offset, reg_ptr);
}
if (rl_idx.is_const) {
OpRegImm(kOpAdd, reg_off, mir_graph_->ConstantValue(rl_idx.orig_sreg));
} else {
- OpRegReg(kOpAdd, reg_off, rl_idx.low_reg);
+ OpRegReg(kOpAdd, reg_off, rl_idx.reg.GetReg());
}
- FreeTemp(rl_obj.low_reg);
- if (rl_idx.low_reg != INVALID_REG) {
- FreeTemp(rl_idx.low_reg);
+ FreeTemp(rl_obj.reg.GetReg());
+ if (rl_idx.location == kLocPhysReg) {
+ FreeTemp(rl_idx.reg.GetReg());
}
RegLocation rl_dest = InlineTarget(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (cu_->instruction_set != kX86) {
- LoadBaseIndexed(reg_ptr, reg_off, rl_result.low_reg, 1, kUnsignedHalf);
+ LoadBaseIndexed(reg_ptr, reg_off, rl_result.reg.GetReg(), 1, kUnsignedHalf);
} else {
- LoadBaseIndexedDisp(reg_ptr, reg_off, 1, data_offset, rl_result.low_reg,
+ LoadBaseIndexedDisp(reg_ptr, reg_off, 1, data_offset, rl_result.reg.GetReg(),
INVALID_REG, kUnsignedHalf, INVALID_SREG);
}
FreeTemp(reg_off);
@@ -1064,18 +1066,18 @@ bool Mir2Lir::GenInlinedStringIsEmptyOrLength(CallInfo* info, bool is_empty) {
rl_obj = LoadValue(rl_obj, kCoreReg);
RegLocation rl_dest = InlineTarget(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- GenNullCheck(rl_obj.s_reg_low, rl_obj.low_reg, info->opt_flags);
- LoadWordDisp(rl_obj.low_reg, mirror::String::CountOffset().Int32Value(), rl_result.low_reg);
+ GenNullCheck(rl_obj.s_reg_low, rl_obj.reg.GetReg(), info->opt_flags);
+ LoadWordDisp(rl_obj.reg.GetReg(), mirror::String::CountOffset().Int32Value(), rl_result.reg.GetReg());
if (is_empty) {
// dst = (dst == 0);
if (cu_->instruction_set == kThumb2) {
int t_reg = AllocTemp();
- OpRegReg(kOpNeg, t_reg, rl_result.low_reg);
- OpRegRegReg(kOpAdc, rl_result.low_reg, rl_result.low_reg, t_reg);
+ OpRegReg(kOpNeg, t_reg, rl_result.reg.GetReg());
+ OpRegRegReg(kOpAdc, rl_result.reg.GetReg(), rl_result.reg.GetReg(), t_reg);
} else {
DCHECK_EQ(cu_->instruction_set, kX86);
- OpRegImm(kOpSub, rl_result.low_reg, 1);
- OpRegImm(kOpLsr, rl_result.low_reg, 31);
+ OpRegImm(kOpSub, rl_result.reg.GetReg(), 1);
+ OpRegImm(kOpLsr, rl_result.reg.GetReg(), 31);
}
}
StoreValue(rl_dest, rl_result);
@@ -1092,15 +1094,15 @@ bool Mir2Lir::GenInlinedReverseBytes(CallInfo* info, OpSize size) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (size == kLong) {
RegLocation rl_i = LoadValueWide(rl_src_i, kCoreReg);
- int r_i_low = rl_i.low_reg;
- if (rl_i.low_reg == rl_result.low_reg) {
- // First REV shall clobber rl_result.low_reg, save the value in a temp for the second REV.
+ int r_i_low = rl_i.reg.GetReg();
+ if (rl_i.reg.GetReg() == rl_result.reg.GetReg()) {
+ // First REV shall clobber rl_result.reg.GetReg(), save the value in a temp for the second REV.
r_i_low = AllocTemp();
- OpRegCopy(r_i_low, rl_i.low_reg);
+ OpRegCopy(r_i_low, rl_i.reg.GetReg());
}
- OpRegReg(kOpRev, rl_result.low_reg, rl_i.high_reg);
- OpRegReg(kOpRev, rl_result.high_reg, r_i_low);
- if (rl_i.low_reg == rl_result.low_reg) {
+ OpRegReg(kOpRev, rl_result.reg.GetReg(), rl_i.reg.GetHighReg());
+ OpRegReg(kOpRev, rl_result.reg.GetHighReg(), r_i_low);
+ if (rl_i.reg.GetReg() == rl_result.reg.GetReg()) {
FreeTemp(r_i_low);
}
StoreValueWide(rl_dest, rl_result);
@@ -1108,7 +1110,7 @@ bool Mir2Lir::GenInlinedReverseBytes(CallInfo* info, OpSize size) {
DCHECK(size == kWord || size == kSignedHalf);
OpKind op = (size == kWord) ? kOpRev : kOpRevsh;
RegLocation rl_i = LoadValue(rl_src_i, kCoreReg);
- OpRegReg(op, rl_result.low_reg, rl_i.low_reg);
+ OpRegReg(op, rl_result.reg.GetReg(), rl_i.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
return true;
@@ -1125,9 +1127,9 @@ bool Mir2Lir::GenInlinedAbsInt(CallInfo* info) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
int sign_reg = AllocTemp();
// abs(x) = y<=x>>31, (x+y)^y.
- OpRegRegImm(kOpAsr, sign_reg, rl_src.low_reg, 31);
- OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, sign_reg);
- OpRegReg(kOpXor, rl_result.low_reg, sign_reg);
+ OpRegRegImm(kOpAsr, sign_reg, rl_src.reg.GetReg(), 31);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), sign_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetReg(), sign_reg);
StoreValue(rl_dest, rl_result);
return true;
}
@@ -1144,11 +1146,11 @@ bool Mir2Lir::GenInlinedAbsLong(CallInfo* info) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
int sign_reg = AllocTemp();
// abs(x) = y<=x>>31, (x+y)^y.
- OpRegRegImm(kOpAsr, sign_reg, rl_src.high_reg, 31);
- OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, sign_reg);
- OpRegRegReg(kOpAdc, rl_result.high_reg, rl_src.high_reg, sign_reg);
- OpRegReg(kOpXor, rl_result.low_reg, sign_reg);
- OpRegReg(kOpXor, rl_result.high_reg, sign_reg);
+ OpRegRegImm(kOpAsr, sign_reg, rl_src.reg.GetHighReg(), 31);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), sign_reg);
+ OpRegRegReg(kOpAdc, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), sign_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetReg(), sign_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetHighReg(), sign_reg);
StoreValueWide(rl_dest, rl_result);
return true;
} else {
@@ -1158,16 +1160,16 @@ bool Mir2Lir::GenInlinedAbsLong(CallInfo* info) {
rl_src = LoadValueWide(rl_src, kCoreReg);
RegLocation rl_dest = InlineTargetWide(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegCopyWide(rl_result.low_reg, rl_result.high_reg, rl_src.low_reg, rl_src.high_reg);
- FreeTemp(rl_src.low_reg);
- FreeTemp(rl_src.high_reg);
+ OpRegCopyWide(rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
+ FreeTemp(rl_src.reg.GetReg());
+ FreeTemp(rl_src.reg.GetHighReg());
int sign_reg = AllocTemp();
// abs(x) = y<=x>>31, (x+y)^y.
- OpRegRegImm(kOpAsr, sign_reg, rl_result.high_reg, 31);
- OpRegReg(kOpAdd, rl_result.low_reg, sign_reg);
- OpRegReg(kOpAdc, rl_result.high_reg, sign_reg);
- OpRegReg(kOpXor, rl_result.low_reg, sign_reg);
- OpRegReg(kOpXor, rl_result.high_reg, sign_reg);
+ OpRegRegImm(kOpAsr, sign_reg, rl_result.reg.GetHighReg(), 31);
+ OpRegReg(kOpAdd, rl_result.reg.GetReg(), sign_reg);
+ OpRegReg(kOpAdc, rl_result.reg.GetHighReg(), sign_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetReg(), sign_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetHighReg(), sign_reg);
StoreValueWide(rl_dest, rl_result);
return true;
}
@@ -1184,7 +1186,7 @@ bool Mir2Lir::GenInlinedAbsFloat(CallInfo* info) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
int signMask = AllocTemp();
LoadConstant(signMask, 0x7fffffff);
- OpRegRegReg(kOpAnd, rl_result.low_reg, rl_src.low_reg, signMask);
+ OpRegRegReg(kOpAnd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), signMask);
FreeTemp(signMask);
StoreValue(rl_dest, rl_result);
return true;
@@ -1199,12 +1201,12 @@ bool Mir2Lir::GenInlinedAbsDouble(CallInfo* info) {
rl_src = LoadValueWide(rl_src, kCoreReg);
RegLocation rl_dest = InlineTargetWide(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegCopyWide(rl_result.low_reg, rl_result.high_reg, rl_src.low_reg, rl_src.high_reg);
- FreeTemp(rl_src.low_reg);
- FreeTemp(rl_src.high_reg);
+ OpRegCopyWide(rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
+ FreeTemp(rl_src.reg.GetReg());
+ FreeTemp(rl_src.reg.GetHighReg());
int signMask = AllocTemp();
LoadConstant(signMask, 0x7fffffff);
- OpRegReg(kOpAnd, rl_result.high_reg, signMask);
+ OpRegReg(kOpAnd, rl_result.reg.GetHighReg(), signMask);
FreeTemp(signMask);
StoreValueWide(rl_dest, rl_result);
return true;
@@ -1316,10 +1318,10 @@ bool Mir2Lir::GenInlinedCurrentThread(CallInfo* info) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
ThreadOffset offset = Thread::PeerOffset();
if (cu_->instruction_set == kThumb2 || cu_->instruction_set == kMips) {
- LoadWordDisp(TargetReg(kSelf), offset.Int32Value(), rl_result.low_reg);
+ LoadWordDisp(TargetReg(kSelf), offset.Int32Value(), rl_result.reg.GetReg());
} else {
CHECK(cu_->instruction_set == kX86);
- reinterpret_cast<X86Mir2Lir*>(this)->OpRegThreadMem(kOpMov, rl_result.low_reg, offset);
+ reinterpret_cast<X86Mir2Lir*>(this)->OpRegThreadMem(kOpMov, rl_result.reg.GetReg(), offset);
}
StoreValue(rl_dest, rl_result);
return true;
@@ -1343,11 +1345,11 @@ bool Mir2Lir::GenInlinedUnsafeGet(CallInfo* info,
RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_long) {
- OpRegReg(kOpAdd, rl_object.low_reg, rl_offset.low_reg);
- LoadBaseDispWide(rl_object.low_reg, 0, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+ OpRegReg(kOpAdd, rl_object.reg.GetReg(), rl_offset.reg.GetReg());
+ LoadBaseDispWide(rl_object.reg.GetReg(), 0, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
StoreValueWide(rl_dest, rl_result);
} else {
- LoadBaseIndexed(rl_object.low_reg, rl_offset.low_reg, rl_result.low_reg, 0, kWord);
+ LoadBaseIndexed(rl_object.reg.GetReg(), rl_offset.reg.GetReg(), rl_result.reg.GetReg(), 0, kWord);
StoreValue(rl_dest, rl_result);
}
return true;
@@ -1372,20 +1374,20 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long,
RegLocation rl_value;
if (is_long) {
rl_value = LoadValueWide(rl_src_value, kCoreReg);
- OpRegReg(kOpAdd, rl_object.low_reg, rl_offset.low_reg);
- StoreBaseDispWide(rl_object.low_reg, 0, rl_value.low_reg, rl_value.high_reg);
+ OpRegReg(kOpAdd, rl_object.reg.GetReg(), rl_offset.reg.GetReg());
+ StoreBaseDispWide(rl_object.reg.GetReg(), 0, rl_value.reg.GetReg(), rl_value.reg.GetHighReg());
} else {
rl_value = LoadValue(rl_src_value, kCoreReg);
- StoreBaseIndexed(rl_object.low_reg, rl_offset.low_reg, rl_value.low_reg, 0, kWord);
+ StoreBaseIndexed(rl_object.reg.GetReg(), rl_offset.reg.GetReg(), rl_value.reg.GetReg(), 0, kWord);
}
// Free up the temp early, to ensure x86 doesn't run out of temporaries in MarkGCCard.
- FreeTemp(rl_offset.low_reg);
+ FreeTemp(rl_offset.reg.GetReg());
if (is_volatile) {
GenMemBarrier(kStoreLoad);
}
if (is_object) {
- MarkGCCard(rl_value.low_reg, rl_object.low_reg);
+ MarkGCCard(rl_value.reg.GetReg(), rl_object.reg.GetReg());
}
return true;
}
diff --git a/compiler/dex/quick/gen_loadstore.cc b/compiler/dex/quick/gen_loadstore.cc
index f7c2821afd..53c47f5975 100644
--- a/compiler/dex/quick/gen_loadstore.cc
+++ b/compiler/dex/quick/gen_loadstore.cc
@@ -92,7 +92,7 @@ LIR* Mir2Lir::StoreWordDisp(int rBase, int displacement, int r_src) {
void Mir2Lir::LoadValueDirect(RegLocation rl_src, int r_dest) {
rl_src = UpdateLoc(rl_src);
if (rl_src.location == kLocPhysReg) {
- OpRegCopy(r_dest, rl_src.low_reg);
+ OpRegCopy(r_dest, rl_src.reg.GetReg());
} else if (IsInexpensiveConstant(rl_src)) {
LoadConstantNoClobber(r_dest, mir_graph_->ConstantValue(rl_src));
} else {
@@ -122,7 +122,7 @@ void Mir2Lir::LoadValueDirectWide(RegLocation rl_src, int reg_lo,
int reg_hi) {
rl_src = UpdateLocWide(rl_src);
if (rl_src.location == kLocPhysReg) {
- OpRegCopyWide(reg_lo, reg_hi, rl_src.low_reg, rl_src.high_reg);
+ OpRegCopyWide(reg_lo, reg_hi, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else if (IsInexpensiveConstant(rl_src)) {
LoadConstantWide(reg_lo, reg_hi, mir_graph_->ConstantValueWide(rl_src));
} else {
@@ -150,9 +150,9 @@ void Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, int reg_lo,
RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
rl_src = EvalLoc(rl_src, op_kind, false);
if (IsInexpensiveConstant(rl_src) || rl_src.location != kLocPhysReg) {
- LoadValueDirect(rl_src, rl_src.low_reg);
+ LoadValueDirect(rl_src, rl_src.reg.GetReg());
rl_src.location = kLocPhysReg;
- MarkLive(rl_src.low_reg, rl_src.s_reg_low);
+ MarkLive(rl_src.reg.GetReg(), rl_src.s_reg_low);
}
return rl_src;
}
@@ -175,34 +175,34 @@ void Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
rl_src = UpdateLoc(rl_src);
rl_dest = UpdateLoc(rl_dest);
if (rl_src.location == kLocPhysReg) {
- if (IsLive(rl_src.low_reg) ||
- IsPromoted(rl_src.low_reg) ||
+ if (IsLive(rl_src.reg.GetReg()) ||
+ IsPromoted(rl_src.reg.GetReg()) ||
(rl_dest.location == kLocPhysReg)) {
// Src is live/promoted or Dest has assigned reg.
rl_dest = EvalLoc(rl_dest, kAnyReg, false);
- OpRegCopy(rl_dest.low_reg, rl_src.low_reg);
+ OpRegCopy(rl_dest.reg.GetReg(), rl_src.reg.GetReg());
} else {
// Just re-assign the registers. Dest gets Src's regs
- rl_dest.low_reg = rl_src.low_reg;
- Clobber(rl_src.low_reg);
+ rl_dest.reg = rl_src.reg;
+ Clobber(rl_src.reg.GetReg());
}
} else {
// Load Src either into promoted Dest or temps allocated for Dest
rl_dest = EvalLoc(rl_dest, kAnyReg, false);
- LoadValueDirect(rl_src, rl_dest.low_reg);
+ LoadValueDirect(rl_src, rl_dest.reg.GetReg());
}
// Dest is now live and dirty (until/if we flush it to home location)
- MarkLive(rl_dest.low_reg, rl_dest.s_reg_low);
+ MarkLive(rl_dest.reg.GetReg(), rl_dest.s_reg_low);
MarkDirty(rl_dest);
ResetDefLoc(rl_dest);
- if (IsDirty(rl_dest.low_reg) &&
+ if (IsDirty(rl_dest.reg.GetReg()) &&
oat_live_out(rl_dest.s_reg_low)) {
def_start = last_lir_insn_;
StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low),
- rl_dest.low_reg, kWord);
+ rl_dest.reg.GetReg(), kWord);
MarkClean(rl_dest);
def_end = last_lir_insn_;
if (!rl_dest.ref) {
@@ -216,10 +216,10 @@ RegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
DCHECK(rl_src.wide);
rl_src = EvalLoc(rl_src, op_kind, false);
if (IsInexpensiveConstant(rl_src) || rl_src.location != kLocPhysReg) {
- LoadValueDirectWide(rl_src, rl_src.low_reg, rl_src.high_reg);
+ LoadValueDirectWide(rl_src, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
rl_src.location = kLocPhysReg;
- MarkLive(rl_src.low_reg, rl_src.s_reg_low);
- MarkLive(rl_src.high_reg, GetSRegHi(rl_src.s_reg_low));
+ MarkLive(rl_src.reg.GetReg(), rl_src.s_reg_low);
+ MarkLive(rl_src.reg.GetHighReg(), GetSRegHi(rl_src.s_reg_low));
}
return rl_src;
}
@@ -237,57 +237,57 @@ void Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
}
LIR* def_start;
LIR* def_end;
- DCHECK_EQ(IsFpReg(rl_src.low_reg), IsFpReg(rl_src.high_reg));
+ DCHECK((rl_src.location != kLocPhysReg) ||
+ (IsFpReg(rl_src.reg.GetReg()) == IsFpReg(rl_src.reg.GetHighReg())));
DCHECK(rl_dest.wide);
DCHECK(rl_src.wide);
if (rl_src.location == kLocPhysReg) {
- if (IsLive(rl_src.low_reg) ||
- IsLive(rl_src.high_reg) ||
- IsPromoted(rl_src.low_reg) ||
- IsPromoted(rl_src.high_reg) ||
+ if (IsLive(rl_src.reg.GetReg()) ||
+ IsLive(rl_src.reg.GetHighReg()) ||
+ IsPromoted(rl_src.reg.GetReg()) ||
+ IsPromoted(rl_src.reg.GetHighReg()) ||
(rl_dest.location == kLocPhysReg)) {
// Src is live or promoted or Dest has assigned reg.
rl_dest = EvalLoc(rl_dest, kAnyReg, false);
- OpRegCopyWide(rl_dest.low_reg, rl_dest.high_reg,
- rl_src.low_reg, rl_src.high_reg);
+ OpRegCopyWide(rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg(),
+ rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
// Just re-assign the registers. Dest gets Src's regs
- rl_dest.low_reg = rl_src.low_reg;
- rl_dest.high_reg = rl_src.high_reg;
- Clobber(rl_src.low_reg);
- Clobber(rl_src.high_reg);
+ rl_dest.reg = rl_src.reg;
+ Clobber(rl_src.reg.GetReg());
+ Clobber(rl_src.reg.GetHighReg());
}
} else {
// Load Src either into promoted Dest or temps allocated for Dest
rl_dest = EvalLoc(rl_dest, kAnyReg, false);
- LoadValueDirectWide(rl_src, rl_dest.low_reg, rl_dest.high_reg);
+ LoadValueDirectWide(rl_src, rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg());
}
// Dest is now live and dirty (until/if we flush it to home location)
- MarkLive(rl_dest.low_reg, rl_dest.s_reg_low);
+ MarkLive(rl_dest.reg.GetReg(), rl_dest.s_reg_low);
// Does this wide value live in two registers (or one vector one)?
- if (rl_dest.low_reg != rl_dest.high_reg) {
- MarkLive(rl_dest.high_reg, GetSRegHi(rl_dest.s_reg_low));
+ if (rl_dest.reg.GetReg() != rl_dest.reg.GetHighReg()) {
+ MarkLive(rl_dest.reg.GetHighReg(), GetSRegHi(rl_dest.s_reg_low));
MarkDirty(rl_dest);
- MarkPair(rl_dest.low_reg, rl_dest.high_reg);
+ MarkPair(rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg());
} else {
// This must be an x86 vector register value,
- DCHECK(IsFpReg(rl_dest.low_reg) && (cu_->instruction_set == kX86));
+ DCHECK(IsFpReg(rl_dest.reg.GetReg()) && (cu_->instruction_set == kX86));
MarkDirty(rl_dest);
}
ResetDefLocWide(rl_dest);
- if ((IsDirty(rl_dest.low_reg) ||
- IsDirty(rl_dest.high_reg)) &&
+ if ((IsDirty(rl_dest.reg.GetReg()) ||
+ IsDirty(rl_dest.reg.GetHighReg())) &&
(oat_live_out(rl_dest.s_reg_low) ||
oat_live_out(GetSRegHi(rl_dest.s_reg_low)))) {
def_start = last_lir_insn_;
DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
StoreBaseDispWide(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low),
- rl_dest.low_reg, rl_dest.high_reg);
+ rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg());
MarkClean(rl_dest);
def_end = last_lir_insn_;
MarkDefWide(rl_dest, def_start, def_end);
@@ -298,25 +298,25 @@ void Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
DCHECK_EQ(rl_src.location, kLocPhysReg);
if (rl_dest.location == kLocPhysReg) {
- OpRegCopy(rl_dest.low_reg, rl_src.low_reg);
+ OpRegCopy(rl_dest.reg.GetReg(), rl_src.reg.GetReg());
} else {
// Just re-assign the register. Dest gets Src's reg.
- rl_dest.low_reg = rl_src.low_reg;
rl_dest.location = kLocPhysReg;
- Clobber(rl_src.low_reg);
+ rl_dest.reg = rl_src.reg;
+ Clobber(rl_src.reg.GetReg());
}
// Dest is now live and dirty (until/if we flush it to home location)
- MarkLive(rl_dest.low_reg, rl_dest.s_reg_low);
+ MarkLive(rl_dest.reg.GetReg(), rl_dest.s_reg_low);
MarkDirty(rl_dest);
ResetDefLoc(rl_dest);
- if (IsDirty(rl_dest.low_reg) &&
+ if (IsDirty(rl_dest.reg.GetReg()) &&
oat_live_out(rl_dest.s_reg_low)) {
LIR *def_start = last_lir_insn_;
StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low),
- rl_dest.low_reg, kWord);
+ rl_dest.reg.GetReg(), kWord);
MarkClean(rl_dest);
LIR *def_end = last_lir_insn_;
if (!rl_dest.ref) {
@@ -327,46 +327,45 @@ void Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
}
void Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
- DCHECK_EQ(IsFpReg(rl_src.low_reg), IsFpReg(rl_src.high_reg));
+ DCHECK_EQ(IsFpReg(rl_src.reg.GetReg()), IsFpReg(rl_src.reg.GetHighReg()));
DCHECK(rl_dest.wide);
DCHECK(rl_src.wide);
DCHECK_EQ(rl_src.location, kLocPhysReg);
if (rl_dest.location == kLocPhysReg) {
- OpRegCopyWide(rl_dest.low_reg, rl_dest.high_reg, rl_src.low_reg, rl_src.high_reg);
+ OpRegCopyWide(rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg(), rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
// Just re-assign the registers. Dest gets Src's regs.
- rl_dest.low_reg = rl_src.low_reg;
- rl_dest.high_reg = rl_src.high_reg;
rl_dest.location = kLocPhysReg;
- Clobber(rl_src.low_reg);
- Clobber(rl_src.high_reg);
+ rl_dest.reg = rl_src.reg;
+ Clobber(rl_src.reg.GetReg());
+ Clobber(rl_src.reg.GetHighReg());
}
// Dest is now live and dirty (until/if we flush it to home location).
- MarkLive(rl_dest.low_reg, rl_dest.s_reg_low);
+ MarkLive(rl_dest.reg.GetReg(), rl_dest.s_reg_low);
// Does this wide value live in two registers (or one vector one)?
- if (rl_dest.low_reg != rl_dest.high_reg) {
- MarkLive(rl_dest.high_reg, GetSRegHi(rl_dest.s_reg_low));
+ if (rl_dest.reg.GetReg() != rl_dest.reg.GetHighReg()) {
+ MarkLive(rl_dest.reg.GetHighReg(), GetSRegHi(rl_dest.s_reg_low));
MarkDirty(rl_dest);
- MarkPair(rl_dest.low_reg, rl_dest.high_reg);
+ MarkPair(rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg());
} else {
// This must be an x86 vector register value,
- DCHECK(IsFpReg(rl_dest.low_reg) && (cu_->instruction_set == kX86));
+ DCHECK(IsFpReg(rl_dest.reg.GetReg()) && (cu_->instruction_set == kX86));
MarkDirty(rl_dest);
}
ResetDefLocWide(rl_dest);
- if ((IsDirty(rl_dest.low_reg) ||
- IsDirty(rl_dest.high_reg)) &&
+ if ((IsDirty(rl_dest.reg.GetReg()) ||
+ IsDirty(rl_dest.reg.GetHighReg())) &&
(oat_live_out(rl_dest.s_reg_low) ||
oat_live_out(GetSRegHi(rl_dest.s_reg_low)))) {
LIR *def_start = last_lir_insn_;
DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
StoreBaseDispWide(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low),
- rl_dest.low_reg, rl_dest.high_reg);
+ rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg());
MarkClean(rl_dest);
LIR *def_end = last_lir_insn_;
MarkDefWide(rl_dest, def_start, def_end);
@@ -385,14 +384,13 @@ RegLocation Mir2Lir::LoadCurrMethod() {
RegLocation Mir2Lir::ForceTemp(RegLocation loc) {
DCHECK(!loc.wide);
DCHECK(loc.location == kLocPhysReg);
- DCHECK(!IsFpReg(loc.low_reg));
- DCHECK(!IsFpReg(loc.high_reg));
- if (IsTemp(loc.low_reg)) {
- Clobber(loc.low_reg);
+ DCHECK(!IsFpReg(loc.reg.GetReg()));
+ if (IsTemp(loc.reg.GetReg())) {
+ Clobber(loc.reg.GetReg());
} else {
int temp_low = AllocTemp();
- OpRegCopy(temp_low, loc.low_reg);
- loc.low_reg = temp_low;
+ OpRegCopy(temp_low, loc.reg.GetReg());
+ loc.reg.SetReg(temp_low);
}
// Ensure that this doesn't represent the original SR any more.
@@ -403,21 +401,21 @@ RegLocation Mir2Lir::ForceTemp(RegLocation loc) {
RegLocation Mir2Lir::ForceTempWide(RegLocation loc) {
DCHECK(loc.wide);
DCHECK(loc.location == kLocPhysReg);
- DCHECK(!IsFpReg(loc.low_reg));
- DCHECK(!IsFpReg(loc.high_reg));
- if (IsTemp(loc.low_reg)) {
- Clobber(loc.low_reg);
+ DCHECK(!IsFpReg(loc.reg.GetReg()));
+ DCHECK(!IsFpReg(loc.reg.GetHighReg()));
+ if (IsTemp(loc.reg.GetReg())) {
+ Clobber(loc.reg.GetReg());
} else {
int temp_low = AllocTemp();
- OpRegCopy(temp_low, loc.low_reg);
- loc.low_reg = temp_low;
+ OpRegCopy(temp_low, loc.reg.GetReg());
+ loc.reg.SetReg(temp_low);
}
- if (IsTemp(loc.high_reg)) {
- Clobber(loc.high_reg);
+ if (IsTemp(loc.reg.GetHighReg())) {
+ Clobber(loc.reg.GetHighReg());
} else {
int temp_high = AllocTemp();
- OpRegCopy(temp_high, loc.high_reg);
- loc.high_reg = temp_high;
+ OpRegCopy(temp_high, loc.reg.GetHighReg());
+ loc.reg.SetHighReg(temp_high);
}
// Ensure that this doesn't represent the original SR any more.
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index a663519b82..88f46fd59a 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -114,7 +114,7 @@ void MipsMir2Lir::GenSparseSwitch(MIR* mir, DexOffset table_offset,
LIR* exit_branch = OpCmpBranch(kCondEq, rBase, rEnd, NULL);
LoadWordDisp(rBase, 0, r_key);
OpRegImm(kOpAdd, rBase, 8);
- OpCmpBranch(kCondNe, rl_src.low_reg, r_key, loop_label);
+ 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);
@@ -162,7 +162,7 @@ void MipsMir2Lir::GenPackedSwitch(MIR* mir, DexOffset table_offset,
bool large_bias = false;
int r_key;
if (low_key == 0) {
- r_key = rl_src.low_reg;
+ r_key = rl_src.reg.GetReg();
} else if ((low_key & 0xffff) != low_key) {
r_key = AllocTemp();
LoadConstant(r_key, low_key);
@@ -179,9 +179,9 @@ void MipsMir2Lir::GenPackedSwitch(MIR* mir, DexOffset table_offset,
NewLIR0(kMipsNop);
} else {
if (large_bias) {
- OpRegRegReg(kOpSub, r_key, rl_src.low_reg, r_key);
+ OpRegRegReg(kOpSub, r_key, rl_src.reg.GetReg(), r_key);
} else {
- OpRegRegImm(kOpSub, r_key, rl_src.low_reg, low_key);
+ OpRegRegImm(kOpSub, r_key, rl_src.reg.GetReg(), low_key);
}
}
GenBarrier(); // Scheduling barrier
@@ -263,7 +263,7 @@ 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.low_reg);
+ LoadWordDisp(rMIPS_SELF, ex_offset, rl_result.reg.GetReg());
LoadConstant(reset_reg, 0);
StoreWordDisp(rMIPS_SELF, ex_offset, reset_reg);
FreeTemp(reset_reg);
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index dad8a3b492..61eb68dc21 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -49,7 +49,7 @@ class MipsMir2Lir : public Mir2Lir {
bool IsFpReg(int reg);
bool SameRegType(int reg1, int reg2);
int AllocTypedTemp(bool fp_hint, int reg_class);
- int AllocTypedTempPair(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);
diff --git a/compiler/dex/quick/mips/fp_mips.cc b/compiler/dex/quick/mips/fp_mips.cc
index 9e2fea94de..cf4f19f84c 100644
--- a/compiler/dex/quick/mips/fp_mips.cc
+++ b/compiler/dex/quick/mips/fp_mips.cc
@@ -64,7 +64,7 @@ void MipsMir2Lir::GenArithOpFloat(Instruction::Code opcode,
rl_src1 = LoadValue(rl_src1, kFPReg);
rl_src2 = LoadValue(rl_src2, kFPReg);
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR3(op, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
+ NewLIR3(op, rl_result.reg.GetReg(), rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
@@ -111,8 +111,8 @@ void MipsMir2Lir::GenArithOpDouble(Instruction::Code opcode,
rl_result = EvalLoc(rl_dest, kFPReg, true);
DCHECK(rl_dest.wide);
DCHECK(rl_result.wide);
- NewLIR3(op, S2d(rl_result.low_reg, rl_result.high_reg), S2d(rl_src1.low_reg, rl_src1.high_reg),
- S2d(rl_src2.low_reg, rl_src2.high_reg));
+ 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()));
StoreValueWide(rl_dest, rl_result);
}
@@ -157,18 +157,18 @@ void MipsMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
}
if (rl_src.wide) {
rl_src = LoadValueWide(rl_src, kFPReg);
- src_reg = S2d(rl_src.low_reg, rl_src.high_reg);
+ src_reg = S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
rl_src = LoadValue(rl_src, kFPReg);
- src_reg = rl_src.low_reg;
+ src_reg = rl_src.reg.GetReg();
}
if (rl_dest.wide) {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg);
+ NewLIR2(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), src_reg);
StoreValueWide(rl_dest, rl_result);
} else {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, rl_result.low_reg, src_reg);
+ NewLIR2(op, rl_result.reg.GetReg(), src_reg);
StoreValue(rl_dest, rl_result);
}
}
@@ -221,7 +221,7 @@ void MipsMir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValue(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpAdd, rl_result.low_reg, rl_src.low_reg, 0x80000000);
+ OpRegRegImm(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0x80000000);
StoreValue(rl_dest, rl_result);
}
@@ -229,8 +229,8 @@ void MipsMir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValueWide(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpAdd, rl_result.high_reg, rl_src.high_reg, 0x80000000);
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
+ OpRegRegImm(kOpAdd, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), 0x80000000);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
StoreValueWide(rl_dest, rl_result);
}
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 013041a9a5..fec801bb4a 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -47,13 +47,13 @@ void MipsMir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1,
int t0 = AllocTemp();
int t1 = AllocTemp();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- NewLIR3(kMipsSlt, t0, rl_src1.high_reg, rl_src2.high_reg);
- NewLIR3(kMipsSlt, t1, rl_src2.high_reg, rl_src1.high_reg);
- NewLIR3(kMipsSubu, rl_result.low_reg, t1, t0);
- LIR* branch = OpCmpImmBranch(kCondNe, rl_result.low_reg, 0, NULL);
- NewLIR3(kMipsSltu, t0, rl_src1.low_reg, rl_src2.low_reg);
- NewLIR3(kMipsSltu, t1, rl_src2.low_reg, rl_src1.low_reg);
- NewLIR3(kMipsSubu, rl_result.low_reg, t1, t0);
+ 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());
+ NewLIR3(kMipsSubu, rl_result.reg.GetReg(), t1, t0);
FreeTemp(t0);
FreeTemp(t1);
LIR* target = NewLIR0(kPseudoTargetLabel);
@@ -228,9 +228,9 @@ RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, int reg1, int reg2,
NewLIR4(kMipsDiv, r_HI, r_LO, reg1, reg2);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_div) {
- NewLIR2(kMipsMflo, rl_result.low_reg, r_LO);
+ NewLIR2(kMipsMflo, rl_result.reg.GetReg(), r_LO);
} else {
- NewLIR2(kMipsMfhi, rl_result.low_reg, r_HI);
+ NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), r_HI);
}
return rl_result;
}
@@ -242,9 +242,9 @@ RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, int reg1, int lit,
NewLIR4(kMipsDiv, r_HI, r_LO, reg1, t_reg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (is_div) {
- NewLIR2(kMipsMflo, rl_result.low_reg, r_LO);
+ NewLIR2(kMipsMflo, rl_result.reg.GetReg(), r_LO);
} else {
- NewLIR2(kMipsMfhi, rl_result.low_reg, r_HI);
+ NewLIR2(kMipsMfhi, rl_result.reg.GetReg(), r_HI);
}
FreeTemp(t_reg);
return rl_result;
@@ -290,7 +290,7 @@ bool MipsMir2Lir::GenInlinedPeek(CallInfo* info, OpSize size) {
RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
DCHECK(size == kSignedByte);
- LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, size, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), size, INVALID_SREG);
StoreValue(rl_dest, rl_result);
return true;
}
@@ -306,7 +306,7 @@ bool MipsMir2Lir::GenInlinedPoke(CallInfo* info, OpSize size) {
RegLocation rl_address = LoadValue(rl_src_address, kCoreReg);
DCHECK(size == kSignedByte);
RegLocation rl_value = LoadValue(rl_src_value, kCoreReg);
- StoreBaseDisp(rl_address.low_reg, 0, rl_value.low_reg, size);
+ StoreBaseDisp(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), size);
return true;
}
@@ -329,11 +329,11 @@ 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.low_reg, second_bit - first_bit);
- OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, t_reg);
+ OpRegRegImm(kOpLsl, t_reg, rl_src.reg.GetReg(), second_bit - first_bit);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), t_reg);
FreeTemp(t_reg);
if (first_bit != 0) {
- OpRegRegImm(kOpLsl, rl_result.low_reg, rl_result.low_reg, first_bit);
+ OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_result.reg.GetReg(), first_bit);
}
}
@@ -385,11 +385,11 @@ void MipsMir2Lir::GenAddLong(Instruction::Code opcode, RegLocation rl_dest,
* addu v1,v1,t1
*/
- OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src2.low_reg, rl_src1.low_reg);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src2.reg.GetReg(), rl_src1.reg.GetReg());
int t_reg = AllocTemp();
- OpRegRegReg(kOpAdd, t_reg, rl_src2.high_reg, rl_src1.high_reg);
- NewLIR3(kMipsSltu, rl_result.high_reg, rl_result.low_reg, rl_src2.low_reg);
- OpRegRegReg(kOpAdd, rl_result.high_reg, rl_result.high_reg, t_reg);
+ 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);
FreeTemp(t_reg);
StoreValueWide(rl_dest, rl_result);
}
@@ -408,10 +408,10 @@ void MipsMir2Lir::GenSubLong(Instruction::Code opcode, RegLocation rl_dest,
*/
int t_reg = AllocTemp();
- NewLIR3(kMipsSltu, t_reg, rl_src1.low_reg, rl_src2.low_reg);
- OpRegRegReg(kOpSub, rl_result.low_reg, rl_src1.low_reg, rl_src2.low_reg);
- OpRegRegReg(kOpSub, rl_result.high_reg, rl_src1.high_reg, rl_src2.high_reg);
- OpRegRegReg(kOpSub, rl_result.high_reg, rl_result.high_reg, t_reg);
+ 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);
FreeTemp(t_reg);
StoreValueWide(rl_dest, rl_result);
}
@@ -427,11 +427,11 @@ void MipsMir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) {
* subu v1,v1,t1
*/
- OpRegReg(kOpNeg, rl_result.low_reg, rl_src.low_reg);
- OpRegReg(kOpNeg, rl_result.high_reg, rl_src.high_reg);
+ 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.low_reg);
- OpRegRegReg(kOpSub, rl_result.high_reg, rl_result.high_reg, t_reg);
+ NewLIR3(kMipsSltu, t_reg, r_ZERO, rl_result.reg.GetReg());
+ OpRegRegReg(kOpSub, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), t_reg);
FreeTemp(t_reg);
StoreValueWide(rl_dest, rl_result);
}
@@ -471,7 +471,7 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
}
/* null object? */
- GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+ GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
int reg_ptr = AllocTemp();
bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
@@ -479,28 +479,28 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
if (needs_range_check) {
reg_len = AllocTemp();
/* Get len */
- LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
+ LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
}
/* reg_ptr -> array data */
- OpRegRegImm(kOpAdd, reg_ptr, rl_array.low_reg, data_offset);
- FreeTemp(rl_array.low_reg);
+ OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg.GetReg(), 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.low_reg, scale);
+ OpRegRegImm(kOpLsl, r_new_index, rl_index.reg.GetReg(), scale);
OpRegReg(kOpAdd, reg_ptr, r_new_index);
FreeTemp(r_new_index);
} else {
- OpRegReg(kOpAdd, reg_ptr, rl_index.low_reg);
+ OpRegReg(kOpAdd, reg_ptr, rl_index.reg.GetReg());
}
- FreeTemp(rl_index.low_reg);
+ FreeTemp(rl_index.reg.GetReg());
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- LoadBaseDispWide(reg_ptr, 0, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+ LoadBaseDispWide(reg_ptr, 0, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
FreeTemp(reg_ptr);
StoreValueWide(rl_dest, rl_result);
@@ -508,10 +508,10 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- LoadBaseIndexed(reg_ptr, rl_index.low_reg, rl_result.low_reg, scale, size);
+ LoadBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_result.reg.GetReg(), scale, size);
FreeTemp(reg_ptr);
StoreValue(rl_dest, rl_result);
@@ -538,17 +538,17 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
rl_index = LoadValue(rl_index, kCoreReg);
int reg_ptr = INVALID_REG;
bool allocated_reg_ptr_temp = false;
- if (IsTemp(rl_array.low_reg) && !card_mark) {
- Clobber(rl_array.low_reg);
- reg_ptr = rl_array.low_reg;
+ if (IsTemp(rl_array.reg.GetReg()) && !card_mark) {
+ Clobber(rl_array.reg.GetReg());
+ reg_ptr = rl_array.reg.GetReg();
} else {
reg_ptr = AllocTemp();
- OpRegCopy(reg_ptr, rl_array.low_reg);
+ OpRegCopy(reg_ptr, rl_array.reg.GetReg());
allocated_reg_ptr_temp = true;
}
/* null object? */
- GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+ GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
bool needs_range_check = (!(opt_flags & MIR_IGNORE_RANGE_CHECK));
int reg_len = INVALID_REG;
@@ -556,7 +556,7 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
reg_len = AllocTemp();
// NOTE: max live temps(4) here.
/* Get len */
- LoadWordDisp(rl_array.low_reg, len_offset, reg_len);
+ LoadWordDisp(rl_array.reg.GetReg(), len_offset, reg_len);
}
/* reg_ptr -> array data */
OpRegImm(kOpAdd, reg_ptr, data_offset);
@@ -565,34 +565,34 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
// TUNING: specific wide routine that can handle fp regs
if (scale) {
int r_new_index = AllocTemp();
- OpRegRegImm(kOpLsl, r_new_index, rl_index.low_reg, scale);
+ OpRegRegImm(kOpLsl, r_new_index, rl_index.reg.GetReg(), scale);
OpRegReg(kOpAdd, reg_ptr, r_new_index);
FreeTemp(r_new_index);
} else {
- OpRegReg(kOpAdd, reg_ptr, rl_index.low_reg);
+ OpRegReg(kOpAdd, reg_ptr, rl_index.reg.GetReg());
}
rl_src = LoadValueWide(rl_src, reg_class);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- StoreBaseDispWide(reg_ptr, 0, rl_src.low_reg, rl_src.high_reg);
+ StoreBaseDispWide(reg_ptr, 0, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
rl_src = LoadValue(rl_src, reg_class);
if (needs_range_check) {
- GenRegRegCheck(kCondUge, rl_index.low_reg, reg_len, kThrowArrayBounds);
+ GenRegRegCheck(kCondUge, rl_index.reg.GetReg(), reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
- StoreBaseIndexed(reg_ptr, rl_index.low_reg, rl_src.low_reg,
+ StoreBaseIndexed(reg_ptr, rl_index.reg.GetReg(), rl_src.reg.GetReg(),
scale, size);
}
if (allocated_reg_ptr_temp) {
FreeTemp(reg_ptr);
}
if (card_mark) {
- MarkGCCard(rl_src.low_reg, rl_array.low_reg);
+ MarkGCCard(rl_src.reg.GetReg(), rl_array.reg.GetReg());
}
}
diff --git a/compiler/dex/quick/mips/mips_lir.h b/compiler/dex/quick/mips/mips_lir.h
index 00eef96cb5..59f442c61a 100644
--- a/compiler/dex/quick/mips/mips_lir.h
+++ b/compiler/dex/quick/mips/mips_lir.h
@@ -141,16 +141,6 @@ namespace art {
#define rMIPS_LR INVALID_REG
#define rMIPS_PC INVALID_REG
-// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
-#define MIPS_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_V0, INVALID_REG, \
- INVALID_SREG, INVALID_SREG}
-#define MIPS_LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_FRESULT0, \
- INVALID_REG, INVALID_SREG, INVALID_SREG}
-#define MIPS_LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_RESULT0, \
- r_RESULT1, INVALID_SREG, INVALID_SREG}
-#define MIPS_LOC_C_RETURN_DOUBLE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r_FRESULT0, \
- r_FRESULT1, INVALID_SREG, INVALID_SREG}
-
enum MipsResourceEncodingPos {
kMipsGPReg0 = 0,
kMipsRegSP = 29,
@@ -279,6 +269,20 @@ enum MipsNativeRegisterPool {
#define rMIPS_INVOKE_TGT r_T9
#define rMIPS_COUNT INVALID_REG
+// 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};
+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};
+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};
+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};
+
enum MipsShiftEncodings {
kMipsLsl = 0x0,
kMipsLsr = 0x1,
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index 224e8f21f2..85c250da0f 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -40,23 +40,19 @@ 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};
RegLocation MipsMir2Lir::LocCReturn() {
- RegLocation res = MIPS_LOC_C_RETURN;
- return res;
+ return mips_loc_c_return;
}
RegLocation MipsMir2Lir::LocCReturnWide() {
- RegLocation res = MIPS_LOC_C_RETURN_WIDE;
- return res;
+ return mips_loc_c_return_wide;
}
RegLocation MipsMir2Lir::LocCReturnFloat() {
- RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
- return res;
+ return mips_loc_c_return_float;
}
RegLocation MipsMir2Lir::LocCReturnDouble() {
- RegLocation res = MIPS_LOC_C_RETURN_DOUBLE;
- return res;
+ return mips_loc_c_return_double;
}
// Return a target-dependent special register.
@@ -441,27 +437,20 @@ void MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) {
#endif
}
-/*
- * Alloc a pair of core registers, or a double. Low reg in low byte,
- * high reg in next byte.
- */
-int MipsMir2Lir::AllocTypedTempPair(bool fp_hint,
- int reg_class) {
+// Alloc a pair of core registers, or a double.
+RegStorage MipsMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
int high_reg;
int low_reg;
- int res = 0;
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
low_reg = AllocTempDouble();
high_reg = low_reg + 1;
- res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
- return res;
+ return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
}
low_reg = AllocTemp();
high_reg = AllocTemp();
- res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
- return res;
+ return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
}
int MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
@@ -505,11 +494,11 @@ void MipsMir2Lir::CompilerInitializeRegAlloc() {
}
void MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free) {
- if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
- (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
+ 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.low_reg);
- FreeTemp(rl_free.high_reg);
+ FreeTemp(rl_free.reg.GetReg());
+ FreeTemp(rl_free.reg.GetHighReg());
}
}
/*
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 8c2ed3667b..03d3634ccb 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -53,8 +53,9 @@ int Mir2Lir::LoadArg(int in_position, bool wide) {
if (wide && reg_arg_high == INVALID_REG) {
// If the low part is not in a reg, we allocate a pair. Otherwise, we just load to high reg.
if (reg_arg_low == INVALID_REG) {
- int new_regs = AllocTypedTempPair(false, kAnyReg);
- DECODE_REG_PAIR(new_regs, reg_arg_low, reg_arg_high);
+ RegStorage new_regs = AllocTypedTempWide(false, kAnyReg);
+ reg_arg_low = new_regs.GetReg();
+ reg_arg_high = new_regs.GetHighReg();
LoadBaseDispWide(TargetReg(kSp), offset, reg_arg_low, reg_arg_high, INVALID_SREG);
} else {
reg_arg_high = AllocTemp();
@@ -70,6 +71,7 @@ int Mir2Lir::LoadArg(int in_position, bool wide) {
}
if (wide) {
+ // TODO: replace w/ RegStorage.
return ENCODE_REG_PAIR(reg_arg_low, reg_arg_high);
} else {
return reg_arg_low;
@@ -90,25 +92,25 @@ void Mir2Lir::LoadArgDirect(int in_position, RegLocation rl_dest) {
if (!rl_dest.wide) {
int reg = GetArgMappingToPhysicalReg(in_position);
if (reg != INVALID_REG) {
- OpRegCopy(rl_dest.low_reg, reg);
+ OpRegCopy(rl_dest.reg.GetReg(), reg);
} else {
- LoadWordDisp(TargetReg(kSp), offset, rl_dest.low_reg);
+ LoadWordDisp(TargetReg(kSp), offset, rl_dest.reg.GetReg());
}
} else {
int reg_arg_low = GetArgMappingToPhysicalReg(in_position);
int reg_arg_high = GetArgMappingToPhysicalReg(in_position + 1);
if (reg_arg_low != INVALID_REG && reg_arg_high != INVALID_REG) {
- OpRegCopyWide(rl_dest.low_reg, rl_dest.high_reg, reg_arg_low, reg_arg_high);
+ OpRegCopyWide(rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg(), reg_arg_low, reg_arg_high);
} else if (reg_arg_low != INVALID_REG && reg_arg_high == INVALID_REG) {
- OpRegCopy(rl_dest.low_reg, reg_arg_low);
+ OpRegCopy(rl_dest.reg.GetReg(), reg_arg_low);
int offset_high = offset + sizeof(uint32_t);
- LoadWordDisp(TargetReg(kSp), offset_high, rl_dest.high_reg);
+ LoadWordDisp(TargetReg(kSp), offset_high, rl_dest.reg.GetHighReg());
} else if (reg_arg_low == INVALID_REG && reg_arg_high != INVALID_REG) {
- OpRegCopy(rl_dest.high_reg, reg_arg_high);
- LoadWordDisp(TargetReg(kSp), offset, rl_dest.low_reg);
+ OpRegCopy(rl_dest.reg.GetHighReg(), reg_arg_high);
+ LoadWordDisp(TargetReg(kSp), offset, rl_dest.reg.GetReg());
} else {
- LoadBaseDispWide(TargetReg(kSp), offset, rl_dest.low_reg, rl_dest.high_reg, INVALID_SREG);
+ LoadBaseDispWide(TargetReg(kSp), offset, rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg(), INVALID_SREG);
}
}
}
@@ -131,9 +133,9 @@ bool Mir2Lir::GenSpecialIGet(MIR* mir, const InlineMethod& special) {
RegLocation rl_dest = wide ? GetReturnWide(double_or_float) : GetReturn(double_or_float);
int reg_obj = LoadArg(data.object_arg);
if (wide) {
- LoadBaseDispWide(reg_obj, data.field_offset, rl_dest.low_reg, rl_dest.high_reg, INVALID_SREG);
+ LoadBaseDispWide(reg_obj, data.field_offset, rl_dest.reg.GetReg(), rl_dest.reg.GetHighReg(), INVALID_SREG);
} else {
- LoadBaseDisp(reg_obj, data.field_offset, rl_dest.low_reg, kWord, INVALID_SREG);
+ LoadBaseDisp(reg_obj, data.field_offset, rl_dest.reg.GetReg(), kWord, INVALID_SREG);
}
if (data.is_volatile) {
GenMemBarrier(kLoadLoad);
@@ -210,7 +212,7 @@ bool Mir2Lir::GenSpecialCase(BasicBlock* bb, MIR* mir, const InlineMethod& speci
successful = true;
RegLocation rl_dest = GetReturn(cu_->shorty[0] == 'F');
GenPrintLabel(mir);
- LoadConstant(rl_dest.low_reg, static_cast<int>(special.d.data));
+ LoadConstant(rl_dest.reg.GetReg(), static_cast<int>(special.d.data));
return_mir = mir_graph_->GetNextUnconditionalMir(bb, mir);
break;
}
@@ -371,19 +373,19 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::CONST_4:
case Instruction::CONST_16:
rl_result = EvalLoc(rl_dest, kAnyReg, true);
- LoadConstantNoClobber(rl_result.low_reg, vB);
+ LoadConstantNoClobber(rl_result.reg.GetReg(), vB);
StoreValue(rl_dest, rl_result);
if (vB == 0) {
- Workaround7250540(rl_dest, rl_result.low_reg);
+ Workaround7250540(rl_dest, rl_result.reg.GetReg());
}
break;
case Instruction::CONST_HIGH16:
rl_result = EvalLoc(rl_dest, kAnyReg, true);
- LoadConstantNoClobber(rl_result.low_reg, vB << 16);
+ LoadConstantNoClobber(rl_result.reg.GetReg(), vB << 16);
StoreValue(rl_dest, rl_result);
if (vB == 0) {
- Workaround7250540(rl_dest, rl_result.low_reg);
+ Workaround7250540(rl_dest, rl_result.reg.GetReg());
}
break;
@@ -398,7 +400,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::CONST_WIDE_HIGH16:
rl_result = EvalLoc(rl_dest, kAnyReg, true);
- LoadConstantWide(rl_result.low_reg, rl_result.high_reg,
+ LoadConstantWide(rl_result.reg.GetReg(), rl_result.reg.GetHighReg(),
static_cast<int64_t>(vB) << 48);
StoreValueWide(rl_dest, rl_result);
break;
@@ -431,9 +433,9 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
int len_offset;
len_offset = mirror::Array::LengthOffset().Int32Value();
rl_src[0] = LoadValue(rl_src[0], kCoreReg);
- GenNullCheck(rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
+ GenNullCheck(rl_src[0].s_reg_low, rl_src[0].reg.GetReg(), opt_flags);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- LoadWordDisp(rl_src[0].low_reg, len_offset, rl_result.low_reg);
+ LoadWordDisp(rl_src[0].reg.GetReg(), len_offset, rl_result.reg.GetReg());
StoreValue(rl_dest, rl_result);
break;
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 6e97c531cd..7522cd9499 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -21,6 +21,7 @@
#include "compiled_method.h"
#include "dex/compiler_enums.h"
#include "dex/compiler_ir.h"
+#include "dex/reg_storage.h"
#include "dex/backend.h"
#include "driver/compiler_driver.h"
#include "leb128_encoder.h"
@@ -813,7 +814,7 @@ class Mir2Lir : public Backend {
virtual bool IsFpReg(int reg) = 0;
virtual bool SameRegType(int reg1, int reg2) = 0;
virtual int AllocTypedTemp(bool fp_hint, int reg_class) = 0;
- virtual int AllocTypedTempPair(bool fp_hint, int reg_class) = 0;
+ virtual RegStorage AllocTypedTempWide(bool fp_hint, int reg_class) = 0;
virtual int S2d(int low_reg, int high_reg) = 0;
virtual int TargetReg(SpecialTargetRegister reg) = 0;
virtual int GetArgMappingToPhysicalReg(int arg_num) = 0;
diff --git a/compiler/dex/quick/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc
index 0a651713ab..3a8942e46e 100644
--- a/compiler/dex/quick/ralloc_util.cc
+++ b/compiler/dex/quick/ralloc_util.cc
@@ -460,7 +460,7 @@ void Mir2Lir::MarkDef(RegLocation rl, LIR *start, LIR *finish) {
DCHECK(!rl.wide);
DCHECK(start && start->next);
DCHECK(finish);
- RegisterInfo* p = GetRegInfo(rl.low_reg);
+ RegisterInfo* p = GetRegInfo(rl.reg.GetReg());
p->def_start = start->next;
p->def_end = finish;
}
@@ -474,8 +474,8 @@ void Mir2Lir::MarkDefWide(RegLocation rl, LIR *start, LIR *finish) {
DCHECK(rl.wide);
DCHECK(start && start->next);
DCHECK(finish);
- RegisterInfo* p = GetRegInfo(rl.low_reg);
- ResetDef(rl.high_reg); // Only track low of pair
+ RegisterInfo* p = GetRegInfo(rl.reg.GetReg());
+ ResetDef(rl.reg.GetHighReg()); // Only track low of pair
p->def_start = start->next;
p->def_end = finish;
}
@@ -483,8 +483,8 @@ void Mir2Lir::MarkDefWide(RegLocation rl, LIR *start, LIR *finish) {
RegLocation Mir2Lir::WideToNarrow(RegLocation rl) {
DCHECK(rl.wide);
if (rl.location == kLocPhysReg) {
- RegisterInfo* info_lo = GetRegInfo(rl.low_reg);
- RegisterInfo* info_hi = GetRegInfo(rl.high_reg);
+ RegisterInfo* info_lo = GetRegInfo(rl.reg.GetReg());
+ RegisterInfo* info_hi = GetRegInfo(rl.reg.GetHighReg());
if (info_lo->is_temp) {
info_lo->pair = false;
info_lo->def_start = NULL;
@@ -502,18 +502,18 @@ RegLocation Mir2Lir::WideToNarrow(RegLocation rl) {
void Mir2Lir::ResetDefLoc(RegLocation rl) {
DCHECK(!rl.wide);
- RegisterInfo* p = IsTemp(rl.low_reg);
+ RegisterInfo* p = IsTemp(rl.reg.GetReg());
if (p && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(!p->pair);
NullifyRange(p->def_start, p->def_end, p->s_reg, rl.s_reg_low);
}
- ResetDef(rl.low_reg);
+ ResetDef(rl.reg.GetReg());
}
void Mir2Lir::ResetDefLocWide(RegLocation rl) {
DCHECK(rl.wide);
- RegisterInfo* p_low = IsTemp(rl.low_reg);
- RegisterInfo* p_high = IsTemp(rl.high_reg);
+ RegisterInfo* p_low = IsTemp(rl.reg.GetReg());
+ RegisterInfo* p_high = IsTemp(rl.reg.GetHighReg());
if (p_low && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_low->pair);
NullifyRange(p_low->def_start, p_low->def_end, p_low->s_reg, rl.s_reg_low);
@@ -521,8 +521,8 @@ void Mir2Lir::ResetDefLocWide(RegLocation rl) {
if (p_high && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_high->pair);
}
- ResetDef(rl.low_reg);
- ResetDef(rl.high_reg);
+ ResetDef(rl.reg.GetReg());
+ ResetDef(rl.reg.GetHighReg());
}
void Mir2Lir::ResetDefTracking() {
@@ -621,10 +621,10 @@ void Mir2Lir::MarkPair(int low_reg, int high_reg) {
}
void Mir2Lir::MarkClean(RegLocation loc) {
- RegisterInfo* info = GetRegInfo(loc.low_reg);
+ RegisterInfo* info = GetRegInfo(loc.reg.GetReg());
info->dirty = false;
if (loc.wide) {
- info = GetRegInfo(loc.high_reg);
+ info = GetRegInfo(loc.reg.GetHighReg());
info->dirty = false;
}
}
@@ -634,10 +634,10 @@ void Mir2Lir::MarkDirty(RegLocation loc) {
// If already home, can't be dirty
return;
}
- RegisterInfo* info = GetRegInfo(loc.low_reg);
+ RegisterInfo* info = GetRegInfo(loc.reg.GetReg());
info->dirty = true;
if (loc.wide) {
- info = GetRegInfo(loc.high_reg);
+ info = GetRegInfo(loc.reg.GetHighReg());
info->dirty = true;
}
}
@@ -707,7 +707,7 @@ RegLocation Mir2Lir::UpdateLoc(RegLocation loc) {
Clobber(info_lo->partner);
FreeTemp(info_lo->reg);
} else {
- loc.low_reg = info_lo->reg;
+ loc.reg = RegStorage(RegStorage::k32BitSolo, info_lo->reg);
loc.location = kLocPhysReg;
}
}
@@ -744,11 +744,10 @@ RegLocation Mir2Lir::UpdateLocWide(RegLocation loc) {
}
if (match) {
// Can reuse - update the register usage info
- loc.low_reg = info_lo->reg;
- loc.high_reg = info_hi->reg;
loc.location = kLocPhysReg;
- MarkPair(loc.low_reg, loc.high_reg);
- DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ 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));
return loc;
}
// Can't easily reuse - clobber and free any overlaps
@@ -779,7 +778,6 @@ RegLocation Mir2Lir::UpdateRawLoc(RegLocation loc) {
RegLocation Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update) {
DCHECK(loc.wide);
- int32_t new_regs;
int32_t low_reg;
int32_t high_reg;
@@ -787,22 +785,21 @@ RegLocation Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update) {
/* If already in registers, we can assume proper form. Right reg class? */
if (loc.location == kLocPhysReg) {
- DCHECK_EQ(IsFpReg(loc.low_reg), IsFpReg(loc.high_reg));
- DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
- if (!RegClassMatches(reg_class, loc.low_reg)) {
+ 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())) {
/* Wrong register class. Reallocate and copy */
- new_regs = AllocTypedTempPair(loc.fp, reg_class);
- low_reg = new_regs & 0xff;
- high_reg = (new_regs >> 8) & 0xff;
- OpRegCopyWide(low_reg, high_reg, loc.low_reg, loc.high_reg);
- CopyRegInfo(low_reg, loc.low_reg);
- CopyRegInfo(high_reg, loc.high_reg);
- Clobber(loc.low_reg);
- Clobber(loc.high_reg);
- loc.low_reg = low_reg;
- loc.high_reg = high_reg;
- MarkPair(loc.low_reg, loc.high_reg);
- DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ 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());
+ loc.reg = new_regs;
+ MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
+ DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
}
return loc;
}
@@ -810,20 +807,18 @@ RegLocation Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update) {
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
DCHECK_NE(GetSRegHi(loc.s_reg_low), INVALID_SREG);
- new_regs = AllocTypedTempPair(loc.fp, reg_class);
- loc.low_reg = new_regs & 0xff;
- loc.high_reg = (new_regs >> 8) & 0xff;
+ loc.reg = AllocTypedTempWide(loc.fp, reg_class);
- MarkPair(loc.low_reg, loc.high_reg);
+ MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
if (update) {
loc.location = kLocPhysReg;
- MarkLive(loc.low_reg, loc.s_reg_low);
+ MarkLive(loc.reg.GetReg(), loc.s_reg_low);
// Does this wide value live in two registers or one vector register?
- if (loc.low_reg != loc.high_reg) {
- MarkLive(loc.high_reg, GetSRegHi(loc.s_reg_low));
+ if (loc.reg.GetReg() != loc.reg.GetHighReg()) {
+ MarkLive(loc.reg.GetHighReg(), GetSRegHi(loc.s_reg_low));
}
}
- DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
return loc;
}
@@ -836,13 +831,13 @@ RegLocation Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update) {
loc = UpdateLoc(loc);
if (loc.location == kLocPhysReg) {
- if (!RegClassMatches(reg_class, loc.low_reg)) {
+ if (!RegClassMatches(reg_class, loc.reg.GetReg())) {
/* Wrong register class. Realloc, copy and transfer ownership */
new_reg = AllocTypedTemp(loc.fp, reg_class);
- OpRegCopy(new_reg, loc.low_reg);
- CopyRegInfo(new_reg, loc.low_reg);
- Clobber(loc.low_reg);
- loc.low_reg = new_reg;
+ OpRegCopy(new_reg, loc.reg.GetReg());
+ CopyRegInfo(new_reg, loc.reg.GetReg());
+ Clobber(loc.reg.GetReg());
+ loc.reg = RegStorage(RegStorage::k32BitSolo, new_reg);
}
return loc;
}
@@ -850,11 +845,11 @@ RegLocation Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update) {
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
new_reg = AllocTypedTemp(loc.fp, reg_class);
- loc.low_reg = new_reg;
+ loc.reg = RegStorage(RegStorage::k32BitSolo, new_reg);
if (update) {
loc.location = kLocPhysReg;
- MarkLive(loc.low_reg, loc.s_reg_low);
+ MarkLive(loc.reg.GetReg(), loc.s_reg_low);
}
return loc;
}
@@ -1006,32 +1001,29 @@ void Mir2Lir::DoPromotion() {
if (curr->fp) {
if (promotion_map_[p_map_idx].fp_location == kLocPhysReg) {
curr->location = kLocPhysReg;
- curr->low_reg = promotion_map_[p_map_idx].FpReg;
+ curr->reg = RegStorage(RegStorage::k32BitSolo, promotion_map_[p_map_idx].FpReg);
curr->home = true;
}
} else {
if (promotion_map_[p_map_idx].core_location == kLocPhysReg) {
curr->location = kLocPhysReg;
- curr->low_reg = promotion_map_[p_map_idx].core_reg;
+ curr->reg = RegStorage(RegStorage::k32BitSolo, promotion_map_[p_map_idx].core_reg);
curr->home = true;
}
}
- curr->high_reg = INVALID_REG;
} else {
if (curr->high_word) {
continue;
}
if (curr->fp) {
if ((promotion_map_[p_map_idx].fp_location == kLocPhysReg) &&
- (promotion_map_[p_map_idx+1].fp_location ==
- kLocPhysReg)) {
+ (promotion_map_[p_map_idx+1].fp_location == kLocPhysReg)) {
int low_reg = promotion_map_[p_map_idx].FpReg;
int high_reg = promotion_map_[p_map_idx+1].FpReg;
// Doubles require pair of singles starting at even reg
if (((low_reg & 0x1) == 0) && ((low_reg + 1) == high_reg)) {
curr->location = kLocPhysReg;
- curr->low_reg = low_reg;
- curr->high_reg = high_reg;
+ curr->reg = RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
curr->home = true;
}
}
@@ -1040,8 +1032,8 @@ void Mir2Lir::DoPromotion() {
&& (promotion_map_[p_map_idx+1].core_location ==
kLocPhysReg)) {
curr->location = kLocPhysReg;
- curr->low_reg = promotion_map_[p_map_idx].core_reg;
- curr->high_reg = promotion_map_[p_map_idx+1].core_reg;
+ curr->reg = RegStorage(RegStorage::k64BitPair, promotion_map_[p_map_idx].core_reg,
+ promotion_map_[p_map_idx+1].core_reg);
curr->home = true;
}
}
@@ -1068,13 +1060,13 @@ RegLocation Mir2Lir::GetReturnWide(bool is_double) {
RegLocation gpr_res = LocCReturnWide();
RegLocation fpr_res = LocCReturnDouble();
RegLocation res = is_double ? fpr_res : gpr_res;
- Clobber(res.low_reg);
- Clobber(res.high_reg);
- LockTemp(res.low_reg);
- LockTemp(res.high_reg);
+ Clobber(res.reg.GetReg());
+ Clobber(res.reg.GetHighReg());
+ LockTemp(res.reg.GetReg());
+ LockTemp(res.reg.GetHighReg());
// Does this wide value live in two registers or one vector register?
- if (res.low_reg != res.high_reg) {
- MarkPair(res.low_reg, res.high_reg);
+ if (res.reg.GetReg() != res.reg.GetHighReg()) {
+ MarkPair(res.reg.GetReg(), res.reg.GetHighReg());
}
return res;
}
@@ -1083,11 +1075,11 @@ RegLocation Mir2Lir::GetReturn(bool is_float) {
RegLocation gpr_res = LocCReturn();
RegLocation fpr_res = LocCReturnFloat();
RegLocation res = is_float ? fpr_res : gpr_res;
- Clobber(res.low_reg);
+ Clobber(res.reg.GetReg());
if (cu_->instruction_set == kMips) {
- MarkInUse(res.low_reg);
+ MarkInUse(res.reg.GetReg());
} else {
- LockTemp(res.low_reg);
+ LockTemp(res.reg.GetReg());
}
return res;
}
diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc
index 0613cdff7a..3708f01120 100644
--- a/compiler/dex/quick/x86/call_x86.cc
+++ b/compiler/dex/quick/x86/call_x86.cc
@@ -40,7 +40,7 @@ void X86Mir2Lir::GenSparseSwitch(MIR* mir, DexOffset table_offset,
int key = keys[i];
BasicBlock* case_block =
mir_graph_->FindBlock(current_dalvik_offset_ + targets[i]);
- OpCmpImmBranch(kCondEq, rl_src.low_reg, key,
+ OpCmpImmBranch(kCondEq, rl_src.reg.GetReg(), key,
&block_label_list_[case_block->id]);
}
}
@@ -87,7 +87,7 @@ void X86Mir2Lir::GenPackedSwitch(MIR* mir, DexOffset table_offset,
// We can use the saved value.
RegLocation rl_method = mir_graph_->GetRegLocation(base_of_code_->s_reg_low);
rl_method = LoadValue(rl_method, kCoreReg);
- start_of_method_reg = rl_method.low_reg;
+ start_of_method_reg = rl_method.reg.GetReg();
store_method_addr_used_ = true;
} else {
start_of_method_reg = AllocTemp();
@@ -97,10 +97,10 @@ void X86Mir2Lir::GenPackedSwitch(MIR* mir, DexOffset table_offset,
int keyReg;
// Remove the bias, if necessary
if (low_key == 0) {
- keyReg = rl_src.low_reg;
+ keyReg = rl_src.reg.GetReg();
} else {
keyReg = AllocTemp();
- OpRegRegImm(kOpSub, keyReg, rl_src.low_reg, low_key);
+ OpRegRegImm(kOpSub, keyReg, rl_src.reg.GetReg(), low_key);
}
// Bounds check - if < 0 or >= size continue following switch
OpRegImm(kOpCmp, keyReg, size-1);
@@ -164,7 +164,7 @@ void X86Mir2Lir::GenFillArrayData(DexOffset table_offset, RegLocation rl_src) {
void X86Mir2Lir::GenMoveException(RegLocation rl_dest) {
int ex_offset = Thread::ExceptionOffset().Int32Value();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- NewLIR2(kX86Mov32RT, rl_result.low_reg, ex_offset);
+ NewLIR2(kX86Mov32RT, rl_result.reg.GetReg(), ex_offset);
NewLIR2(kX86Mov32TI, ex_offset, 0);
StoreValue(rl_dest, rl_result);
}
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 421d51e4fd..55f18ef341 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -48,8 +48,9 @@ class X86Mir2Lir : public Mir2Lir {
// Required for target - register utilities.
bool IsFpReg(int reg);
bool SameRegType(int reg1, int reg2);
+ // TODO: for consistency, make this return a RegStorage as well?
int AllocTypedTemp(bool fp_hint, int reg_class);
- int AllocTypedTempPair(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);
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index 4c2ecc0efd..1827901b1b 100644
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -63,9 +63,9 @@ void X86Mir2Lir::GenArithOpFloat(Instruction::Code opcode,
rl_src1 = LoadValue(rl_src1, kFPReg);
rl_src2 = LoadValue(rl_src2, kFPReg);
rl_result = EvalLoc(rl_dest, kFPReg, true);
- int r_dest = rl_result.low_reg;
- int r_src1 = rl_src1.low_reg;
- int r_src2 = rl_src2.low_reg;
+ int r_dest = rl_result.reg.GetReg();
+ int r_src1 = rl_src1.reg.GetReg();
+ int r_src2 = rl_src2.reg.GetReg();
if (r_dest == r_src2) {
r_src2 = AllocTempFloat();
OpRegCopy(r_src2, r_dest);
@@ -118,9 +118,9 @@ void X86Mir2Lir::GenArithOpDouble(Instruction::Code opcode,
rl_result = EvalLoc(rl_dest, kFPReg, true);
DCHECK(rl_dest.wide);
DCHECK(rl_result.wide);
- int r_dest = S2d(rl_result.low_reg, rl_result.high_reg);
- int r_src1 = S2d(rl_src1.low_reg, rl_src1.high_reg);
- int r_src2 = S2d(rl_src2.low_reg, rl_src2.high_reg);
+ int r_dest = S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg());
+ int r_src1 = S2d(rl_src1.reg.GetReg(), rl_src1.reg.GetHighReg());
+ int r_src2 = S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg());
if (r_dest == r_src2) {
r_src2 = AllocTempDouble() | X86_FP_DOUBLE;
OpRegCopy(r_src2, r_dest);
@@ -140,7 +140,7 @@ void X86Mir2Lir::GenLongToFP(RegLocation rl_dest, RegLocation rl_src, bool is_do
// If the source is in physical register, then put it in its location on stack.
if (rl_src.location == kLocPhysReg) {
- RegisterInfo* lo_info = GetRegInfo(rl_src.low_reg);
+ RegisterInfo* lo_info = GetRegInfo(rl_src.reg.GetReg());
if (lo_info != nullptr && lo_info->is_temp) {
// Calling FlushSpecificReg because it will only write back VR if it is dirty.
@@ -148,7 +148,7 @@ void X86Mir2Lir::GenLongToFP(RegLocation rl_dest, RegLocation rl_src, bool is_do
} else {
// It must have been register promoted if it is not a temp but is still in physical
// register. Since we need it to be in memory to convert, we place it there now.
- StoreBaseDispWide(TargetReg(kSp), src_v_reg_offset, rl_src.low_reg, rl_src.high_reg);
+ StoreBaseDispWide(TargetReg(kSp), src_v_reg_offset, rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
}
}
@@ -181,13 +181,13 @@ void X86Mir2Lir::GenLongToFP(RegLocation rl_dest, RegLocation rl_src, bool is_do
if (is_double) {
rl_result = EvalLocWide(rl_dest, kFPReg, true);
- LoadBaseDispWide(TargetReg(kSp), dest_v_reg_offset, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+ LoadBaseDispWide(TargetReg(kSp), dest_v_reg_offset, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
StoreValueWide(rl_dest, rl_result);
} else {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- LoadWordDisp(TargetReg(kSp), dest_v_reg_offset, rl_result.low_reg);
+ LoadWordDisp(TargetReg(kSp), dest_v_reg_offset, rl_result.reg.GetReg());
StoreValue(rl_dest, rl_result);
}
@@ -219,21 +219,21 @@ void X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
break;
case Instruction::FLOAT_TO_INT: {
rl_src = LoadValue(rl_src, kFPReg);
- src_reg = rl_src.low_reg;
+ src_reg = rl_src.reg.GetReg();
// In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc()
ClobberSReg(rl_dest.s_reg_low);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
int temp_reg = AllocTempFloat();
- LoadConstant(rl_result.low_reg, 0x7fffffff);
- NewLIR2(kX86Cvtsi2ssRR, temp_reg, rl_result.low_reg);
+ LoadConstant(rl_result.reg.GetReg(), 0x7fffffff);
+ NewLIR2(kX86Cvtsi2ssRR, temp_reg, rl_result.reg.GetReg());
NewLIR2(kX86ComissRR, src_reg, temp_reg);
LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA);
LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP);
- NewLIR2(kX86Cvttss2siRR, rl_result.low_reg, src_reg);
+ NewLIR2(kX86Cvttss2siRR, rl_result.reg.GetReg(), src_reg);
LIR* branch_normal = NewLIR1(kX86Jmp8, 0);
branch_na_n->target = NewLIR0(kPseudoTargetLabel);
- NewLIR2(kX86Xor32RR, rl_result.low_reg, rl_result.low_reg);
+ NewLIR2(kX86Xor32RR, rl_result.reg.GetReg(), rl_result.reg.GetReg());
branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel);
branch_normal->target = NewLIR0(kPseudoTargetLabel);
StoreValue(rl_dest, rl_result);
@@ -241,21 +241,21 @@ void X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
}
case Instruction::DOUBLE_TO_INT: {
rl_src = LoadValueWide(rl_src, kFPReg);
- src_reg = rl_src.low_reg;
+ src_reg = rl_src.reg.GetReg();
// In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc()
ClobberSReg(rl_dest.s_reg_low);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
int temp_reg = AllocTempDouble() | X86_FP_DOUBLE;
- LoadConstant(rl_result.low_reg, 0x7fffffff);
- NewLIR2(kX86Cvtsi2sdRR, temp_reg, rl_result.low_reg);
+ LoadConstant(rl_result.reg.GetReg(), 0x7fffffff);
+ NewLIR2(kX86Cvtsi2sdRR, temp_reg, rl_result.reg.GetReg());
NewLIR2(kX86ComisdRR, src_reg, temp_reg);
LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA);
LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP);
- NewLIR2(kX86Cvttsd2siRR, rl_result.low_reg, src_reg);
+ NewLIR2(kX86Cvttsd2siRR, rl_result.reg.GetReg(), src_reg);
LIR* branch_normal = NewLIR1(kX86Jmp8, 0);
branch_na_n->target = NewLIR0(kPseudoTargetLabel);
- NewLIR2(kX86Xor32RR, rl_result.low_reg, rl_result.low_reg);
+ NewLIR2(kX86Xor32RR, rl_result.reg.GetReg(), rl_result.reg.GetReg());
branch_pos_overflow->target = NewLIR0(kPseudoTargetLabel);
branch_normal->target = NewLIR0(kPseudoTargetLabel);
StoreValue(rl_dest, rl_result);
@@ -278,18 +278,18 @@ void X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
}
if (rl_src.wide) {
rl_src = LoadValueWide(rl_src, rcSrc);
- src_reg = S2d(rl_src.low_reg, rl_src.high_reg);
+ src_reg = S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg());
} else {
rl_src = LoadValue(rl_src, rcSrc);
- src_reg = rl_src.low_reg;
+ src_reg = rl_src.reg.GetReg();
}
if (rl_dest.wide) {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, S2d(rl_result.low_reg, rl_result.high_reg), src_reg);
+ NewLIR2(op, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()), src_reg);
StoreValueWide(rl_dest, rl_result);
} else {
rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(op, rl_result.low_reg, src_reg);
+ NewLIR2(op, rl_result.reg.GetReg(), src_reg);
StoreValue(rl_dest, rl_result);
}
}
@@ -302,19 +302,19 @@ void X86Mir2Lir::GenCmpFP(Instruction::Code code, RegLocation rl_dest,
int src_reg2;
if (single) {
rl_src1 = LoadValue(rl_src1, kFPReg);
- src_reg1 = rl_src1.low_reg;
+ src_reg1 = rl_src1.reg.GetReg();
rl_src2 = LoadValue(rl_src2, kFPReg);
- src_reg2 = rl_src2.low_reg;
+ src_reg2 = rl_src2.reg.GetReg();
} else {
rl_src1 = LoadValueWide(rl_src1, kFPReg);
- src_reg1 = S2d(rl_src1.low_reg, rl_src1.high_reg);
+ src_reg1 = S2d(rl_src1.reg.GetReg(), rl_src1.reg.GetHighReg());
rl_src2 = LoadValueWide(rl_src2, kFPReg);
- src_reg2 = S2d(rl_src2.low_reg, rl_src2.high_reg);
+ src_reg2 = S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg());
}
// In case result vreg is also src vreg, break association to avoid useless copy by EvalLoc()
ClobberSReg(rl_dest.s_reg_low);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- LoadConstantNoClobber(rl_result.low_reg, unordered_gt ? 1 : 0);
+ LoadConstantNoClobber(rl_result.reg.GetReg(), unordered_gt ? 1 : 0);
if (single) {
NewLIR2(kX86UcomissRR, src_reg1, src_reg2);
} else {
@@ -325,20 +325,20 @@ void X86Mir2Lir::GenCmpFP(Instruction::Code code, RegLocation rl_dest,
branch = NewLIR2(kX86Jcc8, 0, kX86CondPE);
}
// If the result reg can't be byte accessed, use a jump and move instead of a set.
- if (rl_result.low_reg >= 4) {
+ if (rl_result.reg.GetReg() >= 4) {
LIR* branch2 = NULL;
if (unordered_gt) {
branch2 = NewLIR2(kX86Jcc8, 0, kX86CondA);
- NewLIR2(kX86Mov32RI, rl_result.low_reg, 0x0);
+ NewLIR2(kX86Mov32RI, rl_result.reg.GetReg(), 0x0);
} else {
branch2 = NewLIR2(kX86Jcc8, 0, kX86CondBe);
- NewLIR2(kX86Mov32RI, rl_result.low_reg, 0x1);
+ NewLIR2(kX86Mov32RI, rl_result.reg.GetReg(), 0x1);
}
branch2->target = NewLIR0(kPseudoTargetLabel);
} else {
- NewLIR2(kX86Set8R, rl_result.low_reg, kX86CondA /* above - unsigned > */);
+ NewLIR2(kX86Set8R, rl_result.reg.GetReg(), kX86CondA /* above - unsigned > */);
}
- NewLIR2(kX86Sbb32RI, rl_result.low_reg, 0);
+ NewLIR2(kX86Sbb32RI, rl_result.reg.GetReg(), 0);
if (unordered_gt) {
branch->target = NewLIR0(kPseudoTargetLabel);
}
@@ -357,14 +357,14 @@ void X86Mir2Lir::GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias,
rl_src2 = mir_graph_->GetSrcWide(mir, 2);
rl_src1 = LoadValueWide(rl_src1, kFPReg);
rl_src2 = LoadValueWide(rl_src2, kFPReg);
- NewLIR2(kX86UcomisdRR, S2d(rl_src1.low_reg, rl_src1.high_reg),
- S2d(rl_src2.low_reg, rl_src2.high_reg));
+ NewLIR2(kX86UcomisdRR, S2d(rl_src1.reg.GetReg(), rl_src1.reg.GetHighReg()),
+ S2d(rl_src2.reg.GetReg(), rl_src2.reg.GetHighReg()));
} else {
rl_src1 = mir_graph_->GetSrc(mir, 0);
rl_src2 = mir_graph_->GetSrc(mir, 1);
rl_src1 = LoadValue(rl_src1, kFPReg);
rl_src2 = LoadValue(rl_src2, kFPReg);
- NewLIR2(kX86UcomissRR, rl_src1.low_reg, rl_src2.low_reg);
+ NewLIR2(kX86UcomissRR, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
}
ConditionCode ccode = mir->meta.ccode;
switch (ccode) {
@@ -418,7 +418,7 @@ void X86Mir2Lir::GenNegFloat(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValue(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpAdd, rl_result.low_reg, rl_src.low_reg, 0x80000000);
+ OpRegRegImm(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0x80000000);
StoreValue(rl_dest, rl_result);
}
@@ -426,8 +426,8 @@ void X86Mir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) {
RegLocation rl_result;
rl_src = LoadValueWide(rl_src, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegImm(kOpAdd, rl_result.high_reg, rl_src.high_reg, 0x80000000);
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
+ OpRegRegImm(kOpAdd, rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg(), 0x80000000);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
StoreValueWide(rl_dest, rl_result);
}
@@ -436,8 +436,8 @@ bool X86Mir2Lir::GenInlinedSqrt(CallInfo* info) {
RegLocation rl_dest = InlineTargetWide(info); // double place for result
rl_src = LoadValueWide(rl_src, kFPReg);
RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true);
- NewLIR2(kX86SqrtsdRR, S2d(rl_result.low_reg, rl_result.high_reg),
- S2d(rl_src.low_reg, rl_src.high_reg));
+ NewLIR2(kX86SqrtsdRR, S2d(rl_result.reg.GetReg(), rl_result.reg.GetHighReg()),
+ S2d(rl_src.reg.GetReg(), rl_src.reg.GetHighReg()));
StoreValueWide(rl_dest, rl_result);
return true;
}
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 5f04b7d152..362ab2e57e 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -216,21 +216,21 @@ void X86Mir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
* mov t1, $false_case
* cmovnz result_reg, t1
*/
- const bool result_reg_same_as_src = (rl_src.location == kLocPhysReg && rl_src.low_reg == rl_result.low_reg);
+ const bool result_reg_same_as_src = (rl_src.location == kLocPhysReg && rl_src.reg.GetReg() == rl_result.reg.GetReg());
const bool true_zero_case = (true_val == 0 && false_val != 0 && !result_reg_same_as_src);
const bool false_zero_case = (false_val == 0 && true_val != 0 && !result_reg_same_as_src);
const bool catch_all_case = !(true_zero_case || false_zero_case);
if (true_zero_case || false_zero_case) {
- OpRegReg(kOpXor, rl_result.low_reg, rl_result.low_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetReg(), rl_result.reg.GetReg());
}
if (true_zero_case || false_zero_case || catch_all_case) {
- OpRegImm(kOpCmp, rl_src.low_reg, 0);
+ OpRegImm(kOpCmp, rl_src.reg.GetReg(), 0);
}
if (catch_all_case) {
- OpRegImm(kOpMov, rl_result.low_reg, true_val);
+ OpRegImm(kOpMov, rl_result.reg.GetReg(), true_val);
}
if (true_zero_case || false_zero_case || catch_all_case) {
@@ -239,7 +239,7 @@ void X86Mir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
OpRegImm(kOpMov, temp1_reg, immediateForTemp);
ConditionCode cc = false_zero_case ? kCondEq : kCondNe;
- OpCondRegReg(kOpCmov, cc, rl_result.low_reg, temp1_reg);
+ OpCondRegReg(kOpCmov, cc, rl_result.reg.GetReg(), temp1_reg);
FreeTemp(temp1_reg);
}
@@ -264,15 +264,15 @@ void X86Mir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
*/
// kMirOpSelect is generated just for conditional cases when comparison is done with zero.
- OpRegImm(kOpCmp, rl_src.low_reg, 0);
+ OpRegImm(kOpCmp, rl_src.reg.GetReg(), 0);
- if (rl_result.low_reg == rl_true.low_reg) {
- OpCondRegReg(kOpCmov, kCondNe, rl_result.low_reg, rl_false.low_reg);
- } else if (rl_result.low_reg == rl_false.low_reg) {
- OpCondRegReg(kOpCmov, kCondEq, rl_result.low_reg, rl_true.low_reg);
+ if (rl_result.reg.GetReg() == rl_true.reg.GetReg()) {
+ OpCondRegReg(kOpCmov, kCondNe, rl_result.reg.GetReg(), rl_false.reg.GetReg());
+ } else if (rl_result.reg.GetReg() == rl_false.reg.GetReg()) {
+ OpCondRegReg(kOpCmov, kCondEq, rl_result.reg.GetReg(), rl_true.reg.GetReg());
} else {
- OpRegCopy(rl_result.low_reg, rl_true.low_reg);
- OpCondRegReg(kOpCmov, kCondNe, rl_result.low_reg, rl_false.low_reg);
+ OpRegCopy(rl_result.reg.GetReg(), rl_true.reg.GetReg());
+ OpCondRegReg(kOpCmov, kCondNe, rl_result.reg.GetReg(), rl_false.reg.GetReg());
}
}
@@ -337,8 +337,8 @@ void X86Mir2Lir::GenFusedLongCmpImmBranch(BasicBlock* bb, RegLocation rl_src1,
LIR* taken = &block_label_list_[bb->taken];
LIR* not_taken = &block_label_list_[bb->fall_through];
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
- int32_t low_reg = rl_src1.low_reg;
- int32_t high_reg = rl_src1.high_reg;
+ int32_t low_reg = rl_src1.reg.GetReg();
+ int32_t high_reg = rl_src1.reg.GetHighReg();
if (val == 0 && (ccode == kCondEq || ccode == kCondNe)) {
int t_reg = AllocTemp();
@@ -461,7 +461,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src,
// Assume that the result will be in EDX.
RegLocation rl_result = {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
- r2, INVALID_REG, INVALID_SREG, INVALID_SREG};
+ RegStorage(RegStorage::k32BitSolo, r2), INVALID_SREG, INVALID_SREG};
// handle div/rem by 1 special case.
if (imm == 1) {
@@ -472,7 +472,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src,
// x % 1 == 0.
LoadConstantNoClobber(r0, 0);
// For this case, return the result in EAX.
- rl_result.low_reg = r0;
+ rl_result.reg.SetReg(r0);
}
} else if (imm == -1) { // handle 0x80000000 / -1 special case.
if (is_div) {
@@ -494,7 +494,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src,
LoadConstantNoClobber(r0, 0);
}
// For this case, return the result in EAX.
- rl_result.low_reg = r0;
+ rl_result.reg.SetReg(r0);
} else {
CHECK(imm <= -2 || imm >= 2);
// Use H.S.Warren's Hacker's Delight Chapter 10 and
@@ -524,8 +524,8 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src,
// We will need the value later.
if (rl_src.location == kLocPhysReg) {
// We can use it directly.
- DCHECK(rl_src.low_reg != r0 && rl_src.low_reg != r2);
- numerator_reg = rl_src.low_reg;
+ DCHECK(rl_src.reg.GetReg() != r0 && rl_src.reg.GetReg() != r2);
+ numerator_reg = rl_src.reg.GetReg();
} else {
LoadValueDirectFixed(rl_src, r1);
numerator_reg = r1;
@@ -582,7 +582,7 @@ RegLocation X86Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegLocation rl_src,
NewLIR2(kX86Sub32RR, r0, r2);
// For this case, return the result in EAX.
- rl_result.low_reg = r0;
+ rl_result.reg.SetReg(r0);
}
}
@@ -638,9 +638,9 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
// Result is in EAX for div and EDX for rem.
RegLocation rl_result = {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
- r0, INVALID_REG, INVALID_SREG, INVALID_SREG};
+ RegStorage(RegStorage::k32BitSolo, r0), INVALID_SREG, INVALID_SREG};
if (!is_div) {
- rl_result.low_reg = r2;
+ rl_result.reg.SetReg(r2);
}
return rl_result;
}
@@ -662,22 +662,22 @@ bool X86Mir2Lir::GenInlinedMinMaxInt(CallInfo* info, bool is_min) {
* The reason is that the first copy will inadvertently clobber the second element with
* the first one thus yielding the wrong result. Thus we do a swap in that case.
*/
- if (rl_result.low_reg == rl_src2.low_reg) {
+ if (rl_result.reg.GetReg() == rl_src2.reg.GetReg()) {
std::swap(rl_src1, rl_src2);
}
// Pick the first integer as min/max.
- OpRegCopy(rl_result.low_reg, rl_src1.low_reg);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src1.reg.GetReg());
// If the integers are both in the same register, then there is nothing else to do
// because they are equal and we have already moved one into the result.
- if (rl_src1.low_reg != rl_src2.low_reg) {
+ if (rl_src1.reg.GetReg() != rl_src2.reg.GetReg()) {
// It is possible we didn't pick correctly so do the actual comparison now.
- OpRegReg(kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
+ OpRegReg(kOpCmp, rl_src1.reg.GetReg(), rl_src2.reg.GetReg());
// Conditionally move the other integer into the destination register.
ConditionCode condition_code = is_min ? kCondGt : kCondLt;
- OpCondRegReg(kOpCmov, condition_code, rl_result.low_reg, rl_src2.low_reg);
+ OpCondRegReg(kOpCmov, condition_code, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
}
StoreValue(rl_dest, rl_result);
@@ -692,12 +692,12 @@ bool X86Mir2Lir::GenInlinedPeek(CallInfo* info, OpSize size) {
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
if (size == kLong) {
// Unaligned access is allowed on x86.
- LoadBaseDispWide(rl_address.low_reg, 0, rl_result.low_reg, rl_result.high_reg, INVALID_SREG);
+ LoadBaseDispWide(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), INVALID_SREG);
StoreValueWide(rl_dest, rl_result);
} else {
DCHECK(size == kSignedByte || size == kSignedHalf || size == kWord);
// Unaligned access is allowed on x86.
- LoadBaseDisp(rl_address.low_reg, 0, rl_result.low_reg, size, INVALID_SREG);
+ LoadBaseDisp(rl_address.reg.GetReg(), 0, rl_result.reg.GetReg(), size, INVALID_SREG);
StoreValue(rl_dest, rl_result);
}
return true;
@@ -711,12 +711,12 @@ bool X86Mir2Lir::GenInlinedPoke(CallInfo* info, OpSize size) {
if (size == kLong) {
// Unaligned access is allowed on x86.
RegLocation rl_value = LoadValueWide(rl_src_value, kCoreReg);
- StoreBaseDispWide(rl_address.low_reg, 0, rl_value.low_reg, rl_value.high_reg);
+ StoreBaseDispWide(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), rl_value.reg.GetHighReg());
} else {
DCHECK(size == kSignedByte || size == kSignedHalf || size == kWord);
// Unaligned access is allowed on x86.
RegLocation rl_value = LoadValue(rl_src_value, kCoreReg);
- StoreBaseDisp(rl_address.low_reg, 0, rl_value.low_reg, size);
+ StoreBaseDisp(rl_address.reg.GetReg(), 0, rl_value.reg.GetReg(), size);
}
return true;
}
@@ -776,13 +776,13 @@ bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
// Mark card for object assuming new value is stored.
FreeTemp(r0); // Temporarily release EAX for MarkGCCard().
- MarkGCCard(rl_new_value.low_reg, rl_object.low_reg);
+ MarkGCCard(rl_new_value.reg.GetReg(), rl_object.reg.GetReg());
LockTemp(r0);
}
RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
LoadValueDirect(rl_src_expected, r0);
- NewLIR5(kX86LockCmpxchgAR, rl_object.low_reg, rl_offset.low_reg, 0, 0, rl_new_value.low_reg);
+ NewLIR5(kX86LockCmpxchgAR, rl_object.reg.GetReg(), rl_offset.reg.GetReg(), 0, 0, rl_new_value.reg.GetReg());
FreeTemp(r0);
}
@@ -790,8 +790,8 @@ bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
// Convert ZF to boolean
RegLocation rl_dest = InlineTarget(info); // boolean place for result
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- NewLIR2(kX86Set8R, rl_result.low_reg, kX86CondZ);
- NewLIR2(kX86Movzx8RR, rl_result.low_reg, rl_result.low_reg);
+ NewLIR2(kX86Set8R, rl_result.reg.GetReg(), kX86CondZ);
+ NewLIR2(kX86Movzx8RR, rl_result.reg.GetReg(), rl_result.reg.GetReg());
StoreValue(rl_dest, rl_result);
return true;
}
@@ -830,11 +830,11 @@ void X86Mir2Lir::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.low_reg, second_bit - first_bit);
- OpRegRegReg(kOpAdd, rl_result.low_reg, rl_src.low_reg, t_reg);
+ OpRegRegImm(kOpLsl, t_reg, rl_src.reg.GetReg(), second_bit - first_bit);
+ OpRegRegReg(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), t_reg);
FreeTemp(t_reg);
if (first_bit != 0) {
- OpRegRegImm(kOpLsl, rl_result.low_reg, rl_result.low_reg, first_bit);
+ OpRegRegImm(kOpLsl, rl_result.reg.GetReg(), rl_result.reg.GetReg(), first_bit);
}
}
@@ -918,8 +918,8 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
int64_t val = mir_graph_->ConstantValueWide(rl_src2);
if (val == 0) {
RegLocation rl_result = EvalLocWide(rl_dest, kCoreReg, true);
- OpRegReg(kOpXor, rl_result.low_reg, rl_result.low_reg);
- OpRegReg(kOpXor, rl_result.high_reg, rl_result.high_reg);
+ OpRegReg(kOpXor, rl_result.reg.GetReg(), rl_result.reg.GetReg());
+ OpRegReg(kOpXor, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg());
StoreValueWide(rl_dest, rl_result);
return;
} else if (val == 1) {
@@ -952,8 +952,8 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// ECX <- 1H * 2L
// EAX <- 1L * 2H
if (src1_in_reg) {
- GenImulRegImm(r1, rl_src1.high_reg, val_lo);
- GenImulRegImm(r0, rl_src1.low_reg, val_hi);
+ GenImulRegImm(r1, rl_src1.reg.GetHighReg(), val_lo);
+ GenImulRegImm(r0, rl_src1.reg.GetReg(), val_hi);
} else {
GenImulMemImm(r1, GetSRegHi(rl_src1.s_reg_low), displacement + HIWORD_OFFSET, val_lo);
GenImulMemImm(r0, rl_src1.s_reg_low, displacement + LOWORD_OFFSET, val_hi);
@@ -967,7 +967,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// EDX:EAX <- 2L * 1L (double precision)
if (src1_in_reg) {
- NewLIR1(kX86Mul32DaR, rl_src1.low_reg);
+ NewLIR1(kX86Mul32DaR, rl_src1.reg.GetReg());
} else {
LIR *m = NewLIR2(kX86Mul32DaM, rX86_SP, displacement + LOWORD_OFFSET);
AnnotateDalvikRegAccess(m, (displacement + LOWORD_OFFSET) >> 2,
@@ -978,7 +978,8 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
NewLIR2(kX86Add32RR, r2, r1);
// Result is EDX:EAX
- RegLocation rl_result = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r0, r2,
+ RegLocation rl_result = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k64BitPair, r0, r2),
INVALID_SREG, INVALID_SREG};
StoreValueWide(rl_dest, rl_result);
return;
@@ -1000,7 +1001,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// ECX <- 1H
if (src1_in_reg) {
- NewLIR2(kX86Mov32RR, r1, rl_src1.high_reg);
+ NewLIR2(kX86Mov32RR, r1, rl_src1.reg.GetHighReg());
} else {
LoadBaseDisp(rX86_SP, SRegOffset(rl_src1.s_reg_low) + HIWORD_OFFSET, r1,
kWord, GetSRegHi(rl_src1.s_reg_low));
@@ -1010,7 +1011,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// Take advantage of the fact that the values are the same.
// ECX <- ECX * 2L (1H * 2L)
if (src2_in_reg) {
- NewLIR2(kX86Imul32RR, r1, rl_src2.low_reg);
+ NewLIR2(kX86Imul32RR, r1, rl_src2.reg.GetReg());
} else {
int displacement = SRegOffset(rl_src2.s_reg_low);
LIR *m = NewLIR3(kX86Imul32RM, r1, rX86_SP, displacement + LOWORD_OFFSET);
@@ -1023,7 +1024,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
} else {
// EAX <- 2H
if (src2_in_reg) {
- NewLIR2(kX86Mov32RR, r0, rl_src2.high_reg);
+ NewLIR2(kX86Mov32RR, r0, rl_src2.reg.GetHighReg());
} else {
LoadBaseDisp(rX86_SP, SRegOffset(rl_src2.s_reg_low) + HIWORD_OFFSET, r0,
kWord, GetSRegHi(rl_src2.s_reg_low));
@@ -1031,7 +1032,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// EAX <- EAX * 1L (2H * 1L)
if (src1_in_reg) {
- NewLIR2(kX86Imul32RR, r0, rl_src1.low_reg);
+ NewLIR2(kX86Imul32RR, r0, rl_src1.reg.GetReg());
} else {
int displacement = SRegOffset(rl_src1.s_reg_low);
LIR *m = NewLIR3(kX86Imul32RM, r0, rX86_SP, displacement + LOWORD_OFFSET);
@@ -1041,7 +1042,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// ECX <- ECX * 2L (1H * 2L)
if (src2_in_reg) {
- NewLIR2(kX86Imul32RR, r1, rl_src2.low_reg);
+ NewLIR2(kX86Imul32RR, r1, rl_src2.reg.GetReg());
} else {
int displacement = SRegOffset(rl_src2.s_reg_low);
LIR *m = NewLIR3(kX86Imul32RM, r1, rX86_SP, displacement + LOWORD_OFFSET);
@@ -1055,7 +1056,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// EAX <- 2L
if (src2_in_reg) {
- NewLIR2(kX86Mov32RR, r0, rl_src2.low_reg);
+ NewLIR2(kX86Mov32RR, r0, rl_src2.reg.GetReg());
} else {
LoadBaseDisp(rX86_SP, SRegOffset(rl_src2.s_reg_low) + LOWORD_OFFSET, r0,
kWord, rl_src2.s_reg_low);
@@ -1063,7 +1064,7 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
// EDX:EAX <- 2L * 1L (double precision)
if (src1_in_reg) {
- NewLIR1(kX86Mul32DaR, rl_src1.low_reg);
+ NewLIR1(kX86Mul32DaR, rl_src1.reg.GetReg());
} else {
int displacement = SRegOffset(rl_src1.s_reg_low);
LIR *m = NewLIR2(kX86Mul32DaM, rX86_SP, displacement + LOWORD_OFFSET);
@@ -1075,8 +1076,8 @@ void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation
NewLIR2(kX86Add32RR, r2, r1);
// Result is EDX:EAX
- RegLocation rl_result = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, r0, r2,
- INVALID_SREG, INVALID_SREG};
+ RegLocation rl_result = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k64BitPair, r0, r2), INVALID_SREG, INVALID_SREG};
StoreValueWide(rl_dest, rl_result);
}
@@ -1086,18 +1087,18 @@ void X86Mir2Lir::GenLongRegOrMemOp(RegLocation rl_dest, RegLocation rl_src,
X86OpCode x86op = GetOpcode(op, rl_dest, rl_src, false);
if (rl_src.location == kLocPhysReg) {
// Both operands are in registers.
- if (rl_dest.low_reg == rl_src.high_reg) {
+ if (rl_dest.reg.GetReg() == rl_src.reg.GetHighReg()) {
// The registers are the same, so we would clobber it before the use.
int temp_reg = AllocTemp();
- OpRegCopy(temp_reg, rl_dest.low_reg);
- rl_src.high_reg = temp_reg;
+ OpRegCopy(temp_reg, rl_dest.reg.GetReg());
+ rl_src.reg.SetHighReg(temp_reg);
}
- NewLIR2(x86op, rl_dest.low_reg, rl_src.low_reg);
+ NewLIR2(x86op, rl_dest.reg.GetReg(), rl_src.reg.GetReg());
x86op = GetOpcode(op, rl_dest, rl_src, true);
- NewLIR2(x86op, rl_dest.high_reg, rl_src.high_reg);
- FreeTemp(rl_src.low_reg);
- FreeTemp(rl_src.high_reg);
+ NewLIR2(x86op, rl_dest.reg.GetHighReg(), rl_src.reg.GetHighReg());
+ FreeTemp(rl_src.reg.GetReg());
+ FreeTemp(rl_src.reg.GetHighReg());
return;
}
@@ -1107,11 +1108,11 @@ void X86Mir2Lir::GenLongRegOrMemOp(RegLocation rl_dest, RegLocation rl_src,
int rBase = TargetReg(kSp);
int displacement = SRegOffset(rl_src.s_reg_low);
- LIR *lir = NewLIR3(x86op, rl_dest.low_reg, rBase, displacement + LOWORD_OFFSET);
+ LIR *lir = NewLIR3(x86op, rl_dest.reg.GetReg(), rBase, displacement + LOWORD_OFFSET);
AnnotateDalvikRegAccess(lir, (displacement + LOWORD_OFFSET) >> 2,
true /* is_load */, true /* is64bit */);
x86op = GetOpcode(op, rl_dest, rl_src, true);
- lir = NewLIR3(x86op, rl_dest.high_reg, rBase, displacement + HIWORD_OFFSET);
+ lir = NewLIR3(x86op, rl_dest.reg.GetHighReg(), rBase, displacement + HIWORD_OFFSET);
AnnotateDalvikRegAccess(lir, (displacement + HIWORD_OFFSET) >> 2,
true /* is_load */, true /* is64bit */);
}
@@ -1138,15 +1139,15 @@ void X86Mir2Lir::GenLongArith(RegLocation rl_dest, RegLocation rl_src, Instructi
int rBase = TargetReg(kSp);
int displacement = SRegOffset(rl_dest.s_reg_low);
- LIR *lir = NewLIR3(x86op, rBase, displacement + LOWORD_OFFSET, rl_src.low_reg);
+ LIR *lir = NewLIR3(x86op, rBase, displacement + LOWORD_OFFSET, rl_src.reg.GetReg());
AnnotateDalvikRegAccess(lir, (displacement + LOWORD_OFFSET) >> 2,
false /* is_load */, true /* is64bit */);
x86op = GetOpcode(op, rl_dest, rl_src, true);
- lir = NewLIR3(x86op, rBase, displacement + HIWORD_OFFSET, rl_src.high_reg);
+ lir = NewLIR3(x86op, rBase, displacement + HIWORD_OFFSET, rl_src.reg.GetHighReg());
AnnotateDalvikRegAccess(lir, (displacement + HIWORD_OFFSET) >> 2,
false /* is_load */, true /* is64bit */);
- FreeTemp(rl_src.low_reg);
- FreeTemp(rl_src.high_reg);
+ FreeTemp(rl_src.reg.GetReg());
+ FreeTemp(rl_src.reg.GetHighReg());
}
void X86Mir2Lir::GenLongArith(RegLocation rl_dest, RegLocation rl_src1,
@@ -1188,12 +1189,12 @@ void X86Mir2Lir::GenLongArith(RegLocation rl_dest, RegLocation rl_src1,
// Get one of the source operands into temporary register.
rl_src1 = LoadValueWide(rl_src1, kCoreReg);
- if (IsTemp(rl_src1.low_reg) && IsTemp(rl_src1.high_reg)) {
+ if (IsTemp(rl_src1.reg.GetReg()) && IsTemp(rl_src1.reg.GetHighReg())) {
GenLongRegOrMemOp(rl_src1, rl_src2, op);
} else if (is_commutative) {
rl_src2 = LoadValueWide(rl_src2, kCoreReg);
// We need at least one of them to be a temporary.
- if (!(IsTemp(rl_src2.low_reg) && IsTemp(rl_src2.high_reg))) {
+ if (!(IsTemp(rl_src2.reg.GetReg()) && IsTemp(rl_src2.reg.GetHighReg()))) {
rl_src1 = ForceTempWide(rl_src1);
}
GenLongRegOrMemOp(rl_src1, rl_src2, op);
@@ -1234,15 +1235,16 @@ void X86Mir2Lir::GenXorLong(Instruction::Code opcode, RegLocation rl_dest,
void X86Mir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) {
rl_src = LoadValueWide(rl_src, kCoreReg);
RegLocation rl_result = ForceTempWide(rl_src);
- if (rl_dest.low_reg == rl_src.high_reg) {
+ if (((rl_dest.location == kLocPhysReg) && (rl_src.location == kLocPhysReg)) &&
+ ((rl_dest.reg.GetReg() == rl_src.reg.GetHighReg()))) {
// The registers are the same, so we would clobber it before the use.
int temp_reg = AllocTemp();
- OpRegCopy(temp_reg, rl_result.low_reg);
- rl_result.high_reg = temp_reg;
+ OpRegCopy(temp_reg, rl_result.reg.GetReg());
+ rl_result.reg.SetHighReg(temp_reg);
}
- OpRegReg(kOpNeg, rl_result.low_reg, rl_result.low_reg); // rLow = -rLow
- OpRegImm(kOpAdc, rl_result.high_reg, 0); // rHigh = rHigh + CF
- OpRegReg(kOpNeg, rl_result.high_reg, rl_result.high_reg); // rHigh = -rHigh
+ OpRegReg(kOpNeg, rl_result.reg.GetReg(), rl_result.reg.GetReg()); // rLow = -rLow
+ OpRegImm(kOpAdc, rl_result.reg.GetHighReg(), 0); // rHigh = rHigh + CF
+ OpRegReg(kOpNeg, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg()); // rHigh = -rHigh
StoreValueWide(rl_dest, rl_result);
}
@@ -1284,29 +1286,29 @@ void X86Mir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array,
// If index is constant, just fold it into the data offset
data_offset += constant_index_value << scale;
// treat as non array below
- rl_index.low_reg = INVALID_REG;
+ rl_index.reg = RegStorage(RegStorage::k32BitSolo, INVALID_REG);
}
/* null object? */
- GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+ GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) {
if (constant_index) {
- GenMemImmedCheck(kCondLs, rl_array.low_reg, len_offset,
+ GenMemImmedCheck(kCondLs, rl_array.reg.GetReg(), len_offset,
constant_index_value, kThrowConstantArrayBounds);
} else {
- GenRegMemCheck(kCondUge, rl_index.low_reg, rl_array.low_reg,
+ GenRegMemCheck(kCondUge, rl_index.reg.GetReg(), rl_array.reg.GetReg(),
len_offset, kThrowArrayBounds);
}
}
rl_result = EvalLoc(rl_dest, reg_class, true);
if ((size == kLong) || (size == kDouble)) {
- LoadBaseIndexedDisp(rl_array.low_reg, rl_index.low_reg, scale, data_offset, rl_result.low_reg,
- rl_result.high_reg, size, INVALID_SREG);
+ LoadBaseIndexedDisp(rl_array.reg.GetReg(), rl_index.reg.GetReg(), scale, data_offset, rl_result.reg.GetReg(),
+ rl_result.reg.GetHighReg(), size, INVALID_SREG);
StoreValueWide(rl_dest, rl_result);
} else {
- LoadBaseIndexedDisp(rl_array.low_reg, rl_index.low_reg, scale,
- data_offset, rl_result.low_reg, INVALID_REG, size,
+ LoadBaseIndexedDisp(rl_array.reg.GetReg(), rl_index.reg.GetReg(), scale,
+ data_offset, rl_result.reg.GetReg(), INVALID_REG, size,
INVALID_SREG);
StoreValue(rl_dest, rl_result);
}
@@ -1338,18 +1340,18 @@ void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
constant_index_value = mir_graph_->ConstantValue(rl_index);
data_offset += constant_index_value << scale;
// treat as non array below
- rl_index.low_reg = INVALID_REG;
+ rl_index.reg = RegStorage(RegStorage::k32BitSolo, INVALID_REG);
}
/* null object? */
- GenNullCheck(rl_array.s_reg_low, rl_array.low_reg, opt_flags);
+ GenNullCheck(rl_array.s_reg_low, rl_array.reg.GetReg(), opt_flags);
if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) {
if (constant_index) {
- GenMemImmedCheck(kCondLs, rl_array.low_reg, len_offset,
+ GenMemImmedCheck(kCondLs, rl_array.reg.GetReg(), len_offset,
constant_index_value, kThrowConstantArrayBounds);
} else {
- GenRegMemCheck(kCondUge, rl_index.low_reg, rl_array.low_reg,
+ GenRegMemCheck(kCondUge, rl_index.reg.GetReg(), rl_array.reg.GetReg(),
len_offset, kThrowArrayBounds);
}
}
@@ -1359,21 +1361,21 @@ void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
rl_src = LoadValue(rl_src, reg_class);
}
// If the src reg can't be byte accessed, move it to a temp first.
- if ((size == kSignedByte || size == kUnsignedByte) && rl_src.low_reg >= 4) {
+ if ((size == kSignedByte || size == kUnsignedByte) && rl_src.reg.GetReg() >= 4) {
int temp = AllocTemp();
- OpRegCopy(temp, rl_src.low_reg);
- StoreBaseIndexedDisp(rl_array.low_reg, rl_index.low_reg, scale, data_offset, temp,
+ OpRegCopy(temp, rl_src.reg.GetReg());
+ StoreBaseIndexedDisp(rl_array.reg.GetReg(), rl_index.reg.GetReg(), scale, data_offset, temp,
INVALID_REG, size, INVALID_SREG);
} else {
- StoreBaseIndexedDisp(rl_array.low_reg, rl_index.low_reg, scale, data_offset, rl_src.low_reg,
- rl_src.high_reg, size, INVALID_SREG);
+ StoreBaseIndexedDisp(rl_array.reg.GetReg(), rl_index.reg.GetReg(), scale, data_offset, rl_src.reg.GetReg(),
+ rl_src.wide ? rl_src.reg.GetHighReg() : INVALID_REG, size, INVALID_SREG);
}
if (card_mark) {
// Free rl_index if its a temp. Ensures there are 2 free regs for card mark.
if (!constant_index) {
- FreeTemp(rl_index.low_reg);
+ FreeTemp(rl_index.reg.GetReg());
}
- MarkGCCard(rl_src.low_reg, rl_array.low_reg);
+ MarkGCCard(rl_src.reg.GetReg(), rl_array.reg.GetReg());
}
}
@@ -1385,52 +1387,52 @@ RegLocation X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation
case Instruction::SHL_LONG_2ADDR:
DCHECK_NE(shift_amount, 1); // Prevent a double store from happening.
if (shift_amount == 32) {
- OpRegCopy(rl_result.high_reg, rl_src.low_reg);
- LoadConstant(rl_result.low_reg, 0);
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetReg());
+ LoadConstant(rl_result.reg.GetReg(), 0);
} else if (shift_amount > 31) {
- OpRegCopy(rl_result.high_reg, rl_src.low_reg);
- FreeTemp(rl_src.high_reg);
- NewLIR2(kX86Sal32RI, rl_result.high_reg, shift_amount - 32);
- LoadConstant(rl_result.low_reg, 0);
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetReg());
+ FreeTemp(rl_src.reg.GetHighReg());
+ NewLIR2(kX86Sal32RI, rl_result.reg.GetHighReg(), shift_amount - 32);
+ LoadConstant(rl_result.reg.GetReg(), 0);
} else {
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
- OpRegCopy(rl_result.high_reg, rl_src.high_reg);
- NewLIR3(kX86Shld32RRI, rl_result.high_reg, rl_result.low_reg, shift_amount);
- NewLIR2(kX86Sal32RI, rl_result.low_reg, shift_amount);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
+ NewLIR3(kX86Shld32RRI, rl_result.reg.GetHighReg(), rl_result.reg.GetReg(), shift_amount);
+ NewLIR2(kX86Sal32RI, rl_result.reg.GetReg(), shift_amount);
}
break;
case Instruction::SHR_LONG:
case Instruction::SHR_LONG_2ADDR:
if (shift_amount == 32) {
- OpRegCopy(rl_result.low_reg, rl_src.high_reg);
- OpRegCopy(rl_result.high_reg, rl_src.high_reg);
- NewLIR2(kX86Sar32RI, rl_result.high_reg, 31);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetHighReg());
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
+ NewLIR2(kX86Sar32RI, rl_result.reg.GetHighReg(), 31);
} else if (shift_amount > 31) {
- OpRegCopy(rl_result.low_reg, rl_src.high_reg);
- OpRegCopy(rl_result.high_reg, rl_src.high_reg);
- NewLIR2(kX86Sar32RI, rl_result.low_reg, shift_amount - 32);
- NewLIR2(kX86Sar32RI, rl_result.high_reg, 31);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetHighReg());
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
+ NewLIR2(kX86Sar32RI, rl_result.reg.GetReg(), shift_amount - 32);
+ NewLIR2(kX86Sar32RI, rl_result.reg.GetHighReg(), 31);
} else {
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
- OpRegCopy(rl_result.high_reg, rl_src.high_reg);
- NewLIR3(kX86Shrd32RRI, rl_result.low_reg, rl_result.high_reg, shift_amount);
- NewLIR2(kX86Sar32RI, rl_result.high_reg, shift_amount);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
+ NewLIR3(kX86Shrd32RRI, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), shift_amount);
+ NewLIR2(kX86Sar32RI, rl_result.reg.GetHighReg(), shift_amount);
}
break;
case Instruction::USHR_LONG:
case Instruction::USHR_LONG_2ADDR:
if (shift_amount == 32) {
- OpRegCopy(rl_result.low_reg, rl_src.high_reg);
- LoadConstant(rl_result.high_reg, 0);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetHighReg());
+ LoadConstant(rl_result.reg.GetHighReg(), 0);
} else if (shift_amount > 31) {
- OpRegCopy(rl_result.low_reg, rl_src.high_reg);
- NewLIR2(kX86Shr32RI, rl_result.low_reg, shift_amount - 32);
- LoadConstant(rl_result.high_reg, 0);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetHighReg());
+ NewLIR2(kX86Shr32RI, rl_result.reg.GetReg(), shift_amount - 32);
+ LoadConstant(rl_result.reg.GetHighReg(), 0);
} else {
- OpRegCopy(rl_result.low_reg, rl_src.low_reg);
- OpRegCopy(rl_result.high_reg, rl_src.high_reg);
- NewLIR3(kX86Shrd32RRI, rl_result.low_reg, rl_result.high_reg, shift_amount);
- NewLIR2(kX86Shr32RI, rl_result.high_reg, shift_amount);
+ OpRegCopy(rl_result.reg.GetReg(), rl_src.reg.GetReg());
+ OpRegCopy(rl_result.reg.GetHighReg(), rl_src.reg.GetHighReg());
+ NewLIR3(kX86Shrd32RRI, rl_result.reg.GetReg(), rl_result.reg.GetHighReg(), shift_amount);
+ NewLIR2(kX86Shr32RI, rl_result.reg.GetHighReg(), shift_amount);
}
break;
default:
@@ -1567,7 +1569,7 @@ X86OpCode X86Mir2Lir::GetOpcode(Instruction::Code op, RegLocation loc, bool is_h
int32_t value) {
bool in_mem = loc.location != kLocPhysReg;
bool byte_imm = IS_SIMM8(value);
- DCHECK(in_mem || !IsFpReg(loc.low_reg));
+ DCHECK(in_mem || !IsFpReg(loc.reg.GetReg()));
switch (op) {
case Instruction::ADD_LONG:
case Instruction::ADD_LONG_2ADDR:
@@ -1647,15 +1649,15 @@ void X86Mir2Lir::GenLongImm(RegLocation rl_dest, RegLocation rl_src, Instruction
RegLocation rl_result = EvalLocWide(rl_dest, kCoreReg, true);
DCHECK_EQ(rl_result.location, kLocPhysReg);
- DCHECK(!IsFpReg(rl_result.low_reg));
+ DCHECK(!IsFpReg(rl_result.reg.GetReg()));
if (!IsNoOp(op, val_lo)) {
X86OpCode x86op = GetOpcode(op, rl_result, false, val_lo);
- NewLIR2(x86op, rl_result.low_reg, val_lo);
+ NewLIR2(x86op, rl_result.reg.GetReg(), val_lo);
}
if (!IsNoOp(op, val_hi)) {
X86OpCode x86op = GetOpcode(op, rl_result, true, val_hi);
- NewLIR2(x86op, rl_result.high_reg, val_hi);
+ NewLIR2(x86op, rl_result.reg.GetHighReg(), val_hi);
}
StoreValueWide(rl_dest, rl_result);
}
@@ -1671,15 +1673,15 @@ void X86Mir2Lir::GenLongLongImm(RegLocation rl_dest, RegLocation rl_src1,
// Can we do this directly into the destination registers?
if (rl_dest.location == kLocPhysReg && rl_src1.location == kLocPhysReg &&
- rl_dest.low_reg == rl_src1.low_reg && rl_dest.high_reg == rl_src1.high_reg &&
- !IsFpReg(rl_dest.low_reg)) {
+ rl_dest.reg.GetReg() == rl_src1.reg.GetReg() && rl_dest.reg.GetHighReg() == rl_src1.reg.GetHighReg() &&
+ !IsFpReg(rl_dest.reg.GetReg())) {
if (!IsNoOp(op, val_lo)) {
X86OpCode x86op = GetOpcode(op, rl_dest, false, val_lo);
- NewLIR2(x86op, rl_dest.low_reg, val_lo);
+ NewLIR2(x86op, rl_dest.reg.GetReg(), val_lo);
}
if (!IsNoOp(op, val_hi)) {
X86OpCode x86op = GetOpcode(op, rl_dest, true, val_hi);
- NewLIR2(x86op, rl_dest.high_reg, val_hi);
+ NewLIR2(x86op, rl_dest.reg.GetHighReg(), val_hi);
}
StoreFinalValueWide(rl_dest, rl_dest);
@@ -1693,11 +1695,11 @@ void X86Mir2Lir::GenLongLongImm(RegLocation rl_dest, RegLocation rl_src1,
RegLocation rl_result = ForceTempWide(rl_src1);
if (!IsNoOp(op, val_lo)) {
X86OpCode x86op = GetOpcode(op, rl_result, false, val_lo);
- NewLIR2(x86op, rl_result.low_reg, val_lo);
+ NewLIR2(x86op, rl_result.reg.GetReg(), val_lo);
}
if (!IsNoOp(op, val_hi)) {
X86OpCode x86op = GetOpcode(op, rl_result, true, val_hi);
- NewLIR2(x86op, rl_result.high_reg, val_hi);
+ NewLIR2(x86op, rl_result.reg.GetHighReg(), val_hi);
}
StoreFinalValueWide(rl_dest, rl_result);
@@ -1709,17 +1711,17 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
RegLocation rl_dest, RegLocation rl_src) {
RegLocation object = LoadValue(rl_src, kCoreReg);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- int result_reg = rl_result.low_reg;
+ int result_reg = rl_result.reg.GetReg();
// SETcc only works with EAX..EDX.
- if (result_reg == object.low_reg || result_reg >= 4) {
+ if (result_reg == object.reg.GetReg() || result_reg >= 4) {
result_reg = AllocTypedTemp(false, kCoreReg);
DCHECK_LT(result_reg, 4);
}
// Assume that there is no match.
LoadConstant(result_reg, 0);
- LIR* null_branchover = OpCmpImmBranch(kCondEq, object.low_reg, 0, NULL);
+ LIR* null_branchover = OpCmpImmBranch(kCondEq, object.reg.GetReg(), 0, NULL);
int check_class = AllocTypedTemp(false, kCoreReg);
@@ -1730,11 +1732,11 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
if (rl_method.location == kLocPhysReg) {
if (use_declaring_class) {
- LoadWordDisp(rl_method.low_reg,
+ LoadWordDisp(rl_method.reg.GetReg(),
mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
check_class);
} else {
- LoadWordDisp(rl_method.low_reg,
+ LoadWordDisp(rl_method.reg.GetReg(),
mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(),
check_class);
LoadWordDisp(check_class, offset_of_type, check_class);
@@ -1755,7 +1757,7 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
// Compare the computed class to the class in the object.
DCHECK_EQ(object.location, kLocPhysReg);
- OpRegMem(kOpCmp, check_class, object.low_reg,
+ OpRegMem(kOpCmp, check_class, object.reg.GetReg(),
mirror::Object::ClassOffset().Int32Value());
// Set the low byte of the result to 0 or 1 from the compare condition code.
@@ -1765,7 +1767,7 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx,
null_branchover->target = target;
FreeTemp(check_class);
if (IsTemp(result_reg)) {
- OpRegCopy(rl_result.low_reg, result_reg);
+ OpRegCopy(rl_result.reg.GetReg(), result_reg);
FreeTemp(result_reg);
}
StoreValue(rl_dest, rl_result);
@@ -1818,7 +1820,7 @@ void X86Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_k
RegLocation rl_result = GetReturn(false);
// SETcc only works with EAX..EDX.
- DCHECK_LT(rl_result.low_reg, 4);
+ DCHECK_LT(rl_result.reg.GetReg(), 4);
// Is the class NULL?
LIR* branch1 = OpCmpImmBranch(kCondEq, TargetReg(kArg0), 0, NULL);
@@ -1830,13 +1832,13 @@ void X86Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_k
LIR* branchover = nullptr;
if (type_known_final) {
// Ensure top 3 bytes of result are 0.
- LoadConstant(rl_result.low_reg, 0);
+ LoadConstant(rl_result.reg.GetReg(), 0);
OpRegReg(kOpCmp, TargetReg(kArg1), TargetReg(kArg2));
// Set the low byte of the result to 0 or 1 from the compare condition code.
- NewLIR2(kX86Set8R, rl_result.low_reg, kX86CondEq);
+ NewLIR2(kX86Set8R, rl_result.reg.GetReg(), kX86CondEq);
} else {
if (!type_known_abstract) {
- LoadConstant(rl_result.low_reg, 1); // Assume result succeeds.
+ LoadConstant(rl_result.reg.GetReg(), 1); // Assume result succeeds.
branchover = OpCmpBranch(kCondEq, TargetReg(kArg1), TargetReg(kArg2), NULL);
}
OpRegCopy(TargetReg(kArg0), TargetReg(kArg2));
@@ -1964,7 +1966,7 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_result = UpdateLoc(rl_dest);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegReg(op, rl_result.low_reg, rl_lhs.low_reg);
+ OpRegReg(op, rl_result.reg.GetReg(), rl_lhs.reg.GetReg());
} else {
if (shift_op) {
// X86 doesn't require masking and must use ECX.
@@ -1979,9 +1981,9 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
OpMemReg(op, rl_result, t_reg);
FreeTemp(t_reg);
return;
- } else if (!IsFpReg(rl_result.low_reg)) {
+ } else if (!IsFpReg(rl_result.reg.GetReg())) {
// Can do this directly into the result register
- OpRegReg(op, rl_result.low_reg, t_reg);
+ OpRegReg(op, rl_result.reg.GetReg(), t_reg);
FreeTemp(t_reg);
StoreFinalValue(rl_dest, rl_result);
return;
@@ -1990,7 +1992,7 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
// Three address form, or we can't do directly.
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_lhs.low_reg, t_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_lhs.reg.GetReg(), t_reg);
FreeTemp(t_reg);
} else {
// Multiply is 3 operand only (sort of).
@@ -2001,11 +2003,11 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
// Can we do this from memory directly?
rl_rhs = UpdateLoc(rl_rhs);
if (rl_rhs.location != kLocPhysReg) {
- OpRegMem(op, rl_result.low_reg, rl_rhs);
+ OpRegMem(op, rl_result.reg.GetReg(), rl_rhs);
StoreFinalValue(rl_dest, rl_result);
return;
- } else if (!IsFpReg(rl_rhs.low_reg)) {
- OpRegReg(op, rl_result.low_reg, rl_rhs.low_reg);
+ } else if (!IsFpReg(rl_rhs.reg.GetReg())) {
+ OpRegReg(op, rl_result.reg.GetReg(), rl_rhs.reg.GetReg());
StoreFinalValue(rl_dest, rl_result);
return;
}
@@ -2013,17 +2015,17 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
rl_rhs = LoadValue(rl_rhs, kCoreReg);
if (rl_result.location != kLocPhysReg) {
// Okay, we can do this into memory.
- OpMemReg(op, rl_result, rl_rhs.low_reg);
+ OpMemReg(op, rl_result, rl_rhs.reg.GetReg());
return;
- } else if (!IsFpReg(rl_result.low_reg)) {
+ } else if (!IsFpReg(rl_result.reg.GetReg())) {
// Can do this directly into the result register.
- OpRegReg(op, rl_result.low_reg, rl_rhs.low_reg);
+ OpRegReg(op, rl_result.reg.GetReg(), rl_rhs.reg.GetReg());
StoreFinalValue(rl_dest, rl_result);
return;
} else {
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_lhs.low_reg, rl_rhs.low_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_lhs.reg.GetReg(), rl_rhs.reg.GetReg());
}
} else {
// Try to use reg/memory instructions.
@@ -2035,34 +2037,34 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_rhs = LoadValue(rl_rhs, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_lhs.low_reg, rl_rhs.low_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_lhs.reg.GetReg(), rl_rhs.reg.GetReg());
} else {
// We can optimize by moving to result and using memory operands.
if (rl_rhs.location != kLocPhysReg) {
// Force LHS into result.
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- LoadValueDirect(rl_lhs, rl_result.low_reg);
- OpRegMem(op, rl_result.low_reg, rl_rhs);
+ LoadValueDirect(rl_lhs, rl_result.reg.GetReg());
+ OpRegMem(op, rl_result.reg.GetReg(), rl_rhs);
} else if (rl_lhs.location != kLocPhysReg) {
// RHS is in a register; LHS is in memory.
if (op != kOpSub) {
// Force RHS into result and operate on memory.
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegCopy(rl_result.low_reg, rl_rhs.low_reg);
- OpRegMem(op, rl_result.low_reg, rl_lhs);
+ OpRegCopy(rl_result.reg.GetReg(), rl_rhs.reg.GetReg());
+ OpRegMem(op, rl_result.reg.GetReg(), rl_lhs);
} else {
// Subtraction isn't commutative.
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_rhs = LoadValue(rl_rhs, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_lhs.low_reg, rl_rhs.low_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_lhs.reg.GetReg(), rl_rhs.reg.GetReg());
}
} else {
// Both are in registers.
rl_lhs = LoadValue(rl_lhs, kCoreReg);
rl_rhs = LoadValue(rl_rhs, kCoreReg);
rl_result = EvalLoc(rl_dest, kCoreReg, true);
- OpRegRegReg(op, rl_result.low_reg, rl_lhs.low_reg, rl_rhs.low_reg);
+ OpRegRegReg(op, rl_result.reg.GetReg(), rl_lhs.reg.GetReg(), rl_rhs.reg.GetReg());
}
}
}
@@ -2073,10 +2075,10 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
bool X86Mir2Lir::IsOperationSafeWithoutTemps(RegLocation rl_lhs, RegLocation rl_rhs) {
// If we have non-core registers, then we can't do good things.
- if (rl_lhs.location == kLocPhysReg && IsFpReg(rl_lhs.low_reg)) {
+ if (rl_lhs.location == kLocPhysReg && IsFpReg(rl_lhs.reg.GetReg())) {
return false;
}
- if (rl_rhs.location == kLocPhysReg && IsFpReg(rl_rhs.low_reg)) {
+ if (rl_rhs.location == kLocPhysReg && IsFpReg(rl_rhs.reg.GetReg())) {
return false;
}
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index eea7191c3b..0b8e1ee799 100644
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -49,23 +49,19 @@ namespace art {
};
RegLocation X86Mir2Lir::LocCReturn() {
- RegLocation res = X86_LOC_C_RETURN;
- return res;
+ return x86_loc_c_return;
}
RegLocation X86Mir2Lir::LocCReturnWide() {
- RegLocation res = X86_LOC_C_RETURN_WIDE;
- return res;
+ return x86_loc_c_return_wide;
}
RegLocation X86Mir2Lir::LocCReturnFloat() {
- RegLocation res = X86_LOC_C_RETURN_FLOAT;
- return res;
+ return x86_loc_c_return_float;
}
RegLocation X86Mir2Lir::LocCReturnDouble() {
- RegLocation res = X86_LOC_C_RETURN_DOUBLE;
- return res;
+ return x86_loc_c_return_double;
}
// Return a target-dependent special register.
@@ -390,19 +386,19 @@ void X86Mir2Lir::ClobberCallerSave() {
RegLocation X86Mir2Lir::GetReturnWideAlt() {
RegLocation res = LocCReturnWide();
- CHECK(res.low_reg == rAX);
- CHECK(res.high_reg == rDX);
+ CHECK(res.reg.GetReg() == rAX);
+ CHECK(res.reg.GetHighReg() == rDX);
Clobber(rAX);
Clobber(rDX);
MarkInUse(rAX);
MarkInUse(rDX);
- MarkPair(res.low_reg, res.high_reg);
+ MarkPair(res.reg.GetReg(), res.reg.GetHighReg());
return res;
}
RegLocation X86Mir2Lir::GetReturnAlt() {
RegLocation res = LocCReturn();
- res.low_reg = rDX;
+ res.reg.SetReg(rDX);
Clobber(rDX);
MarkInUse(rDX);
return res;
@@ -430,27 +426,21 @@ void X86Mir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) {
NewLIR0(kX86Mfence);
#endif
}
-/*
- * Alloc a pair of core registers, or a double. Low reg in low byte,
- * high reg in next byte.
- */
-int X86Mir2Lir::AllocTypedTempPair(bool fp_hint,
- int reg_class) {
+
+// Alloc a pair of core registers, or a double.
+RegStorage X86Mir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
int high_reg;
int low_reg;
- int res = 0;
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
low_reg = AllocTempDouble();
high_reg = low_reg; // only one allocated!
- res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
- return res;
+ // TODO: take advantage of 64-bit notation.
+ return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
}
-
low_reg = AllocTemp();
high_reg = AllocTemp();
- res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
- return res;
+ return RegStorage(RegStorage::k64BitPair, low_reg, high_reg);
}
int X86Mir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
@@ -493,11 +483,11 @@ void X86Mir2Lir::CompilerInitializeRegAlloc() {
void X86Mir2Lir::FreeRegLocTemps(RegLocation rl_keep,
RegLocation rl_free) {
- if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
- (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
+ 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.low_reg);
- FreeTemp(rl_free.high_reg);
+ FreeTemp(rl_free.reg.GetReg());
+ FreeTemp(rl_free.reg.GetHighReg());
}
}
@@ -601,11 +591,11 @@ RegLocation X86Mir2Lir::UpdateLocWide(RegLocation loc) {
if (match) {
// We can reuse;update the register usage info.
- loc.low_reg = info_lo->reg;
- loc.high_reg = info_lo->reg; // Play nice with existing code.
loc.location = kLocPhysReg;
loc.vec_len = kVectorLength8;
- DCHECK(IsFpReg(loc.low_reg));
+ // TODO: use k64BitVector
+ loc.reg = RegStorage(RegStorage::k64BitPair, info_lo->reg, info_lo->reg);
+ DCHECK(IsFpReg(loc.reg.GetReg()));
return loc;
}
// We can't easily reuse; clobber and free any overlaps.
@@ -635,11 +625,10 @@ RegLocation X86Mir2Lir::UpdateLocWide(RegLocation loc) {
}
if (match) {
// Can reuse - update the register usage info
- loc.low_reg = info_lo->reg;
- loc.high_reg = info_hi->reg;
+ loc.reg = RegStorage(RegStorage::k64BitPair, info_lo->reg, info_hi->reg);
loc.location = kLocPhysReg;
- MarkPair(loc.low_reg, loc.high_reg);
- DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
+ DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
return loc;
}
// Can't easily reuse - clobber and free any overlaps
@@ -663,7 +652,6 @@ RegLocation X86Mir2Lir::UpdateLocWide(RegLocation loc) {
// TODO: Reunify with common code after 'pair mess' has been fixed
RegLocation X86Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update) {
DCHECK(loc.wide);
- int32_t new_regs;
int32_t low_reg;
int32_t high_reg;
@@ -671,38 +659,37 @@ RegLocation X86Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update)
/* If it is already in a register, we can assume proper form. Is it the right reg class? */
if (loc.location == kLocPhysReg) {
- DCHECK_EQ(IsFpReg(loc.low_reg), loc.IsVectorScalar());
- if (!RegClassMatches(reg_class, loc.low_reg)) {
+ DCHECK_EQ(IsFpReg(loc.reg.GetReg()), loc.IsVectorScalar());
+ if (!RegClassMatches(reg_class, loc.reg.GetReg())) {
/* It is the wrong register class. Reallocate and copy. */
- if (!IsFpReg(loc.low_reg)) {
+ if (!IsFpReg(loc.reg.GetReg())) {
// We want this in a FP reg, and it is in core registers.
DCHECK(reg_class != kCoreReg);
// Allocate this into any FP reg, and mark it with the right size.
low_reg = AllocTypedTemp(true, reg_class);
- OpVectorRegCopyWide(low_reg, loc.low_reg, loc.high_reg);
- CopyRegInfo(low_reg, loc.low_reg);
- Clobber(loc.low_reg);
- Clobber(loc.high_reg);
- loc.low_reg = low_reg;
- loc.high_reg = low_reg; // Play nice with existing code.
+ OpVectorRegCopyWide(low_reg, loc.reg.GetReg(), loc.reg.GetHighReg());
+ CopyRegInfo(low_reg, loc.reg.GetReg());
+ Clobber(loc.reg.GetReg());
+ Clobber(loc.reg.GetHighReg());
+ loc.reg.SetReg(low_reg);
+ loc.reg.SetHighReg(low_reg); // Play nice with existing code.
loc.vec_len = kVectorLength8;
} else {
// The value is in a FP register, and we want it in a pair of core registers.
DCHECK_EQ(reg_class, kCoreReg);
- DCHECK_EQ(loc.low_reg, loc.high_reg);
- new_regs = AllocTypedTempPair(false, kCoreReg); // Force to core registers.
- low_reg = new_regs & 0xff;
- high_reg = (new_regs >> 8) & 0xff;
+ DCHECK_EQ(loc.reg.GetReg(), loc.reg.GetHighReg());
+ RegStorage new_regs = AllocTypedTempWide(false, kCoreReg); // Force to core registers.
+ low_reg = new_regs.GetReg();
+ high_reg = new_regs.GetHighReg();
DCHECK_NE(low_reg, high_reg);
- OpRegCopyWide(low_reg, high_reg, loc.low_reg, loc.high_reg);
- CopyRegInfo(low_reg, loc.low_reg);
- CopyRegInfo(high_reg, loc.high_reg);
- Clobber(loc.low_reg);
- Clobber(loc.high_reg);
- loc.low_reg = low_reg;
- loc.high_reg = high_reg;
- MarkPair(loc.low_reg, loc.high_reg);
- DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ 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());
+ loc.reg = new_regs;
+ MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
+ DCHECK(!IsFpReg(loc.reg.GetReg()) || ((loc.reg.GetReg() & 0x1) == 0));
}
}
return loc;
@@ -711,21 +698,20 @@ RegLocation X86Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update)
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
DCHECK_NE(GetSRegHi(loc.s_reg_low), INVALID_SREG);
- new_regs = AllocTypedTempPair(loc.fp, reg_class);
- loc.low_reg = new_regs & 0xff;
- loc.high_reg = (new_regs >> 8) & 0xff;
+ loc.reg = AllocTypedTempWide(loc.fp, reg_class);
- if (loc.low_reg == loc.high_reg) {
- DCHECK(IsFpReg(loc.low_reg));
+ // FIXME: take advantage of RegStorage notation.
+ if (loc.reg.GetReg() == loc.reg.GetHighReg()) {
+ DCHECK(IsFpReg(loc.reg.GetReg()));
loc.vec_len = kVectorLength8;
} else {
- MarkPair(loc.low_reg, loc.high_reg);
+ MarkPair(loc.reg.GetReg(), loc.reg.GetHighReg());
}
if (update) {
loc.location = kLocPhysReg;
- MarkLive(loc.low_reg, loc.s_reg_low);
- if (loc.low_reg != loc.high_reg) {
- MarkLive(loc.high_reg, GetSRegHi(loc.s_reg_low));
+ MarkLive(loc.reg.GetReg(), loc.s_reg_low);
+ if (loc.reg.GetReg() != loc.reg.GetHighReg()) {
+ MarkLive(loc.reg.GetHighReg(), GetSRegHi(loc.s_reg_low));
}
}
return loc;
@@ -741,14 +727,14 @@ RegLocation X86Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update) {
loc = UpdateLoc(loc);
if (loc.location == kLocPhysReg) {
- if (!RegClassMatches(reg_class, loc.low_reg)) {
+ if (!RegClassMatches(reg_class, loc.reg.GetReg())) {
/* Wrong register class. Realloc, copy and transfer ownership. */
new_reg = AllocTypedTemp(loc.fp, reg_class);
- OpRegCopy(new_reg, loc.low_reg);
- CopyRegInfo(new_reg, loc.low_reg);
- Clobber(loc.low_reg);
- loc.low_reg = new_reg;
- if (IsFpReg(loc.low_reg) && reg_class != kCoreReg)
+ OpRegCopy(new_reg, loc.reg.GetReg());
+ CopyRegInfo(new_reg, loc.reg.GetReg());
+ Clobber(loc.reg.GetReg());
+ loc.reg.SetReg(new_reg);
+ if (IsFpReg(loc.reg.GetReg()) && reg_class != kCoreReg)
loc.vec_len = kVectorLength4;
}
return loc;
@@ -756,14 +742,13 @@ RegLocation X86Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update) {
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
- new_reg = AllocTypedTemp(loc.fp, reg_class);
- loc.low_reg = new_reg;
- if (IsFpReg(loc.low_reg) && reg_class != kCoreReg)
+ loc.reg = RegStorage(RegStorage::k32BitSolo, AllocTypedTemp(loc.fp, reg_class));
+ if (IsFpReg(loc.reg.GetReg()) && reg_class != kCoreReg)
loc.vec_len = kVectorLength4;
if (update) {
loc.location = kLocPhysReg;
- MarkLive(loc.low_reg, loc.s_reg_low);
+ MarkLive(loc.reg.GetReg(), loc.s_reg_low);
}
return loc;
}
@@ -776,15 +761,15 @@ int X86Mir2Lir::AllocTempDouble() {
// TODO: Reunify with common code after 'pair mess' has been fixed
void X86Mir2Lir::ResetDefLocWide(RegLocation rl) {
DCHECK(rl.wide);
- RegisterInfo* p_low = IsTemp(rl.low_reg);
- if (IsFpReg(rl.low_reg)) {
+ RegisterInfo* p_low = IsTemp(rl.reg.GetReg());
+ if (IsFpReg(rl.reg.GetReg())) {
// We are using only the low register.
if (p_low && !(cu_->disable_opt & (1 << kSuppressLoads))) {
NullifyRange(p_low->def_start, p_low->def_end, p_low->s_reg, rl.s_reg_low);
}
- ResetDef(rl.low_reg);
+ ResetDef(rl.reg.GetReg());
} else {
- RegisterInfo* p_high = IsTemp(rl.high_reg);
+ RegisterInfo* p_high = IsTemp(rl.reg.GetHighReg());
if (p_low && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_low->pair);
NullifyRange(p_low->def_start, p_low->def_end, p_low->s_reg, rl.s_reg_low);
@@ -792,8 +777,8 @@ void X86Mir2Lir::ResetDefLocWide(RegLocation rl) {
if (p_high && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_high->pair);
}
- ResetDef(rl.low_reg);
- ResetDef(rl.high_reg);
+ ResetDef(rl.reg.GetReg());
+ ResetDef(rl.reg.GetHighReg());
}
}
@@ -832,8 +817,8 @@ void X86Mir2Lir::DumpRegLocation(RegLocation loc) {
<< (loc.high_word ? " h" : " ")
<< (loc.home ? " H" : " ")
<< " vec_len: " << loc.vec_len
- << ", low: " << static_cast<int>(loc.low_reg)
- << ", high: " << static_cast<int>(loc.high_reg)
+ << ", low: " << static_cast<int>(loc.reg.GetReg())
+ << ", high: " << static_cast<int>(loc.reg.GetHighReg())
<< ", s_reg: " << loc.s_reg_low
<< ", orig: " << loc.orig_sreg;
}
@@ -1036,8 +1021,8 @@ bool X86Mir2Lir::GenInlinedIndexOf(CallInfo* info, bool zero_based) {
// Runtime start index.
rl_start = UpdateLoc(rl_start);
if (rl_start.location == kLocPhysReg) {
- length_compare = OpCmpBranch(kCondLe, rCX, rl_start.low_reg, nullptr);
- OpRegReg(kOpSub, rCX, rl_start.low_reg);
+ length_compare = OpCmpBranch(kCondLe, rCX, rl_start.reg.GetReg(), nullptr);
+ OpRegReg(kOpSub, rCX, rl_start.reg.GetReg());
} else {
// Compare to memory to avoid a register load. Handle pushed EDI.
int displacement = SRegOffset(rl_start.s_reg_low) + sizeof(uint32_t);
@@ -1066,13 +1051,13 @@ bool X86Mir2Lir::GenInlinedIndexOf(CallInfo* info, bool zero_based) {
}
} else {
if (rl_start.location == kLocPhysReg) {
- if (rl_start.low_reg == rDI) {
+ if (rl_start.reg.GetReg() == rDI) {
// We have a slight problem here. We are already using RDI!
// Grab the value from the stack.
LoadWordDisp(rX86_SP, 0, rDX);
OpLea(rDI, rBX, rDX, 1, 0);
} else {
- OpLea(rDI, rBX, rl_start.low_reg, 1, 0);
+ OpLea(rDI, rBX, rl_start.reg.GetReg(), 1, 0);
}
} else {
OpRegCopy(rDI, rBX);
@@ -1094,14 +1079,14 @@ bool X86Mir2Lir::GenInlinedIndexOf(CallInfo* info, bool zero_based) {
// index = ((curr_ptr - orig_ptr) / 2) - 1.
OpRegReg(kOpSub, rDI, rBX);
OpRegImm(kOpAsr, rDI, 1);
- NewLIR3(kX86Lea32RM, rl_return.low_reg, rDI, -1);
+ NewLIR3(kX86Lea32RM, rl_return.reg.GetReg(), rDI, -1);
LIR *all_done = NewLIR1(kX86Jmp8, 0);
// Failed to match; return -1.
LIR *not_found = NewLIR0(kPseudoTargetLabel);
length_compare->target = not_found;
failed_branch->target = not_found;
- LoadConstantNoClobber(rl_return.low_reg, -1);
+ LoadConstantNoClobber(rl_return.reg.GetReg(), -1);
// And join up at the end.
all_done->target = NewLIR0(kPseudoTargetLabel);
diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc
index 48a39bb5b4..d5d6b0e348 100644
--- a/compiler/dex/quick/x86/utility_x86.cc
+++ b/compiler/dex/quick/x86/utility_x86.cc
@@ -514,7 +514,7 @@ LIR* X86Mir2Lir::LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value) {
// We don't know the proper offset for the value, so pick one that will force
// 4 byte offset. We will fix this up in the assembler later to have the right
// value.
- res = LoadBaseDisp(rl_method.low_reg, 256 /* bogus */, r_dest_lo, kDouble, INVALID_SREG);
+ res = LoadBaseDisp(rl_method.reg.GetReg(), 256 /* bogus */, r_dest_lo, kDouble, INVALID_SREG);
res->target = data_target;
res->flags.fixup = kFixupLoad;
SetMemRefType(res, true, kLiteral);
@@ -714,7 +714,7 @@ LIR* X86Mir2Lir::StoreBaseIndexedDisp(int rBase, int r_index, int scale,
opcode = is_array ? kX86Mov8AR : kX86Mov8MR;
break;
default:
- LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody";
+ LOG(FATAL) << "Bad case in StoreBaseIndexedDispBody";
}
if (!is_array) {
diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h
index 4064bd6550..1df9ab1ec3 100644
--- a/compiler/dex/quick/x86/x86_lir.h
+++ b/compiler/dex/quick/x86/x86_lir.h
@@ -126,13 +126,6 @@ namespace art {
/* Mask to strip off fp flags */
#define X86_FP_REG_MASK 0xF
-// RegisterLocation templates return values (rAX, rAX/rDX or XMM0).
-// location, wide, defined, const, fp, core, ref, high_word, home, vec_len, low_reg, high_reg, s_reg_low
-#define X86_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, rAX, INVALID_REG, INVALID_SREG, INVALID_SREG}
-#define X86_LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, rAX, rDX, INVALID_SREG, INVALID_SREG}
-#define X86_LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorLength4, fr0, INVALID_REG, INVALID_SREG, INVALID_SREG}
-#define X86_LOC_C_RETURN_DOUBLE {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorLength8, fr0, fr0, INVALID_SREG, INVALID_SREG}
-
enum X86ResourceEncodingPos {
kX86GPReg0 = 0,
kX86RegSP = 4,
@@ -211,6 +204,22 @@ enum X86NativeRegisterPool {
#define rX86_COUNT rCX
#define rX86_PC INVALID_REG
+// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
+const RegLocation x86_loc_c_return
+ {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
+const RegLocation x86_loc_c_return_wide
+ {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed,
+ RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
+// TODO: update to use k32BitVector (must encode in 7 bits, including fp flag).
+const RegLocation x86_loc_c_return_float
+ {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorLength4,
+ RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
+// TODO: update to use k64BitVector (must encode in 7 bits, including fp flag).
+const RegLocation x86_loc_c_return_double
+ {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorLength8,
+ RegStorage(RegStorage::k64BitPair, fr0, fr1), INVALID_SREG, INVALID_SREG};
+
/*
* The following enum defines the list of supported X86 instructions by the
* assembler. Their corresponding EncodingMap positions will be defined in
diff --git a/compiler/dex/reg_storage.h b/compiler/dex/reg_storage.h
new file mode 100644
index 0000000000..c59617edea
--- /dev/null
+++ b/compiler/dex/reg_storage.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_COMPILER_DEX_REG_STORAGE_H_
+#define ART_COMPILER_DEX_REG_STORAGE_H_
+
+
+namespace art {
+
+/*
+ * Representation of the physical register, register pair or vector holding a Dalvik value.
+ * The basic configuration of the storage (i.e. solo reg, pair, vector) is common across all
+ * targets, but the encoding of the actual storage element is target independent.
+ *
+ * The two most-significant bits describe the basic shape of the storage, while meaning of the
+ * lower 14 bits depends on the shape:
+ *
+ * [PW]
+ * P: 0 -> pair, 1 -> solo (or vector)
+ * W: 1 -> 64 bits, 0 -> 32 bits
+ *
+ * [00] [xxxxxxxxxxxxxx] Invalid (typically all zeros)
+ * [01] [HHHHHHH] [LLLLLLL] 64-bit storage, composed of 2 32-bit registers
+ * [10] [0] [xxxxxx] [RRRRRRR] 32-bit solo register
+ * [11] [0] [xxxxxx] [RRRRRRR] 64-bit solo register
+ * [10] [1] [xxxxxx] [VVVVVVV] 32-bit vector storage
+ * [11] [1] [xxxxxx] [VVVVVVV] 64-bit vector storage
+ *
+ * x - don't care
+ * L - low register number of a pair
+ * H - high register number of a pair
+ * R - register number of a solo reg
+ * V - vector description
+ *
+ * Note that in all non-invalid cases, the low 7 bits must be sufficient to describe
+ * whether the storage element is floating point (see IsFloatReg()).
+ *
+ */
+
+class RegStorage {
+ public:
+ enum RegStorageKind {
+ kInvalid = 0x0000,
+ k64BitPair = 0x4000,
+ k32BitSolo = 0x8000,
+ k64BitSolo = 0xc000,
+ k32BitVector = 0xa000,
+ k64BitVector = 0xe000,
+ kPairMask = 0x8000,
+ kPair = 0x0000,
+ kSizeMask = 0x4000,
+ k64Bit = 0x4000,
+ k32Bit = 0x0000,
+ kVectorMask = 0xa000,
+ kVector = 0xa000,
+ kSolo = 0x8000,
+ kShapeMask = 0xc000,
+ kKindMask = 0xe000
+ };
+
+ static const uint16_t kRegValMask = 0x007f;
+ static const uint16_t kHighRegShift = 7;
+ static const uint16_t kHighRegMask = kRegValMask << kHighRegShift;
+
+ RegStorage(RegStorageKind rs_kind, int reg) {
+ DCHECK_NE(rs_kind & kShapeMask, kInvalid);
+ DCHECK_NE(rs_kind & kShapeMask, k64BitPair);
+ DCHECK_EQ(rs_kind & ~kKindMask, 0);
+ DCHECK_EQ(reg & ~kRegValMask, 0);
+ reg_ = rs_kind | reg;
+ }
+ RegStorage(RegStorageKind rs_kind, int low_reg, int high_reg) {
+ DCHECK_EQ(rs_kind, k64BitPair);
+ DCHECK_EQ(low_reg & ~kRegValMask, 0);
+ DCHECK_EQ(high_reg & ~kRegValMask, 0);
+ reg_ = rs_kind | (high_reg << kHighRegShift) | low_reg;
+ }
+ explicit RegStorage(uint16_t val) : reg_(val) {}
+ RegStorage() : reg_(kInvalid) {}
+ ~RegStorage() {}
+
+ bool IsInvalid() const {
+ return ((reg_ & kShapeMask) == kInvalid);
+ }
+
+ bool Is32Bit() const {
+ DCHECK(!IsInvalid());
+ return ((reg_ & kSizeMask) == k32Bit);
+ }
+
+ bool Is64Bit() const {
+ DCHECK(!IsInvalid());
+ return ((reg_ & kSizeMask) == k64Bit);
+ }
+
+ bool IsPair() const {
+ DCHECK(!IsInvalid());
+ return ((reg_ & kPairMask) == kPair);
+ }
+
+ bool IsSolo() const {
+ DCHECK(!IsInvalid());
+ return ((reg_ & kVectorMask) == kSolo);
+ }
+
+ bool IsVector() const {
+ DCHECK(!IsInvalid());
+ return ((reg_ & kVectorMask) == kVector);
+ }
+
+ // Used to retrieve either the low register of a pair, or the only register.
+ int GetReg() const {
+ DCHECK(!IsInvalid());
+ return (reg_ & kRegValMask);
+ }
+
+ void SetReg(int reg) {
+ DCHECK(!IsInvalid());
+ reg_ = (reg_ & ~kRegValMask) | reg;
+ DCHECK_EQ(GetReg(), reg);
+ }
+
+ // Retrieve the most significant register of a pair.
+ int GetHighReg() const {
+ DCHECK(IsPair());
+ return (reg_ & kHighRegMask) >> kHighRegShift;
+ }
+
+ void SetHighReg(int reg) {
+ DCHECK(IsPair());
+ reg_ = (reg_ & ~kHighRegMask) | (reg << kHighRegShift);
+ DCHECK_EQ(GetHighReg(), reg);
+ }
+
+ int GetRawBits() const {
+ return reg_;
+ }
+
+ private:
+ uint16_t reg_;
+};
+
+} // namespace art
+
+#endif // ART_COMPILER_DEX_REG_STORAGE_H_
diff --git a/compiler/dex/vreg_analysis.cc b/compiler/dex/vreg_analysis.cc
index f8dc223af7..4d2c05166b 100644
--- a/compiler/dex/vreg_analysis.cc
+++ b/compiler/dex/vreg_analysis.cc
@@ -379,16 +379,14 @@ void MIRGraph::DumpRegLocTable(RegLocation* table, int count) {
Mir2Lir* cg = static_cast<Mir2Lir*>(cu_->cg.get());
if (cg != NULL) {
for (int i = 0; i < count; i++) {
- LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c %c%d %c%d S%d",
+ LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c 0x%04x S%d",
table[i].orig_sreg, storage_name[table[i].location],
table[i].wide ? 'W' : 'N', table[i].defined ? 'D' : 'U',
table[i].fp ? 'F' : table[i].ref ? 'R' :'C',
table[i].is_const ? 'c' : 'n',
table[i].high_word ? 'H' : 'L', table[i].home ? 'h' : 't',
- cg->IsFpReg(table[i].low_reg) ? 's' : 'r',
- table[i].low_reg & cg->FpRegMask(),
- cg->IsFpReg(table[i].high_reg) ? 's' : 'r',
- table[i].high_reg & cg->FpRegMask(), table[i].s_reg_low);
+ table[i].reg.GetRawBits(),
+ table[i].s_reg_low);
}
} else {
// Either pre-regalloc or Portable.
@@ -404,9 +402,9 @@ void MIRGraph::DumpRegLocTable(RegLocation* table, int count) {
}
}
-static const RegLocation fresh_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
- kVectorNotUsed, INVALID_REG, INVALID_REG, INVALID_SREG,
- INVALID_SREG};
+// FIXME - will likely need to revisit all uses of this.
+static const RegLocation fresh_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, kVectorNotUsed,
+ RegStorage(), INVALID_SREG, INVALID_SREG};
void MIRGraph::InitRegLocations() {
/* Allocate the location map */