--- gforth/prim 2003/11/06 09:47:49 1.148 +++ gforth/prim 2005/01/19 22:11:52 1.158 @@ -1,6 +1,6 @@ \ 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. @@ -249,7 +249,7 @@ execute ( xt -- ) core #ifndef NO_IP ip=IP; #endif -IF_spTOS(spTOS = sp[0]); +IF_spTOS(spTOS = sp[0]); /* inst_tail would produce a NEXT_P1 */ SUPER_END; EXEC(xt); @@ -259,7 +259,7 @@ perform ( a_addr -- ) gforth #ifndef NO_IP ip=IP; #endif -IF_spTOS(spTOS = sp[0]); +IF_spTOS(spTOS = sp[0]); /* inst_tail would produce a NEXT_P1 */ SUPER_END; EXEC(*(Xt *)a_addr); : @@ -324,7 +324,10 @@ INST_TAIL; JUMP(a_target); #else SET_IP((Xt *)a_target); +INST_TAIL; +NEXT_P2; #endif +SUPER_CONTINUE; /* we do our own control flow, so don't append NEXT etc. */ : r> @ >r ; @@ -433,8 +436,9 @@ condbranch((+loop),n R:nlimit R:n1 -- R: /* dependent upon two's complement arithmetic */ Cell olddiff = n1-nlimit; n2=n1+n; -,if ((olddiff^(olddiff+n))>=0 /* the limit is not crossed */ - || (olddiff^n)>=0 /* it is a wrap-around effect */) { +,if (((olddiff^(olddiff+n)) /* the limit is not crossed */ + &(olddiff^n)) /* OR it is a wrap-around effect */ + >=0) { /* & is used to avoid having two branches for gforth-native */ ,: r> swap r> r> 2dup - >r @@ -463,7 +467,7 @@ if (n<0) { newdiff = -newdiff; } n2=n1+n; -,if (diff>=0 || newdiff<0) { +,if (((~diff)|newdiff)<0) { /* use | to avoid two branches for gforth-native */ ,) \+ @@ -816,7 +820,7 @@ n2 = n1>>1; 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}."" -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_DIV DCell r = fmdiv(d1,n1); n2=r.hi; n3=r.lo; @@ -838,7 +842,7 @@ if (1%-3>0 && (d1<0) != (n1<0) && n2!=0) 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."" -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_DIV DCell r = smdiv(d1,n1); n2=r.hi; n3=r.lo; @@ -859,7 +863,7 @@ if (1%-3<0 && (d1<0) != (n1<0) && n2!=0) r> 0< IF swap negate swap THEN ; m* ( n1 n2 -- d ) core m_star -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_MUL d = mmul(n1,n2); #else d = (DCell)n1 * (DCell)n2; @@ -871,7 +875,7 @@ d = (DCell)n1 * (DCell)n2; um* ( u1 u2 -- ud ) core u_m_star /* use u* as alias */ -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_MUL ud = ummul(u1,u2); #else ud = (UDCell)u1 * (UDCell)u2; @@ -887,7 +891,7 @@ ud = (UDCell)u1 * (UDCell)u2; um/mod ( ud u1 -- u2 u3 ) core u_m_slash_mod ""ud=u3*u1+u2, u1>u2>=0"" -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_DIV UDCell r = umdiv(ud,u1); u2=r.hi; u3=r.lo; @@ -906,9 +910,9 @@ u2 = ud%u1; and >r >r 2dup d+ swap r> + swap r> ; m+ ( d1 n -- d2 ) double m_plus -#ifdef BUGGY_LONG_LONG -d2.lo = d1.lo+n; -d2.hi = d1.hi - (n<0) + (d2.lod d+ ; d+ ( d1 d2 -- d ) double d_plus -#ifdef BUGGY_LONG_LONG -d.lo = d1.lo+d2.lo; -d.hi = d1.hi + d2.hi + (d.lor tuck + swap over u> r> swap - ; d- ( d1 d2 -- d ) double d_minus -#ifdef BUGGY_LONG_LONG -d.lo = d1.lo - d2.lo; -d.hi = d1.hi-d2.hi-(d1.lo>(CELL_BITS-1)); +#ifdef BUGGY_LL_SHIFT +DLO_IS(d2, DLO(d1)<<1); +DHI_IS(d2, (DHI(d1)<<1) | (DLO(d1)>>(CELL_BITS-1))); #else d2 = 2*d1; #endif @@ -959,9 +963,9 @@ d2 = 2*d1; d2/ ( d1 -- d2 ) double d_two_slash ""Arithmetic shift right by 1. For signed numbers this is a floored division by 2."" -#ifdef BUGGY_LONG_LONG -d2.hi = d1.hi>>1; -d2.lo= (d1.lo>>1) | (d1.hi<<(CELL_BITS-1)); +#ifdef BUGGY_LL_SHIFT +DHI_IS(d2, DHI(d1)>>1); +DLO_IS(d2, (DLO(d1)>>1) | (DHI(d1)<<(CELL_BITS-1))); #else d2 = d1>>1; #endif @@ -987,12 +991,20 @@ w2 = ~w1; rshift ( u1 n -- u2 ) core r_shift ""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 ; lshift ( u1 n -- u2 ) core l_shift - u2 = u1< ( \$2 -- f ) \$7 \$3not_equals -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_CMP f = FLAG(\$4.lo!=\$5.lo || \$4.hi!=\$5.hi); #else f = FLAG(\$4!=\$5); #endif \$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); #else f = FLAG(\$4<\$5); #endif \$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); #else f = FLAG(\$4>\$5); #endif \$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); #else f = FLAG(\$4<=\$5); #endif \$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); #else f = FLAG(\$4>=\$5); @@ -1589,16 +1601,8 @@ SUPER_END; return (Label *)n; (system) ( c_addr u -- wretval wior ) gforth paren_system -#ifndef MSDOS -int old_tp=terminal_prepped; -deprep_terminal(); -#endif -wretval=system(cstr(c_addr,u,1)); /* ~ expansion on first part of string? */ +wretval = gforth_system(c_addr, u); wior = IOR(wretval==-1 || (wretval==127 && errno != 0)); -#ifndef MSDOS -if (old_tp) - prep_terminal(); -#endif getenv ( c_addr1 u1 -- c_addr2 u2 ) gforth ""The string @i{c-addr1 u1} specifies an environment variable. The string @i{c-addr2 u2} @@ -1844,6 +1848,21 @@ char * string = cstr(c_addr1, u1, 1); char * pattern = cstr(c_addr2, u2, 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 @@ -1886,11 +1905,7 @@ dsystem = timeval2us(&usage.ru_stime); struct timeval time1; gettimeofday(&time1,NULL); duser = timeval2us(&time1); -#ifndef BUGGY_LONG_LONG -dsystem = (DCell)0; -#else -dsystem=(DCell){0,0}; -#endif +dsystem = DZERO; #endif \+ @@ -1903,13 +1918,17 @@ comparisons(f, r1 r2, f_, r1, r2, gforth comparisons(f0, r, f_zero_, r, 0., float, gforth, float, gforth) d>f ( d -- r ) float d_to_f -#ifdef BUGGY_LONG_LONG +#ifdef BUGGY_LL_D2F extern double ldexp(double x, int exp); -if (d.hi<0) { +if (DHI(d)<0) { +#ifdef BUGGY_LL_ADD 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 - r = ldexp((Float)d.hi,CELL_BITS) + (Float)d.lo; + r = ldexp((Float)DHI(d),CELL_BITS) + (Float)DLO(d); #else r = d; #endif @@ -2353,7 +2372,11 @@ 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); @@ -2372,7 +2395,11 @@ 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); @@ -2404,7 +2431,12 @@ av-call-longlong ( -- d ) gforth av_cal 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 @@ -2437,7 +2469,12 @@ 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*); @@ -2461,7 +2498,11 @@ 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 @@ -2526,7 +2567,10 @@ compile_prim1(a_prim); finish-code ( -- ) gforth finish_code ""Perform delayed steps in code generation (branch resolution, I-cache flushing)."" +IF_spTOS(sp[0]=spTOS); /* workaround for failing to save spTOS + (gcc-2.95.1, gforth-fast --enable-force-reg) */ finish_code(); +IF_spTOS(spTOS=sp[0]); forget-dyncode ( c_code -- f ) gforth-internal forget_dyncode f = forget_dyncode(c_code);