Rizin
unix-like reverse engineering framework and cli tools
dis.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2012 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /* copypasted from http://pastie.org/3732465 */
5 /* adapted by pancake // public license */
6 /* known bugs: some (%s, NULL) happen */
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "dcpu16.h"
11 
12 struct op_code {
14 };
15 
16 struct op_basic {
20 
23 };
24 
25 struct op_nbasic {
30 };
31 
32 typedef union {
33  struct op_code code;
34  struct op_basic b;
35  struct op_nbasic n;
36 } op;
37 
38 static const int opCycle[] = {
39  0, 1, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 2, 2, 2, 2
40 };
41 static const int opCycleB[] = { 0, 2 };
42 
43 static const char *opName[] = {
44  "", "set",
45  "add", "sub", "mul", "div", "mod",
46  "shl", "shr", "and", "bor", "xor",
47  "ife", "ifn", "ifg", "ifb"
48 };
49 
50 static const char *opNameB[] = { "reserved", "jsr" };
51 
52 static const char *regs[] = {
53  "a", "b", "c", "x", "y", "z", "i", "j",
54  "pop", "peek", "push", "sp", "pc", "o"
55 };
56 
57 static inline int needWord(ut8 type) {
58  return ((type <= 0x17) && (type > 0x0f)) || (type == 0x1e) || (type == 0x1f);
59 }
60 
61 static int valPrint(char *out, size_t size_out, ut8 type, ut16 value) {
62  if (type <= 0x07)
63  return snprintf(out, size_out, "%s", regs[type]);
64  if (type <= 0x0f)
65  return snprintf(out, size_out, "[%s]", regs[type - 0x08]);
66  if (type <= 0x17)
67  return snprintf(out, size_out, "[%s + %#hx]", regs[type - 0x10], value);
68  if (type <= 0x1d)
69  return snprintf(out, size_out, "%s", regs[type - 0x18 + 0x08]);
70  if (type == 0x1e)
71  return snprintf(out, size_out, "[%#hx]", value);
72  if (type == 0x1f)
73  return snprintf(out, size_out, "%#hx", value);
74  return snprintf(out, size_out, "%#hx", (short)(type - 0x20));
75 }
76 
77 static int instrPrint(char *out, size_t size_out, const op *o) {
78  char arg[32], arg2[32];
79  if (o->code.opcode == 0) {
80  valPrint(arg, sizeof(arg), o->n.a_type, o->n.a);
81  if (o->n.opcode > 1) {
82  strncpy(out, "invalid", size_out);
83  out[size_out - 1] = 0;
84  return strlen(out);
85  }
86  return snprintf(out, size_out, "%s %s",
87  opNameB[o->n.opcode], arg);
88  }
89  valPrint(arg, sizeof(arg), o->b.a_type, o->b.a);
90  valPrint(arg2, sizeof(arg2), o->b.b_type, o->b.b);
91  return snprintf(out, size_out, "%s %s, %s", opName[o->b.opcode], arg, arg2);
92 }
93 
94 static int instrGet(ut16 in, op *o, ut16 a, ut16 b) {
95  int ret = 1;
96  o->code.opcode = in & 0xF;
97  if (!(o->code.opcode = in & 0xF)) {
98  /* Non basic op code */
99  o->n.opcode = (in >> 4) & 0x3F;
100  o->n.a_type = (in >> 10) & 0x3F;
101 
102  if (needWord(o->n.a_type)) {
103  o->n.a = a;
104  ret++;
105  }
106  } else {
107  o->b.a_type = (in >> 4) & 0x3F;
108  o->b.b_type = (in >> 10) & 0x3F;
109  if (needWord(o->b.a_type)) {
110  o->b.a = a;
111  ret++;
112  if (needWord(o->b.b_type)) {
113  o->b.b = b;
114  ret++;
115  }
116  } else if (needWord(o->b.b_type)) {
117  o->b.b = a;
118  ret++;
119  }
120  }
121  return ret;
122 }
123 
124 static int instrGetCycles(const op *o) {
125  if (o->code.opcode == 0)
126  return opCycleB[o->n.opcode] + needWord(o->n.a_type);
127  return opCycle[o->b.opcode] + needWord(o->b.a_type) + needWord(o->b.b_type);
128 }
129 
130 int dcpu16_disasm(char *out, size_t size_out, const ut16 *inp, int len, int *cost) {
131  op o = { { 0 } };
132  int delta = instrGet(inp[0], &o, inp[1], inp[2]);
133  if (cost)
134  *cost = instrGetCycles(&o) + ((o.b.opcode >= 0xc) ? 1 : 0);
135  instrPrint(out, size_out, &o);
136  // ind = (o.b.opcode >= 0xC);
137  return delta << 1;
138 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
static int value
Definition: cmd_api.c:93
static int valPrint(char *out, size_t size_out, ut8 type, ut16 value)
Definition: dis.c:61
static int needWord(ut8 type)
Definition: dis.c:57
static const char * regs[]
Definition: dis.c:52
static int instrPrint(char *out, size_t size_out, const op *o)
Definition: dis.c:77
static const char * opNameB[]
Definition: dis.c:50
static int instrGetCycles(const op *o)
Definition: dis.c:124
static const char * opName[]
Definition: dis.c:43
static const int opCycle[]
Definition: dis.c:38
int dcpu16_disasm(char *out, size_t size_out, const ut16 *inp, int len, int *cost)
Definition: dis.c:130
static const int opCycleB[]
Definition: dis.c:41
static int instrGet(ut16 in, op *o, ut16 a, ut16 b)
Definition: dis.c:94
uint16_t ut16
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
Definition: inftree9.h:24
Definition: dis.c:16
ut16 a
Definition: dis.c:21
ut16 b
Definition: dis.c:22
ut8 b_type
Definition: dis.c:19
ut8 opcode
Definition: dis.c:17
ut8 a_type
Definition: dis.c:18
Definition: dis.c:12
ut8 opcode
Definition: dis.c:13
Definition: dis.c:25
ut8 __empty
Definition: dis.c:26
ut8 a_type
Definition: dis.c:27
ut16 a
Definition: dis.c:29
ut8 opcode
Definition: dis.c:28
Definition: dis.c:32
struct op_basic b
Definition: dis.c:34
struct op_nbasic n
Definition: dis.c:35
struct op_code code
Definition: dis.c:33
static st64 delta
Definition: vmenus.c:2425