* doc/c-ppc.texi (PowerPC-Opts): Add -mpower4 and -maltivec.
[deliverable/binutils-gdb.git] / gas / config / tc-ns32k.c
index db0d4f11bc007d18daec0b4b20bd0997e726b961..1ef1ef1186994e71e4dca24f5533ef402ea10591 100644 (file)
@@ -1,5 +1,7 @@
 /* ns32k.c  -- Assemble on the National Semiconductor 32k series
-   Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+   Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001
+   Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   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.  */
 
-/*#define SHOW_NUM 1*//* uncomment for debugging */
+/*#define SHOW_NUM 1*//* Uncomment for debugging.  */
 
 #include <stdio.h>
-#include <ctype.h>
-#include "opcode/ns32k.h"
 
 #include "as.h"
+#include "opcode/ns32k.h"
 
 #include "obstack.h"
 
-/* Macros */
-#define IIF_ENTRIES 13         /* number of entries in iif */
-#define PRIVATE_SIZE 256       /* size of my garbage memory */
+/* Macros */
+#define IIF_ENTRIES 13         /* Number of entries in iif.  */
+#define PRIVATE_SIZE 256       /* Size of my garbage memory.  */
 #define MAX_ARGS 4
-#define DEFAULT        -1              /* addr_mode returns this value when plain constant or label is encountered */
-
-#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
-    iif.iifP[ptr].type= a1; \
-    iif.iifP[ptr].size= c1; \
-    iif.iifP[ptr].object= e1; \
-    iif.iifP[ptr].object_adjust= g1; \
-    iif.iifP[ptr].pcrel= i1; \
-    iif.iifP[ptr].pcrel_adjust= k1; \
-    iif.iifP[ptr].im_disp= m1; \
-    iif.iifP[ptr].relax_substate= o1; \
-    iif.iifP[ptr].bit_fixP= q1; \
-    iif.iifP[ptr].addr_mode= s1; \
+#define DEFAULT        -1              /* addr_mode returns this value when
+                                   plain constant or label is
+                                   encountered.  */
+
+#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1)      \
+    iif.iifP[ptr].type= a1;                            \
+    iif.iifP[ptr].size= c1;                            \
+    iif.iifP[ptr].object= e1;                          \
+    iif.iifP[ptr].object_adjust= g1;                   \
+    iif.iifP[ptr].pcrel= i1;                           \
+    iif.iifP[ptr].pcrel_adjust= k1;                    \
+    iif.iifP[ptr].im_disp= m1;                         \
+    iif.iifP[ptr].relax_substate= o1;                  \
+    iif.iifP[ptr].bit_fixP= q1;                                \
+    iif.iifP[ptr].addr_mode= s1;                       \
     iif.iifP[ptr].bsr= u1;
 
 #ifdef SEQUENT_COMPATABILITY
@@ -58,7 +62,8 @@
 
 const char comment_chars[] = "#";
 const char line_comment_chars[] = LINE_COMMENT_CHARS;
-const char line_separator_chars[] = "";
+const char line_separator_chars[] = ";";
+
 #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
 #define ABSOLUTE_PREFIX '@'    /* One or the other MUST be defined */
 #endif
@@ -68,8 +73,10 @@ struct addr_mode
     char mode;                 /* addressing mode of operand (0-31) */
     char scaled_mode;          /* mode combined with scaled mode */
     char scaled_reg;           /* register used in scaled+1 (1-8) */
-    char float_flag;           /* set if R0..R7 was F0..F7 ie a floating-point-register */
-    char am_size;              /* estimated max size of general addr-mode parts*/
+    char float_flag;           /* set if R0..R7 was F0..F7 ie a
+                                  floating-point-register */
+    char am_size;              /* estimated max size of general addr-mode
+                                  parts */
     char im_disp;              /* if im_disp==1 we have a displacement */
     char pcrel;                        /* 1 if pcrel, this is really redundant info */
     char disp_suffix[2];       /* length of displacement(s), 0=undefined */
@@ -79,29 +86,29 @@ struct addr_mode
   };
 typedef struct addr_mode addr_modeS;
 
-
-char *freeptr, *freeptr_static;        /* points at some number of free bytes */
+char *freeptr, *freeptr_static;        /* Points at some number of free bytes.  */
 struct hash_control *inst_hash_handle;
 
-struct ns32k_opcode *desc;     /* pointer at description of instruction */
+struct ns32k_opcode *desc;     /* Pointer at description of instruction.  */
 addr_modeS addr_modeP;
 const char EXP_CHARS[] = "eE";
-const char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */
-
-/* UPPERCASE denotes live names
- * when an instruction is built, IIF is used as an intermidiate form to store
- * the actual parts of the instruction. A ns32k machine instruction can
- * be divided into a couple of sub PARTs. When an instruction is assembled
- * the appropriate PART get an assignment. When an IIF has been completed it's
- * converted to a FRAGment as specified in AS.H */
-
-/* internal structs */
-struct option
-  {
-    char *pattern;
-    unsigned long or;
-    unsigned long and;
-  };
+const char FLT_CHARS[] = "fd"; /* We don't want to support lowercase,
+                                   do we?  */
+
+/* UPPERCASE denotes live names when an instruction is built, IIF is
+ * used as an intermediate form to store the actual parts of the
+ * instruction. A ns32k machine instruction can be divided into a
+ * couple of sub PARTs. When an instruction is assembled the
+ * appropriate PART get an assignment. When an IIF has been completed
+ * it is converted to a FRAGment as specified in AS.H.  */
+
+/* Internal structs.  */
+struct ns32k_option
+{
+  char *pattern;
+  unsigned long or;
+  unsigned long and;
+};
 
 typedef struct
   {
@@ -116,69 +123,68 @@ typedef struct
     int im_disp;               /* True if the object is a displacement */
     relax_substateT relax_substate;    /* Initial relaxsubstate */
     bit_fixS *bit_fixP;                /* Pointer at bit_fix struct */
-    int addr_mode;             /* What addrmode do we associate with this iif-entry */
+    int addr_mode;             /* What addrmode do we associate with this
+                                  iif-entry */
     char bsr;                  /* Sequent hack */
-  }
-
-iif_entryT;                    /* Internal Instruction Format */
+  } iif_entryT;                        /* Internal Instruction Format */
 
 struct int_ins_form
   {
-    int instr_size;            /* Max size of instruction in bytes. */
+    int instr_size;            /* Max size of instruction in bytes.  */
     iif_entryT iifP[IIF_ENTRIES + 1];
   };
+
 struct int_ins_form iif;
 expressionS exprP;
 char *input_line_pointer;
-/* description of the PARTs in IIF
- *object[n]:
- * 0   total length in bytes of entries in iif
- * 1   opcode
- * 2   index_byte_a
- * 3   index_byte_b
- * 4   disp_a_1
- * 5   disp_a_2
- * 6   disp_b_1
- * 7   disp_b_2
- * 8   imm_a
- * 9   imm_b
- * 10  implied1
- * 11  implied2
- *
- * For every entry there is a datalength in bytes. This is stored in size[n].
- *      0,     the objectlength is not explicitly given by the instruction
- *             and the operand is undefined. This is a case for relaxation.
- *             Reserve 4 bytes for the final object.
- *
- *      1,     the entry contains one byte
- *      2,     the entry contains two bytes
- *      3,     the entry contains three bytes
- *      4,     the entry contains four bytes
- *     etc
- *
- * Furthermore, every entry has a data type identifier in type[n].
- *
- *      0,     the entry is void, ignore it.
- *      1,     the entry is a binary number.
- *      2,     the entry is a pointer at an expression.
- *             Where expression may be as simple as a single '1',
- *             and as complicated as  foo-bar+12,
- *             foo and bar may be undefined but suffixed by :{b|w|d} to
- *             control the length of the object.
- *
- *      3,     the entry is a pointer at a bignum struct
- *
- *
- * The low-order-byte coresponds to low physical memory.
- * Obviously a FRAGment must be created for each valid disp in PART whose
- * datalength is undefined (to bad) .
- * The case where just the expression is undefined is less severe and is
- * handled by fix. Here the number of bytes in the objectfile is known.
- * With this representation we simplify the assembly and separates the
- * machine dependent/independent parts in a more clean way (said OE)
- */
+
+/* Description of the PARTs in IIF
+  object[n]:
+   0   total length in bytes of entries in iif
+   1   opcode
+   2   index_byte_a
+   3   index_byte_b
+   4   disp_a_1
+   5   disp_a_2
+   6   disp_b_1
+   7   disp_b_2
+   8   imm_a
+   9   imm_b
+   10  implied1
+   11  implied2
+
+   For every entry there is a datalength in bytes. This is stored in size[n].
+        0,     the objectlength is not explicitly given by the instruction
+               and the operand is undefined. This is a case for relaxation.
+               Reserve 4 bytes for the final object.
+
+        1,     the entry contains one byte
+        2,     the entry contains two bytes
+        3,     the entry contains three bytes
+        4,     the entry contains four bytes
+       etc
+
+   Furthermore, every entry has a data type identifier in type[n].
+
+        0,     the entry is void, ignore it.
+        1,     the entry is a binary number.
+        2,     the entry is a pointer at an expression.
+               Where expression may be as simple as a single '1',
+               and as complicated as  foo-bar+12,
+               foo and bar may be undefined but suffixed by :{b|w|d} to
+               control the length of the object.
+
+        3,     the entry is a pointer at a bignum struct
+
+   The low-order-byte coresponds to low physical memory.
+   Obviously a FRAGment must be created for each valid disp in PART whose
+   datalength is undefined (to bad) .
+   The case where just the expression is undefined is less severe and is
+   handled by fix. Here the number of bytes in the objectfile is known.
+   With this representation we simplify the assembly and separates the
+   machine dependent/independent parts in a more clean way (said OE).  */
 \f
-struct option opt1[] =         /* restore, exit */
+struct ns32k_option opt1[] =           /* restore, exit */
 {
   {"r0", 0x80, 0xff},
   {"r1", 0x40, 0xff},
@@ -190,7 +196,7 @@ struct option opt1[] =              /* restore, exit */
   {"r7", 0x01, 0xff},
   {0, 0x00, 0xff}
 };
-struct option opt2[] =         /* save, enter */
+struct ns32k_option opt2[] =           /* save, enter */
 {
   {"r0", 0x01, 0xff},
   {"r1", 0x02, 0xff},
@@ -202,7 +208,7 @@ struct option opt2[] =              /* save, enter */
   {"r7", 0x80, 0xff},
   {0, 0x00, 0xff}
 };
-struct option opt3[] =         /* setcfg */
+struct ns32k_option opt3[] =           /* setcfg */
 {
   {"c", 0x8, 0xff},
   {"m", 0x4, 0xff},
@@ -210,21 +216,21 @@ struct option opt3[] =            /* setcfg */
   {"i", 0x1, 0xff},
   {0, 0x0, 0xff}
 };
-struct option opt4[] =         /* cinv */
+struct ns32k_option opt4[] =           /* cinv */
 {
   {"a", 0x4, 0xff},
   {"i", 0x2, 0xff},
   {"d", 0x1, 0xff},
   {0, 0x0, 0xff}
 };
-struct option opt5[] =         /* string inst */
+struct ns32k_option opt5[] =           /* string inst */
 {
   {"b", 0x2, 0xff},
   {"u", 0xc, 0xff},
   {"w", 0x4, 0xff},
   {0, 0x0, 0xff}
 };
-struct option opt6[] =         /* plain reg ext,cvtp etc */
+struct ns32k_option opt6[] =           /* plain reg ext,cvtp etc */
 {
   {"r0", 0x00, 0xff},
   {"r1", 0x01, 0xff},
@@ -238,10 +244,10 @@ struct option opt6[] =            /* plain reg ext,cvtp etc */
 };
 
 #if !defined(NS32032) && !defined(NS32532)
-#define NS32032
+#define NS32532
 #endif
 
-struct option cpureg_532[] =   /* lpr spr */
+struct ns32k_option cpureg_532[] =     /* lpr spr */
 {
   {"us", 0x0, 0xff},
   {"dcr", 0x1, 0xff},
@@ -258,7 +264,7 @@ struct option cpureg_532[] =        /* lpr spr */
   {"mod", 0xf, 0xff},
   {0, 0x00, 0xff}
 };
-struct option mmureg_532[] =   /* lmr smr */
+struct ns32k_option mmureg_532[] =     /* lmr smr */
 {
   {"mcr", 0x9, 0xff},
   {"msr", 0xa, 0xff},
@@ -270,7 +276,7 @@ struct option mmureg_532[] =        /* lmr smr */
   {0, 0x0, 0xff}
 };
 
-struct option cpureg_032[] =   /* lpr spr */
+struct ns32k_option cpureg_032[] =     /* lpr spr */
 {
   {"upsr", 0x0, 0xff},
   {"fp", 0x8, 0xff},
@@ -281,7 +287,7 @@ struct option cpureg_032[] =        /* lpr spr */
   {"mod", 0xf, 0xff},
   {0, 0x0, 0xff}
 };
-struct option mmureg_032[] =   /* lmr smr */
+struct ns32k_option mmureg_032[] =     /* lmr smr */
 {
   {"bpr0", 0x0, 0xff},
   {"bpr1", 0x1, 0xff},
@@ -297,43 +303,42 @@ struct option mmureg_032[] =      /* lmr smr */
 };
 
 #if defined(NS32532)
-struct option *cpureg = cpureg_532;
-struct option *mmureg = mmureg_532;
+struct ns32k_option *cpureg = cpureg_532;
+struct ns32k_option *mmureg = mmureg_532;
 #else
-struct option *cpureg = cpureg_032;
-struct option *mmureg = mmureg_032;
+struct ns32k_option *cpureg = cpureg_032;
+struct ns32k_option *mmureg = mmureg_032;
 #endif
 \f
 
 const pseudo_typeS md_pseudo_table[] =
-{                              /* so far empty */
+{                                      /* So far empty.  */
   {0, 0, 0}
 };
 
 #define IND(x,y)       (((x)<<2)+(y))
 
-/* those are index's to relax groups in md_relax_table
-   ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
-   Se function relax_segment in write.c for more info */
+/* Those are index's to relax groups in md_relax_table ie it must be
+   multiplied by 4 to point at a group start. Viz IND(x,y) Se function
+   relax_segment in write.c for more info.  */
 
 #define BRANCH         1
 #define PCREL          2
 
-/* those are index's to entries in a relax group */
+/* Those are index's to entries in a relax group.  */
 
 #define BYTE           0
 #define WORD           1
 #define DOUBLE         2
 #define UNDEF           3
 /* Those limits are calculated from the displacement start in memory.
-   The ns32k uses the begining of the instruction as displacement base.
-   This type of displacements could be handled here by moving the limit window
-   up or down. I choose to use an internal displacement base-adjust as there
-   are other routines that must consider this. Also, as we have two various
-   offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
-   would have had to be used.
-   Now we dont have to think about that. */
-
+   The ns32k uses the begining of the instruction as displacement
+   base.  This type of displacements could be handled here by moving
+   the limit window up or down. I choose to use an internal
+   displacement base-adjust as there are other routines that must
+   consider this. Also, as we have two various offset-adjusts in the
+   ns32k (acb versus br/brs/jsr/bcond), two set of limits would have
+   had to be used.  Now we dont have to think about that.  */
 
 const relax_typeS md_relax_table[] =
 {
@@ -349,7 +354,7 @@ const relax_typeS md_relax_table[] =
 };
 
 /* Array used to test if mode contains displacements.
-   Value is true if mode contains displacement. */
+   Value is true if mode contains displacement.  */
 
 char disp_test[] =
 {0, 0, 0, 0, 0, 0, 0, 0,
@@ -357,34 +362,23 @@ char disp_test[] =
  1, 1, 1, 0, 0, 1, 1, 0,
  1, 1, 1, 1, 1, 1, 1, 1};
 
-/* Array used to calculate max size of displacements */
+/* Array used to calculate max size of displacements */
 
 char disp_size[] =
 {4, 1, 2, 0, 4};
 \f
+static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr));
+static void md_number_to_disp PARAMS ((char *buf, long val, int n));
+static void md_number_to_imm PARAMS ((char *buf, long val, int n));
 
-#if __STDC__ == 1
-
-static segT evaluate_expr (expressionS * resultP, char *ptr);
-static void md_number_to_disp (char *buf, long val, int n);
-static void md_number_to_imm (char *buf, long val, int n);
+/* Parse a general operand into an addressingmode struct
 
-#else /* not __STDC__ */
+   In:  pointer at operand in ascii form
+        pointer at addr_mode struct for result
+        the level of recursion. (always 0 or 1)
 
-static segT evaluate_expr ();
-static void md_number_to_disp ();
-static void md_number_to_imm ();
+   Out: data in addr_mode struct.  */
 
-#endif /* not __STDC__ */
-
-/* Parses a general operand into an addressingmode struct
-
-   in:  pointer at operand in ascii form
-   pointer at addr_mode struct for result
-   the level of recursion. (always 0 or 1)
-
-   out: data in addr_mode struct
-   */
 int
 addr_mode (operand, addr_modeP, recursive_level)
      char *operand;
@@ -396,6 +390,7 @@ addr_mode (operand, addr_modeP, recursive_level)
   register int strl;
   register int mode;
   int j;
+
   mode = DEFAULT;              /* default */
   addr_modeP->scaled_mode = 0; /* why not */
   addr_modeP->scaled_reg = 0;  /* if 0, not scaled index */
@@ -408,22 +403,23 @@ addr_mode (operand, addr_modeP, recursive_level)
   addr_modeP->disp[0] = NULL;
   addr_modeP->disp[1] = NULL;
   str = operand;
+
   if (str[0] == 0)
-    {
-      return (0);
-    }                          /* we don't want this */
+    return 0;
+
   strl = strlen (str);
+
   switch (str[0])
     {
-      /* the following three case statements controls the mode-chars
-                  this is the place to ed if you want to change them */
+      /* The following three case statements controls the mode-chars
+        this is the place to ed if you want to change them.  */
 #ifdef ABSOLUTE_PREFIX
     case ABSOLUTE_PREFIX:
       if (str[strl - 1] == ']')
        break;
       addr_modeP->mode = 21;   /* absolute */
       addr_modeP->disp[0] = str + 1;
-      return (-1);
+      return -1;
 #endif
 #ifdef IMMEDIATE_PREFIX
     case IMMEDIATE_PREFIX:
@@ -431,7 +427,7 @@ addr_mode (operand, addr_modeP, recursive_level)
        break;
       addr_modeP->mode = 20;   /* immediate */
       addr_modeP->disp[0] = str + 1;
-      return (-1);
+      return -1;
 #endif
     case '.':
       if (str[strl - 1] != ']')
@@ -444,11 +440,11 @@ addr_mode (operand, addr_modeP, recursive_level)
                {
                  addr_modeP->mode = 27;        /* pc-relativ */
                  addr_modeP->disp[0] = str + 2;
-                 return (-1);
+                 return -1;
                }
            default:
-             as_warn ("Invalid syntax in PC-relative addressing mode");
-             return (0);
+             as_warn (_("Invalid syntax in PC-relative addressing mode"));
+             return 0;
            }
        }
       break;
@@ -456,12 +452,12 @@ addr_mode (operand, addr_modeP, recursive_level)
       if (str[strl - 1] != ']')
        {
          if ((!strncmp (str, "ext(", 4)) && strl > 7)
-           {                   /* external */
+           {                           /* external */
              addr_modeP->disp[0] = str + 4;
              i = 0;
              j = 2;
              do
-               {               /* disp[0]'s termination point */
+               {                       /* disp[0]'s termination point */
                  j += 1;
                  if (str[j] == '(')
                    i++;
@@ -471,19 +467,23 @@ addr_mode (operand, addr_modeP, recursive_level)
              while (j < strl && i != 0);
              if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
                {
-                 as_warn ("Invalid syntax in External addressing mode");
+                 as_warn (_("Invalid syntax in External addressing mode"));
                  return (0);
                }
-             str[j] = '\000';  /* null terminate disp[0] */
+             str[j] = '\000';          /* null terminate disp[0] */
              addr_modeP->disp[1] = str + j + 2;
              addr_modeP->mode = 22;
-             return (-1);
+             return -1;
            }
        }
       break;
-    default:;
+
+    default:
+      ;
     }
+
   strl = strlen (str);
+
   switch (strl)
     {
     case 2:
@@ -491,21 +491,31 @@ addr_mode (operand, addr_modeP, recursive_level)
        {
        case 'f':
          addr_modeP->float_flag = 1;
+         /* Drop through.  */
        case 'r':
          if (str[1] >= '0' && str[1] < '8')
            {
              addr_modeP->mode = str[1] - '0';
-             return (-1);
+             return -1;
            }
+         break;
+       default:
+         break;
        }
+      /* Drop through.  */
+
     case 3:
       if (!strncmp (str, "tos", 3))
        {
-         addr_modeP->mode = 23;/* TopOfStack */
-         return (-1);
+         addr_modeP->mode = 23;        /* TopOfStack */
+         return -1;
        }
-    default:;
+      break;
+
+    default:
+      break;
     }
+
   if (strl > 4)
     {
       if (str[strl - 1] == ')')
@@ -513,22 +523,18 @@ addr_mode (operand, addr_modeP, recursive_level)
          if (str[strl - 2] == ')')
            {
              if (!strncmp (&str[strl - 5], "(fp", 3))
-               {
-                 mode = 16;    /* Memory Relative */
-               }
-             if (!strncmp (&str[strl - 5], "(sp", 3))
-               {
-                 mode = 17;
-               }
-             if (!strncmp (&str[strl - 5], "(sb", 3))
-               {
-                 mode = 18;
-               }
+               mode = 16;              /* Memory Relative.  */
+             else if (!strncmp (&str[strl - 5], "(sp", 3))
+               mode = 17;
+             else if (!strncmp (&str[strl - 5], "(sb", 3))
+               mode = 18;
+
              if (mode != DEFAULT)
-               {               /* memory relative */
+               {                       /* Memory relative.  */
                  addr_modeP->mode = mode;
-                 j = strl - 5; /* temp for end of disp[0] */
+                 j = strl - 5;         /* Temp for end of disp[0].  */
                  i = 0;
+
                  do
                    {
                      strl -= 1;
@@ -538,56 +544,59 @@ addr_mode (operand, addr_modeP, recursive_level)
                        i--;
                    }
                  while (strl > -1 && i != 0);
+
                  if (i != 0)
                    {
-                     as_warn ("Invalid syntax in Memory Relative addressing mode");
+                     as_warn (_("Invalid syntax in Memory Relative addressing mode"));
                      return (0);
                    }
+
                  addr_modeP->disp[1] = str;
                  addr_modeP->disp[0] = str + strl + 1;
-                 str[j] = '\000';      /* null terminate disp[0] */
-                 str[strl] = '\000';   /* null terminate disp[1] */
-                 return (-1);
+                 str[j] = '\000';      /* Null terminate disp[0] .  */
+                 str[strl] = '\000';   /* Null terminate disp[1].  */
+
+                 return -1;
                }
            }
+
          switch (str[strl - 3])
            {
            case 'r':
            case 'R':
-             if (str[strl - 2] >= '0' && str[strl - 2] < '8' && str[strl - 4] == '(')
+             if (str[strl - 2] >= '0'
+                 && str[strl - 2] < '8'
+                 && str[strl - 4] == '(')
                {
                  addr_modeP->mode = str[strl - 2] - '0' + 8;
                  addr_modeP->disp[0] = str;
                  str[strl - 4] = 0;
-                 return (-1);  /* reg rel */
+                 return -1;            /* reg rel */
                }
+             /* Drop through.  */
+
            default:
              if (!strncmp (&str[strl - 4], "(fp", 3))
-               {
-                 mode = 24;
-               }
-             if (!strncmp (&str[strl - 4], "(sp", 3))
-               {
-                 mode = 25;
-               }
-             if (!strncmp (&str[strl - 4], "(sb", 3))
-               {
-                 mode = 26;
-               }
-             if (!strncmp (&str[strl - 4], "(pc", 3))
-               {
-                 mode = 27;
-               }
+               mode = 24;
+             else if (!strncmp (&str[strl - 4], "(sp", 3))
+               mode = 25;
+             else if (!strncmp (&str[strl - 4], "(sb", 3))
+               mode = 26;
+             else if (!strncmp (&str[strl - 4], "(pc", 3))
+               mode = 27;
+
              if (mode != DEFAULT)
                {
                  addr_modeP->mode = mode;
                  addr_modeP->disp[0] = str;
                  str[strl - 4] = '\0';
-                 return (-1);  /* memory space */
+
+                 return -1;            /* Memory space.  */
                }
            }
        }
-      /* no trailing ')' do we have a ']' ? */
+
+      /* No trailing ')' do we have a ']' ?  */
       if (str[strl - 1] == ']')
        {
          switch (str[strl - 2])
@@ -604,200 +613,216 @@ addr_mode (operand, addr_modeP, recursive_level)
            case 'q':
              mode = 31;
              break;
-           default:;
-             as_warn ("Invalid scaled-indexed mode, use (b,w,d,q)");
-             if (str[strl - 3] != ':' || str[strl - 6] != '[' ||
-                 str[strl - 5] == 'r' || str[strl - 4] < '0' || str[strl - 4] > '7')
-               {
-                 as_warn ("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
-               }
-           }                   /* scaled index */
-         {
-           if (recursive_level > 0)
-             {
-               as_warn ("Scaled-indexed addressing mode combined with scaled-index");
-               return (0);
-             }
-           addr_modeP->am_size += 1;   /* scaled index byte */
-           j = str[strl - 4] - '0';    /* store temporary */
-           str[strl - 6] = '\000';     /* nullterminate for recursive call */
-           i = addr_mode (str, addr_modeP, 1);
-           if (!i || addr_modeP->mode == 20)
-             {
-               as_warn ("Invalid or illegal addressing mode combined with scaled-index");
-               return (0);
-             }
-           addr_modeP->scaled_mode = addr_modeP->mode; /* store the inferior mode */
-           addr_modeP->mode = mode;
-           addr_modeP->scaled_reg = j + 1;
-           return (-1);
-         }
+           default:
+             as_warn (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
+
+             if (str[strl - 3] != ':' || str[strl - 6] != '['
+                 || str[strl - 5] == 'r' || str[strl - 4] < '0'
+                 || str[strl - 4] > '7')
+               as_warn (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
+           } /* Scaled index.  */
+
+         if (recursive_level > 0)
+           {
+             as_warn (_("Scaled-indexed addressing mode combined with scaled-index"));
+             return 0;
+           }
+
+         addr_modeP->am_size += 1;     /* scaled index byte */
+         j = str[strl - 4] - '0';      /* store temporary */
+         str[strl - 6] = '\000';       /* nullterminate for recursive call */
+         i = addr_mode (str, addr_modeP, 1);
+
+         if (!i || addr_modeP->mode == 20)
+           {
+             as_warn (_("Invalid or illegal addressing mode combined with scaled-index"));
+             return 0;
+           }
+
+         addr_modeP->scaled_mode = addr_modeP->mode;   /* Store the inferior mode.  */
+         addr_modeP->mode = mode;
+         addr_modeP->scaled_reg = j + 1;
+
+         return -1;
        }
     }
-  addr_modeP->mode = DEFAULT;  /* default to whatever */
+
+  addr_modeP->mode = DEFAULT;  /* Default to whatever.  */
   addr_modeP->disp[0] = str;
-  return (-1);
+
+  return -1;
 }
 \f
-/* ptr points at string
-   addr_modeP points at struct with result
-   This routine calls addr_mode to determine the general addr.mode of
-   the operand. When this is ready it parses the displacements for size
-   specifying suffixes and determines size of immediate mode via ns32k-opcode.
-   Also builds index bytes if needed.
-   */
+/* ptr points at string addr_modeP points at struct with result This
+   routine calls addr_mode to determine the general addr.mode of the
+   operand. When this is ready it parses the displacements for size
+   specifying suffixes and determines size of immediate mode via
+   ns32k-opcode.  Also builds index bytes if needed.  */
+
 int
 get_addr_mode (ptr, addr_modeP)
      char *ptr;
      addr_modeS *addr_modeP;
 {
   int tmp;
+
   addr_mode (ptr, addr_modeP, 0);
+
   if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
     {
-      /* resolve ambigious operands, this shouldn't
-                  be necessary if one uses standard NSC operand
-                  syntax. But the sequent compiler doesn't!!!
-                  This finds a proper addressinging mode if it
-                  is implicitly stated. See ns32k-opcode.h */
-      (void) evaluate_expr (&exprP, ptr);      /* this call takes time Sigh! */
+      /* Resolve ambigious operands, this shouldn't be necessary if
+        one uses standard NSC operand syntax. But the sequent
+        compiler doesn't!!!  This finds a proper addressinging mode
+        if it is implicitly stated. See ns32k-opcode.h.  */
+      (void) evaluate_expr (&exprP, ptr); /* This call takes time Sigh!  */
+
       if (addr_modeP->mode == DEFAULT)
        {
-         if (exprP.X_add_symbol || exprP.X_subtract_symbol)
-           {
-             addr_modeP->mode = desc->default_model;   /* we have a label */
-           }
+         if (exprP.X_add_symbol || exprP.X_op_symbol)
+           addr_modeP->mode = desc->default_model; /* We have a label.  */
          else
-           {
-             addr_modeP->mode = desc->default_modec;   /* we have a constant */
-           }
+           addr_modeP->mode = desc->default_modec; /* We have a constant.  */
        }
       else
        {
-         if (exprP.X_add_symbol || exprP.X_subtract_symbol)
-           {
-             addr_modeP->scaled_mode = desc->default_model;
-           }
+         if (exprP.X_add_symbol || exprP.X_op_symbol)
+           addr_modeP->scaled_mode = desc->default_model;
          else
-           {
-             addr_modeP->scaled_mode = desc->default_modec;
-           }
+           addr_modeP->scaled_mode = desc->default_modec;
        }
-      /* must put this mess down in addr_mode to handle the scaled case better */
+
+      /* Must put this mess down in addr_mode to handle the scaled
+         case better.  */
     }
-  /* It appears as the sequent compiler wants an absolute when we have a
-          label without @. Constants becomes immediates besides the addr case.
-          Think it does so with local labels too, not optimum, pcrel is better.
-          When I have time I will make gas check this and select pcrel when possible
-          Actually that is trivial.
-          */
+
+  /* It appears as the sequent compiler wants an absolute when we have
+     a label without @. Constants becomes immediates besides the addr
+     case.  Think it does so with local labels too, not optimum, pcrel
+     is better.  When I have time I will make gas check this and
+     select pcrel when possible Actually that is trivial.  */
   if (tmp = addr_modeP->scaled_reg)
-    {                          /* build indexbyte */
-      tmp--;                   /* remember regnumber comes incremented for flagpurpose */
+    {                          /* Build indexbyte.  */
+      tmp--;                   /* Remember regnumber comes incremented for
+                                  flagpurpose.  */
       tmp |= addr_modeP->scaled_mode << 3;
       addr_modeP->index_byte = (char) tmp;
       addr_modeP->am_size += 1;
     }
+
   if (disp_test[addr_modeP->mode])
-    {                          /* there was a displacement, probe for length specifying suffix*/
-      {
-       register char c;
-       register char suffix;
-       register char suffix_sub;
-       register int i;
-       register char *toP;
-       register char *fromP;
-
-       addr_modeP->pcrel = 0;
-       if (disp_test[addr_modeP->mode])
-         {                     /* there is a displacement */
-           if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
-             {                 /* do we have pcrel. mode */
-               addr_modeP->pcrel = 1;
-             }
-           addr_modeP->im_disp = 1;
-           for (i = 0; i < 2; i++)
-             {
-               suffix_sub = suffix = 0;
-               if (toP = addr_modeP->disp[i])
-                 {             /* suffix of expression, the largest size rules */
-                   fromP = toP;
-                   while (c = *fromP++)
-                     {
-                       *toP++ = c;
-                       if (c == ':')
-                         {
-                           switch (*fromP)
-                             {
-                             case '\0':
-                               as_warn ("Premature end of suffix--Defaulting to d");
-                               suffix = 4;
-                               continue;
-                             case 'b':
-                               suffix_sub = 1;
-                               break;
-                             case 'w':
-                               suffix_sub = 2;
-                               break;
-                             case 'd':
-                               suffix_sub = 4;
-                               break;
-                             default:
-                               as_warn ("Bad suffix after ':' use {b|w|d} Defaulting to d");
-                               suffix = 4;
-                             }
-                           fromP++;
-                           toP--;      /* So we write over the ':' */
-                           if (suffix < suffix_sub)
-                             suffix = suffix_sub;
-                         }
-                     }
-                   *toP = '\0';/* terminate properly */
-                   addr_modeP->disp_suffix[i] = suffix;
-                   addr_modeP->am_size += suffix ? suffix : 4;
-                 }
-             }
-         }
-      }
+    {
+      register char c;
+      register char suffix;
+      register char suffix_sub;
+      register int i;
+      register char *toP;
+      register char *fromP;
+
+      /* There was a displacement, probe for length  specifying suffix.  */
+      addr_modeP->pcrel = 0;
+
+      if (disp_test[addr_modeP->mode])
+       {
+         /* There is a displacement.  */
+         if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
+           /* Do we have pcrel. mode.  */
+           addr_modeP->pcrel = 1;
+
+         addr_modeP->im_disp = 1;
+
+         for (i = 0; i < 2; i++)
+           {
+             suffix_sub = suffix = 0;
+
+             if (toP = addr_modeP->disp[i])
+               {
+                 /* Suffix of expression, the largest size rules.  */
+                 fromP = toP;
+
+                 while (c = *fromP++)
+                   {
+                     *toP++ = c;
+                     if (c == ':')
+                       {
+                         switch (*fromP)
+                           {
+                           case '\0':
+                             as_warn (_("Premature end of suffix -- Defaulting to d"));
+                             suffix = 4;
+                             continue;
+                           case 'b':
+                             suffix_sub = 1;
+                             break;
+                           case 'w':
+                             suffix_sub = 2;
+                             break;
+                           case 'd':
+                             suffix_sub = 4;
+                             break;
+                           default:
+                             as_warn (_("Bad suffix after ':' use {b|w|d} Defaulting to d"));
+                             suffix = 4;
+                           }
+
+                         fromP ++;
+                         toP --;       /* So we write over the ':' */
+
+                         if (suffix < suffix_sub)
+                           suffix = suffix_sub;
+                       }
+                   }
+
+                 *toP = '\0'; /* Terminate properly.  */
+                 addr_modeP->disp_suffix[i] = suffix;
+                 addr_modeP->am_size += suffix ? suffix : 4;
+               }
+           }
+       }
     }
   else
     {
       if (addr_modeP->mode == 20)
-       {                       /* look in ns32k_opcode for size */
+       {
+         /* Look in ns32k_opcode for size.  */
          addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
          addr_modeP->im_disp = 0;
        }
     }
+
   return addr_modeP->mode;
 }
 
+/* Read an optionlist.  */
 
-/* read an optionlist */
 void
 optlist (str, optionP, default_map)
-     char *str;                        /* the string to extract options from */
-     struct option *optionP;   /* how to search the string */
-     unsigned long *default_map;/* default pattern and output */
+     char *str;                        /* The string to extract options from.  */
+     struct ns32k_option *optionP;     /* How to search the string.  */
+     unsigned long *default_map;       /* Default pattern and output.  */
 {
   register int i, j, k, strlen1, strlen2;
   register char *patternP, *strP;
+
   strlen1 = strlen (str);
+
   if (strlen1 < 1)
-    {
-      as_fatal ("Very short instr to option, ie you can't do it on a NULLstr");
-    }
+    as_fatal (_("Very short instr to option, ie you can't do it on a NULLstr"));
+
   for (i = 0; optionP[i].pattern != 0; i++)
     {
       strlen2 = strlen (optionP[i].pattern);
+
       for (j = 0; j < strlen1; j++)
        {
          patternP = optionP[i].pattern;
          strP = &str[j];
+
          for (k = 0; k < strlen2; k++)
            {
              if (*(strP++) != *(patternP++))
                break;
            }
+
          if (k == strlen2)
            {                   /* match */
              *default_map |= optionP[i].or;
@@ -807,51 +832,53 @@ optlist (str, optionP, default_map)
     }
 }
 
-/* search struct for symbols
-   This function is used to get the short integer form of reg names
-   in the instructions lmr, smr, lpr, spr
-   return true if str is found in list */
+/* Search struct for symbols.
+   This function is used to get the short integer form of reg names in
+   the instructions lmr, smr, lpr, spr return true if str is found in
+   list.  */
 
 int
 list_search (str, optionP, default_map)
-     char *str;                        /* the string to match */
-     struct option *optionP;   /* list to search */
-     unsigned long *default_map;/* default pattern and output */
+     char *str;                                /* The string to match.  */
+     struct ns32k_option *optionP;     /* List to search.  */
+     unsigned long *default_map;       /* Default pattern and output.  */
 {
   register int i;
+
   for (i = 0; optionP[i].pattern != 0; i++)
     {
       if (!strncmp (optionP[i].pattern, str, 20))
-       {                       /* use strncmp to be safe */
+       {
+         /* Use strncmp to be safe.  */
          *default_map |= optionP[i].or;
          *default_map &= optionP[i].and;
+
          return -1;
        }
     }
-  as_warn ("No such entry in list. (cpu/mmu register)");
+
+  as_warn (_("No such entry in list. (cpu/mmu register)"));
   return 0;
 }
 
-static segT
+static void
 evaluate_expr (resultP, ptr)
      expressionS *resultP;
      char *ptr;
 {
   register char *tmp_line;
-  register segT segment;
+
   tmp_line = input_line_pointer;
   input_line_pointer = ptr;
-  segment = expression (&exprP);
+  expression (&exprP);
   input_line_pointer = tmp_line;
-  return (segment);
 }
 \f
 /* Convert operands to iif-format and adds bitfields to the opcode.
    Operands are parsed in such an order that the opcode is updated from
    its most significant bit, that is when the operand need to alter the
    opcode.
-   Be carefull not to put to objects in the same iif-slot.
-   */
+   Be carefull not to put to objects in the same iif-slot.  */
 
 void
 encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
@@ -863,32 +890,46 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
      char opcode_bit_ptr;
 {
   register int i, j;
+  char d;
   int pcrel, tmp, b, loop, pcrel_adjust;
+
   for (loop = 0; loop < argc; loop++)
     {
-      i = operandsP[loop << 1] - '1';  /* what operand are we supposed to work on */
+      /* What operand are we supposed to work on.  */
+      i = operandsP[loop << 1] - '1';
       if (i > 3)
-       as_fatal ("Internal consistency error.  check ns32k-opcode.h");
+       as_fatal (_("Internal consistency error.  check ns32k-opcode.h"));
+
       pcrel = 0;
       pcrel_adjust = 0;
       tmp = 0;
-      switch (operandsP[(loop << 1) + 1])
+
+      switch ((d = operandsP[(loop << 1) + 1]))
        {
-       case 'f':               /* operand of sfsr turns out to be a nasty specialcase */
+       case 'f':               /* operand of sfsr turns out to be a nasty
+                                  specialcase */
          opcode_bit_ptr -= 5;
+       case 'Z':               /* float not immediate */
        case 'F':               /* 32 bit float general form */
        case 'L':               /* 64 bit float */
-       case 'Q':               /* quad-word    */
+       case 'I':               /* integer not immediate */
        case 'B':               /* byte  */
        case 'W':               /* word  */
        case 'D':               /* double-word  */
-       case 'A':               /* double-word  gen-address-form ie no regs allowed */
+       case 'A':               /* double-word  gen-address-form ie no regs
+                                  allowed */
          get_addr_mode (argv[i], &addr_modeP);
-         iif.instr_size += addr_modeP.am_size;
+
+         if ((addr_modeP.mode == 20) &&
+            (d == 'I' || d == 'Z' || d == 'A'))
+           as_fatal (d == 'A'? _("Address of immediate operand"):
+                       _("Invalid immediate write operand."));
+
          if (opcode_bit_ptr == desc->opcode_size)
            b = 4;
          else
            b = 6;
+
          for (j = b; j < (b + 2); j++)
            {
              if (addr_modeP.disp[j - b])
@@ -899,30 +940,33 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
                       (unsigned long) addr_modeP.disp[j - b],
                       0,
                       addr_modeP.pcrel,
-                      iif.instr_size - addr_modeP.am_size,     /* this aint used (now) */
+                      iif.instr_size,
                       addr_modeP.im_disp,
                       IND (BRANCH, BYTE),
                       NULL,
-                      addr_modeP.scaled_reg ? addr_modeP.scaled_mode : addr_modeP.mode,
+                      (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
+                       : addr_modeP.mode),
                       0);
                }
            }
+
          opcode_bit_ptr -= 5;
          iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
+
          if (addr_modeP.scaled_reg)
            {
              j = b / 2;
-             IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte, 0, 0, 0, 0, 0, NULL, -1, 0);
+             IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
+                  0, 0, 0, 0, 0, NULL, -1, 0);
            }
          break;
+
        case 'b':               /* multiple instruction disp */
          freeptr++;            /* OVE:this is an useful hack */
-         tmp = (int) sprintf (freeptr,
-                              "((%s-1)*%d)\000",
-                              argv[i], desc->im_size);
+         sprintf (freeptr, "((%s-1)*%d)\000", argv[i], desc->im_size);
          argv[i] = freeptr;
-         freeptr = (char *) tmp;
-         pcrel -= 1;           /* make pcrel 0 inspite of what case 'p': wants */
+         pcrel -= 1;           /* make pcrel 0 inspite of what case 'p':
+                                  wants */
          /* fall thru */
        case 'p':               /* displacement - pc relative addressing */
          pcrel += 1;
@@ -932,7 +976,8 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
               pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
          break;
-       case 'H':               /* sequent-hack: the linker wants a bit set when bsr */
+       case 'H':               /* sequent-hack: the linker wants a bit set
+                                  when bsr */
          pcrel = 1;
          iif.instr_size += suffixP[i] ? suffixP[i] : 4;
          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
@@ -956,7 +1001,7 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
        case 'C':               /* cinv instruction optionslist */
          optlist (argv[i], opt4, &tmp);
          opcode_bit_ptr -= 4;
-         iif.iifP[1].object |= tmp << 15;      /*insert the regtype in opcode */
+         iif.iifP[1].object |= tmp << 15; /* insert the regtype in opcode */
          break;
        case 'S':               /* stringinstruction optionslist */
          optlist (argv[i], opt5, &tmp);
@@ -992,8 +1037,10 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
          IIF (10, 2, 1,
               (unsigned long) argv[i], /* i always 2 here */
               0, 0, 0, 0, 0,
-              bit_fix_new (3, 5, 0, 7, 0, 0, 0),       /* a bit_fix is targeted to the byte */
+              bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* a bit_fix is targeted to
+                                                    the byte */
               -1, 0);
+         break;
        case 'G':
          IIF (11, 2, 42,
               (unsigned long) argv[i], /* i always 3 here */
@@ -1004,8 +1051,9 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
          iif.instr_size += 1;
          b = 2 + i;            /* put the extension byte after opcode */
          IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
+         break;
        default:
-         as_fatal ("Bad opcode-table-option, check in file ns32k-opcode.h");
+         as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
        }
     }
 }
@@ -1014,9 +1062,9 @@ encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
    out: internal structure of instruction
    that has been prepared for direct conversion to fragment(s) and
    fixes in a systematical fashion
-   Return-value = recursive_level
-   */
-/* build iif of one assembly text line */
+   Return-value = recursive_level.    */
+/* Build iif of one assembly text line.  */
+
 int
 parse (line, recursive_level)
      char *line;
@@ -1026,50 +1074,64 @@ parse (line, recursive_level)
   register int i;
   int argc, arg_type;
   char sqr, sep;
-  char suffix[MAX_ARGS], *argv[MAX_ARGS];      /* no more than 4 operands */
+  char suffix[MAX_ARGS], *argv[MAX_ARGS];      /* No more than 4 operands.  */
+
   if (recursive_level <= 0)
-    {                          /* called from md_assemble */
-      for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++);
+    {
+      /* Called from md_assemble.  */
+      for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++)
+       continue;
+
       c = *lineptr;
       *lineptr = '\0';
+
       if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
-       {
-         as_fatal ("No such opcode");
-       }
+       as_fatal (_("No such opcode"));
+
       *lineptr = c;
     }
   else
     {
       lineptr = line;
     }
+
   argc = 0;
+
   if (*desc->operands)
     {
       if (*lineptr++ != '\0')
        {
          sqr = '[';
          sep = ',';
+
          while (*lineptr != '\0')
            {
              if (desc->operands[argc << 1])
                {
                  suffix[argc] = 0;
                  arg_type = desc->operands[(argc << 1) + 1];
+
                  switch (arg_type)
                    {
                    case 'd':
                    case 'b':
                    case 'p':
-                   case 'H':   /* the operand is supposed to be a displacement */
-                     /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
+                   case 'H':
+                     /* The operand is supposed to be a displacement.  */
+                     /* Hackwarning: do not forget to update the 4
+                         cases above when editing ns32k-opcode.h.  */
                      suffix_separator = ':';
                      break;
                    default:
-                     suffix_separator = '\255';        /* if this char occurs we loose */
+                     /* If this char occurs we loose.  */
+                     suffix_separator = '\255';
+                     break;
                    }
-                 suffix[argc] = 0;     /* 0 when no ':' is encountered */
+
+                 suffix[argc] = 0; /* 0 when no ':' is encountered */
                  argv[argc] = freeptr;
                  *freeptr = '\0';
+
                  while ((c = *lineptr) != '\0' && c != sep)
                    {
                      if (c == sqr)
@@ -1085,8 +1147,10 @@ parse (line, recursive_level)
                              sep = ',';
                            }
                        }
+
                      if (c == suffix_separator)
-                       {       /* ':' - label/suffix separator */
+                       {
+                         /* ':' - label/suffix separator.  */
                          switch (lineptr[1])
                            {
                            case 'b':
@@ -1099,58 +1163,64 @@ parse (line, recursive_level)
                              suffix[argc] = 4;
                              break;
                            default:
-                             as_warn ("Bad suffix, defaulting to d");
+                             as_warn (_("Bad suffix, defaulting to d"));
                              suffix[argc] = 4;
                              if (lineptr[1] == '\0' || lineptr[1] == sep)
                                {
                                  lineptr += 1;
                                  continue;
                                }
+                             break;
                            }
+
                          lineptr += 2;
                          continue;
                        }
+
                      *freeptr++ = c;
                      lineptr++;
                    }
+
                  *freeptr++ = '\0';
                  argc += 1;
+
                  if (*lineptr == '\0')
                    continue;
+
                  lineptr += 1;
                }
              else
                {
-                 as_fatal ("Too many operands passed to instruction");
+                 as_fatal (_("Too many operands passed to instruction"));
                }
            }
        }
     }
+
   if (argc != strlen (desc->operands) / 2)
     {
       if (strlen (desc->default_args))
-       {                       /* we can apply default, dont goof */
+       {
+         /* We can apply default, don't goof.  */
          if (parse (desc->default_args, 1) != 1)
-           {                   /* check error in default */
-             as_fatal ("Wrong numbers of operands in default, check ns32k-opcodes.h");
-           }
+           /* Check error in default.  */
+           as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
        }
       else
        {
-         as_fatal ("Wrong number of operands");
+         as_fatal (_("Wrong number of operands"));
        }
-
     }
+
   for (i = 0; i < IIF_ENTRIES; i++)
-    {
-      iif.iifP[i].type = 0;    /* mark all entries as void*/
-    }
+    /* Mark all entries as void.  */
+    iif.iifP[i].type = 0;
 
-  /* build opcode iif-entry */
+  /* Build opcode iif-entry.  */
   iif.instr_size = desc->opcode_size / 8;
   IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
 
-  /* this call encodes operands to iif format */
+  /* This call encodes operands to iif format.  */
   if (argc)
     {
       encode_operand (argc,
@@ -1163,76 +1233,93 @@ parse (line, recursive_level)
   return recursive_level;
 }
 \f
+/* Convert iif to fragments.  From this point we start to dribble with
+   functions in other files than this one.(Except hash.c) So, if it's
+   possible to make an iif for an other CPU, you don't need to know
+   what frags, relax, obstacks, etc is in order to port this
+   assembler. You only need to know if it's possible to reduce your
+   cpu-instruction to iif-format (takes some work) and adopt the other
+   md_? parts according to given instructions Note that iif was
+   invented for the clean ns32k`s architecure.  */
+
+/* GAS for the ns32k has a problem. PC relative displacements are
+   relative to the address of the opcode, not the address of the
+   operand. We used to keep track of the offset between the operand
+   and the opcode in pcrel_adjust for each frag and each fix. However,
+   we get into trouble where there are two or more pc-relative
+   operands and the size of the first one can't be determined. Then in
+   the relax phase, the size of the first operand will change and
+   pcrel_adjust will no longer be correct.  The current solution is
+   keep a pointer to the frag with the opcode in it and the offset in
+   that frag for each frag and each fix. Then, when needed, we can
+   always figure out how far it is between the opcode and the pcrel
+   object.  See also md_pcrel_adjust and md_fix_pcrel_adjust.  For
+   objects not part of an instruction, the pointer to the opcode frag
+   is always zero.  */
 
-/* Convert iif to fragments.
-   From this point we start to dribble with functions in other files than
-   this one.(Except hash.c) So, if it's possible to make an iif for an other
-   CPU, you don't need to know what frags, relax, obstacks, etc is in order
-   to port this assembler. You only need to know if it's possible to reduce
-   your cpu-instruction to iif-format (takes some work) and adopt the other
-   md_? parts according to given instructions
-   Note that iif was invented for the clean ns32k`s architecure.
-   */
 void
 convert_iif ()
 {
   int i;
-  int j;
+  bit_fixS *j;
   fragS *inst_frag;
-  char *inst_offset;
-  char **inst_opcode;
+  unsigned int inst_offset;
+  char *inst_opcode;
   char *memP;
-  segT segment;
   int l;
   int k;
-  int rem_size;                        /* count the remaining bytes of instruction */
   char type;
   char size = 0;
-  int size_so_far = 0;         /* used to calculate pcrel_adjust */
+  int size_so_far;
 
-  rem_size = iif.instr_size;
-  memP = frag_more (iif.instr_size);   /* make sure we have enough bytes for instruction */
+  memP = frag_more (0);
   inst_opcode = memP;
-  inst_offset = (char *) (memP - frag_now->fr_literal);
+  inst_offset = (memP - frag_now->fr_literal);
   inst_frag = frag_now;
+
   for (i = 0; i < IIF_ENTRIES; i++)
     {
       if (type = iif.iifP[i].type)
-       {                       /* the object exist, so handle it */
+       {
+         /* The object exist, so handle it.  */
          switch (size = iif.iifP[i].size)
            {
            case 42:
-             size = 0;         /* it's a bitfix that operates on an existing object*/
+             size = 0;
+             /* It's a bitfix that operates on an existing object.  */
              if (iif.iifP[i].bit_fixP->fx_bit_base)
-               {               /* expand fx_bit_base to point at opcode */
-                 iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
-               }
+               /* Expand fx_bit_base to point at opcode.  */
+               iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
+             /* Fall through.  */
+
            case 8:             /* bignum or doublefloat */
-             memset (memP, '\0', 8);
            case 1:
            case 2:
            case 3:
-           case 4:             /* the final size in objectmemory is known */
-             j = (unsigned long) iif.iifP[i].bit_fixP;
+           case 4:
+             /* The final size in objectmemory is known.  */
+             memP = frag_more (size);
+             j = iif.iifP[i].bit_fixP;
+
              switch (type)
                {
-               case 1: /* the object is pure binary */
+               case 1: /* The object is pure binary.  */
                  if (j || iif.iifP[i].pcrel)
                    {
                      fix_new_ns32k (frag_now,
                                     (long) (memP - frag_now->fr_literal),
                                     size,
                                     0,
-                                    0,
                                     iif.iifP[i].object,
                                     iif.iifP[i].pcrel,
-                                    (char) size_so_far,        /*iif.iifP[i].pcrel_adjust,*/
                                     iif.iifP[i].im_disp,
                                     j,
-                                    iif.iifP[i].bsr);  /* sequent hack */
+                                    iif.iifP[i].bsr,   /* sequent hack */
+                                    inst_frag, inst_offset);
                    }
                  else
-                   {           /* good, just put them bytes out */
+                   {
+                     /* Good, just put them bytes out.  */
                      switch (iif.iifP[i].im_disp)
                        {
                        case 0:
@@ -1242,77 +1329,92 @@ convert_iif ()
                          md_number_to_disp (memP, iif.iifP[i].object, size);
                          break;
                        default:
-                         as_fatal ("iif convert internal pcrel/binary");
+                         as_fatal (_("iif convert internal pcrel/binary"));
                        }
                    }
-                 memP += size;
-                 rem_size -= size;
                  break;
-               case 2: /* the object is a pointer at an expression, so unpack
-                                          it, note that bignums may result from the expression
-                                          */
-                 if ((segment = evaluate_expr (&exprP, (char *) iif.iifP[i].object)) == SEG_BIG || size == 8)
+
+               case 2:
+                 /* The object is a pointer at an expression, so
+                     unpack it, note that bignums may result from the
+                     expression.  */
+                 evaluate_expr (&exprP, (char *) iif.iifP[i].object);
+                 if (exprP.X_op == O_big || size == 8)
                    {
                      if ((k = exprP.X_add_number) > 0)
-                       {       /* we have a bignum ie a quad */
-                         /* this can only happens in a long suffixed instruction */
-                         memset (memP, '\0', size);    /* size normally is 8 */
+                       {
+                         /* We have a bignum ie a quad. This can only
+                             happens in a long suffixed instruction.  */
                          if (k * 2 > size)
-                           as_warn ("Bignum too big for long");
+                           as_warn (_("Bignum too big for long"));
+
                          if (k == 3)
                            memP += 2;
+
                          for (l = 0; k > 0; k--, l += 2)
                            {
-                             md_number_to_chars (memP + l, generic_bignum[l >> 1], sizeof (LITTLENUM_TYPE));
+                             md_number_to_chars (memP + l,
+                                                 generic_bignum[l >> 1],
+                                                 sizeof (LITTLENUM_TYPE));
                            }
                        }
                      else
-                       {       /* flonum */
+                       {
+                         /* flonum.  */
                          LITTLENUM_TYPE words[4];
 
                          switch (size)
                            {
                            case 4:
                              gen_to_words (words, 2, 8);
-                             md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE));
-                             md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE));
+                             md_number_to_imm (memP, (long) words[0],
+                                               sizeof (LITTLENUM_TYPE));
+                             md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
+                                               (long) words[1],
+                                               sizeof (LITTLENUM_TYPE));
                              break;
                            case 8:
                              gen_to_words (words, 4, 11);
-                             md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE));
-                             md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE));
-                             md_number_to_imm (memP + 2 * sizeof (LITTLENUM_TYPE), (long) words[2], sizeof (LITTLENUM_TYPE));
-                             md_number_to_imm (memP + 3 * sizeof (LITTLENUM_TYPE), (long) words[3], sizeof (LITTLENUM_TYPE));
+                             md_number_to_imm (memP, (long) words[0],
+                                               sizeof (LITTLENUM_TYPE));
+                             md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
+                                               (long) words[1],
+                                               sizeof (LITTLENUM_TYPE));
+                             md_number_to_imm ((memP + 2
+                                                * sizeof (LITTLENUM_TYPE)),
+                                               (long) words[2],
+                                               sizeof (LITTLENUM_TYPE));
+                             md_number_to_imm ((memP + 3
+                                                * sizeof (LITTLENUM_TYPE)),
+                                               (long) words[3],
+                                               sizeof (LITTLENUM_TYPE));
                              break;
                            }
                        }
-                     memP += size;
-                     rem_size -= size;
                      break;
                    }
                  if (j ||
                      exprP.X_add_symbol ||
-                     exprP.X_subtract_symbol ||
+                     exprP.X_op_symbol ||
                      iif.iifP[i].pcrel)
-                   {           /* fixit */
-                     /* the expression was undefined due to an undefined label */
-                     /* create a fix so we can fix the object later */
+                   {
+                     /* The expression was undefined due to an
+                         undefined label. Create a fix so we can fix
+                         the object later.  */
                      exprP.X_add_number += iif.iifP[i].object_adjust;
-                     fix_new_ns32k (frag_now,
-                                    (long) (memP - frag_now->fr_literal),
-                                    size,
-                                    exprP.X_add_symbol,
-                                    exprP.X_subtract_symbol,
-                                    exprP.X_add_number,
-                                    iif.iifP[i].pcrel,
-                                    (char) size_so_far,        /*iif.iifP[i].pcrel_adjust,*/
-                                    iif.iifP[i].im_disp,
-                                    j,
-                                    iif.iifP[i].bsr);  /* sequent hack */
-
+                     fix_new_ns32k_exp (frag_now,
+                                        (long) (memP - frag_now->fr_literal),
+                                        size,
+                                        &exprP,
+                                        iif.iifP[i].pcrel,
+                                        iif.iifP[i].im_disp,
+                                        j,
+                                        iif.iifP[i].bsr,
+                                        inst_frag, inst_offset);
                    }
                  else
-                   {           /* good, just put them bytes out */
+                   {
+                     /* Good, just put them bytes out.  */
                      switch (iif.iifP[i].im_disp)
                        {
                        case 0:
@@ -1322,172 +1424,220 @@ convert_iif ()
                          md_number_to_disp (memP, exprP.X_add_number, size);
                          break;
                        default:
-                         as_fatal ("iif convert internal pcrel/pointer");
+                         as_fatal (_("iif convert internal pcrel/pointer"));
                        }
                    }
-                 memP += size;
-                 rem_size -= size;
                  break;
                default:
-                 as_fatal ("Internal logic error in iif.iifP[n].type");
+                 as_fatal (_("Internal logic error in iif.iifP[n].type"));
                }
              break;
-           case 0:             /* To bad, the object may be undefined as far as its final
-                                           nsize in object memory is concerned. The size of the object
-                                           in objectmemory is not explicitly given.
-                                           If the object is defined its length can be determined and
-                                           a fix can replace the frag.
-                                           */
+
+           case 0:
+             /* Too bad, the object may be undefined as far as its
+                final nsize in object memory is concerned.  The size
+                of the object in objectmemory is not explicitly
+                given.  If the object is defined its length can be
+                determined and a fix can replace the frag.  */
              {
-               int temp;
-               segment = evaluate_expr (&exprP, (char *) iif.iifP[i].object);
-               if ((exprP.X_add_symbol || exprP.X_subtract_symbol) &&
+               evaluate_expr (&exprP, (char *) iif.iifP[i].object);
+
+               if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
                    !iif.iifP[i].pcrel)
-                 {             /* OVE: hack, clamp to 4 bytes */
-                   size = 4;   /* we dont wan't to frag this, use 4 so it reaches */
-                   fix_new_ns32k (frag_now,
-                                  (long) (memP - frag_now->fr_literal),
-                                  size,
-                                  exprP.X_add_symbol,
-                                  exprP.X_subtract_symbol,
-                                  exprP.X_add_number,
-                                  0,   /* never iif.iifP[i].pcrel, */
-                                  (char) size_so_far,  /*iif.iifP[i].pcrel_adjust,*/
-                                  1,   /* always iif.iifP[i].im_disp, */
-                                  0, 0);
-                   memP += size;
-                   rem_size -= 4;
-                   break;      /* exit this absolute hack */
+                 {
+                   /* Size is unknown until link time so have to
+                       allow 4 bytes.  */
+                   size = 4;
+                   memP = frag_more (size);
+                   fix_new_ns32k_exp (frag_now,
+                                      (long) (memP - frag_now->fr_literal),
+                                      size,
+                                      &exprP,
+                                      0, /* never iif.iifP[i].pcrel, */
+                                      1, /* always iif.iifP[i].im_disp */
+                                      (bit_fixS *) 0, 0,
+                                      inst_frag,
+                                      inst_offset);
+                   break;              /* exit this absolute hack */
                  }
 
-               if (exprP.X_add_symbol || exprP.X_subtract_symbol)
-                 {             /* frag it */
-                   if (exprP.X_subtract_symbol)
-                     {         /* We cant relax this case */
-                       as_fatal ("Can't relax difference");
+               if (exprP.X_add_symbol || exprP.X_op_symbol)
+                 {
+                   /* Frag it.  */
+                   if (exprP.X_op_symbol)
+                     {
+                       /* We cant relax this case.  */
+                       as_fatal (_("Can't relax difference"));
                      }
                    else
                      {
-                       /* at this stage we must undo some of the effect caused
-                                                          by frag_more, ie we must make sure that frag_var causes
-                                                          frag_new to creat a valid fix-size in the frag it`s closing
-                                                          */
-                       temp = -(rem_size - 4);
-                       obstack_blank_fast (&frags, temp);
-                       /* we rewind none, some or all of the requested size we
-                                                          requested by the first frag_more for this iif chunk.
-                                                          Note: that we allocate 4 bytes to an object we NOT YET
-                                                          know the size of, thus rem_size-4.
-                                                          */
-                       (void) frag_variant (rs_machine_dependent,
-                                            4,
-                                            0,
-                                            IND (BRANCH, UNDEF),       /* expecting the worst */
-                                            exprP.X_add_symbol,
-                                            exprP.X_add_number,
-                                            (char *) inst_opcode,
-                                            (char) size_so_far,        /*iif.iifP[i].pcrel_adjust);*/
-                                            iif.iifP[i].bsr);  /* sequent linker hack */
-                       rem_size -= 4;
-                       if (rem_size > 0)
-                         {
-                           memP = frag_more (rem_size);
-                         }
+                       /* Size is not important.  This gets fixed by
+                          relax, but we assume 0 in what follows.  */
+                       memP = frag_more (4); /* Max size.  */
+                       size = 0;
+
+                       {
+                         fragS *old_frag = frag_now;
+                         frag_variant (rs_machine_dependent,
+                                       4, /* Max size.  */
+                                       0, /* Size.  */
+                                       IND (BRANCH, UNDEF), /* Expecting
+                                                                the worst.  */
+                                       exprP.X_add_symbol,
+                                       exprP.X_add_number,
+                                       inst_opcode);
+                         frag_opcode_frag (old_frag) = inst_frag;
+                         frag_opcode_offset (old_frag) = inst_offset;
+                         frag_bsr (old_frag) = iif.iifP[i].bsr;
+                       }
                      }
                  }
                else
-                 {             /* Double work, this is done in md_number_to_disp */
-                   /*        exprP.X_add_number; what was this supposed to be?
-                                                             xoxorich. */
+                 {
+                   /* This duplicates code in md_number_to_disp.  */
                    if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
                      {
                        size = 1;
                      }
                    else
                      {
-                       if (-8192 <= exprP.X_add_number && exprP.X_add_number <= 8191)
+                       if (-8192 <= exprP.X_add_number
+                           && exprP.X_add_number <= 8191)
                          {
                            size = 2;
                          }
                        else
                          {
-                           if (-0x1f000000 <= exprP.X_add_number &&
-                               exprP.X_add_number <= 0x1fffffff)
-                             /* if (-0x40000000<=exprP.X_add_number &&
-                                                                      exprP.X_add_number<=0x3fffffff) */
+                           if (-0x20000000 <= exprP.X_add_number
+                               && exprP.X_add_number<=0x1fffffff)
                              {
                                size = 4;
                              }
                            else
                              {
-                               as_warn ("Displacement to large for :d");
+                               as_warn (_("Displacement to large for :d"));
                                size = 4;
                              }
                          }
                      }
-                   /* rewind the bytes not used */
-                   temp = -(4 - size);
+
+                   memP = frag_more (size);
                    md_number_to_disp (memP, exprP.X_add_number, size);
-                   obstack_blank_fast (&frags, temp);
-                   memP += size;
-                   rem_size -= 4;      /* we allocated this amount */
                  }
              }
              break;
+
            default:
-             as_fatal ("Internal logic error in iif.iifP[].type");
+             as_fatal (_("Internal logic error in iif.iifP[].type"));
            }
-         size_so_far += size;
-         size = 0;
        }
     }
 }
 \f
+#ifdef BFD_ASSEMBLER
+/* This functionality should really be in the bfd library.  */
+static bfd_reloc_code_real_type
+reloc (int size, int pcrel, int type)
+{
+  int length, index;
+  bfd_reloc_code_real_type relocs[] =
+  {
+    BFD_RELOC_NS32K_IMM_8,
+    BFD_RELOC_NS32K_IMM_16,
+    BFD_RELOC_NS32K_IMM_32,
+    BFD_RELOC_NS32K_IMM_8_PCREL,
+    BFD_RELOC_NS32K_IMM_16_PCREL,
+    BFD_RELOC_NS32K_IMM_32_PCREL,
+
+    /* ns32k displacements.  */
+    BFD_RELOC_NS32K_DISP_8,
+    BFD_RELOC_NS32K_DISP_16,
+    BFD_RELOC_NS32K_DISP_32,
+    BFD_RELOC_NS32K_DISP_8_PCREL,
+    BFD_RELOC_NS32K_DISP_16_PCREL,
+    BFD_RELOC_NS32K_DISP_32_PCREL,
+
+    /* Normal 2's complement.  */
+    BFD_RELOC_8,
+    BFD_RELOC_16,
+    BFD_RELOC_32,
+    BFD_RELOC_8_PCREL,
+    BFD_RELOC_16_PCREL,
+    BFD_RELOC_32_PCREL
+  };
+
+  switch (size)
+    {
+    case 1:
+      length = 0;
+      break;
+    case 2:
+      length = 1;
+      break;
+    case 4:
+      length = 2;
+      break;
+    default:
+      length = -1;
+      break;
+    }
+
+  index = length + 3 * pcrel + 6 * type;
+
+  if (index >= 0 && index < sizeof (relocs) / sizeof (relocs[0]))
+    return relocs[index];
+
+  if (pcrel)
+    as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
+           size, type);
+  else
+    as_bad (_("Can not do %d byte relocation for storage type %d"),
+           size, type);
+
+  return BFD_RELOC_NONE;
+
+}
+#endif
+
 void
 md_assemble (line)
      char *line;
 {
   freeptr = freeptr_static;
-  parse (line, 0);             /* explode line to more fix form in iif */
-  convert_iif ();              /* convert iif to frags, fix's etc */
+  parse (line, 0);             /* Explode line to more fix form in iif.  */
+  convert_iif ();              /* Convert iif to frags, fix's etc.  */
 #ifdef SHOW_NUM
   printf (" \t\t\t%s\n", line);
 #endif
 }
 
-
 void
 md_begin ()
 {
-  /* build a hashtable of the instructions */
-  register const struct ns32k_opcode *ptr;
-  register char *stat;
+  /* Build a hashtable of the instructions.  */
+  const struct ns32k_opcode *ptr;
+  const char *stat;
   inst_hash_handle = hash_new ();
+
   for (ptr = ns32k_opcodes; ptr < endop; ptr++)
     {
-      if (*(stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
-       {
-         as_fatal ("Can't hash %s: %s", ptr->name, stat);      /*fatal*/
-         exit (0);
-       }
+      if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
+       /* Fatal.  */
+       as_fatal (_("Can't hash %s: %s"), ptr->name, stat);
     }
-  freeptr_static = (char *) malloc (PRIVATE_SIZE);     /* some private space please! */
-}
-
 
-void
-md_end ()
-{
-  free (freeptr_static);
+  /* Some private space please!  */
+  freeptr_static = (char *) malloc (PRIVATE_SIZE);
 }
 
-/* Must be equal to MAX_PRECISON in atof-ieee.c */
+/* Must be equal to MAX_PRECISON in atof-ieee.c */
 #define MAX_LITTLENUMS 6
 
-/* Turn the string pointed to by litP into a floating point constant of type
-   type, and emit the appropriate bytes.  The number of LITTLENUMS emitted
-   is stored in *sizeP .  An error message is returned, or NULL on OK.
-   */
+/* Turn the string pointed to by litP into a floating point constant
+   of type TYPE, and emit the appropriate bytes.  The number of
+   LITTLENUMS emitted is stored in *SIZEP.  An error message is
+   returned, or NULL on OK.  */
+
 char *
 md_atof (type, litP, sizeP)
      char type;
@@ -1510,22 +1660,25 @@ md_atof (type, litP, sizeP)
       break;
     default:
       *sizeP = 0;
-      return "Bad call to MD_ATOF()";
+      return _("Bad call to MD_ATOF()");
     }
-  t = atof_ns32k (input_line_pointer, type, words);
+
+  t = atof_ieee (input_line_pointer, type, words);
   if (t)
     input_line_pointer = t;
 
   *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
   for (wordP = words + prec; prec--;)
     {
       md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
       litP += sizeof (LITTLENUM_TYPE);
     }
-  return "";                   /* Someone should teach Dean about null pointers */
+
+  return 0;
 }
 \f
-/* Convert number to chars in correct order */
+/* Convert number to chars in correct order */
 
 void
 md_number_to_chars (buf, value, nbytes)
@@ -1533,29 +1686,21 @@ md_number_to_chars (buf, value, nbytes)
      valueT value;
      int nbytes;
 {
-  while (nbytes--)
-    {
-#ifdef SHOW_NUM
-      printf ("%x ", value & 0xff);
-#endif
-      *buf++ = value;          /* Lint wants & MASK_CHAR. */
-      value >>= BITS_PER_CHAR;
-    }
-}                              /* md_number_to_chars() */
-
+  number_to_chars_littleendian (buf, value, nbytes);
+}
 
-/* This is a variant of md_numbers_to_chars. The reason for its' existence
-   is the fact that ns32k uses Huffman coded displacements. This implies
-   that the bit order is reversed in displacements and that they are prefixed
-   with a size-tag.
+/* This is a variant of md_numbers_to_chars. The reason for its'
+   existence is the fact that ns32k uses Huffman coded
+   displacements. This implies that the bit order is reversed in
+   displacements and that they are prefixed with a size-tag.
 
    binary: msb -> lsb
    0xxxxxxx                            byte
    10xxxxxx xxxxxxxx                   word
    11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
 
-   This must be taken care of and we do it here!
-   */
+   This must be taken care of and we do it here!  */
+
 static void
 md_number_to_disp (buf, val, n)
      char *buf;
@@ -1566,7 +1711,7 @@ md_number_to_disp (buf, val, n)
     {
     case 1:
       if (val < -64 || val > 63)
-       as_warn ("Byte displacement out of range.  line number not valid");
+       as_warn (_("Byte displacement out of range.  line number not valid"));
       val &= 0x7f;
 #ifdef SHOW_NUM
       printf ("%x ", val & 0xff);
@@ -1575,7 +1720,7 @@ md_number_to_disp (buf, val, n)
       break;
     case 2:
       if (val < -8192 || val > 8191)
-       as_warn ("Word displacement out of range.  line number not valid");
+       as_warn (_("Word displacement out of range.  line number not valid"));
       val &= 0x3fff;
       val |= 0x8000;
 #ifdef SHOW_NUM
@@ -1588,9 +1733,8 @@ md_number_to_disp (buf, val, n)
       *buf++ = val;
       break;
     case 4:
-      if (val < -0x1f000000 || val >= 0x20000000)
-       /* if (val < -0x20000000 || val >= 0x20000000) */
-       as_warn ("Double word displacement out of range");
+      if (val < -0x20000000 || val >= 0x20000000)
+       as_warn (_("Double word displacement out of range"));
       val |= 0xc0000000;
 #ifdef SHOW_NUM
       printf ("%x ", val >> 24 & 0xff);
@@ -1610,7 +1754,8 @@ md_number_to_disp (buf, val, n)
       *buf++ = val;
       break;
     default:
-      as_fatal ("Internal logic error.  line %s, file \"%s\"", __LINE__, __FILE__);
+      as_fatal (_("Internal logic error.  line %s, file \"%s\""),
+               __LINE__, __FILE__);
     }
 }
 
@@ -1657,83 +1802,13 @@ md_number_to_imm (buf, val, n)
       *buf++ = val;
       break;
     default:
-      as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__);
+      as_fatal (_("Internal logic error. line %s, file \"%s\""),
+               __LINE__, __FILE__);
     }
 }
 
-/* Translate internal representation of relocation info into target format.
-
-   OVE: on a ns32k the twiddling continues at an even deeper level
-   here we have to distinguish between displacements and immediates.
-
-   The sequent has a bit for this. It also has a bit for relocobjects that
-   points at the target for a bsr (BranchSubRoutine) !?!?!?!
-
-   This md_ri.... is tailored for sequent.
-   */
-
-#ifdef comment
-void
-md_ri_to_chars (the_bytes, ri)
-     char *the_bytes;
-     struct reloc_info_generic *ri;
-{
-  if (ri->r_bsr)
-    {
-      ri->r_pcrel = 0;
-    }                          /* sequent seems to want this */
-  md_number_to_chars (the_bytes, ri->r_address, sizeof (ri->r_address));
-  md_number_to_chars (the_bytes + 4, ((long) (ri->r_symbolnum)
-                                     | (long) (ri->r_pcrel << 24)
-                                     | (long) (ri->r_length << 25)
-                                     | (long) (ri->r_extern << 27)
-                                     | (long) (ri->r_bsr << 28)
-                                     | (long) (ri->r_disp << 29)),
-                     4);
-  /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
-}
-
-#endif /* comment */
-
-#ifdef OBJ_AOUT
-void
-tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
-     char *where;
-     struct fix *fixP;
-     relax_addressT segment_address_in_file;
-{
-  /*
-   * In: length of relocation (or of address) in chars: 1, 2 or 4.
-   * Out: GNU LD relocation length code: 0, 1, or 2.
-   */
-
-  static unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
-  long r_symbolnum;
-
-  know (fixP->fx_addsy != NULL);
-
-  md_number_to_chars (where,
-       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
-                     4);
-
-  r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
-                ? S_GET_TYPE (fixP->fx_addsy)
-                : fixP->fx_addsy->sy_number);
-
-  md_number_to_chars (where,
-                     ((long) (r_symbolnum)
-                      | (long) (fixP->fx_pcrel << 24)
-                      | (long) (nbytes_r_length[fixP->fx_size] << 25)
-                      | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
-                      | (long) (fixP->fx_bsr << 28)
-                      | (long) (fixP->fx_im_disp << 29)),
-                     4);
-}
-
-#endif /* OBJ_AOUT */
-
-/* fast bitfiddling support */
-/* mask used to zero bitfield before oring in the true field */
+/* Fast bitfiddling support.  */
+/* Mask used to zero bitfield before oring in the true field.  */
 
 static unsigned long l_mask[] =
 {
@@ -1762,8 +1837,7 @@ static unsigned long r_mask[] =
    This routine is written for modification of the first 4 bytes pointed
    to by buf, to yield speed.
    The ifdef stuff is for selection between a ns32k-dependent routine
-   and a general version. (My advice: use the general version!)
-   */
+   and a general version. (My advice: use the general version!).  */
 
 static void
 md_number_to_field (buf, val, field_ptr)
@@ -1783,28 +1857,26 @@ md_number_to_field (buf, val, field_ptr)
     {
 #ifdef ENDIAN
       if (field_ptr->fx_bit_base)
-       {                       /* override buf */
-         mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
-       }
+       /* Override buf.  */
+       mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
       else
-       {
-         mem_ptr = (unsigned long *) buf;
-       }
+       mem_ptr = (unsigned long *) buf;
+
+      mem_ptr = ((unsigned long *)
+                ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
 #else
       if (field_ptr->fx_bit_base)
-       {                       /* override buf */
-         mem_ptr = (char *) field_ptr->fx_bit_base;
-       }
+       mem_ptr = (char *) field_ptr->fx_bit_base;
       else
-       {
-         mem_ptr = buf;
-       }
-#endif
+       mem_ptr = buf;
+
       mem_ptr += field_ptr->fx_bit_base_adj;
-#ifdef ENDIAN                  /* we have a nice ns32k machine with lowbyte at low-physical mem */
+#endif
+#ifdef ENDIAN
+      /* We have a nice ns32k machine with lowbyte at low-physical mem.  */
       object = *mem_ptr;       /* get some bytes */
 #else /* OVE Goof! the machine is a m68k or dito */
-      /* That takes more byte fiddling */
+      /* That takes more byte fiddling */
       object = 0;
       object |= mem_ptr[3] & 0xff;
       object <<= 8;
@@ -1834,10 +1906,47 @@ md_number_to_field (buf, val, field_ptr)
     }
   else
     {
-      as_warn ("Bit field out of range");
+      as_warn (_("Bit field out of range"));
     }
 }
 
+int
+md_pcrel_adjust (fragP)
+     fragS *fragP;
+{
+  fragS *opcode_frag;
+  addressT opcode_address;
+  unsigned int offset;
+
+  opcode_frag = frag_opcode_frag (fragP);
+  if (opcode_frag == 0)
+    return 0;
+
+  offset = frag_opcode_offset (fragP);
+  opcode_address = offset + opcode_frag->fr_address;
+
+  return fragP->fr_address + fragP->fr_fix - opcode_address;
+}
+
+int
+md_fix_pcrel_adjust (fixP)
+     fixS *fixP;
+{
+  fragS *fragP = fixP->fx_frag;
+  fragS *opcode_frag;
+  addressT opcode_address;
+  unsigned int offset;
+
+  opcode_frag = fix_opcode_frag (fixP);
+  if (opcode_frag == 0)
+    return 0;
+
+  offset = fix_opcode_offset (fixP);
+  opcode_address = offset + opcode_frag->fr_address;
+
+  return fixP->fx_where + fixP->fx_frag->fr_address - opcode_address;
+}
+
 /* Apply a fixS (fixup of an instruction or data that we didn't have
    enough info to complete immediately) to the data in a frag.
 
@@ -1846,42 +1955,59 @@ md_number_to_field (buf, val, field_ptr)
    They all get called from here.  */
 
 void
-md_apply_fix (fixP, val)
+md_apply_fix3 (fixP, valP, seg)
      fixS *fixP;
-     long val;
+     valueT * valP;
+     segT seg ATTRIBUTE_UNUSED;
 {
+  long val = * (long *) valP;
+  fragS *fragP = fixP->fx_frag;
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
 
-  if (fixP->fx_bit_fixP)
-    {                          /* Bitfields to fix, sigh */
-      md_number_to_field (buf, val, fixP->fx_bit_fixP);
-    }
-  else
-    switch (fixP->fx_im_disp)
-      {
+  if (fix_bit_fixP (fixP))
+    /* Bitfields to fix, sigh.  */
+    md_number_to_field (buf, val, fix_bit_fixP (fixP));
 
-      case 0:                  /* Immediate field */
-       md_number_to_imm (buf, val, fixP->fx_size);
-       break;
+  else switch (fix_im_disp (fixP))
+    {
+    case 0:
+      /* Immediate field.  */
+      md_number_to_imm (buf, val, fixP->fx_size);
+      break;
 
-      case 1:                  /* Displacement field */
-       md_number_to_disp (buf,
-                        fixP->fx_pcrel ? val + fixP->fx_pcrel_adjust : val,
-                          fixP->fx_size);
-       break;
+    case 1:
+      /* Displacement field.  */
+      /* Calculate offset */
+      md_number_to_disp (buf,
+                        (fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
+                         : val), fixP->fx_size);
+      break;
 
-      case 2:                  /* Pointer in a data object */
-       md_number_to_chars (buf, val, fixP->fx_size);
-       break;
-      }
+    case 2:
+      /* Pointer in a data object.  */
+      md_number_to_chars (buf, val, fixP->fx_size);
+      break;
+    }
+
+  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+    fixP->fx_done = 1;
 }
 \f
 /* Convert a relaxed displacement to ditto in final output */
 
+#ifndef BFD_ASSEMBLER
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, sec, fragP)
      object_headers *headers;
+     segT sec;
      register fragS *fragP;
+#else
+void
+md_convert_frag (abfd, sec, fragP)
+     bfd *abfd;
+     segT sec;
+     register fragS *fragP;
+#endif
 {
   long disp;
   long ext = 0;
@@ -1889,13 +2015,9 @@ md_convert_frag (headers, fragP)
   /* Address in gas core of the place to store the displacement.  */
   register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
   /* Address in object code of the displacement.  */
-  register int object_address = fragP->fr_fix + fragP->fr_address;
+  int object_address;
 
-  know (fragP->fr_symbol);
-
-  /* The displacement of the address, from current location.  */
-  disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
-  disp += fragP->fr_pcrel_adjust;
+  fragS *opcode_frag;
 
   switch (fragP->fr_subtype)
     {
@@ -1909,66 +2031,71 @@ md_convert_frag (headers, fragP)
       ext = 4;
       break;
     }
-  if (ext)
-    {
-      md_number_to_disp (buffer_address, (long) disp, (int) ext);
-      fragP->fr_fix += ext;
-    }
-}
 
+  if (ext == 0)
+    return;
+
+  know (fragP->fr_symbol);
+
+  object_address = fragP->fr_fix + fragP->fr_address;
+
+  /* The displacement of the address, from current location.  */
+  disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
+  disp += md_pcrel_adjust (fragP);
 
+  md_number_to_disp (buffer_address, (long) disp, (int) ext);
+  fragP->fr_fix += ext;
+}
 
 /* This function returns the estimated size a variable object will occupy,
    one can say that we tries to guess the size of the objects before we
-   actually know it */
+   actually know it */
 
 int
 md_estimate_size_before_relax (fragP, segment)
      register fragS *fragP;
      segT segment;
 {
-  int old_fix;
-  old_fix = fragP->fr_fix;
-  switch (fragP->fr_subtype)
+  if (fragP->fr_subtype == IND (BRANCH, UNDEF))
     {
-    case IND (BRANCH, UNDEF):
-      if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+      if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
        {
-         /* the symbol has been assigned a value */
-         fragP->fr_subtype = IND (BRANCH, BYTE);
-       }
-      else
-       {
-         /* we don't relax symbols defined in an other segment
-                      the thing to do is to assume the object will occupy 4 bytes */
+         /* We don't relax symbols defined in another segment.  The
+            thing to do is to assume the object will occupy 4 bytes.  */
          fix_new_ns32k (fragP,
                         (int) (fragP->fr_fix),
                         4,
                         fragP->fr_symbol,
-                        (symbolS *) 0,
                         fragP->fr_offset,
                         1,
-                        fragP->fr_pcrel_adjust,
                         1,
                         0,
-                        fragP->fr_bsr);        /*sequent hack */
+                        frag_bsr(fragP), /*sequent hack */
+                        frag_opcode_frag (fragP),
+                        frag_opcode_offset (fragP));
          fragP->fr_fix += 4;
-         /* fragP->fr_opcode[1]=0xff; */
+#if 0
+         fragP->fr_opcode[1] = 0xff;
+#endif
          frag_wane (fragP);
-         break;
+         return 4;
        }
-    case IND (BRANCH, BYTE):
-      fragP->fr_var += 1;
-      break;
-    default:
-      break;
+
+      /* Relaxable case.  Set up the initial guess for the variable
+        part of the frag.  */
+      fragP->fr_subtype = IND (BRANCH, BYTE);
     }
-  return fragP->fr_var + fragP->fr_fix - old_fix;
+
+  if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
+    abort ();
+
+  /* Return the size of the variable part of the frag.  */
+  return md_relax_table[fragP->fr_subtype].rlx_length;
 }
 
 int md_short_jump_size = 3;
 int md_long_jump_size = 5;
-const int md_reloc_size = 8;   /* Size of relocation record */
+const int md_reloc_size = 8;   /* Size of relocation record */
 
 void
 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
@@ -1994,61 +2121,74 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
   valueT offset;
 
   offset = to_addr - from_addr;
-  md_number_to_chars (ptr, (valueT) 0xEA, 2);
-  md_number_to_disp (ptr + 2, (valueT) offset, 4);
+  md_number_to_chars (ptr, (valueT) 0xEA, 1);
+  md_number_to_disp (ptr + 1, (valueT) offset, 4);
 }
 \f
-/* JF this is a new function to parse machine-dep options */
+CONST char *md_shortopts = "m:";
+
+struct option md_longopts[] =
+{
+  {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
 int
-md_parse_option (argP, cntP, vecP)
-     char **argP;
-     int *cntP;
-     char ***vecP;
+md_parse_option (c, arg)
+     int c;
+     char *arg;
 {
-  switch (**argP)
+  switch (c)
     {
     case 'm':
-      (*argP)++;
-
-      if (!strcmp (*argP, "32032"))
+      if (!strcmp (arg, "32032"))
        {
          cpureg = cpureg_032;
          mmureg = mmureg_032;
        }
-      else if (!strcmp (*argP, "32532"))
+      else if (!strcmp (arg, "32532"))
        {
          cpureg = cpureg_532;
          mmureg = mmureg_532;
        }
       else
-       as_warn ("Unknown -m option ignored");
-
-      while (**argP)
-       (*argP)++;
+       {
+         as_bad (_("invalid architecture option -m%s"), arg);
+         return 0;
+       }
       break;
 
     default:
       return 0;
     }
+
   return 1;
 }
+
+void
+md_show_usage (stream)
+     FILE *stream;
+{
+  fprintf (stream, _("\
+NS32K options:\n\
+-m32032 | -m32532      select variant of NS32K architecture\n"));
+}
 \f
-/*
- *                     bit_fix_new()
- *
- * Create a bit_fixS in obstack 'notes'.
- * This struct is used to profile the normal fix. If the bit_fixP is a
- * valid pointer (not NULL) the bit_fix data will be used to format the fix.
- */
+/* Create a bit_fixS in obstack 'notes'.
+   This struct is used to profile the normal fix. If the bit_fixP is a
+   valid pointer (not NULL) the bit_fix data will be used to format
+   the fix.  */
+
 bit_fixS *
 bit_fix_new (size, offset, min, max, add, base_type, base_adj)
      char size;                        /* Length of bitfield           */
      char offset;              /* Bit offset to bitfield       */
-     long base_type;           /* 0 or 1, if 1 it's exploded to opcode ptr */
-     long base_adj;
      long min;                 /* Signextended min for bitfield */
      long max;                 /* Signextended max for bitfield */
      long add;                 /* Add mask, used for huffman prefix */
+     long base_type;           /* 0 or 1, if 1 it's exploded to opcode ptr */
+     long base_adj;
 {
   register bit_fixS *bit_fixP;
 
@@ -2066,29 +2206,70 @@ bit_fix_new (size, offset, min, max, add, base_type, base_adj)
 }
 
 void
-fix_new_ns32k (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
-              pcrel_adjust, im_disp, bit_fixP, bsr)
+fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
+              im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
      fragS *frag;              /* Which frag? */
      int where;                        /* Where in that frag? */
-     int size;                 /* 1, 2  or 4 usually. */
-     symbolS *add_symbol;      /* X_add_symbol. */
-     symbolS *sub_symbol;      /* X_subtract_symbol. */
-     long offset;              /* X_add_number. */
-     int pcrel;                        /* TRUE if PC-relative relocation. */
-     char pcrel_adjust;                /* not zero if adjustment of pcrel offset is needed */
-     char im_disp;             /* true if the value to write is a displacement */
-     bit_fixS *bit_fixP;       /* pointer at struct of bit_fix's, ignored if NULL */
-     char bsr;                 /* sequent-linker-hack: 1 when relocobject is a bsr */
+     int size;                 /* 1, 2  or 4 usually.  */
+     symbolS *add_symbol;      /* X_add_symbol.  */
+     long offset;              /* X_add_number.  */
+     int pcrel;                        /* TRUE if PC-relative relocation.  */
+     char im_disp;             /* true if the value to write is a
+                                  displacement */
+     bit_fixS *bit_fixP;       /* pointer at struct of bit_fix's, ignored if
+                                  NULL */
+     char bsr;                 /* sequent-linker-hack: 1 when relocobject is
+                                  a bsr */
+     fragS *opcode_frag;
+     unsigned int opcode_offset;
+{
+  fixS *fixP = fix_new (frag, where, size, add_symbol,
+                       offset, pcrel,
+#ifdef BFD_ASSEMBLER
+                       bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
+#else
+                       NO_RELOC
+#endif
+                       );
 
+  fix_opcode_frag (fixP) = opcode_frag;
+  fix_opcode_offset (fixP) = opcode_offset;
+  fix_im_disp (fixP) = im_disp;
+  fix_bsr (fixP) = bsr;
+  fix_bit_fixP (fixP) = bit_fixP;
+}
+
+void
+fix_new_ns32k_exp (frag, where, size, exp, pcrel,
+                  im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
+     fragS *frag;              /* Which frag? */
+     int where;                        /* Where in that frag? */
+     int size;                 /* 1, 2  or 4 usually.  */
+     expressionS *exp;         /* Expression.  */
+     int pcrel;                        /* TRUE if PC-relative relocation.  */
+     char im_disp;             /* true if the value to write is a
+                                  displacement */
+     bit_fixS *bit_fixP;       /* pointer at struct of bit_fix's, ignored if
+                                  NULL */
+     char bsr;                 /* sequent-linker-hack: 1 when relocobject is
+                                  a bsr */
+     fragS *opcode_frag;
+     unsigned int opcode_offset;
 {
-  fixS *fixP = fix_new (frag, where, size, add_symbol, sub_symbol,
-                       offset, pcrel, NO_RELOC);
+  fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
+#ifdef BFD_ASSEMBLER
+                           bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
+#else
+                           NO_RELOC
+#endif
+                           );
 
-  fixP->fx_pcrel_adjust = pcrel_adjust;
-  fixP->fx_im_disp = im_disp;
-  fixP->fx_bit_fixP = bit_fixP;
-  fixP->fx_bsr = bsr;
-}                              /* fix_new_ns32k() */
+  fix_opcode_frag (fixP) = opcode_frag;
+  fix_opcode_offset (fixP) = opcode_offset;
+  fix_im_disp (fixP) = im_disp;
+  fix_bsr (fixP) = bsr;
+  fix_bit_fixP (fixP) = bit_fixP;
+}
 
 /* This is TC_CONS_FIX_NEW, called by emit_expr in read.c.  */
 
@@ -2096,12 +2277,11 @@ void
 cons_fix_new_ns32k (frag, where, size, exp)
      fragS *frag;              /* Which frag? */
      int where;                        /* Where in that frag? */
-     int size;                 /* 1, 2  or 4 usually. */
-     expressionS *exp;         /* Expression. */
+     int size;                 /* 1, 2  or 4 usually.  */
+     expressionS *exp;         /* Expression.  */
 {
-  fix_new_ns32k (frag, where, size, exp->X_add_symbol,
-                exp->X_subtract_symbol, exp->X_add_number,
-                0, 0, 2, 0, 0);
+  fix_new_ns32k_exp (frag, where, size, exp,
+                    0, 2, 0, 0, 0, 0);
 }
 
 /* We have no need to default values of symbols.  */
@@ -2113,30 +2293,19 @@ md_undefined_symbol (name)
   return 0;
 }
 
-/* Parse an operand that is machine-specific.
-   We just return without modifying the expression if we have nothing
-   to do.  */
-
-/* ARGSUSED */
-void
-md_operand (expressionP)
-     expressionS *expressionP;
-{
-}
-
 /* Round up a section size to the appropriate boundary.  */
+
 valueT
 md_section_align (segment, size)
      segT segment;
      valueT size;
 {
-  return size;                 /* Byte alignment is fine */
+  return size;                 /* Byte alignment is fine */
 }
 
-/* Exactly what point is a PC-relative offset relative TO?
-   On the National warts, they're relative to the address of the offset,
-   with some funny adjustments in some circumstances during blue moons.
-   (??? Is this right?  FIXME-SOON) */
+/* Exactly what point is a PC-relative offset relative TO?  On the
+   ns32k, they're relative to the start of the instruction.  */
+
 long
 md_pcrel_from (fixP)
      fixS *fixP;
@@ -2144,16 +2313,81 @@ md_pcrel_from (fixP)
   long res;
   res = fixP->fx_where + fixP->fx_frag->fr_address;
 #ifdef SEQUENT_COMPATABILITY
-  if (fixP->fx_frag->fr_bsr)
-    res += 0x12                        /* FOO Kludge alert! */
+  if (frag_bsr (fixP->fx_frag))
+    res += 0x12                        /* FOO Kludge alert!  */
 #endif
       return res;
 }
 
-/*
- * Local Variables:
- * comment-column: 0
- * End:
- */
+#ifdef BFD_ASSEMBLER
+
+arelent *
+tc_gen_reloc (section, fixp)
+     asection *section;
+     fixS *fixp;
+{
+  arelent *rel;
+  bfd_reloc_code_real_type code;
+
+  code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));
+
+  rel = (arelent *) xmalloc (sizeof (arelent));
+  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;
+  if (fixp->fx_pcrel)
+    rel->addend = fixp->fx_addnumber;
+  else
+    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 find relocation type for symbol %s, code %d"),
+               name, (int) code);
+    }
+
+  return rel;
+}
+#else /* BFD_ASSEMBLER */
+
+#ifdef OBJ_AOUT
+void
+cons_fix_new_ns32k (where, fixP, segment_address_in_file)
+     char *where;
+     struct fix *fixP;
+     relax_addressT segment_address_in_file;
+{
+  /* In:  Length of relocation (or of address) in chars: 1, 2 or 4.
+     Out: GNU LD relocation length code: 0, 1, or 2.  */
+
+  static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
+  long r_symbolnum;
+
+  know (fixP->fx_addsy != NULL);
+
+  md_number_to_chars (where,
+       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+                     4);
+
+  r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+                ? S_GET_TYPE (fixP->fx_addsy)
+                : fixP->fx_addsy->sy_number);
+
+  md_number_to_chars (where + 4,
+                     ((long) (r_symbolnum)
+                      | (long) (fixP->fx_pcrel << 24)
+                      | (long) (nbytes_r_length[fixP->fx_size] << 25)
+                      | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
+                      | (long) (fix_bsr (fixP) << 28)
+                      | (long) (fix_im_disp (fixP) << 29)),
+                     4);
+}
 
-/* end of tc-ns32k.c */
+#endif /* OBJ_AOUT */
+#endif /* BFD_ASSMEBLER */
This page took 0.060662 seconds and 4 git commands to generate.