diff options
Diffstat (limited to 'compiler/dex/quick/mips/utility_mips.cc')
-rw-r--r-- | compiler/dex/quick/mips/utility_mips.cc | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc index b49f436..d28abbf 100644 --- a/compiler/dex/quick/mips/utility_mips.cc +++ b/compiler/dex/quick/mips/utility_mips.cc @@ -342,6 +342,10 @@ LIR* MipsMir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, R LIR* MipsMir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) { LIR *res; + if (!r_dest.IsPair()) { + // Form 64-bit pair + r_dest = Solo64ToPair64(r_dest); + } res = LoadConstantNoClobber(r_dest.GetLow(), Low32Bits(value)); LoadConstantNoClobber(r_dest.GetHigh(), High32Bits(value)); return res; @@ -448,7 +452,7 @@ LIR* MipsMir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegSto // FIXME: don't split r_dest into 2 containers. LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest, - RegStorage r_dest_hi, OpSize size) { + OpSize size) { /* * Load value from base + displacement. Optionally perform null check * on base (which must have an associated s_reg and MIR). If not @@ -462,23 +466,21 @@ LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStora LIR *load2 = NULL; MipsOpCode opcode = kMipsNop; bool short_form = IS_SIMM16(displacement); - bool pair = false; + bool pair = r_dest.IsPair(); switch (size) { case k64: case kDouble: - pair = true; - opcode = kMipsLw; + if (!pair) { + // Form 64-bit pair + r_dest = Solo64ToPair64(r_dest); + pair = 1; + } if (r_dest.IsFloat()) { + DCHECK_EQ(r_dest.GetLowReg(), r_dest.GetHighReg() - 1); opcode = kMipsFlwc1; - if (r_dest.IsDouble()) { - int reg_num = (r_dest.GetRegNum() << 1) | RegStorage::kFloatingPoint; - r_dest = RegStorage(RegStorage::k64BitSolo, reg_num, reg_num + 1); - } else { - DCHECK(r_dest_hi.IsFloat()); - DCHECK_EQ(r_dest.GetReg(), r_dest_hi.GetReg() - 1); - r_dest_hi.SetReg(r_dest.GetReg() + 1); - } + } else { + opcode = kMipsLw; } short_form = IS_SIMM16_2WORD(displacement); DCHECK_EQ((displacement & 0x3), 0); @@ -515,15 +517,15 @@ LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStora if (!pair) { load = res = NewLIR3(opcode, r_dest.GetReg(), displacement, r_base.GetReg()); } else { - load = res = NewLIR3(opcode, r_dest.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg()); - load2 = NewLIR3(opcode, r_dest_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg()); + load = res = NewLIR3(opcode, r_dest.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg()); + load2 = NewLIR3(opcode, r_dest.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg()); } } else { if (pair) { RegStorage r_tmp = AllocTemp(); res = OpRegRegImm(kOpAdd, r_tmp, r_base, displacement); - load = NewLIR3(opcode, r_dest.GetReg(), LOWORD_OFFSET, r_tmp.GetReg()); - load2 = NewLIR3(opcode, r_dest_hi.GetReg(), HIWORD_OFFSET, r_tmp.GetReg()); + load = NewLIR3(opcode, r_dest.GetLowReg(), LOWORD_OFFSET, r_tmp.GetReg()); + load2 = NewLIR3(opcode, r_dest.GetHighReg(), HIWORD_OFFSET, r_tmp.GetReg()); FreeTemp(r_tmp); } else { RegStorage r_tmp = (r_base == r_dest) ? AllocTemp() : r_dest; @@ -557,11 +559,7 @@ LIR* MipsMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r size = k32; } LIR* load; - if (size == k64 || size == kDouble) { - load = LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), size); - } else { - load = LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size); - } + load = LoadBaseDispBody(r_base, displacement, r_dest, size); if (UNLIKELY(is_volatile == kVolatile)) { // Without context sensitive analysis, we must issue the most conservative barriers. @@ -575,7 +573,7 @@ LIR* MipsMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r // FIXME: don't split r_dest into 2 containers. LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement, - RegStorage r_src, RegStorage r_src_hi, OpSize size) { + RegStorage r_src, OpSize size) { LIR *res; LIR *store = NULL; LIR *store2 = NULL; @@ -586,17 +584,16 @@ LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement, switch (size) { case k64: case kDouble: - opcode = kMipsSw; + if (!pair) { + // Form 64-bit pair + r_src = Solo64ToPair64(r_src); + pair = 1; + } if (r_src.IsFloat()) { + DCHECK_EQ(r_src.GetLowReg(), r_src.GetHighReg() - 1); opcode = kMipsFswc1; - if (r_src.IsDouble()) { - int reg_num = (r_src.GetRegNum() << 1) | RegStorage::kFloatingPoint; - r_src = RegStorage(RegStorage::k64BitPair, reg_num, reg_num + 1); - } else { - DCHECK(r_src_hi.IsFloat()); - DCHECK_EQ(r_src.GetReg(), (r_src_hi.GetReg() - 1)); - r_src_hi.SetReg(r_src.GetReg() + 1); - } + } else { + opcode = kMipsSw; } short_form = IS_SIMM16_2WORD(displacement); DCHECK_EQ((displacement & 0x3), 0); @@ -628,8 +625,8 @@ LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement, if (!pair) { store = res = NewLIR3(opcode, r_src.GetReg(), displacement, r_base.GetReg()); } else { - store = res = NewLIR3(opcode, r_src.GetReg(), displacement + LOWORD_OFFSET, r_base.GetReg()); - store2 = NewLIR3(opcode, r_src_hi.GetReg(), displacement + HIWORD_OFFSET, r_base.GetReg()); + store = res = NewLIR3(opcode, r_src.GetLowReg(), displacement + LOWORD_OFFSET, r_base.GetReg()); + store2 = NewLIR3(opcode, r_src.GetHighReg(), displacement + HIWORD_OFFSET, r_base.GetReg()); } } else { RegStorage r_scratch = AllocTemp(); @@ -637,8 +634,8 @@ LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement, if (!pair) { store = NewLIR3(opcode, r_src.GetReg(), 0, r_scratch.GetReg()); } else { - store = NewLIR3(opcode, r_src.GetReg(), LOWORD_OFFSET, r_scratch.GetReg()); - store2 = NewLIR3(opcode, r_src_hi.GetReg(), HIWORD_OFFSET, r_scratch.GetReg()); + store = NewLIR3(opcode, r_src.GetLowReg(), LOWORD_OFFSET, r_scratch.GetReg()); + store2 = NewLIR3(opcode, r_src.GetHighReg(), HIWORD_OFFSET, r_scratch.GetReg()); } FreeTemp(r_scratch); } @@ -669,11 +666,7 @@ LIR* MipsMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage size = k32; } LIR* store; - if (size == k64 || size == kDouble) { - store = StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), size); - } else { - store = StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size); - } + store = StoreBaseDispBody(r_base, displacement, r_src, size); if (UNLIKELY(is_volatile == kVolatile)) { // A load might follow the volatile store so insert a StoreLoad barrier. |