version 1.5, 1999/05/14 20:55:14
|
version 1.21, 2003/01/07 22:38:36
|
Line 1
|
Line 1
|
/* This file defines a number of threading schemes. |
/* This file defines a number of threading schemes. |
|
|
Copyright (C) 1995, 1996,1997 Free Software Foundation, Inc. |
Copyright (C) 1995, 1996,1997,1999 Free Software Foundation, Inc. |
|
|
This file is part of Gforth. |
This file is part of Gforth. |
|
|
Line 16
|
Line 16
|
|
|
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
|
|
|
|
This files defines macros for threading. Many sets of macros are |
This files defines macros for threading. Many sets of macros are |
Line 91
|
Line 91
|
|
|
*/ |
*/ |
|
|
/* CFA_NEXT: if NEXT uses cfa, you have to #define CFA_NEXT, to get |
|
* cfa declared in engine. |
|
*/ |
|
|
|
#ifdef DOUBLY_INDIRECT |
#ifdef DOUBLY_INDIRECT |
# define CFA_NEXT |
# 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;}) |
# define NEXT_INST (cfa) |
# define NEXT_INST (cfa) |
# 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 ({ip++; ca=**cfa;}) |
# define NEXT_P1 ({\ |
# define NEXT_P2 ({goto *ca;}) |
if (DEBUG_DITC && (cfa<=vm_prims+DOESJUMP || cfa>=vm_prims+npriminfos)) \ |
# define EXEC(XT) ({DEF_CA cfa=(XT); ca=**cfa; goto *ca;}) |
fprintf(stderr,"NEXT encountered prim %p at ip=%p\n", cfa, ip); \ |
# define NEXT1_P1 ({ca = **cfa;}) |
ip++;}) |
# define NEXT1_P2 ({goto *ca;}) |
# define NEXT_P2 ({ca=**cfa; goto *ca;}) |
|
# define EXEC(XT) ({DEF_CA cfa=(XT);\ |
|
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); \ |
|
ca=**cfa; goto *ca;}) |
|
|
|
#elif defined(NO_IP) |
|
|
|
#define NEXT_P0 |
|
#define SET_IP(target) assert(0) |
|
#define INC_IP(n) ((void)0) |
|
#define DEF_CA |
|
#define NEXT_P1 |
|
#define NEXT_P2 ({goto *next_code;}) |
|
/* set next_code to the return address before performing EXEC */ |
|
#define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
|
|
#else /* !defined(DOUBLY_INDIRECT) */ |
#else /* !defined(DOUBLY_INDIRECT) && !defined(NO_IP) */ |
|
|
#if defined(DIRECT_THREADED) |
#if defined(DIRECT_THREADED) |
|
|
/* note that the "cfa dead" versions only work if GETCFA exists and works */ |
/* 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)); |
|
|
|
#ifndef THREADING_SCHEME |
|
#define THREADING_SCHEME 6 |
|
#endif |
|
|
#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 CFA_NEXT |
|
# define NEXT_P0 ({cfa=*ip++;}) |
# define NEXT_P0 ({cfa=*ip++;}) |
# define IP (ip-1) |
# define IP (ip-1) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 126
|
Line 162
|
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 |
# define NEXT_P1 |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==2 |
#if THREADING_SCHEME==2 |
#warning direct threading scheme 2: autoinc, long latency, cfa dead |
#warning direct threading scheme 2: autoinc, long latency, cfa dead |
#ifndef GETCFA |
|
#error GETCFA must be defined for cfa dead threading |
|
#endif |
|
# define NEXT_P0 (ip++) |
# define NEXT_P0 (ip++) |
# define IP (ip-1) |
# define IP (ip-1) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 141
|
Line 174
|
# 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) ({goto *(XT);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
|
|
#if THREADING_SCHEME==3 |
#if THREADING_SCHEME==3 |
#warning direct threading scheme 3: autoinc, low latency, cfa live |
#warning direct threading scheme 3: autoinc, low latency, cfa live |
# define CFA_NEXT |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 157
|
Line 189
|
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 ({cfa=*ip++;}) |
# define NEXT_P1 ({cfa=*ip++;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==4 |
#if THREADING_SCHEME==4 |
#warning direct threading scheme 4: autoinc, low latency, cfa dead |
#warning direct threading scheme 4: autoinc, low latency, cfa dead |
#ifndef GETCFA |
|
#error GETCFA must be defined for cfa dead threading |
|
#endif |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 172
|
Line 201
|
# 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) ({goto *(XT);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==5 |
#if THREADING_SCHEME==5 |
#warning direct threading scheme 5: long latency, cfa live |
#warning direct threading scheme 5: long latency, cfa live |
# define CFA_NEXT |
|
# 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 187
|
Line 215
|
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 (ip++) |
# define NEXT_P1 (ip++) |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==6 |
#if THREADING_SCHEME==6 |
#warning direct threading scheme 6: long latency, cfa dead |
#warning direct threading scheme 6: long latency, cfa dead |
#ifndef GETCFA |
|
#error GETCFA must be defined for cfa dead threading |
|
#endif |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 202
|
Line 227
|
# 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) ({goto *(XT);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
|
|
#if THREADING_SCHEME==7 |
#if THREADING_SCHEME==7 |
#warning direct threading scheme 7: low latency, cfa live |
#warning direct threading scheme 7: low latency, cfa live |
# define CFA_NEXT |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 218
|
Line 242
|
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 ({cfa=*ip++;}) |
# define NEXT_P1 ({cfa=*ip++;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==8 |
#if THREADING_SCHEME==8 |
#warning direct threading scheme 8: cfa dead, i386 hack |
#warning direct threading scheme 8: cfa dead, i386 hack |
#ifndef GETCFA |
|
#error GETCFA must be defined for cfa dead threading |
|
#endif |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 233
|
Line 254
|
# 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) ({goto *(XT);}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==9 |
#if THREADING_SCHEME==9 |
Line 242
|
Line 263
|
/* Power uses a prepare-to-branch instruction, and the latency between |
/* Power uses a prepare-to-branch instruction, and the latency between |
this inst and the branch is 5 cycles on a PPC604; so we utilize this |
this inst and the branch is 5 cycles on a PPC604; so we utilize this |
to do some prefetching in between */ |
to do some prefetching in between */ |
# define CFA_NEXT |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP ip |
# define IP ip |
# define SET_IP(p) ({ip=(p); next_cfa=*ip; NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); next_cfa=*ip; NEXT_P0;}) |
# define NEXT_INST (next_cfa) |
# define NEXT_INST (next_cfa) |
# define INC_IP(const_inc) ({next_cfa=IP[const_inc]; ip+=(const_inc);}) |
# define INC_IP(const_inc) ({next_cfa=IP[const_inc]; ip+=(const_inc);}) |
# define DEF_CA Label ca; |
# define DEF_CA |
# define NEXT_P1 ({ca=next_cfa; cfa=next_cfa; ip++; next_cfa=*ip;}) |
# define NEXT_P1 ({cfa=next_cfa; ip++; next_cfa=*ip;}) |
# define NEXT_P2 ({goto *ca;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
# define MORE_VARS Xt next_cfa; |
# define MORE_VARS Xt next_cfa; |
#endif |
#endif |
|
|
#if THREADING_SCHEME==10 |
#if THREADING_SCHEME==10 |
#warning direct threading scheme 10: plain (no attempt at scheduling) |
#warning direct threading scheme 10: plain (no attempt at scheduling) |
# define CFA_NEXT |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 266
|
Line 285
|
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 |
# define NEXT_P1 |
# define NEXT_P2 ({cfa=*ip++; goto *cfa;}) |
# define NEXT_P2 ({cfa=*ip++; goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto *cfa;}) |
# define EXEC(XT) ({cfa=(XT); goto **cfa;}) |
#endif |
#endif |
|
|
/* direct threaded */ |
/* direct threaded */ |
#else |
#else |
/* indirect THREADED */ |
/* indirect THREADED */ |
|
|
|
#ifndef THREADING_SCHEME |
|
#define THREADING_SCHEME 6 |
|
#endif |
|
|
#if THREADING_SCHEME==1 |
#if THREADING_SCHEME==1 |
#warning indirect threading scheme 1: autoinc, long latency, cisc |
#warning indirect threading scheme 1: autoinc, long latency, cisc |
# define CFA_NEXT |
|
# define NEXT_P0 ({cfa=*ip++;}) |
# define NEXT_P0 ({cfa=*ip++;}) |
# define IP (ip-1) |
# define IP (ip-1) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 289
|
Line 311
|
|
|
#if THREADING_SCHEME==2 |
#if THREADING_SCHEME==2 |
#warning indirect threading scheme 2: autoinc, long latency |
#warning indirect threading scheme 2: autoinc, long latency |
# define CFA_NEXT |
|
# define NEXT_P0 ({cfa=*ip++;}) |
# define NEXT_P0 ({cfa=*ip++;}) |
# define IP (ip-1) |
# define IP (ip-1) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 304
|
Line 325
|
|
|
#if THREADING_SCHEME==3 |
#if THREADING_SCHEME==3 |
#warning indirect threading scheme 3: autoinc, low latency, cisc |
#warning indirect threading scheme 3: autoinc, low latency, cisc |
# define CFA_NEXT |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 318
|
Line 338
|
|
|
#if THREADING_SCHEME==4 |
#if THREADING_SCHEME==4 |
#warning indirect threading scheme 4: autoinc, low latency |
#warning indirect threading scheme 4: autoinc, low latency |
# define CFA_NEXT |
|
# define NEXT_P0 ({cfa=*ip++;}) |
# define NEXT_P0 ({cfa=*ip++;}) |
# define IP (ip-1) |
# define IP (ip-1) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 333
|
Line 352
|
|
|
#if THREADING_SCHEME==5 |
#if THREADING_SCHEME==5 |
#warning indirect threading scheme 5: long latency, cisc |
#warning indirect threading scheme 5: long latency, cisc |
# define CFA_NEXT |
|
# 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 347
|
Line 365
|
|
|
#if THREADING_SCHEME==6 |
#if THREADING_SCHEME==6 |
#warning indirect threading scheme 6: long latency |
#warning indirect threading scheme 6: long latency |
# define CFA_NEXT |
|
# 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 361
|
Line 378
|
|
|
#if THREADING_SCHEME==7 |
#if THREADING_SCHEME==7 |
#warning indirect threading scheme 7: low latency |
#warning indirect threading scheme 7: low latency |
# define CFA_NEXT |
|
# 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 375
|
Line 391
|
|
|
#if THREADING_SCHEME==8 |
#if THREADING_SCHEME==8 |
#warning indirect threading scheme 8: low latency,cisc |
#warning indirect threading scheme 8: low latency,cisc |
# define CFA_NEXT |
|
# define NEXT_P0 |
# define NEXT_P0 |
# define IP (ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(p); NEXT_P0;}) |
Line 390
|
Line 405
|
/* indirect threaded */ |
/* indirect threaded */ |
#endif |
#endif |
|
|
#endif /* !defined(DOUBLY_INDIRECT) */ |
#endif /* !defined(DOUBLY_INDIRECT) && !defined(NO_IP) */ |
|
|
#define NEXT ({DEF_CA NEXT_P1; NEXT_P2;}) |
#define NEXT ({DEF_CA NEXT_P1; NEXT_P2;}) |
|
#define IPTOS NEXT_INST |