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