add a full complement of double-cell primitives

This commit is contained in:
Jesse D. McDonald 2020-10-21 20:11:40 -05:00
parent bcf5d80be0
commit 77607934cd
2 changed files with 211 additions and 68 deletions

View File

@ -657,7 +657,7 @@ defvar CURRENT_ORDER,initial_order,"CURRENT-ORDER"
/* ( a -- ) */ /* ( a -- ) */
defcode DROP defcode DROP
addl $4,%esp pop %eax
NEXT NEXT
/* ( a b -- b a ) */ /* ( a b -- b a ) */
@ -670,7 +670,9 @@ defcode SWAP
/* ( a -- a a ) */ /* ( a -- a a ) */
defcode DUP defcode DUP
pushl (%esp) pop %eax
push %eax
push %eax
NEXT NEXT
/* ( a b -- a b a ) */ /* ( a b -- a b a ) */
@ -681,7 +683,8 @@ defcode OVER
/* ( a b -- b ) */ /* ( a b -- b ) */
defcode NIP defcode NIP
pop %ebx pop %ebx
movl %ebx,(%esp) pop %eax
push %ebx
NEXT NEXT
/* ( a b -- b a b ) */ /* ( a b -- b a b ) */
@ -715,19 +718,8 @@ defcode NROT,"-ROT"
/* ( a b -- ) */ /* ( a b -- ) */
defcode TWODROP,"2DROP" defcode TWODROP,"2DROP"
addl $8,%esp pop %ebx
NEXT pop %eax
/* ( a b -- a b a b ) */
defcode TWODUP,"2DUP"
pushl 4(%esp)
pushl 4(%esp)
NEXT
/* ( a b c d -- a b c d a b ) */
defcode TWOOVER,"2OVER"
pushl 12(%esp)
pushl 12(%esp)
NEXT NEXT
/* ( a b c d -- c d a b ) */ /* ( a b c d -- c d a b ) */
@ -742,6 +734,74 @@ defcode TWOSWAP,"2SWAP"
push %ebx push %ebx
NEXT NEXT
/* ( a b -- a b a b ) */
defcode TWODUP,"2DUP"
pop %ebx
pop %eax
push %eax
push %ebx
push %eax
push %ebx
NEXT
/* ( a b c d -- a b c d a b ) */
defcode TWOOVER,"2OVER"
pushl 12(%esp)
pushl 12(%esp)
NEXT
/* ( a b c d -- c d ) */
defcode TWONIP,"2NIP"
pop %edx
pop %ecx
pop %ebx
pop %eax
push %ecx
push %edx
NEXT
/* ( a b c d -- c d a b c d ) */
defcode TWOTUCK,"2TUCK"
pop %edx
pop %ecx
pop %ebx
pop %eax
push %ecx
push %edx
push %eax
push %ebx
push %ecx
push %edx
NEXT
/* ( a b c d e f -- c d e f a b ) */
defcode TWOROT,"2ROT"
pop %edx
pop %ecx
pop %ebx
pop %eax
xchg %eax,4(%esp)
xchg %ebx,(%esp)
push %ecx
push %edx
push %eax
push %ebx
NEXT
/* ( a b c d e f -- e f a b c d ) */
defcode NTWOROT,"-2ROT"
pop %edx
pop %ecx
pop %ebx
pop %eax
xchg %ecx,4(%esp)
xchg %edx,(%esp)
push %ecx
push %edx
push %eax
push %ebx
NEXT
/* ( xn ... x1 n -- ) */ /* ( xn ... x1 n -- ) */
defcode NDROP defcode NDROP
pop %eax pop %eax
@ -777,6 +837,15 @@ defcode QDUP,"?DUP"
push %eax push %eax
1: NEXT 1: NEXT
/* ( 0 -- 0 0 ) */
/* ( a -- a ) */
defcode QZDUP,"?0DUP"
movl (%esp),%eax
test %eax,%eax
jnz 1f
push %eax
1: NEXT
/* ( a b -- a+b ) */ /* ( a b -- a+b ) */
defcode ADD,"+" defcode ADD,"+"
pop %eax pop %eax
@ -967,6 +1036,11 @@ defcode DTWODIV,"D2/"
rcrl $1,4(%esp) rcrl $1,4(%esp)
NEXT NEXT
defcode DUTWODIV,"DU2/"
shrl $1,(%esp)
rcrl $1,4(%esp)
NEXT
/* ( x1 u -- x2 ) Shift left by u bits */ /* ( x1 u -- x2 ) Shift left by u bits */
defcode LSHIFT defcode LSHIFT
pop %ecx pop %ecx
@ -979,59 +1053,124 @@ defcode RSHIFT
shrl %cl,(%esp) shrl %cl,(%esp)
NEXT NEXT
.macro defzcmp label,opcode,name="\label",flags=0 /* ( xd1 u -- xd2 ) Shift left by u bits */
defcode DLSHIFT
pop %ecx
movl 4(%esp),%eax
shldl %cl,%eax,(%esp)
shll %cl,4(%esp)
NEXT
/* ( ud1 u -- ud2 ) Logical (unsigned) shift right by u bits */
defcode DRSHIFT
pop %ecx
movl (%esp),%eax
shrdl %cl,%eax,4(%esp)
shrl %cl,(%esp)
NEXT
.macro defzcmp label,ncc,name="\label",flags=0
defcode \label,"\name",0,\flags defcode \label,"\name",0,\flags
pop %eax pop %eax
xor %edi,%edi
test %eax,%eax test %eax,%eax
\opcode %al j\ncc 0f
.ifdef .Lsetzflag dec %edi
jmp .Lsetzflag 0: push %edi
.else
.Lsetzflag:
movzbl %al,%eax
neg %eax
push %eax
NEXT NEXT
.endif
.endm .endm
defzcmp ZEQU,sete,"0=" /* ( n|u -- flag ) Equality operators with implicit zero, e.g. flag=d==0 */
defzcmp ZNEQU,setne,"0<>" defzcmp ZEQU,ne,"0="
defzcmp ZLT,setl,"0<" defzcmp ZNEQU,e,"0<>"
defzcmp ZGT,setg,"0>"
defzcmp ZLE,setle,"0<="
defzcmp ZGE,setge,"0>="
.macro defcmp label,opcode,name="\label",flags=0 /* ( n -- flag ) Signed relational operators with implicit zero, e.g. flag=d<0 */
defzcmp ZLT,nl,"0<"
defzcmp ZGT,ng,"0>"
defzcmp ZLE,nle,"0<="
defzcmp ZGE,nge,"0>="
.macro defdzcmp label,ncc,name="\label",flags=0
defcode \label,"\name",0,\flags
pop %ebx
pop %eax
xor %edi,%edi
sub $0,%ebx
sbb $0,%eax
j\ncc 0f
dec %edi
0: push %edi
NEXT
.endm
/* ( d|ud -- flag ) Double-cell equality operators with implicit zero */
defdzcmp DZEQU,ne,"D0="
defdzcmp DZNEQU,e,"D0<>"
/* ( d -- flag ) Double-cell signed relational operators with implicit zero */
defdzcmp DZLT,nl,"D0<"
defdzcmp DZGT,ng,"D0>"
defdzcmp DZLE,nle,"D0<="
defdzcmp DZGE,nge,"D0>="
.macro defcmp label,ncc,name="\label",flags=0
defcode \label,"\name",0,\flags defcode \label,"\name",0,\flags
pop %eax pop %eax
pop %ebx pop %ebx
xor %edi,%edi
cmp %eax,%ebx cmp %eax,%ebx
\opcode %al j\ncc 0f
.ifdef .Lsetflag dec %edi
jmp .Lsetflag 0: push %edi
.else
.Lsetflag:
movzbl %al,%eax
neg %eax
push %eax
NEXT NEXT
.endif
.endm .endm
/* ( a b -- flag ) ( various comparison operators, e.g. flag=a<b ) */ /* ( n1|u1 n2|u2 -- flag ) Equality operators */
defcmp EQU,sete,"=" defcmp EQU,ne,"="
defcmp NEQU,setne,"<>" defcmp NEQU,e,"<>"
defcmp LT,setl,"<"
defcmp GT,setg,">"
defcmp LE,setle,"<="
defcmp GE,setge,">="
/* unsigned variants */ /* ( n1 n2 -- flag ) Signed relational operators */
defcmp ULT,setb,"U<" defcmp LT,nl,"<"
defcmp UGT,seta,"U>" defcmp GT,ng,">"
defcmp ULE,setbe,"U<=" defcmp LE,nle,"<="
defcmp UGE,setae,"U>=" defcmp GE,nge,">="
/* ( u1 u2 -- flag ) Unsigned relational operators */
defcmp ULT,nb,"U<"
defcmp UGT,na,"U>"
defcmp ULE,nbe,"U<="
defcmp UGE,nae,"U>="
.macro defdcmp label,ncc,name="\label",flags=0
defcode \label,"\name",0,\flags
pop %edx
pop %ecx
pop %ebx
pop %eax
xor %edi,%edi
sub %edx,%ebx
sbb %ecx,%eax
j\ncc 0f
dec %edi
0: push %edi
NEXT
.endm
/* ( d1|ud1 d2|ud2 -- flag ) Double-cell equality operators */
defdcmp DEQU,ne,"D="
defdcmp DNEQU,e,"D<>"
/* ( d1 d2 -- flag ) Double-cell signed relational operators */
defdcmp DLT,nl,"D<"
defdcmp DGT,ng,"D>"
defdcmp DLE,nle,"D<="
defdcmp DGE,nge,"D>="
/* ( ud1 ud2 -- flag ) Double-cell unsigned relational operators */
defdcmp DULT,nb,"DU<"
defdcmp DUGT,na,"DU>"
defdcmp DULE,nbe,"DU<="
defdcmp DUGE,nae,"DU>="
defcode AND defcode AND
pop %eax pop %eax

View File

@ -149,9 +149,25 @@ DEFER THROW-UNWIND ( k*x n -- i*x <noreturn> )
: SM/REM ( d1 n1 -- d1%n1 d1/n1 ) : SM/REM ( d1 n1 -- d1%n1 d1/n1 )
DUP >R FM/MOD DUP IF OVER 0< IF 1+ SWAP R> - SWAP ELSE RDROP THEN THEN ; DUP >R FM/MOD DUP IF OVER 0< IF 1+ SWAP R> - SWAP ELSE RDROP THEN THEN ;
\ Signed minimum and maximum
: MIN 2DUP > IF NIP ELSE DROP THEN ; : MIN 2DUP > IF NIP ELSE DROP THEN ;
: MAX 2DUP < IF NIP ELSE DROP THEN ; : MAX 2DUP < IF NIP ELSE DROP THEN ;
\ Unsigned minimum and maximum
: UMIN 2DUP U> IF NIP ELSE DROP THEN ;
: UMAX 2DUP U< IF NIP ELSE DROP THEN ;
\ Return -1, 0, or 1 if n is respectively negative, zero, or positive
: SIGNUM ( n -- -1 | 0 | 1 ) DUP IF 0< 2 * 1+ THEN ;
\ Double-cell versions of standard numeric words
: DABS ( d -- +d ) 2DUP D0< IF DNEGATE THEN ;
: DMIN ( d1 d2 -- d1|d2 ) 2OVER 2OVER D> IF 2SWAP THEN 2DROP ;
: DMAX ( d1 d2 -- d1|d2 ) 2OVER 2OVER D< IF 2SWAP THEN 2DROP ;
: DUMIN ( ud1 ud2 -- ud1|ud2 ) 2OVER 2OVER DU> IF 2SWAP THEN 2DROP ;
: DUMAX ( ud1 ud2 -- ud1|ud2 ) 2OVER 2OVER DU< IF 2SWAP THEN 2DROP ;
: DSIGNUM ( d -- -1 | 0 | 1 ) 2DUP D0= IF DROP ELSE D0< 2 * 1+ THEN ;
\ Define names for the whitespace characters \ Define names for the whitespace characters
8 CONSTANT HT \ Horizontal Tab 8 CONSTANT HT \ Horizontal Tab
10 CONSTANT LF \ Line Feed (newline) 10 CONSTANT LF \ Line Feed (newline)
@ -181,15 +197,6 @@ DEFER THROW-UNWIND ( k*x n -- i*x <noreturn> )
: BYE ( -- <noreturn> ) : BYE ( -- <noreturn> )
BEGIN 0 SYS_EXIT SYSCALL1 DROP AGAIN ; BEGIN 0 SYS_EXIT SYSCALL1 DROP AGAIN ;
: D0= ( xd -- flag ) OR 0= ;
: D0<> ( xd -- flag ) OR 0<> ;
: D0< ( d -- flag ) NIP 0< ;
: D0>= ( d -- flag ) NIP 0>= ;
: D0> ( d -- flag ) DNEGATE NIP 0< ;
: D0<= ( d -- flag ) DNEGATE NIP 0>= ;
: DABS ( d -- +d ) DUP 0< IF DNEGATE THEN ;
80 CONSTANT PNO-BUFFER-BYTES 80 CONSTANT PNO-BUFFER-BYTES
CREATE PNO-BUFFER PNO-BUFFER-BYTES ALLOT CREATE PNO-BUFFER PNO-BUFFER-BYTES ALLOT
PNO-BUFFER PNO-BUFFER-BYTES + CONSTANT PNO-BUFFER-END PNO-BUFFER PNO-BUFFER-BYTES + CONSTANT PNO-BUFFER-END
@ -746,9 +753,6 @@ MARK B
: [CHAR] ( Compilation: "<spaces>ccc" -- ) ( Runtime: -- c ) IMMEDIATE : [CHAR] ( Compilation: "<spaces>ccc" -- ) ( Runtime: -- c ) IMMEDIATE
CHAR POSTPONE LITERAL ; CHAR POSTPONE LITERAL ;
\ Return -1, 0, or 1 if n is respectively negative, zero, or positive
: SIGNUM ( n -- -1 | 0 | 1 ) DUP IF 0< 2 * 1+ THEN ;
\ Return -1, 0, or 1 if the left string is respectively \ Return -1, 0, or 1 if the left string is respectively
\ less than, equal to, or greater than the right string \ less than, equal to, or greater than the right string
: COMPARE ( c-addr1 u1 c-addr2 u2 -- -1 | 0 | 1 ) : COMPARE ( c-addr1 u1 c-addr2 u2 -- -1 | 0 | 1 )
@ -1311,13 +1315,13 @@ DEFINITIONS
DUP 1+ SWAP C@ 2DUP "\"" TYPE TYPE-ESCAPED "\" " TYPE + ALIGNED DUP 1+ SWAP C@ 2DUP "\"" TYPE TYPE-ESCAPED "\" " TYPE + ALIGNED
ENDOF ENDOF
OVER CELL- NONAME-LITERAL? IF OVER CELL- NONAME-LITERAL? IF
DROP DUP @ OVER + 2 CELLS+ DUP R> MAX >R SWAP DROP DUP @ OVER + 2 CELLS+ DUP R> UMAX >R SWAP
"{ " TYPE CELL+ >DFA @ UNTHREAD "} " TYPE "{ " TYPE CELL+ >DFA @ UNTHREAD "} " TYPE
ELSE ELSE
DUP ['] BRANCH = OR-ELSE DUP ['] 0BRANCH = THEN IF DUP ['] BRANCH = OR-ELSE DUP ['] 0BRANCH = THEN IF
>NAME TYPE SPACE >NAME TYPE SPACE
@(+) DUP "{" TYPE DUP 0> IF "+" TYPE THEN . "} " TYPE @(+) DUP "{" TYPE DUP 0> IF "+" TYPE THEN . "} " TYPE
OVER CELL- + R> MAX >R OVER CELL- + R> UMAX >R
ELSE ELSE
DUP WORD? AND-THEN DUP IMMEDIATE? THEN IF DUP WORD? AND-THEN DUP IMMEDIATE? THEN IF
"POSTPONE " TYPE "POSTPONE " TYPE