1 /// Types and constants of M68k architecture 2 module capstone.m68k; 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 M68kRegister : RegisterImpl!M68kRegisterId { 17 package this(in Capstone cs, in int id) { 18 super(cs, id); 19 } 20 } 21 22 /// Architecture-specific InstructionGroup variant 23 class M68kInstructionGroup : InstructionGroupImpl!M68kInstructionGroupId { 24 package this(in Capstone cs, in int id) { 25 super(cs, id); 26 } 27 } 28 29 /// Architecture-specific Detail variant 30 class M68kDetail : DetailImpl!(M68kRegister, M68kInstructionGroup, M68kInstructionDetail) { 31 package this(in Capstone cs, cs_detail* internal) { 32 super(cs, internal); 33 } 34 } 35 36 /// Architecture-specific instruction variant 37 class M68kInstruction : InstructionImpl!(M68kInstructionId, M68kRegister, M68kDetail) { 38 package this(in Capstone cs, cs_insn* internal) { 39 super(cs, internal); 40 } 41 } 42 43 /// Architecture-specific Capstone variant 44 class CapstoneM68k : CapstoneImpl!(M68kInstructionId, M68kInstruction) { 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.m68k, modeFlags); 52 } 53 } 54 55 /** Instruction's operand referring to memory 56 57 This is associated with the `M68kOpType.mem` operand type 58 */ 59 struct M68kOpMem { 60 M68kRegister baseReg; /// Base register (or M68K_REG_INVALID if irrelevant) 61 M68kRegister indexReg; /// Index register (or M68K_REG_INVALID if irrelevant) 62 M68kRegister inBaseReg; /// Indirect base register (or M68K_REG_INVALID if irrelevant) 63 uint inDisp; /// Indirect displacement 64 uint outDisp; /// Other displacement 65 short disp; /// Displacement value 66 ubyte scale; /// Scale for index register 67 ubyte bitfield; /// Set to true if the two values below should be used 68 ubyte width; /// Used for bf* instructions 69 ubyte offset; /// Used for bf* instructions 70 ubyte indexSize; /// 0 = w, 1 = l 71 72 package this(in Capstone cs, m68k_op_mem internal) { 73 baseReg = new M68kRegister(cs, internal.base_reg); 74 indexReg = new M68kRegister(cs, internal.index_reg); 75 inBaseReg = new M68kRegister(cs, internal.in_base_reg); 76 inDisp = internal.in_disp; 77 outDisp = internal.out_disp; 78 disp = internal.disp; 79 scale = internal.scale; 80 bitfield = internal.bitfield; 81 width = internal.width; 82 offset = internal.offset; 83 indexSize = internal.index_size; 84 } 85 } 86 87 /// Branch displacement operand data 88 struct M68kOpBrDisp { 89 int disp; /// Displacement value 90 ubyte dispSize; /// Size from m68k_op_br_disp_size type above 91 92 package this(m68k_op_br_disp internal) { 93 disp = internal.disp; 94 dispSize = internal.disp_size; 95 } 96 } 97 98 /// Union of possible operand types 99 union M68kOpValue{ 100 ulong imm; /// Immediate value for IMM operand 101 double dimm; /// Double imm 102 float simm; /// Float imm 103 M68kRegister reg; /// Register value for REG operand 104 M68kRegister[2] regPair; /// Register pair in one operand 105 M68kOpMem mem; /// Data when operand is targeting memory 106 M68kOpBrDisp brDisp; /// Data when operand is a branch displacement 107 uint registerBits; /// Register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order) 108 } 109 110 /// Instruction's operand 111 struct M68kOp { 112 M68kOpType type; /// Operand type 113 SafeUnion!M68kOpValue value; /// Operand value of type `type` 114 alias value this; /// Convenient access to value (as in original bindings) 115 116 M68kAddressMode addressMode; /// M68k addressing mode for this op 117 118 package this(in Capstone cs, cs_m68k_op internal) { 119 type = internal.type.to!M68kOpType; 120 final switch(type) { 121 case M68kOpType.invalid: 122 break; 123 case M68kOpType.reg: 124 value.reg = new M68kRegister(cs, internal.reg); 125 break; 126 case M68kOpType.imm: 127 value.imm = internal.imm; 128 break; 129 case M68kOpType.mem: 130 value.mem = M68kOpMem(cs, internal.mem); 131 break; 132 case M68kOpType.fpSingle: 133 value.simm = internal.simm; 134 break; 135 case M68kOpType.fpDouble: 136 value.dimm = internal.dimm; 137 break; 138 case M68kOpType.regBits: 139 value.registerBits = internal.register_bits; 140 break; 141 case M68kOpType.regPair: 142 value.regPair = [new M68kRegister(cs, internal.reg_pair.reg_0), new M68kRegister(cs, internal.reg_pair.reg_1)]; 143 break; 144 case M68kOpType.brDisp: 145 value.brDisp = M68kOpBrDisp(internal.br_disp); 146 break; 147 } 148 addressMode = internal.address_mode.to!M68kAddressMode; 149 } 150 } 151 152 /// Operation size of the current instruction (NOT the actual size of instruction) 153 struct M68kOpSize { 154 M68kSizeType type; /// Type of size 155 union { 156 M68kCpuSize cpuSize; /// Size of CPU instruction 157 M68kFpuSize fpuSize; /// Size of the FPU instruction 158 } 159 } 160 161 /// M68k-specific information about an instruction 162 struct M68kInstructionDetail { 163 M68kOp[] operands; /// Operands for this instruction. 164 M68kOpSize opSize; /// Size of data operand works on in bytes (.b, .w, .l, etc) 165 166 package this(in Capstone cs, cs_arch_detail arch_detail){ 167 auto internal = arch_detail.m68k; 168 foreach(op; internal.operands[0..internal.op_count]) 169 operands ~= M68kOp(cs, op); 170 } 171 } 172 173 //============================================================================= 174 // Constants 175 //============================================================================= 176 177 /// M68k Addressing Modes 178 enum M68kAddressMode { 179 none = 0, /// No address mode. 180 181 reg_direct_data, /// Register direct - data 182 reg_direct_addr, /// Register direct - address 183 184 regi_addr, /// Register indirect - address 185 regi_addr_post_inc, /// Register indirect - address with postincrement 186 regi_addr_pre_dec, /// Register indirect - address with predecrement 187 regi_addr_disp, /// Register indirect - address with displacement 188 189 aregi_index_8_bit_disp, /// Address register indirect with index- 8-bit displacement 190 aregi_index_base_disp, /// Address register indirect with index- base displacement 191 192 memi_post_index, /// Memory indirect - postindex 193 memi_pre_index, /// Memory indirect - preindex 194 195 pci_disp, /// Program counter indirect - with displacement 196 197 pci_index_8_bit_disp, /// Program counter indirect with index - with 8-bit displacement 198 pci_index_base_disp, /// Program counter indirect with index - with base displacement 199 200 pc_memi_post_index, /// Program counter memory indirect - postindexed 201 pc_memi_pre_index, /// Program counter memory indirect - preindexed 202 203 absolute_data_short, /// Absolute data addressing - short 204 absolute_data_long, /// Absolute data addressing - long 205 immediate, /// Immediate value 206 207 branch_displacement /// Address as displacement from (pc+2) used by branches 208 } 209 210 /// Operand type for instruction's operands 211 enum M68kOpType { 212 invalid = 0, /// Uninitialized 213 reg, /// Register operand 214 imm, /// Immediate operand 215 mem, /// Memory operand 216 fpSingle, /// Single precision Floating-Point operand 217 fpDouble, /// Double precision Floating-Point operand 218 regBits, /// Register bits move 219 regPair, /// Register pair in the same op (upper 4 bits for first reg, lower for second) 220 brDisp /// Branch displacement 221 } 222 223 /// Displacement size of branch displacement operand 224 enum M68kOpBrDispSize { 225 invalid = 0, /// Uninitialized 226 byte_ = 1, /// Signed 8-bit displacement 227 word = 2, /// Signed 16-bit displacement 228 long_ = 4, /// Signed 32-bit displacement 229 } 230 231 /// Operation size of the CPU instructions 232 enum M68kCpuSize { 233 none = 0, // unsized or unspecified 234 byte_ = 1, // 1 byte in size 235 word = 2, // 2 bytes in size 236 long_ = 4, // 4 bytes in size 237 } 238 239 /** Operation size of the FPU instructions 240 241 Notice that FPU instruction can also use CPU sizes if needed 242 */ 243 enum M68kFpuSize { 244 none = 0, /// Unsized like fsave/frestore 245 single = 4, /// 4 byte in size (single float) 246 double_ = 8, /// 8 byte in size (double) 247 extended = 12, /// 12 byte in size (extended real format) 248 } 249 250 /// Type of size that is being used for the current instruction 251 enum M68kSizeType { 252 invalid = 0, 253 254 cpu, 255 fpu, 256 } 257 258 /// M68k registers and special registers 259 enum M68kRegisterId { 260 invalid = 0, 261 262 d0, 263 d1, 264 d2, 265 d3, 266 d4, 267 d5, 268 d6, 269 d7, 270 271 a0, 272 a1, 273 a2, 274 a3, 275 a4, 276 a5, 277 a6, 278 a7, 279 280 fp0, 281 fp1, 282 fp2, 283 fp3, 284 fp4, 285 fp5, 286 fp6, 287 fp7, 288 289 pc, 290 291 sr, 292 ccr, 293 sfc, 294 dfc, 295 usp, 296 vbr, 297 cacr, 298 caar, 299 msp, 300 isp, 301 tc, 302 itt0, 303 itt1, 304 dtt0, 305 dtt1, 306 mmusr, 307 urp, 308 srp, 309 310 fpcr, 311 fpsr, 312 fpiar 313 } 314 315 /// M68k instruction 316 enum M68kInstructionId { 317 invalid = 0, 318 319 abcd, 320 add, 321 adda, 322 addi, 323 addq, 324 addx, 325 and, 326 andi, 327 asl, 328 asr, 329 bhs, 330 blo, 331 bhi, 332 bls, 333 bcc, 334 bcs, 335 bne, 336 beq, 337 bvc, 338 bvs, 339 bpl, 340 bmi, 341 bge, 342 blt, 343 bgt, 344 ble, 345 bra, 346 bsr, 347 bchg, 348 bclr, 349 bset, 350 btst, 351 bfchg, 352 bfclr, 353 bfexts, 354 bfextu, 355 bfffo, 356 bfins, 357 bfset, 358 bftst, 359 bkpt, 360 callm, 361 cas, 362 cas2, 363 chk, 364 chk2, 365 clr, 366 cmp, 367 cmpa, 368 cmpi, 369 cmpm, 370 cmp2, 371 cinvl, 372 cinvp, 373 cinva, 374 cpushl, 375 cpushp, 376 cpusha, 377 dbt, 378 dbf, 379 dbhi, 380 dbls, 381 dbcc, 382 dbcs, 383 dbne, 384 dbeq, 385 dbvc, 386 dbvs, 387 dbpl, 388 dbmi, 389 dbge, 390 dblt, 391 dbgt, 392 dble, 393 dbra, 394 divs, 395 divsl, 396 divu, 397 divul, 398 eor, 399 eori, 400 exg, 401 ext, 402 extb, 403 fabs, 404 fsabs, 405 fdabs, 406 facos, 407 fadd, 408 fsadd, 409 fdadd, 410 fasin, 411 fatan, 412 fatanh, 413 fbf, 414 fbeq, 415 fbogt, 416 fboge, 417 fbolt, 418 fbole, 419 fbogl, 420 fbor, 421 fbun, 422 fbueq, 423 fbugt, 424 fbuge, 425 fbult, 426 fbule, 427 fbne, 428 fbt, 429 fbsf, 430 fbseq, 431 fbgt, 432 fbge, 433 fblt, 434 fble, 435 fbgl, 436 fbgle, 437 fbngle, 438 fbngl, 439 fbnle, 440 fbnlt, 441 fbnge, 442 fbngt, 443 fbsne, 444 fbst, 445 fcmp, 446 fcos, 447 fcosh, 448 fdbf, 449 fdbeq, 450 fdbogt, 451 fdboge, 452 fdbolt, 453 fdbole, 454 fdbogl, 455 fdbor, 456 fdbun, 457 fdbueq, 458 fdbugt, 459 fdbuge, 460 fdbult, 461 fdbule, 462 fdbne, 463 fdbt, 464 fdbsf, 465 fdbseq, 466 fdbgt, 467 fdbge, 468 fdblt, 469 fdble, 470 fdbgl, 471 fdbgle, 472 fdbngle, 473 fdbngl, 474 fdbnle, 475 fdbnlt, 476 fdbnge, 477 fdbngt, 478 fdbsne, 479 fdbst, 480 fdiv, 481 fsdiv, 482 fddiv, 483 fetox, 484 fetoxm1, 485 fgetexp, 486 fgetman, 487 fint, 488 fintrz, 489 flog10, 490 flog2, 491 flogn, 492 flognp1, 493 fmod, 494 fmove, 495 fsmove, 496 fdmove, 497 fmovecr, 498 fmovem, 499 fmul, 500 fsmul, 501 fdmul, 502 fneg, 503 fsneg, 504 fdneg, 505 fnop, 506 frem, 507 frestore, 508 fsave, 509 fscale, 510 fsgldiv, 511 fsglmul, 512 fsin, 513 fsincos, 514 fsinh, 515 fsqrt, 516 fssqrt, 517 fdsqrt, 518 fsf, 519 fsbeq, 520 fsogt, 521 fsoge, 522 fsolt, 523 fsole, 524 fsogl, 525 fsor, 526 fsun, 527 fsueq, 528 fsugt, 529 fsuge, 530 fsult, 531 fsule, 532 fsne, 533 fst, 534 fssf, 535 fsseq, 536 fsgt, 537 fsge, 538 fslt, 539 fsle, 540 fsgl, 541 fsgle, 542 fsngle, 543 fsngl, 544 fsnle, 545 fsnlt, 546 fsnge, 547 fsngt, 548 fssne, 549 fsst, 550 fsub, 551 fssub, 552 fdsub, 553 ftan, 554 ftanh, 555 ftentox, 556 ftrapf, 557 ftrapeq, 558 ftrapogt, 559 ftrapoge, 560 ftrapolt, 561 ftrapole, 562 ftrapogl, 563 ftrapor, 564 ftrapun, 565 ftrapueq, 566 ftrapugt, 567 ftrapuge, 568 ftrapult, 569 ftrapule, 570 ftrapne, 571 ftrapt, 572 ftrapsf, 573 ftrapseq, 574 ftrapgt, 575 ftrapge, 576 ftraplt, 577 ftraple, 578 ftrapgl, 579 ftrapgle, 580 ftrapngle, 581 ftrapngl, 582 ftrapnle, 583 ftrapnlt, 584 ftrapnge, 585 ftrapngt, 586 ftrapsne, 587 ftrapst, 588 ftst, 589 ftwotox, 590 halt, 591 illegal, 592 jmp, 593 jsr, 594 lea, 595 link, 596 lpstop, 597 lsl, 598 lsr, 599 move, 600 movea, 601 movec, 602 movem, 603 movep, 604 moveq, 605 moves, 606 move16, 607 muls, 608 mulu, 609 nbcd, 610 neg, 611 negx, 612 nop, 613 not, 614 or, 615 ori, 616 pack, 617 pea, 618 pflush, 619 pflusha, 620 pflushan, 621 pflushn, 622 ploadr, 623 ploadw, 624 plpar, 625 plpaw, 626 pmove, 627 pmovefd, 628 ptestr, 629 ptestw, 630 pulse, 631 rems, 632 remu, 633 reset, 634 rol, 635 ror, 636 roxl, 637 roxr, 638 rtd, 639 rte, 640 rtm, 641 rtr, 642 rts, 643 sbcd, 644 st, 645 sf, 646 shi, 647 sls, 648 scc, 649 shs, 650 scs, 651 slo, 652 sne, 653 seq, 654 svc, 655 svs, 656 spl, 657 smi, 658 sge, 659 slt, 660 sgt, 661 sle, 662 stop, 663 sub, 664 suba, 665 subi, 666 subq, 667 subx, 668 swap, 669 tas, 670 trap, 671 trapv, 672 trapt, 673 trapf, 674 traphi, 675 trapls, 676 trapcc, 677 traphs, 678 trapcs, 679 traplo, 680 trapne, 681 trapeq, 682 trapvc, 683 trapvs, 684 trappl, 685 trapmi, 686 trapge, 687 traplt, 688 trapgt, 689 traple, 690 tst, 691 unlk, 692 unpk, 693 } 694 695 /// Group of M68k instructions 696 enum M68kInstructionGroupId { 697 invalid = 0, 698 jump, 699 ret = 3, 700 iret = 5, 701 branch_relative = 7 702 }