Rizin
unix-like reverse engineering framework and cli tools
v810_disas.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2015 danielps
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_types.h>
5 #include <rz_util.h>
6 
7 #include "v810_disas.h"
8 
9 static const char *instrs[] = {
10  [V810_MOV] = "mov",
11  [V810_ADD] = "add",
12  [V810_SUB] = "sub",
13  [V810_CMP] = "cmp",
14  [V810_SHL] = "shl",
15  [V810_SHR] = "shr",
16  [V810_JMP] = "jmp",
17  [V810_SAR] = "sar",
18  [V810_MUL] = "mul",
19  [V810_DIV] = "div",
20  [V810_MULU] = "mulu",
21  [V810_DIVU] = "divu",
22  [V810_OR] = "or",
23  [V810_AND] = "and",
24  [V810_XOR] = "xor",
25  [V810_NOT] = "not",
26  [V810_MOV_IMM5] = "mov",
27  [V810_ADD_IMM5] = "add",
28  [V810_CMP_IMM5] = "cmp",
29  [V810_SHL_IMM5] = "shl",
30  [V810_SHR_IMM5] = "shr",
31  [V810_SAR_IMM5] = "sar",
32  [V810_MOVEA] = "movea",
33  [V810_MOVHI] = "movhi",
34  [V810_ADDI] = "addi",
35  [V810_ORI] = "ori",
36  [V810_ANDI] = "andi",
37  [V810_XORI] = "xori",
38  [V810_JR] = "jr",
39  [V810_JAL] = "jal",
40  [V810_LDB] = "ld.b",
41  [V810_LDH] = "ld.h",
42  [V810_LDW] = "ld.w",
43  [V810_STB] = "st.b",
44  [V810_STH] = "st.h",
45  [V810_STW] = "st.w",
46  [V810_INB] = "in.b",
47  [V810_INH] = "in.h",
48  [V810_CAXI] = "caxi",
49  [V810_INW] = "in.w",
50  [V810_OUTB] = "out.b",
51  [V810_OUTH] = "out.h",
52  [V810_OUTW] = "out.w",
53  [V810_SETF] = "setf",
54  [V810_LDSR] = "ldsr",
55  [V810_STSR] = "stsr",
56  [V810_TRAP] = "trap",
57  [V810_HALT] = "halt",
58  [V810_RETI] = "reti",
59  [V810_SEI] = "sei",
60  [V810_CLI] = "cli",
61 };
62 
63 static const char *bit_instrs[] = {
64  [V810_BIT_SCH0U] = "sch0bsu",
65  [V810_BIT_SCH0D] = "sch0bsd",
66  [V810_BIT_SCH1U] = "sch1bsu",
67  [V810_BIT_SCH1D] = "sch1bsd",
68  [V810_BIT_ORU] = "orbsu",
69  [V810_BIT_ANDU] = "andbsu",
70  [V810_BIT_XORU] = "xorbsu",
71  [V810_BIT_MOVU] = "movbsu",
72  [V810_BIT_ORNU] = "ornbsu",
73  [V810_BIT_ANDNU] = "andnbsu",
74  [V810_BIT_XORNU] = "xornbsu",
75  [V810_BIT_NOTU] = "notbsu",
76 };
77 
78 static const char *ext_instrs[] = {
79  [V810_EXT_CMPF_S] = "cmpf.s",
80  [V810_EXT_CVT_WS] = "cvt.ws",
81  [V810_EXT_CVT_SW] = "cvt.sw",
82  [V810_EXT_ADDF_S] = "addf.s",
83  [V810_EXT_SUBF_S] = "subf.s",
84  [V810_EXT_MULF_S] = "mulf.s",
85  [V810_EXT_DIVF_S] = "divf.s",
86  [V810_EXT_XB] = "xb",
87  [V810_EXT_XH] = "xh",
88  [V810_EXT_REV] = "rev",
89  [V810_EXT_TRNC_SW] = "trnc.sw",
90  [V810_EXT_MPYHW] = "mpyhw",
91 };
92 
93 static const char *conds[] = {
94  [V810_COND_V] = "v",
95  [V810_COND_L] = "l",
96  [V810_COND_E] = "e",
97  [V810_COND_NH] = "nh",
98  [V810_COND_N] = "n",
99  [V810_COND_NONE] = "r",
100  [V810_COND_LT] = "lt",
101  [V810_COND_LE] = "le",
102  [V810_COND_NV] = "nv",
103  [V810_COND_NL] = "nl",
104  [V810_COND_NE] = "ne",
105  [V810_COND_H] = "h",
106  [V810_COND_P] = "p",
107  [V810_COND_GE] = "ge",
108  [V810_COND_GT] = "gt",
109 };
110 
111 static const char *sysreg_names[] = {
112  [V810_SREG_EIPC] = "EIPC",
113  [V810_SREG_EIPSW] = "EIPSW",
114  [V810_SREG_FEPC] = "FEPC",
115  [V810_SREG_FEPSW] = "FEPSW",
116  [V810_SREG_ECR] = "ECR",
117  [V810_SREG_PSW] = "PSW",
118  [V810_SREG_PIR] = "PIR",
119  [V810_SREG_TKCW] = "TKCW",
120  [V810_SREG_CHCW] = "CHCW",
121  [V810_SREG_ADTRE] = "ADTRE",
122 };
123 
124 static int decode_reg_reg(const ut16 instr, struct v810_cmd *cmd) {
125  ut8 opcode;
126 
127  opcode = OPCODE(instr);
128 
129  if (opcode >= sizeof(instrs) / sizeof(char *)) {
130  return -1;
131  }
132 
133  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s", instrs[opcode]);
134 
135  if (opcode == V810_JMP) {
136  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "[r%u]",
137  REG1(instr));
138  } else {
139  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "r%u, r%u",
140  REG1(instr), REG2(instr));
141  }
142 
143  return 2;
144 }
145 
146 static int decode_imm_reg(const ut16 instr, struct v810_cmd *cmd) {
147  ut8 opcode;
148  ut8 immed;
149 
150  opcode = OPCODE(instr);
151 
152  if (opcode >= sizeof(instrs) / sizeof(char *)) {
153  return -1;
154  }
155 
156  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s", instrs[opcode]);
157 
158  immed = IMM5(instr);
159 
160  switch (opcode) {
161  case V810_MOV_IMM5:
162  case V810_ADD_IMM5:
163  case V810_CMP_IMM5:
164  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%d, r%u",
165  (st8)SIGN_EXT_T5(immed), REG2(instr));
166  break;
167  case V810_LDSR:
168  case V810_STSR:
169  if (immed > 0x19 || (immed > 0x7 && immed < 0x18)) {
170  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "s%u, r%u",
171  (ut8)immed, REG2(instr));
172  } else if (sysreg_names[immed]) {
173  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%s, r%u",
174  sysreg_names[immed], REG2(instr));
175  }
176  break;
177  case V810_SETF:
178  case V810_SHL_IMM5:
179  case V810_SHR_IMM5:
180  case V810_SAR_IMM5:
181  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%u, r%u",
182  immed, REG2(instr));
183  break;
184  case V810_TRAP:
185  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%u",
186  immed);
187  break;
188  }
189 
190  return 2;
191 }
192 
193 static int decode_bcond(const ut16 instr, struct v810_cmd *cmd) {
194  st16 disp;
195  ut8 cond;
196 
197  cond = (instr >> 9) & 0xF;
198  disp = DISP9(instr);
199 
200  if (cond == V810_COND_NOP) {
201  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "nop");
202  } else {
203  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "b%s", conds[cond]);
204  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%d", disp);
205  }
206 
207  return 2;
208 }
209 
210 static int decode_jump(const ut16 word1, const ut16 word2, struct v810_cmd *cmd) {
211  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s",
212  instrs[OPCODE(word1)]);
213  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%d",
214  DISP26(word1, word2));
215 
216  return 4;
217 }
218 
219 static int decode_3operands(const ut16 word1, const ut16 word2, struct v810_cmd *cmd) {
220  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s",
221  instrs[OPCODE(word1)]);
222 
223  if (OPCODE(word1) == V810_ADDI) {
224  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "%d, r%d, r%d",
225  (st16)word2, REG1(word1), REG2(word1));
226  } else {
227  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "0x%x, r%d, r%d",
228  word2, REG1(word1), REG2(word1));
229  }
230 
231  return 4;
232 }
233 
234 static int decode_load_store(const ut16 word1, const ut16 word2, struct v810_cmd *cmd) {
235  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s",
236  instrs[OPCODE(word1)]);
237 
238  switch (OPCODE(word1)) {
239  case V810_STB:
240  case V810_STH:
241  case V810_STW:
242  case V810_OUTB:
243  case V810_OUTH:
244  case V810_OUTW:
245  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1,
246  "r%d, %hd[r%d]",
247  REG2(word1), (st16)word2, REG1(word1));
248  break;
249  case V810_LDB:
250  case V810_LDH:
251  case V810_LDW:
252  case V810_INB:
253  case V810_INH:
254  case V810_INW:
255  case V810_CAXI:
256  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1,
257  "%hd[r%d], r%d",
258  (st16)word2, REG1(word1), REG2(word1));
259  break;
260  }
261 
262  return 4;
263 }
264 
265 static int decode_bit_op(const ut16 instr, struct v810_cmd *cmd) {
266  ut8 subop;
267 
268  subop = REG1(instr);
269  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s", bit_instrs[subop]);
270 
271  return 2;
272 }
273 
274 static int decode_extended(const ut16 word1, const ut16 word2, struct v810_cmd *cmd) {
275  ut8 subop = OPCODE(word2);
276  if (subop > 0xC) {
277  return -1;
278  }
279 
280  snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s",
281  ext_instrs[subop]);
282 
283  switch (subop) {
284  case V810_EXT_CMPF_S:
285  case V810_EXT_CVT_WS:
286  case V810_EXT_CVT_SW:
287  case V810_EXT_ADDF_S:
288  case V810_EXT_SUBF_S:
289  case V810_EXT_MULF_S:
290  case V810_EXT_DIVF_S:
291  case V810_EXT_REV:
292  case V810_EXT_TRNC_SW:
293  case V810_EXT_MPYHW:
294  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "r%d, r%d",
295  REG1(word1), REG2(word1));
296  break;
297  case V810_EXT_XB:
298  case V810_EXT_XH:
299  snprintf(cmd->operands, V810_INSTR_MAXLEN - 1, "r%d",
300  REG2(word1));
301  break;
302  default:
303  return -1;
304  }
305 
306  return 4;
307 }
308 
309 int v810_decode_command(const ut8 *instr, int len, struct v810_cmd *cmd) {
310  int ret;
311  ut16 word1 = 0;
312  ut16 word2 = 0;
313 
314  word1 = rz_read_le16(instr);
315  if (len >= 4) {
316  word2 = rz_read_le16(instr + 2);
317  }
318 
319  switch (OPCODE(word1)) {
320  case V810_MOV:
321  case V810_ADD:
322  case V810_SUB:
323  case V810_CMP:
324  case V810_SHL:
325  case V810_SHR:
326  case V810_JMP:
327  case V810_SAR:
328  case V810_MUL:
329  case V810_DIV:
330  case V810_MULU:
331  case V810_DIVU:
332  case V810_OR:
333  case V810_AND:
334  case V810_NOT:
335  case V810_XOR:
336  ret = decode_reg_reg(word1, cmd);
337  break;
338  case V810_MOV_IMM5:
339  case V810_ADD_IMM5:
340  case V810_SETF:
341  case V810_CMP_IMM5:
342  case V810_SHL_IMM5:
343  case V810_SHR_IMM5:
344  case V810_CLI:
345  case V810_SAR_IMM5:
346  case V810_TRAP:
347  case V810_RETI:
348  case V810_HALT:
349  case V810_LDSR:
350  case V810_STSR:
351  case V810_SEI:
352  ret = decode_imm_reg(word1, cmd);
353  break;
354  case V810_MOVEA:
355  case V810_ADDI:
356  case V810_ORI:
357  case V810_ANDI:
358  case V810_XORI:
359  case V810_MOVHI:
360  ret = decode_3operands(word1, word2, cmd);
361  break;
362  case V810_JR:
363  case V810_JAL:
364  ret = decode_jump(word1, word2, cmd);
365  break;
366  case V810_LDB:
367  case V810_LDH:
368  case V810_LDW:
369  case V810_STB:
370  case V810_STH:
371  case V810_STW:
372  case V810_INB:
373  case V810_INH:
374  case V810_CAXI:
375  case V810_INW:
376  case V810_OUTB:
377  case V810_OUTH:
378  case V810_OUTW:
379  ret = decode_load_store(word1, word2, cmd);
380  break;
381  case V810_BSTR:
382  ret = decode_bit_op(word1, cmd);
383  break;
384  case V810_EXT:
385  ret = decode_extended(word1, word2, cmd);
386  break;
387  default:
388  if ((OPCODE(word1) >> 3) == 0x4) {
389  ret = decode_bcond(word1, cmd);
390  } else {
391  ret = -1;
392  }
393  }
394 
395  if ((ret > 0) && (len < ret)) {
396  ret = -1;
397  }
398 
399  return ret;
400 }
size_t len
Definition: 6502dis.c:15
#define OPCODE(word)
Definition: arc-dis.c:66
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint16_t ut16
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206
#define st8
Definition: rz_types_base.h:16
#define st16
Definition: rz_types_base.h:14
#define cond(bop, top, mask, flags)
static int decode_bit_op(const ut16 instr, struct v810_cmd *cmd)
Definition: v810_disas.c:265
static int decode_extended(const ut16 word1, const ut16 word2, struct v810_cmd *cmd)
Definition: v810_disas.c:274
static const char * instrs[]
Definition: v810_disas.c:9
static const char * ext_instrs[]
Definition: v810_disas.c:78
static const char * bit_instrs[]
Definition: v810_disas.c:63
static int decode_3operands(const ut16 word1, const ut16 word2, struct v810_cmd *cmd)
Definition: v810_disas.c:219
static int decode_bcond(const ut16 instr, struct v810_cmd *cmd)
Definition: v810_disas.c:193
static const char * conds[]
Definition: v810_disas.c:93
static const char * sysreg_names[]
Definition: v810_disas.c:111
int v810_decode_command(const ut8 *instr, int len, struct v810_cmd *cmd)
Definition: v810_disas.c:309
static int decode_imm_reg(const ut16 instr, struct v810_cmd *cmd)
Definition: v810_disas.c:146
static int decode_jump(const ut16 word1, const ut16 word2, struct v810_cmd *cmd)
Definition: v810_disas.c:210
static int decode_load_store(const ut16 word1, const ut16 word2, struct v810_cmd *cmd)
Definition: v810_disas.c:234
static int decode_reg_reg(const ut16 instr, struct v810_cmd *cmd)
Definition: v810_disas.c:124
#define V810_INSTR_MAXLEN
Definition: v810_disas.h:7
@ V810_SREG_FEPC
Definition: v810_disas.h:131
@ V810_SREG_FEPSW
Definition: v810_disas.h:132
@ V810_SREG_PIR
Definition: v810_disas.h:135
@ V810_SREG_ADTRE
Definition: v810_disas.h:138
@ V810_SREG_PSW
Definition: v810_disas.h:134
@ V810_SREG_ECR
Definition: v810_disas.h:133
@ V810_SREG_EIPC
Definition: v810_disas.h:129
@ V810_SREG_TKCW
Definition: v810_disas.h:136
@ V810_SREG_EIPSW
Definition: v810_disas.h:130
@ V810_SREG_CHCW
Definition: v810_disas.h:137
@ V810_MUL
Definition: v810_disas.h:31
@ V810_JMP
Definition: v810_disas.h:29
@ V810_TRAP
Definition: v810_disas.h:47
@ V810_STH
Definition: v810_disas.h:67
@ V810_HALT
Definition: v810_disas.h:49
@ V810_JR
Definition: v810_disas.h:57
@ V810_CLI
Definition: v810_disas.h:45
@ V810_LDW
Definition: v810_disas.h:65
@ V810_NOT
Definition: v810_disas.h:38
@ V810_DIV
Definition: v810_disas.h:32
@ V810_OUTW
Definition: v810_disas.h:76
@ V810_OR
Definition: v810_disas.h:35
@ V810_MULU
Definition: v810_disas.h:33
@ V810_JAL
Definition: v810_disas.h:58
@ V810_CMP
Definition: v810_disas.h:26
@ V810_XOR
Definition: v810_disas.h:37
@ V810_MOVEA
Definition: v810_disas.h:55
@ V810_STW
Definition: v810_disas.h:68
@ V810_DIVU
Definition: v810_disas.h:34
@ V810_INH
Definition: v810_disas.h:70
@ V810_EXT
Definition: v810_disas.h:75
@ V810_MOV_IMM5
Definition: v810_disas.h:39
@ V810_ADDI
Definition: v810_disas.h:56
@ V810_STSR
Definition: v810_disas.h:51
@ V810_OUTH
Definition: v810_disas.h:74
@ V810_CAXI
Definition: v810_disas.h:71
@ V810_BSTR
Definition: v810_disas.h:53
@ V810_LDSR
Definition: v810_disas.h:50
@ V810_SUB
Definition: v810_disas.h:25
@ V810_MOVHI
Definition: v810_disas.h:62
@ V810_SHL
Definition: v810_disas.h:27
@ V810_SETF
Definition: v810_disas.h:41
@ V810_SAR
Definition: v810_disas.h:30
@ V810_OUTB
Definition: v810_disas.h:73
@ V810_AND
Definition: v810_disas.h:36
@ V810_RETI
Definition: v810_disas.h:48
@ V810_ADD_IMM5
Definition: v810_disas.h:40
@ V810_LDH
Definition: v810_disas.h:64
@ V810_ADD
Definition: v810_disas.h:24
@ V810_SHR_IMM5
Definition: v810_disas.h:44
@ V810_LDB
Definition: v810_disas.h:63
@ V810_ORI
Definition: v810_disas.h:59
@ V810_STB
Definition: v810_disas.h:66
@ V810_ANDI
Definition: v810_disas.h:60
@ V810_CMP_IMM5
Definition: v810_disas.h:42
@ V810_INB
Definition: v810_disas.h:69
@ V810_INW
Definition: v810_disas.h:72
@ V810_SHL_IMM5
Definition: v810_disas.h:43
@ V810_XORI
Definition: v810_disas.h:61
@ V810_MOV
Definition: v810_disas.h:23
@ V810_SEI
Definition: v810_disas.h:52
@ V810_SHR
Definition: v810_disas.h:28
@ V810_SAR_IMM5
Definition: v810_disas.h:46
#define REG1(instr)
Definition: v810_disas.h:10
#define SIGN_EXT_T5(imm)
Definition: v810_disas.h:15
#define IMM5(instr)
Definition: v810_disas.h:12
#define DISP9(word1)
Definition: v810_disas.h:19
#define REG2(instr)
Definition: v810_disas.h:11
#define DISP26(word1, word2)
Definition: v810_disas.h:20
@ V810_EXT_CMPF_S
Definition: v810_disas.h:95
@ V810_EXT_TRNC_SW
Definition: v810_disas.h:105
@ V810_EXT_REV
Definition: v810_disas.h:104
@ V810_EXT_CVT_WS
Definition: v810_disas.h:96
@ V810_EXT_XH
Definition: v810_disas.h:103
@ V810_EXT_XB
Definition: v810_disas.h:102
@ V810_EXT_SUBF_S
Definition: v810_disas.h:99
@ V810_EXT_ADDF_S
Definition: v810_disas.h:98
@ V810_EXT_CVT_SW
Definition: v810_disas.h:97
@ V810_EXT_DIVF_S
Definition: v810_disas.h:101
@ V810_EXT_MPYHW
Definition: v810_disas.h:106
@ V810_EXT_MULF_S
Definition: v810_disas.h:100
@ V810_COND_NE
Definition: v810_disas.h:120
@ V810_COND_NONE
Definition: v810_disas.h:115
@ V810_COND_GT
Definition: v810_disas.h:125
@ V810_COND_E
Definition: v810_disas.h:112
@ V810_COND_NOP
Definition: v810_disas.h:123
@ V810_COND_H
Definition: v810_disas.h:121
@ V810_COND_LE
Definition: v810_disas.h:117
@ V810_COND_V
Definition: v810_disas.h:110
@ V810_COND_GE
Definition: v810_disas.h:124
@ V810_COND_NL
Definition: v810_disas.h:119
@ V810_COND_N
Definition: v810_disas.h:114
@ V810_COND_NH
Definition: v810_disas.h:113
@ V810_COND_NV
Definition: v810_disas.h:118
@ V810_COND_L
Definition: v810_disas.h:111
@ V810_COND_LT
Definition: v810_disas.h:116
@ V810_COND_P
Definition: v810_disas.h:122
@ V810_BIT_SCH0D
Definition: v810_disas.h:81
@ V810_BIT_ORU
Definition: v810_disas.h:84
@ V810_BIT_SCH0U
Definition: v810_disas.h:80
@ V810_BIT_ORNU
Definition: v810_disas.h:88
@ V810_BIT_SCH1D
Definition: v810_disas.h:83
@ V810_BIT_SCH1U
Definition: v810_disas.h:82
@ V810_BIT_MOVU
Definition: v810_disas.h:87
@ V810_BIT_XORU
Definition: v810_disas.h:86
@ V810_BIT_NOTU
Definition: v810_disas.h:91
@ V810_BIT_ANDNU
Definition: v810_disas.h:89
@ V810_BIT_XORNU
Definition: v810_disas.h:90
@ V810_BIT_ANDU
Definition: v810_disas.h:85