aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fink <martin@finkmartin.com>2024-06-25 14:45:12 +0200
committerMartin Fink <martin@finkmartin.com>2024-06-25 14:48:51 +0200
commita9ce9a8365eb66507b9bcacb4236af77bd33c620 (patch)
tree2721cdb53e84c2e3c223f58268c1458defb4d122
parenta29e738354b55c39d19b42838af2f091b2cc8973 (diff)
Add support for `udf`
-rw-r--r--src/armv8/a64.rs26
-rw-r--r--tests/armv8/a64.rs40
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() {
}