Fix quick mode bugs for Mips.
This patch enable quick mode for Mips and allows the emulator to boot.
However the emulator is still not 100% functional. It still have problems
launching some apps.
Change-Id: Id46a39a649a2fd431a9f13b06ecf34cbd1d20930
Signed-off-by: Douglas Leung <douglas@mips.com>
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 @@
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 @@
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 @@
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 @@
// 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 @@
}
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);
}