Stream: cranelift

Topic: arm64 pacdza ISLE implementation


view this post on Zulip Fritz Rehde (Jun 14 2023 at 18:03):

Hi, I am trying add ARM64's pacdza (https://developer.arm.com/documentation/ddi0602/2021-06/Base-Instructions/PACDA--PACDZA--Pointer-Authentication-Code-for-Data-address--using-key-A-) to cranelift (for a project).
pacdza computes and inserts a Pointer Authentication Code (PAC) for a data address.
The way I interpret the documentation X[d] = AddPACDA(X[d], X[n]); (you can ignore X[n] for now) is that the instruction takes one input parameter in the register Xd, and returns the data address that now contains the PAC also in the register Xd.
I am not sure how to translate the fact, that the instruction takes its input in the same register that the output is written to, to the ISLE format.

Here is my current naive implementation (that does not compile) from aarch64/inst.isle:

;; PACDZA
(Pacdza (rd WritableReg))

;; Helper for emitting `MInst.Pacdza` instructions.
(decl emit_arm64_pacdza (Reg) Reg)
(rule (emit_arm64_pacdza src)
      (let ((dst WritableReg (temp_writable_reg $I64))
            ;; TODO: move src to dst (since rd is used as input and output register)
            (_ Unit (emit (MInst.Mov (operand_size $I64) dst src)))
            (_ Unit (emit (MInst.Pacdza dst))))
        dst))

I thought maybe inserting a move instruction would do the job, but this results in some Register allocation error for vcode.
It also doesn't seem like the right way to do this.
Does anyone have an idea how I can solve this?
Are there maybe some other (arm64) instructions that also use the same register for input and output, on which I could base my implementation?

Thanks for your time and help!

view this post on Zulip Afonso Bordado (Jun 14 2023 at 18:22):

:wave: Hey, In this case you can implement the instruction at the ISLE level as reading from one register and returning the value in another register, they are virtual registers and then you can instruct the register allocator to make sure that they end up in the same physical register after regalloc.

We have an example of this in the AArch64 Backend with the MovK instruction. To ensure that they end up as the same register, you can use reg_reuse_def when specifying the regalloc behaviour of that instruction.

A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.
A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.

view this post on Zulip Fritz Rehde (Jun 14 2023 at 18:58):

Thank you very much, MovK was exactly the kind of example I was looking for!


Last updated: Oct 23 2024 at 20:03 UTC