[ARM GlobalISel] Select G_FCONSTANT for VFP3
Make it possible to TableGen code for FCONSTS and FCONSTD.
We need to make two changes to the TableGen descriptions of vfp_f32imm
and vfp_f64imm respectively:
* add GISelPredicateCode to check that the immediate fits in 8 bits;
* extract the SDNodeXForms into separate definitions and create a
GISDNodeXFormEquiv and a custom renderer function for each of them.
There's a lot of boilerplate to get the actual value of the immediate,
but it basically just boils down to calling ARM_AM::getFP32Imm or
ARM_AM::getFP64Imm.
llvm-svn: 358063
diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
index 0f56504..c7bead9 100644
--- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
+++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
@@ -137,6 +137,9 @@
unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
unsigned Size) const;
+ void renderVFPF32Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
+ void renderVFPF64Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
+
#define GET_GLOBALISEL_PREDICATES_DECL
#include "ARMGenGlobalISel.inc"
#undef GET_GLOBALISEL_PREDICATES_DECL
@@ -804,6 +807,30 @@
return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
}
+void ARMInstructionSelector::renderVFPF32Imm(
+ MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
+ assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
+ "Expected G_FCONSTANT");
+
+ APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
+ uint32_t FPImmEncoding = ARM_AM::getFP32Imm(FPImmValue);
+ assert(FPImmEncoding != -1 && "Invalid immediate value");
+
+ NewInstBuilder.addImm(FPImmEncoding);
+}
+
+void ARMInstructionSelector::renderVFPF64Imm(
+ MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
+ assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
+ "Expected G_FCONSTANT");
+
+ APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
+ uint64_t FPImmEncoding = ARM_AM::getFP64Imm(FPImmValue);
+ assert(FPImmEncoding != -1 && "Invalid immediate value");
+
+ NewInstBuilder.addImm(FPImmEncoding);
+}
+
bool ARMInstructionSelector::select(MachineInstr &I,
CodeGenCoverage &CoverageInfo) const {
assert(I.getParent() && "Instruction should be in a basic block!");