-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline Asm Constraints and Modifiers - RVC, Raw Encodings, Pairs #92
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Sam Elliott <[email protected]>
We have customers with usecases that want more kinds of register constraints and modifiers. This change proposes support for these constraints and modifiers, and their names. Broadly, these are intended to make it easier for users who want to manually assemble instructions inside inline assembly blocks, either using the existing instruction formats, or using the raw form of the `.insn` directive. This makes it easier for hardware designers to experiment on new ISA extensions, and makes it easier to support the use of proprietary extensions with unmodified open-source toolchains. There are three groups of additions here: - Constraints for RVC-compatible registers. These use the `c` prefix on an existing register constraint, so `cr` gives a GPR between x8-x15, and `cf` does the same for an FPR between f8-f15. I'm not aware of compressed vector instructions, but we could add `cvr`, `cvd` and `cvm` in the future if the core architecture ends up having the concept of a vector register with an RVC encoding. - A modifier, `N`, to print the raw encoding of a register. This is used when using `.insn <length>, <encoding>`, where the user wants to pass a value to the instruction in a known register, but where the instruction doesn't follow the existing instruction formats, so the assembly parser is not expecting a register name, just a raw integer. - Constraints for even-odd pairs of registers. These use the `P` prefix on an existing register constraint. At the moment, this only defines `Pr` to mean an even-odd pair of GPRs. (We use `P` as a prefix as `p` already means "pointer" in GCC's target-independent constraints). I think this will print as the even register in the even-odd register pair, but I'm still working on the details around this. While the concept of even-odd register pairs is reasonably "new", there are places in the architecture where these already exist - the doubleword/quad CAS in Zacas, and they are also present in the Zilsd specification. Signed-off-by: Sam Elliott <[email protected]>
@@ -746,13 +746,18 @@ statements, including both RISC-V specific and common operand constraints. | |||
|K |5-bit unsigned immediate integer operand | | |||
|J |Zero integer immediate operand | | |||
|s |symbol or label reference with a constant offset | | |||
|cr |RVC general purpose register (`x8`-`x15`) | | |||
|cf |RVC floating point register (`f8`-`f15`) | | |||
|Pr |Even-odd general purpose register pair | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do any other targets support pair? I haven't been able to find any in LLVM and I don't know how to implement it in LLVM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AArch64 supports tuples of 8 64-bit registers, as implemented here llvm/llvm-project@7d94043
I noticed that the NXP LLVM fork with Zilsd support seems to allocate both v2i<xlen>
and i<2*xlen>
to the paired register class, but maybe we only need to do the former? I'm not sure, as it would be nice to be able to pass uint<2*xlen>_t
to a GPR pair constraint.
I understand that pair constraint is the most complex part of this proposal. I have most of a patch for the other constraints, which I will try to finish in the next few days and post to LLVM.
This change implements support for the `cr` and `cf` register constraints (which allocate a RVC GPR or RVC FPR respectively), and the `N` modifier (which prints the raw encoding of a register rather than the name). The intention behind these additions is to make it easier to use inline assembly when assembling raw instructions that are not supported by the compiler, for instance when experimenting with new instructions or when supporting proprietary extensions outside the toolchain. These implement part of my proposal in riscv-non-isa/riscv-c-api-doc#92 As part of the implementation, I felt there was not enough coverage of inline assembly and the "in X" floating-point extensions, so I have added more regression tests around these configurations.
I have an LLVM implementation of the I am still working on the implementation of the |
This change implements support for the `cr` and `cf` register constraints (which allocate a RVC GPR or RVC FPR respectively), and the `N` modifier (which prints the raw encoding of a register rather than the name). The intention behind these additions is to make it easier to use inline assembly when assembling raw instructions that are not supported by the compiler, for instance when experimenting with new instructions or when supporting proprietary extensions outside the toolchain. These implement part of my proposal in riscv-non-isa/riscv-c-api-doc#92 As part of the implementation, I felt there was not enough coverage of inline assembly and the "in X" floating-point extensions, so I have added more regression tests around these configurations.
There was a question on #39 about whether the paired constraint means "an even GPR", or a "even-odd GPR pair", as both would likely print exactly the same as the even subregister. This matters for liveness analysis as, if So, to be clear, |
We have customers with usecases that want more kinds of register
constraints and modifiers. This change proposes support for these
constraints and modifiers, and their names.
Broadly, these are intended to make it easier for users who want to
manually assemble instructions inside inline assembly blocks, either
using the existing instruction formats, or using the raw form of the
.insn
directive. This makes it easier for hardware designers toexperiment on new ISA extensions, and makes it easier to support
the use of proprietary extensions with unmodified open-source
toolchains.
There are three groups of additions here:
Constraints for RVC-compatible registers. These use the
c
prefix onan existing register constraint, so
cr
gives a GPR between x8-x15,and
cf
does the same for an FPR between f8-f15.I'm not aware of compressed vector instructions, but we could add
cvr
,cvd
andcvm
in the future if the core architecture ends uphaving the concept of a vector register with an RVC encoding.
A modifier,
N
, to print the raw encoding of a register. This is usedwhen using
.insn <length>, <encoding>
, where the user wants to passa value to the instruction in a known register, but where the
instruction doesn't follow the existing instruction formats, so the
assembly parser is not expecting a register name, just a raw integer.
Constraints for even-odd pairs of registers. These use the
P
prefixon an existing register constraint. At the moment, this only defines
Pr
to mean an even-odd pair of GPRs. (We useP
as a prefix asp
already means "pointer" in GCC's target-independent constraints).
I think this will print as the even register in the even-odd register
pair, but I'm still working on the details around this.
While the concept of even-odd register pairs is reasonably "new",
there are places in the architecture where these already exist - the
doubleword/quad CAS in Zacas, and they are also present in the Zilsd
specification.
There's also a commit which fixes a header for the Assembly Constraints table.