1 /// Types and constants of ARM64 architecture
2 module capstone.arm64;
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 Arm64Register : RegisterImpl!Arm64RegisterId {
17     package this(in Capstone cs, in int id) {
18         super(cs, id);
19     }
20 }
21 
22 /// Architecture-specific InstructionGroup variant
23 class Arm64InstructionGroup : InstructionGroupImpl!Arm64InstructionGroupId {
24     package this(in Capstone cs, in int id) {
25         super(cs, id);
26     }
27 }
28 
29 /// Architecture-specific Detail variant
30 class Arm64Detail : DetailImpl!(Arm64Register, Arm64InstructionGroup, Arm64InstructionDetail) {
31     package this(in Capstone cs, cs_detail* internal) {
32 		super(cs, internal);
33 	}
34 }
35 
36 /// Architecture-specific instruction variant
37 class Arm64Instruction : InstructionImpl!(Arm64InstructionId, Arm64Register, Arm64Detail) {
38     package this(in Capstone cs, cs_insn* internal) {
39 		super(cs, internal);
40 	}
41 }
42 
43 /// Architecture-specific Capstone variant
44 class CapstoneArm64 : CapstoneImpl!(Arm64InstructionId, Arm64Instruction) {
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.arm64, modeFlags);
52     }
53 }
54 
55 /** Instruction's operand referring to memory
56 
57 This is associated with the `Arm64OpType.mem` operand type
58 */
59 struct Arm64OpMem {
60 	Arm64Register base;	 /// Base register
61 	Arm64Register index; /// Index register
62 	int disp;			 /// displacement/offset value
63 
64 	package this(in Capstone cs, arm64_op_mem internal){
65         base = new Arm64Register(cs, internal.base);
66         index = new Arm64Register(cs, internal.index);
67         disp = internal.disp;
68     }
69 }
70 
71 /// Optional shift
72 struct Arm64Shift{
73 	Arm64ShiftType type; /// Type of shift
74 	uint value;			 /// value (constant or register) to shift by
75 
76 	package this(cs_arm64_op.Shift internal){
77         type = internal.type.to!Arm64ShiftType;
78         value = internal.value;
79     }
80 }
81 
82 /// Union of possible operand values
83 union Arm64OperandValue {
84 	Arm64Register reg;			/// Register
85 	Arm64MrsReg reg_mrs;		/// MRS register
86 	Arm64MsrReg reg_msr;		/// MSR register
87 	long imm;					/// Immediate
88 	double fp;					/// Floating-point
89 	Arm64OpMem mem;				/// Memory
90 	Arm64PState pstate;			/// P-State
91 	uint sys;					/// SYS
92 	Arm64PrefetchOp prefetch;	/// Prefetch (PRFM)
93 	Arm64BarrierOp barrier;		/// Memory barrier
94 }
95 
96 /// Instruction operand
97 struct Arm64Op {
98 	int vectorIndex;  		 /// Vector index for some vector operands (or -1 if irrelevant)
99 	Arm64Vas vas;	   		 /// Vector arrangement specifier
100 	Arm64Vess vess;	  		 /// Vector element size specifier
101 	Arm64Shift shift; 		 /// Potential shifting of operand
102 	Arm64Extender ext;		 /// Extender type of this operand
103 	Arm64OpType type; 		 /// Operand type
104 	SafeUnion!Arm64OperandValue value; /// Operand value of type `type`
105 	alias value this; 		 /// Conventient access to value (as in original bindings)
106 
107 	/** How is this operand accessed? (READ, WRITE or READ|WRITE)
108 
109 	NOTE: This field is irrelevant, i.e. equals 0, if engine is compiled in DIET mode.
110     */
111 	AccessFlags access;
112 
113     package this(in Capstone cs, cs_arm64_op internal){
114 		vectorIndex = internal.vector_index;
115 		vas = internal.vas.to!Arm64Vas;
116 		vess = internal.vess.to!Arm64Vess;
117 		shift = Arm64Shift(internal.shift);
118 		ext = internal.ext.to!Arm64Extender;
119 		type = internal.type.to!Arm64OpType;
120         access = cast(AccessType)internal.access;
121 		
122 		final switch(internal.type){
123 			case Arm64OpType.invalid:
124 				break;
125 			case Arm64OpType.reg:
126 				value.reg = new Arm64Register(cs, internal.reg);
127 				break;
128 			case Arm64OpType.reg_mrs:
129 				value.reg_mrs = internal.reg.to!Arm64MrsReg;
130 				break;
131 			case Arm64OpType.reg_msr:
132 				value.reg_msr = internal.reg.to!Arm64MsrReg;
133 				break;
134 			case Arm64OpType.imm, Arm64OpType.cimm:
135 				value.imm = internal.imm;
136 				break;
137 			case Arm64OpType.mem:
138 				value.mem = Arm64OpMem(cs, internal.mem);
139 				break;
140 			case Arm64OpType.fp:
141 				value.fp = internal.fp;
142 				break;
143 			case Arm64OpType.pstate:
144 				value.pstate = internal.pstate.to!Arm64PState;
145 				break;
146 			case Arm64OpType.sys:
147 				value.sys = internal.sys;
148 				break;
149 			case Arm64OpType.prefetch:
150 				value.prefetch = internal.prefetch.to!Arm64PrefetchOp;
151 				break;
152 			case Arm64OpType.barrier:
153 				value.barrier = internal.barrier.to!Arm64BarrierOp;
154 				break;
155 		}
156 	}
157 }
158 
159 /// ARM64-specific information about an instruction
160 struct Arm64InstructionDetail {
161 	Arm64Cc cc;		  	/// Conditional code for this instruction
162 	bool updateFlags; 	/// Does this instruction update flags?
163 	bool writeback;	  	/// Does this instruction request writeback?
164 
165 	Arm64Op[] operands; /// Operands for this instruction.
166 
167     package this(in Capstone cs, cs_arch_detail arch_detail){
168 		auto internal = arch_detail.arm64;
169 		cc = internal.cc.to!Arm64Cc;
170 		updateFlags = internal.update_flags;
171 		writeback = internal.writeback;
172 
173 		foreach(op; internal.operands[0..internal.op_count])
174 			operands ~= Arm64Op(cs, op);
175 	}
176 }
177 
178 //=============================================================================
179 // Constants
180 //=============================================================================
181 
182 /// ARM64 shift type
183 enum Arm64ShiftType {
184 	invalid = 0, /// Invalid
185 	lsl = 1,	 /// Logical shift left
186 	msl = 2,	 /// Move shift left
187 	lsr = 3,	 /// Logical shift right
188 	asr = 4,	 /// Arithmetic shift right
189 	ror = 5,	 /// Rotate right
190 }
191 
192 /// ARM64 extender type
193 enum Arm64Extender {
194 	invalid = 0,
195 	uxtb = 1,
196 	uxth = 2,
197 	uxtw = 3,
198 	uxtx = 4,
199 	sxtb = 5,
200 	sxth = 6,
201 	sxtw = 7,
202 	sxtx = 8,
203 }
204 
205 /// ARM64 condition code
206 enum Arm64Cc {
207 	invalid = 0,
208 	eq = 1,      /// Equal
209 	ne = 2,      /// Not equal:                 Not equal, or unordered
210 	hs = 3,      /// Unsigned higher or same:   >, ==, or unordered
211 	lo = 4,      /// Unsigned lower or same:    Less than
212 	mi = 5,      /// Minus, negative:           Less than
213 	pl = 6,      /// Plus, positive or zero:    >, ==, or unordered
214 	vs = 7,      /// Overflow:                  Unordered
215 	vc = 8,      /// No overflow:               Ordered
216 	hi = 9,      /// Unsigned higher:           Greater than, or unordered
217 	ls = 10,     /// Unsigned lower or same:    Less than or equal
218 	ge = 11,     /// Greater than or equal:     Greater than or equal
219 	lt = 12,     /// Less than:                 Less than, or unordered
220 	gt = 13,     /// Signed greater than:       Greater than
221 	le = 14,     /// Signed less than or equal: <, ==, or unordered
222 	al = 15,     /// Always (unconditional):    Always (unconditional)
223 
224 	nv = 16,     /// Always (unconditional):    Always (unconditional) - exists purely to disassemble 0b1111
225 }
226 
227 /// System registers for MRS
228 enum Arm64MrsReg {
229 	invalid           = 0,
230 	mdccsr_el0        = 0x9808, // 10  011  0000  0001  000
231 	dbgdtrrx_el0      = 0x9828, // 10  011  0000  0101  000
232 	mdrar_el1         = 0x8080, // 10  000  0001  0000  000
233 	oslsr_el1         = 0x808c, // 10  000  0001  0001  100
234 	dbgauthstatus_el1 = 0x83f6, // 10  000  0111  1110  110
235 	pmceid0_el0       = 0xdce6, // 11  011  1001  1100  110
236 	pmceid1_el0       = 0xdce7, // 11  011  1001  1100  111
237 	midr_el1          = 0xc000, // 11  000  0000  0000  000
238 	ccsidr_el1        = 0xc800, // 11  001  0000  0000  000
239 	clidr_el1         = 0xc801, // 11  001  0000  0000  001
240 	ctr_el0           = 0xd801, // 11  011  0000  0000  001
241 	mpidr_el1         = 0xc005, // 11  000  0000  0000  101
242 	revidr_el1        = 0xc006, // 11  000  0000  0000  110
243 	aidr_el1          = 0xc807, // 11  001  0000  0000  111
244 	dczid_el0         = 0xd807, // 11  011  0000  0000  111
245 	id_pfr0_el1       = 0xc008, // 11  000  0000  0001  000
246 	id_pfr1_el1       = 0xc009, // 11  000  0000  0001  001
247 	id_dfr0_el1       = 0xc00a, // 11  000  0000  0001  010
248 	id_afr0_el1       = 0xc00b, // 11  000  0000  0001  011
249 	id_mmfr0_el1      = 0xc00c, // 11  000  0000  0001  100
250 	id_mmfr1_el1      = 0xc00d, // 11  000  0000  0001  101
251 	id_mmfr2_el1      = 0xc00e, // 11  000  0000  0001  110
252 	id_mmfr3_el1      = 0xc00f, // 11  000  0000  0001  111
253 	id_isar0_el1      = 0xc010, // 11  000  0000  0010  000
254 	id_isar1_el1      = 0xc011, // 11  000  0000  0010  001
255 	id_isar2_el1      = 0xc012, // 11  000  0000  0010  010
256 	id_isar3_el1      = 0xc013, // 11  000  0000  0010  011
257 	id_isar4_el1      = 0xc014, // 11  000  0000  0010  100
258 	id_isar5_el1      = 0xc015, // 11  000  0000  0010  101
259 	id_a64pfr0_el1    = 0xc020, // 11  000  0000  0100  000
260 	id_a64pfr1_el1    = 0xc021, // 11  000  0000  0100  001
261 	id_a64dfr0_el1    = 0xc028, // 11  000  0000  0101  000
262 	id_a64dfr1_el1    = 0xc029, // 11  000  0000  0101  001
263 	id_a64afr0_el1    = 0xc02c, // 11  000  0000  0101  100
264 	id_a64afr1_el1    = 0xc02d, // 11  000  0000  0101  101
265 	id_a64isar0_el1   = 0xc030, // 11  000  0000  0110  000
266 	id_a64isar1_el1   = 0xc031, // 11  000  0000  0110  001
267 	id_a64mmfr0_el1   = 0xc038, // 11  000  0000  0111  000
268 	id_a64mmfr1_el1   = 0xc039, // 11  000  0000  0111  001
269 	mvfr0_el1         = 0xc018, // 11  000  0000  0011  000
270 	mvfr1_el1         = 0xc019, // 11  000  0000  0011  001
271 	mvfr2_el1         = 0xc01a, // 11  000  0000  0011  010
272 	rvbar_el1         = 0xc601, // 11  000  1100  0000  001
273 	rvbar_el2         = 0xe601, // 11  100  1100  0000  001
274 	rvbar_el3         = 0xf601, // 11  110  1100  0000  001
275 	isr_el1           = 0xc608, // 11  000  1100  0001  000
276 	cntpct_el0        = 0xdf01, // 11  011  1110  0000  001
277 	cntvct_el0        = 0xdf02, // 11  011  1110  0000  010
278 
279 	// Trace registers
280 	trcstatr          = 0x8818, // 10  001  0000  0011  000
281 	trcidr8           = 0x8806, // 10  001  0000  0000  110
282 	trcidr9           = 0x880e, // 10  001  0000  0001  110
283 	trcidr10          = 0x8816, // 10  001  0000  0010  110
284 	trcidr11          = 0x881e, // 10  001  0000  0011  110
285 	trcidr12          = 0x8826, // 10  001  0000  0100  110
286 	trcidr13          = 0x882e, // 10  001  0000  0101  110
287 	trcidr0           = 0x8847, // 10  001  0000  1000  111
288 	trcidr1           = 0x884f, // 10  001  0000  1001  111
289 	trcidr2           = 0x8857, // 10  001  0000  1010  111
290 	trcidr3           = 0x885f, // 10  001  0000  1011  111
291 	trcidr4           = 0x8867, // 10  001  0000  1100  111
292 	trcidr5           = 0x886f, // 10  001  0000  1101  111
293 	trcidr6           = 0x8877, // 10  001  0000  1110  111
294 	trcidr7           = 0x887f, // 10  001  0000  1111  111
295 	trcoslsr          = 0x888c, // 10  001  0001  0001  100
296 	trcpdsr           = 0x88ac, // 10  001  0001  0101  100
297 	trcdevaff0        = 0x8bd6, // 10  001  0111  1010  110
298 	trcdevaff1        = 0x8bde, // 10  001  0111  1011  110
299 	trclsr            = 0x8bee, // 10  001  0111  1101  110
300 	trcauthstatus     = 0x8bf6, // 10  001  0111  1110  110
301 	trcdevarch        = 0x8bfe, // 10  001  0111  1111  110
302 	trcdevid          = 0x8b97, // 10  001  0111  0010  111
303 	trcdevtype        = 0x8b9f, // 10  001  0111  0011  111
304 	trcpidr4          = 0x8ba7, // 10  001  0111  0100  111
305 	trcpidr5          = 0x8baf, // 10  001  0111  0101  111
306 	trcpidr6          = 0x8bb7, // 10  001  0111  0110  111
307 	trcpidr7          = 0x8bbf, // 10  001  0111  0111  111
308 	trcpidr0          = 0x8bc7, // 10  001  0111  1000  111
309 	trcpidr1          = 0x8bcf, // 10  001  0111  1001  111
310 	trcpidr2          = 0x8bd7, // 10  001  0111  1010  111
311 	trcpidr3          = 0x8bdf, // 10  001  0111  1011  111
312 	trccidr0          = 0x8be7, // 10  001  0111  1100  111
313 	trccidr1          = 0x8bef, // 10  001  0111  1101  111
314 	trccidr2          = 0x8bf7, // 10  001  0111  1110  111
315 	trccidr3          = 0x8bff, // 10  001  0111  1111  111
316 
317 	// GICv3 registers
318 	icc_iar1_el1      = 0xc660, // 11  000  1100  1100  000
319 	icc_iar0_el1      = 0xc640, // 11  000  1100  1000  000
320 	icc_hppir1_el1    = 0xc662, // 11  000  1100  1100  010
321 	icc_hppir0_el1    = 0xc642, // 11  000  1100  1000  010
322 	icc_rpr_el1       = 0xc65b, // 11  000  1100  1011  011
323 	ich_vtr_el2       = 0xe659, // 11  100  1100  1011  001
324 	ich_eisr_el2      = 0xe65b, // 11  100  1100  1011  011
325 	ich_elsr_el2      = 0xe65d, // 11  100  1100  1011  101
326 }
327 
328 /// System registers for MSR
329 enum Arm64MsrReg {
330 	dbgdtrtx_el0      = 0x9828, // 10  011  0000  0101  000
331 	oslar_el1         = 0x8084, // 10  000  0001  0000  100
332 	pmswinc_el0       = 0xdce4, // 11  011  1001  1100  100
333 
334 	// Trace registers
335 	trcoslar          = 0x8884, // 10  001  0001  0000  100
336 	trclar            = 0x8be6, // 10  001  0111  1100  110
337 
338 	// GICv3 registers
339 	icc_eoir1_el1     = 0xc661, // 11  000  1100  1100  001
340 	icc_eoir0_el1     = 0xc641, // 11  000  1100  1000  001
341 	icc_dir_el1       = 0xc659, // 11  000  1100  1011  001
342 	icc_sgi1r_el1     = 0xc65d, // 11  000  1100  1011  101
343 	icc_asgi1r_el1    = 0xc65e, // 11  000  1100  1011  110
344 	icc_sgi0r_el1     = 0xc65f, // 11  000  1100  1011  111
345 }
346 
347 /// System PState Field (MSR instruction)
348 enum Arm64PState {
349 	invalid = 0,
350 	spsel   = 0x05,
351 	daifset = 0x1e,
352 	daifclr = 0x1f
353 }
354 
355 /// Vector arrangement specifier (for FloatingPoint/Advanced SIMD instructions)
356 enum Arm64Vas {
357 	invalid = 0,
358 	vas_8b,
359 	vas_16b,
360 	vas_4h,
361 	vas_8h,
362 	vas_2s,
363 	vas_4s,
364 	vas_1d,
365 	vas_2d,
366 	vas_1q,
367 }
368 
369 /// Vector element size specifier
370 enum Arm64Vess {
371 	invalid = 0,
372 	b,
373 	h,
374 	s,
375 	d,
376 }
377 
378 /// Memory barrier operands
379 enum Arm64BarrierOp {
380 	invalid = 0,
381 	oshld = 0x1,
382 	oshst = 0x2,
383 	osh =   0x3,
384 	nshld = 0x5,
385 	nshst = 0x6,
386 	nsh =   0x7,
387 	ishld = 0x9,
388 	ishst = 0xa,
389 	ish =   0xb,
390 	ld =    0xd,
391 	st =    0xe,
392 	sy =    0xf
393 }
394 
395 /// Operand type for instruction's operands
396 enum Arm64OpType {
397 	invalid = 0,  /// Invalid
398 	reg, 		  /// Register operand (`Arm64Register`)
399 	imm, 		  /// Immediate operand (`long`)
400 	mem, 		  /// Memory operand (`Arm64OpMem`)
401 	fp,  		  /// Floating-point operand (`double`)
402 	cimm = 64, 	  /// C-Immediate (`long`)
403 	reg_mrs, 	  /// MRS register operand (`Arm64Register`)
404 	reg_msr,      /// MSR register operand (`Arm64Register`)
405 	pstate, 	  /// P-state operand (`Arm64PState`)
406 	sys, 		  /// Sys operand for ic/dc/at/tlbi instructions (`uint`)
407 	prefetch, 	  /// Prefetch operand prfm (`Arm64PrefetchOp`)
408 	barrier,	  /// Memory barrier operand for isb/dmb/dsb instructions (`Arm64BarrierOp`)
409 }
410 
411 /// TLBI operations
412 enum Arm64TlbiOp {
413 	invalid = 0,
414 	vmalle1is,
415 	vae1is,
416 	aside1is,
417 	vaae1is,
418 	vale1is,
419 	vaale1is,
420 	alle2is,
421 	vae2is,
422 	alle1is,
423 	vale2is,
424 	vmalls12e1is,
425 	alle3is,
426 	vae3is,
427 	vale3is,
428 	ipas2e1is,
429 	ipas2le1is,
430 	ipas2e1,
431 	ipas2le1,
432 	vmalle1,
433 	vae1,
434 	aside1,
435 	vaae1,
436 	vale1,
437 	vaale1,
438 	alle2,
439 	vae2,
440 	alle1,
441 	vale2,
442 	vmalls12e1,
443 	alle3,
444 	vae3,
445 	vale3,
446 }
447 
448 /// AT operations
449 enum Arm64AtOp {
450 	s1e1r,
451 	s1e1w,
452 	s1e0r,
453 	s1e0w,
454 	s1e2r,
455 	s1e2w,
456 	s12e1r,
457 	s12e1w,
458 	s12e0r,
459 	s12e0w,
460 	s1e3r,
461 	s1e3w,
462 }
463 
464 /// DC operations
465 enum Arm64DcOp {
466 	invalid = 0,
467 	zva,
468 	ivac,
469 	isw,
470 	cvac,
471 	csw,
472 	cvau,
473 	civac,
474 	cisw,
475 }
476 
477 /// IC operations
478 enum Arm64IcOp {
479 	invalid = 0,
480 	ialluis,
481 	iallu,
482 	ivau,
483 }
484 
485 /// Prefetch operations (PRFM)
486 enum Arm64PrefetchOp {
487 	invalid = 0,
488 	pldl1keep = 0x00 + 1,
489 	pldl1strm = 0x01 + 1,
490 	pldl2keep = 0x02 + 1,
491 	pldl2strm = 0x03 + 1,
492 	pldl3keep = 0x04 + 1,
493 	pldl3strm = 0x05 + 1,
494 	plil1keep = 0x08 + 1,
495 	plil1strm = 0x09 + 1,
496 	plil2keep = 0x0a + 1,
497 	plil2strm = 0x0b + 1,
498 	plil3keep = 0x0c + 1,
499 	plil3strm = 0x0d + 1,
500 	pstl1keep = 0x10 + 1,
501 	pstl1strm = 0x11 + 1,
502 	pstl2keep = 0x12 + 1,
503 	pstl2strm = 0x13 + 1,
504 	pstl3keep = 0x14 + 1,
505 	pstl3strm = 0x15 + 1,
506 }
507 
508 /// ARM64 registers
509 enum Arm64RegisterId {
510 	invalid = 0,
511 
512 	x29,
513 	x30,
514 	nzcv,
515 	sp,
516 	wsp,
517 	wzr,
518 	xzr,
519 	b0,
520 	b1,
521 	b2,
522 	b3,
523 	b4,
524 	b5,
525 	b6,
526 	b7,
527 	b8,
528 	b9,
529 	b10,
530 	b11,
531 	b12,
532 	b13,
533 	b14,
534 	b15,
535 	b16,
536 	b17,
537 	b18,
538 	b19,
539 	b20,
540 	b21,
541 	b22,
542 	b23,
543 	b24,
544 	b25,
545 	b26,
546 	b27,
547 	b28,
548 	b29,
549 	b30,
550 	b31,
551 	d0,
552 	d1,
553 	d2,
554 	d3,
555 	d4,
556 	d5,
557 	d6,
558 	d7,
559 	d8,
560 	d9,
561 	d10,
562 	d11,
563 	d12,
564 	d13,
565 	d14,
566 	d15,
567 	d16,
568 	d17,
569 	d18,
570 	d19,
571 	d20,
572 	d21,
573 	d22,
574 	d23,
575 	d24,
576 	d25,
577 	d26,
578 	d27,
579 	d28,
580 	d29,
581 	d30,
582 	d31,
583 	h0,
584 	h1,
585 	h2,
586 	h3,
587 	h4,
588 	h5,
589 	h6,
590 	h7,
591 	h8,
592 	h9,
593 	h10,
594 	h11,
595 	h12,
596 	h13,
597 	h14,
598 	h15,
599 	h16,
600 	h17,
601 	h18,
602 	h19,
603 	h20,
604 	h21,
605 	h22,
606 	h23,
607 	h24,
608 	h25,
609 	h26,
610 	h27,
611 	h28,
612 	h29,
613 	h30,
614 	h31,
615 	q0,
616 	q1,
617 	q2,
618 	q3,
619 	q4,
620 	q5,
621 	q6,
622 	q7,
623 	q8,
624 	q9,
625 	q10,
626 	q11,
627 	q12,
628 	q13,
629 	q14,
630 	q15,
631 	q16,
632 	q17,
633 	q18,
634 	q19,
635 	q20,
636 	q21,
637 	q22,
638 	q23,
639 	q24,
640 	q25,
641 	q26,
642 	q27,
643 	q28,
644 	q29,
645 	q30,
646 	q31,
647 	s0,
648 	s1,
649 	s2,
650 	s3,
651 	s4,
652 	s5,
653 	s6,
654 	s7,
655 	s8,
656 	s9,
657 	s10,
658 	s11,
659 	s12,
660 	s13,
661 	s14,
662 	s15,
663 	s16,
664 	s17,
665 	s18,
666 	s19,
667 	s20,
668 	s21,
669 	s22,
670 	s23,
671 	s24,
672 	s25,
673 	s26,
674 	s27,
675 	s28,
676 	s29,
677 	s30,
678 	s31,
679 	w0,
680 	w1,
681 	w2,
682 	w3,
683 	w4,
684 	w5,
685 	w6,
686 	w7,
687 	w8,
688 	w9,
689 	w10,
690 	w11,
691 	w12,
692 	w13,
693 	w14,
694 	w15,
695 	w16,
696 	w17,
697 	w18,
698 	w19,
699 	w20,
700 	w21,
701 	w22,
702 	w23,
703 	w24,
704 	w25,
705 	w26,
706 	w27,
707 	w28,
708 	w29,
709 	w30,
710 	x0,
711 	x1,
712 	x2,
713 	x3,
714 	x4,
715 	x5,
716 	x6,
717 	x7,
718 	x8,
719 	x9,
720 	x10,
721 	x11,
722 	x12,
723 	x13,
724 	x14,
725 	x15,
726 	x16,
727 	x17,
728 	x18,
729 	x19,
730 	x20,
731 	x21,
732 	x22,
733 	x23,
734 	x24,
735 	x25,
736 	x26,
737 	x27,
738 	x28,
739 
740 	v0,
741 	v1,
742 	v2,
743 	v3,
744 	v4,
745 	v5,
746 	v6,
747 	v7,
748 	v8,
749 	v9,
750 	v10,
751 	v11,
752 	v12,
753 	v13,
754 	v14,
755 	v15,
756 	v16,
757 	v17,
758 	v18,
759 	v19,
760 	v20,
761 	v21,
762 	v22,
763 	v23,
764 	v24,
765 	v25,
766 	v26,
767 	v27,
768 	v28,
769 	v29,
770 	v30,
771 	v31,
772 
773 	// Alias registers
774 	ip1 = x16,
775 	ip0 = x17,
776 	fp = x29,
777 	lr = x30,
778 }
779 
780 /// ARM64 instruction
781 enum Arm64InstructionId {
782 	invalid = 0,
783 
784 	abs,
785 	adc,
786 	addhn,
787 	addhn2,
788 	addp,
789 	add,
790 	addv,
791 	adr,
792 	adrp,
793 	aesd,
794 	aese,
795 	aesimc,
796 	aesmc,
797 	and,
798 	asr,
799 	b,
800 	bfm,
801 	bic,
802 	bif,
803 	bit,
804 	bl,
805 	blr,
806 	br,
807 	brk,
808 	bsl,
809 	cbnz,
810 	cbz,
811 	ccmn,
812 	ccmp,
813 	clrex,
814 	cls,
815 	clz,
816 	cmeq,
817 	cmge,
818 	cmgt,
819 	cmhi,
820 	cmhs,
821 	cmle,
822 	cmlt,
823 	cmtst,
824 	cnt,
825 	mov,
826 	crc32b,
827 	crc32cb,
828 	crc32ch,
829 	crc32cw,
830 	crc32cx,
831 	crc32h,
832 	crc32w,
833 	crc32x,
834 	csel,
835 	csinc,
836 	csinv,
837 	csneg,
838 	dcps1,
839 	dcps2,
840 	dcps3,
841 	dmb,
842 	drps,
843 	dsb,
844 	dup,
845 	eon,
846 	eor,
847 	eret,
848 	extr,
849 	ext,
850 	fabd,
851 	fabs,
852 	facge,
853 	facgt,
854 	fadd,
855 	faddp,
856 	fccmp,
857 	fccmpe,
858 	fcmeq,
859 	fcmge,
860 	fcmgt,
861 	fcmle,
862 	fcmlt,
863 	fcmp,
864 	fcmpe,
865 	fcsel,
866 	fcvtas,
867 	fcvtau,
868 	fcvt,
869 	fcvtl,
870 	fcvtl2,
871 	fcvtms,
872 	fcvtmu,
873 	fcvtns,
874 	fcvtnu,
875 	fcvtn,
876 	fcvtn2,
877 	fcvtps,
878 	fcvtpu,
879 	fcvtxn,
880 	fcvtxn2,
881 	fcvtzs,
882 	fcvtzu,
883 	fdiv,
884 	fmadd,
885 	fmax,
886 	fmaxnm,
887 	fmaxnmp,
888 	fmaxnmv,
889 	fmaxp,
890 	fmaxv,
891 	fmin,
892 	fminnm,
893 	fminnmp,
894 	fminnmv,
895 	fminp,
896 	fminv,
897 	fmla,
898 	fmls,
899 	fmov,
900 	fmsub,
901 	fmul,
902 	fmulx,
903 	fneg,
904 	fnmadd,
905 	fnmsub,
906 	fnmul,
907 	frecpe,
908 	frecps,
909 	frecpx,
910 	frinta,
911 	frinti,
912 	frintm,
913 	frintn,
914 	frintp,
915 	frintx,
916 	frintz,
917 	frsqrte,
918 	frsqrts,
919 	fsqrt,
920 	fsub,
921 	hint,
922 	hlt,
923 	hvc,
924 	ins,
925 
926 	isb,
927 	ld1,
928 	ld1r,
929 	ld2r,
930 	ld2,
931 	ld3r,
932 	ld3,
933 	ld4,
934 	ld4r,
935 
936 	ldarb,
937 	ldarh,
938 	ldar,
939 	ldaxp,
940 	ldaxrb,
941 	ldaxrh,
942 	ldaxr,
943 	ldnp,
944 	ldp,
945 	ldpsw,
946 	ldrb,
947 	ldr,
948 	ldrh,
949 	ldrsb,
950 	ldrsh,
951 	ldrsw,
952 	ldtrb,
953 	ldtrh,
954 	ldtrsb,
955 
956 	ldtrsh,
957 	ldtrsw,
958 	ldtr,
959 	ldurb,
960 	ldur,
961 	ldurh,
962 	ldursb,
963 	ldursh,
964 	ldursw,
965 	ldxp,
966 	ldxrb,
967 	ldxrh,
968 	ldxr,
969 	lsl,
970 	lsr,
971 	madd,
972 	mla,
973 	mls,
974 	movi,
975 	movk,
976 	movn,
977 	movz,
978 	mrs,
979 	msr,
980 	msub,
981 	mul,
982 	mvni,
983 	neg,
984 	not,
985 	orn,
986 	orr,
987 	pmull2,
988 	pmull,
989 	pmul,
990 	prfm,
991 	prfum,
992 	raddhn,
993 	raddhn2,
994 	rbit,
995 	ret,
996 	rev16,
997 	rev32,
998 	rev64,
999 	rev,
1000 	ror,
1001 	rshrn2,
1002 	rshrn,
1003 	rsubhn,
1004 	rsubhn2,
1005 	sabal2,
1006 	sabal,
1007 
1008 	saba,
1009 	sabdl2,
1010 	sabdl,
1011 	sabd,
1012 	sadalp,
1013 	saddlp,
1014 	saddlv,
1015 	saddl2,
1016 	saddl,
1017 	saddw2,
1018 	saddw,
1019 	sbc,
1020 	sbfm,
1021 	scvtf,
1022 	sdiv,
1023 	sha1c,
1024 	sha1h,
1025 	sha1m,
1026 	sha1p,
1027 	sha1su0,
1028 	sha1su1,
1029 	sha256h2,
1030 	sha256h,
1031 	sha256su0,
1032 	sha256su1,
1033 	shadd,
1034 	shll2,
1035 	shll,
1036 	shl,
1037 	shrn2,
1038 	shrn,
1039 	shsub,
1040 	sli,
1041 	smaddl,
1042 	smaxp,
1043 	smaxv,
1044 	smax,
1045 	smc,
1046 	sminp,
1047 	sminv,
1048 	smin,
1049 	smlal2,
1050 	smlal,
1051 	smlsl2,
1052 	smlsl,
1053 	smov,
1054 	smsubl,
1055 	smulh,
1056 	smull2,
1057 	smull,
1058 	sqabs,
1059 	sqadd,
1060 	sqdmlal,
1061 	sqdmlal2,
1062 	sqdmlsl,
1063 	sqdmlsl2,
1064 	sqdmulh,
1065 	sqdmull,
1066 	sqdmull2,
1067 	sqneg,
1068 	sqrdmulh,
1069 	sqrshl,
1070 	sqrshrn,
1071 	sqrshrn2,
1072 	sqrshrun,
1073 	sqrshrun2,
1074 	sqshlu,
1075 	sqshl,
1076 	sqshrn,
1077 	sqshrn2,
1078 	sqshrun,
1079 	sqshrun2,
1080 	sqsub,
1081 	sqxtn2,
1082 	sqxtn,
1083 	sqxtun2,
1084 	sqxtun,
1085 	srhadd,
1086 	sri,
1087 	srshl,
1088 	srshr,
1089 	srsra,
1090 	sshll2,
1091 	sshll,
1092 	sshl,
1093 	sshr,
1094 	ssra,
1095 	ssubl2,
1096 	ssubl,
1097 	ssubw2,
1098 	ssubw,
1099 	st1,
1100 	st2,
1101 	st3,
1102 	st4,
1103 	stlrb,
1104 	stlrh,
1105 	stlr,
1106 	stlxp,
1107 	stlxrb,
1108 	stlxrh,
1109 	stlxr,
1110 	stnp,
1111 	stp,
1112 	strb,
1113 	str,
1114 	strh,
1115 	sttrb,
1116 	sttrh,
1117 	sttr,
1118 	sturb,
1119 	stur,
1120 	sturh,
1121 	stxp,
1122 	stxrb,
1123 	stxrh,
1124 	stxr,
1125 	subhn,
1126 	subhn2,
1127 	sub,
1128 	suqadd,
1129 	svc,
1130 	sysl,
1131 	sys,
1132 	tbl,
1133 	tbnz,
1134 	tbx,
1135 	tbz,
1136 	trn1,
1137 	trn2,
1138 	uabal2,
1139 	uabal,
1140 	uaba,
1141 	uabdl2,
1142 	uabdl,
1143 	uabd,
1144 	uadalp,
1145 	uaddlp,
1146 	uaddlv,
1147 	uaddl2,
1148 	uaddl,
1149 	uaddw2,
1150 	uaddw,
1151 	ubfm,
1152 	ucvtf,
1153 	udiv,
1154 	uhadd,
1155 	uhsub,
1156 	umaddl,
1157 	umaxp,
1158 	umaxv,
1159 	umax,
1160 	uminp,
1161 	uminv,
1162 	umin,
1163 	umlal2,
1164 	umlal,
1165 	umlsl2,
1166 	umlsl,
1167 	umov,
1168 	umsubl,
1169 	umulh,
1170 	umull2,
1171 	umull,
1172 	uqadd,
1173 	uqrshl,
1174 	uqrshrn,
1175 	uqrshrn2,
1176 	uqshl,
1177 	uqshrn,
1178 	uqshrn2,
1179 	uqsub,
1180 	uqxtn2,
1181 	uqxtn,
1182 	urecpe,
1183 	urhadd,
1184 	urshl,
1185 	urshr,
1186 	ursqrte,
1187 	ursra,
1188 	ushll2,
1189 	ushll,
1190 	ushl,
1191 	ushr,
1192 	usqadd,
1193 	usra,
1194 	usubl2,
1195 	usubl,
1196 	usubw2,
1197 	usubw,
1198 	uzp1,
1199 	uzp2,
1200 	xtn2,
1201 	xtn,
1202 	zip1,
1203 	zip2,
1204 
1205 	// alias insn
1206 	mneg,
1207 	umnegl,
1208 	smnegl,
1209 	nop,
1210 	yield,
1211 	wfe,
1212 	wfi,
1213 	sev,
1214 	sevl,
1215 	ngc,
1216 	sbfiz,
1217 	ubfiz,
1218 	sbfx,
1219 	ubfx,
1220 	bfi,
1221 	bfxil,
1222 	cmn,
1223 	mvn,
1224 	tst,
1225 	cset,
1226 	cinc,
1227 	csetm,
1228 	cinv,
1229 	cneg,
1230 	sxtb,
1231 	sxth,
1232 	sxtw,
1233 	cmp,
1234 	uxtb,
1235 	uxth,
1236 	uxtw,
1237 	ic,
1238 	dc,
1239 	at,
1240 	tlbi,
1241 
1242 	negs,
1243 	ngcs,
1244 }
1245 
1246 /// Group of ARM64 instructions
1247 enum Arm64InstructionGroupId {
1248 	invalid = 0,
1249 
1250 	// Generic groups
1251 	// all jump instructions (conditional+direct+indirect jumps)
1252 	jump,
1253 	call,
1254 	ret,
1255 	int_,
1256 	privilege = 6,
1257 	branch_relative,
1258 
1259 	// Architecture-specific groups
1260 	crypto = 128,
1261 	fparmv8,
1262 	neon,
1263 	crc,
1264 }