/* tc-mcore.c -- Assemble code for M*Core
- Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 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 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. */
-#include <stdio.h>
#include "as.h"
-#include "bfd.h"
#include "subsegs.h"
#define DEFINE_TABLE
#include "../opcodes/mcore-opc.h"
#include "safe-ctype.h"
-#include <string.h>
#ifdef OBJ_ELF
#include "elf/mcore.h"
#endif
/* Forward declarations for dumb compilers. */
-static void mcore_s_literals PARAMS ((int));
-static void mcore_cons PARAMS ((int));
-static void mcore_float_cons PARAMS ((int));
-static void mcore_stringer PARAMS ((int));
-static void mcore_fill PARAMS ((int));
-static int log2 PARAMS ((unsigned int));
-static char * parse_reg PARAMS ((char *, unsigned *));
-static char * parse_creg PARAMS ((char *, unsigned *));
-static char * parse_exp PARAMS ((char *, expressionS *));
-static char * parse_rt PARAMS ((char *, char **, int, expressionS *));
-static char * parse_imm PARAMS ((char *, unsigned *, unsigned, unsigned));
-static char * parse_mem PARAMS ((char *, unsigned *, unsigned *, unsigned));
-static char * parse_psrmod PARAMS ((char *, unsigned *));
-static void make_name PARAMS ((char *, char *, int));
-static int enter_literal PARAMS ((expressionS *, int));
-static void dump_literals PARAMS ((int));
-static void check_literals PARAMS ((int, int));
-static void mcore_s_text PARAMS ((int));
-static void mcore_s_data PARAMS ((int));
-static void mcore_s_section PARAMS ((int));
-static void mcore_s_bss PARAMS ((int));
-#ifdef OBJ_ELF
-static void mcore_s_comm PARAMS ((int));
-#endif
/* Several places in this file insert raw instructions into the
object. They should use MCORE_INST_XXX macros to get the opcodes
const char line_separator_chars[] = ";";
const char line_comment_chars[] = "#/";
-const int md_reloc_size = 8;
-
static int do_jsri2bsr = 0; /* Change here from 1 by Cruess 19 August 97. */
static int sifilter_mode = 0;
#define C(what,length) (((what) << 2) + (length))
#define GET_WHAT(x) ((x >> 2))
-/* These are the two types of relaxable instruction */
+/* These are the two types of relaxable instruction. */
#define COND_JUMP 1
#define UNCD_JUMP 2
#define UNDEF_WORD_DISP 3
#define C12_LEN 2
-#define C32_LEN 10 /* allow for align */
+#define C32_LEN 10 /* Allow for align. */
#define U12_LEN 2
-#define U32_LEN 8 /* allow for align */
+#define U32_LEN 8 /* Allow for align. */
typedef enum
{
cpu_type cpu = M340;
/* Initialize the relax table. */
-const relax_typeS md_relax_table[] = {
+const relax_typeS md_relax_table[] =
+{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, C32_LEN, 0 }, /* UNDEF_WORD_DISP */
/* UNCD_JUMP */
- { 0, 0, 0, 0 }, /* UNDEF_DISP */
- { 2048, -2046, U12_LEN, C(UNCD_JUMP, DISP32) }, /* DISP12 */
- { 0, 0, U32_LEN, 0 }, /* DISP32 */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, U12_LEN, C(UNCD_JUMP, DISP32) }, /* DISP12 */
+ { 0, 0, U32_LEN, 0 }, /* DISP32 */
{ 0, 0, U32_LEN, 0 } /* UNDEF_WORD_DISP */
};
#define SPANPANIC (1016) /* 1024 - 1 entry - 2 byte rounding. */
#define SPANCLOSE (900)
#define SPANEXIT (600)
-static symbolS * poolsym; /* label for current pool. */
+static symbolS * poolsym; /* Label for current pool. */
static char poolname[8];
static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
-/* This table describes all the machine specific pseudo-ops the assembler
- has to support. The fields are:
- Pseudo-op name without dot
- Function to call to execute this pseudo-op
- Integer arg to pass to the function. */
-const pseudo_typeS md_pseudo_table[] =
+#define POOL_END_LABEL ".LE"
+#define POOL_START_LABEL ".LS"
+
+static void
+make_name (char * s, char * p, int n)
{
- { "export", s_globl, 0 },
- { "import", s_ignore, 0 },
- { "literals", mcore_s_literals, 0 },
- { "page", listing_eject, 0 },
+ static const char hex[] = "0123456789ABCDEF";
- /* The following are to intercept the placement of data into the text
- section (eg addresses for a switch table), so that the space they
- occupy can be taken into account when deciding whether or not to
- dump the current literal pool.
- XXX - currently we do not cope with the .space and .dcb.d directives. */
- { "ascii", mcore_stringer, 0 },
- { "asciz", mcore_stringer, 1 },
- { "byte", mcore_cons, 1 },
- { "dc", mcore_cons, 2 },
- { "dc.b", mcore_cons, 1 },
- { "dc.d", mcore_float_cons, 'd'},
- { "dc.l", mcore_cons, 4 },
- { "dc.s", mcore_float_cons, 'f'},
- { "dc.w", mcore_cons, 2 },
- { "dc.x", mcore_float_cons, 'x'},
- { "double", mcore_float_cons, 'd'},
- { "float", mcore_float_cons, 'f'},
- { "hword", mcore_cons, 2 },
- { "int", mcore_cons, 4 },
- { "long", mcore_cons, 4 },
- { "octa", mcore_cons, 16 },
- { "quad", mcore_cons, 8 },
- { "short", mcore_cons, 2 },
- { "single", mcore_float_cons, 'f'},
- { "string", mcore_stringer, 1 },
- { "word", mcore_cons, 2 },
- { "fill", mcore_fill, 0 },
+ s[0] = p[0];
+ s[1] = p[1];
+ s[2] = p[2];
+ s[3] = hex[(n >> 12) & 0xF];
+ s[4] = hex[(n >> 8) & 0xF];
+ s[5] = hex[(n >> 4) & 0xF];
+ s[6] = hex[(n) & 0xF];
+ s[7] = 0;
+}
- /* Allow for the effect of section changes. */
- { "text", mcore_s_text, 0 },
- { "data", mcore_s_data, 0 },
- { "bss", mcore_s_bss, 1 },
-#ifdef OBJ_EF
- { "comm", mcore_s_comm, 0 },
-#endif
- { "section", mcore_s_section, 0 },
- { "section.s", mcore_s_section, 0 },
- { "sect", mcore_s_section, 0 },
- { "sect.s", mcore_s_section, 0 },
+static void
+dump_literals (int isforce)
+{
+ unsigned int i;
+ struct literal * p;
+ symbolS * brarsym = NULL;
- { 0, 0, 0 }
-};
+ if (poolsize == 0)
+ return;
+
+ /* Must we branch around the literal table? */
+ if (isforce)
+ {
+ char * output;
+ char brarname[8];
+
+ make_name (brarname, POOL_END_LABEL, poolnumber);
+
+ brarsym = symbol_make (brarname);
+
+ symbol_table_insert (brarsym);
+
+ output = frag_var (rs_machine_dependent,
+ md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length,
+ C (UNCD_JUMP, 0), brarsym, 0, 0);
+ output[0] = INST_BYTE0 (MCORE_INST_BR); /* br .+xxx */
+ output[1] = INST_BYTE1 (MCORE_INST_BR);
+ }
+
+ /* Make sure that the section is sufficiently aligned and that
+ the literal table is aligned within it. */
+ record_alignment (now_seg, 2);
+ frag_align (2, 0, 0);
+
+ colon (S_GET_NAME (poolsym));
+
+ for (i = 0, p = litpool; i < poolsize; i++, p++)
+ emit_expr (& p->e, 4);
+
+ if (brarsym != NULL)
+ colon (S_GET_NAME (brarsym));
+
+ poolsize = 0;
+}
static void
-mcore_s_literals (ignore)
- int ignore;
+mcore_s_literals (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 (void (*func) (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
+check_literals (int kind, int offset)
+{
+ poolspan += offset;
+
+ /* SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
+ SPANPANIC means that we must dump now.
+ kind == 0 is any old instruction.
+ kind > 0 means we just had a control transfer instruction.
+ kind == 1 means within a function
+ kind == 2 means we just left a function
+
+ The dump_literals (1) call inserts a branch around the table, so
+ we first look to see if its a situation where we won't have to
+ insert a branch (e.g., the previous instruction was an unconditional
+ branch).
+
+ SPANPANIC is the point where we must dump a single-entry pool.
+ it accounts for alignments and an inserted branch.
+ the 'poolsize*2' accounts for the scenario where we do:
+ lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
+ Note that the 'lit2' reference is 2 bytes further along
+ but the literal it references will be 4 bytes further along,
+ so we must consider the poolsize into this equation.
+ This is slightly over-cautious, but guarantees that we won't
+ panic because a relocation is too distant. */
+
+ if (poolspan > SPANCLOSE && kind > 0)
+ dump_literals (0);
+ else if (poolspan > SPANEXIT && kind > 1)
+ dump_literals (0);
+ else if (poolspan >= (SPANPANIC - poolsize * 2))
+ dump_literals (1);
+}
+
+static void
+mcore_cons (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,
}
static void
-mcore_float_cons (float_type)
- int float_type;
+mcore_float_cons (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
}
static void
-mcore_stringer (append_zero)
- int append_zero;
+mcore_stringer (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
}
static void
-mcore_fill (unused)
- int unused;
+mcore_fill (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);
}
/* Handle the section changing pseudo-ops. These call through to the
normal implementations, but they dump the literal pool first. */
+
static void
-mcore_s_text (ignore)
- int ignore;
+mcore_s_text (int ignore)
{
dump_literals (0);
}
static void
-mcore_s_data (ignore)
- int ignore;
+mcore_s_data (int ignore)
{
dump_literals (0);
}
static void
-mcore_s_section (ignore)
- int ignore;
+mcore_s_section (int ignore)
{
/* Scan forwards to find the name of the section. If the section
being switched to is ".line" then this is a DWARF1 debug section
- which is arbitarily placed inside generated code. In this case
+ which is arbitrarily placed inside generated code. In this case
do not dump the literal pool because it is a) inefficient and
b) would require the generation of extra code to jump around the
pool. */
}
static void
-mcore_s_bss (needs_align)
- int needs_align;
+mcore_s_bss (int needs_align)
{
dump_literals (0);
#ifdef OBJ_ELF
static void
-mcore_s_comm (needs_align)
- int needs_align;
+mcore_s_comm (int needs_align)
{
dump_literals (0);
}
#endif
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ Pseudo-op name without dot
+ Function to call to execute this pseudo-op
+ Integer arg to pass to the function. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "export", s_globl, 0 },
+ { "import", s_ignore, 0 },
+ { "literals", mcore_s_literals, 0 },
+ { "page", listing_eject, 0 },
+
+ /* The following are to intercept the placement of data into the text
+ section (eg addresses for a switch table), so that the space they
+ occupy can be taken into account when deciding whether or not to
+ dump the current literal pool.
+ XXX - currently we do not cope with the .space and .dcb.d directives. */
+ { "ascii", mcore_stringer, 8 + 0 },
+ { "asciz", mcore_stringer, 8 + 1 },
+ { "byte", mcore_cons, 1 },
+ { "dc", mcore_cons, 2 },
+ { "dc.b", mcore_cons, 1 },
+ { "dc.d", mcore_float_cons, 'd'},
+ { "dc.l", mcore_cons, 4 },
+ { "dc.s", mcore_float_cons, 'f'},
+ { "dc.w", mcore_cons, 2 },
+ { "dc.x", mcore_float_cons, 'x'},
+ { "double", mcore_float_cons, 'd'},
+ { "float", mcore_float_cons, 'f'},
+ { "hword", mcore_cons, 2 },
+ { "int", mcore_cons, 4 },
+ { "long", mcore_cons, 4 },
+ { "octa", mcore_cons, 16 },
+ { "quad", mcore_cons, 8 },
+ { "short", mcore_cons, 2 },
+ { "single", mcore_float_cons, 'f'},
+ { "string", mcore_stringer, 8 + 1 },
+ { "word", mcore_cons, 2 },
+ { "fill", mcore_fill, 0 },
+
+ /* Allow for the effect of section changes. */
+ { "text", mcore_s_text, 0 },
+ { "data", mcore_s_data, 0 },
+ { "bss", mcore_s_bss, 1 },
+#ifdef OBJ_ELF
+ { "comm", mcore_s_comm, 0 },
+#endif
+ { "section", mcore_s_section, 0 },
+ { "section.s", mcore_s_section, 0 },
+ { "sect", mcore_s_section, 0 },
+ { "sect.s", mcore_s_section, 0 },
+
+ { 0, 0, 0 }
+};
+
/* This function is called once, at assembler startup time. This should
set up all the tables, etc that the MD part of the assembler needs. */
+
void
-md_begin ()
+md_begin (void)
{
- mcore_opcode_info * opcode;
+ const mcore_opcode_info * opcode;
char * prev_name = "";
opcode_hash_control = hash_new ();
- /* Insert unique names into hash table */
+ /* 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)
- unsigned int val;
+mylog2 (unsigned int val)
{
- int log = -1;
- while (val != 0)
+ int log = -1;
+
+ while (val != 0)
{
- log ++;
- val >>= 1;
+ log ++;
+ val >>= 1;
}
- return log;
+ return log;
}
/* Try to parse a reg name. */
+
static char *
-parse_reg (s, reg)
- char * s;
- unsigned * reg;
+parse_reg (char * s, unsigned * reg)
{
/* Strip leading whitespace. */
while (ISSPACE (* s))
};
static char *
-parse_creg (s, reg)
- char * s;
- unsigned * reg;
+parse_creg (char * s, unsigned * reg)
{
int i;
}
static char *
-parse_psrmod (s, reg)
- char * s;
- unsigned * reg;
+parse_psrmod (char * s, unsigned * reg)
{
int i;
char buf[10];
{
if (! strncmp (psrmods[i].name, buf, 2))
{
- * reg = psrmods[i].value;
+ * reg = psrmods[i].value;
- return s + 2;
+ return s + 2;
}
}
}
static char *
-parse_exp (s, e)
- char * s;
- expressionS * e;
+parse_exp (char * s, expressionS * e)
{
char * save;
- char * new;
+ char * new_pointer;
/* Skip whitespace. */
while (ISSPACE (* s))
if (e->X_op == O_absent)
as_bad (_("missing operand"));
- new = input_line_pointer;
+ new_pointer = input_line_pointer;
input_line_pointer = save;
- return new;
-}
-
-static void
-make_name (s, p, n)
- char * s;
- char * p;
- int n;
-{
- static const char hex[] = "0123456789ABCDEF";
-
- s[0] = p[0];
- s[1] = p[1];
- s[2] = p[2];
- s[3] = hex[(n >> 12) & 0xF];
- s[4] = hex[(n >> 8) & 0xF];
- s[5] = hex[(n >> 4) & 0xF];
- s[6] = hex[(n) & 0xF];
- s[7] = 0;
-}
-
-#define POOL_END_LABEL ".LE"
-#define POOL_START_LABEL ".LS"
-
-static void
-dump_literals (isforce)
- int isforce;
-{
- int i;
- struct literal * p;
- symbolS * brarsym;
-
- if (poolsize == 0)
- return;
-
- /* Must we branch around the literal table? */
- if (isforce)
- {
- char * output;
- char brarname[8];
-
- make_name (brarname, POOL_END_LABEL, poolnumber);
-
- brarsym = symbol_make (brarname);
-
- symbol_table_insert (brarsym);
-
- output = frag_var (rs_machine_dependent,
- md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length,
- md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length,
- C (UNCD_JUMP, 0), brarsym, 0, 0);
- output[0] = INST_BYTE0 (MCORE_INST_BR); /* br .+xxx */
- output[1] = INST_BYTE1 (MCORE_INST_BR);
- }
-
- /* Make sure that the section is sufficiently aligned and that
- the literal table is aligned within it. */
- record_alignment (now_seg, 2);
- frag_align (2, 0, 0);
-
- colon (S_GET_NAME (poolsym));
-
- for (i = 0, p = litpool; i < poolsize; i++, p++)
- emit_expr (& p->e, 4);
-
- if (isforce)
- colon (S_GET_NAME (brarsym));
-
- poolsize = 0;
-}
-
-static void
-check_literals (kind, offset)
- int kind;
- int offset;
-{
- poolspan += offset;
-
- /* SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
- SPANPANIC means that we must dump now.
- kind == 0 is any old instruction.
- kind > 0 means we just had a control transfer instruction.
- kind == 1 means within a function
- kind == 2 means we just left a function
-
- The dump_literals (1) call inserts a branch around the table, so
- we first look to see if its a situation where we won't have to
- insert a branch (e.g., the previous instruction was an unconditional
- branch).
-
- SPANPANIC is the point where we must dump a single-entry pool.
- it accounts for alignments and an inserted branch.
- the 'poolsize*2' accounts for the scenario where we do:
- lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
- Note that the 'lit2' reference is 2 bytes further along
- but the literal it references will be 4 bytes further along,
- so we must consider the poolsize into this equation.
- This is slightly over-cautious, but guarantees that we won't
- panic because a relocation is too distant. */
-
- if (poolspan > SPANCLOSE && kind > 0)
- dump_literals (0);
- else if (poolspan > SPANEXIT && kind > 1)
- dump_literals (0);
- else if (poolspan >= (SPANPANIC - poolsize * 2))
- dump_literals (1);
+ return new_pointer;
}
static int
-enter_literal (e, ispcrel)
- expressionS * e;
- int ispcrel;
+enter_literal (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. */
- dump_literals (1);
- }
+ /* 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. */
+ dump_literals (1);
if (poolsize == 0)
{
/* Parse a literal specification. -- either new or old syntax.
old syntax: the user supplies the label and places the literal.
new syntax: we put it into the literal pool. */
+
static char *
-parse_rt (s, outputp, ispcrel, ep)
- char * s;
- char ** outputp;
- int ispcrel;
- expressionS * ep;
+parse_rt (char * s,
+ char ** outputp,
+ int ispcrel,
+ expressionS * ep)
{
expressionS e;
int n;
}
static char *
-parse_imm (s, val, min, max)
- char * s;
- unsigned * val;
- unsigned min;
- unsigned max;
+parse_imm (char * s,
+ unsigned * val,
+ unsigned min,
+ unsigned max)
{
- char * new;
+ char * new_pointer;
expressionS e;
- new = parse_exp (s, & e);
+ new_pointer = parse_exp (s, & e);
if (e.X_op == O_absent)
; /* 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;
- return new;
+ return new_pointer;
}
static char *
-parse_mem (s, reg, off, siz)
- char * s;
- unsigned * reg;
- unsigned * off;
- unsigned siz;
+parse_mem (char * s,
+ unsigned * reg,
+ unsigned * off,
+ unsigned siz)
{
- char * new;
-
* off = 0;
while (ISSPACE (* s))
the frags/bytes it assembles to. */
void
-md_assemble (str)
- char * str;
+md_assemble (char * str)
{
char * op_start;
char * op_end;
unsigned off;
unsigned isize;
expressionS e;
- char name[20];
+ char name[21];
/* Drop leading whitespace. */
while (ISSPACE (* str))
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);
if (sifilter_mode)
{
- /* Replace with: bsr .+2 ; addi r15,6; jmp rx ; jmp rx */
- inst = MCORE_INST_BSR; /* with 0 displacement */
+ /* Replace with: bsr .+2 ; addi r15,6; jmp rx ; jmp rx. */
+ inst = MCORE_INST_BSR; /* With 0 displacement. */
output[0] = INST_BYTE0 (inst);
output[1] = INST_BYTE1 (inst);
output = frag_more (2);
inst = MCORE_INST_ADDI;
- inst |= 15; /* addi r15,6 */
- inst |= (6 - 1) << 4; /* over the jmp's */
+ inst |= 15; /* addi r15,6 */
+ inst |= (6 - 1) << 4; /* Over the jmp's. */
output[0] = INST_BYTE0 (inst);
output[1] = INST_BYTE1 (inst);
output[0] = INST_BYTE0 (inst);
output[1] = INST_BYTE1 (inst);
- output = frag_more (2); /* 2nd emitted in fallthru */
+ /* 2nd emitted in fallthrough. */
+ output = frag_more (2);
}
break;
output = frag_more (2);
break;
- case X1: /* Handle both syntax-> xtrb- r1,rx OR xtrb- rx */
+ case X1:
+ /* Handle both syntax-> xtrb- r1,rx OR xtrb- rx. */
op_end = parse_reg (op_end + 1, & reg);
/* Skip whitespace. */
while (ISSPACE (* op_end))
++ op_end;
- if (* op_end == ',') /* xtrb- r1,rx */
+ if (* op_end == ',') /* xtrb- r1,rx. */
{
if (reg != 1)
as_bad (_("destination register must be r1"));
output = frag_more (2);
break;
- case O1R1: /* div- rx,r1 */
+ case O1R1: /* div- rx,r1. */
op_end = parse_reg (op_end + 1, & reg);
inst |= reg;
output = frag_more (2);
break;
- case OB2: /* like OB, but arg is 2^n instead of n */
+ case OB2:
+ /* Like OB, but arg is 2^n instead of n. */
op_end = parse_reg (op_end + 1, & reg);
inst |= reg;
op_end = parse_imm (op_end + 1, & reg, 1, 1 << 31);
/* Further restrict the immediate to a power of two. */
if ((reg & (reg - 1)) == 0)
- reg = log2 (reg);
+ reg = mylog2 (reg);
else
{
reg = 0;
if (* op_end == ',')
{
op_end = parse_imm (op_end + 1, & reg, 0, 31);
- /* immediate values of 0 -> 6 translate to movi */
+ /* Immediate values of 0 -> 6 translate to movi. */
if (reg <= 6)
{
inst = (inst & 0xF) | MCORE_INST_BGENI_ALT;
output = frag_more (2);
break;
- case OBR2: /* like OBR, but arg is 2^n instead of n */
+ case OBR2: /* Like OBR, but arg is 2^n instead of n. */
op_end = parse_reg (op_end + 1, & reg);
inst |= reg;
/* Further restrict the immediate to a power of two. */
if ((reg & (reg - 1)) == 0)
- reg = log2 (reg);
+ reg = mylog2 (reg);
else
{
reg = 0;
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
{
}
break;
- case RSI: /* SI, but imm becomes 32-imm */
+ case RSI:
+ /* SI, but imm becomes 32-imm. */
op_end = parse_reg (op_end + 1, & reg);
inst |= reg;
}
symbolS *
-md_undefined_symbol (name)
- char * name;
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
return 0;
}
void
-md_mcore_end ()
+md_mcore_end (void)
{
dump_literals (0);
subseg_set (text_section, 0);
}
/* Various routines to kill one day. */
-/* Equal to MAX_PRECISION in atof-ieee.c */
-#define MAX_LITTLENUMS 6
-/* Turn a string in input_line_pointer into a floating point constant of type
- type, and store the appropriate bytes in *litP. The number of LITTLENUMS
- emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
char *
-md_atof (type, litP, sizeP)
- int type;
- char * litP;
- int * sizeP;
+md_atof (int type, char * litP, int * sizeP)
{
- int prec;
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- int i;
- char * t;
- char * atof_ieee ();
-
- switch (type)
- {
- case 'f':
- case 'F':
- case 's':
- case 'S':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- case 'r':
- case 'R':
- prec = 4;
- break;
-
- case 'x':
- case 'X':
- prec = 6;
- break;
-
- case 'p':
- case 'P':
- prec = 6;
- break;
-
- default:
- *sizeP = 0;
- return _("Bad call to MD_NTOF()");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
-
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * sizeof (LITTLENUM_TYPE);
-
- if (! target_big_endian)
- {
- for (i = prec - 1; i >= 0; i--)
- {
- md_number_to_chars (litP, (valueT) words[i],
- sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
- }
- else
- for (i = 0; i < prec; i++)
- {
- md_number_to_chars (litP, (valueT) words[i],
- sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
+ return ieee_md_atof (type, litP, sizeP, target_big_endian);
}
\f
-CONST char * md_shortopts = "";
+const char * md_shortopts = "";
-#define OPTION_JSRI2BSR_ON (OPTION_MD_BASE + 0)
-#define OPTION_JSRI2BSR_OFF (OPTION_MD_BASE + 1)
-#define OPTION_SIFILTER_ON (OPTION_MD_BASE + 2)
-#define OPTION_SIFILTER_OFF (OPTION_MD_BASE + 3)
-#define OPTION_CPU (OPTION_MD_BASE + 4)
-#define OPTION_EB (OPTION_MD_BASE + 5)
-#define OPTION_EL (OPTION_MD_BASE + 6)
+enum options
+{
+ OPTION_JSRI2BSR_ON = OPTION_MD_BASE,
+ OPTION_JSRI2BSR_OFF,
+ OPTION_SIFILTER_ON,
+ OPTION_SIFILTER_OFF,
+ OPTION_CPU,
+ OPTION_EB,
+ OPTION_EL,
+};
struct option md_longopts[] =
{
size_t md_longopts_size = sizeof (md_longopts);
int
-md_parse_option (c, arg)
- int c;
- char * arg;
+md_parse_option (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_show_usage (stream)
- FILE * stream;
+md_show_usage (FILE * stream)
{
fprintf (stream, _("\
MCORE specific options:\n\
int md_short_jump_size;
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;
+md_create_short_jump (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;
+md_create_long_jump (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;
- register fragS * fragP;
+md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+ segT sec ATTRIBUTE_UNUSED,
+ fragS * fragP)
{
- unsigned char * buffer;
+ char *buffer;
int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
- buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+ buffer = fragP->fr_fix + fragP->fr_literal;
switch (fragP->fr_subtype)
{
case C (COND_JUMP, UNDEF_WORD_DISP):
{
/* A conditional branch wont fit into 12 bits so:
- * b!cond 1f
- * jmpi 0f
- * .align 2
- * 0: .long disp
- * 1:
- *
- * if the b!cond is 4 byte aligned, the literal which would
- * go at x+4 will also be aligned.
- */
+ b!cond 1f
+ jmpi 0f
+ .align 2
+ 0: .long disp
+ 1:
+
+ If the b!cond is 4 byte aligned, the literal which would
+ go at x+4 will also be aligned. */
int first_inst = fragP->fr_fix + fragP->fr_address;
int needpad = (first_inst & 3);
if (! target_big_endian)
buffer[1] ^= 0x08;
else
- buffer[0] ^= 0x08; /* Toggle T/F bit */
+ buffer[0] ^= 0x08; /* Toggle T/F bit. */
- buffer[2] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi */
+ buffer[2] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi. */
buffer[3] = INST_BYTE1 (MCORE_INST_JMPI);
if (needpad)
{
if (! target_big_endian)
{
- buffer[0] = 4; /* branch over jmpi, pad, and ptr */
- buffer[2] = 1; /* jmpi offset of 1 gets the pointer */
+ buffer[0] = 4; /* Branch over jmpi, pad, and ptr. */
+ buffer[2] = 1; /* Jmpi offset of 1 gets the pointer. */
}
else
{
- buffer[1] = 4; /* branch over jmpi, pad, and ptr */
- buffer[3] = 1; /* jmpi offset of 1 gets the pointer */
+ buffer[1] = 4; /* Branch over jmpi, pad, and ptr. */
+ buffer[3] = 1; /* Jmpi offset of 1 gets the pointer. */
}
- buffer[4] = 0; /* alignment/pad */
+ buffer[4] = 0; /* Alignment/pad. */
buffer[5] = 0;
- buffer[6] = 0; /* space for 32 bit address */
+ buffer[6] = 0; /* Space for 32 bit address. */
buffer[7] = 0;
buffer[8] = 0;
buffer[9] = 0;
- /* Make reloc for the long disp */
+ /* Make reloc for the long disp. */
fix_new (fragP, fragP->fr_fix + 6, 4,
fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
for this fragment. */
if (! target_big_endian)
{
- buffer[0] = 3; /* branch over jmpi, and ptr */
- buffer[2] = 0; /* jmpi offset of 0 gets the pointer */
+ buffer[0] = 3; /* Branch over jmpi, and ptr. */
+ buffer[2] = 0; /* Jmpi offset of 0 gets the pointer. */
}
else
{
- buffer[1] = 3; /* branch over jmpi, and ptr */
- buffer[3] = 0; /* jmpi offset of 0 gets the pointer */
+ buffer[1] = 3; /* Branch over jmpi, and ptr. */
+ buffer[3] = 0; /* Jmpi offset of 0 gets the pointer. */
}
- buffer[4] = 0; /* space for 32 bit address */
+ buffer[4] = 0; /* Space for 32 bit address. */
buffer[5] = 0;
buffer[6] = 0;
buffer[7] = 0;
full length of the fragment, not just what we actually
filled in. */
if (! target_big_endian)
- buffer[0] = 4; /* jmpi, ptr, and the 'tail pad' */
+ buffer[0] = 4; /* Jmpi, ptr, and the 'tail pad'. */
else
- buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */
+ buffer[1] = 4; /* Jmpi, ptr, and the 'tail pad'. */
}
}
break;
.align 2
0: .long disp
we need a pad if "first_inst" is 4 byte aligned.
- [because the natural literal place is x + 2] */
+ [because the natural literal place is x + 2]. */
int first_inst = fragP->fr_fix + fragP->fr_address;
int needpad = !(first_inst & 3);
- buffer[0] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi */
+ buffer[0] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi. */
buffer[1] = INST_BYTE1 (MCORE_INST_JMPI);
if (needpad)
{
if (! target_big_endian)
- buffer[0] = 1; /* jmpi offset of 1 since padded */
+ buffer[0] = 1; /* Jmpi offset of 1 since padded. */
else
- buffer[1] = 1; /* jmpi offset of 1 since padded */
- buffer[2] = 0; /* alignment */
+ buffer[1] = 1; /* Jmpi offset of 1 since padded. */
+ buffer[2] = 0; /* Alignment. */
buffer[3] = 0;
- buffer[4] = 0; /* space for 32 bit address */
+ buffer[4] = 0; /* Space for 32 bit address. */
buffer[5] = 0;
buffer[6] = 0;
buffer[7] = 0;
else
{
if (! target_big_endian)
- buffer[0] = 0; /* jmpi offset of 0 if no pad */
+ buffer[0] = 0; /* Jmpi offset of 0 if no pad. */
else
- buffer[1] = 0; /* jmpi offset of 0 if no pad */
- buffer[2] = 0; /* space for 32 bit address */
+ buffer[1] = 0; /* Jmpi offset of 0 if no pad. */
+ buffer[2] = 0; /* Space for 32 bit address. */
buffer[3] = 0;
buffer[4] = 0;
buffer[5] = 0;
/* Applies the desired value to the specified location.
Also sets up addends for 'rela' type relocations. */
-int
-md_apply_fix3 (fixP, valp, segment)
- fixS * fixP;
- valueT * valp;
- segT segment;
+
+void
+md_apply_fix (fixS * fixP,
+ valueT * valP,
+ 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'
into the insn since the addend field will be ignored. */
- return 0;
+ return;
#endif
}
else
switch (fixP->fx_r_type)
{
- case BFD_RELOC_MCORE_PCREL_IMM11BY2: /* second byte of 2 byte opcode */
+ /* Second byte of 2 byte opcode. */
+ case BFD_RELOC_MCORE_PCREL_IMM11BY2:
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);
}
break;
- case BFD_RELOC_MCORE_PCREL_IMM8BY4: /* lower 8 bits of 2 byte opcode */
+ /* Lower 8 bits of 2 byte opcode. */
+ case BFD_RELOC_MCORE_PCREL_IMM8BY4:
val += 3;
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
buf[1] |= (val & 0xff);
break;
- case BFD_RELOC_MCORE_PCREL_IMM4BY2: /* loopt instruction */
+ /* Loopt instruction. */
+ case BFD_RELOC_MCORE_PCREL_IMM4BY2:
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;
}
break;
}
-
- return 0; /* Return value is ignored. */
}
void
-md_operand (expressionP)
- expressionS * expressionP;
+md_operand (expressionS * expressionP)
{
/* Ignore leading hash symbol, if poresent. */
if (* input_line_pointer == '#')
/* Called just before address relaxation, return the length
by which a fragment must grow to reach it's destination. */
int
-md_estimate_size_before_relax (fragP, segment_type)
- register fragS * fragP;
- register segT segment_type;
+md_estimate_size_before_relax (fragS * fragP, segT segment_type)
{
switch (fragP->fr_subtype)
{
case C (UNCD_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (!fragP->fr_symbol)
- {
- fragP->fr_subtype = C (UNCD_JUMP, DISP12);
- }
+ fragP->fr_subtype = C (UNCD_JUMP, DISP12);
else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
- {
- fragP->fr_subtype = C (UNCD_JUMP, DISP12);
- }
+ fragP->fr_subtype = C (UNCD_JUMP, DISP12);
else
- {
- fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
- }
+ fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
break;
case C (COND_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (fragP->fr_symbol
&& S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
- {
- /* Got a symbol and it's defined in this segment, become byte
- sized - maybe it will fix up */
- fragP->fr_subtype = C (COND_JUMP, DISP12);
- }
+ /* Got a symbol and it's defined in this segment, become byte
+ sized - maybe it will fix up */
+ fragP->fr_subtype = C (COND_JUMP, DISP12);
else if (fragP->fr_symbol)
- {
- /* Its got a segment, but its not ours, so it will always be long. */
- fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
- }
+ /* Its got a segment, but its not ours, so it will always be long. */
+ fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
else
- {
- /* We know the abs value. */
- fragP->fr_subtype = C (COND_JUMP, DISP12);
- }
+ /* We know the abs value. */
+ fragP->fr_subtype = C (COND_JUMP, DISP12);
break;
case C (UNCD_JUMP, DISP12):
}
/* Put number into target byte order. */
+
void
-md_number_to_chars (ptr, use, nbytes)
- char * ptr;
- valueT use;
- int nbytes;
+md_number_to_chars (char * ptr, valueT use, int nbytes)
{
- if (! target_big_endian)
- switch (nbytes)
- {
- case 4: ptr[3] = (use >> 24) & 0xff; /* fall through */
- case 3: ptr[2] = (use >> 16) & 0xff; /* fall through */
- case 2: ptr[1] = (use >> 8) & 0xff; /* fall through */
- case 1: ptr[0] = (use >> 0) & 0xff; break;
- default: abort ();
- }
+ if (target_big_endian)
+ number_to_chars_bigendian (ptr, use, nbytes);
else
- switch (nbytes)
- {
- case 4: *ptr++ = (use >> 24) & 0xff; /* fall through */
- case 3: *ptr++ = (use >> 16) & 0xff; /* fall through */
- case 2: *ptr++ = (use >> 8) & 0xff; /* fall through */
- case 1: *ptr++ = (use >> 0) & 0xff; break;
- default: abort ();
- }
+ number_to_chars_littleendian (ptr, use, nbytes);
}
/* Round up a section size to the appropriate boundary. */
+
valueT
-md_section_align (segment, size)
- segT segment;
- valueT size;
+md_section_align (segT segment ATTRIBUTE_UNUSED,
+ valueT size)
{
- return size; /* Byte alignment is fine */
+ /* Byte alignment is fine. */
+ return size;
}
/* The location from which a PC relative jump should be calculated,
given a PC relative reloc. */
+
long
-md_pcrel_from_section (fixp, sec)
- fixS * fixp;
- segT sec;
+md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
{
#ifdef OBJ_ELF
/* If the symbol is undefined or defined in another section
|| (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
{
- assert (fixp->fx_size == 2); /* must be an insn */
+ gas_assert (fixp->fx_size == 2); /* must be an insn */
return fixp->fx_size;
}
#endif
#define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
arelent *
-tc_gen_reloc (section, fixp)
- asection * section;
- fixS * fixp;
+tc_gen_reloc (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;
}
- rel = (arelent *) xmalloc (sizeof (arelent));
- rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ rel = xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
*rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
/* Always pass the addend along! */
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);
- assert (rel->howto != NULL);
+ gas_assert (rel->howto != NULL);
}
return rel;
This is used to force out switch and PC relative relocations when
relaxing. */
int
-mcore_force_relocation (fix)
- fixS * fix;
+mcore_force_relocation (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
-mcore_fix_adjustable (fixP)
- fixS * fixP;
-{
- if (fixP->fx_addsy == NULL)
- return 1;
+bfd_boolean
+mcore_fix_adjustable (fixS * fixP)
+{
/* 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)