diff options
author | Martin Fink <martin@finkmartin.com> | 2024-06-25 14:45:12 +0200 |
---|---|---|
committer | Martin Fink <martin@finkmartin.com> | 2024-06-25 14:48:51 +0200 |
commit | a9ce9a8365eb66507b9bcacb4236af77bd33c620 (patch) | |
tree | 2721cdb53e84c2e3c223f58268c1458defb4d122 | |
parent | a29e738354b55c39d19b42838af2f091b2cc8973 (diff) |
Add support for `udf`
-rw-r--r-- | src/armv8/a64.rs | 26 | ||||
-rw-r--r-- | tests/armv8/a64.rs | 40 |
2 files changed, 62 insertions, 4 deletions
diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 20098b9..87ded05 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -1145,6 +1145,7 @@ impl SysOps { #[allow(missing_docs)] pub enum Opcode { Invalid, + UDF, MOVN, MOVK, MOVZ, @@ -1737,6 +1738,7 @@ impl Display for Opcode { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let text = match *self { Opcode::Invalid => "invalid", + Opcode::UDF => "udf", Opcode::MOVK => "movk", Opcode::ADC => "adc", Opcode::ADCS => "adcs", @@ -3178,8 +3180,8 @@ impl Decoder<ARMv8> for InstDecoder { DataProcessingSimd2, DataProcessingImmediate, BranchExceptionSystem, - SME, SVE, + ReservedSME, } // from ARM architecture refrence manual for ARMv8, C3.1 @@ -3196,7 +3198,7 @@ impl Decoder<ARMv8> for InstDecoder { let section_bits = word >> 25; static SECTIONS: [Section; 16] = [ - Section::SME, // 0000 // SME encodings + Section::ReservedSME, // 0000 // reserved or SME encodings Section::Unallocated, // 0001 Section::SVE, // 0010 // SVE encodings Section::Unallocated, // 0011 @@ -3213,12 +3215,28 @@ impl Decoder<ARMv8> for InstDecoder { Section::LoadStore, // 1110 Section::DataProcessingSimd2, // 1111 ]; - let section = SECTIONS[(section_bits & 0x0f) as usize]; + let section = SECTIONS[(section_bits & 0b1111) as usize]; // crate::armv8::a64::std::eprintln!("word: {:#x}, bits: {:#b}", word, section_bits & 0xf); + let op0 = (word >> 31) & 1; match section { - Section::SME => { + // Reserved encodings + Section::ReservedSME if op0 == 0 => { + let op1 = (word >> 16) & 0b1111_1111; + if op1 != 0 { + return Err(DecodeError::IncompleteDecoder); + } + inst.opcode = Opcode::UDF; + inst.operands = [ + Operand::Imm16((word & 0xffff) as u16), + Operand::Nothing, + Operand::Nothing, + Operand::Nothing, + ]; + }, + // SME encodings + Section::ReservedSME => { return Err(DecodeError::IncompleteDecoder); }, Section::SVE => { diff --git a/tests/armv8/a64.rs b/tests/armv8/a64.rs index 0e76ef6..ae0f108 100644 --- a/tests/armv8/a64.rs +++ b/tests/armv8/a64.rs @@ -51,6 +51,12 @@ fn test_sve() { } #[test] +fn test_sme() { + // SME outer product + test_err([0x00, 0x00, 0xc0, 0x80], DecodeError::IncompleteDecoder); +} + +#[test] fn test_unpredictable() { // could be stx/ldx but Lo1 is `x1` and invalid. test_err([0x00, 0x00, 0x20, 0x08], DecodeError::InvalidOperand); @@ -305,6 +311,40 @@ fn test_decode_arithmetic() { } #[test] +fn test_decode_udf() { + test_decode( + [0x00, 0x00, 0x00, 0x00], + Instruction { + opcode: Opcode::UDF, + operands: [ + Operand::Imm16(0), + Operand::Nothing, + Operand::Nothing, + Operand::Nothing, + ] + } + ); + test_decode( + [0xfe, 0xca, 0x00, 0x00], + Instruction { + opcode: Opcode::UDF, + operands: [ + Operand::Imm16(0xcafe), + Operand::Nothing, + Operand::Nothing, + Operand::Nothing, + ] + } + ); +} + +#[test] +fn test_display_udf() { + test_display([0x00, 0x00, 0x00, 0x00], "udf #0x0"); + test_display([0xfe, 0xca, 0x00, 0x00], "udf #0xcafe"); +} + +#[test] fn test_decode_mul() { } |