Annotation of gforth/vmgen-ex/engine.c, revision 1.3
1.1 anton 1: /* vm interpreter wrapper
2:
3: Copyright (C) 2001 Free Software Foundation, Inc.
4:
5: This file is part of Gforth.
6:
7: Gforth is free software; you can redistribute it and/or
8: modify it under the terms of the GNU General Public License
9: as published by the Free Software Foundation; either version 2
10: of the License, or (at your option) any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; if not, write to the Free Software
19: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
20: */
21:
22: #include "mini.h"
23:
24: /* type change macros; these are specific to the types you use, so you
25: have to change this part */
26: #define vm_Cell2i(x) ((Cell)(x))
27: #define vm_i2Cell(x) (x)
28: #define vm_Cell2target(x) ((Inst *)(x))
29: #define vm_target2Cell(x) ((Cell)(x))
30: #define vm_Cell2a(x) ((char *)(x))
31: #define vm_a2Cell(x) ((Cell)(x))
32:
1.3 ! anton 33: #define vm_Cell2Cell(x) ((Cell)(x))
! 34:
1.2 anton 35: #define USE_spTOS 1
36:
1.1 anton 37: #ifdef USE_spTOS
38: #define IF_spTOS(x) x
39: #else
40: #define IF_spTOS(x)
41: #endif
42:
43: #ifdef VM_DEBUG
1.3 ! anton 44: #define NAME(_x) if (vm_debug) {fprintf(vm_out, "%p: %-20s, ", ip-1, _x); fprintf(vm_out,"fp=%p, sp=%p", fp, sp);}
1.1 anton 45: #else
46: #define NAME(_x)
47: #endif
48:
1.2 anton 49: /* different threading schemes for different architectures; the sparse
50: numbering is there for historical reasons */
1.1 anton 51:
1.2 anton 52: /* here you select the threading scheme; I have only set this up for
53: 386 and generic, because I don't know what preprocessor macros to
54: test for (Gforth uses config.guess instead).
55: Anyway, it's probably best to build them all and select the fastest
56: instead of hardwiring a specific scheme for an architecture. */
57: #ifndef THREADING_SCHEME
1.1 anton 58: #ifdef i386
59: #define THREADING_SCHEME 8
60: #else
61: #define THREADING_SCHEME 5
62: #endif
1.2 anton 63: #endif /* defined(THREADING_SCHEME) */
64:
65: #if THREADING_SCHEME==1
66: /* direct threading scheme 1: autoinc, long latency (HPPA, Sharc) */
67: # define NEXT_P0 ({cfa=*ip++;})
68: # define IP (ip-1)
69: # define SET_IP(p) ({ip=(p); NEXT_P0;})
70: # define NEXT_INST (cfa)
71: # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
72: # define DEF_CA
73: # define NEXT_P1
74: # define NEXT_P2 ({goto *cfa;})
75: #endif
76:
77: #if THREADING_SCHEME==3
78: /* direct threading scheme 3: autoinc, low latency (68K) */
79: # define NEXT_P0
80: # define IP (ip)
81: # define SET_IP(p) ({ip=(p); NEXT_P0;})
82: # define NEXT_INST (*ip)
83: # define INC_IP(const_inc) ({ip+=(const_inc);})
84: # define DEF_CA
85: # define NEXT_P1 ({cfa=*ip++;})
86: # define NEXT_P2 ({goto *cfa;})
87: #endif
1.1 anton 88:
89: #if THREADING_SCHEME==5
1.2 anton 90: /* direct threading scheme 5: early fetching (Alpha, MIPS) */
1.1 anton 91: # define CFA_NEXT
92: # define NEXT_P0 ({cfa=*ip;})
93: # define IP ((Cell *)ip)
94: # define SET_IP(p) ({ip=(Inst *)(p); NEXT_P0;})
95: # define NEXT_INST ((Cell)cfa)
96: # define INC_IP(const_inc) ({cfa=ip[const_inc]; ip+=(const_inc);})
97: # define DEF_CA
98: # define NEXT_P1 (ip++)
99: # define NEXT_P2 ({goto *cfa;})
100: #endif
101:
102: #if THREADING_SCHEME==8
103: /* direct threading scheme 8: i386 hack */
104: # define NEXT_P0
105: # define IP (ip)
106: # define SET_IP(p) ({ip=(p); NEXT_P0;})
107: # define NEXT_INST (*IP)
108: # define INC_IP(const_inc) ({ ip+=(const_inc);})
109: # define DEF_CA
110: # define NEXT_P1 (ip++)
111: # define NEXT_P2 ({goto **(ip-1);})
112: #endif
113:
1.2 anton 114: #if THREADING_SCHEME==9
115: /* direct threading scheme 9: prefetching (for PowerPC) */
116: /* note that the "cfa=next_cfa;" occurs only in NEXT_P1, because this
117: works out better with the capabilities of gcc to introduce and
118: schedule the mtctr instruction. */
119: # define NEXT_P0
120: # define IP ip
121: # define SET_IP(p) ({ip=(p); next_cfa=*ip; NEXT_P0;})
122: # define NEXT_INST (next_cfa)
123: # define INC_IP(const_inc) ({next_cfa=IP[const_inc]; ip+=(const_inc);})
124: # define DEF_CA
125: # define NEXT_P1 ({cfa=next_cfa; ip++; next_cfa=*ip;})
126: # define NEXT_P2 ({goto *cfa;})
127: # define MORE_VARS Inst next_cfa;
128: #endif
129:
130: #if THREADING_SCHEME==10
131: /* direct threading scheme 10: plain (no attempt at scheduling) */
132: # define NEXT_P0
133: # define IP (ip)
134: # define SET_IP(p) ({ip=(p); NEXT_P0;})
135: # define NEXT_INST (*ip)
136: # define INC_IP(const_inc) ({ip+=(const_inc);})
137: # define DEF_CA
138: # define NEXT_P1
139: # define NEXT_P2 ({cfa=*ip++; goto *cfa;})
140: #endif
141:
142:
1.1 anton 143: #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
144: #define IPTOS NEXT_INST
145:
146: #ifdef VM_PROFILING
147: #define SUPER_END vm_count_block(IP)
148: #else
149: #define SUPER_END
150: #endif
151:
152: /* the return type can be anything you want it to */
153: Cell engine(Inst *ip0, Cell *sp, char *fp)
154: {
1.2 anton 155: /* VM registers (you may want to use gcc's "Explicit Reg Vars" here) */
1.1 anton 156: Inst * ip;
157: Inst * cfa;
158: #ifdef USE_spTOS
159: Cell spTOS;
160: #else
161: #define spTOS (sp[0])
162: #endif
163: static Inst labels[] = {
164: #include "mini-labels.i"
165: };
1.2 anton 166: #ifdef MORE_VARS
167: MORE_VARS
168: #endif
1.1 anton 169:
170: if (vm_debug)
171: fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
172: if (ip0 == NULL) {
173: vm_prim = labels;
174: return 0;
175: }
176:
177: /* I don't have a clue where these things come from,
178: but I've put them in macros.h for the moment */
179: IF_spTOS(spTOS = sp[0]);
180:
181: SET_IP(ip0);
1.3 ! anton 182: SUPER_END; /* count the BB starting at ip0 */
1.1 anton 183: NEXT;
184:
185: #include "mini-vm.i"
186: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>