From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100173 invoked by alias); 10 May 2016 15:29:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 98852 invoked by uid 89); 10 May 2016 15:29:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-vk0-f42.google.com Received: from mail-vk0-f42.google.com (HELO mail-vk0-f42.google.com) (209.85.213.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 10 May 2016 15:29:38 +0000 Received: by mail-vk0-f42.google.com with SMTP id m188so20716969vka.1 for ; Tue, 10 May 2016 08:29:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-transfer-encoding; bh=2vE+4wvnViXl0qxVmT9qVmPaSDLjuk8Q4Dnwhn20iG8=; b=bCn9u9zaDPTIY0ZOjXl1kzgK6tblNjdTCWlyH4Tw9jznSq5sEdgOT+PQ4JeA7ynPW3 vPpyr9fLytd4YcNWV1SvPB2Fg3emn0HllbIe5JaASBkZsX/kYiBL1heAQisT1Cs0nyVV 6nRYihHXZqr7PA+rGYHJZ2MV8HqQ7VHgYp5imD5XDXwlE8U3SlbJfLCL1VO2xJpxQmIY ReFemZaGxp8D/DTNT9bnh6nyuCbyipPTaBIXC8MtQVKuGssR5VYUt/TziTUKW6X81uGO SJi3fjCzqqu6if6SiEXjZHHp6z5GzqtUqfFO8T+usxXiTlgzTjx8besEynRPtW0xpQVd SMow== X-Gm-Message-State: AOPr4FW5//kJ+dAFiKm4d4x/OKjwMeWwRQ7IS4skNfXqv+trpn8PX26wU+3vhjKSZ4/rbNJz0BWNRhwS6coofw== MIME-Version: 1.0 X-Received: by 10.31.16.39 with SMTP id g39mr9926840vki.66.1462894175868; Tue, 10 May 2016 08:29:35 -0700 (PDT) Received: by 10.103.76.220 with HTTP; Tue, 10 May 2016 08:29:35 -0700 (PDT) In-Reply-To: <4E89A029A0F8D443B436A5167BA3C53F03D08529@CDSMSX101.ccr.corp.intel.com> References: <4E89A029A0F8D443B436A5167BA3C53F03CFFF3B@CDSMSX101.ccr.corp.intel.com> <4E89A029A0F8D443B436A5167BA3C53F03D08529@CDSMSX101.ccr.corp.intel.com> Date: Tue, 10 May 2016 15:29:00 -0000 Message-ID: Subject: Re: [PATCH] x86 interrupt attribute patch [2/2] From: Uros Bizjak To: "Koval, Julia" Cc: "gcc-patches@gcc.gnu.org" , "Lu, Hongjiu" , "vaalfreja@gmail.com" , "law@redhat.com" , "Zamyatin, Igor" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2016-05/txt/msg00717.txt.bz2 On Tue, May 10, 2016 at 4:54 PM, Koval, Julia wrote: > Gentle ping. > > -----Original Message----- > From: Koval, Julia > Sent: Wednesday, April 20, 2016 4:42 PM > To: gcc-patches@gcc.gnu.org > Cc: Lu, Hongjiu ; vaalfreja@gmail.com; ubizjak@gmai= l.com; law@redhat.com; Zamyatin, Igor > Subject: [PATCH] x86 interrupt attribute patch [2/2] > > Hi, > Here is the new version of interrupt attribute patch. Bootstraped/regtest= ed for Linux/x86_64. Ok for trunk? > > The interrupt and exception handlers are called by x86 processors. X86 h= ardware pushes information onto stack and calls the handler. The requireme= nts 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 excepti= on 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. Support both 32-bit and 64-bit modes. > 2. Flexible for compilers to optimize. > 3. Easy to use by programmers. > > To implement interrupt and exception handlers for x86 processors, a compi= ler should support: > > 'interrupt' attribute > > Use this attribute to indicate that the specified function with mandatory= arguments is an interrupt or exception handler. The compiler generates fu= nction entry and exit sequences suitable for use in an interrupt handler wh= en this attribute is present. The 'IRET' instruction, instead of the 'RET'= instruction, is used to return from interrupt or exception handlers. All = registers, except for the EFLAGS register which is restored by the 'IRET' i= nstruction, are preserved by the compiler. > If the compiler generates MPX, SSE, MMX or x87 instructions in an interru= pt or exception handler, or functions called from an interrupt or exception= handler may contain MPX, SSE, MMX or x87 instructions, the compiler must s= ave and restore the corresponding state. > > Since the direction flag in the FLAGS register in interrupt (exception) h= andlers is undetermined, cld instruction must be emitted in function prolog= ue if rep string instructions are used in interrupt (exception) handler or = interrupt (exception) handler isn't a leaf function. > > Any interruptible-without-stack-switch code must be compiled with -mno-re= d-zone since interrupt handlers can and will, because of the hardware desig= n, touch the red zone. > > 1. interrupt handler must be declared with a mandatory pointer argument: > > struct interrupt_frame; > > __attribute__ ((interrupt)) > void > f (struct interrupt_frame *frame) > { > ... > } > > and user must properly define the structure the pointer pointing to. > > 2. exception handler: > > The exception handler is very similar to the interrupt handler with a dif= ferent mandatory function signature: > > typedef unsigned int uword_t __attribute__ ((mode (__word__))); > > struct interrupt_frame; > > __attribute__ ((interrupt)) > void > f (struct interrupt_frame *frame, uword_t error_code) { ... > } > > and compiler pops the error code off stack before the 'IRET' instruction. > > The exception handler should only be used for exceptions which push an er= ror code and all other exceptions must use the interrupt handler. > The system will crash if the wrong handler is used. > > 'no_caller_saved_registers' attribute > > Use this attribute to indicate that the specified function has no caller-= saved registers. That is, all registers are callee-saved. > The compiler generates proper function entry and exit sequences to save a= nd restore any modified registers, except for the EFLAGS register. > If the compiler generates MPX, SSE, MMX or x87 instructions in a function= with 'no_caller_saved_registers' attribute or functions called from a func= tion with 'no_caller_saved_registers' attribute may contain MPX, SSE, MMX o= r x87 instructions, the compiler must save and restore the corresponding st= ate. > > The user can call functions specified with 'no_caller_saved_registers' > attribute from an interrupt handler without saving and restoring all call= clobbered registers. > > On x86, interrupt handlers are only called by processors which push inter= rupt data onto stack at the address where the normal return address is. In= terrupt handlers must access interrupt data via pointers so that they can u= pdate interrupt data. > gcc/ > > PR target/66960 > PR target/67630 > PR target/67634 > PR target/67841 > PR target/68037 > PR target/68618 > PR target/68661 > PR target/69575 > PR target/69596 > PR target/69734 > * config/i386/i386-protos.h (ix86_epilogue_uses): New prototype. > * config/i386/i386.c (ix86_conditional_register_usage): Preserve > all registers, except for function return registers if there are > no caller-saved registers. > (ix86_set_func_type): New function. > (ix86_set_current_function): Call ix86_set_func_type to set > no_caller_saved_registers and func_type. Call reinit_regs if > caller-saved registers are changed. Don't allow MPX, SSE, MMX > nor x87 instructions in interrupt handler nor function with > no_caller_saved_registers attribute. > (ix86_function_ok_for_sibcall): Return false if there are no > caller-saved registers. > (type_natural_mode): Don't warn ABI change for MMX in interrupt > handler. > (ix86_function_arg_advance): Skip for callee in interrupt > handler. > (ix86_function_arg): Return special arguments in interrupt > handler. > (ix86_promote_function_mode): Promote pointer to word_mode only > for normal functions. > (ix86_can_use_return_insn_p): Don't use `ret' instruction in > interrupt handler. > (ix86_epilogue_uses): New function. > (ix86_hard_regno_scratch_ok): Likewise. > (ix86_save_reg): Preserve all registers in interrupt handler > after reload. Preserve all registers, except for function > return registers, if there are no caller-saved registers after > reload. > (find_drap_reg): Always use callee-saved register if there are > no caller-saved registers. > (ix86_minimum_incoming_stack_boundary): Return MIN_STACK_BOUNDARY > for interrupt handler. > (ix86_expand_prologue): Don't allow DRAP in interrupt handler. > Emit cld instruction if stringops are used in interrupt handler > or interrupt handler isn't a leaf function. > (ix86_expand_epilogue): Generate interrupt return for interrupt > handler and pop the 'ERROR_CODE' off the stack before interrupt > return in exception handler. > (ix86_expand_call): Disallow calling interrupt handler directly. > If there are no caller-saved registers, mark all registers that > are clobbered by the call which returns as clobbered. > (ix86_handle_no_caller_saved_registers_attribute): New function. > (ix86_handle_interrupt_attribute): Likewise. > (ix86_attribute_table): Add interrupt and no_caller_saved_registe= rs > attributes. > (TARGET_HARD_REGNO_SCRATCH_OK): Likewise. > * config/i386/i386.h (ACCUMULATE_OUTGOING_ARGS): Use argument > accumulation in interrupt function if stack may be realigned to > avoid DRAP. > (EPILOGUE_USES): New. > (function_type): New enum. > (machine_function): Add func_type and no_caller_saved_registers. > * config/i386/i386.md (UNSPEC_INTERRUPT_RETURN): New. > (interrupt_return): New pattern. > * doc/extend.texi: Document x86 interrupt and > no_caller_saved_registers attributes. > > gcc/testsuite/ > > PR target/66960 > PR target/67630 > PR target/67634 > PR target/67841 > PR target/68037 > PR target/68618 > PR target/68661 > PR target/69575 > PR target/69596 > PR target/69734 > * gcc.dg/guality/pr68037-1.c: New test. > * gcc.dg/guality/pr68037-2.c: Likewise. > * gcc.dg/guality/pr68037-3.c: Likewise. > * gcc.dg/torture/pr68037-1.c: Likewise. > * gcc.dg/torture/pr68037-2.c: Likewise. > * gcc.dg/torture/pr68037-3.c: Likewise. > * gcc.dg/torture/pr68661-1a.c: Likewise. > * gcc.dg/torture/pr68661-1b.c: Likewise. > * gcc.target/i386/interrupt-1.c: Likewise. > * gcc.target/i386/interrupt-2.c: Likewise. > * gcc.target/i386/interrupt-3.c: Likewise. > * gcc.target/i386/interrupt-4.c: Likewise. > * gcc.target/i386/interrupt-5.c: Likewise. > * gcc.target/i386/interrupt-6.c: Likewise. > * gcc.target/i386/interrupt-7.c: Likewise. > * gcc.target/i386/interrupt-8.c: Likewise. > * gcc.target/i386/interrupt-9.c: Likewise. > * gcc.target/i386/interrupt-10.c: Likewise. > * gcc.target/i386/interrupt-11.c: Likewise. > * gcc.target/i386/interrupt-12.c: Likewise. > * gcc.target/i386/interrupt-13.c: Likewise. > * gcc.target/i386/interrupt-14.c: Likewise. > * gcc.target/i386/interrupt-15.c: Likewise. > * gcc.target/i386/interrupt-16.c: Likewise. > * gcc.target/i386/interrupt-17.c: Likewise. > * gcc.target/i386/interrupt-18.c: Likewise. > * gcc.target/i386/interrupt-19.c: Likewise. > * gcc.target/i386/interrupt-20.c: Likewise. > * gcc.target/i386/interrupt-21.c: Likewise. > * gcc.target/i386/interrupt-22.c: Likewise. > * gcc.target/i386/interrupt-23.c: Likewise. > * gcc.target/i386/interrupt-24.c: Likewise. > * gcc.target/i386/interrupt-25.c: Likewise. > * gcc.target/i386/interrupt-26.c: Likewise. > * gcc.target/i386/interrupt-27.c: Likewise. > * gcc.target/i386/interrupt-28.c: Likewise. > * gcc.target/i386/interrupt-387-err-1.c: Likewise. > * gcc.target/i386/interrupt-387-err-2.c: Likewise. > * gcc.target/i386/interrupt-bnd-err-1.c: Likewise. > * gcc.target/i386/interrupt-bnd-err-2.c: Likewise. > * gcc.target/i386/interrupt-iamcu.c: Likewise. > * gcc.target/i386/interrupt-mmx-err-1.c: Likewise. > * gcc.target/i386/interrupt-mmx-err-2.c: Likewise. > * gcc.target/i386/interrupt-redzone-1.c: Likewise. > * gcc.target/i386/interrupt-redzone-2.c: Likewise. > * gcc.target/i386/interrupt-sibcall-1.c: Likewise. > * gcc.target/i386/interrupt-sibcall-2.c: Likewise. > * gcc.target/i386/interrupt-switch-abi.c: Likewise. OK for mainline, but please commit patch [1/2] first. Thanks, Uros.