Diff for /gforth/prim between versions 1.139 and 1.170

version 1.139, 2003/08/20 09:23:45 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  \ run-time routines for non-primitives.  They are defined as
 \ primitives, because that simplifies things.  \ primitives, because that simplifies things.
   
 (docol) ( -- R:a_retaddr )      gforth-internal paren_docol  (docol) ( -- R:a_retaddr )      gforth-internal paren_docol
 ""run-time routine for colon definitions""  ""run-time routine for colon definitions""
 a_retaddr = (Cell *)ip;  #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));  SET_IP((Xt *)PFA(CFA));
   #endif /* !defined(NO_IP) */
   
 (docon) ( -- w )        gforth-internal paren_docon  (docon) ( -- w )        gforth-internal paren_docon
 ""run-time routine for constants""  ""run-time routine for constants""
 w = *(Cell *)PFA(CFA);  w = *(Cell *)PFA(CFA);
   #ifdef NO_IP
   INST_TAIL;
   goto *next_code;
   #endif /* defined(NO_IP) */
   
 (dovar) ( -- a_body )   gforth-internal paren_dovar  (dovar) ( -- a_body )   gforth-internal paren_dovar
 ""run-time routine for variables and CREATEd words""  ""run-time routine for variables and CREATEd words""
 a_body = PFA(CFA);  a_body = PFA(CFA);
   #ifdef NO_IP
   INST_TAIL;
   goto *next_code;
   #endif /* defined(NO_IP) */
   
 (douser) ( -- a_user )  gforth-internal paren_douser  (douser) ( -- a_user )  gforth-internal paren_douser
 ""run-time routine for constants""  ""run-time routine for constants""
 a_user = (Cell *)(up+*(Cell *)PFA(CFA));  a_user = (Cell *)(up+*(Cell *)PFA(CFA));
   #ifdef NO_IP
   INST_TAIL;
   goto *next_code;
   #endif /* defined(NO_IP) */
   
 (dodefer) ( -- )        gforth-internal paren_dodefer  (dodefer) ( -- )        gforth-internal paren_dodefer
 ""run-time routine for deferred words""  ""run-time routine for deferred words""
 SUPER_END;  #ifndef NO_IP
 EXEC(*(Xt *)PFA(CFA));  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  (dofield) ( n1 -- n2 )  gforth-internal paren_field
 ""run-time routine for fields""  ""run-time routine for fields""
 n2 = n1 + *(Cell *)PFA(CFA);  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  (dodoes) ( -- a_body R:a_retaddr )      gforth-internal paren_dodoes
 ""run-time routine for @code{does>}-defined words""  ""run-time routine for @code{does>}-defined words""
 a_retaddr = (Cell *)ip;  #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);  a_body = PFA(CFA);
 SET_IP(DOES_CODE1(CFA));  SET_IP(DOES_CODE1(CFA));
   #endif /* !defined(NO_IP) */
   
 (does-handler) ( -- )   gforth-internal paren_does_handler  (does-handler) ( -- )   gforth-internal paren_does_handler
 ""just a slot to have an encoding for the DOESJUMP,   ""just a slot to have an encoding for the DOESJUMP, 
 which is no longer used anyway (!! eliminate this)""  which is no longer used anyway (!! eliminate this)""
   
   \F [endif]
   
 \g control  \g control
   
 noop    ( -- )          gforth  noop    ( -- )          gforth
Line 189  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 208  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 218  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 243  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 289  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 298  $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 392  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 422  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 446  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 469  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 492  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 515  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 538  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 633  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 738  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 771  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 793  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 814  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 826  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;
Line 842  ud = (UDCell)u1 * (UDCell)u2; Line 980  ud = (UDCell)u1 * (UDCell)u2;
   
 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 861  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 871  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 881  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 892  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 902  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 914  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 942  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 1011  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 1391  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 1536  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 1791  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 1833  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 1850  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 1981  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 2262  u3 = 0; Line 2434  u3 = 0;
 #  endif  #  endif
 #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  \+FFCALL
   
 av-start-void   ( c_addr -- )   gforth  av_start_void  av-start-void   ( c_addr -- )   gforth  av_start_void
Line 2292  av-double ( r -- ) gforth  av_double Line 2472  av-double ( r -- ) gforth  av_double
 av_double(alist, r);  av_double(alist, r);
   
 av-longlong     ( d -- )        gforth  av_longlong  av-longlong     ( d -- )        gforth  av_longlong
   #ifdef BUGGY_LL_SIZE
   av_longlong(alist, DLO(d));
   #else
 av_longlong(alist, d);  av_longlong(alist, d);
   #endif
   
 av-ptr  ( c_addr -- )   gforth  av_ptr  av-ptr  ( c_addr -- )   gforth  av_ptr
 av_ptr(alist, void*, c_addr);  av_ptr(alist, void*, c_addr);
Line 2311  lp += sizeof(Float); Line 2495  lp += sizeof(Float);
 av_double(alist, r);  av_double(alist, r);
   
 av-longlong-r   ( R:d -- )      gforth  av_longlong_r  av-longlong-r   ( R:d -- )      gforth  av_longlong_r
   #ifdef BUGGY_LL_SIZE
   av_longlong(alist, DLO(d));
   #else
 av_longlong(alist, d);  av_longlong(alist, d);
   #endif
   
 av-ptr-r        ( R:c_addr -- ) gforth  av_ptr_r  av-ptr-r        ( R:c_addr -- ) gforth  av_ptr_r
 av_ptr(alist, void*, c_addr);  av_ptr(alist, void*, c_addr);
Line 2343  av-call-longlong ( -- d ) gforth  av_cal Line 2531  av-call-longlong ( -- d ) gforth  av_cal
 SAVE_REGS  SAVE_REGS
 av_call(alist);  av_call(alist);
 REST_REGS  REST_REGS
   #ifdef BUGGY_LONG_LONG
   DLO_IS(d, llrv);
   DHI_IS(d, 0);
   #else
 d = llrv;  d = llrv;
   #endif
   
 av-call-ptr     ( -- c_addr )   gforth  av_call_ptr  av-call-ptr     ( -- c_addr )   gforth  av_call_ptr
 SAVE_REGS  SAVE_REGS
Line 2376  va-arg-int ( -- w ) gforth va_arg_int Line 2569  va-arg-int ( -- w ) gforth va_arg_int
 w = va_arg_int(clist);  w = va_arg_int(clist);
   
 va-arg-longlong ( -- d )        gforth  va_arg_longlong  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);  d = va_arg_longlong(clist);
   #endif
   
 va-arg-ptr      ( -- c_addr )   gforth  va_arg_ptr  va-arg-ptr      ( -- c_addr )   gforth  va_arg_ptr
 c_addr = (char *)va_arg_ptr(clist,char*);  c_addr = (char *)va_arg_ptr(clist,char*);
Line 2400  va_return_ptr(clist, void *, c_addr); Line 2598  va_return_ptr(clist, void *, c_addr);
 return 0;  return 0;
   
 va-return-longlong ( d -- )     gforth va_return_longlong  va-return-longlong ( d -- )     gforth va_return_longlong
   #ifdef BUGGY_LONG_LONG
   va_return_longlong(clist, d.lo);
   #else
 va_return_longlong(clist, d);  va_return_longlong(clist, d);
   #endif
 return 0;  return 0;
   
 va-return-float ( r -- )        gforth va_return_float  va-return-float ( r -- )        gforth va_return_float
Line 2411  va-return-double ( r -- ) gforth va_retu Line 2613  va-return-double ( r -- ) gforth va_retu
 va_return_double(clist, r);  va_return_double(clist, r);
 return 0;  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')')
Line 2452  fcall(20) Line 2656  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 2471  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 2506  a_addr = groups; Line 2705  a_addr = groups;
   
 \g static_super  \g static_super
   
 \C #if !defined(GFORTH_DEBUGGING) && !defined(INDIRECT_THREADED) && !defined(DOUBLY_INDIRECT) && !defined(VM_PROFILING)  ifdef(`M4_ENGINE_FAST',
   `include(peeprules.vmg)')
 include(peeprules.vmg)  
   
 \C #endif  
   
 \g end  \g end

Removed from v.1.139  
changed lines
  Added in v.1.170


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>