X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68k.c;h=5483f8e017af0b0c1b144ea77cdb270383818e2d;hb=b8ba13856360d1cae00269a0ffe291cf573bb575;hp=65c166d24f8110796652d3d46db0073f7306b06a;hpb=ec2655a6a75bc61d21e6f8ddc1e9f9027a8914dd;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 65c166d24f..5483f8e017 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1,6 +1,5 @@ /* 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-2020 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -28,14 +27,9 @@ #include "opcode/m68k.h" #include "m68k-parse.h" - -#if defined (OBJ_ELF) #include "elf/m68k.h" -#endif -#ifdef M68KCOFF -#include "obj-coff.h" -#endif +static void m68k_elf_cons (int); /* This string holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful. The macro @@ -119,7 +113,7 @@ struct label_line { struct label_line *next; symbolS *label; - char *file; + const char *file; unsigned int line; int text; }; @@ -135,7 +129,7 @@ static struct label_line *current_label; /* Pointer to list holding the opcodes sorted by name. */ static struct m68k_opcode const ** m68k_sorted_opcodes; -/* Its an arbitrary name: This means I don't approve of it. +/* It's an arbitrary name: This means I don't approve of it. See flames below. */ static struct obstack robyn; @@ -176,8 +170,12 @@ static const enum m68k_register mcf_ctrl[] = { RAMBAR0, RAMBAR1, RAMBAR, MBAR, 0 }; +static const enum m68k_register mcf51_ctrl[] = { + VBR, CPUCR, + 0 +}; static const enum m68k_register mcf5206_ctrl[] = { - CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR, + CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR, 0 }; static const enum m68k_register mcf5208_ctrl[] = { @@ -196,8 +194,12 @@ static const enum m68k_register mcf5216_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1, 0 }; +static const enum m68k_register mcf5221x_ctrl[] = { + VBR, FLASHBAR, RAMBAR, RAMBAR1, + 0 +}; static const enum m68k_register mcf52223_ctrl[] = { - VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1, + VBR, FLASHBAR, RAMBAR, RAMBAR1, 0 }; static const enum m68k_register mcf52235_ctrl[] = { @@ -208,6 +210,14 @@ static const enum m68k_register mcf5225_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, MBAR, RAMBAR1, 0 }; +static const enum m68k_register mcf52259_ctrl[] = { + VBR, FLASHBAR, RAMBAR, RAMBAR1, + 0 +}; +static const enum m68k_register mcf52277_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; static const enum m68k_register mcf5235_ctrl[] = { VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, 0 @@ -221,7 +231,7 @@ static const enum m68k_register mcf5250_ctrl[] = { 0 }; static const enum m68k_register mcf5253_ctrl[] = { - VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, MBAR, + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, RAMBAR, MBAR, MBAR2, 0 }; static const enum m68k_register mcf5271_ctrl[] = { @@ -240,8 +250,12 @@ static const enum m68k_register mcf5282_ctrl[] = { VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1, 0 }; +static const enum m68k_register mcf53017_ctrl[] = { + VBR, CACR, ACR0, ACR1, RAMBAR, RAMBAR1, + 0 +}; static const enum m68k_register mcf5307_ctrl[] = { - CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR, + VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR_ALT, MBAR, 0 }; static const enum m68k_register mcf5329_ctrl[] = { @@ -268,13 +282,31 @@ static const enum m68k_register mcfv4e_ctrl[] = { ROMBAR /* ROMBAR0 */, RAMBAR /* RAMBAR1 */, 0 }; +static const enum m68k_register mcf5407_ctrl[] = { + CACR, ASID, ACR0, ACR1, ACR2, ACR3, + VBR, PC, RAMBAR0, RAMBAR1, MBAR, + /* Legacy names */ + TC /* ASID */, + ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */, + MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */, + 0 +}; +static const enum m68k_register 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[] = { @@ -296,7 +328,7 @@ static const enum m68k_register mcf5485_ctrl[] = { 0 }; static const enum m68k_register fido_ctrl[] = { - SFC, DFC, USP, VBR, CAC, MBB, + SFC, DFC, USP, VBR, CAC, MBO, 0 }; #define cpu32_ctrl m68010_ctrl @@ -328,7 +360,7 @@ struct m68k_it } fragb[4]; - int nrel; /* Num of reloc strucs in use. */ + int nrel; /* Num of reloc structs in use. */ struct { int n; @@ -343,11 +375,9 @@ struct m68k_it significance of some values (in the branch instruction, for example). */ int pcrel_fix; -#ifdef OBJ_ELF /* Whether this expression needs special pic relocation, and if so, which. */ enum pic_relocation pic_reloc; -#endif } reloc[5]; /* Five is enough??? */ }; @@ -367,6 +397,7 @@ struct m68k_it ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c)) #define HAVE_LONG_BRANCH(x) \ ((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b)) +#define LONG_BRANCH_VIA_COND(x) (HAVE_LONG_COND(x) && !HAVE_LONG_BRANCH(x)) static struct m68k_it the_ins; /* The instruction being assembled. */ @@ -407,9 +438,7 @@ add_fix (int width, struct m68k_exp *exp, int pc_rel, int pc_fix) the_ins.reloc[the_ins.nrel].exp = exp->exp; the_ins.reloc[the_ins.nrel].wid = width; the_ins.reloc[the_ins.nrel].pcrel_fix = pc_fix; -#ifdef OBJ_ELF the_ins.reloc[the_ins.nrel].pic_reloc = exp->pic_reloc; -#endif the_ins.reloc[the_ins.nrel++].pcrel = pc_rel; } @@ -471,7 +500,7 @@ struct m68k_cpu 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 @@ -506,6 +535,9 @@ static const struct m68k_cpu m68k_archs[] = {0,0,NULL, 0} }; +/* For -mno-mac we want to turn off all types of mac. */ +static const unsigned no_mac = mcfmac | mcfemac; + /* Architecture extensions, here 'alias' -1 for m68k, +1 for cf and 0 for either. */ static const struct m68k_cpu m68k_extensions[] = @@ -513,14 +545,14 @@ static const struct m68k_cpu m68k_extensions[] = {m68851, NULL, "68851", -1}, {m68881, NULL, "68881", -1}, {m68881, NULL, "68882", -1}, - + {cfloat|m68881, NULL, "float", 0}, - + {mcfhwdiv, NULL, "div", 1}, {mcfusp, NULL, "usp", 1}, - {mcfmac, NULL, "mac", 1}, + {mcfmac, (void *)&no_mac, "mac", 1}, {mcfemac, NULL, "emac", 1}, - + {0,NULL,NULL, 0} }; @@ -547,7 +579,7 @@ static const struct m68k_cpu m68k_cpus[] = {m68040, m68040_ctrl, "68ec040", 1}, {m68060, m68060_ctrl, "68060", 0}, {m68060, m68060_ctrl, "68ec060", 1}, - + {cpu32|m68881, cpu32_ctrl, "cpu32", 0}, {cpu32|m68881, cpu32_ctrl, "68330", 1}, {cpu32|m68881, cpu32_ctrl, "68331", 1}, @@ -559,28 +591,43 @@ static const struct m68k_cpu m68k_cpus[] = {cpu32|m68881, cpu32_ctrl, "68341", 1}, {cpu32|m68881, cpu32_ctrl, "68349", 1}, {cpu32|m68881, cpu32_ctrl, "68360", 1}, - + + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51", 0}, + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "51ac", 1}, + {mcfisa_a|mcfisa_c|mcfusp, mcf51_ctrl, "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}, @@ -588,45 +635,69 @@ static const struct m68k_cpu m68k_cpus[] = {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52235_ctrl, "52233", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52235_ctrl, "52234", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52235_ctrl, "52235", 0}, - + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5225_ctrl, "5224", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp, mcf5225_ctrl, "5225", 0}, - + + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52277_ctrl, "52274", -1}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf52277_ctrl, "52277", 0}, + {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "5232", -1}, {mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5235_ctrl, "5233", -1}, {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, mcf_ctrl, "5407",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}, @@ -634,7 +705,7 @@ static const struct m68k_cpu m68k_cpus[] = {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}, @@ -642,7 +713,7 @@ static const struct m68k_cpu m68k_cpus[] = {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}, @@ -650,7 +721,7 @@ static const struct m68k_cpu m68k_cpus[] = {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}, @@ -719,8 +790,14 @@ static void m68k_init_arch (void); #define PCINDEX 8 /* PC + displacement + index. */ #define ABSTOPCREL 9 /* Absolute relax down to 16-bit PC-relative. */ +/* This relaxation is required for branches where there is no long + branch and we are in pcrel mode. We generate a bne/beq pair. */ +#define BRANCHBWPL 10 /* Branch byte, word or pair of longs + */ + /* Note that calls to frag_var need to specify the maximum expansion - needed; this is currently 10 bytes for DBCC. */ + needed; this is currently 12 bytes for bne/beq pair. */ +#define FRAG_VAR_SIZE 12 /* The fields are: How far Forward this mode will reach: @@ -780,6 +857,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 @@ -799,12 +881,9 @@ const pseudo_typeS md_pseudo_table[] = {"even", s_even, 0}, {"skip", s_space, 0}, {"proc", s_proc, 0}, -#if defined (TE_SUN3) || defined (OBJ_ELF) {"align", s_align_bytes, 0}, -#endif -#ifdef OBJ_ELF {"swbeg", s_ignore, 0}, -#endif + {"long", m68k_elf_cons, 4}, {"extend", float_cons, 'x'}, {"ldouble", float_cons, 'x'}, @@ -871,15 +950,7 @@ const pseudo_typeS mote_pseudo_table[] = {"dsb", s_space, 1}, {"xdef", s_globl, 0}, -#ifdef OBJ_ELF {"align", s_align_bytes, 0}, -#else - {"align", s_align_ptwo, 0}, -#endif -#ifdef M68KCOFF - {"sect", obj_coff_section, 0}, - {"section", obj_coff_section, 0}, -#endif {0, 0, 0} }; @@ -904,7 +975,6 @@ static char alt_notend_table[256]; || (*s == ':' \ && alt_notend_table[(unsigned char) s[1]]))) -#ifdef OBJ_ELF /* Return zero if the reference to SYMBOL from within the same segment may be relaxed. */ @@ -976,6 +1046,66 @@ get_reloc_code (int size, int pcrel, enum pic_relocation pic) } break; + case pic_tls_gd: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_GD8; + case 2: + return BFD_RELOC_68K_TLS_GD16; + case 4: + return BFD_RELOC_68K_TLS_GD32; + } + break; + + case pic_tls_ldm: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_LDM8; + case 2: + return BFD_RELOC_68K_TLS_LDM16; + case 4: + return BFD_RELOC_68K_TLS_LDM32; + } + break; + + case pic_tls_ldo: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_LDO8; + case 2: + return BFD_RELOC_68K_TLS_LDO16; + case 4: + return BFD_RELOC_68K_TLS_LDO32; + } + break; + + case pic_tls_ie: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_IE8; + case 2: + return BFD_RELOC_68K_TLS_IE16; + case 4: + return BFD_RELOC_68K_TLS_IE32; + } + break; + + case pic_tls_le: + switch (size) + { + case 1: + return BFD_RELOC_68K_TLS_LE8; + case 2: + return BFD_RELOC_68K_TLS_LE16; + case 4: + return BFD_RELOC_68K_TLS_LE32; + } + break; + case pic_none: if (pcrel) { @@ -1044,6 +1174,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: @@ -1055,16 +1200,6 @@ tc_m68k_fix_adjustable (fixS *fixP) } } -#else /* !OBJ_ELF */ - -#define get_reloc_code(SIZE,PCREL,OTHER) NO_RELOC - -/* 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 */ - arelent * tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) { @@ -1121,6 +1256,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, @@ -1148,37 +1298,20 @@ 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) - 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 if (!fixp->fx_pcrel) 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; } @@ -1192,11 +1325,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; @@ -1266,7 +1399,7 @@ m68k_ip (char *instring) 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; @@ -1301,7 +1434,7 @@ m68k_ip (char *instring) opsfound = opP - &the_ins.operands[0]; /* This ugly hack is to support the floating pt opcodes in their - standard form. Essentially, we fake a first enty of type COP#1 */ + standard form. Essentially, we fake a first entry of type COP#1 */ if (opcode->m_operands[0] == 'I') { int n; @@ -1331,7 +1464,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]; @@ -1795,7 +1928,7 @@ m68k_ip (char *instring) else { const enum m68k_register *rp; - + for (rp = control_regs; *rp; rp++) { if (*rp == opP->reg) @@ -2145,13 +2278,13 @@ m68k_ip (char *instring) 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; the_ins.error = buf; /* Make sure there's a NUL at the end of the buffer -- strncpy - won't write one when it runs out of buffer */ + won't write one when it runs out of buffer. */ buf[space] = 0; #define APPEND(STRING) \ (strncpy (buf, STRING, space), len = strlen (buf), buf += len, space -= len) @@ -2160,34 +2293,41 @@ m68k_ip (char *instring) switch (ok_arch) { case mcfisa_a: - APPEND (_("ColdFire ISA_A")); + APPEND ("ColdFire ISA_A"); break; case mcfhwdiv: - APPEND (_("ColdFire hardware divide")); + APPEND ("ColdFire "); + APPEND (_("hardware divide")); break; case mcfisa_aa: - APPEND (_("ColdFire ISA_A+")); + APPEND ("ColdFire ISA_A+"); break; case mcfisa_b: - APPEND (_("ColdFire ISA_B")); + APPEND ("ColdFire ISA_B"); + break; + case mcfisa_c: + APPEND ("ColdFire ISA_C"); break; case cfloat: - APPEND (_("ColdFire fpu")); + APPEND ("ColdFire fpu"); break; case mfloat: - APPEND (_("M68K fpu")); + APPEND ("M68K fpu"); break; case mmmu: - APPEND (_("M68K mmu")); + APPEND ("M68K mmu"); break; case m68020up: - APPEND (_("68020 or higher")); + APPEND ("68020 "); + APPEND (_("or higher")); break; case m68000up: - APPEND (_("68000 or higher")); + APPEND ("68000 "); + APPEND (_("or higher")); break; case m68010up: - APPEND (_("68010 or higher")); + APPEND ("68010 "); + APPEND (_("or higher")); break; default: paren = 0; @@ -2200,7 +2340,7 @@ m68k_ip (char *instring) { const struct m68k_cpu *alias; int seen_master = 0; - + if (any) APPEND (", "); any = 0; @@ -2231,7 +2371,7 @@ m68k_ip (char *instring) #undef APPEND if (!space) { - /* we ran out of space, so replace the end of the list + /* We ran out of space, so replace the end of the list with ellipsis. */ buf -= 4; while (*buf != ' ') @@ -2257,9 +2397,10 @@ 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! */ + Watch the first step; it's a big one! */ switch (s[0]) { @@ -2459,12 +2600,9 @@ m68k_ip (char *instring) if (opP->reg == PC) { if (opP->disp.size == SIZE_LONG -#ifdef OBJ_ELF /* If the displacement needs pic relocation it cannot be relaxed. */ - || opP->disp.pic_reloc != pic_none -#endif - ) + || opP->disp.pic_reloc != pic_none) { addword (0x0170); add_fix ('l', &opP->disp, 1, 2); @@ -2583,7 +2721,7 @@ m68k_ip (char *instring) default: abort (); } - /* IF its simple, + /* IF it's simple, GET US OUT OF HERE! */ /* Must be INDEX, with an index register. Address @@ -2629,12 +2767,9 @@ m68k_ip (char *instring) && opP->reg == PC && isvar (&opP->disp) && subs (&opP->disp) == NULL -#ifdef OBJ_ELF /* If the displacement needs pic relocation it cannot be relaxed. */ - && opP->disp.pic_reloc == pic_none -#endif - ) + && opP->disp.pic_reloc == pic_none) { /* The code in md_convert_frag_1 needs to be able to adjust nextword. Call frag_grow @@ -2778,11 +2913,9 @@ m68k_ip (char *instring) if (isvar (&opP->disp) && !subs (&opP->disp) && adds (&opP->disp) -#ifdef OBJ_ELF /* If the displacement needs pic relocation it cannot be relaxed. */ && opP->disp.pic_reloc == pic_none -#endif && !flag_long_jumps && !strchr ("~%&$?", s[0])) { @@ -2792,7 +2925,7 @@ m68k_ip (char *instring) 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); @@ -2898,6 +3031,7 @@ m68k_ip (char *instring) break; case '3': tmpreg &= 0xFF; + /* Fall through. */ case '8': case 'C': case 'j': @@ -2917,7 +3051,7 @@ m68k_ip (char *instring) case 'B': tmpreg = get_num (&opP->disp, 90); - + switch (s[1]) { case 'B': @@ -2937,28 +3071,26 @@ m68k_ip (char *instring) 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. */ - || opP->disp.pic_reloc != pic_none -#endif - || 0) + || opP->disp.pic_reloc != pic_none) { 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 @@ -3003,7 +3135,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)) @@ -3073,7 +3206,7 @@ m68k_ip (char *instring) case 'e': /* EMAC ACCx, reg/reg. */ install_operand (s[1], opP->reg - ACC); break; - + case 'E': /* Ignore it. */ break; @@ -3134,6 +3267,15 @@ m68k_ip (char *instring) 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; @@ -3142,6 +3284,7 @@ m68k_ip (char *instring) tmpreg = 0x801; break; case CAAR: + case CPUCR: tmpreg = 0x802; break; case MSP: @@ -3232,7 +3375,7 @@ m68k_ip (char *instring) case CAC: tmpreg = 0xFFE; break; - case MBB: + case MBO: tmpreg = 0xFFF; break; default: @@ -3511,7 +3654,7 @@ m68k_ip (char *instring) } } - /* By the time whe get here (FINALLY) the_ins contains the complete + /* By the time when get here (FINALLY) the_ins contains the complete instruction, ready to be emitted. . . */ } @@ -3553,10 +3696,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 @@ -3701,7 +3843,7 @@ install_gen_operand (int mode, int val) switch (mode) { case '/': /* Special for mask loads for mac/msac insns with - possible mask; trailing_ampersend set in bit 8. */ + possible mask; trailing_ampersand set in bit 8. */ the_ins.opcode[0] |= (val & 0x3f); the_ins.opcode[1] |= (((val & 0x100) >> 8) << 5); break; @@ -3733,9 +3875,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) @@ -3904,6 +4046,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. */ @@ -3928,6 +4071,10 @@ static const struct init_entry init_table[] = { "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 }, @@ -3973,8 +4120,11 @@ static const struct init_entry init_table[] = { "mbar2", MBAR2 }, /* mcf5249 registers. */ + { "rgpiobar", RGPIOBAR }, /* mcf54418 registers. */ + { "cac", CAC }, /* fido registers. */ - { "mbb", MBB }, /* fido registers. */ + { "mbb", MBO }, /* fido registers (obsolete). */ + { "mbo", MBO }, /* fido registers. */ /* End of control registers. */ { "ac", AC }, @@ -4102,7 +4252,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. */ @@ -4163,10 +4313,8 @@ md_assemble (char *str) current_label = NULL; } -#ifdef OBJ_ELF /* Tie dwarf2 debug info to the address at the start of the insn. */ dwarf2_emit_insn (0); -#endif if (the_ins.nfrag == 0) { @@ -4201,7 +4349,7 @@ md_assemble (char *str) n = 4; break; default: - as_fatal (_("Don't know how to figure width of %c in md_assemble()"), + as_fatal (_("Don't know how to figure out width of %c in md_assemble()"), the_ins.reloc[m].wid); } @@ -4229,7 +4377,7 @@ md_assemble (char *str) for (n = 1; n < the_ins.nfrag; n++) wid += 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff); /* frag_var part. */ - wid += 10; + wid += FRAG_VAR_SIZE; /* Make sure the whole insn fits in one chunk, in particular that the var part is attached, as we access one byte before the variable frag for byte branches. */ @@ -4277,11 +4425,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) { @@ -4365,13 +4514,10 @@ md_begin (void) 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; @@ -4384,7 +4530,7 @@ md_begin (void) obstack_begin (&robyn, 4000); for (i = 0; i < m68k_numopcodes; i++) { - hack = slak = (struct m68k_incant *) obstack_alloc (&robyn, sizeof (struct m68k_incant)); + hack = slak = XOBNEW (&robyn, struct m68k_incant); do { ins = m68k_sorted_opcodes[i]; @@ -4394,7 +4540,7 @@ md_begin (void) 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 @@ -4410,11 +4556,11 @@ md_begin (void) 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 @@ -4432,7 +4578,7 @@ md_begin (void) { const char *name = m68k_opcode_aliases[i].primary; const char *alias = m68k_opcode_aliases[i].alias; - PTR val = hash_find (op_hash, name); + void *val = hash_find (op_hash, name); if (!val) as_fatal (_("Internal Error: Can't find %s in hash table"), name); @@ -4471,7 +4617,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); @@ -4531,7 +4677,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; @@ -4543,11 +4689,9 @@ md_begin (void) init_regtable (); -#ifdef OBJ_ELF record_alignment (text_section, 2); record_alignment (data_section, 2); record_alignment (bss_section, 2); -#endif } @@ -4558,17 +4702,15 @@ 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; -#ifdef OBJ_ELF dwarf2_emit_label (sym); -#endif } /* This is called when a value that is not an instruction is emitted. */ @@ -4648,63 +4790,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 @@ -4731,7 +4820,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1; -#ifdef OBJ_ELF if (fixP->fx_addsy) { memset (buf, 0, fixP->fx_size); @@ -4741,17 +4829,33 @@ 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 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) @@ -4830,12 +4934,12 @@ md_convert_frag_1 (fragS *fragP) 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. */ @@ -4849,6 +4953,7 @@ md_convert_frag_1 (fragS *fragP) case TAB (BRABSJUNC, BYTE): case TAB (BRABSJCOND, BYTE): case TAB (BRANCHBW, BYTE): + case TAB (BRANCHBWPL, BYTE): know (issbyte (disp)); if (disp == 0) as_bad_where (fragP->fr_file, fragP->fr_line, @@ -4861,6 +4966,7 @@ md_convert_frag_1 (fragS *fragP) case TAB (BRABSJUNC, SHORT): case TAB (BRABSJCOND, SHORT): case TAB (BRANCHBW, SHORT): + case TAB (BRANCHBWPL, SHORT): fragP->fr_opcode[1] = 0x00; fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, 1, RELAX_RELOC_PC16); @@ -4872,6 +4978,24 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_offset, 1, RELAX_RELOC_PC32); fragP->fr_fix += 4; break; + case TAB (BRANCHBWPL, LONG): + /* Here we are converting an unconditional branch into a pair of + conditional branches, in order to get the range. */ + fragP->fr_opcode[0] = 0x66; /* bne */ + fragP->fr_opcode[1] = 0xFF; + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC32); + fixP->fx_file = fragP->fr_file; + fixP->fx_line = fragP->fr_line; + fragP->fr_fix += 4; /* Skip first offset */ + buffer_address += 4; + *buffer_address++ = 0x67; /* beq */ + *buffer_address++ = 0xff; + fragP->fr_fix += 2; /* Skip second branch opcode */ + fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 1, RELAX_RELOC_PC32); + fragP->fr_fix += 4; + break; case TAB (BRABSJUNC, LONG): if (fragP->fr_opcode[0] == 0x61) /* jbsr */ { @@ -4944,10 +5068,6 @@ md_convert_frag_1 (fragS *fragP) /* 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. */ @@ -4999,14 +5119,14 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_fix += 4; break; case TAB (PCINDEX, BYTE): - assert (fragP->fr_fix >= 2); + gas_assert (fragP->fr_fix >= 2); buffer_address[-2] &= ~1; fixP = fix_new (fragP, fragP->fr_fix - 1, 1, fragP->fr_symbol, fragP->fr_offset, 1, RELAX_RELOC_PC8); fixP->fx_pcrel_adjust = 1; break; case TAB (PCINDEX, SHORT): - assert (fragP->fr_fix >= 2); + gas_assert (fragP->fr_fix >= 2); buffer_address[-2] |= 0x1; buffer_address[-1] = 0x20; fixP = fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol, @@ -5015,7 +5135,7 @@ md_convert_frag_1 (fragS *fragP) fragP->fr_fix += 2; break; case TAB (PCINDEX, LONG): - assert (fragP->fr_fix >= 2); + gas_assert (fragP->fr_fix >= 2); buffer_address[-2] |= 0x1; buffer_address[-1] = 0x30; fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol, @@ -5030,7 +5150,8 @@ md_convert_frag_1 (fragS *fragP) break; case TAB (ABSTOPCREL, LONG): if (flag_keep_pcrel) - as_fatal (_("Conversion of PC relative displacement to absolute")); + as_bad_where (fragP->fr_file, fragP->fr_line, + _("Conversion of PC relative displacement to absolute")); /* The thing to do here is force it to ABSOLUTE LONG, since ABSTOPCREL is really trying to shorten an ABSOLUTE address anyway. */ if ((fragP->fr_opcode[1] & 0x3F) != 0x3A) @@ -5067,6 +5188,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): { @@ -5186,36 +5308,6 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) return md_relax_table[fragP->fr_subtype].rlx_length; } -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) -/* the bit-field entries in the relocation_info struct plays hell - with the byte-order problems of cross-assembly. So as a hack, - I added this mach. dependent ri twiddler. Ugly, but it gets - you there. -KWK */ -/* on m68k: first 4 bytes are normal unsigned long, next three bytes - are symbolnum, most sig. byte first. Last byte is broken up with - bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower - nibble as nuthin. (on Sun 3 at least) */ -/* Translate the internal relocation information into target-specific - format. */ -#ifdef comment -void -md_ri_to_chars (char *the_bytes, struct reloc_info_generic *ri) -{ - /* This is easy. */ - md_number_to_chars (the_bytes, ri->r_address, 4); - /* Now the fun stuff. */ - the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff; - the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff; - the_bytes[6] = ri->r_symbolnum & 0x0ff; - the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) - | ((ri->r_length << 5) & 0x60) - | ((ri->r_extern << 4) & 0x10)); -} - -#endif - -#endif /* OBJ_AOUT or OBJ_BOUT */ - #ifndef WORKING_DOT_WORD int md_short_jump_size = 4; int md_long_jump_size = 6; @@ -5259,7 +5351,7 @@ md_create_long_jump (char *ptr, addressT from_addr, addressT to_addr, #endif -/* Different values of OK tell what its OK to return. Things that +/* Different values of OK tell what it's OK to return. Things that aren't OK are an error (what a shock, no?) 0: Everything is OK @@ -5442,8 +5534,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 (); @@ -5482,7 +5574,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++)) ; @@ -5510,7 +5602,7 @@ mri_chip (void) { ++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++)) ; @@ -5675,8 +5767,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++) { @@ -5686,14 +5777,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 @@ -5704,7 +5795,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++ == ','); @@ -5885,7 +5976,7 @@ 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; @@ -6005,7 +6096,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; @@ -6018,7 +6109,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; @@ -6177,8 +6268,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 : @@ -6297,9 +6388,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'; @@ -6317,7 +6408,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; @@ -6566,7 +6657,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); @@ -6637,7 +6728,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); @@ -6675,7 +6766,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); @@ -6849,7 +6940,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; @@ -7083,7 +7174,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); @@ -7115,7 +7206,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++; @@ -7123,7 +7214,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; @@ -7143,7 +7234,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)) @@ -7168,7 +7259,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; @@ -7197,7 +7288,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) { @@ -7223,7 +7314,7 @@ m68k_lookup_cpu (const char *arg, const struct m68k_cpu *table, return 0; } -/* Set the cpu, issuing errors if it is unrecognized, or invalid */ +/* Set the cpu, issuing errors if it is unrecognized. */ static int m68k_set_cpu (char const *name, int allow_m, int silent) @@ -7238,18 +7329,11 @@ m68k_set_cpu (char const *name, int allow_m, int silent) as_bad (_("cpu `%s' unrecognized"), name); return 0; } - - if (selected_cpu && selected_cpu != cpu) - { - as_bad (_("already selected `%s' processor"), - selected_cpu->name); - return 0; - } selected_cpu = cpu; return 1; } -/* Set the architecture, issuing errors if it is unrecognized, or invalid */ +/* Set the architecture, issuing errors if it is unrecognized. */ static int m68k_set_arch (char const *name, int allow_m, int silent) @@ -7264,14 +7348,6 @@ m68k_set_arch (char const *name, int allow_m, int silent) as_bad (_("architecture `%s' unrecognized"), name); return 0; } - - if (selected_arch && selected_arch != arch) - { - as_bad (_("already selected `%s' architecture"), - selected_arch->name); - return 0; - } - selected_arch = arch; return 1; } @@ -7295,7 +7371,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; @@ -7305,11 +7382,7 @@ m68k_set_extension (char const *name, int allow_m, int silent) Invocation line includes a switch not recognized by the base assembler. */ -#ifdef OBJ_ELF const char *md_shortopts = "lSA:m:kQ:V"; -#else -const char *md_shortopts = "lSA:m:k"; -#endif struct option md_longopts[] = { #define OPTION_PIC (OPTION_MD_BASE) @@ -7334,7 +7407,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) { @@ -7378,7 +7451,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 != '|') @@ -7451,7 +7524,7 @@ m68k_init_arch (void) } else current_architecture |= selected_cpu->arch; - + current_architecture &= ~not_current_architecture; if ((current_architecture & (cfloat | m68881)) == (cfloat | m68881)) @@ -7483,7 +7556,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) @@ -7496,7 +7569,7 @@ m68k_init_arch (void) if (cpu_of_arch (current_architecture) < m68020 || arch_coldfire_p (current_architecture)) md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0; - + initialized = 1; } @@ -7505,7 +7578,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') @@ -7514,7 +7586,6 @@ md_show_usage (FILE *stream) { 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) @@ -7529,11 +7600,11 @@ md_show_usage (FILE *stream) "), default_cpu); for (i = 0; m68k_extensions[i].name; i++) fprintf (stream, _("\ --m[no-]%-16s enable/disable%s architecture extension\n\ +-m[no-]%-16s enable/disable %s architecture extension\n\ "), 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\ @@ -7547,13 +7618,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"); @@ -7562,7 +7633,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")); } @@ -7675,18 +7746,6 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED) valueT md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) { -#ifdef OBJ_AOUT - /* For a.out, force the section size to be aligned. If we don't do - this, BFD will align it for us, but it will not write out the - final bytes of the section. This may be a bug in BFD, but it is - easier to fix it here since that is how the other a.out targets - work. */ - int align; - - align = bfd_get_section_alignment (stdoutput, segment); - size = ((size + (1 << align) - 1) & ((valueT) -1 << align)); -#endif - return size; } @@ -7699,20 +7758,17 @@ 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; } -#ifdef OBJ_ELF 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. */ @@ -7723,7 +7779,7 @@ m68k_elf_final_processing (void) 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] = @@ -7734,6 +7790,7 @@ m68k_elf_final_processing (void) {EF_M68K_CF_ISA_B_NOUSP,mcfisa_a|mcfisa_b|mcfhwdiv}, {EF_M68K_CF_ISA_B, mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp}, {EF_M68K_CF_ISA_C, mcfisa_a|mcfisa_c|mcfhwdiv|mcfusp}, + {EF_M68K_CF_ISA_C_NODIV,mcfisa_a|mcfisa_c|mcfusp}, {0,0}, }; static const unsigned mac_features[][2] = @@ -7744,7 +7801,7 @@ m68k_elf_final_processing (void) }; 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++) @@ -7783,10 +7840,120 @@ m68k_elf_final_processing (void) } elf_elfheader (stdoutput)->e_flags |= flags; } -#endif + +/* 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 (ngettext ("%s relocations do not fit in %u byte", + "%s relocations do not fit in %u bytes", + nbytes), + 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 (); +} int -tc_m68k_regname_to_dw2regnum (char *regname) +tc_m68k_regname_to_dw2regnum (const char *regname) { unsigned int regnum; static const char *const regnames[] = @@ -7815,3 +7982,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); +} +