1 /// Types and constants of M680x architecture 2 module capstone.m680x; 3 4 import std.conv: to; 5 import std.typecons: BitFlags; 6 7 import capstone.api; 8 import capstone.capstone; 9 import capstone.detail; 10 import capstone.instruction; 11 import capstone.instructiongroup; 12 import capstone.internal; 13 import capstone.register; 14 import capstone.utils; 15 16 /// Architecture-specific Register variant 17 class M680xRegister : RegisterImpl!M680xRegisterId { 18 package this(in Capstone cs, in int id) { 19 super(cs, id); 20 } 21 } 22 23 /// Architecture-specific InstructionGroup variant 24 class M680xInstructionGroup : InstructionGroupImpl!M680xInstructionGroupId { 25 package this(in Capstone cs, in int id) { 26 super(cs, id); 27 } 28 } 29 30 /// Architecture-specific Detail variant 31 class M680xDetail : DetailImpl!(M680xRegister, M680xInstructionGroup, M680xInstructionDetail) { 32 package this(in Capstone cs, cs_detail* internal) { 33 super(cs, internal); 34 } 35 } 36 37 /// Architecture-specific instruction variant 38 class M680xInstruction : InstructionImpl!(M680xInstructionId, M680xRegister, M680xDetail) { 39 package this(in Capstone cs, cs_insn* internal) { 40 super(cs, internal); 41 } 42 } 43 44 /// Architecture-specific Capstone variant 45 class CapstoneM680x : CapstoneImpl!(M680xInstructionId, M680xInstruction) { 46 /** Creates an architecture-specific instance with a given mode of interpretation 47 48 Params: 49 modeFlags = The (initial) mode of interpretation, which can still be changed later on 50 */ 51 this(in ModeFlags modeFlags){ 52 super(Arch.m680x, modeFlags); 53 } 54 } 55 56 /// Instruction's operand referring to indexed addressing 57 struct M680xOpIdx { 58 M680xRegister baseReg; /// Base register (or `M680xRegisterId.invalid` if irrelevant) 59 M680xRegister offsetReg; /// Offset register (or `M680xRegisterId.invalid` if irrelevant) 60 short offset; /// 5-,8- or 16-bit offset 61 ushort offsetAddr; /// = offset addr. if baseReg.id == M680xRegisterId.pc. Calculated as offset + PC 62 M680xOffsetBits offsetBits; /// Offset width in bits for indexed addressing 63 byte incDec; /// Inc. or dec. value: 0: no inc-/decrement, 1 .. 8: increment by 1 .. 8, -1 .. -8: decrement by 1 .. 8. 64 /// If flag M680xFlag.postIncDec set it is post inc-/decrement otherwise pre inc-/decrement 65 BitFlags!M680xFlag flags; /// 8-bit flags (see above) 66 67 package this(in Capstone cs, m680x_op_idx internal) { 68 baseReg = new M680xRegister(cs, internal.base_reg); 69 offsetReg = new M680xRegister(cs, internal.offset_reg); 70 offset = internal.offset; 71 offsetAddr = internal.offset_addr; 72 offsetBits = internal.offset_bits.to!M680xOffsetBits; 73 incDec = internal.inc_dec; 74 flags = cast(M680xFlag)internal.flags; 75 } 76 } 77 78 /// Instruction's memory operand referring to relative addressing (Bcc/LBcc) 79 struct M680xOpRel { 80 ushort address; /// The absolute address. Calculated as PC + offset. PC is the first address after the instruction. 81 short offset; /// The offset/displacement value 82 83 package this(m680x_op_rel internal) { 84 address = internal.address; 85 offset = internal.offset; 86 } 87 } 88 89 /// Instruction's operand referring to extended addressing 90 struct M680xOpExt { 91 ushort address; /// The absolute address 92 bool indirect; /// true if extended indirect addressing 93 94 package this(m680x_op_ext internal) { 95 address = internal.address; 96 indirect = internal.indirect; 97 } 98 } 99 100 /// Union of possible operand types 101 union M680xOpValue{ 102 int imm; /// Immediate value for IMM operand 103 M680xRegister reg; /// Register value for REG operand 104 M680xOpIdx idx; /// Indexed addressing operand 105 M680xOpRel rel; /// Relative address. operand (Bcc/LBcc) 106 M680xOpExt ext; /// Extended address 107 ubyte directAddr; /// Direct address (lower 8-bit) 108 ubyte constVal; /// Constant value (bit index, page nr.) 109 } 110 111 /// Instruction's operand 112 struct M680xOp { 113 M680xOpType type; /// Operand type 114 SafeUnion!M680xOpValue value; /// Operand value of type `type` 115 alias value this; /// Convenient access to value (as in original bindings) 116 117 ubyte size; /// Size of this operand (in bytes) 118 119 /** How is this operand accessed? (READ, WRITE or READ|WRITE) 120 121 NOTE: This field is irrelevant, i.e. equals 0, if engine is compiled in DIET mode. 122 */ 123 AccessFlags access; 124 125 package this(in Capstone cs, cs_m680x_op internal) { 126 type = internal.type.to!M680xOpType; 127 final switch(type) { 128 case M680xOpType.invalid: 129 break; 130 case M680xOpType.register: 131 value.reg = new M680xRegister(cs, internal.reg); 132 break; 133 case M680xOpType.immediate: 134 value.imm = internal.imm; 135 break; 136 case M680xOpType.indexed: 137 value.idx = M680xOpIdx(cs, internal.idx); 138 break; 139 case M680xOpType.extended: 140 value.ext = M680xOpExt(internal.ext); 141 break; 142 case M680xOpType.direct: 143 value.directAddr = internal.direct_addr; 144 break; 145 case M680xOpType.relative: 146 value.rel = M680xOpRel(internal.rel); 147 break; 148 case M680xOpType.constant: 149 value.constVal = internal.const_val; 150 break; 151 } 152 size = internal.size; 153 access = cast(AccessType)internal.access; 154 } 155 } 156 157 /// M680x-specific information about an instruction 158 struct M680xInstructionDetail { 159 M680xOp[] operands; /// Operands for this instruction 160 BitFlags!M680xInstructionFlag flags; /// See `M680xInstructionFlag` 161 162 package this(in Capstone cs, cs_arch_detail arch_detail){ 163 auto internal = arch_detail.m680x; 164 foreach(op; internal.operands[0..internal.op_count]) 165 operands ~= M680xOp(cs, op); 166 flags = cast(M680xInstructionFlag)internal.flags; 167 } 168 } 169 170 //============================================================================= 171 // Constants 172 //============================================================================= 173 174 /// Operand type for instruction's operands 175 enum M680xOpType { 176 invalid = 0, /// Uninitialized 177 register, /// Register operand 178 immediate, /// Immediate operand 179 indexed, /// Indexed addressing operand 180 extended, /// Extended addressing operand 181 direct, /// Direct addressing operand 182 relative, /// Relative addressing operand 183 constant, /// Constant operand (Displayed as number only). Used e.g. for a bit index or page number. 184 } 185 186 /// Supported bit values for `M680xOpIdx.offsetBits` 187 enum M680xOffsetBits { 188 none = 0, 189 _5 = 5, 190 _8 = 8, 191 _9 = 9, 192 _16 = 16 193 } 194 195 /// Supported bit flags for `M680xOpIdx.flags` 196 enum M680xFlag { 197 indirect = 1, 198 noComma = 2, 199 postIncDec = 4 200 } 201 202 /// M680X instruction flags: 203 enum M680xInstructionFlag { 204 firstOpInMnem = 1, /// The first (register) operand is part of the instruction mnemonic 205 secondOpInMnem = 2 /// The second (register) operand is part of the instruction mnemonic 206 } 207 208 /// M680X registers and special registers 209 enum M680xRegisterId { 210 invalid = 0, 211 212 a, /// M6800/1/2/3/9, HD6301/9 213 b, /// M6800/1/2/3/9, HD6301/9 214 e, /// HD6309 215 f, /// HD6309 216 _0, /// HD6309 217 218 d, /// M6801/3/9, HD6301/9 219 w, /// HD6309 220 221 cc, /// M6800/1/2/3/9, M6301/9 222 dp, /// M6809/M6309 223 md, /// M6309 224 225 hx, /// M6808 226 h, /// M6808 227 x, /// M6800/1/2/3/9, M6301/9 228 y, /// M6809/M6309 229 s, /// M6809/M6309 230 u, /// M6809/M6309 231 v, /// M6309 232 233 q, /// M6309 234 235 pc, /// M6800/1/2/3/9, M6301/9 236 237 tmp2, /// CPU12 238 tmp3, /// CPU12 239 } 240 241 /// M680X instruction IDs 242 enum M680xInstructionId { 243 invld = 0, 244 aba, /// M6800/1/2/3 245 abx, 246 aby, 247 adc, 248 adca, 249 adcb, 250 adcd, 251 adcr, 252 add, 253 adda, 254 addb, 255 addd, 256 adde, 257 addf, 258 addr, 259 addw, 260 aim, 261 ais, 262 aix, 263 and, 264 anda, 265 andb, 266 andcc, 267 andd, 268 andr, 269 asl, 270 asla, 271 aslb, 272 asld, /// or LSLD 273 asr, 274 asra, 275 asrb, 276 asrd, 277 asrx, 278 band, 279 bcc, /// or BHS 280 bclr, 281 bcs, /// or BLO 282 beor, 283 beq, 284 bge, 285 bgnd, 286 bgt, 287 bhcc, 288 bhcs, 289 bhi, 290 biand, 291 bieor, 292 bih, 293 bil, 294 bior, 295 bit, 296 bita, 297 bitb, 298 bitd, 299 bitmd, 300 ble, 301 bls, 302 blt, 303 bmc, 304 bmi, 305 bms, 306 bne, 307 bor, 308 bpl, 309 brclr, 310 brset, 311 bra, 312 brn, 313 bset, 314 bsr, 315 bvc, 316 bvs, 317 call, 318 cba, /// M6800/1/2/3 319 cbeq, 320 cbeqa, 321 cbeqx, 322 clc, /// M6800/1/2/3 323 cli, /// M6800/1/2/3 324 clr, 325 clra, 326 clrb, 327 clrd, 328 clre, 329 clrf, 330 clrh, 331 clrw, 332 clrx, 333 clv, /// M6800/1/2/3 334 cmp, 335 cmpa, 336 cmpb, 337 cmpd, 338 cmpe, 339 cmpf, 340 cmpr, 341 cmps, 342 cmpu, 343 cmpw, 344 cmpx, 345 cmpy, 346 com, 347 coma, 348 comb, 349 comd, 350 come, 351 comf, 352 comw, 353 comx, 354 cpd, 355 cphx, 356 cps, 357 cpx, /// M6800/1/2/3 358 cpy, 359 cwai, 360 daa, 361 dbeq, 362 dbne, 363 dbnz, 364 dbnza, 365 dbnzx, 366 dec, 367 deca, 368 decb, 369 decd, 370 dece, 371 decf, 372 decw, 373 decx, 374 des, /// M6800/1/2/3 375 dex, /// M6800/1/2/3 376 dey, 377 div, 378 divd, 379 divq, 380 ediv, 381 edivs, 382 eim, 383 emacs, 384 emaxd, 385 emaxm, 386 emind, 387 eminm, 388 emul, 389 emuls, 390 eor, 391 eora, 392 eorb, 393 eord, 394 eorr, 395 etbl, 396 exg, 397 fdiv, 398 ibeq, 399 ibne, 400 idiv, 401 idivs, 402 illgl, 403 inc, 404 inca, 405 incb, 406 incd, 407 ince, 408 incf, 409 incw, 410 incx, 411 ins, /// M6800/1/2/3 412 inx, /// M6800/1/2/3 413 iny, 414 jmp, 415 jsr, 416 lbcc, /// or LBHS 417 lbcs, /// or LBLO 418 lbeq, 419 lbge, 420 lbgt, 421 lbhi, 422 lble, 423 lbls, 424 lblt, 425 lbmi, 426 lbne, 427 lbpl, 428 lbra, 429 lbrn, 430 lbsr, 431 lbvc, 432 lbvs, 433 lda, 434 ldaa, /// M6800/1/2/3 435 ldab, /// M6800/1/2/3 436 ldb, 437 ldbt, 438 ldd, 439 lde, 440 ldf, 441 ldhx, 442 ldmd, 443 ldq, 444 lds, 445 ldu, 446 ldw, 447 ldx, 448 ldy, 449 leas, 450 leau, 451 leax, 452 leay, 453 lsl, 454 lsla, 455 lslb, 456 lsld, 457 lslx, 458 lsr, 459 lsra, 460 lsrb, 461 lsrd, /// or ASRD 462 lsrw, 463 lsrx, 464 maxa, 465 maxm, 466 mem, 467 mina, 468 minm, 469 mov, 470 movb, 471 movw, 472 mul, 473 muld, 474 neg, 475 nega, 476 negb, 477 negd, 478 negx, 479 nop, 480 nsa, 481 oim, 482 ora, 483 oraa, /// M6800/1/2/3 484 orab, /// M6800/1/2/3 485 orb, 486 orcc, 487 ord, 488 orr, 489 psha, /// M6800/1/2/3 490 pshb, /// M6800/1/2/3 491 pshc, 492 pshd, 493 pshh, 494 pshs, 495 pshsw, 496 pshu, 497 pshuw, 498 pshx, /// M6800/1/2/3 499 pshy, 500 pula, /// M6800/1/2/3 501 pulb, /// M6800/1/2/3 502 pulc, 503 puld, 504 pulh, 505 puls, 506 pulsw, 507 pulu, 508 puluw, 509 pulx, /// M6800/1/2/3 510 puly, 511 rev, 512 revw, 513 rol, 514 rola, 515 rolb, 516 rold, 517 rolw, 518 rolx, 519 ror, 520 rora, 521 rorb, 522 rord, 523 rorw, 524 rorx, 525 rsp, 526 rtc, 527 rti, 528 rts, 529 sba, /// M6800/1/2/3 530 sbc, 531 sbca, 532 sbcb, 533 sbcd, 534 sbcr, 535 sec, 536 sei, 537 sev, 538 sex, 539 sexw, 540 slp, 541 sta, 542 staa, /// M6800/1/2/3 543 stab, /// M6800/1/2/3 544 stb, 545 stbt, 546 std, 547 ste, 548 stf, 549 stop, 550 sthx, 551 stq, 552 sts, 553 stu, 554 stw, 555 stx, 556 sty, 557 sub, 558 suba, 559 subb, 560 subd, 561 sube, 562 subf, 563 subr, 564 subw, 565 swi, 566 swi2, 567 swi3, 568 sync, 569 tab, /// M6800/1/2/3 570 tap, /// M6800/1/2/3 571 tax, 572 tba, /// M6800/1/2/3 573 tbeq, 574 tbl, 575 tbne, 576 test, 577 tfm, 578 tfr, 579 tim, 580 tpa, /// M6800/1/2/3 581 tst, 582 tsta, 583 tstb, 584 tstd, 585 tste, 586 tstf, 587 tstw, 588 tstx, 589 tsx, /// M6800/1/2/3 590 tsy, 591 txa, 592 txs, /// M6800/1/2/3 593 tys, 594 wai, /// M6800/1/2/3 595 wait, 596 wav, 597 wavr, 598 xgdx, /// HD6301 599 xgdy, 600 } 601 602 /// Group of M680X instructions 603 enum M680xInstructionGroupId { 604 invalid = 0, 605 // Generic groups 606 // all jump instructions (conditional+direct+indirect jumps) 607 jump, 608 // all call instructions 609 call, 610 // all return instructions 611 ret, 612 // all interrupt instructions (int+syscall) 613 int_, 614 // all interrupt return instructions 615 iret, 616 // all privileged instructions 617 priv, 618 // all relative branching instructions 619 brarel, 620 }