;; 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.
(: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
(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))
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
#!/bin/sh
-nm -p "$@" | grep -v " [FUtdb?] "
+nm -p "$@" | grep -v " [AabcdgIiNnrstUuvw?-] "
#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:
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 */
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;
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)) {
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);
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;
}
/* 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;
}
}
-/* 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;
/* 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;
- FIXNUM_VALUE(*os_context_register_addr(context, rt));
dest = rd;
break;
-
- default:
- dest = 32;
- break;
}
break;
result = FIXNUM_VALUE(*os_context_register_addr(context,rs)) + (immed>>2);
dest = rt;
break;
-
- default:
- dest = 32;
- break;
}
if (dest < 32) {
*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);
}
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;
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;
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;
return call_into_lisp(function, args, 3);
}
-
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
#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) \
.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
*/
#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
/* 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
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
/*
* 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
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
/* 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
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. */
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
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)
#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 *
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)
{
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);
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);
/* 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 "
.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) ; \\
;;; 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"