Annotation of gforth/vmgen-ex2/engine.c, revision 1.1
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: #define vm_Cell2Cell(_x,_y) ((_y)=(_x))
! 25:
! 26: #define USE_spTOS 1
! 27:
! 28: #ifdef USE_spTOS
! 29: #define IF_spTOS(x) x
! 30: #else
! 31: #define IF_spTOS(x)
! 32: #endif
! 33:
! 34: #ifdef VM_DEBUG
! 35: #define NAME(_x) if (vm_debug) {fprintf(vm_out, "%p: %-20s, ", ip-1, _x); fprintf(vm_out,"fp=%p, sp=%p", fp, sp);}
! 36: #else
! 37: #define NAME(_x)
! 38: #endif
! 39:
! 40: /* different threading schemes for different architectures; the sparse
! 41: numbering is there for historical reasons */
! 42:
! 43: /* here you select the threading scheme; I have only set this up for
! 44: 386 and generic, because I don't know what preprocessor macros to
! 45: test for (Gforth uses config.guess instead).
! 46: Anyway, it's probably best to build them all and select the fastest
! 47: instead of hardwiring a specific scheme for an architecture. */
! 48: #ifndef THREADING_SCHEME
! 49: #ifdef i386
! 50: #define THREADING_SCHEME 8
! 51: #else
! 52: #define THREADING_SCHEME 5
! 53: #endif
! 54: #endif /* defined(THREADING_SCHEME) */
! 55:
! 56: #if THREADING_SCHEME==1
! 57: /* direct threading scheme 1: autoinc, long latency (HPPA, Sharc) */
! 58: # define NEXT_P0 ({cfa=*ip++;})
! 59: # define IP (ip-1)
! 60: # define SET_IP(p) ({ip=(p); NEXT_P0;})
! 61: # define NEXT_INST (cfa)
! 62: # define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);})
! 63: # define DEF_CA
! 64: # define NEXT_P1
! 65: # define NEXT_P2 ({goto *cfa;})
! 66: #endif
! 67:
! 68: #if THREADING_SCHEME==3
! 69: /* direct threading scheme 3: autoinc, low latency (68K) */
! 70: # define NEXT_P0
! 71: # define IP (ip)
! 72: # define SET_IP(p) ({ip=(p); NEXT_P0;})
! 73: # define NEXT_INST (*ip)
! 74: # define INC_IP(const_inc) ({ip+=(const_inc);})
! 75: # define DEF_CA
! 76: # define NEXT_P1 ({cfa=*ip++;})
! 77: # define NEXT_P2 ({goto *cfa;})
! 78: #endif
! 79:
! 80: #if THREADING_SCHEME==5
! 81: /* direct threading scheme 5: early fetching (Alpha, MIPS) */
! 82: # define CFA_NEXT
! 83: # define NEXT_P0 ({cfa=*ip;})
! 84: # define IP ((Cell *)ip)
! 85: # define SET_IP(p) ({ip=(Inst *)(p); NEXT_P0;})
! 86: # define NEXT_INST ((Cell)cfa)
! 87: # define INC_IP(const_inc) ({cfa=ip[const_inc]; ip+=(const_inc);})
! 88: # define DEF_CA
! 89: # define NEXT_P1 (ip++)
! 90: # define NEXT_P2 ({goto *cfa;})
! 91: #endif
! 92:
! 93: #if THREADING_SCHEME==8
! 94: /* direct threading scheme 8: i386 hack */
! 95: # define NEXT_P0
! 96: # define IP (ip)
! 97: # define SET_IP(p) ({ip=(p); NEXT_P0;})
! 98: # define NEXT_INST (*IP)
! 99: # define INC_IP(const_inc) ({ ip+=(const_inc);})
! 100: # define DEF_CA
! 101: # define NEXT_P1 (ip++)
! 102: # define NEXT_P2 ({goto *((*(ip-1)).inst);})
! 103: #endif
! 104:
! 105: #if THREADING_SCHEME==9
! 106: /* direct threading scheme 9: prefetching (for PowerPC) */
! 107: /* note that the "cfa=next_cfa;" occurs only in NEXT_P1, because this
! 108: works out better with the capabilities of gcc to introduce and
! 109: schedule the mtctr instruction. */
! 110: # define NEXT_P0
! 111: # define IP ip
! 112: # define SET_IP(p) ({ip=(p); next_cfa=*ip; NEXT_P0;})
! 113: # define NEXT_INST (next_cfa)
! 114: # define INC_IP(const_inc) ({next_cfa=IP[const_inc]; ip+=(const_inc);})
! 115: # define DEF_CA
! 116: # define NEXT_P1 ({cfa=next_cfa; ip++; next_cfa=*ip;})
! 117: # define NEXT_P2 ({goto *cfa;})
! 118: # define MORE_VARS Inst next_cfa;
! 119: #endif
! 120:
! 121: #if THREADING_SCHEME==10
! 122: /* direct threading scheme 10: plain (no attempt at scheduling) */
! 123: # define NEXT_P0
! 124: # define IP (ip)
! 125: # define SET_IP(p) ({ip=(p); NEXT_P0;})
! 126: # define NEXT_INST (*ip)
! 127: # define INC_IP(const_inc) ({ip+=(const_inc);})
! 128: # define DEF_CA
! 129: # define NEXT_P1
! 130: # define NEXT_P2 ({cfa=*ip++; goto *cfa;})
! 131: #endif
! 132:
! 133:
! 134: #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
! 135: #define IPTOS ((Cell)(NEXT_INST))
! 136: #define CASE
! 137:
! 138: #ifdef VM_PROFILING
! 139: #define SUPER_END vm_count_block(IP)
! 140: #else
! 141: #define SUPER_END
! 142: #endif
! 143:
! 144: #define INST_ADDR(name) (Label)&&I_##name
! 145: #define LABEL(name) I_##name
! 146:
! 147: /* the return type can be anything you want it to */
! 148: long engine(Cell *ip0, Cell *sp, char *fp)
! 149: {
! 150: /* VM registers (you may want to use gcc's "Explicit Reg Vars" here) */
! 151: Cell * ip;
! 152: Cell * cfa;
! 153: #ifdef USE_spTOS
! 154: Cell spTOS;
! 155: #else
! 156: #define spTOS (sp[0])
! 157: #endif
! 158: static Label labels[] = {
! 159: #include "mini-labels.i"
! 160: };
! 161: #ifdef MORE_VARS
! 162: MORE_VARS
! 163: #endif
! 164:
! 165: if (vm_debug)
! 166: fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
! 167: if (ip0 == NULL) {
! 168: vm_prim = labels;
! 169: return 0;
! 170: }
! 171:
! 172: /* I don't have a clue where these things come from,
! 173: but I've put them in macros.h for the moment */
! 174: IF_spTOS(spTOS = sp[0]);
! 175:
! 176: SET_IP(ip0);
! 177: SUPER_END; /* count the BB starting at ip0 */
! 178: NEXT;
! 179:
! 180: #include "mini-vm.i"
! 181: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>