From f551a6bed26e1c5e9938a1c45b47f1531ed64555 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 16 Mar 2024 21:10:00 +0000 Subject: fix movi (immediate) to unpack immediate correctly .... and add tests that exercise movi with an immediate other than 0 --- src/armv8/a64.rs | 12 ++++++------ tests/armv8/a64.rs | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 55fbbed..6d3b29f 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -3454,13 +3454,13 @@ impl Decoder for InstDecoder { } else /* if opc == Opcode::MOVI || opc == Opcode::MVNI */ { if cmode == 0b1110 && op == 1 { let abcdefgh = ((abc << 5) | defgh) as u64; - let abcdefgh = (abcdefgh | (abcdefgh << 16)) & 0x000000ff000000ff; - let abcdefgh = (abcdefgh | (abcdefgh << 8)) & 0x00ff00ff00ff00ff; - let abcdefgh = (abcdefgh | (abcdefgh << 4)) & 0x0f0f0f0f0f0f0f0f; - let abcdefgh = (abcdefgh | (abcdefgh << 2)) & 0x3333333333333333; - let abcdefgh = (abcdefgh | (abcdefgh << 1)) & 0x5555555555555555; + let mut bytes = [0u8; 8]; + for i in 0..8 { + let byte = ((abcdefgh as i8) << (7 - i)) >> 7; + bytes[i] = byte as u8; + } - Operand::Imm64(abcdefgh | (abcdefgh << 1)) + Operand::Imm64(u64::from_le_bytes(bytes)) } else { let abcdefgh = ((abc << 5) | defgh) as u64; let imm8 = abcdefgh; diff --git a/tests/armv8/a64.rs b/tests/armv8/a64.rs index 6af5291..3f8c4e4 100644 --- a/tests/armv8/a64.rs +++ b/tests/armv8/a64.rs @@ -4331,6 +4331,8 @@ fn test_movi() { ([0x01, 0xe4, 0x00, 0x6f], "movi v1.2d, #0x0"), ([0x02, 0xe4, 0x00, 0x6f], "movi v2.2d, #0x0"), ([0x03, 0xe4, 0x00, 0x2f], "movi d3, #0x0"), + ([0x23, 0xe4, 0x00, 0x2f], "movi d3, #0xff"), + ([0xa3, 0xe4, 0x00, 0x2f], "movi d3, #0xff00ff"), ]; let errs = run_tests(TESTS); -- cgit v1.1