* remote.c (struct packet_reg): Declare.
[deliverable/binutils-gdb.git] / gas / config / tc-h8300.c
index 161337ce2531c53cb773d8a6c62941210bffbcbd..13be34625c0b77f3f1d8c3b606342d9b0caee0af 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-h8300.c -- Assemble code for the Hitachi H8/300
-   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 2000
-   Free Software Foundation.
+   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001
+   Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 #define DEFINE_TABLE
 #define h8_opcodes ops
 #include "opcode/h8300.h"
-#include <ctype.h>
+#include "safe-ctype.h"
+
+#ifdef OBJ_ELF
+#include "elf/h8.h"
+#endif
 
 const char comment_chars[] = ";";
 const char line_comment_chars[] = "#";
@@ -55,6 +59,10 @@ h8300hmode ()
 {
   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"));
+#endif
 }
 
 void
@@ -62,6 +70,10 @@ h8300smode ()
 {
   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"));
+#endif
 }
 
 void
@@ -117,6 +129,11 @@ md_begin ()
   char prev_buffer[100];
   int idx = 0;
 
+#ifdef BFD_ASSEMBLER
+  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300))
+    as_warn (_("could not set architecture and machine"));
+#endif
+
   opcode_hash_control = hash_new ();
   prev_buffer[0] = 0;
 
@@ -330,7 +347,7 @@ skip_colonthing (ptr, exp, mode)
            {
              *mode |= L_16;
            }
-         while (isdigit (*ptr))
+         while (ISDIGIT (*ptr))
            ptr++;
        }
     }
@@ -401,8 +418,8 @@ get_operand (ptr, op, dst, direction)
 
   /* Gross.  Gross.  ldm and stm have a format not easily handled
      by get_operand.  We deal with it explicitly here.  */
-  if (src[0] == 'e' && src[1] == 'r' && isdigit (src[2])
-      && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit (src[6]))
+  if (src[0] == 'e' && src[1] == 'r' && ISDIGIT (src[2])
+      && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && ISDIGIT (src[6]))
     {
       int low, high;
 
@@ -1081,6 +1098,7 @@ build_bytes (this_try, operand)
          int where = size16 ? 2 : 1;
          int size = size16 ? 2 : 1;
          int type = size16 ? R_PCRWORD : R_PCRBYTE;
+         fixS *fixP;
 
          check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
 
@@ -1090,16 +1108,25 @@ build_bytes (this_try, operand)
                       (unsigned long) operand->exp.X_add_number);
            }
 
+#ifndef OBJ_ELF
+         /* The COFF port has always been off by one, changing it
+            now would be an incompatible change, so we leave it as-is.
+
+            We don't want to do this for ELF as we want to be
+            compatible with the proposed ELF format from Hitachi.  */
          operand[i].exp.X_add_number -= 1;
+#endif
+
          operand[i].exp.X_add_number =
            ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
 
-         fix_new_exp (frag_now,
-                      output - frag_now->fr_literal + where,
-                      size,
-                      &operand[i].exp,
-                      1,
-                      type);
+         fixP = fix_new_exp (frag_now,
+                             output - frag_now->fr_literal + where,
+                             size,
+                             &operand[i].exp,
+                             1,
+                             type);
+         fixP->fx_signed = 1;
        }
       else if (x & MEMIND)
        {
@@ -1113,6 +1140,15 @@ build_bytes (this_try, operand)
        }
       else if (x & ABSJMP)
        {
+         int where = 0;
+
+#ifdef OBJ_ELF
+         /* 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.  */
+         where += 1;
+#endif
+
          /* This jmp may be a jump or a branch.  */
 
          check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");
@@ -1125,7 +1161,7 @@ build_bytes (this_try, operand)
            operand[i].exp.X_add_number =
              ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
          fix_new_exp (frag_now,
-                      output - frag_now->fr_literal,
+                      output - frag_now->fr_literal + where,
                       4,
                       &operand[i].exp,
                       0,
@@ -1300,12 +1336,14 @@ md_assemble (str)
   build_bytes (opcode, operand);
 }
 
+#ifndef BFD_ASSEMBLER
 void
 tc_crawl_symbol_chain (headers)
      object_headers *headers ATTRIBUTE_UNUSED;
 {
   printf (_("call to tc_crawl_symbol_chain \n"));
 }
+#endif
 
 symbolS *
 md_undefined_symbol (name)
@@ -1314,12 +1352,14 @@ md_undefined_symbol (name)
   return 0;
 }
 
+#ifndef BFD_ASSEMBLER
 void
 tc_headers_hook (headers)
      object_headers *headers ATTRIBUTE_UNUSED;
 {
   printf (_("call to tc_headers_hook \n"));
 }
+#endif
 
 /* Various routines to kill one day */
 /* Equal to MAX_PRECISION in atof-ieee.c */
@@ -1415,7 +1455,11 @@ tc_aout_fix_to_chars ()
 
 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;
 {
@@ -1423,21 +1467,43 @@ md_convert_frag (headers, seg, fragP)
   abort ();
 }
 
+#ifdef BFD_ASSEMBLER
+valueT
+md_section_align (segment, size)
+     segT segment;
+     valueT size;
+{
+  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]));
+          & (-1 << section_alignment[(int) seg]));
 }
+#endif
 
+
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+     fixS *fixP;
+     valueT *valp;
+#else
 void
 md_apply_fix (fixP, val)
      fixS *fixP;
      long val;
+#endif
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+#ifdef BFD_ASSEMBLER
+  long val = *valp;
+#endif
 
   switch (fixP->fx_size)
     {
@@ -1485,6 +1551,7 @@ md_pcrel_from (fixP)
   abort ();
 }
 
+#ifndef BFD_ASSEMBLER
 void
 tc_reloc_mangle (fix_ptr, intr, base)
      fixS *fix_ptr;
@@ -1547,3 +1614,48 @@ tc_reloc_mangle (fix_ptr, intr, base)
   else
     intr->r_symndx = -1;
 }
+#else /* BFD_ASSEMBLER */
+arelent *
+tc_gen_reloc (section, fixp)
+     asection *section ATTRIBUTE_UNUSED;
+     fixS *fixp;
+{
+  arelent *rel;
+  bfd_reloc_code_real_type r_type;
+
+  if (fixp->fx_addsy && fixp->fx_subsy)
+    {
+      if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
+         || 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");
+         return NULL;
+       }
+    }
+
+  rel = (arelent *) xmalloc (sizeof (arelent));
+  rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+  rel->addend = fixp->fx_offset;
+
+  r_type = fixp->fx_r_type;
+
+#define DEBUG 0
+#if DEBUG
+  fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
+  fflush(stderr);
+#endif
+  rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
+  if (rel->howto == NULL)
+    {
+      as_bad_where (fixp->fx_file, fixp->fx_line,
+                   _("Cannot represent relocation type %s"),
+                   bfd_get_reloc_code_name (r_type));
+      return NULL;
+    }
+
+  return rel;
+}
+#endif
This page took 0.026553 seconds and 4 git commands to generate.