X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-mcore.c;h=ec03a296d2a64f6ed93a712d8b4aa34e9581dcef;hb=7766fd10024dc0587838fbc4608f3f8e30e17a26;hp=c10b75d226c76f9aaed71dbe32e4c1b4dc85e6cf;hpb=67c1ffbec916d2c18096f2a285d4f5812f20bd24;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-mcore.c b/gas/config/tc-mcore.c index c10b75d226..ec03a296d2 100644 --- a/gas/config/tc-mcore.c +++ b/gas/config/tc-mcore.c @@ -1,11 +1,11 @@ /* tc-mcore.c -- Assemble code for M*Core - Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999-2016 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, @@ -15,17 +15,14 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ -#include #include "as.h" -#include "bfd.h" #include "subsegs.h" #define DEFINE_TABLE #include "../opcodes/mcore-opc.h" #include "safe-ctype.h" -#include #ifdef OBJ_ELF #include "elf/mcore.h" @@ -36,31 +33,6 @@ #endif /* 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)); -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 @@ -73,8 +45,6 @@ const char comment_chars[] = "#/"; 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; @@ -88,7 +58,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; #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 @@ -98,9 +68,9 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; #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 { @@ -112,7 +82,8 @@ cpu_type; 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 }, @@ -162,68 +133,76 @@ static unsigned long poolspan; #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, const 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_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 }, +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 ATTRIBUTE_UNUSED; +mcore_s_literals (int ignore ATTRIBUTE_UNUSED) { dump_literals (0); demand_empty_rest_of_line (); @@ -232,9 +211,7 @@ mcore_s_literals (ignore) /* Perform FUNC (ARG), and track number of bytes added to frag. */ static void -mcore_pool_count (func, arg) - void (*func) PARAMS ((int)); - int arg; +mcore_pool_count (void (*func) (int), int arg) { const fragS *curr_frag = frag_now; offsetT added = -frag_now_fix_octets (); @@ -252,8 +229,42 @@ mcore_pool_count (func, arg) } static void -mcore_cons (nbytes) - int nbytes; +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); @@ -268,8 +279,7 @@ mcore_cons (nbytes) } static void -mcore_float_cons (float_type) - int float_type; +mcore_float_cons (int float_type) { if (now_seg == text_section) mcore_pool_count (float_cons, float_type); @@ -284,8 +294,7 @@ mcore_float_cons (float_type) } static void -mcore_stringer (append_zero) - int append_zero; +mcore_stringer (int append_zero) { if (now_seg == text_section) mcore_pool_count (stringer, append_zero); @@ -301,8 +310,7 @@ mcore_stringer (append_zero) } static void -mcore_fill (unused) - int unused; +mcore_fill (int unused) { if (now_seg == text_section) mcore_pool_count (s_fill, unused); @@ -314,9 +322,9 @@ mcore_fill (unused) /* 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); @@ -328,8 +336,7 @@ mcore_s_text (ignore) } static void -mcore_s_data (ignore) - int ignore; +mcore_s_data (int ignore) { dump_literals (0); @@ -341,8 +348,7 @@ mcore_s_data (ignore) } 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 @@ -370,8 +376,7 @@ mcore_s_section (ignore) } static void -mcore_s_bss (needs_align) - int needs_align; +mcore_s_bss (int needs_align) { dump_literals (0); @@ -380,8 +385,7 @@ mcore_s_bss (needs_align) #ifdef OBJ_ELF static void -mcore_s_comm (needs_align) - int needs_align; +mcore_s_comm (int needs_align) { dump_literals (0); @@ -389,47 +393,103 @@ mcore_s_comm (needs_align) } #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) { - const mcore_opcode_info * opcode; - char * prev_name = ""; + const char * prev_name = ""; + unsigned int i; opcode_hash_control = hash_new (); - /* Insert unique names into hash table */ - for (opcode = mcore_table; opcode->name; opcode ++) + /* Insert unique names into hash table. */ + for (i = 0; i < ARRAY_SIZE (mcore_table); i++) { - if (! streq (prev_name, opcode->name)) + if (! streq (prev_name, mcore_table[i].name)) { - prev_name = opcode->name; - hash_insert (opcode_hash_control, opcode->name, (char *) opcode); + prev_name = mcore_table[i].name; + hash_insert (opcode_hash_control, mcore_table[i].name, (char *) &mcore_table[i]); } } } /* 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; } - 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)) @@ -463,7 +523,7 @@ parse_reg (s, reg) static struct Cregs { - char * name; + const char * name; unsigned int crnum; } cregs[] = @@ -485,9 +545,7 @@ cregs[] = }; static char * -parse_creg (s, reg) - char * s; - unsigned * reg; +parse_creg (char * s, unsigned * reg) { int i; @@ -547,15 +605,13 @@ parse_creg (s, reg) } static char * -parse_psrmod (s, reg) - char * s; - unsigned * reg; +parse_psrmod (char * s, unsigned * reg) { int i; char buf[10]; static struct psrmods { - char * name; + const char * name; unsigned int value; } psrmods[] = @@ -587,12 +643,10 @@ parse_psrmod (s, reg) } 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)) @@ -606,135 +660,26 @@ parse_exp (s, e) 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; -{ - unsigned int i; - struct literal * p; - symbolS * brarsym = NULL; - - 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 -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) { 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) { @@ -773,12 +718,12 @@ enter_literal (e, ispcrel) /* 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; @@ -820,16 +765,15 @@ parse_rt (s, outputp, ispcrel, ep) } 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. */ @@ -841,15 +785,14 @@ parse_imm (s, val, min, max) * 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) { * off = 0; @@ -903,8 +846,7 @@ parse_mem (s, reg, off, siz) the frags/bytes it assembles to. */ void -md_assemble (str) - char * str; +md_assemble (char * str) { char * op_start; char * op_end; @@ -916,7 +858,7 @@ md_assemble (str) unsigned off; unsigned isize; expressionS e; - char name[20]; + char name[21]; /* Drop leading whitespace. */ while (ISSPACE (* str)) @@ -992,15 +934,15 @@ md_assemble (str) 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); @@ -1009,7 +951,8 @@ md_assemble (str) 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; @@ -1036,7 +979,7 @@ md_assemble (str) as_bad (_("M340 specific opcode used when assembling for M210")); break; } - /* drop through... */ + /* Fall through. */ case O2: op_end = parse_reg (op_end + 1, & reg); inst |= reg; @@ -1056,14 +999,15 @@ md_assemble (str) 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")); @@ -1075,7 +1019,7 @@ md_assemble (str) 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; @@ -1133,7 +1077,8 @@ md_assemble (str) 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; @@ -1146,7 +1091,7 @@ md_assemble (str) 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; @@ -1173,7 +1118,7 @@ md_assemble (str) 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; @@ -1189,7 +1134,7 @@ md_assemble (str) 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; @@ -1203,7 +1148,7 @@ md_assemble (str) /* Further restrict the immediate to a power of two. */ if ((reg & (reg - 1)) == 0) - reg = log2 (reg); + reg = mylog2 (reg); else { reg = 0; @@ -1542,7 +1487,8 @@ md_assemble (str) } 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; @@ -1652,108 +1598,45 @@ md_assemble (str) output[0] = INST_BYTE0 (inst); output[1] = INST_BYTE1 (inst); +#ifdef OBJ_ELF + dwarf2_emit_insn (2); +#endif check_literals (opcode->transfer, isize); } symbolS * -md_undefined_symbol (name) - char *name ATTRIBUTE_UNUSED; +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; -{ - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - int i; - char * t; - 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; +const char * +md_atof (int type, char * litP, int * sizeP) +{ + return ieee_md_atof (type, litP, sizeP, target_big_endian); } 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[] = { @@ -1770,9 +1653,7 @@ 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, const char * arg) { switch (c) { @@ -1801,8 +1682,7 @@ md_parse_option (c, arg) } void -md_show_usage (stream) - FILE * stream; +md_show_usage (FILE * stream) { fprintf (stream, _("\ MCORE specific options:\n\ @@ -1816,38 +1696,36 @@ MCORE specific options:\n\ int md_short_jump_size; void -md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, 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; +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 ATTRIBUTE_UNUSED; - addressT from_Nddr ATTRIBUTE_UNUSED; - addressT to_Nddr ATTRIBUTE_UNUSED; - fragS * frag ATTRIBUTE_UNUSED; - symbolS * to_symbol ATTRIBUTE_UNUSED; +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 ATTRIBUTE_UNUSED; - segT sec ATTRIBUTE_UNUSED; - 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) { @@ -1889,47 +1767,46 @@ md_convert_frag (abfd, sec, fragP) 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); @@ -1943,16 +1820,16 @@ md_convert_frag (abfd, sec, fragP) 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; @@ -1968,9 +1845,9 @@ md_convert_frag (abfd, sec, fragP) 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; @@ -1984,22 +1861,22 @@ md_convert_frag (abfd, sec, fragP) .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; @@ -2013,10 +1890,10 @@ md_convert_frag (abfd, sec, fragP) 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; @@ -2038,13 +1915,12 @@ md_convert_frag (abfd, sec, fragP) Also sets up addends for 'rela' type relocations. */ void -md_apply_fix3 (fixP, valP, segment) - fixS * fixP; - valueT * valP; - segT segment ATTRIBUTE_UNUSED; +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 * file = fixP->fx_file ? fixP->fx_file : _("unknown"); const char * symname; /* Note: use offsetT because it is signed, valueT is unsigned. */ offsetT val = *valP; @@ -2067,7 +1943,8 @@ md_apply_fix3 (fixP, valP, segment) 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%lx bytes)"), (long) val); @@ -2088,7 +1965,8 @@ md_apply_fix3 (fixP, valP, segment) } 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) @@ -2101,7 +1979,8 @@ md_apply_fix3 (fixP, valP, segment) 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%lx)"), (long) val); @@ -2161,8 +2040,7 @@ md_apply_fix3 (fixP, valP, segment) } void -md_operand (expressionP) - expressionS * expressionP; +md_operand (expressionS * expressionP) { /* Ignore leading hash symbol, if poresent. */ if (* input_line_pointer == '#') @@ -2177,9 +2055,7 @@ int md_long_jump_size; /* 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) { @@ -2189,38 +2065,26 @@ md_estimate_size_before_relax (fragP, segment_type) 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): @@ -2238,47 +2102,31 @@ md_estimate_size_before_relax (fragP, segment_type) } /* 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 ATTRIBUTE_UNUSED; - 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 ATTRIBUTE_UNUSED; +md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED) { #ifdef OBJ_ELF /* If the symbol is undefined or defined in another section @@ -2289,7 +2137,7 @@ md_pcrel_from_section (fixp, sec) || (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 @@ -2302,9 +2150,7 @@ md_pcrel_from_section (fixp, sec) #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break arelent * -tc_gen_reloc (section, fixp) - asection * section ATTRIBUTE_UNUSED; - fixS * fixp; +tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) { arelent * rel; bfd_reloc_code_real_type code; @@ -2340,8 +2186,8 @@ tc_gen_reloc (section, fixp) break; } - rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + rel = XNEW (arelent); + rel->sym_ptr_ptr = XNEW (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! */ @@ -2357,7 +2203,7 @@ tc_gen_reloc (section, fixp) /* 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; @@ -2368,8 +2214,7 @@ tc_gen_reloc (section, fixp) 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_RVA) return 1; @@ -2379,9 +2224,9 @@ mcore_force_relocation (fix) /* Return true if the fix can be handled by GAS, false if it must be passed through to the linker. */ + bfd_boolean -mcore_fix_adjustable (fixP) - fixS * fixP; +mcore_fix_adjustable (fixS * fixP) { /* We need the symbol name for the VTABLE entries. */ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT