Hi, I had a look at the problem. Actually,
if (a < HIDDEN) { do { /* something */ } while (a < HIDDEN); } is equivalent to while (a < HIDDEN) { /* something */ } and the latter saves code for one comparison. So changing that *should* not break/heal anything. I did not check that. I dug into the code generator to find what goes wrong: "a" resides in (MSB) r0x1004 ...r0x1007 (LSB), "exp" is in (MSB) r0x100B r0x100A (LSB) with a temporary in r0x1009 r0x1008. HIDDEN is 0x00800000, so a < HIDDEN is turned into !(a & 0xFF800000), which is correct. ; .line 72; "ulong2fs.c" if(a < HIDDEN) { MOVF r0x1005,W BTFSC r0x1005,7 GOTO _00114_DS_ ==> Bit 7 in the third byte of a is set ==> a is not less than HIDDEN, bail out. Great. MOVF r0x1004,W ANDLW 0xff BTFSS STATUS,2 GOTO _00114_DS_ ==> The MSB of a is not 0, bail out. Great. _00110_DS_ ; .line 74; "ulong2fs.c" a<<=1; BCF STATUS,0 BANKSEL r0x1007 RLF r0x1007,F RLF r0x1006,F RLF r0x1005,F RLF r0x1004,F ; .line 75; "ulong2fs.c" exp--; MOVLW 0xff ADDWF r0x1008,F BTFSS STATUS,0 DECF r0x1009,F ; .line 76; "ulong2fs.c" } while (a < HIDDEN); MOVF r0x1005,W BTFSS r0x1005,7 GOTO _00110_DS_ ==> This is completely bogus: We should bail out (GOTO _00114_DS_) if (a & 0x00800000) OR if (a & 0xff000000). Instead we resume the loop if any one of the conditions is false. This should read # MOVF r0x1005,W # BTFSC r0x1005,7 # condition reversed # GOTO _00114_DS_ # different label, may need to be __new_label__ to update exp from its temporary, but I dont care for now MOVF r0x1004,W ANDLW 0xff BTFSC STATUS,2 // Skip if ZERO flag == 0, i.e., result not 0? GOTO _00110_DS_ // taken when ZERO flag == 1, i.e., result was 0 ==> a & 0xFF000000 == 0, so remembering a & 0x00800000 == 0 as well, we have a < HIDDEN and stay in the loop. Great. __new_label__ # The following is caused by using exp-- instead of --exp and preserves an unused copy of the original value MOVF r0x1008,W MOVWF r0x100A MOVF r0x1009,W MOVWF r0x100B ;;100 MOVF r0x1007,W _00114_DS_ I have also had a look at the pic source (src/pic14/gen.c, genAnd(), genJumpTrueOrFalse(), and friends), but this code is so arcane (or incompletely ported from its source) that I will probably not be able to actually fix this until, say, this weekend. It may take considerably longer ... Considering that the solution you provided merely hides the bug, I'll not commit it for now. Sorry for the bad news. > Since I am not a developer but merely a user of few weeks experience, > can I ask someone on this list to help me by bringing in the fix > (and a test if possible)? It might also be desirable to review the other > implementations of the same function, as far as more exist. As stated above, the implementations are semantically equivalent (unless I am mistaken) and need not be touched except for efficiency, as the while(){} construct seems to yield slightly more compact code. Kind regards, Raphael ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_feb _______________________________________________ Sdcc-user mailing list Sdcc-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sdcc-user