xref: /netbsd-src/external/gpl3/gdb/dist/sim/m68hc11/gencode.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
2    Copyright 1999-2020 Free Software Foundation, Inc.
3    Written by Stephane Carrez (stcarrez@nerim.fr)
4 
5 This file is part of GDB, GAS, and the GNU binutils.
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 
26 #include "ansidecl.h"
27 #include "libiberty.h"
28 #include "opcode/m68hc11.h"
29 
30 /* Combination of CCR flags.  */
31 #define M6811_ZC_BIT	M6811_Z_BIT|M6811_C_BIT
32 #define M6811_NZ_BIT	M6811_N_BIT|M6811_Z_BIT
33 #define M6811_NZV_BIT	M6811_N_BIT|M6811_Z_BIT|M6811_V_BIT
34 #define M6811_NZC_BIT	M6811_N_BIT|M6811_Z_BIT|M6811_C_BIT
35 #define M6811_NVC_BIT	M6811_N_BIT|M6811_V_BIT|M6811_C_BIT
36 #define M6811_ZVC_BIT	M6811_Z_BIT|M6811_V_BIT|M6811_C_BIT
37 #define M6811_NZVC_BIT	M6811_ZVC_BIT|M6811_N_BIT
38 #define M6811_HNZVC_BIT M6811_NZVC_BIT|M6811_H_BIT
39 #define M6811_HNVC_BIT  M6811_NVC_BIT|M6811_H_BIT
40 #define M6811_VC_BIT    M6811_V_BIT|M6811_C_BIT
41 
42 /* Flags when the insn only changes some CCR flags.  */
43 #define CHG_NONE	0,0,0
44 #define CHG_Z		0,0,M6811_Z_BIT
45 #define CHG_C		0,0,M6811_C_BIT
46 #define CHG_ZVC		0,0,M6811_ZVC_BIT
47 #define CHG_NZC         0,0,M6811_NZC_BIT
48 #define CHG_NZV		0,0,M6811_NZV_BIT
49 #define CHG_NZVC	0,0,M6811_NZVC_BIT
50 #define CHG_HNZVC	0,0,M6811_HNZVC_BIT
51 #define CHG_ALL		0,0,0xff
52 
53 /* The insn clears and changes some flags.  */
54 #define CLR_I		0,M6811_I_BIT,0
55 #define CLR_C		0,M6811_C_BIT,0
56 #define CLR_V		0,M6811_V_BIT,0
57 #define CLR_V_CHG_ZC	0,M6811_V_BIT,M6811_ZC_BIT
58 #define CLR_V_CHG_NZ	0,M6811_V_BIT,M6811_NZ_BIT
59 #define CLR_V_CHG_ZVC	0,M6811_V_BIT,M6811_ZVC_BIT
60 #define CLR_N_CHG_ZVC	0,M6811_N_BIT,M6811_ZVC_BIT /* Used by lsr */
61 #define CLR_VC_CHG_NZ   0,M6811_VC_BIT,M6811_NZ_BIT
62 
63 /* The insn sets some flags.  */
64 #define SET_I		M6811_I_BIT,0,0
65 #define SET_C		M6811_C_BIT,0,0
66 #define SET_V		M6811_V_BIT,0,0
67 #define SET_Z_CLR_NVC	M6811_Z_BIT,M6811_NVC_BIT,0
68 #define SET_C_CLR_V_CHG_NZ M6811_C_BIT,M6811_V_BIT,M6811_NZ_BIT
69 #define SET_Z_CHG_HNVC  M6811_Z_BIT,0,M6811_HNVC_BIT
70 
71 #define _M 0xff
72 
73 static int cpu_type;
74 
75 struct m6811_opcode_pattern
76 {
77   const char *name;
78   const char *pattern;
79   const char *ccr_update;
80 };
81 
82 /*
83  *  { "test", M6811_OP_NONE, 1, 0x00, 5, _M,  CHG_NONE },
84  * Name -+					 +---- Insn CCR changes
85  * Format  ------+			   +---------- Max # cycles
86  * Size	    -----------------+	      +--------------- Min # cycles
87  *				 +-------------------- Opcode
88  */
89 struct m6811_opcode_pattern m6811_opcode_patterns[] = {
90   /* Move 8 and 16 bits.  We need two implementations: one that sets the
91      flags and one that preserve them.	*/
92   { "movtst8",	"dst8 = src8",	 "cpu_ccr_update_tst8 (cpu, dst8)" },
93   { "movtst16", "dst16 = src16", "cpu_ccr_update_tst16 (cpu, dst16)" },
94   { "mov8",	"dst8 = src8" },
95   { "mov16",	"dst16 = src16" },
96   { "lea16",	"dst16 = addr" },
97 
98   /* Conditional branches.  'addr' is the address of the branch.  */
99   { "bra", "cpu_set_pc (cpu, addr)" },
100   { "bhi",
101    "if ((cpu_get_ccr (cpu) & (M6811_C_BIT|M6811_Z_BIT)) == 0)\n@ \
102      cpu_set_pc (cpu, addr)" },
103   { "bls",
104     "if ((cpu_get_ccr (cpu) & (M6811_C_BIT|M6811_Z_BIT)))\n@ \
105      cpu_set_pc (cpu, addr)" },
106   { "bcc", "if (!cpu_get_ccr_C (cpu))\n@ cpu_set_pc (cpu, addr)" },
107   { "bcs", "if (cpu_get_ccr_C (cpu))\n@ cpu_set_pc (cpu, addr)" },
108   { "bne", "if (!cpu_get_ccr_Z (cpu))\n@ cpu_set_pc (cpu, addr)" },
109   { "beq", "if (cpu_get_ccr_Z (cpu))\n@ cpu_set_pc (cpu, addr)" },
110   { "bvc", "if (!cpu_get_ccr_V (cpu))\n@ cpu_set_pc (cpu, addr)" },
111   { "bvs", "if (cpu_get_ccr_V (cpu))\n@ cpu_set_pc (cpu, addr)" },
112   { "bpl", "if (!cpu_get_ccr_N (cpu))\n@ cpu_set_pc (cpu, addr)" },
113   { "bmi", "if (cpu_get_ccr_N (cpu))\n@ cpu_set_pc (cpu, addr)" },
114   { "bge", "if ((cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu)) == 0)\n@ cpu_set_pc (cpu, addr)" },
115   { "blt", "if ((cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu)))\n@ cpu_set_pc (cpu, addr)" },
116   { "bgt",
117     "if ((cpu_get_ccr_Z (cpu) | (cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu))) == 0)\n@ \
118      cpu_set_pc (cpu, addr)" },
119   { "ble",
120     "if ((cpu_get_ccr_Z (cpu) | (cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu))))\n@ \
121      cpu_set_pc (cpu, addr)" },
122 
123   /* brclr and brset perform a test and a conditional jump at the same
124      time.  Flags are not changed.  */
125   { "brclr8",
126     "if ((src8 & dst8) == 0)\n@	 cpu_set_pc (cpu, addr)" },
127   { "brset8",
128     "if (((~src8) & dst8) == 0)\n@  cpu_set_pc (cpu, addr)" },
129 
130 
131   { "rts11",  "addr = cpu_m68hc11_pop_uint16 (cpu); cpu_set_pc (cpu, addr); cpu_return (cpu)" },
132   { "rts12",  "addr = cpu_m68hc12_pop_uint16 (cpu); cpu_set_pc (cpu, addr); cpu_return (cpu)" },
133 
134   { "mul16", "dst16 = ((uint16) src8 & 0x0FF) * ((uint16) dst8 & 0x0FF)",
135     "cpu_set_ccr_C (cpu, src8 & 0x80)" },
136   { "neg8", "dst8 = - src8",
137     "cpu_set_ccr_C (cpu, src8 == 0); cpu_ccr_update_tst8 (cpu, dst8)" },
138   { "com8", "dst8 = ~src8",
139     "cpu_set_ccr_C (cpu, 1); cpu_ccr_update_tst8 (cpu, dst8);" },
140   { "clr8", "dst8 = 0",
141     "cpu_set_ccr (cpu, (cpu_get_ccr (cpu) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
142 M6811_I_BIT)) | M6811_Z_BIT)"},
143   { "clr16","dst16 = 0",
144     "cpu_set_ccr (cpu, (cpu_get_ccr (cpu) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
145 M6811_I_BIR)) | M6811_Z_BIT)"},
146 
147   /* 8-bits shift and rotation.	 */
148   { "lsr8",  "dst8 = src8 >> 1",
149     "cpu_set_ccr_C (cpu, src8 & 1); cpu_ccr_update_shift8 (cpu, dst8)" },
150   { "lsl8",  "dst8 = src8 << 1",
151     "cpu_set_ccr_C (cpu, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (cpu, dst8)" },
152   { "asr8",  "dst8 = (src8 >> 1) | (src8 & 0x80)",
153     "cpu_set_ccr_C (cpu, src8 & 1); cpu_ccr_update_shift8 (cpu, dst8)" },
154   { "ror8",  "dst8 = (src8 >> 1) | (cpu_get_ccr_C (cpu) << 7)",
155     "cpu_set_ccr_C (cpu, src8 & 1); cpu_ccr_update_shift8 (cpu, dst8)" },
156   { "rol8",  "dst8 = (src8 << 1) | (cpu_get_ccr_C (cpu))",
157     "cpu_set_ccr_C (cpu, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (cpu, dst8)" },
158 
159   /* 16-bits shift instructions.  */
160   { "lsl16",  "dst16 = src16 << 1",
161     "cpu_set_ccr_C (cpu, (src16&0x8000) >> 15); cpu_ccr_update_shift16 (cpu, dst16)"},
162   { "lsr16",  "dst16 = src16 >> 1",
163     "cpu_set_ccr_C (cpu, src16 & 1); cpu_ccr_update_shift16 (cpu, dst16)"},
164 
165   { "dec8", "dst8 = src8 - 1", "cpu_ccr_update_tst8 (cpu, dst8)" },
166   { "inc8", "dst8 = src8 + 1", "cpu_ccr_update_tst8 (cpu, dst8)" },
167   { "tst8", 0, "cpu_set_ccr_C (cpu, 0); cpu_ccr_update_tst8 (cpu, src8)" },
168 
169   { "sub8", "cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\
170 dst8 = dst8 - src8", 0 },
171   { "add8", "cpu_ccr_update_add8 (cpu, dst8 + src8, dst8, src8);\
172 dst8 = dst8 + src8", 0 },
173   { "sbc8", "if (cpu_get_ccr_C (cpu))\n@ \
174 {\n\
175   cpu_ccr_update_sub8 (cpu, dst8 - src8 - 1, dst8, src8);\n\
176   dst8 = dst8 - src8 - 1;\n\
177 }\n\
178 else\n\
179 {\n\
180   cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\n\
181   dst8 = dst8 - src8;\n\
182 }", 0 },
183   { "adc8", "if (cpu_get_ccr_C (cpu))\n@ \
184 {\n\
185   cpu_ccr_update_add8 (cpu, dst8 + src8 + 1, dst8, src8);\n\
186   dst8 = dst8 + src8 + 1;\n\
187 }\n\
188 else\n\
189 {\n\
190   cpu_ccr_update_add8 (cpu, dst8 + src8, dst8, src8);\n\
191   dst8 = dst8 + src8;\n\
192 }",
193     0 },
194 
195   /* 8-bits logical operations.	 */
196   { "and8", "dst8 = dst8 & src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
197   { "eor8", "dst8 = dst8 ^ src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
198   { "or8",  "dst8 = dst8 | src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
199   { "bclr8","dst8 = (~dst8) & src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
200 
201   /* 16-bits add and subtract instructions.  */
202   { "sub16", "cpu_ccr_update_sub16 (cpu, dst16 - src16, dst16, src16);\
203 dst16 = dst16 - src16", 0 },
204   { "add16", "cpu_ccr_update_add16 (cpu, dst16 + src16, dst16, src16);\
205 dst16 = dst16 + src16", 0 },
206   { "inc16", "dst16 = src16 + 1", "cpu_set_ccr_Z (cpu, dst16 == 0)" },
207   { "dec16", "dst16 = src16 - 1", "cpu_set_ccr_Z (cpu, dst16 == 0)" },
208 
209   /* Special increment/decrement for the stack pointer:
210      flags are not changed.  */
211   { "ins16", "dst16 = src16 + 1" },
212   { "des16", "dst16 = src16 - 1" },
213 
214   { "jsr_11_16", "cpu_m68hc11_push_uint16 (cpu, cpu_get_pc (cpu)); cpu_call (cpu, addr)"},
215   { "jsr_12_16", "cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu)); cpu_call (cpu, addr)"},
216 
217   /* xgdx and xgdx patterns. Flags are not changed.  */
218   { "xgdxy16", "dst16 = cpu_get_d (cpu); cpu_set_d (cpu, src16)"},
219   { "stop", "cpu_special (cpu, M6811_STOP)"},
220 
221   /* tsx, tsy, txs, tys don't affect the flags.	 Sp value is corrected
222      by +/- 1.	*/
223   { "tsxy16", "dst16 = src16 + 1;"},
224   { "txys16", "dst16 = src16 - 1;"},
225 
226   /* Add b to X or Y with an unsigned extension 8->16.	Flags not changed.  */
227   { "abxy16","dst16 = dst16 + (uint16) src8"},
228 
229   /* After 'daa', the Z flag is undefined. Mark it as changed.	*/
230   { "daa8",  "cpu_special (cpu, M6811_DAA)" },
231   { "nop",  0 },
232 
233 
234   /* Integer divide:
235      (parallel (set IX (div D IX))
236 	       (set D  (mod D IX)))  */
237   { "idiv16", "if (src16 == 0)\n{\n\
238 dst16 = 0xffff;\
239 }\nelse\n{\n\
240 cpu_set_d (cpu, dst16 % src16);\
241 dst16 = dst16 / src16;\
242 }",
243   "cpu_set_ccr_Z (cpu, dst16 == 0); cpu_set_ccr_V (cpu, 0);\
244 cpu_set_ccr_C (cpu, src16 == 0)" },
245 
246   /* Fractional divide:
247      (parallel (set IX (div (mul D 65536) IX)
248 	       (set D  (mod (mul D 65536) IX))))  */
249   { "fdiv16", "if (src16 <= dst16 )\n{\n\
250 dst16 = 0xffff;\n\
251 cpu_set_ccr_Z (cpu, 0);\n\
252 cpu_set_ccr_V (cpu, 1);\n\
253 cpu_set_ccr_C (cpu, dst16 == 0);\n\
254 }\nelse\n{\n\
255 unsigned long l = (unsigned long) (dst16) << 16;\n\
256 cpu_set_d (cpu, (uint16) (l % (unsigned long) (src16)));\n\
257 dst16 = (uint16) (l / (unsigned long) (src16));\n\
258 cpu_set_ccr_V (cpu, 0);\n\
259 cpu_set_ccr_C (cpu, 0);\n\
260 cpu_set_ccr_Z (cpu, dst16 == 0);\n\
261 }", 0 },
262 
263   /* Operations to get/set the CCR.  */
264   { "clv",  0, "cpu_set_ccr_V (cpu, 0)" },
265   { "sev",  0, "cpu_set_ccr_V (cpu, 1)" },
266   { "clc",  0, "cpu_set_ccr_C (cpu, 0)" },
267   { "sec",  0, "cpu_set_ccr_C (cpu, 1)" },
268   { "cli",  0, "cpu_set_ccr_I (cpu, 0)" },
269   { "sei",  0, "cpu_set_ccr_I (cpu, 1)" },
270 
271   /* Some special instructions are implemented by 'cpu_special'.  */
272   { "rti11",  "cpu_special (cpu, M6811_RTI)" },
273   { "rti12",  "cpu_special (cpu, M6812_RTI)" },
274   { "wai",  "cpu_special (cpu, M6811_WAI)" },
275   { "test", "cpu_special (cpu, M6811_TEST)" },
276   { "swi",  "cpu_special (cpu, M6811_SWI)" },
277   { "syscall","cpu_special (cpu, M6811_EMUL_SYSCALL)" },
278 
279   { "page2", "cpu_page2_interp (cpu)", 0 },
280   { "page3", "cpu_page3_interp (cpu)", 0 },
281   { "page4", "cpu_page4_interp (cpu)", 0 },
282 
283   /* 68HC12 special instructions.  */
284   { "bgnd",  "cpu_special (cpu, M6812_BGND)" },
285   { "call8", "cpu_special (cpu, M6812_CALL)" },
286   { "call_ind", "cpu_special (cpu, M6812_CALL_INDIRECT)" },
287   { "dbcc8", "cpu_dbcc (cpu)" },
288   { "ediv",  "cpu_special (cpu, M6812_EDIV)" },
289   { "emul",  "{ uint32 src1 = (uint32) cpu_get_d (cpu);\
290   uint32 src2 = (uint32) cpu_get_y (cpu);\
291   src1 *= src2;\
292   cpu_set_d (cpu, src1);\
293   cpu_set_y (cpu, src1 >> 16);\
294   cpu_set_ccr_Z (cpu, src1 == 0);\
295   cpu_set_ccr_C (cpu, src1 & 0x08000);\
296   cpu_set_ccr_N (cpu, src1 & 0x80000000);}" },
297   { "emuls",  "cpu_special (cpu, M6812_EMULS)" },
298   { "mem",   "cpu_special (cpu, M6812_MEM)" },
299   { "rtc",   "cpu_special (cpu, M6812_RTC)" },
300   { "emacs", "cpu_special (cpu, M6812_EMACS)" },
301   { "idivs", "cpu_special (cpu, M6812_IDIVS)" },
302   { "edivs", "cpu_special (cpu, M6812_EDIVS)" },
303   { "exg8",  "cpu_exg (cpu, src8)" },
304   { "move8", "cpu_move8 (cpu, op)" },
305   { "move16","cpu_move16 (cpu, op)" },
306 
307   { "max8",  "cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\
308               if (dst8 < src8) dst8 = src8" },
309   { "min8",  "cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\
310               if (dst8 > src8) dst8 = src8" },
311   { "max16", "cpu_ccr_update_sub16 (cpu, dst16 - src16, dst16, src16);\
312               if (dst16 < src16) dst16 = src16" },
313   { "min16", "cpu_ccr_update_sub16 (cpu, dst16 - src16, dst16, src16);\
314               if (dst16 > src16) dst16 = src16" },
315 
316   { "rev",   "cpu_special (cpu, M6812_REV);" },
317   { "revw",  "cpu_special (cpu, M6812_REVW);" },
318   { "wav",   "cpu_special (cpu, M6812_WAV);" },
319   { "tbl8",  "cpu_special (cpu, M6812_ETBL);" },
320   { "tbl16", "cpu_special (cpu, M6812_ETBL);" }
321 };
322 
323 /* Definition of an opcode of the 68HC11.  */
324 struct m6811_opcode_def
325 {
326   const char	 *name;
327   const char	 *operands;
328   const char	 *insn_pattern;
329   unsigned char	 insn_size;
330   unsigned char	 insn_code;
331   unsigned char	 insn_min_cycles;
332   unsigned char	 insn_max_cycles;
333   unsigned char	 set_flags_mask;
334   unsigned char	 clr_flags_mask;
335   unsigned char	 chg_flags_mask;
336 };
337 
338 
339 /*
340  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
341  * Name -+					 +----- Insn CCR changes
342  * Operands  ---+			  +------------ Max # cycles
343  * Pattern   -----------+	       +--------------- Min # cycles
344  * Size	     -----------------+	  +-------------------- Opcode
345  *
346  * Operands   Fetch operand		Save result
347  * -------    --------------		------------
348  * x->x	      src16 = x			x = dst16
349  * d->d	      src16 = d			d = dst16
350  * b,a->a     src8 = b dst8 = a		a = dst8
351  * sp->x      src16 = sp		x = dst16
352  * (sp)->a    src8 = pop8		a = dst8
353  * a->(sp)    src8 = a			push8 dst8
354  * (x)->(x)   src8 = (IND, X)		(IND, X) = dst8
355  * (y)->a     src8 = (IND, Y)		a = dst8
356  * ()->b      src8 = (EXT)		b = dst8
357  */
358 struct m6811_opcode_def m6811_page1_opcodes[] = {
359   { "test", 0,		0,	     1, 0x00,  5, _M,  CHG_NONE },
360   { "nop",  0,		0,	     1, 0x01,  2,  2,  CHG_NONE },
361   { "idiv", "x,d->x",	"idiv16",    1, 0x02,  3, 41,  CLR_V_CHG_ZC},
362   { "fdiv", "x,d->x",	"fdiv16",    1, 0x03,  3, 41,  CHG_ZVC},
363   { "lsrd", "d->d",	"lsr16",     1, 0x04,  3,  3,  CLR_N_CHG_ZVC },
364   { "asld", "d->d",	"lsl16",     1, 0x05,  3,  3,  CHG_NZVC },
365   { "tap",  "a->ccr",	"mov8",	     1, 0x06,  2,  2,  CHG_ALL},
366   { "tpa",  "ccr->a",	"mov8",	     1, 0x07,  2,  2,  CHG_NONE },
367   { "inx",  "x->x",	"inc16",     1, 0x08,  3,  3,  CHG_Z },
368   { "dex",  "x->x",	"dec16",     1, 0x09,  3,  3,  CHG_Z },
369   { "clv",  0,		0,	     1, 0x0a,  2,  2,  CLR_V },
370   { "sev",  0,		0,	     1, 0x0b,  2,  2,  SET_V },
371   { "clc",  0,		0,	     1, 0x0c,  2,  2,  CLR_C },
372   { "sec",  0,		0,	     1, 0x0d,  2,  2,  SET_C },
373   { "cli",  0,		0,	     1, 0x0e,  2,  2,  CLR_I },
374   { "sei",  0,		0,	     1, 0x0f,  2,  2,  SET_I },
375   { "sba",  "b,a->a",	"sub8",	     1, 0x10,  2,  2,  CHG_NZVC },
376   { "cba",  "b,a",	"sub8",	     1, 0x11,  2,  2,  CHG_NZVC },
377   { "brset","*,#,r",	"brset8",    4, 0x12,  6,  6, CHG_NONE },
378   { "brclr","*,#,r",	"brclr8",    4, 0x13,  6,  6, CHG_NONE },
379   { "bset", "*,#->*",	"or8",	     3, 0x14,  6,  6, CLR_V_CHG_NZ },
380   { "bclr", "*,#->*",	"bclr8",     3, 0x15,  6,  6, CLR_V_CHG_NZ },
381   { "tab",  "a->b",	"movtst8",   1, 0x16,  2,  2, CLR_V_CHG_NZ },
382   { "tba",  "b->a",	"movtst8",   1, 0x17,  2,  2, CLR_V_CHG_NZ },
383   { "page2", 0,		"page2",     1, 0x18,  0,  0, CHG_NONE },
384   { "page3", 0,		"page3",     1, 0x1a,  0,  0, CHG_NONE },
385 
386   /* After 'daa', the Z flag is undefined.  Mark it as changed.	 */
387   { "daa",  "",	        "daa8",	     1, 0x19,  2,  2, CHG_NZVC },
388   { "aba",  "b,a->a",	"add8",	     1, 0x1b,  2,  2, CHG_HNZVC},
389   { "bset", "(x),#->(x)","or8",	     3, 0x1c,  7,  7, CLR_V_CHG_NZ },
390   { "bclr", "(x),#->(x)","bclr8",    3, 0x1d,  7,  7, CLR_V_CHG_NZ },
391   { "brset","(x),#,r",	"brset8",    4, 0x1e,  7,  7, CHG_NONE },
392   { "brclr","(x),#,r",	"brclr8",    4, 0x1f,  7,  7, CHG_NONE },
393 
394   /* Relative branch.  All of them take 3 bytes.  Flags not changed.  */
395   { "bra",  "r",	0,	     2, 0x20,  3,  3, CHG_NONE },
396   { "brn",  "r",	"nop",	     2, 0x21,  3,  3, CHG_NONE },
397   { "bhi",  "r",	0,	     2, 0x22,  3,  3, CHG_NONE },
398   { "bls",  "r",	0,	     2, 0x23,  3,  3, CHG_NONE },
399   { "bcc",  "r",	0,	     2, 0x24,  3,  3, CHG_NONE },
400   { "bcs",  "r",	0,	     2, 0x25,  3,  3, CHG_NONE },
401   { "bne",  "r",	0,	     2, 0x26,  3,  3, CHG_NONE },
402   { "beq",  "r",	0,	     2, 0x27,  3,  3, CHG_NONE },
403   { "bvc",  "r",	0,	     2, 0x28,  3,  3, CHG_NONE },
404   { "bvs",  "r",	0,	     2, 0x29,  3,  3, CHG_NONE },
405   { "bpl",  "r",	0,	     2, 0x2a,  3,  3, CHG_NONE },
406   { "bmi",  "r",	0,	     2, 0x2b,  3,  3, CHG_NONE },
407   { "bge",  "r",	0,	     2, 0x2c,  3,  3, CHG_NONE },
408   { "blt",  "r",	0,	     2, 0x2d,  3,  3, CHG_NONE },
409   { "bgt",  "r",	0,	     2, 0x2e,  3,  3, CHG_NONE },
410   { "ble",  "r",	0,	     2, 0x2f,  3,  3, CHG_NONE },
411 
412   { "tsx",  "sp->x",	"tsxy16",    1, 0x30,  3,  3, CHG_NONE },
413   { "ins",  "sp->sp",	"ins16",     1, 0x31,  3,  3, CHG_NONE },
414   { "pula", "(sp)->a",	"mov8",	     1, 0x32,  4,  4, CHG_NONE },
415   { "pulb", "(sp)->b",	"mov8",	     1, 0x33,  4,  4, CHG_NONE },
416   { "des",  "sp->sp",	"des16",     1, 0x34,  3,  3, CHG_NONE },
417   { "txs",  "x->sp",	"txys16",    1, 0x35,  3,  3, CHG_NONE },
418   { "psha", "a->(sp)",	"mov8",	     1, 0x36,  3,  3, CHG_NONE },
419   { "pshb", "b->(sp)",	"mov8",	     1, 0x37,  3,  3, CHG_NONE },
420   { "pulx", "(sp)->x",	"mov16",     1, 0x38,  5,  5, CHG_NONE },
421   { "rts",  0,		"rts11",     1, 0x39,  5,  5, CHG_NONE },
422   { "abx",  "b,x->x",	"abxy16",    1, 0x3a,  3,  3, CHG_NONE },
423   { "rti",  0,		"rti11",     1, 0x3b, 12, 12, CHG_ALL},
424   { "pshx", "x->(sp)",	"mov16",     1, 0x3c,  4,  4, CHG_NONE },
425   { "mul",  "b,a->d",	"mul16",     1, 0x3d,  3, 10, CHG_C },
426   { "wai",  0,		0,	     1, 0x3e, 14, _M, CHG_NONE },
427   { "swi",  0,		0,	     1, 0x3f, 14, _M, CHG_NONE },
428   { "nega", "a->a",	"neg8",	     1, 0x40,  2,  2, CHG_NZVC },
429   { "syscall", "",	"syscall",   1, 0x41,  2,  2, CHG_NONE },
430   { "coma", "a->a",	"com8",	     1, 0x43,  2,  2, SET_C_CLR_V_CHG_NZ },
431   { "lsra", "a->a",	"lsr8",	     1, 0x44,  2,  2, CLR_N_CHG_ZVC},
432   { "rora", "a->a",	"ror8",	     1, 0x46,  2,  2, CHG_NZVC },
433   { "asra", "a->a",	"asr8",	     1, 0x47,  2,  2, CHG_NZVC },
434   { "asla", "a->a",	"lsl8",	     1, 0x48,  2,  2, CHG_NZVC },
435   { "rola", "a->a",	"rol8",	     1, 0x49,  2,  2, CHG_NZVC },
436   { "deca", "a->a",	"dec8",	     1, 0x4a,  2,  2, CHG_NZV },
437   { "inca", "a->a",	"inc8",	     1, 0x4c,  2,  2, CHG_NZV },
438   { "tsta", "a",	"tst8",	     1, 0x4d,  2,  2, CLR_V_CHG_NZ },
439   { "clra", "->a",	"clr8",	     1, 0x4f,  2,  2, SET_Z_CLR_NVC },
440   { "negb", "b->b",	"neg8",	     1, 0x50,  2,  2, CHG_NZVC },
441   { "comb", "b->b",	"com8",	     1, 0x53,  2,  2, SET_C_CLR_V_CHG_NZ },
442   { "lsrb", "b->b",	"lsr8",	     1, 0x54,  2,  2, CLR_N_CHG_ZVC },
443   { "rorb", "b->b",	"ror8",	     1, 0x56,  2,  2, CHG_NZVC },
444   { "asrb", "b->b",	"asr8",	     1, 0x57,  2,  2, CHG_NZVC },
445   { "aslb", "b->b",	"lsl8",	     1, 0x58,  2,  2, CHG_NZVC },
446   { "rolb", "b->b",	"rol8",	     1, 0x59,  2,  2, CHG_NZVC },
447   { "decb", "b->b",	"dec8",	     1, 0x5a,  2,  2, CHG_NZV },
448   { "incb", "b->b",	"inc8",	     1, 0x5c,  2,  2, CHG_NZV },
449   { "tstb", "b",	"tst8",	     1, 0x5d,  2,  2, CLR_V_CHG_NZ },
450   { "clrb", "->b",	"clr8",	     1, 0x5f,  2,  2, SET_Z_CLR_NVC },
451   { "neg",  "(x)->(x)", "neg8",	     2, 0x60,  6,  6, CHG_NZVC },
452   { "com",  "(x)->(x)", "com8",	     2, 0x63,  6,  6, SET_C_CLR_V_CHG_NZ },
453   { "lsr",  "(x)->(x)", "lsr8",	     2, 0x64,  6,  6, CLR_N_CHG_ZVC },
454   { "ror",  "(x)->(x)", "ror8",	     2, 0x66,  6,  6, CHG_NZVC },
455   { "asr",  "(x)->(x)", "asr8",	     2, 0x67,  6,  6, CHG_NZVC },
456   { "asl",  "(x)->(x)", "lsl8",	     2, 0x68,  6,  6, CHG_NZVC },
457   { "rol",  "(x)->(x)", "rol8",	     2, 0x69,  6,  6, CHG_NZVC },
458   { "dec",  "(x)->(x)", "dec8",	     2, 0x6a,  6,  6, CHG_NZV },
459   { "inc",  "(x)->(x)", "inc8",	     2, 0x6c,  6,  6, CHG_NZV },
460   { "tst",  "(x)",	"tst8",	     2, 0x6d,  6,  6, CLR_V_CHG_NZ },
461   { "jmp",  "&(x)",	"bra",	     2, 0x6e,  3,  3, CHG_NONE },
462   { "clr",  "->(x)",	"clr8",	     2, 0x6f,  6,  6, SET_Z_CLR_NVC },
463   { "neg",  "()->()",	"neg8",	     3, 0x70,  6,  6, CHG_NZVC },
464   { "com",  "()->()",	"com8",	     3, 0x73,  6,  6, SET_C_CLR_V_CHG_NZ },
465   { "lsr",  "()->()",	"lsr8",	     3, 0x74,  6,  6, CLR_V_CHG_ZVC },
466   { "ror",  "()->()",	"ror8",	     3, 0x76,  6,  6, CHG_NZVC },
467   { "asr",  "()->()",	"asr8",	     3, 0x77,  6,  6, CHG_NZVC },
468   { "asl",  "()->()",	"lsl8",	     3, 0x78,  6,  6, CHG_NZVC },
469   { "rol",  "()->()",	"rol8",	     3, 0x79,  6,  6, CHG_NZVC },
470   { "dec",  "()->()",	"dec8",	     3, 0x7a,  6,  6, CHG_NZV },
471   { "inc",  "()->()",	"inc8",	     3, 0x7c,  6,  6, CHG_NZV },
472   { "tst",  "()",	"tst8",	     3, 0x7d,  6,  6, CLR_V_CHG_NZ },
473   { "jmp",  "&()",	"bra",	     3, 0x7e,  3,  3, CHG_NONE },
474   { "clr",  "->()",	"clr8",	     3, 0x7f,  6,  6, SET_Z_CLR_NVC },
475   { "suba", "#,a->a",	"sub8",	     2, 0x80,  2,  2, CHG_NZVC },
476   { "cmpa", "#,a",	"sub8",	     2, 0x81,  2,  2, CHG_NZVC },
477   { "sbca", "#,a->a",	"sbc8",	     2, 0x82,  2,  2, CHG_NZVC },
478   { "subd", "#,d->d",	"sub16",     3, 0x83,  4,  4, CHG_NZVC },
479   { "anda", "#,a->a",	"and8",	     2, 0x84,  2,  2, CLR_V_CHG_NZ },
480   { "bita", "#,a",	"and8",	     2, 0x85,  2,  2, CLR_V_CHG_NZ },
481   { "ldaa", "#->a",	"movtst8",   2, 0x86,  2,  2, CLR_V_CHG_NZ },
482   { "eora", "#,a->a",	"eor8",	     2, 0x88,  2,  2, CLR_V_CHG_NZ },
483   { "adca", "#,a->a",	"adc8",	     2, 0x89,  2,  2, CHG_HNZVC },
484   { "oraa", "#,a->a",	"or8",	     2, 0x8a,  2,  2, CLR_V_CHG_NZ },
485   { "adda", "#,a->a",	"add8",	     2, 0x8b,  2,  2, CHG_HNZVC },
486   { "cmpx", "#,x",	"sub16",     3, 0x8c,  4,  4, CHG_NZVC },
487   { "bsr",  "r",	"jsr_11_16", 2, 0x8d,  6,  6, CHG_NONE },
488   { "lds",  "#->sp",	"movtst16",  3, 0x8e,  3,  3, CLR_V_CHG_NZ },
489   { "xgdx", "x->x",	"xgdxy16",   1, 0x8f,  3,  3, CHG_NONE },
490   { "suba", "*,a->a",	"sub8",	     2, 0x90,  3,  3, CHG_NZVC },
491   { "cmpa", "*,a",	"sub8",	     2, 0x91,  3,  3, CHG_NZVC },
492   { "sbca", "*,a->a",	"sbc8",	     2, 0x92,  3,  3, CHG_NZVC },
493   { "subd", "*,d->d",	"sub16",     2, 0x93,  5,  5, CHG_NZVC },
494   { "anda", "*,a->a",	"and8",	     2, 0x94,  3,  3, CLR_V_CHG_NZ },
495   { "bita", "*,a",	"and8",	     2, 0x95,  3,  3, CLR_V_CHG_NZ },
496   { "ldaa", "*->a",	"movtst8",   2, 0x96,  3,  3, CLR_V_CHG_NZ },
497   { "staa", "a->*",	"movtst8",   2, 0x97,  3,  3, CLR_V_CHG_NZ },
498   { "eora", "*,a->a",	"eor8",	     2, 0x98,  3,  3, CLR_V_CHG_NZ },
499   { "adca", "*,a->a",	"adc8",	     2, 0x99,  3,  3, CHG_HNZVC },
500   { "oraa", "*,a->a",	"or8",	     2, 0x9a,  3,  3, CLR_V_CHG_NZ },
501   { "adda", "*,a->a",	"add8",	     2, 0x9b,  3,  3, CHG_HNZVC },
502   { "cmpx", "*,x",	"sub16",     2, 0x9c,  5,  5, CHG_NZVC },
503   { "jsr",  "*",	"jsr_11_16", 2, 0x9d,  5,  5, CHG_NONE },
504   { "lds",  "*->sp",	"movtst16",  2, 0x9e,  4,  4, CLR_V_CHG_NZ },
505   { "sts",  "sp->*",	"movtst16",  2, 0x9f,  4,  4, CLR_V_CHG_NZ },
506   { "suba", "(x),a->a", "sub8",	     2, 0xa0,  4,  4, CHG_NZVC },
507   { "cmpa", "(x),a",	"sub8",	     2, 0xa1,  4,  4, CHG_NZVC },
508   { "sbca", "(x),a->a", "sbc8",	     2, 0xa2,  4,  4, CHG_NZVC },
509   { "subd", "(x),d->d", "sub16",     2, 0xa3,  6,  6, CHG_NZVC },
510   { "anda", "(x),a->a", "and8",	     2, 0xa4,  4,  4, CLR_V_CHG_NZ },
511   { "bita", "(x),a",	"and8",	     2, 0xa5,  4,  4, CLR_V_CHG_NZ },
512   { "ldaa", "(x)->a",	"movtst8",   2, 0xa6,  4,  4, CLR_V_CHG_NZ },
513   { "staa", "a->(x)",	"movtst8",   2, 0xa7,  4,  4, CLR_V_CHG_NZ },
514   { "eora", "(x),a->a", "eor8",	     2, 0xa8,  4,  4, CLR_V_CHG_NZ },
515   { "adca", "(x),a->a", "adc8",	     2, 0xa9,  4,  4, CHG_HNZVC },
516   { "oraa", "(x),a->a", "or8",	     2, 0xaa,  4,  4, CLR_V_CHG_NZ },
517   { "adda", "(x),a->a", "add8",	     2, 0xab,  4,  4, CHG_HNZVC },
518   { "cmpx", "(x),x",	"sub16",     2, 0xac,  6,  6, CHG_NZVC },
519   { "jsr",  "&(x)",	"jsr_11_16", 2, 0xad,  6,  6, CHG_NONE },
520   { "lds",  "(x)->sp",	"movtst16",  2, 0xae,  5,  5, CLR_V_CHG_NZ },
521   { "sts",  "sp->(x)",	"movtst16",  2, 0xaf,  5,  5, CLR_V_CHG_NZ },
522   { "suba", "(),a->a",	"sub8",	     3, 0xb0,  4,  4, CHG_NZVC },
523   { "cmpa", "(),a",	"sub8",	     3, 0xb1,  4,  4, CHG_NZVC },
524   { "sbca", "(),a->a",	"sbc8",	     3, 0xb2,  4,  4, CHG_NZVC },
525   { "subd", "(),d->d",	"sub16",     3, 0xb3,  6,  6, CHG_NZVC },
526   { "anda", "(),a->a",	"and8",	     3, 0xb4,  4,  4, CLR_V_CHG_NZ },
527   { "bita", "(),a",	"and8",	     3, 0xb5,  4,  4, CLR_V_CHG_NZ },
528   { "ldaa", "()->a",	"movtst8",   3, 0xb6,  4,  4, CLR_V_CHG_NZ },
529   { "staa", "a->()",	"movtst8",   3, 0xb7,  4,  4, CLR_V_CHG_NZ },
530   { "eora", "(),a->a",	"eor8",	     3, 0xb8,  4,  4, CLR_V_CHG_NZ },
531   { "adca", "(),a->a",	"adc8",	     3, 0xb9,  4,  4, CHG_HNZVC },
532   { "oraa", "(),a->a",	"or8",	     3, 0xba,  4,  4, CLR_V_CHG_NZ },
533   { "adda", "(),a->a",	"add8",	     3, 0xbb,  4,  4, CHG_HNZVC },
534   { "cmpx", "(),x",	"sub16",     3, 0xbc,  5,  5, CHG_NZVC },
535   { "jsr",  "&()",	"jsr_11_16", 3, 0xbd,  6,  6, CHG_NONE },
536   { "lds",  "()->sp",	"movtst16",  3, 0xbe,  5,  5, CLR_V_CHG_NZ },
537   { "sts",  "sp->()",	"movtst16",  3, 0xbf,  5,  5, CLR_V_CHG_NZ },
538   { "subb", "#,b->b",	"sub8",	     2, 0xc0,  2,  2, CHG_NZVC },
539   { "cmpb", "#,b",	"sub8",	     2, 0xc1,  2,  2, CHG_NZVC },
540   { "sbcb", "#,b->b",	"sbc8",	     2, 0xc2,  2,  2, CHG_NZVC },
541   { "addd", "#,d->d",	"add16",     3, 0xc3,  4,  4, CHG_NZVC },
542   { "andb", "#,b->b",	"and8",	     2, 0xc4,  2,  2, CLR_V_CHG_NZ },
543   { "bitb", "#,b",	"and8",	     2, 0xc5,  2,  2, CLR_V_CHG_NZ },
544   { "ldab", "#->b",	"movtst8",   2, 0xc6,  2,  2, CLR_V_CHG_NZ },
545   { "eorb", "#,b->b",	"eor8",	     2, 0xc8,  2,  2, CLR_V_CHG_NZ },
546   { "adcb", "#,b->b",	"adc8",	     2, 0xc9,  2,  2, CHG_HNZVC },
547   { "orab", "#,b->b",	"or8",	     2, 0xca,  2,  2, CLR_V_CHG_NZ },
548   { "addb", "#,b->b",	"add8",	     2, 0xcb,  2,  2, CHG_HNZVC },
549   { "ldd",  "#->d",	"movtst16",  3, 0xcc,  3,  3, CLR_V_CHG_NZ },
550   { "page4",0,		"page4",     1, 0xcd,  0,  0, CHG_NONE },
551   { "ldx",  "#->x",	"movtst16",  3, 0xce,  3,  3, CLR_V_CHG_NZ },
552   { "stop", 0,		0,	     1, 0xcf,  2,  2, CHG_NONE },
553   { "subb", "*,b->b",	"sub8",	     2, 0xd0,  3,  3, CHG_NZVC },
554   { "cmpb", "*,b",	"sub8",	     2, 0xd1,  3,  3, CHG_NZVC },
555   { "sbcb", "*,b->b",	"sbc8",	     2, 0xd2,  3,  3, CHG_NZVC },
556   { "addd", "*,d->d",	"add16",     2, 0xd3,  5,  5, CHG_NZVC },
557   { "andb", "*,b->b",	"and8",	     2, 0xd4,  3,  3, CLR_V_CHG_NZ },
558   { "bitb", "*,b",	"and8",	     2, 0xd5,  3,  3, CLR_V_CHG_NZ },
559   { "ldab", "*->b",	"movtst8",   2, 0xd6,  3,  3, CLR_V_CHG_NZ },
560   { "stab", "b->*",	"movtst8",   2, 0xd7,  3,  3, CLR_V_CHG_NZ },
561   { "eorb", "*,b->b",	"eor8",	     2, 0xd8,  3,  3, CLR_V_CHG_NZ },
562   { "adcb", "*,b->b",	"adc8",	     2, 0xd9,  3,  3, CHG_HNZVC },
563   { "orab", "*,b->b",	"or8",	     2, 0xda,  3,  3, CLR_V_CHG_NZ },
564   { "addb", "*,b->b",	"add8",	     2, 0xdb,  3,  3, CHG_HNZVC },
565   { "ldd",  "*->d",	"movtst16",  2, 0xdc,  4,  4, CLR_V_CHG_NZ },
566   { "std",  "d->*",	"movtst16",  2, 0xdd,  4,  4, CLR_V_CHG_NZ },
567   { "ldx",  "*->x",	"movtst16",  2, 0xde,  4,  4, CLR_V_CHG_NZ },
568   { "stx",  "x->*",	"movtst16",  2, 0xdf,  4,  4, CLR_V_CHG_NZ },
569   { "subb", "(x),b->b", "sub8",	     2, 0xe0,  4,  4, CHG_NZVC },
570   { "cmpb", "(x),b",	"sub8",	     2, 0xe1,  4,  4, CHG_NZVC },
571   { "sbcb", "(x),b->b", "sbc8",	     2, 0xe2,  4,  4, CHG_NZVC },
572   { "addd", "(x),d->d", "add16",     2, 0xe3,  6,  6, CHG_NZVC },
573   { "andb", "(x),b->b", "and8",	     2, 0xe4,  4,  4, CLR_V_CHG_NZ },
574   { "bitb", "(x),b",	"and8",	     2, 0xe5,  4,  4, CLR_V_CHG_NZ },
575   { "ldab", "(x)->b",	"movtst8",   2, 0xe6,  4,  4, CLR_V_CHG_NZ },
576   { "stab", "b->(x)",	"movtst8",   2, 0xe7,  4,  4, CLR_V_CHG_NZ },
577   { "eorb", "(x),b->b", "eor8",	     2, 0xe8,  4,  4, CLR_V_CHG_NZ },
578   { "adcb", "(x),b->b", "adc8",	     2, 0xe9,  4,  4, CHG_HNZVC },
579   { "orab", "(x),b->b", "or8",	     2, 0xea,  4,  4, CLR_V_CHG_NZ },
580   { "addb", "(x),b->b", "add8",	     2, 0xeb,  4,  4, CHG_HNZVC },
581   { "ldd",  "(x)->d",	"movtst16",  2, 0xec,  5,  5, CLR_V_CHG_NZ },
582   { "std",  "d->(x)",	"movtst16",  2, 0xed,  5,  5, CLR_V_CHG_NZ },
583   { "ldx",  "(x)->x",	"movtst16",  2, 0xee,  5,  5, CLR_V_CHG_NZ },
584   { "stx",  "x->(x)",	"movtst16",  2, 0xef,  5,  5, CLR_V_CHG_NZ },
585   { "subb", "(),b->b",	"sub8",	     3, 0xf0,  4,  4, CHG_NZVC },
586   { "cmpb", "(),b",	"sub8",	     3, 0xf1,  4,  4, CHG_NZVC },
587   { "sbcb", "(),b->b",	"sbc8",	     3, 0xf2,  4,  4, CHG_NZVC },
588   { "addd", "(),d->d",	"add16",     3, 0xf3,  6,  6, CHG_NZVC },
589   { "andb", "(),b->b",	"and8",	     3, 0xf4,  4,  4, CLR_V_CHG_NZ },
590   { "bitb", "(),b",	"and8",	     3, 0xf5,  4,  4, CLR_V_CHG_NZ },
591   { "ldab", "()->b",	"movtst8",   3, 0xf6,  4,  4, CLR_V_CHG_NZ },
592   { "stab", "b->()",	"movtst8",   3, 0xf7,  4,  4, CLR_V_CHG_NZ },
593   { "eorb", "(),b->b",	"eor8",	     3, 0xf8,  4,  4, CLR_V_CHG_NZ },
594   { "adcb", "(),b->b",	"eor8",	     3, 0xf9,  4,  4, CHG_HNZVC },
595   { "orab", "(),b->b",	"or8",	     3, 0xfa,  4,  4, CLR_V_CHG_NZ },
596   { "addb", "(),b->b",	"add8",	     3, 0xfb,  4,  4, CHG_HNZVC },
597   { "ldd",  "()->d",	"movtst16",  3, 0xfc,  5,  5, CLR_V_CHG_NZ },
598   { "std",  "d->()",	"movtst16",  3, 0xfd,  5,  5, CLR_V_CHG_NZ },
599   { "ldx",  "()->x",	"movtst16",  3, 0xfe,  5,  5, CLR_V_CHG_NZ },
600   { "stx",  "x->()",	"movtst16",  3, 0xff,  5,  5, CLR_V_CHG_NZ }
601 };
602 
603 
604 /* Page 2 opcodes */
605 /*
606  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
607  * Name -+					 +----- Insn CCR changes
608  * Operands  ---+			  +------------ Max # cycles
609  * Pattern   -----------+	       +--------------- Min # cycles
610  * Size	     -----------------+	  +-------------------- Opcode
611  */
612 struct m6811_opcode_def m6811_page2_opcodes[] = {
613   { "iny",  "y->y",	"inc16",     2, 0x08, 4, 4, CHG_Z },
614   { "dey",  "y->y",	"dec16",     2, 0x09, 4, 4, CHG_Z },
615   { "bset", "(y),#->(y)","or8",	     4, 0x1c, 8, 8, CLR_V_CHG_NZ },
616   { "bclr", "(y),#->(y)","bclr8",    4, 0x1d, 8, 8, CLR_V_CHG_NZ },
617   { "brset","(y),#,r",	 "brset8",   5, 0x1e, 8, 8, CHG_NONE },
618   { "brclr","(y),#,r",	"brclr8",    5, 0x1f, 8, 8, CHG_NONE },
619   { "tsy",  "sp->y",	"tsxy16",    2, 0x30, 4, 4, CHG_NONE },
620   { "tys",  "y->sp",	"txys16",    2, 0x35, 4, 4, CHG_NONE },
621   { "puly", "(sp)->y",	"mov16",     2, 0x38, 6, 6, CHG_NONE },
622   { "aby",  "b,y->y",	"abxy16",    2, 0x3a, 4, 4, CHG_NONE },
623   { "pshy", "y->(sp)",	"mov16",     2, 0x3c, 5, 5, CHG_NONE },
624   { "neg",  "(y)->(y)", "neg8",	     3, 0x60, 7, 7, CHG_NZVC },
625   { "com",  "(y)->(y)", "com8",	     3, 0x63, 7, 7, SET_C_CLR_V_CHG_NZ},
626   { "lsr",  "(y)->(y)", "lsr8",	     3, 0x64, 7, 7, CLR_V_CHG_ZVC },
627   { "ror",  "(y)->(y)", "ror8",	     3, 0x66, 7, 7, CHG_NZVC },
628   { "asr",  "(y)->(y)", "asr8",	     3, 0x67, 7, 7, CHG_NZVC },
629   { "asl",  "(y)->(y)", "lsl8",	     3, 0x68, 7, 7, CHG_NZVC },
630   { "rol",  "(y)->(y)", "rol8",	     3, 0x69, 7, 7, CHG_NZVC },
631   { "dec",  "(y)->(y)", "dec8",	     3, 0x6a, 7, 7, CHG_NZV },
632   { "inc",  "(y)->(y)", "inc8",	     3, 0x6c, 7, 7, CHG_NZV },
633   { "tst",  "(y)",	"tst8",	     3, 0x6d, 7, 7, CLR_V_CHG_NZ },
634   { "jmp",  "&(y)",	"bra",	     3, 0x6e, 4, 4, CHG_NONE },
635   { "clr",  "->(y)",	"clr8",	     3, 0x6f, 7, 7, SET_Z_CLR_NVC },
636   { "cmpy", "#,y",	"sub16",     4, 0x8c, 5, 5, CHG_NZVC },
637   { "xgdy", "y->y",	"xgdxy16",   2, 0x8f, 4, 4, CHG_NONE },
638   { "cmpy", "*,y",	"sub16",     3, 0x9c, 6, 6, CHG_NZVC },
639   { "suba", "(y),a->a", "sub8",	     3, 0xa0, 5, 5, CHG_NZVC },
640   { "cmpa", "(y),a",	"sub8",	     3, 0xa1, 5, 5, CHG_NZVC },
641   { "sbca", "(y),a->a", "sbc8",	     3, 0xa2, 5, 5, CHG_NZVC },
642   { "subd", "(y),d->d", "sub16",     3, 0xa3, 7, 7, CHG_NZVC },
643   { "anda", "(y),a->a", "and8",	     3, 0xa4, 5, 5, CLR_V_CHG_NZ },
644   { "bita", "(y),a",	"and8",	     3, 0xa5, 5, 5, CLR_V_CHG_NZ },
645   { "ldaa", "(y)->a",	"movtst8",   3, 0xa6, 5, 5, CLR_V_CHG_NZ },
646   { "staa", "a->(y)",	"movtst8",   3, 0xa7, 5, 5, CLR_V_CHG_NZ },
647   { "eora", "(y),a->a", "eor8",	     3, 0xa8, 5, 5, CLR_V_CHG_NZ },
648   { "adca", "(y),a->a", "adc8",	     3, 0xa9, 5, 5, CHG_HNZVC },
649   { "oraa", "(y),a->a", "or8",	     3, 0xaa, 5, 5, CLR_V_CHG_NZ },
650   { "adda", "(y),a->a", "add8",	     3, 0xab, 5, 5, CHG_HNZVC },
651   { "cmpy", "(y),y",	"sub16",     3, 0xac, 7, 7, CHG_NZVC },
652   { "jsr",  "&(y)",	"jsr_11_16", 3, 0xad, 6, 6, CHG_NONE },
653   { "lds",  "(y)->sp",	"movtst16",  3, 0xae, 6, 6, CLR_V_CHG_NZ },
654   { "sts",  "sp->(y)",	"movtst16",  3, 0xaf, 6, 6, CLR_V_CHG_NZ },
655   { "cmpy", "(),y",	"sub16",     4, 0xbc, 7, 7, CHG_NZVC },
656   { "ldy",  "#->y",	"movtst16",  4, 0xce, 4, 4, CLR_V_CHG_NZ },
657   { "ldy",  "*->y",	"movtst16",  3, 0xde, 5, 5, CLR_V_CHG_NZ },
658   { "sty",  "y->*",	"movtst16",  3, 0xdf, 5, 5, CLR_V_CHG_NZ },
659   { "subb", "(y),b->b", "sub8",	     3, 0xe0, 5, 5, CHG_NZVC },
660   { "cmpb", "(y),b",	"sub8",	     3, 0xe1, 5, 5, CHG_NZVC },
661   { "sbcb", "(y),b->b", "sbc8",	     3, 0xe2, 5, 5, CHG_NZVC },
662   { "addd", "(y),d->d", "add16",     3, 0xe3, 7, 7, CHG_NZVC },
663   { "andb", "(y),b->b", "and8",	     3, 0xe4, 5, 5, CLR_V_CHG_NZ },
664   { "bitb", "(y),b",	"and8",	     3, 0xe5, 5, 5, CLR_V_CHG_NZ },
665   { "ldab", "(y)->b",	"movtst8",   3, 0xe6, 5, 5, CLR_V_CHG_NZ },
666   { "stab", "b->(y)",	"movtst8",   3, 0xe7, 5, 5, CLR_V_CHG_NZ },
667   { "eorb", "(y),b->b", "eor8",	     3, 0xe8, 5, 5, CLR_V_CHG_NZ },
668   { "adcb", "(y),b->b", "adc8",	     3, 0xe9, 5, 5, CHG_HNZVC },
669   { "orab", "(y),b->b", "or8",	     3, 0xea, 5, 5, CLR_V_CHG_NZ },
670   { "addb", "(y),b->b", "add8",	     3, 0xeb, 5, 5, CHG_HNZVC },
671   { "ldd",  "(y)->d",	"movtst16",  3, 0xec, 6, 6, CLR_V_CHG_NZ },
672   { "std",  "d->(y)",	"movtst16",  3, 0xed, 6, 6, CLR_V_CHG_NZ },
673   { "ldy",  "(y)->y",	"movtst16",  3, 0xee, 6, 6, CLR_V_CHG_NZ },
674   { "sty",  "y->(y)",	"movtst16",  3, 0xef, 6, 6, CLR_V_CHG_NZ },
675   { "ldy",  "()->y",	"movtst16",  4, 0xfe, 6, 6, CLR_V_CHG_NZ },
676   { "sty",  "y->()",	"movtst16",  4, 0xff, 6, 6, CLR_V_CHG_NZ }
677 };
678 
679 /* Page 3 opcodes */
680 /*
681  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
682  * Name -+					 +----- Insn CCR changes
683  * Operands  ---+			  +------------ Max # cycles
684  * Pattern   -----------+	       +--------------- Min # cycles
685  * Size	     -----------------+	  +-------------------- Opcode
686  */
687 struct m6811_opcode_def m6811_page3_opcodes[] = {
688   { "cmpd", "#,d",	"sub16",     4, 0x83, 5, 5, CHG_NZVC },
689   { "cmpd", "*,d",	"sub16",     3, 0x93, 6, 6, CHG_NZVC },
690   { "cmpd", "(x),d",	"sub16",     3, 0xa3, 7, 7, CHG_NZVC },
691   { "cmpy", "(x),y",	"sub16",     3, 0xac, 7, 7, CHG_NZVC },
692   { "cmpd", "(),d",	"sub16",     4, 0xb3, 7, 7, CHG_NZVC },
693   { "ldy",  "(x)->y",	"movtst16",  3, 0xee, 6, 6, CLR_V_CHG_NZ },
694   { "sty",  "y->(x)",	"movtst16",  3, 0xef, 6, 6, CLR_V_CHG_NZ }
695 };
696 
697 /* Page 4 opcodes */
698 /*
699  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
700  * Name -+					 +----- Insn CCR changes
701  * Operands  ---+			  +------------ Max # cycles
702  * Pattern   -----------+	       +--------------- Min # cycles
703  * Size	     -----------------+	  +-------------------- Opcode
704  */
705 struct m6811_opcode_def m6811_page4_opcodes[] = {
706   { "syscall", "",	"syscall",   2, 0x03, 6, 6, CHG_NONE },
707   { "cmpd", "(y),d",	"sub16",     3, 0xa3, 7, 7, CHG_NZVC },
708   { "cmpx", "(y),x",	"sub16",     3, 0xac, 7, 7, CHG_NZVC },
709   { "ldx",  "(y)->x",	"movtst16",  3, 0xee, 6, 6, CLR_V_CHG_NZ },
710   { "stx",  "x->(y)",	"movtst16",  3, 0xef, 6, 6, CLR_V_CHG_NZ }
711 };
712 
713 /* 68HC12 opcodes */
714 /*
715  *  { "dex", "x->x", "dec16", 1, 0x00, 5, _M,  CHG_NONE },
716  * Name -+					 +----- Insn CCR changes
717  * Operands  ---+			  +------------ Max # cycles
718  * Pattern   -----------+	       +--------------- Min # cycles
719  * Size	     -----------------+	  +-------------------- Opcode
720  */
721 struct m6811_opcode_def m6812_page1_opcodes[] = {
722   { "adca", "#,a->a",    "adc8",     2, 0x89,  1,  1,  CHG_HNZVC },
723   { "adca", "*,a->a",    "adc8",     2, 0x99,  3,  3,  CHG_HNZVC },
724   { "adca", "(),a->a",   "adc8",     3, 0xb9,  3,  3,  CHG_HNZVC },
725   { "adca", "[],a->a",   "adc8",     2, 0xa9,  3,  3,  CHG_HNZVC },
726 
727   { "adcb", "#,b->b",    "adc8",     2, 0xc9,  1,  1,  CHG_HNZVC },
728   { "adcb", "*,b->b",    "adc8",     3, 0xd9,  3,  3,  CHG_HNZVC },
729   { "adcb", "(),b->b",   "adc8",     3, 0xf9,  3,  3,  CHG_HNZVC },
730   { "adcb", "[],b->b",   "adc8",     2, 0xe9,  3,  3,  CHG_HNZVC },
731 
732   { "adda", "#,a->a",    "add8",     2, 0x8b,  1,  1,  CHG_HNZVC },
733   { "adda", "*,a->a",    "add8",     3, 0x9b,  3,  3,  CHG_HNZVC },
734   { "adda", "(),a->a",   "add8",     3, 0xbb,  3,  3,  CHG_HNZVC },
735   { "adda", "[],a->a",   "add8",     2, 0xab,  3,  3,  CHG_HNZVC },
736 
737   { "addb", "#,b->b",    "add8",     2, 0xcb,  1,  1,  CHG_HNZVC },
738   { "addb", "*,b->b",    "add8",     3, 0xdb,  3,  3,  CHG_HNZVC },
739   { "addb", "(),b->b",   "add8",     3, 0xfb,  3,  3,  CHG_HNZVC },
740   { "addb", "[],b->b",   "add8",     2, 0xeb,  3,  3,  CHG_HNZVC },
741 
742   { "addd", "#,d->d",    "add16",    3, 0xc3,  2,  2,  CHG_NZVC },
743   { "addd", "*,d->d",    "add16",    2, 0xd3,  3,  3,  CHG_NZVC },
744   { "addd", "(),d->d",   "add16",    3, 0xf3,  3,  3,  CHG_NZVC },
745   { "addd", "[],d->d",   "add16",    2, 0xe3,  3,  3,  CHG_NZVC },
746 
747   { "anda", "#,a->a",    "and8",     2, 0x84,  1,  1,  CLR_V_CHG_NZ },
748   { "anda", "*,a->a",    "and8",     2, 0x94,  3,  3,  CLR_V_CHG_NZ },
749   { "anda", "(),a->a",   "and8",     3, 0xb4,  3,  3,  CLR_V_CHG_NZ },
750   { "anda", "[],a->a",   "and8",     2, 0xa4,  3,  3,  CLR_V_CHG_NZ },
751 
752   { "andb", "#,b->b",    "and8",     2, 0xc4,  1,  1,  CLR_V_CHG_NZ },
753   { "andb", "*,b->b",    "and8",     2, 0xd4,  3,  3,  CLR_V_CHG_NZ },
754   { "andb", "(),b->b",   "and8",     3, 0xf4,  3,  3,  CLR_V_CHG_NZ },
755   { "andb", "[],b->b",   "and8",     2, 0xe4,  3,  3,  CLR_V_CHG_NZ },
756 
757   { "andcc", "#,ccr->ccr", "and8",   2, 0x10,  1,  1,  CHG_ALL },
758 
759   { "asl",  "()->()",    "lsl8",     3, 0x78,  4,  4,  CHG_NZVC },
760   { "asl",  "[]->[]",    "lsl8",     2, 0x68,  3,  3,  CHG_NZVC },
761 
762   { "asla", "a->a",      "lsl8",     1, 0x48,  1,  1,  CHG_NZVC },
763   { "aslb", "b->b",      "lsl8",     1, 0x58,  1,  1,  CHG_NZVC },
764   { "asld", "d->d",      "lsl16",    1, 0x59,  1,  1,  CHG_NZVC },
765 
766   { "asr",  "()->()",    "asr8",     3, 0x77,  4,  4,  CHG_NZVC },
767   { "asr",  "[]->[]",    "asr8",     2, 0x67,  3,  3,  CHG_NZVC },
768 
769   { "asra", "a->a",      "asr8",     1, 0x47,  1,  1,  CHG_NZVC },
770   { "asrb", "b->b",      "asr8",     1, 0x57,  1,  1,  CHG_NZVC },
771 
772   { "bcc",  "r",         0,          2, 0x24,  1,  3,  CHG_NONE },
773 
774   { "bclr", "*,#->*",    "bclr8",    3, 0x4d,  4,  4,  CLR_V_CHG_NZ },
775   { "bclr", "(),#->()",  "bclr8",    4, 0x1d,  4,  4,  CLR_V_CHG_NZ },
776   { "bclr", "[],#->[]",  "bclr8",    3, 0x0d,  4,  4,  CLR_V_CHG_NZ },
777 
778   { "bcs",  "r",         0,          2, 0x25,  1,  3, CHG_NONE },
779   { "beq",  "r",         0,          2, 0x27,  1,  3, CHG_NONE },
780   { "bge",  "r",         0,          2, 0x2c,  1,  3, CHG_NONE },
781 
782   { "bgnd",  0,          0,          1, 0x00,  5,  5, CHG_NONE },
783 
784   { "bgt",  "r",         0,          2, 0x2e,  1,  3, CHG_NONE },
785   { "bhi",  "r",         0,          2, 0x22,  1,  3, CHG_NONE },
786 
787   { "bita", "#,a",       "and8",     2, 0x85,  1,  1, CLR_V_CHG_NZ },
788   { "bita", "*,a",       "and8",     2, 0x95,  3,  3, CLR_V_CHG_NZ },
789   { "bita", "(),a",      "and8",     3, 0xb5,  3,  3, CLR_V_CHG_NZ },
790   { "bita", "[],a",      "and8",     2, 0xa5,  3,  3,  CLR_V_CHG_NZ },
791 
792   { "bitb", "#,b",       "and8",     2, 0xc5,  1,  1, CLR_V_CHG_NZ },
793   { "bitb", "*,b",       "and8",     2, 0xd5,  3,  3, CLR_V_CHG_NZ },
794   { "bitb", "(),b",      "and8",     3, 0xf5,  3,  3, CLR_V_CHG_NZ },
795   { "bitb", "[],b",      "and8",     2, 0xe5,  3,  3,  CLR_V_CHG_NZ },
796 
797   { "ble",  "r",          0,         2, 0x2f,  1,  3, CHG_NONE },
798   { "bls",  "r",          0,         2, 0x23,  1,  3, CHG_NONE },
799   { "blt",  "r",          0,         2, 0x2d,  1,  3, CHG_NONE },
800   { "bmi",  "r",          0,         2, 0x2b,  1,  3, CHG_NONE },
801   { "bne",  "r",          0,         2, 0x26,  1,  3, CHG_NONE },
802   { "bpl",  "r",          0,         2, 0x2a,  1,  3, CHG_NONE },
803   { "bra",  "r",          0,         2, 0x20,  1,  3, CHG_NONE },
804 
805   { "brclr", "*,#,r",     "brclr8",  4, 0x4f,  4,  4,  CHG_NONE },
806   { "brclr", "(),#,r",    "brclr8",  5, 0x1f,  5,  5,  CHG_NONE },
807   { "brclr", "[],#,r",    "brclr8",  4, 0x0f,  4,  4,  CHG_NONE },
808 
809   { "brn",  "r",          "nop",     2, 0x21,  1,  3,  CHG_NONE },
810 
811   { "brset", "*,#,r",     "brset8",  4, 0x4e,  4,  4,  CHG_NONE },
812   { "brset", "(),#,r",    "brset8",  5, 0x1e,  5,  5,  CHG_NONE },
813   { "brset", "[],#,r",    "brset8",  4, 0x0e,  4,  4,  CHG_NONE },
814 
815   { "bset",  "*,#->*",    "or8",     3, 0x4c,  4,  4,  CLR_V_CHG_NZ },
816   { "bset",  "(),#->()",  "or8",     4, 0x1c,  4,  4,  CLR_V_CHG_NZ },
817   { "bset",  "[],#->[]",  "or8",     3, 0x0c,  4,  4,  CLR_V_CHG_NZ },
818 
819   { "bsr",   "r",         "jsr_12_16", 2, 0x07,  4,  4, CHG_NONE },
820 
821   { "bvc",   "r",         0,         2, 0x28,  1,  3, CHG_NONE },
822   { "bvs",   "r",         0,         2, 0x29,  1,  3, CHG_NONE },
823 
824   { "call",  "",          "call8",   4, 0x4a,  8,  8,  CHG_NONE },
825   { "call",  "",          "call_ind",2, 0x4b,  8,  8,  CHG_NONE },
826 
827   { "clr",   "->()",      "clr8",    3, 0x79,  3,  3,  SET_Z_CLR_NVC },
828   { "clr",   "->[]",      "clr8",    2, 0x69,  2,  2,  SET_Z_CLR_NVC },
829 
830   { "clra",  "->a",       "clr8",    1, 0x87,  1,  1,  SET_Z_CLR_NVC },
831   { "clrb",  "->b",       "clr8",    1, 0xc7,  1,  1,  SET_Z_CLR_NVC },
832 
833   { "cpa",  "#,a",        "sub8",    2, 0x81,  1,  1,  CHG_NZVC },
834   { "cpa",  "*,a",        "sub8",    2, 0x91,  3,  3,  CHG_NZVC },
835   { "cpa",  "(),a",       "sub8",    3, 0xb1,  3,  3,  CHG_NZVC },
836   { "cpa",  "[],a",       "sub8",    2, 0xa1,  3,  3,  CHG_NZVC },
837 
838   { "cpb",  "#,b",        "sub8",    2, 0xc1,  1,  1,  CHG_NZVC },
839   { "cpb",  "*,b",        "sub8",    2, 0xd1,  3,  3,  CHG_NZVC },
840   { "cpb",  "(),b",       "sub8",    3, 0xf1,  3,  3,  CHG_NZVC },
841   { "cpb",  "[],b",       "sub8",    2, 0xe1,  3,  3,  CHG_NZVC },
842 
843   { "com",   "()->()",    "com8",    3, 0x71,  4,  4,  SET_C_CLR_V_CHG_NZ },
844   { "com",   "[]->[]",    "com8",    2, 0x61,  3,  3,  SET_C_CLR_V_CHG_NZ },
845 
846   { "coma",  "a->a",      "com8",    1, 0x41,  1,  1,  SET_C_CLR_V_CHG_NZ },
847   { "comb",  "b->b",      "com8",    1, 0x51,  1,  1,  SET_C_CLR_V_CHG_NZ },
848 
849   { "cpd",   "#,d",       "sub16",   3, 0x8c,  2,  2,  CHG_NZVC },
850   { "cpd",   "*,d",       "sub16",   2, 0x9c,  3,  3,  CHG_NZVC },
851   { "cpd",   "(),d",      "sub16",   3, 0xbc,  3,  3,  CHG_NZVC },
852   { "cpd",   "[],d",      "sub16",   2, 0xac,  3,  3,  CHG_NZVC },
853 
854   { "cps",   "#,sp",      "sub16",   3, 0x8f,  2,  2,  CHG_NZVC },
855   { "cps",   "*,sp",      "sub16",   2, 0x9f,  3,  3,  CHG_NZVC },
856   { "cps",   "(),sp",     "sub16",   3, 0xbf,  3,  3,  CHG_NZVC },
857   { "cps",   "[],sp",     "sub16",   2, 0xaf,  3,  3,  CHG_NZVC },
858 
859   { "cpx",   "#,x",       "sub16",   3, 0x8e,  2,  2,  CHG_NZVC },
860   { "cpx",   "*,x",       "sub16",   2, 0x9e,  3,  3,  CHG_NZVC },
861   { "cpx",   "(),x",      "sub16",   3, 0xbe,  3,  3,  CHG_NZVC },
862   { "cpx",   "[],x",      "sub16",   2, 0xae,  3,  3,  CHG_NZVC },
863 
864   { "cpy",   "#,y",       "sub16",   3, 0x8d,  2,  2,  CHG_NZVC },
865   { "cpy",   "*,y",       "sub16",   2, 0x9d,  3,  3,  CHG_NZVC },
866   { "cpy",   "(),y",      "sub16",   3, 0xbd,  3,  3,  CHG_NZVC },
867   { "cpy",   "[],y",      "sub16",   2, 0xad,  3,  3,  CHG_NZVC },
868 
869   /* dbeq, dbne, ibeq, ibne, tbeq, tbne */
870   { "dbeq",   0,          "dbcc8",   3, 0x04,  3,  3, CHG_NONE },
871 
872   { "dec",   "()->()",    "dec8",    3, 0x73,  4,  4,  CHG_NZV },
873   { "dec",   "[]->[]",    "dec8",    2, 0x63,  3,  3,  CHG_NZV },
874 
875   { "deca",  "a->a",      "dec8",    1, 0x43,  1,  1,  CHG_NZV },
876   { "decb",  "b->b",      "dec8",    1, 0x53,  1,  1,  CHG_NZV },
877 
878   { "dex",   "x->x",      "dec16",   1, 0x09,  1,  1,  CHG_Z },
879   { "dey",   "y->y",      "dec16",   1, 0x03,  1,  1,  CHG_Z },
880 
881   { "ediv",  0,           0,         1, 0x11,  11,  11,  CHG_NZVC },
882   { "emul",  0,           0,         1, 0x13,  3,  3,  CHG_NZC },
883 
884   { "eora",  "#,a->a",    "eor8",    2, 0x88,  1,  1,  CLR_V_CHG_NZ },
885   { "eora",  "*,a->a",    "eor8",    2, 0x98,  3,  3,  CLR_V_CHG_NZ },
886   { "eora",  "(),a->a",   "eor8",    3, 0xb8,  3,  3,  CLR_V_CHG_NZ },
887   { "eora",  "[],a->a",   "eor8",    2, 0xa8,  3,  3,  CLR_V_CHG_NZ },
888 
889   { "eorb",  "#,b->b",    "eor8",    2, 0xc8,  1,  1,  CLR_V_CHG_NZ },
890   { "eorb",  "*,b->b",    "eor8",    2, 0xd8,  3,  3,  CLR_V_CHG_NZ },
891   { "eorb",  "(),b->b",   "eor8",    3, 0xf8,  3,  3,  CLR_V_CHG_NZ },
892   { "eorb",  "[],b->b",   "eor8",    2, 0xe8,  3,  3,  CLR_V_CHG_NZ },
893 
894   /* exg, sex, tfr */
895   { "exg",   "#",         "exg8",    2, 0xb7,  1,  1,  CHG_NONE },
896 
897   { "inc",   "()->()",    "inc8",    3, 0x72,  4,  4,  CHG_NZV },
898   { "inc",   "[]->[]",    "inc8",    2, 0x62,  3,  3,  CHG_NZV },
899 
900   { "inca",  "a->a",      "inc8",    1, 0x42,  1,  1,  CHG_NZV },
901   { "incb",  "b->b",      "inc8",    1, 0x52,  1,  1,  CHG_NZV },
902 
903   { "inx",   "x->x",      "inc16",   1, 0x08,  1,  1,  CHG_Z },
904   { "iny",   "y->y",      "inc16",   1, 0x02,  1,  1,  CHG_Z },
905 
906   { "jmp",   "&()",       "bra",     3, 0x06,  3,  3,  CHG_NONE },
907   { "jmp",   "&[]",       "bra",     2, 0x05,  3,  3,  CHG_NONE },
908 
909   { "jsr",   "*",         "jsr_12_16",   2, 0x17,  4,  4,  CHG_NONE },
910   { "jsr",   "&()",       "jsr_12_16",   3, 0x16,  4,  4,  CHG_NONE },
911   { "jsr",   "&[]",       "jsr_12_16",   2, 0x15,  4,  4,  CHG_NONE },
912 
913   { "ldaa", "#->a",       "movtst8", 2, 0x86,  1,  1,  CLR_V_CHG_NZ },
914   { "ldaa", "*->a",       "movtst8", 2, 0x96,  3,  3,  CLR_V_CHG_NZ },
915   { "ldaa", "()->a",      "movtst8", 3, 0xb6,  3,  3,  CLR_V_CHG_NZ },
916   { "ldaa", "[]->a",      "movtst8", 2, 0xa6,  3,  3,  CLR_V_CHG_NZ },
917 
918   { "ldab", "#->b",       "movtst8", 2, 0xc6,  1,  1,  CLR_V_CHG_NZ },
919   { "ldab", "*->b",       "movtst8", 2, 0xd6,  3,  3,  CLR_V_CHG_NZ },
920   { "ldab", "()->b",      "movtst8", 3, 0xf6,  3,  3,  CLR_V_CHG_NZ },
921   { "ldab", "[]->b",      "movtst8", 2, 0xe6,  3,  3,  CLR_V_CHG_NZ },
922 
923   { "ldd",  "#->d",       "movtst16", 3, 0xcc,  2,  2,  CLR_V_CHG_NZ },
924   { "ldd",  "*->d",       "movtst16", 2, 0xdc,  3,  3,  CLR_V_CHG_NZ },
925   { "ldd",  "()->d",      "movtst16", 3, 0xfc,  3,  3,  CLR_V_CHG_NZ },
926   { "ldd",  "[]->d",      "movtst16", 2, 0xec,  3,  3,  CLR_V_CHG_NZ },
927 
928   { "lds",  "#->sp",      "movtst16", 3, 0xcf,  2,  2,  CLR_V_CHG_NZ },
929   { "lds",  "*->sp",      "movtst16", 2, 0xdf,  3,  3,  CLR_V_CHG_NZ },
930   { "lds",  "()->sp",     "movtst16", 3, 0xff,  3,  3,  CLR_V_CHG_NZ },
931   { "lds",  "[]->sp",     "movtst16", 2, 0xef,  3,  3,  CLR_V_CHG_NZ },
932 
933   { "ldx",  "#->x",       "movtst16", 3, 0xce,  2,  2,  CLR_V_CHG_NZ },
934   { "ldx",  "*->x",       "movtst16", 2, 0xde,  3,  3,  CLR_V_CHG_NZ },
935   { "ldx",  "()->x",      "movtst16", 3, 0xfe,  3,  3,  CLR_V_CHG_NZ },
936   { "ldx",  "[]->x",      "movtst16", 2, 0xee,  3,  3,  CLR_V_CHG_NZ },
937 
938   { "ldy",  "#->y",       "movtst16", 3, 0xcd,  2,  2,  CLR_V_CHG_NZ },
939   { "ldy",  "*->y",       "movtst16", 2, 0xdd,  3,  3,  CLR_V_CHG_NZ },
940   { "ldy",  "()->y",      "movtst16", 3, 0xfd,  3,  3,  CLR_V_CHG_NZ },
941   { "ldy",  "[]->y",      "movtst16", 2, 0xed,  3,  3,  CLR_V_CHG_NZ },
942 
943   { "leas", "&[]->sp",    "lea16",   2, 0x1b,  2,  2,  CHG_NONE },
944   { "leax", "&[]->x",     "lea16",   2, 0x1a,  2,  2,  CHG_NONE },
945   { "leay", "&[]->y",     "lea16",   2, 0x19,  2,  2,  CHG_NONE },
946 
947   { "lsr",  "()->()",     "lsr8",    3, 0x74,  4,  4,  CLR_N_CHG_ZVC },
948   { "lsr",  "[]->[]",     "lsr8",    2, 0x64,  3,  3,  CLR_N_CHG_ZVC },
949 
950   { "lsra", "a->a",       "lsr8",    1, 0x44,  1,  1,  CLR_N_CHG_ZVC },
951   { "lsrb", "b->b",       "lsr8",    1, 0x54,  1,  1,  CLR_N_CHG_ZVC },
952   { "lsrd", "d->d",       "lsr16",   1, 0x49,  1,  1,  CLR_N_CHG_ZVC },
953 
954   { "mem",  0,            0,         1, 0x01,  5,  5,  CHG_HNZVC },
955 
956   { "mul",  "b,a->d",     "mul16",   1, 0x12,  3,  3,  CHG_C },
957 
958   { "neg",  "()->()",     "neg8",    3, 0x70,  4,  4,  CHG_NZVC },
959   { "neg",  "[]->[]",     "neg8",    2, 0x60,  3,  3,  CHG_NZVC },
960 
961   { "nega", "a->a",       "neg8",    1, 0x40,  1,  1,  CHG_NZVC },
962   { "negb", "b->b",       "neg8",    1, 0x50,  1,  1,  CHG_NZVC },
963 
964   { "nop",  "",           "nop",     1, 0xa7,  1,  1,  CHG_NONE },
965 
966   { "oraa", "#,a->a",     "or8",     2, 0x8a,  1,  1,  CLR_V_CHG_NZ },
967   { "oraa", "*,a->a",     "or8",     2, 0x9a,  3,  3,  CLR_V_CHG_NZ },
968   { "oraa", "(),a->a",    "or8",     3, 0xba,  3,  3,  CLR_V_CHG_NZ },
969   { "oraa", "[],a->a",    "or8",     2, 0xaa,  3,  3,  CLR_V_CHG_NZ },
970 
971   { "orab", "#,b->b",     "or8",     2, 0xca,  1,  1,  CLR_V_CHG_NZ },
972   { "orab", "*,b->b",     "or8",     2, 0xda,  3,  3,  CLR_V_CHG_NZ },
973   { "orab", "(),b->b",    "or8",     3, 0xfa,  3,  3,  CLR_V_CHG_NZ },
974   { "orab", "[],b->b",    "or8",     2, 0xea,  3,  3,  CLR_V_CHG_NZ },
975 
976   { "orcc", "#,ccr->ccr", "or8",     2, 0x14,  1,  1,  CHG_ALL },
977 
978   { "page2", 0,		  "page2",   1, 0x18,  0,  0,  CHG_NONE },
979 
980   { "psha", "a->(sp)",    "mov8",    1, 0x36,  2,  2,  CHG_NONE },
981   { "pshb", "b->(sp)",    "mov8",    1, 0x37,  2,  2,  CHG_NONE },
982   { "pshc", "ccr->(sp)",  "mov8",    1, 0x39,  2,  2,  CHG_NONE },
983   { "pshd", "d->(sp)",    "mov16",   1, 0x3b,  2,  2,  CHG_NONE },
984   { "pshx", "x->(sp)",    "mov16",   1, 0x34,  2,  2,  CHG_NONE },
985   { "pshy", "y->(sp)",    "mov16",   1, 0x35,  2,  2,  CHG_NONE },
986 
987   { "pula", "(sp)->a",    "mov8",    1, 0x32,  3,  3,  CHG_NONE },
988   { "pulb", "(sp)->b",    "mov8",    1, 0x33,  3,  3,  CHG_NONE },
989   { "pulc", "(sp)->ccr",  "mov8",    1, 0x38,  3,  3,  CHG_ALL },
990   { "puld", "(sp)->d",    "mov16",   1, 0x3a,  3,  3,  CHG_NONE },
991   { "pulx", "(sp)->x",    "mov16",   1, 0x30,  3,  3,  CHG_NONE },
992   { "puly", "(sp)->y",    "mov16",   1, 0x31,  3,  3,  CHG_NONE },
993 
994   { "rol",  "()->()",     "rol8",    3, 0x75,  4,  4,  CHG_NZVC },
995   { "rol",  "[]->[]",     "rol8",    2, 0x65,  3,  3,  CHG_NZVC },
996 
997   { "rola", "a->a",       "rol8",    1, 0x45,  1,  1,  CHG_NZVC },
998   { "rolb", "b->b",       "rol8",    1, 0x55,  1,  1,  CHG_NZVC },
999 
1000   { "ror",  "()->()",     "ror8",    3, 0x76,  4,  4,  CHG_NZVC },
1001   { "ror",  "[]->[]",     "ror8",    2, 0x66,  3,  3,  CHG_NZVC },
1002 
1003   { "rora", "a->a",       "ror8",    1, 0x46,  1,  1,  CHG_NZVC },
1004   { "rorb", "b->b",       "ror8",    1, 0x56,  1,  1,  CHG_NZVC },
1005 
1006   { "rtc",  0,            0,         1, 0x0a,  6,  6,  CHG_NONE },
1007   { "rti",  0,            "rti12",   1, 0x0b,  8, 10,  CHG_ALL},
1008   { "rts",  0,            "rts12",   1, 0x3d,  5,  5,  CHG_NONE },
1009 
1010   { "sbca", "#,a->a",     "sbc8",    2, 0x82,  1,  1,  CHG_NZVC },
1011   { "sbca", "*,a->a",     "sbc8",    2, 0x92,  3,  3,  CHG_NZVC },
1012   { "sbca", "(),a->a",    "sbc8",    3, 0xb2,  3,  3,  CHG_NZVC },
1013   { "sbca", "[],a->a",    "sbc8",    2, 0xa2,  3,  3,  CHG_NZVC },
1014 
1015   { "sbcb", "#,b->b",     "sbc8",    2, 0xc2,  1,  1,  CHG_NZVC },
1016   { "sbcb", "*,b->b",     "sbc8",    2, 0xd2,  3,  3,  CHG_NZVC },
1017   { "sbcb", "(),b->b",    "sbc8",    3, 0xf2,  3,  3,  CHG_NZVC },
1018   { "sbcb", "[],b->b",    "sbc8",    2, 0xe2,  3,  3,  CHG_NZVC },
1019 
1020   { "staa", "a->*",       "movtst8", 2, 0x5a,  2,  2,  CLR_V_CHG_NZ },
1021   { "staa", "a->()",      "movtst8", 3, 0x7a,  3,  3,  CLR_V_CHG_NZ },
1022   { "staa", "a->[]",      "movtst8", 2, 0x6a,  2,  2,  CLR_V_CHG_NZ },
1023 
1024   { "stab", "b->*",       "movtst8", 2, 0x5b,  2,  2,  CLR_V_CHG_NZ },
1025   { "stab", "b->()",      "movtst8", 3, 0x7b,  3,  3,  CLR_V_CHG_NZ },
1026   { "stab", "b->[]",      "movtst8", 2, 0x6b,  2,  2,  CLR_V_CHG_NZ },
1027 
1028   { "std",  "d->*",       "movtst16", 2, 0x5c,  2,  2,  CLR_V_CHG_NZ },
1029   { "std",  "d->()",      "movtst16", 3, 0x7c,  3,  3,  CLR_V_CHG_NZ },
1030   { "std",  "d->[]",      "movtst16", 2, 0x6c,  2,  2,  CLR_V_CHG_NZ },
1031 
1032   { "sts",  "sp->*",      "movtst16", 2, 0x5f,  2,  2,  CLR_V_CHG_NZ },
1033   { "sts",  "sp->()",     "movtst16", 3, 0x7f,  3,  3,  CLR_V_CHG_NZ },
1034   { "sts",  "sp->[]",     "movtst16", 2, 0x6f,  2,  2,  CLR_V_CHG_NZ },
1035 
1036   { "stx",  "x->*",       "movtst16", 2, 0x5e,  2,  2,  CLR_V_CHG_NZ },
1037   { "stx",  "x->()",      "movtst16", 3, 0x7e,  3,  3,  CLR_V_CHG_NZ },
1038   { "stx",  "x->[]",      "movtst16", 2, 0x6e,  2,  2,  CLR_V_CHG_NZ },
1039 
1040   { "sty",  "y->*",       "movtst16", 2, 0x5d,  2,  2,  CLR_V_CHG_NZ },
1041   { "sty",  "y->()",      "movtst16", 3, 0x7d,  3,  3,  CLR_V_CHG_NZ },
1042   { "sty",  "y->[]",      "movtst16", 2, 0x6d,  2,  2,  CLR_V_CHG_NZ },
1043 
1044   { "suba", "#,a->a",     "sub8",     2, 0x80,  1,  1,  CHG_NZVC },
1045   { "suba", "*,a->a",     "sub8",     2, 0x90,  3,  3,  CHG_NZVC },
1046   { "suba", "(),a->a",    "sub8",     3, 0xb0,  3,  3,  CHG_NZVC },
1047   { "suba", "[],a->a",    "sub8",     2, 0xa0,  3,  3,  CHG_NZVC },
1048 
1049   { "subb", "#,b->b",     "sub8",     2, 0xc0,  1,  1,  CHG_NZVC },
1050   { "subb", "*,b->b",     "sub8",     2, 0xd0,  3,  3,  CHG_NZVC },
1051   { "subb", "(),b->b",    "sub8",     3, 0xf0,  3,  3,  CHG_NZVC },
1052   { "subb", "[],b->b",    "sub8",     2, 0xe0,  3,  3,  CHG_NZVC },
1053 
1054   { "subd", "#,d->d",     "sub16",    3, 0x83,  2,  2,  CHG_NZVC },
1055   { "subd", "*,d->d",     "sub16",    2, 0x93,  3,  3,  CHG_NZVC },
1056   { "subd", "(),d->d",    "sub16",    3, 0xb3,  3,  3,  CHG_NZVC },
1057   { "subd", "[],d->d",    "sub16",    2, 0xa3,  3,  3,  CHG_NZVC },
1058 
1059   { "swi",  0,            0,          1, 0x3f,  9,  9,  CHG_NONE },
1060 
1061   { "tst",  "()",         "tst8",     3, 0xf7,  3,  3,  CLR_VC_CHG_NZ },
1062   { "tst",  "[]",         "tst8",     2, 0xe7,  3,  3,  CLR_VC_CHG_NZ },
1063 
1064   { "tsta", "a",          "tst8",     1, 0x97,  1,  1,  CLR_VC_CHG_NZ },
1065   { "tstb", "b",          "tst8",     1, 0xd7,  1,  1,  CLR_VC_CHG_NZ },
1066 
1067   { "wai",  0,            0,          1, 0x3e,  8,  _M, CHG_NONE }
1068 };
1069 
1070 struct m6811_opcode_def m6812_page2_opcodes[] = {
1071   { "cba",  "b,a",        "sub8",     2, 0x17,  2,  2,  CHG_NZVC },
1072 
1073   /* After 'daa', the Z flag is undefined. Mark it as changed.  */
1074   { "daa",  0,            "daa8",     2, 0x07,  3,  3,  CHG_NZVC },
1075 
1076   { "edivs", 0,           0,          2, 0x14,  12,  12,  CHG_NZVC },
1077   { "emacs", 0,           0,          2, 0x12,  13,  13,  CHG_NZVC },
1078 
1079   { "emaxd", "[],d->d",   "max16",    3, 0x1a,  4,  4,  CHG_NZVC },
1080   { "emaxm", "[],d->[]",  "max16",    3, 0x1e,  4,  4,  CHG_NZVC },
1081   { "emind", "[],d->d",   "min16",    3, 0x1b,  4,  4,  CHG_NZVC },
1082   { "eminm", "[],d->[]",  "min16",    3, 0x1f,  4,  4,  CHG_NZVC },
1083 
1084   { "emuls", 0,           0,          2, 0x13,  3,  3,  CHG_NZC },
1085   { "etbl",  "[]",        "tbl16",    3, 0x3f, 10, 10,  CHG_NZC },
1086   { "fdiv",  "x,d->x",    "fdiv16",   2, 0x11, 12, 12,  CHG_ZVC },
1087   { "idiv",  "x,d->x",    "idiv16",   2, 0x10, 12, 12,  CLR_V_CHG_ZC },
1088   { "idivs", 0,           0,          2, 0x15, 12, 12,  CHG_NZVC },
1089 
1090   { "lbcc",  "R",         "bcc",      4, 0x24,  3,  4,  CHG_NONE },
1091   { "lbcs",  "R",         "bcs",      4, 0x25,  3,  4,  CHG_NONE },
1092   { "lbeq",  "R",         "beq",      4, 0x27,  3,  4,  CHG_NONE },
1093   { "lbge",  "R",         "bge",      4, 0x2c,  3,  4,  CHG_NONE },
1094   { "lbgt",  "R",         "bgt",      4, 0x2e,  3,  4,  CHG_NONE },
1095   { "lbhi",  "R",         "bhi",      4, 0x22,  3,  4,  CHG_NONE },
1096   { "lble",  "R",         "ble",      4, 0x2f,  3,  4,  CHG_NONE },
1097   { "lbls",  "R",         "bls",      4, 0x23,  3,  4,  CHG_NONE },
1098   { "lblt",  "R",         "blt",      4, 0x2d,  3,  4,  CHG_NONE },
1099   { "lbmi",  "R",         "bmi",      4, 0x2b,  3,  4,  CHG_NONE },
1100   { "lbne",  "R",         "bne",      4, 0x26,  3,  4,  CHG_NONE },
1101   { "lbpl",  "R",         "bpl",      4, 0x2a,  3,  4,  CHG_NONE },
1102   { "lbra",  "R",         "bra",      4, 0x20,  4,  4,  CHG_NONE },
1103   { "lbrn",  "R",         "nop",      4, 0x21,  3,  3,  CHG_NONE },
1104   { "lbvc",  "R",         "bvc",      4, 0x28,  3,  4,  CHG_NONE },
1105   { "lbvs",  "R",         "bvs",      4, 0x29,  3,  4,  CHG_NONE },
1106 
1107   { "maxa",  "[],a->a",   "max8",     3, 0x18,  4,  4,  CHG_NZVC },
1108   { "maxm",  "[],a->[]",  "max8",     3, 0x1c,  4,  4,  CHG_NZVC },
1109   { "mina",  "[],a->a",   "min8",     3, 0x19,  4,  4,  CHG_NZVC },
1110   { "minm",  "[],a->[]",  "min8",     3, 0x1d,  4,  4,  CHG_NZVC },
1111 
1112   { "movb",  0,           "move8",    5, 0x0b,  4,  4,  CHG_NONE },
1113   { "movb",  0,           "move8",    4, 0x08,  4,  4,  CHG_NONE },
1114   { "movb",  0,           "move8",    6, 0x0c,  6,  6,  CHG_NONE },
1115   { "movb",  0,           "move8",    5, 0x09,  5,  5,  CHG_NONE },
1116   { "movb",  0,           "move8",    5, 0x0d,  5,  5,  CHG_NONE },
1117   { "movb",  0,           "move8",    4, 0x0a,  5,  5,  CHG_NONE },
1118 
1119   { "movw",  0,           "move16",   6, 0x03,  5,  5,  CHG_NONE },
1120   { "movw",  0,           "move16",   5, 0x00,  4,  4,  CHG_NONE },
1121   { "movw",  0,           "move16",   6, 0x04,  6,  6,  CHG_NONE },
1122   { "movw",  0,           "move16",   5, 0x01,  5,  5,  CHG_NONE },
1123   { "movw",  0,           "move16",   5, 0x05,  5,  5,  CHG_NONE },
1124   { "movw",  0,           "move16",   4, 0x02,  5,  5,  CHG_NONE },
1125 
1126   { "rev",  0,            0,          2, 0x3a,  _M, _M, CHG_HNZVC },
1127   { "revw", 0,            0,          2, 0x3b,  _M, _M, CHG_HNZVC },
1128   { "sba",  "b,a->a",     "sub8",     2, 0x16,  2,  2,  CHG_NZVC },
1129 
1130   { "stop", 0,            0,          2, 0x3e,  2,  9,  CHG_NONE },
1131 
1132   { "tab",  "a->b",       "movtst8",  2, 0x0e,  2,  2,  CLR_V_CHG_NZ },
1133   { "tba",  "b->a",       "movtst8",  2, 0x0f,  2,  2,  CLR_V_CHG_NZ },
1134 
1135   { "wav",  0,            0,          2, 0x3c,  8,  _M, SET_Z_CHG_HNVC }
1136 };
1137 
1138 void fatal_error (const struct m6811_opcode_def*, const char*, ...);
1139 void print (FILE*, int, const char*,...);
1140 int gen_fetch_operands (FILE*, int, const struct m6811_opcode_def*,
1141 			const char*);
1142 void gen_save_result (FILE*, int, const struct m6811_opcode_def*,
1143 		      int, const char*);
1144 const struct m6811_opcode_pattern*
1145 find_opcode_pattern (const struct m6811_opcode_def*);
1146 void gen_interp (FILE*, int, const struct m6811_opcode_def*);
1147 void gen_interpreter_for_table (FILE*, int,
1148 				const struct m6811_opcode_def*,
1149 				int, const char*);
1150 void gen_interpreter (FILE*);
1151 
1152 
1153 static int indent_level = 2;
1154 static int current_insn_size = 0;
1155 
1156 /* Fatal error message and exit.  This method is called when an inconsistency
1157    is detected in the generation table.	 */
1158 void
1159 fatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...)
1160 {
1161   va_list argp;
1162 
1163   fprintf (stderr, "Fatal error: ");
1164   va_start (argp, msg);
1165   vfprintf (stderr,  msg, argp);
1166   va_end (argp);
1167   fprintf (stderr, "\n");
1168   if (opcode)
1169     {
1170       fprintf (stderr, "Opcode: 0x%02x %s %s\n",
1171 	       opcode->insn_code,
1172 	       opcode->name ? opcode->name : "(null)",
1173 	       opcode->operands ? opcode->operands : "(null)");
1174     }
1175   exit (1);
1176 }
1177 
1178 
1179 /* Format and pretty print for the code generation.  (printf like format).  */
1180 void
1181 print (FILE *fp, int col, const char *msg, ...)
1182 {
1183   va_list argp;
1184   char buf[1024];
1185   int cur_col = -1;
1186   int i;
1187 
1188   /* Format in a buffer.  */
1189   va_start (argp, msg);
1190   vsprintf (buf, msg, argp);
1191   va_end (argp);
1192 
1193   /* Basic pretty print:
1194      - Every line is indented at column 'col',
1195      - Indentation is updated when '{' and '}' are found,
1196      - Indentation is incremented by the special character '@' (not displayed).
1197      - New lines inserted automatically after ';'  */
1198   for (i = 0; buf[i]; i++)
1199     {
1200       if (buf[i] == '{')
1201 	col += indent_level;
1202       else if (buf[i] == '}')
1203 	col -= indent_level;
1204       else if (buf[i] == '@')
1205 	{
1206 	  col += indent_level;
1207 	  continue;
1208 	}
1209       if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n')
1210 	{
1211 	  cur_col = 0;
1212 	  while (cur_col < col)
1213 	    {
1214 	      fputc (' ', fp);
1215 	      cur_col++;
1216 	    }
1217 	}
1218       if (buf[i] == '}')
1219 	col -= indent_level;
1220       else if (buf[i] == '{')
1221 	col += indent_level;
1222       else if (buf[i] == '\n')
1223 	cur_col = -1;
1224 
1225       if (cur_col != -1 || buf[i] == '\n')
1226 	fputc (buf[i], fp);
1227 
1228       if (buf[i] == ';')
1229 	{
1230 	  fputc ('\n', fp);
1231 	  cur_col = -1;
1232 	}
1233     }
1234 }
1235 
1236 
1237 /* Generate the code to obtain the operands before execution of the
1238    instruction.	 Operands are copied in local variables.  This allows to
1239    have the same instruction pattern and different operand formats.
1240    There is a maximum of 3 variables:
1241 
1242 		       8-bits	       16-bits
1243    1st operand:		src8		src16
1244    2nd operand:		dst8		dst16
1245    alt operand:		addr		addr
1246 
1247    The operand string is interpreted as follows:
1248 
1249    a	Copy A register in the local 8-bits variable.
1250    b	"    B "
1251    ccr	"    ccr "
1252    d	"    D "	"      "    16-bits variable.
1253    x	"    X "
1254    y	"    Y "
1255    sp	"    SP "
1256    pc   "    PC "
1257    *	68HC11 page0 memory pointer.
1258 	Get 8-bits page0 offset from program, set up 'addr' local
1259 	variable to refer to the location in page0.
1260 	Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1261    (x)	68HC11 indirect access with X register.
1262 	Get 8-bits unsigned offset from program, set up 'addr' = X + offset.
1263 	Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1264    (y)	Same as (x) with Y register.
1265    ()	68HC11 extended address mode (global variable).
1266 	Get 16-bits address from program and set 'addr'.
1267 	Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1268    []   68HC12 indexed addressing mode
1269    (sp) Pop
1270 	Pop a 8/16-bits value from stack and set in a 8/16-bits variable.
1271    r	Relative branch
1272 	Get 8-bits relative branch, compute absolute address and set 'addr'
1273    #	68HC11 immediate value
1274 	Get a 8/16-bits value from program and set a 8/16-bits variable.
1275    &(x)
1276    &(y)
1277    &()	Similar to (x), (y) and () except that we don't read the
1278 	value pointed to by 'addr' (ie, only 'addr' is setup). Used by jmp/jsr.
1279    &[]  Similar to [] but don't read the value pointed to by the address.
1280    ,	Operand separator.
1281    -	End of input operands.
1282 
1283    Example:
1284        (x),a->a	      addr = x + (uint16) (fetch8 (cpu));
1285 		      src8 = a
1286        *,#,r	      addr = (uint16) (fetch8 (cpu))  <- Temporary 'addr'
1287 		      src8 = read_mem8 (cpu, addr)
1288 		      dst8 = fetch8 (cpu)
1289 		      addr = fetch_relbranch (cpu)    <- Final 'addr'
1290 
1291    Returns 1 if the 'addr' operand is set, 0 otherwise.	 */
1292 int
1293 gen_fetch_operands (FILE *fp, int col,
1294 		    const struct m6811_opcode_def *opcode,
1295 		    const char *operand_size)
1296 {
1297   static char *vars[2] = {
1298     "src",
1299     "dst"
1300   };
1301   char c;
1302   int addr_set = 0;
1303   int cur_var = 0;
1304   const char *operands = opcode->operands;
1305 
1306   if (operands == 0)
1307     operands = "";
1308 
1309   while ((c = *operands++) != 0)
1310     {
1311       switch (c)
1312 	{
1313 	case 'a':
1314 	  if (cur_var >= 2)
1315 	    fatal_error (opcode, "Too many locals");
1316 
1317 	  print (fp, col, "%s8 = cpu_get_a (cpu);", vars[cur_var]);
1318 	  break;
1319 
1320 	case 'b':
1321 	  if (cur_var >= 2)
1322 	    fatal_error (opcode, "Too many locals");
1323 
1324 	  print (fp, col, "%s8 = cpu_get_b (cpu);", vars[cur_var]);
1325 	  break;
1326 
1327 	case 'd':
1328 	  if (cur_var >= 2)
1329 	    fatal_error (opcode, "Too many locals");
1330 
1331 	  print (fp, col, "%s16 = cpu_get_d (cpu);", vars[cur_var]);
1332 	  break;
1333 
1334 	case 'x':
1335 	  if (cur_var >= 2)
1336 	    fatal_error (opcode, "Too many locals");
1337 
1338 	  print (fp, col, "%s16 = cpu_get_x (cpu);", vars[cur_var]);
1339 	  break;
1340 
1341 	case 'y':
1342 	  if (cur_var >= 2)
1343 	    fatal_error (opcode, "Too many locals");
1344 
1345 	  print (fp, col, "%s16 = cpu_get_y (cpu);", vars[cur_var]);
1346 	  break;
1347 
1348 	case '*':
1349 	  if (cur_var >= 2)
1350 	    fatal_error (opcode, "Too many locals");
1351 
1352 	  if (addr_set)
1353 	    fatal_error (opcode, "Wrong use of '*', 'addr' already used");
1354 
1355 	  addr_set = 1;
1356 	  current_insn_size += 1;
1357 	  print (fp, col, "addr = (uint16) cpu_fetch8 (cpu);");
1358 	  print (fp, col, "%s%s = memory_read%s (cpu, addr);",
1359 		 vars[cur_var], operand_size, operand_size);
1360 	  break;
1361 
1362 	case '&':
1363 	  if (addr_set)
1364 	    fatal_error (opcode, "Wrong use of '&', 'addr' already used");
1365 
1366 	  addr_set = 1;
1367 	  if (strncmp (operands, "(x)", 3) == 0)
1368 	    {
1369 	      current_insn_size += 1;
1370 	      print (fp, col, "addr = cpu_get_x (cpu) + (uint16) cpu_fetch8 (cpu);");
1371 	      operands += 3;
1372 	    }
1373 	  else if (strncmp (operands, "(y)", 3) == 0)
1374 	    {
1375 	      current_insn_size += 1;
1376 	      print (fp, col, "addr = cpu_get_y (cpu) + (uint16) cpu_fetch8 (cpu);");
1377 	      operands += 3;
1378 	    }
1379 	  else if (strncmp (operands, "()", 2) == 0)
1380 	    {
1381 	      current_insn_size += 2;
1382 	      print (fp, col, "addr = cpu_fetch16 (cpu);");
1383 	      operands += 2;
1384 	    }
1385 	  else if (strncmp (operands, "[]", 2) == 0)
1386 	    {
1387 	      current_insn_size += 1;
1388 	      print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu, 0);");
1389 	      operands += 2;
1390 	    }
1391 	  else
1392 	    {
1393 	      fatal_error (opcode, "Unknown operand");
1394 	    }
1395 	  break;
1396 
1397 	case '(':
1398 	  if (cur_var >= 2)
1399 	    fatal_error (opcode, "Too many locals");
1400 
1401 	  if (addr_set)
1402 	    fatal_error (opcode, "Wrong use of '(', 'addr' already used");
1403 
1404 	  if (strncmp (operands, "x)", 2) == 0)
1405 	    {
1406 	      addr_set = 1;
1407 	      current_insn_size += 1;
1408 	      print (fp, col, "addr = cpu_get_x (cpu) + (uint16) cpu_fetch8 (cpu);");
1409 	      print (fp, col, "%s%s = memory_read%s (cpu, addr);",
1410 		     vars[cur_var], operand_size, operand_size);
1411 	      operands += 2;
1412 	    }
1413 	  else if (strncmp (operands, "y)", 2) == 0)
1414 	    {
1415 	      addr_set = 1;
1416 	      current_insn_size += 1;
1417 	      print (fp, col, "addr = cpu_get_y (cpu) + (uint16) cpu_fetch8 (cpu);");
1418 	      print (fp, col, "%s%s = memory_read%s (cpu, addr);",
1419 		     vars[cur_var], operand_size, operand_size);
1420 	      operands += 2;
1421 	    }
1422 	  else if (strncmp (operands, ")", 1) == 0)
1423 	    {
1424 	      addr_set = 1;
1425 	      current_insn_size += 2;
1426 	      print (fp, col, "addr = cpu_fetch16 (cpu);");
1427 	      print (fp, col, "%s%s = memory_read%s (cpu, addr);",
1428 		     vars[cur_var], operand_size, operand_size);
1429 	      operands++;
1430 	    }
1431 	  else if (strncmp (operands, "@)", 2) == 0)
1432 	    {
1433 	      current_insn_size += 2;
1434 	      print (fp, col, "addr = cpu_fetch16 (cpu);");
1435 	      print (fp, col, "%s%s = memory_read%s (cpu, addr);",
1436 		     vars[cur_var], operand_size, operand_size);
1437 	      operands += 2;
1438 	    }
1439 	  else if (strncmp (operands, "sp)", 3) == 0)
1440 	    {
1441 	      print (fp, col, "%s%s = cpu_%s_pop_uint%s (cpu);",
1442 		     vars[cur_var], operand_size,
1443                      cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1444                      operand_size);
1445 	      operands += 3;
1446 	    }
1447 	  else
1448 	    {
1449 	      fatal_error (opcode, "Unknown operand");
1450 	    }
1451 	  break;
1452 
1453 	case '[':
1454 	  if (cur_var >= 2)
1455 	    fatal_error (opcode, "Too many locals");
1456 
1457 	  if (addr_set)
1458 	    fatal_error (opcode, "Wrong use of '[', 'addr' already used");
1459 
1460 	  if (strncmp (operands, "]", 1) == 0)
1461 	    {
1462 	      addr_set = 1;
1463 	      current_insn_size += 1;
1464 	      print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu,0);");
1465 	      print (fp, col, "%s%s = memory_read%s (cpu, addr);",
1466 		     vars[cur_var], operand_size, operand_size);
1467 	      operands += 1;
1468 	    }
1469 #if 0 /* This code is never executed (see strncmp above), but it has not been
1470 	 removed because it may be that there is a typo in strncmp test below.  */
1471 	  else if (strncmp (operands, "]", 1) == 0)
1472 	    {
1473 	      current_insn_size += 1;
1474 	      print (fp, col, "%s%s = cpu_get_indexed_operand%s (cpu,0);",
1475 		     vars[cur_var], operand_size, operand_size);
1476 	      operands += 1;
1477 	    }
1478 #endif
1479 	  else
1480 	    {
1481 	      fatal_error (opcode, "Unknown operand");
1482 	    }
1483 	  break;
1484 
1485 	case '{':
1486 	  if (cur_var >= 2)
1487 	    fatal_error (opcode, "Too many locals");
1488 
1489 	  if (addr_set)
1490 	    fatal_error (opcode, "Wrong use of '{', 'addr' already used");
1491 
1492 	  if (strncmp (operands, "}", 1) == 0)
1493 	    {
1494 	      current_insn_size += 1;
1495 	      print (fp, col, "%s%s = cpu_get_indexed_operand%s (cpu, 1);",
1496 		     vars[cur_var], operand_size, operand_size);
1497 	      operands += 1;
1498 	    }
1499 	  else
1500 	    {
1501 	      fatal_error (opcode, "Unknown operand");
1502 	    }
1503 	  break;
1504 
1505 	case 's':
1506 	  if (cur_var >= 2)
1507 	    fatal_error (opcode, "Too many locals");
1508 
1509 	  if (strncmp (operands, "p", 1) == 0)
1510 	    {
1511 	      print (fp, col, "%s16 = cpu_get_sp (cpu);", vars[cur_var]);
1512 	      operands++;
1513 	    }
1514 	  else
1515 	    {
1516 	      fatal_error (opcode, "Unknown operands");
1517 	    }
1518 	  break;
1519 
1520 	case 'c':
1521 	  if (strncmp (operands, "cr", 2) == 0)
1522 	    {
1523 	      print (fp, col, "%s8 = cpu_get_ccr (cpu);", vars[cur_var]);
1524 	      operands += 2;
1525 	    }
1526 	  else
1527 	    {
1528 	      fatal_error (opcode, "Unknown operands");
1529 	    }
1530 	  break;
1531 
1532 	case 'r':
1533 	  if (addr_set && cur_var != 2)
1534 	    fatal_error (opcode, "Wrong use of 'r'");
1535 
1536 	  addr_set = 1;
1537 	  current_insn_size += 1;
1538 	  print (fp, col, "addr = cpu_fetch_relbranch (cpu);");
1539 	  break;
1540 
1541 	case 'R':
1542 	  if (addr_set && cur_var != 2)
1543 	    fatal_error (opcode, "Wrong use of 'R'");
1544 
1545 	  addr_set = 1;
1546 	  current_insn_size += 2;
1547 	  print (fp, col, "addr = cpu_fetch_relbranch16 (cpu);");
1548 	  break;
1549 
1550 	case '#':
1551 	  if (strcmp (operand_size, "8") == 0)
1552 	    {
1553 	      current_insn_size += 1;
1554 	    }
1555 	  else
1556 	    {
1557 	      current_insn_size += 2;
1558 	    }
1559 	  print (fp, col, "%s%s = cpu_fetch%s (cpu);", vars[cur_var],
1560 		 operand_size, operand_size);
1561 	  break;
1562 
1563 	case ',':
1564 	  cur_var ++;
1565 	  break;
1566 
1567 	case '-':
1568 	  return addr_set;
1569 
1570 	default:
1571 	  fatal_error (opcode, "Invalid operands");
1572 	  break;
1573 	}
1574     }
1575   return addr_set;
1576 }
1577 
1578 
1579 /* Generate the code to save the instruction result.  The result is in
1580    a local variable: either 'dst8' or 'dst16'.
1581    There may be only one result.  Instructions with 2 results (ie idiv
1582    and fdiv), take care of saving the first value.
1583 
1584    The operand string is the same as for 'gen_fetch_operands'.
1585    Everything before '->' is ignored.  If the '->' is not found, it
1586    is assumed that there is nothing to save.  After '->', the operand
1587    string is interpreted as follows:
1588 
1589    a	Save 'dst8' in A register
1590    b	"	       B "
1591    ccr	"	       CCR "
1592    d	"    'dst16'   D "
1593    x	"	       X "
1594    y	"	       Y "
1595    sp	"	       SP "
1596    *	68HC11 page0 memory pointer.
1597    (x)	68HC11 indirect access with X register.
1598    (y)	Same as (x) with Y register.
1599    ()	68HC11 extended address mode (global variable).
1600 	For these modes, if they were used as an input operand,
1601 	the 'addr' variable contains the address of memory where
1602 	the result must be saved.
1603 	If they were not used an input operand, 'addr' is computed
1604 	(as in gen_fetch_operands()), and the result is saved.
1605    []   68HC12 indexed indirect
1606    (sp) Push
1607 	Push the 8/16-bits result on the stack.	 */
1608 void
1609 gen_save_result (FILE *fp, int col,
1610 		 const struct m6811_opcode_def *opcode,
1611 		 int addr_set,
1612 		 const char *operand_size)
1613 {
1614   char c;
1615   const char *operands = opcode->operands;
1616 
1617   /* When the result is saved, 'result_size' is a string which
1618      indicates the size of the saved result ("8" or "16").  This
1619      is a sanity check with 'operand_size' to detect inconsistencies
1620      in the different tables.  */
1621   const char *result_size = 0;
1622 
1623   if (operands == 0)
1624     operands = "";
1625 
1626   operands = strchr (operands, '-');
1627   if (operands == 0)
1628     return;
1629 
1630   operands++;
1631   if (*operands++ != '>')
1632     {
1633       fatal_error (opcode, "Invalid operand");
1634     }
1635 
1636   c = *operands++;
1637   switch (c)
1638     {
1639     case 'a':
1640       result_size = "8";
1641       print (fp, col, "cpu_set_a (cpu, dst8);");
1642       break;
1643 
1644     case 'b':
1645       result_size = "8";
1646       print (fp, col, "cpu_set_b (cpu, dst8);");
1647       break;
1648 
1649     case 'd':
1650       result_size = "16";
1651       print (fp, col, "cpu_set_d (cpu, dst16);");
1652       break;
1653 
1654     case 'x':
1655       result_size = "16";
1656       print (fp, col, "cpu_set_x (cpu, dst16);");
1657       break;
1658 
1659     case 'y':
1660       result_size = "16";
1661       print (fp, col, "cpu_set_y (cpu, dst16);");
1662       break;
1663 
1664     case '*':
1665       if (addr_set == 0)
1666 	{
1667 	  current_insn_size += 1;
1668 	  print (fp, col, "addr = (uint16) cpu_fetch8 (cpu);");
1669 	}
1670       result_size = operand_size;
1671       print (fp, col, "memory_write%s (cpu, addr, dst%s);",
1672 	     operand_size, operand_size);
1673       break;
1674 
1675     case '(':
1676       if (strncmp (operands, "x)", 2) == 0)
1677 	{
1678 	  if (addr_set == 0)
1679 	    {
1680 	      current_insn_size += 1;
1681 	      print (fp, col, "addr = cpu_get_x (cpu) + cpu_fetch8 (cpu);");
1682 	    }
1683 	  print (fp, col, "memory_write%s (cpu, addr, dst%s);",
1684 		 operand_size, operand_size);
1685 	  operands += 2;
1686 	  result_size = operand_size;
1687 	}
1688       else if (strncmp (operands, "y)", 2) == 0)
1689 	{
1690 	  if (addr_set == 0)
1691 	    {
1692 	      current_insn_size += 1;
1693 	      print (fp, col, "addr = cpu_get_y (cpu) + cpu_fetch8 (cpu);");
1694 	    }
1695 	  print (fp, col, "memory_write%s (cpu, addr, dst%s);",
1696 		 operand_size, operand_size);
1697 	  operands += 2;
1698 	  result_size = operand_size;
1699 	}
1700       else if (strncmp (operands, ")", 1) == 0)
1701 	{
1702 	  if (addr_set == 0)
1703 	    {
1704 	      current_insn_size += 2;
1705 	      print (fp, col, "addr = cpu_fetch16 (cpu);");
1706 	    }
1707 	  print (fp, col, "memory_write%s (cpu, addr, dst%s);",
1708 		 operand_size, operand_size);
1709 	  operands++;
1710 	  result_size = operand_size;
1711 	}
1712       else if (strncmp (operands, "sp)", 3) == 0)
1713 	{
1714 	  print (fp, col, "cpu_%s_push_uint%s (cpu, dst%s);",
1715                  cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1716 		 operand_size, operand_size);
1717 	  operands += 3;
1718 	  result_size = operand_size;
1719 	}
1720       else
1721 	{
1722 	  fatal_error (opcode, "Invalid operand");
1723 	}
1724       break;
1725 
1726     case '[':
1727       if (strncmp (operands, "]", 1) == 0)
1728 	{
1729 	  if (addr_set == 0)
1730 	    {
1731 	      current_insn_size += 1;
1732 	      print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu,0);");
1733 	    }
1734 	  print (fp, col, "memory_write%s (cpu, addr, dst%s);",
1735 		 operand_size, operand_size);
1736 	  operands++;
1737 	  result_size = operand_size;
1738 	}
1739       else
1740 	{
1741 	  fatal_error (opcode, "Invalid operand");
1742 	}
1743       break;
1744 
1745     case '{':
1746       if (strncmp (operands, "}", 1) == 0)
1747 	{
1748 	  current_insn_size += 1;
1749 	  print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu, 1);");
1750 	  print (fp, col, "memory_write%s (cpu, addr, dst%s);",
1751 		 operand_size, operand_size);
1752 	  operands++;
1753 	  result_size = operand_size;
1754 	}
1755       else
1756 	{
1757 	  fatal_error (opcode, "Invalid operand");
1758 	}
1759       break;
1760 
1761     case 's':
1762       if (strncmp (operands, "p", 1) == 0)
1763 	{
1764 	  print (fp, col, "cpu_set_sp (cpu, dst16);");
1765 	  operands++;
1766 	  result_size = "16";
1767 	}
1768       else
1769 	{
1770 	  fatal_error (opcode, "Invalid operand");
1771 	}
1772       break;
1773 
1774     case 'c':
1775       if (strncmp (operands, "cr", 2) == 0)
1776 	{
1777 	  print (fp, col, "cpu_set_ccr (cpu, dst8);");
1778 	  operands += 2;
1779 	  result_size = "8";
1780 	}
1781       else
1782 	{
1783 	  fatal_error (opcode, "Invalid operand");
1784 	}
1785       break;
1786 
1787     default:
1788       fatal_error (opcode, "Invalid operand");
1789       break;
1790     }
1791 
1792   if (*operands != 0)
1793     fatal_error (opcode, "Garbage at end of operand");
1794 
1795   if (result_size == 0)
1796     fatal_error (opcode, "? No result seems to be saved");
1797 
1798   if (strcmp (result_size, operand_size) != 0)
1799     fatal_error (opcode, "Result saved different than pattern size");
1800 }
1801 
1802 
1803 /* Find the instruction pattern for a given instruction.  */
1804 const struct m6811_opcode_pattern*
1805 find_opcode_pattern (const struct m6811_opcode_def *opcode)
1806 {
1807   int i;
1808   const char *pattern = opcode->insn_pattern;
1809 
1810   if (pattern == 0)
1811     {
1812       pattern = opcode->name;
1813     }
1814   for (i = 0; i < ARRAY_SIZE (m6811_opcode_patterns); i++)
1815     {
1816       if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
1817 	{
1818 	  return &m6811_opcode_patterns[i];
1819 	}
1820     }
1821   fatal_error (opcode, "Unknown instruction pattern");
1822   return 0;
1823 }
1824 
1825 /* Generate the code for interpretation of instruction 'opcode'.  */
1826 void
1827 gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
1828 {
1829   const char *operands = opcode->operands;
1830   int addr_set;
1831   const char *pattern = opcode->insn_pattern;
1832   const struct m6811_opcode_pattern *op;
1833   const char *operand_size;
1834 
1835   if (pattern == 0)
1836     {
1837       pattern = opcode->name;
1838     }
1839 
1840   /* Find out the size of the operands: 8 or 16-bits.  */
1841   if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
1842     {
1843       operand_size = "8";
1844     }
1845   else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
1846     {
1847       operand_size = "16";
1848     }
1849   else
1850     {
1851       operand_size = "";
1852     }
1853 
1854   if (operands == 0)
1855     operands = "";
1856 
1857   /* Generate entry point for the instruction.	*/
1858   print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
1859 	 opcode->name, operands);
1860   col += indent_level;
1861 
1862   /* Generate the code to get the instruction operands.	 */
1863   addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
1864 
1865   /* Generate instruction interpretation.  */
1866   op = find_opcode_pattern (opcode);
1867   if (op->pattern)
1868     {
1869       print (fp, col, "%s;", op->pattern);
1870     }
1871 
1872   /* Generate the code to save the result.  */
1873   gen_save_result (fp, col, opcode, addr_set, operand_size);
1874 
1875   /* For some instructions, generate the code to update the flags.  */
1876   if (op && op->ccr_update)
1877     {
1878       print (fp, col, "%s;", op->ccr_update);
1879     }
1880   print (fp, col, "break;");
1881 }
1882 
1883 
1884 /* Generate the interpretor for a given 68HC11 page set.  */
1885 void
1886 gen_interpreter_for_table (FILE *fp, int col,
1887 			   const struct m6811_opcode_def *table,
1888 			   int size,
1889 			   const char *cycles_table_name)
1890 {
1891   int i;
1892   int init_size;
1893 
1894   init_size = table == m6811_page1_opcodes
1895     || table == m6812_page1_opcodes? 1 : 2;
1896 
1897   /* Get the opcode and dispatch directly.  */
1898   print (fp, col, "op = cpu_fetch8 (cpu);");
1899   print (fp, col, "cpu_add_cycles (cpu, %s[op]);", cycles_table_name);
1900 
1901   print (fp, col, "switch (op)\n");
1902   col += indent_level;
1903   print (fp, col, "{\n");
1904 
1905   for (i = 0; i < size; i++)
1906     {
1907       /* The table contains duplicate entries (ie, instruction aliases).  */
1908       if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
1909 	continue;
1910 
1911       current_insn_size = init_size;
1912       gen_interp (fp, col, &table[i]);
1913 #if 0
1914       if (current_insn_size != table[i].insn_size)
1915 	{
1916 	  fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
1917 		       current_insn_size, table[i].insn_size);
1918 	}
1919 #endif
1920     }
1921 
1922   print (fp, col, "default:\n");
1923   print (fp, col + indent_level, "cpu_special (cpu, M6811_ILLEGAL);");
1924   print (fp, col + indent_level, "break;");
1925   print (fp, col, "}\n");
1926 }
1927 
1928 /* Generate the table of instruction cycle.  These tables are indexed
1929    by the opcode number to allow a fast cycle time computation.	 */
1930 void
1931 gen_cycle_table (FILE *fp, const char *name,
1932 		 const struct m6811_opcode_def *table,
1933 		 int size)
1934 {
1935   int i;
1936   char cycles[256];
1937   int page1;
1938 
1939   page1 = table == m6811_page1_opcodes;
1940 
1941   /* Build the cycles table.  The table is indexed by the opcode.  */
1942   memset (cycles, 0, sizeof (cycles));
1943   while (--size >= 0)
1944     {
1945       if (table->insn_min_cycles > table->insn_max_cycles)
1946 	fatal_error (table, "Wrong insn cycles");
1947 
1948       if (table->insn_max_cycles == _M)
1949 	cycles[table->insn_code] = table->insn_min_cycles;
1950       else
1951 	cycles[table->insn_code] = table->insn_max_cycles;
1952 
1953       table++;
1954     }
1955 
1956   /* Some check: for the page1 opcode, the cycle type of the page2/3/4
1957      opcode must be 0.	*/
1958   if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
1959 		|| cycles[M6811_OPCODE_PAGE3] != 0
1960 		|| cycles[M6811_OPCODE_PAGE4] != 0))
1961       fatal_error (0, "Invalid cycle table");
1962 
1963   /* Generates the cycles table.  */
1964   print (fp, 0, "static const unsigned char %s[256] = {\n", name);
1965   for (i = 0; i < 256; i++)
1966     {
1967       if ((i % 16) == 0)
1968 	{
1969 	  print (fp, indent_level, "/* %3d */ ", i);
1970 	}
1971       fprintf (fp, "%2d", cycles[i]);
1972       if (i != 255)
1973 	fprintf (fp, ",");
1974 
1975       if ((i % 16) != 15)
1976 	fprintf (fp, " ");
1977       else
1978 	fprintf (fp, "\n");
1979     }
1980   print (fp, 0, "};\n\n");
1981 }
1982 
1983 #define USE_SRC8 1
1984 #define USE_DST8 2
1985 
1986 void
1987 gen_function_entry (FILE *fp, const char *name, int locals)
1988 {
1989   /* Generate interpretor entry point.	*/
1990   print (fp, 0, "%s (sim_cpu *cpu)\n", name);
1991   print (fp, indent_level, "{\n");
1992 
1993   /* Interpretor local variables.  */
1994   print (fp, indent_level, "unsigned char op;");
1995   print (fp, indent_level, "uint16 addr, src16, dst16;");
1996   if (locals & USE_SRC8)
1997     print (fp, indent_level, "uint8 src8;\n");
1998   if (locals & USE_DST8)
1999     print (fp, indent_level, "uint8 dst8;\n");
2000 }
2001 
2002 void
2003 gen_function_close (FILE *fp)
2004 {
2005   print (fp, 0, "}\n");
2006 }
2007 
2008 int
2009 cmp_opcode (const void *e1, const void *e2)
2010 {
2011   struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
2012   struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
2013 
2014   return (int) (op1->insn_code) - (int) (op2->insn_code);
2015 }
2016 
2017 void
2018 prepare_table (struct m6811_opcode_def* table, int size)
2019 {
2020   int i;
2021 
2022   qsort (table, size, sizeof (table[0]), cmp_opcode);
2023   for (i = 1; i < size; i++)
2024     {
2025       if (table[i].insn_code == table[i-1].insn_code)
2026 	{
2027 	  fprintf (stderr, "Two insns with code 0x%02x\n",
2028 		   table[i].insn_code);
2029 	}
2030     }
2031 }
2032 
2033 void
2034 gen_interpreter (FILE *fp)
2035 {
2036   int col = 0;
2037 
2038   prepare_table (m6811_page1_opcodes, ARRAY_SIZE (m6811_page1_opcodes));
2039   prepare_table (m6811_page2_opcodes, ARRAY_SIZE (m6811_page2_opcodes));
2040   prepare_table (m6811_page3_opcodes, ARRAY_SIZE (m6811_page3_opcodes));
2041   prepare_table (m6811_page4_opcodes, ARRAY_SIZE (m6811_page4_opcodes));
2042 
2043   prepare_table (m6812_page1_opcodes, ARRAY_SIZE (m6812_page1_opcodes));
2044   prepare_table (m6812_page2_opcodes, ARRAY_SIZE (m6812_page2_opcodes));
2045 
2046   /* Generate header of interpretor.  */
2047   print (fp, col, "/* File generated automatically by gencode. */\n");
2048   print (fp, col, "#include \"sim-main.h\"\n\n");
2049 
2050   if (cpu_type & cpu6811)
2051     {
2052       gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
2053 		       ARRAY_SIZE (m6811_page1_opcodes));
2054       gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
2055 		       ARRAY_SIZE (m6811_page2_opcodes));
2056       gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
2057 		       ARRAY_SIZE (m6811_page3_opcodes));
2058       gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
2059 		       ARRAY_SIZE (m6811_page4_opcodes));
2060 
2061       gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
2062       gen_interpreter_for_table (fp, indent_level,
2063 				 m6811_page3_opcodes,
2064 				 ARRAY_SIZE (m6811_page3_opcodes),
2065 				 "cycles_page3");
2066       gen_function_close (fp);
2067 
2068       gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
2069       gen_interpreter_for_table (fp, indent_level,
2070 				 m6811_page4_opcodes,
2071 				 ARRAY_SIZE (m6811_page4_opcodes),
2072 				 "cycles_page4");
2073       gen_function_close (fp);
2074 
2075       /* Generate the page 2, 3 and 4 handlers.  */
2076       gen_function_entry (fp, "static void\ncpu_page2_interp",
2077                           USE_SRC8 | USE_DST8);
2078       gen_interpreter_for_table (fp, indent_level,
2079 				 m6811_page2_opcodes,
2080 				 ARRAY_SIZE (m6811_page2_opcodes),
2081 				 "cycles_page2");
2082       gen_function_close (fp);
2083 
2084       /* Generate the interpretor entry point.  */
2085       gen_function_entry (fp, "void\ncpu_interp_m6811",
2086                           USE_SRC8 | USE_DST8);
2087 
2088       gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
2089 				 ARRAY_SIZE (m6811_page1_opcodes),
2090 				 "cycles_page1");
2091       gen_function_close (fp);
2092     }
2093   else
2094     {
2095       gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
2096 		       ARRAY_SIZE (m6812_page1_opcodes));
2097       gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
2098 		       ARRAY_SIZE (m6812_page2_opcodes));
2099 
2100       gen_function_entry (fp, "static void\ncpu_page2_interp",
2101                           USE_SRC8 | USE_DST8);
2102       gen_interpreter_for_table (fp, indent_level,
2103 				 m6812_page2_opcodes,
2104 				 ARRAY_SIZE (m6812_page2_opcodes),
2105 				 "cycles_page2");
2106       gen_function_close (fp);
2107 
2108       /* Generate the interpretor entry point.  */
2109       gen_function_entry (fp, "void\ncpu_interp_m6812",
2110                           USE_SRC8 | USE_DST8);
2111 
2112       gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
2113 				 ARRAY_SIZE (m6812_page1_opcodes),
2114 				 "cycles_page1");
2115       gen_function_close (fp);
2116     }
2117 }
2118 
2119 void
2120 usage (char* prog)
2121 {
2122   fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
2123   exit (2);
2124 }
2125 
2126 int
2127 main (int argc, char *argv[])
2128 {
2129   int i;
2130 
2131   for (i = 1; i < argc; i++)
2132     {
2133       if (strcmp (argv[i], "-m6811") == 0)
2134 	cpu_type = cpu6811;
2135       else if (strcmp (argv[i], "-m6812") == 0)
2136 	cpu_type = cpu6812;
2137       else
2138 	{
2139 	  usage (argv[0]);
2140 	}
2141     }
2142   if (cpu_type == 0)
2143     usage (argv[0]);
2144 
2145   gen_interpreter (stdout);
2146   if (fclose (stdout) != 0)
2147     {
2148       fprintf (stderr, "Error while generating the interpreter: %d\n",
2149 	       errno);
2150       return 1;
2151     }
2152   return 0;
2153 }
2154