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

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

Re: [avr-gcc-list] Code Optimisation question re: volatile


From: David Brown
Subject: Re: [avr-gcc-list] Code Optimisation question re: volatile
Date: Fri, 23 Jul 2004 08:36:14 +0200

> This really isn't a critical question, but I'm curious... I want a 2
> pins (0, 1) to toggle on PORTB every time an interrupt it called.  This
> is the most optimised code I've come up with :
>
> pwm_state = (PORTB = pwm_state) ^ _b00000011;
>

I'm afraid you are getting the code you asked for in this case.  It is
possible to "cheat" about volatility - using *(unsigned char*)(&PORTB) will
strip the "volatile" qualifier, at the cost of a compile-time warning and
some ugly code.  However, there are better ways to do it - "better" in the
sense of being more readably and maintainable and also hopefully generating
better code (although I haven't tried compiling them).  My suggestion would
be simply:

    PORTB = pwm_state;
    pwm_state ^= _b00000011;

If you really want to use an ugly assign-to-assignment-result syntax (and
they are ugly, and low readability, and banned by any decent coding
standard), you could use:

    PORTB = (pwm_state ^= _b00000011);

(Note that here, pwm_state toggles *before* assignment to portb.)

mvh.,

David





> now, with -Os (size) optimisation, I get :
>
>  1325 053c 8091 0000            lds r24,pwm_state
>  1326 0540 88BB                 out 56-0x20,r24
>  1327 0542 88B3                 in r24,56-0x20
>  1328 0544 93E0                 ldi r25,lo8(3)
>  1329 0546 8927                 eor r24,r25
>  1330 0548 8093 0000            sts pwm_state,r24
>
> with -O3 optimisation, I get :
>
>  959 03c2 4091 0000             lds r20,pwm_state
>  960 03c6 48BB                  out 56-0x20,r20
>  961 03c8 28B3                  in r18,56-0x20
>  962 03ca 33E0                  ldi r19,lo8(3)
>  963 03cc 2327                  eor r18,r19
>  964 03ce 2093 0000             sts pwm_state,r18
>
> It seems to me that the ideal code would be :
>
>  1325 053c 8091 0000            lds r24,pwm_state
>  1326 0540 88BB                 out 56-0x20,r24
>  1328 0544 93E0                 ldi r25,lo8(3)
>  1329 0546 8927                 eor r24,r25
>  1330 0548 8093 0000            sts pwm_state,r24
>
> But it's not doing that because PORTB is defined as volatile.  Is there
> any way to temporarily get gcc to ignore the volatile flag for one
> subroutine?  I'm going to increase the xtal speed and see if that fixes
> my problem :/  If it don't work, use a bigger hammer.  I might try to do
> inline assembly if that fails... Is there any more efficient way of
> doing it?  This is on an atmega16, btw.. Oh, also, the prolog and
> epilogue are pretty big - would inline assembly get rid of that?
>
> thanks,
> Reza
>
> _______________________________________________
> avr-gcc-list mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list
>




reply via email to

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