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