version 1.128, 2003/05/08 08:49:24
|
version 1.170, 2005/03/17 18:49:03
|
Line 1
|
Line 1
|
\ Gforth primitives |
\ Gforth primitives |
|
|
\ Copyright (C) 1995,1996,1997,1998,2000,2003 Free Software Foundation, Inc. |
\ Copyright (C) 1995,1996,1997,1998,2000,2003,2004 Free Software Foundation, Inc. |
|
|
\ This file is part of Gforth. |
\ This file is part of Gforth. |
|
|
Line 136
|
Line 136
|
\ throw execute, cfa and NEXT1 out? |
\ throw execute, cfa and NEXT1 out? |
\ macroize *ip, ip++, *ip++ (pipelining)? |
\ macroize *ip, ip++, *ip++ (pipelining)? |
|
|
|
\ Stack caching setup |
|
|
|
ifdef(`M4_ENGINE_FAST', `include(cache1.vmg)', `include(cache0.vmg)') |
|
|
\ these m4 macros would collide with identifiers |
\ these m4 macros would collide with identifiers |
undefine(`index') |
undefine(`index') |
undefine(`shift') |
undefine(`shift') |
undefine(`symbols') |
undefine(`symbols') |
|
|
|
\F 0 [if] |
|
|
|
\ run-time routines for non-primitives. They are defined as |
|
\ primitives, because that simplifies things. |
|
|
|
(docol) ( -- R:a_retaddr ) gforth-internal paren_docol |
|
""run-time routine for colon definitions"" |
|
#ifdef NO_IP |
|
a_retaddr = next_code; |
|
INST_TAIL; |
|
goto **(Label *)PFA(CFA); |
|
#else /* !defined(NO_IP) */ |
|
a_retaddr = (Cell *)IP; |
|
SET_IP((Xt *)PFA(CFA)); |
|
#endif /* !defined(NO_IP) */ |
|
|
|
(docon) ( -- w ) gforth-internal paren_docon |
|
""run-time routine for constants"" |
|
w = *(Cell *)PFA(CFA); |
|
#ifdef NO_IP |
|
INST_TAIL; |
|
goto *next_code; |
|
#endif /* defined(NO_IP) */ |
|
|
|
(dovar) ( -- a_body ) gforth-internal paren_dovar |
|
""run-time routine for variables and CREATEd words"" |
|
a_body = PFA(CFA); |
|
#ifdef NO_IP |
|
INST_TAIL; |
|
goto *next_code; |
|
#endif /* defined(NO_IP) */ |
|
|
|
(douser) ( -- a_user ) gforth-internal paren_douser |
|
""run-time routine for constants"" |
|
a_user = (Cell *)(up+*(Cell *)PFA(CFA)); |
|
#ifdef NO_IP |
|
INST_TAIL; |
|
goto *next_code; |
|
#endif /* defined(NO_IP) */ |
|
|
|
(dodefer) ( -- ) gforth-internal paren_dodefer |
|
""run-time routine for deferred words"" |
|
#ifndef NO_IP |
|
ip=IP; /* undo any ip updating that may have been performed by NEXT_P0 */ |
|
#endif /* !defined(NO_IP) */ |
|
SUPER_END; /* !! probably unnecessary and may lead to measurement errors */ |
|
VM_JUMP(EXEC1(*(Xt *)PFA(CFA))); |
|
|
|
(dofield) ( n1 -- n2 ) gforth-internal paren_field |
|
""run-time routine for fields"" |
|
n2 = n1 + *(Cell *)PFA(CFA); |
|
#ifdef NO_IP |
|
INST_TAIL; |
|
goto *next_code; |
|
#endif /* defined(NO_IP) */ |
|
|
|
(dodoes) ( -- a_body R:a_retaddr ) gforth-internal paren_dodoes |
|
""run-time routine for @code{does>}-defined words"" |
|
#ifdef NO_IP |
|
a_retaddr = next_code; |
|
a_body = PFA(CFA); |
|
INST_TAIL; |
|
goto **(Label *)DOES_CODE1(CFA); |
|
#else /* !defined(NO_IP) */ |
|
a_retaddr = (Cell *)IP; |
|
a_body = PFA(CFA); |
|
SET_IP(DOES_CODE1(CFA)); |
|
#endif /* !defined(NO_IP) */ |
|
|
|
(does-handler) ( -- ) gforth-internal paren_does_handler |
|
""just a slot to have an encoding for the DOESJUMP, |
|
which is no longer used anyway (!! eliminate this)"" |
|
|
|
\F [endif] |
|
|
\g control |
\g control |
|
|
noop ( -- ) gforth |
noop ( -- ) gforth |
Line 150 noop ( -- ) gforth
|
Line 229 noop ( -- ) gforth
|
call ( #a_callee -- R:a_retaddr ) new |
call ( #a_callee -- R:a_retaddr ) new |
""Call callee (a variant of docol with inline argument)."" |
""Call callee (a variant of docol with inline argument)."" |
#ifdef NO_IP |
#ifdef NO_IP |
|
assert(0); |
INST_TAIL; |
INST_TAIL; |
JUMP(a_callee); |
JUMP(a_callee); |
#else |
#else |
Line 169 execute ( xt -- ) core
|
Line 249 execute ( xt -- ) core
|
#ifndef NO_IP |
#ifndef NO_IP |
ip=IP; |
ip=IP; |
#endif |
#endif |
IF_spTOS(spTOS = sp[0]); |
|
SUPER_END; |
SUPER_END; |
EXEC(xt); |
VM_JUMP(EXEC1(xt)); |
|
|
perform ( a_addr -- ) gforth |
perform ( a_addr -- ) gforth |
""@code{@@ execute}."" |
""@code{@@ execute}."" |
Line 179 perform ( a_addr -- ) gforth
|
Line 258 perform ( a_addr -- ) gforth
|
#ifndef NO_IP |
#ifndef NO_IP |
ip=IP; |
ip=IP; |
#endif |
#endif |
IF_spTOS(spTOS = sp[0]); |
|
SUPER_END; |
SUPER_END; |
EXEC(*(Xt *)a_addr); |
VM_JUMP(EXEC1(*(Xt *)a_addr)); |
: |
: |
@ execute ; |
@ execute ; |
|
|
Line 204 lit-perform ( #a_addr -- ) new lit_perfo
|
Line 282 lit-perform ( #a_addr -- ) new lit_perfo
|
ip=IP; |
ip=IP; |
#endif |
#endif |
SUPER_END; |
SUPER_END; |
EXEC(*(Xt *)a_addr); |
VM_JUMP(EXEC1(*(Xt *)a_addr)); |
|
|
does-exec ( #a_cfa -- R:nest a_pfa ) new does_exec |
does-exec ( #a_cfa -- R:nest a_pfa ) new does_exec |
#ifdef NO_IP |
#ifdef NO_IP |
Line 250 SET_IP((Xt *)a_target);
|
Line 328 SET_IP((Xt *)a_target);
|
|
|
\ condbranch(forthname,stackeffect,restline,code1,code2,forthcode) |
\ condbranch(forthname,stackeffect,restline,code1,code2,forthcode) |
\ this is non-syntactical: code must open a brace that is closed by the macro |
\ this is non-syntactical: code must open a brace that is closed by the macro |
|
\ condbranch(forthname,stackeffect,restline,code1,code2,forthcode) |
|
\ this is non-syntactical: code must open a brace that is closed by the macro |
define(condbranch, |
define(condbranch, |
$1 ( `#'a_target $2 ) $3 |
$1 ( `#'a_target $2 ) $3 |
$4 #ifdef NO_IP |
$4 #ifdef NO_IP |
Line 259 $5 #ifdef NO_IP
|
Line 339 $5 #ifdef NO_IP
|
JUMP(a_target); |
JUMP(a_target); |
#else |
#else |
SET_IP((Xt *)a_target); |
SET_IP((Xt *)a_target); |
|
#endif |
|
} |
|
$6 |
|
|
|
\+glocals |
|
|
|
$1-lp+!`#' ( `#'a_target `#'nlocals $2 ) $3_lp_plus_store_number |
|
$4 #ifdef NO_IP |
|
INST_TAIL; |
|
#endif |
|
$5 lp += nlocals; |
|
#ifdef NO_IP |
|
JUMP(a_target); |
|
#else |
|
SET_IP((Xt *)a_target); |
|
#endif |
|
} |
|
|
|
\+ |
|
) |
|
|
|
\ version that generates two jumps (not good for PR 15242 workaround) |
|
define(condbranch_twojump, |
|
$1 ( `#'a_target $2 ) $3 |
|
$4 #ifdef NO_IP |
|
INST_TAIL; |
|
#endif |
|
$5 #ifdef NO_IP |
|
JUMP(a_target); |
|
#else |
|
SET_IP((Xt *)a_target); |
INST_TAIL; NEXT_P2; |
INST_TAIL; NEXT_P2; |
#endif |
#endif |
} |
} |
Line 353 condbranch((+loop),n R:nlimit R:n1 -- R:
|
Line 464 condbranch((+loop),n R:nlimit R:n1 -- R:
|
/* dependent upon two's complement arithmetic */ |
/* dependent upon two's complement arithmetic */ |
Cell olddiff = n1-nlimit; |
Cell olddiff = n1-nlimit; |
n2=n1+n; |
n2=n1+n; |
,if ((olddiff^(olddiff+n))>=0 /* the limit is not crossed */ |
,if (((olddiff^(olddiff+n)) /* the limit is not crossed */ |
|| (olddiff^n)>=0 /* it is a wrap-around effect */) { |
&(olddiff^n)) /* OR it is a wrap-around effect */ |
|
>=0) { /* & is used to avoid having two branches for gforth-native */ |
,: |
,: |
r> swap |
r> swap |
r> r> 2dup - >r |
r> r> 2dup - >r |
Line 383 if (n<0) {
|
Line 495 if (n<0) {
|
newdiff = -newdiff; |
newdiff = -newdiff; |
} |
} |
n2=n1+n; |
n2=n1+n; |
,if (diff>=0 || newdiff<0) { |
,if (((~diff)|newdiff)<0) { /* use | to avoid two branches for gforth-native */ |
,) |
,) |
|
|
\+ |
\+ |
Line 407 if (nstart == nlimit) {
|
Line 519 if (nstart == nlimit) {
|
JUMP(a_target); |
JUMP(a_target); |
#else |
#else |
SET_IP((Xt *)a_target); |
SET_IP((Xt *)a_target); |
INST_TAIL; NEXT_P2; |
|
#endif |
#endif |
} |
} |
SUPER_CONTINUE; |
|
: |
: |
2dup = |
2dup = |
IF r> swap rot >r >r |
IF r> swap rot >r >r |
Line 430 if (nstart >= nlimit) {
|
Line 540 if (nstart >= nlimit) {
|
JUMP(a_target); |
JUMP(a_target); |
#else |
#else |
SET_IP((Xt *)a_target); |
SET_IP((Xt *)a_target); |
INST_TAIL; NEXT_P2; |
|
#endif |
#endif |
} |
} |
SUPER_CONTINUE; |
|
: |
: |
swap 2dup |
swap 2dup |
r> swap >r swap >r |
r> swap >r swap >r |
Line 453 if (ustart >= ulimit) {
|
Line 561 if (ustart >= ulimit) {
|
JUMP(a_target); |
JUMP(a_target); |
#else |
#else |
SET_IP((Xt *)a_target); |
SET_IP((Xt *)a_target); |
INST_TAIL; NEXT_P2; |
|
#endif |
#endif |
} |
} |
SUPER_CONTINUE; |
|
: |
: |
swap 2dup |
swap 2dup |
r> swap >r swap >r |
r> swap >r swap >r |
Line 476 if (nstart <= nlimit) {
|
Line 582 if (nstart <= nlimit) {
|
JUMP(a_target); |
JUMP(a_target); |
#else |
#else |
SET_IP((Xt *)a_target); |
SET_IP((Xt *)a_target); |
INST_TAIL; NEXT_P2; |
|
#endif |
#endif |
} |
} |
SUPER_CONTINUE; |
|
: |
: |
swap 2dup |
swap 2dup |
r> swap >r swap >r |
r> swap >r swap >r |
Line 499 if (ustart <= ulimit) {
|
Line 603 if (ustart <= ulimit) {
|
JUMP(a_target); |
JUMP(a_target); |
#else |
#else |
SET_IP((Xt *)a_target); |
SET_IP((Xt *)a_target); |
INST_TAIL; NEXT_P2; |
|
#endif |
#endif |
} |
} |
SUPER_CONTINUE; |
|
: |
: |
swap 2dup |
swap 2dup |
r> swap >r swap >r |
r> swap >r swap >r |
Line 594 n = compare(c_addr1, u1, c_addr2, u2);
|
Line 696 n = compare(c_addr1, u1, c_addr2, u2);
|
: |
: |
rot 2dup swap - >r min swap -text dup |
rot 2dup swap - >r min swap -text dup |
IF rdrop ELSE drop r> sgn THEN ; |
IF rdrop ELSE drop r> sgn THEN ; |
|
: -text ( c_addr1 u c_addr2 -- n ) |
|
swap bounds |
|
?DO dup c@ I c@ = WHILE 1+ LOOP drop 0 |
|
ELSE c@ I c@ - unloop THEN sgn ; |
: sgn ( n -- -1/0/1 ) |
: sgn ( n -- -1/0/1 ) |
dup 0= IF EXIT THEN 0< 2* 1+ ; |
dup 0= IF EXIT THEN 0< 2* 1+ ; |
|
|
Line 699 n = n1*n2;
|
Line 805 n = n1*n2;
|
|
|
/ ( n1 n2 -- n ) core slash |
/ ( n1 n2 -- n ) core slash |
n = n1/n2; |
n = n1/n2; |
|
if(FLOORED_DIV && ((n1^n2) < 0) && (n1%n2 != 0)) n--; |
: |
: |
/mod nip ; |
/mod nip ; |
|
|
mod ( n1 n2 -- n ) core |
mod ( n1 n2 -- n ) core |
n = n1%n2; |
n = n1%n2; |
|
if(FLOORED_DIV && ((n1^n2) < 0) && n!=0) n += n2; |
: |
: |
/mod drop ; |
/mod drop ; |
|
|
/mod ( n1 n2 -- n3 n4 ) core slash_mod |
/mod ( n1 n2 -- n3 n4 ) core slash_mod |
n4 = n1/n2; |
n4 = n1/n2; |
n3 = n1%n2; /* !! is this correct? look into C standard! */ |
n3 = n1%n2; /* !! is this correct? look into C standard! */ |
|
if (FLOORED_DIV && ((n1^n2) < 0) && n3!=0) { |
|
n4--; |
|
n3+=n2; |
|
} |
: |
: |
>r s>d r> fm/mod ; |
>r s>d r> fm/mod ; |
|
|
|
*/mod ( n1 n2 n3 -- n4 n5 ) core star_slash_mod |
|
""n1*n2=n3*n5+n4, with the intermediate result (n1*n2) being double."" |
|
#ifdef BUGGY_LL_MUL |
|
DCell d = mmul(n1,n2); |
|
#else |
|
DCell d = (DCell)n1 * (DCell)n2; |
|
#endif |
|
#ifdef BUGGY_LL_DIV |
|
DCell r = fmdiv(d,n3); |
|
n4=DHI(r); |
|
n5=DLO(r); |
|
#else |
|
/* assumes that the processor uses either floored or symmetric division */ |
|
n5 = d/n3; |
|
n4 = d%n3; |
|
if (FLOORED_DIV && ((DHI(d)^n3)<0) && n4!=0) { |
|
n5--; |
|
n4+=n3; |
|
} |
|
#endif |
|
: |
|
>r m* r> fm/mod ; |
|
|
|
*/ ( n1 n2 n3 -- n4 ) core star_slash |
|
""n4=(n1*n2)/n3, with the intermediate result being double."" |
|
#ifdef BUGGY_LL_MUL |
|
DCell d = mmul(n1,n2); |
|
#else |
|
DCell d = (DCell)n1 * (DCell)n2; |
|
#endif |
|
#ifdef BUGGY_LL_DIV |
|
DCell r = fmdiv(d,n3); |
|
n4=DLO(r); |
|
#else |
|
/* assumes that the processor uses either floored or symmetric division */ |
|
n4 = d/n3; |
|
if (FLOORED_DIV && ((DHI(d)^n3)<0) && (d%n3)!=0) n4--; |
|
#endif |
|
: |
|
*/mod nip ; |
|
|
2* ( n1 -- n2 ) core two_star |
2* ( n1 -- n2 ) core two_star |
""Shift left by 1; also works on unsigned numbers"" |
""Shift left by 1; also works on unsigned numbers"" |
n2 = 2*n1; |
n2 = 2*n1; |
Line 732 n2 = n1>>1;
|
Line 885 n2 = n1>>1;
|
|
|
fm/mod ( d1 n1 -- n2 n3 ) core f_m_slash_mod |
fm/mod ( d1 n1 -- n2 n3 ) core f_m_slash_mod |
""Floored division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, @i{n1}>@i{n2}>=0 or 0>=@i{n2}>@i{n1}."" |
""Floored division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, @i{n1}>@i{n2}>=0 or 0>=@i{n2}>@i{n1}."" |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_DIV |
|
#ifdef ASM_SM_SLASH_REM |
|
ASM_SM_SLASH_REM(d1.lo, d1.hi, n1, n2, n3); |
|
if (((DHI(d1)^n1)<0) && n2!=0) { |
|
n3--; |
|
n2+=n1; |
|
} |
|
#else /* !defined(ASM_SM_SLASH_REM) */ |
DCell r = fmdiv(d1,n1); |
DCell r = fmdiv(d1,n1); |
n2=r.hi; |
n2=DHI(r); |
n3=r.lo; |
n3=DLO(r); |
#else |
#endif /* !defined(ASM_SM_SLASH_REM) */ |
|
#else |
|
#ifdef ASM_SM_SLASH_REM4 |
|
ASM_SM_SLASH_REM4(d1, n1, n2, n3); |
|
if (((DHI(d1)^n1)<0) && n2!=0) { |
|
n3--; |
|
n2+=n1; |
|
} |
|
#else /* !defined(ASM_SM_SLASH_REM4) */ |
/* assumes that the processor uses either floored or symmetric division */ |
/* assumes that the processor uses either floored or symmetric division */ |
n3 = d1/n1; |
n3 = d1/n1; |
n2 = d1%n1; |
n2 = d1%n1; |
/* note that this 1%-3>0 is optimized by the compiler */ |
/* note that this 1%-3>0 is optimized by the compiler */ |
if (1%-3>0 && (d1<0) != (n1<0) && n2!=0) { |
if (1%-3>0 && ((DHI(d1)^n1)<0) && n2!=0) { |
n3--; |
n3--; |
n2+=n1; |
n2+=n1; |
} |
} |
|
#endif /* !defined(ASM_SM_SLASH_REM4) */ |
#endif |
#endif |
: |
: |
dup >r dup 0< IF negate >r dnegate r> THEN |
dup >r dup 0< IF negate >r dnegate r> THEN |
Line 754 if (1%-3>0 && (d1<0) != (n1<0) && n2!=0)
|
Line 923 if (1%-3>0 && (d1<0) != (n1<0) && n2!=0)
|
|
|
sm/rem ( d1 n1 -- n2 n3 ) core s_m_slash_rem |
sm/rem ( d1 n1 -- n2 n3 ) core s_m_slash_rem |
""Symmetric division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, sign(@i{n2})=sign(@i{d1}) or 0."" |
""Symmetric division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, sign(@i{n2})=sign(@i{d1}) or 0."" |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_DIV |
|
#ifdef ASM_SM_SLASH_REM |
|
ASM_SM_SLASH_REM(d1.lo, d1.hi, n1, n2, n3); |
|
#else /* !defined(ASM_SM_SLASH_REM) */ |
DCell r = smdiv(d1,n1); |
DCell r = smdiv(d1,n1); |
n2=r.hi; |
n2=DHI(r); |
n3=r.lo; |
n3=DLO(r); |
#else |
#endif /* !defined(ASM_SM_SLASH_REM) */ |
|
#else |
|
#ifdef ASM_SM_SLASH_REM4 |
|
ASM_SM_SLASH_REM4(d1, n1, n2, n3); |
|
#else /* !defined(ASM_SM_SLASH_REM4) */ |
/* assumes that the processor uses either floored or symmetric division */ |
/* assumes that the processor uses either floored or symmetric division */ |
n3 = d1/n1; |
n3 = d1/n1; |
n2 = d1%n1; |
n2 = d1%n1; |
/* note that this 1%-3<0 is optimized by the compiler */ |
/* note that this 1%-3<0 is optimized by the compiler */ |
if (1%-3<0 && (d1<0) != (n1<0) && n2!=0) { |
if (1%-3<0 && ((DHI(d1)^n1)<0) && n2!=0) { |
n3++; |
n3++; |
n2-=n1; |
n2-=n1; |
} |
} |
|
#endif /* !defined(ASM_SM_SLASH_REM4) */ |
#endif |
#endif |
: |
: |
over >r dup >r abs -rot |
over >r dup >r abs -rot |
Line 775 if (1%-3<0 && (d1<0) != (n1<0) && n2!=0)
|
Line 952 if (1%-3<0 && (d1<0) != (n1<0) && n2!=0)
|
r> 0< IF swap negate swap THEN ; |
r> 0< IF swap negate swap THEN ; |
|
|
m* ( n1 n2 -- d ) core m_star |
m* ( n1 n2 -- d ) core m_star |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_MUL |
d = mmul(n1,n2); |
d = mmul(n1,n2); |
#else |
#else |
d = (DCell)n1 * (DCell)n2; |
d = (DCell)n1 * (DCell)n2; |
Line 787 d = (DCell)n1 * (DCell)n2;
|
Line 964 d = (DCell)n1 * (DCell)n2;
|
|
|
um* ( u1 u2 -- ud ) core u_m_star |
um* ( u1 u2 -- ud ) core u_m_star |
/* use u* as alias */ |
/* use u* as alias */ |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_MUL |
ud = ummul(u1,u2); |
ud = ummul(u1,u2); |
#else |
#else |
ud = (UDCell)u1 * (UDCell)u2; |
ud = (UDCell)u1 * (UDCell)u2; |
#endif |
#endif |
: |
: |
>r >r 0 0 r> r> [ 8 cells ] literal 0 |
0 -rot dup [ 8 cells ] literal - |
DO |
DO |
over >r dup >r 0< and d2*+ drop |
dup 0< I' and d2*+ drop |
r> 2* r> swap |
LOOP ; |
LOOP 2drop ; |
|
: d2*+ ( ud n -- ud+n c ) |
: d2*+ ( ud n -- ud+n c ) |
over MINI |
over MINI |
and >r >r 2dup d+ swap r> + swap r> ; |
and >r >r 2dup d+ swap r> + swap r> ; |
|
|
um/mod ( ud u1 -- u2 u3 ) core u_m_slash_mod |
um/mod ( ud u1 -- u2 u3 ) core u_m_slash_mod |
""ud=u3*u1+u2, u1>u2>=0"" |
""ud=u3*u1+u2, u1>u2>=0"" |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_DIV |
|
#ifdef ASM_UM_SLASH_MOD |
|
ASM_UM_SLASH_MOD(ud.lo, ud.hi, u1, u2, u3); |
|
#else /* !defined(ASM_UM_SLASH_MOD) */ |
UDCell r = umdiv(ud,u1); |
UDCell r = umdiv(ud,u1); |
u2=r.hi; |
u2=DHI(r); |
u3=r.lo; |
u3=DLO(r); |
#else |
#endif /* !defined(ASM_UM_SLASH_MOD) */ |
|
#else |
|
#ifdef ASM_UM_SLASH_MOD4 |
|
ASM_UM_SLASH_MOD4(ud, u1, u2, u3); |
|
#else /* !defined(ASM_UM_SLASH_MOD4) */ |
u3 = ud/u1; |
u3 = ud/u1; |
u2 = ud%u1; |
u2 = ud%u1; |
|
#endif /* !defined(ASM_UM_SLASH_MOD4) */ |
#endif |
#endif |
: |
: |
0 swap [ 8 cells 1 + ] literal 0 |
0 swap [ 8 cells 1 + ] literal 0 |
Line 823 u2 = ud%u1;
|
Line 1007 u2 = ud%u1;
|
and >r >r 2dup d+ swap r> + swap r> ; |
and >r >r 2dup d+ swap r> + swap r> ; |
|
|
m+ ( d1 n -- d2 ) double m_plus |
m+ ( d1 n -- d2 ) double m_plus |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_ADD |
d2.lo = d1.lo+n; |
DLO_IS(d2, DLO(d1)+n); |
d2.hi = d1.hi - (n<0) + (d2.lo<d1.lo); |
DHI_IS(d2, DHI(d1) - (n<0) + (DLO(d2)<DLO(d1))); |
#else |
#else |
d2 = d1+n; |
d2 = d1+n; |
#endif |
#endif |
Line 833 d2 = d1+n;
|
Line 1017 d2 = d1+n;
|
s>d d+ ; |
s>d d+ ; |
|
|
d+ ( d1 d2 -- d ) double d_plus |
d+ ( d1 d2 -- d ) double d_plus |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_ADD |
d.lo = d1.lo+d2.lo; |
DLO_IS(d, DLO(d1) + DLO(d2)); |
d.hi = d1.hi + d2.hi + (d.lo<d1.lo); |
DHI_IS(d, DHI(d1) + DHI(d2) + (d.lo<DLO(d1))); |
#else |
#else |
d = d1+d2; |
d = d1+d2; |
#endif |
#endif |
Line 843 d = d1+d2;
|
Line 1027 d = d1+d2;
|
rot + >r tuck + swap over u> r> swap - ; |
rot + >r tuck + swap over u> r> swap - ; |
|
|
d- ( d1 d2 -- d ) double d_minus |
d- ( d1 d2 -- d ) double d_minus |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_ADD |
d.lo = d1.lo - d2.lo; |
DLO_IS(d, DLO(d1) - DLO(d2)); |
d.hi = d1.hi-d2.hi-(d1.lo<d2.lo); |
DHI_IS(d, DHI(d1)-DHI(d2)-(DLO(d1)<DLO(d2))); |
#else |
#else |
d = d1-d2; |
d = d1-d2; |
#endif |
#endif |
Line 854 d = d1-d2;
|
Line 1038 d = d1-d2;
|
|
|
dnegate ( d1 -- d2 ) double d_negate |
dnegate ( d1 -- d2 ) double d_negate |
/* use dminus as alias */ |
/* use dminus as alias */ |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_ADD |
d2 = dnegate(d1); |
d2 = dnegate(d1); |
#else |
#else |
d2 = -d1; |
d2 = -d1; |
Line 864 d2 = -d1;
|
Line 1048 d2 = -d1;
|
|
|
d2* ( d1 -- d2 ) double d_two_star |
d2* ( d1 -- d2 ) double d_two_star |
""Shift left by 1; also works on unsigned numbers"" |
""Shift left by 1; also works on unsigned numbers"" |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_SHIFT |
d2.lo = d1.lo<<1; |
DLO_IS(d2, DLO(d1)<<1); |
d2.hi = (d1.hi<<1) | (d1.lo>>(CELL_BITS-1)); |
DHI_IS(d2, (DHI(d1)<<1) | (DLO(d1)>>(CELL_BITS-1))); |
#else |
#else |
d2 = 2*d1; |
d2 = 2*d1; |
#endif |
#endif |
Line 876 d2 = 2*d1;
|
Line 1060 d2 = 2*d1;
|
d2/ ( d1 -- d2 ) double d_two_slash |
d2/ ( d1 -- d2 ) double d_two_slash |
""Arithmetic shift right by 1. For signed numbers this is a floored |
""Arithmetic shift right by 1. For signed numbers this is a floored |
division by 2."" |
division by 2."" |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_SHIFT |
d2.hi = d1.hi>>1; |
DHI_IS(d2, DHI(d1)>>1); |
d2.lo= (d1.lo>>1) | (d1.hi<<(CELL_BITS-1)); |
DLO_IS(d2, (DLO(d1)>>1) | (DHI(d1)<<(CELL_BITS-1))); |
#else |
#else |
d2 = d1>>1; |
d2 = d1>>1; |
#endif |
#endif |
Line 904 w2 = ~w1;
|
Line 1088 w2 = ~w1;
|
|
|
rshift ( u1 n -- u2 ) core r_shift |
rshift ( u1 n -- u2 ) core r_shift |
""Logical shift right by @i{n} bits."" |
""Logical shift right by @i{n} bits."" |
u2 = u1>>n; |
#ifdef BROKEN_SHIFT |
|
u2 = rshift(u1, n); |
|
#else |
|
u2 = u1 >> n; |
|
#endif |
: |
: |
0 ?DO 2/ MAXI and LOOP ; |
0 ?DO 2/ MAXI and LOOP ; |
|
|
lshift ( u1 n -- u2 ) core l_shift |
lshift ( u1 n -- u2 ) core l_shift |
u2 = u1<<n; |
#ifdef BROKEN_SHIFT |
|
u2 = lshift(u1, n); |
|
#else |
|
u2 = u1 << n; |
|
#endif |
: |
: |
0 ?DO 2* LOOP ; |
0 ?DO 2* LOOP ; |
|
|
Line 973 comparisons(u, u1 u2, u_, u1, u2, gforth
|
Line 1165 comparisons(u, u1 u2, u_, u1, u2, gforth
|
\ dcomparisons(prefix, args, prefix, arg1, arg2, wordsets...) |
\ dcomparisons(prefix, args, prefix, arg1, arg2, wordsets...) |
define(dcomparisons, |
define(dcomparisons, |
$1= ( $2 -- f ) $6 $3equals |
$1= ( $2 -- f ) $6 $3equals |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_CMP |
f = FLAG($4.lo==$5.lo && $4.hi==$5.hi); |
f = FLAG($4.lo==$5.lo && $4.hi==$5.hi); |
#else |
#else |
f = FLAG($4==$5); |
f = FLAG($4==$5); |
#endif |
#endif |
|
|
$1<> ( $2 -- f ) $7 $3not_equals |
$1<> ( $2 -- f ) $7 $3not_equals |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_CMP |
f = FLAG($4.lo!=$5.lo || $4.hi!=$5.hi); |
f = FLAG($4.lo!=$5.lo || $4.hi!=$5.hi); |
#else |
#else |
f = FLAG($4!=$5); |
f = FLAG($4!=$5); |
#endif |
#endif |
|
|
$1< ( $2 -- f ) $8 $3less_than |
$1< ( $2 -- f ) $8 $3less_than |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_CMP |
f = FLAG($4.hi==$5.hi ? $4.lo<$5.lo : $4.hi<$5.hi); |
f = FLAG($4.hi==$5.hi ? $4.lo<$5.lo : $4.hi<$5.hi); |
#else |
#else |
f = FLAG($4<$5); |
f = FLAG($4<$5); |
#endif |
#endif |
|
|
$1> ( $2 -- f ) $9 $3greater_than |
$1> ( $2 -- f ) $9 $3greater_than |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_CMP |
f = FLAG($4.hi==$5.hi ? $4.lo>$5.lo : $4.hi>$5.hi); |
f = FLAG($4.hi==$5.hi ? $4.lo>$5.lo : $4.hi>$5.hi); |
#else |
#else |
f = FLAG($4>$5); |
f = FLAG($4>$5); |
#endif |
#endif |
|
|
$1<= ( $2 -- f ) gforth $3less_or_equal |
$1<= ( $2 -- f ) gforth $3less_or_equal |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_CMP |
f = FLAG($4.hi==$5.hi ? $4.lo<=$5.lo : $4.hi<=$5.hi); |
f = FLAG($4.hi==$5.hi ? $4.lo<=$5.lo : $4.hi<=$5.hi); |
#else |
#else |
f = FLAG($4<=$5); |
f = FLAG($4<=$5); |
#endif |
#endif |
|
|
$1>= ( $2 -- f ) gforth $3greater_or_equal |
$1>= ( $2 -- f ) gforth $3greater_or_equal |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_CMP |
f = FLAG($4.hi==$5.hi ? $4.lo>=$5.lo : $4.hi>=$5.hi); |
f = FLAG($4.hi==$5.hi ? $4.lo>=$5.lo : $4.hi>=$5.hi); |
#else |
#else |
f = FLAG($4>=$5); |
f = FLAG($4>=$5); |
Line 1084 rdrop ( R:w -- ) gforth
|
Line 1276 rdrop ( R:w -- ) gforth
|
: |
: |
r> r> drop >r ; |
r> r> drop >r ; |
|
|
2>r ( w1 w2 -- R:w1 R:w2 ) core-ext two_to_r |
2>r ( d -- R:d ) core-ext two_to_r |
: |
: |
swap r> swap >r swap >r >r ; |
swap r> swap >r swap >r >r ; |
|
|
2r> ( R:w1 R:w2 -- w1 w2 ) core-ext two_r_from |
2r> ( R:d -- d ) core-ext two_r_from |
: |
: |
r> r> swap r> swap >r swap ; |
r> r> swap r> swap >r swap ; |
|
|
2r@ ( R:w1 R:w2 -- R:w1 R:w2 w1 w2 ) core-ext two_r_fetch |
2r@ ( R:d -- R:d d ) core-ext two_r_fetch |
: |
: |
i' j ; |
i' j ; |
|
|
2rdrop ( R:w1 R:w2 -- ) gforth two_r_drop |
2rdrop ( R:d -- ) gforth two_r_drop |
: |
: |
r> r> drop r> drop >r ; |
r> r> drop r> drop >r ; |
|
|
Line 1316 c_addr2 = c_addr1+1;
|
Line 1508 c_addr2 = c_addr1+1;
|
|
|
\g compiler |
\g compiler |
|
|
|
\+f83headerstring |
|
|
|
(f83find) ( c_addr u f83name1 -- f83name2 ) new paren_f83find |
|
for (; f83name1 != NULL; f83name1 = (struct F83Name *)(f83name1->next)) |
|
if ((UCell)F83NAME_COUNT(f83name1)==u && |
|
memcasecmp(c_addr, f83name1->name, u)== 0 /* or inline? */) |
|
break; |
|
f83name2=f83name1; |
|
: |
|
BEGIN dup WHILE (find-samelen) dup WHILE |
|
>r 2dup r@ cell+ char+ capscomp 0= |
|
IF 2drop r> EXIT THEN |
|
r> @ |
|
REPEAT THEN nip nip ; |
|
: (find-samelen) ( u f83name1 -- u f83name2/0 ) |
|
BEGIN 2dup cell+ c@ $1F and <> WHILE @ dup 0= UNTIL THEN ; |
|
: capscomp ( c_addr1 u c_addr2 -- n ) |
|
swap bounds |
|
?DO dup c@ I c@ <> |
|
IF dup c@ toupper I c@ toupper = |
|
ELSE true THEN WHILE 1+ LOOP drop 0 |
|
ELSE c@ toupper I c@ toupper - unloop THEN sgn ; |
|
: sgn ( n -- -1/0/1 ) |
|
dup 0= IF EXIT THEN 0< 2* 1+ ; |
|
|
|
\- |
|
|
(listlfind) ( c_addr u longname1 -- longname2 ) new paren_listlfind |
(listlfind) ( c_addr u longname1 -- longname2 ) new paren_listlfind |
longname2=listlfind(c_addr, u, longname1); |
longname2=listlfind(c_addr, u, longname1); |
: |
: |
Line 1326 longname2=listlfind(c_addr, u, longname1
|
Line 1545 longname2=listlfind(c_addr, u, longname1
|
REPEAT THEN nip nip ; |
REPEAT THEN nip nip ; |
: (findl-samelen) ( u longname1 -- u longname2/0 ) |
: (findl-samelen) ( u longname1 -- u longname2/0 ) |
BEGIN 2dup cell+ @ lcount-mask and <> WHILE @ dup 0= UNTIL THEN ; |
BEGIN 2dup cell+ @ lcount-mask and <> WHILE @ dup 0= UNTIL THEN ; |
|
: capscomp ( c_addr1 u c_addr2 -- n ) |
|
swap bounds |
|
?DO dup c@ I c@ <> |
|
IF dup c@ toupper I c@ toupper = |
|
ELSE true THEN WHILE 1+ LOOP drop 0 |
|
ELSE c@ toupper I c@ toupper - unloop THEN sgn ; |
|
: sgn ( n -- -1/0/1 ) |
|
dup 0= IF EXIT THEN 0< 2* 1+ ; |
|
|
\+hash |
\+hash |
|
|
Line 1349 longname2 = tablelfind(c_addr, u, a_addr
|
Line 1576 longname2 = tablelfind(c_addr, u, a_addr
|
IF 2drop r> rdrop EXIT THEN THEN |
IF 2drop r> rdrop EXIT THEN THEN |
rdrop r> |
rdrop r> |
REPEAT nip nip ; |
REPEAT nip nip ; |
|
: -text ( c_addr1 u c_addr2 -- n ) |
|
swap bounds |
|
?DO dup c@ I c@ = WHILE 1+ LOOP drop 0 |
|
ELSE c@ I c@ - unloop THEN sgn ; |
|
: sgn ( n -- -1/0/1 ) |
|
dup 0= IF EXIT THEN 0< 2* 1+ ; |
|
|
(hashkey1) ( c_addr u ubits -- ukey ) gforth paren_hashkey1 |
(hashkey1) ( c_addr u ubits -- ukey ) gforth paren_hashkey1 |
""ukey is the hash key for the string c_addr u fitting in ubits bits"" |
""ukey is the hash key for the string c_addr u fitting in ubits bits"" |
Line 1368 Create rot-values
|
Line 1601 Create rot-values
|
|
|
\+ |
\+ |
|
|
|
\+ |
|
|
(parse-white) ( c_addr1 u1 -- c_addr2 u2 ) gforth paren_parse_white |
(parse-white) ( c_addr1 u1 -- c_addr2 u2 ) gforth paren_parse_white |
struct Cellpair r=parse_white(c_addr1, u1); |
struct Cellpair r=parse_white(c_addr1, u1); |
c_addr2 = (Char *)(r.n1); |
c_addr2 = (Char *)(r.n1); |
Line 1463 SUPER_END;
|
Line 1698 SUPER_END;
|
return (Label *)n; |
return (Label *)n; |
|
|
(system) ( c_addr u -- wretval wior ) gforth paren_system |
(system) ( c_addr u -- wretval wior ) gforth paren_system |
#ifndef MSDOS |
wretval = gforth_system(c_addr, u); |
int old_tp=terminal_prepped; |
|
deprep_terminal(); |
|
#endif |
|
wretval=system(cstr(c_addr,u,1)); /* ~ expansion on first part of string? */ |
|
wior = IOR(wretval==-1 || (wretval==127 && errno != 0)); |
wior = IOR(wretval==-1 || (wretval==127 && errno != 0)); |
#ifndef MSDOS |
|
if (old_tp) |
|
prep_terminal(); |
|
#endif |
|
|
|
getenv ( c_addr1 u1 -- c_addr2 u2 ) gforth |
getenv ( c_addr1 u1 -- c_addr2 u2 ) gforth |
""The string @i{c-addr1 u1} specifies an environment variable. The string @i{c-addr2 u2} |
""The string @i{c-addr1 u1} specifies an environment variable. The string @i{c-addr2 u2} |
Line 1561 c_addr = strerror(n);
|
Line 1788 c_addr = strerror(n);
|
u = strlen(c_addr); |
u = strlen(c_addr); |
|
|
strsignal ( n -- c_addr u ) gforth |
strsignal ( n -- c_addr u ) gforth |
c_addr = strsignal(n); |
c_addr = (Address)strsignal(n); |
u = strlen(c_addr); |
u = strlen(c_addr); |
|
|
call-c ( w -- ) gforth call_c |
call-c ( w -- ) gforth call_c |
Line 1718 char * string = cstr(c_addr1, u1, 1);
|
Line 1945 char * string = cstr(c_addr1, u1, 1);
|
char * pattern = cstr(c_addr2, u2, 0); |
char * pattern = cstr(c_addr2, u2, 0); |
flag = FLAG(!fnmatch(pattern, string, 0)); |
flag = FLAG(!fnmatch(pattern, string, 0)); |
|
|
|
set-dir ( c_addr u -- wior ) gforth set_dir |
|
""Change the current directory to @i{c-addr, u}. |
|
Return an error if this is not possible"" |
|
wior = IOR(chdir(tilde_cstr(c_addr, u, 1))); |
|
|
|
get-dir ( c_addr1 u1 -- c_addr2 u2 ) gforth get_dir |
|
""Store the current directory in the buffer specified by @{c-addr1, u1}. |
|
If the buffer size is not sufficient, return 0 0"" |
|
c_addr2 = getcwd(c_addr1, u1); |
|
if(c_addr2 != NULL) { |
|
u2 = strlen(c_addr2); |
|
} else { |
|
u2 = 0; |
|
} |
|
|
\+ |
\+ |
|
|
newline ( -- c_addr u ) gforth |
newline ( -- c_addr u ) gforth |
Line 1760 dsystem = timeval2us(&usage.ru_stime);
|
Line 2002 dsystem = timeval2us(&usage.ru_stime);
|
struct timeval time1; |
struct timeval time1; |
gettimeofday(&time1,NULL); |
gettimeofday(&time1,NULL); |
duser = timeval2us(&time1); |
duser = timeval2us(&time1); |
#ifndef BUGGY_LONG_LONG |
dsystem = DZERO; |
dsystem = (DCell)0; |
|
#else |
|
dsystem=(DCell){0,0}; |
|
#endif |
|
#endif |
#endif |
|
|
\+ |
\+ |
Line 1777 comparisons(f, r1 r2, f_, r1, r2, gforth
|
Line 2015 comparisons(f, r1 r2, f_, r1, r2, gforth
|
comparisons(f0, r, f_zero_, r, 0., float, gforth, float, gforth) |
comparisons(f0, r, f_zero_, r, 0., float, gforth, float, gforth) |
|
|
d>f ( d -- r ) float d_to_f |
d>f ( d -- r ) float d_to_f |
#ifdef BUGGY_LONG_LONG |
#ifdef BUGGY_LL_D2F |
extern double ldexp(double x, int exp); |
extern double ldexp(double x, int exp); |
if (d.hi<0) { |
if (DHI(d)<0) { |
|
#ifdef BUGGY_LL_ADD |
DCell d2=dnegate(d); |
DCell d2=dnegate(d); |
r = -(ldexp((Float)d2.hi,CELL_BITS) + (Float)d2.lo); |
#else |
|
DCell d2=-d; |
|
#endif |
|
r = -(ldexp((Float)DHI(d2),CELL_BITS) + (Float)DLO(d2)); |
} else |
} else |
r = ldexp((Float)d.hi,CELL_BITS) + (Float)d.lo; |
r = ldexp((Float)DHI(d),CELL_BITS) + (Float)DLO(d); |
#else |
#else |
r = d; |
r = d; |
#endif |
#endif |
Line 1908 f2=FLAG(isdigit((unsigned)(sig[0]))!=0);
|
Line 2150 f2=FLAG(isdigit((unsigned)(sig[0]))!=0);
|
siglen=strlen(sig); |
siglen=strlen(sig); |
if (siglen>u) /* happens in glibc-2.1.3 if 999.. is rounded up */ |
if (siglen>u) /* happens in glibc-2.1.3 if 999.. is rounded up */ |
siglen=u; |
siglen=u; |
|
if (!f2) /* workaround Cygwin trailing 0s for Inf and Nan */ |
|
for (; sig[siglen-1]=='0'; siglen--); |
|
; |
memcpy(c_addr,sig,siglen); |
memcpy(c_addr,sig,siglen); |
memset(c_addr+siglen,f2?'0':' ',u-siglen); |
memset(c_addr+siglen,f2?'0':' ',u-siglen); |
|
|
Line 2162 r = fp[u+1]; /* +1, because update of fp
|
Line 2407 r = fp[u+1]; /* +1, because update of fp
|
|
|
\g syslib |
\g syslib |
|
|
|
open-lib ( c_addr1 u1 -- u2 ) gforth open_lib |
|
#if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) |
|
#ifndef RTLD_GLOBAL |
|
#define RTLD_GLOBAL 0 |
|
#endif |
|
u2=(UCell) dlopen(cstr(c_addr1, u1, 1), RTLD_GLOBAL | RTLD_LAZY); |
|
#else |
|
# ifdef _WIN32 |
|
u2 = (Cell) GetModuleHandle(cstr(c_addr1, u1, 1)); |
|
# else |
|
#warning Define open-lib! |
|
u2 = 0; |
|
# endif |
|
#endif |
|
|
|
lib-sym ( c_addr1 u1 u2 -- u3 ) gforth lib_sym |
|
#if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) |
|
u3 = (UCell) dlsym((void*)u2,cstr(c_addr1, u1, 1)); |
|
#else |
|
# ifdef _WIN32 |
|
u3 = (Cell) GetProcAddress((HMODULE)u2, cstr(c_addr1, u1, 1)); |
|
# else |
|
#warning Define lib-sym! |
|
u3 = 0; |
|
# endif |
|
#endif |
|
|
|
wcall ( u -- ) gforth |
|
IF_fpTOS(fp[0]=fpTOS); |
|
FP=fp; |
|
sp=(Cell*)(SYSCALL(Cell*(*)(Cell *, void *))u)(sp, &FP); |
|
fp=FP; |
|
IF_spTOS(spTOS=sp[0];) |
|
IF_fpTOS(fpTOS=fp[0]); |
|
|
|
\+FFCALL |
|
|
|
av-start-void ( c_addr -- ) gforth av_start_void |
|
av_start_void(alist, c_addr); |
|
|
|
av-start-int ( c_addr -- ) gforth av_start_int |
|
av_start_int(alist, c_addr, &irv); |
|
|
|
av-start-float ( c_addr -- ) gforth av_start_float |
|
av_start_float(alist, c_addr, &frv); |
|
|
|
av-start-double ( c_addr -- ) gforth av_start_double |
|
av_start_double(alist, c_addr, &drv); |
|
|
|
av-start-longlong ( c_addr -- ) gforth av_start_longlong |
|
av_start_longlong(alist, c_addr, &llrv); |
|
|
|
av-start-ptr ( c_addr -- ) gforth av_start_ptr |
|
av_start_ptr(alist, c_addr, void*, &prv); |
|
|
|
av-int ( w -- ) gforth av_int |
|
av_int(alist, w); |
|
|
|
av-float ( r -- ) gforth av_float |
|
av_float(alist, r); |
|
|
|
av-double ( r -- ) gforth av_double |
|
av_double(alist, r); |
|
|
|
av-longlong ( d -- ) gforth av_longlong |
|
#ifdef BUGGY_LL_SIZE |
|
av_longlong(alist, DLO(d)); |
|
#else |
|
av_longlong(alist, d); |
|
#endif |
|
|
|
av-ptr ( c_addr -- ) gforth av_ptr |
|
av_ptr(alist, void*, c_addr); |
|
|
|
av-int-r ( R:w -- ) gforth av_int_r |
|
av_int(alist, w); |
|
|
|
av-float-r ( -- ) gforth av_float_r |
|
float r = *(Float*)lp; |
|
lp += sizeof(Float); |
|
av_float(alist, r); |
|
|
|
av-double-r ( -- ) gforth av_double_r |
|
double r = *(Float*)lp; |
|
lp += sizeof(Float); |
|
av_double(alist, r); |
|
|
|
av-longlong-r ( R:d -- ) gforth av_longlong_r |
|
#ifdef BUGGY_LL_SIZE |
|
av_longlong(alist, DLO(d)); |
|
#else |
|
av_longlong(alist, d); |
|
#endif |
|
|
|
av-ptr-r ( R:c_addr -- ) gforth av_ptr_r |
|
av_ptr(alist, void*, c_addr); |
|
|
|
av-call-void ( -- ) gforth av_call_void |
|
SAVE_REGS |
|
av_call(alist); |
|
REST_REGS |
|
|
|
av-call-int ( -- w ) gforth av_call_int |
|
SAVE_REGS |
|
av_call(alist); |
|
REST_REGS |
|
w = irv; |
|
|
|
av-call-float ( -- r ) gforth av_call_float |
|
SAVE_REGS |
|
av_call(alist); |
|
REST_REGS |
|
r = frv; |
|
|
|
av-call-double ( -- r ) gforth av_call_double |
|
SAVE_REGS |
|
av_call(alist); |
|
REST_REGS |
|
r = drv; |
|
|
|
av-call-longlong ( -- d ) gforth av_call_longlong |
|
SAVE_REGS |
|
av_call(alist); |
|
REST_REGS |
|
#ifdef BUGGY_LONG_LONG |
|
DLO_IS(d, llrv); |
|
DHI_IS(d, 0); |
|
#else |
|
d = llrv; |
|
#endif |
|
|
|
av-call-ptr ( -- c_addr ) gforth av_call_ptr |
|
SAVE_REGS |
|
av_call(alist); |
|
REST_REGS |
|
c_addr = prv; |
|
|
|
alloc-callback ( a_ip -- c_addr ) gforth alloc_callback |
|
c_addr = (char *)alloc_callback(engine_callback, (Xt *)a_ip); |
|
|
|
va-start-void ( -- ) gforth va_start_void |
|
va_start_void(clist); |
|
|
|
va-start-int ( -- ) gforth va_start_int |
|
va_start_int(clist); |
|
|
|
va-start-longlong ( -- ) gforth va_start_longlong |
|
va_start_longlong(clist); |
|
|
|
va-start-ptr ( -- ) gforth va_start_ptr |
|
va_start_ptr(clist, (char *)); |
|
|
|
va-start-float ( -- ) gforth va_start_float |
|
va_start_float(clist); |
|
|
|
va-start-double ( -- ) gforth va_start_double |
|
va_start_double(clist); |
|
|
|
va-arg-int ( -- w ) gforth va_arg_int |
|
w = va_arg_int(clist); |
|
|
|
va-arg-longlong ( -- d ) gforth va_arg_longlong |
|
#ifdef BUGGY_LONG_LONG |
|
DLO_IS(d, va_arg_longlong(clist)); |
|
DHI_IS(d, 0); |
|
#else |
|
d = va_arg_longlong(clist); |
|
#endif |
|
|
|
va-arg-ptr ( -- c_addr ) gforth va_arg_ptr |
|
c_addr = (char *)va_arg_ptr(clist,char*); |
|
|
|
va-arg-float ( -- r ) gforth va_arg_float |
|
r = va_arg_float(clist); |
|
|
|
va-arg-double ( -- r ) gforth va_arg_double |
|
r = va_arg_double(clist); |
|
|
|
va-return-void ( -- ) gforth va_return_void |
|
va_return_void(clist); |
|
return 0; |
|
|
|
va-return-int ( w -- ) gforth va_return_int |
|
va_return_int(clist, w); |
|
return 0; |
|
|
|
va-return-ptr ( c_addr -- ) gforth va_return_ptr |
|
va_return_ptr(clist, void *, c_addr); |
|
return 0; |
|
|
|
va-return-longlong ( d -- ) gforth va_return_longlong |
|
#ifdef BUGGY_LONG_LONG |
|
va_return_longlong(clist, d.lo); |
|
#else |
|
va_return_longlong(clist, d); |
|
#endif |
|
return 0; |
|
|
|
va-return-float ( r -- ) gforth va_return_float |
|
va_return_float(clist, r); |
|
return 0; |
|
|
|
va-return-double ( r -- ) gforth va_return_double |
|
va_return_double(clist, r); |
|
return 0; |
|
|
|
\+ |
|
|
|
\+OLDCALL |
|
|
define(`uploop', |
define(`uploop', |
`pushdef(`$1', `$2')_uploop(`$1', `$2', `$3', `$4', `$5')`'popdef(`$1')') |
`pushdef(`$1', `$2')_uploop(`$1', `$2', `$3', `$4', `$5')`'popdef(`$1')') |
define(`_uploop', |
define(`_uploop', |
Line 2193 rret = (SYSCALL(Float(*)(argdlist($1)))u
|
Line 2648 rret = (SYSCALL(Float(*)(argdlist($1)))u
|
|
|
\ close ' to keep fontify happy |
\ close ' to keep fontify happy |
|
|
open-lib ( c_addr1 u1 -- u2 ) gforth open_lib |
|
#if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) |
|
#ifndef RTLD_GLOBAL |
|
#define RTLD_GLOBAL 0 |
|
#endif |
|
u2=(UCell) dlopen(cstr(c_addr1, u1, 1), RTLD_GLOBAL | RTLD_LAZY); |
|
#else |
|
# ifdef _WIN32 |
|
u2 = (Cell) GetModuleHandle(cstr(c_addr1, u1, 1)); |
|
# else |
|
#warning Define open-lib! |
|
u2 = 0; |
|
# endif |
|
#endif |
|
|
|
lib-sym ( c_addr1 u1 u2 -- u3 ) gforth lib_sym |
|
#if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) |
|
u3 = (UCell) dlsym((void*)u2,cstr(c_addr1, u1, 1)); |
|
#else |
|
# ifdef _WIN32 |
|
u3 = (Cell) GetProcAddress((HMODULE)u2, cstr(c_addr1, u1, 1)); |
|
# else |
|
#warning Define lib-sym! |
|
u3 = 0; |
|
# endif |
|
#endif |
|
|
|
uploop(i, 0, 7, `icall(i)') |
uploop(i, 0, 7, `icall(i)') |
icall(20) |
icall(20) |
uploop(i, 0, 7, `fcall(i)') |
uploop(i, 0, 7, `fcall(i)') |
fcall(20) |
fcall(20) |
|
|
\+ |
\+ |
|
\+ |
|
|
wcall ( u -- ) gforth |
\g peephole |
IF_fpTOS(fp[0]=fpTOS); |
|
FP=fp; |
|
sp=(Cell*)(SYSCALL(Cell*(*)(Cell *, void *))u)(sp, &FP); |
|
fp=FP; |
|
IF_spTOS(spTOS=sp[0];) |
|
IF_fpTOS(fpTOS=fp[0]); |
|
|
|
\+peephole |
\+peephole |
|
|
\g peephole |
|
|
|
compile-prim1 ( a_prim -- ) gforth compile_prim1 |
compile-prim1 ( a_prim -- ) gforth compile_prim1 |
""compile prim (incl. immargs) at @var{a_prim}"" |
""compile prim (incl. immargs) at @var{a_prim}"" |
compile_prim1(a_prim); |
compile_prim1(a_prim); |
Line 2246 compile_prim1(a_prim);
|
Line 2667 compile_prim1(a_prim);
|
finish-code ( -- ) gforth finish_code |
finish-code ( -- ) gforth finish_code |
""Perform delayed steps in code generation (branch resolution, I-cache |
""Perform delayed steps in code generation (branch resolution, I-cache |
flushing)."" |
flushing)."" |
|
IF_spTOS(sp[0]=spTOS); /* workaround for failing to save spTOS |
|
(gcc-2.95.1, gforth-fast --enable-force-reg) */ |
finish_code(); |
finish_code(); |
|
IF_spTOS(spTOS=sp[0]); |
|
|
forget-dyncode ( c_code -- f ) gforth-internal forget_dyncode |
forget-dyncode ( c_code -- f ) gforth-internal forget_dyncode |
f = forget_dyncode(c_code); |
f = forget_dyncode(c_code); |
Line 2273 JUMP(a_callee);
|
Line 2697 JUMP(a_callee);
|
assert(0); |
assert(0); |
#endif |
#endif |
|
|
|
tag-offsets ( -- a_addr ) gforth tag_offsets |
|
extern Cell groups[32]; |
|
a_addr = groups; |
|
|
\+ |
\+ |
|
|
\g static_super |
\g static_super |
|
|
super0 = lit call |
ifdef(`M4_ENGINE_FAST', |
|
`include(peeprules.vmg)') |
include(peeprules.vmg) |
|
|
|
\g end |
\g end |