0.9.0.7:
authorChristophe Rhodes <csr21@cam.ac.uk>
Sat, 30 Apr 2005 09:40:41 +0000 (09:40 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Sat, 30 Apr 2005 09:40:41 +0000 (09:40 +0000)
Begin MIPS megamerge from Thiemo Suifer ("More MIPS-related patches"
sbcl-devel 2005-04-23)

This patch merges those pieces which only touch MIPS code, and
as such I can't really test in a non-trivial way.
... don't use nl4 (pa-flag) in assembly routines
Message-ID: <20050422211550.GB10767@hattusa.textio>
... fix my thinko in the fixnum/sb-xc:fixnum backend immediate-sc
routine
Message-ID: <20050422212056.GC10767@hattusa.textio>
... use linux-nm.  (Other backends maybe should do the same)
Message-ID: <20050422213247.GE10767@hattusa.textio>
... lotso mips runtime cleanups
Message-ID: <20050422224553.GJ10767@hattusa.textio>
... an untested mips spinlock implementation
Message-ID: <20050422224830.GK10767@hattusa.textio>
... mips-assem.S fixes
Message-ID: <20050422232020.GL10767@hattusa.textio>
... more runtime fixes
Message-ID: <20050422233014.GM10767@hattusa.textio>
... load delay fixes for ldso-stubs
Message-ID: <20050422233501.GO10767@hattusa.textio>

12 files changed:
src/assembly/mips/assem-rtns.lisp
src/compiler/mips/call.lisp
src/compiler/mips/vm.lisp
src/runtime/Config.mips-linux
src/runtime/linux-nm
src/runtime/mips-arch.c
src/runtime/mips-arch.h
src/runtime/mips-assem.S
src/runtime/mips-linux-os.c
src/runtime/mips-linux-os.h
tools-for-build/ldso-stubs.lisp
version.lisp-expr

index c172655..0e3a85c 100644 (file)
@@ -17,7 +17,7 @@
      ;; These are just needed to facilitate the transfer
      (:temp lip interior-reg lip-offset)
      (:temp count any-reg nl2-offset)
-     (:temp dst any-reg nl4-offset)
+     (:temp dst any-reg nl3-offset)
      (:temp temp descriptor-reg l0-offset)
 
      ;; These are needed so we can get at the register args.
index 51c5f5f..8e21f1e 100644 (file)
@@ -1041,7 +1041,7 @@ default-value-8
   (:temporary (:sc any-reg :offset nl0-offset) result)
   (:temporary (:sc any-reg :offset nl1-offset) count)
   (:temporary (:sc any-reg :offset nl2-offset) src)
-  (:temporary (:sc any-reg :offset nl4-offset) dst)
+  (:temporary (:sc any-reg :offset nl3-offset) dst)
   (:temporary (:sc descriptor-reg :offset l0-offset) temp)
   (:info fixed)
   (:generator 20
index 631e039..819af13 100644 (file)
      (if (static-symbol-p value)
         (sc-number-or-lose 'immediate)
         nil))
-    ((integer #.sb!xc:most-negative-fixnum sb!xc:most-positive-fixnum)
+    ((or (integer #.sb!xc:most-negative-fixnum #.sb!xc:most-positive-fixnum)
+        system-area-pointer character)
      (sc-number-or-lose 'immediate))
     (system-area-pointer
      (sc-number-or-lose 'immediate))
index b853340..3f2abb5 100644 (file)
 CFLAGS += -Dmips -g
 LD = ld
 LINKFLAGS = -v -g -O2
-NM = nm -p
+NM = ./linux-nm
 
 ASSEM_SRC = mips-assem.S ldso-stubs.S
-ARCH_SRC = mips-arch.c #undefineds.c
+ARCH_SRC = mips-arch.c
 
 OS_SRC = linux-os.c mips-linux-os.c os-common.c 
 OS_LIBS= -ldl
index f85e7e5..2804e90 100755 (executable)
@@ -1,2 +1,2 @@
 #!/bin/sh
-nm -p "$@" | grep -v " [FUtdb?] "
+nm -p "$@" | grep -v " [AabcdgIiNnrstUuvw?-] "
index 1e442b4..4c91b74 100644 (file)
 #include "breakpoint.h"
 #include "monitor.h"
 
-void arch_init()
+#include "genesis/constants.h"
+
+void
+arch_init()
 {
     return;
 }
 
-os_vm_address_t arch_get_bad_addr(int signam, siginfo_t *siginfo, os_context_t *context)
+os_vm_address_t
+arch_get_bad_addr(int signam, siginfo_t *siginfo, os_context_t *context)
 {
     /* Classic CMUCL comment:
 
@@ -34,15 +38,15 @@ os_vm_address_t arch_get_bad_addr(int signam, siginfo_t *siginfo, os_context_t *
     return (os_vm_address_t) siginfo->si_addr;
 }
 
-unsigned long 
-emulate_branch(os_context_t *context, unsigned long inst)
+static unsigned int
+emulate_branch(os_context_t *context, unsigned int inst)
 {
-    long opcode = inst >> 26;
-    long r1 = (inst >> 21) & 0x1f;
-    long r2 = (inst >> 16) & 0x1f;
-    long bdisp = ((inst&(1<<15)) ? inst | (-1 << 16) : inst&0x7fff) << 2;
-    long jdisp = (inst&0x3ffffff) << 2;
-    long disp = 0;
+    unsigned int opcode = inst >> 26;
+    unsigned int r1 = (inst >> 21) & 0x1f;
+    unsigned int r2 = (inst >> 16) & 0x1f;
+    unsigned int bdisp = ((inst&(1<<15)) ? inst | (-1 << 16) : inst&0x7fff) << 2;
+    unsigned int jdisp = (inst&0x3ffffff) << 2;
+    unsigned int disp = 0;
 
     switch(opcode) {
     case 0x1: /* bltz, bgez, bltzal, bgezal */
@@ -58,12 +62,14 @@ emulate_branch(os_context_t *context, unsigned long inst)
        case 0x10: /* bltzal */
            if(*os_context_register_addr(context, r1) < 0)
                disp = bdisp;
-           *os_context_register_addr(context, 31) = *os_context_pc_addr(context) + 4;
+           *os_context_register_addr(context, 31)
+               = *os_context_pc_addr(context) + 4;
            break;
        case 0x11: /* bgezal */
            if(*os_context_register_addr(context, r1) >= 0)
                disp = bdisp;
-           *os_context_register_addr(context, 31) = *os_context_pc_addr(context) + 4;
+           *os_context_register_addr(context, 31)
+               = *os_context_pc_addr(context) + 4;
            break;
        }
        break;
@@ -92,13 +98,15 @@ emulate_branch(os_context_t *context, unsigned long inst)
        break;
     case 0x3: /* jal */
        disp = jdisp;
-       *os_context_register_addr(context, 31) = *os_context_pc_addr(context) + 4;
+       *os_context_register_addr(context, 31)
+           = *os_context_pc_addr(context) + 4;
        break;
     }
-    return (*os_context_pc_addr(context) + disp);
+    return *os_context_pc_addr(context) + disp;
 }
 
-void arch_skip_instruction(os_context_t *context)
+void
+arch_skip_instruction(os_context_t *context)
 {
     /* Skip the offending instruction */
     if (os_context_bd_cause(context)) {
@@ -109,17 +117,17 @@ void arch_skip_instruction(os_context_t *context)
            better (it can hardly be worse).  We lose() to remind the
            porter to review this code.  -- CSR, 2002-09-06 */
        lose("bd_cause branch taken; review code for new OS?\n");
-        *os_context_pc_addr(context) = 
-           emulate_branch(context, 
-                          *(unsigned long *) *os_context_pc_addr(context));
-    }
-    else
+        *os_context_pc_addr(context)
+           = emulate_branch(context, *os_context_pc_addr(context));
+    } else
         *os_context_pc_addr(context) += 4;
 
-    os_flush_icache((os_vm_address_t) *os_context_pc_addr(context), sizeof(unsigned long));
+    os_flush_icache((os_vm_address_t)*os_context_pc_addr(context),
+                   sizeof(unsigned int));
 }
 
-unsigned char *arch_internal_error_arguments(os_context_t *context)
+unsigned char *
+arch_internal_error_arguments(os_context_t *context)
 {
     if (os_context_bd_cause(context))
        return (unsigned char *)(*os_context_pc_addr(context) + 8);
@@ -127,41 +135,44 @@ unsigned char *arch_internal_error_arguments(os_context_t *context)
        return (unsigned char *)(*os_context_pc_addr(context) + 4);
 }
 
-boolean arch_pseudo_atomic_atomic(os_context_t *context)
+boolean
+arch_pseudo_atomic_atomic(os_context_t *context)
 {
     return *os_context_register_addr(context, reg_ALLOC) & 1;
 }
 
-#define PSEUDO_ATOMIC_INTERRUPTED_BIAS 0x7f000000
-
-void arch_set_pseudo_atomic_interrupted(os_context_t *context)
+void
+arch_set_pseudo_atomic_interrupted(os_context_t *context)
 {
-    *os_context_register_addr(context, reg_NL4) |= 1<<31;
+    *os_context_register_addr(context, reg_NL4) |= -1LL<<31;
 }
 
-unsigned long arch_install_breakpoint(void *pc)
+unsigned long
+arch_install_breakpoint(void *pc)
 {
-    unsigned long *ptr = (unsigned long *)pc;
-    unsigned long result = *ptr;
-    *ptr = (trap_Breakpoint << 16) | 0xd;
+    unsigned int *ptr = (unsigned int *)pc;
+    unsigned long result = (unsigned long) *ptr;
 
-    os_flush_icache((os_vm_address_t)ptr, sizeof(unsigned long));
+    *ptr = (trap_Breakpoint << 16) | 0xd;
+    os_flush_icache((os_vm_address_t)ptr, sizeof(unsigned int));
 
     return result;
 }
 
-void arch_remove_breakpoint(void *pc, unsigned long orig_inst)
+void
+arch_remove_breakpoint(void *pc, unsigned long orig_inst)
 {
-    *(unsigned long *)pc = orig_inst;
+    unsigned int *ptr = (unsigned int *)pc;
 
-    os_flush_icache((os_vm_address_t)pc, sizeof(unsigned long));
+    *ptr = (unsigned int) orig_inst;
+    os_flush_icache((os_vm_address_t)ptr, sizeof(unsigned int));
 }
 
-static unsigned long *skipped_break_addr, displaced_after_inst;
+static unsigned int *skipped_break_addr, displaced_after_inst;
 static sigset_t orig_sigmask;
 
-void arch_do_displaced_inst(os_context_t *context,
-                           unsigned int orig_inst)
+void
+arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
 {
     unsigned int *pc = (unsigned int *)*os_context_pc_addr(context);
     unsigned int *break_pc, *next_pc;
@@ -182,71 +193,78 @@ void arch_do_displaced_inst(os_context_t *context,
     }
 
     /* Put the original instruction back. */
-    *break_pc = orig_inst;
-    os_flush_icache((os_vm_address_t)break_pc, sizeof(unsigned int));
+    arch_remove_breakpoint(break_pc, orig_inst);
     skipped_break_addr = break_pc;
 
     /* Figure out where it goes. */
     opcode = next_inst >> 26;
-    if (opcode == 1 || ((opcode & 0x3c) == 0x4) || ((next_inst & 0xf00e0000) == 0x80000000)) {
-        
-        next_pc = emulate_branch(context, next_inst);
-    }
+    if (opcode == 1 || ((opcode & 0x3c) == 0x4) || ((next_inst & 0xf00e0000) == 0x80000000))
+        next_pc = (unsigned int *)emulate_branch(context, next_inst);
     else
        next_pc = pc+1;
 
-    displaced_after_inst = *next_pc;
-    *next_pc = (trap_AfterBreakpoint << 16) | 0xd;
-    os_flush_icache((os_vm_address_t)next_pc, sizeof(unsigned int));
+    displaced_after_inst = arch_install_breakpoint(next_pc);
 }
 
-static void sigtrap_handler(int signal, siginfo_t *info, void *void_context)
+static void
+sigill_handler(int signal, siginfo_t *info, void *void_context)
+{
+    os_context_t *context = arch_os_get_context(&void_context);
+
+    fake_foreign_function_call(context);
+    monitor_or_something();
+}
+
+static void
+sigtrap_handler(int signal, siginfo_t *info, void *void_context)
 {
     os_context_t *context = arch_os_get_context(&void_context);
     sigset_t *mask;
     unsigned int code;
-    /* Don't disallow recursive breakpoint traps.  Otherwise, we can't */
-    /* use debugger breakpoints anywhere in here. */
+    sigset_t ss;
+
+    /* Don't disallow recursive breakpoint traps.  Otherwise, we can't
+       use debugger breakpoints anywhere in here. */
     mask = os_context_sigmask_addr(context);
     sigprocmask(SIG_SETMASK, mask, NULL);
     code = ((*(int *) (*os_context_pc_addr(context))) >> 16) & 0x1f;
 
     switch (code) {
+    case trap_Halt:
+       fake_foreign_function_call(context);
+       lose("%%primitive halt called; the party is over.\n");
+
     case trap_PendingInterrupt:
        arch_skip_instruction(context);
+       sigemptyset(&ss);
+       sigaddset(&ss,SIGTRAP);
+       sigprocmask(SIG_UNBLOCK,&ss,0);
        interrupt_handle_pending(context);
        break;
-       
-    case trap_Halt:
-       fake_foreign_function_call(context);
-       lose("%%primitive halt called; the party is over.\n");
-       
+
     case trap_Error:
     case trap_Cerror:
        interrupt_internal_error(signal, info, context, code==trap_Cerror);
        break;
-       
+
     case trap_Breakpoint:
        handle_breakpoint(signal, info, context);
        break;
-       
+
     case trap_FunEndBreakpoint:
        *os_context_pc_addr(context) = (int)handle_fun_end_breakpoint(signal, info, context);
+       os_flush_icache((os_vm_address_t)*os_context_pc_addr(context), sizeof(unsigned int));
        break;
-       
+
     case trap_AfterBreakpoint:
-       *skipped_break_addr = (trap_Breakpoint << 16) | 0xd;
-       os_flush_icache((os_vm_address_t)skipped_break_addr,
-                       sizeof(unsigned long));
-       skipped_break_addr = NULL;
-       *(unsigned long *)(*os_context_pc_addr(context)) = displaced_after_inst;
-       os_flush_icache((os_vm_address_t) *os_context_pc_addr(context), sizeof(unsigned int));
+       arch_remove_breakpoint(os_context_pc_addr(context), displaced_after_inst);
+       displaced_after_inst = arch_install_breakpoint(skipped_break_addr);
        *os_context_sigmask_addr(context) = orig_sigmask;
        break;
 
     case 0x10:
-       /* Clear the flag */
-       *os_context_register_addr(context, reg_NL4) &= 0x7fffffff;
+       /* Clear the pseudo-atomic flag */
+       *os_context_register_addr(context, reg_NL4) &= ~(-1LL<<31);
        arch_skip_instruction(context);
        interrupt_handle_pending(context);
        return;
@@ -257,22 +275,21 @@ static void sigtrap_handler(int signal, siginfo_t *info, void *void_context)
     }
 }
 
-/* FIXME: We must have one of these somewhere. Also, export
-   N-FIXNUM-TAG-BITS from Lispland and use it rather than 2 here. */
-#define FIXNUM_VALUE(lispobj) (((int)lispobj)>>2)
+#define FIXNUM_VALUE(lispobj) (((int)lispobj) >> N_FIXNUM_TAG_BITS)
 
-void sigfpe_handler(int signal, siginfo_t *info, void *void_context)
+static void
+sigfpe_handler(int signal, siginfo_t *info, void *void_context)
 {
-    unsigned long bad_inst;
-    unsigned int op, rs, rt, rd, funct, dest;
+    unsigned int bad_inst;
+    unsigned int op, rs, rt, rd, funct, dest = 32;
     int immed;
-    long result;
+    unsigned int result;
     os_context_t *context = arch_os_get_context(&void_context);
 
     if (os_context_bd_cause(context))
-        bad_inst = *(unsigned long *)(*os_context_pc_addr(context) + 4);
+        bad_inst = *(unsigned int *)(*os_context_pc_addr(context) + 4);
     else
-        bad_inst = *(unsigned long *)(*os_context_pc_addr(context));
+        bad_inst = *(unsigned int *)(*os_context_pc_addr(context));
 
     op = (bad_inst >> 26) & 0x3f;
     rs = (bad_inst >> 21) & 0x1f;
@@ -291,8 +308,7 @@ void sigfpe_handler(int signal, siginfo_t *info, void *void_context)
            /* Check to see if this is really a pa_interrupted hit */
            if (rs == reg_ALLOC && rt == reg_NL4) {
                *os_context_register_addr(context, reg_ALLOC)
-                   += (*os_context_register_addr(context, reg_NL4)
-                       - PSEUDO_ATOMIC_INTERRUPTED_BIAS);
+                   += *os_context_register_addr(context, reg_NL4) &= ~(-1LL<<31);
                arch_skip_instruction(context);
                interrupt_handle_pending(context);
                return;
@@ -307,10 +323,6 @@ void sigfpe_handler(int signal, siginfo_t *info, void *void_context)
                - FIXNUM_VALUE(*os_context_register_addr(context, rt));
            dest = rd;
            break;
-           
-       default:
-           dest = 32;
-           break;
        }
        break;
        
@@ -318,10 +330,6 @@ void sigfpe_handler(int signal, siginfo_t *info, void *void_context)
        result = FIXNUM_VALUE(*os_context_register_addr(context,rs)) + (immed>>2);
        dest = rt;
        break;
-       
-    default:
-       dest = 32;
-       break;
     }
     
     if (dest < 32) {
@@ -331,8 +339,8 @@ void sigfpe_handler(int signal, siginfo_t *info, void *void_context)
         *os_context_register_addr(context,dest) = alloc_number(result);
 
        *os_context_register_addr(context, reg_ALLOC) =
-           (unsigned long) dynamic_space_free_pointer;
-       
+           (unsigned int) dynamic_space_free_pointer;
+
         arch_skip_instruction(context);
        
     }
@@ -340,22 +348,26 @@ void sigfpe_handler(int signal, siginfo_t *info, void *void_context)
         interrupt_handle_now(signal, info, context);
 }
 
-void arch_install_interrupt_handlers()
+void
+arch_install_interrupt_handlers()
 {    
+    undoably_install_low_level_interrupt_handler(SIGILL,sigill_handler);
     undoably_install_low_level_interrupt_handler(SIGTRAP,sigtrap_handler);
     undoably_install_low_level_interrupt_handler(SIGFPE,sigfpe_handler);
 }
 
 extern lispobj call_into_lisp(lispobj fun, lispobj *args, int nargs);
 
-lispobj funcall0(lispobj function)
+lispobj
+funcall0(lispobj function)
 {
     lispobj *args = current_control_stack_pointer;
 
     return call_into_lisp(function, args, 0);
 }
 
-lispobj funcall1(lispobj function, lispobj arg0)
+lispobj
+funcall1(lispobj function, lispobj arg0)
 {
     lispobj *args = current_control_stack_pointer;
 
@@ -365,7 +377,8 @@ lispobj funcall1(lispobj function, lispobj arg0)
     return call_into_lisp(function, args, 1);
 }
 
-lispobj funcall2(lispobj function, lispobj arg0, lispobj arg1)
+lispobj
+funcall2(lispobj function, lispobj arg0, lispobj arg1)
 {
     lispobj *args = current_control_stack_pointer;
 
@@ -376,7 +389,8 @@ lispobj funcall2(lispobj function, lispobj arg0, lispobj arg1)
     return call_into_lisp(function, args, 2);
 }
 
-lispobj funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
+lispobj
+funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
 {
     lispobj *args = current_control_stack_pointer;
 
@@ -387,4 +401,3 @@ lispobj funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
 
     return call_into_lisp(function, args, 3);
 }
-
index 7cde570..ee04c3e 100644 (file)
@@ -5,7 +5,37 @@
 static inline void 
 get_spinlock(volatile lispobj *word, long value)
 {
-    *word=value;               /* FIXME for threads */
+#ifdef LISP_FEATURE_SB_THREAD
+    unsigned long __old = (volatile lispobj)*word;
+    unsigned long __prev;
+    int __cmp;
+
+    __asm__ __volatile__ (
+       "       .set push\n"
+       "       .set mips2\n"
+       "       .set noreorder\n"
+       "1:     ll      %[__prev],%[__mem]\n"
+       "       bne     %[__prev],%[__old],2f\n"
+       "        li     %[__cmp],0\n"
+       "       move    %[__cmp],%[__new]\n"
+       "       sc      %[__cmp],%[__mem]\n"
+       "       beqz    %[__cmp],1b\n"
+       "        nop\n"
+       "       sync\n"
+       "2:\n"
+       "       .set pop"
+       : [__prev] "=&r" (__prev),
+         [__cmp] "=&r" (__cmp)
+       : [__mem] "R" (*word),
+         [__old] "r" (__old),
+         [__new] "r" (value)
+       : "memory");
+
+    if (!cmp) 
+       lose("recursive get_spinlock: 0x%x,%d\n", word, value);
+#else /* LISP_FEATURE_SB_THREAD */
+    *word=value;
+#endif
 }
 
 static inline void
index 5bf5448..b22bbd7 100644 (file)
 #define ra $31
 
 /*
+ * LEAF - declare leaf routine
+ */
+#define        LEAF(symbol)                                    \
+               .globl  symbol;                         \
+               .align  2;                              \
+               .type   symbol,@function;               \
+               .ent    symbol,0;                       \
+symbol:                .frame  sp,0,ra
+
+/*
  * NESTED - declare nested routine entry point
  */
 #define        NESTED(symbol, framesize, rpc)                  \
@@ -56,6 +66,21 @@ symbol:              .frame  sp, framesize, rpc
                .end    function;                       \
                .size   function,.-function
 
+/*
+ * EXPORT - export definition of symbol
+ */
+#define EXPORT(symbol)                                 \
+               .globl  symbol;                         \
+symbol:
+
+/*
+ * FEXPORT - export definition of a function symbol
+ */
+#define FEXPORT(symbol)                                        \
+               .globl  symbol;                         \
+               .type   symbol,@function;               \
+symbol:
+
 
        .text
        
@@ -64,51 +89,44 @@ symbol:             .frame  sp, framesize, rpc
  */
 #define framesize 16*4
        NESTED(call_into_lisp, framesize, ra)
+       .set    noreorder
+       .cpload t9
+       .set    reorder
        subu    sp, framesize
+
        /* Save all the C regs. */
-       .mask   0xd0ff0000, -4
-       sw      ra, framesize(sp)
-       sw      s8, framesize-4(sp)
-       sw      gp, framesize-8(sp)
-       sw      s7, framesize-12(sp)
-       sw      s6, framesize-16(sp)
-       sw      s5, framesize-20(sp)
-       sw      s4, framesize-24(sp)
-       sw      s3, framesize-28(sp)
-       sw      s2, framesize-32(sp)
-       sw      s1, framesize-36(sp)
-       sw      s0, framesize-40(sp)
-
-       /* Clear descriptor regs */
-       move    t0, zero
-       move    t1, zero
-       move    t2, zero
-       move    t3, zero
-       move    t4, zero
-       move    t5, zero
-       move    t6, zero
-       move    t7, zero
-       move    t8, zero
-       move    s0, zero
-       move    s1, zero
-       move    s2, zero
-       move    s3, zero
-       move    ra, zero
+       .mask   0xc0ff0000, -8
+       sw      ra, framesize-8(sp)
+       sw      s8, framesize-12(sp)
+       /* No .cprestore, we don't want automatic gp restauration. */
+       sw      gp, framesize-16(sp)
+       sw      s7, framesize-20(sp)
+       sw      s6, framesize-24(sp)
+       sw      s5, framesize-28(sp)
+       sw      s4, framesize-32(sp)
+       sw      s3, framesize-36(sp)
+       sw      s2, framesize-40(sp)
+       sw      s1, framesize-44(sp)
+       sw      s0, framesize-48(sp)
 
        li      reg_NIL, NIL
 
-       /* Start pseudo-atomic. */
+       /* Clear unsaved boxed descriptor regs */
+       li      reg_FDEFN, 0            # t6
+       li      reg_L1, 0               # t8
+
+       /* Turn on pseudo-atomic. */
        .set    noreorder
        li      reg_NL4, 0
        li      reg_ALLOC, 1
         .set    reorder
 
-       /* No longer in foreign call. */
+       /* Mark us as in Lisp land. */
        sw      zero, foreign_function_call_active
 
        /* Load the allocation pointer, preserving the low-bit of alloc */
        lw      reg_BSP, dynamic_space_free_pointer
-       add     reg_ALLOC, reg_BSP
+       addu    reg_ALLOC, reg_BSP
 
        /* Load the rest of the LISP state. */
        lw      reg_BSP, current_binding_stack_pointer
@@ -117,12 +135,10 @@ symbol:           .frame  sp, framesize, rpc
 
        /* Check for interrupt */
         .set    noreorder
-       bgez    reg_NL4, pa1
-       nop
+       bgez    reg_NL4, 1f
+        subu   reg_ALLOC, 1
        break   0x10
-pa1:
-       subu    reg_ALLOC, 1
-       .set    reorder
+1:     .set    reorder
 
        /* Pass in args */
        move    reg_LEXENV, a0
@@ -158,51 +174,51 @@ mipsmungelra:
 lra:
        .word   RETURN_PC_HEADER_WIDETAG
 
-       /* Multiple value return spot, clear stack */
+       /* Multiple value return spot, clear stack. */
        move    reg_CSP, reg_OCFP
-       nop
+        nop
+
+       /* Single value return spot. */
 
-       /* Set pseudo-atomic flag. */
+       /* Pass one return value back to C land. */ 
+       move    v0, reg_A0      # reg_CFUNC
+
+       /* Nested lisp -> C calls may have clobbered gp. */
+       lw      gp, framesize-16(sp)
+
+       /* Set the pseudo-atomic flag. */
        li      reg_NL4, 0
        addu    reg_ALLOC, 1
        .set    reorder
 
-       /* Save LISP registers. */
+       /* Save LISP state. */
        subu    reg_NL0, reg_ALLOC, 1
        sw      reg_NL0, dynamic_space_free_pointer
        sw      reg_BSP, current_binding_stack_pointer
        sw      reg_CSP, current_control_stack_pointer
        sw      reg_CFP, current_control_frame_pointer
 
-       /* Pass one return value back to C land. */ 
-       /* v0 is reg_ALLOC in this new world, so do this after saving
-           reg_ALLOC in dynamic_space_free_pointer */
-       move    v0, reg_A0
-
-       /* Back in foreign function call */
-       sw      reg_CFP, foreign_function_call_active
+       /* Mark us as in C land. */
+       sw      reg_CSP, foreign_function_call_active
 
        /* Check for interrupt */
        .set    noreorder
-       bgez    reg_NL4, pa2
-       nop
+       bgez    reg_NL4, 1f
+        subu   reg_ALLOC, 1
        break   0x10
-pa2:
-       subu    reg_ALLOC, 1
-       .set    reorder
+1:     .set    reorder
 
        /* Restore C regs */
-       lw      ra, framesize(sp)
-       lw      s8, framesize-4(sp)
-       lw      gp, framesize-8(sp)
-       lw      s7, framesize-12(sp)
-       lw      s6, framesize-16(sp)
-       lw      s5, framesize-20(sp)
-       lw      s4, framesize-24(sp)
-       lw      s3, framesize-28(sp)
-       lw      s2, framesize-32(sp)
-       lw      s1, framesize-36(sp)
-       lw      s0, framesize-40(sp)
+       lw      ra, framesize-8(sp)
+       lw      s8, framesize-12(sp)
+       lw      s7, framesize-20(sp)
+       lw      s6, framesize-24(sp)
+       lw      s5, framesize-28(sp)
+       lw      s4, framesize-32(sp)
+       lw      s3, framesize-36(sp)
+       lw      s2, framesize-40(sp)
+       lw      s1, framesize-44(sp)
+       lw      s0, framesize-48(sp)
 
        /* Restore C stack. */
        addu    sp, framesize
@@ -215,23 +231,28 @@ pa2:
 /*
  * Transfering control from Lisp into C
  */
-       .globl  call_into_c
-       .align  2
-       .type   call_into_c,@function
-       .ent    call_into_c,0
-call_into_c:
-       /* Set up a stack frame. */
+       NESTED(call_into_c, 0, ra)
+       /* The stack frame was already set up from lisp. We have
+          to fake the correct gp value for this function, though. */
+       .set    noreorder
+       .set    noat
+       lui     gp, %hi(_gp_disp)
+       addiu   gp, %lo(_gp_disp)
+       lui     reg_NL3, %hi(call_into_c)
+       addiu   reg_NL3, %lo(call_into_c)
+       addu    gp, reg_NL3
+       .set    at
+       .set    reorder
+
        move    reg_OCFP, reg_CFP
        move    reg_CFP, reg_CSP
        addu    reg_CSP, reg_CFP, 32
-       sw      reg_OCFP, 0(reg_CFP)
-       subu    reg_NL4, reg_LIP, reg_CODE
-       addu    reg_NL4, OTHER_POINTER_LOWTAG
-       sw      reg_NL4, 4(reg_CFP)
-       sw      reg_CODE, 8(reg_CFP)
-        sw      gp, 12(reg_CFP)
 
-       /* Note: the C stack is already set up. */
+       subu    reg_LIP, reg_CODE
+       addu    reg_LIP, OTHER_POINTER_LOWTAG
+       sw      reg_LIP, (reg_CFP)
+       sw      reg_CODE, 4(reg_CFP)
+       sw      gp, 8(reg_CFP)
 
        /* Set the pseudo-atomic flag. */
        .set    noreorder
@@ -239,9 +260,9 @@ call_into_c:
        addu    reg_ALLOC, 1
        .set    reorder
 
-       /* Save lisp state. */
-       subu    t0, reg_ALLOC, 1
-       sw      t0, dynamic_space_free_pointer
+       /* Save LISP state. */
+       subu    reg_A0, reg_ALLOC, 1
+       sw      reg_A0, dynamic_space_free_pointer
        sw      reg_BSP, current_binding_stack_pointer
        sw      reg_CSP, current_control_stack_pointer
        sw      reg_CFP, current_control_frame_pointer
@@ -249,36 +270,31 @@ call_into_c:
        /* Mark us as in C land. */
        sw      reg_CSP, foreign_function_call_active
 
-       /* Were we interrupted? */
+       /* Check for interrupt */
        .set    noreorder
-       bgez    reg_NL4, pa3
-       nop
+       bgez    reg_NL4, 1f
+        subu   reg_ALLOC, 1
        break   0x10
-pa3:
-       subu    reg_ALLOC, 1
-       .set    reorder
+1:     .set    reorder
 
        /* Into C land we go. */
        move    t9, reg_CFUNC
        jalr    t9
-       nop
 
-       lw      gp, 12(reg_CFP)
+       lw      gp, 8(reg_CFP)
        
-       /* Clear unsaved descriptor regs */
-       move    t0, zero
-       move    t1, zero
-       move    t2, zero
-       move    t3, zero
-       move    t4, zero
-       move    t5, zero
-       move    t6, zero
-       move    t7, zero
-       move    t8, zero
-       move    s0, zero
-       move    s2, zero
-       move    s3, zero
-       move    ra, zero
+       li      reg_NIL, NIL
+
+       /* Clear unsaved boxed descriptor regs */
+       li      reg_A0, 0               # t0
+       li      reg_A1, 0               # t1
+       li      reg_A2, 0               # t2
+       li      reg_A3, 0               # t3
+       li      reg_A4, 0               # t4
+       li      reg_A5, 0               # t5
+       li      reg_FDEFN, 0            # t6
+       li      reg_LEXENV, 0           # t7
+       li      reg_L1, 0               # t8
 
        /* Turn on pseudo-atomic. */
        .set    noreorder
@@ -286,27 +302,27 @@ pa3:
        li      reg_ALLOC, 1
        .set    reorder
 
-       /* Mark us at in Lisp land. */
+       /* Mark us as in Lisp land. */
        sw      zero, foreign_function_call_active
 
-       /* Restore ALLOC, preserving pseudo-atomic-atomic */
-       lw      a0, dynamic_space_free_pointer
-       addu    reg_ALLOC, a0
+       /* Load the allocation pointer, preserving the low-bit of alloc */
+       lw      reg_BSP, dynamic_space_free_pointer
+       addu    reg_ALLOC, reg_BSP
+
+       lw      reg_BSP, current_binding_stack_pointer
+
+       /* Restore LRA & CODE */
+       lw      reg_LIP, (reg_CFP)
+       lw      reg_CODE, 4(reg_CFP)
+       subu    reg_LIP, OTHER_POINTER_LOWTAG
+       addu    reg_LIP, reg_CODE
 
        /* Check for interrupt */
        .set    noreorder
-       bgez    reg_NL4, pa4
-       nop
+       bgez    reg_NL4, 1f
+        subu   reg_ALLOC, 1
        break   0x10
-pa4:
-       subu    reg_ALLOC, 1
-       .set    reorder
-
-       /* Restore LRA & CODE (they may have been GC'ed) */
-       lw      reg_CODE, 8(reg_CFP)
-       lw      a0, 4(reg_CFP)
-       subu    a0, OTHER_POINTER_LOWTAG
-       addu    reg_LIP, reg_CODE, a0
+1:     .set    reorder
 
        /* Reset the lisp stack. */
        /* Note: OCFP and CFP are in saved regs. */
@@ -314,56 +330,47 @@ pa4:
        move    reg_CFP, reg_OCFP
 
        /* Return to LISP. */
-       j       reg_LIP
-
+       jr      reg_LIP
        END(call_into_c)
 
-       .globl  start_of_tramps
-start_of_tramps:
+       EXPORT(start_of_tramps)
 
 /*
  * The undefined-function trampoline.
  */
-        .globl  undefined_tramp
-        .ent    undefined_tramp
-undefined_tramp:
-        break   10
-        .byte    4
-        .byte    UNDEFINED_FUN_ERROR
-        .byte    254
-        .byte    (0xc0 + sc_DescriptorReg)
-        .byte    1
-        .align 2
-        .end    undefined_tramp
+       LEAF(undefined_tramp)
+        break  10
+        .byte  4
+        .byte  UNDEFINED_FUN_ERROR
+        .byte  254
+        .byte  (0xc0 + sc_DescriptorReg)
+        .byte  1
+       .align  2
+       END(undefined_tramp)
 
 /*
  * The closure trampoline.
  */
-        .globl  closure_tramp
-        .ent    closure_tramp
-closure_tramp:
-        lw      reg_LEXENV, FDEFN_FUN_OFFSET(reg_FDEFN)
-        lw      reg_L0, CLOSURE_FUN_OFFSET(reg_LEXENV)
-        addu    reg_LIP, reg_L0, SIMPLE_FUN_CODE_OFFSET
-        j       reg_LIP
-        .end    closure_tramp
-
-       .globl  end_of_tramps
-end_of_tramps:
+       LEAF(closure_tramp)
+        lw     reg_LEXENV, FDEFN_FUN_OFFSET(reg_FDEFN)
+        lw     reg_L0, CLOSURE_FUN_OFFSET(reg_LEXENV)
+        addu   reg_LIP, reg_L0, SIMPLE_FUN_CODE_OFFSET
+        jr     reg_LIP
+       END(closure_tramp)
 
+       EXPORT(end_of_tramps)
 
 /*
  * Function-end breakpoint magic.
  */
-
-       .align  2
+       LEAF(fun_end_breakpoint_guts)
        .set    noreorder
-       .globl  function_end_breakpoint_guts
-fun_end_breakpoint_guts:
+       .align  3
        .word   RETURN_PC_HEADER_WIDETAG
        
-       beq     zero, zero, 1f
-       nop
+       b       multiple_value_return
+        nop
+
        move    reg_OCFP, reg_CSP
        addu    reg_CSP, 4
        li      reg_NARGS, 4
@@ -372,14 +379,14 @@ fun_end_breakpoint_guts:
        move    reg_A3, reg_NIL
        move    reg_A4, reg_NIL
        move    reg_A5, reg_NIL
-1:
 
-       .globl  fun_end_breakpoint_trap
-fun_end_breakpoint_trap:
+multiple_value_return:
+
+       FEXPORT(fun_end_breakpoint_trap)
        break   trap_FunEndBreakpoint
-       beq     zero, zero, 1b
-       nop
+1:     b       1b
+        nop
 
-       .globl  fun_end_breakpoint_end
-fun_end_breakpoint_end:
+       EXPORT(fun_end_breakpoint_end)
        .set    reorder
+       END(fun_end_breakpoint_guts)
index 1b9bed7..2cda92c 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "validate.h"
 /* for cacheflush() */
-#include <asm/cachectl.h>
+#include <sys/cachectl.h>
+
+#include "validate.h"
 
-/* FIXME: For CAUSEF_BD */
-#include <asm/mipsregs.h>
 size_t os_vm_page_size;
 
+int
+arch_os_thread_init(struct thread *thread)
+{
 #ifdef LISP_FEATURE_SB_THREAD
-#error "Define threading support functions"
-#else
-int arch_os_thread_init(struct thread *thread) {
+#warning "Check threading support functions"
+#endif
     return 1;                  /* success */
 }
-int arch_os_thread_cleanup(struct thread *thread) {
+
+int
+arch_os_thread_cleanup(struct thread *thread)
+{
+#ifdef LISP_FEATURE_SB_THREAD
+#warning "Check threading support functions"
+#endif
     return 1;                  /* success */
 }
-#endif
 
 os_context_register_t *
 os_context_register_addr(os_context_t *context, int offset)
 {
-    if (offset == 0) {
-       /* KLUDGE: I'm not sure, but it's possible that Linux puts the
-           contents of the Processor Status Word in the (wired-zero)
-           slot in the mcontext. In any case, the following is
-           unlikely to do any harm: */
-       static unsigned long long zero;
-       zero = 0;
-       return &zero;
-    } else {
-       return &(((struct sigcontext *) &(context->uc_mcontext))->sc_regs[offset]);
-    }
+    return &(((struct sigcontext *)&(context->uc_mcontext))->sc_regs[offset]);
 }
 
 os_context_register_t *
 os_context_pc_addr(os_context_t *context)
 {
     /* Why do I get all the silly ports? -- CSR, 2002-08-11 */
-    return &(((struct sigcontext *) &(context->uc_mcontext))->sc_pc);
+    return &(((struct sigcontext *)&(context->uc_mcontext))->sc_pc);
 }
 
 sigset_t *
@@ -82,6 +78,12 @@ os_context_sigmask_addr(os_context_t *context)
     return &(context->uc_sigmask);
 }
 
+unsigned int
+os_context_fp_control(os_context_t *context)
+{
+    /* FIXME: Probably do something. */
+}
+
 void 
 os_restore_fp_control(os_context_t *context)
 {
@@ -99,6 +101,8 @@ os_context_bd_cause(os_context_t *context)
        loop" where a (BREAK 16) not in a branch delay slot would have
        CAUSEF_BD filled. So, we comment
 
+       #include <asm/mipsregs.h>
+
         return (((struct sigcontext *) &(context->uc_mcontext))->sc_cause 
                & CAUSEF_BD);
 
index 02d53f0..c28d9be 100644 (file)
@@ -8,7 +8,7 @@ static inline os_context_t *arch_os_get_context(void **void_context) {
     return (os_context_t *) *void_context;
 }
 
-unsigned long os_context_fp_control(os_context_t *context);
+unsigned int os_context_fp_control(os_context_t *context);
 void os_restore_fp_control(os_context_t *context);
 unsigned int os_context_bd_cause(os_context_t *context);
 
index 5b81bf5..132c44a 100644 (file)
@@ -46,7 +46,9 @@ ldso_stub__~A: ;                                \\
 /* This is an automatically generated file, please do not hand-edit it.
  * See the program tools-for-build/ldso-stubs.lisp. */
 
+#ifndef LANGUAGE_ASSEMBLY
 #define LANGUAGE_ASSEMBLY
+#endif
 #include \"sbcl.h\""
 
 #!+sparc "
@@ -123,17 +125,19 @@ ldso_stub__ ## fct ## $lazy_ptr:          @\\
        .type   ldso_stub__ ## fct,@function ; \\
        .ent    ldso_stub__ ## fct ;           \\
 ldso_stub__ ## fct: ;                  \\
+       .set noat ;                    \\
        addiu $29,-48 ;                \\
        sw $28,40($29) ;               \\
        sw $31,44($29) ;               \\
        lw $25,64($29) ;               \\
+       lw  $1,68($29) ;               \\
        sw $25,16($29) ;               \\
-       lw $25,68($29) ;               \\
-       sw $25,20($29) ;               \\
+       sw  $1,20($29) ;               \\
        lw $25,72($29) ;               \\
+       lw  $1,76($29) ;               \\
        sw $25,24($29) ;               \\
-       lw $25,76($29) ;               \\
-       sw $25,28($29) ;               \\
+       sw  $1,28($29) ;               \\
+       .set at ;                      \\
        la $25, fct ;                  \\
        jalr $25 ;                     \\
        lw $31,44($29) ;               \\
index a65c404..dcfe46e 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.9.0.6"
+"0.9.0.7"