Index: /branches/ia32/lisp-kernel/x86-spentry32.s
===================================================================
--- /branches/ia32/lisp-kernel/x86-spentry32.s	(revision 8349)
+++ /branches/ia32/lisp-kernel/x86-spentry32.s	(revision 8350)
@@ -577,5 +577,82 @@
 	
 _spentry(nthrow1value)
-	__(int $3)
+	__(movb $1,%rcontext:tcr.unwinding)
+local_label(_nthrow1v_nextframe):
+	__(subl $fixnumone,%imm0)
+	__(js local_label(_nthrow1v_done))
+	__(movd %imm0,%mm0)
+	__(movl %rcontext:tcr.catch_top,%temp1)
+	__(movl catch_frame.link(%temp1),%imm0)
+	__(movl %imm0,%rcontext:tcr.catch_top)
+	__(movl catch_frame.db_link(%temp1),%imm0)
+	__(cmpl %imm0,%rcontext:tcr.db_link)
+	__(jz local_label(_nthrow1v_dont_unbind))
+	__(push %temp1)
+	__(push %temp0)
+	__(push %arg_z)
+	__(push [$]local_label(_nthrow1v_back_from_unbind))
+	__(jmp _SPunbind_to)
+__(tra(local_label(_nthrow1v_back_from_unbind)))
+	__(pop %arg_z)
+	__(pop %temp0)
+	__(pop %temp1)
+local_label(_nthrow1v_dont_unbind):
+	__(cmpb $unbound_marker,catch_frame.catch_tag(%temp1))
+	__(je local_label(_nthrow1v_do_unwind))
+/* A catch frame.  If the last one, restore context from there. */
+	__(movd %mm0,%imm0)
+	__(test %imm0,%imm0)	/* last catch frame? */
+	__(jne local_label(_nthrow1v_skip))
+	__(movl catch_frame.xframe(%temp1),%arg_y)
+	__(movl %arg_y,%rcontext:tcr.xframe)
+	__(movl catch_frame.esp(%temp1),%esp)
+	__(movl catch_frame.ebp(%temp1),%ebp)
+	__(movd catch_frame.foreign_sp(%temp1),%stack_temp)
+	__(movd %stack_temp,%rcontext:tcr.foreign_sp)
+local_label(_nthrow1v_skip):
+	__(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
+	__(movl %imm0,%rcontext:tcr.save_tsp)
+	__(movl %imm0,%rcontext:tcr.next_tsp)
+	__(movd %mm0,%imm0)
+	__(jmp local_label(_nthrow1v_nextframe))
+local_label(_nthrow1v_do_unwind):
+/* This is harder, but not as hard (not as much BLTing) as the */
+/* multiple-value case. */
+	__(movl catch_frame.xframe(%temp1),%arg_y)
+	__(movl %arg_y,%rcontext:tcr.xframe)
+	__(movl catch_frame.ebp(%temp1),%ebp)
+	__(movl catch_frame.esp(%temp1),%esp)
+	__(movd catch_frame.foreign_sp(%temp1),%stack_temp)
+	__(movd %stack_temp,%rcontext:tcr.foreign_sp)
+	/* Discard the catch frame so we can build a temp frame. */
+	__(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
+	__(movl %imm0,%rcontext:tcr.save_tsp)
+	__(movl %imm0,%rcontext:tcr.next_tsp)
+	__(movl catch_frame.pc(%temp1),%xfn) /* xfn is temp1 */
+	__(TSP_Alloc_Fixed((3*node_size),%imm0))
+	__(addl $tsp_frame.fixed_overhead,%imm0)
+	__(movl %ra0,(%imm0))
+	__(movd %mm0,node_size*1(%imm0))
+	__(movl %arg_z,node_size*2(%imm0))
+/* Ready to call cleanup code.  Set up tra, jmp to %xfn. */
+	__(push $local_label(_nthrow1v_called_cleanup))
+	__(movb $0,%rcontext:tcr.unwinding)
+	__(jmp *%xfn)
+__(tra(local_label(_nthrow1v_called_cleanup)))
+	__(movb $1,%rcontext:tcr.unwinding)
+	__(movl %rcontext:tcr.save_tsp,%imm0)
+	__(movl tsp_frame.data_offset+(0*node_size)(%imm0),%ra0)
+	__(movd tsp_frame.data_offset+(1*node_size)(%imm0),%mm0)
+	__(movl tsp_frame.data_offset+(2*node_size)(%imm0),%arg_z)
+	__(movl (%imm0),%imm0)
+	__(movl %imm0,%rcontext:tcr.save_tsp)
+	__(movl %imm0,%rcontext:tcr.next_tsp)
+	__(movd %mm0,%imm0)
+	__(jmp local_label(_nthrow1v_nextframe))
+local_label(_nthrow1v_done):
+	__(movb $0,%rcontext:tcr.unwinding)
+	__(check_pending_interrupt(%imm0))
+local_label(_nthrow1v_return):
+	__(jmp *%ra0)
 _endsubp(nthrow1value)
 
@@ -1025,5 +1102,7 @@
 	__(int $3)
 _endsubp(makeu64)
-	
+
+/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
+/* unbound_marker), arg_y = symbol */
 _spentry(specref)
 	__(int $3)
@@ -1047,9 +1126,9 @@
 	
 _spentry(specrefcheck)
-	__(movl %rcontext:tcr.tlb_pointer,%temp1)
 	__(mov %arg_z,%arg_y)
 	__(movl symbol.binding_index(%arg_z),%imm0)
 	__(cmp %rcontext:tcr.tlb_limit,%imm0)
 	__(jae 7f)
+	__(movl %rcontext:tcr.tlb_pointer,%temp1)
 	__(movl (%temp1,%imm0),%arg_z)
 	__(cmpb $no_thread_local_binding_marker,%arg_z_b)
@@ -1082,4 +1161,5 @@
 _endsubp(mvpasssym)
 
+/* */
 _spentry(unbind)
 	__(int $3)
@@ -1091,5 +1171,15 @@
 
 _spentry(unbind_to)
-	__(int $3)
+	__(movl %rcontext:tcr.db_link,%temp0)
+	__(movl %rcontext:tcr.tlb_pointer,%arg_z)
+1:
+	__(movl binding.sym(%temp0),%temp1)
+	__(movl binding.val(%temp0),%arg_y)
+	__(movl binding.link(%temp0),%temp0)
+	__(movl %arg_y,(%arg_z,%temp1))
+	__(cmpl %temp0,%imm0)
+	__(jne 1b)
+	__(movl %temp0,%rcontext:tcr.db_link)
+	__(ret)
 _endsubp(unbind_to)
 
@@ -1127,6 +1217,21 @@
 _endsubp(bind_interrupt_level)
 
+/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
+/* non-negative, check for pending interrupts. */
 _spentry(unbind_interrupt_level)
-	__(int $3)
+	__(movl %rcontext:tcr.tlb_pointer,%arg_y)
+	__(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
+	__(test %imm0,%imm0)
+	__(movl %rcontext:tcr.db_link,%imm0)
+	__(movl binding.val(%imm0),%temp0)
+	__(movl binding.link(%imm0),%imm0)
+	__(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
+	__(movl %imm0,%rcontext:tcr.db_link)
+	__(js,pn 1f)
+0:	__(repret)
+1:	__(test %temp0,%temp0)
+	__(js 0b)
+	__(check_pending_enabled_interrupt(2f))
+2:	__(repret)
 _endsubp(unbind_interrupt_level)
 
