diff options
author | iximeow <me@iximeow.net> | 2021-12-27 19:24:02 -0800 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-12-27 19:24:02 -0800 |
commit | 1e26b5a52a7150565c1cfe7b92866a6f13c714fb (patch) | |
tree | 75c58f6c07a25f1bfbdc4f88fd60363ea15d23ee /src/armv8 | |
parent | 4e28a1078e93c15bc8b9076504f2eba4656ccf76 (diff) |
movi/mvni scalar/vector
Diffstat (limited to 'src/armv8')
-rw-r--r-- | src/armv8/a64.rs | 56 |
1 files changed, 40 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<ARMv8> 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<ARMv8> 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` |