This patches adds a 32 bit register class for use with Zfinx instructions. This makes them more similar to F instructions and allows us to only spill 32 bits.
I've added CodeGenOnly instructions for load/store using GPRF32 as that gave better results than insert_subreg/extract_subreg.
Function arguments use this new GPRF32 register class for f32 arguments with Zfinx. Eliminating the need to use RISCVISD::FMV* nodes.
This is similar to #107446 which adds a 16 bit register class.
This patches adds a 16 bit register class for use with Zhinx
instructions. This makes them more similar to Zfh instructions and
allows us to only spill 16 bits.
I've added CodeGenOnly instructions for load/store using GPRF16 as that
gave better results than insert_subreg/extract_subreg. I'm using FSGNJ
for GPRF16 copy with Zhinx as that gave better results. Zhinxmin will
use ADDI+subreg operations.
Function arguments use this new GPRF16 register class for f16 arguments
with Zhinxmin. Eliminating the need to use RISCVISD::FMV* nodes.
I plan to extend this idea to Zfinx next.
We need to insert a insert_subvector or extract_subvector which feels
pretty custom.
This should make it easier to support fixed vector arguments for GISel.
Scalar FP calling convention has gotten more complicated with recent
changes to Zfinx/Zdinx, proposed addition of a GPRF16 register class,
and using customReg for f16/bf16 and other FP types small than XLen.
The previous code tried to share a single getReg and getMem call for
many different cases. This patch separates all the FP register handling
to the top of the function with their own getReg calls. The only
exception is f64 with XLen==32, when we are out of FPRs or not able to
use FPRs due to ABI.
The way I've structured this, we no longer need to correct the LocVT for
FP back to ValVT before the call to getMem.
AllocateStack returns int64_t and CCValAssign::getMem expects an
int64_t. The interfaces used unsigned prior to
da42b2846c82063bd1bce78d6a046f78f218eb72.
Offsets for RISC-V should be positive and less than 32-bits so this
shouldn't be a functional change.
With Zfinx/Zdinx, f32/f64 are legal types for a GPR, we don't need a
bitcast.
This avoids turning fneg/fabs into bitwise operations purely because of
these bitcasts. If the bitwise operations are faster for some reason on
a Zfinx CPU, then that seems like it should be done for all fneg/fabs,
not just ones near function arguments/returns.
I don't have much interest in Zfinx, this just makes the code more
similar to what I proposed for Zhinx in #107446.
DataLayout, ABI, and TargetLowering can all be obtained via the
MachineFunction reference in the State object. This is how the targets
that use TableGen for CC handlers get these objects.
This might be a little slower, but it simplies all the callers in
SelectionDAG and GlobalISel.
These are used by both SelectionDAG and GlobalISel and are separate from
RISCVTargetLowering.
Having a separate file is how other targets are structured. Though other
targets generate most of their calling convention code through tablegen.
I moved the `CC_RISV` functions from the `llvm::RISCV` namespace to
`llvm::`. That's what the tablegen code on other targets does and the
functions already have RISCV in their name. `RISCVCCAssignFn` is moved
from `RISCVTargetLowering` to the `llvm` namespace.