Skip to content

Commit 6f64a60

Browse files
[AArch64] Initial compiler support for SVE unwind on Windows. (#138609)
Most bits of this are straightforward: when we emit SVE instructions in the prologue/epilogue, emit corresponding opcodes. The unfortunately nasty bit is the handling of the frame pointer in functions that use the SVE calling convention. If we have SVE callee saves, and need to restore the stack pointer from the frame pointer, it's impossible to encode callee saves that happen after the frame pointer. So this patch rearranges the stack to put SVE callee saves first. This isn't really that complicated on its own, but it leads to a lot of tricky conditionals (see FPAfterSVECalleeSaves).
1 parent b6f9800 commit 6f64a60

File tree

9 files changed

+2760
-41
lines changed

9 files changed

+2760
-41
lines changed

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,6 +3273,32 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
32733273
-MI->getOperand(2).getImm());
32743274
return;
32753275

3276+
case AArch64::SEH_AllocZ:
3277+
assert(MI->getOperand(0).getImm() >= 0 &&
3278+
"AllocZ SEH opcode offset must be non-negative");
3279+
assert(MI->getOperand(0).getImm() <= 255 &&
3280+
"AllocZ SEH opcode offset must fit into 8 bits");
3281+
TS->emitARM64WinCFIAllocZ(MI->getOperand(0).getImm());
3282+
return;
3283+
3284+
case AArch64::SEH_SaveZReg:
3285+
assert(MI->getOperand(1).getImm() >= 0 &&
3286+
"SaveZReg SEH opcode offset must be non-negative");
3287+
assert(MI->getOperand(1).getImm() <= 255 &&
3288+
"SaveZReg SEH opcode offset must fit into 8 bits");
3289+
TS->emitARM64WinCFISaveZReg(MI->getOperand(0).getImm(),
3290+
MI->getOperand(1).getImm());
3291+
return;
3292+
3293+
case AArch64::SEH_SavePReg:
3294+
assert(MI->getOperand(1).getImm() >= 0 &&
3295+
"SavePReg SEH opcode offset must be non-negative");
3296+
assert(MI->getOperand(1).getImm() <= 255 &&
3297+
"SavePReg SEH opcode offset must fit into 8 bits");
3298+
TS->emitARM64WinCFISavePReg(MI->getOperand(0).getImm(),
3299+
MI->getOperand(1).getImm());
3300+
return;
3301+
32763302
case AArch64::BLR:
32773303
case AArch64::BR: {
32783304
recordIfImportCall(MI);

llvm/lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,9 @@ def CSR_Win_AArch64_Arm64EC_Thunk : CalleeSavedRegs<(add (sequence "Q%u", 6, 15)
606606
def CSR_AArch64_AAVPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
607607
X25, X26, X27, X28, LR, FP,
608608
(sequence "Q%u", 8, 23))>;
609+
def CSR_Win_AArch64_AAVPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
610+
X25, X26, X27, X28, FP, LR,
611+
(sequence "Q%u", 8, 23))>;
609612

610613
// Functions taking SVE arguments or returning an SVE type
611614
// must (additionally) preserve full Z8-Z23 and predicate registers P4-P15
@@ -619,6 +622,11 @@ def CSR_Darwin_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "Z%u", 8, 23),
619622
LR, FP, X19, X20, X21, X22,
620623
X23, X24, X25, X26, X27, X28)>;
621624

625+
def CSR_Win_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "P%u", 4, 15),
626+
(sequence "Z%u", 8, 23),
627+
X19, X20, X21, X22, X23, X24,
628+
X25, X26, X27, X28, FP, LR)>;
629+
622630
// SME ABI support routines such as __arm_tpidr2_save/restore preserve most registers.
623631
def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
624632
: CalleeSavedRegs<(add (sequence "Z%u", 0, 31),

0 commit comments

Comments
 (0)