version 1.16, 2002/11/24 13:54:02
|
version 1.19, 2003/01/02 21:40:22
|
Line 91
|
Line 91
|
|
|
*/ |
*/ |
|
|
|
|
|
|
#ifdef DOUBLY_INDIRECT |
#ifdef DOUBLY_INDIRECT |
|
# ifndef DEBUG_DITC |
|
# define DEBUG_DITC 0 |
|
# endif |
|
/* define to 1 if you want to check consistency */ |
# define NEXT_P0 ({cfa=*ip;}) |
# define NEXT_P0 ({cfa=*ip;}) |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 101
|
Line 103
|
# define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);}) |
# define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);}) |
# define DEF_CA Label ca; |
# define DEF_CA Label ca; |
# define NEXT_P1 ({\ |
# define NEXT_P1 ({\ |
if (cfa<=vm_prims+DOESJUMP || cfa>=vm_prims+npriminfos) \ |
if (DEBUG_DITC && (cfa<=vm_prims+DOESJUMP || cfa>=vm_prims+npriminfos)) \ |
fprintf(stderr,"NEXT encountered prim %p at ip=%p\n", cfa, ip); \ |
fprintf(stderr,"NEXT encountered prim %p at ip=%p\n", cfa, ip); \ |
ip++; ca=**cfa;}) |
ip++; ca=**cfa;}) |
# define NEXT_P2 ({goto *ca;}) |
# define NEXT_P2 ({goto *ca;}) |
# define EXEC(XT) ({DEF_CA cfa=(XT);\ |
# define EXEC(XT) ({DEF_CA cfa=(XT);\ |
if (cfa>vm_prims+DOESJUMP && cfa<vm_prims+npriminfos) \ |
if (DEBUG_DITC && (cfa>vm_prims+DOESJUMP && cfa<vm_prims+npriminfos)) \ |
fprintf(stderr,"EXEC encountered xt %p at ip=%p, vm_prims=%p, xts=%p\n", cfa, ip, vm_prims, xts); \ |
fprintf(stderr,"EXEC encountered xt %p at ip=%p, vm_prims=%p, xts=%p\n", cfa, ip, vm_prims, xts); \ |
ca=**cfa; goto *ca;}) |
ca=**cfa; goto *ca;}) |
|
|
Line 125
|
Line 127
|
|
|
#if defined(DIRECT_THREADED) |
#if defined(DIRECT_THREADED) |
|
|
|
/* This lets the compiler know that cfa is dead before; we place it at |
|
"goto *"s that perform direct threaded dispatch (i.e., not EXECUTE |
|
etc.), and thus do not reach doers, which would use cfa; the only |
|
way to a doer is through EXECUTE etc., which set the cfa |
|
themselves. |
|
|
|
Some of these direct threaded schemes use "cfa" to hold the code |
|
address in normal direct threaded code. Of course we cannot use |
|
KILLS there. |
|
|
|
KILLS works by having an empty asm instruction, and claiming to the |
|
compiler that it writes to cfa. |
|
|
|
KILLS is optional. You can write |
|
|
|
#define KILLS |
|
|
|
and lose just a little performance. |
|
*/ |
|
#define KILLS asm("":"=X"(cfa)); |
|
|
#if THREADING_SCHEME==1 |
#if THREADING_SCHEME==1 |
#warning direct threading scheme 1: autoinc, long latency, cfa live |
#warning direct threading scheme 1: autoinc, long latency, cfa live |
# define NEXT_P0 ({cfa=*ip++;}) |
# define NEXT_P0 ({cfa=*ip++;}) |
Line 147
|
Line 170
|
# define INC_IP(const_inc) ({ ip+=(const_inc);}) |
# define INC_IP(const_inc) ({ ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 |
# define NEXT_P1 |
# define NEXT_P2 ({goto **(ip-1);}) |
# define NEXT_P2 ({KILLS goto **(ip-1);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
Line 174
|
Line 197
|
# define INC_IP(const_inc) ({ ip+=(const_inc);}) |
# define INC_IP(const_inc) ({ ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 |
# define NEXT_P1 |
# define NEXT_P2 ({goto **(ip++);}) |
# define NEXT_P2 ({KILLS goto **(ip++);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
Line 200
|
Line 223
|
# define INC_IP(const_inc) ({ip+=(const_inc);}) |
# define INC_IP(const_inc) ({ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 (ip++) |
# define NEXT_P1 (ip++) |
# define NEXT_P2 ({goto **(ip-1);}) |
# define NEXT_P2 ({KILLS goto **(ip-1);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
Line 227
|
Line 250
|
# define INC_IP(const_inc) ({ ip+=(const_inc);}) |
# define INC_IP(const_inc) ({ ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 (ip++) |
# define NEXT_P1 (ip++) |
# define NEXT_P2 ({goto **(ip-1);}) |
# define NEXT_P2 ({KILLS goto **(ip-1);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|