diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/armv8/a64.rs | 81 | 
1 files changed, 70 insertions, 11 deletions
| diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 95458ca..e3635f1 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -809,11 +809,23 @@ impl Display for Instruction {              Opcode::MRS => {                  write!(fmt, "mrs")?;              } -            Opcode::SYS => { -                write!(fmt, "sys")?; -            } -            Opcode::SYSL => { -                write!(fmt, "sys")?; +            Opcode::SYS(ops) => { +                return write!(fmt, "sys {:#x}, {}, {}, {:#x}, {}", +                    ops.op1(), +                    self.operands[0], +                    self.operands[1], +                    ops.op2(), +                    self.operands[2], +                ); +            } +            Opcode::SYSL(ops) => { +                return write!(fmt, "sysl {}, {:#x}, {}, {}, {:#x}", +                    self.operands[0], +                    ops.op1(), +                    self.operands[1], +                    self.operands[2], +                    ops.op2(), +                );              }              Opcode::ISB => {                  write!(fmt, "isb")?; @@ -2387,6 +2399,29 @@ impl Default for Instruction {  }  #[derive(Copy, Clone, Debug, PartialEq)] +#[repr(transparent)] +pub struct SysOps { +    data: u8 +} + +impl SysOps { +    fn new(op1: u8, op2: u8) -> Self { +        SysOps { +            data: op1 | (op2 << 4) +        } +    } + +    #[inline] +    pub fn op1(&self) -> u8 { +        self.data & 0b1111 +    } +    #[inline] +    pub fn op2(&self) -> u8 { +        (self.data >> 4) & 0b1111 +    } +} + +#[derive(Copy, Clone, Debug, PartialEq)]  #[repr(u16)]  pub enum Opcode {      Invalid, @@ -2490,8 +2525,8 @@ pub enum Opcode {      DRPS,      MSR,      MRS, -    SYS, -    SYSL, +    SYS(SysOps), +    SYSL(SysOps),      ISB,      DSB,      DMB, @@ -2939,6 +2974,7 @@ pub enum Operand {      RegPostIndexReg(u16, u16),      PrefetchOp(u16),      SystemReg(u16), +    ControlReg(u16),      PstateField(u8),  } @@ -2969,6 +3005,9 @@ impl Display for Operand {                      }                  }              }, +            Operand::ControlReg(reg) => { +                write!(fmt, "cr{}", reg) +            },              Operand::PrefetchOp(op) => {                  let ty = (op >> 3) & 0b11;                  let target = (op >> 1) & 0b11; @@ -9671,8 +9710,18 @@ impl Decoder<ARMv8> for InstDecoder {                                      }                                  }                                  0b001 => { -                                    inst.opcode = Opcode::SYS; -                                    return Err(DecodeError::IncompleteDecoder); +                                    let Rt = word & 0b1111; +                                    let op2 = (word >> 5) & 0b111; +                                    let CRm = (word >> 8) & 0b1111; +                                    let CRn = (word >> 12) & 0b1111; +                                    let op1 = (word >> 16) & 0b111; +                                    inst.opcode = Opcode::SYS(SysOps::new(op1 as u8, op2 as u8)); +                                    inst.operands = [ +                                        Operand::Register(SizeCode::X, Rt as u16), +                                        Operand::ControlReg(CRn as u16), +                                        Operand::ControlReg(CRm as u16), +                                        Operand::Nothing, +                                    ];                                  }                                  0b010 |                                  0b011 => { @@ -9690,8 +9739,18 @@ impl Decoder<ARMv8> for InstDecoder {                                      inst.opcode = Opcode::Invalid;                                  }                                  0b101 => { -                                    inst.opcode = Opcode::SYSL; -                                    return Err(DecodeError::IncompleteDecoder); +                                    let Rt = word & 0b1111; +                                    let op2 = (word >> 5) & 0b111; +                                    let CRm = (word >> 8) & 0b1111; +                                    let CRn = (word >> 12) & 0b1111; +                                    let op1 = (word >> 16) & 0b111; +                                    inst.opcode = Opcode::SYSL(SysOps::new(op1 as u8, op2 as u8)); +                                    inst.operands = [ +                                        Operand::ControlReg(CRn as u16), +                                        Operand::ControlReg(CRm as u16), +                                        Operand::Register(SizeCode::X, Rt as u16), +                                        Operand::Nothing, +                                    ];                                  }                                  0b110 |                                  0b111 => { | 
