Coverage Report

Created: 2025-07-20 06:54

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