Hi all, I have this interesting test case for you guys, and girls.
#include <avr/io.h> unsigned int GetStackPointer() { volatile unsigned int sp = (SPH << 8) | SPL; return sp; } int main(void) { while(1) { PORTA.OUT = GetStackPointer(); } } After building it with Atmel Studio 6.2 (default project settings, -mmcu=atxmega128a4u), AVR8/GNU C Compiler/Linker : 4.8.1 the .lss contains this gem: unsigned int GetStackPointer() { 21a: cf 93 push r28 21c: df 93 push r29 21e: 1f 92 push r1 220: 1f 92 push r1 222: cd b7 in r28, 0x3d ; 61 224: de b7 in r29, 0x3e ; 62 volatile unsigned int sp = (SPH << 8) | SPL; 226: 2e b7 in r18, 0x3e ; 62 228: 8d b7 in r24, 0x3d ; 61 22a: 90 e0 ldi r25, 0x00 ; 0 22c: 92 2b or r25, r18 22e: 89 83 std Y+1, r24 ; 0x01 230: 9a 83 std Y+2, r25 ; 0x02 return sp; 232: 89 81 ldd r24, Y+1 ; 0x01 234: 9a 81 ldd r25, Y+2 ; 0x02 } 236: 0f 90 pop r0 238: 0f 90 pop r0 23a: df 91 pop r29 23c: cf 91 pop r28 23e: 08 95 ret (Atmel Studio 7 (Version: 7.0.1417), gcc version 5.4.0 (AVR_8_bit_GNU_Toolchain_3.6.0_1734) does the same.) (If anyone interested I can attach the whole compressed project.) I'm mostly interested in the push r1, pop r0 pairs. Why? What are they doing? Who puts them there? Can someone "fix" the compiler/binutils? This seems to be a bug for me. AFAIK r1 is the zero reg, and r0 is temp reg, so this should not cause problems, so it's not a critical bug, only optimization issue. (Unnecessary __tmp_reg__ =__zero_reg__ ) I know that a better implementation would be unsigned int GetStackPointer() { unsigned int sp = (SPH << 8) | SPL; 21a: 2e b7 in r18, 0x3e ; 62 21c: 8d b7 in r24, 0x3d ; 61 21e: 90 e0 ldi r25, 0x00 ; 0 return sp; } 220: 92 2b or r25, r18 222: 08 95 ret (I'm not really sure why (SPH << 8) | SPL; isn't optimized correctly/fully, but it isn't the point here.) And my optimal solution is unsigned int GetStackPointer() { union { unsigned int w; unsigned char b[2];} w; w.b[0] = SPL; w.b[1] = SPH; 21a: 8d b7 in r24, 0x3d ; 61 21c: 9e b7 in r25, 0x3e ; 62 return w.w; } 21e: 08 95 ret But the weird volatile issue is not the point here. I see push r1, pop r0 in other functions, but this was the smallest test case that produced this anomaly. What do you think? Üdvözlettel, Szikra Istvan
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list