aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-12-27 17:49:01 -0800
committeriximeow <me@iximeow.net>2021-12-27 17:49:01 -0800
commit15a12c78353db700ffb96f454e528a5b6afb4f1d (patch)
tree396c3435afd49ebe63d63497636901c776538d13
parentea8888c84c73f73ac17006539b86f0ef800d80b6 (diff)
fix Advanced SIMD Scalar Three Same
-rw-r--r--src/armv8/a64.rs117
-rw-r--r--test/armv8/a64.rs17
2 files changed, 79 insertions, 55 deletions
diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs
index 70dcfcd..abe0cae 100644
--- a/src/armv8/a64.rs
+++ b/src/armv8/a64.rs
@@ -1578,6 +1578,9 @@ impl Display for Instruction {
Opcode::FCVTL => {
write!(fmt, "fcvtl");
}
+ Opcode::FCVTL2 => {
+ write!(fmt, "fcvtl2");
+ }
Opcode::FCVTNS => {
write!(fmt, "fcvtns");
}
@@ -2177,6 +2180,7 @@ pub enum Opcode {
FCVTN,
FCMGT,
FCVTL,
+ FCVTL2,
FCVTNS,
FCVTPS,
FCVTMS,
@@ -3801,7 +3805,11 @@ impl Decoder<ARMv8> for InstDecoder {
(opc, table[(((size & 1) << 1) | q) as usize]?)
};
- inst.opcode = opc;
+ if opc == Opcode::FCVTL && q != 0 {
+ inst.opcode = Opcode::FCVTL2;
+ } else {
+ inst.opcode = opc;
+ }
inst.operands = [
Operand::SIMDRegisterElements(datasize_a, Rd as u16, elemsize_a),
Operand::SIMDRegisterElements(datasize_b, Rn as u16, elemsize_b),
@@ -4291,7 +4299,6 @@ impl Decoder<ARMv8> for InstDecoder {
Operand::Nothing,
];
}
-// return Err(DecodeError::IncompleteDecoder);
} else if (op3 & 0b000_111111) == 0b000_000000 {
// op2 = x1xx, op3 = xxx000000
// `Conversion between floating-point and fixed-point`
@@ -4829,11 +4836,11 @@ impl Decoder<ARMv8> for InstDecoder {
} else if opcode < 0b11000 {
// TODO: validate operands
const OPCODES_U0_LOW: &[Result<(Opcode, &'static OperandSizeTable), DecodeError>] = &[
- Ok((Opcode::SHADD, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::SQADD, TABLE_A)),
- Ok((Opcode::SRHADD, TABLE_A)),
Err(DecodeError::InvalidOpcode),
- Ok((Opcode::SHSUB, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::SQSUB, TABLE_A)),
Ok((Opcode::CMGT, TABLE_A)),
Ok((Opcode::CMGE, TABLE_A)),
@@ -4841,25 +4848,25 @@ impl Decoder<ARMv8> for InstDecoder {
Ok((Opcode::SQSHL, TABLE_A)),
Ok((Opcode::SRSHL, TABLE_A)),
Ok((Opcode::SQRSHL, TABLE_A)),
- Ok((Opcode::SMAX, TABLE_A)),
- Ok((Opcode::SMIN, TABLE_A)),
- Ok((Opcode::SABD, TABLE_A)),
- Ok((Opcode::SABA, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::ADD, TABLE_A)),
Ok((Opcode::CMTST, TABLE_A)),
- Ok((Opcode::MLA, TABLE_A)),
- Ok((Opcode::MUL, TABLE_A)),
- Ok((Opcode::SMAXP, TABLE_A)),
- Ok((Opcode::SMINP, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::SQDMULH, TABLE_A)),
- Ok((Opcode::ADDP, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
];
const OPCODES_U1_LOW: &[Result<(Opcode, &'static OperandSizeTable), DecodeError>] = &[
- Ok((Opcode::UHADD, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::UQADD, TABLE_A)),
- Ok((Opcode::URHADD, TABLE_A)),
Err(DecodeError::InvalidOpcode),
- Ok((Opcode::UHSUB, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::UQSUB, TABLE_A)),
Ok((Opcode::CMHI, TABLE_A)),
Ok((Opcode::CMHS, TABLE_A)),
@@ -4867,16 +4874,16 @@ impl Decoder<ARMv8> for InstDecoder {
Ok((Opcode::UQSHL, TABLE_A)),
Ok((Opcode::URSHL, TABLE_A)),
Ok((Opcode::UQRSHL, TABLE_A)),
- Ok((Opcode::UMAX, TABLE_A)),
- Ok((Opcode::UMIN, TABLE_A)),
- Ok((Opcode::UABD, TABLE_A)),
- Ok((Opcode::UABA, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::SUB, TABLE_A)),
Ok((Opcode::CMEQ, TABLE_A)),
- Ok((Opcode::MLS, TABLE_A)),
- Ok((Opcode::PMUL, TABLE_A)),
- Ok((Opcode::UMAXP, TABLE_A)),
- Ok((Opcode::UMINP, TABLE_A)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::SQRDMULH, TABLE_A)),
Err(DecodeError::InvalidOpcode),
];
@@ -4889,48 +4896,49 @@ impl Decoder<ARMv8> for InstDecoder {
let (va_width, va_elem, vb_width, vb_elem) = table[((size << 1) | q) as usize]?;
inst.opcode = opcode;
inst.operands = [
- Operand::SIMDRegisterElements(va_width, Rd as u16, va_elem),
- Operand::SIMDRegisterElements(vb_width, Rn as u16, vb_elem),
- Operand::SIMDRegisterElements(vb_width, Rm as u16, vb_elem),
+ Operand::SIMDRegister(va_elem, Rd as u16),
+ Operand::SIMDRegister(vb_elem, Rn as u16),
+ Operand::SIMDRegister(vb_elem, Rm as u16),
Operand::Nothing,
]
} else {
// indexed by ((opcode - 0b11000) << 1) | (size >> 1)
- const OPCODES_U0_HIGH: &[Result<(Opcode, &'static OperandSizeTable), DecodeError>] = &[
- Ok((Opcode::FMAXNM, TABLE_C)),
- Ok((Opcode::FMINNM, TABLE_C)),
- Ok((Opcode::FMLA, TABLE_C)),
- Ok((Opcode::FMLS, TABLE_C)),
- Ok((Opcode::FADD, TABLE_C)),
- Ok((Opcode::FSUB, TABLE_C)),
+ const OPCODES_U0_HIGH: &[Result<(Opcode, &'static OperandSizeTable), DecodeError>; 16] = &[
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Ok((Opcode::FMULX, TABLE_C)),
Err(DecodeError::InvalidOpcode),
Ok((Opcode::FCMEQ, TABLE_C)),
Err(DecodeError::InvalidOpcode),
- Ok((Opcode::FMLAL, TABLE_C)), // only if size & 0b01 is 0
- Ok((Opcode::FMLSL, TABLE_C)), // only if size & 0b01 is 0
- Ok((Opcode::FMAX, TABLE_C)),
- Ok((Opcode::FMIN, TABLE_C)),
- Ok((Opcode::FRECPS, TABLE_C)),
- Ok((Opcode::FRSQRTS, TABLE_C)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
];
- const OPCODES_U1_HIGH: &[Result<(Opcode, &'static OperandSizeTable), DecodeError>] = &[
- Ok((Opcode::FMAXNMP, TABLE_C)),
- Ok((Opcode::FMINNMP, TABLE_C)),
- Ok((Opcode::FMLAL2, TABLE_C)),
- Ok((Opcode::FMLSL2, TABLE_C)),
+ const OPCODES_U1_HIGH: &[Result<(Opcode, &'static OperandSizeTable), DecodeError>; 16] = &[
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ // 0b11010
Err(DecodeError::InvalidOpcode),
- Ok((Opcode::FADDP, TABLE_C)),
Ok((Opcode::FABD, TABLE_C)),
- Ok((Opcode::FMUL, TABLE_C)),
Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ // 0b11100
Ok((Opcode::FCMGE, TABLE_C)),
Ok((Opcode::FCMGT, TABLE_C)),
Ok((Opcode::FACGE, TABLE_C)),
Ok((Opcode::FACGT, TABLE_C)),
- Ok((Opcode::FMAXP, TABLE_C)),
- Ok((Opcode::FMINP, TABLE_C)),
- Ok((Opcode::FDIV, TABLE_C)),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
+ Err(DecodeError::InvalidOpcode),
Err(DecodeError::InvalidOpcode),
];
let index = ((opcode - 0b11000) << 1) | (size >> 1);
@@ -4944,13 +4952,12 @@ impl Decoder<ARMv8> for InstDecoder {
let (va_width, va_elem, vb_width, vb_elem) = table[(((size & 0b01) << 1) | q) as usize]?;
inst.opcode = opcode;
inst.operands = [
- Operand::SIMDRegisterElements(va_width, Rd as u16, va_elem),
- Operand::SIMDRegisterElements(vb_width, Rn as u16, vb_elem),
- Operand::SIMDRegisterElements(vb_width, Rm as u16, vb_elem),
+ Operand::SIMDRegister(va_elem, Rd as u16),
+ Operand::SIMDRegister(vb_elem, Rn as u16),
+ Operand::SIMDRegister(vb_elem, Rm as u16),
Operand::Nothing,
]
};
-// return Err(DecodeError::IncompleteDecoder);
} else {
if op3 & 0b10 == 0b00 {
// `Advanced SIMD scalar three different`
diff --git a/test/armv8/a64.rs b/test/armv8/a64.rs
index 1659327..eb88da2 100644
--- a/test/armv8/a64.rs
+++ b/test/armv8/a64.rs
@@ -4250,3 +4250,20 @@ fn test_cvt_general() {
assert!(errs.is_empty());
}
+
+#[test]
+fn test_fabd_general() {
+ const TESTS: &[([u8; 4], &'static str)] = &[
+ ([0x20, 0xd4, 0xa0, 0x7e], "fabd s0, s1, s0"),
+ ([0x21, 0xd4, 0xa0, 0x7e], "fabd s1, s1, s0"),
+ ([0xd6, 0xd6, 0xf9, 0x7e], "fabd d22, d22, d25"),
+ ([0x21, 0xd4, 0xfa, 0x7e], "fabd d1, d1, d26"),
+ ];
+ let errs = run_tests(TESTS);
+
+ for err in errs.iter() {
+ println!("{}", err);
+ }
+
+ assert!(errs.is_empty());
+}