version 1.3, 2002/08/07 10:11:19
|
version 1.9, 2007/12/31 18:40:26
|
Line 1
|
Line 1
|
/* vm interpreter wrapper |
/* vm interpreter wrapper |
|
|
Copyright (C) 2001 Free Software Foundation, Inc. |
Copyright (C) 2001,2002,2003 Free Software Foundation, Inc. |
|
|
This file is part of Gforth. |
This file is part of Gforth. |
|
|
Gforth is free software; you can redistribute it and/or |
Gforth is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
as published by the Free Software Foundation, either version 3 |
of the License, or (at your option) any later version. |
of the License, or (at your option) any later version. |
|
|
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
Line 15
|
Line 15
|
GNU General Public License for more details. |
GNU General Public License for more details. |
|
|
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
along with this program; if not, see http://www.gnu.org/licenses/. |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
|
*/ |
*/ |
|
|
#include "mini.h" |
#include "mini.h" |
Line 40
|
Line 39
|
|
|
/* here you select the threading scheme; I have only set this up for |
/* here you select the threading scheme; I have only set this up for |
386 and generic, because I don't know what preprocessor macros to |
386 and generic, because I don't know what preprocessor macros to |
test for (Gforth uses config.guess instead). |
test for (Gforth uses config.guess instead). Anyway, it's probably |
Anyway, it's probably best to build them all and select the fastest |
best to build them all and select the fastest instead of hardwiring |
instead of hardwiring a specific scheme for an architecture. */ |
a specific scheme for an architecture. E.g., scheme 8 is fastest |
|
for Gforth "make bench" on a 486, whereas scheme 5 is fastest for |
|
"mini fib.mini" on an Athlon */ |
#ifndef THREADING_SCHEME |
#ifndef THREADING_SCHEME |
#ifdef i386 |
|
#define THREADING_SCHEME 8 |
|
#else |
|
#define THREADING_SCHEME 5 |
#define THREADING_SCHEME 5 |
#endif |
|
#endif /* defined(THREADING_SCHEME) */ |
#endif /* defined(THREADING_SCHEME) */ |
|
|
#ifdef __GNUC__ |
#ifdef __GNUC__ |
Line 61
|
Line 58
|
# define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);}) |
# define INC_IP(const_inc) ({cfa=IP[const_inc]; ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 |
# define NEXT_P1 |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *(cfa.inst);}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==3 |
#if THREADING_SCHEME==3 |
Line 73
|
Line 70
|
# define INC_IP(const_inc) ({ip+=(const_inc);}) |
# define INC_IP(const_inc) ({ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 ({cfa=*ip++;}) |
# define NEXT_P1 ({cfa=*ip++;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *(cfa.inst);}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==5 |
#if THREADING_SCHEME==5 |
/* direct threading scheme 5: early fetching (Alpha, MIPS) */ |
/* direct threading scheme 5: early fetching (Alpha, MIPS) */ |
# define CFA_NEXT |
# define CFA_NEXT |
# define NEXT_P0 ({cfa=*ip;}) |
# define NEXT_P0 ({cfa=*ip;}) |
# define IP ((Cell *)ip) |
# define IP (ip) |
# define SET_IP(p) ({ip=(Inst *)(p); NEXT_P0;}) |
# define SET_IP(p) ({ip=(Inst *)(p); NEXT_P0;}) |
# define NEXT_INST ((Cell)cfa) |
# define NEXT_INST (cfa) |
# define INC_IP(const_inc) ({cfa=ip[const_inc]; ip+=(const_inc);}) |
# define INC_IP(const_inc) ({cfa=ip[const_inc]; ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 (ip++) |
# define NEXT_P1 (ip++) |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *(cfa.inst);}) |
#endif |
#endif |
|
|
#if THREADING_SCHEME==8 |
#if THREADING_SCHEME==8 |
Line 113
|
Line 110
|
# define INC_IP(const_inc) ({next_cfa=IP[const_inc]; ip+=(const_inc);}) |
# define INC_IP(const_inc) ({next_cfa=IP[const_inc]; ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 ({cfa=next_cfa; ip++; next_cfa=*ip;}) |
# define NEXT_P1 ({cfa=next_cfa; ip++; next_cfa=*ip;}) |
# define NEXT_P2 ({goto *cfa;}) |
# define NEXT_P2 ({goto *(cfa.inst);}) |
# define MORE_VARS Inst next_cfa; |
# define MORE_VARS Cell next_cfa; |
#endif |
#endif |
|
|
#if THREADING_SCHEME==10 |
#if THREADING_SCHEME==10 |
Line 126
|
Line 123
|
# define INC_IP(const_inc) ({ip+=(const_inc);}) |
# define INC_IP(const_inc) ({ip+=(const_inc);}) |
# define DEF_CA |
# define DEF_CA |
# define NEXT_P1 |
# define NEXT_P1 |
# define NEXT_P2 ({cfa=*ip++; goto *cfa;}) |
# define NEXT_P2 ({cfa=*ip++; goto *(cfa.inst);}) |
#endif |
#endif |
|
|
|
|
#define NEXT ({DEF_CA NEXT_P1; NEXT_P2;}) |
#define NEXT ({DEF_CA NEXT_P1; NEXT_P2;}) |
#define IPTOS ((Cell)(NEXT_INST)) |
#define IPTOS ((NEXT_INST)) |
#define CASE |
|
|
|
#define INST_ADDR(name) (Label)&&I_##name |
#define INST_ADDR(name) (Label)&&I_##name |
#define LABEL(name) I_##name |
#define LABEL(name) I_##name: |
#else /* !defined(__GNUC__) */ |
#else /* !defined(__GNUC__) */ |
/* use switch dispatch */ |
/* use switch dispatch */ |
#define DEF_CA |
#define DEF_CA |
Line 148
|
Line 144
|
#define INC_IP(const_inc) (ip+=(const_inc)) |
#define INC_IP(const_inc) (ip+=(const_inc)) |
#define IPTOS NEXT_INST |
#define IPTOS NEXT_INST |
#define INST_ADDR(name) I_##name |
#define INST_ADDR(name) I_##name |
#define LABEL(name) case I_##name |
#define LABEL(name) case I_##name: |
|
|
#endif /* !defined(__GNUC__) */ |
#endif /* !defined(__GNUC__) */ |
|
|
|
#define LABEL2(x) |
|
|
#ifdef VM_PROFILING |
#ifdef VM_PROFILING |
#define SUPER_END vm_count_block(IP) |
#define SUPER_END vm_count_block(IP) |
#else |
#else |
Line 164 enum {
|
Line 162 enum {
|
}; |
}; |
#endif |
#endif |
|
|
|
#if defined(__GNUC__) && ((__GNUC__==2 && defined(__GNUC_MINOR__) && __GNUC_MINOR__>=7)||(__GNUC__>2)) |
|
#define MAYBE_UNUSED __attribute__((unused)) |
|
#else |
|
#define MAYBE_UNUSED |
|
#endif |
|
|
/* the return type can be anything you want it to */ |
/* the return type can be anything you want it to */ |
long engine(Cell *ip0, Cell *sp, char *fp) |
long engine(Cell *ip0, Cell *sp, char *fp) |
{ |
{ |
/* VM registers (you may want to use gcc's "Explicit Reg Vars" here) */ |
/* VM registers (you may want to use gcc's "Explicit Reg Vars" here) */ |
Cell * ip; |
Cell * ip; |
Cell * cfa; |
Cell cfa; |
#ifdef USE_spTOS |
#ifdef USE_spTOS |
Cell spTOS; |
Cell spTOS; |
#else |
#else |