From bcca550b3dc542284715c19655c1885bdf2d3b67 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 2 Dec 2021 15:00:57 +0000 Subject: [PATCH] aarch64: Add BC instruction This patch adds support for the Armv8.8-A BC instruction. [https://developer.arm.com/documentation/ddi0596/2021-09/Base-Instructions/BC-cond--Branch-Consistent-conditionally-?lang=en] include/ * opcode/aarch64.h (AARCH64_FEATURE_HBC): New macro. (AARCH64_ARCH_V8_8): Make armv8.8-a imply AARCH64_FEATURE_HBC. opcodes/ * aarch64-tbl.h (aarch64_feature_hbc): New variable. (HBC, HBC_INSN): New macros. (aarch64_opcode_table): Add BC.C. * aarch64-dis-2.c: Regenerate. gas/ * doc/c-aarch64.texi: Document +hbc. * config/tc-aarch64.c (aarch64_features): Add "hbc". * testsuite/gas/aarch64/hbc.s, testsuite/gas/aarch64/hbc.d: New test. * testsuite/gas/aarch64/hbc-invalid.s, testsuite/gas/aarch64/hbc-invalid.l, testsuite/gas/aarch64/hbc-invalid.d: New test. --- gas/config/tc-aarch64.c | 2 + gas/doc/c-aarch64.texi | 2 + gas/testsuite/gas/aarch64/hbc-invalid.d | 1 + gas/testsuite/gas/aarch64/hbc-invalid.l | 3 + gas/testsuite/gas/aarch64/hbc-invalid.s | 8 ++ gas/testsuite/gas/aarch64/hbc.d | 37 +++++++++ gas/testsuite/gas/aarch64/hbc.s | 37 +++++++++ include/opcode/aarch64.h | 4 +- opcodes/aarch64-dis-2.c | 105 +++++++++++++----------- opcodes/aarch64-tbl.h | 7 ++ 10 files changed, 158 insertions(+), 48 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/hbc-invalid.d create mode 100644 gas/testsuite/gas/aarch64/hbc-invalid.l create mode 100644 gas/testsuite/gas/aarch64/hbc-invalid.s create mode 100644 gas/testsuite/gas/aarch64/hbc.d create mode 100644 gas/testsuite/gas/aarch64/hbc.s diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index ea65da580de..7277f38a4bb 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -9980,6 +9980,8 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = { AARCH64_ARCH_NONE}, {"mops", AARCH64_FEATURE (AARCH64_FEATURE_MOPS, 0), AARCH64_ARCH_NONE}, + {"hbc", AARCH64_FEATURE (AARCH64_FEATURE_HBC, 0), + AARCH64_ARCH_NONE}, {NULL, AARCH64_ARCH_NONE, AARCH64_ARCH_NONE}, }; diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi index 7edcccec7eb..29bfd49207f 100644 --- a/gas/doc/c-aarch64.texi +++ b/gas/doc/c-aarch64.texi @@ -183,6 +183,8 @@ automatically cause those extensions to be disabled. @tab Enable ARMv8.2 16-bit floating-point support. This implies @code{fp}. @item @code{fp} @tab ARMv8-A @tab ARMv8-A or later @tab Enable floating-point extensions. +@item @code{hbc} @tab @tab Armv8.8-A or later + @tab Enable Armv8.8-A hinted conditional branch instructions @item @code{i8mm} @tab ARMv8.2-A @tab ARMv8.6-A or later @tab Enable Int8 Matrix Multiply extension. @item @code{lor} @tab ARMv8-A @tab ARMv8.1-A or later diff --git a/gas/testsuite/gas/aarch64/hbc-invalid.d b/gas/testsuite/gas/aarch64/hbc-invalid.d new file mode 100644 index 00000000000..f243de547f6 --- /dev/null +++ b/gas/testsuite/gas/aarch64/hbc-invalid.d @@ -0,0 +1 @@ +#error_output: hbc-invalid.l diff --git a/gas/testsuite/gas/aarch64/hbc-invalid.l b/gas/testsuite/gas/aarch64/hbc-invalid.l new file mode 100644 index 00000000000..aef7a21c1dd --- /dev/null +++ b/gas/testsuite/gas/aarch64/hbc-invalid.l @@ -0,0 +1,3 @@ +[^:]*: Assembler messages: +[^:]*:4: Error: selected processor does not support `bc.eq 1b' +[^:]*:8: Error: selected processor does not support `bc.eq 1b' diff --git a/gas/testsuite/gas/aarch64/hbc-invalid.s b/gas/testsuite/gas/aarch64/hbc-invalid.s new file mode 100644 index 00000000000..bc2208755d9 --- /dev/null +++ b/gas/testsuite/gas/aarch64/hbc-invalid.s @@ -0,0 +1,8 @@ + .arch armv8.7-a + +1: + bc.eq 1b + + .arch armv8.7-a+mops + + bc.eq 1b diff --git a/gas/testsuite/gas/aarch64/hbc.d b/gas/testsuite/gas/aarch64/hbc.d new file mode 100644 index 00000000000..baf963d4d1f --- /dev/null +++ b/gas/testsuite/gas/aarch64/hbc.d @@ -0,0 +1,37 @@ +# objdump: -dr + +.* + + +Disassembly of section \.text: + +0+ <\.text>: +[^:]*: 54000010 bc\.eq 0 <\.text> // bc\.none +[^:]*: 54fffff1 bc\.ne 0 <\.text> // bc\.any +[^:]*: 54ffffd9 bc\.ls 0 <\.text> // bc\.plast +[^:]*: 54ffffb3 bc\.cc 0 <\.text> // bc\.lo, bc\.ul, bc\.last +[^:]*: 54ffff98 bc\.hi 0 <\.text> // bc\.pmore +[^:]*: 54ffff72 bc\.cs 0 <\.text> // bc\.hs, bc\.nlast +[^:]*: 54ffff58 bc\.hi 0 <\.text> // bc\.pmore +[^:]*: 54ffff3b bc\.lt 0 <\.text> // bc\.tstop +[^:]*: 54ffff1d bc\.le 0 <\.text> +[^:]*: 54fffefc bc\.gt 0 <\.text> +[^:]*: 54fffeda bc\.ge 0 <\.text> // bc\.tcont +[^:]*: 54fffeb3 bc\.cc 0 <\.text> // bc\.lo, bc\.ul, bc\.last +[^:]*: 54fffe92 bc\.cs 0 <\.text> // bc\.hs, bc\.nlast +[^:]*: 54fffe76 bc\.vs 0 <\.text> +[^:]*: 54fffe57 bc\.vc 0 <\.text> +[^:]*: 54fffe34 bc\.mi 0 <\.text> // bc\.first +[^:]*: 54fffe15 bc\.pl 0 <\.text> // bc\.nfrst +[^:]*: 54fffdf3 bc\.cc 0 <\.text> // bc\.lo, bc\.ul, bc\.last +[^:]*: 54fffdd1 bc\.ne 0 <\.text> // bc\.any +[^:]*: 54fffdb0 bc\.eq 0 <\.text> // bc\.none +[^:]*: 54fffd94 bc\.mi 0 <\.text> // bc\.first +[^:]*: 54fffd75 bc\.pl 0 <\.text> // bc\.nfrst +[^:]*: 54fffd53 bc\.cc 0 <\.text> // bc\.lo, bc\.ul, bc\.last +[^:]*: 54fffd32 bc\.cs 0 <\.text> // bc\.hs, bc\.nlast +[^:]*: 54fffd18 bc\.hi 0 <\.text> // bc\.pmore +[^:]*: 54fffcf9 bc\.ls 0 <\.text> // bc\.plast +[^:]*: 54fffcda bc\.ge 0 <\.text> // bc\.tcont +[^:]*: 54fffcbb bc\.lt 0 <\.text> // bc\.tstop +[^:]*: 54fffc90 bc\.eq 0 <\.text> // bc\.none diff --git a/gas/testsuite/gas/aarch64/hbc.s b/gas/testsuite/gas/aarch64/hbc.s new file mode 100644 index 00000000000..23af6ba8edd --- /dev/null +++ b/gas/testsuite/gas/aarch64/hbc.s @@ -0,0 +1,37 @@ + .arch armv8.8-a + +1: + bc.eq 1b + bc.ne 1b + bc.ls 1b + bc.lo 1b + bc.hi 1b + bc.hs 1b + bc.hi 1b + bc.lt 1b + bc.le 1b + bc.gt 1b + bc.ge 1b + bc.cc 1b + bc.cs 1b + bc.vs 1b + bc.vc 1b + bc.mi 1b + bc.pl 1b + + bc.ul 1b + + bc.any 1b + bc.none 1b + bc.first 1b + bc.nfrst 1b + bc.last 1b + bc.nlast 1b + bc.pmore 1b + bc.plast 1b + bc.tcont 1b + bc.tstop 1b + + .arch armv8.7-a+hbc + + bc.eq 1b diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 21ba0bf0074..4d4f108f39a 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -88,6 +88,7 @@ typedef uint32_t aarch64_insn; #define AARCH64_FEATURE_MEMTAG (1ULL << 48) /* Memory Tagging Extension. */ #define AARCH64_FEATURE_TME (1ULL << 49) /* Transactional Memory Extension. */ #define AARCH64_FEATURE_MOPS (1ULL << 50) /* Standardization of memory operations. */ +#define AARCH64_FEATURE_HBC (1ULL << 51) /* Hinted conditional branches. */ #define AARCH64_FEATURE_I8MM (1ULL << 52) /* Matrix Multiply instructions. */ #define AARCH64_FEATURE_F32MM (1ULL << 53) #define AARCH64_FEATURE_F64MM (1ULL << 54) @@ -145,7 +146,8 @@ typedef uint32_t aarch64_insn; | AARCH64_FEATURE_LS64) #define AARCH64_ARCH_V8_8 AARCH64_FEATURE (AARCH64_ARCH_V8_7, \ AARCH64_FEATURE_V8_8 \ - | AARCH64_FEATURE_MOPS) + | AARCH64_FEATURE_MOPS \ + | AARCH64_FEATURE_HBC) #define AARCH64_ARCH_V8_R (AARCH64_FEATURE (AARCH64_ARCH_V8_4, \ AARCH64_FEATURE_V8_R) \ & ~(AARCH64_FEATURE_V8_A | AARCH64_FEATURE_LOR)) diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c index 70cbf908e81..37a0f8c80f6 100644 --- a/opcodes/aarch64-dis-2.c +++ b/opcodes/aarch64-dis-2.c @@ -16913,87 +16913,98 @@ aarch64_opcode_lookup_1 (uint32_t word) } else { - if (((word >> 10) & 0x1) == 0) + if (((word >> 25) & 0x1) == 0) { - if (((word >> 21) & 0x1) == 0) + /* 33222222222211111111110000000000 + 10987654321098765432109876543210 + x1010100xxxxxxxxxxxxxxxxxxx1xxxx + bc.c. */ + return 2631; + } + else + { + if (((word >> 10) & 0x1) == 0) { - if (((word >> 22) & 0x1) == 0) + if (((word >> 21) & 0x1) == 0) { - if (((word >> 23) & 0x1) == 0) + if (((word >> 22) & 0x1) == 0) { - /* 33222222222211111111110000000000 - 10987654321098765432109876543210 - x10101x0000xxxxxxxxxx0xxxxx1xxxx - braaz. */ - return 647; + if (((word >> 23) & 0x1) == 0) + { + /* 33222222222211111111110000000000 + 10987654321098765432109876543210 + x1010110000xxxxxxxxxx0xxxxx1xxxx + braaz. */ + return 647; + } + else + { + /* 33222222222211111111110000000000 + 10987654321098765432109876543210 + x1010110100xxxxxxxxxx0xxxxx1xxxx + eretaa. */ + return 653; + } } else { /* 33222222222211111111110000000000 10987654321098765432109876543210 - x10101x0100xxxxxxxxxx0xxxxx1xxxx - eretaa. */ - return 653; + x1010110x10xxxxxxxxxx0xxxxx1xxxx + retaa. */ + return 651; } } else { /* 33222222222211111111110000000000 10987654321098765432109876543210 - x10101x0x10xxxxxxxxxx0xxxxx1xxxx - retaa. */ - return 651; + x1010110xx1xxxxxxxxxx0xxxxx1xxxx + blraaz. */ + return 649; } } else { - /* 33222222222211111111110000000000 - 10987654321098765432109876543210 - x10101x0xx1xxxxxxxxxx0xxxxx1xxxx - blraaz. */ - return 649; - } - } - else - { - if (((word >> 21) & 0x1) == 0) - { - if (((word >> 22) & 0x1) == 0) + if (((word >> 21) & 0x1) == 0) { - if (((word >> 23) & 0x1) == 0) + if (((word >> 22) & 0x1) == 0) { - /* 33222222222211111111110000000000 - 10987654321098765432109876543210 - x10101x0000xxxxxxxxxx1xxxxx1xxxx - brabz. */ - return 648; + if (((word >> 23) & 0x1) == 0) + { + /* 33222222222211111111110000000000 + 10987654321098765432109876543210 + x1010110000xxxxxxxxxx1xxxxx1xxxx + brabz. */ + return 648; + } + else + { + /* 33222222222211111111110000000000 + 10987654321098765432109876543210 + x1010110100xxxxxxxxxx1xxxxx1xxxx + eretab. */ + return 654; + } } else { /* 33222222222211111111110000000000 10987654321098765432109876543210 - x10101x0100xxxxxxxxxx1xxxxx1xxxx - eretab. */ - return 654; + x1010110x10xxxxxxxxxx1xxxxx1xxxx + retab. */ + return 652; } } else { /* 33222222222211111111110000000000 10987654321098765432109876543210 - x10101x0x10xxxxxxxxxx1xxxxx1xxxx - retab. */ - return 652; + x1010110xx1xxxxxxxxxx1xxxxx1xxxx + blrabz. */ + return 650; } } - else - { - /* 33222222222211111111110000000000 - 10987654321098765432109876543210 - x10101x0xx1xxxxxxxxxx1xxxxx1xxxx - blrabz. */ - return 650; - } } } } diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 51d8532b8f2..08721b13227 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -2497,6 +2497,8 @@ static const aarch64_feature_set aarch64_feature_mops = AARCH64_FEATURE (AARCH64_FEATURE_MOPS, 0); static const aarch64_feature_set aarch64_feature_mops_memtag = AARCH64_FEATURE (AARCH64_FEATURE_MOPS | AARCH64_FEATURE_MEMTAG, 0); +static const aarch64_feature_set aarch64_feature_hbc = + AARCH64_FEATURE (AARCH64_FEATURE_HBC, 0); #define CORE &aarch64_feature_v8 #define FP &aarch64_feature_fp @@ -2550,6 +2552,7 @@ static const aarch64_feature_set aarch64_feature_mops_memtag = #define FLAGM &aarch64_feature_flagm #define MOPS &aarch64_feature_mops #define MOPS_MEMTAG &aarch64_feature_mops_memtag +#define HBC &aarch64_feature_hbc #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \ { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL } @@ -2681,6 +2684,8 @@ static const aarch64_feature_set aarch64_feature_mops_memtag = #define MOPS_MEMTAG_INSN(NAME, OPCODE, MASK, CLASS, OPS, QUALS, FLAGS, CONSTRAINTS, VERIFIER) \ { NAME, OPCODE, MASK, CLASS, 0, MOPS_MEMTAG, OPS, QUALS, FLAGS, \ CONSTRAINTS, 0, VERIFIER } +#define HBC_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \ + { NAME, OPCODE, MASK, CLASS, 0, HBC, OPS, QUALS, FLAGS, 0, 0, NULL } #define MOPS_CPY_OP1_OP2_PME_INSN(NAME, OPCODE, MASK, FLAGS, CONSTRAINTS) \ MOPS_INSN (NAME, OPCODE, MASK, 0, \ @@ -5417,6 +5422,8 @@ const struct aarch64_opcode aarch64_opcode_table[] = setge setget setgen setgetn */ MOPS_SET_INSN ("setg", 0x1dc00400, 0xffe0fc00, MOPS_MEMTAG_INSN), + HBC_INSN ("bc.c", 0x54000010, 0xff000010, condbranch, OP1 (ADDR_PCREL19), QL_PCREL_NIL, F_COND), + {0, 0, 0, 0, 0, 0, {}, {}, 0, 0, 0, NULL}, }; -- 2.30.2