1 /// Types and constants of ARM architecture 2 module capstone.arm; 3 4 import std.variant; 5 import std.exception: enforce; 6 7 import capstone.internal; 8 import capstone.utils; 9 10 /** Instruction's operand referring to memory 11 12 This is associated with the `ArmOpType.mem` operand type 13 */ 14 struct ArmOpMem { 15 ArmRegister base; /// Base register 16 ArmRegister index; /// Index register 17 int scale; /// Scale for index register (can be 1, or -1) 18 int disp; /// Displacement value 19 } 20 21 /// Optional shift 22 struct ArmShift{ 23 ArmShiftType type; /// Type of shift 24 uint value; /// value (constant or register) to shift by 25 } 26 27 /// Tagged union of possible operand values 28 alias ArmOpValue = TaggedUnion!(ArmRegister, "reg", int, "imm", double, "fp", ArmOpMem, "mem", ArmSetendType, "setend"); 29 30 /// Instruction's operand 31 struct ArmOp { 32 int vectorIndex; /// Vector index for some vector operands (or -1 if irrelevant) 33 ArmShift shift; /// Potential shifting of operand 34 ArmOpType type; /// Operand type 35 ArmOpValue value; /// Operand value of type `type` 36 alias value this; /// Convenient access to value (as in original bindings) 37 38 /** In some instructions, an operand can be subtracted or added to the base register. 39 40 If TRUE, this operand is subtracted. Otherwise, it is added. 41 */ 42 bool subtracted; 43 44 package this(cs_arm_op internal){ 45 vectorIndex = internal.vector_index; 46 shift = internal.shift; 47 type = internal.type; 48 final switch(internal.type){ 49 case ArmOpType.invalid: 50 break; 51 case ArmOpType.reg, ArmOpType.sysreg: 52 value.reg = internal.reg; 53 break; 54 case ArmOpType.imm, ArmOpType.cimm, ArmOpType.pimm: 55 value.imm = internal.imm; 56 break; 57 case ArmOpType.mem: 58 value.mem = internal.mem; 59 break; 60 case ArmOpType.fp: 61 value.fp = internal.fp; 62 break; 63 case ArmOpType.setend: 64 value.setend = internal.setend; 65 break; 66 } 67 subtracted = internal.subtracted; 68 } 69 } 70 71 /// ARM-specific information about an instruction 72 struct ArmInstructionDetail { 73 bool usermode; /// User-mode registers to be loaded (for LDM/STM instructions) 74 int vectorSize; /// Scalar size for vector instructions 75 ArmVectordataType vectorData; /// Data type for elements of vector instructions 76 ArmCpsmodeType cpsMode; /// Mode operand for CPS instruction 77 ArmCpsflagType cpsFlag; /// Flags operand for CPS instruction 78 ArmCc cc; /// Conditional code for this instruction 79 bool updateFlags; /// Does this instruction update flags? 80 bool writeback; /// Does this instruction write-back? 81 ArmMemBarrier memBarrier; /// Option for some memory barrier instructions 82 83 ArmOp[] operands; /// Operands for this instruction. 84 85 package this(cs_arch_detail arch_detail){ 86 this(arch_detail.arm); 87 } 88 package this(cs_arm internal) { 89 usermode = internal.usermode; 90 vectorSize = internal.vector_size; 91 vectorData = internal.vector_data; 92 cpsMode = internal.cps_mode; 93 cpsFlag = internal.cps_flag; 94 cc = internal.cc; 95 updateFlags = internal.update_flags; 96 writeback = internal.writeback; 97 memBarrier = internal.mem_barrier; 98 99 foreach(op; internal.operands[0..internal.op_count]) 100 operands ~= ArmOp(op); 101 } 102 } 103 104 //============================================================================= 105 // Constants 106 //============================================================================= 107 108 /// ARM shift type 109 enum ArmShiftType { 110 invalid = 0, /// Invalid 111 asr, /// Arithmetic shift right (with immediate const) 112 lsl, /// Logical shift left (with immediate const) 113 lsr, /// Logical shift right (with immediate const) 114 ror, /// Rotate right (with immediate const) 115 rrx, /// Rotate right with extend (with immediate const) 116 asr_reg, /// Arithmetic shift right (with register) 117 lsl_reg, /// Logical shift left (with register) 118 lsr_reg, /// Logical shift right (with register) 119 ror_reg, /// Rotate right (with register) 120 rrx_reg, /// Rotate right with extend (with register) 121 } 122 123 /// ARM condition code 124 enum ArmCc { 125 invalid = 0, /// Invalid 126 eq, /// Equal Equal 127 ne, /// Not equal Not equal, or unordered 128 hs, /// Carry set >, ==, or unordered 129 lo, /// Carry clear Less than 130 mi, /// Minus, negative Less than 131 pl, /// Plus, positive or zero >, ==, or unordered 132 vs, /// Overflow Unordered 133 vc, /// No overflow Not unordered 134 hi, /// Unsigned higher Greater than, or unordered 135 ls, /// Unsigned lower or same Less than or equal 136 ge, /// Greater than or equal Greater than or equal 137 lt, /// Less than Less than, or unordered 138 gt, /// Greater than Greater than 139 le, /// Less than or equal <, ==, or unordered 140 al /// Always (unconditional) Always (unconditional) 141 } 142 143 /// System registers for MSR 144 enum ArmSysreg { 145 invalid = 0, 146 147 // SPSR* registers can be OR combined 148 spsr_c = 1, 149 spsr_x = 2, 150 spsr_s = 4, 151 spsr_f = 8, 152 153 // CPSR* registers can be OR combined 154 cpsr_c = 16, 155 cpsr_x = 32, 156 cpsr_s = 64, 157 cpsr_f = 128, 158 159 // Independent registers 160 apsr = 256, 161 apsr_g, 162 apsr_nzcvq, 163 apsr_nzcvqg, 164 165 iapsr, 166 iapsr_g, 167 iapsr_nzcvqg, 168 169 eapsr, 170 eapsr_g, 171 eapsr_nzcvqg, 172 173 xpsr, 174 xpsr_g, 175 xpsr_nzcvqg, 176 177 ipsr, 178 epsr, 179 iepsr, 180 181 msp, 182 psp, 183 primask, 184 basepri, 185 basepri_max, 186 faultmask, 187 control, 188 } 189 190 /// The memory barrier constants map directly to the 4-bit encoding of the option field for Memory Barrier operations 191 enum ArmMemBarrier { 192 invalid = 0, 193 reserved_0, 194 oshld, 195 oshst, 196 osh, 197 reserved_4, 198 nshld, 199 nshst, 200 nsh, 201 reserved_8, 202 ishld, 203 ishst, 204 ish, 205 reserved_12, 206 ld, 207 st, 208 sy, 209 } 210 211 /// Operand type for instruction's operands 212 enum ArmOpType { 213 invalid = 0, /// Invalid 214 reg, /// Register operand (`ArmRegister`) 215 imm, /// Immediate operand (`int`) 216 mem, /// Memory operand (`ArmOpMem`) 217 fp, /// Floating-Point operand (`double`). 218 cimm = 64, /// C-Immediate (`int` / coprocessor registers) 219 pimm, /// P-Immediate (`int` / coprocessor registers) 220 setend, /// Operand for SETEND instruction (`ArmSetendType`) 221 sysreg, /// MSR/MRS system register operand (`ArmRegister`) 222 } 223 224 /// Operand type for SETEND instruction 225 enum ArmSetendType { 226 invalid = 0, /// Invalid 227 be, /// Big-endian operand 228 le, /// Little-endian operand 229 } 230 231 /// Mode operand of CPS instruction 232 enum ArmCpsmodeType { 233 invalid = 0, /// Invalid 234 ie = 2, /// Interrupt or abort enable 235 id = 3 /// Interrupt or abort disable 236 } 237 238 /// Flags operand of CPS instruction 239 enum ArmCpsflagType { 240 invalid = 0, /// Invalid 241 f = 1, /// Enables or disables FIQ interrupts 242 i = 2, /// Enables or disables IRQ interrupts 243 a = 4, /// Enables or disables imprecise aborts 244 none = 16, /// No flag 245 } 246 247 /// Data type for elements of vector instructions. 248 enum ArmVectordataType { 249 invalid = 0, 250 251 // Integer type 252 i8, 253 i16, 254 i32, 255 i64, 256 257 // Signed integer type 258 s8, 259 s16, 260 s32, 261 s64, 262 263 // Unsigned integer type 264 u8, 265 u16, 266 u32, 267 u64, 268 269 // Data type for VMUL/VMULL 270 p8, 271 272 // Floating type 273 f32, 274 f64, 275 276 // Convert float <-> float 277 f16f64, // f16.f64 278 f64f16, // f64.f16 279 f32f16, // f32.f16 280 f16f32, // f32.f16 281 f64f32, // f64.f32 282 f32f64, // f32.f64 283 284 // Convert integer <-> float 285 s32f32, // s32.f32 286 u32f32, // u32.f32 287 f32s32, // f32.s32 288 f32u32, // f32.u32 289 f64s16, // f64.s16 290 f32s16, // f32.s16 291 f64s32, // f64.s32 292 s16f64, // s16.f64 293 s16f32, // s16.f64 294 s32f64, // s32.f64 295 u16f64, // u16.f64 296 u16f32, // u16.f32 297 u32f64, // u32.f64 298 f64u16, // f64.u16 299 f32u16, // f32.u16 300 f64u32, // f64.u32 301 } 302 303 /// ARM registers 304 enum ArmRegister { 305 invalid = 0, 306 apsr, 307 apsr_nzcv, 308 cpsr, 309 fpexc, 310 fpinst, 311 fpscr, 312 fpscr_nzcv, 313 fpsid, 314 itstate, 315 lr, 316 pc, 317 sp, 318 spsr, 319 d0, 320 d1, 321 d2, 322 d3, 323 d4, 324 d5, 325 d6, 326 d7, 327 d8, 328 d9, 329 d10, 330 d11, 331 d12, 332 d13, 333 d14, 334 d15, 335 d16, 336 d17, 337 d18, 338 d19, 339 d20, 340 d21, 341 d22, 342 d23, 343 d24, 344 d25, 345 d26, 346 d27, 347 d28, 348 d29, 349 d30, 350 d31, 351 fpinst2, 352 mvfr0, 353 mvfr1, 354 mvfr2, 355 q0, 356 q1, 357 q2, 358 q3, 359 q4, 360 q5, 361 q6, 362 q7, 363 q8, 364 q9, 365 q10, 366 q11, 367 q12, 368 q13, 369 q14, 370 q15, 371 r0, 372 r1, 373 r2, 374 r3, 375 r4, 376 r5, 377 r6, 378 r7, 379 r8, 380 r9, 381 r10, 382 r11, 383 r12, 384 s0, 385 s1, 386 s2, 387 s3, 388 s4, 389 s5, 390 s6, 391 s7, 392 s8, 393 s9, 394 s10, 395 s11, 396 s12, 397 s13, 398 s14, 399 s15, 400 s16, 401 s17, 402 s18, 403 s19, 404 s20, 405 s21, 406 s22, 407 s23, 408 s24, 409 s25, 410 s26, 411 s27, 412 s28, 413 s29, 414 s30, 415 s31, 416 417 // Alias registers 418 r13 = sp, 419 r14 = lr, 420 r15 = pc, 421 422 sb = r9, 423 sl = r10, 424 fp = r11, 425 ip = r12, 426 } 427 428 /// ARM instruction 429 enum ArmInstructionId { 430 invalid = 0, 431 432 adc, 433 add, 434 adr, 435 aesd, 436 aese, 437 aesimc, 438 aesmc, 439 and, 440 bfc, 441 bfi, 442 bic, 443 bkpt, 444 bl, 445 blx, 446 bx, 447 bxj, 448 b, 449 cdp, 450 cdp2, 451 clrex, 452 clz, 453 cmn, 454 cmp, 455 cps, 456 crc32b, 457 crc32cb, 458 crc32ch, 459 crc32cw, 460 crc32h, 461 crc32w, 462 dbg, 463 dmb, 464 dsb, 465 eor, 466 vmov, 467 fldmdbx, 468 fldmiax, 469 vmrs, 470 fstmdbx, 471 fstmiax, 472 hint, 473 hlt, 474 isb, 475 lda, 476 ldab, 477 ldaex, 478 ldaexb, 479 ldaexd, 480 ldaexh, 481 ldah, 482 ldc2l, 483 ldc2, 484 ldcl, 485 ldc, 486 ldmda, 487 ldmdb, 488 ldm, 489 ldmib, 490 ldrbt, 491 ldrb, 492 ldrd, 493 ldrex, 494 ldrexb, 495 ldrexd, 496 ldrexh, 497 ldrh, 498 ldrht, 499 ldrsb, 500 ldrsbt, 501 ldrsh, 502 ldrsht, 503 ldrt, 504 ldr, 505 mcr, 506 mcr2, 507 mcrr, 508 mcrr2, 509 mla, 510 mls, 511 mov, 512 movt, 513 movw, 514 mrc, 515 mrc2, 516 mrrc, 517 mrrc2, 518 mrs, 519 msr, 520 mul, 521 mvn, 522 orr, 523 pkhbt, 524 pkhtb, 525 pldw, 526 pld, 527 pli, 528 qadd, 529 qadd16, 530 qadd8, 531 qasx, 532 qdadd, 533 qdsub, 534 qsax, 535 qsub, 536 qsub16, 537 qsub8, 538 rbit, 539 rev, 540 rev16, 541 revsh, 542 rfeda, 543 rfedb, 544 rfeia, 545 rfeib, 546 rsb, 547 rsc, 548 sadd16, 549 sadd8, 550 sasx, 551 sbc, 552 sbfx, 553 sdiv, 554 sel, 555 setend, 556 sha1c, 557 sha1h, 558 sha1m, 559 sha1p, 560 sha1su0, 561 sha1su1, 562 sha256h, 563 sha256h2, 564 sha256su0, 565 sha256su1, 566 shadd16, 567 shadd8, 568 shasx, 569 shsax, 570 shsub16, 571 shsub8, 572 smc, 573 smlabb, 574 smlabt, 575 smlad, 576 smladx, 577 smlal, 578 smlalbb, 579 smlalbt, 580 smlald, 581 smlaldx, 582 smlaltb, 583 smlaltt, 584 smlatb, 585 smlatt, 586 smlawb, 587 smlawt, 588 smlsd, 589 smlsdx, 590 smlsld, 591 smlsldx, 592 smmla, 593 smmlar, 594 smmls, 595 smmlsr, 596 smmul, 597 smmulr, 598 smuad, 599 smuadx, 600 smulbb, 601 smulbt, 602 smull, 603 smultb, 604 smultt, 605 smulwb, 606 smulwt, 607 smusd, 608 smusdx, 609 srsda, 610 srsdb, 611 srsia, 612 srsib, 613 ssat, 614 ssat16, 615 ssax, 616 ssub16, 617 ssub8, 618 stc2l, 619 stc2, 620 stcl, 621 stc, 622 stl, 623 stlb, 624 stlex, 625 stlexb, 626 stlexd, 627 stlexh, 628 stlh, 629 stmda, 630 stmdb, 631 stm, 632 stmib, 633 strbt, 634 strb, 635 strd, 636 strex, 637 strexb, 638 strexd, 639 strexh, 640 strh, 641 strht, 642 strt, 643 str, 644 sub, 645 svc, 646 swp, 647 swpb, 648 sxtab, 649 sxtab16, 650 sxtah, 651 sxtb, 652 sxtb16, 653 sxth, 654 teq, 655 trap, 656 tst, 657 uadd16, 658 uadd8, 659 uasx, 660 ubfx, 661 udf, 662 udiv, 663 uhadd16, 664 uhadd8, 665 uhasx, 666 uhsax, 667 uhsub16, 668 uhsub8, 669 umaal, 670 umlal, 671 umull, 672 uqadd16, 673 uqadd8, 674 uqasx, 675 uqsax, 676 uqsub16, 677 uqsub8, 678 usad8, 679 usada8, 680 usat, 681 usat16, 682 usax, 683 usub16, 684 usub8, 685 uxtab, 686 uxtab16, 687 uxtah, 688 uxtb, 689 uxtb16, 690 uxth, 691 vabal, 692 vaba, 693 vabdl, 694 vabd, 695 vabs, 696 vacge, 697 vacgt, 698 vadd, 699 vaddhn, 700 vaddl, 701 vaddw, 702 vand, 703 vbic, 704 vbif, 705 vbit, 706 vbsl, 707 vceq, 708 vcge, 709 vcgt, 710 vcle, 711 vcls, 712 vclt, 713 vclz, 714 vcmp, 715 vcmpe, 716 vcnt, 717 vcvta, 718 vcvtb, 719 vcvt, 720 vcvtm, 721 vcvtn, 722 vcvtp, 723 vcvtt, 724 vdiv, 725 vdup, 726 veor, 727 vext, 728 vfma, 729 vfms, 730 vfnma, 731 vfnms, 732 vhadd, 733 vhsub, 734 vld1, 735 vld2, 736 vld3, 737 vld4, 738 vldmdb, 739 vldmia, 740 vldr, 741 vmaxnm, 742 vmax, 743 vminnm, 744 vmin, 745 vmla, 746 vmlal, 747 vmls, 748 vmlsl, 749 vmovl, 750 vmovn, 751 vmsr, 752 vmul, 753 vmull, 754 vmvn, 755 vneg, 756 vnmla, 757 vnmls, 758 vnmul, 759 vorn, 760 vorr, 761 vpadal, 762 vpaddl, 763 vpadd, 764 vpmax, 765 vpmin, 766 vqabs, 767 vqadd, 768 vqdmlal, 769 vqdmlsl, 770 vqdmulh, 771 vqdmull, 772 vqmovun, 773 vqmovn, 774 vqneg, 775 vqrdmulh, 776 vqrshl, 777 vqrshrn, 778 vqrshrun, 779 vqshl, 780 vqshlu, 781 vqshrn, 782 vqshrun, 783 vqsub, 784 vraddhn, 785 vrecpe, 786 vrecps, 787 vrev16, 788 vrev32, 789 vrev64, 790 vrhadd, 791 vrinta, 792 vrintm, 793 vrintn, 794 vrintp, 795 vrintr, 796 vrintx, 797 vrintz, 798 vrshl, 799 vrshrn, 800 vrshr, 801 vrsqrte, 802 vrsqrts, 803 vrsra, 804 vrsubhn, 805 vseleq, 806 vselge, 807 vselgt, 808 vselvs, 809 vshll, 810 vshl, 811 vshrn, 812 vshr, 813 vsli, 814 vsqrt, 815 vsra, 816 vsri, 817 vst1, 818 vst2, 819 vst3, 820 vst4, 821 vstmdb, 822 vstmia, 823 vstr, 824 vsub, 825 vsubhn, 826 vsubl, 827 vsubw, 828 vswp, 829 vtbl, 830 vtbx, 831 vcvtr, 832 vtrn, 833 vtst, 834 vuzp, 835 vzip, 836 addw, 837 asr, 838 dcps1, 839 dcps2, 840 dcps3, 841 it, 842 lsl, 843 lsr, 844 asrs, 845 lsrs, 846 orn, 847 ror, 848 rrx, 849 subs, 850 subw, 851 tbb, 852 tbh, 853 cbnz, 854 cbz, 855 movs, 856 pop, 857 push, 858 859 // Special instructions 860 nop, 861 yield, 862 wfe, 863 wfi, 864 sev, 865 sevl, 866 vpush, 867 vpop 868 } 869 870 /// Group of ARM instructions 871 enum ArmInstructionGroup { 872 invalid = 0, 873 874 // Generic groups 875 // All jump instructions (conditional+direct+indirect jumps) 876 jump, 877 878 // Architecture-specific groups 879 crypto = 128, 880 databarrier, 881 divide, 882 fparmv8, 883 multpro, 884 neon, 885 t2extractpack, 886 thumb2dsp, 887 trustzone, 888 v4t, 889 v5t, 890 v5te, 891 v6, 892 v6t2, 893 v7, 894 v8, 895 vfp2, 896 vfp3, 897 vfp4, 898 arm, 899 mclass, 900 notmclass, 901 thumb, 902 thumb1only, 903 thumb2, 904 prev8, 905 fpvmlx, 906 mulops, 907 crc, 908 dpvfp, 909 v6m 910 }