]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m68hc11/gencode.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / sim / m68hc11 / gencode.c
CommitLineData
81e09ed8 1/* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
1d506c26 2 Copyright 1999-2024 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 */
f64e47a2 92static struct m6811_opcode_pattern m6811_opcode_patterns[] = {
e0709f50
AC
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 */
f64e47a2 361static struct 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 */
f64e47a2 615static struct 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 */
f64e47a2 690static struct 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 */
f64e47a2 708static struct 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 */
f64e47a2 724static struct m6811_opcode_def m6812_page1_opcodes[] = {
81e09ed8
SC
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
f64e47a2 1073static struct m6811_opcode_def m6812_page2_opcodes[] = {
81e09ed8
SC
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
e0709f50
AC
1141
1142static int indent_level = 2;
1143static int current_insn_size = 0;
1144
1145/* Fatal error message and exit. This method is called when an inconsistency
1146 is detected in the generation table. */
c6352113 1147ATTRIBUTE_PRINTF_2
f64e47a2 1148static void
81e09ed8 1149fatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...)
e0709f50 1150{
81e09ed8
SC
1151 va_list argp;
1152
1153 fprintf (stderr, "Fatal error: ");
1154 va_start (argp, msg);
1155 vfprintf (stderr, msg, argp);
1156 va_end (argp);
1157 fprintf (stderr, "\n");
e0709f50
AC
1158 if (opcode)
1159 {
1160 fprintf (stderr, "Opcode: 0x%02x %s %s\n",
81e09ed8
SC
1161 opcode->insn_code,
1162 opcode->name ? opcode->name : "(null)",
1163 opcode->operands ? opcode->operands : "(null)");
e0709f50
AC
1164 }
1165 exit (1);
1166}
1167
1168
1169/* Format and pretty print for the code generation. (printf like format). */
c6352113 1170ATTRIBUTE_PRINTF_3
f64e47a2 1171static void
e0709f50
AC
1172print (FILE *fp, int col, const char *msg, ...)
1173{
1174 va_list argp;
1175 char buf[1024];
1176 int cur_col = -1;
1177 int i;
1178
1179 /* Format in a buffer. */
1180 va_start (argp, msg);
1181 vsprintf (buf, msg, argp);
1182 va_end (argp);
1183
1184 /* Basic pretty print:
1185 - Every line is indented at column 'col',
1186 - Indentation is updated when '{' and '}' are found,
1187 - Indentation is incremented by the special character '@' (not displayed).
1188 - New lines inserted automatically after ';' */
1189 for (i = 0; buf[i]; i++)
1190 {
1191 if (buf[i] == '{')
1192 col += indent_level;
1193 else if (buf[i] == '}')
1194 col -= indent_level;
1195 else if (buf[i] == '@')
1196 {
1197 col += indent_level;
1198 continue;
1199 }
1200 if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n')
1201 {
1202 cur_col = 0;
1203 while (cur_col < col)
1204 {
1205 fputc (' ', fp);
1206 cur_col++;
1207 }
1208 }
1209 if (buf[i] == '}')
1210 col -= indent_level;
1211 else if (buf[i] == '{')
1212 col += indent_level;
1213 else if (buf[i] == '\n')
1214 cur_col = -1;
1215
1216 if (cur_col != -1 || buf[i] == '\n')
1217 fputc (buf[i], fp);
1218
1219 if (buf[i] == ';')
1220 {
1221 fputc ('\n', fp);
1222 cur_col = -1;
1223 }
1224 }
1225}
1226
1227
1228/* Generate the code to obtain the operands before execution of the
1229 instruction. Operands are copied in local variables. This allows to
1230 have the same instruction pattern and different operand formats.
1231 There is a maximum of 3 variables:
1232
1233 8-bits 16-bits
1234 1st operand: src8 src16
1235 2nd operand: dst8 dst16
1236 alt operand: addr addr
1237
1238 The operand string is interpreted as follows:
1239
1240 a Copy A register in the local 8-bits variable.
1241 b " B "
1242 ccr " ccr "
1243 d " D " " " 16-bits variable.
1244 x " X "
1245 y " Y "
1246 sp " SP "
81e09ed8 1247 pc " PC "
e0709f50
AC
1248 * 68HC11 page0 memory pointer.
1249 Get 8-bits page0 offset from program, set up 'addr' local
1250 variable to refer to the location in page0.
1251 Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1252 (x) 68HC11 indirect access with X register.
1253 Get 8-bits unsigned offset from program, set up 'addr' = X + offset.
1254 Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
1255 (y) Same as (x) with Y register.
1256 () 68HC11 extended address mode (global variable).
1257 Get 16-bits address from program and set 'addr'.
1258 Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
81e09ed8 1259 [] 68HC12 indexed addressing mode
e0709f50
AC
1260 (sp) Pop
1261 Pop a 8/16-bits value from stack and set in a 8/16-bits variable.
1262 r Relative branch
1263 Get 8-bits relative branch, compute absolute address and set 'addr'
1264 # 68HC11 immediate value
1265 Get a 8/16-bits value from program and set a 8/16-bits variable.
1266 &(x)
1267 &(y)
1268 &() Similar to (x), (y) and () except that we don't read the
1269 value pointed to by 'addr' (ie, only 'addr' is setup). Used by jmp/jsr.
81e09ed8 1270 &[] Similar to [] but don't read the value pointed to by the address.
e0709f50
AC
1271 , Operand separator.
1272 - End of input operands.
1273
1274 Example:
7606e1a3 1275 (x),a->a addr = x + (uint16_t) (fetch8 (cpu));
e0709f50 1276 src8 = a
7606e1a3 1277 *,#,r addr = (uint16_t) (fetch8 (cpu)) <- Temporary 'addr'
6f64fd48
MF
1278 src8 = read_mem8 (cpu, addr)
1279 dst8 = fetch8 (cpu)
1280 addr = fetch_relbranch (cpu) <- Final 'addr'
e0709f50
AC
1281
1282 Returns 1 if the 'addr' operand is set, 0 otherwise. */
f64e47a2 1283static int
e0709f50
AC
1284gen_fetch_operands (FILE *fp, int col,
1285 const struct m6811_opcode_def *opcode,
1286 const char *operand_size)
1287{
1288 static char *vars[2] = {
1289 "src",
1290 "dst"
1291 };
1292 char c;
1293 int addr_set = 0;
1294 int cur_var = 0;
1295 const char *operands = opcode->operands;
1296
1297 if (operands == 0)
1298 operands = "";
1299
1300 while ((c = *operands++) != 0)
1301 {
1302 switch (c)
1303 {
1304 case 'a':
1305 if (cur_var >= 2)
1306 fatal_error (opcode, "Too many locals");
1307
6f64fd48 1308 print (fp, col, "%s8 = cpu_get_a (cpu);", vars[cur_var]);
e0709f50
AC
1309 break;
1310
1311 case 'b':
1312 if (cur_var >= 2)
1313 fatal_error (opcode, "Too many locals");
1314
6f64fd48 1315 print (fp, col, "%s8 = cpu_get_b (cpu);", vars[cur_var]);
e0709f50
AC
1316 break;
1317
1318 case 'd':
1319 if (cur_var >= 2)
1320 fatal_error (opcode, "Too many locals");
1321
6f64fd48 1322 print (fp, col, "%s16 = cpu_get_d (cpu);", vars[cur_var]);
e0709f50
AC
1323 break;
1324
1325 case 'x':
1326 if (cur_var >= 2)
1327 fatal_error (opcode, "Too many locals");
1328
6f64fd48 1329 print (fp, col, "%s16 = cpu_get_x (cpu);", vars[cur_var]);
e0709f50
AC
1330 break;
1331
1332 case 'y':
1333 if (cur_var >= 2)
1334 fatal_error (opcode, "Too many locals");
1335
6f64fd48 1336 print (fp, col, "%s16 = cpu_get_y (cpu);", vars[cur_var]);
e0709f50
AC
1337 break;
1338
1339 case '*':
1340 if (cur_var >= 2)
1341 fatal_error (opcode, "Too many locals");
1342
1343 if (addr_set)
1344 fatal_error (opcode, "Wrong use of '*', 'addr' already used");
1345
1346 addr_set = 1;
1347 current_insn_size += 1;
7606e1a3 1348 print (fp, col, "addr = (uint16_t) cpu_fetch8 (cpu);");
6f64fd48 1349 print (fp, col, "%s%s = memory_read%s (cpu, addr);",
e0709f50
AC
1350 vars[cur_var], operand_size, operand_size);
1351 break;
1352
1353 case '&':
1354 if (addr_set)
1355 fatal_error (opcode, "Wrong use of '&', 'addr' already used");
1356
1357 addr_set = 1;
1358 if (strncmp (operands, "(x)", 3) == 0)
1359 {
1360 current_insn_size += 1;
7606e1a3 1361 print (fp, col, "addr = cpu_get_x (cpu) + (uint16_t) cpu_fetch8 (cpu);");
e0709f50
AC
1362 operands += 3;
1363 }
1364 else if (strncmp (operands, "(y)", 3) == 0)
1365 {
1366 current_insn_size += 1;
7606e1a3 1367 print (fp, col, "addr = cpu_get_y (cpu) + (uint16_t) cpu_fetch8 (cpu);");
e0709f50
AC
1368 operands += 3;
1369 }
1370 else if (strncmp (operands, "()", 2) == 0)
1371 {
1372 current_insn_size += 2;
6f64fd48 1373 print (fp, col, "addr = cpu_fetch16 (cpu);");
e0709f50
AC
1374 operands += 2;
1375 }
81e09ed8
SC
1376 else if (strncmp (operands, "[]", 2) == 0)
1377 {
1378 current_insn_size += 1;
6f64fd48 1379 print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu, 0);");
81e09ed8
SC
1380 operands += 2;
1381 }
e0709f50
AC
1382 else
1383 {
1384 fatal_error (opcode, "Unknown operand");
1385 }
1386 break;
1387
1388 case '(':
1389 if (cur_var >= 2)
1390 fatal_error (opcode, "Too many locals");
1391
1392 if (addr_set)
1393 fatal_error (opcode, "Wrong use of '(', 'addr' already used");
1394
1395 if (strncmp (operands, "x)", 2) == 0)
1396 {
1397 addr_set = 1;
1398 current_insn_size += 1;
7606e1a3 1399 print (fp, col, "addr = cpu_get_x (cpu) + (uint16_t) cpu_fetch8 (cpu);");
6f64fd48 1400 print (fp, col, "%s%s = memory_read%s (cpu, addr);",
e0709f50
AC
1401 vars[cur_var], operand_size, operand_size);
1402 operands += 2;
1403 }
1404 else if (strncmp (operands, "y)", 2) == 0)
1405 {
1406 addr_set = 1;
1407 current_insn_size += 1;
7606e1a3 1408 print (fp, col, "addr = cpu_get_y (cpu) + (uint16_t) cpu_fetch8 (cpu);");
6f64fd48 1409 print (fp, col, "%s%s = memory_read%s (cpu, addr);",
e0709f50
AC
1410 vars[cur_var], operand_size, operand_size);
1411 operands += 2;
1412 }
1413 else if (strncmp (operands, ")", 1) == 0)
1414 {
1415 addr_set = 1;
1416 current_insn_size += 2;
6f64fd48
MF
1417 print (fp, col, "addr = cpu_fetch16 (cpu);");
1418 print (fp, col, "%s%s = memory_read%s (cpu, addr);",
e0709f50
AC
1419 vars[cur_var], operand_size, operand_size);
1420 operands++;
1421 }
81e09ed8 1422 else if (strncmp (operands, "@)", 2) == 0)
e0709f50 1423 {
81e09ed8 1424 current_insn_size += 2;
6f64fd48
MF
1425 print (fp, col, "addr = cpu_fetch16 (cpu);");
1426 print (fp, col, "%s%s = memory_read%s (cpu, addr);",
e0709f50 1427 vars[cur_var], operand_size, operand_size);
81e09ed8
SC
1428 operands += 2;
1429 }
1430 else if (strncmp (operands, "sp)", 3) == 0)
1431 {
6f64fd48 1432 print (fp, col, "%s%s = cpu_%s_pop_uint%s (cpu);",
81e09ed8
SC
1433 vars[cur_var], operand_size,
1434 cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
1435 operand_size);
e0709f50
AC
1436 operands += 3;
1437 }
1438 else
1439 {
1440 fatal_error (opcode, "Unknown operand");
1441 }
1442 break;
1443
81e09ed8
SC
1444 case '[':
1445 if (cur_var >= 2)
1446 fatal_error (opcode, "Too many locals");
1447
1448 if (addr_set)
1449 fatal_error (opcode, "Wrong use of '[', 'addr' already used");
1450
1451 if (strncmp (operands, "]", 1) == 0)
1452 {
1453 addr_set = 1;
1454 current_insn_size += 1;
6f64fd48
MF
1455 print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu,0);");
1456 print (fp, col, "%s%s = memory_read%s (cpu, addr);",
81e09ed8
SC
1457 vars[cur_var], operand_size, operand_size);
1458 operands += 1;
1459 }
0a13382c
NC
1460#if 0 /* This code is never executed (see strncmp above), but it has not been
1461 removed because it may be that there is a typo in strncmp test below. */
81e09ed8
SC
1462 else if (strncmp (operands, "]", 1) == 0)
1463 {
1464 current_insn_size += 1;
6f64fd48 1465 print (fp, col, "%s%s = cpu_get_indexed_operand%s (cpu,0);",
81e09ed8
SC
1466 vars[cur_var], operand_size, operand_size);
1467 operands += 1;
1468 }
0a13382c 1469#endif
81e09ed8
SC
1470 else
1471 {
1472 fatal_error (opcode, "Unknown operand");
1473 }
1474 break;
1475
1476 case '{':
1477 if (cur_var >= 2)
1478 fatal_error (opcode, "Too many locals");
1479
1480 if (addr_set)
1481 fatal_error (opcode, "Wrong use of '{', 'addr' already used");
1482
1483 if (strncmp (operands, "}", 1) == 0)
1484 {
1485 current_insn_size += 1;
6f64fd48 1486 print (fp, col, "%s%s = cpu_get_indexed_operand%s (cpu, 1);",
81e09ed8
SC
1487 vars[cur_var], operand_size, operand_size);
1488 operands += 1;
1489 }
1490 else
1491 {
1492 fatal_error (opcode, "Unknown operand");
1493 }
1494 break;
1495
e0709f50
AC
1496 case 's':
1497 if (cur_var >= 2)
1498 fatal_error (opcode, "Too many locals");
1499
1500 if (strncmp (operands, "p", 1) == 0)
1501 {
6f64fd48 1502 print (fp, col, "%s16 = cpu_get_sp (cpu);", vars[cur_var]);
e0709f50
AC
1503 operands++;
1504 }
1505 else
1506 {
1507 fatal_error (opcode, "Unknown operands");
1508 }
1509 break;
1510
1511 case 'c':
1512 if (strncmp (operands, "cr", 2) == 0)
1513 {
6f64fd48 1514 print (fp, col, "%s8 = cpu_get_ccr (cpu);", vars[cur_var]);
e0709f50
AC
1515 operands += 2;
1516 }
1517 else
1518 {
1519 fatal_error (opcode, "Unknown operands");
1520 }
1521 break;
1522
1523 case 'r':
1524 if (addr_set && cur_var != 2)
1525 fatal_error (opcode, "Wrong use of 'r'");
1526
1527 addr_set = 1;
1528 current_insn_size += 1;
6f64fd48 1529 print (fp, col, "addr = cpu_fetch_relbranch (cpu);");
e0709f50
AC
1530 break;
1531
81e09ed8
SC
1532 case 'R':
1533 if (addr_set && cur_var != 2)
1534 fatal_error (opcode, "Wrong use of 'R'");
1535
1536 addr_set = 1;
1537 current_insn_size += 2;
6f64fd48 1538 print (fp, col, "addr = cpu_fetch_relbranch16 (cpu);");
81e09ed8
SC
1539 break;
1540
e0709f50
AC
1541 case '#':
1542 if (strcmp (operand_size, "8") == 0)
1543 {
1544 current_insn_size += 1;
1545 }
1546 else
1547 {
1548 current_insn_size += 2;
1549 }
6f64fd48 1550 print (fp, col, "%s%s = cpu_fetch%s (cpu);", vars[cur_var],
e0709f50
AC
1551 operand_size, operand_size);
1552 break;
1553
1554 case ',':
1555 cur_var ++;
1556 break;
1557
1558 case '-':
1559 return addr_set;
1560
1561 default:
1562 fatal_error (opcode, "Invalid operands");
1563 break;
1564 }
1565 }
1566 return addr_set;
1567}
1568
1569
1570/* Generate the code to save the instruction result. The result is in
1571 a local variable: either 'dst8' or 'dst16'.
1572 There may be only one result. Instructions with 2 results (ie idiv
1573 and fdiv), take care of saving the first value.
1574
1575 The operand string is the same as for 'gen_fetch_operands'.
1576 Everything before '->' is ignored. If the '->' is not found, it
1577 is assumed that there is nothing to save. After '->', the operand
1578 string is interpreted as follows:
1579
1580 a Save 'dst8' in A register
1581 b " B "
1582 ccr " CCR "
1583 d " 'dst16' D "
1584 x " X "
1585 y " Y "
1586 sp " SP "
1587 * 68HC11 page0 memory pointer.
1588 (x) 68HC11 indirect access with X register.
1589 (y) Same as (x) with Y register.
1590 () 68HC11 extended address mode (global variable).
1591 For these modes, if they were used as an input operand,
1592 the 'addr' variable contains the address of memory where
1593 the result must be saved.
1594 If they were not used an input operand, 'addr' is computed
1595 (as in gen_fetch_operands()), and the result is saved.
81e09ed8 1596 [] 68HC12 indexed indirect
e0709f50
AC
1597 (sp) Push
1598 Push the 8/16-bits result on the stack. */
f64e47a2 1599static void
e0709f50
AC
1600gen_save_result (FILE *fp, int col,
1601 const struct m6811_opcode_def *opcode,
1602 int addr_set,
1603 const char *operand_size)
1604{
1605 char c;
1606 const char *operands = opcode->operands;
1607
1608 /* When the result is saved, 'result_size' is a string which
1609 indicates the size of the saved result ("8" or "16"). This
1610 is a sanity check with 'operand_size' to detect inconsistencies
1611 in the different tables. */
1612 const char *result_size = 0;
1613
1614 if (operands == 0)
1615 operands = "";
1616
1617 operands = strchr (operands, '-');
1618 if (operands == 0)
1619 return;
1620
1621 operands++;
1622 if (*operands++ != '>')
1623 {
1624 fatal_error (opcode, "Invalid operand");
1625 }
1626
1627 c = *operands++;
1628 switch (c)
1629 {
1630 case 'a':
1631 result_size = "8";
6f64fd48 1632 print (fp, col, "cpu_set_a (cpu, dst8);");
e0709f50
AC
1633 break;
1634
1635 case 'b':
1636 result_size = "8";
6f64fd48 1637 print (fp, col, "cpu_set_b (cpu, dst8);");
e0709f50
AC
1638 break;
1639
1640 case 'd':
1641 result_size = "16";
6f64fd48 1642 print (fp, col, "cpu_set_d (cpu, dst16);");
e0709f50
AC
1643 break;
1644
1645 case 'x':
1646 result_size = "16";
6f64fd48 1647 print (fp, col, "cpu_set_x (cpu, dst16);");
e0709f50
AC
1648 break;
1649
1650 case 'y':
1651 result_size = "16";
6f64fd48 1652 print (fp, col, "cpu_set_y (cpu, dst16);");
e0709f50
AC
1653 break;
1654
1655 case '*':
1656 if (addr_set == 0)
1657 {
1658 current_insn_size += 1;
7606e1a3 1659 print (fp, col, "addr = (uint16_t) cpu_fetch8 (cpu);");
e0709f50
AC
1660 }
1661 result_size = operand_size;
6f64fd48 1662 print (fp, col, "memory_write%s (cpu, addr, dst%s);",
e0709f50
AC
1663 operand_size, operand_size);
1664 break;
1665
1666 case '(':
1667 if (strncmp (operands, "x)", 2) == 0)
1668 {
1669 if (addr_set == 0)
1670 {
1671 current_insn_size += 1;
6f64fd48 1672 print (fp, col, "addr = cpu_get_x (cpu) + cpu_fetch8 (cpu);");
e0709f50 1673 }
6f64fd48 1674 print (fp, col, "memory_write%s (cpu, addr, dst%s);",
e0709f50
AC
1675 operand_size, operand_size);
1676 operands += 2;
1677 result_size = operand_size;
1678 }
1679 else if (strncmp (operands, "y)", 2) == 0)
1680 {
1681 if (addr_set == 0)
1682 {
1683 current_insn_size += 1;
6f64fd48 1684 print (fp, col, "addr = cpu_get_y (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, ")", 1) == 0)
1692 {
1693 if (addr_set == 0)
1694 {
1695 current_insn_size += 2;
6f64fd48 1696 print (fp, col, "addr = cpu_fetch16 (cpu);");
e0709f50 1697 }
6f64fd48 1698 print (fp, col, "memory_write%s (cpu, addr, dst%s);",
e0709f50
AC
1699 operand_size, operand_size);
1700 operands++;
1701 result_size = operand_size;
1702 }
1703 else if (strncmp (operands, "sp)", 3) == 0)
1704 {
6f64fd48 1705 print (fp, col, "cpu_%s_push_uint%s (cpu, dst%s);",
81e09ed8 1706 cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
e0709f50
AC
1707 operand_size, operand_size);
1708 operands += 3;
1709 result_size = operand_size;
1710 }
1711 else
1712 {
1713 fatal_error (opcode, "Invalid operand");
1714 }
1715 break;
1716
81e09ed8
SC
1717 case '[':
1718 if (strncmp (operands, "]", 1) == 0)
1719 {
1720 if (addr_set == 0)
1721 {
1722 current_insn_size += 1;
6f64fd48 1723 print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu,0);");
81e09ed8 1724 }
6f64fd48 1725 print (fp, col, "memory_write%s (cpu, addr, dst%s);",
81e09ed8
SC
1726 operand_size, operand_size);
1727 operands++;
1728 result_size = operand_size;
1729 }
1730 else
1731 {
1732 fatal_error (opcode, "Invalid operand");
1733 }
1734 break;
1735
1736 case '{':
1737 if (strncmp (operands, "}", 1) == 0)
1738 {
1739 current_insn_size += 1;
6f64fd48
MF
1740 print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu, 1);");
1741 print (fp, col, "memory_write%s (cpu, addr, dst%s);",
81e09ed8
SC
1742 operand_size, operand_size);
1743 operands++;
1744 result_size = operand_size;
1745 }
1746 else
1747 {
1748 fatal_error (opcode, "Invalid operand");
1749 }
1750 break;
1751
e0709f50
AC
1752 case 's':
1753 if (strncmp (operands, "p", 1) == 0)
1754 {
6f64fd48 1755 print (fp, col, "cpu_set_sp (cpu, dst16);");
e0709f50
AC
1756 operands++;
1757 result_size = "16";
1758 }
1759 else
1760 {
1761 fatal_error (opcode, "Invalid operand");
1762 }
1763 break;
1764
1765 case 'c':
1766 if (strncmp (operands, "cr", 2) == 0)
1767 {
6f64fd48 1768 print (fp, col, "cpu_set_ccr (cpu, dst8);");
e0709f50
AC
1769 operands += 2;
1770 result_size = "8";
1771 }
1772 else
1773 {
1774 fatal_error (opcode, "Invalid operand");
1775 }
1776 break;
1777
1778 default:
1779 fatal_error (opcode, "Invalid operand");
1780 break;
1781 }
1782
1783 if (*operands != 0)
1784 fatal_error (opcode, "Garbage at end of operand");
1785
1786 if (result_size == 0)
1787 fatal_error (opcode, "? No result seems to be saved");
1788
1789 if (strcmp (result_size, operand_size) != 0)
1790 fatal_error (opcode, "Result saved different than pattern size");
1791}
1792
1793
1794/* Find the instruction pattern for a given instruction. */
f64e47a2 1795static const struct m6811_opcode_pattern*
e0709f50
AC
1796find_opcode_pattern (const struct m6811_opcode_def *opcode)
1797{
1798 int i;
1799 const char *pattern = opcode->insn_pattern;
1800
1801 if (pattern == 0)
1802 {
1803 pattern = opcode->name;
1804 }
13a590ca 1805 for (i = 0; i < ARRAY_SIZE (m6811_opcode_patterns); i++)
e0709f50
AC
1806 {
1807 if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
1808 {
1809 return &m6811_opcode_patterns[i];
1810 }
1811 }
1812 fatal_error (opcode, "Unknown instruction pattern");
1813 return 0;
1814}
1815
e0709f50 1816/* Generate the code for interpretation of instruction 'opcode'. */
f64e47a2 1817static void
e0709f50
AC
1818gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
1819{
1820 const char *operands = opcode->operands;
1821 int addr_set;
1822 const char *pattern = opcode->insn_pattern;
1823 const struct m6811_opcode_pattern *op;
1824 const char *operand_size;
1825
1826 if (pattern == 0)
1827 {
1828 pattern = opcode->name;
1829 }
1830
1831 /* Find out the size of the operands: 8 or 16-bits. */
1832 if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
1833 {
1834 operand_size = "8";
1835 }
1836 else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
1837 {
1838 operand_size = "16";
1839 }
1840 else
1841 {
1842 operand_size = "";
1843 }
1844
1845 if (operands == 0)
1846 operands = "";
1847
1848 /* Generate entry point for the instruction. */
1849 print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
1850 opcode->name, operands);
1851 col += indent_level;
1852
1853 /* Generate the code to get the instruction operands. */
1854 addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
1855
1856 /* Generate instruction interpretation. */
1857 op = find_opcode_pattern (opcode);
1858 if (op->pattern)
1859 {
1860 print (fp, col, "%s;", op->pattern);
1861 }
1862
1863 /* Generate the code to save the result. */
1864 gen_save_result (fp, col, opcode, addr_set, operand_size);
1865
1866 /* For some instructions, generate the code to update the flags. */
1867 if (op && op->ccr_update)
1868 {
1869 print (fp, col, "%s;", op->ccr_update);
1870 }
1871 print (fp, col, "break;");
1872}
1873
1874
1875/* Generate the interpretor for a given 68HC11 page set. */
f64e47a2 1876static void
e0709f50
AC
1877gen_interpreter_for_table (FILE *fp, int col,
1878 const struct m6811_opcode_def *table,
1879 int size,
1880 const char *cycles_table_name)
1881{
1882 int i;
1883 int init_size;
1884
81e09ed8
SC
1885 init_size = table == m6811_page1_opcodes
1886 || table == m6812_page1_opcodes? 1 : 2;
e0709f50
AC
1887
1888 /* Get the opcode and dispatch directly. */
6f64fd48
MF
1889 print (fp, col, "op = cpu_fetch8 (cpu);");
1890 print (fp, col, "cpu_add_cycles (cpu, %s[op]);", cycles_table_name);
e0709f50
AC
1891
1892 print (fp, col, "switch (op)\n");
1893 col += indent_level;
1894 print (fp, col, "{\n");
1895
1896 for (i = 0; i < size; i++)
1897 {
1898 /* The table contains duplicate entries (ie, instruction aliases). */
1899 if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
1900 continue;
1901
1902 current_insn_size = init_size;
1903 gen_interp (fp, col, &table[i]);
81e09ed8 1904#if 0
e0709f50
AC
1905 if (current_insn_size != table[i].insn_size)
1906 {
81e09ed8
SC
1907 fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
1908 current_insn_size, table[i].insn_size);
e0709f50 1909 }
81e09ed8 1910#endif
e0709f50
AC
1911 }
1912
1913 print (fp, col, "default:\n");
6f64fd48 1914 print (fp, col + indent_level, "cpu_special (cpu, M6811_ILLEGAL);");
e0709f50
AC
1915 print (fp, col + indent_level, "break;");
1916 print (fp, col, "}\n");
1917}
1918
1919/* Generate the table of instruction cycle. These tables are indexed
1920 by the opcode number to allow a fast cycle time computation. */
f64e47a2 1921static void
e0709f50
AC
1922gen_cycle_table (FILE *fp, const char *name,
1923 const struct m6811_opcode_def *table,
1924 int size)
1925{
1926 int i;
1927 char cycles[256];
1928 int page1;
1929
1930 page1 = table == m6811_page1_opcodes;
1931
1932 /* Build the cycles table. The table is indexed by the opcode. */
1933 memset (cycles, 0, sizeof (cycles));
1934 while (--size >= 0)
1935 {
1936 if (table->insn_min_cycles > table->insn_max_cycles)
1937 fatal_error (table, "Wrong insn cycles");
1938
1939 if (table->insn_max_cycles == _M)
1940 cycles[table->insn_code] = table->insn_min_cycles;
1941 else
1942 cycles[table->insn_code] = table->insn_max_cycles;
1943
1944 table++;
1945 }
1946
1947 /* Some check: for the page1 opcode, the cycle type of the page2/3/4
1948 opcode must be 0. */
1949 if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
1950 || cycles[M6811_OPCODE_PAGE3] != 0
1951 || cycles[M6811_OPCODE_PAGE4] != 0))
1952 fatal_error (0, "Invalid cycle table");
1953
1954 /* Generates the cycles table. */
1955 print (fp, 0, "static const unsigned char %s[256] = {\n", name);
1956 for (i = 0; i < 256; i++)
1957 {
1958 if ((i % 16) == 0)
1959 {
1960 print (fp, indent_level, "/* %3d */ ", i);
1961 }
1962 fprintf (fp, "%2d", cycles[i]);
1963 if (i != 255)
1964 fprintf (fp, ",");
1965
1966 if ((i % 16) != 15)
1967 fprintf (fp, " ");
1968 else
1969 fprintf (fp, "\n");
1970 }
1971 print (fp, 0, "};\n\n");
1972}
1973
63f36def
SC
1974#define USE_SRC8 1
1975#define USE_DST8 2
1976
f64e47a2 1977static void
63f36def 1978gen_function_entry (FILE *fp, const char *name, int locals)
e0709f50
AC
1979{
1980 /* Generate interpretor entry point. */
6f64fd48 1981 print (fp, 0, "%s (sim_cpu *cpu)\n", name);
e0709f50
AC
1982 print (fp, indent_level, "{\n");
1983
1984 /* Interpretor local variables. */
1985 print (fp, indent_level, "unsigned char op;");
7606e1a3 1986 print (fp, indent_level, "uint16_t addr, src16, dst16;");
63f36def 1987 if (locals & USE_SRC8)
7606e1a3 1988 print (fp, indent_level, "uint8_t src8;\n");
63f36def 1989 if (locals & USE_DST8)
7606e1a3 1990 print (fp, indent_level, "uint8_t dst8;\n");
e0709f50
AC
1991}
1992
f64e47a2 1993static void
e0709f50
AC
1994gen_function_close (FILE *fp)
1995{
1996 print (fp, 0, "}\n");
1997}
1998
f64e47a2 1999static int
527aaa4a 2000cmp_opcode (const void *e1, const void *e2)
81e09ed8
SC
2001{
2002 struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
2003 struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
2004
2005 return (int) (op1->insn_code) - (int) (op2->insn_code);
2006}
2007
f64e47a2 2008static void
81e09ed8
SC
2009prepare_table (struct m6811_opcode_def* table, int size)
2010{
2011 int i;
2012
2013 qsort (table, size, sizeof (table[0]), cmp_opcode);
2014 for (i = 1; i < size; i++)
2015 {
2016 if (table[i].insn_code == table[i-1].insn_code)
2017 {
2018 fprintf (stderr, "Two insns with code 0x%02x\n",
2019 table[i].insn_code);
2020 }
2021 }
2022}
2023
f64e47a2 2024static void
e0709f50
AC
2025gen_interpreter (FILE *fp)
2026{
2027 int col = 0;
2028
13a590ca
MF
2029 prepare_table (m6811_page1_opcodes, ARRAY_SIZE (m6811_page1_opcodes));
2030 prepare_table (m6811_page2_opcodes, ARRAY_SIZE (m6811_page2_opcodes));
2031 prepare_table (m6811_page3_opcodes, ARRAY_SIZE (m6811_page3_opcodes));
2032 prepare_table (m6811_page4_opcodes, ARRAY_SIZE (m6811_page4_opcodes));
81e09ed8 2033
13a590ca
MF
2034 prepare_table (m6812_page1_opcodes, ARRAY_SIZE (m6812_page1_opcodes));
2035 prepare_table (m6812_page2_opcodes, ARRAY_SIZE (m6812_page2_opcodes));
81e09ed8 2036
e0709f50
AC
2037 /* Generate header of interpretor. */
2038 print (fp, col, "/* File generated automatically by gencode. */\n");
600ddfd5 2039 print (fp, col, "#include \"m68hc11-sim.h\"\n\n");
e0709f50 2040
81e09ed8
SC
2041 if (cpu_type & cpu6811)
2042 {
2043 gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
13a590ca 2044 ARRAY_SIZE (m6811_page1_opcodes));
81e09ed8 2045 gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
13a590ca 2046 ARRAY_SIZE (m6811_page2_opcodes));
81e09ed8 2047 gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
13a590ca 2048 ARRAY_SIZE (m6811_page3_opcodes));
81e09ed8 2049 gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
13a590ca 2050 ARRAY_SIZE (m6811_page4_opcodes));
81e09ed8 2051
63f36def 2052 gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
81e09ed8
SC
2053 gen_interpreter_for_table (fp, indent_level,
2054 m6811_page3_opcodes,
13a590ca 2055 ARRAY_SIZE (m6811_page3_opcodes),
81e09ed8
SC
2056 "cycles_page3");
2057 gen_function_close (fp);
e0709f50 2058
63f36def 2059 gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
81e09ed8
SC
2060 gen_interpreter_for_table (fp, indent_level,
2061 m6811_page4_opcodes,
13a590ca 2062 ARRAY_SIZE (m6811_page4_opcodes),
81e09ed8
SC
2063 "cycles_page4");
2064 gen_function_close (fp);
2065
2066 /* Generate the page 2, 3 and 4 handlers. */
63f36def
SC
2067 gen_function_entry (fp, "static void\ncpu_page2_interp",
2068 USE_SRC8 | USE_DST8);
81e09ed8
SC
2069 gen_interpreter_for_table (fp, indent_level,
2070 m6811_page2_opcodes,
13a590ca 2071 ARRAY_SIZE (m6811_page2_opcodes),
81e09ed8
SC
2072 "cycles_page2");
2073 gen_function_close (fp);
2074
2075 /* Generate the interpretor entry point. */
63f36def
SC
2076 gen_function_entry (fp, "void\ncpu_interp_m6811",
2077 USE_SRC8 | USE_DST8);
81e09ed8
SC
2078
2079 gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
13a590ca 2080 ARRAY_SIZE (m6811_page1_opcodes),
81e09ed8
SC
2081 "cycles_page1");
2082 gen_function_close (fp);
2083 }
2084 else
2085 {
2086 gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
13a590ca 2087 ARRAY_SIZE (m6812_page1_opcodes));
81e09ed8 2088 gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
13a590ca 2089 ARRAY_SIZE (m6812_page2_opcodes));
81e09ed8 2090
63f36def
SC
2091 gen_function_entry (fp, "static void\ncpu_page2_interp",
2092 USE_SRC8 | USE_DST8);
81e09ed8
SC
2093 gen_interpreter_for_table (fp, indent_level,
2094 m6812_page2_opcodes,
13a590ca 2095 ARRAY_SIZE (m6812_page2_opcodes),
81e09ed8
SC
2096 "cycles_page2");
2097 gen_function_close (fp);
2098
2099 /* Generate the interpretor entry point. */
63f36def
SC
2100 gen_function_entry (fp, "void\ncpu_interp_m6812",
2101 USE_SRC8 | USE_DST8);
81e09ed8
SC
2102
2103 gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
13a590ca 2104 ARRAY_SIZE (m6812_page1_opcodes),
81e09ed8
SC
2105 "cycles_page1");
2106 gen_function_close (fp);
2107 }
2108}
2109
f64e47a2 2110static void
81e09ed8
SC
2111usage (char* prog)
2112{
2113 fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
2114 exit (2);
e0709f50
AC
2115}
2116
2117int
2118main (int argc, char *argv[])
2119{
81e09ed8
SC
2120 int i;
2121
2122 for (i = 1; i < argc; i++)
2123 {
2124 if (strcmp (argv[i], "-m6811") == 0)
2125 cpu_type = cpu6811;
2126 else if (strcmp (argv[i], "-m6812") == 0)
2127 cpu_type = cpu6812;
2128 else
2129 {
2130 usage (argv[0]);
2131 }
2132 }
2133 if (cpu_type == 0)
2134 usage (argv[0]);
2135
e0709f50
AC
2136 gen_interpreter (stdout);
2137 if (fclose (stdout) != 0)
2138 {
2139 fprintf (stderr, "Error while generating the interpreter: %d\n",
2140 errno);
2141 return 1;
2142 }
2143 return 0;
2144}