/* This is the machine-specific part for the Power (incl. PPC) architecture
Copyright (C) 1995 Free Software Foundation, Inc.
This file is part of Gforth.
Gforth is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(USE_TOS) && !defined(USE_NO_TOS)
#define USE_TOS
#endif
#ifndef INDIRECT_THREADED
#ifndef DIRECT_THREADED
/* #define DIRECT_THREADED */
#endif
#endif
#include "32bit.h"
/* cache flush stuff */
#warning If you get assembly errors, here is the reason why
#define FLUSH_ICACHE(addr,size) asm("icbi (%0); isync"::"b"(addr))
/* this assumes size=4 */
/* the mnemonics are for the PPC and the syntax is a wild guess; for
Power the mnemonic for the isync instruction is "ics" and I have
not found an equivalent for the icbi instruction in my reference.
*/
#ifdef DIRECT_THREADED
#warning Direct threading for Power has not been tested
/* 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)
/* I'll assume the code resides in the lower (or upper) 32M of the
address space and use absolute addressing in the jumps to the
handlers. This makes it possible to use the full address space for
direct threaded Forth (even on 64-bit PowerPCs). However, the
linker has to ensure that this really happens */
#define JUMP_TARGET_BITS 0
/* assuming the code is in the lower 32M; if it is in the upper 32M,
define JUMP_TARGET_BITS as ~0x3ffffff */
#define JUMP_MASK 0x3fffffc
/* CODE_ADDRESS is the address of the code jumped to through the code field */
#define CODE_ADDRESS(cfa) ((Label)(((*(unsigned *)(cfa))&JUMP_MASK)|JUMP_TARGET_BITS))
/* MAKE_CF creates an appropriate code field at the cfa; ca is the
code address. For those familiar with assembly, this is a `ba'
instruction in both Power and PowerPC assembly languages */
#define MAKE_CF(cfa,ca) (*(long *)(cfa) = 0x48000002|(ca))
/* this is the point where the does code for the word with the xt cfa
starts. Since a branch is only a cell on Power, we can use the
second cell of the cfa for storing the does address */
#define DOES_CODE(cfa) \
({ unsigned *_cfa=(unsigned *)(cfa); \
_cfa[0]==(0x48000002|&&docol) ? DOES_CODE1(_cfa) : 0; })
DOES_CODE(label)
/* this is a special version of DOES_CODE for use in dodoes */
#define DOES_CODE1(cfa) ((Xt *)(((long *)(cfa))[1]))
/* 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 Power architecture */
#define DOES_HANDLER_SIZE 8
#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 PPC, 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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>