X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68k.c;h=4d2c0e4d05617ad017f3fa0100d6972ccb97ade8;hb=87789e08e5cb2191af1122ed98af2d6c023b3a0a;hp=f5646cdc10f6c27a91d28e374b4f9171a9c72430;hpb=a9d34880555ed60254118c80850a4e4a6f62104f;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index f5646cdc10..4d2c0e4d05 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1,12 +1,11 @@ /* 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 Free Software Foundation, Inc. + Copyright (C) 1987-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, @@ -37,6 +36,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 @@ -119,7 +122,7 @@ struct label_line { struct label_line *next; symbolS *label; - char *file; + const char *file; unsigned int line; int text; }; @@ -152,58 +155,192 @@ struct m68k_incant #define getone(x) ((((x)->m_opcode)>>16)&0xffff) #define gettwo(x) (((x)->m_opcode)&0xffff) -static const enum m68k_register m68000_control_regs[] = { 0 }; -static const enum m68k_register m68010_control_regs[] = { +static const enum m68k_register m68000_ctrl[] = { 0 }; +static const enum m68k_register m68010_ctrl[] = { SFC, DFC, USP, VBR, 0 }; -static const enum m68k_register m68020_control_regs[] = { +static const enum m68k_register m68020_ctrl[] = { SFC, DFC, USP, VBR, CACR, CAAR, MSP, ISP, 0 }; -static const enum m68k_register m68040_control_regs[] = { +static const enum m68k_register m68040_ctrl[] = { SFC, DFC, CACR, TC, ITT0, ITT1, DTT0, DTT1, USP, VBR, MSP, ISP, MMUSR, URP, SRP, 0 }; -static const enum m68k_register m68060_control_regs[] = { +static const enum m68k_register m68060_ctrl[] = { SFC, DFC, CACR, TC, ITT0, ITT1, DTT0, DTT1, BUSCR, USP, VBR, URP, SRP, PCR, 0 }; -static const enum m68k_register mcf_control_regs[] = { +static const enum m68k_register mcf_ctrl[] = { CACR, TC, ACR0, ACR1, ACR2, ACR3, VBR, ROMBAR, - RAMBAR0, RAMBAR1, MBAR, + 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 +}; +static const enum m68k_register mcf5208_ctrl[] = { + CACR, ACR0, ACR1, VBR, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcf5210a_ctrl[] = { + VBR, CACR, ACR0, ACR1, ROMBAR, RAMBAR, RAMBAR1, MBAR, + 0 +}; +static const enum m68k_register mcf5213_ctrl[] = { + VBR, RAMBAR, RAMBAR1, FLASHBAR, + 0 +}; +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, FLASHBAR, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcf52235_ctrl[] = { + VBR, FLASHBAR, RAMBAR, RAMBAR1, 0 }; -static const enum m68k_register mcf5208_control_regs[] = { - CACR, ACR0, ACR1, VBR, RAMBAR1, +static const enum m68k_register mcf5225_ctrl[] = { + VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, MBAR, RAMBAR1, 0 }; -static const enum m68k_register mcf5213_control_regs[] = { - VBR, RAMBAR, FLASHBAR, +static const enum m68k_register mcf52259_ctrl[] = { + VBR, FLASHBAR, RAMBAR, RAMBAR1, 0 }; -static const enum m68k_register mcf5329_control_regs[] = { - CACR, ACR0, ACR1, VBR, RAMBAR, +static const enum m68k_register mcf52277_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, 0 }; -static const enum m68k_register mcf5249_control_regs[] = { - CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR1, MBAR, MBAR2, +static const enum m68k_register mcf5235_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, 0 }; -static const enum m68k_register mcf528x_control_regs[] = { - CACR, ACR0, ACR1, VBR, FLASHBAR, RAMBAR, +static const enum m68k_register mcf5249_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, RAMBAR, MBAR, MBAR2, 0 }; -static const enum m68k_register mcfv4e_control_regs[] = { - CACR, TC, ITT0, ITT1, DTT0, DTT1, BUSCR, VBR, PC, ROMBAR, - ROMBAR1, RAMBAR0, RAMBAR1, MPCR, EDRAMBAR, SECMBAR, MBAR, MBAR0, MBAR1, +static const enum m68k_register mcf5250_ctrl[] = { + VBR, + 0 +}; +static const enum m68k_register mcf5253_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, RAMBAR, MBAR, MBAR2, + 0 +}; +static const enum m68k_register mcf5271_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcf5272_ctrl[] = { + VBR, CACR, ACR0, ACR1, ROMBAR, RAMBAR_ALT, RAMBAR0, MBAR, + 0 +}; +static const enum m68k_register mcf5275_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; +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[] = { + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR_ALT, MBAR, + 0 +}; +static const enum m68k_register mcf5329_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcf5373_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcfv4e_ctrl[] = { + CACR, ASID, ACR0, ACR1, ACR2, ACR3, MMUBAR, + VBR, PC, ROMBAR0, ROMBAR1, RAMBAR0, RAMBAR1, + MBAR, SECMBAR, + MPCR /* Multiprocessor Control register */, + EDRAMBAR /* Embedded DRAM Base Address Register */, + /* Permutation control registers. */ PCR1U0, PCR1L0, PCR1U1, PCR1L1, PCR2U0, PCR2L0, PCR2U1, PCR2L1, PCR3U0, PCR3L0, PCR3U1, PCR3L1, + /* Legacy names */ + TC /* ASID */, BUSCR /* MMUBAR */, + ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */, + MBAR1 /* MBAR */, MBAR2 /* SECMBAR */, MBAR0 /* SECMBAR */, + 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 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, + /* Legacy names */ + TC /* ASID */, BUSCR /* MMUBAR */, + ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */, + RAMBAR /* RAMBAR1 */, 0 }; -#define cpu32_control_regs m68010_control_regs +static const enum m68k_register mcf5475_ctrl[] = { + CACR, ASID, ACR0, ACR1, ACR2, ACR3, MMUBAR, + VBR, PC, RAMBAR0, RAMBAR1, MBAR, + /* Legacy names */ + TC /* ASID */, BUSCR /* MMUBAR */, + ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */, + MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */, + 0 +}; +static const enum m68k_register mcf5485_ctrl[] = { + CACR, ASID, ACR0, ACR1, ACR2, ACR3, MMUBAR, + VBR, PC, RAMBAR0, RAMBAR1, MBAR, + /* Legacy names */ + TC /* ASID */, BUSCR /* MMUBAR */, + ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */, + MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */, + 0 +}; +static const enum m68k_register fido_ctrl[] = { + SFC, DFC, USP, VBR, CAC, MBO, + 0 +}; +#define cpu32_ctrl m68010_ctrl static const enum m68k_register *control_regs; @@ -256,14 +393,22 @@ struct m68k_it reloc[5]; /* Five is enough??? */ }; -#define cpu_of_arch(x) ((x) & (m68000up | mcfisa_a)) +#define cpu_of_arch(x) ((x) & (m68000up | mcfisa_a | fido_a)) #define float_of_arch(x) ((x) & mfloat) #define mmu_of_arch(x) ((x) & mmmu) #define arch_coldfire_p(x) ((x) & mcfisa_a) #define arch_coldfire_fpu(x) ((x) & cfloat) /* Macros for determining if cpu supports a specific addressing mode. */ -#define HAVE_LONG_BRANCH(x) ((x) & (m68020|m68030|m68040|m68060|cpu32|mcfisa_b)) +#define HAVE_LONG_DISP(x) \ + ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c)) +#define HAVE_LONG_CALL(x) \ + ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c)) +#define HAVE_LONG_COND(x) \ + ((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. */ @@ -366,7 +511,7 @@ static void s_m68k_arch (int); struct m68k_cpu { unsigned long arch; /* Architecture features. */ - unsigned long chip; /* Specific chip */ + const enum m68k_register *control_regs; /* Control regs on chip */ const char *name; /* Name */ int alias; /* Alias for a cannonical name. If 1, then succeeds canonical name, if -1 then @@ -379,7 +524,6 @@ struct m68k_cpu disabled. */ static int current_architecture; static int not_current_architecture; -static int current_chip; static const struct m68k_cpu *selected_arch; static const struct m68k_cpu *selected_cpu; static int initialized; @@ -387,135 +531,216 @@ static int initialized; /* Architecture models. */ static const struct m68k_cpu m68k_archs[] = { - {m68000, cpu_m68000, "68000", 0}, - {m68010, cpu_m68010, "68010", 0}, - {m68020|m68881|m68851, cpu_m68020, "68020", 0}, - {m68030|m68881|m68851, cpu_m68030, "68030", 0}, - {m68040, cpu_m68040, "68040", 0}, - {m68060, cpu_m68060, "68060", 0}, - {cpu32|m68881, cpu_cpu32, "cpu32", 0}, - {mcfisa_a|mcfhwdiv, 0, "isaa", 0}, - {mcfisa_a|mcfhwdiv|mcfisa_aa|mcfusp, 0, "isaaplus", 0}, - {mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp, 0, "isab", 0}, - {mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "cfv4e", 0}, + {m68000, m68000_ctrl, "68000", 0}, + {m68010, m68010_ctrl, "68010", 0}, + {m68020|m68881|m68851, m68020_ctrl, "68020", 0}, + {m68030|m68881|m68851, m68020_ctrl, "68030", 0}, + {m68040, m68040_ctrl, "68040", 0}, + {m68060, m68060_ctrl, "68060", 0}, + {cpu32|m68881, cpu32_ctrl, "cpu32", 0}, + {fido_a, fido_ctrl, "fidoa", 0}, + {mcfisa_a|mcfhwdiv, NULL, "isaa", 0}, + {mcfisa_a|mcfhwdiv|mcfisa_aa|mcfusp, NULL, "isaaplus", 0}, + {mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp, NULL, "isab", 0}, + {mcfisa_a|mcfhwdiv|mcfisa_c|mcfusp, NULL, "isac", 0}, + {mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac|mcfusp, mcf_ctrl, "cfv4", 0}, + {mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcfv4e_ctrl, "cfv4e", 0}, {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, 0, "68851", -1}, - {m68881, 0, "68881", -1}, - {m68881, 0, "68882", -1}, - - {cfloat|m68881, 0, "float", 0}, - - {mcfhwdiv, 0, "div", 1}, - {mcfusp, 0, "usp", 1}, - {mcfmac, 0, "mac", 1}, - {mcfemac, 0, "emac", 1}, - - {0,0,NULL, 0} + {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, (void *)&no_mac, "mac", 1}, + {mcfemac, NULL, "emac", 1}, + + {0,NULL,NULL, 0} }; /* Processor list */ static const struct m68k_cpu m68k_cpus[] = { - { m68000, cpu_m68000, "68000", 0}, - { m68010, cpu_m68010, "68010", 0}, - { m68020|m68881|m68851, cpu_m68020, "68020", 0}, - { m68030|m68881|m68851, cpu_m68030, "68030", 0}, - { m68040, cpu_m68040, "68040", 0}, - { m68060, cpu_m68060, "68060", 0}, - { cpu32|m68881, cpu_cpu32, "cpu32", 0}, - { mcfisa_a, cpu_cf5200, "5200", 0}, - { mcfisa_a|mcfhwdiv|mcfmac, cpu_cf5206e, "5206e", 0}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf5208, "5208", 0}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, cpu_cf5213, "5213", 0}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,cpu_cf521x, "521x", 0}, - { mcfisa_a|mcfhwdiv|mcfemac, cpu_cf5249, "5249", 0}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,cpu_cf528x, "528x", 0}, - { mcfisa_a|mcfhwdiv|mcfmac, cpu_cf5307, "5307", 0}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf5329, "5329", 0}, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac, cpu_cf5407, "5407",0}, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "547x", 0}, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "548x", 0}, - /* Aliases (effectively, so far as gas is concerned) for the above - cpus. */ - { m68020|m68881|m68851, cpu_m68020, "68k", 1}, - { m68000, cpu_m68000, "68008", 1}, - { m68000, cpu_m68000, "68302", 1}, - { m68000, cpu_m68000, "68306", 1}, - { m68000, cpu_m68000, "68307", 1}, - { m68000, cpu_m68000, "68322", 1}, - { m68000, cpu_m68000, "68356", 1}, - { m68000, cpu_m68000, "68ec000", 1}, - { m68000, cpu_m68000, "68hc000", 1}, - { m68000, cpu_m68000, "68hc001", 1}, - { m68020|m68881|m68851, cpu_m68020, "68ec020", 1}, - { m68030|m68881|m68851, cpu_m68030, "68ec030", 1}, - { m68040, cpu_m68040, "68ec040", 1}, - { m68060, cpu_m68060, "68ec060", 1}, - { cpu32|m68881, cpu_cpu32, "68330", 1}, - { cpu32|m68881, cpu_cpu32, "68331", 1}, - { cpu32|m68881, cpu_cpu32, "68332", 1}, - { cpu32|m68881, cpu_cpu32, "68333", 1}, - { cpu32|m68881, cpu_cpu32, "68334", 1}, - { cpu32|m68881, cpu_cpu32, "68336", 1}, - { cpu32|m68881, cpu_cpu32, "68340", 1}, - { cpu32|m68881, cpu_cpu32, "68341", 1}, - { cpu32|m68881, cpu_cpu32, "68349", 1}, - { cpu32|m68881, cpu_cpu32, "68360", 1}, - { mcfisa_a, cpu_cf5200, "5202", 1}, - { mcfisa_a, cpu_cf5200, "5204", 1}, - { mcfisa_a, cpu_cf5200, "5206", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf5208, "5207", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, cpu_cf5213, "5211", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, cpu_cf5213, "5212", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf521x, "5214", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf521x, "5216", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf5329, "5327", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf5329, "5328", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf528x, "5280", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf528x, "5281", 1}, - { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, cpu_cf528x, "5282", 1}, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac, cpu_cf5407, "cfv4", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "cfv4e", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "5470", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "5471", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "5472", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "5473", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "5474", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf547x, "5475", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "5480", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "5481", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "5482", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "5483", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "5484", 1 }, - { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, - cpu_cf548x, "5485", 1 }, - {0,0,NULL, 0} + {m68000, m68000_ctrl, "68000", 0}, + {m68000, m68000_ctrl, "68ec000", 1}, + {m68000, m68000_ctrl, "68hc000", 1}, + {m68000, m68000_ctrl, "68hc001", 1}, + {m68000, m68000_ctrl, "68008", 1}, + {m68000, m68000_ctrl, "68302", 1}, + {m68000, m68000_ctrl, "68306", 1}, + {m68000, m68000_ctrl, "68307", 1}, + {m68000, m68000_ctrl, "68322", 1}, + {m68000, m68000_ctrl, "68356", 1}, + {m68010, m68010_ctrl, "68010", 0}, + {m68020|m68881|m68851, m68020_ctrl, "68020", 0}, + {m68020|m68881|m68851, m68020_ctrl, "68k", 1}, + {m68020|m68881|m68851, m68020_ctrl, "68ec020", 1}, + {m68030|m68881|m68851, m68020_ctrl, "68030", 0}, + {m68030|m68881|m68851, m68020_ctrl, "68ec030", 1}, + {m68040, m68040_ctrl, "68040", 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, "68332", 1}, + {cpu32|m68881, cpu32_ctrl, "68333", 1}, + {cpu32|m68881, cpu32_ctrl, "68334", 1}, + {cpu32|m68881, cpu32_ctrl, "68336", 1}, + {cpu32|m68881, cpu32_ctrl, "68340", 1}, + {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, "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, "52230", -1}, + {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, "5473", -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, "5483", -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}, + + {0,NULL,NULL, 0} }; -#define CPU_ALLOW_MC 1 -#define CPU_ALLOW_NEGATION 4 - static const struct m68k_cpu *m68k_lookup_cpu (const char *, const struct m68k_cpu *, int, int *); static int m68k_set_arch (const char *, int, int); @@ -578,8 +803,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: @@ -639,6 +870,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 @@ -663,6 +899,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'}, @@ -763,74 +1000,6 @@ static char alt_notend_table[256]; || (*s == ':' \ && alt_notend_table[(unsigned char) s[1]]))) -/* Return a human readable string holding the list of chips that are - valid for a particular architecture, suppressing aliases (unless - there is only one of them). */ - -static char * -find_cf_chip (int architecture) -{ - static char buf[1024]; - int i, j, n_chips, n_alias; - char *cp; - - strcpy (buf, " ("); - cp = buf + strlen (buf); - - for (i = 0, n_chips = 0, n_alias = 0; m68k_cpus[i].name; ++i) - if (m68k_cpus[i].arch & architecture) - { - n_chips++; - if (m68k_cpus[i].alias) - n_alias++; - } - - if (n_chips == 0) - as_fatal (_("no matching ColdFire architectures found")); - - if (n_alias > 1) - n_chips -= n_alias; - - for (i = 0, j = 0; m68k_cpus[i].name && j < n_chips; ++i) - if (m68k_cpus[i].arch & architecture) - { - if (j) - { - if ((j == n_chips - 1 && !(n_alias > 1)) || ! n_alias) - { - if (n_chips == 2) - { - strncpy (cp, _(" or "), (sizeof (buf) - (cp - buf))); - cp += strlen (cp); - } - else - { - strncpy (cp, _(", or "), (sizeof (buf) - (cp - buf))); - cp += strlen (cp); - } - } - else - { - strncpy (cp, ", ", (sizeof (buf) - (cp - buf))); - cp += strlen (cp); - } - } - strncpy (cp, m68k_cpus[i].name, (sizeof (buf) - (cp - buf))); - cp += strlen (cp); - j++; - } - - if (n_alias > 1) - { - strncpy (cp, _(", or aliases"), (sizeof (buf) - (cp - buf))); - cp += strlen (cp); - } - - strncpy (cp, ")", (sizeof (buf) - (cp - buf))); - - return buf; -} - #ifdef OBJ_ELF /* Return zero if the reference to SYMBOL from within the same segment may @@ -903,6 +1072,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) { @@ -971,6 +1200,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: @@ -986,7 +1230,9 @@ tc_m68k_fix_adjustable (fixS *fixP) #define get_reloc_code(SIZE,PCREL,OTHER) NO_RELOC -#define relaxable_symbol(symbol) 1 +/* PR gas/3041 Weak symbols are not relaxable + because they must be treated as extern. */ +#define relaxable_symbol(symbol) (!(S_IS_WEAK (symbol))) #endif /* OBJ_ELF */ @@ -1046,6 +1292,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, @@ -1073,12 +1334,39 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) #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 reloc->addend = 0; @@ -1087,15 +1375,13 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) 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; } @@ -1109,11 +1395,11 @@ static struct hash_control *op_hash; 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; @@ -1248,7 +1534,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]; @@ -1712,10 +1998,20 @@ m68k_ip (char *instring) else { const enum m68k_register *rp; - + for (rp = control_regs; *rp; rp++) - if (*rp == opP->reg) - break; + { + if (*rp == opP->reg) + break; + /* In most CPUs RAMBAR refers to control reg + c05 (RAMBAR1), but a few CPUs have it + refer to c04 (RAMBAR0). */ + else if (*rp == RAMBAR_ALT && opP->reg == RAMBAR) + { + opP->reg = RAMBAR_ALT; + break; + } + } if (*rp == 0) losing++; } @@ -1872,6 +2168,22 @@ m68k_ip (char *instring) losing++; break; + case 'j': + if (opP->mode != IMMED) + losing++; + else if (opP->disp.exp.X_op != O_constant + || TRUNC (opP->disp.exp.X_add_number) - 1 > 7) + losing++; + break; + + case 'K': + if (opP->mode != IMMED) + losing++; + else if (opP->disp.exp.X_op != O_constant + || TRUNC (opP->disp.exp.X_add_number) > 511) + losing++; + break; + /* JF these are out of order. We could put them in order if we were willing to put up with bunches of #ifdef m68851s in the code. @@ -2033,92 +2345,109 @@ m68k_ip (char *instring) if (ok_arch && !(ok_arch & current_architecture)) { - char buf[200], *cp; - - strncpy (buf, - _("invalid instruction for this architecture; needs "), - sizeof (buf)); - cp = buf + strlen (buf); + const struct m68k_cpu *cpu; + int any = 0; + size_t space = 400; + char *buf = XNEWVEC (char, space + 1); + size_t len; + int paren = 1; + + 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. */ + buf[space] = 0; +#define APPEND(STRING) \ + (strncpy (buf, STRING, space), len = strlen (buf), buf += len, space -= len) + + APPEND (_("invalid instruction for this architecture; needs ")); switch (ok_arch) { case mcfisa_a: - strncpy (cp, _("ColdFire ISA_A"), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); - strncpy (cp, find_cf_chip (ok_arch), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); + APPEND ("ColdFire ISA_A"); break; case mcfhwdiv: - strncpy (cp, _("ColdFire hardware divide"), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); - strncpy (cp, find_cf_chip (ok_arch), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); + APPEND ("ColdFire "); + APPEND (_("hardware divide")); break; case mcfisa_aa: - strncpy (cp, _("ColdFire ISA_A+"), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); - strncpy (cp, find_cf_chip (ok_arch), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); + APPEND ("ColdFire ISA_A+"); break; case mcfisa_b: - strncpy (cp, _("ColdFire ISA_B"), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); - strncpy (cp, find_cf_chip (ok_arch), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); + APPEND ("ColdFire ISA_B"); + break; + case mcfisa_c: + APPEND ("ColdFire ISA_C"); break; case cfloat: - strncpy (cp, _("ColdFire fpu"), sizeof (buf) - (cp - buf)); - cp += strlen (cp); - strncpy (cp, find_cf_chip (ok_arch), - sizeof (buf) - (cp - buf)); - cp += strlen (cp); + APPEND ("ColdFire fpu"); break; case mfloat: - strcpy (cp, _("fpu (68040, 68060 or 68881/68882)")); + APPEND ("M68K fpu"); break; case mmmu: - strcpy (cp, _("mmu (68030 or 68851)")); + APPEND ("M68K mmu"); break; case m68020up: - strcpy (cp, _("68020 or higher")); + APPEND ("68020 "); + APPEND (_("or higher")); break; case m68000up: - strcpy (cp, _("68000 or higher")); + APPEND ("68000 "); + APPEND (_("or higher")); break; case m68010up: - strcpy (cp, _("68010 or higher")); + APPEND ("68010 "); + APPEND (_("or higher")); break; default: + paren = 0; + } + if (paren) + APPEND (" ("); + + for (cpu = m68k_cpus; cpu->name; cpu++) + if (!cpu->alias && (cpu->arch & ok_arch)) { - int got_one = 0, idx; - - for (idx = 0; m68k_cpus[idx].name; idx++) - { - if ((m68k_cpus[idx].arch & ok_arch) - && ! m68k_cpus[idx].alias) - { - if (got_one) - { - strcpy (cp, " or "); - cp += strlen (cp); - } - got_one = 1; - strcpy (cp, m68k_cpus[idx].name); - cp += strlen (cp); - } - } + const struct m68k_cpu *alias; + int seen_master = 0; + + if (any) + APPEND (", "); + any = 0; + APPEND (cpu->name); + for (alias = cpu; alias != m68k_cpus; alias--) + if (alias[-1].alias >= 0) + break; + for (; !seen_master || alias->alias > 0; alias++) + { + if (!alias->alias) + seen_master = 1; + else + { + if (any) + APPEND (", "); + else + APPEND (" ["); + APPEND (alias->name); + any = 1; + } + } + if (any) + APPEND ("]"); + any = 1; } + if (paren) + APPEND (")"); +#undef APPEND + if (!space) + { + /* We ran out of space, so replace the end of the list + with ellipsis. */ + buf -= 4; + while (*buf != ' ') + buf--; + strcpy (buf, " ..."); } - cp = xmalloc (strlen (buf) + 1); - strcpy (cp, buf); - the_ins.error = cp; } else the_ins.error = _("operands mismatch"); @@ -2137,6 +2466,9 @@ 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! */ switch (s[0]) @@ -2796,6 +3128,7 @@ m68k_ip (char *instring) case 'B': tmpreg = get_num (&opP->disp, 90); + switch (s[1]) { case 'B': @@ -2807,23 +3140,37 @@ m68k_ip (char *instring) break; case 'L': long_branch: - if (! HAVE_LONG_BRANCH (current_architecture)) - as_warn (_("Can't use long branches on 68000/68010/5200")); the_ins.opcode[0] |= 0xff; add_fix ('l', &opP->disp, 1, 0); addword (0); addword (0); break; - case 'g': - if (subs (&opP->disp)) /* We can't relax it. */ - goto long_branch; + 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 - /* If the displacement needs pic relocation it cannot be - relaxed. */ - if (opP->disp.pic_reloc != pic_none) - goto long_branch; + /* If the displacement needs pic relocation it cannot be + relaxed. */ + || opP->disp.pic_reloc != pic_none #endif + || 0) + { + if (!have_disp) + 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 @@ -2849,7 +3196,7 @@ m68k_ip (char *instring) /* Now we know it's going into the relaxer. Now figure out which mode. We try in this order of preference: long branch, absolute jump, byte/word branches only. */ - if (HAVE_LONG_BRANCH (current_architecture)) + if (have_disp) add_frag (adds (&opP->disp), SEXT (offs (&opP->disp)), TAB (BRANCHBWL, SZ_UNDEF)); @@ -2868,7 +3215,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)) @@ -2878,7 +3226,7 @@ m68k_ip (char *instring) jumps. */ if (((the_ins.opcode[0] & 0xf0f8) == 0x50c8) && (HAVE_LONG_BRANCH (current_architecture) - || (! flag_keep_pcrel))) + || ! flag_keep_pcrel)) { if (HAVE_LONG_BRANCH (current_architecture)) add_frag (adds (&opP->disp), @@ -2938,7 +3286,7 @@ m68k_ip (char *instring) case 'e': /* EMAC ACCx, reg/reg. */ install_operand (s[1], opP->reg - ACC); break; - + case 'E': /* Ignore it. */ break; @@ -2976,6 +3324,7 @@ m68k_ip (char *instring) tmpreg = 0x002; break; case TC: + case ASID: tmpreg = 0x003; break; case ACR0: @@ -2995,8 +3344,18 @@ m68k_ip (char *instring) tmpreg = 0x007; break; case BUSCR: + 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; @@ -3005,6 +3364,7 @@ m68k_ip (char *instring) tmpreg = 0x801; break; case CAAR: + case CPUCR: tmpreg = 0x802; break; case MSP: @@ -3026,6 +3386,7 @@ m68k_ip (char *instring) tmpreg = 0x808; break; case ROMBAR: + case ROMBAR0: tmpreg = 0xC00; break; case ROMBAR1: @@ -3033,6 +3394,7 @@ m68k_ip (char *instring) break; case FLASHBAR: case RAMBAR0: + case RAMBAR_ALT: tmpreg = 0xC04; break; case RAMBAR: @@ -3090,6 +3452,12 @@ m68k_ip (char *instring) case PCR3U1: tmpreg = 0xD0F; break; + case CAC: + tmpreg = 0xFFE; + break; + case MBO: + tmpreg = 0xFFF; + break; default: abort (); } @@ -3353,6 +3721,14 @@ m68k_ip (char *instring) tmpreg = 0; install_operand (s[1], tmpreg); break; + case 'j': + tmpreg = get_num (&opP->disp, 10); + install_operand (s[1], tmpreg - 1); + break; + case 'K': + tmpreg = get_num (&opP->disp, 65); + install_operand (s[1], tmpreg); + break; default: abort (); } @@ -3400,10 +3776,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 @@ -3421,6 +3796,9 @@ install_operand (int mode, int val) case 'd': the_ins.opcode[0] |= val << 9; break; + case 'E': + the_ins.opcode[1] |= val << 9; + break; case '1': the_ins.opcode[1] |= val << 12; break; @@ -3577,9 +3955,9 @@ install_gen_operand (int mode, int val) 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) @@ -3748,6 +4126,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. */ @@ -3765,22 +4144,28 @@ static const struct init_entry init_table[] = { "dacr0", DTT0 }, /* Data Access Control Register 0. */ { "dacr1", DTT1 }, /* Data Access Control Register 0. */ - /* mcf5200 versions of same. The ColdFire programmer's reference + /* Coldfire versions of same. The ColdFire programmer's reference manual indicated that the order is 2,3,0,1, but Ken Rose says that 0,1,2,3 is the correct order. */ { "acr0", ACR0 }, /* Access Control Unit 0. */ { "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 }, + { "asid", ASID }, { "mmusr", MMUSR }, /* MMU Status Register. */ { "srp", SRP }, /* User Root Pointer. */ { "urp", URP }, /* Supervisor Root Pointer. */ { "buscr", BUSCR }, + { "mmubar", MMUBAR }, { "pcr", PCR }, { "rombar", ROMBAR }, /* ROM Base Address Register. */ @@ -3790,7 +4175,7 @@ static const struct init_entry init_table[] = { "mbar0", MBAR0 }, /* mcfv4e registers. */ { "mbar1", MBAR1 }, /* mcfv4e registers. */ - { "rombar0", ROMBAR }, /* mcfv4e registers. */ + { "rombar0", ROMBAR0 }, /* mcfv4e registers. */ { "rombar1", ROMBAR1 }, /* mcfv4e registers. */ { "mpcr", MPCR }, /* mcfv4e registers. */ { "edrambar", EDRAMBAR }, /* mcfv4e registers. */ @@ -3814,6 +4199,12 @@ static const struct init_entry init_table[] = { "rambar", RAMBAR }, /* mcf528x registers. */ { "mbar2", MBAR2 }, /* mcf5249 registers. */ + + { "rgpiobar", RGPIOBAR }, /* mcf54418 registers. */ + + { "cac", CAC }, /* fido registers. */ + { "mbb", MBO }, /* fido registers (obsolete). */ + { "mbo", MBO }, /* fido registers. */ /* End of control registers. */ { "ac", AC }, @@ -3941,7 +4332,7 @@ md_assemble (char *str) } 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. */ @@ -4068,7 +4459,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. */ @@ -4116,11 +4507,12 @@ 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); } - 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) { @@ -4207,10 +4599,7 @@ md_begin (void) /* First sort the opcode table into alphabetical order to seperate 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; @@ -4223,23 +4612,37 @@ 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 = XOBNEW (&robyn, struct m68k_incant); do { ins = m68k_sorted_opcodes[i]; - /* We *could* ignore insns that don't match our - arch here by just leaving them out of the hash. */ + /* We must enter all insns into the table, because .arch and + .cpu directives can change things. */ slak->m_operands = ins->args; - slak->m_opnum = strlen (slak->m_operands) / 2; slak->m_arch = ins->arch; slak->m_opcode = ins->opcode; - /* This is kludgey. */ - slak->m_codenum = ((ins->match) & 0xffffL) ? 2 : 1; + + /* 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 + in the second word. A leading dot in the operands + string also indicates 2 opcodes. */ + if (*slak->m_operands == '.') + { + slak->m_operands++; + slak->m_codenum = 2; + } + else if (ins->match & 0xffffL) + slak->m_codenum = 2; + 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 @@ -4257,7 +4660,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); @@ -4296,7 +4699,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); @@ -4356,7 +4759,7 @@ md_begin (void) 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; @@ -4375,68 +4778,6 @@ md_begin (void) #endif } -static void -select_control_regs (void) -{ - /* Note which set of "movec" control registers is available. */ - switch (current_chip) - { - case 0: - if (verbose) - as_warn (_("architecture not yet selected: defaulting to 68020")); - control_regs = m68020_control_regs; - break; - - case cpu_m68000: - control_regs = m68000_control_regs; - break; - case cpu_m68010: - control_regs = m68010_control_regs; - break; - case cpu_m68020: - case cpu_m68030: - control_regs = m68020_control_regs; - break; - case cpu_m68040: - control_regs = m68040_control_regs; - break; - case cpu_m68060: - control_regs = m68060_control_regs; - break; - case cpu_cpu32: - control_regs = cpu32_control_regs; - break; - case cpu_cf5200: - case cpu_cf5206e: - case cpu_cf5307: - case cpu_cf5407: - control_regs = mcf_control_regs; - break; - case cpu_cf5249: - control_regs = mcf5249_control_regs; - break; - case cpu_cf528x: - case cpu_cf521x: - control_regs = mcf528x_control_regs; - break; - case cpu_cf547x: - case cpu_cf548x: - control_regs = mcfv4e_control_regs; - break; - case cpu_cf5208: - control_regs = mcf5208_control_regs; - break; - case cpu_cf5213: - control_regs = mcf5213_control_regs; - break; - case cpu_cf5329: - control_regs = mcf5329_control_regs; - break; - default: - abort (); - } -} - /* This is called when a label is defined. */ @@ -4445,10 +4786,10 @@ m68k_frob_label (symbolS *sym) { 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; @@ -4535,63 +4876,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 * +const 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 @@ -4628,6 +4916,39 @@ 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) + /* PR gas/3041 Do not fix frags referencing a weak symbol. */ + if (fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)) + { + memset (buf, 0, fixP->fx_size); + fixP->fx_addnumber = val; /* Remember value for emit_reloc. */ return; } #endif @@ -4680,7 +5001,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) if ((addressT) val > upper_limit && (val > 0 || val < lower_limit)) - as_bad_where (fixP->fx_file, fixP->fx_line, _("value out of range")); + as_bad_where (fixP->fx_file, fixP->fx_line, + _("value %ld out of range"), (long)val); /* A one byte PC-relative reloc means a short branch. We can't use a short branch with a value of 0 or -1, because those indicate @@ -4693,7 +5015,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) && (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) && (val == 0 || val == -1)) - as_bad_where (fixP->fx_file, fixP->fx_line, _("invalid byte branch offset")); + as_bad_where (fixP->fx_file, fixP->fx_line, + _("invalid byte branch offset")); } /* *fragP has been relaxed to its final size, and now needs to have @@ -4704,15 +5027,15 @@ static void md_convert_frag_1 (fragS *fragP) { long disp; - fixS *fixP; + 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. */ @@ -4726,6 +5049,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, @@ -4738,36 +5062,57 @@ 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; - fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, - 1, RELAX_RELOC_PC16); + fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC16); fragP->fr_fix += 2; break; case TAB (BRANCHBWL, LONG): fragP->fr_opcode[1] = (char) 0xFF; - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, - 1, RELAX_RELOC_PC32); + 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 (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 */ { if (flag_keep_pcrel) - as_fatal (_("Tried to convert PC relative BSR to absolute JSR")); + as_bad_where (fragP->fr_file, fragP->fr_line, + _("Conversion of PC relative BSR to absolute JSR")); fragP->fr_opcode[0] = 0x4E; fragP->fr_opcode[1] = (char) 0xB9; /* JSR with ABSL LONG operand. */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, - 0, RELAX_RELOC_ABS32); + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 0, RELAX_RELOC_ABS32); fragP->fr_fix += 4; } else if (fragP->fr_opcode[0] == 0x60) /* jbra */ { if (flag_keep_pcrel) - as_fatal (_("Tried to convert PC relative branch to absolute jump")); + as_bad_where (fragP->fr_file, fragP->fr_line, + _("Conversion of PC relative branch to absolute jump")); fragP->fr_opcode[0] = 0x4E; fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG operand. */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, - 0, RELAX_RELOC_ABS32); + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 0, RELAX_RELOC_ABS32); fragP->fr_fix += 4; } else @@ -4779,7 +5124,8 @@ md_convert_frag_1 (fragS *fragP) break; case TAB (BRABSJCOND, LONG): if (flag_keep_pcrel) - as_fatal (_("Tried to convert PC relative conditional branch to absolute jump")); + as_bad_where (fragP->fr_file, fragP->fr_line, + _("Conversion of PC relative conditional branch to absolute jump")); /* Only Bcc 68000 instructions can come here Change bcc into b!cc/jmp absl long. */ @@ -4792,35 +5138,32 @@ md_convert_frag_1 (fragS *fragP) *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */ *buffer_address++ = (char) 0xf9; fragP->fr_fix += 2; /* Account for jmp instruction. */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, - fragP->fr_offset, 0, RELAX_RELOC_ABS32); + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 0, RELAX_RELOC_ABS32); fragP->fr_fix += 4; break; case TAB (FBRANCH, SHORT): know ((fragP->fr_opcode[1] & 0x40) == 0); - fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, - 1, RELAX_RELOC_PC16); + fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC16); fragP->fr_fix += 2; break; case TAB (FBRANCH, LONG): fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit. */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, - 1, RELAX_RELOC_PC32); + 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 (DBCCLBR, SHORT): case TAB (DBCCABSJ, SHORT): - fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, - 1, RELAX_RELOC_PC16); + fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC16); fragP->fr_fix += 2; break; case TAB (DBCCLBR, LONG): /* 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_fatal (_("Tried to convert DBcc to absolute jump")); - *buffer_address++ = 0x00; /* Branch offset = 4. */ *buffer_address++ = 0x04; *buffer_address++ = 0x60; /* Put in bra pc+6. */ @@ -4829,8 +5172,8 @@ md_convert_frag_1 (fragS *fragP) *buffer_address++ = (char) 0xff; fragP->fr_fix += 6; /* Account for bra/jmp instructions. */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, 1, - RELAX_RELOC_PC32); + 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 (DBCCABSJ, LONG): @@ -4838,7 +5181,8 @@ md_convert_frag_1 (fragS *fragP) Change dbcc into dbcc/jmp. JF: these used to be fr_opcode[2-7], but that's wrong. */ if (flag_keep_pcrel) - as_fatal (_("Tried to convert PC relative conditional branch to absolute jump")); + as_bad_where (fragP->fr_file, fragP->fr_line, + _("Conversion of PC relative conditional branch to absolute jump")); *buffer_address++ = 0x00; /* Branch offset = 4. */ *buffer_address++ = 0x04; @@ -4848,15 +5192,15 @@ md_convert_frag_1 (fragS *fragP) *buffer_address++ = (char) 0xf9; fragP->fr_fix += 6; /* Account for bra/jmp instructions. */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, 0, - RELAX_RELOC_ABS32); + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 0, RELAX_RELOC_ABS32); fragP->fr_fix += 4; break; case TAB (PCREL1632, SHORT): fragP->fr_opcode[1] &= ~0x3F; fragP->fr_opcode[1] |= 0x3A; /* 072 - mode 7.2 */ - fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol, - fragP->fr_offset, 1, RELAX_RELOC_PC16); + fixP = fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC16); fragP->fr_fix += 2; break; case TAB (PCREL1632, LONG): @@ -4871,14 +5215,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, @@ -4887,7 +5231,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, @@ -4896,24 +5240,30 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_fix += 4; break; case TAB (ABSTOPCREL, SHORT): - fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, - 1, RELAX_RELOC_PC16); + fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC16); fragP->fr_fix += 2; break; case TAB (ABSTOPCREL, LONG): if (flag_keep_pcrel) - as_fatal (_("Tried to convert PC relative conditional branch to absolute jump")); + 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) abort (); fragP->fr_opcode[1] &= ~0x3F; fragP->fr_opcode[1] |= 0x39; /* Mode 7.1 */ - fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset, - 0, RELAX_RELOC_ABS32); + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 0, RELAX_RELOC_ABS32); fragP->fr_fix += 4; break; } + if (fixP) + { + fixP->fx_file = fragP->fr_file; + fixP->fx_line = fragP->fr_line; + } } void @@ -4934,6 +5284,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): { @@ -5137,6 +5488,7 @@ md_create_long_jump (char *ptr, addressT from_addr, addressT to_addr, 50: absolute 0:127 only 55: absolute -64:63 only 60: absolute -128:127 only + 65: absolute 0:511 only 70: absolute 0:4095 only 80: absolute -1, 1:7 only 90: No bignums. */ @@ -5192,6 +5544,10 @@ get_num (struct m68k_exp *exp, int ok) if ((valueT) SEXT (offs (exp)) + 128 > 255) goto outrange; break; + case 65: + if ((valueT) TRUNC (offs (exp)) > 511) + goto outrange; + break; case 70: if ((valueT) TRUNC (offs (exp)) > 4095) { @@ -5304,8 +5660,8 @@ s_bss (int ignore ATTRIBUTE_UNUSED) 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 (); @@ -5344,7 +5700,7 @@ mri_chip (void) 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++)) ; @@ -5366,13 +5722,13 @@ mri_chip (void) else current_architecture &= m68881 | m68851; current_architecture |= m68k_cpus[i].arch & ~(m68881 | m68851); - current_chip = m68k_cpus[i].chip; + control_regs = m68k_cpus[i].control_regs; while (*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++)) ; @@ -5383,9 +5739,6 @@ mri_chip (void) current_architecture |= m68851; *input_line_pointer = c; } - - /* Update info about available control registers. */ - select_control_regs (); } /* The MRI CHIP pseudo-op. */ @@ -5540,8 +5893,7 @@ s_opt (int ignore ATTRIBUTE_UNUSED) 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++) { @@ -5551,14 +5903,14 @@ s_opt (int ignore ATTRIBUTE_UNUSED) { /* 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 @@ -5569,7 +5921,7 @@ s_opt (int ignore ATTRIBUTE_UNUSED) if (i >= OPTCOUNT) { as_bad (_("option `%s' not recognized"), s); - *input_line_pointer = c; + restore_line_pointer (c); } } while (*input_line_pointer++ == ','); @@ -5731,7 +6083,7 @@ struct save_opts int keep_locals; int short_refs; int architecture; - int chip; + const enum m68k_register *control_regs; int quick; int rel32; int listing; @@ -5750,13 +6102,13 @@ s_save (int ignore ATTRIBUTE_UNUSED) { 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; s->short_refs = flag_short_refs; s->architecture = current_architecture; - s->chip = current_chip; + s->control_regs = control_regs; s->quick = m68k_quick; s->rel32 = m68k_rel32; s->listing = listing; @@ -5790,7 +6142,7 @@ s_restore (int ignore ATTRIBUTE_UNUSED) flag_keep_locals = s->keep_locals; flag_short_refs = s->short_refs; current_architecture = s->architecture; - current_chip = s->chip; + control_regs = s->control_regs; m68k_quick = s->quick; m68k_rel32 = s->rel32; listing = s->listing; @@ -5870,7 +6222,7 @@ mri_control_label (void) { 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; @@ -5883,7 +6235,7 @@ push_mri_control (enum mri_control_type type) { 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; @@ -6042,8 +6394,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 : @@ -6162,9 +6514,9 @@ build_mri_control_operand (int qual, int cc, char *leftstart, char *leftstop, 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'; @@ -6182,7 +6534,7 @@ build_mri_control_operand (int qual, int cc, char *leftstart, char *leftstop, free (buf); } - buf = (char *) xmalloc (20 + strlen (truelab)); + buf = XNEWVEC (char, 20 + strlen (truelab)); s = buf; *s++ = 'b'; *s++ = cc >> 8; @@ -6431,7 +6783,7 @@ s_mri_else (int qual) 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); @@ -6502,7 +6854,7 @@ s_mri_break (int extent) 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); @@ -6540,7 +6892,7 @@ s_mri_next (int extent) 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); @@ -6714,7 +7066,7 @@ s_mri_for (int qual) /* 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; @@ -6948,7 +7300,7 @@ s_mri_endw (int ignore ATTRIBUTE_UNUSED) 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); @@ -6980,7 +7332,7 @@ s_m68k_cpu (int ignored ATTRIBUTE_UNUSED) ignore_rest_of_line (); return; } - + name = input_line_pointer; while (*input_line_pointer && !ISSPACE(*input_line_pointer)) input_line_pointer++; @@ -6988,7 +7340,7 @@ s_m68k_cpu (int ignored ATTRIBUTE_UNUSED) *input_line_pointer = 0; m68k_set_cpu (name, 1, 0); - + *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -7008,7 +7360,7 @@ s_m68k_arch (int ignored ATTRIBUTE_UNUSED) ignore_rest_of_line (); return; } - + name = input_line_pointer; while (*input_line_pointer && *input_line_pointer != ',' && !ISSPACE (*input_line_pointer)) @@ -7033,7 +7385,7 @@ s_m68k_arch (int ignored ATTRIBUTE_UNUSED) } while (m68k_set_extension (name, 1, 0)); } - + *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -7062,7 +7414,7 @@ m68k_lookup_cpu (const char *arg, const struct m68k_cpu *table, *negated = 1; } } - + /* Remove 'm' or 'mc' prefix from 68k variants. */ if (allow_m) { @@ -7079,11 +7431,16 @@ m68k_lookup_cpu (const char *arg, const struct m68k_cpu *table, for (; table->name; table++) if (!strcmp (arg, table->name)) - return table; + { + if (table->alias < -1 || table->alias > 1) + as_bad (_("`%s' is deprecated, use `%s'"), + table->name, table[table->alias < 0 ? 1 : -1].name); + return 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) @@ -7098,18 +7455,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) @@ -7124,14 +7474,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; } @@ -7155,7 +7497,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; @@ -7194,7 +7537,7 @@ struct option md_longopts[] = { 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) { @@ -7238,7 +7581,7 @@ md_parse_option (int c, char *arg) 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 != '|') @@ -7305,21 +7648,14 @@ m68k_init_arch (void) not_current_architecture &= ~current_architecture; } if (selected_arch) - current_architecture |= selected_arch->arch; + { + current_architecture |= selected_arch->arch; + control_regs = selected_arch->control_regs; + } else current_architecture |= selected_cpu->arch; current_architecture &= ~not_current_architecture; - - if (selected_cpu) - { - if (current_architecture & ~selected_cpu->arch) - { - as_bad (_("selected processor does not have all features of selected architecture")); - current_architecture - = selected_cpu->arch & ~not_current_architecture; - } - } if ((current_architecture & (cfloat | m68881)) == (cfloat | m68881)) { @@ -7330,6 +7666,17 @@ m68k_init_arch (void) current_architecture ^= m68881; } + if (selected_cpu) + { + control_regs = selected_cpu->control_regs; + if (current_architecture & ~selected_cpu->arch) + { + as_bad (_("selected processor does not have all features of selected architecture")); + current_architecture + = selected_cpu->arch & ~not_current_architecture; + } + } + if ((current_architecture & m68k_mask) && (current_architecture & ~m68k_mask)) { @@ -7339,7 +7686,7 @@ m68k_init_arch (void) 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) @@ -7349,13 +7696,10 @@ m68k_init_arch (void) } /* What other incompatibilities could we check for? */ - /* Note which set of "movec" control registers is available. */ - select_control_regs (); - if (cpu_of_arch (current_architecture) < m68020 || arch_coldfire_p (current_architecture)) md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0; - + initialized = 1; } @@ -7364,7 +7708,6 @@ md_show_usage (FILE *stream) { 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') @@ -7373,16 +7716,11 @@ md_show_usage (FILE *stream) { if (strcasecmp (default_cpu, m68k_cpus[i].name) == 0) { - default_arch = m68k_cpus[i].arch; - for (i = 0; m68k_cpus[i].name; i++) - { - if (m68k_cpus[i].arch == default_arch - && !m68k_cpus[i].alias) - { - default_cpu = m68k_cpus[i].name; - break; - } - } + while (m68k_cpus[i].alias > 0) + i--; + while (m68k_cpus[i].alias < 0) + i++; + default_cpu = m68k_cpus[i].name; } } @@ -7396,7 +7734,7 @@ md_show_usage (FILE *stream) "), 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\ @@ -7410,13 +7748,13 @@ md_show_usage (FILE *stream) --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"); @@ -7425,7 +7763,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")); } @@ -7547,7 +7885,7 @@ md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) 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; @@ -7562,9 +7900,7 @@ md_pcrel_from (fixS *fixP) { 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; @@ -7575,38 +7911,42 @@ void 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. */ if (cpu_of_arch (current_architecture) & cpu32) flags |= EF_M68K_CPU32; + else if (cpu_of_arch (current_architecture) & fido_a) + flags |= EF_M68K_FIDO; 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] = { - {EF_M68K_ISA_A_NODIV, mcfisa_a}, - {EF_M68K_ISA_A, mcfisa_a|mcfhwdiv}, - {EF_M68K_ISA_A_PLUS,mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp}, - {EF_M68K_ISA_B_NOUSP,mcfisa_a|mcfisa_b|mcfhwdiv}, - {EF_M68K_ISA_B, mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp}, + {EF_M68K_CF_ISA_A_NODIV,mcfisa_a}, + {EF_M68K_CF_ISA_A, mcfisa_a|mcfhwdiv}, + {EF_M68K_CF_ISA_A_PLUS, mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp}, + {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] = { - {EF_M68K_MAC, mcfmac}, - {EF_M68K_EMAC, mcfemac}, + {EF_M68K_CF_MAC, mcfmac}, + {EF_M68K_CF_EMAC, mcfemac}, {0,0}, }; unsigned ix; unsigned pattern; - + pattern = (current_architecture - & (mcfisa_a|mcfisa_aa|mcfisa_b|mcfhwdiv|mcfusp)); + & (mcfisa_a|mcfisa_aa|mcfisa_b|mcfisa_c|mcfhwdiv|mcfusp)); for (ix = 0; isa_features[ix][1]; ix++) { if (pattern == isa_features[ix][1]) @@ -7623,7 +7963,7 @@ m68k_elf_final_processing (void) else { if (current_architecture & cfloat) - flags |= EF_M68K_FLOAT | EF_M68K_CFV4E; + flags |= EF_M68K_CF_FLOAT | EF_M68K_CFV4E; pattern = current_architecture & (mcfmac|mcfemac); if (pattern) @@ -7643,6 +7983,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 @@ -7675,3 +8124,17 @@ tc_m68k_frame_initial_instructions (void) 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); +} +