[cfe-dev] RFC: Support x86 interrupt and exception handlers

H.J. Lu via cfe-dev cfe-dev at lists.llvm.org
Thu Sep 3 10:37:18 PDT 2015

The interrupt and exception handlers are called by x86 processors.  X86
hardware puts information on stack and calls the handler.  The
requirements are

1. Both interrupt and exception handlers must use the 'IRET' instruction,
instead of the 'RET' instruction, to return from the handlers.
2. All registers are callee-saved in interrupt and exception handlers.
3. The difference between interrupt and exception handlers is the
exception handler must pop 'ERROR_CODE' off the stack before the 'IRET'

The design goals of interrupt and exception handlers for x86 processors

1. No new calling convention in compiler.
2. Support both 32-bit and 64-bit modes.
3. Flexible for compilers to optimize.
4. Easy to use by programmers.

To implement interrupt and exception handlers for x86 processors, a
compiler should support:

1. void * __builtin_ia32_interrupt_data (void)

This function returns a pointer to interrupt or exception data pushed
onto the stack by processor.

The __builtin_frame_address builtin isn't suitable for interrupt and
exception handlers since it returns the stack frame address on the
callee side and compiler may generate a new stack frame for stack

2. 'interrupt' attribute

Use this attribute to indicate that the specified void function without
arguments is an interrupt handler.  The compiler generates function entry
and exit sequences suitable for use in an interrupt handler when this
attribute is present.  The 'IRET' instruction, instead of the
'RET' instruction, is used to return from interrupt handlers.  All
registers, except for the EFLAGS register which is restored by the
'IRET' instruction, are preserved by the compiler.  The red zone
isn't supported in an interrupt handler; that is an interrupt
handler can't access stack beyond the current stack pointer.

You can use the builtin '__builtin_ia32_interrupt_data' function to access
data pushed onto the stack by processor:

f () __attribute__ ((interrupt))
  void *p = __builtin_ia32_interrupt_data ();

3. 'exception' attribute

Use 'exception' instead of 'interrupt' for handlers intended to be
used for 'exception' (i.e. those that must pop 'ERROR_CODE' off the
stack before the 'IRET' instruction):

f () __attribute__ ((exception))
  void *p = __builtin_ia32_interrupt_data ();

Any comments, suggestions?



More information about the cfe-dev mailing list