"
minf...@arcor.de" <
minf...@arcor.de> writes:
>Isn't it a bit of a hen-and-egg problem? To implement F=/F<> (which are
>non-standard words) correctly, you need isnan/FNAN? - or vice versa.
I would expect that an implementation of F= and F<> just invokes the
corresponding CPU instructions without special-casing NaNs. And
indeed:
\ Gforth
see f=
Code f=
5623F8D636C2: mov $00[r13],r8
5623F8D636C6: xor r8d,r8d
5623F8D636C9: sub r13,$08
5623F8D636CD: mov edx,$0
5623F8D636D2: movsd xmm0,$08[r12]
5623F8D636D9: mov rax,r12
5623F8D636DC: lea r12,$10[r12]
5623F8D636E1: ucomisd xmm0,xmm15
5623F8D636E6: movsd xmm15,$10[rax]
5623F8D636EC: setnp r8lb
5623F8D636F0: cmovnz r8,rdx
5623F8D636F4: add r15,$08
5623F8D636F8: neg r8
5623F8D636FB: mov rcx,-$08[r15]
5623F8D636FF: jmp ecx
end-code
\ lxf
see f=
8691334 88DE3C4 29 88DE3AB 25 prim F=
88DE3C4 DFE9 fucomip ST(1)
88DE3C6 DDD8 fstp ST(0)
88DE3C8 0F9BC0 setnp al
88DE3CB 0FBEC0 movsx eax , al
88DE3CE 0F94C1 sete cl
88DE3D1 0FBEC9 movsx ecx , cl
88DE3D4 21C8 and eax , ecx
88DE3D6 F7D8 neg eax
88DE3D8 895DFC mov [ebp-4h] , ebx
88DE3DB 8BD8 mov ebx , eax
88DE3DD 8D6DFC lea ebp , [ebp-4h]
88DE3E0 C3 ret near
\ iForth
FORTH> see f=
Flags:
$10139AE0 : F= 488BC04883ED088F4500 H.@H.m..E.
$10139AEA f2poprev, 41DB6D10D9C941DB6D004D8D A[m.YIA[m.M.
6D20 m
$10139AF8 fcompp DED9 ^Y
$10139AFA fnstsw ax DFE0 _`
$10139AFC and rax, $00004400 d#
4881E000440000 H.`.D..
$10139B03 xor rax, $00004000 d#
4881F000400000 H.p.@..
$10139B0A sete al 0F94C0 ..@
$10139B0D movzx rbx, al 480FB6D8 H.6X
$10139B11 neg rbx 48F7DB Hw[
$10139B14 push rbx 53 S
$10139B15 ; 488B45004883C508FFE0 H.E.H.E..`
And here's an example of the pitfalls of FP numbers:
VFX Forth 64 5.11 RC2 [build 0112] 2021-05-02 for Linux x64
© MicroProcessor Engineering Ltd, 1998-2021
see f=
F=
( 004C4550 E8EBFBFFFF ) CALL 004C4140 F-
( 004C4555 E836FFFFFF ) CALL 004C4490 F0=
( 004C455A C3 ) RET/NEXT
( 11 bytes, 3 instructions )
Let's see how well this works:
1e 0e f/ fdup f= . \ 0 ok
SSE Exception 0000:1F85
By contrast:
gforth: 1e 0e f/ fdup f= . \ -1 ok
iForth: 1e 0e f/ fdup f= . \ -1 ok
lxf: 1e 0e f/ fdup f= . \ -1 ok
>GCC does this via fpclassify(f) which is just a bit pattern matcher, similar
>to your other example.
The code shown for Gforth comes out of gcc. No bit pattern matching
going on here.