avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Where is the peephole optimizer?


From: Ben Jackson
Subject: [avr-gcc-list] Where is the peephole optimizer?
Date: Tue, 26 Jul 2005 21:42:01 -0700
User-agent: Mutt/1.5.6i

I'm getting started with AVR GCC, and I must say it's really nice to
have a real toolchain (vs PIC work with MPLAB or SDCC or GPASM).  I
built gcc 3.4.4 with no trouble and only one snag in avr-libc (which
has now been patched in 1.2.4 I see).

As a paranoid kind of guy, I'm spending a lot of time looking at the
output of the compiler to see how smart it is (SDCC will make you that
kind of paranoid in a hurry!).  I decided to see what floating point
math generated.  From:

        long int count, duration;
        double freq;

        freq = (double)count / (double)duration;

I get a few odd things.  Conversion to float:

 1f4:   80 91 68 00     lds     r24, 0x0068
 1f8:   90 91 69 00     lds     r25, 0x0069
 1fc:   a0 91 6a 00     lds     r26, 0x006A
 200:   b0 91 6b 00     lds     r27, 0x006B
 204:   68 2f           mov     r22, r24
 206:   79 2f           mov     r23, r25
 208:   8a 2f           mov     r24, r26
 20a:   9b 2f           mov     r25, r27
 20c:   7d d0           rcall   .+250           ; 0x308 <__floatsisf>

Why is it loading into one set of registers and then shuffling it
around?  I've tried -Os, -O3, and a bunch of flags.  Same thing.
On return the result goes in r14-r17, then repeat that two-step
for the other conversion.  Then the mother of all register shuffling:

 230:   b9 2f           mov     r27, r25
 232:   a8 2f           mov     r26, r24
 234:   97 2f           mov     r25, r23
 236:   86 2f           mov     r24, r22
 238:   28 2f           mov     r18, r24
 23a:   39 2f           mov     r19, r25
 23c:   4a 2f           mov     r20, r26
 23e:   5b 2f           mov     r21, r27
 240:   91 2f           mov     r25, r17
 242:   80 2f           mov     r24, r16
 244:   7f 2d           mov     r23, r15
 246:   6e 2d           mov     r22, r14
 248:   17 d0           rcall   .+46            ; 0x278 <__divsf3>

and then again to save, why use one register when two will do:

 24a:   b9 2f           mov     r27, r25
 24c:   a8 2f           mov     r26, r24
 24e:   97 2f           mov     r25, r23
 250:   86 2f           mov     r24, r22
 252:   80 93 60 00     sts     0x0060, r24
 256:   90 93 61 00     sts     0x0061, r25
 25a:   a0 93 62 00     sts     0x0062, r26
 25e:   b0 93 63 00     sts     0x0063, r27

What's going on?  Is 3.4.4 a bad version to be using?  What are the
most stable GCC releases for the AVR port?  I'm working with the
AT90S2313 (inherited a few tubes (!) of them for free) so I'm size
conscious here.  I've seen gcc do some phenominally clever tricks
with registers so I'm pretty sure this is not the best it can do.

Aside from that I noticed that libgcc is providing a really really
bloated __flostsisf, which is alleviated by remembering -lm to get
the sleek avr-libc version.  Are there any other gotches like that
I should be aware of?

Thanks!

-- 
Ben Jackson
<address@hidden>
http://www.ben.com/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]