From 6c0ecdbad70456b22b538d957e93478b14d0e0bc Mon Sep 17 00:00:00 2001 From: Srinath Parvathaneni Date: Thu, 2 Nov 2023 12:44:13 +0000 Subject: [PATCH] aarch64: Add support for Check Feature Status Extension. This patch adds support for Check Feature Status Extension (CHK) which is mandatory from Armv8.0-A. Also this patch supports "chkfeat" instruction (hint #40). --- gas/NEWS | 2 ++ gas/config/tc-aarch64.c | 29 ++++++++++++++++++--------- gas/doc/c-aarch64.texi | 2 ++ gas/testsuite/gas/aarch64/chk-bad-1.d | 4 ++++ gas/testsuite/gas/aarch64/chk-bad-1.l | 13 ++++++++++++ gas/testsuite/gas/aarch64/chk-bad-1.s | 12 +++++++++++ gas/testsuite/gas/aarch64/chk.d | 11 ++++++++++ gas/testsuite/gas/aarch64/chk.s | 2 ++ gas/testsuite/gas/aarch64/system.d | 2 +- include/opcode/aarch64.h | 7 +++++-- opcodes/aarch64-opc.c | 4 ++++ opcodes/aarch64-tbl.h | 7 +++++++ 12 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/chk-bad-1.d create mode 100644 gas/testsuite/gas/aarch64/chk-bad-1.l create mode 100644 gas/testsuite/gas/aarch64/chk-bad-1.s create mode 100644 gas/testsuite/gas/aarch64/chk.d create mode 100644 gas/testsuite/gas/aarch64/chk.s diff --git a/gas/NEWS b/gas/NEWS index ca03cad90c3..2b593c151bb 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add support for AArch64 Check Feature Status Extension (CHK). + * Add support for 'armv8.9-a' and 'armv9.4-a' for -march in AArch64 GAS. * Add support for Intel USER_MSR instructions. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 7d7e54965f1..f5b7b427dd6 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -6570,6 +6570,7 @@ parse_operands (char *str, const aarch64_opcode *opcode) case AARCH64_OPND_Rm: case AARCH64_OPND_Rt: case AARCH64_OPND_Rt2: + case AARCH64_OPND_X16: case AARCH64_OPND_Rs: case AARCH64_OPND_Ra: case AARCH64_OPND_Rt_LS64: @@ -6581,17 +6582,26 @@ parse_operands (char *str, const aarch64_opcode *opcode) /* In LS64 load/store instructions Rt register number must be even and <=22. */ if (operands[i] == AARCH64_OPND_Rt_LS64) - { - /* We've already checked if this is valid register. - This will check if register number (Rt) is not undefined for LS64 - instructions: - if Rt<4:3> == '11' || Rt<0> == '1' then UNDEFINED. */ - if ((info->reg.regno & 0x18) == 0x18 || (info->reg.regno & 0x01) == 0x01) { - set_syntax_error (_("invalid Rt register number in 64-byte load/store")); - goto failure; + /* We've already checked if this is valid register. + This will check if register number (Rt) is not undefined for + LS64 instructions: + if Rt<4:3> == '11' || Rt<0> == '1' then UNDEFINED. */ + if ((info->reg.regno & 0x18) == 0x18 + || (info->reg.regno & 0x01) == 0x01) + { + set_syntax_error + (_("invalid Rt register number in 64-byte load/store")); + goto failure; + } + } + else if (operands[i] == AARCH64_OPND_X16) + { + if (info->reg.regno != 16) + { + goto failure; + } } - } break; case AARCH64_OPND_Rd_SP: @@ -10314,6 +10324,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = { {"mops", AARCH64_FEATURE (MOPS), AARCH64_NO_FEATURES}, {"hbc", AARCH64_FEATURE (HBC), AARCH64_NO_FEATURES}, {"cssc", AARCH64_FEATURE (CSSC), AARCH64_NO_FEATURES}, + {"chk", AARCH64_FEATURE (CHK), AARCH64_NO_FEATURES}, {NULL, AARCH64_NO_FEATURES, AARCH64_NO_FEATURES}, }; diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi index 9b73fbf70b2..0cabf72e8e2 100644 --- a/gas/doc/c-aarch64.texi +++ b/gas/doc/c-aarch64.texi @@ -259,6 +259,8 @@ automatically cause those extensions to be disabled. @tab Enable SVE2 SM4 Extension. This implies @code{sm4} and @code{sve2}. @item @code{tme} @tab ARMv8-A @tab No @tab Enable Transactional Memory Extensions. +@item @code{chk} @tab ARMv8-A @tab ARMv8-A + @tab Enable Check Feature Status Extension. @end multitable @node AArch64 Syntax diff --git a/gas/testsuite/gas/aarch64/chk-bad-1.d b/gas/testsuite/gas/aarch64/chk-bad-1.d new file mode 100644 index 00000000000..6389d05f951 --- /dev/null +++ b/gas/testsuite/gas/aarch64/chk-bad-1.d @@ -0,0 +1,4 @@ +#name: Test of chkfeat extension operand +#source: chk-bad-1.s +#as: -march=armv8-a +#error_output: chk-bad-1.l diff --git a/gas/testsuite/gas/aarch64/chk-bad-1.l b/gas/testsuite/gas/aarch64/chk-bad-1.l new file mode 100644 index 00000000000..b7403c21f45 --- /dev/null +++ b/gas/testsuite/gas/aarch64/chk-bad-1.l @@ -0,0 +1,13 @@ +[^ :]+: Assembler messages: +[^ :]+:[0-9]+: Error: expected an integer or zero register at operand 1 -- `chkfeat' +[^ :]+:[0-9]+: Error: operand 1 must be X16 -- `chkfeat x0' +[^ :]+:[0-9]+: Error: operand 1 must be X16 -- `chkfeat x10' +[^ :]+:[0-9]+: Error: operand 1 must be X16 -- `chkfeat x17' +[^ :]+:[0-9]+: Error: operand 1 must be X16 -- `chkfeat x30' +[^ :]+:[0-9]+: Error: expected an integer or zero register at operand 1 -- `chkfeat x31' +[^ :]+:[0-9]+: Error: operand mismatch -- `chkfeat w16' +[^ :]+:[0-9]+: Info: did you mean this\? +[^ :]+:[0-9]+: Info: chkfeat x16 +[^ :]+:[0-9]+: Error: operand 1 must be X16 -- `chkfeat xzr' +[^ :]+:[0-9]+: Error: operand 1 must be X16 -- `chkfeat wzr' +[^ :]+:[0-9]+: Error: expected an integer or zero register at operand 1 -- `chkfeat sp' diff --git a/gas/testsuite/gas/aarch64/chk-bad-1.s b/gas/testsuite/gas/aarch64/chk-bad-1.s new file mode 100644 index 00000000000..5e75d58ffa8 --- /dev/null +++ b/gas/testsuite/gas/aarch64/chk-bad-1.s @@ -0,0 +1,12 @@ + .text + chkfeat + chkfeat x0 + chkfeat x10 + chkfeat x17 + chkfeat x30 + chkfeat x31 + chkfeat x16 + chkfeat w16 + chkfeat xzr + chkfeat wzr + chkfeat sp diff --git a/gas/testsuite/gas/aarch64/chk.d b/gas/testsuite/gas/aarch64/chk.d new file mode 100644 index 00000000000..6222eca4ddf --- /dev/null +++ b/gas/testsuite/gas/aarch64/chk.d @@ -0,0 +1,11 @@ +#name: Test of Check Feature Status Instruction. +#as: -march=armv8-a +#objdump: -dr + +[^:]+: file format .* + + +[^:]+: + +[^:]+: +.*: d503251f chkfeat x16 diff --git a/gas/testsuite/gas/aarch64/chk.s b/gas/testsuite/gas/aarch64/chk.s new file mode 100644 index 00000000000..3d6dc53e046 --- /dev/null +++ b/gas/testsuite/gas/aarch64/chk.s @@ -0,0 +1,2 @@ + .text + chkfeat x16 diff --git a/gas/testsuite/gas/aarch64/system.d b/gas/testsuite/gas/aarch64/system.d index 6de9aeb00d1..8ad27465504 100644 --- a/gas/testsuite/gas/aarch64/system.d +++ b/gas/testsuite/gas/aarch64/system.d @@ -55,7 +55,7 @@ Disassembly of section \.text: .*: d50324bf hint #0x25 .*: d50324df (hint #0x26|bti jc) .*: d50324ff hint #0x27 -.*: d503251f hint #0x28 +.*: d503251f (hint #0x28|chkfeat x16) .*: d503253f hint #0x29 .*: d503255f hint #0x2a .*: d503257f hint #0x2b diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 631ecf1a4fd..a60965c82b3 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -159,9 +159,10 @@ enum aarch64_feature_bit { AARCH64_FEATURE_CSSC, /* Armv8.9-A processors. */ AARCH64_FEATURE_V8_9A, + /* Check Feature Status Extension. */ + AARCH64_FEATURE_CHK, /* SME2. */ AARCH64_FEATURE_SME2, - DUMMY1, DUMMY2, AARCH64_NUM_FEATURES }; @@ -183,7 +184,8 @@ enum aarch64_feature_bit { #define AARCH64_ARCH_V8A_FEATURES(X) (AARCH64_FEATBIT (X, V8A) \ | AARCH64_FEATBIT (X, FP) \ | AARCH64_FEATBIT (X, RAS) \ - | AARCH64_FEATBIT (X, SIMD)) + | AARCH64_FEATBIT (X, SIMD) \ + | AARCH64_FEATBIT (X, CHK)) #define AARCH64_ARCH_V8_1A_FEATURES(X) (AARCH64_FEATBIT (X, V8_1A) \ | AARCH64_FEATBIT (X, CRC) \ | AARCH64_FEATBIT (X, LSE) \ @@ -386,6 +388,7 @@ enum aarch64_opnd AARCH64_OPND_Rm, /* Integer register as source. */ AARCH64_OPND_Rt, /* Integer register used in ld/st instructions. */ AARCH64_OPND_Rt2, /* Integer register used in ld/st pair instructions. */ + AARCH64_OPND_X16, /* Integer register x16 in chkfeat instruction. */ AARCH64_OPND_Rt_LS64, /* Integer register used in LS64 instructions. */ AARCH64_OPND_Rt_SP, /* Integer Rt or SP used in STG instructions. */ AARCH64_OPND_Rs, /* Integer register used in ld/st exclusive. */ diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 295638d6d8c..599bb636537 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -4612,6 +4612,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, snprintf (buf, size, "%s", style_sub_mnem (styler, "csync")); break; + case AARCH64_OPND_X16: + snprintf (buf, size, "%s", style_reg (styler, "x16")); + break; + case AARCH64_OPND_SME_ZT0: snprintf (buf, size, "%s", style_reg (styler, "zt0")); break; diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index dc72b13f5f7..8f4bfc3f2d8 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -2572,6 +2572,8 @@ static const aarch64_feature_set aarch64_feature_hbc = AARCH64_FEATURE (HBC); static const aarch64_feature_set aarch64_feature_cssc = AARCH64_FEATURE (CSSC); +static const aarch64_feature_set aarch64_feature_chk = + AARCH64_FEATURE (CHK); #define CORE &aarch64_feature_v8 #define FP &aarch64_feature_fp @@ -2630,6 +2632,7 @@ static const aarch64_feature_set aarch64_feature_cssc = #define MOPS_MEMTAG &aarch64_feature_mops_memtag #define HBC &aarch64_feature_hbc #define CSSC &aarch64_feature_cssc +#define CHK &aarch64_feature_chk #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL } @@ -2777,6 +2780,8 @@ static const aarch64_feature_set aarch64_feature_cssc = { NAME, OPCODE, MASK, CLASS, 0, HBC, OPS, QUALS, FLAGS, 0, 0, NULL } #define CSSC_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, cssc, 0, CSSC, OPS, QUALS, FLAGS, 0, 0, NULL } +#define CHK_INSN(NAME, OPCODE, MASK, OPS, QUALS, FLAGS) \ + { NAME, OPCODE, MASK, ic_system, 0, CHK, OPS, QUALS, FLAGS, 0, 0, NULL } #define MOPS_CPY_OP1_OP2_PME_INSN(NAME, OPCODE, MASK, FLAGS, CONSTRAINTS) \ MOPS_INSN (NAME, OPCODE, MASK, 0, \ @@ -4106,6 +4111,7 @@ const struct aarch64_opcode aarch64_opcode_table[] = SME_INSN ("smstart", 0xd503417f, 0xfffff1ff, sme_start, 0, OP1 (SME_SM_ZA), {}, F_SYS_WRITE, 0), SME_INSN ("smstop", 0xd503407f, 0xfffff1ff, sme_stop, 0, OP1 (SME_SM_ZA), {}, F_SYS_WRITE, 0), /* System. */ + CHK_INSN ("chkfeat", 0xd503251f, 0xffffffff, OP1 (X16), QL_I1X, 0), CORE_INSN ("msr", 0xd500401f, 0xfff8f01f, ic_system, 0, OP2 (PSTATEFIELD, UIMM4), {}, F_SYS_WRITE), CORE_INSN ("hint",0xd503201f, 0xfffff01f, ic_system, 0, OP1 (UIMM7), {}, F_HAS_ALIAS), CORE_INSN ("nop", 0xd503201f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS), @@ -6092,6 +6098,7 @@ const struct aarch64_opcode aarch64_opcode_table[] = Y(INT_REG, regno, "Rm", 0, F(FLD_Rm), "an integer register") \ Y(INT_REG, regno, "Rt", 0, F(FLD_Rt), "an integer register") \ Y(INT_REG, regno, "Rt2", 0, F(FLD_Rt2), "an integer register") \ + Y(INT_REG, none, "X16", 0, F(), "X16") \ Y(INT_REG, regno, "Rt_LS64", 0, F(FLD_Rt), "an integer register") \ Y(INT_REG, regno, "Rt_SP", OPD_F_MAYBE_SP, F(FLD_Rt), \ "an integer or stack pointer register") \ -- 2.39.2