/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 | 68.7k | { |
138 | | // support everything |
139 | 68.7k | return (uint64_t)-1; |
140 | 68.7k | } |
141 | | |
142 | | static unsigned getReg(const unsigned *RegTable, unsigned RegNo) |
143 | 126k | { |
144 | 126k | if (RegNo > 31) |
145 | 54 | return ~0U; |
146 | 126k | return RegTable[RegNo]; |
147 | 126k | } |
148 | | |
149 | | static DecodeStatus DecodeGPRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
150 | | uint64_t Address, void *Decoder) |
151 | 88.2k | { |
152 | 88.2k | unsigned Reg; |
153 | | |
154 | 88.2k | if (RegNo > 31) |
155 | 0 | return MCDisassembler_Fail; |
156 | | |
157 | 88.2k | Reg = getReg(GPRegsDecoderTable, RegNo); |
158 | 88.2k | if (Reg == ~0U) |
159 | 0 | return MCDisassembler_Fail; |
160 | 88.2k | MCOperand_CreateReg0(Inst, Reg); |
161 | | |
162 | 88.2k | return MCDisassembler_Success; |
163 | 88.2k | } |
164 | | |
165 | | static DecodeStatus DecodeControlRegsRegisterClass(MCInst *Inst, unsigned RegNo, |
166 | | uint64_t Address, |
167 | | void *Decoder) |
168 | 2.25k | { |
169 | 2.25k | unsigned Reg; |
170 | | |
171 | 2.25k | if (RegNo > 31) |
172 | 0 | return MCDisassembler_Fail; |
173 | | |
174 | 2.25k | Reg = getReg(ControlRegsDecoderTable, RegNo); |
175 | 2.25k | if (Reg == ~0U) |
176 | 5 | return MCDisassembler_Fail; |
177 | 2.24k | MCOperand_CreateReg0(Inst, Reg); |
178 | | |
179 | 2.24k | return MCDisassembler_Success; |
180 | 2.25k | } |
181 | | |
182 | | static DecodeStatus DecodeScst5(MCInst *Inst, unsigned Val, uint64_t Address, |
183 | | void *Decoder) |
184 | 11.0k | { |
185 | 11.0k | int32_t imm; |
186 | | |
187 | 11.0k | imm = Val; |
188 | | /* Sign extend 5 bit value */ |
189 | 11.0k | if (imm & (1 << (5 - 1))) |
190 | 5.72k | imm |= ~((1 << 5) - 1); |
191 | | |
192 | 11.0k | MCOperand_CreateImm0(Inst, imm); |
193 | | |
194 | 11.0k | return MCDisassembler_Success; |
195 | 11.0k | } |
196 | | |
197 | | static DecodeStatus DecodeScst16(MCInst *Inst, unsigned Val, uint64_t Address, |
198 | | void *Decoder) |
199 | 3.02k | { |
200 | 3.02k | int32_t imm; |
201 | | |
202 | 3.02k | imm = Val; |
203 | | /* Sign extend 16 bit value */ |
204 | 3.02k | if (imm & (1 << (16 - 1))) |
205 | 1.69k | imm |= ~((1 << 16) - 1); |
206 | | |
207 | 3.02k | MCOperand_CreateImm0(Inst, imm); |
208 | | |
209 | 3.02k | return MCDisassembler_Success; |
210 | 3.02k | } |
211 | | |
212 | | static DecodeStatus DecodePCRelScst7(MCInst *Inst, unsigned Val, |
213 | | uint64_t Address, void *Decoder) |
214 | 2.51k | { |
215 | 2.51k | int32_t imm; |
216 | | |
217 | 2.51k | imm = Val; |
218 | | /* Sign extend 7 bit value */ |
219 | 2.51k | if (imm & (1 << (7 - 1))) |
220 | 1.78k | imm |= ~((1 << 7) - 1); |
221 | | |
222 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
223 | 2.51k | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
224 | | |
225 | 2.51k | return MCDisassembler_Success; |
226 | 2.51k | } |
227 | | |
228 | | static DecodeStatus DecodePCRelScst10(MCInst *Inst, unsigned Val, |
229 | | uint64_t Address, void *Decoder) |
230 | 1.08k | { |
231 | 1.08k | int32_t imm; |
232 | | |
233 | 1.08k | imm = Val; |
234 | | /* Sign extend 10 bit value */ |
235 | 1.08k | if (imm & (1 << (10 - 1))) |
236 | 352 | imm |= ~((1 << 10) - 1); |
237 | | |
238 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
239 | 1.08k | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
240 | | |
241 | 1.08k | return MCDisassembler_Success; |
242 | 1.08k | } |
243 | | |
244 | | static DecodeStatus DecodePCRelScst12(MCInst *Inst, unsigned Val, |
245 | | uint64_t Address, void *Decoder) |
246 | 1.44k | { |
247 | 1.44k | int32_t imm; |
248 | | |
249 | 1.44k | imm = Val; |
250 | | /* Sign extend 12 bit value */ |
251 | 1.44k | if (imm & (1 << (12 - 1))) |
252 | 614 | imm |= ~((1 << 12) - 1); |
253 | | |
254 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
255 | 1.44k | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
256 | | |
257 | 1.44k | return MCDisassembler_Success; |
258 | 1.44k | } |
259 | | |
260 | | static DecodeStatus DecodePCRelScst21(MCInst *Inst, unsigned Val, |
261 | | uint64_t Address, void *Decoder) |
262 | 2.90k | { |
263 | 2.90k | int32_t imm; |
264 | | |
265 | 2.90k | imm = Val; |
266 | | /* Sign extend 21 bit value */ |
267 | 2.90k | if (imm & (1 << (21 - 1))) |
268 | 1.09k | imm |= ~((1 << 21) - 1); |
269 | | |
270 | | /* Address is relative to the address of the first instruction in the fetch packet */ |
271 | 2.90k | MCOperand_CreateImm0(Inst, (Address & ~31) + (imm * 4)); |
272 | | |
273 | 2.90k | return MCDisassembler_Success; |
274 | 2.90k | } |
275 | | |
276 | | static DecodeStatus DecodeMemOperand(MCInst *Inst, unsigned Val, |
277 | | uint64_t Address, void *Decoder) |
278 | 7.48k | { |
279 | 7.48k | return DecodeMemOperandSc(Inst, Val | (1 << 15), Address, Decoder); |
280 | 7.48k | } |
281 | | |
282 | | static DecodeStatus DecodeMemOperandSc(MCInst *Inst, unsigned Val, |
283 | | uint64_t Address, void *Decoder) |
284 | 4.31k | { |
285 | 4.31k | uint8_t scaled, base, offset, mode, unit; |
286 | 4.31k | unsigned basereg, offsetreg; |
287 | | |
288 | 4.31k | scaled = (Val >> 15) & 1; |
289 | 4.31k | base = (Val >> 10) & 0x1f; |
290 | 4.31k | offset = (Val >> 5) & 0x1f; |
291 | 4.31k | mode = (Val >> 1) & 0xf; |
292 | 4.31k | unit = Val & 1; |
293 | | |
294 | 4.31k | if ((base >= TMS320C64X_REG_A0) && (base <= TMS320C64X_REG_A31)) |
295 | 23 | 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 | 4.31k | basereg = getReg(GPRegsDecoderTable, base); |
299 | 4.31k | if (basereg == ~0U) |
300 | 23 | return MCDisassembler_Fail; |
301 | | |
302 | 4.29k | switch (mode) { |
303 | 740 | case 0: |
304 | 973 | case 1: |
305 | 1.23k | case 8: |
306 | 1.51k | case 9: |
307 | 1.91k | case 10: |
308 | 2.32k | case 11: |
309 | 2.32k | MCOperand_CreateImm0(Inst, (scaled << 19) | (basereg << 12) | |
310 | 2.32k | (offset << 5) | (mode << 1) | |
311 | 2.32k | unit); |
312 | 2.32k | break; |
313 | 284 | case 4: |
314 | 505 | case 5: |
315 | 801 | case 12: |
316 | 1.24k | case 13: |
317 | 1.61k | case 14: |
318 | 1.94k | case 15: |
319 | 1.94k | if ((offset >= TMS320C64X_REG_A0) && |
320 | 1.94k | (offset <= TMS320C64X_REG_A31)) |
321 | 3 | offset = (offset - TMS320C64X_REG_A0 + |
322 | 3 | 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 | 1.94k | offsetreg = getReg(GPRegsDecoderTable, offset); |
326 | 1.94k | if (offsetreg == ~0U) |
327 | 3 | return MCDisassembler_Fail; |
328 | 1.94k | MCOperand_CreateImm0(Inst, (scaled << 19) | (basereg << 12) | |
329 | 1.94k | (offsetreg << 5) | |
330 | 1.94k | (mode << 1) | unit); |
331 | 1.94k | break; |
332 | 16 | default: |
333 | 16 | return MCDisassembler_Fail; |
334 | 4.29k | } |
335 | | |
336 | 4.27k | return MCDisassembler_Success; |
337 | 4.29k | } |
338 | | |
339 | | static DecodeStatus DecodeMemOperand2(MCInst *Inst, unsigned Val, |
340 | | uint64_t Address, void *Decoder) |
341 | 5.00k | { |
342 | 5.00k | uint16_t offset; |
343 | 5.00k | unsigned basereg; |
344 | | |
345 | 5.00k | if (Val & 1) |
346 | 2.94k | basereg = TMS320C64X_REG_B15; |
347 | 2.06k | else |
348 | 2.06k | basereg = TMS320C64X_REG_B14; |
349 | | |
350 | 5.00k | offset = (Val >> 1) & 0x7fff; |
351 | 5.00k | MCOperand_CreateImm0(Inst, (offset << 7) | basereg); |
352 | | |
353 | 5.00k | return MCDisassembler_Success; |
354 | 5.00k | } |
355 | | |
356 | | static DecodeStatus DecodeRegPair5(MCInst *Inst, unsigned RegNo, |
357 | | uint64_t Address, void *Decoder) |
358 | 21.7k | { |
359 | 21.7k | unsigned Reg; |
360 | | |
361 | 21.7k | if (RegNo > 31) |
362 | 0 | return MCDisassembler_Fail; |
363 | | |
364 | 21.7k | Reg = getReg(GPRegsDecoderTable, RegNo); |
365 | 21.7k | MCOperand_CreateReg0(Inst, Reg); |
366 | | |
367 | 21.7k | return MCDisassembler_Success; |
368 | 21.7k | } |
369 | | |
370 | | static DecodeStatus DecodeRegPair4(MCInst *Inst, unsigned RegNo, |
371 | | uint64_t Address, void *Decoder) |
372 | 1.62k | { |
373 | 1.62k | unsigned Reg; |
374 | | |
375 | 1.62k | if (RegNo > 15) |
376 | 0 | return MCDisassembler_Fail; |
377 | | |
378 | 1.62k | Reg = getReg(GPRegsDecoderTable, RegNo << 1); |
379 | 1.62k | MCOperand_CreateReg0(Inst, Reg); |
380 | | |
381 | 1.62k | return MCDisassembler_Success; |
382 | 1.62k | } |
383 | | |
384 | | static DecodeStatus DecodeCondRegister(MCInst *Inst, unsigned Val, |
385 | | uint64_t Address, void *Decoder) |
386 | 68.3k | { |
387 | 68.3k | DecodeStatus ret = MCDisassembler_Success; |
388 | | |
389 | 68.3k | if (!Inst->flat_insn->detail) |
390 | 0 | return MCDisassembler_Success; |
391 | | |
392 | 68.3k | switch (Val) { |
393 | 14.5k | case 0: |
394 | 23.9k | case 7: |
395 | 23.9k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
396 | 23.9k | TMS320C64X_REG_INVALID; |
397 | 23.9k | break; |
398 | 8.29k | case 1: |
399 | 8.29k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
400 | 8.29k | TMS320C64X_REG_B0; |
401 | 8.29k | break; |
402 | 6.58k | case 2: |
403 | 6.58k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
404 | 6.58k | TMS320C64X_REG_B1; |
405 | 6.58k | break; |
406 | 9.08k | case 3: |
407 | 9.08k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
408 | 9.08k | TMS320C64X_REG_B2; |
409 | 9.08k | break; |
410 | 7.37k | case 4: |
411 | 7.37k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
412 | 7.37k | TMS320C64X_REG_A1; |
413 | 7.37k | break; |
414 | 7.79k | case 5: |
415 | 7.79k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
416 | 7.79k | TMS320C64X_REG_A2; |
417 | 7.79k | break; |
418 | 5.28k | case 6: |
419 | 5.28k | Inst->flat_insn->detail->tms320c64x.condition.reg = |
420 | 5.28k | TMS320C64X_REG_A0; |
421 | 5.28k | 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 | 68.3k | } |
428 | | |
429 | 68.3k | return ret; |
430 | 68.3k | } |
431 | | |
432 | | static DecodeStatus DecodeCondRegisterZero(MCInst *Inst, unsigned Val, |
433 | | uint64_t Address, void *Decoder) |
434 | 68.3k | { |
435 | 68.3k | DecodeStatus ret = MCDisassembler_Success; |
436 | | |
437 | 68.3k | if (!Inst->flat_insn->detail) |
438 | 0 | return MCDisassembler_Success; |
439 | | |
440 | 68.3k | switch (Val) { |
441 | 36.9k | case 0: |
442 | 36.9k | Inst->flat_insn->detail->tms320c64x.condition.zero = 0; |
443 | 36.9k | break; |
444 | 31.3k | case 1: |
445 | 31.3k | Inst->flat_insn->detail->tms320c64x.condition.zero = 1; |
446 | 31.3k | break; |
447 | 0 | default: |
448 | 0 | Inst->flat_insn->detail->tms320c64x.condition.zero = 0; |
449 | 0 | ret = MCDisassembler_Fail; |
450 | 0 | break; |
451 | 68.3k | } |
452 | | |
453 | 68.3k | return ret; |
454 | 68.3k | } |
455 | | |
456 | | static DecodeStatus DecodeSide(MCInst *Inst, unsigned Val, uint64_t Address, |
457 | | void *Decoder) |
458 | 68.3k | { |
459 | 68.3k | DecodeStatus ret = MCDisassembler_Success; |
460 | 68.3k | MCOperand *op; |
461 | 68.3k | int i; |
462 | | |
463 | | /* This is pretty messy, probably we should find a better way */ |
464 | 68.3k | if (Val == 1) { |
465 | 100k | for (i = 0; i < Inst->size; i++) { |
466 | 71.5k | op = &Inst->Operands[i]; |
467 | 71.5k | if (op->Kind == kRegister) { |
468 | 48.9k | if ((op->RegVal >= TMS320C64X_REG_A0) && |
469 | 48.9k | (op->RegVal <= TMS320C64X_REG_A31)) |
470 | 43.0k | op->RegVal = (op->RegVal - |
471 | 43.0k | TMS320C64X_REG_A0 + |
472 | 43.0k | TMS320C64X_REG_B0); |
473 | 5.92k | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
474 | 5.92k | (op->RegVal <= TMS320C64X_REG_B31)) |
475 | 3.75k | op->RegVal = (op->RegVal - |
476 | 3.75k | TMS320C64X_REG_B0 + |
477 | 3.75k | TMS320C64X_REG_A0); |
478 | 48.9k | } |
479 | 71.5k | } |
480 | 28.8k | } |
481 | | |
482 | 68.3k | if (!Inst->flat_insn->detail) |
483 | 0 | return MCDisassembler_Success; |
484 | | |
485 | 68.3k | switch (Val) { |
486 | 39.5k | case 0: |
487 | 39.5k | Inst->flat_insn->detail->tms320c64x.funit.side = 1; |
488 | 39.5k | break; |
489 | 28.8k | case 1: |
490 | 28.8k | Inst->flat_insn->detail->tms320c64x.funit.side = 2; |
491 | 28.8k | break; |
492 | 0 | default: |
493 | 0 | Inst->flat_insn->detail->tms320c64x.funit.side = 0; |
494 | 0 | ret = MCDisassembler_Fail; |
495 | 0 | break; |
496 | 68.3k | } |
497 | | |
498 | 68.3k | return ret; |
499 | 68.3k | } |
500 | | |
501 | | static DecodeStatus DecodeParallel(MCInst *Inst, unsigned Val, uint64_t Address, |
502 | | void *Decoder) |
503 | 68.3k | { |
504 | 68.3k | DecodeStatus ret = MCDisassembler_Success; |
505 | | |
506 | 68.3k | if (!Inst->flat_insn->detail) |
507 | 0 | return MCDisassembler_Success; |
508 | | |
509 | 68.3k | switch (Val) { |
510 | 36.5k | case 0: |
511 | 36.5k | Inst->flat_insn->detail->tms320c64x.parallel = 0; |
512 | 36.5k | break; |
513 | 31.8k | case 1: |
514 | 31.8k | Inst->flat_insn->detail->tms320c64x.parallel = 1; |
515 | 31.8k | break; |
516 | 0 | default: |
517 | 0 | Inst->flat_insn->detail->tms320c64x.parallel = -1; |
518 | 0 | ret = MCDisassembler_Fail; |
519 | 0 | break; |
520 | 68.3k | } |
521 | | |
522 | 68.3k | return ret; |
523 | 68.3k | } |
524 | | |
525 | | static DecodeStatus DecodeCrosspathX1(MCInst *Inst, unsigned Val, |
526 | | uint64_t Address, void *Decoder) |
527 | 940 | { |
528 | 940 | DecodeStatus ret = MCDisassembler_Success; |
529 | 940 | MCOperand *op; |
530 | | |
531 | 940 | if (!Inst->flat_insn->detail) |
532 | 0 | return MCDisassembler_Success; |
533 | | |
534 | 940 | switch (Val) { |
535 | 498 | case 0: |
536 | 498 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
537 | 498 | break; |
538 | 442 | case 1: |
539 | 442 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 1; |
540 | 442 | op = &Inst->Operands[0]; |
541 | 442 | if (op->Kind == kRegister) { |
542 | 442 | if ((op->RegVal >= TMS320C64X_REG_A0) && |
543 | 442 | (op->RegVal <= TMS320C64X_REG_A31)) |
544 | 442 | op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + |
545 | 442 | 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 | 442 | } |
551 | 442 | break; |
552 | 0 | default: |
553 | 0 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
554 | 0 | ret = MCDisassembler_Fail; |
555 | 0 | break; |
556 | 940 | } |
557 | | |
558 | 940 | return ret; |
559 | 940 | } |
560 | | |
561 | | static DecodeStatus DecodeCrosspathX2(MCInst *Inst, unsigned Val, |
562 | | uint64_t Address, void *Decoder) |
563 | 22.0k | { |
564 | 22.0k | DecodeStatus ret = MCDisassembler_Success; |
565 | 22.0k | MCOperand *op; |
566 | | |
567 | 22.0k | if (!Inst->flat_insn->detail) |
568 | 0 | return MCDisassembler_Success; |
569 | | |
570 | 22.0k | switch (Val) { |
571 | 12.1k | case 0: |
572 | 12.1k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
573 | 12.1k | break; |
574 | 9.90k | case 1: |
575 | 9.90k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 1; |
576 | 9.90k | op = &Inst->Operands[1]; |
577 | 9.90k | if (op->Kind == kRegister) { |
578 | 8.58k | if ((op->RegVal >= TMS320C64X_REG_A0) && |
579 | 8.58k | (op->RegVal <= TMS320C64X_REG_A31)) |
580 | 6.99k | op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + |
581 | 6.99k | TMS320C64X_REG_B0); |
582 | 1.59k | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
583 | 1.59k | (op->RegVal <= TMS320C64X_REG_B31)) |
584 | 0 | op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + |
585 | 0 | TMS320C64X_REG_A0); |
586 | 8.58k | } |
587 | 9.90k | break; |
588 | 0 | default: |
589 | 0 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
590 | 0 | ret = MCDisassembler_Fail; |
591 | 0 | break; |
592 | 22.0k | } |
593 | | |
594 | 22.0k | return ret; |
595 | 22.0k | } |
596 | | |
597 | | static DecodeStatus DecodeCrosspathX3(MCInst *Inst, unsigned Val, |
598 | | uint64_t Address, void *Decoder) |
599 | 11.3k | { |
600 | 11.3k | DecodeStatus ret = MCDisassembler_Success; |
601 | 11.3k | MCOperand *op; |
602 | | |
603 | 11.3k | if (!Inst->flat_insn->detail) |
604 | 0 | return MCDisassembler_Success; |
605 | | |
606 | 11.3k | switch (Val) { |
607 | 5.28k | case 0: |
608 | 5.28k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 0; |
609 | 5.28k | break; |
610 | 6.08k | case 1: |
611 | 6.08k | Inst->flat_insn->detail->tms320c64x.funit.crosspath = 2; |
612 | 6.08k | op = &Inst->Operands[2]; |
613 | 6.08k | if (op->Kind == kRegister) { |
614 | 2.41k | if ((op->RegVal >= TMS320C64X_REG_A0) && |
615 | 2.41k | (op->RegVal <= TMS320C64X_REG_A31)) |
616 | 2.01k | op->RegVal = (op->RegVal - TMS320C64X_REG_A0 + |
617 | 2.01k | TMS320C64X_REG_B0); |
618 | 400 | else if ((op->RegVal >= TMS320C64X_REG_B0) && |
619 | 400 | (op->RegVal <= TMS320C64X_REG_B31)) |
620 | 269 | op->RegVal = (op->RegVal - TMS320C64X_REG_B0 + |
621 | 269 | TMS320C64X_REG_A0); |
622 | 2.41k | } |
623 | 6.08k | break; |
624 | 0 | default: |
625 | 0 | Inst->flat_insn->detail->tms320c64x.funit.crosspath = -1; |
626 | 0 | ret = MCDisassembler_Fail; |
627 | 0 | break; |
628 | 11.3k | } |
629 | | |
630 | 11.3k | return ret; |
631 | 11.3k | } |
632 | | |
633 | | static DecodeStatus DecodeNop(MCInst *Inst, unsigned Val, uint64_t Address, |
634 | | void *Decoder) |
635 | 1.74k | { |
636 | 1.74k | MCOperand_CreateImm0(Inst, Val + 1); |
637 | | |
638 | 1.74k | return MCDisassembler_Success; |
639 | 1.74k | } |
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 | 69.7k | { |
648 | 69.7k | uint32_t insn; |
649 | 69.7k | DecodeStatus result; |
650 | | |
651 | 69.7k | if (code_len < 4) { |
652 | 998 | *size = 0; |
653 | 998 | return MCDisassembler_Fail; |
654 | 998 | } |
655 | | |
656 | 68.7k | if (MI->flat_insn->detail) |
657 | 68.7k | memset(MI->flat_insn->detail, 0, |
658 | 68.7k | offsetof(cs_detail, tms320c64x) + sizeof(cs_tms320c64x)); |
659 | | |
660 | 68.7k | insn = readBytes32(MI, code); |
661 | 68.7k | result = |
662 | 68.7k | decodeInstruction_4(DecoderTable32, MI, insn, address, info, 0); |
663 | | |
664 | 68.7k | if (result == MCDisassembler_Success) { |
665 | 68.3k | *size = 4; |
666 | 68.3k | return true; |
667 | 68.3k | } |
668 | | |
669 | 369 | MCInst_clear(MI); |
670 | 369 | *size = 0; |
671 | 369 | return false; |
672 | 68.7k | } |
673 | | |
674 | | void TMS320C64x_init(MCRegisterInfo *MRI) |
675 | 2.50k | { |
676 | 2.50k | MCRegisterInfo_InitMCRegisterInfo(MRI, TMS320C64xRegDesc, 90, 0, 0, |
677 | 2.50k | TMS320C64xMCRegisterClasses, 7, 0, 0, |
678 | 2.50k | TMS320C64xRegDiffLists, 0, |
679 | 2.50k | TMS320C64xSubRegIdxLists, 1, 0); |
680 | 2.50k | } |
681 | | |
682 | | #endif |