Fix compile time warning for tc-h8300.c when using gcc 5+.
[binutils-gdb.git] / gas / config / tc-h8300.c
index f383e79d232230175ded87bf944e15ad7b31dcda..9ff813809b7c2b097aa9020fb49e704831113b2f 100644 (file)
@@ -1,12 +1,11 @@
 /* tc-h8300.c -- Assemble code for the Renesas H8/300
 /* tc-h8300.c -- Assemble code for the Renesas H8/300
-   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-   2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1991-2015 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   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
 
    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.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /* Written By Steve Chamberlain <sac@cygnus.com>.  */
 
 
 /* Written By Steve Chamberlain <sac@cygnus.com>.  */
 
-#include <stdio.h>
 #include "as.h"
 #include "subsegs.h"
 #include "as.h"
 #include "subsegs.h"
-#include "bfd.h"
-
-#ifdef BFD_ASSEMBLER
 #include "dwarf2dbg.h"
 #include "dwarf2dbg.h"
-#endif
 
 #define DEFINE_TABLE
 #define h8_opcodes ops
 
 #define DEFINE_TABLE
 #define h8_opcodes ops
 
 const char comment_chars[] = ";";
 const char line_comment_chars[] = "#";
 
 const char comment_chars[] = ";";
 const char line_comment_chars[] = "#";
+#ifdef TE_LINUX
+const char line_separator_chars[] = "!";
+#else
 const char line_separator_chars[] = "";
 const char line_separator_chars[] = "";
+#endif
 
 
-void cons         PARAMS ((int));
-void sbranch      PARAMS ((int));
-void h8300hmode   PARAMS ((int));
-void h8300smode   PARAMS ((int));
-void h8300hnmode  PARAMS ((int));
-void h8300snmode  PARAMS ((int));
-void h8300sxmode  PARAMS ((int));
-void h8300sxnmode PARAMS ((int));
-static void pint  PARAMS ((int));
+static void sbranch (int);
+static void h8300hmode (int);
+static void h8300smode (int);
+static void h8300hnmode (int);
+static void h8300snmode (int);
+static void h8300sxmode (int);
+static void h8300sxnmode (int);
+static void pint (int);
 
 int Hmode;
 int Smode;
 int Nmode;
 int SXmode;
 
 
 int Hmode;
 int Smode;
 int Nmode;
 int SXmode;
 
-#define PSIZE (Hmode ? L_32 : L_16)
+static int default_mach = bfd_mach_h8300;
 
 
-int bsize = L_8;               /* Default branch displacement.  */
+#define PSIZE (Hmode && !Nmode ? L_32 : L_16)
+
+static int bsize = L_8;                /* Default branch displacement.  */
 
 struct h8_instruction
 {
 
 struct h8_instruction
 {
@@ -71,99 +70,121 @@ struct h8_instruction
   const struct h8_opcode *opcode;
 };
 
   const struct h8_opcode *opcode;
 };
 
-struct h8_instruction *h8_instructions;
+static struct h8_instruction *h8_instructions;
 
 
-void
-h8300hmode (arg)
-     int arg ATTRIBUTE_UNUSED;
+static void
+h8300hmode (int arg ATTRIBUTE_UNUSED)
 {
   Hmode = 1;
   Smode = 0;
 {
   Hmode = 1;
   Smode = 0;
-#ifdef BFD_ASSEMBLER
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
     as_warn (_("could not set architecture and machine"));
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
     as_warn (_("could not set architecture and machine"));
-#endif
 }
 
 }
 
-void
-h8300smode (arg)
-     int arg ATTRIBUTE_UNUSED;
+static void
+h8300smode (int arg ATTRIBUTE_UNUSED)
 {
   Smode = 1;
   Hmode = 1;
 {
   Smode = 1;
   Hmode = 1;
-#ifdef BFD_ASSEMBLER
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
     as_warn (_("could not set architecture and machine"));
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
     as_warn (_("could not set architecture and machine"));
-#endif
 }
 
 }
 
-void
-h8300hnmode (arg)
-     int arg ATTRIBUTE_UNUSED;
+static void
+h8300hnmode (int arg ATTRIBUTE_UNUSED)
 {
   Hmode = 1;
   Smode = 0;
   Nmode = 1;
 {
   Hmode = 1;
   Smode = 0;
   Nmode = 1;
-#ifdef BFD_ASSEMBLER
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300hn))
     as_warn (_("could not set architecture and machine"));
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300hn))
     as_warn (_("could not set architecture and machine"));
-#endif
 }
 
 }
 
-void
-h8300snmode (arg)
-     int arg ATTRIBUTE_UNUSED;
+static void
+h8300snmode (int arg ATTRIBUTE_UNUSED)
 {
   Smode = 1;
   Hmode = 1;
   Nmode = 1;
 {
   Smode = 1;
   Hmode = 1;
   Nmode = 1;
-#ifdef BFD_ASSEMBLER
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sn))
     as_warn (_("could not set architecture and machine"));
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sn))
     as_warn (_("could not set architecture and machine"));
-#endif
 }
 
 }
 
-void
-h8300sxmode (arg)
-     int arg ATTRIBUTE_UNUSED;
+static void
+h8300sxmode (int arg ATTRIBUTE_UNUSED)
 {
   Smode = 1;
   Hmode = 1;
   SXmode = 1;
 {
   Smode = 1;
   Hmode = 1;
   SXmode = 1;
-#ifdef BFD_ASSEMBLER
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sx))
     as_warn (_("could not set architecture and machine"));
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sx))
     as_warn (_("could not set architecture and machine"));
-#endif
 }
 
 }
 
-void
-h8300sxnmode (arg)
-     int arg ATTRIBUTE_UNUSED;
+static void
+h8300sxnmode (int arg ATTRIBUTE_UNUSED)
 {
   Smode = 1;
   Hmode = 1;
   SXmode = 1;
   Nmode = 1;
 {
   Smode = 1;
   Hmode = 1;
   SXmode = 1;
   Nmode = 1;
-#ifdef BFD_ASSEMBLER
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sxn))
     as_warn (_("could not set architecture and machine"));
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sxn))
     as_warn (_("could not set architecture and machine"));
-#endif
 }
 
 }
 
-void
-sbranch (size)
-     int size;
+static void
+sbranch (int size)
 {
   bsize = size;
 }
 
 static void
 {
   bsize = size;
 }
 
 static void
-pint (arg)
-     int arg ATTRIBUTE_UNUSED;
+pint (int arg ATTRIBUTE_UNUSED)
 {
   cons (Hmode ? 4 : 2);
 }
 
 {
   cons (Hmode ? 4 : 2);
 }
 
+/* Like obj_elf_section, but issues a warning for new
+   sections which do not have an attribute specification.  */
+
+static void
+h8300_elf_section (int push)
+{
+  static const char * known_data_sections [] = { ".rodata", ".tdata", ".tbss" };
+  static const char * known_data_prefixes [] = { ".debug", ".zdebug", ".gnu.warning" };
+  char * saved_ilp = input_line_pointer;
+  char * name;
+
+  name = obj_elf_section_name ();
+  if (name == NULL)
+    return;
+
+  if (* input_line_pointer != ','
+      && bfd_get_section_by_name (stdoutput, name) == NULL)
+    {
+      signed int i;
+
+      /* Ignore this warning for well known data sections.  */
+      for (i = ARRAY_SIZE (known_data_sections); i--;)
+       if (strcmp (name, known_data_sections[i]) == 0)
+         break;
+
+      if (i < 0)
+       for (i = ARRAY_SIZE (known_data_prefixes); i--;)
+         if (strncmp (name, known_data_prefixes[i],
+                      strlen (known_data_prefixes[i])) == 0)
+           break;
+
+      if (i < 0)
+       as_warn (_("new section '%s' defined without attributes - this might cause problems"), name);
+    }
+
+  /* FIXME: We ought to free the memory allocated by obj_elf_section_name()
+     for 'name', but we do not know if it was taken from the obstack, via
+     demand_copy_C_string(), or xmalloc()ed.  */
+  input_line_pointer = saved_ilp;
+  obj_elf_section (push);
+}
+
 /* This table describes all the machine specific pseudo-ops the assembler
    has to support.  The fields are:
    pseudo-op name without dot
 /* This table describes all the machine specific pseudo-ops the assembler
    has to support.  The fields are:
    pseudo-op name without dot
@@ -190,11 +211,17 @@ const pseudo_typeS md_pseudo_table[] =
   {"import",  s_ignore, 0},
   {"page",    listing_eject, 0},
   {"program", s_ignore, 0},
   {"import",  s_ignore, 0},
   {"page",    listing_eject, 0},
   {"program", s_ignore, 0},
+
+#ifdef OBJ_ELF
+  {"section",   h8300_elf_section, 0},
+  {"section.s", h8300_elf_section, 0},
+  {"sect",      h8300_elf_section, 0},
+  {"sect.s",    h8300_elf_section, 0},
+#endif
+
   {0, 0, 0}
 };
 
   {0, 0, 0}
 };
 
-const int md_reloc_size;
-
 const char EXP_CHARS[] = "eE";
 
 /* Chars that mean this number is a floating point constant
 const char EXP_CHARS[] = "eE";
 
 /* Chars that mean this number is a floating point constant
@@ -209,7 +236,7 @@ static struct hash_control *opcode_hash_control;    /* Opcode mnemonics.  */
    needs.  */
 
 void
    needs.  */
 
 void
-md_begin ()
+md_begin (void)
 {
   unsigned int nopcodes;
   struct h8_opcode *p, *p1;
 {
   unsigned int nopcodes;
   struct h8_opcode *p, *p1;
@@ -217,10 +244,8 @@ md_begin ()
   char prev_buffer[100];
   int idx = 0;
 
   char prev_buffer[100];
   int idx = 0;
 
-#ifdef BFD_ASSEMBLER
-  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300))
+  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, default_mach))
     as_warn (_("could not set architecture and machine"));
     as_warn (_("could not set architecture and machine"));
-#endif
 
   opcode_hash_control = hash_new ();
   prev_buffer[0] = 0;
 
   opcode_hash_control = hash_new ();
   prev_buffer[0] = 0;
@@ -319,13 +344,6 @@ md_begin ()
   linkrelax = 1;
 }
 
   linkrelax = 1;
 }
 
-struct h8_exp
-{
-  char *e_beg;
-  char *e_end;
-  expressionS e_exp;
-};
-
 struct h8_op
 {
   op_type mode;
 struct h8_op
 {
   op_type mode;
@@ -333,20 +351,19 @@ struct h8_op
   expressionS exp;
 };
 
   expressionS exp;
 };
 
-static void clever_message PARAMS ((const struct h8_instruction *, struct h8_op *));
-static void fix_operand_size PARAMS ((struct h8_op *, int));
-static void build_bytes    PARAMS ((const struct h8_instruction *, struct h8_op *));
-static void do_a_fix_imm   PARAMS ((int, int, struct h8_op *, int));
-static void check_operand  PARAMS ((struct h8_op *, unsigned int, char *));
-static const struct h8_instruction * get_specific PARAMS ((const struct h8_instruction *, struct h8_op *, int));
-static char *get_operands PARAMS ((unsigned, char *, struct h8_op *));
-static void get_operand PARAMS ((char **, struct h8_op *, int));
-static int parse_reg PARAMS ((char *, op_type *, unsigned *, int));
-static char *skip_colonthing PARAMS ((char *, int *));
-static char *parse_exp PARAMS ((char *, struct h8_op *));
-
-static int constant_fits_width_p PARAMS ((struct h8_op *, unsigned int));
-static int constant_fits_size_p PARAMS ((struct h8_op *, int, int));
+static void clever_message (const struct h8_instruction *, struct h8_op *);
+static void fix_operand_size (struct h8_op *, int);
+static void build_bytes (const struct h8_instruction *, struct h8_op *);
+static void do_a_fix_imm (int, int, struct h8_op *, int, const struct h8_instruction *);
+static void check_operand (struct h8_op *, unsigned int, char *);
+static const struct h8_instruction * get_specific (const struct h8_instruction *, struct h8_op *, int) ;
+static char *get_operands (unsigned, char *, struct h8_op *);
+static void get_operand (char **, struct h8_op *, int);
+static int parse_reg (char *, op_type *, unsigned *, int);
+static char *skip_colonthing (char *, int *);
+static char *parse_exp (char *, struct h8_op *);
+
+static int constant_fits_size_p (struct h8_op *, int, int);
 
 /*
   parse operands
 
 /*
   parse operands
@@ -362,11 +379,7 @@ static int constant_fits_size_p PARAMS ((struct h8_op *, int, int));
 /* Try to parse a reg name.  Return the number of chars consumed.  */
 
 static int
 /* Try to parse a reg name.  Return the number of chars consumed.  */
 
 static int
-parse_reg (src, mode, reg, direction)
-     char *src;
-     op_type *mode;
-     unsigned int *reg;
-     int direction;
+parse_reg (char *src, op_type *mode, unsigned int *reg, int direction)
 {
   char *end;
   int len;
 {
   char *end;
   int len;
@@ -479,9 +492,7 @@ parse_reg (src, mode, reg, direction)
    in OP->MODE, otherwise leave it for later code to decide.  */
 
 static char *
    in OP->MODE, otherwise leave it for later code to decide.  */
 
 static char *
-parse_exp (src, op)
-     char *src;
-     struct h8_op *op;
+parse_exp (char *src, struct h8_op *op)
 {
   char *save;
 
 {
   char *save;
 
@@ -501,9 +512,7 @@ parse_exp (src, op)
    in *MODE.  Leave *MODE unchanged otherwise.  */
 
 static char *
    in *MODE.  Leave *MODE unchanged otherwise.  */
 
 static char *
-skip_colonthing (src, mode)
-     char *src;
-     int *mode;
+skip_colonthing (char *src, int *mode)
 {
   if (*src == ':')
     {
 {
   if (*src == ':')
     {
@@ -550,23 +559,23 @@ skip_colonthing (src, mode)
    @@aa[:8]            memory indirect.  */
 
 static int
    @@aa[:8]            memory indirect.  */
 
 static int
-constant_fits_width_p (operand, width)
-     struct h8_op *operand;
-     unsigned int width;
+constant_fits_width_p (struct h8_op *operand, offsetT width)
 {
 {
-  return ((operand->exp.X_add_number & ~width) == 0
-         || (operand->exp.X_add_number | width) == (unsigned)(~0));
+  offsetT num;
+
+  num = ((operand->exp.X_add_number & 0xffffffff) ^ 0x80000000) - 0x80000000;
+  return (num & ~width) == 0 || (num | width) == ~0;
 }
 
 static int
 }
 
 static int
-constant_fits_size_p (operand, size, no_symbols)
-     struct h8_op *operand;
-     int size, no_symbols;
+constant_fits_size_p (struct h8_op *operand, int size, int no_symbols)
 {
 {
-  offsetT num = operand->exp.X_add_number;
+  offsetT num;
+
   if (no_symbols
       && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
     return 0;
   if (no_symbols
       && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
     return 0;
+  num = operand->exp.X_add_number & 0xffffffff;
   switch (size)
     {
     case L_2:
   switch (size)
     {
     case L_2:
@@ -580,11 +589,13 @@ constant_fits_size_p (operand, size, no_symbols)
     case L_5:
       return num >= 1 && num < 32;
     case L_8:
     case L_5:
       return num >= 1 && num < 32;
     case L_8:
-      return (num & ~0xFF) == 0 || ((unsigned)num | 0x7F) == ~0u;
+      num = (num ^ 0x80000000) - 0x80000000;
+      return (num & ~0xFF) == 0 || (num | 0x7F) == ~0;
     case L_8U:
       return (num & ~0xFF) == 0;
     case L_16:
     case L_8U:
       return (num & ~0xFF) == 0;
     case L_16:
-      return (num & ~0xFFFF) == 0 || ((unsigned)num | 0x7FFF) == ~0u;
+      num = (num ^ 0x80000000) - 0x80000000;
+      return (num & ~0xFFFF) == 0 || (num | 0x7FFF) == ~0;
     case L_16U:
       return (num & ~0xFFFF) == 0;
     case L_32:
     case L_16U:
       return (num & ~0xFFFF) == 0;
     case L_32:
@@ -595,10 +606,7 @@ constant_fits_size_p (operand, size, no_symbols)
 }
 
 static void
 }
 
 static void
-get_operand (ptr, op, direction)
-     char **ptr;
-     struct h8_op *op;
-     int direction;
+get_operand (char **ptr, struct h8_op *op, int direction)
 {
   char *src = *ptr;
   op_type mode;
 {
   char *src = *ptr;
   op_type mode;
@@ -622,15 +630,18 @@ get_operand (ptr, op, direction)
       low = src[2] - '0';
       high = src[6] - '0';
 
       low = src[2] - '0';
       high = src[6] - '0';
 
-      if (high == low)
-       as_bad (_("Invalid register list for ldm/stm\n"));
-
-      if (high < low)
+       /* Check register pair's validity as per tech note TN-H8*-193A/E
+         from Renesas for H8S and H8SX hardware manual.  */
+      if (   !(low == 0 && (high == 1 || high == 2 || high == 3))
+          && !(low == 1 && (high == 2 || high == 3 || high == 4) && SXmode)
+          && !(low == 2 && (high == 3 || ((high == 4 || high == 5) && SXmode)))
+          && !(low == 3 && (high == 4 || high == 5 || high == 6) && SXmode)
+          && !(low == 4 && (high == 5 || high == 6))
+          && !(low == 4 && high == 7 && SXmode)
+          && !(low == 5 && (high == 6 || high == 7) && SXmode)
+          && !(low == 6 && high == 7 && SXmode))
        as_bad (_("Invalid register list for ldm/stm\n"));
 
        as_bad (_("Invalid register list for ldm/stm\n"));
 
-      if (high - low > 3)
-       as_bad (_("Invalid register list for ldm/stm)\n"));
-
       /* Even sicker.  We encode two registers into op->reg.  One
         for the low register to save, the other for the high
         register to save;  we also set the high bit in op->reg
       /* Even sicker.  We encode two registers into op->reg.  One
         for the low register to save, the other for the high
         register to save;  we also set the high bit in op->reg
@@ -672,7 +683,7 @@ get_operand (ptr, op, direction)
              op->mode = (op->mode & ~SIZE) | L_8;
              break;
            default:
              op->mode = (op->mode & ~SIZE) | L_8;
              break;
            default:
-             as_warn ("invalid suffix after register.");
+             as_warn (_("invalid suffix after register."));
              break;
            }
          src += 2;
              break;
            }
          src += 2;
@@ -689,7 +700,7 @@ get_operand (ptr, op, direction)
          *ptr = parse_exp (src + 1, op);
          if (op->exp.X_add_number >= 0x100)
            {
          *ptr = parse_exp (src + 1, op);
          if (op->exp.X_add_number >= 0x100)
            {
-             int divisor;
+             int divisor = 1;
 
              op->mode = VECIND;
              /* FIXME : 2?  or 4?  */
 
              op->mode = VECIND;
              /* FIXME : 2?  or 4?  */
@@ -718,7 +729,9 @@ get_operand (ptr, op, direction)
              return;
            }
 
              return;
            }
 
-         if ((mode & SIZE) != PSIZE)
+         if (((mode & SIZE) != PSIZE)
+             /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
+             && (!Nmode || ((mode & SIZE) != L_32)))
            as_bad (_("Wrong size pointer register for architecture."));
 
          op->mode = src[0] == '-' ? RDPREDEC : RDPREINC;
            as_bad (_("Wrong size pointer register for architecture."));
 
          op->mode = src[0] == '-' ? RDPREDEC : RDPREINC;
@@ -828,7 +841,9 @@ get_operand (ptr, op, direction)
          src += len;
          if (*src == '+' || *src == '-')
            {
          src += len;
          if (*src == '+' || *src == '-')
            {
-             if ((mode & SIZE) != PSIZE)
+             if (((mode & SIZE) != PSIZE)
+                 /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
+                 && (!Nmode || ((mode & SIZE) != L_32)))
                as_bad (_("Wrong size pointer register for architecture."));
              op->mode = *src == '+' ? RSPOSTINC : RSPOSTDEC;
              op->reg = num;
                as_bad (_("Wrong size pointer register for architecture."));
              op->mode = *src == '+' ? RSPOSTINC : RSPOSTDEC;
              op->reg = num;
@@ -836,7 +851,9 @@ get_operand (ptr, op, direction)
              *ptr = src;
              return;
            }
              *ptr = src;
              return;
            }
-         if ((mode & SIZE) != PSIZE)
+         if (((mode & SIZE) != PSIZE)
+             /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
+             && (!Nmode || ((mode & SIZE) != L_32)))
            as_bad (_("Wrong size pointer register for architecture."));
 
          op->mode = direction | IND | PSIZE;
            as_bad (_("Wrong size pointer register for architecture."));
 
          op->mode = direction | IND | PSIZE;
@@ -879,10 +896,7 @@ get_operand (ptr, op, direction)
 }
 
 static char *
 }
 
 static char *
-get_operands (noperands, op_end, operand)
-     unsigned int noperands;
-     char *op_end;
-     struct h8_op *operand;
+get_operands (unsigned int noperands, char *op_end, struct h8_op *operand)
 {
   char *ptr = op_end;
 
 {
   char *ptr = op_end;
 
@@ -998,13 +1012,13 @@ get_mova_operands (char *op_end, struct h8_op *operand)
 
  error:
   as_bad (_("expected valid addressing mode for mova: \"@(disp, ea.sz),ERn\""));
 
  error:
   as_bad (_("expected valid addressing mode for mova: \"@(disp, ea.sz),ERn\""));
-  return;
 }
 
 static void
 get_rtsl_operands (char *ptr, struct h8_op *operand)
 {
 }
 
 static void
 get_rtsl_operands (char *ptr, struct h8_op *operand)
 {
-  int mode, num, num2, len, type = 0;
+  int mode, len, type = 0;
+  unsigned int num, num2;
 
   ptr++;
   if (*ptr == '(')
 
   ptr++;
   if (*ptr == '(')
@@ -1030,7 +1044,7 @@ get_rtsl_operands (char *ptr, struct h8_op *operand)
       ptr += len;
       /* CONST_xxx are used as placeholders in the opcode table.  */
       num = num2 - num;
       ptr += len;
       /* CONST_xxx are used as placeholders in the opcode table.  */
       num = num2 - num;
-      if (num < 0 || num > 3)
+      if (num > 3)
        {
          as_bad (_("invalid register list"));
          return;
        {
          as_bad (_("invalid register list"));
          return;
@@ -1054,10 +1068,8 @@ get_rtsl_operands (char *ptr, struct h8_op *operand)
    provided.  */
 
 static const struct h8_instruction *
    provided.  */
 
 static const struct h8_instruction *
-get_specific (instruction, operands, size)
-     const struct h8_instruction *instruction;
-     struct h8_op *operands;
-     int size;
+get_specific (const struct h8_instruction *instruction,
+             struct h8_op *operands, int size)
 {
   const struct h8_instruction *this_try = instruction;
   const struct h8_instruction *found_other = 0, *found_mismatched = 0;
 {
   const struct h8_instruction *this_try = instruction;
   const struct h8_instruction *found_other = 0, *found_mismatched = 0;
@@ -1181,7 +1193,7 @@ get_specific (instruction, operands, size)
                }
              else if (x_mode == IMM && op_mode != IMM)
                {
                }
              else if (x_mode == IMM && op_mode != IMM)
                {
-                 offsetT num = operands[i].exp.X_add_number;
+                 offsetT num = operands[i].exp.X_add_number & 0xffffffff;
                  if (op_mode == KBIT || op_mode == DBIT)
                    /* This is ok if the immediate value is sensible.  */;
                  else if (op_mode == CONST_2)
                  if (op_mode == KBIT || op_mode == DBIT)
                    /* This is ok if the immediate value is sensible.  */;
                  else if (op_mode == CONST_2)
@@ -1221,15 +1233,6 @@ get_specific (instruction, operands, size)
                      x |= x_size = L_32;
                    }
 
                      x |= x_size = L_32;
                    }
 
-#if 0 /* ??? */
-                 /* Promote an L8 to L_16 if it makes us match.  */
-                 if ((op_mode == ABS || op_mode == DISP) && x_size == L_8)
-                   {
-                     if (op_size == L_16)
-                       x_size = L_16;
-                   }
-#endif
-
                  if (((x_size == L_16 && op_size == L_16U)
                       || (x_size == L_8 && op_size == L_8U)
                       || (x_size == L_3 && op_size == L_3NZ))
                  if (((x_size == L_16 && op_size == L_16U)
                       || (x_size == L_8 && op_size == L_8U)
                       || (x_size == L_3 && op_size == L_3NZ))
@@ -1283,10 +1286,7 @@ get_specific (instruction, operands, size)
 }
 
 static void
 }
 
 static void
-check_operand (operand, width, string)
-     struct h8_op *operand;
-     unsigned int width;
-     char *string;
+check_operand (struct h8_op *operand, unsigned int width, char *string)
 {
   if (operand->exp.X_add_symbol == 0
       && operand->exp.X_op_symbol == 0)
 {
   if (operand->exp.X_add_symbol == 0
       && operand->exp.X_op_symbol == 0)
@@ -1333,10 +1333,7 @@ check_operand (operand, width, string)
      (may relax into an 8bit absolute address).  */
 
 static void
      (may relax into an 8bit absolute address).  */
 
 static void
-do_a_fix_imm (offset, nibble, operand, relaxmode)
-     int offset, nibble;
-     struct h8_op *operand;
-     int relaxmode;
+do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode, const struct h8_instruction *this_try)
 {
   int idx;
   int size;
 {
   int idx;
   int size;
@@ -1376,6 +1373,17 @@ do_a_fix_imm (offset, nibble, operand, relaxmode)
          check_operand (operand, 0xffff, t);
          bytes[0] |= operand->exp.X_add_number >> 8;
          bytes[1] |= operand->exp.X_add_number >> 0;
          check_operand (operand, 0xffff, t);
          bytes[0] |= operand->exp.X_add_number >> 8;
          bytes[1] |= operand->exp.X_add_number >> 0;
+#ifdef OBJ_ELF
+         /* MOVA needs both relocs to relax the second operand properly.  */
+         if (relaxmode != 0
+             && (OP_KIND(this_try->opcode->how) == O_MOVAB
+                 || OP_KIND(this_try->opcode->how) == O_MOVAW
+                 || OP_KIND(this_try->opcode->how) == O_MOVAL))
+           {
+             idx = BFD_RELOC_16;
+             fix_new_exp (frag_now, offset, 2, &operand->exp, 0, idx);
+           }
+#endif
          break;
        case L_24:
          check_operand (operand, 0xffffff, t);
          break;
        case L_24:
          check_operand (operand, 0xffffff, t);
@@ -1392,7 +1400,12 @@ do_a_fix_imm (offset, nibble, operand, relaxmode)
          bytes[3] |= operand->exp.X_add_number >> 0;
          if (relaxmode != 0)
            {
          bytes[3] |= operand->exp.X_add_number >> 0;
          if (relaxmode != 0)
            {
-             idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
+#ifdef OBJ_ELF
+             if ((operand->mode & MODE) == DISP && relaxmode == 1)
+               idx = BFD_RELOC_H8_DISP32A16;
+             else
+#endif
+               idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
              fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
            }
          break;
              fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
            }
          break;
@@ -1406,6 +1419,11 @@ do_a_fix_imm (offset, nibble, operand, relaxmode)
        case L_32:
          size = 4;
          where = (operand->mode & SIZE) == L_24 ? -1 : 0;
        case L_32:
          size = 4;
          where = (operand->mode & SIZE) == L_24 ? -1 : 0;
+#ifdef OBJ_ELF
+         if ((operand->mode & MODE) == DISP && relaxmode == 1)
+           idx = BFD_RELOC_H8_DISP32A16;
+         else
+#endif
          if (relaxmode == 2)
            idx = R_MOV24B1;
          else if (relaxmode == 1)
          if (relaxmode == 2)
            idx = R_MOV24B1;
          else if (relaxmode == 1)
@@ -1448,13 +1466,11 @@ do_a_fix_imm (offset, nibble, operand, relaxmode)
 /* Now we know what sort of opcodes it is, let's build the bytes.  */
 
 static void
 /* Now we know what sort of opcodes it is, let's build the bytes.  */
 
 static void
-build_bytes (this_try, operand)
-     const struct h8_instruction *this_try;
-     struct h8_op *operand;
+build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
 {
   int i;
   char *output = frag_more (this_try->length);
 {
   int i;
   char *output = frag_more (this_try->length);
-  op_type *nibble_ptr = this_try->opcode->data.nib;
+  const op_type *nibble_ptr = this_try->opcode->data.nib;
   op_type c;
   unsigned int nibble_count = 0;
   int op_at[3];
   op_type c;
   unsigned int nibble_count = 0;
   int op_at[3];
@@ -1614,9 +1630,23 @@ build_bytes (this_try, operand)
   for (i = 0; i < this_try->length; i++)
     output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
 
   for (i = 0; i < this_try->length; i++)
     output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
 
-  /* Note if this is a movb instruction -- there's a special relaxation
-     which only applies to them.  */
-  if (this_try->opcode->how == O (O_MOV, SB))
+  /* Note if this is a mov.b or a bit manipulation instruction
+     there is a special relaxation which only applies.  */
+  if (   this_try->opcode->how == O (O_MOV,   SB)
+      || this_try->opcode->how == O (O_BCLR,  SB)
+      || this_try->opcode->how == O (O_BAND,  SB)
+      || this_try->opcode->how == O (O_BIAND, SB)
+      || this_try->opcode->how == O (O_BILD,  SB)
+      || this_try->opcode->how == O (O_BIOR,  SB)
+      || this_try->opcode->how == O (O_BIST,  SB)
+      || this_try->opcode->how == O (O_BIXOR, SB)
+      || this_try->opcode->how == O (O_BLD,   SB)
+      || this_try->opcode->how == O (O_BNOT,  SB)
+      || this_try->opcode->how == O (O_BOR,   SB)
+      || this_try->opcode->how == O (O_BSET,  SB)
+      || this_try->opcode->how == O (O_BST,   SB)
+      || this_try->opcode->how == O (O_BTST,  SB)
+      || this_try->opcode->how == O (O_BXOR,  SB))
     movb = 1;
 
   /* Output any fixes.  */
     movb = 1;
 
   /* Output any fixes.  */
@@ -1626,13 +1656,22 @@ build_bytes (this_try, operand)
       int x_mode = x & MODE;
 
       if (x_mode == IMM || x_mode == DISP)
       int x_mode = x & MODE;
 
       if (x_mode == IMM || x_mode == DISP)
-       do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
-                     op_at[i] & 1, operand + i, (x & MEMRELAX) != 0);
-
+       {
+#ifndef OBJ_ELF
+         /* Remove MEMRELAX flag added in h8300.h on mov with
+            addressing mode "register indirect with displacement".  */
+         if (x_mode == DISP)
+           x &= ~MEMRELAX;
+#endif
+         do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
+                       op_at[i] & 1, operand + i, (x & MEMRELAX) != 0,
+                       this_try);
+       }
       else if (x_mode == ABS)
        do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
                      op_at[i] & 1, operand + i,
       else if (x_mode == ABS)
        do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
                      op_at[i] & 1, operand + i,
-                     (x & MEMRELAX) ? movb + 1 : 0);
+                     (x & MEMRELAX) ? movb + 1 : 0,
+                     this_try);
 
       else if (x_mode == PCREL)
        {
 
       else if (x_mode == PCREL)
        {
@@ -1746,9 +1785,8 @@ build_bytes (this_try, operand)
    detect errors.  */
 
 static void
    detect errors.  */
 
 static void
-clever_message (instruction, operand)
-     const struct h8_instruction *instruction;
-     struct h8_op *operand;
+clever_message (const struct h8_instruction *instruction,
+               struct h8_op *operand)
 {
   /* Find out if there was more than one possible opcode.  */
 
 {
   /* Find out if there was more than one possible opcode.  */
 
@@ -1817,9 +1855,7 @@ clever_message (instruction, operand)
    displacement in an @(d:2,ERn) operand.  */
 
 static void
    displacement in an @(d:2,ERn) operand.  */
 
 static void
-fix_operand_size (operand, size)
-     struct h8_op *operand;
-     int size;
+fix_operand_size (struct h8_op *operand, int size)
 {
   if (SXmode && (operand->mode & MODE) == DISP)
     {
 {
   if (SXmode && (operand->mode & MODE) == DISP)
     {
@@ -1855,8 +1891,9 @@ fix_operand_size (operand, size)
           is safe.  get_specific() will relax L_24 into L_32 where
           necessary.  */
        if (Hmode
           is safe.  get_specific() will relax L_24 into L_32 where
           necessary.  */
        if (Hmode
-           && (operand->exp.X_add_number < -32768
-               || operand->exp.X_add_number > 32767
+           && !Nmode 
+           && ((((addressT) operand->exp.X_add_number + 0x8000)
+                & 0xffffffff) > 0xffff
                || operand->exp.X_add_symbol != 0
                || operand->exp.X_op_symbol != 0))
          operand->mode |= L_24;
                || operand->exp.X_add_symbol != 0
                || operand->exp.X_op_symbol != 0))
          operand->mode |= L_24;
@@ -1865,10 +1902,14 @@ fix_operand_size (operand, size)
        break;
 
       case PCREL:
        break;
 
       case PCREL:
-       /* This condition is long standing, though somewhat suspect.  */
-       if (operand->exp.X_add_number > -128
-           && operand->exp.X_add_number < 127)
-         operand->mode |= L_8;
+       if ((((addressT) operand->exp.X_add_number + 0x80)
+            & 0xffffffff) <= 0xff)
+         {
+           if (operand->exp.X_add_symbol != NULL)
+             operand->mode |= bsize;
+           else
+             operand->mode |= L_8;
+         }
        else
          operand->mode |= L_16;
        break;
        else
          operand->mode |= L_16;
        break;
@@ -1881,8 +1922,7 @@ fix_operand_size (operand, size)
    the frags/bytes it assembles.  */
 
 void
    the frags/bytes it assembles.  */
 
 void
-md_assemble (str)
-     char *str;
+md_assemble (char *str)
 {
   char *op_start;
   char *op_end;
 {
   char *op_start;
   char *op_end;
@@ -1958,6 +1998,27 @@ md_assemble (str)
   *op_end = c;
   prev_instruction = instruction;
 
   *op_end = c;
   prev_instruction = instruction;
 
+  /* Now we have operands from instruction.
+     Let's check them out for ldm and stm.  */
+  if (OP_KIND (instruction->opcode->how) == O_LDM)
+    {
+      /* The first operand must be @er7+, and the
+        second operand must be a register pair.  */
+      if ((operand[0].mode != RSINC)
+           || (operand[0].reg != 7)
+           || ((operand[1].reg & 0x80000000) == 0))
+       as_bad (_("invalid operand in ldm"));
+    }
+  else if (OP_KIND (instruction->opcode->how) == O_STM)
+    {
+      /* The first operand must be a register pair,
+        and the second operand must be @-er7.  */
+      if (((operand[0].reg & 0x80000000) == 0)
+            || (operand[1].mode != RDDEC)
+            || (operand[1].reg != 7))
+       as_bad (_("invalid operand in stm"));
+    }
+
   size = SN;
   if (dot)
     {
   size = SN;
   if (dot)
     {
@@ -2029,169 +2090,177 @@ md_assemble (str)
 
   build_bytes (instruction, operand);
 
 
   build_bytes (instruction, operand);
 
-#ifdef BFD_ASSEMBLER
   dwarf2_emit_insn (instruction->length);
   dwarf2_emit_insn (instruction->length);
-#endif
 }
 
 }
 
-#ifndef BFD_ASSEMBLER
-void
-tc_crawl_symbol_chain (headers)
-     object_headers *headers ATTRIBUTE_UNUSED;
-{
-  printf (_("call to tc_crawl_symbol_chain \n"));
-}
-#endif
-
 symbolS *
 symbolS *
-md_undefined_symbol (name)
-     char *name ATTRIBUTE_UNUSED;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 {
   return 0;
 }
 
-#ifndef BFD_ASSEMBLER
-void
-tc_headers_hook (headers)
-     object_headers *headers ATTRIBUTE_UNUSED;
+/* Various routines to kill one day.  */
+
+char *
+md_atof (int type, char *litP, int *sizeP)
 {
 {
-  printf (_("call to tc_headers_hook \n"));
+  return ieee_md_atof (type, litP, sizeP, TRUE);
 }
 }
-#endif
+\f
+#define OPTION_H_TICK_HEX      (OPTION_MD_BASE)
+#define OPTION_MACH            (OPTION_MD_BASE+1)
 
 
-/* Various routines to kill one day */
-/* Equal to MAX_PRECISION in atof-ieee.c */
-#define MAX_LITTLENUMS 6
+const char *md_shortopts = "";
+struct option md_longopts[] =
+{
+  { "h-tick-hex", no_argument,       NULL, OPTION_H_TICK_HEX  },
+  { "mach", required_argument, NULL, OPTION_MACH },
+  {NULL, no_argument, NULL, 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.  */
+size_t md_longopts_size = sizeof (md_longopts);
 
 
-char *
-md_atof (type, litP, sizeP)
-     char type;
-     char *litP;
-     int *sizeP;
+struct mach_func
 {
 {
-  int prec;
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *wordP;
-  char *t;
+  const char *name;
+  void (*func) (void);
+};
 
 
-  switch (type)
-    {
-    case 'f':
-    case 'F':
-    case 's':
-    case 'S':
-      prec = 2;
-      break;
+static void
+mach_h8300h (void)
+{
+  Hmode = 1;
+  Smode = 0;
+  Nmode = 0;
+  SXmode = 0;
+  default_mach = bfd_mach_h8300h;
+}
 
 
-    case 'd':
-    case 'D':
-    case 'r':
-    case 'R':
-      prec = 4;
-      break;
+static void
+mach_h8300hn (void)
+{
+  Hmode = 1;
+  Smode = 0;
+  Nmode = 1;
+  SXmode = 0;
+  default_mach = bfd_mach_h8300hn;
+}
 
 
-    case 'x':
-    case 'X':
-      prec = 6;
-      break;
+static void
+mach_h8300s (void)
+{
+  Hmode = 1;
+  Smode = 1;
+  Nmode = 0;
+  SXmode = 0;
+  default_mach = bfd_mach_h8300s;
+}
 
 
-    case 'p':
-    case 'P':
-      prec = 6;
-      break;
+static void
+mach_h8300sn (void)
+{
+  Hmode = 1;
+  Smode = 1;
+  Nmode = 1;
+  SXmode = 0;
+  default_mach = bfd_mach_h8300sn;
+}
 
 
-    default:
-      *sizeP = 0;
-      return _("Bad call to MD_ATOF()");
-    }
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
+static void
+mach_h8300sx (void)
+{
+  Hmode = 1;
+  Smode = 1;
+  Nmode = 0;
+  SXmode = 1;
+  default_mach = bfd_mach_h8300sx;
+}
 
 
-  *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;
+static void
+mach_h8300sxn (void)
+{
+  Hmode = 1;
+  Smode = 1;
+  Nmode = 1;
+  SXmode = 1;
+  default_mach = bfd_mach_h8300sxn;
 }
 }
-\f
-const char *md_shortopts = "";
-struct option md_longopts[] = {
-  {NULL, no_argument, NULL, 0}
-};
 
 
-size_t md_longopts_size = sizeof (md_longopts);
+const struct mach_func mach_table[] =
+{
+  {"h8300h",  mach_h8300h},
+  {"h8300hn", mach_h8300hn},
+  {"h8300s",  mach_h8300s},
+  {"h8300sn", mach_h8300sn},
+  {"h8300sx", mach_h8300sx},
+  {"h8300sxn", mach_h8300sxn}
+};
 
 int
 
 int
-md_parse_option (c, arg)
-     int c ATTRIBUTE_UNUSED;
-     char *arg ATTRIBUTE_UNUSED;
+md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
 {
 {
-  return 0;
+  unsigned int i;
+  switch (c)
+    {
+    case OPTION_H_TICK_HEX:
+      enable_h_tick_hex = 1;
+      break;
+    case OPTION_MACH:
+      for (i = 0; i < sizeof(mach_table) / sizeof(struct mach_func); i++)
+       {
+         if (strcasecmp (arg, mach_table[i].name) == 0)
+           {
+             mach_table[i].func();
+             break;
+           }
+       }
+      if (i >= sizeof(mach_table) / sizeof(struct mach_func))
+       as_bad (_("Invalid argument to --mach option: %s"), arg);
+      break;
+    default:
+      return 0;
+    }
+  return 1;
 }
 
 void
 }
 
 void
-md_show_usage (stream)
-     FILE *stream ATTRIBUTE_UNUSED;
+md_show_usage (FILE *stream)
 {
 {
+  fprintf (stream, _(" H8300-specific assembler options:\n"));
+  fprintf (stream, _("\
+  -mach=<name>             Set the H8300 machine type to one of:\n\
+                           h8300h, h8300hn, h8300s, h8300sn, h8300sx, h8300sxn\n"));
+  fprintf (stream, _("\
+  -h-tick-hex              Support H'00 style hex constants\n"));
 }
 \f
 }
 \f
-void tc_aout_fix_to_chars PARAMS ((void));
+void tc_aout_fix_to_chars (void);
 
 void
 
 void
-tc_aout_fix_to_chars ()
+tc_aout_fix_to_chars (void)
 {
   printf (_("call to tc_aout_fix_to_chars \n"));
   abort ();
 }
 
 void
 {
   printf (_("call to tc_aout_fix_to_chars \n"));
   abort ();
 }
 
 void
-md_convert_frag (headers, seg, fragP)
-#ifdef BFD_ASSEMBLER
-     bfd *headers ATTRIBUTE_UNUSED;
-#else
-     object_headers *headers ATTRIBUTE_UNUSED;
-#endif
-     segT seg ATTRIBUTE_UNUSED;
-     fragS *fragP ATTRIBUTE_UNUSED;
+md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
+                segT seg ATTRIBUTE_UNUSED,
+                fragS *fragP ATTRIBUTE_UNUSED)
 {
   printf (_("call to md_convert_frag \n"));
   abort ();
 }
 
 {
   printf (_("call to md_convert_frag \n"));
   abort ();
 }
 
-#ifdef BFD_ASSEMBLER
 valueT
 valueT
-md_section_align (segment, size)
-     segT segment;
-     valueT size;
+md_section_align (segT segment, valueT size)
 {
   int align = bfd_get_section_alignment (stdoutput, segment);
 {
   int align = bfd_get_section_alignment (stdoutput, segment);
-  return ((size + (1 << align) - 1) & (-1 << align));
-}
-#else
-valueT
-md_section_align (seg, size)
-     segT seg;
-     valueT size;
-{
-  return ((size + (1 << section_alignment[(int) seg]) - 1)
-         & (-1 << section_alignment[(int) seg]));
+  return ((size + (1 << align) - 1) & (-1U << align));
 }
 }
-#endif
-
 
 void
 
 void
-md_apply_fix3 (fixP, valP, seg)
-     fixS *fixP;
-     valueT *valP;
-     segT seg ATTRIBUTE_UNUSED;
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   long val = *valP;
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   long val = *valP;
@@ -2211,6 +2280,13 @@ md_apply_fix3 (fixP, valP, seg)
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
       *buf++ = (val >> 8);
       *buf++ = val;
       break;
+    case 8:
+      /* This can arise when the .quad or .8byte pseudo-ops are used.
+        Returning here (without setting fx_done) will cause the code
+        to attempt to generate a reloc which will then fail with the
+        slightly more helpful error message: "Cannot represent
+        relocation type BFD_RELOC_64".  */
+      return;
     default:
       abort ();
     }
     default:
       abort ();
     }
@@ -2220,99 +2296,30 @@ md_apply_fix3 (fixP, valP, seg)
 }
 
 int
 }
 
 int
-md_estimate_size_before_relax (fragP, segment_type)
-     register fragS *fragP ATTRIBUTE_UNUSED;
-     register segT segment_type ATTRIBUTE_UNUSED;
+md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
+                              segT segment_type ATTRIBUTE_UNUSED)
 {
 {
-  printf (_("call tomd_estimate_size_before_relax \n"));
+  printf (_("call to md_estimate_size_before_relax \n"));
   abort ();
 }
 
 /* Put number into target byte order.  */
 void
   abort ();
 }
 
 /* Put number into target byte order.  */
 void
-md_number_to_chars (ptr, use, nbytes)
-     char *ptr;
-     valueT use;
-     int nbytes;
+md_number_to_chars (char *ptr, valueT use, int nbytes)
 {
   number_to_chars_bigendian (ptr, use, nbytes);
 }
 
 long
 {
   number_to_chars_bigendian (ptr, use, nbytes);
 }
 
 long
-md_pcrel_from (fixP)
-     fixS *fixP ATTRIBUTE_UNUSED;
+md_pcrel_from (fixS *fixp)
 {
 {
-  abort ();
+  as_bad_where (fixp->fx_file, fixp->fx_line,
+               _("Unexpected reference to a symbol in a non-code section"));
+  return 0;
 }
 
 }
 
-#ifndef BFD_ASSEMBLER
-void
-tc_reloc_mangle (fix_ptr, intr, base)
-     fixS *fix_ptr;
-     struct internal_reloc *intr;
-     bfd_vma base;
-
-{
-  symbolS *symbol_ptr;
-
-  symbol_ptr = fix_ptr->fx_addsy;
-
-  /* If this relocation is attached to a symbol then it's ok
-     to output it.  */
-  if (fix_ptr->fx_r_type == TC_CONS_RELOC)
-    {
-      /* cons likes to create reloc32's whatever the size of the reloc..
-       */
-      switch (fix_ptr->fx_size)
-       {
-       case 4:
-         intr->r_type = R_RELLONG;
-         break;
-       case 2:
-         intr->r_type = R_RELWORD;
-         break;
-       case 1:
-         intr->r_type = R_RELBYTE;
-         break;
-       default:
-         abort ();
-       }
-    }
-  else
-    {
-      intr->r_type = fix_ptr->fx_r_type;
-    }
-
-  intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
-  intr->r_offset = fix_ptr->fx_offset;
-
-  if (symbol_ptr)
-    {
-      if (symbol_ptr->sy_number != -1)
-       intr->r_symndx = symbol_ptr->sy_number;
-      else
-       {
-         symbolS *segsym;
-
-         /* This case arises when a reference is made to `.'.  */
-         segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;
-         if (segsym == NULL)
-           intr->r_symndx = -1;
-         else
-           {
-             intr->r_symndx = segsym->sy_number;
-             intr->r_offset += S_GET_VALUE (symbol_ptr);
-           }
-       }
-    }
-  else
-    intr->r_symndx = -1;
-}
-#else /* BFD_ASSEMBLER */
 arelent *
 arelent *
-tc_gen_reloc (section, fixp)
-     asection *section ATTRIBUTE_UNUSED;
-     fixS *fixp;
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 {
   arelent *rel;
   bfd_reloc_code_real_type r_type;
 {
   arelent *rel;
   bfd_reloc_code_real_type r_type;
@@ -2323,13 +2330,13 @@ tc_gen_reloc (section, fixp)
          || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
        {
          as_bad_where (fixp->fx_file, fixp->fx_line,
          || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
        {
          as_bad_where (fixp->fx_file, fixp->fx_line,
-                       "Difference of symbols in different sections is not supported");
+                       _("Difference of symbols in different sections is not supported"));
          return NULL;
        }
     }
 
          return NULL;
        }
     }
 
-  rel = (arelent *) xmalloc (sizeof (arelent));
-  rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  rel = xmalloc (sizeof (arelent));
+  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
   rel->addend = fixp->fx_offset;
   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
   rel->addend = fixp->fx_offset;
@@ -2339,7 +2346,7 @@ tc_gen_reloc (section, fixp)
 #define DEBUG 0
 #if DEBUG
   fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
 #define DEBUG 0
 #if DEBUG
   fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
-  fflush(stderr);
+  fflush (stderr);
 #endif
   rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
   if (rel->howto == NULL)
 #endif
   rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
   if (rel->howto == NULL)
@@ -2352,4 +2359,3 @@ tc_gen_reloc (section, fixp)
 
   return rel;
 }
 
   return rel;
 }
-#endif