/* tc-i960.c - All the i80960-specific stuff
Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2005
+ 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010
Free Software Foundation, Inc.
This file is part of GAS.
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 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
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, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
/* See comment on md_parse_option for 80960-specific invocation options. */
less than 4096 is specified, in which case we need neither a fixup nor
a relocation directive. */
-#include <stdio.h>
-
#include "as.h"
#include "safe-ctype.h"
extern char *input_line_pointer;
-#if !defined (BFD_ASSEMBLER) && !defined (BFD)
-#ifdef OBJ_COFF
-const int md_reloc_size = sizeof (struct reloc);
-#else /* OBJ_COFF */
-const int md_reloc_size = sizeof (struct relocation_info);
-#endif /* OBJ_COFF */
-#endif
-
/* Local i80960 routines. */
struct memS;
struct regop;
char opdesc; /* Operand descriptor byte. */
memS instr; /* Description of binary to be output. */
char *outP; /* Where the binary was output to. */
- expressionS expr; /* Parsed expression. */
+ expressionS exp; /* Parsed expression. */
/* ->description of deferred address fixup. */
fixS *fixP;
/* Parse the displacement; this must be done before emitting the
opcode, in case it is an expression using `.'. */
- parse_expr (instr.e, &expr);
+ parse_expr (instr.e, &exp);
/* Output opcode. */
outP = emit (instr.opcode);
return;
/* Process the displacement. */
- switch (expr.X_op)
+ switch (exp.X_op)
{
case O_illegal:
as_bad (_("expression syntax error"));
case O_constant:
if (instr.disp == 32)
- (void) emit (offs (expr)); /* Output displacement. */
+ (void) emit (offs (exp)); /* Output displacement. */
else
{
/* 12-bit displacement. */
- if (offs (expr) & ~0xfff)
+ if (offs (exp) & ~0xfff)
{
/* Won't fit in 12 bits: convert already-output
instruction to MEMB format, output
displacement. */
mema_to_memb (outP);
- (void) emit (offs (expr));
+ (void) emit (offs (exp));
}
else
{
/* WILL fit in 12 bits: OR into opcode and
overwrite the binary we already put out. */
- instr.opcode |= offs (expr);
+ instr.opcode |= offs (exp);
md_number_to_chars (outP, instr.opcode, 4);
}
}
outP = emit ((long) 0);
fixP = fix_new_exp (frag_now,
outP - frag_now->fr_literal,
- 4, & expr, 0, NO_RELOC);
+ 4, &exp, 0, NO_RELOC);
/* Steve's linker relaxing hack. Mark this 32-bit relocation as
being in the instruction stream, specifically as part of a callx
instruction. */
break;
case REG:
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
reg_fmt (args, oP);
break;
case MEM1:
if (args[0][0] == 'c' && args[0][1] == 'a')
{
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
mem_fmt (args, oP, 1);
break;
}
case MEM12:
case MEM16:
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
mem_fmt (args, oP, 0);
break;
case CALLJ:
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
/* Output opcode & set up "fixup" (relocation); flag
relocation as 'callj' type. */
know (oP->num_ops == 1);
number_to_chars_littleendian (buf, value, n);
}
-#define MAX_LITTLENUMS 6
-#define LNUM_SIZE sizeof (LITTLENUM_TYPE)
-
-/* md_atof: convert ascii to floating point
-
- Turn a string at input_line_pointer into a floating point constant of type
- 'type', and store the appropriate bytes at *litP. The number of LITTLENUMS
- emitted is returned at 'sizeP'. An error message is returned, or a pointer
- to an empty message if OK.
-
- Note we call the i386 floating point routine, rather than complicating
- things with more files or symbolic links. */
-
char *
md_atof (int type, char *litP, int *sizeP)
{
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- LITTLENUM_TYPE *wordP;
- int prec;
- char *t;
-
- switch (type)
- {
- case 'f':
- case 'F':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- prec = 4;
- break;
-
- case 't':
- case 'T':
- prec = 5;
- type = 'x'; /* That's what atof_ieee() understands. */
- break;
-
- default:
- *sizeP = 0;
- return _("Bad call to md_atof()");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * LNUM_SIZE;
-
- /* Output the LITTLENUMs in REVERSE order in accord with i80960
- word-order. (Dunno why atof_ieee doesn't do it in the right
- order in the first place -- probably because it's a hack of
- atof_m68k.) */
- for (wordP = words + prec - 1; prec--;)
- {
- md_number_to_chars (litP, (long) (*wordP--), LNUM_SIZE);
- litP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
+ return ieee_md_atof (type, litP, sizeP, FALSE);
}
static void
If the fragment substate is 2, a 13-bit displacement was not enough.
Replace the cobr with a two instructions (a compare and a branch). */
-#ifndef BFD_ASSEMBLER
-void
-md_convert_frag (object_headers *headers ATTRIBUTE_UNUSED,
- segT seg ATTRIBUTE_UNUSED,
- fragS *fragP)
-#else
void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
segT sec ATTRIBUTE_UNUSED,
fragS *fragP)
-#endif
{
/* Structure describing needed address fix. */
fixS *fixP;
char buf[20];
/* Where the binary was output to. */
char *p;
- /* Pointer to description of deferred address fixup. */
- fixS *fixP;
if (!instrument_branches)
return;
{
sprintf (buf, "%s%d", BR_LABEL_BASE, i);
p = emit (0);
- fixP = fix_new (frag_now,
- p - frag_now->fr_literal,
- 4, symbol_find (buf), 0, 0, NO_RELOC);
+ fix_new (frag_now,
+ p - frag_now->fr_literal,
+ 4, symbol_find (buf), 0, 0, NO_RELOC);
}
}
}
void
-md_apply_fix3 (fixS *fixP,
+md_apply_fix (fixS *fixP,
valueT *valP,
segT seg ATTRIBUTE_UNUSED)
{
if (!fixP->fx_bit_fixP)
{
-#ifndef BFD_ASSEMBLER
- /* For callx, we always want to write out zero, and emit a
- symbolic relocation. */
- if (fixP->fx_bsr)
- val = 0;
-
- fixP->fx_addnumber = val;
-#endif
-
md_number_to_imm (place, val, fixP->fx_size);
}
else if ((int) (size_t) fixP->fx_bit_fixP == 13
#endif /* OBJ_AOUT or OBJ_BOUT */
-#if defined (OBJ_COFF) && defined (BFD)
-short
-tc_coff_fix2rtype (fixS *fixP)
-{
- if (fixP->fx_bsr)
- abort ();
-
- if (fixP->fx_pcrel == 0 && fixP->fx_size == 4)
- return R_RELLONG;
-
- if (fixP->fx_pcrel != 0 && fixP->fx_size == 4)
- return R_IPRMED;
-
- abort ();
- return 0;
-}
-
-int
-tc_coff_sizemachdep (fragS *frag)
-{
- if (frag->fr_next)
- return frag->fr_next->fr_address - frag->fr_address;
- else
- return 0;
-}
-#endif
-
/* Align an address by rounding it up to the specified boundary. */
valueT
{
int align;
-#ifdef BFD_ASSEMBLER
align = bfd_get_section_alignment (stdoutput, seg);
-#else
- align = section_alignment[(int) seg];
-#endif
return (addr + (1 << align) - 1) & (-1 << align);
}
extern int coff_flags;
-#ifdef OBJ_COFF
-void
-tc_headers_hook (object_headers *headers)
-{
- switch (architecture)
- {
- case ARCH_KA:
- coff_flags |= F_I960KA;
- break;
-
- case ARCH_KB:
- coff_flags |= F_I960KB;
- break;
-
- case ARCH_MC:
- coff_flags |= F_I960MC;
- break;
-
- case ARCH_CA:
- coff_flags |= F_I960CA;
- break;
-
- case ARCH_JX:
- coff_flags |= F_I960JX;
- break;
-
- case ARCH_HX:
- coff_flags |= F_I960HX;
- break;
-
- default:
- if (iclasses_seen == I_BASE)
- coff_flags |= F_I960CORE;
- else if (iclasses_seen & I_CX)
- coff_flags |= F_I960CA;
- else if (iclasses_seen & I_HX)
- coff_flags |= F_I960HX;
- else if (iclasses_seen & I_JX)
- coff_flags |= F_I960JX;
- else if (iclasses_seen & I_CX2)
- coff_flags |= F_I960CA;
- else if (iclasses_seen & I_MIL)
- coff_flags |= F_I960MC;
- else if (iclasses_seen & (I_DEC | I_FP))
- coff_flags |= F_I960KB;
- else
- coff_flags |= F_I960KA;
- break;
- }
-
- if (flag_readonly_data_in_text)
- {
- headers->filehdr.f_magic = I960RWMAGIC;
- headers->aouthdr.magic = OMAGIC;
- }
- else
- {
- headers->filehdr.f_magic = I960ROMAGIC;
- headers->aouthdr.magic = NMAGIC;
- } /* set magic numbers */
-}
-
-#endif /* OBJ_COFF */
-
-#ifndef BFD_ASSEMBLER
-
-/* Things going on here:
-
- For bout, We need to assure a couple of simplifying
- assumptions about leafprocs for the linker: the leafproc
- entry symbols will be defined in the same assembly in
- which they're declared with the '.leafproc' directive;
- and if a leafproc has both 'call' and 'bal' entry points
- they are both global or both local.
-
- For coff, the call symbol has a second aux entry that
- contains the bal entry point. The bal symbol becomes a
- label.
-
- For coff representation, the call symbol has a second aux entry that
- contains the bal entry point. The bal symbol becomes a label. */
-
-void
-tc_crawl_symbol_chain (object_headers *headers ATTRIBUTE_UNUSED)
-{
- symbolS *symbolP;
-
- for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
- {
-#ifdef OBJ_COFF
- if (TC_S_IS_SYSPROC (symbolP))
- {
- /* Second aux entry already contains the sysproc number. */
- S_SET_NUMBER_AUXILIARY (symbolP, 2);
- S_SET_STORAGE_CLASS (symbolP, C_SCALL);
- S_SET_DATA_TYPE (symbolP, S_GET_DATA_TYPE (symbolP) | (DT_FCN << N_BTSHFT));
- continue;
- }
-#endif /* OBJ_COFF */
-
- if (!TC_S_IS_BALNAME (symbolP) && !TC_S_IS_CALLNAME (symbolP))
- continue;
-
- if (!S_IS_DEFINED (symbolP))
- as_bad (_("leafproc symbol '%s' undefined"), S_GET_NAME (symbolP));
-
- if (TC_S_IS_CALLNAME (symbolP))
- {
- symbolS *balP = tc_get_bal_of_call (symbolP);
-
- if (S_IS_EXTERNAL (symbolP) != S_IS_EXTERNAL (balP))
- {
- S_SET_EXTERNAL (symbolP);
- S_SET_EXTERNAL (balP);
- as_warn (_("Warning: making leafproc entries %s and %s both global\n"),
- S_GET_NAME (symbolP), S_GET_NAME (balP));
- } /* externality mismatch */
- } /* if callname */
- } /* walk the symbol chain */
-}
-
-#endif /* ! BFD_ASSEMBLER */
-
/* For aout or bout, the bal immediately follows the call.
For coff, we cheat and store a pointer to the bal symbol in the
return 1;
}
-#ifdef BFD_ASSEMBLER
-
/* From cgen.c: */
static short
if (reloc->howto == NULL)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "internal error: can't export reloc type %d (`%s')",
+ _("internal error: can't export reloc type %d (`%s')"),
fixP->fx_r_type,
bfd_get_reloc_code_name (fixP->fx_r_type));
return NULL;
}
- assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+ gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
/* end from cgen.c */
-#endif /* BFD_ASSEMBLER */
-
const pseudo_typeS md_pseudo_table[] =
{
{"bss", s_lcomm, 1},