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