From: Christophe Rhodes Date: Sat, 30 Apr 2005 09:40:41 +0000 (+0000) Subject: 0.9.0.7: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=5e2b057871cf47c795c75106899f5fb05dc3397e;p=sbcl.git 0.9.0.7: 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> --- diff --git a/src/assembly/mips/assem-rtns.lisp b/src/assembly/mips/assem-rtns.lisp index c172655..0e3a85c 100644 --- a/src/assembly/mips/assem-rtns.lisp +++ b/src/assembly/mips/assem-rtns.lisp @@ -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. diff --git a/src/compiler/mips/call.lisp b/src/compiler/mips/call.lisp index 51c5f5f..8e21f1e 100644 --- a/src/compiler/mips/call.lisp +++ b/src/compiler/mips/call.lisp @@ -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 diff --git a/src/compiler/mips/vm.lisp b/src/compiler/mips/vm.lisp index 631e039..819af13 100644 --- a/src/compiler/mips/vm.lisp +++ b/src/compiler/mips/vm.lisp @@ -286,7 +286,8 @@ (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)) diff --git a/src/runtime/Config.mips-linux b/src/runtime/Config.mips-linux index b853340..3f2abb5 100644 --- a/src/runtime/Config.mips-linux +++ b/src/runtime/Config.mips-linux @@ -10,10 +10,10 @@ 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 diff --git a/src/runtime/linux-nm b/src/runtime/linux-nm index f85e7e5..2804e90 100755 --- a/src/runtime/linux-nm +++ b/src/runtime/linux-nm @@ -1,2 +1,2 @@ #!/bin/sh -nm -p "$@" | grep -v " [FUtdb?] " +nm -p "$@" | grep -v " [AabcdgIiNnrstUuvw?-] " diff --git a/src/runtime/mips-arch.c b/src/runtime/mips-arch.c index 1e442b4..4c91b74 100644 --- a/src/runtime/mips-arch.c +++ b/src/runtime/mips-arch.c @@ -21,12 +21,16 @@ #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); } - diff --git a/src/runtime/mips-arch.h b/src/runtime/mips-arch.h index 7cde570..ee04c3e 100644 --- a/src/runtime/mips-arch.h +++ b/src/runtime/mips-arch.h @@ -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 diff --git a/src/runtime/mips-assem.S b/src/runtime/mips-assem.S index 5bf5448..b22bbd7 100644 --- a/src/runtime/mips-assem.S +++ b/src/runtime/mips-assem.S @@ -40,6 +40,16 @@ #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) diff --git a/src/runtime/mips-linux-os.c b/src/runtime/mips-linux-os.c index 1b9bed7..2cda92c 100644 --- a/src/runtime/mips-linux-os.c +++ b/src/runtime/mips-linux-os.c @@ -34,46 +34,42 @@ #include #include -#include "validate.h" /* for cacheflush() */ -#include +#include + +#include "validate.h" -/* FIXME: For CAUSEF_BD */ -#include 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 + return (((struct sigcontext *) &(context->uc_mcontext))->sc_cause & CAUSEF_BD); diff --git a/src/runtime/mips-linux-os.h b/src/runtime/mips-linux-os.h index 02d53f0..c28d9be 100644 --- a/src/runtime/mips-linux-os.h +++ b/src/runtime/mips-linux-os.h @@ -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); diff --git a/tools-for-build/ldso-stubs.lisp b/tools-for-build/ldso-stubs.lisp index 5b81bf5..132c44a 100644 --- a/tools-for-build/ldso-stubs.lisp +++ b/tools-for-build/ldso-stubs.lisp @@ -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) ; \\ diff --git a/version.lisp-expr b/version.lisp-expr index a65c404..dcfe46e 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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"