File:  [gforth] / gforth / vmgen-ex / engine.c
Revision 1.3: download - view: text, annotated - select for diffs
Tue May 1 10:20:55 2001 UTC (22 years, 11 months ago) by anton
Branches: MAIN
CVS tags: HEAD
fixed profiling
completed README

    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: 
   33: #define vm_Cell2Cell(x) ((Cell)(x))
   34: 
   35: #define USE_spTOS 1
   36: 
   37: #ifdef USE_spTOS
   38: #define IF_spTOS(x) x
   39: #else
   40: #define IF_spTOS(x)
   41: #endif
   42: 
   43: #ifdef VM_DEBUG
   44: #define NAME(_x) if (vm_debug) {fprintf(vm_out, "%p: %-20s, ", ip-1, _x); fprintf(vm_out,"fp=%p, sp=%p", fp, sp);}
   45: #else
   46: #define NAME(_x)
   47: #endif
   48: 
   49: /* different threading schemes for different architectures; the sparse
   50:    numbering is there for historical reasons */
   51: 
   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
   58: #ifdef i386
   59: #define THREADING_SCHEME 8
   60: #else
   61: #define THREADING_SCHEME 5
   62: #endif
   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
   88: 
   89: #if THREADING_SCHEME==5
   90: /* direct threading scheme 5: early fetching (Alpha, MIPS) */
   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: 
  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: 
  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: {
  155:   /* VM registers (you may want to use gcc's "Explicit Reg Vars" here) */
  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:   };
  166: #ifdef MORE_VARS
  167:   MORE_VARS
  168: #endif
  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);
  182:   SUPER_END;  /* count the BB starting at ip0 */
  183:   NEXT;
  184: 
  185: #include "mini-vm.i"
  186: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>