LoongArch: Support referring to FCSRs as $fcsrX
[binutils-gdb.git] / opcodes / avr-dis.c
index ab38366f64e89119defe74c0469fa4730e3c71ea..aa97eebcaac3026282a60f32cafa79af7ef2913b 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassemble AVR instructions.
-   Copyright (C) 1999-2019 Free Software Foundation, Inc.
+   Copyright (C) 1999-2023 Free Software Foundation, Inc.
 
    Contributed by Denis Chertykov <denisc@overta.ru>
 
@@ -25,7 +25,7 @@
 #include "disassemble.h"
 #include "opintl.h"
 #include "libiberty.h"
-#include "bfd_stdint.h"
+#include <stdint.h>
 
 struct avr_opcodes_s
 {
@@ -49,8 +49,18 @@ const struct avr_opcodes_s avr_opcodes[] =
 static const char * comment_start = "0x";
 
 static int
-avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constraint,
-             char *opcode_str, char *buf, char *comment, int regs, int *sym, bfd_vma *sym_addr)
+avr_operand (unsigned int        insn,
+            unsigned int        insn2,
+            unsigned int        pc,
+            int                 constraint,
+             char *              opcode_str,
+            char *              buf,
+            char *              comment,
+            enum disassembler_style *  style,
+            int                 regs,
+            int *               sym,
+            bfd_vma *           sym_addr,
+            disassemble_info *  info)
 {
   int ok = 1;
   *sym = 0;
@@ -65,6 +75,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        insn = (insn & 0x01f0) >> 4; /* Destination register.  */
 
       sprintf (buf, "r%d", insn);
+      *style = dis_style_register;
       break;
 
     case 'd':
@@ -72,10 +83,12 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        sprintf (buf, "r%d", 16 + (insn & 0xf));
       else
        sprintf (buf, "r%d", 16 + ((insn & 0xf0) >> 4));
+      *style = dis_style_register;
       break;
 
     case 'w':
       sprintf (buf, "r%d", 24 + ((insn & 0x30) >> 3));
+      *style = dis_style_register;
       break;
 
     case 'a':
@@ -83,6 +96,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        sprintf (buf, "r%d", 16 + (insn & 7));
       else
        sprintf (buf, "r%d", 16 + ((insn >> 4) & 7));
+      *style = dis_style_register;
       break;
 
     case 'v':
@@ -90,6 +104,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        sprintf (buf, "r%d", (insn & 0xf) * 2);
       else
        sprintf (buf, "r%d", ((insn & 0xf0) >> 3));
+      *style = dis_style_register;
       break;
 
     case 'e':
@@ -114,6 +129,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        if (AVR_UNDEF_P (insn))
          sprintf (comment, _("undefined"));
       }
+      *style = dis_style_register;
       break;
 
     case 'z':
@@ -134,6 +150,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
       *buf = '\0';
       if (AVR_UNDEF_P (insn))
        sprintf (comment, _("undefined"));
+      *style = dis_style_register;
       break;
 
     case 'b':
@@ -150,6 +167,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
          *buf++ = 'Z';
        sprintf (buf, "+%d", x);
        sprintf (comment, "0x%02x", x);
+       *style = dis_style_register;
       }
       break;
 
@@ -161,6 +179,10 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
         objdump_print_address() which would affect many targets.  */
       sprintf (buf, "%#lx", (unsigned long) *sym_addr);
       strcpy (comment, comment_start);
+      info->insn_info_valid = 1;
+      info->insn_type = dis_jsr;
+      info->target = *sym_addr;
+      *style = dis_style_address;
       break;
 
     case 'L':
@@ -170,6 +192,10 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
         *sym = 1;
         *sym_addr = pc + 2 + rel_addr;
        strcpy (comment, comment_start);
+        info->insn_info_valid = 1;
+        info->insn_type = dis_branch;
+        info->target = *sym_addr;
+       *style = dis_style_address_offset;
       }
       break;
 
@@ -181,6 +207,10 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
         *sym = 1;
         *sym_addr = pc + 2 + rel_addr;
        strcpy (comment, comment_start);
+        info->insn_info_valid = 1;
+        info->insn_type = dis_condbranch;
+        info->target = *sym_addr;
+       *style = dis_style_address_offset;
       }
       break;
 
@@ -191,6 +221,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
         *sym_addr = val;
         sprintf (buf, "0x%04X", insn2);
         strcpy (comment, comment_start);
+       *style = dis_style_immediate;
       }
       break;
 
@@ -204,12 +235,14 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
         *sym_addr = val | 0x800000;
         sprintf (buf, "0x%02x", val);
         strcpy (comment, comment_start);
+       *style = dis_style_immediate;
       }
       break;
 
     case 'M':
       sprintf (buf, "0x%02X", ((insn & 0xf00) >> 4) | (insn & 0xf));
       sprintf (comment, "%d", ((insn & 0xf00) >> 4) | (insn & 0xf));
+      *style = dis_style_immediate;
       break;
 
     case 'n':
@@ -217,6 +250,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
       /* xgettext:c-format */
       opcodes_error_handler (_("internal disassembler error"));
       ok = 0;
+      *style = dis_style_immediate;
       break;
 
     case 'K':
@@ -226,15 +260,18 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        x = (insn & 0xf) | ((insn >> 2) & 0x30);
        sprintf (buf, "0x%02x", x);
        sprintf (comment, "%d", x);
+       *style = dis_style_immediate;
       }
       break;
 
     case 's':
       sprintf (buf, "%d", insn & 7);
+      *style = dis_style_immediate;
       break;
 
     case 'S':
       sprintf (buf, "%d", (insn >> 4) & 7);
+      *style = dis_style_immediate;
       break;
 
     case 'P':
@@ -245,6 +282,7 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        x |= (insn >> 5) & 0x30;
        sprintf (buf, "0x%02x", x);
        sprintf (comment, "%d", x);
+       *style = dis_style_address;
       }
       break;
 
@@ -255,11 +293,13 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
        x = (insn >> 3) & 0x1f;
        sprintf (buf, "0x%02x", x);
        sprintf (comment, "%d", x);
+       *style = dis_style_address;
       }
       break;
 
     case 'E':
       sprintf (buf, "%d", (insn >> 4) & 15);
+      *style = dis_style_immediate;
       break;
 
     case '?':
@@ -305,15 +345,23 @@ print_insn_avr (bfd_vma addr, disassemble_info *info)
   const struct avr_opcodes_s *opcode;
   static unsigned int *maskptr;
   void *stream = info->stream;
-  fprintf_ftype prin = info->fprintf_func;
+  fprintf_styled_ftype prin = info->fprintf_styled_func;
   static unsigned int *avr_bin_masks;
   static int initialized;
   int cmd_len = 2;
   int ok = 0;
   char op1[20], op2[20], comment1[40], comment2[40];
+  enum disassembler_style style_op1, style_op2;
   int sym_op1 = 0, sym_op2 = 0;
   bfd_vma sym_addr1, sym_addr2;
 
+  /* Clear instruction information field.  */
+  info->insn_info_valid = 0;
+  info->branch_delay_insns = 0;
+  info->data_size = 0;
+  info->insn_type = dis_noninsn;
+  info->target = 0;
+  info->target2 = 0;
 
   if (!initialized)
     {
@@ -375,6 +423,8 @@ print_insn_avr (bfd_vma addr, disassemble_info *info)
   op2[0] = 0;
   comment1[0] = 0;
   comment2[0] = 0;
+  style_op1 = dis_style_text;
+  style_op2 = dis_style_text;
 
   if (opcode->name)
     {
@@ -395,11 +445,15 @@ print_insn_avr (bfd_vma addr, disassemble_info *info)
        {
          int regs = REGISTER_P (*constraints);
 
-         ok = avr_operand (insn, insn2, addr, *constraints, opcode_str, op1, comment1, 0, &sym_op1, &sym_addr1);
+         ok = avr_operand (insn, insn2, addr, *constraints, opcode_str, op1,
+                           comment1, &style_op1, 0, &sym_op1, &sym_addr1,
+                           info);
 
          if (ok && *(++constraints) == ',')
-           ok = avr_operand (insn, insn2, addr, *(++constraints), opcode_str, op2,
-                             *comment1 ? comment2 : comment1, regs, &sym_op2, &sym_addr2);
+           ok = avr_operand (insn, insn2, addr, *(++constraints), opcode_str,
+                             op2, *comment1 ? comment2 : comment1,
+                             &style_op2, regs, &sym_op2, &sym_addr2,
+                             info);
        }
     }
 
@@ -412,22 +466,26 @@ print_insn_avr (bfd_vma addr, disassemble_info *info)
       comment2[0] = 0;
     }
 
-  (*prin) (stream, "%s", ok ? opcode->name : ".word");
-
+  (*prin) (stream, ok ? dis_style_mnemonic : dis_style_assembler_directive,
+          "%s", ok ? opcode->name : ".word");
+  
   if (*op1)
-      (*prin) (stream, "\t%s", op1);
+    (*prin) (stream, style_op1, "\t%s", op1);
 
   if (*op2)
-    (*prin) (stream, ", %s", op2);
+    {
+      (*prin) (stream, dis_style_text, ", ");
+      (*prin) (stream, style_op2, "%s", op2);
+    }
 
   if (*comment1)
-    (*prin) (stream, "\t; %s", comment1);
+    (*prin) (stream, dis_style_comment_start, "\t; %s", comment1);
 
   if (sym_op1)
     info->print_address_func (sym_addr1, info);
 
   if (*comment2)
-    (*prin) (stream, " %s", comment2);
+    (*prin) (stream, dis_style_comment_start, " %s", comment2);
 
   if (sym_op2)
     info->print_address_func (sym_addr2, info);