[ARM][gas] Fix warnings about uninitialised uses and unused const variables
[deliverable/binutils-gdb.git] / gas / config / tc-i860.c
index f3b3f91af14ddf9ddeec3ba0036aa120e0819767..858d81e9983e8cdddb8c93cbb53a1b5518d55100 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-i860.c -- Assembler for the Intel i860 architecture.
 /* tc-i860.c -- Assembler for the Intel i860 architecture.
-   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1989-2016 Free Software Foundation, Inc.
 
    Brought back from the dead and completely reworked
    by Jason Eckhardt <jle@cygnus.com>.
 
    Brought back from the dead and completely reworked
    by Jason Eckhardt <jle@cygnus.com>.
@@ -9,7 +8,7 @@
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
    any later version.
 
    GAS is distributed in the hope that it will be useful,
 
    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
 
    You should have received a copy of the GNU General Public License along
    with GAS; see the file COPYING.  If not, write to the Free Software
-   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
 #include "as.h"
 #include "as.h"
+#include "safe-ctype.h"
 #include "subsegs.h"
 #include "opcode/i860.h"
 #include "elf/i860.h"
 
 
 #include "subsegs.h"
 #include "opcode/i860.h"
 #include "elf/i860.h"
 
 
-/* Defined by default since this is primarily a SVR4/860 assembler.
-   However, I'm trying to leave the door open for Intel syntax. Of course,
-   if full support for anything other than SVR4 is done, then we should
-   select this based on a command-line flag.  */
-#define SYNTAX_SVR4
-
-
 /* The opcode hash table.  */
 static struct hash_control *op_hash = NULL;
 
 /* The opcode hash table.  */
 static struct hash_control *op_hash = NULL;
 
@@ -56,26 +46,28 @@ const char EXP_CHARS[] = "eE";
    As in 0f12.456 or 0d1.2345e12.  */
 const char FLT_CHARS[] = "rRsSfFdDxXpP";
 
    As in 0f12.456 or 0d1.2345e12.  */
 const char FLT_CHARS[] = "rRsSfFdDxXpP";
 
+/* Register prefix (depends on syntax).  */
+static char reg_prefix;
 
 
-/* Register prefix.  */
-#ifdef SYNTAX_SVR4
-static const char reg_prefix = '%';
-#else
-static const char reg_prefix = 0;
-#endif
-
+#define MAX_FIXUPS 2
 
 struct i860_it
 {
 
 struct i860_it
 {
-  char *error;
+  const char *error;
   unsigned long opcode;
   unsigned long opcode;
-  expressionS exp;
   enum expand_type expand;
   enum expand_type expand;
-  bfd_reloc_code_real_type reloc;
-  int pcrel;
-  valueT fup;
+  struct i860_fi
+  {
+    expressionS exp;
+    bfd_reloc_code_real_type reloc;
+    int pcrel;
+    valueT fup;
+  } fi[MAX_FIXUPS];
 } the_insn;
 
 } the_insn;
 
+/* The current fixup count.  */
+static int fc;
+
 static char *expr_end;
 
 /* Indicates error if a pseudo operation was expanded after a branch.  */
 static char *expr_end;
 
 /* Indicates error if a pseudo operation was expanded after a branch.  */
@@ -84,32 +76,34 @@ static char last_expand;
 /* If true, then warn if any pseudo operations were expanded.  */
 static int target_warn_expand = 0;
 
 /* If true, then warn if any pseudo operations were expanded.  */
 static int target_warn_expand = 0;
 
+/* If true, then XP support is enabled.  */
+static int target_xp = 0;
+
+/* If true, then Intel syntax is enabled (default to AT&T/SVR4 syntax).  */
+static int target_intel_syntax = 0;
+
 
 /* Prototypes.  */
 
 /* Prototypes.  */
-static void i860_process_insn  PARAMS ((char *));
-static void s_dual             PARAMS ((int));
-static void s_enddual          PARAMS ((int));
-static void s_atmp             PARAMS ((int));
-static int i860_get_expression PARAMS ((char *));
-static bfd_reloc_code_real_type obtain_reloc_for_imm16
-  PARAMS ((fixS *, long *));
+static void i860_process_insn (char *);
+static void s_dual (int);
+static void s_enddual (int);
+static void s_atmp (int);
+static void s_align_wrapper (int);
+static int i860_get_expression (char *);
+static bfd_reloc_code_real_type obtain_reloc_for_imm16 (fixS *, long *);
 #ifdef DEBUG_I860
 #ifdef DEBUG_I860
-static void print_insn         PARAMS ((struct i860_it *));
+static void print_insn (struct i860_it *);
 #endif
 
 #endif
 
-
 const pseudo_typeS md_pseudo_table[] =
 {
 const pseudo_typeS md_pseudo_table[] =
 {
-#ifdef OBJ_ELF
-  {"align",   s_align_bytes, 0},
-#endif
-  {"dual",    s_dual,        0},
-  {"enddual", s_enddual,     0},
-  {"atmp",    s_atmp,        0},
-  {NULL,      0,             0},
+  {"align",   s_align_wrapper, 0},
+  {"dual",    s_dual,          0},
+  {"enddual", s_enddual,       0},
+  {"atmp",    s_atmp,          0},
+  {NULL,      0,               0},
 };
 
 };
 
-
 /* Dual-instruction mode handling.  */
 enum dual
 {
 /* Dual-instruction mode handling.  */
 enum dual
 {
@@ -117,33 +111,41 @@ enum dual
 };
 static enum dual dual_mode = DUAL_OFF;
 
 };
 static enum dual dual_mode = DUAL_OFF;
 
-
 /* Handle ".dual" directive.  */
 static void
 /* Handle ".dual" directive.  */
 static void
-s_dual (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_dual (int ignore ATTRIBUTE_UNUSED)
 {
 {
-  dual_mode = DUAL_ON;
+  if (target_intel_syntax)
+    dual_mode = DUAL_ON;
+  else
+    as_bad (_("Directive .dual available only with -mintel-syntax option"));
 }
 
 }
 
-
 /* Handle ".enddual" directive.  */
 static void
 /* Handle ".enddual" directive.  */
 static void
-s_enddual (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_enddual (int ignore ATTRIBUTE_UNUSED)
 {
 {
-  dual_mode = DUAL_OFF;
+  if (target_intel_syntax)
+    dual_mode = DUAL_OFF;
+  else
+    as_bad (_("Directive .enddual available only with -mintel-syntax option"));
 }
 
 }
 
-
 /* Temporary register used when expanding assembler pseudo operations.  */
 static int atmp = 31;
 
 static void
 /* Temporary register used when expanding assembler pseudo operations.  */
 static int atmp = 31;
 
 static void
-s_atmp (ignore)
-     int ignore ATTRIBUTE_UNUSED;
+s_atmp (int ignore ATTRIBUTE_UNUSED)
 {
 {
-  register int temp;
+  int temp;
+
+  if (! target_intel_syntax)
+    {
+      as_bad (_("Directive .atmp available only with -mintel-syntax option"));
+      demand_empty_rest_of_line ();
+      return;
+    }
+
   if (strncmp (input_line_pointer, "sp", 2) == 0)
     {
       input_line_pointer += 2;
   if (strncmp (input_line_pointer, "sp", 2) == 0)
     {
       input_line_pointer += 2;
@@ -170,12 +172,44 @@ s_atmp (ignore)
   demand_empty_rest_of_line ();
 }
 
   demand_empty_rest_of_line ();
 }
 
+/* Handle ".align" directive depending on syntax mode.
+   AT&T/SVR4 syntax uses the standard align directive.  However,
+   the Intel syntax additionally allows keywords for the alignment
+   parameter: ".align type", where type is one of {.short, .long,
+   .quad, .single, .double} representing alignments of 2, 4,
+   16, 4, and 8, respectively.  */
+static void
+s_align_wrapper (int arg)
+{
+  char *parm = input_line_pointer;
+
+  if (target_intel_syntax)
+    {
+      /* Replace a keyword with the equivalent integer so the
+         standard align routine can parse the directive.  */
+      if (strncmp (parm, ".short", 6) == 0)
+        strncpy (parm, "     2", 6);
+      else if (strncmp (parm, ".long", 5) == 0)
+        strncpy (parm, "    4", 5);
+      else if (strncmp (parm, ".quad", 5) == 0)
+        strncpy (parm, "   16", 5);
+      else if (strncmp (parm, ".single", 7) == 0)
+        strncpy (parm, "      4", 7);
+      else if (strncmp (parm, ".double", 7) == 0)
+        strncpy (parm, "      8", 7);
+
+      while (*input_line_pointer == ' ')
+        ++input_line_pointer;
+    }
+
+  s_align_bytes (arg);
+}
 
 /* This function is called once, at assembler startup time.  It should
    set up all the tables and data structures that the MD part of the
    assembler will need.  */
 void
 
 /* This function is called once, at assembler startup time.  It should
    set up all the tables and data structures that the MD part of the
    assembler will need.  */
 void
-md_begin ()
+md_begin (void)
 {
   const char *retval = NULL;
   int lose = 0;
 {
   const char *retval = NULL;
   int lose = 0;
@@ -186,7 +220,7 @@ md_begin ()
   while (i860_opcodes[i].name != NULL)
     {
       const char *name = i860_opcodes[i].name;
   while (i860_opcodes[i].name != NULL)
     {
       const char *name = i860_opcodes[i].name;
-      retval = hash_insert (op_hash, name, (PTR)&i860_opcodes[i]);
+      retval = hash_insert (op_hash, name, (void *) &i860_opcodes[i]);
       if (retval != NULL)
        {
          fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
       if (retval != NULL)
        {
          fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
@@ -210,35 +244,38 @@ md_begin ()
 
   if (lose)
     as_fatal (_("Defective assembler.  No assembly attempted."));
 
   if (lose)
     as_fatal (_("Defective assembler.  No assembly attempted."));
-}
 
 
+  /* Set the register prefix for either Intel or AT&T/SVR4 syntax.  */
+  reg_prefix = target_intel_syntax ? 0 : '%';
+}
 
 /* This is the core of the machine-dependent assembler.  STR points to a
    machine dependent instruction.  This function emits the frags/bytes
    it assembles to.  */
 void
 
 /* This is the core of the machine-dependent assembler.  STR points to a
    machine dependent instruction.  This function emits the frags/bytes
    it assembles to.  */
 void
-md_assemble (str)
-     char *str;
+md_assemble (char *str)
 {
   char *destp;
   int num_opcodes = 1;
   int i;
   struct i860_it pseudo[3];
 
 {
   char *destp;
   int num_opcodes = 1;
   int i;
   struct i860_it pseudo[3];
 
-  assert (str);
+  gas_assert (str);
+  fc = 0;
 
   /* Assemble the instruction.  */
   i860_process_insn (str);
 
   /* Check for expandable flag to produce pseudo-instructions.  This
      is an undesirable feature that should be avoided.  */
 
   /* Assemble the instruction.  */
   i860_process_insn (str);
 
   /* Check for expandable flag to produce pseudo-instructions.  This
      is an undesirable feature that should be avoided.  */
-  if (the_insn.expand != 0
-      && ! (the_insn.fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT
+  if (the_insn.expand != 0 && the_insn.expand != XP_ONLY
+      && ! (the_insn.fi[0].fup & (OP_SEL_HA | OP_SEL_H | OP_SEL_L | OP_SEL_GOT
                            | OP_SEL_GOTOFF | OP_SEL_PLT)))
     {
       for (i = 0; i < 3; i++)
        pseudo[i] = the_insn;
 
                            | OP_SEL_GOTOFF | OP_SEL_PLT)))
     {
       for (i = 0; i < 3; i++)
        pseudo[i] = the_insn;
 
+      fc = 1;
       switch (the_insn.expand)
        {
 
       switch (the_insn.expand)
        {
 
@@ -247,103 +284,106 @@ md_assemble (str)
          break;
 
        case E_MOV:
          break;
 
        case E_MOV:
-         if (the_insn.exp.X_add_symbol == NULL
-             && the_insn.exp.X_op_symbol == NULL
-             && (the_insn.exp.X_add_number < (1 << 15)
-                 && the_insn.exp.X_add_number >= -(1 << 15)))
+         if (the_insn.fi[0].exp.X_add_symbol == NULL
+             && the_insn.fi[0].exp.X_op_symbol == NULL
+             && (the_insn.fi[0].exp.X_add_number < (1 << 15)
+                 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
            break;
 
          /* Emit "or l%const,r0,ireg_dest".  */
          pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
            break;
 
          /* Emit "or l%const,r0,ireg_dest".  */
          pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
-         pseudo[0].fup = (OP_IMM_S16 | OP_SEL_L);
+         pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
 
          /* Emit "orh h%const,ireg_dest,ireg_dest".  */
          pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000
                              | ((the_insn.opcode & 0x001f0000) << 5);
 
          /* Emit "orh h%const,ireg_dest,ireg_dest".  */
          pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000
                              | ((the_insn.opcode & 0x001f0000) << 5);
-         pseudo[1].fup = (OP_IMM_S16 | OP_SEL_H);
+         pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
 
          num_opcodes = 2;
          break;
 
        case E_ADDR:
 
          num_opcodes = 2;
          break;
 
        case E_ADDR:
-         if (the_insn.exp.X_add_symbol == NULL
-             && the_insn.exp.X_op_symbol == NULL
-             && (the_insn.exp.X_add_number < (1 << 15)
-                 && the_insn.exp.X_add_number >= -(1 << 15)))
+         if (the_insn.fi[0].exp.X_add_symbol == NULL
+             && the_insn.fi[0].exp.X_op_symbol == NULL
+             && (the_insn.fi[0].exp.X_add_number < (1 << 15)
+                 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
            break;
 
            break;
 
-         /* Emit "orh ha%addr_expr,r0,r31".  */
-         pseudo[0].opcode = 0xec000000 | (atmp << 16);
-         pseudo[0].fup = (OP_IMM_S16 | OP_SEL_HA);
+         /* Emit "orh ha%addr_expr,ireg_src2,r31".  */
+         pseudo[0].opcode = 0xec000000 | (the_insn.opcode & 0x03e00000)
+                            | (atmp << 16);
+         pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_HA);
 
          /* Emit "l%addr_expr(r31),ireg_dest".  We pick up the fixup
             information from the original instruction.   */
          pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
 
          /* Emit "l%addr_expr(r31),ireg_dest".  We pick up the fixup
             information from the original instruction.   */
          pseudo[1].opcode = (the_insn.opcode & ~0x03e00000) | (atmp << 21);
-         pseudo[1].fup = the_insn.fup | OP_SEL_L;
+         pseudo[1].fi[0].fup = the_insn.fi[0].fup | OP_SEL_L;
 
          num_opcodes = 2;
          break;
 
        case E_U32:
 
          num_opcodes = 2;
          break;
 
        case E_U32:
-         if (the_insn.exp.X_add_symbol == NULL
-             && the_insn.exp.X_op_symbol == NULL
-             && (the_insn.exp.X_add_number < (1 << 16)
-                 && the_insn.exp.X_add_number >= 0))
+         if (the_insn.fi[0].exp.X_add_symbol == NULL
+             && the_insn.fi[0].exp.X_op_symbol == NULL
+             && (the_insn.fi[0].exp.X_add_number < (1 << 16)
+                 && the_insn.fi[0].exp.X_add_number >= 0))
            break;
 
          /* Emit "$(opcode)h h%const,ireg_src2,r31".  */
          pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
                              | (atmp << 16);
            break;
 
          /* Emit "$(opcode)h h%const,ireg_src2,r31".  */
          pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000
                              | (atmp << 16);
-         pseudo[0].fup = (OP_IMM_S16 | OP_SEL_H);
+         pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
 
          /* Emit "$(opcode) l%const,r31,ireg_dest".  */
          pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
                              | (atmp << 21);
 
          /* Emit "$(opcode) l%const,r31,ireg_dest".  */
          pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000
                              | (atmp << 21);
-         pseudo[1].fup = (OP_IMM_S16 | OP_SEL_L);
+         pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
 
          num_opcodes = 2;
          break;
 
        case E_AND:
 
          num_opcodes = 2;
          break;
 
        case E_AND:
-         if (the_insn.exp.X_add_symbol == NULL
-             && the_insn.exp.X_op_symbol == NULL
-             && (the_insn.exp.X_add_number < (1 << 16)
-                 && the_insn.exp.X_add_number >= 0))
+         if (the_insn.fi[0].exp.X_add_symbol == NULL
+             && the_insn.fi[0].exp.X_op_symbol == NULL
+             && (the_insn.fi[0].exp.X_add_number < (1 << 16)
+                 && the_insn.fi[0].exp.X_add_number >= 0))
            break;
 
          /* Emit "andnot h%const,ireg_src2,r31".  */
          pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
                              | (atmp << 16);
            break;
 
          /* Emit "andnot h%const,ireg_src2,r31".  */
          pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000
                              | (atmp << 16);
-         pseudo[0].fup = (OP_IMM_S16 | OP_SEL_H);
-         pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number;
+         pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
+         pseudo[0].fi[0].exp.X_add_number =
+            -1 - the_insn.fi[0].exp.X_add_number;
 
          /* Emit "andnot l%const,r31,ireg_dest".  */
          pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
                              | (atmp << 21);
 
          /* Emit "andnot l%const,r31,ireg_dest".  */
          pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000
                              | (atmp << 21);
-         pseudo[1].fup = (OP_IMM_S16 | OP_SEL_L);
-         pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number;
+         pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
+         pseudo[1].fi[0].exp.X_add_number =
+            -1 - the_insn.fi[0].exp.X_add_number;
 
          num_opcodes = 2;
          break;
 
        case E_S32:
 
          num_opcodes = 2;
          break;
 
        case E_S32:
-         if (the_insn.exp.X_add_symbol == NULL
-             && the_insn.exp.X_op_symbol == NULL
-             && (the_insn.exp.X_add_number < (1 << 15)
-                 && the_insn.exp.X_add_number >= -(1 << 15)))
+         if (the_insn.fi[0].exp.X_add_symbol == NULL
+             && the_insn.fi[0].exp.X_op_symbol == NULL
+             && (the_insn.fi[0].exp.X_add_number < (1 << 15)
+                 && the_insn.fi[0].exp.X_add_number >= -(1 << 15)))
            break;
 
          /* Emit "orh h%const,r0,r31".  */
          pseudo[0].opcode = 0xec000000 | (atmp << 16);
            break;
 
          /* Emit "orh h%const,r0,r31".  */
          pseudo[0].opcode = 0xec000000 | (atmp << 16);
-         pseudo[0].fup = (OP_IMM_S16 | OP_SEL_H);
+         pseudo[0].fi[0].fup = (OP_IMM_S16 | OP_SEL_H);
 
          /* Emit "or l%const,r31,r31".  */
          pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
 
          /* Emit "or l%const,r31,r31".  */
          pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
-         pseudo[1].fup = (OP_IMM_S16 | OP_SEL_L);
+         pseudo[1].fi[0].fup = (OP_IMM_S16 | OP_SEL_L);
 
          /* Emit "r31,ireg_src2,ireg_dest".  */
          pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
 
          /* Emit "r31,ireg_src2,ireg_dest".  */
          pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
-         pseudo[2].fup = OP_IMM_S16;
+         pseudo[2].fi[0].fup = OP_IMM_S16;
 
          num_opcodes = 3;
          break;
 
          num_opcodes = 3;
          break;
@@ -367,43 +407,49 @@ md_assemble (str)
        as_warn (_("An instruction was expanded (%s)"), str);
     }
 
        as_warn (_("An instruction was expanded (%s)"), str);
     }
 
+  dwarf2_emit_insn (0);
   i = 0;
   do
     {
   i = 0;
   do
     {
+      int tmp;
+
       /* Output the opcode.  Note that the i860 always reads instructions
         as little-endian data.  */
       destp = frag_more (4);
       number_to_chars_littleendian (destp, the_insn.opcode, 4);
 
       /* Check for expanded opcode after branch or in dual mode.  */
       /* Output the opcode.  Note that the i860 always reads instructions
         as little-endian data.  */
       destp = frag_more (4);
       number_to_chars_littleendian (destp, the_insn.opcode, 4);
 
       /* Check for expanded opcode after branch or in dual mode.  */
-      last_expand = the_insn.pcrel;
-
-      /* Output the symbol-dependent stuff.  */
-      if (the_insn.fup != OP_NONE)
-       {
-         fixS *fix;
-         fix = fix_new_exp (frag_now,
-                            destp - frag_now->fr_literal,
-                            4,
-                            &the_insn.exp,
-                            the_insn.pcrel,
-                            the_insn.reloc);
-
-         /* Despite the odd name, this is a scratch field.  We use
-            it to encode operand type information.  */ 
-         fix->fx_addnumber = the_insn.fup;
-       }
+      last_expand = the_insn.fi[0].pcrel;
+
+      /* Output the symbol-dependent stuff.  Only btne and bte will ever
+         loop more than once here, since only they (possibly) have more
+         than one fixup.  */
+      for (tmp = 0; tmp < fc; tmp++)
+        {
+          if (the_insn.fi[tmp].fup != OP_NONE)
+           {
+             fixS *fix;
+             fix = fix_new_exp (frag_now,
+                                destp - frag_now->fr_literal,
+                                4,
+                                &the_insn.fi[tmp].exp,
+                                the_insn.fi[tmp].pcrel,
+                                the_insn.fi[tmp].reloc);
+
+            /* Despite the odd name, this is a scratch field.  We use
+               it to encode operand type information.  */
+            fix->fx_addnumber = the_insn.fi[tmp].fup;
+          }
+        }
       the_insn = pseudo[++i];
     }
   while (--num_opcodes > 0);
 
 }
 
       the_insn = pseudo[++i];
     }
   while (--num_opcodes > 0);
 
 }
 
-
 /* Assemble the instruction pointed to by STR.  */
 static void
 /* Assemble the instruction pointed to by STR.  */
 static void
-i860_process_insn (str)
-     char *str;
+i860_process_insn (char *str)
 {
   char *s;
   const char *args;
 {
   char *s;
   const char *args;
@@ -422,7 +468,7 @@ i860_process_insn (str)
   opcode = 0;
 #endif
 
   opcode = 0;
 #endif
 
-  for (s = str; islower (*s) || *s == '.' || *s == '3'
+  for (s = str; ISLOWER (*s) || *s == '.' || *s == '3'
        || *s == '2' || *s == '1'; ++s)
     ;
 
        || *s == '2' || *s == '1'; ++s)
     ;
 
@@ -468,15 +514,23 @@ i860_process_insn (str)
   args_start = s;
   for (;;)
     {
   args_start = s;
   for (;;)
     {
+      int t;
       opcode = insn->match;
       memset (&the_insn, '\0', sizeof (the_insn));
       opcode = insn->match;
       memset (&the_insn, '\0', sizeof (the_insn));
-      the_insn.reloc = BFD_RELOC_NONE;
-      the_insn.pcrel = 0;
-      the_insn.fup = OP_NONE;
+      fc = 0;
+      for (t = 0; t < MAX_FIXUPS; t++)
+        {
+          the_insn.fi[t].reloc = BFD_RELOC_NONE;
+          the_insn.fi[t].pcrel = 0;
+          the_insn.fi[t].fup = OP_NONE;
+        }
 
       /* Build the opcode, checking as we go that the operands match.  */
       for (args = insn->args; ; ++args)
        {
 
       /* Build the opcode, checking as we go that the operands match.  */
       for (args = insn->args; ; ++args)
        {
+          if (fc > MAX_FIXUPS)
+            abort ();
+
          switch (*args)
            {
 
          switch (*args)
            {
 
@@ -498,9 +552,9 @@ i860_process_insn (str)
 
            /* Must be at least one digit.  */
            case '#':
 
            /* Must be at least one digit.  */
            case '#':
-             if (isdigit (*s++))
+             if (ISDIGIT (*s++))
                {
                {
-                 while (isdigit (*s))
+                 while (ISDIGIT (*s))
                    ++s;
                  continue;
                }
                    ++s;
                  continue;
                }
@@ -513,7 +567,7 @@ i860_process_insn (str)
              /* Check for register prefix if necessary.  */
              if (reg_prefix && *s != reg_prefix)
                goto error;
              /* Check for register prefix if necessary.  */
              if (reg_prefix && *s != reg_prefix)
                goto error;
-             else
+             else if (reg_prefix)
                s++;
 
              switch (*s)
                s++;
 
              switch (*s)
@@ -541,11 +595,11 @@ i860_process_insn (str)
                /* Any register r0..r31.  */
                case 'r':
                  s++;
                /* Any register r0..r31.  */
                case 'r':
                  s++;
-                 if (!isdigit (c = *s++))
+                 if (!ISDIGIT (c = *s++))
                    {
                      goto error;
                    }
                    {
                      goto error;
                    }
-                 if (isdigit (*s))
+                 if (ISDIGIT (*s))
                    {
                      if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
                        goto error;
                    {
                      if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
                        goto error;
@@ -585,13 +639,13 @@ i860_process_insn (str)
              /* Check for register prefix if necessary.  */
              if (reg_prefix && *s != reg_prefix)
                goto error;
              /* Check for register prefix if necessary.  */
              if (reg_prefix && *s != reg_prefix)
                goto error;
-             else
+             else if (reg_prefix)
                s++;
 
                s++;
 
-             if (*s++ == 'f' && isdigit (*s))
+             if (*s++ == 'f' && ISDIGIT (*s))
                {
                  mask = *s++;
                {
                  mask = *s++;
-                 if (isdigit (*s))
+                 if (ISDIGIT (*s))
                    {
                      mask = 10 * (mask - '0') + (*s++ - '0');
                      if (mask >= 32)
                    {
                      mask = 10 * (mask - '0') + (*s++ - '0');
                      if (mask >= 32)
@@ -615,12 +669,6 @@ i860_process_insn (str)
 
                    case 'g':
                      opcode |= mask << 16;
 
                    case 'g':
                      opcode |= mask << 16;
-                     if (dual_mode != DUAL_OFF)
-                       opcode |= (1 << 9);
-                     if (dual_mode == DUAL_DDOT)
-                       dual_mode = DUAL_OFF;
-                     if (dual_mode == DUAL_ONDDOT)
-                       dual_mode = DUAL_ON;
                      if ((opcode & (1 << 10)) && mask != 0
                          && (mask == ((opcode >> 11) & 0x1f)))
                        as_warn (_("Pipelined instruction: fsrc1 = fdest"));
                      if ((opcode & (1 << 10)) && mask != 0
                          && (mask == ((opcode >> 11) & 0x1f)))
                        as_warn (_("Pipelined instruction: fsrc1 = fdest"));
@@ -634,7 +682,7 @@ i860_process_insn (str)
              /* Check for register prefix if necessary.  */
              if (reg_prefix && *s != reg_prefix)
                goto error;
              /* Check for register prefix if necessary.  */
              if (reg_prefix && *s != reg_prefix)
                goto error;
-             else
+             else if (reg_prefix)
                s++;
 
              if (strncmp (s, "fir", 3) == 0)
                s++;
 
              if (strncmp (s, "fir", 3) == 0)
@@ -673,6 +721,43 @@ i860_process_insn (str)
                  s += 4;
                  continue;
                }
                  s += 4;
                  continue;
                }
+             /* The remaining control registers are XP only.  */
+             if (target_xp && strncmp (s, "bear", 4) == 0)
+               {
+                 opcode |= 0x6 << 21;
+                 s += 4;
+                 continue;
+               }
+             if (target_xp && strncmp (s, "ccr", 3) == 0)
+               {
+                 opcode |= 0x7 << 21;
+                 s += 3;
+                 continue;
+               }
+             if (target_xp && strncmp (s, "p0", 2) == 0)
+               {
+                 opcode |= 0x8 << 21;
+                 s += 2;
+                 continue;
+               }
+             if (target_xp && strncmp (s, "p1", 2) == 0)
+               {
+                 opcode |= 0x9 << 21;
+                 s += 2;
+                 continue;
+               }
+             if (target_xp && strncmp (s, "p2", 2) == 0)
+               {
+                 opcode |= 0xa << 21;
+                 s += 2;
+                 continue;
+               }
+             if (target_xp && strncmp (s, "p3", 2) == 0)
+               {
+                 opcode |= 0xb << 21;
+                 s += 2;
+                 continue;
+               }
              break;
 
            /* 5-bit immediate in src1.  */
              break;
 
            /* 5-bit immediate in src1.  */
@@ -680,74 +765,75 @@ i860_process_insn (str)
              if (! i860_get_expression (s))
                {
                  s = expr_end;
              if (! i860_get_expression (s))
                {
                  s = expr_end;
-                 the_insn.fup |= OP_IMM_U5;
+                 the_insn.fi[fc].fup |= OP_IMM_U5;
+                 fc++;
                  continue;
                }
              break;
 
            /* 26-bit immediate, relative branch (lbroff).  */
            case 'l':
                  continue;
                }
              break;
 
            /* 26-bit immediate, relative branch (lbroff).  */
            case 'l':
-             the_insn.pcrel = 1;
-             the_insn.fup |= OP_IMM_BR26;
+             the_insn.fi[fc].pcrel = 1;
+             the_insn.fi[fc].fup |= OP_IMM_BR26;
              goto immediate;
 
            /* 16-bit split immediate, relative branch (sbroff).  */
            case 'r':
              goto immediate;
 
            /* 16-bit split immediate, relative branch (sbroff).  */
            case 'r':
-             the_insn.pcrel = 1;
-             the_insn.fup |= OP_IMM_BR16;
+             the_insn.fi[fc].pcrel = 1;
+             the_insn.fi[fc].fup |= OP_IMM_BR16;
              goto immediate;
 
            /* 16-bit split immediate.  */
            case 's':
              goto immediate;
 
            /* 16-bit split immediate.  */
            case 's':
-             the_insn.fup |= OP_IMM_SPLIT16;
+             the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
              goto immediate;
 
            /* 16-bit split immediate, byte aligned (st.b).  */
            case 'S':
              goto immediate;
 
            /* 16-bit split immediate, byte aligned (st.b).  */
            case 'S':
-             the_insn.fup |= OP_IMM_SPLIT16;
+             the_insn.fi[fc].fup |= OP_IMM_SPLIT16;
              goto immediate;
 
            /* 16-bit split immediate, half-word aligned (st.s).  */
            case 'T':
              goto immediate;
 
            /* 16-bit split immediate, half-word aligned (st.s).  */
            case 'T':
-             the_insn.fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2);
+             the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2);
              goto immediate;
 
            /* 16-bit split immediate, word aligned (st.l).  */
            case 'U':
              goto immediate;
 
            /* 16-bit split immediate, word aligned (st.l).  */
            case 'U':
-             the_insn.fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4);
+             the_insn.fi[fc].fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4);
              goto immediate;
 
            /* 16-bit immediate.  */
            case 'i':
              goto immediate;
 
            /* 16-bit immediate.  */
            case 'i':
-             the_insn.fup |= OP_IMM_S16;
+             the_insn.fi[fc].fup |= OP_IMM_S16;
              goto immediate;
 
            /* 16-bit immediate, byte aligned (ld.b).  */
            case 'I':
              goto immediate;
 
            /* 16-bit immediate, byte aligned (ld.b).  */
            case 'I':
-             the_insn.fup |= OP_IMM_S16;
+             the_insn.fi[fc].fup |= OP_IMM_S16;
              goto immediate;
 
            /* 16-bit immediate, half-word aligned (ld.s).  */
            case 'J':
              goto immediate;
 
            /* 16-bit immediate, half-word aligned (ld.s).  */
            case 'J':
-             the_insn.fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2);
+             the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2);
              goto immediate;
 
            /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l).  */
            case 'K':
              if (insn->name[0] == 'l')
              goto immediate;
 
            /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l).  */
            case 'K':
              if (insn->name[0] == 'l')
-               the_insn.fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4);
+               the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4);
              else
              else
-               the_insn.fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4);
+               the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4);
              goto immediate;
 
            /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d).  */
            case 'L':
              goto immediate;
 
            /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d).  */
            case 'L':
-             the_insn.fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8);
+             the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8);
              goto immediate;
 
            /* 16-bit immediate, quad-word aligned (fld.q, fst.q).  */
            case 'M':
              goto immediate;
 
            /* 16-bit immediate, quad-word aligned (fld.q, fst.q).  */
            case 'M':
-             the_insn.fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16);
+             the_insn.fi[fc].fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16);
 
              /*FALLTHROUGH*/
 
 
              /*FALLTHROUGH*/
 
@@ -755,90 +841,97 @@ i860_process_insn (str)
                 SVR4 syntax. The Intel syntax is "ha%immediate"
                 whereas SVR4 syntax is "[immediate]@ha".  */
            immediate:
                 SVR4 syntax. The Intel syntax is "ha%immediate"
                 whereas SVR4 syntax is "[immediate]@ha".  */
            immediate:
-#ifdef SYNTAX_SVR4
-             if (*s == ' ')
-               s++;
-
-             /* Note that if i860_get_expression() fails, we will still
-                have created U entries in the symbol table for the
-                'symbols' in the input string.  Try not to create U
-                symbols for registers, etc.  */
-             if (! i860_get_expression (s))
-               s = expr_end;
-             else
-               goto error;
-
-             if (strncmp (s, "@ha", 3) == 0)
-               {
-                 the_insn.fup |= OP_SEL_HA;
-                 s += 3;
-               }
-             else if (strncmp (s, "@h", 2) == 0)
+             if (target_intel_syntax == 0)
                {
                {
-                 the_insn.fup |= OP_SEL_H;
-                 s += 2;
-               }
-             else if (strncmp (s, "@l", 2) == 0)
-               {
-                 the_insn.fup |= OP_SEL_L;
-                 s += 2;
-               }
-             else if (strncmp (s, "@gotoff", 7) == 0
-                      || strncmp (s, "@GOTOFF", 7) == 0)
-               {
-                 as_bad (_("Assembler does not yet support PIC"));
-                 the_insn.fup |= OP_SEL_GOTOFF;
-                 s += 7;
-               }
-             else if (strncmp (s, "@got", 4) == 0
-                      || strncmp (s, "@GOT", 4) == 0)
-               {
-                 as_bad (_("Assembler does not yet support PIC"));
-                 the_insn.fup |= OP_SEL_GOT;
-                 s += 4;
-               }
-             else if (strncmp (s, "@plt", 4) == 0
-                      || strncmp (s, "@PLT", 4) == 0)
-               {
-                 as_bad (_("Assembler does not yet support PIC"));
-                 the_insn.fup |= OP_SEL_PLT;
-                 s += 4;
-               }
+                 /* AT&T/SVR4 syntax.  */
+                 if (*s == ' ')
+                   s++;
+
+                 /* Note that if i860_get_expression() fails, we will still
+                    have created U entries in the symbol table for the
+                    'symbols' in the input string.  Try not to create U
+                    symbols for registers, etc.  */
+                 if (! i860_get_expression (s))
+                   s = expr_end;
+                 else
+                   goto error;
+
+                 if (strncmp (s, "@ha", 3) == 0)
+                   {
+                     the_insn.fi[fc].fup |= OP_SEL_HA;
+                     s += 3;
+                   }
+                 else if (strncmp (s, "@h", 2) == 0)
+                   {
+                     the_insn.fi[fc].fup |= OP_SEL_H;
+                     s += 2;
+                   }
+                 else if (strncmp (s, "@l", 2) == 0)
+                   {
+                     the_insn.fi[fc].fup |= OP_SEL_L;
+                     s += 2;
+                   }
+                 else if (strncmp (s, "@gotoff", 7) == 0
+                          || strncmp (s, "@GOTOFF", 7) == 0)
+                   {
+                     as_bad (_("Assembler does not yet support PIC"));
+                     the_insn.fi[fc].fup |= OP_SEL_GOTOFF;
+                     s += 7;
+                   }
+                 else if (strncmp (s, "@got", 4) == 0
+                          || strncmp (s, "@GOT", 4) == 0)
+                   {
+                     as_bad (_("Assembler does not yet support PIC"));
+                     the_insn.fi[fc].fup |= OP_SEL_GOT;
+                     s += 4;
+                   }
+                 else if (strncmp (s, "@plt", 4) == 0
+                          || strncmp (s, "@PLT", 4) == 0)
+                   {
+                     as_bad (_("Assembler does not yet support PIC"));
+                     the_insn.fi[fc].fup |= OP_SEL_PLT;
+                     s += 4;
+                   }
 
 
-             the_insn.expand = insn->expand;
+                 the_insn.expand = insn->expand;
+                  fc++;
 
 
-             continue;
-#else /* ! SYNTAX_SVR4 */
-             if (*s == ' ')
-               s++;
-             if (strncmp (s, "ha%", 3) == 0)
-               {
-                 the_insn.fup |= OP_SEL_HA;
-                 s += 3;
+                 continue;
                }
                }
-             else if (strncmp (s, "h%", 2) == 0)
-               {
-                 the_insn.fup |= OP_SEL_H;
-                 s += 2;
-               }
-             else if (strncmp (s, "l%", 2) == 0)
+             else
                {
                {
-                 the_insn.fup |= OP_SEL_L;
-                 s += 2;
+                 /* Intel syntax.  */
+                 if (*s == ' ')
+                   s++;
+                 if (strncmp (s, "ha%", 3) == 0)
+                   {
+                     the_insn.fi[fc].fup |= OP_SEL_HA;
+                     s += 3;
+                   }
+                 else if (strncmp (s, "h%", 2) == 0)
+                   {
+                     the_insn.fi[fc].fup |= OP_SEL_H;
+                     s += 2;
+                   }
+                 else if (strncmp (s, "l%", 2) == 0)
+                   {
+                     the_insn.fi[fc].fup |= OP_SEL_L;
+                     s += 2;
+                   }
+                 the_insn.expand = insn->expand;
+
+                 /* Note that if i860_get_expression() fails, we will still
+                    have created U entries in the symbol table for the
+                    'symbols' in the input string.  Try not to create U
+                    symbols for registers, etc.  */
+                 if (! i860_get_expression (s))
+                   s = expr_end;
+                 else
+                   goto error;
+
+                  fc++;
+                 continue;
                }
                }
-             the_insn.expand = insn->expand;
-
-             /* Note that if i860_get_expression() fails, we will still
-                have created U entries in the symbol table for the
-                'symbols' in the input string.  Try not to create U
-                symbols for registers, etc.  */
-             if (! i860_get_expression (s))
-               s = expr_end;
-             else
-               goto error;
-
-             continue;
-#endif /* SYNTAX_SVR4 */
              break;
 
            default:
              break;
 
            default:
@@ -866,20 +959,43 @@ i860_process_insn (str)
       break;
     }
 
       break;
     }
 
+  /* Set the dual bit on this instruction if necessary.  */
+  if (dual_mode != DUAL_OFF)
+    {
+      if ((opcode & 0xfc000000) == 0x48000000 || opcode == 0xb0000000)
+        {
+         /* The instruction is a flop or a fnop, so set its dual bit
+            (but check that it is 8-byte aligned).  */
+         if (((frag_now->fr_address + frag_now_fix_octets ()) & 7) == 0)
+           opcode |= (1 << 9);
+         else
+            as_bad (_("'d.%s' must be 8-byte aligned"), insn->name);
+
+          if (dual_mode == DUAL_DDOT)
+           dual_mode = DUAL_OFF;
+          else if (dual_mode == DUAL_ONDDOT)
+           dual_mode = DUAL_ON;
+        }
+      else if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
+        as_bad (_("Prefix 'd.' invalid for instruction `%s'"), insn->name);
+    }
+
   the_insn.opcode = opcode;
   the_insn.opcode = opcode;
-}
 
 
+  /* Only recognize XP instructions when the user has requested it.  */
+  if (insn->expand == XP_ONLY && ! target_xp)
+    as_bad (_("Unknown opcode: `%s'"), insn->name);
+}
 
 static int
 
 static int
-i860_get_expression (str)
-     char *str;
+i860_get_expression (char *str)
 {
   char *save_in;
   segT seg;
 
   save_in = input_line_pointer;
   input_line_pointer = str;
 {
   char *save_in;
   segT seg;
 
   save_in = input_line_pointer;
   input_line_pointer = str;
-  seg = expression (&the_insn.exp);
+  seg = expression (&the_insn.fi[fc].exp);
   if (seg != absolute_section
       && seg != undefined_section
       && ! SEG_NORMAL (seg))
   if (seg != absolute_section
       && seg != undefined_section
       && ! SEG_NORMAL (seg))
@@ -894,76 +1010,15 @@ i860_get_expression (str)
   return 0;
 }
 
   return 0;
 }
 
-
-/* Turn a string in input_line_pointer into a floating point constant of
-   type TYPE, and store the appropriate bytes in *LITP.  The number of
-   LITTLENUMS emitted is stored in *SIZEP.  An error message is returned,
-   or NULL on OK.  */
-
-/* Equal to MAX_PRECISION in atof-ieee.c.  */
-#define MAX_LITTLENUMS 6
-
-char *
-md_atof (type, litP, sizeP)
-     char type;
-     char *litP;
-     int *sizeP;
+const char *
+md_atof (int type, char *litP, int *sizeP)
 {
 {
-  int prec;
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *wordP;
-  char *t;
-  char *atof_ieee ();
-
-  switch (type)
-    {
-    case 'f':
-    case 'F':
-    case 's':
-    case 'S':
-      prec = 2;
-      break;
-
-    case 'd':
-    case 'D':
-    case 'r':
-    case 'R':
-      prec = 4;
-      break;
-
-    case 'x':
-    case 'X':
-      prec = 6;
-      break;
-
-    case 'p':
-    case 'P':
-      prec = 6;
-      break;
-
-    default:
-      *sizeP = 0;
-      return _("Bad call to MD_ATOF()");
-    }
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-  *sizeP = prec * sizeof (LITTLENUM_TYPE);
-  for (wordP = words; prec--;)
-    {
-      md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
-      litP += sizeof (LITTLENUM_TYPE);
-    }
-  return 0;
+  return ieee_md_atof (type, litP, sizeP, TRUE);
 }
 
 }
 
-
 /* Write out in current endian mode.  */
 void
 /* Write out in current endian mode.  */
 void
-md_number_to_chars (buf, val, n)
-     char *buf;
-     valueT val;
-     int n;
+md_number_to_chars (char *buf, valueT val, int n)
 {
   if (target_big_endian)
     number_to_chars_bigendian (buf, val, n);
 {
   if (target_big_endian)
     number_to_chars_bigendian (buf, val, n);
@@ -971,43 +1026,17 @@ md_number_to_chars (buf, val, n)
     number_to_chars_littleendian (buf, val, n);
 }
 
     number_to_chars_littleendian (buf, val, n);
 }
 
-
-/* This should never be called for i860.  */
-void
-md_number_to_disp (buf, val, n)
-     char *buf ATTRIBUTE_UNUSED;
-     long val ATTRIBUTE_UNUSED;
-     int n ATTRIBUTE_UNUSED;
-{
-  as_fatal (_("md_number_to_disp\n"));
-}
-
-
-/* This should never be called for i860.  */
-void
-md_number_to_field (buf, val, fix)
-     char *buf ATTRIBUTE_UNUSED;
-     long val ATTRIBUTE_UNUSED;
-     void *fix ATTRIBUTE_UNUSED;
-{
-  as_fatal (_("i860_number_to_field\n"));
-}
-
-
 /* This should never be called for i860.  */
 int
 /* This should never be called for i860.  */
 int
-md_estimate_size_before_relax (fragP, segtype)
-     register fragS *fragP ATTRIBUTE_UNUSED;
-     segT segtype ATTRIBUTE_UNUSED;
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+                              segT segtype ATTRIBUTE_UNUSED)
 {
 {
-  as_fatal (_("i860_estimate_size_before_relax\n"));
+  as_fatal (_("relaxation not supported\n"));
 }
 
 }
 
-
 #ifdef DEBUG_I860
 static void
 #ifdef DEBUG_I860
 static void
-print_insn (insn)
-     struct i860_it *insn;
+print_insn (struct i860_it *insn)
 {
   if (insn->error)
     fprintf (stderr, "ERROR: %s\n", insn->error);
 {
   if (insn->error)
     fprintf (stderr, "ERROR: %s\n", insn->error);
@@ -1031,32 +1060,31 @@ print_insn (insn)
 }
 #endif /* DEBUG_I860 */
 
 }
 #endif /* DEBUG_I860 */
 
-
 \f
 #ifdef OBJ_ELF
 \f
 #ifdef OBJ_ELF
-CONST char *md_shortopts = "VQ:";
+const char *md_shortopts = "VQ:";
 #else
 #else
-CONST char *md_shortopts = "";
+const char *md_shortopts = "";
 #endif
 
 #endif
 
-
 #define OPTION_EB              (OPTION_MD_BASE + 0)
 #define OPTION_EL              (OPTION_MD_BASE + 1)
 #define OPTION_WARN_EXPAND     (OPTION_MD_BASE + 2)
 #define OPTION_EB              (OPTION_MD_BASE + 0)
 #define OPTION_EL              (OPTION_MD_BASE + 1)
 #define OPTION_WARN_EXPAND     (OPTION_MD_BASE + 2)
+#define OPTION_XP              (OPTION_MD_BASE + 3)
+#define OPTION_INTEL_SYNTAX    (OPTION_MD_BASE + 4)
 
 struct option md_longopts[] = {
   { "EB",          no_argument, NULL, OPTION_EB },
   { "EL",          no_argument, NULL, OPTION_EL },
   { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
 
 struct option md_longopts[] = {
   { "EB",          no_argument, NULL, OPTION_EB },
   { "EL",          no_argument, NULL, OPTION_EL },
   { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND },
+  { "mxp",         no_argument, NULL, OPTION_XP },
+  { "mintel-syntax",no_argument, NULL, OPTION_INTEL_SYNTAX },
   { NULL,          no_argument, NULL, 0 }
 };
 size_t md_longopts_size = sizeof (md_longopts);
 
   { NULL,          no_argument, NULL, 0 }
 };
 size_t md_longopts_size = sizeof (md_longopts);
 
-
 int
 int
-md_parse_option (c, arg)
-     int c;
-     char *arg ATTRIBUTE_UNUSED;
+md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
 {
   switch (c)
     {
 {
   switch (c)
     {
@@ -1072,6 +1100,14 @@ md_parse_option (c, arg)
       target_warn_expand = 1;
       break;
 
       target_warn_expand = 1;
       break;
 
+    case OPTION_XP:
+      target_xp = 1;
+      break;
+
+    case OPTION_INTEL_SYNTAX:
+      target_intel_syntax = 1;
+      break;
+
 #ifdef OBJ_ELF
     /* SVR4 argument compatibility (-V): print version ID.  */
     case 'V':
 #ifdef OBJ_ELF
     /* SVR4 argument compatibility (-V): print version ID.  */
     case 'V':
@@ -1091,15 +1127,15 @@ md_parse_option (c, arg)
   return 1;
 }
 
   return 1;
 }
 
-
 void
 void
-md_show_usage (stream)
-     FILE *stream;
+md_show_usage (FILE *stream)
 {
   fprintf (stream, _("\
   -EL                    generate code for little endian mode (default)\n\
   -EB                    generate code for big endian mode\n\
 {
   fprintf (stream, _("\
   -EL                    generate code for little endian mode (default)\n\
   -EB                    generate code for big endian mode\n\
-  -mwarn-expand                  warn if pseudo operations are expanded\n"));
+  -mwarn-expand                  warn if pseudo operations are expanded\n\
+  -mxp                   enable i860XP support (disabled by default)\n\
+  -mintel-syntax         enable Intel syntax (default to AT&T/SVR4)\n"));
 #ifdef OBJ_ELF
   /* SVR4 compatibility flags.  */
   fprintf (stream, _("\
 #ifdef OBJ_ELF
   /* SVR4 compatibility flags.  */
   fprintf (stream, _("\
@@ -1111,21 +1147,18 @@ md_show_usage (stream)
 \f
 /* We have no need to default values of symbols.  */
 symbolS *
 \f
 /* We have no need to default values of symbols.  */
 symbolS *
-md_undefined_symbol (name)
-     char *name ATTRIBUTE_UNUSED;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 {
   return 0;
 }
 
-
 /* The i860 denotes auto-increment with '++'.  */
 void
 /* The i860 denotes auto-increment with '++'.  */
 void
-md_operand (exp)
-     expressionS *exp;
+md_operand (expressionS *exp)
 {
   char *s;
 
 {
   char *s;
 
-  for (s = input_line_pointer; s; s++)
+  for (s = input_line_pointer; *s; s++)
     {
       if (s[0] == '+' && s[1] == '+')
        {
     {
       if (s[0] == '+' && s[1] == '+')
        {
@@ -1136,38 +1169,31 @@ md_operand (exp)
     }
 }
 
     }
 }
 
-
 /* Round up a section size to the appropriate boundary.  */
 valueT
 /* Round up a section size to the appropriate boundary.  */
 valueT
-md_section_align (segment, size)
-     segT segment ATTRIBUTE_UNUSED;
-     valueT size ATTRIBUTE_UNUSED;
+md_section_align (segT segment ATTRIBUTE_UNUSED,
+                 valueT size ATTRIBUTE_UNUSED)
 {
   /* Byte alignment is fine.  */
   return size;
 }
 
 {
   /* Byte alignment is fine.  */
   return size;
 }
 
-
 /* On the i860, a PC-relative offset is relative to the address of the
 /* On the i860, a PC-relative offset is relative to the address of the
-   of the offset plus its size.  */
+   offset plus its size.  */
 long
 long
-md_pcrel_from (fixP)
-     fixS *fixP;
+md_pcrel_from (fixS *fixP)
 {
   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
 }
 
 {
   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
 }
 
-
 /* Determine the relocation needed for non PC-relative 16-bit immediates.
    Also adjust the given immediate as necessary.  Finally, check that
    all constraints (such as alignment) are satisfied.   */
 static bfd_reloc_code_real_type
 /* Determine the relocation needed for non PC-relative 16-bit immediates.
    Also adjust the given immediate as necessary.  Finally, check that
    all constraints (such as alignment) are satisfied.   */
 static bfd_reloc_code_real_type
-obtain_reloc_for_imm16 (fix, val)
-     fixS *fix;
-     long *val;
+obtain_reloc_for_imm16 (fixS *fix, long *val)
 {
   valueT fup = fix->fx_addnumber;
 {
   valueT fup = fix->fx_addnumber;
-  bfd_reloc_code_real_type reloc;  
+  bfd_reloc_code_real_type reloc;
 
   if (fix->fx_pcrel)
     abort ();
 
   if (fix->fx_pcrel)
     abort ();
@@ -1253,19 +1279,15 @@ obtain_reloc_for_imm16 (fix, val)
   return reloc;
 }
 
   return reloc;
 }
 
-
 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
    we will have to generate a reloc entry.  */
 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
    we will have to generate a reloc entry.  */
-int
-md_apply_fix3 (fix, valuep, seg)
-     fixS *fix;
-     valueT *valuep;
-     segT seg ATTRIBUTE_UNUSED;
-{
 
 
+void
+md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+{
   char *buf;
   char *buf;
-  long val = (long)(*valuep);
+  long val = *valP;
   unsigned long insn;
   valueT fup;
 
   unsigned long insn;
   valueT fup;
 
@@ -1279,7 +1301,7 @@ md_apply_fix3 (fix, valuep, seg)
 
   /* Determine the necessary relocations as well as inserting an
      immediate into the instruction.   */
 
   /* Determine the necessary relocations as well as inserting an
      immediate into the instruction.   */
-  if (fup == OP_IMM_U5)
+  if (fup & OP_IMM_U5)
     {
       if (val & ~0x1f)
        as_bad_where (fix->fx_file, fix->fx_line,
     {
       if (val & ~0x1f)
        as_bad_where (fix->fx_file, fix->fx_line,
@@ -1298,26 +1320,35 @@ md_apply_fix3 (fix, valuep, seg)
       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
 
       /* Insert the immediate.  */
       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
 
       /* Insert the immediate.  */
-      insn |= val & 0xffff;
-      bfd_putl32 (insn, buf);
-
-      fix->fx_done = (fix->fx_addsy == 0);
+      if (fix->fx_addsy)
+       fix->fx_done = 0;
+      else
+       {
+         insn |= val & 0xffff;
+         bfd_putl32 (insn, buf);
+         fix->fx_r_type = BFD_RELOC_NONE;
+         fix->fx_done = 1;
+       }
     }
   else if (fup & OP_IMM_U16)
     }
   else if (fup & OP_IMM_U16)
-    {
-      abort ();
-    }
+    abort ();
+
   else if (fup & OP_IMM_SPLIT16)
     {
       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
 
       /* Insert the immediate.  */
   else if (fup & OP_IMM_SPLIT16)
     {
       fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val);
 
       /* Insert the immediate.  */
-      insn |= val & 0x7ff;
-      insn |= (val & 0xf800) << 5;
-      bfd_putl32 (insn, buf);
-
-      fix->fx_done = (fix->fx_addsy == 0);
-    } 
+      if (fix->fx_addsy)
+       fix->fx_done = 0;
+      else
+       {
+         insn |= val & 0x7ff;
+         insn |= (val & 0xf800) << 5;
+         bfd_putl32 (insn, buf);
+         fix->fx_r_type = BFD_RELOC_NONE;
+         fix->fx_done = 1;
+       }
+    }
   else if (fup & OP_IMM_BR16)
     {
       if (val & 0x3)
   else if (fup & OP_IMM_BR16)
     {
       if (val & 0x3)
@@ -1327,12 +1358,19 @@ md_apply_fix3 (fix, valuep, seg)
       val = val >> 2;
 
       /* Insert the immediate.  */
       val = val >> 2;
 
       /* Insert the immediate.  */
-      insn |= (val & 0x7ff);
-      insn |= ((val & 0xf800) << 5);
-      bfd_putl32 (insn, buf);
-
-      fix->fx_r_type = BFD_RELOC_860_PC16;
-      fix->fx_done = (fix->fx_addsy == 0);
+      if (fix->fx_addsy)
+       {
+         fix->fx_done = 0;
+         fix->fx_r_type = BFD_RELOC_860_PC16;
+       }
+      else
+       {
+         insn |= (val & 0x7ff);
+         insn |= ((val & 0xf800) << 5);
+         bfd_putl32 (insn, buf);
+         fix->fx_r_type = BFD_RELOC_NONE;
+         fix->fx_done = 1;
+       }
     }
   else if (fup & OP_IMM_BR26)
     {
     }
   else if (fup & OP_IMM_BR26)
     {
@@ -1343,43 +1381,53 @@ md_apply_fix3 (fix, valuep, seg)
       val >>= 2;
 
       /* Insert the immediate.  */
       val >>= 2;
 
       /* Insert the immediate.  */
-      insn |= (val & 0x3ffffff);
-      bfd_putl32 (insn, buf);
-
-      fix->fx_r_type = BFD_RELOC_860_PC26;
-      fix->fx_done = (fix->fx_addsy == 0);
+      if (fix->fx_addsy)
+       {
+         fix->fx_r_type = BFD_RELOC_860_PC26;
+         fix->fx_done = 0;
+       }
+      else
+       {
+         insn |= (val & 0x3ffffff);
+         bfd_putl32 (insn, buf);
+         fix->fx_r_type = BFD_RELOC_NONE;
+         fix->fx_done = 1;
+       }
     }
   else if (fup != OP_NONE)
     {
     }
   else if (fup != OP_NONE)
     {
-      as_bad_where (fix->fx_file, fix->fx_line, 
-                   _("Unrecognized fix-up (0x%08x)"), fup);
+      as_bad_where (fix->fx_file, fix->fx_line,
+                   _("Unrecognized fix-up (0x%08lx)"), (unsigned long) fup);
       abort ();
     }
   else
     {
       /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
         reach here (???).  */
       abort ();
     }
   else
     {
       /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000"
         reach here (???).  */
-      insn |= (val & 0xffffffff);
-      bfd_putl32 (insn, buf);
-      fix->fx_r_type = BFD_RELOC_32;
-      fix->fx_done = (fix->fx_addsy == 0);
+      if (fix->fx_addsy)
+       {
+         fix->fx_r_type = BFD_RELOC_32;
+         fix->fx_done = 0;
+       }
+      else
+       {
+         insn |= (val & 0xffffffff);
+         bfd_putl32 (insn, buf);
+         fix->fx_r_type = BFD_RELOC_NONE;
+         fix->fx_done = 1;
+       }
     }
     }
-
-  /* Return value ignored.  */
-  return 0;
 }
 
 }
 
-
 /* Generate a machine dependent reloc from a fixup.  */
 arelent*
 /* Generate a machine dependent reloc from a fixup.  */
 arelent*
-tc_gen_reloc (section, fixp)
-     asection *section ATTRIBUTE_UNUSED;
-     fixS *fixp;
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
+             fixS *fixp)
 {
   arelent *reloc;
 
 {
   arelent *reloc;
 
-  reloc = xmalloc (sizeof (*reloc));
-  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  reloc = XNEW (arelent);
+  reloc->sym_ptr_ptr = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc->addend = fixp->fx_offset;
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc->addend = fixp->fx_offset;
@@ -1394,3 +1442,50 @@ tc_gen_reloc (section, fixp)
   return reloc;
 }
 
   return reloc;
 }
 
+/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
+   of an rs_align_code fragment.  */
+
+void
+i860_handle_align (fragS *fragp)
+{
+  /* Instructions are always stored little-endian on the i860.  */
+  static const unsigned char le_nop[] = { 0x00, 0x00, 0x00, 0xA0 };
+
+  int bytes;
+  char *p;
+
+  if (fragp->fr_type != rs_align_code)
+    return;
+
+  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+  p = fragp->fr_literal + fragp->fr_fix;
+
+  /* Make sure we are on a 4-byte boundary, in case someone has been
+     putting data into a text section.  */
+  if (bytes & 3)
+    {
+      int fix = bytes & 3;
+      memset (p, 0, fix);
+      p += fix;
+      fragp->fr_fix += fix;
+    }
+
+  memcpy (p, le_nop, 4);
+  fragp->fr_var = 4;
+}
+
+/* This is called after a user-defined label is seen.  We check
+   if the label has a double colon (valid in Intel syntax mode only),
+   in which case it should be externalized.  */
+
+void
+i860_check_label (symbolS *labelsym)
+{
+  /* At this point, the current line pointer is sitting on the character
+     just after the first colon on the label.  */
+  if (target_intel_syntax && *input_line_pointer == ':')
+    {
+      S_SET_EXTERNAL (labelsym);
+      input_line_pointer++;
+    }
+}
This page took 0.057112 seconds and 4 git commands to generate.