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>