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
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user