Introduce complex_operation
[binutils-gdb.git] / cpu / m32c.opc
index 226f8d0a25e6097b29cf5afd55b030fc3d1025a7..2796e1c1cffb1bfa3dff4a34baa3947b3621ff4b 100644 (file)
@@ -1,6 +1,6 @@
 /* m32c opcode support.  -*- C -*-
 
 /* m32c opcode support.  -*- C -*-
 
-   Copyright 2005 Free Software Foundation, Inc.
+   Copyright 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
 
    Contributed by Red Hat Inc; developed under contract from Renesas
 
 
    Contributed by Red Hat Inc; developed under contract from Renesas
 
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,7 +18,9 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
 
 /* This file is an addendum to m32c.cpu.  Heavy use of C code isn't
    appropriate in .cpu files, so it resides here.  This especially applies
 
 /* This file is an addendum to m32c.cpu.  Heavy use of C code isn't
    appropriate in .cpu files, so it resides here.  This especially applies
@@ -38,8 +40,8 @@
 /* -- opc.h */
 
 /* Needed for RTL's 'ext' and 'trunc' operators.  */
 /* -- opc.h */
 
 /* Needed for RTL's 'ext' and 'trunc' operators.  */
-#include "cgen-types.h"
-#include "cgen-ops.h"
+#include "cgen/basic-modes.h"
+#include "cgen/basic-ops.h"
 
 /* We can't use the default hash size because many bits are used by
    operands.  */
 
 /* We can't use the default hash size because many bits are used by
    operands.  */
@@ -154,27 +156,26 @@ parse_unsigned8 (CGEN_CPU_DESC cd, const char **strp,
                 int opindex, unsigned long *valuep)
 {
   const char *errmsg = 0;
                 int opindex, unsigned long *valuep)
 {
   const char *errmsg = 0;
-  unsigned long value;
+  unsigned long value = 0;
   long have_zero = 0;
 
   if (strncasecmp (*strp, "%dsp8(", 6) == 0)
     {
       enum cgen_parse_operand_result result_type;
   long have_zero = 0;
 
   if (strncasecmp (*strp, "%dsp8(", 6) == 0)
     {
       enum cgen_parse_operand_result result_type;
-      bfd_vma value;
-      const char *errmsg;
+      bfd_vma val;
 
       *strp += 6;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_8,
 
       *strp += 6;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_8,
-                                  & result_type, & value);
+                                  & result_type, & val);
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
-       {
-         return _("%dsp8() takes a symbolic address, not a number");
-       }
+       return _("%dsp8() takes a symbolic address, not a number");
+
+      value = val;
       *valuep = value;
       return errmsg;
     }
       *valuep = value;
       return errmsg;
     }
@@ -251,26 +252,25 @@ parse_signed8 (CGEN_CPU_DESC cd, const char **strp,
               int opindex, signed long *valuep)
 {
   const char *errmsg = 0;
               int opindex, signed long *valuep)
 {
   const char *errmsg = 0;
-  signed long value;
+  signed long value = 0;
 
   if (strncasecmp (*strp, "%hi8(", 5) == 0)
     {
       enum cgen_parse_operand_result result_type;
 
   if (strncasecmp (*strp, "%hi8(", 5) == 0)
     {
       enum cgen_parse_operand_result result_type;
-      bfd_vma value;
-      const char *errmsg;
+      bfd_vma val;
 
       *strp += 5;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32C_HI8,
 
       *strp += 5;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32C_HI8,
-                                  & result_type, & value);
+                                  & result_type, & val);
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
-       {
-         value >>= 16;
-       }
+       val >>= 16;
+
+      value = val;
       *valuep = value;
       return errmsg;
     }
       *valuep = value;
       return errmsg;
     }
@@ -292,27 +292,26 @@ parse_unsigned16 (CGEN_CPU_DESC cd, const char **strp,
                 int opindex, unsigned long *valuep)
 {
   const char *errmsg = 0;
                 int opindex, unsigned long *valuep)
 {
   const char *errmsg = 0;
-  unsigned long value;
+  unsigned long value = 0;
   long have_zero = 0;
 
   if (strncasecmp (*strp, "%dsp16(", 7) == 0)
     {
       enum cgen_parse_operand_result result_type;
   long have_zero = 0;
 
   if (strncasecmp (*strp, "%dsp16(", 7) == 0)
     {
       enum cgen_parse_operand_result result_type;
-      bfd_vma value;
-      const char *errmsg;
+      bfd_vma val;
 
       *strp += 7;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_16,
 
       *strp += 7;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_16,
-                                  & result_type, & value);
+                                  & result_type, & val);
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
-       {
-         return _("%dsp16() takes a symbolic address, not a number");
-       }
+       return _("%dsp16() takes a symbolic address, not a number");
+
+      value = val;
       *valuep = value;
       return errmsg;
     }
       *valuep = value;
       return errmsg;
     }
@@ -352,26 +351,25 @@ parse_signed16 (CGEN_CPU_DESC cd, const char **strp,
               int opindex, signed long *valuep)
 {
   const char *errmsg = 0;
               int opindex, signed long *valuep)
 {
   const char *errmsg = 0;
-  signed long value;
+  signed long value = 0;
 
   if (strncasecmp (*strp, "%lo16(", 6) == 0)
     {
       enum cgen_parse_operand_result result_type;
 
   if (strncasecmp (*strp, "%lo16(", 6) == 0)
     {
       enum cgen_parse_operand_result result_type;
-      bfd_vma value;
-      const char *errmsg;
+      bfd_vma val;
 
       *strp += 6;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
 
       *strp += 6;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
-                                  & result_type, & value);
+                                  & result_type, & val);
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
-       {
-         value &= 0xffff;
-       }
+       val &= 0xffff;
+
+      value = val;
       *valuep = value;
       return errmsg;
     }
       *valuep = value;
       return errmsg;
     }
@@ -379,21 +377,20 @@ parse_signed16 (CGEN_CPU_DESC cd, const char **strp,
   if (strncasecmp (*strp, "%hi16(", 6) == 0)
     {
       enum cgen_parse_operand_result result_type;
   if (strncasecmp (*strp, "%hi16(", 6) == 0)
     {
       enum cgen_parse_operand_result result_type;
-      bfd_vma value;
-      const char *errmsg;
+      bfd_vma val;
 
       *strp += 6;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
 
       *strp += 6;
       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
-                                  & result_type, & value);
+                                  & result_type, & val);
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
       if (**strp != ')')
        return _("missing `)'");
       (*strp) ++;
 
       if (errmsg == NULL
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
-       {
-         value >>= 16;
-       }
+       val >>= 16;
+
+      value = val;
       *valuep = value;
       return errmsg;
     }
       *valuep = value;
       return errmsg;
     }
@@ -533,6 +530,24 @@ parse_imm3_S (CGEN_CPU_DESC cd, const char **strp,
   return 0;
 }
 
   return 0;
 }
 
+static const char *
+parse_bit3_S (CGEN_CPU_DESC cd, const char **strp,
+            int opindex, signed long *valuep)
+{
+  const char *errmsg = 0;
+  signed long value;
+  
+  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
+  if (errmsg)
+    return errmsg;
+
+  if (value < 0 || value > 7)
+    return _("immediate is out of range 0-7");
+
+  *valuep = value;
+  return 0;
+}
+
 static const char *
 parse_lab_5_3 (CGEN_CPU_DESC cd,
               const char **strp,
 static const char *
 parse_lab_5_3 (CGEN_CPU_DESC cd,
               const char **strp,
@@ -551,7 +566,7 @@ parse_lab_5_3 (CGEN_CPU_DESC cd,
   if (type_addr)
     *type_addr = op_res;
 
   if (type_addr)
     *type_addr = op_res;
 
-  if (op_res == CGEN_PARSE_OPERAND_ADDRESS)
+  if (op_res == CGEN_PARSE_OPERAND_RESULT_QUEUED)
     {
       /* This is a hack; the field cannot handle near-zero signed
         offsets that CGEN wants to put in to indicate an "empty"
     {
       /* This is a hack; the field cannot handle near-zero signed
         offsets that CGEN wants to put in to indicate an "empty"
@@ -590,13 +605,14 @@ parse_Bitno16R (CGEN_CPU_DESC cd, const char **strp,
 static const char *
 parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
                        int opindex, unsigned long *valuep,
 static const char *
 parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
                        int opindex, unsigned long *valuep,
-                       unsigned bits)
+                       unsigned bits, int allow_syms)
 {
   const char *errmsg = 0;
   unsigned long bit;
   unsigned long base;
   const char *newp = *strp;
   unsigned long long bitbase;
 {
   const char *errmsg = 0;
   unsigned long bit;
   unsigned long base;
   const char *newp = *strp;
   unsigned long long bitbase;
+  long have_zero = 0;
 
   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
   if (errmsg)
 
   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
   if (errmsg)
@@ -606,6 +622,11 @@ parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
     return "Missing base for bit,base:8";
 
   ++newp;
     return "Missing base for bit,base:8";
 
   ++newp;
+
+  if (strncmp (newp, "0x0", 3) == 0 
+      || (newp[0] == '0' && newp[1] != 'x'))
+    have_zero = 1;
+
   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base);
   if (errmsg)
     return errmsg;
   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base);
   if (errmsg)
     return errmsg;
@@ -615,6 +636,21 @@ parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
   if (bitbase >= (1ull << bits))
     return _("bit,base is out of range");
 
   if (bitbase >= (1ull << bits))
     return _("bit,base is out of range");
 
+  /* If this field may require a relocation then use larger displacement.  */
+  if (! have_zero && base == 0)
+    {
+      switch (allow_syms) {
+      case 0:
+       return _("bit,base out of range for symbol");
+      case 1:
+       break;
+      case 2:
+       if (strncmp (newp, "[sb]", 4) != 0)
+         return _("bit,base out of range for symbol");
+       break;
+      }
+    }
+
   *valuep = bitbase;
   *strp = newp;
   return 0;
   *valuep = bitbase;
   *strp = newp;
   return 0;
@@ -623,7 +659,7 @@ parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
 static const char *
 parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
                      int opindex, signed long *valuep,
 static const char *
 parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
                      int opindex, signed long *valuep,
-                     unsigned bits)
+                     unsigned bits, int allow_syms)
 {
   const char *errmsg = 0;
   unsigned long bit;
 {
   const char *errmsg = 0;
   unsigned long bit;
@@ -631,6 +667,7 @@ parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
   const char *newp = *strp;
   long long bitbase;
   long long limit;
   const char *newp = *strp;
   long long bitbase;
   long long limit;
+  long have_zero = 0;
 
   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
   if (errmsg)
 
   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
   if (errmsg)
@@ -640,6 +677,11 @@ parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
     return "Missing base for bit,base:8";
 
   ++newp;
     return "Missing base for bit,base:8";
 
   ++newp;
+
+  if (strncmp (newp, "0x0", 3) == 0 
+      || (newp[0] == '0' && newp[1] != 'x'))
+    have_zero = 1;
+
   errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base);
   if (errmsg)
     return errmsg;
   errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base);
   if (errmsg)
     return errmsg;
@@ -650,6 +692,10 @@ parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
   if (bitbase < -limit || bitbase >= limit)
     return _("bit,base is out of range");
 
   if (bitbase < -limit || bitbase >= limit)
     return _("bit,base is out of range");
 
+  /* If this field may require a relocation then use larger displacement.  */
+  if (! have_zero && base == 0 && ! allow_syms)
+    return _("bit,base out of range for symbol");
+
   *valuep = bitbase;
   *strp = newp;
   return 0;
   *valuep = bitbase;
   *strp = newp;
   return 0;
@@ -659,56 +705,56 @@ static const char *
 parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
 parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
-  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8);
+  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8, 0);
 }
 
 static const char *
 parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
 }
 
 static const char *
 parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
-  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11);
+  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11, 0);
 }
 
 static const char *
 parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp,
                          int opindex, unsigned long *valuep)
 {
 }
 
 static const char *
 parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp,
                          int opindex, unsigned long *valuep)
 {
-  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16);
+  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16, 1);
 }
 
 static const char *
 parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
 }
 
 static const char *
 parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
-  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19);
+  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19, 2);
 }
 
 static const char *
 parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
 }
 
 static const char *
 parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp,
                         int opindex, unsigned long *valuep)
 {
-  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27);
+  return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27, 1);
 }
 
 static const char *
 parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
                       int opindex, signed long *valuep)
 {
 }
 
 static const char *
 parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
                       int opindex, signed long *valuep)
 {
-  return parse_signed_bitbase (cd, strp, opindex, valuep, 8);
+  return parse_signed_bitbase (cd, strp, opindex, valuep, 8, 1);
 }
 
 static const char *
 parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
                       int opindex, signed long *valuep)
 {
 }
 
 static const char *
 parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
                       int opindex, signed long *valuep)
 {
-  return parse_signed_bitbase (cd, strp, opindex, valuep, 11);
+  return parse_signed_bitbase (cd, strp, opindex, valuep, 11, 0);
 }
 
 static const char *
 parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
                       int opindex, signed long *valuep)
 {
 }
 
 static const char *
 parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
                       int opindex, signed long *valuep)
 {
-  return parse_signed_bitbase (cd, strp, opindex, valuep, 19);
+  return parse_signed_bitbase (cd, strp, opindex, valuep, 19, 1);
 }
 
 /* Parse the suffix as :<char> or as nothing followed by a whitespace.  */
 }
 
 /* Parse the suffix as :<char> or as nothing followed by a whitespace.  */
@@ -824,14 +870,14 @@ m32c_cgen_insn_supported (CGEN_CPU_DESC cd,
                          const CGEN_INSN *insn)
 {
   int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
                          const CGEN_INSN *insn)
 {
   int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
-  int isas = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ISA);
+  CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
 
   /* If attributes are absent, assume no restriction.  */
   if (machs == 0)
     machs = ~0;
 
   return ((machs & cd->machs)
 
   /* If attributes are absent, assume no restriction.  */
   if (machs == 0)
     machs = ~0;
 
   return ((machs & cd->machs)
-         && (isas & cd->isas));
+          && cgen_bitset_intersect_p (& isas, cd->isas));
 }
 
 /* Parse a set of registers, R0,R1,A0,A1,SB,FB.  */
 }
 
 /* Parse a set of registers, R0,R1,A0,A1,SB,FB.  */
@@ -1070,7 +1116,7 @@ print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
   };
   disassemble_info *info = dis_info;
   int mask;
   };
   disassemble_info *info = dis_info;
   int mask;
-  int index = 0;
+  int reg_index = 0;
   char* comma = "";
 
   if (push)
   char* comma = "";
 
   if (push)
@@ -1084,7 +1130,7 @@ print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
       comma = ",";
     }
 
       comma = ",";
     }
 
-  for (index = 1; index <= 7; ++index)
+  for (reg_index = 1; reg_index <= 7; ++reg_index)
     {
       if (push)
         mask >>= 1;
     {
       if (push)
         mask >>= 1;
@@ -1094,7 +1140,7 @@ print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
       if (value & mask)
         {
           (*info->fprintf_func) (info->stream, "%s%s", comma,
       if (value & mask)
         {
           (*info->fprintf_func) (info->stream, "%s%s", comma,
-                                m16c_register_names [index]);
+                                m16c_register_names [reg_index]);
           comma = ",";
         }
     }
           comma = ",";
         }
     }