1 /*
2  * virtual machine
3  *
4  * $Id: vm2.h 1.1.1.15 Wed, 19 Apr 2000 22:43:15 +0200 crad $
5  */
6 
7 #define FAST					/* 2 stacks and TOS  */
8 #undef  LIGHTSPEED				/* use system stack */
9 
10 #ifdef FAST
11 #define FORCE_REG				/* force register choice */
12 #define USE_TOS					/* don't use tos register */
13 #undef  USE_SYS_STACK			/* use the same system stack */
14 
15 #ifdef __i386__
16 #define IPREG	asm("%esi")
17 #define SPREG	asm("%edi")
18 #define TOSREG	asm("%ebx")
19 #endif
20 
21 #ifdef __sparc__
22 /* have trouble with sparc now. Does not want to work... :( */
23 #define IPREG	/*	asm("%g6") */
24 
25 /* egcc (2.91.x) can use machine register for SP */
26 #if (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 91)
27 #define SPREG	/*	asm("%g6") */
28 #endif
29 
30 #define TOSREG		asm("%g7")
31 #endif
32 
33 #endif /* FAST */
34 
35 #ifdef LIGHTSPEED
36 #define FORCE_REG				/* force register choice */
37 #undef  USE_TOS					/* don't use tos register */
38 #define USE_SYS_STACK			/* use the same system stack */
39 
40 #define IPREG	asm("%esi")
41 #define SPREG	asm("%esp")
42 #define TOSREG
43 #endif
44 
45 #ifndef IPREG
46 #define IPREG
47 #endif
48 #ifndef SPREG
49 #define SPREG
50 #endif
51 #ifndef TOSREG
52 #define TOSREG
53 #endif
54 
55 /* when defined, check for stack under/overflow */
56 #define STACK_CHECKS
57 
58 /* compress stack as much as possible when optionnal arguments are
59  * involved */
60 #define STACK_OPT_COMPRESS
61 
62 /* max number of cell we can push before next check */
63 #define STACK_OVERFLOW_GRACE	100
64 
65 /* max number of argument with callc opcode */
66 #define SCM_OP_CALLC_MAX		10
67 
68 /*-- opcodes : keep it sync with symbols[] in engine */
69 enum SCM_OPCODES {
70   SCM_OP_NOP=0,
71   SCM_OP_END,
72 
73   SCM_OP_DOLET,					/* proc: */
74   SCM_OP_DOLETSTAR,
75   SCM_OP_ENDLET_JUMP,			/* used only before a call/jump */
76 
77   SCM_OP_DROP,					/* drop value on stack */
78   SCM_OP_PUSH,
79   SCM_OP_PUSHV,
80   SCM_OP_PUSHN,
81 
82   SCM_OP_PUSHL,					/* push value of a local assoc */
83   SCM_OP_PUSHL0,				/* push value of a local assoc */
84   SCM_OP_PUSHL1,				/* push value of a local assoc */
85   SCM_OP_PUSHL2,				/* push value of a local assoc */
86   SCM_OP_PUSHL3,				/* push value of a local assoc */
87 
88   SCM_OP_ALLOC,					/* alloc n slots on stack */
89 
90   SCM_OP_PUSHLIST,				/* push a list to the stack */
91 
92   SCM_OP_MARK,					/* set rsp */
93   SCM_OP_MKCLOSURE,
94 
95   SCM_OP_ENDLET,				/* normal end of let clause */
96   SCM_OP_RETURN,				/* return from call */
97 
98   SCM_OP_CALLC,					/* C prim with fixed number of args */
99   SCM_OP_CALLC0,				/* C prim no args */
100   SCM_OP_CALLC1,				/* C prim 1  arg  */
101   SCM_OP_CALLC2,				/* C prim 2  args */
102   SCM_OP_CALLC3,				/* C prim 3  args */
103   SCM_OP_CALLC4,				/* C prim 4  args */
104   SCM_OP_CALLC5,				/* C prim 5  args */
105   SCM_OP_CALLC6,				/* C prim 6  args */
106   SCM_OP_CALLC7,				/* C prim 7  args */
107   SCM_OP_CALLC8,				/* C prim 8  args */
108   SCM_OP_CALLC9,				/* C prim 9  args */
109   SCM_OP_CALLC10,				/* C prim 10 args */
110   SCM_OP_CALLS,					/* C prim with variable number of args */
111 
112   SCM_OP_NO_CALL,
113   SCM_OP_JUMP,
114   SCM_OP_CALL,
115   SCM_OP_CALL_PRIM,
116   SCM_OP_CALL_CPRIM,
117   SCM_OP_CALL_CODE,
118   SCM_OP_CALL_PROC,
119   SCM_OP_CALL_CLOSURE,
120   SCM_OP_CALL_MACRO,
121   SCM_OP_CALL_EXTFUNC,
122   SCM_OP_CALL_VMFUNC,
123 
124   SCM_OP_CATCH,					/* low level error handling */
125   SCM_OP_UNCATCH,
126 
127   SCM_OP_STORE,					/* store global variable */
128   SCM_OP_SETL,					/* local var store */
129   SCM_OP_SETL0,					/* local var store */
130   SCM_OP_SETL0DROP,				/* local var store */
131 
132   SCM_OP_GETVAR,
133   SCM_OP_SETVAR,
134 
135   SCM_OP_BR_AND,				/* special branch for and */
136   SCM_OP_BR_OR,					/* special branch for or */
137   SCM_OP_BR_COND,				/* special branch for cond */
138   SCM_OP_BR_WHILE,				/* special branch for while */
139   SCM_OP_BRA,					/* branch allways */
140   SCM_OP_BRF,					/* pop and branch if false */
141   SCM_OP_BRT,					/* pop and branch if not false */
142 
143   SCM_OP_SAVE_R0,
144   SCM_OP_LOAD_R0,
145 
146   SCM_OP_MAX };
147 
148 #ifdef __VM2_INTERNAL__
149 
150 /*-- how to push and pop to the machine */
151 
152 #ifndef USE_TOS
153 #ifdef USE_SYS_STACK
154 #	define supdate()
155 #	define spush(x) { __asm__ __volatile__ ( "pushl %0" : : "g"(x) ); }
156 #	define spop(x)  { __asm__ __volatile__ ( "popl %0" : "=g"(x) : ); }
157 #	define TOS		sp[0]
158 #else
159 #	define supdate()
160 #	define spush(x)	{*(--sp) = (void*)(x); }
161 #	define spop(x)	{(x)=*sp++; }
162 #	define sdrop()	{ sp++; }
163 #	define TOS		sp[0]
164 #endif
165 
166 #else
167 /* TOS is a cache for the top of the stack */
168 #define supdate()	{ *sp=TOS; }
169 #define spush(x)	{ supdate(); sp--;  TOS=(x); }
170 #define spop(x)		{ (x)=TOS;  sp++;  TOS=*sp; }
171 #define sdrop()		{ sp++; TOS=*sp; }
172 #endif
173 
174 #ifndef USE_TOS
175 #ifdef USE_SYS_STACK
176 #	define supdate()
177 #	define spush(x) { __asm__ __volatile__ ( "pushl %0" : : "g"(x) ); }
178 #	define spop(x)  { __asm__ __volatile__ ( "popl %0" : "=g"(x) : ); }
179 #	define TOS		sp[0]
180 #else  /* ! USE_SYS_STACK */
181 #	define supdate()
182 #	define spush(x)	{*(--sp) = (void*)(x); }
183 #	define spop(x)	{(x)=*sp++; }
184 #	define sdrop()	{ sp++; }
185 #	define TOS		sp[0]
186 #endif	/* ! USE_SYS_STACK */
187 
188 #else	/* USE_TOS */
189 
190 #if USE_SYS_STACK
191 #	error "Use sys_stack and TOS not defined yet. Do it yourself"
192 #else /* !USE_SYS_STACK */
193 	/* TOS is a cache for the top of the stack */
194 #	define supdate()	{ *sp=TOS; }
195 #	define spush(x)	{ supdate(); sp--;  TOS=(x); }
196 #	define spop(x)		{ (x)=TOS;  sp++;  TOS=*sp; }
197 #	define sdrop()		{ sp++; TOS=*sp; }
198 #endif	/* USE_SYS_STACK */
199 #endif	/* USE_TOS */
200 
201 #define sresync()	{ supdate();  scm_sp=(SOBJ*)sp;  }
202 
203 #endif
204 
205 /*-- forward and prototypes */
206 
207 extern SCM_PRIM_TABLE *scm_prim_table;		/* opcode table */
208 
209 void 		scm_vmfunc_mark(SOBJ obj);
210 void 		scm_vmfunc_sweep(SOBJ obj);
211 
212 void        scm_engine_init();
213 SCM_PRIM_TABLE *scm_get_addr(int opc);
214 int         scm_is_opcode_address(void *p);
215 SCM_PRIM_TABLE *scm_search_opcode_address(char *name);
216 char 		*scm_search_opcode_name(void *p);
217 SOBJ        scm_disassemble(SOBJ *code, int nslots);
218