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