IA-64 port

Gwenole Beauchesne gbeauchesne at mandrakesoft.com
Tue Dec 11 03:02:40 PST 2001


On Mon, 10 Dec 2001, John R. Daily wrote:

> I've been working to get kaffe working on Debian/ia64 via libffi,
> and I've run into a roadblock.

I too provided a port of the interpreter (no JIT then) in Mandrake Linux
8.1 for Itanium. Patches are attached, to be compiled with gcc3. libffi is
not required. Details will come later since I am a little sick at the
moment.

Second patch from release 11mdk attached.

Bye,
Gwenolé.
-------------- next part --------------
--- kaffe-snap/kaffe/kaffe/main.c.ia64	Sun Aug 19 16:41:34 2001
+++ kaffe-snap/kaffe/kaffe/main.c	Thu Nov 29 09:41:43 2001
@@ -301,6 +301,12 @@
 			printFullVersion();
 			exit(0);
 		}
+#if defined(__ia64__)
+		else if (strcmp(argv[i], "-ia32") == 0) {
+			i++;
+			/* FIXME: skip, case handled by the calle script */
+		}
+#endif
 		else if (strcmp(argv[i], "-classpath") == 0) {
 			i++;
 			if (argv[i] == 0) {
@@ -571,6 +577,9 @@
 	dprintf("	-help			Print this message\n");
 	dprintf("	-version		Print version number\n");
 	dprintf("	-fullversion		Print verbose version info\n");
+#if defined(__ia64__)
+	dprintf("	-ia32			Execute the ia32 version of Kaffe\n");
+#endif
 	dprintf("	-ss <size>		Maximum native stack size\n");
 	dprintf("	-mx <size> 		Maximum heap size\n");
 	dprintf("	-ms <size> 		Initial heap size\n");
--- kaffe-snap/kaffe/kaffevm/systems/unix-jthreads/jthread.c.ia64	Fri Jun 22 06:53:41 2001
+++ kaffe-snap/kaffe/kaffevm/systems/unix-jthreads/jthread.c	Thu Nov 29 09:41:43 2001
@@ -170,6 +170,16 @@
 #define GET_FP(E)       (((void**)(E))[FP_OFFSET])
 #define SET_FP(E, V)    ((void**)(E))[FP_OFFSET] = (V)
 
+/*
+ * Macros to set and extract backing store pointer from jmp_buf
+ * (IA-64 specific)
+ */
+#if defined(__ia64__)
+#define BSP_OFFSET	17
+#define GET_BSP(E)	(((void**)(E))[BSP_OFFSET])
+#define SET_BSP(E, V)	((void**)(E))[BSP_OFFSET] = (V)
+#endif
+
 /* Set the base pointer in a jmp_buf if we can (only a convenience) */
 #if defined(BP_OFFSET)
 #define SET_BP(E, V)    ((void**)(E))[BP_OFFSET] = (V)
@@ -1245,6 +1255,16 @@
 {
 	jthread *jtid; 
 	void	*oldstack, *newstack;
+#if defined(__ia64__)
+	void	*oldbsp, *newbsp;
+#endif
+	size_t   page_size;
+	
+	/* Adjust stack size */
+	page_size = getpagesize();
+	if (threadStackSize == 0)
+		threadStackSize = THREADSTACKSIZE;
+	threadStackSize = (threadStackSize + page_size - 1) & -page_size;
 
 	/*
 	 * Disable stop to protect the threadLock lock, and prevent
@@ -1254,7 +1274,7 @@
 	jthread_disable_stop();
 
 	jmutex_lock(&threadLock);
-        jtid = newThreadCtx(threadStackSize);
+	jtid = newThreadCtx(threadStackSize);
 	if (!jtid) {
 		jmutex_unlock(&threadLock);
 		jthread_enable_stop();
@@ -1289,7 +1309,7 @@
 	 *
 	 * To be safe, we immediately call a new function.
 	 */
-        if (JTHREAD_SETJMP(jtid->env)) {
+        if (JTHREAD_SETJMP(JTHREAD_ACCESS_JMPBUF(jtid, env))) {
 		/* new thread */
 		start_this_sucker_on_a_new_frame();
 		assert(!"Never!");
@@ -1300,34 +1320,57 @@
 	SAVE_FP(jtid->fpstate);
 #endif
 	/* set up context for new thread */
-	oldstack = GET_SP(jtid->env);
+	oldstack = GET_SP(JTHREAD_ACCESS_JMPBUF(jtid, env));
+#if defined(__ia64__)
+	oldbsp = GET_BSP(JTHREAD_ACCESS_JMPBUF(jtid, env));
+#endif
 
 #if defined(STACK_GROWS_UP)
 	newstack = jtid->stackBase+STACK_COPY;
 	memcpy(newstack-STACK_COPY, oldstack-STACK_COPY, STACK_COPY);
 #else /* !STACK_GROWS_UP */
-	newstack = jtid->stackEnd-STACK_COPY;
+	newstack = jtid->stackEnd;
+#if defined(__ia64__)
+	/*
+	 * The stack segment is split in the middle. The upper half is used
+	 * as backing store for the register stack which grows upward.
+	 * The lower half is used for the traditional memory stack which
+	 * grows downward. Both stacks start in the middle and grow outward
+	 * from each other.
+	 */
+	newstack -= (threadStackSize >> 1);
+	newbsp = newstack;
+	/* Make register stack 64-byte aligned */
+	if ((unsigned long)newbsp & 0x3f)
+		newbsp = newbsp + (0x40 - ((unsigned long)newbsp & 0x3f));
+	newbsp += STACK_COPY;
+	memcpy(newbsp-STACK_COPY, oldbsp-STACK_COPY, STACK_COPY);
+#endif
+	newstack -= STACK_COPY;
 	memcpy(newstack, oldstack, STACK_COPY);
 #endif /* !STACK_GROWS_UP */
 
 #if defined(NEED_STACK_ALIGN)
-        newstack = (void *) STACK_ALIGN(newstack);
+	newstack = (void *) STACK_ALIGN(newstack);
 #endif
 
-	SET_SP(jtid->env, newstack);
+	SET_SP(JTHREAD_ACCESS_JMPBUF(jtid, env), newstack);
+#if defined(__ia64__)
+	SET_BSP(JTHREAD_ACCESS_JMPBUF(jtid, env), newbsp);
+#endif
 
 #if defined(SET_BP)
 	/*
 	 * Clear the base pointer in the new thread's stack.
 	 * Nice for debugging, but not strictly necessary.
 	 */
-	SET_BP(jtid->env, 0);
+	SET_BP(JTHREAD_ACCESS_JMPBUF(jtid, env), 0);
 #endif
 
 
 #if defined(FP_OFFSET)
 	/* needed for: IRIX */
-	SET_FP(jtid->env, newstack + ((void *)GET_FP(jtid->env) - oldstack));
+	SET_FP(JTHREAD_ACCESS_JMPBUF(jtid, env), newstack + ((void *)GET_FP(JTHREAD_ACCESS_JMPBUF(jtid, env)) - oldstack));
 #endif
 
         resumeThread(jtid);
@@ -1574,10 +1617,9 @@
 #if defined(CONTEXT_SWITCH)
 				CONTEXT_SWITCH(lastThread, currentJThread);
 #else
-				if (JTHREAD_SETJMP(lastThread->env) == 0) {
-				    lastThread->restorePoint = 
-					GET_SP(lastThread->env);
-				    JTHREAD_LONGJMP(currentJThread->env, 1);
+				if (JTHREAD_SETJMP(JTHREAD_ACCESS_JMPBUF(lastThread, env)) == 0) {
+				    lastThread->restorePoint = GET_SP(JTHREAD_ACCESS_JMPBUF(lastThread, env));
+				    JTHREAD_LONGJMP(JTHREAD_ACCESS_JMPBUF(currentJThread, env), 1);
 				}
 #endif
 #if defined(LOAD_FP)
--- kaffe-snap/kaffe/kaffevm/systems/unix-jthreads/jthread.h.ia64	Wed Jun 21 09:07:35 2000
+++ kaffe-snap/kaffe/kaffevm/systems/unix-jthreads/jthread.h	Thu Nov 29 09:41:43 2001
@@ -90,7 +90,7 @@
 	 * used to hold the current Java thread
 	 */
 	void*				jlThread;
-	JTHREAD_JMPBUF			env;
+	JTHREAD_DECLARE_JMPBUF		(env);
 #if defined(SAVED_FP_SIZE)
 	char				fpstate[SAVED_FP_SIZE];
 #endif
--- kaffe-snap/kaffe/kaffevm/jni.c.ia64	Fri Jun 22 06:53:39 2001
+++ kaffe-snap/kaffe/kaffevm/jni.c	Thu Nov 29 09:41:43 2001
@@ -3502,7 +3502,7 @@
 		 * handling, as well as functions which only delay
 		 * external exceptions.
 		 */
-		JTHREAD_LONGJMP(frame->jbuf, 1);
+		JTHREAD_LONGJMP(JTHREAD_ACCESS_JMPBUF(frame, jbuf), 1);
 	}
 }
 
--- kaffe-snap/kaffe/kaffevm/exception.c.ia64	Fri Jun 22 06:53:39 2001
+++ kaffe-snap/kaffe/kaffevm/exception.c	Thu Nov 29 09:41:43 2001
@@ -432,12 +432,12 @@
 			if (res == true) {
 				unhand(ct)->needOnStack = STACK_HIGH;
 				frame->pc = einfo.handler;
-				JTHREAD_LONGJMP(frame->jbuf, 1);
+				JTHREAD_LONGJMP(JTHREAD_ACCESS_JMPBUF(frame, jbuf), 1);
 			}
 
 			/* If not here, exit monitor if synchronised. */
 			if (obj != 0 && (einfo.method->accflags & ACC_SYNCHRONISED) != 0) {
-				_slowUnlockMutexIfHeld(&obj->lock, frame->jbuf);
+				_slowUnlockMutexIfHeld(&obj->lock, JTHREAD_ACCESS_JMPBUF(frame, jbuf));
 			}
 		}
 	}
--- kaffe-snap/kaffe/kaffevm/exception.h.ia64	Fri Jun 22 06:53:39 2001
+++ kaffe-snap/kaffe/kaffevm/exception.h	Thu Nov 29 09:41:43 2001
@@ -38,7 +38,7 @@
 
 typedef struct _vmException {
 	struct _vmException*		prev;
-	JTHREAD_JMPBUF			jbuf;
+	JTHREAD_DECLARE_JMPBUF		(jbuf);
 	struct _methods*		meth;
 	u4				pc;
 	struct Hjava_lang_Object*	mobj;
--- kaffe-snap/kaffe/scripts/kaffe.in.ia64	Mon Oct 18 04:20:44 1999
+++ kaffe-snap/kaffe/scripts/kaffe.in	Thu Nov 29 09:41:43 2001
@@ -38,6 +38,20 @@
 : ${KAFFE_NATIVE_LIBRARY_DIR="@nativedir@"}
 : ${KAFFE_OLD_NATIVE_LIBRARY_DIR="$KAFFE_CLASSDIR/lib/@KAFFE_ARCHOS@"}
 
+if test x"$(uname -m)"x = x"ia64"x; then
+  # Use ia32 version of Kaffe, if requested
+  ia32mode=no
+  for arg in "$@"; do
+    [ -z "${arg/#-ia32/}" ] && ia32mode=yes
+  done
+  if test x"${ia32mode}"x = x"yes"x; then
+    KAFFE_TARGET_ARCH=$(echo ${KAFFE_LIBDIR/ia64/i?86} | sed -e "s/.*\(i.86\)/\1/")
+    KAFFE_LIBDIR=${KAFFE_LIBDIR/ia64/$KAFFE_TARGET_ARCH}
+    KAFFE_LIBEXECDIR=${KAFFE_LIBEXECDIR/ia64/$KAFFE_TARGET_ARCH}
+    KAFFE_NATIVE_LIBRARY_DIR=${KAFFE_NATIVE_LIBRARY_DIR/ia64/$KAFFE_TARGET_ARCH}
+  fi
+fi
+
 if test x"${KAFFEHOME+set}"x != x"set"x; then
   KAFFEHOME="@prefix@"
 fi
--- kaffe-snap/config/Makefile.am.ia64	Sun Aug 19 16:41:32 2001
+++ kaffe-snap/config/Makefile.am	Thu Nov 29 09:41:43 2001
@@ -60,6 +60,11 @@
 	arm/netbsd1/md.h \
 	arm/threads.h \
 	arm/trampolines.c \
+	ia64/common.h \
+	ia64/linux/md.c \
+	ia64/linux/md.h \
+	ia64/threads.h \
+	ia64/sysdepCallMethod.h \
 	i386/beos/config.frag \
 	i386/beos/jit-md.h \
 	i386/beos/jit3-md.h \
--- kaffe-snap/config/ia64/common.h.ia64	Thu Nov 29 09:41:43 2001
+++ kaffe-snap/config/ia64/common.h	Thu Nov 29 09:41:43 2001
@@ -0,0 +1,22 @@
+/*
+ * ia64/common.h
+ * Common IA-64 configuration information.
+ *
+ * Copyright (c) 2001
+ *	MandrakeSoft.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#ifndef __ia64_common_h
+#define __ia64_common_h
+
+#define NEED_STACK_ALIGN
+#define STACK_ALIGN(p)  ((((unsigned long)(p)) & 15) ^ (unsigned long)(p))
+
+#if NEED_sysdepCallMethod
+#include "sysdepCallMethod.h"
+#endif
+
+#endif
--- kaffe-snap/config/ia64/linux/config.frag.ia64	Thu Nov 29 09:41:43 2001
+++ kaffe-snap/config/ia64/linux/config.frag	Thu Nov 29 09:41:43 2001
@@ -0,0 +1,10 @@
+#
+# ia64/Linux configuration
+#
+Khost_cpu=ia64
+Khost_os=linux
+
+if test x"$with_threads" = x"linux-threads" ; then
+	CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+	VM_LIBS="$VM_LIBS -lpthread"
+fi
--- kaffe-snap/config/ia64/linux/md.c.ia64	Thu Nov 29 09:41:43 2001
+++ kaffe-snap/config/ia64/linux/md.c	Thu Nov 29 09:41:43 2001
@@ -0,0 +1,302 @@
+/*
+ * ia64/linux/md.c
+ * Linux IA-64 specific functions.
+ *
+ * Copyright (c) 2001
+ *	MandrakeSoft.  All rights reserved.
+ *
+ * Copyright (C) 2000
+ *  Silicon Graphics, Inc.  All Rights Reserved.
+ *  IA64_context_{save,restore} functions from State Threads Library
+ *
+ * Copyright (c) 2001
+ *	Transvirtual Technologies, Inc.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+
+void
+init_md(void)
+{
+#if defined(M_MMAP_MAX) && defined(HAVE_MALLOPT)
+	mallopt(M_MMAP_MAX, 0);
+#endif
+}
+
+/*
+ * Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ * The internal __jmp_buf layout is different from one used
+ * by setjmp()/longjmp().
+ *
+ *       Offset   Description
+ *       ------   -----------
+ *       0x000    stack pointer (r12)
+ *       0x008    gp (r1)
+ *       0x010    caller's unat
+ *       0x018    fpsr
+ *       0x020    r4
+ *       0x028    r5
+ *       0x030    r6
+ *       0x038    r7
+ *       0x040    rp (b0)
+ *       0x048    b1
+ *       0x050    b2
+ *       0x058    b3
+ *       0x060    b4
+ *       0x068    b5
+ *       0x070    ar.pfs
+ *       0x078    ar.lc
+ *       0x080    pr
+ *       0x088    ar.bsp
+ *       0x090    ar.unat
+ *       0x098    &__jmp_buf
+ *       0x0a0    ar.rsc
+ *       0x0a8    ar.rnat
+ *       0x0b0     f2
+ *       0x0c0     f3
+ *       0x0d0     f4
+ *       0x0e0     f5
+ *       0x0f0    f16
+ *       0x100    f17
+ *       0x110    f18
+ *       0x120    f19
+ *       0x130    f20
+ *       0x130    f21
+ *       0x140    f22
+ *       0x150    f23
+ *       0x160    f24
+ *       0x170    f25
+ *       0x180    f26
+ *       0x190    f27
+ *       0x1a0    f28
+ *       0x1b0    f29
+ *       0x1c0    f30
+ *       0x1d0    f31
+ *
+ * Note that the address of __jmp_buf is saved but not used: we assume
+ * that the jmp_buf data structure is never moved around in memory.
+ */
+
+/*
+ * Implemented according to "IA-64 Software Conventions and Runtime
+ * Architecture Guide", Chapter 10: "Context Management".
+ */
+
+        /* IA64_context_save(__jmp_buf env) */
+        asm("
+        .text
+        .align 32
+        .global IA64_context_save#
+        .proc IA64_context_save#
+IA64_context_save:
+        alloc r14 = ar.pfs,1,0,0,0
+        mov r16 = ar.unat
+        ;;
+        mov r17 = ar.fpsr
+        mov r2 = in0
+        add r3 = 8,in0
+        ;;
+        st8.spill.nta [r2] = sp,16    // r12 (sp)
+        st8.spill.nta [r3] = gp,16    // r1  (gp)
+        ;;
+        st8.nta [r2] = r16,16         // save caller's unat
+        st8.nta [r3] = r17,16         // save fpsr
+        add r8 = 0xb0,in0
+        ;;   
+        st8.spill.nta [r2] = r4,16    // r4
+        st8.spill.nta [r3] = r5,16    // r5
+        add r9 = 0xc0,in0
+        ;;
+        stf.spill.nta [r8] = f2,32
+        stf.spill.nta [r9] = f3,32
+        mov r15 = rp
+        ;;
+        stf.spill.nta [r8] = f4,32
+        stf.spill.nta [r9] = f5,32
+        mov r17 = b1
+        ;;
+        stf.spill.nta [r8] = f16,32
+        stf.spill.nta [r9] = f17,32
+        mov r18 = b2
+        ;;
+        stf.spill.nta [r8] = f18,32
+        stf.spill.nta [r9] = f19,32
+        mov r19 = b3
+        ;;
+        stf.spill.nta [r8] = f20,32
+        stf.spill.nta [r9] = f21,32
+        mov r20 = b4
+        ;;
+        stf.spill.nta [r8] = f22,32
+        stf.spill.nta [r9] = f23,32
+        mov r21 = b5
+        ;;
+        stf.spill.nta [r8] = f24,32
+        stf.spill.nta [r9] = f25,32
+        mov r22 = ar.lc
+        ;;
+        stf.spill.nta [r8] = f26,32
+        stf.spill.nta [r9] = f27,32
+        mov r24 = pr
+        ;;
+        stf.spill.nta [r8] = f28,32
+        stf.spill.nta [r9] = f29,32
+        ;;
+        stf.spill.nta [r8] = f30
+        stf.spill.nta [r9] = f31
+        st8.spill.nta [r2] = r6,16    // r6
+        st8.spill.nta [r3] = r7,16    // r7
+        ;;
+        mov r23 = ar.bsp
+        mov r25 = ar.unat
+        st8.nta [r2] = r15,16         // b0
+        st8.nta [r3] = r17,16         // b1
+        ;;
+        st8.nta [r2] = r18,16         // b2
+        st8.nta [r3] = r19,16         // b3
+        mov r26 = ar.rsc
+        ;;
+        st8.nta [r2] = r20,16         // b4
+        st8.nta [r3] = r21,16         // b5
+        ;;
+        st8.nta [r2] = r14,16         // ar.pfs
+        st8.nta [r3] = r22,16         // ar.lc
+        ;;
+        st8.nta [r2] = r24,16         // pr
+        st8.nta [r3] = r23,16         // ar.bsp
+        ;;
+        st8.nta [r2] = r25,16         // ar.unat
+        st8.nta [r3] = in0,16         // &__jmp_buf (just in case)
+        ;;
+        st8.nta [r2] = r26            // ar.rsc
+        ;;
+        flushrs                       // flush dirty regs to backing store
+        ;;
+        and r27 = ~0x3,r26            // clear ar.rsc.mode
+        ;;
+        mov ar.rsc = r27              // put RSE in enforced lazy mode
+        ;;
+        mov r28 = ar.rnat
+        ;;
+        st8.nta [r3] = r28            // ar.rnat
+        mov ar.rsc = r26              // restore ar.rsc
+        ;;
+        mov r8 = 0
+        br.ret.sptk.few b0
+        .endp IA64_context_save#
+        ");
+
+        /* IA64_context_restore(__jmp_buf env, int val) */
+        asm("
+        .text
+        .align 32
+        .global IA64_context_restore#
+        .proc IA64_context_restore#
+IA64_context_restore:
+        alloc r8 = ar.pfs,2,0,0,0
+        add r2 = 0x88,in0             // r2 <- &jmpbuf.ar_bsp
+        mov r16 = ar.rsc
+        ;;
+        flushrs                       // flush dirty regs to backing store
+        ;;
+        and r17 = ~0x3,r16            // clear ar.rsc.mode
+        ;;
+        mov ar.rsc = r17              // put RSE in enforced lazy mode
+        ;;
+        invala                        // invalidate the ALAT
+        ;;
+        ld8 r23 = [r2],8              // r23 <- jmpbuf.ar_bsp
+        ;;
+        mov ar.bspstore = r23         // write BSPSTORE
+        ld8 r25 = [r2],24             // r25 <- jmpbuf.ar_unat
+        ;;
+        ld8 r26 = [r2],-8             // r26 <- jmpbuf.ar_rnat
+        ;;
+        mov ar.rnat = r26             // write RNAT
+        ld8 r27 = [r2]                // r27 <- jmpbuf.ar_rsc
+        ;;
+        mov ar.rsc = r27              // write RSE control
+        mov r2 = in0
+        ;;
+        mov ar.unat = r25             // write ar.unat
+        add r3 = 8,in0
+        ;;
+        ld8.fill.nta sp = [r2],16     // r12 (sp)
+        ld8.fill.nta gp = [r3],16     // r1  (gp)
+        ;;
+        ld8.nta r16 = [r2],16         // caller's unat
+        ld8.nta r17 = [r3],16         // fpsr
+        ;;
+        ld8.fill.nta r4 = [r2],16     // r4
+        ld8.fill.nta r5 = [r3],16     // r5
+        ;;
+        ld8.fill.nta r6 = [r2],16     // r6
+        ld8.fill.nta r7 = [r3],16     // r7
+        ;;
+        mov ar.unat = r16             // restore caller's unat
+        mov ar.fpsr = r17             // restore fpsr
+        ;;
+        ld8.nta r16 = [r2],16         // b0
+        ld8.nta r17 = [r3],16         // b1
+        ;;
+        ld8.nta r18 = [r2],16         // b2
+        ld8.nta r19 = [r3],16         // b3
+        ;;
+        ld8.nta r20 = [r2],16         // b4
+        ld8.nta r21 = [r3],16         // b5
+        ;;
+        ld8.nta r11 = [r2],16         // ar.pfs
+        ld8.nta r22 = [r3],72         // ar.lc
+        ;;
+        ld8.nta r24 = [r2],48         // pr
+        mov b0 = r16
+        ;;
+        ldf.fill.nta f2 = [r2],32
+        ldf.fill.nta f3 = [r3],32
+        mov b1 = r17
+        ;;
+        ldf.fill.nta f4 = [r2],32
+        ldf.fill.nta f5 = [r3],32
+        mov b2 = r18
+        ;;
+        ldf.fill.nta f16 = [r2],32
+        ldf.fill.nta f17 = [r3],32
+        mov b3 = r19
+        ;;
+        ldf.fill.nta f18 = [r2],32
+        ldf.fill.nta f19 = [r3],32
+        mov b4 = r20
+        ;;
+        ldf.fill.nta f20 = [r2],32
+        ldf.fill.nta f21 = [r3],32
+        mov b5 = r21
+        ;;
+        ldf.fill.nta f22 = [r2],32
+        ldf.fill.nta f23 = [r3],32
+        mov ar.lc = r22
+        ;;
+        ldf.fill.nta f24 = [r2],32
+        ldf.fill.nta f25 = [r3],32
+        cmp.eq p6,p7 = 0,in1
+        ;;
+        ldf.fill.nta f26 = [r2],32
+        ldf.fill.nta f27 = [r3],32
+        mov ar.pfs = r11
+        ;;
+        ldf.fill.nta f28 = [r2],32
+        ldf.fill.nta f29 = [r3],32
+        ;;
+        ldf.fill.nta f30 = [r2]
+        ldf.fill.nta f31 = [r3]
+(p6)    mov r8 = 1
+(p7)    mov r8 = in1
+        mov pr = r24,-1
+        br.ret.sptk.few b0
+        .endp IA64_context_restore#
+        ");
--- kaffe-snap/config/ia64/linux/md.h.ia64	Thu Nov 29 09:41:43 2001
+++ kaffe-snap/config/ia64/linux/md.h	Thu Nov 29 10:18:05 2001
@@ -0,0 +1,57 @@
+/*
+ * ia64/linux/md.h
+ * Linux IA-64 configuration information.
+ *
+ * Copyright (c) 2001
+ *	MandrakeSoft.  All rights reserved.
+ *
+ * Copyright (c) 2001
+ *	Transvirtual Technologies, Inc.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#ifndef __ia64_linux_md_h
+#define __ia64_linux_md_h
+
+#include <setjmp.h>
+#include "ia64/common.h"
+#include "ia64/threads.h"
+
+/* Linux requires a little initialisation */
+extern void init_md(void);
+#define	INIT_MD() init_md()
+
+extern int IA64_context_save(jmp_buf env);
+extern void IA64_context_restore(jmp_buf env, int val);
+
+#if 0
+#undef JTHREAD_SETJMP
+#define JTHREAD_SETJMP(env)			IA64_context_save((env))
+#undef JTHREAD_LONGJMP
+#define JTHREAD_LONGJMP(env, val)		IA64_context_restore((env), (val))
+#endif
+
+#define SIGNAL_ARGS(sig, scp)			int sig, siginfo_t *sip, struct sigcontext *scp
+#define SIGNAL_CONTEXT_POINTER(scp)		struct sigcontext *scp
+#define GET_SIGNAL_CONTEXT_POINTER(sc)		(sc)
+#define SIGNAL_PC(scp)				((scp)->sc_ip & ~0x3ULL)
+
+#ifdef HAVE_IA64INTRIN_H
+
+#include <ia64intrin.h>
+#undef COMPARE_AND_EXCHANGE
+#define COMPARE_AND_EXCHANGE(A, O, N) \
+	__sync_bool_compare_and_swap((A), (O), (N))
+
+#else
+
+#include <asm/atomic.h>
+#undef COMPARE_AND_EXCHANGE
+#define COMPARE_AND_EXCHANGE(A, O, N) \
+	(cmpxchg((A), (O), (N)) == (O))
+		
+#endif /* HAVE_IA64INTRIN_H */
+
+#endif
--- kaffe-snap/config/ia64/sysdepCallMethod.h.ia64	Thu Nov 29 09:41:43 2001
+++ kaffe-snap/config/ia64/sysdepCallMethod.h	Thu Nov 29 09:41:43 2001
@@ -0,0 +1,249 @@
+/*
+ * ia64/sysdepCallMethod.h
+ * Dynamically build function calls using IA-64 SVR4 ABI.
+ *
+ * Copyright (c) 2001
+ *	MandrakeSoft.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+/* This define will cause callMethodV and callMethodA to avoid
+   introducing unused slots after jlongs and jdoubles.  */
+#ifndef NO_HOLES
+# define NO_HOLES 1
+#endif
+
+/* This define will cause callMethodV and callMethodA to promote every
+   integer type to a 64bit word, and every float to double, so that
+   every value can be loaded as a single 64bit word.  It also causes
+   float arguments to be marked as 'D'.  */
+#ifndef PROMOTE_TO_64bits
+# define PROMOTE_TO_64bits 1
+#endif
+ 
+#ifndef PROMOTE_jfloat2jdouble
+# define PROMOTE_jfloat2jdouble 0
+#endif
+
+/* ARG_TYPE is the type of a register used for passing arguments.  */
+#define ARG_TYPE	long
+
+/* ARG_TYPES is a parameter list declaration for a function type
+   that takes all possible arguments in registers.  */
+#define ARG_TYPES	ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE
+
+/* ARG_LIST is the argument list for such a function.  */
+#define ARG_LIST	a0, a1, a2, a3, a4, a5, a6, a7
+
+/* GPR_ARGS is the number of GPR (integer) registers for passing
+   arguments.  */
+#define GPR_ARGS	8
+
+/* FPR_ARGS is the number of FPR (float) registers for passing
+   arguments.  */
+#define FPR_ARGS	8
+
+/* ARG_DISPLACEMENT is the offset between the beginning of a
+   variable-sized array, allocated in the stack, and the position of
+   the first argument that can't be passed in a register.  */
+#define ARG_DISPLACEMENT	0
+
+/* ARG_GPR a case label and a statement that arranges for one integer
+   argument to be passed. */
+#define ARG_GPR(N) \
+    case N+1: a##N = gpr[N];
+
+/* ARG_FPR a case label and a statement that arranges for one float
+   argument to be passed. */
+#define ARG_FPR(N) \
+    case N+1: d##N = fpr[N];
+
+
+/* Make a call to a native or Java (JIT) method.  This assembly code should
+   build a standard C call using the passed call information.  By its
+   nature this is highly processor specific.  This function is mandatory
+   for both JIT and Interpreter (since stubs have now been deprecated).  */
+static inline void sysdepCallMethod(callMethodInfo* call)
+{
+    void *func = call->function;
+    jvalue *callargs = call->args;
+    char *calltype = call->calltype;
+    jvalue *args = callargs;
+    jvalue *last = &callargs[call->nrargs];
+    int nr_gpr = 0;
+    int nr_fpr = 0;
+    int nr_stack = 0;
+
+    unsigned long *stack;
+    unsigned long *gpr;
+    double *fpr;
+
+    /* Compute gpr[], fpr[] and stack[] arrays' size */
+    while (args != last) {
+	  switch (calltype[(args++) - callargs]) {
+	  case 'F':
+	  case 'D':
+		if (nr_fpr < FPR_ARGS) {
+		  nr_fpr++;
+		  nr_gpr++;
+		}
+		else
+		  nr_stack++;
+		break;
+		
+	  default:
+		if (nr_gpr < GPR_ARGS)
+		  nr_gpr++;
+		else
+		  nr_stack++;
+		break;
+	  }
+	}
+
+    /* Allocate all arrays with one big alloca() */
+    {
+	  int nr = nr_gpr + nr_fpr + nr_stack;
+	  
+	  /* stack, if used, must be 16 bytes aligned */
+	  if (nr_stack)
+		nr = (nr + 1) & ~1;
+
+	  /* stack[] is in called parameters area.  */
+	  stack = __builtin_alloca (8 * nr);
+
+	  /* gpr[] and fpr[] are in callee local variable area.  */
+	  gpr = stack + nr_stack;
+	  fpr = (double *)(gpr + nr_gpr);
+	  
+	  /* if __buildin_alloc() does not handle link-area, skip it.  */
+	  stack += ARG_DISPLACEMENT;
+    }
+
+    /* build gpr[], fpr[] and stack[] arrays */
+    nr_gpr = 0;
+	nr_fpr = 0;
+	nr_stack = 0;
+	
+    args = callargs;
+    while (args != last) {
+	  switch (calltype[args - callargs]) {
+	  case 'F': {
+		jvalue value = { .d = (double)args->f };
+		if (nr_fpr < FPR_ARGS) {
+		  fpr[nr_fpr++] = value.d;
+		  gpr[nr_gpr++] = value.j;
+		}
+		else {
+		  *(float *)stack = value.d;
+		  stack++;
+		}
+		break;
+	  }
+	  
+	  case 'D': {
+		jvalue value = { .d = args->d };
+	    if (nr_fpr < FPR_ARGS) {
+		  fpr[nr_fpr++] = value.d;
+		  gpr[nr_gpr++] = value.j;
+	    }
+		else {
+		  *(double *)stack = value.d;
+		  stack++;
+		}
+		break;
+	  }
+	  
+	  default:
+		if (nr_gpr < GPR_ARGS)
+		  gpr[nr_gpr++] = args->j;
+		else
+		  *stack++ = args->j;
+	  }
+	  args++;
+    }
+
+    {
+	  register ARG_TYPE a0 asm("out0");
+	  register ARG_TYPE a1 asm("out1");
+	  register ARG_TYPE a2 asm("out2");
+	  register ARG_TYPE a3 asm("out3");
+	  register ARG_TYPE a4 asm("out4");
+	  register ARG_TYPE a5 asm("out5");
+	  register ARG_TYPE a6 asm("out6");
+	  register ARG_TYPE a7 asm("out7");
+	  
+	  register double d0 asm("f8");
+	  register double d1 asm("f9");
+	  register double d2 asm("f10");
+	  register double d3 asm("f11");
+	  register double d4 asm("f12");
+	  register double d5 asm("f13");
+	  register double d6 asm("f14");
+	  register double d7 asm("f15");
+	  
+	  /* load FPR registers from fpr[] */
+	  switch (nr_fpr) {
+		ARG_FPR(7);
+		ARG_FPR(6);
+		ARG_FPR(5);
+		ARG_FPR(4);
+		ARG_FPR(3);
+		ARG_FPR(2);
+		ARG_FPR(1);
+		ARG_FPR(0);
+	  case 0:;
+	  }
+
+	  /* load GPR registers from gpr[] */
+	  switch (nr_gpr) {
+		ARG_GPR(7);
+		ARG_GPR(6);
+		ARG_GPR(5);
+		ARG_GPR(4);
+		ARG_GPR(3);
+		ARG_GPR(2);
+		ARG_GPR(1);
+		ARG_GPR(0);
+	  case 0:;
+	  }
+	  
+	  /* Ensure that the assignments to f* registers won't be optimized away. */
+	  asm ("" ::
+		   "f" (d0), "f" (d1), "f" (d2), "f" (d3),
+		   "f" (d4), "f" (d5), "f" (d6), "f" (d7));
+
+	  switch(call->retsize) {
+	  case 0:
+	    /* Must be void.  */
+	    ((void (*)(ARG_TYPES))(func))(ARG_LIST);
+	    break;
+		
+	  case 1:
+	    if (call->rettype == 'F')
+		  call->ret->f = ((jfloat (*)(ARG_TYPES))(func))(ARG_LIST);
+	    else /* Must be 32-bit or smaller int.  */
+		  call->ret->i = ((jint (*)(ARG_TYPES))(func))(ARG_LIST);
+	    break;
+
+	  default:
+	    /* It could've been `case 2;', but then we'd get an additional cmp
+	     * that we don't really need.  */
+	    if (call->rettype == 'D')
+		  call->ret->d = ((jdouble (*)(ARG_TYPES))(func))(ARG_LIST);
+	    else /* Must be jlong.  */
+		  call->ret->j = ((jlong (*)(ARG_TYPES))(func))(ARG_LIST);
+	    break;
+	  }
+    }
+}
+
+#undef ARG_TYPE
+#undef ARG_TYPES
+#undef ARG_LIST
+#undef GPR_ARGS
+#undef FPR_ARGS
+#undef ARG_DISPLACEMENT
+#undef ARG_GPR
+#undef ARG_FPR
--- kaffe-snap/config/ia64/threads.h.ia64	Thu Nov 29 09:41:43 2001
+++ kaffe-snap/config/ia64/threads.h	Thu Nov 29 09:41:43 2001
@@ -0,0 +1,33 @@
+/*
+ * ia64/threads.h
+ * IA-64 threading information.
+ *
+ * Copyright (c) 2001
+ *	MandrakeSoft.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#ifndef __ia64_threads_h
+#define __ia64_threads_h
+
+/**/
+/* Thread handling */
+/**/
+#define	USE_INTERNAL_THREADS
+
+/*
+ * Set a default size for the stack.
+ * Includes register stack size
+ */
+#define	THREADSTACKSIZE	(128 * 1024)
+
+/*
+ * Stack offset.
+ * This is the offset into the setjmp buffer where the stack pointer is
+ * stored.  This may be different with different OSes.
+ */
+#define	SP_OFFSET	0
+
+#endif
--- kaffe-snap/config/Makefile.in.ia64	Sun Aug 19 16:41:32 2001
+++ kaffe-snap/config/Makefile.in	Thu Nov 29 09:41:43 2001
@@ -188,6 +188,11 @@
 	arm/netbsd1/md.h \
 	arm/threads.h \
 	arm/trampolines.c \
+	ia64/common.h \
+	ia64/linux/md.c \
+	ia64/linux/md.h \
+	ia64/threads.h \
+	ia64/sysdepCallMethod.h \
 	i386/beos/config.frag \
 	i386/beos/jit-md.h \
 	i386/beos/jit3-md.h \
--- kaffe-snap/config/config-setjmp.h.ia64	Mon Aug  6 06:06:50 2001
+++ kaffe-snap/config/config-setjmp.h	Thu Nov 29 09:41:43 2001
@@ -90,4 +90,12 @@
 
 #endif
 
+#if defined(__ia64__)
+#define JTHREAD_DECLARE_JMPBUF(x)	JTHREAD_JMPBUF x; void * x##_pad
+#define JTHREAD_ACCESS_JMPBUF(x, y)	(__typeof__((x)->y[0]) *) ((((unsigned long)&(x)->y) + 15) & -16)
+#else
+#define JTHREAD_DECLARE_JMPBUF(x)	JTHREAD_JMPBUF x
+#define JTHREAD_ACCESS_JMPBUF(x, y)	(x)->y
+#endif
+
 #endif


More information about the kaffe mailing list