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