--- gforth/prim 2003/10/09 14:15:19 1.145 +++ gforth/prim 2004/04/10 10:09:52 1.153 @@ -138,44 +138,7 @@ \ Stack caching setup -\E register IPTOS Cell -\E register spTOS Cell -\E register sp1 Cell -\E register sp2 Cell -\E register sp3 Cell - -\E create IPregs IPTOS , -\E create regs sp2 , sp1 , spTOS , - -\E IPregs 1 0 stack-state IPss1 -\E regs 3 cells + 0 0 stack-state ss0 -\E regs 2 cells + 1 0 stack-state ss1 -\E regs 1 cells + 2 1 stack-state ss2 -\E regs 0 cells + 3 2 stack-state ss3 - -\ the first of these is the default state -\E state S0 -\E state S1 -\E state S2 -\E state S3 - -\E ss0 data-stack S0 set-ss -\E ss1 data-stack S1 set-ss -\E ss2 data-stack S2 set-ss -\E ss3 data-stack S3 set-ss - -\E IPss1 inst-stream S0 set-ss -\E IPss1 inst-stream S1 set-ss -\E IPss1 inst-stream S2 set-ss -\E IPss1 inst-stream S3 set-ss - -\E data-stack to cache-stack -\E here 4 cache-states 2! s0 , s1 , s2 , s3 , - -\ !! the following should be automatic -\E S0 to state-default -\E state-default to state-in -\E state-default to state-out +ifdef(`M4_ENGINE_FAST', `include(cache1.vmg)', `include(cache0.vmg)') \ these m4 macros would collide with identifiers undefine(`index') @@ -189,36 +152,67 @@ undefine(`symbols') (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 */ EXEC(*(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, @@ -235,6 +229,7 @@ noop ( -- ) gforth call ( #a_callee -- R:a_retaddr ) new ""Call callee (a variant of docol with inline argument)."" #ifdef NO_IP +assert(0); INST_TAIL; JUMP(a_callee); #else @@ -254,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); @@ -264,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); : @@ -329,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 ; @@ -438,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 @@ -468,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 */ ,) \+ @@ -2358,7 +2357,11 @@ av-double ( r -- ) gforth av_double av_double(alist, r); av-longlong ( d -- ) gforth av_longlong +#ifdef BUGGY_LONG_LONG +av_longlong(alist, d.lo); +#else av_longlong(alist, d); +#endif av-ptr ( c_addr -- ) gforth av_ptr av_ptr(alist, void*, c_addr); @@ -2377,7 +2380,11 @@ lp += sizeof(Float); av_double(alist, r); av-longlong-r ( R:d -- ) gforth av_longlong_r +#ifdef BUGGY_LONG_LONG +av_longlong(alist, d.lo); +#else av_longlong(alist, d); +#endif av-ptr-r ( R:c_addr -- ) gforth av_ptr_r av_ptr(alist, void*, c_addr); @@ -2409,7 +2416,12 @@ av-call-longlong ( -- d ) gforth av_cal SAVE_REGS av_call(alist); REST_REGS +#ifdef BUGGY_LONG_LONG +d.lo = llrv; +d.hi = 0; +#else d = llrv; +#endif av-call-ptr ( -- c_addr ) gforth av_call_ptr SAVE_REGS @@ -2442,7 +2454,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 +d.lo = va_arg_longlong(clist); +d.hi = 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*); @@ -2466,7 +2483,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 @@ -2531,7 +2552,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); @@ -2566,10 +2590,7 @@ a_addr = groups; \g static_super -\C #if !defined(GFORTH_DEBUGGING) && !defined(INDIRECT_THREADED) && !defined(DOUBLY_INDIRECT) && !defined(VM_PROFILING) - -include(peeprules.vmg) - -\C #endif +ifdef(`M4_ENGINE_FAST', +`include(peeprules.vmg)') \g end