[llvm] [AArch64][GlobalISel] Implement selectVaStartAAPCS (PR #106979)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 3 23:32:29 PDT 2024
================
@@ -1994,7 +1994,108 @@ bool AArch64InstructionSelector::selectVectorAshrLshr(
bool AArch64InstructionSelector::selectVaStartAAPCS(
MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
- return false;
+
+ if (MF.getSubtarget<AArch64Subtarget>().isCallingConvWin64(
+ MF.getFunction().getCallingConv(), MF.getFunction().isVarArg()))
+ return false;
+
+ // The layout of the va_list struct is specified in the AArch64 Procedure Call
+ // Standard, section 10.1.5.
+
+ const AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
+ const unsigned PtrSize = STI.isTargetILP32() ? 4 : 8;
+ const auto *PtrRegClass =
+ STI.isTargetILP32() ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass;
+
+ const MCInstrDesc &MCIDAddAddr =
+ TII.get(STI.isTargetILP32() ? AArch64::ADDWri : AArch64::ADDXri);
+ const MCInstrDesc &MCIDStoreAddr =
+ TII.get(STI.isTargetILP32() ? AArch64::STRWui : AArch64::STRXui);
+
+ /*
+ * typedef struct va_list {
+ * void * stack; // next stack param
+ * void * gr_top; // end of GP arg reg save area
+ * void * vr_top; // end of FP/SIMD arg reg save area
+ * int gr_offs; // offset from gr_top to next GP register arg
+ * int vr_offs; // offset from vr_top to next FP/SIMD register arg
+ * } va_list;
+ */
+ const auto VAList = I.getOperand(0).getReg();
+
+ // Our current offset in bytes from the va_list struct (VAList).
+ unsigned OffsetBytes = 0;
+
+ // Helper function to store (FrameIndex + Imm) to VAList at offset OffsetBytes
+ // and increment OffsetBytes by PtrSize.
+ const auto PushAddress = [&](const int FrameIndex, const int64_t Imm) {
+ const Register Top = MRI.createVirtualRegister(PtrRegClass);
+ auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), MCIDAddAddr)
+ .addDef(Top)
+ .addFrameIndex(FrameIndex)
+ .addImm(Imm)
+ .addImm(0);
+ constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
+
+ MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), MCIDStoreAddr)
+ .addUse(Top)
+ .addUse(VAList)
+ .addImm(OffsetBytes / PtrSize)
+ .addMemOperand(MF.getMachineMemOperand(
+ (*I.memoperands_begin())
+ ->getPointerInfo()
+ .getWithOffset(OffsetBytes),
+ MachineMemOperand::MOStore, PtrSize, Align(PtrSize)));
----------------
arsenm wrote:
Should do commonAlignment of the original alignments and the offset
https://github.com/llvm/llvm-project/pull/106979
More information about the llvm-commits
mailing list