[PATCH v4] [binutils] aarch64: Support for FEAT_CMPBR

Alice Carlotti alice.carlotti@arm.com
Thu May 8 14:42:16 GMT 2025


On Thu, May 08, 2025 at 02:05:22PM +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
> ---
> I've addressed the comments from v3. 
> 
> > 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.
> 
> cmpbr.[sd] is for the main instructions, while cmpbr-1.[sd] is for the
> pseudo instructions, checking that it dissasembles into the main
> instruction mnemonic. I've changed the name of the file of -1 into -pseudo but
> let me know if you think having one test file is better.

Ah, I see - the new names make this much clearer, thanks.  Either one or two
test files is fine; however, see my comment on that test below.

> > 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.
> 
> I've made these changes.
> 
> 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-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        |  13 +
>  gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.d |   4 +
>  gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.l |   3 +
>  gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.s |   3 +
>  gas/testsuite/gas/aarch64/cmpbr-pseudo.d     |  67 +++
>  gas/testsuite/gas/aarch64/cmpbr-pseudo.s     |  59 ++
>  gas/testsuite/gas/aarch64/cmpbr.d            | 583 +++++++++++++++++++
>  gas/testsuite/gas/aarch64/cmpbr.s            | 435 ++++++++++++++
>  include/opcode/aarch64.h                     |   5 +
>  opcodes/aarch64-opc.c                        |   3 +
>  opcodes/aarch64-opc.h                        |   1 +
>  opcodes/aarch64-tbl.h                        |  66 +++
>  21 files changed, 1322 insertions(+), 2 deletions(-)
>  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-pseudo-bad.d
>  create mode 100644 gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.l
>  create mode 100644 gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.s
>  create mode 100644 gas/testsuite/gas/aarch64/cmpbr-pseudo.d
>  create mode 100644 gas/testsuite/gas/aarch64/cmpbr-pseudo.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-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
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-far.s b/gas/testsuite/gas/aarch64/cmpbr-far.s
> new file mode 100644
> index 00000000000..927d4229a60
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-far.s
> @@ -0,0 +1,13 @@
> +a:
> +	.rept 257
> +	nop
> +	.endr
> +	cbgt w0, w1, a
> +
> +	cbgt w0, w1, b
> +	.rept 255
> +	nop
> +	.endr
> +
> +b:
> +	nop
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.d b/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.d
> new file mode 100644
> index 00000000000..444b554a8d9
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.d
> @@ -0,0 +1,4 @@
> +#name: Test of out-of-range cmpbr operands
> +#source: cmpbr-pseudo-bad.s
> +#as: -march=armv8-a+cmpbr
> +#error_output: cmpbr-pseudo-bad.l
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.l b/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.l
> new file mode 100644
> index 00000000000..3839baf9772
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.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-pseudo-bad.s b/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.s
> new file mode 100644
> index 00000000000..1fd0c3a3909
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-pseudo-bad.s
> @@ -0,0 +1,3 @@
> +a:
> +	cbge	w0, #0, a
> +	cble	w0, #63, a
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-pseudo.d b/gas/testsuite/gas/aarch64/cmpbr-pseudo.d
> new file mode 100644
> index 00000000000..bdd2c3cbf33
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-pseudo.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>:
> +.*:	741f0000 	cbgt	w0, wzr, 0 <a>
> +.*:	741f3fe0 	cbgt	w0, wzr, 0 <a>
> +.*:	743f3fc0 	cbge	w0, wzr, 0 <a>
> +.*:	743f3fa0 	cbge	w0, wzr, 0 <a>
> +.*:	745f3f80 	cbhi	w0, wzr, 0 <a>
> +.*:	745f3f60 	cbhi	w0, wzr, 0 <a>
> +.*:	747f3f40 	cbhs	w0, wzr, 0 <a>
> +.*:	747f3f20 	cbhs	w0, wzr, 0 <a>
> +
> +.* <b>:
> +.*:	f41f0000 	cbgt	x0, xzr, 20 <b>
> +.*:	f41f3fe0 	cbgt	x0, xzr, 20 <b>
> +.*:	f43f3fc0 	cbge	x0, xzr, 20 <b>
> +.*:	f43f3fa0 	cbge	x0, xzr, 20 <b>
> +.*:	f45f3f80 	cbhi	x0, xzr, 20 <b>
> +.*:	f45f3f60 	cbhi	x0, xzr, 20 <b>
> +.*:	f47f3f40 	cbhs	x0, xzr, 20 <b>
> +.*:	f47f3f20 	cbhs	x0, xzr, 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>
> +.*:	f5663f5f 	cblo	xzr, #12, 60 <d>
> +.*:	f5663f3f 	cblo	xzr, #12, 60 <d>
> +
> +.* <e>:
> +.*:	741f8000 	cbbgt	w0, wzr, 80 <e>
> +.*:	741fbfe0 	cbbgt	w0, wzr, 80 <e>
> +.*:	743fbfc0 	cbbge	w0, wzr, 80 <e>
> +.*:	743fbfa0 	cbbge	w0, wzr, 80 <e>
> +.*:	745fbf80 	cbbhi	w0, wzr, 80 <e>
> +.*:	745fbf60 	cbbhi	w0, wzr, 80 <e>
> +.*:	747fbf40 	cbbhs	w0, wzr, 80 <e>
> +.*:	747fbf20 	cbbhs	w0, wzr, 80 <e>
> +
> +.* <f>:
> +.*:	741fc000 	cbhgt	w0, wzr, a0 <f>
> +.*:	741fffe0 	cbhgt	w0, wzr, a0 <f>
> +.*:	743fffc0 	cbhge	w0, wzr, a0 <f>
> +.*:	743fffa0 	cbhge	w0, wzr, a0 <f>
> +.*:	745fff80 	cbhhi	w0, wzr, a0 <f>
> +.*:	745fff60 	cbhhi	w0, wzr, a0 <f>
> +.*:	747fff40 	cbhhs	w0, wzr, a0 <f>
> +.*:	747fff20 	cbhhs	w0, wzr, a0 <f>
> diff --git a/gas/testsuite/gas/aarch64/cmpbr-pseudo.s b/gas/testsuite/gas/aarch64/cmpbr-pseudo.s
> new file mode 100644
> index 00000000000..fb8dbc7f16e
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr-pseudo.s
> @@ -0,0 +1,59 @@

The aliases in Binutils are generally defined independently of the instructions
they are aliasing, so they usually need to be tested as thoroughly as the
aliased instructions for assembly purposes.  (This is part of the reason that
I'd tend to test aliases in the same test file as the aliased instruction.)

> +a:
> +	cbgt	w0, wzr, a
> +	cblt	wzr, w0, a
> +	cbge	w0, wzr, a
> +	cble	wzr, w0, a
> +	cbhi	w0, wzr, a
> +	cblo	wzr, w0, a
> +	cbhs	w0, wzr, a
> +	cbls	wzr, w0, a
> +
> +b:
> +	cbgt	x0, xzr, b
> +	cblt	xzr, x0, b
> +	cbge	x0, xzr, b
> +	cble	xzr, x0, b
> +	cbhi	x0, xzr, b
> +	cblo	xzr, x0, b
> +	cbhs	x0, xzr, b
> +	cbls	xzr, 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	xzr, #12, d
> +	cbls	xzr, #11, d
> +
> +e:
> +	cbbgt	w0, wzr, e
> +	cbblt	wzr, w0, e
> +	cbbge	w0, wzr, e
> +	cbble	wzr, w0, e
> +	cbbhi	w0, wzr, e
> +	cbblo	wzr, w0, e
> +	cbbhs	w0, wzr, e
> +	cbbls	wzr, w0, e
> +
> +f:
> +	cbhgt	w0, wzr, f
> +	cbhlt	wzr, w0, f
> +	cbhge	w0, wzr, f
> +	cbhle	wzr, w0, f
> +	cbhhi	w0, wzr, f
> +	cbhlo	wzr, w0, f
> +	cbhhs	w0, wzr, f
> +	cbhls	wzr, w0, f
> diff --git a/gas/testsuite/gas/aarch64/cmpbr.d b/gas/testsuite/gas/aarch64/cmpbr.d
> new file mode 100644
> index 00000000000..0868a232e6d
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr.d
> @@ -0,0 +1,583 @@
> +#name: Test for FEAT_CMPBR
> +#as: -march=armv8-a+cmpbr
> +#objdump: -dr
> +
> +.*:     file format .*
> +
> +Disassembly of section .text:
> +
> +.* <cbgt_0>:
> +.*:	75000000 	cbgt	w0, #0, 0 <cbgt_0>
> +.*:	75003fe0 	cbgt	w0, #0, 0 <cbgt_0>
> +
> +.* <cbgt_1>:
> +.*:	751f8000 	cbgt	w0, #63, 8 <cbgt_1>
> +.*:	751fbfe0 	cbgt	w0, #63, 8 <cbgt_1>
> +
> +.* <cbgt_2>:
> +.*:	7500001f 	cbgt	wzr, #0, 10 <cbgt_2>
> +.*:	75003fff 	cbgt	wzr, #0, 10 <cbgt_2>
> +
> +.* <cbgt_3>:
> +.*:	751f801f 	cbgt	wzr, #63, 18 <cbgt_3>
> +.*:	751fbfff 	cbgt	wzr, #63, 18 <cbgt_3>
> +
> +.* <cbgt_4>:
> +.*:	f5000000 	cbgt	x0, #0, 20 <cbgt_4>
> +.*:	f5003fe0 	cbgt	x0, #0, 20 <cbgt_4>
> +
> +.* <cbgt_5>:
> +.*:	f51f8000 	cbgt	x0, #63, 28 <cbgt_5>
> +.*:	f51fbfe0 	cbgt	x0, #63, 28 <cbgt_5>
> +
> +.* <cbgt_6>:
> +.*:	f500001f 	cbgt	xzr, #0, 30 <cbgt_6>
> +.*:	f5003fff 	cbgt	xzr, #0, 30 <cbgt_6>
> +
> +.* <cbgt_7>:
> +.*:	f51f801f 	cbgt	xzr, #63, 38 <cbgt_7>
> +.*:	f51fbfff 	cbgt	xzr, #63, 38 <cbgt_7>
> +
> +.* <cblt_0>:
> +.*:	75200000 	cblt	w0, #0, 40 <cblt_0>
> +.*:	75203fe0 	cblt	w0, #0, 40 <cblt_0>
> +
> +.* <cblt_1>:
> +.*:	753f8000 	cblt	w0, #63, 48 <cblt_1>
> +.*:	753fbfe0 	cblt	w0, #63, 48 <cblt_1>
> +
> +.* <cblt_2>:
> +.*:	7520001f 	cblt	wzr, #0, 50 <cblt_2>
> +.*:	75203fff 	cblt	wzr, #0, 50 <cblt_2>
> +
> +.* <cblt_3>:
> +.*:	753f801f 	cblt	wzr, #63, 58 <cblt_3>
> +.*:	753fbfff 	cblt	wzr, #63, 58 <cblt_3>
> +
> +.* <cblt_4>:
> +.*:	f5200000 	cblt	x0, #0, 60 <cblt_4>
> +.*:	f5203fe0 	cblt	x0, #0, 60 <cblt_4>
> +
> +.* <cblt_5>:
> +.*:	f53f8000 	cblt	x0, #63, 68 <cblt_5>
> +.*:	f53fbfe0 	cblt	x0, #63, 68 <cblt_5>
> +
> +.* <cblt_6>:
> +.*:	f520001f 	cblt	xzr, #0, 70 <cblt_6>
> +.*:	f5203fff 	cblt	xzr, #0, 70 <cblt_6>
> +
> +.* <cblt_7>:
> +.*:	f53f801f 	cblt	xzr, #63, 78 <cblt_7>
> +.*:	f53fbfff 	cblt	xzr, #63, 78 <cblt_7>
> +
> +.* <cbhi_0>:
> +.*:	75400000 	cbhi	w0, #0, 80 <cbhi_0>
> +.*:	75403fe0 	cbhi	w0, #0, 80 <cbhi_0>
> +
> +.* <cbhi_1>:
> +.*:	755f8000 	cbhi	w0, #63, 88 <cbhi_1>
> +.*:	755fbfe0 	cbhi	w0, #63, 88 <cbhi_1>
> +
> +.* <cbhi_2>:
> +.*:	7540001f 	cbhi	wzr, #0, 90 <cbhi_2>
> +.*:	75403fff 	cbhi	wzr, #0, 90 <cbhi_2>
> +
> +.* <cbhi_3>:
> +.*:	755f801f 	cbhi	wzr, #63, 98 <cbhi_3>
> +.*:	755fbfff 	cbhi	wzr, #63, 98 <cbhi_3>
> +
> +.* <cbhi_4>:
> +.*:	f5400000 	cbhi	x0, #0, a0 <cbhi_4>
> +.*:	f5403fe0 	cbhi	x0, #0, a0 <cbhi_4>
> +
> +.* <cbhi_5>:
> +.*:	f55f8000 	cbhi	x0, #63, a8 <cbhi_5>
> +.*:	f55fbfe0 	cbhi	x0, #63, a8 <cbhi_5>
> +
> +.* <cbhi_6>:
> +.*:	f540001f 	cbhi	xzr, #0, b0 <cbhi_6>
> +.*:	f5403fff 	cbhi	xzr, #0, b0 <cbhi_6>
> +
> +.* <cbhi_7>:
> +.*:	f55f801f 	cbhi	xzr, #63, b8 <cbhi_7>
> +.*:	f55fbfff 	cbhi	xzr, #63, b8 <cbhi_7>
> +
> +.* <cblo_0>:
> +.*:	75600000 	cblo	w0, #0, c0 <cblo_0>
> +.*:	75603fe0 	cblo	w0, #0, c0 <cblo_0>
> +
> +.* <cblo_1>:
> +.*:	757f8000 	cblo	w0, #63, c8 <cblo_1>
> +.*:	757fbfe0 	cblo	w0, #63, c8 <cblo_1>
> +
> +.* <cblo_2>:
> +.*:	7560001f 	cblo	wzr, #0, d0 <cblo_2>
> +.*:	75603fff 	cblo	wzr, #0, d0 <cblo_2>
> +
> +.* <cblo_3>:
> +.*:	757f801f 	cblo	wzr, #63, d8 <cblo_3>
> +.*:	757fbfff 	cblo	wzr, #63, d8 <cblo_3>
> +
> +.* <cblo_4>:
> +.*:	f5600000 	cblo	x0, #0, e0 <cblo_4>
> +.*:	f5603fe0 	cblo	x0, #0, e0 <cblo_4>
> +
> +.* <cblo_5>:
> +.*:	f57f8000 	cblo	x0, #63, e8 <cblo_5>
> +.*:	f57fbfe0 	cblo	x0, #63, e8 <cblo_5>
> +
> +.* <cblo_6>:
> +.*:	f560001f 	cblo	xzr, #0, f0 <cblo_6>
> +.*:	f5603fff 	cblo	xzr, #0, f0 <cblo_6>
> +
> +.* <cblo_7>:
> +.*:	f57f801f 	cblo	xzr, #63, f8 <cblo_7>
> +.*:	f57fbfff 	cblo	xzr, #63, f8 <cblo_7>
> +
> +.* <cbeq_0>:
> +.*:	75c00000 	cbeq	w0, #0, 100 <cbeq_0>
> +.*:	75c03fe0 	cbeq	w0, #0, 100 <cbeq_0>
> +
> +.* <cbeq_1>:
> +.*:	75df8000 	cbeq	w0, #63, 108 <cbeq_1>
> +.*:	75dfbfe0 	cbeq	w0, #63, 108 <cbeq_1>
> +
> +.* <cbeq_2>:
> +.*:	75c0001f 	cbeq	wzr, #0, 110 <cbeq_2>
> +.*:	75c03fff 	cbeq	wzr, #0, 110 <cbeq_2>
> +
> +.* <cbeq_3>:
> +.*:	75df801f 	cbeq	wzr, #63, 118 <cbeq_3>
> +.*:	75dfbfff 	cbeq	wzr, #63, 118 <cbeq_3>
> +
> +.* <cbeq_4>:
> +.*:	f5c00000 	cbeq	x0, #0, 120 <cbeq_4>
> +.*:	f5c03fe0 	cbeq	x0, #0, 120 <cbeq_4>
> +
> +.* <cbeq_5>:
> +.*:	f5df8000 	cbeq	x0, #63, 128 <cbeq_5>
> +.*:	f5dfbfe0 	cbeq	x0, #63, 128 <cbeq_5>
> +
> +.* <cbeq_6>:
> +.*:	f5c0001f 	cbeq	xzr, #0, 130 <cbeq_6>
> +.*:	f5c03fff 	cbeq	xzr, #0, 130 <cbeq_6>
> +
> +.* <cbeq_7>:
> +.*:	f5df801f 	cbeq	xzr, #63, 138 <cbeq_7>
> +.*:	f5dfbfff 	cbeq	xzr, #63, 138 <cbeq_7>
> +
> +.* <cbne_0>:
> +.*:	75e00000 	cbne	w0, #0, 140 <cbne_0>
> +.*:	75e03fe0 	cbne	w0, #0, 140 <cbne_0>
> +
> +.* <cbne_1>:
> +.*:	75ff8000 	cbne	w0, #63, 148 <cbne_1>
> +.*:	75ffbfe0 	cbne	w0, #63, 148 <cbne_1>
> +
> +.* <cbne_2>:
> +.*:	75e0001f 	cbne	wzr, #0, 150 <cbne_2>
> +.*:	75e03fff 	cbne	wzr, #0, 150 <cbne_2>
> +
> +.* <cbne_3>:
> +.*:	75ff801f 	cbne	wzr, #63, 158 <cbne_3>
> +.*:	75ffbfff 	cbne	wzr, #63, 158 <cbne_3>
> +
> +.* <cbne_4>:
> +.*:	f5e00000 	cbne	x0, #0, 160 <cbne_4>
> +.*:	f5e03fe0 	cbne	x0, #0, 160 <cbne_4>
> +
> +.* <cbne_5>:
> +.*:	f5ff8000 	cbne	x0, #63, 168 <cbne_5>
> +.*:	f5ffbfe0 	cbne	x0, #63, 168 <cbne_5>
> +
> +.* <cbne_6>:
> +.*:	f5e0001f 	cbne	xzr, #0, 170 <cbne_6>
> +.*:	f5e03fff 	cbne	xzr, #0, 170 <cbne_6>
> +
> +.* <cbne_7>:
> +.*:	f5ff801f 	cbne	xzr, #63, 178 <cbne_7>
> +.*:	f5ffbfff 	cbne	xzr, #63, 178 <cbne_7>
> +
> +.* <cbgt_8>:
> +.*:	74000000 	cbgt	w0, w0, 180 <cbgt_8>
> +.*:	74003fe0 	cbgt	w0, w0, 180 <cbgt_8>
> +
> +.* <cbgt_9>:
> +.*:	741f0000 	cbgt	w0, wzr, 188 <cbgt_9>
> +.*:	741f3fe0 	cbgt	w0, wzr, 188 <cbgt_9>
> +
> +.* <cbgt_10>:
> +.*:	7400001f 	cbgt	wzr, w0, 190 <cbgt_10>
> +.*:	74003fff 	cbgt	wzr, w0, 190 <cbgt_10>
> +
> +.* <cbgt_11>:
> +.*:	741f001f 	cbgt	wzr, wzr, 198 <cbgt_11>
> +.*:	741f3fff 	cbgt	wzr, wzr, 198 <cbgt_11>
> +
> +.* <cbgt_12>:
> +.*:	f4000000 	cbgt	x0, x0, 1a0 <cbgt_12>
> +.*:	f4003fe0 	cbgt	x0, x0, 1a0 <cbgt_12>
> +
> +.* <cbgt_13>:
> +.*:	f41f0000 	cbgt	x0, xzr, 1a8 <cbgt_13>
> +.*:	f41f3fe0 	cbgt	x0, xzr, 1a8 <cbgt_13>
> +
> +.* <cbgt_14>:
> +.*:	f400001f 	cbgt	xzr, x0, 1b0 <cbgt_14>
> +.*:	f4003fff 	cbgt	xzr, x0, 1b0 <cbgt_14>
> +
> +.* <cbgt_15>:
> +.*:	f41f001f 	cbgt	xzr, xzr, 1b8 <cbgt_15>
> +.*:	f41f3fff 	cbgt	xzr, xzr, 1b8 <cbgt_15>
> +
> +.* <cbge_8>:
> +.*:	74200000 	cbge	w0, w0, 1c0 <cbge_8>
> +.*:	74203fe0 	cbge	w0, w0, 1c0 <cbge_8>
> +
> +.* <cbge_9>:
> +.*:	743f0000 	cbge	w0, wzr, 1c8 <cbge_9>
> +.*:	743f3fe0 	cbge	w0, wzr, 1c8 <cbge_9>
> +
> +.* <cbge_10>:
> +.*:	7420001f 	cbge	wzr, w0, 1d0 <cbge_10>
> +.*:	74203fff 	cbge	wzr, w0, 1d0 <cbge_10>
> +
> +.* <cbge_11>:
> +.*:	743f001f 	cbge	wzr, wzr, 1d8 <cbge_11>
> +.*:	743f3fff 	cbge	wzr, wzr, 1d8 <cbge_11>
> +
> +.* <cbge_12>:
> +.*:	f4200000 	cbge	x0, x0, 1e0 <cbge_12>
> +.*:	f4203fe0 	cbge	x0, x0, 1e0 <cbge_12>
> +
> +.* <cbge_13>:
> +.*:	f43f0000 	cbge	x0, xzr, 1e8 <cbge_13>
> +.*:	f43f3fe0 	cbge	x0, xzr, 1e8 <cbge_13>
> +
> +.* <cbge_14>:
> +.*:	f420001f 	cbge	xzr, x0, 1f0 <cbge_14>
> +.*:	f4203fff 	cbge	xzr, x0, 1f0 <cbge_14>
> +
> +.* <cbge_15>:
> +.*:	f43f001f 	cbge	xzr, xzr, 1f8 <cbge_15>
> +.*:	f43f3fff 	cbge	xzr, xzr, 1f8 <cbge_15>
> +
> +.* <cbhi_8>:
> +.*:	74400000 	cbhi	w0, w0, 200 <cbhi_8>
> +.*:	74403fe0 	cbhi	w0, w0, 200 <cbhi_8>
> +
> +.* <cbhi_9>:
> +.*:	745f0000 	cbhi	w0, wzr, 208 <cbhi_9>
> +.*:	745f3fe0 	cbhi	w0, wzr, 208 <cbhi_9>
> +
> +.* <cbhi_10>:
> +.*:	7440001f 	cbhi	wzr, w0, 210 <cbhi_10>
> +.*:	74403fff 	cbhi	wzr, w0, 210 <cbhi_10>
> +
> +.* <cbhi_11>:
> +.*:	745f001f 	cbhi	wzr, wzr, 218 <cbhi_11>
> +.*:	745f3fff 	cbhi	wzr, wzr, 218 <cbhi_11>
> +
> +.* <cbhi_12>:
> +.*:	f4400000 	cbhi	x0, x0, 220 <cbhi_12>
> +.*:	f4403fe0 	cbhi	x0, x0, 220 <cbhi_12>
> +
> +.* <cbhi_13>:
> +.*:	f45f0000 	cbhi	x0, xzr, 228 <cbhi_13>
> +.*:	f45f3fe0 	cbhi	x0, xzr, 228 <cbhi_13>
> +
> +.* <cbhi_14>:
> +.*:	f440001f 	cbhi	xzr, x0, 230 <cbhi_14>
> +.*:	f4403fff 	cbhi	xzr, x0, 230 <cbhi_14>
> +
> +.* <cbhi_15>:
> +.*:	f45f001f 	cbhi	xzr, xzr, 238 <cbhi_15>
> +.*:	f45f3fff 	cbhi	xzr, xzr, 238 <cbhi_15>
> +
> +.* <cbhs_8>:
> +.*:	74600000 	cbhs	w0, w0, 240 <cbhs_8>
> +.*:	74603fe0 	cbhs	w0, w0, 240 <cbhs_8>
> +
> +.* <cbhs_9>:
> +.*:	747f0000 	cbhs	w0, wzr, 248 <cbhs_9>
> +.*:	747f3fe0 	cbhs	w0, wzr, 248 <cbhs_9>
> +
> +.* <cbhs_10>:
> +.*:	7460001f 	cbhs	wzr, w0, 250 <cbhs_10>
> +.*:	74603fff 	cbhs	wzr, w0, 250 <cbhs_10>
> +
> +.* <cbhs_11>:
> +.*:	747f001f 	cbhs	wzr, wzr, 258 <cbhs_11>
> +.*:	747f3fff 	cbhs	wzr, wzr, 258 <cbhs_11>
> +
> +.* <cbhs_12>:
> +.*:	f4600000 	cbhs	x0, x0, 260 <cbhs_12>
> +.*:	f4603fe0 	cbhs	x0, x0, 260 <cbhs_12>
> +
> +.* <cbhs_13>:
> +.*:	f47f0000 	cbhs	x0, xzr, 268 <cbhs_13>
> +.*:	f47f3fe0 	cbhs	x0, xzr, 268 <cbhs_13>
> +
> +.* <cbhs_14>:
> +.*:	f460001f 	cbhs	xzr, x0, 270 <cbhs_14>
> +.*:	f4603fff 	cbhs	xzr, x0, 270 <cbhs_14>
> +
> +.* <cbhs_15>:
> +.*:	f47f001f 	cbhs	xzr, xzr, 278 <cbhs_15>
> +.*:	f47f3fff 	cbhs	xzr, xzr, 278 <cbhs_15>
> +
> +.* <cbeq_8>:
> +.*:	74c00000 	cbeq	w0, w0, 280 <cbeq_8>
> +.*:	74c03fe0 	cbeq	w0, w0, 280 <cbeq_8>
> +
> +.* <cbeq_9>:
> +.*:	74df0000 	cbeq	w0, wzr, 288 <cbeq_9>
> +.*:	74df3fe0 	cbeq	w0, wzr, 288 <cbeq_9>
> +
> +.* <cbeq_10>:
> +.*:	74c0001f 	cbeq	wzr, w0, 290 <cbeq_10>
> +.*:	74c03fff 	cbeq	wzr, w0, 290 <cbeq_10>
> +
> +.* <cbeq_11>:
> +.*:	74df001f 	cbeq	wzr, wzr, 298 <cbeq_11>
> +.*:	74df3fff 	cbeq	wzr, wzr, 298 <cbeq_11>
> +
> +.* <cbeq_12>:
> +.*:	f4c00000 	cbeq	x0, x0, 2a0 <cbeq_12>
> +.*:	f4c03fe0 	cbeq	x0, x0, 2a0 <cbeq_12>
> +
> +.* <cbeq_13>:
> +.*:	f4df0000 	cbeq	x0, xzr, 2a8 <cbeq_13>
> +.*:	f4df3fe0 	cbeq	x0, xzr, 2a8 <cbeq_13>
> +
> +.* <cbeq_14>:
> +.*:	f4c0001f 	cbeq	xzr, x0, 2b0 <cbeq_14>
> +.*:	f4c03fff 	cbeq	xzr, x0, 2b0 <cbeq_14>
> +
> +.* <cbeq_15>:
> +.*:	f4df001f 	cbeq	xzr, xzr, 2b8 <cbeq_15>
> +.*:	f4df3fff 	cbeq	xzr, xzr, 2b8 <cbeq_15>
> +
> +.* <cbne_8>:
> +.*:	74e00000 	cbne	w0, w0, 2c0 <cbne_8>
> +.*:	74e03fe0 	cbne	w0, w0, 2c0 <cbne_8>
> +
> +.* <cbne_9>:
> +.*:	74ff0000 	cbne	w0, wzr, 2c8 <cbne_9>
> +.*:	74ff3fe0 	cbne	w0, wzr, 2c8 <cbne_9>
> +
> +.* <cbne_10>:
> +.*:	74e0001f 	cbne	wzr, w0, 2d0 <cbne_10>
> +.*:	74e03fff 	cbne	wzr, w0, 2d0 <cbne_10>
> +
> +.* <cbne_11>:
> +.*:	74ff001f 	cbne	wzr, wzr, 2d8 <cbne_11>
> +.*:	74ff3fff 	cbne	wzr, wzr, 2d8 <cbne_11>
> +
> +.* <cbne_12>:
> +.*:	f4e00000 	cbne	x0, x0, 2e0 <cbne_12>
> +.*:	f4e03fe0 	cbne	x0, x0, 2e0 <cbne_12>
> +
> +.* <cbne_13>:
> +.*:	f4ff0000 	cbne	x0, xzr, 2e8 <cbne_13>
> +.*:	f4ff3fe0 	cbne	x0, xzr, 2e8 <cbne_13>
> +
> +.* <cbne_14>:
> +.*:	f4e0001f 	cbne	xzr, x0, 2f0 <cbne_14>
> +.*:	f4e03fff 	cbne	xzr, x0, 2f0 <cbne_14>
> +
> +.* <cbne_15>:
> +.*:	f4ff001f 	cbne	xzr, xzr, 2f8 <cbne_15>
> +.*:	f4ff3fff 	cbne	xzr, xzr, 2f8 <cbne_15>
> +
> +.* <cbbgt_0>:
> +.*:	74008000 	cbbgt	w0, w0, 300 <cbbgt_0>
> +.*:	7400bfe0 	cbbgt	w0, w0, 300 <cbbgt_0>
> +
> +.* <cbbgt_1>:
> +.*:	741f8000 	cbbgt	w0, wzr, 308 <cbbgt_1>
> +.*:	741fbfe0 	cbbgt	w0, wzr, 308 <cbbgt_1>
> +
> +.* <cbbgt_2>:
> +.*:	7400801f 	cbbgt	wzr, w0, 310 <cbbgt_2>
> +.*:	7400bfff 	cbbgt	wzr, w0, 310 <cbbgt_2>
> +
> +.* <cbbgt_3>:
> +.*:	741f801f 	cbbgt	wzr, wzr, 318 <cbbgt_3>
> +.*:	741fbfff 	cbbgt	wzr, wzr, 318 <cbbgt_3>
> +
> +.* <cbbge_0>:
> +.*:	74208000 	cbbge	w0, w0, 320 <cbbge_0>
> +.*:	7420bfe0 	cbbge	w0, w0, 320 <cbbge_0>
> +
> +.* <cbbge_1>:
> +.*:	743f8000 	cbbge	w0, wzr, 328 <cbbge_1>
> +.*:	743fbfe0 	cbbge	w0, wzr, 328 <cbbge_1>
> +
> +.* <cbbge_2>:
> +.*:	7420801f 	cbbge	wzr, w0, 330 <cbbge_2>
> +.*:	7420bfff 	cbbge	wzr, w0, 330 <cbbge_2>
> +
> +.* <cbbge_3>:
> +.*:	743f801f 	cbbge	wzr, wzr, 338 <cbbge_3>
> +.*:	743fbfff 	cbbge	wzr, wzr, 338 <cbbge_3>
> +
> +.* <cbbhi_0>:
> +.*:	74408000 	cbbhi	w0, w0, 340 <cbbhi_0>
> +.*:	7440bfe0 	cbbhi	w0, w0, 340 <cbbhi_0>
> +
> +.* <cbbhi_1>:
> +.*:	745f8000 	cbbhi	w0, wzr, 348 <cbbhi_1>
> +.*:	745fbfe0 	cbbhi	w0, wzr, 348 <cbbhi_1>
> +
> +.* <cbbhi_2>:
> +.*:	7440801f 	cbbhi	wzr, w0, 350 <cbbhi_2>
> +.*:	7440bfff 	cbbhi	wzr, w0, 350 <cbbhi_2>
> +
> +.* <cbbhi_3>:
> +.*:	745f801f 	cbbhi	wzr, wzr, 358 <cbbhi_3>
> +.*:	745fbfff 	cbbhi	wzr, wzr, 358 <cbbhi_3>
> +
> +.* <cbbhs_0>:
> +.*:	74608000 	cbbhs	w0, w0, 360 <cbbhs_0>
> +.*:	7460bfe0 	cbbhs	w0, w0, 360 <cbbhs_0>
> +
> +.* <cbbhs_1>:
> +.*:	747f8000 	cbbhs	w0, wzr, 368 <cbbhs_1>
> +.*:	747fbfe0 	cbbhs	w0, wzr, 368 <cbbhs_1>
> +
> +.* <cbbhs_2>:
> +.*:	7460801f 	cbbhs	wzr, w0, 370 <cbbhs_2>
> +.*:	7460bfff 	cbbhs	wzr, w0, 370 <cbbhs_2>
> +
> +.* <cbbhs_3>:
> +.*:	747f801f 	cbbhs	wzr, wzr, 378 <cbbhs_3>
> +.*:	747fbfff 	cbbhs	wzr, wzr, 378 <cbbhs_3>
> +
> +.* <cbbeq_0>:
> +.*:	74c08000 	cbbeq	w0, w0, 380 <cbbeq_0>
> +.*:	74c0bfe0 	cbbeq	w0, w0, 380 <cbbeq_0>
> +
> +.* <cbbeq_1>:
> +.*:	74df8000 	cbbeq	w0, wzr, 388 <cbbeq_1>
> +.*:	74dfbfe0 	cbbeq	w0, wzr, 388 <cbbeq_1>
> +
> +.* <cbbeq_2>:
> +.*:	74c0801f 	cbbeq	wzr, w0, 390 <cbbeq_2>
> +.*:	74c0bfff 	cbbeq	wzr, w0, 390 <cbbeq_2>
> +
> +.* <cbbeq_3>:
> +.*:	74df801f 	cbbeq	wzr, wzr, 398 <cbbeq_3>
> +.*:	74dfbfff 	cbbeq	wzr, wzr, 398 <cbbeq_3>
> +
> +.* <cbbne_0>:
> +.*:	74e08000 	cbbne	w0, w0, 3a0 <cbbne_0>
> +.*:	74e0bfe0 	cbbne	w0, w0, 3a0 <cbbne_0>
> +
> +.* <cbbne_1>:
> +.*:	74ff8000 	cbbne	w0, wzr, 3a8 <cbbne_1>
> +.*:	74ffbfe0 	cbbne	w0, wzr, 3a8 <cbbne_1>
> +
> +.* <cbbne_2>:
> +.*:	74e0801f 	cbbne	wzr, w0, 3b0 <cbbne_2>
> +.*:	74e0bfff 	cbbne	wzr, w0, 3b0 <cbbne_2>
> +
> +.* <cbbne_3>:
> +.*:	74ff801f 	cbbne	wzr, wzr, 3b8 <cbbne_3>
> +.*:	74ffbfff 	cbbne	wzr, wzr, 3b8 <cbbne_3>
> +
> +.* <cbhgt_0>:
> +.*:	7400c000 	cbhgt	w0, w0, 3c0 <cbhgt_0>
> +.*:	7400ffe0 	cbhgt	w0, w0, 3c0 <cbhgt_0>
> +
> +.* <cbhgt_1>:
> +.*:	741fc000 	cbhgt	w0, wzr, 3c8 <cbhgt_1>
> +.*:	741fffe0 	cbhgt	w0, wzr, 3c8 <cbhgt_1>
> +
> +.* <cbhgt_2>:
> +.*:	7400c01f 	cbhgt	wzr, w0, 3d0 <cbhgt_2>
> +.*:	7400ffff 	cbhgt	wzr, w0, 3d0 <cbhgt_2>
> +
> +.* <cbhgt_3>:
> +.*:	741fc01f 	cbhgt	wzr, wzr, 3d8 <cbhgt_3>
> +.*:	741fffff 	cbhgt	wzr, wzr, 3d8 <cbhgt_3>
> +
> +.* <cbhge_0>:
> +.*:	7420c000 	cbhge	w0, w0, 3e0 <cbhge_0>
> +.*:	7420ffe0 	cbhge	w0, w0, 3e0 <cbhge_0>
> +
> +.* <cbhge_1>:
> +.*:	743fc000 	cbhge	w0, wzr, 3e8 <cbhge_1>
> +.*:	743fffe0 	cbhge	w0, wzr, 3e8 <cbhge_1>
> +
> +.* <cbhge_2>:
> +.*:	7420c01f 	cbhge	wzr, w0, 3f0 <cbhge_2>
> +.*:	7420ffff 	cbhge	wzr, w0, 3f0 <cbhge_2>
> +
> +.* <cbhge_3>:
> +.*:	743fc01f 	cbhge	wzr, wzr, 3f8 <cbhge_3>
> +.*:	743fffff 	cbhge	wzr, wzr, 3f8 <cbhge_3>
> +
> +.* <cbhhi_0>:
> +.*:	7440c000 	cbhhi	w0, w0, 400 <cbhhi_0>
> +.*:	7440ffe0 	cbhhi	w0, w0, 400 <cbhhi_0>
> +
> +.* <cbhhi_1>:
> +.*:	745fc000 	cbhhi	w0, wzr, 408 <cbhhi_1>
> +.*:	745fffe0 	cbhhi	w0, wzr, 408 <cbhhi_1>
> +
> +.* <cbhhi_2>:
> +.*:	7440c01f 	cbhhi	wzr, w0, 410 <cbhhi_2>
> +.*:	7440ffff 	cbhhi	wzr, w0, 410 <cbhhi_2>
> +
> +.* <cbhhi_3>:
> +.*:	745fc01f 	cbhhi	wzr, wzr, 418 <cbhhi_3>
> +.*:	745fffff 	cbhhi	wzr, wzr, 418 <cbhhi_3>
> +
> +.* <cbhhs_0>:
> +.*:	7460c000 	cbhhs	w0, w0, 420 <cbhhs_0>
> +.*:	7460ffe0 	cbhhs	w0, w0, 420 <cbhhs_0>
> +
> +.* <cbhhs_1>:
> +.*:	747fc000 	cbhhs	w0, wzr, 428 <cbhhs_1>
> +.*:	747fffe0 	cbhhs	w0, wzr, 428 <cbhhs_1>
> +
> +.* <cbhhs_2>:
> +.*:	7460c01f 	cbhhs	wzr, w0, 430 <cbhhs_2>
> +.*:	7460ffff 	cbhhs	wzr, w0, 430 <cbhhs_2>
> +
> +.* <cbhhs_3>:
> +.*:	747fc01f 	cbhhs	wzr, wzr, 438 <cbhhs_3>
> +.*:	747fffff 	cbhhs	wzr, wzr, 438 <cbhhs_3>
> +
> +.* <cbheq_0>:
> +.*:	74c0c000 	cbheq	w0, w0, 440 <cbheq_0>
> +.*:	74c0ffe0 	cbheq	w0, w0, 440 <cbheq_0>
> +
> +.* <cbheq_1>:
> +.*:	74dfc000 	cbheq	w0, wzr, 448 <cbheq_1>
> +.*:	74dfffe0 	cbheq	w0, wzr, 448 <cbheq_1>
> +
> +.* <cbheq_2>:
> +.*:	74c0c01f 	cbheq	wzr, w0, 450 <cbheq_2>
> +.*:	74c0ffff 	cbheq	wzr, w0, 450 <cbheq_2>
> +
> +.* <cbheq_3>:
> +.*:	74dfc01f 	cbheq	wzr, wzr, 458 <cbheq_3>
> +.*:	74dfffff 	cbheq	wzr, wzr, 458 <cbheq_3>
> +
> +.* <cbhne_0>:
> +.*:	74e0c000 	cbhne	w0, w0, 460 <cbhne_0>
> +.*:	74e0ffe0 	cbhne	w0, w0, 460 <cbhne_0>
> +
> +.* <cbhne_1>:
> +.*:	74ffc000 	cbhne	w0, wzr, 468 <cbhne_1>
> +.*:	74ffffe0 	cbhne	w0, wzr, 468 <cbhne_1>
> +
> +.* <cbhne_2>:
> +.*:	74e0c01f 	cbhne	wzr, w0, 470 <cbhne_2>
> +.*:	74e0ffff 	cbhne	wzr, w0, 470 <cbhne_2>
> +
> +.* <cbhne_3>:
> +.*:	74ffc01f 	cbhne	wzr, wzr, 478 <cbhne_3>
> +.*:	74ffffff 	cbhne	wzr, wzr, 478 <cbhne_3>
> diff --git a/gas/testsuite/gas/aarch64/cmpbr.s b/gas/testsuite/gas/aarch64/cmpbr.s
> new file mode 100644
> index 00000000000..a7d067681b7
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/cmpbr.s
> @@ -0,0 +1,435 @@
> +cbgt_0:
> +	cbgt	w0, #0, cbgt_0
> +	cbgt	w0, #0, cbgt_0
> +cbgt_1:
> +	cbgt	w0, #63, cbgt_1
> +	cbgt	w0, #63, cbgt_1
> +cbgt_2:
> +	cbgt	wzr, #0, cbgt_2
> +	cbgt	wzr, #0, cbgt_2
> +cbgt_3:
> +	cbgt	wzr, #63, cbgt_3
> +	cbgt	wzr, #63, cbgt_3
> +cbgt_4:
> +	cbgt	x0, #0, cbgt_4
> +	cbgt	x0, #0, cbgt_4
> +cbgt_5:
> +	cbgt	x0, #63, cbgt_5
> +	cbgt	x0, #63, cbgt_5
> +cbgt_6:
> +	cbgt	xzr, #0, cbgt_6
> +	cbgt	xzr, #0, cbgt_6
> +cbgt_7:
> +	cbgt	xzr, #63, cbgt_7
> +	cbgt	xzr, #63, cbgt_7
> +cblt_0:
> +	cblt	w0, #0, cblt_0
> +	cblt	w0, #0, cblt_0
> +cblt_1:
> +	cblt	w0, #63, cblt_1
> +	cblt	w0, #63, cblt_1
> +cblt_2:
> +	cblt	wzr, #0, cblt_2
> +	cblt	wzr, #0, cblt_2
> +cblt_3:
> +	cblt	wzr, #63, cblt_3
> +	cblt	wzr, #63, cblt_3
> +cblt_4:
> +	cblt	x0, #0, cblt_4
> +	cblt	x0, #0, cblt_4
> +cblt_5:
> +	cblt	x0, #63, cblt_5
> +	cblt	x0, #63, cblt_5
> +cblt_6:
> +	cblt	xzr, #0, cblt_6
> +	cblt	xzr, #0, cblt_6
> +cblt_7:
> +	cblt	xzr, #63, cblt_7
> +	cblt	xzr, #63, cblt_7
> +cbhi_0:
> +	cbhi	w0, #0, cbhi_0
> +	cbhi	w0, #0, cbhi_0
> +cbhi_1:
> +	cbhi	w0, #63, cbhi_1
> +	cbhi	w0, #63, cbhi_1
> +cbhi_2:
> +	cbhi	wzr, #0, cbhi_2
> +	cbhi	wzr, #0, cbhi_2
> +cbhi_3:
> +	cbhi	wzr, #63, cbhi_3
> +	cbhi	wzr, #63, cbhi_3
> +cbhi_4:
> +	cbhi	x0, #0, cbhi_4
> +	cbhi	x0, #0, cbhi_4
> +cbhi_5:
> +	cbhi	x0, #63, cbhi_5
> +	cbhi	x0, #63, cbhi_5
> +cbhi_6:
> +	cbhi	xzr, #0, cbhi_6
> +	cbhi	xzr, #0, cbhi_6
> +cbhi_7:
> +	cbhi	xzr, #63, cbhi_7
> +	cbhi	xzr, #63, cbhi_7
> +cblo_0:
> +	cblo	w0, #0, cblo_0
> +	cblo	w0, #0, cblo_0
> +cblo_1:
> +	cblo	w0, #63, cblo_1
> +	cblo	w0, #63, cblo_1
> +cblo_2:
> +	cblo	wzr, #0, cblo_2
> +	cblo	wzr, #0, cblo_2
> +cblo_3:
> +	cblo	wzr, #63, cblo_3
> +	cblo	wzr, #63, cblo_3
> +cblo_4:
> +	cblo	x0, #0, cblo_4
> +	cblo	x0, #0, cblo_4
> +cblo_5:
> +	cblo	x0, #63, cblo_5
> +	cblo	x0, #63, cblo_5
> +cblo_6:
> +	cblo	xzr, #0, cblo_6
> +	cblo	xzr, #0, cblo_6
> +cblo_7:
> +	cblo	xzr, #63, cblo_7
> +	cblo	xzr, #63, cblo_7
> +cbeq_0:
> +	cbeq	w0, #0, cbeq_0
> +	cbeq	w0, #0, cbeq_0
> +cbeq_1:
> +	cbeq	w0, #63, cbeq_1
> +	cbeq	w0, #63, cbeq_1
> +cbeq_2:
> +	cbeq	wzr, #0, cbeq_2
> +	cbeq	wzr, #0, cbeq_2
> +cbeq_3:
> +	cbeq	wzr, #63, cbeq_3
> +	cbeq	wzr, #63, cbeq_3
> +cbeq_4:
> +	cbeq	x0, #0, cbeq_4
> +	cbeq	x0, #0, cbeq_4
> +cbeq_5:
> +	cbeq	x0, #63, cbeq_5
> +	cbeq	x0, #63, cbeq_5
> +cbeq_6:
> +	cbeq	xzr, #0, cbeq_6
> +	cbeq	xzr, #0, cbeq_6
> +cbeq_7:
> +	cbeq	xzr, #63, cbeq_7
> +	cbeq	xzr, #63, cbeq_7
> +cbne_0:
> +	cbne	w0, #0, cbne_0
> +	cbne	w0, #0, cbne_0
> +cbne_1:
> +	cbne	w0, #63, cbne_1
> +	cbne	w0, #63, cbne_1
> +cbne_2:
> +	cbne	wzr, #0, cbne_2
> +	cbne	wzr, #0, cbne_2
> +cbne_3:
> +	cbne	wzr, #63, cbne_3
> +	cbne	wzr, #63, cbne_3
> +cbne_4:
> +	cbne	x0, #0, cbne_4
> +	cbne	x0, #0, cbne_4
> +cbne_5:
> +	cbne	x0, #63, cbne_5
> +	cbne	x0, #63, cbne_5
> +cbne_6:
> +	cbne	xzr, #0, cbne_6
> +	cbne	xzr, #0, cbne_6
> +cbne_7:
> +	cbne	xzr, #63, cbne_7
> +	cbne	xzr, #63, cbne_7
> +
> +cbgt_8:
> +	cbgt	w0, w0, cbgt_8
> +	cbgt	w0, w0, cbgt_8
> +cbgt_9:
> +	cbgt	w0, wzr, cbgt_9
> +	cbgt	w0, wzr, cbgt_9
> +cbgt_10:
> +	cbgt	wzr, w0, cbgt_10
> +	cbgt	wzr, w0, cbgt_10
> +cbgt_11:
> +	cbgt	wzr, wzr, cbgt_11
> +	cbgt	wzr, wzr, cbgt_11
> +cbgt_12:
> +	cbgt	x0, x0, cbgt_12
> +	cbgt	x0, x0, cbgt_12
> +cbgt_13:
> +	cbgt	x0, xzr, cbgt_13
> +	cbgt	x0, xzr, cbgt_13
> +cbgt_14:
> +	cbgt	xzr, x0, cbgt_14
> +	cbgt	xzr, x0, cbgt_14
> +cbgt_15:
> +	cbgt	xzr, xzr, cbgt_15
> +	cbgt	xzr, xzr, cbgt_15
> +cbge_8:
> +	cbge	w0, w0, cbge_8
> +	cbge	w0, w0, cbge_8
> +cbge_9:
> +	cbge	w0, wzr, cbge_9
> +	cbge	w0, wzr, cbge_9
> +cbge_10:
> +	cbge	wzr, w0, cbge_10
> +	cbge	wzr, w0, cbge_10
> +cbge_11:
> +	cbge	wzr, wzr, cbge_11
> +	cbge	wzr, wzr, cbge_11
> +cbge_12:
> +	cbge	x0, x0, cbge_12
> +	cbge	x0, x0, cbge_12
> +cbge_13:
> +	cbge	x0, xzr, cbge_13
> +	cbge	x0, xzr, cbge_13
> +cbge_14:
> +	cbge	xzr, x0, cbge_14
> +	cbge	xzr, x0, cbge_14
> +cbge_15:
> +	cbge	xzr, xzr, cbge_15
> +	cbge	xzr, xzr, cbge_15
> +cbhi_8:
> +	cbhi	w0, w0, cbhi_8
> +	cbhi	w0, w0, cbhi_8
> +cbhi_9:
> +	cbhi	w0, wzr, cbhi_9
> +	cbhi	w0, wzr, cbhi_9
> +cbhi_10:
> +	cbhi	wzr, w0, cbhi_10
> +	cbhi	wzr, w0, cbhi_10
> +cbhi_11:
> +	cbhi	wzr, wzr, cbhi_11
> +	cbhi	wzr, wzr, cbhi_11
> +cbhi_12:
> +	cbhi	x0, x0, cbhi_12
> +	cbhi	x0, x0, cbhi_12
> +cbhi_13:
> +	cbhi	x0, xzr, cbhi_13
> +	cbhi	x0, xzr, cbhi_13
> +cbhi_14:
> +	cbhi	xzr, x0, cbhi_14
> +	cbhi	xzr, x0, cbhi_14
> +cbhi_15:
> +	cbhi	xzr, xzr, cbhi_15
> +	cbhi	xzr, xzr, cbhi_15
> +cbhs_8:
> +	cbhs	w0, w0, cbhs_8
> +	cbhs	w0, w0, cbhs_8
> +cbhs_9:
> +	cbhs	w0, wzr, cbhs_9
> +	cbhs	w0, wzr, cbhs_9
> +cbhs_10:
> +	cbhs	wzr, w0, cbhs_10
> +	cbhs	wzr, w0, cbhs_10
> +cbhs_11:
> +	cbhs	wzr, wzr, cbhs_11
> +	cbhs	wzr, wzr, cbhs_11
> +cbhs_12:
> +	cbhs	x0, x0, cbhs_12
> +	cbhs	x0, x0, cbhs_12
> +cbhs_13:
> +	cbhs	x0, xzr, cbhs_13
> +	cbhs	x0, xzr, cbhs_13
> +cbhs_14:
> +	cbhs	xzr, x0, cbhs_14
> +	cbhs	xzr, x0, cbhs_14
> +cbhs_15:
> +	cbhs	xzr, xzr, cbhs_15
> +	cbhs	xzr, xzr, cbhs_15
> +cbeq_8:
> +	cbeq	w0, w0, cbeq_8
> +	cbeq	w0, w0, cbeq_8
> +cbeq_9:
> +	cbeq	w0, wzr, cbeq_9
> +	cbeq	w0, wzr, cbeq_9
> +cbeq_10:
> +	cbeq	wzr, w0, cbeq_10
> +	cbeq	wzr, w0, cbeq_10
> +cbeq_11:
> +	cbeq	wzr, wzr, cbeq_11
> +	cbeq	wzr, wzr, cbeq_11
> +cbeq_12:
> +	cbeq	x0, x0, cbeq_12
> +	cbeq	x0, x0, cbeq_12
> +cbeq_13:
> +	cbeq	x0, xzr, cbeq_13
> +	cbeq	x0, xzr, cbeq_13
> +cbeq_14:
> +	cbeq	xzr, x0, cbeq_14
> +	cbeq	xzr, x0, cbeq_14
> +cbeq_15:
> +	cbeq	xzr, xzr, cbeq_15
> +	cbeq	xzr, xzr, cbeq_15
> +cbne_8:
> +	cbne	w0, w0, cbne_8
> +	cbne	w0, w0, cbne_8
> +cbne_9:
> +	cbne	w0, wzr, cbne_9
> +	cbne	w0, wzr, cbne_9
> +cbne_10:
> +	cbne	wzr, w0, cbne_10
> +	cbne	wzr, w0, cbne_10
> +cbne_11:
> +	cbne	wzr, wzr, cbne_11
> +	cbne	wzr, wzr, cbne_11
> +cbne_12:
> +	cbne	x0, x0, cbne_12
> +	cbne	x0, x0, cbne_12
> +cbne_13:
> +	cbne	x0, xzr, cbne_13
> +	cbne	x0, xzr, cbne_13
> +cbne_14:
> +	cbne	xzr, x0, cbne_14
> +	cbne	xzr, x0, cbne_14
> +cbne_15:
> +	cbne	xzr, xzr, cbne_15
> +	cbne	xzr, xzr, cbne_15
> +
> +cbbgt_0:
> +	cbbgt	w0, w0, cbbgt_0
> +	cbbgt	w0, w0, cbbgt_0
> +cbbgt_1:
> +	cbbgt	w0, wzr, cbbgt_1
> +	cbbgt	w0, wzr, cbbgt_1
> +cbbgt_2:
> +	cbbgt	wzr, w0, cbbgt_2
> +	cbbgt	wzr, w0, cbbgt_2
> +cbbgt_3:
> +	cbbgt	wzr, wzr, cbbgt_3
> +	cbbgt	wzr, wzr, cbbgt_3
> +cbbge_0:
> +	cbbge	w0, w0, cbbge_0
> +	cbbge	w0, w0, cbbge_0
> +cbbge_1:
> +	cbbge	w0, wzr, cbbge_1
> +	cbbge	w0, wzr, cbbge_1
> +cbbge_2:
> +	cbbge	wzr, w0, cbbge_2
> +	cbbge	wzr, w0, cbbge_2
> +cbbge_3:
> +	cbbge	wzr, wzr, cbbge_3
> +	cbbge	wzr, wzr, cbbge_3
> +cbbhi_0:
> +	cbbhi	w0, w0, cbbhi_0
> +	cbbhi	w0, w0, cbbhi_0
> +cbbhi_1:
> +	cbbhi	w0, wzr, cbbhi_1
> +	cbbhi	w0, wzr, cbbhi_1
> +cbbhi_2:
> +	cbbhi	wzr, w0, cbbhi_2
> +	cbbhi	wzr, w0, cbbhi_2
> +cbbhi_3:
> +	cbbhi	wzr, wzr, cbbhi_3
> +	cbbhi	wzr, wzr, cbbhi_3
> +cbbhs_0:
> +	cbbhs	w0, w0, cbbhs_0
> +	cbbhs	w0, w0, cbbhs_0
> +cbbhs_1:
> +	cbbhs	w0, wzr, cbbhs_1
> +	cbbhs	w0, wzr, cbbhs_1
> +cbbhs_2:
> +	cbbhs	wzr, w0, cbbhs_2
> +	cbbhs	wzr, w0, cbbhs_2
> +cbbhs_3:
> +	cbbhs	wzr, wzr, cbbhs_3
> +	cbbhs	wzr, wzr, cbbhs_3
> +cbbeq_0:
> +	cbbeq	w0, w0, cbbeq_0
> +	cbbeq	w0, w0, cbbeq_0
> +cbbeq_1:
> +	cbbeq	w0, wzr, cbbeq_1
> +	cbbeq	w0, wzr, cbbeq_1
> +cbbeq_2:
> +	cbbeq	wzr, w0, cbbeq_2
> +	cbbeq	wzr, w0, cbbeq_2
> +cbbeq_3:
> +	cbbeq	wzr, wzr, cbbeq_3
> +	cbbeq	wzr, wzr, cbbeq_3
> +cbbne_0:
> +	cbbne	w0, w0, cbbne_0
> +	cbbne	w0, w0, cbbne_0
> +cbbne_1:
> +	cbbne	w0, wzr, cbbne_1
> +	cbbne	w0, wzr, cbbne_1
> +cbbne_2:
> +	cbbne	wzr, w0, cbbne_2
> +	cbbne	wzr, w0, cbbne_2
> +cbbne_3:
> +	cbbne	wzr, wzr, cbbne_3
> +	cbbne	wzr, wzr, cbbne_3
> +
> +cbhgt_0:
> +	cbhgt	w0, w0, cbhgt_0
> +	cbhgt	w0, w0, cbhgt_0
> +cbhgt_1:
> +	cbhgt	w0, wzr, cbhgt_1
> +	cbhgt	w0, wzr, cbhgt_1
> +cbhgt_2:
> +	cbhgt	wzr, w0, cbhgt_2
> +	cbhgt	wzr, w0, cbhgt_2
> +cbhgt_3:
> +	cbhgt	wzr, wzr, cbhgt_3
> +	cbhgt	wzr, wzr, cbhgt_3
> +cbhge_0:
> +	cbhge	w0, w0, cbhge_0
> +	cbhge	w0, w0, cbhge_0
> +cbhge_1:
> +	cbhge	w0, wzr, cbhge_1
> +	cbhge	w0, wzr, cbhge_1
> +cbhge_2:
> +	cbhge	wzr, w0, cbhge_2
> +	cbhge	wzr, w0, cbhge_2
> +cbhge_3:
> +	cbhge	wzr, wzr, cbhge_3
> +	cbhge	wzr, wzr, cbhge_3
> +cbhhi_0:
> +	cbhhi	w0, w0, cbhhi_0
> +	cbhhi	w0, w0, cbhhi_0
> +cbhhi_1:
> +	cbhhi	w0, wzr, cbhhi_1
> +	cbhhi	w0, wzr, cbhhi_1
> +cbhhi_2:
> +	cbhhi	wzr, w0, cbhhi_2
> +	cbhhi	wzr, w0, cbhhi_2
> +cbhhi_3:
> +	cbhhi	wzr, wzr, cbhhi_3
> +	cbhhi	wzr, wzr, cbhhi_3
> +cbhhs_0:
> +	cbhhs	w0, w0, cbhhs_0
> +	cbhhs	w0, w0, cbhhs_0
> +cbhhs_1:
> +	cbhhs	w0, wzr, cbhhs_1
> +	cbhhs	w0, wzr, cbhhs_1
> +cbhhs_2:
> +	cbhhs	wzr, w0, cbhhs_2
> +	cbhhs	wzr, w0, cbhhs_2
> +cbhhs_3:
> +	cbhhs	wzr, wzr, cbhhs_3
> +	cbhhs	wzr, wzr, cbhhs_3
> +cbheq_0:
> +	cbheq	w0, w0, cbheq_0
> +	cbheq	w0, w0, cbheq_0
> +cbheq_1:
> +	cbheq	w0, wzr, cbheq_1
> +	cbheq	w0, wzr, cbheq_1
> +cbheq_2:
> +	cbheq	wzr, w0, cbheq_2
> +	cbheq	wzr, w0, cbheq_2
> +cbheq_3:
> +	cbheq	wzr, wzr, cbheq_3
> +	cbheq	wzr, wzr, cbheq_3
> +cbhne_0:
> +	cbhne	w0, w0, cbhne_0
> +	cbhne	w0, w0, cbhne_0
> +cbhne_1:
> +	cbhne	w0, wzr, cbhne_1
> +	cbhne	w0, wzr, cbhne_1
> +cbhne_2:
> +	cbhne	wzr, w0, cbhne_2
> +	cbhne	wzr, w0, cbhne_2
> +cbhne_3:
> +	cbhne	wzr, wzr, cbhne_3
> +	cbhne	wzr, wzr, cbhne_3

Thanks, I think this is good coverage for the non-pseudo instructions.  For
future reference, I would also be satisfied with a bit less, e.g. for 'cbhne'
I'd also accept just:

+Lcbhne:
+	cbhne	w0, w0, Lcbhne
+	cbhne	w0, wzr, Lcbhne
+	cbhne	wzr, w0, Lcbhne

> 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