From 02adc1a61ab671a13a61c1f6748d90fc7d78b09d Mon Sep 17 00:00:00 2001 From: Martyn Capewell Date: Thu, 14 Oct 2021 15:36:54 +0100 Subject: Tidy up no-argument disassembly Use a zero-length string when disassembling instructions which require no arguments, and factorise those instructions into a separate handler function. --- src/aarch64/cpu-features-auditor-aarch64.cc | 28 +++ src/aarch64/decoder-visitor-map-aarch64.h | 28 --- src/aarch64/disasm-aarch64.cc | 342 ++++++++++------------------ src/aarch64/disasm-aarch64.h | 2 + src/aarch64/simulator-aarch64.cc | 28 +++ 5 files changed, 173 insertions(+), 255 deletions(-) (limited to 'src/aarch64') diff --git a/src/aarch64/cpu-features-auditor-aarch64.cc b/src/aarch64/cpu-features-auditor-aarch64.cc index 689038d7..275a45a9 100644 --- a/src/aarch64/cpu-features-auditor-aarch64.cc +++ b/src/aarch64/cpu-features-auditor-aarch64.cc @@ -36,6 +36,34 @@ namespace aarch64 { CPUFeaturesAuditor::FormToVisitorFnMap CPUFeaturesAuditor::form_to_visitor_ = { DEFAULT_FORM_TO_VISITOR_MAP(CPUFeaturesAuditor), + {"autia1716_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"autiasp_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"autiaz_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"autib1716_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"autibsp_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"autibz_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"axflag_m_pstate", &CPUFeaturesAuditor::VisitSystem}, + {"cfinv_m_pstate", &CPUFeaturesAuditor::VisitSystem}, + {"csdb_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"dgh_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"esb_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"isb_bi_barriers", &CPUFeaturesAuditor::VisitSystem}, + {"nop_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"pacia1716_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"paciasp_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"paciaz_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"pacib1716_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"pacibsp_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"pacibz_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"pssbb_only_barriers", &CPUFeaturesAuditor::VisitSystem}, + {"sev_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"sevl_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"ssbb_only_barriers", &CPUFeaturesAuditor::VisitSystem}, + {"wfe_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"wfi_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"xaflag_m_pstate", &CPUFeaturesAuditor::VisitSystem}, + {"xpaclri_hi_hints", &CPUFeaturesAuditor::VisitSystem}, + {"yield_hi_hints", &CPUFeaturesAuditor::VisitSystem}, {"fcmla_asimdelem_c_h", &CPUFeaturesAuditor::VisitNEONByIndexedElement}, {"fcmla_asimdelem_c_s", &CPUFeaturesAuditor::VisitNEONByIndexedElement}, {"fmlal2_asimdelem_lh", &CPUFeaturesAuditor::VisitNEONByIndexedElement}, diff --git a/src/aarch64/decoder-visitor-map-aarch64.h b/src/aarch64/decoder-visitor-map-aarch64.h index 2a3c975e..e72b86b8 100644 --- a/src/aarch64/decoder-visitor-map-aarch64.h +++ b/src/aarch64/decoder-visitor-map-aarch64.h @@ -2719,48 +2719,20 @@ {"adrp_only_pcreladdr", &VISITORCLASS::VisitPCRelAddressing}, \ {"adr_only_pcreladdr", &VISITORCLASS::VisitPCRelAddressing}, \ {"rmif_only_rmif", &VISITORCLASS::VisitRotateRightIntoFlags}, \ - {"autia1716_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"autiasp_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"autiaz_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"autib1716_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"autibsp_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"autibz_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"axflag_m_pstate", &VISITORCLASS::VisitSystem}, \ {"bti_hb_hints", &VISITORCLASS::VisitSystem}, \ - {"cfinv_m_pstate", &VISITORCLASS::VisitSystem}, \ {"clrex_bn_barriers", &VISITORCLASS::VisitSystem}, \ - {"csdb_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"dgh_hi_hints", &VISITORCLASS::VisitSystem}, \ {"dmb_bo_barriers", &VISITORCLASS::VisitSystem}, \ {"dsb_bo_barriers", &VISITORCLASS::VisitSystem}, \ - {"esb_hi_hints", &VISITORCLASS::VisitSystem}, \ {"hint_hm_hints", &VISITORCLASS::VisitSystem}, \ - {"isb_bi_barriers", &VISITORCLASS::VisitSystem}, \ {"mrs_rs_systemmove", &VISITORCLASS::VisitSystem}, \ {"msr_si_pstate", &VISITORCLASS::VisitSystem}, \ {"msr_sr_systemmove", &VISITORCLASS::VisitSystem}, \ - {"nop_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"pacia1716_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"paciasp_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"paciaz_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"pacib1716_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"pacibsp_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"pacibz_hi_hints", &VISITORCLASS::VisitSystem}, \ {"psb_hc_hints", &VISITORCLASS::VisitSystem}, \ - {"pssbb_only_barriers", &VISITORCLASS::VisitSystem}, \ {"sb_only_barriers", &VISITORCLASS::VisitSystem}, \ - {"sevl_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"sev_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"ssbb_only_barriers", &VISITORCLASS::VisitSystem}, \ {"sysl_rc_systeminstrs", &VISITORCLASS::VisitSystem}, \ {"sys_cr_systeminstrs", &VISITORCLASS::VisitSystem}, \ {"tcommit_only_barriers", &VISITORCLASS::VisitSystem}, \ {"tsb_hc_hints", &VISITORCLASS::VisitSystem}, \ - {"wfe_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"wfi_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"xaflag_m_pstate", &VISITORCLASS::VisitSystem}, \ - {"xpaclri_hi_hints", &VISITORCLASS::VisitSystem}, \ - {"yield_hi_hints", &VISITORCLASS::VisitSystem}, \ {"tbnz_only_testbranch", &VISITORCLASS::VisitTestBranch}, \ {"tbz_only_testbranch", &VISITORCLASS::VisitTestBranch}, \ {"bl_only_branch_imm", &VISITORCLASS::VisitUnconditionalBranch}, \ diff --git a/src/aarch64/disasm-aarch64.cc b/src/aarch64/disasm-aarch64.cc index e8af6246..f08fb922 100644 --- a/src/aarch64/disasm-aarch64.cc +++ b/src/aarch64/disasm-aarch64.cc @@ -35,6 +35,34 @@ namespace aarch64 { Disassembler::FormToVisitorFnMap Disassembler::form_to_visitor_ = { DEFAULT_FORM_TO_VISITOR_MAP(Disassembler), + {"autia1716_hi_hints", &Disassembler::DisassembleNoArgs}, + {"autiasp_hi_hints", &Disassembler::DisassembleNoArgs}, + {"autiaz_hi_hints", &Disassembler::DisassembleNoArgs}, + {"autib1716_hi_hints", &Disassembler::DisassembleNoArgs}, + {"autibsp_hi_hints", &Disassembler::DisassembleNoArgs}, + {"autibz_hi_hints", &Disassembler::DisassembleNoArgs}, + {"axflag_m_pstate", &Disassembler::DisassembleNoArgs}, + {"cfinv_m_pstate", &Disassembler::DisassembleNoArgs}, + {"csdb_hi_hints", &Disassembler::DisassembleNoArgs}, + {"dgh_hi_hints", &Disassembler::DisassembleNoArgs}, + {"ssbb_only_barriers", &Disassembler::DisassembleNoArgs}, + {"pssbb_only_barriers", &Disassembler::DisassembleNoArgs}, + {"esb_hi_hints", &Disassembler::DisassembleNoArgs}, + {"isb_bi_barriers", &Disassembler::DisassembleNoArgs}, + {"nop_hi_hints", &Disassembler::DisassembleNoArgs}, + {"pacia1716_hi_hints", &Disassembler::DisassembleNoArgs}, + {"paciasp_hi_hints", &Disassembler::DisassembleNoArgs}, + {"paciaz_hi_hints", &Disassembler::DisassembleNoArgs}, + {"pacib1716_hi_hints", &Disassembler::DisassembleNoArgs}, + {"pacibsp_hi_hints", &Disassembler::DisassembleNoArgs}, + {"pacibz_hi_hints", &Disassembler::DisassembleNoArgs}, + {"sev_hi_hints", &Disassembler::DisassembleNoArgs}, + {"sevl_hi_hints", &Disassembler::DisassembleNoArgs}, + {"wfe_hi_hints", &Disassembler::DisassembleNoArgs}, + {"wfi_hi_hints", &Disassembler::DisassembleNoArgs}, + {"xaflag_m_pstate", &Disassembler::DisassembleNoArgs}, + {"xpaclri_hi_hints", &Disassembler::DisassembleNoArgs}, + {"yield_hi_hints", &Disassembler::DisassembleNoArgs}, {"smlal_asimdelem_l", &Disassembler::DisassembleNEONMulByElementLong}, {"smlsl_asimdelem_l", &Disassembler::DisassembleNEONMulByElementLong}, {"smull_asimdelem_l", &Disassembler::DisassembleNEONMulByElementLong}, @@ -1003,70 +1031,27 @@ void Disassembler::VisitConditionalBranch(const Instruction *instr) { void Disassembler::VisitUnconditionalBranchToRegister( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form; + const char *mnemonic = mnemonic_.c_str(); + const char *form = "'Xn"; - switch (instr->Mask(UnconditionalBranchToRegisterMask)) { - case BR: - mnemonic = "br"; - form = "'Xn"; - break; - case BLR: - mnemonic = "blr"; - form = "'Xn"; - break; - case RET: { - mnemonic = "ret"; + switch (form_hash_) { + case Hash("ret_64r_branch_reg"): if (instr->GetRn() == kLinkRegCode) { - form = NULL; - } else { - form = "'Xn"; + form = ""; } break; - } - case BRAAZ: - mnemonic = "braaz"; - form = "'Xn"; - break; - case BRABZ: - mnemonic = "brabz"; - form = "'Xn"; - break; - case BLRAAZ: - mnemonic = "blraaz"; - form = "'Xn"; - break; - case BLRABZ: - mnemonic = "blrabz"; - form = "'Xn"; - break; - case RETAA: - mnemonic = "retaa"; - form = NULL; + case Hash("retaa_64e_branch_reg"): + case Hash("retab_64e_branch_reg"): + form = ""; break; - case RETAB: - mnemonic = "retab"; - form = NULL; - break; - case BRAA: - mnemonic = "braa"; - form = "'Xn, 'Xds"; - break; - case BRAB: - mnemonic = "brab"; - form = "'Xn, 'Xds"; - break; - case BLRAA: - mnemonic = "blraa"; - form = "'Xn, 'Xds"; - break; - case BLRAB: - mnemonic = "blrab"; + case Hash("braa_64p_branch_reg"): + case Hash("brab_64p_branch_reg"): + case Hash("blraa_64p_branch_reg"): + case Hash("blrab_64p_branch_reg"): form = "'Xn, 'Xds"; break; - default: - form = "(UnconditionalBranchToRegister)"; } + Format(instr, mnemonic, form); } @@ -2461,183 +2446,85 @@ void Disassembler::VisitFPFixedPointConvert(const Instruction *instr) { Format(instr, mnemonic, form); } -// clang-format off -#define PAUTH_SYSTEM_MNEMONICS(V) \ - V(PACIA1716, "pacia1716") \ - V(PACIB1716, "pacib1716") \ - V(AUTIA1716, "autia1716") \ - V(AUTIB1716, "autib1716") \ - V(PACIAZ, "paciaz") \ - V(PACIASP, "paciasp") \ - V(PACIBZ, "pacibz") \ - V(PACIBSP, "pacibsp") \ - V(AUTIAZ, "autiaz") \ - V(AUTIASP, "autiasp") \ - V(AUTIBZ, "autibz") \ - V(AUTIBSP, "autibsp") -// clang-format on +void Disassembler::DisassembleNoArgs(const Instruction *instr) { + Format(instr, mnemonic_.c_str(), ""); +} void Disassembler::VisitSystem(const Instruction *instr) { - // Some system instructions hijack their Op and Cp fields to represent a - // range of immediates instead of indicating a different instruction. This - // makes the decoding tricky. - const char *mnemonic = "unimplemented"; + const char *mnemonic = mnemonic_.c_str(); const char *form = "(System)"; - if (instr->GetInstructionBits() == XPACLRI) { - mnemonic = "xpaclri"; - form = NULL; - } else if (instr->Mask(SystemPStateFMask) == SystemPStateFixed) { - switch (instr->Mask(SystemPStateMask)) { - case CFINV: - mnemonic = "cfinv"; - form = NULL; - break; - case AXFLAG: - mnemonic = "axflag"; - form = NULL; - break; - case XAFLAG: - mnemonic = "xaflag"; - form = NULL; - break; - } - } else if (instr->Mask(SystemPAuthFMask) == SystemPAuthFixed) { - switch (instr->Mask(SystemPAuthMask)) { -#define PAUTH_CASE(NAME, MN) \ - case NAME: \ - mnemonic = MN; \ - form = NULL; \ - break; + const char *suffix = NULL; - PAUTH_SYSTEM_MNEMONICS(PAUTH_CASE) -#undef PAUTH_CASE - } - } else if (instr->Mask(SystemExclusiveMonitorFMask) == - SystemExclusiveMonitorFixed) { - switch (instr->Mask(SystemExclusiveMonitorMask)) { - case CLREX: { - mnemonic = "clrex"; - form = (instr->GetCRm() == 0xf) ? NULL : "'IX"; - break; - } - } - } else if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) { - switch (instr->Mask(SystemSysRegMask)) { - case MRS: { - mnemonic = "mrs"; - form = "'Xt, 'IY"; - break; - } - case MSR: { - mnemonic = "msr"; - form = "'IY, 'Xt"; - break; - } - } - } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { - form = NULL; - switch (instr->GetImmHint()) { - case NOP: - mnemonic = "nop"; - break; - case YIELD: - mnemonic = "yield"; - break; - case WFE: - mnemonic = "wfe"; - break; - case WFI: - mnemonic = "wfi"; - break; - case SEV: - mnemonic = "sev"; - break; - case SEVL: - mnemonic = "sevl"; - break; - case ESB: - mnemonic = "esb"; - break; - case CSDB: - mnemonic = "csdb"; - break; - case BTI: - mnemonic = "bti"; - break; - case BTI_c: - mnemonic = "bti c"; - break; - case BTI_j: - mnemonic = "bti j"; - break; - case BTI_jc: - mnemonic = "bti jc"; - break; - default: - // Fall back to 'hint #'. - form = "'IH"; - mnemonic = "hint"; - break; - } - } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) { - switch (instr->Mask(MemBarrierMask)) { - case DMB: { - mnemonic = "dmb"; - form = "'M"; - break; - } - case DSB: { - mnemonic = "dsb"; - form = "'M"; - break; - } - case ISB: { - mnemonic = "isb"; - form = NULL; - break; + switch (form_hash_) { + case Hash("clrex_bn_barriers"): + form = (instr->GetCRm() == 0xf) ? "" : "'IX"; + break; + case Hash("mrs_rs_systemmove"): + form = "'Xt, 'IY"; + break; + case Hash("msr_si_pstate"): + case Hash("msr_sr_systemmove"): + form = "'IY, 'Xt"; + break; + case Hash("bti_hb_hints"): + switch (instr->ExtractBits(7, 6)) { + case 0: + form = ""; + break; + case 1: + form = "c"; + break; + case 2: + form = "j"; + break; + case 3: + form = "jc"; + break; } - } - } else if (instr->Mask(SystemSysFMask) == SystemSysFixed) { - switch (instr->GetSysOp()) { - case IVAU: - mnemonic = "ic"; - form = "ivau, 'Xt"; - break; - case CVAC: - mnemonic = "dc"; - form = "cvac, 'Xt"; - break; - case CVAU: - mnemonic = "dc"; - form = "cvau, 'Xt"; - break; - case CVAP: - mnemonic = "dc"; - form = "cvap, 'Xt"; - break; - case CVADP: - mnemonic = "dc"; - form = "cvadp, 'Xt"; - break; - case CIVAC: - mnemonic = "dc"; - form = "civac, 'Xt"; - break; - case ZVA: - mnemonic = "dc"; - form = "zva, 'Xt"; - break; - default: - mnemonic = "sys"; - if (instr->GetRt() == 31) { + break; + case Hash("hint_hm_hints"): + form = "'IH"; + break; + case Hash("dmb_bo_barriers"): + case Hash("dsb_bo_barriers"): + form = "'M"; + break; + case Hash("sys_cr_systeminstrs"): + mnemonic = "dc"; + suffix = ", 'Xt"; + switch (instr->GetSysOp()) { + case IVAU: + mnemonic = "ic"; + form = "ivau"; + break; + case CVAC: + form = "cvac"; + break; + case CVAU: + form = "cvau"; + break; + case CVAP: + form = "cvap"; + break; + case CVADP: + form = "cvadp"; + break; + case CIVAC: + form = "civac"; + break; + case ZVA: + form = "zva"; + break; + default: + mnemonic = "sys"; form = "'G1, 'Kn, 'Km, 'G2"; - } else { - form = "'G1, 'Kn, 'Km, 'G2, 'Xt"; - } - break; - } + if (instr->GetRt() == 31) { + suffix = NULL; + } + break; + } } - Format(instr, mnemonic, form); + Format(instr, mnemonic, form, suffix); } @@ -10251,9 +10138,10 @@ void Disassembler::Format(const Instruction *instr, const char *format0, const char *format1) { VIXL_ASSERT(mnemonic != NULL); + VIXL_ASSERT(format0 != NULL); ResetOutput(); Substitute(instr, mnemonic); - if (format0 != NULL) { + if (format0[0] != 0) { // Not a zero-length string. VIXL_ASSERT(buffer_pos_ < buffer_size_); buffer_[buffer_pos_++] = ' '; Substitute(instr, format0); diff --git a/src/aarch64/disasm-aarch64.h b/src/aarch64/disasm-aarch64.h index 0a2850a8..51e57454 100644 --- a/src/aarch64/disasm-aarch64.h +++ b/src/aarch64/disasm-aarch64.h @@ -191,6 +191,8 @@ class Disassembler : public DecoderVisitor { void DisassembleSVEFlogb(const Instruction* instr); void DisassembleSVEFPPair(const Instruction* instr); + void DisassembleNoArgs(const Instruction* instr); + void DisassembleNEONMulByElementLong(const Instruction* instr); void DisassembleNEONDotProdByElement(const Instruction* instr); void DisassembleNEONFPMulByElement(const Instruction* instr); diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc index 20e6b21b..573cdf60 100644 --- a/src/aarch64/simulator-aarch64.cc +++ b/src/aarch64/simulator-aarch64.cc @@ -69,6 +69,34 @@ SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) { Simulator::FormToVisitorFnMap Simulator::form_to_visitor_ = { DEFAULT_FORM_TO_VISITOR_MAP(Simulator), + {"autia1716_hi_hints", &Simulator::VisitSystem}, + {"autiasp_hi_hints", &Simulator::VisitSystem}, + {"autiaz_hi_hints", &Simulator::VisitSystem}, + {"autib1716_hi_hints", &Simulator::VisitSystem}, + {"autibsp_hi_hints", &Simulator::VisitSystem}, + {"autibz_hi_hints", &Simulator::VisitSystem}, + {"axflag_m_pstate", &Simulator::VisitSystem}, + {"cfinv_m_pstate", &Simulator::VisitSystem}, + {"csdb_hi_hints", &Simulator::VisitSystem}, + {"dgh_hi_hints", &Simulator::VisitSystem}, + {"esb_hi_hints", &Simulator::VisitSystem}, + {"isb_bi_barriers", &Simulator::VisitSystem}, + {"nop_hi_hints", &Simulator::VisitSystem}, + {"pacia1716_hi_hints", &Simulator::VisitSystem}, + {"paciasp_hi_hints", &Simulator::VisitSystem}, + {"paciaz_hi_hints", &Simulator::VisitSystem}, + {"pacib1716_hi_hints", &Simulator::VisitSystem}, + {"pacibsp_hi_hints", &Simulator::VisitSystem}, + {"pacibz_hi_hints", &Simulator::VisitSystem}, + {"pssbb_only_barriers", &Simulator::VisitSystem}, + {"sev_hi_hints", &Simulator::VisitSystem}, + {"sevl_hi_hints", &Simulator::VisitSystem}, + {"ssbb_only_barriers", &Simulator::VisitSystem}, + {"wfe_hi_hints", &Simulator::VisitSystem}, + {"wfi_hi_hints", &Simulator::VisitSystem}, + {"xaflag_m_pstate", &Simulator::VisitSystem}, + {"xpaclri_hi_hints", &Simulator::VisitSystem}, + {"yield_hi_hints", &Simulator::VisitSystem}, {"smlal_asimdelem_l", &Simulator::SimulateNEONMulByElementLong}, {"smlsl_asimdelem_l", &Simulator::SimulateNEONMulByElementLong}, {"smull_asimdelem_l", &Simulator::SimulateNEONMulByElementLong}, -- cgit v1.2.3