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�.
--- 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

Reply via email to