diff options
Diffstat (limited to 'compiler/dex/quick/mips/target_mips.cc')
-rw-r--r-- | compiler/dex/quick/mips/target_mips.cc | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc index 76b5243..1d02cf7 100644 --- a/compiler/dex/quick/mips/target_mips.cc +++ b/compiler/dex/quick/mips/target_mips.cc @@ -75,6 +75,13 @@ RegLocation MipsMir2Lir::LocCReturnDouble() { return mips_loc_c_return_double; } +// Convert k64BitSolo into k64BitPair +RegStorage MipsMir2Lir::Solo64ToPair64(RegStorage reg) { + DCHECK(reg.IsDouble()); + int reg_num = (reg.GetRegNum() & ~1) | RegStorage::kFloatingPoint; + return RegStorage(RegStorage::k64BitPair, reg_num, reg_num + 1); +} + // Return a target-dependent special register. RegStorage MipsMir2Lir::TargetReg(SpecialTargetRegister reg) { RegStorage res_reg; @@ -123,7 +130,11 @@ RegStorage MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) { ResourceMask MipsMir2Lir::GetRegMaskCommon(const RegStorage& reg) const { return reg.IsDouble() /* Each double register is equal to a pair of single-precision FP registers */ +#if (FR_BIT == 0) + ? ResourceMask::TwoBits((reg.GetRegNum() & ~1) + kMipsFPReg0) +#else ? ResourceMask::TwoBits(reg.GetRegNum() * 2 + kMipsFPReg0) +#endif : ResourceMask::Bit(reg.IsSingle() ? reg.GetRegNum() + kMipsFPReg0 : reg.GetRegNum()); } @@ -443,7 +454,11 @@ void MipsMir2Lir::CompilerInitializeRegAlloc() { GrowableArray<RegisterInfo*>::Iterator it(®_pool_->sp_regs_); for (RegisterInfo* info = it.Next(); info != nullptr; info = it.Next()) { int sp_reg_num = info->GetReg().GetRegNum(); +#if (FR_BIT == 0) + int dp_reg_num = sp_reg_num & ~1; +#else int dp_reg_num = sp_reg_num >> 1; +#endif RegStorage dp_reg = RegStorage::Solo64(RegStorage::kFloatingPoint | dp_reg_num); RegisterInfo* dp_reg_info = GetRegInfo(dp_reg); // Double precision register's master storage should refer to itself. @@ -462,7 +477,11 @@ void MipsMir2Lir::CompilerInitializeRegAlloc() { // TODO: adjust when we roll to hard float calling convention. reg_pool_->next_core_reg_ = 2; reg_pool_->next_sp_reg_ = 2; +#if (FR_BIT == 0) + reg_pool_->next_dp_reg_ = 2; +#else reg_pool_->next_dp_reg_ = 1; +#endif } /* @@ -531,8 +550,13 @@ bool MipsMir2Lir::SupportsVolatileLoadStore(OpSize size) { } RegisterClass MipsMir2Lir::RegClassForFieldLoadStore(OpSize size, bool is_volatile) { - // No support for 64-bit atomic load/store on mips. - DCHECK(size != k64 && size != kDouble); + if (UNLIKELY(is_volatile)) { + // On Mips, atomic 64-bit load/store requires an fp register. + // Smaller aligned load/store is atomic for both core and fp registers. + if (size == k64 || size == kDouble) { + return kFPReg; + } + } // TODO: Verify that both core and fp registers are suitable for smaller sizes. return RegClassBySize(size); } |