This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
How avoid bad optimization in gcc >= 4.3?
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: gcc-help at gcc dot gnu dot org
- Date: Mon, 22 Dec 2008 13:40:43 +0100
- Subject: How avoid bad optimization in gcc >= 4.3?
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