diff options
Diffstat (limited to 'compiler/dex/quick')
| -rw-r--r-- | compiler/dex/quick/arm/fp_arm.cc | 14 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/target_arm.cc | 13 | ||||
| -rw-r--r-- | compiler/dex/quick/codegen_util.cc | 26 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 13 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 21 |
5 files changed, 64 insertions, 23 deletions
diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc index bb02f74751..c922eb19b8 100644 --- a/compiler/dex/quick/arm/fp_arm.cc +++ b/compiler/dex/quick/arm/fp_arm.cc @@ -141,8 +141,11 @@ void ArmMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, Re break; case Instruction::LONG_TO_DOUBLE: { rl_src = LoadValueWide(rl_src, kFPReg); - RegStorage src_low = rl_src.reg.DoubleToLowSingle(); - RegStorage src_high = rl_src.reg.DoubleToHighSingle(); + RegisterInfo* info = GetRegInfo(rl_src.reg); + RegStorage src_low = info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg(); + DCHECK(src_low.Valid()); + RegStorage src_high = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg(); + DCHECK(src_high.Valid()); rl_result = EvalLoc(rl_dest, kFPReg, true); RegStorage tmp1 = AllocTempDouble(); RegStorage tmp2 = AllocTempDouble(); @@ -161,8 +164,11 @@ void ArmMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, Re return; case Instruction::LONG_TO_FLOAT: { rl_src = LoadValueWide(rl_src, kFPReg); - RegStorage src_low = rl_src.reg.DoubleToLowSingle(); - RegStorage src_high = rl_src.reg.DoubleToHighSingle(); + RegisterInfo* info = GetRegInfo(rl_src.reg); + RegStorage src_low = info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg(); + DCHECK(src_low.Valid()); + RegStorage src_high = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg(); + DCHECK(src_high.Valid()); rl_result = EvalLoc(rl_dest, kFPReg, true); // Allocate temp registers. RegStorage high_val = AllocTempDouble(); diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc index 1520c52a7a..309f676315 100644 --- a/compiler/dex/quick/arm/target_arm.cc +++ b/compiler/dex/quick/arm/target_arm.cc @@ -575,10 +575,10 @@ void ArmMir2Lir::CompilerInitializeRegAlloc() { // 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); + DCHECK_EQ(info->StorageMask(), RegisterInfo::kLowSingleStorageMask); if (sp_reg_num & 1) { - // For odd singles, change to user the high word of the backing double. - info->SetStorageMask(0x2); + // For odd singles, change to use the high word of the backing double. + info->SetStorageMask(RegisterInfo::kHighSingleStorageMask); } } @@ -786,10 +786,13 @@ RegStorage ArmMir2Lir::AllocPreservedDouble(int s_reg) { } } if (res.Valid()) { + RegisterInfo* info = GetRegInfo(res); promotion_map_[p_map_idx].fp_location = kLocPhysReg; - promotion_map_[p_map_idx].FpReg = res.DoubleToLowSingle().GetReg(); + promotion_map_[p_map_idx].FpReg = + info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg().GetReg(); promotion_map_[p_map_idx+1].fp_location = kLocPhysReg; - promotion_map_[p_map_idx+1].FpReg = res.DoubleToHighSingle().GetReg(); + promotion_map_[p_map_idx+1].FpReg = + info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg().GetReg(); } return res; } diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 256135df71..3fbbc4eba7 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -1201,21 +1201,27 @@ std::vector<uint8_t>* Mir2Lir::ReturnCallFrameInformation() { } RegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) { - loc.wide = false; if (loc.location == kLocPhysReg) { + DCHECK(!loc.reg.Is32Bit()); if (loc.reg.IsPair()) { - loc.reg = loc.reg.GetLow(); + RegisterInfo* info_lo = GetRegInfo(loc.reg.GetLow()); + RegisterInfo* info_hi = GetRegInfo(loc.reg.GetHigh()); + info_lo->SetIsWide(false); + info_hi->SetIsWide(false); + loc.reg = info_lo->GetReg(); } else { - // FIXME: temp workaround. - // Issue here: how do we narrow to a 32-bit value in 64-bit container? - // Probably the wrong thing to narrow the RegStorage container here. That - // should be a target decision. At the RegLocation level, we're only - // modifying the view of the Dalvik value - this is orthogonal to the storage - // container size. Consider this a temp workaround. - DCHECK(loc.reg.IsDouble()); - loc.reg = loc.reg.DoubleToLowSingle(); + RegisterInfo* info = GetRegInfo(loc.reg); + RegisterInfo* info_new = info->FindMatchingView(RegisterInfo::k32SoloStorageMask); + DCHECK(info_new != nullptr); + if (info->IsLive() && (info->SReg() == loc.s_reg_low)) { + info->MarkDead(); + info_new->MarkLive(loc.s_reg_low); + } + loc.reg = info_new->GetReg(); } + DCHECK(loc.reg.Valid()); } + loc.wide = false; return loc; } diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 5ec1ca9d63..a6d56bdf3b 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -864,8 +864,17 @@ 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) { - // NOTE: not correct for 64-bit core regs, but this needs rewriting for hard-float. - reg = rl_arg.reg.IsPair() ? rl_arg.reg.GetHigh() : rl_arg.reg.DoubleToHighSingle(); + if (rl_arg.reg.IsPair()) { + reg = rl_arg.reg.GetHigh(); + } else { + RegisterInfo* info = GetRegInfo(rl_arg.reg); + info = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask); + if (info == nullptr) { + // NOTE: For hard float convention we won't split arguments across reg/mem. + UNIMPLEMENTED(FATAL) << "Needs hard float api."; + } + reg = info->GetReg(); + } } else { // kArg2 & rArg3 can safely be used here reg = TargetReg(kArg3); diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index f58f078711..361aba8852 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -332,6 +332,15 @@ class Mir2Lir : public Backend { return arena->Alloc(size, kArenaAllocRegAlloc); } + static const uint32_t k32SoloStorageMask = 0x00000001; + static const uint32_t kLowSingleStorageMask = 0x00000001; + static const uint32_t kHighSingleStorageMask = 0x00000002; + static const uint32_t k64SoloStorageMask = 0x00000003; + static const uint32_t k128SoloStorageMask = 0x0000000f; + static const uint32_t k256SoloStorageMask = 0x000000ff; + static const uint32_t k512SoloStorageMask = 0x0000ffff; + static const uint32_t k1024SoloStorageMask = 0xffffffff; + bool InUse() { return (storage_mask_ & master_->used_storage_) != 0; } void MarkInUse() { master_->used_storage_ |= storage_mask_; } void MarkFree() { master_->used_storage_ &= ~storage_mask_; } @@ -389,7 +398,15 @@ class Mir2Lir : public Backend { LIR* DefEnd() { return def_end_; } void SetDefEnd(LIR* def_end) { def_end_ = def_end; } void ResetDefBody() { def_start_ = def_end_ = nullptr; } - + // Find member of aliased set matching storage_used; return nullptr if none. + RegisterInfo* FindMatchingView(uint32_t storage_used) { + RegisterInfo* res = Master(); + for (; res != nullptr; res = res->GetAliasChain()) { + if (res->StorageMask() == storage_used) + break; + } + return res; + } private: RegStorage reg_; @@ -648,7 +665,7 @@ class Mir2Lir : public Backend { virtual void EndInvoke(CallInfo* info) {} - // Handle bookkeeping to convert a wide RegLocation to a narow RegLocation. No code generated. + // Handle bookkeeping to convert a wide RegLocation to a narrow RegLocation. No code generated. RegLocation NarrowRegLoc(RegLocation loc); // Shared by all targets - implemented in local_optimizations.cc |