1 /// Types and constants of TMS320C64x architecture 2 module capstone.tms320c64x; 3 4 import std.conv: to; 5 6 import capstone.api; 7 import capstone.capstone; 8 import capstone.detail; 9 import capstone.instruction; 10 import capstone.instructiongroup; 11 import capstone.internal; 12 import capstone.register; 13 import capstone.utils; 14 15 /// Architecture-specific Register variant 16 class Tms320c64xRegister : RegisterImpl!Tms320c64xRegisterId { 17 package this(in Capstone cs, in int id) { 18 super(cs, id); 19 } 20 } 21 22 /// Architecture-specific InstructionGroup variant 23 class Tms320c64xInstructionGroup : InstructionGroupImpl!Tms320c64xInstructionGroupId { 24 package this(in Capstone cs, in int id) { 25 super(cs, id); 26 } 27 } 28 29 /// Architecture-specific Detail variant 30 class Tms320c64xDetail : DetailImpl!(Tms320c64xRegister, Tms320c64xInstructionGroup, Tms320c64xInstructionDetail) { 31 package this(in Capstone cs, cs_detail* internal) { 32 super(cs, internal); 33 } 34 } 35 36 /// Architecture-specific instruction variant 37 class Tms320c64xInstruction : InstructionImpl!(Tms320c64xInstructionId, Tms320c64xRegister, Tms320c64xDetail) { 38 package this(in Capstone cs, cs_insn* internal) { 39 super(cs, internal); 40 } 41 } 42 43 /// Architecture-specific Capstone variant 44 class CapstoneTms320c64x : CapstoneImpl!(Tms320c64xInstructionId, Tms320c64xInstruction) { 45 /** Creates an architecture-specific instance with a given mode of interpretation 46 47 Params: 48 modeFlags = The (initial) mode of interpretation, which can still be changed later on 49 */ 50 this(in ModeFlags modeFlags){ 51 super(Arch.tms320c64x, modeFlags); 52 } 53 } 54 55 /// Union of possible displacement values 56 union Tms320c64xDispValue { 57 uint constant; /// Constant displacement/offset 58 Tms320c64xRegister register; /// Register stating displacement/offset 59 } 60 61 /** Instruction's operand referring to memory 62 63 This is associated with the `Tms320c64xOpType.mem` operand type 64 */ 65 struct Tms320c64xOpMem { 66 Tms320c64xRegister base; /// Base register 67 SafeUnion!Tms320c64xDispValue disp; /// Displacement/offset value 68 uint unit; /// Unit of base and offset register 69 uint scaled; /// Offset scaled 70 Tms320c64xMemDisp disptype; /// Displacement type 71 Tms320c64xMemDir direction; /// Direction 72 Tms320c64xMemMod modify; /// Modification 73 74 package this(in Capstone cs, tms320c64x_op_mem internal) { 75 base = new Tms320c64xRegister(cs, internal.base); 76 unit = internal.unit; 77 scaled = internal.scaled; 78 disptype = internal.disptype.to!Tms320c64xMemDisp; 79 if(disptype == Tms320c64xMemDisp.register) 80 disp.register = new Tms320c64xRegister(cs, internal.disp); 81 else 82 disp.constant = internal.disp; 83 direction = internal.direction.to!Tms320c64xMemDir; 84 modify = internal.modify.to!Tms320c64xMemMod; 85 } 86 } 87 88 /// Union of possible operand types 89 union Tms320c64xOpValue{ 90 Tms320c64xRegister reg; /// Register 91 int imm; /// Immediate 92 Tms320c64xOpMem mem; /// Memory 93 Tms320c64xRegister[2] regpair; /// Register pair 94 } 95 96 /// Instruction's operand 97 struct Tms320c64xOp { 98 Tms320c64xOpType type; /// Operand type 99 SafeUnion!Tms320c64xOpValue value; /// Operand value of type `type` 100 alias value this; /// Convenient access to value (as in original bindings) 101 102 package this(in Capstone cs, cs_tms320c64x_op internal){ 103 type = internal.type.to!Tms320c64xOpType; 104 final switch(internal.type) { 105 case Tms320c64xOpType.invalid: 106 break; 107 case Tms320c64xOpType.reg: 108 value.reg = new Tms320c64xRegister(cs, internal.reg); 109 break; 110 case Tms320c64xOpType.imm: 111 value.imm = internal.imm; 112 break; 113 case Tms320c64xOpType.mem: 114 value.mem = Tms320c64xOpMem(cs, internal.mem); 115 break; 116 case Tms320c64xOpType.regpair: 117 value.regpair = [new Tms320c64xRegister(cs, internal.reg), new Tms320c64xRegister(cs, internal.reg+1)]; 118 break; 119 } 120 } 121 } 122 123 /// Condition of instruction 124 struct Tms320c64xCondition { 125 Tms320c64xRegister reg; /// Condition register tested 126 bool zero; /// True iff testing for zero 127 128 package this(in Capstone cs, cs_tms320c64x_condition internal) { 129 reg = new Tms320c64xRegister(cs, internal.reg); 130 zero = internal.zero == 1; 131 } 132 } 133 134 /// Funcional unit associated with an instruction 135 struct Tms320c64xFunit { 136 Tms320c64xFunitType unit; /// Functional unit identifier 137 uint side; /// The side/data path the unit is on 138 bool crosspath; /// True iff using crosspath 139 140 package this(cs_tms320c64x_funit internal) { 141 unit = internal.unit.to!Tms320c64xFunitType; 142 side = internal.side; 143 crosspath = internal.crosspath==1; 144 } 145 } 146 147 /// TMS320C64x-specific information about an instruction 148 struct Tms320c64xInstructionDetail { 149 Tms320c64xOp[] operands; /// Operands for this instruction. 150 Tms320c64xCondition condition; /// Condition of instruction (irrelevant if invalid conditional register) 151 Tms320c64xFunit funit; /// Associated functional unit 152 bool parallel; /// True iff executed in parallel with previous instruction 153 154 package this(in Capstone cs, cs_arch_detail arch_detail){ 155 auto internal = arch_detail.tms320c64x; 156 foreach(op; internal.operands[0..internal.op_count]) 157 operands ~= Tms320c64xOp(cs, op); 158 condition = Tms320c64xCondition(cs, internal.condition); 159 funit = Tms320c64xFunit(internal.funit); 160 parallel = internal.parallel.to!bool; 161 } 162 } 163 164 //============================================================================= 165 // Constants 166 //============================================================================= 167 168 /// Operand type for instruction's operands 169 enum Tms320c64xOpType { 170 invalid = 0, /// Uninitialized 171 reg, /// Register operand 172 imm, /// Immediate operand 173 mem, /// Memory operand 174 regpair = 64, /// Register pair for double word ops 175 } 176 177 /// Memory operand displacement kind 178 enum Tms320c64xMemDisp { 179 invalid = 0, 180 constant, 181 register, 182 } 183 184 /// Memory operand direction 185 enum Tms320c64xMemDir { 186 invalid = 0, 187 fw, 188 bw, 189 } 190 191 /// Memory operand modification type 192 enum Tms320c64xMemMod { 193 invalid = 0, 194 no, 195 pre, 196 post, 197 } 198 199 /// Functional unit type 200 enum Tms320c64xFunitType { 201 invalid = 0, 202 d, /// Adder/Subtractor (used for address generation) 203 l, /// ALU 204 m, /// Multiplier 205 s, /// Shifter 206 no 207 } 208 209 /// TMS320C64x registers 210 enum Tms320c64xRegisterId { 211 invalid = 0, 212 213 amr, 214 csr, 215 dier, 216 dnum, 217 ecr, 218 gfpgfr, 219 gplya, 220 gplyb, 221 icr, 222 ier, 223 ierr, 224 ilc, 225 irp, 226 isr, 227 istp, 228 itsr, 229 nrp, 230 ntsr, 231 rep, 232 rilc, 233 ssr, 234 tsch, 235 tscl, 236 tsr, 237 a0, 238 a1, 239 a2, 240 a3, 241 a4, 242 a5, 243 a6, 244 a7, 245 a8, 246 a9, 247 a10, 248 a11, 249 a12, 250 a13, 251 a14, 252 a15, 253 a16, 254 a17, 255 a18, 256 a19, 257 a20, 258 a21, 259 a22, 260 a23, 261 a24, 262 a25, 263 a26, 264 a27, 265 a28, 266 a29, 267 a30, 268 a31, 269 b0, 270 b1, 271 b2, 272 b3, 273 b4, 274 b5, 275 b6, 276 b7, 277 b8, 278 b9, 279 b10, 280 b11, 281 b12, 282 b13, 283 b14, 284 b15, 285 b16, 286 b17, 287 b18, 288 b19, 289 b20, 290 b21, 291 b22, 292 b23, 293 b24, 294 b25, 295 b26, 296 b27, 297 b28, 298 b29, 299 b30, 300 b31, 301 pce1, 302 303 // Alias registers 304 efr = ecr, 305 ifr = isr, 306 } 307 308 /// TMS320C64x instructions 309 enum Tms320c64xInstructionId { 310 invalid = 0, 311 312 abs, 313 abs2, 314 add, 315 add2, 316 add4, 317 addab, 318 addad, 319 addah, 320 addaw, 321 addk, 322 addkpc, 323 addu, 324 and, 325 andn, 326 avg2, 327 avgu4, 328 b, 329 bdec, 330 bitc4, 331 bnop, 332 bpos, 333 clr, 334 cmpeq, 335 cmpeq2, 336 cmpeq4, 337 cmpgt, 338 cmpgt2, 339 cmpgtu4, 340 cmplt, 341 cmpltu, 342 deal, 343 dotp2, 344 dotpn2, 345 dotpnrsu2, 346 dotprsu2, 347 dotpsu4, 348 dotpu4, 349 ext, 350 extu, 351 gmpgtu, 352 gmpy4, 353 ldb, 354 ldbu, 355 lddw, 356 ldh, 357 ldhu, 358 ldndw, 359 ldnw, 360 ldw, 361 lmbd, 362 max2, 363 maxu4, 364 min2, 365 minu4, 366 mpy, 367 mpy2, 368 mpyh, 369 mpyhi, 370 mpyhir, 371 mpyhl, 372 mpyhlu, 373 mpyhslu, 374 mpyhsu, 375 mpyhu, 376 mpyhuls, 377 mpyhus, 378 mpylh, 379 mpylhu, 380 mpyli, 381 mpylir, 382 mpylshu, 383 mpyluhs, 384 mpysu, 385 mpysu4, 386 mpyu, 387 mpyu4, 388 mpyus, 389 mvc, 390 mvd, 391 mvk, 392 mvkl, 393 mvklh, 394 nop, 395 norm, 396 or, 397 pack2, 398 packh2, 399 packh4, 400 packhl2, 401 packl4, 402 packlh2, 403 rotl, 404 sadd, 405 sadd2, 406 saddu4, 407 saddus2, 408 sat, 409 set, 410 shfl, 411 shl, 412 shlmb, 413 shr, 414 shr2, 415 shrmb, 416 shru, 417 shru2, 418 smpy, 419 smpy2, 420 smpyh, 421 smpyhl, 422 smpylh, 423 spack2, 424 spacku4, 425 sshl, 426 sshvl, 427 sshvr, 428 ssub, 429 stb, 430 stdw, 431 sth, 432 stndw, 433 stnw, 434 stw, 435 sub, 436 sub2, 437 sub4, 438 subab, 439 subabs4, 440 subah, 441 subaw, 442 subc, 443 subu, 444 swap4, 445 unpkhu4, 446 unpklu4, 447 xor, 448 xpnd2, 449 xpnd4, 450 // Aliases 451 idle, 452 mv, 453 neg, 454 not, 455 swap2, 456 zero, 457 } 458 459 /// Group of TMS320C64x instructions 460 enum Tms320c64xInstructionGroupId { 461 invalid = 0, 462 463 jump, 464 465 funit_d = 128, 466 funit_l, 467 funit_m, 468 funit_s, 469 funit_no, 470 }