From 435743171b26d89c5df6b77689b136ca91cf7b56 Mon Sep 17 00:00:00 2001 From: iximeow Date: Wed, 29 Dec 2021 02:14:28 -0800 Subject: more armv8.1 instructions, fix cas operand check --- src/armv8/a64.rs | 24 ++++++++++++++++++++---- test/armv8/a64.rs | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 8b96f60..eb6c14d 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -753,9 +753,12 @@ pub enum Opcode { ADRP, EXTR, LDAR, + LDLAR, LDARB, + LDLARB, LDAXRB, LDARH, + LDLARH, LDAXP, LDAXR, LDAXRH, @@ -784,8 +787,11 @@ pub enum Opcode { LDXRB, LDXRH, STLR, + STLLR, STLRB, + STLLRB, STLRH, + STLLRH, STLXP, STLXR, STLXRB, @@ -1971,6 +1977,12 @@ impl Display for Opcode { Opcode::RORV => "rorv", Opcode::INS => "ins", Opcode::DUP => "dup", + Opcode::LDLARB => "ldlarb", + Opcode::LDLARH => "ldlarh", + Opcode::LDLAR => "ldlar", + Opcode::STLLRB => "stllrb", + Opcode::STLLRH => "stllrh", + Opcode::STLLR => "stllr", Opcode::Bcc(cond) => { return write!(fmt, "b.{}", Operand::ConditionCode(cond)); @@ -6981,10 +6993,6 @@ impl Decoder for InstDecoder { (Opcode::CAS(ar), SizeCode::X) }; - if Rt & 1 != 0 || Rn & 1 != 0 { - return Err(DecodeError::InvalidOperand); - } - inst.opcode = opcode; inst.operands = [ Operand::Register(size_code, Rs), @@ -7003,13 +7011,21 @@ impl Decoder for InstDecoder { // STLR -> Wt (Rt) Xn|SP (Rn) // LDAR -> Wt (Rt) Xn|SP (Rn) inst.opcode = match (size, Lo1, o0) { + (0b00, 0b00, 0b0) => Opcode::STLLRB, (0b00, 0b00, 0b1) => Opcode::STLRB, + (0b00, 0b10, 0b0) => Opcode::LDLARB, (0b00, 0b10, 0b1) => Opcode::LDARB, + (0b01, 0b00, 0b0) => Opcode::STLLRH, (0b01, 0b00, 0b1) => Opcode::STLRH, + (0b01, 0b10, 0b0) => Opcode::LDLARH, (0b01, 0b10, 0b1) => Opcode::LDARH, + (0b10, 0b00, 0b0) => Opcode::STLLR, // 32-bit (0b10, 0b00, 0b1) => Opcode::STLR, // 32-bit + (0b10, 0b10, 0b0) => Opcode::LDLAR, // 32-bit (0b10, 0b10, 0b1) => Opcode::LDAR, // 32-bit + (0b11, 0b00, 0b0) => Opcode::STLLR, // 64-bit (0b11, 0b00, 0b1) => Opcode::STLR, // 64-bit + (0b11, 0b10, 0b0) => Opcode::LDLAR, // 64-bit (0b11, 0b10, 0b1) => Opcode::LDAR, // 64-bit _ => { inst.opcode = Opcode::Invalid; diff --git a/test/armv8/a64.rs b/test/armv8/a64.rs index 2ee09c7..92115e0 100644 --- a/test/armv8/a64.rs +++ b/test/armv8/a64.rs @@ -4377,6 +4377,21 @@ fn test_mismatches() { fn test_cas() { const TESTS: &[([u8; 4], &'static str)] = &[ ([0x20, 0x7c, 0x20, 0x08], "casp w0, w1, w0, w1, [x1]"), + ([0x01, 0x7c, 0xa0, 0x08], "casb w0, w1, [x0]"), + ]; + let errs = run_tests(TESTS); + + for err in errs.iter() { + println!("{}", err); + } + + assert!(errs.is_empty()); +} + +#[test] +fn test_stll() { + const TESTS: &[([u8; 4], &'static str)] = &[ + ([0x00, 0x7c, 0x9f, 0x08], "stllrb w0, [x0]"), ]; let errs = run_tests(TESTS); -- cgit v1.1