Rizin
unix-like reverse engineering framework and cli tools
analysis_sh.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2010-2013 eloi <limited-entropy.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <string.h>
5 #include <rz_types.h>
6 #include <rz_lib.h>
7 #include <rz_asm.h>
8 #include <rz_analysis.h>
9 #include "../arch/sh/sh_il.h"
10 
11 #define API static
12 
13 #define LONG_SIZE 4
14 #define WORD_SIZE 2
15 #define BYTE_SIZE 1
16 
17 /*
18  * all processor instructions are implemented, but all FPU are missing
19  * DIV1,MAC.W,MAC.L,rte,rts should be checked
20  * also tests are written, but still could be some issues, if I misunderstand instructions.
21  * If you found some bugs, please open an issue
22  */
23 
24 #define BIT_32(x) x ",0x80000000,&"
25 #define S16_EXT(x) x ",DUP,0x8000,&,?{,0xFFFFFFFFFFFF0000,|,}"
26 #define S32_EXT(x) x ",DUP,0x80000000,&,?{,0xFFFFFFFF00000000,|,}"
27 #define IS_T "sr,0x1,&,"
28 #define SET_T "0x1,sr,|="
29 #define CLR_T "0xFFFFFFFE,sr,&="
30 // Macros for different instruction types
31 
32 #define IS_CLRT(x) x == 0x0008
33 #define IS_NOP(x) x == 0x0009
34 #define IS_RTS(x) x == 0x000b
35 #define IS_SETT(x) x == 0x0018
36 #define IS_DIV0U(x) x == 0x0019
37 #define IS_SLEEP(x) x == 0x001b
38 #define IS_CLRMAC(x) x == 0x0028
39 #define IS_RTE(x) x == 0x002b
40 
41 #define IS_STCSR1(x) (((x)&0xF0CF) == 0x0002) // mask stc Rn,{SR,gbr,VBR,SSR}
42 #define IS_BSRF(x) ((x)&0xf0ff) == 0x0003
43 #define IS_BRAF(x) (((x)&0xf0ff) == 0x0023)
44 #define IS_MOVB_REG_TO_R0REL(x) (((x)&0xF00F) == 0x0004)
45 #define IS_MOVW_REG_TO_R0REL(x) (((x)&0xF00F) == 0x0005)
46 #define IS_MOVL_REG_TO_R0REL(x) (((x)&0xF00F) == 0x0006)
47 #define IS_MULL(x) (((x)&0xF00F) == 0x0007)
48 #define IS_MOVB_R0REL_TO_REG(x) (((x)&0xF00F) == 0x000C)
49 #define IS_MOVW_R0REL_TO_REG(x) (((x)&0xF00F) == 0x000D)
50 #define IS_MOVL_R0REL_TO_REG(x) (((x)&0xF00F) == 0x000E)
51 #define IS_MACL(x) (((x)&0xF00F) == 0x000F)
52 #define IS_MOVT(x) (((x)&0xF0FF) == 0x0029)
53 #define IS_STSMACH(x) (((x)&0xF0FF) == 0x000A)
54 #define IS_STSMACL(x) (((x)&0xF0FF) == 0x001A)
55 #define IS_STSPR(x) (((x)&0xF0FF) == 0x002A)
56 //#define IS_STSFPUL(x) (((x) & 0xF0FF) == 0x005A) //FP*: todo maybe someday
57 //#define IS_STSFPSCR(x) (((x) & 0xF0FF) == 0x006A)
58 #define IS_MOVB_REG_TO_REGREF(x) (((x)&0xF00F) == 0x2000)
59 #define IS_MOVW_REG_TO_REGREF(x) (((x)&0xF00F) == 0x2001)
60 #define IS_MOVL_REG_TO_REGREF(x) (((x)&0xF00F) == 0x2002)
61 //#define invalid?(x) (((x) & 0xF00F) == 0x2003) //illegal on sh2e
62 #define IS_PUSHB(x) (((x)&0xF00F) == 0x2004)
63 #define IS_PUSHW(x) (((x)&0xF00F) == 0x2005)
64 #define IS_PUSHL(x) (((x)&0xF00F) == 0x2006)
65 #define IS_DIV0S(x) (((x)&0xF00F) == 0x2007)
66 #define IS_TSTRR(x) (((x)&0xF00F) == 0x2008)
67 #define IS_AND_REGS(x) (((x)&0xF00F) == 0x2009)
68 #define IS_XOR_REGS(x) (((x)&0xF00F) == 0x200A)
69 #define IS_OR_REGS(x) (((x)&0xF00F) == 0x200B)
70 #define IS_CMPSTR(x) (((x)&0xF00F) == 0x200C)
71 #define IS_XTRCT(x) (((x)&0xF00F) == 0x200D)
72 #define IS_MULUW(x) (((x)&0xF00F) == 0x200E)
73 #define IS_MULSW(x) (((x)&0xF00F) == 0x200F)
74 #define IS_CMPEQ(x) (((x)&0xF00F) == 0x3000)
75 //#define invalid?(x) (((x) & 0xF00F) == 0x3001)
76 #define IS_CMPHS(x) (((x)&0xF00F) == 0x3002)
77 #define IS_CMPGE(x) (((x)&0xF00F) == 0x3003)
78 #define IS_CMPHI(x) (((x)&0xF00F) == 0x3006)
79 #define IS_CMPGT(x) (((x)&0xF00F) == 0x3007)
80 #define IS_DIV1(x) (((x)&0xF00F) == 0x3004)
81 #define IS_DMULU(x) (((x)&0xF00F) == 0x3005)
82 #define IS_DMULS(x) (((x)&0xF00F) == 0x300D)
83 #define IS_SUB(x) (((x)&0xF00F) == 0x3008)
84 //#define invalid?(x) (((x) & 0xF00F) == 0x3009)
85 #define IS_SUBC(x) (((x)&0xF00F) == 0x300A)
86 #define IS_SUBV(x) (((x)&0xF00F) == 0x300B)
87 #define IS_ADD(x) (((x)&0xF00F) == 0x300C)
88 #define IS_ADDC(x) (((x)&0xF00F) == 0x300E)
89 #define IS_ADDV(x) (((x)&0xF00F) == 0x300F)
90 #define IS_MACW(x) (((x)&0xF00F) == 0x400F)
91 #define IS_JSR(x) (((x)&0xf0ff) == 0x400b)
92 #define IS_JMP(x) (((x)&0xf0ff) == 0x402b)
93 #define IS_CMPPL(x) (((x)&0xf0ff) == 0x4015)
94 #define IS_CMPPZ(x) (((x)&0xf0ff) == 0x4011)
95 #define IS_LDCSR(x) (((x)&0xF0FF) == 0x400E)
96 #define IS_LDCGBR(x) (((x)&0xF0FF) == 0x401E)
97 #define IS_LDCVBR(x) (((x)&0xF0FF) == 0x402E)
98 #define IS_LDCLSR(x) (((x)&0xF0FF) == 0x4007)
99 #define IS_LDCLSRGBR(x) (((x)&0xF0FF) == 0x4017)
100 #define IS_LDCLSRVBR(x) (((x)&0xF0FF) == 0x4027)
101 #define IS_LDSMACH(x) (((x)&0xF0FF) == 0x400A)
102 #define IS_LDSMACL(x) (((x)&0xF0FF) == 0x401A)
103 #define IS_LDSLMACH(x) (((x)&0xF0FF) == 0x4006)
104 #define IS_LDSLMACL(x) (((x)&0xF0FF) == 0x4016)
105 #define IS_LDSPR(x) (((x)&0xF0FF) == 0x402A)
106 #define IS_LDSLPR(x) (((x)&0xF0FF) == 0x4026)
107 //#define IS_LDSFPUL(x) (((x) & 0xF0FF) == 0x405A) //FP*: todo maybe someday
108 //#define IS_LDSFPSCR(x) (((x) & 0xF0FF) == 0x406A)
109 //#define IS_LDSLFPUL(x) (((x) & 0xF0FF) == 0x4066)
110 //#define IS_LDSLFPSCR(x) (((x) & 0xF0FF) == 0x4056)
111 #define IS_ROTCR(x) (((x)&0xF0FF) == 0x4025)
112 #define IS_ROTCL(x) (((x)&0xF0FF) == 0x4024)
113 #define IS_ROTL(x) (((x)&0xF0FF) == 0x4004)
114 #define IS_ROTR(x) (((x)&0xF0FF) == 0x4005)
115 // not on sh2e : shad, shld
116 
117 //#define IS_SHIFT1(x) (((x) & 0xF0DE) == 0x4000) //unused (treated as switch-case)
118 // other shl{l,r}{,2,8,16} in switch case also.
119 
120 #define IS_STSLMACL(x) (((x)&0xF0FF) == 0x4012)
121 #define IS_STSLMACH(x) (((x)&0xF0FF) == 0x4002)
122 #define IS_STCLSR(x) (((x)&0xF0FF) == 0x4003)
123 #define IS_STCLGBR(x) (((x)&0xF0FF) == 0x4013)
124 #define IS_STCLVBR(x) (((x)&0xF0FF) == 0x4023)
125 // todo: other stc.l not on sh2e
126 #define IS_STSLPR(x) (((x)&0xF0FF) == 0x4022)
127 //#define IS_STSLFPUL(x) (((x) & 0xF0FF) == 0x4052)
128 //#define IS_STSLFPSCR(x) (((x) & 0xF0FF) == 0x4062)
129 #define IS_TASB(x) (((x)&0xF0FF) == 0x401B)
130 #define IS_DT(x) (((x)&0xF0FF) == 0x4010)
131 
132 #define IS_MOVB_REGREF_TO_REG(x) (((x)&0xF00F) == 0x6000)
133 #define IS_MOVW_REGREF_TO_REG(x) (((x)&0xF00F) == 0x6001)
134 #define IS_MOVL_REGREF_TO_REG(x) (((x)&0xF00F) == 0x6002)
135 #define IS_MOV_REGS(x) (((x)&0xf00f) == 0x6003)
136 #define IS_MOVB_POP(x) (((x)&0xF00F) == 0x6004)
137 #define IS_MOVW_POP(x) (((x)&0xF00F) == 0x6005)
138 #define IS_MOVL_POP(x) (((x)&0xF00F) == 0x6006)
139 #define IS_NOT(x) (((x)&0xF00F) == 0x6007)
140 #define IS_SWAPB(x) (((x)&0xF00F) == 0x6008)
141 #define IS_SWAPW(x) (((x)&0xF00F) == 0x6009)
142 #define IS_NEG(x) (((x)&0xF00F) == 0x600B)
143 #define IS_NEGC(x) (((x)&0xF00F) == 0x600A)
144 #define IS_EXT(x) (((x)&0xF00C) == 0x600C) // match ext{s,u}.{b,w}
145 
146 #define IS_MOVB_R0_REGDISP(x) (((x)&0xFF00) == 0x8000)
147 #define IS_MOVW_R0_REGDISP(x) (((x)&0xFF00) == 0x8100)
148 //#define illegal?(x) (((x) & 0xF900) == 0x8000) //match 8{2,3,6,7}00
149 #define IS_MOVB_REGDISP_R0(x) (((x)&0xFF00) == 0x8400)
150 #define IS_MOVW_REGDISP_R0(x) (((x)&0xFF00) == 0x8500)
151 #define IS_CMPIMM(x) (((x)&0xFF00) == 0x8800)
152 //#define illegal?(x) (((x) & 0xFB00) == 0x8A00) //match 8{A,E}00
153 #define IS_BT(x) (((x)&0xff00) == 0x8900)
154 #define IS_BF(x) (((x)&0xff00) == 0x8B00)
155 #define IS_BTS(x) (((x)&0xff00) == 0x8D00)
156 #define IS_BFS(x) (((x)&0xff00) == 0x8F00)
157 #define IS_BT_OR_BF(x) IS_BT(x) || IS_BTS(x) || IS_BF(x) || IS_BFS(x)
158 
159 #define IS_MOVB_R0_GBRREF(x) (((x)&0xFF00) == 0xC000)
160 #define IS_MOVW_R0_GBRREF(x) (((x)&0xFF00) == 0xC100)
161 #define IS_MOVL_R0_GBRREF(x) (((x)&0xFF00) == 0xC200)
162 #define IS_TRAP(x) (((x)&0xFF00) == 0xC300)
163 #define IS_MOVB_GBRREF_R0(x) (((x)&0xFF00) == 0xC400)
164 #define IS_MOVW_GBRREF_R0(x) (((x)&0xFF00) == 0xC500)
165 #define IS_MOVL_GBRREF_R0(x) (((x)&0xFF00) == 0xC600)
166 #define IS_MOVA_PCREL_R0(x) (((x)&0xFF00) == 0xC700)
167 #define IS_BINLOGIC_IMM_R0(x) (((x)&0xFC00) == 0xC800) // match C{8,9,A,B}00
168 #define IS_BINLOGIC_IMM_GBR(x) (((x)&0xFC00) == 0xCC00) // match C{C,D,E,F}00 : *.b #imm, @(R0,gbr)
169 
170 /* Compute PC-relative displacement for branch instructions */
171 #define GET_BRA_OFFSET(x) ((x)&0x0fff)
172 #define GET_BTF_OFFSET(x) ((x)&0x00ff)
173 
174 /* Compute reg nr for BRAF,BSR,BSRF,JMP,JSR */
175 #define GET_TARGET_REG(x) (((x) >> 8) & 0x0f)
176 #define GET_SOURCE_REG(x) (((x) >> 4) & 0x0f)
177 
178 /* index of PC reg in regs[] array*/
179 #define PC_IDX 16
180 
181 /* for {bra,bsr} only: (sign-extend 12bit offset)<<1 + PC +4 */
182 static ut64 disarm_12bit_offset(RzAnalysisOp *op, unsigned int insoff) {
183  ut64 off = insoff;
184  /* sign extend if higher bit is 1 (0x0800) */
185  if ((off & 0x0800) == 0x0800) {
186  off |= ~0xFFF;
187  }
188  return (op->addr) + (off << 1) + 4;
189 }
190 
191 /* for bt,bf sign-extended offsets : return PC+4+ (exts.b offset)<<1 */
193  /* pc (really, op->addr) is 64 bits, so we need to sign-extend
194  * to 64 bits instead of the 32 the actual CPU does */
195  ut64 off = offs;
196  /* sign extend if higher bit is 1 (0x08) */
197  if ((off & 0x80) == 0x80) {
198  off |= ~0xFF;
199  }
200  return (off << 1) + pc + 4;
201 }
202 
203 static char *regs[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "pc" };
204 
207  ret->type = RZ_ANALYSIS_VAL_REG;
208  ret->reg = rz_reg_get(analysis->reg, regs[idx], RZ_REG_TYPE_GPR);
209  return ret;
210 }
211 
214  ret->type = RZ_ANALYSIS_VAL_IMM;
215  ret->imm = v;
216  return ret;
217 }
218 
219 /* Implements @(disp,Rn) , size=1 for .b, 2 for .w, 4 for .l */
221  RzAnalysisValue *ret = analysis_fill_ai_rg(analysis, reg);
222  ret->type = RZ_ANALYSIS_VAL_MEM;
223  ret->memref = size;
224  ret->delta = delta * size;
225  return ret;
226 }
227 
228 /* Rn */
230  RzAnalysisValue *ret = analysis_fill_ai_rg(analysis, reg);
231  ret->type = RZ_ANALYSIS_VAL_MEM;
232  ret->memref = size;
233  return ret;
234 }
235 
236 /* @(R0,Rx) references for all sizes */
238  RzAnalysisValue *ret = analysis_fill_ai_rg(analysis, 0);
239  ret->type = RZ_ANALYSIS_VAL_MEM;
240  ret->regdelta = rz_reg_get(analysis->reg, regs[reg], RZ_REG_TYPE_GPR);
241  ret->memref = size;
242  return ret;
243 }
244 
245 // @(disp,PC) for size=2(.w), size=4(.l). disp is 0-extended
248  ret->type = RZ_ANALYSIS_VAL_MEM;
249  if (size == 2) {
250  ret->base = op->addr + 4;
251  ret->delta = disp << 1;
252  } else {
253  ret->base = (op->addr + 4) & ~0x03;
254  ret->delta = disp << 2;
255  }
256  ret->memref = size;
257  return ret;
258 }
259 
260 //= PC+4+R<reg>
263  ret->type = RZ_ANALYSIS_VAL_REG;
264  ret->reg = rz_reg_get(analysis->reg, regs[reg], RZ_REG_TYPE_GPR);
265  ret->base = op->addr + 4;
266  return ret;
267 }
268 
269 /* 16 decoder routines, based on 1st nibble value */
270 static int first_nibble_is_0(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) { // STOP
271  if (IS_BSRF(code)) {
272  /* Call 'far' subroutine Rn+PC+4 */
274  op->delay = 1;
275  op->dst = analysis_regrel_jump(analysis, op, GET_TARGET_REG(code));
276  rz_strbuf_setf(&op->esil, "1,SETD,pc,2,+,pr,=,r%d,2,+,pc,+=", GET_TARGET_REG(code));
277  } else if (IS_BRAF(code)) {
279  op->dst = analysis_regrel_jump(analysis, op, GET_TARGET_REG(code));
280  op->eob = true;
281  op->delay = 1;
282  rz_strbuf_setf(&op->esil, "1,SETD,r%d,2,+,pc,+=", GET_TARGET_REG(code));
283  } else if (IS_RTS(code)) {
284  op->type = RZ_ANALYSIS_OP_TYPE_RET;
285  op->delay = 1;
286  op->eob = true;
287  rz_strbuf_setf(&op->esil, "pr,pc,=");
288  } else if (IS_RTE(code)) {
289  op->type = RZ_ANALYSIS_OP_TYPE_RET;
290  op->delay = 1;
291  op->eob = true;
292  // rz_strbuf_setf (&op->esil, "1,SETD,r15,[4],4,+,pc,=,r15,4,+,[4],0xFFF0FFF,&,sr,=,8,r15,+=");
293  // not sure if should be added 4 to pc
294  rz_strbuf_setf(&op->esil, "1,SETD,r15,[4],pc,=,r15,4,+,[4],0xFFF0FFF,&,sr,=,8,r15,+=");
295  } else if (IS_MOVB_REG_TO_R0REL(code)) { // 0000nnnnmmmm0100 mov.b <REG_M>,@(R0,<REG_N>)
297  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
299  rz_strbuf_setf(&op->esil, "r%d,0xFF,&,r0,r%d,+,=[1]", GET_SOURCE_REG(code), GET_TARGET_REG(code));
300  } else if (IS_MOVW_REG_TO_R0REL(code)) {
302  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
304  rz_strbuf_setf(&op->esil, "r%d,0xFFFF,&,r0,r%d,+,=[2]", GET_SOURCE_REG(code), GET_TARGET_REG(code));
305  } else if (IS_MOVL_REG_TO_R0REL(code)) {
307  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
309  rz_strbuf_setf(&op->esil, "r%d,r0,r%d,+,=[4]", GET_SOURCE_REG(code), GET_TARGET_REG(code));
310  } else if (IS_MOVB_R0REL_TO_REG(code)) {
313  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
314  rz_strbuf_setf(&op->esil, "r0,r%d,+,[1],r%d,=,0x000000FF,r%d,&=,r%d,0x80,&,?{,0xFFFFFF00,r%d,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
315  } else if (IS_MOVW_R0REL_TO_REG(code)) {
318  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
319  rz_strbuf_setf(&op->esil, "r0,r%d,+,[2],r%d,=,0x0000FFFF,r%d,&=,r%d,0x8000,&,?{,0xFFFF0000,r%d,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
320  } else if (IS_MOVL_R0REL_TO_REG(code)) {
323  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
324  rz_strbuf_setf(&op->esil, "r0,r%d,+,[4],r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
325  } else if (IS_NOP(code)) {
326  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
327  rz_strbuf_setf(&op->esil, " ");
328  } else if (IS_CLRT(code)) {
329  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
330  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=");
331  } else if (IS_SETT(code)) {
332  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
333  rz_strbuf_setf(&op->esil, "0x1,sr,|=");
334  } else if (IS_CLRMAC(code)) {
335  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
336  rz_strbuf_setf(&op->esil, "0,mach,=,0,macl,=");
337  } else if (IS_DIV0U(code)) {
338  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
339  rz_strbuf_setf(&op->esil, "0xFFFFFCFE,sr,&=");
340  } else if (IS_MOVT(code)) {
341  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
342  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
343  rz_strbuf_setf(&op->esil, "0x1,sr,&,r%d,=", GET_TARGET_REG(code));
344  } else if (IS_MULL(code)) { // multiply long
345  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
346  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
347  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
348  rz_strbuf_setf(&op->esil, "r%d,r%d,*,macl,=", GET_TARGET_REG(code), GET_SOURCE_REG(code));
349  } else if (IS_SLEEP(code)) {
350  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
351  rz_strbuf_setf(&op->esil, "sleep_called,TRAP");
352  } else if (IS_STSMACH(code)) { // 0000nnnn0000101_ sts MAC*,<REG_N>
353  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
354  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
355  rz_strbuf_setf(&op->esil, "mach,r%d,=", GET_TARGET_REG(code));
356  } else if (IS_STSMACL(code)) { // 0000nnnn0000101_ sts MAC*,<REG_N>
357  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
358  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
359  rz_strbuf_setf(&op->esil, "macl,r%d,=", GET_TARGET_REG(code));
360  } else if (IS_STSLMACL(code)) {
361  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
362  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
363  rz_strbuf_setf(&op->esil, "macl,r%d,=", GET_TARGET_REG(code));
364  } else if (IS_STCSR1(code)) { // 0000nnnn00010010 stc {sr,gbr,vbr,ssr},<REG_N>
365  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
366  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
367  // todo: plug in src
368  switch (GET_SOURCE_REG(code)) {
369  case 0:
370  rz_strbuf_setf(&op->esil, "sr,r%d,=", GET_TARGET_REG(code));
371  break;
372  case 1:
373  rz_strbuf_setf(&op->esil, "gbr,r%d,=", GET_TARGET_REG(code));
374  break;
375  case 2:
376  rz_strbuf_setf(&op->esil, "vbr,r%d,=", GET_TARGET_REG(code));
377  break;
378  default:
379  rz_strbuf_setf(&op->esil, "%s", "");
380  break;
381  }
382  } else if (IS_STSPR(code)) { // 0000nnnn00101010 sts PR,<REG_N>
383  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
384  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
385  rz_strbuf_setf(&op->esil, "pr,r%d,=", GET_TARGET_REG(code));
386  } else if (IS_MACL(code)) {
387  rz_strbuf_setf(&op->esil,
388  "mach,0x80000000,&,!," // mach_old sign (0)
389  S32_EXT("r%d,[4]") "," //@Rn sign extended
390  S32_EXT("r%d,[4]") "," //@Rm sign extended
391  "*," //(1)
392  "macl,32,mach,<<,|," // macl | (mach << 32)
393  "+," // MAC+@Rm*@Rn
394  "32," S32_EXT("r%d,[4]") "," //@Rn sign extended
395  S32_EXT("r%d,[4]") "," //@Rm sign extended
396  "*,"
397  "4,r%d,+=," // Rn+=4
398  "4,r%d,+=," // Rm+=4
399  "0xffffffff00000000,&,>>,mach,=," // MACH > mach
400  "0xffffffff,&,macl,=,"
401  "0x2,sr,&,!,?{,BREAK,}," // if S==0 BREAK
402  "0x00007fff,mach,>,"
403  "0x80000000,mach,&,!,&,"
404  "?{,0x00007fff,mach,=,0xffffffff,macl,=,}," // if (mach>0x00007fff&&mach>0) mac=0x00007fffffffffff
405  "0xffff8000,mach,<,"
406  "0x80000000,mach,&,!,!,&,"
407  "?{,0xffff8000,mach,=,0x0,macl,=,}," // if (mach>0xffff8000&&mach<0) mac=0xffff800000000000
408  ,
412  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
413  }
414  return op->size;
415 }
416 
417 // nibble=1; 0001nnnnmmmmi4*4 mov.l <REG_M>,@(<disp>,<REG_N>)
418 static int movl_reg_rdisp(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
420  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
421  op->dst = analysis_fill_reg_disp_mem(analysis, GET_TARGET_REG(code), code & 0x0F, LONG_SIZE);
422  rz_strbuf_setf(&op->esil, "r%d,r%d,0x%x,+,=[4]", GET_SOURCE_REG(code), GET_TARGET_REG(code), (code & 0xF) << 2);
423  return op->size;
424 }
425 
427  if (IS_MOVB_REG_TO_REGREF(code)) { // 0010nnnnmmmm0000 mov.b <REG_M>,@<REG_N>
429  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
431  rz_strbuf_setf(&op->esil, "r%d,r%d,=[1]", GET_SOURCE_REG(code), GET_TARGET_REG(code));
432  } else if (IS_MOVW_REG_TO_REGREF(code)) {
434  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
436  rz_strbuf_setf(&op->esil, "r%d,r%d,=[2]", GET_SOURCE_REG(code) & 0xFF, GET_TARGET_REG(code));
437  } else if (IS_MOVL_REG_TO_REGREF(code)) {
439  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
441  rz_strbuf_setf(&op->esil, "r%d,r%d,=[4]", GET_SOURCE_REG(code) & 0xFF, GET_TARGET_REG(code));
442  } else if (IS_AND_REGS(code)) {
443  op->type = RZ_ANALYSIS_OP_TYPE_AND;
444  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
445  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
446  rz_strbuf_setf(&op->esil, "r%d,r%d,&=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
447  } else if (IS_XOR_REGS(code)) {
448  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
449  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
450  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
451  rz_strbuf_setf(&op->esil, "r%d,r%d,^=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
452  } else if (IS_OR_REGS(code)) {
453  op->type = RZ_ANALYSIS_OP_TYPE_OR;
454  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
455  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
456  rz_strbuf_setf(&op->esil, "r%d,r%d,|=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
457  } else if (IS_PUSHB(code)) {
459  rz_strbuf_setf(&op->esil, "1,r%d,-=,r%d,r%d,=[1]", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
460  } else if (IS_PUSHW(code)) {
462  rz_strbuf_setf(&op->esil, "2,r%d,-=,r%d,r%d,=[2]", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
463  } else if (IS_PUSHL(code)) {
465  rz_strbuf_setf(&op->esil, "4,r%d,-=,r%d,r%d,=[4]", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
466  } else if (IS_TSTRR(code)) {
468  rz_strbuf_setf(&op->esil, "1,sr,|=,r%d,r%d,&,?{,0xFFFFFFFE,sr,&=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code));
469  } else if (IS_CMPSTR(code)) { // 0010nnnnmmmm1100 cmp/str <REG_M>,<REG_N>
470  op->type = RZ_ANALYSIS_OP_TYPE_ACMP; // maybe not?
471  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
472  op->src[1] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
473  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,24,r%d,r%d,^,>>,0xFF,&,!,?{,1,sr,|=,},16,r%d,r%d,^,>>,0xFF,&,!,?{,1,sr,|=,},8,r%d,r%d,^,>>,0xFF,&,!,?{,1,sr,|=,},r%d,r%d,^,0xFF,&,!,?{,1,sr,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
474  } else if (IS_XTRCT(code)) { // 0010nnnnmmmm1101 xtrct <REG_M>,<REG_N>
475  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
476  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
477  op->src[1] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
478  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
479  rz_strbuf_setf(&op->esil, "16,r%d,0xFFFF,&,<<,16,r%d,0xFFFF0000,&,>>,|,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
480  } else if (IS_DIV0S(code)) {
481  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
482  rz_strbuf_setf(&op->esil, "0xFFFFFCFE,sr,&=,r%d,0x80000000,&,?{,0x200,sr,|=,},r%d,0x80000000,&,?{,0x100,sr,|=,},sr,1,sr,<<,^,0x200,&,?{,1,sr,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code));
483  } else if (IS_MULUW(code)) {
484  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
485  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
486  op->src[1] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
487  rz_strbuf_setf(&op->esil, "r%d,0xFFFF,&,r%d,0xFFFF,&,*,macl,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
488  } else if (IS_MULSW(code)) { // 0010nnnnmmmm111_ mul{s,u}.w <REG_M>,<REG_N>
489  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
490  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
491  op->src[1] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
492  rz_strbuf_setf(&op->esil, S16_EXT("r%d") "," S16_EXT("r%d") ",*,macl,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
493  }
494 
495  return op->size;
496 }
497 
499  // TODO Handle carry/overflow , CMP/xx?
500  if (IS_ADD(code)) {
501  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
502  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
503  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
504  rz_strbuf_setf(&op->esil, "r%d,r%d,+=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
505  } else if (IS_ADDC(code)) {
506  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
507  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
508  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
509  rz_strbuf_setf(&op->esil, "sr,0x1,&,0xFFFFFFFE,sr,&=,r%d,+=,31,$c,sr,|,sr,:=,r%d,r%d,+=,31,$c,sr,|,sr,:=", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
510  } else if (IS_ADDV(code)) {
511  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
512  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
513  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
514  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,r%d,+=,31,$o,sr,|=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
515  } else if (IS_SUB(code)) {
516  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
517  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
518  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
519  rz_strbuf_setf(&op->esil, "r%d,r%d,-=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
520  } else if (IS_SUBC(code)) {
521  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
522  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
523  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
524  rz_strbuf_setf(&op->esil, "sr,1,&," CLR_T ",r%d,-=,31,$b,sr,|,sr,:=,r%d,r%d,-=,31,$b,sr,|,sr,:=", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
525  } else if (IS_SUBV(code)) {
526  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
527  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
528  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
529  rz_strbuf_setf(&op->esil, CLR_T ",r%d,r%d,-=,31,$o,sr,|,sr,:=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
530  } else if (IS_CMPEQ(code)) {
531  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
532  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
533  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
534  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&,r%d,r%d,^,!,|,sr,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
535  } else if (IS_CMPGE(code)) {
536  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
537  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
538  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
539  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,r%d,>=,?{,0x1,sr,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code));
540  } else if (IS_CMPGT(code)) {
541  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
542  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
543  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
544  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,r%d,>,?{,0x1,sr,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code));
545  } else if (IS_CMPHI(code)) {
546  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
547  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
548  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
549  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x100000000,+,r%d,0x100000000,+,>,?{,0x1,sr,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code));
550  } else if (IS_CMPHS(code)) {
551  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
552  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
553  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
554  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x100000000,+,r%d,0x100000000,+,>=,?{,0x1,sr,|=,}", GET_SOURCE_REG(code), GET_TARGET_REG(code));
555  } else if (IS_DIV1(code)) {
556  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
557  op->src[0] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
558  op->src[1] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
559  rz_strbuf_setf(&op->esil,
560  "1,sr,>>,sr,^,0x80,&," // old_Q^M
561  "0xFFFFFF7F,sr,&=,"
562  "1,r%d,DUP,0x80000000,&,?{,0x80,sr,|=,},<<,sr,0x1,&,|,r%d,=," // shift Q<-Rn<-T
563  "DUP,!,!,?{,"
564  "r%d,NUM," // Rn_old (before subtract)
565  "r%d,r%d,+=,"
566  "r%d,<,}{," // tmp0
567  "r%d,NUM," // Rn_old (before subtract)
568  "r%d,r%d,-=,"
569  "r%d,>,}," // tmp0
570  "sr,0x80,&,!,!,^," // Q^tmp0
571  "sr,0x100,&,?{,!,}," // if (M) !(Q^tmp0)
572  "0xFFFFFF7F,sr,&=," // Q==0
573  "?{,0x80,sr,|=,}," // Q=!(Q^tmp0)or(Q^tmp0)
574  CLR_T ","
575  "1,sr,>>,sr,^,0x80,&,!,sr,|=", // sr=!Q^M
583  } else if (IS_DMULU(code)) {
584  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
585  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
586  op->src[1] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
587  rz_strbuf_setf(&op->esil, "32,r%d,r%d,*,DUP,0xFFFFFFFF,&,macl,=,>>,mach,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
588  } else if (IS_DMULS(code)) {
589  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
590  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
591  op->src[1] = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
592  rz_strbuf_setf(&op->esil, "32,r%d,r%d,0x80000000,&,?{,0xFFFFFFFF00000000,+,},r%d,r%d,0x80000000,&,?{,0xFFFFFFFF00000000,+,},*,DUP,0xFFFFFFFF,&,macl,=,>>,mach,=", GET_SOURCE_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
593  }
594  return op->size;
595 }
596 
598  switch (code & 0xF0FF) { // TODO: change to common } else if construction
599  case 0x4020: // shal
600  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
601  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x80000000,&,?{,0x1,sr,|=,},1,r%d,<<=", GET_TARGET_REG(code), GET_TARGET_REG(code));
602  break;
603  case 0x4021: // shar
604  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
605  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x1,&,?{,0x1,sr,|=,},0,r%d,0x80000000,&,?{,0x80000000,+,},1,r%d,>>=,r%d,|=", GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
606  break;
607  case 0x4000: // shll
608  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
609  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x80000000,&,?{,0x1,sr,|=,},1,r%d,<<=", GET_TARGET_REG(code), GET_TARGET_REG(code));
610  break;
611  case 0x4008: // shll2
612  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
613  rz_strbuf_setf(&op->esil, "2,r%d,<<=", GET_TARGET_REG(code));
614  break;
615  case 0x4018: // shll8
616  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
617  rz_strbuf_setf(&op->esil, "8,r%d,<<=", GET_TARGET_REG(code));
618  break;
619  case 0x4028: // shll16
620  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
621  rz_strbuf_setf(&op->esil, "16,r%d,<<=", GET_TARGET_REG(code));
622  break;
623  case 0x4001: // shlr
624  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x1,&,?{,0x1,sr,|=,},1,r%d,>>=", GET_TARGET_REG(code), GET_TARGET_REG(code));
625  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
626  break;
627  case 0x4009: // shlr2
628  rz_strbuf_setf(&op->esil, "2,r%d,>>=", GET_TARGET_REG(code));
629  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
630  break;
631  case 0x4019: // shlr8
632  rz_strbuf_setf(&op->esil, "8,r%d,>>=", GET_TARGET_REG(code));
633  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
634  break;
635  case 0x4029: // shlr16
636  rz_strbuf_setf(&op->esil, "16,r%d,>>=", GET_TARGET_REG(code));
637  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
638  break;
639  default:
640  break;
641  }
642 
643  if (IS_JSR(code)) {
644  // op->type = RZ_ANALYSIS_OP_TYPE_UCALL; //call to reg
645  op->type = RZ_ANALYSIS_OP_TYPE_RCALL; // call to reg
646  op->delay = 1;
647  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
648  rz_strbuf_setf(&op->esil, "1,SETD,pc,2,+,pr,=,r%d,pc,=", GET_TARGET_REG(code));
649  } else if (IS_JMP(code)) {
650  op->type = RZ_ANALYSIS_OP_TYPE_UJMP; // jmp to reg
651  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
652  op->delay = 1;
653  op->eob = true;
654  rz_strbuf_setf(&op->esil, "1,SETD,r%d,pc,=", GET_TARGET_REG(code));
655  } else if (IS_CMPPL(code)) {
656  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
657  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,0,r%d,>,?{,0x1,sr,|=,}", GET_TARGET_REG(code));
658  } else if (IS_CMPPZ(code)) {
659  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
660  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,0,r%d,>=,?{,0x1,sr,|=,}", GET_TARGET_REG(code));
661  } else if (IS_LDCLSR(code)) {
662  op->type = RZ_ANALYSIS_OP_TYPE_POP;
663  rz_strbuf_setf(&op->esil, "r%d,[4],0x0FFF0FFF,&,sr,=,4,r%d,+=", GET_TARGET_REG(code), GET_TARGET_REG(code));
664  } else if (IS_LDCLSRGBR(code)) {
665  op->type = RZ_ANALYSIS_OP_TYPE_POP;
666  rz_strbuf_setf(&op->esil, "r%d,[4],gbr,=,4,r%d,+=", GET_TARGET_REG(code), GET_TARGET_REG(code));
667  } else if (IS_LDCLSRVBR(code)) {
668  op->type = RZ_ANALYSIS_OP_TYPE_POP;
669  rz_strbuf_setf(&op->esil, "r%d,[4],vbr,=,4,r%d,+=", GET_TARGET_REG(code), GET_TARGET_REG(code));
670  // todo ssr?
671  } else if (IS_LDSLMACH(code)) {
672  op->type = RZ_ANALYSIS_OP_TYPE_POP;
673  rz_strbuf_setf(&op->esil, "r%d,[4],mach,=,4,r%d,+=", GET_TARGET_REG(code), GET_TARGET_REG(code));
674  } else if (IS_LDSLMACL(code)) {
675  op->type = RZ_ANALYSIS_OP_TYPE_POP;
676  rz_strbuf_setf(&op->esil, "r%d,[4],macl,=,4,r%d,+=", GET_TARGET_REG(code), GET_TARGET_REG(code));
677  } else if (IS_LDSLPR(code)) {
678  op->type = RZ_ANALYSIS_OP_TYPE_POP;
679  rz_strbuf_setf(&op->esil, "r%d,[4],pr,=,4,r%d,+=", GET_TARGET_REG(code), GET_TARGET_REG(code));
680  } else if (IS_LDCSR(code)) {
681  rz_strbuf_setf(&op->esil, "r%d,0x0FFF0FFF,&,sr,=", GET_TARGET_REG(code));
682  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
683  } else if (IS_LDCGBR(code)) {
684  rz_strbuf_setf(&op->esil, "r%d,gbr,=", GET_TARGET_REG(code));
685  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
686  } else if (IS_LDCVBR(code)) {
687  rz_strbuf_setf(&op->esil, "r%d,vbr,=", GET_TARGET_REG(code));
688  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
689  } else if (IS_LDSMACH(code)) {
690  rz_strbuf_setf(&op->esil, "r%d,mach,=", GET_TARGET_REG(code));
691  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
692  } else if (IS_LDSMACL(code)) {
693  rz_strbuf_setf(&op->esil, "r%d,macl,=", GET_TARGET_REG(code));
694  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
695  } else if (IS_LDSPR(code)) {
696  rz_strbuf_setf(&op->esil, "r%d,pr,=", GET_TARGET_REG(code));
697  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
698  } else if (IS_ROTR(code)) {
699  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,0x1,&,sr,|=,0x1,r%d,>>>,r%d,=", GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
701  } else if (IS_ROTL(code)) {
702  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,0x1,r%d,<<<,r%d,=,r%d,0x1,&,sr,|=", GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
704  } else if (IS_ROTCR(code)) {
705  rz_strbuf_setf(&op->esil, "0,sr,0x1,&,?{,0x80000000,},0xFFFFFFFE,sr,&=,r%d,1,&,sr,|=,1,r%d,>>=,r%d,|=", GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
707  } else if (IS_ROTCL(code)) {
708  rz_strbuf_setf(&op->esil, "sr,0x1,&,0xFFFFFFFE,sr,&=,r%d,0x80000000,&,?{,1,sr,|=,},1,r%d,<<=,r%d,|=", GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
710  } else if (IS_STCLSR(code)) {
711  rz_strbuf_setf(&op->esil, "4,r%d,-=,sr,r%d,=[4]", GET_TARGET_REG(code), GET_TARGET_REG(code));
713  } else if (IS_STCLGBR(code)) {
714  rz_strbuf_setf(&op->esil, "4,r%d,-=,gbr,r%d,=[4]", GET_TARGET_REG(code), GET_TARGET_REG(code));
716  } else if (IS_STCLVBR(code)) {
717  rz_strbuf_setf(&op->esil, "4,r%d,-=,vbr,r%d,=[4]", GET_TARGET_REG(code), GET_TARGET_REG(code));
719  } else if (IS_STSLMACL(code)) {
720  rz_strbuf_setf(&op->esil, "4,r%d,-=,macl,r%d,=[4]", GET_TARGET_REG(code), GET_TARGET_REG(code));
722  } else if (IS_STSLMACH(code)) {
723  rz_strbuf_setf(&op->esil, "4,r%d,-=,mach,r%d,=[4]", GET_TARGET_REG(code), GET_TARGET_REG(code));
725  } else if (IS_STSLPR(code)) {
727  rz_strbuf_setf(&op->esil, "4,r%d,-=,pr,r%d,=[4]", GET_TARGET_REG(code), GET_TARGET_REG(code));
728  } else if (IS_TASB(code)) {
729  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r%d,[1],!,?{,0x80,r%d,=[1],1,sr,|=,}", GET_TARGET_REG(code), GET_TARGET_REG(code));
730  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
731  } else if (IS_DT(code)) {
732  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,1,r%d,-=,$z,sr,|,sr,:=", GET_TARGET_REG(code));
733  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
734  } else if (IS_MACW(code)) {
735  rz_strbuf_setf(&op->esil,
736  "0x2,sr,&,!,?{," // if S==0
737  S16_EXT("r%d,[2]") "," //@Rn sign extended
738  S16_EXT("r%d,[2]") "," //@Rm sign extended
739  "*,"
740  "macl,32,mach,<<,|," // macl | (mach << 32)
741  "+," // MAC+@Rm*@Rn
742  "32," S16_EXT("r%d,[2]") "," //@Rn sign extended
743  S16_EXT("r%d,[2]") "," //@Rm sign extended
744  "*,"
745  "0xffffffff00000000,&,>>,mach,=," // MACH > mach
746  "0xffffffff,&,macl,=,"
747  "}{," // if S==1
748  S16_EXT("r%d,[2]") "," //@Rn sign extended
749  S16_EXT("r%d,[2]") "," //@Rm sign extended
750  "*"
751  "macl,+=," // macl+(@Rm+@Rm)
752  "31,$o,?{," // if overflow
753  "macl,0x80000000,&,?{,"
754  "0x7fffffff,macl,=,"
755  "}{,"
756  "0x80000000,macl,=,"
757  "},"
758  "},"
759  "},"
760  "2,r%d,+=," // Rn+=2
761  "2,r%d,+=,", // Rm+=2
766  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
767  }
768  return op->size;
769 }
770 
771 // nibble=5; 0101nnnnmmmmi4*4 mov.l @(<disp>,<REG_M>),<REG_N>
772 static int movl_rdisp_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
774  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
775  op->src[0] = analysis_fill_reg_disp_mem(analysis, GET_SOURCE_REG(code), code & 0x0F, LONG_SIZE);
776  rz_strbuf_setf(&op->esil, "r%d,0x%x,+,[4],r%d,=", GET_SOURCE_REG(code), (code & 0xF) * 4, GET_TARGET_REG(code));
777  return op->size;
778 }
779 
781  if (IS_MOV_REGS(code)) {
782  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
783  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
784  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
785  rz_strbuf_setf(&op->esil, "r%d,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
786  } else if (IS_MOVB_REGREF_TO_REG(code)) {
788  op->src[0] = analysis_fill_reg_ref(analysis, GET_SOURCE_REG(code), BYTE_SIZE);
789  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
790  rz_strbuf_setf(&op->esil, "0x000000FF,r%d,&=,r%d,[1],DUP,0x80,&,?{,0xFFFFFF00,|=,},r%d,=", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
791  } else if (IS_MOVW_REGREF_TO_REG(code)) {
793  op->src[0] = analysis_fill_reg_ref(analysis, GET_SOURCE_REG(code), WORD_SIZE);
794  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
795  rz_strbuf_setf(&op->esil, "0x0000FFFF,r%d,&=,r%d,[2],DUP,0x8000,&,?{,0xFFFF0000,|=,},r%d,=", GET_TARGET_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
796  } else if (IS_MOVL_REGREF_TO_REG(code)) {
798  op->src[0] = analysis_fill_reg_ref(analysis, GET_SOURCE_REG(code), LONG_SIZE);
799  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
800  rz_strbuf_setf(&op->esil, "r%d,[4],r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
801  } else if (IS_EXT(code)) {
802  // ext{s,u}.{b,w} instructs. todo : more detail ?
803  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
804  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
805  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
806  switch (code & 0xF) {
807  case 0xC: // EXTU.B
808  rz_strbuf_setf(&op->esil, "r%d,0xFF,&,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
809  break;
810  case 0xD: // EXTU.W
811  rz_strbuf_setf(&op->esil, "r%d,0xFFFF,&,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
812  break;
813  case 0xE: // EXTS.B
814  rz_strbuf_setf(&op->esil, "r%d,0xFF,&,DUP,0x80,&,?{,0xFFFFFF00,|,},r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
815  break;
816  case 0xF: // EXTS.W
817  rz_strbuf_setf(&op->esil, "r%d,0xFFFF,&,DUP,0x8000,&,?{,0xFFFF0000,|,},r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
818  break;
819  default:
820  rz_strbuf_setf(&op->esil, "TODO,NOT IMPLEMENTED");
821  break;
822  }
823  } else if (IS_MOVB_POP(code)) {
824  op->type = RZ_ANALYSIS_OP_TYPE_POP;
825  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
826  rz_strbuf_setf(&op->esil, "r%d,[1],DUP,0x80,&,?{,0xFFFFFF00,|,},r%d,=,1,r%d,+=", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_SOURCE_REG(code));
827  } else if (IS_MOVW_POP(code)) {
828  op->type = RZ_ANALYSIS_OP_TYPE_POP;
829  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
830  rz_strbuf_setf(&op->esil, "r%d,[2],DUP,0x8000,&,?{,0xFFFF0000,|,},r%d,=,2,r%d,+=", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_SOURCE_REG(code));
831  } else if (IS_MOVL_POP(code)) {
832  op->type = RZ_ANALYSIS_OP_TYPE_POP;
833  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
834  rz_strbuf_setf(&op->esil, "r%d,[4],r%d,=,4,r%d,+=", GET_SOURCE_REG(code), GET_TARGET_REG(code), GET_SOURCE_REG(code));
835  } else if (IS_NEG(code)) {
836  // todo: neg and negc details
837  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
838  rz_strbuf_setf(&op->esil, "r%d,0,-,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
839  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
840  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
841  } else if (IS_NEGC(code)) {
842  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
843  rz_strbuf_setf(&op->esil, "1,sr,&,0xFFFFFFFE,sr,&=,r%d,+,0,-,31,$b,sr,|,sr,=,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
844  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
845  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
846  } else if (IS_NOT(code)) {
847  // todo : details?
848  rz_strbuf_setf(&op->esil, "0xFFFFFFFF,r%d,^,r%d,=", GET_SOURCE_REG(code), GET_TARGET_REG(code));
849  op->type = RZ_ANALYSIS_OP_TYPE_NOT;
850  op->src[0] = analysis_fill_ai_rg(analysis, GET_SOURCE_REG(code));
851  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
852  } else if (IS_SWAPB(code)) {
853  rz_strbuf_setf(&op->esil, "r%d,0xFFFF0000,&,8,r%d,0xFF,&,<<,|,8,r%d,0xFF00,&,>>,|,r%d,=", GET_SOURCE_REG(code), GET_SOURCE_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
854  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
855  // todo : details
856  } else if (IS_SWAPW(code)) {
857  rz_strbuf_setf(&op->esil, "16,r%d,0xFFFF,&,<<,16,r%d,0xFFFF0000,&,>>,|,r%d,=", GET_SOURCE_REG(code), GET_SOURCE_REG(code), GET_TARGET_REG(code));
858  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
859  }
860  return op->size;
861 }
862 
863 // nibble=7; 0111nnnni8*1.... add #<imm>,<REG_N>
864 static int add_imm(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
865  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
866  op->src[0] = analysis_fill_im(analysis, (st8)(code & 0xFF)); // Casting to (st8) forces sign-extension.
867  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
868  rz_strbuf_setf(&op->esil, "0x%x,DUP,0x80,&,?{,0xFFFFFF00,|,},r%d,+=", code & 0xFF, GET_TARGET_REG(code));
869  return op->size;
870 }
871 
873  if (IS_BT_OR_BF(code)) {
874  op->type = RZ_ANALYSIS_OP_TYPE_CJMP; // Jump if true or jump if false insns
875  op->jump = disarm_8bit_offset(op->addr, GET_BTF_OFFSET(code));
876  op->fail = op->addr + 2;
877  op->eob = true;
878  if (IS_BT(code)) {
879  rz_strbuf_setf(&op->esil, "sr,1,&,?{,0x%" PFMT64x ",pc,=,}", op->jump);
880  } else if (IS_BTS(code)) {
881  rz_strbuf_setf(&op->esil, "1,SETD,sr,1,&,?{,0x%" PFMT64x ",pc,=,}", op->jump);
882  op->delay = 1; // Only /S versions have a delay slot
883  } else if (IS_BFS(code)) {
884  rz_strbuf_setf(&op->esil, "1,SETD,sr,1,&,!,?{,0x%" PFMT64x ",pc,=,}", op->jump);
885  op->delay = 1; // Only /S versions have a delay slot
886  } else if (IS_BF(code)) {
887  rz_strbuf_setf(&op->esil, "sr,1,&,!,?{,0x%" PFMT64x ",pc,=,}", op->jump);
888  }
889  } else if (IS_MOVB_REGDISP_R0(code)) {
890  // 10000100mmmmi4*1 mov.b @(<disp>,<REG_M>),R0
892  op->dst = analysis_fill_ai_rg(analysis, 0);
893  op->src[0] = analysis_fill_reg_disp_mem(analysis, GET_SOURCE_REG(code), code & 0x0F, BYTE_SIZE);
894  rz_strbuf_setf(&op->esil, "r%d,0x%x,+,[1],DUP,0x80,&,?{,0xFFFFFF00,|,},r0,=", GET_SOURCE_REG(code), code & 0xF);
895  } else if (IS_MOVW_REGDISP_R0(code)) {
896  // 10000101mmmmi4*2 mov.w @(<disp>,<REG_M>),R0
898  op->dst = analysis_fill_ai_rg(analysis, 0);
899  op->src[0] = analysis_fill_reg_disp_mem(analysis, GET_SOURCE_REG(code), code & 0x0F, WORD_SIZE);
900  rz_strbuf_setf(&op->esil, "r%d,0x%x,+,[2],DUP,0x8000,&,?{,0xFFFF0000,|,},r0,=", GET_SOURCE_REG(code), (code & 0xF) * 2);
901  } else if (IS_CMPIMM(code)) {
902  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
903  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,0x%x,DUP,0x80,&,?{,0xFFFFFF00,|,},r0,==,$z,sr,|,sr,:=", code & 0xFF);
904  } else if (IS_MOVB_R0_REGDISP(code)) {
905  /* 10000000mmmmi4*1 mov.b R0,@(<disp>,<REG_M>)*/
907  op->src[0] = analysis_fill_ai_rg(analysis, 0);
908  op->dst = analysis_fill_reg_disp_mem(analysis, GET_SOURCE_REG(code), code & 0x0F, BYTE_SIZE);
909  rz_strbuf_setf(&op->esil, "r0,0xFF,&,0x%x,r%d,+,=[1]", code & 0xF, GET_SOURCE_REG(code));
910  } else if (IS_MOVW_R0_REGDISP(code)) {
911  // 10000001mmmmi4*2 mov.w R0,@(<disp>,<REG_M>))
913  op->src[0] = analysis_fill_ai_rg(analysis, 0);
914  op->dst = analysis_fill_reg_disp_mem(analysis, GET_SOURCE_REG(code), code & 0x0F, WORD_SIZE);
915  rz_strbuf_setf(&op->esil, "r0,0xFFFF,&,0x%x,r%d,+,=[2]", (code & 0xF) * 2, GET_SOURCE_REG(code));
916  }
917  return op->size;
918 }
919 
920 // nibble=9; 1001nnnni8p2.... mov.w @(<disp>,PC),<REG_N>
921 static int movw_pcdisp_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
923  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
924  op->src[0] = rz_analysis_value_new();
925  op->src[0]->base = (code & 0xFF) * 2 + op->addr + 4;
926  op->src[0]->memref = 1;
927  rz_strbuf_setf(&op->esil, "0x%" PFMT64x ",[2],r%d,=,r%d,0x8000,&,?{,0xFFFF0000,r%d,|=,}", op->src[0]->base, GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
928  return op->size;
929 }
930 
931 // nibble=A; 1010i12......... bra <bdisp12>
932 static int bra(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
933  /* Unconditional branch, relative to PC */
934  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
935  op->delay = 1;
937  op->eob = true;
938  rz_strbuf_setf(&op->esil, "1,SETD,0x%" PFMT64x ",pc,=", op->jump);
939  return op->size;
940 }
941 
942 // nibble=B; 1011i12......... bsr <bdisp12>
943 static int bsr(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
944  /* Subroutine call, relative to PC */
947  op->delay = 1;
948  rz_strbuf_setf(&op->esil, "1,SETD,pc,2,+,pr,=,0x%" PFMT64x ",pc,=", op->jump);
949  return op->size;
950 }
951 
953  if (IS_TRAP(code)) {
954  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
955  op->val = (ut8)(code & 0xFF);
956  rz_strbuf_setf(&op->esil, "4,r15,-=,sr,r15,=[4],4,r15,-=,2,pc,-,r15,=[4],2,0x%x,<<,4,+,vbr,+,pc,=", code & 0xFF);
957  } else if (IS_MOVA_PCREL_R0(code)) {
958  // 11000111i8p4.... mova @(<disp>,PC),R0
959  op->type = RZ_ANALYSIS_OP_TYPE_LEA;
960  op->src[0] = analysis_pcrel_disp_mov(analysis, op, code & 0xFF, LONG_SIZE); // this is wrong !
961  op->dst = analysis_fill_ai_rg(analysis, 0); // Always R0
962  rz_strbuf_setf(&op->esil, "0x%x,pc,+,r0,=", (code & 0xFF) * 4);
963  } else if (IS_BINLOGIC_IMM_R0(code)) { // 110010__i8 (binop) #imm, R0
964  op->src[0] = analysis_fill_im(analysis, code & 0xFF);
965  op->src[1] = analysis_fill_ai_rg(analysis, 0); // Always R0
966  op->dst = analysis_fill_ai_rg(analysis, 0); // Always R0 except tst #imm, R0
967  switch (code & 0xFF00) {
968  case 0xC800: // tst
969  // TODO : get correct op->dst ! (T flag)
971  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r0,0x%x,&,!,?{,1,sr,|=,}", code & 0xFF);
972  break;
973  case 0xC900: // and
974  op->type = RZ_ANALYSIS_OP_TYPE_AND;
975  rz_strbuf_setf(&op->esil, "0x%x,r0,&=", code & 0xFF);
976  break;
977  case 0xCA00: // xor
978  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
979  rz_strbuf_setf(&op->esil, "0x%x,r0,^=", code & 0xFF);
980  break;
981  case 0xCB00: // or
982  op->type = RZ_ANALYSIS_OP_TYPE_OR;
983  rz_strbuf_setf(&op->esil, "0x%x,r0,|=", code & 0xFF);
984  break;
985  }
986  } else if (IS_BINLOGIC_IMM_GBR(code)) { // 110011__i8 (binop).b #imm, @(R0,gbr)
987  op->src[0] = analysis_fill_im(analysis, code & 0xFF);
988  switch (code & 0xFF00) {
989  case 0xCC00: // tst
990  // TODO : get correct op->dst ! (T flag)
992  rz_strbuf_setf(&op->esil, "0xFFFFFFFE,sr,&=,r0,gbr,+,[1],0x%x,&,!,?{,1,sr,|=,}", code & 0xFF);
993  break;
994  case 0xCD00: // and
995  op->type = RZ_ANALYSIS_OP_TYPE_AND;
996  rz_strbuf_setf(&op->esil, "r0,gbr,+,[1],0x%x,&,r0,gbr,+,=[1]", code & 0xFF);
997  break;
998  case 0xCE00: // xor
999  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
1000  rz_strbuf_setf(&op->esil, "r0,gbr,+,[1],0x%x,^,r0,gbr,+,=[1]", code & 0xFF);
1001  break;
1002  case 0xCF00: // or
1003  op->type = RZ_ANALYSIS_OP_TYPE_OR;
1004  rz_strbuf_setf(&op->esil, "r0,gbr,+,[1],0x%x,|,r0,gbr,+,=[1]", code & 0xFF);
1005  break;
1006  }
1007  // TODO : implement @(R0,gbr) dest and src[1]
1008  } else if (IS_MOVB_R0_GBRREF(code)) {
1009  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1010  op->src[0] = analysis_fill_ai_rg(analysis, 0);
1011  rz_strbuf_setf(&op->esil, "r0,gbr,0x%x,+,=[1]", code & 0xFF);
1012  } else if (IS_MOVW_R0_GBRREF(code)) {
1013  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1014  op->src[0] = analysis_fill_ai_rg(analysis, 0);
1015  rz_strbuf_setf(&op->esil, "r0,gbr,0x%x,+,=[2]", (code & 0xFF) * 2);
1016  } else if (IS_MOVL_R0_GBRREF(code)) {
1017  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
1018  op->src[0] = analysis_fill_ai_rg(analysis, 0);
1019  rz_strbuf_setf(&op->esil, "r0,gbr,0x%x,+,=[4]", (code & 0xFF) * 4);
1020  } else if (IS_MOVB_GBRREF_R0(code)) {
1021  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1022  op->dst = analysis_fill_ai_rg(analysis, 0);
1023  rz_strbuf_setf(&op->esil, "gbr,0x%x,+,[1],DUP,0x80,&,?{,0xFFFFFF00,|,},r0,=", (code & 0xFF));
1024  } else if (IS_MOVW_GBRREF_R0(code)) {
1025  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1026  op->dst = analysis_fill_ai_rg(analysis, 0);
1027  rz_strbuf_setf(&op->esil, "gbr,0x%x,+,[2],DUP,0x8000,&,?{,0xFFFF0000,|,},r0,=", (code & 0xFF) * 2);
1028  } else if (IS_MOVL_GBRREF_R0(code)) {
1029  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1030  op->dst = analysis_fill_ai_rg(analysis, 0);
1031  rz_strbuf_setf(&op->esil, "gbr,0x%x,+,[4],r0,=", (code & 0xFF) * 4);
1032  }
1033 
1034  return op->size;
1035 }
1036 
1037 // nibble=d; 1101nnnni8 : mov.l @(<disp>,PC), Rn
1039  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
1040  op->src[0] = analysis_pcrel_disp_mov(analysis, op, code & 0xFF, LONG_SIZE);
1041  // TODO: check it
1042  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
1043  // rz_strbuf_setf (&op->esil, "0x%x,[4],r%d,=", (code & 0xFF) * 4 + (op->addr & 0xfffffff3) + 4, GET_TARGET_REG (code));
1044  rz_strbuf_setf(&op->esil, "0x%" PFMT64x ",[4],r%d,=", (code & 0xFF) * 4 + ((op->addr >> 2) << 2) + 4, GET_TARGET_REG(code));
1045  return op->size;
1046 }
1047 
1048 // nibble=e; 1110nnnni8*1.... mov #<imm>,<REG_N>
1049 static int mov_imm_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
1050  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
1051  op->dst = analysis_fill_ai_rg(analysis, GET_TARGET_REG(code));
1052  op->src[0] = analysis_fill_im(analysis, (st8)(code & 0xFF));
1053  rz_strbuf_setf(&op->esil, "0x%x,r%d,=,r%d,0x80,&,?{,0xFFFFFF00,r%d,|=,}", code & 0xFF, GET_TARGET_REG(code), GET_TARGET_REG(code), GET_TARGET_REG(code));
1054  return op->size;
1055 }
1056 
1057 // nibble=f;
1058 static int fpu_insn(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code) {
1059  // Not interested on FPU stuff for now
1060  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
1061  return op->size;
1062 }
1063 
1064 /* Table of routines for further analysis based on 1st nibble */
1073  add_imm,
1076  bra,
1077  bsr,
1080  mov_imm_reg,
1081  fpu_insn
1082 };
1083 
1084 /* This is the basic operation analysis. Just initialize and jump to
1085  * routines defined in first_nibble_decode table
1086  */
1087 static int sh_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) {
1088  ut8 op_MSB, op_LSB;
1089  int ret;
1090  if (!data || len < 2) {
1091  return 0;
1092  }
1093  op->addr = addr;
1094  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
1095 
1096  op->size = 2;
1097 
1098  op_MSB = analysis->big_endian ? data[0] : data[1];
1099  op_LSB = analysis->big_endian ? data[1] : data[0];
1100  ut16 opcode = (ut16)op_MSB << 8 | op_LSB;
1101  ret = first_nibble_decode[(op_MSB >> 4) & 0x0F](analysis, op, opcode);
1102 
1103  // RzIL uplifting
1104  SHOp *ilop = sh_disassembler(opcode);
1106  ctx->use_banked = true;
1107 
1108  rz_sh_il_opcode(analysis, op, addr, ilop, ctx);
1109  RZ_FREE(ctx);
1110  RZ_FREE(ilop);
1111 
1112  return ret;
1113 }
1114 
1115 /* Set the profile register */
1116 static RZ_OWN char *sh_get_reg_profile(RzAnalysis *analysis) {
1117  // TODO Add fpu regs
1118  const char *p =
1119  "=PC pc\n"
1120  "=SN r0\n"
1121  "=SP r15\n"
1122  "=BP r14\n"
1123  "=A0 r4\n"
1124  "=A1 r5\n"
1125  "=A2 r6\n"
1126  "=A3 r7\n"
1127  "=R0 r0\n"
1128  "gpr r0 .32 0 0\n"
1129  "gpr r1 .32 4 0\n"
1130  "gpr r2 .32 8 0\n"
1131  "gpr r3 .32 12 0\n"
1132  "gpr r4 .32 16 0\n"
1133  "gpr r5 .32 20 0\n"
1134  "gpr r6 .32 24 0\n"
1135  "gpr r7 .32 28 0\n"
1136  "gpr r0b .32 32 0\n"
1137  "gpr r1b .32 36 0\n"
1138  "gpr r2b .32 40 0\n"
1139  "gpr r3b .32 44 0\n"
1140  "gpr r4b .32 48 0\n"
1141  "gpr r5b .32 52 0\n"
1142  "gpr r6b .32 56 0\n"
1143  "gpr r7b .32 60 0\n"
1144  "gpr r8 .32 64 0\n"
1145  "gpr r9 .32 68 0\n"
1146  "gpr r10 .32 72 0\n"
1147  "gpr r11 .32 76 0\n"
1148  "gpr r12 .32 80 0\n"
1149  "gpr r13 .32 84 0\n"
1150  "gpr r14 .32 88 0\n"
1151  "gpr r15 .32 92 0\n"
1152  "gpr pc .32 96 0\n"
1153  "gpr sr .32 100 0\n"
1154  "gpr sr_t .1 100.0 0\n"
1155  "gpr sr_s .1 100.1 0\n"
1156  "gpr sr_i .4 100.4 0\n"
1157  "gpr sr_q .1 101.0 0\n"
1158  "gpr sr_m .1 101.1 0\n"
1159  "gpr sr_f .1 101.7 0\n"
1160  "gpr sr_b .1 103.4 0\n"
1161  "gpr sr_r .1 103.5 0\n"
1162  "gpr sr_d .1 103.6 0\n"
1163  "gpr gbr .32 104 0\n"
1164  "gpr ssr .32 108 0\n"
1165  "gpr spc .32 112 0\n"
1166  "gpr sgr .32 116 0\n"
1167  "gpr dbr .32 120 0\n"
1168  "gpr vbr .32 124 0\n"
1169  "gpr mach .32 128 0\n"
1170  "gpr macl .32 132 0\n"
1171  "gpr pr .32 136 0\n";
1172 
1173  return strdup(p);
1174 }
1175 
1176 static int archinfo(RzAnalysis *analysis, int q) {
1177 #if 0
1178  if (q == RZ_ANALYSIS_ARCHINFO_ALIGN) {
1179  return 4;
1180  }
1181 #endif
1182  return 2; /* :) */
1183 }
1184 
1186  .name = "sh",
1187  .desc = "SH-4 code analysis plugin",
1188  .license = "LGPL3",
1189  .arch = "sh",
1190  .archinfo = archinfo,
1191  .bits = 32,
1192  .op = &sh_op,
1193  .get_reg_profile = &sh_get_reg_profile,
1194  .esil = true,
1195  .il_config = rz_sh_il_config
1196 
1197 };
1198 
1199 #ifndef RZ_PLUGIN_INCORE
1202  .data = &rz_analysis_plugin_sh,
1203  .version = RZ_VERSION
1204 };
1205 #endif
size_t len
Definition: 6502dis.c:15
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
Definition: value.c:6
#define mask()
#define IS_BF(x)
Definition: analysis_sh.c:154
#define IS_LDCSR(x)
Definition: analysis_sh.c:95
#define IS_STSLMACH(x)
Definition: analysis_sh.c:121
static RzAnalysisValue * analysis_fill_ai_rg(RzAnalysis *analysis, int idx)
Definition: analysis_sh.c:205
static RzAnalysisValue * analysis_fill_reg_disp_mem(RzAnalysis *analysis, int reg, st64 delta, st64 size)
Definition: analysis_sh.c:220
static ut64 disarm_8bit_offset(ut64 pc, ut32 offs)
Definition: analysis_sh.c:192
#define IS_MOVB_GBRREF_R0(x)
Definition: analysis_sh.c:163
#define IS_LDCLSRGBR(x)
Definition: analysis_sh.c:99
#define S16_EXT(x)
Definition: analysis_sh.c:25
#define IS_RTS(x)
Definition: analysis_sh.c:34
#define IS_SUB(x)
Definition: analysis_sh.c:83
#define IS_LDCVBR(x)
Definition: analysis_sh.c:97
static int movl_rdisp_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:772
#define IS_SUBV(x)
Definition: analysis_sh.c:86
#define GET_BTF_OFFSET(x)
Definition: analysis_sh.c:172
#define IS_RTE(x)
Definition: analysis_sh.c:39
#define IS_CMPGE(x)
Definition: analysis_sh.c:77
#define IS_ADDC(x)
Definition: analysis_sh.c:88
#define IS_MOVL_REG_TO_REGREF(x)
Definition: analysis_sh.c:60
static int(* first_nibble_decode[])(RzAnalysis *, RzAnalysisOp *, ut16)
Definition: analysis_sh.c:1065
static int first_nibble_is_3(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:498
#define GET_SOURCE_REG(x)
Definition: analysis_sh.c:176
#define IS_XOR_REGS(x)
Definition: analysis_sh.c:68
#define IS_NEGC(x)
Definition: analysis_sh.c:143
#define IS_MULUW(x)
Definition: analysis_sh.c:72
#define IS_CMPHS(x)
Definition: analysis_sh.c:76
#define IS_TRAP(x)
Definition: analysis_sh.c:162
#define IS_MOVB_POP(x)
Definition: analysis_sh.c:136
#define IS_STSPR(x)
Definition: analysis_sh.c:55
#define IS_CMPEQ(x)
Definition: analysis_sh.c:74
#define IS_NOT(x)
Definition: analysis_sh.c:139
#define IS_MULL(x)
Definition: analysis_sh.c:47
#define IS_LDSMACL(x)
Definition: analysis_sh.c:102
#define IS_BTS(x)
Definition: analysis_sh.c:155
#define IS_LDCLSRVBR(x)
Definition: analysis_sh.c:100
#define IS_ROTCL(x)
Definition: analysis_sh.c:112
#define IS_MOVB_REG_TO_REGREF(x)
Definition: analysis_sh.c:58
#define IS_DMULS(x)
Definition: analysis_sh.c:82
#define IS_CMPIMM(x)
Definition: analysis_sh.c:151
#define IS_SWAPB(x)
Definition: analysis_sh.c:140
RzAnalysisPlugin rz_analysis_plugin_sh
Definition: analysis_sh.c:1185
#define GET_BRA_OFFSET(x)
Definition: analysis_sh.c:171
#define IS_MOVB_R0_REGDISP(x)
Definition: analysis_sh.c:146
static int movl_reg_rdisp(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:418
static int movl_pcdisp_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:1038
#define IS_STCLGBR(x)
Definition: analysis_sh.c:123
static int first_nibble_is_4(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:597
#define IS_BT_OR_BF(x)
Definition: analysis_sh.c:157
static RzAnalysisValue * analysis_fill_r0_reg_ref(RzAnalysis *analysis, int reg, st64 size)
Definition: analysis_sh.c:237
static RzAnalysisValue * analysis_fill_reg_ref(RzAnalysis *analysis, int reg, st64 size)
Definition: analysis_sh.c:229
#define IS_AND_REGS(x)
Definition: analysis_sh.c:67
#define IS_CLRMAC(x)
Definition: analysis_sh.c:38
#define IS_MOVW_REG_TO_R0REL(x)
Definition: analysis_sh.c:45
static RZ_OWN char * sh_get_reg_profile(RzAnalysis *analysis)
Definition: analysis_sh.c:1116
#define IS_XTRCT(x)
Definition: analysis_sh.c:71
#define IS_CMPPL(x)
Definition: analysis_sh.c:93
static int movw_pcdisp_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:921
static ut64 disarm_12bit_offset(RzAnalysisOp *op, unsigned int insoff)
Definition: analysis_sh.c:182
#define IS_STSMACH(x)
Definition: analysis_sh.c:53
static int first_nibble_is_8(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:872
static int add_imm(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:864
#define GET_TARGET_REG(x)
Definition: analysis_sh.c:175
#define IS_LDCGBR(x)
Definition: analysis_sh.c:96
#define IS_MOVW_REG_TO_REGREF(x)
Definition: analysis_sh.c:59
#define IS_BINLOGIC_IMM_R0(x)
Definition: analysis_sh.c:167
#define IS_PUSHW(x)
Definition: analysis_sh.c:63
static int first_nibble_is_0(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:270
#define IS_DT(x)
Definition: analysis_sh.c:130
#define IS_SLEEP(x)
Definition: analysis_sh.c:37
#define IS_ROTL(x)
Definition: analysis_sh.c:113
#define IS_CMPSTR(x)
Definition: analysis_sh.c:70
static char * regs[]
Definition: analysis_sh.c:203
#define IS_STSMACL(x)
Definition: analysis_sh.c:54
RZ_API RzLibStruct rizin_plugin
Definition: analysis_sh.c:1200
#define IS_MOVL_R0_GBRREF(x)
Definition: analysis_sh.c:161
#define IS_MOVB_REG_TO_R0REL(x)
Definition: analysis_sh.c:44
#define IS_CLRT(x)
Definition: analysis_sh.c:32
#define IS_CMPHI(x)
Definition: analysis_sh.c:78
#define IS_MOVW_REGDISP_R0(x)
Definition: analysis_sh.c:150
#define IS_LDSLMACL(x)
Definition: analysis_sh.c:104
#define BYTE_SIZE
Definition: analysis_sh.c:15
#define IS_ROTR(x)
Definition: analysis_sh.c:114
static int first_nibble_is_6(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:780
#define WORD_SIZE
Definition: analysis_sh.c:14
#define IS_SWAPW(x)
Definition: analysis_sh.c:141
#define IS_JSR(x)
Definition: analysis_sh.c:91
#define IS_LDSLMACH(x)
Definition: analysis_sh.c:103
static RzAnalysisValue * analysis_fill_im(RzAnalysis *analysis, st32 v)
Definition: analysis_sh.c:212
#define IS_MOVL_REGREF_TO_REG(x)
Definition: analysis_sh.c:134
#define IS_STSLMACL(x)
Definition: analysis_sh.c:120
#define IS_MOVW_R0_GBRREF(x)
Definition: analysis_sh.c:160
#define CLR_T
Definition: analysis_sh.c:29
#define IS_OR_REGS(x)
Definition: analysis_sh.c:69
#define IS_MOVW_GBRREF_R0(x)
Definition: analysis_sh.c:164
#define IS_BRAF(x)
Definition: analysis_sh.c:43
#define IS_MOVB_R0REL_TO_REG(x)
Definition: analysis_sh.c:48
#define IS_MOVA_PCREL_R0(x)
Definition: analysis_sh.c:166
#define IS_SUBC(x)
Definition: analysis_sh.c:85
#define IS_BFS(x)
Definition: analysis_sh.c:156
#define IS_STCSR1(x)
Definition: analysis_sh.c:41
#define IS_NEG(x)
Definition: analysis_sh.c:142
#define IS_NOP(x)
Definition: analysis_sh.c:33
#define IS_PUSHB(x)
Definition: analysis_sh.c:62
#define IS_LDSPR(x)
Definition: analysis_sh.c:105
static int bra(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:932
#define IS_STSLPR(x)
Definition: analysis_sh.c:126
#define IS_DIV0U(x)
Definition: analysis_sh.c:36
#define IS_STCLVBR(x)
Definition: analysis_sh.c:124
#define IS_DIV0S(x)
Definition: analysis_sh.c:65
#define IS_DMULU(x)
Definition: analysis_sh.c:81
#define IS_MOVT(x)
Definition: analysis_sh.c:52
#define IS_MOVB_REGDISP_R0(x)
Definition: analysis_sh.c:149
static int sh_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: analysis_sh.c:1087
#define IS_CMPGT(x)
Definition: analysis_sh.c:79
#define IS_CMPPZ(x)
Definition: analysis_sh.c:94
#define IS_ADDV(x)
Definition: analysis_sh.c:89
static RzAnalysisValue * analysis_regrel_jump(RzAnalysis *analysis, RzAnalysisOp *op, ut8 reg)
Definition: analysis_sh.c:261
#define IS_TASB(x)
Definition: analysis_sh.c:129
static RzAnalysisValue * analysis_pcrel_disp_mov(RzAnalysis *analysis, RzAnalysisOp *op, ut8 disp, int size)
Definition: analysis_sh.c:246
#define IS_EXT(x)
Definition: analysis_sh.c:144
#define IS_TSTRR(x)
Definition: analysis_sh.c:66
#define S32_EXT(x)
Definition: analysis_sh.c:26
#define IS_MOVL_POP(x)
Definition: analysis_sh.c:138
#define IS_LDSLPR(x)
Definition: analysis_sh.c:106
#define IS_MOVL_REG_TO_R0REL(x)
Definition: analysis_sh.c:46
#define IS_MACW(x)
Definition: analysis_sh.c:90
static int mov_imm_reg(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:1049
#define IS_JMP(x)
Definition: analysis_sh.c:92
#define IS_BSRF(x)
Definition: analysis_sh.c:42
#define IS_MOVW_R0REL_TO_REG(x)
Definition: analysis_sh.c:49
static int bsr(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:943
static int first_nibble_is_c(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:952
static int archinfo(RzAnalysis *analysis, int q)
Definition: analysis_sh.c:1176
#define IS_MOVW_R0_REGDISP(x)
Definition: analysis_sh.c:147
#define IS_BT(x)
Definition: analysis_sh.c:153
#define IS_MOVL_R0REL_TO_REG(x)
Definition: analysis_sh.c:50
static int fpu_insn(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:1058
#define IS_MOVB_R0_GBRREF(x)
Definition: analysis_sh.c:159
#define IS_SETT(x)
Definition: analysis_sh.c:35
#define IS_DIV1(x)
Definition: analysis_sh.c:80
#define IS_STCLSR(x)
Definition: analysis_sh.c:122
#define IS_ADD(x)
Definition: analysis_sh.c:87
#define IS_MULSW(x)
Definition: analysis_sh.c:73
#define IS_ROTCR(x)
Definition: analysis_sh.c:111
#define IS_MOVW_POP(x)
Definition: analysis_sh.c:137
#define IS_MOVB_REGREF_TO_REG(x)
Definition: analysis_sh.c:132
#define IS_MACL(x)
Definition: analysis_sh.c:51
#define IS_BINLOGIC_IMM_GBR(x)
Definition: analysis_sh.c:168
#define IS_LDSMACH(x)
Definition: analysis_sh.c:101
#define IS_LDCLSR(x)
Definition: analysis_sh.c:98
static int first_nibble_is_2(RzAnalysis *analysis, RzAnalysisOp *op, ut16 code)
Definition: analysis_sh.c:426
#define IS_MOVL_GBRREF_R0(x)
Definition: analysis_sh.c:165
#define IS_PUSHL(x)
Definition: analysis_sh.c:64
#define IS_MOVW_REGREF_TO_REG(x)
Definition: analysis_sh.c:133
#define IS_MOV_REGS(x)
Definition: analysis_sh.c:135
#define LONG_SIZE
Definition: analysis_sh.c:13
#define RZ_API
#define ut8
Definition: dcpu16.h:8
uint16_t ut16
uint32_t ut32
const char * v
Definition: dsignal.c:12
voidpf void uLong size
Definition: ioapi.h:138
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int idx
Definition: setup.py:197
int off
Definition: pal.c:13
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
@ RZ_ANALYSIS_VAL_IMM
Definition: rz_analysis.h:770
@ RZ_ANALYSIS_VAL_REG
Definition: rz_analysis.h:768
@ RZ_ANALYSIS_VAL_MEM
Definition: rz_analysis.h:769
@ RZ_ANALYSIS_OP_FAMILY_FPU
Definition: rz_analysis.h:313
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_ROL
Definition: rz_analysis.h:420
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_SAL
Definition: rz_analysis.h:408
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_ROR
Definition: rz_analysis.h:419
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_DIV
Definition: rz_analysis.h:405
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_SHL
Definition: rz_analysis.h:407
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_NOT
Definition: rz_analysis.h:414
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_ACMP
Definition: rz_analysis.h:400
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define st8
Definition: rz_types_base.h:16
#define st64
Definition: rz_types_base.h:10
#define st32
Definition: rz_types_base.h:12
#define RZ_VERSION
Definition: rz_version.h:8
static int
Definition: sfsocketcall.h:114
RZ_IPI RZ_OWN SHOp * sh_disassembler(ut16 opcode)
Disassemble opcode and return a SHOp.
Definition: disassembler.c:130
RZ_IPI bool rz_sh_il_opcode(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisOp *aop, ut64 pc, RZ_BORROW RZ_NONNULL const SHOp *op, RZ_NULLABLE SHILContext *ctx)
Store the lifted IL for op in aop This function also takes care of initializing and adding the privil...
Definition: sh_il.c:1759
RZ_IPI RzAnalysisILConfig * rz_sh_il_config(RZ_NONNULL RzAnalysis *analysis)
Initialize new config for the SuperH IL.
Definition: sh_il.c:1784
Definition: inftree9.h:24
const char * version
Definition: rz_analysis.h:1239
RzAnalysisValueType type
Definition: rz_analysis.h:775
RzRegItem * regdelta
Definition: rz_analysis.h:785
To store the context of the IL lifter ; Used to pass around information outside effects Other context...
Definition: sh_il.h:14
Definition: dis.c:32
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58