Hi! I was wondering if adding some instructions to the aarch64 development backend would be a good way to contribute.
If so, I wanted to ask about a problem I’m running into. I was trying to see if I could add a sub_reg64_reg64_reg64
function. (I’m relatively new to assembly in general, so I’m figuring a lot of this out as I go.)
#[inline(always)]
fn sub_reg64_reg64_reg64(
buf: &mut Vec<'_, u8>,
dst: AArch64GeneralReg,
src1: AArch64GeneralReg,
src2: AArch64GeneralReg,
) {
let inst = ArithmeticShifted::new(true, false, ShiftType::LSL, 0, src2, src1, dst);
buf.extend(inst.bytes());
}
//…
#[test]
fn test_sub_reg64_reg64_reg64() {
disassembler_test!(
sub_reg64_reg64_reg64,
|reg1: AArch64GeneralReg, reg2: AArch64GeneralReg, reg3: AArch64GeneralReg| format!(
"sub {}, {}, {}",
reg1.capstone_string(UsesZR),
reg2.capstone_string(UsesZR),
reg3.capstone_string(UsesZR)
),
ALL_GENERAL_REGS,
ALL_GENERAL_REGS,
ALL_GENERAL_REGS
);
}
One of the assertions is failing:
thread 'generic64::aarch64::tests::test_sub_reg64_reg64_reg64' panicked at 'assertion failed: `(left == right)`
left: `"sub x0, xzr, x0"`,
right: `"neg x0, x0"`', crates/compiler/gen_dev/src/generic64/aarch64.rs:1715:9
So it looks like the output is disassembled into "neg x0, x0"
, which doesn’t equal "sub x0, xzr, x0"
. But if I understand correctly, neg x0, x0
is actually an alias for sub x0, xzr, x0
. They assemble to the same machine code: https://armconverter.com/?code=sub%20x0,%20xzr,%20x0 vs https://armconverter.com/?code=neg%20x0,%20x0. Is this a problem you all have run into before?
Oh, interesting. It looks like you found an edge case in the test harness.
It doesn't know equivalences and is just doing string comparisons.
I guess you can add an extra conditional to that lambda.
if reg2 == ZeroRegister {
format!("neg {}, {}", reg1.capstone_string(UsesZR), reg3.capstone_string(UsesZR),)
} else {
// old format
}
Yeah, that makes the test pass
Thanks!
Do you think just that function is worth making a pull request for? I added the top-level function, but I haven't added anything to the sub_reg64_reg64_reg64
function in AArch64Assembler
, since I'm not sure how to test that. (Though add_reg64_reg64_reg64
in AArch64Assembler
is very simple, so I guess this one probably is too.)
Actually, it causes a dead code warning if I don't add use it, so I guess I probably shouldn't make a PR without doing that?
Yeah, shouldn't be too hard to pipe it through. Should be identical to add if I had to guess.
Once it is piped through, it should be good for a pr.
Testing may be a bit more complex. I think we would need to expand feature flags to enable dev-aarch64 tests separate from dev-x86_64 tests.
Oh, I also think we need some more instructions implemented before we can run our test cases.
The number related tests can be run with: cargo test-gen-dev -- gen_num::
But on aarch64, they currently will all fail because we don't have certain required instructions. panicked at 'not yet implemented: jump instructions for AArch64'
Anyway, pipeline it through, it can't be tested yet. I guess it would be extra valuable, if you could target the instructions need to get the test cases running, but any added instructions is useful.
Sounds good!
Last updated: Jul 06 2025 at 12:14 UTC