* 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.
This commit is contained in:
Ian Lance Taylor 1993-07-15 16:02:21 +00:00
parent f09aae8404
commit c978e704a9
8 changed files with 252 additions and 19 deletions

View 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

View 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 */

View File

@ -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)

View 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 */

View 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 */

View 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 ;;

View 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
{

View 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. */