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