* Preliminary support for m88k-coff.
authorIan Lance Taylor <ian@airs.com>
Thu, 15 Jul 1993 16:02:21 +0000 (16:02 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 15 Jul 1993 16:02:21 +0000 (16:02 +0000)
* configure.in (m88k-*-coff*): New target.  Use coffbfd and
m88kcoff.
* config/m88kcoff.mt: New file.
* read.c (lex_type): New macro LEX_AT to set lex type of '@'.
(pseudo_set): Handle difference of symbols in different fragments
by saving the entire expression as the value of the symbol.
* symbols.c (resolve_symbol_value): Resolve difference
expressions.
* config/obj-coffbfd.c (obj_pseudo_table): If TC_M88K, accept
"sdef" as a synonym for "def".
* config/obj-coffbfd.h: If TC_M88K, include coff/m88k.h and set
TARGET_FORMAT.
(S_IS_LOCAL): Any symbol which includes \001 in the name is local.
* config/tc-m88k.c, config/tc-m88k.h: Numerous changes to bring
m88k port up to date, and to add COFF support.

gas/ChangeLog
gas/config/obj-coffbfd.c
gas/config/obj-coffbfd.h
gas/config/tc-m88k.c
gas/config/tc-m88k.h
gas/configure.in
gas/read.c
gas/symbols.c

index 87b2827cbe3bd5daf7e9c68e048aaa70322b947e..8b331fd43eff056bac399cc1d911350274e510e6 100644 (file)
@@ -1,3 +1,22 @@
+Thu Jul 15 11:51:03 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * Preliminary support for m88k-coff.
+       * configure.in (m88k-*-coff*): New target.  Use coffbfd and
+       m88kcoff.
+       * config/m88kcoff.mt: New file.
+       * read.c (lex_type): New macro LEX_AT to set lex type of '@'.
+       (pseudo_set): Handle difference of symbols in different fragments
+       by saving the entire expression as the value of the symbol.
+       * symbols.c (resolve_symbol_value): Resolve difference
+       expressions.
+       * config/obj-coffbfd.c (obj_pseudo_table): If TC_M88K, accept
+       "sdef" as a synonym for "def".
+       * config/obj-coffbfd.h: If TC_M88K, include coff/m88k.h and set
+       TARGET_FORMAT.
+       (S_IS_LOCAL): Any symbol which includes \001 in the name is local.
+       * config/tc-m88k.c, config/tc-m88k.h: Numerous changes to bring
+       m88k port up to date, and to add COFF support.
+
 Wed Jul 14 15:09:32 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
        * Removed sy_forward and replaced it with an undefined expression
index d62bea7644588e3fdf9f6a1e641dcaffd7e75bfa..04967397056ae1e36d72ab3a42e397fdaa0e820a 100644 (file)
@@ -178,6 +178,10 @@ const pseudo_typeS obj_pseudo_table[] =
   {"ident", obj_coff_ident, 0},
   {"ABORT", s_abort, 0},
   {"lcomm", obj_coff_lcomm, 0},
+#ifdef TC_M88K
+  /* The m88k uses sdef instead of def.  */
+  {"sdef", obj_coff_def, 0},
+#endif
   {NULL}                       /* end sentinel */
 };                             /* obj_pseudo_table */
 
index 9984a72a725cc68a92a0f9a89c5c02ee740408b2..c96e6bfa121feda746d27f3f4c7eafe7abb04177 100644 (file)
 #define TARGET_FORMAT "coff-m68k"
 #endif
 
+#ifdef TC_M88K
+#include "coff/m88k.h"
+#define TARGET_FORMAT "coff-m88kbcs"
+#endif
+
 #ifdef TC_I386
 #include "coff/i386.h"
 #define TARGET_FORMAT "coff-i386"
@@ -156,10 +161,11 @@ obj_symbol_type;
 /* True if a debug special symbol entry */
 #define S_IS_DEBUG(s)          ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION)
 /* True if a symbol is local symbol name */
-/* A symbol name whose name begin with ^A is a gas internal pseudo symbol */
-#define S_IS_LOCAL(s)          (S_GET_NAME(s)[0] == '\001' || \
-                                (s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION || \
-                                (S_LOCAL_NAME(s) && !flagseen['L']))
+/* A symbol name whose name includes ^A is a gas internal pseudo symbol */
+#define S_IS_LOCAL(s) \
+  ((s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION \
+   || (S_LOCAL_NAME(s) && !flagseen['L']) \
+   || (strchr (s, '\001') != NULL))
 /* True if a symbol is not defined in this file */
 #define S_IS_EXTERN(s)         ((s)->sy_symbol.ost_entry.n_scnum == 0 \
                                 && S_GET_VALUE (s) == 0)
index 9f3a8e4a266fa9ac028e713564abb6cf6719eb98..2178be3d52edacffe2a802dc916145ef33ef5c02 100644 (file)
@@ -155,20 +155,19 @@ const char EXP_CHARS[] = "eE";
 /* or    0H1.234E-12 (see exp chars above) */
 const char FLT_CHARS[] = "dDfF";
 
-extern void float_cons (), cons (), s_globl (), s_line (), s_space (),
+extern void float_cons (), cons (), s_globl (), s_space (),
   s_set (), s_lcomm ();
 static void s_file ();
-static void s_bss ();
 
 const pseudo_typeS md_pseudo_table[] =
 {
+  {"align", s_align_bytes, 4},
   {"def", s_set, 0},
   {"dfloat", float_cons, 'd'},
   {"ffloat", float_cons, 'f'},
   {"global", s_globl, 0},
   {"half", cons, 2},
-  {"bss", s_bss, 0},
-  {"ln", s_line, 0},
+  {"bss", s_lcomm, 1},
   {"string", stringer, 0},
   {"word", cons, 4},
   {"zero", s_space, 0},
@@ -222,6 +221,7 @@ md_assemble (op)
      char *op;
 {
   char *param, *thisfrag;
+  char c;
   struct m88k_opcode *format;
   struct m88k_insn insn;
 
@@ -231,14 +231,46 @@ md_assemble (op)
 
   for (param = op; *param != 0 && !isspace (*param); param++)
     ;
-  if (*param != 0)
-    *param++ = 0;
+  c = *param;
+  *param++ = '\0';
 
   /* try to find the instruction in the hash table */
 
   if ((format = (struct m88k_opcode *) hash_find (op_hash, op)) == NULL)
     {
-      as_fatal ("Invalid mnemonic '%s'", op);
+      extern struct hash_control *po_hash;
+      pseudo_typeS *pop;
+      char *hold;
+
+      /* The m88k assembler does not use `.' before pseudo-ops, for
+        some reason.  So if don't find an opcode, try for a
+        pseudo-op.  */
+      pop = (pseudo_typeS *) hash_find (po_hash, op);
+
+      if (pop == NULL)
+       {
+         as_bad ("Invalid mnemonic '%s'", op);
+         return;
+       }
+
+      /* Restore the character after the opcode.  */
+      *--param = c;
+
+      /* Now we have to hack.  The pseudo-op code expects
+        input_line_pointer to point to the first non-whitespace
+        character after the pseudo-op itself.  The calling code has
+        already advanced input_line_pointer to the end of the line
+        and inserted a null byte.  We set things up for the pseudo-op
+        code, and then prepare to return from this function.  */
+      hold = input_line_pointer;
+      *hold = ';';
+      input_line_pointer = param;
+      SKIP_WHITESPACE ();
+
+      (*pop->poc_handler) (pop->poc_val);
+
+      input_line_pointer = hold;
+
       return;
     }
 
@@ -943,6 +975,11 @@ md_number_to_chars (buf, val, nbytes)
     }
 }
 
+#if 0
+
+/* This routine is never called.  What is it for?
+   Ian Taylor, Cygnus Support 13 Jul 1993 */
+
 void
 md_number_to_imm (buf, val, nbytes, fixP, seg_type)
      unsigned char *buf;
@@ -1014,6 +1051,8 @@ md_number_to_imm (buf, val, nbytes, fixP, seg_type)
     }
 }
 
+#endif /* 0 */
+
 void
 md_number_to_disp (buf, val, nbytes)
      char *buf;
@@ -1157,6 +1196,13 @@ md_end ()
 {
 }
 
+#if 0
+
+/* As far as I can tell, this routine is never called.  What is it
+   doing here?
+   Ian Taylor, Cygnus Support 13 Jul 1993 */
+
+
 /*
  * Risc relocations are completely different, so it needs
  * this machine dependent routine to emit them.
@@ -1213,6 +1259,14 @@ emit_relocations (fixP, segment_address_in_file)
   return;
 }
 
+#endif /* 0 */
+
+#if 0
+
+/* This routine can be subsumed by s_lcomm in read.c.
+   Ian Taylor, Cygnus Support 13 Jul 1993 */
+
+
 static void
 s_bss ()
 {
@@ -1290,3 +1344,105 @@ s_bss ()
 
   return;
 }
+
+#endif /* 0 */
+
+#ifdef M88KCOFF
+
+/* These functions are needed if we are linking with obj-coffbfd.c.
+   That file may be replaced by a more BFD oriented version at some
+   point.  If that happens, these functions should be rexamined.
+
+   Ian Lance Taylor, Cygnus Support, 13 July 1993.  */
+
+/* Given a fixS structure (created by a call to fix_new, above),
+   return the BFD relocation type to use for it.  */
+
+short
+tc_coff_fix2rtype (fixp)
+     fixS *fixp;
+{
+  switch (fixp->fx_r_type)
+    {
+    case RELOC_LO16:
+      return R_LVRT16;
+    case RELOC_HI16:
+      return R_HVRT16;
+    case RELOC_PC16:
+      return R_PCR16L;
+    case RELOC_PC26:
+      return R_PCR26L;
+    case RELOC_32:
+      return R_VRT32;
+    case RELOC_IW16:
+      return R_VRT16;
+    default:
+      abort ();
+    }
+}
+
+/* Apply a fixS to the object file.  Since COFF does not use addends
+   in relocs, the addend is actually stored directly in the object
+   file itself.  */
+
+void
+md_apply_fix (fixp, val)
+     fixS *fixp;
+     long val;
+{
+  char *buf;
+
+  buf = fixp->fx_frag->fr_literal + fixp->fx_where;
+
+  switch (fixp->fx_r_type)
+    {
+    case RELOC_IW16:
+      buf[2] = val >> 8;
+      buf[3] = val;
+      break;
+
+    case RELOC_LO16:
+      buf[0] = val >> 8;
+      buf[1] = val;
+      break;
+
+    case RELOC_HI16:
+      buf[0] = val >> 24;
+      buf[1] = val >> 16;
+      break;
+
+    case RELOC_PC16:
+      buf[0] = val >> 10;
+      buf[1] = val >> 2;
+      break;
+
+    case RELOC_PC26:
+      buf[0] |= (val >> 26) & 0x03;
+      buf[1] = val >> 18;
+      buf[2] = val >> 10;
+      buf[3] = val >> 2;
+      break;
+
+    case RELOC_32:
+      buf[0] = val >> 24;
+      buf[1] = val >> 16;
+      buf[2] = val >> 8;
+      buf[3] = val;
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+/* Where a PC relative offset is calculated from.  On the m88k they
+   are calculated from just after the instruction.  */
+
+long
+md_pcrel_from (fixp)
+     fixS *fixp;
+{
+  return fixp->fx_frag->fr_address + fixp->fx_where + 4;
+}
+
+#endif /* M88KCOFF */
index 677cdb76ec91278d9e0ddea4592b874b957d474d..eaec784ac5441641e28d1a86d6fbdada7804b853 100644 (file)
@@ -20,6 +20,14 @@ You should have received a copy of the GNU General Public License
 along with GAS; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#define TC_M88K
+
+#ifdef M88KCOFF
+#define COFF_MAGIC MC88OMAGIC
+#define BFD_ARCH bfd_arch_m88k
+#define COFF_FLAGS F_AR32W
+#endif
+
 #define NEED_FX_R_TYPE
 
 /* different type of relocation available in the m88k */
@@ -47,11 +55,33 @@ struct reloc_info_m88k
 
 #define relocation_info reloc_info_m88k
 
-#define LOCAL_LABEL(name) (name[0] =='@' \
-                         && ( name [1] == 'L' || name [1] == '.' ))
+/* The m88k uses '@' to start local labels.  */
+#define LEX_AT (LEX_BEGIN_NAME | LEX_NAME)
+#define LOCAL_LABEL(name) \
+  ((name[0] =='@' && (name [1] == 'L' || name [1] == '.')) \
+   || (name[0] == 'L' && name[1] == '0' && name[2] == '\001'))
 
 #ifndef BFD_ASSEMBLER
 #define md_convert_frag(h,f)           {as_fatal ("m88k convert_frag\n");}
 #else
 #define md_convert_frag(b,s,f)         {as_fatal ("m88k convert_frag\n");}
 #endif
+
+/* We don't need to do anything special for undefined symbols.  */
+#define md_undefined_symbol(s) 0
+
+/* We have no special operand handling.  */
+#define md_operand(e)
+
+#ifdef M88KCOFF
+
+/* Whether a reloc should be output.  */
+#define TC_COUNT_RELOC(fixp) ((fixp)->fx_addsy != NULL)
+
+/* Get the BFD reloc type to use for a gas fixS structure.  */
+#define TC_COFF_FIX2RTYPE(fixp) tc_coff_fix2rtype (fixp)
+
+/* No special hook needed for symbols.  */
+#define tc_coff_symbol_emit_hook(s)
+
+#endif /* M88KCOFF */
index 8905e3bf4564506ed1a7ede4e32bf4e34836a160..b62ab1a24a7e55e5e2d7465ab3ab8c3349dd1160 100644 (file)
@@ -141,6 +141,8 @@ case ${generic_target} in
                        obj_format=coffbfd gas_target=m68kcoff ;;
   m68k-*-hpux)         obj_format=hp300 emulation=hp300 ;;
 
+  m88k-*-coff*)                obj_format=coffbfd gas_target=m88kcoff ;;
+
   # don't change emulation like *-*-bsd does
   mips-*-bsd*)         bfd_gas=yes obj_format=aout gas_target=mips-lit ;;
   mips-*-ultrix*)      obj_format=ecoff gas_target=mips-lit ;;
index 2a5dabee9eaf271be77d3135d8e2774f0f3cd26c..c3cb7113aa7e44fdf8e53c4b74042329617213ad 100644 (file)
@@ -68,6 +68,11 @@ char *input_line_pointer;    /*->next char of source file to parse. */
 die horribly;
 #endif
 
+#ifndef LEX_AT
+/* The m88k unfortunately uses @ as a label beginner.  */
+#define LEX_AT 0
+#endif
+
 /* used by is_... macros. our ctype[] */
 const char lex_type[256] =
 {
@@ -75,7 +80,7 @@ const char lex_type[256] =
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /* PQRSTUVWXYZ[\]^_ */
   0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,      /* _!"#$%&'()*+,-./ */
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,      /* 0123456789:;<=>? */
-  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,      /* @ABCDEFGHIJKLMNO */
+  LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3,      /* PQRSTUVWXYZ[\]^_ */
   0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,      /* `abcdefghijklmno */
   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,      /* pqrstuvwxyz{|}~. */
@@ -1473,11 +1478,7 @@ pseudo_set (symbolP)
                S_GET_VALUE (exp.X_subtract_symbol);
              goto abs;
            }
-         as_bad ("Invalid expression: separation between symbols `%s'",
-                 S_GET_NAME (exp.X_add_symbol));
-         as_bad (" and `%s' may not be constant",
-                 S_GET_NAME (exp.X_subtract_symbol));
-         need_pass_2++;
+         symbolP->sy_value = exp;
        }
       else
        {
index 05db99a14e15d303e6598c7a32b6baa67ef3c88c..535810f1f96f69388987c1d8f46e8079b8bbc487 100644 (file)
@@ -602,6 +602,21 @@ resolve_symbol_value (symp)
                        + symp->sy_frag->fr_address
                        + S_GET_VALUE (symp->sy_value.X_add_symbol)));
        }
+      else if (symp->sy_value.X_seg == diff_section)
+       {
+         resolve_symbol_value (symp->sy_value.X_add_symbol);
+         resolve_symbol_value (symp->sy_value.X_subtract_symbol);
+         if (S_GET_SEGMENT (symp->sy_value.X_add_symbol)
+             != S_GET_SEGMENT (symp->sy_value.X_subtract_symbol))
+           as_bad ("%s is difference of symbols in different sections",
+                   S_GET_NAME (symp));
+         S_SET_VALUE (symp,
+                      (symp->sy_value.X_add_number
+                       + symp->sy_frag->fr_address
+                       + S_GET_VALUE (symp->sy_value.X_add_symbol)
+                       - S_GET_VALUE (symp->sy_value.X_subtract_symbol)));
+         S_SET_SEGMENT (symp, absolute_section);
+       }
       else
        {
          /* More cases need to be added here.  */