Index: /branches/arm/lisp-kernel/ARM-notes.txt
===================================================================
--- /branches/arm/lisp-kernel/ARM-notes.txt	(revision 13686)
+++ /branches/arm/lisp-kernel/ARM-notes.txt	(revision 13687)
@@ -85,4 +85,15 @@
 callee-save NVRs.
 
+There are some cases in the runtime where we effectively want
+to exchange the lr with the saved lr value in a stack frame.  It's
+possible to do this with a "swp" instruction; "swp" as a means
+of doing interlocked memory operations has been deprecated in
+ARMv6 and later.  We don't care about those semantics, and if
+there are only a few places (calling UNWIND-PROTECT cleanup
+forms) that need to do this it's probably better to use "swp"
+rather than inventing a scheme that allows some register to
+be temporarily treated as a locative.
+
+
 - Subprim calls
 
@@ -200,2 +211,11 @@
 
   [explain complexity here ...]
+
+
+ - misc
+
+I -hope- that the altstack mechanism works on all platforms and that
+we don't have to explicitly check for stack overflow on r13.  (If it
+does, we probably want to check for r13 overflow in the altstack/Mach
+fault handler and unprotect pages there.)
+
Index: /branches/arm/lisp-kernel/arm-asmutils.s
===================================================================
--- /branches/arm/lisp-kernel/arm-asmutils.s	(revision 13686)
+++ /branches/arm/lisp-kernel/arm-asmutils.s	(revision 13687)
@@ -20,66 +20,19 @@
 
 	_beginfile
-/*  Zero R4 cache lines, starting at address in R3.  Each line is assumed to be */
-/* R5 bytes wide. */
-_exportfn(C(zero_cache_lines))
-	__(cmpri(cr0,r4,0))
-	__(mtctr r4)
-	__(beqlr)
-1:
-	__(DCBZL(0,r3))
-	__(add r3,r3,r5)
-	__(bdnz 1b)
-	__(blr)
-_endfn
 
-/*  Flush R4 cache lines, starting at address in R3.  Each line is */
-/* assumed to be R5 bytes wide. */
-_exportfn(C(flush_cache_lines))
-	__(cmpri(cr0,r4,0))
-	__(mtctr r4)
-        __(mr r6,r3)
-	__(beqlr)
-1:
-	__(dcbst 0,r3)
-        __(add r3,r3,r5)
-        __(bdnz 1b)
-	__(sync)                /* wait until dcbst's get to memory */
-        __(mr r3,r6)
-        __(mtctr r4)
-2:      
-	__(icbi 0,r3)
-	__(add r3,r3,r5)
-	__(bdnz 2b)
-        __(sync)
-	__(isync)
-	__(blr)
-/* The strange reference to "exp" is supposed to force the kernel to */
-/* load libm, so lisp code can use it.   Under Darwin, the functionality */
-/* of libm is contained in libsystem, along with libc & everything else. */
+/* Force data from r0 to r1 into the icache */        
+_exportfn(C(_make_data_executable))
+        __(mov r2,#0)           /* options.  Pass as 0 until we know better */
+        __(mov r12,r7)          /* preserve r7 ;  r12 saved by syscall */
+        __(mov r7,0x0f0000)     /* __ARM_NR_cacheflush */
+        __(add r7,r7,#2)
+	__(svc #0)
+        __(mov r7,r12)
+	__(bx lr)
 
-        __ifndef(`DARWIN')
-        .data
-        __ifdef(`PPC64')
-        .quad exp
-        __else
-        .long exp
-        __endif
-        .text        
-        __endif
-_endfn
-
-_exportfn(C(touch_page))
-        __(str(r3,0(r3)))
-        __(li r4,0)
-        __(str(r4,0(r3)))
-        __(li r3,1) /* can't assume that low 32 bits of r3 are non-zero */
-        .globl C(touch_page_end)
-C(touch_page_end):
-        __(blr)
-_endfn
                                 
 _exportfn(C(current_stack_pointer))
-	__(mr r3,sp)
-	__(blr)
+	__(mr r0,sp)
+	__(bx lr)
 _endfn
 	
@@ -90,26 +43,7 @@
 
 _exportfn(C(noop))
-	__(blr)
+	__(bx lr)
 _endfn
 
-_exportfn(C(set_fpscr))
-	__(stru(sp,-32(sp)))
-	__(stw r3,12(sp))
-	__(lfd f0,8(sp))
-	__(mtfsf 0xff,f0)
-	__(la sp,32(sp))
-	__(blr)
-_endfn
-
-
-_exportfn(C(get_fpscr))
-	__(stru(sp,-32(sp)))
-        __(mffs f0)
-        __(stfd f0,8(sp))
-        __(lwz r3,12(sp))
-	__(la sp,32(sp))
-	__(blr)
-_endfn
-                
 
 
@@ -120,15 +54,25 @@
 
 _exportfn(C(store_conditional))
-        __(mr r6,r3)
-1:      __(lrarx(r3,0,r6))
-        __(cmpw r3,r4)
-        __(bne- 2f)
-        __(strcx(r5,0,r6))
-        __(bne- 1b)
-        __(isync)
-        __(blr)
-2:      __(li r0,RESERVATION_DISCHARGE)
-        __(strcx(r0,0,r0))
-        __(blr)
+        __ifdef([LINUX])
+        /* To deal with different ARM variants, Linux provides
+           a magic kernel function that does the right thing in
+           the absence of ldrex/strex/clrex and memory-barrier
+           functions.  That function takes args in a different
+           order (r0 = expected oldval, r1 = newval, r2 = addr.)
+        */
+        __(stmdb pc!,{r4,lr})
+        __(eor r0,r0,r2)
+        __(eor r2,r2,r0)
+        __(eor r0,r0,r2)
+0:      __(ldr r3,[r2])
+        __(cmp r3,r0)
+        __(bne 1f)   
+        __(mov lr,#0xffff0fff)
+        __(add lr,lr,#(0xffff0fc0 - 0xffff0fff))
+        __(blx lr)
+        __(bcc 0b)
+1:      __(mov r0,r3)
+        __(ldmia pc!,{r4,lr})
+        __endif
 _endfn
 
Index: /branches/arm/lisp-kernel/arm-constants.s
===================================================================
--- /branches/arm/lisp-kernel/arm-constants.s	(revision 13686)
+++ /branches/arm/lisp-kernel/arm-constants.s	(revision 13687)
@@ -44,16 +44,20 @@
 /* registers.  These assignments may not be viable. */
 
-define(`arg_z',`r0')
-define(`arg_y',`r1')
-define(`arg_x',`r2')
-define(`temp0',`r3')
-define(`temp1',`r4')
-define(`temp2',`r5')
-define(`imm0',`r6')             /* even, so ldrd/strd can use imm0/imm1 */
-define(`imm1',`r7')
-define(`imm2',`r9')
-define(`vsp',`r9')
-define(`fn',`r10')
-define(`rcontext',`r11')
+define(`imm0',`r0')             /* even, so ldrd/strd can use imm0/imm1 */
+define(`imm1',`r1')
+define(`imm2',`r2')
+/* rcontext = r3 can be used as an imm reg in certain contexts
+   (its value must be easily recovered, but that value never changes
+   during a thread's lifetime.)
+*/        
+define(`rcontext',`r3')         
+define(`arg_z',`r4')
+define(`arg_y',`r5')
+define(`arg_x',`r6')
+define(`temp0',`r7')
+define(`temp1',`r8')
+define(`temp2',`r9')
+define(`vsp',`r10')
+define(`fn',`r11')
 define(`allocptr',`r12')
 define(`sp',`r13')
@@ -658,5 +662,5 @@
 
 define(`whole_reg',`temp1')
-define(`arg_reg',`temp3')
+define(`arg_reg',`temp0')
 define(`keyvect_reg',`temp2')
 define(`mask_req_start',`24')
Index: /branches/arm/lisp-kernel/arm-macros.s
===================================================================
--- /branches/arm/lisp-kernel/arm-macros.s	(revision 13686)
+++ /branches/arm/lisp-kernel/arm-macros.s	(revision 13687)
@@ -214,4 +214,13 @@
 ')
 
+define(`vpush_all_argregs',`
+        __(stmdb vsp!,{arg_z,arg_y,arg_x})
+        ')
+
+define(`vpop_all_argregs',`
+        __(ldmia vsp!,{arg_z,arg_y,arg_x})
+        ')
+                        
+                
 
 /* $1 = arg/temp reg for lisp_frame_marker, $2 = value for lisp_frame.savevsp */                
@@ -414,9 +423,16 @@
 ')
 
+/* Stack-allocate an ivector; $1 = header, $0 = dnode-aligned
+   size in bytes. */
+define(`stack_allocate_ivector',`
+        __(str $1,[sp,-$2]!)
+        ')
+        
+                        
 /* Stack-allocate an ivector and zero its contents; caller may
    change subtag of header after it's zeroed. 
    $1 = header (tagged as subtag_u32_vector until zeroed), $2 = dnode-
    aligned size in bytes).  Both $1 and $2 are modified here. */
-define(`stack_allocate_zeroed_word_vector',`
+define(`stack_allocate_zeroed_ivector',`
        new_macro_labels()
         __(str $1,[sp,-$2]!)
@@ -442,5 +458,5 @@
 define(`check_pending_interrupt',`
 	new_macro_labels()
-        __(ldr $1,tcr.tlb_pointer(rcontext))
+        __(ldr $1,[rcontext,#tcr.tlb_pointer])
 	__(ldr $1,[$1,$INTERRUPT_LEVEL_BINDING_INDEX])
         __(cmp $1,#0)
@@ -465,9 +481,9 @@
         __(cmp $2,#fulltag_immheader)
         __(extract_lowbyte($2,$1))
-        __(mov $1,$1 lsr #num_subtag_bits)
-        __(moveq $1,$1 lsl #2)
+        __(mov $1,$1,lsr #num_subtag_bits)
+        __(moveq $1,$1,lsl #2)
         __(beq macro_label(bytes))
         __(cmp $2,#max_32_bit_ivector_subtag)
-        __(movle $1,$1 lsl #2)
+        __(movle $1,$1,lsl #2)
         __(ble macro_label(bytes))
         __(cmp $2,#max_8_bit_ivector_subtag)
@@ -486,2 +502,61 @@
         __(add $1,$1,$3)
         ')
+
+/* This may need to be inlined.  $1=link, $2=saved sym idx, $3 = tlb, $4 = value */
+define(`do_unbind_to',`
+        __(ldr $1,[rcontext,#tcr.db_link])
+        __(ldr $3,[rcontext,#tcr.tlb_pointer])
+1:      __(ldr $2,[$1,#binding.sym])
+        __(ldr $4,[$1,#binding.val])
+        __(ldr $1,[$1,#binding.link])
+        __(cmp imm0,$1)
+        __(str $4,[$3,$2])
+        __(bne 1b)
+        __(str $1,[rcontext,#tcr.db_link])
+        ')                
+
+/* Linux provides a weird kernel entrypoint to do cmpxchg on hardware
+   that may not support it natively.  Darwin only runs on ARMv6 hardware,
+   which can use ldrex/strex instructions to do cmpxchg inline.  On
+   SMP hardware, the cmpxchg should be followe by a 'dmb' (data memory
+   barrier) instruction, which is only available on ARMv7.  Confused yet?
+   The Linux kernel function clobbers some registers, and we may need
+   some support in pc_luser_xp() to fix things up at interrupt/suspend
+   time.
+   Generally, imm1 = mask with exactly one bit set, *imm2 = address of
+   refbits word. */
+
+define(`set_ref_bit',`
+        new_macro_labels()
+        __ifdef(`LINUX')
+        .globl set_ref_bit_entry_$1
+set_ref_bit_entry_$1:   
+        __(build_lisp_frame(imm0))  /* we clobber lr */
+        __(mov temp1,imm1)
+        __(mov temp2,rcontext)
+macro_label(again):     
+        __(ldr lr,macro_label(linux_kernel_cmpxchg))
+        __(ldr r0,[r2])
+        __(orr r1,r0,temp1)
+        __(blx lr)
+        .globl set_ref_bit_return_$1
+set_ref_bit_return_$1:   
+        __(mov rcontext,temp2)
+        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
+        __(bcc macro_label(again))
+        __(restore_lisp_frame(imm0))
+        __(b macro_label(continue))
+macro_label(linux_kernel_cmpxchg):
+        .word 0xffff0fc0        /* magic address */
+macro_label(continue):
+        __endif
+        __ifdef(`DARWIN')
+macro_label(again):     
+        __(ldrex r0,[r2])
+        __(orr r0,r0,r1)
+        __(strex r0,r0,[r2])
+        __(cmp r0,#0)
+        __(bne macro_label(again))
+        __endif
+        ')
+                        
Index: /branches/arm/lisp-kernel/arm-spentry.s
===================================================================
--- /branches/arm/lisp-kernel/arm-spentry.s	(revision 13686)
+++ /branches/arm/lisp-kernel/arm-spentry.s	(revision 13687)
@@ -46,4 +46,281 @@
 ')
 
+_spentry(builtin_plus)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(adds arg_z,arg_y,arg_z)
+	__(bxvc lr)
+	__(b _SPfix_overflow)
+1:
+	__(jump_builtin(_builtin_plus,2))
+        
+_spentry(builtin_minus)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(subs arg_z,arg_y,arg_z)
+	__(bxvc lr)
+	__(b _SPfix_overflow)
+1:
+	__(jump_builtin(_builtin_minus,2))
+
+_spentry(builtin_times)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(unbox_fixnum(imm2,arg_z))
+	__(smull arg_z,imm1,imm2,arg_y)
+	/* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */
+	/* imm1 is just a sign extension of arg_z, return arg_z */
+	__(cmp imm1,arg_z,asr #(nbits_in_word-1))
+	__(bxeq lr)
+	/* Need to ashift the pair imm1:imm0 right fixnumshift bits */
+	__(mov imm0,imm0,lsr #fixnumshift)
+	__(and imm2,imm1,#fixnummask)
+	__(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift))
+	__(unbox_fixnum(imm1,imm1))
+	__(b _SPmakes64)
+
+1: __(jump_builtin(_builtin_times,2))
+
+_spentry(builtin_div)
+        __(jump_builtin(_builtin_div,2))
+
+_spentry(builtin_eq)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(cmp arg_y,arg_z)
+	__(mov arg_z,#nil_value)
+	__(addeq arg_z,arg_z,#t_offset)
+	__(bx lr)        
+1:
+	__(jump_builtin(_builtin_eq,2))
+                        
+_spentry(builtin_ne)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(cmp arg_y,arg_z)
+	__(mov arg_z,#nil_value)
+	__(addne arg_z,arg_z,#t_offset)
+	__(bx lr)
+1:
+	__(jump_builtin(_builtin_ne,2))
+
+_spentry(builtin_gt)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(cmp arg_y,arg_z)
+	__(mov arg_z,#nil_value)
+	__(addgt arg_z,arg_z,#t_offset)
+	__(bx lr)
+1:
+	__(jump_builtin(_builtin_gt,2))
+
+_spentry(builtin_ge)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(cmp arg_y,arg_z)
+	__(mov arg_z,#nil_value)
+	__(addge arg_z,arg_z,#t_offset)
+	__(bx lr)
+1:
+	__(jump_builtin(_builtin_ge,2))
+
+_spentry(builtin_lt)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(cmp arg_y,arg_z)
+	__(mov arg_z,#nil_value)
+	__(addgt arg_z,arg_z,#t_offset)
+	__(bx lr)
+1:
+	__(jump_builtin(_builtin_lt,2))
+
+_spentry(builtin_le)
+	__(test_two_fixnums(arg_y,arg_z,imm0))
+	__(bne 1f)
+	__(cmp arg_y,arg_z)
+	__(mov arg_z,#nil_value)
+	__(addle arg_z,arg_z,#t_offset)
+	__(bx lr)
+1:
+	__(jump_builtin(_builtin_le,2))
+
+_spentry(builtin_eql)
+        __(cmp arg_y,arg_z)
+        __(beq 1f)
+        __(extract_fulltag(imm0,arg_y))
+        __(extract_fulltag(imm1,arg_z))
+        __(cmp imm0,imm1)
+        __(bne 2f)
+        __(cmp imm0,#fulltag_misc)
+        __(bne 2f)
+        __(jump_builtin(_builtin_eql,2))
+1:      __(mov arg_z,#nil_value)
+        __(add arg_z,arg_z,#t_offset)
+        __(bx lr)
+2:      __(mov arg_z,#nil_value)
+        __(bx lr)
+        
+_spentry(builtin_length)
+        __(extract_typecode(imm0,arg_z))
+        __(cmp imm0,#min_vector_subtag)
+        __(ldreq arg_z,[arg_z,#vectorH.logsize])
+        __(bxeq lr)
+        __(blo 1f)
+        __(vector_length(arg_z,arg_z,imm0))
+        __(bx lr)
+1:      __(cmp imm0,#tag_list)
+        __(bne 8f)
+        __(mov temp2,#-1<<fixnum_shift)
+        __(mov temp0,arg_z) /* fast pointer  */
+        __(mov temp1,arg_z) /* slow pointer  */
+2:      __(cmp temp0,#nil_value)
+        __(add temp2,temp2,#fixnumone)
+        __(beq 9f)
+        __(extract_lisptag(imm0,temp0))
+        __(cmp imm0,#tag_list)
+        __(bne 8f)
+        __(_cdr(temp0,temp0))
+        __(tst temp2,#fixnumone)
+        __(beq 2b)
+        __(_cdr(temp1,temp1))
+        __(cmp temp1,temp0)
+        __(bne 2b)
+8: 
+        __(jump_builtin(_builtin_length,1))
+9:      __(mov arg_z,temp2)
+        __(bx lr)       
+
+_spentry(builtin_seqtype)
+        __(extract_typecode(imm0,arg_z))
+        __(cmp imm0,#min_vector_subtag)
+        __(movge arg_z,#nil_value)
+        __(bxge lr)
+        __(cmp imm0,#tag_list)
+        __(moveq arg_z,#nil_value)
+        __(addeq arg_z,arg_z,#t_offset)
+        __(bxeq lr)
+        __(jump_builtin(_builtin_seqtype,1))
+
+/* This is usually inlined these days */
+_spentry(builtin_assq)
+        __(b 2f)
+1:      __(trap_unless_list(arg_z,imm0))
+        __(_car(arg_x,arg_z))
+        __(_cdr(arg_z,arg_z))
+        __(cmp arg_x,#nil_value)
+        __(beq 2f)
+        __(trap_unless_list(arg_x,imm0))
+        __(_car(temp0,arg_x))
+        __(cmp temp0,arg_y)
+        __(bne 2f)
+        __(mov arg_z,arg_x)
+        __(bx lr)
+2:      __(cmp arg_z,#nil_value)
+        __(bne 1b)
+        __(bx lr)
+ 
+_spentry(builtin_memq)
+        __(cmp arg_z,nil_value)
+        __(b 2f)
+1:      __(trap_unless_list(arg_z,imm0))
+        __(_car(arg_x,arg_z))
+        __(_cdr(temp0,arg_z))
+        __(cmp arg_x,arg_y)
+        __(bxeq lr)
+        __(cmp temp0,nil_value)
+        __(mov arg_z,temp0)
+2:      __(bne 1b)
+        __(bx lr)
+
+_spentry(builtin_logbitp)
+/* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
+        __(test_two_fixnums(arg_y,arg_z,imm0))
+        __(bne 1f)
+        __(uuo_suspend_now(al))
+        __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
+        __(bhs 1f)
+        __(unbox_fixnum(imm0,arg_y))
+        __(mov imm1,#fixnum1)
+        __(tst arg_z,imm1,lsl imm0)
+        __(mov arg_z,#nil_value)
+        __(addne arg_z,arg_z,#t_offset)
+        __(bx lr)
+1:
+        __(jump_builtin(_builtin_logbitp,2))
+
+_spentry(builtin_logior)
+        __(orr imm0,arg_y,arg_z)
+        __(test_fixnum(imm0))
+        __(moveq arg_z,imm0)
+        __(bxeq lr)
+        __(jump_builtin(_builtin_logior,2))
+
+_spentry(builtin_logand)
+        __(test_two_fixnums(arg_y,arg_z,imm0))
+        __(andeq arg_z,arg_y,arg_z)
+        __(bxeq lr)
+        __(jump_builtin(_builtin_logand,2))
+          
+_spentry(builtin_ash)
+        __(test_two_fixnums(arg_y,arg_z,imm0))
+        __(bne 9f)
+        __(cmp arg_z,#0)
+        __(bgt 1f)
+        __(moveq arg_z,arg_y)
+        __(bxeq lr)
+        /* Shift right */
+        __(unbox_fixnum(imm2,arg_z))
+        __(rsb imm2,imm2,#0)
+        __(cmp imm2,#32)
+        __(movge imm2,#31)
+        __(mov arg_z,#-fixnumone)
+        __(and arg_z,arg_z,arg_y,lsr imm2)
+        __(bx lr)
+        /* shift left */
+1:      __(unbox_fixnum(imm0,arg_y))
+        __(unbox_fixnum(imm2,arg_z))
+        __(cmp imm2,#32)
+        __(moveq imm1,imm0)
+        __(moveq imm0,#0)
+        __(beq _SPmakes64)
+        __(bgt 9f)
+        __(mov imm1,imm1,asl imm2)
+        __(rsb imm2,imm2,#32)
+        __(orr imm1,imm1,imm0,asr imm2)
+        __(unbox_fixnum(imm2,arg_z))
+        __(mov imm0,imm0,asl imm2)
+        __(b _SPmake64)
+9:  
+        __(jump_builtin(_builtin_ash,2))
+                                	
+_spentry(builtin_negate)
+        __(test_fixnum(arg_z))
+        __(bne 1f)
+        __(rsbs arg_z,arg_z,#0)
+        __(bxvc lr)
+        __(b _SPfix_overflow)
+1:
+        __(jump_builtin(_builtin_negate,1))
+ 
+_spentry(builtin_logxor)
+        __(test_two_fixnums(arg_y,arg_z,imm0))
+        __(eoreq arg_z,arg_y,arg_z)
+        __(bxeq lr)
+        __(jump_builtin(_builtin_logxor,2))
+
+_spentry(builtin_aref1)
+        __(extract_typecode(imm0,arg_y))
+        __(cmp imm0,#min_vector_subtag)
+        __(box_fixnum(arg_x,imm0))
+        __(bgt _SPsubtag_misc_ref)
+        __(jump_builtin(_builtin_aref1,2))
+
+_spentry(builtin_aset1)
+        __(extract_typecode(imm0,arg_x))
+        __(cmp imm0,#min_vector_subtag)
+        __(box_fixnum(temp0,imm0))
+        __(bgt _SPsubtag_misc_set)
+        __(jump_builtin(_builtin_aset1,3))
+                	
 _spentry(jmpsym)
 	__(jump_fname())
@@ -163,21 +440,5 @@
 	__(b _SPmakes32)
 
-_spentry(builtin_plus)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(adds arg_z,arg_y,arg_z)
-	__(bxvc lr)
-	__(b _SPfix_overflow)
-1:
-	__(jump_builtin(_builtin_plus,2))
-
-_spentry(builtin_minus)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(subs arg_z,arg_y,arg_z)
-	__(bxvc lr)
-	__(b _SPfix_overflow)
-1:
-	__(jump_builtin(_builtin_minus,2))
+
 
 /*  Construct a lisp integer out of the 64-bit unsigned value in */
@@ -211,81 +472,8 @@
 	__(bx lr)
 
-_spentry(builtin_times)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(unbox_fixnum(imm2,arg_z))
-	__(smull arg_z,imm1,imm2,arg_y)
-	/* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */
-	/* imm1 is just a sign extension of arg_z, return arg_z */
-	__(cmp imm1,arg_z,asr #(nbits_in_word-1))
-	__(bxeq lr)
-	/* Need to ashift the pair imm1:imm0 right fixnumshift bits */
-	__(mov imm0,imm0,lsr #fixnumshift)
-	__(and imm2,imm1,#fixnummask)
-	__(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift))
-	__(unbox_fixnum(imm1,imm1))
-	__(b _SPmakes64)
-
-1: __(jump_builtin(_builtin_times,2))
-
-_spentry(builtin_eq)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(cmp arg_y,arg_z)
-	__(mov arg_z,#nil_value)
-	__(addeq arg_z,arg_z,#t_offset)
-	__(bx lr)        
-1:
-	__(jump_builtin(_builtin_eq,2))
-
-_spentry(builtin_ne)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(cmp arg_y,arg_z)
-	__(mov arg_z,#nil_value)
-	__(addne arg_z,arg_z,#t_offset)
-	__(bx lr)
-1:
-	__(jump_builtin(_builtin_ne,2))
-
-_spentry(builtin_gt)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(cmp arg_y,arg_z)
-	__(mov arg_z,#nil_value)
-	__(addgt arg_z,arg_z,#t_offset)
-	__(bx lr)
-1:
-	__(jump_builtin(_builtin_gt,2))
-
-_spentry(builtin_ge)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(cmp arg_y,arg_z)
-	__(mov arg_z,#nil_value)
-	__(addge arg_z,arg_z,#t_offset)
-	__(bx lr)
-1:
-	__(jump_builtin(_builtin_ge,2))
-
-_spentry(builtin_lt)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(cmp arg_y,arg_z)
-	__(mov arg_z,#nil_value)
-	__(addgt arg_z,arg_z,#t_offset)
-	__(bx lr)
-1:
-	__(jump_builtin(_builtin_lt,2))
-
-_spentry(builtin_le)
-	__(test_two_fixnums(arg_y,arg_z,imm0))
-	__(bne 1f)
-	__(cmp arg_y,arg_z)
-	__(mov arg_z,#nil_value)
-	__(addle arg_z,arg_z,#t_offset)
-	__(bx lr)
-1:
-	__(jump_builtin(_builtin_le,2))
+
+
+
+
 
 /* funcall nfn, returning multiple values if it does.  */
@@ -365,92 +553,30 @@
 	__(b local_label(return_values))                         
 
-dnl /* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
-dnl /* Otherwise, process unwind-protects and throw to indicated catch frame.  */
-dnl 
-dnl _spentry(throw)
-dnl  __(ldr imm1,[rcontext, #tcr.catch_top])
-dnl  __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
-dnl  __(cmpri(cr0,imm1,0))
-dnl  __(ldr temp0,[vsp,nargs])
-dnl  __(beq- cr0,local_label(_throw_tag_not_found))
-dnl local_label(_throw_loop):
-dnl  __(ldr temp1,[imm1,#catch_frame.catch_tag])
-dnl  __(cmpr(cr0,temp0,temp1))
-dnl  __(mov imm2,imm1)
-dnl  __(ldr imm1,[imm1,#catch_frame.link])
-dnl  __(cmpri(cr1,imm1,0))
-dnl  __(beq cr0,local_label(_throw_found))
-dnl  __(addi imm0,imm0,fixnum_one)
-dnl  __(beq- cr1,local_label(_throw_tag_not_found))
-dnl  __(b local_label(_throw_loop))
-dnl /* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
-dnl /* frames. If target isn't a multiple-value receiver, discard extra values */
-dnl /* (less hair, maybe.)  */
-dnl local_label(_throw_found):
-dnl  __(ldr imm1,[imm2,#catch_frame.mvflag])
-dnl  __(cmpri(cr0,imm1,0))
-dnl  __(cmpri(cr1,nargs,0))
-dnl  __(mov fn,#0)
-dnl  __(add imm1,vsp,nargs)
-dnl  __(add imm1,[imm1,#-node_size])
-dnl  __(bne cr0,local_label(_throw_all_values))
-dnl  __(set_nargs(1))
-dnl  __(beq cr1,local_label(_throw_default_1_val))
-dnl  __(mov vsp,imm1)
-dnl  __(b local_label(_throw_all_values))
-dnl local_label(_throw_default_1_val):
-dnl  __(mov imm4,#nil_value)
-dnl  __(vpush1(imm4))
-dnl local_label(_throw_all_values):
-dnl  __(bl _SPnthrowvalues)
-dnl  __(ldr imm3,[rcontext,#tcr.catch_top])
-dnl  __(ldr imm1,[rcontext,#tcr.db_link])
-dnl  __(ldr imm0,[imm3,#catch_frame.db_link])
-dnl  __(ldr imm4,[imm3,#catch_frame.mvflag])
-dnl  __(cmpr(cr0,imm0,imm1))
-dnl  __(cmpri(cr1,imm4,0))
-dnl  __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
-dnl  __(beq cr0,local_label(_throw_dont_unbind))
-dnl         __(bl _SPunbind_to)
-dnl local_label(_throw_dont_unbind):
-dnl  __(add imm0,vsp,nargs)
-dnl  __(cmpri(cr0,nargs,0))
-dnl  __(ldr imm1,[imm3,#catch_frame.csp])
-dnl  __(ldr imm1,[imm1,#lisp_frame.savevsp])
-dnl  __(bne cr1,local_label(_throw_multiple))
-dnl         /* Catcher expects single value in arg_z  */
-dnl  __(ldr arg_z,[imm0,#-node_size])
-dnl  __(b local_label(_throw_pushed_values))
-dnl local_label(_throw_multiple):
-dnl  __(beq cr0,local_label(_throw_pushed_values))
-dnl  __(mov imm2,nargs)
-dnl local_label(_throw_mvloop):
-dnl  __(subi imm2,imm2,fixnum_one)
-dnl  __(cmpri(imm2,0))
-dnl  __(ldru(temp0,-node_size(imm0)))
-dnl  __(push(temp0,imm1))
-dnl  __(bgt local_label(_throw_mvloop))
-dnl local_label(_throw_pushed_values):
-dnl  __(mov vsp,imm1)
-dnl  __(ldr imm1,[imm3,#catch_frame.xframe])
-dnl  __(str(imm1,tcr.xframe(rcontext)))
-dnl  __(ldr sp,[imm3,#catch_frame.csp])
-dnl  __(ldr fn,[sp,#lisp_frame.savefn])
-dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
-dnl  __(discard_lisp_frame())
-dnl  __(mtlr loc_pc)
-dnl         __(restore_catch_nvrs(imm3))
-dnl  __(ldr imm3,[imm3,#catch_frame.link])
-dnl  __(str(imm3,tcr.catch_top(rcontext)))
-dnl  __(unlink(tsp))
-dnl  __(bx lr)
-dnl local_label(_throw_tag_not_found):
-dnl  __(uuo_interr(error_throw_tag_missing,temp0))
-dnl  __(strux(temp0,vsp,nargs))
-dnl  __(b _SPthrow)
-dnl 
-dnl 
-dnl /* This takes N multiple values atop the vstack.  */
-dnl _spentry(nthrowvalues)
+/* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
+/* Otherwise, process unwind-protects and throw to indicated catch frame.  */
+
+                
+ _spentry(throw)
+        __(ldr imm1,[rcontext, #tcr.catch_top])
+        __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
+        __(cmp imm1,#0)
+        __(ldr temp0,[vsp,nargs])
+        __(beq local_label(_throw_tag_not_found))
+local_label(_throw_loop):
+        __(ldr temp1,[imm1,#catch_frame.catch_tag])
+        __(cmp temp0,temp1)
+        __(mov imm2,imm1)
+        __(ldr imm1,[imm1,#catch_frame.link])
+        __(beq C(_throw_found))
+        __(cmp imm1,#0)
+        __(add imm0,imm0,#fixnum_one)
+        __(bne local_label(_throw_loop))
+local_label(_throw_tag_not_found):
+        __(uuo_error_no_throw_tag(al,temp0))
+        __(str temp0,[vsp,nargs])
+        __(b _SPthrow)
+
+/* This takes N multiple values atop the vstack.  */
+_spentry(nthrowvalues)
 dnl         __(mov imm1,#1)
 dnl  __(mov imm4,imm0)
@@ -464,5 +590,5 @@
 dnl  __(ldr imm0,[temp0,#catch_frame.db_link])
 dnl  __(ldr imm3,[temp0,#catch_frame.link])
-dnl  __(cmpr(cr0,imm0,imm1))
+dnl  __(cmpr(imm0,imm1))
 dnl  __(str(imm3,tcr.catch_top(rcontext)))
 dnl  __(ldr temp1,[temp0,#catch_frame.catch_tag])
@@ -471,5 +597,5 @@
 dnl  __(str(first_nvr,tcr.xframe(rcontext)))
 dnl  __(ldr sp,[temp0,#catch_frame.csp])
-dnl  __(beq cr0,local_label(_nthrowv_dont_unbind))
+dnl  __(beq local_label(_nthrowv_dont_unbind))
 dnl  __(mflr loc_pc)
 dnl         __(bl _SPunbind_to)
@@ -488,5 +614,5 @@
 dnl  __(push(temp1,imm0))
 dnl local_label(_nthrowv_push_test):
-dnl  __(cmpri(imm2,0))
+dnl  __(cmp imm2,#0))
 dnl  __(subi imm2,imm2,fixnum_one)
 dnl  __(bne local_label(_nthrowv_push_loop))
@@ -529,5 +655,5 @@
 dnl  __(subi imm2,imm2,fixnum_one)
 dnl local_label(_nthrowv_tpushtest):
-dnl  __(cmpri(imm2,0))
+dnl  __(cmp imm2,#0)
 dnl  __(bne local_label(_nthrowv_tpushloop))
 dnl  __(stru(imm4,node_size(imm0)))
@@ -553,5 +679,5 @@
 dnl  __(subi imm2,imm2,fixnum_one)
 dnl local_label(_nthrowv_tpoptest):
-dnl  __(cmpri(imm2,0))
+dnl  __(cmp imm2,#0)
 dnl  __(bne local_label(_nthrowv_tpoploop))
 dnl  __(ldr imm4,[imm0,#node_size])
@@ -567,81 +693,14 @@
 dnl         __(mov nargs,imm4)
 dnl         __(bx lr)
-dnl 
-dnl /* This is a (slight) optimization.  When running an unwind-protect, */
-dnl /* save the single value and the throw count in the tstack frame. */
-dnl /* Note that this takes a single value in arg_z.  */
-dnl _spentry(nthrow1value)
-dnl         __(mov imm1,#1)
-dnl  __(mov imm4,imm0)
-dnl         __(str(imm1,tcr.unwinding(rcontext)))
-dnl local_label(_nthrow1v_nextframe):
-dnl  __(subi imm4,imm4,fixnum_one)
-dnl  __(cmpri(cr1,imm4,0))
-dnl  __(ldr temp0,[rcontext,#tcr.catch_top])
-dnl  __(ldr imm1,[rcontext,#tcr.db_link])
-dnl  __(set_nargs(1))
-dnl  __(blt cr1,local_label(_nthrow1v_done))
-dnl  __(ldr imm3,[temp0,#catch_frame.link])
-dnl  __(ldr imm0,[temp0,#catch_frame.db_link])
-dnl  __(cmpr(cr0,imm0,imm1))
-dnl  __(str(imm3,tcr.catch_top(rcontext)))
-dnl         __(ldr imm3,[temp0,#catch_frame.xframe])
-dnl  __(ldr temp1,[temp0,#catch_frame.catch_tag])
-dnl  __(cmpri(cr7,temp1,unbound_marker))  /* unwind-protect ?  */
-dnl         __(str(imm3,tcr.xframe(rcontext)))
-dnl  __(ldr sp,[temp0,#catch_frame.csp])
-dnl  __(beq cr0,local_label(_nthrow1v_dont_unbind))
-dnl   __(mflr loc_pc)
-dnl          __(bl _SPunbind_to)
-dnl   __(mtlr loc_pc)
-dnl local_label(_nthrow1v_dont_unbind):
-dnl  __(beq cr7,local_label(_nthrow1v_do_unwind))
-dnl         /* A catch frame.  If the last one, restore context from there.  */
-dnl  __(bne cr1,local_label(_nthrow1v_skip))
-dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
-dnl         __(restore_catch_nvrs(temp0))
-dnl local_label(_nthrow1v_skip):
-dnl  __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
-dnl  __(unlink(tsp))
-dnl  __(discard_lisp_frame())
-dnl  __(b local_label(_nthrow1v_nextframe))
-dnl local_label(_nthrow1v_do_unwind):
-dnl         /* This is harder, but not as hard (not as much BLTing) as the  */
-dnl         /* multiple-value case.  */
-dnl         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
-dnl         /* protect.  (Clever, eh ?)  */
-dnl 
-dnl         __(restore_catch_nvrs(temp0))
-dnl  __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
-dnl  __(unlink(tsp))
-dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
-dnl  __(ldr nfn,[sp,#lisp_frame.savefn])
-dnl  __(mtctr loc_pc)  /* cleanup code address.  */
-dnl  __(str(fn,lisp_frame.savefn(sp)))
-dnl  __(mflr loc_pc)
-dnl  __(mov fn,nfn)
-dnl  __(str(loc_pc,lisp_frame.savelr(sp)))
-dnl  __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
-dnl  __(str(arg_z,tsp_frame.data_offset(tsp)))
-dnl  __(str(imm4,tsp_frame.data_offset+node_size(tsp)))
-dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
-dnl         __(str(rzero,tcr.unwinding(rcontext)))
-dnl  __(bctrl)
-dnl         __(mov imm1,#1)
-dnl  __(ldr arg_z,[tsp,#tsp_frame.data_offset])
-dnl         __(str(imm1,tcr.unwinding(rcontext)))
-dnl  __(ldr imm4,[tsp,#tsp_frame.data_offset+node_size])
-dnl  __(ldr fn,[sp,#lisp_frame.savefn])
-dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
-dnl  __(discard_lisp_frame())
-dnl  __(mtlr loc_pc)
-dnl  __(unlink(tsp))
-dnl  __(b local_label(_nthrow1v_nextframe))
-dnl local_label(_nthrow1v_done):
-dnl         __(str(rzero,tcr.unwinding(rcontext)))
-dnl         /* nargs has an undefined value here, so we can clobber it while */
-dnl         /* polling for a deferred interrupt  */
-dnl         __(check_pending_interrupt())
-dnl         __(bx lr)
+
+/* This is a (slight) optimization.  When running an unwind-protect, */
+/* save the single value and the throw count in the tstack frame. */
+/* Note that this takes a single value in arg_z.  */
+_spentry(nthrow1value)
+        __(mov imm1,#1)
+        __(mov temp2,imm0)
+        __(str imm1,[rcontext,#tcr.unwinding])
+        __(b C(nthrow1v))
+
 
 /* arg_z = symbol: bind it to its current value          */
@@ -700,80 +759,76 @@
         __(set_nargs(2))
         __(b _SPksignalerr)
-dnl 
-dnl 
-dnl /* The function pc_luser_xp() - which is used to ensure that suspended threads */
-dnl /* are suspended in a GC-safe way - has to treat these subprims (which  */
-dnl /* implement the EGC write-barrier) specially.  Specifically, a store that */
-dnl /* might introduce an intergenerational reference (a young pointer stored  */
-dnl /* in an old object) has to "memoize" that reference by setting a bit in  */
-dnl /* the global "refbits" bitmap. */
-dnl /* This has to happen atomically, and has to happen atomically wrt GC. */
-dnl /* Note that updating a word in a bitmap is itself not atomic, unless we use */
-dnl /* interlocked loads and stores. */
-dnl 
-dnl 
-dnl /* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
-dnl /* are in the function, we can do the store (even if it's already been done)  */
-dnl /* and calculate whether or not we need to set the bit out-of-line.  (Actually */
-dnl /* setting the bit needs to be done atomically, unless we're sure that other */
-dnl /* threads are suspended.) */
-dnl /* We can unconditionally set the suspended thread's PC to its LR. */
-dnl  
-dnl         .globl C(egc_write_barrier_start)
-dnl _spentry(rplaca)
-dnl C(egc_write_barrier_start):
-dnl         __(cmplr(cr2,arg_z,arg_y))
-dnl         __(_rplaca(arg_y,arg_z))
-dnl         __(blelr cr2)
-dnl         __(ref_global(imm2,ref_base))
-dnl         __(sub imm0,arg_y,imm2)
-dnl         __(load_highbit(imm3))
-dnl         __(srri(imm0,imm0,dnode_shift))       
-dnl         __(ref_global(imm1,oldspace_dnode_count))
-dnl         __(extract_bit_shift_count(imm4,imm0))
-dnl         __(cmplr(imm0,imm1))
-dnl         __(srr(imm3,imm3,imm4))
-dnl         __(srri(imm0,imm0,bitmap_shift))       
-dnl         __(ref_global(imm2,refbits))
-dnl         __(bgelr)
-dnl         __(slri(imm0,imm0,word_shift))
-dnl         __(ldr imm1,[imm2,imm0])
-dnl         __(and. imm1,imm1,imm3)
-dnl         __(bnelr)
-dnl 1:      __(lrarx(imm1,imm2,imm0))
-dnl         __(or imm1,imm1,imm3)
-dnl         __(strcx(imm1,imm2,imm0))
-dnl         __(bne- 1b)
-dnl         __(isync)
-dnl         __(bx lr)
-dnl 
-dnl         .globl C(egc_rplacd)
-dnl _spentry(rplacd)
-dnl C(egc_rplacd):
-dnl         __(cmplr(cr2,arg_z,arg_y))
-dnl  __(_rplacd(arg_y,arg_z))
-dnl         __(blelr cr2)
-dnl         __(ref_global(imm2,ref_base))
-dnl         __(sub imm0,arg_y,imm2)
-dnl         __(load_highbit(imm3))
-dnl         __(srri(imm0,imm0,dnode_shift))       
-dnl         __(ref_global(imm1,oldspace_dnode_count))
-dnl         __(extract_bit_shift_count(imm4,imm0))
-dnl         __(cmplr(imm0,imm1))
-dnl         __(srr(imm3,imm3,imm4))
-dnl         __(srri(imm0,imm0,bitmap_shift))       
-dnl         __(ref_global(imm2,refbits))
-dnl         __(bgelr)
-dnl         __(slri(imm0,imm0,word_shift))
-dnl         __(ldr imm1,[imm2,imm0])
-dnl         __(and. imm1,imm1,imm3)
-dnl         __(bnelr)        
-dnl 1:      __(lrarx(imm1,imm2,imm0))
-dnl         __(or imm1,imm1,imm3)
-dnl         __(strcx(imm1,imm2,imm0))
-dnl         __(bne- 1b)
-dnl         __(isync)
-dnl         __(bx lr)
-dnl 
+
+ 
+/* The function pc_luser_xp() - which is used to ensure that suspended threads */
+/* are suspended in a GC-safe way - has to treat these subprims (which  */
+/* implement the EGC write-barrier) specially.  Specifically, a store that */
+/* might introduce an intergenerational reference (a young pointer stored  */
+/* in an old object) has to "memoize" that reference by setting a bit in  */
+/* the global "refbits" bitmap. */
+/* This has to happen atomically, and has to happen atomically wrt GC. */
+/* Note that updating a word in a bitmap is itself not atomic, unless we use */
+/* interlocked loads and stores. */
+
+
+/* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
+/* are in the function, we can do the store (even if it's already been done)  */
+/* and calculate whether or not we need to set the bit out-of-line.  (Actually */
+/* setting the bit needs to be done atomically, unless we're sure that other */
+/* threads are suspended.) */
+/* We can unconditionally set the suspended thread's PC to its LR. */
+
+        .globl C(egc_write_barrier_start)
+_spentry(rplaca)
+C(egc_write_barrier_start):     
+        __(cmp arg_z,arg_y)
+        __(_rplaca(arg_y,arg_z))
+        __(bxls lr)
+        __(ref_global(temp0,ref_base))
+        __(sub imm0,arg_y,temp0)
+        __(mov imm0,imm0,lsr #dnode_shift)
+        __(ref_global(temp0,oldspace_dnode_count))
+        __(cmp imm0,temp0)
+        __(bxhs lr)
+        __(and imm2,imm0,#31)
+        __(mov imm1,#0x80000000)
+        __(mov imm1,imm1,lsr imm2)
+        __(mov imm0,imm0,lsr #bitmap_shift)
+        __(ref_global(imm2,refbits))
+        __(add imm2,imm2,imm0,lsl #word_shift)
+        __(ldr imm0,[imm2])
+        __(ands imm0,imm0,imm1)
+        __(bxne lr)
+        __(build_lisp_frame(imm0))
+        __(set_ref_bit(rplaca))
+        __(bx lr)
+
+
+        .globl C(egc_rplacd)
+_spentry(rplacd)
+C(egc_rplacd):
+        __(cmp arg_z,arg_y)
+        __(_rplacd(arg_y,arg_z))
+        __(bxls lr)
+        __(ref_global(temp0,ref_base))
+        __(sub imm0,arg_y,temp0)
+        __(mov imm0,imm0,lsr #dnode_shift)
+        __(ref_global(temp0,oldspace_dnode_count))
+        __(cmp imm0,temp0)
+        __(bxhs lr)
+        __(and imm2,imm0,#31)
+        __(mov imm1,#0x80000000)
+        __(mov imm1,imm1,lsr imm2)
+        __(mov imm0,imm0,lsr #bitmap_shift)
+        __(ref_global(imm2,refbits))
+        __(add imm2,imm2,imm0,lsl #word_shift)
+        __(ldr imm0,[imm2])
+        __(ands imm0,imm0,imm1)
+        __(bxne lr)
+        __(build_lisp_frame(imm0))
+        __(set_ref_bit(rplacd))
+        __(bx lr)
+	
+
 /* Storing into a gvector can be handled the same way as storing into a CONS. */
 
@@ -781,32 +836,29 @@
 _spentry(gvset)
 C(egc_gvset):
-dnl         __(cmplr(cr2,arg_z,arg_x))
+        __(cmp arg_z,arg_x)
 	__(add imm0,arg_y,#misc_data_offset)
 	__(str arg_z,[arg_x,imm0])
-	__(bx lr)
-dnl         __(blelr cr2)
-dnl         __(add imm0,imm0,arg_x)
-dnl         __(ref_global(imm2,ref_base))
-dnl         __(load_highbit(imm3))
-dnl         __(ref_global(imm1,oldspace_dnode_count))
-dnl         __(sub imm0,imm0,imm2)
-dnl         __(srri(imm0,imm0,dnode_shift))       
-dnl         __(cmplr(imm0,imm1))
-dnl         __(extract_bit_shift_count(imm4,imm0))
-dnl         __(srri(imm0,imm0,bitmap_shift))       
-dnl         __(srr(imm3,imm3,imm4))
-dnl         __(ref_global(imm2,refbits))
-dnl         __(bgelr)
-dnl         __(slri(imm0,imm0,word_shift))
-dnl         __(ldrx(imm1,imm2,imm0))
-dnl         __(and. imm1,imm1,imm3)
-dnl         __(bnelr)        
-dnl 1:      __(lrarx(imm1,imm2,imm0))
-dnl         __(or imm1,imm1,imm3)
-dnl         __(strcx(imm1,imm2,imm0))
-dnl         __(bne- 1b)
-dnl         __(isync)
-dnl         __(bx lr)
-dnl 
+        __(bxls lr)
+        __(add imm0,imm0,arg_x)
+        __(ref_global(temp0,ref_base))
+        __(sub imm0,imm0,temp0)
+        __(mov imm0,imm0,lsr #dnode_shift)
+        __(ref_global(temp0,oldspace_dnode_count))
+        __(cmp imm0,temp0)
+        __(bxhs lr)
+        __(and imm2,imm0,#31)
+        __(mov imm1,#0x80000000)
+        __(mov imm1,imm1,lsr imm2)
+        __(mov imm0,imm0,lsr #bitmap_shift)
+        __(ref_global(imm2,refbits))
+        __(add imm2,imm2,imm0,lsl #word_shift)
+        __(ldr imm0,[imm2])
+        __(ands imm0,imm0,imm1)
+        __(bxne lr)
+        __(build_lisp_frame(imm0))
+        __(set_ref_bit(gvset))
+        __(bx lr)
+
+        
 dnl /* This is a special case of storing into a gvector: if we need to memoize  */
 dnl /* the store, record the address of the hash-table vector in the refmap,  */
@@ -987,5 +1039,5 @@
         __(mov imm0,temp2,lsl #num_subtag_bits-word_shift)
         __(orr imm0,imm0,#subtag_u32_vector)
-        __(stack_allocate_zeroed_word_vector(imm0,temp2))
+        __(stack_allocate_zeroed_ivector(imm0,temp2))
         __(mov imm0,#subtag_simple_vector)
         __(strb imm0,[sp,#0])
@@ -1014,5 +1066,5 @@
         __(mov imm0,nargs,lsl #num_subtag_bits-fixnumshift)
         __(orr imm0,imm0,#subtag_u32_vector)
-        __(stack_allocate_zeroed_word_vector(imm0,imm1))
+        __(stack_allocate_zeroed_ivector(imm0,imm1))
         __(mov imm0,#subtag_simple_vector)
         __(strb imm0,[sp,#0])
@@ -1043,5 +1095,5 @@
 dnl  /* but it's better to check now than to crash later. */
 dnl  
-dnl  __(cmpri(arg_z,nil_value))
+dnl  __(cmp arg_z,#nil_value)
 dnl  __(mov arg_x,arg_z) /* fast  */
 dnl  __(mov temp1,arg_z) /* slow  */
@@ -1067,5 +1119,5 @@
 dnl  __(mov arg_x,arg_y)
 dnl 1:
-dnl  __(cmpri(cr0,arg_x,nil_value))
+dnl  __(cmp arg_x,#nil_value)
 dnl  __(la imm0,node_size(imm0))
 dnl  __(_cdr(arg_x,arg_x))
@@ -1074,9 +1126,9 @@
 dnl  /* Determine word count, add 1 (to align), and make room.  */
 dnl  /* if count is 0, make an empty tsp frame and exit  */
-dnl  __(cmpri(cr0,imm0,0))
+dnl  __(cmp imm0,#0)
 dnl  __(add imm1,imm0,imm0)
 dnl  __(add imm1,imm1,imm0)
 dnl         __(dnode_align(imm1,imm1,node_size))
-dnl  __(bne+ cr0,2f)
+dnl  __(bne+ 2f)
 dnl   __(TSP_Alloc_Fixed_Boxed(2*node_size))
 dnl   __(bx lr)
@@ -1097,5 +1149,5 @@
 dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer]) /* Need to reload after trap  */
 dnl         __(ldrx(temp3,imm4,imm0))
-dnl  __(cmpri(cr0,arg_x,nil_value))
+dnl  __(cmp arg_x,#nil_value)
 dnl         __(mov temp2,#unbound_marker)
 dnl         __(beq cr1,4f)
@@ -1107,5 +1159,5 @@
 dnl         __(str temp2,imm4,imm0)
 dnl  __(mov imm1,imm2)
-dnl  __(bne cr0,3b)
+dnl  __(bne 3b)
 dnl  __(str(imm2,tcr.db_link(rcontext)))
 dnl  __(bx lr)
@@ -1127,5 +1179,5 @@
         __(mov imm0,#subtag_u32_vector)
         __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
-        __(stack_allocate_zeroed_word_vector(imm0,imm1))
+        __(stack_allocate_zeroed_ivector(imm0,imm1))
         __(unbox_fixnum(imm0,arg_z))
         __(strb imm0,[sp])
@@ -1151,5 +1203,5 @@
         __(cmp imm1,#stack_alloc_limit)
         __(bhs 9f)
-        __(stack_allocate_zeroed_word_vector(imm0,imm1))
+        __(stack_allocate_zeroed_ivector(imm0,imm1))
         __(add arg_z,sp,#fulltag_misc)
         __(bx lr)
@@ -1234,27 +1286,21 @@
         __(bx lr)
 
-dnl /* Indicate whether &optional arguments were actually supplied.  nargs  */
-dnl /* contains the actual arg count (minus the number of required args);  */
-dnl /* imm0 contains the number of &optional args in the lambda list.  */
-dnl /* Note that nargs may be > imm0 if &rest/&key is involved.  */
-dnl _spentry(opt_supplied_p)
-dnl  __(mov imm1,#0)
-dnl 1:
-dnl  /* (vpush (< imm1 nargs))  */
-dnl   __(xor imm2,imm1,nargs)
-dnl   __(srawi imm2,imm2,31)
-dnl   __(or imm2,imm2,imm1)
-dnl   __(addi imm1,imm1,#fixnumone)
-dnl   __(cmpr(cr0,imm1,imm0))
-dnl   __(subf imm2,nargs,imm2)
-dnl   __(srwi imm2,imm2,31)
-dnl   __(insrwi imm2,imm2,1,27)
-dnl   __(addi imm2,imm2,nil_value)
-dnl   __(vpush1(imm2))
-dnl   __(bne cr0,1b)
-dnl   __(bx lr)
-dnl  
-dnl 
-dnl 
+/* Indicate whether &optional arguments were actually supplied.  nargs  */
+/* contains the actual arg count (minus the number of required args);  */
+/* imm0 contains the number of &optional args in the lambda list.  */
+/* Note that nargs may be > imm0 if &rest/&key is involved.  */
+_spentry(opt_supplied_p)
+        __(mov imm1,#0)
+        __(mov arg_x,#nil_value)
+        __(add arg_x,arg_x,#t_offset)        
+1:     
+        /* (vpush (< imm1 nargs))  */
+        __(cmp imm1,nargs)
+        __(subeq imm1,imm1,#t_offset)
+        __(vpush1(imm1))
+        __(cmp imm1,imm0)
+        __(bne 1b)
+        __(bx lr)
+
 /* Cons a list of length nargs  and vpush it.  */
 /* Use this entry point to heap-cons a simple &rest arg.  */
@@ -1304,6 +1350,6 @@
         __(vpush1(arg_z))
         __(bx lr)
-dnl 
-dnl  
+
+
 dnl _spentry(simple_keywords)
 dnl  __(mov imm0,#0)
@@ -1345,7 +1391,7 @@
 dnl  /* So, the number of args pushed so far is the larger of nargs  */
 dnl  /* and the (canonical) total of required/&optional args received.  */
-dnl  __(cmpr(cr0,nargs,imm0))
+dnl  __(cmpr(nargs,imm0))
 dnl  __(add arg_z,vsp,nargs)
-dnl  __(bge+ cr0,1f)
+dnl  __(bge+ 1f)
 dnl  __(add arg_z,vsp,imm0)
 dnl 1:
@@ -1358,5 +1404,5 @@
 dnl  /* If there aren't any such pairs, the first step is the last  */
 dnl  /* step.  */
-dnl  __(cmpri(cr0,imm3,0))
+dnl  __(cmp imm3,#0)
 dnl  __(mov arg_z,#0)
 dnl  __(sub imm1,nargs,imm0)
@@ -1366,13 +1412,13 @@
 dnl 2:
 dnl  __(addi arg_z,arg_z,fixnum_one)
-dnl  __(cmplr(cr0,arg_z,imm3))
+dnl  __(cmplr(arg_z,imm3))
 dnl  __(mov imm5,#nil_value)
 dnl  __(vpush1(imm5))
 dnl  __(vpush1(imm5))
 dnl 3:
-dnl  __(bne cr0,2b)
+dnl  __(bne 2b)
 dnl  __(andi. arg_z,imm1,fixnum_one)
 dnl  __(blelr cr1) /* no keyword/value pairs to consider.  */
-dnl  __(bne cr0,odd_keywords)
+dnl  __(bne odd_keywords)
 dnl  /* We have key/value pairs.  Move them to the top of the vstack,  */
 dnl  /* then set the value/supplied-p vars to NIL.  */
@@ -1393,5 +1439,5 @@
 dnl  __(mov imm4,#nil_value)
 dnl  __(subi arg_z,arg_z,2<<fixnumshift)
-dnl  __(cmplri(cr0,arg_z,0))
+dnl  __(cmplri(arg_z,0))
 dnl  __(ldr arg_x,[varptr,#node_size*0])
 dnl  __(ldr arg_y,[varptr,#node_size*1])
@@ -1402,5 +1448,5 @@
 dnl  __(str(arg_y,node_size*1(valptr)))
 dnl  __(la valptr,node_size*2(valptr))
-dnl  __(bne cr0,4b)
+dnl  __(bne 4b)
 dnl 
 dnl 
@@ -1416,5 +1462,5 @@
 dnl  __(mov imm4,valptr)
 dnl 5:
-dnl         __(cmpri(cr0,keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
+dnl         __(cmpri(keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
 dnl  __(ldru(arg_z,-node_size(valptr)))
 dnl  __(ldru(arg_y,-node_size(valptr)))
@@ -1425,5 +1471,5 @@
 dnl  __(cmpr(cr7,valptr,limit))
 dnl  __(bne cr6,6f)
-dnl         __(bge cr0,6f) /* Already seen :allow-other-keys  */
+dnl         __(bge 6f) /* Already seen :allow-other-keys  */
 dnl         __(ori keyword_flags,keyword_flags,16<<fixnumshift)
 dnl  __(beq cr1,6f)
@@ -1438,13 +1484,13 @@
 dnl  __(cmpr(cr1,imm0,imm3))
 dnl  __(ldrx(arg_x,keyword_vector,imm1))
-dnl  __(cmpr(cr0,arg_x,arg_z))
+dnl  __(cmpr(arg_x,arg_z))
 dnl  __(addi imm1,imm1,fixnum_one)
-dnl  __(bne cr0,8f)
+dnl  __(bne 8f)
 dnl  __(add imm0,imm0,imm0)
 dnl  __(sub imm0,varptr,imm0)
 dnl  __(ldr arg_x,[imm0,#0])
-dnl  __(cmpri(cr0,arg_x,nil_value))
+dnl  __(cmp arg_x,#nil_value)
 dnl  __(mov arg_z,#t_value)
-dnl  __(bne cr0,9f)
+dnl  __(bne 9f)
 dnl  __(str(arg_y,node_size(imm0)))
 dnl  __(str(arg_z,0(imm0)))
@@ -1466,6 +1512,6 @@
 dnl  /* keyword/value pairs from the vstack.  */
 dnl  __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift))
-dnl  __(cmpri(cr0,imm0,2<<fixnumshift))
-dnl  __(beq- cr0,badkeys)
+dnl  __(cmpri(imm0,2<<fixnumshift))
+dnl  __(beq- badkeys)
 dnl  __(andi. imm2,keyword_flags,4<<fixnumshift)
 dnl  __(bnelr cr0)
@@ -1502,142 +1548,144 @@
         __(jump_fname)
 
-dnl /* As in the heap-consed cases, only stack-cons the &rest arg  */
-dnl _spentry(stack_rest_arg)
-dnl  __(mov imm0,#0)
-dnl  __(vpush_argregs())
-dnl         __(b _SPstack_cons_rest_arg)
-dnl 
-dnl  
-dnl _spentry(req_stack_rest_arg)
-dnl  __(vpush_argregs())
-dnl         __(b _SPstack_cons_rest_arg)
-dnl  
-dnl _spentry(stack_cons_rest_arg)
-dnl  __(sub imm1,nargs,imm0)
-dnl  __(cmpri(cr0,imm1,0))
-dnl  __(cmpri(cr1,imm1,(4096-dnode_size)/2))
-dnl  __(mov arg_z,#nil_value)
-dnl  __(ble cr0,2f)  /* always temp-push something.  */
-dnl  __(bge cr1,3f)
-dnl  __(add imm1,imm1,imm1)
-dnl  __(dnode_align(imm2,imm1,tsp_frame.fixed_overhead))
-dnl  __(TSP_Alloc_Var_Boxed(imm2,imm3))
-dnl  __(la imm0,tsp_frame.data_offset+fulltag_cons(tsp))
-dnl 1:
-dnl  __(cmpri(cr0,imm1,cons.size)) /* last time through ?  */
-dnl  __(subi imm1,imm1,cons.size)
-dnl  __(vpop(arg_x))
-dnl  __(_rplacd(imm0,arg_z))
-dnl  __(_rplaca(imm0,arg_x))
-dnl  __(mov arg_z,imm0)
-dnl  __(la imm0,cons.size(imm0))
-dnl  __(bne cr0,1b)
-dnl  __(vpush1(arg_z))
-dnl  __(bx lr)
-dnl 2:
-dnl  __(TSP_Alloc_Fixed_Unboxed(0))
-dnl  __(vpush1(arg_z))
-dnl  __(bx lr)
-dnl 3:
-dnl  __(TSP_Alloc_Fixed_Unboxed(0))
-dnl  __(b _SPheap_cons_rest_arg)
-dnl 
+/* As in the heap-consed cases, only stack-cons the &rest arg  */
+_spentry(stack_rest_arg)
+        __(mov imm0,#0)
+        __(vpush_argregs())
+        __(b _SPstack_cons_rest_arg)
+
+_spentry(req_stack_rest_arg)
+        __(vpush_argregs())
+        __(b _SPstack_cons_rest_arg)
+
+_spentry(stack_cons_rest_arg)
+        __(sub imm1,nargs,imm0)
+        __(cmp imm1,#0)
+        __(mov arg_z,#nil_value)
+        __(ble 2f)  /* always temp-push something.  */
+        __(add imm1,imm1,imm1)
+        __(mov temp0,imm1)
+        __(add imm1,imm1,#node_size)
+        __(dnode_align(imm0,imm1,node_size))
+        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
+        __(orr imm1,imm1,#subtag_u32_vector)
+        __(cmp imm1,#stack_alloc_limit)
+        __(bge 3f)
+        __(stack_allocate_zeroed_ivector(imm1,imm0))
+        __(mov imm0,#subtag_simple_vector)
+        __(strb imm0,[sp])
+        __(add imm0,sp,#dnode_size+fulltag_cons)
+1:
+        __(subs temp0,temp0,#fixnumone)
+        __(vpop1(arg_x))
+        __(_rplacd(imm0,arg_z))
+        __(_rplaca(imm0,arg_x))
+        __(mov arg_z,imm0)
+        __(add imm0,imm0,#cons.size)
+        __(bne 1b)
+        __(vpush1(arg_z))
+        __(bx lr)
+2:
+        __(movc16(imm0,make_header(1,subtag_u32_vector)))
+        __(mov imm1,#0)
+        __(stmdb sp!,{imm0,imm1})
+        __(vpush1(arg_z))
+        __(bx lr)
+3:
+        __(movc16(imm0,make_header(1,subtag_u32_vector)))
+        __(mov imm1,#0)
+        __(stmdb sp!,{imm0,imm1})
+        __(b _SPheap_cons_rest_arg)
+
 	
-dnl /* Prepend all but the first two (closure code, fn) and last two  */
-dnl /* (function name, lfbits) elements of nfn to the "arglist".  */
-dnl /* Doing things this way (the same way that 68K MCL does) lets  */
-dnl /* functions which take "inherited arguments" work consistently  */
-dnl /* even in cases where no closure object is created.  */
-dnl _spentry(call_closure)        
-dnl  __(cmpri(cr0,nargs,nargregs<<fixnumshift))
-dnl  __(cmpri(cr1,nargs,fixnum_one))
-dnl  __(vector_length(imm0,nfn,imm0))
-dnl  __(subi imm0,imm0,4<<fixnumshift) /* imm0 = inherited arg count  */
-dnl  __(mov imm1,#misc_data_offset+(2<<fixnumshift)) /* point to 1st arg  */
-dnl  __(mov imm4,#nil_value)
-dnl  __(ble+ cr0,local_label(no_insert))
-dnl  /* Some arguments have already been vpushed.  Vpush imm0's worth  */
-dnl  /* of NILs, copy those arguments that have already been vpushed from  */
-dnl  /* the old TOS to the new, then insert all of the inerited args  */
-dnl  /* and go to the function.  */
-dnl  __(mov imm2,#0)
-dnl local_label(push_nil_loop):
-dnl  __(addi imm2,imm2,fixnum_one)
-dnl  __(cmpr(cr2,imm2,imm0))
-dnl  __(vpush1(imm4))
-dnl  __(bne cr2,local_label(push_nil_loop))
-dnl 
-dnl  __(mov imm3,vsp)
-dnl  __(add imm4,vsp,imm0)
-dnl  __(subi imm2,nargs,nargregs<<fixnumshift)
-dnl local_label(copy_already_loop):
-dnl  __(cmpri(cr2,imm2,fixnum_one))
-dnl  __(subi imm2,imm2,fixnum_one)
-dnl  __(ldr fname,[imm4,#0])
-dnl  __(addi imm4,imm4,fixnum_one)
-dnl  __(str(fname,0(imm3)))
-dnl  __(addi imm3,imm3,fixnum_one)
-dnl  __(bne cr2,local_label(copy_already_loop))
-dnl 
-dnl local_label(insert_loop):
-dnl  __(cmpri(cr2,imm0,fixnum_one))
-dnl  __(ldrx(fname,nfn,imm1))
-dnl  __(addi imm1,imm1,fixnum_one)
-dnl  __(addi nargs,nargs,fixnum_one)
-dnl  __(subi imm0,imm0,fixnum_one)
-dnl  __(push(fname,imm4))
-dnl  __(bne cr2,local_label(insert_loop))
-dnl  __(b local_label(go))
-dnl local_label(no_insert):
-dnl  /* nargregs or fewer args were already vpushed.  */
-dnl  /* if exactly nargregs, vpush remaining inherited vars.  */
-dnl  __(add imm2,imm1,imm0)
-dnl  __(bne cr0,local_label(set_regs))
-dnl local_label(vpush_remaining):
-dnl  __(cmpri(cr2,imm0,fixnum_one))
-dnl  __(ldrx(fname,nfn,imm1))
-dnl  __(addi imm1,imm1,fixnum_one)
-dnl  __(vpush1(fname))
-dnl  __(subi imm0,imm0,fixnum_one)
-dnl  __(addi nargs,nargs,fixnum_one)
-dnl  __(bne cr2,local_label(vpush_remaining))
-dnl  __(b local_label(go))
-dnl local_label(set_regs):
-dnl  /* if nargs was > 1 (and we know that it was < 3), it must have  */
-dnl  /* been 2.  Set arg_x, then vpush the remaining args.  */
-dnl  __(ble cr1,local_label(set_y_z))
-dnl local_label(set_arg_x):
-dnl  __(subi imm0,imm0,fixnum_one)
-dnl  __(cmpri(cr0,imm0,0))
-dnl  __(subi imm2,imm2,fixnum_one)
-dnl  __(ldrx(arg_x,nfn,imm2))
-dnl  __(addi nargs,nargs,fixnum_one)
-dnl  __(bne cr0,local_label(vpush_remaining))
-dnl  __(b local_label(go))
-dnl  /* Maybe set arg_y or arg_z, preceding args  */
-dnl local_label(set_y_z):
-dnl  __(bne cr1,local_label(set_arg_z))
-dnl  /* Set arg_y, maybe arg_x, preceding args  */
-dnl local_label(set_arg_y):
-dnl  __(subi imm0,imm0,fixnum_one)
-dnl  __(cmpri(cr0,imm0,0))
-dnl  __(subi imm2,imm2,fixnum_one)
-dnl  __(ldrx(arg_y,nfn,imm2))
-dnl  __(addi nargs,nargs,fixnum_one)
-dnl  __(bne cr0,local_label(set_arg_x))
-dnl  __(b local_label(go))
-dnl local_label(set_arg_z):
-dnl  __(subi imm0,imm0,fixnum_one)
-dnl  __(cmpri(cr0,imm0,0))
-dnl  __(subi imm2,imm2,fixnum_one)
-dnl  __(ldrx(arg_z,nfn,imm2))
-dnl  __(addi nargs,nargs,fixnum_one)
-dnl  __(bne cr0,local_label(set_arg_y))
-dnl 
-dnl local_label(go):
-dnl  __(vrefr(nfn,nfn,1))
-dnl  __(ldr loc_pc,[nfn,#_function.codevector])
-dnl  __(mtctr loc_pc)
-dnl  __(bctr)
+/* Prepend all but the first three (entrypoint, closure code, fn) and last two  */
+/* (function name, lfbits) elements of nfn to the "arglist".  */
+/* functions which take "inherited arguments" work consistently  */
+/* even in cases where no closure object is created.  */
+_spentry(call_closure)        
+        __(cmp nargs,nargregs<<fixnumshift)
+        __(vector_length(imm0,nfn,imm0))
+        __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count  */
+        __(ble local_label(no_insert))
+        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
+        /* of NILs, copy those arguments that have already been vpushed from  */
+        /* the old TOS to the new, then insert all of the inerited args  */
+        /* and go to the function.  */
+        __(vpush_all_argregs())
+        __(mov arg_x,imm0)
+        __(mov arg_y,#nil_value)
+local_label(push_nil_loop):
+        __(subs arg_x,arg_x,#fixnumone)
+        __(vpush1(arg_y))
+        __(bne local_label(push_nil_loop))
+        __(add arg_y,vsp,imm0)
+        __(mov imm1,#0)
+local_label(copy_already_loop): 
+        __(ldr arg_x,[vsp,imm1])
+        __(str arg_x,[arg_y,imm1])
+        __(add imm1,imm1,#fixnumone)
+        __(cmp imm1,imm0)
+        __(bne local_label(copy_already_loop))
+        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
+        __(add arg_y,vsp,nargs)
+        __(add arg_y,arg_y,imm0)
+local_label(insert_loop):
+        __(subs imm0,imm0,#fixnumone)
+        __(ldr fname,[nfn,imm1])
+        __(add imm1,imm1,#fixnumone)
+        __(add nargs,nargs,#fixnumone)
+        __(push1(fname,arg_y))
+        __(bne local_label(insert_loop))
+        __(vpop_all_argregs())
+        __(b local_label(go))
+local_label(no_insert):
+/* nargregs or fewer args were already vpushed.  */
+/* if exactly nargregs, vpush remaining inherited vars.  */
+        __(cmp nargs,#nargregs<<fixnumshift)
+        __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift))
+        __(bne local_label(set_regs))
+local_label(vpush_remaining):
+        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
+local_label(vpush_remaining_loop):              
+        __(ldr fname,[nfn,imm1])
+        __(add imm1,imm1,#fixnum_one)
+        __(vpush1(fname))
+        __(subs imm0,imm0,#fixnum_one)
+        __(add nargs,nargs,#fixnum_one)
+        __(bne  local_label(vpush_remaining_loop))
+        __(b local_label(go))
+local_label(set_regs):
+        /* if nargs was > 1 (and we know that it was < 3), it must have  */
+        /* been 2.  Set arg_x, then vpush the remaining args.  */
+        __(cmp nargs,#fixnumone)
+        __(ble local_label(set_y_z))
+local_label(set_arg_x):
+        __(subs imm0,imm0,#fixnum_one)
+        __(sub imm1,imm1,#fixnum_one)
+        __(ldr arg_x,[nfn,imm1])
+        __(add nargs,nargs,#fixnum_one)
+        __(bne local_label(vpush_remaining))
+        __(b local_label(go))
+        /* Maybe set arg_y or arg_z, preceding args  */
+local_label(set_y_z):
+        __(cmp nargs,#fixnumone)
+        __(bne local_label(set_arg_z))
+        /* Set arg_y, maybe arg_x, preceding args  */
+local_label(set_arg_y):
+        __(subs imm0,imm0,fixnum_one)
+        __(sub imm1,imm1,#fixnum_one)
+        __(ldr arg_y,[nfn,imm1])
+        __(add nargs,nargs,#fixnum_one)
+        __(bne local_label(set_arg_x))
+        __(b local_label(go))
+local_label(set_arg_z):
+        __(subs imm0,imm0,#fixnum_one)
+        __(sub imm1,imm1,#fixnum_one)
+        __(ldr arg_z,[nfn,imm1])
+        __(add nargs,nargs,#fixnum_one)
+        __(bne local_label(set_arg_y))
+ 
+local_label(go):
+        __(vrefr(nfn,nfn,2))
+        __(ldr pc,[nfn,#_function.entrypoint])
 
 
@@ -1828,60 +1876,63 @@
         __(b C(misc_ref_common))
 
-_spentry(builtin_aref1)
-        __(extract_typecode(imm0,arg_y))
-        __(cmp imm0,#min_vector_subtag)
-        __(box_fixnum(arg_x,imm0))
-        __(bgt _SPsubtag_misc_ref)
-        __(jump_builtin(_builtin_aref1,2))
-
-dnl /* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
-dnl /* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
-dnl /* in arg_z on exit.  */
-dnl _spentry(makestackblock)
-dnl  __(unbox_fixnum(imm0,arg_z))
-dnl         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
-dnl  __(cmplri(cr0,imm0,tstack_alloc_limit))
-dnl  __(bge cr0,1f)
-dnl  __(TSP_Alloc_Var_Unboxed(imm0))
-dnl  __(mov imm0,#macptr_header)
-dnl  __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
-dnl  __(str(imm0,tsp_frame.data_offset(tsp)))
-dnl  __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
-dnl  __(str(imm1,macptr.address(arg_z)))
-dnl   __(stfd fp_zero,macptr.domain(arg_z))
-dnl  __(bx lr)
-dnl 
-dnl         /* Too big. Heap cons a gcable macptr  */
-dnl 1:
-dnl  __(TSP_Alloc_Fixed_Unboxed(0))
-dnl  __(set_nargs(1))
-dnl  __(mov fname,#nrs.new_gcable_ptr)
-dnl  __(jump_fname())
-dnl 
-dnl /* As above, only set the block's contents to 0.  */
-dnl _spentry(makestackblock0)
-dnl  __(unbox_fixnum(imm0,arg_z))
-dnl         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
-dnl  __(cmplri(cr0,imm0,tstack_alloc_limit))
-dnl  __(bge cr0,3f)
-dnl  __(TSP_Alloc_Var_Unboxed(imm0))
-dnl  __(Zero_TSP_Frame(imm0,imm1))
-dnl  __(mov imm0,#macptr_header)
-dnl  __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
-dnl  __(str(imm0,tsp_frame.data_offset(tsp)))
-dnl  __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
-dnl  __(str(imm1,macptr.address(arg_z))) /* makestackblock0 expects the address to be in imm1  */
-dnl  __(stfd fp_zero,macptr.domain(arg_z))
-dnl  __(bx lr)
-dnl 
-dnl         /* Too big. Heap cons a gcable macptr  */
-dnl 3:
-dnl  __(TSP_Alloc_Fixed_Unboxed(0)) /* "raw" block to make the compiler happy  */
-dnl 
-dnl  __(mov arg_y,arg_z) /* save block size  */
-dnl  __(mov arg_z,#t_value) /* clear-p arg to %new-gcable-ptr  */
-dnl  __(set_nargs(2))
-dnl  __(mov fname,#nrs.new_gcable_ptr)
-dnl  __(jump_fname())
+
+/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
+/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
+/* in arg_z on exit.  */
+_spentry(makestackblock)
+        __(unbox_fixnum(imm1,arg_z))
+        __(dnode_align(imm1,imm1,0))
+        __(add imm1,imm1,#macptr.size+node_size)
+        __(add imm0,imm1,#node_size)
+        __(mov imm1,imm1,lsl #num_subtag_bits)
+        __(orr imm1,imm1,#subtag_u8_vector)
+        __(cmp imm0,#stack_alloc_limit)
+        __(bhs 1f)
+        __(stack_allocate_ivector(imm1,imm0))
+        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
+        __(str imm1,[sp,#dnode_size])
+        __(mov imm0,#0)
+        __(str imm0,[sp,#dnode_size+macptr.type-fulltag_misc])
+        __(str imm0,[sp,#dnode_size+macptr.domain-fulltag_misc])
+        __(add imm0,sp,#macptr.size+dnode_size)
+        __(str imm0,[sp,#dnode_size+macptr.address-fulltag_misc])
+        __(add arg_z,sp,#dnode_size+fulltag_misc)
+        __(bx lr)
+
+        /* Too big. Heap cons a gcable macptr  */
+1:
+        __(mov imm1,#subtag_u8_vector)
+        __(str imm1,[sp,#-dnode_size]!)
+        __(set_nargs(1))
+        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
+        __(jump_fname())
+
+/* As above, only set the block's contents to 0.  */
+_spentry(makestackblock0)
+        __(unbox_fixnum(imm1,arg_z))
+        __(dnode_align(imm1,imm1,0))
+        __(add imm1,imm1,#macptr.size+node_size)
+        __(add imm0,imm1,#node_size)
+        __(mov imm1,imm1,lsl #num_subtag_bits)
+        __(orr imm1,imm1,#subtag_u8_vector)
+        __(cmp imm0,#stack_alloc_limit)
+        __(bhs 1f)
+        __(stack_allocate_zeroed_ivector(imm1,imm0))
+        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
+        __(str imm1,[sp,#dnode_size])
+        __(add imm0,sp,#macptr.size+dnode_size)
+        __(str imm0,[sp,#dnode_size+macptr.address-fulltag_misc])
+        __(add arg_z,sp,#dnode_size+fulltag_misc)
+        __(bx lr)
+        /* Too big. Heap cons a gcable macptr  */
+1:
+        __(mov imm1,#subtag_u8_vector)
+        __(str imm1,[sp,#-dnode_size]!)
+        __(mov arg_y,arg_z) /* save block size  */
+        __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr  */
+        __(add arg_z,arg_z,#t_offset)
+        __(set_nargs(2))
+        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
+        __(jump_fname())
 
 /* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
@@ -1895,5 +1946,5 @@
         __(cmp imm0,#stack_alloc_limit)
         __(bge 4f)
-        __(stack_allocate_zeroed_word_vector(imm1,imm0))
+        __(stack_allocate_zeroed_ivector(imm1,imm0))
         __(mov imm0,#subtag_simple_vector)
         __(strb imm0,[sp,#0])
@@ -1926,30 +1977,26 @@
         __(bx lr)
 
-dnl /* subtype (boxed) vpushed before initial values. (Had better be a  */
-dnl /* node header subtag.) Nargs set to count of things vpushed.  */
-dnl 
-dnl _spentry(stkgvector)
-dnl  __(la imm0,-fixnum_one(nargs))
-dnl  __(cmpri(cr1,imm0,0))
-dnl  __(add imm1,vsp,nargs)
-dnl  __(ldru(temp0,-node_size(imm1)))
-dnl  __(slri(imm2,imm0,num_subtag_bits-fixnumshift))
-dnl   __(rlwimi imm2,temp0,32-fixnumshift,32-num_subtag_bits,31)
-dnl         __(dnode_align(imm0,imm0,node_size+tsp_frame.fixed_overhead))
-dnl  __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
-dnl  __(str(imm2,tsp_frame.data_offset(tsp)))
-dnl  __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
-dnl  __(la imm3,misc_header_offset(arg_z))
-dnl  __(mov imm0,#fixnum1)
-dnl  __(b 2f)
-dnl 1:
-dnl  __(addi imm0,imm0,fixnum1)
-dnl  __(cmpr(cr1,imm0,nargs))
-dnl  __(ldru(temp0,-node_size(imm1)))
-dnl  __(stru(temp0,node_size(imm3)))
-dnl 2:
-dnl  __(bne cr1,1b)
-dnl  __(add vsp,vsp,nargs)
-dnl  __(bx lr)
+/* subtype (boxed) vpushed before initial values. (Had better be a  */
+/* node header subtag.) Nargs set to count of things vpushed.  */
+
+_spentry(stkgvector)
+        __(sub imm0,nargs,#fixnumone)
+        __(ldr temp0,[vsp,imm0])
+        __(dnode_align(temp1,imm0,node_size))
+        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
+        __(orr imm1,imm1,#subtag_u32_vector)
+        __(stack_allocate_zeroed_ivector(imm1,temp1))
+        __(unbox_fixnum(imm1,temp0))
+        __(strb imm1,[sp])
+        __(add arg_z,sp,#fulltag_misc)
+        __(add imm0,sp,nargs)
+        __(b 2f)
+1:
+        __(vpop1(temp0))
+        __(push1(temp0,imm0))
+2:      __(subs nargs,nargs,#fixnumone)
+        __(bne 1b)
+        __(add vsp,vsp,#fixnumone)
+        __(bx lr)
 
 /* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
@@ -1994,255 +2041,42 @@
         __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
 
-dnl         
-dnl 
-dnl /* Destructuring-bind, macro-bind.  */
-dnl    
-dnl /* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
-dnl /* likewise immX regs.  */
-dnl /* arg_z preserved, nothing else in particular defined on exit.  */
-dnl /* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
-dnl /* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
-dnl /* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
-dnl /* opt-supplied-p flag in PPC bit mask_initopt,  */
-dnl /* keyp flag in PPC bit mask_keyp,  */
-dnl /* &allow-other-keys flag in PPC bit mask_aok,  */
-dnl /* &rest flag in PPC bit mask_restp.  */
-dnl /* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
-dnl /* length key count.  */
-dnl 
-dnl _spentry(macro_bind)
-dnl   __(mov whole_reg,arg_reg)
-dnl   __(extract_lisptag(imm0,arg_reg))
-dnl   __(cmpri(cr0,imm0,tag_list))
-dnl   __(bne- cr0,1f)
-dnl   __(_cdr(arg_reg,arg_reg))
-dnl   __(b (local_label(destbind1)))
-dnl 1:
-dnl  __(mov arg_y,#XCALLNOMATCH)
-dnl  __(mov arg_z,whole_reg)
-dnl  __(set_nargs(2))
-dnl  __(b _SPksignalerr)
-dnl 
-dnl 
-dnl _spentry(destructuring_bind)
-dnl  __(Mov whole_reg,arg_reg)
-dnl         __(b local_label(destbind1))
-dnl  
-dnl _spentry(destructuring_bind_inner)
-dnl  __(mov whole_reg,arg_z)
-dnl local_label(destbind1): 
-dnl  /* Extract required arg count.  */
-dnl  /* A bug in gas: can't handle shift count of "32" (= 0  */
-dnl  ifelse(eval(mask_req_width+mask_req_start),eval(32),`
-dnl  __(clrlwi. imm0,nargs,mask_req_start)
-dnl  ',`
-dnl  __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
-dnl  ')
-dnl  __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
-dnl  __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
-dnl  __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
-dnl  __(cmpri(cr4,imm4,0))
-dnl  __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
-dnl  __(cmpri(cr5,imm4,0))
-dnl  __(cmpri(cr1,imm1,0))
-dnl  __(cmpri(cr2,imm2,0))
-dnl  /* Save entry vsp in case of error.  */
-dnl  __(mov imm4,vsp)
-dnl  __(beq cr0,2f)
-dnl 1:
-dnl  __(cmpri(cr7,arg_reg,nil_value))
-dnl   __(extract_lisptag(imm3,arg_reg))
-dnl   __(cmpri(cr3,imm3,tag_list))
-dnl  __(subi imm0,imm0,1)
-dnl  __(cmpri(cr0,imm0,0))
-dnl  __(beq cr7,toofew)
-dnl  __(bne cr3,badlist)
-dnl  __(ldr arg_x,[arg_reg,#cons.car])
-dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
-dnl  __(vpush1(arg_x))
-dnl  __(bne cr0,1b)
-dnl 2:
-dnl  __(beq cr1,rest_keys)
-dnl  __(bne cr2,opt_supp)
-dnl  /* 'simple' &optionals:  no supplied-p, default to nil.  */
-dnl simple_opt_loop:
-dnl  __(cmpri(cr0,arg_reg,nil_value))
-dnl   __(extract_lisptag(imm3,arg_reg))
-dnl   __(cmpri(cr3,imm3,tag_list))
-dnl  __(subi imm1,imm1,1)
-dnl  __(cmpri(cr1,imm1,0))
-dnl  __(mov imm5,#nil_value)
-dnl  __(beq cr0,default_simple_opt)
-dnl  __(bne cr3,badlist)
-dnl  __(ldr arg_x,[arg_reg,#cons.car])
-dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
-dnl  __(vpush1(arg_x))
-dnl  __(bne cr1,simple_opt_loop)
-dnl  __(b rest_keys)
-dnl default_simple_opt_loop:
-dnl  __(subi imm1,imm1,1)
-dnl  __(cmpri(cr1,imm1,0))
-dnl default_simple_opt:
-dnl  __(vpush1(imm5))
-dnl  __(bne cr1,default_simple_opt_loop)
-dnl  __(b rest_keys)
-dnl  /* Provide supplied-p vars for the &optionals.  */
-dnl opt_supp:
-dnl  __(mov arg_y,#t_value)
-dnl opt_supp_loop:
-dnl  __(cmpri(cr0,arg_reg,nil_value))
-dnl   __(extract_lisptag(imm3,arg_reg))
-dnl   __(cmpri(cr3,imm3,tag_list))
-dnl  __(subi imm1,imm1,1)
-dnl  __(cmpri(cr1,imm1,0))
-dnl  __(beq cr0,default_hard_opt)
-dnl  __(bne cr3,badlist)
-dnl  __(ldr arg_x,[arg_reg,#cons.car])
-dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
-dnl  __(vpush1(arg_x))
-dnl  __(vpush1(arg_y))
-dnl  __(bne cr1,opt_supp_loop)
-dnl  __(b rest_keys)
-dnl default_hard_opt_loop:
-dnl  __(subi imm1,imm1,1)
-dnl  __(cmpri(cr1,imm1,0))
-dnl default_hard_opt:
-dnl  __(vpush1(imm5))
-dnl  __(vpush1(imm5))
-dnl  __(bne cr1,default_hard_opt_loop)
-dnl rest_keys:
-dnl  __(cmpri(cr0,arg_reg,nil_value))
-dnl  __(bne cr5,have_rest)
-dnl  __(bne cr4,have_keys)
-dnl  __(bne cr0,toomany)
-dnl  __(bx lr)
-dnl have_rest:
-dnl  __(vpush1(arg_reg))
-dnl  __(beqlr cr4)
-dnl have_keys:
-dnl  /* Ensure that arg_reg contains a proper,even-length list.  */
-dnl  /* Insist that its length is <= 512 (as a cheap circularity check.)  */
-dnl  __(mov imm0,#256)
-dnl  __(mov arg_x,arg_reg)
-dnl count_keys_loop:
-dnl   __(extract_lisptag(imm3,arg_x))
-dnl   __(cmpri(cr3,imm3,tag_list))
-dnl  __(cmpri(cr0,arg_x,nil_value))
-dnl  __(subi imm0,imm0,1)
-dnl  __(cmpri(cr4,imm0,0))
-dnl  __(beq cr0,counted_keys)
-dnl  __(bne cr3,badlist)
-dnl  __(ldr arg_x,[arg_x,#cons.cdr])
-dnl   __(extract_lisptag(imm3,arg_x))
-dnl   __(cmpri(cr3,imm3,tag_list))
-dnl  __(blt cr4,toomany)
-dnl  __(cmpri(cr0,arg_x,nil_value))
-dnl  __(beq cr0,db_badkeys)
-dnl  __(bne cr3,badlist)
-dnl  __(ldr arg_x,[arg_x,#cons.cdr])
-dnl  __(b count_keys_loop)
-dnl counted_keys:
-dnl  /* We've got a proper, even-length list of key/value pairs in */
-dnl  /* arg_reg. For each keyword var in the lambda-list, push a pair */
-dnl  /* of NILs on the vstack.  */
-dnl  __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
-dnl  __(mov imm2,imm0)  /* save number of keys  */
-dnl  __(mov imm5,#nil_value)
-dnl  __(b push_pair_test)
-dnl push_pair_loop:
-dnl  __(cmpri(cr0,imm0,1))
-dnl  __(subi imm0,imm0,1)
-dnl  __(vpush1(imm5))
-dnl  __(vpush1(imm5))
-dnl push_pair_test:
-dnl  __(bne cr0,push_pair_loop)
-dnl  __(slwi imm2,imm2,dnode_shift)  /* pairs -> bytes  */
-dnl  __(add imm2,vsp,imm2)  /* imm2 points below pairs  */
-dnl  __(mov imm0,#0)   /* count unknown keywords so far  */
-dnl  __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
-dnl  __(extrwi nargs,nargs,mask_key_width,mask_key_start)
-dnl  /* Now, for each keyword/value pair in the list  */
-dnl  /*  a) if the keyword is found in the keyword vector, set the  */
-dnl  /*     corresponding entry on the vstack to the value and the  */
-dnl  /*     associated supplied-p var to T.  */
-dnl  /*  b) Regardless of whether or not the keyword is found,  */
-dnl         /*     if :ALLOW-OTHER-KEYS is provided with a non-nil value, */
-dnl  /*     set the low bit of imm1 to indicate that unknown keywords  */
-dnl  /*     are acceptable. (This bit is pre-set above to the value */
-dnl         /*     the encoded value of &allow_other_keys.) */
-dnl  /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
-dnl  /*     the count of unknown keywords in the high bits of imm1*/
-dnl  /* At the end of the list, signal an error if any unknown keywords were seen  */
-dnl  /* but not allowed.  Otherwise, return.  */
-dnl 
-dnl match_keys_loop:
-dnl  __(cmpri(cr0,arg_reg,nil_value))
-dnl  __(mov imm0,#0)
-dnl  __(mov imm3,#misc_data_offset)
-dnl  __(beq cr0,matched_keys)
-dnl  __(ldr arg_x,[arg_reg,#cons.car])
-dnl  __(mov arg_y,#nrs.kallowotherkeys)
-dnl  __(cmpr(cr3,arg_x,arg_y)) /* :ALLOW-OTHER-KEYS ?  */
-dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
-dnl  __(ldr arg_y,[arg_reg,#cons.car])
-dnl  __(cmpr(cr4,imm0,nargs))
-dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
-dnl  __(b match_test)
-dnl match_loop:
-dnl  __(ldrx(temp0,keyvect_reg,imm3))
-dnl  __(cmpr(cr0,arg_x,temp0))
-dnl  __(addi imm0,imm0,1)
-dnl  __(cmpr(cr4,imm0,nargs))
-dnl  __(addi imm3,imm3,node_size)
-dnl  __(bne cr0,match_test)
-dnl  /* Got a hit.  Unless this keyword's been seen already, set it.  */
-dnl  __(slwi imm0,imm0,dnode_shift)
-dnl  __(subf imm0,imm0,imm2)
-dnl  __(ldr temp0,[imm0,#0])
-dnl  __(cmpri(cr0,temp0,nil_value))
-dnl  __(mov temp0,#t_value)
-dnl  __(bne cr0,match_keys_loop) /* already saw this  */
-dnl  __(str(arg_y,node_size*1(imm0)))
-dnl  __(str(temp0,node_size*0(imm0)))
-dnl         __(bne cr3,match_keys_loop)
-dnl  __(b match_keys_check_aok)
-dnl match_test:
-dnl  __(bne cr4,match_loop)
-dnl         __(beq cr3,match_keys_check_aok)
-dnl         __(addi imm1,imm1,node_size)
-dnl         __(b match_keys_loop)
-dnl match_keys_check_aok:
-dnl         __(andi. imm0,imm1,2)  /* check "seen-aok" bit in imm1 */
-dnl         __(cmpri cr1,arg_y,nil_value) /* check value */
-dnl         __(ori imm1,imm1,2)
-dnl         __(bne cr0,match_keys_loop) /* duplicate aok */
-dnl         __(beq cr1,match_keys_loop)
-dnl         __(ori imm1,imm1,1)
-dnl  __(b match_keys_loop)
-dnl matched_keys:
-dnl         __(clrrwi. imm0,imm1,2)
-dnl         __(beqlr)
-dnl         __(andi. imm1,imm1,1)
-dnl         __(bnelr)
-dnl  /* Some unrecognized keywords.  Complain generically about  */
-dnl  /* invalid keywords.  */
-dnl db_badkeys:
-dnl  __(mov arg_y,#XBADKEYS)
-dnl  __(b destructure_error)
-dnl toomany:
-dnl  __(mov arg_y,#XCALLTOOMANY)
-dnl  __(b destructure_error)
-dnl toofew:
-dnl  __(mov arg_y,#XCALLTOOFEW)
-dnl  __(b destructure_error)
-dnl badlist:
-dnl  __(mov arg_y,#XCALLNOMATCH)
-dnl  /* b destructure_error  */
-dnl destructure_error:
-dnl  __(mov vsp,imm4)  /* undo everything done to the stack  */
-dnl  __(mov arg_z,whole_reg)
-dnl  __(set_nargs(2))
-dnl  __(b _SPksignalerr)
-dnl         
+
+
+/* Destructuring-bind, macro-bind.  */
+   
+/* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
+/* likewise immX regs.  */
+/* arg_z preserved, nothing else in particular defined on exit.  */
+/* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
+/* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
+/* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
+/* opt-supplied-p flag in PPC bit mask_initopt,  */
+/* keyp flag in PPC bit mask_keyp,  */
+/* &allow-other-keys flag in PPC bit mask_aok,  */
+/* &rest flag in PPC bit mask_restp.  */
+/* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
+/* length key count.  */
+
+_spentry(macro_bind)
+        __(mov whole_reg,arg_reg)
+        __(extract_lisptag(imm0,arg_reg))
+        __(cmp imm0,#tag_list)
+        __(bne 1f)
+        __(_cdr(arg_reg,arg_reg))
+        __(b C(destbind1))
+1:
+        __(mov arg_y,#XCALLNOMATCH)
+        __(mov arg_z,whole_reg)
+        __(set_nargs(2))
+        __(b _SPksignalerr)
+
+_spentry(destructuring_bind)
+        __(mov whole_reg,arg_reg)
+        __(b C(destbind1))
+
+_spentry(destructuring_bind_inner)
+        __(mov whole_reg,arg_z)
+        __(b C(destbind1))
+
 dnl /* vpush the values in the value set atop the vsp, incrementing nargs.  */
 dnl /* Discard the tsp frame; leave values atop the vsp.  */
@@ -2257,9 +2091,9 @@
 dnl local_label(walkloop):
 dnl  __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment  */
-dnl  __(cmpr(cr0,imm0,imm3)) /* last segment?  */
+dnl  __(cmpr(imm0,imm3)) /* last segment?  */
 dnl  __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
 dnl  __(mov imm2,imm1) /* last segment <- current segment  */
 dnl  __(mov imm1,imm3) /* current segment <- next segment  */
-dnl  __(bne cr0,local_label(walkloop))
+dnl  __(bne local_label(walkloop))
 dnl 
 dnl         /* the final segment ptr is now in imm2  */
@@ -2267,5 +2101,5 @@
 dnl local_label(pushloop):
 dnl  __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment  */
-dnl  __(cmpri(cr0,imm0,0))
+dnl  __(cmpri(imm0,0))
 dnl  __(cmpr(cr1,imm2,tsp))
 dnl  __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
@@ -2275,9 +2109,9 @@
 dnl 1:
 dnl  __(ldru(arg_z,-node_size(imm3)))
-dnl  __(cmpri(cr0,imm0,fixnum_one))
+dnl  __(cmpri(imm0,fixnum_one))
 dnl  __(subi imm0,imm0,fixnum_one)
 dnl  __(vpush1(arg_z))
 dnl 2:
-dnl  __(bne cr0,1b)
+dnl  __(bne 1b)
 dnl  __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment  */
 dnl  __(bne cr1,local_label(pushloop))
@@ -2343,5 +2177,5 @@
 dnl  __(cmpri(cr4,imm0,2<<fixnumshift))
 dnl  __(add imm1,arg_z,imm0)
-dnl  __(cmpri(cr0,imm0,0))
+dnl  __(cmpri(imm0,0))
 dnl  __(add nargs,nargs,imm0)
 dnl  __(cmpri(cr1,nargs,0))
@@ -2350,5 +2184,5 @@
 dnl  __(bge cr3,9f)
 dnl  __(beq cr4,2f)
-dnl  __(bne cr0,1f)
+dnl  __(bne 1f)
 dnl  /* lexpr count was 0; vpop the arg regs that  */
 dnl  /* were vpushed by the caller  */
@@ -2410,5 +2244,5 @@
 dnl /* the difference between the current VSP and the target.  */
 dnl _spentry(mvslide)
-dnl  __(cmpri(cr0,nargs,0))
+dnl  __(cmpri(nargs,0))
 dnl  __(mov imm3,nargs)
 dnl  __(add imm2,vsp,nargs)
@@ -2417,9 +2251,9 @@
 dnl  __(beq 2f)
 dnl 1:
-dnl  __(cmpri(cr0,imm3,1<<fixnumshift))
+dnl  __(cmpri(imm3,1<<fixnumshift))
 dnl  __(subi imm3,imm3,1<<fixnumshift)
 dnl  __(ldru(temp0,-node_size(imm0)))
 dnl  __(stru(temp0,-node_size(imm2)))
-dnl  __(bne cr0,1b)
+dnl  __(bne 1b)
 dnl 2:
 dnl  __(mov vsp,imm2)
@@ -2457,12 +2291,12 @@
 dnl  __(add imm3,imm3,nargs)
 dnl  __(add imm0,vsp,nargs)
-dnl  __(cmpr(cr0,imm0,vsp))
+dnl  __(cmpr(imm0,vsp))
 dnl  __(b 2f)
 dnl 1:
 dnl  __(ldru(arg_z,-node_size(imm0)))
-dnl  __(cmpr(cr0,imm0,vsp))
+dnl  __(cmpr(imm0,vsp))
 dnl  __(stru(arg_z,-node_size(imm3)))
 dnl 2:
-dnl  __(bne cr0,1b)
+dnl  __(bne 1b)
 dnl  __(add vsp,vsp,nargs) /*  discard values  */
 dnl  __(bx lr)
@@ -2478,7 +2312,7 @@
 dnl 
 dnl _spentry(add_values)
-dnl  __(cmpri(cr0,nargs,0))
+dnl  __(cmpri(nargs,0))
 dnl  __(ldr imm1,[tsp,#0])
-dnl  __(bne cr0,local_label(save_values_to_tsp))
+dnl  __(bne local_label(save_values_to_tsp))
 dnl  __(bx lr)
 dnl         
@@ -2547,29 +2381,6 @@
 dnl  __(discard_lisp_frame())
 dnl  __(bctr)
-dnl 
-dnl _spentry(savecontextvsp)
-dnl  __(ldr imm0,[rcontext,#tcr.cs_limit])
-dnl  __(build_lisp_frame(fn,loc_pc,vsp))
-dnl  __(mov fn,nfn)
-dnl  __(trllt(sp,imm0))
-dnl  __(bx lr)
-dnl 
-dnl _spentry(savecontext0)
-dnl  __(add imm0,vsp,imm0)
-dnl  __(build_lisp_frame(fn,loc_pc,imm0))
-dnl  __(ldr imm0,[rcontext,#tcr.cs_limit])
-dnl  __(mov fn,nfn)
-dnl  __(trllt(sp,imm0))
-dnl  __(bx lr)
-dnl 
-dnl 
-dnl /* Like .SPrestorefullcontext, only the saved return address  */
-dnl /* winds up in loc-pc instead of getting thrashed around ...  */
-dnl _spentry(restorecontext)
-dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
-dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
-dnl  __(ldr fn,[sp,#lisp_frame.savefn])
-dnl  __(discard_lisp_frame())
-dnl  __(bx lr)
+dnl
+
 dnl 
 dnl         
@@ -2582,7 +2393,7 @@
 dnl _spentry(lexpr_entry)
 dnl  __(ref_global(imm1,ret1val_addr))
-dnl  __(cmpr(cr0,imm1,loc_pc))
+dnl  __(cmpr(imm1,loc_pc))
 dnl  __(build_lisp_frame(fn,loc_pc,imm0))
-dnl  __(bne cr0,1f)
+dnl  __(bne 1f)
 dnl  __(ref_global(imm0,lexpr_return))
 dnl  __(build_lisp_frame(rzero,imm0,vsp))
@@ -2605,314 +2416,16 @@
 
 
-_spentry(builtin_div)
-        __(jump_builtin(_builtin_div,2))
-
-_spentry(builtin_eql)
-        __(cmp arg_y,arg_z)
-        __(beq 1f)
-        __(extract_fulltag(imm0,arg_y))
-        __(extract_fulltag(imm1,arg_z))
-        __(cmp imm0,imm1)
-        __(bne 2f)
-        __(cmp imm0,#fulltag_misc)
-        __(bne 2f)
-        __(jump_builtin(_builtin_eql,2))
-1:      __(mov arg_z,#nil_value)
-        __(add arg_z,arg_z,#t_offset)
-        __(bx lr)
-2:      __(mov arg_z,#nil_value)
-        __(bx lr)
-dnl         
-dnl _spentry(builtin_length)
-dnl         __(cmpri(cr1,arg_z,nil_value))
-dnl  __(extract_typecode(imm0,arg_z))
-dnl  __(cmpri(cr0,imm0,min_vector_subtag))
-dnl         __(beq cr1,1f)
-dnl   __(cmpwi cr2,imm0,tag_list)
-dnl  __(beq- cr0,2f)
-dnl  __(blt- cr0,3f)
-dnl  /* (simple-array * (*))  */
-dnl  __(vector_length(arg_z,arg_z,imm0))
-dnl  __(bx lr)
-dnl 1:      __(mov arg_z,#0)
-dnl         __(bx lr)
-dnl 2:
-dnl  __(ldr arg_z,[arg_z,#vectorH.logsize])
-dnl  __(bx lr)        
-dnl 3: __(bne cr2,8f)
-dnl  __(mov temp2,#-1<<fixnum_shift)
-dnl  __(mov temp0,arg_z) /* fast pointer  */
-dnl  __(mov temp1,arg_z) /* slow pointer  */
-dnl 4:  __(extract_lisptag(imm0,temp0))
-dnl   __(cmpri(cr7,temp0,nil_value))
-dnl   __(cmpri(cr1,imm0,tag_list))
-dnl   __(addi temp2,temp2,fixnum_one)
-dnl   __(beq cr7,9f)
-dnl   __(andi. imm0,temp2,1<<fixnum_shift)
-dnl   __(bne cr1,8f)
-dnl   __(extract_lisptag(imm1,temp1)) 
-dnl   __(_cdr(temp0,temp0))
-dnl   __(cmpri(cr1,imm1,tag_list))
-dnl   __(beq cr0,4b)
-dnl   __(bne cr1,8f)
-dnl   __(_cdr(temp1,temp1))
-dnl   __(cmpr(cr0,temp0,temp1))
-dnl   __(bne cr0,4b)
-
-dnl 8: 
-dnl  __(jump_builtin(_builtin_length,1))
-dnl 9: 
-dnl  __(mov arg_z,temp2)
-dnl  __(bx lr)
-dnl         
-dnl _spentry(builtin_seqtype)
-dnl   __(extract_typecode(imm0,arg_z))
-dnl    __(cmpri(cr0,imm0,tag_list))
-dnl  __(cmpri(cr1,imm0,min_vector_subtag))
-dnl  __(beq cr0,1f)
-dnl  __(blt- cr1,2f)
-dnl  __(mov arg_z,#nil_value)
-dnl  __(bx lr)
-dnl 1: __(mov arg_z,#t_value)
-dnl  __(bx lr)
-dnl 2:
-dnl  __(jump_builtin(_builtin_seqtype,1))
-
-/* This is                  
-_spentry(builtin_assq)
-        __(b 2f)
-1:      __(trap_unless_list(arg_z,imm0))
-        __(_car(arg_x,arg_z))
-        __(_cdr(arg_z,arg_z))
-        __(cmp arg_x,#nil_value)
-        __(beq 2f)
-        __(trap_unless_list(arg_x,imm0))
-        __(_car(temp0,arg_x))
-        __(cmp temp0,arg_y)
-        __(bne 2f)
-        __(mov arg_z,arg_x)
-        __(bx lr)
-2:      __(cmp arg_z,#nil_value)
-        __(bne 1b)
-        __(bx lr)
- 
-_spentry(builtin_memq)
-        __(cmp arg_z,nil_value)
-        __(b 2f)
-1:      __(trap_unless_list(arg_z,imm0))
-        __(_car(arg_x,arg_z))
-        __(_cdr(temp0,arg_z))
-        __(cmp arg_x,arg_y)
-        __(bxeq lr)
-        __(cmp temp0,nil_value)
-        __(mov arg_z,temp0)
-2:      __(bne 1b)
-        __(bx lr)
+
+
  
                  
-_spentry(builtin_logbitp)
-/* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
-        __(test_two_fixnums(arg_y,arg_z,imm0))
-        __(bne 1f)
-        __(uuo_suspend_now(al))
-        __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
-        __(bhs 1f)
-        __(unbox_fixnum(imm0,arg_y))
-        __(mov imm1,#fixnum1)
-        __(tst arg_z,imm1,lsl imm0)
-        __(mov arg_z,#nil_value)
-        __(addne arg_z,arg_z,#t_offset)
-        __(bx lr)
-1:
-        __(jump_builtin(_builtin_logbitp,2))
-
-_spentry(builtin_logior)
-        __(orr imm0,arg_y,arg_z)
-        __(test_fixnum(imm0))
-        __(moveq arg_z,imm0)
-        __(bxeq lr)
-        __(jump_builtin(_builtin_logior,2))
-
-_spentry(builtin_logand)
-        __(test_two_fixnums(arg_y,arg_z,imm0))
-        __(andeq arg_z,arg_y,arg_z)
-        __(bxeq lr)
-        __(jump_builtin(_builtin_logand,2))
-          
-_spentry(builtin_ash)
-        __(test_two_fixnums(arg_y,arg_z,imm0))
-        __(bne 9f)
-        __(cmp arg_z,#0)
-        __(bgt 1f)
-        __(moveq arg_z,arg_y)
-        __(bxeq lr)
-        /* Shift right */
-        __(unbox_fixnum(imm2,arg_z))
-        __(rsb imm2,imm2,#0)
-        __(cmp imm2,#32)
-        __(movge imm2,#31)
-        __(mov arg_z,#-fixnumone)
-        __(and arg_z,arg_z,arg_y,lsr imm2)
-        __(bx lr)
-        /* shift left */
-1:      __(unbox_fixnum(imm0,arg_y))
-        __(mov imm1,imm0,asr #31)
-        __(unbox_fixnum(imm2,arg_z))
-        __(cmp imm2,#32)
-        __(moveq imm1,imm0)
-        __(moveq imm0,#0)
-        __(beq _SPmakes64)
-        __(bgt 9f)
-        __(mov imm1,imm1,asl imm2)
-        __(rsb imm2,imm2,#32)
-        __(orr imm1,imm1,imm0,lsr imm2)
-        __(unbox_fixnum(imm2,arg_z))
-        __(mov imm0,imm0,asl imm2)
-        __(b _SPmake64)
-9:  
-        __(jump_builtin(_builtin_ash,2))
-
-_spentry(builtin_negate)
-        __(test_fixnum(arg_z))
-        __(bne 1f)
-        __(rsbs arg_z,arg_z,#0)
-        __(bxvc lr)
-        __(b _SPfix_overflow)
-1:
-        __(jump_builtin(_builtin_negate,1))
-dnl 
-dnl _spentry(builtin_logxor)
-dnl         __(extract_lisptag(imm0,arg_y))
-dnl         __(extract_lisptag(imm1,arg_z))
-dnl         __(ands imm0,imm0,imm1)
-dnl  __(eoreq arg_z,arg_y,arg_z)
-dnl  __(bxeq lr)
-dnl  __(jump_builtin(_builtin_logxor,2))
-dnl 
-dnl 
-dnl 
-dnl         
-dnl _spentry(builtin_aset1)
-dnl  __(extract_typecode(imm0,arg_x))
-dnl  __(cmpri(cr0,imm0,min_vector_subtag))
-dnl  __(box_fixnum(temp0,imm0))
-dnl  __(bgt cr0,1f)
-dnl  __(jump_builtin(_builtin_aset1,3))
-dnl 1:
-dnl  __(b _SPsubtag_misc_set)
-dnl 
-dnl /* Enter the debugger  */
-dnl _spentry(breakpoint)
-dnl  __(mov r3,#0)
-dnl  __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter)  */
-dnl  __(bx lr)  /* if handler didn't  */
-dnl 
-dnl /* */
-dnl /* We're entered with an eabi_c_frame on the C stack.  There's a */
-dnl /* lisp_frame reserved underneath it; we'll link it in in a minute. */
-dnl /* Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
-dnl /* then shrink the eabi_c_frame. */
-dnl /*  */
-dnl  
-dnl _spentry(eabi_ff_call)
-dnl  __(mflr loc_pc)
-dnl  __(str(sp,eabi_c_frame.savelr(sp)))
-dnl  __(vpush_saveregs())  /* Now we can use save0-save7 to point to stacks  */
-dnl  __(mov save0,rcontext) /* or address globals.  */
-dnl  __(extract_typecode(imm0,arg_z))
-dnl  __(cmpri(imm0,subtag_macptr))
-dnl  __(ldr save1,[sp,#0]) /* bottom of reserved lisp frame  */
-dnl  __(la save2,-lisp_frame.size(save1)) /* top of lisp frame */
-dnl         __(zero_doublewords save2,0,lisp_frame.size)
-dnl  __(str(save1,lisp_frame.backlink(save2)))
-dnl  __(str(save2,c_frame.backlink(sp)))
-dnl  __(str(fn,lisp_frame.savefn(save2)))
-dnl  __(str(loc_pc,lisp_frame.savelr(save2)))
-dnl  __(str(vsp,lisp_frame.savevsp(save2)))
-dnl  __(bne 1f)
-dnl  __(ldr arg_z,[arg_z,#macptr.address])
-dnl 1:
-dnl  __(ldr save3,[rcontext,#tcr.cs_area])
-dnl  __(str(save2,area.active(save3)))
-dnl  __(str(allocptr,tcr.save_allocptr(rcontext)))
-dnl  __(str(allocbase,tcr.save_allocbase(rcontext)))
-dnl  __(str(tsp,tcr.save_tsp(rcontext)))
-dnl  __(str(vsp,tcr.save_vsp(rcontext)))
-dnl  __(mtctr arg_z)
-dnl  __(str(rzero,tcr.ffi_exception(rcontext)))
-dnl  __(mffs f0)
-dnl  __(stfd f0,tcr.lisp_fpscr(rcontext)) /* remember lisp's fpscr  */
-dnl  __(mtfsf 0xff,fp_zero) /* zero foreign fpscr  */
-dnl  __(mov imm1,#TCR_STATE_FOREIGN)
-dnl  __(str(imm1,tcr.valence(rcontext)))
-dnl  __(ldr r2,[rcontext,#tcr.native_thread_info])
-dnl  __(ldr r13,[0,#lisp_globals.saveR13])
-dnl  __(ldr r3,[sp,#eabi_c_frame.param0])
-dnl  __(ldr r4,[sp,#eabi_c_frame.param1])
-dnl  __(ldr r5,[sp,#eabi_c_frame.param2])
-dnl  __(ldr r6,[sp,#eabi_c_frame.param3])
-dnl  __(ldr r7,[sp,#eabi_c_frame.param4])
-dnl  __(ldr r8,[sp,#eabi_c_frame.param5])
-dnl  __(ldr r9,[sp,#eabi_c_frame.param6])
-dnl  __(ldr r10,[sp,#eabi_c_frame.param7])
-dnl  __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
-dnl  __(str(rzero,eabi_c_frame.savelr(save1)))
-dnl  __(str(save2,eabi_c_frame.backlink(save1)))
-dnl  __(mov sp,save1)
-dnl  /* If we're calling a varargs C function, it'll want to */
-dnl  /* know whether or not we've passed any args in FP regs. */
-dnl  /* Better to say that we did (and force callee to save FP */
-dnl  /* arg regs on entry) than to say that we didn't and get */
-dnl  /* garbage results  */
-dnl  __(crset 6)
-dnl  __(bctrl)
-dnl  /* C should have preserved save0 (= rcontext) for us.  */
-dnl  __(ldr sp,[sp,#0])
-dnl  __(mov imm2,save0)
-dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
-dnl  __(mov rzero,#0)
-dnl  __(mov loc_pc,rzero)
-dnl  __(mov arg_x,#nil_value)
-dnl  __(mov arg_y,#nil_value)
-dnl  __(mov arg_z,#nil_value)
-dnl  __(mov temp0,#nil_value)
-dnl  __(mov temp1,#nil_value)
-dnl  __(mov temp2,#nil_value)
-dnl  __(mov temp3,#nil_value)
-dnl  __(mov fn,#nil_value)
-dnl  __(mov rcontext,imm2)
-dnl  __(mov imm2,#TCR_STATE_LISP)
-dnl  __(ldr tsp,[rcontext,#tcr.save_tsp])
-dnl         __(mov save0,#0)
-dnl         __(mov save1,#0)
-dnl         __(mov save2,#0)
-dnl         __(mov save3,#0)
-dnl         __(mov save4,#0)
-dnl         __(mov save5,#0)
-dnl         __(mov save6,#0)
-dnl         __(mov save7,#0)
-dnl         __(mov allocptr,#-dnode_size)
-dnl         __(mov allocbase,#-dnode_size)
-dnl  __(str(imm2,tcr.valence(rcontext))) 
-dnl  __(vpop_saveregs())
-dnl  __(ldr allocptr,[rcontext,#tcr.save_allocptr])
-dnl  __(ldr allocbase,[rcontext,#tcr.save_allocbase])
-dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
-dnl  __(mtlr loc_pc)
-dnl  __(ldr fn,[sp,#lisp_frame.savefn])
-dnl  __(mffs f0)
-dnl  __(stfd f0,8(sp))
-dnl  __(lwz imm3,12(sp)) /* imm3 = FPSCR after call  */
-dnl         __(clrrwi imm2,imm3,8)
-dnl  __(discard_lisp_frame())
-dnl  __(str(imm2,tcr.ffi_exception(rcontext)))
-dnl  __(lfd f0,tcr.lisp_fpscr(rcontext))
-dnl  __(mtfsf 0xff,f0)
-dnl  __(check_pending_interrupt(`cr1'))
-dnl         __(mtxer rzero)
-dnl         __(mtctr rzero)
-dnl  __(bx lr)
-
-
+
+
+
+/* Enter the debugger  */
+_spentry(breakpoint)
+        __(mov r3,#0)
+        __(uuo_debug_trap(al))
+        __(bx lr)  /* if handler didn't  */
 
 
@@ -3021,7 +2534,7 @@
 dnl  __(cmpri(cr1,arg_z,0))
 dnl  __(ldr imm0,[rcontext,#tcr.interrupt_pending])
-dnl  __(cmpri(cr0,imm0,0))
+dnl  __(cmpri(imm0,0))
 dnl  __(bne cr1,1f)
-dnl  __(beq cr0,1f)
+dnl  __(beq 1f)
 dnl  __(str(rzero,tcr.interrupt_pending(rcontext)))
 dnl  __(mov nargs,#fixnum_one)
@@ -3034,6 +2547,6 @@
 
 	
-dnl /* Construct a lisp integer out of the 32-bit signed value in imm0 */
-dnl /* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
+/* Construct a lisp integer out of the 32-bit signed value in imm0 */
+/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
 
 _spentry(gets32)
@@ -3096,63 +2609,56 @@
         __(jump_fname())
 
-dnl _spentry(unbind)
-dnl         __(ldr imm1,[rcontext,#tcr.db_link])
-dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])   
-dnl         __(ldr imm3,[imm1,#binding.sym])
-dnl         __(ldr temp1,[imm1,#binding.val])
-dnl         __(ldr imm1,[imm1,#binding.link])
-dnl         __(str temp1,imm2,imm3)
-dnl         __(str(imm1,tcr.db_link(rcontext)))
-dnl         __(bx lr)
-dnl 
-dnl _spentry(unbind_n)
-dnl         __(ldr imm1,[rcontext,#tcr.db_link])
-dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])   
-dnl 1:      __(subi imm0,imm0,1)
-dnl         __(ldr imm3,[imm1,#binding.sym])
-dnl         __(ldr temp1,[imm1,#binding.val])
-dnl         __(cmpri(imm0,0))
-dnl         __(ldr imm1,[imm1,#binding.link])
-dnl         __(str temp1,imm2,imm3)
-dnl         __(bne 1b)
-dnl         __(str(imm1,tcr.db_link(rcontext)))
-dnl         __(bx lr)
-dnl 
-dnl /* */
-dnl /* Clobbers imm1,imm2,imm5,arg_x, arg_y */
-dnl 
-dnl _spentry(unbind_to)
-dnl         __(ldr imm1,[rcontext,#tcr.db_link])
-dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
-dnl 1:      __(ldr imm5,[imm1,#binding.sym])
-dnl         __(ldr arg_y,[imm1,#binding.val])
-dnl         __(ldr imm1,[imm1,#binding.link])
-dnl         __(cmpr(imm0,imm1))
-dnl         __(str arg_y,imm2,imm5)
-dnl         __(bne 1b)
-dnl         __(str(imm1,tcr.db_link(rcontext)))
-dnl         __(bx lr)
-dnl  
-dnl 
-dnl 
-dnl /* */
-dnl /* Restore the special bindings from the top of the tstack,  */
-dnl /* leaving the tstack frame allocated.  */
-dnl /* Note that there might be 0 saved bindings, in which case  */
-dnl /* do nothing.  */
-dnl /* Note also that this is -only- called from an unwind-protect  */
-dnl /* cleanup form, and that .SPnthrowXXX is keeping one or more  */
-dnl /* values in a frame on top of the tstack.  */
-dnl /*  */
-dnl                         
-dnl _spentry(progvrestore)
-dnl  __(ldr imm0,[tsp,#tsp_frame.backlink]) /* ignore .SPnthrowXXX values frame  */
-dnl  __(ldr imm0,[imm0,#tsp_frame.data_offset])
-dnl  __(cmpri(cr0,imm0,0))
-dnl  __(unbox_fixnum(imm0,imm0))
-dnl  __(bne+ cr0,_SPunbind_n)
-dnl  __(bx lr)
-dnl 
- /* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
+_spentry(unbind)
+        __(ldr imm1,[rcontext,#tcr.db_link])
+        __(ldr temp0,[rcontext,#tcr.tlb_pointer])   
+        __(ldr imm0,[imm1,#binding.sym])
+        __(ldr temp1,[imm1,#binding.val])
+        __(ldr imm1,[imm1,#binding.link])
+        __(str temp1,[temp0,imm0])
+        __(str imm1,[rcontext,#tcr.db_link])
+        __(bx lr)
+
+/* Clobbers imm1,temp0,arg_x, arg_y */        
+_spentry(unbind_n)
+        __(ldr imm1,[rcontext,#tcr.db_link])
+        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
+1:      __(ldr temp0,[imm1,#binding.sym])
+        __(ldr arg_y,[imm1,#binding.val])
+        __(ldr imm1,[imm1,#binding.link])
+        __(subs imm0,imm0,#1)
+        __(str arg_y,[arg_x,temp0])
+        __(bne 1b)
+        __(str imm1,[rcontext,#tcr.db_link])
+        __(bx lr)
+
+/* */
+/* Clobbers imm1,temp0,arg_x, arg_y */
+
+_spentry(unbind_to)
+        do_unbind_to(imm1,temp1,arg_x,arg_y)
+        __(bx lr)
+ 
+
+ 
+/* */
+/* Restore the special bindings from the top of the tstack,  */
+/* leaving the tstack frame allocated.  */
+/* Note that there might be 0 saved bindings, in which case  */
+/* do nothing.  */
+/* Note also that this is -only- called from an unwind-protect  */
+/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
+/* values in a frame on top of the tstack.  */
+/*  */
+                         
+_spentry(progvrestore)
+        __(skip_stack_vector(imm0,imm1,sp))
+        /* There might be a lisp_frame at imm0.  Not sure */
+        __(ldr imm0,[imm0,#node_size]) /* or maybe node_size+lisp_frame.size */
+        __(cmp imm0,#0)
+        __(unbox_fixnum(imm0,imm0))
+        __(bne _SPunbind_n)
+        __(bx lr)
+
+/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
 /* for pending interrupts after doing so.  */
 _spentry(bind_interrupt_level_0)
@@ -3314,74 +2820,71 @@
 
 
-dnl /* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
-dnl _spentry(aset2)
-dnl         __(extract_typecode(imm2,temp0))
-dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
-dnl         __(cmpri(cr2,imm2,subtag_arrayH))
-dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
-dnl         __(bne cr2,1f)
-dnl         __(ldr imm1,[temp0,#arrayH.rank])
-dnl         __(cmpri(imm1,2<<fixnumshift))
-dnl         __(bne 1f)
-dnl         /* It's a 2-dimensional array.  Check bounds */
-dnl         __(ldr imm0,[temp0,#arrayH.dim0])
-dnl         __(trlge(arg_x,imm0))
-dnl         __(ldr imm0,[temp0,#arrayH.dim0+node_size])
-dnl         __(trlge(arg_y,imm0))
-dnl         __(unbox_fixnum(imm0,imm0))
-dnl         __(mullr(arg_x,arg_x,imm0))
-dnl         __(add arg_y,arg_y,arg_x)
-dnl         /* arg_y is now row-major-index; get data vector and
-dnl            add in possible offset */
-dnl         __(mov arg_x,temp0)
-dnl 0:      __(ldr imm0,[arg_x,#arrayH.displacement])
-dnl         __(ldr arg_x,[arg_x,#arrayH.data_vector])
-dnl         __(extract_subtag(imm1,arg_x))
-dnl         __(cmpri(imm1,subtag_vectorH))
-dnl         __(add arg_y,arg_y,imm0)
-dnl         __(bgt C(misc_set_common))
-dnl         __(b 0b)
-dnl 1:              
-dnl         __(uuo_interr(error_object_not_array_2d,temp0))        
-dnl                 
-dnl /* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */        
-dnl _spentry(aset3)
-dnl         __(extract_typecode(imm2,temp1))
-dnl         __(trap_unless_lisptag_equal(temp0,tag_fixnum,imm0))
-dnl         __(cmpri(cr2,imm2,subtag_arrayH))
-dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
-dnl         __(bne cr2,1f)
-dnl         __(ldr imm1,[temp1,#arrayH.rank])
-dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
-dnl         __(cmpri(imm1,3<<fixnumshift))
-dnl         __(bne 1f)
-dnl         /* It's a 3-dimensional array.  Check bounds */
-dnl         __(ldr imm2,arrayH.dim0+(node_size*2)(temp1)))
-dnl         __(ldr imm1,[temp1,#arrayH.dim0+node_size])
-dnl         __(ldr imm0,[temp1,#arrayH.dim0])
-dnl         __(trlge(arg_y,imm2))
-dnl         __(unbox_fixnum(imm2,imm2))
-dnl         __(trlge(arg_x,imm1))
-dnl         __(unbox_fixnum(imm1,imm1))
-dnl         __(trlge(temp0,imm0))
-dnl         __(mullr(arg_x,arg_x,imm2))
-dnl         __(mullr(imm1,imm2,imm1))
-dnl         __(mullr(temp0,imm1,temp0))
-dnl         __(add arg_y,arg_y,arg_x)
-dnl         __(add arg_y,arg_y,temp0)
-dnl         __(mov arg_x,temp1)
-dnl 0:      __(ldr temp0,[arg_x,#arrayH.displacement])
-dnl         __(ldr arg_x,[arg_x,#arrayH.data_vector])
-dnl         __(extract_subtag(imm1,arg_x))
-dnl         __(cmpri(imm1,subtag_vectorH))
-dnl         __(add arg_y,arg_y,temp0)
-dnl         __(bgt C(misc_set_common))
-dnl         __(b 0b)
-dnl 1:              
-dnl         __(uuo_interr(error_object_not_array_3d,temp1))
-dnl 
-dnl 
-dnl         
-dnl 
+/* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
+_spentry(aset2)
+        __(extract_typecode(imm0,temp0))
+        __(cmp imm0,#subtag_arrayH)
+        __(ldreq imm0,[temp0,#arrayH.rank])
+        __(cmpeq imm0,#2<<fixnumshift)
+        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array2d))
+        __(trap_unless_fixnum(arg_x))
+        __(trap_unless_fixnum(arg_y))
+        /* It's a 2-dimensional array.  Check bounds */
+        __(ldr imm0,[temp0,#arrayH.dim0])
+        __(cmp arg_x,imm0)
+        __(uuo_error_array_bounds(hs,arg_x,temp0))
+        __(ldr imm0,[temp0,#arrayH.dim0+node_size])
+        __(cmp arg_y,imm0)
+        __(uuo_error_array_bounds(hs,arg_y,temp0))
+        __(unbox_fixnum(imm0,imm0))
+        __(mul temp1,arg_x,imm0)
+        __(add arg_y,arg_y,temp1)
+        /* arg_y is now row-major-index; get data vector and
+           add in possible offset */
+        __(mov arg_x,temp0)
+0:      __(ldr imm0,[arg_x,#arrayH.displacement])
+        __(ldr arg_x,[arg_x,#arrayH.data_vector])
+        __(extract_subtag(imm1,arg_x))
+        __(cmp imm1,#subtag_vectorH)
+        __(add arg_y,arg_y,imm0)
+        __(bgt C(misc_set_common))
+        __(b 0b)
+
+                 
+/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */        
+_spentry(aset3)
+        __(extract_typecode(imm0,temp1))
+        __(cmp imm0,#subtag_arrayH)
+        __(ldreq imm0,[temp1,#arrayH.rank])
+        __(cmpeq imm0,#3<<fixnumshift)
+        __(uuo_error_reg_not_xtype(ne,temp1,xtype_array3d))
+        __(trap_unless_fixnum(temp0))
+        __(trap_unless_fixnum(arg_x))
+        __(trap_unless_fixnum(arg_y))
+        /* It's a 3-dimensional array.  Check bounds */
+        __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)])
+        __(ldr imm1,[temp1,#arrayH.dim0+node_size])
+        __(ldr imm0,[temp1,#arrayH.dim0])
+        __(cmp arg_y,imm2)
+        __(uuo_error_array_bounds(hs,arg_y,temp1))
+        __(cmp arg_x,imm1)
+        __(uuo_error_array_bounds(hs,arg_x,temp1))
+        __(unbox_fixnum(imm1,imm1))
+        __(cmp temp0,imm0)
+        __(uuo_error_array_bounds(hs,temp0,temp1))
+        __(mul arg_x,imm2,arg_x)
+        __(mul imm1,imm2,imm1)
+        __(mul temp0,imm1,temp0)
+        __(add arg_y,arg_y,arg_x)
+        __(add arg_y,arg_y,temp0)
+        __(mov arg_x,temp1)
+0:      __(ldr temp0,[arg_x,#arrayH.displacement])
+        __(ldr arg_x,[arg_x,#arrayH.data_vector])
+        __(extract_subtag(imm1,arg_x))
+        __(cmp imm1,#subtag_vectorH)
+        __(add arg_y,arg_y,temp0)
+        __(bgt C(misc_set_common))
+        __(b 0b)
+
+
 _spentry(nmkunwind)
         __(mov imm2,#-fixnumone)
@@ -4199,5 +3702,5 @@
 	__(mov imm2,arg_y,lsl #1)
 	__(add imm2,imm2,#misc_dfloat_offset)
-	__(strd imm0,imm1,[arg_z,imm2])
+	__(strd imm0,imm1,[arg_x,imm2])
 	__(bx lr)
 local_label(misc_set_invalid):  
@@ -4207,3 +3710,351 @@
 	__(b _SPksignalerr)                
 
+C(destbind1): 
+dnl  /* Extract required arg count.  */
+dnl  /* A bug in gas: can't handle shift count of "32" (= 0  */
+dnl  ifelse(eval(mask_req_width+mask_req_start),eval(32),`
+dnl  __(clrlwi. imm0,nargs,mask_req_start)
+dnl  ',`
+dnl  __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
+dnl  ')
+dnl  __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
+dnl  __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
+dnl  __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
+dnl  __(cmpri(cr4,imm4,0))
+dnl  __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
+dnl  __(cmpri(cr5,imm4,0))
+dnl  __(cmpri(cr1,imm1,0))
+dnl  __(cmpri(cr2,imm2,0))
+dnl  /* Save entry vsp in case of error.  */
+dnl  __(mov imm4,vsp)
+dnl  __(beq 2f)
+dnl 1:
+dnl  __(cmpri(cr7,arg_reg,nil_value))
+dnl   __(extract_lisptag(imm3,arg_reg))
+dnl   __(cmpri(cr3,imm3,tag_list))
+dnl  __(subi imm0,imm0,1)
+dnl  __(cmpri(imm0,0))
+dnl  __(beq cr7,toofew)
+dnl  __(bne cr3,badlist)
+dnl  __(ldr arg_x,[arg_reg,#cons.car])
+dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
+dnl  __(vpush1(arg_x))
+dnl  __(bne 1b)
+dnl 2:
+dnl  __(beq cr1,rest_keys)
+dnl  __(bne cr2,opt_supp)
+dnl  /* 'simple' &optionals:  no supplied-p, default to nil.  */
+dnl simple_opt_loop:
+dnl  __(cmpri(arg_reg,nil_value))
+dnl   __(extract_lisptag(imm3,arg_reg))
+dnl   __(cmpri(cr3,imm3,tag_list))
+dnl  __(subi imm1,imm1,1)
+dnl  __(cmpri(cr1,imm1,0))
+dnl  __(mov imm5,#nil_value)
+dnl  __(beq default_simple_opt)
+dnl  __(bne cr3,badlist)
+dnl  __(ldr arg_x,[arg_reg,#cons.car])
+dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
+dnl  __(vpush1(arg_x))
+dnl  __(bne cr1,simple_opt_loop)
+dnl  __(b rest_keys)
+dnl default_simple_opt_loop:
+dnl  __(subi imm1,imm1,1)
+dnl  __(cmpri(cr1,imm1,0))
+dnl default_simple_opt:
+dnl  __(vpush1(imm5))
+dnl  __(bne cr1,default_simple_opt_loop)
+dnl  __(b rest_keys)
+dnl  /* Provide supplied-p vars for the &optionals.  */
+dnl opt_supp:
+dnl  __(mov arg_y,#t_value)
+dnl opt_supp_loop:
+dnl  __(cmpri(arg_reg,nil_value))
+dnl   __(extract_lisptag(imm3,arg_reg))
+dnl   __(cmpri(cr3,imm3,tag_list))
+dnl  __(subi imm1,imm1,1)
+dnl  __(cmpri(cr1,imm1,0))
+dnl  __(beq default_hard_opt)
+dnl  __(bne cr3,badlist)
+dnl  __(ldr arg_x,[arg_reg,#cons.car])
+dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
+dnl  __(vpush1(arg_x))
+dnl  __(vpush1(arg_y))
+dnl  __(bne cr1,opt_supp_loop)
+dnl  __(b rest_keys)
+dnl default_hard_opt_loop:
+dnl  __(subi imm1,imm1,1)
+dnl  __(cmpri(cr1,imm1,0))
+dnl default_hard_opt:
+dnl  __(vpush1(imm5))
+dnl  __(vpush1(imm5))
+dnl  __(bne cr1,default_hard_opt_loop)
+dnl rest_keys:
+dnl  __(cmpri(arg_reg,nil_value))
+dnl  __(bne cr5,have_rest)
+dnl  __(bne cr4,have_keys)
+dnl  __(bne toomany)
+dnl  __(bx lr)
+dnl have_rest:
+dnl  __(vpush1(arg_reg))
+dnl  __(beqlr cr4)
+dnl have_keys:
+dnl  /* Ensure that arg_reg contains a proper,even-length list.  */
+dnl  /* Insist that its length is <= 512 (as a cheap circularity check.)  */
+dnl  __(mov imm0,#256)
+dnl  __(mov arg_x,arg_reg)
+dnl count_keys_loop:
+dnl   __(extract_lisptag(imm3,arg_x))
+dnl   __(cmpri(cr3,imm3,tag_list))
+dnl  __(cmpri(arg_x,nil_value))
+dnl  __(subi imm0,imm0,1)
+dnl  __(cmpri(cr4,imm0,0))
+dnl  __(beq counted_keys)
+dnl  __(bne cr3,badlist)
+dnl  __(ldr arg_x,[arg_x,#cons.cdr])
+dnl   __(extract_lisptag(imm3,arg_x))
+dnl   __(cmpri(cr3,imm3,tag_list))
+dnl  __(blt cr4,toomany)
+dnl  __(cmpri(arg_x,nil_value))
+dnl  __(beq db_badkeys)
+dnl  __(bne cr3,badlist)
+dnl  __(ldr arg_x,[arg_x,#cons.cdr])
+dnl  __(b count_keys_loop)
+dnl counted_keys:
+dnl  /* We've got a proper, even-length list of key/value pairs in */
+dnl  /* arg_reg. For each keyword var in the lambda-list, push a pair */
+dnl  /* of NILs on the vstack.  */
+dnl  __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
+dnl  __(mov imm2,imm0)  /* save number of keys  */
+dnl  __(mov imm5,#nil_value)
+dnl  __(b push_pair_test)
+dnl push_pair_loop:
+dnl  __(cmpri(imm0,1))
+dnl  __(subi imm0,imm0,1)
+dnl  __(vpush1(imm5))
+dnl  __(vpush1(imm5))
+dnl push_pair_test:
+dnl  __(bne push_pair_loop)
+dnl  __(slwi imm2,imm2,dnode_shift)  /* pairs -> bytes  */
+dnl  __(add imm2,vsp,imm2)  /* imm2 points below pairs  */
+dnl  __(mov imm0,#0)   /* count unknown keywords so far  */
+dnl  __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
+dnl  __(extrwi nargs,nargs,mask_key_width,mask_key_start)
+dnl  /* Now, for each keyword/value pair in the list  */
+dnl  /*  a) if the keyword is found in the keyword vector, set the  */
+dnl  /*     corresponding entry on the vstack to the value and the  */
+dnl  /*     associated supplied-p var to T.  */
+dnl  /*  b) Regardless of whether or not the keyword is found,  */
+dnl         /*     if :ALLOW-OTHER-KEYS is provided with a non-nil value, */
+dnl  /*     set the low bit of imm1 to indicate that unknown keywords  */
+dnl  /*     are acceptable. (This bit is pre-set above to the value */
+dnl         /*     the encoded value of &allow_other_keys.) */
+dnl  /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
+dnl  /*     the count of unknown keywords in the high bits of imm1*/
+dnl  /* At the end of the list, signal an error if any unknown keywords were seen  */
+dnl  /* but not allowed.  Otherwise, return.  */
+dnl 
+dnl match_keys_loop:
+dnl  __(cmpri(arg_reg,nil_value))
+dnl  __(mov imm0,#0)
+dnl  __(mov imm3,#misc_data_offset)
+dnl  __(beq matched_keys)
+dnl  __(ldr arg_x,[arg_reg,#cons.car])
+dnl  __(mov arg_y,#nrs.kallowotherkeys)
+dnl  __(cmpr(cr3,arg_x,arg_y)) /* :ALLOW-OTHER-KEYS ?  */
+dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
+dnl  __(ldr arg_y,[arg_reg,#cons.car])
+dnl  __(cmpr(cr4,imm0,nargs))
+dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
+dnl  __(b match_test)
+dnl match_loop:
+dnl  __(ldrx(temp0,keyvect_reg,imm3))
+dnl  __(cmpr(arg_x,temp0))
+dnl  __(addi imm0,imm0,1)
+dnl  __(cmpr(cr4,imm0,nargs))
+dnl  __(addi imm3,imm3,node_size)
+dnl  __(bne match_test)
+dnl  /* Got a hit.  Unless this keyword's been seen already, set it.  */
+dnl  __(slwi imm0,imm0,dnode_shift)
+dnl  __(subf imm0,imm0,imm2)
+dnl  __(ldr temp0,[imm0,#0])
+dnl  __(cmpri(temp0,nil_value))
+dnl  __(mov temp0,#t_value)
+dnl  __(bne match_keys_loop) /* already saw this  */
+dnl  __(str(arg_y,node_size*1(imm0)))
+dnl  __(str(temp0,node_size*0(imm0)))
+dnl         __(bne cr3,match_keys_loop)
+dnl  __(b match_keys_check_aok)
+dnl match_test:
+dnl  __(bne cr4,match_loop)
+dnl         __(beq cr3,match_keys_check_aok)
+dnl         __(addi imm1,imm1,node_size)
+dnl         __(b match_keys_loop)
+dnl match_keys_check_aok:
+dnl         __(andi. imm0,imm1,2)  /* check "seen-aok" bit in imm1 */
+dnl         __(cmpri cr1,arg_y,nil_value) /* check value */
+dnl         __(ori imm1,imm1,2)
+dnl         __(bne match_keys_loop) /* duplicate aok */
+dnl         __(beq cr1,match_keys_loop)
+dnl         __(ori imm1,imm1,1)
+dnl  __(b match_keys_loop)
+dnl matched_keys:
+dnl         __(clrrwi. imm0,imm1,2)
+dnl         __(beqlr)
+dnl         __(andi. imm1,imm1,1)
+dnl         __(bnelr)
+dnl  /* Some unrecognized keywords.  Complain generically about  */
+dnl  /* invalid keywords.  */
+dnl db_badkeys:
+dnl  __(mov arg_y,#XBADKEYS)
+dnl  __(b destructure_error)
+dnl toomany:
+dnl  __(mov arg_y,#XCALLTOOMANY)
+dnl  __(b destructure_error)
+dnl toofew:
+dnl  __(mov arg_y,#XCALLTOOFEW)
+dnl  __(b destructure_error)
+dnl badlist:
+dnl  __(mov arg_y,#XCALLNOMATCH)
+dnl  /* b destructure_error  */
+dnl destructure_error:
+dnl  __(mov vsp,imm4)  /* undo everything done to the stack  */
+dnl  __(mov arg_z,whole_reg)
+dnl  __(set_nargs(2))
+dnl  __(b _SPksignalerr)
+
+/* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
+/* frames. If target isn't a multiple-value receiver, discard extra values */
+/* (less hair, maybe.)  */
+C(_throw_found):
+pushdef(`__',`
+        .word 0
+        ')        
+        __(ldr imm1,[imm2,#catch_frame.mvflag])
+        __(cmpri(imm1,0))
+        __(cmpri(cr1,nargs,0))
+        __(mov fn,#0)
+        __(add imm1,vsp,nargs)
+        __(add imm1,[imm1,#-node_size])
+        __(bne local_label(_throw_all_values))
+        __(set_nargs(1))
+        __(beq cr1,local_label(_throw_default_1_val))
+        __(mov vsp,imm1)
+        __(b local_label(_throw_all_values))
+local_label(_throw_default_1_val):
+        __(mov imm4,#nil_value)
+        __(vpush1(imm4))
+local_label(_throw_all_values):
+        __(bl _SPnthrowvalues)
+        __(ldr imm3,[rcontext,#tcr.catch_top])
+        __(ldr imm1,[rcontext,#tcr.db_link])
+        __(ldr imm0,[imm3,#catch_frame.db_link])
+        __(ldr imm4,[imm3,#catch_frame.mvflag])
+        __(cmpr(imm0,imm1))
+        __(cmpri(cr1,imm4,0))
+        __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
+        __(beq local_label(_throw_dont_unbind))
+        __(bl _SPunbind_to)
+local_label(_throw_dont_unbind):
+        __(add imm0,vsp,nargs)
+        __(cmpri(nargs,0))
+        __(ldr imm1,[imm3,#catch_frame.csp])
+        __(ldr imm1,[imm1,#lisp_frame.savevsp])
+        __(bne cr1,local_label(_throw_multiple))
+        /* Catcher expects single value in arg_z  */
+        __(ldr arg_z,[imm0,#-node_size])
+        __(b local_label(_throw_pushed_values))
+local_label(_throw_multiple):
+        __(beq local_label(_throw_pushed_values))
+        __(mov imm2,nargs)
+local_label(_throw_mvloop):
+        __(sub imm2,imm2,fixnum_one)
+        __(cmpri(imm2,0))
+        __(ldru(temp0,-node_size(imm0)))
+        __(push(temp0,imm1))
+        __(bgt local_label(_throw_mvloop))
+local_label(_throw_pushed_values):
+        __(mov vsp,imm1)
+        __(ldr imm1,[imm3,#catch_frame.xframe])
+        __(str(imm1,tcr.xframe(rcontext)))
+        __(ldr sp,[imm3,#catch_frame.csp])
+        __(ldr fn,[sp,#lisp_frame.savefn])
+        __(ldr loc_pc,[sp,#lisp_frame.savelr])
+        __(discard_lisp_frame())
+        __(mtlr loc_pc)
+        __(restore_catch_nvrs(imm3))
+        __(ldr imm3,[imm3,#catch_frame.link])
+        __(str(imm3,tcr.catch_top(rcontext)))
+        __(unlink(tsp))
+        __(bx lr)
+popdef(`__')
+
+C(nthrow1v):    
+local_label(_nthrow1v_nextframe):
+        __(subs temp2,temp2,#fixnum_one)
+        __(ldr temp0,[rcontext,#tcr.catch_top])
+        __(ldr imm1,[rcontext,#tcr.db_link])
+        __(set_nargs(1))
+        __(blt local_label(_nthrow1v_done))
+        __(ldr arg_y,[temp0,#catch_frame.link])
+        __(ldr imm0,[temp0,#catch_frame.db_link])
+        __(cmp imm0,imm1)
+        __(str arg_y,[rcontext,#tcr.catch_top])
+        __(ldr arg_y,[temp0,#catch_frame.xframe])
+        __(str arg_y,[rcontext,#tcr.xframe])
+        __(beq local_label(_nthrow1v_dont_unbind))
+        __(do_unbind_to(imm0,temp1,arg_x,arg_y))
+local_label(_nthrow1v_dont_unbind):
+        __(ldr temp1,[temp0,#catch_frame.catch_tag])
+        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
+        __(beq local_label(_nthrow1v_do_unwind))
+        /* A catch frame.  If the last one, restore context from there.  */
+        __(cmp temp2,#0)
+        __(ldreq vsp,[sp,#lisp_frame.savevsp])
+        __(add sp,sp,#catch_frame.size+lisp_frame.size)
+        __(b local_label(_nthrow1v_nextframe))
+local_label(_nthrow1v_do_unwind):
+pushdef(`__',`
+        .word 0
+        ')        
+        /* This is harder, but not as hard (not as much BLTing) as the  */
+        /* multiple-value case.  */
+        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
+        /* protect.  (Clever, eh ?)  */
+
+        __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
+        __(unlink(tsp))
+        __(ldr loc_pc,[sp,#lisp_frame.savelr])
+        __(ldr nfn,[sp,#lisp_frame.savefn])
+        __(mtctr loc_pc)  /* cleanup code address.  */
+        __(str(fn,lisp_frame.savefn(sp)))
+        __(mflr loc_pc)
+        __(mov fn,nfn)
+        __(str(loc_pc,lisp_frame.savelr(sp)))
+        __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
+        __(str(arg_z,tsp_frame.data_offset(tsp)))
+        __(str(temp2,tsp_frame.data_offset+node_size(tsp)))
+        __(ldr vsp,[sp,#lisp_frame.savevsp])
+        __(str(rzero,tcr.unwinding(rcontext)))
+        __(bctrl)
+        __(mov imm1,#1)
+        __(ldr arg_z,[tsp,#tsp_frame.data_offset])
+        __(str(imm1,tcr.unwinding(rcontext)))
+        __(ldr temp2,[tsp,#tsp_frame.data_offset+node_size])
+        __(ldr fn,[sp,#lisp_frame.savefn])
+        __(ldr loc_pc,[sp,#lisp_frame.savelr])
+        __(discard_lisp_frame())
+        __(mtlr loc_pc)
+        __(unlink(tsp))
+        __(b local_label(_nthrow1v_nextframe))
+popdef(`__')        
+local_label(_nthrow1v_done):
+        __(mov imm0,#0)
+        __(str imm0,[rcontext,#tcr.unwinding])
+        /* nargs has an undefined value here, so we can clobber it while */
+        /* polling for a deferred interrupt  */
+        __(check_pending_interrupt(nargs))
+        __(bx lr)
+        
+        
 	_endfile
Index: /branches/arm/lisp-kernel/arm-uuo.s
===================================================================
--- /branches/arm/lisp-kernel/arm-uuo.s	(revision 13686)
+++ /branches/arm/lisp-kernel/arm-uuo.s	(revision 13687)
@@ -83,4 +83,5 @@
 define(`uuo_error_not_callable',`unaryUUO($1,$2,2)')
 define(`uuo_tlb_too_small',`unaryUUO($1,$2,4)')
+define(`uuo_error_no_throw_tag',`unaryUUO($1,$2,5)')
 
 /* Binary UUOs */
