/* tc-mcore.c -- Assemble code for M*Core
- Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
/* Forward declarations for dumb compilers. */
static void mcore_s_literals PARAMS ((int));
+static void mcore_pool_count PARAMS ((void (*) (int), int));
static void mcore_cons PARAMS ((int));
static void mcore_float_cons PARAMS ((int));
static void mcore_stringer PARAMS ((int));
{ "text", mcore_s_text, 0 },
{ "data", mcore_s_data, 0 },
{ "bss", mcore_s_bss, 1 },
-#ifdef OBJ_EF
+#ifdef OBJ_ELF
{ "comm", mcore_s_comm, 0 },
#endif
{ "section", mcore_s_section, 0 },
static void
mcore_s_literals (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
dump_literals (0);
demand_empty_rest_of_line ();
}
+/* Perform FUNC (ARG), and track number of bytes added to frag. */
+
static void
-mcore_cons (nbytes)
- int nbytes;
+mcore_pool_count (func, arg)
+ void (*func) PARAMS ((int));
+ int arg;
{
- if (now_seg == text_section)
- {
- char * ptr = input_line_pointer;
- int commas = 1;
+ const fragS *curr_frag = frag_now;
+ offsetT added = -frag_now_fix_octets ();
- /* Count the number of commas on the line. */
- while (! is_end_of_line [(unsigned char) * ptr])
- commas += * ptr ++ == ',';
+ (*func) (arg);
- poolspan += nbytes * commas;
+ while (curr_frag != frag_now)
+ {
+ added += curr_frag->fr_fix;
+ curr_frag = curr_frag->fr_next;
}
- cons (nbytes);
+ added += frag_now_fix_octets ();
+ poolspan += added;
+}
+
+static void
+mcore_cons (nbytes)
+ int nbytes;
+{
+ if (now_seg == text_section)
+ mcore_pool_count (cons, nbytes);
+ else
+ cons (nbytes);
/* In theory we ought to call check_literals (2,0) here in case
we need to dump the literal table. We cannot do this however,
int float_type;
{
if (now_seg == text_section)
- {
- char * ptr = input_line_pointer;
- int commas = 1;
-
-#ifdef REPEAT_CONS_EXPRESSIONS
-#error REPEAT_CONS_EXPRESSIONS not handled
-#endif
-
- /* Count the number of commas on the line. */
- while (! is_end_of_line [(unsigned char) * ptr])
- commas += * ptr ++ == ',';
-
- /* We would like to compute "hex_float (float_type) * commas"
- but hex_float is not exported from read.c */
- float_type == 'f' ? 4 : (float_type == 'd' ? 8 : 12);
- poolspan += float_type * commas;
- }
-
- float_cons (float_type);
+ mcore_pool_count (float_cons, float_type);
+ else
+ float_cons (float_type);
/* See the comment in mcore_cons () about calling check_literals.
It is unlikely that a switch table will be constructed using
int append_zero;
{
if (now_seg == text_section)
- {
- char * ptr = input_line_pointer;
-
- /* In theory we should compute how many bytes are going to
- be occupied by the string(s) and add this to the poolspan.
- To keep things simple however, we just add the number of
- bytes left on the current line. This will be an over-
- estimate, which is OK, and automatically allows for the
- appending a zero byte, since the real string(s) is/are
- required to be enclosed in double quotes. */
- while (! is_end_of_line [(unsigned char) * ptr])
- ptr ++;
-
- poolspan += ptr - input_line_pointer;
- }
-
- stringer (append_zero);
+ mcore_pool_count (stringer, append_zero);
+ else
+ stringer (append_zero);
/* We call check_literals here in case a large number of strings are
being placed into the text section with a sequence of stringer
int unused;
{
if (now_seg == text_section)
- {
- char * str = input_line_pointer;
- int size = 1;
- int repeat;
-
- repeat = atoi (str);
-
- /* Look to see if a size has been specified. */
- while (*str != '\n' && *str != 0 && *str != ',')
- ++ str;
-
- if (* str == ',')
- {
- size = atoi (str + 1);
-
- if (size > 8)
- size = 8;
- else if (size < 0)
- size = 0;
- }
-
- poolspan += size * repeat;
- }
-
- s_fill (unused);
+ mcore_pool_count (s_fill, unused);
+ else
+ s_fill (unused);
check_literals (2, 0);
}
void
md_begin ()
{
- mcore_opcode_info * opcode;
+ const mcore_opcode_info * opcode;
char * prev_name = "";
opcode_hash_control = hash_new ();
/* Insert unique names into hash table */
for (opcode = mcore_table; opcode->name; opcode ++)
{
- if (streq (prev_name, opcode->name))
- {
- /* Make all the opcodes with the same name point to the same
- string. */
- opcode->name = prev_name;
- }
- else
+ if (! streq (prev_name, opcode->name))
{
prev_name = opcode->name;
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
}
}
-static int reg_m;
-static int reg_n;
-static expressionS immediate; /* absolute expression */
-
/* Get a log2(val). */
static int
log2 (val)
int log = -1;
while (val != 0)
{
- log ++;
- val >>= 1;
+ log ++;
+ val >>= 1;
}
return log;
{
if (! strncmp (psrmods[i].name, buf, 2))
{
- * reg = psrmods[i].value;
+ * reg = psrmods[i].value;
- return s + 2;
+ return s + 2;
}
}
dump_literals (isforce)
int isforce;
{
- int i;
+ unsigned int i;
struct literal * p;
- symbolS * brarsym;
+ symbolS * brarsym = NULL;
if (poolsize == 0)
return;
for (i = 0, p = litpool; i < poolsize; i++, p++)
emit_expr (& p->e, 4);
- if (isforce)
+ if (brarsym != NULL)
colon (S_GET_NAME (brarsym));
poolsize = 0;
expressionS * e;
int ispcrel;
{
- int i;
+ unsigned int i;
struct literal * p;
if (poolsize >= MAX_POOL_SIZE - 2)
{
/* The literal pool is as full as we can handle. We have
- to be 2 entries shy of the 1024/4=256 entries because we
- have to allow for the branch (2 bytes) and the alignment
- (2 bytes before the first insn referencing the pool and
- 2 bytes before the pool itself) == 6 bytes, rounds up
- to 2 entries. */
+ to be 2 entries shy of the 1024/4=256 entries because we
+ have to allow for the branch (2 bytes) and the alignment
+ (2 bytes before the first insn referencing the pool and
+ 2 bytes before the pool itself) == 6 bytes, rounds up
+ to 2 entries. */
dump_literals (1);
}
; /* An error message has already been emitted. */
else if (e.X_op != O_constant)
as_bad (_("operand must be a constant"));
- else if (e.X_add_number < min || e.X_add_number > max)
- as_bad (_("operand must be absolute in range %d..%d, not %d"),
- min, max, e.X_add_number);
+ else if ((addressT) e.X_add_number < min || (addressT) e.X_add_number > max)
+ as_bad (_("operand must be absolute in range %u..%u, not %ld"),
+ min, max, (long) e.X_add_number);
* val = e.X_add_number;
unsigned * off;
unsigned siz;
{
- char * new;
-
* off = 0;
while (ISSPACE (* s))
inst |= reg;
output = frag_more (2);
/* In a sifilter mode, we emit this insn 2 times,
- fixes problem of an interrupt during a jmp.. */
+ fixes problem of an interrupt during a jmp.. */
if (sifilter_mode)
{
output[0] = INST_BYTE0 (inst);
size = 2;
else if ((inst & 0x6000) == 0x2000)
size = 1;
+ else
+ abort ();
op_end = parse_mem (op_end + 1, & reg, & off, size);
{
/* parse_rt calls frag_more() for us. */
input_line_pointer = parse_rt (op_end + 1, & output, 0, 0);
- op_end = input_line_pointer;
+ op_end = input_line_pointer;
}
else
{
symbolS *
md_undefined_symbol (name)
- char * name;
+ char *name ATTRIBUTE_UNUSED;
{
return 0;
}
LITTLENUM_TYPE words[MAX_LITTLENUMS];
int i;
char * t;
- char * atof_ieee ();
switch (type)
{
int c;
char * arg;
{
- int i;
- char * p;
-
switch (c)
{
case OPTION_CPU:
else if (streq (arg, "340"))
cpu = M340;
else
- as_warn (_("unrecognised cpu type '%s'"), arg);
+ as_warn (_("unrecognised cpu type '%s'"), arg);
break;
case OPTION_EB: target_big_endian = 1; break;
void
md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
- char * ptr;
- addressT from_Nddr;
- addressT to_Nddr;
- fragS * frag;
- symbolS * to_symbol;
+ char * ptr ATTRIBUTE_UNUSED;
+ addressT from_Nddr ATTRIBUTE_UNUSED;
+ addressT to_Nddr ATTRIBUTE_UNUSED;
+ fragS * frag ATTRIBUTE_UNUSED;
+ symbolS * to_symbol ATTRIBUTE_UNUSED;
{
as_fatal (_("failed sanity check: short_jump"));
}
void
md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
- char * ptr;
- addressT from_Nddr;
- addressT to_Nddr;
- fragS * frag;
- symbolS * to_symbol;
+ char * ptr ATTRIBUTE_UNUSED;
+ addressT from_Nddr ATTRIBUTE_UNUSED;
+ addressT to_Nddr ATTRIBUTE_UNUSED;
+ fragS * frag ATTRIBUTE_UNUSED;
+ symbolS * to_symbol ATTRIBUTE_UNUSED;
{
as_fatal (_("failed sanity check: long_jump"));
}
/* Called after relaxing, change the frags so they know how big they are. */
void
md_convert_frag (abfd, sec, fragP)
- bfd * abfd;
- segT sec;
+ bfd * abfd ATTRIBUTE_UNUSED;
+ segT sec ATTRIBUTE_UNUSED;
register fragS * fragP;
{
unsigned char * buffer;
md_apply_fix3 (fixP, valP, segment)
fixS * fixP;
valueT * valP;
- segT segment;
+ segT segment ATTRIBUTE_UNUSED;
{
char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
const char * symname;
/* Note: use offsetT because it is signed, valueT is unsigned. */
- offsetT val = * (offsetT *) valP;
+ offsetT val = *valP;
symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
/* Save this for the addend in the relocation record. */
fixP->fx_addnumber = val;
- /* If the fix is relative to a symbol which is not defined, or not
- in the same segment as the fix, we cannot resolve it here. */
- if (fixP->fx_addsy != NULL
- && ( ! S_IS_DEFINED (fixP->fx_addsy)
- || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
+ if (fixP->fx_addsy != NULL)
{
- fixP->fx_done = 0;
#ifdef OBJ_ELF
/* For ELF we can just return and let the reloc that will be generated
take care of everything. For COFF we still have to insert 'val'
case BFD_RELOC_MCORE_PCREL_IMM11BY2: /* second byte of 2 byte opcode */
if ((val & 1) != 0)
as_bad_where (file, fixP->fx_line,
- _("odd distance branch (0x%x bytes)"), val);
+ _("odd distance branch (0x%lx bytes)"), (long) val);
val /= 2;
if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1))
as_bad_where (file, fixP->fx_line,
- _("pcrel for branch to %s too far (0x%x)"),
- symname, val);
+ _("pcrel for branch to %s too far (0x%lx)"),
+ symname, (long) val);
if (target_big_endian)
{
buf[0] |= ((val >> 8) & 0x7);
val /= 4;
if (val & ~0xff)
as_bad_where (file, fixP->fx_line,
- _("pcrel for lrw/jmpi/jsri to %s too far (0x%x)"),
- symname, val);
+ _("pcrel for lrw/jmpi/jsri to %s too far (0x%lx)"),
+ symname, (long) val);
else if (! target_big_endian)
buf[0] |= (val & 0xff);
else
case BFD_RELOC_MCORE_PCREL_IMM4BY2: /* loopt instruction */
if ((val < -32) || (val > -2))
as_bad_where (file, fixP->fx_line,
- _("pcrel for loopt too far (0x%x)"), val);
+ _("pcrel for loopt too far (0x%lx)"), (long) val);
val /= 2;
if (! target_big_endian)
buf[0] |= (val & 0xf);
case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2:
/* Conditional linker map jsri to bsr. */
/* If its a local target and close enough, fix it.
- NB: >= -2k for backwards bsr; < 2k for forwards... */
+ NB: >= -2k for backwards bsr; < 2k for forwards... */
if (fixP->fx_addsy == 0 && val >= -2048 && val < 2048)
{
long nval = (val / 2) & 0x7ff;
/* Round up a section size to the appropriate boundary. */
valueT
md_section_align (segment, size)
- segT segment;
+ segT segment ATTRIBUTE_UNUSED;
valueT size;
{
return size; /* Byte alignment is fine */
long
md_pcrel_from_section (fixp, sec)
fixS * fixp;
- segT sec;
+ segT sec ATTRIBUTE_UNUSED;
{
#ifdef OBJ_ELF
/* If the symbol is undefined or defined in another section
arelent *
tc_gen_reloc (section, fixp)
- asection * section;
+ asection * section ATTRIBUTE_UNUSED;
fixS * fixp;
{
arelent * rel;
bfd_reloc_code_real_type code;
- int handled = 0;
switch (fixp->fx_r_type)
{
default:
switch (F (fixp->fx_size, fixp->fx_pcrel))
- {
- MAP (1, 0, BFD_RELOC_8);
- MAP (2, 0, BFD_RELOC_16);
- MAP (4, 0, BFD_RELOC_32);
- MAP (1, 1, BFD_RELOC_8_PCREL);
- MAP (2, 1, BFD_RELOC_16_PCREL);
- MAP (4, 1, BFD_RELOC_32_PCREL);
- default:
+ {
+ MAP (1, 0, BFD_RELOC_8);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (4, 0, BFD_RELOC_32);
+ MAP (1, 1, BFD_RELOC_8_PCREL);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 1, BFD_RELOC_32_PCREL);
+ default:
code = fixp->fx_r_type;
- as_bad (_("Can not do %d byte %srelocation"),
+ as_bad (_("Can not do %d byte %srelocation"),
fixp->fx_size,
- fixp->fx_pcrel ? _("pc-relative") : "");
- }
+ fixp->fx_pcrel ? _("pc-relative") : "");
+ }
break;
}
if (rel->howto == NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
- _("Cannot represent relocation type %s"),
- bfd_get_reloc_code_name (code));
+ _("Cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (code));
/* Set howto to a garbage value so that we can keep going. */
rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
mcore_force_relocation (fix)
fixS * fix;
{
- if ( fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
- || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
- || fix->fx_r_type == BFD_RELOC_RVA)
+ if (fix->fx_r_type == BFD_RELOC_RVA)
return 1;
- return 0;
+ return generic_force_reloc (fix);
}
/* Return true if the fix can be handled by GAS, false if it must
be passed through to the linker. */
-boolean
+bfd_boolean
mcore_fix_adjustable (fixP)
fixS * fixP;
{
- if (fixP->fx_addsy == NULL)
- return 1;
-
/* We need the symbol name for the VTABLE entries. */
if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)