X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68k.c;fp=gas%2Fconfig%2Ftc-m68k.c;h=7bb6828260a2e8ca7755eeeffa98a63cc3889bd1;hp=65c166d24f8110796652d3d46db0073f7306b06a;hb=d5da4f291af551c0b8b79e1d4a9b173d60e5c10e;hpb=7b5ea4fcdf2819e070665ab5610f8b48e3867c10 diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 65c166d..7bb6828 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1,6 +1,7 @@ /* tc-m68k.c -- Assemble for the m68k family Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -37,6 +38,10 @@ #include "obj-coff.h" #endif +#ifdef OBJ_ELF +static void m68k_elf_cons (int); +#endif + /* This string holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful. The macro tc_comment_chars points to this. We use this, rather than the @@ -176,6 +181,10 @@ static const enum m68k_register mcf_ctrl[] = { RAMBAR0, RAMBAR1, RAMBAR, MBAR, 0 }; +static const enum m68k_register mcf51_ctrl[] = { + VBR, CPUCR, + 0 +}; static const enum m68k_register mcf5206_ctrl[] = { CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR, 0 @@ -196,6 +205,10 @@ static const enum m68k_register mcf5216_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1, 0 }; +static const enum m68k_register mcf5221x_ctrl[] = { + VBR, FLASHBAR, RAMBAR, RAMBAR1, + 0 +}; static const enum m68k_register mcf52223_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1, 0 @@ -208,6 +221,14 @@ static const enum m68k_register mcf5225_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, MBAR, RAMBAR1, 0 }; +static const enum m68k_register mcf52259_ctrl[] = { + VBR, FLASHBAR, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcf52277_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; static const enum m68k_register mcf5235_ctrl[] = { VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, 0 @@ -221,7 +242,7 @@ static const enum m68k_register mcf5250_ctrl[] = { 0 }; static const enum m68k_register mcf5253_ctrl[] = { - VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, MBAR, + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, RAMBAR, MBAR, MBAR2, 0 }; static const enum m68k_register mcf5271_ctrl[] = { @@ -240,8 +261,12 @@ static const enum m68k_register mcf5282_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1, 0 }; +static const enum m68k_register mcf53017_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; static const enum m68k_register mcf5307_ctrl[] = { - CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR, + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR_ALT, MBAR, 0 }; static const enum m68k_register mcf5329_ctrl[] = { @@ -268,6 +293,15 @@ static const enum m68k_register mcfv4e_ctrl[] = { ROMBAR /* ROMBAR0 */, RAMBAR /* RAMBAR1 */, 0 }; +static const enum m68k_register mcf5407_ctrl[] = { + CACR, ASID, ACR0, ACR1, ACR2, ACR3, + VBR, PC, RAMBAR0, RAMBAR1, MBAR, + /* Legacy names */ + TC /* ASID */, + ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */, + MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */, + 0 +}; static const enum m68k_register mcf54455_ctrl[] = { CACR, ASID, ACR0, ACR1, ACR2, ACR3, MMUBAR, VBR, PC, RAMBAR1, MBAR, @@ -296,7 +330,7 @@ static const enum m68k_register mcf5485_ctrl[] = { 0 }; static const enum m68k_register fido_ctrl[] = { - SFC, DFC, USP, VBR, CAC, MBB, + SFC, DFC, USP, VBR, CAC, MBO, 0 }; #define cpu32_ctrl m68010_ctrl @@ -367,6 +401,7 @@ struct m68k_it ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c)) #define HAVE_LONG_BRANCH(x) \ ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b)) +#define LONG_BRANCH_VIA_COND(x) (HAVE_LONG_COND(x) && !HAVE_LONG_BRANCH(x)) static struct m68k_it the_ins; /* The instruction being assembled. */ @@ -506,6 +541,9 @@ static const struct m68k_cpu m68k_archs[] = {0,0,NULL, 0} }; +/* For -mno-mac we want to turn off all types of mac. */ +static const unsigned no_mac = mcfmac | mcfemac; + /* Architecture extensions, here 'alias' -1 for m68k, +1 for cf and 0 for either. */ static const struct m68k_cpu m68k_extensions[] = @@ -513,14 +551,14 @@ static const struct m68k_cpu m68k_extensions[] = {m68851, NULL, "68851", -1}, {m68881, NULL, "68881", -1}, {m68881, NULL, "68882", -1}, - + {cfloat|m68881, NULL, "float", 0}, - + {mcfhwdiv, NULL, "div", 1}, {mcfusp, NULL, "usp", 1}, - {mcfmac, NULL, "mac", 1}, + {mcfmac, (void *)&no_mac, "mac", 1}, {mcfemac, NULL, "emac", 1}, - + {0,NULL,NULL, 0} }; @@ -547,7 +585,7 @@ static const struct m68k_cpu m68k_cpus[] = {m68040, m68040_ctrl, "68ec040", 1}, {m68060, m68060_ctrl, "68060", 0}, {m68060, m68060_ctrl, "68ec060", 1}, - + {cpu32|m68881, cpu32_ctrl, "cpu32", 0}, {cpu32|m68881, cpu32_ctrl, "68330", 1}, {cpu32|m68881, cpu32_ctrl, "68331", 1}, @@ -559,28 +597,37 @@ static const struct m68k_cpu m68k_cpus[] = {cpu32|m68881, cpu32_ctrl, "68341", 1}, {cpu32|m68881, cpu32_ctrl, "68349", 1}, {cpu32|m68881, cpu32_ctrl, "68360", 1}, - + + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51", 0}, + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51ac", 1}, + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51cn", 1}, + {mcfisa_a|mcfisa_c|mcfusp|mcfmac, mcf51_ctrl, "51em", 1}, + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51jm", 1}, + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51qe", 1}, + {mcfisa_a, mcf_ctrl, "5200", 0}, {mcfisa_a, mcf_ctrl, "5202", 1}, {mcfisa_a, mcf_ctrl, "5204", 1}, {mcfisa_a, mcf5206_ctrl, "5206", 1}, - + {mcfisa_a|mcfhwdiv|mcfmac, mcf5206_ctrl, "5206e", 0}, - + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5208_ctrl, "5207", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5208_ctrl, "5208", 0}, - + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5210a_ctrl, "5210a", 0}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5210a_ctrl, "5211a", 1}, - + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5213_ctrl, "5211", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5213_ctrl, "5212", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5213_ctrl, "5213", 0}, - + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5216_ctrl, "5214", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5216_ctrl, "5216", 0}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5216_ctrl, "521x", 2}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5221x_ctrl, "5221x", 0}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf52223_ctrl, "52221", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf52223_ctrl, "52223", 0}, @@ -588,9 +635,12 @@ static const struct m68k_cpu m68k_cpus[] = {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52235_ctrl, "52233", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52235_ctrl, "52234", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52235_ctrl, "52235", 0}, - + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5225_ctrl, "5224", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5225_ctrl, "5225", 0}, + + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52277_ctrl, "52274", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52277_ctrl, "52277", 0}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "5232", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "5233", -1}, @@ -601,7 +651,14 @@ static const struct m68k_cpu m68k_cpus[] = {mcfisa_a|mcfhwdiv|mcfemac, mcf5249_ctrl, "5249", 0}, {mcfisa_a|mcfhwdiv|mcfemac, mcf5250_ctrl, "5250", 0}, {mcfisa_a|mcfhwdiv|mcfemac, mcf5253_ctrl, "5253", 0}, - + + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52259_ctrl, "52252", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52259_ctrl, "52254", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52259_ctrl, "52255", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52259_ctrl, "52256", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52259_ctrl, "52258", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52259_ctrl, "52259", 0}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5271_ctrl, "5270", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5271_ctrl, "5271", 0}, @@ -615,6 +672,14 @@ static const struct m68k_cpu m68k_cpus[] = {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5282_ctrl, "5282", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5282_ctrl, "528x", 0}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53011", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53012", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53013", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53014", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53015", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53016", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf53017_ctrl, "53017", 0}, + {mcfisa_a|mcfhwdiv|mcfmac, mcf5307_ctrl, "5307", 0}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5329_ctrl, "5327", -1}, @@ -626,7 +691,7 @@ static const struct m68k_cpu m68k_cpus[] = {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5373_ctrl, "5373", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5373_ctrl, "537x", 0}, - {mcfisa_a|mcfisa_b|mcfhwdiv|mcfmac, mcf_ctrl, "5407",0}, + {mcfisa_a|mcfisa_b|mcfhwdiv|mcfmac, mcf5407_ctrl, "5407",0}, {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54450", -1}, {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54451", -1}, @@ -719,8 +784,14 @@ static void m68k_init_arch (void); #define PCINDEX 8 /* PC + displacement + index. */ #define ABSTOPCREL 9 /* Absolute relax down to 16-bit PC-relative. */ +/* This relaxation is required for branches where there is no long + branch and we are in pcrel mode. We generate a bne/beq pair. */ +#define BRANCHBWPL 10 /* Branch byte, word or pair of longs + */ + /* Note that calls to frag_var need to specify the maximum expansion - needed; this is currently 10 bytes for DBCC. */ + needed; this is currently 12 bytes for bne/beq pair. */ +#define FRAG_VAR_SIZE 12 /* The fields are: How far Forward this mode will reach: @@ -780,6 +851,11 @@ relax_typeS md_relax_table[] = { 32767, -32768, 2, TAB (ABSTOPCREL, LONG) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, + + { 127, -128, 0, TAB (BRANCHBWPL, SHORT) }, + { 32767, -32768, 2, TAB (BRANCHBWPL, LONG) }, + { 0, 0, 10, 0 }, + { 1, 1, 0, 0 }, }; /* These are the machine dependent pseudo-ops. These are included so @@ -804,6 +880,7 @@ const pseudo_typeS md_pseudo_table[] = #endif #ifdef OBJ_ELF {"swbeg", s_ignore, 0}, + {"long", m68k_elf_cons, 4}, #endif {"extend", float_cons, 'x'}, {"ldouble", float_cons, 'x'}, @@ -976,6 +1053,66 @@ get_reloc_code (int size, int pcrel, enum pic_relocation pic) } break; + case pic_tls_gd: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_GD8; + case 2: + return BFD_RELOC_68K_TLS_GD16; + case 4: + return BFD_RELOC_68K_TLS_GD32; + } + break; + + case pic_tls_ldm: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_LDM8; + case 2: + return BFD_RELOC_68K_TLS_LDM16; + case 4: + return BFD_RELOC_68K_TLS_LDM32; + } + break; + + case pic_tls_ldo: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_LDO8; + case 2: + return BFD_RELOC_68K_TLS_LDO16; + case 4: + return BFD_RELOC_68K_TLS_LDO32; + } + break; + + case pic_tls_ie: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_IE8; + case 2: + return BFD_RELOC_68K_TLS_IE16; + case 4: + return BFD_RELOC_68K_TLS_IE32; + } + break; + + case pic_tls_le: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_LE8; + case 2: + return BFD_RELOC_68K_TLS_LE16; + case 4: + return BFD_RELOC_68K_TLS_LE32; + } + break; + case pic_none: if (pcrel) { @@ -1044,6 +1181,21 @@ tc_m68k_fix_adjustable (fixS *fixP) case BFD_RELOC_8_PLTOFF: case BFD_RELOC_16_PLTOFF: case BFD_RELOC_32_PLTOFF: + case BFD_RELOC_68K_TLS_GD32: + case BFD_RELOC_68K_TLS_GD16: + case BFD_RELOC_68K_TLS_GD8: + case BFD_RELOC_68K_TLS_LDM32: + case BFD_RELOC_68K_TLS_LDM16: + case BFD_RELOC_68K_TLS_LDM8: + case BFD_RELOC_68K_TLS_LDO32: + case BFD_RELOC_68K_TLS_LDO16: + case BFD_RELOC_68K_TLS_LDO8: + case BFD_RELOC_68K_TLS_IE32: + case BFD_RELOC_68K_TLS_IE16: + case BFD_RELOC_68K_TLS_IE8: + case BFD_RELOC_68K_TLS_LE32: + case BFD_RELOC_68K_TLS_LE16: + case BFD_RELOC_68K_TLS_LE8: return 0; case BFD_RELOC_VTABLE_INHERIT: @@ -1121,6 +1273,21 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) case BFD_RELOC_8_PLTOFF: case BFD_RELOC_16_PLTOFF: case BFD_RELOC_32_PLTOFF: + case BFD_RELOC_68K_TLS_GD32: + case BFD_RELOC_68K_TLS_GD16: + case BFD_RELOC_68K_TLS_GD8: + case BFD_RELOC_68K_TLS_LDM32: + case BFD_RELOC_68K_TLS_LDM16: + case BFD_RELOC_68K_TLS_LDM8: + case BFD_RELOC_68K_TLS_LDO32: + case BFD_RELOC_68K_TLS_LDO16: + case BFD_RELOC_68K_TLS_LDO8: + case BFD_RELOC_68K_TLS_IE32: + case BFD_RELOC_68K_TLS_IE16: + case BFD_RELOC_68K_TLS_IE8: + case BFD_RELOC_68K_TLS_LE32: + case BFD_RELOC_68K_TLS_LE16: + case BFD_RELOC_68K_TLS_LE8: break; default: as_bad_where (fixp->fx_file, fixp->fx_line, @@ -1178,7 +1345,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) #endif reloc->howto = bfd_reloc_type_lookup (stdoutput, code); - assert (reloc->howto != 0); + gas_assert (reloc->howto != 0); return reloc; } @@ -1331,7 +1498,7 @@ m68k_ip (char *instring) /* Make a copy of the operands of this insn so that we can modify them safely, should we want to. */ - assert (opsfound <= (int) ARRAY_SIZE (operands_backup)); + gas_assert (opsfound <= (int) ARRAY_SIZE (operands_backup)); for (i = 0; i < opsfound; i++) operands_backup[i] = the_ins.operands[i]; @@ -2151,7 +2318,7 @@ m68k_ip (char *instring) the_ins.error = buf; /* Make sure there's a NUL at the end of the buffer -- strncpy - won't write one when it runs out of buffer */ + won't write one when it runs out of buffer. */ buf[space] = 0; #define APPEND(STRING) \ (strncpy (buf, STRING, space), len = strlen (buf), buf += len, space -= len) @@ -2160,34 +2327,41 @@ m68k_ip (char *instring) switch (ok_arch) { case mcfisa_a: - APPEND (_("ColdFire ISA_A")); + APPEND ("ColdFire ISA_A"); break; case mcfhwdiv: - APPEND (_("ColdFire hardware divide")); + APPEND ("ColdFire "); + APPEND (_("hardware divide")); break; case mcfisa_aa: - APPEND (_("ColdFire ISA_A+")); + APPEND ("ColdFire ISA_A+"); break; case mcfisa_b: - APPEND (_("ColdFire ISA_B")); + APPEND ("ColdFire ISA_B"); + break; + case mcfisa_c: + APPEND ("ColdFire ISA_C"); break; case cfloat: - APPEND (_("ColdFire fpu")); + APPEND ("ColdFire fpu"); break; case mfloat: - APPEND (_("M68K fpu")); + APPEND ("M68K fpu"); break; case mmmu: - APPEND (_("M68K mmu")); + APPEND ("M68K mmu"); break; case m68020up: - APPEND (_("68020 or higher")); + APPEND ("68020 "); + APPEND (_("or higher")); break; case m68000up: - APPEND (_("68000 or higher")); + APPEND ("68000 "); + APPEND (_("or higher")); break; case m68010up: - APPEND (_("68010 or higher")); + APPEND ("68010 "); + APPEND (_("or higher")); break; default: paren = 0; @@ -2231,7 +2405,7 @@ m68k_ip (char *instring) #undef APPEND if (!space) { - /* we ran out of space, so replace the end of the list + /* We ran out of space, so replace the end of the list with ellipsis. */ buf -= 4; while (*buf != ' ') @@ -2257,6 +2431,7 @@ m68k_ip (char *instring) for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { int have_disp = 0; + int use_pl = 0; /* This switch is a doozy. Watch the first step; its a big one! */ @@ -2940,6 +3115,7 @@ m68k_ip (char *instring) case 'b': /* Unconditional branch */ have_disp = HAVE_LONG_BRANCH (current_architecture); + use_pl = LONG_BRANCH_VIA_COND (current_architecture); goto var_branch; case 's': /* Unconditional subroutine */ @@ -3003,7 +3179,8 @@ m68k_ip (char *instring) else add_frag (adds (&opP->disp), SEXT (offs (&opP->disp)), - TAB (BRANCHBW, SZ_UNDEF)); + (use_pl ? TAB (BRANCHBWPL, SZ_UNDEF) + : TAB (BRANCHBW, SZ_UNDEF))); break; case 'w': if (isvar (&opP->disp)) @@ -3142,6 +3319,7 @@ m68k_ip (char *instring) tmpreg = 0x801; break; case CAAR: + case CPUCR: tmpreg = 0x802; break; case MSP: @@ -3232,7 +3410,7 @@ m68k_ip (char *instring) case CAC: tmpreg = 0xFFE; break; - case MBB: + case MBO: tmpreg = 0xFFF; break; default: @@ -3553,10 +3731,9 @@ reverse_8_bits (int in) return out; } /* reverse_8_bits() */ -/* Cause an extra frag to be generated here, inserting up to 10 bytes - (that value is chosen in the frag_var call in md_assemble). TYPE - is the subtype of the frag to be generated; its primary type is - rs_machine_dependent. +/* Cause an extra frag to be generated here, inserting up to + FRAG_VAR_SIZE bytes. TYPE is the subtype of the frag to be + generated; its primary type is rs_machine_dependent. The TYPE parameter is also used by md_convert_frag_1 and md_estimate_size_before_relax. The appropriate type of fixup will @@ -3904,6 +4081,7 @@ static const struct init_entry init_table[] = { "dfcr", DFC }, { "cacr", CACR }, /* Cache Control Register. */ { "caar", CAAR }, /* Cache Address Register. */ + { "cpucr", CPUCR }, /* CPU Control Register. */ { "usp", USP }, /* User Stack Pointer. */ { "vbr", VBR }, /* Vector Base Register. */ @@ -3974,7 +4152,8 @@ static const struct init_entry init_table[] = { "mbar2", MBAR2 }, /* mcf5249 registers. */ { "cac", CAC }, /* fido registers. */ - { "mbb", MBB }, /* fido registers. */ + { "mbb", MBO }, /* fido registers (obsolete). */ + { "mbo", MBO }, /* fido registers. */ /* End of control registers. */ { "ac", AC }, @@ -4229,7 +4408,7 @@ md_assemble (char *str) for (n = 1; n < the_ins.nfrag; n++) wid += 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff); /* frag_var part. */ - wid += 10; + wid += FRAG_VAR_SIZE; /* Make sure the whole insn fits in one chunk, in particular that the var part is attached, as we access one byte before the variable frag for byte branches. */ @@ -4277,7 +4456,7 @@ md_assemble (char *str) the_ins.reloc[m].pic_reloc)); fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix; } - (void) frag_var (rs_machine_dependent, 10, 0, + (void) frag_var (rs_machine_dependent, FRAG_VAR_SIZE, 0, (relax_substateT) (the_ins.fragb[n].fragty), the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P); } @@ -4384,7 +4563,7 @@ md_begin (void) obstack_begin (&robyn, 4000); for (i = 0; i < m68k_numopcodes; i++) { - hack = slak = (struct m68k_incant *) obstack_alloc (&robyn, sizeof (struct m68k_incant)); + hack = slak = obstack_alloc (&robyn, sizeof (struct m68k_incant)); do { ins = m68k_sorted_opcodes[i]; @@ -4432,7 +4611,7 @@ md_begin (void) { const char *name = m68k_opcode_aliases[i].primary; const char *alias = m68k_opcode_aliases[i].alias; - PTR val = hash_find (op_hash, name); + void *val = hash_find (op_hash, name); if (!val) as_fatal (_("Internal Error: Can't find %s in hash table"), name); @@ -4471,7 +4650,7 @@ md_begin (void) { const char *name = mri_aliases[i].primary; const char *alias = mri_aliases[i].alias; - PTR val = hash_find (op_hash, name); + void *val = hash_find (op_hash, name); if (!val) as_fatal (_("Internal Error: Can't find %s in hash table"), name); @@ -4648,63 +4827,10 @@ m68k_mri_mode_change (int on) } } -/* 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 (int type, char *litP, int *sizeP) { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - 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_ATOF()"); - } - t = atof_ieee (input_line_pointer, type, words); - if (t) - input_line_pointer = t; - - *sizeP = prec * sizeof (LITTLENUM_TYPE); - for (wordP = words; prec--;) - { - md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } - return 0; + return ieee_md_atof (type, litP, sizeP, TRUE); } void @@ -4741,6 +4867,31 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy)) S_SET_WEAK (fixP->fx_addsy); + + switch (fixP->fx_r_type) + { + case BFD_RELOC_68K_TLS_GD32: + case BFD_RELOC_68K_TLS_GD16: + case BFD_RELOC_68K_TLS_GD8: + case BFD_RELOC_68K_TLS_LDM32: + case BFD_RELOC_68K_TLS_LDM16: + case BFD_RELOC_68K_TLS_LDM8: + case BFD_RELOC_68K_TLS_LDO32: + case BFD_RELOC_68K_TLS_LDO16: + case BFD_RELOC_68K_TLS_LDO8: + case BFD_RELOC_68K_TLS_IE32: + case BFD_RELOC_68K_TLS_IE16: + case BFD_RELOC_68K_TLS_IE8: + case BFD_RELOC_68K_TLS_LE32: + case BFD_RELOC_68K_TLS_LE16: + case BFD_RELOC_68K_TLS_LE8: + S_SET_THREAD_LOCAL (fixP->fx_addsy); + break; + + default: + break; + } + return; } #elif defined(OBJ_AOUT) @@ -4849,6 +5000,7 @@ md_convert_frag_1 (fragS *fragP) case TAB (BRABSJUNC, BYTE): case TAB (BRABSJCOND, BYTE): case TAB (BRANCHBW, BYTE): + case TAB (BRANCHBWPL, BYTE): know (issbyte (disp)); if (disp == 0) as_bad_where (fragP->fr_file, fragP->fr_line, @@ -4861,6 +5013,7 @@ md_convert_frag_1 (fragS *fragP) case TAB (BRABSJUNC, SHORT): case TAB (BRABSJCOND, SHORT): case TAB (BRANCHBW, SHORT): + case TAB (BRANCHBWPL, SHORT): fragP->fr_opcode[1] = 0x00; fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, 1, RELAX_RELOC_PC16); @@ -4872,6 +5025,24 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_offset, 1, RELAX_RELOC_PC32); fragP->fr_fix += 4; break; + case TAB (BRANCHBWPL, LONG): + /* Here we are converting an unconditional branch into a pair of + conditional branches, in order to get the range. */ + fragP->fr_opcode[0] = 0x66; /* bne */ + fragP->fr_opcode[1] = 0xFF; + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC32); + fixP->fx_file = fragP->fr_file; + fixP->fx_line = fragP->fr_line; + fragP->fr_fix += 4; /* Skip first offset */ + buffer_address += 4; + *buffer_address++ = 0x67; /* beq */ + *buffer_address++ = 0xff; + fragP->fr_fix += 2; /* Skip second branch opcode */ + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC32); + fragP->fr_fix += 4; + break; case TAB (BRABSJUNC, LONG): if (fragP->fr_opcode[0] == 0x61) /* jbsr */ { @@ -4999,14 +5170,14 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_fix += 4; break; case TAB (PCINDEX, BYTE): - assert (fragP->fr_fix >= 2); + gas_assert (fragP->fr_fix >= 2); buffer_address[-2] &= ~1; fixP = fix_new (fragP, fragP->fr_fix - 1, 1, fragP->fr_symbol, fragP->fr_offset, 1, RELAX_RELOC_PC8); fixP->fx_pcrel_adjust = 1; break; case TAB (PCINDEX, SHORT): - assert (fragP->fr_fix >= 2); + gas_assert (fragP->fr_fix >= 2); buffer_address[-2] |= 0x1; buffer_address[-1] = 0x20; fixP = fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol, @@ -5015,7 +5186,7 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_fix += 2; break; case TAB (PCINDEX, LONG): - assert (fragP->fr_fix >= 2); + gas_assert (fragP->fr_fix >= 2); buffer_address[-2] |= 0x1; buffer_address[-1] = 0x30; fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol, @@ -5030,7 +5201,8 @@ md_convert_frag_1 (fragS *fragP) break; case TAB (ABSTOPCREL, LONG): if (flag_keep_pcrel) - as_fatal (_("Conversion of PC relative displacement to absolute")); + as_bad_where (fragP->fr_file, fragP->fr_line, + _("Conversion of PC relative displacement to absolute")); /* The thing to do here is force it to ABSOLUTE LONG, since ABSTOPCREL is really trying to shorten an ABSOLUTE address anyway. */ if ((fragP->fr_opcode[1] & 0x3F) != 0x3A) @@ -5067,6 +5239,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) switch (fragP->fr_subtype) { case TAB (BRANCHBWL, SZ_UNDEF): + case TAB (BRANCHBWPL, SZ_UNDEF): case TAB (BRABSJUNC, SZ_UNDEF): case TAB (BRABSJCOND, SZ_UNDEF): { @@ -6177,8 +6350,8 @@ swap_mri_condition (int cc) case MCC ('g', 't'): return MCC ('l', 't'); case MCC ('l', 'e'): return MCC ('g', 'e'); /* Issue a warning for conditions we can not swap. */ - case MCC ('n', 'e'): return MCC ('n', 'e'); // no problem here - case MCC ('e', 'q'): return MCC ('e', 'q'); // also no problem + case MCC ('n', 'e'): return MCC ('n', 'e'); /* no problem here */ + case MCC ('e', 'q'): return MCC ('e', 'q'); /* also no problem */ case MCC ('v', 'c'): case MCC ('v', 's'): default : @@ -7223,7 +7396,7 @@ m68k_lookup_cpu (const char *arg, const struct m68k_cpu *table, return 0; } -/* Set the cpu, issuing errors if it is unrecognized, or invalid */ +/* Set the cpu, issuing errors if it is unrecognized. */ static int m68k_set_cpu (char const *name, int allow_m, int silent) @@ -7238,18 +7411,11 @@ m68k_set_cpu (char const *name, int allow_m, int silent) as_bad (_("cpu `%s' unrecognized"), name); return 0; } - - if (selected_cpu && selected_cpu != cpu) - { - as_bad (_("already selected `%s' processor"), - selected_cpu->name); - return 0; - } selected_cpu = cpu; return 1; } -/* Set the architecture, issuing errors if it is unrecognized, or invalid */ +/* Set the architecture, issuing errors if it is unrecognized. */ static int m68k_set_arch (char const *name, int allow_m, int silent) @@ -7264,14 +7430,6 @@ m68k_set_arch (char const *name, int allow_m, int silent) as_bad (_("architecture `%s' unrecognized"), name); return 0; } - - if (selected_arch && selected_arch != arch) - { - as_bad (_("already selected `%s' architecture"), - selected_arch->name); - return 0; - } - selected_arch = arch; return 1; } @@ -7295,7 +7453,8 @@ m68k_set_extension (char const *name, int allow_m, int silent) } if (negated) - not_current_architecture |= ext->arch; + not_current_architecture |= (ext->control_regs + ? *(unsigned *)ext->control_regs: ext->arch); else current_architecture |= ext->arch; return 1; @@ -7553,7 +7712,7 @@ md_show_usage (FILE *stream) { if (i) fprintf (stream, " | "); - fprintf (stream, m68k_archs[i].name); + fprintf (stream, "%s", m68k_archs[i].name); } fprintf (stream, "\n"); @@ -7562,7 +7721,7 @@ md_show_usage (FILE *stream) { if (i) fprintf (stream, " | "); - fprintf (stream, m68k_cpus[i].name); + fprintf (stream, "%s", m68k_cpus[i].name); } fprintf (stream, _("\n")); } @@ -7734,6 +7893,7 @@ m68k_elf_final_processing (void) {EF_M68K_CF_ISA_B_NOUSP,mcfisa_a|mcfisa_b|mcfhwdiv}, {EF_M68K_CF_ISA_B, mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp}, {EF_M68K_CF_ISA_C, mcfisa_a|mcfisa_c|mcfhwdiv|mcfusp}, + {EF_M68K_CF_ISA_C_NODIV,mcfisa_a|mcfisa_c|mcfusp}, {0,0}, }; static const unsigned mac_features[][2] = @@ -7783,6 +7943,115 @@ m68k_elf_final_processing (void) } elf_elfheader (stdoutput)->e_flags |= flags; } + +/* Parse @TLSLDO and return the desired relocation. */ +static bfd_reloc_code_real_type +m68k_elf_suffix (char **str_p, expressionS *exp_p) +{ + char ident[20]; + char *str = *str_p; + char *str2; + int ch; + int len; + + if (*str++ != '@') + return BFD_RELOC_UNUSED; + + for (ch = *str, str2 = ident; + (str2 < ident + sizeof (ident) - 1 + && (ISALNUM (ch) || ch == '@')); + ch = *++str) + { + *str2++ = ch; + } + + *str2 = '\0'; + len = str2 - ident; + + if (strncmp (ident, "TLSLDO", 6) == 0 + && len == 6) + { + /* Now check for identifier@suffix+constant. */ + if (*str == '-' || *str == '+') + { + char *orig_line = input_line_pointer; + expressionS new_exp; + + input_line_pointer = str; + expression (&new_exp); + if (new_exp.X_op == O_constant) + { + exp_p->X_add_number += new_exp.X_add_number; + str = input_line_pointer; + } + + if (&input_line_pointer != str_p) + input_line_pointer = orig_line; + } + *str_p = str; + + return BFD_RELOC_68K_TLS_LDO32; + } + + return BFD_RELOC_UNUSED; +} + +/* Handles .long +0x8000 debug info. + Clobbers input_line_pointer, checks end-of-line. + Adapted from tc-ppc.c:ppc_elf_cons. */ +static void +m68k_elf_cons (int nbytes /* 4=.long */) +{ + if (is_it_end_of_statement ()) + { + demand_empty_rest_of_line (); + return; + } + + do + { + expressionS exp; + bfd_reloc_code_real_type reloc; + + expression (&exp); + if (exp.X_op == O_symbol + && *input_line_pointer == '@' + && (reloc = m68k_elf_suffix (&input_line_pointer, + &exp)) != BFD_RELOC_UNUSED) + { + reloc_howto_type *reloc_howto; + int size; + + reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc); + size = bfd_get_reloc_size (reloc_howto); + + if (size > nbytes) + { + as_bad (_("%s relocations do not fit in %d bytes\n"), + reloc_howto->name, nbytes); + } + else + { + char *p; + int offset; + + p = frag_more (nbytes); + offset = 0; + if (target_big_endian) + offset = nbytes - size; + fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size, + &exp, 0, reloc); + } + } + else + emit_expr (&exp, (unsigned int) nbytes); + } + while (*input_line_pointer++ == ','); + + /* Put terminator back into stream. */ + input_line_pointer--; + demand_empty_rest_of_line (); +} #endif int