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 Sdcc-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sdcc-user