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

Reply via email to