M680XDisassembler.c
Go to the documentation of this file.
1 /* Capstone Disassembly Engine */
2 /* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
3 
4 /* ======================================================================== */
5 /* ================================ INCLUDES ============================== */
6 /* ======================================================================== */
7 
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include "../../cs_priv.h"
13 #include "../../utils.h"
14 
15 #include "../../MCInst.h"
16 #include "../../MCInstrDesc.h"
17 #include "../../MCRegisterInfo.h"
18 #include "M680XInstPrinter.h"
19 #include "M680XDisassembler.h"
21 
22 #ifdef CAPSTONE_HAS_M680X
23 
24 #ifndef DECL_SPEC
25 #ifdef _MSC_VER
26 #define DECL_SPEC __cdecl
27 #else
28 #define DECL_SPEC
29 #endif // _MSC_VER
30 #endif // DECL_SPEC
31 
32 /* ======================================================================== */
33 /* ============================ GENERAL DEFINES =========================== */
34 /* ======================================================================== */
35 
36 /* ======================================================================== */
37 /* =============================== PROTOTYPES ============================= */
38 /* ======================================================================== */
39 
40 typedef enum insn_hdlr_id {
41  illgl_hid,
42  rel8_hid,
43  rel16_hid,
44  imm8_hid,
45  imm16_hid,
46  imm32_hid,
47  dir_hid,
48  ext_hid,
49  idxX_hid,
50  idxY_hid,
51  idx09_hid,
52  inh_hid,
53  rr09_hid,
54  rbits_hid,
55  bitmv_hid,
56  tfm_hid,
57  opidx_hid,
58  opidxdr_hid,
59  idxX0_hid,
60  idxX16_hid,
61  imm8rel_hid,
62  idxS_hid,
63  idxS16_hid,
64  idxXp_hid,
65  idxX0p_hid,
66  idx12_hid,
67  idx12s_hid,
68  rr12_hid,
69  loop_hid,
70  index_hid,
71  imm8i12x_hid,
72  imm16i12x_hid,
73  exti12x_hid,
74  HANDLER_ID_ENDING,
75 } insn_hdlr_id;
76 
77 // Access modes for the first 4 operands. If there are more than
78 // four operands they use the same access mode as the 4th operand.
79 //
80 // u: unchanged
81 // r: (r)read access
82 // w: (w)write access
83 // m: (m)odify access (= read + write)
84 //
85 typedef enum e_access_mode {
86 
87  uuuu,
88  rrrr,
89  wwww,
90  rwww,
91  rrrm,
92  rmmm,
93  wrrr,
94  mrrr,
95  mwww,
96  mmmm,
97  mwrr,
98  mmrr,
99  wmmm,
100  rruu,
101  muuu,
102  ACCESS_MODE_ENDING,
103 } e_access_mode;
104 
105 // Access type values are compatible with enum cs_ac_type:
106 typedef enum e_access {
107  UNCHANGED = CS_AC_INVALID,
108  READ = CS_AC_READ,
109  WRITE = CS_AC_WRITE,
110  MODIFY = (CS_AC_READ | CS_AC_WRITE),
111 } e_access;
112 
113 /* Properties of one instruction in PAGE1 (without prefix) */
114 typedef struct inst_page1 {
115  m680x_insn insn : 9;
116  insn_hdlr_id handler_id1 : 6; /* first instruction handler id */
117  insn_hdlr_id handler_id2 : 6; /* second instruction handler id */
118 } inst_page1;
119 
120 /* Properties of one instruction in any other PAGE X */
121 typedef struct inst_pageX {
122  unsigned opcode : 8;
123  m680x_insn insn : 9;
124  insn_hdlr_id handler_id1 : 6; /* first instruction handler id */
125  insn_hdlr_id handler_id2 : 6; /* second instruction handler id */
126 } inst_pageX;
127 
128 typedef struct insn_props {
129  unsigned group : 4;
130  e_access_mode access_mode : 5;
131  m680x_reg reg0 : 5;
132  m680x_reg reg1 : 5;
133  bool cc_modified : 1;
134  bool update_reg_access : 1;
135 } insn_props;
136 
137 #include "m6800.inc"
138 #include "m6801.inc"
139 #include "hd6301.inc"
140 #include "m6811.inc"
141 #include "cpu12.inc"
142 #include "m6805.inc"
143 #include "m6808.inc"
144 #include "hcs08.inc"
145 #include "m6809.inc"
146 #include "hd6309.inc"
147 
148 #include "insn_props.inc"
149 
151 
152 // M680X instuctions have 1 up to 8 bytes (CPU12: MOVW IDX2,IDX2).
153 // A reader is needed to read a byte or word from a given memory address.
154 // See also X86 reader(...)
155 static bool read_byte(const m680x_info *info, uint8_t *byte, uint16_t address)
156 {
157  if (address - info->offset >= info->size)
158  // out of code buffer range
159  return false;
160 
161  *byte = info->code[address - info->offset];
162 
163  return true;
164 }
165 
166 static bool read_byte_sign_extended(const m680x_info *info, int16_t *word,
167  uint16_t address)
168 {
169  if (address - info->offset >= info->size)
170  // out of code buffer range
171  return false;
172 
173  *word = (int16_t) info->code[address - info->offset];
174 
175  if (*word & 0x80)
176  *word |= 0xFF00;
177 
178  return true;
179 }
180 
181 static bool read_word(const m680x_info *info, uint16_t *word, uint16_t address)
182 {
183  if (address + 1 - info->offset >= info->size)
184  // out of code buffer range
185  return false;
186 
187  *word = (uint16_t)info->code[address - info->offset] << 8;
188  *word |= (uint16_t)info->code[address + 1 - info->offset];
189 
190  return true;
191 }
192 
193 static bool read_sdword(const m680x_info *info, int32_t *sdword,
194  uint16_t address)
195 {
196  if (address + 3 - info->offset >= info->size)
197  // out of code buffer range
198  return false;
199 
200  *sdword = (uint32_t)info->code[address - info->offset] << 24;
201  *sdword |= (uint32_t)info->code[address + 1 - info->offset] << 16;
202  *sdword |= (uint32_t)info->code[address + 2 - info->offset] << 8;
203  *sdword |= (uint32_t)info->code[address + 3 - info->offset];
204 
205  return true;
206 }
207 
208 // For PAGE2 and PAGE3 opcodes when using an an array of inst_page1 most
209 // entries have M680X_INS_ILLGL. To avoid wasting memory an inst_pageX is
210 // used which contains the opcode. Using a binary search for the right opcode
211 // is much faster (= O(log n) ) in comparison to a linear search ( = O(n) ).
212 static int binary_search(const inst_pageX *const inst_pageX_table,
213  int table_size, uint8_t opcode)
214 {
215  int first = 0;
216  int last = table_size - 1;
217  int middle = (first + last) / 2;
218 
219  while (first <= last) {
220  if (inst_pageX_table[middle].opcode < opcode) {
221  first = middle + 1;
222  }
223  else if (inst_pageX_table[middle].opcode == opcode) {
224  return middle; /* item found */
225  }
226  else
227  last = middle - 1;
228 
229  middle = (first + last) / 2;
230  }
231 
232  if (first > last)
233  return -1; /* item not found */
234 
235  return -2;
236 }
237 
238 void M680X_get_insn_id(cs_struct *handle, cs_insn *insn, unsigned int id)
239 {
240  const m680x_info *const info = (const m680x_info *)handle->printer_info;
241  const cpu_tables *cpu = info->cpu;
242  uint8_t insn_prefix = (id >> 8) & 0xff;
243  int index;
244  int i;
245 
246  insn->id = M680X_INS_ILLGL;
247 
248  for (i = 0; i < ARR_SIZE(cpu->pageX_prefix); ++i) {
249  if (cpu->pageX_table_size[i] == 0 ||
250  (cpu->inst_pageX_table[i] == NULL))
251  break;
252 
253  if (cpu->pageX_prefix[i] == insn_prefix) {
254  index = binary_search(cpu->inst_pageX_table[i],
255  cpu->pageX_table_size[i], id & 0xff);
256  insn->id = (index >= 0) ?
257  cpu->inst_pageX_table[i][index].insn :
259  return;
260  }
261  }
262 
263  if (insn_prefix != 0)
264  return;
265 
266  insn->id = cpu->inst_page1_table[id].insn;
267 
268  if (insn->id != M680X_INS_ILLGL)
269  return;
270 
271  // Check if opcode byte is present in an overlay table
272  for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
273  if (cpu->overlay_table_size[i] == 0 ||
274  (cpu->inst_overlay_table[i] == NULL))
275  break;
276 
277  if ((index = binary_search(cpu->inst_overlay_table[i],
278  cpu->overlay_table_size[i],
279  id & 0xff)) >= 0) {
280  insn->id = cpu->inst_overlay_table[i][index].insn;
281  return;
282  }
283  }
284 }
285 
286 static void add_insn_group(cs_detail *detail, m680x_group_type group)
287 {
288  if (detail != NULL &&
290  detail->groups[detail->groups_count++] = (uint8_t)group;
291 }
292 
293 static bool exists_reg_list(uint16_t *regs, uint8_t count, m680x_reg reg)
294 {
295  uint8_t i;
296 
297  for (i = 0; i < count; ++i) {
298  if (regs[i] == (uint16_t)reg)
299  return true;
300  }
301 
302  return false;
303 }
304 
305 static void add_reg_to_rw_list(MCInst *MI, m680x_reg reg, e_access access)
306 {
307  cs_detail *detail = MI->flat_insn->detail;
308 
309  if (detail == NULL || (reg == M680X_REG_INVALID))
310  return;
311 
312  switch (access) {
313  case MODIFY:
314  if (!exists_reg_list(detail->regs_read,
315  detail->regs_read_count, reg))
316  detail->regs_read[detail->regs_read_count++] =
317  (uint16_t)reg;
318 
319  // intentionally fall through
320 
321  case WRITE:
322  if (!exists_reg_list(detail->regs_write,
323  detail->regs_write_count, reg))
324  detail->regs_write[detail->regs_write_count++] =
325  (uint16_t)reg;
326 
327  break;
328 
329  case READ:
330  if (!exists_reg_list(detail->regs_read,
331  detail->regs_read_count, reg))
332  detail->regs_read[detail->regs_read_count++] =
333  (uint16_t)reg;
334 
335  break;
336 
337  case UNCHANGED:
338  default:
339  break;
340  }
341 }
342 
343 static void update_am_reg_list(MCInst *MI, m680x_info *info, cs_m680x_op *op,
344  e_access access)
345 {
346  if (MI->flat_insn->detail == NULL)
347  return;
348 
349  switch (op->type) {
350  case M680X_OP_REGISTER:
351  add_reg_to_rw_list(MI, op->reg, access);
352  break;
353 
354  case M680X_OP_INDEXED:
355  add_reg_to_rw_list(MI, op->idx.base_reg, READ);
356 
357  if (op->idx.base_reg == M680X_REG_X &&
358  info->cpu->reg_byte_size[M680X_REG_H])
359  add_reg_to_rw_list(MI, M680X_REG_H, READ);
360 
361 
362  if (op->idx.offset_reg != M680X_REG_INVALID)
363  add_reg_to_rw_list(MI, op->idx.offset_reg, READ);
364 
365  if (op->idx.inc_dec) {
366  add_reg_to_rw_list(MI, op->idx.base_reg, WRITE);
367 
368  if (op->idx.base_reg == M680X_REG_X &&
369  info->cpu->reg_byte_size[M680X_REG_H])
371  }
372 
373  break;
374 
375  default:
376  break;
377  }
378 }
379 
380 static const e_access g_access_mode_to_access[4][15] = {
381  {
382  UNCHANGED, READ, WRITE, READ, READ, READ, WRITE, MODIFY,
383  MODIFY, MODIFY, MODIFY, MODIFY, WRITE, READ, MODIFY,
384  },
385  {
386  UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ, READ,
387  WRITE, MODIFY, WRITE, MODIFY, MODIFY, READ, UNCHANGED,
388  },
389  {
390  UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ, READ,
391  WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
392  },
393  {
394  UNCHANGED, READ, WRITE, WRITE, MODIFY, MODIFY, READ, READ,
395  WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
396  },
397 };
398 
399 static e_access get_access(int operator_index, e_access_mode access_mode)
400 {
401  int idx = (operator_index > 3) ? 3 : operator_index;
402 
403  return g_access_mode_to_access[idx][access_mode];
404 }
405 
406 static void build_regs_read_write_counts(MCInst *MI, m680x_info *info,
407  e_access_mode access_mode)
408 {
409  cs_m680x *m680x = &info->m680x;
410  int i;
411 
412  if (MI->flat_insn->detail == NULL || (!m680x->op_count))
413  return;
414 
415  for (i = 0; i < m680x->op_count; ++i) {
416 
417  e_access access = get_access(i, access_mode);
418  update_am_reg_list(MI, info, &m680x->operands[i], access);
419  }
420 }
421 
422 static void add_operators_access(MCInst *MI, m680x_info *info,
423  e_access_mode access_mode)
424 {
425  cs_m680x *m680x = &info->m680x;
426  int offset = 0;
427  int i;
428 
429  if (MI->flat_insn->detail == NULL || (!m680x->op_count) ||
430  (access_mode == uuuu))
431  return;
432 
433  for (i = 0; i < m680x->op_count; ++i) {
434  e_access access;
435 
436  // Ugly fix: MULD has a register operand, an immediate operand
437  // AND an implicitly changed register W
438  if (info->insn == M680X_INS_MULD && (i == 1))
439  offset = 1;
440 
441  access = get_access(i + offset, access_mode);
442  m680x->operands[i].access = access;
443  }
444 }
445 
446 typedef struct insn_to_changed_regs {
447  m680x_insn insn;
448  e_access_mode access_mode;
449  m680x_reg regs[10];
450 } insn_to_changed_regs;
451 
452 static void set_changed_regs_read_write_counts(MCInst *MI, m680x_info *info)
453 {
454  //TABLE
455 #define EOL M680X_REG_INVALID
456  static const insn_to_changed_regs changed_regs[] = {
457  { M680X_INS_BSR, mmmm, { M680X_REG_S, EOL } },
458  { M680X_INS_CALL, mmmm, { M680X_REG_S, EOL } },
459  {
460  M680X_INS_CWAI, mrrr, {
464  },
465  },
466  { M680X_INS_DAA, mrrr, { M680X_REG_A, EOL } },
467  {
468  M680X_INS_DIV, mmrr, {
470  }
471  },
472  {
473  M680X_INS_EDIV, mmrr, {
475  }
476  },
477  {
478  M680X_INS_EDIVS, mmrr, {
480  }
481  },
482  { M680X_INS_EMACS, mrrr, { M680X_REG_X, M680X_REG_Y, EOL } },
483  { M680X_INS_EMAXM, rrrr, { M680X_REG_D, EOL } },
484  { M680X_INS_EMINM, rrrr, { M680X_REG_D, EOL } },
485  { M680X_INS_EMUL, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
486  { M680X_INS_EMULS, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
487  { M680X_INS_ETBL, wmmm, { M680X_REG_A, M680X_REG_B, EOL } },
488  { M680X_INS_FDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
489  { M680X_INS_IDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
490  { M680X_INS_IDIVS, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
491  { M680X_INS_JSR, mmmm, { M680X_REG_S, EOL } },
492  { M680X_INS_LBSR, mmmm, { M680X_REG_S, EOL } },
493  { M680X_INS_MAXM, rrrr, { M680X_REG_A, EOL } },
494  { M680X_INS_MINM, rrrr, { M680X_REG_A, EOL } },
495  {
496  M680X_INS_MEM, mmrr, {
498  }
499  },
500  { M680X_INS_MUL, mmmm, { M680X_REG_A, M680X_REG_B, EOL } },
501  { M680X_INS_MULD, mwrr, { M680X_REG_D, M680X_REG_W, EOL } },
502  { M680X_INS_PSHA, rmmm, { M680X_REG_A, M680X_REG_S, EOL } },
503  { M680X_INS_PSHB, rmmm, { M680X_REG_B, M680X_REG_S, EOL } },
504  { M680X_INS_PSHC, rmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
505  { M680X_INS_PSHD, rmmm, { M680X_REG_D, M680X_REG_S, EOL } },
506  { M680X_INS_PSHH, rmmm, { M680X_REG_H, M680X_REG_S, EOL } },
507  { M680X_INS_PSHX, rmmm, { M680X_REG_X, M680X_REG_S, EOL } },
508  { M680X_INS_PSHY, rmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
509  { M680X_INS_PULA, wmmm, { M680X_REG_A, M680X_REG_S, EOL } },
510  { M680X_INS_PULB, wmmm, { M680X_REG_B, M680X_REG_S, EOL } },
511  { M680X_INS_PULC, wmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
512  { M680X_INS_PULD, wmmm, { M680X_REG_D, M680X_REG_S, EOL } },
513  { M680X_INS_PULH, wmmm, { M680X_REG_H, M680X_REG_S, EOL } },
514  { M680X_INS_PULX, wmmm, { M680X_REG_X, M680X_REG_S, EOL } },
515  { M680X_INS_PULY, wmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
516  {
517  M680X_INS_REV, mmrr, {
519  }
520  },
521  {
522  M680X_INS_REVW, mmmm, {
524  }
525  },
526  { M680X_INS_RTC, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
527  {
528  M680X_INS_RTI, mwww, {
532  EOL
533  },
534  },
535  { M680X_INS_RTS, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
536  { M680X_INS_SEX, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
537  { M680X_INS_SEXW, rwww, { M680X_REG_W, M680X_REG_D, EOL } },
538  {
539  M680X_INS_SWI, mmrr, {
543  EOL
544  }
545  },
546  {
547  M680X_INS_SWI2, mmrr, {
551  EOL
552  },
553  },
554  {
555  M680X_INS_SWI3, mmrr, {
559  EOL
560  },
561  },
562  { M680X_INS_TBL, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
563  {
564  M680X_INS_WAI, mrrr, {
567  EOL
568  }
569  },
570  {
571  M680X_INS_WAV, rmmm, {
573  M680X_REG_Y, EOL
574  }
575  },
576  {
577  M680X_INS_WAVR, rmmm, {
579  M680X_REG_Y, EOL
580  }
581  },
582  };
583 
584  int i, j;
585 
586  if (MI->flat_insn->detail == NULL)
587  return;
588 
589  for (i = 0; i < ARR_SIZE(changed_regs); ++i) {
590  if (info->insn == changed_regs[i].insn) {
591  e_access_mode access_mode = changed_regs[i].access_mode;
592 
593  for (j = 0; changed_regs[i].regs[j] != EOL; ++j) {
594  e_access access;
595 
596  m680x_reg reg = changed_regs[i].regs[j];
597 
598  if (!info->cpu->reg_byte_size[reg]) {
599  if (info->insn != M680X_INS_MUL)
600  continue;
601 
602  // Hack for M68HC05: MUL uses reg. A,X
603  reg = M680X_REG_X;
604  }
605 
606  access = get_access(j, access_mode);
607  add_reg_to_rw_list(MI, reg, access);
608  }
609  }
610  }
611 
612 #undef EOL
613 }
614 
615 typedef struct insn_desc {
617  m680x_insn insn;
618  insn_hdlr_id hid[2];
619  uint16_t insn_size;
620 } insn_desc;
621 
622 static bool is_indexed09_post_byte_valid(const m680x_info *info,
623  uint16_t *address, uint8_t post_byte, insn_desc *insn_description)
624 {
625  uint8_t ir = 0;
626  bool retval;
627 
628  switch (post_byte & 0x9F) {
629  case 0x87:
630  case 0x8A:
631  case 0x8E:
632  case 0x8F:
633  case 0x90:
634  case 0x92:
635  case 0x97:
636  case 0x9A:
637  case 0x9E:
638  return false; // illegal indexed post bytes
639 
640  case 0x88: // n8,R
641  case 0x8C: // n8,PCR
642  case 0x98: // [n8,R]
643  case 0x9C: // [n8,PCR]
644  insn_description->insn_size++;
645  return read_byte(info, &ir, (*address)++);
646 
647  case 0x89: // n16,R
648  case 0x8D: // n16,PCR
649  case 0x99: // [n16,R]
650  case 0x9D: // [n16,PCR]
651  insn_description->insn_size += 2;
652  retval = read_byte(info, &ir, *address + 1);
653  *address += 2;
654  return retval;
655 
656  case 0x9F: // [n]
657  insn_description->insn_size += 2;
658  retval = (post_byte & 0x60) == 0 &&
659  read_byte(info, &ir, *address + 1);
660  *address += 2;
661  return retval;
662  }
663 
664  return true; // Any other indexed post byte is valid and
665  // no additional bytes have to be read.
666 }
667 
668 static bool is_indexed12_post_byte_valid(const m680x_info *info,
669  uint16_t *address, uint8_t post_byte, insn_desc *insn_description,
670  bool is_subset)
671 {
672  uint8_t ir;
673  bool result;
674 
675  if (!(post_byte & 0x20)) // n5,R
676  return true;
677 
678  switch (post_byte & 0xe7) {
679  case 0xe0:
680  case 0xe1: // n9,R
681  if (is_subset)
682  return false;
683 
684  insn_description->insn_size++;
685  return read_byte(info, &ir, (*address)++);
686 
687  case 0xe2: // n16,R
688  case 0xe3: // [n16,R]
689  if (is_subset)
690  return false;
691 
692  insn_description->insn_size += 2;
693  result = read_byte(info, &ir, *address + 1);
694  *address += 2;
695  return result;
696 
697  case 0xe4: // A,R
698  case 0xe5: // B,R
699  case 0xe6: // D,R
700  case 0xe7: // [D,R]
701  default: // n,-r n,+r n,r- n,r+
702  break;
703  }
704 
705  return true;
706 }
707 
708 // Check for M6809/HD6309 TFR/EXG instruction for valid register
709 static bool is_tfr09_reg_valid(const m680x_info *info, uint8_t reg_nibble)
710 {
711  if (info->cpu->tfr_reg_valid != NULL)
712  return info->cpu->tfr_reg_valid[reg_nibble];
713 
714  return true; // e.g. for the M6309 all registers are valid
715 }
716 
717 // Check for CPU12 TFR/EXG instruction for valid register
718 static bool is_exg_tfr12_post_byte_valid(const m680x_info *info,
719  uint8_t post_byte)
720 {
721  return !(post_byte & 0x08);
722 }
723 
724 static bool is_tfm_reg_valid(const m680x_info *info, uint8_t reg_nibble)
725 {
726  // HD6809 TFM instruction: Only register X,Y,U,S,D is allowed
727  return reg_nibble <= 4;
728 }
729 
730 static bool is_loop_post_byte_valid(const m680x_info *info, uint8_t post_byte)
731 {
732  // According to documentation bit 3 is don't care and not checked here.
733  if (post_byte >= 0xc0)
734  return false;
735 
736  return ((post_byte & 0x07) != 2 && ((post_byte & 0x07) != 3));
737 }
738 
739 static bool is_sufficient_code_size(const m680x_info *info, uint16_t address,
740  insn_desc *insn_description)
741 {
742  int i;
743  bool retval;
744 
745  for (i = 0; i < 2; i++) {
746  uint8_t ir = 0;
747  bool is_subset = false;
748 
749  switch (insn_description->hid[i]) {
750 
751  case imm32_hid:
752  insn_description->insn_size += 4;
753  retval = read_byte(info, &ir, address + 3);
754  address += 4;
755  break;
756 
757  case ext_hid:
758  case imm16_hid:
759  case rel16_hid:
760  case imm8rel_hid:
761  case opidxdr_hid:
762  case idxX16_hid:
763  case idxS16_hid:
764  insn_description->insn_size += 2;
765  retval = read_byte(info, &ir, address + 1);
766  address += 2;
767  break;
768 
769  case rel8_hid:
770  case dir_hid:
771  case rbits_hid:
772  case imm8_hid:
773  case idxX_hid:
774  case idxXp_hid:
775  case idxY_hid:
776  case idxS_hid:
777  case index_hid:
778  insn_description->insn_size += 1;
779  retval = read_byte(info, &ir, address++);
780  break;
781 
782  case illgl_hid:
783  case inh_hid:
784  case idxX0_hid:
785  case idxX0p_hid:
786  case opidx_hid:
787  retval = true;
788  break;
789 
790  case idx09_hid:
791  insn_description->insn_size += 1;
792 
793  if (!read_byte(info, &ir, address++))
794  retval = false;
795  else
796  retval = is_indexed09_post_byte_valid(info,
797  &address, ir, insn_description);
798 
799  break;
800 
801  case idx12s_hid:
802  is_subset = true;
803 
804  // intentionally fall through
805 
806  case idx12_hid:
807  insn_description->insn_size += 1;
808 
809  if (!read_byte(info, &ir, address++))
810  retval = false;
811  else
812  retval = is_indexed12_post_byte_valid(info,
813  &address, ir, insn_description,
814  is_subset);
815 
816  break;
817 
818  case exti12x_hid:
819  case imm16i12x_hid:
820  insn_description->insn_size += 1;
821 
822  if (!read_byte(info, &ir, address++))
823  retval = false;
824  else if (!is_indexed12_post_byte_valid(info, &address,
825  ir, insn_description, false))
826  retval = false;
827  else {
828  insn_description->insn_size += 2;
829  retval = read_byte(info, &ir, address + 1);
830  address += 2;
831  }
832 
833  break;
834 
835  case imm8i12x_hid:
836  insn_description->insn_size += 1;
837 
838  if (!read_byte(info, &ir, address++))
839  retval = false;
840  else if (!is_indexed12_post_byte_valid(info, &address,
841  ir, insn_description, false))
842  retval = false;
843  else {
844  insn_description->insn_size += 1;
845  retval = read_byte(info, &ir, address++);
846  }
847 
848  break;
849 
850  case tfm_hid:
851  insn_description->insn_size += 1;
852 
853  if (!read_byte(info, &ir, address++))
854  retval = false;
855  else
856  retval = is_tfm_reg_valid(info, (ir >> 4) & 0x0F) &&
857  is_tfm_reg_valid(info, ir & 0x0F);
858 
859  break;
860 
861  case rr09_hid:
862  insn_description->insn_size += 1;
863 
864  if (!read_byte(info, &ir, address++))
865  retval = false;
866  else
867  retval = is_tfr09_reg_valid(info, (ir >> 4) & 0x0F) &&
868  is_tfr09_reg_valid(info, ir & 0x0F);
869 
870  break;
871 
872  case rr12_hid:
873  insn_description->insn_size += 1;
874 
875  if (!read_byte(info, &ir, address++))
876  retval = false;
877  else
878  retval = is_exg_tfr12_post_byte_valid(info, ir);
879 
880  break;
881 
882  case bitmv_hid:
883  insn_description->insn_size += 2;
884 
885  if (!read_byte(info, &ir, address++))
886  retval = false;
887  else if ((ir & 0xc0) == 0xc0)
888  retval = false; // Invalid register specified
889  else
890  retval = read_byte(info, &ir, address++);
891 
892  break;
893 
894  case loop_hid:
895  insn_description->insn_size += 2;
896 
897  if (!read_byte(info, &ir, address++))
898  retval = false;
899  else if (!is_loop_post_byte_valid(info, ir))
900  retval = false;
901  else
902  retval = read_byte(info, &ir, address++);
903 
904  break;
905 
906  default:
907  fprintf(stderr, "Internal error: Unexpected instruction "
908  "handler id %d\n", insn_description->hid[i]);
909  retval = false;
910  break;
911  }
912 
913  if (!retval)
914  return false;
915  }
916 
917  return retval;
918 }
919 
920 // Check for a valid M680X instruction AND for enough bytes in the code buffer
921 // Return an instruction description in insn_desc.
922 static bool decode_insn(const m680x_info *info, uint16_t address,
923  insn_desc *insn_description)
924 {
925  const inst_pageX *inst_table = NULL;
926  const cpu_tables *cpu = info->cpu;
927  int table_size = 0;
928  uint16_t base_address = address;
929  uint8_t ir; // instruction register
930  int i;
931  int index;
932 
933  if (!read_byte(info, &ir, address++))
934  return false;
935 
936  insn_description->insn = M680X_INS_ILLGL;
937  insn_description->opcode = ir;
938 
939  // Check if a page prefix byte is present
940  for (i = 0; i < ARR_SIZE(cpu->pageX_table_size); ++i) {
941  if (cpu->pageX_table_size[i] == 0 ||
942  (cpu->inst_pageX_table[i] == NULL))
943  break;
944 
945  if ((cpu->pageX_prefix[i] == ir)) {
946  // Get pageX instruction and handler id.
947  // Abort for illegal instr.
948  inst_table = cpu->inst_pageX_table[i];
949  table_size = cpu->pageX_table_size[i];
950 
951  if (!read_byte(info, &ir, address++))
952  return false;
953 
954  insn_description->opcode =
955  (insn_description->opcode << 8) | ir;
956 
957  if ((index = binary_search(inst_table, table_size, ir)) < 0)
958  return false;
959 
960  insn_description->hid[0] =
961  inst_table[index].handler_id1;
962  insn_description->hid[1] =
963  inst_table[index].handler_id2;
964  insn_description->insn = inst_table[index].insn;
965  break;
966  }
967  }
968 
969  if (insn_description->insn == M680X_INS_ILLGL) {
970  // Get page1 insn description
971  insn_description->insn = cpu->inst_page1_table[ir].insn;
972  insn_description->hid[0] =
973  cpu->inst_page1_table[ir].handler_id1;
974  insn_description->hid[1] =
975  cpu->inst_page1_table[ir].handler_id2;
976  }
977 
978  if (insn_description->insn == M680X_INS_ILLGL) {
979  // Check if opcode byte is present in an overlay table
980  for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
981  if (cpu->overlay_table_size[i] == 0 ||
982  (cpu->inst_overlay_table[i] == NULL))
983  break;
984 
985  inst_table = cpu->inst_overlay_table[i];
986  table_size = cpu->overlay_table_size[i];
987 
988  if ((index = binary_search(inst_table, table_size,
989  ir)) >= 0) {
990  insn_description->hid[0] =
991  inst_table[index].handler_id1;
992  insn_description->hid[1] =
993  inst_table[index].handler_id2;
994  insn_description->insn = inst_table[index].insn;
995  break;
996  }
997  }
998  }
999 
1000  insn_description->insn_size = address - base_address;
1001 
1002  return (insn_description->insn != M680X_INS_ILLGL) &&
1003  (insn_description->insn != M680X_INS_INVLD) &&
1004  is_sufficient_code_size(info, address, insn_description);
1005 }
1006 
1007 static void illegal_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1008 {
1009  cs_m680x_op *op0 = &info->m680x.operands[info->m680x.op_count++];
1010  uint8_t temp8 = 0;
1011 
1012  info->insn = M680X_INS_ILLGL;
1013  read_byte(info, &temp8, (*address)++);
1014  op0->imm = (int32_t)temp8 & 0xff;
1015  op0->type = M680X_OP_IMMEDIATE;
1016  op0->size = 1;
1017 }
1018 
1019 static void inherent_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1020 {
1021  // There is nothing to do here :-)
1022 }
1023 
1024 static void add_reg_operand(m680x_info *info, m680x_reg reg)
1025 {
1026  cs_m680x *m680x = &info->m680x;
1027  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1028 
1029  op->type = M680X_OP_REGISTER;
1030  op->reg = reg;
1031  op->size = info->cpu->reg_byte_size[reg];
1032 }
1033 
1034 static void set_operand_size(m680x_info *info, cs_m680x_op *op,
1035  uint8_t default_size)
1036 {
1037  cs_m680x *m680x = &info->m680x;
1038 
1039  if (info->insn == M680X_INS_JMP || info->insn == M680X_INS_JSR)
1040  op->size = 0;
1041  else if (info->insn == M680X_INS_DIVD ||
1042  ((info->insn == M680X_INS_AIS || info->insn == M680X_INS_AIX) &&
1043  op->type != M680X_OP_REGISTER))
1044  op->size = 1;
1045  else if (info->insn == M680X_INS_DIVQ ||
1046  info->insn == M680X_INS_MOVW)
1047  op->size = 2;
1048  else if (info->insn == M680X_INS_EMACS)
1049  op->size = 4;
1050  else if ((m680x->op_count > 0) &&
1051  (m680x->operands[0].type == M680X_OP_REGISTER))
1052  op->size = m680x->operands[0].size;
1053  else
1054  op->size = default_size;
1055 }
1056 
1057 static const m680x_reg reg_s_reg_ids[] = {
1060 };
1061 
1062 static const m680x_reg reg_u_reg_ids[] = {
1065 };
1066 
1067 static void reg_bits_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1068 {
1069  cs_m680x_op *op0 = &info->m680x.operands[0];
1070  uint8_t reg_bits = 0;
1071  uint16_t bit_index;
1072  const m680x_reg *reg_to_reg_ids;
1073 
1074  read_byte(info, &reg_bits, (*address)++);
1075 
1076  switch (op0->reg) {
1077  case M680X_REG_U:
1078  reg_to_reg_ids = &reg_u_reg_ids[0];
1079  break;
1080 
1081  case M680X_REG_S:
1082  reg_to_reg_ids = &reg_s_reg_ids[0];
1083  break;
1084 
1085  default:
1086  fprintf(stderr, "Internal error: Unexpected operand0 register "
1087  "%d\n", op0->reg);
1088  abort();
1089  }
1090 
1091  if ((info->insn == M680X_INS_PULU ||
1092  (info->insn == M680X_INS_PULS)) &&
1093  ((reg_bits & 0x80) != 0))
1094  // PULS xxx,PC or PULU xxx,PC which is like return from
1095  // subroutine (RTS)
1096  add_insn_group(MI->flat_insn->detail, M680X_GRP_RET);
1097 
1098  for (bit_index = 0; bit_index < 8; ++bit_index) {
1099  if (reg_bits & (1 << bit_index))
1100  add_reg_operand(info, reg_to_reg_ids[bit_index]);
1101  }
1102 }
1103 
1104 static const m680x_reg g_tfr_exg_reg_ids[] = {
1105  /* 16-bit registers */
1108  /* 8-bit registers */
1111 };
1112 
1113 static void reg_reg09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1114 {
1115  uint8_t regs = 0;
1116 
1117  read_byte(info, &regs, (*address)++);
1118 
1119  add_reg_operand(info, g_tfr_exg_reg_ids[regs >> 4]);
1120  add_reg_operand(info, g_tfr_exg_reg_ids[regs & 0x0f]);
1121 
1122  if ((regs & 0x0f) == 0x05) {
1123  // EXG xxx,PC or TFR xxx,PC which is like a JMP
1124  add_insn_group(MI->flat_insn->detail, M680X_GRP_JUMP);
1125  }
1126 }
1127 
1128 
1129 static void reg_reg12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1130 {
1131  static const m680x_reg g_tfr_exg12_reg0_ids[] = {
1134  };
1135  static const m680x_reg g_tfr_exg12_reg1_ids[] = {
1138  };
1139  uint8_t regs = 0;
1140 
1141  read_byte(info, &regs, (*address)++);
1142 
1143  // The opcode of this instruction depends on
1144  // the msb of its post byte.
1145  if (regs & 0x80)
1146  info->insn = M680X_INS_EXG;
1147  else
1148  info->insn = M680X_INS_TFR;
1149 
1150  add_reg_operand(info, g_tfr_exg12_reg0_ids[(regs >> 4) & 0x07]);
1151  add_reg_operand(info, g_tfr_exg12_reg1_ids[regs & 0x07]);
1152 }
1153 
1154 static void add_rel_operand(m680x_info *info, int16_t offset, uint16_t address)
1155 {
1156  cs_m680x *m680x = &info->m680x;
1157  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1158 
1159  op->type = M680X_OP_RELATIVE;
1160  op->size = 0;
1161  op->rel.offset = offset;
1162  op->rel.address = address;
1163 }
1164 
1165 static void relative8_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1166 {
1167  int16_t offset = 0;
1168 
1169  read_byte_sign_extended(info, &offset, (*address)++);
1170  add_rel_operand(info, offset, *address + offset);
1171  add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
1172 
1173  if ((info->insn != M680X_INS_BRA) &&
1174  (info->insn != M680X_INS_BSR) &&
1175  (info->insn != M680X_INS_BRN))
1176  add_reg_to_rw_list(MI, M680X_REG_CC, READ);
1177 }
1178 
1179 static void relative16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1180 {
1181  uint16_t offset = 0;
1182 
1183  read_word(info, &offset, *address);
1184  *address += 2;
1185  add_rel_operand(info, (int16_t)offset, *address + offset);
1186  add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
1187 
1188  if ((info->insn != M680X_INS_LBRA) &&
1189  (info->insn != M680X_INS_LBSR) &&
1190  (info->insn != M680X_INS_LBRN))
1191  add_reg_to_rw_list(MI, M680X_REG_CC, READ);
1192 }
1193 
1194 static const m680x_reg g_rr5_to_reg_ids[] = {
1196 };
1197 
1198 static void add_indexed_operand(m680x_info *info, m680x_reg base_reg,
1199  bool post_inc_dec, uint8_t inc_dec, uint8_t offset_bits,
1200  uint16_t offset, bool no_comma)
1201 {
1202  cs_m680x *m680x = &info->m680x;
1203  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1204 
1205  op->type = M680X_OP_INDEXED;
1206  set_operand_size(info, op, 1);
1207  op->idx.base_reg = base_reg;
1208  op->idx.offset_reg = M680X_REG_INVALID;
1209  op->idx.inc_dec = inc_dec;
1210 
1211  if (inc_dec && post_inc_dec)
1213 
1214  if (offset_bits != M680X_OFFSET_NONE) {
1215  op->idx.offset = offset;
1216  op->idx.offset_addr = 0;
1217  }
1218 
1219  op->idx.offset_bits = offset_bits;
1220  op->idx.flags |= (no_comma ? M680X_IDX_NO_COMMA : 0);
1221 }
1222 
1223 // M6800/1/2/3 indexed mode handler
1224 static void indexedX_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1225 {
1226  uint8_t offset = 0;
1227 
1228  read_byte(info, &offset, (*address)++);
1229 
1230  add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_8,
1231  (uint16_t)offset, false);
1232 }
1233 
1234 static void indexedY_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1235 {
1236  uint8_t offset = 0;
1237 
1238  read_byte(info, &offset, (*address)++);
1239 
1240  add_indexed_operand(info, M680X_REG_Y, false, 0, M680X_OFFSET_BITS_8,
1241  (uint16_t)offset, false);
1242 }
1243 
1244 // M6809/M6309 indexed mode handler
1245 static void indexed09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1246 {
1247  cs_m680x *m680x = &info->m680x;
1248  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1249  uint8_t post_byte = 0;
1250  uint16_t offset = 0;
1251  int16_t soffset = 0;
1252 
1253  read_byte(info, &post_byte, (*address)++);
1254 
1255  op->type = M680X_OP_INDEXED;
1256  set_operand_size(info, op, 1);
1257  op->idx.base_reg = g_rr5_to_reg_ids[(post_byte >> 5) & 0x03];
1258  op->idx.offset_reg = M680X_REG_INVALID;
1259 
1260  if (!(post_byte & 0x80)) {
1261  // n5,R
1262  if ((post_byte & 0x10) == 0x10)
1263  op->idx.offset = post_byte | 0xfff0;
1264  else
1265  op->idx.offset = post_byte & 0x0f;
1266 
1267  op->idx.offset_addr = op->idx.offset + *address;
1268  op->idx.offset_bits = M680X_OFFSET_BITS_5;
1269  }
1270  else {
1271  if ((post_byte & 0x10) == 0x10)
1272  op->idx.flags |= M680X_IDX_INDIRECT;
1273 
1274  // indexed addressing
1275  switch (post_byte & 0x1f) {
1276  case 0x00: // ,R+
1277  op->idx.inc_dec = 1;
1279  break;
1280 
1281  case 0x11: // [,R++]
1282  case 0x01: // ,R++
1283  op->idx.inc_dec = 2;
1285  break;
1286 
1287  case 0x02: // ,-R
1288  op->idx.inc_dec = -1;
1289  break;
1290 
1291  case 0x13: // [,--R]
1292  case 0x03: // ,--R
1293  op->idx.inc_dec = -2;
1294  break;
1295 
1296  case 0x14: // [,R]
1297  case 0x04: // ,R
1298  break;
1299 
1300  case 0x15: // [B,R]
1301  case 0x05: // B,R
1302  op->idx.offset_reg = M680X_REG_B;
1303  break;
1304 
1305  case 0x16: // [A,R]
1306  case 0x06: // A,R
1307  op->idx.offset_reg = M680X_REG_A;
1308  break;
1309 
1310  case 0x1c: // [n8,PCR]
1311  case 0x0c: // n8,PCR
1312  op->idx.base_reg = M680X_REG_PC;
1313  read_byte_sign_extended(info, &soffset, (*address)++);
1314  op->idx.offset_addr = offset + *address;
1315  op->idx.offset = soffset;
1316  op->idx.offset_bits = M680X_OFFSET_BITS_8;
1317  break;
1318 
1319  case 0x18: // [n8,R]
1320  case 0x08: // n8,R
1321  read_byte_sign_extended(info, &soffset, (*address)++);
1322  op->idx.offset = soffset;
1323  op->idx.offset_bits = M680X_OFFSET_BITS_8;
1324  break;
1325 
1326  case 0x1d: // [n16,PCR]
1327  case 0x0d: // n16,PCR
1328  op->idx.base_reg = M680X_REG_PC;
1329  read_word(info, &offset, *address);
1330  *address += 2;
1331  op->idx.offset_addr = offset + *address;
1332  op->idx.offset = (int16_t)offset;
1333  op->idx.offset_bits = M680X_OFFSET_BITS_16;
1334  break;
1335 
1336  case 0x19: // [n16,R]
1337  case 0x09: // n16,R
1338  read_word(info, &offset, *address);
1339  *address += 2;
1340  op->idx.offset = (int16_t)offset;
1341  op->idx.offset_bits = M680X_OFFSET_BITS_16;
1342  break;
1343 
1344  case 0x1b: // [D,R]
1345  case 0x0b: // D,R
1346  op->idx.offset_reg = M680X_REG_D;
1347  break;
1348 
1349  case 0x1f: // [n16]
1350  op->type = M680X_OP_EXTENDED;
1351  op->ext.indirect = true;
1352  read_word(info, &op->ext.address, *address);
1353  *address += 2;
1354  break;
1355 
1356  default:
1357  op->idx.base_reg = M680X_REG_INVALID;
1358  break;
1359  }
1360  }
1361 
1362  if (((info->insn == M680X_INS_LEAU) ||
1363  (info->insn == M680X_INS_LEAS) ||
1364  (info->insn == M680X_INS_LEAX) ||
1365  (info->insn == M680X_INS_LEAY)) &&
1366  (m680x->operands[0].reg == M680X_REG_X ||
1367  (m680x->operands[0].reg == M680X_REG_Y)))
1368  // Only LEAX and LEAY modify CC register
1369  add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
1370 }
1371 
1372 
1373 m680x_reg g_idx12_to_reg_ids[4] = {
1375 };
1376 
1377 m680x_reg g_or12_to_reg_ids[3] = {
1379 };
1380 
1381 // CPU12 indexed mode handler
1382 static void indexed12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1383 {
1384  cs_m680x *m680x = &info->m680x;
1385  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1386  uint8_t post_byte = 0;
1387  uint8_t offset8 = 0;
1388 
1389  read_byte(info, &post_byte, (*address)++);
1390 
1391  op->type = M680X_OP_INDEXED;
1392  set_operand_size(info, op, 1);
1393  op->idx.offset_reg = M680X_REG_INVALID;
1394 
1395  if (!(post_byte & 0x20)) {
1396  // n5,R n5 is a 5-bit signed offset
1397  op->idx.base_reg = g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
1398 
1399  if ((post_byte & 0x10) == 0x10)
1400  op->idx.offset = post_byte | 0xfff0;
1401  else
1402  op->idx.offset = post_byte & 0x0f;
1403 
1404  op->idx.offset_addr = op->idx.offset + *address;
1405  op->idx.offset_bits = M680X_OFFSET_BITS_5;
1406  }
1407  else {
1408  if ((post_byte & 0xe0) == 0xe0)
1409  op->idx.base_reg =
1410  g_idx12_to_reg_ids[(post_byte >> 3) & 0x03];
1411 
1412  switch (post_byte & 0xe7) {
1413  case 0xe0:
1414  case 0xe1: // n9,R
1415  read_byte(info, &offset8, (*address)++);
1416  op->idx.offset = offset8;
1417 
1418  if (post_byte & 0x01) // sign extension
1419  op->idx.offset |= 0xff00;
1420 
1421  op->idx.offset_bits = M680X_OFFSET_BITS_9;
1422 
1423  if (op->idx.base_reg == M680X_REG_PC)
1424  op->idx.offset_addr = op->idx.offset + *address;
1425 
1426  break;
1427 
1428  case 0xe3: // [n16,R]
1429  op->idx.flags |= M680X_IDX_INDIRECT;
1430 
1431  // intentionally fall through
1432  case 0xe2: // n16,R
1433  read_word(info, (uint16_t *)&op->idx.offset, *address);
1434  (*address) += 2;
1435  op->idx.offset_bits = M680X_OFFSET_BITS_16;
1436 
1437  if (op->idx.base_reg == M680X_REG_PC)
1438  op->idx.offset_addr = op->idx.offset + *address;
1439 
1440  break;
1441 
1442  case 0xe4: // A,R
1443  case 0xe5: // B,R
1444  case 0xe6: // D,R
1445  op->idx.offset_reg =
1446  g_or12_to_reg_ids[post_byte & 0x03];
1447  break;
1448 
1449  case 0xe7: // [D,R]
1450  op->idx.offset_reg = M680X_REG_D;
1451  op->idx.flags |= M680X_IDX_INDIRECT;
1452  break;
1453 
1454  default: // n,-r n,+r n,r- n,r+
1455  // PC is not allowed in this mode
1456  op->idx.base_reg =
1457  g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
1458  op->idx.inc_dec = post_byte & 0x0f;
1459 
1460  if (op->idx.inc_dec & 0x08) // evtl. sign extend value
1461  op->idx.inc_dec |= 0xf0;
1462 
1463  if (op->idx.inc_dec >= 0)
1464  op->idx.inc_dec++;
1465 
1466  if (post_byte & 0x10)
1468 
1469  break;
1470 
1471  }
1472  }
1473 }
1474 
1475 static void index_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1476 {
1477  cs_m680x *m680x = &info->m680x;
1478  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1479 
1480  op->type = M680X_OP_CONSTANT;
1481  read_byte(info, &op->const_val, (*address)++);
1482 };
1483 
1484 static void direct_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1485 {
1486  cs_m680x *m680x = &info->m680x;
1487  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1488 
1489  op->type = M680X_OP_DIRECT;
1490  set_operand_size(info, op, 1);
1491  read_byte(info, &op->direct_addr, (*address)++);
1492 };
1493 
1494 static void extended_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1495 {
1496  cs_m680x *m680x = &info->m680x;
1497  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1498 
1499  op->type = M680X_OP_EXTENDED;
1500  set_operand_size(info, op, 1);
1501  read_word(info, &op->ext.address, *address);
1502  *address += 2;
1503 }
1504 
1505 static void immediate_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1506 {
1507  cs_m680x *m680x = &info->m680x;
1508  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1509  uint16_t word = 0;
1510  int16_t sword = 0;
1511 
1512  op->type = M680X_OP_IMMEDIATE;
1513  set_operand_size(info, op, 1);
1514 
1515  switch (op->size) {
1516  case 1:
1517  read_byte_sign_extended(info, &sword, *address);
1518  op->imm = sword;
1519  break;
1520 
1521  case 2:
1522  read_word(info, &word, *address);
1523  op->imm = (int16_t)word;
1524  break;
1525 
1526  case 4:
1527  read_sdword(info, &op->imm, *address);
1528  break;
1529 
1530  default:
1531  op->imm = 0;
1532  fprintf(stderr, "Internal error: Unexpected immediate byte "
1533  "size %d.\n", op->size);
1534  }
1535 
1536  *address += op->size;
1537 }
1538 
1539 // handler for bit move instructions, e.g: BAND A,5,1,$40 Used by HD6309
1540 static void bit_move_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1541 {
1542  static const m680x_reg m680x_reg[] = {
1544  };
1545 
1546  uint8_t post_byte = 0;
1547  cs_m680x *m680x = &info->m680x;
1548  cs_m680x_op *op;
1549 
1550  read_byte(info, &post_byte, *address);
1551  (*address)++;
1552 
1553  // operand[0] = register
1554  add_reg_operand(info, m680x_reg[post_byte >> 6]);
1555 
1556  // operand[1] = bit index in source operand
1557  op = &m680x->operands[m680x->op_count++];
1558  op->type = M680X_OP_CONSTANT;
1559  op->const_val = (post_byte >> 3) & 0x07;
1560 
1561  // operand[2] = bit index in destination operand
1562  op = &m680x->operands[m680x->op_count++];
1563  op->type = M680X_OP_CONSTANT;
1564  op->const_val = post_byte & 0x07;
1565 
1566  direct_hdlr(MI, info, address);
1567 }
1568 
1569 // handler for TFM instruction, e.g: TFM X+,Y+ Used by HD6309
1570 static void tfm_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1571 {
1572  static const uint8_t inc_dec_r0[] = {
1573  1, -1, 1, 0,
1574  };
1575  static const uint8_t inc_dec_r1[] = {
1576  1, -1, 0, 1,
1577  };
1578  uint8_t regs = 0;
1579  uint8_t index = (MI->Opcode & 0xff) - 0x38;
1580 
1581  read_byte(info, &regs, *address);
1582 
1583  add_indexed_operand(info, g_tfr_exg_reg_ids[regs >> 4], true,
1584  inc_dec_r0[index], M680X_OFFSET_NONE, 0, true);
1585  add_indexed_operand(info, g_tfr_exg_reg_ids[regs & 0x0f], true,
1586  inc_dec_r1[index], M680X_OFFSET_NONE, 0, true);
1587 
1588  add_reg_to_rw_list(MI, M680X_REG_W, READ | WRITE);
1589 }
1590 
1591 static void opidx_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1592 {
1593  cs_m680x *m680x = &info->m680x;
1594  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1595 
1596  // bit index is coded in Opcode
1597  op->type = M680X_OP_CONSTANT;
1598  op->const_val = (MI->Opcode & 0x0e) >> 1;
1599 }
1600 
1601 // handler for bit test and branch instruction. Used by M6805.
1602 // The bit index is part of the opcode.
1603 // Example: BRSET 3,<$40,LOOP
1604 static void opidx_dir_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1605 {
1606  cs_m680x *m680x = &info->m680x;
1607  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1608 
1609  // bit index is coded in Opcode
1610  op->type = M680X_OP_CONSTANT;
1611  op->const_val = (MI->Opcode & 0x0e) >> 1;
1612  direct_hdlr(MI, info, address);
1613  relative8_hdlr(MI, info, address);
1614 
1615  add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
1616 }
1617 
1618 static void indexedX0_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1619 {
1620  add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_NONE,
1621  0, false);
1622 }
1623 
1624 static void indexedX16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1625 {
1626  uint16_t offset = 0;
1627 
1628  read_word(info, &offset, *address);
1629  *address += 2;
1630  add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_16,
1631  offset, false);
1632 }
1633 
1634 static void imm_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1635 {
1636  immediate_hdlr(MI, info, address);
1637  relative8_hdlr(MI, info, address);
1638 }
1639 
1640 static void indexedS_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1641 {
1642  uint8_t offset = 0;
1643 
1644  read_byte(info, &offset, (*address)++);
1645 
1646  add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_8,
1647  (uint16_t)offset, false);
1648 }
1649 
1650 static void indexedS16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1651 {
1652  uint16_t offset = 0;
1653 
1654  read_word(info, &offset, *address);
1655  address += 2;
1656 
1657  add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_16,
1658  offset, false);
1659 }
1660 
1661 static void indexedX0p_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1662 {
1663  add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_NONE,
1664  0, true);
1665 }
1666 
1667 static void indexedXp_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1668 {
1669  uint8_t offset = 0;
1670 
1671  read_byte(info, &offset, (*address)++);
1672 
1673  add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_BITS_8,
1674  (uint16_t)offset, false);
1675 }
1676 
1677 static void imm_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1678 {
1679  cs_m680x *m680x = &info->m680x;
1680  cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1681 
1682  indexed12_hdlr(MI, info, address);
1683  op->type = M680X_OP_IMMEDIATE;
1684 
1685  if (info->insn == M680X_INS_MOVW) {
1686  uint16_t imm16 = 0;
1687 
1688  read_word(info, &imm16, *address);
1689  op->imm = (int16_t)imm16;
1690  op->size = 2;
1691  }
1692  else {
1693  uint8_t imm8 = 0;
1694 
1695  read_byte(info, &imm8, *address);
1696  op->imm = (int8_t)imm8;
1697  op->size = 1;
1698  }
1699 
1700  set_operand_size(info, op, 1);
1701 }
1702 
1703 static void ext_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1704 {
1705  cs_m680x *m680x = &info->m680x;
1706  cs_m680x_op *op0 = &m680x->operands[m680x->op_count++];
1707  uint16_t imm16 = 0;
1708 
1709  indexed12_hdlr(MI, info, address);
1710  read_word(info, &imm16, *address);
1711  op0->type = M680X_OP_EXTENDED;
1712  op0->ext.address = (int16_t)imm16;
1713  set_operand_size(info, op0, 1);
1714 }
1715 
1716 // handler for CPU12 DBEQ/DNBE/IBEQ/IBNE/TBEQ/TBNE instructions.
1717 // Example: DBNE X,$1000
1718 static void loop_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1719 {
1720  static const m680x_reg index_to_reg_id[] = {
1723  };
1724  static const m680x_insn index_to_insn_id[] = {
1727  };
1728  cs_m680x *m680x = &info->m680x;
1729  uint8_t post_byte = 0;
1730  uint8_t rel = 0;
1731  cs_m680x_op *op;
1732 
1733  read_byte(info, &post_byte, (*address)++);
1734 
1735  info->insn = index_to_insn_id[(post_byte >> 5) & 0x07];
1736 
1737  if (info->insn == M680X_INS_ILLGL) {
1738  fprintf(stderr, "Internal error: Unexpected post byte "
1739  "in loop instruction %02X.\n", post_byte);
1740  illegal_hdlr(MI, info, address);
1741  };
1742 
1743  read_byte(info, &rel, (*address)++);
1744 
1745  add_reg_operand(info, index_to_reg_id[post_byte & 0x07]);
1746 
1747  op = &m680x->operands[m680x->op_count++];
1748 
1749  op->type = M680X_OP_RELATIVE;
1750 
1751  op->rel.offset = (post_byte & 0x10) ? 0xff00 | rel : rel;
1752 
1753  op->rel.address = *address + op->rel.offset;
1754 
1755  add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
1756 }
1757 
1758 static void (*const g_insn_handler[])(MCInst *, m680x_info *, uint16_t *) = {
1759  illegal_hdlr,
1760  relative8_hdlr,
1761  relative16_hdlr,
1762  immediate_hdlr, // 8-bit
1763  immediate_hdlr, // 16-bit
1764  immediate_hdlr, // 32-bit
1765  direct_hdlr,
1766  extended_hdlr,
1767  indexedX_hdlr,
1768  indexedY_hdlr,
1769  indexed09_hdlr,
1770  inherent_hdlr,
1771  reg_reg09_hdlr,
1772  reg_bits_hdlr,
1773  bit_move_hdlr,
1774  tfm_hdlr,
1775  opidx_hdlr,
1776  opidx_dir_rel_hdlr,
1777  indexedX0_hdlr,
1778  indexedX16_hdlr,
1779  imm_rel_hdlr,
1780  indexedS_hdlr,
1781  indexedS16_hdlr,
1782  indexedXp_hdlr,
1783  indexedX0p_hdlr,
1784  indexed12_hdlr,
1785  indexed12_hdlr, // subset of indexed12
1786  reg_reg12_hdlr,
1787  loop_hdlr,
1788  index_hdlr,
1789  imm_idx12_x_hdlr,
1790  imm_idx12_x_hdlr,
1791  ext_idx12_x_hdlr,
1792 }; /* handler function pointers */
1793 
1794 /* Disasemble one instruction at address and store in str_buff */
1795 static unsigned int m680x_disassemble(MCInst *MI, m680x_info *info,
1796  uint16_t address)
1797 {
1798  cs_m680x *m680x = &info->m680x;
1799  cs_detail *detail = MI->flat_insn->detail;
1800  uint16_t base_address = address;
1801  insn_desc insn_description;
1802  e_access_mode access_mode;
1803 
1804  if (detail != NULL) {
1805  memset(detail, 0, offsetof(cs_detail, m680x)+sizeof(cs_m680x));
1806  }
1807 
1808  memset(&insn_description, 0, sizeof(insn_description));
1809  memset(m680x, 0, sizeof(*m680x));
1810  info->insn_size = 1;
1811 
1812  if (decode_insn(info, address, &insn_description)) {
1813  m680x_reg reg;
1814 
1815  if (insn_description.opcode > 0xff)
1816  address += 2; // 8-bit opcode + page prefix
1817  else
1818  address++; // 8-bit opcode only
1819 
1820  info->insn = insn_description.insn;
1821 
1822  MCInst_setOpcode(MI, insn_description.opcode);
1823 
1824  reg = g_insn_props[info->insn].reg0;
1825 
1826  if (reg != M680X_REG_INVALID) {
1827  if (reg == M680X_REG_HX &&
1828  (!info->cpu->reg_byte_size[reg]))
1829  reg = M680X_REG_X;
1830 
1831  add_reg_operand(info, reg);
1832  // First (or second) operand is a register which is
1833  // part of the mnemonic
1834  m680x->flags |= M680X_FIRST_OP_IN_MNEM;
1835  reg = g_insn_props[info->insn].reg1;
1836 
1837  if (reg != M680X_REG_INVALID) {
1838  if (reg == M680X_REG_HX &&
1839  (!info->cpu->reg_byte_size[reg]))
1840  reg = M680X_REG_X;
1841 
1842  add_reg_operand(info, reg);
1843  m680x->flags |= M680X_SECOND_OP_IN_MNEM;
1844  }
1845  }
1846 
1847  // Call addressing mode specific instruction handler
1848  (g_insn_handler[insn_description.hid[0]])(MI, info,
1849  &address);
1850  (g_insn_handler[insn_description.hid[1]])(MI, info,
1851  &address);
1852 
1853  add_insn_group(detail, g_insn_props[info->insn].group);
1854 
1855  if (g_insn_props[info->insn].cc_modified &&
1856  (info->cpu->insn_cc_not_modified[0] != info->insn) &&
1857  (info->cpu->insn_cc_not_modified[1] != info->insn))
1858  add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
1859 
1860  access_mode = g_insn_props[info->insn].access_mode;
1861 
1862  // Fix for M6805 BSET/BCLR. It has a differnt operand order
1863  // in comparison to the M6811
1864  if ((info->cpu->insn_cc_not_modified[0] == info->insn) ||
1865  (info->cpu->insn_cc_not_modified[1] == info->insn))
1866  access_mode = rmmm;
1867 
1868  build_regs_read_write_counts(MI, info, access_mode);
1869  add_operators_access(MI, info, access_mode);
1870 
1871  if (g_insn_props[info->insn].update_reg_access)
1872  set_changed_regs_read_write_counts(MI, info);
1873 
1874  info->insn_size = insn_description.insn_size;
1875 
1876  return info->insn_size;
1877  }
1878  else
1879  MCInst_setOpcode(MI, insn_description.opcode);
1880 
1881  // Illegal instruction
1882  address = base_address;
1883  illegal_hdlr(MI, info, &address);
1884  return 1;
1885 }
1886 
1887 // Tables to get the byte size of a register on the CPU
1888 // based on an enum m680x_reg value.
1889 // Invalid registers return 0.
1890 static const uint8_t g_m6800_reg_byte_size[22] = {
1891  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1892  0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
1893 };
1894 
1895 static const uint8_t g_m6805_reg_byte_size[22] = {
1896  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1897  0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0
1898 };
1899 
1900 static const uint8_t g_m6808_reg_byte_size[22] = {
1901  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1902  0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 0, 0
1903 };
1904 
1905 static const uint8_t g_m6801_reg_byte_size[22] = {
1906  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1907  0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
1908 };
1909 
1910 static const uint8_t g_m6811_reg_byte_size[22] = {
1911  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1912  0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0
1913 };
1914 
1915 static const uint8_t g_cpu12_reg_byte_size[22] = {
1916  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1917  0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2
1918 };
1919 
1920 static const uint8_t g_m6809_reg_byte_size[22] = {
1921  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1922  0, 1, 1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0
1923 };
1924 
1925 static const uint8_t g_hd6309_reg_byte_size[22] = {
1926  // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1927  0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 4, 2, 0, 0
1928 };
1929 
1930 // Table to check for a valid register nibble on the M6809 CPU
1931 // used for TFR and EXG instruction.
1932 static const bool m6809_tfr_reg_valid[16] = {
1933  true, true, true, true, true, true, false, false,
1934  true, true, true, true, false, false, false, false,
1935 };
1936 
1937 static const cpu_tables g_cpu_tables[] = {
1938  {
1939  // M680X_CPU_TYPE_INVALID
1940  NULL,
1941  { NULL, NULL },
1942  { 0, 0 },
1943  { 0x00, 0x00, 0x00 },
1944  { NULL, NULL, NULL },
1945  { 0, 0, 0 },
1946  NULL,
1947  NULL,
1949  },
1950  {
1951  // M680X_CPU_TYPE_6301
1952  &g_m6800_inst_page1_table[0],
1953  { &g_m6801_inst_overlay_table[0], &g_hd6301_inst_overlay_table[0] },
1954  {
1955  ARR_SIZE(g_m6801_inst_overlay_table),
1956  ARR_SIZE(g_hd6301_inst_overlay_table)
1957  },
1958  { 0x00, 0x00, 0x00 },
1959  { NULL, NULL, NULL },
1960  { 0, 0, 0 },
1961  &g_m6801_reg_byte_size[0],
1962  NULL,
1964  },
1965  {
1966  // M680X_CPU_TYPE_6309
1967  &g_m6809_inst_page1_table[0],
1968  { &g_hd6309_inst_overlay_table[0], NULL },
1969  { ARR_SIZE(g_hd6309_inst_overlay_table), 0 },
1970  { 0x10, 0x11, 0x00 },
1971  { &g_hd6309_inst_page2_table[0], &g_hd6309_inst_page3_table[0], NULL },
1972  {
1973  ARR_SIZE(g_hd6309_inst_page2_table),
1974  ARR_SIZE(g_hd6309_inst_page3_table),
1975  0
1976  },
1977  &g_hd6309_reg_byte_size[0],
1978  NULL,
1980  },
1981  {
1982  // M680X_CPU_TYPE_6800
1983  &g_m6800_inst_page1_table[0],
1984  { NULL, NULL },
1985  { 0, 0 },
1986  { 0x00, 0x00, 0x00 },
1987  { NULL, NULL, NULL },
1988  { 0, 0, 0 },
1989  &g_m6800_reg_byte_size[0],
1990  NULL,
1992  },
1993  {
1994  // M680X_CPU_TYPE_6801
1995  &g_m6800_inst_page1_table[0],
1996  { &g_m6801_inst_overlay_table[0], NULL },
1997  { ARR_SIZE(g_m6801_inst_overlay_table), 0 },
1998  { 0x00, 0x00, 0x00 },
1999  { NULL, NULL, NULL },
2000  { 0, 0, 0 },
2001  &g_m6801_reg_byte_size[0],
2002  NULL,
2004  },
2005  {
2006  // M680X_CPU_TYPE_6805
2007  &g_m6805_inst_page1_table[0],
2008  { NULL, NULL },
2009  { 0, 0 },
2010  { 0x00, 0x00, 0x00 },
2011  { NULL, NULL, NULL },
2012  { 0, 0, 0 },
2013  &g_m6805_reg_byte_size[0],
2014  NULL,
2016  },
2017  {
2018  // M680X_CPU_TYPE_6808
2019  &g_m6805_inst_page1_table[0],
2020  { &g_m6808_inst_overlay_table[0], NULL },
2021  { ARR_SIZE(g_m6808_inst_overlay_table), 0 },
2022  { 0x9E, 0x00, 0x00 },
2023  { &g_m6808_inst_page2_table[0], NULL, NULL },
2024  { ARR_SIZE(g_m6808_inst_page2_table), 0, 0 },
2025  &g_m6808_reg_byte_size[0],
2026  NULL,
2028  },
2029  {
2030  // M680X_CPU_TYPE_6809
2031  &g_m6809_inst_page1_table[0],
2032  { NULL, NULL },
2033  { 0, 0 },
2034  { 0x10, 0x11, 0x00 },
2035  {
2036  &g_m6809_inst_page2_table[0],
2037  &g_m6809_inst_page3_table[0],
2038  NULL
2039  },
2040  {
2041  ARR_SIZE(g_m6809_inst_page2_table),
2042  ARR_SIZE(g_m6809_inst_page3_table),
2043  0
2044  },
2045  &g_m6809_reg_byte_size[0],
2046  &m6809_tfr_reg_valid[0],
2048  },
2049  {
2050  // M680X_CPU_TYPE_6811
2051  &g_m6800_inst_page1_table[0],
2052  {
2053  &g_m6801_inst_overlay_table[0],
2054  &g_m6811_inst_overlay_table[0]
2055  },
2056  {
2057  ARR_SIZE(g_m6801_inst_overlay_table),
2058  ARR_SIZE(g_m6811_inst_overlay_table)
2059  },
2060  { 0x18, 0x1A, 0xCD },
2061  {
2062  &g_m6811_inst_page2_table[0],
2063  &g_m6811_inst_page3_table[0],
2064  &g_m6811_inst_page4_table[0]
2065  },
2066  {
2067  ARR_SIZE(g_m6811_inst_page2_table),
2068  ARR_SIZE(g_m6811_inst_page3_table),
2069  ARR_SIZE(g_m6811_inst_page4_table)
2070  },
2071  &g_m6811_reg_byte_size[0],
2072  NULL,
2074  },
2075  {
2076  // M680X_CPU_TYPE_CPU12
2077  &g_cpu12_inst_page1_table[0],
2078  { NULL, NULL },
2079  { 0, 0 },
2080  { 0x18, 0x00, 0x00 },
2081  { &g_cpu12_inst_page2_table[0], NULL, NULL },
2082  { ARR_SIZE(g_cpu12_inst_page2_table), 0, 0 },
2083  &g_cpu12_reg_byte_size[0],
2084  NULL,
2086  },
2087  {
2088  // M680X_CPU_TYPE_HCS08
2089  &g_m6805_inst_page1_table[0],
2090  {
2091  &g_m6808_inst_overlay_table[0],
2092  &g_hcs08_inst_overlay_table[0]
2093  },
2094  {
2095  ARR_SIZE(g_m6808_inst_overlay_table),
2096  ARR_SIZE(g_hcs08_inst_overlay_table)
2097  },
2098  { 0x9E, 0x00, 0x00 },
2099  { &g_hcs08_inst_page2_table[0], NULL, NULL },
2100  { ARR_SIZE(g_hcs08_inst_page2_table), 0, 0 },
2101  &g_m6808_reg_byte_size[0],
2102  NULL,
2104  },
2105 };
2106 
2107 static const char *s_cpu_type[] = {
2108  "INVALID", "6301", "6309", "6800", "6801", "6805", "6808",
2109  "6809", "6811", "CPU12", "HCS08",
2110 };
2111 
2112 static bool m680x_setup_internals(m680x_info *info, e_cpu_type cpu_type,
2113  uint16_t address,
2114  const uint8_t *code, uint16_t code_len)
2115 {
2116  if (cpu_type == M680X_CPU_TYPE_INVALID) {
2117  fprintf(stderr, "M680X_CPU_TYPE_%s is not suppported\n",
2118  s_cpu_type[cpu_type]);
2119  return false;
2120  }
2121 
2122  info->code = code;
2123  info->size = code_len;
2124  info->offset = address;
2125  info->cpu_type = cpu_type;
2126 
2127  info->cpu = &g_cpu_tables[info->cpu_type];
2128 
2129  return true;
2130 }
2131 
2132 bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
2133  MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
2134 {
2135  unsigned int insn_size = 0;
2136  e_cpu_type cpu_type = M680X_CPU_TYPE_INVALID; // No default CPU type
2137  cs_struct *handle = (cs_struct *)ud;
2138  m680x_info *info = (m680x_info *)handle->printer_info;
2139 
2140  MCInst_clear(MI);
2141 
2142  if (handle->mode & CS_MODE_M680X_6800)
2143  cpu_type = M680X_CPU_TYPE_6800;
2144 
2145  else if (handle->mode & CS_MODE_M680X_6801)
2146  cpu_type = M680X_CPU_TYPE_6801;
2147 
2148  else if (handle->mode & CS_MODE_M680X_6805)
2149  cpu_type = M680X_CPU_TYPE_6805;
2150 
2151  else if (handle->mode & CS_MODE_M680X_6808)
2152  cpu_type = M680X_CPU_TYPE_6808;
2153 
2154  else if (handle->mode & CS_MODE_M680X_HCS08)
2155  cpu_type = M680X_CPU_TYPE_HCS08;
2156 
2157  else if (handle->mode & CS_MODE_M680X_6809)
2158  cpu_type = M680X_CPU_TYPE_6809;
2159 
2160  else if (handle->mode & CS_MODE_M680X_6301)
2161  cpu_type = M680X_CPU_TYPE_6301;
2162 
2163  else if (handle->mode & CS_MODE_M680X_6309)
2164  cpu_type = M680X_CPU_TYPE_6309;
2165 
2166  else if (handle->mode & CS_MODE_M680X_6811)
2167  cpu_type = M680X_CPU_TYPE_6811;
2168 
2169  else if (handle->mode & CS_MODE_M680X_CPU12)
2170  cpu_type = M680X_CPU_TYPE_CPU12;
2171 
2172  if (cpu_type != M680X_CPU_TYPE_INVALID &&
2173  m680x_setup_internals(info, cpu_type, (uint16_t)address, code,
2174  code_len))
2175  insn_size = m680x_disassemble(MI, info, (uint16_t)address);
2176 
2177  if (insn_size == 0) {
2178  *size = 1;
2179  return false;
2180  }
2181 
2182  // Make sure we always stay within range
2183  if (insn_size > code_len) {
2184  *size = (uint16_t)code_len;
2185  return false;
2186  }
2187  else
2188  *size = (uint16_t)insn_size;
2189 
2190  return true;
2191 }
2192 
2194 {
2195  if (M680X_REG_ENDING != ARR_SIZE(g_m6800_reg_byte_size)) {
2196  fprintf(stderr, "Internal error: Size mismatch in enum "
2197  "m680x_reg and g_m6800_reg_byte_size\n");
2198 
2199  return CS_ERR_MODE;
2200  }
2201 
2202  if (M680X_REG_ENDING != ARR_SIZE(g_m6801_reg_byte_size)) {
2203  fprintf(stderr, "Internal error: Size mismatch in enum "
2204  "m680x_reg and g_m6801_reg_byte_size\n");
2205 
2206  return CS_ERR_MODE;
2207  }
2208 
2209  if (M680X_REG_ENDING != ARR_SIZE(g_m6805_reg_byte_size)) {
2210  fprintf(stderr, "Internal error: Size mismatch in enum "
2211  "m680x_reg and g_m6805_reg_byte_size\n");
2212 
2213  return CS_ERR_MODE;
2214  }
2215 
2216  if (M680X_REG_ENDING != ARR_SIZE(g_m6808_reg_byte_size)) {
2217  fprintf(stderr, "Internal error: Size mismatch in enum "
2218  "m680x_reg and g_m6808_reg_byte_size\n");
2219 
2220  return CS_ERR_MODE;
2221  }
2222 
2223  if (M680X_REG_ENDING != ARR_SIZE(g_m6811_reg_byte_size)) {
2224  fprintf(stderr, "Internal error: Size mismatch in enum "
2225  "m680x_reg and g_m6811_reg_byte_size\n");
2226 
2227  return CS_ERR_MODE;
2228  }
2229 
2230  if (M680X_REG_ENDING != ARR_SIZE(g_cpu12_reg_byte_size)) {
2231  fprintf(stderr, "Internal error: Size mismatch in enum "
2232  "m680x_reg and g_cpu12_reg_byte_size\n");
2233 
2234  return CS_ERR_MODE;
2235  }
2236 
2237  if (M680X_REG_ENDING != ARR_SIZE(g_m6809_reg_byte_size)) {
2238  fprintf(stderr, "Internal error: Size mismatch in enum "
2239  "m680x_reg and g_m6809_reg_byte_size\n");
2240 
2241  return CS_ERR_MODE;
2242  }
2243 
2244  if (M680X_INS_ENDING != ARR_SIZE(g_insn_props)) {
2245  fprintf(stderr, "Internal error: Size mismatch in enum "
2246  "m680x_insn and g_insn_props\n");
2247 
2248  return CS_ERR_MODE;
2249  }
2250 
2251  if (M680X_CPU_TYPE_ENDING != ARR_SIZE(s_cpu_type)) {
2252  fprintf(stderr, "Internal error: Size mismatch in enum "
2253  "e_cpu_type and s_cpu_type\n");
2254 
2255  return CS_ERR_MODE;
2256  }
2257 
2258  if (M680X_CPU_TYPE_ENDING != ARR_SIZE(g_cpu_tables)) {
2259  fprintf(stderr, "Internal error: Size mismatch in enum "
2260  "e_cpu_type and g_cpu_tables\n");
2261 
2262  return CS_ERR_MODE;
2263  }
2264 
2265  if (HANDLER_ID_ENDING != ARR_SIZE(g_insn_handler)) {
2266  fprintf(stderr, "Internal error: Size mismatch in enum "
2267  "insn_hdlr_id and g_insn_handler\n");
2268 
2269  return CS_ERR_MODE;
2270  }
2271 
2272  if (ACCESS_MODE_ENDING != MATRIX_SIZE(g_access_mode_to_access)) {
2273  fprintf(stderr, "Internal error: Size mismatch in enum "
2274  "e_access_mode and g_access_mode_to_access\n");
2275 
2276  return CS_ERR_MODE;
2277  }
2278 
2279  return CS_ERR_OK;
2280 }
2281 
2282 #ifndef CAPSTONE_DIET
2283 void M680X_reg_access(const cs_insn *insn,
2284  cs_regs regs_read, uint8_t *regs_read_count,
2285  cs_regs regs_write, uint8_t *regs_write_count)
2286 {
2287  if (insn->detail == NULL) {
2288  *regs_read_count = 0;
2289  *regs_write_count = 0;
2290  }
2291  else {
2292  *regs_read_count = insn->detail->regs_read_count;
2293  *regs_write_count = insn->detail->regs_write_count;
2294 
2295  memcpy(regs_read, insn->detail->regs_read,
2296  *regs_read_count * sizeof(insn->detail->regs_read[0]));
2297  memcpy(regs_write, insn->detail->regs_write,
2298  *regs_write_count *
2299  sizeof(insn->detail->regs_write[0]));
2300  }
2301 }
2302 #endif
2303 
2304 #endif
2305 
M680X_INS_MEM
@ M680X_INS_MEM
Definition: m680x.h:396
M680X_INS_SEXW
@ M680X_INS_SEXW
Definition: m680x.h:469
M680X_CPU_TYPE_6811
@ M680X_CPU_TYPE_6811
Definition: M680XDisassemblerInternals.h:19
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
M680X_INS_PSHC
@ M680X_INS_PSHC
Definition: m680x.h:421
M680X_INS_BCLR
@ M680X_INS_BCLR
Definition: m680x.h:210
M680X_REG_S
@ M680X_REG_S
M6809/M6309.
Definition: m680x.h:40
grpc_op::flags
uint32_t flags
Definition: grpc_types.h:644
M680X_INS_PULB
@ M680X_INS_PULB
M6800/1/2/3.
Definition: m680x.h:431
cpu_tables::insn_cc_not_modified
m680x_insn insn_cc_not_modified[2]
Definition: M680XDisassemblerInternals.h:38
M680X_INS_SEX
@ M680X_INS_SEX
Definition: m680x.h:468
M680X_INS_MULD
@ M680X_INS_MULD
Definition: m680x.h:403
build_regs_read_write_counts
static void build_regs_read_write_counts(m68k_info *info)
Definition: M68KDisassembler.c:3955
M680X_INS_DBNE
@ M680X_INS_DBNE
Definition: m680x.h:292
M680X_INS_EMULS
@ M680X_INS_EMULS
Definition: m680x.h:319
M680X_REG_E
@ M680X_REG_E
HD6309.
Definition: m680x.h:25
M680X_INS_CWAI
@ M680X_INS_CWAI
Definition: m680x.h:289
M680X_INS_TFR
@ M680X_INS_TFR
Definition: m680x.h:508
M680X_INS_PULC
@ M680X_INS_PULC
Definition: m680x.h:432
M680X_OFFSET_BITS_8
#define M680X_OFFSET_BITS_8
Definition: m680x.h:70
absl::str_format_internal::LengthMod::j
@ j
CS_MODE_M680X_6800
@ CS_MODE_M680X_6800
M680X Motorola 6800,6802 mode.
Definition: capstone.h:129
M680XDisassemblerInternals.h
M680X_INS_RTI
@ M680X_INS_RTI
Definition: m680x.h:457
M680X_INS_PSHX
@ M680X_INS_PSHX
M6800/1/2/3.
Definition: m680x.h:428
M680X_OP_CONSTANT
@ M680X_OP_CONSTANT
Used e.g. for a bit index or page number.
Definition: m680x.h:63
m680x_info::cpu_type
e_cpu_type cpu_type
Definition: M680XDisassemblerInternals.h:46
add_reg_to_rw_list
static void add_reg_to_rw_list(m68k_info *info, m68k_reg reg, int write)
Definition: M68KDisassembler.c:3855
memset
return memset(p, 0, total)
cpu_tables::inst_page1_table
const struct inst_page1 * inst_page1_table
Definition: M680XDisassemblerInternals.h:30
M680X_INS_TBL
@ M680X_INS_TBL
Definition: m680x.h:504
MCInst::Opcode
unsigned Opcode
Definition: MCInst.h:93
M680X_OP_EXTENDED
@ M680X_OP_EXTENDED
= Extended addressing operand.
Definition: m680x.h:60
M680X_INS_AIS
@ M680X_INS_AIS
Definition: m680x.h:191
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
M680X_OP_DIRECT
@ M680X_OP_DIRECT
= Direct addressing operand.
Definition: m680x.h:61
cpu_tables::tfr_reg_valid
const bool * tfr_reg_valid
Definition: M680XDisassemblerInternals.h:37
M680X_OP_IMMEDIATE
@ M680X_OP_IMMEDIATE
= Immediate operand.
Definition: m680x.h:58
M680X_OFFSET_BITS_9
#define M680X_OFFSET_BITS_9
Definition: m680x.h:71
CS_MODE_M680X_6805
@ CS_MODE_M680X_6805
M680X Motorola/Freescale 6805 mode.
Definition: capstone.h:131
M680X_REG_A
@ M680X_REG_A
M6800/1/2/3/9, HD6301/9.
Definition: m680x.h:23
cpu_tables::pageX_prefix
uint8_t pageX_prefix[3]
Definition: M680XDisassemblerInternals.h:33
M680X_INS_PULX
@ M680X_INS_PULX
M6800/1/2/3.
Definition: m680x.h:439
M680X_INS_EMINM
@ M680X_INS_EMINM
Definition: m680x.h:317
CS_MODE_M680X_CPU12
@ CS_MODE_M680X_CPU12
used on M68HC12/HCS12
Definition: capstone.h:135
string.h
cs_m680x_op::access
uint8_t access
Definition: m680x.h:129
M680X_INS_IBEQ
@ M680X_INS_IBEQ
Definition: m680x.h:328
M680X_get_insn_id
void M680X_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
M680X_INS_MAXM
@ M680X_INS_MAXM
Definition: m680x.h:395
M680X_INS_IBNE
@ M680X_INS_IBNE
Definition: m680x.h:329
CS_MODE_M680X_6801
@ CS_MODE_M680X_6801
M680X Motorola 6801,6803 mode.
Definition: capstone.h:130
m680x_reg
m680x_reg
M680X registers and special registers.
Definition: m680x.h:20
M680X_CPU_TYPE_6809
@ M680X_CPU_TYPE_6809
Definition: M680XDisassemblerInternals.h:18
M680X_INS_JMP
@ M680X_INS_JMP
Definition: m680x.h:344
cpu_tables::overlay_table_size
size_t overlay_table_size[2]
Definition: M680XDisassemblerInternals.h:32
M680X_GRP_JUMP
@ M680X_GRP_JUMP
= CS_GRP_INVALID
Definition: m680x.h:137
M680X_REG_HX
@ M680X_REG_HX
M6808.
Definition: m680x.h:36
m680x_insn
m680x_insn
M680X instruction IDs.
Definition: m680x.h:172
M680X_INS_PSHB
@ M680X_INS_PSHB
M6800/1/2/3.
Definition: m680x.h:420
M680X_INS_PSHD
@ M680X_INS_PSHD
Definition: m680x.h:422
m680x_info::code
const uint8_t * code
Definition: M680XDisassemblerInternals.h:43
M680X_reg_access
void M680X_reg_access(const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count)
M680X_FIRST_OP_IN_MNEM
#define M680X_FIRST_OP_IN_MNEM
Definition: m680x.h:159
detail
Definition: test_winkernel.cpp:39
M680X_INS_EDIV
@ M680X_INS_EDIV
Definition: m680x.h:310
M680X_CPU_TYPE_ENDING
@ M680X_CPU_TYPE_ENDING
Definition: M680XDisassemblerInternals.h:23
M680X_INS_DIVQ
@ M680X_INS_DIVQ
Definition: m680x.h:309
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
M680X_CPU_TYPE_CPU12
@ M680X_CPU_TYPE_CPU12
Definition: M680XDisassemblerInternals.h:20
M680X_INS_DBEQ
@ M680X_INS_DBEQ
Definition: m680x.h:291
cs_m680x::op_count
uint8_t op_count
number of operands for the instruction or 0
Definition: m680x.h:167
CS_AC_READ
@ CS_AC_READ
Operand read from memory or register.
Definition: capstone.h:205
cs_m680x_op::size
uint8_t size
Definition: m680x.h:125
MCInst_clear
void MCInst_clear(MCInst *inst)
Definition: MCInst.c:37
grpc_status._async.code
code
Definition: grpcio_status/grpc_status/_async.py:34
e_cpu_type
e_cpu_type
Definition: M680XDisassemblerInternals.h:10
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
m680x_info::insn_size
uint8_t insn_size
Definition: M680XDisassemblerInternals.h:50
m680x_info
Definition: M680XDisassemblerInternals.h:42
M680X_GRP_BRAREL
@ M680X_GRP_BRAREL
= CS_GRP_BRANCH_RELATIVE
Definition: m680x.h:149
M680X_REG_W
@ M680X_REG_W
HD6309.
Definition: m680x.h:30
CS_MODE_M680X_6808
@ CS_MODE_M680X_6808
M680X Motorola/Freescale/NXP 68HC08 mode.
Definition: capstone.h:132
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
M680X_INS_EMACS
@ M680X_INS_EMACS
Definition: m680x.h:313
M680X_GRP_INVALID
@ M680X_GRP_INVALID
Definition: m680x.h:134
cs_struct
Definition: cs_priv.h:51
M680X_INS_RTC
@ M680X_INS_RTC
Definition: m680x.h:456
M680X_CPU_TYPE_INVALID
@ M680X_CPU_TYPE_INVALID
Definition: M680XDisassemblerInternals.h:11
M680X_INS_AIX
@ M680X_INS_AIX
Definition: m680x.h:192
M680X_INS_LEAS
@ M680X_INS_LEAS
Definition: m680x.h:379
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
M680X_INS_WAVR
@ M680X_INS_WAVR
Definition: m680x.h:527
M680X_IDX_POST_INC_DEC
#define M680X_IDX_POST_INC_DEC
Definition: m680x.h:78
M680X_INS_BSR
@ M680X_INS_BSR
Definition: m680x.h:244
M680X_REG_DP
@ M680X_REG_DP
M6809/M6309.
Definition: m680x.h:33
capstone.CS_ERR_OK
CS_ERR_OK
Definition: third_party/bloaty/third_party/capstone/bindings/python/capstone/__init__.py:237
int16_t
signed short int16_t
Definition: stdint-msvc2008.h:76
M680X_REG_D
@ M680X_REG_D
M6801/3/9, HD6301/9.
Definition: m680x.h:29
cs_m680x_op::imm
int32_t imm
immediate value for IMM operand
Definition: m680x.h:117
M680X_INS_DIVD
@ M680X_INS_DIVD
Definition: m680x.h:308
M680X_OFFSET_NONE
#define M680X_OFFSET_NONE
Definition: m680x.h:68
M680X_INS_PSHA
@ M680X_INS_PSHA
M6800/1/2/3.
Definition: m680x.h:419
M680X_INS_TBEQ
@ M680X_INS_TBEQ
Definition: m680x.h:503
update_am_reg_list
static void update_am_reg_list(m68k_info *info, cs_m68k_op *op, int write)
Definition: M68KDisassembler.c:3878
M680X_INS_ENDING
@ M680X_INS_ENDING
Definition: m680x.h:530
M680X_CPU_TYPE_6808
@ M680X_CPU_TYPE_6808
Definition: M680XDisassemblerInternals.h:17
M680X_INS_BRA
@ M680X_INS_BRA
Definition: m680x.h:241
M680X_INS_CALL
@ M680X_INS_CALL
Definition: m680x.h:247
WRITE
#define WRITE(byte)
M680X_INS_MOVW
@ M680X_INS_MOVW
Definition: m680x.h:401
MATRIX_SIZE
#define MATRIX_SIZE(a)
Definition: utils.h:55
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
M680X_INS_WAV
@ M680X_INS_WAV
Definition: m680x.h:526
M680X_OFFSET_BITS_5
#define M680X_OFFSET_BITS_5
Definition: m680x.h:69
M680X_CPU_TYPE_6805
@ M680X_CPU_TYPE_6805
Definition: M680XDisassemblerInternals.h:16
M680X_INS_LEAU
@ M680X_INS_LEAU
Definition: m680x.h:380
M680X_REG_PC
@ M680X_REG_PC
M6800/1/2/3/9, M6301/9.
Definition: m680x.h:46
M680X_INS_EXG
@ M680X_INS_EXG
Definition: m680x.h:326
M680X_CPU_TYPE_6801
@ M680X_CPU_TYPE_6801
Definition: M680XDisassemblerInternals.h:15
M680X_REG_X
@ M680X_REG_X
M6800/1/2/3/9, M6301/9.
Definition: m680x.h:38
M680X_REG_U
@ M680X_REG_U
M6809/M6309.
Definition: m680x.h:41
M680X_REG_0
@ M680X_REG_0
HD6309.
Definition: m680x.h:27
cs_m680x::flags
uint8_t flags
See: M680X instruction flags.
Definition: m680x.h:166
cs_m680x
The M680X instruction and it's operands.
Definition: m680x.h:165
M680X_INS_PULD
@ M680X_INS_PULD
Definition: m680x.h:433
CS_MODE_M680X_6809
@ CS_MODE_M680X_6809
M680X Motorola 6809 mode.
Definition: capstone.h:133
M680X_REG_V
@ M680X_REG_V
M6309.
Definition: m680x.h:42
M680XDisassembler.h
cs_m680x_op::reg
m680x_reg reg
register value for REG operand
Definition: m680x.h:118
setup.idx
idx
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:197
M680X_IDX_INDIRECT
#define M680X_IDX_INDIRECT
Definition: m680x.h:76
M680X_INS_LEAY
@ M680X_INS_LEAY
Definition: m680x.h:382
M680X_INS_LBRA
@ M680X_INS_LBRA
Definition: m680x.h:358
CS_AC_INVALID
@ CS_AC_INVALID
Uninitialized/invalid access type.
Definition: capstone.h:204
CS_MODE_M680X_6309
@ CS_MODE_M680X_6309
M680X Hitachi 6309 mode.
Definition: capstone.h:128
M680X_INS_INVLD
@ M680X_INS_INVLD
Definition: m680x.h:173
m680x_info::insn
m680x_insn insn
Definition: M680XDisassemblerInternals.h:49
m680x_info::cpu
const cpu_tables * cpu
Definition: M680XDisassemblerInternals.h:48
M680X_IDX_NO_COMMA
#define M680X_IDX_NO_COMMA
Definition: m680x.h:77
cpu_tables::reg_byte_size
const uint8_t * reg_byte_size
Definition: M680XDisassemblerInternals.h:36
cs_m680x::operands
cs_m680x_op operands[M680X_OPERAND_COUNT]
operands for this insn.
Definition: m680x.h:168
M680X_INS_DAA
@ M680X_INS_DAA
Definition: m680x.h:290
CS_MODE_M680X_HCS08
@ CS_MODE_M680X_HCS08
M680X Freescale/NXP HCS08 mode.
Definition: capstone.h:137
M680X_getInstruction
bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info)
csh
size_t csh
Definition: capstone.h:71
M680X_INS_EMUL
@ M680X_INS_EMUL
Definition: m680x.h:318
MCInst
Definition: MCInst.h:88
M680X_SECOND_OP_IN_MNEM
#define M680X_SECOND_OP_IN_MNEM
Definition: m680x.h:162
M680X_INS_LEAX
@ M680X_INS_LEAX
Definition: m680x.h:381
M680X_CPU_TYPE_HCS08
@ M680X_CPU_TYPE_HCS08
Definition: M680XDisassemblerInternals.h:22
capstone.CS_ERR_MODE
CS_ERR_MODE
Definition: third_party/bloaty/third_party/capstone/bindings/python/capstone/__init__.py:242
M680X_REG_TMP2
@ M680X_REG_TMP2
CPU12.
Definition: m680x.h:48
M680X_REG_F
@ M680X_REG_F
HD6309.
Definition: m680x.h:26
M680X_GRP_ENDING
@ M680X_GRP_ENDING
Definition: m680x.h:152
upload.group
group
Definition: bloaty/third_party/googletest/googlemock/scripts/upload.py:397
M680X_CPU_TYPE_6800
@ M680X_CPU_TYPE_6800
Definition: M680XDisassemblerInternals.h:14
M680XInstPrinter.h
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
M680X_INS_PULU
@ M680X_INS_PULU
Definition: m680x.h:437
M680X_INS_PSHH
@ M680X_INS_PSHH
Definition: m680x.h:423
M680X_INS_PULA
@ M680X_INS_PULA
M6800/1/2/3.
Definition: m680x.h:430
M680X_INS_BRN
@ M680X_INS_BRN
Definition: m680x.h:242
M680X_REG_Y
@ M680X_REG_Y
M6809/M6309.
Definition: m680x.h:39
M680X_CPU_TYPE_6301
@ M680X_CPU_TYPE_6301
Definition: M680XDisassemblerInternals.h:12
cs_m680x_op::ext
m680x_op_ext ext
Extended address.
Definition: m680x.h:121
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
first
StrT first
Definition: cxa_demangle.cpp:4884
M680X_OP_RELATIVE
@ M680X_OP_RELATIVE
= Relative addressing operand.
Definition: m680x.h:62
cpu_tables
Definition: M680XDisassemblerInternals.h:29
M680X_OP_INDEXED
@ M680X_OP_INDEXED
= Indexed addressing operand.
Definition: m680x.h:59
M680X_INS_ETBL
@ M680X_INS_ETBL
Definition: m680x.h:325
M680X_disassembler_init
cs_err M680X_disassembler_init(cs_struct *ud)
cpu_tables::pageX_table_size
size_t pageX_table_size[3]
Definition: M680XDisassemblerInternals.h:35
cpu_tables::inst_overlay_table
const struct inst_pageX * inst_overlay_table[2]
Definition: M680XDisassemblerInternals.h:31
M680X_INS_TBNE
@ M680X_INS_TBNE
Definition: m680x.h:505
M680X_INS_RTS
@ M680X_INS_RTS
Definition: m680x.h:458
M680X_INS_BSET
@ M680X_INS_BSET
Definition: m680x.h:243
m680x_group_type
m680x_group_type
Group of M680X instructions.
Definition: m680x.h:133
M680X_INS_SWI3
@ M680X_INS_SWI3
Definition: m680x.h:497
M680X_REG_CC
@ M680X_REG_CC
M6800/1/2/3/9, M6301/9.
Definition: m680x.h:32
mkowners.rel
rel
Definition: mkowners.py:109
m680x_op_ext::address
uint16_t address
The absolute address.
Definition: m680x.h:109
M680X_REG_B
@ M680X_REG_B
M6800/1/2/3/9, HD6301/9.
Definition: m680x.h:24
M680X_INS_FDIV
@ M680X_INS_FDIV
Definition: m680x.h:327
M680X_INS_PULH
@ M680X_INS_PULH
Definition: m680x.h:434
M680X_INS_SWI2
@ M680X_INS_SWI2
Definition: m680x.h:496
M680X_INS_ILLGL
@ M680X_INS_ILLGL
Definition: m680x.h:332
m680x_info::m680x
cs_m680x m680x
Definition: M680XDisassemblerInternals.h:47
M680X_INS_WAI
@ M680X_INS_WAI
M6800/1/2/3.
Definition: m680x.h:524
cs_m680x_op::type
m680x_op_type type
Definition: m680x.h:115
M680X_INS_EDIVS
@ M680X_INS_EDIVS
Definition: m680x.h:311
handle
static csh handle
Definition: test_arm_regression.c:16
M680X_OP_REGISTER
@ M680X_OP_REGISTER
= Register operand.
Definition: m680x.h:57
CS_MODE_M680X_6301
@ CS_MODE_M680X_6301
M680X Hitachi 6301,6303 mode.
Definition: capstone.h:127
M680X_INS_MINM
@ M680X_INS_MINM
Definition: m680x.h:398
M680X_CPU_TYPE_6309
@ M680X_CPU_TYPE_6309
Definition: M680XDisassemblerInternals.h:13
M680X_INS_IDIVS
@ M680X_INS_IDIVS
Definition: m680x.h:331
M680X_INS_IDIV
@ M680X_INS_IDIV
Definition: m680x.h:330
int8_t
signed char int8_t
Definition: stdint-msvc2008.h:75
cs_m680x_op
Instruction operand.
Definition: m680x.h:114
code
Definition: bloaty/third_party/zlib/contrib/infback9/inftree9.h:24
M680X_REG_INVALID
@ M680X_REG_INVALID
Definition: m680x.h:21
M680X_REG_TMP3
@ M680X_REG_TMP3
CPU12.
Definition: m680x.h:49
M680X_INS_LBSR
@ M680X_INS_LBSR
Definition: m680x.h:360
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
M680X_INS_REVW
@ M680X_INS_REVW
Definition: m680x.h:442
M680X_INS_REV
@ M680X_INS_REV
Definition: m680x.h:441
cpu_tables::inst_pageX_table
const struct inst_pageX * inst_pageX_table[3]
Definition: M680XDisassemblerInternals.h:34
M680X_INS_JSR
@ M680X_INS_JSR
Definition: m680x.h:345
M680X_GRP_RET
@ M680X_GRP_RET
= CS_GRP_RET
Definition: m680x.h:141
M680X_INS_SWI
@ M680X_INS_SWI
Definition: m680x.h:495
MCInst_setOpcode
void MCInst_setOpcode(MCInst *inst, unsigned Op)
Definition: MCInst.c:55
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
m680x_info::offset
uint16_t offset
Definition: M680XDisassemblerInternals.h:45
M680X_INS_MUL
@ M680X_INS_MUL
Definition: m680x.h:402
M680X_OFFSET_BITS_16
#define M680X_OFFSET_BITS_16
Definition: m680x.h:72
M680X_INS_PSHY
@ M680X_INS_PSHY
Definition: m680x.h:429
access
Definition: bloaty/third_party/zlib/examples/zran.c:75
m680x_info::size
uint32_t size
Definition: M680XDisassemblerInternals.h:44
M680X_INS_PULS
@ M680X_INS_PULS
Definition: m680x.h:435
CS_MODE_M680X_6811
@ CS_MODE_M680X_6811
M680X Motorola/Freescale/NXP 68HC11 mode.
Definition: capstone.h:134
opcode
opcode
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:6290
M680X_INS_LBRN
@ M680X_INS_LBRN
Definition: m680x.h:359
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
M680X_INS_PULY
@ M680X_INS_PULY
Definition: m680x.h:440
M680X_INS_EMAXM
@ M680X_INS_EMAXM
Definition: m680x.h:315
M680X_REG_ENDING
@ M680X_REG_ENDING
<– mark the end of the list of registers
Definition: m680x.h:51
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
exists_reg_list
static int exists_reg_list(uint16_t *regs, uint8_t count, m68k_reg reg)
Definition: M68KDisassembler.c:3843
MCInst::flat_insn
cs_insn * flat_insn
Definition: MCInst.h:95
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
CS_AC_WRITE
@ CS_AC_WRITE
Operand write to memory or register.
Definition: capstone.h:206
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
id
uint32_t id
Definition: flow_control_fuzzer.cc:70
ARR_SIZE
#define ARR_SIZE(a)
Definition: ocaml.c:13
M680X_REG_H
@ M680X_REG_H
M6808.
Definition: m680x.h:37
M680X_INS_DIV
@ M680X_INS_DIV
Definition: m680x.h:307


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:30