From 1e26b5a52a7150565c1cfe7b92866a6f13c714fb Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 27 Dec 2021 19:24:02 -0800 Subject: movi/mvni scalar/vector --- src/armv8/a64.rs | 56 +++++++++++++++++++++++++++++++++++++++---------------- test/armv8/a64.rs | 20 ++++++++++++++++++++ 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 408bc13..8ab4542 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -2723,7 +2723,7 @@ impl Decoder for InstDecoder { Ok((Opcode::MVNI, SIMDSizeCode::H)), Ok((Opcode::BIC, SIMDSizeCode::H)), Ok((Opcode::MVNI, SIMDSizeCode::H)), Ok((Opcode::BIC, SIMDSizeCode::H)), Ok((Opcode::MVNI, SIMDSizeCode::S)), Ok((Opcode::BIC, SIMDSizeCode::S)), - Ok((Opcode::MVNI, SIMDSizeCode::B)), Ok((Opcode::FMOV, SIMDSizeCode::B)), + Ok((Opcode::MOVI, SIMDSizeCode::D)), Ok((Opcode::FMOV, SIMDSizeCode::B)), ]; if cmode == 0b1111 && op == 1 && Q == 0 { @@ -2739,25 +2739,49 @@ impl Decoder for InstDecoder { } else if opc == Opcode::ORR || opc == Opcode::BIC { // abcdefgh let abcdefgh = (abc << 5) | defgh; - abcdefgh as u64 + Operand::Imm64(abcdefgh as u64) } else /* if opc == Opcode::MOVI || opc == Opcode::MVNI */ { - 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; - - abcdefgh | (abcdefgh << 1) + if cmode == 0b1110 { + 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; + + Operand::Imm64(abcdefgh | (abcdefgh << 1)) + } else { + let abcdefgh = ((abc << 5) | defgh) as u64; + let imm8 = abcdefgh; + let amount = match size { + SIMDSizeCode::H => { + (cmode & 0b0010) << 1 + } + SIMDSizeCode::S => { + (cmode & 0b0110) << 2 + } + _ => 0, + }; + Operand::ImmShift(imm8 as u16, amount as u8) + } }; inst.opcode = opc; - inst.operands = [ - Operand::SIMDRegisterElements(datasize, Rd as u16, size), - Operand::Imm64(imm), - Operand::Nothing, - Operand::Nothing, - ]; + if Q == 0 && op == 1 && cmode == 0b1110 && o2 == 0 { + inst.operands = [ + Operand::SIMDRegister(size, Rd as u16), + imm, + Operand::Nothing, + Operand::Nothing, + ]; + } else { + inst.operands = [ + Operand::SIMDRegisterElements(datasize, Rd as u16, size), + imm, + Operand::Nothing, + Operand::Nothing, + ]; + } } } else { // `Advanced SIMD vector x indexed element` diff --git a/test/armv8/a64.rs b/test/armv8/a64.rs index 4ee0bff..ed2b49d 100644 --- a/test/armv8/a64.rs +++ b/test/armv8/a64.rs @@ -4319,3 +4319,23 @@ fn test_simd_abs() { assert!(errs.is_empty()); } + +#[test] +fn test_movi() { + const TESTS: &[([u8; 4], &'static str)] = &[ + ([0x1c, 0x04, 0x00, 0x0f], "movi v28.2s, 0x0"), + ([0x28, 0x04, 0x00, 0x0f], "movi v8.2s, 0x1"), + ([0x80, 0x66, 0x01, 0x0f], "movi v0.2s, 0x34, lsl 24"), + ([0x17, 0x64, 0x04, 0x0f], "movi v23.2s, 0x80, lsl 24"), + ([0x01, 0xe4, 0x00, 0x6f], "movi v1.2d, 0x0"), + ([0x02, 0xe4, 0x00, 0x6f], "movi v2.2d, 0x0"), + ([0x03, 0xe4, 0x00, 0x2f], "movi d3, 0x0"), + ]; + let errs = run_tests(TESTS); + + for err in errs.iter() { + println!("{}", err); + } + + assert!(errs.is_empty()); +} -- cgit v1.1