Annotation of gforth/vmgen-ex2/engine.c, revision 1.2

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: 
1.2     ! anton      56: #ifdef __GNUC__
1.1       anton      57: #if THREADING_SCHEME==1
                     58: /* direct threading scheme 1: autoinc, long latency (HPPA, Sharc) */
                     59: #  define NEXT_P0      ({cfa=*ip++;})
                     60: #  define IP           (ip-1)
                     61: #  define SET_IP(p)    ({ip=(p); NEXT_P0;})
                     62: #  define NEXT_INST    (cfa)
                     63: #  define INC_IP(const_inc)    ({cfa=IP[const_inc]; ip+=(const_inc);})
                     64: #  define DEF_CA
                     65: #  define NEXT_P1
                     66: #  define NEXT_P2      ({goto *cfa;})
                     67: #endif
                     68: 
                     69: #if THREADING_SCHEME==3
                     70: /* direct threading scheme 3: autoinc, low latency (68K) */
                     71: #  define NEXT_P0
                     72: #  define IP           (ip)
                     73: #  define SET_IP(p)    ({ip=(p); NEXT_P0;})
                     74: #  define NEXT_INST    (*ip)
                     75: #  define INC_IP(const_inc)    ({ip+=(const_inc);})
                     76: #  define DEF_CA
                     77: #  define NEXT_P1      ({cfa=*ip++;})
                     78: #  define NEXT_P2      ({goto *cfa;})
                     79: #endif
                     80: 
                     81: #if THREADING_SCHEME==5
                     82: /* direct threading scheme 5: early fetching (Alpha, MIPS) */
                     83: #  define CFA_NEXT
                     84: #  define NEXT_P0      ({cfa=*ip;})
                     85: #  define IP           ((Cell *)ip)
                     86: #  define SET_IP(p)    ({ip=(Inst *)(p); NEXT_P0;})
                     87: #  define NEXT_INST    ((Cell)cfa)
                     88: #  define INC_IP(const_inc)    ({cfa=ip[const_inc]; ip+=(const_inc);})
                     89: #  define DEF_CA
                     90: #  define NEXT_P1      (ip++)
                     91: #  define NEXT_P2      ({goto *cfa;})
                     92: #endif
                     93: 
                     94: #if THREADING_SCHEME==8
                     95: /* direct threading scheme 8: i386 hack */
                     96: #  define NEXT_P0
                     97: #  define IP           (ip)
                     98: #  define SET_IP(p)    ({ip=(p); NEXT_P0;})
                     99: #  define NEXT_INST    (*IP)
                    100: #  define INC_IP(const_inc)    ({ ip+=(const_inc);})
                    101: #  define DEF_CA
                    102: #  define NEXT_P1      (ip++)
                    103: #  define NEXT_P2      ({goto *((*(ip-1)).inst);})
                    104: #endif
                    105: 
                    106: #if THREADING_SCHEME==9
                    107: /* direct threading scheme 9: prefetching (for PowerPC) */
                    108: /* note that the "cfa=next_cfa;" occurs only in NEXT_P1, because this
                    109:    works out better with the capabilities of gcc to introduce and
                    110:    schedule the mtctr instruction. */
                    111: #  define NEXT_P0
                    112: #  define IP           ip
                    113: #  define SET_IP(p)    ({ip=(p); next_cfa=*ip; NEXT_P0;})
                    114: #  define NEXT_INST    (next_cfa)
                    115: #  define INC_IP(const_inc)    ({next_cfa=IP[const_inc]; ip+=(const_inc);})
                    116: #  define DEF_CA       
                    117: #  define NEXT_P1      ({cfa=next_cfa; ip++; next_cfa=*ip;})
                    118: #  define NEXT_P2      ({goto *cfa;})
                    119: #  define MORE_VARS    Inst next_cfa;
                    120: #endif
                    121: 
                    122: #if THREADING_SCHEME==10
                    123: /* direct threading scheme 10: plain (no attempt at scheduling) */
                    124: #  define NEXT_P0
                    125: #  define IP           (ip)
                    126: #  define SET_IP(p)    ({ip=(p); NEXT_P0;})
                    127: #  define NEXT_INST    (*ip)
                    128: #  define INC_IP(const_inc)    ({ip+=(const_inc);})
                    129: #  define DEF_CA
                    130: #  define NEXT_P1
                    131: #  define NEXT_P2      ({cfa=*ip++; goto *cfa;})
                    132: #endif
                    133: 
                    134: 
                    135: #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
                    136: #define IPTOS ((Cell)(NEXT_INST))
                    137: #define CASE
                    138: 
1.2     ! anton     139: #define INST_ADDR(name) (Label)&&I_##name
        !           140: #define LABEL(name) I_##name
        !           141: #else /* !defined(__GNUC__) */
        !           142: /* use switch dispatch */
        !           143: #define DEF_CA
        !           144: #define NEXT_P0
        !           145: #define NEXT_P1
        !           146: #define NEXT_P2 goto next_inst;
        !           147: #define SET_IP(p)      (ip=(p))
        !           148: #define IP              ip
        !           149: #define NEXT_INST      (*ip)
        !           150: #define INC_IP(const_inc)      (ip+=(const_inc))
        !           151: #define IPTOS NEXT_INST
        !           152: #define INST_ADDR(name) I_##name
        !           153: #define LABEL(name) case I_##name
        !           154: 
        !           155: #endif /* !defined(__GNUC__) */
        !           156: 
1.1       anton     157: #ifdef VM_PROFILING
                    158: #define SUPER_END  vm_count_block(IP)
                    159: #else
                    160: #define SUPER_END
                    161: #endif
                    162: 
1.2     ! anton     163: #ifndef __GNUC__
        !           164: enum {
        !           165: #include "mini-labels.i"
        !           166: };
        !           167: #endif
1.1       anton     168: 
                    169: /* the return type can be anything you want it to */
                    170: long engine(Cell *ip0, Cell *sp, char *fp)
                    171: {
                    172:   /* VM registers (you may want to use gcc's "Explicit Reg Vars" here) */
                    173:   Cell * ip;
                    174:   Cell * cfa;
                    175: #ifdef USE_spTOS
                    176:   Cell   spTOS;
                    177: #else
                    178: #define spTOS (sp[0])
                    179: #endif
                    180:   static Label   labels[] = {
                    181: #include "mini-labels.i"
                    182:   };
                    183: #ifdef MORE_VARS
                    184:   MORE_VARS
                    185: #endif
                    186: 
                    187:   if (vm_debug)
                    188:       fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
                    189:   if (ip0 == NULL) {
                    190:     vm_prim = labels;
                    191:     return 0;
                    192:   }
                    193: 
                    194:   /* I don't have a clue where these things come from,
                    195:      but I've put them in macros.h for the moment */
                    196:   IF_spTOS(spTOS = sp[0]);
                    197: 
                    198:   SET_IP(ip0);
                    199:   SUPER_END;  /* count the BB starting at ip0 */
1.2     ! anton     200: 
        !           201: #ifdef __GNUC__
1.1       anton     202:   NEXT;
                    203: #include "mini-vm.i"
1.2     ! anton     204: #else  
        !           205:  next_inst:
        !           206:   switch((*ip++).inst) {
        !           207: #include "mini-vm.i"
        !           208:   default:
        !           209:     fprintf(stderr,"unknown instruction %d at %p\n", ip[-1], ip-1);
        !           210:     exit(1);
        !           211:   }
        !           212: #endif
1.1       anton     213: }

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