/* 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.
+ Copyright (C) 1987-2017 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#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
{
struct label_line *next;
symbolS *label;
- char *file;
+ const char *file;
unsigned int line;
int text;
};
RAMBAR0, RAMBAR1, RAMBAR, MBAR,
0
};
-static const enum m68k_register mcf51qe_ctrl[] = {
- VBR,
+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,
+ CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR,
0
};
static const enum m68k_register mcf5208_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,
+ VBR, FLASHBAR, RAMBAR, RAMBAR1,
0
};
static const enum m68k_register mcf52235_ctrl[] = {
- VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1,
+ VBR, FLASHBAR, RAMBAR, RAMBAR1,
0
};
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
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[] = {
MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */,
0
};
+static const enum m68k_register mcf54418_ctrl[] = {
+ CACR, ASID, ACR0, ACR1, ACR2, ACR3, ACR4, ACR5, ACR6, ACR7, MMUBAR, RGPIOBAR,
+ VBR, PC, RAMBAR1,
+ /* Legacy names */
+ TC /* ASID */, BUSCR /* MMUBAR */,
+ ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */,
+ RAMBAR /* RAMBAR1 */,
+ 0
+};
static const enum m68k_register mcf54455_ctrl[] = {
CACR, ASID, ACR0, ACR1, ACR2, ACR3, MMUBAR,
- VBR, PC, RAMBAR1, MBAR,
+ VBR, PC, RAMBAR1,
/* Legacy names */
TC /* ASID */, BUSCR /* MMUBAR */,
ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */,
- MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */,
+ RAMBAR /* RAMBAR1 */,
0
};
static const enum m68k_register mcf5475_ctrl[] = {
unsigned long arch; /* Architecture features. */
const enum m68k_register *control_regs; /* Control regs on chip */
const char *name; /* Name */
- int alias; /* Alias for a cannonical name. If 1, then
+ int alias; /* Alias for a canonical name. If 1, then
succeeds canonical name, if -1 then
succeeds canonical name, if <-1 ||>1 this is a
deprecated name, and the next/previous name
{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[] =
{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}
};
{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},
{cpu32|m68881, cpu32_ctrl, "68349", 1},
{cpu32|m68881, cpu32_ctrl, "68360", 1},
- {mcfisa_a|mcfisa_c|mcfusp, mcf51qe_ctrl, "51qe", 0},
-
+ {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, "51ag", 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|mcfmac, mcf51_ctrl, "51je", 1},
+ {mcfisa_a|mcfisa_c|mcfusp|mcfemac, mcf51_ctrl, "51jf", 1},
+ {mcfisa_a|mcfisa_c|mcfusp|mcfemac, mcf51_ctrl, "51jg", 1},
+ {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51jm", 1},
+ {mcfisa_a|mcfisa_c|mcfusp|mcfmac, mcf51_ctrl, "51mm", 1},
+ {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51qe", 1},
+ {mcfisa_a|mcfisa_c|mcfusp|mcfemac, mcf51_ctrl, "51qm", 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},
{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},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "5234", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "5235", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "523x", 0},
-
+
{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},
-
+
{mcfisa_a|mcfhwdiv|mcfmac, mcf5272_ctrl, "5272", 0},
-
+
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5275_ctrl, "5274", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5275_ctrl, "5275", 0},
-
+
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5282_ctrl, "5280", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5282_ctrl, "5281", -1},
{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},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5329_ctrl, "5328", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5329_ctrl, "5329", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5329_ctrl, "532x", 0},
-
+
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5373_ctrl, "5372", -1},
{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, mcf5407_ctrl, "5407",0},
+ {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54418_ctrl, "54410", -1},
+ {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54418_ctrl, "54415", -1},
+ {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54418_ctrl, "54416", -1},
+ {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54418_ctrl, "54417", -1},
+ {mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54418_ctrl, "54418", 0},
+
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54450", -1},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54451", -1},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54452", -1},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54453", -1},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54454", -1},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54455", 0},
-
+
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5475_ctrl, "5470", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5475_ctrl, "5471", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5475_ctrl, "5472", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5475_ctrl, "5474", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5475_ctrl, "5475", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5475_ctrl, "547x", 0},
-
+
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5485_ctrl, "5480", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5485_ctrl, "5481", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5485_ctrl, "5482", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5485_ctrl, "5484", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5485_ctrl, "5485", -1},
{mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcf5485_ctrl, "548x", 0},
-
+
{fido_a, fido_ctrl, "fidoa", 0},
{fido_a, fido_ctrl, "fido", 1},
{ 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 },
#endif
#ifdef OBJ_ELF
{"swbeg", s_ignore, 0},
+ {"long", m68k_elf_cons, 4},
#endif
{"extend", float_cons, 'x'},
{"ldouble", float_cons, 'x'},
}
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)
{
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:
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,
#undef F
#undef MAP
- reloc = (arelent *) xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ reloc = XNEW (arelent);
+ reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
#ifndef OBJ_ELF
- if (fixp->fx_pcrel)
+ if (OUTPUT_FLAVOR == bfd_target_aout_flavour
+ && fixp->fx_addsy
+ && S_IS_WEAK (fixp->fx_addsy)
+ && ! bfd_is_und_section (S_GET_SEGMENT (fixp->fx_addsy)))
+ {
+ /* PR gas/3041 References to weak symbols must be treated as extern
+ in order to be overridable by the linker, even if they are defined
+ in the same object file. So the original addend must be written
+ "as is" into the output section without further processing.
+ The addend value must be hacked here in order to force
+ bfd_install_relocation() to write the original value into the
+ output section.
+ 1) MD_APPLY_SYM_VALUE() is set to 1 for m68k/a.out, so the symbol
+ value has already been added to the addend in fixup_segment(). We
+ have to remove it.
+ 2) bfd_install_relocation() will incorrectly treat this symbol as
+ resolved, so it will write the symbol value plus its addend and
+ section VMA. As a workaround we can tweak the addend value here in
+ order to get the original value in the section after the call to
+ bfd_install_relocation(). */
+ reloc->addend = fixp->fx_addnumber
+ /* Fix because of MD_APPLY_SYM_VALUE() */
+ - S_GET_VALUE (fixp->fx_addsy)
+ /* Fix for bfd_install_relocation() */
+ - (S_GET_VALUE (fixp->fx_addsy)
+ + S_GET_SEGMENT (fixp->fx_addsy)->vma);
+ }
+ else if (fixp->fx_pcrel)
reloc->addend = fixp->fx_addnumber;
- else if (OUTPUT_FLAVOR == bfd_target_aout_flavour
- && fixp->fx_addsy
- && S_IS_WEAK (fixp->fx_addsy)
- && ! bfd_is_und_section (S_GET_SEGMENT (fixp->fx_addsy)))
- /* PR gas/3041 Adjust addend in order to force bfd_install_relocation()
- to put the symbol offset into frags referencing a weak symbol. */
- reloc->addend = fixp->fx_addnumber
- - (S_GET_VALUE (fixp->fx_addsy) * 2);
else
reloc->addend = 0;
#else
reloc->addend = fixp->fx_addnumber;
else
reloc->addend = (section->vma
- /* Explicit sign extension in case char is
- unsigned. */
- + ((fixp->fx_pcrel_adjust & 0xff) ^ 0x80) - 0x80
+ + fixp->fx_pcrel_adjust
+ fixp->fx_addnumber
+ md_pcrel_from (fixp));
#endif
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
- assert (reloc->howto != 0);
+ gas_assert (reloc->howto != 0);
return reloc;
}
static void
m68k_ip (char *instring)
{
- register char *p;
- register struct m68k_op *opP;
- register const struct m68k_incant *opcode;
- register const char *s;
- register int tmpreg = 0, baseo = 0, outro = 0, nextword;
+ char *p;
+ struct m68k_op *opP;
+ const struct m68k_incant *opcode;
+ const char *s;
+ int tmpreg = 0, baseo = 0, outro = 0, nextword;
char *pdot, *pdotmove;
enum m68k_size siz1, siz2;
char c;
char *old = input_line_pointer;
*old = '\n';
input_line_pointer = p;
- /* Ahh - it's a motorola style psuedo op. */
+ /* Ahh - it's a motorola style pseudo op. */
mote_pseudo_table[opcode->m_opnum].poc_handler
(mote_pseudo_table[opcode->m_opnum].poc_val);
input_line_pointer = old;
/* 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];
else
{
const enum m68k_register *rp;
-
+
for (rp = control_regs; *rp; rp++)
{
if (*rp == opP->reg)
const struct m68k_cpu *cpu;
int any = 0;
size_t space = 400;
- char *buf = xmalloc (space + 1);
+ char *buf = XNEWVEC (char, space + 1);
size_t len;
int paren = 1;
{
const struct m68k_cpu *alias;
int seen_master = 0;
-
+
if (any)
APPEND (", ");
any = 0;
{
int have_disp = 0;
int use_pl = 0;
-
+
/* This switch is a doozy.
Watch the first step; its a big one! */
switch (s[0])
TAB (ABSTOPCREL, SZ_UNDEF));
break;
}
- /* Fall through into long. */
+ /* Fall through. */
case SIZE_LONG:
if (isvar (&opP->disp))
add_fix ('l', &opP->disp, 0, 0);
break;
case '3':
tmpreg &= 0xFF;
+ /* Fall through. */
case '8':
case 'C':
case 'j':
case 'B':
tmpreg = get_num (&opP->disp, 90);
-
+
switch (s[1])
{
case 'B':
case 'g': /* Conditional branch */
have_disp = HAVE_LONG_CALL (current_architecture);
goto var_branch;
-
+
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 */
have_disp = HAVE_LONG_CALL (current_architecture);
-
+
var_branch:
if (subs (&opP->disp) /* We can't relax it. */
#ifdef OBJ_ELF
as_warn (_("Can't use long branches on this architecture"));
goto long_branch;
}
-
+
/* This could either be a symbol, or an absolute
address. If it's an absolute address, turn it into
an absolute jump right here and keep it out of the
case 'e': /* EMAC ACCx, reg/reg. */
install_operand (s[1], opP->reg - ACC);
break;
-
+
case 'E': /* Ignore it. */
break;
case MMUBAR:
tmpreg = 0x008;
break;
+ case RGPIOBAR:
+ tmpreg = 0x009;
+ break;
+ case ACR4:
+ case ACR5:
+ case ACR6:
+ case ACR7:
+ tmpreg = 0x00c + (opP->reg - ACR4);
+ break;
case USP:
tmpreg = 0x800;
tmpreg = 0x801;
break;
case CAAR:
+ case CPUCR:
tmpreg = 0x802;
break;
case MSP:
static char *
crack_operand (char *str, struct m68k_op *opP)
{
- register int parens;
- register int c;
- register char *beg_str;
+ int parens;
+ int c;
+ char *beg_str;
int inquote = 0;
if (!str)
{ "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. */
{ "acr1", ACR1 }, /* Access Control Unit 1. */
{ "acr2", ACR2 }, /* Access Control Unit 2. */
{ "acr3", ACR3 }, /* Access Control Unit 3. */
+ { "acr4", ACR4 }, /* Access Control Unit 4. */
+ { "acr5", ACR5 }, /* Access Control Unit 5. */
+ { "acr6", ACR6 }, /* Access Control Unit 6. */
+ { "acr7", ACR7 }, /* Access Control Unit 7. */
{ "tc", TC }, /* MMU Translation Control Register. */
{ "tcr", TC },
{ "mbar2", MBAR2 }, /* mcf5249 registers. */
+ { "rgpiobar", RGPIOBAR }, /* mcf54418 registers. */
+
{ "cac", CAC }, /* fido registers. */
{ "mbb", MBO }, /* fido registers (obsolete). */
{ "mbo", MBO }, /* fido registers. */
}
if (!initialized)
m68k_init_arch ();
-
+
/* In MRI mode, the instruction and operands are separated by a
space. Anything following the operands is a comment. The label
has already been removed. */
(relax_substateT) (the_ins.fragb[n].fragty),
the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
}
- n = (the_ins.numo - the_ins.fragb[n - 1].fragoff);
+ gas_assert (the_ins.nfrag >= 1);
+ n = the_ins.numo - the_ins.fragb[the_ins.nfrag - 1].fragoff;
shorts_this_frag = 0;
if (n)
{
m68k_rel32 = 0;
}
- /* First sort the opcode table into alphabetical order to seperate
+ /* First sort the opcode table into alphabetical order to separate
the order that the assembler wants to see the opcodes from the
order that the disassembler wants to see them. */
- m68k_sorted_opcodes = xmalloc (m68k_numopcodes * sizeof (* m68k_sorted_opcodes));
- if (!m68k_sorted_opcodes)
- as_fatal (_("Internal Error: Can't allocate m68k_sorted_opcodes of size %d"),
- m68k_numopcodes * ((int) sizeof (* m68k_sorted_opcodes)));
+ m68k_sorted_opcodes = XNEWVEC (const struct m68k_opcode *, m68k_numopcodes);
for (i = m68k_numopcodes; i--;)
m68k_sorted_opcodes[i] = m68k_opcodes + i;
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 = XOBNEW (&robyn, struct m68k_incant);
do
{
ins = m68k_sorted_opcodes[i];
slak->m_operands = ins->args;
slak->m_arch = ins->arch;
slak->m_opcode = ins->opcode;
-
+
/* In most cases we can determine the number of opcode words
by checking the second word of the mask. Unfortunately
some instructions have 2 opcode words, but no fixed bits
else
slak->m_codenum = 1;
slak->m_opnum = strlen (slak->m_operands) / 2;
-
+
if (i + 1 != m68k_numopcodes
&& !strcmp (ins->name, m68k_sorted_opcodes[i + 1]->name))
{
- slak->m_next = obstack_alloc (&robyn, sizeof (struct m68k_incant));
+ slak->m_next = XOBNEW (&robyn, struct m68k_incant);
i++;
}
else
{
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);
{
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);
while (mote_pseudo_table[n].poc_name)
{
- hack = obstack_alloc (&robyn, sizeof (struct m68k_incant));
+ hack = XOBNEW (&robyn, struct m68k_incant);
hash_insert (op_hash,
mote_pseudo_table[n].poc_name, (char *) hack);
hack->m_operands = 0;
{
struct label_line *n;
- n = (struct label_line *) xmalloc (sizeof *n);
+ n = XNEW (struct label_line);
n->next = labels;
n->label = sym;
- as_where (&n->file, &n->line);
+ n->file = as_where (&n->line);
n->text = 0;
labels = n;
current_label = n;
}
}
-char *
+const char *
md_atof (int type, char *litP, int *sizeP)
{
return ieee_md_atof (type, litP, sizeP, TRUE);
&& !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)
fixS *fixP = NULL;
/* Address in object code of the displacement. */
- register int object_address = fragP->fr_fix + fragP->fr_address;
+ int object_address = fragP->fr_fix + fragP->fr_address;
/* Address in gas core of the place to store the displacement. */
/* This convinces the native rs6000 compiler to generate the code we
want. */
- register char *buffer_address = fragP->fr_literal;
+ char *buffer_address = fragP->fr_literal;
buffer_address += fragP->fr_fix;
/* End ibm compiler workaround. */
/* Only DBcc instructions can come here.
Change dbcc into dbcc/bral.
JF: these used to be fr_opcode[2-7], but that's wrong. */
- if (flag_keep_pcrel)
- as_bad_where (fragP->fr_file, fragP->fr_line,
- _("Conversion of DBcc to absolute jump"));
-
*buffer_address++ = 0x00; /* Branch offset = 4. */
*buffer_address++ = 0x04;
*buffer_address++ = 0x60; /* Put in bra pc+6. */
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,
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,
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)
static void
s_even (int ignore ATTRIBUTE_UNUSED)
{
- register int temp;
- register long temp_fill;
+ int temp;
+ long temp_fill;
temp = 1; /* JF should be 2? */
temp_fill = get_absolute_expression ();
int i;
s = input_line_pointer;
- /* We can't use get_symbol_end since the processor names are not proper
+ /* We can't use get_symbol_name since the processor names are not proper
symbols. */
while (is_part_of_name (c = *input_line_pointer++))
;
{
++input_line_pointer;
s = input_line_pointer;
- /* We can't use get_symbol_end since the processor names are not
+ /* We can't use get_symbol_name since the processor names are not
proper symbols. */
while (is_part_of_name (c = *input_line_pointer++))
;
t = 0;
}
- s = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&s);
for (i = 0, o = opt_table; i < OPTCOUNT; i++, o++)
{
{
/* Restore input_line_pointer now in case the option
takes arguments. */
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
(*o->pfn) (o->arg, t);
}
else if (o->pvar != NULL)
{
if (! t && o->arg == o->notarg)
as_bad (_("option `%s' may not be negated"), s);
- *input_line_pointer = c;
+ restore_line_pointer (c);
*o->pvar = t ? o->arg : o->notarg;
}
else
if (i >= OPTCOUNT)
{
as_bad (_("option `%s' not recognized"), s);
- *input_line_pointer = c;
+ restore_line_pointer (c);
}
}
while (*input_line_pointer++ == ',');
{
struct save_opts *s;
- s = (struct save_opts *) xmalloc (sizeof (struct save_opts));
+ s = XNEW (struct save_opts);
s->abspcadd = m68k_abspcadd;
s->symbols_case_sensitive = symbols_case_sensitive;
s->keep_locals = flag_keep_locals;
{
char *n;
- n = (char *) xmalloc (20);
+ n = XNEWVEC (char, 20);
sprintf (n, "%smc%d", FAKE_LABEL_NAME, mri_control_index);
++mri_control_index;
return n;
{
struct mri_control_info *n;
- n = (struct mri_control_info *) xmalloc (sizeof (struct mri_control_info));
+ n = XNEW (struct mri_control_info);
n->type = type;
n->else_seen = 0;
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 :
if (leftstart != NULL)
{
- buf = (char *) xmalloc (20
- + (leftstop - leftstart)
- + (rightstop - rightstart));
+ buf = XNEWVEC (char, (20
+ + (leftstop - leftstart)
+ + (rightstop - rightstart)));
s = buf;
*s++ = 'c';
*s++ = 'm';
free (buf);
}
- buf = (char *) xmalloc (20 + strlen (truelab));
+ buf = XNEWVEC (char, 20 + strlen (truelab));
s = buf;
*s++ = 'b';
*s++ = cc >> 8;
mri_control_stack->else_seen = 1;
- buf = (char *) xmalloc (20 + strlen (mri_control_stack->bottom));
+ buf = XNEWVEC (char, 20 + strlen (mri_control_stack->bottom));
q[0] = TOLOWER (qual);
q[1] = '\0';
sprintf (buf, "bra%s %s", q, mri_control_stack->bottom);
return;
}
- buf = (char *) xmalloc (20 + strlen (n->bottom));
+ buf = XNEWVEC (char, 20 + strlen (n->bottom));
ex[0] = TOLOWER (extent);
ex[1] = '\0';
sprintf (buf, "bra%s %s", ex, n->bottom);
return;
}
- buf = (char *) xmalloc (20 + strlen (n->next));
+ buf = XNEWVEC (char, 20 + strlen (n->next));
ex[0] = TOLOWER (extent);
ex[1] = '\0';
sprintf (buf, "bra%s %s", ex, n->next);
/* We have fully parsed the FOR operands. Now build the loop. */
n = push_mri_control (mri_for);
- buf = (char *) xmalloc (50 + (input_line_pointer - varstart));
+ buf = XNEWVEC (char, 50 + (input_line_pointer - varstart));
/* Move init,var. */
s = buf;
return;
}
- buf = (char *) xmalloc (20 + strlen (mri_control_stack->next));
+ buf = XNEWVEC (char, 20 + strlen (mri_control_stack->next));
sprintf (buf, "bra %s", mri_control_stack->next);
mri_assemble (buf);
free (buf);
ignore_rest_of_line ();
return;
}
-
+
name = input_line_pointer;
while (*input_line_pointer && !ISSPACE(*input_line_pointer))
input_line_pointer++;
*input_line_pointer = 0;
m68k_set_cpu (name, 1, 0);
-
+
*input_line_pointer = saved_char;
demand_empty_rest_of_line ();
return;
ignore_rest_of_line ();
return;
}
-
+
name = input_line_pointer;
while (*input_line_pointer && *input_line_pointer != ','
&& !ISSPACE (*input_line_pointer))
}
while (m68k_set_extension (name, 1, 0));
}
-
+
*input_line_pointer = saved_char;
demand_empty_rest_of_line ();
return;
*negated = 1;
}
}
-
+
/* Remove 'm' or 'mc' prefix from 68k variants. */
if (allow_m)
{
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)
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)
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;
}
}
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;
size_t md_longopts_size = sizeof (md_longopts);
int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
{
switch (c)
{
char *n, *t;
const char *s;
- n = (char *) xmalloc (strlen (m68k_comment_chars) + 1);
+ n = XNEWVEC (char, strlen (m68k_comment_chars) + 1);
t = n;
for (s = m68k_comment_chars; *s != '\0'; s++)
if (*s != '|')
}
else
current_architecture |= selected_cpu->arch;
-
+
current_architecture &= ~not_current_architecture;
if ((current_architecture & (cfloat | m68881)) == (cfloat | m68881))
else
current_architecture &= ~m68k_mask;
}
-
+
/* Permit m68881 specification with all cpus; those that can't work
with a coprocessor could be doing emulation. */
if (current_architecture & m68851)
if (cpu_of_arch (current_architecture) < m68020
|| arch_coldfire_p (current_architecture))
md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0;
-
+
initialized = 1;
}
{
const char *default_cpu = TARGET_CPU;
int i;
- unsigned int default_arch;
/* Get the canonical name for the default target CPU. */
if (*default_cpu == 'm')
{
if (strcasecmp (default_cpu, m68k_cpus[i].name) == 0)
{
- default_arch = m68k_cpus[i].arch;
while (m68k_cpus[i].alias > 0)
i--;
while (m68k_cpus[i].alias < 0)
"), m68k_extensions[i].name,
m68k_extensions[i].alias > 0 ? " ColdFire"
: m68k_extensions[i].alias < 0 ? " m68k" : "");
-
+
fprintf (stream, _("\
-l use 1 word for refs to undefined symbols [default 2]\n\
-pic, -k generate position independent code\n\
--disp-size-default-16 displacement with unknown size is 16 bits\n\
--disp-size-default-32 displacement with unknown size is 32 bits (default)\n\
"));
-
+
fprintf (stream, _("Architecture variants are: "));
for (i = 0; m68k_archs[i].name; i++)
{
if (i)
fprintf (stream, " | ");
- fprintf (stream, m68k_archs[i].name);
+ fprintf (stream, "%s", m68k_archs[i].name);
}
fprintf (stream, "\n");
{
if (i)
fprintf (stream, " | ");
- fprintf (stream, m68k_cpus[i].name);
+ fprintf (stream, "%s", m68k_cpus[i].name);
}
fprintf (stream, _("\n"));
}
int align;
align = bfd_get_section_alignment (stdoutput, segment);
- size = ((size + (1 << align) - 1) & ((valueT) -1 << align));
+ size = ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
#endif
return size;
{
int adjust;
- /* Because fx_pcrel_adjust is a char, and may be unsigned, we explicitly
- sign extend the value here. */
- adjust = ((fixP->fx_pcrel_adjust & 0xff) ^ 0x80) - 0x80;
+ adjust = fixP->fx_pcrel_adjust;
if (adjust == 64)
adjust = -1;
return fixP->fx_where + fixP->fx_frag->fr_address - adjust;
m68k_elf_final_processing (void)
{
unsigned flags = 0;
-
+
if (arch_coldfire_fpu (current_architecture))
flags |= EF_M68K_CFV4E;
/* Set file-specific flags if this is a cpu32 processor. */
else if ((cpu_of_arch (current_architecture) & m68000up)
&& !(cpu_of_arch (current_architecture) & m68020up))
flags |= EF_M68K_M68000;
-
+
if (current_architecture & mcfisa_a)
{
static const unsigned isa_features[][2] =
};
unsigned ix;
unsigned pattern;
-
+
pattern = (current_architecture
& (mcfisa_a|mcfisa_aa|mcfisa_b|mcfisa_c|mcfhwdiv|mcfusp));
for (ix = 0; isa_features[ix][1]; ix++)
}
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 <tls_symbol>+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
-tc_m68k_regname_to_dw2regnum (char *regname)
+tc_m68k_regname_to_dw2regnum (const char *regname)
{
unsigned int regnum;
static const char *const regnames[] =
cfi_add_CFA_def_cfa (sp_regno, -DWARF2_CIE_DATA_ALIGNMENT);
cfi_add_CFA_offset (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT);
}
+
+/* Check and emit error if broken-word handling has failed to fix up a
+ case-table. This is called from write.c, after doing everything it
+ knows about how to handle broken words. */
+
+void
+tc_m68k_check_adjusted_broken_word (offsetT new_offset, struct broken_word *brokwP)
+{
+ if (new_offset > 32767 || new_offset < -32768)
+ as_bad_where (brokwP->frag->fr_file, brokwP->frag->fr_line,
+ _("Adjusted signed .word (%#lx) overflows: `switch'-statement too large."),
+ (long) new_offset);
+}
+