From: John Baldwin Date: Tue, 11 Oct 2022 22:07:41 +0000 (-0700) Subject: Initial support for disassembling CHERI-RISC-V instructions. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eed5ba5c57dbc843ab116205dbad946a9f4855ce;p=thirdparty%2Fbinutils-gdb.git Initial support for disassembling CHERI-RISC-V instructions. This does not yet handle capability mode. --- diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 95d2ffc10b5..368f26efdaf 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -2405,6 +2405,11 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, || riscv_subset_supports (rps, "zve32f")); case INSN_CLASS_SVINVAL: return riscv_subset_supports (rps, "svinval"); + case INSN_CLASS_XCHERI: + return riscv_subset_supports (rps, "xcheri"); + case INSN_CLASS_XCHERI_AND_A: + return (riscv_subset_supports (rps, "xcheri") + && riscv_subset_supports (rps, "a")); default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); @@ -2499,6 +2504,16 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "v' or `zve64d' or `zve64f' or `zve32f"; case INSN_CLASS_SVINVAL: return "svinval"; + case INSN_CLASS_XCHERI: + return "xcheri"; + case INSN_CLASS_XCHERI_AND_A: + if (!riscv_subset_supports (rps, "xcheri") + && !riscv_subset_supports (rps, "a")) + return "xcheri' and `a"; + else if (!riscv_subset_supports (rps, "xcheri")) + return "xcheri"; + else + return "a"; default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 3eea33a5dae..8e41c1d5b7a 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2045,6 +2045,193 @@ #define MASK_CBO_INVAL 0xfff07fff #define MATCH_CBO_ZERO 0x40200f #define MASK_CBO_ZERO 0xfff07fff +/* Xcheri instructions. */ +#define MATCH_CGETPERM 0xfe00005b +#define MASK_CGETPERM 0xfff0707f +#define MATCH_CGETTYPE 0xfe10005b +#define MASK_CGETTYPE 0xfff0707f +#define MATCH_CGETBASE 0xfe20005b +#define MASK_CGETBASE 0xfff0707f +#define MATCH_CGETLEN 0xfe30005b +#define MASK_CGETLEN 0xfff0707f +#define MATCH_CGETTAG 0xfe40005b +#define MASK_CGETTAG 0xfff0707f +#define MATCH_CGETSEALED 0xfe50005b +#define MASK_CGETSEALED 0xfff0707f +#define MATCH_CGETOFFSET 0xfe60005b +#define MASK_CGETOFFSET 0xfff0707f +#define MATCH_CGETFLAGS 0xfe70005b +#define MASK_CGETFLAGS 0xfff0707f +#define MATCH_CGETADDR 0xfef0005b +#define MASK_CGETADDR 0xfff0707f +#define MATCH_CSEAL 0x1600005b +#define MASK_CSEAL 0xfe00707f +#define MATCH_CSEALENTRY 0xff10005b +#define MASK_CSEALENTRY 0xfff0707f +#define MATCH_CUNSEAL 0x1800005b +#define MASK_CUNSEAL 0xfe00707f +#define MATCH_CANDPERM 0x1a00005b +#define MASK_CANDPERM 0xfe00707f +#define MATCH_CSETFLAGS 0x1c00005b +#define MASK_CSETFLAGS 0xfe00707f +#define MATCH_CSETOFFSET 0x1e00005b +#define MASK_CSETOFFSET 0xfe00707f +#define MATCH_CSETADDR 0x2000005b +#define MASK_CSETADDR 0xfe00707f +#define MATCH_CINCOFFSET 0x2200005b +#define MASK_CINCOFFSET 0xfe00707f +#define MATCH_CINCOFFSETIMMEDIATE 0x105b +#define MASK_CINCOFFSETIMMEDIATE 0x707f +#define MATCH_CSETBOUNDS 0x1000005b +#define MASK_CSETBOUNDS 0xfe00707f +#define MATCH_CSETBOUNDSEXACT 0x1200005b +#define MASK_CSETBOUNDSEXACT 0xfe00707f +#define MATCH_CSETBOUNDSIMMEDIATE 0x205b +#define MASK_CSETBOUNDSIMMEDIATE 0x707f +#define MATCH_CCLEARTAG 0xfeb0005b +#define MASK_CCLEARTAG 0xfff0707f +#define MATCH_CBUILDCAP 0x3a00005b +#define MASK_CBUILDCAP 0xfe00707f +#define MATCH_CCOPYTYPE 0x3c00005b +#define MASK_CCOPYTYPE 0xfe00707f +#define MATCH_CCSEAL 0x3e00005b +#define MASK_CCSEAL 0xfe00707f +#define MATCH_CTOPTR 0x2400005b +#define MASK_CTOPTR 0xfe00707f +#define MATCH_CFROMPTR 0x2600005b +#define MASK_CFROMPTR 0xfe00707f +#define MATCH_CSUB 0x2800005b +#define MASK_CSUB 0xfe00707f +#define MATCH_CMOVE 0xfea0005b +#define MASK_CMOVE 0xfff0707f +#define MATCH_CTESTSUBSET 0x4000005b +#define MASK_CTESTSUBSET 0xfe00707f +#define MATCH_CSETEQUALEXACT 0x4200005b +#define MASK_CSETEQUALEXACT 0xfe00707f +#define MATCH_CINVOKE 0xfc0000db +#define MASK_CINVOKE 0xfe007fff +#define MATCH_CSPECIALRW 0x200005b +#define MASK_CSPECIALRW 0xfe00707f +#define MATCH_CROUNDREPRESENTABLELENGTH 0xfe80005b +#define MASK_CROUNDREPRESENTABLELENGTH 0xfff0707f +#define MATCH_CREPRESENTABLEALIGNMENTMASK 0xfe90005b +#define MASK_CREPRESENTABLEALIGNMENTMASK 0xfff0707f +#define MATCH_JALR_CAP 0xfec0005b +#define MASK_JALR_CAP 0xfff0707f +#define MATCH_LB_DDC 0xfa00005b +#define MASK_LB_DDC 0xfff0707f +#define MATCH_LH_DDC 0xfa10005b +#define MASK_LH_DDC 0xfff0707f +#define MATCH_LW_DDC 0xfa20005b +#define MASK_LW_DDC 0xfff0707f +#define MATCH_LD_DDC 0xfa30005b +#define MASK_LD_DDC 0xfff0707f +#define MATCH_LQ_DDC 0xfb70005b +#define MASK_LQ_DDC 0xfff0707f +#define MATCH_LBU_DDC 0xfa40005b +#define MASK_LBU_DDC 0xfff0707f +#define MATCH_LHU_DDC 0xfa50005b +#define MASK_LHU_DDC 0xfff0707f +#define MATCH_LWU_DDC 0xfa60005b +#define MASK_LWU_DDC 0xfff0707f +#define MATCH_LDU_DDC 0xfa70005b +#define MASK_LDU_DDC 0xfff0707f +#define MATCH_LB_CAP 0xfa80005b +#define MASK_LB_CAP 0xfff0707f +#define MATCH_LH_CAP 0xfa90005b +#define MASK_LH_CAP 0xfff0707f +#define MATCH_LW_CAP 0xfaa0005b +#define MASK_LW_CAP 0xfff0707f +#define MATCH_LD_CAP 0xfab0005b +#define MASK_LD_CAP 0xfff0707f +#define MATCH_LQ_CAP 0xfbf0005b +#define MASK_LQ_CAP 0xfff0707f +#define MATCH_LBU_CAP 0xfac0005b +#define MASK_LBU_CAP 0xfff0707f +#define MATCH_LHU_CAP 0xfad0005b +#define MASK_LHU_CAP 0xfff0707f +#define MATCH_LWU_CAP 0xfae0005b +#define MASK_LWU_CAP 0xfff0707f +#define MATCH_LDU_CAP 0xfaf0005b +#define MASK_LDU_CAP 0xfff0707f +#define MATCH_LR_B_DDC 0xfb00005b +#define MASK_LR_B_DDC 0xfff0707f +#define MATCH_LR_H_DDC 0xfb10005b +#define MASK_LR_H_DDC 0xfff0707f +#define MATCH_LR_W_DDC 0xfb20005b +#define MASK_LR_W_DDC 0xfff0707f +#define MATCH_LR_D_DDC 0xfb30005b +#define MASK_LR_D_DDC 0xfff0707f +#define MATCH_LR_Q_DDC 0xfb40005b +#define MASK_LR_Q_DDC 0xfff0707f +#define MATCH_LR_B_CAP 0xfb80005b +#define MASK_LR_B_CAP 0xfff0707f +#define MATCH_LR_H_CAP 0xfb90005b +#define MASK_LR_H_CAP 0xfff0707f +#define MATCH_LR_W_CAP 0xfba0005b +#define MASK_LR_W_CAP 0xfff0707f +#define MATCH_LR_D_CAP 0xfbb0005b +#define MASK_LR_D_CAP 0xfff0707f +#define MATCH_LR_Q_CAP 0xfbc0005b +#define MASK_LR_Q_CAP 0xfff0707f +#define MATCH_SB_DDC 0xf800005b +#define MASK_SB_DDC 0xfe007fff +#define MATCH_SH_DDC 0xf80000db +#define MASK_SH_DDC 0xfe007fff +#define MATCH_SW_DDC 0xf800015b +#define MASK_SW_DDC 0xfe007fff +#define MATCH_SD_DDC 0xf80001db +#define MASK_SD_DDC 0xfe007fff +#define MATCH_SQ_DDC 0xf800025b +#define MASK_SQ_DDC 0xfe007fff +#define MATCH_SB_CAP 0xf800045b +#define MASK_SB_CAP 0xfe007fff +#define MATCH_SH_CAP 0xf80004db +#define MASK_SH_CAP 0xfe007fff +#define MATCH_SW_CAP 0xf800055b +#define MASK_SW_CAP 0xfe007fff +#define MATCH_SD_CAP 0xf80005db +#define MASK_SD_CAP 0xfe007fff +#define MATCH_SQ_CAP 0xf800065b +#define MASK_SQ_CAP 0xfe007fff +#define MATCH_SC_B_DDC 0xf800085b +#define MASK_SC_B_DDC 0xfe007fff +#define MATCH_SC_H_DDC 0xf80008db +#define MASK_SC_H_DDC 0xfe007fff +#define MATCH_SC_W_DDC 0xf800095b +#define MASK_SC_W_DDC 0xfe007fff +#define MATCH_SC_D_DDC 0xf80009db +#define MASK_SC_D_DDC 0xfe007fff +#define MATCH_SC_Q_DDC 0xf8000a5b +#define MASK_SC_Q_DDC 0xfe007fff +#define MATCH_SC_B_CAP 0xf8000c5b +#define MASK_SC_B_CAP 0xfe007fff +#define MATCH_SC_H_CAP 0xf8000cdb +#define MASK_SC_H_CAP 0xfe007fff +#define MATCH_SC_W_CAP 0xf8000d5b +#define MASK_SC_W_CAP 0xfe007fff +#define MATCH_SC_D_CAP 0xf8000ddb +#define MASK_SC_D_CAP 0xfe007fff +#define MATCH_SC_Q_CAP 0xf8000e5b +#define MASK_SC_Q_CAP 0xfe007fff +#define MATCH_LQ 0x200f +#define MASK_LQ 0x707f +#define MATCH_SQ 0x4023 +#define MASK_SQ 0x707f +#define MATCH_LR_B 0x1000002f +#define MASK_LR_B 0xf9f0707f +#define MATCH_SC_B 0x1800002f +#define MASK_SC_B 0xf800707f +#define MATCH_LR_H 0x1000102f +#define MASK_LR_H 0xf9f0707f +#define MATCH_SC_H 0x1800102f +#define MASK_SC_H 0xf800707f +#define MATCH_LR_Q 0x1000402f +#define MASK_LR_Q 0xf9f0707f +#define MATCH_SC_Q 0x1800402f +#define MASK_SC_Q 0xf800707f +#define MATCH_AMOSWAP_Q 0x800402f +#define MASK_AMOSWAP_Q 0xf800707f /* Unprivileged Counter/Timers CSR addresses. */ #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 @@ -2393,6 +2580,21 @@ #define CSR_VL 0xc20 #define CSR_VTYPE 0xc21 #define CSR_VLENB 0xc22 +/* CHERI SCRs. */ +#define CHERI_SCR_PCC 0x0 +#define CHERI_SCR_DDC 0x1 +#define CHERI_SCR_UTCC 0x4 +#define CHERI_SCR_UTDC 0x5 +#define CHERI_SCR_USCRATCHC 0x6 +#define CHERI_SCR_UEPCC 0x7 +#define CHERI_SCR_STCC 0xc +#define CHERI_SCR_STDC 0xd +#define CHERI_SCR_SSCRATCHC 0xe +#define CHERI_SCR_SEPCC 0xf +#define CHERI_SCR_MTCC 0x1c +#define CHERI_SCR_MTDC 0x1d +#define CHERI_SCR_MSCRATCHC 0x1e +#define CHERI_SCR_MEPCC 0x1f #endif /* RISCV_ENCODING_H */ #ifdef DECLARE_INSN DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32) @@ -2720,6 +2922,99 @@ DECLARE_INSN(hsv_b, MATCH_HSV_B, MASK_HSV_B) DECLARE_INSN(hsv_h, MATCH_HSV_H, MASK_HSV_H) DECLARE_INSN(hsv_w, MATCH_HSV_W, MASK_HSV_W) DECLARE_INSN(hsv_d, MATCH_HSV_D, MASK_HSV_D) +DECLARE_INSN(cgetperm, MATCH_CGETPERM, MASK_CGETPERM) +DECLARE_INSN(cgettype, MATCH_CGETTYPE, MASK_CGETTYPE) +DECLARE_INSN(cgetbase, MATCH_CGETBASE, MASK_CGETBASE) +DECLARE_INSN(cgetlen, MATCH_CGETLEN, MASK_CGETLEN) +DECLARE_INSN(cgettag, MATCH_CGETTAG, MASK_CGETTAG) +DECLARE_INSN(cgetsealed, MATCH_CGETSEALED, MASK_CGETSEALED) +DECLARE_INSN(cgetoffset, MATCH_CGETOFFSET, MASK_CGETOFFSET) +DECLARE_INSN(cgetflags, MATCH_CGETFLAGS, MASK_CGETFLAGS) +DECLARE_INSN(cgetaddr, MATCH_CGETADDR, MASK_CGETADDR) +DECLARE_INSN(cseal, MATCH_CSEAL, MASK_CSEAL) +DECLARE_INSN(csealentry, MATCH_CSEALENTRY, MASK_CSEALENTRY) +DECLARE_INSN(cunseal, MATCH_CUNSEAL, MASK_CUNSEAL) +DECLARE_INSN(candperm, MATCH_CANDPERM, MASK_CANDPERM) +DECLARE_INSN(csetflags, MATCH_CSETFLAGS, MASK_CSETFLAGS) +DECLARE_INSN(csetoffset, MATCH_CSETOFFSET, MASK_CSETOFFSET) +DECLARE_INSN(csetaddr, MATCH_CSETADDR, MASK_CSETADDR) +DECLARE_INSN(cincoffset, MATCH_CINCOFFSET, MASK_CINCOFFSET) +DECLARE_INSN(cincoffsetimmediate, MATCH_CINCOFFSETIMMEDIATE, MASK_CINCOFFSETIMMEDIATE) +DECLARE_INSN(csetbounds, MATCH_CSETBOUNDS, MASK_CSETBOUNDS) +DECLARE_INSN(csetboundsexact, MATCH_CSETBOUNDSEXACT, MASK_CSETBOUNDSEXACT) +DECLARE_INSN(csetboundsimmediate, MATCH_CSETBOUNDSIMMEDIATE, MASK_CSETBOUNDSIMMEDIATE) +DECLARE_INSN(ccleartag, MATCH_CCLEARTAG, MASK_CCLEARTAG) +DECLARE_INSN(cbuildcap, MATCH_CBUILDCAP, MASK_CBUILDCAP) +DECLARE_INSN(ccopytype, MATCH_CCOPYTYPE, MASK_CCOPYTYPE) +DECLARE_INSN(ccseal, MATCH_CCSEAL, MASK_CCSEAL) +DECLARE_INSN(ctoptr, MATCH_CTOPTR, MASK_CTOPTR) +DECLARE_INSN(cfromptr, MATCH_CFROMPTR, MASK_CFROMPTR) +DECLARE_INSN(csub, MATCH_CSUB, MASK_CSUB) +DECLARE_INSN(cmove, MATCH_CMOVE, MASK_CMOVE) +DECLARE_INSN(ctestsubset, MATCH_CTESTSUBSET, MASK_CTESTSUBSET) +DECLARE_INSN(csetequalexact, MATCH_CSETEQUALEXACT, MASK_CSETEQUALEXACT) +DECLARE_INSN(jalr_cap, MATCH_JALR_CAP, MASK_JALR_CAP) +DECLARE_INSN(cinvoke, MATCH_CINVOKE, MASK_CINVOKE) +DECLARE_INSN(cspecialrw, MATCH_CSPECIALRW, MASK_CSPECIALRW) +DECLARE_INSN(croundrepresentablelength, MATCH_CROUNDREPRESENTABLELENGTH, MASK_CROUNDREPRESENTABLELENGTH) +DECLARE_INSN(crepresentablealignmentmask, MATCH_CREPRESENTABLEALIGNMENTMASK, MASK_CREPRESENTABLEALIGNMENTMASK) +DECLARE_INSN(lb_ddc, MATCH_LB_DDC, MASK_LB_DDC) +DECLARE_INSN(lh_ddc, MATCH_LH_DDC, MASK_LH_DDC) +DECLARE_INSN(lw_ddc, MATCH_LW_DDC, MASK_LW_DDC) +DECLARE_INSN(ld_ddc, MATCH_LD_DDC, MASK_LD_DDC) +DECLARE_INSN(lq_ddc, MATCH_LQ_DDC, MASK_LQ_DDC) +DECLARE_INSN(lbu_ddc, MATCH_LBU_DDC, MASK_LBU_DDC) +DECLARE_INSN(lhu_ddc, MATCH_LHU_DDC, MASK_LHU_DDC) +DECLARE_INSN(lwu_ddc, MATCH_LWU_DDC, MASK_LWU_DDC) +DECLARE_INSN(ldu_ddc, MATCH_LDU_DDC, MASK_LDU_DDC) +DECLARE_INSN(lb_cap, MATCH_LB_CAP, MASK_LB_CAP) +DECLARE_INSN(lh_cap, MATCH_LH_CAP, MASK_LH_CAP) +DECLARE_INSN(lw_cap, MATCH_LW_CAP, MASK_LW_CAP) +DECLARE_INSN(ld_cap, MATCH_LD_CAP, MASK_LD_CAP) +DECLARE_INSN(lq_cap, MATCH_LQ_CAP, MASK_LQ_CAP) +DECLARE_INSN(lbu_cap, MATCH_LBU_CAP, MASK_LBU_CAP) +DECLARE_INSN(lhu_cap, MATCH_LHU_CAP, MASK_LHU_CAP) +DECLARE_INSN(lwu_cap, MATCH_LWU_CAP, MASK_LWU_CAP) +DECLARE_INSN(ldu_cap, MATCH_LDU_CAP, MASK_LDU_CAP) +DECLARE_INSN(lr_b_ddc, MATCH_LR_B_DDC, MASK_LR_B_DDC) +DECLARE_INSN(lr_h_ddc, MATCH_LR_H_DDC, MASK_LR_H_DDC) +DECLARE_INSN(lr_w_ddc, MATCH_LR_W_DDC, MASK_LR_W_DDC) +DECLARE_INSN(lr_d_ddc, MATCH_LR_D_DDC, MASK_LR_D_DDC) +DECLARE_INSN(lr_q_ddc, MATCH_LR_Q_DDC, MASK_LR_Q_DDC) +DECLARE_INSN(lr_b_cap, MATCH_LR_B_CAP, MASK_LR_B_CAP) +DECLARE_INSN(lr_h_cap, MATCH_LR_H_CAP, MASK_LR_H_CAP) +DECLARE_INSN(lr_w_cap, MATCH_LR_W_CAP, MASK_LR_W_CAP) +DECLARE_INSN(lr_d_cap, MATCH_LR_D_CAP, MASK_LR_D_CAP) +DECLARE_INSN(lr_q_cap, MATCH_LR_Q_CAP, MASK_LR_Q_CAP) +DECLARE_INSN(sb_ddc, MATCH_SB_DDC, MASK_SB_DDC) +DECLARE_INSN(sh_ddc, MATCH_SH_DDC, MASK_SH_DDC) +DECLARE_INSN(sw_ddc, MATCH_SW_DDC, MASK_SW_DDC) +DECLARE_INSN(sd_ddc, MATCH_SD_DDC, MASK_SD_DDC) +DECLARE_INSN(sq_ddc, MATCH_SQ_DDC, MASK_SQ_DDC) +DECLARE_INSN(sb_cap, MATCH_SB_CAP, MASK_SB_CAP) +DECLARE_INSN(sh_cap, MATCH_SH_CAP, MASK_SH_CAP) +DECLARE_INSN(sw_cap, MATCH_SW_CAP, MASK_SW_CAP) +DECLARE_INSN(sd_cap, MATCH_SD_CAP, MASK_SD_CAP) +DECLARE_INSN(sq_cap, MATCH_SQ_CAP, MASK_SQ_CAP) +DECLARE_INSN(sc_b_ddc, MATCH_SC_B_DDC, MASK_SC_B_DDC) +DECLARE_INSN(sc_h_ddc, MATCH_SC_H_DDC, MASK_SC_H_DDC) +DECLARE_INSN(sc_w_ddc, MATCH_SC_W_DDC, MASK_SC_W_DDC) +DECLARE_INSN(sc_d_ddc, MATCH_SC_D_DDC, MASK_SC_D_DDC) +DECLARE_INSN(sc_q_ddc, MATCH_SC_Q_DDC, MASK_SC_Q_DDC) +DECLARE_INSN(sc_b_cap, MATCH_SC_B_CAP, MASK_SC_B_CAP) +DECLARE_INSN(sc_h_cap, MATCH_SC_H_CAP, MASK_SC_H_CAP) +DECLARE_INSN(sc_w_cap, MATCH_SC_W_CAP, MASK_SC_W_CAP) +DECLARE_INSN(sc_d_cap, MATCH_SC_D_CAP, MASK_SC_D_CAP) +DECLARE_INSN(sc_q_cap, MATCH_SC_Q_CAP, MASK_SC_Q_CAP) +DECLARE_INSN(lq, MATCH_LQ, MASK_LQ) +DECLARE_INSN(sq, MATCH_SQ, MASK_SQ) +DECLARE_INSN(lr_b, MATCH_LR_B, MASK_LR_B) +DECLARE_INSN(sc_b, MATCH_SC_B, MASK_SC_B) +DECLARE_INSN(lr_h, MATCH_LR_H, MASK_LR_H) +DECLARE_INSN(sc_h, MATCH_SC_H, MASK_SC_H) +DECLARE_INSN(lr_q, MATCH_LR_Q, MASK_LR_Q) +DECLARE_INSN(sc_q, MATCH_SC_Q, MASK_SC_Q) +DECLARE_INSN(amoswap_q, MATCH_AMOSWAP_Q, MASK_AMOSWAP_Q) #endif /* DECLARE_INSN */ #ifdef DECLARE_CSR /* Unprivileged Counter/Timers CSRs. */ @@ -3087,3 +3382,19 @@ DECLARE_CSR_ALIAS(tmexttrigger, CSR_TDATA1, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NON DECLARE_CSR_ALIAS(textra32, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE) DECLARE_CSR_ALIAS(textra64, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE) #endif /* DECLARE_CSR_ALIAS */ +#ifdef DECLARE_CHERI_SCR +DECLARE_CHERI_SCR(pcc, CHERI_SCR_PCC) +DECLARE_CHERI_SCR(ddc, CHERI_SCR_DDC) +DECLARE_CHERI_SCR(utcc, CHERI_SCR_UTCC) +DECLARE_CHERI_SCR(utdc, CHERI_SCR_UTDC) +DECLARE_CHERI_SCR(uscratchc, CHERI_SCR_USCRATCHC) +DECLARE_CHERI_SCR(uepcc, CHERI_SCR_UEPCC) +DECLARE_CHERI_SCR(stcc, CHERI_SCR_STCC) +DECLARE_CHERI_SCR(stdc, CHERI_SCR_STDC) +DECLARE_CHERI_SCR(sscratchc, CHERI_SCR_SSCRATCHC) +DECLARE_CHERI_SCR(sepcc, CHERI_SCR_SEPCC) +DECLARE_CHERI_SCR(mtcc, CHERI_SCR_MTCC) +DECLARE_CHERI_SCR(mtdc, CHERI_SCR_MTDC) +DECLARE_CHERI_SCR(mscratchc, CHERI_SCR_MSCRATCHC) +DECLARE_CHERI_SCR(mepcc, CHERI_SCR_MEPCC) +#endif diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index b769769b4ec..dd8ff167885 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -256,6 +256,12 @@ static const char * const riscv_pred_succ[16] = #define OP_MASK_FUNCT2 0x3 #define OP_SH_FUNCT2 25 +/* CHERI fields */ +#define OP_MASK_IMM16 0xffff +#define OP_SH_IMM16 16 +#define OP_MASK_SCR 0x1f +#define OP_SH_SCR 20 + /* RVC fields. */ #define OP_MASK_OP2 0x3 @@ -323,8 +329,13 @@ static const char * const riscv_pred_succ[16] = #define X_T2 7 #define X_T3 28 +/* ABI names for selected c-registers. */ + +#define C_CRA 1 + #define NGPR 32 #define NFPR 32 +#define NGPCR 32 /* These fake label defines are use by both the assembler, and libopcodes. The assembler uses this when it needs to generate a fake @@ -391,6 +402,8 @@ enum riscv_insn_class INSN_CLASS_ZICBOM, INSN_CLASS_ZICBOP, INSN_CLASS_ZICBOZ, + INSN_CLASS_XCHERI, + INSN_CLASS_XCHERI_AND_A, }; /* This structure holds information for a particular instruction. */ @@ -513,6 +526,8 @@ extern const char * const riscv_gpr_names_numeric[NGPR]; extern const char * const riscv_gpr_names_abi[NGPR]; extern const char * const riscv_fpr_names_numeric[NFPR]; extern const char * const riscv_fpr_names_abi[NFPR]; +extern const char * const riscv_gpcr_names_numeric[NGPCR]; +extern const char * const riscv_gpcr_names_abi[NGPCR]; extern const char * const riscv_vecr_names_numeric[NVECR]; extern const char * const riscv_vecm_names_numeric[NVECM]; extern const char * const riscv_vsew[8]; diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 57b798d8e14..9477dbaf7c3 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -61,6 +61,7 @@ enum riscv_seg_mstate last_map_state; static const char * const *riscv_gpr_names; static const char * const *riscv_fpr_names; +static const char * const *riscv_gpcr_names; /* If set, disassemble as most general instruction. */ static int no_aliases; @@ -70,6 +71,7 @@ set_default_riscv_dis_options (void) { riscv_gpr_names = riscv_gpr_names_abi; riscv_fpr_names = riscv_fpr_names_abi; + riscv_gpcr_names = riscv_gpcr_names_abi; no_aliases = 0; } @@ -82,6 +84,7 @@ parse_riscv_dis_option_without_args (const char *option) { riscv_gpr_names = riscv_gpr_names_numeric; riscv_fpr_names = riscv_fpr_names_numeric; + riscv_gpcr_names = riscv_gpcr_names_numeric; } else return false; @@ -360,6 +363,60 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info } break; + case 'X': /* CHERI */ + switch (*++oparg) + { + case 's': + print (info->stream, "%s", riscv_gpcr_names[rs1]); + break; + case 't': + print (info->stream, "%s", riscv_gpcr_names[EXTRACT_OPERAND (RS2, l)]); + break; + case 'd': + print (info->stream, "%s", riscv_gpcr_names[rd]); + break; + case 'D': /* 0 means DDC */ + { + const char *reg_name = NULL; + unsigned int reg = 0; + switch (*++oparg) + { + case 's': + reg = rs1; + break; + case 't': + reg = EXTRACT_OPERAND (RS2, l); + break; + } + if (reg == 0) + reg_name = "ddc"; + else + reg_name = riscv_gpcr_names[reg]; + print (info->stream, "%s", reg_name); + break; + } + case 'E': + { + const char* scr_name = NULL; + unsigned int scr = EXTRACT_OPERAND (SCR, l); + switch (scr) + { +#define DECLARE_CHERI_SCR(name, num) case num: scr_name = #name; break; +#include "opcode/riscv-opc.h" +#undef DECLARE_CHERI_SCR + } + if (scr_name) + print (info->stream, "%s", scr_name); + else + print (info->stream, "0x%x", scr); + break; + } + case 'I': + print (info->stream, "0x%x", (int) EXTRACT_OPERAND (IMM16, l) & 0xffff); + break; + } + break; + case ',': case '(': case ')': diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 523d1652267..85b388b4f03 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -1,5 +1,12 @@ /* RISC-V opcode list Copyright (C) 2011-2022 Free Software Foundation, Inc. + Copyright (c) 2018 Hesham Almatary + All rights reserved. + + This software was, in part, developed by SRI International and the + University of Cambridge Computer Laboratory (Department of Computer + Science and Technology) under DARPA contract HR0011-18-C-0016 + ("ECATS"), as part of the DARPA SSITH research programme. Contributed by Andrew Waterman (andrew@sifive.com). Based on MIPS target. @@ -58,6 +65,20 @@ const char * const riscv_fpr_names_abi[NFPR] = "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11" }; +const char * const riscv_gpcr_names_numeric[NGPCR] = { + "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", + "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", + "c16", "c17", "c18", "c19", "c20", "c21", "c22", "c23", + "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31" +}; + +const char * const riscv_gpcr_names_abi[NGPCR] = { + "cnull", "cra", "csp", "cgp", "ctp", "ct0", "ct1", "ct2", + "cs0", "cs1", "ca0", "ca1", "ca2", "ca3", "ca4", "ca5", + "ca6", "ca7", "cs2", "cs3", "cs4", "cs5", "cs6", "cs7", + "cs8", "cs9", "cs10", "cs11", "ct3", "ct4", "ct5", "ct6" +}; + /* RVV registers. */ const char * const riscv_vecr_names_numeric[NVECR] = { @@ -131,6 +152,11 @@ const char * const riscv_vma[2] = #define MASK_VS2 (OP_MASK_VS2 << OP_SH_VS2) #define MASK_VMASK (OP_MASK_VMASK << OP_SH_VMASK) +/* CHERI */ +#define MASK_CS1 (OP_MASK_RS1 << OP_SH_RS1) +#define MASK_CS2 (OP_MASK_RS2 << OP_SH_RS2) +#define MASK_CD (OP_MASK_RD << OP_SH_RD) + static int match_opcode (const struct riscv_opcode *op, insn_t insn) { @@ -1762,6 +1788,185 @@ const struct riscv_opcode riscv_opcodes[] = {"hsv.w", 0, INSN_CLASS_I, "t,0(s)", MATCH_HSV_W, MASK_HSV_W, match_opcode, INSN_DREF|INSN_4_BYTE }, {"hsv.d", 64, INSN_CLASS_I, "t,0(s)", MATCH_HSV_D, MASK_HSV_D, match_opcode, INSN_DREF|INSN_8_BYTE }, +/* CHERI */ + +/* Capability-Inspection Instructions */ +{"cgetperm", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETPERM, MASK_CGETPERM, match_opcode, 0}, +{"cgetype", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETTYPE, MASK_CGETTYPE, match_opcode, 0}, +{"cgetbase", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETBASE, MASK_CGETBASE, match_opcode, 0}, +{"cgetlen", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETLEN, MASK_CGETLEN, match_opcode, 0}, +{"cgettag", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETTAG, MASK_CGETTAG, match_opcode, 0}, +{"cgetsealed", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETSEALED, MASK_CGETSEALED, match_opcode, 0}, +{"cgetoffset", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETOFFSET, MASK_CGETOFFSET, match_opcode, 0}, +{"cgetflags", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETFLAGS, MASK_CGETFLAGS, match_opcode, 0}, +{"cgetaddr", 0, INSN_CLASS_XCHERI, "d,Xs", MATCH_CGETADDR, MASK_CGETADDR, match_opcode, 0}, + +/* Capability-Modification Instructions */ +{"cseal", 0, INSN_CLASS_XCHERI, "Xd,Xs,Xt", MATCH_CSEAL, MASK_CSEAL, match_opcode, 0}, +{"cunseal", 0, INSN_CLASS_XCHERI, "Xd,Xs,Xt", MATCH_CUNSEAL, MASK_CUNSEAL, match_opcode, 0}, + +{"candperm", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CANDPERM, MASK_CANDPERM, match_opcode, 0}, +{"csetflags", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CSETFLAGS, MASK_CSETFLAGS, match_opcode, 0}, +{"csetoffset", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CSETOFFSET, MASK_CSETOFFSET, match_opcode, 0}, +{"csetaddr", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CSETADDR, MASK_CSETADDR, match_opcode, 0}, +{"cincoffset", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CINCOFFSET, MASK_CINCOFFSET, match_opcode, 0}, +{"cincoffset", 0, INSN_CLASS_XCHERI, "Xd,Xs,j", MATCH_CINCOFFSETIMMEDIATE, MASK_CINCOFFSETIMMEDIATE, match_opcode, 0}, +{"cincoffsetimm", 0, INSN_CLASS_XCHERI, "Xd,Xs,j", MATCH_CINCOFFSETIMMEDIATE, MASK_CINCOFFSETIMMEDIATE, match_opcode, INSN_ALIAS}, +{"csetbounds", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CSETBOUNDS, MASK_CSETBOUNDS, match_opcode, 0}, +{"csetbounds", 0, INSN_CLASS_XCHERI, "Xd,Xs,j", MATCH_CSETBOUNDSIMMEDIATE, MASK_CSETBOUNDSIMMEDIATE, match_opcode, 0}, +{"csetboundsimm", 0, INSN_CLASS_XCHERI, "Xd,Xs,j", MATCH_CSETBOUNDSIMMEDIATE, MASK_CSETBOUNDSIMMEDIATE, match_opcode, INSN_ALIAS}, +{"csetboundsexact", 0, INSN_CLASS_XCHERI, "Xd,Xs,t", MATCH_CSETBOUNDSEXACT, MASK_CSETBOUNDSEXACT, match_opcode, 0}, + +{"ccleartag", 0, INSN_CLASS_XCHERI, "Xd,Xs", MATCH_CCLEARTAG, MASK_CCLEARTAG, match_opcode, 0}, +{"cbuildcap", 0, INSN_CLASS_XCHERI, "Xd,XDs,Xt", MATCH_CBUILDCAP, MASK_CBUILDCAP, match_opcode, 0}, +{"ccopytype", 0, INSN_CLASS_XCHERI, "Xd,Xs,Xt", MATCH_CCOPYTYPE, MASK_CCOPYTYPE, match_opcode, 0}, +{"ccseal", 0, INSN_CLASS_XCHERI, "Xd,Xs,Xt", MATCH_CCSEAL, MASK_CCSEAL, match_opcode, 0}, +{"csealentry", 0, INSN_CLASS_XCHERI, "Xd,Xs", MATCH_CSEALENTRY, MASK_CSEALENTRY, match_opcode, 0}, + +/* Pointer-Arithmetic Instructions */ +{"ctoptr", 0, INSN_CLASS_XCHERI, "d,Xs,XDt", MATCH_CTOPTR, MASK_CTOPTR, match_opcode, 0}, +{"cfromptr", 0, INSN_CLASS_XCHERI, "Xd,XDs,t", MATCH_CFROMPTR, MASK_CFROMPTR, match_opcode, 0}, +{"csub", 0, INSN_CLASS_XCHERI, "d,Xs,Xt", MATCH_CSUB, MASK_CSUB, match_opcode, 0}, + +{"cmove", 0, INSN_CLASS_XCHERI, "Xd,Xs", MATCH_CMOVE, MASK_CMOVE, match_opcode, 0}, + +/* Pointer-Comparison Instructions */ +{"ctestsubset", 0, INSN_CLASS_XCHERI, "d,XDs,Xt", MATCH_CTESTSUBSET, MASK_CTESTSUBSET, match_opcode, 0}, +{"cseqx", 0, INSN_CLASS_XCHERI, "d,Xs,Xt", MATCH_CSETEQUALEXACT, MASK_CSETEQUALEXACT, match_opcode, INSN_ALIAS}, +{"csetequalexact", 0, INSN_CLASS_XCHERI, "d,Xs,Xt", MATCH_CSETEQUALEXACT, MASK_CSETEQUALEXACT, match_opcode, 0}, + +/* Control-Flow Instructions */ +{"ret.cap", 0, INSN_CLASS_XCHERI, "", MATCH_JALR_CAP | (C_CRA << OP_SH_RS1), MASK_JALR_CAP | MASK_CD | MASK_CS1, match_opcode, INSN_ALIAS|INSN_BRANCH }, +{"jr.cap", 0, INSN_CLASS_XCHERI, "Xs", MATCH_JALR_CAP, MASK_JALR_CAP | MASK_CD, match_opcode, INSN_ALIAS|INSN_BRANCH }, +{"jalr.cap", 0, INSN_CLASS_XCHERI, "Xd,Xs", MATCH_JALR_CAP, MASK_JALR_CAP, match_opcode, INSN_JSR}, + +{"cinvoke", 0, INSN_CLASS_XCHERI, "Xs,Xt", MATCH_CINVOKE, MASK_CINVOKE, match_opcode, INSN_BRANCH}, + +/* Special Capability Register Access Instructions */ +{"cspecialr", 0, INSN_CLASS_XCHERI, "Xd,XE", MATCH_CSPECIALRW, MASK_CSPECIALRW | MASK_RS1, match_opcode, INSN_ALIAS}, +{"cspecialw", 0, INSN_CLASS_XCHERI, "Xs,XE", MATCH_CSPECIALRW, MASK_CSPECIALRW | MASK_RD, match_opcode, INSN_ALIAS}, +{"cspecialrw", 0, INSN_CLASS_XCHERI, "Xd,Xs,XE",MATCH_CSPECIALRW, MASK_CSPECIALRW, match_opcode, 0}, + +/* Fast Register-Clearing Instructions */ +/* +{"cclearlo", 0, INSN_CLASS_XCHERI, "XI", MATCH_CCLEARLO, MASK_CCLEARLO, match_opcode, 0}, +{"cclearhi", 0, INSN_CLASS_XCHERI, "XI", MATCH_CCLEARHI, MASK_CCLEARHI, match_opcode, 0}, +{"fpclearlo", 0, INSN_CLASS_XCHERI, "XI", MATCH_FPCLEARLO, MASK_FPCLEARLO, match_opcode, 0}, +{"fpclearhi", 0, INSN_CLASS_XCHERI, "XI", MATCH_FPCLEARHI, MASK_FPCLEARHI, match_opcode, 0}, +*/ + +/* Adjusting to Compressed Capability Precision Instructions */ +{"crrl", 0, INSN_CLASS_XCHERI, "d,s", MATCH_CROUNDREPRESENTABLELENGTH, MASK_CROUNDREPRESENTABLELENGTH, match_opcode, INSN_ALIAS}, +{"croundrepresentablelength", 0, INSN_CLASS_XCHERI, "d,s", MATCH_CROUNDREPRESENTABLELENGTH, MASK_CROUNDREPRESENTABLELENGTH, match_opcode, 0}, +{"cram", 0, INSN_CLASS_XCHERI, "d,s", MATCH_CREPRESENTABLEALIGNMENTMASK, MASK_CREPRESENTABLEALIGNMENTMASK, match_opcode, INSN_ALIAS}, +{"crepresentablealignmentmask", 0, INSN_CLASS_XCHERI, "d,s", MATCH_CREPRESENTABLEALIGNMENTMASK, MASK_CREPRESENTABLEALIGNMENTMASK, match_opcode, 0}, + +/* Memory Loads with Explicit Address Type Instructions */ +{"lb.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LB_DDC, MASK_LB_DDC, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lh.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LH_DDC, MASK_LH_DDC, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lw.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LW_DDC, MASK_LW_DDC, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"ld.ddc", 64, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LD_DDC, MASK_LD_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lc.ddc", 32, INSN_CLASS_XCHERI, "Xd,0(s)", MATCH_LD_DDC, MASK_LD_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lc.ddc", 64, INSN_CLASS_XCHERI, "Xd,0(s)", MATCH_LQ_DDC, MASK_LQ_DDC, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"lbu.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LBU_DDC, MASK_LBU_DDC, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lhu.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LHU_DDC, MASK_LHU_DDC, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lwu.ddc", 64, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LWU_DDC, MASK_LWU_DDC, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"lb.cap", 0, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LB_CAP, MASK_LB_CAP, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lh.cap", 0, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LH_CAP, MASK_LH_CAP, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lw.cap", 0, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LW_CAP, MASK_LW_CAP, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"ld.cap", 64, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LD_CAP, MASK_LD_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lc.cap", 32, INSN_CLASS_XCHERI, "Xd,0(Xs)",MATCH_LD_CAP, MASK_LD_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lc.cap", 64, INSN_CLASS_XCHERI, "Xd,0(Xs)",MATCH_LQ_CAP, MASK_LQ_CAP, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"lbu.cap", 0, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LBU_CAP, MASK_LBU_CAP, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lhu.cap", 0, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LHU_CAP, MASK_LHU_CAP, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lwu.cap", 64, INSN_CLASS_XCHERI, "d,0(Xs)", MATCH_LWU_CAP, MASK_LWU_CAP, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"lr.b.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_B_DDC, MASK_LR_B_DDC, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lr.h.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_H_DDC, MASK_LR_H_DDC, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lr.w.ddc", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_W_DDC, MASK_LR_W_DDC, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"lr.d.ddc", 64, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_D_DDC, MASK_LR_D_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.ddc", 32, INSN_CLASS_XCHERI, "Xd,0(s)", MATCH_LR_D_DDC, MASK_LR_D_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.ddc", 64, INSN_CLASS_XCHERI, "Xd,0(s)", MATCH_LR_Q_DDC, MASK_LR_Q_DDC, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"lr.b.cap", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_B_CAP, MASK_LR_B_CAP, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lr.h.cap", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_H_CAP, MASK_LR_H_CAP, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lr.w.cap", 0, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_W_CAP, MASK_LR_W_CAP, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"lr.d.cap", 64, INSN_CLASS_XCHERI, "d,0(s)", MATCH_LR_D_CAP, MASK_LR_D_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.cap", 32, INSN_CLASS_XCHERI, "Xd,0(s)", MATCH_LR_D_CAP, MASK_LR_D_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.cap", 64, INSN_CLASS_XCHERI, "Xd,0(s)", MATCH_LR_Q_CAP, MASK_LR_Q_CAP, match_opcode, INSN_DREF|INSN_16_BYTE}, + +/* Memory Stores with Explicit Address Type Instructions */ +{"sb.ddc", 0, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SB_DDC, MASK_SB_DDC, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sh.ddc", 0, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SH_DDC, MASK_SH_DDC, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sw.ddc", 0, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SW_DDC, MASK_SW_DDC, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"sd.ddc", 64, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SD_DDC, MASK_SD_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.ddc", 32, INSN_CLASS_XCHERI, "Xt,0(s)", MATCH_SD_DDC, MASK_SD_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.ddc", 64, INSN_CLASS_XCHERI, "Xt,0(s)", MATCH_SQ_DDC, MASK_SQ_DDC, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sb.cap", 0, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SB_CAP, MASK_SB_CAP, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sh.cap", 0, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SH_CAP, MASK_SH_CAP, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sw.cap", 0, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SW_CAP, MASK_SW_CAP, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"sd.cap", 64, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SD_CAP, MASK_SD_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.cap", 32, INSN_CLASS_XCHERI, "Xt,0(Xs)",MATCH_SD_CAP, MASK_SD_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.cap", 64, INSN_CLASS_XCHERI, "Xt,0(Xs)",MATCH_SQ_CAP, MASK_SQ_CAP, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc.b.ddc", 0, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SC_B_DDC, MASK_SC_B_DDC, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sc.h.ddc", 0, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SC_H_DDC, MASK_SC_H_DDC, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sc.w.ddc", 0, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SC_W_DDC, MASK_SC_W_DDC, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"sc.d.ddc", 64, INSN_CLASS_XCHERI, "t,0(s)", MATCH_SC_D_DDC, MASK_SC_D_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.ddc", 32, INSN_CLASS_XCHERI, "Xt,0(s)", MATCH_SC_D_DDC, MASK_SC_D_DDC, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.ddc", 64, INSN_CLASS_XCHERI, "Xt,0(s)", MATCH_SC_Q_DDC, MASK_SC_Q_DDC, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc.b.cap", 0, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SC_B_CAP, MASK_SC_B_CAP, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sc.h.cap", 0, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SC_H_CAP, MASK_SC_H_CAP, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sc.w.cap", 0, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SC_W_CAP, MASK_SC_W_CAP, match_opcode, INSN_DREF|INSN_4_BYTE}, +{"sc.d.cap", 64, INSN_CLASS_XCHERI, "t,0(Xs)", MATCH_SC_D_CAP, MASK_SC_D_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.cap", 32, INSN_CLASS_XCHERI, "Xt,0(Xs)",MATCH_SC_D_CAP, MASK_SC_D_CAP, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.cap", 64, INSN_CLASS_XCHERI, "Xt,0(Xs)",MATCH_SC_Q_CAP, MASK_SC_Q_CAP, match_opcode, INSN_DREF|INSN_16_BYTE}, + +/* Memory-Access Instructions */ +{"lc", 32, INSN_CLASS_XCHERI, "Xd,o(s)", MATCH_LD, MASK_LD, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lc", 64, INSN_CLASS_XCHERI, "Xd,o(s)", MATCH_LQ, MASK_LQ, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc", 32, INSN_CLASS_XCHERI, "Xt,q(s)", MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc", 64, INSN_CLASS_XCHERI, "Xt,q(s)", MATCH_SQ, MASK_SQ, match_opcode, INSN_DREF|INSN_16_BYTE}, + +/* Atomic Memory-Access Instructions */ +{"lr.b", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_B, MASK_LR_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sc.b", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_B, MASK_SC_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lr.b.aq", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_B | MASK_AQ, MASK_LR_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sc.b.aq", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_B | MASK_AQ, MASK_SC_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lr.b.rl", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_B | MASK_RL, MASK_LR_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sc.b.rl", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_B | MASK_RL, MASK_SC_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lr.b.aqrl", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_B | MASK_AQRL, MASK_LR_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"sc.b.aqrl", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_B | MASK_AQRL, MASK_SC_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE}, +{"lr.h", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_B, MASK_LR_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sc.h", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_B, MASK_SC_B | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lr.h.aq", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_H | MASK_AQ, MASK_LR_H | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sc.h.aq", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_H | MASK_AQ, MASK_SC_H | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lr.h.rl", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_H | MASK_RL, MASK_LR_H | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sc.h.rl", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_H | MASK_RL, MASK_SC_H | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lr.h.aqrl", 0, INSN_CLASS_XCHERI_AND_A, "d,0(s)", MATCH_LR_H | MASK_AQRL, MASK_LR_H | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"sc.h.aqrl", 0, INSN_CLASS_XCHERI_AND_A, "d,t,0(s)", MATCH_SC_H | MASK_AQRL, MASK_SC_H | MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE}, +{"lr.c", 32, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c", 64, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_Q, MASK_LR_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc.c", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_Q, MASK_SC_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"lr.c.aq", 32, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_D | MASK_AQ, MASK_LR_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.aq", 64, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_Q | MASK_AQ, MASK_LR_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc.c.aq", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_D | MASK_AQ, MASK_SC_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.aq", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_Q | MASK_AQ, MASK_SC_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"lr.c.rl", 32, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_D | MASK_RL, MASK_LR_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.rl", 64, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_Q | MASK_RL, MASK_LR_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc.c.rl", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_D | MASK_RL, MASK_SC_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.rl", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_Q | MASK_RL, MASK_SC_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"lr.c.aqrl", 32, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"lr.c.aqrl", 64, INSN_CLASS_XCHERI_AND_A, "Xd,0(s)", MATCH_LR_Q | MASK_AQRL, MASK_LR_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"sc.c.aqrl", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE}, +{"sc.c.aqrl", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_SC_Q | MASK_AQRL, MASK_SC_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE}, +{"amoswap.c", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_D, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"amoswap.c", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_Q, MASK_AMOSWAP_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE }, +{"amoswap.c.aq", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_D | MASK_AQ, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"amoswap.c.aq", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_Q | MASK_AQ, MASK_AMOSWAP_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE }, +{"amoswap.c.rl", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_D | MASK_RL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"amoswap.c.rl", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_Q | MASK_RL, MASK_AMOSWAP_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE }, +{"amoswap.c.aqrl", 32, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE }, +{"amoswap.c.aqrl", 64, INSN_CLASS_XCHERI_AND_A, "Xd,t,0(s)", MATCH_AMOSWAP_Q | MASK_AQRL, MASK_AMOSWAP_Q | MASK_AQRL, match_opcode, INSN_DREF|INSN_16_BYTE }, + /* Terminate the list. */ {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0} };