aarch64emu/
opcodes.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Structs to parse aarch64 instructions.
5
6use crate::Cpu;
7use crate::emulator::EmulatorOperations;
8use crate::emulator::Error;
9
10#[derive(Debug, PartialEq)]
11pub enum Aarch64DecodeGroup {
12    Reserved,
13    ScalableMatrixExtension,
14    ScalableVectorExtension,
15    ImmediateData,
16    BranchesExceptionsAndSystem,
17    LoadStore(Aarch64DecodeLoadStoreGroup),
18    RegisterData,
19    FpAndAdvancedData,
20}
21
22pub fn decode_group<E>(opcode: u32) -> Result<Aarch64DecodeGroup, Box<Error<E>>> {
23    let op0 = opcode >> 31;
24    let op1 = ((opcode >> 25) as u8) & 0xf;
25    Ok(match op1 {
26        0 if op0 == 0 => Aarch64DecodeGroup::Reserved,
27        0 => Aarch64DecodeGroup::ScalableMatrixExtension,
28        2 => Aarch64DecodeGroup::ScalableVectorExtension,
29        8 | 9 => Aarch64DecodeGroup::ImmediateData,
30        10 | 11 => Aarch64DecodeGroup::BranchesExceptionsAndSystem,
31        4 | 6 | 12 | 14 => Aarch64DecodeGroup::LoadStore(decode_load_store_group(opcode)?),
32        5 | 13 => Aarch64DecodeGroup::RegisterData,
33        7 | 15 => Aarch64DecodeGroup::FpAndAdvancedData,
34        1 | 3 => {
35            return Err(Box::new(Error::UnsupportedInstruction(opcode)));
36        }
37        16.. => unreachable!("masked with 0xf"),
38    })
39}
40
41#[derive(Debug, PartialEq)]
42pub enum Aarch64DecodeLoadStoreGroup {
43    CompareAndSwapPair,
44    AdvancedSimdMultiStruct,
45    AdvancedSimdMultiStructPostIndex,
46    AdvancedSimd,
47    AdvancedSimdPostIndex,
48    MemoryTags,
49    ExclusivePair,
50    ExclusiveRegister,
51    Ordered,
52    CompareAndSwap,
53    UnscaledImmediate,
54    RegisterLiteral,
55    MemoryCopyAndSet,
56    NoAllocatePair,
57    RegisterPairPostIndex,
58    RegisterPairOffset,
59    RegisterPairPreIndex,
60    RegisterUnscaledImmediate,
61    RegisterImmediatePostIndex,
62    RegisterUnprivileged,
63    RegisterImmediatePreIndex,
64    Atomic,
65    RegisterOffset,
66    RegisterPac,
67    RegisterUnsignedImmediate,
68}
69
70fn decode_load_store_group<E>(opcode: u32) -> Result<Aarch64DecodeLoadStoreGroup, Box<Error<E>>> {
71    let op0 = (opcode >> 28) as u8;
72    let op1 = (opcode >> 26) & 1;
73    let op2 = ((opcode >> 23) & 3) as u8;
74    let op3 = ((opcode >> 16) & 0x3f) as u8;
75    let op4 = ((opcode >> 10) & 3) as u8;
76    Ok(match op0 {
77        0 | 4 | 8 | 12 if op1 == 0 => {
78            if op2 == 0 {
79                if (op3 & 0x20) == 0 {
80                    Aarch64DecodeLoadStoreGroup::ExclusiveRegister
81                } else if op0 == 0 || op0 == 4 {
82                    Aarch64DecodeLoadStoreGroup::CompareAndSwapPair
83                } else {
84                    Aarch64DecodeLoadStoreGroup::ExclusivePair
85                }
86            } else if (op3 & 0x20) != 0 {
87                Aarch64DecodeLoadStoreGroup::CompareAndSwap
88            } else {
89                Aarch64DecodeLoadStoreGroup::Ordered
90            }
91        }
92        0 | 4 => match op2 {
93            0 if op3 == 0 => Aarch64DecodeLoadStoreGroup::AdvancedSimdMultiStruct,
94            0 => {
95                return Err(Box::new(Error::UnsupportedInstruction(opcode)));
96            }
97            1 if ((op3 & 0x20) == 0) => {
98                Aarch64DecodeLoadStoreGroup::AdvancedSimdMultiStructPostIndex
99            }
100            1 => {
101                return Err(Box::new(Error::UnsupportedInstruction(opcode)));
102            }
103            2 if ((op3 & 0x1f) == 0) => Aarch64DecodeLoadStoreGroup::AdvancedSimd,
104            2 => {
105                return Err(Box::new(Error::UnsupportedInstruction(opcode)));
106            }
107            3 => Aarch64DecodeLoadStoreGroup::AdvancedSimdPostIndex,
108            4.. => unreachable!("masked with 0x3"),
109        },
110        8 | 12 => {
111            return Err(Box::new(Error::UnsupportedInstruction(opcode)));
112        }
113        13 if op1 == 0 && (op2 & 2) != 0 && (op3 & 0x20) != 0 => {
114            Aarch64DecodeLoadStoreGroup::MemoryTags
115        }
116        1 | 5 | 9 | 13 if (op2 & 2) != 0 => {
117            if (op0 == 13) && (op3 & 0x20) != 0 {
118                Aarch64DecodeLoadStoreGroup::MemoryTags
119            } else if (op3 & 0x20) != 0 {
120                return Err(Box::new(Error::UnsupportedInstruction(opcode)));
121            } else if op4 == 0 {
122                Aarch64DecodeLoadStoreGroup::UnscaledImmediate
123            } else {
124                Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet
125            }
126        }
127        1 | 5 | 9 | 13 => Aarch64DecodeLoadStoreGroup::RegisterLiteral,
128        2 | 6 | 10 | 14 if op2 == 0 => Aarch64DecodeLoadStoreGroup::NoAllocatePair,
129        2 | 6 | 10 | 14 if op2 == 1 => Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex,
130        2 | 6 | 10 | 14 if op2 == 2 => Aarch64DecodeLoadStoreGroup::RegisterPairOffset,
131        2 | 6 | 10 | 14 => Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex,
132        3 | 7 | 11 | 15 if ((op2 & 2) != 0) => {
133            Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate
134        }
135        3 | 7 | 11 | 15 if op4 == 0 => {
136            if (op3 & 0x20) != 0 {
137                Aarch64DecodeLoadStoreGroup::Atomic
138            } else {
139                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate
140            }
141        }
142        3 | 7 | 11 | 15 if op4 == 1 => {
143            if (op3 & 0x20) != 0 {
144                Aarch64DecodeLoadStoreGroup::RegisterPac
145            } else {
146                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex
147            }
148        }
149        3 | 7 | 11 | 15 if op4 == 2 => {
150            if (op3 & 0x20) != 0 {
151                Aarch64DecodeLoadStoreGroup::RegisterOffset
152            } else {
153                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged
154            }
155        }
156        3 | 7 | 11 | 15 => {
157            if (op3 & 0x20) != 0 {
158                Aarch64DecodeLoadStoreGroup::RegisterPac
159            } else {
160                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex
161            }
162        }
163        16.. => unreachable!("masked with 0xf"),
164    })
165}
166
167pub struct LoadRegisterLiteral(pub u32);
168impl LoadRegisterLiteral {
169    fn opc(&self) -> u8 {
170        (self.0 >> 30) as u8
171    }
172
173    // register name: V
174    fn is_fp_register(&self) -> bool {
175        ((self.0 >> 26) & 1) != 0
176    }
177
178    fn imm(&self) -> i64 {
179        // imm = imm_val * 4
180        let imm = (self.0 >> 3) & 0x1ffffc;
181        // sign-extend
182        let imm = if imm & 0x100000 != 0 {
183            0xffe00000 | imm
184        } else {
185            imm
186        };
187        imm as i32 as i64
188    }
189
190    fn rt(&self) -> u8 {
191        (self.0 & 0x1f) as u8
192    }
193
194    pub async fn emulate<T: Cpu>(
195        &self,
196        emulate: &mut EmulatorOperations<T>,
197    ) -> Result<(), Box<Error<T::Error>>> {
198        if self.opc() == 3 && !self.is_fp_register() {
199            // PRFM prefetch instruction
200            return Ok(());
201        }
202        let address = emulate.cpu.pc().wrapping_add(self.imm() as u64);
203        let mut buf = [0_u8; 16];
204        let new_val = if self.opc() == 0 {
205            // 32-bit load
206            emulate.read_memory(address, &mut buf[..4]).await?;
207            u32::from_ne_bytes(buf[..4].try_into().unwrap()) as u128
208        } else if self.opc() == 1 {
209            // 64-bit load
210            emulate.read_memory(address, &mut buf[..8]).await?;
211            u64::from_ne_bytes(buf[..8].try_into().unwrap()) as u128
212        } else if self.opc() == 2 && !self.is_fp_register() {
213            // 32-bit sign extend load
214            emulate.read_memory(address, &mut buf[..4]).await?;
215            let original = u32::from_ne_bytes(buf[..4].try_into().unwrap());
216            if original & 0x80000000 != 0 {
217                0xffffffff_00000000 | original as u128
218            } else {
219                original as u128
220            }
221        } else if self.opc() == 2 {
222            // 128-bit floating point load
223            emulate.read_memory(address, &mut buf[..]).await?;
224            u128::from_ne_bytes(buf[..].try_into().unwrap())
225        } else {
226            return Err(Box::new(Error::UnsupportedInstruction(self.0)));
227        };
228        if !self.is_fp_register() {
229            if self.rt() != 31 {
230                emulate.cpu.update_x(self.rt(), new_val as u64);
231            }
232        } else {
233            emulate.cpu.update_q(self.rt(), new_val);
234        }
235        Ok(())
236    }
237}
238
239#[derive(Debug)]
240enum LoadStoreRegisterByteCount {
241    One,
242    Two,
243    Four,
244    Eight,
245    FloatingPoint,
246}
247
248pub struct LoadStoreRegister(pub u32);
249impl LoadStoreRegister {
250    fn size(&self) -> u8 {
251        (self.0 >> 30) as u8
252    }
253
254    // register name: V
255    fn is_fp_register(&self) -> bool {
256        (self.0 & 0x04000000) != 0
257    }
258
259    fn opc(&self) -> u8 {
260        ((self.0 >> 22) & 3) as u8
261    }
262
263    fn data_size<E>(&self) -> Result<LoadStoreRegisterByteCount, Error<E>> {
264        let op = self.size() << 2 | self.opc();
265        let result = match op {
266            0..=1 => LoadStoreRegisterByteCount::One,
267            2..=3 if self.is_fp_register() => LoadStoreRegisterByteCount::FloatingPoint,
268            2..=3 => LoadStoreRegisterByteCount::One,
269            4..=7 => LoadStoreRegisterByteCount::Two,
270            8..=9 => LoadStoreRegisterByteCount::Four,
271            10 if !self.is_fp_register() => LoadStoreRegisterByteCount::Four,
272            12..=13 => LoadStoreRegisterByteCount::Eight,
273            _ => {
274                return Err(Error::UnsupportedInstruction(self.0));
275            }
276        };
277        Ok(result)
278    }
279
280    fn address<T: Cpu>(
281        &self,
282        emulate: &mut EmulatorOperations<T>,
283    ) -> Result<(u64, u64), Box<Error<T::Error>>> {
284        let start_address = if self.rn() < 31 {
285            emulate.cpu.x(self.rn())
286        } else {
287            emulate.cpu.sp()
288        };
289        let end_address = match decode_load_store_group(self.0)? {
290            Aarch64DecodeLoadStoreGroup::UnscaledImmediate
291            | Aarch64DecodeLoadStoreGroup::RegisterUnprivileged
292            | Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate
293            | Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex
294            | Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex => {
295                // imm9
296                let unsigned_addr = (self.0 >> 12) & 0x1ff;
297                let signed_addr = if (unsigned_addr & 0x100) != 0 {
298                    (0xfffffe00 | unsigned_addr) as i32
299                } else {
300                    unsigned_addr as i32
301                } as i64;
302                (start_address as i64).wrapping_add(signed_addr) as u64
303            }
304            Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate => {
305                let size = self.data_size()?;
306                let shift = 10
307                    - match size {
308                        LoadStoreRegisterByteCount::One => 0,
309                        LoadStoreRegisterByteCount::Two => 1,
310                        LoadStoreRegisterByteCount::Four => 2,
311                        LoadStoreRegisterByteCount::Eight => 3,
312                        LoadStoreRegisterByteCount::FloatingPoint => 4,
313                    };
314                start_address.wrapping_add((self.0 as u64 & 0x3ffc00) >> shift)
315            }
316            Aarch64DecodeLoadStoreGroup::RegisterOffset => {
317                let rm = ((self.0 >> 16) & 0x1f) as u8;
318                let option = (self.0 >> 13) & 0x7;
319                let apply_shift = (self.0 & 0x1000) != 0;
320                let offset = if rm == 31 { 0 } else { emulate.cpu.x(rm) };
321                let offset = if (option & 1) != 0 {
322                    // 64-bit register index
323                    offset
324                } else if option == 6 && (offset & 0x80000000) != 0 {
325                    // SXTW: 32-bit sign-extended
326                    0xffffffff_00000000 | (offset & 0xffffffff)
327                } else {
328                    // UXTW or SXTW w/o the sign bit set: 32-bit unsigned
329                    offset & 0xffffffff
330                };
331                // If shift (S bit) is set, offset is in size being fetched instead of bytes.
332                let offset = if apply_shift {
333                    let size = self.data_size()?;
334                    match size {
335                        LoadStoreRegisterByteCount::One => {
336                            return Err(Box::new(Error::UnsupportedInstruction(self.0)));
337                        }
338                        LoadStoreRegisterByteCount::Two => offset << 1,
339                        LoadStoreRegisterByteCount::Four => offset << 2,
340                        LoadStoreRegisterByteCount::Eight => offset << 3,
341                        LoadStoreRegisterByteCount::FloatingPoint => offset << 4,
342                    }
343                } else {
344                    offset
345                };
346                start_address.wrapping_add(offset)
347            }
348            _ => panic!("Unsupported opcode"),
349        };
350        Ok((start_address, end_address))
351    }
352
353    fn rn(&self) -> u8 {
354        ((self.0 >> 5) & 0x1f) as u8
355    }
356
357    fn rt(&self) -> u8 {
358        (self.0 & 0x1f) as u8
359    }
360
361    pub async fn emulate<T: Cpu>(
362        &self,
363        emulate: &mut EmulatorOperations<T>,
364    ) -> Result<(), Box<Error<T::Error>>> {
365        let op_group = decode_load_store_group(self.0)?;
366        let op = self.size() << 2 | self.opc();
367        if op == 14 {
368            match op_group {
369                Aarch64DecodeLoadStoreGroup::UnscaledImmediate
370                | Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate
371                | Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate
372                | Aarch64DecodeLoadStoreGroup::RegisterOffset => {
373                    // ignore prefetch instructions
374                    return Ok(());
375                }
376                _ => {
377                    // unallocated
378                    return Err(Box::new(Error::UnsupportedInstruction(self.0)));
379                }
380            }
381        }
382        let (start_address, end_address) = self.address(emulate)?;
383        let address = if matches!(
384            op_group,
385            Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex
386        ) {
387            start_address
388        } else {
389            end_address
390        };
391        let size = self.data_size()?;
392        let register_index = self.rt();
393        tracing::info!(
394            ?op_group,
395            op,
396            start_address,
397            end_address,
398            address,
399            ?size,
400            "instruction emulation"
401        );
402        // index register: self.rn()
403        // src/dest register: self.rt()
404        // self.v() == 1: FP registers
405        // self.size() << 2 | self.opc
406        //     0 // 8-bit store
407        //     1 // 8-bit load
408        //     2 // 8-bit signed load extended to 64-bits or floating point load
409        //     3 // 8-bit signed load extended to 32-bits or floating point store
410        //     4 // 16-bit store
411        //     5 // 16-bit load
412        //     6 // 16-bit signed load extended to 64-bits
413        //     7 // 16-bit signed load extended to 32-bits
414        //     8 // 32-bit store
415        //     9 // 32-bit load
416        //    10 // 32-bit signed load load extended to 64-bits (not supported for fp)
417        //    12 // 64-bit store
418        //    13 // 64-bit load
419        //    14 // prefetch
420        match op {
421            0 | 4 | 8 | 12 => {
422                // Store registry value into memory.
423                let reg_val = if self.is_fp_register() {
424                    emulate.cpu.d(register_index).to_le_bytes()
425                } else if register_index == 31 {
426                    0_u64.to_le_bytes()
427                } else {
428                    emulate.cpu.x(register_index).to_le_bytes()
429                };
430                match size {
431                    LoadStoreRegisterByteCount::One => {
432                        emulate.write_memory(address, &reg_val[..1]).await?
433                    }
434                    LoadStoreRegisterByteCount::Two => {
435                        emulate.write_memory(address, &reg_val[..2]).await?
436                    }
437                    LoadStoreRegisterByteCount::Four => {
438                        emulate.write_memory(address, &reg_val[..4]).await?
439                    }
440                    LoadStoreRegisterByteCount::Eight => {
441                        emulate.write_memory(address, &reg_val[..8]).await?
442                    }
443                    LoadStoreRegisterByteCount::FloatingPoint => {
444                        emulate.write_memory(address, &reg_val[..]).await?
445                    }
446                }
447            }
448            2 if self.is_fp_register() => {
449                let reg_val = emulate.cpu.q(register_index).to_le_bytes();
450                emulate.write_memory(address, &reg_val[..]).await?;
451            }
452            3 if self.is_fp_register() => {
453                let mut new_val = [0_u8; 16];
454                emulate.read_memory(address, &mut new_val[..]).await?;
455                let new_val = u128::from_ne_bytes(new_val);
456                emulate.cpu.update_q(register_index, new_val);
457            }
458            1 | 2 | 3 | 5 | 6 | 7 | 9 | 10 | 13 => {
459                // Load register with new value from memory.
460                let mut buf = [0_u8; 8];
461                let new_val = match size {
462                    LoadStoreRegisterByteCount::One => {
463                        emulate.read_memory(address, &mut buf[..1]).await?;
464                        u8::from_ne_bytes(buf[..1].try_into().unwrap()) as u64
465                    }
466                    LoadStoreRegisterByteCount::Two => {
467                        emulate.read_memory(address, &mut buf[..2]).await?;
468                        u16::from_ne_bytes(buf[..2].try_into().unwrap()) as u64
469                    }
470                    LoadStoreRegisterByteCount::Four => {
471                        emulate.read_memory(address, &mut buf[..4]).await?;
472                        u32::from_ne_bytes(buf[..4].try_into().unwrap()) as u64
473                    }
474                    LoadStoreRegisterByteCount::Eight => {
475                        emulate.read_memory(address, &mut buf[..]).await?;
476                        u64::from_ne_bytes(buf[..].try_into().unwrap())
477                    }
478                    _ => return Err(Box::new(Error::UnsupportedInstruction(self.0))),
479                };
480                let new_val = if op == 2 && (new_val & 0x80) != 0 {
481                    // Sign extend a byte into eight bytes
482                    0xffffffff_ffffff00 | new_val
483                } else if op == 3 && (new_val & 0x80) != 0 {
484                    // Sign extend a byte into four bytes
485                    0xffffff00 | new_val
486                } else if op == 6 && (new_val & 0x8000) != 0 {
487                    // Sign extend two bytes into eight btes
488                    0xffffffff_ffff0000 | new_val
489                } else if op == 7 && (new_val & 0x8000) != 0 {
490                    // Sign extend two bytes into four bytes
491                    0xffff0000 | new_val
492                } else if op == 10 && (new_val & 0x80000000) != 0 {
493                    // Sign extend four bytes into eight bytes
494                    0xffffffff_00000000 | new_val
495                } else {
496                    new_val
497                };
498                if self.is_fp_register() {
499                    emulate.cpu.update_d(register_index, new_val);
500                } else if register_index != 31 {
501                    emulate.cpu.update_x(register_index, new_val);
502                }
503            }
504            _ => return Err(Box::new(Error::UnsupportedInstruction(self.0))),
505        }
506        if matches!(
507            op_group,
508            Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex
509                | Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex
510        ) {
511            // Update the index register with the end value.
512            if self.rn() < 31 {
513                emulate.cpu.update_x(self.rn(), end_address);
514            } else {
515                emulate.cpu.update_sp(end_address);
516            }
517        }
518        Ok(())
519    }
520}
521
522pub struct LoadStoreRegisterPair(pub u32);
523impl LoadStoreRegisterPair {
524    fn size<E>(
525        &self,
526        op_group: &Aarch64DecodeLoadStoreGroup,
527    ) -> Result<(LoadStoreRegisterByteCount, bool), Error<E>> {
528        let mut sign_extend = false;
529        let size = match (self.0 >> 30) as u8 {
530            0 => LoadStoreRegisterByteCount::Four,
531            1 if self.is_fp_register() => LoadStoreRegisterByteCount::Eight,
532            // Support for LDPSW; STGP not currently supported.
533            1 if self.is_load()
534                && matches!(
535                    op_group,
536                    Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex
537                        | Aarch64DecodeLoadStoreGroup::RegisterPairOffset
538                        | Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex
539                ) =>
540            {
541                sign_extend = true;
542                LoadStoreRegisterByteCount::Four
543            }
544            2 if self.is_fp_register() => LoadStoreRegisterByteCount::FloatingPoint,
545            2 => LoadStoreRegisterByteCount::Eight,
546            _ => {
547                return Err(Error::UnsupportedInstruction(self.0));
548            }
549        };
550        Ok((size, sign_extend))
551    }
552
553    // register name: V
554    fn is_fp_register(&self) -> bool {
555        (self.0 & 0x04000000) != 0
556    }
557
558    fn is_load(&self) -> bool {
559        (self.0 & 0x00400000) != 0
560    }
561
562    fn imm(&self) -> i64 {
563        let unsigned = ((self.0 >> 15) & 0x7f) as u16;
564        if (unsigned & 0x40) != 0 {
565            (0xff80 | unsigned) as i16 as i64
566        } else {
567            unsigned as i64
568        }
569    }
570
571    fn rt2(&self) -> u8 {
572        ((self.0 >> 10) & 0x1f) as u8
573    }
574
575    fn rn(&self) -> u8 {
576        ((self.0 >> 5) & 0x1f) as u8
577    }
578
579    fn rt(&self) -> u8 {
580        (self.0 & 0x1f) as u8
581    }
582
583    pub async fn emulate<T: Cpu>(
584        &self,
585        emulate: &mut EmulatorOperations<T>,
586    ) -> Result<(), Box<Error<T::Error>>> {
587        let op_group = decode_load_store_group(self.0)?;
588        // p649
589        let (size, sign_extend) = self.size(&op_group)?;
590        let size_bytes: usize = match size {
591            LoadStoreRegisterByteCount::Four => 4,
592            LoadStoreRegisterByteCount::Eight => 8,
593            LoadStoreRegisterByteCount::FloatingPoint => 16,
594            _ => {
595                return Err(Box::new(Error::UnsupportedInstruction(self.0)));
596            }
597        };
598        let start_address = if self.rn() != 31 {
599            emulate.cpu.x(self.rn())
600        } else {
601            emulate.cpu.sp()
602        };
603        let end_address = (start_address as i64 + self.imm() * (size_bytes as i64)) as u64;
604        let address = if matches!(op_group, Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex) {
605            start_address
606        } else {
607            end_address
608        };
609        if self.is_load() {
610            // N.B. We could read both values at once, but many of our virtual
611            //      devices' MMIO handlers expect specific sizes, so break the
612            //      operation into two separate accesses.
613            let mut value = [0_u8; 16];
614            let get_val = |val: &[u8]| match size {
615                LoadStoreRegisterByteCount::Four => {
616                    let val = u32::from_le_bytes(val.try_into().unwrap());
617                    if sign_extend && (val & 0x80000000) != 0 {
618                        val as u128 | 0xffffffff_00000000
619                    } else {
620                        val as u128
621                    }
622                }
623                LoadStoreRegisterByteCount::Eight => {
624                    u64::from_le_bytes(val.try_into().unwrap()) as u128
625                }
626                LoadStoreRegisterByteCount::FloatingPoint => {
627                    u128::from_le_bytes(val.try_into().unwrap())
628                }
629                _ => unreachable!(),
630            };
631            let val = &mut value[..size_bytes];
632            let val1 = {
633                emulate.read_memory(address, val).await?;
634                get_val(val)
635            };
636            let val2 = {
637                emulate
638                    .read_memory(address + (size_bytes as u64), val)
639                    .await?;
640                get_val(val)
641            };
642            if self.is_fp_register() {
643                emulate.cpu.update_q(self.rt(), val1);
644            } else if self.rt() != 31 {
645                emulate.cpu.update_x(self.rt(), val1 as u64);
646            }
647            if self.is_fp_register() {
648                emulate.cpu.update_q(self.rt2(), val2);
649            } else if self.rt2() != 31 {
650                emulate.cpu.update_x(self.rt2(), val2 as u64);
651            }
652        } else {
653            let mut value = [0_u8; 16];
654            let val1 = if self.is_fp_register() {
655                emulate.cpu.q(self.rt())
656            } else if self.rt() != 31 {
657                emulate.cpu.x(self.rt()) as u128
658            } else {
659                0
660            };
661            let val2 = if self.is_fp_register() {
662                emulate.cpu.q(self.rt2())
663            } else if self.rt2() != 31 {
664                emulate.cpu.x(self.rt2()) as u128
665            } else {
666                0
667            };
668            let get_val = |val: u128| match size {
669                LoadStoreRegisterByteCount::Four => {
670                    ((val & 0xffffffff) as u32).to_le_bytes().to_vec()
671                }
672                LoadStoreRegisterByteCount::Eight => {
673                    ((val & 0xffffffff_ffffffff) as u64).to_le_bytes().to_vec()
674                }
675                LoadStoreRegisterByteCount::FloatingPoint => val.to_le_bytes().to_vec(),
676                _ => unreachable!(),
677            };
678            // N.B. We could write both values at once, but many of our virtual
679            //      devices' MMIO handlers expect specific sizes, so break the
680            //      operation into two separate accesses.
681            value[..size_bytes].copy_from_slice(get_val(val1).as_slice());
682            emulate.write_memory(address, &value[..size_bytes]).await?;
683            value[..size_bytes].copy_from_slice(get_val(val2).as_slice());
684            emulate.write_memory(address, &value[..size_bytes]).await?;
685        }
686        if matches!(
687            op_group,
688            Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex
689                | Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex
690        ) {
691            // Update the index register with the end value.
692            if self.rn() < 31 {
693                emulate.cpu.update_x(self.rn(), end_address);
694            } else {
695                emulate.cpu.update_sp(end_address);
696            }
697        }
698        Ok(())
699    }
700}
701
702pub struct LoadStoreAtomic(pub u32);
703impl LoadStoreAtomic {
704    fn size(&self) -> u64 {
705        1 << (self.0 >> 30)
706    }
707
708    fn rs(&self) -> u8 {
709        ((self.0 >> 16) & 0x1f) as u8
710    }
711
712    fn op3_opc(&self) -> u8 {
713        ((self.0 >> 12) & 0xf) as u8
714    }
715
716    fn rn(&self) -> u8 {
717        ((self.0 >> 5) & 0x1f) as u8
718    }
719
720    fn rt(&self) -> u8 {
721        (self.0 & 0x1f) as u8
722    }
723
724    pub async fn emulate<T: Cpu>(
725        &self,
726        emulate: &mut EmulatorOperations<T>,
727    ) -> Result<(), Box<Error<T::Error>>> {
728        let rn = self.rn();
729        let address = if rn < 31 {
730            emulate.cpu.x(self.rn())
731        } else {
732            emulate.cpu.sp()
733        };
734        let size = self.size();
735        let size_mask = if size < 8 {
736            (1 << (8 * self.size())) - 1
737        } else {
738            0xffffffff_ffffffff
739        };
740        let rt = self.rt();
741        let rs = self.rs();
742        let update_val = if rs != 31 {
743            emulate.cpu.x(rs) & size_mask
744        } else {
745            0
746        };
747        loop {
748            let mut value_buf = [0_u8; 8];
749            emulate.read_memory(address, &mut value_buf).await?;
750            let value = u64::from_le_bytes(value_buf);
751            let sized_value = value & size_mask;
752            let new_value = match self.op3_opc() {
753                0 => sized_value.wrapping_add(update_val),
754                1 => sized_value & !update_val,
755                2 => sized_value ^ update_val,
756                3 => sized_value | update_val,
757                4 => match size {
758                    1 => (sized_value as i8).max(update_val as i8) as u64,
759                    2 => (sized_value as i16).max(update_val as i16) as u64,
760                    4 => (sized_value as i32).max(update_val as i32) as u64,
761                    8 => (sized_value as i64).max(update_val as i64) as u64,
762                    _ => unreachable!(),
763                },
764                5 => match size {
765                    1 => (sized_value as i8).min(update_val as i8) as u64,
766                    2 => (sized_value as i16).min(update_val as i16) as u64,
767                    4 => (sized_value as i32).min(update_val as i32) as u64,
768                    8 => (sized_value as i64).min(update_val as i64) as u64,
769                    _ => unreachable!(),
770                },
771                6 => sized_value.max(update_val),
772                7 => sized_value.min(update_val),
773                8 => update_val,
774                12 => value,
775                _ => {
776                    return Err(Box::new(Error::UnsupportedLoadStoreInstruction(
777                        Aarch64DecodeLoadStoreGroup::Atomic,
778                        self.0,
779                    )));
780                }
781            };
782            let new_value = value & !size_mask | new_value & size_mask;
783            if emulate
784                .compare_and_write_memory(address, &value_buf, &new_value.to_le_bytes()[..])
785                .await?
786            {
787                if rt != 31 {
788                    emulate.cpu.update_x(rt, sized_value);
789                }
790                break;
791            }
792        }
793        Ok(())
794    }
795}
796
797#[cfg(test)]
798mod tests {
799    use super::*;
800
801    #[test]
802    fn verify_groups() {
803        let check_groups = [
804            (0, Aarch64DecodeGroup::Reserved),
805            (0x80000000, Aarch64DecodeGroup::ScalableMatrixExtension),
806            (0x04000000, Aarch64DecodeGroup::ScalableVectorExtension),
807            (0x84000000, Aarch64DecodeGroup::ScalableVectorExtension),
808            (0x10000000, Aarch64DecodeGroup::ImmediateData),
809            (0x12000000, Aarch64DecodeGroup::ImmediateData),
810            (0x90000000, Aarch64DecodeGroup::ImmediateData),
811            (0x92000000, Aarch64DecodeGroup::ImmediateData),
812            (0x14000000, Aarch64DecodeGroup::BranchesExceptionsAndSystem),
813            (0x16000000, Aarch64DecodeGroup::BranchesExceptionsAndSystem),
814            (0x94000000, Aarch64DecodeGroup::BranchesExceptionsAndSystem),
815            (0x96000000, Aarch64DecodeGroup::BranchesExceptionsAndSystem),
816            (0x0a000000, Aarch64DecodeGroup::RegisterData),
817            (0x1a000000, Aarch64DecodeGroup::RegisterData),
818            (0x8a000000, Aarch64DecodeGroup::RegisterData),
819            (0x9a000000, Aarch64DecodeGroup::RegisterData),
820            (0x0e000000, Aarch64DecodeGroup::FpAndAdvancedData),
821            (0x1e000000, Aarch64DecodeGroup::FpAndAdvancedData),
822            (0x8e000000, Aarch64DecodeGroup::FpAndAdvancedData),
823            (0x9e000000, Aarch64DecodeGroup::FpAndAdvancedData),
824        ];
825        for (opcode, expected) in check_groups {
826            match decode_group::<()>(opcode) {
827                Ok(result) => {
828                    if result != expected {
829                        panic!(
830                            "{:08x} generated {:?}, expected {:?}",
831                            opcode, result, expected
832                        )
833                    }
834                }
835                Err(err) => panic!(
836                    "{:08x} failed with {}, expected {:?}",
837                    opcode, err, expected
838                ),
839            }
840        }
841
842        let check_invalid_groups = [0x02000000, 0x82000000, 0x06000000, 0x86000000];
843        for opcode in check_invalid_groups {
844            assert!(
845                decode_group::<()>(opcode).is_err(),
846                "{:08x} expected to be invalid",
847                opcode,
848            );
849        }
850    }
851
852    #[test]
853    fn verify_load_store_groups() {
854        let check_groups = [
855            (0x08200000, Aarch64DecodeLoadStoreGroup::CompareAndSwapPair),
856            (0x083f0000, Aarch64DecodeLoadStoreGroup::CompareAndSwapPair),
857            (0x48200000, Aarch64DecodeLoadStoreGroup::CompareAndSwapPair),
858            (0x483f0000, Aarch64DecodeLoadStoreGroup::CompareAndSwapPair),
859            (0x08000000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
860            (0x08010000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
861            (0x08020000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
862            (0x08040000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
863            (0x08080000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
864            (0x08100000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
865            (0x48000000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
866            (0x481f0000, Aarch64DecodeLoadStoreGroup::ExclusiveRegister),
867            (0x88200000, Aarch64DecodeLoadStoreGroup::ExclusivePair),
868            (0x883f0000, Aarch64DecodeLoadStoreGroup::ExclusivePair),
869            (0xc8200000, Aarch64DecodeLoadStoreGroup::ExclusivePair),
870            (0xc83f0000, Aarch64DecodeLoadStoreGroup::ExclusivePair),
871            (0x08800000, Aarch64DecodeLoadStoreGroup::Ordered),
872            (0x08810000, Aarch64DecodeLoadStoreGroup::Ordered),
873            (0x08820000, Aarch64DecodeLoadStoreGroup::Ordered),
874            (0x08840000, Aarch64DecodeLoadStoreGroup::Ordered),
875            (0x08880000, Aarch64DecodeLoadStoreGroup::Ordered),
876            (0x08900000, Aarch64DecodeLoadStoreGroup::Ordered),
877            (0x08a00000, Aarch64DecodeLoadStoreGroup::CompareAndSwap),
878            (0x08a10000, Aarch64DecodeLoadStoreGroup::CompareAndSwap),
879            (0x08a20000, Aarch64DecodeLoadStoreGroup::CompareAndSwap),
880            (0x08a40000, Aarch64DecodeLoadStoreGroup::CompareAndSwap),
881            (0x08a80000, Aarch64DecodeLoadStoreGroup::CompareAndSwap),
882            (0x08b00000, Aarch64DecodeLoadStoreGroup::CompareAndSwap),
883            (
884                0x0c000000,
885                Aarch64DecodeLoadStoreGroup::AdvancedSimdMultiStruct,
886            ),
887            (
888                0x0c800000,
889                Aarch64DecodeLoadStoreGroup::AdvancedSimdMultiStructPostIndex,
890            ),
891            (
892                0x4c800000,
893                Aarch64DecodeLoadStoreGroup::AdvancedSimdMultiStructPostIndex,
894            ),
895            (0x0d000000, Aarch64DecodeLoadStoreGroup::AdvancedSimd),
896            (0x4d000000, Aarch64DecodeLoadStoreGroup::AdvancedSimd),
897            (0x0d200000, Aarch64DecodeLoadStoreGroup::AdvancedSimd),
898            (0x4d200000, Aarch64DecodeLoadStoreGroup::AdvancedSimd),
899            (
900                0x0d800000,
901                Aarch64DecodeLoadStoreGroup::AdvancedSimdPostIndex,
902            ),
903            (
904                0x4d800000,
905                Aarch64DecodeLoadStoreGroup::AdvancedSimdPostIndex,
906            ),
907            (0xd9200000, Aarch64DecodeLoadStoreGroup::MemoryTags),
908            (0xd9210000, Aarch64DecodeLoadStoreGroup::MemoryTags),
909            (0xd9220000, Aarch64DecodeLoadStoreGroup::MemoryTags),
910            (0xd9240000, Aarch64DecodeLoadStoreGroup::MemoryTags),
911            (0xd9280000, Aarch64DecodeLoadStoreGroup::MemoryTags),
912            (0xd9300000, Aarch64DecodeLoadStoreGroup::MemoryTags),
913            (0x19000000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
914            (0x19010000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
915            (0x19020000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
916            (0x19040000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
917            (0x19080000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
918            (0x19100000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
919            (0x59000000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
920            (0x59010000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
921            (0x59020000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
922            (0x59040000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
923            (0x59080000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
924            (0x59100000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
925            (0x99000000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
926            (0x99010000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
927            (0x99020000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
928            (0x99040000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
929            (0x99080000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
930            (0x99100000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
931            (0xd9000000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
932            (0xd9010000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
933            (0xd9020000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
934            (0xd9040000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
935            (0xd9080000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
936            (0xd9100000, Aarch64DecodeLoadStoreGroup::UnscaledImmediate),
937            (0x19000400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
938            (0x19010400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
939            (0x19020400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
940            (0x19040400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
941            (0x19080400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
942            (0x19100400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
943            (0x59000400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
944            (0x59010400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
945            (0x59020400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
946            (0x59040400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
947            (0x59080400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
948            (0x59100400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
949            (0x99000400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
950            (0x99010400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
951            (0x99020400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
952            (0x99040400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
953            (0x99080400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
954            (0x99100400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
955            (0xd9000400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
956            (0xd9010400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
957            (0xd9020400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
958            (0xd9040400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
959            (0xd9080400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
960            (0xd9100400, Aarch64DecodeLoadStoreGroup::MemoryCopyAndSet),
961            (0x18000000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
962            (0x18800000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
963            (0x58000000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
964            (0x58800000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
965            (0x98000000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
966            (0x98800000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
967            (0xd8000000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
968            (0xd8800000, Aarch64DecodeLoadStoreGroup::RegisterLiteral),
969            (0x28000000, Aarch64DecodeLoadStoreGroup::NoAllocatePair),
970            (0x6c000000, Aarch64DecodeLoadStoreGroup::NoAllocatePair),
971            (0xac000000, Aarch64DecodeLoadStoreGroup::NoAllocatePair),
972            (0xe8000000, Aarch64DecodeLoadStoreGroup::NoAllocatePair),
973            (
974                0x28800000,
975                Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex,
976            ),
977            (
978                0x6c800000,
979                Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex,
980            ),
981            (
982                0xac800000,
983                Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex,
984            ),
985            (
986                0xe8800000,
987                Aarch64DecodeLoadStoreGroup::RegisterPairPostIndex,
988            ),
989            (0x29000000, Aarch64DecodeLoadStoreGroup::RegisterPairOffset),
990            (0x6d000000, Aarch64DecodeLoadStoreGroup::RegisterPairOffset),
991            (0xad000000, Aarch64DecodeLoadStoreGroup::RegisterPairOffset),
992            (0xe9000000, Aarch64DecodeLoadStoreGroup::RegisterPairOffset),
993            (
994                0x29800000,
995                Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex,
996            ),
997            (
998                0x6d800000,
999                Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex,
1000            ),
1001            (
1002                0xad800000,
1003                Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex,
1004            ),
1005            (
1006                0xe9800000,
1007                Aarch64DecodeLoadStoreGroup::RegisterPairPreIndex,
1008            ),
1009            (
1010                0x39000000,
1011                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1012            ),
1013            (
1014                0x3d800000,
1015                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1016            ),
1017            (
1018                0x7d000000,
1019                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1020            ),
1021            (
1022                0x79800000,
1023                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1024            ),
1025            (
1026                0xb9000000,
1027                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1028            ),
1029            (
1030                0xbd800000,
1031                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1032            ),
1033            (
1034                0xfd000000,
1035                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1036            ),
1037            (
1038                0xf9800000,
1039                Aarch64DecodeLoadStoreGroup::RegisterUnsignedImmediate,
1040            ),
1041            (
1042                0x38000000,
1043                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1044            ),
1045            (
1046                0x3c010000,
1047                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1048            ),
1049            (
1050                0x3c020000,
1051                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1052            ),
1053            (
1054                0x38040000,
1055                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1056            ),
1057            (
1058                0x38080000,
1059                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1060            ),
1061            (
1062                0x3c100000,
1063                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1064            ),
1065            (
1066                0x3c810000,
1067                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1068            ),
1069            (
1070                0x38820000,
1071                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1072            ),
1073            (
1074                0x38840000,
1075                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1076            ),
1077            (
1078                0x3c880000,
1079                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1080            ),
1081            (
1082                0x3c900000,
1083                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1084            ),
1085            (
1086                0x78000000,
1087                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1088            ),
1089            (
1090                0x78010000,
1091                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1092            ),
1093            (
1094                0x7c020000,
1095                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1096            ),
1097            (
1098                0x7c040000,
1099                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1100            ),
1101            (
1102                0x78080000,
1103                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1104            ),
1105            (
1106                0x78100000,
1107                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1108            ),
1109            (
1110                0x7c810000,
1111                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1112            ),
1113            (
1114                0x7c820000,
1115                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1116            ),
1117            (
1118                0x7c840000,
1119                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1120            ),
1121            (
1122                0x78880000,
1123                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1124            ),
1125            (
1126                0x78900000,
1127                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1128            ),
1129            (
1130                0xbc000000,
1131                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1132            ),
1133            (
1134                0xbc010000,
1135                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1136            ),
1137            (
1138                0xb8020000,
1139                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1140            ),
1141            (
1142                0xb8040000,
1143                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1144            ),
1145            (
1146                0xbc080000,
1147                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1148            ),
1149            (
1150                0xbc100000,
1151                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1152            ),
1153            (
1154                0xb8810000,
1155                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1156            ),
1157            (
1158                0xb8820000,
1159                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1160            ),
1161            (
1162                0xbc840000,
1163                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1164            ),
1165            (
1166                0xbc880000,
1167                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1168            ),
1169            (
1170                0xb8900000,
1171                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1172            ),
1173            (
1174                0xf8000000,
1175                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1176            ),
1177            (
1178                0xfc010000,
1179                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1180            ),
1181            (
1182                0xfc020000,
1183                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1184            ),
1185            (
1186                0xf8040000,
1187                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1188            ),
1189            (
1190                0xf8080000,
1191                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1192            ),
1193            (
1194                0xfc100000,
1195                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1196            ),
1197            (
1198                0xfc810000,
1199                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1200            ),
1201            (
1202                0xf8820000,
1203                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1204            ),
1205            (
1206                0xf8840000,
1207                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1208            ),
1209            (
1210                0xfc880000,
1211                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1212            ),
1213            (
1214                0xfc900000,
1215                Aarch64DecodeLoadStoreGroup::RegisterUnscaledImmediate,
1216            ),
1217            (0x38200000, Aarch64DecodeLoadStoreGroup::Atomic),
1218            (0x38210000, Aarch64DecodeLoadStoreGroup::Atomic),
1219            (0x3c220000, Aarch64DecodeLoadStoreGroup::Atomic),
1220            (0x3c240000, Aarch64DecodeLoadStoreGroup::Atomic),
1221            (0x38280000, Aarch64DecodeLoadStoreGroup::Atomic),
1222            (0x38300000, Aarch64DecodeLoadStoreGroup::Atomic),
1223            (0x3ca10000, Aarch64DecodeLoadStoreGroup::Atomic),
1224            (0x3ca20000, Aarch64DecodeLoadStoreGroup::Atomic),
1225            (0x38a40000, Aarch64DecodeLoadStoreGroup::Atomic),
1226            (0x38a80000, Aarch64DecodeLoadStoreGroup::Atomic),
1227            (0x3cb00000, Aarch64DecodeLoadStoreGroup::Atomic),
1228            (0x7c200000, Aarch64DecodeLoadStoreGroup::Atomic),
1229            (0x78210000, Aarch64DecodeLoadStoreGroup::Atomic),
1230            (0x78220000, Aarch64DecodeLoadStoreGroup::Atomic),
1231            (0x7c240000, Aarch64DecodeLoadStoreGroup::Atomic),
1232            (0x7c280000, Aarch64DecodeLoadStoreGroup::Atomic),
1233            (0x78300000, Aarch64DecodeLoadStoreGroup::Atomic),
1234            (0x78a10000, Aarch64DecodeLoadStoreGroup::Atomic),
1235            (0x7ca20000, Aarch64DecodeLoadStoreGroup::Atomic),
1236            (0x7ca40000, Aarch64DecodeLoadStoreGroup::Atomic),
1237            (0x78a80000, Aarch64DecodeLoadStoreGroup::Atomic),
1238            (0x78b00000, Aarch64DecodeLoadStoreGroup::Atomic),
1239            (0xbc200000, Aarch64DecodeLoadStoreGroup::Atomic),
1240            (0xbc210000, Aarch64DecodeLoadStoreGroup::Atomic),
1241            (0xb8220000, Aarch64DecodeLoadStoreGroup::Atomic),
1242            (0xb8240000, Aarch64DecodeLoadStoreGroup::Atomic),
1243            (0xbc280000, Aarch64DecodeLoadStoreGroup::Atomic),
1244            (0xbc300000, Aarch64DecodeLoadStoreGroup::Atomic),
1245            (0xb8a10000, Aarch64DecodeLoadStoreGroup::Atomic),
1246            (0xb8a20000, Aarch64DecodeLoadStoreGroup::Atomic),
1247            (0xbca40000, Aarch64DecodeLoadStoreGroup::Atomic),
1248            (0xbca80000, Aarch64DecodeLoadStoreGroup::Atomic),
1249            (0xb8b00000, Aarch64DecodeLoadStoreGroup::Atomic),
1250            (0xf8200000, Aarch64DecodeLoadStoreGroup::Atomic),
1251            (0xfc210000, Aarch64DecodeLoadStoreGroup::Atomic),
1252            (0xfc220000, Aarch64DecodeLoadStoreGroup::Atomic),
1253            (0xf8240000, Aarch64DecodeLoadStoreGroup::Atomic),
1254            (0xf8280000, Aarch64DecodeLoadStoreGroup::Atomic),
1255            (0xfc300000, Aarch64DecodeLoadStoreGroup::Atomic),
1256            (0xfca10000, Aarch64DecodeLoadStoreGroup::Atomic),
1257            (0xf8a20000, Aarch64DecodeLoadStoreGroup::Atomic),
1258            (0xf8a40000, Aarch64DecodeLoadStoreGroup::Atomic),
1259            (0xfca80000, Aarch64DecodeLoadStoreGroup::Atomic),
1260            (0xfcb00000, Aarch64DecodeLoadStoreGroup::Atomic),
1261            (
1262                0x38000400,
1263                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1264            ),
1265            (
1266                0x38010400,
1267                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1268            ),
1269            (
1270                0x3c020400,
1271                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1272            ),
1273            (
1274                0x3c040400,
1275                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1276            ),
1277            (
1278                0x38080400,
1279                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1280            ),
1281            (
1282                0x38100400,
1283                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1284            ),
1285            (
1286                0x3c810400,
1287                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1288            ),
1289            (
1290                0x3c820400,
1291                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1292            ),
1293            (
1294                0x38840400,
1295                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1296            ),
1297            (
1298                0x38880400,
1299                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1300            ),
1301            (
1302                0x3c100400,
1303                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1304            ),
1305            (
1306                0x7c000400,
1307                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1308            ),
1309            (
1310                0x78010400,
1311                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1312            ),
1313            (
1314                0x78020400,
1315                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1316            ),
1317            (
1318                0x7c040400,
1319                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1320            ),
1321            (
1322                0x7c080400,
1323                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1324            ),
1325            (
1326                0x78100400,
1327                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1328            ),
1329            (
1330                0x78810400,
1331                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1332            ),
1333            (
1334                0x7c820400,
1335                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1336            ),
1337            (
1338                0x7c840400,
1339                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1340            ),
1341            (
1342                0x78880400,
1343                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1344            ),
1345            (
1346                0x78900400,
1347                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1348            ),
1349            (
1350                0xbc000400,
1351                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1352            ),
1353            (
1354                0xbc010400,
1355                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1356            ),
1357            (
1358                0xb8020400,
1359                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1360            ),
1361            (
1362                0xb8040400,
1363                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1364            ),
1365            (
1366                0xbc080400,
1367                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1368            ),
1369            (
1370                0xbc100400,
1371                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1372            ),
1373            (
1374                0xb8810400,
1375                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1376            ),
1377            (
1378                0xb8820400,
1379                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1380            ),
1381            (
1382                0xbc840400,
1383                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1384            ),
1385            (
1386                0xbc880400,
1387                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1388            ),
1389            (
1390                0xb8900400,
1391                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1392            ),
1393            (
1394                0xf8000400,
1395                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1396            ),
1397            (
1398                0xfc010400,
1399                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1400            ),
1401            (
1402                0xfc020400,
1403                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1404            ),
1405            (
1406                0xf8040400,
1407                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1408            ),
1409            (
1410                0xf8080400,
1411                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1412            ),
1413            (
1414                0xfc100400,
1415                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1416            ),
1417            (
1418                0xfc810400,
1419                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1420            ),
1421            (
1422                0xf8820400,
1423                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1424            ),
1425            (
1426                0xf8840400,
1427                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1428            ),
1429            (
1430                0xfc880400,
1431                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1432            ),
1433            (
1434                0xfc900400,
1435                Aarch64DecodeLoadStoreGroup::RegisterImmediatePostIndex,
1436            ),
1437            (
1438                0x38000800,
1439                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1440            ),
1441            (
1442                0x38010800,
1443                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1444            ),
1445            (
1446                0x3c020800,
1447                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1448            ),
1449            (
1450                0x3c040800,
1451                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1452            ),
1453            (
1454                0x38080800,
1455                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1456            ),
1457            (
1458                0x38100800,
1459                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1460            ),
1461            (
1462                0x3c810800,
1463                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1464            ),
1465            (
1466                0x3c820800,
1467                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1468            ),
1469            (
1470                0x38840800,
1471                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1472            ),
1473            (
1474                0x38880800,
1475                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1476            ),
1477            (
1478                0x3c900800,
1479                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1480            ),
1481            (
1482                0x7c000800,
1483                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1484            ),
1485            (
1486                0x78010800,
1487                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1488            ),
1489            (
1490                0x78020800,
1491                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1492            ),
1493            (
1494                0x7c040800,
1495                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1496            ),
1497            (
1498                0x7c080800,
1499                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1500            ),
1501            (
1502                0x78100800,
1503                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1504            ),
1505            (
1506                0x78810800,
1507                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1508            ),
1509            (
1510                0x7c820800,
1511                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1512            ),
1513            (
1514                0x7c840800,
1515                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1516            ),
1517            (
1518                0x78880800,
1519                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1520            ),
1521            (
1522                0x78900800,
1523                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1524            ),
1525            (
1526                0xbc000800,
1527                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1528            ),
1529            (
1530                0xbc010800,
1531                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1532            ),
1533            (
1534                0xb8020800,
1535                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1536            ),
1537            (
1538                0xb8040800,
1539                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1540            ),
1541            (
1542                0xbc080800,
1543                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1544            ),
1545            (
1546                0xbc100800,
1547                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1548            ),
1549            (
1550                0xb8810800,
1551                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1552            ),
1553            (
1554                0xb8820800,
1555                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1556            ),
1557            (
1558                0xbc840800,
1559                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1560            ),
1561            (
1562                0xbc880800,
1563                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1564            ),
1565            (
1566                0xb8900800,
1567                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1568            ),
1569            (
1570                0xf8000800,
1571                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1572            ),
1573            (
1574                0xfc010800,
1575                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1576            ),
1577            (
1578                0xfc020800,
1579                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1580            ),
1581            (
1582                0xf8040800,
1583                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1584            ),
1585            (
1586                0xf8080800,
1587                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1588            ),
1589            (
1590                0xfc100800,
1591                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1592            ),
1593            (
1594                0xfc810800,
1595                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1596            ),
1597            (
1598                0xf8820800,
1599                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1600            ),
1601            (
1602                0xf8840800,
1603                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1604            ),
1605            (
1606                0xfc880800,
1607                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1608            ),
1609            (
1610                0xfc900800,
1611                Aarch64DecodeLoadStoreGroup::RegisterUnprivileged,
1612            ),
1613            (0x38200800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1614            (0x38210800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1615            (0x3c220800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1616            (0x3c240800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1617            (0x38280800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1618            (0x38300800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1619            (0x3ca10800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1620            (0x3ca20800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1621            (0x38a40800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1622            (0x38a80800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1623            (0x3cb00800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1624            (0x7c200800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1625            (0x78210800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1626            (0x78220800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1627            (0x7c240800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1628            (0x7c280800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1629            (0x78300800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1630            (0x78a10800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1631            (0x7ca20800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1632            (0x7ca40800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1633            (0x78a80800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1634            (0x78b00800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1635            (0xbc200800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1636            (0xbc210800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1637            (0xb8220800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1638            (0xb8240800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1639            (0xbc280800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1640            (0xbc300800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1641            (0xb8a10800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1642            (0xb8a20800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1643            (0xbca40800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1644            (0xbca80800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1645            (0xb8b00800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1646            (0xf8200800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1647            (0xfc210800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1648            (0xfc220800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1649            (0xf8240800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1650            (0xf8280800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1651            (0xfc300800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1652            (0xfca10800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1653            (0xf8a20800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1654            (0xf8a40800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1655            (0xfca80800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1656            (0xfcb00800, Aarch64DecodeLoadStoreGroup::RegisterOffset),
1657            (
1658                0x38000c00,
1659                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1660            ),
1661            (
1662                0x38010c00,
1663                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1664            ),
1665            (
1666                0x3c020c00,
1667                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1668            ),
1669            (
1670                0x3c040c00,
1671                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1672            ),
1673            (
1674                0x38080c00,
1675                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1676            ),
1677            (
1678                0x38100c00,
1679                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1680            ),
1681            (
1682                0x3c810c00,
1683                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1684            ),
1685            (
1686                0x3c820c00,
1687                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1688            ),
1689            (
1690                0x38840c00,
1691                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1692            ),
1693            (
1694                0x38880c00,
1695                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1696            ),
1697            (
1698                0x3c900c00,
1699                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1700            ),
1701            (
1702                0x7c000c00,
1703                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1704            ),
1705            (
1706                0x78010c00,
1707                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1708            ),
1709            (
1710                0x78020c00,
1711                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1712            ),
1713            (
1714                0x7c040c00,
1715                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1716            ),
1717            (
1718                0x7c080c00,
1719                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1720            ),
1721            (
1722                0x78100c00,
1723                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1724            ),
1725            (
1726                0x78810c00,
1727                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1728            ),
1729            (
1730                0x7c820c00,
1731                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1732            ),
1733            (
1734                0x7c840c00,
1735                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1736            ),
1737            (
1738                0x78880c00,
1739                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1740            ),
1741            (
1742                0x78900c00,
1743                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1744            ),
1745            (
1746                0xbc000c00,
1747                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1748            ),
1749            (
1750                0xbc010c00,
1751                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1752            ),
1753            (
1754                0xb8020c00,
1755                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1756            ),
1757            (
1758                0xb8040c00,
1759                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1760            ),
1761            (
1762                0xbc080c00,
1763                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1764            ),
1765            (
1766                0xbc100c00,
1767                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1768            ),
1769            (
1770                0xb8810c00,
1771                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1772            ),
1773            (
1774                0xb8820c00,
1775                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1776            ),
1777            (
1778                0xbc840c00,
1779                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1780            ),
1781            (
1782                0xbc880c00,
1783                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1784            ),
1785            (
1786                0xb8900c00,
1787                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1788            ),
1789            (
1790                0xf8000c00,
1791                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1792            ),
1793            (
1794                0xfc010c00,
1795                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1796            ),
1797            (
1798                0xfc020c00,
1799                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1800            ),
1801            (
1802                0xf8040c00,
1803                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1804            ),
1805            (
1806                0xf8080c00,
1807                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1808            ),
1809            (
1810                0xfc100c00,
1811                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1812            ),
1813            (
1814                0xfc810c00,
1815                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1816            ),
1817            (
1818                0xf8820c00,
1819                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1820            ),
1821            (
1822                0xf8840c00,
1823                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1824            ),
1825            (
1826                0xfc880c00,
1827                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1828            ),
1829            (
1830                0xfc900c00,
1831                Aarch64DecodeLoadStoreGroup::RegisterImmediatePreIndex,
1832            ),
1833            (0x38200400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1834            (0x38210400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1835            (0x3c220400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1836            (0x3c240400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1837            (0x38280400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1838            (0x38300400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1839            (0x3ca10400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1840            (0x3ca20400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1841            (0x38a40400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1842            (0x38a80400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1843            (0x3cb00400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1844            (0x7c200400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1845            (0x78210400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1846            (0x78220400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1847            (0x7c240400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1848            (0x7c280400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1849            (0x78300400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1850            (0x78a10400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1851            (0x7ca20400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1852            (0x7ca40400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1853            (0x78a80400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1854            (0x78b00400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1855            (0xbc200400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1856            (0xbc210400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1857            (0xb8220400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1858            (0xb8240400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1859            (0xbc280400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1860            (0xbc300400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1861            (0xb8a10400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1862            (0xb8a20400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1863            (0xbca40400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1864            (0xbca80400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1865            (0xb8b00400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1866            (0xf8200400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1867            (0xfc210400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1868            (0xfc220400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1869            (0xf8240400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1870            (0xf8280400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1871            (0xfc300400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1872            (0xfca10400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1873            (0xf8a20400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1874            (0xf8a40400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1875            (0xfca80400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1876            (0xfcb00400, Aarch64DecodeLoadStoreGroup::RegisterPac),
1877            (0x38200c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1878            (0x38210c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1879            (0x3c220c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1880            (0x3c240c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1881            (0x38280c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1882            (0x38300c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1883            (0x3ca10c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1884            (0x3ca20c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1885            (0x38a40c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1886            (0x38a80c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1887            (0x3cb00c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1888            (0x7c200c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1889            (0x78210c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1890            (0x78220c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1891            (0x7c240c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1892            (0x7c280c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1893            (0x78300c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1894            (0x78a10c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1895            (0x7ca20c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1896            (0x7ca40c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1897            (0x78a80c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1898            (0x78b00c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1899            (0xbc200c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1900            (0xbc210c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1901            (0xb8220c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1902            (0xb8240c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1903            (0xbc280c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1904            (0xbc300c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1905            (0xb8a10c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1906            (0xb8a20c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1907            (0xbca40c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1908            (0xbca80c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1909            (0xb8b00c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1910            (0xf8200c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1911            (0xfc210c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1912            (0xfc220c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1913            (0xf8240c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1914            (0xf8280c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1915            (0xfc300c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1916            (0xfca10c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1917            (0xf8a20c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1918            (0xf8a40c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1919            (0xfca80c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1920            (0xfcb00c00, Aarch64DecodeLoadStoreGroup::RegisterPac),
1921        ];
1922        for (opcode, expected) in check_groups {
1923            match decode_group::<()>(opcode) {
1924                Ok(result) => {
1925                    let expected = Aarch64DecodeGroup::LoadStore(expected);
1926                    if result != expected {
1927                        panic!(
1928                            "{:08x} generated {:?}, expected {:?}",
1929                            opcode, result, expected
1930                        )
1931                    }
1932                }
1933                Err(err) => panic!(
1934                    "{:08x} failed with {}, expected {:?}",
1935                    opcode, err, expected
1936                ),
1937            }
1938        }
1939        let check_invalid_groups = [
1940            0x0c010000, 0x0c200000, 0x0ca00000, 0x0d010000, 0x0d020000, 0x0d040000, 0x0d080000,
1941            0x0d100000, 0x4d1f0000,
1942        ];
1943        for opcode in check_invalid_groups {
1944            assert!(
1945                decode_group::<()>(opcode).is_err(),
1946                "{:08x} expected to be invalid",
1947                opcode
1948            );
1949        }
1950    }
1951}