Note: re-sending message as it wasn't delivered to avr-libc-dev
On Fri, Feb 06, 2009 at 08:20:49AM -0700, Weddington, Eric wrote:
> > > +#define sleep_bod_disable() \
> > > +(__extension__({ \
> > > + __asm__ __volatile__ ( \
> > > + "ori %0,%1" \
> > > + : "+d" (MCUCR) \
> > > + : "i" (_BV(BODS) | _BV(BODSE)) \
> > > + ); \
> > > + __asm__ __volatile__ ( \
> > > + "andi %0,%1" \
> > > + : "=d" (MCUCR) \
> > > + : "i" (~_BV(BODSE)) \
> > > + ); \
> > > +}))
>
> [...]
>
> My big question is: Do I have to worry that GCC will somehow select a
> different register for MCUCR in the second __asm__ statement? I would
> think that since I am letting gcc select the register in the first
> __asm__ statement and having gcc do the output, that gcc will know
> which register that MCUCR lives in and can match that with the second
> __asm__ statement. From my tests, it seems that it is truly the case;
> the registers always match so that it generates (pseudocode):
>
> in X, 85-32
> ori X, 96
> out 85-32, X
> andi X, -33
> out 85-32, X
>
> where "X" is always the same high register ("d" constraint).
>
> This is important to meet the timed sequence needed to disable the BOD
> before sleeping.
Is there any disadvantage to including the OUT instructions directly
instead of breaking up the macro into two asm statements? This could
break unexpectedly - as you said the timing is crucial here.
I guess this trick would not work if the sfr contents could change
between OUTs - in the above case compiler assumed (why?) that they
won't.
Regards,
--
Krzysztof Kościuszkiewicz
Skype: dr.vee, Gadu: 111851, Jabber: [email protected]
"Simplicity is the ultimate sophistication" -- Leonardo da Vinci
_______________________________________________
AVR-libc-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev