public inbox for binutils-cvs@sourceware.org
help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@sourceware.org>
To: bfd-cvs@sourceware.org
Subject: [binutils-gdb] libopcodes/aarch64: add support for disassembler styling
Date: Fri, 29 Jul 2022 13:04:06 +0000 (GMT)	[thread overview]
Message-ID: <20220729130406.720CF3857C69@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=76a4c1e063fabb45d15597a6dd17813e92875a43

commit 76a4c1e063fabb45d15597a6dd17813e92875a43
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 structure, the
    structure contains a callback function and some state.
    
    When aarch64_print_operand needs to format part of its output this can
    be done by using the callback function within the new structure, this
    callback returns a string with special embedded markers that indicate
    which mode should be used for each piece of text.  Back in
    aarch64-dis.c we can spot these special style markers and use this to
    split the disassembler output up and apply the correct style to each
    piece.
    
    To make aarch64-opc.c clearer a series of new static functions have
    been added, e.g. 'style_reg', 'style_imm', etc.  Each of these
    functions formats a piece of text in a different style, 'register' and
    'immediate' in this case.
    
    Here's an example taken from aarch64-opc.c of the new functions in
    use:
    
        snprintf (buf, size, "[%s, %s]!",
                  style_reg (styler, base),
                  style_imm (styler, "#%d", opnd->addr.offset.imm));
    
    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, the callback function
    used in the assembler ignores the styling information and just returns
    an plain string.
    
    I've used the source files in gas/testsuite/gas/aarch64/ for testing,
    and have manually gone through and checked that the styling looks
    reasonable, however, I'm not an AArch64 expert, so it is possible that
    the odd piece is styled incorrectly.  Please point out any mistakes
    I've made.
    
    With objdump disassembler color turned off, there should be no change
    in the output after this commit.

Diff:
---
 gas/config/tc-aarch64.c  |  45 ++++-
 include/opcode/aarch64.h |  28 ++-
 opcodes/aarch64-dis.c    | 247 ++++++++++++++++++++++----
 opcodes/aarch64-opc.c    | 445 ++++++++++++++++++++++++++++++++---------------
 opcodes/disassemble.c    |   1 +
 5 files changed, 587 insertions(+), 179 deletions(-)

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index e12b68ed2c8..f023e5b0a28 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -5324,6 +5324,41 @@ assign_qualifier_sequence (aarch64_inst *instr,
     instr->operands[i].qualifier = *qualifiers;
 }
 
+/* Callback used by aarch64_print_operand to apply STYLE to the
+   disassembler output created from FMT and ARGS.  The STYLER object holds
+   any required state.  Must return a pointer to a string (created from FMT
+   and ARGS) that will continue to be valid until the complete disassembled
+   instruction has been printed.
+
+   We don't currently add any styling to the output of the disassembler as
+   used within assembler error messages, and so STYLE is ignored here.  A
+   new string is allocated on the obstack help within STYLER and returned
+   to the caller.  */
+
+static const char *aarch64_apply_style
+	(struct aarch64_styler *styler,
+	 enum disassembler_style style ATTRIBUTE_UNUSED,
+	 const char *fmt, va_list args)
+{
+  int res;
+  char *ptr;
+  struct obstack *stack = (struct obstack *) styler->state;
+  va_list ap;
+
+  /* Calculate the required space.  */
+  va_copy (ap, args);
+  res = vsnprintf (NULL, 0, fmt, ap);
+  va_end (ap);
+  gas_assert (res >= 0);
+
+  /* Allocate space on the obstack and format the result.  */
+  ptr = (char *) obstack_alloc (stack, res + 1);
+  res = vsnprintf (ptr, (res + 1), fmt, args);
+  gas_assert (res >= 0);
+
+  return ptr;
+}
+
 /* Print operands for the diagnosis purpose.  */
 
 static void
@@ -5331,6 +5366,12 @@ print_operands (char *buf, const aarch64_opcode *opcode,
 		const aarch64_opnd_info *opnds)
 {
   int i;
+  struct aarch64_styler styler;
+  struct obstack content;
+  obstack_init (&content);
+
+  styler.apply_style = aarch64_apply_style;
+  styler.state = (void *) &content;
 
   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
     {
@@ -5348,7 +5389,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, &styler);
 
       /* Delimiter.  */
       if (str[0] != '\0')
@@ -5366,6 +5407,8 @@ print_operands (char *buf, const aarch64_opcode *opcode,
 	  strcat (buf, cmt);
 	}
     }
+
+  obstack_free (&content, NULL);
 }
 
 /* Send to stderr a string as information.  */
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 186ba9a4800..9477ac98f3b 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,36 @@ aarch64_replace_opcode (struct aarch64_inst *,
 extern const aarch64_opcode *
 aarch64_get_opcode (enum aarch64_op);
 
+/* An instance of this structure is passed to aarch64_print_operand, and
+   the callback within this structure is used to apply styling to the
+   disassembler output.  This structure encapsulates the callback and a
+   state pointer.  */
+
+struct aarch64_styler
+{
+  /* The callback used to apply styling.  Returns a string created from FMT
+     and ARGS with STYLE applied to the string.  STYLER is a pointer back
+     to this object so that the callback can access the state member.
+
+     The string returned from this callback must remain valid until the
+     call to aarch64_print_operand has completed.  */
+  const char *(*apply_style) (struct aarch64_styler *styler,
+			      enum disassembler_style style,
+			      const char *fmt,
+			      va_list args);
+
+  /* A pointer to a state object which can be used by the apply_style
+     callback function.  */
+  void *state;
+};
+
 /* 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,
+		       struct aarch64_styler *styler);
 
 /* Miscellaneous interface.  */
 
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index acaad28fdff..9e98f0d2f20 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -25,9 +25,18 @@
 #include "opintl.h"
 #include "aarch64-dis.h"
 #include "elf-bfd.h"
+#include "safe-ctype.h"
+#include "obstack.h"
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
 
 #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 +3284,90 @@ aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
   return ERR_UND;
 }
 
+/* Return a short string to indicate a switch to STYLE.  These strings
+   will be embedded into the disassembled operand text (as produced by
+   aarch64_print_operand), and then spotted in the print_operands function
+   so that the disassembler output can be split by 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];
+}
+
+/* Callback used by aarch64_print_operand to apply STYLE to the
+   disassembler output created from FMT and ARGS.  The STYLER object holds
+   any required state.  Must return a pointer to a string (created from FMT
+   and ARGS) that will continue to be valid until the complete disassembled
+   instruction has been printed.
+
+   We return a string that includes two embedded style markers, the first,
+   places at the start of the string, indicates a switch to STYLE, and the
+   second, placed at the end of the string, indicates a switch back to the
+   default text style.
+
+   Later, when we print the operand text we take care to collapse any
+   adjacent style markers, and to ignore any style markers that appear at
+   the very end of a complete operand string.  */
+
+static const char *aarch64_apply_style (struct aarch64_styler *styler,
+					enum disassembler_style style,
+					const char *fmt,
+					va_list args)
+{
+  int res;
+  char *ptr, *tmp;
+  struct obstack *stack = (struct obstack *) styler->state;
+  va_list ap;
+
+  /* These are the two strings for switching styles.  */
+  const char *style_on = get_style_text (style);
+  const char *style_off = get_style_text (dis_style_text);
+
+  /* Calculate space needed once FMT and ARGS are expanded.  */
+  va_copy (ap, args);
+  res = vsnprintf (NULL, 0, fmt, ap);
+  va_end (ap);
+  assert (res >= 0);
+
+  /* Allocate space on the obstack for the expanded FMT and ARGS, as well
+     as the two strings for switching styles, then write all of these
+     strings onto the obstack.  */
+  ptr = (char *) obstack_alloc (stack, res + strlen (style_on)
+				+ strlen (style_off) + 1);
+  tmp = stpcpy (ptr, style_on);
+  res = vsnprintf (tmp, (res + 1), fmt, args);
+  assert (res >= 0);
+  tmp += res;
+  strcpy (tmp, style_off);
+
+  return ptr;
+}
+
 /* Print operands.  */
 
 static void
@@ -3284,6 +3377,13 @@ print_operands (bfd_vma pc, const aarch64_opcode *opcode,
 {
   char *notes = NULL;
   int i, pcrel_p, num_printed;
+  struct aarch64_styler styler;
+  struct obstack content;
+  obstack_init (&content);
+
+  styler.apply_style = aarch64_apply_style;
+  styler.state = (void *) &content;
+
   for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
     {
       char str[128];
@@ -3301,33 +3401,97 @@ 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, &styler);
 
       /* 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;
+		  if (len > 0)
+		    {
+		      if ((*info->fprintf_styled_func) (info->stream,
+							curr_style,
+							"%.*s",
+							len, start) < 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);
       }
+
+    obstack_free (&content, NULL);
 }
 
 /* Set NAME to a copy of INST's mnemonic with the "." suffix removed.  */
@@ -3359,10 +3523,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 +3545,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 +3565,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 +3680,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 +3728,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..1d4668a3fbd 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -3038,18 +3038,78 @@ expand_fp_imm (int size, uint32_t imm8)
   return imm;
 }
 
+/* Return a string based on FMT with the register style applied.  */
+
+static const char *
+style_reg (struct aarch64_styler *styler, const char *fmt, ...)
+{
+  const char *txt;
+  va_list ap;
+
+  va_start (ap, fmt);
+  txt = styler->apply_style (styler, dis_style_register, fmt, ap);
+  va_end (ap);
+
+  return txt;
+}
+
+/* Return a string based on FMT with the immediate style applied.  */
+
+static const char *
+style_imm (struct aarch64_styler *styler, const char *fmt, ...)
+{
+  const char *txt;
+  va_list ap;
+
+  va_start (ap, fmt);
+  txt = styler->apply_style (styler, dis_style_immediate, fmt, ap);
+  va_end (ap);
+
+  return txt;
+}
+
+/* Return a string based on FMT with the sub-mnemonic style applied.  */
+
+static const char *
+style_sub_mnem (struct aarch64_styler *styler, const char *fmt, ...)
+{
+  const char *txt;
+  va_list ap;
+
+  va_start (ap, fmt);
+  txt = styler->apply_style (styler, dis_style_sub_mnemonic, fmt, ap);
+  va_end (ap);
+
+  return txt;
+}
+
+/* Return a string based on FMT with the address style applied.  */
+
+static const char *
+style_addr (struct aarch64_styler *styler, const char *fmt, ...)
+{
+  const char *txt;
+  va_list ap;
+
+  va_start (ap, fmt);
+  txt = styler->apply_style (styler, dis_style_address, fmt, ap);
+  va_end (ap);
+
+  return txt;
+}
+
 /* Produce the string representation of the register list operand *OPND
    in the buffer pointed by BUF of size SIZE.  PREFIX is the part of
    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, struct aarch64_styler *styler)
 {
   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 +3117,8 @@ 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]",
+	      style_imm (styler, "%" PRIi64, (opnd->reglist.index % 100)));
   else
     tb[0] = '\0';
 
@@ -3065,8 +3126,9 @@ 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",
+	      style_reg (styler, "%s%d.%s", prefix, first_reg, qlf_name),
+	      style_reg (styler, "%s%d.%s", prefix, last_reg, qlf_name), tb);
   else
     {
       const int reg0 = first_reg;
@@ -3077,21 +3139,30 @@ 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",
+		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
+		    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",
+		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
+		    style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
+		    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}%s",
+		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
+		    style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
+		    style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
+		    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, %s}%s",
+		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
+		    style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
+		    style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
+		    style_reg (styler, "%s%d.%s", prefix, reg3, qlf_name),
+		    tb);
 	  break;
 	}
     }
@@ -3103,32 +3174,41 @@ 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,
+				struct aarch64_styler *styler)
 {
   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]!", style_reg (styler, base));
           else
-	    snprintf (buf, size, "[%s, #%d]!", base, opnd->addr.offset.imm);
+	    snprintf (buf, size, "[%s, %s]!",
+		      style_reg (styler, base),
+		      style_imm (styler, "#%d", opnd->addr.offset.imm));
         }
       else
-	snprintf (buf, size, "[%s], #%d", base, opnd->addr.offset.imm);
+	snprintf (buf, size, "[%s], %s",
+		  style_reg (styler, base),
+		  style_imm (styler, "#%d", 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]",
+		    style_reg (styler, base),
+		    style_imm (styler, "#%d", opnd->addr.offset.imm),
+		    style_sub_mnem (styler, "mul vl"));
 	}
       else if (opnd->addr.offset.imm)
-	snprintf (buf, size, "[%s, #%d]", base, opnd->addr.offset.imm);
+	snprintf (buf, size, "[%s, %s]",
+		  style_reg (styler, base),
+		  style_imm (styler, "#%d", opnd->addr.offset.imm));
       else
-	snprintf (buf, size, "[%s]", base);
+	snprintf (buf, size, "[%s]", style_reg (styler, base));
     }
 }
 
@@ -3138,9 +3218,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,
+			       struct aarch64_styler *styler)
 {
-  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 +3242,20 @@ 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",
+		  style_sub_mnem (styler, shift_name),
+		  style_imm (styler, "#%" PRIi64,
   /* PR 21096: The %100 is to silence a warning about possible truncation.  */
-		  (opnd->shifter.amount % 100));
+			     (opnd->shifter.amount % 100)));
       else
-	snprintf (tb, sizeof (tb), ", %s", shift_name);
+	snprintf (tb, sizeof (tb), ", %s",
+		  style_sub_mnem (styler, shift_name));
     }
   else
     tb[0] = '\0';
 
-  snprintf (buf, size, "[%s, %s%s]", base, offset, tb);
+  snprintf (buf, size, "[%s, %s%s]", style_reg (styler, base),
+	    style_reg (styler, offset), tb);
 }
 
 /* Print ZA tiles from imm8 in ZERO instruction.
@@ -3183,7 +3268,8 @@ print_register_offset_address (char *buf, size_t size,
     * An all-zeros immediate is disassembled as an empty list { }.
 */
 static void
-print_sme_za_list(char *buf, size_t size, int mask)
+print_sme_za_list (char *buf, size_t size, int mask,
+		   struct aarch64_styler *styler)
 {
   const char* zan[] = { "za",    "za0.h", "za1.h", "za0.s",
                         "za1.s", "za2.s", "za3.s", "za0.d",
@@ -3203,9 +3289,9 @@ print_sme_za_list(char *buf, size_t size, int mask)
         {
           mask &= ~zan_v[i];
           if (k > 1)
-            k += snprintf (buf + k, size - k, ", %s", zan[i]);
-          else
-            k += snprintf (buf + k, size - k, "%s", zan[i]);
+	    k += snprintf (buf + k, size - k, ", ");
+
+	  k += snprintf (buf + k, size - k, "%s", style_reg (styler, zan[i]));
         }
       if (mask == 0)
         break;
@@ -3230,7 +3316,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,
+		       struct aarch64_styler *styler)
 {
   unsigned int i, num_conds;
   const char *name = NULL;
@@ -3279,7 +3366,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
       assert (opnd->qualifier == AARCH64_OPND_QLF_W
 	      || opnd->qualifier == AARCH64_OPND_QLF_X);
       snprintf (buf, size, "%s",
-		get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
+		style_reg (styler, get_int_reg_name (opnd->reg.regno,
+						     opnd->qualifier, 0)));
       break;
 
     case AARCH64_OPND_Rd_SP:
@@ -3292,7 +3380,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 	      || opnd->qualifier == AARCH64_OPND_QLF_X
 	      || opnd->qualifier == AARCH64_OPND_QLF_SP);
       snprintf (buf, size, "%s",
-		get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
+		style_reg (styler, get_int_reg_name (opnd->reg.regno,
+						     opnd->qualifier, 1)));
       break;
 
     case AARCH64_OPND_Rm_EXT:
@@ -3312,19 +3401,21 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 	    {
 	      /* Shifter omitted.  */
 	      snprintf (buf, size, "%s",
-			get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
+			style_reg (styler,
+				   get_int_reg_name (opnd->reg.regno,
+						     opnd->qualifier, 0)));
 	      break;
 	    }
 	}
       if (opnd->shifter.amount)
-	snprintf (buf, size, "%s, %s #%" PRIi64,
-		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
-		  aarch64_operand_modifiers[kind].name,
-		  opnd->shifter.amount);
+	snprintf (buf, size, "%s, %s %s",
+		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
+		  style_sub_mnem (styler, aarch64_operand_modifiers[kind].name),
+		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
       else
 	snprintf (buf, size, "%s, %s",
-		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
-		  aarch64_operand_modifiers[kind].name);
+		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
+		  style_sub_mnem (styler, aarch64_operand_modifiers[kind].name));
       break;
 
     case AARCH64_OPND_Rm_SFT:
@@ -3332,12 +3423,13 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 	      || opnd->qualifier == AARCH64_OPND_QLF_X);
       if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
 	snprintf (buf, size, "%s",
-		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
+		  style_reg (styler, get_int_reg_name (opnd->reg.regno,
+						       opnd->qualifier, 0)));
       else
-	snprintf (buf, size, "%s, %s #%" PRIi64,
-		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
-		  aarch64_operand_modifiers[opnd->shifter.kind].name,
-		  opnd->shifter.amount);
+	snprintf (buf, size, "%s, %s %s",
+		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
+		  style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
+		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
       break;
 
     case AARCH64_OPND_Fd:
@@ -3353,16 +3445,19 @@ 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),
-		opnd->reg.regno);
+      snprintf (buf, size, "%s",
+		style_reg (styler, "%s%d",
+			   aarch64_get_qualifier_name (opnd->qualifier),
+			   opnd->reg.regno));
       break;
 
     case AARCH64_OPND_Va:
     case AARCH64_OPND_Vd:
     case AARCH64_OPND_Vn:
     case AARCH64_OPND_Vm:
-      snprintf (buf, size, "v%d.%s", opnd->reg.regno,
-		aarch64_get_qualifier_name (opnd->qualifier));
+      snprintf (buf, size, "%s",
+		style_reg (styler, "v%d.%s", opnd->reg.regno,
+			   aarch64_get_qualifier_name (opnd->qualifier)));
       break;
 
     case AARCH64_OPND_Ed:
@@ -3370,21 +3465,24 @@ 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,
-		aarch64_get_qualifier_name (opnd->qualifier),
-		opnd->reglane.index);
+      snprintf (buf, size, "%s[%s]",
+		style_reg (styler, "v%d.%s", opnd->reglane.regno,
+			   aarch64_get_qualifier_name (opnd->qualifier)),
+		style_imm (styler, "%" PRIi64, opnd->reglane.index));
       break;
 
     case AARCH64_OPND_VdD1:
     case AARCH64_OPND_VnD1:
-      snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
+      snprintf (buf, size, "%s[%s]",
+		style_reg (styler, "v%d.d", opnd->reg.regno),
+		style_imm (styler, "1"));
       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", styler);
       break;
 
     case AARCH64_OPND_SVE_Pd:
@@ -3397,14 +3495,17 @@ 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, "%s",
+		  style_reg (styler, "p%d", 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,
-		  aarch64_get_qualifier_name (opnd->qualifier));
+	snprintf (buf, size, "%s",
+		  style_reg (styler, "p%d/%s", opnd->reg.regno,
+			     aarch64_get_qualifier_name (opnd->qualifier)));
       else
-	snprintf (buf, size, "p%d.%s", opnd->reg.regno,
-		  aarch64_get_qualifier_name (opnd->qualifier));
+	snprintf (buf, size, "%s",
+		  style_reg (styler, "p%d.%s", opnd->reg.regno,
+			     aarch64_get_qualifier_name (opnd->qualifier)));
       break;
 
     case AARCH64_OPND_SVE_Za_5:
@@ -3415,15 +3516,16 @@ 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, "%s", style_reg (styler, "z%d", opnd->reg.regno));
       else
-	snprintf (buf, size, "z%d.%s", opnd->reg.regno,
-		  aarch64_get_qualifier_name (opnd->qualifier));
+	snprintf (buf, size, "%s",
+		  style_reg (styler, "z%d.%s", 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", styler);
       break;
 
     case AARCH64_OPND_SVE_Zm3_INDEX:
@@ -3432,55 +3534,61 @@ 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,
-		aarch64_get_qualifier_name (opnd->qualifier),
-		opnd->reglane.index);
+      snprintf (buf, size, "%s[%s]",
+		style_reg (styler, "z%d.%s", opnd->reglane.regno,
+			   aarch64_get_qualifier_name (opnd->qualifier)),
+		style_imm (styler, "%" PRIi64, opnd->reglane.index));
       break;
 
     case AARCH64_OPND_SME_ZAda_2b:
     case AARCH64_OPND_SME_ZAda_3b:
-      snprintf (buf, size, "za%d.%s", opnd->reg.regno,
-                aarch64_get_qualifier_name (opnd->qualifier));
+      snprintf (buf, size, "%s",
+		style_reg (styler, "za%d.%s", opnd->reg.regno,
+			   aarch64_get_qualifier_name (opnd->qualifier)));
       break;
 
     case AARCH64_OPND_SME_ZA_HV_idx_src:
     case AARCH64_OPND_SME_ZA_HV_idx_dest:
     case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
-      snprintf (buf, size, "%sza%d%c.%s[w%d, %d]%s",
-                opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
-                opnd->za_tile_vector.regno,
-                opnd->za_tile_vector.v == 1 ? 'v' : 'h',
-                aarch64_get_qualifier_name (opnd->qualifier),
-                opnd->za_tile_vector.index.regno,
-                opnd->za_tile_vector.index.imm,
-                opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
+      snprintf (buf, size, "%s%s[%s, %s]%s",
+		opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
+		style_reg (styler, "za%d%c.%s",
+			   opnd->za_tile_vector.regno,
+			   opnd->za_tile_vector.v == 1 ? 'v' : 'h',
+			   aarch64_get_qualifier_name (opnd->qualifier)),
+		style_reg (styler, "w%d", opnd->za_tile_vector.index.regno),
+		style_imm (styler, "%d", opnd->za_tile_vector.index.imm),
+		opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
       break;
 
     case AARCH64_OPND_SME_list_of_64bit_tiles:
-      print_sme_za_list (buf, size, opnd->reg.regno);
+      print_sme_za_list (buf, size, opnd->reg.regno, styler);
       break;
 
     case AARCH64_OPND_SME_ZA_array:
-      snprintf (buf, size, "za[w%d, %d]",
-                opnd->za_tile_vector.index.regno,
-                opnd->za_tile_vector.index.imm);
+      snprintf (buf, size, "%s[%s, %s]",
+		style_reg (styler, "za"),
+		style_reg (styler, "w%d", opnd->za_tile_vector.index.regno),
+		style_imm (styler, "%d", opnd->za_tile_vector.index.imm));
       break;
 
     case AARCH64_OPND_SME_SM_ZA:
-      snprintf (buf, size, "%s", opnd->reg.regno == 's' ? "sm" : "za");
+      snprintf (buf, size, "%s",
+		style_reg (styler, opnd->reg.regno == 's' ? "sm" : "za"));
       break;
 
     case AARCH64_OPND_SME_PnT_Wm_imm:
-      snprintf (buf, size, "p%d.%s[w%d, %d]",
-                opnd->za_tile_vector.regno,
-                aarch64_get_qualifier_name (opnd->qualifier),
-                opnd->za_tile_vector.index.regno,
-                opnd->za_tile_vector.index.imm);
+      snprintf (buf, size, "%s[%s, %s]",
+		style_reg (styler, "p%d.%s", opnd->za_tile_vector.regno,
+			   aarch64_get_qualifier_name (opnd->qualifier)),
+                style_reg (styler, "w%d", opnd->za_tile_vector.index.regno),
+                style_imm (styler, "%d", opnd->za_tile_vector.index.imm));
       break;
 
     case AARCH64_OPND_CRn:
     case AARCH64_OPND_CRm:
-      snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
+      snprintf (buf, size, "%s",
+		style_reg (styler, "C%" PRIi64, opnd->imm.value));
       break;
 
     case AARCH64_OPND_IDX:
@@ -3521,7 +3629,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",
+		style_imm (styler, "#%" PRIi64, opnd->imm.value));
       break;
 
     case AARCH64_OPND_SVE_I1_HALF_ONE:
@@ -3530,7 +3639,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", style_imm (styler, "#%.1f", c.f));
 	break;
       }
 
@@ -3541,9 +3650,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",
+		  style_reg (styler, aarch64_sve_pattern_array[enum_value]));
       else
-	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+	snprintf (buf, size, "%s",
+		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
       break;
 
     case AARCH64_OPND_SVE_PATTERN_SCALED:
@@ -3554,15 +3665,20 @@ 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",
+		  style_reg (styler,
+			     aarch64_sve_pattern_array[opnd->imm.value]));
       else
-	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+	snprintf (buf, size, "%s",
+		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
       if (opnd->shifter.operator_present)
 	{
 	  size_t len = strlen (buf);
-	  snprintf (buf + len, size - len, ", %s #%" PRIi64,
-		    aarch64_operand_modifiers[opnd->shifter.kind].name,
-		    opnd->shifter.amount);
+	  const char *shift_name
+	    = aarch64_operand_modifiers[opnd->shifter.kind].name;
+	  snprintf (buf + len, size - len, ", %s %s",
+		    style_sub_mnem (styler, shift_name),
+		    style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
 	}
       break;
 
@@ -3570,9 +3686,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",
+		  style_reg (styler, aarch64_sve_prfop_array[enum_value]));
       else
-	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+	snprintf (buf, size, "%s",
+		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
       break;
 
     case AARCH64_OPND_IMM_MOV:
@@ -3581,12 +3699,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",
+			style_imm (styler, "#0x%-20x", 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", style_imm (styler, "#0x%-20" PRIx64,
+						opnd->imm.value));
 	  snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
 	  break;
 	default:
@@ -3596,7 +3716,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", style_imm (styler, "#0.0"));
       break;
 
     case AARCH64_OPND_LIMM:
@@ -3606,30 +3726,38 @@ 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,
-		  opnd->shifter.amount);
+	snprintf (buf, size, "%s, %s %s",
+		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
+		  style_sub_mnem (styler, "lsl"),
+		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
       else
-	snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
+	snprintf (buf, size, "%s",
+		  style_imm (styler, "#0x%" PRIx64, 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",
+		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
       else
-	snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
-		  aarch64_operand_modifiers[opnd->shifter.kind].name,
-		  opnd->shifter.amount);
+	snprintf (buf, size, "%s, %s %s",
+		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
+		  style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
+		  style_imm (styler, "#%" PRIi64, 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,
-		  opnd->shifter.amount);
+	snprintf (buf, size, "%s, %s %s",
+		  style_imm (styler, "#%" PRIi64, opnd->imm.value),
+		  style_sub_mnem (styler, "lsl"),
+		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
       else
-	snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+	snprintf (buf, size, "%s",
+		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
       break;
 
     case AARCH64_OPND_FPIMM:
@@ -3641,21 +3769,21 @@ 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", style_imm (styler, "#%.18e", 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", style_imm (styler, "#%.18e", 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", style_imm (styler, "#%.18e", c.d));
 	    }
 	  break;
 	default:
@@ -3676,12 +3804,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",
+		style_imm (styler, "#0x%x", (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",
+		style_sub_mnem (styler, opnd->cond->names[0]));
       num_conds = ARRAY_SIZE (opnd->cond->names);
       for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
 	{
@@ -3706,7 +3836,7 @@ 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", style_addr (styler, "#0x%" PRIx64 , addr));
       break;
 
     case AARCH64_OPND_ADDR_PCREL14:
@@ -3722,7 +3852,7 @@ 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", style_addr (styler, "#0x%" PRIx64, addr));
       break;
 
     case AARCH64_OPND_ADDR_SIMPLE:
@@ -3732,12 +3862,16 @@ 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",
+		      style_reg (styler, name),
+		      style_reg (styler, "x%d", opnd->addr.offset.regno));
 	  else
-	    snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
+	    snprintf (buf, size, "[%s], %s",
+		      style_reg (styler, name),
+		      style_imm (styler, "#%d", opnd->addr.offset.imm));
 	}
       else
-	snprintf (buf, size, "[%s]", name);
+	snprintf (buf, size, "[%s]", style_reg (styler, name));
       break;
 
     case AARCH64_OPND_ADDR_REGOFF:
@@ -3753,14 +3887,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), styler);
       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), styler);
       break;
 
     case AARCH64_OPND_SVE_ADDR_RZ:
@@ -3777,7 +3911,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),
+	 styler);
       break;
 
     case AARCH64_OPND_ADDR_SIMM7:
@@ -3801,7 +3936,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),
+	 styler);
       break;
 
     case AARCH64_OPND_SVE_ADDR_ZI_U5:
@@ -3810,7 +3946,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),
+	 styler);
       break;
 
     case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
@@ -3819,15 +3956,18 @@ 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),
+	 styler);
       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]",
+		  style_reg (styler, name),
+		  style_imm (styler, "#%d", opnd->addr.offset.imm));
       else
-	snprintf (buf, size, "[%s]", name);
+	snprintf (buf, size, "[%s]", style_reg (styler, name));
       break;
 
     case AARCH64_OPND_SYSREG:
@@ -3866,14 +4006,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 	}
 
       if (name)
-	snprintf (buf, size, "%s", name);
+	snprintf (buf, size, "%s", style_reg (styler, 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, "%s",
+		    style_reg (styler, "s%u_%u_c%u_c%u_%u",
+			       (value >> 14) & 0x3, (value >> 11) & 0x7,
+			       (value >> 7) & 0xf, (value >> 3) & 0xf,
+			       value & 0x7));
 	}
       break;
 
@@ -3891,7 +4033,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
             break;
           }
       assert (aarch64_pstatefields[i].name);
-      snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
+      snprintf (buf, size, "%s",
+		style_reg (styler, aarch64_pstatefields[i].name));
       break;
 
     case AARCH64_OPND_SYSREG_AT:
@@ -3899,12 +4042,18 @@ 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", style_reg (styler, opnd->sysins_op->name));
       break;
 
     case AARCH64_OPND_BARRIER:
     case AARCH64_OPND_BARRIER_DSB_NXS:
-      snprintf (buf, size, "%s", opnd->barrier->name);
+      {
+	if (opnd->barrier->name[0] == '#')
+	  snprintf (buf, size, "%s", style_imm (styler, opnd->barrier->name));
+	else
+	  snprintf (buf, size, "%s",
+		    style_sub_mnem (styler, opnd->barrier->name));
+      }
       break;
 
     case AARCH64_OPND_BARRIER_ISB:
@@ -3912,34 +4061,40 @@ 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",
+		  style_imm (styler, "#0x%x", opnd->barrier->value));
       break;
 
     case AARCH64_OPND_PRFOP:
       if (opnd->prfop->name != NULL)
-	snprintf (buf, size, "%s", opnd->prfop->name);
+	snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name));
       else
-	snprintf (buf, size, "#0x%02x", opnd->prfop->value);
+	snprintf (buf, size, "%s", style_imm (styler, "#0x%02x",
+					      opnd->prfop->value));
       break;
 
     case AARCH64_OPND_BARRIER_PSB:
-      snprintf (buf, size, "csync");
+      snprintf (buf, size, "%s", style_sub_mnem (styler, "csync"));
       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",
+		  style_sub_mnem (styler, 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));
+		style_reg (styler,
+			   get_int_reg_name (opnd->reg.regno,
+					     AARCH64_OPND_QLF_X, 0)));
       break;
 
     case AARCH64_OPND_MOPS_WB_Rn:
       snprintf (buf, size, "%s!",
-		get_int_reg_name (opnd->reg.regno, AARCH64_OPND_QLF_X, 0));
+		style_reg (styler, get_int_reg_name (opnd->reg.regno,
+						     AARCH64_OPND_QLF_X, 0)));
       break;
 
     default:
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 4090e94b623..79a2f3dabe5 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -610,6 +610,7 @@ disassemble_init_for_target (struct disassemble_info * info)
     case bfd_arch_aarch64:
       info->symbol_is_valid = aarch64_symbol_is_valid;
       info->disassembler_needs_relocs = true;
+      info->created_styled_output = true;
       break;
 #endif
 #ifdef ARCH_arc


                 reply	other threads:[~2022-07-29 13:04 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20220729130406.720CF3857C69@sourceware.org \
    --to=aburgess@sourceware.org \
    --cc=bfd-cvs@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).