From c978e704a9a21709c255feb5aa49ead641ee158e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 15 Jul 1993 16:02:21 +0000 Subject: [PATCH] * 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. --- gas/ChangeLog | 19 +++++ gas/config/obj-coffbfd.c | 4 + gas/config/obj-coffbfd.h | 14 +++- gas/config/tc-m88k.c | 170 +++++++++++++++++++++++++++++++++++++-- gas/config/tc-m88k.h | 34 +++++++- gas/configure.in | 2 + gas/read.c | 13 +-- gas/symbols.c | 15 ++++ 8 files changed, 252 insertions(+), 19 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 87b2827cbe3..8b331fd43ef 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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 diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index d62bea76445..04967397056 100644 --- a/gas/config/obj-coffbfd.c +++ b/gas/config/obj-coffbfd.c @@ -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 */ diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h index 9984a72a725..c96e6bfa121 100644 --- a/gas/config/obj-coffbfd.h +++ b/gas/config/obj-coffbfd.h @@ -64,6 +64,11 @@ #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) diff --git a/gas/config/tc-m88k.c b/gas/config/tc-m88k.c index 9f3a8e4a266..2178be3d52e 100644 --- a/gas/config/tc-m88k.c +++ b/gas/config/tc-m88k.c @@ -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 */ diff --git a/gas/config/tc-m88k.h b/gas/config/tc-m88k.h index 677cdb76ec9..eaec784ac54 100644 --- a/gas/config/tc-m88k.h +++ b/gas/config/tc-m88k.h @@ -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 */ diff --git a/gas/configure.in b/gas/configure.in index 8905e3bf456..b62ab1a24a7 100644 --- a/gas/configure.in +++ b/gas/configure.in @@ -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 ;; diff --git a/gas/read.c b/gas/read.c index 2a5dabee9ea..c3cb7113aa7 100644 --- a/gas/read.c +++ b/gas/read.c @@ -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 { diff --git a/gas/symbols.c b/gas/symbols.c index 05db99a14e1..535810f1f96 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -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. */ -- 2.30.2