X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m88k.c;h=f77460a0caf0050db9601a6f75661782857f0c89;hb=7dcc9865504dca99a950c4d11d54c3a3a5f0b8c9;hp=67edb55963393d93c4ece72f6dd625e6987e13d7;hpb=90d85bc42b2c6a71cb0b9da4db9c92648b965314;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m88k.c b/gas/config/tc-m88k.c index 67edb55963..f77460a0ca 100644 --- a/gas/config/tc-m88k.c +++ b/gas/config/tc-m88k.c @@ -1,13 +1,14 @@ /* m88k.c -- Assembler for the Motorola 88000 Contributed by Devon Bowen of Buffalo University and Torbjorn Granlund of the Swedish Institute of Computer Science. - Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 + 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 -the Free Software Foundation; either version 1, or (at your option) +the Free Software Foundation; either version 2, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -16,37 +17,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 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. */ +along with GAS; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ #include -#include "m88k-opcode.h" #include "as.h" -#include "frags.h" -#include "struc-symbol.h" -#include "flonum.h" -#include "expr.h" -#include "hash.h" -#include "md.h" -#include "m88k.h" -#include "write.h" -#include "read.h" -/* -#include "obstack.h" -#include "struc-symbol.h" -*/ -#include "symbols.h" - -char *getval (); -char *get_reg (); -char *get_imm16 (); -char *get_bf (); -char *get_pcr (); -char *get_cmp (); -char *get_cnd (); -char *get_cr (); -char *get_fcr (); -char *get_vec9 (); +#include "subsegs.h" +#include "m88k-opcode.h" struct field_val_assoc { @@ -101,9 +79,9 @@ struct field_val_assoc fcr_regs[] = struct field_val_assoc cmpslot[] = { -/* Integer Floating point */ - {"nc", 0}, - {"cp", 1}, +/* Integer Floating point */ + {"nc", 0}, + {"cp", 1}, {"eq", 2}, {"ne", 3}, {"gt", 4}, @@ -114,6 +92,12 @@ struct field_val_assoc cmpslot[] = {"ls", 9}, {"ib", 9}, {"lo", 10}, {"in", 10}, {"hs", 11}, {"ob", 11}, + {"be", 12}, {"ue", 12}, + {"nb", 13}, {"lg", 13}, + {"he", 14}, {"ug", 14}, + {"nh", 15}, {"ule", 15}, + {"ul", 16}, + {"uge", 17}, {NULL, 0}, }; @@ -137,61 +121,76 @@ struct m88k_insn enum reloc_type reloc; }; +static char *get_bf PARAMS ((char *param, unsigned *valp)); +static char *get_cmp PARAMS ((char *param, unsigned *valp)); +static char *get_cnd PARAMS ((char *param, unsigned *valp)); +static char *get_cr PARAMS ((char *param, unsigned *regnop)); +static char *get_fcr PARAMS ((char *param, unsigned *regnop)); +static char *get_imm16 PARAMS ((char *param, struct m88k_insn *insn)); +static char *get_o6 PARAMS ((char *param, unsigned *valp)); +static char *get_reg PARAMS ((char *param, unsigned *regnop, int reg_prefix)); +static char *get_vec9 PARAMS ((char *param, unsigned *valp)); +static char *getval PARAMS ((char *param, unsigned int *valp)); + +static char *get_pcr PARAMS ((char *param, struct m88k_insn *insn, + enum reloc_type reloc)); + +static int calcop PARAMS ((struct m88k_opcode *format, + char *param, struct m88k_insn *insn)); + + extern char *myname; static struct hash_control *op_hash = NULL; /* These bits should be turned off in the first address of every segment */ int md_seg_align = 7; -/* This is the number to put at the beginning of the a.out file */ -long omagic = OMAGIC; - /* These chars start a comment anywhere in a source file (except inside another comment */ -char comment_chars[] = ";"; +const char comment_chars[] = ";"; /* These chars only start a comment at the beginning of a line. */ -char line_comment_chars[] = "#"; +const char line_comment_chars[] = "#"; + +const char line_separator_chars[] = ""; /* Chars that can be used to separate mant from exp in floating point nums */ -char EXP_CHARS[] = "eE"; +const char EXP_CHARS[] = "eE"; /* Chars that mean this number is a floating point constant */ /* as in 0f123.456 */ /* or 0H1.234E-12 (see exp chars above) */ -char FLT_CHARS[] = "dDfF"; +const char FLT_CHARS[] = "dDfF"; -extern void float_cons (), cons (), s_globl (), s_line (), - s_space (), s_set (), stringer (), s_lcomm (); -static void s_file (); -static void s_bss (); +extern void float_cons (), cons (), s_globl (), s_space (), + s_set (), s_lcomm (); 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}, + {"half", cons, 2}, + {"bss", s_lcomm, 1}, {"string", stringer, 0}, - {"word", cons, 4 }, - {"zero", s_space, 0}, + {"word", cons, 4}, + /* Force set to be treated as an instruction. */ + {"set", NULL, 0}, + {".set", s_set, 0}, {0} }; void md_begin () { - char *retval = NULL; + const char *retval = NULL; unsigned int i = 0; /* initialize hash table */ op_hash = hash_new (); - if (op_hash == NULL) - as_fatal ("Could not initialize hash table"); /* loop until you see the end of the list */ @@ -203,9 +202,9 @@ md_begin () retval = hash_insert (op_hash, name, &m88k_opcodes[i]); - if (retval != NULL && *retval != '\0') - as_fatal ("Can't hash instruction '%s':%s", - m88k_opcodes[i].name, retval); + if (retval != NULL) + as_fatal (_("Can't hash instruction '%s':%s"), + m88k_opcodes[i].name, retval); /* skip to next unique mnemonic or end of list */ @@ -213,21 +212,33 @@ md_begin () ; } } + +CONST char *md_shortopts = ""; +struct option md_longopts[] = { + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof(md_longopts); -void -md_parse_option (argP, cntP, vecP) - char **argP; - int *cntP; - char ***vecP; +int +md_parse_option (c, arg) + int c; + char *arg; { - as_warn ("unknown option: -%s", *argP); + return 0; } +void +md_show_usage (stream) + FILE *stream; +{ +} + void md_assemble (op) char *op; { char *param, *thisfrag; + char c; struct m88k_opcode *format; struct m88k_insn insn; @@ -237,23 +248,23 @@ 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); + as_bad (_("Invalid mnemonic '%s'"), op); return; } /* try parsing this instruction into insn */ insn.exp.X_add_symbol = 0; - insn.exp.X_subtract_symbol = 0; + insn.exp.X_op_symbol = 0; insn.exp.X_add_number = 0; - insn.exp.X_seg = 0; + insn.exp.X_op = O_illegal; insn.reloc = NO_RELOC; while (!calcop (format, param, &insn)) @@ -264,7 +275,7 @@ md_assemble (op) format++; else { - as_fatal ("Parameter syntax error"); + as_fatal (_("Parameter syntax error")); return; } } @@ -283,56 +294,48 @@ md_assemble (op) case RELOC_LO16: case RELOC_HI16: - fix_new (frag_now, - thisfrag - frag_now->fr_literal + 2, - 2, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 0, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal + 2, + 2, + &insn.exp, + 0, + insn.reloc); break; case RELOC_IW16: - fix_new (frag_now, - thisfrag - frag_now->fr_literal, - 4, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 0, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal, + 4, + &insn.exp, + 0, + insn.reloc); break; case RELOC_PC16: - fix_new (frag_now, - thisfrag - frag_now->fr_literal + 2, - 2, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 1, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal + 2, + 2, + &insn.exp, + 1, + insn.reloc); break; case RELOC_PC26: - fix_new (frag_now, - thisfrag - frag_now->fr_literal, - 4, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 1, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal, + 4, + &insn.exp, + 1, + insn.reloc); break; default: - as_fatal ("Unknown relocation type"); + as_fatal (_("Unknown relocation type")); break; } } -int +static int calcop (format, param, insn) struct m88k_opcode *format; char *param; @@ -342,6 +345,7 @@ calcop (format, param, insn) int f; unsigned val; unsigned opcode; + int reg_prefix = 'r'; insn->opcode = format->opcode; opcode = 0; @@ -355,7 +359,7 @@ calcop (format, param, insn) { case 0: insn->opcode |= opcode; - return *param == 0; + return (*param == 0 || *param == '\n'); default: if (f != *param++) @@ -363,22 +367,34 @@ calcop (format, param, insn) break; case 'd': - param = get_reg (param, &val); + param = get_reg (param, &val, reg_prefix); + reg_prefix = 'r'; opcode |= val << 21; break; + case 'o': + param = get_o6 (param, &val); + opcode |= ((val >> 2) << 7); + break; + + case 'x': + reg_prefix = 'x'; + break; + case '1': - param = get_reg (param, &val); + param = get_reg (param, &val, reg_prefix); + reg_prefix = 'r'; opcode |= val << 16; break; case '2': - param = get_reg (param, &val); + param = get_reg (param, &val, reg_prefix); + reg_prefix = 'r'; opcode |= val; break; case '3': - param = get_reg (param, &val); + param = get_reg (param, &val, 'r'); opcode |= (val << 16) | val; break; @@ -427,13 +443,13 @@ calcop (format, param, insn) case '?': /* Having this here repeats the warning somtimes. But can't we stand that? */ - as_warn ("Use of obsolete instruction"); + as_warn (_("Use of obsolete instruction")); break; } } } -char * +static char * match_name (param, assoc_tab, valp) char *param; struct field_val_assoc *assoc_tab; @@ -457,16 +473,17 @@ match_name (param, assoc_tab, valp) } } -char * -get_reg (param, regnop) +static char * +get_reg (param, regnop, reg_prefix) char *param; unsigned *regnop; + int reg_prefix; { unsigned c; unsigned regno; c = *param++; - if (c == 'r') + if (c == reg_prefix) { regno = *param++ - '0'; if (regno < 10) @@ -503,14 +520,13 @@ get_reg (param, regnop) return 0; } -char * +static char * get_imm16 (param, insn) char *param; struct m88k_insn *insn; { enum reloc_type reloc = NO_RELOC; unsigned int val; - segT seg; char *save_ptr; if (!strncmp (param, "hi16", 4) && !isalnum (param[4])) @@ -531,20 +547,20 @@ get_imm16 (param, insn) save_ptr = input_line_pointer; input_line_pointer = param; - seg = expression (&insn->exp); + expression (&insn->exp); param = input_line_pointer; input_line_pointer = save_ptr; val = insn->exp.X_add_number; - if (seg == SEG_ABSOLUTE) + if (insn->exp.X_op == O_constant) { /* Insert the value now, and reset reloc to NO_RELOC. */ if (reloc == NO_RELOC) { /* Warn about too big expressions if not surrounded by xx16. */ if (val > 0xffff) - as_warn ("Expression truncated to 16 bits"); + as_warn (_("Expression truncated to 16 bits")); } if (reloc == RELOC_HI16) @@ -563,30 +579,29 @@ get_imm16 (param, insn) return param; } -char * +static char * get_pcr (param, insn, reloc) char *param; struct m88k_insn *insn; enum reloc_type reloc; { char *saveptr, *saveparam; - segT seg; saveptr = input_line_pointer; input_line_pointer = param; - seg = expression (&insn->exp); + expression (&insn->exp); saveparam = input_line_pointer; input_line_pointer = saveptr; - /* Botch: We should relocate now if SEG_ABSOLUTE. */ + /* Botch: We should relocate now if O_constant. */ insn->reloc = reloc; return saveparam; } -char * +static char * get_cmp (param, valp) char *param; unsigned *valp; @@ -611,7 +626,7 @@ get_cmp (param, valp) if (val >= 32) { - as_warn ("Expression truncated to 5 bits"); + as_warn (_("Expression truncated to 5 bits")); val %= 32; } } @@ -620,7 +635,7 @@ get_cmp (param, valp) return param; } -char * +static char * get_cnd (param, valp) char *param; unsigned *valp; @@ -633,7 +648,7 @@ get_cnd (param, valp) if (val >= 32) { - as_warn ("Expression truncated to 5 bits"); + as_warn (_("Expression truncated to 5 bits")); val %= 32; } } @@ -657,7 +672,7 @@ get_cnd (param, valp) return param; } -char * +static char * get_bf2 (param, bc) char *param; int bc; @@ -680,7 +695,7 @@ get_bf2 (param, bc) } } -char * +static char * get_bf_offset_expression (param, offsetp) char *param; unsigned *offsetp; @@ -709,7 +724,7 @@ get_bf_offset_expression (param, offsetp) return param; } -char * +static char * get_bf (param, valp) char *param; unsigned *valp; @@ -727,9 +742,9 @@ get_bf (param, valp) { /* We did not find '<'. We have an offset (width implicitly 32). */ param = get_bf_offset_expression (param, &offset); + input_line_pointer = save_ptr; if (param == NULL) return NULL; - input_line_pointer = save_ptr; } else { @@ -740,7 +755,7 @@ get_bf (param, valp) *param++ = 0; /* Overwrite the '>' */ width = get_absolute_expression (); - xp = get_bf_offset_expression (xp, &offset); + xp = get_bf_offset_expression (xp, &offset); input_line_pointer = save_ptr; if (xp + 1 != param) @@ -752,15 +767,13 @@ get_bf (param, valp) return param; } -char * +static char * get_cr (param, regnop) char *param; unsigned *regnop; { unsigned regno; unsigned c; - int i; - int name_len; if (!strncmp (param, "cr", 2)) { @@ -798,15 +811,13 @@ get_cr (param, regnop) return param; } -char * +static char * get_fcr (param, regnop) char *param; unsigned *regnop; { unsigned regno; unsigned c; - int i; - int name_len; if (!strncmp (param, "fcr", 3)) { @@ -844,7 +855,7 @@ get_fcr (param, regnop) return param; } -char * +static char * get_vec9 (param, valp) char *param; unsigned *valp; @@ -859,19 +870,41 @@ get_vec9 (param, valp) input_line_pointer = save_ptr; if (val >= 1 << 9) - as_warn ("Expression truncated to 9 bits"); + as_warn (_("Expression truncated to 9 bits")); *valp = val % (1 << 9); return param; } - + +static char * +get_o6 (param, valp) + char *param; + unsigned *valp; +{ + unsigned val; + char *save_ptr; + + save_ptr = input_line_pointer; + input_line_pointer = param; + val = get_absolute_expression (); + param = input_line_pointer; + input_line_pointer = save_ptr; + + if (val & 0x3) + as_warn (_("Removed lower 2 bits of expression")); + + *valp = val; + + return(param); +} + #define hexval(z) \ (isdigit (z) ? (z) - '0' : \ islower (z) ? (z) - 'a' + 10 : \ isupper (z) ? (z) - 'A' + 10 : -1) -char * +static char * getval (param, valp) char *param; unsigned int *valp; @@ -920,33 +953,25 @@ getval (param, valp) void md_number_to_chars (buf, val, nbytes) -char *buf; -int val; -int nbytes; + char *buf; + valueT val; + int nbytes; { - switch (nbytes) - { - case 4: - *buf++ = val >> 24; - *buf++ = val >> 16; - case 2: - *buf++ = val >> 8; - case 1: - *buf = val; - break; - - default: - abort (); - } + number_to_chars_bigendian (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; -unsigned int val; -int nbytes; -fixS *fixP; -int seg_type; + unsigned char *buf; + unsigned int val; + int nbytes; + fixS *fixP; + int seg_type; { if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC) { @@ -1006,28 +1031,30 @@ int seg_type; break; default: - as_fatal ("Bad relocation type"); + as_fatal (_("Bad relocation type")); break; } } +#endif /* 0 */ + void md_number_to_disp (buf, val, nbytes) -char *buf; -int val; -int nbytes; + char *buf; + int val; + int nbytes; { - as_fatal ("md_number_to_disp not defined"); + as_fatal (_("md_number_to_disp not defined")); md_number_to_chars (buf, val, nbytes); } void md_number_to_field (buf, val, nbytes) -char *buf; -int val; -int nbytes; + char *buf; + int val; + int nbytes; { - as_fatal ("md_number_to_field not defined"); + as_fatal (_("md_number_to_field not defined")); md_number_to_chars (buf, val, nbytes); } @@ -1043,11 +1070,10 @@ md_atof (type, litP, sizeP) char *litP; int *sizeP; { - int prec; + int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; LITTLENUM_TYPE *wordP; - char *t; - char *atof_ieee (); + char *t; switch (type) { @@ -1076,20 +1102,20 @@ md_atof (type, litP, sizeP) break; default: - *sizeP=0; - return "Bad call to MD_ATOF()"; + *sizeP = 0; + return _("Bad call to MD_ATOF()"); } - t=atof_ieee (input_line_pointer, type, words); + t = atof_ieee (input_line_pointer, type, words); if (t) - input_line_pointer=t; + input_line_pointer = t; - *sizeP=prec * sizeof (LITTLENUM_TYPE); - for (wordP=words;prec--;) + *sizeP = prec * sizeof (LITTLENUM_TYPE); + for (wordP = words; prec--;) { md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); - litP+=sizeof (LITTLENUM_TYPE); + litP += sizeof (LITTLENUM_TYPE); } - return ""; /* Someone should teach Dean about null pointers */ + return 0; } int md_short_jump_size = 4; @@ -1097,17 +1123,19 @@ int md_short_jump_size = 4; void md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) char *ptr; - long from_addr, to_addr; + addressT from_addr, to_addr; fragS *frag; symbolS *to_symbol; { - ptr[0] = 0xc0; ptr[1] = 0x00; ptr[2] = 0x00; ptr[3] = 0x00; + ptr[0] = (char) 0xc0; + ptr[1] = 0x00; + ptr[2] = 0x00; + ptr[3] = 0x00; fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, - (symbolS *) 0, - (long int) 0, + (offsetT) 0, 0, RELOC_PC26); /* Botch: Shouldn't this be RELOC_PC16? */ } @@ -1117,17 +1145,19 @@ int md_long_jump_size = 4; void md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) char *ptr; - long from_addr, to_addr; + addressT from_addr, to_addr; fragS *frag; symbolS *to_symbol; { - ptr[0] = 0xc0; ptr[1] = 0x00; ptr[2] = 0x00; ptr[3] = 0x00; + ptr[0] = (char) 0xc0; + ptr[1] = 0x00; + ptr[2] = 0x00; + ptr[3] = 0x00; fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, - (symbolS *) 0, - (long int) 0, + (offsetT) 0, 0, RELOC_PC26); } @@ -1135,24 +1165,18 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) int md_estimate_size_before_relax (fragP, segment_type) fragS *fragP; - int segment_type; + segT segment_type; { - as_fatal ("Relaxation should never occur"); + as_fatal (_("Relaxation should never occur")); + return (-1); } -const relax_typeS md_relax_table[] = {0}; +#if 0 -void -md_convert_frag (fragP) - fragS *fragP; -{ - as_fatal ("Relaxation should never occur"); -} +/* As far as I can tell, this routine is never called. What is it + doing here? + Ian Taylor, Cygnus Support 13 Jul 1993 */ -void -md_end () -{ -} /* * Risc relocations are completely different, so it needs @@ -1160,109 +1184,269 @@ md_end () */ void emit_relocations (fixP, segment_address_in_file) - fixS *fixP; - relax_addressT segment_address_in_file; + fixS *fixP; + relax_addressT segment_address_in_file; { - struct reloc_info_m88k ri; - symbolS *symbolP; - extern char *next_object_file_charP; - - bzero ((char *) &ri, sizeof (ri)); - for (; fixP; fixP = fixP->fx_next) { + struct reloc_info_m88k ri; + symbolS *symbolP; + extern char *next_object_file_charP; - if (fixP->fx_r_type >= NO_RELOC) { - fprintf (stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type); - abort (); + bzero ((char *) &ri, sizeof (ri)); + for (; fixP; fixP = fixP->fx_next) + { + if (fixP->fx_r_type >= NO_RELOC) + { + fprintf (stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type); + abort (); } - if ((symbolP = fixP->fx_addsy) != NULL) { - ri.r_address = fixP->fx_frag->fr_address + - fixP->fx_where - segment_address_in_file; - if ((symbolP->sy_type & N_TYPE) == N_UNDF) { - ri.r_extern = 1; - ri.r_symbolnum = symbolP->sy_number; - } else { - ri.r_extern = 0; - ri.r_symbolnum = symbolP->sy_type & N_TYPE; + if ((symbolP = fixP->fx_addsy) != NULL) + { + ri.r_address = fixP->fx_frag->fr_address + + fixP->fx_where - segment_address_in_file; + if ((symbolP->sy_type & N_TYPE) == N_UNDF) + { + ri.r_extern = 1; + ri.r_symbolnum = symbolP->sy_number; + } + else + { + ri.r_extern = 0; + ri.r_symbolnum = symbolP->sy_type & N_TYPE; } - if (symbolP && symbolP->sy_frag) { - ri.r_addend = symbolP->sy_frag->fr_address; + if (symbolP && symbol_get_frag (symbolP)) + { + ri.r_addend = symbol_get_frag (symbolP)->fr_address; } - ri.r_type = fixP->fx_r_type; - if (fixP->fx_pcrel) { -/* ri.r_addend -= fixP->fx_where; */ - ri.r_addend -= ri.r_address; - } else { - ri.r_addend = fixP->fx_addnumber; + ri.r_type = fixP->fx_r_type; + if (fixP->fx_pcrel) + { + ri.r_addend -= ri.r_address; + } + else + { + ri.r_addend = fixP->fx_addnumber; } -/* md_ri_to_chars ((char *) &ri, ri); */ - append (&next_object_file_charP, (char *)& ri, sizeof (ri)); + append (&next_object_file_charP, (char *) &ri, sizeof (ri)); } } - 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() +s_bss () { char *name; char c; char *p; - int temp, bss_align = 1; + int temp, bss_align; symbolS *symbolP; - extern const char is_end_of_line [256]; name = input_line_pointer; - c = get_symbol_end(); + c = get_symbol_end (); p = input_line_pointer; *p = c; - SKIP_WHITESPACE(); - if ( * input_line_pointer != ',' ) + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') { - as_warn("Expected comma after name"); - ignore_rest_of_line(); + as_warn (_("Expected comma after name")); + ignore_rest_of_line (); return; } - input_line_pointer ++; - if ((temp = get_absolute_expression()) < 0) + input_line_pointer++; + if ((temp = get_absolute_expression ()) < 0) { - as_warn("BSS length (%d.) <0! Ignored.", temp); - ignore_rest_of_line(); + as_warn (_("BSS length (%d.) <0! Ignored."), temp); + ignore_rest_of_line (); return; } *p = 0; - symbolP = symbol_find_or_make(name); + symbolP = symbol_find_or_make (name); *p = c; if (*input_line_pointer == ',') { input_line_pointer++; - bss_align = get_absolute_expression(); - while (local_bss_counter % bss_align != 0) - local_bss_counter++; + bss_align = get_absolute_expression (); } + else + bss_align = 0; - if (symbolP->sy_other == 0 - && symbolP->sy_desc == 0 - && ((symbolP->sy_type == N_BSS - && symbolP->sy_value == local_bss_counter) - || ((symbolP->sy_type & N_TYPE) == N_UNDF - && symbolP->sy_value == 0))) + if (!S_IS_DEFINED(symbolP) + || S_GET_SEGMENT(symbolP) == SEG_BSS) { - symbolP->sy_value = local_bss_counter; - symbolP->sy_type = N_BSS; - symbolP->sy_frag = & bss_address_frag; - local_bss_counter += temp; + if (! need_pass_2) + { + char *p; + segT current_seg = now_seg; + subsegT current_subseg = now_subseg; + + subseg_set (SEG_BSS, 1); /* switch to bss */ + + if (bss_align) + frag_align (bss_align, 0, 0); + + /* detach from old frag */ + if (symbolP->sy_type == N_BSS && symbol_get_frag (symbolP) != NULL) + symbol_get_frag (symbolP)->fr_symbol = NULL; + + symbol_set_frag (symbolP, frag_now); + p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, + (offsetT) temp, (char *)0); + *p = 0; + S_SET_SEGMENT (symbolP, SEG_BSS); + + subseg_set (current_seg, current_subseg); + } } else { - as_warn( "Ignoring attempt to re-define symbol from %d. to %d.", - symbolP->sy_value, local_bss_counter ); + as_warn (_("Ignoring attempt to re-define symbol %s."), name); } + while (!is_end_of_line[*input_line_pointer]) { input_line_pointer++; } +} + +#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; + fixp->fx_offset = 0; + + switch (fixp->fx_r_type) + { + case RELOC_IW16: + fixp->fx_offset = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + break; + + case RELOC_LO16: + fixp->fx_offset = val >> 16; + buf[0] = val >> 8; + buf[1] = val; + break; + + case RELOC_HI16: + fixp->fx_offset = val >> 16; + buf[0] = val >> 8; + buf[1] = val; + 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 (); + } +} - return; +/* 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; +{ + switch (fixp->fx_r_type) + { + case RELOC_PC16: + return fixp->fx_frag->fr_address + fixp->fx_where - 2; + case RELOC_PC26: + return fixp->fx_frag->fr_address + fixp->fx_where; + default: + abort (); + } + /*NOTREACHED*/ } + +/* When we align the .init section, insert the correct NOP pattern. */ + +int +m88k_do_align (n, fill, max, len) + int n; + const char *fill; + int len; + int max; +{ + if (fill == NULL + && strcmp (obj_segment_name (now_seg), ".init") == 0) + { + static const unsigned char nop_pattern[] = { 0xf4, 0x00, 0x58, 0x00 }; + frag_align_pattern (n, nop_pattern, sizeof (nop_pattern), max); + return 1; + } + return 0; +} + +#endif /* M88KCOFF */