>> Did I miss anything in the documentation that would tell me not to >> use auto variables in .initX sections after .init2 that sets the >> stack? > > If you declare the function being "naked", you cannot expect the > compiler to allocate a stack frame.
What one expects and reality are often different. Before I submit a patch for the documentation, to prevent others from shooting themselves in the foot, I wanted to make sure I understood how stack frames are working. In looking at the .lss file, I see something that I do not understand, when comping code for the XMega128A1 using GCC 4.7.1-rc1 Is the timing of the XMega OUT instruction different than a non-XMega part, in that it would prevent an interrupt between two sequential OUT instructions? What happens when an interrupt happens between the instructions that manipulate the stack pointer in the epilogue/prologue? If there is 256 bytes of stack head-room between the heap/bss maybe nothing (it would not be noticed as a problem). Going back to Anatoly original OS_Main/OS_Task patch: http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg03812.html Using his example code from that email, copied in to the file main.c, compiling using the Makefile at the end of this message, Non-XMega run: # Non-XMega the stack manipulation is properly protected. # The non-XMega parts delay a cycle when enabling interrupts, # hence it is safe to save stack_hi, enable interrupts, save_lo, # this code disables interrupts when modifying the stack pointer 0x3E/0x3F: 00000090 <__prologue_saves__>: [snip pushs] b4: cd b7 in r28, 0x3d ; 61 b6: de b7 in r29, 0x3e ; 62 b8: ca 1b sub r28, r26 ba: db 0b sbc r29, r27 bc: 0f b6 in r0, 0x3f ; 63 be: f8 94 cli ; Disable Interrupts c0: de bf out 0x3e, r29 ; 62 c2: 0f be out 0x3f, r0 ; 63 Enable Interrupts are delayed till after next instruction c4: cd bf out 0x3d, r28 ; 61 c6: 09 94 ijmp 000000c8 <__epilogue_restores__>: [snip pops] f0: 0f b6 in r0, 0x3f ; 63 f2: f8 94 cli ; Disable Interrupts f4: de bf out 0x3e, r29 ; 62 f6: 0f be out 0x3f, r0 ; 63 Enable Interrupts are delayed till after next instruction f8: cd bf out 0x3d, r28 ; 61 fa: ca 2f mov r28, r26 fc: db 2f mov r29, r27 fe: 08 95 ret I'm fine with the above code, however I question this XMega run: # This code DOES NOT disable interrupts when modifying the stack # pointer 0x3D/0x3E: 000002b0 <__prologue_saves__>: [snip pushs] 2d4: cd b7 in r28, 0x3d ; 61 2d6: de b7 in r29, 0x3e ; 62 2d8: ca 1b sub r28, r26 2da: db 0b sbc r29, r27 2dc: cd bf out 0x3d, r28 ; 61 ; [What happens if an interrupt happens between these two out instructions?] 2de: de bf out 0x3e, r29 ; 62 2e0: 19 94 eijmp 000002e2 <__epilogue_restores__>: [snip ldds] 306: ce 0f add r28, r30 308: d1 1d adc r29, r1 30a: cd bf out 0x3d, r28 ; 61 ; [What happens if an interrupt happens between these two out instructions?] 30c: de bf out 0x3e, r29 ; 62 30e: ed 01 movw r28, r26 310: 08 95 ret For anyone that wants to reproduce: # -------------- Cut Here main.c -------------- __attribute__ ((noinline)) int fn0(long a1, long a2, long a3, long a4, long a5) { return 0; } // Note this is commented out, OS_MAIN/OS_TASK are not relevant at this point: //__attribute__ ((OS_main)) int main(void) { volatile long long a; // local var, need function frame a = 1; return fn0(1, 2, 3, 4, 5); // use call-saved regs } # -------------- Cut Here -------------- And this Makefile of mine: # -------------- Cut Here Makefile -------------- MCU=atxmega128a1 # # NOTE, that this is commented out, it is the important point. # Uncomment to see the Xmega main.lss output and compare. # #M_MCU=-mmcu=$(MCU) SRC=main.c TARGET=main OBJDIR = . CSTANDARD = -std=gnu99 CFLAGS += $(CSTANDARD) # Functions prologues/epilogues expanded as call to appropriate # subroutines. Code size will be smaller. Use subroutines for function # prologue/epilogue. For complex functions that use many registers (that needs # to be saved/restored on function entry/exit), this saves some space at the # cost of a slightly increased execution time. CFLAGS += -mcall-prologues # -adhlns...: create assembler listing CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) # Be verbose: CFLAGS += -v ALL_CFLAGS = -v $(M_MCU) $(CFLAGS) # Tools: OBJDUMP = avr-objdump CC = avr-gcc SHELL = sh REMOVE = rm -f OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) all: build build: elf lss elf: $(TARGET).elf lss: $(TARGET).lss # Create extended listing file from ELF output file. %.lss: %.elf # -h Display section headers # -S Intermix source code with disassembly # -z Do not skip blocks of zero when disassembling $(OBJDUMP) -h -S -z $(OBJDIR)/$< > $(OBJDIR)/$@ %.elf: $(OBJ) $(info ) $(info ALL_CFLAGS = $(ALL_CFLAGS)) $(info ) $(CC) $(ALL_CFLAGS) $^ --output $(OBJDIR)/$@ $(LDFLAGS) # Compile: create object files from C source files. $(OBJDIR)/%.o : %.c $(CC) -c $(ALL_CFLAGS) $< -o $@ clean: $(REMOVE) $(TARGET).elf $(REMOVE) $(TARGET).lss # -------------- Cut Here -------------- _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list