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