X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68hc11.c;h=11af780bfe081e15df2a7f1cfd7589e17970df5a;hb=5496abe1c5c31aa6648e8fdb15e4122025bcabfe;hp=d8e8545edfbb91021fd245b6c63a582e14a9c3ec;hpb=e629c13fd65b99b3385122adb22ee2f384550637;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index d8e8545edf..11af780bfe 100644 --- a/gas/config/tc-m68hc11.c +++ b/gas/config/tc-m68hc11.c @@ -1,12 +1,13 @@ /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@worldnet.fr) + Copyright (C) 1999-2020 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@nerim.fr) + XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk) This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -16,15 +17,15 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + the Free Software Foundation, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ -#include -#include #include "as.h" +#include "safe-ctype.h" #include "subsegs.h" #include "opcode/m68hc11.h" #include "dwarf2dbg.h" +#include "elf/m68hc11.h" const char comment_chars[] = ";!"; const char line_comment_chars[] = "#*"; @@ -36,8 +37,9 @@ const char FLT_CHARS[] = "dD"; #define STATE_CONDITIONAL_BRANCH (1) #define STATE_PC_RELATIVE (2) #define STATE_INDEXED_OFFSET (3) -#define STATE_XBCC_BRANCH (4) -#define STATE_CONDITIONAL_BRANCH_6812 (5) +#define STATE_INDEXED_PCREL (4) +#define STATE_XBCC_BRANCH (5) +#define STATE_CONDITIONAL_BRANCH_6812 (6) #define STATE_BYTE (0) #define STATE_BITS5 (0) @@ -49,6 +51,8 @@ const char FLT_CHARS[] = "dD"; /* This macro has no side-effects. */ #define ENCODE_RELAX(what,length) (((what) << 2) + (length)) +#define RELAX_STATE(s) ((s) >> 2) +#define RELAX_LENGTH(s) ((s) & 3) #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF)) @@ -61,7 +65,8 @@ const char FLT_CHARS[] = "dD"; 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. */ -relax_typeS md_relax_table[] = { +relax_typeS md_relax_table[] = +{ {1, 1, 0, 0}, /* First entries aren't used. */ {1, 1, 0, 0}, /* For no good reason except. */ {1, 1, 0, 0}, /* that the VAX doesn't either. */ @@ -87,6 +92,14 @@ relax_typeS md_relax_table[] = { {0, 0, 2, 0}, {1, 1, 0, 0}, + /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits. + For the 9-bit case, there will be a -1 correction to take into + account the new byte that's why the range is -255..256. */ + {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)}, + {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)}, + {0, 0, 2, 0}, + {1, 1, 0, 0}, + /* Relax for dbeq/ibeq/tbeq r,: These insns are translated into db!cc +3 jmp L. */ {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)}, @@ -104,7 +117,8 @@ relax_typeS md_relax_table[] = { }; /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */ -typedef enum register_id { +typedef enum register_id +{ REG_NONE = -1, REG_A = 0, REG_B = 1, @@ -113,17 +127,30 @@ typedef enum register_id { REG_X = 5, REG_Y = 6, REG_SP = 7, - REG_PC = 8 + REG_PC = 8, + REG_R0 = 0, + REG_R1 = 1, + REG_R2 = 2, + REG_R3 = 3, + REG_R4 = 4, + REG_R5 = 5, + REG_R6 = 6, + REG_R7 = 7, + REG_SP_XG = 8, + REG_PC_XG = 9, + REG_CCR_XG = 10 } register_id; -typedef struct operand { +typedef struct operand +{ expressionS exp; register_id reg1; register_id reg2; int mode; } operand; -struct m68hc11_opcode_def { +struct m68hc11_opcode_def +{ long format; int min_operands; int max_operands; @@ -135,34 +162,75 @@ struct m68hc11_opcode_def { static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0; static int m68hc11_nb_opcode_defs = 0; -typedef struct alias { +typedef struct alias +{ const char *name; const char *alias; } alias; -static alias alias_opcodes[] = { +static alias alias_opcodes[] = +{ {"cpd", "cmpd"}, {"cpx", "cmpx"}, {"cpy", "cmpy"}, {0, 0} }; +struct m9s12xg_opcode_def +{ + long format; + int min_operands; + int max_operands; + int nb_modes; + int used; + struct m9s12xg_opcode *opcode; +}; + /* Local functions. */ -static register_id reg_name_search PARAMS ((char *)); -static register_id register_name PARAMS ((void)); -static int check_range PARAMS ((long, int)); -static void print_opcode_list PARAMS ((void)); -static void get_default_target PARAMS ((void)); -static void print_insn_format PARAMS ((char *)); -static int get_operand PARAMS ((operand *, int, long)); -static void fixup8 PARAMS ((expressionS *, int, int)); -static void fixup16 PARAMS ((expressionS *, int, int)); -static struct m68hc11_opcode *find_opcode - PARAMS ((struct m68hc11_opcode_def *, operand *, int *)); -static void build_jump_insn - PARAMS ((struct m68hc11_opcode *, operand *, int, int)); -static void build_insn - PARAMS ((struct m68hc11_opcode *, operand *, int)); +static register_id reg_name_search (char *); +static register_id register_name (void); +static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *); +static char *print_opcode_format (struct m68hc11_opcode *, int); +static char *skip_whites (char *); +static int check_range (long, int); +static void print_opcode_list (void); +static void get_default_target (void); +static void print_insn_format (char *); +static int get_operand (operand *, int, long); +static void fixup8 (expressionS *, int, int); +static void fixup16 (expressionS *, int, int); +static void fixup24 (expressionS *, int, int); +static void fixup8_xg (expressionS *, int, int); +static unsigned char convert_branch (unsigned char); +static char *m68hc11_new_insn (int); +static void build_dbranch_insn (struct m68hc11_opcode *, + operand *, int, int); +static int build_indexed_byte (operand *, int, int); +static int build_reg_mode (operand *, int); + +static struct m68hc11_opcode *find (struct m68hc11_opcode_def *, + operand *, int); +static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *, + operand *, int *); +static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int); +static void build_insn_xg (struct m68hc11_opcode *, operand *, int); +static void build_insn (struct m68hc11_opcode *, operand *, int); +static int relaxable_symbol (symbolS *); + +/* Pseudo op to indicate a relax group. */ +static void s_m68hc11_relax (int); + +/* Pseudo op to control the ELF flags. */ +static void s_m68hc11_mode (int); + +/* Process directives specified via pseudo ops. */ +static void s_m68hc11_parse_pseudo_instruction (int); + +/* Mark the symbols with STO_M68HC12_FAR to indicate the functions + are using 'rtc' for returning. It is necessary to use 'call' + to invoke them. This is also used by the debugger to correctly + find the stack frame. */ +static void s_m68hc11_mark_symbol (int); /* Controls whether relative branches can be turned into long branches. When the relative offset is too large, the insn are changed: @@ -173,8 +241,8 @@ static void build_insn dbcc -> db!cc +3 jmp L - Setting the flag forbidds this. */ -static short flag_fixed_branchs = 0; + Setting the flag forbids this. */ +static short flag_fixed_branches = 0; /* Force to use long jumps (absolute) instead of relative branches. */ static short flag_force_long_jumps = 0; @@ -198,7 +266,7 @@ static short flag_print_opcodes = 0; static struct hash_control *m68hc11_hash; /* Current cpu (either cpu6811 or cpu6812). This is determined automagically - by 'get_default_target' by looking at default BFD vector. This is overriden + by 'get_default_target' by looking at default BFD vector. This is overridden with the -m option. */ static int current_architecture = 0; @@ -211,6 +279,9 @@ static int num_opcodes; /* The opcodes sorted by name and filtered by current cpu. */ static struct m68hc11_opcode *m68hc11_sorted_opcodes; +/* ELF flags to set in the output file header. */ +static int elf_flags = E_M68HC11_F64; + /* 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. */ @@ -220,33 +291,49 @@ static struct m68hc11_opcode *m68hc11_sorted_opcodes; pseudo-op name without dot function to call to execute this pseudo-op Integer arg to pass to the function. */ -const pseudo_typeS md_pseudo_table[] = { +const pseudo_typeS md_pseudo_table[] = +{ /* The following pseudo-ops are supported for MRI compatibility. */ {"fcb", cons, 1}, {"fdb", cons, 2}, - {"fcc", stringer, 1}, + {"fqb", cons, 4}, + {"fcc", stringer, 8 + 1}, {"rmb", s_space, 0}, - /* Dwarf2 support for Gcc. */ - {"file", dwarf2_directive_file, 0}, - {"loc", dwarf2_directive_loc, 0}, - /* Motorola ALIS. */ {"xrefb", s_ignore, 0}, /* Same as xref */ + /* Gcc driven relaxation. */ + {"relax", s_m68hc11_relax, 0}, + + /* .mode instruction (ala SH). */ + {"mode", s_m68hc11_mode, 0}, + + /* .far instruction. */ + {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR}, + + /* .interrupt instruction. */ + {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT}, + + /* .nobankwarning instruction. */ + {"nobankwarning", s_m68hc11_parse_pseudo_instruction, E_M68HC11_NO_BANK_WARNING}, + {0, 0, 0} }; /* Options and initialization. */ -CONST char *md_shortopts = "Sm:"; +const char *md_shortopts = "Sm:"; -struct option md_longopts[] = { +struct option md_longopts[] = +{ #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE) - {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, + {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, + {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelled version kept for backwards compatibility. */ -#define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1) - {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHS}, +#define OPTION_SHORT_BRANCHES (OPTION_MD_BASE + 1) + {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES}, + {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelled version kept for backwards compatibility. */ #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2) {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE}, @@ -260,6 +347,21 @@ struct option md_longopts[] = { #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5) {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE}, +#define OPTION_MSHORT (OPTION_MD_BASE + 6) + {"mshort", no_argument, NULL, OPTION_MSHORT}, + +#define OPTION_MLONG (OPTION_MD_BASE + 7) + {"mlong", no_argument, NULL, OPTION_MLONG}, + +#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8) + {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE}, + +#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9) + {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE}, + +#define OPTION_XGATE_RAMOFFSET (OPTION_MD_BASE + 10) + {"xgate-ramoffset", no_argument, NULL, OPTION_XGATE_RAMOFFSET}, + {NULL, no_argument, NULL, 0} }; size_t md_longopts_size = sizeof (md_longopts); @@ -268,7 +370,7 @@ size_t md_longopts_size = sizeof (md_longopts); options and on the -m68hc11/-m68hc12 option. If no option is specified, we must get the default. */ const char * -m68hc11_arch_format () +m68hc11_arch_format (void) { get_default_target (); if (current_architecture & cpu6811) @@ -278,7 +380,7 @@ m68hc11_arch_format () } enum bfd_architecture -m68hc11_arch () +m68hc11_arch (void) { get_default_target (); if (current_architecture & cpu6811) @@ -288,36 +390,46 @@ m68hc11_arch () } int -m68hc11_mach () +m68hc11_mach (void) { return 0; } /* Listing header selected according to cpu. */ const char * -m68hc11_listing_header () +m68hc11_listing_header (void) { if (current_architecture & cpu6811) return "M68HC11 GAS "; + else if (current_architecture & cpuxgate) + return "XGATE GAS "; + else if (current_architecture & cpu9s12x) + return "S12X GAS "; else return "M68HC12 GAS "; } void -md_show_usage (stream) - FILE *stream; +md_show_usage (FILE *stream) { get_default_target (); fprintf (stream, _("\ -Motorola 68HC11/68HC12 options:\n\ - -m68hc11 | -m68hc12 specify the processor [default %s]\n\ - --force-long-branchs always turn relative branchs into absolute ones\n\ - -S,--short-branchs do not turn relative branchs into absolute ones\n\ +Motorola 68HC11/68HC12/68HCS12 options:\n\ + -m68hc11 | -m68hc12 |\n\ + -m68hcs12 | -mm9s12x |\n\ + -mm9s12xg specify the processor [default %s]\n\ + -mshort use 16-bit int ABI (default)\n\ + -mlong use 32-bit int ABI\n\ + -mshort-double use 32-bit double ABI\n\ + -mlong-double use 64-bit double ABI (default)\n\ + --force-long-branches always turn relative branches into absolute ones\n\ + -S,--short-branches do not turn relative branches into absolute ones\n\ when the offset is out of range\n\ --strict-direct-mode do not turn the direct mode into extended mode\n\ when the instruction does not support direct mode\n\ --print-insn-syntax print the syntax of instruction in case of error\n\ --print-opcodes print the list of instructions with syntax\n\ + --xgate-ramoffset offset ram addresses by 0xc000\n\ --generate-example generate an example of each instruction\n\ (used for testing)\n"), default_cpu); @@ -325,7 +437,7 @@ Motorola 68HC11/68HC12 options:\n\ /* Try to identify the default target based on the BFD library. */ static void -get_default_target () +get_default_target (void) { const bfd_target *target; bfd abfd; @@ -355,8 +467,7 @@ get_default_target () } void -m68hc11_print_statistics (file) - FILE *file; +m68hc11_print_statistics (FILE *file) { int i; struct m68hc11_opcode_def *opc; @@ -379,17 +490,15 @@ m68hc11_print_statistics (file) } int -md_parse_option (c, arg) - int c; - char *arg; +md_parse_option (int c, const char *arg) { get_default_target (); switch (c) { /* -S means keep external to 2 bit offset rather than 16 bit one. */ - case OPTION_SHORT_BRANCHS: + case OPTION_SHORT_BRANCHES: case 'S': - flag_fixed_branchs = 1; + flag_fixed_branches = 1; break; case OPTION_FORCE_LONG_BRANCH: @@ -412,11 +521,42 @@ md_parse_option (c, arg) flag_print_opcodes = 2; break; + case OPTION_MSHORT: + elf_flags &= ~E_M68HC11_I32; + break; + + case OPTION_MLONG: + elf_flags |= E_M68HC11_I32; + break; + + case OPTION_MSHORT_DOUBLE: + elf_flags &= ~E_M68HC11_F64; + break; + + case OPTION_MLONG_DOUBLE: + elf_flags |= E_M68HC11_F64; + break; + + case OPTION_XGATE_RAMOFFSET: + elf_flags |= E_M68HC11_XGATE_RAMOFFSET; + break; + case 'm': - if (strcasecmp (arg, "68hc11") == 0) + if ((strcasecmp (arg, "68hc11") == 0) + || (strcasecmp (arg, "m68hc11") == 0)) current_architecture = cpu6811; - else if (strcasecmp (arg, "68hc12") == 0) + else if ((strcasecmp (arg, "68hc12") == 0) + || (strcasecmp (arg, "m68hc12") == 0)) current_architecture = cpu6812; + else if ((strcasecmp (arg, "68hcs12") == 0) + || (strcasecmp (arg, "m68hcs12") == 0)) + current_architecture = cpu6812 | cpu6812s; + else if (strcasecmp (arg, "m9s12x") == 0) + current_architecture = cpu6812 | cpu6812s | cpu9s12x; + else if ((strcasecmp (arg, "m9s12xg") == 0) + || (strcasecmp (arg, "xgate") == 0)) + /* xgate for backwards compatibility */ + current_architecture = cpuxgate; else as_bad (_("Option `%s' is not recognized."), arg); break; @@ -429,97 +569,41 @@ md_parse_option (c, arg) } symbolS * -md_undefined_symbol (name) - char *name ATTRIBUTE_UNUSED; +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) { return 0; } -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - -/* Turn a string in input_line_pointer into a floating point constant - of type TYPE, and store the appropriate bytes in *LITP. The number - of LITTLENUMS emitted is stored in *SIZEP. An error message is - returned, or NULL on OK. */ -char * -md_atof (type, litP, sizeP) - char type; - char *litP; - int *sizeP; +const char * +md_atof (int type, char *litP, int *sizeP) { - int prec; - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - - switch (type) - { - case 'f': - case 'F': - case 's': - case 'S': - prec = 2; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = 4; - break; - - case 'x': - case 'X': - prec = 6; - break; - - case 'p': - case 'P': - prec = 6; - break; - - default: - *sizeP = 0; - return _("Bad call to MD_ATOF()"); - } - t = atof_ieee (input_line_pointer, type, words); - if (t) - input_line_pointer = t; - - *sizeP = prec * sizeof (LITTLENUM_TYPE); - for (wordP = words; prec--;) - { - md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } - return 0; + return ieee_md_atof (type, litP, sizeP, TRUE); } valueT -md_section_align (seg, addr) - asection *seg; - valueT addr; +md_section_align (asection *seg, valueT addr) { - int align = bfd_get_section_alignment (stdoutput, seg); - return ((addr + (1 << align) - 1) & (-1 << align)); + int align = bfd_section_alignment (seg); + return ((addr + (1 << align) - 1) & -(1 << align)); } static int -cmp_opcode (op1, op2) - struct m68hc11_opcode *op1; - struct m68hc11_opcode *op2; +cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2) { return strcmp (op1->name, op2->name); } +#define IS_CALL_SYMBOL(MODE) \ +(((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \ + == ((M6812_OP_PAGE|M6811_OP_IND16))) + /* Initialize the assembler. Create the opcode hash table (sorted on the names) with the M6811 opcode table (from opcode library). */ void -md_begin () +md_begin (void) { - char *prev_name = ""; + const char *prev_name = ""; struct m68hc11_opcode *opcodes; struct m68hc11_opcode_def *opc = 0; int i, j; @@ -529,9 +613,7 @@ md_begin () m68hc11_hash = hash_new (); /* Get a writable copy of the opcode table and sort it on the names. */ - opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes * - sizeof (struct - m68hc11_opcode)); + opcodes = XNEWVEC (struct m68hc11_opcode, m68hc11_num_opcodes); m68hc11_sorted_opcodes = opcodes; num_opcodes = 0; for (i = 0; i < m68hc11_num_opcodes; i++) @@ -557,10 +639,10 @@ md_begin () } } } - qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode); + qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), + (int (*) (const void*, const void*)) cmp_opcode); - opc = (struct m68hc11_opcode_def *) - xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def)); + opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes); m68hc11_opcode_defs = opc--; /* Insert unique names into hash table. The M6811 instruction set @@ -582,24 +664,46 @@ md_begin () opc->nb_modes = 0; opc->opcode = opcodes; opc->used = 0; - hash_insert (m68hc11_hash, opcodes->name, (char *) opc); + hash_insert (m68hc11_hash, opcodes->name, opc); } opc->nb_modes++; opc->format |= opcodes->format; /* See how many operands this opcode needs. */ expect = 0; - if (opcodes->format & M6811_OP_MASK) - expect++; - if (opcodes->format & M6811_OP_BITMASK) - expect++; - if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) - expect++; - if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)) - expect++; + if (opcodes->arch == cpuxgate) + { + if (opcodes->format & (M68XG_OP_IMM3 | M68XG_OP_R | M68XG_OP_REL9 + | M68XG_OP_REL10 )) + expect = 1; + else if (opcodes->format & (M68XG_OP_R_R | M68XG_OP_R_IMM4 + | M68XG_OP_R_IMM8 | M68XG_OP_R_IMM8)) + expect = 2; + else if (opcodes->format & (M68XG_OP_R_R_R | M68XG_OP_R_R_OFFS5 + | M68XG_OP_RD_RB_RI | M68XG_OP_RD_RB_RIp + | M68XG_OP_RD_RB_mRI)) + expect = 3; + } + else + { + if (opcodes->format & M6811_OP_MASK) + expect++; + if (opcodes->format & M6811_OP_BITMASK) + expect++; + if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) + expect++; + if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)) + expect++; + /* Special case for call instruction. */ + if ((opcodes->format & M6812_OP_PAGE) + && !(opcodes->format & M6811_OP_IND16)) + expect++; + } if (expect < opc->min_operands) opc->min_operands = expect; + if (IS_CALL_SYMBOL (opcodes->format)) + expect++; if (expect > opc->max_operands) opc->max_operands = expect; } @@ -614,7 +718,7 @@ md_begin () } void -m68hc11_init_after_args () +m68hc11_init_after_args (void) { } @@ -623,10 +727,9 @@ m68hc11_init_after_args () /* Return a string that represents the operand format for the instruction. When example is true, this generates an example of operand. This is used to give an example and also to generate a test. */ + static char * -print_opcode_format (opcode, example) - struct m68hc11_opcode *opcode; - int example; +print_opcode_format (struct m68hc11_opcode *opcode, int example) { static char buf[128]; int format = opcode->format; @@ -634,111 +737,231 @@ print_opcode_format (opcode, example) p = buf; buf[0] = 0; - if (format & M6811_OP_IMM8) - { - if (example) - sprintf (p, "#%d", rand () & 0x0FF); - else - strcpy (p, _("#")); - p = &p[strlen (p)]; - } - if (format & M6811_OP_IMM16) + if (current_architecture == cpuxgate) { - if (example) - sprintf (p, "#%d", rand () & 0x0FFFF); - else - strcpy (p, _("#")); - p = &p[strlen (p)]; + if (format & M68XG_OP_IMM3) + { + if (example) + sprintf (p, "#%d", rand () & 0x007); + else + strcpy (p, _("imm3")); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R) + { + if (example) + sprintf (p, "R%d", rand () & 0x07); + else + strcpy (p, _("RD")); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R_R) + { + if (example) + sprintf (p, "R%d,R%d", rand () & 0x07, rand () & 0x07); + else + strcpy (p, _("RD,RS")); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R_IMM4) + { + if (example) + sprintf (p, "R%d,#%d", rand () & 0x07, rand () & 0x0f); + else + strcpy (p, _("RI, #imm4")); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R_R_R) + { + if (example) + sprintf (p, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07); + else + strcpy (p, "RD,RS1,RS2"); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_REL9) + { + if (example) + sprintf (p, "%d", rand () & 0x1FF); + else + strcpy (p, ""); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_REL10) + { + if (example) + sprintf (p, "%d", rand () & 0x3FF); + else + strcpy (p, ""); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R_R_OFFS5) + { + if (example) + sprintf (p, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f); + else + strcpy (p, _("RD, (RI,#offs5)")); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_RD_RB_RI) + { + if (example) + sprintf (p, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07); + else + strcpy (p, "RD, (RB, RI)"); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_RD_RB_RIp) + { + if (example) + sprintf (p, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07); + else + strcpy (p, "RD, (RB, RI+)"); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_RD_RB_mRI) + { + if (example) + sprintf (p, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07); + else + strcpy (p, "RD, (RB, -RI)"); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R_IMM8) + { + if (example) + sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xff); + else + strcpy (p, "RD, #imm8"); + p = &p[strlen (p)]; + } + else if (format & M68XG_OP_R_IMM16) + { + if (example) + sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff); + else + strcpy (p, "RD, #imm16"); + p = &p[strlen (p)]; + } } - - if (format & M6811_OP_IX) + else { - if (example) - sprintf (p, "%d,X", rand () & 0x0FF); - else - strcpy (p, _(",X")); - p = &p[strlen (p)]; - } - if (format & M6811_OP_IY) - { - if (example) - sprintf (p, "%d,X", rand () & 0x0FF); - else - strcpy (p, _(",X")); - p = &p[strlen (p)]; - } + if (format & M6811_OP_IMM8) + { + if (example) + sprintf (p, "#%d", rand () & 0x0FF); + else + strcpy (p, _("#")); + p = &p[strlen (p)]; + } - if (format & M6812_OP_IDX) - { - if (example) - sprintf (p, "%d,X", rand () & 0x0FF); - else - strcpy (p, "n,r"); - p = &p[strlen (p)]; - } + if (format & M6811_OP_IMM16) + { + if (example) + sprintf (p, "#%d", rand () & 0x0FFFF); + else + strcpy (p, _("#")); + p = &p[strlen (p)]; + } - if (format & M6811_OP_DIRECT) - { - if (example) - sprintf (p, "*Z%d", rand () & 0x0FF); - else - strcpy (p, _("*")); - p = &p[strlen (p)]; - } + if (format & M6811_OP_IX) + { + if (example) + sprintf (p, "%d,X", rand () & 0x0FF); + else + strcpy (p, _(",X")); + p = &p[strlen (p)]; + } - if (format & M6811_OP_BITMASK) - { - if (buf[0]) - *p++ = ' '; + if (format & M6811_OP_IY) + { + if (example) + sprintf (p, "%d,X", rand () & 0x0FF); + else + strcpy (p, _(",X")); + p = &p[strlen (p)]; + } - if (example) - sprintf (p, "#$%02x", rand () & 0x0FF); - else - strcpy (p, _("#")); + if (format & M6812_OP_IDX) + { + if (example) + sprintf (p, "%d,X", rand () & 0x0FF); + else + strcpy (p, "n,r"); + p = &p[strlen (p)]; + } - p = &p[strlen (p)]; - if (format & M6811_OP_JUMP_REL) - *p++ = ' '; - } + if (format & M6812_OP_PAGE) + { + if (example) + sprintf (p, ", %d", rand () & 0x0FF); + else + strcpy (p, ", "); + p = &p[strlen (p)]; + } - if (format & M6811_OP_IND16) - { - if (example) - sprintf (p, _("symbol%d"), rand () & 0x0FF); - else - strcpy (p, _("")); + if (format & M6811_OP_DIRECT) + { + if (example) + sprintf (p, "*Z%d", rand () & 0x0FF); + else + strcpy (p, _("*")); + p = &p[strlen (p)]; + } - p = &p[strlen (p)]; - } + if (format & M6811_OP_BITMASK) + { + if (buf[0]) + *p++ = ' '; - if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) - { - if (example) + if (example) + sprintf (p, "#$%02x", rand () & 0x0FF); + else + strcpy (p, _("#")); + + p = &p[strlen (p)]; + if (format & M6811_OP_JUMP_REL) + *p++ = ' '; + } + + if (format & M6811_OP_IND16) { - if (format & M6811_OP_BITMASK) - { - sprintf (p, ".+%d", rand () & 0x7F); - } + if (example) + sprintf (p, _("symbol%d"), rand () & 0x0FF); else + strcpy (p, _("")); + + p = &p[strlen (p)]; + } + + if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) + { + if (example) { - sprintf (p, "L%d", rand () & 0x0FF); + if (format & M6811_OP_BITMASK) + { + sprintf (p, ".+%d", rand () & 0x7F); + } + else + { + sprintf (p, "L%d", rand () & 0x0FF); + } } + else + strcpy (p, _("