s12z-dis.c revision 1.1.1.1 1 1.1 christos /* s12z-dis.c -- Freescale S12Z disassembly
2 1.1 christos Copyright (C) 2018 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of the GNU opcodes library.
5 1.1 christos
6 1.1 christos This library is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 christos License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 christos MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include <stdio.h>
23 1.1 christos #include <stdint.h>
24 1.1 christos #include <stdbool.h>
25 1.1 christos #include <assert.h>
26 1.1 christos
27 1.1 christos #include "s12z.h"
28 1.1 christos
29 1.1 christos #include "bfd.h"
30 1.1 christos #include "dis-asm.h"
31 1.1 christos
32 1.1 christos
33 1.1 christos #include "disassemble.h"
34 1.1 christos
35 1.1 christos static int
36 1.1 christos read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
37 1.1 christos struct disassemble_info* info)
38 1.1 christos {
39 1.1 christos int status = (*info->read_memory_func) (memaddr, buffer, size, info);
40 1.1 christos if (status != 0)
41 1.1 christos {
42 1.1 christos (*info->memory_error_func) (status, memaddr, info);
43 1.1 christos return -1;
44 1.1 christos }
45 1.1 christos return 0;
46 1.1 christos }
47 1.1 christos
48 1.1 christos typedef int (* insn_bytes_f) (bfd_vma memaddr,
49 1.1 christos struct disassemble_info* info);
50 1.1 christos
51 1.1 christos typedef void (*operands_f) (bfd_vma memaddr, struct disassemble_info* info);
52 1.1 christos
53 1.1 christos enum OPR_MODE
54 1.1 christos {
55 1.1 christos OPR_IMMe4,
56 1.1 christos OPR_REG,
57 1.1 christos OPR_OFXYS,
58 1.1 christos OPR_XY_PRE_INC,
59 1.1 christos OPR_XY_POST_INC,
60 1.1 christos OPR_XY_PRE_DEC,
61 1.1 christos OPR_XY_POST_DEC,
62 1.1 christos OPR_S_PRE_DEC,
63 1.1 christos OPR_S_POST_INC,
64 1.1 christos OPR_REG_DIRECT,
65 1.1 christos OPR_REG_INDIRECT,
66 1.1 christos OPR_IDX_DIRECT,
67 1.1 christos OPR_IDX_INDIRECT,
68 1.1 christos OPR_EXT1,
69 1.1 christos OPR_IDX2_REG,
70 1.1 christos OPR_IDX3_DIRECT,
71 1.1 christos OPR_IDX3_INDIRECT,
72 1.1 christos
73 1.1 christos OPR_EXT18,
74 1.1 christos OPR_IDX3_DIRECT_REG,
75 1.1 christos OPR_EXT3_DIRECT,
76 1.1 christos OPR_EXT3_INDIRECT
77 1.1 christos };
78 1.1 christos
79 1.1 christos struct opr_pb
80 1.1 christos {
81 1.1 christos uint8_t mask;
82 1.1 christos uint8_t value;
83 1.1 christos int n_operands;
84 1.1 christos enum OPR_MODE mode;
85 1.1 christos };
86 1.1 christos
87 1.1 christos static const struct opr_pb opr_pb[] = {
88 1.1 christos {0xF0, 0x70, 1, OPR_IMMe4},
89 1.1 christos {0xF8, 0xB8, 1, OPR_REG},
90 1.1 christos {0xC0, 0x40, 1, OPR_OFXYS},
91 1.1 christos {0xEF, 0xE3, 1, OPR_XY_PRE_INC},
92 1.1 christos {0xEF, 0xE7, 1, OPR_XY_POST_INC},
93 1.1 christos {0xEF, 0xC3, 1, OPR_XY_PRE_DEC},
94 1.1 christos {0xEF, 0xC7, 1, OPR_XY_POST_DEC},
95 1.1 christos {0xFF, 0xFB, 1, OPR_S_PRE_DEC},
96 1.1 christos {0xFF, 0xFF, 1, OPR_S_POST_INC},
97 1.1 christos {0xC8, 0x88, 1, OPR_REG_DIRECT},
98 1.1 christos {0xE8, 0xC8, 1, OPR_REG_INDIRECT},
99 1.1 christos
100 1.1 christos {0xCE, 0xC0, 2, OPR_IDX_DIRECT},
101 1.1 christos {0xCE, 0xC4, 2, OPR_IDX_INDIRECT},
102 1.1 christos {0xC0, 0x00, 2, OPR_EXT1},
103 1.1 christos
104 1.1 christos {0xC8, 0x80, 3, OPR_IDX2_REG},
105 1.1 christos {0xFA, 0xF8, 3, OPR_EXT18},
106 1.1 christos
107 1.1 christos {0xCF, 0xC2, 4, OPR_IDX3_DIRECT},
108 1.1 christos {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT},
109 1.1 christos
110 1.1 christos {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG},
111 1.1 christos {0xFF, 0xFA, 4, OPR_EXT3_DIRECT},
112 1.1 christos {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT},
113 1.1 christos };
114 1.1 christos
115 1.1 christos
116 1.1 christos /* Return the number of bytes in a OPR operand, including the XB postbyte.
117 1.1 christos It does not include any preceeding opcodes. */
118 1.1 christos static int
119 1.1 christos opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
120 1.1 christos {
121 1.1 christos bfd_byte xb;
122 1.1 christos int status = read_memory (memaddr, &xb, 1, info);
123 1.1 christos if (status < 0)
124 1.1 christos return status;
125 1.1 christos
126 1.1 christos size_t i;
127 1.1 christos for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
128 1.1 christos {
129 1.1 christos const struct opr_pb *pb = opr_pb + i;
130 1.1 christos if ((xb & pb->mask) == pb->value)
131 1.1 christos {
132 1.1 christos return pb->n_operands;
133 1.1 christos }
134 1.1 christos }
135 1.1 christos
136 1.1 christos return 1;
137 1.1 christos }
138 1.1 christos
139 1.1 christos static int
140 1.1 christos opr_n_bytes_p1 (bfd_vma memaddr, struct disassemble_info* info)
141 1.1 christos {
142 1.1 christos return 1 + opr_n_bytes (memaddr, info);
143 1.1 christos }
144 1.1 christos
145 1.1 christos static int
146 1.1 christos opr_n_bytes2 (bfd_vma memaddr, struct disassemble_info* info)
147 1.1 christos {
148 1.1 christos int s = opr_n_bytes (memaddr, info);
149 1.1 christos s += opr_n_bytes (memaddr + s, info);
150 1.1 christos return s + 1;
151 1.1 christos }
152 1.1 christos
153 1.1 christos enum BB_MODE
154 1.1 christos {
155 1.1 christos BB_REG_REG_REG,
156 1.1 christos BB_REG_REG_IMM,
157 1.1 christos BB_REG_OPR_REG,
158 1.1 christos BB_OPR_REG_REG,
159 1.1 christos BB_REG_OPR_IMM,
160 1.1 christos BB_OPR_REG_IMM
161 1.1 christos };
162 1.1 christos
163 1.1 christos struct opr_bb
164 1.1 christos {
165 1.1 christos uint8_t mask;
166 1.1 christos uint8_t value;
167 1.1 christos int n_operands;
168 1.1 christos bool opr;
169 1.1 christos enum BB_MODE mode;
170 1.1 christos };
171 1.1 christos
172 1.1 christos static const struct opr_bb bb_modes[] =
173 1.1 christos {
174 1.1 christos {0x60, 0x00, 2, false, BB_REG_REG_REG},
175 1.1 christos {0x60, 0x20, 3, false, BB_REG_REG_IMM},
176 1.1 christos {0x70, 0x40, 2, true, BB_REG_OPR_REG},
177 1.1 christos {0x70, 0x50, 2, true, BB_OPR_REG_REG},
178 1.1 christos {0x70, 0x60, 3, true, BB_REG_OPR_IMM},
179 1.1 christos {0x70, 0x70, 3, true, BB_OPR_REG_IMM}
180 1.1 christos };
181 1.1 christos
182 1.1 christos static int
183 1.1 christos bfextins_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
184 1.1 christos {
185 1.1 christos bfd_byte bb;
186 1.1 christos int status = read_memory (memaddr, &bb, 1, info);
187 1.1 christos if (status < 0)
188 1.1 christos return status;
189 1.1 christos
190 1.1 christos size_t i;
191 1.1 christos const struct opr_bb *bbs = 0;
192 1.1 christos for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
193 1.1 christos {
194 1.1 christos bbs = bb_modes + i;
195 1.1 christos if ((bb & bbs->mask) == bbs->value)
196 1.1 christos {
197 1.1 christos break;
198 1.1 christos }
199 1.1 christos }
200 1.1 christos
201 1.1 christos int n = bbs->n_operands;
202 1.1 christos if (bbs->opr)
203 1.1 christos n += opr_n_bytes (memaddr + n - 1, info);
204 1.1 christos
205 1.1 christos return n;
206 1.1 christos }
207 1.1 christos
208 1.1 christos static int
209 1.1 christos single (bfd_vma memaddr ATTRIBUTE_UNUSED,
210 1.1 christos struct disassemble_info* info ATTRIBUTE_UNUSED)
211 1.1 christos {
212 1.1 christos return 1;
213 1.1 christos }
214 1.1 christos
215 1.1 christos static int
216 1.1 christos two (bfd_vma memaddr ATTRIBUTE_UNUSED,
217 1.1 christos struct disassemble_info* info ATTRIBUTE_UNUSED)
218 1.1 christos {
219 1.1 christos return 2;
220 1.1 christos }
221 1.1 christos
222 1.1 christos static int
223 1.1 christos three (bfd_vma memaddr ATTRIBUTE_UNUSED,
224 1.1 christos struct disassemble_info* info ATTRIBUTE_UNUSED)
225 1.1 christos {
226 1.1 christos return 3;
227 1.1 christos }
228 1.1 christos
229 1.1 christos static int
230 1.1 christos four (bfd_vma memaddr ATTRIBUTE_UNUSED,
231 1.1 christos struct disassemble_info* info ATTRIBUTE_UNUSED)
232 1.1 christos {
233 1.1 christos return 4;
234 1.1 christos }
235 1.1 christos
236 1.1 christos static int
237 1.1 christos five (bfd_vma memaddr ATTRIBUTE_UNUSED,
238 1.1 christos struct disassemble_info* info ATTRIBUTE_UNUSED)
239 1.1 christos {
240 1.1 christos return 5;
241 1.1 christos }
242 1.1 christos
243 1.1 christos static int
244 1.1 christos pcrel_15bit (bfd_vma memaddr, struct disassemble_info* info)
245 1.1 christos {
246 1.1 christos bfd_byte byte;
247 1.1 christos int status = read_memory (memaddr, &byte, 1, info);
248 1.1 christos if (status < 0)
249 1.1 christos return status;
250 1.1 christos return (byte & 0x80) ? 3 : 2;
251 1.1 christos }
252 1.1 christos
253 1.1 christos
254 1.1 christos
255 1.1 christos
257 1.1 christos static void
258 1.1 christos operand_separator (struct disassemble_info *info)
259 1.1 christos {
260 1.1 christos if ((info->flags & 0x2))
261 1.1 christos {
262 1.1 christos (*info->fprintf_func) (info->stream, ", ");
263 1.1 christos }
264 1.1 christos else
265 1.1 christos {
266 1.1 christos (*info->fprintf_func) (info->stream, " ");
267 1.1 christos }
268 1.1 christos
269 1.1 christos info->flags |= 0x2;
270 1.1 christos }
271 1.1 christos
272 1.1 christos
273 1.1 christos
275 1.1 christos static void
276 1.1 christos imm1 (bfd_vma memaddr, struct disassemble_info* info)
277 1.1 christos {
278 1.1 christos bfd_byte byte;
279 1.1 christos int status = read_memory (memaddr, &byte, 1, info);
280 1.1 christos if (status < 0)
281 1.1 christos return;
282 1.1 christos
283 1.1 christos operand_separator (info);
284 1.1 christos (*info->fprintf_func) (info->stream, "#%d", byte);
285 1.1 christos }
286 1.1 christos
287 1.1 christos static void
288 1.1 christos trap_decode (bfd_vma memaddr, struct disassemble_info* info)
289 1.1 christos {
290 1.1 christos imm1 (memaddr - 1, info);
291 1.1 christos }
292 1.1 christos
293 1.1 christos
294 1.1 christos const struct reg registers[S12Z_N_REGISTERS] =
295 1.1 christos {
296 1.1 christos {"d2", 2},
297 1.1 christos {"d3", 2},
298 1.1 christos {"d4", 2},
299 1.1 christos {"d5", 2},
300 1.1 christos
301 1.1 christos {"d0", 1},
302 1.1 christos {"d1", 1},
303 1.1 christos
304 1.1 christos {"d6", 4},
305 1.1 christos {"d7", 4},
306 1.1 christos
307 1.1 christos {"x", 3},
308 1.1 christos {"y", 3},
309 1.1 christos {"s", 3},
310 1.1 christos {"p", 3},
311 1.1 christos {"cch", 1},
312 1.1 christos {"ccl", 1},
313 1.1 christos {"ccw", 2}
314 1.1 christos };
315 1.1 christos
316 1.1 christos static char *
317 1.1 christos xys_from_postbyte (uint8_t postbyte)
318 1.1 christos {
319 1.1 christos char *reg = "?";
320 1.1 christos switch ((postbyte & 0x30) >> 4)
321 1.1 christos {
322 1.1 christos case 0:
323 1.1 christos reg = "x";
324 1.1 christos break;
325 1.1 christos case 1:
326 1.1 christos reg = "y";
327 1.1 christos break;
328 1.1 christos case 2:
329 1.1 christos reg = "s";
330 1.1 christos break;
331 1.1 christos default:
332 1.1 christos reg = "?";
333 1.1 christos break;
334 1.1 christos }
335 1.1 christos return reg;
336 1.1 christos }
337 1.1 christos
338 1.1 christos static char *
339 1.1 christos xysp_from_postbyte (uint8_t postbyte)
340 1.1 christos {
341 1.1 christos char *reg = "?";
342 1.1 christos switch ((postbyte & 0x30) >> 4)
343 1.1 christos {
344 1.1 christos case 0:
345 1.1 christos reg = "x";
346 1.1 christos break;
347 1.1 christos case 1:
348 1.1 christos reg = "y";
349 1.1 christos break;
350 1.1 christos case 2:
351 1.1 christos reg = "s";
352 1.1 christos break;
353 1.1 christos default:
354 1.1 christos reg = "p";
355 1.1 christos break;
356 1.1 christos }
357 1.1 christos return reg;
358 1.1 christos }
359 1.1 christos
360 1.1 christos /* Render the symbol name whose value is ADDR or the adddress itself if there is
361 1.1 christos no symbol. */
362 1.1 christos static void
363 1.1 christos decode_possible_symbol (bfd_vma addr, struct disassemble_info *info)
364 1.1 christos {
365 1.1 christos if (!info->symbol_at_address_func (addr, info))
366 1.1 christos {
367 1.1 christos (*info->fprintf_func) (info->stream, "%" BFD_VMA_FMT "d", addr);
368 1.1 christos }
369 1.1 christos else
370 1.1 christos {
371 1.1 christos asymbol *sym = NULL;
372 1.1 christos int j;
373 1.1 christos for (j = 0; j < info->symtab_size; ++j)
374 1.1 christos {
375 1.1 christos sym = info->symtab[j];
376 1.1 christos if (bfd_asymbol_value (sym) == addr)
377 1.1 christos {
378 1.1 christos break;
379 1.1 christos }
380 1.1 christos }
381 1.1 christos if (j < info->symtab_size)
382 1.1 christos (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
383 1.1 christos }
384 1.1 christos }
385 1.1 christos
386 1.1 christos static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info);
387 1.1 christos
388 1.1 christos static void
389 1.1 christos ext24_decode (bfd_vma memaddr, struct disassemble_info* info)
390 1.1 christos {
391 1.1 christos uint8_t buffer[3];
392 1.1 christos int status = read_memory (memaddr, buffer, 3, info);
393 1.1 christos if (status < 0)
394 1.1 christos return;
395 1.1 christos
396 1.1 christos int i;
397 1.1 christos uint32_t addr = 0;
398 1.1 christos for (i = 0; i < 3; ++i)
399 1.1 christos {
400 1.1 christos addr <<= 8;
401 1.1 christos addr |= buffer[i];
402 1.1 christos }
403 1.1 christos
404 1.1 christos operand_separator (info);
405 1.1 christos decode_possible_symbol (addr, info);
406 1.1 christos }
407 1.1 christos
408 1.1 christos
409 1.1 christos static uint32_t
410 1.1 christos decode_signed_value (bfd_vma memaddr, struct disassemble_info* info, short size)
411 1.1 christos {
412 1.1 christos assert (size >0);
413 1.1 christos assert (size <= 4);
414 1.1 christos bfd_byte buffer[4];
415 1.1 christos if (0 > read_memory (memaddr, buffer, size, info))
416 1.1 christos {
417 1.1 christos return 0;
418 1.1 christos }
419 1.1 christos
420 1.1 christos int i;
421 1.1 christos uint32_t value = 0;
422 1.1 christos for (i = 0; i < size; ++i)
423 1.1 christos {
424 1.1 christos value |= buffer[i] << (8 * (size - i - 1));
425 1.1 christos }
426 1.1 christos
427 1.1 christos if (buffer[0] & 0x80)
428 1.1 christos {
429 1.1 christos /* Deal with negative values */
430 1.1 christos value -= 0x1UL << (size * 8);
431 1.1 christos }
432 1.1 christos return value;
433 1.1 christos }
434 1.1 christos
435 1.1 christos
436 1.1 christos static void
437 1.1 christos opr_decode (bfd_vma memaddr, struct disassemble_info* info)
438 1.1 christos {
439 1.1 christos bfd_byte postbyte;
440 1.1 christos int status = read_memory (memaddr, &postbyte, 1, info);
441 1.1 christos if (status < 0)
442 1.1 christos return;
443 1.1 christos
444 1.1 christos enum OPR_MODE mode = -1;
445 1.1 christos size_t i;
446 1.1 christos for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
447 1.1 christos {
448 1.1 christos const struct opr_pb *pb = opr_pb + i;
449 1.1 christos if ((postbyte & pb->mask) == pb->value)
450 1.1 christos {
451 1.1 christos mode = pb->mode;
452 1.1 christos break;
453 1.1 christos }
454 1.1 christos }
455 1.1 christos
456 1.1 christos operand_separator (info);
457 1.1 christos switch (mode)
458 1.1 christos {
459 1.1 christos case OPR_IMMe4:
460 1.1 christos {
461 1.1 christos int n;
462 1.1 christos uint8_t x = (postbyte & 0x0F);
463 1.1 christos if (x == 0)
464 1.1 christos n = -1;
465 1.1 christos else
466 1.1 christos n = x;
467 1.1 christos
468 1.1 christos (*info->fprintf_func) (info->stream, "#%d", n);
469 1.1 christos break;
470 1.1 christos }
471 1.1 christos case OPR_REG:
472 1.1 christos {
473 1.1 christos uint8_t x = (postbyte & 0x07);
474 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[x].name);
475 1.1 christos break;
476 1.1 christos }
477 1.1 christos case OPR_OFXYS:
478 1.1 christos {
479 1.1 christos const char *reg = xys_from_postbyte (postbyte);
480 1.1 christos (*info->fprintf_func) (info->stream, "(%d,%s)", postbyte & 0x0F, reg);
481 1.1 christos break;
482 1.1 christos }
483 1.1 christos case OPR_REG_DIRECT:
484 1.1 christos {
485 1.1 christos (*info->fprintf_func) (info->stream, "(%s,%s)", registers[postbyte & 0x07].name,
486 1.1 christos xys_from_postbyte (postbyte));
487 1.1 christos break;
488 1.1 christos }
489 1.1 christos case OPR_REG_INDIRECT:
490 1.1 christos {
491 1.1 christos (*info->fprintf_func) (info->stream, "[%s,%s]", registers[postbyte & 0x07].name,
492 1.1 christos (postbyte & 0x10) ? "y": "x");
493 1.1 christos break;
494 1.1 christos }
495 1.1 christos
496 1.1 christos case OPR_IDX_INDIRECT:
497 1.1 christos {
498 1.1 christos uint8_t x1;
499 1.1 christos read_memory (memaddr + 1, &x1, 1, info);
500 1.1 christos int idx = x1;
501 1.1 christos
502 1.1 christos if (postbyte & 0x01)
503 1.1 christos {
504 1.1 christos /* Deal with negative values */
505 1.1 christos idx -= 0x1UL << 8;
506 1.1 christos }
507 1.1 christos
508 1.1 christos (*info->fprintf_func) (info->stream, "[%d,%s]", idx,
509 1.1 christos xysp_from_postbyte (postbyte));
510 1.1 christos break;
511 1.1 christos }
512 1.1 christos
513 1.1 christos case OPR_IDX3_DIRECT:
514 1.1 christos {
515 1.1 christos uint8_t x[3];
516 1.1 christos read_memory (memaddr + 1, x, 3, info);
517 1.1 christos int idx = x[0] << 16 | x[1] << 8 | x[2];
518 1.1 christos
519 1.1 christos if (x[0] & 0x80)
520 1.1 christos {
521 1.1 christos /* Deal with negative values */
522 1.1 christos idx -= 0x1UL << 24;
523 1.1 christos }
524 1.1 christos
525 1.1 christos (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
526 1.1 christos xysp_from_postbyte (postbyte));
527 1.1 christos break;
528 1.1 christos }
529 1.1 christos
530 1.1 christos case OPR_IDX3_DIRECT_REG:
531 1.1 christos {
532 1.1 christos uint8_t x[3];
533 1.1 christos read_memory (memaddr + 1, x, 3, info);
534 1.1 christos int idx = x[0] << 16 | x[1] << 8 | x[2];
535 1.1 christos
536 1.1 christos if (x[0] & 0x80)
537 1.1 christos {
538 1.1 christos /* Deal with negative values */
539 1.1 christos idx -= 0x1UL << 24;
540 1.1 christos }
541 1.1 christos
542 1.1 christos (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
543 1.1 christos registers[postbyte & 0x07].name);
544 1.1 christos break;
545 1.1 christos }
546 1.1 christos
547 1.1 christos case OPR_IDX3_INDIRECT:
548 1.1 christos {
549 1.1 christos uint8_t x[3];
550 1.1 christos read_memory (memaddr + 1, x, 3, info);
551 1.1 christos int idx = x[0] << 16 | x[1] << 8 | x[2];
552 1.1 christos
553 1.1 christos if (x[0] & 0x80)
554 1.1 christos {
555 1.1 christos /* Deal with negative values */
556 1.1 christos idx -= 0x1UL << 24;
557 1.1 christos }
558 1.1 christos
559 1.1 christos (*info->fprintf_func) (info->stream, "[%d,%s]", idx,
560 1.1 christos xysp_from_postbyte (postbyte));
561 1.1 christos break;
562 1.1 christos }
563 1.1 christos
564 1.1 christos case OPR_IDX_DIRECT:
565 1.1 christos {
566 1.1 christos uint8_t x1;
567 1.1 christos read_memory (memaddr + 1, &x1, 1, info);
568 1.1 christos int idx = x1;
569 1.1 christos
570 1.1 christos if (postbyte & 0x01)
571 1.1 christos {
572 1.1 christos /* Deal with negative values */
573 1.1 christos idx -= 0x1UL << 8;
574 1.1 christos }
575 1.1 christos
576 1.1 christos (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
577 1.1 christos xysp_from_postbyte (postbyte));
578 1.1 christos break;
579 1.1 christos }
580 1.1 christos
581 1.1 christos case OPR_IDX2_REG:
582 1.1 christos {
583 1.1 christos uint8_t x[2];
584 1.1 christos read_memory (memaddr + 1, x, 2, info);
585 1.1 christos uint32_t offset = x[1] | x[0] << 8 ;
586 1.1 christos offset |= (postbyte & 0x30) << 12;
587 1.1 christos
588 1.1 christos (*info->fprintf_func) (info->stream, "(%d,%s)", offset,
589 1.1 christos registers[postbyte & 0x07].name);
590 1.1 christos break;
591 1.1 christos }
592 1.1 christos
593 1.1 christos case OPR_XY_PRE_INC:
594 1.1 christos {
595 1.1 christos (*info->fprintf_func) (info->stream, "(+%s)",
596 1.1 christos (postbyte & 0x10) ? "y": "x");
597 1.1 christos
598 1.1 christos break;
599 1.1 christos }
600 1.1 christos case OPR_XY_POST_INC:
601 1.1 christos {
602 1.1 christos (*info->fprintf_func) (info->stream, "(%s+)",
603 1.1 christos (postbyte & 0x10) ? "y": "x");
604 1.1 christos
605 1.1 christos break;
606 1.1 christos }
607 1.1 christos case OPR_XY_PRE_DEC:
608 1.1 christos {
609 1.1 christos (*info->fprintf_func) (info->stream, "(-%s)",
610 1.1 christos (postbyte & 0x10) ? "y": "x");
611 1.1 christos
612 1.1 christos break;
613 1.1 christos }
614 1.1 christos case OPR_XY_POST_DEC:
615 1.1 christos {
616 1.1 christos (*info->fprintf_func) (info->stream, "(%s-)",
617 1.1 christos (postbyte & 0x10) ? "y": "x");
618 1.1 christos
619 1.1 christos break;
620 1.1 christos }
621 1.1 christos case OPR_S_PRE_DEC:
622 1.1 christos {
623 1.1 christos (*info->fprintf_func) (info->stream, "(-s)");
624 1.1 christos break;
625 1.1 christos }
626 1.1 christos case OPR_S_POST_INC:
627 1.1 christos {
628 1.1 christos (*info->fprintf_func) (info->stream, "(s+)");
629 1.1 christos break;
630 1.1 christos }
631 1.1 christos
632 1.1 christos case OPR_EXT18:
633 1.1 christos {
634 1.1 christos const size_t size = 2;
635 1.1 christos bfd_byte buffer[4];
636 1.1 christos status = read_memory (memaddr + 1, buffer, size, info);
637 1.1 christos if (status < 0)
638 1.1 christos return;
639 1.1 christos
640 1.1 christos uint32_t ext18 = 0;
641 1.1 christos for (i = 0; i < size; ++i)
642 1.1 christos {
643 1.1 christos ext18 <<= 8;
644 1.1 christos ext18 |= buffer[i];
645 1.1 christos }
646 1.1 christos
647 1.1 christos ext18 |= (postbyte & 0x01) << 16;
648 1.1 christos ext18 |= (postbyte & 0x04) << 15;
649 1.1 christos
650 1.1 christos decode_possible_symbol (ext18, info);
651 1.1 christos break;
652 1.1 christos }
653 1.1 christos
654 1.1 christos case OPR_EXT1:
655 1.1 christos {
656 1.1 christos uint8_t x1 = 0;
657 1.1 christos read_memory (memaddr + 1, &x1, 1, info);
658 1.1 christos int16_t addr;
659 1.1 christos addr = x1;
660 1.1 christos addr |= (postbyte & 0x3f) << 8;
661 1.1 christos
662 1.1 christos decode_possible_symbol (addr, info);
663 1.1 christos break;
664 1.1 christos }
665 1.1 christos
666 1.1 christos case OPR_EXT3_DIRECT:
667 1.1 christos {
668 1.1 christos const size_t size = 3;
669 1.1 christos bfd_byte buffer[4];
670 1.1 christos status = read_memory (memaddr + 1, buffer, size, info);
671 1.1 christos if (status < 0)
672 1.1 christos return;
673 1.1 christos
674 1.1 christos uint32_t ext24 = 0;
675 1.1 christos for (i = 0; i < size; ++i)
676 1.1 christos {
677 1.1 christos ext24 |= buffer[i] << (8 * (size - i - 1));
678 1.1 christos }
679 1.1 christos
680 1.1 christos decode_possible_symbol (ext24, info);
681 1.1 christos break;
682 1.1 christos }
683 1.1 christos
684 1.1 christos case OPR_EXT3_INDIRECT:
685 1.1 christos {
686 1.1 christos const size_t size = 3;
687 1.1 christos bfd_byte buffer[4];
688 1.1 christos status = read_memory (memaddr + 1, buffer, size, info);
689 1.1 christos if (status < 0)
690 1.1 christos return;
691 1.1 christos
692 1.1 christos uint32_t ext24 = 0;
693 1.1 christos for (i = 0; i < size; ++i)
694 1.1 christos {
695 1.1 christos ext24 |= buffer[i] << (8 * (size - i - 1));
696 1.1 christos }
697 1.1 christos
698 1.1 christos (*info->fprintf_func) (info->stream, "[%d]", ext24);
699 1.1 christos
700 1.1 christos break;
701 1.1 christos }
702 1.1 christos
703 1.1 christos default:
704 1.1 christos (*info->fprintf_func) (info->stream, "Unknown OPR mode #0x%x (%d)", postbyte, mode);
705 1.1 christos }
706 1.1 christos }
707 1.1 christos
708 1.1 christos
709 1.1 christos static void
710 1.1 christos opr_decode2 (bfd_vma memaddr, struct disassemble_info* info)
711 1.1 christos {
712 1.1 christos int n = opr_n_bytes (memaddr, info);
713 1.1 christos opr_decode (memaddr, info);
714 1.1 christos opr_decode (memaddr + n, info);
715 1.1 christos }
716 1.1 christos
717 1.1 christos static void
718 1.1 christos imm1234 (bfd_vma memaddr, struct disassemble_info* info, int base)
719 1.1 christos {
720 1.1 christos bfd_byte opcode;
721 1.1 christos int status = read_memory (memaddr - 1, &opcode, 1, info);
722 1.1 christos if (status < 0)
723 1.1 christos return;
724 1.1 christos
725 1.1 christos opcode -= base;
726 1.1 christos
727 1.1 christos int size = registers[opcode & 0xF].bytes;
728 1.1 christos
729 1.1 christos uint32_t imm = decode_signed_value (memaddr, info, size);
730 1.1 christos operand_separator (info);
731 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
732 1.1 christos }
733 1.1 christos
734 1.1 christos
735 1.1 christos /* Special case of LD and CMP with register S and IMM operand */
736 1.1 christos static void
737 1.1 christos reg_s_imm (bfd_vma memaddr, struct disassemble_info* info)
738 1.1 christos {
739 1.1 christos operand_separator (info);
740 1.1 christos (*info->fprintf_func) (info->stream, "s");
741 1.1 christos
742 1.1 christos uint32_t imm = decode_signed_value (memaddr, info, 3);
743 1.1 christos operand_separator (info);
744 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
745 1.1 christos }
746 1.1 christos
747 1.1 christos /* Special case of LD, CMP and ST with register S and OPR operand */
748 1.1 christos static void
749 1.1 christos reg_s_opr (bfd_vma memaddr, struct disassemble_info* info)
750 1.1 christos {
751 1.1 christos operand_separator (info);
752 1.1 christos (*info->fprintf_func) (info->stream, "s");
753 1.1 christos
754 1.1 christos opr_decode (memaddr, info);
755 1.1 christos }
756 1.1 christos
757 1.1 christos static void
758 1.1 christos imm1234_8base (bfd_vma memaddr, struct disassemble_info* info)
759 1.1 christos {
760 1.1 christos imm1234 (memaddr, info, 8);
761 1.1 christos }
762 1.1 christos
763 1.1 christos static void
764 1.1 christos imm1234_0base (bfd_vma memaddr, struct disassemble_info* info)
765 1.1 christos {
766 1.1 christos imm1234 (memaddr, info, 0);
767 1.1 christos }
768 1.1 christos
769 1.1 christos static void
770 1.1 christos tfr (bfd_vma memaddr, struct disassemble_info* info)
771 1.1 christos {
772 1.1 christos bfd_byte byte;
773 1.1 christos int status = read_memory (memaddr, &byte, 1, info);
774 1.1 christos if (status < 0)
775 1.1 christos return;
776 1.1 christos
777 1.1 christos operand_separator (info);
778 1.1 christos (*info->fprintf_func) (info->stream, "%s, %s",
779 1.1 christos registers[byte >> 4].name,
780 1.1 christos registers[byte & 0xF].name);
781 1.1 christos }
782 1.1 christos
783 1.1 christos
784 1.1 christos static void
785 1.1 christos reg (bfd_vma memaddr, struct disassemble_info* info)
786 1.1 christos {
787 1.1 christos bfd_byte byte;
788 1.1 christos int status = read_memory (memaddr - 1, &byte, 1, info);
789 1.1 christos if (status < 0)
790 1.1 christos return;
791 1.1 christos
792 1.1 christos operand_separator (info);
793 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x07].name);
794 1.1 christos }
795 1.1 christos
796 1.1 christos static void
797 1.1 christos reg_xy (bfd_vma memaddr, struct disassemble_info* info)
798 1.1 christos {
799 1.1 christos bfd_byte byte;
800 1.1 christos int status = read_memory (memaddr - 1, &byte, 1, info);
801 1.1 christos if (status < 0)
802 1.1 christos return;
803 1.1 christos
804 1.1 christos operand_separator (info);
805 1.1 christos (*info->fprintf_func) (info->stream, "%s", (byte & 0x01) ? "y" : "x");
806 1.1 christos }
807 1.1 christos
808 1.1 christos static void
809 1.1 christos lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info)
810 1.1 christos {
811 1.1 christos bfd_byte byte;
812 1.1 christos int status = read_memory (memaddr - 1, &byte, 1, info);
813 1.1 christos if (status < 0)
814 1.1 christos return;
815 1.1 christos
816 1.1 christos char *reg = NULL;
817 1.1 christos switch (byte & 0x03)
818 1.1 christos {
819 1.1 christos case 0x00:
820 1.1 christos reg = "x";
821 1.1 christos break;
822 1.1 christos case 0x01:
823 1.1 christos reg = "y";
824 1.1 christos break;
825 1.1 christos case 0x02:
826 1.1 christos reg = "s";
827 1.1 christos break;
828 1.1 christos }
829 1.1 christos
830 1.1 christos operand_separator (info);
831 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg);
832 1.1 christos opr_decode (memaddr, info);
833 1.1 christos }
834 1.1 christos
835 1.1 christos
836 1.1 christos
837 1.1 christos static void
838 1.1 christos lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info)
839 1.1 christos {
840 1.1 christos bfd_byte byte;
841 1.1 christos int status = read_memory (memaddr - 1, &byte, 1, info);
842 1.1 christos if (status < 0)
843 1.1 christos return;
844 1.1 christos
845 1.1 christos char *reg = NULL;
846 1.1 christos switch (byte & 0x03)
847 1.1 christos {
848 1.1 christos case 0x00:
849 1.1 christos reg = "x";
850 1.1 christos break;
851 1.1 christos case 0x01:
852 1.1 christos reg = "y";
853 1.1 christos break;
854 1.1 christos case 0x02:
855 1.1 christos reg = "s";
856 1.1 christos break;
857 1.1 christos }
858 1.1 christos
859 1.1 christos status = read_memory (memaddr, &byte, 1, info);
860 1.1 christos if (status < 0)
861 1.1 christos return;
862 1.1 christos
863 1.1 christos int8_t v = byte;
864 1.1 christos
865 1.1 christos operand_separator (info);
866 1.1 christos (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg, v, reg);
867 1.1 christos }
868 1.1 christos
869 1.1 christos
870 1.1 christos /* PC Relative offsets of size 15 or 7 bits */
871 1.1 christos static void
872 1.1 christos rel_15_7 (bfd_vma memaddr, struct disassemble_info* info, int offset)
873 1.1 christos {
874 1.1 christos bfd_byte upper;
875 1.1 christos int status = read_memory (memaddr, &upper, 1, info);
876 1.1 christos if (status < 0)
877 1.1 christos return;
878 1.1 christos
879 1.1 christos bool rel_size = (upper & 0x80);
880 1.1 christos
881 1.1 christos int16_t addr = upper;
882 1.1 christos if (rel_size)
883 1.1 christos {
884 1.1 christos /* 15 bits. Get the next byte */
885 1.1 christos bfd_byte lower;
886 1.1 christos status = read_memory (memaddr + 1, &lower, 1, info);
887 1.1 christos if (status < 0)
888 1.1 christos return;
889 1.1 christos
890 1.1 christos addr <<= 8;
891 1.1 christos addr |= lower;
892 1.1 christos addr &= 0x7FFF;
893 1.1 christos
894 1.1 christos bool negative = (addr & 0x4000);
895 1.1 christos addr &= 0x3FFF;
896 1.1 christos if (negative)
897 1.1 christos addr = addr - 0x4000;
898 1.1 christos }
899 1.1 christos else
900 1.1 christos {
901 1.1 christos /* 7 bits. */
902 1.1 christos bool negative = (addr & 0x40);
903 1.1 christos addr &= 0x3F;
904 1.1 christos if (negative)
905 1.1 christos addr = addr - 0x40;
906 1.1 christos }
907 1.1 christos
908 1.1 christos operand_separator (info);
909 1.1 christos if (!info->symbol_at_address_func (addr + memaddr - offset, info))
910 1.1 christos {
911 1.1 christos (*info->fprintf_func) (info->stream, "*%+d", addr);
912 1.1 christos }
913 1.1 christos else
914 1.1 christos {
915 1.1 christos asymbol *sym = NULL;
916 1.1 christos int i;
917 1.1 christos for (i = 0; i < info->symtab_size; ++i)
918 1.1 christos {
919 1.1 christos sym = info->symtab[i];
920 1.1 christos if (bfd_asymbol_value (sym) == addr + memaddr - offset)
921 1.1 christos {
922 1.1 christos break;
923 1.1 christos }
924 1.1 christos }
925 1.1 christos if (i < info->symtab_size)
926 1.1 christos (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
927 1.1 christos }
928 1.1 christos }
929 1.1 christos
930 1.1 christos
931 1.1 christos /* PC Relative offsets of size 15 or 7 bits */
932 1.1 christos static void
933 1.1 christos decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info)
934 1.1 christos {
935 1.1 christos rel_15_7 (memaddr, info, 1);
936 1.1 christos }
937 1.1 christos
938 1.1 christos struct opcode
939 1.1 christos {
940 1.1 christos const char *mnemonic;
941 1.1 christos insn_bytes_f insn_bytes;
942 1.1 christos operands_f operands;
943 1.1 christos operands_f operands2;
944 1.1 christos };
945 1.1 christos
946 1.1 christos static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
947 1.1 christos static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
948 1.1 christos static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
949 1.1 christos static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info);
950 1.1 christos static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info);
951 1.1 christos static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
952 1.1 christos static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
953 1.1 christos static void mul_decode (bfd_vma memaddr, struct disassemble_info* info);
954 1.1 christos static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
955 1.1 christos static void bm_decode (bfd_vma memaddr, struct disassemble_info* info);
956 1.1 christos
957 1.1 christos static void
958 1.1 christos cmp_xy (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
959 1.1 christos {
960 1.1 christos operand_separator (info);
961 1.1 christos (*info->fprintf_func) (info->stream, "x, y");
962 1.1 christos }
963 1.1 christos
964 1.1 christos static void
965 1.1 christos sub_d6_x_y (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
966 1.1 christos {
967 1.1 christos operand_separator (info);
968 1.1 christos (*info->fprintf_func) (info->stream, "d6, x, y");
969 1.1 christos }
970 1.1 christos
971 1.1 christos static void
972 1.1 christos sub_d6_y_x (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
973 1.1 christos {
974 1.1 christos operand_separator (info);
975 1.1 christos (*info->fprintf_func) (info->stream, "d6, y, x");
976 1.1 christos }
977 1.1 christos
978 1.1 christos static const char shift_size_table[] = {
979 1.1 christos 'b', 'w', 'p', 'l'
980 1.1 christos };
981 1.1 christos
982 1.1 christos static const struct opcode page2[] =
983 1.1 christos {
984 1.1 christos [0x00] = {"ld", opr_n_bytes_p1, 0, reg_s_opr},
985 1.1 christos [0x01] = {"st", opr_n_bytes_p1, 0, reg_s_opr},
986 1.1 christos [0x02] = {"cmp", opr_n_bytes_p1, 0, reg_s_opr},
987 1.1 christos [0x03] = {"ld", four, 0, reg_s_imm},
988 1.1 christos [0x04] = {"cmp", four, 0, reg_s_imm},
989 1.1 christos [0x05] = {"stop", single, 0, 0},
990 1.1 christos [0x06] = {"wai", single, 0, 0},
991 1.1 christos [0x07] = {"sys", single, 0, 0},
992 1.1 christos [0x08] = {NULL, bfextins_n_bytes, 0, 0}, /* BFEXT / BFINS */
993 1.1 christos [0x09] = {NULL, bfextins_n_bytes, 0, 0},
994 1.1 christos [0x0a] = {NULL, bfextins_n_bytes, 0, 0},
995 1.1 christos [0x0b] = {NULL, bfextins_n_bytes, 0, 0},
996 1.1 christos [0x0c] = {NULL, bfextins_n_bytes, 0, 0},
997 1.1 christos [0x0d] = {NULL, bfextins_n_bytes, 0, 0},
998 1.1 christos [0x0e] = {NULL, bfextins_n_bytes, 0, 0},
999 1.1 christos [0x0f] = {NULL, bfextins_n_bytes, 0, 0},
1000 1.1 christos [0x10] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1001 1.1 christos [0x11] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1002 1.1 christos [0x12] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1003 1.1 christos [0x13] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1004 1.1 christos [0x14] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1005 1.1 christos [0x15] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1006 1.1 christos [0x16] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1007 1.1 christos [0x17] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1008 1.1 christos [0x18] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1009 1.1 christos [0x19] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1010 1.1 christos [0x1a] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1011 1.1 christos [0x1b] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1012 1.1 christos [0x1c] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1013 1.1 christos [0x1d] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1014 1.1 christos [0x1e] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1015 1.1 christos [0x1f] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1016 1.1 christos [0x20] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1017 1.1 christos [0x21] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1018 1.1 christos [0x22] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1019 1.1 christos [0x23] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1020 1.1 christos [0x24] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1021 1.1 christos [0x25] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1022 1.1 christos [0x26] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1023 1.1 christos [0x27] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1024 1.1 christos [0x28] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1025 1.1 christos [0x29] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1026 1.1 christos [0x2a] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1027 1.1 christos [0x2b] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1028 1.1 christos [0x2c] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1029 1.1 christos [0x2d] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1030 1.1 christos [0x2e] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1031 1.1 christos [0x2f] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1032 1.1 christos [0x30] = {"div", mul_n_bytes, mul_decode, 0},
1033 1.1 christos [0x31] = {"div", mul_n_bytes, mul_decode, 0},
1034 1.1 christos [0x32] = {"div", mul_n_bytes, mul_decode, 0},
1035 1.1 christos [0x33] = {"div", mul_n_bytes, mul_decode, 0},
1036 1.1 christos [0x34] = {"div", mul_n_bytes, mul_decode, 0},
1037 1.1 christos [0x35] = {"div", mul_n_bytes, mul_decode, 0},
1038 1.1 christos [0x36] = {"div", mul_n_bytes, mul_decode, 0},
1039 1.1 christos [0x37] = {"div", mul_n_bytes, mul_decode, 0},
1040 1.1 christos [0x38] = {"mod", mul_n_bytes, mul_decode, 0},
1041 1.1 christos [0x39] = {"mod", mul_n_bytes, mul_decode, 0},
1042 1.1 christos [0x3a] = {"mod", mul_n_bytes, mul_decode, 0},
1043 1.1 christos [0x3b] = {"mod", mul_n_bytes, mul_decode, 0},
1044 1.1 christos [0x3c] = {"mod", mul_n_bytes, mul_decode, 0},
1045 1.1 christos [0x3d] = {"mod", mul_n_bytes, mul_decode, 0},
1046 1.1 christos [0x3e] = {"mod", mul_n_bytes, mul_decode, 0},
1047 1.1 christos [0x3f] = {"mod", mul_n_bytes, mul_decode, 0},
1048 1.1 christos [0x40] = {"abs", single, reg, 0},
1049 1.1 christos [0x41] = {"abs", single, reg, 0},
1050 1.1 christos [0x42] = {"abs", single, reg, 0},
1051 1.1 christos [0x43] = {"abs", single, reg, 0},
1052 1.1 christos [0x44] = {"abs", single, reg, 0},
1053 1.1 christos [0x45] = {"abs", single, reg, 0},
1054 1.1 christos [0x46] = {"abs", single, reg, 0},
1055 1.1 christos [0x47] = {"abs", single, reg, 0},
1056 1.1 christos [0x48] = {"mac", mul_n_bytes, mul_decode, 0},
1057 1.1 christos [0x49] = {"mac", mul_n_bytes, mul_decode, 0},
1058 1.1 christos [0x4a] = {"mac", mul_n_bytes, mul_decode, 0},
1059 1.1 christos [0x4b] = {"mac", mul_n_bytes, mul_decode, 0},
1060 1.1 christos [0x4c] = {"mac", mul_n_bytes, mul_decode, 0},
1061 1.1 christos [0x4d] = {"mac", mul_n_bytes, mul_decode, 0},
1062 1.1 christos [0x4e] = {"mac", mul_n_bytes, mul_decode, 0},
1063 1.1 christos [0x4f] = {"mac", mul_n_bytes, mul_decode, 0},
1064 1.1 christos [0x50] = {"adc", three, reg, imm1234_0base},
1065 1.1 christos [0x51] = {"adc", three, reg, imm1234_0base},
1066 1.1 christos [0x52] = {"adc", three, reg, imm1234_0base},
1067 1.1 christos [0x53] = {"adc", three, reg, imm1234_0base},
1068 1.1 christos [0x54] = {"adc", two, reg, imm1234_0base},
1069 1.1 christos [0x55] = {"adc", two, reg, imm1234_0base},
1070 1.1 christos [0x56] = {"adc", five, reg, imm1234_0base},
1071 1.1 christos [0x57] = {"adc", five, reg, imm1234_0base},
1072 1.1 christos [0x58] = {"bit", three, reg, imm1234_8base},
1073 1.1 christos [0x59] = {"bit", three, reg, imm1234_8base},
1074 1.1 christos [0x5a] = {"bit", three, reg, imm1234_8base},
1075 1.1 christos [0x5b] = {"bit", three, reg, imm1234_8base},
1076 1.1 christos [0x5c] = {"bit", two, reg, imm1234_8base},
1077 1.1 christos [0x5d] = {"bit", two, reg, imm1234_8base},
1078 1.1 christos [0x5e] = {"bit", five, reg, imm1234_8base},
1079 1.1 christos [0x5f] = {"bit", five, reg, imm1234_8base},
1080 1.1 christos [0x60] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1081 1.1 christos [0x61] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1082 1.1 christos [0x62] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1083 1.1 christos [0x63] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1084 1.1 christos [0x64] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1085 1.1 christos [0x65] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1086 1.1 christos [0x66] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1087 1.1 christos [0x67] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1088 1.1 christos [0x68] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1089 1.1 christos [0x69] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1090 1.1 christos [0x6a] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1091 1.1 christos [0x6b] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1092 1.1 christos [0x6c] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1093 1.1 christos [0x6d] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1094 1.1 christos [0x6e] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1095 1.1 christos [0x6f] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1096 1.1 christos [0x70] = {"sbc", three, reg, imm1234_0base},
1097 1.1 christos [0x71] = {"sbc", three, reg, imm1234_0base},
1098 1.1 christos [0x72] = {"sbc", three, reg, imm1234_0base},
1099 1.1 christos [0x73] = {"sbc", three, reg, imm1234_0base},
1100 1.1 christos [0x74] = {"sbc", two, reg, imm1234_0base},
1101 1.1 christos [0x75] = {"sbc", two, reg, imm1234_0base},
1102 1.1 christos [0x76] = {"sbc", five, reg, imm1234_0base},
1103 1.1 christos [0x77] = {"sbc", five, reg, imm1234_0base},
1104 1.1 christos [0x78] = {"eor", three, reg, imm1234_8base},
1105 1.1 christos [0x79] = {"eor", three, reg, imm1234_8base},
1106 1.1 christos [0x7a] = {"eor", three, reg, imm1234_8base},
1107 1.1 christos [0x7b] = {"eor", three, reg, imm1234_8base},
1108 1.1 christos [0x7c] = {"eor", two, reg, imm1234_8base},
1109 1.1 christos [0x7d] = {"eor", two, reg, imm1234_8base},
1110 1.1 christos [0x7e] = {"eor", five, reg, imm1234_8base},
1111 1.1 christos [0x7f] = {"eor", five, reg, imm1234_8base},
1112 1.1 christos [0x80] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1113 1.1 christos [0x81] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1114 1.1 christos [0x82] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1115 1.1 christos [0x83] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1116 1.1 christos [0x84] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1117 1.1 christos [0x85] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1118 1.1 christos [0x86] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1119 1.1 christos [0x87] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1120 1.1 christos [0x88] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1121 1.1 christos [0x89] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1122 1.1 christos [0x8a] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1123 1.1 christos [0x8b] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1124 1.1 christos [0x8c] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1125 1.1 christos [0x8d] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1126 1.1 christos [0x8e] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1127 1.1 christos [0x8f] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1128 1.1 christos [0x90] = {"rti", single, 0, 0},
1129 1.1 christos [0x91] = {"clb", two, tfr, 0},
1130 1.1 christos [0x92] = {"trap", single, trap_decode, 0},
1131 1.1 christos [0x93] = {"trap", single, trap_decode, 0},
1132 1.1 christos [0x94] = {"trap", single, trap_decode, 0},
1133 1.1 christos [0x95] = {"trap", single, trap_decode, 0},
1134 1.1 christos [0x96] = {"trap", single, trap_decode, 0},
1135 1.1 christos [0x97] = {"trap", single, trap_decode, 0},
1136 1.1 christos [0x98] = {"trap", single, trap_decode, 0},
1137 1.1 christos [0x99] = {"trap", single, trap_decode, 0},
1138 1.1 christos [0x9a] = {"trap", single, trap_decode, 0},
1139 1.1 christos [0x9b] = {"trap", single, trap_decode, 0},
1140 1.1 christos [0x9c] = {"trap", single, trap_decode, 0},
1141 1.1 christos [0x9d] = {"trap", single, trap_decode, 0},
1142 1.1 christos [0x9e] = {"trap", single, trap_decode, 0},
1143 1.1 christos [0x9f] = {"trap", single, trap_decode, 0},
1144 1.1 christos [0xa0] = {"sat", single, reg, 0},
1145 1.1 christos [0xa1] = {"sat", single, reg, 0},
1146 1.1 christos [0xa2] = {"sat", single, reg, 0},
1147 1.1 christos [0xa3] = {"sat", single, reg, 0},
1148 1.1 christos [0xa4] = {"sat", single, reg, 0},
1149 1.1 christos [0xa5] = {"sat", single, reg, 0},
1150 1.1 christos [0xa6] = {"sat", single, reg, 0},
1151 1.1 christos [0xa7] = {"sat", single, reg, 0},
1152 1.1 christos [0xa8] = {"trap", single, trap_decode, 0},
1153 1.1 christos [0xa9] = {"trap", single, trap_decode, 0},
1154 1.1 christos [0xaa] = {"trap", single, trap_decode, 0},
1155 1.1 christos [0xab] = {"trap", single, trap_decode, 0},
1156 1.1 christos [0xac] = {"trap", single, trap_decode, 0},
1157 1.1 christos [0xad] = {"trap", single, trap_decode, 0},
1158 1.1 christos [0xae] = {"trap", single, trap_decode, 0},
1159 1.1 christos [0xaf] = {"trap", single, trap_decode, 0},
1160 1.1 christos [0xb0] = {"qmul", mul_n_bytes, mul_decode, 0},
1161 1.1 christos [0xb1] = {"qmul", mul_n_bytes, mul_decode, 0},
1162 1.1 christos [0xb2] = {"qmul", mul_n_bytes, mul_decode, 0},
1163 1.1 christos [0xb3] = {"qmul", mul_n_bytes, mul_decode, 0},
1164 1.1 christos [0xb4] = {"qmul", mul_n_bytes, mul_decode, 0},
1165 1.1 christos [0xb5] = {"qmul", mul_n_bytes, mul_decode, 0},
1166 1.1 christos [0xb6] = {"qmul", mul_n_bytes, mul_decode, 0},
1167 1.1 christos [0xb7] = {"qmul", mul_n_bytes, mul_decode, 0},
1168 1.1 christos [0xb8] = {"trap", single, trap_decode, 0},
1169 1.1 christos [0xb9] = {"trap", single, trap_decode, 0},
1170 1.1 christos [0xba] = {"trap", single, trap_decode, 0},
1171 1.1 christos [0xbb] = {"trap", single, trap_decode, 0},
1172 1.1 christos [0xbc] = {"trap", single, trap_decode, 0},
1173 1.1 christos [0xbd] = {"trap", single, trap_decode, 0},
1174 1.1 christos [0xbe] = {"trap", single, trap_decode, 0},
1175 1.1 christos [0xbf] = {"trap", single, trap_decode, 0},
1176 1.1 christos [0xc0] = {"trap", single, trap_decode, 0},
1177 1.1 christos [0xc1] = {"trap", single, trap_decode, 0},
1178 1.1 christos [0xc2] = {"trap", single, trap_decode, 0},
1179 1.1 christos [0xc3] = {"trap", single, trap_decode, 0},
1180 1.1 christos [0xc4] = {"trap", single, trap_decode, 0},
1181 1.1 christos [0xc5] = {"trap", single, trap_decode, 0},
1182 1.1 christos [0xc6] = {"trap", single, trap_decode, 0},
1183 1.1 christos [0xc7] = {"trap", single, trap_decode, 0},
1184 1.1 christos [0xc8] = {"trap", single, trap_decode, 0},
1185 1.1 christos [0xc9] = {"trap", single, trap_decode, 0},
1186 1.1 christos [0xca] = {"trap", single, trap_decode, 0},
1187 1.1 christos [0xcb] = {"trap", single, trap_decode, 0},
1188 1.1 christos [0xcc] = {"trap", single, trap_decode, 0},
1189 1.1 christos [0xcd] = {"trap", single, trap_decode, 0},
1190 1.1 christos [0xce] = {"trap", single, trap_decode, 0},
1191 1.1 christos [0xcf] = {"trap", single, trap_decode, 0},
1192 1.1 christos [0xd0] = {"trap", single, trap_decode, 0},
1193 1.1 christos [0xd1] = {"trap", single, trap_decode, 0},
1194 1.1 christos [0xd2] = {"trap", single, trap_decode, 0},
1195 1.1 christos [0xd3] = {"trap", single, trap_decode, 0},
1196 1.1 christos [0xd4] = {"trap", single, trap_decode, 0},
1197 1.1 christos [0xd5] = {"trap", single, trap_decode, 0},
1198 1.1 christos [0xd6] = {"trap", single, trap_decode, 0},
1199 1.1 christos [0xd7] = {"trap", single, trap_decode, 0},
1200 1.1 christos [0xd8] = {"trap", single, trap_decode, 0},
1201 1.1 christos [0xd9] = {"trap", single, trap_decode, 0},
1202 1.1 christos [0xda] = {"trap", single, trap_decode, 0},
1203 1.1 christos [0xdb] = {"trap", single, trap_decode, 0},
1204 1.1 christos [0xdc] = {"trap", single, trap_decode, 0},
1205 1.1 christos [0xdd] = {"trap", single, trap_decode, 0},
1206 1.1 christos [0xde] = {"trap", single, trap_decode, 0},
1207 1.1 christos [0xdf] = {"trap", single, trap_decode, 0},
1208 1.1 christos [0xe0] = {"trap", single, trap_decode, 0},
1209 1.1 christos [0xe1] = {"trap", single, trap_decode, 0},
1210 1.1 christos [0xe2] = {"trap", single, trap_decode, 0},
1211 1.1 christos [0xe3] = {"trap", single, trap_decode, 0},
1212 1.1 christos [0xe4] = {"trap", single, trap_decode, 0},
1213 1.1 christos [0xe5] = {"trap", single, trap_decode, 0},
1214 1.1 christos [0xe6] = {"trap", single, trap_decode, 0},
1215 1.1 christos [0xe7] = {"trap", single, trap_decode, 0},
1216 1.1 christos [0xe8] = {"trap", single, trap_decode, 0},
1217 1.1 christos [0xe9] = {"trap", single, trap_decode, 0},
1218 1.1 christos [0xea] = {"trap", single, trap_decode, 0},
1219 1.1 christos [0xeb] = {"trap", single, trap_decode, 0},
1220 1.1 christos [0xec] = {"trap", single, trap_decode, 0},
1221 1.1 christos [0xed] = {"trap", single, trap_decode, 0},
1222 1.1 christos [0xee] = {"trap", single, trap_decode, 0},
1223 1.1 christos [0xef] = {"trap", single, trap_decode, 0},
1224 1.1 christos [0xf0] = {"trap", single, trap_decode, 0},
1225 1.1 christos [0xf1] = {"trap", single, trap_decode, 0},
1226 1.1 christos [0xf2] = {"trap", single, trap_decode, 0},
1227 1.1 christos [0xf3] = {"trap", single, trap_decode, 0},
1228 1.1 christos [0xf4] = {"trap", single, trap_decode, 0},
1229 1.1 christos [0xf5] = {"trap", single, trap_decode, 0},
1230 1.1 christos [0xf6] = {"trap", single, trap_decode, 0},
1231 1.1 christos [0xf7] = {"trap", single, trap_decode, 0},
1232 1.1 christos [0xf8] = {"trap", single, trap_decode, 0},
1233 1.1 christos [0xf9] = {"trap", single, trap_decode, 0},
1234 1.1 christos [0xfa] = {"trap", single, trap_decode, 0},
1235 1.1 christos [0xfb] = {"trap", single, trap_decode, 0},
1236 1.1 christos [0xfc] = {"trap", single, trap_decode, 0},
1237 1.1 christos [0xfd] = {"trap", single, trap_decode, 0},
1238 1.1 christos [0xfe] = {"trap", single, trap_decode, 0},
1239 1.1 christos [0xff] = {"trap", single, trap_decode, 0},
1240 1.1 christos };
1241 1.1 christos
1242 1.1 christos static const struct opcode page1[] =
1243 1.1 christos {
1244 1.1 christos [0x00] = {"bgnd", single, 0, 0},
1245 1.1 christos [0x01] = {"nop", single, 0, 0},
1246 1.1 christos [0x02] = {"brclr", bm_rel_n_bytes, bm_rel_decode, 0},
1247 1.1 christos [0x03] = {"brset", bm_rel_n_bytes, bm_rel_decode, 0},
1248 1.1 christos [0x04] = {NULL, two, 0, 0}, /* psh/pul */
1249 1.1 christos [0x05] = {"rts", single, 0, 0},
1250 1.1 christos [0x06] = {"lea", opr_n_bytes_p1, reg, opr_decode},
1251 1.1 christos [0x07] = {"lea", opr_n_bytes_p1, reg, opr_decode},
1252 1.1 christos [0x08] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
1253 1.1 christos [0x09] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
1254 1.1 christos [0x0a] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
1255 1.1 christos [0x0b] = {NULL, loop_prim_n_bytes, 0, 0}, /* Loop primitives TBcc / DBcc */
1256 1.1 christos [0x0c] = {"mov.b", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1257 1.1 christos [0x0d] = {"mov.w", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1258 1.1 christos [0x0e] = {"mov.p", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1259 1.1 christos [0x0f] = {"mov.l", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1260 1.1 christos [0x10] = {NULL, shift_n_bytes, 0, 0}, /* lsr/lsl/asl/asr/rol/ror */
1261 1.1 christos [0x11] = {NULL, shift_n_bytes, 0, 0},
1262 1.1 christos [0x12] = {NULL, shift_n_bytes, 0, 0},
1263 1.1 christos [0x13] = {NULL, shift_n_bytes, 0, 0},
1264 1.1 christos [0x14] = {NULL, shift_n_bytes, 0, 0},
1265 1.1 christos [0x15] = {NULL, shift_n_bytes, 0, 0},
1266 1.1 christos [0x16] = {NULL, shift_n_bytes, 0, 0},
1267 1.1 christos [0x17] = {NULL, shift_n_bytes, 0, 0},
1268 1.1 christos [0x18] = {"lea", two, lea_reg_xys, NULL},
1269 1.1 christos [0x19] = {"lea", two, lea_reg_xys, NULL},
1270 1.1 christos [0x1a] = {"lea", two, lea_reg_xys, NULL},
1271 1.1 christos /* 0x1b PG2 */
1272 1.1 christos [0x1c] = {"mov.b", opr_n_bytes2, 0, opr_decode2},
1273 1.1 christos [0x1d] = {"mov.w", opr_n_bytes2, 0, opr_decode2},
1274 1.1 christos [0x1e] = {"mov.p", opr_n_bytes2, 0, opr_decode2},
1275 1.1 christos [0x1f] = {"mov.l", opr_n_bytes2, 0, opr_decode2},
1276 1.1 christos [0x20] = {"bra", pcrel_15bit, decode_rel_15_7, 0},
1277 1.1 christos [0x21] = {"bsr", pcrel_15bit, decode_rel_15_7, 0},
1278 1.1 christos [0x22] = {"bhi", pcrel_15bit, decode_rel_15_7, 0},
1279 1.1 christos [0x23] = {"bls", pcrel_15bit, decode_rel_15_7, 0},
1280 1.1 christos [0x24] = {"bcc", pcrel_15bit, decode_rel_15_7, 0},
1281 1.1 christos [0x25] = {"bcs", pcrel_15bit, decode_rel_15_7, 0},
1282 1.1 christos [0x26] = {"bne", pcrel_15bit, decode_rel_15_7, 0},
1283 1.1 christos [0x27] = {"beq", pcrel_15bit, decode_rel_15_7, 0},
1284 1.1 christos [0x28] = {"bvc", pcrel_15bit, decode_rel_15_7, 0},
1285 1.1 christos [0x29] = {"bvs", pcrel_15bit, decode_rel_15_7, 0},
1286 1.1 christos [0x2a] = {"bpl", pcrel_15bit, decode_rel_15_7, 0},
1287 1.1 christos [0x2b] = {"bmi", pcrel_15bit, decode_rel_15_7, 0},
1288 1.1 christos [0x2c] = {"bge", pcrel_15bit, decode_rel_15_7, 0},
1289 1.1 christos [0x2d] = {"blt", pcrel_15bit, decode_rel_15_7, 0},
1290 1.1 christos [0x2e] = {"bgt", pcrel_15bit, decode_rel_15_7, 0},
1291 1.1 christos [0x2f] = {"ble", pcrel_15bit, decode_rel_15_7, 0},
1292 1.1 christos [0x30] = {"inc", single, reg, 0},
1293 1.1 christos [0x31] = {"inc", single, reg, 0},
1294 1.1 christos [0x32] = {"inc", single, reg, 0},
1295 1.1 christos [0x33] = {"inc", single, reg, 0},
1296 1.1 christos [0x34] = {"inc", single, reg, 0},
1297 1.1 christos [0x35] = {"inc", single, reg, 0},
1298 1.1 christos [0x36] = {"inc", single, reg, 0},
1299 1.1 christos [0x37] = {"inc", single, reg, 0},
1300 1.1 christos [0x38] = {"clr", single, reg, 0},
1301 1.1 christos [0x39] = {"clr", single, reg, 0},
1302 1.1 christos [0x3a] = {"clr", single, reg, 0},
1303 1.1 christos [0x3b] = {"clr", single, reg, 0},
1304 1.1 christos [0x3c] = {"clr", single, reg, 0},
1305 1.1 christos [0x3d] = {"clr", single, reg, 0},
1306 1.1 christos [0x3e] = {"clr", single, reg, 0},
1307 1.1 christos [0x3f] = {"clr", single, reg, 0},
1308 1.1 christos [0x40] = {"dec", single, reg, 0},
1309 1.1 christos [0x41] = {"dec", single, reg, 0},
1310 1.1 christos [0x42] = {"dec", single, reg, 0},
1311 1.1 christos [0x43] = {"dec", single, reg, 0},
1312 1.1 christos [0x44] = {"dec", single, reg, 0},
1313 1.1 christos [0x45] = {"dec", single, reg, 0},
1314 1.1 christos [0x46] = {"dec", single, reg, 0},
1315 1.1 christos [0x47] = {"dec", single, reg, 0},
1316 1.1 christos [0x48] = {"mul", mul_n_bytes, mul_decode, 0},
1317 1.1 christos [0x49] = {"mul", mul_n_bytes, mul_decode, 0},
1318 1.1 christos [0x4a] = {"mul", mul_n_bytes, mul_decode, 0},
1319 1.1 christos [0x4b] = {"mul", mul_n_bytes, mul_decode, 0},
1320 1.1 christos [0x4c] = {"mul", mul_n_bytes, mul_decode, 0},
1321 1.1 christos [0x4d] = {"mul", mul_n_bytes, mul_decode, 0},
1322 1.1 christos [0x4e] = {"mul", mul_n_bytes, mul_decode, 0},
1323 1.1 christos [0x4f] = {"mul", mul_n_bytes, mul_decode, 0},
1324 1.1 christos [0x50] = {"add", three, reg, imm1234_0base},
1325 1.1 christos [0x51] = {"add", three, reg, imm1234_0base},
1326 1.1 christos [0x52] = {"add", three, reg, imm1234_0base},
1327 1.1 christos [0x53] = {"add", three, reg, imm1234_0base},
1328 1.1 christos [0x54] = {"add", two, reg, imm1234_0base},
1329 1.1 christos [0x55] = {"add", two, reg, imm1234_0base},
1330 1.1 christos [0x56] = {"add", five, reg, imm1234_0base},
1331 1.1 christos [0x57] = {"add", five, reg, imm1234_0base},
1332 1.1 christos [0x58] = {"and", three, reg, imm1234_8base},
1333 1.1 christos [0x59] = {"and", three, reg, imm1234_8base},
1334 1.1 christos [0x5a] = {"and", three, reg, imm1234_8base},
1335 1.1 christos [0x5b] = {"and", three, reg, imm1234_8base},
1336 1.1 christos [0x5c] = {"and", two, reg, imm1234_8base},
1337 1.1 christos [0x5d] = {"and", two, reg, imm1234_8base},
1338 1.1 christos [0x5e] = {"and", five, reg, imm1234_8base},
1339 1.1 christos [0x5f] = {"and", five, reg, imm1234_8base},
1340 1.1 christos [0x60] = {"add", opr_n_bytes_p1, reg, opr_decode},
1341 1.1 christos [0x61] = {"add", opr_n_bytes_p1, reg, opr_decode},
1342 1.1 christos [0x62] = {"add", opr_n_bytes_p1, reg, opr_decode},
1343 1.1 christos [0x63] = {"add", opr_n_bytes_p1, reg, opr_decode},
1344 1.1 christos [0x64] = {"add", opr_n_bytes_p1, reg, opr_decode},
1345 1.1 christos [0x65] = {"add", opr_n_bytes_p1, reg, opr_decode},
1346 1.1 christos [0x66] = {"add", opr_n_bytes_p1, reg, opr_decode},
1347 1.1 christos [0x67] = {"add", opr_n_bytes_p1, reg, opr_decode},
1348 1.1 christos [0x68] = {"and", opr_n_bytes_p1, reg, opr_decode},
1349 1.1 christos [0x69] = {"and", opr_n_bytes_p1, reg, opr_decode},
1350 1.1 christos [0x6a] = {"and", opr_n_bytes_p1, reg, opr_decode},
1351 1.1 christos [0x6b] = {"and", opr_n_bytes_p1, reg, opr_decode},
1352 1.1 christos [0x6c] = {"and", opr_n_bytes_p1, reg, opr_decode},
1353 1.1 christos [0x6d] = {"and", opr_n_bytes_p1, reg, opr_decode},
1354 1.1 christos [0x6e] = {"and", opr_n_bytes_p1, reg, opr_decode},
1355 1.1 christos [0x6f] = {"and", opr_n_bytes_p1, reg, opr_decode},
1356 1.1 christos [0x70] = {"sub", three, reg, imm1234_0base},
1357 1.1 christos [0x71] = {"sub", three, reg, imm1234_0base},
1358 1.1 christos [0x72] = {"sub", three, reg, imm1234_0base},
1359 1.1 christos [0x73] = {"sub", three, reg, imm1234_0base},
1360 1.1 christos [0x74] = {"sub", two, reg, imm1234_0base},
1361 1.1 christos [0x75] = {"sub", two, reg, imm1234_0base},
1362 1.1 christos [0x76] = {"sub", five, reg, imm1234_0base},
1363 1.1 christos [0x77] = {"sub", five, reg, imm1234_0base},
1364 1.1 christos [0x78] = {"or", three, reg, imm1234_8base},
1365 1.1 christos [0x79] = {"or", three, reg, imm1234_8base},
1366 1.1 christos [0x7a] = {"or", three, reg, imm1234_8base},
1367 1.1 christos [0x7b] = {"or", three, reg, imm1234_8base},
1368 1.1 christos [0x7c] = {"or", two, reg, imm1234_8base},
1369 1.1 christos [0x7d] = {"or", two, reg, imm1234_8base},
1370 1.1 christos [0x7e] = {"or", five, reg, imm1234_8base},
1371 1.1 christos [0x7f] = {"or", five, reg, imm1234_8base},
1372 1.1 christos [0x80] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1373 1.1 christos [0x81] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1374 1.1 christos [0x82] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1375 1.1 christos [0x83] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1376 1.1 christos [0x84] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1377 1.1 christos [0x85] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1378 1.1 christos [0x86] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1379 1.1 christos [0x87] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1380 1.1 christos [0x88] = {"or", opr_n_bytes_p1, reg, opr_decode},
1381 1.1 christos [0x89] = {"or", opr_n_bytes_p1, reg, opr_decode},
1382 1.1 christos [0x8a] = {"or", opr_n_bytes_p1, reg, opr_decode},
1383 1.1 christos [0x8b] = {"or", opr_n_bytes_p1, reg, opr_decode},
1384 1.1 christos [0x8c] = {"or", opr_n_bytes_p1, reg, opr_decode},
1385 1.1 christos [0x8d] = {"or", opr_n_bytes_p1, reg, opr_decode},
1386 1.1 christos [0x8e] = {"or", opr_n_bytes_p1, reg, opr_decode},
1387 1.1 christos [0x8f] = {"or", opr_n_bytes_p1, reg, opr_decode},
1388 1.1 christos [0x90] = {"ld", three, reg, imm1234_0base},
1389 1.1 christos [0x91] = {"ld", three, reg, imm1234_0base},
1390 1.1 christos [0x92] = {"ld", three, reg, imm1234_0base},
1391 1.1 christos [0x93] = {"ld", three, reg, imm1234_0base},
1392 1.1 christos [0x94] = {"ld", two, reg, imm1234_0base},
1393 1.1 christos [0x95] = {"ld", two, reg, imm1234_0base},
1394 1.1 christos [0x96] = {"ld", five, reg, imm1234_0base},
1395 1.1 christos [0x97] = {"ld", five, reg, imm1234_0base},
1396 1.1 christos [0x98] = {"ld", four, reg_xy, imm1234_0base},
1397 1.1 christos [0x99] = {"ld", four, reg_xy, imm1234_0base},
1398 1.1 christos [0x9a] = {"clr", single, reg_xy, 0},
1399 1.1 christos [0x9b] = {"clr", single, reg_xy, 0},
1400 1.1 christos [0x9c] = {"inc.b", opr_n_bytes_p1, 0, opr_decode},
1401 1.1 christos [0x9d] = {"inc.w", opr_n_bytes_p1, 0, opr_decode},
1402 1.1 christos [0x9e] = {"tfr", two, tfr, NULL},
1403 1.1 christos [0x9f] = {"inc.l", opr_n_bytes_p1, 0, opr_decode},
1404 1.1 christos [0xa0] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1405 1.1 christos [0xa1] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1406 1.1 christos [0xa2] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1407 1.1 christos [0xa3] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1408 1.1 christos [0xa4] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1409 1.1 christos [0xa5] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1410 1.1 christos [0xa6] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1411 1.1 christos [0xa7] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1412 1.1 christos [0xa8] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode},
1413 1.1 christos [0xa9] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode},
1414 1.1 christos [0xaa] = {"jmp", opr_n_bytes_p1, opr_decode, 0},
1415 1.1 christos [0xab] = {"jsr", opr_n_bytes_p1, opr_decode, 0},
1416 1.1 christos [0xac] = {"dec.b", opr_n_bytes_p1, 0, opr_decode},
1417 1.1 christos [0xad] = {"dec.w", opr_n_bytes_p1, 0, opr_decode},
1418 1.1 christos [0xae] = {NULL, two, 0, 0}, /* EXG / SEX */
1419 1.1 christos [0xaf] = {"dec.l", opr_n_bytes_p1, 0, opr_decode},
1420 1.1 christos [0xb0] = {"ld", four, reg, ext24_decode},
1421 1.1 christos [0xb1] = {"ld", four, reg, ext24_decode},
1422 1.1 christos [0xb2] = {"ld", four, reg, ext24_decode},
1423 1.1 christos [0xb3] = {"ld", four, reg, ext24_decode},
1424 1.1 christos [0xb4] = {"ld", four, reg, ext24_decode},
1425 1.1 christos [0xb5] = {"ld", four, reg, ext24_decode},
1426 1.1 christos [0xb6] = {"ld", four, reg, ext24_decode},
1427 1.1 christos [0xb7] = {"ld", four, reg, ext24_decode},
1428 1.1 christos [0xb8] = {"ld", four, reg_xy, ext24_decode},
1429 1.1 christos [0xb9] = {"ld", four, reg_xy, ext24_decode},
1430 1.1 christos [0xba] = {"jmp", four, ext24_decode, 0},
1431 1.1 christos [0xbb] = {"jsr", four, ext24_decode, 0},
1432 1.1 christos [0xbc] = {"clr.b", opr_n_bytes_p1, 0, opr_decode},
1433 1.1 christos [0xbd] = {"clr.w", opr_n_bytes_p1, 0, opr_decode},
1434 1.1 christos [0xbe] = {"clr.p", opr_n_bytes_p1, 0, opr_decode},
1435 1.1 christos [0xbf] = {"clr.l", opr_n_bytes_p1, 0, opr_decode},
1436 1.1 christos [0xc0] = {"st", opr_n_bytes_p1, reg, opr_decode},
1437 1.1 christos [0xc1] = {"st", opr_n_bytes_p1, reg, opr_decode},
1438 1.1 christos [0xc2] = {"st", opr_n_bytes_p1, reg, opr_decode},
1439 1.1 christos [0xc3] = {"st", opr_n_bytes_p1, reg, opr_decode},
1440 1.1 christos [0xc4] = {"st", opr_n_bytes_p1, reg, opr_decode},
1441 1.1 christos [0xc5] = {"st", opr_n_bytes_p1, reg, opr_decode},
1442 1.1 christos [0xc6] = {"st", opr_n_bytes_p1, reg, opr_decode},
1443 1.1 christos [0xc7] = {"st", opr_n_bytes_p1, reg, opr_decode},
1444 1.1 christos [0xc8] = {"st", opr_n_bytes_p1, reg_xy, opr_decode},
1445 1.1 christos [0xc9] = {"st", opr_n_bytes_p1, reg_xy, opr_decode},
1446 1.1 christos [0xca] = {"ld", three, reg_xy, ld_18bit_decode},
1447 1.1 christos [0xcb] = {"ld", three, reg_xy, ld_18bit_decode},
1448 1.1 christos [0xcc] = {"com.b", opr_n_bytes_p1, NULL, opr_decode},
1449 1.1 christos [0xcd] = {"com.w", opr_n_bytes_p1, NULL, opr_decode},
1450 1.1 christos [0xce] = {"andcc", two, imm1, 0},
1451 1.1 christos [0xcf] = {"com.l", opr_n_bytes_p1, NULL, opr_decode},
1452 1.1 christos [0xd0] = {"st", four, reg, ext24_decode},
1453 1.1 christos [0xd1] = {"st", four, reg, ext24_decode},
1454 1.1 christos [0xd2] = {"st", four, reg, ext24_decode},
1455 1.1 christos [0xd3] = {"st", four, reg, ext24_decode},
1456 1.1 christos [0xd4] = {"st", four, reg, ext24_decode},
1457 1.1 christos [0xd5] = {"st", four, reg, ext24_decode},
1458 1.1 christos [0xd6] = {"st", four, reg, ext24_decode},
1459 1.1 christos [0xd7] = {"st", four, reg, ext24_decode},
1460 1.1 christos [0xd8] = {"st", four, reg_xy, ext24_decode},
1461 1.1 christos [0xd9] = {"st", four, reg_xy, ext24_decode},
1462 1.1 christos [0xda] = {"ld", three, reg_xy, ld_18bit_decode},
1463 1.1 christos [0xdb] = {"ld", three, reg_xy, ld_18bit_decode},
1464 1.1 christos [0xdc] = {"neg.b", opr_n_bytes_p1, NULL, opr_decode},
1465 1.1 christos [0xdd] = {"neg.w", opr_n_bytes_p1, NULL, opr_decode},
1466 1.1 christos [0xde] = {"orcc", two, imm1, 0},
1467 1.1 christos [0xdf] = {"neg.l", opr_n_bytes_p1, NULL, opr_decode},
1468 1.1 christos [0xe0] = {"cmp", three, reg, imm1234_0base},
1469 1.1 christos [0xe1] = {"cmp", three, reg, imm1234_0base},
1470 1.1 christos [0xe2] = {"cmp", three, reg, imm1234_0base},
1471 1.1 christos [0xe3] = {"cmp", three, reg, imm1234_0base},
1472 1.1 christos [0xe4] = {"cmp", two, reg, imm1234_0base},
1473 1.1 christos [0xe5] = {"cmp", two, reg, imm1234_0base},
1474 1.1 christos [0xe6] = {"cmp", five, reg, imm1234_0base},
1475 1.1 christos [0xe7] = {"cmp", five, reg, imm1234_0base},
1476 1.1 christos [0xe8] = {"cmp", four, reg_xy, imm1234_0base},
1477 1.1 christos [0xe9] = {"cmp", four, reg_xy, imm1234_0base},
1478 1.1 christos [0xea] = {"ld", three, reg_xy, ld_18bit_decode},
1479 1.1 christos [0xeb] = {"ld", three, reg_xy, ld_18bit_decode},
1480 1.1 christos [0xec] = {"bclr", bm_n_bytes, bm_decode, 0},
1481 1.1 christos [0xed] = {"bset", bm_n_bytes, bm_decode, 0},
1482 1.1 christos [0xee] = {"btgl", bm_n_bytes, bm_decode, 0},
1483 1.1 christos [0xef] = {"!!invalid!!", NULL, NULL, NULL}, /* SPARE */
1484 1.1 christos [0xf0] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1485 1.1 christos [0xf1] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1486 1.1 christos [0xf2] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1487 1.1 christos [0xf3] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1488 1.1 christos [0xf4] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1489 1.1 christos [0xf5] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1490 1.1 christos [0xf6] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1491 1.1 christos [0xf7] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1492 1.1 christos [0xf8] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode},
1493 1.1 christos [0xf9] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode},
1494 1.1 christos [0xfa] = {"ld", three, reg_xy, ld_18bit_decode},
1495 1.1 christos [0xfb] = {"ld", three, reg_xy, ld_18bit_decode},
1496 1.1 christos [0xfc] = {"cmp", single, cmp_xy, 0},
1497 1.1 christos [0xfd] = {"sub", single, sub_d6_x_y, 0},
1498 1.1 christos [0xfe] = {"sub", single, sub_d6_y_x, 0},
1499 1.1 christos [0xff] = {"swi", single, 0, 0}
1500 1.1 christos };
1501 1.1 christos
1502 1.1 christos
1503 1.1 christos static const char *oprregs1[] =
1504 1.1 christos {
1505 1.1 christos "d3", "d2", "d1", "d0", "ccl", "cch"
1506 1.1 christos };
1507 1.1 christos
1508 1.1 christos static const char *oprregs2[] =
1509 1.1 christos {
1510 1.1 christos "y", "x", "d7", "d6", "d5", "d4"
1511 1.1 christos };
1512 1.1 christos
1513 1.1 christos
1514 1.1 christos
1515 1.1 christos
1517 1.1 christos enum MUL_MODE
1518 1.1 christos {
1519 1.1 christos MUL_REG_REG,
1520 1.1 christos MUL_REG_OPR,
1521 1.1 christos MUL_REG_IMM,
1522 1.1 christos MUL_OPR_OPR
1523 1.1 christos };
1524 1.1 christos
1525 1.1 christos struct mb
1526 1.1 christos {
1527 1.1 christos uint8_t mask;
1528 1.1 christos uint8_t value;
1529 1.1 christos enum MUL_MODE mode;
1530 1.1 christos };
1531 1.1 christos
1532 1.1 christos static const struct mb mul_table[] = {
1533 1.1 christos {0x40, 0x00, MUL_REG_REG},
1534 1.1 christos
1535 1.1 christos {0x47, 0x40, MUL_REG_OPR},
1536 1.1 christos {0x47, 0x41, MUL_REG_OPR},
1537 1.1 christos {0x47, 0x43, MUL_REG_OPR},
1538 1.1 christos
1539 1.1 christos {0x47, 0x44, MUL_REG_IMM},
1540 1.1 christos {0x47, 0x45, MUL_REG_IMM},
1541 1.1 christos {0x47, 0x47, MUL_REG_IMM},
1542 1.1 christos
1543 1.1 christos {0x43, 0x42, MUL_OPR_OPR},
1544 1.1 christos };
1545 1.1 christos
1546 1.1 christos static void
1547 1.1 christos mul_decode (bfd_vma memaddr, struct disassemble_info* info)
1548 1.1 christos {
1549 1.1 christos uint8_t mb;
1550 1.1 christos int status = read_memory (memaddr, &mb, 1, info);
1551 1.1 christos if (status < 0)
1552 1.1 christos return;
1553 1.1 christos
1554 1.1 christos
1555 1.1 christos uint8_t byte;
1556 1.1 christos status = read_memory (memaddr - 1, &byte, 1, info);
1557 1.1 christos if (status < 0)
1558 1.1 christos return;
1559 1.1 christos
1560 1.1 christos (*info->fprintf_func) (info->stream, "%c", (mb & 0x80) ? 's' : 'u');
1561 1.1 christos
1562 1.1 christos enum MUL_MODE mode = -1;
1563 1.1 christos size_t i;
1564 1.1 christos for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i)
1565 1.1 christos {
1566 1.1 christos const struct mb *mm = mul_table + i;
1567 1.1 christos if ((mb & mm->mask) == mm->value)
1568 1.1 christos {
1569 1.1 christos mode = mm->mode;
1570 1.1 christos break;
1571 1.1 christos }
1572 1.1 christos }
1573 1.1 christos
1574 1.1 christos switch (mode)
1575 1.1 christos {
1576 1.1 christos case MUL_REG_REG:
1577 1.1 christos break;
1578 1.1 christos case MUL_OPR_OPR:
1579 1.1 christos {
1580 1.1 christos int size1 = (mb & 0x30) >> 4;
1581 1.1 christos int size2 = (mb & 0x0c) >> 2;
1582 1.1 christos (*info->fprintf_func) (info->stream, ".%c%c",
1583 1.1 christos shift_size_table [size1],
1584 1.1 christos shift_size_table [size2]);
1585 1.1 christos }
1586 1.1 christos break;
1587 1.1 christos default:
1588 1.1 christos {
1589 1.1 christos int size = (mb & 0x3);
1590 1.1 christos (*info->fprintf_func) (info->stream, ".%c", shift_size_table [size]);
1591 1.1 christos }
1592 1.1 christos break;
1593 1.1 christos }
1594 1.1 christos
1595 1.1 christos operand_separator (info);
1596 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
1597 1.1 christos
1598 1.1 christos switch (mode)
1599 1.1 christos {
1600 1.1 christos case MUL_REG_REG:
1601 1.1 christos case MUL_REG_IMM:
1602 1.1 christos case MUL_REG_OPR:
1603 1.1 christos operand_separator (info);
1604 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[(mb & 0x38) >> 3].name);
1605 1.1 christos break;
1606 1.1 christos default:
1607 1.1 christos break;
1608 1.1 christos }
1609 1.1 christos
1610 1.1 christos switch (mode)
1611 1.1 christos {
1612 1.1 christos case MUL_REG_IMM:
1613 1.1 christos operand_separator (info);
1614 1.1 christos int size = (mb & 0x3);
1615 1.1 christos uint32_t imm = decode_signed_value (memaddr + 1, info, size + 1);
1616 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
1617 1.1 christos break;
1618 1.1 christos case MUL_REG_REG:
1619 1.1 christos operand_separator (info);
1620 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[mb & 0x07].name);
1621 1.1 christos break;
1622 1.1 christos case MUL_REG_OPR:
1623 1.1 christos opr_decode (memaddr + 1, info);
1624 1.1 christos break;
1625 1.1 christos case MUL_OPR_OPR:
1626 1.1 christos {
1627 1.1 christos int first = opr_n_bytes (memaddr + 1, info);
1628 1.1 christos opr_decode (memaddr + 1, info);
1629 1.1 christos opr_decode (memaddr + first + 1, info);
1630 1.1 christos break;
1631 1.1 christos }
1632 1.1 christos }
1633 1.1 christos }
1634 1.1 christos
1635 1.1 christos
1636 1.1 christos static int
1637 1.1 christos mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1638 1.1 christos {
1639 1.1 christos int nx = 2;
1640 1.1 christos uint8_t mb;
1641 1.1 christos int status = read_memory (memaddr, &mb, 1, info);
1642 1.1 christos if (status < 0)
1643 1.1 christos return 0;
1644 1.1 christos
1645 1.1 christos enum MUL_MODE mode = -1;
1646 1.1 christos size_t i;
1647 1.1 christos for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i)
1648 1.1 christos {
1649 1.1 christos const struct mb *mm = mul_table + i;
1650 1.1 christos if ((mb & mm->mask) == mm->value)
1651 1.1 christos {
1652 1.1 christos mode = mm->mode;
1653 1.1 christos break;
1654 1.1 christos }
1655 1.1 christos }
1656 1.1 christos
1657 1.1 christos int size = (mb & 0x3) + 1;
1658 1.1 christos
1659 1.1 christos switch (mode)
1660 1.1 christos {
1661 1.1 christos case MUL_REG_IMM:
1662 1.1 christos nx += size;
1663 1.1 christos break;
1664 1.1 christos case MUL_REG_REG:
1665 1.1 christos break;
1666 1.1 christos case MUL_REG_OPR:
1667 1.1 christos nx += opr_n_bytes (memaddr + 1, info);
1668 1.1 christos break;
1669 1.1 christos case MUL_OPR_OPR:
1670 1.1 christos {
1671 1.1 christos int first = opr_n_bytes (memaddr + nx - 1, info);
1672 1.1 christos nx += first;
1673 1.1 christos int second = opr_n_bytes (memaddr + nx - 1, info);
1674 1.1 christos nx += second;
1675 1.1 christos }
1676 1.1 christos break;
1677 1.1 christos }
1678 1.1 christos
1679 1.1 christos return nx;
1680 1.1 christos }
1681 1.1 christos
1682 1.1 christos
1683 1.1 christos enum BM_MODE {
1685 1.1 christos BM_REG_IMM,
1686 1.1 christos BM_RESERVED0,
1687 1.1 christos BM_OPR_B,
1688 1.1 christos BM_OPR_W,
1689 1.1 christos BM_OPR_L,
1690 1.1 christos BM_OPR_REG,
1691 1.1 christos BM_RESERVED1
1692 1.1 christos };
1693 1.1 christos
1694 1.1 christos struct bm
1695 1.1 christos {
1696 1.1 christos uint8_t mask;
1697 1.1 christos uint8_t value;
1698 1.1 christos enum BM_MODE mode;
1699 1.1 christos };
1700 1.1 christos
1701 1.1 christos static const struct bm bm_table[] = {
1702 1.1 christos { 0xC6, 0x04, BM_REG_IMM},
1703 1.1 christos { 0x84, 0x00, BM_REG_IMM},
1704 1.1 christos { 0x06, 0x06, BM_REG_IMM},
1705 1.1 christos { 0xC6, 0x44, BM_RESERVED0},
1706 1.1 christos // 00
1707 1.1 christos { 0x8F, 0x80, BM_OPR_B},
1708 1.1 christos { 0x8E, 0x82, BM_OPR_W},
1709 1.1 christos { 0x8C, 0x88, BM_OPR_L},
1710 1.1 christos
1711 1.1 christos { 0x83, 0x81, BM_OPR_REG},
1712 1.1 christos { 0x87, 0x84, BM_RESERVED1},
1713 1.1 christos };
1714 1.1 christos
1715 1.1 christos static void
1716 1.1 christos bm_decode (bfd_vma memaddr, struct disassemble_info* info)
1717 1.1 christos {
1718 1.1 christos uint8_t bm;
1719 1.1 christos int status = read_memory (memaddr, &bm, 1, info);
1720 1.1 christos if (status < 0)
1721 1.1 christos return;
1722 1.1 christos
1723 1.1 christos size_t i;
1724 1.1 christos enum BM_MODE mode = -1;
1725 1.1 christos for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1726 1.1 christos {
1727 1.1 christos const struct bm *bme = bm_table + i;
1728 1.1 christos if ((bm & bme->mask) == bme->value)
1729 1.1 christos {
1730 1.1 christos mode = bme->mode;
1731 1.1 christos break;
1732 1.1 christos }
1733 1.1 christos }
1734 1.1 christos
1735 1.1 christos switch (mode)
1736 1.1 christos {
1737 1.1 christos case BM_REG_IMM:
1738 1.1 christos operand_separator (info);
1739 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
1740 1.1 christos break;
1741 1.1 christos case BM_OPR_B:
1742 1.1 christos (*info->fprintf_func) (info->stream, ".%c", 'b');
1743 1.1 christos opr_decode (memaddr + 1, info);
1744 1.1 christos break;
1745 1.1 christos case BM_OPR_W:
1746 1.1 christos (*info->fprintf_func) (info->stream, ".%c", 'w');
1747 1.1 christos opr_decode (memaddr + 1, info);
1748 1.1 christos break;
1749 1.1 christos case BM_OPR_L:
1750 1.1 christos (*info->fprintf_func) (info->stream, ".%c", 'l');
1751 1.1 christos opr_decode (memaddr + 1, info);
1752 1.1 christos break;
1753 1.1 christos case BM_OPR_REG:
1754 1.1 christos {
1755 1.1 christos uint8_t xb;
1756 1.1 christos read_memory (memaddr + 1, &xb, 1, info);
1757 1.1 christos /* Don't emit a size suffix for register operands */
1758 1.1 christos if ((xb & 0xF8) != 0xB8)
1759 1.1 christos (*info->fprintf_func) (info->stream, ".%c", shift_size_table[(bm & 0x0c) >> 2]);
1760 1.1 christos opr_decode (memaddr + 1, info);
1761 1.1 christos }
1762 1.1 christos break;
1763 1.1 christos case BM_RESERVED0:
1764 1.1 christos case BM_RESERVED1:
1765 1.1 christos assert (0);
1766 1.1 christos break;
1767 1.1 christos }
1768 1.1 christos
1769 1.1 christos uint8_t imm = 0;
1770 1.1 christos operand_separator (info);
1771 1.1 christos switch (mode)
1772 1.1 christos {
1773 1.1 christos case BM_REG_IMM:
1774 1.1 christos {
1775 1.1 christos imm = (bm & 0xF8) >> 3;
1776 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
1777 1.1 christos }
1778 1.1 christos break;
1779 1.1 christos case BM_OPR_L:
1780 1.1 christos imm |= (bm & 0x03) << 3;
1781 1.1 christos /* fallthrough */
1782 1.1 christos case BM_OPR_W:
1783 1.1 christos imm |= (bm & 0x01) << 3;
1784 1.1 christos /* fallthrough */
1785 1.1 christos case BM_OPR_B:
1786 1.1 christos imm |= (bm & 0x70) >> 4;
1787 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
1788 1.1 christos break;
1789 1.1 christos case BM_OPR_REG:
1790 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1791 1.1 christos break;
1792 1.1 christos case BM_RESERVED0:
1793 1.1 christos case BM_RESERVED1:
1794 1.1 christos assert (0);
1795 1.1 christos break;
1796 1.1 christos }
1797 1.1 christos }
1798 1.1 christos
1799 1.1 christos
1800 1.1 christos static void
1801 1.1 christos bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info)
1802 1.1 christos {
1803 1.1 christos uint8_t bm;
1804 1.1 christos int status = read_memory (memaddr, &bm, 1, info);
1805 1.1 christos if (status < 0)
1806 1.1 christos return;
1807 1.1 christos
1808 1.1 christos size_t i;
1809 1.1 christos enum BM_MODE mode = -1;
1810 1.1 christos for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1811 1.1 christos {
1812 1.1 christos const struct bm *bme = bm_table + i;
1813 1.1 christos if ((bm & bme->mask) == bme->value)
1814 1.1 christos {
1815 1.1 christos mode = bme->mode;
1816 1.1 christos break;
1817 1.1 christos }
1818 1.1 christos }
1819 1.1 christos
1820 1.1 christos switch (mode)
1821 1.1 christos {
1822 1.1 christos case BM_REG_IMM:
1823 1.1 christos break;
1824 1.1 christos case BM_OPR_B:
1825 1.1 christos (*info->fprintf_func) (info->stream, ".%c", 'b');
1826 1.1 christos break;
1827 1.1 christos case BM_OPR_W:
1828 1.1 christos (*info->fprintf_func) (info->stream, ".%c", 'w');
1829 1.1 christos break;
1830 1.1 christos case BM_OPR_L:
1831 1.1 christos (*info->fprintf_func) (info->stream, ".%c", 'l');
1832 1.1 christos break;
1833 1.1 christos case BM_OPR_REG:
1834 1.1 christos {
1835 1.1 christos uint8_t xb;
1836 1.1 christos read_memory (memaddr + 1, &xb, 1, info);
1837 1.1 christos /* Don't emit a size suffix for register operands */
1838 1.1 christos if ((xb & 0xF8) != 0xB8)
1839 1.1 christos (*info->fprintf_func) (info->stream, ".%c",
1840 1.1 christos shift_size_table[(bm & 0x0C) >> 2]);
1841 1.1 christos }
1842 1.1 christos break;
1843 1.1 christos case BM_RESERVED0:
1844 1.1 christos case BM_RESERVED1:
1845 1.1 christos assert (0);
1846 1.1 christos break;
1847 1.1 christos }
1848 1.1 christos
1849 1.1 christos int n = 1;
1850 1.1 christos switch (mode)
1851 1.1 christos {
1852 1.1 christos case BM_REG_IMM:
1853 1.1 christos operand_separator (info);
1854 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
1855 1.1 christos break;
1856 1.1 christos case BM_OPR_B:
1857 1.1 christos case BM_OPR_W:
1858 1.1 christos case BM_OPR_L:
1859 1.1 christos opr_decode (memaddr + 1, info);
1860 1.1 christos n = 1 + opr_n_bytes (memaddr + 1, info);
1861 1.1 christos break;
1862 1.1 christos case BM_OPR_REG:
1863 1.1 christos opr_decode (memaddr + 1, info);
1864 1.1 christos break;
1865 1.1 christos case BM_RESERVED0:
1866 1.1 christos case BM_RESERVED1:
1867 1.1 christos assert (0);
1868 1.1 christos break;
1869 1.1 christos }
1870 1.1 christos
1871 1.1 christos
1872 1.1 christos int imm = 0;
1873 1.1 christos operand_separator (info);
1874 1.1 christos switch (mode)
1875 1.1 christos {
1876 1.1 christos case BM_OPR_L:
1877 1.1 christos imm |= (bm & 0x02) << 3;
1878 1.1 christos /* fall through */
1879 1.1 christos case BM_OPR_W:
1880 1.1 christos imm |= (bm & 0x01) << 3;
1881 1.1 christos /* fall through */
1882 1.1 christos case BM_OPR_B:
1883 1.1 christos imm |= (bm & 0x70) >> 4;
1884 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
1885 1.1 christos break;
1886 1.1 christos case BM_REG_IMM:
1887 1.1 christos imm = (bm & 0xF8) >> 3;
1888 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
1889 1.1 christos break;
1890 1.1 christos case BM_RESERVED0:
1891 1.1 christos case BM_RESERVED1:
1892 1.1 christos assert (0);
1893 1.1 christos break;
1894 1.1 christos case BM_OPR_REG:
1895 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1896 1.1 christos n += opr_n_bytes (memaddr + 1, info);
1897 1.1 christos break;
1898 1.1 christos }
1899 1.1 christos
1900 1.1 christos rel_15_7 (memaddr + n, info, n + 1);
1901 1.1 christos }
1902 1.1 christos
1903 1.1 christos static int
1904 1.1 christos bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1905 1.1 christos {
1906 1.1 christos uint8_t bm;
1907 1.1 christos int status = read_memory (memaddr, &bm, 1, info);
1908 1.1 christos if (status < 0)
1909 1.1 christos return status;
1910 1.1 christos
1911 1.1 christos size_t i;
1912 1.1 christos enum BM_MODE mode = -1;
1913 1.1 christos for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1914 1.1 christos {
1915 1.1 christos const struct bm *bme = bm_table + i;
1916 1.1 christos if ((bm & bme->mask) == bme->value)
1917 1.1 christos {
1918 1.1 christos mode = bme->mode;
1919 1.1 christos break;
1920 1.1 christos }
1921 1.1 christos }
1922 1.1 christos
1923 1.1 christos int n = 2;
1924 1.1 christos switch (mode)
1925 1.1 christos {
1926 1.1 christos case BM_REG_IMM:
1927 1.1 christos break;
1928 1.1 christos
1929 1.1 christos case BM_OPR_B:
1930 1.1 christos case BM_OPR_W:
1931 1.1 christos case BM_OPR_L:
1932 1.1 christos n += opr_n_bytes (memaddr + 1, info);
1933 1.1 christos break;
1934 1.1 christos case BM_OPR_REG:
1935 1.1 christos n += opr_n_bytes (memaddr + 1, info);
1936 1.1 christos break;
1937 1.1 christos default:
1938 1.1 christos break;
1939 1.1 christos }
1940 1.1 christos
1941 1.1 christos return n;
1942 1.1 christos }
1943 1.1 christos
1944 1.1 christos static int
1945 1.1 christos bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1946 1.1 christos {
1947 1.1 christos int n = 1 + bm_n_bytes (memaddr, info);
1948 1.1 christos
1949 1.1 christos bfd_byte rb;
1950 1.1 christos int status = read_memory (memaddr + n - 2, &rb, 1, info);
1951 1.1 christos if (status != 0)
1952 1.1 christos return status;
1953 1.1 christos
1954 1.1 christos if (rb & 0x80)
1955 1.1 christos n++;
1956 1.1 christos
1957 1.1 christos return n;
1958 1.1 christos }
1959 1.1 christos
1960 1.1 christos
1961 1.1 christos
1962 1.1 christos
1964 1.1 christos
1965 1.1 christos /* shift direction */
1966 1.1 christos enum SB_DIR
1967 1.1 christos {
1968 1.1 christos SB_LEFT,
1969 1.1 christos SB_RIGHT
1970 1.1 christos };
1971 1.1 christos
1972 1.1 christos enum SB_TYPE
1973 1.1 christos {
1974 1.1 christos SB_ARITHMETIC,
1975 1.1 christos SB_LOGICAL
1976 1.1 christos };
1977 1.1 christos
1978 1.1 christos
1979 1.1 christos enum SB_MODE
1980 1.1 christos {
1981 1.1 christos SB_REG_REG_N_EFF,
1982 1.1 christos SB_REG_REG_N,
1983 1.1 christos SB_REG_OPR_EFF,
1984 1.1 christos SB_ROT,
1985 1.1 christos SB_REG_OPR_OPR,
1986 1.1 christos SB_OPR_N
1987 1.1 christos };
1988 1.1 christos
1989 1.1 christos struct sb
1990 1.1 christos {
1991 1.1 christos uint8_t mask;
1992 1.1 christos uint8_t value;
1993 1.1 christos enum SB_MODE mode;
1994 1.1 christos };
1995 1.1 christos
1996 1.1 christos static const struct sb sb_table[] = {
1997 1.1 christos {0x30, 0x00, SB_REG_REG_N_EFF},
1998 1.1 christos {0x30, 0x10, SB_REG_REG_N},
1999 1.1 christos {0x34, 0x20, SB_REG_OPR_EFF},
2000 1.1 christos {0x34, 0x24, SB_ROT},
2001 1.1 christos {0x34, 0x30, SB_REG_OPR_OPR},
2002 1.1 christos {0x34, 0x34, SB_OPR_N},
2003 1.1 christos };
2004 1.1 christos
2005 1.1 christos static int
2006 1.1 christos shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2007 1.1 christos {
2008 1.1 christos bfd_byte sb;
2009 1.1 christos int status = read_memory (memaddr++, &sb, 1, info);
2010 1.1 christos if (status != 0)
2011 1.1 christos return status;
2012 1.1 christos
2013 1.1 christos size_t i;
2014 1.1 christos enum SB_MODE mode = -1;
2015 1.1 christos for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2016 1.1 christos {
2017 1.1 christos const struct sb *sbe = sb_table + i;
2018 1.1 christos if ((sb & sbe->mask) == sbe->value)
2019 1.1 christos mode = sbe->mode;
2020 1.1 christos }
2021 1.1 christos
2022 1.1 christos switch (mode)
2023 1.1 christos {
2024 1.1 christos case SB_REG_REG_N_EFF:
2025 1.1 christos return 2;
2026 1.1 christos break;
2027 1.1 christos case SB_REG_OPR_EFF:
2028 1.1 christos case SB_ROT:
2029 1.1 christos return 2 + opr_n_bytes (memaddr, info);
2030 1.1 christos break;
2031 1.1 christos case SB_REG_OPR_OPR:
2032 1.1 christos {
2033 1.1 christos int opr1 = opr_n_bytes (memaddr, info);
2034 1.1 christos int opr2 = 0;
2035 1.1 christos if ((sb & 0x30) != 0x20)
2036 1.1 christos opr2 = opr_n_bytes (memaddr + opr1, info);
2037 1.1 christos return 2 + opr1 + opr2;
2038 1.1 christos }
2039 1.1 christos break;
2040 1.1 christos default:
2041 1.1 christos return 3;
2042 1.1 christos }
2043 1.1 christos
2044 1.1 christos /* not reached */
2045 1.1 christos return -1;
2046 1.1 christos }
2047 1.1 christos
2048 1.1 christos
2050 1.1 christos static int
2051 1.1 christos mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2052 1.1 christos {
2053 1.1 christos bfd_byte byte;
2054 1.1 christos int status = read_memory (memaddr - 1, &byte, 1, info);
2055 1.1 christos if (status < 0)
2056 1.1 christos return status;
2057 1.1 christos
2058 1.1 christos int size = byte - 0x0c + 1;
2059 1.1 christos
2060 1.1 christos return size + opr_n_bytes (memaddr + size, info) + 1;
2061 1.1 christos }
2062 1.1 christos
2063 1.1 christos static void
2064 1.1 christos mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info)
2065 1.1 christos {
2066 1.1 christos bfd_byte byte;
2067 1.1 christos int status = read_memory (memaddr - 1, &byte, 1, info);
2068 1.1 christos if (status < 0)
2069 1.1 christos return ;
2070 1.1 christos
2071 1.1 christos int size = byte - 0x0c + 1;
2072 1.1 christos uint32_t imm = decode_signed_value (memaddr, info, size);
2073 1.1 christos
2074 1.1 christos operand_separator (info);
2075 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
2076 1.1 christos opr_decode (memaddr + size, info);
2077 1.1 christos }
2078 1.1 christos
2079 1.1 christos
2080 1.1 christos
2082 1.1 christos static void
2083 1.1 christos ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info)
2084 1.1 christos {
2085 1.1 christos size_t size = 3;
2086 1.1 christos bfd_byte buffer[3];
2087 1.1 christos int status = read_memory (memaddr, buffer + 1, 2, info);
2088 1.1 christos if (status < 0)
2089 1.1 christos return ;
2090 1.1 christos
2091 1.1 christos
2092 1.1 christos status = read_memory (memaddr - 1, buffer, 1, info);
2093 1.1 christos if (status < 0)
2094 1.1 christos return ;
2095 1.1 christos
2096 1.1 christos buffer[0] = (buffer[0] & 0x30) >> 4;
2097 1.1 christos
2098 1.1 christos size_t i;
2099 1.1 christos uint32_t imm = 0;
2100 1.1 christos for (i = 0; i < size; ++i)
2101 1.1 christos {
2102 1.1 christos imm |= buffer[i] << (8 * (size - i - 1));
2103 1.1 christos }
2104 1.1 christos
2105 1.1 christos operand_separator (info);
2106 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
2107 1.1 christos }
2108 1.1 christos
2109 1.1 christos
2110 1.1 christos
2112 1.1 christos /* Loop Primitives */
2113 1.1 christos
2114 1.1 christos enum LP_MODE {
2115 1.1 christos LP_REG,
2116 1.1 christos LP_XY,
2117 1.1 christos LP_OPR
2118 1.1 christos };
2119 1.1 christos
2120 1.1 christos struct lp
2121 1.1 christos {
2122 1.1 christos uint8_t mask;
2123 1.1 christos uint8_t value;
2124 1.1 christos enum LP_MODE mode;
2125 1.1 christos };
2126 1.1 christos
2127 1.1 christos static const struct lp lp_mode[] = {
2128 1.1 christos {0x08, 0x00, LP_REG},
2129 1.1 christos {0x0C, 0x08, LP_XY},
2130 1.1 christos {0x0C, 0x0C, LP_OPR},
2131 1.1 christos };
2132 1.1 christos
2133 1.1 christos
2134 1.1 christos static const char *lb_condition[] =
2135 1.1 christos {
2136 1.1 christos "ne", "eq", "pl", "mi", "gt", "le",
2137 1.1 christos "??", "??"
2138 1.1 christos };
2139 1.1 christos
2140 1.1 christos static int
2141 1.1 christos loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2142 1.1 christos {
2143 1.1 christos int mx = 0;
2144 1.1 christos uint8_t lb;
2145 1.1 christos read_memory (memaddr + mx++, &lb, 1, info);
2146 1.1 christos
2147 1.1 christos enum LP_MODE mode = -1;
2148 1.1 christos size_t i;
2149 1.1 christos for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
2150 1.1 christos {
2151 1.1 christos const struct lp *pb = lp_mode + i;
2152 1.1 christos if ((lb & pb->mask) == pb->value)
2153 1.1 christos {
2154 1.1 christos mode = pb->mode;
2155 1.1 christos break;
2156 1.1 christos }
2157 1.1 christos }
2158 1.1 christos
2159 1.1 christos if (mode == LP_OPR)
2160 1.1 christos {
2161 1.1 christos mx += opr_n_bytes (memaddr + mx, info) ;
2162 1.1 christos }
2163 1.1 christos
2164 1.1 christos uint8_t rb;
2165 1.1 christos read_memory (memaddr + mx++, &rb, 1, info);
2166 1.1 christos if (rb & 0x80)
2167 1.1 christos mx++;
2168 1.1 christos
2169 1.1 christos return mx + 1;
2170 1.1 christos }
2171 1.1 christos
2172 1.1 christos
2173 1.1 christos
2174 1.1 christos
2176 1.1 christos static int
2177 1.1 christos print_insn_exg_sex (bfd_vma memaddr, struct disassemble_info* info)
2178 1.1 christos {
2179 1.1 christos uint8_t eb;
2180 1.1 christos int status = read_memory (memaddr, &eb, 1, info);
2181 1.1 christos if (status < 0)
2182 1.1 christos return -1;
2183 1.1 christos
2184 1.1 christos const struct reg *first = ®isters[(eb & 0xf0) >> 4];
2185 1.1 christos const struct reg *second = ®isters[(eb & 0xf)];
2186 1.1 christos
2187 1.1 christos if (first->bytes < second->bytes)
2188 1.1 christos (*info->fprintf_func) (info->stream, "sex");
2189 1.1 christos else
2190 1.1 christos (*info->fprintf_func) (info->stream, "exg");
2191 1.1 christos
2192 1.1 christos operand_separator (info);
2193 1.1 christos (*info->fprintf_func) (info->stream, "%s", first->name);
2194 1.1 christos operand_separator (info);
2195 1.1 christos (*info->fprintf_func) (info->stream, "%s", second->name);
2196 1.1 christos return 0;
2197 1.1 christos }
2198 1.1 christos
2199 1.1 christos
2200 1.1 christos
2201 1.1 christos static int
2202 1.1 christos print_insn_loop_primitive (bfd_vma memaddr, struct disassemble_info* info)
2203 1.1 christos {
2204 1.1 christos int offs = 1;
2205 1.1 christos uint8_t lb;
2206 1.1 christos int status = read_memory (memaddr, &lb, 1, info);
2207 1.1 christos
2208 1.1 christos char mnemonic[7];
2209 1.1 christos int x = 0;
2210 1.1 christos mnemonic[x++] = (lb & 0x80) ? 'd' : 't';
2211 1.1 christos mnemonic[x++] = 'b';
2212 1.1 christos stpcpy (mnemonic + x, lb_condition [(lb & 0x70) >> 4]);
2213 1.1 christos x += 2;
2214 1.1 christos
2215 1.1 christos const char *reg = NULL;
2216 1.1 christos enum LP_MODE mode = -1;
2217 1.1 christos size_t i;
2218 1.1 christos for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
2219 1.1 christos {
2220 1.1 christos const struct lp *pb = lp_mode + i;
2221 1.1 christos if ((lb & pb->mask) == pb->value)
2222 1.1 christos {
2223 1.1 christos mode = pb->mode;
2224 1.1 christos break;
2225 1.1 christos }
2226 1.1 christos }
2227 1.1 christos
2228 1.1 christos switch (mode)
2229 1.1 christos {
2230 1.1 christos case LP_REG:
2231 1.1 christos reg = registers [lb & 0x07].name;
2232 1.1 christos break;
2233 1.1 christos case LP_XY:
2234 1.1 christos reg = (lb & 0x1) ? "y" : "x";
2235 1.1 christos break;
2236 1.1 christos case LP_OPR:
2237 1.1 christos mnemonic[x++] = '.';
2238 1.1 christos mnemonic[x++] = shift_size_table [lb & 0x03];
2239 1.1 christos offs += opr_n_bytes (memaddr + 1, info);
2240 1.1 christos break;
2241 1.1 christos }
2242 1.1 christos
2243 1.1 christos mnemonic[x++] = '\0';
2244 1.1 christos
2245 1.1 christos (*info->fprintf_func) (info->stream, "%s", mnemonic);
2246 1.1 christos
2247 1.1 christos if (mode == LP_OPR)
2248 1.1 christos opr_decode (memaddr + 1, info);
2249 1.1 christos else
2250 1.1 christos {
2251 1.1 christos operand_separator (info);
2252 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg);
2253 1.1 christos }
2254 1.1 christos
2255 1.1 christos rel_15_7 (memaddr + offs, info, offs + 1);
2256 1.1 christos
2257 1.1 christos return status;
2258 1.1 christos }
2259 1.1 christos
2260 1.1 christos
2261 1.1 christos static int
2262 1.1 christos print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte)
2263 1.1 christos {
2264 1.1 christos size_t i;
2265 1.1 christos uint8_t sb;
2266 1.1 christos int status = read_memory (memaddr, &sb, 1, info);
2267 1.1 christos if (status < 0)
2268 1.1 christos return status;
2269 1.1 christos
2270 1.1 christos enum SB_DIR dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT;
2271 1.1 christos enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL;
2272 1.1 christos enum SB_MODE mode = -1;
2273 1.1 christos for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2274 1.1 christos {
2275 1.1 christos const struct sb *sbe = sb_table + i;
2276 1.1 christos if ((sb & sbe->mask) == sbe->value)
2277 1.1 christos mode = sbe->mode;
2278 1.1 christos }
2279 1.1 christos
2280 1.1 christos char mnemonic[6];
2281 1.1 christos int x = 0;
2282 1.1 christos if (mode == SB_ROT)
2283 1.1 christos {
2284 1.1 christos mnemonic[x++] = 'r';
2285 1.1 christos mnemonic[x++] = 'o';
2286 1.1 christos }
2287 1.1 christos else
2288 1.1 christos {
2289 1.1 christos mnemonic[x++] = (type == SB_LOGICAL) ? 'l' : 'a';
2290 1.1 christos mnemonic[x++] = 's';
2291 1.1 christos }
2292 1.1 christos
2293 1.1 christos mnemonic[x++] = (dir == SB_LEFT) ? 'l' : 'r';
2294 1.1 christos
2295 1.1 christos switch (mode)
2296 1.1 christos {
2297 1.1 christos case SB_REG_OPR_EFF:
2298 1.1 christos case SB_ROT:
2299 1.1 christos case SB_REG_OPR_OPR:
2300 1.1 christos mnemonic[x++] = '.';
2301 1.1 christos mnemonic[x++] = shift_size_table[sb & 0x03];
2302 1.1 christos break;
2303 1.1 christos case SB_OPR_N:
2304 1.1 christos {
2305 1.1 christos uint8_t xb;
2306 1.1 christos read_memory (memaddr + 1, &xb, 1, info);
2307 1.1 christos /* The size suffix is not printed if the OPR operand refers
2308 1.1 christos directly to a register, because the size is implied by the
2309 1.1 christos size of that register. */
2310 1.1 christos if ((xb & 0xF8) != 0xB8)
2311 1.1 christos {
2312 1.1 christos mnemonic[x++] = '.';
2313 1.1 christos mnemonic[x++] = shift_size_table[sb & 0x03];
2314 1.1 christos }
2315 1.1 christos }
2316 1.1 christos break;
2317 1.1 christos default:
2318 1.1 christos break;
2319 1.1 christos };
2320 1.1 christos
2321 1.1 christos mnemonic[x++] = '\0';
2322 1.1 christos
2323 1.1 christos (*info->fprintf_func) (info->stream, "%s", mnemonic);
2324 1.1 christos
2325 1.1 christos /* Destination register */
2326 1.1 christos switch (mode)
2327 1.1 christos {
2328 1.1 christos case SB_REG_REG_N_EFF:
2329 1.1 christos case SB_REG_REG_N:
2330 1.1 christos case SB_REG_OPR_EFF:
2331 1.1 christos case SB_REG_OPR_OPR:
2332 1.1 christos operand_separator (info);
2333 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
2334 1.1 christos break;
2335 1.1 christos
2336 1.1 christos case SB_ROT:
2337 1.1 christos opr_decode (memaddr + 1, info);
2338 1.1 christos break;
2339 1.1 christos
2340 1.1 christos default:
2341 1.1 christos break;
2342 1.1 christos }
2343 1.1 christos
2344 1.1 christos /* Source register */
2345 1.1 christos switch (mode)
2346 1.1 christos {
2347 1.1 christos case SB_REG_REG_N_EFF:
2348 1.1 christos case SB_REG_REG_N:
2349 1.1 christos operand_separator (info);
2350 1.1 christos (*info->fprintf_func) (info->stream, "%s", registers[sb & 0x7].name);
2351 1.1 christos break;
2352 1.1 christos
2353 1.1 christos case SB_REG_OPR_OPR:
2354 1.1 christos opr_decode (memaddr + 1, info);
2355 1.1 christos break;
2356 1.1 christos
2357 1.1 christos default:
2358 1.1 christos break;
2359 1.1 christos }
2360 1.1 christos
2361 1.1 christos /* 3rd arg */
2362 1.1 christos switch (mode)
2363 1.1 christos {
2364 1.1 christos case SB_REG_OPR_EFF:
2365 1.1 christos case SB_OPR_N:
2366 1.1 christos opr_decode (memaddr + 1, info);
2367 1.1 christos break;
2368 1.1 christos
2369 1.1 christos case SB_REG_REG_N:
2370 1.1 christos if (sb & 0x08)
2371 1.1 christos {
2372 1.1 christos operand_separator (info);
2373 1.1 christos if (byte & 0x10)
2374 1.1 christos {
2375 1.1 christos uint8_t xb;
2376 1.1 christos read_memory (memaddr + 1, &xb, 1, info);
2377 1.1 christos int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
2378 1.1 christos (*info->fprintf_func) (info->stream, "#%d", shift);
2379 1.1 christos }
2380 1.1 christos else
2381 1.1 christos {
2382 1.1 christos (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__);
2383 1.1 christos }
2384 1.1 christos }
2385 1.1 christos else
2386 1.1 christos {
2387 1.1 christos opr_decode (memaddr + 1, info);
2388 1.1 christos }
2389 1.1 christos break;
2390 1.1 christos case SB_REG_OPR_OPR:
2391 1.1 christos {
2392 1.1 christos uint8_t xb;
2393 1.1 christos int n = opr_n_bytes (memaddr + 1, info);
2394 1.1 christos read_memory (memaddr + 1 + n, &xb, 1, info);
2395 1.1 christos
2396 1.1 christos if ((xb & 0xF0) == 0x70)
2397 1.1 christos {
2398 1.1 christos int imm = xb & 0x0F;
2399 1.1 christos imm <<= 1;
2400 1.1 christos imm |= (sb & 0x08) >> 3;
2401 1.1 christos operand_separator (info);
2402 1.1 christos (*info->fprintf_func) (info->stream, "#%d", imm);
2403 1.1 christos }
2404 1.1 christos else
2405 1.1 christos {
2406 1.1 christos opr_decode (memaddr + 1 + n, info);
2407 1.1 christos }
2408 1.1 christos }
2409 1.1 christos break;
2410 1.1 christos default:
2411 1.1 christos break;
2412 1.1 christos }
2413 1.1 christos
2414 1.1 christos switch (mode)
2415 1.1 christos {
2416 1.1 christos case SB_REG_REG_N_EFF:
2417 1.1 christos case SB_REG_OPR_EFF:
2418 1.1 christos case SB_OPR_N:
2419 1.1 christos operand_separator (info);
2420 1.1 christos (*info->fprintf_func) (info->stream, "#%d",
2421 1.1 christos (sb & 0x08) ? 2 : 1);
2422 1.1 christos break;
2423 1.1 christos
2424 1.1 christos default:
2425 1.1 christos break;
2426 1.1 christos }
2427 1.1 christos
2428 1.1 christos return 0;
2429 1.1 christos }
2430 1.1 christos
2431 1.1 christos int
2432 1.1 christos print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
2433 1.1 christos {
2434 1.1 christos bfd_byte byte;
2435 1.1 christos int status = read_memory (memaddr++, &byte, 1, info);
2436 1.1 christos if (status != 0)
2437 1.1 christos return status;
2438 1.1 christos
2439 1.1 christos const struct opcode *opc2 = NULL;
2440 1.1 christos const struct opcode *opc = page1 + byte;
2441 1.1 christos if (opc->mnemonic)
2442 1.1 christos {
2443 1.1 christos (*info->fprintf_func) (info->stream, "%s", opc->mnemonic);
2444 1.1 christos }
2445 1.1 christos else
2446 1.1 christos {
2447 1.1 christos /* The special cases ... */
2448 1.1 christos switch (byte)
2449 1.1 christos {
2450 1.1 christos case PAGE2_PREBYTE:
2451 1.1 christos {
2452 1.1 christos bfd_byte byte2;
2453 1.1 christos read_memory (memaddr++, &byte2, 1, info);
2454 1.1 christos opc2 = page2 + byte2;
2455 1.1 christos if (opc2->mnemonic)
2456 1.1 christos {
2457 1.1 christos (*info->fprintf_func) (info->stream, "%s", opc2->mnemonic);
2458 1.1 christos
2459 1.1 christos if (opc2->operands)
2460 1.1 christos {
2461 1.1 christos opc2->operands (memaddr, info);
2462 1.1 christos }
2463 1.1 christos
2464 1.1 christos if (opc2->operands2)
2465 1.1 christos {
2466 1.1 christos opc2->operands2 (memaddr, info);
2467 1.1 christos }
2468 1.1 christos }
2469 1.1 christos else if (byte2 >= 0x08 && byte2 <= 0x1F)
2470 1.1 christos {
2471 1.1 christos bfd_byte bb;
2472 1.1 christos read_memory (memaddr, &bb, 1, info);
2473 1.1 christos if (bb & 0x80)
2474 1.1 christos (*info->fprintf_func) (info->stream, "bfins");
2475 1.1 christos else
2476 1.1 christos (*info->fprintf_func) (info->stream, "bfext");
2477 1.1 christos
2478 1.1 christos enum BB_MODE mode = -1;
2479 1.1 christos size_t i;
2480 1.1 christos const struct opr_bb *bbs = 0;
2481 1.1 christos for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
2482 1.1 christos {
2483 1.1 christos bbs = bb_modes + i;
2484 1.1 christos if ((bb & bbs->mask) == bbs->value)
2485 1.1 christos {
2486 1.1 christos mode = bbs->mode;
2487 1.1 christos break;
2488 1.1 christos }
2489 1.1 christos }
2490 1.1 christos
2491 1.1 christos switch (mode)
2492 1.1 christos {
2493 1.1 christos case BB_REG_OPR_REG:
2494 1.1 christos case BB_REG_OPR_IMM:
2495 1.1 christos case BB_OPR_REG_REG:
2496 1.1 christos case BB_OPR_REG_IMM:
2497 1.1 christos {
2498 1.1 christos int size = (bb >> 2) & 0x03;
2499 1.1 christos (*info->fprintf_func) (info->stream, ".%c",
2500 1.1 christos shift_size_table [size]);
2501 1.1 christos }
2502 1.1 christos break;
2503 1.1 christos default:
2504 1.1 christos break;
2505 1.1 christos }
2506 1.1 christos
2507 1.1 christos int reg1 = byte2 & 0x07;
2508 1.1 christos /* First operand */
2509 1.1 christos switch (mode)
2510 1.1 christos {
2511 1.1 christos case BB_REG_REG_REG:
2512 1.1 christos case BB_REG_REG_IMM:
2513 1.1 christos case BB_REG_OPR_REG:
2514 1.1 christos case BB_REG_OPR_IMM:
2515 1.1 christos operand_separator (info);
2516 1.1 christos (*info->fprintf_func) (info->stream, "%s",
2517 1.1 christos registers[reg1].name);
2518 1.1 christos break;
2519 1.1 christos case BB_OPR_REG_REG:
2520 1.1 christos opr_decode (memaddr + 1, info);
2521 1.1 christos break;
2522 1.1 christos case BB_OPR_REG_IMM:
2523 1.1 christos opr_decode (memaddr + 2, info);
2524 1.1 christos break;
2525 1.1 christos }
2526 1.1 christos
2527 1.1 christos /* Second operand */
2528 1.1 christos switch (mode)
2529 1.1 christos {
2530 1.1 christos case BB_REG_REG_REG:
2531 1.1 christos case BB_REG_REG_IMM:
2532 1.1 christos {
2533 1.1 christos int reg_src = (bb >> 2) & 0x07;
2534 1.1 christos operand_separator (info);
2535 1.1 christos (*info->fprintf_func) (info->stream, "%s",
2536 1.1 christos registers[reg_src].name);
2537 1.1 christos }
2538 1.1 christos break;
2539 1.1 christos case BB_OPR_REG_REG:
2540 1.1 christos case BB_OPR_REG_IMM:
2541 1.1 christos {
2542 1.1 christos int reg_src = (byte2 & 0x07);
2543 1.1 christos operand_separator (info);
2544 1.1 christos (*info->fprintf_func) (info->stream, "%s",
2545 1.1 christos registers[reg_src].name);
2546 1.1 christos }
2547 1.1 christos break;
2548 1.1 christos case BB_REG_OPR_REG:
2549 1.1 christos opr_decode (memaddr + 1, info);
2550 1.1 christos break;
2551 1.1 christos case BB_REG_OPR_IMM:
2552 1.1 christos opr_decode (memaddr + 2, info);
2553 1.1 christos break;
2554 1.1 christos }
2555 1.1 christos
2556 1.1 christos /* Third operand */
2557 1.1 christos operand_separator (info);
2558 1.1 christos switch (mode)
2559 1.1 christos {
2560 1.1 christos case BB_REG_REG_REG:
2561 1.1 christos case BB_OPR_REG_REG:
2562 1.1 christos case BB_REG_OPR_REG:
2563 1.1 christos {
2564 1.1 christos int reg_parm = bb & 0x03;
2565 1.1 christos (*info->fprintf_func) (info->stream, "%s",
2566 1.1 christos registers[reg_parm].name);
2567 1.1 christos }
2568 1.1 christos break;
2569 1.1 christos case BB_REG_REG_IMM:
2570 1.1 christos case BB_OPR_REG_IMM:
2571 1.1 christos case BB_REG_OPR_IMM:
2572 1.1 christos {
2573 1.1 christos bfd_byte i1;
2574 1.1 christos read_memory (memaddr + 1, &i1, 1, info);
2575 1.1 christos int offset = i1 & 0x1f;
2576 1.1 christos int width = bb & 0x03;
2577 1.1 christos width <<= 3;
2578 1.1 christos width |= i1 >> 5;
2579 1.1 christos (*info->fprintf_func) (info->stream, "#%d:%d", width, offset);
2580 1.1 christos }
2581 1.1 christos break;
2582 1.1 christos }
2583 1.1 christos }
2584 1.1 christos }
2585 1.1 christos break;
2586 1.1 christos case 0xae: /* EXG / SEX */
2587 1.1 christos status = print_insn_exg_sex (memaddr, info);
2588 1.1 christos break;
2589 1.1 christos case 0x0b: /* Loop Primitives TBcc and DBcc */
2590 1.1 christos status = print_insn_loop_primitive (memaddr, info);
2591 1.1 christos break;
2592 1.1 christos case 0x10: /* shift */
2593 1.1 christos case 0x11: /* shift */
2594 1.1 christos case 0x12: /* shift */
2595 1.1 christos case 0x13: /* shift */
2596 1.1 christos case 0x14: /* shift */
2597 1.1 christos case 0x15: /* shift */
2598 1.1 christos case 0x16: /* shift */
2599 1.1 christos case 0x17: /* shift */
2600 1.1 christos status = print_insn_shift (memaddr, info, byte);
2601 1.1 christos break;
2602 1.1 christos case 0x04: /* psh / pul */
2603 1.1 christos {
2604 1.1 christos read_memory (memaddr, &byte, 1, info);
2605 1.1 christos (*info->fprintf_func) (info->stream, (byte & 0x80) ? "pul" : "psh");
2606 1.1 christos int bit;
2607 1.1 christos if (byte & 0x40)
2608 1.1 christos {
2609 1.1 christos if ((byte & 0x3F) == 0)
2610 1.1 christos {
2611 1.1 christos operand_separator (info);
2612 1.1 christos (*info->fprintf_func) (info->stream, "%s", "ALL16b");
2613 1.1 christos }
2614 1.1 christos else
2615 1.1 christos for (bit = 5; bit >= 0; --bit)
2616 1.1 christos {
2617 1.1 christos if (byte & (0x1 << bit))
2618 1.1 christos {
2619 1.1 christos operand_separator (info);
2620 1.1 christos (*info->fprintf_func) (info->stream, "%s", oprregs2[bit]);
2621 1.1 christos }
2622 1.1 christos }
2623 1.1 christos }
2624 1.1 christos else
2625 1.1 christos {
2626 1.1 christos if ((byte & 0x3F) == 0)
2627 1.1 christos {
2628 1.1 christos operand_separator (info);
2629 1.1 christos (*info->fprintf_func) (info->stream, "%s", "ALL");
2630 1.1 christos }
2631 1.1 christos else
2632 1.1 christos for (bit = 5; bit >= 0; --bit)
2633 1.1 christos {
2634 1.1 christos if (byte & (0x1 << bit))
2635 1.1 christos {
2636 1.1 christos operand_separator (info);
2637 1.1 christos (*info->fprintf_func) (info->stream, "%s", oprregs1[bit]);
2638 1.1 christos }
2639 1.1 christos }
2640 1.1 christos }
2641 1.1 christos }
2642 1.1 christos break;
2643 1.1 christos default:
2644 1.1 christos operand_separator (info);
2645 1.1 christos (*info->fprintf_func) (info->stream, "???");
2646 1.1 christos break;
2647 1.1 christos }
2648 1.1 christos }
2649 1.1 christos
2650 1.1 christos if (opc2 == NULL)
2651 1.1 christos {
2652 1.1 christos if (opc->operands)
2653 1.1 christos {
2654 1.1 christos opc->operands (memaddr, info);
2655 1.1 christos }
2656 1.1 christos
2657 1.1 christos if (opc->operands2)
2658 1.1 christos {
2659 1.1 christos opc->operands2 (memaddr, info);
2660 1.1 christos }
2661 1.1 christos }
2662 1.1 christos
2663 1.1 christos int n = 0;
2664 1.1 christos
2665 1.1 christos /* Opcodes in page2 have an additional byte */
2666 1.1 christos if (opc2)
2667 1.1 christos n++;
2668 1.1 christos
2669 1.1 christos if (opc2 && opc2->insn_bytes == 0)
2670 1.1 christos return n;
2671 1.1 christos
2672 1.1 christos if (!opc2 && opc->insn_bytes == 0)
2673 return n;
2674
2675 if (opc2)
2676 n += opc2->insn_bytes (memaddr, info);
2677 else
2678 n += opc->insn_bytes (memaddr, info);
2679
2680 return n;
2681 }
2682