/src/capstonenext/arch/TMS320C64x/TMS320C64xDisassembler.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 <string.h> |
7 | | |
8 | | #include "../../cs_priv.h" |
9 | | #include "../../utils.h" |
10 | | |
11 | | #include "TMS320C64xDisassembler.h" |
12 | | |
13 | | #include "../../MCInst.h" |
14 | | #include "../../MCInstrDesc.h" |
15 | | #include "../../MCFixedLenDisassembler.h" |
16 | | #include "../../MCRegisterInfo.h" |
17 | | #include "../../MCDisassembler.h" |
18 | | #include "../../MathExtras.h" |
19 | | |
20 | | static uint64_t getFeatureBits(int mode); |
21 | | |
22 | | static DecodeStatus DecodeGPRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
23 | | uint64_t Address, void *Decoder); |
24 | | |
25 | | static DecodeStatus DecodeControlRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
26 | | uint64_t Address, |
27 | | void *Decoder); |
28 | | |
29 | | static DecodeStatus DecodeScst5(MCInst *Inst, unsigned Val, uint64_t Address, |
30 | | void *Decoder); |
31 | | |
32 | | static DecodeStatus DecodeScst16(MCInst *Inst, unsigned Val, uint64_t Address, |
33 | | void *Decoder); |
34 | | |
35 | | static DecodeStatus DecodePCRelScst7(MCInst *Inst, unsigned Val, |
36 | | uint64_t Address, void *Decoder); |
37 | | |
38 | | static DecodeStatus DecodePCRelScst10(MCInst *Inst, unsigned Val, |
39 | | uint64_t Address, void *Decoder); |
40 | | |
41 | | static DecodeStatus DecodePCRelScst12(MCInst *Inst, unsigned Val, |
42 | | uint64_t Address, void *Decoder); |
43 | | |
44 | | static DecodeStatus DecodePCRelScst21(MCInst *Inst, unsigned Val, |
45 | | uint64_t Address, void *Decoder); |
46 | | |
47 | | static DecodeStatus DecodeMemOperand(MCInst *Inst, unsigned Val, |
48 | | uint64_t Address, void *Decoder); |
49 | | |
50 | | static DecodeStatus DecodeMemOperandSc(MCInst *Inst, unsigned Val, |
51 | | uint64_t Address, void *Decoder); |
52 | | |
53 | | static DecodeStatus DecodeMemOperand2(MCInst *Inst, unsigned Val, |
54 | | uint64_t Address, void *Decoder); |
55 | | |
56 | | static DecodeStatus DecodeRegPair5(MCInst *Inst, unsigned RegNo, |
57 | | uint64_t Address, void *Decoder); |
58 | | |
59 | | static DecodeStatus DecodeRegPair4(MCInst *Inst, unsigned RegNo, |
60 | | uint64_t Address, void *Decoder); |
61 | | |
62 | | static DecodeStatus DecodeCondRegister(MCInst *Inst, unsigned Val, |
63 | | uint64_t Address, void *Decoder); |
64 | | |
65 | | static DecodeStatus DecodeCondRegisterZero(MCInst *Inst, unsigned Val, |
66 | | uint64_t Address, void *Decoder); |
67 | | |
68 | | static DecodeStatus DecodeSide(MCInst *Inst, unsigned Val, uint64_t Address, |
69 | | void *Decoder); |
70 | | |
71 | | static DecodeStatus DecodeParallel(MCInst *Inst, unsigned Val, uint64_t Address, |
72 | | void *Decoder); |
73 | | |
74 | | static DecodeStatus DecodeCrosspathX1(MCInst *Inst, unsigned Val, |
75 | | uint64_t Address, void *Decoder); |
76 | | |
77 | | static DecodeStatus DecodeCrosspathX2(MCInst *Inst, unsigned Val, |
78 | | uint64_t Address, void *Decoder); |
79 | | |
80 | | static DecodeStatus DecodeCrosspathX3(MCInst *Inst, unsigned Val, |
81 | | uint64_t Address, void *Decoder); |
82 | | |
83 | | static DecodeStatus DecodeNop(MCInst *Inst, unsigned Val, uint64_t Address, |
84 | | void *Decoder); |
85 | | |
86 | | #include "TMS320C64xGenDisassemblerTables.inc" |
87 | | |
88 | | #define GET_REGINFO_ENUM |
89 | | #define GET_REGINFO_MC_DESC |
90 | | #include "TMS320C64xGenRegisterInfo.inc" |
91 | | |
92 | | static const unsigned GPRegsDecoderTable[] = { |
93 | | TMS320C64x_A0, TMS320C64x_A1, TMS320C64x_A2, TMS320C64x_A3, |
94 | | TMS320C64x_A4, TMS320C64x_A5, TMS320C64x_A6, TMS320C64x_A7, |
95 | | TMS320C64x_A8, TMS320C64x_A9, TMS320C64x_A10, TMS320C64x_A11, |
96 | | TMS320C64x_A12, TMS320C64x_A13, TMS320C64x_A14, TMS320C64x_A15, |
97 | | TMS320C64x_A16, TMS320C64x_A17, TMS320C64x_A18, TMS320C64x_A19, |
98 | | TMS320C64x_A20, TMS320C64x_A21, TMS320C64x_A22, TMS320C64x_A23, |
99 | | TMS320C64x_A24, TMS320C64x_A25, TMS320C64x_A26, TMS320C64x_A27, |
100 | | TMS320C64x_A28, TMS320C64x_A29, TMS320C64x_A30, TMS320C64x_A31 |
101 | | }; |
102 | | |
103 | | static const unsigned ControlRegsDecoderTable[] = { TMS320C64x_AMR, |
104 | | TMS320C64x_CSR, |
105 | | TMS320C64x_ISR, |
106 | | TMS320C64x_ICR, |
107 | | TMS320C64x_IER, |
108 | | TMS320C64x_ISTP, |
109 | | TMS320C64x_IRP, |
110 | | TMS320C64x_NRP, |
111 | | ~0U, |
112 | | ~0U, |
113 | | TMS320C64x_TSCL, |
114 | | TMS320C64x_TSCH, |
115 | | ~0U, |
116 | | TMS320C64x_ILC, |
117 | | TMS320C64x_RILC, |
118 | | TMS320C64x_REP, |
119 | | TMS320C64x_PCE1, |
120 | | TMS320C64x_DNUM, |
121 | | ~0U, |
122 | | ~0U, |
123 | | ~0U, |
124 | | TMS320C64x_SSR, |
125 | | TMS320C64x_GPLYA, |
126 | | TMS320C64x_GPLYB, |
127 | | TMS320C64x_GFPGFR, |
128 | | TMS320C64x_DIER, |
129 | | TMS320C64x_TSR, |
130 | | TMS320C64x_ITSR, |
131 | | TMS320C64x_NTSR, |
132 | | TMS320C64x_ECR, |
133 | | ~0U, |
134 | | TMS320C64x_IERR }; |
135 | | |
136 | | static uint64_t getFeatureBits(int mode) |
137 | 23.9k | { |
138 | | // support everything |
139 | 23.9k | return (uint64_t)-1; |
140 | 23.9k | } |
141 | | |
142 | | static unsigned getReg(const unsigned *RegTable, unsigned RegNo) |
143 | 42.5k | { |
144 | 42.5k | if (RegNo > 31) |
145 | 20 | return ~0U; |
146 | 42.5k | return RegTable[RegNo]; |
147 | 42.5k | } |
148 | | |
149 | | static DecodeStatus DecodeGPRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
150 | | uint64_t Address, void *Decoder) |
151 | 31.6k | { |
152 | 31.6k | unsigned Reg; |
153 | | |
154 | 31.6k | if (RegNo > 31) |
155 | 0 | return MCDisassembler_Fail; |
156 | | |
157 | 31.6k | Reg = getReg(GPRegsDecoderTable, RegNo); |
158 | 31.6k | if (Reg == ~0U) |
159 | 0 | return MCDisassembler_Fail; |
160 | 31.6k | MCOperand_CreateReg0(Inst, Reg); |
161 | | |
162 | 31.6k | return MCDisassembler_Success; |
163 | 31.6k | } |
164 | | |
165 | | static DecodeStatus DecodeControlRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
166 | | uint64_t Address, |
167 | | void *Decoder) |
168 | 1.14k | { |
169 | 1.14k | unsigned Reg; |
170 | | |
171 | 1.14k | if (RegNo > 31) |
172 | 0 | return MCDisassembler_Fail; |
173 | | |
174 | 1.14k | Reg = getReg(ControlRegsDecoderTable, RegNo); |
175 | 1.14k | if (Reg == ~0U) |
176 | 1 | return MCDisassembler_Fail; |
177 | 1.14k | MCOperand_CreateReg0(Inst, Reg); |
178 | | |
179 | 1.14k | return MCDisassembler_Success; |
180 | 1.14k | } |
181 | | |
182 | | static DecodeStatus DecodeScst5(MCInst *Inst, unsigned Val, uint64_t Address, |
183 | | void *Decoder) |
184 | 3.61k | { |
185 | 3.61k | int32_t imm; |
186 | | |
187 | 3.61k | imm = Val; |
188 | | /* Sign extend 5 bit value */ |
189 | 3.61k | if (imm & (1 << (5 - 1))) |
190 | 1.36k | imm |= ~((1 << 5) - 1); |
191 | | |
192 | 3.61k | MCOperand_CreateImm0(Inst, imm); |
193 | | |
194 | 3.61k | return MCDisassembler_Success; |
195 | 3.61k | } |
196 | | |
197 | | static DecodeStatus DecodeScst16(MCInst *Inst, unsigned Val, uint64_t Address, |
198 | | void *Decoder) |
199 | 897 | { |
200 | 897 | int32_t imm; |
201 | | |
202 | 897 | imm = Val; |
203 | | /* Sign extend 16 bit value */ |
204 | 897 | if (imm & (1 << (16 - 1))) |
205 | 647 | imm |= ~((1 << 16) - 1); |
206 | | |
207 | 897 | MCOperand_CreateImm0(Inst, imm); |
208 | | |
209 | 897 | return MCDisassembler_Success; |
210 | 897 | } |
211 | | |
212 | | static DecodeStatus DecodePCRelScst7(MCInst *Inst, unsigned Val, |
213 | | uint64_t Address, void *Decoder) |
214 | 355 | { |
215 | 355 | int32_t imm; |
216 | | |
217 | 355 | imm = Val; |
218 | | /* Sign extend 7 bit value */ |
219 | 355 | if (imm & (1 << (7 - 1))) |
220 | 328 | imm |= ~((1 << 7) - 1); |
221 | | |
222 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
223 | 355 | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
224 | | |
225 | 355 | return MCDisassembler_Success; |
226 | 355 | } |
227 | | |
228 | | static DecodeStatus DecodePCRelScst10(MCInst *Inst, unsigned Val, |
229 | | uint64_t Address, void *Decoder) |
230 | 499 | { |
231 | 499 | int32_t imm; |
232 | | |
233 | 499 | imm = Val; |
234 | | /* Sign extend 10 bit value */ |
235 | 499 | if (imm & (1 << (10 - 1))) |
236 | 273 | imm |= ~((1 << 10) - 1); |
237 | | |
238 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
239 | 499 | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
240 | | |
241 | 499 | return MCDisassembler_Success; |
242 | 499 | } |
243 | | |
244 | | static DecodeStatus DecodePCRelScst12(MCInst *Inst, unsigned Val, |
245 | | uint64_t Address, void *Decoder) |
246 | 287 | { |
247 | 287 | int32_t imm; |
248 | | |
249 | 287 | imm = Val; |
250 | | /* Sign extend 12 bit value */ |
251 | 287 | if (imm & (1 << (12 - 1))) |
252 | 84 | imm |= ~((1 << 12) - 1); |
253 | | |
254 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
255 | 287 | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
256 | | |
257 | 287 | return MCDisassembler_Success; |
258 | 287 | } |
259 | | |
260 | | static DecodeStatus DecodePCRelScst21(MCInst *Inst, unsigned Val, |
261 | | uint64_t Address, void *Decoder) |
262 | 1.48k | { |
263 | 1.48k | int32_t imm; |
264 | | |
265 | 1.48k | imm = Val; |
266 | | /* Sign extend 21 bit value */ |
267 | 1.48k | if (imm & (1 << (21 - 1))) |
268 | 698 | imm |= ~((1 << 21) - 1); |
269 | | |
270 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
271 | 1.48k | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
272 | | |
273 | 1.48k | return MCDisassembler_Success; |
274 | 1.48k | } |
275 | | |
276 | | static DecodeStatus DecodeMemOperand(MCInst *Inst, unsigned Val, |
277 | | uint64_t Address, void *Decoder) |
278 | 2.20k | { |
279 | 2.20k | return DecodeMemOperandSc(Inst, Val | (1 << 15), Address, Decoder); |
280 | 2.20k | } |
281 | | |
282 | | static DecodeStatus DecodeMemOperandSc(MCInst *Inst, unsigned Val, |
283 | | uint64_t Address, void *Decoder) |
284 | 2.47k | { |
285 | 2.47k | uint8_t scaled, base, offset, mode, unit; |
286 | 2.47k | unsigned basereg, offsetreg; |
287 | | |
288 | 2.47k | scaled = (Val >> 15) & 1; |
289 | 2.47k | base = (Val >> 10) & 0x1f; |
290 | 2.47k | offset = (Val >> 5) & 0x1f; |
291 | 2.47k | mode = (Val >> 1) & 0xf; |
292 | 2.47k | unit = Val & 1; |
293 | | |
294 | 2.47k | if ((base >= TMS320C64X_REG_A0) && (base <= TMS320C64X_REG_A31)) |
295 | 18 | base = (base - TMS320C64X_REG_A0 + TMS320C64X_REG_B0); |
296 | | // base cannot be a B register, because it was ANDed above with 0x1f. |
297 | | // And the TMS320C64X_REG_B0 > 31 |
298 | 2.47k | basereg = getReg(GPRegsDecoderTable, base); |
299 | 2.47k | if (basereg == ~0U) |
300 | 18 | return MCDisassembler_Fail; |
301 | | |
302 | 2.45k | switch (mode) { |
303 | 652 | case 0: |
304 | 889 | case 1: |
305 | 1.12k | case 8: |
306 | 1.32k | case 9: |
307 | 1.57k | case 10: |
308 | 1.83k | case 11: |
309 | 1.83k | MCOperand_CreateImm0(Inst, (scaled << 19) | (basereg << 12) | |
310 | 1.83k | (offset << 5) | (mode << 1) | |
311 | 1.83k | unit); |
312 | 1.83k | break; |
313 | 105 | case 4: |
314 | 185 | case 5: |
315 | 239 | case 12: |
316 | 373 | case 13: |
317 | 404 | case 14: |
318 | 605 | case 15: |
319 | 605 | if ((offset >= TMS320C64X_REG_A0) && |
320 | 605 | (offset <= TMS320C64X_REG_A31)) |
321 | 2 | offset = (offset - TMS320C64X_REG_A0 + |
322 | 2 | TMS320C64X_REG_B0); |
323 | | // offset cannot be a B register, because it was ANDed above with 0x1f. |
324 | | // And the TMS320C64X_REG_B0 > 31 |
325 | 605 | offsetreg = getReg(GPRegsDecoderTable, offset); |
326 | 605 | if (offsetreg == ~0U) |
327 | 2 | return MCDisassembler_Fail; |
328 | 603 | MCOperand_CreateImm0(Inst, (scaled << 19) | (basereg << 12) | |
329 | 603 | (offsetreg << 5) | |
330 | 603 | (mode << 1) | unit); |
331 | 603 | break; |
332 | 12 | default: |
333 | 12 | return MCDisassembler_Fail; |
334 | 2.45k | } |
335 | | |
336 | 2.44k | return MCDisassembler_Success; |
337 | 2.45k | } |
338 | | |
339 | | static DecodeStatus DecodeMemOperand2(MCInst *Inst, unsigned Val, |
340 | | uint64_t Address, void *Decoder) |
341 | 2.53k | { |
342 | 2.53k | uint16_t offset; |
343 | 2.53k | unsigned basereg; |
344 | | |
345 | 2.53k | if (Val & 1) |
346 | 1.22k | basereg = TMS320C64X_REG_B15; |
347 | 1.30k | else |
348 | 1.30k | basereg = TMS320C64X_REG_B14; |
349 | | |
350 | 2.53k | offset = (Val >> 1) & 0x7fff; |
351 | 2.53k | MCOperand_CreateImm0(Inst, (offset << 7) | basereg); |
352 | | |
353 | 2.53k | return MCDisassembler_Success; |
354 | 2.53k | } |
355 | | |
356 | | static DecodeStatus DecodeRegPair5(MCInst *Inst, unsigned RegNo, |
357 | | uint64_t Address, void *Decoder) |
358 | 6.45k | { |
359 | 6.45k | unsigned Reg; |
360 | | |
361 | 6.45k | if (RegNo > 31) |
362 | 0 | return MCDisassembler_Fail; |
363 | | |
364 | 6.45k | Reg = getReg(GPRegsDecoderTable, RegNo); |
365 | 6.45k | MCOperand_CreateReg0(Inst, Reg); |
366 | | |
367 | 6.45k | return MCDisassembler_Success; |
368 | 6.45k | } |
369 | | |
370 | | static DecodeStatus DecodeRegPair4(MCInst *Inst, unsigned RegNo, |
371 | | uint64_t Address, void *Decoder) |
372 | 272 | { |
373 | 272 | unsigned Reg; |
374 | | |
375 | 272 | if (RegNo > 15) |
376 | 0 | return MCDisassembler_Fail; |
377 | | |
378 | 272 | Reg = getReg(GPRegsDecoderTable, RegNo << 1); |
379 | 272 | MCOperand_CreateReg0(Inst, Reg); |
380 | | |
381 | 272 | return MCDisassembler_Success; |
382 | 272 | } |
383 | | |
384 | | static DecodeStatus DecodeCondRegister(MCInst *Inst, unsigned Val, |
385 | | uint64_t Address, void *Decoder) |
386 | 23.8k | { |
387 | 23.8k | DecodeStatus ret = MCDisassembler_Success; |
388 | | |
389 | 23.8k | if (!Inst->flat_insn->detail) |
390 | 0 | return MCDisassembler_Success; |
391 | | |
392 | 23.8k | switch (Val) { |
393 | 5.41k | case 0: |
394 | 10.0k | case 7: |
395 | 10.0k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
396 | 10.0k | TMS320C64X_REG_INVALID; |
397 | 10.0k | break; |
398 | 2.79k | case 1: |
399 | 2.79k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
400 | 2.79k | TMS320C64X_REG_B0; |
401 | 2.79k | break; |
402 | 2.26k | case 2: |
403 | 2.26k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
404 | 2.26k | TMS320C64X_REG_B1; |
405 | 2.26k | break; |
406 | 2.64k | case 3: |
407 | 2.64k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
408 | 2.64k | TMS320C64X_REG_B2; |
409 | 2.64k | break; |
410 | 2.55k | case 4: |
411 | 2.55k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
412 | 2.55k | TMS320C64X_REG_A1; |
413 | 2.55k | break; |
414 | 2.17k | case 5: |
415 | 2.17k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
416 | 2.17k | TMS320C64X_REG_A2; |
417 | 2.17k | break; |
418 | 1.38k | case 6: |
419 | 1.38k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
420 | 1.38k | TMS320C64X_REG_A0; |
421 | 1.38k | break; |
422 | 0 | default: |
423 | 0 | Inst->flat_insn->detail->tms320c64x.condition.reg = |
424 | 0 | TMS320C64X_REG_INVALID; |
425 | 0 | ret = MCDisassembler_Fail; |
426 | 0 | break; |
427 | 23.8k | } |
428 | | |
429 | 23.8k | return ret; |
430 | 23.8k | } |
431 | | |
432 | | static DecodeStatus DecodeCondRegisterZero(MCInst *Inst, unsigned Val, |
433 | | uint64_t Address, void *Decoder) |
434 | 23.8k | { |
435 | 23.8k | DecodeStatus ret = MCDisassembler_Success; |
436 | | |
437 | 23.8k | if (!Inst->flat_insn->detail) |
438 | 0 | return MCDisassembler_Success; |
439 | | |
440 | 23.8k | switch (Val) { |
441 | 12.0k | case 0: |
442 | 12.0k | Inst->flat_insn->detail->tms320c64x.condition.zero = 0; |
443 | 12.0k | break; |
444 | 11.7k | case 1: |
445 | 11.7k | Inst->flat_insn->detail->tms320c64x.condition.zero = 1; |
446 | 11.7k | break; |
447 | 0 | default: |
448 | 0 | Inst->flat_insn->detail->tms320c64x.condition.zero = 0; |
449 | 0 | ret = MCDisassembler_Fail; |
450 | 0 | break; |
451 | 23.8k | } |
452 | | |
453 | 23.8k | return ret; |
454 | 23.8k | } |
455 | | |
456 | | static DecodeStatus DecodeSide(MCInst *Inst, unsigned Val, uint64_t Address, |
457 | | void *Decoder) |
458 | 23.8k | { |
459 | 23.8k | DecodeStatus ret = MCDisassembler_Success; |
460 | 23.8k | MCOperand *op; |
461 | 23.8k | int i; |
462 | | |
463 | | /* This is pretty messy, probably we should find a better way */ |
464 | 23.8k | if (Val == 1) { |
465 | 38.3k | for (i = 0; i < Inst->size; i++) { |
466 | 27.5k | op = &Inst->Operands[i]; |
467 | 27.5k | if (op->Kind == kRegister) { |
468 | 19.2k | if ((op->RegVal >= TMS320C64X_REG_A0) && |
469 | 19.2k | (op->RegVal <= TMS320C64X_REG_A31)) |
470 | 16.5k | op->RegVal = (op->RegVal - |
471 | 16.5k | TMS320C64X_REG_A0 + |
472 | 16.5k | TMS320C64X_REG_B0); |
473 | 2.66k | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
474 | 2.66k | (op->RegVal <= TMS320C64X_REG_B31)) |
475 | 1.57k | op->RegVal = (op->RegVal - |
476 | 1.57k | TMS320C64X_REG_B0 + |
477 | 1.57k | TMS320C64X_REG_A0); |
478 | 19.2k | } |
479 | 27.5k | } |
480 | 10.7k | } |
481 | | |
482 | 23.8k | if (!Inst->flat_insn->detail) |
483 | 0 | return MCDisassembler_Success; |
484 | | |
485 | 23.8k | switch (Val) { |
486 | 13.0k | case 0: |
487 | 13.0k | Inst->flat_insn->detail->tms320c64x.funit.side = 1; |
488 | 13.0k | break; |
489 | 10.7k | case 1: |
490 | 10.7k | Inst->flat_insn->detail->tms320c64x.funit.side = 2; |
491 | 10.7k | break; |
492 | 0 | default: |
493 | 0 | Inst->flat_insn->detail->tms320c64x.funit.side = 0; |
494 | 0 | ret = MCDisassembler_Fail; |
495 | 0 | break; |
496 | 23.8k | } |
497 | | |
498 | 23.8k | return ret; |
499 | 23.8k | } |
500 | | |
501 | | static DecodeStatus DecodeParallel(MCInst *Inst, unsigned Val, uint64_t Address, |
502 | | void *Decoder) |
503 | 23.8k | { |
504 | 23.8k | DecodeStatus ret = MCDisassembler_Success; |
505 | | |
506 | 23.8k | if (!Inst->flat_insn->detail) |
507 | 0 | return MCDisassembler_Success; |
508 | | |
509 | 23.8k | switch (Val) { |
510 | 13.6k | case 0: |
511 | 13.6k | Inst->flat_insn->detail->tms320c64x.parallel = 0; |
512 | 13.6k | break; |
513 | 10.1k | case 1: |
514 | 10.1k | Inst->flat_insn->detail->tms320c64x.parallel = 1; |
515 | 10.1k | break; |
516 | 0 | default: |
517 | 0 | Inst->flat_insn->detail->tms320c64x.parallel = -1; |
518 | 0 | ret = MCDisassembler_Fail; |
519 | 0 | break; |
520 | 23.8k | } |
521 | | |
522 | 23.8k | return ret; |
523 | 23.8k | } |
524 | | |
525 | | static DecodeStatus DecodeCrosspathX1(MCInst *Inst, unsigned Val, |
526 | | uint64_t Address, void *Decoder) |
527 | 392 | { |
528 | 392 | DecodeStatus ret = MCDisassembler_Success; |
529 | 392 | MCOperand *op; |
530 | | |
531 | 392 | if (!Inst->flat_insn->detail) |
532 | 0 | return MCDisassembler_Success; |
533 | | |
534 | 392 | switch (Val) { |
535 | 173 | case 0: |
536 | 173 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
537 | 173 | break; |
538 | 219 | case 1: |
539 | 219 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 1; |
540 | 219 | op = &Inst->Operands[0]; |
541 | 219 | if (op->Kind == kRegister) { |
542 | 219 | if ((op->RegVal >= TMS320C64X_REG_A0) && |
543 | 219 | (op->RegVal <= TMS320C64X_REG_A31)) |
544 | 219 | op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + |
545 | 219 | TMS320C64X_REG_B0); |
546 | 0 | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
547 | 0 | (op->RegVal <= TMS320C64X_REG_B31)) |
548 | 0 | op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + |
549 | 0 | TMS320C64X_REG_A0); |
550 | 219 | } |
551 | 219 | break; |
552 | 0 | default: |
553 | 0 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
554 | 0 | ret = MCDisassembler_Fail; |
555 | 0 | break; |
556 | 392 | } |
557 | | |
558 | 392 | return ret; |
559 | 392 | } |
560 | | |
561 | | static DecodeStatus DecodeCrosspathX2(MCInst *Inst, unsigned Val, |
562 | | uint64_t Address, void *Decoder) |
563 | 8.75k | { |
564 | 8.75k | DecodeStatus ret = MCDisassembler_Success; |
565 | 8.75k | MCOperand *op; |
566 | | |
567 | 8.75k | if (!Inst->flat_insn->detail) |
568 | 0 | return MCDisassembler_Success; |
569 | | |
570 | 8.75k | switch (Val) { |
571 | 4.54k | case 0: |
572 | 4.54k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
573 | 4.54k | break; |
574 | 4.20k | case 1: |
575 | 4.20k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 1; |
576 | 4.20k | op = &Inst->Operands[1]; |
577 | 4.20k | if (op->Kind == kRegister) { |
578 | 3.81k | if ((op->RegVal >= TMS320C64X_REG_A0) && |
579 | 3.81k | (op->RegVal <= TMS320C64X_REG_A31)) |
580 | 2.78k | op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + |
581 | 2.78k | TMS320C64X_REG_B0); |
582 | 1.03k | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
583 | 1.03k | (op->RegVal <= TMS320C64X_REG_B31)) |
584 | 0 | op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + |
585 | 0 | TMS320C64X_REG_A0); |
586 | 3.81k | } |
587 | 4.20k | break; |
588 | 0 | default: |
589 | 0 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
590 | 0 | ret = MCDisassembler_Fail; |
591 | 0 | break; |
592 | 8.75k | } |
593 | | |
594 | 8.75k | return ret; |
595 | 8.75k | } |
596 | | |
597 | | static DecodeStatus DecodeCrosspathX3(MCInst *Inst, unsigned Val, |
598 | | uint64_t Address, void *Decoder) |
599 | 3.13k | { |
600 | 3.13k | DecodeStatus ret = MCDisassembler_Success; |
601 | 3.13k | MCOperand *op; |
602 | | |
603 | 3.13k | if (!Inst->flat_insn->detail) |
604 | 0 | return MCDisassembler_Success; |
605 | | |
606 | 3.13k | switch (Val) { |
607 | 1.29k | case 0: |
608 | 1.29k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
609 | 1.29k | break; |
610 | 1.84k | case 1: |
611 | 1.84k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 2; |
612 | 1.84k | op = &Inst->Operands[2]; |
613 | 1.84k | if (op->Kind == kRegister) { |
614 | 401 | if ((op->RegVal >= TMS320C64X_REG_A0) && |
615 | 401 | (op->RegVal <= TMS320C64X_REG_A31)) |
616 | 401 | op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + |
617 | 401 | TMS320C64X_REG_B0); |
618 | 0 | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
619 | 0 | (op->RegVal <= TMS320C64X_REG_B31)) |
620 | 0 | op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + |
621 | 0 | TMS320C64X_REG_A0); |
622 | 401 | } |
623 | 1.84k | break; |
624 | 0 | default: |
625 | 0 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
626 | 0 | ret = MCDisassembler_Fail; |
627 | 0 | break; |
628 | 3.13k | } |
629 | | |
630 | 3.13k | return ret; |
631 | 3.13k | } |
632 | | |
633 | | static DecodeStatus DecodeNop(MCInst *Inst, unsigned Val, uint64_t Address, |
634 | | void *Decoder) |
635 | 675 | { |
636 | 675 | MCOperand_CreateImm0(Inst, Val + 1); |
637 | | |
638 | 675 | return MCDisassembler_Success; |
639 | 675 | } |
640 | | |
641 | | #define GET_INSTRINFO_ENUM |
642 | | #include "TMS320C64xGenInstrInfo.inc" |
643 | | |
644 | | bool TMS320C64x_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
645 | | MCInst *MI, uint16_t *size, uint64_t address, |
646 | | void *info) |
647 | 24.2k | { |
648 | 24.2k | uint32_t insn; |
649 | 24.2k | DecodeStatus result; |
650 | | |
651 | 24.2k | if (code_len < 4) { |
652 | 280 | *size = 0; |
653 | 280 | return MCDisassembler_Fail; |
654 | 280 | } |
655 | | |
656 | 23.9k | if (MI->flat_insn->detail) |
657 | 23.9k | memset(MI->flat_insn->detail, 0, |
658 | 23.9k | offsetof(cs_detail, tms320c64x) + sizeof(cs_tms320c64x)); |
659 | | |
660 | 23.9k | insn = readBytes32(MI, code); |
661 | 23.9k | result = |
662 | 23.9k | decodeInstruction_4(DecoderTable32, MI, insn, address, info, 0); |
663 | | |
664 | 23.9k | if (result == MCDisassembler_Success) { |
665 | 23.8k | *size = 4; |
666 | 23.8k | return true; |
667 | 23.8k | } |
668 | | |
669 | 173 | MCInst_clear(MI); |
670 | 173 | *size = 0; |
671 | 173 | return false; |
672 | 23.9k | } |
673 | | |
674 | | void TMS320C64x_init(MCRegisterInfo *MRI) |
675 | 740 | { |
676 | 740 | MCRegisterInfo_InitMCRegisterInfo(MRI, TMS320C64xRegDesc, 90, 0, 0, |
677 | 740 | TMS320C64xMCRegisterClasses, 7, 0, 0, |
678 | 740 | TMS320C64xRegDiffLists, 0, |
679 | 740 | TMS320C64xSubRegIdxLists, 1, 0); |
680 | 740 | } |
681 | | |
682 | | #endif |