version 1.5, 1999/02/06 22:28:22
|
version 1.11, 2002/03/22 20:36:25
|
Line 1
|
Line 1
|
/* DEC Alpha |
/* DEC Alpha |
|
|
Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc. |
Copyright (C) 1995,1996,1997,1998,2000 Free Software Foundation, Inc. |
|
|
This file is part of Gforth. |
This file is part of Gforth. |
|
|
Line 16
|
Line 16
|
|
|
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, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
*/ |
*/ |
|
|
/* Be careful: long long on Alpha are 64 bit :-(( */ |
/* Be careful: long long on Alpha are 64 bit :-(( */ |
Line 29
|
Line 29
|
#define USE_TOS |
#define USE_TOS |
#endif |
#endif |
|
|
#ifndef INDIRECT_THREADED |
|
#ifndef DIRECT_THREADED |
|
#define DIRECT_THREADED |
|
#endif |
|
#endif |
|
|
|
#define FLUSH_ICACHE(addr,size) asm("call_pal 0x86") /* imb (instruction-memory barrier) */ |
#define FLUSH_ICACHE(addr,size) asm("call_pal 0x86") /* imb (instruction-memory barrier) */ |
|
|
#include "../generic/machine.h" |
#include "../generic/machine.h" |
Line 100 typedef short Int16;
|
Line 94 typedef short Int16;
|
code gcc produces for the cpu_dep routine. |
code gcc produces for the cpu_dep routine. |
*/ |
*/ |
|
|
#define CPU_DEP2 register Label _alpha_docol asm("$9")=&&docol; \ |
/* if you change this, also change _DOCOL_LABEL below */ |
|
#define DO_BASE (&&docol) |
|
|
|
#define CPU_DEP2 register Label _alpha_docol asm("$9")=DO_BASE; \ |
register Label _alpha_ca; |
register Label _alpha_ca; |
|
|
#define CPU_DEP3 cpu_dep: asm("lda %0, 500(%1)":"=r"(_alpha_ca):"r"(_alpha_docol)); goto *_alpha_ca; |
#define CPU_DEP3 cpu_dep: asm("lda %0, 500(%1)":"=r"(_alpha_ca):"r"(_alpha_docol)); goto *_alpha_ca; |
Line 109 typedef short Int16;
|
Line 106 typedef short Int16;
|
|
|
|
|
/* CODE_ADDRESS is the address of the code jumped to through the code field */ |
/* CODE_ADDRESS is the address of the code jumped to through the code field */ |
#define CODE_ADDRESS(wa) ({Int32 *_wa=(Int32 *)(wa); \ |
#define CODE_ADDRESS(wa) ({ \ |
(_wa[0]&0xfc000000)==0x68000000 ? /*JMP?*/\ |
Int32 *_wa=(Int32 *)(wa); \ |
&&docol : \ |
(_wa[0]&0xfc000000)==0x68000000 ? /*JMP?*/\ |
&&docol+((Int16 *)_wa)[0]; }) |
DO_BASE : \ |
|
((((_wa[0]^((Int32 *)_CPU_DEP_LABEL)[0]) & 0xffff0000)==0 && \ |
|
((_wa[1]^((Int32 *)_CPU_DEP_LABEL)[1]) & 0xffffc000)==0 ) ? \ |
|
(DO_BASE+((Int16 *)_wa)[0]) : \ |
|
(Label)_wa); }) |
|
|
#define _CPU_DEP_LABEL (symbols[DOESJUMP]) |
#define _CPU_DEP_LABEL (symbols[DOESJUMP]) |
#define _DOCOL_LABEL (symbols[DOCOL]) |
#define _DOCOL_LABEL (symbols[DOCOL]) |
|
|
/* MAKE_CF creates an appropriate code field at the wa; ca is the code |
/* MAKE_CF creates an appropriate code field at the wa; ca is the code |
address. For the Alpha, this is a lda followed by a jmp (or just a |
address. For the Alpha, this is a lda followed by a jmp (or just a |
jmp, if ca==&&docol). We patch the jmp with a good hint (on the |
jmp, if ca==DO_BASE). We patch the jmp with a good hint (on the |
21064A this saves 5 cycles!) */ |
21064A this saves 5 cycles!) */ |
#define MAKE_CF(wa,ca) ({ \ |
#define MAKE_CF(wa,ca) ({ \ |
Int32 *_wa=(Int32 *)(wa); \ |
Int32 *_wa=(Int32 *)(wa); \ |
Label _ca=(Label)(ca); \ |
Label _ca=(Label)(ca); \ |
if (_ca==_DOCOL_LABEL) \ |
if (_ca==_DOCOL_LABEL) \ |
_wa[0]=(((0x1a<<26)|(31<<21)|(9<<16))| \ |
_wa[0]=(((0x1a<<26)|(31<<21)|(9<<16))| \ |
(((((Cell)_ca)-((Cell)_wa)-4) & 0xffff)>>2)); \ |
(((((Cell)_ca)-((Cell)_wa)-4) & 0xffff)>>2)); \ |
else { \ |
else { \ |
_wa[0]=((((Int32 *)_CPU_DEP_LABEL)[0] & 0xffff0000)| \ |
_wa[0]=((((Int32 *)_CPU_DEP_LABEL)[0] & 0xffff0000)| \ |
((((Cell)_ca)-((Cell)_DOCOL_LABEL)) & 0xffff)); \ |
((((Cell)_ca)-((Cell)_DOCOL_LABEL)) & 0xffff)); \ |
_wa[1]=((((Int32 *)_CPU_DEP_LABEL)[1] & 0xffffc000)| \ |
_wa[1]=((((Int32 *)_CPU_DEP_LABEL)[1] & 0xffffc000)| \ |
(((((Cell)_ca)-((Cell)_wa)-8) & 0xffff)>>2)); \ |
(((((Cell)_ca)-((Cell)_wa)-8) & 0xffff)>>2)); \ |
} \ |
} \ |
}) |
}) |
|
|
/* this is the point where the does code for the word with the xt cfa |
/* this is the point where the does code for the word with the xt cfa |
starts. Because the jump to the code field takes only one cell on |
starts. Because the jump to the code field takes only one cell on |
Line 142 typedef short Int16;
|
Line 143 typedef short Int16;
|
#define DOES_CODE(cfa) \ |
#define DOES_CODE(cfa) \ |
({ Int32 *_wa=(cfa); \ |
({ Int32 *_wa=(cfa); \ |
(_wa[0] == ((((Int32 *)_CPU_DEP_LABEL)[0] & 0xffff0000)| \ |
(_wa[0] == ((((Int32 *)_CPU_DEP_LABEL)[0] & 0xffff0000)| \ |
((((Cell)&&dodoes)-((Cell)&&docol)) & 0xffff)) && \ |
((((Cell)&&dodoes)-((Cell)DO_BASE)) & 0xffff)) && \ |
(_wa[1]&0xffffc000) == (((Int32 *)_CPU_DEP_LABEL)[1] & 0xffffc000)) \ |
(_wa[1]&0xffffc000) == (((Int32 *)_CPU_DEP_LABEL)[1] & 0xffffc000)) \ |
? DOES_CODE1(_wa) : 0; }) |
? DOES_CODE1(_wa) : 0; }) |
|
|
Line 152 typedef short Int16;
|
Line 153 typedef short Int16;
|
/* the does handler resides between DOES> and the following Forth |
/* the does handler resides between DOES> and the following Forth |
code. Since the code-field jumps directly to dodoes, the |
code. Since the code-field jumps directly to dodoes, the |
does-handler is not needed for the Alpha architecture */ |
does-handler is not needed for the Alpha architecture */ |
#define MAKE_DOES_HANDLER(addr) 0 |
#define MAKE_DOES_HANDLER(addr) ((void)0) |
|
|
/* This makes a code field for a does-defined word. doesp is the |
/* This makes a code field for a does-defined word. doesp is the |
address of the does-code. On the Alpha, the code field consists of |
address of the does-code. On the Alpha, the code field consists of |
Line 162 typedef short Int16;
|
Line 163 typedef short Int16;
|
_cfa[1] = (doesp); }) |
_cfa[1] = (doesp); }) |
#endif |
#endif |
|
|
|
/* dynamic superinstruction stuff */ |
|
|
|
#define INST_GRANULARITY 4 |
|
#define IND_JUMP_LENGTH 4 |
|
#define IS_NEXT_JUMP(_addr) (((*(unsigned *)(_addr))&0xffe00000) == 0x6be00000) |
|
#define ALIGN_CODE { \ |
|
int align_diff; \ |
|
old_code_here = (Address)(((((Cell)old_code_here)-1)|0xf)+1); \ |
|
align_diff = old_code_here - code_here; \ |
|
memcpy(code_here, ((char *)(int []){0x47ff041f,0x2fe00000,0x47ff041f,0x2fe00000})+16-align_diff,align_diff); \ |
|
code_here = old_code_here; \ |
|
} |
|
|
#ifdef FORCE_REG |
#ifdef FORCE_REG |
/* $9-$14 are callee-saved, $1-$8 and $22-$25 are caller-saved */ |
/* $9-$14 are callee-saved, $1-$8 and $22-$25 are caller-saved */ |
#define IPREG asm("$10") |
#define IPREG asm("$10") |