On systems with a separate floating poing stack (Forth 200x standard systems), one disadvantage of the separate fp stack is the occasional need to push and pop floating point numbers off the fp stack. Temporary fp variables are okay for simplesolutions, but are restrictive compared to having a stack onto which the fp numbers are pushed and popped.
On systems with a separate floating poing stack (Forth 200x standard systems), one disadvantage of the separate fp stack is the occasional
need to push and pop floating point numbers off the fp stack. Temporary
fp variables are okay for simple solutions, but are restrictive compared
to having a stack onto which the fp numbers are pushed and popped.
On Forth systems which provide FP@ and FP! for getting and setting the floating point stack pointer, and RP@ and RP! for the return stack
pointer, the words F>R and FR> may be defined in source as shown below.
Assumptions:
1. The width of the floating point stack, in bytes, is given by 1 FLOATS
2. The width above does not need to be a multiple of 1 CELLS
3. The floating point stack is contiguous.
The following code works in kForth-64 and in Gforth.
1 floats constant fpsize
fpsize 1 cells /mod swap [IF] 1+ [THEN] cells constant fpcells
\ From Wil Baden's toolkit
: :inline ( "name <char> ccc<char>" -- )
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
POSTPONE ; IMMEDIATE ;
:inline f>r ( F: r -- ) ( r: -- i*x ) fp@ rp@ fpcells - 2dup fpsize move
rp! fpsize + fp! ;
:inline fr> ( F: -- r ) ( r: i*x -- ) rp@ fp@ fpsize - 2dup fpsize move
fp! fpcells + rp! ;
\ Test code
: test1 f>r fr> ;
3.214e test1 \ F: 3.214e
: test2 fdup f>r 1e f- f>r fr> fr> ;
1.23e test2 \ F: 2.3e-1 1.23e0
On 22/05/2023 9:05 am, Krishna Myneni wrote:solutions, but are restrictive compared to having a stack onto which the fp numbers are pushed and popped.
On systems with a separate floating poing stack (Forth 200x standard systems), one disadvantage of the separate fp stack is the occasional need to push and pop floating point numbers off the fp stack. Temporary fp variables are okay for simple
I'd be interested in the case for having F>R FR> should anyone care to make it (?)
I very rarely use fp but there was an instance in implementing fp on my system
where F>R FR> would have come in handy. In the end I used a hidden variable but
it did make me wonder. Implementation in my case would be a trivial code definition.
Krishna Myneni schrieb am Montag, 22. Mai 2023 um 01:05:33 UTC+2:
On systems with a separate floating poing stack (Forth 200x standard
systems), one disadvantage of the separate fp stack is the occasional
need to push and pop floating point numbers off the fp stack. Temporary
fp variables are okay for simple solutions, but are restrictive compared
to having a stack onto which the fp numbers are pushed and popped.
On Forth systems which provide FP@ and FP! for getting and setting the
floating point stack pointer, and RP@ and RP! for the return stack
pointer, the words F>R and FR> may be defined in source as shown below.
Assumptions:
1. The width of the floating point stack, in bytes, is given by 1 FLOATS
2. The width above does not need to be a multiple of 1 CELLS
3. The floating point stack is contiguous.
The following code works in kForth-64 and in Gforth.
1 floats constant fpsize
fpsize 1 cells /mod swap [IF] 1+ [THEN] cells constant fpcells
\ From Wil Baden's toolkit
: :inline ( "name <char> ccc<char>" -- )
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
POSTPONE ; IMMEDIATE ;
:inline f>r ( F: r -- ) ( r: -- i*x ) fp@ rp@ fpcells - 2dup fpsize move
rp! fpsize + fp! ;
:inline fr> ( F: -- r ) ( r: i*x -- ) rp@ fp@ fpsize - 2dup fpsize move
fp! fpcells + rp! ;
\ Test code
: test1 f>r fr> ;
3.214e test1 \ F: 3.214e
: test2 fdup f>r 1e f- f>r fr> fr> ;
1.23e test2 \ F: 2.3e-1 1.23e0
FP-alignment was obviously no issue here.
On 5/22/23 22:48, minforth wrote:
...Maybe more generally we need to use CMOVE rather than MOVE to avoid the issue of alignment. On Intel it will work as implemented above.
FP-alignment was obviously no issue here.
As a matter of interest are there any fp implementations that require better than
cell aligned addresses?
Maybe more generally we need to use CMOVE rather than MOVE to avoid the
issue of alignment. On Intel it will work as implemented above.
On 5/22/23 22:48, minforth wrote:the issue of alignment. On Intel it will work as implemented above.
...Maybe more generally we need to use CMOVE rather than MOVE to avoid
FP-alignment was obviously no issue here.
As a matter of interest are there any fp implementations that require
better than
cell aligned addresses?
On systems with a separate floating poing stack (Forth 200x standard >systems), one disadvantage of the separate fp stack is the occasional
need to push and pop floating point numbers off the fp stack. Temporary
fp variables are okay for simple solutions, but are restrictive compared
to having a stack onto which the fp numbers are pushed and popped.
On Forth systems which provide FP@ and FP! for getting and setting the >floating point stack pointer, and RP@ and RP! for the return stack
pointer, the words F>R and FR> may be defined in source as shown below.
Assumptions:
1. The width of the floating point stack, in bytes, is given by 1 FLOATS
2. The width above does not need to be a multiple of 1 CELLS
3. The floating point stack is contiguous.
The following code works in kForth-64 and in Gforth.
1 floats constant fpsize
fpsize 1 cells /mod swap [IF] 1+ [THEN] cells constant fpcells
\ From Wil Baden's toolkit
: :inline ( "name <char> ccc<char>" -- )
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
POSTPONE ; IMMEDIATE ;
:inline f>r ( F: r -- ) ( r: -- i*x ) fp@ rp@ fpcells - 2dup fpsize move
rp! fpsize + fp! ;
:inline fr> ( F: -- r ) ( r: i*x -- ) rp@ fp@ fpsize - 2dup fpsize move
fp! fpcells + rp! ;
dxforth <dxforth@gmail.com> writes:
As a matter of interest are there any fp implementations that requirebetter than
cell aligned addresses?
32-bit Gforth on hardware that requires 8-byte alignment of DP FP
numbers, e.g., MIPS, SPARC or some ARM implementations. That's why
Gforth does not have F>R FR>.
- anton
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
Maybe more generally we need to use CMOVE rather than MOVE to avoid the >>issue of alignment. On Intel it will work as implemented above.
No. MOVE has no alignment requirements, CMOVE requires
character-aligned addresses (although on pretty much all systems that
is only a theoretical concern, because 1 char = 1 on them).
- anton
...
That's why
Gforth does not have F>R FR>.
In article <2023May24.101026@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
Krishna Myneni <krishna.myneni@ccreweb.org> writes:
Maybe more generally we need to use CMOVE rather than MOVE to avoid the
issue of alignment. On Intel it will work as implemented above.
No. MOVE has no alignment requirements, CMOVE requires
character-aligned addresses (although on pretty much all systems that
is only a theoretical concern, because 1 char = 1 on them).
One of this requires memory propagation, and the other is intelligent, i.e. moves up or down with overlapping regions. That is the most important distinction. It is hard to remember which is which though.
On 24/05/2023 5:48 pm, Anton Ertl wrote:
...
That's why
Gforth does not have F>R FR>.
So not cell-aligned but what excludes those functions?
R would be something like (on MIPS):
dxforth <dxforth@gmail.com> writes:
On 24/05/2023 5:48 pm, Anton Ertl wrote:
...
That's why
Gforth does not have F>R FR>.
So not cell-aligned but what excludes those functions?
R would be something like (on MIPS):
addiu $rp, $rp, -8
sd $ftos, 0($rp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
But rp is not necessarily 8-byte-aligned, and if not, this produces a
SIGBUS. An implementation that does not have this problem would
require significantly more instructions, and is slower than one might
expect. By contrast, the locals stack pointer is always aligned for
cells and floats, so you don't run into this problem with FP locals.
- anton
On 24.05.2023 18:23, Anton Ertl wrote:
dxforth <dxforth@gmail.com> writes:
On 24/05/2023 5:48 pm, Anton Ertl wrote:
...
That's why
Gforth does not have F>R FR>.
So not cell-aligned but what excludes those functions?
R would be something like (on MIPS):
addiu $rp, $rp, -8
sd $ftos, 0($rp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
But rp is not necessarily 8-byte-aligned, and if not, this produces a
SIGBUS. An implementation that does not have this problem would
require significantly more instructions, and is slower than one might
expect. By contrast, the locals stack pointer is always aligned for
cells and floats, so you don't run into this problem with FP locals.
- anton
remedy ($tmp is placeholder for a free scratch register):
Consume three words on the return stack and 8-align ftos within these.
FtoR: addiu $rp, $rp, -12
addiu $tmp, $rp, 7
ins $tmp, $zero, 0, 3 # up-align tmp to multiple of 8
sd $ftos, 0($tmp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
FRfrom: addiu $fp, $fp, -8
sd $ftos, 8($fp)
addiu $tmp, $rp, 7
ins $tmp, $zero, 0, 3 # up-align tmp to multiple of 8
ld $ftos, 0($tmp)
addiu $rp, $rp, 12
NEXT
R:ori $tmp, $rp, 7
Bernd Linsel <bl1-thispartdoesnotbelonghere@gmx.com> writes:
On 24.05.2023 18:23, Anton Ertl wrote:
dxforth <dxforth@gmail.com> writes:
On 24/05/2023 5:48 pm, Anton Ertl wrote:
...
That's why
Gforth does not have F>R FR>.
So not cell-aligned but what excludes those functions?
R would be something like (on MIPS):
addiu $rp, $rp, -8
sd $ftos, 0($rp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
But rp is not necessarily 8-byte-aligned, and if not, this produces a
SIGBUS. An implementation that does not have this problem would
require significantly more instructions, and is slower than one might
expect. By contrast, the locals stack pointer is always aligned for
cells and floats, so you don't run into this problem with FP locals.
- anton
remedy ($tmp is placeholder for a free scratch register):
Consume three words on the return stack and 8-align ftos within these.
FtoR: addiu $rp, $rp, -12
addiu $tmp, $rp, 7
ins $tmp, $zero, 0, 3 # up-align tmp to multiple of 8
sd $ftos, 0($tmp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
FRfrom: addiu $fp, $fp, -8
sd $ftos, 8($fp)
addiu $tmp, $rp, 7
ins $tmp, $zero, 0, 3 # up-align tmp to multiple of 8
ld $ftos, 0($tmp)
addiu $rp, $rp, 12
NEXT
Clever! Now for MIPS I without the "ins" instruction. Maybe
something like:
R:ori $tmp, $rp, 7
addiu $rp, $rp, -12
sd $ftos, -15($tmp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
Not sure if it I got the details right, but with some tweaks the
general idea should be workable. And likewise for FR>.
The end result would be that F>R consumes 12 bytes and an extra
instruction on the return stack on every target. Better that what I
had in mind, but still worse than F>L.
- anton
dxforth <dxforth@gmail.com> writes:
On 24/05/2023 5:48 pm, Anton Ertl wrote:
...
That's why
Gforth does not have F>R FR>.
So not cell-aligned but what excludes those functions?
R would be something like (on MIPS):
addiu $rp, $rp, -8
sd $ftos, 0($rp)
ld $ftos, 0($fp)
addiu $fp, $fp, 8
NEXT
But rp is not necessarily 8-byte-aligned, and if not, this produces a
SIGBUS. An implementation that does not have this problem would
require significantly more instructions, and is slower than one might
expect.
By contrast, the locals stack pointer is always aligned for
cells and floats, so you don't run into this problem with FP locals.
Extending locals beyond cells takes effort and resources. If one has
FP locals, granted there's not much point providing F>R FR> .
On Thursday, May 25, 2023 at 4:55:08 AM UTC+2, dxforth wrote:
[..]
Extending locals beyond cells takes effort and resources. If one has
FP locals, granted there's not much point providing F>R FR> .
Effort? In iForth the locals stack can hold extended floats (10 bytes),
which take 16 bytes of aligned memory (iForth specific). That means
that most of the aligned SSE/AVX type variables/registers can also
be held there. Extending the locals stack to be 256 / 512 bits wide is
just changing a constant in the metacompiler. Maybe I'll do that when
we want our own AVX assembler.
AFAIK SwiftForth doesn't handle locals beyond integer. That they haven't >extended it to doubles and floats is what - ignorance?
Effort? In iForth the locals stack can hold extended floats (10 bytes),
which take 16 bytes of aligned memory (iForth specific). That means
that most of the aligned SSE/AVX type variables/registers can also
be held there. Extending the locals stack to be 256 / 512 bits wide is
just changing a constant in the metacompiler. Maybe I'll do that when
we want our own AVX assembler.
Extending locals beyond cells takes effort and resources. If one has
FP locals, granted there's not much point providing F>R FR> .
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 41:41:43 |
Calls: | 6,708 |
Calls today: | 1 |
Files: | 12,243 |
Messages: | 5,353,855 |