[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Elk on SUN4



Patches for ELK on the SPARC.

This was my first sparc program, so it could be stupid in places, but it 
seems to work. Any and all bugs are my fault, and anything that works is
due to help from from Mark Weiser, John Gilmore, and Mitch Bradley's
kick-ass Sun-4 Forth system.

Some times it seems to try to allocate huge amounts of memory, and runs
out of stack space. I haven't tracked this bug down yet, but please let me
know if you do.

	-Don Hopkins (don@brillig.umd.edu)

* Changed files:

** Makefile:

Put the following definitions in the top level Makefile.
I changed the GENERIC and the SCHEME_DIR definitions to do the quoting
differently, because it was confusing the SunOS 3.2 compiler.

SCHEME_DIR= /f/net/scm/scm
GENERIC= char *
MACHTYPE= sparc                                        # vax 68k 386 sparc
DIR= -DDEF_LOAD_DIR=\\\"$(SCHEME_DIR)\\\"
GEN= -DGENERIC=\"$(GENERIC)\"
CFLAGS= $(INC) $(DIR) $(GEN) -O4                     # SunOS 4.0
LDFLAGS= -x                                         # 4.n BSD

** src/config.h:

Right before the end of the #ifdef sun section, add the following:

#  ifdef sparc
/* This is outside of this .h file cause the sun 3 3.2 preprocesser
   barfs on pragma, even if it's ifdef'ed out. */
#    include "sparc.h"
#  endif

I found I had to change the heap size to get the test programs to work
(I doubled it from 512 to 1024):

#define HEAP_SIZE            1024       /* in KBytes */

* New files:

** src/sparc.h:
    Required because SunOS 3.2 cpp barfs on "#pragma". Enclosed.

** src/stack.s.sparc:

    Implements stack manipulation code on sparc. Enclosed.

** src/alloca.s.sparc:

    Just an empty file. (Not enclosed. Buy me a beer, and I'll be 
    happy to supply you with a uuencoded compressed tar file with a 
    hand-made empty file that will work very well for this purpose.)

* Instructions:

Apply the changes to "Makefile" and "src/config.h".
Put the files "src/sparc.h" and "src/stack.s.sparc" in place.
Make an empty file, "src/alloca.s.sparc" (unless you'd rather buy me a beer).
Type "make" in the top level directory.

* Files:

** src/sparc.h

#include <alloca.h>
extern int saveenv(), jmpenv();
#pragma unknown_control_flow(saveenv,jmpenv)

** src/stack.s.sparc

/* int stksize();
 */
	.globl	_stksize
	.globl	_Special
_stksize:
	set	_stkbase,%o1
	ld	[%o1],%o1
	mov	%sp,%o0
	sub	%o1,%o0,%o0
	retl
	add	%o0,256,%o0

/* int saveenv(char* envbuf);
 */
	.globl	_saveenv
_saveenv:
	save	%sp,-96,%sp		/* new window */
					/* i0: char *envbuf */

	t	0x3			/* ST_FLUSH_WINDOWS trap */

	st	%i7,[%i0+4]		/* saved PC */
	mov	%y,%l0
	st	%l0,[%i0+8]		/* Y register */
#ifdef notdef
/* Illegal instruction. This doesn't seem to be necessary... */
	mov	%psr,%l0
	st	%l0,[%i0+12]		/* PSR register */
#endif
	st	%sp,[%i0+16]		/* SP register */
	st	%fp,[%i0+20]		/* FP register */

	st	%g1,[%i0+40]		/* save globals */
	st	%g2,[%i0+44]
	st	%g3,[%i0+48]
	st	%g4,[%i0+52]
	st	%g5,[%i0+56]
	st	%g6,[%i0+60]
	st	%g7,[%i0+64]

	mov	%sp,%l0			/* %l0 source */
	add	%i0,128,%l1		/* %l1 dest */
	set	_stkbase,%l2		/* %l2 limit */
	ld	[%l2],%l2

rep1:	/* copy stack to buf */
	ld	[%l0],%l3
	st	%l3,[%l1]
	inc	4,%l1
	cmp	%l0,%l2
	bleu	rep1
	inc	4,%l0

	sub	%l1,%l0,%l1		/* %l1 relocation offset */
	st	%l1,[%i0]		/* store at front of buffer */

	set	_Special,%i0		/* return value */
	ld	[%i0],%i0

	ret
	restore

/* dead jmpenv(const char* envbuf, int retcode);
 */
	.globl	_jmpenv
_jmpenv:
	save	%sp,-96,%sp		/* new window */
					/* i0: char *envbuf */
					/* i1: int retcode */

	t	0x3			/* ST_FLUSH_WINDOWS trap */

	ld	[%i0+16],%l1		/* l1: SP register */
	mov	%l1,%sp

	add	%i0,128,%l0		/* %l0: source */
					/* %l1: dest */
	set	_stkbase,%l2		/* %l2: limit */
	ld	[%l2],%l2

rep2:	/* copy buf to stack */
	ld	[%l0],%l3
	st	%l3,[%l1]
	inc	4,%l1
	cmp	%l1,%l2
	bleu	rep2
	inc	4,%l0

	ld	[%i0+40],%g1
	ld	[%i0+44],%g2
	ld	[%i0+48],%g3
	ld	[%i0+52],%g4
	ld	[%i0+56],%g5
	ld	[%i0+60],%g6
	ld	[%i0+64],%g6

	ld	[%i0+20],%fp
#ifdef notdef
	ld	[%i0+12],%l0
/* Illegal instruction. This doesn't seem to be necessary... */
	mov	%l0,%psr
#endif
	ld	[%i0+8],%l0
	mov	%l0,%y
	ld	[%i0+4],%i7

	nop			/* ??? */
	mov	%i1,%i0

	ret
	restore