X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-m68hc11.c;h=5cf6f7f77b27d78a15f150d1747369c7e3a18306;hb=24cc21fe5b8a88dc1ecde9006ece10145fef1035;hp=34dbf6b41fde143bf90ab48ad97e8ed9db6b777d;hpb=2f9046641f748e9a27c97759570dcb983cbab4e9;p=binutils-gdb.git diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index 34dbf6b41fd..5cf6f7f77b2 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, 2002 Free Software Foundation, Inc. + Copyright (C) 1999-2022 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,10 +17,9 @@ 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 "as.h" #include "safe-ctype.h" #include "subsegs.h" @@ -37,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) @@ -64,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. */ @@ -90,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)}, @@ -107,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, @@ -116,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; @@ -138,61 +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 cmp_opcode PARAMS ((struct m68hc11_opcode *, - struct m68hc11_opcode *)); -static char *print_opcode_format PARAMS ((struct m68hc11_opcode *, int)); -static char *skip_whites PARAMS ((char *)); -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 void fixup24 PARAMS ((expressionS *, int, int)); -static unsigned char convert_branch PARAMS ((unsigned char)); -static char *m68hc11_new_insn PARAMS ((int)); -static void build_dbranch_insn PARAMS ((struct m68hc11_opcode *, - operand *, int, int)); -static int build_indexed_byte PARAMS ((operand *, int, int)); -static int build_reg_mode PARAMS ((operand *, int)); - -static struct m68hc11_opcode *find - PARAMS ((struct m68hc11_opcode_def *, operand *, 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 int relaxable_symbol PARAMS ((symbolS *)); +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 PARAMS((int)); +static void s_m68hc11_relax (int); /* Pseudo op to control the ELF flags. */ -static void s_m68hc11_mode PARAMS ((int)); +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 PARAMS ((int)); +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: @@ -203,8 +241,8 @@ static void s_m68hc11_mark_symbol PARAMS ((int)); 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; @@ -225,10 +263,10 @@ static short flag_print_insn_syntax = 0; static short flag_print_opcodes = 0; /* Opcode hash table. */ -static struct hash_control *m68hc11_hash; +static htab_t 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; @@ -253,17 +291,15 @@ static int elf_flags = E_M68HC11_F64; 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", (void (*) PARAMS ((int))) dwarf2_directive_file, 0}, - {"loc", dwarf2_directive_loc, 0}, - /* Motorola ALIS. */ {"xrefb", s_ignore, 0}, /* Same as xref */ @@ -279,6 +315,9 @@ const pseudo_typeS md_pseudo_table[] = { /* .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} }; @@ -286,12 +325,15 @@ const pseudo_typeS md_pseudo_table[] = { 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}, @@ -317,6 +359,9 @@ struct option md_longopts[] = { #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); @@ -325,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) @@ -335,7 +380,7 @@ m68hc11_arch_format () } enum bfd_architecture -m68hc11_arch () +m68hc11_arch (void) { get_default_target (); if (current_architecture & cpu6811) @@ -345,40 +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\ +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-branchs always turn relative branchs into absolute ones\n\ - -S,--short-branchs do not turn relative branchs into absolute ones\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); @@ -386,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; @@ -416,13 +467,12 @@ get_default_target () } void -m68hc11_print_statistics (file) - FILE *file; +m68hc11_print_statistics (FILE *file) { int i; struct m68hc11_opcode_def *opc; - hash_print_statistics (file, "opcode table", m68hc11_hash); + htab_print_statistics (file, "opcode table", m68hc11_hash); opc = m68hc11_opcode_defs; if (opc == 0 || m68hc11_nb_opcode_defs == 0) @@ -440,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: @@ -489,11 +537,26 @@ md_parse_option (c, arg) 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; @@ -506,86 +569,26 @@ 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); } @@ -598,21 +601,19 @@ cmp_opcode (op1, op2) (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; get_default_target (); - m68hc11_hash = hash_new (); + m68hc11_hash = str_htab_create (); /* 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++) @@ -638,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 @@ -663,30 +664,46 @@ md_begin () opc->nb_modes = 0; opc->opcode = opcodes; opc->used = 0; - hash_insert (m68hc11_hash, opcodes->name, (char *) opc); + str_hash_insert (m68hc11_hash, opcodes->name, opc, 0); } 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++; - /* Special case for call instruction. */ - if ((opcodes->format & M6812_OP_PAGE) - && !(opcodes->format & M6811_OP_IND16)) - 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++; + expect++; if (expect > opc->max_operands) opc->max_operands = expect; } @@ -701,7 +718,7 @@ md_begin () } void -m68hc11_init_after_args () +m68hc11_init_after_args (void) { } @@ -710,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; @@ -721,120 +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 & M6812_OP_PAGE) - { - if (example) - sprintf (p, ", %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_DIRECT) - { - if (example) - sprintf (p, "*Z%d", rand () & 0x0FF); - else - strcpy (p, _("*")); - 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_BITMASK) - { - if (buf[0]) - *p++ = ' '; + if (format & M6812_OP_IDX) + { + if (example) + sprintf (p, "%d,X", rand () & 0x0FF); + else + strcpy (p, "n,r"); + p = &p[strlen (p)]; + } - if (example) - sprintf (p, "#$%02x", rand () & 0x0FF); - else - strcpy (p, _("#")); + if (format & M6812_OP_PAGE) + { + if (example) + sprintf (p, ", %d", rand () & 0x0FF); + else + strcpy (p, ", "); + p = &p[strlen (p)]; + } - p = &p[strlen (p)]; - if (format & M6811_OP_JUMP_REL) - *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_IND16) - { - if (example) - sprintf (p, _("symbol%d"), rand () & 0x0FF); - else - strcpy (p, _("")); + if (format & M6811_OP_BITMASK) + { + if (buf[0]) + *p++ = ' '; - p = &p[strlen (p)]; - } + if (example) + sprintf (p, "#$%02x", rand () & 0x0FF); + else + strcpy (p, _("#")); - if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) - { - if (example) + 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, _("