]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - opcodes/cr16-dis.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / opcodes / cr16-dis.c
index 1fc8c2b7a6333bc0e57da213320e453b4a9c8d91..d5840cb81f810431a6521c8674b48f47c1c3610c 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassembler code for CR16.
-   Copyright 2007, 2008, 2009, 2012  Free Software Foundation, Inc.
+   Copyright (C) 2007-2021 Free Software Foundation, Inc.
    Contributed by M R Swami Reddy (MR.Swami.Reddy@nsc.com).
 
    This file is part of GAS, GDB and the GNU binutils.
@@ -18,8 +18,8 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#include "dis-asm.h"
 #include "sysdep.h"
+#include "disassemble.h"
 #include "opcode/cr16.h"
 #include "libiberty.h"
 
 #define ESCAPE_16_BIT  0xB
 
 /* Extract 'n_bits' from 'a' starting from offset 'offs'.  */
-#define EXTRACT(a, offs, n_bits)                    \
-  (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL)   \
-  : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
+#define EXTRACT(a, offs, n_bits) \
+  (((a) >> (offs)) & ((1ul << ((n_bits) - 1) << 1) - 1))
 
-/* Set Bit Mask - a mask to set all bits starting from offset 'offs'.  */
-#define SBM(offs)  ((((1 << (32 - offs)) -1) << (offs)))
-
-typedef unsigned long dwordU;
-typedef unsigned short wordU;
-
-typedef struct
-{
-  dwordU val;
-  int nbits;
-} parameter;
+/* Set Bit Mask - a mask to set all bits in a 32-bit word starting
+   from offset 'offs'.  */
+#define SBM(offs)  ((1ul << 31 << 1) - (1ul << (offs)))
 
 /* Structure to map valid 'cinv' instruction options.  */
 
@@ -57,7 +48,7 @@ typedef struct
 cinv_entry;
 
 /* CR16 'cinv' options mapping.  */
-const cinv_entry cr16_cinvs[] =
+static const cinv_entry cr16_cinvs[] =
 {
   {"cinv[i]",     "cinv    [i]"},
   {"cinv[i,u]",   "cinv    [i,u]"},
@@ -81,20 +72,20 @@ typedef enum REG_ARG_TYPE
 REG_ARG_TYPE;
 
 /* Current opcode table entry we're disassembling.  */
-const inst *instruction;
+static const inst *instruction;
 /* Current instruction we're disassembling.  */
-ins currInsn;
+static ins cr16_currInsn;
 /* The current instruction is read into 3 consecutive words.  */
-wordU words[3];
+static wordU cr16_words[3];
 /* Contains all words in appropriate order.  */
-ULONGLONG allWords;
+static ULONGLONG cr16_allWords;
 /* Holds the current processed argument number.  */
-int processing_argument_number;
+static int processing_argument_number;
 /* Nonzero means a IMM4 instruction.  */
-int imm4flag;
+static int imm4flag;
 /* Nonzero means the instruction's original size is
    incremented (escape sequence is used).  */
-int size_changed;
+static int size_changed;
 
 
 /* Print the constant expression length.  */
@@ -281,7 +272,7 @@ getprocpregname (int reg_index)
   return "ILLEGAL REGISTER";
 }
 
-/* START and END are relating 'allWords' struct, which is 48 bits size.
+/* START and END are relating 'cr16_allWords' struct, which is 48 bits size.
 
                           START|--------|END
              +---------+---------+---------+---------+
@@ -290,14 +281,10 @@ getprocpregname (int reg_index)
                        0         16        32        48
     words                  [0]       [1]       [2]      */
 
-static parameter
+static inline dwordU
 makelongparameter (ULONGLONG val, int start, int end)
 {
-  parameter p;
-
-  p.val = (dwordU) EXTRACT (val, 48 - end, end - start);
-  p.nbits = end - start;
-  return p;
+  return EXTRACT (val, 48 - end, end - start);
 }
 
 /* Build a mask of the instruction's 'constant' opcode,
@@ -317,12 +304,12 @@ build_mask (void)
 
 /* Search for a matching opcode. Return 1 for success, 0 for failure.  */
 
-static int
-match_opcode (void)
+int
+cr16_match_opcode (void)
 {
   unsigned long mask;
-  /* The instruction 'constant' opcode doewsn't exceed 32 bits.  */
-  unsigned long doubleWord = (words[1] + (words[0] << 16)) & 0xffffffff;
+  /* The instruction 'constant' opcode doesn't exceed 32 bits.  */
+  unsigned long doubleWord = cr16_words[1] + ((unsigned) cr16_words[0] << 16);
 
   /* Start searching from end of instruction table.  */
   instruction = &cr16_instruction[NUMOPCODES - 2];
@@ -331,15 +318,12 @@ match_opcode (void)
   while (instruction >= cr16_instruction)
     {
       mask = build_mask ();
-      /* Adjust mask for bcond with 32-bit size instruction */
-      if ((IS_INSN_MNEMONIC("b") && instruction->size == 2))
-        mask = 0xff0f0000;
 
       if ((doubleWord & mask) == BIN (instruction->match,
-                                      instruction->match_bits))
-        return 1;
+                                     instruction->match_bits))
+       return 1;
       else
-        instruction--;
+       instruction--;
     }
   return 0;
 }
@@ -350,7 +334,7 @@ static void
 make_argument (argument * a, int start_bits)
 {
   int inst_bit_size;
-  parameter p;
+  dwordU p;
 
   if ((instruction->size == 3) && a->size >= 16)
     inst_bit_size = 48;
@@ -360,70 +344,75 @@ make_argument (argument * a, int start_bits)
   switch (a->type)
     {
     case arg_r:
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
-                             inst_bit_size - start_bits);
-      a->r = p.val;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->r = p;
       break;
 
     case arg_rp:
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
-                             inst_bit_size - start_bits);
-      a->rp = p.val;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->rp = p;
       break;
 
     case arg_pr:
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
-                             inst_bit_size - start_bits);
-      a->pr = p.val;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->pr = p;
       break;
 
     case arg_prp:
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
-                             inst_bit_size - start_bits);
-      a->prp = p.val;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->prp = p;
       break;
 
     case arg_ic:
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
-                             inst_bit_size - start_bits);
-      a->constant = p.val;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->constant = p;
       break;
 
     case arg_cc:
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
-                             inst_bit_size - start_bits);
-
-      a->cc = p.val;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->cc = p;
       break;
 
     case arg_idxr:
-      if ((IS_INSN_MNEMONIC ("cbitb"))
-         || (IS_INSN_MNEMONIC ("sbitb"))
-         || (IS_INSN_MNEMONIC ("tbitb")))
-       p = makelongparameter (allWords, 8, 9);
+      if (IS_INSN_TYPE (CSTBIT_INS) && instruction->mnemonic[4] == 'b')
+       p = makelongparameter (cr16_allWords, 8, 9);
       else
-       p = makelongparameter (allWords, 9, 10);
-      a->i_r = p.val;
-      p = makelongparameter (allWords, inst_bit_size - a->size, inst_bit_size);
-      a->constant = p.val;
+       p = makelongparameter (cr16_allWords, 9, 10);
+      a->i_r = p;
+      p = makelongparameter (cr16_allWords,
+                            inst_bit_size - a->size, inst_bit_size);
+      a->constant = p;
       break;
 
     case arg_idxrp:
-      p = makelongparameter (allWords, start_bits + 12, start_bits + 13);
-      a->i_r = p.val;
-      p = makelongparameter (allWords, start_bits + 13, start_bits + 16);
-      a->rp = p.val;
+      p = makelongparameter (cr16_allWords, start_bits + 12, start_bits + 13);
+      a->i_r = p;
+      p = makelongparameter (cr16_allWords, start_bits + 13, start_bits + 16);
+      a->rp = p;
       if (inst_bit_size > 32)
        {
-         p = makelongparameter (allWords, inst_bit_size - start_bits - 12,
+         p = makelongparameter (cr16_allWords, inst_bit_size - start_bits - 12,
                                 inst_bit_size);
-         a->constant = ((p.val & 0xffff) | (p.val >> 8 & 0xf0000));
+         a->constant = (p & 0xffff) | (p >> 8 & 0xf0000);
        }
       else if (instruction->size == 2)
        {
-         p = makelongparameter (allWords, inst_bit_size - 22, inst_bit_size);
-         a->constant = (p.val & 0xf) | (((p.val >>20) & 0x3) << 4)
-           | ((p.val >>14 & 0x3) << 6) | (((p.val >>7) & 0x1f) <<7);
+         p = makelongparameter (cr16_allWords, inst_bit_size - 22,
+                                inst_bit_size);
+         a->constant = ((p & 0xf) | (((p >> 20) & 0x3) << 4)
+                        | ((p >> 14 & 0x3) << 6) | (((p >>7) & 0x1f) << 7));
        }
       else if (instruction->size == 1 && a->size == 0)
        a->constant = 0;
@@ -431,48 +420,49 @@ make_argument (argument * a, int start_bits)
       break;
 
     case arg_rbase:
-      p = makelongparameter (allWords, inst_bit_size, inst_bit_size);
-      a->constant = p.val;
-      p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
-                             inst_bit_size - start_bits);
-      a->r = p.val;
+      p = makelongparameter (cr16_allWords, inst_bit_size, inst_bit_size);
+      a->constant = p;
+      p = makelongparameter (cr16_allWords, inst_bit_size - (start_bits + 4),
+                            inst_bit_size - start_bits);
+      a->r = p;
       break;
 
     case arg_cr:
-      p = makelongparameter (allWords, start_bits + 12, start_bits + 16);
-      a->r = p.val;
-      p = makelongparameter (allWords, inst_bit_size - 16, inst_bit_size);
-      a->constant = p.val;
+      p = makelongparameter (cr16_allWords, start_bits + 12, start_bits + 16);
+      a->r = p;
+      p = makelongparameter (cr16_allWords, inst_bit_size - 28, inst_bit_size);
+      a->constant = ((p >> 8) & 0xf0000) | (p & 0xffff);
       break;
 
     case arg_crp:
       if (instruction->size == 1)
-       p = makelongparameter (allWords, 12, 16);
+       p = makelongparameter (cr16_allWords, 12, 16);
       else
-       p = makelongparameter (allWords, start_bits + 12, start_bits + 16);
-      a->rp = p.val;
+       p = makelongparameter (cr16_allWords, start_bits + 12, start_bits + 16);
+      a->rp = p;
 
       if (inst_bit_size > 32)
        {
-         p = makelongparameter (allWords, inst_bit_size - start_bits - 12,
+         p = makelongparameter (cr16_allWords, inst_bit_size - start_bits - 12,
                                 inst_bit_size);
-         a->constant = ((p.val & 0xffff) | (p.val >> 8 & 0xf0000));
+         a->constant = ((p & 0xffff) | (p >> 8 & 0xf0000));
        }
       else if (instruction->size == 2)
        {
-         p = makelongparameter (allWords, inst_bit_size - 16, inst_bit_size);
-         a->constant = p.val;
+         p = makelongparameter (cr16_allWords, inst_bit_size - 16,
+                                inst_bit_size);
+         a->constant = p;
        }
       else if (instruction->size == 1 && a->size != 0)
        {
-         p = makelongparameter (allWords, 4, 8);
+         p = makelongparameter (cr16_allWords, 4, 8);
          if (IS_INSN_MNEMONIC ("loadw")
              || IS_INSN_MNEMONIC ("loadd")
              || IS_INSN_MNEMONIC ("storw")
              || IS_INSN_MNEMONIC ("stord"))
-           a->constant = (p.val * 2);
+           a->constant = p * 2;
          else
-           a->constant = p.val;
+           a->constant = p;
        }
       else /* below case for 0x0(reg pair) */
        a->constant = 0;
@@ -489,38 +479,39 @@ make_argument (argument * a, int start_bits)
          switch (a->size)
            {
            case 8 :
-             p = makelongparameter (allWords, 0, start_bits);
-             a->constant = ((((p.val&0xf00)>>4)) | (p.val&0xf));
+             p = makelongparameter (cr16_allWords, 0, start_bits);
+             a->constant = ((p & 0xf00) >> 4) | (p & 0xf);
              break;
 
            case 24:
              if (instruction->size == 3)
                {
-                 p = makelongparameter (allWords, 16, inst_bit_size);
-                 a->constant = ((((p.val>>16)&0xf) << 20)
-                                | (((p.val>>24)&0xf) << 16)
-                                | (p.val & 0xffff));
+                 p = makelongparameter (cr16_allWords, 16, inst_bit_size);
+                 a->constant = ((((p >> 16) & 0xf) << 20)
+                                | (((p >> 24) & 0xf) << 16)
+                                | (p & 0xffff));
                }
              else if (instruction->size == 2)
                {
-                 p = makelongparameter (allWords, 8, inst_bit_size);
-                 a->constant = p.val;
+                 p = makelongparameter (cr16_allWords, 8, inst_bit_size);
+                 a->constant = p;
                }
              break;
 
            default:
-             p = makelongparameter (allWords, inst_bit_size - (start_bits +
-                                                               a->size), inst_bit_size - start_bits);
-             a->constant = p.val;
+             p = makelongparameter (cr16_allWords,
+                                    inst_bit_size - (start_bits + a->size),
+                                    inst_bit_size - start_bits);
+             a->constant = p;
              break;
            }
        }
       else
        {
-         p = makelongparameter (allWords, inst_bit_size -
-                                (start_bits + a->size),
+         p = makelongparameter (cr16_allWords,
+                                inst_bit_size - (start_bits + a->size),
                                 inst_bit_size - start_bits);
-         a->constant = p.val;
+         a->constant = p;
        }
       break;
 
@@ -717,30 +708,30 @@ print_arguments (ins *currentInsn, bfd_vma memaddr, struct disassemble_info *inf
 
       /* For "bal (ra), disp17" instruction only.  */
       if ((IS_INSN_MNEMONIC ("bal")) && (i == 0) && instruction->size == 2)
-        {
-          info->fprintf_func (info->stream, "(ra),");
-          continue;
-        }
+       {
+         info->fprintf_func (info->stream, "(ra),");
+         continue;
+       }
 
       if ((INST_HAS_REG_LIST) && (i == 2))
-        info->fprintf_func (info->stream, "RA");
+       info->fprintf_func (info->stream, "RA");
       else
-        print_arg (&currentInsn->arg[i], memaddr, info);
+       print_arg (&currentInsn->arg[i], memaddr, info);
 
       if ((i != currentInsn->nargs - 1) && (!IS_INSN_MNEMONIC ("b")))
-        info->fprintf_func (info->stream, ",");
+       info->fprintf_func (info->stream, ",");
     }
 }
 
 /* Build the instruction's arguments.  */
 
-static void
-make_instruction (void)
+void
+cr16_make_instruction (void)
 {
   int i;
   unsigned int shift;
 
-  for (i = 0; i < currInsn.nargs; i++)
+  for (i = 0; i < cr16_currInsn.nargs; i++)
     {
       argument a;
 
@@ -750,13 +741,13 @@ make_instruction (void)
       shift = instruction->operands[i].shift;
 
       make_argument (&a, shift);
-      currInsn.arg[i] = a;
+      cr16_currInsn.arg[i] = a;
     }
 
   /* Calculate instruction size (in bytes).  */
-  currInsn.size = instruction->size + (size_changed ? 1 : 0);
+  cr16_currInsn.size = instruction->size + (size_changed ? 1 : 0);
   /* Now in bits.  */
-  currInsn.size *= 2;
+  cr16_currInsn.size *= 2;
 }
 
 /* Retrieve a single word from a given memory address.  */
@@ -785,10 +776,10 @@ get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
   bfd_vma mem;
 
   for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
-    words[i] = get_word_at_PC (mem, info);
+    cr16_words[i] = get_word_at_PC (mem, info);
 
-  allWords =
-    ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
+  cr16_allWords =  ((ULONGLONG) cr16_words[0] << 32)
+                  + ((unsigned long) cr16_words[1] << 16) + cr16_words[2];
 }
 
 /* Prints the instruction by calling print_arguments after proper matching.  */
@@ -805,24 +796,25 @@ print_insn_cr16 (bfd_vma memaddr, struct disassemble_info *info)
   /* Retrieve the encoding from current memory location.  */
   get_words_at_PC (memaddr, info);
   /* Find a matching opcode in table.  */
-  is_decoded = match_opcode ();
+  is_decoded = cr16_match_opcode ();
   /* If found, print the instruction's mnemonic and arguments.  */
-  if (is_decoded > 0 && (words[0] << 16 || words[1]) != 0)
+  if (is_decoded > 0 && (cr16_words[0] != 0 || cr16_words[1] != 0))
     {
       if (strneq (instruction->mnemonic, "cinv", 4))
-        info->fprintf_func (info->stream,"%s", getcinvstring (instruction->mnemonic));
+       info->fprintf_func (info->stream,"%s",
+                           getcinvstring (instruction->mnemonic));
       else
-        info->fprintf_func (info->stream, "%s", instruction->mnemonic);
+       info->fprintf_func (info->stream, "%s", instruction->mnemonic);
 
-      if (((currInsn.nargs = get_number_of_operands ()) != 0)
+      if (((cr16_currInsn.nargs = get_number_of_operands ()) != 0)
          && ! (IS_INSN_MNEMONIC ("b")))
-        info->fprintf_func (info->stream, "\t");
-      make_instruction ();
+       info->fprintf_func (info->stream, "\t");
+      cr16_make_instruction ();
       /* For push/pop/pushrtn with RA instructions.  */
-      if ((INST_HAS_REG_LIST) && ((words[0] >> 7) & 0x1))
-        currInsn.nargs +=1;
-      print_arguments (&currInsn, memaddr, info);
-      return currInsn.size;
+      if ((INST_HAS_REG_LIST) && ((cr16_words[0] >> 7) & 0x1))
+       cr16_currInsn.nargs +=1;
+      print_arguments (&cr16_currInsn, memaddr, info);
+      return cr16_currInsn.size;
     }
 
   /* No match found.  */