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 }