From: Richard Ball Date: Fri, 16 Jan 2026 12:16:04 +0000 (+0000) Subject: aarch64: Add support for MLBI system instructions X-Git-Tag: binutils-2_46~243 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8e004f124877849c654c0f24c2960970dbc1ee8;p=thirdparty%2Fbinutils-gdb.git aarch64: Add support for MLBI system instructions This patch adds support for MLB invalidate (MLBI) instruction. Syntax: MLBI {, } This instruction is an alias to "SYS #4, C7, C0, #{, }" and MLBI being the preferred disassembly. The following list of MLBI operations are supported in this patch for the MLBI instructions enabled by "+mpamv2" * alle1 * vmalle1 * vpide1 * vpmge1 --- diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index d23c5039afc..8a1638e00ae 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -559,6 +559,7 @@ static htab_t aarch64_sys_regs_dc_hsh; static htab_t aarch64_sys_regs_at_hsh; static htab_t aarch64_sys_regs_tlbi_hsh; static htab_t aarch64_sys_regs_plbi_hsh; +static htab_t aarch64_sys_regs_mlbi_hsh; static htab_t aarch64_sys_regs_sr_hsh; static htab_t aarch64_reg_hsh; static htab_t aarch64_barrier_opt_hsh; @@ -8106,6 +8107,11 @@ parse_operands (char *str, const aarch64_opcode *opcode) parse_sys_ins_reg (&str, aarch64_sys_regs_plbi_hsh, false); goto sys_reg_ins; + case AARCH64_OPND_SYSREG_MLBI: + inst.base.operands[i].sysins_op = + parse_sys_ins_reg (&str, aarch64_sys_regs_mlbi_hsh, false); + goto sys_reg_ins; + case AARCH64_OPND_SYSREG_TLBIP: inst.base.operands[i].sysins_op = parse_sys_ins_reg (&str, aarch64_sys_regs_tlbi_hsh, true); @@ -10503,6 +10509,7 @@ md_begin (void) aarch64_sys_regs_at_hsh = str_htab_create (); aarch64_sys_regs_tlbi_hsh = str_htab_create (); aarch64_sys_regs_plbi_hsh = str_htab_create (); + aarch64_sys_regs_mlbi_hsh = str_htab_create (); aarch64_sys_regs_sr_hsh = str_htab_create (); aarch64_reg_hsh = str_htab_create (); aarch64_barrier_opt_hsh = str_htab_create (); @@ -10549,6 +10556,11 @@ md_begin (void) aarch64_sys_regs_plbi[i].name, aarch64_sys_regs_plbi + i); + for (i = 0; aarch64_sys_regs_mlbi[i].name != NULL; i++) + sysreg_hash_insert (aarch64_sys_regs_mlbi_hsh, + aarch64_sys_regs_mlbi[i].name, + aarch64_sys_regs_mlbi + i); + for (i = 0; aarch64_sys_regs_sr[i].name != NULL; i++) sysreg_hash_insert (aarch64_sys_regs_sr_hsh, aarch64_sys_regs_sr[i].name, diff --git a/gas/testsuite/gas/aarch64/mlbi-1.d b/gas/testsuite/gas/aarch64/mlbi-1.d new file mode 100644 index 00000000000..32647b6e829 --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-1.d @@ -0,0 +1,14 @@ +#as: -march=armv8-a+mpamv2 +#objdump: -dr + +[^:]+: file format .* + +Disassembly of section \.text: + +[^:]+: +.*: d50c70bf mlbi vmalle1 +.*: d50c709f mlbi alle1 +.*: d50c70c0 mlbi vpide1, x0 +.*: d50c70df mlbi vpide1, xzr +.*: d50c70e0 mlbi vpmge1, x0 +.*: d50c70ff mlbi vpmge1, xzr \ No newline at end of file diff --git a/gas/testsuite/gas/aarch64/mlbi-1.s b/gas/testsuite/gas/aarch64/mlbi-1.s new file mode 100644 index 00000000000..008715f2f7b --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-1.s @@ -0,0 +1,9 @@ + .irp mlbi_op vmalle1,alle1 + mlbi \mlbi_op + .endr + + .irp mlbi_op vpide1,vpmge1 + .irp rt, x0, xzr + mlbi \mlbi_op, \rt + .endr + .endr diff --git a/gas/testsuite/gas/aarch64/mlbi-invalid-1.d b/gas/testsuite/gas/aarch64/mlbi-invalid-1.d new file mode 100644 index 00000000000..6b66cb8f47c --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-invalid-1.d @@ -0,0 +1,3 @@ +#name: Invalid mpamv2 MLBI instructions. +#as: -march=armv8-a+mpamv2 +#error_output: mlbi-invalid-1.l diff --git a/gas/testsuite/gas/aarch64/mlbi-invalid-1.l b/gas/testsuite/gas/aarch64/mlbi-invalid-1.l new file mode 100644 index 00000000000..65af536ae55 --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-invalid-1.l @@ -0,0 +1,7 @@ +.*: Assembler messages: +.*: Error: missing register at operand 2 -- `mlbi vpide1' +.*: Error: missing register at operand 2 -- `mlbi vpmge1' +.*: Error: extraneous register at operand 2 -- `mlbi vmalle1,x0' +.*: Error: extraneous register at operand 2 -- `mlbi vmalle1,xzr' +.*: Error: extraneous register at operand 2 -- `mlbi alle1,x0' +.*: Error: extraneous register at operand 2 -- `mlbi alle1,xzr' \ No newline at end of file diff --git a/gas/testsuite/gas/aarch64/mlbi-invalid-1.s b/gas/testsuite/gas/aarch64/mlbi-invalid-1.s new file mode 100644 index 00000000000..a687d83c42e --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-invalid-1.s @@ -0,0 +1,9 @@ + .irp mlbi_op vpide1,vpmge1 + mlbi \mlbi_op + .endr + + .irp mlbi_op vmalle1,alle1 + .irp rt, x0, xzr + mlbi \mlbi_op, \rt + .endr + .endr diff --git a/gas/testsuite/gas/aarch64/mlbi-invalid-2.d b/gas/testsuite/gas/aarch64/mlbi-invalid-2.d new file mode 100644 index 00000000000..11ea14f644b --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-invalid-2.d @@ -0,0 +1,4 @@ +#name: MLBI instructions without +mpamv2. +#as: -march=armv8-a +#source: mlbi-1.s +#error_output: mlbi-invalid-2.l \ No newline at end of file diff --git a/gas/testsuite/gas/aarch64/mlbi-invalid-2.l b/gas/testsuite/gas/aarch64/mlbi-invalid-2.l new file mode 100644 index 00000000000..cfc61f68d3b --- /dev/null +++ b/gas/testsuite/gas/aarch64/mlbi-invalid-2.l @@ -0,0 +1,13 @@ +.*: Assembler messages: +.*: Error: selected processor does not support system register name 'vmalle1' +.*: Error: selected processor does not support `mlbi vmalle1' +.*: Error: selected processor does not support system register name 'alle1' +.*: Error: selected processor does not support `mlbi alle1' +.*: Error: selected processor does not support system register name 'vpide1' +.*: Error: selected processor does not support `mlbi vpide1,x0' +.*: Error: selected processor does not support system register name 'vpide1' +.*: Error: selected processor does not support `mlbi vpide1,xzr' +.*: Error: selected processor does not support system register name 'vpmge1' +.*: Error: selected processor does not support `mlbi vpmge1,x0' +.*: Error: selected processor does not support system register name 'vpmge1' +.*: Error: selected processor does not support `mlbi vpmge1,xzr' \ No newline at end of file diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index e12296fc71a..16d8d1b9cd9 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -751,6 +751,7 @@ enum aarch64_opnd AARCH64_OPND_SYSREG_TLBI, /* System register operand. */ AARCH64_OPND_SYSREG_TLBIP, /* System register operand. */ AARCH64_OPND_SYSREG_PLBI, /* System register operand. */ + AARCH64_OPND_SYSREG_MLBI, /* System register operand. */ AARCH64_OPND_SYSREG_SR, /* System register RCTX operand. */ AARCH64_OPND_BARRIER, /* Barrier operand. */ AARCH64_OPND_BARRIER_DSB_NXS, /* Barrier operand for DSB nXS variant. */ @@ -1676,6 +1677,7 @@ extern const aarch64_sys_ins_reg aarch64_sys_regs_dc []; extern const aarch64_sys_ins_reg aarch64_sys_regs_at []; extern const aarch64_sys_ins_reg aarch64_sys_regs_tlbi []; extern const aarch64_sys_ins_reg aarch64_sys_regs_plbi []; +extern const aarch64_sys_ins_reg aarch64_sys_regs_mlbi []; extern const aarch64_sys_ins_reg aarch64_sys_ins_gic []; extern const aarch64_sys_ins_reg aarch64_sys_ins_gicr []; extern const aarch64_sys_ins_reg aarch64_sys_ins_gsb []; diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c index ca2c939d5b2..f166ca4e1a8 100644 --- a/opcodes/aarch64-asm-2.c +++ b/opcodes/aarch64-asm-2.c @@ -570,6 +570,7 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode) case A64_OPID_d5080000_ic_SYSREG_IC_Rt_SYS: case A64_OPID_d5080000_dc_SYSREG_DC_Rt: case A64_OPID_d5080000_at_SYSREG_AT_Rt: + case A64_OPID_d5080000_mlbi_SYSREG_MLBI_Rt_SYS: case A64_OPID_d5080000_sys_UIMM3_OP1_CRn_CRm_UIMM3_OP2_Rt: value = A64_OPID_d5080000_sys_UIMM3_OP1_CRn_CRm_UIMM3_OP2_Rt; break; @@ -1021,6 +1022,7 @@ aarch64_insert_operand (const aarch64_operand *self, case AARCH64_OPND_SYSREG_TLBI: case AARCH64_OPND_SYSREG_TLBIP: case AARCH64_OPND_SYSREG_PLBI: + case AARCH64_OPND_SYSREG_MLBI: case AARCH64_OPND_SYSREG_SR: case AARCH64_OPND_GIC: case AARCH64_OPND_GICR: diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c index 9dcb83fefac..3f61936e398 100644 --- a/opcodes/aarch64-dis-2.c +++ b/opcodes/aarch64-dis-2.c @@ -37588,6 +37588,9 @@ aarch64_find_next_alias_opcode (const aarch64_opcode *opcode) value = A64_OPID_d5080000_at_SYSREG_AT_Rt; break; case A64_OPID_d5080000_at_SYSREG_AT_Rt: + value = A64_OPID_d5080000_mlbi_SYSREG_MLBI_Rt_SYS; + break; + case A64_OPID_d5080000_mlbi_SYSREG_MLBI_Rt_SYS: value = A64_OPID_d5080000_sys_UIMM3_OP1_CRn_CRm_UIMM3_OP2_Rt; break; case A64_OPID_d5480000_tlbip_SYSREG_TLBIP_Rt_SYS_PAIRREG_OR_XZR: @@ -38003,6 +38006,7 @@ aarch64_extract_operand (const aarch64_operand *self, case AARCH64_OPND_SYSREG_TLBI: case AARCH64_OPND_SYSREG_TLBIP: case AARCH64_OPND_SYSREG_PLBI: + case AARCH64_OPND_SYSREG_MLBI: case AARCH64_OPND_SYSREG_SR: case AARCH64_OPND_GIC: case AARCH64_OPND_GICR: diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index e9614a11002..552be689da8 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -1436,6 +1436,7 @@ aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED, case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break; case AARCH64_OPND_SYSREG_TLBIP: sysins_ops = aarch64_sys_regs_tlbi; break; case AARCH64_OPND_SYSREG_PLBI: sysins_ops = aarch64_sys_regs_plbi; break; + case AARCH64_OPND_SYSREG_MLBI: sysins_ops = aarch64_sys_regs_mlbi; break; case AARCH64_OPND_SYSREG_SR: sysins_ops = aarch64_sys_regs_sr; /* Let's remove op2 for rctx. Refer to comments in the definition of diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c index 4f447aef78f..9c5ac08ed96 100644 --- a/opcodes/aarch64-opc-2.c +++ b/opcodes/aarch64-opc-2.c @@ -144,6 +144,7 @@ const struct aarch64_operand aarch64_operands[] = {AARCH64_OPND_CLASS_SYSTEM, "SYSREG_TLBI", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a TBL invalidation operation specifier"}, {AARCH64_OPND_CLASS_SYSTEM, "SYSREG_TLBIP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a 128-bit TBL invalidation operation specifier"}, {AARCH64_OPND_CLASS_SYSTEM, "SYSREG_PLBI", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a PLB invalidation operation specifier"}, + {AARCH64_OPND_CLASS_SYSTEM, "SYSREG_MLBI", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a MLB invalidation operation specifier"}, {AARCH64_OPND_CLASS_SYSTEM, "SYSREG_SR", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a Speculation Restriction option name (RCTX)"}, {AARCH64_OPND_CLASS_SYSTEM, "BARRIER", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a barrier option name"}, {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_DSB_NXS", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the DSB nXS option qualifier name SY, ISH, NSH, OSH or an optional 5-bit unsigned immediate"}, diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index e4ce347bdc9..df6b5fd0790 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -5089,6 +5089,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_SYSREG_TLBI: case AARCH64_OPND_SYSREG_TLBIP: case AARCH64_OPND_SYSREG_PLBI: + case AARCH64_OPND_SYSREG_MLBI: case AARCH64_OPND_SYSREG_SR: snprintf (buf, size, "%s", style_reg (styler, opnd->sysins_op->name)); break; @@ -5500,6 +5501,15 @@ const aarch64_sys_ins_reg aarch64_sys_regs_plbi[] = { 0, CPENS (0,0,0,0), 0, AARCH64_NO_FEATURES } }; +const aarch64_sys_ins_reg aarch64_sys_regs_mlbi[] = +{ + { "alle1", CPENS (4, C7, C0, 4), 0, AARCH64_FEATURE (MPAMv2)}, + { "vmalle1", CPENS (4, C7, C0, 5), 0, AARCH64_FEATURE (MPAMv2)}, + { "vpide1", CPENS (4, C7, C0, 6), F_HASXT, AARCH64_FEATURE (MPAMv2)}, + { "vpmge1", CPENS (4, C7, C0, 7), F_HASXT, AARCH64_FEATURE (MPAMv2)}, + { 0, CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES } +}; + const aarch64_sys_ins_reg aarch64_sys_ins_gic[] = { { "cdaff", CPENS (0,C12,C1,3), 0, AARCH64_NO_FEATURES }, diff --git a/opcodes/aarch64-tbl-2.h b/opcodes/aarch64-tbl-2.h index e9bc188c69f..d3399bbf5ec 100644 --- a/opcodes/aarch64-tbl-2.h +++ b/opcodes/aarch64-tbl-2.h @@ -1396,6 +1396,7 @@ enum aarch64_opcode_idx A64_OPID_d503349f_pssbb, A64_OPID_d50330bf_dmb_BARRIER, A64_OPID_d50330df_isb_BARRIER_ISB, + A64_OPID_d5080000_mlbi_SYSREG_MLBI_Rt_SYS, A64_OPID_d50330ff_sb, A64_OPID_d508779f_gcspushx, A64_OPID_d50877df_gcspopx, diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 82b3e9dd2ce..0451585bfc4 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -3102,6 +3102,8 @@ static const aarch64_feature_set aarch64_feature_POE2 = AARCH64_FEATURE (POE2); static const aarch64_feature_set aarch64_feature_tev = AARCH64_FEATURE (TEV); +static const aarch64_feature_set aarch64_feature_mpamv2 = + AARCH64_FEATURE (MPAMv2); #define CORE &aarch64_feature_v8 #define FP &aarch64_feature_fp @@ -3238,6 +3240,7 @@ static const aarch64_feature_set aarch64_feature_tev = #define SVE_B16MM &aarch64_feature_sve_b16mm #define POE2 &aarch64_feature_POE2 #define TEV &aarch64_feature_tev +#define MPAMV2 &aarch64_feature_mpamv2 #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS | F_INVALID_IMM_SYMS_1, 0, 0, NULL } @@ -3433,6 +3436,8 @@ static const aarch64_feature_set aarch64_feature_tev = #define MOPS_GO_INSN(NAME, OPCODE, MASK, CLASS, OPS, QUALS, FLAGS, CONSTRAINTS, VERIFIER) \ { NAME, OPCODE, MASK, CLASS, 0, MOPS_GO, OPS, QUALS, FLAGS, \ CONSTRAINTS, 0, VERIFIER } +#define MPAMV2_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \ + { NAME, OPCODE, MASK, CLASS, 0, MPAMV2, OPS, QUALS, FLAGS | F_INVALID_IMM_SYMS_1, 0, 0, NULL } #define HBC_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, CLASS, 0, HBC, OPS, QUALS, FLAGS, 0, 0, NULL } #define CSSC_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS) \ @@ -5126,6 +5131,7 @@ const struct aarch64_opcode aarch64_opcode_table[] = CORE_INSN ("pssbb", 0xd503349f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), CORE_INSN ("dmb", 0xd50330bf, 0xfffff0ff, ic_system, 0, OP1 (BARRIER), {}, 0), CORE_INSN ("isb", 0xd50330df, 0xfffff0ff, ic_system, 0, OP1 (BARRIER_ISB), {}, F_OPD0_OPT | F_DEFAULT (0xF)), + MPAMV2_INSN ("mlbi", 0xd5080000, 0xfff80000, ic_system, OP2 (SYSREG_MLBI, Rt_SYS), QL_SRC_X, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)), SB_INSN ("sb", 0xd50330ff, 0xffffffff, ic_system, OP0 (), {}, 0), GCS_INSN ("gcspushx", 0xd508779f, 0xffffffff, OP0 (), {}, 0), GCS_INSN ("gcspopx", 0xd50877df, 0xffffffff, OP0 (), {}, 0), @@ -8141,6 +8147,8 @@ const struct aarch64_opcode aarch64_opcode_table[] = "a 128-bit TBL invalidation operation specifier") \ Y(SYSTEM, sysins_op, "SYSREG_PLBI", 0, F(), \ "a PLB invalidation operation specifier") \ + Y(SYSTEM, sysins_op, "SYSREG_MLBI", 0, F(), \ + "a MLB invalidation operation specifier") \ Y(SYSTEM, sysins_op, "SYSREG_SR", 0, F(), \ "a Speculation Restriction option name (RCTX)") \ Y(SYSTEM, barrier, "BARRIER", 0, F(), \