[PATCH v3] aarch64: Support for FEAT_CMPBR
Alice Carlotti
alice.carlotti@arm.com
Wed May 7 16:22:54 GMT 2025
On Wed, May 07, 2025 at 02:23:02PM +0100, Ezra.Sitorus@arm.com wrote:
> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> FEAT_CMPBR - Compare and branch instructions. This patch adds these
> instructions:
> - CB<CC> (register)
> - CB<CC> (immediate)
> - CBH<CC>
> - CBB<CC>
>
> where CC is one of the following:
> - EQ
> - NE
> - GT
> - GE
> - LT
> - LE
> - HI
> - HS
> - LO
> - LS
> ---
> Regression tested on aarch64-none-linux-gnu. Comments from v2 have been
> addressed in this version. Can somebody commit this if it looks OK?
Thanks for the changes; I have just a few testsuite nits/suggestions to
mention.
>
> Ezra
>
> bfd/elfnn-aarch64.c | 3 +
> bfd/reloc.c | 6 ++
> gas/config/tc-aarch64.c | 42 +++++++++-
> gas/doc/c-aarch64.texi | 2 +
> gas/testsuite/gas/aarch64/cmpbr-1.d | 67 +++++++++++++++
> gas/testsuite/gas/aarch64/cmpbr-1.s | 59 ++++++++++++++
> gas/testsuite/gas/aarch64/cmpbr-bad-1.d | 4 +
> gas/testsuite/gas/aarch64/cmpbr-bad-1.l | 3 +
> gas/testsuite/gas/aarch64/cmpbr-bad-1.s | 3 +
> gas/testsuite/gas/aarch64/cmpbr-bad.d | 4 +
> gas/testsuite/gas/aarch64/cmpbr-bad.l | 13 +++
> gas/testsuite/gas/aarch64/cmpbr-bad.s | 5 ++
> gas/testsuite/gas/aarch64/cmpbr-far.d | 4 +
> gas/testsuite/gas/aarch64/cmpbr-far.l | 3 +
> gas/testsuite/gas/aarch64/cmpbr-far.s | 11 +++
> gas/testsuite/gas/aarch64/cmpbr.d | 103 ++++++++++++++++++++++++
> gas/testsuite/gas/aarch64/cmpbr.s | 90 +++++++++++++++++++++
> include/opcode/aarch64.h | 5 ++
> opcodes/aarch64-opc.c | 3 +
> opcodes/aarch64-opc.h | 1 +
> opcodes/aarch64-tbl.h | 66 +++++++++++++++
> 21 files changed, 495 insertions(+), 2 deletions(-)
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-1.d
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-1.s
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-bad-1.d
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-bad-1.l
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-bad-1.s
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-bad.d
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-bad.l
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-bad.s
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-far.d
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-far.l
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr-far.s
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr.d
> create mode 100644 gas/testsuite/gas/aarch64/cmpbr.s
>
> diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> index 548da1f8b30..8f399204f04 100644
> --- a/bfd/elfnn-aarch64.c
> +++ b/bfd/elfnn-aarch64.c
> @@ -2268,6 +2268,9 @@ elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
> if (code == BFD_RELOC_AARCH64_NONE)
> return &elfNN_aarch64_howto_none;
>
> + if (code == BFD_RELOC_AARCH64_BRANCH9)
> + return &elfNN_aarch64_howto_none;
> +
> return NULL;
> }
>
> diff --git a/bfd/reloc.c b/bfd/reloc.c
> index d3ddafb7305..c9d53bb9e11 100644
> --- a/bfd/reloc.c
> +++ b/bfd/reloc.c
> @@ -7418,6 +7418,12 @@ ENUM
> ENUMDOC
> AArch64 pseudo relocation code to be used internally by the AArch64
> assembler and not (currently) written to any object files.
> +ENUM
> + BFD_RELOC_AARCH64_BRANCH9
> +ENUMDOC
> + AArch64 9 bit pc-relative conditional branch and compare & branch.
> + The lowest two bits must be zero and are not stored in the
> + instruction, giving an 11 bit signed byte offset.
> ENUM
> BFD_RELOC_TILEPRO_COPY
> ENUMX
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index acb56044fb5..e6bd6a7e2f9 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -5175,6 +5175,13 @@ encode_branch_ofs_26 (uint32_t ofs)
> return ofs & ((1 << 26) - 1);
> }
>
> +/* encode the 9-bit offset of FEAT_CMPBR compare and branch */
> +static inline uint32_t
> +encode_cond_branch_ofs_9 (uint32_t ofs)
> +{
> + return (ofs & ((1 << 9) - 1)) << 5;
> +}
> +
> /* encode the 19-bit offset of conditional branch and compare & branch */
> static inline uint32_t
> encode_cond_branch_ofs_19 (uint32_t ofs)
> @@ -6388,6 +6395,8 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
> case AARCH64_OPND_UIMM3_OP2:
> case AARCH64_OPND_IMM:
> case AARCH64_OPND_IMM_2:
> + case AARCH64_OPND_IMMP1_2:
> + case AARCH64_OPND_IMMS1_2:
> case AARCH64_OPND_WIDTH:
> case AARCH64_OPND_UIMM7:
> case AARCH64_OPND_NZCV:
> @@ -7154,6 +7163,16 @@ parse_operands (char *str, const aarch64_opcode *opcode)
> info->imm.value = val;
> break;
>
> + case AARCH64_OPND_IMMP1_2:
> + po_imm_or_fail (1, 64);
> + info->imm.value = val - 1;
> + break;
> +
> + case AARCH64_OPND_IMMS1_2:
> + po_imm_or_fail (-1, 62);
> + info->imm.value = val + 1;
> + break;
> +
> case AARCH64_OPND_SVE_AIMM:
> case AARCH64_OPND_SVE_ASIMM:
> po_imm_nc_or_fail ();
> @@ -7450,6 +7469,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
> info->imm.value = 0;
> break;
>
> + case AARCH64_OPND_ADDR_PCREL9:
> case AARCH64_OPND_ADDR_PCREL14:
> case AARCH64_OPND_ADDR_PCREL19:
> case AARCH64_OPND_ADDR_PCREL21:
> @@ -7487,8 +7507,11 @@ parse_operands (char *str, const aarch64_opcode *opcode)
> case compbranch:
> case condbranch:
> /* e.g. CBZ or B.COND */
> - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19);
> - inst.reloc.type = BFD_RELOC_AARCH64_BRANCH19;
> + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL9
> + || operands[i] == AARCH64_OPND_ADDR_PCREL19);
> + inst.reloc.type = (operands[i] == AARCH64_OPND_ADDR_PCREL9)
> + ? BFD_RELOC_AARCH64_BRANCH9
> + : BFD_RELOC_AARCH64_BRANCH19;
> break;
> case testbranch:
> /* e.g. TBZ */
> @@ -9670,6 +9693,20 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
> }
> break;
>
> + case BFD_RELOC_AARCH64_BRANCH9:
> + if (fixP->fx_done || !seg->use_rela_p)
> + {
> + if (value & 3)
> + as_bad_where (fixP->fx_file, fixP->fx_line,
> + _("conditional branch target not word aligned"));
> + if (signed_overflow (value, 11))
> + as_bad_where (fixP->fx_file, fixP->fx_line,
> + _("conditional branch out of range"));
> + insn = get_aarch64_insn (buf);
> + insn |= encode_cond_branch_ofs_9 (value >> 2);
> + put_aarch64_insn (buf, insn);
> + }
> + break;
> case BFD_RELOC_AARCH64_BRANCH19:
> if (fixP->fx_done || !seg->use_rela_p)
> {
> @@ -10672,6 +10709,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
> {"rng", AARCH64_FEATURE (RNG), AARCH64_NO_FEATURES},
> {"ssbs", AARCH64_FEATURE (SSBS), AARCH64_NO_FEATURES},
> {"memtag", AARCH64_FEATURE (MEMTAG), AARCH64_NO_FEATURES},
> + {"cmpbr", AARCH64_FEATURE (CMPBR), AARCH64_NO_FEATURES},
> {"sve2", AARCH64_FEATURE (SVE2), AARCH64_FEATURE (SVE)},
> {"sve2-sm4", AARCH64_FEATURE (SVE2_SM4),
> AARCH64_FEATURES (2, SVE2, SM4)},
> diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
> index 10888d1e78f..3a8e2819c5b 100644
> --- a/gas/doc/c-aarch64.texi
> +++ b/gas/doc/c-aarch64.texi
> @@ -167,6 +167,8 @@ automatically cause those extensions to be disabled.
> @tab Enable the Branch Record Buffer extension.
> @item @code{chk} @tab
> @tab Enable the Check Feature Status Extension.
> +@item @code{cmpbr} @tab
> + @tab Enable Compare and Branch instructions.
> @item @code{compnum} @tab @code{simd}
> @tab Enable the complex number SIMD extensions. An alias of @code{fcma}.
> @item @code{cpa} @tab
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-1.d b/gas/testsuite/gas/aarch64/cmpbr-1.d
> new file mode 100644
> index 00000000000..91b162c1b1c
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-1.d
> @@ -0,0 +1,67 @@
> +#name: Test for FEAT_CMPBR pseudo-instructions
> +#as: -march=armv8-a+cmpbr
> +#objdump: -dr
> +
> +.*: file format .*
> +
> +Disassembly of section .text:
> +
> +.* <a>:
> +.*: 741e0000 cbgt w0, w30, 0 <a>
> +.*: 741e3fe0 cbgt w0, w30, 0 <a>
> +.*: 743e3fc0 cbge w0, w30, 0 <a>
> +.*: 743e3fa0 cbge w0, w30, 0 <a>
> +.*: 745e3f80 cbhi w0, w30, 0 <a>
> +.*: 745e3f60 cbhi w0, w30, 0 <a>
> +.*: 747e3f40 cbhs w0, w30, 0 <a>
> +.*: 747e3f20 cbhs w0, w30, 0 <a>
> +
> +.* <b>:
> +.*: f41e0000 cbgt x0, x30, 20 <b>
> +.*: f41e3fe0 cbgt x0, x30, 20 <b>
> +.*: f43e3fc0 cbge x0, x30, 20 <b>
> +.*: f43e3fa0 cbge x0, x30, 20 <b>
> +.*: f45e3f80 cbhi x0, x30, 20 <b>
> +.*: f45e3f60 cbhi x0, x30, 20 <b>
> +.*: f47e3f40 cbhs x0, x30, 20 <b>
> +.*: f47e3f20 cbhs x0, x30, 20 <b>
> +
> +.* <c>:
> +.*: 75050000 cbgt w0, #10, 40 <c>
> +.*: 75053fe0 cbgt w0, #10, 40 <c>
> +.*: 75263fc0 cblt w0, #12, 40 <c>
> +.*: 75263fa0 cblt w0, #12, 40 <c>
> +.*: 75453f80 cbhi w0, #10, 40 <c>
> +.*: 75453f60 cbhi w0, #10, 40 <c>
> +.*: 75663f40 cblo w0, #12, 40 <c>
> +.*: 75663f20 cblo w0, #12, 40 <c>
> +
> +.* <d>:
> +.*: f5050000 cbgt x0, #10, 60 <d>
> +.*: f5053fe0 cbgt x0, #10, 60 <d>
> +.*: f5263fc0 cblt x0, #12, 60 <d>
> +.*: f5263fa0 cblt x0, #12, 60 <d>
> +.*: f5453f80 cbhi x0, #10, 60 <d>
> +.*: f5453f60 cbhi x0, #10, 60 <d>
> +.*: f5663f5e cblo x30, #12, 60 <d>
> +.*: f5663f3e cblo x30, #12, 60 <d>
> +
> +.* <e>:
> +.*: 741e8000 cbbgt w0, w30, 80 <e>
> +.*: 741ebfe0 cbbgt w0, w30, 80 <e>
> +.*: 743ebfc0 cbbge w0, w30, 80 <e>
> +.*: 743ebfa0 cbbge w0, w30, 80 <e>
> +.*: 745ebf80 cbbhi w0, w30, 80 <e>
> +.*: 745ebf60 cbbhi w0, w30, 80 <e>
> +.*: 747ebf40 cbbhs w0, w30, 80 <e>
> +.*: 747ebf20 cbbhs w0, w30, 80 <e>
> +
> +.* <f>:
> +.*: 741ec000 cbhgt w0, w30, a0 <f>
> +.*: 741effe0 cbhgt w0, w30, a0 <f>
> +.*: 743effc0 cbhge w0, w30, a0 <f>
> +.*: 743effa0 cbhge w0, w30, a0 <f>
> +.*: 745eff80 cbhhi w0, w30, a0 <f>
> +.*: 745eff60 cbhhi w0, w30, a0 <f>
> +.*: 747eff40 cbhhs w0, w30, a0 <f>
> +.*: 747eff20 cbhhs w0, w30, a0 <f>
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-1.s b/gas/testsuite/gas/aarch64/cmpbr-1.s
> new file mode 100644
> index 00000000000..97ea7823f2c
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-1.s
> @@ -0,0 +1,59 @@
> +a:
> + cbgt w0, w30, a
> + cblt w30, w0, a
> + cbge w0, w30, a
> + cble w30, w0, a
> + cbhi w0, w30, a
> + cblo w30, w0, a
> + cbhs w0, w30, a
> + cbls w30, w0, a
> +
> +b:
> + cbgt x0, x30, b
> + cblt x30, x0, b
> + cbge x0, x30, b
> + cble x30, x0, b
> + cbhi x0, x30, b
> + cblo x30, x0, b
> + cbhs x0, x30, b
> + cbls x30, x0, b
> +
> +c:
> + cbgt w0, #10, c
> + cbge w0, #11, c
> + cblt w0, #12, c
> + cble w0, #11, c
> + cbhi w0, #10, c
> + cbhs w0, #11, c
> + cblo w0, #12, c
> + cbls w0, #11, c
> +
> +d:
> + cbgt x0, #10, d
> + cbge x0, #11, d
> + cblt x0, #12, d
> + cble x0, #11, d
> + cbhi x0, #10, d
> + cbhs x0, #11, d
> + cblo x30, #12, d
> + cbls x30, #11, d
> +
> +e:
> + cbbgt w0, w30, e
> + cbblt w30, w0, e
> + cbbge w0, w30, e
> + cbble w30, w0, e
> + cbbhi w0, w30, e
> + cbblo w30, w0, e
> + cbbhs w0, w30, e
> + cbbls w30, w0, e
> +
> +f:
> + cbhgt w0, w30, f
> + cbhlt w30, w0, f
> + cbhge w0, w30, f
> + cbhle w30, w0, f
> + cbhhi w0, w30, f
> + cbhlo w30, w0, f
> + cbhhs w0, w30, f
> + cbhls w30, w0, f
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-bad-1.d b/gas/testsuite/gas/aarch64/cmpbr-bad-1.d
> new file mode 100644
> index 00000000000..f563d274bad
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-bad-1.d
> @@ -0,0 +1,4 @@
> +#name: Test of out-of-range cmpbr operands
> +#source: cmpbr-bad-1.s
> +#as: -march=armv8-a+cmpbr
> +#error_output: cmpbr-bad-1.l
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-bad-1.l b/gas/testsuite/gas/aarch64/cmpbr-bad-1.l
> new file mode 100644
> index 00000000000..3839baf9772
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-bad-1.l
> @@ -0,0 +1,3 @@
> +.[^ :]+: Assembler messages:
> +[^ :]+:[0-9]+: Error: immediate value out of range 1 to 64 at operand 2 -- `cbge w0,#0,a'
> +[^ :]+:[0-9]+: Error: immediate value out of range -1 to 62 at operand 2 -- `cble w0,#63,a'
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-bad-1.s b/gas/testsuite/gas/aarch64/cmpbr-bad-1.s
> new file mode 100644
> index 00000000000..1fd0c3a3909
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-bad-1.s
> @@ -0,0 +1,3 @@
> +a:
> + cbge w0, #0, a
> + cble w0, #63, a
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-bad.d b/gas/testsuite/gas/aarch64/cmpbr-bad.d
> new file mode 100644
> index 00000000000..6487979e85f
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-bad.d
> @@ -0,0 +1,4 @@
> +#name: Test of invalid cmpbr operands
> +#source: cmpbr-bad.s
> +#as: -march=armv8-a+cmpbr
> +#error_output: cmpbr-bad.l
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-bad.l b/gas/testsuite/gas/aarch64/cmpbr-bad.l
> new file mode 100644
> index 00000000000..f705cfd0043
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-bad.l
> @@ -0,0 +1,13 @@
> +.[^ :]+: Assembler messages:
> +[^ :]+:[0-9]+: Error: operand mismatch -- `cbgt w0,x1,a'
> +[^ :]+:[0-9]+: Info: did you mean this\?
> +[^ :]+:[0-9]+: Info: cbgt w0, w1, #0x0
> +[^ :]+:[0-9]+: Info: other valid variant\(s\):
> +[^ :]+:[0-9]+: Info: cbgt x0, x1, #0x0
> +[^ :]+:[0-9]+: Error: immediate value out of range 0 to 63 at operand 2 -- `cbgt w0,#64,a'
> +[^ :]+:[0-9]+: Error: operand mismatch -- `cbbgt x0,x1,a'
> +[^ :]+:[0-9]+: Info: did you mean this\?
> +[^ :]+:[0-9]+: Info: cbbgt w0, w1, #0x0
> +[^ :]+:[0-9]+: Error: operand mismatch -- `cbhgt x0,x1,a'
> +[^ :]+:[0-9]+: Info: did you mean this\?
> +[^ :]+:[0-9]+: Info: cbhgt w0, w1, #0x0
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-bad.s b/gas/testsuite/gas/aarch64/cmpbr-bad.s
> new file mode 100644
> index 00000000000..8fb1e617254
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-bad.s
> @@ -0,0 +1,5 @@
> +a:
> + cbgt w0, x1, a
> + cbgt w0, #64, a
> + cbbgt x0, x1, a
> + cbhgt x0, x1, a
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-far.d b/gas/testsuite/gas/aarch64/cmpbr-far.d
> new file mode 100644
> index 00000000000..a027cdfb837
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-far.d
> @@ -0,0 +1,4 @@
> +#name: CMPBR instructions that branch too far
> +#source: cmpbr-far.s
> +#as: -march=armv8-a+cmpbr
> +#error_output: cmpbr-far.l
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-far.l b/gas/testsuite/gas/aarch64/cmpbr-far.l
> new file mode 100644
> index 00000000000..6432035a1f3
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-far.l
> @@ -0,0 +1,3 @@
> +.[^ :]+: Assembler messages:
> +[^ :]+:[0-9]+: Error: conditional branch out of range
> +[^ :]+:[0-9]+: Error: conditional branch out of range
I don't think this test is as effective as it could be, since it doesn't show
which two offsets are rejected. It would be more effective if you replaced all
the valid cbgt instructions with nops, and tested the valid offsets in a
separate test.
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-far.s b/gas/testsuite/gas/aarch64/cmpbr-far.s
> new file mode 100644
> index 00000000000..56f63dce1eb
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-far.s
> @@ -0,0 +1,11 @@
> +a:
> + .rept 258
> + cbgt w0, w1, a
> + .endr
> +
> + .rept 256
> + cbgt w0, w1, b
> + .endr
> +
> +b:
> + nop
> diff --git a/gas/testsuite/gas/aarch64/cmpbr.d b/gas/testsuite/gas/aarch64/cmpbr.d
> new file mode 100644
> index 00000000000..33862a1b19a
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr.d
> @@ -0,0 +1,103 @@
> +#name: Test for FEAT_CMPBR
> +#as: -march=armv8-a+cmpbr
> +#objdump: -dr
> +
> +.*: file format .*
> +
> +Disassembly of section .text:
> +
> +.* <a>:
> +.*: 74000000 cbgt w0, w0, 0 <a>
> +.*: 741e3fe0 cbgt w0, w30, 0 <a>
> +.*: 74003fde cbgt w30, w0, 0 <a>
> +.*: 74203fa0 cbge w0, w0, 0 <a>
> +.*: 743e3f80 cbge w0, w30, 0 <a>
> +.*: 74203f7e cbge w30, w0, 0 <a>
> +.*: 74403f40 cbhi w0, w0, 0 <a>
> +.*: 745e3f20 cbhi w0, w30, 0 <a>
> +.*: 74403f1e cbhi w30, w0, 0 <a>
> +.*: 74603ee0 cbhs w0, w0, 0 <a>
> +.*: 747e3ec0 cbhs w0, w30, 0 <a>
> +.*: 74603ebe cbhs w30, w0, 0 <a>
> +
> +.* <b>:
> +.*: f4000000 cbgt x0, x0, 30 <b>
> +.*: f41e3fe0 cbgt x0, x30, 30 <b>
> +.*: f4003fde cbgt x30, x0, 30 <b>
> +.*: f4203fa0 cbge x0, x0, 30 <b>
> +.*: f43e3f80 cbge x0, x30, 30 <b>
> +.*: f4203f7e cbge x30, x0, 30 <b>
> +.*: f4403f40 cbhi x0, x0, 30 <b>
> +.*: f45e3f20 cbhi x0, x30, 30 <b>
> +.*: f4403f1e cbhi x30, x0, 30 <b>
> +.*: f4603ee0 cbhs x0, x0, 30 <b>
> +.*: f47e3ec0 cbhs x0, x30, 30 <b>
> +.*: f4603ebe cbhs x30, x0, 30 <b>
> +
> +.* <c>:
> +.*: 75000000 cbgt w0, #0, 60 <c>
> +.*: 7500bffe cbgt w30, #1, 60 <c>
> +.*: 75203fc0 cblt w0, #0, 60 <c>
> +.*: 75213fbe cblt w30, #2, 60 <c>
> +.*: 75403f80 cbhi w0, #0, 60 <c>
> +.*: 7541bf7e cbhi w30, #3, 60 <c>
> +.*: 75603f40 cblo w0, #0, 60 <c>
> +.*: 75623f3e cblo w30, #4, 60 <c>
> +.*: 75c03f00 cbeq w0, #0, 60 <c>
> +.*: 75c2befe cbeq w30, #5, 60 <c>
> +.*: 75e03ec0 cbne w0, #0, 60 <c>
> +.*: 75e33ebe cbne w30, #6, 60 <c>
> +
> +.* <d>:
> +.*: f5000000 cbgt x0, #0, 90 <d>
> +.*: f500bffe cbgt x30, #1, 90 <d>
> +.*: f5203fc0 cblt x0, #0, 90 <d>
> +.*: f5213fbe cblt x30, #2, 90 <d>
> +.*: f5403f80 cbhi x0, #0, 90 <d>
> +.*: f541bf7e cbhi x30, #3, 90 <d>
> +.*: f5603f40 cblo x0, #0, 90 <d>
> +.*: f5623f3e cblo x30, #4, 90 <d>
> +.*: f5c03f00 cbeq x0, #0, 90 <d>
> +.*: f5c2befe cbeq x30, #5, 90 <d>
> +.*: f5e03ec0 cbne x0, #0, 90 <d>
> +.*: f5e33ebe cbne x30, #6, 90 <d>
> +
> +.* <e>:
> +.*: 74008000 cbbgt w0, w0, c0 <e>
> +.*: 741ebfe0 cbbgt w0, w30, c0 <e>
> +.*: 7400bfde cbbgt w30, w0, c0 <e>
> +.*: 7420bfa0 cbbge w0, w0, c0 <e>
> +.*: 743ebf80 cbbge w0, w30, c0 <e>
> +.*: 7420bf7e cbbge w30, w0, c0 <e>
> +.*: 7440bf40 cbbhi w0, w0, c0 <e>
> +.*: 745ebf20 cbbhi w0, w30, c0 <e>
> +.*: 7440bf1e cbbhi w30, w0, c0 <e>
> +.*: 7460bee0 cbbhs w0, w0, c0 <e>
> +.*: 747ebec0 cbbhs w0, w30, c0 <e>
> +.*: 7460bebe cbbhs w30, w0, c0 <e>
> +.*: 74c0be80 cbbeq w0, w0, c0 <e>
> +.*: 74debe60 cbbeq w0, w30, c0 <e>
> +.*: 74c0be5e cbbeq w30, w0, c0 <e>
> +.*: 74e0be20 cbbne w0, w0, c0 <e>
> +.*: 74febe00 cbbne w0, w30, c0 <e>
> +.*: 74e0bdfe cbbne w30, w0, c0 <e>
> +
> +.* <f>:
> +.*: 74008000 cbbgt w0, w0, 108 <f>
> +.*: 741ebfe0 cbbgt w0, w30, 108 <f>
> +.*: 7400bfde cbbgt w30, w0, 108 <f>
> +.*: 7420bfa0 cbbge w0, w0, 108 <f>
> +.*: 743ebf80 cbbge w0, w30, 108 <f>
> +.*: 7420bf7e cbbge w30, w0, 108 <f>
> +.*: 7440bf40 cbbhi w0, w0, 108 <f>
> +.*: 745ebf20 cbbhi w0, w30, 108 <f>
> +.*: 7440bf1e cbbhi w30, w0, 108 <f>
> +.*: 7460bee0 cbbhs w0, w0, 108 <f>
> +.*: 747ebec0 cbbhs w0, w30, 108 <f>
> +.*: 7460bebe cbbhs w30, w0, 108 <f>
> +.*: 74c0be80 cbbeq w0, w0, 108 <f>
> +.*: 74debe60 cbbeq w0, w30, 108 <f>
> +.*: 74c0be5e cbbeq w30, w0, 108 <f>
> +.*: 74e0be20 cbbne w0, w0, 108 <f>
> +.*: 74febe00 cbbne w0, w30, 108 <f>
> +.*: 74e0bdfe cbbne w30, w0, 108 <f>
> diff --git a/gas/testsuite/gas/aarch64/cmpbr.s b/gas/testsuite/gas/aarch64/cmpbr.s
> new file mode 100644
> index 00000000000..b10b16792bf
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr.s
> @@ -0,0 +1,90 @@
> +a:
> + cbgt w0, w0, a
> + cbgt w0, w30, a
> + cbgt w30, w0, a
> + cbge w0, w0, a
> + cbge w0, w30, a
> + cbge w30, w0, a
> + cbhi w0, w0, a
> + cbhi w0, w30, a
> + cbhi w30, w0, a
> + cbhs w0, w0, a
> + cbhs w0, w30, a
> + cbhs w30, w0, a
> +b:
> + cbgt x0, x0, b
> + cbgt x0, x30, b
> + cbgt x30, x0, b
> + cbge x0, x0, b
> + cbge x0, x30, b
> + cbge x30, x0, b
> + cbhi x0, x0, b
> + cbhi x0, x30, b
> + cbhi x30, x0, b
> + cbhs x0, x0, b
> + cbhs x0, x30, b
> + cbhs x30, x0, b
> +c:
> + cbgt w0, #0, c
> + cbgt w30, #1, c
> + cblt w0, #0, c
> + cblt w30, #2, c
> + cbhi w0, #0, c
> + cbhi w30, #3, c
> + cblo w0, #0, c
> + cblo w30, #4, c
> + cbeq w0, #0, c
> + cbeq w30, #5, c
> + cbne w0, #0, c
> + cbne w30, #6, c
> +d:
> + cbgt x0, #0, d
> + cbgt x30, #1, d
> + cblt x0, #0, d
> + cblt x30, #2, d
> + cbhi x0, #0, d
> + cbhi x30, #3, d
> + cblo x0, #0, d
> + cblo x30, #4, d
> + cbeq x0, #0, d
> + cbeq x30, #5, d
> + cbne x0, #0, d
> + cbne x30, #6, d
> +e:
> + cbbgt w0, w0, e
> + cbbgt w0, w30, e
> + cbbgt w30, w0, e
> + cbbge w0, w0, e
> + cbbge w0, w30, e
> + cbbge w30, w0, e
> + cbbhi w0, w0, e
> + cbbhi w0, w30, e
> + cbbhi w30, w0, e
> + cbbhs w0, w0, e
> + cbbhs w0, w30, e
> + cbbhs w30, w0, e
> + cbbeq w0, w0, e
> + cbbeq w0, w30, e
> + cbbeq w30, w0, e
> + cbbne w0, w0, e
> + cbbne w0, w30, e
> + cbbne w30, w0, e
> +f:
> + cbbgt w0, w0, f
> + cbbgt w0, w30, f
> + cbbgt w30, w0, f
> + cbbge w0, w0, f
> + cbbge w0, w30, f
> + cbbge w30, w0, f
> + cbbhi w0, w0, f
> + cbbhi w0, w30, f
> + cbbhi w30, w0, f
> + cbbhs w0, w0, f
> + cbbhs w0, w30, f
> + cbbhs w30, w0, f
> + cbbeq w0, w0, f
> + cbbeq w0, w30, f
> + cbbeq w30, w0, f
> + cbbne w0, w0, f
> + cbbne w0, w30, f
> + cbbne w30, w0, f
A few remarks:
I'm not sure why you have both cmpbr.[sd] and cmpbr-1.[sd]. I'd expect two
different tests with the same base name to be labelled -1 and -2 instead (at
least if they were being added at the same time). However, in this case they
seem to be testing the same thing, so I don't see why it isn't just a single
test instead.
I think it's generally more effective to use wzr/xzr in tests instead of
w30/x30 (when used in combination with w0/x0 and no other values). This
verifies that we are using the correct choice of wzr or wsp, and xzr or sp, for
register 31, and ensures that we have a test where the least significant bit of
the register number is not zero.
I'd also like to see better coverage of the offset values - e.g. by ensuring
that we test offsets of both 0 and -1 (i.e. 0x0 and 0x1ff) for every entry in
the opcode table. You could achieve this by using a separate label for each
opcode table entry, so that the first offsets start again from 0 each time.
> diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
> index dfe3f05820a..0b124de59d7 100644
> --- a/include/opcode/aarch64.h
> +++ b/include/opcode/aarch64.h
> @@ -135,6 +135,8 @@ enum aarch64_feature_bit {
> AARCH64_FEATURE_ID_PFR2,
> /* SSBS mechanism enabled. */
> AARCH64_FEATURE_SSBS,
> + /* Compare and branch instructions. */
> + AARCH64_FEATURE_CMPBR,
> /* Memory Tagging Extension. */
> AARCH64_FEATURE_MEMTAG,
> /* Transactional Memory Extension. */
> @@ -618,6 +620,8 @@ enum aarch64_opnd
> AARCH64_OPND_WIDTH, /* Immediate #<width> in e.g. BFI. */
> AARCH64_OPND_IMM, /* Immediate. */
> AARCH64_OPND_IMM_2, /* Immediate. */
> + AARCH64_OPND_IMMP1_2, /* Immediate plus 1. */
> + AARCH64_OPND_IMMS1_2, /* Immediate minus 1. */
> AARCH64_OPND_UIMM3_OP1,/* Unsigned 3-bit immediate in the op1 field. */
> AARCH64_OPND_UIMM3_OP2,/* Unsigned 3-bit immediate in the op2 field. */
> AARCH64_OPND_UIMM4, /* Unsigned 4-bit immediate in the CRm field. */
> @@ -645,6 +649,7 @@ enum aarch64_opnd
> AARCH64_OPND_COND1, /* Same as the above, but excluding AL and NV. */
>
> AARCH64_OPND_ADDR_ADRP, /* Memory address for ADRP */
> + AARCH64_OPND_ADDR_PCREL9, /* 9-bit PC-relative address for e.g. CB<cc>. */
> AARCH64_OPND_ADDR_PCREL14, /* 14-bit PC-relative address for e.g. TBZ. */
> AARCH64_OPND_ADDR_PCREL19, /* 19-bit PC-relative address for e.g. LDR. */
> AARCH64_OPND_ADDR_PCREL21, /* 21-bit PC-relative address for e.g. ADR. */
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 4f0c71696fa..b93c7069ef6 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -381,6 +381,7 @@ const aarch64_field fields[] =
> { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
> { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
> { 12, 9 }, /* imm9: in load/store pre/post index instructions. */
> + { 5, 9 }, /* imm9_5: in CB<cc> (immediate). */
> { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
> { 5, 14 }, /* imm14: in test bit and branch instructions. */
> { 0, 16 }, /* imm16_0: in udf instruction. */
> @@ -2417,6 +2418,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
> }
> break;
>
> + case AARCH64_OPND_ADDR_PCREL9:
> case AARCH64_OPND_ADDR_PCREL14:
> case AARCH64_OPND_ADDR_PCREL19:
> case AARCH64_OPND_ADDR_PCREL21:
> @@ -4781,6 +4783,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
> snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr));
> break;
>
> + case AARCH64_OPND_ADDR_PCREL9:
> case AARCH64_OPND_ADDR_PCREL14:
> case AARCH64_OPND_ADDR_PCREL19:
> case AARCH64_OPND_ADDR_PCREL21:
> diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
> index 9ab9bdf5123..3086f0285d8 100644
> --- a/opcodes/aarch64-opc.h
> +++ b/opcodes/aarch64-opc.h
> @@ -185,6 +185,7 @@ enum aarch64_field_kind
> FLD_imm7,
> FLD_imm8,
> FLD_imm9,
> + FLD_imm9_5,
> FLD_imm12,
> FLD_imm14,
> FLD_imm16_0,
> diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
> index 8b64eb07067..4f22f3491e5 100644
> --- a/opcodes/aarch64-tbl.h
> +++ b/opcodes/aarch64-tbl.h
> @@ -136,6 +136,19 @@
> QLF2(X,NIL), \
> }
>
> +/* e.g. CBBGT <Wt>, <Wm>, <label>. */
> +#define QL_W2NIL \
> +{ \
> + QLF3(W,W,NIL), \
> +}
> +
> +/* e.g. CBGT <Wt>, #<imm6>, <label>. */
> +#define QL_R_IMM_NIL \
> +{ \
> + QLF3(W,imm_0_63,NIL), \
> + QLF3(X,imm_0_63,NIL), \
> +}
> +
> /* e.g. LDR <Dt>, <label>. */
> #define QL_FP_PCREL \
> { \
> @@ -2737,6 +2750,8 @@ static const aarch64_feature_set aarch64_feature_predres =
> AARCH64_FEATURE (PREDRES);
> static const aarch64_feature_set aarch64_feature_predres2 =
> AARCH64_FEATURES (2, PREDRES, PREDRES2);
> +static const aarch64_feature_set aarch64_feature_cmpbr =
> + AARCH64_FEATURE (CMPBR);
> static const aarch64_feature_set aarch64_feature_memtag =
> AARCH64_FEATURE (MEMTAG);
> static const aarch64_feature_set aarch64_feature_bfloat16 =
> @@ -2897,6 +2912,7 @@ static const aarch64_feature_set aarch64_feature_sve2p1_sme2p1 =
> #define SB &aarch64_feature_sb
> #define PREDRES &aarch64_feature_predres
> #define PREDRES2 &aarch64_feature_predres2
> +#define CMPBR &aarch64_feature_cmpbr
> #define MEMTAG &aarch64_feature_memtag
> #define TME &aarch64_feature_tme
> #define SVE2 &aarch64_feature_sve2
> @@ -3022,6 +3038,8 @@ static const aarch64_feature_set aarch64_feature_sve2p1_sme2p1 =
> { NAME, OPCODE, MASK, CLASS, 0, SB, OPS, QUALS, FLAGS, 0, 0, NULL }
> #define PREDRES_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> { NAME, OPCODE, MASK, CLASS, 0, PREDRES, OPS, QUALS, FLAGS, 0, 0, NULL }
> +#define CMPBR_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> + { NAME, OPCODE, MASK, CLASS, 0, CMPBR, OPS, QUALS, FLAGS, 0, 0, NULL }
> #define MEMTAG_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> { NAME, OPCODE, MASK, CLASS, 0, MEMTAG, OPS, QUALS, FLAGS, 0, 0, NULL }
> #define _TME_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
> @@ -3965,6 +3983,50 @@ const struct aarch64_opcode aarch64_opcode_table[] =
> CORE_INSN ("cbnz", 0x35000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
> /* Conditional branch (immediate). */
> CORE_INSN ("b.c", 0x54000000, 0xff000010, condbranch, 0, OP1 (ADDR_PCREL19), QL_PCREL_NIL, F_COND),
> + /* Compare registers and branch. */
> + CMPBR_INSN ("cbgt", 0x74000000, 0x7fe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_R2NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cblt", 0x74000000, 0x7fe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_R2NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbge", 0x74200000, 0x7fe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_R2NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cble", 0x74200000, 0x7fe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_R2NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbhi", 0x74400000, 0x7fe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_R2NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cblo", 0x74400000, 0x7fe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_R2NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbhs", 0x74600000, 0x7fe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_R2NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cbls", 0x74600000, 0x7fe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_R2NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbeq", 0x74c00000, 0x7fe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_R2NIL, F_SF),
> + CMPBR_INSN ("cbne", 0x74e00000, 0x7fe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_R2NIL, F_SF),
> + /* Compare register with immediate and branch. */
> + CMPBR_INSN ("cbgt", 0x75000000, 0x7fe04000, compbranch, OP3 (Rt, IMM_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cbge", 0x75000000, 0x7fe04000, compbranch, OP3 (Rt, IMMP1_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cblt", 0x75200000, 0x7fe04000, compbranch, OP3 (Rt, IMM_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cble", 0x75200000, 0x7fe04000, compbranch, OP3 (Rt, IMMS1_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbhi", 0x75400000, 0x7fe04000, compbranch, OP3 (Rt, IMM_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cbhs", 0x75400000, 0x7fe04000, compbranch, OP3 (Rt, IMMP1_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cblo", 0x75600000, 0x7fe04000, compbranch, OP3 (Rt, IMM_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_HAS_ALIAS),
> + CMPBR_INSN ("cbls", 0x75600000, 0x7fe04000, compbranch, OP3 (Rt, IMMS1_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF | F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbeq", 0x75c00000, 0x7fe04000, compbranch, OP3 (Rt, IMM_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF),
> + CMPBR_INSN ("cbne", 0x75e00000, 0x7fe04000, compbranch, OP3 (Rt, IMM_2, ADDR_PCREL9), QL_R_IMM_NIL, F_SF),
> + /* Compare bytes and branch. */
> + CMPBR_INSN ("cbbgt", 0x74008000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbblt", 0x74008000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbbge", 0x74208000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbble", 0x74208000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbbhi", 0x74408000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbblo", 0x74408000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbbhs", 0x74608000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbbls", 0x74608000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbbeq", 0x74c08000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, 0),
> + CMPBR_INSN ("cbbne", 0x74e08000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, 0),
> + /* Compare halfwords and branch. */
> + CMPBR_INSN ("cbhgt", 0x7400c000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbhlt", 0x7400c000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbhge", 0x7420c000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbhle", 0x7420c000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbhhi", 0x7440c000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbhlo", 0x7440c000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbhhs", 0x7460c000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, F_HAS_ALIAS),
> + CMPBR_INSN ("cbhls", 0x7460c000, 0xffe0c000, compbranch, OP3 (Rm, Rt, ADDR_PCREL9), QL_W2NIL, F_ALIAS | F_PSEUDO),
> + CMPBR_INSN ("cbheq", 0x74c0c000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, 0),
> + CMPBR_INSN ("cbhne", 0x74e0c000, 0xffe0c000, compbranch, OP3 (Rt, Rm, ADDR_PCREL9), QL_W2NIL, 0),
> /* Conditional compare (immediate). */
> CORE_INSN ("ccmn", 0x3a400800, 0x7fe00c10, condcmp_imm, 0, OP4 (Rn, CCMP_IMM, NZCV, COND), QL_CCMP_IMM, F_SF),
> CORE_INSN ("ccmp", 0x7a400800, 0x7fe00c10, condcmp_imm, 0, OP4 (Rn, CCMP_IMM, NZCV, COND), QL_CCMP_IMM, F_SF),
> @@ -7126,6 +7188,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
> "the width of the bit-field") \
> Y(IMMEDIATE, imm, "IMM", 0, F(FLD_imm6_10), "an immediate") \
> Y(IMMEDIATE, imm, "IMM_2", 0, F(FLD_imm6_15), "an immediate") \
> + Y(IMMEDIATE, imm, "IMMP1_2", 0, F(FLD_imm6_15), "an immediate plus 1") \
> + Y(IMMEDIATE, imm, "IMMS1_2", 0, F(FLD_imm6_15), "an immediate minus 1") \
> Y(IMMEDIATE, imm, "UIMM3_OP1", 0, F(FLD_op1), \
> "a 3-bit unsigned immediate") \
> Y(IMMEDIATE, imm, "UIMM3_OP2", 0, F(FLD_op2), \
> @@ -7170,6 +7234,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
> "one of the standard conditions, excluding AL and NV.") \
> X(ADDRESS, 0, ext_imm, "ADDR_ADRP", OPD_F_SEXT, F(FLD_immhi, FLD_immlo),\
> "21-bit PC-relative address of a 4KB page") \
> + Y(ADDRESS, imm, "ADDR_PCREL9", OPD_F_SEXT | OPD_F_SHIFT_BY_2, \
> + F(FLD_imm9_5), "9-bit PC-relative address") \
> Y(ADDRESS, imm, "ADDR_PCREL14", OPD_F_SEXT | OPD_F_SHIFT_BY_2, \
> F(FLD_imm14), "14-bit PC-relative address") \
> Y(ADDRESS, imm, "ADDR_PCREL19", OPD_F_SEXT | OPD_F_SHIFT_BY_2, \
> --
> 2.45.2
More information about the Binutils
mailing list