Hello Martin,
> Also, a bug in D0>:
> Hmmm, something wrong here I feel:
>
>> (ATmega2560)> decimal 1553994000. d0> . 1572137999. d0> .
>> -1 0 ok
yes there is.
Short answer:
The assembly version produces the wrong result,
when the MostSignificantBit of the lower *word* is set.
> trunk/avr8/words/d-greaterzero.asm
The forth version is ok.
> trunk/common/lib/forth2012/double/d-greater-zero.frt
Workaround: use the forth code.
Sightly longer answer:
> | > $7FFF. d0> .
> | -1 ok
> | > $8000. d0> .
> | 0 ok
The exakt value of the high word (here $) is irrelevant.
The Forth version works as advertised:
> | > : new.d0> 2dup or >r d0< 0= r> and 0= 0= ;
> | ok
> | > $7FFF. new.d0> .
> | -1 ok
> | > $8000. new.d0> .
> | -1 ok
The gory details:
So after a dive into the assembly code, reading the docs and a
fair amount of head scratching I think I see cause of the
problem:
#+name: trunk/avr8/macros.asm
#+begin_src asm
.macro loadtos
ld tosl, Y+
ld tosh, Y+
.endmacro
#+end_src
#+name: trunk/avr8/words/d-greaterzero.asm
#+begin_src asm
; ( d -- flag )
; Compare
; compares if a double double cell number is greater 0
VE_DGREATERZERO:
.dw $ff03 ; flags,length
.db "d0>",0 ; name
.dw VE_HEAD ; link to previous voc entry
.set VE_HEAD = VE_DGREATERZERO ; advance pointer to first voc entry
XT_DGREATERZERO:; XT eXecution Token is here
.dw PFA_DGREATERZERO; branch to PFA, this is an assembly word
PFA_DGREATERZERO: ; so PFA is right here!
cp tosl, zerol ; comparetop-of-stack-low, zero-low
cpc tosh, zeroh ; compare-with-carry top-of-stack-high, zero-high
; The result at this point is stored as flags in the STATUS
; register. The original values are left unchanged.
loadtos ; *I guess at this point*
; TOS resides in a register pair
; Y points to the remainder of the stack
; in RAM. So loadtos moves the former
; TOS-1 element into register pair tos
; does ld change the status register flags? nope.
cpc tosl, zerol ; compare-with-carry top-of-stack-1-low, zero-low
cpc tosh, zeroh ; compare-widh-carry top-of-stack-1-high, zero-high
; at this point we have consumed 4 Register values and compared
; them with zero. Reading up on the exact workings of "cp" and
; "cpc" I conclude
;
; cp Rd, Rr
; calculates R = Rd - Rr
; and stores the flags derived from the result R in the status
; register. In particular
;
; Flag Z is set if all bits of the result R are cleared.
;
; Flag S (Signed) = N xor V
;
; Flag N (Negative) is set when R7 (MSB in R) ist set, clear
;otherwise
;
; Flag V (oVerflow) is set if calculating the result produces a
;2 complements overflow.
;since Rr is zero, there should never be such an
;overflow. So in this case V=0.
;
; The S flag is set, if any of the 4 Bytes (== 2 words) have
; their MSB set. That's what we see in the example above.
;
brlt PFA_ZERO1 ; Branch if Less Than, Signed
; Tests the signed flag and branches, if S is set
; at this point, the S flag is used. I currently think that only
; the MSB of the highest Byte should be inspected for this
; decision.
brbs 1, PFA_ZERO1 ; Branch if Status Flag Set, bit 1 (Z) is used
; however, at this point the Z flag is used! Therefore the lower
; Bytes must have been inspected as well!
rjmp PFA_TRUE1 ; jump, (tail call opt.)
; --
PFA_ZERO1:
movw tosl, zerol; copy 0,0 to tosl,h
jmp_ DO_NEXT
; --
PFA_TRUE1:
ser tosl; ser set all bits in register
ser tosh
jmp_ DO_NEXT
#+end_src
I'm not sure I have yet understood the problem in all details.
E.g. the error should show up as well, if only the MSB of a
lower Byte is set.
> | > $0080. d0> .
> | -1 ok
> | > $8000. d0> .
> | 0 ok
> | > $0080. d0> .
> | -1 ok
> | > $8000. d0> .
> | -1 ok
But that is not the case.
Moreover I'm uncertain, how to fix this, or whether the assembly
version should just be removed. Inspecting the code tree
reveals, that this file was added in Version 5.2 and was
unchanged ever since. So it never has worked, it seems.
Any suggestions?
Happy Hacking.
Cheers,
Erich
--
May the Forth be with you ...
___
Amforth-devel mailing list for http://amforth.sf.net/
Amforth-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/amforth-devel