* config/tc-xtensa.h (resource_table): Change units to unsigned chars.
[deliverable/binutils-gdb.git] / gas / config / tc-m88k.c
index af243b2e4c71c7dff17b87aeda101bd52e4f229a..d4a950ebc1dcaef2c0b6e557b32f87d14c2464fa 100644 (file)
@@ -1,28 +1,29 @@
 /* m88k.c -- Assembler for the Motorola 88000
    Contributed by Devon Bowen of Buffalo University
    and Torbjorn Granlund of the Swedish Institute of Computer Science.
-   Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999,
+   2000, 2001, 2002, 2003, 2005
    Free Software Foundation, Inc.
 
-This file is part of GAS, the GNU Assembler.
+   This file is part of GAS, the GNU Assembler.
 
-GAS 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, or (at your option)
-any later version.
+   GAS 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, or (at your option)
+   any later version.
 
-GAS is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GAS; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
-#include <ctype.h>
 #include "as.h"
+#include "safe-ctype.h"
 #include "subsegs.h"
 #include "m88k-opcode.h"
 
@@ -79,7 +80,7 @@ struct field_val_assoc fcr_regs[] =
 
 struct field_val_assoc cmpslot[] =
 {
-/* Integer     Floating point */
+/* Integer     Floating point */
   {"nc", 0},
   {"cp", 1},
   {"eq", 2},
@@ -121,31 +122,14 @@ struct m88k_insn
   enum reloc_type reloc;
 };
 
-static char *get_bf PARAMS ((char *param, unsigned *valp));
-static char *get_cmp PARAMS ((char *param, unsigned *valp));
-static char *get_cnd PARAMS ((char *param, unsigned *valp));
-static char *get_cr PARAMS ((char *param, unsigned *regnop));
-static char *get_fcr PARAMS ((char *param, unsigned *regnop));
-static char *get_imm16 PARAMS ((char *param, struct m88k_insn *insn));
-static char *get_o6 PARAMS ((char *param, unsigned *valp));
-static char *get_reg PARAMS ((char *param, unsigned *regnop, int reg_prefix));
-static char *get_vec9 PARAMS ((char *param, unsigned *valp));
-static char *getval PARAMS ((char *param, unsigned int *valp));
-
-static char *get_pcr PARAMS ((char *param, struct m88k_insn *insn,
-                     enum reloc_type reloc));
-
-static int calcop PARAMS ((struct m88k_opcode *format,
-                          char *param, struct m88k_insn *insn));
-
 extern char *myname;
 static struct hash_control *op_hash = NULL;
 
-/* These bits should be turned off in the first address of every segment */
+/* These bits should be turned off in the first address of every segment */
 int md_seg_align = 7;
 
 /* These chars start a comment anywhere in a source file (except inside
-   another comment */
+   another comment */
 const char comment_chars[] = ";";
 
 /* These chars only start a comment at the beginning of a line.  */
@@ -153,330 +137,376 @@ const char line_comment_chars[] = "#";
 
 const char line_separator_chars[] = "";
 
-/* Chars that can be used to separate mant from exp in floating point nums */
+/* Chars that can be used to separate mant from exp in floating point nums */
 const char EXP_CHARS[] = "eE";
 
-/* Chars that mean this number is a floating point constant */
-/* as in 0f123.456 */
-/* or    0H1.234E-12 (see exp chars above) */
+/* Chars that mean this number is a floating point constant.
+   as in 0f123.456
+   or    0H1.234E-12 (see exp chars above).  */
 const char FLT_CHARS[] = "dDfF";
 
-extern void float_cons (), cons (), s_globl (), s_space (),
-  s_set (), s_lcomm ();
-
-const pseudo_typeS md_pseudo_table[] =
-{
-  {"align", s_align_bytes, 4},
-  {"def", s_set, 0},
-  {"dfloat", float_cons, 'd'},
-  {"ffloat", float_cons, 'f'},
-  {"global", s_globl, 0},
-  {"half", cons, 2},
-  {"bss", s_lcomm, 1},
-  {"string", stringer, 0},
-  {"word", cons, 4},
-  /* Force set to be treated as an instruction.  */
-  {"set", NULL, 0},
-  {".set", s_set, 0},
-  {0}
-};
-
 void
-md_begin ()
+md_begin (void)
 {
   const char *retval = NULL;
   unsigned int i = 0;
 
-  /* initialize hash table */
-
+  /* Initialize hash table.  */
   op_hash = hash_new ();
 
-  /* loop until you see the end of the list */
-
   while (*m88k_opcodes[i].name)
     {
       char *name = m88k_opcodes[i].name;
 
-      /* hash each mnemonic and record its position */
-
+      /* Hash each mnemonic and record its position.  */
       retval = hash_insert (op_hash, name, &m88k_opcodes[i]);
 
       if (retval != NULL)
        as_fatal (_("Can't hash instruction '%s':%s"),
                  m88k_opcodes[i].name, retval);
 
-      /* skip to next unique mnemonic or end of list */
-
+      /* Skip to next unique mnemonic or end of list.  */
       for (i++; !strcmp (m88k_opcodes[i].name, name); i++)
        ;
     }
 }
 \f
-CONST char *md_shortopts = "";
-struct option md_longopts[] = {
+const char *md_shortopts = "";
+struct option md_longopts[] =
+{
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
 
 int
-md_parse_option (c, arg)
-     int c;
-     char *arg;
+md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 void
-md_show_usage (stream)
-     FILE *stream;
+md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
 {
 }
 \f
-void
-md_assemble (op)
-     char *op;
+static char *
+get_o6 (char *param, unsigned *valp)
 {
-  char *param, *thisfrag;
-  char c;
-  struct m88k_opcode *format;
-  struct m88k_insn insn;
+  unsigned val;
+  char *save_ptr;
 
-  assert (op);
+  save_ptr = input_line_pointer;
+  input_line_pointer = param;
+  val = get_absolute_expression ();
+  param = input_line_pointer;
+  input_line_pointer = save_ptr;
 
-  /* skip over instruction to find parameters */
+  if (val & 0x3)
+    as_warn (_("Removed lower 2 bits of expression"));
 
-  for (param = op; *param != 0 && !isspace (*param); param++)
-    ;
-  c = *param;
-  *param++ = '\0';
+  *valp = val;
 
-  /* try to find the instruction in the hash table */
+  return (param);
+}
 
-  if ((format = (struct m88k_opcode *) hash_find (op_hash, op)) == NULL)
-    {
-      as_bad (_("Invalid mnemonic '%s'"), op);
-      return;
-    }
+static char *
+get_vec9 (char *param, unsigned *valp)
+{
+  unsigned val;
+  char *save_ptr;
 
-  /* try parsing this instruction into insn */
+  save_ptr = input_line_pointer;
+  input_line_pointer = param;
+  val = get_absolute_expression ();
+  param = input_line_pointer;
+  input_line_pointer = save_ptr;
 
-  insn.exp.X_add_symbol = 0;
-  insn.exp.X_op_symbol = 0;
-  insn.exp.X_add_number = 0;
-  insn.exp.X_op = O_illegal;
-  insn.reloc = NO_RELOC;
+  if (val >= 1 << 9)
+    as_warn (_("Expression truncated to 9 bits"));
 
-  while (!calcop (format, param, &insn))
-    {
-      /* if it doesn't parse try the next instruction */
+  *valp = val % (1 << 9);
 
-      if (!strcmp (format[0].name, format[1].name))
-       format++;
-      else
-       {
-         as_fatal (_("Parameter syntax error"));
-         return;
-       }
-    }
+  return param;
+}
 
-  /* grow the current frag and plop in the opcode */
+static char *
+get_bf2 (char *param, int bc)
+{
+  int depth = 0;
+  int c;
 
-  thisfrag = frag_more (4);
-  md_number_to_chars (thisfrag, insn.opcode, 4);
+  for (;;)
+    {
+      c = *param;
+      if (c == 0)
+       return param;
+      else if (c == '(')
+       depth++;
+      else if (c == ')')
+       depth--;
+      else if (c == bc && depth <= 0)
+       return param;
+      param++;
+    }
+}
 
-  /* if this instruction requires labels mark it for later */
+static char *
+match_name (char *param,
+           struct field_val_assoc *assoc_tab,
+           unsigned *valp)
+{
+  int i;
+  char *name;
+  int name_len;
 
-  switch (insn.reloc)
+  for (i = 0;; i++)
     {
-    case NO_RELOC:
-      break;
-
-    case RELOC_LO16:
-    case RELOC_HI16:
-      fix_new_exp (frag_now,
-                  thisfrag - frag_now->fr_literal + 2,
-                  2,
-                  &insn.exp,
-                  0,
-                  insn.reloc);
-      break;
+      name = assoc_tab[i].name;
+      if (name == NULL)
+       return NULL;
+      name_len = strlen (name);
+      if (!strncmp (param, name, name_len))
+       {
+         *valp = assoc_tab[i].val;
+         return param + name_len;
+       }
+    }
+}
 
-    case RELOC_IW16:
-      fix_new_exp (frag_now,
-                  thisfrag - frag_now->fr_literal,
-                  4,
-                  &insn.exp,
-                  0,
-                  insn.reloc);
-      break;
+static char *
+get_bf_offset_expression (char *param, unsigned *offsetp)
+{
+  unsigned offset;
 
-    case RELOC_PC16:
-      fix_new_exp (frag_now,
-                  thisfrag - frag_now->fr_literal + 2,
-                  2,
-                  &insn.exp,
-                  1,
-                  insn.reloc);
-      break;
+  if (ISALPHA (param[0]))
+    {
+      param[0] = TOLOWER (param[0]);
+      param[1] = TOLOWER (param[1]);
 
-    case RELOC_PC26:
-      fix_new_exp (frag_now,
-                  thisfrag - frag_now->fr_literal,
-                  4,
-                  &insn.exp,
-                  1,
-                  insn.reloc);
-      break;
+      param = match_name (param, cmpslot, offsetp);
 
-    default:
-      as_fatal (_("Unknown relocation type"));
-      break;
+      return param;
     }
+  else
+    {
+      input_line_pointer = param;
+      offset = get_absolute_expression ();
+      param = input_line_pointer;
+    }
+
+  *offsetp = offset;
+  return param;
 }
 
-static int
-calcop (format, param, insn)
-     struct m88k_opcode *format;
-     char *param;
-     struct m88k_insn *insn;
+static char *
+get_bf (char *param, unsigned *valp)
 {
-  char *fmt = format->op_spec;
-  int f;
-  unsigned val;
-  unsigned opcode;
-  int reg_prefix = 'r';
+  unsigned offset = 0;
+  unsigned width = 0;
+  char *xp;
+  char *save_ptr;
 
-  insn->opcode = format->opcode;
-  opcode = 0;
+  xp = get_bf2 (param, '<');
 
-  for (;;)
+  save_ptr = input_line_pointer;
+  input_line_pointer = param;
+  if (*xp == 0)
     {
-      if (param == 0)
-       return 0;
-      f = *fmt++;
-      switch (f)
-       {
-       case 0:
-         insn->opcode |= opcode;
-         return (*param == 0 || *param == '\n');
+      /* We did not find '<'.  We have an offset (width implicitly 32).  */
+      param = get_bf_offset_expression (param, &offset);
+      input_line_pointer = save_ptr;
+      if (param == NULL)
+       return NULL;
+    }
+  else
+    {
+      *xp++ = 0;               /* Overwrite the '<'.  */
+      param = get_bf2 (xp, '>');
+      if (*param == 0)
+       return NULL;
+      *param++ = 0;            /* Overwrite the '>'.  */
 
-       default:
-         if (f != *param++)
-           return 0;
-         break;
+      width = get_absolute_expression ();
+      xp = get_bf_offset_expression (xp, &offset);
+      input_line_pointer = save_ptr;
 
-       case 'd':
-         param = get_reg (param, &val, reg_prefix);
-         reg_prefix = 'r';
-         opcode |= val << 21;
-         break;
+      if (xp + 1 != param)
+       return NULL;
+    }
 
-       case 'o':
-         param = get_o6 (param, &val);
-         opcode |= ((val >> 2) << 7);
-         break;
+  *valp = ((width % 32) << 5) | (offset % 32);
 
-       case 'x':
-         reg_prefix = 'x';
-         break;
+  return param;
+}
 
-       case '1':
-         param = get_reg (param, &val, reg_prefix);
-         reg_prefix = 'r';
-         opcode |= val << 16;
-         break;
+static char *
+get_cr (char *param, unsigned *regnop)
+{
+  unsigned regno;
+  unsigned c;
 
-       case '2':
-         param = get_reg (param, &val, reg_prefix);
-         reg_prefix = 'r';
-         opcode |= val;
-         break;
+  if (!strncmp (param, "cr", 2))
+    {
+      param += 2;
 
-       case '3':
-         param = get_reg (param, &val, 'r');
-         opcode |= (val << 16) | val;
-         break;
+      regno = *param++ - '0';
+      if (regno < 10)
+       {
+         if (regno == 0)
+           {
+             *regnop = 0;
+             return param;
+           }
+         c = *param - '0';
+         if (c < 10)
+           {
+             regno = regno * 10 + c;
+             if (c < 64)
+               {
+                 *regnop = regno;
+                 return param + 1;
+               }
+           }
+         else
+           {
+             *regnop = regno;
+             return param;
+           }
+       }
+      return NULL;
+    }
 
-       case 'I':
-         param = get_imm16 (param, insn);
-         break;
+  param = match_name (param, cr_regs, regnop);
 
-       case 'b':
-         param = get_bf (param, &val);
-         opcode |= val;
-         break;
+  return param;
+}
 
-       case 'p':
-         param = get_pcr (param, insn, RELOC_PC16);
-         break;
+static char *
+get_fcr (char *param, unsigned *regnop)
+{
+  unsigned regno;
+  unsigned c;
 
-       case 'P':
-         param = get_pcr (param, insn, RELOC_PC26);
-         break;
+  if (!strncmp (param, "fcr", 3))
+    {
+      param += 3;
 
-       case 'B':
-         param = get_cmp (param, &val);
-         opcode |= val;
-         break;
+      regno = *param++ - '0';
+      if (regno < 10)
+       {
+         if (regno == 0)
+           {
+             *regnop = 0;
+             return param;
+           }
+         c = *param - '0';
+         if (c < 10)
+           {
+             regno = regno * 10 + c;
+             if (c < 64)
+               {
+                 *regnop = regno;
+                 return param + 1;
+               }
+           }
+         else
+           {
+             *regnop = regno;
+             return param;
+           }
+       }
+      return NULL;
+    }
 
-       case 'M':
-         param = get_cnd (param, &val);
-         opcode |= val;
-         break;
+  param = match_name (param, fcr_regs, regnop);
 
-       case 'c':
-         param = get_cr (param, &val);
-         opcode |= val << 5;
-         break;
+  return param;
+}
 
-       case 'f':
-         param = get_fcr (param, &val);
-         opcode |= val << 5;
-         break;
+#define hexval(z) \
+  (ISDIGIT (z) ? (z) - '0' :                                           \
+   ISLOWER (z) ? (z) - 'a' + 10 :                                      \
+   ISUPPER (z) ? (z) - 'A' + 10 : (unsigned) -1)
 
-       case 'V':
-         param = get_vec9 (param, &val);
-         opcode |= val;
-         break;
+static char *
+getval (char *param, unsigned int *valp)
+{
+  unsigned int val = 0;
+  unsigned int c;
 
-       case '?':
-         /* Having this here repeats the warning somtimes.
-          But can't we stand that?  */
-         as_warn (_("Use of obsolete instruction"));
-         break;
+  c = *param++;
+  if (c == '0')
+    {
+      c = *param++;
+      if (c == 'x' || c == 'X')
+       {
+         c = *param++;
+         c = hexval (c);
+         while (c < 16)
+           {
+             val = val * 16 + c;
+             c = *param++;
+             c = hexval (c);
+           }
+       }
+      else
+       {
+         c -= '0';
+         while (c < 8)
+           {
+             val = val * 8 + c;
+             c = *param++ - '0';
+           }
+       }
+    }
+  else
+    {
+      c -= '0';
+      while (c < 10)
+       {
+         val = val * 10 + c;
+         c = *param++ - '0';
        }
     }
+
+  *valp = val;
+  return param - 1;
 }
 
 static char *
-match_name (param, assoc_tab, valp)
-     char *param;
-     struct field_val_assoc *assoc_tab;
-     unsigned *valp;
+get_cnd (char *param, unsigned *valp)
 {
-  int i;
-  char *name;
-  int name_len;
+  unsigned int val;
 
-  for (i = 0;; i++)
+  if (ISDIGIT (*param))
     {
-      name = assoc_tab[i].name;
-      if (name == NULL)
-       return NULL;
-      name_len = strlen (name);
-      if (!strncmp (param, name, name_len))
+      param = getval (param, &val);
+
+      if (val >= 32)
        {
-         *valp = assoc_tab[i].val;
-         return param + name_len;
+         as_warn (_("Expression truncated to 5 bits"));
+         val %= 32;
        }
     }
+  else
+    {
+      param[0] = TOLOWER (param[0]);
+      param[1] = TOLOWER (param[1]);
+
+      param = match_name (param, cndmsk, valp);
+
+      if (param == NULL)
+       return NULL;
+
+      val = *valp;
+    }
+
+  *valp = val << 21;
+  return param;
 }
 
 static char *
-get_reg (param, regnop, reg_prefix)
-     char *param;
-     unsigned *regnop;
-     int reg_prefix;
+get_reg (char *param, unsigned *regnop, unsigned int reg_prefix)
 {
   unsigned c;
   unsigned regno;
@@ -520,25 +550,23 @@ get_reg (param, regnop, reg_prefix)
 }
 
 static char *
-get_imm16 (param, insn)
-     char *param;
-     struct m88k_insn *insn;
+get_imm16 (char *param, struct m88k_insn *insn)
 {
   enum reloc_type reloc = NO_RELOC;
   unsigned int val;
   char *save_ptr;
 
-  if (!strncmp (param, "hi16", 4) && !isalnum (param[4]))
+  if (!strncmp (param, "hi16", 4) && !ISALNUM (param[4]))
     {
       reloc = RELOC_HI16;
       param += 4;
     }
-  else if (!strncmp (param, "lo16", 4) && !isalnum (param[4]))
+  else if (!strncmp (param, "lo16", 4) && !ISALNUM (param[4]))
     {
       reloc = RELOC_LO16;
       param += 4;
     }
-  else if (!strncmp (param, "iw16", 4) && !isalnum (param[4]))
+  else if (!strncmp (param, "iw16", 4) && !ISALNUM (param[4]))
     {
       reloc = RELOC_IW16;
       param += 4;
@@ -579,10 +607,7 @@ get_imm16 (param, insn)
 }
 
 static char *
-get_pcr (param, insn, reloc)
-     char *param;
-     struct m88k_insn *insn;
-     enum reloc_type reloc;
+get_pcr (char *param, struct m88k_insn *insn, enum reloc_type reloc)
 {
   char *saveptr, *saveparam;
 
@@ -601,9 +626,7 @@ get_pcr (param, insn, reloc)
 }
 
 static char *
-get_cmp (param, valp)
-     char *param;
-     unsigned *valp;
+get_cmp (char *param, unsigned *valp)
 {
   unsigned int val;
   char *save_ptr;
@@ -634,440 +657,228 @@ get_cmp (param, valp)
   return param;
 }
 
-static char *
-get_cnd (param, valp)
-     char *param;
-     unsigned *valp;
+static int
+calcop (struct m88k_opcode *format,
+       char *param,
+       struct m88k_insn *insn)
 {
-  unsigned int val;
-
-  if (isdigit (*param))
-    {
-      param = getval (param, &val);
-
-      if (val >= 32)
-       {
-         as_warn (_("Expression truncated to 5 bits"));
-         val %= 32;
-       }
-    }
-  else
-    {
-      if (isupper (*param))
-       *param = tolower (*param);
-
-      if (isupper (param[1]))
-       param[1] = tolower (param[1]);
-
-      param = match_name (param, cndmsk, valp);
-
-      if (param == NULL)
-       return NULL;
-
-      val = *valp;
-    }
-
-  *valp = val << 21;
-  return param;
-}
+  char *fmt = format->op_spec;
+  int f;
+  unsigned val;
+  unsigned opcode;
+  unsigned int reg_prefix = 'r';
 
-static char *
-get_bf2 (param, bc)
-     char *param;
-     int bc;
-{
-  int depth = 0;
-  int c;
+  insn->opcode = format->opcode;
+  opcode = 0;
 
   for (;;)
     {
-      c = *param;
-      if (c == 0)
-       return param;
-      else if (c == '(')
-       depth++;
-      else if (c == ')')
-       depth--;
-      else if (c == bc && depth <= 0)
-       return param;
-      param++;
-    }
-}
-
-static char *
-get_bf_offset_expression (param, offsetp)
-     char *param;
-     unsigned *offsetp;
-{
-  unsigned offset;
-
-  if (isalpha (param[0]))
-    {
-      if (isupper (param[0]))
-       param[0] = tolower (param[0]);
-      if (isupper (param[1]))
-       param[1] = tolower (param[1]);
-
-      param = match_name (param, cmpslot, offsetp);
-
-      return param;
-    }
-  else
-    {
-      input_line_pointer = param;
-      offset = get_absolute_expression ();
-      param = input_line_pointer;
-    }
-
-  *offsetp = offset;
-  return param;
-}
-
-static char *
-get_bf (param, valp)
-     char *param;
-     unsigned *valp;
-{
-  unsigned offset = 0;
-  unsigned width = 0;
-  char *xp;
-  char *save_ptr;
-
-  xp = get_bf2 (param, '<');
-
-  save_ptr = input_line_pointer;
-  input_line_pointer = param;
-  if (*xp == 0)
-    {
-      /* We did not find '<'.  We have an offset (width implicitly 32).  */
-      param = get_bf_offset_expression (param, &offset);
-      input_line_pointer = save_ptr;
-      if (param == NULL)
-       return NULL;
-    }
-  else
-    {
-      *xp++ = 0;               /* Overwrite the '<' */
-      param = get_bf2 (xp, '>');
-      if (*param == 0)
-       return NULL;
-      *param++ = 0;            /* Overwrite the '>' */
-
-      width = get_absolute_expression ();
-      xp = get_bf_offset_expression (xp, &offset);
-      input_line_pointer = save_ptr;
-
-      if (xp + 1 != param)
-       return NULL;
-    }
-
-  *valp = ((width % 32) << 5) | (offset % 32);
-
-  return param;
-}
-
-static char *
-get_cr (param, regnop)
-     char *param;
-     unsigned *regnop;
-{
-  unsigned regno;
-  unsigned c;
-
-  if (!strncmp (param, "cr", 2))
-    {
-      param += 2;
-
-      regno = *param++ - '0';
-      if (regno < 10)
+      if (param == 0)
+       return 0;
+      f = *fmt++;
+      switch (f)
        {
-         if (regno == 0)
-           {
-             *regnop = 0;
-             return param;
-           }
-         c = *param - '0';
-         if (c < 10)
-           {
-             regno = regno * 10 + c;
-             if (c < 64)
-               {
-                 *regnop = regno;
-                 return param + 1;
-               }
-           }
-         else
-           {
-             *regnop = regno;
-             return param;
-           }
-       }
-      return NULL;
-    }
-
-  param = match_name (param, cr_regs, regnop);
-
-  return param;
-}
-
-static char *
-get_fcr (param, regnop)
-     char *param;
-     unsigned *regnop;
-{
-  unsigned regno;
-  unsigned c;
-
-  if (!strncmp (param, "fcr", 3))
-    {
-      param += 3;
+       case 0:
+         insn->opcode |= opcode;
+         return (*param == 0 || *param == '\n');
 
-      regno = *param++ - '0';
-      if (regno < 10)
-       {
-         if (regno == 0)
-           {
-             *regnop = 0;
-             return param;
-           }
-         c = *param - '0';
-         if (c < 10)
-           {
-             regno = regno * 10 + c;
-             if (c < 64)
-               {
-                 *regnop = regno;
-                 return param + 1;
-               }
-           }
-         else
-           {
-             *regnop = regno;
-             return param;
-           }
-       }
-      return NULL;
-    }
+       default:
+         if (f != *param++)
+           return 0;
+         break;
 
-  param = match_name (param, fcr_regs, regnop);
+       case 'd':
+         param = get_reg (param, &val, reg_prefix);
+         reg_prefix = 'r';
+         opcode |= val << 21;
+         break;
 
-  return param;
-}
+       case 'o':
+         param = get_o6 (param, &val);
+         opcode |= ((val >> 2) << 7);
+         break;
 
-static char *
-get_vec9 (param, valp)
-     char *param;
-     unsigned *valp;
-{
-  unsigned val;
-  char *save_ptr;
+       case 'x':
+         reg_prefix = 'x';
+         break;
 
-  save_ptr = input_line_pointer;
-  input_line_pointer = param;
-  val = get_absolute_expression ();
-  param = input_line_pointer;
-  input_line_pointer = save_ptr;
+       case '1':
+         param = get_reg (param, &val, reg_prefix);
+         reg_prefix = 'r';
+         opcode |= val << 16;
+         break;
 
-  if (val >= 1 << 9)
-    as_warn (_("Expression truncated to 9 bits"));
+       case '2':
+         param = get_reg (param, &val, reg_prefix);
+         reg_prefix = 'r';
+         opcode |= val;
+         break;
 
-  *valp = val % (1 << 9);
+       case '3':
+         param = get_reg (param, &val, 'r');
+         opcode |= (val << 16) | val;
+         break;
 
-  return param;
-}
+       case 'I':
+         param = get_imm16 (param, insn);
+         break;
 
-static char *
-get_o6 (param, valp)
-     char *param;
-     unsigned *valp;
-{
-  unsigned val;
-  char *save_ptr;
+       case 'b':
+         param = get_bf (param, &val);
+         opcode |= val;
+         break;
 
-  save_ptr = input_line_pointer;
-  input_line_pointer = param;
-  val = get_absolute_expression ();
-  param = input_line_pointer;
-  input_line_pointer = save_ptr;
+       case 'p':
+         param = get_pcr (param, insn, RELOC_PC16);
+         break;
 
-  if (val & 0x3)
-    as_warn (_("Removed lower 2 bits of expression"));
+       case 'P':
+         param = get_pcr (param, insn, RELOC_PC26);
+         break;
 
-  *valp = val;
+       case 'B':
+         param = get_cmp (param, &val);
+         opcode |= val;
+         break;
 
-  return(param);
-}
+       case 'M':
+         param = get_cnd (param, &val);
+         opcode |= val;
+         break;
 
-#define hexval(z) \
-  (isdigit (z) ? (z) - '0' :                                           \
-   islower (z) ? (z) - 'a' + 10 :                                      \
-   isupper (z) ? (z) - 'A' + 10 : -1)
+       case 'c':
+         param = get_cr (param, &val);
+         opcode |= val << 5;
+         break;
 
-static char *
-getval (param, valp)
-     char *param;
-     unsigned int *valp;
-{
-  unsigned int val = 0;
-  unsigned int c;
+       case 'f':
+         param = get_fcr (param, &val);
+         opcode |= val << 5;
+         break;
 
-  c = *param++;
-  if (c == '0')
-    {
-      c = *param++;
-      if (c == 'x' || c == 'X')
-       {
-         c = *param++;
-         c = hexval (c);
-         while (c < 16)
-           {
-             val = val * 16 + c;
-             c = *param++;
-             c = hexval (c);
-           }
-       }
-      else
-       {
-         c -= '0';
-         while (c < 8)
-           {
-             val = val * 8 + c;
-             c = *param++ - '0';
-           }
-       }
-    }
-  else
-    {
-      c -= '0';
-      while (c < 10)
-       {
-         val = val * 10 + c;
-         c = *param++ - '0';
+       case 'V':
+         param = get_vec9 (param, &val);
+         opcode |= val;
+         break;
+
+       case '?':
+         /* Having this here repeats the warning somtimes.
+          But can't we stand that?  */
+         as_warn (_("Use of obsolete instruction"));
+         break;
        }
     }
-
-  *valp = val;
-  return param - 1;
 }
 
 void
-md_number_to_chars (buf, val, nbytes)
-     char *buf;
-     valueT val;
-     int nbytes;
+md_assemble (char *op)
 {
-  number_to_chars_bigendian (buf, val, nbytes);
-}
+  char *param, *thisfrag;
+  char c;
+  struct m88k_opcode *format;
+  struct m88k_insn insn;
 
-#if 0
+  assert (op);
 
-/* This routine is never called.  What is it for?
-   Ian Taylor, Cygnus Support 13 Jul 1993 */
+  /* Skip over instruction to find parameters.  */
+  for (param = op; *param != 0 && !ISSPACE (*param); param++)
+    ;
+  c = *param;
+  *param++ = '\0';
 
-void
-md_number_to_imm (buf, val, nbytes, fixP, seg_type)
-     unsigned char *buf;
-     unsigned int val;
-     int nbytes;
-     fixS *fixP;
-     int seg_type;
-{
-  if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC)
+  /* Try to find the instruction in the hash table.  */
+  if ((format = (struct m88k_opcode *) hash_find (op_hash, op)) == NULL)
     {
-      switch (nbytes)
-       {
-       case 4:
-         *buf++ = val >> 24;
-         *buf++ = val >> 16;
-       case 2:
-         *buf++ = val >> 8;
-       case 1:
-         *buf = val;
-         break;
+      as_bad (_("Invalid mnemonic '%s'"), op);
+      return;
+    }
 
-       default:
-         abort ();
+  /* Try parsing this instruction into insn.  */
+  insn.exp.X_add_symbol = 0;
+  insn.exp.X_op_symbol = 0;
+  insn.exp.X_add_number = 0;
+  insn.exp.X_op = O_illegal;
+  insn.reloc = NO_RELOC;
+
+  while (!calcop (format, param, &insn))
+    {
+      /* If it doesn't parse try the next instruction.  */
+      if (!strcmp (format[0].name, format[1].name))
+       format++;
+      else
+       {
+         as_fatal (_("Parameter syntax error"));
+         return;
        }
-      return;
     }
 
-  switch (fixP->fx_r_type)
+  /* Grow the current frag and plop in the opcode.  */
+  thisfrag = frag_more (4);
+  md_number_to_chars (thisfrag, insn.opcode, 4);
+
+  /* If this instruction requires labels mark it for later.  */
+  switch (insn.reloc)
     {
-    case RELOC_IW16:
-      buf[2] = val >> 8;
-      buf[3] = val;
+    case NO_RELOC:
       break;
 
     case RELOC_LO16:
-      buf[0] = val >> 8;
-      buf[1] = val;
+    case RELOC_HI16:
+      fix_new_exp (frag_now,
+                  thisfrag - frag_now->fr_literal + 2,
+                  2,
+                  &insn.exp,
+                  0,
+                  insn.reloc);
       break;
 
-    case RELOC_HI16:
-      buf[0] = val >> 24;
-      buf[1] = val >> 16;
+    case RELOC_IW16:
+      fix_new_exp (frag_now,
+                  thisfrag - frag_now->fr_literal,
+                  4,
+                  &insn.exp,
+                  0,
+                  insn.reloc);
       break;
 
     case RELOC_PC16:
-      val += 4;
-      buf[0] = val >> 10;
-      buf[1] = val >> 2;
+      fix_new_exp (frag_now,
+                  thisfrag - frag_now->fr_literal + 2,
+                  2,
+                  &insn.exp,
+                  1,
+                  insn.reloc);
       break;
 
     case RELOC_PC26:
-      val += 4;
-      buf[0] |= (val >> 26) & 0x03;
-      buf[1] = val >> 18;
-      buf[2] = val >> 10;
-      buf[3] = val >> 2;
-      break;
-
-    case RELOC_32:
-      buf[0] = val >> 24;
-      buf[1] = val >> 16;
-      buf[2] = val >> 8;
-      buf[3] = val;
+      fix_new_exp (frag_now,
+                  thisfrag - frag_now->fr_literal,
+                  4,
+                  &insn.exp,
+                  1,
+                  insn.reloc);
       break;
 
     default:
-      as_fatal (_("Bad relocation type"));
+      as_fatal (_("Unknown relocation type"));
       break;
     }
 }
 
-#endif /* 0 */
-
-void
-md_number_to_disp (buf, val, nbytes)
-     char *buf;
-     int val;
-     int nbytes;
-{
-  as_fatal (_("md_number_to_disp not defined"));
-  md_number_to_chars (buf, val, nbytes);
-}
-
 void
-md_number_to_field (buf, val, nbytes)
-     char *buf;
-     int val;
-     int nbytes;
+md_number_to_chars (char *buf, valueT val, int nbytes)
 {
-  as_fatal (_("md_number_to_field not defined"));
-  md_number_to_chars (buf, val, nbytes);
+  number_to_chars_bigendian (buf, val, nbytes);
 }
 
 #define MAX_LITTLENUMS 6
 
 /* Turn a string in input_line_pointer into a floating point constant of type
    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
-   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
- */
+   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.  */
+
 char *
-md_atof (type, litP, sizeP)
-     char type;
-     char *litP;
-     int *sizeP;
+md_atof (int type, char *litP, int *sizeP)
 {
   int prec;
   LITTLENUM_TYPE words[MAX_LITTLENUMS];
@@ -1120,11 +931,11 @@ md_atof (type, litP, sizeP)
 int md_short_jump_size = 4;
 
 void
-md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
-     char *ptr;
-     addressT from_addr, to_addr;
-     fragS *frag;
-     symbolS *to_symbol;
+md_create_short_jump (char *ptr,
+                     addressT from_addr ATTRIBUTE_UNUSED,
+                     addressT to_addr ATTRIBUTE_UNUSED,
+                     fragS *frag,
+                     symbolS *to_symbol)
 {
   ptr[0] = (char) 0xc0;
   ptr[1] = 0x00;
@@ -1142,11 +953,11 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
 int md_long_jump_size = 4;
 
 void
-md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
-     char *ptr;
-     addressT from_addr, to_addr;
-     fragS *frag;
-     symbolS *to_symbol;
+md_create_long_jump (char *ptr,
+                    addressT from_addr ATTRIBUTE_UNUSED,
+                    addressT to_addr ATTRIBUTE_UNUSED,
+                    fragS *frag,
+                    symbolS *to_symbol)
 {
   ptr[0] = (char) 0xc0;
   ptr[1] = 0x00;
@@ -1162,165 +973,18 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
 }
 
 int
-md_estimate_size_before_relax (fragP, segment_type)
-     fragS *fragP;
-     segT segment_type;
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+                              segT segment_type ATTRIBUTE_UNUSED)
 {
   as_fatal (_("Relaxation should never occur"));
-  return (-1);
-}
-
-#if 0
-
-/* As far as I can tell, this routine is never called.  What is it
-   doing here?
-   Ian Taylor, Cygnus Support 13 Jul 1993 */
-
-/*
- * Risc relocations are completely different, so it needs
- * this machine dependent routine to emit them.
- */
-void
-emit_relocations (fixP, segment_address_in_file)
-     fixS *fixP;
-     relax_addressT segment_address_in_file;
-{
-  struct reloc_info_m88k ri;
-  symbolS *symbolP;
-  extern char *next_object_file_charP;
-
-  bzero ((char *) &ri, sizeof (ri));
-  for (; fixP; fixP = fixP->fx_next)
-    {
-      if (fixP->fx_r_type >= NO_RELOC)
-       {
-         fprintf (stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
-         abort ();
-       }
-
-      if ((symbolP = fixP->fx_addsy) != NULL)
-       {
-         ri.r_address = fixP->fx_frag->fr_address +
-           fixP->fx_where - segment_address_in_file;
-         if ((symbolP->sy_type & N_TYPE) == N_UNDF)
-           {
-             ri.r_extern = 1;
-             ri.r_symbolnum = symbolP->sy_number;
-           }
-         else
-           {
-             ri.r_extern = 0;
-             ri.r_symbolnum = symbolP->sy_type & N_TYPE;
-           }
-         if (symbolP && symbol_get_frag (symbolP))
-           {
-             ri.r_addend = symbol_get_frag (symbolP)->fr_address;
-           }
-         ri.r_type = fixP->fx_r_type;
-         if (fixP->fx_pcrel)
-           {
-             ri.r_addend -= ri.r_address;
-           }
-         else
-           {
-             ri.r_addend = fixP->fx_addnumber;
-           }
-
-         append (&next_object_file_charP, (char *) &ri, sizeof (ri));
-       }
-    }
-}
-
-#endif /* 0 */
-
-#if 0
-
-/* This routine can be subsumed by s_lcomm in read.c.
-   Ian Taylor, Cygnus Support 13 Jul 1993 */
-
-static void
-s_bss ()
-{
-  char *name;
-  char c;
-  char *p;
-  int temp, bss_align;
-  symbolS *symbolP;
-
-  name = input_line_pointer;
-  c = get_symbol_end ();
-  p = input_line_pointer;
-  *p = c;
-  SKIP_WHITESPACE ();
-  if (*input_line_pointer != ',')
-    {
-      as_warn (_("Expected comma after name"));
-      ignore_rest_of_line ();
-      return;
-    }
-  input_line_pointer++;
-  if ((temp = get_absolute_expression ()) < 0)
-    {
-      as_warn (_("BSS length (%d.) <0! Ignored."), temp);
-      ignore_rest_of_line ();
-      return;
-    }
-  *p = 0;
-  symbolP = symbol_find_or_make (name);
-  *p = c;
-  if (*input_line_pointer == ',')
-    {
-      input_line_pointer++;
-      bss_align = get_absolute_expression ();
-    }
-  else
-    bss_align = 0;
-
-  if (!S_IS_DEFINED(symbolP)
-      || S_GET_SEGMENT(symbolP) == SEG_BSS)
-    {
-      if (! need_pass_2)
-       {
-         char *p;
-         segT current_seg = now_seg;
-         subsegT current_subseg = now_subseg;
-
-         subseg_set (SEG_BSS, 1); /* switch to bss     */
-
-         if (bss_align)
-           frag_align (bss_align, 0, 0);
-
-         /* detach from old frag */
-         if (symbolP->sy_type == N_BSS && symbol_get_frag (symbolP) != NULL)
-           symbol_get_frag (symbolP)->fr_symbol = NULL;
-
-         symbol_set_frag (symbolP, frag_now);
-         p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
-                       (offsetT) temp, (char *)0);
-         *p = 0;
-         S_SET_SEGMENT (symbolP, SEG_BSS);
-
-         subseg_set (current_seg, current_subseg);
-       }
-    }
-  else
-    {
-      as_warn (_("Ignoring attempt to re-define symbol %s."), name);
-    }
-
-  while (!is_end_of_line[(unsigned char) *input_line_pointer])
-    {
-      input_line_pointer++;
-    }
+  return -1;
 }
 
-#endif /* 0 */
-
 #ifdef M88KCOFF
 
 /* These functions are needed if we are linking with obj-coffbfd.c.
    That file may be replaced by a more BFD oriented version at some
-   point.  If that happens, these functions should be rexamined.
+   point.  If that happens, these functions should be reexamined.
 
    Ian Lance Taylor, Cygnus Support, 13 July 1993.  */
 
@@ -1328,8 +992,7 @@ s_bss ()
    return the BFD relocation type to use for it.  */
 
 short
-tc_coff_fix2rtype (fixp)
-     fixS *fixp;
+tc_coff_fix2rtype (fixS *fixp)
 {
   switch (fixp->fx_r_type)
     {
@@ -1355,31 +1018,30 @@ tc_coff_fix2rtype (fixp)
    file itself.  */
 
 void
-md_apply_fix (fixp, val)
-     fixS *fixp;
-     long val;
+md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
 {
+  long val = * (long *) valP;
   char *buf;
 
-  buf = fixp->fx_frag->fr_literal + fixp->fx_where;
-  fixp->fx_offset = 0;
+  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+  fixP->fx_offset = 0;
 
-  switch (fixp->fx_r_type)
+  switch (fixP->fx_r_type)
     {
     case RELOC_IW16:
-      fixp->fx_offset = val >> 16;
+      fixP->fx_offset = val >> 16;
       buf[2] = val >> 8;
       buf[3] = val;
       break;
 
     case RELOC_LO16:
-      fixp->fx_offset = val >> 16;
+      fixP->fx_offset = val >> 16;
       buf[0] = val >> 8;
       buf[1] = val;
       break;
 
     case RELOC_HI16:
-      fixp->fx_offset = val >> 16;
+      fixP->fx_offset = val >> 16;
       buf[0] = val >> 8;
       buf[1] = val;
       break;
@@ -1406,14 +1068,16 @@ md_apply_fix (fixp, val)
     default:
       abort ();
     }
+
+  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+    fixP->fx_done = 1;
 }
 
 /* Where a PC relative offset is calculated from.  On the m88k they
    are calculated from just after the instruction.  */
 
 long
-md_pcrel_from (fixp)
-     fixS *fixp;
+md_pcrel_from (fixS *fixp)
 {
   switch (fixp->fx_r_type)
     {
@@ -1424,14 +1088,12 @@ md_pcrel_from (fixp)
     default:
       abort ();
     }
-  /*NOTREACHED*/
 }
 
 /* Fill in rs_align_code fragments.  */
 
 void
-m88k_handle_align (fragp)
-     fragS *fragp;
+m88k_handle_align (fragS *fragp)
 {
   static const unsigned char nop_pattern[] = { 0xf4, 0x00, 0x58, 0x00 };
 
@@ -1458,3 +1120,19 @@ m88k_handle_align (fragp)
 }
 
 #endif /* M88KCOFF */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+  {"align", s_align_bytes, 4},
+  {"def", s_set, 0},
+  {"dfloat", float_cons, 'd'},
+  {"ffloat", float_cons, 'f'},
+  {"half", cons, 2},
+  {"bss", s_lcomm, 1},
+  {"string", stringer, 0},
+  {"word", cons, 4},
+  /* Force set to be treated as an instruction.  */
+  {"set", NULL, 0},
+  {".set", s_set, 0},
+  {NULL, NULL, 0}
+};
This page took 0.042603 seconds and 4 git commands to generate.