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