----- Original Message ----- > From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org> > To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org > Sent: Monday, September 21, 2015 11:27:18 AM > Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers > > On Thu, Sep 17, 2015 at 12:26 PM, H.J. Lu <hjl.to...@gmail.com> > wrote: > > 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. > > > > This updated spec adds > > unsigned int __builtin_exception_error (void) > unsigned long long int __builtin_exception_error (void) > > This function returns the exception error code pushed onto the stack > by > processor. Its return value is 64 bits in 64-bit mode and 32 bits in > 32-bit mode. This function can only be used in exception handler. > > It also changes the definition of > > void * __builtin_interrupt_data (void) > > so that it returns a pointer to the data layout pushed onto stack > by processor for both interrupt and exception handlers. > > > -- > 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 the return address 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. unsigned int __builtin_exception_error (void) > unsigned long long int __builtin_exception_error (void) > > This function returns the exception error code pushed onto the stack > by > processor. Its return value is 64 bits in 64-bit mode and 32 bits in > 32-bit mode. This function can only be used in exception handler.
Instead of adding more builtins for these, why not simply model this by giving the handler function a non-trivial signature? So, for example, the interrupt handler would be: void handler(void *); and the exception handler would be: void handler(size_t); -Hal > > 3. '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 the interrupted function; that is an interrupt > handler may access stack within 128 bytes of the current stack > pointer. > > You can use the builtin '__builtin_interrupt_data' function to access > the interrupt data pushed onto the stack by processor: > > void > f () __attribute__ ((interrupt)) > { > void *p = __builtin_interrupt_data (); > ... > } > > 4. '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). > > You can use the builtin '__builtin_exception_error' function to > access the exception error code pushed onto the stack by processor > as well as the builtin '__builtin_interrupt_data' function to > access the exception data on stack: > > void > f () __attribute__ ((exception)) > { > unsigned int error = __builtin_exception_error (); > void *p = __builtin_interrupt_data (); > ... > } > _______________________________________________ > cfe-dev mailing list > cfe-...@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev > -- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory