diff options
author | Andreas Gampe <agampe@google.com> | 2014-07-15 18:52:36 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-07-15 00:17:18 +0000 |
commit | 76e6773dfed9e9bf382bbb8d6c8654525fa44b0c (patch) | |
tree | b0f05bc85deeb3f86ec478c6f5bd8525cd85dfce | |
parent | 524e5e3815d2b16ee77beda9976b7ec3aa54aba6 (diff) | |
parent | ed7a0f2fb84b200ab6ef34e30dcbba4c0cf8d435 (diff) | |
download | art-76e6773dfed9e9bf382bbb8d6c8654525fa44b0c.zip art-76e6773dfed9e9bf382bbb8d6c8654525fa44b0c.tar.gz art-76e6773dfed9e9bf382bbb8d6c8654525fa44b0c.tar.bz2 |
Merge "AArch64: improve usage of TargetReg() and friends."
-rw-r--r-- | compiler/dex/quick/arm64/assemble_arm64.cc | 22 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/codegen_arm64.h | 8 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/target_arm64.cc | 78 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 2 |
4 files changed, 54 insertions, 56 deletions
diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc index 083277d..462be54 100644 --- a/compiler/dex/quick/arm64/assemble_arm64.cc +++ b/compiler/dex/quick/arm64/assemble_arm64.cc @@ -655,10 +655,10 @@ uint8_t* Arm64Mir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { if (kIsDebugBuild && (kFailOnSizeError || kReportSizeError)) { // Register usage checks: First establish register usage requirements based on the // format in `kind'. - bool want_float = false; - bool want_64_bit = false; - bool want_var_size = true; - bool want_zero = false; + bool want_float = false; // Want a float (rather than core) register. + bool want_64_bit = false; // Want a 64-bit (rather than 32-bit) register. + bool want_var_size = true; // Want register with variable size (kFmtReg{R,F}). + bool want_zero = false; // Want the zero (rather than sp) register. switch (kind) { case kFmtRegX: want_64_bit = true; @@ -717,9 +717,6 @@ uint8_t* Arm64Mir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { } } - // TODO(Arm64): if !want_size_match, then we still should compare the size of the - // register with the size required by the instruction width (kA64Wide). - // Fail, if `expected' contains an unsatisfied requirement. if (expected != nullptr) { LOG(WARNING) << "Method: " << PrettyMethod(cu_->method_idx, *cu_->dex_file) @@ -734,11 +731,12 @@ uint8_t* Arm64Mir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { } } - // TODO(Arm64): this may or may not be necessary, depending on how wzr, xzr are - // defined. - if (is_zero) { - operand = 31; - } + // In the lines below, we rely on (operand & 0x1f) == 31 to be true for register sp + // and zr. This means that these two registers do not need any special treatment, as + // their bottom 5 bits are correctly set to 31 == 0b11111, which is the right + // value for encoding both sp and zr. + COMPILE_ASSERT((rxzr & 0x1f) == 0x1f, rzr_register_number_must_be_31); + COMPILE_ASSERT((rsp & 0x1f) == 0x1f, rsp_register_number_must_be_31); } value = (operand << encoder->field_loc[i].start) & diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h index e4eeeaf..de97653 100644 --- a/compiler/dex/quick/arm64/codegen_arm64.h +++ b/compiler/dex/quick/arm64/codegen_arm64.h @@ -105,16 +105,14 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { // Required for target - register utilities. RegStorage TargetReg(SpecialTargetRegister reg) OVERRIDE; RegStorage TargetReg(SpecialTargetRegister symbolic_reg, WideKind wide_kind) OVERRIDE { - RegStorage reg = TargetReg(symbolic_reg); if (wide_kind == kWide || wide_kind == kRef) { - return (reg.Is64Bit()) ? reg : As64BitReg(reg); + return As64BitReg(TargetReg(symbolic_reg)); } else { - return (reg.Is32Bit()) ? reg : As32BitReg(reg); + return Check32BitReg(TargetReg(symbolic_reg)); } } RegStorage TargetPtrReg(SpecialTargetRegister symbolic_reg) OVERRIDE { - RegStorage reg = TargetReg(symbolic_reg); - return (reg.Is64Bit() ? reg : As64BitReg(reg)); + return As64BitReg(TargetReg(symbolic_reg)); } RegStorage GetArgMappingToPhysicalReg(int arg_num); RegLocation GetReturnAlt(); diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index 2212380..6a27ad0 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -108,19 +108,19 @@ RegLocation Arm64Mir2Lir::LocCReturnDouble() { RegStorage Arm64Mir2Lir::TargetReg(SpecialTargetRegister reg) { RegStorage res_reg = RegStorage::InvalidReg(); switch (reg) { - case kSelf: res_reg = rs_xSELF; break; - case kSuspend: res_reg = rs_xSUSPEND; break; - case kLr: res_reg = rs_xLR; break; + case kSelf: res_reg = rs_wSELF; break; + case kSuspend: res_reg = rs_wSUSPEND; break; + case kLr: res_reg = rs_wLR; break; case kPc: res_reg = RegStorage::InvalidReg(); break; - case kSp: res_reg = rs_sp; break; - case kArg0: res_reg = rs_x0; break; - case kArg1: res_reg = rs_x1; break; - case kArg2: res_reg = rs_x2; break; - case kArg3: res_reg = rs_x3; break; - case kArg4: res_reg = rs_x4; break; - case kArg5: res_reg = rs_x5; break; - case kArg6: res_reg = rs_x6; break; - case kArg7: res_reg = rs_x7; break; + case kSp: res_reg = rs_wsp; break; + case kArg0: res_reg = rs_w0; break; + case kArg1: res_reg = rs_w1; break; + case kArg2: res_reg = rs_w2; break; + case kArg3: res_reg = rs_w3; break; + case kArg4: res_reg = rs_w4; break; + case kArg5: res_reg = rs_w5; break; + case kArg6: res_reg = rs_w6; break; + case kArg7: res_reg = rs_w7; break; case kFArg0: res_reg = rs_f0; break; case kFArg1: res_reg = rs_f1; break; case kFArg2: res_reg = rs_f2; break; @@ -129,10 +129,10 @@ RegStorage Arm64Mir2Lir::TargetReg(SpecialTargetRegister reg) { case kFArg5: res_reg = rs_f5; break; case kFArg6: res_reg = rs_f6; break; case kFArg7: res_reg = rs_f7; break; - case kRet0: res_reg = rs_x0; break; - case kRet1: res_reg = rs_x1; break; - case kInvokeTgt: res_reg = rs_xLR; break; - case kHiddenArg: res_reg = rs_x12; break; + case kRet0: res_reg = rs_w0; break; + case kRet1: res_reg = rs_w1; break; + case kInvokeTgt: res_reg = rs_wLR; break; + case kHiddenArg: res_reg = rs_w12; break; case kHiddenFpArg: res_reg = RegStorage::InvalidReg(); break; case kCount: res_reg = RegStorage::InvalidReg(); break; default: res_reg = RegStorage::InvalidReg(); @@ -929,13 +929,13 @@ void Arm64Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { */ RegLocation rl_src = rl_method; rl_src.location = kLocPhysReg; - rl_src.reg = TargetReg(kArg0); + rl_src.reg = TargetReg(kArg0, kRef); rl_src.home = false; MarkLive(rl_src); StoreValue(rl_method, rl_src); // If Method* has been promoted, explicitly flush if (rl_method.location == kLocPhysReg) { - StoreRefDisp(TargetReg(kSp), 0, TargetReg(kArg0), kNotVolatile); + StoreRefDisp(TargetPtrReg(kSp), 0, rl_src.reg, kNotVolatile); } if (cu_->num_ins == 0) { @@ -961,9 +961,9 @@ void Arm64Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { } else { // Needs flush. if (t_loc->ref) { - StoreRefDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, kNotVolatile); + StoreRefDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), reg, kNotVolatile); } else { - StoreBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), reg, t_loc->wide ? k64 : k32, + StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), reg, t_loc->wide ? k64 : k32, kNotVolatile); } } @@ -971,9 +971,9 @@ void Arm64Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { // 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); + LoadRefDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), t_loc->reg, kNotVolatile); } else { - LoadBaseDisp(TargetReg(kSp), SRegOffset(start_vreg + i), t_loc->reg, + LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(start_vreg + i), t_loc->reg, t_loc->wide ? k64 : k32, kNotVolatile); } } @@ -1070,7 +1070,7 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, loc = UpdateLocWide(loc); if (loc.location == kLocPhysReg) { ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); - StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k64, kNotVolatile); + StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k64, kNotVolatile); } next_arg += 2; } else { @@ -1078,9 +1078,10 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, if (loc.location == kLocPhysReg) { ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); if (loc.ref) { - StoreRefDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, kNotVolatile); + StoreRefDisp(TargetPtrReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, kNotVolatile); } else { - StoreBaseDisp(TargetReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k32, kNotVolatile); + StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(loc.s_reg_low), loc.reg, k32, + kNotVolatile); } } next_arg++; @@ -1114,8 +1115,8 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, RegStorage temp = TargetReg(kArg3, kNotWide); // Now load the argument VR and store to the outs. - Load32Disp(TargetReg(kSp), current_src_offset, temp); - Store32Disp(TargetReg(kSp), current_dest_offset, temp); + Load32Disp(TargetPtrReg(kSp), current_src_offset, temp); + Store32Disp(TargetPtrReg(kSp), current_dest_offset, temp); current_src_offset += bytes_to_move; current_dest_offset += bytes_to_move; @@ -1126,8 +1127,7 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, // Now handle rest not registers if they are if (in_to_reg_storage_mapping.IsThereStackMapped()) { - RegStorage regSingle = TargetReg(kArg2); - RegStorage regWide = RegStorage::Solo64(TargetReg(kArg3).GetReg()); + RegStorage regWide = TargetReg(kArg3, kWide); for (int i = start_index; i <= last_mapped_in + regs_left_to_pass_via_stack; i++) { RegLocation rl_arg = info->args[i]; rl_arg = UpdateRawLoc(rl_arg); @@ -1139,25 +1139,27 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); if (rl_arg.wide) { if (rl_arg.location == kLocPhysReg) { - StoreBaseDisp(TargetReg(kSp), out_offset, rl_arg.reg, k64, kNotVolatile); + StoreBaseDisp(TargetPtrReg(kSp), out_offset, rl_arg.reg, k64, kNotVolatile); } else { LoadValueDirectWideFixed(rl_arg, regWide); - StoreBaseDisp(TargetReg(kSp), out_offset, regWide, k64, kNotVolatile); + StoreBaseDisp(TargetPtrReg(kSp), out_offset, regWide, k64, kNotVolatile); } } else { if (rl_arg.location == kLocPhysReg) { if (rl_arg.ref) { - StoreRefDisp(TargetReg(kSp), out_offset, rl_arg.reg, kNotVolatile); + StoreRefDisp(TargetPtrReg(kSp), out_offset, rl_arg.reg, kNotVolatile); } else { - StoreBaseDisp(TargetReg(kSp), out_offset, rl_arg.reg, k32, kNotVolatile); + StoreBaseDisp(TargetPtrReg(kSp), out_offset, rl_arg.reg, k32, kNotVolatile); } } else { if (rl_arg.ref) { + RegStorage regSingle = TargetReg(kArg2, kRef); LoadValueDirectFixed(rl_arg, regSingle); - StoreRefDisp(TargetReg(kSp), out_offset, regSingle, kNotVolatile); + StoreRefDisp(TargetPtrReg(kSp), out_offset, regSingle, kNotVolatile); } else { - LoadValueDirectFixed(rl_arg, As32BitReg(regSingle)); - StoreBaseDisp(TargetReg(kSp), out_offset, As32BitReg(regSingle), k32, kNotVolatile); + RegStorage regSingle = TargetReg(kArg2, kNotWide); + LoadValueDirectFixed(rl_arg, regSingle); + StoreBaseDisp(TargetPtrReg(kSp), out_offset, regSingle, k32, kNotVolatile); } } } @@ -1194,13 +1196,13 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, direct_code, direct_method, type); if (pcrLabel) { if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { - *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1), info->opt_flags); + *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1, kRef), info->opt_flags); } else { *pcrLabel = nullptr; // In lieu of generating a check for kArg1 being null, we need to // perform a load when doing implicit checks. RegStorage tmp = AllocTemp(); - Load32Disp(TargetReg(kArg1), 0, tmp); + Load32Disp(TargetReg(kArg1, kRef), 0, tmp); MarkPossibleNullPointerException(info->opt_flags); FreeTemp(tmp); } diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 634ab94..fd0fe6e 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -1201,7 +1201,7 @@ class Mir2Lir : public Backend { * @param wide_kind What kind of view of the special register is required. * @return Return the #RegStorage corresponding to the given purpose @p reg. * - * Note: For 32b system, wide (kWide) views only make sense for the argument registers and the + * @note For 32b system, wide (kWide) views only make sense for the argument registers and the * return. In that case, this function should return a pair where the first component of * the result will be the indicated special register. */ |