X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68k.c;h=04baa6e6e3bd292c22637412fb4a033040676709;hb=e80e03907ce9e819196f7c0410fd8e783897c57f;hp=ff209a942e3e9b5545364e2f84070d491959c2a9;hpb=23b7f870fb76af586dc3a62b64b6e2368b42d64d;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index ff209a942e..04baa6e6e3 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1,7 +1,6 @@ /* tc-m68k.c -- Assemble for the m68k family Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 - Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -25,6 +24,7 @@ #include "obstack.h" #include "subsegs.h" #include "dwarf2dbg.h" +#include "dw2gencfi.h" #include "opcode/m68k.h" #include "m68k-parse.h" @@ -33,6 +33,10 @@ #include "elf/m68k.h" #endif +#ifdef M68KCOFF +#include "obj-coff.h" +#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 @@ -54,19 +58,19 @@ const char line_comment_chars[] = "#*"; const char line_separator_chars[] = ";"; -/* Chars that can be used to separate mant from exp in floating point nums */ -CONST char EXP_CHARS[] = "eE"; +/* Chars that can be used to separate mant from exp in floating point nums. */ +const char EXP_CHARS[] = "eE"; /* Chars that mean this number is a floating point constant, as in "0f12.456" or "0d1.2345e12". */ -CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP"; +const char FLT_CHARS[] = "rRsSfFdDxXeEpP"; /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be changed in read.c . Ideally it shouldn't have to know about it at all, but nothing is ideal around here. */ -const int md_reloc_size = 8; /* Size of relocation record */ +const int md_reloc_size = 8; /* Size of relocation record. */ /* Are we trying to generate PIC code? If so, absolute references ought to be made into linkage table references or pc-relative @@ -74,8 +78,8 @@ const int md_reloc_size = 8; /* Size of relocation record */ to denote pic relocations. */ int flag_want_pic; -static int flag_short_refs; /* -l option */ -static int flag_long_jumps; /* -S option */ +static int flag_short_refs; /* -l option. */ +static int flag_long_jumps; /* -S option. */ static int flag_keep_pcrel; /* --pcrel option. */ #ifdef REGISTER_PREFIX_OPTIONAL @@ -113,7 +117,6 @@ static enum m68k_size m68k_index_width_default = SIZE_LONG; /* We want to warn if any text labels are misaligned. In order to get the right line number, we need to record the line number for each label. */ - struct label_line { struct label_line *next; @@ -131,8 +134,11 @@ static struct label_line *labels; static struct label_line *current_label; -/* Its an arbitrary name: This means I don't approve of it */ -/* See flames below */ +/* 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. + See flames below. */ static struct obstack robyn; struct m68k_incant @@ -168,40 +174,55 @@ static const enum m68k_register m68060_control_regs[] = { 0 }; static const enum m68k_register mcf_control_regs[] = { - CACR, TC, ITT0, ITT1, DTT0, DTT1, VBR, ROMBAR, + CACR, TC, ACR0, ACR1, ACR2, ACR3, VBR, ROMBAR, RAMBAR0, RAMBAR1, MBAR, 0 }; +static const enum m68k_register mcf5249_control_regs[] = { + CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR1, MBAR, MBAR2, + 0 +}; +static const enum m68k_register mcf528x_control_regs[] = { + CACR, ACR0, ACR1, VBR, FLASHBAR, RAMBAR, + 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, + PCR1U0, PCR1L0, PCR1U1, PCR1L1, PCR2U0, PCR2L0, PCR2U1, PCR2L1, + PCR3U0, PCR3L0, PCR3U1, PCR3L1, + 0 +}; #define cpu32_control_regs m68010_control_regs static const enum m68k_register *control_regs; -/* internal form of a 68020 instruction */ +/* Internal form of a 68020 instruction. */ struct m68k_it { const char *error; - const char *args; /* list of opcode info */ + const char *args; /* List of opcode info. */ int numargs; - int numo; /* Number of shorts in opcode */ + int numo; /* Number of shorts in opcode. */ short opcode[11]; struct m68k_op operands[6]; - int nexp; /* number of exprs in use */ + int nexp; /* Number of exprs in use. */ struct m68k_exp exprs[4]; - int nfrag; /* Number of frags we have to produce */ + int nfrag; /* Number of frags we have to produce. */ struct { - int fragoff; /* Where in the current opcode the frag ends */ + int fragoff; /* Where in the current opcode the frag ends. */ symbolS *fadd; offsetT foff; int fragty; } fragb[4]; - int nrel; /* Num of reloc strucs in use */ + int nrel; /* Num of reloc strucs in use. */ struct { int n; @@ -222,65 +243,54 @@ struct m68k_it enum pic_relocation pic_reloc; #endif } - reloc[5]; /* Five is enough??? */ + reloc[5]; /* Five is enough??? */ }; -#define cpu_of_arch(x) ((x) & (m68000up|mcf)) +#define cpu_of_arch(x) ((x) & (m68000up | mcfisa_a)) #define float_of_arch(x) ((x) & mfloat) #define mmu_of_arch(x) ((x) & mmmu) -#define arch_coldfire_p(x) (((x) & mcf) != 0) +#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|mcf5407)) +/* Macros for determining if cpu supports a specific addressing mode. */ +#define HAVE_LONG_BRANCH(x) ((x) & (m68020|m68030|m68040|m68060|cpu32|mcfisa_b)) -static struct m68k_it the_ins; /* the instruction being assembled */ +static struct m68k_it the_ins; /* The instruction being assembled. */ #define op(ex) ((ex)->exp.X_op) #define adds(ex) ((ex)->exp.X_add_symbol) #define subs(ex) ((ex)->exp.X_op_symbol) #define offs(ex) ((ex)->exp.X_add_number) -/* Macros for adding things to the m68k_it struct */ - -#define addword(w) the_ins.opcode[the_ins.numo++]=(w) +/* Macros for adding things to the m68k_it struct. */ +#define addword(w) (the_ins.opcode[the_ins.numo++] = (w)) -/* Static functions. */ +/* Like addword, but goes BEFORE general operands. */ -static void insop PARAMS ((int, const struct m68k_incant *)); -static void add_fix PARAMS ((int, struct m68k_exp *, int, int)); -static void add_frag PARAMS ((symbolS *, offsetT, int)); - -/* Like addword, but goes BEFORE general operands */ static void -insop (w, opcode) - int w; - const struct m68k_incant *opcode; +insop (int w, const struct m68k_incant *opcode) { int z; for (z = the_ins.numo; z > opcode->m_codenum; --z) - the_ins.opcode[z]=the_ins.opcode[z-1]; - for (z = 0;z < the_ins.nrel; z++) - the_ins.reloc[z].n+=2; + the_ins.opcode[z] = the_ins.opcode[z - 1]; + for (z = 0; z < the_ins.nrel; z++) + the_ins.reloc[z].n += 2; for (z = 0; z < the_ins.nfrag; z++) the_ins.fragb[z].fragoff++; - the_ins.opcode[opcode->m_codenum]=w; + the_ins.opcode[opcode->m_codenum] = w; the_ins.numo++; } /* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch. */ static void -add_fix (width, exp, pc_rel, pc_fix) - int width; - struct m68k_exp *exp; - int pc_rel; - int pc_fix; +add_fix (int width, struct m68k_exp *exp, int pc_rel, int pc_fix) { - the_ins.reloc[the_ins.nrel].n = ((width == 'B' || width == '3') - ? (the_ins.numo*2-1) - : (((width)=='b') - ? (the_ins.numo*2+1) - : (the_ins.numo*2))); + the_ins.reloc[the_ins.nrel].n = (width == 'B' || width == '3' + ? the_ins.numo * 2 - 1 + : (width == 'b' + ? the_ins.numo * 2 + 1 + : the_ins.numo * 2)); 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; @@ -301,109 +311,126 @@ add_fix (width, exp, pc_rel, pc_fix) ADD becomes the FR_SYMBOL field of the frag, and OFF the FR_OFFSET. */ static void -add_frag (add, off, type) - symbolS *add; - offsetT off; - int type; +add_frag (symbolS *add, offsetT off, int type) { - the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo; - the_ins.fragb[the_ins.nfrag].fadd=add; - the_ins.fragb[the_ins.nfrag].foff=off; - the_ins.fragb[the_ins.nfrag++].fragty=type; + the_ins.fragb[the_ins.nfrag].fragoff = the_ins.numo; + the_ins.fragb[the_ins.nfrag].fadd = add; + the_ins.fragb[the_ins.nfrag].foff = off; + the_ins.fragb[the_ins.nfrag++].fragty = type; } #define isvar(ex) \ (op (ex) != O_constant && op (ex) != O_big) -static char *crack_operand PARAMS ((char *str, struct m68k_op *opP)); -static int get_num PARAMS ((struct m68k_exp *exp, int ok)); -static void m68k_ip PARAMS ((char *)); -static void insert_reg PARAMS ((const char *, int)); -static void select_control_regs PARAMS ((void)); -static void init_regtable PARAMS ((void)); -static int reverse_16_bits PARAMS ((int in)); -static int reverse_8_bits PARAMS ((int in)); -static void install_gen_operand PARAMS ((int mode, int val)); -static void install_operand PARAMS ((int mode, int val)); -static void s_bss PARAMS ((int)); -static void s_data1 PARAMS ((int)); -static void s_data2 PARAMS ((int)); -static void s_even PARAMS ((int)); -static void s_proc PARAMS ((int)); -static void mri_chip PARAMS ((void)); -static void s_chip PARAMS ((int)); -static void s_fopt PARAMS ((int)); -static void s_opt PARAMS ((int)); -static void s_reg PARAMS ((int)); -static void s_restore PARAMS ((int)); -static void s_save PARAMS ((int)); -static void s_mri_if PARAMS ((int)); -static void s_mri_else PARAMS ((int)); -static void s_mri_endi PARAMS ((int)); -static void s_mri_break PARAMS ((int)); -static void s_mri_next PARAMS ((int)); -static void s_mri_for PARAMS ((int)); -static void s_mri_endf PARAMS ((int)); -static void s_mri_repeat PARAMS ((int)); -static void s_mri_until PARAMS ((int)); -static void s_mri_while PARAMS ((int)); -static void s_mri_endw PARAMS ((int)); -static void md_convert_frag_1 PARAMS ((fragS *)); +static char *crack_operand (char *str, struct m68k_op *opP); +static int get_num (struct m68k_exp *exp, int ok); +static int reverse_16_bits (int in); +static int reverse_8_bits (int in); +static void install_gen_operand (int mode, int val); +static void install_operand (int mode, int val); +static void s_bss (int); +static void s_data1 (int); +static void s_data2 (int); +static void s_even (int); +static void s_proc (int); +static void s_chip (int); +static void s_fopt (int); +static void s_opt (int); +static void s_reg (int); +static void s_restore (int); +static void s_save (int); +static void s_mri_if (int); +static void s_mri_else (int); +static void s_mri_endi (int); +static void s_mri_break (int); +static void s_mri_next (int); +static void s_mri_for (int); +static void s_mri_endf (int); +static void s_mri_repeat (int); +static void s_mri_until (int); +static void s_mri_while (int); +static void s_mri_endw (int); static int current_architecture; +static int current_chip; struct m68k_cpu { unsigned long arch; + unsigned long chip; const char *name; int alias; }; static const struct m68k_cpu archs[] = { - { m68000, "68000", 0 }, - { m68010, "68010", 0 }, - { m68020, "68020", 0 }, - { m68030, "68030", 0 }, - { m68040, "68040", 0 }, - { m68060, "68060", 0 }, - { cpu32, "cpu32", 0 }, - { m68881, "68881", 0 }, - { m68851, "68851", 0 }, - { mcf5200, "5200", 0 }, - { mcf5206e, "5206e", 0 }, - { mcf5307, "5307", 0}, - { mcf5407, "5407", 0}, + { m68000, m68000, "68000", 0 }, + { m68010, m68010, "68010", 0 }, + { m68020, m68020, "68020", 0 }, + { m68030, m68030, "68030", 0 }, + { m68040, m68040, "68040", 0 }, + { m68060, m68060, "68060", 0 }, + { cpu32, cpu32, "cpu32", 0 }, + { m68881, m68881, "68881", 0 }, + { m68851, m68851, "68851", 0 }, + { mcfisa_a, mcf5200, "5200", 0 }, + { mcfisa_a|mcfhwdiv|mcfmac, mcf5206e, "5206e", 0 }, + { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf521x, "521x", 0 }, + { mcfisa_a|mcfhwdiv|mcfemac, mcf5249, "5249", 0 }, + { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf528x, "528x", 0 }, + { mcfisa_a|mcfhwdiv|mcfmac, mcf5307, "5307", 0 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac, mcf5407, "5407", 0 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "547x", 0 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5480, "548x", 0 }, /* Aliases (effectively, so far as gas is concerned) for the above cpus. */ - { m68020, "68k", 1 }, - { m68000, "68008", 1 }, - { m68000, "68302", 1 }, - { m68000, "68306", 1 }, - { m68000, "68307", 1 }, - { m68000, "68322", 1 }, - { m68000, "68356", 1 }, - { m68000, "68ec000", 1 }, - { m68000, "68hc000", 1 }, - { m68000, "68hc001", 1 }, - { m68020, "68ec020", 1 }, - { m68030, "68ec030", 1 }, - { m68040, "68ec040", 1 }, - { m68060, "68ec060", 1 }, - { cpu32, "68330", 1 }, - { cpu32, "68331", 1 }, - { cpu32, "68332", 1 }, - { cpu32, "68333", 1 }, - { cpu32, "68334", 1 }, - { cpu32, "68336", 1 }, - { cpu32, "68340", 1 }, - { cpu32, "68341", 1 }, - { cpu32, "68349", 1 }, - { cpu32, "68360", 1 }, - { m68881, "68882", 1 }, - { mcf5200, "5202", 1 }, - { mcf5200, "5204", 1 }, - { mcf5200, "5206", 1 }, + { m68020, m68020, "68k", 1 }, + { m68000, m68000, "68008", 1 }, + { m68000, m68000, "68302", 1 }, + { m68000, m68000, "68306", 1 }, + { m68000, m68000, "68307", 1 }, + { m68000, m68000, "68322", 1 }, + { m68000, m68000, "68356", 1 }, + { m68000, m68000, "68ec000", 1 }, + { m68000, m68000, "68hc000", 1 }, + { m68000, m68000, "68hc001", 1 }, + { m68020, m68020, "68ec020", 1 }, + { m68030, m68030, "68ec030", 1 }, + { m68040, m68040, "68ec040", 1 }, + { m68060, m68060, "68ec060", 1 }, + { cpu32, cpu32, "68330", 1 }, + { cpu32, cpu32, "68331", 1 }, + { cpu32, cpu32, "68332", 1 }, + { cpu32, cpu32, "68333", 1 }, + { cpu32, cpu32, "68334", 1 }, + { cpu32, cpu32, "68336", 1 }, + { cpu32, cpu32, "68340", 1 }, + { cpu32, cpu32, "68341", 1 }, + { cpu32, cpu32, "68349", 1 }, + { cpu32, cpu32, "68360", 1 }, + { m68881, m68881, "68882", 1 }, + { mcfisa_a, mcf5200, "5202", 1 }, + { mcfisa_a, mcf5200, "5204", 1 }, + { mcfisa_a, mcf5200, "5206", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_aa|mcfemac, mcf521x, "5214", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_aa|mcfemac, mcf521x, "5216", 1 }, + { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac, mcf528x, "5280", 1 }, + { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac, mcf528x, "5281", 1 }, + { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac, mcf528x, "5282", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac, mcf5407, "cfv4", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5470", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5471", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5472", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5473", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5474", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5475", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5480", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5481", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5482", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5483", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5484", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "5485", 1 }, + { mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac|mcfusp|cfloat, mcf5470, "cfv4e", 1 }, }; static const int n_archs = sizeof (archs) / sizeof (archs[0]); @@ -431,10 +458,10 @@ static const int n_archs = sizeof (archs) / sizeof (archs[0]); BYTE and SHORT forms, punting if that isn't enough. This gives us four different relaxation modes for branches: */ -#define BRANCHBWL 0 /* branch byte, word, or long */ -#define BRABSJUNC 1 /* absolute jump for LONG, unconditional */ -#define BRABSJCOND 2 /* absolute jump for LONG, conditional */ -#define BRANCHBW 3 /* branch byte or word */ +#define BRANCHBWL 0 /* Branch byte, word, or long. */ +#define BRABSJUNC 1 /* Absolute jump for LONG, unconditional. */ +#define BRABSJCOND 2 /* Absolute jump for LONG, conditional. */ +#define BRANCHBW 3 /* Branch byte or word. */ /* We also relax coprocessor branches and DBcc's. All CPUs that support coprocessor branches support them in word and long forms, so we have only @@ -444,9 +471,9 @@ static const int n_archs = sizeof (archs) / sizeof (archs[0]); This gives us two relaxation modes. If long branches are not available and absolute jumps are not acceptable, we don't relax DBcc's. */ -#define FBRANCH 4 /* coprocessor branch */ -#define DBCCLBR 5 /* DBcc relaxable with a long branch */ -#define DBCCABSJ 6 /* DBcc relaxable with an absolute jump */ +#define FBRANCH 4 /* Coprocessor branch. */ +#define DBCCLBR 5 /* DBcc relaxable with a long branch. */ +#define DBCCABSJ 6 /* DBcc relaxable with an absolute jump. */ /* That's all for instruction relaxation. However, we also relax PC-relative operands. Specifically, we have three operand relaxation modes. On the @@ -459,9 +486,9 @@ static const int n_archs = sizeof (archs) / sizeof (archs[0]); form of the PC+displacement+index operand. Finally, some absolute operands can be relaxed down to 16-bit PC-relative. */ -#define PCREL1632 7 /* 16-bit or 32-bit PC-relative */ -#define PCINDEX 8 /* PC+displacement+index */ -#define ABSTOPCREL 9 /* absolute relax down to 16-bit PC-relative */ +#define PCREL1632 7 /* 16-bit or 32-bit PC-relative. */ +#define PCINDEX 8 /* PC + displacement + index. */ +#define ABSTOPCREL 9 /* Absolute relax down to 16-bit PC-relative. */ /* Note that calls to frag_var need to specify the maximum expansion needed; this is currently 10 bytes for DBCC. */ @@ -471,7 +498,8 @@ static const int n_archs = sizeof (archs) / sizeof (archs[0]); How far Backward this mode will reach: How many bytes this mode will add to the size of the frag Which mode to go to if the offset won't fit in this one - */ + + Please check tc-m68k.h:md_prepare_relax_scan if changing this table. */ relax_typeS md_relax_table[] = { { 127, -128, 0, TAB (BRANCHBWL, SHORT) }, @@ -494,22 +522,22 @@ relax_typeS md_relax_table[] = { 1, 1, 0, 0 }, { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE */ + { 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE. */ { 32767, -32768, 2, TAB (FBRANCH, LONG) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */ + { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE. */ { 32767, -32768, 2, TAB (DBCCLBR, LONG) }, { 0, 0, 10, 0 }, { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */ + { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE. */ { 32767, -32768, 2, TAB (DBCCABSJ, LONG) }, { 0, 0, 10, 0 }, { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, /* PCREL1632 doesn't come BYTE */ + { 1, 1, 0, 0 }, /* PCREL1632 doesn't come BYTE. */ { 32767, -32768, 2, TAB (PCREL1632, LONG) }, { 0, 0, 6, 0 }, { 1, 1, 0, 0 }, @@ -519,7 +547,7 @@ relax_typeS md_relax_table[] = { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, - { 1, 1, 0, 0 }, /* ABSTOPCREL doesn't come BYTE */ + { 1, 1, 0, 0 }, /* ABSTOPCREL doesn't come BYTE. */ { 32767, -32768, 2, TAB (ABSTOPCREL, LONG) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, @@ -527,15 +555,13 @@ relax_typeS md_relax_table[] = /* These are the machine dependent pseudo-ops. These are included so the assembler can work on the output from the SUN C compiler, which - generates these. - */ + generates these. */ /* This table describes all the machine specific pseudo-ops the assembler has to support. The fields are: pseudo-op name without dot function to call to execute this pseudo-op - Integer arg to pass to the function - */ + Integer arg to pass to the function. */ const pseudo_typeS md_pseudo_table[] = { {"data1", s_data1, 0}, @@ -553,12 +579,6 @@ const pseudo_typeS md_pseudo_table[] = {"extend", float_cons, 'x'}, {"ldouble", float_cons, 'x'}, -#ifdef OBJ_ELF - /* Dwarf2 support for Gcc. */ - {"file", dwarf2_directive_file, 0}, - {"loc", dwarf2_directive_loc, 0}, -#endif - /* The following pseudo-ops are supported for MRI compatibility. */ {"chip", s_chip, 0}, {"comline", s_space, 1}, @@ -603,14 +623,9 @@ const pseudo_typeS md_pseudo_table[] = }; /* The mote pseudo ops are put into the opcode table, since they - don't start with a . they look like opcodes to gas. - */ - -#ifdef M68KCOFF -extern void obj_coff_section PARAMS ((int)); -#endif + don't start with a . they look like opcodes to gas. */ -CONST pseudo_typeS mote_pseudo_table[] = +const pseudo_typeS mote_pseudo_table[] = { {"dcl", cons, 4}, @@ -636,17 +651,15 @@ CONST pseudo_typeS mote_pseudo_table[] = {0, 0, 0} }; -#define issbyte(x) ((x)>=-128 && (x)<=127) -#define isubyte(x) ((x)>=0 && (x)<=255) -#define issword(x) ((x)>=-32768 && (x)<=32767) -#define isuword(x) ((x)>=0 && (x)<=65535) +#define issbyte(x) ((x) >= -128 && (x) <= 127) +#define isubyte(x) ((x) >= 0 && (x) <= 255) +#define issword(x) ((x) >= -32768 && (x) <= 32767) +#define isuword(x) ((x) >= 0 && (x) <= 65535) -#define isbyte(x) ((x)>= -255 && (x)<=255) -#define isword(x) ((x)>=-65536 && (x)<=65535) +#define isbyte(x) ((x) >= -255 && (x) <= 255) +#define isword(x) ((x) >= -65536 && (x) <= 65535) #define islong(x) (1) -extern char *input_line_pointer; - static char notend_table[256]; static char alt_notend_table[256]; #define notend(s) \ @@ -654,28 +667,97 @@ 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; i < n_archs; ++i) + if (archs[i].arch & architecture) + { + n_chips++; + if (archs[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; i < n_archs && j < n_chips; ++i) + if (archs[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, archs[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; +} + #if defined (M68KCOFF) && !defined (BFD_ASSEMBLER) #ifdef NO_PCREL_RELOCS int -make_pcrel_absolute(fixP, add_number) - fixS *fixP; - long *add_number; +make_pcrel_absolute (fixS *fixP, long *add_number) { register unsigned char *opcode = fixP->fx_frag->fr_opcode; - /* rewrite the PC relative instructions to absolute address ones. - * these are rumoured to be faster, and the apollo linker refuses - * to deal with the PC relative relocations. - */ - if (opcode[0] == 0x60 && opcode[1] == 0xff) /* BRA -> JMP */ + /* Rewrite the PC relative instructions to absolute address ones. + these are rumored to be faster, and the apollo linker refuses + to deal with the PC relative relocations. */ + if (opcode[0] == 0x60 && opcode[1] == 0xff) /* BRA -> JMP. */ { + if (flag_keep_pcrel) + as_fatal (_("Tried to convert PC relative branch to absolute jump")); opcode[0] = 0x4e; opcode[1] = 0xf9; } - else if (opcode[0] == 0x61 && opcode[1] == 0xff) /* BSR -> JSR */ + else if (opcode[0] == 0x61 && opcode[1] == 0xff) /* BSR -> JSR. */ { + if (flag_keep_pcrel) + as_fatal (_("Tried to convert PC relative BSR to absolute JSR")); opcode[0] = 0x4e; opcode[1] = 0xb9; } @@ -688,8 +770,7 @@ make_pcrel_absolute(fixP, add_number) #endif /* NO_PCREL_RELOCS */ short -tc_coff_fix2rtype (fixP) - fixS *fixP; +tc_coff_fix2rtype (fixS *fixP) { if (fixP->fx_tcbit && fixP->fx_size == 4) return R_RELLONG_NEG; @@ -699,13 +780,13 @@ tc_coff_fix2rtype (fixP) : fixP->fx_size == 2 ? R_DIR16 : R_DIR32); #else - return (fixP->fx_pcrel ? - (fixP->fx_size == 1 ? R_PCRBYTE : - fixP->fx_size == 2 ? R_PCRWORD : - R_PCRLONG) : - (fixP->fx_size == 1 ? R_RELBYTE : - fixP->fx_size == 2 ? R_RELWORD : - R_RELLONG)); + return (fixP->fx_pcrel + ? (fixP->fx_size == 1 ? R_PCRBYTE + : fixP->fx_size == 2 ? R_PCRWORD + : R_PCRLONG) + : (fixP->fx_size == 1 ? R_RELBYTE + : fixP->fx_size == 2 ? R_RELWORD + : R_RELLONG)); #endif } @@ -723,21 +804,15 @@ tc_coff_fix2rtype (fixP) libraries, and we can relax any external sym. */ #define relaxable_symbol(symbol) \ - (!((S_IS_EXTERNAL (symbol) && strcmp (TARGET_OS, "elf") != 0) \ + (!((S_IS_EXTERNAL (symbol) && EXTERN_FORCE_RELOC) \ || S_IS_WEAK (symbol))) /* Compute the relocation code for a fixup of SIZE bytes, using pc relative relocation if PCREL is non-zero. PIC says whether a special pic relocation was requested. */ -static bfd_reloc_code_real_type get_reloc_code - PARAMS ((int, int, enum pic_relocation)); - static bfd_reloc_code_real_type -get_reloc_code (size, pcrel, pic) - int size; - int pcrel; - enum pic_relocation pic; +get_reloc_code (int size, int pcrel, enum pic_relocation pic) { switch (pic) { @@ -840,14 +915,9 @@ get_reloc_code (size, pcrel, pic) correctly, so in some cases we force the original symbol to be used. */ int -tc_m68k_fix_adjustable (fixP) - fixS *fixP; +tc_m68k_fix_adjustable (fixS *fixP) { - /* Prevent all adjustments to global symbols. */ - if (! relaxable_symbol (fixP->fx_addsy)) - return 0; - - /* adjust_reloc_syms doesn't know about the GOT */ + /* Adjust_reloc_syms doesn't know about the GOT. */ switch (fixP->fx_r_type) { case BFD_RELOC_8_GOT_PCREL: @@ -884,9 +954,7 @@ tc_m68k_fix_adjustable (fixP) #ifdef BFD_ASSEMBLER arelent * -tc_gen_reloc (section, fixp) - asection *section; - fixS *fixp; +tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; bfd_reloc_code_real_type code; @@ -1004,8 +1072,7 @@ static struct hash_control *op_hash; /* Assemble an m68k instruction. */ static void -m68k_ip (instring) - char *instring; +m68k_ip (char *instring) { register char *p; register struct m68k_op *opP; @@ -1022,7 +1089,7 @@ m68k_ip (instring) unsigned long ok_arch = 0; if (*instring == ' ') - instring++; /* skip leading whitespace */ + instring++; /* Skip leading whitespace. */ /* Scan up to end of operation-code, which MUST end in end-of-string or exactly 1 space. */ @@ -1071,7 +1138,7 @@ m68k_ip (instring) return; } - /* found a legitimate opcode, start matching operands */ + /* Found a legitimate opcode, start matching operands. */ while (*p == ' ') ++p; @@ -1080,7 +1147,7 @@ m68k_ip (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 psuedo op. */ mote_pseudo_table[opcode->m_opnum].poc_handler (mote_pseudo_table[opcode->m_opnum].poc_val); input_line_pointer = old; @@ -1123,14 +1190,13 @@ m68k_ip (instring) for (n = opsfound; n > 0; --n) the_ins.operands[n] = the_ins.operands[n - 1]; - memset ((char *) (&the_ins.operands[0]), '\0', - sizeof (the_ins.operands[0])); + memset (&the_ins.operands[0], '\0', sizeof (the_ins.operands[0])); the_ins.operands[0].mode = CONTROL; the_ins.operands[0].reg = m68k_float_copnum; opsfound++; } - /* We've got the operands. Find an opcode that'll accept them */ + /* We've got the operands. Find an opcode that'll accept them. */ for (losing = 0;;) { /* If we didn't get the right number of ops, or we have no @@ -1223,7 +1289,7 @@ m68k_ip (instring) default: losing++; } - break; + break; case 'n': switch (opP->mode) @@ -1233,7 +1299,7 @@ m68k_ip (instring) default: losing++; } - break; + break; case 'o': switch (opP->mode) @@ -1245,7 +1311,7 @@ m68k_ip (instring) default: losing++; } - break; + break; case 'p': switch (opP->mode) @@ -1258,12 +1324,12 @@ m68k_ip (instring) break; case DISP: if (opP->reg == PC || opP->reg == ZPC) - losing++; + losing++; break; default: losing++; } - break; + break; case 'q': switch (opP->mode) @@ -1275,13 +1341,13 @@ m68k_ip (instring) break; case DISP: if (opP->reg == PC || opP->reg == ZPC) - losing++; + losing++; break; default: losing++; break; } - break; + break; case 'v': switch (opP->mode) @@ -1294,7 +1360,7 @@ m68k_ip (instring) break; case DISP: if (opP->reg == PC || opP->reg == ZPC) - losing++; + losing++; break; default: losing++; @@ -1500,6 +1566,14 @@ m68k_ip (instring) ++losing; break; + case '4': + if (opP->mode != AINDR && opP->mode != AINC && opP->mode != ADEC + && (opP->mode != DISP + || opP->reg < ADDR0 + || opP->reg > ADDR7)) + ++losing; + break; + case 'B': /* FOO */ if (opP->mode != ABSL || (flag_long_jumps @@ -1507,6 +1581,24 @@ m68k_ip (instring) losing++; break; + case 'b': + switch (opP->mode) + { + case IMMED: + case ABSL: + case AREG: + case FPREG: + case CONTROL: + case POST: + case PRE: + case REGLST: + losing++; + break; + default: + break; + } + break; + case 'C': if (opP->mode != CONTROL || opP->reg != CCR) losing++; @@ -1529,6 +1621,12 @@ m68k_ip (instring) losing++; break; + case 'e': + if (opP->reg != ACC && opP->reg != ACC1 + && opP->reg != ACC2 && opP->reg != ACC3) + losing++; + break; + case 'F': if (opP->mode != FPREG) losing++; @@ -1539,6 +1637,11 @@ m68k_ip (instring) losing++; break; + case 'g': + if (opP->reg != ACCEXT01 && opP->reg != ACCEXT23) + losing++; + break; + case 'H': if (opP->reg != MASK) losing++; @@ -1551,6 +1654,11 @@ m68k_ip (instring) losing++; break; + case 'i': + if (opP->mode != LSH && opP->mode != RSH) + losing++; + break; + case 'J': if (opP->mode != CONTROL || opP->reg < USP @@ -1711,6 +1819,16 @@ m68k_ip (instring) losing++; break; + case 'x': + if (opP->mode != IMMED) + losing++; + else if (opP->disp.exp.X_op != O_constant + || opP->disp.exp.X_add_number < -1 + || opP->disp.exp.X_add_number > 7 + || opP->disp.exp.X_add_number == 0) + 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. @@ -1718,7 +1836,7 @@ m68k_ip (instring) Don't forget that you need these operands to use 68030 MMU instructions. */ #ifndef NO_68851 - /* Memory addressing mode used by pflushr */ + /* Memory addressing mode used by pflushr. */ case '|': if (opP->mode == CONTROL || opP->mode == FPREG @@ -1772,6 +1890,25 @@ m68k_ip (instring) losing++; break; + case 'w': + switch (opP->mode) + { + case IMMED: + case ABSL: + case AREG: + case DREG: + case FPREG: + case CONTROL: + case POST: + case PRE: + case REGLST: + losing++; + break; + default: + break; + } + break; + case 'X': if (opP->mode != CONTROL || (!(opP->reg >= BAD && opP->reg <= BAD + 7) @@ -1795,9 +1932,7 @@ m68k_ip (instring) && opP->reg != IC && opP->reg != DC && opP->reg != BC)) - { - losing++; - } /* not a cache specifier. */ + losing++; break; case '_': @@ -1818,19 +1953,29 @@ m68k_ip (instring) opP->mode = AREG; break; + case 'y': + if (!(opP->mode == AINDR + || (opP->mode == DISP + && !(opP->reg == PC || opP->reg == ZPC)))) + losing++; + break; + + case 'z': + if (!(opP->mode == AINDR || opP->mode == DISP)) + losing++; + break; + default: abort (); - } /* switch on type of operand */ + } if (losing) break; - } /* for each operand */ - } /* if immediately wrong */ + } + } if (!losing) - { - break; - } /* got it. */ + break; opcode = opcode->m_next; @@ -1841,11 +1986,51 @@ m68k_ip (instring) { char buf[200], *cp; - strcpy (buf, - _("invalid instruction for this architecture; needs ")); + strncpy (buf, + _("invalid instruction for this architecture; needs "), + sizeof (buf)); cp = buf + strlen (buf); 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); + 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); + 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); + 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); + 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); + break; case mfloat: strcpy (cp, _("fpu (68040, 68060 or 68881/68882)")); break; @@ -1864,9 +2049,8 @@ m68k_ip (instring) default: { int got_one = 0, idx; - for (idx = 0; - idx < (int) (sizeof (archs) / sizeof (archs[0])); - idx++) + + for (idx = 0; idx < n_archs; idx++) { if ((archs[idx].arch & ok_arch) && ! archs[idx].alias) @@ -1890,13 +2074,12 @@ m68k_ip (instring) else the_ins.error = _("operands mismatch"); return; - } /* Fell off the end */ + } losing = 0; } - /* now assemble it */ - + /* Now assemble it. */ the_ins.args = opcode->m_operands; the_ins.numargs = opcode->m_opnum; the_ins.numo = opcode->m_codenum; @@ -1906,7 +2089,7 @@ m68k_ip (instring) for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) { /* This switch is a doozy. - Watch the first step; its a big one! */ + Watch the first step; its a big one! */ switch (s[0]) { @@ -1922,12 +2105,17 @@ m68k_ip (instring) case '/': case '<': case '>': + case 'b': case 'm': case 'n': case 'o': case 'p': case 'q': case 'v': + case 'w': + case 'y': + case 'z': + case '4': #ifndef NO_68851 case '|': #endif @@ -1936,7 +2124,7 @@ m68k_ip (instring) case IMMED: tmpreg = 0x3c; /* 7.4 */ if (strchr ("bwl", s[1])) - nextword = get_num (&opP->disp, 80); + nextword = get_num (&opP->disp, 90); else nextword = get_num (&opP->disp, 0); if (isvar (&opP->disp)) @@ -1989,7 +2177,7 @@ m68k_ip (instring) if (!baseo) break; - /* We gotta put out some float */ + /* We gotta put out some float. */ if (op (&opP->disp) != O_big) { valueT val; @@ -2048,7 +2236,20 @@ m68k_ip (instring) break; case DISP: - nextword = get_num (&opP->disp, 80); + nextword = get_num (&opP->disp, 90); + + /* Convert mode 5 addressing with a zero offset into + mode 2 addressing to reduce the instruction size by a + word. */ + if (! isvar (&opP->disp) + && (nextword == 0) + && (opP->disp.size == SIZE_UNSPEC) + && (opP->reg >= ADDR0) + && (opP->reg <= ADDR7)) + { + tmpreg = 0x10 + opP->reg - ADDR; /* 2.areg */ + break; + } if (opP->reg == PC && ! isvar (&opP->disp) @@ -2063,7 +2264,7 @@ m68k_ip (instring) #endif } - /* Force into index mode. Hope this works */ + /* Force into index mode. Hope this works. */ /* We do the first bit for 32-bit displacements, and the second bit for 16 bit ones. It is possible that we @@ -2144,9 +2345,9 @@ m68k_ip (instring) case PRE: case BASE: nextword = 0; - baseo = get_num (&opP->disp, 80); + baseo = get_num (&opP->disp, 90); if (opP->mode == POST || opP->mode == PRE) - outro = get_num (&opP->odisp, 80); + outro = get_num (&opP->odisp, 90); /* Figure out the `addressing mode'. Also turn on the BASE_DISABLE bit, if needed. */ if (opP->reg == PC || opP->reg == ZPC) @@ -2174,7 +2375,7 @@ m68k_ip (instring) else siz2 = SIZE_UNSPEC; - /* Index register stuff */ + /* Index register stuff. */ if (opP->index.reg != 0 && opP->index.reg >= DATA && opP->index.reg <= ADDR7) @@ -2189,7 +2390,8 @@ m68k_ip (instring) if ((opP->index.scale != 1 && cpu_of_arch (current_architecture) < m68020) || (opP->index.scale == 8 - && arch_coldfire_p (current_architecture))) + && (arch_coldfire_p (current_architecture) + && !arch_coldfire_fpu (current_architecture)))) { opP->error = _("scale factor invalid on this architecture; needs cpu32 or 68020 or higher"); @@ -2274,18 +2476,18 @@ m68k_ip (instring) the frag obstack to make all the bytes contiguous. */ frag_grow (14); - nextword += baseo & 0xff; - addword (nextword); - add_frag (adds (&opP->disp), offs (&opP->disp), - TAB (PCINDEX, SZ_UNDEF)); + nextword += baseo & 0xff; + addword (nextword); + add_frag (adds (&opP->disp), offs (&opP->disp), + TAB (PCINDEX, SZ_UNDEF)); break; - } + } } } else { - nextword |= 0x40; /* No index reg */ + nextword |= 0x40; /* No index reg. */ if (opP->index.reg >= ZDATA0 && opP->index.reg <= ZDATA7) nextword |= (opP->index.reg - ZDATA0) << 12; @@ -2333,7 +2535,7 @@ m68k_ip (instring) break; } - /* Figure out innner displacement stuff */ + /* Figure out inner displacement stuff. */ if (opP->mode == POST || opP->mode == PRE) { if (cpu_of_arch (current_architecture) & cpu32) @@ -2394,7 +2596,7 @@ m68k_ip (instring) break; case ABSL: - nextword = get_num (&opP->disp, 80); + nextword = get_num (&opP->disp, 90); switch (opP->disp.size) { default: @@ -2423,7 +2625,7 @@ m68k_ip (instring) TAB (ABSTOPCREL, SZ_UNDEF)); break; } - /* Fall through into long */ + /* Fall through into long. */ case SIZE_LONG: if (isvar (&opP->disp)) add_fix ('l', &opP->disp, 0, 0); @@ -2436,7 +2638,8 @@ m68k_ip (instring) case SIZE_BYTE: as_bad (_("unsupported byte value; use a different suffix")); /* Fall through. */ - case SIZE_WORD: /* Word */ + + case SIZE_WORD: if (isvar (&opP->disp)) add_fix ('w', &opP->disp, 0, 0); @@ -2451,6 +2654,16 @@ m68k_ip (instring) as_bad (_("unknown/incorrect operand")); /* abort (); */ } + + /* If s[0] is '4', then this is for the mac instructions + that can have a trailing_ampersand set. If so, set 0x100 + bit on tmpreg so install_gen_operand can check for it and + set the appropriate bit (word2, bit 5). */ + if (s[0] == '4') + { + if (opP->trailing_ampersand) + tmpreg |= 0x100; + } install_gen_operand (s[1], tmpreg); break; @@ -2469,7 +2682,7 @@ m68k_ip (instring) break; case '3': default: - tmpreg = 80; + tmpreg = 90; break; } tmpreg = get_num (&opP->disp, tmpreg); @@ -2536,7 +2749,7 @@ m68k_ip (instring) break; case 'B': - tmpreg = get_num (&opP->disp, 80); + tmpreg = get_num (&opP->disp, 90); switch (s[1]) { case 'B': @@ -2556,7 +2769,7 @@ m68k_ip (instring) addword (0); break; case 'g': - if (subs (&opP->disp)) /* We can't relax it */ + if (subs (&opP->disp)) /* We can't relax it. */ goto long_branch; #ifdef OBJ_ELF @@ -2629,12 +2842,12 @@ m68k_ip (instring) } addword (0); break; - case 'C': /* Fixed size LONG coproc branches */ + case 'C': /* Fixed size LONG coproc branches. */ add_fix ('l', &opP->disp, 1, 0); addword (0); addword (0); break; - case 'c': /* Var size Coprocesssor branches */ + case 'c': /* Var size Coprocesssor branches. */ if (subs (&opP->disp) || (adds (&opP->disp) == 0)) { the_ins.opcode[the_ins.numo - 1] |= 0x40; @@ -2651,12 +2864,12 @@ m68k_ip (instring) } break; - case 'C': /* Ignore it */ + case 'C': /* Ignore it. */ break; - case 'd': /* JF this is a kludge */ + case 'd': /* JF this is a kludge. */ install_operand ('s', opP->reg - ADDR); - tmpreg = get_num (&opP->disp, 80); + tmpreg = get_num (&opP->disp, 90); if (!issword (tmpreg)) { as_warn (_("Expression out of range, using 0")); @@ -2669,14 +2882,22 @@ m68k_ip (instring) install_operand (s[1], opP->reg - DATA); break; - case 'E': /* Ignore it */ + case 'e': /* EMAC ACCx, reg/reg. */ + install_operand (s[1], opP->reg - ACC); + break; + + case 'E': /* Ignore it. */ break; case 'F': install_operand (s[1], opP->reg - FP0); break; - case 'G': /* Ignore it */ + case 'g': /* EMAC ACCEXTx. */ + install_operand (s[1], opP->reg - ACCEXT01); + break; + + case 'G': /* Ignore it. */ case 'H': break; @@ -2685,7 +2906,11 @@ m68k_ip (instring) install_operand (s[1], tmpreg); break; - case 'J': /* JF foo */ + case 'i': /* MAC/EMAC scale factor. */ + install_operand (s[1], opP->mode == LSH ? 0x1 : 0x3); + break; + + case 'J': /* JF foo. */ switch (opP->reg) { case SFC: @@ -2700,15 +2925,19 @@ m68k_ip (instring) case TC: tmpreg = 0x003; break; + case ACR0: case ITT0: tmpreg = 0x004; break; + case ACR1: case ITT1: tmpreg = 0x005; break; + case ACR2: case DTT0: tmpreg = 0x006; break; + case ACR3: case DTT1: tmpreg = 0x007; break; @@ -2746,15 +2975,68 @@ m68k_ip (instring) case ROMBAR: tmpreg = 0xC00; break; + case ROMBAR1: + tmpreg = 0xC01; + break; + case FLASHBAR: case RAMBAR0: tmpreg = 0xC04; break; + case RAMBAR: case RAMBAR1: tmpreg = 0xC05; break; + case MPCR: + tmpreg = 0xC0C; + break; + case EDRAMBAR: + tmpreg = 0xC0D; + break; + case MBAR0: + case MBAR2: + case SECMBAR: + tmpreg = 0xC0E; + break; + case MBAR1: case MBAR: tmpreg = 0xC0F; break; + case PCR1U0: + tmpreg = 0xD02; + break; + case PCR1L0: + tmpreg = 0xD03; + break; + case PCR2U0: + tmpreg = 0xD04; + break; + case PCR2L0: + tmpreg = 0xD05; + break; + case PCR3U0: + tmpreg = 0xD06; + break; + case PCR3L0: + tmpreg = 0xD07; + break; + case PCR1L1: + tmpreg = 0xD0A; + break; + case PCR1U1: + tmpreg = 0xD0B; + break; + case PCR2L1: + tmpreg = 0xD0C; + break; + case PCR2U1: + tmpreg = 0xD0D; + break; + case PCR3L1: + tmpreg = 0xD0E; + break; + case PCR3U1: + tmpreg = 0xD0F; + break; default: abort (); } @@ -2826,7 +3108,7 @@ m68k_ip (instring) case 'R': /* This depends on the fact that ADDR registers are eight more than their corresponding DATA regs, so the result - will have the ADDR_REG bit set */ + will have the ADDR_REG bit set. */ install_operand (s[1], opP->reg - DATA); break; @@ -2849,14 +3131,14 @@ m68k_ip (instring) install_operand (s[1], tmpreg); break; - case 'S': /* Ignore it */ + case 'S': /* Ignore it. */ break; case 'T': install_operand (s[1], get_num (&opP->disp, 30)); break; - case 'U': /* Ignore it */ + case 'U': /* Ignore it. */ break; case 'c': @@ -2876,7 +3158,7 @@ m68k_ip (instring) break; default: as_fatal (_("failed sanity check")); - } /* switch on cache token */ + } /* switch on cache token. */ install_operand (s[1], tmpreg); break; #ifndef NO_68851 @@ -3000,17 +3282,23 @@ m68k_ip (instring) tmpreg = get_num (&opP->disp, 20); install_operand (s[1], tmpreg); break; - case '_': /* used only for move16 absolute 32-bit address */ + case '_': /* used only for move16 absolute 32-bit address. */ if (isvar (&opP->disp)) add_fix ('l', &opP->disp, 0, 0); - tmpreg = get_num (&opP->disp, 80); + tmpreg = get_num (&opP->disp, 90); addword (tmpreg >> 16); addword (tmpreg & 0xFFFF); break; case 'u': install_operand (s[1], opP->reg - DATA0L); opP->reg -= (DATA0L); - opP->reg &= 0x0F; /* remove upper/lower bit */ + opP->reg &= 0x0F; /* remove upper/lower bit. */ + break; + case 'x': + tmpreg = get_num (&opP->disp, 80); + if (tmpreg == -1) + tmpreg = 0; + install_operand (s[1], tmpreg); break; default: abort (); @@ -3022,8 +3310,7 @@ m68k_ip (instring) } static int -reverse_16_bits (in) - int in; +reverse_16_bits (int in) { int out = 0; int n; @@ -3042,8 +3329,7 @@ reverse_16_bits (in) } /* reverse_16_bits() */ static int -reverse_8_bits (in) - int in; +reverse_8_bits (int in) { int out = 0; int n; @@ -3072,14 +3358,12 @@ reverse_8_bits (in) ADD becomes the FR_SYMBOL field of the frag, and OFF the FR_OFFSET. */ static void -install_operand (mode, val) - int mode; - int val; +install_operand (int mode, int val) { switch (mode) { case 's': - the_ins.opcode[0] |= val & 0xFF; /* JF FF is for M kludge */ + the_ins.opcode[0] |= val & 0xFF; /* JF FF is for M kludge. */ break; case 'd': the_ins.opcode[0] |= val << 9; @@ -3134,7 +3418,7 @@ install_operand (mode, val) break; case 'j': the_ins.opcode[1] |= val; - the_ins.numo++; /* What a hack */ + the_ins.numo++; /* What a hack. */ break; case 'k': the_ins.opcode[1] |= val << 4; @@ -3156,38 +3440,62 @@ install_operand (mode, val) the_ins.opcode[0] |= ((val & 0x7) << 9); the_ins.opcode[1] |= ((val & 0x10) << (7 - 4)); break; - case 'n': + case 'n': /* MAC/EMAC Rx on !load. */ the_ins.opcode[0] |= ((val & 0x8) << (6 - 3)); the_ins.opcode[0] |= ((val & 0x7) << 9); + the_ins.opcode[1] |= ((val & 0x10) << (7 - 4)); break; - case 'o': + case 'o': /* MAC/EMAC Rx on load. */ the_ins.opcode[1] |= val << 12; the_ins.opcode[1] |= ((val & 0x10) << (7 - 4)); break; - case 'M': + case 'M': /* MAC/EMAC Ry on !load. */ the_ins.opcode[0] |= (val & 0xF); the_ins.opcode[1] |= ((val & 0x10) << (6 - 4)); break; - case 'N': + case 'N': /* MAC/EMAC Ry on load. */ the_ins.opcode[1] |= (val & 0xF); the_ins.opcode[1] |= ((val & 0x10) << (6 - 4)); break; case 'h': the_ins.opcode[1] |= ((val != 1) << 10); break; + case 'F': + the_ins.opcode[0] |= ((val & 0x3) << 9); + break; + case 'f': + the_ins.opcode[0] |= ((val & 0x3) << 0); + break; + case 'G': /* EMAC accumulator in a EMAC load instruction. */ + the_ins.opcode[0] |= ((~val & 0x1) << 7); + the_ins.opcode[1] |= ((val & 0x2) << (4 - 1)); + break; + case 'H': /* EMAC accumulator in a EMAC non-load instruction. */ + the_ins.opcode[0] |= ((val & 0x1) << 7); + the_ins.opcode[1] |= ((val & 0x2) << (4 - 1)); + break; + case 'I': + the_ins.opcode[1] |= ((val & 0x3) << 9); + break; + case ']': + the_ins.opcode[0] |= (val & 0x1) <<10; + break; case 'c': default: as_fatal (_("failed sanity check.")); } -} /* install_operand() */ +} static void -install_gen_operand (mode, val) - int mode; - int val; +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. */ + the_ins.opcode[0] |= (val & 0x3f); + the_ins.opcode[1] |= (((val & 0x100) >> 8) << 5); + break; case 's': the_ins.opcode[0] |= val; break; @@ -3204,21 +3512,17 @@ install_gen_operand (mode, val) case 'p': the_ins.opcode[0] |= val; break; - /* more stuff goes here */ + /* more stuff goes here. */ default: as_fatal (_("failed sanity check.")); } -} /* install_gen_operand() */ +} -/* - * verify that we have some number of paren pairs, do m68k_ip_op(), and - * then deal with the bitfield hack. - */ +/* Verify that we have some number of paren pairs, do m68k_ip_op(), and + then deal with the bitfield hack. */ static char * -crack_operand (str, opP) - register char *str; - register struct m68k_op *opP; +crack_operand (char *str, struct m68k_op *opP) { register int parens; register int c; @@ -3239,7 +3543,7 @@ crack_operand (str, opP) else if (*str == ')') { if (!parens) - { /* ERROR */ + { /* ERROR. */ opP->error = _("Extra )"); return str; } @@ -3250,7 +3554,7 @@ crack_operand (str, opP) inquote = ! inquote; } if (!*str && parens) - { /* ERROR */ + { /* ERROR. */ opP->error = _("Missing )"); return str; } @@ -3263,7 +3567,7 @@ crack_operand (str, opP) } *str = c; if (c == '}') - c = *++str; /* JF bitfield hack */ + c = *++str; /* JF bitfield hack. */ if (c) { c = *++str; @@ -3288,9 +3592,7 @@ crack_operand (str, opP) */ static void -insert_reg (regname, regnum) - const char *regname; - int regnum; +insert_reg (const char *regname, int regnum) { char buf[100]; int i; @@ -3377,56 +3679,89 @@ static const struct init_entry init_table[] = { "cc", CCR }, { "acc", ACC }, + { "acc0", ACC }, + { "acc1", ACC1 }, + { "acc2", ACC2 }, + { "acc3", ACC3 }, + { "accext01", ACCEXT01 }, + { "accext23", ACCEXT23 }, { "macsr", MACSR }, { "mask", MASK }, - /* control registers */ - { "sfc", SFC }, /* Source Function Code */ + /* Control registers. */ + { "sfc", SFC }, /* Source Function Code. */ { "sfcr", SFC }, - { "dfc", DFC }, /* Destination Function Code */ + { "dfc", DFC }, /* Destination Function Code. */ { "dfcr", DFC }, - { "cacr", CACR }, /* Cache Control Register */ - { "caar", CAAR }, /* Cache Address Register */ + { "cacr", CACR }, /* Cache Control Register. */ + { "caar", CAAR }, /* Cache Address Register. */ - { "usp", USP }, /* User Stack Pointer */ - { "vbr", VBR }, /* Vector Base Register */ - { "msp", MSP }, /* Master Stack Pointer */ - { "isp", ISP }, /* Interrupt Stack Pointer */ + { "usp", USP }, /* User Stack Pointer. */ + { "vbr", VBR }, /* Vector Base Register. */ + { "msp", MSP }, /* Master Stack Pointer. */ + { "isp", ISP }, /* Interrupt Stack Pointer. */ - { "itt0", ITT0 }, /* Instruction Transparent Translation Reg 0 */ - { "itt1", ITT1 }, /* Instruction Transparent Translation Reg 1 */ - { "dtt0", DTT0 }, /* Data Transparent Translation Register 0 */ - { "dtt1", DTT1 }, /* Data Transparent Translation Register 1 */ + { "itt0", ITT0 }, /* Instruction Transparent Translation Reg 0. */ + { "itt1", ITT1 }, /* Instruction Transparent Translation Reg 1. */ + { "dtt0", DTT0 }, /* Data Transparent Translation Register 0. */ + { "dtt1", DTT1 }, /* Data Transparent Translation Register 1. */ /* 68ec040 versions of same */ - { "iacr0", ITT0 }, /* Instruction Access Control Register 0 */ - { "iacr1", ITT1 }, /* Instruction Access Control Register 0 */ - { "dacr0", DTT0 }, /* Data Access Control Register 0 */ - { "dacr1", DTT1 }, /* Data Access Control Register 0 */ + { "iacr0", ITT0 }, /* Instruction Access Control Register 0. */ + { "iacr1", ITT1 }, /* Instruction Access Control Register 0. */ + { "dacr0", DTT0 }, /* Data Access Control Register 0. */ + { "dacr1", DTT1 }, /* Data Access Control Register 0. */ /* mcf5200 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", ITT0 }, /* Access Control Unit 0 */ - { "acr1", ITT1 }, /* Access Control Unit 1 */ - { "acr2", DTT0 }, /* Access Control Unit 2 */ - { "acr3", DTT1 }, /* Access Control Unit 3 */ + { "acr0", ACR0 }, /* Access Control Unit 0. */ + { "acr1", ACR1 }, /* Access Control Unit 1. */ + { "acr2", ACR2 }, /* Access Control Unit 2. */ + { "acr3", ACR3 }, /* Access Control Unit 3. */ - { "tc", TC }, /* MMU Translation Control Register */ + { "tc", TC }, /* MMU Translation Control Register. */ { "tcr", TC }, - { "mmusr", MMUSR }, /* MMU Status Register */ - { "srp", SRP }, /* User Root Pointer */ - { "urp", URP }, /* Supervisor Root Pointer */ + { "mmusr", MMUSR }, /* MMU Status Register. */ + { "srp", SRP }, /* User Root Pointer. */ + { "urp", URP }, /* Supervisor Root Pointer. */ { "buscr", BUSCR }, { "pcr", PCR }, - { "rombar", ROMBAR }, /* ROM Base Address Register */ - { "rambar0", RAMBAR0 }, /* ROM Base Address Register */ - { "rambar1", RAMBAR1 }, /* ROM Base Address Register */ - { "mbar", MBAR }, /* Module Base Address Register */ - /* end of control registers */ + { "rombar", ROMBAR }, /* ROM Base Address Register. */ + { "rambar0", RAMBAR0 }, /* ROM Base Address Register. */ + { "rambar1", RAMBAR1 }, /* ROM Base Address Register. */ + { "mbar", MBAR }, /* Module Base Address Register. */ + + { "mbar0", MBAR0 }, /* mcfv4e registers. */ + { "mbar1", MBAR1 }, /* mcfv4e registers. */ + { "rombar0", ROMBAR }, /* mcfv4e registers. */ + { "rombar1", ROMBAR1 }, /* mcfv4e registers. */ + { "mpcr", MPCR }, /* mcfv4e registers. */ + { "edrambar", EDRAMBAR }, /* mcfv4e registers. */ + { "secmbar", SECMBAR }, /* mcfv4e registers. */ + { "asid", TC }, /* mcfv4e registers. */ + { "mmubar", BUSCR }, /* mcfv4e registers. */ + { "pcr1u0", PCR1U0 }, /* mcfv4e registers. */ + { "pcr1l0", PCR1L0 }, /* mcfv4e registers. */ + { "pcr2u0", PCR2U0 }, /* mcfv4e registers. */ + { "pcr2l0", PCR2L0 }, /* mcfv4e registers. */ + { "pcr3u0", PCR3U0 }, /* mcfv4e registers. */ + { "pcr3l0", PCR3L0 }, /* mcfv4e registers. */ + { "pcr1u1", PCR1U1 }, /* mcfv4e registers. */ + { "pcr1l1", PCR1L1 }, /* mcfv4e registers. */ + { "pcr2u1", PCR2U1 }, /* mcfv4e registers. */ + { "pcr2l1", PCR2L1 }, /* mcfv4e registers. */ + { "pcr3u1", PCR3U1 }, /* mcfv4e registers. */ + { "pcr3l1", PCR3L1 }, /* mcfv4e registers. */ + + { "flashbar", FLASHBAR }, /* mcf528x registers. */ + { "rambar", RAMBAR }, /* mcf528x registers. */ + + { "mbar2", MBAR2 }, /* mcf5249 registers. */ + /* End of control registers. */ { "ac", AC }, { "bc", BC }, @@ -3460,10 +3795,10 @@ static const struct init_entry init_table[] = { "tt0", TT0 }, { "tt1", TT1 }, - /* 68ec030 versions of same */ + /* 68ec030 versions of same. */ { "ac0", TT0 }, { "ac1", TT1 }, - /* 68ec030 access control unit, identical to 030 MMU status reg */ + /* 68ec030 access control unit, identical to 030 MMU status reg. */ { "acusr", PSR }, /* Suppressed data and address registers. */ @@ -3525,7 +3860,7 @@ static const struct init_entry init_table[] = }; static void -init_regtable () +init_regtable (void) { int i; for (i = 0; init_table[i].name; i++) @@ -3540,8 +3875,7 @@ int m68k_aout_machtype = 2; #endif void -md_assemble (str) - char *str; +md_assemble (char *str) { const char *er; short *fromP; @@ -3586,7 +3920,7 @@ md_assemble (str) } } - memset ((char *) (&the_ins), '\0', sizeof (the_ins)); + memset (&the_ins, '\0', sizeof (the_ins)); m68k_ip (str); er = the_ins.error; if (!er) @@ -3618,7 +3952,7 @@ md_assemble (str) if (the_ins.nfrag == 0) { - /* No frag hacking involved; just put it out */ + /* No frag hacking involved; just put it out. */ toP = frag_more (2 * the_ins.numo); fromP = &the_ins.opcode[0]; for (m = the_ins.numo; m; --m) @@ -3627,7 +3961,7 @@ md_assemble (str) toP += 2; fromP++; } - /* put out symbol-dependent info */ + /* Put out symbol-dependent info. */ for (m = 0; m < the_ins.nrel; m++) { switch (the_ins.reloc[m].wid) @@ -3668,7 +4002,7 @@ md_assemble (str) return; } - /* There's some frag hacking */ + /* There's some frag hacking. */ { /* Calculate the max frag size. */ int wid; @@ -3764,13 +4098,37 @@ md_assemble (str) } } +/* Comparison function used by qsort to rank the opcode entries by name. */ + +static int +m68k_compare_opcode (const void * v1, const void * v2) +{ + struct m68k_opcode * op1, * op2; + int ret; + + op1 = *(struct m68k_opcode **) v1; + op2 = *(struct m68k_opcode **) v2; + + /* Compare the two names. If different, return the comparison. + If the same, return the order they are in the opcode table. */ + ret = strcmp (op1->name, op2->name); + if (ret) + return ret; + if (op1 < op2) + return -1; + return 0; +} + void -md_begin () +md_begin (void) { - /* - * md_begin -- set up hash tables with 68000 instructions. - * similar to what the vax assembler does. ---phr - */ + const struct m68k_opcode *ins; + struct m68k_incant *hack, *slak; + const char *retval = 0; /* Empty string, or error msg text. */ + int i; + + /* Set up hash tables with 68000 instructions. + similar to what the vax assembler does. */ /* RMS claims the thing to do is take the m68k-opcode.h table, and make a copy of it at runtime, adding in the information we want but isn't there. I think it'd be better to have an awk script hack the table @@ -3778,11 +4136,6 @@ md_begin () my lord ghod hath spoken, so we do it this way. Excuse the ugly var names. */ - const struct m68k_opcode *ins; - struct m68k_incant *hack, *slak; - const char *retval = 0; /* empty string, or error msg text */ - int i; - if (flag_mri) { flag_reg_prefix_optional = 1; @@ -3791,6 +4144,20 @@ md_begin () m68k_rel32 = 0; } + /* 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 * sizeof (* m68k_sorted_opcodes)); + + for (i = m68k_numopcodes; i--;) + m68k_sorted_opcodes[i] = m68k_opcodes + i; + + qsort (m68k_sorted_opcodes, m68k_numopcodes, + sizeof (m68k_sorted_opcodes[0]), m68k_compare_opcode); + op_hash = hash_new (); obstack_begin (&robyn, 4000); @@ -3799,19 +4166,20 @@ md_begin () hack = slak = (struct m68k_incant *) obstack_alloc (&robyn, sizeof (struct m68k_incant)); do { - ins = &m68k_opcodes[i]; - /* We *could* ignore insns that don't match our arch here - but just leaving them out of the hash. */ + ins = m68k_sorted_opcodes[i]; + + /* We *could* ignore insns that don't match our + arch here by just leaving them out of the hash. */ 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 */ + /* This is kludgey. */ slak->m_codenum = ((ins->match) & 0xffffL) ? 2 : 1; if (i + 1 != m68k_numopcodes - && !strcmp (ins->name, m68k_opcodes[i + 1].name)) + && !strcmp (ins->name, m68k_sorted_opcodes[i + 1]->name)) { - slak->m_next = (struct m68k_incant *) obstack_alloc (&robyn, sizeof (struct m68k_incant)); + slak->m_next = obstack_alloc (&robyn, sizeof (struct m68k_incant)); i++; } else @@ -3830,6 +4198,7 @@ md_begin () const char *name = m68k_opcode_aliases[i].primary; const char *alias = m68k_opcode_aliases[i].alias; PTR val = hash_find (op_hash, name); + if (!val) as_fatal (_("Internal Error: Can't find %s in hash table"), name); retval = hash_insert (op_hash, alias, val); @@ -3868,6 +4237,7 @@ md_begin () const char *name = mri_aliases[i].primary; const char *alias = mri_aliases[i].alias; PTR val = hash_find (op_hash, name); + if (!val) as_fatal (_("Internal Error: Can't find %s in hash table"), name); retval = hash_jam (op_hash, alias, val); @@ -3881,6 +4251,7 @@ md_begin () notend_table[i] = 0; alt_notend_table[i] = 0; } + notend_table[','] = 1; notend_table['{'] = 1; notend_table['}'] = 1; @@ -3897,18 +4268,15 @@ md_begin () #endif /* We need to put '(' in alt_notend_table to handle - cas2 %d0:%d2,%d3:%d4,(%a0):(%a1) - */ + cas2 %d0:%d2,%d3:%d4,(%a0):(%a1) */ alt_notend_table['('] = 1; /* We need to put '@' in alt_notend_table to handle - cas2 %d0:%d2,%d3:%d4,@(%d0):@(%d1) - */ + cas2 %d0:%d2,%d3:%d4,@(%d0):@(%d1) */ alt_notend_table['@'] = 1; /* We need to put digits in alt_notend_table to handle - bfextu %d0{24:1},%d0 - */ + bfextu %d0{24:1},%d0 */ alt_notend_table['0'] = 1; alt_notend_table['1'] = 1; alt_notend_table['2'] = 1; @@ -3922,13 +4290,13 @@ md_begin () #ifndef MIT_SYNTAX_ONLY /* Insert pseudo ops, these have to go into the opcode table since - gas expects pseudo ops to start with a dot */ + gas expects pseudo ops to start with a dot. */ { int n = 0; + while (mote_pseudo_table[n].poc_name) { - hack = (struct m68k_incant *) - obstack_alloc (&robyn, sizeof (struct m68k_incant)); + hack = obstack_alloc (&robyn, sizeof (struct m68k_incant)); hash_insert (op_hash, mote_pseudo_table[n].poc_name, (char *) hack); hack->m_operands = 0; @@ -3948,11 +4316,17 @@ md_begin () } static void -select_control_regs () +select_control_regs (void) { /* Note which set of "movec" control registers is available. */ - switch (cpu_of_arch (current_architecture)) + switch (current_chip) { + case 0: + if (verbose) + as_warn (_("architecture not yet selected: defaulting to 68020")); + control_regs = m68020_control_regs; + break; + case m68000: control_regs = m68000_control_regs; break; @@ -3978,13 +4352,24 @@ select_control_regs () case mcf5407: control_regs = mcf_control_regs; break; + case mcf5249: + control_regs = mcf5249_control_regs; + break; + case mcf528x: + case mcf521x: + control_regs = mcf528x_control_regs; + break; + case mcf5470: + case mcf5480: + control_regs = mcfv4e_control_regs; + break; default: abort (); } } void -m68k_init_after_args () +m68k_init_after_args (void) { if (cpu_of_arch (current_architecture) == 0) { @@ -4009,9 +4394,7 @@ m68k_init_after_args () if (current_architecture & m68851) { if (current_architecture & m68040) - { - as_warn (_("68040 and 68851 specified; mmu instructions may assemble incorrectly")); - } + as_warn (_("68040 and 68851 specified; mmu instructions may assemble incorrectly")); } /* What other incompatibilities could we check for? */ @@ -4020,17 +4403,16 @@ m68k_init_after_args () && (cpu_of_arch (current_architecture) /* Can CPU32 have a 68881 coprocessor?? */ & (m68020 | m68030 | cpu32))) - { - current_architecture |= m68881; - } + current_architecture |= m68881; + if (!no_68851 && (cpu_of_arch (current_architecture) & m68020up) != 0 && (cpu_of_arch (current_architecture) & m68040up) == 0) - { - current_architecture |= m68851; - } + current_architecture |= m68851; + if (no_68881 && (current_architecture & m68881)) as_bad (_("options for 68881 and no-68881 both given")); + if (no_68851 && (current_architecture & m68851)) as_bad (_("options for 68851 and no-68851 both given")); @@ -4057,8 +4439,7 @@ m68k_init_after_args () /* This is called when a label is defined. */ void -m68k_frob_label (sym) - symbolS *sym; +m68k_frob_label (symbolS *sym) { struct label_line *n; @@ -4074,7 +4455,7 @@ m68k_frob_label (sym) /* This is called when a value that is not an instruction is emitted. */ void -m68k_flush_pending_output () +m68k_flush_pending_output (void) { current_label = NULL; } @@ -4084,8 +4465,7 @@ m68k_flush_pending_output () odd location. */ void -m68k_frob_symbol (sym) - symbolS *sym; +m68k_frob_symbol (symbolS *sym) { if (S_GET_SEGMENT (sym) == reg_section && (int) S_GET_VALUE (sym) < 0) @@ -4115,8 +4495,7 @@ m68k_frob_symbol (sym) pseudo-op. */ void -m68k_mri_mode_change (on) - int on; +m68k_mri_mode_change (int on) { if (on) { @@ -4150,7 +4529,7 @@ m68k_mri_mode_change (on) } } -/* Equal to MAX_PRECISION in atof-ieee.c */ +/* Equal to MAX_PRECISION in atof-ieee.c. */ #define MAX_LITTLENUMS 6 /* Turn a string in input_line_pointer into a floating point constant @@ -4159,10 +4538,7 @@ m68k_mri_mode_change (on) returned, or NULL on OK. */ char * -md_atof (type, litP, sizeP) - char type; - char *litP; - int *sizeP; +md_atof (int type, char *litP, int *sizeP) { int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; @@ -4213,19 +4589,13 @@ md_atof (type, litP, sizeP) } void -md_number_to_chars (buf, val, n) - char *buf; - valueT val; - int n; +md_number_to_chars (char *buf, valueT val, int n) { number_to_chars_bigendian (buf, val, n); } void -md_apply_fix3 (fixP, valP, seg) - fixS *fixP; - valueT *valP; - segT seg ATTRIBUTE_UNUSED; +md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) { offsetT val = *valP; addressT upper_limit; @@ -4235,7 +4605,7 @@ md_apply_fix3 (fixP, valP, seg) to generate the code we want. */ char *buf = fixP->fx_frag->fr_literal; buf += fixP->fx_where; - /* end ibm compiler workaround */ + /* End ibm compiler workaround. */ val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000; @@ -4246,7 +4616,7 @@ md_apply_fix3 (fixP, valP, seg) if (fixP->fx_addsy) { memset (buf, 0, fixP->fx_size); - fixP->fx_addnumber = val; /* Remember value for emit_reloc */ + fixP->fx_addnumber = val; /* Remember value for emit_reloc. */ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT && !S_IS_DEFINED (fixP->fx_addsy) @@ -4283,7 +4653,7 @@ md_apply_fix3 (fixP, valP, seg) *buf++ = (val >> 8); *buf++ = val; upper_limit = 0x7fffffff; - lower_limit = - (offsetT) 0x7fffffff - 1; /* avoid constant overflow */ + lower_limit = - (offsetT) 0x7fffffff - 1; /* Avoid constant overflow. */ break; default: BAD_CASE (fixP->fx_size); @@ -4330,8 +4700,7 @@ md_apply_fix3 (fixP, valP, seg) MAGIC here. .. */ static void -md_convert_frag_1 (fragP) - register fragS *fragP; +md_convert_frag_1 (fragS *fragP) { long disp; fixS *fixP; @@ -4344,7 +4713,7 @@ md_convert_frag_1 (fragP) want. */ register char *buffer_address = fragP->fr_literal; buffer_address += fragP->fr_fix; - /* end ibm compiler workaround */ + /* End ibm compiler workaround. */ /* The displacement of the address, from current location. */ disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0; @@ -4382,16 +4751,20 @@ md_convert_frag_1 (fragP) 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")); fragP->fr_opcode[0] = 0x4E; - fragP->fr_opcode[1] = (char) 0xB9; /* JSR with ABSL LONG operand */ + 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); 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")); fragP->fr_opcode[0] = 0x4E; - fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG operand */ + 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); fragP->fr_fix += 4; @@ -4404,18 +4777,20 @@ md_convert_frag_1 (fragP) } break; case TAB (BRABSJCOND, LONG): - /* Only Bcc 68000 instructions can come here. */ - /* Change bcc into b!cc/jmp absl long. */ + if (flag_keep_pcrel) + as_fatal (_("Tried to convert PC relative conditional branch to absolute jump")); - fragP->fr_opcode[0] ^= 0x01; /* invert bcc */ - fragP->fr_opcode[1] = 0x6;/* branch offset = 6 */ + /* Only Bcc 68000 instructions can come here + Change bcc into b!cc/jmp absl long. */ + fragP->fr_opcode[0] ^= 0x01; /* Invert bcc. */ + fragP->fr_opcode[1] = 0x06; /* Branch offset = 6. */ /* JF: these used to be fr_opcode[2,3], but they may be in a - different frag, in which case refering to them is a no-no. + different frag, in which case referring to them is a no-no. Only fr_opcode[0,1] are guaranteed to work. */ *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */ *buffer_address++ = (char) 0xf9; - fragP->fr_fix += 2; /* account for jmp instruction */ + 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); fragP->fr_fix += 4; @@ -4427,7 +4802,7 @@ md_convert_frag_1 (fragP) fragP->fr_fix += 2; break; case TAB (FBRANCH, LONG): - fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */ + 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); fragP->fr_fix += 4; @@ -4439,35 +4814,39 @@ md_convert_frag_1 (fragP) fragP->fr_fix += 2; break; case TAB (DBCCLBR, LONG): - /* only DBcc instructions can come here */ - /* Change dbcc into dbcc/bral. */ + /* 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")); - /* JF: these used to be fr_opcode[2-7], but that's wrong */ - *buffer_address++ = 0x00; /* branch offset = 4 */ + *buffer_address++ = 0x00; /* Branch offset = 4. */ *buffer_address++ = 0x04; - *buffer_address++ = 0x60; /* put in bra pc+6 */ + *buffer_address++ = 0x60; /* Put in bra pc+6. */ *buffer_address++ = 0x06; *buffer_address++ = 0x60; /* Put in bral (0x60ff). */ *buffer_address++ = (char) 0xff; - fragP->fr_fix += 6; /* account for bra/jmp instructions */ + 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); fragP->fr_fix += 4; break; case TAB (DBCCABSJ, LONG): - /* only DBcc instructions can come here */ - /* Change dbcc into dbcc/jmp. */ + /* Only DBcc instructions can come here. + 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")); - /* JF: these used to be fr_opcode[2-7], but that's wrong */ - *buffer_address++ = 0x00; /* branch offset = 4 */ + *buffer_address++ = 0x00; /* Branch offset = 4. */ *buffer_address++ = 0x04; - *buffer_address++ = 0x60; /* put in bra pc+6 */ + *buffer_address++ = 0x60; /* Put in bra pc + 6. */ *buffer_address++ = 0x06; - *buffer_address++ = 0x4e; /* Put in jmp long (0x4ef9). */ + *buffer_address++ = 0x4e; /* Put in jmp long (0x4ef9). */ *buffer_address++ = (char) 0xf9; - fragP->fr_fix += 6; /* account for bra/jmp instructions */ + 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); fragP->fr_fix += 4; @@ -4521,8 +4900,10 @@ md_convert_frag_1 (fragP) 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")); /* The thing to do here is force it to ABSOLUTE LONG, since - ABSTOPCREL is really trying to shorten an ABSOLUTE address anyway */ + ABSTOPCREL is really trying to shorten an ABSOLUTE address anyway. */ if ((fragP->fr_opcode[1] & 0x3F) != 0x3A) abort (); fragP->fr_opcode[1] &= ~0x3F; @@ -4537,10 +4918,9 @@ md_convert_frag_1 (fragP) #ifndef BFD_ASSEMBLER void -md_convert_frag (headers, sec, fragP) - object_headers *headers ATTRIBUTE_UNUSED; - segT sec ATTRIBUTE_UNUSED; - fragS *fragP; +md_convert_frag (object_headers *headers ATTRIBUTE_UNUSED, + segT sec ATTRIBUTE_UNUSED, + fragS *fragP) { md_convert_frag_1 (fragP); } @@ -4548,10 +4928,9 @@ md_convert_frag (headers, sec, fragP) #else void -md_convert_frag (abfd, sec, fragP) - bfd *abfd ATTRIBUTE_UNUSED; - segT sec ATTRIBUTE_UNUSED; - fragS *fragP; +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, + segT sec ATTRIBUTE_UNUSED, + fragS *fragP) { md_convert_frag_1 (fragP); } @@ -4561,9 +4940,7 @@ md_convert_frag (abfd, sec, fragP) the frag list to be relaxed */ int -md_estimate_size_before_relax (fragP, segment) - register fragS *fragP; - segT segment; +md_estimate_size_before_relax (fragS *fragP, segT segment) { /* Handle SZ_UNDEF first, it can be changed to BYTE or SHORT. */ switch (fragP->fr_subtype) @@ -4692,7 +5069,7 @@ md_estimate_size_before_relax (fragP, segment) /* 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 */ + 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 @@ -4701,42 +5078,39 @@ md_estimate_size_before_relax (fragP, segment) format. */ #ifdef comment void -md_ri_to_chars (the_bytes, ri) - char *the_bytes; - struct reloc_info_generic *ri; +md_ri_to_chars (char *the_bytes, struct reloc_info_generic *ri) { - /* this is easy */ + /* This is easy. */ md_number_to_chars (the_bytes, ri->r_address, 4); - /* now the fun stuff */ + /* 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)); + 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 /* comment */ +#endif #ifndef BFD_ASSEMBLER void -tc_aout_fix_to_chars (where, fixP, segment_address_in_file) - char *where; - fixS *fixP; - relax_addressT segment_address_in_file; +tc_aout_fix_to_chars (char *where, fixS *fixP, + relax_addressT segment_address_in_file) { /* * In: length of relocation (or of address) in chars: 1, 2 or 4. * Out: GNU LD relocation length code: 0, 1, or 2. */ - static CONST unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2}; + static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2}; long r_symbolnum; know (fixP->fx_addsy != NULL); md_number_to_chars (where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, - 4); + (fixP->fx_frag->fr_address + + fixP->fx_where - segment_address_in_file), 4); r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) ? S_GET_TYPE (fixP->fx_addsy) @@ -4745,23 +5119,22 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file) where[4] = (r_symbolnum >> 16) & 0x0ff; where[5] = (r_symbolnum >> 8) & 0x0ff; where[6] = r_symbolnum & 0x0ff; - where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) | - (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10)); + where[7] = (((fixP->fx_pcrel << 7) & 0x80) + | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) + | ((!S_IS_DEFINED (fixP->fx_addsy) << 4) & 0x10)); } #endif #endif /* OBJ_AOUT or OBJ_BOUT */ #ifndef WORKING_DOT_WORD -CONST int md_short_jump_size = 4; -CONST int md_long_jump_size = 6; +const int md_short_jump_size = 4; +const int md_long_jump_size = 6; void -md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - addressT from_addr, to_addr; - fragS *frag ATTRIBUTE_UNUSED; - symbolS *to_symbol ATTRIBUTE_UNUSED; +md_create_short_jump (char *ptr, addressT from_addr, addressT to_addr, + fragS *frag ATTRIBUTE_UNUSED, + symbolS *to_symbol ATTRIBUTE_UNUSED) { valueT offset; @@ -4772,16 +5145,15 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) } void -md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) - char *ptr; - addressT from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; +md_create_long_jump (char *ptr, addressT from_addr, addressT to_addr, + fragS *frag, symbolS *to_symbol) { valueT offset; - if (!HAVE_LONG_BRANCH(current_architecture)) + if (!HAVE_LONG_BRANCH (current_architecture)) { + if (flag_keep_pcrel) + as_fatal (_("Tried to convert PC relative branch to absolute jump")); offset = to_addr - S_GET_VALUE (to_symbol); md_number_to_chars (ptr, (valueT) 0x4EF9, 2); md_number_to_chars (ptr + 2, (valueT) offset, 4); @@ -4802,26 +5174,23 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) aren't OK are an error (what a shock, no?) 0: Everything is OK - 10: Absolute 1:8 only - 20: Absolute 0:7 only - 30: absolute 0:15 only - 40: Absolute 0:31 only - 50: absolute 0:127 only + 10: Absolute 1:8 only + 20: Absolute 0:7 only + 30: absolute 0:15 only + 40: Absolute 0:31 only + 50: absolute 0:127 only 55: absolute -64:63 only - 60: absolute -128:127 only - 70: absolute 0:4095 only - 80: No bignums - - */ + 60: absolute -128:127 only + 70: absolute 0:4095 only + 80: absolute -1, 1:7 only + 90: No bignums. */ static int -get_num (exp, ok) - struct m68k_exp *exp; - int ok; +get_num (struct m68k_exp *exp, int ok) { if (exp->exp.X_op == O_absent) { - /* Do the same thing the VAX asm does */ + /* Do the same thing the VAX asm does. */ op (exp) = O_constant; adds (exp) = 0; subs (exp) = 0; @@ -4875,24 +5244,33 @@ get_num (exp, ok) offs (exp) = 0; } break; + case 80: + if (offs (exp) < -1 + || offs (exp) > 7 + || offs (exp) == 0) + { + as_warn (_("expression out of range: defaulting to 1")); + offs (exp) = 1; + } + break; default: break; } } else if (exp->exp.X_op == O_big) { - if (offs (exp) <= 0 /* flonum */ - && (ok == 80 /* no bignums */ - || (ok > 10 /* small-int ranges including 0 ok */ + if (offs (exp) <= 0 /* flonum. */ + && (ok == 90 /* no bignums */ + || (ok > 10 /* Small-int ranges including 0 ok. */ /* If we have a flonum zero, a zero integer should do as well (e.g., in moveq). */ && generic_floating_point_number.exponent == 0 && generic_floating_point_number.low[0] == 0))) { - /* HACK! Turn it into a long */ + /* HACK! Turn it into a long. */ LITTLENUM_TYPE words[6]; - gen_to_words (words, 2, 8L); /* These numbers are magic! */ + gen_to_words (words, 2, 8L); /* These numbers are magic! */ op (exp) = O_constant; adds (exp) = 0; subs (exp) = 0; @@ -4910,7 +5288,7 @@ get_num (exp, ok) } else { - if (ok >= 10 && ok <= 70) + if (ok >= 10 && ok <= 80) { op (exp) = O_constant; adds (exp) = 0; @@ -4945,24 +5323,21 @@ get_num (exp, ok) /* These are the back-ends for the various machine dependent pseudo-ops. */ static void -s_data1 (ignore) - int ignore ATTRIBUTE_UNUSED; +s_data1 (int ignore ATTRIBUTE_UNUSED) { subseg_set (data_section, 1); demand_empty_rest_of_line (); } static void -s_data2 (ignore) - int ignore ATTRIBUTE_UNUSED; +s_data2 (int ignore ATTRIBUTE_UNUSED) { subseg_set (data_section, 2); demand_empty_rest_of_line (); } static void -s_bss (ignore) - int ignore ATTRIBUTE_UNUSED; +s_bss (int ignore ATTRIBUTE_UNUSED) { /* We don't support putting frags in the BSS segment, we fake it by marking in_bss, then looking at s_skip for clues. */ @@ -4972,8 +5347,7 @@ s_bss (ignore) } static void -s_even (ignore) - int ignore ATTRIBUTE_UNUSED; +s_even (int ignore ATTRIBUTE_UNUSED) { register int temp; register long temp_fill; @@ -4987,8 +5361,7 @@ s_even (ignore) } static void -s_proc (ignore) - int ignore ATTRIBUTE_UNUSED; +s_proc (int ignore ATTRIBUTE_UNUSED) { demand_empty_rest_of_line (); } @@ -5000,8 +5373,7 @@ s_proc (ignore) alignment is needed. */ int -m68k_conditional_pseudoop (pop) - pseudo_typeS *pop; +m68k_conditional_pseudoop (pseudo_typeS *pop) { return (pop->poc_handler == s_mri_if || pop->poc_handler == s_mri_else); @@ -5010,7 +5382,7 @@ m68k_conditional_pseudoop (pop) /* Handle an MRI style chip specification. */ static void -mri_chip () +mri_chip (void) { char *s; char c; @@ -5039,6 +5411,7 @@ mri_chip () else current_architecture &= m68881 | m68851; current_architecture |= archs[i].arch; + current_chip = archs[i].chip; while (*input_line_pointer == '/') { @@ -5063,8 +5436,7 @@ mri_chip () /* The MRI CHIP pseudo-op. */ static void -s_chip (ignore) - int ignore ATTRIBUTE_UNUSED; +s_chip (int ignore ATTRIBUTE_UNUSED) { char *stop = NULL; char stopc; @@ -5080,8 +5452,7 @@ s_chip (ignore) /* The MRI FOPT pseudo-op. */ static void -s_fopt (ignore) - int ignore ATTRIBUTE_UNUSED; +s_fopt (int ignore ATTRIBUTE_UNUSED) { SKIP_WHITESPACE (); @@ -5116,7 +5487,7 @@ struct opt_action /* If this is not NULL, just call this function. The first argument is the ARG field of this structure, the second argument is whether the option was negated. */ - void (*pfn) PARAMS ((int arg, int on)); + void (*pfn) (int arg, int on); /* If this is not NULL, and the PFN field is NULL, set the variable this points to. Set it to the ARG field if the option was not @@ -5134,11 +5505,11 @@ struct opt_action /* The table used to handle the MRI OPT pseudo-op. */ -static void skip_to_comma PARAMS ((int, int)); -static void opt_nest PARAMS ((int, int)); -static void opt_chip PARAMS ((int, int)); -static void opt_list PARAMS ((int, int)); -static void opt_list_symbols PARAMS ((int, int)); +static void skip_to_comma (int, int); +static void opt_nest (int, int); +static void opt_chip (int, int); +static void opt_list (int, int); +static void opt_list_symbols (int, int); static const struct opt_action opt_table[] = { @@ -5190,8 +5561,7 @@ static const struct opt_action opt_table[] = /* The MRI OPT pseudo-op. */ static void -s_opt (ignore) - int ignore ATTRIBUTE_UNUSED; +s_opt (int ignore ATTRIBUTE_UNUSED) { do { @@ -5255,12 +5625,10 @@ s_opt (ignore) } /* Skip ahead to a comma. This is used for OPT options which we do - not suppor tand which take arguments. */ + not support and which take arguments. */ static void -skip_to_comma (arg, on) - int arg ATTRIBUTE_UNUSED; - int on ATTRIBUTE_UNUSED; +skip_to_comma (int arg ATTRIBUTE_UNUSED, int on ATTRIBUTE_UNUSED) { while (*input_line_pointer != ',' && ! is_end_of_line[(unsigned char) *input_line_pointer]) @@ -5270,9 +5638,7 @@ skip_to_comma (arg, on) /* Handle the OPT NEST=depth option. */ static void -opt_nest (arg, on) - int arg ATTRIBUTE_UNUSED; - int on ATTRIBUTE_UNUSED; +opt_nest (int arg ATTRIBUTE_UNUSED, int on ATTRIBUTE_UNUSED) { if (*input_line_pointer != '=') { @@ -5287,9 +5653,7 @@ opt_nest (arg, on) /* Handle the OPT P=chip option. */ static void -opt_chip (arg, on) - int arg ATTRIBUTE_UNUSED; - int on ATTRIBUTE_UNUSED; +opt_chip (int arg ATTRIBUTE_UNUSED, int on ATTRIBUTE_UNUSED) { if (*input_line_pointer != '=') { @@ -5304,9 +5668,7 @@ opt_chip (arg, on) /* Handle the OPT S option. */ static void -opt_list (arg, on) - int arg ATTRIBUTE_UNUSED; - int on; +opt_list (int arg ATTRIBUTE_UNUSED, int on) { listing_list (on); } @@ -5314,21 +5676,18 @@ opt_list (arg, on) /* Handle the OPT T option. */ static void -opt_list_symbols (arg, on) - int arg ATTRIBUTE_UNUSED; - int on; +opt_list_symbols (int arg ATTRIBUTE_UNUSED, int on) { if (on) listing |= LISTING_SYMBOLS; else - listing &=~ LISTING_SYMBOLS; + listing &= ~LISTING_SYMBOLS; } /* Handle the MRI REG pseudo-op. */ static void -s_reg (ignore) - int ignore ATTRIBUTE_UNUSED; +s_reg (int ignore ATTRIBUTE_UNUSED) { char *s; int c; @@ -5417,6 +5776,7 @@ struct save_opts int keep_locals; int short_refs; int architecture; + int chip; int quick; int rel32; int listing; @@ -5431,8 +5791,7 @@ static struct save_opts *save_stack; /* The MRI SAVE pseudo-op. */ static void -s_save (ignore) - int ignore ATTRIBUTE_UNUSED; +s_save (int ignore ATTRIBUTE_UNUSED) { struct save_opts *s; @@ -5442,6 +5801,7 @@ s_save (ignore) s->keep_locals = flag_keep_locals; s->short_refs = flag_short_refs; s->architecture = current_architecture; + s->chip = current_chip; s->quick = m68k_quick; s->rel32 = m68k_rel32; s->listing = listing; @@ -5456,8 +5816,7 @@ s_save (ignore) /* The MRI RESTORE pseudo-op. */ static void -s_restore (ignore) - int ignore ATTRIBUTE_UNUSED; +s_restore (int ignore ATTRIBUTE_UNUSED) { struct save_opts *s; @@ -5476,6 +5835,7 @@ s_restore (ignore) flag_keep_locals = s->keep_locals; flag_short_refs = s->short_refs; current_architecture = s->architecture; + current_chip = s->chip; m68k_quick = s->quick; m68k_rel32 = s->rel32; listing = s->listing; @@ -5534,29 +5894,10 @@ static struct mri_control_info *mri_control_stack; static int mri_control_index; -/* Some function prototypes. */ - -static void mri_assemble PARAMS ((char *)); -static char *mri_control_label PARAMS ((void)); -static struct mri_control_info *push_mri_control - PARAMS ((enum mri_control_type)); -static void pop_mri_control PARAMS ((void)); -static int parse_mri_condition PARAMS ((int *)); -static int parse_mri_control_operand - PARAMS ((int *, char **, char **, char **, char **)); -static int swap_mri_condition PARAMS ((int)); -static int reverse_mri_condition PARAMS ((int)); -static void build_mri_control_operand - PARAMS ((int, int, char *, char *, char *, char *, const char *, - const char *, int)); -static void parse_mri_control_expression - PARAMS ((char *, int, const char *, const char *, int)); - /* Assemble an instruction for an MRI structured control directive. */ static void -mri_assemble (str) - char *str; +mri_assemble (char *str) { char *s; @@ -5570,7 +5911,7 @@ mri_assemble (str) /* Generate a new MRI label structured control directive label name. */ static char * -mri_control_label () +mri_control_label (void) { char *n; @@ -5583,8 +5924,7 @@ mri_control_label () /* Create a new MRI structured control directive. */ static struct mri_control_info * -push_mri_control (type) - enum mri_control_type type; +push_mri_control (enum mri_control_type type) { struct mri_control_info *n; @@ -5608,7 +5948,7 @@ push_mri_control (type) /* Pop off the stack of MRI structured control directives. */ static void -pop_mri_control () +pop_mri_control (void) { struct mri_control_info *n; @@ -5624,8 +5964,7 @@ pop_mri_control () /* Recognize a condition code in an MRI structured control expression. */ static int -parse_mri_condition (pcc) - int *pcc; +parse_mri_condition (int *pcc) { char c1, c2; @@ -5655,12 +5994,8 @@ parse_mri_condition (pcc) /* Parse a single operand in an MRI structured control expression. */ static int -parse_mri_control_operand (pcc, leftstart, leftstop, rightstart, rightstop) - int *pcc; - char **leftstart; - char **leftstop; - char **rightstart; - char **rightstop; +parse_mri_control_operand (int *pcc, char **leftstart, char **leftstop, + char **rightstart, char **rightstop) { char *s; @@ -5706,14 +6041,14 @@ parse_mri_control_operand (pcc, leftstart, leftstop, rightstart, rightstop) /* We must make sure we don't misinterpret AND/OR at the end of labels! if d0 #FOOAND and d1 #BAROR then ^^^ ^^ */ - if ( ( s == input_line_pointer - || *(s-1) == ' ' - || *(s-1) == '\t') - && ( ( strncasecmp (s, "AND", 3) == 0 - && (s[3] == '.' || ! is_part_of_name (s[3]))) - || ( strncasecmp (s, "OR", 2) == 0 - && (s[2] == '.' || ! is_part_of_name (s[2]))))) - break; + if ((s == input_line_pointer + || *(s-1) == ' ' + || *(s-1) == '\t') + && ((strncasecmp (s, "AND", 3) == 0 + && (s[3] == '.' || ! is_part_of_name (s[3]))) + || (strncasecmp (s, "OR", 2) == 0 + && (s[2] == '.' || ! is_part_of_name (s[2]))))) + break; } *rightstart = input_line_pointer; @@ -5733,17 +6068,16 @@ parse_mri_control_operand (pcc, leftstart, leftstop, rightstart, rightstop) it generates the same result when the operands are swapped. */ static int -swap_mri_condition (cc) - int cc; +swap_mri_condition (int cc) { switch (cc) { case MCC ('h', 'i'): return MCC ('c', 's'); case MCC ('l', 's'): return MCC ('c', 'c'); - /* is an alias for */ + /* is an alias for . */ case MCC ('h', 's'): case MCC ('c', 'c'): return MCC ('l', 's'); - /* is an alias for */ + /* is an alias for . */ case MCC ('l', 'o'): case MCC ('c', 's'): return MCC ('h', 'i'); case MCC ('p', 'l'): return MCC ('m', 'i'); @@ -5752,7 +6086,7 @@ swap_mri_condition (cc) case MCC ('l', 't'): return MCC ('g', 't'); 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 */ + /* 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 ('v', 'c'): @@ -5768,8 +6102,7 @@ swap_mri_condition (cc) /* Reverse the sense of a condition. */ static int -reverse_mri_condition (cc) - int cc; +reverse_mri_condition (int cc) { switch (cc) { @@ -5803,17 +6136,10 @@ reverse_mri_condition (cc) use for the branch. */ static void -build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart, - rightstop, truelab, falselab, extent) - int qual; - int cc; - char *leftstart; - char *leftstop; - char *rightstart; - char *rightstop; - const char *truelab; - const char *falselab; - int extent; +build_mri_control_operand (int qual, int cc, char *leftstart, char *leftstop, + char *rightstart, char *rightstop, + const char *truelab, const char *falselab, + int extent) { char *buf; char *s; @@ -5846,27 +6172,29 @@ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart, { char *temp; - /* Correct conditional handling: - if #1 d0 then ;means if (1 < d0) - ... - endi + /* Correct conditional handling: + if #1 d0 then ;means if (1 < d0) + ... + endi - should assemble to: + should assemble to: - cmp #1,d0 if we do *not* swap the operands - bgt true we need the swapped condition! - ble false - true: - ... - false: - */ + cmp #1,d0 if we do *not* swap the operands + bgt true we need the swapped condition! + ble false + true: + ... + false: + */ temp = leftstart; leftstart = rightstart; rightstart = temp; temp = leftstop; leftstop = rightstop; rightstop = temp; - } else { + } + else + { cc = swap_mri_condition (cc); } } @@ -5920,12 +6248,8 @@ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart, expression. EXTENT is the size to use for the branch. */ static void -parse_mri_control_expression (stop, qual, truelab, falselab, extent) - char *stop; - int qual; - const char *truelab; - const char *falselab; - int extent; +parse_mri_control_expression (char *stop, int qual, const char *truelab, + const char *falselab, int extent) { int c; int cc; @@ -6030,8 +6354,7 @@ parse_mri_control_expression (stop, qual, truelab, falselab, extent) on its operands. */ static void -s_mri_if (qual) - int qual; +s_mri_if (int qual) { char *s; int c; @@ -6044,13 +6367,13 @@ s_mri_if (qual) or at first column of a line (I think this can't actually happen here?) This is important when assembling: if d0 12(a0,d0*2) then - if d0 #CONST*20 then */ - while ( ! ( is_end_of_line[(unsigned char) *s] - || ( flag_mri - && *s == '*' - && ( s == input_line_pointer - || *(s-1) == ' ' - || *(s-1) == '\t')))) + if d0 #CONST*20 then. */ + while (! (is_end_of_line[(unsigned char) *s] + || (flag_mri + && *s == '*' + && (s == input_line_pointer + || *(s-1) == ' ' + || *(s-1) == '\t')))) ++s; --s; while (s > input_line_pointer && (*s == ' ' || *s == '\t')) @@ -6115,8 +6438,7 @@ s_mri_if (qual) it is a conditional else. */ static void -s_mri_else (qual) - int qual; +s_mri_else (int qual) { int c; char *buf; @@ -6175,8 +6497,7 @@ s_mri_else (qual) /* Handle the MRI ENDI pseudo-op. */ static void -s_mri_endi (ignore) - int ignore ATTRIBUTE_UNUSED; +s_mri_endi (int ignore ATTRIBUTE_UNUSED) { if (mri_control_stack == NULL || mri_control_stack->type != mri_if) @@ -6207,8 +6528,7 @@ s_mri_endi (ignore) /* Handle the MRI BREAK pseudo-op. */ static void -s_mri_break (extent) - int extent; +s_mri_break (int extent) { struct mri_control_info *n; char *buf; @@ -6246,8 +6566,7 @@ s_mri_break (extent) /* Handle the MRI NEXT pseudo-op. */ static void -s_mri_next (extent) - int extent; +s_mri_next (int extent) { struct mri_control_info *n; char *buf; @@ -6285,8 +6604,7 @@ s_mri_next (extent) /* Handle the MRI FOR pseudo-op. */ static void -s_mri_for (qual) - int qual; +s_mri_for (int qual) { const char *varstart, *varstop; const char *initstart, *initstop; @@ -6439,12 +6757,11 @@ s_mri_for (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)); - /* move init,var */ + /* Move init,var. */ s = buf; *s++ = 'm'; *s++ = 'o'; @@ -6463,7 +6780,7 @@ s_mri_for (qual) colon (n->top); - /* cmp end,var */ + /* cmp end,var. */ s = buf; *s++ = 'c'; *s++ = 'm'; @@ -6479,7 +6796,7 @@ s_mri_for (qual) *s = '\0'; mri_assemble (buf); - /* bcc bottom */ + /* bcc bottom. */ ex[0] = TOLOWER (extent); ex[1] = '\0'; if (up) @@ -6518,8 +6835,7 @@ s_mri_for (qual) /* Handle the MRI ENDF pseudo-op. */ static void -s_mri_endf (ignore) - int ignore ATTRIBUTE_UNUSED; +s_mri_endf (int ignore ATTRIBUTE_UNUSED) { if (mri_control_stack == NULL || mri_control_stack->type != mri_for) @@ -6554,8 +6870,7 @@ s_mri_endf (ignore) /* Handle the MRI REPEAT pseudo-op. */ static void -s_mri_repeat (ignore) - int ignore ATTRIBUTE_UNUSED; +s_mri_repeat (int ignore ATTRIBUTE_UNUSED) { struct mri_control_info *n; @@ -6572,8 +6887,7 @@ s_mri_repeat (ignore) /* Handle the MRI UNTIL pseudo-op. */ static void -s_mri_until (qual) - int qual; +s_mri_until (int qual) { char *s; @@ -6611,8 +6925,7 @@ s_mri_until (qual) /* Handle the MRI WHILE pseudo-op. */ static void -s_mri_while (qual) - int qual; +s_mri_while (int qual) { char *s; @@ -6623,13 +6936,13 @@ s_mri_while (qual) or at first column of a line (I think this can't actually happen here?) This is important when assembling: while d0 12(a0,d0*2) do - while d0 #CONST*20 do */ - while ( ! ( is_end_of_line[(unsigned char) *s] - || ( flag_mri - && *s == '*' - && ( s == input_line_pointer - || *(s-1) == ' ' - || *(s-1) == '\t')))) + while d0 #CONST*20 do. */ + while (! (is_end_of_line[(unsigned char) *s] + || (flag_mri + && *s == '*' + && (s == input_line_pointer + || *(s-1) == ' ' + || *(s-1) == '\t')))) s++; --s; while (*s == ' ' || *s == '\t') @@ -6668,8 +6981,7 @@ s_mri_while (qual) /* Handle the MRI ENDW pseudo-op. */ static void -s_mri_endw (ignore) - int ignore ATTRIBUTE_UNUSED; +s_mri_endw (int ignore ATTRIBUTE_UNUSED) { char *buf; @@ -6699,36 +7011,33 @@ s_mri_endw (ignore) demand_empty_rest_of_line (); } -/* - * md_parse_option - * Invocation line includes a switch not recognized by the base assembler. - * See if it's a processor-specific option. These are: - * - * -[A]m[c]68000, -[A]m[c]68008, -[A]m[c]68010, -[A]m[c]68020, -[A]m[c]68030, -[A]m[c]68040 - * -[A]m[c]68881, -[A]m[c]68882, -[A]m[c]68851 - * Select the architecture. Instructions or features not - * supported by the selected architecture cause fatal - * errors. More than one may be specified. The default is - * -m68020 -m68851 -m68881. Note that -m68008 is a synonym - * for -m68000, and -m68882 is a synonym for -m68881. - * -[A]m[c]no-68851, -[A]m[c]no-68881 - * Don't accept 688?1 instructions. (The "c" is kind of silly, - * so don't use or document it, but that's the way the parsing - * works). - * - * -pic Indicates PIC. - * -k Indicates PIC. (Sun 3 only.) - * --pcrel Never turn PC-relative branches into absolute jumps. - * - * --bitwise-or - * Permit `|' to be used in expressions. - * - */ +/* md_parse_option + Invocation line includes a switch not recognized by the base assembler. + See if it's a processor-specific option. These are: + + -[A]m[c]68000, -[A]m[c]68008, -[A]m[c]68010, -[A]m[c]68020, -[A]m[c]68030, -[A]m[c]68040 + -[A]m[c]68881, -[A]m[c]68882, -[A]m[c]68851 + Select the architecture. Instructions or features not + supported by the selected architecture cause fatal + errors. More than one may be specified. The default is + -m68020 -m68851 -m68881. Note that -m68008 is a synonym + for -m68000, and -m68882 is a synonym for -m68881. + -[A]m[c]no-68851, -[A]m[c]no-68881 + Don't accept 688?1 instructions. (The "c" is kind of silly, + so don't use or document it, but that's the way the parsing + works). + + -pic Indicates PIC. + -k Indicates PIC. (Sun 3 only.) + --pcrel + Never turn PC-relative branches into absolute jumps. + --bitwise-or + Permit `|' to be used in expressions. */ #ifdef OBJ_ELF -CONST char *md_shortopts = "lSA:m:kQ:V"; +const char *md_shortopts = "lSA:m:kQ:V"; #else -CONST char *md_shortopts = "lSA:m:k"; +const char *md_shortopts = "lSA:m:k"; #endif struct option md_longopts[] = { @@ -6754,14 +7063,12 @@ struct option md_longopts[] = { size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (c, arg) - int c; - char *arg; +md_parse_option (int c, char *arg) { switch (c) { case 'l': /* -l means keep external to 2 bit offset - rather than 16 bit one */ + rather than 16 bit one. */ flag_short_refs = 1; break; @@ -6777,8 +7084,8 @@ md_parse_option (c, arg) case 'A': if (*arg == 'm') - arg++; - /* intentional fall-through */ + arg++; + /* Intentional fall-through. */ case 'm': if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') @@ -6798,18 +7105,15 @@ md_parse_option (c, arg) if (!strcmp (arg, archs[i].name)) break; if (i == n_archs) - { - unknown: - as_bad (_("unrecognized option `%s'"), oarg); - return 0; - } + return 0; + arch = archs[i].arch; if (arch == m68881) no_68881 = 1; else if (arch == m68851) no_68851 = 1; else - goto unknown; + return 0; } else { @@ -6822,11 +7126,13 @@ md_parse_option (c, arg) if (!strcmp (arg, archs[i].name)) { unsigned long arch = archs[i].arch; + if (cpu_of_arch (arch)) /* It's a cpu spec. */ { current_architecture &= ~m68000up; current_architecture |= arch; + current_chip = archs[i].chip; } else if (arch == m68881) { @@ -6854,7 +7160,7 @@ md_parse_option (c, arg) case OPTION_PIC: case 'k': flag_want_pic = 1; - break; /* -pic, Position Independent Code */ + break; /* -pic, Position Independent Code. */ case OPTION_REGISTER_PREFIX_OPTIONAL: flag_reg_prefix_optional = 1; @@ -6912,19 +7218,44 @@ md_parse_option (c, arg) } void -md_show_usage (stream) - FILE *stream; +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') + default_cpu++; + for (i = 0; i < n_archs; i++) + { + if (strcasecmp (default_cpu, archs[i].name) == 0) + { + default_arch = archs[i].arch; + for (i = 0; i < n_archs; i++) + { + if (archs[i].arch == default_arch + && !archs[i].alias) + { + default_cpu = archs[i].name; + break; + } + } + } + } + fprintf (stream, _("\ 680X0 options:\n\ -l use 1 word for refs to undefined symbols [default 2]\n\ -m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060 |\n\ -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -m68360 | -mcpu32 |\n\ --m5200 | -m5202 | -m5204 | -m5206 | -m5206e | -m5307 | -m5407\n\ - specify variant of 680X0 architecture [default 68020]\n\ +-m5200 | -m5202 | -m5204 | -m5206 | -m5206e | -m521x | -m5249 |\n\ +-m528x | -m5307 | -m5407 | -m547x | -m548x | -mcfv4 | -mcfv4e\n\ + specify variant of 680X0 architecture [default %s]\n\ -m68881 | -m68882 | -mno-68881 | -mno-68882\n\ target has/lacks floating-point coprocessor\n\ - [default yes for 68020, 68030, and cpu32]\n")); + [default yes for 68020, 68030, and cpu32]\n"), + default_cpu); fprintf (stream, _("\ -m68851 | -mno-68851\n\ target has/lacks memory-management unit coprocessor\n\ @@ -6945,9 +7276,9 @@ md_show_usage (stream) #ifdef TEST2 /* TEST2: Test md_assemble() */ -/* Warning, this routine probably doesn't work anymore */ - -main () +/* Warning, this routine probably doesn't work anymore. */ +int +main (void) { struct m68k_it the_ins; char buf[120]; @@ -6988,21 +7319,27 @@ main () printf ("op%d Error %s in %s\n", n, the_ins.operands[n].error, buf); continue; } - printf ("mode %d, reg %d, ", the_ins.operands[n].mode, the_ins.operands[n].reg); + printf ("mode %d, reg %d, ", the_ins.operands[n].mode, + the_ins.operands[n].reg); if (the_ins.operands[n].b_const) - printf ("Constant: '%.*s', ", 1 + the_ins.operands[n].e_const - the_ins.operands[n].b_const, the_ins.operands[n].b_const); - printf ("ireg %d, isiz %d, imul %d, ", the_ins.operands[n].ireg, the_ins.operands[n].isiz, the_ins.operands[n].imul); + printf ("Constant: '%.*s', ", + 1 + the_ins.operands[n].e_const - the_ins.operands[n].b_const, + the_ins.operands[n].b_const); + printf ("ireg %d, isiz %d, imul %d, ", the_ins.operands[n].ireg, + the_ins.operands[n].isiz, the_ins.operands[n].imul); if (the_ins.operands[n].b_iadd) - printf ("Iadd: '%.*s',", 1 + the_ins.operands[n].e_iadd - the_ins.operands[n].b_iadd, the_ins.operands[n].b_iadd); - (void) putchar ('\n'); + printf ("Iadd: '%.*s',", + 1 + the_ins.operands[n].e_iadd - the_ins.operands[n].b_iadd, + the_ins.operands[n].b_iadd); + putchar ('\n'); } } m68k_ip_end (); return 0; } -is_label (str) - char *str; +int +is_label (char *str) { while (*str == ' ') str++; @@ -7035,17 +7372,14 @@ is_label (str) /* We have no need to default values of symbols. */ symbolS * -md_undefined_symbol (name) - char *name ATTRIBUTE_UNUSED; +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) { return 0; } /* Round up a section size to the appropriate boundary. */ valueT -md_section_align (segment, size) - segT segment ATTRIBUTE_UNUSED; - valueT size; +md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) { #ifdef OBJ_AOUT #ifdef BFD_ASSEMBLER @@ -7069,8 +7403,7 @@ md_section_align (segment, size) word. The difference between the addresses of the offset and the first extension word is stored in fx_pcrel_adjust. */ long -md_pcrel_from (fixP) - fixS *fixP; +md_pcrel_from (fixS *fixP) { int adjust; @@ -7086,14 +7419,12 @@ md_pcrel_from (fixP) #ifdef OBJ_COFF void -tc_coff_symbol_emit_hook (ignore) - symbolS *ignore ATTRIBUTE_UNUSED; +tc_coff_symbol_emit_hook (symbolS *ignore ATTRIBUTE_UNUSED) { } int -tc_coff_sizemachdep (frag) - fragS *frag; +tc_coff_sizemachdep (fragS *frag) { switch (frag->fr_subtype & 0x3) { @@ -7111,11 +7442,47 @@ tc_coff_sizemachdep (frag) #endif #endif + #ifdef OBJ_ELF -void m68k_elf_final_processing() +void +m68k_elf_final_processing (void) { - /* Set file-specific flags if this is a cpu32 processor */ - if (cpu_of_arch (current_architecture) & cpu32) - elf_elfheader (stdoutput)->e_flags |= EF_CPU32; + /* Set file-specific flags if this is a cpu32 processor. */ + if (cpu_of_arch (current_architecture) & cpu32) + elf_elfheader (stdoutput)->e_flags |= EF_CPU32; + else if ((cpu_of_arch (current_architecture) & m68000up) + && !(cpu_of_arch (current_architecture) & m68020up)) + elf_elfheader (stdoutput)->e_flags |= EF_M68000; } #endif + +int +tc_m68k_regname_to_dw2regnum (const char *regname) +{ + unsigned int regnum; + static const char *const regnames[] = + { + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", + "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", + "pc" + }; + + for (regnum = 0; regnum < ARRAY_SIZE (regnames); regnum++) + if (strcmp (regname, regnames[regnum]) == 0) + return regnum; + + return -1; +} + +void +tc_m68k_frame_initial_instructions (void) +{ + static int sp_regno = -1; + + if (sp_regno < 0) + sp_regno = tc_m68k_regname_to_dw2regnum ("sp"); + + cfi_add_CFA_def_cfa (sp_regno, -DWARF2_CIE_DATA_ALIGNMENT); + cfi_add_CFA_offset (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT); +}