[PATCH] D30049: x86 interrupt calling convention: re-align stack pointer on 64-bit if an error code was pushed

Philipp Oppermann via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 18 06:45:52 PST 2017


phil-opp added a comment.

> Amjad pointed out to me that the incoming alignment to an interrupt handler is only guaranteed to be 0 mod 8, not 8 mod 16 as is the case with the normal x86-64 ABI. HJ mentions this in 26477.

The x86_64 architecture unconditionally aligns the stack on a 16-byte boundary when an interrupt occurs. From the AMD64 manual (Section 8.9.3):

> In legacy mode, the interrupt-stack pointer can be aligned at any address boundary. Long mode, however, aligns the stack on a 16-byte boundary. This alignment is performed by the processor in hardware before pushing items onto the stack frame. The  revious RSP is saved unconditionally on the new stack by the interrupt mechanism. A subsequent IRET instruction automatically restores the previous RSP.

It even says:

> Aligning the stack on a 16-byte boundary allows optimal performance for saving and restoring the 16-byte XMM registers. The interrupt handler can save and restore the XMM registers using the faster 16-byte aligned loads and stores (MOVAPS), rather than unaligned loads and stores (MOVUPS).

The problem is that the CPU pushes an error code for some exceptions, which destroys the 16-byte alignment. This patches fixes this problem.

Regarding the YMM and ZMM registers: I think they are already saved if the target supports them: https://github.com/llvm-mirror/llvm/blob/47cf6aadec0bc58d970052092ee85a69b3625792/lib/Target/X86/X86RegisterInfo.cpp#L336-L342

The situation on 32-bit x86 is vastly different. The CPU performs no stack alignment at all, so you're correct that we need dynamic realignment.


https://reviews.llvm.org/D30049





More information about the llvm-commits mailing list