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