summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/arm64/target_arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/quick/arm64/target_arm64.cc')
-rw-r--r--compiler/dex/quick/arm64/target_arm64.cc97
1 files changed, 54 insertions, 43 deletions
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index dcb0050..6985de6 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -22,6 +22,7 @@
#include "dex/compiler_internals.h"
#include "dex/quick/mir_to_lir-inl.h"
+#include "dex/reg_storage_eq.h"
namespace art {
@@ -648,29 +649,6 @@ void Arm64Mir2Lir::AdjustSpillMask() {
num_core_spills_++;
}
-/*
- * Mark a callee-save fp register as promoted.
- */
-void Arm64Mir2Lir::MarkPreservedSingle(int v_reg, RegStorage reg) {
- DCHECK(reg.IsFloat());
- int adjusted_reg_num = reg.GetRegNum() - A64_FP_CALLEE_SAVE_BASE;
- // Ensure fp_vmap_table is large enough
- int table_size = fp_vmap_table_.size();
- for (int i = table_size; i < (adjusted_reg_num + 1); i++) {
- fp_vmap_table_.push_back(INVALID_VREG);
- }
- // Add the current mapping
- fp_vmap_table_[adjusted_reg_num] = v_reg;
- // Size of fp_vmap_table is high-water mark, use to set mask
- num_fp_spills_ = fp_vmap_table_.size();
- fp_spill_mask_ = ((1 << num_fp_spills_) - 1) << A64_FP_CALLEE_SAVE_BASE;
-}
-
-void Arm64Mir2Lir::MarkPreservedDouble(int v_reg, RegStorage reg) {
- DCHECK(reg.IsDouble());
- MarkPreservedSingle(v_reg, reg);
-}
-
/* Clobber all regs that might be used by an external C call */
void Arm64Mir2Lir::ClobberCallerSave() {
Clobber(rs_x0);
@@ -904,7 +882,7 @@ static RegStorage GetArgPhysicalReg(RegLocation* loc, int* num_gpr_used, int* nu
int n = *num_gpr_used;
if (n < 8) {
*num_gpr_used = n + 1;
- if (loc->wide) {
+ if (loc->wide || loc->ref) {
*op_size = k64;
return RegStorage::Solo64(n);
} else {
@@ -965,35 +943,64 @@ void Arm64Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) {
ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
int start_vreg = cu_->num_dalvik_registers - cu_->num_ins;
for (int i = 0; i < cu_->num_ins; i++) {
- PromotionMap* v_map = &promotion_map_[start_vreg + i];
RegLocation* t_loc = &ArgLocs[i];
OpSize op_size;
RegStorage reg = GetArgPhysicalReg(t_loc, &num_gpr_used, &num_fpr_used, &op_size);
if (reg.Valid()) {
- if ((v_map->core_location == kLocPhysReg) && !t_loc->fp) {
- OpRegCopy(RegStorage::Solo32(v_map->core_reg), reg);
- } else if ((v_map->fp_location == kLocPhysReg) && t_loc->fp) {
- OpRegCopy(RegStorage::Solo32(v_map->FpReg), reg);
+ // If arriving in register.
+
+ // We have already updated the arg location with promoted info
+ // so we can be based on it.
+ if (t_loc->location == kLocPhysReg) {
+ // Just copy it.
+ OpRegCopy(t_loc->reg, reg);
} else {
- StoreBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, op_size, kNotVolatile);
- if (reg.Is64Bit()) {
- if (SRegOffset(start_vreg + i) + 4 != SRegOffset(start_vreg + i + 1)) {
- LOG(FATAL) << "64 bit value stored in non-consecutive 4 bytes slots";
- }
- i += 1;
+ // Needs flush.
+ if (t_loc->ref) {
+ StoreRefDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, kNotVolatile);
+ } else {
+ StoreBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, t_loc->wide ? k64 : k32,
+ kNotVolatile);
}
}
} else {
- // If arriving in frame & promoted
- if (v_map->core_location == kLocPhysReg) {
- LoadWordDisp(TargetReg(kSp), SRegOffset(start_vreg + i),
- RegStorage::Solo32(v_map->core_reg));
- }
- if (v_map->fp_location == kLocPhysReg) {
- LoadWordDisp(TargetReg(kSp), SRegOffset(start_vreg + i), RegStorage::Solo32(v_map->FpReg));
+ // If arriving in frame & promoted.
+ if (t_loc->location == kLocPhysReg) {
+ if (t_loc->ref) {
+ LoadRefDisp(TargetReg(kSp), SRegOffset(start_vreg + i), t_loc->reg, kNotVolatile);
+ } else {
+ LoadBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), t_loc->reg,
+ t_loc->wide ? k64 : k32, kNotVolatile);
+ }
}
}
+ if (t_loc->wide) {
+ // Increment i to skip the next one.
+ i++;
+ }
+ // if ((v_map->core_location == kLocPhysReg) && !t_loc->fp) {
+ // OpRegCopy(RegStorage::Solo32(v_map->core_reg), reg);
+ // } else if ((v_map->fp_location == kLocPhysReg) && t_loc->fp) {
+ // OpRegCopy(RegStorage::Solo32(v_map->fp_reg), reg);
+ // } else {
+ // StoreBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, op_size, kNotVolatile);
+ // if (reg.Is64Bit()) {
+ // if (SRegOffset(start_vreg + i) + 4 != SRegOffset(start_vreg + i + 1)) {
+ // LOG(FATAL) << "64 bit value stored in non-consecutive 4 bytes slots";
+ // }
+ // i += 1;
+ // }
+ // }
+ // } else {
+ // // If arriving in frame & promoted
+ // if (v_map->core_location == kLocPhysReg) {
+ // LoadWordDisp(TargetReg(kSp), SRegOffset(start_vreg + i),
+ // RegStorage::Solo32(v_map->core_reg));
+ // }
+ // if (v_map->fp_location == kLocPhysReg) {
+ // LoadWordDisp(TargetReg(kSp), SRegOffset(start_vreg + i), RegStorage::Solo32(v_map->fp_reg));
+ // }
}
}
@@ -1067,7 +1074,11 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state,
loc = UpdateLoc(loc);
if (loc.location == kLocPhysReg) {
ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
- StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k32, kNotVolatile);
+ if (loc.ref) {
+ StoreRefDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, kNotVolatile);
+ } else {
+ StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k32, kNotVolatile);
+ }
}
next_arg++;
}