Regenerate configure
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
index 48a34a698977086cb22949d1e3becae069aa2db1..5100f0d8bbb00a9612ea1b237b0e127fc9f0e91c 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, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1991-2016 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,
 
 /* 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
 
 static void sbranch (int);
 static void h8300hmode (int);
 
 static void sbranch (int);
 static void h8300hmode (int);
@@ -57,6 +55,8 @@ int Smode;
 int Nmode;
 int SXmode;
 
 int Nmode;
 int SXmode;
 
+static int default_mach = bfd_mach_h8300;
+
 #define PSIZE (Hmode && !Nmode ? L_32 : L_16)
 
 static int bsize = L_8;                /* Default branch displacement.  */
 #define PSIZE (Hmode && !Nmode ? L_32 : L_16)
 
 static int bsize = L_8;                /* Default branch displacement.  */
@@ -77,10 +77,8 @@ 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
 }
 
 static void
 }
 
 static void
@@ -88,10 +86,8 @@ 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
 }
 
 static void
 }
 
 static void
@@ -100,10 +96,8 @@ 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
 }
 
 static void
 }
 
 static void
@@ -112,10 +106,8 @@ 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
 }
 
 static void
 }
 
 static void
@@ -124,10 +116,8 @@ 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
 }
 
 static void
 }
 
 static void
@@ -137,10 +127,8 @@ h8300sxnmode (int arg ATTRIBUTE_UNUSED)
   Hmode = 1;
   SXmode = 1;
   Nmode = 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
 }
 
 static void
 }
 
 static void
@@ -155,6 +143,48 @@ 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;
+  const 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
@@ -181,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
@@ -208,16 +244,14 @@ md_begin (void)
   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;
 
   nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
 
   opcode_hash_control = hash_new ();
   prev_buffer[0] = 0;
 
   nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
-  
+
   h8_instructions = (struct h8_instruction *)
     xmalloc (nopcodes * sizeof (struct h8_instruction));
 
   h8_instructions = (struct h8_instruction *)
     xmalloc (nopcodes * sizeof (struct h8_instruction));
 
@@ -232,7 +266,7 @@ md_begin (void)
     {
       struct h8_opcode *first_skipped = 0;
       int len, cmplen = 0;
     {
       struct h8_opcode *first_skipped = 0;
       int len, cmplen = 0;
-      char *src = p1->name;
+      const char *src = p1->name;
       char *dst, *buffer;
 
       if (p1->name == 0)
       char *dst, *buffer;
 
       if (p1->name == 0)
@@ -320,8 +354,8 @@ struct h8_op
 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 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);
-static void check_operand (struct h8_op *, unsigned int, char *);
+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, const 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 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);
@@ -329,7 +363,6 @@ static int parse_reg (char *, op_type *, unsigned *, int);
 static char *skip_colonthing (char *, int *);
 static char *parse_exp (char *, struct h8_op *);
 
 static char *skip_colonthing (char *, int *);
 static char *parse_exp (char *, struct h8_op *);
 
-static int constant_fits_width_p (struct h8_op *, unsigned int);
 static int constant_fits_size_p (struct h8_op *, int, int);
 
 /*
 static int constant_fits_size_p (struct h8_op *, int, int);
 
 /*
@@ -351,7 +384,7 @@ parse_reg (char *src, op_type *mode, unsigned int *reg, int direction)
   char *end;
   int len;
 
   char *end;
   int len;
 
-  /* Cribbed from get_symbol_end.  */
+  /* Cribbed from get_symbol_name.  */
   if (!is_name_beginner (*src) || *src == '\001')
     return 0;
   end = src + 1;
   if (!is_name_beginner (*src) || *src == '\001')
     return 0;
   end = src + 1;
@@ -365,36 +398,36 @@ parse_reg (char *src, op_type *mode, unsigned int *reg, int direction)
       *reg = 7;
       return len;
     }
       *reg = 7;
       return len;
     }
-  if (len == 3 && 
-      TOLOWER (src[0]) == 'c' && 
-      TOLOWER (src[1]) == 'c' && 
+  if (len == 3 &&
+      TOLOWER (src[0]) == 'c' &&
+      TOLOWER (src[1]) == 'c' &&
       TOLOWER (src[2]) == 'r')
     {
       *mode = CCR;
       *reg = 0;
       return len;
     }
       TOLOWER (src[2]) == 'r')
     {
       *mode = CCR;
       *reg = 0;
       return len;
     }
-  if (len == 3 && 
-      TOLOWER (src[0]) == 'e' && 
-      TOLOWER (src[1]) == 'x' && 
+  if (len == 3 &&
+      TOLOWER (src[0]) == 'e' &&
+      TOLOWER (src[1]) == 'x' &&
       TOLOWER (src[2]) == 'r')
     {
       *mode = EXR;
       *reg = 1;
       return len;
     }
       TOLOWER (src[2]) == 'r')
     {
       *mode = EXR;
       *reg = 1;
       return len;
     }
-  if (len == 3 && 
-      TOLOWER (src[0]) == 'v' && 
-      TOLOWER (src[1]) == 'b' && 
+  if (len == 3 &&
+      TOLOWER (src[0]) == 'v' &&
+      TOLOWER (src[1]) == 'b' &&
       TOLOWER (src[2]) == 'r')
     {
       *mode = VBR;
       *reg = 6;
       return len;
     }
       TOLOWER (src[2]) == 'r')
     {
       *mode = VBR;
       *reg = 6;
       return len;
     }
-  if (len == 3 && 
-      TOLOWER (src[0]) == 's' && 
-      TOLOWER (src[1]) == 'b' && 
+  if (len == 3 &&
+      TOLOWER (src[0]) == 's' &&
+      TOLOWER (src[1]) == 'b' &&
       TOLOWER (src[2]) == 'r')
     {
       *mode = SBR;
       TOLOWER (src[2]) == 'r')
     {
       *mode = SBR;
@@ -526,19 +559,23 @@ skip_colonthing (char *src, int *mode)
    @@aa[:8]            memory indirect.  */
 
 static int
    @@aa[:8]            memory indirect.  */
 
 static int
-constant_fits_width_p (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
 constant_fits_size_p (struct h8_op *operand, int size, int no_symbols)
 {
 }
 
 static int
 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:
@@ -552,11 +589,13 @@ constant_fits_size_p (struct h8_op *operand, int size, int 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:
@@ -582,7 +621,7 @@ get_operand (char **ptr, struct h8_op *op, int direction)
 
   /* Gross.  Gross.  ldm and stm have a format not easily handled
      by get_operand.  We deal with it explicitly here.  */
 
   /* Gross.  Gross.  ldm and stm have a format not easily handled
      by get_operand.  We deal with it explicitly here.  */
-  if (TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' && 
+  if (TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' &&
       ISDIGIT (src[2]) && src[3] == '-' &&
       TOLOWER (src[4]) == 'e' && TOLOWER (src[5]) == 'r' && ISDIGIT (src[6]))
     {
       ISDIGIT (src[2]) && src[3] == '-' &&
       TOLOWER (src[4]) == 'e' && TOLOWER (src[5]) == 'r' && ISDIGIT (src[6]))
     {
@@ -644,7 +683,7 @@ get_operand (char **ptr, struct h8_op *op, int 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;
@@ -725,7 +764,7 @@ get_operand (char **ptr, struct h8_op *op, int direction)
                }
              if (mode
                  && src[len + 2] == ','
                }
              if (mode
                  && src[len + 2] == ','
-                 && TOLOWER (src[len + 3]) != 'p' 
+                 && TOLOWER (src[len + 3]) != 'p'
                  && TOLOWER (src[len + 4]) != 'c'
                  && src[len + 5] != ')')
                {
                  && TOLOWER (src[len + 4]) != 'c'
                  && src[len + 5] != ')')
                {
@@ -787,7 +826,7 @@ get_operand (char **ptr, struct h8_op *op, int direction)
            op->mode |= DISP | direction;
          src = skip_colonthing (src, &op->mode);
 
            op->mode |= DISP | direction;
          src = skip_colonthing (src, &op->mode);
 
-         if (*src != ')' && '(')
+         if (*src != ')')
            {
              as_bad (_("expected @(exp, reg16)"));
              return;
            {
              as_bad (_("expected @(exp, reg16)"));
              return;
@@ -839,9 +878,9 @@ get_operand (char **ptr, struct h8_op *op, int direction)
       *ptr = parse_exp (src + 1, op);
       return;
     }
       *ptr = parse_exp (src + 1, op);
       return;
     }
-  else if (strncmp (src, "mach", 4) == 0 || 
+  else if (strncmp (src, "mach", 4) == 0 ||
           strncmp (src, "macl", 4) == 0 ||
           strncmp (src, "macl", 4) == 0 ||
-          strncmp (src, "MACH", 4) == 0 || 
+          strncmp (src, "MACH", 4) == 0 ||
           strncmp (src, "MACL", 4) == 0)
     {
       op->reg = TOLOWER (src[3]) == 'l';
           strncmp (src, "MACL", 4) == 0)
     {
       op->reg = TOLOWER (src[3]) == 'l';
@@ -940,7 +979,7 @@ get_mova_operands (char *op_end, struct h8_op *operand)
     }
   else if ((operand[1].mode & MODE) == LOWREG)
     {
     }
   else if ((operand[1].mode & MODE) == LOWREG)
     {
-      switch (operand[1].mode & SIZE) 
+      switch (operand[1].mode & SIZE)
        {
        case L_8:
          operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
        {
        case L_8:
          operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
@@ -1154,7 +1193,7 @@ get_specific (const struct h8_instruction *instruction,
                }
              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)
@@ -1247,7 +1286,7 @@ get_specific (const struct h8_instruction *instruction,
 }
 
 static void
 }
 
 static void
-check_operand (struct h8_op *operand, unsigned int width, char *string)
+check_operand (struct h8_op *operand, unsigned int width, const 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)
@@ -1294,14 +1333,14 @@ check_operand (struct h8_op *operand, unsigned int width, char *string)
      (may relax into an 8bit absolute address).  */
 
 static void
      (may relax into an 8bit absolute address).  */
 
 static void
-do_a_fix_imm (int offset, int 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 where;
   char *bytes = frag_now->fr_literal + offset;
 
 {
   int idx;
   int size;
   int where;
   char *bytes = frag_now->fr_literal + offset;
 
-  char *t = ((operand->mode & MODE) == IMM) ? "#" : "@";
+  const char *t = ((operand->mode & MODE) == IMM) ? "#" : "@";
 
   if (operand->exp.X_add_symbol == 0)
     {
 
   if (operand->exp.X_add_symbol == 0)
     {
@@ -1334,6 +1373,17 @@ do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int 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);
@@ -1350,7 +1400,12 @@ do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int 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;
@@ -1364,6 +1419,11 @@ do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int 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)
@@ -1410,7 +1470,7 @@ 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];
@@ -1423,12 +1483,12 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
   if (!Hmode && this_try->opcode->available != AV_H8)
     as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
             this_try->opcode->name);
   if (!Hmode && this_try->opcode->available != AV_H8)
     as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
             this_try->opcode->name);
-  else if (!Smode 
-          && this_try->opcode->available != AV_H8 
+  else if (!Smode
+          && this_try->opcode->available != AV_H8
           && this_try->opcode->available != AV_H8H)
     as_warn (_("Opcode `%s' with these operand types not available in H8/300H mode"),
             this_try->opcode->name);
           && this_try->opcode->available != AV_H8H)
     as_warn (_("Opcode `%s' with these operand types not available in H8/300H mode"),
             this_try->opcode->name);
-  else if (!SXmode 
+  else if (!SXmode
           && this_try->opcode->available != AV_H8
           && this_try->opcode->available != AV_H8H
           && this_try->opcode->available != AV_H8S)
           && this_try->opcode->available != AV_H8
           && this_try->opcode->available != AV_H8H
           && this_try->opcode->available != AV_H8S)
@@ -1570,7 +1630,7 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *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 or a bit manipulation instruction
+  /* 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)
      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)
@@ -1596,13 +1656,22 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *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)
        {
@@ -1679,7 +1748,7 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
          /* To be compatible with the proposed H8 ELF format, we
             want the relocation's offset to point to the first byte
             that will be modified, not to the start of the instruction.  */
          /* To be compatible with the proposed H8 ELF format, we
             want the relocation's offset to point to the first byte
             that will be modified, not to the start of the instruction.  */
-         
+
          if ((operand->mode & SIZE) == L_32)
            {
              where = 2;
          if ((operand->mode & SIZE) == L_32)
            {
              where = 2;
@@ -1691,8 +1760,8 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
 
          /* This jmp may be a jump or a branch.  */
 
 
          /* This jmp may be a jump or a branch.  */
 
-         check_operand (operand + i, 
-                        SXmode ? 0xffffffff : Hmode ? 0xffffff : 0xffff, 
+         check_operand (operand + i,
+                        SXmode ? 0xffffffff : Hmode ? 0xffffff : 0xffff,
                         "@");
 
          if (operand[i].exp.X_add_number & 1)
                         "@");
 
          if (operand[i].exp.X_add_number & 1)
@@ -1822,9 +1891,9 @@ fix_operand_size (struct h8_op *operand, int 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
-           && !Nmode 
-           && (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;
@@ -1833,10 +1902,14 @@ fix_operand_size (struct h8_op *operand, int 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;
@@ -2017,18 +2090,8 @@ md_assemble (char *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 (object_headers *headers ATTRIBUTE_UNUSED)
-{
-  printf (_("call to tc_crawl_symbol_chain \n"));
 }
 }
-#endif
 
 symbolS *
 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
 
 symbolS *
 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
@@ -2036,90 +2099,139 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   return 0;
 }
 
   return 0;
 }
 
-#ifndef BFD_ASSEMBLER
-void
-tc_headers_hook (object_headers *headers ATTRIBUTE_UNUSED)
+/* Various routines to kill one day.  */
+
+const 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 (int 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 (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c ATTRIBUTE_UNUSED, const 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 (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
 void tc_aout_fix_to_chars (void);
 }
 \f
 void tc_aout_fix_to_chars (void);
@@ -2132,12 +2244,7 @@ tc_aout_fix_to_chars (void)
 }
 
 void
 }
 
 void
-md_convert_frag (
-#ifdef BFD_ASSEMBLER
-                bfd *headers ATTRIBUTE_UNUSED,
-#else
-                object_headers *headers ATTRIBUTE_UNUSED,
-#endif
+md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
                 segT seg ATTRIBUTE_UNUSED,
                 fragS *fragP ATTRIBUTE_UNUSED)
 {
                 segT seg ATTRIBUTE_UNUSED,
                 fragS *fragP ATTRIBUTE_UNUSED)
 {
@@ -2145,25 +2252,15 @@ md_convert_frag (
   abort ();
 }
 
   abort ();
 }
 
-#ifdef BFD_ASSEMBLER
 valueT
 md_section_align (segT segment, valueT size)
 {
   int align = bfd_get_section_alignment (stdoutput, segment);
 valueT
 md_section_align (segT segment, valueT size)
 {
   int align = bfd_get_section_alignment (stdoutput, segment);
-  return ((size + (1 << align) - 1) & (-1 << align));
+  return ((size + (1 << align) - 1) & (-1U << align));
 }
 }
-#else
-valueT
-md_section_align (segT seg, valueT size)
-{
-  return ((size + (1 << section_alignment[(int) seg]) - 1)
-         & (-1 << section_alignment[(int) seg]));
-}
-#endif
-
 
 void
 
 void
-md_apply_fix3 (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;
@@ -2183,6 +2280,13 @@ md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       *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 ();
     }
@@ -2192,10 +2296,10 @@ md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 }
 
 int
 }
 
 int
-md_estimate_size_before_relax (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 ();
 }
 
   abort ();
 }
 
@@ -2207,71 +2311,13 @@ md_number_to_chars (char *ptr, valueT use, int nbytes)
 }
 
 long
 }
 
 long
-md_pcrel_from (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 (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 *
 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 {
 arelent *
 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 {
@@ -2284,13 +2330,13 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *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 = XNEW (arelent);
+  rel->sym_ptr_ptr = XNEW (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;
@@ -2300,7 +2346,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *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)
@@ -2313,4 +2359,3 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 
   return rel;
 }
 
   return rel;
 }
-#endif
This page took 0.042705 seconds and 4 git commands to generate.