decode exts[bhw][.] and pnop

This commit is contained in:
Jacob Lifshay 2026-01-19 15:41:56 -08:00
parent aa85ecab01
commit 1fc56e02f9
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 7586 additions and 54709 deletions

View file

@ -842,6 +842,71 @@ fn test_cases() -> Vec<TestCase> {
0x7c832879;
|[a, b]| a & !b;
}
macro_rules! insn_exts {
(
$mnemonic:literal $dest:literal, $src:literal;
$encoding:literal;
$OutputIntegerMode:ident;
) => {
retval.push(insn_single(
concat!($mnemonic, " ", stringify!($dest), ", ", stringify!($src)),
$encoding,
None,
LogicalMOp::logical_i(
MOpDestReg::new_sim(
&[MOpRegNum::power_isa_gpr_reg_num($dest)],
if $mnemonic.contains('.') {
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM]
} else {
&[]
},
),
[MOpRegNum::power_isa_gpr_reg_imm($src).value],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.$OutputIntegerMode(),
LogicalMOp::lut_from_fn(|[a, b]| a | b),
),
));
};
}
insn_exts! {
"extsb" 3, 4;
0x7c830774;
SignExt8;
}
insn_exts! {
"extsb." 3, 4;
0x7c830775;
SignExt8;
}
insn_exts! {
"extsh" 3, 4;
0x7c830734;
SignExt16;
}
insn_exts! {
"extsh." 3, 4;
0x7c830735;
SignExt16;
}
insn_exts! {
"extsw" 3, 4;
0x7c8307b4;
SignExt32;
}
insn_exts! {
"extsw." 3, 4;
0x7c8307b5;
SignExt32;
}
// ensure pnop decodes to zero instructions
retval.push(insn_empty(
// LLVM doesn't support the pnop instruction:
// https://github.com/llvm/llvm-project/issues/176831
".long 0x07000000, 0 # pnop",
0x07000000,
Some(0),
));
retval
}
@ -900,6 +965,24 @@ fn test_test_cases_assembly() -> std::io::Result<()> {
let Some(line) = lines.next() else {
panic!("output missing line for: {test_case:?}");
};
if line.starts_with("\t.long") {
assert_eq!(
line,
format!("\t.long\t{first_input}"),
"test_case={test_case:?}\nline:\n{line}"
);
if let Some(second_input) = second_input {
let Some(line) = lines.next() else {
panic!("output missing line for: {test_case:?}");
};
assert_eq!(
line,
format!("\t.long\t{second_input}"),
"test_case={test_case:?}\nline:\n{line}"
);
}
continue;
}
let Some((_, comment)) = line.split_once('#') else {
panic!("output line missing comment. test_case={test_case:?}\nline:\n{line}");
};