On Fri, 18 Jan 2013, Vincent Pelletier wrote:
> Hi.
>
> I'm looking at asm generated for the following loop (8051, a CYCFX2LP
> actually) with sdcc 3.1.0#7066:
>
> __sbit __at 0x98+1 TI;
> void main() {
> while (!TI);
> TI = 0;
> }
>
> I get this:
>
> 00101$:
> jbc _TI,00115$
> sjmp 00101$
> 00115$:
>
> Wouldn't it be more efficient, for such bit polling loop, to use instead:
>
> 00101$:
> jnb _TI,00101$
> clr _TI
>
> The first version polls _TI every 7 cycles.
> The second version polls _TI every 4 cycles.
> If _TI is set on loop entry, the first version exits after 4 cycles while the
> second exits after 6 cycles. I believe it's sane to assume this is an unlikely
> event, so it shouldn't matter too much.
>
> Regards,
> --
> Vincent Pelletier
The compiler is thinking you are trying to use TI as a binary semaphore
and so implements the sequence with an atomic test and clear to eliminate
the possibility that an interrupt might occur between the while loop and
the assignment. It does not realize that you are simply polling a hardware
status bit followed by a write to a control bit (that happens to be at the
same location as the status bit). From a C perspective, both of these
operations look like the same C code.
With TI=0 not present, sdcc would not treat this as a special case and
instead would use the jnb instruction that you expected. If you were
simply curious about sdcc's odd instruction selection, I hope this is a
sufficient explanation of what's going on here. Otherwise, if this cycle
timing issue is critical in your application and you need to change this
behavior, there several methods you could use:
1) If there is any operation that is performed after TI=0, that could be
moved to preceed TI=0, then doing so would keep the compiler from seeing
this as a semaphore style operation.
2) You could split TI into two bits (that happen to be at the same
address) and use one for read and one for writes:
__sbit __at 0x98+1 TI;
__sbit __at 0x98+1 TIclear;
void main() {
while (!TI);
TIclear = 0;
}
3) You could use a custom peephole rule:
replace {
%3:
jbc %1,%2
sjmp %3
%2:
} by {
%3:
jnb %1,%3
clr %1
} if labelRefCount %2 1
(Just put this in a file "peep.def" (or whatever) and then add the option
"--peep-file peep.def" to the parameters passed to sdcc when compiling)
Erik
------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. SALE $99.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122912
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user