Coverage Report

Created: 2026-03-03 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonenext/arch/M68K/M68KInstPrinter.c
Line
Count
Source
1
/* Capstone Disassembly Engine */
2
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */
3
4
#include <stdio.h> // DEBUG
5
#include <stdlib.h>
6
#include <string.h>
7
8
#include "M68KInstPrinter.h"
9
10
#include "M68KDisassembler.h"
11
12
#include "../../cs_priv.h"
13
#include "../../Mapping.h"
14
#include "../../utils.h"
15
16
#include "../../MCInst.h"
17
#include "../../MCInstrDesc.h"
18
#include "../../MCRegisterInfo.h"
19
20
#ifndef CAPSTONE_DIET
21
static const char s_spacing[] = " ";
22
23
static const char *const s_reg_names[] = {
24
  "invalid", "d0",    "d1",    "d2",  "d3",  "d4",   "d5",   "d6",
25
  "d7",    "a0",    "a1",    "a2",  "a3",  "a4",   "a5",   "a6",
26
  "a7",    "fp0",   "fp1",   "fp2", "fp3", "fp4",  "fp5",  "fp6",
27
  "fp7",     "pc",    "sr",    "ccr", "sfc", "dfc",  "usp",  "vbr",
28
  "cacr",    "caar",  "msp",   "isp", "tc",  "itt0", "itt1", "dtt0",
29
  "dtt1",    "mmusr", "urp",   "srp",
30
31
  "fpcr",    "fpsr",  "fpiar",
32
};
33
34
static const char *const s_instruction_names[] = {
35
  "invalid",  "abcd", "add",      "adda", "addi",      "addq",
36
  "addx",     "and",  "andi",     "asl",  "asr",       "bhs",
37
  "blo",      "bhi",  "bls",      "bcc",  "bcs",       "bne",
38
  "beq",      "bvc",  "bvs",      "bpl",  "bmi",       "bge",
39
  "blt",      "bgt",  "ble",      "bra",  "bsr",       "bchg",
40
  "bclr",     "bset", "btst",     "bfchg",  "bfclr",     "bfexts",
41
  "bfextu",   "bfffo",  "bfins",    "bfset",  "bftst",     "bkpt",
42
  "callm",    "cas",  "cas2",     "chk",  "chk2",      "clr",
43
  "cmp",      "cmpa", "cmpi",     "cmpm", "cmp2",      "cinvl",
44
  "cinvp",    "cinva",  "cpushl",   "cpushp", "cpusha",    "dbt",
45
  "dbf",      "dbhi", "dbls",     "dbcc", "dbcs",      "dbne",
46
  "dbeq",     "dbvc", "dbvs",     "dbpl", "dbmi",      "dbge",
47
  "dblt",     "dbgt", "dble",     "dbra", "divs",      "divsl",
48
  "divu",     "divul",  "eor",      "eori", "exg",       "ext",
49
  "extb",     "fabs", "fsabs",    "fdabs",  "facos",     "fadd",
50
  "fsadd",    "fdadd",  "fasin",    "fatan",  "fatanh",    "fbf",
51
  "fbeq",     "fbogt",  "fboge",    "fbolt",  "fbole",     "fbogl",
52
  "fbor",     "fbun", "fbueq",    "fbugt",  "fbuge",     "fbult",
53
  "fbule",    "fbne", "fbt",      "fbsf", "fbseq",     "fbgt",
54
  "fbge",     "fblt", "fble",     "fbgl", "fbgle",     "fbngle",
55
  "fbngl",    "fbnle",  "fbnlt",    "fbnge",  "fbngt",     "fbsne",
56
  "fbst",     "fcmp", "fcos",     "fcosh",  "fdbf",      "fdbeq",
57
  "fdbogt",   "fdboge", "fdbolt",   "fdbole", "fdbogl",    "fdbor",
58
  "fdbun",    "fdbueq", "fdbugt",   "fdbuge", "fdbult",    "fdbule",
59
  "fdbne",    "fdbt", "fdbsf",    "fdbseq", "fdbgt",     "fdbge",
60
  "fdblt",    "fdble",  "fdbgl",    "fdbgle", "fdbngle",   "fdbngl",
61
  "fdbnle",   "fdbnlt", "fdbnge",   "fdbngt", "fdbsne",    "fdbst",
62
  "fdiv",     "fsdiv",  "fddiv",    "fetox",  "fetoxm1",   "fgetexp",
63
  "fgetman",  "fint", "fintrz",   "flog10", "flog2",     "flogn",
64
  "flognp1",  "fmod", "fmove",    "fsmove", "fdmove",    "fmovecr",
65
  "fmovem",   "fmul", "fsmul",    "fdmul",  "fneg",      "fsneg",
66
  "fdneg",    "fnop", "frem",     "frestore", "fsave",     "fscale",
67
  "fsgldiv",  "fsglmul",  "fsin",     "fsincos",  "fsinh",     "fsqrt",
68
  "fssqrt",   "fdsqrt", "fsf",      "fseq", "fsogt",     "fsoge",
69
  "fsolt",    "fsole",  "fsogl",    "fsor", "fsun",      "fsueq",
70
  "fsugt",    "fsuge",  "fsult",    "fsule",  "fsne",      "fst",
71
  "fssf",     "fsseq",  "fsgt",     "fsge", "fslt",      "fsle",
72
  "fsgl",     "fsgle",  "fsngle",   "fsngl",  "fsnle",     "fsnlt",
73
  "fsnge",    "fsngt",  "fssne",    "fsst", "fsub",      "fssub",
74
  "fdsub",    "ftan", "ftanh",    "ftentox",  "ftrapf",    "ftrapeq",
75
  "ftrapogt", "ftrapoge", "ftrapolt", "ftrapole", "ftrapogl",  "ftrapor",
76
  "ftrapun",  "ftrapueq", "ftrapugt", "ftrapuge", "ftrapult",  "ftrapule",
77
  "ftrapne",  "ftrapt", "ftrapsf",  "ftrapseq", "ftrapgt",   "ftrapge",
78
  "ftraplt",  "ftraple",  "ftrapgl",  "ftrapgle", "ftrapngle", "ftrapngl",
79
  "ftrapnle", "ftrapnlt", "ftrapnge", "ftrapngt", "ftrapsne",  "ftrapst",
80
  "ftst",     "ftwotox",  "halt",     "illegal",  "jmp",       "jsr",
81
  "lea",      "link", "lpstop",   "lsl",  "lsr",       "move",
82
  "movea",    "movec",  "movem",    "movep",  "moveq",     "moves",
83
  "move16",   "muls", "mulu",     "nbcd", "neg",       "negx",
84
  "nop",      "not",  "or",     "ori",  "pack",      "pea",
85
  "pflush",   "pflusha",  "pflushan", "pflushn",  "ploadr",    "ploadw",
86
  "plpar",    "plpaw",  "pmove",    "pmovefd",  "ptestr",    "ptestw",
87
  "pulse",    "rems", "remu",     "reset",  "rol",       "ror",
88
  "roxl",     "roxr", "rtd",      "rte",  "rtm",       "rtr",
89
  "rts",      "sbcd", "st",     "sf", "shi",       "sls",
90
  "scc",      "shs",  "scs",      "slo",  "sne",       "seq",
91
  "svc",      "svs",  "spl",      "smi",  "sge",       "slt",
92
  "sgt",      "sle",  "stop",     "sub",  "suba",      "subi",
93
  "subq",     "subx", "swap",     "tas",  "trap",      "trapv",
94
  "trapt",    "trapf",  "traphi",   "trapls", "trapcc",    "traphs",
95
  "trapcs",   "traplo", "trapne",   "trapeq", "trapvc",    "trapvs",
96
  "trappl",   "trapmi", "trapge",   "traplt", "trapgt",    "traple",
97
  "tst",      "unlk", "unpk",
98
};
99
#endif
100
101
#ifndef CAPSTONE_DIET
102
static const char *getRegName(m68k_reg reg)
103
41.2k
{
104
41.2k
  return s_reg_names[(int)reg];
105
41.2k
}
106
107
static void printRegbitsRange(char *buffer, size_t buf_len, uint32_t data,
108
            const char *prefix)
109
20.6k
{
110
20.6k
  unsigned int first = 0;
111
20.6k
  unsigned int run_length = 0;
112
20.6k
  int i;
113
114
165k
  for (i = 0; i < 8; ++i) {
115
145k
    if (data & (1 << i)) {
116
23.4k
      first = i;
117
23.4k
      run_length = 0;
118
119
43.3k
      while (i < 7 && (data & (1 << (i + 1)))) {
120
19.8k
        i++;
121
19.8k
        run_length++;
122
19.8k
      }
123
124
23.4k
      if (buffer[0] != 0)
125
16.6k
        strncat(buffer, "/", buf_len - 1);
126
127
23.4k
      snprintf(buffer + strlen(buffer), buf_len, "%s%" PRId32,
128
23.4k
         prefix, first);
129
23.4k
      if (run_length > 0)
130
8.99k
        snprintf(buffer + strlen(buffer), buf_len,
131
8.99k
           "-%s%" PRId32, prefix,
132
8.99k
           first + run_length);
133
23.4k
    }
134
145k
  }
135
20.6k
}
136
137
static void registerBits(SStream *O, const cs_m68k_op *op)
138
7.83k
{
139
7.83k
  char buffer[128];
140
7.83k
  unsigned int data = op->register_bits;
141
142
7.83k
  buffer[0] = 0;
143
144
7.83k
  if (!data) {
145
959
    SStream_concat(O, "%s", "#$0");
146
959
    return;
147
959
  }
148
149
6.87k
  printRegbitsRange(buffer, sizeof(buffer), data & 0xff, "d");
150
6.87k
  printRegbitsRange(buffer, sizeof(buffer), (data >> 8) & 0xff, "a");
151
6.87k
  printRegbitsRange(buffer, sizeof(buffer), (data >> 16) & 0xff, "fp");
152
153
6.87k
  SStream_concat(O, "%s", buffer);
154
6.87k
}
155
156
static void registerPair(SStream *O, const cs_m68k_op *op)
157
4.05k
{
158
4.05k
  SStream_concat(O, "%s:%s", s_reg_names[op->reg_pair.reg_0],
159
4.05k
           s_reg_names[op->reg_pair.reg_1]);
160
4.05k
}
161
162
static void printAddressingMode(SStream *O, unsigned int pc,
163
        const cs_m68k *inst, const cs_m68k_op *op)
164
134k
{
165
134k
  switch (op->address_mode) {
166
17.5k
  case M68K_AM_NONE:
167
17.5k
    switch (op->type) {
168
1.27k
    case M68K_OP_REG_BITS:
169
1.27k
      registerBits(O, op);
170
1.27k
      break;
171
631
    case M68K_OP_REG_PAIR:
172
631
      registerPair(O, op);
173
631
      break;
174
15.5k
    case M68K_OP_REG:
175
15.5k
      SStream_concat(O, "%s", s_reg_names[op->reg]);
176
15.5k
      break;
177
136
    default:
178
136
      break;
179
17.5k
    }
180
17.5k
    break;
181
182
41.1k
  case M68K_AM_REG_DIRECT_DATA:
183
41.1k
    SStream_concat(O, "d%" PRId32, (op->reg - M68K_REG_D0));
184
41.1k
    break;
185
5.43k
  case M68K_AM_REG_DIRECT_ADDR:
186
5.43k
    SStream_concat(O, "a%" PRId32, (op->reg - M68K_REG_A0));
187
5.43k
    break;
188
9.20k
  case M68K_AM_REGI_ADDR:
189
9.20k
    SStream_concat(O, "(a%" PRId32 ")", (op->reg - M68K_REG_A0));
190
9.20k
    break;
191
7.79k
  case M68K_AM_REGI_ADDR_POST_INC:
192
7.79k
    SStream_concat(O, "(a%" PRId32 ")+", (op->reg - M68K_REG_A0));
193
7.79k
    break;
194
13.9k
  case M68K_AM_REGI_ADDR_PRE_DEC:
195
13.9k
    SStream_concat(O, "-(a%" PRId32 ")", (op->reg - M68K_REG_A0));
196
13.9k
    break;
197
5.03k
  case M68K_AM_REGI_ADDR_DISP:
198
5.03k
    SStream_concat(O, "%s$%" PRIx16 "(a%" PRId32 ")",
199
5.03k
             op->mem.disp < 0 ? "-" : "", abs(op->mem.disp),
200
5.03k
             (op->mem.base_reg - M68K_REG_A0));
201
5.03k
    break;
202
489
  case M68K_AM_PCI_DISP:
203
489
    SStream_concat(O, "$%" PRIx32 "(pc)", pc + 2 + op->mem.disp);
204
489
    break;
205
1.11k
  case M68K_AM_ABSOLUTE_DATA_SHORT:
206
1.11k
    SStream_concat(O, "$%" PRIx32 ".w", op->imm);
207
1.11k
    break;
208
886
  case M68K_AM_ABSOLUTE_DATA_LONG:
209
886
    SStream_concat(O, "$%" PRIx64 ".l", op->imm);
210
886
    break;
211
19.9k
  case M68K_AM_IMMEDIATE:
212
19.9k
    if (inst->op_size.type == M68K_SIZE_TYPE_FPU) {
213
#if defined(_KERNEL_MODE)
214
      // Issue #681: Windows kernel does not support formatting float point
215
      SStream_concat(O, "#<float_point_unsupported>");
216
      break;
217
#else
218
111
      if (inst->op_size.fpu_size == M68K_FPU_SIZE_SINGLE)
219
32
        SStream_concat(O, "#%f", op->simm);
220
79
      else if (inst->op_size.fpu_size == M68K_FPU_SIZE_DOUBLE)
221
79
        SStream_concat(O, "#%f", op->dimm);
222
0
      else
223
0
        SStream_concat(O, "#<unsupported>");
224
111
      break;
225
111
#endif
226
111
    }
227
19.8k
    SStream_concat(O, "#$%" PRIx64, op->imm);
228
19.8k
    break;
229
430
  case M68K_AM_PCI_INDEX_8_BIT_DISP:
230
430
    SStream_concat(O, "$%" PRIx32 "(pc,%s%s.%c)",
231
430
             pc + 2 + op->mem.disp, s_spacing,
232
430
             getRegName(op->mem.index_reg),
233
430
             op->mem.index_size ? 'l' : 'w');
234
430
    break;
235
2.16k
  case M68K_AM_AREGI_INDEX_8_BIT_DISP:
236
2.16k
    SStream_concat(O, "%s$%" PRIx16 "(%s,%s%s.%c)",
237
2.16k
             op->mem.disp < 0 ? "-" : "", abs(op->mem.disp),
238
2.16k
             getRegName(op->mem.base_reg), s_spacing,
239
2.16k
             getRegName(op->mem.index_reg),
240
2.16k
             op->mem.index_size ? 'l' : 'w');
241
2.16k
    break;
242
319
  case M68K_AM_PCI_INDEX_BASE_DISP:
243
1.65k
  case M68K_AM_AREGI_INDEX_BASE_DISP:
244
245
1.65k
    if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
246
319
      SStream_concat(O, "$%" PRIx32,
247
319
               pc + 2 + op->mem.in_disp);
248
1.33k
    } else if (op->mem.in_disp != 0) {
249
392
      SStream_concat(O, "%s$%" PRIx32,
250
392
               op->mem.in_disp >= 0 ? "" : "-",
251
392
               abs(op->mem.in_disp));
252
392
    }
253
254
1.65k
    SStream_concat0(O, "(");
255
256
1.65k
    if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
257
319
      SStream_concat0(O, "pc");
258
1.33k
    } else if (op->mem.base_reg != M68K_REG_INVALID) {
259
1.00k
      SStream_concat(O, "a%" PRId32,
260
1.00k
               op->mem.base_reg - M68K_REG_A0);
261
1.00k
    }
262
263
1.65k
    if ((op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP ||
264
1.33k
         op->mem.base_reg != M68K_REG_INVALID) &&
265
1.32k
        op->mem.index_reg != M68K_REG_INVALID)
266
1.14k
      SStream_concat(O, ",%s", s_spacing);
267
268
1.65k
    if (op->mem.index_reg != M68K_REG_INVALID) {
269
1.42k
      SStream_concat(O, "%s.%c",
270
1.42k
               getRegName(op->mem.index_reg),
271
1.42k
               op->mem.index_size ? 'l' : 'w');
272
1.42k
      if (op->mem.scale > 0)
273
1.00k
        SStream_concat(O, "%s*%s%" PRId8, s_spacing,
274
1.00k
                 s_spacing, op->mem.scale);
275
1.42k
    }
276
277
1.65k
    SStream_concat0(O, ")");
278
1.65k
    break;
279
    // It's ok to just use PCMI here as is as we set base_reg to PC in the disassembler. While this is not strictly correct it makes the code
280
    // easier and that is what actually happens when the code is executed anyway.
281
282
198
  case M68K_AM_PC_MEMI_POST_INDEX:
283
464
  case M68K_AM_PC_MEMI_PRE_INDEX:
284
1.13k
  case M68K_AM_MEMI_PRE_INDEX:
285
2.02k
  case M68K_AM_MEMI_POST_INDEX:
286
2.02k
    SStream_concat0(O, "([");
287
288
2.02k
    if (op->address_mode == M68K_AM_PC_MEMI_POST_INDEX ||
289
1.82k
        op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX) {
290
464
      SStream_concat(O, "$%" PRIx32,
291
464
               pc + 2 + op->mem.in_disp);
292
1.56k
    } else if (op->mem.in_disp != 0) {
293
602
      SStream_concat(O, "%s$%" PRIx32,
294
602
               op->mem.in_disp >= 0 ? "" : "-",
295
602
               abs(op->mem.in_disp));
296
602
    }
297
298
2.02k
    if (op->mem.base_reg != M68K_REG_INVALID) {
299
1.51k
      if (op->mem.in_disp != 0)
300
652
        SStream_concat(O, ",%s%s", s_spacing,
301
652
                 getRegName(op->mem.base_reg));
302
863
      else
303
863
        SStream_concat(O, "%s",
304
863
                 getRegName(op->mem.base_reg));
305
1.51k
    }
306
307
2.02k
    if (op->address_mode == M68K_AM_MEMI_POST_INDEX ||
308
1.13k
        op->address_mode == M68K_AM_PC_MEMI_POST_INDEX)
309
1.08k
      SStream_concat0(O, "]");
310
311
2.02k
    if (op->mem.index_reg != M68K_REG_INVALID)
312
1.47k
      SStream_concat(O, ",%s%s.%c", s_spacing,
313
1.47k
               getRegName(op->mem.index_reg),
314
1.47k
               op->mem.index_size ? 'l' : 'w');
315
316
2.02k
    if (op->mem.scale > 0)
317
1.22k
      SStream_concat(O, "%s*%s%" PRId8, s_spacing, s_spacing,
318
1.22k
               op->mem.scale);
319
320
2.02k
    if (op->address_mode == M68K_AM_MEMI_PRE_INDEX ||
321
1.35k
        op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX)
322
938
      SStream_concat0(O, "]");
323
324
2.02k
    if (op->mem.out_disp != 0) {
325
1.14k
      SStream_concat(O, ",%s%s$%" PRIx32, s_spacing,
326
1.14k
               op->mem.out_disp >= 0 ? "" : "-",
327
1.14k
               abs(op->mem.out_disp));
328
1.14k
    }
329
330
2.02k
    SStream_concat0(O, ")");
331
2.02k
    break;
332
6.07k
  case M68K_AM_BRANCH_DISPLACEMENT:
333
6.07k
    SStream_concat(O, "$%" PRIx32, pc + 2 + op->br_disp.disp);
334
6.07k
  default:
335
6.07k
    break;
336
134k
  }
337
338
134k
  if (op->mem.bitfield)
339
177
    SStream_concat(O, "{%" PRId8 ":%" PRId8 "}", op->mem.offset,
340
177
             op->mem.width);
341
134k
}
342
#endif
343
344
#define m68k_sizeof_array(array) (int)(sizeof(array) / sizeof(array[0]))
345
1.16M
#define m68k_min(a, b) (a < b) ? a : b
346
347
void M68K_printInst(MCInst *MI, SStream *O, void *PrinterInfo)
348
387k
{
349
387k
#ifndef CAPSTONE_DIET
350
387k
  m68k_info *info = (m68k_info *)PrinterInfo;
351
387k
  cs_m68k *ext = &info->extension;
352
387k
  cs_detail *detail = NULL;
353
387k
  int i = 0;
354
355
387k
  detail = MI->flat_insn->detail;
356
387k
  if (detail) {
357
387k
    int regs_read_count =
358
387k
      m68k_min(m68k_sizeof_array(detail->regs_read),
359
387k
         info->regs_read_count);
360
387k
    int regs_write_count =
361
387k
      m68k_min(m68k_sizeof_array(detail->regs_write),
362
387k
         info->regs_write_count);
363
387k
    int groups_count = m68k_min(m68k_sizeof_array(detail->groups),
364
387k
              info->groups_count);
365
366
387k
    memcpy(&detail->m68k, ext, sizeof(cs_m68k));
367
368
387k
    memcpy(&detail->regs_read, &info->regs_read,
369
387k
           regs_read_count * sizeof(info->regs_read[0]));
370
387k
    detail->regs_read_count = regs_read_count;
371
372
387k
    memcpy(&detail->regs_write, &info->regs_write,
373
387k
           regs_write_count * sizeof(info->regs_write[0]));
374
387k
    detail->regs_write_count = regs_write_count;
375
376
387k
    memcpy(&detail->groups, &info->groups, groups_count);
377
387k
    detail->groups_count = groups_count;
378
387k
  }
379
380
387k
  if (MI->Opcode == M68K_INS_INVALID) {
381
50.8k
    if (ext->op_count)
382
50.8k
      SStream_concat(O, "dc.w $%" PRIx32,
383
50.8k
               ext->operands[0].imm);
384
0
    else
385
0
      SStream_concat(O, "dc.w $<unknown>");
386
50.8k
    return;
387
50.8k
  }
388
389
336k
  SStream_concat0(O, (char *)s_instruction_names[MI->Opcode]);
390
391
336k
  switch (ext->op_size.type) {
392
0
  case M68K_SIZE_TYPE_INVALID:
393
0
    break;
394
395
332k
  case M68K_SIZE_TYPE_CPU:
396
332k
    switch (ext->op_size.cpu_size) {
397
103k
    case M68K_CPU_SIZE_BYTE:
398
103k
      SStream_concat0(O, ".b");
399
103k
      break;
400
92.8k
    case M68K_CPU_SIZE_WORD:
401
92.8k
      SStream_concat0(O, ".w");
402
92.8k
      break;
403
79.6k
    case M68K_CPU_SIZE_LONG:
404
79.6k
      SStream_concat0(O, ".l");
405
79.6k
      break;
406
56.4k
    case M68K_CPU_SIZE_NONE:
407
56.4k
      break;
408
332k
    }
409
332k
    break;
410
411
332k
  case M68K_SIZE_TYPE_FPU:
412
4.05k
    switch (ext->op_size.fpu_size) {
413
720
    case M68K_FPU_SIZE_SINGLE:
414
720
      SStream_concat0(O, ".s");
415
720
      break;
416
1.68k
    case M68K_FPU_SIZE_DOUBLE:
417
1.68k
      SStream_concat0(O, ".d");
418
1.68k
      break;
419
1.65k
    case M68K_FPU_SIZE_EXTENDED:
420
1.65k
      SStream_concat0(O, ".x");
421
1.65k
      break;
422
0
    case M68K_FPU_SIZE_NONE:
423
0
      break;
424
4.05k
    }
425
4.05k
    break;
426
336k
  }
427
428
336k
  SStream_concat0(O, " ");
429
430
  // this one is a bit spacial so we do special things
431
432
336k
  if (MI->Opcode == M68K_INS_CAS2) {
433
1.85k
    int reg_value_0, reg_value_1;
434
1.85k
    printAddressingMode(O, info->pc, ext, &ext->operands[0]);
435
1.85k
    SStream_concat0(O, ",");
436
1.85k
    printAddressingMode(O, info->pc, ext, &ext->operands[1]);
437
1.85k
    SStream_concat0(O, ",");
438
1.85k
    reg_value_0 = ext->operands[2].register_bits >> 4;
439
1.85k
    reg_value_1 = ext->operands[2].register_bits & 0xf;
440
1.85k
    SStream_concat(O, "(%s):(%s)",
441
1.85k
             s_reg_names[M68K_REG_D0 + reg_value_0],
442
1.85k
             s_reg_names[M68K_REG_D0 + reg_value_1]);
443
1.85k
    return;
444
1.85k
  }
445
446
937k
  for (i = 0; i < ext->op_count; ++i) {
447
602k
    printAddressingMode(O, info->pc, ext, &ext->operands[i]);
448
602k
    if ((i + 1) != ext->op_count)
449
271k
      SStream_concat(O, ",%s", s_spacing);
450
602k
  }
451
334k
#endif
452
334k
}
453
454
const char *M68K_reg_name(csh handle, unsigned int reg)
455
496k
{
456
#ifdef CAPSTONE_DIET
457
  return NULL;
458
#else
459
496k
  if (reg >= ARR_SIZE(s_reg_names)) {
460
0
    return NULL;
461
0
  }
462
496k
  return s_reg_names[(int)reg];
463
496k
#endif
464
496k
}
465
466
void M68K_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
467
387k
{
468
387k
  insn->id = id; // These id's matches for 68k
469
387k
}
470
471
const char *M68K_insn_name(csh handle, unsigned int id)
472
387k
{
473
#ifdef CAPSTONE_DIET
474
  return NULL;
475
#else
476
387k
  return s_instruction_names[id];
477
387k
#endif
478
387k
}
479
480
#ifndef CAPSTONE_DIET
481
static const name_map group_name_maps[] = {
482
  { M68K_GRP_INVALID, NULL },
483
  { M68K_GRP_JUMP, "jump" },
484
  { M68K_GRP_RET, "ret" },
485
  { M68K_GRP_IRET, "iret" },
486
  { M68K_GRP_BRANCH_RELATIVE, "branch_relative" },
487
};
488
#endif
489
490
const char *M68K_group_name(csh handle, unsigned int id)
491
66.0k
{
492
66.0k
#ifndef CAPSTONE_DIET
493
66.0k
  return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
494
#else
495
  return NULL;
496
#endif
497
66.0k
}
498
499
#ifndef CAPSTONE_DIET
500
void M68K_reg_access(const cs_insn *insn, cs_regs regs_read,
501
         uint8_t *regs_read_count, cs_regs regs_write,
502
         uint8_t *regs_write_count)
503
0
{
504
0
  uint8_t read_count, write_count;
505
506
0
  read_count = insn->detail->regs_read_count;
507
0
  write_count = insn->detail->regs_write_count;
508
509
  // implicit registers
510
0
  memcpy(regs_read, insn->detail->regs_read,
511
0
         read_count * sizeof(insn->detail->regs_read[0]));
512
0
  memcpy(regs_write, insn->detail->regs_write,
513
0
         write_count * sizeof(insn->detail->regs_write[0]));
514
515
0
  *regs_read_count = read_count;
516
0
  *regs_write_count = write_count;
517
0
}
518
#endif