Diff for /gforth/Attic/alpha.h between versions 1.3 and 1.4

version 1.3, 1995/11/29 20:20:33 version 1.4, 1995/12/10 19:02:06
Line 26 Line 26
 #define USE_TOS  #define USE_TOS
 #endif  #endif
   
 #ifdef DIRECT_THREADED  #ifndef INDIRECT_THREADED
 #warning direct threading not supported on the Alpha (yet)  #ifndef DIRECT_THREADED
 #undefine DIRECT_THREADED  /* #define DIRECT_THREADED */
   #endif
 #endif  #endif
   
 #define FLUSH_ICACHE(addr,size)         asm("call_pal 0x86") /* imb */  #define FLUSH_ICACHE(addr,size)         asm("call_pal 0x86") /* imb (instruction-memory barrier) */
   
 #include "32bit.h"  #include "32bit.h"
   
   #ifdef DIRECT_THREADED
   #ifdef WORDS_BIGENDIAN
   #error Direct threading only supported for little-endian Alphas.
   /* big-endian Alphas still store instructions in little-endian format,
      so you would have to reverse the instruction accesses in the following
   */
   #endif
   #if SIZEOF_CHAR_P != 8
   #error Direct threading only supported for Alphas with 64-bit Cells.
   /* some of the stuff below assumes that the first cell in a code field
      can contain 2 instructions
   
      A simple way around this problem would be to have _alpha_docol
      contain &&dodoes. This would slow down colon defs, however.
   
      Another way is to use a special DOES_HANDLER, like most other CPUs */
   #endif
   
   #warning Direct threading for Alpha may not work with all compiler versions
   
   typedef int Int32;
   typedef short Int16;
   
   /* PFA gives the parameter field address corresponding to a cfa */
   #define PFA(cfa)        (((Cell *)cfa)+2)
   /* PFA1 is a special version for use just after a NEXT1 */
   /* the improvement here is that we may destroy cfa before using PFA1 */
   #define PFA1(cfa)       PFA(cfa)
   
   /*
      On the Alpha, code (in the text segment) typically cannot be
      reached from the dictionary (in the data segment) with a normal
      branch. It also usually takes too long (and too much space on
      32-bit systems) to load the address as literal and jump indirectly.
      
      So, what we do is this: a pointer into our code (at docol, to be
      exact) is kept in a register: _alpha_docol. When the innner
      interpreter jumps to the word address of a variable etc., the
      destination address is computed from that with a lda instruction
      and stored in another register: _alpha_ca. Then an indirect jump
      through _alpha_ca is performed. For docol, we need not compute
      _alpha_ca first.
   
      How do we tell gcc all this? We declare the registers as variables:
      _alpha_docol as explicit variable, to avoid spilling; _alpha_ca is
      so short-lived, so it hopefully won't be spilled. A
      pseudo-primitive cpu_dep is created with code that let's gcc's data
      flow analysis know that _alpha_docol is used and that _alpha_ca may
      be defined and used after any NEXT and before any primitive.  We
      let gcc choose the register for _alpha_ca and simply change the
      code gcc produces for the cpu_dep routine.
   */
   
   #define CPU_DEP2        register Label _alpha_docol asm("$9")=&&docol; \
                           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_DEP1        (&&cpu_dep)
   
   
   /* CODE_ADDRESS is the address of the code jumped to through the code field */
   #define CODE_ADDRESS(wa)        ({Int32 *_wa=(Int32 *)(wa); \
                                       (_wa[0]&0xfc000000)==0x68000000 ? /*JMP?*/\
                                       &&docol : \
                                       &&docol+((Int16 *)_wa)[0]; })
   
   #define _CPU_DEP_LABEL  (symbols[DOESJUMP])
   #define _DOCOL_LABEL    (symbols[DOCOL])
   
   /* 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 */
   #define MAKE_CF(wa,ca)  ({ \
                                Int32 *_wa=(Int32 *)(wa); \
                                Int32 *_ca=(Int32 *)(ca); \
                                _wa[0]=((((Int32 *)_CPU_DEP_LABEL)[0] & 0xffff0000)| \
                                         ((((Cell)_ca)-((Cell)_DOCOL_LABEL)) & 0xffff)); \
                                _wa[1]=((((Int32 *)_CPU_DEP_LABEL)[1] & 0xffffc000)| \
                                         (((((Cell)_ca)-((Cell)_wa)-8) & 0xffff)>>2)); \
                            })
   
   /* 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
      64-bit systems we can use the second cell of the cfa for storing
      the does address */
   #define DOES_CODE(cfa)  ((Xt *)(((Cell *)(cfa))[1]))
   /* this is a special version of DOES_CODE for use in dodoes */
   #define DOES_CODE1(label)       DOES_CODE(label)
   
   /* the does handler resides between DOES> and the following Forth
      code. Since the code-field jumps directly to dodoes, the
      does-handler is not needed for the Alpha architecture */
   #define DOES_HANDLER_SIZE       (2*sizeof(Cell))
   #define MAKE_DOES_HANDLER(addr)   0
   
   /* 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
      a jump to dodoes and the address of the does code */
   #define MAKE_DOES_CF(cfa,doesp) ({Xt *_cfa = (Xt *)(cfa); \
                                       MAKE_CF(_cfa, symbols[DODOES]); \
                                       _cfa[1] = (doesp); })
   #endif
   

Removed from v.1.3  
changed lines
  Added in v.1.4


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