Rizin
unix-like reverse engineering framework and cli tools
pic_midrange.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2018 courk <courk@courk.cc>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include "pic_midrange.h"
5 
6 static const PicMidrangeOpInfo
8  { "nop", PIC_MIDRANGE_OP_ARGS_NONE },
9  { "return", PIC_MIDRANGE_OP_ARGS_NONE },
10  { "retfie", PIC_MIDRANGE_OP_ARGS_NONE },
11  { "option", PIC_MIDRANGE_OP_ARGS_NONE },
12  { "sleep", PIC_MIDRANGE_OP_ARGS_NONE },
13  { "clrwdt", PIC_MIDRANGE_OP_ARGS_NONE },
14  { "tris", PIC_MIDRANGE_OP_ARGS_2F },
15  { "movwf", PIC_MIDRANGE_OP_ARGS_7F },
16  { "clr", PIC_MIDRANGE_OP_ARGS_1D_7F },
17  { "subwf", PIC_MIDRANGE_OP_ARGS_1D_7F },
18  { "decf", PIC_MIDRANGE_OP_ARGS_1D_7F },
19  { "iorwf", PIC_MIDRANGE_OP_ARGS_1D_7F },
20  { "andwf", PIC_MIDRANGE_OP_ARGS_1D_7F },
21  { "xorwf", PIC_MIDRANGE_OP_ARGS_1D_7F },
22  { "addwf", PIC_MIDRANGE_OP_ARGS_1D_7F },
23  { "movf", PIC_MIDRANGE_OP_ARGS_1D_7F },
24  { "comf", PIC_MIDRANGE_OP_ARGS_1D_7F },
25  { "incf", PIC_MIDRANGE_OP_ARGS_1D_7F },
26  { "decfsz", PIC_MIDRANGE_OP_ARGS_1D_7F },
27  { "rrf", PIC_MIDRANGE_OP_ARGS_1D_7F },
28  { "rlf", PIC_MIDRANGE_OP_ARGS_1D_7F },
29  { "swapf", PIC_MIDRANGE_OP_ARGS_1D_7F },
30  { "incfsz", PIC_MIDRANGE_OP_ARGS_1D_7F },
31  { "bcf", PIC_MIDRANGE_OP_ARGS_3B_7F },
32  { "bsf", PIC_MIDRANGE_OP_ARGS_3B_7F },
33  { "btfsc", PIC_MIDRANGE_OP_ARGS_3B_7F },
34  { "btfss", PIC_MIDRANGE_OP_ARGS_3B_7F },
35  { "call", PIC_MIDRANGE_OP_ARGS_11K },
36  { "goto", PIC_MIDRANGE_OP_ARGS_11K },
37  { "movlw", PIC_MIDRANGE_OP_ARGS_8K },
38  { "retlw", PIC_MIDRANGE_OP_ARGS_8K },
39  { "iorlw", PIC_MIDRANGE_OP_ARGS_8K },
40  { "andlw", PIC_MIDRANGE_OP_ARGS_8K },
41  { "xorlw", PIC_MIDRANGE_OP_ARGS_8K },
42  { "sublw", PIC_MIDRANGE_OP_ARGS_8K },
43  { "addlw", PIC_MIDRANGE_OP_ARGS_8K },
44  { "reset", PIC_MIDRANGE_OP_ARGS_NONE },
45  { "callw", PIC_MIDRANGE_OP_ARGS_NONE },
46  { "brw", PIC_MIDRANGE_OP_ARGS_NONE },
47  { "moviw", PIC_MIDRANGE_OP_ARGS_1N_2M },
48  { "movwi", PIC_MIDRANGE_OP_ARGS_1N_2M },
49  { "movlb", PIC_MIDRANGE_OP_ARGS_4K },
50  { "lslf", PIC_MIDRANGE_OP_ARGS_1D_7F },
51  { "lsrf", PIC_MIDRANGE_OP_ARGS_1D_7F },
52  { "asrf", PIC_MIDRANGE_OP_ARGS_1D_7F },
53  { "subwfb", PIC_MIDRANGE_OP_ARGS_1D_7F },
54  { "addwfc", PIC_MIDRANGE_OP_ARGS_1D_7F },
55  { "addfsr", PIC_MIDRANGE_OP_ARGS_1N_6K },
56  { "movlp", PIC_MIDRANGE_OP_ARGS_7F },
57  { "bra", PIC_MIDRANGE_OP_ARGS_9K },
58  { "moviw", PIC_MIDRANGE_OP_ARGS_1N_6K },
59  { "movwi", PIC_MIDRANGE_OP_ARGS_1N_6K }
60  };
61 
62 static const char *PicMidrangeFsrOps[] = { "++FSR%d", "--FSR%d", "FSR%d++",
63  "FSR%d--" };
64 
66  if (instr & (1 << 14)) {
68  }
69 
70  switch (instr >> 11) { // 3 first MSB bits
71  case 0x4: return PIC_MIDRANGE_OPCODE_CALL;
72  case 0x5: return PIC_MIDRANGE_OPCODE_GOTO;
73  }
74 
75  switch (instr >> 10) { // 4 first MSB bits
76  case 0x4: return PIC_MIDRANGE_OPCODE_BCF;
77  case 0x5: return PIC_MIDRANGE_OPCODE_BSF;
78  case 0x6: return PIC_MIDRANGE_OPCODE_BTFSC;
79  case 0x7: return PIC_MIDRANGE_OPCODE_BTFSS;
80  }
81 
82  switch (instr >> 9) { // 5 first MSB bits
83  case 0x19: return PIC_MIDRANGE_OPCODE_BRA;
84  }
85 
86  switch (instr >> 8) { // 6 first MSB bits
87  case 0x1: return PIC_MIDRANGE_OPCODE_CLR;
88  case 0x2: return PIC_MIDRANGE_OPCODE_SUBWF;
89  case 0x3: return PIC_MIDRANGE_OPCODE_DECF;
90  case 0x4: return PIC_MIDRANGE_OPCODE_IORWF;
91  case 0x5: return PIC_MIDRANGE_OPCODE_ANDWF;
92  case 0x6: return PIC_MIDRANGE_OPCODE_XORWF;
93  case 0x7: return PIC_MIDRANGE_OPCODE_ADDWF;
94  case 0x8: return PIC_MIDRANGE_OPCODE_MOVF;
95  case 0x9: return PIC_MIDRANGE_OPCODE_COMF;
96  case 0xa: return PIC_MIDRANGE_OPCODE_INCF;
97  case 0xb: return PIC_MIDRANGE_OPCODE_DECFSZ;
98  case 0xc: return PIC_MIDRANGE_OPCODE_RRF;
99  case 0xd: return PIC_MIDRANGE_OPCODE_RLF;
100  case 0xe: return PIC_MIDRANGE_OPCODE_SWAPF;
101  case 0xf: return PIC_MIDRANGE_OPCODE_INCFSZ;
102  case 0x38: return PIC_MIDRANGE_OPCODE_IORLW;
103  case 0x39: return PIC_MIDRANGE_OPCODE_ANDLW;
104  case 0x3a: return PIC_MIDRANGE_OPCODE_XORLW;
105  case 0x30: return PIC_MIDRANGE_OPCODE_MOVLW;
106  case 0x34: return PIC_MIDRANGE_OPCODE_RETLW;
107  case 0x3c: return PIC_MIDRANGE_OPCODE_SUBLW;
108  case 0x3e: return PIC_MIDRANGE_OPCODE_ADDLW;
109  case 0x35: return PIC_MIDRANGE_OPCODE_LSLF;
110  case 0x36: return PIC_MIDRANGE_OPCODE_LSRF;
111  case 0x37: return PIC_MIDRANGE_OPCODE_ASRF;
112  case 0x3b: return PIC_MIDRANGE_OPCODE_SUBWFB;
113  case 0x3d: return PIC_MIDRANGE_OPCODE_ADDWFC;
114  }
115 
116  switch (instr >> 7) { // 7 first MSB bits
117  case 0x1: return PIC_MIDRANGE_OPCODE_MOVWF;
118  case 0x62: return PIC_MIDRANGE_OPCODE_ADDFSR;
119  case 0x63: return PIC_MIDRANGE_OPCODE_MOVLP;
120  case 0x7e: return PIC_MIDRANGE_OPCODE_MOVIW_2;
121  case 0x7f: return PIC_MIDRANGE_OPCODE_MOVWI_2;
122  }
123 
124  switch (instr >> 5) { // 9 first MSB bits
125  case 0x1: return PIC_MIDRANGE_OPCODE_MOVLB;
126  }
127 
128  switch (instr >> 3) { // 11 first MSB bits
129  case 0x2: return PIC_MIDRANGE_OPCODE_MOVIW_1;
130  case 0x3: return PIC_MIDRANGE_OPCODE_MOVWI_1;
131  }
132 
133  switch (instr >> 2) { // 12 first MSB bits
134  case 0x19: return PIC_MIDRANGE_OPCODE_TRIS;
135  }
136 
137  switch (instr) {
138  case 0x0: return PIC_MIDRANGE_OPCODE_NOP;
139  case 0x1: return PIC_MIDRANGE_OPCODE_RESET;
140  case 0xa: return PIC_MIDRANGE_OPCODE_CALLW;
141  case 0xb: return PIC_MIDRANGE_OPCODE_BRW;
142  case 0x8: return PIC_MIDRANGE_OPCODE_RETURN;
143  case 0x9: return PIC_MIDRANGE_OPCODE_RETFIE;
144  case 0x62: return PIC_MIDRANGE_OPCODE_OPTION;
145  case 0x63: return PIC_MIDRANGE_OPCODE_SLEEP;
146  case 0x64: return PIC_MIDRANGE_OPCODE_CLRWDT;
147  }
148 
150 }
151 
153  if (opcode >= PIC_MIDRANGE_OPCODE_INVALID) {
154  return NULL;
155  }
156  return &pic_midrange_op_info[opcode];
157 }
158 
159 int pic_midrange_disassemble(RzAsmOp *op, char *opbuf, const ut8 *b, int l) {
160  char fsr_op[6];
161  st16 branch;
162 
163 #define EMIT_INVALID \
164  { \
165  op->size = 2; \
166  strcpy(opbuf, "invalid"); \
167  return 1; \
168  }
169  if (!b || l < 2) {
171  }
172 
173  ut16 instr = rz_read_le16(b);
175  if (opcode == PIC_MIDRANGE_OPCODE_INVALID) {
177  }
178 
179  const PicMidrangeOpInfo *op_info = pic_midrange_get_op_info(opcode);
180  if (!op_info) {
182  }
183 
184 #undef EMIT_INVALID
185 
186  op->size = 2;
187 
188  const char *buf_asm = NULL;
189  switch (op_info->args) {
191  buf_asm = op_info->mnemonic;
192  break;
194  buf_asm = sdb_fmt("%s 0x%x", op_info->mnemonic, instr & PIC_MIDRANGE_OP_ARGS_2F_MASK_F);
195  break;
197  buf_asm = sdb_fmt("%s 0x%x", op_info->mnemonic, instr & PIC_MIDRANGE_OP_ARGS_7F_MASK_F);
198  break;
200  buf_asm = sdb_fmt("%s 0x%x, %c", op_info->mnemonic,
202  (instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_D) >> 7 ? 'f' : 'w');
203  break;
205  if (opcode == PIC_MIDRANGE_OPCODE_ADDFSR) {
206  buf_asm = sdb_fmt("%s FSR%d, 0x%x", op_info->mnemonic,
208  6,
210  } else {
211  buf_asm = sdb_fmt("%s 0x%x[FSR%d]", op_info->mnemonic,
213  (instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_N) >> 6);
214  }
215  break;
217  buf_asm = sdb_fmt("%s 0x%x, %d", op_info->mnemonic, instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_F,
218  (instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_B) >> 7);
219  break;
221  buf_asm = sdb_fmt("%s 0x%x", op_info->mnemonic, instr & PIC_MIDRANGE_OP_ARGS_4K_MASK_K);
222  break;
224  buf_asm = sdb_fmt("%s 0x%x", op_info->mnemonic, instr & PIC_MIDRANGE_OP_ARGS_8K_MASK_K);
225  break;
228  branch |= ((branch & 0x100) ? 0xfe00 : 0);
229  buf_asm = sdb_fmt("%s %s0x%x",
230  op_info->mnemonic, branch < 0 ? "-" : "",
231  branch < 0 ? -branch : branch);
232  break;
234  buf_asm = sdb_fmt("%s 0x%x", op_info->mnemonic, instr & PIC_MIDRANGE_OP_ARGS_11K_MASK_K);
235  break;
237  snprintf(
238  fsr_op, sizeof(fsr_op),
239  PicMidrangeFsrOps[instr &
241  (instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_N) >> 2);
242  buf_asm = sdb_fmt("%s %s", op_info->mnemonic, fsr_op);
243  break;
244  }
245  if (buf_asm) {
246  strcpy(opbuf, buf_asm);
247  }
248  return op->size;
249 }
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
#define EMIT_INVALID
const PicMidrangeOpInfo * pic_midrange_get_op_info(PicMidrangeOpcode opcode)
Definition: pic_midrange.c:152
static const char * PicMidrangeFsrOps[]
Definition: pic_midrange.c:62
int pic_midrange_disassemble(RzAsmOp *op, char *opbuf, const ut8 *b, int l)
Definition: pic_midrange.c:159
static const PicMidrangeOpInfo pic_midrange_op_info[PIC_MIDRANGE_OPCODE_INVALID]
Definition: pic_midrange.c:7
PicMidrangeOpcode pic_midrange_get_opcode(ut16 instr)
Definition: pic_midrange.c:65
#define PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_F
Definition: pic_midrange.h:27
PicMidrangeOpcode
Definition: pic_midrange.h:44
@ PIC_MIDRANGE_OPCODE_ADDWFC
Definition: pic_midrange.h:91
@ PIC_MIDRANGE_OPCODE_TRIS
Definition: pic_midrange.h:51
@ PIC_MIDRANGE_OPCODE_DECFSZ
Definition: pic_midrange.h:63
@ PIC_MIDRANGE_OPCODE_MOVLW
Definition: pic_midrange.h:74
@ PIC_MIDRANGE_OPCODE_RETFIE
Definition: pic_midrange.h:47
@ PIC_MIDRANGE_OPCODE_BCF
Definition: pic_midrange.h:68
@ PIC_MIDRANGE_OPCODE_INVALID
Definition: pic_midrange.h:97
@ PIC_MIDRANGE_OPCODE_MOVLP
Definition: pic_midrange.h:93
@ PIC_MIDRANGE_OPCODE_NOP
Definition: pic_midrange.h:45
@ PIC_MIDRANGE_OPCODE_MOVLB
Definition: pic_midrange.h:86
@ PIC_MIDRANGE_OPCODE_INCFSZ
Definition: pic_midrange.h:67
@ PIC_MIDRANGE_OPCODE_COMF
Definition: pic_midrange.h:61
@ PIC_MIDRANGE_OPCODE_ANDLW
Definition: pic_midrange.h:77
@ PIC_MIDRANGE_OPCODE_SUBWF
Definition: pic_midrange.h:54
@ PIC_MIDRANGE_OPCODE_IORWF
Definition: pic_midrange.h:56
@ PIC_MIDRANGE_OPCODE_RLF
Definition: pic_midrange.h:65
@ PIC_MIDRANGE_OPCODE_MOVIW_2
Definition: pic_midrange.h:95
@ PIC_MIDRANGE_OPCODE_BRW
Definition: pic_midrange.h:83
@ PIC_MIDRANGE_OPCODE_MOVF
Definition: pic_midrange.h:60
@ PIC_MIDRANGE_OPCODE_OPTION
Definition: pic_midrange.h:48
@ PIC_MIDRANGE_OPCODE_RETLW
Definition: pic_midrange.h:75
@ PIC_MIDRANGE_OPCODE_CLR
Definition: pic_midrange.h:53
@ PIC_MIDRANGE_OPCODE_MOVWI_2
Definition: pic_midrange.h:96
@ PIC_MIDRANGE_OPCODE_MOVWF
Definition: pic_midrange.h:52
@ PIC_MIDRANGE_OPCODE_ASRF
Definition: pic_midrange.h:89
@ PIC_MIDRANGE_OPCODE_ADDLW
Definition: pic_midrange.h:80
@ PIC_MIDRANGE_OPCODE_BTFSC
Definition: pic_midrange.h:70
@ PIC_MIDRANGE_OPCODE_BSF
Definition: pic_midrange.h:69
@ PIC_MIDRANGE_OPCODE_LSRF
Definition: pic_midrange.h:88
@ PIC_MIDRANGE_OPCODE_SUBLW
Definition: pic_midrange.h:79
@ PIC_MIDRANGE_OPCODE_BTFSS
Definition: pic_midrange.h:71
@ PIC_MIDRANGE_OPCODE_SWAPF
Definition: pic_midrange.h:66
@ PIC_MIDRANGE_OPCODE_LSLF
Definition: pic_midrange.h:87
@ PIC_MIDRANGE_OPCODE_CLRWDT
Definition: pic_midrange.h:50
@ PIC_MIDRANGE_OPCODE_INCF
Definition: pic_midrange.h:62
@ PIC_MIDRANGE_OPCODE_SUBWFB
Definition: pic_midrange.h:90
@ PIC_MIDRANGE_OPCODE_CALL
Definition: pic_midrange.h:72
@ PIC_MIDRANGE_OPCODE_MOVIW_1
Definition: pic_midrange.h:84
@ PIC_MIDRANGE_OPCODE_ADDWF
Definition: pic_midrange.h:59
@ PIC_MIDRANGE_OPCODE_RETURN
Definition: pic_midrange.h:46
@ PIC_MIDRANGE_OPCODE_ADDFSR
Definition: pic_midrange.h:92
@ PIC_MIDRANGE_OPCODE_XORWF
Definition: pic_midrange.h:58
@ PIC_MIDRANGE_OPCODE_RESET
Definition: pic_midrange.h:81
@ PIC_MIDRANGE_OPCODE_GOTO
Definition: pic_midrange.h:73
@ PIC_MIDRANGE_OPCODE_MOVWI_1
Definition: pic_midrange.h:85
@ PIC_MIDRANGE_OPCODE_IORLW
Definition: pic_midrange.h:76
@ PIC_MIDRANGE_OPCODE_ANDWF
Definition: pic_midrange.h:57
@ PIC_MIDRANGE_OPCODE_CALLW
Definition: pic_midrange.h:82
@ PIC_MIDRANGE_OPCODE_XORLW
Definition: pic_midrange.h:78
@ PIC_MIDRANGE_OPCODE_DECF
Definition: pic_midrange.h:55
@ PIC_MIDRANGE_OPCODE_SLEEP
Definition: pic_midrange.h:49
@ PIC_MIDRANGE_OPCODE_RRF
Definition: pic_midrange.h:64
@ PIC_MIDRANGE_OPCODE_BRA
Definition: pic_midrange.h:94
#define PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_F
Definition: pic_midrange.h:31
#define PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_D
Definition: pic_midrange.h:26
#define PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_B
Definition: pic_midrange.h:30
#define PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_N
Definition: pic_midrange.h:28
#define PIC_MIDRANGE_OP_ARGS_2F_MASK_F
Definition: pic_midrange.h:24
#define PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_M
Definition: pic_midrange.h:37
#define PIC_MIDRANGE_OP_ARGS_4K_MASK_K
Definition: pic_midrange.h:32
#define PIC_MIDRANGE_OP_ARGS_9K_MASK_K
Definition: pic_midrange.h:34
#define PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_N
Definition: pic_midrange.h:36
#define PIC_MIDRANGE_OP_ARGS_11K_MASK_K
Definition: pic_midrange.h:35
#define PIC_MIDRANGE_OP_ARGS_7F_MASK_F
Definition: pic_midrange.h:25
@ PIC_MIDRANGE_OP_ARGS_11K
Definition: pic_midrange.h:20
@ PIC_MIDRANGE_OP_ARGS_2F
Definition: pic_midrange.h:12
@ PIC_MIDRANGE_OP_ARGS_4K
Definition: pic_midrange.h:17
@ PIC_MIDRANGE_OP_ARGS_1D_7F
Definition: pic_midrange.h:14
@ PIC_MIDRANGE_OP_ARGS_9K
Definition: pic_midrange.h:19
@ PIC_MIDRANGE_OP_ARGS_1N_6K
Definition: pic_midrange.h:15
@ PIC_MIDRANGE_OP_ARGS_8K
Definition: pic_midrange.h:18
@ PIC_MIDRANGE_OP_ARGS_1N_2M
Definition: pic_midrange.h:21
@ PIC_MIDRANGE_OP_ARGS_NONE
Definition: pic_midrange.h:11
@ PIC_MIDRANGE_OP_ARGS_3B_7F
Definition: pic_midrange.h:16
@ PIC_MIDRANGE_OP_ARGS_7F
Definition: pic_midrange.h:13
#define PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_K
Definition: pic_midrange.h:29
#define PIC_MIDRANGE_OP_ARGS_8K_MASK_K
Definition: pic_midrange.h:33
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206
#define st16
Definition: rz_types_base.h:14
#define b(i)
Definition: sha256.c:42
const char * mnemonic
Definition: pic_midrange.h:40
PicMidrangeOpArgs args
Definition: pic_midrange.h:41
Definition: dis.c:32