Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #135446

F>R, FR@ and FR> Float to return stack words

From peter <peter.noreply@tin.it>
Newsgroups comp.lang.forth
Subject F>R, FR@ and FR> Float to return stack words
Date 2026-08-28 00:04 +0200
Organization A noiseless patient Spider
Message-ID <20260828000428.00007e53@tin.it> (permalink)

Show all headers | View raw


I recently wanted to adapt compelx-kahan.fs, the complex implementation
by Julian V. Noble and David N. Williams, to the capabilities of 
ntf64/lxf64.

One thing I wanted to get away from was the Baden-style float locals,
fa fb .. and to-fa to-fb .. and the use of temporary buffers.

I replaced them with F>R, FR@ and FR>. Moving floats to the return stack.
This works well as both stacks are 64 bits. The effect was very good.

Taking Z* as an example:

Original Z* using 2 temporary buffers

: z*    (f: x y u v -- x*u-y*v  x*v+y*u)
(
Uses the algorithm followed by jvn:
  [x+iy]*[u+iv] = [[x+y]*u - y*[u+v]] + i[[x+y]*u + x*[v-u]]
Requires 3 multiplications and 5 additions.
)
  zdup f+                               (f: x y u v u+v)
  [ fnoname ] literal f!                (f: x y u v)
  fover f-                              (f: x y u v-u)
  [ fnoname float+ ] literal f!         (f: x y u)
  frot fdup                             (f: y u x x)
  [ fnoname float+ ] literal f@         (f: y u x x v-u)
  f*
  [ fnoname float+ ] literal f!         (f: y u x)
  frot fdup                             (f: u x y y)
  [ fnoname ] literal f@                (f: u x y y u+v)
  f*
  [ fnoname ] literal f!                (f: u x y)
  f+  f* fdup                           (f: u*[x+y] u*[x+y])
  [ fnoname ] literal f@ f-             (f: u*[x+y] x*u-y*v)
  fswap
  [ fnoname float+ ] literal f@         (f: x*u-y*v u*[x+y] x*[v-u])
  f+ ;                                  (f: x*u-y*v x*v+y*u)

With more or less direct exchange to using the return stack
I got

: z*    ( f: x y u v -- x*u-y*v  x*v+y*u)
  zdup f+ f>r                           ( f: x y u v  r: u+v)
  fover f- f>r                          ( f: x y u  r: u+v v-u)
  frot fdup fr>                         ( f: y u x x v-u r: u+v)
  f*                                    ( f: y u x x*'v-u' r: u+v)
  fr> fswap f>r f>r                     ( f: y u x r: x*'v-u' u+v)
  frot fdup fr>                         ( f: u x y y u+v r: x*'v-u')
  f* f>r                                ( f: u x y r: x*'v-u' y*'u+v')
  f+ f* fdup fr> f- fswap fr>           ( f: x*u-y*v u*[x+y] x*[v-u])
  f+ ;                                  ( f: x*u-y*v x*v+y*u)

The original give the following assembler code

seea Z*
0x4291A0  C4C17B584D00         vaddsd xmm1, xmm0, qword ptr [r13]
0x4291A6  C5FB110DD2965D00     vmovsd qword ptr [rel 0xA02880], xmm1
0x4291AE  C4C17B5C4500         vsubsd xmm0, xmm0, qword ptr [r13]
0x4291B4  C5FB1105CC965D00     vmovsd qword ptr [rel 0xA02888], xmm0
0x4291BC  C5FB1005C4965D00     vmovsd xmm0, qword ptr [rel 0xA02888]
0x4291C4  C4C17B594510         vmulsd xmm0, xmm0, qword ptr [r13+0x10]
0x4291CA  C5FB1105B6965D00     vmovsd qword ptr [rel 0xA02888], xmm0
0x4291D2  C5FB1005A6965D00     vmovsd xmm0, qword ptr [rel 0xA02880]
0x4291DA  C4C17B594508         vmulsd xmm0, xmm0, qword ptr [r13+0x8]
0x4291E0  C5FB110598965D00     vmovsd qword ptr [rel 0xA02880], xmm0
0x4291E8  C4C17B104508         vmovsd xmm0, qword ptr [r13+0x8]
0x4291EE  C4C17B584510         vaddsd xmm0, xmm0, qword ptr [r13+0x10]
0x4291F4  C4C17B594500         vmulsd xmm0, xmm0, qword ptr [r13]
0x4291FA  C5FB100D7E965D00     vmovsd xmm1, qword ptr [rel 0xA02880]
0x429202  C5FB5CD1             vsubsd xmm2, xmm0, xmm1
0x429206  C5FB100D7A965D00     vmovsd xmm1, qword ptr [rel 0xA02888]
0x42920E  C5F358C8             vaddsd xmm1, xmm1, xmm0
0x429212  C5F310C1             vmovsd xmm0, xmm1, xmm1
0x429216  C4C17B115510         vmovsd qword ptr [r13+0x10], xmm2
0x42921C  4D8D6D10             lea r13, [r13+0x10]
0x429220  C3                   ret
129 bytes, 21 instructions
ok

There are 3 multiplications, 5 add/sub and 8 loads/stores to the buffer

The revised version gives

seea Z*
0x428A50  C4C17B584D00         vaddsd xmm1, xmm0, qword ptr [r13]
0x428A56  C4C17B5C4500         vsubsd xmm0, xmm0, qword ptr [r13]
0x428A5C  C4C17B594510         vmulsd xmm0, xmm0, qword ptr [r13+0x10]
0x428A62  C4C173594D08         vmulsd xmm1, xmm1, qword ptr [r13+0x8]
0x428A68  C4C17B105508         vmovsd xmm2, qword ptr [r13+0x8]
0x428A6E  C4C16B585510         vaddsd xmm2, xmm2, qword ptr [r13+0x10]
0x428A74  C4C16B595500         vmulsd xmm2, xmm2, qword ptr [r13]
0x428A7A  C5EB5CD9             vsubsd xmm3, xmm2, xmm1
0x428A7E  C5FB58C2             vaddsd xmm0, xmm0, xmm2
0x428A82  C4C17B115D10         vmovsd qword ptr [r13+0x10], xmm3
0x428A88  4D8D6D10             lea r13, [r13+0x10]
0x428A8C  C3                   ret
61 bytes, 12 instructions
ok

Half the size and all memory loads/stores gone.

With the returns stack use I can also do things like
    
: +ulp f>r r> 1+ >r fr> ;  ok

0e +ulp e.  5e-324  ok
0e +ulp fh.  0x0.0000000000001p-1022  ok

seea +ulp
0x42A260  C4E1F97EC0          vmovq rax, xmm0
0x42A265  48FFC0              inc rax
0x42A268  C4E1F96EC0          vmovq xmm0, rax
0x42A26D  C3                  ret
14 bytes, 4 instructions
ok

An alternative I considered was to introduce float locals. It would probably 
have been more complicated. The result, in the best case, would be equal in
the generated code. The problem with locals is the scope, that is to the end 
of the word. Of course the source would be more readable!

I might still implement float locals.

What do you have in your system?

BR
Peter

Back to comp.lang.forth | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

F>R, FR@ and FR> Float to return stack words peter <peter.noreply@tin.it> - 2026-08-28 00:04 +0200
  Re: F>R, FR@ and FR> Float to return stack words dxf <dxforth@gmail.com> - 2026-08-28 14:44 +1000
  Re: F>R, FR@ and FR> Float to return stack words anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-08-28 06:50 +0000
  Re: F>R, FR@ and FR> Float to return stack words marcel hendrix <mhx@iae.nl> - 2026-08-28 19:35 +0200
  Re: F>R, FR@ and FR> Float to return stack words peter <peter.noreply@tin.it> - 2026-08-30 10:06 +0200
    Re: F>R, FR@ and FR> Float to return stack words anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-08-30 13:31 +0000
      Re: F>R, FR@ and FR> Float to return stack words peter <peter.noreply@tin.it> - 2026-08-30 15:58 +0200
        Re: F>R, FR@ and FR> Float to return stack words anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-08-30 15:12 +0000

csiph-web