diff options
Diffstat (limited to 'gas/config/tc-mcore.c')
-rw-r--r-- | gas/config/tc-mcore.c | 226 |
1 files changed, 132 insertions, 94 deletions
diff --git a/gas/config/tc-mcore.c b/gas/config/tc-mcore.c index 7e784354eab..d33fc9f8bbf 100644 --- a/gas/config/tc-mcore.c +++ b/gas/config/tc-mcore.c @@ -1,6 +1,5 @@ /* tc-mcore.c -- Assemble code for M*Core - - Copyright (C) 1993,1994, 1999 Free Software Foundation. + Copyright (C) 1999 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -53,16 +52,19 @@ 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)); -#ifdef OBJ_ELF 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 and then use these two macros to crack the MCORE_INST value into the appropriate byte values. */ -#define INST_BYTE0(x) (((x) >> 8) & 0xFF) -#define INST_BYTE1(x) ((x) & 0xFF) +#define INST_BYTE0(x) (((x) >> 8) & 0xFF) +#define INST_BYTE1(x) ((x) & 0xFF) const char comment_chars[] = "#/"; const char line_separator_chars[] = ";"; @@ -70,7 +72,6 @@ const char line_comment_chars[] = "#/"; const int md_reloc_size = 8; -static int relax; /* set if -relax seen */ static int do_jsri2bsr = 0; /* change here from 1 by Cruess 19 August 97 */ static int sifilter_mode = 0; @@ -165,7 +166,6 @@ const pseudo_typeS md_pseudo_table[] = { "import", s_ignore, 0 }, { "literals", mcore_s_literals, 0 }, { "page", listing_eject, 0 }, - { "bss", s_lcomm_bytes, 1 }, /* The following are to intercept the placement of data into the text section (eg addresses for a switch table), so that the space they @@ -197,13 +197,15 @@ const pseudo_typeS md_pseudo_table[] = /* Allow for the effect of section changes. */ { "text", mcore_s_text, 0 }, { "data", mcore_s_data, 0 }, - -#ifdef OBJ_ELF + { "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 }, -#endif + { 0, 0, 0 } }; @@ -304,13 +306,20 @@ mcore_stringer (append_zero) 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; { dump_literals (0); +#ifdef OBJ_ELF + obj_elf_text (ignore); +#else s_text (ignore); +#endif } static void @@ -319,9 +328,47 @@ mcore_s_data (ignore) { dump_literals (0); +#ifdef OBJ_ELF + obj_elf_data (ignore); +#else s_data (ignore); +#endif } +static void +mcore_s_section (ignore) + int ignore; +{ + dump_literals (0); + +#ifdef OBJ_ELF + obj_elf_section (ignore); +#endif +#ifdef OBJ_COFF + obj_coff_section (ignore); +#endif +} + +static void +mcore_s_bss (needs_align) + int needs_align; +{ + dump_literals (0); + + s_lcomm_bytes (needs_align); +} + +#ifdef OBJ_ELF +static void +mcore_s_comm (needs_align) + int needs_align; +{ + dump_literals (0); + + obj_elf_common (needs_align); +} +#endif + /* 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 @@ -394,7 +441,7 @@ parse_reg (s, reg) } else if ( tolower (s[0]) == 's' && tolower (s[1]) == 'p' - && (isspace (s[2]) || s[2] == ',')) + && ! isalnum (s[2])) { * reg = 0; return s + 2; @@ -533,13 +580,16 @@ make_name (s, p, n) 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; - struct symbol * brarsym; + symbolS * brarsym; if (poolsize == 0) return; @@ -550,7 +600,7 @@ dump_literals (isforce) char * output; char brarname[8]; - make_name (brarname, ".YP.", poolnumber); + make_name (brarname, POOL_END_LABEL, poolnumber); brarsym = symbol_make (brarname); @@ -642,7 +692,7 @@ enter_literal (e, ispcrel) if (++ poolnumber > 0xFFFF) as_fatal (_("more than 65K literal pools")); - make_name (poolname, ".XP.", poolnumber); + make_name (poolname, POOL_START_LABEL, poolnumber); poolsym = symbol_make (poolname); symbol_table_insert (poolsym); poolspan = 0; @@ -877,8 +927,8 @@ md_assemble (str) fixes problem of an interrupt during a jmp.. */ if (sifilter_mode) { - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); } break; @@ -896,20 +946,20 @@ md_assemble (str) { /* Replace with: bsr .+2 ; addi r15,6; jmp rx ; jmp rx */ inst = MCORE_INST_BSR; /* with 0 displacement */ - output[0] = (inst >> 8); - output[1] = (inst); + 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 */ - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); inst = MCORE_INST_JMP | reg; - output[0] = (inst >> 8); - output[1] = (inst); + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); output = frag_more (2); /* 2nd emitted in fallthru */ } @@ -1496,8 +1546,8 @@ md_assemble (str) as_bad (_("unimplemented opcode \"%s\""), name); } - output[0] = inst >> 8; - output[1] = inst; + output[0] = INST_BYTE0 (inst); + output[1] = INST_BYTE1 (inst); check_literals (opcode->transfer, isize); } @@ -1531,7 +1581,7 @@ md_atof (type, litP, sizeP) { int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE * wordP; + int i; char * t; char * atof_ieee (); @@ -1573,26 +1623,25 @@ md_atof (type, litP, sizeP) *sizeP = prec * sizeof (LITTLENUM_TYPE); - for (wordP = words; prec--;) - { - md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } + 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_shortopts = ""; -#define OPTION_RELAX (OPTION_MD_BASE) -#define OPTION_JSRI2BSR_ON (OPTION_MD_BASE + 1) -#define OPTION_JSRI2BSR_OFF (OPTION_MD_BASE + 2) -#define OPTION_SIFILTER_ON (OPTION_MD_BASE + 3) -#define OPTION_SIFILTER_OFF (OPTION_MD_BASE + 4) +#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) struct option md_longopts[] = { - { "relax", no_argument, NULL, OPTION_RELAX}, { "no-jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_OFF}, { "jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_ON}, { "sifilter", no_argument, NULL, OPTION_SIFILTER_ON}, @@ -1613,7 +1662,6 @@ md_parse_option (c, arg) switch (c) { - case OPTION_RELAX: relax = 1; break; case OPTION_JSRI2BSR_ON: do_jsri2bsr = 1; break; case OPTION_JSRI2BSR_OFF: do_jsri2bsr = 0; break; case OPTION_SIFILTER_ON: sifilter_mode = 1; break; @@ -1630,9 +1678,8 @@ md_show_usage (stream) { fprintf (stream, _("\ MCORE specific options:\n\ - -{no-}jsri2bsr {dis}able jsri to bsr transformation (def: off)\n\ - -{no-}sifilter {dis}able silicon filter behavior (def: off)\n\ - -relax alter jump instructions for long displacements\n")); + -{no-}jsri2bsr {dis}able jsri to bsr transformation (def: dis)\n\ + -{no-}sifilter {dis}able silicon filter behavior (def: dis)")); } int md_short_jump_size; @@ -1670,7 +1717,7 @@ md_convert_frag (abfd, sec, fragP) int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal); - targ_addr += fragP->fr_symbol->sy_frag->fr_address; + targ_addr += symbol_get_frag (fragP->fr_symbol)->fr_address; switch (fragP->fr_subtype) { @@ -1683,14 +1730,17 @@ md_convert_frag (abfd, sec, fragP) int disp = targ_addr - next_inst; if (disp & 1) - as_bad (_("odd displacement at %x"), next_inst - 2); + as_bad (_("odd displacement at %x"), next_inst - 2); disp >>= 1; - t0 = buffer[0] & 0xF8; + { + t0 = buffer[0] & 0xF8; + + md_number_to_chars (buffer, disp, 2); - md_number_to_chars (buffer, disp, 2); + buffer[0] = (buffer[0] & 0x07) | t0; + } - buffer[0] = (buffer[0] & 0x07) | t0; fragP->fr_fix += 2; fragP->fr_var = 0; } @@ -1712,15 +1762,18 @@ md_convert_frag (abfd, sec, fragP) int first_inst = fragP->fr_fix + fragP->fr_address; int needpad = (first_inst & 3); - buffer[0] ^= 0x08; /* Toggle T/F bit */ + buffer[0] ^= 0x08; /* Toggle T/F bit */ buffer[2] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi */ buffer[3] = INST_BYTE1 (MCORE_INST_JMPI); if (needpad) { - 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[5] = 0; buffer[6] = 0; /* space for 32 bit address */ @@ -1740,8 +1793,11 @@ md_convert_frag (abfd, sec, fragP) shrinking the fragment. '3' is the amount of code that we inserted here, but '4' is right for the space we reserved for this fragment. */ - 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[5] = 0; buffer[6] = 0; @@ -1752,12 +1808,12 @@ md_convert_frag (abfd, sec, fragP) fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32); fragP->fr_fix += C32_LEN; - /* frag is actually shorter (see the other side of this ifdef) - but gas isn't prepared for that. We have to re-adjust + /* Frag is actually shorter (see the other side of this ifdef) + but gas isn't prepared for that. We have to re-adjust the branch displacement so that it goes beyond the full length of the fragment, not just what we actually filled in. */ - buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */ + buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */ } fragP->fr_var = 0; @@ -1782,7 +1838,7 @@ md_convert_frag (abfd, sec, fragP) if (needpad) { - buffer[1] = 1; /* jmpi offset of 1 since padded */ + buffer[1] = 1; /* jmpi offset of 1 since padded */ buffer[2] = 0; /* alignment */ buffer[3] = 0; buffer[4] = 0; /* space for 32 bit address */ @@ -1798,7 +1854,7 @@ md_convert_frag (abfd, sec, fragP) } else { - buffer[1] = 0; /* jmpi offset of 0 if no pad */ + buffer[1] = 0; /* jmpi offset of 0 if no pad */ buffer[2] = 0; /* space for 32 bit address */ buffer[3] = 0; buffer[4] = 0; @@ -1865,9 +1921,9 @@ md_apply_fix3 (fixP, valp, segment) as_bad_where (file, fixP->fx_line, _("pcrel for branch to %s too far (0x%x)"), symname, val); - buf[0] |= ((val >> 8) & 0x7); - buf[1] |= (val & 0xff); - break; + buf[0] |= ((val >> 8) & 0x7); + buf[1] |= (val & 0xff); + break; case BFD_RELOC_MCORE_PCREL_IMM8BY4: /* lower 8 bits of 2 byte opcode */ val += 3; @@ -1878,14 +1934,14 @@ md_apply_fix3 (fixP, valp, segment) symname, val); else buf[1] |= (val & 0xff); - break; + break; 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); val /= 2; - buf[1] |= (val & 0xf); + buf[1] |= (val & 0xf); break; case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: @@ -1898,8 +1954,8 @@ md_apply_fix3 (fixP, valp, segment) nval |= MCORE_INST_BSR; /* REPLACE the instruction, don't just modify it. */ - buf[0] = ((nval >> 8) & 0xff); - buf[1] = (nval & 0xff); + buf[0] = INST_BYTE0 (nval); + buf[1] = INST_BYTE1 (nval); } else fixP->fx_done = 0; @@ -1923,21 +1979,14 @@ md_apply_fix3 (fixP, valp, segment) #endif { if (fixP->fx_size == 4) - { - *buf++ = val >> 24; - *buf++ = val >> 16; - *buf++ = val >> 8; - *buf = val; - } + ; else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767) - { - *buf++ = val >> 8; - *buf = val; - } + ; else if (fixP->fx_size == 1 && val >= -256 && val <= 255) - *buf = val; + ; else abort (); + md_number_to_chars (buf, val, fixP->fx_size); } break; } @@ -2022,21 +2071,20 @@ 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; { - 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 (); - } + 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 (); + } } /* Round up a section size to the appropriate boundary. */ @@ -2117,7 +2165,8 @@ tc_gen_reloc (section, fixp) } rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = & fixp->fx_addsy->bsym; + rel->sym_ptr_ptr = (asymbol **) 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! */ rel->addend = fixp->fx_addnumber; @@ -2169,15 +2218,4 @@ mcore_fix_adjustable (fixP) return 1; } - -/* Handle the .section pseudo-op. This is like the usual one, but it - dumps the literal pool before changing the section. */ -static void -mcore_s_section (ignore) - int ignore; -{ - dump_literals (0); - - obj_elf_section (ignore); -} #endif /* OBJ_ELF */ |