public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Richard Earnshaw <Richard.Earnshaw@foss.arm.com>
To: Andrew Burgess <aburgess@redhat.com>,
	Andrew Burgess via Binutils <binutils@sourceware.org>
Subject: Re: [PATCHv2 2/2] libopcodes/aarch64: add support for disassembler styling
Date: Tue, 5 Jul 2022 14:10:57 +0100	[thread overview]
Message-ID: <fd6ec2f8-4293-0d76-dd13-e54004dba441@foss.arm.com> (raw)
In-Reply-To: <87fsjfbu3v.fsf@redhat.com>

I think my biggest criticism of this approach is the need to rewrite all 
the template strings, eg:

-    snprintf (buf, size, "{%s%d.%s-%s%d.%s}%s", prefix, first_reg, 
qlf_name,
-	      prefix, last_reg, qlf_name, tb);
+    snprintf (buf, size, "%s{%s%s%d.%s%s-%s%s%d.%s%s}%s", ...

It would all be so much cleaner if we could write something more like


   snprintf (buf, size, "{%s-%s}%s",
             format_reg (prefix, first_reg, qlf_name),
             format_reg (prefix, last_reg, qlf_name), ...

I guess the difficultly here would be creating a lot of garbage strings 
that would then need to be garbage-collected later on, but still...

Who said obstacks?

R.

On 05/07/2022 13:51, Andrew Burgess via Binutils wrote:
> 
> Apologies, I left some debug code in this latest version of the
> patch.  Here's an update with the debug code removed.
> 
> Thanks,
> Andrew
> 
> ---
> 
> commit 69a681f8747a145dcaba969ae8972a20d1176a05
> Author: Andrew Burgess <aburgess@redhat.com>
> Date:   Thu Apr 28 13:31:07 2022 +0100
> 
>      libopcodes/aarch64: add support for disassembler styling
>      
>      This commit enables disassembler styling for AArch64.  After this
>      commit it is possible to have objdump style AArch64 disassembler
>      output (using --disassembler-color option).  Once the required GDB
>      patches are merged, GDB will also style the disassembler output.
>      
>      The changes to support styling are mostly split between two files
>      opcodes/aarch64-dis.c and opcodes/aarch64-opc.c.
>      
>      The entry point for the AArch64 disassembler can be found in
>      aarch64-dis.c, this file handles printing the instruction mnemonics,
>      and assembler directives (e.g. '.byte', '.word', etc).  Some operands,
>      mostly relating to assembler directives are also printed from this
>      file.  This commit changes all of this to pass through suitable
>      styling information.
>      
>      However, for most "normal" instructions, the instruction operands are
>      printed using a two step process.  From aarch64-dis.c, in the
>      print_operands function, the function aarch64_print_operand is called,
>      this function is in aarch64-opc.c, and converts an instruction operand
>      into a string.  Then, back in print_operands (aarch64-dis.c), the
>      operand string is printed.
>      
>      Unfortunately, the string returned by aarch64_print_operand can be
>      quite complex, it will include syntax elements, like '[' and ']', in
>      addition to register names and immediate values.  In some cases, a
>      single operand will expand into what will appear (to the user) as
>      multiple operands separated with a ','.
>      
>      This makes the task of styling more complex, all these different
>      components need to by styled differently, so we need to get the
>      styling information out of aarch64_print_operand in some way.
>      
>      The solution that I propose here is similar to the solution that I
>      used for the i386 disassembler.
>      
>      Currently, aarch64_print_operand uses snprintf to write the operand
>      text into a buffer provided by the caller.
>      
>      What I propose is that we pass an extra argument to the
>      aarch64_print_operand function, this argument will be a callback
>      function that converts a disassembler style into a string.  These
>      strings can then be written into the buffer using snprintf.  Here's an
>      example, 'get_style' is the new callback function:
>      
>          snprintf (buf, size, "%s%s",
>                    get_style (dis_style_register),
>                    get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
>      
>      The string returned by 'get_style' is a special sequence of characters
>      that is not otherwise seen in the disassembler output.  In the
>      print_operands function we can now scan the buffer returned by
>      aarch64_print_operand, and split the text based on the style
>      markers.  Each separately styled block is then printed with the
>      correct style.
>      
>      The aarch64_print_operand function is also called from the assembler
>      to aid in printing diagnostic messages.  Right now I have no plans to
>      add styling to the assembler output, and so, in this case, the
>      'get_style' callback is a dummy function that always returns an empty
>      string.  As a result, when the assembler calls aarch64_print_operand,
>      the string returns can be immediately printed with no special style
>      handling required.
>      
>      I've gone through and updated arch64-opc.c as best I can to add
>      styling information.  I've mostly used the gas/testsuite/gas/aarch64
>      tests to check the styling, assembling then disassembling each source
>      file, then checking that the output looks reasonable.
>      
>      With objdump disassembler color turned off, there should be no change
>      in the output after this commit.
> 
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index 779db31828b..740bde53ea8 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -5347,6 +5347,15 @@ assign_qualifier_sequence (aarch64_inst *instr,
>       instr->operands[i].qualifier = *qualifiers;
>   }
>   
> +/* Return a string indicating a switch to STYLE.  As the assembler doesn't
> +   use styling in its output, this always returns an empty string.  */
> +
> +static const char *
> +get_style_text (enum disassembler_style style ATTRIBUTE_UNUSED)
> +{
> +  return "";
> +}
> +
>   /* Print operands for the diagnosis purpose.  */
>   
>   static void
> @@ -5371,7 +5380,7 @@ print_operands (char *buf, const aarch64_opcode *opcode,
>   
>         /* Generate the operand string in STR.  */
>         aarch64_print_operand (str, sizeof (str), 0, opcode, opnds, i, NULL, NULL,
> -			     NULL, cmt, sizeof (cmt), cpu_variant);
> +			     NULL, cmt, sizeof (cmt), cpu_variant, get_style_text);
>   
>         /* Delimiter.  */
>         if (str[0] != '\0')
> diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
> index 186ba9a4800..373deb6b49c 100644
> --- a/include/opcode/aarch64.h
> +++ b/include/opcode/aarch64.h
> @@ -27,6 +27,8 @@
>   #include <assert.h>
>   #include <stdlib.h>
>   
> +#include "dis-asm.h"
> +
>   #ifdef __cplusplus
>   extern "C" {
>   #endif
> @@ -1367,12 +1369,16 @@ aarch64_replace_opcode (struct aarch64_inst *,
>   extern const aarch64_opcode *
>   aarch64_get_opcode (enum aarch64_op);
>   
> +/* Return a text string that indicates a change of disassembler style.  */
> +typedef const char *(*get_style_func) (enum disassembler_style);
> +
>   /* Generate the string representation of an operand.  */
>   extern void
>   aarch64_print_operand (char *, size_t, bfd_vma, const aarch64_opcode *,
>   		       const aarch64_opnd_info *, int, int *, bfd_vma *,
>   		       char **, char *, size_t,
> -		       aarch64_feature_set features);
> +		       aarch64_feature_set features,
> +		       get_style_func get_style);
>   
>   /* Miscellaneous interface.  */
>   
> diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
> index acaad28fdff..fbbd0c5e087 100644
> --- a/opcodes/aarch64-dis.c
> +++ b/opcodes/aarch64-dis.c
> @@ -25,9 +25,14 @@
>   #include "opintl.h"
>   #include "aarch64-dis.h"
>   #include "elf-bfd.h"
> +#include "safe-ctype.h"
>   
>   #define INSNLEN 4
>   
> +/* This character is used to encode style information within the output
> +   buffers.  See get_style_text and print_operands for more details.  */
> +#define STYLE_MARKER_CHAR '\002'
> +
>   /* Cached mapping symbol state.  */
>   enum map_type
>   {
> @@ -3275,6 +3280,45 @@ aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
>     return ERR_UND;
>   }
>   
> +/* When the aarch64_print_operand code is building the string to represent
> +   an operand, this function is called each time we need to change style,
> +   with STYLE being the new style.  The string returned from this function
> +   will then be embedded in to the operand buffer.
> +
> +   When we finally print the operand buffer in print_operands, we find
> +   these style markers and split the operand text into chunks, where each
> +   chunk is a series of characters with the same style.  */
> +
> +static const char *
> +get_style_text (enum disassembler_style style)
> +{
> +  static bool init = false;
> +  static char formats[16][4];
> +  unsigned num;
> +
> +  /* First time through we build a string for every possible format.  This
> +     code relies on there being no more than 16 different styles (there's
> +     an assert below for this).  */
> +  if (!init)
> +    {
> +      int i;
> +
> +      for (i = 0; i <= 0xf; ++i)
> +	{
> +	  int res = snprintf (&formats[i][0], sizeof (formats[i]), "%c%x%c",
> +			      STYLE_MARKER_CHAR, i, STYLE_MARKER_CHAR);
> +	  assert (res == 3);
> +	}
> +
> +      init = true;
> +    }
> +
> +  /* Return the string that marks switching to STYLE.  */
> +  num = (unsigned) style;
> +  assert (style <= 0xf);
> +  return formats[num];
> +}
> +
>   /* Print operands.  */
>   
>   static void
> @@ -3301,32 +3345,91 @@ print_operands (bfd_vma pc, const aarch64_opcode *opcode,
>         /* Generate the operand string in STR.  */
>         aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
>   			     &info->target, &notes, cmt, sizeof (cmt),
> -			     arch_variant);
> +			     arch_variant, get_style_text);
>   
>         /* Print the delimiter (taking account of omitted operand(s)).  */
>         if (str[0] != '\0')
> -	(*info->fprintf_func) (info->stream, "%s",
> -			       num_printed++ == 0 ? "\t" : ", ");
> +	(*info->fprintf_styled_func) (info->stream, dis_style_text, "%s",
> +				      num_printed++ == 0 ? "\t" : ", ");
>   
>         /* Print the operand.  */
>         if (pcrel_p)
>   	(*info->print_address_func) (info->target, info);
>         else
>   	{
> -	  (*info->fprintf_func) (info->stream, "%s", str);
> -
> -	  /* Print the comment.  This works because only the last operand
> -	     ever adds a comment.  If that ever changes then we'll need to
> -	     be smarter here.  */
> -	  if (cmt[0] != '\0')
> -	    (*info->fprintf_func) (info->stream, "\t// %s", cmt);
> +	  /* This operand came from aarch64_print_operand, and will include
> +	     embedded strings indicating which style each character should
> +	     have.  In the following code we split the text based on
> +	     CURR_STYLE, and call the styled print callback to print each
> +	     block of text in the appropriate style.  */
> +	  char *start, *curr;
> +	  enum disassembler_style curr_style = dis_style_text;
> +
> +	  start = curr = str;
> +	  do
> +	    {
> +	      if (*curr == '\0'
> +		  || (*curr == STYLE_MARKER_CHAR
> +		      && ISXDIGIT (*(curr + 1))
> +		      && *(curr + 2) == STYLE_MARKER_CHAR))
> +		{
> +		  /* Output content between our START position and CURR.  */
> +		  int len = curr - start;
> +		  int n = (*info->fprintf_styled_func) (info->stream,
> +							curr_style,
> +							"%.*s", len, start);
> +		  if (n < 0)
> +		    break;
> +
> +		  if (*curr == '\0')
> +		    break;
> +
> +		  /* Skip over the initial STYLE_MARKER_CHAR.  */
> +		  ++curr;
> +
> +		  /* Update the CURR_STYLE.  As there are less than 16
> +		     styles, it is possible, that if the input is corrupted
> +		     in some way, that we might set CURR_STYLE to an
> +		     invalid value.  Don't worry though, we check for this
> +		     situation.  */
> +		  if (*curr >= '0' && *curr <= '9')
> +		    curr_style = (enum disassembler_style) (*curr - '0');
> +		  else if (*curr >= 'a' && *curr <= 'f')
> +		    curr_style = (enum disassembler_style) (*curr - 'a' + 10);
> +		  else
> +		    curr_style = dis_style_text;
> +
> +		  /* Check for an invalid style having been selected.  This
> +		     should never happen, but it doesn't hurt to be a
> +		     little paranoid.  */
> +		  if (curr_style > dis_style_comment_start)
> +		    curr_style = dis_style_text;
> +
> +		  /* Skip the hex character, and the closing STYLE_MARKER_CHAR.  */
> +		  curr += 2;
> +
> +		  /* Reset the START to after the style marker.  */
> +		  start = curr;
> +		}
> +	      else
> +		++curr;
> +	    }
> +	  while (true);
>   	}
> +
> +      /* Print the comment.  This works because only the last operand ever
> +	 adds a comment.  If that ever changes then we'll need to be
> +	 smarter here.  */
> +      if (cmt[0] != '\0')
> +	(*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
> +				      "\t// %s", cmt);
>       }
>   
>       if (notes && !no_notes)
>         {
>   	*has_notes = true;
> -	(*info->fprintf_func) (info->stream, "  // note: %s", notes);
> +	(*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
> +				      "  // note: %s", notes);
>         }
>   }
>   
> @@ -3359,10 +3462,12 @@ print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
>         char name[8];
>   
>         remove_dot_suffix (name, inst);
> -      (*info->fprintf_func) (info->stream, "%s.%s", name, inst->cond->names[0]);
> +      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
> +				    "%s.%s", name, inst->cond->names[0]);
>       }
>     else
> -    (*info->fprintf_func) (info->stream, "%s", inst->opcode->name);
> +    (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
> +				  "%s", inst->opcode->name);
>   }
>   
>   /* Decide whether we need to print a comment after the operands of
> @@ -3379,9 +3484,10 @@ print_comment (const aarch64_inst *inst, struct disassemble_info *info)
>         remove_dot_suffix (name, inst);
>         num_conds = ARRAY_SIZE (inst->cond->names);
>         for (i = 1; i < num_conds && inst->cond->names[i]; ++i)
> -	(*info->fprintf_func) (info->stream, "%s %s.%s",
> -			       i == 1 ? "  //" : ",",
> -			       name, inst->cond->names[i]);
> +	(*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
> +				      "%s %s.%s",
> +				      i == 1 ? "  //" : ",",
> +				      name, inst->cond->names[i]);
>       }
>   }
>   
> @@ -3398,28 +3504,30 @@ print_verifier_notes (aarch64_operand_error *detail,
>        would not have succeeded.  We can safely ignore these.  */
>     assert (detail->non_fatal);
>   
> -  (*info->fprintf_func) (info->stream, "  // note: ");
> +  (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
> +				"  // note: ");
>     switch (detail->kind)
>       {
>       case AARCH64_OPDE_A_SHOULD_FOLLOW_B:
> -      (*info->fprintf_func) (info->stream,
> -			     _("this `%s' should have an immediately"
> -			       " preceding `%s'"),
> -			     detail->data[0].s, detail->data[1].s);
> +      (*info->fprintf_styled_func) (info->stream, dis_style_text,
> +				    _("this `%s' should have an immediately"
> +				      " preceding `%s'"),
> +				    detail->data[0].s, detail->data[1].s);
>         break;
>   
>       case AARCH64_OPDE_EXPECTED_A_AFTER_B:
> -      (*info->fprintf_func) (info->stream,
> -			     _("expected `%s' after previous `%s'"),
> -			     detail->data[0].s, detail->data[1].s);
> +      (*info->fprintf_styled_func) (info->stream, dis_style_text,
> +				    _("expected `%s' after previous `%s'"),
> +				    detail->data[0].s, detail->data[1].s);
>         break;
>   
>       default:
>         assert (detail->error);
> -      (*info->fprintf_func) (info->stream, "%s", detail->error);
> +      (*info->fprintf_styled_func) (info->stream, dis_style_text,
> +				    "%s", detail->error);
>         if (detail->index >= 0)
> -	(*info->fprintf_func) (info->stream, " at operand %d",
> -			       detail->index + 1);
> +	(*info->fprintf_styled_func) (info->stream, dis_style_text,
> +				      " at operand %d", detail->index + 1);
>         break;
>       }
>   }
> @@ -3511,8 +3619,13 @@ print_insn_aarch64_word (bfd_vma pc,
>       case ERR_NYI:
>         /* Handle undefined instructions.  */
>         info->insn_type = dis_noninsn;
> -      (*info->fprintf_func) (info->stream,".inst\t0x%08x ; %s",
> -			     word, err_msg[ret]);
> +      (*info->fprintf_styled_func) (info->stream,
> +				    dis_style_assembler_directive,
> +				    ".inst\t");
> +      (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
> +				    "0x%08x", word);
> +      (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
> +				    " ; %s", err_msg[ret]);
>         break;
>       case ERR_OK:
>         user_friendly_fixup (&inst);
> @@ -3554,13 +3667,22 @@ print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
>     switch (info->bytes_per_chunk)
>       {
>       case 1:
> -      info->fprintf_func (info->stream, ".byte\t0x%02x", word);
> +      info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
> +				 ".byte\t");
> +      info->fprintf_styled_func (info->stream, dis_style_immediate,
> +				 "0x%02x", word);
>         break;
>       case 2:
> -      info->fprintf_func (info->stream, ".short\t0x%04x", word);
> +      info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
> +				 ".short\t");
> +      info->fprintf_styled_func (info->stream, dis_style_immediate,
> +				 "0x%04x", word);
>         break;
>       case 4:
> -      info->fprintf_func (info->stream, ".word\t0x%08x", word);
> +      info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
> +				 ".word\t");
> +      info->fprintf_styled_func (info->stream, dis_style_immediate,
> +				 "0x%08x", word);
>         break;
>       default:
>         abort ();
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 1c93f836020..4f38a3328d4 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -3043,13 +3043,13 @@ expand_fp_imm (int size, uint32_t imm8)
>      the register name that comes before the register number, such as "v".  */
>   static void
>   print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
> -		     const char *prefix)
> +		     const char *prefix, get_style_func get_style)
>   {
>     const int num_regs = opnd->reglist.num_regs;
>     const int first_reg = opnd->reglist.first_regno;
>     const int last_reg = (first_reg + num_regs - 1) & 0x1f;
>     const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
> -  char tb[8];	/* Temporary buffer.  */
> +  char tb[16];	/* Temporary buffer.  */
>   
>     assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
>     assert (num_regs >= 1 && num_regs <= 4);
> @@ -3057,7 +3057,9 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
>     /* Prepare the index if any.  */
>     if (opnd->reglist.has_index)
>       /* PR 21096: The %100 is to silence a warning about possible truncation.  */
> -    snprintf (tb, 8, "[%" PRIi64 "]", (opnd->reglist.index % 100));
> +    snprintf (tb, sizeof (tb), "%s[%s%" PRIi64 "%s]",
> +	      get_style (dis_style_text), get_style (dis_style_immediate),
> +	      (opnd->reglist.index % 100), get_style (dis_style_text));
>     else
>       tb[0] = '\0';
>   
> @@ -3065,8 +3067,11 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
>        more than two registers in the list, and the register numbers
>        are monotonically increasing in increments of one.  */
>     if (num_regs > 2 && last_reg > first_reg)
> -    snprintf (buf, size, "{%s%d.%s-%s%d.%s}%s", prefix, first_reg, qlf_name,
> -	      prefix, last_reg, qlf_name, tb);
> +    snprintf (buf, size, "%s{%s%s%d.%s%s-%s%s%d.%s%s}%s",
> +	      get_style (dis_style_text), get_style (dis_style_register),
> +	      prefix, first_reg, qlf_name, get_style (dis_style_text),
> +	      get_style (dis_style_register), prefix, last_reg, qlf_name,
> +	      get_style (dis_style_text), tb);
>     else
>       {
>         const int reg0 = first_reg;
> @@ -3077,21 +3082,40 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
>         switch (num_regs)
>   	{
>   	case 1:
> -	  snprintf (buf, size, "{%s%d.%s}%s", prefix, reg0, qlf_name, tb);
> +	  snprintf (buf, size, "%s{%s%s%d.%s%s}%s",
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg0, qlf_name,
> +		    get_style (dis_style_text), tb);
>   	  break;
>   	case 2:
> -	  snprintf (buf, size, "{%s%d.%s, %s%d.%s}%s", prefix, reg0, qlf_name,
> -		    prefix, reg1, qlf_name, tb);
> +	  snprintf (buf, size, "%s{%s%s%d.%s%s, %s%s%d.%s%s}%s",
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg0, qlf_name,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg1, qlf_name,
> +		    get_style (dis_style_text), tb);
>   	  break;
>   	case 3:
> -	  snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s}%s",
> -		    prefix, reg0, qlf_name, prefix, reg1, qlf_name,
> -		    prefix, reg2, qlf_name, tb);
> +	  snprintf (buf, size, "%s{%s%s%d.%s%s, %s%s%d.%s%s, %s%s%d.%s%s}%s",
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg0, qlf_name,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg1, qlf_name,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg2, qlf_name,
> +		    get_style (dis_style_text), tb);
>   	  break;
>   	case 4:
> -	  snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s, %s%d.%s}%s",
> -		    prefix, reg0, qlf_name, prefix, reg1, qlf_name,
> -		    prefix, reg2, qlf_name, prefix, reg3, qlf_name, tb);
> +	  snprintf (buf, size, "%s{%s%s%d.%s%s, %s%s%d.%s%s, %s%s%d.%s%s, %s%s%d.%s%s}%s",
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg0, qlf_name,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg1, qlf_name,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg2, qlf_name,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), prefix, reg3, qlf_name,
> +		    get_style (dis_style_text), tb);
>   	  break;
>   	}
>       }
> @@ -3103,32 +3127,53 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
>   static void
>   print_immediate_offset_address (char *buf, size_t size,
>   				const aarch64_opnd_info *opnd,
> -				const char *base)
> +				const char *base, get_style_func get_style)
>   {
>     if (opnd->addr.writeback)
>       {
>         if (opnd->addr.preind)
>           {
>   	  if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
> -            snprintf (buf, size, "[%s]!", base);
> +	    snprintf (buf, size, "%s[%s%s%s]!",
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_register), base,
> +		      get_style (dis_style_text));
>             else
> -	    snprintf (buf, size, "[%s, #%d]!", base, opnd->addr.offset.imm);
> +	    snprintf (buf, size, "%s[%s%s%s, %s#%d%s]!",
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_register), base,
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_immediate), opnd->addr.offset.imm,
> +		      get_style (dis_style_text));
>           }
>         else
> -	snprintf (buf, size, "[%s], #%d", base, opnd->addr.offset.imm);
> +	snprintf (buf, size, "%s[%s%s%s], %s#%d",
> +		  get_style (dis_style_text), get_style (dis_style_register),
> +		  base, get_style (dis_style_text),
> +		  get_style (dis_style_immediate), opnd->addr.offset.imm);
>       }
>     else
>       {
>         if (opnd->shifter.operator_present)
>   	{
>   	  assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
> -	  snprintf (buf, size, "[%s, #%d, mul vl]",
> -		    base, opnd->addr.offset.imm);
> +	  snprintf (buf, size, "%s[%s%s%s, %s#%d%s, mul vl]",
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_register), base,
> +		    get_style (dis_style_text),
> +		    get_style (dis_style_immediate), opnd->addr.offset.imm,
> +		    get_style (dis_style_text));
>   	}
>         else if (opnd->addr.offset.imm)
> -	snprintf (buf, size, "[%s, #%d]", base, opnd->addr.offset.imm);
> +	snprintf (buf, size, "%s[%s%s%s, %s#%d%s]",
> +		  get_style (dis_style_text), get_style (dis_style_register),
> +		  base, get_style (dis_style_text),
> +		  get_style (dis_style_immediate), opnd->addr.offset.imm,
> +		  get_style (dis_style_text));
>         else
> -	snprintf (buf, size, "[%s]", base);
> +	snprintf (buf, size, "%s[%s%s%s]", get_style (dis_style_text),
> +		  get_style (dis_style_register), base,
> +		  get_style (dis_style_text));
>       }
>   }
>   
> @@ -3138,9 +3183,10 @@ print_immediate_offset_address (char *buf, size_t size,
>   static void
>   print_register_offset_address (char *buf, size_t size,
>   			       const aarch64_opnd_info *opnd,
> -			       const char *base, const char *offset)
> +			       const char *base, const char *offset,
> +			       get_style_func get_style)
>   {
> -  char tb[16];			/* Temporary buffer.  */
> +  char tb[32];			/* Temporary buffer.  */
>     bool print_extend_p = true;
>     bool print_amount_p = true;
>     const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
> @@ -3161,16 +3207,23 @@ print_register_offset_address (char *buf, size_t size,
>     if (print_extend_p)
>       {
>         if (print_amount_p)
> -	snprintf (tb, sizeof (tb), ", %s #%" PRIi64, shift_name,
> +	snprintf (tb, sizeof (tb), ", %s%s %s#%" PRIi64,
> +		  get_style (dis_style_sub_mnemonic),
> +		  shift_name,
> +		  get_style (dis_style_immediate),
>     /* PR 21096: The %100 is to silence a warning about possible truncation.  */
>   		  (opnd->shifter.amount % 100));
>         else
> -	snprintf (tb, sizeof (tb), ", %s", shift_name);
> +	snprintf (tb, sizeof (tb), ", %s%s",
> +		  get_style (dis_style_sub_mnemonic), shift_name);
>       }
>     else
>       tb[0] = '\0';
>   
> -  snprintf (buf, size, "[%s, %s%s]", base, offset, tb);
> +  snprintf (buf, size, "%s[%s%s%s, %s%s%s%s]",
> +	    get_style (dis_style_text), get_style (dis_style_register),
> +	    base, get_style (dis_style_text), get_style (dis_style_register),
> +	    offset, get_style (dis_style_text), tb);
>   }
>   
>   /* Print ZA tiles from imm8 in ZERO instruction.
> @@ -3230,7 +3283,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   		       const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
>   		       bfd_vma *address, char** notes,
>   		       char *comment, size_t comment_size,
> -		       aarch64_feature_set features)
> +		       aarch64_feature_set features,
> +		       get_style_func get_style)
>   {
>     unsigned int i, num_conds;
>     const char *name = NULL;
> @@ -3278,7 +3332,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	break;
>         assert (opnd->qualifier == AARCH64_OPND_QLF_W
>   	      || opnd->qualifier == AARCH64_OPND_QLF_X);
> -      snprintf (buf, size, "%s",
> +      snprintf (buf, size, "%s%s",
> +		get_style (dis_style_register),
>   		get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
>         break;
>   
> @@ -3291,7 +3346,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	      || opnd->qualifier == AARCH64_OPND_QLF_WSP
>   	      || opnd->qualifier == AARCH64_OPND_QLF_X
>   	      || opnd->qualifier == AARCH64_OPND_QLF_SP);
> -      snprintf (buf, size, "%s",
> +      snprintf (buf, size, "%s%s",
> +		get_style (dis_style_register),
>   		get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
>         break;
>   
> @@ -3311,19 +3367,26 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	  if (opnd->shifter.amount == 0)
>   	    {
>   	      /* Shifter omitted.  */
> -	      snprintf (buf, size, "%s",
> +	      snprintf (buf, size, "%s%s",
> +			get_style (dis_style_register),
>   			get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
>   	      break;
>   	    }
>   	}
>         if (opnd->shifter.amount)
> -	snprintf (buf, size, "%s, %s #%" PRIi64,
> +	snprintf (buf, size, "%s%s%s, %s%s %s#%" PRIi64,
> +		  get_style (dis_style_register),
>   		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
> +		  get_style (dis_style_text),
> +		  get_style (dis_style_sub_mnemonic),
>   		  aarch64_operand_modifiers[kind].name,
> -		  opnd->shifter.amount);
> +		  get_style (dis_style_immediate), opnd->shifter.amount);
>         else
> -	snprintf (buf, size, "%s, %s",
> +	snprintf (buf, size, "%s%s%s, %s%s",
> +		  get_style (dis_style_register),
>   		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
> +		  get_style (dis_style_text),
> +		  get_style (dis_style_sub_mnemonic),
>   		  aarch64_operand_modifiers[kind].name);
>         break;
>   
> @@ -3331,13 +3394,17 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         assert (opnd->qualifier == AARCH64_OPND_QLF_W
>   	      || opnd->qualifier == AARCH64_OPND_QLF_X);
>         if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
> -	snprintf (buf, size, "%s",
> +	snprintf (buf, size, "%s%s",
> +		  get_style (dis_style_register),
>   		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
>         else
> -	snprintf (buf, size, "%s, %s #%" PRIi64,
> +	snprintf (buf, size, "%s%s%s, %s%s %s#%" PRIi64,
> +		  get_style (dis_style_register),
>   		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
> +		  get_style (dis_style_text),
> +		  get_style (dis_style_sub_mnemonic),
>   		  aarch64_operand_modifiers[opnd->shifter.kind].name,
> -		  opnd->shifter.amount);
> +		  get_style (dis_style_immediate), opnd->shifter.amount);
>         break;
>   
>       case AARCH64_OPND_Fd:
> @@ -3353,7 +3420,9 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_Vd:
>       case AARCH64_OPND_SVE_Vm:
>       case AARCH64_OPND_SVE_Vn:
> -      snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
> +      snprintf (buf, size, "%s%s%d",
> +		get_style (dis_style_register),
> +		aarch64_get_qualifier_name (opnd->qualifier),
>   		opnd->reg.regno);
>         break;
>   
> @@ -3361,7 +3430,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_Vd:
>       case AARCH64_OPND_Vn:
>       case AARCH64_OPND_Vm:
> -      snprintf (buf, size, "v%d.%s", opnd->reg.regno,
> +      snprintf (buf, size, "%sv%d.%s",
> +		get_style (dis_style_register), opnd->reg.regno,
>   		aarch64_get_qualifier_name (opnd->qualifier));
>         break;
>   
> @@ -3370,21 +3440,26 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_Em:
>       case AARCH64_OPND_Em16:
>       case AARCH64_OPND_SM3_IMM2:
> -      snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
> +      snprintf (buf, size, "%sv%d.%s%s[%s%" PRIi64 "%s]",
> +		get_style (dis_style_register), opnd->reglane.regno,
>   		aarch64_get_qualifier_name (opnd->qualifier),
> -		opnd->reglane.index);
> +		get_style (dis_style_text), get_style (dis_style_immediate),
> +		opnd->reglane.index, get_style (dis_style_text));
>         break;
>   
>       case AARCH64_OPND_VdD1:
>       case AARCH64_OPND_VnD1:
> -      snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
> +      snprintf (buf, size, "%sv%d.d%s[%s1%s]",
> +		get_style (dis_style_register), opnd->reg.regno,
> +		get_style (dis_style_text), get_style (dis_style_immediate),
> +		get_style (dis_style_text));
>         break;
>   
>       case AARCH64_OPND_LVn:
>       case AARCH64_OPND_LVt:
>       case AARCH64_OPND_LVt_AL:
>       case AARCH64_OPND_LEt:
> -      print_register_list (buf, size, opnd, "v");
> +      print_register_list (buf, size, opnd, "v", get_style);
>         break;
>   
>       case AARCH64_OPND_SVE_Pd:
> @@ -3397,13 +3472,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_Pt:
>       case AARCH64_OPND_SME_Pm:
>         if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
> -	snprintf (buf, size, "p%d", opnd->reg.regno);
> +	snprintf (buf, size, "%sp%d", get_style (dis_style_register),
> +		  opnd->reg.regno);
>         else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
>   	       || opnd->qualifier == AARCH64_OPND_QLF_P_M)
> -	snprintf (buf, size, "p%d/%s", opnd->reg.regno,
> +	snprintf (buf, size, "%sp%d/%s", get_style (dis_style_register),
> +		  opnd->reg.regno,
>   		  aarch64_get_qualifier_name (opnd->qualifier));
>         else
> -	snprintf (buf, size, "p%d.%s", opnd->reg.regno,
> +	snprintf (buf, size, "%sp%d.%s", get_style (dis_style_register),
> +		  opnd->reg.regno,
>   		  aarch64_get_qualifier_name (opnd->qualifier));
>         break;
>   
> @@ -3415,15 +3493,17 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_Zn:
>       case AARCH64_OPND_SVE_Zt:
>         if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
> -	snprintf (buf, size, "z%d", opnd->reg.regno);
> +	snprintf (buf, size, "%sz%d", get_style (dis_style_register),
> +		  opnd->reg.regno);
>         else
> -	snprintf (buf, size, "z%d.%s", opnd->reg.regno,
> +	snprintf (buf, size, "%sz%d.%s", get_style (dis_style_register),
> +		  opnd->reg.regno,
>   		  aarch64_get_qualifier_name (opnd->qualifier));
>         break;
>   
>       case AARCH64_OPND_SVE_ZnxN:
>       case AARCH64_OPND_SVE_ZtxN:
> -      print_register_list (buf, size, opnd, "z");
> +      print_register_list (buf, size, opnd, "z", get_style);
>         break;
>   
>       case AARCH64_OPND_SVE_Zm3_INDEX:
> @@ -3432,14 +3512,18 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_Zm4_11_INDEX:
>       case AARCH64_OPND_SVE_Zm4_INDEX:
>       case AARCH64_OPND_SVE_Zn_INDEX:
> -      snprintf (buf, size, "z%d.%s[%" PRIi64 "]", opnd->reglane.regno,
> +      snprintf (buf, size, "%sz%d.%s%s[%s%" PRIi64 "%s]",
> +		get_style (dis_style_register), opnd->reglane.regno,
>   		aarch64_get_qualifier_name (opnd->qualifier),
> -		opnd->reglane.index);
> +		get_style (dis_style_text),
> +		get_style (dis_style_immediate), opnd->reglane.index,
> +		get_style (dis_style_text));
>         break;
>   
>       case AARCH64_OPND_SME_ZAda_2b:
>       case AARCH64_OPND_SME_ZAda_3b:
> -      snprintf (buf, size, "za%d.%s", opnd->reg.regno,
> +      snprintf (buf, size, "%sza%d.%s", get_style (dis_style_register),
> +		opnd->reg.regno,
>                   aarch64_get_qualifier_name (opnd->qualifier));
>         break;
>   
> @@ -3467,7 +3551,9 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         break;
>   
>       case AARCH64_OPND_SME_SM_ZA:
> -      snprintf (buf, size, "%s", opnd->reg.regno == 's' ? "sm" : "za");
> +      snprintf (buf, size, "%s%s",
> +		get_style (dis_style_register),
> +		opnd->reg.regno == 's' ? "sm" : "za");
>         break;
>   
>       case AARCH64_OPND_SME_PnT_Wm_imm:
> @@ -3480,7 +3566,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   
>       case AARCH64_OPND_CRn:
>       case AARCH64_OPND_CRm:
> -      snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
> +      snprintf (buf, size, "%sC%" PRIi64, get_style (dis_style_register),
> +		opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_IDX:
> @@ -3521,7 +3608,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_IMM_ROT1:
>       case AARCH64_OPND_SVE_IMM_ROT2:
>       case AARCH64_OPND_SVE_IMM_ROT3:
> -      snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
> +      snprintf (buf, size, "%s#%" PRIi64, get_style (dis_style_immediate),
> +		opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_SVE_I1_HALF_ONE:
> @@ -3530,7 +3618,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         {
>   	single_conv_t c;
>   	c.i = opnd->imm.value;
> -	snprintf (buf, size, "#%.1f", c.f);
> +	snprintf (buf, size, "%s#%.1f", get_style (dis_style_immediate), c.f);
>   	break;
>         }
>   
> @@ -3541,9 +3629,11 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         enum_value = opnd->imm.value;
>         assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
>         if (aarch64_sve_pattern_array[enum_value])
> -	snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
> +	snprintf (buf, size, "%s%s", get_style (dis_style_register),
> +		  aarch64_sve_pattern_array[enum_value]);
>         else
> -	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
> +	snprintf (buf, size, "%s#%" PRIi64, get_style (dis_style_immediate),
> +		  opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_SVE_PATTERN_SCALED:
> @@ -3554,13 +3644,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         enum_value = opnd->imm.value;
>         assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
>         if (aarch64_sve_pattern_array[opnd->imm.value])
> -	snprintf (buf, size, "%s", aarch64_sve_pattern_array[opnd->imm.value]);
> +	snprintf (buf, size, "%s%s", get_style (dis_style_register),
> +		  aarch64_sve_pattern_array[opnd->imm.value]);
>         else
> -	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
> +	snprintf (buf, size, "%s#%" PRIi64, get_style (dis_style_immediate),
> +		  opnd->imm.value);
>         if (opnd->shifter.operator_present)
>   	{
>   	  size_t len = strlen (buf);
> -	  snprintf (buf + len, size - len, ", %s #%" PRIi64,
> +	  snprintf (buf + len, size - len, ", %s%s #%" PRIi64,
> +		    get_style (dis_style_sub_mnemonic),
>   		    aarch64_operand_modifiers[opnd->shifter.kind].name,
>   		    opnd->shifter.amount);
>   	}
> @@ -3570,9 +3663,11 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         enum_value = opnd->imm.value;
>         assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
>         if (aarch64_sve_prfop_array[enum_value])
> -	snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
> +	snprintf (buf, size, "%s%s", get_style (dis_style_register),
> +		  aarch64_sve_prfop_array[enum_value]);
>         else
> -	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
> +	snprintf (buf, size, "%s#%" PRIi64, get_style (dis_style_immediate),
> +		  opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_IMM_MOV:
> @@ -3581,12 +3676,14 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	case 4:	/* e.g. MOV Wd, #<imm32>.  */
>   	    {
>   	      int imm32 = opnd->imm.value;
> -	      snprintf (buf, size, "#0x%-20x", imm32);
> +	      snprintf (buf, size, "%s#0x%-20x",
> +			get_style (dis_style_immediate), imm32);
>   	      snprintf (comment, comment_size, "#%d", imm32);
>   	    }
>   	  break;
>   	case 8:	/* e.g. MOV Xd, #<imm64>.  */
> -	  snprintf (buf, size, "#0x%-20" PRIx64, opnd->imm.value);
> +	  snprintf (buf, size, "%s#0x%-20" PRIx64,
> +		    get_style (dis_style_immediate), opnd->imm.value);
>   	  snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
>   	  break;
>   	default:
> @@ -3596,7 +3693,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         break;
>   
>       case AARCH64_OPND_FPIMM0:
> -      snprintf (buf, size, "#0.0");
> +      snprintf (buf, size, "%s#0.0", get_style (dis_style_immediate));
>         break;
>   
>       case AARCH64_OPND_LIMM:
> @@ -3606,30 +3703,42 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_LIMM:
>       case AARCH64_OPND_SVE_LIMM_MOV:
>         if (opnd->shifter.amount)
> -	snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
> +	snprintf (buf, size, "%s#0x%" PRIx64 "%s, %slsl %s#%" PRIi64,
> +		  get_style (dis_style_immediate), opnd->imm.value,
> +		  get_style (dis_style_text),
> +		  get_style (dis_style_sub_mnemonic),
> +		  get_style (dis_style_immediate),
>   		  opnd->shifter.amount);
>         else
> -	snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
> +	snprintf (buf, size, "%s#0x%" PRIx64,
> +		  get_style (dis_style_immediate), opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_SIMD_IMM:
>       case AARCH64_OPND_SIMD_IMM_SFT:
>         if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
>   	  || opnd->shifter.kind == AARCH64_MOD_NONE)
> -	snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
> +	snprintf (buf, size, "%s#0x%" PRIx64,
> +		  get_style (dis_style_immediate), opnd->imm.value);
>         else
> -	snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
> +	snprintf (buf, size, "%s#0x%" PRIx64 "%s, %s%s %s#%" PRIi64,
> +		  get_style (dis_style_immediate), opnd->imm.value,
> +		  get_style (dis_style_text),
> +		  get_style (dis_style_sub_mnemonic),
>   		  aarch64_operand_modifiers[opnd->shifter.kind].name,
> -		  opnd->shifter.amount);
> +		  get_style (dis_style_immediate), opnd->shifter.amount);
>         break;
>   
>       case AARCH64_OPND_SVE_AIMM:
>       case AARCH64_OPND_SVE_ASIMM:
>         if (opnd->shifter.amount)
> -	snprintf (buf, size, "#%" PRIi64 ", lsl #%" PRIi64, opnd->imm.value,
> +	snprintf (buf, size, "%s#%" PRIi64 "%s, lsl %s#%" PRIi64,
> +		  get_style (dis_style_immediate), opnd->imm.value,
> +		  get_style (dis_style_text), get_style (dis_style_immediate),
>   		  opnd->shifter.amount);
>         else
> -	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
> +	snprintf (buf, size, "%s#%" PRIi64, get_style (dis_style_immediate),
> +		  opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_FPIMM:
> @@ -3641,21 +3750,24 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	    {
>   	      half_conv_t c;
>   	      c.i = expand_fp_imm (2, opnd->imm.value);
> -	      snprintf (buf, size,  "#%.18e", c.f);
> +	      snprintf (buf, size,  "%s#%.18e",
> +			get_style (dis_style_immediate), c.f);
>   	    }
>   	  break;
>   	case 4:	/* e.g. FMOV <Vd>.4S, #<imm>.  */
>   	    {
>   	      single_conv_t c;
>   	      c.i = expand_fp_imm (4, opnd->imm.value);
> -	      snprintf (buf, size,  "#%.18e", c.f);
> +	      snprintf (buf, size,  "%s#%.18e",
> +			get_style (dis_style_immediate), c.f);
>   	    }
>   	  break;
>   	case 8:	/* e.g. FMOV <Sd>, #<imm>.  */
>   	    {
>   	      double_conv_t c;
>   	      c.i = expand_fp_imm (8, opnd->imm.value);
> -	      snprintf (buf, size,  "#%.18e", c.d);
> +	      snprintf (buf, size,  "%s#%.18e",
> +			get_style (dis_style_immediate), c.d);
>   	    }
>   	  break;
>   	default:
> @@ -3676,12 +3788,14 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	      (int64_t) get_optional_operand_default_value (opcode)))
>   	/* Omit the operand, e.g. DCPS1.  */
>   	break;
> -      snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
> +      snprintf (buf, size, "%s#0x%x", get_style (dis_style_immediate),
> +		(unsigned int)opnd->imm.value);
>         break;
>   
>       case AARCH64_OPND_COND:
>       case AARCH64_OPND_COND1:
> -      snprintf (buf, size, "%s", opnd->cond->names[0]);
> +      snprintf (buf, size, "%s%s", get_style (dis_style_sub_mnemonic),
> +		opnd->cond->names[0]);
>         num_conds = ARRAY_SIZE (opnd->cond->names);
>         for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
>   	{
> @@ -3706,7 +3820,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	 in the disassemble_info will take care of the printing.  But some
>   	 other callers may be still interested in getting the string in *STR,
>   	 so here we do snprintf regardless.  */
> -      snprintf (buf, size, "#0x%" PRIx64, addr);
> +      snprintf (buf, size, "%s#0x%" PRIx64,
> +		get_style (dis_style_address), addr);
>         break;
>   
>       case AARCH64_OPND_ADDR_PCREL14:
> @@ -3722,7 +3837,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	 in the disassemble_info will take care of the printing.  But some
>   	 other callers may be still interested in getting the string in *STR,
>   	 so here we do snprintf regardless.  */
> -      snprintf (buf, size, "#0x%" PRIx64, addr);
> +      snprintf (buf, size, "%s#0x%" PRIx64, get_style (dis_style_address),
> +		addr);
>         break;
>   
>       case AARCH64_OPND_ADDR_SIMPLE:
> @@ -3732,12 +3848,24 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
>   	{
>   	  if (opnd->addr.offset.is_reg)
> -	    snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
> +	    snprintf (buf, size, "%s[%s%s%s], %sx%d",
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_register), name,
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_register),
> +		      opnd->addr.offset.regno);
>   	  else
> -	    snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
> +	    snprintf (buf, size, "%s[%s%s%s], %s#%d",
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_register), name,
> +		      get_style (dis_style_text),
> +		      get_style (dis_style_immediate),
> +		      opnd->addr.offset.imm);
>   	}
>         else
> -	snprintf (buf, size, "[%s]", name);
> +	snprintf (buf, size, "%s[%s%s%s]",
> +		  get_style (dis_style_text), get_style (dis_style_register),
> +		  name, get_style (dis_style_text));
>         break;
>   
>       case AARCH64_OPND_ADDR_REGOFF:
> @@ -3753,14 +3881,14 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_ADDR_RX_LSL3:
>         print_register_offset_address
>   	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
> -	 get_offset_int_reg_name (opnd));
> +	 get_offset_int_reg_name (opnd), get_style);
>         break;
>   
>       case AARCH64_OPND_SVE_ADDR_ZX:
>         print_register_offset_address
>   	(buf, size, opnd,
>   	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
> -	 get_64bit_int_reg_name (opnd->addr.offset.regno, 0));
> +	 get_64bit_int_reg_name (opnd->addr.offset.regno, 0), get_style);
>         break;
>   
>       case AARCH64_OPND_SVE_ADDR_RZ:
> @@ -3777,7 +3905,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
>         print_register_offset_address
>   	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
> -	 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
> +	 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
> +	 get_style);
>         break;
>   
>       case AARCH64_OPND_ADDR_SIMM7:
> @@ -3801,7 +3930,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_ADDR_RI_U6x4:
>       case AARCH64_OPND_SVE_ADDR_RI_U6x8:
>         print_immediate_offset_address
> -	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
> +	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
> +	 get_style);
>         break;
>   
>       case AARCH64_OPND_SVE_ADDR_ZI_U5:
> @@ -3810,7 +3940,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
>         print_immediate_offset_address
>   	(buf, size, opnd,
> -	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier));
> +	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
> +	 get_style);
>         break;
>   
>       case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
> @@ -3819,15 +3950,22 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         print_register_offset_address
>   	(buf, size, opnd,
>   	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
> -	 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
> +	 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
> +	 get_style);
>         break;
>   
>       case AARCH64_OPND_ADDR_UIMM12:
>         name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
>         if (opnd->addr.offset.imm)
> -	snprintf (buf, size, "[%s, #%d]", name, opnd->addr.offset.imm);
> +	snprintf (buf, size, "%s[%s%s%s, %s#%d%s]",
> +		  get_style (dis_style_text), get_style (dis_style_register),
> +		  name, get_style (dis_style_text),
> +		  get_style (dis_style_immediate), opnd->addr.offset.imm,
> +		  get_style (dis_style_text));
>         else
> -	snprintf (buf, size, "[%s]", name);
> +	snprintf (buf, size, "%s[%s%s%s]", get_style (dis_style_text),
> +		  get_style (dis_style_register), name,
> +		  get_style (dis_style_text));
>         break;
>   
>       case AARCH64_OPND_SYSREG:
> @@ -3866,14 +4004,15 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>   	}
>   
>         if (name)
> -	snprintf (buf, size, "%s", name);
> +	snprintf (buf, size, "%s%s", get_style (dis_style_register), name);
>         else
>   	{
>   	  /* Implementation defined system register.  */
>   	  unsigned int value = opnd->sysreg.value;
> -	  snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
> -		    (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
> -		    value & 0x7);
> +	  snprintf (buf, size, "%ss%u_%u_c%u_c%u_%u",
> +		    get_style (dis_style_register), (value >> 14) & 0x3,
> +		    (value >> 11) & 0x7, (value >> 7) & 0xf,
> +		    (value >> 3) & 0xf, value & 0x7);
>   	}
>         break;
>   
> @@ -3899,12 +4038,21 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>       case AARCH64_OPND_SYSREG_IC:
>       case AARCH64_OPND_SYSREG_TLBI:
>       case AARCH64_OPND_SYSREG_SR:
> -      snprintf (buf, size, "%s", opnd->sysins_op->name);
> +      snprintf (buf, size, "%s%s", get_style (dis_style_register),
> +		opnd->sysins_op->name);
>         break;
>   
>       case AARCH64_OPND_BARRIER:
>       case AARCH64_OPND_BARRIER_DSB_NXS:
> -      snprintf (buf, size, "%s", opnd->barrier->name);
> +      {
> +	enum disassembler_style style;
> +	if (opnd->barrier->name[0] == '#')
> +	  style = dis_style_immediate;
> +	else
> +	  style = dis_style_sub_mnemonic;
> +	snprintf (buf, size, "%s%s", get_style (style),
> +		  opnd->barrier->name);
> +      }
>         break;
>   
>       case AARCH64_OPND_BARRIER_ISB:
> @@ -3912,38 +4060,46 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>         if (! optional_operand_p (opcode, idx)
>   	  || (opnd->barrier->value
>   	      != get_optional_operand_default_value (opcode)))
> -	snprintf (buf, size, "#0x%x", opnd->barrier->value);
> +	snprintf (buf, size, "%s#0x%x", get_style (dis_style_immediate),
> +		  opnd->barrier->value);
>         break;
>   
>       case AARCH64_OPND_PRFOP:
>         if (opnd->prfop->name != NULL)
> -	snprintf (buf, size, "%s", opnd->prfop->name);
> +	snprintf (buf, size, "%s%s", get_style (dis_style_sub_mnemonic),
> +		  opnd->prfop->name);
>         else
> -	snprintf (buf, size, "#0x%02x", opnd->prfop->value);
> +	snprintf (buf, size, "%s#0x%02x", get_style (dis_style_immediate),
> +		  opnd->prfop->value);
>         break;
>   
>       case AARCH64_OPND_BARRIER_PSB:
> -      snprintf (buf, size, "csync");
> +      snprintf (buf, size, "%scsync", get_style (dis_style_sub_mnemonic));
>         break;
>   
>       case AARCH64_OPND_BTI_TARGET:
>         if ((HINT_FLAG (opnd->hint_option->value) & HINT_OPD_F_NOPRINT) == 0)
> -	snprintf (buf, size, "%s", opnd->hint_option->name);
> +	snprintf (buf, size, "%s%s", get_style (dis_style_sub_mnemonic),
> +		  opnd->hint_option->name);
>         break;
>   
>       case AARCH64_OPND_MOPS_ADDR_Rd:
>       case AARCH64_OPND_MOPS_ADDR_Rs:
> -      snprintf (buf, size, "[%s]!",
> -		get_int_reg_name (opnd->reg.regno, AARCH64_OPND_QLF_X, 0));
> +      snprintf (buf, size, "%s[%s%s%s]!",
> +		get_style (dis_style_text), get_style (dis_style_register),
> +		get_int_reg_name (opnd->reg.regno, AARCH64_OPND_QLF_X, 0),
> +		get_style (dis_style_text));
>         break;
>   
>       case AARCH64_OPND_MOPS_WB_Rn:
> -      snprintf (buf, size, "%s!",
> -		get_int_reg_name (opnd->reg.regno, AARCH64_OPND_QLF_X, 0));
> +      snprintf (buf, size, "%s%s%s!",
> +		get_style (dis_style_register),
> +		get_int_reg_name (opnd->reg.regno, AARCH64_OPND_QLF_X, 0),
> +		get_style (dis_style_text));
>         break;
>   
>       default:
> -      snprintf (buf, size, "<invalid>");
> +      snprintf (buf, size, "%s<invalid>", get_style (dis_style_text));
>         break;
>       }
>   }
> 

  reply	other threads:[~2022-07-05 13:10 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-21 11:22 [PATCH 0/2] AArch64 libopcodes styling Andrew Burgess
2022-06-21 11:22 ` [PATCH 1/2] opcodes/aarch64: split off creation of comment text in disassembler Andrew Burgess
2022-06-22 11:02   ` Nick Clifton
2022-06-29 11:19     ` Andrew Burgess
2022-06-21 11:22 ` [PATCH 2/2] libopcodes/aarch64: add support for disassembler styling Andrew Burgess
2022-06-22 11:15   ` Nick Clifton
2022-06-29 11:01     ` Andrew Burgess
2022-06-29 11:12       ` Jan Beulich
2022-06-29 12:36   ` Richard Earnshaw
2022-07-04  9:52   ` Nick Clifton
2022-07-05 12:45 ` [PATCHv2 0/2] AArch64 libopcodes styling Andrew Burgess
2022-07-05 12:46   ` [PATCHv2 1/2] opcodes: add new sub-mnemonic disassembler style Andrew Burgess
2022-07-05 12:46   ` [PATCHv2 2/2] libopcodes/aarch64: add support for disassembler styling Andrew Burgess
2022-07-05 12:51     ` Andrew Burgess
2022-07-05 13:10       ` Richard Earnshaw [this message]
2022-07-07 10:23         ` [PATCHv3 0/2] AArch64 libopcodes styling Andrew Burgess
2022-07-07 10:23           ` [PATCHv3 1/2] opcodes: add new sub-mnemonic disassembler style Andrew Burgess
2022-07-07 10:23           ` [PATCHv3 2/2] libopcodes/aarch64: add support for disassembler styling Andrew Burgess
2022-07-07 10:44             ` Andrew Burgess
2022-07-08 10:25           ` [PATCHv4 0/2] AArch64 libopcodes styling Andrew Burgess
2022-07-08 10:25             ` [PATCHv4 1/2] opcodes: add new sub-mnemonic disassembler style Andrew Burgess
2022-07-26 13:54               ` Nick Clifton
2022-07-08 10:25             ` [PATCHv4 2/2] libopcodes/aarch64: add support for disassembler styling Andrew Burgess
2022-07-19 15:33               ` Richard Earnshaw
2022-07-21  8:56                 ` [PATCHv5 0/2] AArch64 libopcodes styling Andrew Burgess
2022-07-21  8:56                   ` [PATCHv5 1/2] opcodes: add new sub-mnemonic disassembler style Andrew Burgess
2022-07-25 13:34                     ` Andrew Burgess
2022-07-21  8:56                   ` [PATCHv5 2/2] libopcodes/aarch64: add support for disassembler styling Andrew Burgess
2022-07-26 13:55                     ` Nick Clifton
2022-07-29 13:12                       ` Andrew Burgess
2022-07-19 12:52             ` [PATCHv4 0/2] AArch64 libopcodes styling Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fd6ec2f8-4293-0d76-dd13-e54004dba441@foss.arm.com \
    --to=richard.earnshaw@foss.arm.com \
    --cc=aburgess@redhat.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).