--- gforth/engine/engine.c 2001/02/06 16:53:07 1.26 +++ gforth/engine/engine.c 2002/01/14 08:40:24 1.38 @@ -19,7 +19,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. */ +undefine(`symbols') + #include "config.h" +#include "forth.h" #include #include #include @@ -27,7 +30,6 @@ #include #include #include -#include "forth.h" #include "io.h" #include "threaded.h" #ifndef STANDALONE @@ -196,6 +198,7 @@ DCell timeval2us(struct timeval *tvp) #ifdef HAS_FILE static char* fileattr[6]={"rb","rb","r+b","r+b","wb","wb"}; +static char* pfileattr[6]={"r","r","r+","r+","w","w"}; #ifndef O_BINARY #define O_BINARY 0 @@ -244,6 +247,8 @@ static int ufileattr[6]= { #define vm_longname2Cell(x) ((Cell)(x)) #define vm_r2Float(x) (x) +#define vm_Cell2Cell(x) (x) + /* if machine.h has not defined explicit registers, define them as implicit */ #ifndef IPREG #define IPREG @@ -285,6 +290,20 @@ static int ufileattr[6]= { #define DOCFA Xt cfa; GETCFA(cfa) #endif +/* instructions containing these must be the last instruction of a + super-instruction (e.g., branches, EXECUTE, and other instructions + ending the basic block). Instructions containing SET_IP get this + automatically, so you usually don't have to write it. If you have + to write it, write it after IP points to the next instruction. + Used for profiling. Don't write it in a word containing SET_IP, or + the following block will be counted twice. */ +#ifdef VM_PROFILING +#define SUPER_END vm_count_block(IP) +#else +#define SUPER_END +#endif +#define SUPER_CONTINUE + #ifdef GFORTH_DEBUGGING /* define some VM registers as global variables, so they survive exceptions; global register variables are not up to the task (according to the @@ -293,7 +312,37 @@ Xt *ip; Cell *rp; #endif -Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0) +#ifdef DEBUG +#define CFA_TO_NAME(__cfa) \ + Cell len, i; \ + char * name = __cfa; \ + for(i=0; i<32; i+=sizeof(Cell)) { \ + len = ((Cell*)name)[-1]; \ + if(len < 0) { \ + len &= 0x1F; \ + if((len+sizeof(Cell)) > i) break; \ + } len = 0; \ + name -= sizeof(Cell); \ + } +#endif + +Xt *primtable(Label symbols[], Cell size) +{ +#ifdef DIRECT_THREADED + return symbols; +#else /* !defined(DIRECT_THREADED) */ + Xt *xts = (Xt *)malloc(size*sizeof(Xt)); + Cell i; + + for (i=0; i=MAX_SYMBOLS) { fprintf(stderr,"gforth-ditc: more than %d primitives\n",MAX_SYMBOLS); exit(1); } - symbols[i] = &routines[i]; + xts[i] = symbols[i] = &routines[i]; } #endif /* defined(DOUBLY_INDIRECT) */ return symbols; @@ -370,6 +431,7 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * IF_fpTOS(fpTOS = fp[0]); /* prep_terminal(); */ SET_IP(ip); + SUPER_END; /* count the first block, too */ NEXT; @@ -381,12 +443,17 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * { DOCFA; #ifdef DEBUG - fprintf(stderr,"%08lx: col: %08lx\n",(Cell)ip,(Cell)PFA1(cfa)); + { + CFA_TO_NAME(cfa); + fprintf(stderr,"%08lx: col: %08lx %.*s\n",(Cell)ip,(Cell)PFA1(cfa), + len,name); + } #endif #ifdef CISC_NEXT /* this is the simple version */ *--rp = (Cell)ip; SET_IP((Xt *)PFA1(cfa)); + SUPER_END; NEXT; #else /* this one is important, so we help the compiler optimizing */ @@ -394,6 +461,7 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * DEF_CA rp[-1] = (Cell)ip; SET_IP((Xt *)PFA1(cfa)); + SUPER_END; NEXT_P1; rp--; NEXT_P2; @@ -455,6 +523,7 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * #ifdef DEBUG fprintf(stderr,"%08lx: defer: %08lx\n",(Cell)ip,*(Cell*)PFA1(cfa)); #endif + SUPER_END; EXEC(*(Xt *)PFA1(cfa)); } @@ -504,9 +573,25 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * *--sp = (Cell)PFA(cfa); #endif SET_IP(DOES_CODE1(cfa)); + SUPER_END; /* fprintf(stderr,"TOS = %08lx, IP=%08lx\n", spTOS, IP);*/ } NEXT; +#ifndef IN_ENGINE2 +#define LABEL(name) I_##name +#else +#define LABEL(name) J_##name: asm(".skip 16"); I_##name +#endif #include "prim.i" -} +#undef LABEL + after_last: return (Label *)0; + /*needed only to get the length of the last primitive */ +}' +) + +Label *engine enginerest + +#define IN_ENGINE2 +Label *engine2 enginerest +