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

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