Hi, is there a way to prevent gcc 4.3.x from doing bad optimizations? I attached an example that shows the performance degradation for a source compiled with -Os (-O2 is similar) for target avr. The code from the new compiler increased by at about 30% with respect to good old 3.4.6 and needs more as double of stack slots (13 instead of 6). text data bss dec hex filename 156 0 0 156 9c foo-3.4.6.o 206 0 0 206 ce foo-4.3.2.o Moreover, it expands a rather trivial address computation into a multiplication on a target without hardware multiplier, so there is additional, unacceptable time and code penalty caused by a call to __mulhi3 from libgcc2. The multiplication is by -2, i.e. trivial I tried various options like -fno-tree-loop-im etc. but no -fno-Option seems to be able to stop gcc from generating the highly expensive, innecessary multiplications. Can you give me some hints? Greets Georg-Johann
# 1 "foo.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "foo.c" # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 1 3 # 80 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/inttypes.h" 1 3 # 37 "e:/winavr-20081205/lib/gcc/../../avr/include/inttypes.h" 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/stdint.h" 1 3 # 121 "e:/winavr-20081205/lib/gcc/../../avr/include/stdint.h" 3 typedef int int8_t __attribute__((__mode__(__QI__))); typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); typedef int int16_t __attribute__ ((__mode__ (__HI__))); typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); typedef int int32_t __attribute__ ((__mode__ (__SI__))); typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); typedef int int64_t __attribute__((__mode__(__DI__))); typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); # 142 "e:/winavr-20081205/lib/gcc/../../avr/include/stdint.h" 3 typedef int16_t intptr_t; typedef uint16_t uintptr_t; # 159 "e:/winavr-20081205/lib/gcc/../../avr/include/stdint.h" 3 typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; # 213 "e:/winavr-20081205/lib/gcc/../../avr/include/stdint.h" 3 typedef int8_t int_fast8_t; typedef uint8_t uint_fast8_t; typedef int16_t int_fast16_t; typedef uint16_t uint_fast16_t; typedef int32_t int_fast32_t; typedef uint32_t uint_fast32_t; typedef int64_t int_fast64_t; typedef uint64_t uint_fast64_t; # 273 "e:/winavr-20081205/lib/gcc/../../avr/include/stdint.h" 3 typedef int64_t intmax_t; typedef uint64_t uintmax_t; # 38 "e:/winavr-20081205/lib/gcc/../../avr/include/inttypes.h" 2 3 # 77 "e:/winavr-20081205/lib/gcc/../../avr/include/inttypes.h" 3 typedef int32_t int_farptr_t; typedef uint32_t uint_farptr_t; # 81 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 2 3 # 1 "e:\\winavr-20081205\\bin\\../lib/gcc/avr/4.3.2/include/stddef.h" 1 3 4 # 214 "e:\\winavr-20081205\\bin\\../lib/gcc/avr/4.3.2/include/stddef.h" 3 4 typedef unsigned int size_t; # 82 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 2 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 1 3 # 99 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/sfr_defs.h" 1 3 # 100 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 284 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/iotn85.h" 1 3 # 38 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/iotn85.h" 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/iotnx5.h" 1 3 # 39 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/iotn85.h" 2 3 # 285 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 334 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/portpins.h" 1 3 # 335 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/common.h" 1 3 # 337 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/version.h" 1 3 # 339 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/fuse.h" 1 3 # 234 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/fuse.h" 3 typedef struct { unsigned char low; unsigned char high; unsigned char extended; } __fuse_t; # 342 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 1 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/lock.h" 1 3 # 345 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/io.h" 2 3 # 83 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 2 3 # 211 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 3 typedef void prog_void __attribute__((__progmem__)); typedef char prog_char __attribute__((__progmem__)); typedef unsigned char prog_uchar __attribute__((__progmem__)); typedef int8_t prog_int8_t __attribute__((__progmem__)); typedef uint8_t prog_uint8_t __attribute__((__progmem__)); typedef int16_t prog_int16_t __attribute__((__progmem__)); typedef uint16_t prog_uint16_t __attribute__((__progmem__)); typedef int32_t prog_int32_t __attribute__((__progmem__)); typedef uint32_t prog_uint32_t __attribute__((__progmem__)); typedef int64_t prog_int64_t __attribute__((__progmem__)); typedef uint64_t prog_uint64_t __attribute__((__progmem__)); # 744 "e:/winavr-20081205/lib/gcc/../../avr/include/avr/pgmspace.h" 3 extern const prog_void * memchr_P(const prog_void *, int __val, size_t __len) __attribute__((__const__)); extern int memcmp_P(const void *, const prog_void *, size_t) __attribute__((__pure__)); extern void *memcpy_P(void *, const prog_void *, size_t); extern void *memmem_P(const void *, size_t, const prog_void *, size_t) __attribute__((__pure__)); extern const prog_void * memrchr_P(const prog_void *, int __val, size_t __len) __attribute__((__const__)); extern char *strcat_P(char *, const prog_char *); extern const prog_char * strchr_P(const prog_char *, int __val) __attribute__((__const__)); extern const prog_char * strchrnul_P(const prog_char *, int __val) __attribute__((__const__)); extern int strcmp_P(const char *, const prog_char *) __attribute__((__pure__)); extern char *strcpy_P(char *, const prog_char *); extern int strcasecmp_P(const char *, const prog_char *) __attribute__((__pure__)); extern char *strcasestr_P(const char *, const prog_char *) __attribute__((__pure__)); extern size_t strcspn_P(const char *__s, const prog_char * __reject) __attribute__((__pure__)); extern size_t strlcat_P (char *, const prog_char *, size_t ); extern size_t strlcpy_P (char *, const prog_char *, size_t ); extern size_t strlen_P(const prog_char *) __attribute__((__const__)); extern size_t strnlen_P(const prog_char *, size_t) __attribute__((__const__)); extern int strncmp_P(const char *, const prog_char *, size_t) __attribute__((__pure__)); extern int strncasecmp_P(const char *, const prog_char *, size_t) __attribute__((__pure__)); extern char *strncat_P(char *, const prog_char *, size_t); extern char *strncpy_P(char *, const prog_char *, size_t); extern char *strpbrk_P(const char *__s, const prog_char * __accept) __attribute__((__pure__)); extern const prog_char * strrchr_P(const prog_char *, int __val) __attribute__((__const__)); extern char *strsep_P(char **__sp, const prog_char * __delim); extern size_t strspn_P(const char *__s, const prog_char * __accept) __attribute__((__pure__)); extern char *strstr_P(const char *, const prog_char *) __attribute__((__pure__)); # 2 "foo.c" 2 # 1 "codes.h" 1 # 15 "codes.h" struct codeElement { uint16_t onTime; uint16_t offTime; }; # 39 "codes.h" typedef struct { uint8_t timer_val; uint16_t puls[10]; uint8_t codes[]; } powercode_t; extern const powercode_t * const powerCodes[] __attribute__((__progmem__)); extern const uint8_t num_codes; # 3 "foo.c" 2 # 36 "foo.c" extern void xmitCodeElement (uint16_t, uint16_t); void foo (void) { uint8_t i, j; uint16_t ontime, offtime; for (i=0; i < num_codes; i++) { powercode_t * code = (powercode_t*) (__extension__({ uint16_t __addr16 = (uint16_t)((uint16_t)(& powerCodes[i])); uint16_t __result; __asm__ ( "lpm %A0, Z+" "\n\t" "lpm %B0, Z" "\n\t" : "=r" (__result), "=z" (__addr16) : "1" (__addr16) ); __result; })); uint8_t freq = (__extension__({ uint16_t __addr16 = (uint16_t)((uint16_t)(& code->timer_val)); uint8_t __result; __asm__ ( "lpm %0, Z" "\n\t" : "=r" (__result) : "z" (__addr16) ); __result; })); (*(volatile uint8_t *)((0x29) + 0x20)) = (*(volatile uint8_t *)((0x2D) + 0x20)) = freq; j = 0; do { uint8_t on_off = (__extension__({ uint16_t __addr16 = (uint16_t)((uint16_t)(& code->codes[j])); uint8_t __result; __asm__ ( "lpm %0, Z" "\n\t" : "=r" (__result) : "z" (__addr16) ); __result; })); uint8_t on_idx = on_off & 0xf; uint8_t off_idx = on_off >> 4; ontime = (__extension__({ uint16_t __addr16 = (uint16_t)((uint16_t)(& code->puls[on_idx-1])); uint16_t __result; __asm__ ( "lpm %A0, Z+" "\n\t" "lpm %B0, Z" "\n\t" : "=r" (__result), "=z" (__addr16) : "1" (__addr16) ); __result; })); offtime = 0; if (off_idx) offtime = (__extension__({ uint16_t __addr16 = (uint16_t)((uint16_t)(& code->puls[off_idx-1])); uint16_t __result; __asm__ ( "lpm %A0, Z+" "\n\t" "lpm %B0, Z" "\n\t" : "=r" (__result), "=z" (__addr16) : "1" (__addr16) ); __result; })); xmitCodeElement (ontime, offtime); j++; } while (offtime != 0); } }
.file "foo.c" .arch attiny85 __SREG__ = 0x3f __SP_H__ = 0x3e __SP_L__ = 0x3d __tmp_reg__ = 0 __zero_reg__ = 1 .global __do_copy_data .global __do_clear_bss ; GNU C version 3.4.6 (avr) ; compiled by GNU C version 3.4.2 (mingw-special). ; GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32702 ; options passed: -fpreprocessed -mmcu=attiny85 -auxbase -Os -W -Wall ; -Winline -Wstrict-prototypes -fverbose-asm -fno-keep-inline-functions ; -fno-common ; options enabled: -feliminate-unused-debug-types -fdefer-pop ; -fomit-frame-pointer -foptimize-sibling-calls -funit-at-a-time ; -fcse-follow-jumps -fcse-skip-blocks -fexpensive-optimizations ; -fthread-jumps -fstrength-reduce -fpeephole -fforce-mem -ffunction-cse ; -fkeep-static-consts -fcaller-saves -freg-struct-return -fgcse ; -fgcse-lm -fgcse-sm -fgcse-las -floop-optimize -fcrossjumping ; -fif-conversion -fif-conversion2 -frerun-cse-after-loop ; -frerun-loop-opt -fdelete-null-pointer-checks -fsched-interblock ; -fsched-spec -fsched-stalled-insns -fsched-stalled-insns-dep ; -fbranch-count-reg -freorder-functions -fcprop-registers -fverbose-asm ; -fregmove -foptimize-register-move -fargument-alias -fstrict-aliasing ; -fmerge-constants -fzero-initialized-in-bss -fident -fpeephole2 ; -fguess-branch-probability -fmath-errno -ftrapping-math ; -minit-stack=__stack -mmcu=attiny85 .text .global foo .type foo, @function foo: /* prologue: frame size=0 */ push r14 push r15 push r16 push r17 push r28 push r29 /* prologue end (size=6) */ clr r14 ; i ; 10 *movqi/7 [length = 1] lds r24,num_codes ; num_codes, num_codes ; 135 *movqi/4 [length = 2] cp r14,r24 ; i, num_codes ; 136 cmpqi/1 [length = 1] brlo .+2 ; ; 137 branch [length = 2] rjmp .L11 ; .L9: mov r30,r14 ; __addr16, i ; 22 zero_extendqihi2/2 [length = 2] clr r31 ; __addr16 add r30,r30 ; __addr16, __addr16 ; 24 *addhi3/1 [length = 2] adc r31,r31 ; __addr16, __addr16 subi r30,lo8(-(powerCodes)) ; __addr16, ; 25 *addhi3/4 [length = 2] sbci r31,hi8(-(powerCodes)) ; __addr16, /* #APP */ lpm r16, Z+ ; __result lpm r17, Z ; __result /* #NOAPP */ mov r31,r17 ; , __result ; 150 *movhi/1 [length = 2] mov r30,r16 ; , __result /* #APP */ lpm r24, Z ; __result /* #NOAPP */ out 77-0x20,r24 ; , __result ; 39 *movqi/3 [length = 1] in r24,77-0x20 ; tmp57, ; 40 *movqi/4 [length = 1] out 73-0x20,r24 ; , tmp57 ; 41 *movqi/3 [length = 1] clr r15 ; j ; 43 *movqi/7 [length = 1] .L5: mov r31,r17 ; tmp61, __result ; 151 *movhi/1 [length = 2] mov r30,r16 ; tmp61, __result add r30,r15 ; tmp61, j ; 53 *addhi3_zero_extend [length = 2] adc r31,__zero_reg__ ; tmp61 adiw r30,21 ; tmp61, ; 54 *addhi3/2 [length = 1] /* #APP */ lpm r24, Z ; __result /* #NOAPP */ mov r18,r24 ; off_idx, __result ; 152 *movqi/1 [length = 1] swap r18 ; off_idx ; 61 lshrqi3/5 [length = 2] andi r18,0x0f ; off_idx andi r24,lo8(15) ; __result, ; 148 andqi3/2 [length = 1] mov r30,r24 ; __addr16, __result ; 65 zero_extendqihi2/2 [length = 2] clr r31 ; __addr16 add r30,r30 ; __addr16, __addr16 ; 67 *addhi3/1 [length = 2] adc r31,r31 ; __addr16, __addr16 add r30,r16 ; __addr16, __result ; 68 *addhi3/1 [length = 2] adc r31,r17 ; __addr16, __result sbiw r30,1 ; __addr16, ; 69 *addhi3/3 [length = 1] /* #APP */ lpm r24, Z+ ; __result lpm r25, Z ; __result /* #NOAPP */ ldi r28,lo8(0) ; offtime, ; 74 *movhi/4 [length = 2] ldi r29,hi8(0) ; offtime, tst r18 ; off_idx ; 76 tstqi [length = 1] breq .L8 ; , ; 77 branch [length = 1] mov r30,r18 ; __addr16, off_idx ; 81 zero_extendqihi2/2 [length = 2] clr r31 ; __addr16 add r30,r30 ; __addr16, __addr16 ; 83 *addhi3/1 [length = 2] adc r31,r31 ; __addr16, __addr16 add r30,r16 ; __addr16, __result ; 84 *addhi3/1 [length = 2] adc r31,r17 ; __addr16, __result sbiw r30,1 ; __addr16, ; 85 *addhi3/3 [length = 1] /* #APP */ lpm r28, Z+ ; offtime lpm r29, Z ; offtime /* #NOAPP */ .L8: mov r22,r28 ; offtime, offtime ; 91 *movhi/1 [length = 2] mov r23,r29 ; offtime, offtime rcall xmitCodeElement ; ; 93 call_insn/3 [length = 1] inc r15 ; j ; 95 addqi3/3 [length = 1] or r28,r29 ; offtime ; 100 tsthi/1 [length = 1] brne .L5 ; , ; 101 branch [length = 1] inc r14 ; i ; 110 addqi3/3 [length = 1] lds r24,num_codes ; num_codes, num_codes ; 13 *movqi/4 [length = 2] cp r14,r24 ; i, num_codes ; 14 cmpqi/1 [length = 1] brsh .+2 ; ; 15 branch [length = 2] rjmp .L9 ; .L11: /* epilogue: frame size=0 */ pop r29 pop r28 pop r17 pop r16 pop r15 pop r14 ret /* epilogue end (size=7) */ /* function foo size 96 (83) */ .size foo, .-foo /* File "foo.c": code 96 = 0x0060 ( 83), prologues 6, epilogues 7 */
# 1 "foo.c" # 1 "<built-in>" # 1 "<command line>" # 1 "foo.c" # 1 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 1 3 # 78 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 3 # 1 "E:/WinAVR_20060421/avr/include/inttypes.h" 1 3 # 37 "E:/WinAVR_20060421/avr/include/inttypes.h" 3 # 1 "E:/WinAVR_20060421/avr/include/stdint.h" 1 3 # 116 "E:/WinAVR_20060421/avr/include/stdint.h" 3 typedef int int8_t __attribute__((__mode__(__QI__))); typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); typedef int int16_t __attribute__ ((__mode__ (__HI__))); typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); typedef int int32_t __attribute__ ((__mode__ (__SI__))); typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); typedef int int64_t __attribute__((__mode__(__DI__))); typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); # 135 "E:/WinAVR_20060421/avr/include/stdint.h" 3 typedef int16_t intptr_t; typedef uint16_t uintptr_t; # 152 "E:/WinAVR_20060421/avr/include/stdint.h" 3 typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; # 200 "E:/WinAVR_20060421/avr/include/stdint.h" 3 typedef int8_t int_fast8_t; typedef uint8_t uint_fast8_t; typedef int16_t int_fast16_t; typedef uint16_t uint_fast16_t; typedef int32_t int_fast32_t; typedef uint32_t uint_fast32_t; typedef int64_t int_fast64_t; typedef uint64_t uint_fast64_t; # 249 "E:/WinAVR_20060421/avr/include/stdint.h" 3 typedef int64_t intmax_t; typedef uint64_t uintmax_t; # 38 "E:/WinAVR_20060421/avr/include/inttypes.h" 2 3 # 76 "E:/WinAVR_20060421/avr/include/inttypes.h" 3 typedef int32_t int_farptr_t; typedef uint32_t uint_farptr_t; # 79 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 2 3 # 1 "e:\\WinAVR_20060421\\bin/../lib/gcc/avr/3.4.6/include/stddef.h" 1 3 4 # 213 "e:\\WinAVR_20060421\\bin/../lib/gcc/avr/3.4.6/include/stddef.h" 3 4 typedef unsigned int size_t; # 80 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 2 3 # 1 "E:/WinAVR_20060421/avr/include/avr/io.h" 1 3 # 86 "E:/WinAVR_20060421/avr/include/avr/io.h" 3 # 1 "E:/WinAVR_20060421/avr/include/avr/sfr_defs.h" 1 3 # 87 "E:/WinAVR_20060421/avr/include/avr/io.h" 2 3 # 298 "E:/WinAVR_20060421/avr/include/avr/io.h" 3 # 1 "E:/WinAVR_20060421/avr/include/avr/iotn85.h" 1 3 # 38 "E:/WinAVR_20060421/avr/include/avr/iotn85.h" 3 # 1 "E:/WinAVR_20060421/avr/include/avr/iotnx5.h" 1 3 # 39 "E:/WinAVR_20060421/avr/include/avr/iotn85.h" 2 3 # 299 "E:/WinAVR_20060421/avr/include/avr/io.h" 2 3 # 328 "E:/WinAVR_20060421/avr/include/avr/io.h" 3 # 1 "E:/WinAVR_20060421/avr/include/avr/portpins.h" 1 3 # 329 "E:/WinAVR_20060421/avr/include/avr/io.h" 2 3 # 338 "E:/WinAVR_20060421/avr/include/avr/io.h" 3 # 1 "E:/WinAVR_20060421/avr/include/avr/version.h" 1 3 # 339 "E:/WinAVR_20060421/avr/include/avr/io.h" 2 3 # 81 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 2 3 # 203 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 3 typedef void prog_void __attribute__((__progmem__)); typedef char prog_char __attribute__((__progmem__)); typedef unsigned char prog_uchar __attribute__((__progmem__)); typedef int8_t prog_int8_t __attribute__((__progmem__)); typedef uint8_t prog_uint8_t __attribute__((__progmem__)); typedef int16_t prog_int16_t __attribute__((__progmem__)); typedef uint16_t prog_uint16_t __attribute__((__progmem__)); typedef int32_t prog_int32_t __attribute__((__progmem__)); typedef uint32_t prog_uint32_t __attribute__((__progmem__)); typedef int64_t prog_int64_t __attribute__((__progmem__)); typedef uint64_t prog_uint64_t __attribute__((__progmem__)); # 606 "E:/WinAVR_20060421/avr/include/avr/pgmspace.h" 3 extern void *memcpy_P(void *, const prog_void *, size_t); extern char *strcat_P(char *, const prog_char *); extern int strcmp_P(const char *, const prog_char *) __attribute__((__pure__)); extern char *strcpy_P(char *, const prog_char *); extern int strcasecmp_P(const char *, const prog_char *) __attribute__((__pure__)); extern size_t strlcat_P (char *, const prog_char *, size_t ); extern size_t strlcpy_P (char *, const prog_char *, size_t ); extern size_t strlen_P(const prog_char *) __attribute__((__const__)); extern size_t strnlen_P(const prog_char *, size_t) __attribute__((__const__)); extern int strncmp_P(const char *, const prog_char *, size_t) __attribute__((__pure__)); extern int strncasecmp_P(const char *, const prog_char *, size_t) __attribute__((__pure__)); extern char *strncat_P(char *, const prog_char *, size_t); extern char *strncpy_P(char *, const prog_char *, size_t); extern char *strstr_P(const char *, const prog_char *) __attribute__((__pure__)); # 2 "foo.c" 2 # 1 "codes.h" 1 # 15 "codes.h" struct codeElement { uint16_t onTime; uint16_t offTime; }; # 39 "codes.h" typedef struct { uint8_t timer_val; uint16_t puls[10]; uint8_t codes[]; } powercode_t; extern const powercode_t * const powerCodes[] __attribute__((__progmem__)); extern const uint8_t num_codes; # 3 "foo.c" 2 # 36 "foo.c" extern void xmitCodeElement (uint16_t, uint16_t); void foo (void) { uint8_t i, j; uint16_t ontime, offtime; for (i=0; i < num_codes; i++) { powercode_t * code = (powercode_t*) (__extension__({ uint16_t __addr16 = (uint16_t)(& powerCodes[i]); uint16_t __result; __asm__ ( "lpm %A0, Z+" "\n\t" "lpm %B0, Z" "\n\t" : "=r" (__result), "=z" (__addr16) : "1" (__addr16) ); __result; })); uint8_t freq = (__extension__({ uint16_t __addr16 = (uint16_t)(& code->timer_val); uint8_t __result; __asm__ ( "lpm %0, Z" "\n\t" : "=r" (__result) : "z" (__addr16) ); __result; })); (*(volatile uint8_t *)((0x29) + 0x20)) = (*(volatile uint8_t *)((0x2D) + 0x20)) = freq; j = 0; do { uint8_t on_off = (__extension__({ uint16_t __addr16 = (uint16_t)(& code->codes[j]); uint8_t __result; __asm__ ( "lpm %0, Z" "\n\t" : "=r" (__result) : "z" (__addr16) ); __result; })); uint8_t on_idx = on_off & 0xf; uint8_t off_idx = on_off >> 4; ontime = (__extension__({ uint16_t __addr16 = (uint16_t)(& code->puls[on_idx-1]); uint16_t __result; __asm__ ( "lpm %A0, Z+" "\n\t" "lpm %B0, Z" "\n\t" : "=r" (__result), "=z" (__addr16) : "1" (__addr16) ); __result; })); offtime = 0; if (off_idx) offtime = (__extension__({ uint16_t __addr16 = (uint16_t)(& code->puls[off_idx-1]); uint16_t __result; __asm__ ( "lpm %A0, Z+" "\n\t" "lpm %B0, Z" "\n\t" : "=r" (__result), "=z" (__addr16) : "1" (__addr16) ); __result; })); xmitCodeElement (ontime, offtime); j++; } while (offtime != 0); } }
.file "foo.c" __SREG__ = 0x3f __SP_H__ = 0x3e __SP_L__ = 0x3d __CCP__ = 0x34 __tmp_reg__ = 0 __zero_reg__ = 1 .global __do_copy_data .global __do_clear_bss ; GNU C (WinAVR 20081205) version 4.3.2 (avr) ; compiled by GNU C version 3.4.5 (mingw-vista special r3), GMP version 4.2.3, MPFR version 2.3.2. ; GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32702 ; options passed: -fpreprocessed foo.i -mmcu=attiny85 -Os -W -Wall ; -Winline -Wstrict-prototypes -fverbose-asm -fno-keep-inline-functions ; -fno-common -fno-inline-small-functions -fno-tree-scev-cprop ; -fno-split-wide-types ; options enabled: -falign-loops -fargument-alias -fauto-inc-dec ; -fbranch-count-reg -fcaller-saves -fcprop-registers -fcrossjumping ; -fcse-follow-jumps -fdefer-pop -fearly-inlining ; -feliminate-unused-debug-types -fexpensive-optimizations ; -fforward-propagate -ffunction-cse -fgcse -fgcse-lm ; -fguess-branch-probability -fident -fif-conversion -fif-conversion2 ; -finline-functions -finline-functions-called-once -fipa-pure-const ; -fipa-reference -fivopts -fkeep-static-consts -fleading-underscore ; -fmath-errno -fmerge-constants -fmerge-debug-strings ; -fmove-loop-invariants -fomit-frame-pointer -foptimize-register-move ; -foptimize-sibling-calls -fpeephole -fpeephole2 -freg-struct-return ; -fregmove -freorder-functions -frerun-cse-after-loop -fsched-interblock ; -fsched-spec -fsched-stalled-insns-dep -fsigned-zeros ; -fsplit-ivs-in-unroller -fstrict-aliasing -fstrict-overflow ; -fthread-jumps -ftoplevel-reorder -ftrapping-math -ftree-ccp ; -ftree-copy-prop -ftree-copyrename -ftree-dce -ftree-dominator-opts ; -ftree-dse -ftree-fre -ftree-loop-im -ftree-loop-ivcanon ; -ftree-loop-optimize -ftree-parallelize-loops= -ftree-reassoc ; -ftree-salias -ftree-sink -ftree-sra -ftree-store-ccp -ftree-ter ; -ftree-vect-loop-version -ftree-vrp -funit-at-a-time -fverbose-asm ; -fzero-initialized-in-bss ; Compiler executable checksum: 67867e0bb6a39ca5af7615e31f09b8c9 .text .global foo .type foo, @function foo: push r7 ; ; 121 *pushqi/1 [length = 1] push r8 ; ; 122 *pushqi/1 [length = 1] push r9 ; ; 123 *pushqi/1 [length = 1] push r10 ; ; 124 *pushqi/1 [length = 1] push r11 ; ; 125 *pushqi/1 [length = 1] push r12 ; ; 126 *pushqi/1 [length = 1] push r13 ; ; 127 *pushqi/1 [length = 1] push r14 ; ; 128 *pushqi/1 [length = 1] push r15 ; ; 129 *pushqi/1 [length = 1] push r16 ; ; 130 *pushqi/1 [length = 1] push r17 ; ; 131 *pushqi/1 [length = 1] push r28 ; ; 132 *pushqi/1 [length = 1] push r29 ; ; 133 *pushqi/1 [length = 1] /* prologue: function */ /* frame size = 0 */ lds r7,num_codes ; num_codes.4, num_codes ; 8 *movqi/4 [length = 2] ldi r25,lo8(powerCodes) ; , ; 153 *reload_inhi [length = 4] mov r14,r25 ; ivtmp.22, ldi r25,hi8(powerCodes) ; , mov r15,r25 ; ivtmp.22, clr r12 ; i ; 10 *movqi/7 [length = 1] ldi r24,lo8(1) ; , ; 152 *reload_inhi [length = 3] mov r8,r24 ; tmp82, mov r9,__zero_reg__ ; tmp82 rjmp .L2 ; ; 154 jump [length = 1] .L7: movw r30,r14 ; __addr16, ivtmp.22 ; 107 *movhi/1 [length = 1] /* #APP */ ; 45 "foo.c" 1 lpm r16, Z+ ; __result lpm r17, Z ; __result ; 0 "" 2 /* #NOAPP */ movw r30,r16 ; , __result ; 109 *movhi/1 [length = 1] /* #APP */ ; 47 "foo.c" 1 lpm r24, Z ; __result ; 0 "" 2 /* #NOAPP */ out 77-32,r24 ; ,, __result ; 18 *movqi/3 [length = 1] in r24,77-32 ; D.1362,, ; 20 *movqi/4 [length = 1] out 73-32,r24 ; ,, D.1362 ; 22 *movqi/3 [length = 1] movw r10,r16 ; D.1366, __result ; 110 *movhi/1 [length = 1] sec ; 23 *addhi3/5 [length = 3] adc r10,__zero_reg__ ; D.1366 adc r11,__zero_reg__ ; D.1366 clr r13 ; j ; 96 *movqi/7 [length = 1] .L6: mov r30,r13 ; j, j ; 117 *movqi/1 [length = 1] ldi r31,lo8(0) ; j, ; 118 *movqi/2 [length = 1] adiw r30,21 ; j, ; 27 *addhi3/2 [length = 1] add r30,r16 ; j, __result ; 28 *addhi3/1 [length = 2] adc r31,r17 ; j, __result /* #APP */ ; 55 "foo.c" 1 lpm r30, Z ; __result ; 0 "" 2 /* #NOAPP */ mov r20,r30 ; off_idx, __result ; 111 *movqi/1 [length = 1] swap r20 ; off_idx ; 119 *swap [length = 1] andi r20,lo8(15) ; off_idx, ; 120 andqi3/2 [length = 1] andi r30,lo8(15) ; __result, ; 31 andqi3/2 [length = 1] movw r24,r8 ; , tmp82 ; 112 *movhi/1 [length = 1] sub r24,r30 ; , __result ; 36 *subhi3_zero_extend1 [length = 2] sbc r25,__zero_reg__ ; ldi r22,lo8(-2) ; , ; 37 *movhi/4 [length = 2] ldi r23,hi8(-2) ; , rcall __mulhi3 ; 38 *mulhi3_call [length = 1] movw r30,r10 ; __addr16, D.1366 ; 113 *movhi/1 [length = 1] add r30,r24 ; __addr16, ; 40 *addhi3/1 [length = 2] adc r31,r25 ; __addr16, /* #APP */ ; 59 "foo.c" 1 lpm r18, Z+ ; __result lpm r19, Z ; __result ; 0 "" 2 /* #NOAPP */ tst r20 ; off_idx ; 42 tstqi [length = 1] brne .L3 ; , ; 43 branch [length = 1] ldi r28,lo8(0) ; offtime, ; 100 *movhi/4 [length = 2] ldi r29,hi8(0) ; offtime, rjmp .L4 ; ; 156 jump [length = 1] .L3: movw r24,r8 ; , tmp82 ; 114 *movhi/1 [length = 1] sub r24,r20 ; , off_idx ; 54 *subhi3_zero_extend1 [length = 2] sbc r25,__zero_reg__ ; ldi r22,lo8(-2) ; , ; 55 *movhi/4 [length = 2] ldi r23,hi8(-2) ; , rcall __mulhi3 ; 56 *mulhi3_call [length = 1] movw r30,r10 ; __addr16, D.1366 ; 115 *movhi/1 [length = 1] add r30,r24 ; __addr16, ; 58 *addhi3/1 [length = 2] adc r31,r25 ; __addr16, /* #APP */ ; 62 "foo.c" 1 lpm r28, Z+ ; offtime lpm r29, Z ; offtime ; 0 "" 2 /* #NOAPP */ .L4: movw r24,r18 ; , __result ; 64 *movhi/1 [length = 1] movw r22,r28 ; , offtime ; 65 *movhi/1 [length = 1] rcall xmitCodeElement ; ; 66 call_insn/3 [length = 1] or r28,r29 ; offtime ; 67 tsthi/1 [length = 1] breq .L5 ; , ; 68 branch [length = 1] inc r13 ; j ; 70 addqi3/3 [length = 1] rjmp .L6 ; ; 158 jump [length = 1] .L5: inc r12 ; i ; 76 addqi3/3 [length = 1] ldi r24,lo8(2) ; , ; 116 *movhi/4 [length = 2] ldi r25,hi8(2) ; , add r14,r24 ; ivtmp.22, ; 77 *addhi3/1 [length = 2] adc r15,r25 ; ivtmp.22, .L2: cp r12,r7 ; i, num_codes.4 ; 81 cmpqi/1 [length = 1] brsh .+2 ; ; 82 branch [length = 2] rjmp .L7 ; /* epilogue start */ pop r29 ; ; 136 popqi [length = 1] pop r28 ; ; 137 popqi [length = 1] pop r17 ; ; 138 popqi [length = 1] pop r16 ; ; 139 popqi [length = 1] pop r15 ; ; 140 popqi [length = 1] pop r14 ; ; 141 popqi [length = 1] pop r13 ; ; 142 popqi [length = 1] pop r12 ; ; 143 popqi [length = 1] pop r11 ; ; 144 popqi [length = 1] pop r10 ; ; 145 popqi [length = 1] pop r9 ; ; 146 popqi [length = 1] pop r8 ; ; 147 popqi [length = 1] pop r7 ; ; 148 popqi [length = 1] ret ; 149 return_from_epilogue [length = 1] .size foo, .-foo