aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-12-29 02:14:28 -0800
committeriximeow <me@iximeow.net>2021-12-29 02:14:28 -0800
commit435743171b26d89c5df6b77689b136ca91cf7b56 (patch)
tree47dd8b5106ed5ba4728e213acacc10ff8d358e2a
parentd040eddf4f31583032b27d3dd51cc341a14e7299 (diff)
more armv8.1 instructions, fix cas operand check
-rw-r--r--src/armv8/a64.rs24
-rw-r--r--test/armv8/a64.rs15
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<ARMv8> 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<ARMv8> 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);