Convert to ISO C90 formatting
authorNick Clifton <nickc@redhat.com>
Wed, 23 Mar 2005 11:18:14 +0000 (11:18 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 23 Mar 2005 11:18:14 +0000 (11:18 +0000)
gas/ChangeLog
gas/config/atof-vax.c
gas/config/tc-pdp11.c
gas/config/tc-tic30.c
gas/config/tc-tic30.h

index ec121e1d8d141173e4e1b39711ead95e88c6d1fb..ad73b79f0eba6ef188861d296bbf51195221da72 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-23  Nick Clifton  <nickc@redhat.com>
+
+       * config/tc-tic30.c: Convert to ISO C90 formatting.
+       * config/tc-tic30.h: Convert to ISO C90 formatting.
+       * config/tc-pdp11.c: Convert to ISO C90 formatting.
+       * config/atof-vax.c: Convert to ISO C90 formatting.
+
 2005-03-21  Maciej W. Rozycki  <macro@mips.com>
 
        * config/tc-mips.c (mips_frob_file): Sort BFD_RELOC_MIPS16_LO16
index 7c9f04e7fd1c1e802ed294230acf862a802e7e62..b94e5609f91406eb744fd6443e65429495f9442e 100644 (file)
@@ -1,5 +1,5 @@
 /* atof_vax.c - turn a Flonum into a VAX floating point number
-   Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000
+   Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 #include "as.h"
 
-static int atof_vax_sizeof PARAMS ((int));
-static int next_bits PARAMS ((int));
-static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
-static int what_kind_of_float PARAMS ((int, int *, long *));
-static char *atof_vax PARAMS ((char *, int, LITTLENUM_TYPE *));
-
 /* Precision in LittleNums.  */
-#define MAX_PRECISION (8)
-#define H_PRECISION (8)
-#define G_PRECISION (4)
-#define D_PRECISION (4)
-#define F_PRECISION (2)
+#define MAX_PRECISION  8
+#define H_PRECISION    8
+#define G_PRECISION    4
+#define D_PRECISION    4
+#define F_PRECISION    2
 
 /* Length in LittleNums of guard bits.  */
-#define GUARD (2)
+#define GUARD          2
 
-int flonum_gen2vax PARAMS ((int format_letter, FLONUM_TYPE * f,
-                           LITTLENUM_TYPE * words));
+int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *);
 
 /* Number of chars in flonum type 'letter'.  */
+
 static int
-atof_vax_sizeof (letter)
-     int letter;
+atof_vax_sizeof (int letter)
 {
   int return_value;
 
-  /*
-   * Permitting uppercase letters is probably a bad idea.
-   * Please use only lower-cased letters in case the upper-cased
-   * ones become unsupported!
-   */
+  /* Permitting uppercase letters is probably a bad idea.
+     Please use only lower-cased letters in case the upper-cased
+     ones become unsupported!  */
   switch (letter)
     {
     case 'f':
@@ -75,8 +66,9 @@ atof_vax_sizeof (letter)
       return_value = 0;
       break;
     }
-  return (return_value);
-}                              /* atof_vax_sizeof */
+
+  return return_value;
+}
 
 static const long mask[] =
 {
@@ -116,14 +108,13 @@ static const long mask[] =
 };
 \f
 
-/* Shared between flonum_gen2vax and next_bits */
+/* Shared between flonum_gen2vax and next_bits */
 static int bits_left_in_littlenum;
 static LITTLENUM_TYPE *littlenum_pointer;
 static LITTLENUM_TYPE *littlenum_end;
 
 static int
-next_bits (number_of_bits)
-     int number_of_bits;
+next_bits (int number_of_bits)
 {
   int return_value;
 
@@ -144,23 +135,22 @@ next_bits (number_of_bits)
       bits_left_in_littlenum -= number_of_bits;
       return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
     }
-  return (return_value);
+  return return_value;
 }
 
 static void
-make_invalid_floating_point_number (words)
-     LITTLENUM_TYPE *words;
+make_invalid_floating_point_number (LITTLENUM_TYPE *words)
 {
-  *words = 0x8000;             /* Floating Reserved Operand Code */
+  *words = 0x8000;             /* Floating Reserved Operand Code */
 }
+
 \f
 static int                     /* 0 means letter is OK.  */
-what_kind_of_float (letter, precisionP, exponent_bitsP)
-     int letter;               /* In: lowercase please. What kind of float? */
-     int *precisionP;          /* Number of 16-bit words in the float.  */
-     long *exponent_bitsP;     /* Number of exponent bits.  */
+what_kind_of_float (int letter,                        /* In: lowercase please. What kind of float?  */
+                   int *precisionP,            /* Number of 16-bit words in the float.  */
+                   long *exponent_bitsP)       /* Number of exponent bits.  */
 {
-  int retval;                  /* 0: OK.  */
+  int retval;
 
   retval = 0;
   switch (letter)
@@ -189,29 +179,24 @@ what_kind_of_float (letter, precisionP, exponent_bitsP)
       retval = 69;
       break;
     }
-  return (retval);
+  return retval;
 }
 \f
-/***********************************************************************\
- *                                                                     *
- *     Warning: this returns 16-bit LITTLENUMs, because that is        *
- *     what the VAX thinks in. It is up to the caller to figure        *
- *     out any alignment problems and to conspire for the bytes/word   *
- *     to be emitted in the right order. Bigendians beware!            *
- *                                                                     *
- \***********************************************************************/
-
-static char *                          /* Return pointer past text consumed.  */
-atof_vax (str, what_kind, words)
-     char *str;                        /* Text to convert to binary.  */
-     int what_kind;            /* 'd', 'f', 'g', 'h' */
-     LITTLENUM_TYPE *words;    /* Build the binary here.  */
+/* Warning: this returns 16-bit LITTLENUMs, because that is
+   what the VAX thinks in. It is up to the caller to figure
+   out any alignment problems and to conspire for the bytes/word
+   to be emitted in the right order. Bigendians beware!  */
+
+static char *
+atof_vax (char *str,                   /* Text to convert to binary.  */
+         int what_kind,                /* 'd', 'f', 'g', 'h'  */
+         LITTLENUM_TYPE *words)        /* Build the binary here.  */
 {
   FLONUM_TYPE f;
   LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
-  /* Extra bits for zeroed low-order bits.  */
-  /* The 1st MAX_PRECISION are zeroed, */
-  /* the last contain flonum bits.  */
+  /* Extra bits for zeroed low-order bits.
+     The 1st MAX_PRECISION are zeroed,
+     the last contain flonum bits.  */
   char *return_value;
   int precision;               /* Number of 16-bit words in the format.  */
   long exponent_bits;
@@ -225,7 +210,7 @@ atof_vax (str, what_kind, words)
 
   if (what_kind_of_float (what_kind, &precision, &exponent_bits))
     {
-      return_value = NULL;     /* We lost.  */
+      return_value = NULL;
       make_invalid_floating_point_number (words);
     }
 
@@ -233,37 +218,30 @@ atof_vax (str, what_kind, words)
     {
       memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
 
-      /* Use more LittleNums than seems */
-      /* necessary: the highest flonum may have */
-      /* 15 leading 0 bits, so could be useless.  */
+      /* Use more LittleNums than seems
+         necessary: the highest flonum may have
+         15 leading 0 bits, so could be useless.  */
       f.high = f.low + precision - 1 + GUARD;
 
       if (atof_generic (&return_value, ".", "eE", &f))
        {
          make_invalid_floating_point_number (words);
-         return_value = NULL;  /* we lost */
-       }
-      else
-       {
-         if (flonum_gen2vax (what_kind, &f, words))
-           {
-             return_value = NULL;
-           }
+         return_value = NULL;
        }
+      else if (flonum_gen2vax (what_kind, &f, words))
+       return_value = NULL;
     }
-  return (return_value);
-}                              /* atof_vax() */
+
+  return return_value;
+}
 \f
-/*
- * In: a flonum, a vax floating point format.
- * Out: a vax floating-point bit pattern.
- */
-
-int                            /* 0: OK.  */
-flonum_gen2vax (format_letter, f, words)
-     int format_letter;                /* One of 'd' 'f' 'g' 'h'.  */
-     FLONUM_TYPE *f;
-     LITTLENUM_TYPE *words;    /* Deliver answer here.  */
+/* In: a flonum, a vax floating point format.
+   Out: a vax floating-point bit pattern.  */
+
+int
+flonum_gen2vax (int format_letter,     /* One of 'd' 'f' 'g' 'h'.  */
+               FLONUM_TYPE *f,
+               LITTLENUM_TYPE *words)  /* Deliver answer here.  */
 {
   LITTLENUM_TYPE *lp;
   int precision;
@@ -273,16 +251,14 @@ flonum_gen2vax (format_letter, f, words)
   return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
 
   if (return_value != 0)
-    {
-      make_invalid_floating_point_number (words);
-    }
+    make_invalid_floating_point_number (words);
+
   else
     {
       if (f->low > f->leader)
-       {
-         /* 0.0e0 seen.  */
-         memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
-       }
+       /* 0.0e0 seen.  */
+       memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
+
       else
        {
          long exponent_1;
@@ -292,49 +268,31 @@ flonum_gen2vax (format_letter, f, words)
          int exponent_skippage;
          LITTLENUM_TYPE word1;
 
-         /* JF: Deal with new Nan, +Inf and -Inf codes */
+         /* JF: Deal with new Nan, +Inf and -Inf codes */
          if (f->sign != '-' && f->sign != '+')
            {
              make_invalid_floating_point_number (words);
              return return_value;
            }
-         /*
-                        * All vaxen floating_point formats (so far) have:
-                        * Bit 15 is sign bit.
-                        * Bits 14:n are excess-whatever exponent.
-                        * Bits n-1:0 (if any) are most significant bits of fraction.
-                        * Bits 15:0 of the next word are the next most significant bits.
-                        * And so on for each other word.
-                        *
-                        * All this to be compatible with a KF11?? (Which is still faster
-                        * than lots of vaxen I can think of, but it also has higher
-                        * maintenance costs ... sigh).
-                        *
-                        * So we need: number of bits of exponent, number of bits of
-                        * mantissa.
-                        */
-
-#ifdef NEVER                   /******* This zeroing seems redundant - Dean 3may86 **********/
-         /*
-                        * No matter how few bits we got back from the atof()
-                        * routine, add enough zero littlenums so the rest of the
-                        * code won't run out of "significant" bits in the mantissa.
-                        */
-         {
-           LITTLENUM_TYPE *ltp;
-           for (ltp = f->leader + 1;
-                ltp <= f->low + precision;
-                ltp++)
-             {
-               *ltp = 0;
-             }
-         }
-#endif
+
+         /* All vaxen floating_point formats (so far) have:
+            Bit 15 is sign bit.
+            Bits 14:n are excess-whatever exponent.
+            Bits n-1:0 (if any) are most significant bits of fraction.
+            Bits 15:0 of the next word are the next most significant bits.
+            And so on for each other word.
+
+            All this to be compatible with a KF11?? (Which is still faster
+            than lots of vaxen I can think of, but it also has higher
+            maintenance costs ... sigh).
+
+            So we need: number of bits of exponent, number of bits of
+            mantissa.  */
 
          bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
          littlenum_pointer = f->leader;
          littlenum_end = f->low;
-         /* Seek (and forget) 1st significant bit */
+         /* Seek (and forget) 1st significant bit */
          for (exponent_skippage = 0;
               !next_bits (1);
               exponent_skippage++);;
@@ -350,24 +308,19 @@ flonum_gen2vax (format_letter, f, words)
 
          if (exponent_4 & ~mask[exponent_bits])
            {
-             /*
-                                * Exponent overflow. Lose immediately.
-                                */
-
+             /* Exponent overflow. Lose immediately.  */
              make_invalid_floating_point_number (words);
 
-             /*
-                                * We leave return_value alone: admit we read the
-                                * number, but return a floating exception
-                                * because we can't encode the number.
-                                */
+             /* We leave return_value alone: admit we read the
+                number, but return a floating exception
+                because we can't encode the number.  */
            }
          else
            {
              lp = words;
 
-             /* Word 1. Sign, exponent and perhaps high bits.  */
-             /* Assume 2's complement integers.  */
+             /* Word 1. Sign, exponent and perhaps high bits.
+                Assume 2's complement integers.  */
              word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
                       | ((f->sign == '+') ? 0 : 0x8000)
                       | next_bits (15 - exponent_bits));
@@ -375,32 +328,26 @@ flonum_gen2vax (format_letter, f, words)
 
              /* The rest of the words are just mantissa bits.  */
              for (; lp < words + precision; lp++)
-               {
-                 *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
-               }
+               *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
 
              if (next_bits (1))
                {
-                 /*
-                                        * Since the NEXT bit is a 1, round UP the mantissa.
-                                        * The cunning design of these hidden-1 floats permits
-                                        * us to let the mantissa overflow into the exponent, and
-                                        * it 'does the right thing'. However, we lose if the
-                                        * highest-order bit of the lowest-order word flips.
-                                        * Is that clear?
-                                        */
-
+                 /* Since the NEXT bit is a 1, round UP the mantissa.
+                    The cunning design of these hidden-1 floats permits
+                    us to let the mantissa overflow into the exponent, and
+                    it 'does the right thing'. However, we lose if the
+                    highest-order bit of the lowest-order word flips.
+                    Is that clear?  */
                  unsigned long carry;
 
                  /*
-                                         #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
-                                         Please allow at least 1 more bit in carry than is in a LITTLENUM.
-                                         We need that extra bit to hold a carry during a LITTLENUM carry
-                                         propagation. Another extra bit (kept 0) will assure us that we
-                                         don't get a sticky sign bit after shifting right, and that
-                                         permits us to propagate the carry without any masking of bits.
-                                         #endif
-                                         */
+                   #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+                   Please allow at least 1 more bit in carry than is in a LITTLENUM.
+                   We need that extra bit to hold a carry during a LITTLENUM carry
+                   propagation. Another extra bit (kept 0) will assure us that we
+                   don't get a sticky sign bit after shifting right, and that
+                   permits us to propagate the carry without any masking of bits.
+                   #endif   */
                  for (carry = 1, lp--;
                       carry && (lp >= words);
                       lp--)
@@ -413,68 +360,61 @@ flonum_gen2vax (format_letter, f, words)
                  if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
                    {
                      make_invalid_floating_point_number (words);
-                     /*
-                                                * We leave return_value alone: admit we read the
-                                                * number, but return a floating exception
-                                                * because we can't encode the number.
-                                                */
+                     /* We leave return_value alone: admit we read the
+                        number, but return a floating exception
+                        because we can't encode the number.  */
                    }
-               }               /* if (we needed to round up) */
-           }                   /* if (exponent overflow) */
-       }                       /* if (0.0e0) */
-    }                          /* if (float_type was OK) */
-  return (return_value);
-}                              /* flonum_gen2vax() */
-
-/* JF this used to be in vax.c but this looks like a better place for it */
-
-/*
- *             md_atof()
- *
- * In: input_line_pointer->the 1st character of a floating-point
- *             number.
- *     1 letter denoting the type of statement that wants a
- *             binary floating point number returned.
- *     Address of where to build floating point literal.
- *             Assumed to be 'big enough'.
- *     Address of where to return size of literal (in chars).
- *
- * Out:        Input_line_pointer->of next char after floating number.
- *     Error message, or 0.
- *     Floating point literal.
- *     Number of chars we used for the literal.
- */
-
-#define MAXIMUM_NUMBER_OF_LITTLENUMS (8)       /* For .hfloats.  */
+               }
+           }
+       }
+    }
+  return return_value;
+}
+
+/* JF this used to be in vax.c but this looks like a better place for it.  */
+
+/* In: input_line_pointer->the 1st character of a floating-point
+               number.
+       1 letter denoting the type of statement that wants a
+               binary floating point number returned.
+       Address of where to build floating point literal.
+               Assumed to be 'big enough'.
+       Address of where to return size of literal (in chars).
+  
+   Out:        Input_line_pointer->of next char after floating number.
+       Error message, or 0.
+       Floating point literal.
+       Number of chars we used for the literal.  */
+
+#define MAXIMUM_NUMBER_OF_LITTLENUMS  8        /* For .hfloats.  */
 
 char *
-md_atof (what_statement_type, literalP, sizeP)
-     int what_statement_type;
-     char *literalP;
-     int *sizeP;
+md_atof (int what_statement_type,
+        char *literalP,
+        int *sizeP)
 {
   LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS];
-  register char kind_of_float;
-  register int number_of_chars;
-  register LITTLENUM_TYPE *littlenumP;
+  char kind_of_float;
+  int number_of_chars;
+  LITTLENUM_TYPE *littlenumP;
 
   switch (what_statement_type)
     {
-    case 'F':                  /* .float */
-    case 'f':                  /* .ffloat */
+    case 'F':
+    case 'f':
       kind_of_float = 'f';
       break;
 
-    case 'D':                  /* .double */
-    case 'd':                  /* .dfloat */
+    case 'D':
+    case 'd':
       kind_of_float = 'd';
       break;
 
-    case 'g':                  /* .gfloat */
+    case 'g':
       kind_of_float = 'g';
       break;
 
-    case 'h':                  /* .hfloat */
+    case 'h':
       kind_of_float = 'h';
       break;
 
@@ -485,17 +425,15 @@ md_atof (what_statement_type, literalP, sizeP)
 
   if (kind_of_float)
     {
-      register LITTLENUM_TYPE *limit;
+      LITTLENUM_TYPE *limit;
 
       input_line_pointer = atof_vax (input_line_pointer,
                                     kind_of_float,
                                     words);
-      /*
-       * The atof_vax() builds up 16-bit numbers.
-       * Since the assembler may not be running on
-       * a little-endian machine, be very careful about
-       * converting words to chars.
-       */
+      /* The atof_vax() builds up 16-bit numbers.
+         Since the assembler may not be running on
+         a little-endian machine, be very careful about
+         converting words to chars.  */
       number_of_chars = atof_vax_sizeof (kind_of_float);
       know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE));
       limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
@@ -506,12 +444,8 @@ md_atof (what_statement_type, literalP, sizeP)
        };
     }
   else
-    {
-      number_of_chars = 0;
-    };
+    number_of_chars = 0;
 
   *sizeP = number_of_chars;
   return kind_of_float ? NULL : _("Bad call to md_atof()");
 }
-
-/* end of atof-vax.c */
index 71870bdf3153642b893c56ad2d62fe18f05b6bf2..19311e6d75c8c743947bdee4bc69f6e2ff8796b0 100644 (file)
    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.  */
 
-/*
-  Apparently unused functions:
-    md_convert_frag
-    md_estimate_size_before_relax
-    md_create_short_jump
-    md_create_long_jump
-*/
-
 #include "as.h"
 #include "safe-ctype.h"
 #include "opcode/pdp11.h"
 
-static int set_option PARAMS ((char *arg));
-static int set_cpu_model PARAMS ((char *arg));
-static int set_machine_model PARAMS ((char *arg));
-
-extern int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
-                                   LITTLENUM_TYPE * words));
+extern int flonum_gen2vax (int, FLONUM_TYPE * f, LITTLENUM_TYPE *);
 
-#define TRUE 1
+#define TRUE  1
 #define FALSE 0
 
-/*
- * A representation for PDP-11 machine code.
- */
+/* A representation for PDP-11 machine code.  */
 struct pdp11_code
 {
   char *error;
   int code;
-  int additional;      /* is there an additional word? */
-  int word;            /* additional word, if any */
+  int additional;      /* Is there an additional word?  */
+  int word;            /* Additional word, if any.  */
   struct
   {
     bfd_reloc_code_real_type type;
@@ -56,17 +41,13 @@ struct pdp11_code
   } reloc;
 };
 
-/*
- * Instruction set extensions.
- *
- * If you change this from an array to something else, please update
- * the "PDP-11 instruction set extensions" comment in pdp11.h.
- */
+/* Instruction set extensions.
+
+   If you change this from an array to something else, please update
+   the "PDP-11 instruction set extensions" comment in pdp11.h.  */
 int pdp11_extension[PDP11_EXT_NUM];
 
-/*
- * Assembly options.
- */
+/* Assembly options.  */
 
 #define ASM_OPT_PIC 1
 #define ASM_OPT_NUM 2
@@ -74,7 +55,7 @@ int pdp11_extension[PDP11_EXT_NUM];
 int asm_option[ASM_OPT_NUM];
 
 /* 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.  */
@@ -82,12 +63,12 @@ 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";
 
 void pseudo_even (int);
@@ -100,8 +81,94 @@ const pseudo_typeS md_pseudo_table[] =
   { 0, 0, 0 },
 };
 
+static struct hash_control *insn_hash = NULL;
+\f
+static int
+set_option (char *arg)
+{
+  int yes = 1;
+
+  if (strcmp (arg, "all-extensions") == 0
+      || strcmp (arg, "all") == 0)
+    {
+      memset (pdp11_extension, ~0, sizeof pdp11_extension);
+      pdp11_extension[PDP11_NONE] = 0;
+      return 1;
+    }
+  else if (strcmp (arg, "no-extensions") == 0)
+    {
+      memset (pdp11_extension, 0, sizeof pdp11_extension);
+      pdp11_extension[PDP11_BASIC] = 1;
+      return 1;
+    }
+
+  if (strncmp (arg, "no-", 3) == 0)
+    {
+      yes = 0;
+      arg += 3;
+    }
+
+  /* Commersial instructions.  */
+  if (strcmp (arg, "cis") == 0)
+    pdp11_extension[PDP11_CIS] = yes;
+  /* Call supervisor mode.  */
+  else if (strcmp (arg, "csm") == 0)
+    pdp11_extension[PDP11_CSM] = yes;
+  /* Extended instruction set.  */
+  else if (strcmp (arg, "eis") == 0)
+    pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
+  /* KEV11 floating-point.  */
+  else if (strcmp (arg, "fis") == 0
+          || strcmp (arg, "kev11") == 0
+          || strcmp (arg, "kev-11") == 0)
+    pdp11_extension[PDP11_FIS] = yes;
+  /* FP-11 floating-point.  */
+  else if (strcmp (arg, "fpp") == 0
+          || strcmp (arg, "fpu") == 0
+          || strcmp (arg, "fp11") == 0
+          || strcmp (arg, "fp-11") == 0
+          || strcmp (arg, "fpj11") == 0
+          || strcmp (arg, "fp-j11") == 0
+          || strcmp (arg, "fpj-11") == 0)
+    pdp11_extension[PDP11_FPP] = yes;
+  /* Limited extended insns.  */
+  else if (strcmp (arg, "limited-eis") == 0)
+    {
+      pdp11_extension[PDP11_LEIS] = yes;
+      if (!pdp11_extension[PDP11_LEIS])
+       pdp11_extension[PDP11_EIS] = 0;
+    }
+  /* Move from processor type.  */
+  else if (strcmp (arg, "mfpt") == 0)
+    pdp11_extension[PDP11_MFPT] = yes;
+  /* Multiprocessor insns:  */
+  else if (strncmp (arg, "mproc", 5) == 0
+          /* TSTSET, WRTLCK */
+          || strncmp (arg, "multiproc", 9) == 0)
+    pdp11_extension[PDP11_MPROC] = yes;
+  /* Move from/to proc status.  */
+  else if (strcmp (arg, "mxps") == 0)
+    pdp11_extension[PDP11_MXPS] = yes;
+  /* Position-independent code.  */
+  else if (strcmp (arg, "pic") == 0)
+    asm_option[ASM_OPT_PIC] = yes;
+  /* Set priority level.  */
+  else if (strcmp (arg, "spl") == 0)
+    pdp11_extension[PDP11_SPL] = yes;
+  /* Microcode instructions:  */
+  else if (strcmp (arg, "ucode") == 0
+          /* LDUB, MED, XFC */
+          || strcmp (arg, "microcode") == 0)
+    pdp11_extension[PDP11_UCODE] = yes;
+  else
+    return 0;
+
+  return 1;
+}
+
+
 static void
-init_defaults ()
+init_defaults (void)
 {
   static int first = 1;
 
@@ -113,10 +180,8 @@ init_defaults ()
     }
 }
 
-static struct hash_control *insn_hash = NULL;
-
 void
-md_begin ()
+md_begin (void)
 {
   int i;
 
@@ -127,21 +192,17 @@ md_begin ()
     as_fatal ("Virtual memory exhausted");
 
   for (i = 0; i < pdp11_num_opcodes; i++)
-    hash_insert (insn_hash, pdp11_opcodes[i].name, (PTR)(pdp11_opcodes + i));
+    hash_insert (insn_hash, pdp11_opcodes[i].name, (void *) (pdp11_opcodes + i));
   for (i = 0; i < pdp11_num_aliases; i++)
-    hash_insert (insn_hash, pdp11_aliases[i].name, (PTR)(pdp11_aliases + i));
+    hash_insert (insn_hash, pdp11_aliases[i].name, (void *) (pdp11_aliases + i));
 }
 
 void
-md_number_to_chars (con, value, nbytes)
-     char con[];
-     valueT value;
-     int nbytes;
+md_number_to_chars (char con[], valueT value, int nbytes)
 {
   /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
-   * 0x12345678 is stored as "\x56\x78\x12\x34". It's
-   * anyones guess what 0x123456 would be stored like.
-   */
+     0x12345678 is stored as "\x56\x78\x12\x34". It's
+     anyones guess what 0x123456 would be stored like.  */
 
   switch (nbytes)
     {
@@ -151,13 +212,13 @@ md_number_to_chars (con, value, nbytes)
       con[0] =  value       & 0xff;
       break;
     case 2:
-      con[0] =  value       & 0xff;
+      con[0] =  value        & 0xff;
       con[1] = (value >>  8) & 0xff;
       break;
     case 4:
       con[0] = (value >> 16) & 0xff;
       con[1] = (value >> 24) & 0xff;
-      con[2] =  value       & 0xff;
+      con[2] =  value        & 0xff;
       con[3] = (value >>  8) & 0xff;
       break;
     default:
@@ -169,10 +230,9 @@ md_number_to_chars (con, value, nbytes)
    that they reference.  Knows about order of bytes in address.  */
 
 void
-md_apply_fix3 (fixP, valP, seg)
-     fixS *fixP;
-     valueT * valP;
-     segT seg ATTRIBUTE_UNUSED;
+md_apply_fix3 (fixS *fixP,
+              valueT * valP,
+              segT seg ATTRIBUTE_UNUSED)
 {
   valueT code;
   valueT mask;
@@ -223,10 +283,8 @@ md_chars_to_number (con, nbytes)
      int nbytes;               /* Number of bytes in the input.  */
 {
   /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
-   * 0x12345678 is stored as "\x56\x78\x12\x34". It's
-   * anyones guess what 0x123456 would be stored like.
-   */
-
+     0x12345678 is stored as "\x56\x78\x12\x34". It's
+     anyones guess what 0x123456 would be stored like.  */
   switch (nbytes)
     {
     case 0:
@@ -237,8 +295,8 @@ md_chars_to_number (con, nbytes)
       return (con[1] << BITS_PER_CHAR) | con[0];
     case 4:
       return
-       (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR)) |
-        ((con[3] << BITS_PER_CHAR) | con[2]);
+       (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR))
+       |((con[3] << BITS_PER_CHAR) | con[2]);
     default:
       BAD_CASE (nbytes);
       return 0;
@@ -280,14 +338,14 @@ parse_reg (char *str, struct pdp11_code *operand)
          return str - 1;
        }
     }
-  else if (strncmp (str, "sp", 2) == 0 ||
-          strncmp (str, "SP", 2) == 0)
+  else if (strncmp (str, "sp", 2) == 0
+          || strncmp (str, "SP", 2) == 0)
     {
       operand->code = 6;
       str += 2;
     }
-  else if (strncmp (str, "pc", 2) == 0 ||
-          strncmp (str, "PC", 2) == 0)
+  else if (strncmp (str, "pc", 2) == 0
+          || strncmp (str, "PC", 2) == 0)
     {
       operand->code = 7;
       str += 2;
@@ -305,10 +363,10 @@ static char *
 parse_ac5 (char *str, struct pdp11_code *operand)
 {
   str = skip_whitespace (str);
-  if (strncmp (str, "fr", 2) == 0 ||
-      strncmp (str, "FR", 2) == 0 ||
-      strncmp (str, "ac", 2) == 0 ||
-      strncmp (str, "AC", 2) == 0)
+  if (strncmp (str, "fr", 2) == 0
+      || strncmp (str, "FR", 2) == 0
+      || strncmp (str, "ac", 2) == 0
+      || strncmp (str, "AC", 2) == 0)
     {
       str += 2;
       switch (*str)
@@ -400,7 +458,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
        }
       break;
 
-    case '#':                          /* immediate */
+      /* Immediate.  */
+    case '#':
     case '$':
       str = parse_expression (str + 1, operand);
       if (operand->error)
@@ -423,7 +482,7 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
               operand->error = "Error in expression";
               break;
             }
-          /* it's a floating literal...  */
+          /* It's a floating literal...  */
           know (operand->reloc.exp.X_add_number < 0);
           flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
           operand->word = literal_float[0];
@@ -437,7 +496,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
       operand->code = 027;
       break;
 
-    default:                           /* label, d(rn), -(rn) */
+      /* label, d(rn), -(rn)  */
+    default:
       {
        char *old = str;
 
@@ -463,7 +523,7 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
 
        str = skip_whitespace (str);
 
-       if (*str != '(')                /* label */
+       if (*str != '(')
          {
            if (operand->reloc.exp.X_op != O_symbol)
              {
@@ -478,7 +538,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
            break;
          }
 
-       str++;                          /* d(rn) */
+       /* d(rn) */
+       str++;
        str = parse_reg (str, operand);
        if (operand->error)
          return str;
@@ -507,9 +568,8 @@ parse_op_no_deferred (char *str, struct pdp11_code *operand)
                operand->word = operand->reloc.exp.X_add_number;
              }
            else
-             {
-               operand->word = operand->reloc.exp.X_add_number;
-             }
+             operand->word = operand->reloc.exp.X_add_number;
+
            break;
          default:
            BAD_CASE (operand->reloc.exp.X_op);
@@ -591,8 +651,7 @@ parse_separator (char *str, int *error)
 }
 
 void
-md_assemble (instruction_string)
-     char *instruction_string;
+md_assemble (char *instruction_string)
 {
   const struct pdp11_opcode *op;
   struct pdp11_code insn, op1, op2;
@@ -957,18 +1016,16 @@ md_assemble (instruction_string)
 }
 
 int
-md_estimate_size_before_relax (fragP, segment)
-     fragS *fragP ATTRIBUTE_UNUSED;
-     segT segment ATTRIBUTE_UNUSED;
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+                              segT segment ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 void
-md_convert_frag (headers, seg, fragP)
-     bfd *headers ATTRIBUTE_UNUSED;
-     segT seg ATTRIBUTE_UNUSED;
-     fragS *fragP ATTRIBUTE_UNUSED;
+md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
+                segT seg ATTRIBUTE_UNUSED,
+                fragS *fragP ATTRIBUTE_UNUSED)
 {
 }
 
@@ -976,98 +1033,25 @@ int md_short_jump_size = 2;
 int md_long_jump_size = 4;
 
 void
-md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
-     char *ptr ATTRIBUTE_UNUSED;
-     addressT from_addr ATTRIBUTE_UNUSED;
-     addressT to_addr ATTRIBUTE_UNUSED;
-     fragS *frag ATTRIBUTE_UNUSED;
-     symbolS *to_symbol ATTRIBUTE_UNUSED;
+md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
+                     addressT from_addr ATTRIBUTE_UNUSED,
+                     addressT to_addr ATTRIBUTE_UNUSED,
+                     fragS *frag ATTRIBUTE_UNUSED,
+                     symbolS *to_symbol ATTRIBUTE_UNUSED)
 {
 }
 
 void
-md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
-     char *ptr ATTRIBUTE_UNUSED;
-     addressT from_addr ATTRIBUTE_UNUSED;
-     addressT to_addr ATTRIBUTE_UNUSED;
-     fragS *frag ATTRIBUTE_UNUSED;
-     symbolS *to_symbol ATTRIBUTE_UNUSED;
+md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
+                    addressT from_addr ATTRIBUTE_UNUSED,
+                    addressT to_addr ATTRIBUTE_UNUSED,
+                    fragS *frag ATTRIBUTE_UNUSED,
+                    symbolS *to_symbol ATTRIBUTE_UNUSED)
 {
 }
 
 static int
-set_option (arg)
-     char *arg;
-{
-  int yes = 1;
-
-  if (strcmp (arg, "all-extensions") == 0 ||
-      strcmp (arg, "all") == 0)
-    {
-      memset (pdp11_extension, ~0, sizeof pdp11_extension);
-      pdp11_extension[PDP11_NONE] = 0;
-      return 1;
-    }
-  else if (strcmp (arg, "no-extensions") == 0)
-    {
-      memset (pdp11_extension, 0, sizeof pdp11_extension);
-      pdp11_extension[PDP11_BASIC] = 1;
-      return 1;
-    }
-
-  if (strncmp (arg, "no-", 3) == 0)
-    {
-      yes = 0;
-      arg += 3;
-    }
-
-  if (strcmp (arg, "cis") == 0)                        /* commersial instructions */
-    pdp11_extension[PDP11_CIS] = yes;
-  else if (strcmp (arg, "csm") == 0)           /* call supervisor mode */
-    pdp11_extension[PDP11_CSM] = yes;
-  else if (strcmp (arg, "eis") == 0)           /* extended instruction set */
-    pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
-  else if (strcmp (arg, "fis") == 0 ||         /* KEV11 floating-point */
-          strcmp (arg, "kev11") == 0 ||
-          strcmp (arg, "kev-11") == 0)
-    pdp11_extension[PDP11_FIS] = yes;
-  else if (strcmp (arg, "fpp") == 0 ||         /* FP-11 floating-point */
-          strcmp (arg, "fpu") == 0 ||
-          strcmp (arg, "fp11") == 0 ||
-          strcmp (arg, "fp-11") == 0 ||
-          strcmp (arg, "fpj11") == 0 ||
-          strcmp (arg, "fp-j11") == 0 ||
-          strcmp (arg, "fpj-11") == 0)
-    pdp11_extension[PDP11_FPP] = yes;
-  else if (strcmp (arg, "limited-eis") == 0)   /* limited extended insns */
-    {
-      pdp11_extension[PDP11_LEIS] = yes;
-      if (!pdp11_extension[PDP11_LEIS])
-       pdp11_extension[PDP11_EIS] = 0;
-    }
-  else if (strcmp (arg, "mfpt") == 0)          /* move from processor type */
-    pdp11_extension[PDP11_MFPT] = yes;
-  else if (strncmp (arg, "mproc", 5) == 0 ||   /* multiprocessor insns: */
-          strncmp (arg, "multiproc", 9) == 0 ) /* TSTSET, WRTLCK */
-    pdp11_extension[PDP11_MPROC] = yes;
-  else if (strcmp (arg, "mxps") == 0)          /* move from/to proc status */
-    pdp11_extension[PDP11_MXPS] = yes;
-  else if (strcmp (arg, "pic") == 0)           /* position-independent code */
-    asm_option[ASM_OPT_PIC] = yes;
-  else if (strcmp (arg, "spl") == 0)           /* set priority level */
-    pdp11_extension[PDP11_SPL] = yes;
-  else if (strcmp (arg, "ucode") == 0 ||       /* microcode instructions: */
-          strcmp (arg, "microcode") == 0)      /* LDUB, MED, XFC */
-    pdp11_extension[PDP11_UCODE] = yes;
-  else
-    return 0;
-
-  return 1;
-}
-
-static int
-set_cpu_model (arg)
-     char *arg;
+set_cpu_model (char *arg)
 {
   char buf[4];
   char *model = buf;
@@ -1082,8 +1066,7 @@ set_cpu_model (arg)
 
   if (model[-1] == 'd')
     {
-      if (arg[0] == 'f' ||
-         arg[0] == 'j')
+      if (arg[0] == 'f' || arg[0] == 'j')
        model[-1] = *arg++;
     }
   else if (model[-1] == 'x')
@@ -1105,7 +1088,7 @@ set_cpu_model (arg)
        return 0;
     }
 
-  /* allow up to two revision letters */
+  /* Allow up to two revision letters.  */
   if (arg[0] != 0)
     *model++ = *arg++;
   if (arg[0] != 0)
@@ -1115,70 +1098,80 @@ set_cpu_model (arg)
 
   set_option ("no-extensions");
 
-  if (strncmp (buf, "a", 1) == 0)              /* KA11 (11/15/20) */
-    return 1; /* no extensions */
+  /* KA11 (11/15/20).  */
+  if (strncmp (buf, "a", 1) == 0)
+    return 1; /* No extensions.  */
 
-  else if (strncmp (buf, "b", 1) == 0)         /* KB11 (11/45/50/55/70) */
-    return set_option ("eis") &&
-           set_option ("spl");
+  /* KB11 (11/45/50/55/70).  */
+  else if (strncmp (buf, "b", 1) == 0)
+    return set_option ("eis") && set_option ("spl");
 
-  else if (strncmp (buf, "da", 2) == 0)                /* KD11-A (11/35/40) */
+  /* KD11-A (11/35/40).  */
+  else if (strncmp (buf, "da", 2) == 0)
     return set_option ("limited-eis");
 
-  else if (strncmp (buf, "db", 2) == 0 ||      /* KD11-B (11/05/10) */
-          strncmp (buf, "dd", 2) == 0)         /* KD11-D (11/04) */
+  /* KD11-B (11/05/10).  */
+  else if (strncmp (buf, "db", 2) == 0
+          /* KD11-D (11/04).  */
+          || strncmp (buf, "dd", 2) == 0)
     return 1; /* no extensions */
 
-  else if (strncmp (buf, "de", 2) == 0)                /* KD11-E (11/34) */
-    return set_option ("eis") &&
-           set_option ("mxps");
-
-  else if (strncmp (buf, "df", 2) == 0 ||      /* KD11-F (11/03) */
-          strncmp (buf, "dh", 2) == 0 ||       /* KD11-H (11/03) */
-          strncmp (buf, "dq", 2) == 0)         /* KD11-Q (11/03) */
-    return set_option ("limited-eis") &&
-           set_option ("mxps");
-
-  else if (strncmp (buf, "dk", 2) == 0)                /* KD11-K (11/60) */
-    return set_option ("eis") &&
-           set_option ("mxps") &&
-           set_option ("ucode");
-
-  else if (strncmp (buf, "dz", 2) == 0)                /* KD11-Z (11/44) */
-    return set_option ("csm") &&
-           set_option ("eis") &&
-           set_option ("mfpt") &&
-           set_option ("mxps") &&
-           set_option ("spl");
-
-  else if (strncmp (buf, "f", 1) == 0)         /* F11 (11/23/24) */
-    return set_option ("eis") &&
-           set_option ("mfpt") &&
-           set_option ("mxps");
-
-  else if (strncmp (buf, "j", 1) == 0)         /* J11 (11/53/73/83/84/93/94)*/
-    return set_option ("csm") &&
-           set_option ("eis") &&
-           set_option ("mfpt") &&
-           set_option ("multiproc") &&
-           set_option ("mxps") &&
-           set_option ("spl");
-
-  else if (strncmp (buf, "t", 1) == 0)         /* T11 (11/21) */
-    return set_option ("limited-eis") &&
-           set_option ("mxps");
+  /* KD11-E (11/34).  */
+  else if (strncmp (buf, "de", 2) == 0)
+    return set_option ("eis") && set_option ("mxps");
+
+  /* KD11-F (11/03).  */
+  else if (strncmp (buf, "df", 2) == 0
+          /* KD11-H (11/03).  */
+          || strncmp (buf, "dh", 2) == 0
+          /* KD11-Q (11/03).  */
+          || strncmp (buf, "dq", 2) == 0)
+    return set_option ("limited-eis") && set_option ("mxps");
+
+  /* KD11-K (11/60).  */
+  else if (strncmp (buf, "dk", 2) == 0)
+    return set_option ("eis")
+      && set_option ("mxps")
+      && set_option ("ucode");
+
+  /* KD11-Z (11/44).  */
+  else if (strncmp (buf, "dz", 2) == 0)
+    return set_option ("csm")
+      && set_option ("eis")
+      && set_option ("mfpt")
+      && set_option ("mxps")
+      && set_option ("spl");
+
+  /* F11 (11/23/24).  */
+  else if (strncmp (buf, "f", 1) == 0)
+    return set_option ("eis")
+      && set_option ("mfpt")
+      && set_option ("mxps");
+
+  /* J11 (11/53/73/83/84/93/94).  */
+  else if (strncmp (buf, "j", 1) == 0)
+    return set_option ("csm")
+      && set_option ("eis")
+      && set_option ("mfpt")
+      && set_option ("multiproc")
+      && set_option ("mxps")
+      && set_option ("spl");
+
+  /* T11 (11/21).  */
+  else if (strncmp (buf, "t", 1) == 0)
+    return set_option ("limited-eis")
+      && set_option ("mxps");
 
   else
     return 0;
 }
 
 static int
-set_machine_model (arg)
-     char *arg;
+set_machine_model (char *arg)
 {
-  if (strncmp (arg, "pdp-11/", 7) != 0 &&
-      strncmp (arg, "pdp11/", 6) != 0 &&
-      strncmp (arg, "11/", 3) != 0)
+  if (strncmp (arg, "pdp-11/", 7) != 0
+      && strncmp (arg, "pdp11/", 6) != 0
+      && strncmp (arg, "11/", 3) != 0)
     return 0;
 
   if (strncmp (arg, "pdp", 3) == 0)
@@ -1188,56 +1181,56 @@ set_machine_model (arg)
   if (strncmp (arg, "11/", 3) == 0)
     arg += 3;
 
-  if (strcmp (arg, "03") == 0)                 /* 11/03 */
-    return set_cpu_model ("kd11f");            /* KD11-F */
+  if (strcmp (arg, "03") == 0)
+    return set_cpu_model ("kd11f");
+
+  else if (strcmp (arg, "04") == 0)
+    return set_cpu_model ("kd11d");
 
-  else if (strcmp (arg, "04") == 0)            /* 11/04 */
-    return set_cpu_model ("kd11d");            /* KD11-D */
+  else if (strcmp (arg, "05") == 0
+          || strcmp (arg, "10") == 0)
+    return set_cpu_model ("kd11b");
 
-  else if (strcmp (arg, "05") == 0 ||          /* 11/05 or 11/10 */
-          strcmp (arg, "10") == 0)
-    return set_cpu_model ("kd11b");            /* KD11-B */
+  else if (strcmp (arg, "15") == 0
+          || strcmp (arg, "20") == 0)
+    return set_cpu_model ("ka11");
 
-  else if (strcmp (arg, "15") == 0 ||          /* 11/15 or 11/20 */
-          strcmp (arg, "20") == 0)
-    return set_cpu_model ("ka11");             /* KA11 */
+  else if (strcmp (arg, "21") == 0)
+    return set_cpu_model ("t11");
 
-  else if (strcmp (arg, "21") == 0)            /* 11/21 */
-    return set_cpu_model ("t11");              /* T11 */
+  else if (strcmp (arg, "23") == 0
+          || strcmp (arg, "24") == 0)
+    return set_cpu_model ("f11");
 
-  else if (strcmp (arg, "23") == 0 ||          /* 11/23 or 11/24 */
-          strcmp (arg, "24") == 0)
-    return set_cpu_model ("f11");              /* F11 */
+  else if (strcmp (arg, "34") == 0
+          || strcmp (arg, "34a") == 0)
+    return set_cpu_model ("kd11e");
 
-  else if (strcmp (arg, "34") == 0 ||          /* 11/34 or 11/34a */
-           strcmp (arg, "34a") == 0)
-    return set_cpu_model ("kd11e");            /* KD11-E */
+  else if (strcmp (arg, "35") == 0
+          || strcmp (arg, "40") == 0)
+    return set_cpu_model ("kd11da");
 
-  else if (strcmp (arg, "35") == 0 ||          /* 11/35 or 11/40 */
-          strcmp (arg, "40") == 0)
-    return set_cpu_model ("kd11da");           /* KD11-A */
+  else if (strcmp (arg, "44") == 0)
+    return set_cpu_model ("kd11dz");
 
-  else if (strcmp (arg, "44") == 0)            /* 11/44 */
-    return set_cpu_model ("kd11dz");           /* KD11-Z */
+  else if (strcmp (arg, "45") == 0
+          || strcmp (arg, "50") == 0
+          || strcmp (arg, "55") == 0
+          || strcmp (arg, "70") == 0)
+    return set_cpu_model ("kb11");
 
-  else if (strcmp (arg, "45") == 0 ||          /* 11/45/50/55/70 */
-          strcmp (arg, "50") == 0 ||
-          strcmp (arg, "55") == 0 ||
-          strcmp (arg, "70") == 0)
-    return set_cpu_model ("kb11");             /* KB11 */
+  else if (strcmp (arg, "60") == 0)
+    return set_cpu_model ("kd11k");
 
-  else if (strcmp (arg, "60") == 0)            /* 11/60 */
-    return set_cpu_model ("kd11k");            /* KD11-K */ /* FPP? */
+  else if (strcmp (arg, "53") == 0
+          || strcmp (arg, "73") == 0
+          || strcmp (arg, "83") == 0
+          || strcmp (arg, "84") == 0
+          || strcmp (arg, "93") == 0
+          || strcmp (arg, "94") == 0)
+    return set_cpu_model ("j11")
+      && set_option ("fpp");
 
-  else if (strcmp (arg, "53") == 0 ||          /* 11/53/73/83/84/93/94 */
-          strcmp (arg, "73") == 0 ||
-          strcmp (arg, "83") == 0 ||
-          strcmp (arg, "84") == 0 ||
-          strcmp (arg, "93") == 0 ||
-          strcmp (arg, "94") == 0)
-    return set_cpu_model ("j11") &&            /* J11 */
-           set_option ("fpp");                 /* All J11 machines come */
-                                               /* with FPP installed.  */
   else
     return 0;
 }
@@ -1257,16 +1250,11 @@ struct option md_longopts[] =
 
 size_t md_longopts_size = sizeof (md_longopts);
 
-/*
- * md_parse_option
- *     Invocation line includes a switch not recognized by the base assembler.
- *     See if it's a processor-specific option.
- */
+/* Invocation line includes a switch not recognized by the base assembler.
+   See if it's a processor-specific option.  */
 
 int
-md_parse_option (c, arg)
-     int c;
-     char *arg;
+md_parse_option (int c, char *arg)
 {
   init_defaults ();
 
@@ -1303,249 +1291,8 @@ md_parse_option (c, arg)
   return 0;
 }
 
-/*
-One possible way of parsing options.
-
-enum
-{
-  OPTION_CSM,
-  OPTION_CIS,
-  ...
-};
-
-struct
-{
-  const char *pattern;
-  int opt;
-  const char *description;
-} options;
-
-static struct options extension_opts[] =
-{
-  { "Ncsm", OPTION_CSM,
-                       "allow (disallow) CSM instruction" },
-  { "Ncis", OPTION_CIS,
-                       "allow (disallow) commersial instruction set" },
-  { "Neis", OPTION_EIS,
-                       "allow (disallow) extended instruction set" },
-  ...
-  { "all-extensions", OPTION_ALL_EXTENSIONS,
-                       "allow all instruction set extensions\n\
-                       (this is the default)" },
-  { "no-extensions", OPTION_NO_EXTENSIONS,
-                       "disallow all instruction set extensions" },
-  { "pic", OPTION_PIC,
-                       "position-independent code" },
-};
-
-static struct options cpu_opts[] =
-{
-  { "Ka_11_*", OPTION_KA11, "KA11 CPU. ..." },
-  { "Kb_11_*", OPTION_KB11, "KB11 CPU. ..." },
-  { "Kd_11_a*", OPTION_KD11A, "KD11-A CPU. ..." },
-  { "Kd_11_b*", OPTION_KD11B, "KD11-B CPU. ..." },
-  { "Kd_11_d*", OPTION_KD11D, "KD11-D CPU. ..." },
-  { "Kd_11_e*", OPTION_KD11E, "KD11-E CPU. ..." },
-  { "Kd_11_f*", OPTION_KD11F, "KD11-F CPU. ..." },
-  { "Kd_11_h*", OPTION_KD11H, "KD11-H CPU. ..." },
-  { "Kd_11_q*", OPTION_KD11Q, "KD11-Q CPU. ..." },
-  { "Kd_11_z*", OPTION_KD11Z, "KD11-Z CPU. ..." },
-  { "Df_11_*", OPTION_F11, "F11 CPU. ..." },
-  { "Dj_11_*", OPTION_J11, "J11 CPU. ..." },
-  { "Dt_11_*", OPTION_T11, "T11 CPU. ..." },
-};
-
-static struct options model_opts[] =
-{
-  { "P03", OPTION_PDP11_03, "same as ..." },
-  { "P04", OPTION_PDP11_04, "same as ..." },
-  { "P05", OPTION_PDP11_05, "same as ..." },
-  { "P10", OPTION_PDP11_10, "same as ..." },
-  { "P15", OPTION_PDP11_15, "same as ..." },
-  { "P20", OPTION_PDP11_20, "same as ..." },
-  { "P21", OPTION_PDP11_21, "same as ..." },
-  { "P24", OPTION_PDP11_24, "same as ..." },
-  { "P34", OPTION_PDP11_34, "same as ..." },
-  { "P34a", OPTION_PDP11_34A, "same as ..." },
-  { "P40", OPTION_PDP11_40, "same as ..." },
-  { "P44", OPTION_PDP11_44, "same as ..." },
-  { "P45", OPTION_PDP11_45, "same as ..." },
-  { "P50", OPTION_PDP11_50, "same as ..." },
-  { "P53", OPTION_PDP11_53, "same as ..." },
-  { "P55", OPTION_PDP11_55, "same as ..." },
-  { "P60", OPTION_PDP11_60, "same as ..." },
-  { "P70", OPTION_PDP11_70, "same as ..." },
-  { "P73", OPTION_PDP11_73, "same as ..." },
-  { "P83", OPTION_PDP11_83, "same as ..." },
-  { "P84", OPTION_PDP11_84, "same as ..." },
-  { "P93", OPTION_PDP11_93, "same as ..." },
-  { "P94", OPTION_PDP11_94, "same as ..." },
-};
-
-struct
-{
-  const char *title;
-  struct options *opts;
-  int num;
-} all_opts[] =
-{
-  { "PDP-11 instruction set extentions",
-    extension_opts,
-    sizeof extension_opts / sizeof extension_opts[0] },
-  { "PDP-11 CPU model options",
-    cpu_opts,
-    sizeof cpu_opts / sizeof cpu_opts[0] },
-  { "PDP-11 machine model options",
-    model_opts,
-    sizeof model_opts / sizeof model_opts[0] },
-};
-
-int
-parse_match (char *arg, char *pattern)
-{
-  int yes = 1;
-
-  while (*pattern)
-    {
-      switch (*pattern++)
-       {
-       case 'N':
-         if (strncmp (arg, "no-") == 0)
-           {
-             yes = 0;
-             arg += 3;
-           }
-         break;
-
-       case 'K':
-         if (arg[0] == 'k')
-           arg++;
-         break;
-
-       case 'D':
-         if (strncmp (arg, "kd", 2) == 0)
-           arg +=2;
-         break;
-
-       case 'P':
-         if (strncmp (arg, "pdp-11/", 7) == 0)
-           arg += 7;
-         else if (strncmp (arg, "pdp11/", 6) == 0)
-           arg += 6;
-         else if (strncmp (arg, "11/", 3) == 0)
-           arg += 3;
-         break;
-
-       case '_':
-         if (arg[0] == "-")
-           {
-             if (*++arg == 0)
-               return 0;
-           }
-         break;
-
-       case '*':
-         return 1;
-
-       default:
-         if (*arg++ != pattern[-1])
-           return 0;
-       }
-    }
-
-  return arg[0] == 0;
-}
-
-int
-fprint_opt (stream, pattern)
-     FILE *stream;
-     const char *pattern;
-{
-  int n;
-
-  while (*pattern)
-    {
-      switch (*pattern++)
-       {
-       case 'N':
-         n += fprintf (stream, "(no-)");
-         break;
-
-       case 'K':
-         n += fprintf (stream, "k");
-         break;
-
-       case 'P':
-         n += fprintf (stream "11/");
-         break;
-
-       case 'D':
-       case '_':
-       case '*':
-         break;
-
-       default:
-         fputc (pattern[-1], stream);
-         n++;
-       }
-    }
-
-  return n;
-}
-
-int
-parse_option (char *arg)
-{
-  int i, j;
-
-  for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
-    {
-      for (j = 0; j < all_opts[i].num; j++)
-       {
-         if (parse_match (arg, all_opts[i].opts[j].pattern))
-           {
-             set_option (all_opts[i].opts[j].opt);
-             return 1;
-           }
-       }
-    }
-
-  return 0;
-}
-
-static void
-fprint_space (stream, n)
-     FILE *stream;
-     int n;
-{
-  while (n--)
-    fputc (' ', stream);
-}
-
 void
-md_show_usage (stream)
-     FILE *stream;
-{
-  int i, j, n;
-
-  for (i = 0; i < sizeof all_opts / sizeof all_opts[0]; i++)
-    {
-      fprintf (stream "\n%s:\n\n", all_opts[i].title);
-
-      for (j = 0; j < all_opts[i].num; j++)
-       {
-         fprintf (stream, "-m");
-         n = fprintf_opt (stream, all_opts[i].opts[j].pattern);
-         fprint_space (stream, 22 - n);
-         fprintf (stream, "%s\n", all_opts[i].opts[j].description);
-       }
-    }
-}
-*/
-
-void
-md_show_usage (stream)
-     FILE *stream;
+md_show_usage (FILE *stream)
 {
   fprintf (stream, "\
 \n\
@@ -1619,40 +1366,37 @@ PDP-11 machine model options:\n\
 }
 
 symbolS *
-md_undefined_symbol (name)
-     char *name ATTRIBUTE_UNUSED;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 valueT
-md_section_align (segment, size)
-     segT segment ATTRIBUTE_UNUSED;
-     valueT size;
+md_section_align (segT segment ATTRIBUTE_UNUSED,
+                 valueT size)
 {
   return (size + 1) & ~1;
 }
 
 long
-md_pcrel_from (fixP)
-     fixS *fixP;
+md_pcrel_from (fixS *fixP)
 {
   return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
 }
 
 /* Translate internal representation of relocation info to BFD target
    format.  */
+
 arelent *
-tc_gen_reloc (section, fixp)
-     asection *section ATTRIBUTE_UNUSED;
-     fixS *fixp;
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
+             fixS *fixp)
 {
   arelent *reloc;
   bfd_reloc_code_real_type code;
 
-  reloc = (arelent *) xmalloc (sizeof (arelent));
+  reloc = xmalloc (sizeof (* reloc));
 
-  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
 
@@ -1691,8 +1435,7 @@ tc_gen_reloc (section, fixp)
 }
 
 void
-pseudo_bss (c)
-     int c ATTRIBUTE_UNUSED;
+pseudo_bss (int c ATTRIBUTE_UNUSED)
 {
   int temp;
 
@@ -1702,12 +1445,9 @@ pseudo_bss (c)
 }
 
 void
-pseudo_even (c)
-     int c ATTRIBUTE_UNUSED;
+pseudo_even (int c ATTRIBUTE_UNUSED)
 {
   int alignment = 1; /* 2^1 */
   frag_align (alignment, 0, 1);
   record_alignment (now_seg, alignment);
 }
-
-/* end of tc-pdp11.c */
index 7234741c9b81990cd643ebd45c8a6264921ce8c6..40baefc21bfa0f39c9c7fc5c416856e5274feafc 100644 (file)
 /* Put here all non-digit non-letter characters that may occur in an
    operand.  */
 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
-static char *ordinal_names[] = {
+static char *ordinal_names[] =
+{
   "first", "second", "third", "fourth", "fifth"
 };
 
 const int md_reloc_size = 0;
 
-const char comment_chars[] = ";";
-const char line_comment_chars[] = "*";
+const char comment_chars[]        = ";";
+const char line_comment_chars[]   = "*";
 const char line_separator_chars[] = "";
 
 const char *md_shortopts = "";
-struct option md_longopts[] = {
+struct option md_longopts[] =
+{
   {NULL, no_argument, NULL, 0}
 };
 
 size_t md_longopts_size = sizeof (md_longopts);
 
-/* Chars that mean this number is a floating point constant.  */
-/* As in 0f12.456 */
-/* or    0d1.2345e12 */
+/* Chars that mean this number is a floating point constant.
+   As in 0f12.456
+   or    0d1.2345e12.  */
 const char FLT_CHARS[] = "fFdDxX";
 
 /* Chars that can be used to separate mant from exp in floating point
    nums.  */
 const char EXP_CHARS[] = "eE";
 
-/* tables for lexical analysis */
+/* Tables for lexical analysis.  */
 static char opcode_chars[256];
 static char register_chars[256];
 static char operand_chars[256];
@@ -71,22 +73,21 @@ static char space_chars[256];
 static char identifier_chars[256];
 static char digit_chars[256];
 
-/* lexical macros */
-#define is_opcode_char(x) (opcode_chars[(unsigned char) x])
-#define is_operand_char(x) (operand_chars[(unsigned char) x])
-#define is_register_char(x) (register_chars[(unsigned char) x])
-#define is_space_char(x) (space_chars[(unsigned char) x])
-#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
-#define is_digit_char(x) (digit_chars[(unsigned char) x])
+/* Lexical macros.  */
+#define is_opcode_char(x)     (opcode_chars     [(unsigned char) x])
+#define is_operand_char(x)    (operand_chars    [(unsigned char) x])
+#define is_register_char(x)   (register_chars   [(unsigned char) x])
+#define is_space_char(x)      (space_chars      [(unsigned char) x])
+#define is_identifier_char(x) (identifier_chars [(unsigned char) x])
+#define is_digit_char(x)      (digit_chars      [(unsigned char) x])
 
-const pseudo_typeS md_pseudo_table[] = {
+const pseudo_typeS md_pseudo_table[] =
+{
   {0, 0, 0}
 };
 
-int debug PARAMS ((const char *string, ...));
-
-int
-debug VPARAMS ((const char *string, ...))
+static int
+debug (const char *string, ...)
 {
   if (flag_debug)
     {
@@ -105,64 +106,85 @@ debug VPARAMS ((const char *string, ...))
     return 0;
 }
 
-/* hash table for opcode lookup */
+/* Hash table for opcode lookup.  */
 static struct hash_control *op_hash;
-/* hash table for parallel opcode lookup */
+/* Hash table for parallel opcode lookup.  */
 static struct hash_control *parop_hash;
-/* hash table for register lookup */
+/* Hash table for register lookup.  */
 static struct hash_control *reg_hash;
-/* hash table for indirect addressing lookup */
+/* Hash table for indirect addressing lookup.  */
 static struct hash_control *ind_hash;
 
 void
-md_begin ()
+md_begin (void)
 {
   const char *hash_err;
+
   debug ("In md_begin()\n");
   op_hash = hash_new ();
+
   {
     const template *current_optab = tic30_optab;
+
     for (; current_optab < tic30_optab_end; current_optab++)
       {
-       hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
+       hash_err = hash_insert (op_hash, current_optab->name,
+                               (char *) current_optab);
        if (hash_err)
-         as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
+         as_fatal ("Internal Error: Can't Hash %s: %s",
+                   current_optab->name, hash_err);
       }
   }
+
   parop_hash = hash_new ();
+
   {
     const partemplate *current_parop = tic30_paroptab;
+
     for (; current_parop < tic30_paroptab_end; current_parop++)
       {
-       hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
+       hash_err = hash_insert (parop_hash, current_parop->name,
+                               (char *) current_parop);
        if (hash_err)
-         as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
+         as_fatal ("Internal Error: Can't Hash %s: %s",
+                   current_parop->name, hash_err);
       }
   }
+
   reg_hash = hash_new ();
+
   {
     const reg *current_reg = tic30_regtab;
+
     for (; current_reg < tic30_regtab_end; current_reg++)
       {
-       hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
+       hash_err = hash_insert (reg_hash, current_reg->name,
+                               (char *) current_reg);
        if (hash_err)
-         as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
+         as_fatal ("Internal Error: Can't Hash %s: %s",
+                   current_reg->name, hash_err);
       }
   }
+
   ind_hash = hash_new ();
+
   {
     const ind_addr_type *current_ind = tic30_indaddr_tab;
+
     for (; current_ind < tic30_indaddrtab_end; current_ind++)
       {
-       hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
+       hash_err = hash_insert (ind_hash, current_ind->syntax,
+                               (char *) current_ind);
        if (hash_err)
-         as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
+         as_fatal ("Internal Error: Can't Hash %s: %s",
+                   current_ind->syntax, hash_err);
       }
   }
-  /* fill in lexical tables:  opcode_chars, operand_chars, space_chars */
+
+  /* Fill in lexical tables:  opcode_chars, operand_chars, space_chars.  */
   {
-    register int c;
-    register char *p;
+    int c;
+    char *p;
 
     for (c = 0; c < 256; c++)
       {
@@ -177,17 +199,20 @@ md_begin ()
            register_chars[c] = opcode_chars[c];
          }
        else if (c == ')' || c == '(')
-         {
-           register_chars[c] = c;
-         }
+         register_chars[c] = c;
+
        if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
          operand_chars[c] = c;
+
        if (ISDIGIT (c) || c == '-')
          digit_chars[c] = c;
+
        if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
          identifier_chars[c] = c;
+
        if (c == ' ' || c == '\t')
          space_chars[c] = c;
+
        if (c == '_')
          opcode_chars[c] = c;
       }
@@ -196,34 +221,39 @@ md_begin ()
   }
 }
 
-/* Address Mode OR values */
+/* Address Mode OR values */
 #define AM_Register  0x00000000
 #define AM_Direct    0x00200000
 #define AM_Indirect  0x00400000
 #define AM_Immediate 0x00600000
 #define AM_NotReq    0xFFFFFFFF
 
-/* PC Relative OR values */
+/* PC Relative OR values */
 #define PC_Register 0x00000000
 #define PC_Relative 0x02000000
 
-typedef struct {
+typedef struct
+{
   unsigned op_type;
-  struct {
+  struct
+  {
     int resolved;
     unsigned address;
     char *label;
     expressionS direct_expr;
   } direct;
-  struct {
+  struct
+  {
     unsigned mod;
     int ARnum;
     unsigned char disp;
   } indirect;
-  struct {
+  struct
+  {
     unsigned opcode;
   } reg;
-  struct {
+  struct
+  {
     int resolved;
     int decimal_found;
     float f_number;
@@ -234,564 +264,403 @@ typedef struct {
   } immediate;
 } operand;
 
-int tic30_parallel_insn PARAMS ((char *));
-operand *tic30_operand PARAMS ((char *));
-char *tic30_find_parallel_insn PARAMS ((char *, char *));
-
 template *opcode;
 
-struct tic30_insn {
-  template *tm;                        /* Template of current instruction */
-  unsigned opcode;             /* Final opcode */
-  unsigned int operands;       /* Number of given operands */
-  /* Type of operand given in instruction */
+struct tic30_insn
+{
+  template *tm;                        /* Template of current instruction.  */
+  unsigned opcode;             /* Final opcode.  */
+  unsigned int operands;       /* Number of given operands.  */
+  /* Type of operand given in instruction.  */
   operand *operand_type[MAX_OPERANDS];
-  unsigned addressing_mode;    /* Final addressing mode of instruction */
+  unsigned addressing_mode;    /* Final addressing mode of instruction */
 };
 
 struct tic30_insn insn;
 static int found_parallel_insn;
 
-void
-md_assemble (line)
-     char *line;
-{
-  template *opcode;
-  char *current_posn;
-  char *token_start;
-  char save_char;
-  unsigned int count;
+static char output_invalid_buf[8];
 
-  debug ("In md_assemble() with argument %s\n", line);
-  memset (&insn, '\0', sizeof (insn));
-  if (found_parallel_insn)
-    {
-      debug ("Line is second part of parallel instruction\n\n");
-      found_parallel_insn = 0;
-      return;
-    }
-  if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
-    current_posn = line;
+static char *
+output_invalid (char c)
+{
+  if (ISPRINT (c))
+    sprintf (output_invalid_buf, "'%c'", c);
   else
-    found_parallel_insn = 1;
-  while (is_space_char (*current_posn))
-    current_posn++;
-  token_start = current_posn;
-  if (!is_opcode_char (*current_posn))
-    {
-      as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
-      return;
-    }
-  /* Check if instruction is a parallel instruction by seeing if the first
-     character is a q.  */
-  if (*token_start == 'q')
+    sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
+  return output_invalid_buf;
+}
+
+/* next_line points to the next line after the current instruction
+   (current_line).  Search for the parallel bars, and if found, merge two
+   lines into internal syntax for a parallel instruction:
+     q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
+   By this stage, all comments are scrubbed, and only the bare lines are
+   given.  */
+
+#define NONE           0
+#define START_OPCODE   1
+#define END_OPCODE     2
+#define START_OPERANDS 3
+#define END_OPERANDS   4
+
+static char *
+tic30_find_parallel_insn (char *current_line, char *next_line)
+{
+  int found_parallel = 0;
+  char first_opcode[256];
+  char second_opcode[256];
+  char first_operands[256];
+  char second_operands[256];
+  char *parallel_insn;
+
+  debug ("In tic30_find_parallel_insn()\n");
+  while (!is_end_of_line[(unsigned char) *next_line])
     {
-      if (tic30_parallel_insn (token_start))
+      if (*next_line == PARALLEL_SEPARATOR
+         && *(next_line + 1) == PARALLEL_SEPARATOR)
        {
-         if (found_parallel_insn)
-           free (token_start);
-         return;
+         found_parallel = 1;
+         next_line++;
+         break;
        }
+      next_line++;
     }
-  while (is_opcode_char (*current_posn))
-    current_posn++;
-  {                            /* Find instruction */
-    save_char = *current_posn;
-    *current_posn = '\0';
-    opcode = (template *) hash_find (op_hash, token_start);
-    if (opcode)
-      {
-       debug ("Found instruction %s\n", opcode->name);
-       insn.tm = opcode;
-      }
-    else
+  if (!found_parallel)
+    return NULL;
+  debug ("Found a parallel instruction\n");
+
+  {
+    int i;
+    char *opcode, *operands, *line;
+
+    for (i = 0; i < 2; i++)
       {
-       debug ("Didn't find insn\n");
-       as_bad ("Unknown TMS320C30 instruction: %s", token_start);
-       return;
-      }
-    *current_posn = save_char;
-  }
-  if (*current_posn != END_OF_INSN)
-    {                          /* Find operands */
-      int paren_not_balanced;
-      int expecting_operand = 0;
-      int this_operand;
-      do
+       if (i == 0)
+         {
+           opcode = &first_opcode[0];
+           operands = &first_operands[0];
+           line = current_line;
+         }
+       else
+         {
+           opcode = &second_opcode[0];
+           operands = &second_operands[0];
+           line = next_line;
+         }
+
        {
-         /* skip optional white space before operand */
-         while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
-           {
-             if (!is_space_char (*current_posn))
-               {
-                 as_bad ("Invalid character %s before %s operand",
-                         output_invalid (*current_posn),
-                         ordinal_names[insn.operands]);
-                 return;
-               }
-             current_posn++;
-           }
-         token_start = current_posn;   /* after white space */
-         paren_not_balanced = 0;
-         while (paren_not_balanced || *current_posn != ',')
+         int search_status = NONE;
+         int char_ptr = 0;
+         char c;
+
+         while (!is_end_of_line[(unsigned char) (c = *line)])
            {
-             if (*current_posn == END_OF_INSN)
-               {
-                 if (paren_not_balanced)
-                   {
-                     as_bad ("Unbalanced parenthesis in %s operand.",
-                             ordinal_names[insn.operands]);
-                     return;
-                   }
-                 else
-                   break;      /* we are done */
-               }
-             else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
-               {
-                 as_bad ("Invalid character %s in %s operand",
-                         output_invalid (*current_posn),
-                         ordinal_names[insn.operands]);
-                 return;
-               }
-             if (*current_posn == '(')
-               ++paren_not_balanced;
-             if (*current_posn == ')')
-               --paren_not_balanced;
-             current_posn++;
-           }
-         if (current_posn != token_start)
-           {                   /* yes, we've read in another operand */
-             this_operand = insn.operands++;
-             if (insn.operands > MAX_OPERANDS)
+             if (is_opcode_char (c) && search_status == NONE)
                {
-                 as_bad ("Spurious operands; (%d operands/instruction max)",
-                         MAX_OPERANDS);
-                 return;
+                 opcode[char_ptr++] = TOLOWER (c);
+                 search_status = START_OPCODE;
                }
-             /* now parse operand adding info to 'insn' as we go along */
-             save_char = *current_posn;
-             *current_posn = '\0';
-             insn.operand_type[this_operand] = tic30_operand (token_start);
-             *current_posn = save_char;
-             if (insn.operand_type[this_operand] == NULL)
-               return;
-           }
-         else
-           {
-             if (expecting_operand)
+             else if (is_opcode_char (c) && search_status == START_OPCODE)
+               opcode[char_ptr++] = TOLOWER (c);
+             else if (!is_opcode_char (c) && search_status == START_OPCODE)
                {
-                 as_bad ("Expecting operand after ','; got nothing");
-                 return;
+                 opcode[char_ptr] = '\0';
+                 char_ptr = 0;
+                 search_status = END_OPCODE;
                }
-             if (*current_posn == ',')
+             else if (is_operand_char (c) && search_status == START_OPERANDS)
+               operands[char_ptr++] = c;
+
+             if (is_operand_char (c) && search_status == END_OPCODE)
                {
-                 as_bad ("Expecting operand before ','; got nothing");
-                 return;
-               }
-           }
-         /* now *current_posn must be either ',' or END_OF_INSN */
-         if (*current_posn == ',')
-           {
-             if (*++current_posn == END_OF_INSN)
-               {               /* just skip it, if it's \n complain */
-                 as_bad ("Expecting operand after ','; got nothing");
-                 return;
+                 operands[char_ptr++] = c;
+                 search_status = START_OPERANDS;
                }
-             expecting_operand = 1;
+
+             line++;
            }
+         if (search_status != START_OPERANDS)
+           return NULL;
+         operands[char_ptr] = '\0';
        }
-      while (*current_posn != END_OF_INSN);    /* until we get end of insn */
-    }
-  debug ("Number of operands found: %d\n", insn.operands);
-  /* Check that number of operands is correct */
-  if (insn.operands != insn.tm->operands)
+      }
+  }
+  parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
+                         + strlen (second_opcode) + strlen (second_operands) + 8);
+  sprintf (parallel_insn, "q_%s_%s %s | %s",
+          first_opcode, second_opcode,
+          first_operands, second_operands);
+  debug ("parallel insn = %s\n", parallel_insn);
+  return parallel_insn;
+}
+
+#undef NONE
+#undef START_OPCODE
+#undef END_OPCODE
+#undef START_OPERANDS
+#undef END_OPERANDS
+
+static operand *
+tic30_operand (char *token)
+{
+  unsigned int count;
+  char ind_buffer[strlen (token)];
+  operand *current_op;
+
+  debug ("In tic30_operand with %s\n", token);
+  current_op = malloc (sizeof (* current_op));
+  memset (current_op, '\0', sizeof (operand));
+
+  if (*token == DIRECT_REFERENCE)
     {
-      unsigned int i;
-      unsigned int numops = insn.tm->operands;
-      /* If operands are not the same, then see if any of the operands are not
-         required.  Then recheck with number of given operands.  If they are still not
-         the same, then give an error, otherwise carry on.  */
-      for (i = 0; i < insn.tm->operands; i++)
-       if (insn.tm->operand_types[i] & NotReq)
-         numops--;
-      if (insn.operands != numops)
+      char *token_posn = token + 1;
+      int direct_label = 0;
+
+      debug ("Found direct reference\n");
+      while (*token_posn)
        {
-         as_bad ("Incorrect number of operands given");
-         return;
+         if (!is_digit_char (*token_posn))
+           direct_label = 1;
+         token_posn++;
        }
-    }
-  insn.addressing_mode = AM_NotReq;
-  for (count = 0; count < insn.operands; count++)
-    {
-      if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
+
+      if (direct_label)
        {
-         debug ("Operand %d matches\n", count + 1);
-         /* If instruction has two operands and has an AddressMode modifier then set
-            addressing mode type for instruction */
-         if (insn.tm->opcode_modifier == AddressMode)
+         char *save_input_line_pointer;
+         segT retval;
+
+         debug ("Direct reference is a label\n");
+         current_op->direct.label = token + 1;
+         save_input_line_pointer = input_line_pointer;
+         input_line_pointer = token + 1;
+         debug ("Current input_line_pointer: %s\n", input_line_pointer);
+         retval = expression (&current_op->direct.direct_expr);
+
+         debug ("Expression type: %d\n",
+                current_op->direct.direct_expr.X_op);
+         debug ("Expression addnum: %d\n",
+                current_op->direct.direct_expr.X_add_number);
+         debug ("Segment: %d\n", retval);
+
+         input_line_pointer = save_input_line_pointer;
+
+         if (current_op->direct.direct_expr.X_op == O_constant)
            {
-             int addr_insn = 0;
-             /* Store instruction uses the second operand for the address mode.  */
-             if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
-               addr_insn = 1;
-             if (insn.operand_type[addr_insn]->op_type & (AllReg))
-               insn.addressing_mode = AM_Register;
-             else if (insn.operand_type[addr_insn]->op_type & Direct)
-               insn.addressing_mode = AM_Direct;
-             else if (insn.operand_type[addr_insn]->op_type & Indirect)
-               insn.addressing_mode = AM_Indirect;
-             else
-               insn.addressing_mode = AM_Immediate;
+             current_op->direct.address =
+               current_op->direct.direct_expr.X_add_number;
+             current_op->direct.resolved = 1;
            }
        }
       else
        {
-         as_bad ("The %s operand doesn't match", ordinal_names[count]);
-         return;
+         debug ("Direct reference is a number\n");
+         current_op->direct.address = atoi (token + 1);
+         current_op->direct.resolved = 1;
        }
+      current_op->op_type = Direct;
     }
-  /* Now set the addressing mode for 3 operand instructions.  */
-  if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
+  else if (*token == INDIRECT_REFERENCE)
     {
-      /* Set the addressing mode to the values used for 2 operand instructions in the
-         G addressing field of the opcode.  */
-      char *p;
-      switch (insn.operand_type[0]->op_type)
-       {
-       case Rn:
-       case ARn:
-       case DPReg:
-       case OtherReg:
-         if (insn.operand_type[1]->op_type & (AllReg))
-           insn.addressing_mode = AM_Register;
-         else if (insn.operand_type[1]->op_type & Indirect)
-           insn.addressing_mode = AM_Direct;
-         else
-           {
-             /* Shouldn't make it to this stage */
-             as_bad ("Incompatible first and second operands in instruction");
-             return;
-           }
-         break;
-       case Indirect:
-         if (insn.operand_type[1]->op_type & (AllReg))
-           insn.addressing_mode = AM_Indirect;
-         else if (insn.operand_type[1]->op_type & Indirect)
-           insn.addressing_mode = AM_Immediate;
-         else
-           {
-             /* Shouldn't make it to this stage */
-             as_bad ("Incompatible first and second operands in instruction");
-             return;
-           }
-         break;
-       }
-      /* Now make up the opcode for the 3 operand instructions.  As in parallel
-         instructions, there will be no unresolved values, so they can be fully formed
-         and added to the frag table.  */
-      insn.opcode = insn.tm->base_opcode;
-      if (insn.operand_type[0]->op_type & Indirect)
-       {
-         insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
-         insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
-       }
-      else
-       insn.opcode |= (insn.operand_type[0]->reg.opcode);
-      if (insn.operand_type[1]->op_type & Indirect)
-       {
-         insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
-         insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
-       }
-      else
-       insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
-      if (insn.operands == 3)
-       insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
-      insn.opcode |= insn.addressing_mode;
-      p = frag_more (INSN_SIZE);
-      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-    }
-  else
-    {                          /* Not a three operand instruction */
-      char *p;
-      int am_insn = -1;
-      insn.opcode = insn.tm->base_opcode;
-      /* Create frag for instruction - all instructions are 4 bytes long.  */
-      p = frag_more (INSN_SIZE);
-      if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
+      /* Indirect reference operand.  */
+      int found_ar = 0;
+      int found_disp = 0;
+      int ar_number = -1;
+      int disp_number = 0;
+      int buffer_posn = 1;
+      ind_addr_type *ind_addr_op;
+
+      debug ("Found indirect reference\n");
+      ind_buffer[0] = *token;
+
+      for (count = 1; count < strlen (token); count++)
        {
-         insn.opcode |= insn.addressing_mode;
-         if (insn.addressing_mode == AM_Indirect)
-           {
-             /* Determine which operand gives the addressing mode */
-             if (insn.operand_type[0]->op_type & Indirect)
-               am_insn = 0;
-             if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
-               am_insn = 1;
-             insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
-             insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
-             insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
-             if (insn.operands > 1)
-               insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
-             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-           }
-         else if (insn.addressing_mode == AM_Register)
-           {
-             insn.opcode |= (insn.operand_type[0]->reg.opcode);
-             if (insn.operands > 1)
-               insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
-             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-           }
-         else if (insn.addressing_mode == AM_Direct)
+         /* Strip operand.  */
+         ind_buffer[buffer_posn] = TOLOWER (*(token + count));
+
+         if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
+             && (*(token + count) == 'r' || *(token + count) == 'R'))
            {
-             if (insn.operand_type[0]->op_type & Direct)
-               am_insn = 0;
-             if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
-               am_insn = 1;
-             if (insn.operands > 1)
-               insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
-             if (insn.operand_type[am_insn]->direct.resolved == 1)
+             /* AR reference is found, so get its number and remove
+                it from the buffer so it can pass through hash_find().  */
+             if (found_ar)
                {
-                 /* Resolved values can be placed straight into instruction word, and output */
-                 insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                 as_bad ("More than one AR register found in indirect reference");
+                 return NULL;
                }
-             else
-               {               /* Unresolved direct addressing mode instruction */
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
+             if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
+               {
+                 as_bad ("Illegal AR register in indirect reference");
+                 return NULL;
                }
+             ar_number = *(token + count + 1) - '0';
+             found_ar = 1;
+             count++;
            }
-         else if (insn.addressing_mode == AM_Immediate)
+
+         if (*(token + count) == '(')
            {
-             if (insn.operand_type[0]->immediate.resolved == 1)
+             /* Parenthesis found, so check if a displacement value is
+                inside.  If so, get the value and remove it from the
+                buffer.  */
+             if (is_digit_char (*(token + count + 1)))
                {
-                 char *keeploc;
-                 int size;
-                 if (insn.operands > 1)
-                   insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
-                 switch (insn.tm->imm_arg_type)
+                 char disp[10];
+                 int disp_posn = 0;
+
+                 if (found_disp)
                    {
-                   case Imm_Float:
-                     debug ("Floating point first operand\n");
-                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                     keeploc = input_line_pointer;
-                     input_line_pointer = insn.operand_type[0]->immediate.label;
-                     if (md_atof ('f', p + 2, &size) != 0)
-                       {
-                         as_bad ("invalid short form floating point immediate operand");
-                         return;
-                       }
-                     input_line_pointer = keeploc;
-                     break;
-                   case Imm_UInt:
-                     debug ("Unsigned int first operand\n");
-                     if (insn.operand_type[0]->immediate.decimal_found)
-                       as_warn ("rounding down first operand float to unsigned int");
-                     if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
-                       as_warn ("only lower 16-bits of first operand are used");
-                     insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
-                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                     break;
-                   case Imm_SInt:
-                     debug ("Int first operand\n");
-                     if (insn.operand_type[0]->immediate.decimal_found)
-                       as_warn ("rounding down first operand float to signed int");
-                     if (insn.operand_type[0]->immediate.s_number < -32768 ||
-                         insn.operand_type[0]->immediate.s_number > 32767)
+                     as_bad ("More than one displacement found in indirect reference");
+                     return NULL;
+                   }
+                 count++;
+                 while (*(token + count) != ')')
+                   {
+                     if (!is_digit_char (*(token + count)))
                        {
-                         as_bad ("first operand is too large for 16-bit signed int");
-                         return;
+                         as_bad ("Invalid displacement in indirect reference");
+                         return NULL;
                        }
-                     insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
-                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                     break;
+                     disp[disp_posn++] = *(token + (count++));
                    }
-               }
-             else
-               {               /* Unresolved immediate label */
-                 if (insn.operands > 1)
-                   insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+                 disp[disp_posn] = '\0';
+                 disp_number = atoi (disp);
+                 count--;
+                 found_disp = 1;
                }
            }
+         buffer_posn++;
        }
-      else if (insn.tm->opcode_modifier == PCRel)
+
+      ind_buffer[buffer_posn] = '\0';
+      if (!found_ar)
        {
-         /* Conditional Branch and Call instructions */
-         if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
+         as_bad ("AR register not found in indirect reference");
+         return NULL;
+       }
+
+      ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
+      if (ind_addr_op)
+       {
+         debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
+         if (ind_addr_op->displacement == IMPLIED_DISP)
            {
-             if (insn.operand_type[0]->op_type & (AllReg))
-               {
-                 insn.opcode |= (insn.operand_type[0]->reg.opcode);
-                 insn.opcode |= PC_Register;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-               }
-             else
-               {
-                 insn.opcode |= PC_Relative;
-                 if (insn.operand_type[0]->immediate.resolved == 1)
-                   {
-                     insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
-                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                   }
-                 else
-                   {
-                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                     fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
-                   }
-               }
+             found_disp = 1;
+             disp_number = 1;
            }
-         else if ((insn.tm->operand_types[0] & ARn) == ARn)
+         else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
            {
-             /* Decrement and Branch instructions */
-             insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
-             if (insn.operand_type[1]->op_type & (AllReg))
-               {
-                 insn.opcode |= (insn.operand_type[1]->reg.opcode);
-                 insn.opcode |= PC_Register;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-               }
-             else if (insn.operand_type[1]->immediate.resolved == 1)
-               {
-                 if (insn.operand_type[0]->immediate.decimal_found)
-                   {
-                     as_bad ("first operand is floating point");
-                     return;
-                   }
-                 if (insn.operand_type[0]->immediate.s_number < -32768 ||
-                     insn.operand_type[0]->immediate.s_number > 32767)
-                   {
-                     as_bad ("first operand is too large for 16-bit signed int");
-                     return;
-                   }
-                 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
-                 insn.opcode |= PC_Relative;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-               }
-             else
-               {
-                 insn.opcode |= PC_Relative;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
-               }
+             /* Maybe an implied displacement of 1 again.  */
+             as_bad ("required displacement wasn't given in indirect reference");
+             return 0;
            }
        }
-      else if (insn.tm->operand_types[0] == IVector)
+      else
        {
-         /* Trap instructions */
-         if (insn.operand_type[0]->op_type & IVector)
-           insn.opcode |= (insn.operand_type[0]->immediate.u_number);
-         else
-           {                   /* Shouldn't get here */
-             as_bad ("interrupt vector for trap instruction out of range");
-             return;
-           }
-         md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+         as_bad ("illegal indirect reference");
+         return NULL;
        }
-      else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
+
+      if (found_disp && (disp_number < 0 || disp_number > 255))
        {
-         /* Push, Pop and Rotate instructions */
-         insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
-         md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+         as_bad ("displacement must be an unsigned 8-bit number");
+         return NULL;
        }
-      else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
+
+      current_op->indirect.mod = ind_addr_op->modfield;
+      current_op->indirect.disp = disp_number;
+      current_op->indirect.ARnum = ar_number;
+      current_op->op_type = Indirect;
+    }
+  else
+    {
+      reg *regop = (reg *) hash_find (reg_hash, token);
+
+      if (regop)
        {
-         /* LDP Instruction needs to be tested for before the next section */
-         if (insn.operand_type[0]->op_type & Direct)
-           {
-             if (insn.operand_type[0]->direct.resolved == 1)
-               {
-                 /* Direct addressing uses lower 8 bits of direct address */
-                 insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-               }
-             else
-               {
-                 fixS *fix;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
-                 /* Ensure that the assembler doesn't complain about fitting a 24-bit
-                    address into 8 bits.  */
-                 fix->fx_no_overflow = 1;
-               }
-           }
+         debug ("Found register operand: %s\n", regop->name);
+         if (regop->regtype == REG_ARn)
+           current_op->op_type = ARn;
+         else if (regop->regtype == REG_Rn)
+           current_op->op_type = Rn;
+         else if (regop->regtype == REG_DP)
+           current_op->op_type = DPReg;
          else
-           {
-             if (insn.operand_type[0]->immediate.resolved == 1)
-               {
-                 /* Immediate addressing uses upper 8 bits of address */
-                 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
-                   {
-                     as_bad ("LDP instruction needs a 24-bit operand");
-                     return;
-                   }
-                 insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-               }
-             else
-               {
-                 fixS *fix;
-                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-                 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
-                 fix->fx_no_overflow = 1;
-               }
-           }
+           current_op->op_type = OtherReg;
+         current_op->reg.opcode = regop->opcode;
        }
-      else if (insn.tm->operand_types[0] & (Imm24))
+      else
        {
-         /* Unconditional Branch and Call instructions */
-         if (insn.operand_type[0]->immediate.resolved == 1)
+         if (!is_digit_char (*token)
+             || *(token + 1) == 'x'
+             || strchr (token, 'h'))
            {
-             if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
-               as_warn ("first operand is too large for a 24-bit displacement");
-             insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
-             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+             char *save_input_line_pointer;
+             segT retval;
+
+             debug ("Probably a label: %s\n", token);
+             current_op->immediate.label = malloc (strlen (token) + 1);
+             strcpy (current_op->immediate.label, token);
+             current_op->immediate.label[strlen (token)] = '\0';
+             save_input_line_pointer = input_line_pointer;
+             input_line_pointer = token;
+
+             debug ("Current input_line_pointer: %s\n", input_line_pointer);
+             retval = expression (&current_op->immediate.imm_expr);
+             debug ("Expression type: %d\n",
+                    current_op->immediate.imm_expr.X_op);
+             debug ("Expression addnum: %d\n",
+                    current_op->immediate.imm_expr.X_add_number);
+             debug ("Segment: %d\n", retval);
+             input_line_pointer = save_input_line_pointer;
+
+             if (current_op->immediate.imm_expr.X_op == O_constant)
+               {
+                 current_op->immediate.s_number
+                   = current_op->immediate.imm_expr.X_add_number;
+                 current_op->immediate.u_number
+                   = (unsigned int) current_op->immediate.imm_expr.X_add_number;
+                 current_op->immediate.resolved = 1;
+               }
            }
          else
            {
-             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-             fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+             unsigned count;
+
+             debug ("Found a number or displacement\n");
+             for (count = 0; count < strlen (token); count++)
+               if (*(token + count) == '.')
+                 current_op->immediate.decimal_found = 1;
+             current_op->immediate.label = malloc (strlen (token) + 1);
+             strcpy (current_op->immediate.label, token);
+             current_op->immediate.label[strlen (token)] = '\0';
+             current_op->immediate.f_number = (float) atof (token);
+             current_op->immediate.s_number = (int) atoi (token);
+             current_op->immediate.u_number = (unsigned int) atoi (token);
+             current_op->immediate.resolved = 1;
            }
-       }
-      else if (insn.tm->operand_types[0] & NotReq)
-       {
-         /* Check for NOP instruction without arguments.  */
-         md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
-       }
-      else if (insn.tm->operands == 0)
-       {
-         /* Check for instructions without operands.  */
-         md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+         current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
+         if (current_op->immediate.u_number <= 31)
+           current_op->op_type |= IVector;
        }
     }
-  debug ("Addressing mode: %08X\n", insn.addressing_mode);
-  {
-    unsigned int i;
-    for (i = 0; i < insn.operands; i++)
-      {
-       if (insn.operand_type[i]->immediate.label)
-         free (insn.operand_type[i]->immediate.label);
-       free (insn.operand_type[i]);
-      }
-  }
-  debug ("Final opcode: %08X\n", insn.opcode);
-  debug ("\n");
+  return current_op;
 }
 
-struct tic30_par_insn {
-  partemplate *tm;             /* Template of current parallel instruction */
-  unsigned operands[2];                /* Number of given operands for each insn */
-  /* Type of operand given in instruction */
+struct tic30_par_insn
+{
+  partemplate *tm;             /* Template of current parallel instruction.  */
+  unsigned operands[2];                /* Number of given operands for each insn.  */
+  /* Type of operand given in instruction.  */
   operand *operand_type[2][MAX_OPERANDS];
   int swap_operands;           /* Whether to swap operands around.  */
-  unsigned p_field;            /* Value of p field in multiply add/sub instructions */
-  unsigned opcode;             /* Final opcode */
+  unsigned p_field;            /* Value of p field in multiply add/sub instructions */
+  unsigned opcode;             /* Final opcode */
 };
 
 struct tic30_par_insn p_insn;
 
-int
+static int
 tic30_parallel_insn (char *token)
 {
   static partemplate *p_opcode;
@@ -801,9 +670,11 @@ tic30_parallel_insn (char *token)
 
   debug ("In tic30_parallel_insn with %s\n", token);
   memset (&p_insn, '\0', sizeof (p_insn));
+
   while (is_opcode_char (*current_posn))
     current_posn++;
-  {                            /* Find instruction */
+  {
+    /* Find instruction.  */
     save_char = *current_posn;
     *current_posn = '\0';
     p_opcode = (partemplate *) hash_find (parop_hash, token);
@@ -814,10 +685,8 @@ tic30_parallel_insn (char *token)
       }
     else
       {
-       char first_opcode[6] =
-       {0};
-       char second_opcode[6] =
-       {0};
+       char first_opcode[6] = {0};
+       char second_opcode[6] = {0};
        unsigned int i;
        int current_opcode = -1;
        int char_ptr = 0;
@@ -825,17 +694,20 @@ tic30_parallel_insn (char *token)
        for (i = 0; i < strlen (token); i++)
          {
            char ch = *(token + i);
+
            if (ch == '_' && current_opcode == -1)
              {
                current_opcode = 0;
                continue;
              }
+
            if (ch == '_' && current_opcode == 0)
              {
                current_opcode = 1;
                char_ptr = 0;
                continue;
              }
+
            switch (current_opcode)
              {
              case 0:
@@ -846,10 +718,12 @@ tic30_parallel_insn (char *token)
                break;
              }
          }
+
        debug ("first_opcode = %s\n", first_opcode);
        debug ("second_opcode = %s\n", second_opcode);
        sprintf (token, "q_%s_%s", second_opcode, first_opcode);
        p_opcode = (partemplate *) hash_find (parop_hash, token);
+
        if (p_opcode)
          {
            debug ("Found instruction %s\n", p_opcode->name);
@@ -861,16 +735,21 @@ tic30_parallel_insn (char *token)
       }
     *current_posn = save_char;
   }
-  {                            /* Find operands */
+
+  {
+    /* Find operands.  */
     int paren_not_balanced;
     int expecting_operand = 0;
     int found_separator = 0;
+
     do
       {
-       /* skip optional white space before operand */
-       while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
+       /* Skip optional white space before operand.  */
+       while (!is_operand_char (*current_posn)
+              && *current_posn != END_OF_INSN)
          {
-           if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
+           if (!is_space_char (*current_posn)
+               && *current_posn != PARALLEL_SEPARATOR)
              {
                as_bad ("Invalid character %s before %s operand",
                        output_invalid (*current_posn),
@@ -881,8 +760,10 @@ tic30_parallel_insn (char *token)
              found_separator = 1;
            current_posn++;
          }
-       token_start = current_posn;     /* after white space */
+
+       token_start = current_posn;
        paren_not_balanced = 0;
+
        while (paren_not_balanced || *current_posn != ',')
          {
            if (*current_posn == END_OF_INSN)
@@ -894,7 +775,7 @@ tic30_parallel_insn (char *token)
                    return 1;
                  }
                else
-                 break;        /* we are done */
+                 break;
              }
            else if (*current_posn == PARALLEL_SEPARATOR)
              {
@@ -902,21 +783,25 @@ tic30_parallel_insn (char *token)
                  current_posn--;
                break;
              }
-           else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
+           else if (!is_operand_char (*current_posn)
+                    && !is_space_char (*current_posn))
              {
                as_bad ("Invalid character %s in %s operand",
                        output_invalid (*current_posn),
                        ordinal_names[insn.operands]);
                return 1;
              }
+
            if (*current_posn == '(')
              ++paren_not_balanced;
            if (*current_posn == ')')
              --paren_not_balanced;
            current_posn++;
          }
+
        if (current_posn != token_start)
-         {                     /* yes, we've read in another operand */
+         {
+           /* Yes, we've read in another operand.  */
            p_insn.operands[found_separator]++;
            if (p_insn.operands[found_separator] > MAX_OPERANDS)
              {
@@ -924,7 +809,8 @@ tic30_parallel_insn (char *token)
                        MAX_OPERANDS);
                return 1;
              }
-           /* now parse operand adding info to 'insn' as we go along */
+
+           /* Now parse operand adding info to 'insn' as we go along.  */
            save_char = *current_posn;
            *current_posn = '\0';
            p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
@@ -946,19 +832,22 @@ tic30_parallel_insn (char *token)
                return 1;
              }
          }
-       /* now *current_posn must be either ',' or END_OF_INSN */
+
+       /* Now *current_posn must be either ',' or END_OF_INSN.  */
        if (*current_posn == ',')
          {
            if (*++current_posn == END_OF_INSN)
-             {                 /* just skip it, if it's \n complain */
+             {
+               /* Just skip it, if it's \n complain.  */
                as_bad ("Expecting operand after ','; got nothing");
                return 1;
              }
            expecting_operand = 1;
          }
       }
-    while (*current_posn != END_OF_INSN);      /* until we get end of insn */
+    while (*current_posn != END_OF_INSN);
   }
+
   if (p_insn.swap_operands)
     {
       int temp_num, i;
@@ -974,22 +863,28 @@ tic30_parallel_insn (char *token)
          p_insn.operand_type[1][i] = temp_op;
        }
     }
+
   if (p_insn.operands[0] != p_insn.tm->operands_1)
     {
       as_bad ("incorrect number of operands given in the first instruction");
       return 1;
     }
+
   if (p_insn.operands[1] != p_insn.tm->operands_2)
     {
       as_bad ("incorrect number of operands given in the second instruction");
       return 1;
     }
+
   debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
   debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
-  {                            /* Now check if operands are correct */
+
+  {
+    /* Now check if operands are correct.  */
     int count;
     int num_rn = 0;
     int num_ind = 0;
+
     for (count = 0; count < 2; count++)
       {
        unsigned int i;
@@ -998,64 +893,76 @@ tic30_parallel_insn (char *token)
            if ((p_insn.operand_type[count][i]->op_type &
                 p_insn.tm->operand_types[count][i]) == 0)
              {
-               as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
+               as_bad ("%s instruction, operand %d doesn't match",
+                       ordinal_names[count], i + 1);
                return 1;
              }
-           /* Get number of R register and indirect reference contained within the first
-              two operands of each instruction.  This is required for the multiply
-              parallel instructions which require two R registers and two indirect
-              references, but not in any particular place.  */
+
+           /* Get number of R register and indirect reference contained
+              within the first two operands of each instruction.  This is
+              required for the multiply parallel instructions which require
+              two R registers and two indirect references, but not in any
+              particular place.  */
            if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
              num_rn++;
-           else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
+           else if ((p_insn.operand_type[count][i]->op_type & Indirect)
+                    && i < 2)
              num_ind++;
          }
       }
-    if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
+
+    if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
+       == (Indirect | Rn))
       {
-       /* Check for the multiply instructions */
+       /* Check for the multiply instructions */
        if (num_rn != 2)
          {
            as_bad ("incorrect format for multiply parallel instruction");
            return 1;
          }
+
        if (num_ind != 2)
-         {                     /* Shouldn't get here */
+         {
+           /* Shouldn't get here.  */
            as_bad ("incorrect format for multiply parallel instruction");
            return 1;
          }
-       if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
-           (p_insn.operand_type[0][2]->reg.opcode != 0x01))
+
+       if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
+           && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
          {
            as_bad ("destination for multiply can only be R0 or R1");
            return 1;
          }
-       if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
-           (p_insn.operand_type[1][2]->reg.opcode != 0x03))
+
+       if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
+           && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
          {
            as_bad ("destination for add/subtract can only be R2 or R3");
            return 1;
          }
-       /* Now determine the P field for the instruction */
+
+       /* Now determine the P field for the instruction.  */
        if (p_insn.operand_type[0][0]->op_type & Indirect)
          {
            if (p_insn.operand_type[0][1]->op_type & Indirect)
-             p_insn.p_field = 0x00000000;      /* Ind * Ind, Rn  +/- Rn  */
+             p_insn.p_field = 0x00000000;      /* Ind * Ind, Rn  +/- Rn.  */
            else if (p_insn.operand_type[1][0]->op_type & Indirect)
-             p_insn.p_field = 0x01000000;      /* Ind * Rn,  Ind +/- Rn  */
+             p_insn.p_field = 0x01000000;      /* Ind * Rn,  Ind +/- Rn.  */
            else
-             p_insn.p_field = 0x03000000;      /* Ind * Rn,  Rn  +/- Ind */
+             p_insn.p_field = 0x03000000;      /* Ind * Rn,  Rn  +/- Ind */
          }
        else
          {
            if (p_insn.operand_type[0][1]->op_type & Rn)
-             p_insn.p_field = 0x02000000;      /* Rn  * Rn,  Ind +/- Ind */
+             p_insn.p_field = 0x02000000;      /* Rn  * Rn,  Ind +/- Ind */
            else if (p_insn.operand_type[1][0]->op_type & Indirect)
              {
                operand *temp;
-               p_insn.p_field = 0x01000000;    /* Rn  * Ind, Ind +/- Rn  */
-               /* Need to swap the two multiply operands around so that everything is in
-                  its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
+               p_insn.p_field = 0x01000000;    /* Rn  * Ind, Ind +/- Rn.  */
+               /* Need to swap the two multiply operands around so that
+                  everything is in its place for the opcode makeup.
+                  ie so Ind * Rn, Ind +/- Rn.  */
                temp = p_insn.operand_type[0][0];
                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
                p_insn.operand_type[0][1] = temp;
@@ -1063,7 +970,7 @@ tic30_parallel_insn (char *token)
            else
              {
                operand *temp;
-               p_insn.p_field = 0x03000000;    /* Rn  * Ind, Rn  +/- Ind */
+               p_insn.p_field = 0x03000000;    /* Rn  * Ind, Rn  +/- Ind */
                temp = p_insn.operand_type[0][0];
                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
                p_insn.operand_type[0][1] = temp;
@@ -1071,772 +978,1034 @@ tic30_parallel_insn (char *token)
          }
       }
   }
+
   debug ("P field: %08X\n", p_insn.p_field);
-  /* Finalise opcode.  This is easier for parallel instructions as they have to be
-     fully resolved, there are no memory addresses allowed, except through indirect
-     addressing, so there are no labels to resolve.  */
+
+  /* Finalise opcode.  This is easier for parallel instructions as they have
+     to be fully resolved, there are no memory addresses allowed, except
+     through indirect addressing, so there are no labels to resolve.  */
+  p_insn.opcode = p_insn.tm->base_opcode;
+
+  switch (p_insn.tm->oporder)
+    {
+    case OO_4op1:
+      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+      break;
+
+    case OO_4op2:
+      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+      p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+      p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
+      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+      if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
+       as_warn ("loading the same register in parallel operation");
+      break;
+
+    case OO_4op3:
+      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+      p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
+      break;
+
+    case OO_5op1:
+      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+      p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+      break;
+
+    case OO_5op2:
+      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+      p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+      p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+      break;
+
+    case OO_PField:
+      p_insn.opcode |= p_insn.p_field;
+      if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
+       p_insn.opcode |= 0x00800000;
+      if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
+       p_insn.opcode |= 0x00400000;
+
+      switch (p_insn.p_field)
+       {
+       case 0x00000000:
+         p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+         p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+         p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+         p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
+         break;
+       case 0x01000000:
+         p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
+         p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+         p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+         p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+         break;
+       case 0x02000000:
+         p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+         p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+         p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+         p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+         p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+         break;
+       case 0x03000000:
+         p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+         p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+         p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+         p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+         p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+         break;
+       }
+      break;
+    }
+
   {
-    p_insn.opcode = p_insn.tm->base_opcode;
-    switch (p_insn.tm->oporder)
-      {
-      case OO_4op1:
-       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
-       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
-       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
-       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
-       break;
-      case OO_4op2:
-       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
-       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
-       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
-       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
-       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
-       if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
-         as_warn ("loading the same register in parallel operation");
-       break;
-      case OO_4op3:
-       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
-       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
-       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
-       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
-       break;
-      case OO_5op1:
-       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
-       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
-       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
-       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
-       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
-       break;
-      case OO_5op2:
-       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
-       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
-       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
-       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
-       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
-       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
-       break;
-      case OO_PField:
-       p_insn.opcode |= p_insn.p_field;
-       if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
-         p_insn.opcode |= 0x00800000;
-       if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
-         p_insn.opcode |= 0x00400000;
-       switch (p_insn.p_field)
-         {
-         case 0x00000000:
-           p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
-           p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
-           p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
-           p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
-           break;
-         case 0x01000000:
-           p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
-           p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
-           p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
-           p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
-           break;
-         case 0x02000000:
-           p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
-           p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
-           p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
-           p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
-           p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
-           break;
-         case 0x03000000:
-           p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
-           p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
-           p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
-           p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
-           p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
-           break;
-         }
-       break;
-      }
-  }                            /* Opcode is finalised at this point for all parallel instructions.  */
-  {                            /* Output opcode */
     char *p;
+
     p = frag_more (INSN_SIZE);
     md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
   }
+
   {
     unsigned int i, j;
+
     for (i = 0; i < 2; i++)
       for (j = 0; j < p_insn.operands[i]; j++)
        free (p_insn.operand_type[i][j]);
   }
+
   debug ("Final opcode: %08X\n", p_insn.opcode);
   debug ("\n");
+
   return 1;
 }
 
-operand *
-tic30_operand (token)
-     char *token;
+/* In order to get gas to ignore any | chars at the start of a line,
+   this function returns true if a | is found in a line.  */
+
+int
+tic30_unrecognized_line (int c)
 {
-  unsigned int count;
-  char ind_buffer[strlen (token)];
-  operand *current_op;
+  debug ("In tc_unrecognized_line\n");
+  return (c == PARALLEL_SEPARATOR);
+}
 
-  debug ("In tic30_operand with %s\n", token);
-  current_op = (operand *) malloc (sizeof (operand));
-  memset (current_op, '\0', sizeof (operand));
-  if (*token == DIRECT_REFERENCE)
-    {
-      char *token_posn = token + 1;
-      int direct_label = 0;
-      debug ("Found direct reference\n");
-      while (*token_posn)
-       {
-         if (!is_digit_char (*token_posn))
-           direct_label = 1;
-         token_posn++;
-       }
-      if (direct_label)
-       {
-         char *save_input_line_pointer;
-         segT retval;
-         debug ("Direct reference is a label\n");
-         current_op->direct.label = token + 1;
-         save_input_line_pointer = input_line_pointer;
-         input_line_pointer = token + 1;
-         debug ("Current input_line_pointer: %s\n", input_line_pointer);
-         retval = expression (&current_op->direct.direct_expr);
-         debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
-         debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
-         debug ("Segment: %d\n", retval);
-         input_line_pointer = save_input_line_pointer;
-         if (current_op->direct.direct_expr.X_op == O_constant)
+int
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+                              segT segment ATTRIBUTE_UNUSED)
+{
+  debug ("In md_estimate_size_before_relax()\n");
+  return 0;
+}
+
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
+                segT sec ATTRIBUTE_UNUSED,
+                register fragS *fragP ATTRIBUTE_UNUSED)
+{
+  debug ("In md_convert_frag()\n");
+}
+
+void
+md_apply_fix3 (fixS *fixP,
+              valueT *valP,
+              segT seg ATTRIBUTE_UNUSED)
+{
+  valueT value = *valP;
+
+  debug ("In md_apply_fix() with value = %ld\n", (long) value);
+  debug ("Values in fixP\n");
+  debug ("fx_size = %d\n", fixP->fx_size);
+  debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
+  debug ("fx_where = %d\n", fixP->fx_where);
+  debug ("fx_offset = %d\n", (int) fixP->fx_offset);
+  {
+    char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+    value /= INSN_SIZE;
+    if (fixP->fx_size == 1)
+      /* Special fix for LDP instruction.  */
+      value = (value & 0x00FF0000) >> 16;
+
+    debug ("new value = %ld\n", (long) value);
+    md_number_to_chars (buf, value, fixP->fx_size);
+  }
+
+  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+    fixP->fx_done = 1;
+}
+
+int
+md_parse_option (int c ATTRIBUTE_UNUSED,
+                char *arg ATTRIBUTE_UNUSED)
+{
+  debug ("In md_parse_option()\n");
+  return 0;
+}
+
+void
+md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
+{
+  debug ("In md_show_usage()\n");
+}
+
+symbolS *
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
+{
+  debug ("In md_undefined_symbol()\n");
+  return (symbolS *) 0;
+}
+
+valueT
+md_section_align (segT segment, valueT size)
+{
+  debug ("In md_section_align() segment = %d and size = %d\n",
+        segment, size);
+  size = (size + 3) / 4;
+  size *= 4;
+  debug ("New size value = %d\n", size);
+  return size;
+}
+
+long
+md_pcrel_from (fixS *fixP)
+{
+  int offset;
+
+  debug ("In md_pcrel_from()\n");
+  debug ("fx_where = %d\n", fixP->fx_where);
+  debug ("fx_size = %d\n", fixP->fx_size);
+  /* Find the opcode that represents the current instruction in the
+     fr_literal storage area, and check bit 21.  Bit 21 contains whether the
+     current instruction is a delayed one or not, and then set the offset
+     value appropriately.  */
+  if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
+    offset = 3;
+  else
+    offset = 1;
+  debug ("offset = %d\n", offset);
+  /* PC Relative instructions have a format:
+     displacement = Label - (PC + offset)
+     This function returns PC + offset where:
+     fx_where - fx_size = PC
+     INSN_SIZE * offset = offset number of instructions.  */
+  return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
+}
+
+char *
+md_atof (int what_statement_type,
+        char *literalP,
+        int *sizeP)
+{
+  int prec;
+  char *token;
+  char keepval;
+  unsigned long value;
+  float float_value;
+
+  debug ("In md_atof()\n");
+  debug ("precision = %c\n", what_statement_type);
+  debug ("literal = %s\n", literalP);
+  debug ("line = ");
+  token = input_line_pointer;
+  while (!is_end_of_line[(unsigned char) *input_line_pointer]
+        && (*input_line_pointer != ','))
+    {
+      debug ("%c", *input_line_pointer);
+      input_line_pointer++;
+    }
+
+  keepval = *input_line_pointer;
+  *input_line_pointer = '\0';
+  debug ("\n");
+  float_value = (float) atof (token);
+  *input_line_pointer = keepval;
+  debug ("float_value = %f\n", float_value);
+
+  switch (what_statement_type)
+    {
+    case 'f':
+    case 'F':
+    case 's':
+    case 'S':
+      prec = 2;
+      break;
+
+    case 'd':
+    case 'D':
+    case 'r':
+    case 'R':
+      prec = 4;
+      break;
+
+    default:
+      *sizeP = 0;
+      return "Bad call to MD_ATOF()";
+    }
+
+  if (float_value == 0.0)
+    value = (prec == 2) ? 0x00008000L : 0x80000000L;
+  else
+    {
+      unsigned long exp, sign, mant, tmsfloat;
+      union
+      {
+       float f;
+       long  l;
+      }
+      converter;
+
+      converter.f = float_value;
+      tmsfloat = converter.l;
+      sign = tmsfloat & 0x80000000;
+      mant = tmsfloat & 0x007FFFFF;
+      exp = tmsfloat & 0x7F800000;
+      exp <<= 1;
+      if (exp == 0xFF000000)
+       {
+         if (mant == 0)
+           value = 0x7F7FFFFF;
+         else if (sign == 0)
+           value = 0x7F7FFFFF;
+         else
+           value = 0x7F800000;
+       }
+      else
+       {
+         exp -= 0x7F000000;
+         if (sign)
            {
-             current_op->direct.address = current_op->direct.direct_expr.X_add_number;
-             current_op->direct.resolved = 1;
+             mant = mant & 0x007FFFFF;
+             mant = -mant;
+             mant = mant & 0x00FFFFFF;
+             if (mant == 0)
+               {
+                 mant |= 0x00800000;
+                 exp = (long) exp - 0x01000000;
+               }
+           }
+         tmsfloat = exp | mant;
+         value = tmsfloat;
+       }
+      if (prec == 2)
+       {
+         long exp, mant;
+
+         if (tmsfloat == 0x80000000)
+           value = 0x8000;
+         else
+           {
+             value = 0;
+             exp = (tmsfloat & 0xFF000000);
+             exp >>= 24;
+             mant = tmsfloat & 0x007FFFFF;
+             if (tmsfloat & 0x00800000)
+               {
+                 mant |= 0xFF000000;
+                 mant += 0x00000800;
+                 mant >>= 12;
+                 mant |= 0x00000800;
+                 mant &= 0x0FFF;
+                 if (exp > 7)
+                   value = 0x7800;
+               }
+             else
+               {
+                 mant |= 0x00800000;
+                 mant += 0x00000800;
+                 exp += (mant >> 24);
+                 mant >>= 12;
+                 mant &= 0x07FF;
+                 if (exp > 7)
+                   value = 0x77FF;
+               }
+             if (exp < -8)
+               value = 0x8000;
+             if (value == 0)
+               {
+                 mant = (exp << 12) | mant;
+                 value = mant & 0xFFFF;
+               }
+           }
+       }
+    }
+  md_number_to_chars (literalP, value, prec);
+  *sizeP = prec;
+  return 0;
+}
+
+void
+md_number_to_chars (char *buf, valueT val, int n)
+{
+  debug ("In md_number_to_chars()\n");
+  number_to_chars_bigendian (buf, val, n);
+}
+
+#define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
+#define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
+
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
+{
+  arelent *rel;
+  bfd_reloc_code_real_type code = 0;
+
+  debug ("In tc_gen_reloc()\n");
+  debug ("fixP.size = %d\n", fixP->fx_size);
+  debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
+  debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
+
+  switch (F (fixP->fx_size, fixP->fx_pcrel))
+    {
+      MAP (1, 0, BFD_RELOC_TIC30_LDP);
+      MAP (2, 0, BFD_RELOC_16);
+      MAP (3, 0, BFD_RELOC_24);
+      MAP (2, 1, BFD_RELOC_16_PCREL);
+      MAP (4, 0, BFD_RELOC_32);
+    default:
+      as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
+             fixP->fx_pcrel ? "pc-relative " : "");
+    }
+#undef MAP
+#undef F
+
+  rel = xmalloc (sizeof (* rel));
+  assert (rel != 0);
+  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
+  rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
+  rel->addend = 0;
+  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+  if (!rel->howto)
+    {
+      const char *name;
+
+      name = S_GET_NAME (fixP->fx_addsy);
+      if (name == NULL)
+       name = "<unknown>";
+      as_fatal ("Cannot generate relocation type for symbol %s, code %s",
+               name, bfd_get_reloc_code_name (code));
+    }
+  return rel;
+}
+
+void
+md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
+{
+  debug ("In md_operand()\n");
+}
+
+void
+md_assemble (char *line)
+{
+  template *opcode;
+  char *current_posn;
+  char *token_start;
+  char save_char;
+  unsigned int count;
+
+  debug ("In md_assemble() with argument %s\n", line);
+  memset (&insn, '\0', sizeof (insn));
+  if (found_parallel_insn)
+    {
+      debug ("Line is second part of parallel instruction\n\n");
+      found_parallel_insn = 0;
+      return;
+    }
+  if ((current_posn =
+       tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
+    current_posn = line;
+  else
+    found_parallel_insn = 1;
+
+  while (is_space_char (*current_posn))
+    current_posn++;
+
+  token_start = current_posn;
+
+  if (!is_opcode_char (*current_posn))
+    {
+      as_bad ("Invalid character %s in opcode",
+             output_invalid (*current_posn));
+      return;
+    }
+  /* Check if instruction is a parallel instruction
+     by seeing if the first character is a q.  */
+  if (*token_start == 'q')
+    {
+      if (tic30_parallel_insn (token_start))
+       {
+         if (found_parallel_insn)
+           free (token_start);
+         return;
+       }
+    }
+  while (is_opcode_char (*current_posn))
+    current_posn++;
+  {
+    /* Find instruction.  */
+    save_char = *current_posn;
+    *current_posn = '\0';
+    opcode = (template *) hash_find (op_hash, token_start);
+    if (opcode)
+      {
+       debug ("Found instruction %s\n", opcode->name);
+       insn.tm = opcode;
+      }
+    else
+      {
+       debug ("Didn't find insn\n");
+       as_bad ("Unknown TMS320C30 instruction: %s", token_start);
+       return;
+      }
+    *current_posn = save_char;
+  }
+
+  if (*current_posn != END_OF_INSN)
+    {
+      /* Find operands.  */
+      int paren_not_balanced;
+      int expecting_operand = 0;
+      int this_operand;
+      do
+       {
+         /* Skip optional white space before operand.  */
+         while (!is_operand_char (*current_posn)
+                && *current_posn != END_OF_INSN)
+           {
+             if (!is_space_char (*current_posn))
+               {
+                 as_bad ("Invalid character %s before %s operand",
+                         output_invalid (*current_posn),
+                         ordinal_names[insn.operands]);
+                 return;
+               }
+             current_posn++;
+           }
+         token_start = current_posn;
+         paren_not_balanced = 0;
+         while (paren_not_balanced || *current_posn != ',')
+           {
+             if (*current_posn == END_OF_INSN)
+               {
+                 if (paren_not_balanced)
+                   {
+                     as_bad ("Unbalanced parenthesis in %s operand.",
+                             ordinal_names[insn.operands]);
+                     return;
+                   }
+                 else
+                   break;
+               }
+             else if (!is_operand_char (*current_posn)
+                      && !is_space_char (*current_posn))
+               {
+                 as_bad ("Invalid character %s in %s operand",
+                         output_invalid (*current_posn),
+                         ordinal_names[insn.operands]);
+                 return;
+               }
+             if (*current_posn == '(')
+               ++paren_not_balanced;
+             if (*current_posn == ')')
+               --paren_not_balanced;
+             current_posn++;
+           }
+         if (current_posn != token_start)
+           {
+             /* Yes, we've read in another operand.  */
+             this_operand = insn.operands++;
+             if (insn.operands > MAX_OPERANDS)
+               {
+                 as_bad ("Spurious operands; (%d operands/instruction max)",
+                         MAX_OPERANDS);
+                 return;
+               }
+
+             /* Now parse operand adding info to 'insn' as we go along.  */
+             save_char = *current_posn;
+             *current_posn = '\0';
+             insn.operand_type[this_operand] = tic30_operand (token_start);
+             *current_posn = save_char;
+             if (insn.operand_type[this_operand] == NULL)
+               return;
            }
-       }
-      else
-       {
-         debug ("Direct reference is a number\n");
-         current_op->direct.address = atoi (token + 1);
-         current_op->direct.resolved = 1;
-       }
-      current_op->op_type = Direct;
-    }
-  else if (*token == INDIRECT_REFERENCE)
-    {                          /* Indirect reference operand */
-      int found_ar = 0;
-      int found_disp = 0;
-      int ar_number = -1;
-      int disp_number = 0;
-      int buffer_posn = 1;
-      ind_addr_type *ind_addr_op;
-      debug ("Found indirect reference\n");
-      ind_buffer[0] = *token;
-      for (count = 1; count < strlen (token); count++)
-       {                       /* Strip operand */
-         ind_buffer[buffer_posn] = TOLOWER (*(token + count));
-         if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
-             (*(token + count) == 'r' || *(token + count) == 'R'))
+         else
            {
-             /* AR reference is found, so get its number and remove it from the buffer
-                so it can pass through hash_find() */
-             if (found_ar)
+             if (expecting_operand)
                {
-                 as_bad ("More than one AR register found in indirect reference");
-                 return NULL;
+                 as_bad ("Expecting operand after ','; got nothing");
+                 return;
                }
-             if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
+             if (*current_posn == ',')
                {
-                 as_bad ("Illegal AR register in indirect reference");
-                 return NULL;
+                 as_bad ("Expecting operand before ','; got nothing");
+                 return;
                }
-             ar_number = *(token + count + 1) - '0';
-             found_ar = 1;
-             count++;
            }
-         if (*(token + count) == '(')
+
+         /* Now *current_posn must be either ',' or END_OF_INSN.  */
+         if (*current_posn == ',')
            {
-             /* Parenthesis found, so check if a displacement value is inside.  If so, get
-                the value and remove it from the buffer.  */
-             if (is_digit_char (*(token + count + 1)))
+             if (*++current_posn == END_OF_INSN)
                {
-                 char disp[10];
-                 int disp_posn = 0;
-
-                 if (found_disp)
-                   {
-                     as_bad ("More than one displacement found in indirect reference");
-                     return NULL;
-                   }
-                 count++;
-                 while (*(token + count) != ')')
-                   {
-                     if (!is_digit_char (*(token + count)))
-                       {
-                         as_bad ("Invalid displacement in indirect reference");
-                         return NULL;
-                       }
-                     disp[disp_posn++] = *(token + (count++));
-                   }
-                 disp[disp_posn] = '\0';
-                 disp_number = atoi (disp);
-                 count--;
-                 found_disp = 1;
+                 /* Just skip it, if it's \n complain.  */
+                 as_bad ("Expecting operand after ','; got nothing");
+                 return;
                }
+             expecting_operand = 1;
            }
-         buffer_posn++;
        }
-      ind_buffer[buffer_posn] = '\0';
-      if (!found_ar)
+      while (*current_posn != END_OF_INSN);
+    }
+
+  debug ("Number of operands found: %d\n", insn.operands);
+
+  /* Check that number of operands is correct.  */
+  if (insn.operands != insn.tm->operands)
+    {
+      unsigned int i;
+      unsigned int numops = insn.tm->operands;
+
+      /* If operands are not the same, then see if any of the operands are
+        not required.  Then recheck with number of given operands.  If they
+        are still not the same, then give an error, otherwise carry on.  */
+      for (i = 0; i < insn.tm->operands; i++)
+       if (insn.tm->operand_types[i] & NotReq)
+         numops--;
+      if (insn.operands != numops)
        {
-         as_bad ("AR register not found in indirect reference");
-         return NULL;
+         as_bad ("Incorrect number of operands given");
+         return;
        }
-      ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
-      if (ind_addr_op)
+    }
+  insn.addressing_mode = AM_NotReq;
+  for (count = 0; count < insn.operands; count++)
+    {
+      if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
        {
-         debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
-         if (ind_addr_op->displacement == IMPLIED_DISP)
-           {
-             found_disp = 1;
-             disp_number = 1;
-           }
-         else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
+         debug ("Operand %d matches\n", count + 1);
+         /* If instruction has two operands and has an AddressMode
+            modifier then set addressing mode type for instruction.  */
+         if (insn.tm->opcode_modifier == AddressMode)
            {
-             /* Maybe an implied displacement of 1 again */
-             as_bad ("required displacement wasn't given in indirect reference");
-             return 0;
+             int addr_insn = 0;
+             /* Store instruction uses the second
+                operand for the address mode.  */
+             if ((insn.tm->operand_types[1] & (Indirect | Direct))
+                 == (Indirect | Direct))
+               addr_insn = 1;
+
+             if (insn.operand_type[addr_insn]->op_type & (AllReg))
+               insn.addressing_mode = AM_Register;
+             else if (insn.operand_type[addr_insn]->op_type & Direct)
+               insn.addressing_mode = AM_Direct;
+             else if (insn.operand_type[addr_insn]->op_type & Indirect)
+               insn.addressing_mode = AM_Indirect;
+             else
+               insn.addressing_mode = AM_Immediate;
            }
        }
       else
        {
-         as_bad ("illegal indirect reference");
-         return NULL;
-       }
-      if (found_disp && (disp_number < 0 || disp_number > 255))
-       {
-         as_bad ("displacement must be an unsigned 8-bit number");
-         return NULL;
+         as_bad ("The %s operand doesn't match", ordinal_names[count]);
+         return;
        }
-      current_op->indirect.mod = ind_addr_op->modfield;
-      current_op->indirect.disp = disp_number;
-      current_op->indirect.ARnum = ar_number;
-      current_op->op_type = Indirect;
     }
-  else
+
+  /* Now set the addressing mode for 3 operand instructions.  */
+  if ((insn.tm->operand_types[0] & op3T1)
+      && (insn.tm->operand_types[1] & op3T2))
     {
-      reg *regop = (reg *) hash_find (reg_hash, token);
-      if (regop)
+      /* Set the addressing mode to the values used for 2 operand
+        instructions in the  G addressing field of the opcode.  */
+      char *p;
+      switch (insn.operand_type[0]->op_type)
        {
-         debug ("Found register operand: %s\n", regop->name);
-         if (regop->regtype == REG_ARn)
-           current_op->op_type = ARn;
-         else if (regop->regtype == REG_Rn)
-           current_op->op_type = Rn;
-         else if (regop->regtype == REG_DP)
-           current_op->op_type = DPReg;
+       case Rn:
+       case ARn:
+       case DPReg:
+       case OtherReg:
+         if (insn.operand_type[1]->op_type & (AllReg))
+           insn.addressing_mode = AM_Register;
+         else if (insn.operand_type[1]->op_type & Indirect)
+           insn.addressing_mode = AM_Direct;
          else
-           current_op->op_type = OtherReg;
-         current_op->reg.opcode = regop->opcode;
-       }
-      else
-       {
-         if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
            {
-             char *save_input_line_pointer;
-             segT retval;
-             debug ("Probably a label: %s\n", token);
-             current_op->immediate.label = (char *) malloc (strlen (token) + 1);
-             strcpy (current_op->immediate.label, token);
-             current_op->immediate.label[strlen (token)] = '\0';
-             save_input_line_pointer = input_line_pointer;
-             input_line_pointer = token;
-             debug ("Current input_line_pointer: %s\n", input_line_pointer);
-             retval = expression (&current_op->immediate.imm_expr);
-             debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
-             debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
-             debug ("Segment: %d\n", retval);
-             input_line_pointer = save_input_line_pointer;
-             if (current_op->immediate.imm_expr.X_op == O_constant)
-               {
-                 current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
-                 current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
-                 current_op->immediate.resolved = 1;
-               }
+             /* Shouldn't make it to this stage.  */
+             as_bad ("Incompatible first and second operands in instruction");
+             return;
            }
+         break;
+       case Indirect:
+         if (insn.operand_type[1]->op_type & (AllReg))
+           insn.addressing_mode = AM_Indirect;
+         else if (insn.operand_type[1]->op_type & Indirect)
+           insn.addressing_mode = AM_Immediate;
          else
            {
-             unsigned count;
-             debug ("Found a number or displacement\n");
-             for (count = 0; count < strlen (token); count++)
-               if (*(token + count) == '.')
-                 current_op->immediate.decimal_found = 1;
-             current_op->immediate.label = (char *) malloc (strlen (token) + 1);
-             strcpy (current_op->immediate.label, token);
-             current_op->immediate.label[strlen (token)] = '\0';
-             current_op->immediate.f_number = (float) atof (token);
-             current_op->immediate.s_number = (int) atoi (token);
-             current_op->immediate.u_number = (unsigned int) atoi (token);
-             current_op->immediate.resolved = 1;
-           }
-         current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
-         if (current_op->immediate.u_number <= 31)
-           current_op->op_type |= IVector;
-       }
-    }
-  return current_op;
-}
-
-/* next_line points to the next line after the current instruction (current_line).
-   Search for the parallel bars, and if found, merge two lines into internal syntax
-   for a parallel instruction:
-   q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
-   By this stage, all comments are scrubbed, and only the bare lines are given.
- */
-
-#define NONE           0
-#define START_OPCODE   1
-#define END_OPCODE     2
-#define START_OPERANDS 3
-#define END_OPERANDS   4
-
-char *
-tic30_find_parallel_insn (current_line, next_line)
-     char *current_line;
-     char *next_line;
-{
-  int found_parallel = 0;
-  char first_opcode[256];
-  char second_opcode[256];
-  char first_operands[256];
-  char second_operands[256];
-  char *parallel_insn;
-
-  debug ("In tic30_find_parallel_insn()\n");
-  while (!is_end_of_line[(unsigned char) *next_line])
-    {
-      if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
-       {
-         found_parallel = 1;
-         next_line++;
-         break;
-       }
-      next_line++;
-    }
-  if (!found_parallel)
-    return NULL;
-  debug ("Found a parallel instruction\n");
-  {
-    int i;
-    char *opcode, *operands, *line;
-
-    for (i = 0; i < 2; i++)
-      {
-       if (i == 0)
-         {
-           opcode = &first_opcode[0];
-           operands = &first_operands[0];
-           line = current_line;
-         }
-       else
-         {
-           opcode = &second_opcode[0];
-           operands = &second_operands[0];
-           line = next_line;
-         }
+             /* Shouldn't make it to this stage.  */
+             as_bad ("Incompatible first and second operands in instruction");
+             return;
+           }
+         break;
+       }
+      /* Now make up the opcode for the 3 operand instructions.  As in
+        parallel instructions, there will be no unresolved values, so they
+        can be fully formed and added to the frag table.  */
+      insn.opcode = insn.tm->base_opcode;
+      if (insn.operand_type[0]->op_type & Indirect)
        {
-         int search_status = NONE;
-         int char_ptr = 0;
-         char c;
+         insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
+         insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
+       }
+      else
+       insn.opcode |= (insn.operand_type[0]->reg.opcode);
 
-         while (!is_end_of_line[(unsigned char) (c = *line)])
+      if (insn.operand_type[1]->op_type & Indirect)
+       {
+         insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
+         insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
+       }
+      else
+       insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
+
+      if (insn.operands == 3)
+       insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
+
+      insn.opcode |= insn.addressing_mode;
+      p = frag_more (INSN_SIZE);
+      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+    }
+  else
+    {
+      /* Not a three operand instruction.  */
+      char *p;
+      int am_insn = -1;
+      insn.opcode = insn.tm->base_opcode;
+      /* Create frag for instruction - all instructions are 4 bytes long.  */
+      p = frag_more (INSN_SIZE);
+      if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
+       {
+         insn.opcode |= insn.addressing_mode;
+         if (insn.addressing_mode == AM_Indirect)
            {
-             if (is_opcode_char (c) && search_status == NONE)
-               {
-                 opcode[char_ptr++] = TOLOWER (c);
-                 search_status = START_OPCODE;
-               }
-             else if (is_opcode_char (c) && search_status == START_OPCODE)
-               {
-                 opcode[char_ptr++] = TOLOWER (c);
-               }
-             else if (!is_opcode_char (c) && search_status == START_OPCODE)
-               {
-                 opcode[char_ptr] = '\0';
-                 char_ptr = 0;
-                 search_status = END_OPCODE;
-               }
-             else if (is_operand_char (c) && search_status == START_OPERANDS)
+             /* Determine which operand gives the addressing mode.  */
+             if (insn.operand_type[0]->op_type & Indirect)
+               am_insn = 0;
+             if ((insn.operands > 1)
+                 && (insn.operand_type[1]->op_type & Indirect))
+               am_insn = 1;
+             insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
+             insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
+             insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
+             if (insn.operands > 1)
+               insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
+             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+           }
+         else if (insn.addressing_mode == AM_Register)
+           {
+             insn.opcode |= (insn.operand_type[0]->reg.opcode);
+             if (insn.operands > 1)
+               insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+           }
+         else if (insn.addressing_mode == AM_Direct)
+           {
+             if (insn.operand_type[0]->op_type & Direct)
+               am_insn = 0;
+             if ((insn.operands > 1)
+                 && (insn.operand_type[1]->op_type & Direct))
+               am_insn = 1;
+             if (insn.operands > 1)
+               insn.opcode |=
+                 (insn.operand_type[! am_insn]->reg.opcode << 16);
+             if (insn.operand_type[am_insn]->direct.resolved == 1)
                {
-                 operands[char_ptr++] = c;
+                 /* Resolved values can be placed straight
+                    into instruction word, and output.  */
+                 insn.opcode |=
+                   (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                }
-             if (is_operand_char (c) && search_status == END_OPCODE)
+             else
                {
-                 operands[char_ptr++] = c;
-                 search_status = START_OPERANDS;
+                 /* Unresolved direct addressing mode instruction.  */
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
+                              & insn.operand_type[am_insn]->direct.direct_expr,
+                              0, 0);
                }
-             line++;
            }
-         if (search_status != START_OPERANDS)
-           return NULL;
-         operands[char_ptr] = '\0';
-       }
-      }
-  }
-  parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
-                    strlen (second_opcode) + strlen (second_operands) + 8);
-  sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
-  debug ("parallel insn = %s\n", parallel_insn);
-  return parallel_insn;
-}
-
-#undef NONE
-#undef START_OPCODE
-#undef END_OPCODE
-#undef START_OPERANDS
-#undef END_OPERANDS
-
-/* In order to get gas to ignore any | chars at the start of a line,
-   this function returns true if a | is found in a line.  */
-
-int
-tic30_unrecognized_line (c)
-     int c;
-{
-  debug ("In tc_unrecognized_line\n");
-  return (c == PARALLEL_SEPARATOR);
-}
-
-int
-md_estimate_size_before_relax (fragP, segment)
-     fragS *fragP ATTRIBUTE_UNUSED;
-     segT segment ATTRIBUTE_UNUSED;
-{
-  debug ("In md_estimate_size_before_relax()\n");
-  return 0;
-}
-
-void
-md_convert_frag (abfd, sec, fragP)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     segT sec ATTRIBUTE_UNUSED;
-     register fragS *fragP ATTRIBUTE_UNUSED;
-{
-  debug ("In md_convert_frag()\n");
-}
-
-void
-md_apply_fix3 (fixP, valP, seg)
-     fixS *fixP;
-     valueT *valP;
-     segT seg ATTRIBUTE_UNUSED;
-{
-  valueT value = *valP;
-
-  debug ("In md_apply_fix() with value = %ld\n", (long) value);
-  debug ("Values in fixP\n");
-  debug ("fx_size = %d\n", fixP->fx_size);
-  debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
-  debug ("fx_where = %d\n", fixP->fx_where);
-  debug ("fx_offset = %d\n", (int) fixP->fx_offset);
-  {
-    char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
-
-    value /= INSN_SIZE;
-    if (fixP->fx_size == 1)
-      /* Special fix for LDP instruction.  */
-      value = (value & 0x00FF0000) >> 16;
-
-    debug ("new value = %ld\n", (long) value);
-    md_number_to_chars (buf, value, fixP->fx_size);
-  }
-
-  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
-    fixP->fx_done = 1;
-}
-
-int
-md_parse_option (c, arg)
-     int c ATTRIBUTE_UNUSED;
-     char *arg ATTRIBUTE_UNUSED;
-{
-  debug ("In md_parse_option()\n");
-  return 0;
-}
+         else if (insn.addressing_mode == AM_Immediate)
+           {
+             if (insn.operand_type[0]->immediate.resolved == 1)
+               {
+                 char *keeploc;
+                 int size;
 
-void
-md_show_usage (stream)
-     FILE *stream ATTRIBUTE_UNUSED;
-{
-  debug ("In md_show_usage()\n");
-}
+                 if (insn.operands > 1)
+                   insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
 
-symbolS *
-md_undefined_symbol (name)
-     char *name ATTRIBUTE_UNUSED;
-{
-  debug ("In md_undefined_symbol()\n");
-  return (symbolS *) 0;
-}
+                 switch (insn.tm->imm_arg_type)
+                   {
+                   case Imm_Float:
+                     debug ("Floating point first operand\n");
+                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
 
-valueT
-md_section_align (segment, size)
-     segT segment;
-     valueT size;
-{
-  debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
-  size = (size + 3) / 4;
-  size *= 4;
-  debug ("New size value = %d\n", size);
-  return size;
-}
+                     keeploc = input_line_pointer;
+                     input_line_pointer =
+                       insn.operand_type[0]->immediate.label;
 
-long
-md_pcrel_from (fixP)
-     fixS *fixP;
-{
-  int offset;
+                     if (md_atof ('f', p + 2, & size) != 0)
+                       {
+                         as_bad ("invalid short form floating point immediate operand");
+                         return;
+                       }
 
-  debug ("In md_pcrel_from()\n");
-  debug ("fx_where = %d\n", fixP->fx_where);
-  debug ("fx_size = %d\n", fixP->fx_size);
-  /* Find the opcode that represents the current instruction in the fr_literal
-     storage area, and check bit 21.  Bit 21 contains whether the current instruction
-     is a delayed one or not, and then set the offset value appropriately.  */
-  if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
-    offset = 3;
-  else
-    offset = 1;
-  debug ("offset = %d\n", offset);
-  /* PC Relative instructions have a format:
-     displacement = Label - (PC + offset)
-     This function returns PC + offset where:
-     fx_where - fx_size = PC
-     INSN_SIZE * offset = offset number of instructions
-   */
-  return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
-}
+                     input_line_pointer = keeploc;
+                     break;
 
-char *
-md_atof (what_statement_type, literalP, sizeP)
-     int what_statement_type;
-     char *literalP;
-     int *sizeP;
-{
-  int prec;
-  char *token;
-  char keepval;
-  unsigned long value;
-  float float_value;
-  debug ("In md_atof()\n");
-  debug ("precision = %c\n", what_statement_type);
-  debug ("literal = %s\n", literalP);
-  debug ("line = ");
-  token = input_line_pointer;
-  while (!is_end_of_line[(unsigned char) *input_line_pointer]
-        && (*input_line_pointer != ','))
-    {
-      debug ("%c", *input_line_pointer);
-      input_line_pointer++;
-    }
-  keepval = *input_line_pointer;
-  *input_line_pointer = '\0';
-  debug ("\n");
-  float_value = (float) atof (token);
-  *input_line_pointer = keepval;
-  debug ("float_value = %f\n", float_value);
-  switch (what_statement_type)
-    {
-    case 'f':
-    case 'F':
-    case 's':
-    case 'S':
-      prec = 2;
-      break;
+                   case Imm_UInt:
+                     debug ("Unsigned int first operand\n");
+                     if (insn.operand_type[0]->immediate.decimal_found)
+                       as_warn ("rounding down first operand float to unsigned int");
+                     if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
+                       as_warn ("only lower 16-bits of first operand are used");
+                     insn.opcode |=
+                       (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
+                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                     break;
 
-    case 'd':
-    case 'D':
-    case 'r':
-    case 'R':
-      prec = 4;
-      break;
+                   case Imm_SInt:
+                     debug ("Int first operand\n");
 
-    default:
-      *sizeP = 0;
-      return "Bad call to MD_ATOF()";
-    }
-  if (float_value == 0.0)
-    {
-      value = (prec == 2) ? 0x00008000L : 0x80000000L;
-    }
-  else
-    {
-      unsigned long exp, sign, mant, tmsfloat;
-      tmsfloat = *((long *) &float_value);
-      sign = tmsfloat & 0x80000000;
-      mant = tmsfloat & 0x007FFFFF;
-      exp = tmsfloat & 0x7F800000;
-      exp <<= 1;
-      if (exp == 0xFF000000)
-       {
-         if (mant == 0)
-           value = 0x7F7FFFFF;
-         else if (sign == 0)
-           value = 0x7F7FFFFF;
-         else
-           value = 0x7F800000;
+                     if (insn.operand_type[0]->immediate.decimal_found)
+                       as_warn ("rounding down first operand float to signed int");
+
+                     if (insn.operand_type[0]->immediate.s_number < -32768 ||
+                         insn.operand_type[0]->immediate.s_number > 32767)
+                       {
+                         as_bad ("first operand is too large for 16-bit signed int");
+                         return;
+                       }
+                     insn.opcode |=
+                       (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
+                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                     break;
+                   }
+               }
+             else
+               {
+                 /* Unresolved immediate label.  */
+                 if (insn.operands > 1)
+                   insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
+                              & insn.operand_type[0]->immediate.imm_expr,
+                              0, 0);
+               }
+           }
        }
-      else
+      else if (insn.tm->opcode_modifier == PCRel)
        {
-         exp -= 0x7F000000;
-         if (sign)
+         /* Conditional Branch and Call instructions.  */
+         if ((insn.tm->operand_types[0] & (AllReg | Disp))
+             == (AllReg | Disp))
            {
-             mant = mant & 0x007FFFFF;
-             mant = -mant;
-             mant = mant & 0x00FFFFFF;
-             if (mant == 0)
+             if (insn.operand_type[0]->op_type & (AllReg))
                {
-                 mant |= 0x00800000;
-                 exp = (long) exp - 0x01000000;
+                 insn.opcode |= (insn.operand_type[0]->reg.opcode);
+                 insn.opcode |= PC_Register;
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+               }
+             else
+               {
+                 insn.opcode |= PC_Relative;
+                 if (insn.operand_type[0]->immediate.resolved == 1)
+                   {
+                     insn.opcode |=
+                       (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
+                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                   }
+                 else
+                   {
+                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                     fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
+                                  2, & insn.operand_type[0]->immediate.imm_expr,
+                                  1, 0);
+                   }
+               }
+           }
+         else if ((insn.tm->operand_types[0] & ARn) == ARn)
+           {
+             /* Decrement and Branch instructions.  */
+             insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
+             if (insn.operand_type[1]->op_type & (AllReg))
+               {
+                 insn.opcode |= (insn.operand_type[1]->reg.opcode);
+                 insn.opcode |= PC_Register;
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+               }
+             else if (insn.operand_type[1]->immediate.resolved == 1)
+               {
+                 if (insn.operand_type[0]->immediate.decimal_found)
+                   {
+                     as_bad ("first operand is floating point");
+                     return;
+                   }
+                 if (insn.operand_type[0]->immediate.s_number < -32768 ||
+                     insn.operand_type[0]->immediate.s_number > 32767)
+                   {
+                     as_bad ("first operand is too large for 16-bit signed int");
+                     return;
+                   }
+                 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
+                 insn.opcode |= PC_Relative;
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+               }
+             else
+               {
+                 insn.opcode |= PC_Relative;
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
+                              & insn.operand_type[1]->immediate.imm_expr,
+                              1, 0);
                }
            }
-         tmsfloat = exp | mant;
-         value = tmsfloat;
        }
-      if (prec == 2)
+      else if (insn.tm->operand_types[0] == IVector)
        {
-         long exp, mant;
-
-         if (tmsfloat == 0x80000000)
+         /* Trap instructions.  */
+         if (insn.operand_type[0]->op_type & IVector)
+           insn.opcode |= (insn.operand_type[0]->immediate.u_number);
+         else
            {
-             value = 0x8000;
+             /* Shouldn't get here.  */
+             as_bad ("interrupt vector for trap instruction out of range");
+             return;
            }
-         else
+         md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+       }
+      else if (insn.tm->opcode_modifier == StackOp
+              || insn.tm->opcode_modifier == Rotate)
+       {
+         /* Push, Pop and Rotate instructions.  */
+         insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
+         md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+       }
+      else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
+              == (Abs24 | Direct))
+       {
+         /* LDP Instruction needs to be tested
+            for before the next section.  */
+         if (insn.operand_type[0]->op_type & Direct)
            {
-             value = 0;
-             exp = (tmsfloat & 0xFF000000);
-             exp >>= 24;
-             mant = tmsfloat & 0x007FFFFF;
-             if (tmsfloat & 0x00800000)
+             if (insn.operand_type[0]->direct.resolved == 1)
                {
-                 mant |= 0xFF000000;
-                 mant += 0x00000800;
-                 mant >>= 12;
-                 mant |= 0x00000800;
-                 mant &= 0x0FFF;
-                 if (exp > 7)
-                   value = 0x7800;
+                 /* Direct addressing uses lower 8 bits of direct address.  */
+                 insn.opcode |=
+                   (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                }
              else
                {
-                 mant |= 0x00800000;
-                 mant += 0x00000800;
-                 exp += (mant >> 24);
-                 mant >>= 12;
-                 mant &= 0x07FF;
-                 if (exp > 7)
-                   value = 0x77FF;
+                 fixS *fix;
+
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
+                                    1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
+                 /* Ensure that the assembler doesn't complain
+                    about fitting a 24-bit address into 8 bits.  */
+                 fix->fx_no_overflow = 1;
                }
-             if (exp < -8)
-               value = 0x8000;
-             if (value == 0)
+           }
+         else
+           {
+             if (insn.operand_type[0]->immediate.resolved == 1)
                {
-                 mant = (exp << 12) | mant;
-                 value = mant & 0xFFFF;
+                 /* Immediate addressing uses upper 8 bits of address.  */
+                 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+                   {
+                     as_bad ("LDP instruction needs a 24-bit operand");
+                     return;
+                   }
+                 insn.opcode |=
+                   ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+               }
+             else
+               {
+                 fixS *fix;
+                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+                 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
+                                    1, &insn.operand_type[0]->immediate.imm_expr,
+                                    0, 0);
+                 fix->fx_no_overflow = 1;
                }
            }
        }
-    }
-  md_number_to_chars (literalP, value, prec);
-  *sizeP = prec;
-  return 0;
-}
-
-void
-md_number_to_chars (buf, val, n)
-     char *buf;
-     valueT val;
-     int n;
-{
-  debug ("In md_number_to_chars()\n");
-  number_to_chars_bigendian (buf, val, n);
-  /*  number_to_chars_littleendian(buf,val,n); */
-}
-
-#define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
-#define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
-
-arelent *
-tc_gen_reloc (section, fixP)
-     asection *section ATTRIBUTE_UNUSED;
-     fixS *fixP;
-{
-  arelent *rel;
-  bfd_reloc_code_real_type code = 0;
-
-  debug ("In tc_gen_reloc()\n");
-  debug ("fixP.size = %d\n", fixP->fx_size);
-  debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
-  debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
-  switch (F (fixP->fx_size, fixP->fx_pcrel))
-    {
-      MAP (1, 0, BFD_RELOC_TIC30_LDP);
-      MAP (2, 0, BFD_RELOC_16);
-      MAP (3, 0, BFD_RELOC_24);
-      MAP (2, 1, BFD_RELOC_16_PCREL);
-      MAP (4, 0, BFD_RELOC_32);
-    default:
-      as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
-             fixP->fx_pcrel ? "pc-relative " : "");
-    }
-#undef MAP
-#undef F
+      else if (insn.tm->operand_types[0] & (Imm24))
+       {
+         /* Unconditional Branch and Call instructions.  */
+         if (insn.operand_type[0]->immediate.resolved == 1)
+           {
+             if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+               as_warn ("first operand is too large for a 24-bit displacement");
+             insn.opcode |=
+               (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
+             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+           }
+         else
+           {
+             md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+             fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
+                          & insn.operand_type[0]->immediate.imm_expr, 0, 0);
+           }
+       }
+      else if (insn.tm->operand_types[0] & NotReq)
+       /* Check for NOP instruction without arguments.  */
+       md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
 
-  rel = (arelent *) xmalloc (sizeof (arelent));
-  assert (rel != 0);
-  rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
-  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
-  rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
-  rel->addend = 0;
-  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
-  if (!rel->howto)
-    {
-      const char *name;
-      name = S_GET_NAME (fixP->fx_addsy);
-      if (name == NULL)
-       name = "<unknown>";
-      as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
+      else if (insn.tm->operands == 0)
+       /* Check for instructions without operands.  */
+       md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
     }
-  return rel;
-}
+  debug ("Addressing mode: %08X\n", insn.addressing_mode);
+  {
+    unsigned int i;
 
-void
-md_operand (expressionP)
-     expressionS *expressionP ATTRIBUTE_UNUSED;
-{
-  debug ("In md_operand()\n");
+    for (i = 0; i < insn.operands; i++)
+      {
+       if (insn.operand_type[i]->immediate.label)
+         free (insn.operand_type[i]->immediate.label);
+       free (insn.operand_type[i]);
+      }
+  }
+  debug ("Final opcode: %08X\n", insn.opcode);
+  debug ("\n");
 }
 
-char output_invalid_buf[8];
-
-char *
-output_invalid (c)
-     char c;
-{
-  if (ISPRINT (c))
-    sprintf (output_invalid_buf, "'%c'", c);
-  else
-    sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
-  return output_invalid_buf;
-}
index 039671b57d60523fcbfc0518d080929876af1c72..c6cb16935fd21ad08a5cd246357a598146db6b32 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-tic30.h -- Header file for tc-tic30.c
-   Copyright 1998, 2000, 2002 Free Software Foundation, Inc.
+   Copyright 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
 
    This file is part of GAS, the GNU Assembler.
 
 #define TARGET_ARCH            bfd_arch_tic30
 #define TARGET_BYTES_BIG_ENDIAN        1
-
 #define WORKING_DOT_WORD
-
-char *output_invalid PARAMS ((int c));
-
-#define END_OF_INSN '\0'
-#define MAX_OPERANDS 6
-#define DIRECT_REFERENCE '@'
-#define INDIRECT_REFERENCE '*'
-#define PARALLEL_SEPARATOR '|'
-#define INSN_SIZE 4
+#define END_OF_INSN            '\0'
+#define MAX_OPERANDS           6
+#define DIRECT_REFERENCE       '@'
+#define INDIRECT_REFERENCE     '*'
+#define PARALLEL_SEPARATOR     '|'
+#define INSN_SIZE              4
 
 /* Define this to 1 if you want the debug output to be on stdout,
    otherwise stderr will be used.  If stderr is used, there will be a
    better synchronisation with the as_bad outputs, but you can't
    capture the output.  */
-#define USE_STDOUT 0
+#define USE_STDOUT             0
 
 #define tc_unrecognized_line tic30_unrecognized_line
 
-extern int tic30_unrecognized_line PARAMS ((int));
+extern int tic30_unrecognized_line (int);
 
 #define tc_aout_pre_write_hook {}