On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu <hjl.to...@gmail.com> wrote: >> To implement interrupt and exception handlers for x86 processors, a >> compiler should support: >> >> 1. void * __builtin_ia32_interrupt_data (void) > > I got a feedback on the name of this builtin function. Since > it also works for 64-bit, we should avoid ia32 in its name. > We'd like to change it to > > void * __builtin_interrupt_data (void) >
Here is the updated spec. H.J. --- The interrupt and exception handlers are called by x86 processors. X86 hardware pushes information onto 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' instruction. The design goals of interrupt and exception handlers for x86 processors are: 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_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 alignment. 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_interrupt_data' function to access data pushed onto the stack by processor: void f () __attribute__ ((interrupt)) { void *p = __builtin_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): void f () __attribute__ ((exception)) { void *p = __builtin_interrupt_data (); ... }