From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ln01.mxout.alfaservers.com (ln01.mxout.alfaservers.com [85.17.185.57]) by sourceware.org (Postfix) with ESMTPS id 4F0E13858D28 for ; Sat, 18 Dec 2021 16:31:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4F0E13858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=blueice.be Authentication-Results: sourceware.org; spf=none smtp.mailfrom=blueice.be Received: from ip-83-134-247-29.dsl.scarlet.be ([83.134.247.29]:47840 helo=[192.168.178.60]) by ln01.alfaservers.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1myccX-0006rS-Jk for gcc-help@gcc.gnu.org; Sat, 18 Dec 2021 17:31:27 +0100 Subject: Re: RFC: AVR interrupt handling issue To: gcc-help@gcc.gnu.org References: From: Henri Cloetens Message-ID: <58038025-f6b3-4f41-00bb-31e28467420e@blueice.be> Date: Sat, 18 Dec 2021 17:31:18 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - ln01.alfaservers.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - blueice.be X-Get-Message-Sender-Via: ln01.alfaservers.com: authenticated_id: henri.cloetens@blueice.be X-Authenticated-Sender: ln01.alfaservers.com: henri.cloetens@blueice.be X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00, DEAR_SOMETHING, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, NICE_REPLY_A, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Dec 2021 16:31:28 -0000 Dear Sir, To customize the stack/unstacking, you need to modify the code of your backend port. I mean, the emitting of the stack/unstacking for the normal case (no interrupt, but function call), is in the backend part, NOT in the 'main' files, that are not intended to be modified. I would recommend you look there, and also in other backends, to find out how to do this. Best Regards, Henri. On 12/18/21 5:00 PM, Ian Molton wrote: > Hi all, > > I posted about this yesterday on the binutils list, but in the light of > day, I find myself re-thinking it; > > Right now, gcc will emit ISR prologues and epilogues such as this: > > __vector_35: > push r1 ; > push r0 ; > in r0,__SREG__ ; , > push r0 ; > clr __zero_reg__ ; > in r0,__RAMPZ__ ; , > push r0 ; > push r18 ; > push r19 > push r20 ; > push r21 ; > push r22 ; > push r23 ; > push r24 ; > push r25 ; > push r26 ; > push r27 ; > push r30 ; > push r31 ; > push r28 ; > push r29 ; > > // External func call to provoke pro/epilogue > // generation for this example... > call foo_func(); > ... > > pop r29 ; > pop r28 ; > pop r31 ; > pop r30 ; > pop r27 ; > pop r26 ; > pop r25 ; > pop r24 ; > pop r23 ; > pop r22 ; > pop r21 ; > pop r20 ; > pop r19 ; > pop r18 ; > pop r0 ; > out __RAMPZ__,r0 ; , > pop r0 ; > out __SREG__,r0 ; , > pop r0 ; > pop r1 ; > reti > > > The problem I have is that I want to switch to a separate irq stack when > I get an interrupt, which I cannot do in C, since all the prologue is > executed before the function body. > > I *can* do it if I use an assembler stub that then calls my ISR, which > switches stacks, and pushes the address of a custom epilogue onto the > stack, before executing the ISR, but this obviously wastes a lot of > cycles pushing the epilogue address, and by necessity, some of the > registers that the existing ISR prologue will redundantly push again. > > likewise, being able to insert my own epilogue sequence would allow me > to avoid an additional branch in the return path from the ISR. > > I can see two solutions to this problem: > > 1) Allow the compiler to omit certain registers from being saved in the > ISR prologue > > 2) Allow the user to specify custom pro/epilogue functions. > (-finstrument functions is similar, but not close enough) > > > 1) would work, but would require careful futzing about with the linker > to arrange the code in such a way that my prologue and epilogue are > located immediately around the ISR code. implementation could look like > -mno-save-isr-prologue="r0,r1,SREG,r26,r27" (or whatever regs the custom > prologue might save prior to the ISR prologue) > > 2) would be ideal. The compiler would know which registers the custom > prologue functions use, and would therefore be able to omit saving them > from the ISR prologue (and conversely from the epilogue). > > > Something like > > __attribute__ ((naked)) > void my_isr_prologue (void) > { > asm volatile("... whatever" : : : ); > } > > __attribute__ ((naked)) > void my_isr_epilogue (void) > { > asm volatile("... un-whatever" : : : ); > asm volatile("reti"); > } > > __attribute__ ((__isr_prologue__(my_isr_prologue, my_isr_epilogue))) > __attribute__ ((signal)) > __vector_35(void) > { > > ... do interrupt-y things ... > > } > > Thoguhts? I can see that I could implement option 1) thus: > > I specify -mno-gas-isr-prologues to force gcc to emit full > pro/epi-logues in the assembler output. > > I can modify gcc/config/avr/avr.c at this point: > > (~line 1893) > > avr_regs_to_save (&set); > > if (no-save-isr-prologue) > { > // FIXME Remove registers my custom prologue saves from the set > ... > } > > if (cfun->machine->is_interrupt || cfun->machine->is_signal) > { > ... > > which just leaves me with a (trivial) script to write that can stuff my > prologue / epilogue into the assembler, and re-assemble it into an object. > > The downside is that very simple ISRs which don't need many registers > will be less efficient. But we're calling C here, and I would write such > simple ISRs in assembler anyway. > > > Option 2) would require more knowledge of gcc than I currently have. > > > Other (doomed? cursed?) options: > > 3) > > It almost seems like this could be solved if a function with > __attribute__ ((signal)) could (inline-) call another function with the > same attribute. The first function would not need to save any call-used > registers other than the ones it uses itself, and the called function > would be able to avoid saving any call-used registers that were saved by > its calling function. > > I suspect, however that that approach is probably doomed to failure, as > inlining the second function (to avoid the overhead of calling it) would > presumably also relocate its register save instructions right back to > the first functions prologue, where it isn't wanted, as described above. > > 4) > > Use a naked function for the ISR and a script to process the assembler > in order to generate the prologue and epilogue > > The GCC docs state that one should not write C code in a naked function. > Presumably, as long as you add enough prologue to provide a C > environment, this isn't a problem, but its explicitly disallowed, and > would require me writing a script to parse the assembler output to > generate the entire prologue/epilogue sequences. In a sense, this is the > "purest" option, but I suspect properly determining the registers used > in this way would be a challenge. > > Presumably this is why the __gcc_isr method of generating pro/epilogues > is a task split between GCC and binutils? > > I am at a bit of a loss as to what information binutils is supposed to > have in this case, that gcc does not - why *is* it done that way? > > I've poked at inline asm with gcc, and find that I can use clobbers to > force a save of RAMPZ (etc.) from inline assembler within an ISR, so I > don't really "get" what the __gcc_isr approach is buying... the ability > to write inline asm without being explicit about clobbers? What for? > > Thoughts?