1use alloc::{format, string::ToString, vec::Vec};
2use core::cmp::Ordering;
3
4use anyhow::Result;
5use object::elf;
6use yaxpeax_arch::{Arch as YaxpeaxArch, Decoder, Reader, U8Reader};
7use yaxpeax_arm::armv8::a64::{
8 ARMv8, DecodeError, InstDecoder, Instruction, Opcode, Operand, SIMDSizeCode, ShiftStyle,
9 SizeCode,
10};
11
12use crate::{
13 arch::{Arch, OPCODE_INVALID},
14 diff::{DiffObjConfig, display::InstructionPart},
15 obj::{
16 InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
17 },
18};
19
20#[derive(Debug)]
21pub struct ArchArm64 {}
22
23impl ArchArm64 {
24 pub fn new(_file: &object::File) -> Result<Self> { Ok(Self {}) }
25}
26
27impl Arch for ArchArm64 {
28 fn scan_instructions_internal(
29 &self,
30 address: u64,
31 code: &[u8],
32 _section_index: usize,
33 _relocations: &[Relocation],
34 _diff_config: &DiffObjConfig,
35 ) -> Result<Vec<InstructionRef>> {
36 let start_address = address;
37 let mut ops = Vec::<InstructionRef>::with_capacity(code.len() / 4);
38
39 let mut reader = U8Reader::new(code);
40 let decoder = InstDecoder::default();
41 let mut ins = Instruction::default();
42 loop {
43 let offset = <U8Reader<'_> as Reader<
45 <ARMv8 as YaxpeaxArch>::Address,
46 <ARMv8 as YaxpeaxArch>::Word,
47 >>::total_offset(&mut reader);
48 let address = start_address + offset;
49 match decoder.decode_into(&mut ins, &mut reader) {
50 Ok(()) => {}
51 Err(e) => match e {
52 DecodeError::ExhaustedInput => break,
53 DecodeError::InvalidOpcode
54 | DecodeError::InvalidOperand
55 | DecodeError::IncompleteDecoder => {
56 ops.push(InstructionRef {
57 address,
58 size: 4,
59 opcode: OPCODE_INVALID,
60 branch_dest: None,
61 });
62 continue;
63 }
64 },
65 }
66
67 let opcode = opcode_to_u16(ins.opcode);
68 let branch_dest =
69 branch_dest(opcode, address, &code[offset as usize..offset as usize + 4]);
70 ops.push(InstructionRef { address, size: 4, opcode, branch_dest });
71 }
72
73 Ok(ops)
74 }
75
76 fn display_instruction(
77 &self,
78 resolved: ResolvedInstructionRef,
79 _diff_config: &DiffObjConfig,
80 cb: &mut dyn FnMut(InstructionPart) -> Result<()>,
81 ) -> Result<()> {
82 let mut reader = U8Reader::new(resolved.code);
83 let decoder = InstDecoder::default();
84 let mut ins = Instruction::default();
85 if decoder.decode_into(&mut ins, &mut reader).is_err() {
86 cb(InstructionPart::opcode("<invalid>", OPCODE_INVALID))?;
87 return Ok(());
88 }
89
90 let mut ctx = DisplayCtx {
91 address: resolved.ins_ref.address,
92 section_index: 0,
93 start_address: resolved.symbol.address,
94 end_address: resolved.symbol.address + resolved.symbol.size,
95 reloc: resolved.relocation,
96 };
97
98 let mut display_args = Vec::with_capacity(16);
99 let mnemonic = display_instruction(&mut |ret| display_args.push(ret), &ins, &mut ctx);
100 cb(InstructionPart::opcode(mnemonic, resolved.ins_ref.opcode))?;
101 for arg in display_args {
102 cb(arg)?;
103 }
104 Ok(())
105 }
106
107 fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> {
108 match flags {
109 RelocationFlags::Elf(r_type) => match r_type {
110 elf::R_AARCH64_NONE => Some("R_AARCH64_NONE"),
111 elf::R_AARCH64_ABS64 => Some("R_AARCH64_ABS64"),
112 elf::R_AARCH64_ABS32 => Some("R_AARCH64_ABS32"),
113 elf::R_AARCH64_ABS16 => Some("R_AARCH64_ABS16"),
114 elf::R_AARCH64_PREL64 => Some("R_AARCH64_PREL64"),
115 elf::R_AARCH64_PREL32 => Some("R_AARCH64_PREL32"),
116 elf::R_AARCH64_PREL16 => Some("R_AARCH64_PREL16"),
117 elf::R_AARCH64_ADR_PREL_PG_HI21 => Some("R_AARCH64_ADR_PREL_PG_HI21"),
118 elf::R_AARCH64_ADD_ABS_LO12_NC => Some("R_AARCH64_ADD_ABS_LO12_NC"),
119 elf::R_AARCH64_JUMP26 => Some("R_AARCH64_JUMP26"),
120 elf::R_AARCH64_CALL26 => Some("R_AARCH64_CALL26"),
121 elf::R_AARCH64_LDST32_ABS_LO12_NC => Some("R_AARCH64_LDST32_ABS_LO12_NC"),
122 elf::R_AARCH64_ADR_GOT_PAGE => Some("R_AARCH64_ADR_GOT_PAGE"),
123 elf::R_AARCH64_LD64_GOT_LO12_NC => Some("R_AARCH64_LD64_GOT_LO12_NC"),
124 _ => None,
125 },
126 _ => None,
127 }
128 }
129
130 fn data_reloc_size(&self, flags: RelocationFlags) -> usize {
131 match flags {
132 RelocationFlags::Elf(r_type) => match r_type {
133 elf::R_AARCH64_ABS64 => 8,
134 elf::R_AARCH64_ABS32 => 4,
135 elf::R_AARCH64_ABS16 => 2,
136 elf::R_AARCH64_PREL64 => 8,
137 elf::R_AARCH64_PREL32 => 4,
138 elf::R_AARCH64_PREL16 => 2,
139 _ => 1,
140 },
141 _ => 1,
142 }
143 }
144}
145
146fn branch_dest(opcode: u16, address: u64, code: &[u8]) -> Option<u64> {
147 const OPCODE_B: u16 = opcode_to_u16(Opcode::B);
148 const OPCODE_BL: u16 = opcode_to_u16(Opcode::BL);
149 const OPCODE_BCC: u16 = opcode_to_u16(Opcode::Bcc(0));
150 const OPCODE_CBZ: u16 = opcode_to_u16(Opcode::CBZ);
151 const OPCODE_CBNZ: u16 = opcode_to_u16(Opcode::CBNZ);
152 const OPCODE_TBZ: u16 = opcode_to_u16(Opcode::TBZ);
153 const OPCODE_TBNZ: u16 = opcode_to_u16(Opcode::TBNZ);
154
155 let word = u32::from_le_bytes(code.try_into().ok()?);
156 match opcode {
157 OPCODE_B | OPCODE_BL => {
158 let offset = ((word & 0x03ff_ffff) << 2) as i32;
159 let extended_offset = (offset << 4) >> 4;
160 address.checked_add_signed(extended_offset as i64)
161 }
162 OPCODE_BCC | OPCODE_CBZ | OPCODE_CBNZ => {
163 let offset = (word as i32 & 0x00ff_ffe0) >> 3;
164 let extended_offset = (offset << 11) >> 11;
165 address.checked_add_signed(extended_offset as i64)
166 }
167 OPCODE_TBZ | OPCODE_TBNZ => {
168 let offset = (word as i32 & 0x0007_ffe0) >> 3;
169 let extended_offset = (offset << 16) >> 16;
170 address.checked_add_signed(extended_offset as i64)
171 }
172 _ => None,
173 }
174}
175
176struct DisplayCtx<'a> {
177 address: u64,
178 section_index: usize,
179 start_address: u64,
180 end_address: u64,
181 reloc: Option<ResolvedRelocation<'a>>,
182}
183
184fn display_instruction<Cb>(args: &mut Cb, ins: &Instruction, ctx: &mut DisplayCtx) -> &'static str
189where Cb: FnMut(InstructionPart<'static>) {
190 let mnemonic = match ins.opcode {
191 Opcode::Invalid => return "<invalid>",
192 Opcode::UDF => "udf",
193 Opcode::MOVN => {
194 let imm = if let Operand::ImmShift(imm, shift) = ins.operands[1] {
195 !((imm as u64) << shift)
196 } else {
197 unreachable!("movn operand 1 is always ImmShift");
198 };
199 let imm = if let Operand::Register(size, _) = ins.operands[0] {
200 if size == SizeCode::W { imm as u32 as u64 } else { imm }
201 } else {
202 unreachable!("movn operand 0 is always Register");
203 };
204 push_operand(args, &ins.operands[0], ctx);
205 push_separator(args);
206 push_unsigned(args, imm);
207 return "mov";
208 }
209 Opcode::MOVK => "movk",
210 Opcode::MOVZ => {
211 let imm = if let Operand::ImmShift(imm, shift) = ins.operands[1] {
212 (imm as u64) << shift
213 } else {
214 unreachable!("movz operand is always ImmShift");
215 };
216 let imm = if let Operand::Register(size, _) = ins.operands[0] {
217 if size == SizeCode::W { imm as u32 as u64 } else { imm }
218 } else {
219 unreachable!("movz operand 0 is always Register");
220 };
221 push_operand(args, &ins.operands[0], ctx);
222 push_separator(args);
223 push_unsigned(args, imm);
224 return "mov";
225 }
226 Opcode::ADC => "adc",
227 Opcode::ADCS => "adcs",
228 Opcode::SBC => {
229 if let Operand::Register(_, 31) = ins.operands[1] {
230 push_operand(args, &ins.operands[0], ctx);
231 push_separator(args);
232 push_operand(args, &ins.operands[2], ctx);
233 return "ngc";
234 } else {
235 "sbc"
236 }
237 }
238 Opcode::SBCS => {
239 if let Operand::Register(_, 31) = ins.operands[1] {
240 push_operand(args, &ins.operands[0], ctx);
241 push_separator(args);
242 push_operand(args, &ins.operands[2], ctx);
243 return "ngcs";
244 } else {
245 "sbcs"
246 }
247 }
248 Opcode::AND => "and",
249 Opcode::ORR => {
250 if let Operand::Register(_, 31) = ins.operands[1] {
251 if let Operand::Immediate(0) = ins.operands[2] {
252 push_operand(args, &ins.operands[0], ctx);
253 push_separator(args);
254 push_operand(args, &ins.operands[1], ctx);
255 return "mov";
256 } else if let Operand::RegShift(style, amt, size, r) = ins.operands[2] {
257 if style == ShiftStyle::LSL && amt == 0 {
258 push_operand(args, &ins.operands[0], ctx);
259 push_separator(args);
260 push_register(args, size, r, false);
261 return "mov";
262 }
263 } else {
264 push_operand(args, &ins.operands[0], ctx);
265 push_separator(args);
266 push_operand(args, &ins.operands[2], ctx);
267 return "mov";
268 }
269 } else if ins.operands[1] == ins.operands[2] {
270 push_operand(args, &ins.operands[0], ctx);
271 push_separator(args);
272 push_operand(args, &ins.operands[1], ctx);
273 return "mov";
274 }
275 "orr"
276 }
277 Opcode::ORN => {
278 if let Operand::Register(_, 31) = ins.operands[1] {
279 push_operand(args, &ins.operands[0], ctx);
280 push_separator(args);
281 push_operand(args, &ins.operands[2], ctx);
282 return "mvn";
283 }
284 "orn"
285 }
286 Opcode::EOR => "eor",
287 Opcode::EON => "eon",
288 Opcode::BIC => "bic",
289 Opcode::BICS => "bics",
290 Opcode::ANDS => {
291 if let Operand::Register(_, 31) = ins.operands[0] {
292 push_operand(args, &ins.operands[1], ctx);
293 push_separator(args);
294 push_operand(args, &ins.operands[2], ctx);
295 return "tst";
296 }
297 "ands"
298 }
299 Opcode::ADDS => {
300 if let Operand::Register(_, 31) = ins.operands[0] {
301 push_operand(args, &ins.operands[1], ctx);
302 push_separator(args);
303 push_operand(args, &ins.operands[2], ctx);
304 return "cmn";
305 } else if let Operand::RegShift(ShiftStyle::LSL, 0, size, reg) = ins.operands[2] {
306 push_operand(args, &ins.operands[0], ctx);
307 push_separator(args);
308 push_operand(args, &ins.operands[1], ctx);
309 push_separator(args);
310 push_register(args, size, reg, false);
311 return "adds";
312 }
313 "adds"
314 }
315 Opcode::ADD => {
316 if let Operand::Immediate(0) = ins.operands[2] {
317 if let Operand::RegisterOrSP(size, 31) = ins.operands[0] {
318 push_register(args, size, 31, true);
319 push_separator(args);
320 push_operand(args, &ins.operands[1], ctx);
321 return "mov";
322 } else if let Operand::RegisterOrSP(size, 31) = ins.operands[1] {
323 push_operand(args, &ins.operands[0], ctx);
324 push_separator(args);
325 push_register(args, size, 31, true);
326 return "mov";
327 }
328 } else if let Operand::RegShift(ShiftStyle::LSL, 0, size, reg) = ins.operands[2] {
329 push_operand(args, &ins.operands[0], ctx);
330 push_separator(args);
331 push_operand(args, &ins.operands[1], ctx);
332 push_separator(args);
333 push_register(args, size, reg, false);
334 return "add";
335 }
336 "add"
337 }
338 Opcode::SUBS => {
339 if let Operand::Register(_, 31) = ins.operands[0] {
340 push_operand(args, &ins.operands[1], ctx);
341 push_separator(args);
342 push_operand(args, &ins.operands[2], ctx);
343 return "cmp";
344 } else if let Operand::Register(_, 31) = ins.operands[1] {
345 push_operand(args, &ins.operands[0], ctx);
346 push_separator(args);
347 push_operand(args, &ins.operands[2], ctx);
348 return "negs";
349 } else if let Operand::RegShift(ShiftStyle::LSL, 0, size, reg) = ins.operands[2] {
350 push_operand(args, &ins.operands[0], ctx);
351 push_separator(args);
352 push_operand(args, &ins.operands[1], ctx);
353 push_separator(args);
354 push_register(args, size, reg, false);
355 return "subs";
356 }
357 "subs"
358 }
359 Opcode::SUB => {
360 if let Operand::Register(_, 31) = ins.operands[1] {
361 push_operand(args, &ins.operands[0], ctx);
362 push_separator(args);
363 push_operand(args, &ins.operands[2], ctx);
364 return "neg";
365 } else if let Operand::RegShift(ShiftStyle::LSL, 0, size, reg) = ins.operands[2] {
366 push_operand(args, &ins.operands[0], ctx);
367 push_separator(args);
368 push_operand(args, &ins.operands[1], ctx);
369 push_separator(args);
370 push_register(args, size, reg, false);
371 return "sub";
372 }
373 "sub"
374 }
375 Opcode::BFM => {
376 if let (Operand::Immediate(immr), Operand::Immediate(imms)) =
377 (ins.operands[2], ins.operands[3])
378 {
379 if imms < immr {
380 if let Operand::Register(sz, rn) = ins.operands[1] {
381 let width = imms + 1;
382 let lsb = if sz == SizeCode::W {
383 ((-(immr as i8)) as u8) & 0x1f
384 } else {
385 ((-(immr as i8)) as u8) & 0x3f
386 };
387 return if rn == 31 {
388 push_operand(args, &ins.operands[0], ctx);
389 push_separator(args);
390 push_unsigned(args, lsb as u64);
391 push_separator(args);
392 push_unsigned(args, width as u64);
393 "bfc"
394 } else {
395 push_operand(args, &ins.operands[0], ctx);
396 push_separator(args);
397 push_operand(args, &ins.operands[1], ctx);
398 push_separator(args);
399 push_unsigned(args, lsb as u64);
400 push_separator(args);
401 push_unsigned(args, width as u64);
402 "bfi"
403 };
404 }
405 } else {
406 let lsb = immr;
408 let width = imms + 1 - lsb;
409 push_operand(args, &ins.operands[0], ctx);
410 push_separator(args);
411 push_operand(args, &ins.operands[1], ctx);
412 push_separator(args);
413 push_unsigned(args, lsb as u64);
414 push_separator(args);
415 push_unsigned(args, width as u64);
416 return "bfxil";
417 }
418 }
419 "bfm"
420 }
421 Opcode::UBFM => {
422 if let (
424 Operand::Register(SizeCode::W, _),
425 Operand::Register(SizeCode::W, _),
426 Operand::Immediate(0),
427 ) = (ins.operands[0], ins.operands[1], ins.operands[2])
428 {
429 if let Operand::Immediate(7) = ins.operands[3] {
430 push_operand(args, &ins.operands[0], ctx);
431 push_separator(args);
432 push_operand(args, &ins.operands[1], ctx);
433 return "uxtb";
434 } else if let Operand::Immediate(15) = ins.operands[3] {
435 push_operand(args, &ins.operands[0], ctx);
436 push_separator(args);
437 push_operand(args, &ins.operands[1], ctx);
438 return "uxth";
439 }
440 }
441 if let Operand::Immediate(imms) = ins.operands[3] {
442 let size = if let Operand::Register(size, _) = ins.operands[0] {
443 size
444 } else {
445 unreachable!("operand 0 is a register");
446 };
447 match (imms, size) {
448 (63, SizeCode::X) | (31, SizeCode::W) => {
449 push_operand(args, &ins.operands[0], ctx);
450 push_separator(args);
451 push_operand(args, &ins.operands[1], ctx);
452 push_separator(args);
453 push_operand(args, &ins.operands[2], ctx);
454 return "lsr";
455 }
456 _ => {
457 let size = if size == SizeCode::X { 64 } else { 32 };
458 let immr = if let Operand::Immediate(immr) = ins.operands[2] {
459 immr
460 } else {
461 unreachable!("operand 3 is a register");
462 };
463 if imms + 1 == immr {
464 push_operand(args, &ins.operands[0], ctx);
465 push_separator(args);
466 push_operand(args, &ins.operands[1], ctx);
467 push_separator(args);
468 push_unsigned(args, (size - imms - 1) as u64);
469 return "lsl";
470 }
471 if imms < immr {
472 push_operand(args, &ins.operands[0], ctx);
473 push_separator(args);
474 push_operand(args, &ins.operands[1], ctx);
475 push_separator(args);
476 push_unsigned(args, (size - immr) as u64);
477 push_separator(args);
478 push_unsigned(args, (imms + 1) as u64);
479 return "ubfiz";
480 }
481 }
482 }
483 }
484 let width = if let (Operand::Immediate(lsb), Operand::Immediate(width)) =
486 (ins.operands[2], ins.operands[3])
487 {
488 Operand::Immediate(width - lsb + 1)
489 } else {
490 unreachable!("last two operands of ubfm are always immediates");
491 };
492 push_operand(args, &ins.operands[0], ctx);
493 push_separator(args);
494 push_operand(args, &ins.operands[1], ctx);
495 push_separator(args);
496 push_operand(args, &ins.operands[2], ctx);
497 push_separator(args);
498 push_operand(args, &width, ctx);
499 return "ubfx";
500 }
501 Opcode::SBFM => {
502 if let Operand::Immediate(63) = ins.operands[3]
503 && let Operand::Register(SizeCode::X, _) = ins.operands[0]
504 {
505 push_operand(args, &ins.operands[0], ctx);
506 push_separator(args);
507 push_operand(args, &ins.operands[1], ctx);
508 push_separator(args);
509 push_operand(args, &ins.operands[2], ctx);
510 return "asr";
511 }
512 if let Operand::Immediate(31) = ins.operands[3]
513 && let Operand::Register(SizeCode::W, _) = ins.operands[0]
514 {
515 push_operand(args, &ins.operands[0], ctx);
516 push_separator(args);
517 push_operand(args, &ins.operands[1], ctx);
518 push_separator(args);
519 push_operand(args, &ins.operands[2], ctx);
520 return "asr";
521 }
522 if let Operand::Immediate(0) = ins.operands[2] {
523 let newsrc = if let Operand::Register(_size, srcnum) = ins.operands[1] {
524 Operand::Register(SizeCode::W, srcnum)
525 } else {
526 unreachable!("operand 1 is always a register");
527 };
528 if let Operand::Immediate(7) = ins.operands[3] {
529 push_operand(args, &ins.operands[0], ctx);
530 push_separator(args);
531 push_operand(args, &newsrc, ctx);
532 return "sxtb";
533 } else if let Operand::Immediate(15) = ins.operands[3] {
534 push_operand(args, &ins.operands[0], ctx);
535 push_separator(args);
536 push_operand(args, &newsrc, ctx);
537 return "sxth";
538 } else if let Operand::Immediate(31) = ins.operands[3] {
539 push_operand(args, &ins.operands[0], ctx);
540 push_separator(args);
541 push_operand(args, &newsrc, ctx);
542 return "sxtw";
543 }
544 }
545 if let (Operand::Immediate(imms), Operand::Immediate(immr)) =
546 (ins.operands[2], ins.operands[3])
547 && immr < imms
548 {
549 let size = if let Operand::Register(size, _) = ins.operands[0] {
550 if size == SizeCode::W { 32 } else { 64 }
551 } else {
552 unreachable!("operand 0 is always a register");
553 };
554 push_operand(args, &ins.operands[0], ctx);
555 push_separator(args);
556 push_operand(args, &ins.operands[1], ctx);
557 push_separator(args);
558 push_unsigned(args, (size - imms) as u64);
559 push_separator(args);
560 push_unsigned(args, (immr + 1) as u64);
561 return "sbfiz";
562 }
563 let width = if let (Operand::Immediate(lsb), Operand::Immediate(width)) =
565 (ins.operands[2], ins.operands[3])
566 {
567 Operand::Immediate(width - lsb + 1)
568 } else {
569 unreachable!("last two operands of sbfm are always immediates");
570 };
571 push_operand(args, &ins.operands[0], ctx);
572 push_separator(args);
573 push_operand(args, &ins.operands[1], ctx);
574 push_separator(args);
575 push_operand(args, &ins.operands[2], ctx);
576 push_separator(args);
577 push_operand(args, &width, ctx);
578 return "sbfx";
579 }
580 Opcode::ADR => "adr",
581 Opcode::ADRP => "adrp",
582 Opcode::EXTR => {
583 if let (Operand::Register(_, rn), Operand::Register(_, rm)) =
584 (ins.operands[1], ins.operands[2])
585 && rn == rm
586 {
587 push_operand(args, &ins.operands[0], ctx);
588 push_separator(args);
589 push_operand(args, &ins.operands[2], ctx);
590 push_separator(args);
591 push_operand(args, &ins.operands[3], ctx);
592 return "ror";
593 }
594 "extr"
595 }
596 Opcode::LDAR => "ldar",
597 Opcode::LDLAR => "ldlar",
598 Opcode::LDARB => "ldarb",
599 Opcode::LDLARB => "ldlarb",
600 Opcode::LDAXRB => "ldaxrb",
601 Opcode::LDARH => "ldarh",
602 Opcode::LDLARH => "ldlarh",
603 Opcode::LDAXP => "ldaxp",
604 Opcode::LDAXR => "ldaxr",
605 Opcode::LDAXRH => "ldaxrh",
606 Opcode::LDP => "ldp",
607 Opcode::LDPSW => "ldpsw",
608 Opcode::LDR => "ldr",
609 Opcode::LDRB => "ldrb",
610 Opcode::LDRSB => "ldrsb",
611 Opcode::LDRSW => "ldrsw",
612 Opcode::LDRSH => "ldrsh",
613 Opcode::LDRH => "ldrh",
614 Opcode::LDTR => "ldtr",
615 Opcode::LDTRB => "ldtrb",
616 Opcode::LDTRH => "ldtrh",
617 Opcode::LDTRSB => "ldtrsb",
618 Opcode::LDTRSH => "ldtrsh",
619 Opcode::LDTRSW => "ldtrsw",
620 Opcode::LDUR => "ldur",
621 Opcode::LDURB => "ldurb",
622 Opcode::LDURSB => "ldursb",
623 Opcode::LDURSW => "ldursw",
624 Opcode::LDURSH => "ldursh",
625 Opcode::LDURH => "ldurh",
626 Opcode::LDXP => "ldxp",
627 Opcode::LDXR => "ldxr",
628 Opcode::LDXRB => "ldxrb",
629 Opcode::LDXRH => "ldxrh",
630 Opcode::STLR => "stlr",
631 Opcode::STLRB => "stlrb",
632 Opcode::STLRH => "stlrh",
633 Opcode::STLXP => "stlxp",
634 Opcode::STLLRB => "stllrb",
635 Opcode::STLLRH => "stllrh",
636 Opcode::STLLR => "stllr",
637 Opcode::STLXR => "stlxr",
638 Opcode::STLXRB => "stlxrb",
639 Opcode::STLXRH => "stlxrh",
640 Opcode::STP => "stp",
641 Opcode::STR => "str",
642 Opcode::STTR => "sttr",
643 Opcode::STTRB => "sttrb",
644 Opcode::STTRH => "sttrh",
645 Opcode::STRB => "strb",
646 Opcode::STRH => "strh",
647 Opcode::STRW => "strw",
648 Opcode::STUR => "stur",
649 Opcode::STURB => "sturb",
650 Opcode::STURH => "sturh",
651 Opcode::STXP => "stxp",
652 Opcode::STXR => "stxr",
653 Opcode::STXRB => "stxrb",
654 Opcode::STXRH => "stxrh",
655 Opcode::TBZ => "tbz",
656 Opcode::TBNZ => "tbnz",
657 Opcode::CBZ => "cbz",
658 Opcode::CBNZ => "cbnz",
659 Opcode::B => "b",
660 Opcode::BR => "br",
661 Opcode::Bcc(cond) => match cond {
662 0b0000 => "b.eq",
663 0b0001 => "b.ne",
664 0b0010 => "b.hs",
665 0b0011 => "b.lo",
666 0b0100 => "b.mi",
667 0b0101 => "b.pl",
668 0b0110 => "b.vs",
669 0b0111 => "b.vc",
670 0b1000 => "b.hi",
671 0b1001 => "b.ls",
672 0b1010 => "b.ge",
673 0b1011 => "b.lt",
674 0b1100 => "b.gt",
675 0b1101 => "b.le",
676 0b1110 => "b.al",
677 0b1111 => "b.nv",
678 _ => return "<invalid>",
679 },
680 Opcode::BL => "bl",
681 Opcode::BLR => "blr",
682 Opcode::SVC => "svc",
683 Opcode::HVC => "hvc",
684 Opcode::SMC => "smc",
685 Opcode::BRK => "brk",
686 Opcode::HLT => "hlt",
687 Opcode::DCPS1 => "dcps1",
688 Opcode::DCPS2 => "dcps2",
689 Opcode::DCPS3 => "dcps3",
690 Opcode::RET => {
691 if let Operand::Register(SizeCode::X, 30) = ins.operands[0] {
692 return "ret";
694 }
695 "ret"
696 }
697 Opcode::ERET => "eret",
698 Opcode::DRPS => "drps",
699 Opcode::MSR => "msr",
700 Opcode::MRS => "mrs",
701 Opcode::SYS(ops) => {
702 push_unsigned(args, ops.op1() as u64);
703 push_separator(args);
704 push_operand(args, &ins.operands[1], ctx);
705 push_separator(args);
706 push_operand(args, &ins.operands[2], ctx);
707 push_separator(args);
708 push_unsigned(args, ops.op2() as u64);
709 push_separator(args);
710 push_operand(args, &ins.operands[0], ctx);
711 return "sys";
712 }
713 Opcode::SYSL(ops) => {
714 push_operand(args, &ins.operands[2], ctx);
715 push_separator(args);
716 push_unsigned(args, ops.op1() as u64);
717 push_separator(args);
718 push_operand(args, &ins.operands[0], ctx);
719 push_separator(args);
720 push_operand(args, &ins.operands[1], ctx);
721 push_separator(args);
722 push_unsigned(args, ops.op2() as u64);
723 return "sysl";
724 }
725 Opcode::ISB => {
726 if let Operand::Imm16(15) = ins.operands[0] {
728 return "isb";
729 }
730 "isb"
731 }
732 Opcode::DSB(option) => {
733 push_barrier(args, option);
734 return "dsb";
735 }
736 Opcode::DMB(option) => {
737 push_barrier(args, option);
738 return "dmb";
739 }
740 Opcode::SB => "sb",
741 Opcode::SSSB => "sssb",
742 Opcode::HINT => {
743 if let (Operand::ControlReg(crn), Operand::Immediate(op2)) =
744 (ins.operands[0], ins.operands[1])
745 {
746 let hint_num = (crn << 3) | op2 as u16;
747 return match hint_num & 0b111111 {
748 0 => "nop",
749 1 => "yield",
750 2 => "wfe",
751 3 => "wfi",
752 4 => "sev",
753 0x10 => "esb",
754 0x11 => {
755 push_opaque(args, "csync");
756 "psb"
757 }
758 0x12 => {
759 push_opaque(args, "csync");
760 "tsb"
761 }
762 0x14 => "csdb",
763 0x15 => "sevl",
764 _ => {
765 push_unsigned(args, hint_num as u64);
766 "hint"
767 }
768 };
769 }
770 "hint"
771 }
772 Opcode::CLREX => "clrex",
773 Opcode::CSEL => "csel",
774 Opcode::CSNEG => {
775 if let (
776 Operand::Register(_size, rn),
777 Operand::Register(_, rm),
778 Operand::ConditionCode(cond),
779 ) = (ins.operands[1], ins.operands[2], ins.operands[3])
780 {
781 if cond < 0b1110 && rn == rm {
782 push_operand(args, &ins.operands[0], ctx);
783 push_separator(args);
784 push_operand(args, &ins.operands[2], ctx);
785 push_separator(args);
786 push_condition_code(args, cond ^ 0x01);
787 return "cneg";
788 }
789 } else {
790 unreachable!("operands 2 and 3 are always registers");
791 }
792 "csneg"
793 }
794 Opcode::CSINC => {
795 if let (Operand::Register(_, n), Operand::Register(_, m), Operand::ConditionCode(cond)) =
796 (ins.operands[1], ins.operands[2], ins.operands[3])
797 && n == m
798 && cond < 0b1110
799 {
800 return if n == 31 {
801 push_operand(args, &ins.operands[0], ctx);
802 push_separator(args);
803 push_condition_code(args, cond ^ 0x01);
804 "cset"
805 } else {
806 push_operand(args, &ins.operands[0], ctx);
807 push_separator(args);
808 push_operand(args, &ins.operands[1], ctx);
809 push_separator(args);
810 push_condition_code(args, cond ^ 0x01);
811 "cinc"
812 };
813 }
814 "csinc"
815 }
816 Opcode::CSINV => {
817 if let (
818 Operand::Register(_, n),
819 Operand::Register(_, m),
820 Operand::ConditionCode(cond),
821 ) = (ins.operands[1], ins.operands[2], ins.operands[3])
822 {
823 if n == m && n != 31 && cond < 0b1110 {
824 push_operand(args, &ins.operands[0], ctx);
825 push_separator(args);
826 push_operand(args, &ins.operands[1], ctx);
827 push_separator(args);
828 push_condition_code(args, cond ^ 0x01);
829 return "cinv";
830 } else if n == m && n == 31 && cond < 0b1110 {
831 push_operand(args, &ins.operands[0], ctx);
832 push_separator(args);
833 push_condition_code(args, cond ^ 0x01);
834 return "csetm";
835 }
836 }
837 "csinv"
838 }
839 Opcode::CCMN => "ccmn",
840 Opcode::CCMP => "ccmp",
841 Opcode::RBIT => "rbit",
842 Opcode::REV16 => "rev16",
843 Opcode::REV => "rev",
844 Opcode::REV32 => "rev32",
845 Opcode::CLZ => "clz",
846 Opcode::CLS => "cls",
847 Opcode::MADD => {
848 if let Operand::Register(_, 31) = ins.operands[3] {
849 push_operand(args, &ins.operands[0], ctx);
850 push_separator(args);
851 push_operand(args, &ins.operands[1], ctx);
852 push_separator(args);
853 push_operand(args, &ins.operands[2], ctx);
854 return "mul";
855 }
856 "madd"
857 }
858 Opcode::MSUB => {
859 if let Operand::Register(_, 31) = ins.operands[3] {
860 push_operand(args, &ins.operands[0], ctx);
861 push_separator(args);
862 push_operand(args, &ins.operands[1], ctx);
863 push_separator(args);
864 push_operand(args, &ins.operands[2], ctx);
865 return "mneg";
866 }
867 "msub"
868 }
869 Opcode::SMADDL => {
870 if let Operand::Register(_, 31) = ins.operands[3] {
871 push_operand(args, &ins.operands[0], ctx);
872 push_separator(args);
873 push_operand(args, &ins.operands[1], ctx);
874 push_separator(args);
875 push_operand(args, &ins.operands[2], ctx);
876 return "smull";
877 }
878 "smaddl"
879 }
880 Opcode::SMSUBL => {
881 if let Operand::Register(_, 31) = ins.operands[3] {
882 push_operand(args, &ins.operands[0], ctx);
883 push_separator(args);
884 push_operand(args, &ins.operands[1], ctx);
885 push_separator(args);
886 push_operand(args, &ins.operands[2], ctx);
887 return "smnegl";
888 }
889 "smsubl"
890 }
891 Opcode::SMULH => "smulh",
892 Opcode::UMADDL => {
893 if let Operand::Register(_, 31) = ins.operands[3] {
894 push_operand(args, &ins.operands[0], ctx);
895 push_separator(args);
896 push_operand(args, &ins.operands[1], ctx);
897 push_separator(args);
898 push_operand(args, &ins.operands[2], ctx);
899 return "umull";
900 }
901 "umaddl"
902 }
903 Opcode::UMSUBL => {
904 if let Operand::Register(_, 31) = ins.operands[3] {
905 push_operand(args, &ins.operands[0], ctx);
906 push_separator(args);
907 push_operand(args, &ins.operands[1], ctx);
908 push_separator(args);
909 push_operand(args, &ins.operands[2], ctx);
910 return "umnegl";
911 }
912 "umsubl"
913 }
914 Opcode::UMULH => "umulh",
915 Opcode::UDIV => "udiv",
916 Opcode::SDIV => "sdiv",
917 Opcode::LSLV => "lsl",
919 Opcode::LSRV => "lsr",
921 Opcode::ASRV => "asr",
923 Opcode::RORV => "ror",
925 Opcode::CRC32B => "crc32b",
926 Opcode::CRC32H => "crc32h",
927 Opcode::CRC32W => "crc32w",
928 Opcode::CRC32X => "crc32x",
929 Opcode::CRC32CB => "crc32cb",
930 Opcode::CRC32CH => "crc32ch",
931 Opcode::CRC32CW => "crc32cw",
932 Opcode::CRC32CX => "crc32cx",
933 Opcode::STNP => "stnp",
934 Opcode::LDNP => "ldnp",
935 Opcode::ST1 => "st1",
936 Opcode::ST2 => "st2",
937 Opcode::ST3 => "st3",
938 Opcode::ST4 => "st4",
939 Opcode::LD1 => "ld1",
940 Opcode::LD2 => "ld2",
941 Opcode::LD3 => "ld3",
942 Opcode::LD4 => "ld4",
943 Opcode::LD1R => "ld1r",
944 Opcode::LD2R => "ld2r",
945 Opcode::LD3R => "ld3r",
946 Opcode::LD4R => "ld4r",
947 Opcode::FMADD => "fmadd",
948 Opcode::FMSUB => "fmsub",
949 Opcode::FNMADD => "fnmadd",
950 Opcode::FNMSUB => "fnmsub",
951 Opcode::SCVTF => "scvtf",
952 Opcode::UCVTF => "ucvtf",
953 Opcode::FCVTZS => "fcvtzs",
954 Opcode::FCVTZU => "fcvtzu",
955 Opcode::FMOV => "fmov",
956 Opcode::FABS => "fabs",
957 Opcode::FNEG => "fneg",
958 Opcode::FSQRT => "fsqrt",
959 Opcode::FRINTN => "frintn",
960 Opcode::FRINTP => "frintp",
961 Opcode::FRINTM => "frintm",
962 Opcode::FRINTZ => "frintz",
963 Opcode::FRINTA => "frinta",
964 Opcode::FRINTX => "frintx",
965 Opcode::FRINTI => "frinti",
966 Opcode::FRINT32Z => "frint32z",
967 Opcode::FRINT32X => "frint32x",
968 Opcode::FRINT64Z => "frint64z",
969 Opcode::FRINT64X => "frint64x",
970 Opcode::BFCVT => "bfcvt",
971 Opcode::FCVT => "fcvt",
972 Opcode::FCMP => "fcmp",
973 Opcode::FCMPE => "fcmpe",
974 Opcode::FMUL => "fmul",
975 Opcode::FDIV => "fdiv",
976 Opcode::FADD => "fadd",
977 Opcode::FSUB => "fsub",
978 Opcode::FMAX => "fmax",
979 Opcode::FMIN => "fmin",
980 Opcode::FMAXNM => "fmaxnm",
981 Opcode::FMINNM => "fminnm",
982 Opcode::FNMUL => "fnmul",
983 Opcode::FCSEL => "fcsel",
984 Opcode::FCCMP => "fccmp",
985 Opcode::FCCMPE => "fccmpe",
986 Opcode::FMULX => "fmulx",
987 Opcode::FMLSL => "fmlsl",
988 Opcode::FMLAL => "fmlal",
989 Opcode::SQRDMLSH => "sqrdmlsh",
990 Opcode::UDOT => "udot",
991 Opcode::SQRDMLAH => "sqrdmlah",
992 Opcode::UMULL => "umull",
993 Opcode::UMULL2 => "umull2",
994 Opcode::UMLSL => "umlsl",
995 Opcode::UMLSL2 => "umlsl2",
996 Opcode::MLS => "mls",
997 Opcode::UMLAL => "umlal",
998 Opcode::UMLAL2 => "umlal2",
999 Opcode::MLA => "mla",
1000 Opcode::SDOT => "sdot",
1001 Opcode::SQDMULH => "sqdmulh",
1002 Opcode::SQDMULL => "sqdmull",
1003 Opcode::SQDMULL2 => "sqdmull2",
1004 Opcode::SMULL => "smull",
1005 Opcode::SMULL2 => "smull2",
1006 Opcode::MUL => "mul",
1007 Opcode::SQDMLSL => "sqdmlsl",
1008 Opcode::SQDMLSL2 => "sqdmlsl2",
1009 Opcode::SMLSL => "smlsl",
1010 Opcode::SMLSL2 => "smlsl2",
1011 Opcode::SQDMLAL => "sqdmlal",
1012 Opcode::SQDMLAL2 => "sqdmlal2",
1013 Opcode::SMLAL => "smlal",
1014 Opcode::SMLAL2 => "smlal2",
1015 Opcode::SQRDMULH => "sqrdmulh",
1016 Opcode::FCMLA => "fcmla",
1017 Opcode::SSHR => "sshr",
1018 Opcode::SSRA => "ssra",
1019 Opcode::SRSHR => "srshr",
1020 Opcode::SRSRA => "srsra",
1021 Opcode::SHL => "shl",
1022 Opcode::SQSHL => "sqshl",
1023 Opcode::SHRN => "shrn",
1024 Opcode::SHRN2 => "shrn2",
1025 Opcode::RSHRN => "rshrn",
1026 Opcode::SQSHRN => "sqshrn",
1027 Opcode::SQRSHRN => "sqrshrn",
1028 Opcode::SSHLL => "sshll",
1029 Opcode::USHLL => "ushll",
1030 Opcode::USHR => "ushr",
1031 Opcode::USRA => "usra",
1032 Opcode::URSHR => "urshr",
1033 Opcode::URSRA => "ursra",
1034 Opcode::SRI => "sri",
1035 Opcode::SLI => "sli",
1036 Opcode::SQSHLU => "sqshlu",
1037 Opcode::UQSHL => "uqshl",
1038 Opcode::SQSHRUN => "sqshrun",
1039 Opcode::SQRSHRUN => "sqrshrun",
1040 Opcode::UQSHRN => "uqshrn",
1041 Opcode::UQRSHRN => "uqrshrn",
1042 Opcode::MOVI => "movi",
1043 Opcode::MVNI => "mvni",
1044 Opcode::SHADD => "shadd",
1045 Opcode::SQADD => "sqadd",
1046 Opcode::SRHADD => "srhadd",
1047 Opcode::SHSUB => "shsub",
1048 Opcode::SQSUB => "sqsub",
1049 Opcode::CMGT => "cmgt",
1050 Opcode::CMGE => "cmge",
1051 Opcode::SSHL => "sshl",
1052 Opcode::SRSHL => "srshl",
1053 Opcode::SQRSHL => "sqrshl",
1054 Opcode::SMAX => "smax",
1055 Opcode::SMIN => "smin",
1056 Opcode::SABD => "sabd",
1057 Opcode::SABA => "saba",
1058 Opcode::CMTST => "cmtst",
1059 Opcode::SMAXP => "smaxp",
1060 Opcode::SMINP => "sminp",
1061 Opcode::ADDP => "addp",
1062 Opcode::UHADD => "uhadd",
1063 Opcode::UQADD => "uqadd",
1064 Opcode::URHADD => "urhadd",
1065 Opcode::UHSUB => "uhsub",
1066 Opcode::UQSUB => "uqsub",
1067 Opcode::CMHI => "cmhi",
1068 Opcode::CMHS => "cmhs",
1069 Opcode::USHL => "ushl",
1070 Opcode::URSHL => "urshl",
1071 Opcode::UQRSHL => "uqrshl",
1072 Opcode::UMAX => "umax",
1073 Opcode::UMIN => "umin",
1074 Opcode::UABD => "uabd",
1075 Opcode::UABA => "uaba",
1076 Opcode::CMEQ => "cmeq",
1077 Opcode::PMUL => "pmul",
1078 Opcode::UMAXP => "umaxp",
1079 Opcode::UMINP => "uminp",
1080 Opcode::FMLA => "fmla",
1081 Opcode::FCMEQ => "fcmeq",
1082 Opcode::FRECPS => "frecps",
1083 Opcode::BSL => "bsl",
1084 Opcode::BIT => "bit",
1085 Opcode::BIF => "bif",
1086 Opcode::FMAXNMP => "fmaxnmp",
1087 Opcode::FMINMNP => "fminmnp",
1088 Opcode::FADDP => "faddp",
1089 Opcode::FCMGE => "fcmge",
1090 Opcode::FACGE => "facge",
1091 Opcode::FMAXP => "fmaxp",
1092 Opcode::SADDL => "saddl",
1093 Opcode::SADDL2 => "saddl2",
1094 Opcode::SADDW => "saddw",
1095 Opcode::SADDW2 => "saddw2",
1096 Opcode::SSUBL => "ssubl",
1097 Opcode::SSUBL2 => "ssubl2",
1098 Opcode::SSUBW => "ssubw",
1099 Opcode::SSUBW2 => "ssubw2",
1100 Opcode::ADDHN => "addhn",
1101 Opcode::ADDHN2 => "addhn2",
1102 Opcode::SABAL => "sabal",
1103 Opcode::SABAL2 => "sabal2",
1104 Opcode::SUBHN => "subhn",
1105 Opcode::SUBHN2 => "subhn2",
1106 Opcode::SABDL => "sabdl",
1107 Opcode::SABDL2 => "sabdl2",
1108 Opcode::PMULL => "pmull",
1109 Opcode::PMULL2 => "pmull2",
1110 Opcode::UADDL => "uaddl",
1111 Opcode::UADDL2 => "uaddl2",
1112 Opcode::UADDW => "uaddw",
1113 Opcode::UADDW2 => "uaddw2",
1114 Opcode::USUBL => "usubl",
1115 Opcode::USUBL2 => "usubl2",
1116 Opcode::USUBW => "usubw",
1117 Opcode::USUBW2 => "usubw2",
1118 Opcode::RADDHN => "raddhn",
1119 Opcode::RADDHN2 => "raddhn2",
1120 Opcode::RSUBHN => "rsubhn",
1121 Opcode::RSUBHN2 => "rsubhn2",
1122 Opcode::UABAL => "uabal",
1123 Opcode::UABAL2 => "uabal2",
1124 Opcode::UABDL => "uabdl",
1125 Opcode::UABDL2 => "uabdl2",
1126 Opcode::REV64 => "rev64",
1127 Opcode::SADDLP => "saddlp",
1128 Opcode::SUQADD => "suqadd",
1129 Opcode::CNT => "cnt",
1130 Opcode::SADALP => "sadalp",
1131 Opcode::SQABS => "sqabs",
1132 Opcode::CMLT => "cmlt",
1133 Opcode::ABS => "abs",
1134 Opcode::XTN => "xtn",
1135 Opcode::XTN2 => "xtn2",
1136 Opcode::SQXTN => "sqxtn",
1137 Opcode::SQXTN2 => "sqxtn2",
1138 Opcode::FCVTN => "fcvtn",
1139 Opcode::FCVTN2 => "fcvtn2",
1140 Opcode::FCMGT => "fcmgt",
1141 Opcode::FCVTL => "fcvtl",
1142 Opcode::FCVTL2 => "fcvtl2",
1143 Opcode::FCVTNS => "fcvtns",
1144 Opcode::FCVTPS => "fcvtps",
1145 Opcode::FCVTMS => "fcvtms",
1146 Opcode::FCVTAS => "fcvtas",
1147 Opcode::URECPE => "urecpe",
1148 Opcode::FRECPE => "frecpe",
1149 Opcode::UADDLP => "uaddlp",
1150 Opcode::USQADD => "usqadd",
1151 Opcode::UADALP => "uadalp",
1152 Opcode::SQNEG => "sqneg",
1153 Opcode::CMLE => "cmle",
1154 Opcode::NEG => "neg",
1155 Opcode::SQXTUN => "sqxtun",
1156 Opcode::SQXTUN2 => "sqxtun2",
1157 Opcode::SHLL => "shll",
1158 Opcode::SHLL2 => "shll2",
1159 Opcode::UQXTN => "uqxtn",
1160 Opcode::UQXTN2 => "uqxtn2",
1161 Opcode::FCVTXN => "fcvtxn",
1162 Opcode::FCVTXN2 => "fcvtxn2",
1163 Opcode::FCVTNU => "fcvtnu",
1164 Opcode::FCVTMU => "fcvtmu",
1165 Opcode::FCVTAU => "fcvtau",
1166 Opcode::INS => "mov",
1168 Opcode::EXT => "ext",
1169 Opcode::DUP => {
1170 if let Operand::Register(_, _) = ins.operands[1] {
1171 "dup"
1172 } else {
1173 "mov"
1174 }
1175 }
1176 Opcode::UZP1 => "uzp1",
1177 Opcode::TRN1 => "trn1",
1178 Opcode::ZIP1 => "zip1",
1179 Opcode::UZP2 => "uzp2",
1180 Opcode::TRN2 => "trn2",
1181 Opcode::ZIP2 => "zip2",
1182 Opcode::SMOV => "smov",
1183 Opcode::UMOV => {
1184 if let (
1185 Operand::Register(reg_sz, _),
1186 Operand::SIMDRegisterElementsLane(_, _, elem_sz, _),
1187 ) = (ins.operands[0], ins.operands[1])
1188 && ((reg_sz == SizeCode::W && elem_sz == SIMDSizeCode::S)
1189 || (reg_sz == SizeCode::X && elem_sz == SIMDSizeCode::D))
1190 {
1191 push_operand(args, &ins.operands[0], ctx);
1192 push_separator(args);
1193 push_operand(args, &ins.operands[1], ctx);
1194 return "mov";
1195 }
1196 "umov"
1197 }
1198 Opcode::SQSHRN2 => "sqshrn2",
1199 Opcode::SQRSHRN2 => "sqrshrn2",
1200 Opcode::SQSHRUN2 => "sqshrun2",
1201 Opcode::UQSHRN2 => "uqshrn2",
1202 Opcode::UQRSHRN2 => "uqrshrn2",
1203 Opcode::FMLS => "fmls",
1204 Opcode::FRECPX => "frecpx",
1205 Opcode::FRSQRTE => "frsqrte",
1206 Opcode::FCVTPU => "fcvtpu",
1207 Opcode::FCMLT => "fcmlt",
1208 Opcode::FCMLE => "fcmle",
1209 Opcode::FMAXNMV => "fmaxnmv",
1210 Opcode::FMINNMV => "fminnmv",
1211 Opcode::FMAXV => "fmaxv",
1212 Opcode::FMINV => "fminv",
1213 Opcode::UADDLV => "uaddlv",
1214 Opcode::SADDLV => "saddlv",
1215 Opcode::UMAXV => "umaxv",
1216 Opcode::SMAXV => "smaxv",
1217 Opcode::UMINV => "uminv",
1218 Opcode::SMINV => "sminv",
1219 Opcode::ADDV => "addv",
1220 Opcode::FRSQRTS => "frsqrts",
1221 Opcode::FMINNMP => "fminnmp",
1222 Opcode::FMLAL2 => "fmlal2",
1223 Opcode::FMLSL2 => "fmlsl2",
1224 Opcode::FABD => "fabd",
1225 Opcode::FACGT => "facgt",
1226 Opcode::FMINP => "fminp",
1227 Opcode::FJCVTZS => "fjcvtzs",
1228 Opcode::URSQRTE => "ursqrte",
1229 Opcode::PRFM => "prfm",
1230 Opcode::PRFUM => "prfum",
1231 Opcode::AESE => "aese",
1232 Opcode::AESD => "aesd",
1233 Opcode::AESMC => "aesmc",
1234 Opcode::AESIMC => "aesimc",
1235 Opcode::SHA1H => "sha1h",
1236 Opcode::SHA1SU1 => "sha1su1",
1237 Opcode::SHA256SU0 => "sha256su0",
1238 Opcode::SM3TT1A => "sm3tt1a",
1239 Opcode::SM3TT1B => "sm3tt1b",
1240 Opcode::SM3TT2A => "sm3tt2a",
1241 Opcode::SM3TT2B => "sm3tt2b",
1242 Opcode::SHA512H => "sha512h",
1243 Opcode::SHA512H2 => "sha512h2",
1244 Opcode::SHA512SU1 => "sha512su1",
1245 Opcode::RAX1 => "rax1",
1246 Opcode::SM3PARTW1 => "sm3partw1",
1247 Opcode::SM3PARTW2 => "sm3partw2",
1248 Opcode::SM4EKEY => "sm4ekey",
1249 Opcode::BCAX => "bcax",
1250 Opcode::SM3SS1 => "sm3ss1",
1251 Opcode::SHA512SU0 => "sha512su0",
1252 Opcode::SM4E => "sm4e",
1253 Opcode::EOR3 => "eor3",
1254 Opcode::XAR => "xar",
1255 Opcode::LDRAA => "ldraa",
1256 Opcode::LDRAB => "ldrab",
1257 Opcode::LDAPR => "ldapr",
1258 Opcode::LDAPRH => "ldaprh",
1259 Opcode::LDAPRB => "ldaprb",
1260 Opcode::SWP(ar) => {
1261 if ar == 0 {
1262 "swp"
1263 } else if ar == 0b01 {
1264 "swpl"
1265 } else if ar == 0b10 {
1266 "swpa"
1267 } else {
1268 "swpal"
1269 }
1270 }
1271 Opcode::SWPB(ar) => {
1272 if ar == 0 {
1273 "swpb"
1274 } else if ar == 0b01 {
1275 "swplb"
1276 } else if ar == 0b10 {
1277 "swpab"
1278 } else {
1279 "swpalb"
1280 }
1281 }
1282 Opcode::SWPH(ar) => {
1283 if ar == 0 {
1284 "swph"
1285 } else if ar == 0b01 {
1286 "swplh"
1287 } else if ar == 0b10 {
1288 "swpah"
1289 } else {
1290 "swpalh"
1291 }
1292 }
1293 Opcode::LDADDB(ar) => {
1294 if let Operand::Register(_, rt) = ins.operands[1]
1295 && rt == 31
1296 && ar & 0b10 == 0b00
1297 {
1298 let inst = if ar & 0b01 == 0b00 { "staddb" } else { "staddlb" };
1299 push_operand(args, &ins.operands[0], ctx);
1300 push_separator(args);
1301 push_operand(args, &ins.operands[2], ctx);
1302 return inst;
1303 }
1304 if ar == 0 {
1305 "ldaddb"
1306 } else if ar == 0b01 {
1307 "ldaddlb"
1308 } else if ar == 0b10 {
1309 "ldaddab"
1310 } else {
1311 "ldaddalb"
1312 }
1313 }
1314 Opcode::LDCLRB(ar) => {
1315 if let Operand::Register(_, rt) = ins.operands[1]
1316 && rt == 31
1317 && ar & 0b10 == 0b00
1318 {
1319 let inst = if ar & 0b01 == 0b00 { "stclrb" } else { "stclrlb" };
1320 push_operand(args, &ins.operands[0], ctx);
1321 push_separator(args);
1322 push_operand(args, &ins.operands[2], ctx);
1323 return inst;
1324 }
1325 if ar == 0 {
1326 "ldclrb"
1327 } else if ar == 0b01 {
1328 "ldclrlb"
1329 } else if ar == 0b10 {
1330 "ldclrab"
1331 } else {
1332 "ldclralb"
1333 }
1334 }
1335 Opcode::LDEORB(ar) => {
1336 if let Operand::Register(_, rt) = ins.operands[1]
1337 && rt == 31
1338 && ar & 0b10 == 0b00
1339 {
1340 let inst = if ar & 0b01 == 0b00 { "steorb" } else { "steorlb" };
1341 push_operand(args, &ins.operands[0], ctx);
1342 push_separator(args);
1343 push_operand(args, &ins.operands[2], ctx);
1344 return inst;
1345 }
1346 if ar == 0 {
1347 "ldeorb"
1348 } else if ar == 0b01 {
1349 "ldeorlb"
1350 } else if ar == 0b10 {
1351 "ldeorab"
1352 } else {
1353 "ldeoralb"
1354 }
1355 }
1356 Opcode::LDSETB(ar) => {
1357 if let Operand::Register(_, rt) = ins.operands[1]
1358 && rt == 31
1359 && ar & 0b10 == 0b00
1360 {
1361 let inst = if ar & 0b01 == 0b00 { "stsetb" } else { "stsetlb" };
1362 push_operand(args, &ins.operands[0], ctx);
1363 push_separator(args);
1364 push_operand(args, &ins.operands[2], ctx);
1365 return inst;
1366 }
1367 if ar == 0 {
1368 "ldsetb"
1369 } else if ar == 0b01 {
1370 "ldsetlb"
1371 } else if ar == 0b10 {
1372 "ldsetab"
1373 } else {
1374 "ldsetalb"
1375 }
1376 }
1377 Opcode::LDSMAXB(ar) => {
1378 if let Operand::Register(_, rt) = ins.operands[1]
1379 && rt == 31
1380 && ar & 0b10 == 0b00
1381 {
1382 let inst = if ar & 0b01 == 0b00 { "stsmaxb" } else { "stsmaxlb" };
1383 push_operand(args, &ins.operands[0], ctx);
1384 push_separator(args);
1385 push_operand(args, &ins.operands[2], ctx);
1386 return inst;
1387 }
1388 if ar == 0 {
1389 "ldsmaxb"
1390 } else if ar == 0b01 {
1391 "ldsmaxlb"
1392 } else if ar == 0b10 {
1393 "ldsmaxab"
1394 } else {
1395 "ldsmaxalb"
1396 }
1397 }
1398 Opcode::LDSMINB(ar) => {
1399 if let Operand::Register(_, rt) = ins.operands[1]
1400 && rt == 31
1401 && ar & 0b10 == 0b00
1402 {
1403 let inst = if ar & 0b01 == 0b00 { "stsminb" } else { "stsminlb" };
1404 push_operand(args, &ins.operands[0], ctx);
1405 push_separator(args);
1406 push_operand(args, &ins.operands[2], ctx);
1407 return inst;
1408 }
1409 if ar == 0 {
1410 "ldsminb"
1411 } else if ar == 0b01 {
1412 "ldsminlb"
1413 } else if ar == 0b10 {
1414 "ldsminab"
1415 } else {
1416 "ldsminalb"
1417 }
1418 }
1419 Opcode::LDUMAXB(ar) => {
1420 if let Operand::Register(_, rt) = ins.operands[1]
1421 && rt == 31
1422 && ar & 0b10 == 0b00
1423 {
1424 let inst = if ar & 0b01 == 0b00 { "stumaxb" } else { "stumaxlb" };
1425 push_operand(args, &ins.operands[0], ctx);
1426 push_separator(args);
1427 push_operand(args, &ins.operands[2], ctx);
1428 return inst;
1429 }
1430 if ar == 0 {
1431 "ldumaxb"
1432 } else if ar == 0b01 {
1433 "ldumaxlb"
1434 } else if ar == 0b10 {
1435 "ldumaxab"
1436 } else {
1437 "ldumaxalb"
1438 }
1439 }
1440 Opcode::LDUMINB(ar) => {
1441 if let Operand::Register(_, rt) = ins.operands[1]
1442 && rt == 31
1443 && ar & 0b10 == 0b00
1444 {
1445 let inst = if ar & 0b01 == 0b00 { "stuminb" } else { "stuminlb" };
1446 push_operand(args, &ins.operands[0], ctx);
1447 push_separator(args);
1448 push_operand(args, &ins.operands[2], ctx);
1449 return inst;
1450 }
1451 if ar == 0 {
1453 "lduminb"
1454 } else if ar == 0b01 {
1455 "lduminlb"
1456 } else if ar == 0b10 {
1457 "lduminab"
1458 } else {
1459 "lduminalb"
1460 }
1461 }
1462 Opcode::LDADDH(ar) => {
1463 if let Operand::Register(_, rt) = ins.operands[1]
1464 && rt == 31
1465 && ar & 0b10 == 0b00
1466 {
1467 let inst = if ar & 0b01 == 0b00 { "staddh" } else { "staddlh" };
1468 push_operand(args, &ins.operands[0], ctx);
1469 push_separator(args);
1470 push_operand(args, &ins.operands[2], ctx);
1471 return inst;
1472 }
1473 if ar == 0 {
1474 "ldaddh"
1475 } else if ar == 0b01 {
1476 "ldaddlh"
1477 } else if ar == 0b10 {
1478 "ldaddah"
1479 } else {
1480 "ldaddalh"
1481 }
1482 }
1483 Opcode::LDCLRH(ar) => {
1484 if let Operand::Register(_, rt) = ins.operands[1]
1485 && rt == 31
1486 && ar & 0b10 == 0b00
1487 {
1488 let inst = if ar & 0b01 == 0b00 { "stclrh" } else { "stclrlh" };
1489 push_operand(args, &ins.operands[0], ctx);
1490 push_separator(args);
1491 push_operand(args, &ins.operands[2], ctx);
1492 return inst;
1493 }
1494 if ar == 0 {
1495 "ldclrh"
1496 } else if ar == 0b01 {
1497 "ldclrlh"
1498 } else if ar == 0b10 {
1499 "ldclrah"
1500 } else {
1501 "ldclralh"
1502 }
1503 }
1504 Opcode::LDEORH(ar) => {
1505 if let Operand::Register(_, rt) = ins.operands[1]
1506 && rt == 31
1507 && ar & 0b10 == 0b00
1508 {
1509 let inst = if ar & 0b01 == 0b00 { "steorh" } else { "steorlh" };
1510 push_operand(args, &ins.operands[0], ctx);
1511 push_separator(args);
1512 push_operand(args, &ins.operands[2], ctx);
1513 return inst;
1514 }
1515 if ar == 0 {
1516 "ldeorh"
1517 } else if ar == 0b01 {
1518 "ldeorlh"
1519 } else if ar == 0b10 {
1520 "ldeorah"
1521 } else {
1522 "ldeoralh"
1523 }
1524 }
1525 Opcode::LDSETH(ar) => {
1526 if let Operand::Register(_, rt) = ins.operands[1]
1527 && rt == 31
1528 && ar & 0b10 == 0b00
1529 {
1530 let inst = if ar & 0b01 == 0b00 { "stseth" } else { "stsetlh" };
1531 push_operand(args, &ins.operands[0], ctx);
1532 push_separator(args);
1533 push_operand(args, &ins.operands[2], ctx);
1534 return inst;
1535 }
1536 if ar == 0 {
1537 "ldseth"
1538 } else if ar == 0b01 {
1539 "ldsetlh"
1540 } else if ar == 0b10 {
1541 "ldsetah"
1542 } else {
1543 "ldsetalh"
1544 }
1545 }
1546 Opcode::LDSMAXH(ar) => {
1547 if let Operand::Register(_, rt) = ins.operands[1]
1548 && rt == 31
1549 && ar & 0b10 == 0b00
1550 {
1551 let inst = if ar & 0b01 == 0b00 { "stsmaxh" } else { "stsmaxlh" };
1552 push_operand(args, &ins.operands[0], ctx);
1553 push_separator(args);
1554 push_operand(args, &ins.operands[2], ctx);
1555 return inst;
1556 }
1557 if ar == 0 {
1558 "ldsmaxh"
1559 } else if ar == 0b01 {
1560 "ldsmaxlh"
1561 } else if ar == 0b10 {
1562 "ldsmaxah"
1563 } else {
1564 "ldsmaxalh"
1565 }
1566 }
1567 Opcode::LDSMINH(ar) => {
1568 if let Operand::Register(_, rt) = ins.operands[1]
1569 && rt == 31
1570 && ar & 0b10 == 0b00
1571 {
1572 let inst = if ar & 0b01 == 0b00 { "stsminh" } else { "stsminlh" };
1573 push_operand(args, &ins.operands[0], ctx);
1574 push_separator(args);
1575 push_operand(args, &ins.operands[2], ctx);
1576 return inst;
1577 }
1578 if ar == 0 {
1579 "ldsminh"
1580 } else if ar == 0b01 {
1581 "ldsminlh"
1582 } else if ar == 0b10 {
1583 "ldsminah"
1584 } else {
1585 "ldsminalh"
1586 }
1587 }
1588 Opcode::LDUMAXH(ar) => {
1589 if let Operand::Register(_, rt) = ins.operands[1]
1590 && rt == 31
1591 && ar & 0b10 == 0b00
1592 {
1593 let inst = if ar & 0b01 == 0b00 { "stumaxh" } else { "stumaxlh" };
1594 push_operand(args, &ins.operands[0], ctx);
1595 push_separator(args);
1596 push_operand(args, &ins.operands[2], ctx);
1597 return inst;
1598 }
1599 if ar == 0 {
1600 "ldumaxh"
1601 } else if ar == 0b01 {
1602 "ldumaxlh"
1603 } else if ar == 0b10 {
1604 "ldumaxah"
1605 } else {
1606 "ldumaxalh"
1607 }
1608 }
1609 Opcode::LDUMINH(ar) => {
1610 if let Operand::Register(_, rt) = ins.operands[1]
1611 && rt == 31
1612 && ar & 0b10 == 0b00
1613 {
1614 let inst = if ar & 0b01 == 0b00 { "stuminh" } else { "stuminlh" };
1615 push_operand(args, &ins.operands[0], ctx);
1616 push_separator(args);
1617 push_operand(args, &ins.operands[2], ctx);
1618 return inst;
1619 }
1620 if ar == 0 {
1621 "lduminh"
1622 } else if ar == 0b01 {
1623 "lduminlh"
1624 } else if ar == 0b10 {
1625 "lduminah"
1626 } else {
1627 "lduminalh"
1628 }
1629 }
1630 Opcode::LDADD(ar) => {
1631 if let Operand::Register(_, rt) = ins.operands[1]
1632 && rt == 31
1633 && ar & 0b10 == 0b00
1634 {
1635 let inst = if ar & 0b01 == 0b00 { "stadd" } else { "staddl" };
1636 push_operand(args, &ins.operands[0], ctx);
1637 push_separator(args);
1638 push_operand(args, &ins.operands[2], ctx);
1639 return inst;
1640 }
1641 if ar == 0 {
1642 "ldadd"
1643 } else if ar == 0b01 {
1644 "ldaddl"
1645 } else if ar == 0b10 {
1646 "ldadda"
1647 } else {
1648 "ldaddal"
1649 }
1650 }
1651 Opcode::LDCLR(ar) => {
1652 if let Operand::Register(_, rt) = ins.operands[1]
1653 && rt == 31
1654 && ar & 0b10 == 0b00
1655 {
1656 let inst = if ar & 0b01 == 0b00 { "stclr" } else { "stclrl" };
1657 push_operand(args, &ins.operands[0], ctx);
1658 push_separator(args);
1659 push_operand(args, &ins.operands[2], ctx);
1660 return inst;
1661 }
1662 if ar == 0 {
1663 "ldclr"
1664 } else if ar == 0b01 {
1665 "ldclrl"
1666 } else if ar == 0b10 {
1667 "ldclra"
1668 } else {
1669 "ldclral"
1670 }
1671 }
1672 Opcode::LDEOR(ar) => {
1673 if let Operand::Register(_, rt) = ins.operands[1]
1674 && rt == 31
1675 && ar & 0b10 == 0b00
1676 {
1677 let inst = if ar & 0b01 == 0b00 { "steor" } else { "steorl" };
1678 push_operand(args, &ins.operands[0], ctx);
1679 push_separator(args);
1680 push_operand(args, &ins.operands[2], ctx);
1681 return inst;
1682 }
1683 if ar == 0 {
1684 "ldeor"
1685 } else if ar == 0b01 {
1686 "ldeorl"
1687 } else if ar == 0b10 {
1688 "ldeora"
1689 } else {
1690 "ldeoral"
1691 }
1692 }
1693 Opcode::LDSET(ar) => {
1694 if let Operand::Register(_, rt) = ins.operands[1]
1695 && rt == 31
1696 && ar & 0b10 == 0b00
1697 {
1698 let inst = if ar & 0b01 == 0b00 { "stset" } else { "stsetl" };
1699 push_operand(args, &ins.operands[0], ctx);
1700 push_separator(args);
1701 push_operand(args, &ins.operands[2], ctx);
1702 return inst;
1703 }
1704 if ar == 0 {
1705 "ldset"
1706 } else if ar == 0b01 {
1707 "ldsetl"
1708 } else if ar == 0b10 {
1709 "ldseta"
1710 } else {
1711 "ldsetal"
1712 }
1713 }
1714 Opcode::LDSMAX(ar) => {
1715 if let Operand::Register(_, rt) = ins.operands[1]
1716 && rt == 31
1717 && ar & 0b10 == 0b00
1718 {
1719 let inst = if ar & 0b01 == 0b00 { "stsmax" } else { "stsmaxl" };
1720 push_operand(args, &ins.operands[0], ctx);
1721 push_separator(args);
1722 push_operand(args, &ins.operands[2], ctx);
1723 return inst;
1724 }
1725 if ar == 0 {
1726 "ldsmax"
1727 } else if ar == 0b01 {
1728 "ldsmaxl"
1729 } else if ar == 0b10 {
1730 "ldsmaxa"
1731 } else {
1732 "ldsmaxal"
1733 }
1734 }
1735 Opcode::LDSMIN(ar) => {
1736 if let Operand::Register(_, rt) = ins.operands[1]
1737 && rt == 31
1738 && ar & 0b10 == 0b00
1739 {
1740 let inst = if ar & 0b01 == 0b00 { "stsmin" } else { "stsminl" };
1741 push_operand(args, &ins.operands[0], ctx);
1742 push_separator(args);
1743 push_operand(args, &ins.operands[2], ctx);
1744 return inst;
1745 }
1746 if ar == 0 {
1747 "ldsmin"
1748 } else if ar == 0b01 {
1749 "ldsminl"
1750 } else if ar == 0b10 {
1751 "ldsmina"
1752 } else {
1753 "ldsminal"
1754 }
1755 }
1756 Opcode::LDUMAX(ar) => {
1757 if let Operand::Register(_, rt) = ins.operands[1]
1758 && rt == 31
1759 && ar & 0b10 == 0b00
1760 {
1761 let inst = if ar & 0b01 == 0b00 { "stumax" } else { "stumaxl" };
1762 push_operand(args, &ins.operands[0], ctx);
1763 push_separator(args);
1764 push_operand(args, &ins.operands[2], ctx);
1765 return inst;
1766 }
1767 if ar == 0 {
1768 "ldumax"
1769 } else if ar == 0b01 {
1770 "ldumaxl"
1771 } else if ar == 0b10 {
1772 "ldumaxa"
1773 } else {
1774 "ldumaxal"
1775 }
1776 }
1777 Opcode::LDUMIN(ar) => {
1778 if let Operand::Register(_, rt) = ins.operands[1]
1779 && rt == 31
1780 && ar & 0b10 == 0b00
1781 {
1782 let inst = if ar & 0b01 == 0b00 { "stumin" } else { "stuminl" };
1783 push_operand(args, &ins.operands[0], ctx);
1784 push_separator(args);
1785 push_operand(args, &ins.operands[2], ctx);
1786 return inst;
1787 }
1788 if ar == 0 {
1789 "ldumin"
1790 } else if ar == 0b01 {
1791 "lduminl"
1792 } else if ar == 0b10 {
1793 "ldumina"
1794 } else {
1795 "lduminal"
1796 }
1797 }
1798 Opcode::CAS(ar) => {
1799 if ar == 0 {
1800 "cas"
1801 } else if ar == 0b01 {
1802 "casl"
1803 } else if ar == 0b10 {
1804 "casa"
1805 } else {
1806 "casal"
1807 }
1808 }
1809 Opcode::CASH(ar) => {
1810 if ar == 0 {
1811 "cash"
1812 } else if ar == 0b01 {
1813 "caslh"
1814 } else if ar == 0b10 {
1815 "casah"
1816 } else {
1817 "casalh"
1818 }
1819 }
1820 Opcode::CASB(ar) => {
1821 if ar == 0 {
1822 "casb"
1823 } else if ar == 0b01 {
1824 "caslb"
1825 } else if ar == 0b10 {
1826 "casab"
1827 } else {
1828 "casalb"
1829 }
1830 }
1831 Opcode::CASP(ar) => {
1832 if ar == 0 {
1833 "casp"
1834 } else if ar == 0b01 {
1835 "caspl"
1836 } else if ar == 0b10 {
1837 "caspa"
1838 } else {
1839 "caspal"
1840 }
1841 }
1842 Opcode::TBL => "tbl",
1843 Opcode::TBX => "tbx",
1844 Opcode::FCADD => "fcadd",
1845 Opcode::LDGM => "ldgm",
1846 Opcode::LDG => "ldm",
1847 Opcode::STGM => "stgm",
1848 Opcode::STZGM => "stzgm",
1849 Opcode::STG => "stg",
1850 Opcode::STZG => "stzg",
1851 Opcode::ST2G => "st2g",
1852 Opcode::STZ2G => "stz2g",
1853 Opcode::LDAPUR => "ldapur",
1854 Opcode::LDAPURB => "ldapurb",
1855 Opcode::LDAPURH => "ldapurh",
1856 Opcode::LDAPURSB => "ldapursb",
1857 Opcode::LDAPURSH => "ldapursh",
1858 Opcode::LDAPURSW => "ldapursw",
1859 Opcode::STLUR => "stlur",
1860 Opcode::STLURB => "stlurb",
1861 Opcode::STLURH => "stlurh",
1862 Opcode::SETF8 => "setf8",
1863 Opcode::SETF16 => "setf16",
1864 Opcode::RMIF => "rmif",
1865 Opcode::NOT => "mvn",
1867 Opcode::RSHRN2 => "rshrn2",
1868 Opcode::SQRSHRUN2 => "sqrshrun2",
1869 Opcode::USHLL2 => "ushll2",
1870 Opcode::SSHLL2 => "sshll2",
1871 Opcode::SHA1C => "sha1c",
1872 Opcode::SHA1P => "sha1p",
1873 Opcode::SHA1M => "sha1m",
1874 Opcode::SHA1SU0 => "sha1su0",
1875 Opcode::SHA256H => "sha256h",
1876 Opcode::SHA256H2 => "sha256h2",
1877 Opcode::SHA256SU1 => "sha256su1",
1878 Opcode::BLRAA => "blraa",
1879 Opcode::BLRAAZ => "blraaz",
1880 Opcode::BLRAB => "blrab",
1881 Opcode::BLRABZ => "blrabz",
1882 Opcode::BRAA => "braa",
1883 Opcode::BRAAZ => "braaz",
1884 Opcode::BRAB => "brab",
1885 Opcode::BRABZ => "brabz",
1886 Opcode::ERETAA => "eretaa",
1887 Opcode::ERETAB => "eretab",
1888 Opcode::RETAA => "retaa",
1889 Opcode::RETAB => "retab",
1890 Opcode::PACIA => "pacia",
1891 Opcode::PACIB => "pacib",
1892 Opcode::PACDA => "pacda",
1893 Opcode::PACDB => "pacdb",
1894 Opcode::AUTIA => "autia",
1895 Opcode::AUTIB => "autib",
1896 Opcode::AUTDA => "autda",
1897 Opcode::AUTDB => "autdb",
1898 Opcode::PACIZA => "paciza",
1899 Opcode::PACIZB => "pacizb",
1900 Opcode::PACDZA => "pacdza",
1901 Opcode::PACDZB => "pacdzb",
1902 Opcode::AUTIZA => "autiza",
1903 Opcode::AUTIZB => "autizb",
1904 Opcode::AUTDZA => "autdza",
1905 Opcode::AUTDZB => "autdzb",
1906 Opcode::XPACI => "xpaci",
1907 Opcode::XPACD => "xpacd",
1908 Opcode::PACGA => "pacga",
1909 Opcode::GMI => "gmi",
1910 Opcode::IRG => "irg",
1911 Opcode::SUBP => "subp",
1912 Opcode::SUBPS => "subps",
1913 };
1914
1915 for (i, o) in ins.operands.iter().enumerate() {
1917 if let Operand::Nothing = o {
1918 break;
1919 }
1920 if i > 0 {
1921 push_separator(args);
1922 }
1923 push_operand(args, o, ctx);
1924 }
1925 mnemonic
1926}
1927
1928const REG_NAMES_X: [&str; 31] = [
1929 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14",
1930 "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27",
1931 "x28", "x29", "x30",
1932];
1933
1934const REG_NAMES_W: [&str; 31] = [
1935 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14",
1936 "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", "w24", "w25", "w26", "w27",
1937 "w28", "w29", "w30",
1938];
1939
1940fn reg_name(size: SizeCode, reg: u16, sp: bool) -> &'static str {
1941 match reg.cmp(&31) {
1942 Ordering::Less => match size {
1943 SizeCode::X => REG_NAMES_X[reg as usize],
1944 SizeCode::W => REG_NAMES_W[reg as usize],
1945 },
1946 Ordering::Equal => {
1947 if sp {
1948 match size {
1949 SizeCode::X => "sp",
1950 SizeCode::W => "wsp",
1951 }
1952 } else {
1953 match size {
1954 SizeCode::X => "xzr",
1955 SizeCode::W => "wzr",
1956 }
1957 }
1958 }
1959 Ordering::Greater => "<invalid>",
1960 }
1961}
1962
1963fn shift_style(style: ShiftStyle) -> &'static str {
1964 match style {
1965 ShiftStyle::LSL => "lsl",
1966 ShiftStyle::LSR => "lsr",
1967 ShiftStyle::ASR => "asr",
1968 ShiftStyle::ROR => "ror",
1969 ShiftStyle::UXTB => "uxtb",
1970 ShiftStyle::UXTH => "uxth",
1971 ShiftStyle::UXTW => "uxtw",
1972 ShiftStyle::UXTX => "uxtx",
1973 ShiftStyle::SXTB => "sxtb",
1974 ShiftStyle::SXTH => "sxth",
1975 ShiftStyle::SXTW => "sxtw",
1976 ShiftStyle::SXTX => "sxtx",
1977 }
1978}
1979
1980fn condition_code(cond: u8) -> &'static str {
1981 match cond {
1982 0b0000 => "eq",
1983 0b0010 => "hs",
1984 0b0100 => "mi",
1985 0b0110 => "vs",
1986 0b1000 => "hi",
1987 0b1010 => "ge",
1988 0b1100 => "gt",
1989 0b1110 => "al",
1990 0b0001 => "ne",
1991 0b0011 => "lo",
1992 0b0101 => "pl",
1993 0b0111 => "vc",
1994 0b1001 => "ls",
1995 0b1011 => "lt",
1996 0b1101 => "le",
1997 0b1111 => "nv",
1998 _ => "<invalid>",
1999 }
2000}
2001
2002#[inline]
2003fn push_register<Cb>(args: &mut Cb, size: SizeCode, reg: u16, sp: bool)
2004where Cb: FnMut(InstructionPart<'static>) {
2005 push_opaque(args, reg_name(size, reg, sp));
2006}
2007
2008#[inline]
2009fn push_shift<Cb>(args: &mut Cb, style: ShiftStyle, amount: u8)
2010where Cb: FnMut(InstructionPart<'static>) {
2011 push_opaque(args, shift_style(style));
2012 if amount != 0 {
2013 push_plain(args, " ");
2014 push_unsigned(args, amount as u64);
2015 }
2016}
2017
2018#[inline]
2019fn push_condition_code<Cb>(args: &mut Cb, cond: u8)
2020where Cb: FnMut(InstructionPart<'static>) {
2021 push_opaque(args, condition_code(cond));
2022}
2023
2024fn push_barrier<Cb>(args: &mut Cb, option: u8)
2025where Cb: FnMut(InstructionPart<'static>) {
2026 match option {
2027 0b0001 => push_opaque(args, "oshld"),
2028 0b0010 => push_opaque(args, "oshst"),
2029 0b0011 => push_opaque(args, "osh"),
2030 0b0101 => push_opaque(args, "nshld"),
2031 0b0110 => push_opaque(args, "nshst"),
2032 0b0111 => push_opaque(args, "nsh"),
2033 0b1001 => push_opaque(args, "ishld"),
2034 0b1010 => push_opaque(args, "ishst"),
2035 0b1011 => push_opaque(args, "ish"),
2036 0b1101 => push_opaque(args, "ld"),
2037 0b1110 => push_opaque(args, "st"),
2038 0b1111 => push_opaque(args, "sy"),
2039 _ => push_unsigned(args, option as u64),
2040 }
2041}
2042
2043#[inline]
2044fn push_opaque<'a, Cb>(args: &mut Cb, text: &'a str)
2045where Cb: FnMut(InstructionPart<'a>) {
2046 args(InstructionPart::opaque(text));
2047}
2048
2049#[inline]
2050fn push_plain<Cb>(args: &mut Cb, text: &'static str)
2051where Cb: FnMut(InstructionPart<'static>) {
2052 args(InstructionPart::basic(text));
2053}
2054
2055#[inline]
2056fn push_separator<Cb>(args: &mut Cb)
2057where Cb: FnMut(InstructionPart<'static>) {
2058 args(InstructionPart::separator());
2059}
2060
2061#[inline]
2062fn push_unsigned<Cb>(args: &mut Cb, v: u64)
2063where Cb: FnMut(InstructionPart<'static>) {
2064 push_plain(args, "#");
2065 args(InstructionPart::unsigned(v));
2066}
2067
2068#[inline]
2069fn push_signed<Cb>(args: &mut Cb, v: i64)
2070where Cb: FnMut(InstructionPart<'static>) {
2071 push_plain(args, "#");
2072 args(InstructionPart::signed(v));
2073}
2074
2075fn is_pc_offset_reloc(reloc: Option<ResolvedRelocation>) -> Option<ResolvedRelocation> {
2077 if let Some(resolved) = reloc
2078 && let RelocationFlags::Elf(
2079 elf::R_AARCH64_ADR_PREL_PG_HI21
2080 | elf::R_AARCH64_JUMP26
2081 | elf::R_AARCH64_CALL26
2082 | elf::R_AARCH64_ADR_GOT_PAGE,
2083 ) = resolved.relocation.flags
2084 {
2085 return Some(resolved);
2086 }
2087 None
2088}
2089
2090fn is_imm_reloc(resolved: Option<ResolvedRelocation>) -> bool {
2092 resolved.is_some_and(|r| {
2093 matches!(r.relocation.flags, RelocationFlags::Elf(elf::R_AARCH64_ADD_ABS_LO12_NC))
2094 })
2095}
2096
2097fn is_reg_index_reloc(resolved: Option<ResolvedRelocation>) -> bool {
2099 resolved.is_some_and(|r| {
2100 matches!(
2101 r.relocation.flags,
2102 RelocationFlags::Elf(
2103 elf::R_AARCH64_LDST32_ABS_LO12_NC | elf::R_AARCH64_LD64_GOT_LO12_NC
2104 )
2105 )
2106 })
2107}
2108
2109fn push_operand<Cb>(args: &mut Cb, o: &Operand, ctx: &mut DisplayCtx)
2110where Cb: FnMut(InstructionPart<'static>) {
2111 match o {
2112 Operand::Nothing => unreachable!(),
2113 Operand::PCOffset(off) => {
2114 if let Some(resolved) = is_pc_offset_reloc(ctx.reloc) {
2115 let target_address =
2116 resolved.symbol.address.checked_add_signed(resolved.relocation.addend);
2117 if resolved.symbol.section == Some(ctx.section_index)
2118 && matches!(target_address, Some(addr) if addr > ctx.start_address && addr < ctx.end_address)
2119 {
2120 let dest = target_address.unwrap();
2121 push_plain(args, "$");
2122 args(InstructionPart::branch_dest(dest));
2123 } else {
2124 args(InstructionPart::reloc());
2125 }
2126 } else {
2127 let dest = ctx.address.saturating_add_signed(*off);
2128 push_plain(args, "$");
2129 args(InstructionPart::branch_dest(dest));
2130 }
2131 }
2132 Operand::Immediate(imm) => {
2133 if is_imm_reloc(ctx.reloc) {
2134 args(InstructionPart::reloc());
2135 } else {
2136 push_unsigned(args, *imm as u64);
2137 }
2138 }
2139 Operand::Imm64(imm) => {
2140 push_unsigned(args, *imm);
2141 }
2142 Operand::Imm16(imm) => {
2143 push_unsigned(args, *imm as u64);
2144 }
2145 Operand::Register(size, reg) => {
2146 push_register(args, *size, *reg, false);
2147 }
2148 Operand::RegisterPair(size, reg) => {
2149 push_register(args, *size, *reg, false);
2150 push_separator(args);
2151 push_register(args, *size, *reg + 1, false);
2152 }
2153 Operand::RegisterOrSP(size, reg) => {
2154 push_register(args, *size, *reg, true);
2155 }
2156 Operand::ConditionCode(cond) => match cond {
2157 0b0000 => push_opaque(args, "eq"),
2158 0b0010 => push_opaque(args, "hs"),
2159 0b0100 => push_opaque(args, "mi"),
2160 0b0110 => push_opaque(args, "vs"),
2161 0b1000 => push_opaque(args, "hi"),
2162 0b1010 => push_opaque(args, "ge"),
2163 0b1100 => push_opaque(args, "gt"),
2164 0b1110 => push_opaque(args, "al"),
2165 0b0001 => push_opaque(args, "ne"),
2166 0b0011 => push_opaque(args, "lo"),
2167 0b0101 => push_opaque(args, "pl"),
2168 0b0111 => push_opaque(args, "vc"),
2169 0b1001 => push_opaque(args, "ls"),
2170 0b1011 => push_opaque(args, "lt"),
2171 0b1101 => push_opaque(args, "le"),
2172 0b1111 => push_opaque(args, "nv"),
2173 _ => unreachable!(),
2174 },
2175 Operand::ImmShift(i, shift) => {
2176 push_unsigned(args, *i as u64);
2177 if *shift > 0 {
2178 push_separator(args);
2179 push_opaque(args, "lsl");
2180 push_plain(args, " ");
2181 push_unsigned(args, *shift as u64);
2182 }
2183 }
2184 Operand::ImmShiftMSL(i, shift) => {
2185 push_unsigned(args, *i as u64);
2186 if *shift > 0 {
2187 push_separator(args);
2188 push_opaque(args, "msl");
2189 push_plain(args, " ");
2190 push_unsigned(args, *shift as u64);
2191 }
2192 }
2193 Operand::RegShift(shift_type, amount, size, reg) => match size {
2194 SizeCode::X => {
2195 push_register(args, SizeCode::X, *reg, false);
2196 if (*shift_type == ShiftStyle::LSL || *shift_type == ShiftStyle::UXTX)
2197 && *amount == 0
2198 {
2199 } else {
2201 push_separator(args);
2202 push_shift(args, *shift_type, *amount);
2203 }
2204 }
2205 SizeCode::W => {
2206 push_register(args, SizeCode::W, *reg, false);
2207 if *shift_type == ShiftStyle::LSL && *amount == 0 {
2208 } else {
2210 push_separator(args);
2211 push_shift(args, *shift_type, *amount);
2212 }
2213 }
2214 },
2215 Operand::RegRegOffset(reg, index_reg, index_size, extend, amount) => {
2216 push_plain(args, "[");
2217 push_register(args, SizeCode::X, *reg, true);
2218 push_separator(args);
2219 push_register(args, *index_size, *index_reg, false);
2220 if extend == &ShiftStyle::LSL && *amount == 0 {
2221 } else if ((extend == &ShiftStyle::UXTW && index_size == &SizeCode::W)
2223 || (extend == &ShiftStyle::UXTX && index_size == &SizeCode::X))
2224 && *amount == 0
2225 {
2226 push_separator(args);
2227 push_shift(args, *extend, 0);
2228 } else {
2229 push_separator(args);
2230 push_shift(args, *extend, *amount);
2231 }
2232 push_plain(args, "]");
2233 }
2234 Operand::RegPreIndex(reg, offset, wback_bit) => {
2235 push_plain(args, "[");
2236 push_register(args, SizeCode::X, *reg, true);
2237 if is_reg_index_reloc(ctx.reloc) {
2238 push_separator(args);
2239 args(InstructionPart::reloc());
2240 } else if *offset != 0 || *wback_bit {
2241 push_separator(args);
2242 push_signed(args, *offset as i64);
2243 }
2244 push_plain(args, "]");
2245 if *wback_bit {
2246 push_plain(args, "!");
2247 }
2248 }
2249 Operand::RegPostIndex(reg, offset) => {
2250 push_plain(args, "[");
2251 push_register(args, SizeCode::X, *reg, true);
2252 push_plain(args, "]");
2253 push_separator(args);
2254 if is_reg_index_reloc(ctx.reloc) {
2255 args(InstructionPart::reloc());
2256 } else {
2257 push_signed(args, *offset as i64);
2258 }
2259 }
2260 Operand::RegPostIndexReg(reg, offset_reg) => {
2261 push_plain(args, "[");
2262 push_register(args, SizeCode::X, *reg, true);
2263 push_plain(args, "]");
2264 push_separator(args);
2265 args(InstructionPart::opaque(format!("x{offset_reg}")));
2267 }
2268 Operand::SIMDRegister(_, _)
2270 | Operand::SIMDRegisterElements(_, _, _)
2271 | Operand::SIMDRegisterElementsLane(_, _, _, _)
2272 | Operand::SIMDRegisterElementsMultipleLane(_, _, _, _, _)
2273 | Operand::SIMDRegisterGroup(_, _, _, _)
2274 | Operand::SIMDRegisterGroupLane(_, _, _, _)
2275 | Operand::ImmediateDouble(_)
2276 | Operand::PrefetchOp(_)
2277 | Operand::SystemReg(_)
2278 | Operand::ControlReg(_)
2279 | Operand::PstateField(_) => {
2280 args(InstructionPart::opaque(o.to_string()));
2281 }
2282 }
2283}
2284
2285const fn opcode_to_u16(opcode: Opcode) -> u16 {
2287 match opcode {
2288 Opcode::Invalid => OPCODE_INVALID,
2289 Opcode::UDF => 0,
2290 Opcode::MOVN => 1,
2291 Opcode::MOVK => 2,
2292 Opcode::MOVZ => 3,
2293 Opcode::ADC => 4,
2294 Opcode::ADCS => 5,
2295 Opcode::SBC => 6,
2296 Opcode::SBCS => 7,
2297 Opcode::AND => 8,
2298 Opcode::ORR => 9,
2299 Opcode::ORN => 10,
2300 Opcode::EOR => 11,
2301 Opcode::EON => 12,
2302 Opcode::BIC => 13,
2303 Opcode::BICS => 14,
2304 Opcode::ANDS => 15,
2305 Opcode::ADDS => 16,
2306 Opcode::ADD => 17,
2307 Opcode::SUBS => 18,
2308 Opcode::SUB => 19,
2309 Opcode::BFM => 20,
2310 Opcode::UBFM => 21,
2311 Opcode::SBFM => 22,
2312 Opcode::ADR => 23,
2313 Opcode::ADRP => 24,
2314 Opcode::EXTR => 25,
2315 Opcode::LDAR => 26,
2316 Opcode::LDLAR => 27,
2317 Opcode::LDARB => 28,
2318 Opcode::LDLARB => 29,
2319 Opcode::LDAXRB => 30,
2320 Opcode::LDARH => 31,
2321 Opcode::LDLARH => 32,
2322 Opcode::LDAXP => 33,
2323 Opcode::LDAXR => 34,
2324 Opcode::LDAXRH => 35,
2325 Opcode::LDP => 36,
2326 Opcode::LDPSW => 37,
2327 Opcode::LDR => 38,
2328 Opcode::LDRB => 39,
2329 Opcode::LDRSB => 40,
2330 Opcode::LDRSW => 41,
2331 Opcode::LDRSH => 42,
2332 Opcode::LDRH => 43,
2333 Opcode::LDTR => 44,
2334 Opcode::LDTRB => 45,
2335 Opcode::LDTRH => 46,
2336 Opcode::LDTRSB => 47,
2337 Opcode::LDTRSH => 48,
2338 Opcode::LDTRSW => 49,
2339 Opcode::LDUR => 50,
2340 Opcode::LDURB => 51,
2341 Opcode::LDURSB => 52,
2342 Opcode::LDURSW => 53,
2343 Opcode::LDURSH => 54,
2344 Opcode::LDURH => 55,
2345 Opcode::LDXP => 56,
2346 Opcode::LDXR => 57,
2347 Opcode::LDXRB => 58,
2348 Opcode::LDXRH => 59,
2349 Opcode::STLR => 60,
2350 Opcode::STLLR => 61,
2351 Opcode::STLRB => 62,
2352 Opcode::STLLRB => 63,
2353 Opcode::STLRH => 64,
2354 Opcode::STLLRH => 65,
2355 Opcode::STLXP => 66,
2356 Opcode::STLXR => 67,
2357 Opcode::STLXRB => 68,
2358 Opcode::STLXRH => 69,
2359 Opcode::STP => 70,
2360 Opcode::STR => 71,
2361 Opcode::STTR => 72,
2362 Opcode::STTRB => 73,
2363 Opcode::STTRH => 74,
2364 Opcode::STRB => 75,
2365 Opcode::STRH => 76,
2366 Opcode::STRW => 77,
2367 Opcode::STUR => 78,
2368 Opcode::STURB => 79,
2369 Opcode::STURH => 80,
2370 Opcode::STXP => 81,
2371 Opcode::STXR => 82,
2372 Opcode::STXRB => 83,
2373 Opcode::STXRH => 84,
2374 Opcode::TBZ => 85,
2375 Opcode::TBNZ => 86,
2376 Opcode::CBZ => 87,
2377 Opcode::CBNZ => 88,
2378 Opcode::B => 89,
2379 Opcode::BR => 90,
2380 Opcode::Bcc(_) => 91,
2381 Opcode::BL => 92,
2382 Opcode::BLR => 93,
2383 Opcode::SVC => 94,
2384 Opcode::HVC => 95,
2385 Opcode::SMC => 96,
2386 Opcode::BRK => 97,
2387 Opcode::HLT => 98,
2388 Opcode::DCPS1 => 99,
2389 Opcode::DCPS2 => 100,
2390 Opcode::DCPS3 => 101,
2391 Opcode::RET => 102,
2392 Opcode::ERET => 103,
2393 Opcode::DRPS => 104,
2394 Opcode::MSR => 105,
2395 Opcode::MRS => 106,
2396 Opcode::SYS(_) => 107,
2397 Opcode::SYSL(_) => 108,
2398 Opcode::ISB => 109,
2399 Opcode::DSB(_) => 110,
2400 Opcode::DMB(_) => 111,
2401 Opcode::SB => 112,
2402 Opcode::SSSB => 113,
2403 Opcode::HINT => 114,
2404 Opcode::CLREX => 115,
2405 Opcode::CSEL => 116,
2406 Opcode::CSNEG => 117,
2407 Opcode::CSINC => 118,
2408 Opcode::CSINV => 119,
2409 Opcode::CCMN => 120,
2410 Opcode::CCMP => 121,
2411 Opcode::RBIT => 122,
2412 Opcode::REV16 => 123,
2413 Opcode::REV => 124,
2414 Opcode::REV32 => 125,
2415 Opcode::CLZ => 126,
2416 Opcode::CLS => 127,
2417 Opcode::MADD => 128,
2418 Opcode::MSUB => 129,
2419 Opcode::SMADDL => 130,
2420 Opcode::SMSUBL => 131,
2421 Opcode::SMULH => 132,
2422 Opcode::UMADDL => 133,
2423 Opcode::UMSUBL => 134,
2424 Opcode::UMULH => 135,
2425 Opcode::UDIV => 136,
2426 Opcode::SDIV => 137,
2427 Opcode::LSLV => 138,
2428 Opcode::LSRV => 139,
2429 Opcode::ASRV => 140,
2430 Opcode::RORV => 141,
2431 Opcode::CRC32B => 142,
2432 Opcode::CRC32H => 143,
2433 Opcode::CRC32W => 144,
2434 Opcode::CRC32X => 145,
2435 Opcode::CRC32CB => 146,
2436 Opcode::CRC32CH => 147,
2437 Opcode::CRC32CW => 148,
2438 Opcode::CRC32CX => 149,
2439 Opcode::STNP => 150,
2440 Opcode::LDNP => 151,
2441 Opcode::ST1 => 152,
2442 Opcode::ST2 => 153,
2443 Opcode::ST3 => 154,
2444 Opcode::ST4 => 155,
2445 Opcode::LD1 => 156,
2446 Opcode::LD2 => 157,
2447 Opcode::LD3 => 158,
2448 Opcode::LD4 => 159,
2449 Opcode::LD1R => 160,
2450 Opcode::LD2R => 161,
2451 Opcode::LD3R => 162,
2452 Opcode::LD4R => 163,
2453 Opcode::FMADD => 164,
2454 Opcode::FMSUB => 165,
2455 Opcode::FNMADD => 166,
2456 Opcode::FNMSUB => 167,
2457 Opcode::SCVTF => 168,
2458 Opcode::UCVTF => 169,
2459 Opcode::FCVTZS => 170,
2460 Opcode::FCVTZU => 171,
2461 Opcode::FMOV => 172,
2462 Opcode::FABS => 173,
2463 Opcode::FNEG => 174,
2464 Opcode::FSQRT => 175,
2465 Opcode::FRINTN => 176,
2466 Opcode::FRINTP => 177,
2467 Opcode::FRINTM => 178,
2468 Opcode::FRINTZ => 179,
2469 Opcode::FRINTA => 180,
2470 Opcode::FRINTX => 181,
2471 Opcode::FRINTI => 182,
2472 Opcode::FRINT32Z => 183,
2473 Opcode::FRINT32X => 184,
2474 Opcode::FRINT64Z => 185,
2475 Opcode::FRINT64X => 186,
2476 Opcode::BFCVT => 187,
2477 Opcode::FCVT => 188,
2478 Opcode::FCMP => 189,
2479 Opcode::FCMPE => 190,
2480 Opcode::FMUL => 191,
2481 Opcode::FDIV => 192,
2482 Opcode::FADD => 193,
2483 Opcode::FSUB => 194,
2484 Opcode::FMAX => 195,
2485 Opcode::FMIN => 196,
2486 Opcode::FMAXNM => 197,
2487 Opcode::FMINNM => 198,
2488 Opcode::FNMUL => 199,
2489 Opcode::FCSEL => 200,
2490 Opcode::FCCMP => 201,
2491 Opcode::FCCMPE => 202,
2492 Opcode::FMULX => 203,
2493 Opcode::FMLSL => 204,
2494 Opcode::FMLAL => 205,
2495 Opcode::SQRDMLSH => 206,
2496 Opcode::UDOT => 207,
2497 Opcode::SQRDMLAH => 208,
2498 Opcode::UMULL => 209,
2499 Opcode::UMULL2 => 210,
2500 Opcode::UMLSL => 211,
2501 Opcode::UMLSL2 => 212,
2502 Opcode::MLS => 213,
2503 Opcode::UMLAL => 214,
2504 Opcode::UMLAL2 => 215,
2505 Opcode::MLA => 216,
2506 Opcode::SDOT => 217,
2507 Opcode::SQDMULH => 218,
2508 Opcode::SQDMULL => 219,
2509 Opcode::SQDMULL2 => 220,
2510 Opcode::SMULL => 221,
2511 Opcode::SMULL2 => 222,
2512 Opcode::MUL => 223,
2513 Opcode::SQDMLSL => 224,
2514 Opcode::SQDMLSL2 => 225,
2515 Opcode::SMLSL => 226,
2516 Opcode::SMLSL2 => 227,
2517 Opcode::SQDMLAL => 228,
2518 Opcode::SQDMLAL2 => 229,
2519 Opcode::SMLAL => 230,
2520 Opcode::SMLAL2 => 231,
2521 Opcode::SQRDMULH => 232,
2522 Opcode::FCMLA => 233,
2523 Opcode::SSHR => 234,
2524 Opcode::SSRA => 235,
2525 Opcode::SRSHR => 236,
2526 Opcode::SRSRA => 237,
2527 Opcode::SHL => 238,
2528 Opcode::SQSHL => 239,
2529 Opcode::SHRN => 240,
2530 Opcode::RSHRN => 241,
2531 Opcode::SQSHRN => 242,
2532 Opcode::SQRSHRN => 243,
2533 Opcode::SSHLL => 244,
2534 Opcode::USHR => 245,
2535 Opcode::USRA => 246,
2536 Opcode::URSHR => 247,
2537 Opcode::URSRA => 248,
2538 Opcode::SRI => 249,
2539 Opcode::SLI => 250,
2540 Opcode::SQSHLU => 251,
2541 Opcode::UQSHL => 252,
2542 Opcode::SQSHRUN => 253,
2543 Opcode::SQRSHRUN => 254,
2544 Opcode::UQSHRN => 255,
2545 Opcode::UQRSHRN => 256,
2546 Opcode::USHLL => 257,
2547 Opcode::MOVI => 258,
2548 Opcode::MVNI => 259,
2549 Opcode::SHADD => 260,
2550 Opcode::SQADD => 261,
2551 Opcode::SRHADD => 262,
2552 Opcode::SHSUB => 263,
2553 Opcode::SQSUB => 264,
2554 Opcode::CMGT => 265,
2555 Opcode::CMGE => 266,
2556 Opcode::SSHL => 267,
2557 Opcode::SRSHL => 268,
2558 Opcode::SQRSHL => 269,
2559 Opcode::SMAX => 270,
2560 Opcode::SMIN => 271,
2561 Opcode::SABD => 272,
2562 Opcode::SABA => 273,
2563 Opcode::CMTST => 274,
2564 Opcode::SMAXP => 275,
2565 Opcode::SMINP => 276,
2566 Opcode::ADDP => 277,
2567 Opcode::UHADD => 278,
2568 Opcode::UQADD => 279,
2569 Opcode::URHADD => 280,
2570 Opcode::UHSUB => 281,
2571 Opcode::UQSUB => 282,
2572 Opcode::CMHI => 283,
2573 Opcode::CMHS => 284,
2574 Opcode::USHL => 285,
2575 Opcode::URSHL => 286,
2576 Opcode::UQRSHL => 287,
2577 Opcode::UMAX => 288,
2578 Opcode::UMIN => 289,
2579 Opcode::UABD => 290,
2580 Opcode::UABA => 291,
2581 Opcode::CMEQ => 292,
2582 Opcode::PMUL => 293,
2583 Opcode::UMAXP => 294,
2584 Opcode::UMINP => 295,
2585 Opcode::FMLA => 296,
2586 Opcode::FCMEQ => 297,
2587 Opcode::FRECPS => 298,
2588 Opcode::BSL => 299,
2589 Opcode::BIT => 300,
2590 Opcode::BIF => 301,
2591 Opcode::FMAXNMP => 302,
2592 Opcode::FMINMNP => 303,
2593 Opcode::FADDP => 304,
2594 Opcode::FCMGE => 305,
2595 Opcode::FACGE => 306,
2596 Opcode::FMAXP => 307,
2597 Opcode::SADDL => 308,
2598 Opcode::SADDL2 => 309,
2599 Opcode::SADDW => 310,
2600 Opcode::SADDW2 => 311,
2601 Opcode::SSUBL => 312,
2602 Opcode::SSUBL2 => 313,
2603 Opcode::SSUBW => 314,
2604 Opcode::SSUBW2 => 315,
2605 Opcode::ADDHN => 316,
2606 Opcode::ADDHN2 => 317,
2607 Opcode::SABAL => 318,
2608 Opcode::SABAL2 => 319,
2609 Opcode::SUBHN => 320,
2610 Opcode::SUBHN2 => 321,
2611 Opcode::SABDL => 322,
2612 Opcode::SABDL2 => 323,
2613 Opcode::PMULL => 324,
2614 Opcode::PMULL2 => 325,
2615 Opcode::UADDL => 326,
2616 Opcode::UADDL2 => 327,
2617 Opcode::UADDW => 328,
2618 Opcode::UADDW2 => 329,
2619 Opcode::USUBL => 330,
2620 Opcode::USUBL2 => 331,
2621 Opcode::USUBW => 332,
2622 Opcode::USUBW2 => 333,
2623 Opcode::RADDHN => 334,
2624 Opcode::RADDHN2 => 335,
2625 Opcode::RSUBHN => 336,
2626 Opcode::RSUBHN2 => 337,
2627 Opcode::UABAL => 338,
2628 Opcode::UABAL2 => 339,
2629 Opcode::UABDL => 340,
2630 Opcode::UABDL2 => 341,
2631 Opcode::REV64 => 342,
2632 Opcode::SADDLP => 343,
2633 Opcode::SUQADD => 344,
2634 Opcode::CNT => 345,
2635 Opcode::SADALP => 346,
2636 Opcode::SQABS => 347,
2637 Opcode::CMLT => 348,
2638 Opcode::ABS => 349,
2639 Opcode::XTN => 350,
2640 Opcode::XTN2 => 351,
2641 Opcode::SQXTN => 352,
2642 Opcode::SQXTN2 => 353,
2643 Opcode::FCVTN => 354,
2644 Opcode::FCVTN2 => 355,
2645 Opcode::FCMGT => 356,
2646 Opcode::FCVTL => 357,
2647 Opcode::FCVTL2 => 358,
2648 Opcode::FCVTNS => 359,
2649 Opcode::FCVTPS => 360,
2650 Opcode::FCVTMS => 361,
2651 Opcode::FCVTAS => 362,
2652 Opcode::URECPE => 363,
2653 Opcode::FRECPE => 364,
2654 Opcode::UADDLP => 365,
2655 Opcode::USQADD => 366,
2656 Opcode::UADALP => 367,
2657 Opcode::SQNEG => 368,
2658 Opcode::CMLE => 369,
2659 Opcode::NEG => 370,
2660 Opcode::SQXTUN => 371,
2661 Opcode::SQXTUN2 => 372,
2662 Opcode::SHLL => 373,
2663 Opcode::SHLL2 => 374,
2664 Opcode::UQXTN => 375,
2665 Opcode::UQXTN2 => 376,
2666 Opcode::FCVTXN => 377,
2667 Opcode::FCVTXN2 => 378,
2668 Opcode::FCVTNU => 379,
2669 Opcode::FCVTMU => 380,
2670 Opcode::FCVTAU => 381,
2671 Opcode::INS => 382,
2672 Opcode::EXT => 383,
2673 Opcode::DUP => 384,
2674 Opcode::UZP1 => 385,
2675 Opcode::TRN1 => 386,
2676 Opcode::ZIP1 => 387,
2677 Opcode::UZP2 => 388,
2678 Opcode::TRN2 => 389,
2679 Opcode::ZIP2 => 390,
2680 Opcode::SMOV => 391,
2681 Opcode::UMOV => 392,
2682 Opcode::SQSHRN2 => 393,
2683 Opcode::SQRSHRN2 => 394,
2684 Opcode::SQSHRUN2 => 395,
2685 Opcode::UQSHRN2 => 396,
2686 Opcode::UQRSHRN2 => 397,
2687 Opcode::FMLS => 398,
2688 Opcode::FRECPX => 399,
2689 Opcode::FRSQRTE => 400,
2690 Opcode::FCVTPU => 401,
2691 Opcode::FCMLT => 402,
2692 Opcode::FCMLE => 403,
2693 Opcode::FMAXNMV => 404,
2694 Opcode::FMINNMV => 405,
2695 Opcode::FMAXV => 406,
2696 Opcode::FMINV => 407,
2697 Opcode::UADDLV => 408,
2698 Opcode::SADDLV => 409,
2699 Opcode::UMAXV => 410,
2700 Opcode::SMAXV => 411,
2701 Opcode::UMINV => 412,
2702 Opcode::SMINV => 413,
2703 Opcode::ADDV => 414,
2704 Opcode::FRSQRTS => 415,
2705 Opcode::FMINNMP => 416,
2706 Opcode::FMLAL2 => 417,
2707 Opcode::FMLSL2 => 418,
2708 Opcode::FABD => 419,
2709 Opcode::FACGT => 420,
2710 Opcode::FMINP => 421,
2711 Opcode::FJCVTZS => 422,
2712 Opcode::URSQRTE => 423,
2713 Opcode::PRFM => 424,
2714 Opcode::PRFUM => 425,
2715 Opcode::AESE => 426,
2716 Opcode::AESD => 427,
2717 Opcode::AESMC => 428,
2718 Opcode::AESIMC => 429,
2719 Opcode::SHA1H => 430,
2720 Opcode::SHA1SU1 => 431,
2721 Opcode::SHA256SU0 => 432,
2722 Opcode::SM3TT1A => 433,
2723 Opcode::SM3TT1B => 434,
2724 Opcode::SM3TT2A => 435,
2725 Opcode::SM3TT2B => 436,
2726 Opcode::SHA512H => 437,
2727 Opcode::SHA512H2 => 438,
2728 Opcode::SHA512SU1 => 439,
2729 Opcode::RAX1 => 440,
2730 Opcode::SM3PARTW1 => 441,
2731 Opcode::SM3PARTW2 => 442,
2732 Opcode::SM4EKEY => 443,
2733 Opcode::BCAX => 444,
2734 Opcode::SM3SS1 => 445,
2735 Opcode::SHA512SU0 => 446,
2736 Opcode::SM4E => 447,
2737 Opcode::EOR3 => 448,
2738 Opcode::XAR => 449,
2739 Opcode::LDRAA => 450,
2740 Opcode::LDRAB => 451,
2741 Opcode::LDAPR => 452,
2742 Opcode::LDAPRH => 453,
2743 Opcode::LDAPRB => 454,
2744 Opcode::SWP(_) => 455,
2745 Opcode::SWPB(_) => 456,
2746 Opcode::SWPH(_) => 457,
2747 Opcode::LDADDB(_) => 458,
2748 Opcode::LDCLRB(_) => 459,
2749 Opcode::LDEORB(_) => 460,
2750 Opcode::LDSETB(_) => 461,
2751 Opcode::LDSMAXB(_) => 462,
2752 Opcode::LDSMINB(_) => 463,
2753 Opcode::LDUMAXB(_) => 464,
2754 Opcode::LDUMINB(_) => 465,
2755 Opcode::LDADDH(_) => 466,
2756 Opcode::LDCLRH(_) => 467,
2757 Opcode::LDEORH(_) => 468,
2758 Opcode::LDSETH(_) => 469,
2759 Opcode::LDSMAXH(_) => 470,
2760 Opcode::LDSMINH(_) => 471,
2761 Opcode::LDUMAXH(_) => 472,
2762 Opcode::LDUMINH(_) => 473,
2763 Opcode::LDADD(_) => 474,
2764 Opcode::LDCLR(_) => 475,
2765 Opcode::LDEOR(_) => 476,
2766 Opcode::LDSET(_) => 477,
2767 Opcode::LDSMAX(_) => 478,
2768 Opcode::LDSMIN(_) => 479,
2769 Opcode::LDUMAX(_) => 480,
2770 Opcode::LDUMIN(_) => 481,
2771 Opcode::CAS(_) => 482,
2772 Opcode::CASH(_) => 483,
2773 Opcode::CASB(_) => 484,
2774 Opcode::CASP(_) => 485,
2775 Opcode::TBL => 486,
2776 Opcode::TBX => 487,
2777 Opcode::FCADD => 488,
2778 Opcode::LDGM => 489,
2779 Opcode::LDG => 490,
2780 Opcode::STGM => 491,
2781 Opcode::STZGM => 492,
2782 Opcode::STG => 493,
2783 Opcode::STZG => 494,
2784 Opcode::ST2G => 495,
2785 Opcode::STZ2G => 496,
2786 Opcode::LDAPUR => 497,
2787 Opcode::LDAPURB => 498,
2788 Opcode::LDAPURH => 499,
2789 Opcode::LDAPURSB => 500,
2790 Opcode::LDAPURSH => 501,
2791 Opcode::LDAPURSW => 502,
2792 Opcode::STLUR => 503,
2793 Opcode::STLURB => 504,
2794 Opcode::STLURH => 505,
2795 Opcode::SETF8 => 506,
2796 Opcode::SETF16 => 507,
2797 Opcode::RMIF => 508,
2798 Opcode::NOT => 509,
2799 Opcode::RSHRN2 => 510,
2800 Opcode::SQRSHRUN2 => 511,
2801 Opcode::USHLL2 => 512,
2802 Opcode::SSHLL2 => 513,
2803 Opcode::SHA1C => 514,
2804 Opcode::SHA1P => 515,
2805 Opcode::SHA1M => 516,
2806 Opcode::SHA1SU0 => 517,
2807 Opcode::SHA256H => 518,
2808 Opcode::SHA256H2 => 519,
2809 Opcode::SHA256SU1 => 520,
2810 Opcode::SHRN2 => 521,
2811 Opcode::BLRAA => 522,
2812 Opcode::BLRAAZ => 523,
2813 Opcode::BLRAB => 524,
2814 Opcode::BLRABZ => 525,
2815 Opcode::BRAA => 526,
2816 Opcode::BRAAZ => 527,
2817 Opcode::BRAB => 528,
2818 Opcode::BRABZ => 529,
2819 Opcode::RETAA => 530,
2820 Opcode::RETAB => 531,
2821 Opcode::ERETAA => 532,
2822 Opcode::ERETAB => 533,
2823 Opcode::PACIA => 534,
2824 Opcode::PACIB => 535,
2825 Opcode::PACDA => 536,
2826 Opcode::PACDB => 537,
2827 Opcode::AUTIA => 538,
2828 Opcode::AUTIB => 539,
2829 Opcode::AUTDA => 540,
2830 Opcode::AUTDB => 541,
2831 Opcode::PACIZA => 542,
2832 Opcode::PACIZB => 543,
2833 Opcode::PACDZA => 544,
2834 Opcode::PACDZB => 545,
2835 Opcode::AUTIZA => 546,
2836 Opcode::AUTIZB => 547,
2837 Opcode::AUTDZA => 548,
2838 Opcode::AUTDZB => 549,
2839 Opcode::XPACI => 550,
2840 Opcode::XPACD => 551,
2841 Opcode::PACGA => 552,
2842 Opcode::GMI => 553,
2843 Opcode::IRG => 554,
2844 Opcode::SUBP => 555,
2845 Opcode::SUBPS => 556,
2846 }
2847}