dynasm-rs icon indicating copy to clipboard operation
dynasm-rs copied to clipboard

Incorrect instruction encoding on AArch64 when using `xzr` as the destination register

Open losfair opened this issue 5 years ago • 3 comments

Hi,

I'm trying to generate some code like:

        dynasm!(self.a
            ; .arch aarch64
            ; add X(31), X(1), 1
        );

Dynasm successfully assembles this without reporting an error. However, the assembled code is:

add     sp, x1, #0x1

Which is incorrect according to the documentation that specifies only the dynamic encoding prefix XSP should encode a sp operand.

Is something like add xzr, x1, #0x1 unencodable? If that's the case, maybe dynasm should return an error instead of generating sp silently.

losfair avatar Nov 15 '20 08:11 losfair

add xzr, x1, #0x1 is indeed unencodable, as can be seen in the instruction reference where the relevant format (two regs and an immediate) specifies:

add Xn|SP, Xm|SP, #uimm {, LSL #uimm1 }                         (#uimm < 4096, #uimm1 = [0, 12])

You're right that using an X dynamic register instead of an XSP dynamic register shouldn't allow this instruction to match at all, so something is going wrong here. I'll investigate.

CensoredUsername avatar Nov 15 '20 16:11 CensoredUsername

Found the bug, that part of the code also allows non-XSP family registers through so normal registers that aren't the zero reg can be used. This exemption is needed for static registers (what family is X1, X or XSP), but it doesn't actually check that they're static so dynamic regs get a pass as well.

Easy fix, but will break working user code so probably have to cut a new release for this.

CensoredUsername avatar Nov 15 '20 16:11 CensoredUsername

In the meantime you can try this fix at 83743bf.

CensoredUsername avatar Nov 15 '20 17:11 CensoredUsername

This has been merged into master with v2.0.0.

CensoredUsername avatar Jan 31 '23 16:01 CensoredUsername