summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorGoran Jakovljevic <Goran.Jakovljevic@imgtec.com>2015-07-28 14:26:12 +0200
committerRoland Levillain <rpl@google.com>2015-08-11 23:37:50 +0100
commit6aec9daecf37fcf02e47ffa7c8faa8a3de2dc412 (patch)
treeb5122c173c1cb9a4937179b9335be4a02d1b32e1 /compiler
parent0d9982daaff119e709d0424a700042751120bd60 (diff)
downloadart-6aec9daecf37fcf02e47ffa7c8faa8a3de2dc412.zip
art-6aec9daecf37fcf02e47ffa7c8faa8a3de2dc412.tar.gz
art-6aec9daecf37fcf02e47ffa7c8faa8a3de2dc412.tar.bz2
[MIPS] Avoid using odd numbered fp registers
Don't use odd numbered fp registers for single precision data on MIPS32r6 (64-bit FPU). Bug: 23050326 Change-Id: I35cc19df091149773411e2336b01c170929376bc (cherry picked from commit fc8156a3df88e259c892d50bf23f7c4f11531844)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/quick/mips/target_mips.cc49
1 files changed, 27 insertions, 22 deletions
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index b098bc2..ec4bad7 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -49,9 +49,11 @@ static constexpr RegStorage reserved_regs_arr_32[] =
static constexpr RegStorage core_temps_arr_32[] =
{rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0_32, rs_rT1_32, rs_rT2_32, rs_rT3_32,
rs_rT4_32, rs_rT5_32, rs_rT6_32, rs_rT7_32, rs_rT8};
-static constexpr RegStorage sp_temps_arr_32[] =
+static constexpr RegStorage sp_fr0_temps_arr_32[] =
{rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
+static constexpr RegStorage sp_fr1_temps_arr_32[] =
+ {rs_rF0, rs_rF2, rs_rF4, rs_rF6, rs_rF8, rs_rF10, rs_rF12, rs_rF14};
static constexpr RegStorage dp_fr0_temps_arr_32[] =
{rs_rD0_fr0, rs_rD1_fr0, rs_rD2_fr0, rs_rD3_fr0, rs_rD4_fr0, rs_rD5_fr0, rs_rD6_fr0,
rs_rD7_fr0};
@@ -130,7 +132,8 @@ static constexpr ArrayRef<const RegStorage> dp_fr0_regs_32(dp_fr0_regs_arr_32);
static constexpr ArrayRef<const RegStorage> dp_fr1_regs_32(dp_fr1_regs_arr_32);
static constexpr ArrayRef<const RegStorage> reserved_regs_32(reserved_regs_arr_32);
static constexpr ArrayRef<const RegStorage> core_temps_32(core_temps_arr_32);
-static constexpr ArrayRef<const RegStorage> sp_temps_32(sp_temps_arr_32);
+static constexpr ArrayRef<const RegStorage> sp_fr0_temps_32(sp_fr0_temps_arr_32);
+static constexpr ArrayRef<const RegStorage> sp_fr1_temps_32(sp_fr1_temps_arr_32);
static constexpr ArrayRef<const RegStorage> dp_fr0_temps_32(dp_fr0_temps_arr_32);
static constexpr ArrayRef<const RegStorage> dp_fr1_temps_32(dp_fr1_temps_arr_32);
@@ -591,22 +594,22 @@ void MipsMir2Lir::ClobberCallerSave() {
Clobber(rs_rFP);
Clobber(rs_rRA);
Clobber(rs_rF0);
- Clobber(rs_rF1);
Clobber(rs_rF2);
- Clobber(rs_rF3);
Clobber(rs_rF4);
- Clobber(rs_rF5);
Clobber(rs_rF6);
- Clobber(rs_rF7);
Clobber(rs_rF8);
- Clobber(rs_rF9);
Clobber(rs_rF10);
- Clobber(rs_rF11);
Clobber(rs_rF12);
- Clobber(rs_rF13);
Clobber(rs_rF14);
- Clobber(rs_rF15);
if (fpuIs32Bit_) {
+ Clobber(rs_rF1);
+ Clobber(rs_rF3);
+ Clobber(rs_rF5);
+ Clobber(rs_rF7);
+ Clobber(rs_rF9);
+ Clobber(rs_rF11);
+ Clobber(rs_rF13);
+ Clobber(rs_rF15);
Clobber(rs_rD0_fr0);
Clobber(rs_rD1_fr0);
Clobber(rs_rD2_fr0);
@@ -717,24 +720,26 @@ void MipsMir2Lir::CompilerInitializeRegAlloc() {
fpuIs32Bit_ ? dp_fr0_regs_32 : dp_fr1_regs_32,
reserved_regs_32, empty_pool, // reserved64
core_temps_32, empty_pool, // core64_temps
- sp_temps_32,
+ fpuIs32Bit_ ? sp_fr0_temps_32 : sp_fr1_temps_32,
fpuIs32Bit_ ? dp_fr0_temps_32 : dp_fr1_temps_32));
// Alias single precision floats to appropriate half of overlapping double.
for (RegisterInfo* info : reg_pool_->sp_regs_) {
int sp_reg_num = info->GetReg().GetRegNum();
int dp_reg_num = sp_reg_num & ~1;
- 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.
- DCHECK_EQ(dp_reg_info, dp_reg_info->Master());
- // Redirect single precision's master storage to master.
- info->SetMaster(dp_reg_info);
- // Singles should show a single 32-bit mask bit, at first referring to the low half.
- DCHECK_EQ(info->StorageMask(), 0x1U);
- if (sp_reg_num & 1) {
- // For odd singles, change to user the high word of the backing double.
- info->SetStorageMask(0x2);
+ if (fpuIs32Bit_ || (sp_reg_num == dp_reg_num)) {
+ 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.
+ DCHECK_EQ(dp_reg_info, dp_reg_info->Master());
+ // Redirect single precision's master storage to master.
+ info->SetMaster(dp_reg_info);
+ // Singles should show a single 32-bit mask bit, at first referring to the low half.
+ DCHECK_EQ(info->StorageMask(), 0x1U);
+ if (sp_reg_num & 1) {
+ // For odd singles, change to user the high word of the backing double.
+ info->SetStorageMask(0x2);
+ }
}
}
}