--- gforth/prim 2003/11/02 22:15:28 1.147 +++ gforth/prim 2004/04/10 10:09:52 1.153 @@ -152,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, @@ -198,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 @@ -217,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); @@ -227,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); : @@ -292,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 ; @@ -401,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 @@ -431,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 */ ,) \+ @@ -2321,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); @@ -2340,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); @@ -2372,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 @@ -2405,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*); @@ -2429,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 @@ -2494,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);