/src/capstonenext/arch/TMS320C64x/TMS320C64xInstPrinter.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Capstone Disassembly Engine */ |
2 | | /* TMS320C64x Backend by Fotis Loukos <me@fotisl.com> 2016 */ |
3 | | |
4 | | #ifdef CAPSTONE_HAS_TMS320C64X |
5 | | |
6 | | #include <ctype.h> |
7 | | #include <string.h> |
8 | | |
9 | | #include "TMS320C64xInstPrinter.h" |
10 | | #include "../../MCInst.h" |
11 | | #include "../../utils.h" |
12 | | #include "../../SStream.h" |
13 | | #include "../../MCRegisterInfo.h" |
14 | | #include "../../MathExtras.h" |
15 | | #include "TMS320C64xMapping.h" |
16 | | |
17 | | #include "capstone/tms320c64x.h" |
18 | | |
19 | | static const char *getRegisterName(unsigned RegNo); |
20 | | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O); |
21 | | static void printMemOperand(MCInst *MI, unsigned OpNo, SStream *O); |
22 | | static void printMemOperand2(MCInst *MI, unsigned OpNo, SStream *O); |
23 | | static void printRegPair(MCInst *MI, unsigned OpNo, SStream *O); |
24 | | |
25 | | void TMS320C64x_post_printer(csh ud, cs_insn *insn, SStream *insn_asm, MCInst *mci) |
26 | 36.0k | { |
27 | 36.0k | SStream ss; |
28 | 36.0k | const char *op_str_ptr, *p2; |
29 | 36.0k | char tmp[8] = { 0 }; |
30 | 36.0k | unsigned int unit = 0; |
31 | 36.0k | int i; |
32 | 36.0k | cs_tms320c64x *tms320c64x; |
33 | | |
34 | 36.0k | if (mci->csh->detail_opt) { |
35 | 36.0k | tms320c64x = &mci->flat_insn->detail->tms320c64x; |
36 | | |
37 | 36.0k | for (i = 0; i < insn->detail->groups_count; i++) { |
38 | 36.0k | switch(insn->detail->groups[i]) { |
39 | 10.5k | case TMS320C64X_GRP_FUNIT_D: |
40 | 10.5k | unit = TMS320C64X_FUNIT_D; |
41 | 10.5k | break; |
42 | 7.97k | case TMS320C64X_GRP_FUNIT_L: |
43 | 7.97k | unit = TMS320C64X_FUNIT_L; |
44 | 7.97k | break; |
45 | 2.58k | case TMS320C64X_GRP_FUNIT_M: |
46 | 2.58k | unit = TMS320C64X_FUNIT_M; |
47 | 2.58k | break; |
48 | 14.1k | case TMS320C64X_GRP_FUNIT_S: |
49 | 14.1k | unit = TMS320C64X_FUNIT_S; |
50 | 14.1k | break; |
51 | 841 | case TMS320C64X_GRP_FUNIT_NO: |
52 | 841 | unit = TMS320C64X_FUNIT_NO; |
53 | 841 | break; |
54 | 36.0k | } |
55 | 36.0k | if (unit != 0) |
56 | 36.0k | break; |
57 | 36.0k | } |
58 | 36.0k | tms320c64x->funit.unit = unit; |
59 | | |
60 | 36.0k | SStream_Init(&ss); |
61 | 36.0k | if (tms320c64x->condition.reg != TMS320C64X_REG_INVALID) |
62 | 25.3k | SStream_concat(&ss, "[%c%s]|", (tms320c64x->condition.zero == 1) ? '!' : '|', cs_reg_name(ud, tms320c64x->condition.reg)); |
63 | | |
64 | | // Sorry for all the fixes below. I don't have time to add more helper SStream functions. |
65 | | // Before that they messed around with the private buffer of the stream. |
66 | | // So it is better now. But still not efficient. |
67 | 36.0k | op_str_ptr = strchr(SStream_rbuf(insn_asm), '\t'); |
68 | | |
69 | 36.0k | if ((op_str_ptr != NULL) && (((p2 = strchr(op_str_ptr, '[')) != NULL) || ((p2 = strchr(op_str_ptr, '(')) != NULL))) { |
70 | 37.9k | while ((p2 > op_str_ptr) && ((*p2 != 'a') && (*p2 != 'b'))) |
71 | 28.7k | p2--; |
72 | 9.16k | if (p2 == op_str_ptr) { |
73 | 0 | SStream_Flush(insn_asm, NULL); |
74 | 0 | SStream_concat0(insn_asm, "Invalid!"); |
75 | 0 | return; |
76 | 0 | } |
77 | 9.16k | if (*p2 == 'a') |
78 | 4.26k | strncpy(tmp, "1T", sizeof(tmp)); |
79 | 4.90k | else |
80 | 4.90k | strncpy(tmp, "2T", sizeof(tmp)); |
81 | 26.8k | } else { |
82 | 26.8k | tmp[0] = '\0'; |
83 | 26.8k | } |
84 | 36.0k | SStream mnem_post = { 0 }; |
85 | 36.0k | SStream_Init(&mnem_post); |
86 | 36.0k | switch(tms320c64x->funit.unit) { |
87 | 10.5k | case TMS320C64X_FUNIT_D: |
88 | 10.5k | SStream_concat(&mnem_post, ".D%s%u", tmp, tms320c64x->funit.side); |
89 | 10.5k | break; |
90 | 7.97k | case TMS320C64X_FUNIT_L: |
91 | 7.97k | SStream_concat(&mnem_post, ".L%s%u", tmp, tms320c64x->funit.side); |
92 | 7.97k | break; |
93 | 2.58k | case TMS320C64X_FUNIT_M: |
94 | 2.58k | SStream_concat(&mnem_post, ".M%s%u", tmp, tms320c64x->funit.side); |
95 | 2.58k | break; |
96 | 14.1k | case TMS320C64X_FUNIT_S: |
97 | 14.1k | SStream_concat(&mnem_post, ".S%s%u", tmp, tms320c64x->funit.side); |
98 | 14.1k | break; |
99 | 36.0k | } |
100 | 36.0k | if (tms320c64x->funit.crosspath > 0) |
101 | 9.04k | SStream_concat0(&mnem_post, "X"); |
102 | | |
103 | 36.0k | if (op_str_ptr != NULL) { |
104 | | // There is an op_str |
105 | 35.2k | SStream_concat1(&mnem_post, '\t'); |
106 | 35.2k | SStream_replc_str(insn_asm, '\t', SStream_rbuf(&mnem_post)); |
107 | 35.2k | } |
108 | | |
109 | 36.0k | if (tms320c64x->parallel != 0) |
110 | 15.5k | SStream_concat0(insn_asm, "\t||"); |
111 | 36.0k | SStream_concat0(&ss, SStream_rbuf(insn_asm)); |
112 | 36.0k | SStream_Flush(insn_asm, NULL); |
113 | 36.0k | SStream_concat0(insn_asm, SStream_rbuf(&ss)); |
114 | 36.0k | } |
115 | 36.0k | } |
116 | | |
117 | | #define PRINT_ALIAS_INSTR |
118 | | #include "TMS320C64xGenAsmWriter.inc" |
119 | | |
120 | | #define GET_INSTRINFO_ENUM |
121 | | #include "TMS320C64xGenInstrInfo.inc" |
122 | | |
123 | | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) |
124 | 147k | { |
125 | 147k | MCOperand *Op = MCInst_getOperand(MI, OpNo); |
126 | 147k | unsigned reg; |
127 | | |
128 | 147k | if (MCOperand_isReg(Op)) { |
129 | 104k | reg = MCOperand_getReg(Op); |
130 | 104k | if ((MCInst_getOpcode(MI) == TMS320C64x_MVC_s1_rr) && (OpNo == 1)) { |
131 | 2.33k | switch(reg) { |
132 | 410 | case TMS320C64X_REG_EFR: |
133 | 410 | SStream_concat0(O, "EFR"); |
134 | 410 | break; |
135 | 840 | case TMS320C64X_REG_IFR: |
136 | 840 | SStream_concat0(O, "IFR"); |
137 | 840 | break; |
138 | 1.08k | default: |
139 | 1.08k | SStream_concat0(O, getRegisterName(reg)); |
140 | 1.08k | break; |
141 | 2.33k | } |
142 | 102k | } else { |
143 | 102k | SStream_concat0(O, getRegisterName(reg)); |
144 | 102k | } |
145 | | |
146 | 104k | if (MI->csh->detail_opt) { |
147 | 104k | MI->flat_insn->detail->tms320c64x.operands[MI->flat_insn->detail->tms320c64x.op_count].type = TMS320C64X_OP_REG; |
148 | 104k | MI->flat_insn->detail->tms320c64x.operands[MI->flat_insn->detail->tms320c64x.op_count].reg = reg; |
149 | 104k | MI->flat_insn->detail->tms320c64x.op_count++; |
150 | 104k | } |
151 | 104k | } else if (MCOperand_isImm(Op)) { |
152 | 43.3k | int64_t Imm = MCOperand_getImm(Op); |
153 | | |
154 | 43.3k | if (Imm >= 0) { |
155 | 35.6k | if (Imm > HEX_THRESHOLD) |
156 | 21.2k | SStream_concat(O, "0x%"PRIx64, Imm); |
157 | 14.4k | else |
158 | 14.4k | SStream_concat(O, "%"PRIu64, Imm); |
159 | 35.6k | } else { |
160 | 7.64k | if (Imm < -HEX_THRESHOLD) |
161 | 6.46k | SStream_concat(O, "-0x%"PRIx64, -Imm); |
162 | 1.17k | else |
163 | 1.17k | SStream_concat(O, "-%"PRIu64, -Imm); |
164 | 7.64k | } |
165 | | |
166 | 43.3k | if (MI->csh->detail_opt) { |
167 | 43.3k | MI->flat_insn->detail->tms320c64x.operands[MI->flat_insn->detail->tms320c64x.op_count].type = TMS320C64X_OP_IMM; |
168 | 43.3k | MI->flat_insn->detail->tms320c64x.operands[MI->flat_insn->detail->tms320c64x.op_count].imm = Imm; |
169 | 43.3k | MI->flat_insn->detail->tms320c64x.op_count++; |
170 | 43.3k | } |
171 | 43.3k | } |
172 | 147k | } |
173 | | |
174 | | static void printMemOperand(MCInst *MI, unsigned OpNo, SStream *O) |
175 | 8.19k | { |
176 | 8.19k | MCOperand *Op = MCInst_getOperand(MI, OpNo); |
177 | 8.19k | int64_t Val = MCOperand_getImm(Op); |
178 | 8.19k | unsigned scaled, base, offset, mode, unit; |
179 | 8.19k | cs_tms320c64x *tms320c64x; |
180 | 8.19k | char st, nd; |
181 | | |
182 | 8.19k | scaled = (Val >> 19) & 1; |
183 | 8.19k | base = (Val >> 12) & 0x7f; |
184 | 8.19k | offset = (Val >> 5) & 0x7f; |
185 | 8.19k | mode = (Val >> 1) & 0xf; |
186 | 8.19k | unit = Val & 1; |
187 | | |
188 | 8.19k | if (scaled) { |
189 | 7.11k | st = '['; |
190 | 7.11k | nd = ']'; |
191 | 7.11k | } else { |
192 | 1.08k | st = '('; |
193 | 1.08k | nd = ')'; |
194 | 1.08k | } |
195 | | |
196 | 8.19k | switch(mode) { |
197 | 1.14k | case 0: |
198 | 1.14k | SStream_concat(O, "*-%s%c%u%c", getRegisterName(base), st, offset, nd); |
199 | 1.14k | break; |
200 | 599 | case 1: |
201 | 599 | SStream_concat(O, "*+%s%c%u%c", getRegisterName(base), st, offset, nd); |
202 | 599 | break; |
203 | 651 | case 4: |
204 | 651 | SStream_concat(O, "*-%s%c%s%c", getRegisterName(base), st, getRegisterName(offset), nd); |
205 | 651 | break; |
206 | 389 | case 5: |
207 | 389 | SStream_concat(O, "*+%s%c%s%c", getRegisterName(base), st, getRegisterName(offset), nd); |
208 | 389 | break; |
209 | 474 | case 8: |
210 | 474 | SStream_concat(O, "*--%s%c%u%c", getRegisterName(base), st, offset, nd); |
211 | 474 | break; |
212 | 788 | case 9: |
213 | 788 | SStream_concat(O, "*++%s%c%u%c", getRegisterName(base), st, offset, nd); |
214 | 788 | break; |
215 | 919 | case 10: |
216 | 919 | SStream_concat(O, "*%s--%c%u%c", getRegisterName(base), st, offset, nd); |
217 | 919 | break; |
218 | 1.33k | case 11: |
219 | 1.33k | SStream_concat(O, "*%s++%c%u%c", getRegisterName(base), st, offset, nd); |
220 | 1.33k | break; |
221 | 729 | case 12: |
222 | 729 | SStream_concat(O, "*--%s%c%s%c", getRegisterName(base), st, getRegisterName(offset), nd); |
223 | 729 | break; |
224 | 573 | case 13: |
225 | 573 | SStream_concat(O, "*++%s%c%s%c", getRegisterName(base), st, getRegisterName(offset), nd); |
226 | 573 | break; |
227 | 359 | case 14: |
228 | 359 | SStream_concat(O, "*%s--%c%s%c", getRegisterName(base), st, getRegisterName(offset), nd); |
229 | 359 | break; |
230 | 244 | case 15: |
231 | 244 | SStream_concat(O, "*%s++%c%s%c", getRegisterName(base), st, getRegisterName(offset), nd); |
232 | 244 | break; |
233 | 8.19k | } |
234 | | |
235 | 8.19k | if (MI->csh->detail_opt) { |
236 | 8.19k | tms320c64x = &MI->flat_insn->detail->tms320c64x; |
237 | | |
238 | 8.19k | tms320c64x->operands[tms320c64x->op_count].type = TMS320C64X_OP_MEM; |
239 | 8.19k | tms320c64x->operands[tms320c64x->op_count].mem.base = base; |
240 | 8.19k | tms320c64x->operands[tms320c64x->op_count].mem.disp = offset; |
241 | 8.19k | tms320c64x->operands[tms320c64x->op_count].mem.unit = unit + 1; |
242 | 8.19k | tms320c64x->operands[tms320c64x->op_count].mem.scaled = scaled; |
243 | 8.19k | switch(mode) { |
244 | 1.14k | case 0: |
245 | 1.14k | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
246 | 1.14k | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_BW; |
247 | 1.14k | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_NO; |
248 | 1.14k | break; |
249 | 599 | case 1: |
250 | 599 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
251 | 599 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
252 | 599 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_NO; |
253 | 599 | break; |
254 | 651 | case 4: |
255 | 651 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_REGISTER; |
256 | 651 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_BW; |
257 | 651 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_NO; |
258 | 651 | break; |
259 | 389 | case 5: |
260 | 389 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_REGISTER; |
261 | 389 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
262 | 389 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_NO; |
263 | 389 | break; |
264 | 474 | case 8: |
265 | 474 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
266 | 474 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_BW; |
267 | 474 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_PRE; |
268 | 474 | break; |
269 | 788 | case 9: |
270 | 788 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
271 | 788 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
272 | 788 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_PRE; |
273 | 788 | break; |
274 | 919 | case 10: |
275 | 919 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
276 | 919 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_BW; |
277 | 919 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_POST; |
278 | 919 | break; |
279 | 1.33k | case 11: |
280 | 1.33k | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
281 | 1.33k | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
282 | 1.33k | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_POST; |
283 | 1.33k | break; |
284 | 729 | case 12: |
285 | 729 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_REGISTER; |
286 | 729 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_BW; |
287 | 729 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_PRE; |
288 | 729 | break; |
289 | 573 | case 13: |
290 | 573 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_REGISTER; |
291 | 573 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
292 | 573 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_PRE; |
293 | 573 | break; |
294 | 359 | case 14: |
295 | 359 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_REGISTER; |
296 | 359 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_BW; |
297 | 359 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_POST; |
298 | 359 | break; |
299 | 244 | case 15: |
300 | 244 | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_REGISTER; |
301 | 244 | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
302 | 244 | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_POST; |
303 | 244 | break; |
304 | 8.19k | } |
305 | 8.19k | tms320c64x->op_count++; |
306 | 8.19k | } |
307 | 8.19k | } |
308 | | |
309 | | static void printMemOperand2(MCInst *MI, unsigned OpNo, SStream *O) |
310 | 8.48k | { |
311 | 8.48k | MCOperand *Op = MCInst_getOperand(MI, OpNo); |
312 | 8.48k | int64_t Val = MCOperand_getImm(Op); |
313 | 8.48k | uint16_t offset; |
314 | 8.48k | unsigned basereg; |
315 | 8.48k | cs_tms320c64x *tms320c64x; |
316 | | |
317 | 8.48k | basereg = Val & 0x7f; |
318 | 8.48k | offset = (Val >> 7) & 0x7fff; |
319 | 8.48k | SStream_concat(O, "*+%s[0x%x]", getRegisterName(basereg), offset); |
320 | | |
321 | 8.48k | if (MI->csh->detail_opt) { |
322 | 8.48k | tms320c64x = &MI->flat_insn->detail->tms320c64x; |
323 | | |
324 | 8.48k | tms320c64x->operands[tms320c64x->op_count].type = TMS320C64X_OP_MEM; |
325 | 8.48k | tms320c64x->operands[tms320c64x->op_count].mem.base = basereg; |
326 | 8.48k | tms320c64x->operands[tms320c64x->op_count].mem.unit = 2; |
327 | 8.48k | tms320c64x->operands[tms320c64x->op_count].mem.disp = offset; |
328 | 8.48k | tms320c64x->operands[tms320c64x->op_count].mem.disptype = TMS320C64X_MEM_DISP_CONSTANT; |
329 | 8.48k | tms320c64x->operands[tms320c64x->op_count].mem.direction = TMS320C64X_MEM_DIR_FW; |
330 | 8.48k | tms320c64x->operands[tms320c64x->op_count].mem.modify = TMS320C64X_MEM_MOD_NO; |
331 | 8.48k | tms320c64x->op_count++; |
332 | 8.48k | } |
333 | 8.48k | } |
334 | | |
335 | | static void printRegPair(MCInst *MI, unsigned OpNo, SStream *O) |
336 | 22.9k | { |
337 | 22.9k | MCOperand *Op = MCInst_getOperand(MI, OpNo); |
338 | 22.9k | unsigned reg = MCOperand_getReg(Op); |
339 | 22.9k | cs_tms320c64x *tms320c64x; |
340 | | |
341 | 22.9k | SStream_concat(O, "%s:%s", getRegisterName(reg + 1), getRegisterName(reg)); |
342 | | |
343 | 22.9k | if (MI->csh->detail_opt) { |
344 | 22.9k | tms320c64x = &MI->flat_insn->detail->tms320c64x; |
345 | | |
346 | 22.9k | tms320c64x->operands[tms320c64x->op_count].type = TMS320C64X_OP_REGPAIR; |
347 | 22.9k | tms320c64x->operands[tms320c64x->op_count].reg = reg; |
348 | 22.9k | tms320c64x->op_count++; |
349 | 22.9k | } |
350 | 22.9k | } |
351 | | |
352 | | static bool printAliasInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI) |
353 | 77.8k | { |
354 | 77.8k | unsigned opcode = MCInst_getOpcode(MI); |
355 | 77.8k | MCOperand *op; |
356 | | |
357 | 77.8k | switch(opcode) { |
358 | | /* ADD.Dx -i, x, y -> SUB.Dx x, i, y */ |
359 | 328 | case TMS320C64x_ADD_d2_rir: |
360 | | /* ADD.L -i, x, y -> SUB.L x, i, y */ |
361 | 820 | case TMS320C64x_ADD_l1_irr: |
362 | 1.27k | case TMS320C64x_ADD_l1_ipp: |
363 | | /* ADD.S -i, x, y -> SUB.S x, i, y */ |
364 | 2.00k | case TMS320C64x_ADD_s1_irr: |
365 | 2.00k | if ((MCInst_getNumOperands(MI) == 3) && |
366 | 2.00k | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
367 | 2.00k | MCOperand_isReg(MCInst_getOperand(MI, 1)) && |
368 | 2.00k | MCOperand_isImm(MCInst_getOperand(MI, 2)) && |
369 | 2.00k | (MCOperand_getImm(MCInst_getOperand(MI, 2)) < 0)) { |
370 | | |
371 | 699 | MCInst_setOpcodePub(MI, TMS320C64X_INS_SUB); |
372 | 699 | op = MCInst_getOperand(MI, 2); |
373 | 699 | MCOperand_setImm(op, -MCOperand_getImm(op)); |
374 | | |
375 | 699 | SStream_concat0(O, "SUB\t"); |
376 | 699 | printOperand(MI, 1, O); |
377 | 699 | SStream_concat0(O, ", "); |
378 | 699 | printOperand(MI, 2, O); |
379 | 699 | SStream_concat0(O, ", "); |
380 | 699 | printOperand(MI, 0, O); |
381 | | |
382 | 699 | return true; |
383 | 699 | } |
384 | 1.30k | break; |
385 | 77.8k | } |
386 | 77.1k | switch(opcode) { |
387 | | /* ADD.D 0, x, y -> MV.D x, y */ |
388 | 486 | case TMS320C64x_ADD_d1_rir: |
389 | | /* OR.D x, 0, y -> MV.D x, y */ |
390 | 923 | case TMS320C64x_OR_d2_rir: |
391 | | /* ADD.L 0, x, y -> MV.L x, y */ |
392 | 1.22k | case TMS320C64x_ADD_l1_irr: |
393 | 1.36k | case TMS320C64x_ADD_l1_ipp: |
394 | | /* OR.L 0, x, y -> MV.L x, y */ |
395 | 1.85k | case TMS320C64x_OR_l1_irr: |
396 | | /* ADD.S 0, x, y -> MV.S x, y */ |
397 | 2.56k | case TMS320C64x_ADD_s1_irr: |
398 | | /* OR.S 0, x, y -> MV.S x, y */ |
399 | 3.05k | case TMS320C64x_OR_s1_irr: |
400 | 3.05k | if ((MCInst_getNumOperands(MI) == 3) && |
401 | 3.05k | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
402 | 3.05k | MCOperand_isReg(MCInst_getOperand(MI, 1)) && |
403 | 3.05k | MCOperand_isImm(MCInst_getOperand(MI, 2)) && |
404 | 3.05k | (MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0)) { |
405 | | |
406 | 243 | MCInst_setOpcodePub(MI, TMS320C64X_INS_MV); |
407 | 243 | MI->size--; |
408 | | |
409 | 243 | SStream_concat0(O, "MV\t"); |
410 | 243 | printOperand(MI, 1, O); |
411 | 243 | SStream_concat0(O, ", "); |
412 | 243 | printOperand(MI, 0, O); |
413 | | |
414 | 243 | return true; |
415 | 243 | } |
416 | 2.80k | break; |
417 | 77.1k | } |
418 | 76.9k | switch(opcode) { |
419 | | /* XOR.D -1, x, y -> NOT.D x, y */ |
420 | 528 | case TMS320C64x_XOR_d2_rir: |
421 | | /* XOR.L -1, x, y -> NOT.L x, y */ |
422 | 768 | case TMS320C64x_XOR_l1_irr: |
423 | | /* XOR.S -1, x, y -> NOT.S x, y */ |
424 | 1.56k | case TMS320C64x_XOR_s1_irr: |
425 | 1.56k | if ((MCInst_getNumOperands(MI) == 3) && |
426 | 1.56k | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
427 | 1.56k | MCOperand_isReg(MCInst_getOperand(MI, 1)) && |
428 | 1.56k | MCOperand_isImm(MCInst_getOperand(MI, 2)) && |
429 | 1.56k | (MCOperand_getImm(MCInst_getOperand(MI, 2)) == -1)) { |
430 | | |
431 | 262 | MCInst_setOpcodePub(MI, TMS320C64X_INS_NOT); |
432 | 262 | MI->size--; |
433 | | |
434 | 262 | SStream_concat0(O, "NOT\t"); |
435 | 262 | printOperand(MI, 1, O); |
436 | 262 | SStream_concat0(O, ", "); |
437 | 262 | printOperand(MI, 0, O); |
438 | | |
439 | 262 | return true; |
440 | 262 | } |
441 | 1.29k | break; |
442 | 76.9k | } |
443 | 76.6k | switch(opcode) { |
444 | | /* MVK.D 0, x -> ZERO.D x */ |
445 | 572 | case TMS320C64x_MVK_d1_rr: |
446 | | /* MVK.L 0, x -> ZERO.L x */ |
447 | 2.01k | case TMS320C64x_MVK_l2_ir: |
448 | 2.01k | if ((MCInst_getNumOperands(MI) == 2) && |
449 | 2.01k | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
450 | 2.01k | MCOperand_isImm(MCInst_getOperand(MI, 1)) && |
451 | 2.01k | (MCOperand_getImm(MCInst_getOperand(MI, 1)) == 0)) { |
452 | | |
453 | 540 | MCInst_setOpcodePub(MI, TMS320C64X_INS_ZERO); |
454 | 540 | MI->size--; |
455 | | |
456 | 540 | SStream_concat0(O, "ZERO\t"); |
457 | 540 | printOperand(MI, 0, O); |
458 | | |
459 | 540 | return true; |
460 | 540 | } |
461 | 1.47k | break; |
462 | 76.6k | } |
463 | 76.1k | switch(opcode) { |
464 | | /* SUB.L x, x, y -> ZERO.L y */ |
465 | 928 | case TMS320C64x_SUB_l1_rrp_x1: |
466 | | /* SUB.S x, x, y -> ZERO.S y */ |
467 | 1.08k | case TMS320C64x_SUB_s1_rrr: |
468 | 1.08k | if ((MCInst_getNumOperands(MI) == 3) && |
469 | 1.08k | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
470 | 1.08k | MCOperand_isReg(MCInst_getOperand(MI, 1)) && |
471 | 1.08k | MCOperand_isReg(MCInst_getOperand(MI, 2)) && |
472 | 1.08k | (MCOperand_getReg(MCInst_getOperand(MI, 1)) == MCOperand_getReg(MCInst_getOperand(MI, 2)))) { |
473 | | |
474 | 366 | MCInst_setOpcodePub(MI, TMS320C64X_INS_ZERO); |
475 | 366 | MI->size -= 2; |
476 | | |
477 | 366 | SStream_concat0(O, "ZERO\t"); |
478 | 366 | printOperand(MI, 0, O); |
479 | | |
480 | 366 | return true; |
481 | 366 | } |
482 | 714 | break; |
483 | 76.1k | } |
484 | 75.7k | switch(opcode) { |
485 | | /* SUB.L 0, x, y -> NEG.L x, y */ |
486 | 902 | case TMS320C64x_SUB_l1_irr: |
487 | 1.48k | case TMS320C64x_SUB_l1_ipp: |
488 | | /* SUB.S 0, x, y -> NEG.S x, y */ |
489 | 1.60k | case TMS320C64x_SUB_s1_irr: |
490 | 1.60k | if ((MCInst_getNumOperands(MI) == 3) && |
491 | 1.60k | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
492 | 1.60k | MCOperand_isReg(MCInst_getOperand(MI, 1)) && |
493 | 1.60k | MCOperand_isImm(MCInst_getOperand(MI, 2)) && |
494 | 1.60k | (MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0)) { |
495 | | |
496 | 291 | MCInst_setOpcodePub(MI, TMS320C64X_INS_NEG); |
497 | 291 | MI->size--; |
498 | | |
499 | 291 | SStream_concat0(O, "NEG\t"); |
500 | 291 | printOperand(MI, 1, O); |
501 | 291 | SStream_concat0(O, ", "); |
502 | 291 | printOperand(MI, 0, O); |
503 | | |
504 | 291 | return true; |
505 | 291 | } |
506 | 1.31k | break; |
507 | 75.7k | } |
508 | 75.4k | switch(opcode) { |
509 | | /* PACKLH2.L x, x, y -> SWAP2.L x, y */ |
510 | 434 | case TMS320C64x_PACKLH2_l1_rrr_x2: |
511 | | /* PACKLH2.S x, x, y -> SWAP2.S x, y */ |
512 | 852 | case TMS320C64x_PACKLH2_s1_rrr: |
513 | 852 | if ((MCInst_getNumOperands(MI) == 3) && |
514 | 852 | MCOperand_isReg(MCInst_getOperand(MI, 0)) && |
515 | 852 | MCOperand_isReg(MCInst_getOperand(MI, 1)) && |
516 | 852 | MCOperand_isReg(MCInst_getOperand(MI, 2)) && |
517 | 852 | (MCOperand_getReg(MCInst_getOperand(MI, 1)) == MCOperand_getReg(MCInst_getOperand(MI, 2)))) { |
518 | | |
519 | 50 | MCInst_setOpcodePub(MI, TMS320C64X_INS_SWAP2); |
520 | 50 | MI->size--; |
521 | | |
522 | 50 | SStream_concat0(O, "SWAP2\t"); |
523 | 50 | printOperand(MI, 1, O); |
524 | 50 | SStream_concat0(O, ", "); |
525 | 50 | printOperand(MI, 0, O); |
526 | | |
527 | 50 | return true; |
528 | 50 | } |
529 | 802 | break; |
530 | 75.4k | } |
531 | 75.4k | switch(opcode) { |
532 | | /* NOP 16 -> IDLE */ |
533 | | /* NOP 1 -> NOP */ |
534 | 1.80k | case TMS320C64x_NOP_n: |
535 | 1.80k | if ((MCInst_getNumOperands(MI) == 1) && |
536 | 1.80k | MCOperand_isImm(MCInst_getOperand(MI, 0)) && |
537 | 1.80k | (MCOperand_getReg(MCInst_getOperand(MI, 0)) == 16)) { |
538 | | |
539 | 281 | MCInst_setOpcodePub(MI, TMS320C64X_INS_IDLE); |
540 | 281 | MI->size--; |
541 | | |
542 | 281 | SStream_concat0(O, "IDLE"); |
543 | | |
544 | 281 | return true; |
545 | 281 | } |
546 | 1.52k | if ((MCInst_getNumOperands(MI) == 1) && |
547 | 1.52k | MCOperand_isImm(MCInst_getOperand(MI, 0)) && |
548 | 1.52k | (MCOperand_getReg(MCInst_getOperand(MI, 0)) == 1)) { |
549 | | |
550 | 1.15k | MI->size--; |
551 | | |
552 | 1.15k | SStream_concat0(O, "NOP"); |
553 | | |
554 | 1.15k | return true; |
555 | 1.15k | } |
556 | 366 | break; |
557 | 75.4k | } |
558 | | |
559 | 73.9k | return false; |
560 | 75.4k | } |
561 | | |
562 | | void TMS320C64x_printInst(MCInst *MI, SStream *O, void *Info) |
563 | 77.8k | { |
564 | 77.8k | if (!printAliasInstruction(MI, O, Info)) |
565 | 73.9k | printInstruction(MI, O, Info); |
566 | 77.8k | } |
567 | | |
568 | | #endif |