Changeset 13687


Ignore:
Timestamp:
May 7, 2010, 5:54:15 AM (10 years ago)
Author:
gb
Message:

More stuff!

Location:
branches/arm/lisp-kernel
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/arm/lisp-kernel/ARM-notes.txt

    r13663 r13687  
    8585callee-save NVRs.
    8686
     87There are some cases in the runtime where we effectively want
     88to exchange the lr with the saved lr value in a stack frame.  It's
     89possible to do this with a "swp" instruction; "swp" as a means
     90of doing interlocked memory operations has been deprecated in
     91ARMv6 and later.  We don't care about those semantics, and if
     92there are only a few places (calling UNWIND-PROTECT cleanup
     93forms) that need to do this it's probably better to use "swp"
     94rather than inventing a scheme that allows some register to
     95be temporarily treated as a locative.
     96
     97
    8798- Subprim calls
    8899
     
    200211
    201212  [explain complexity here ...]
     213
     214
     215 - misc
     216
     217I -hope- that the altstack mechanism works on all platforms and that
     218we don't have to explicitly check for stack overflow on r13.  (If it
     219does, we probably want to check for r13 overflow in the altstack/Mach
     220fault handler and unprotect pages there.)
     221
  • branches/arm/lisp-kernel/arm-asmutils.s

    r13668 r13687  
    2020
    2121        _beginfile
    22 /*  Zero R4 cache lines, starting at address in R3.  Each line is assumed to be */
    23 /* R5 bytes wide. */
    24 _exportfn(C(zero_cache_lines))
    25         __(cmpri(cr0,r4,0))
    26         __(mtctr r4)
    27         __(beqlr)
    28 1:
    29         __(DCBZL(0,r3))
    30         __(add r3,r3,r5)
    31         __(bdnz 1b)
    32         __(blr)
    33 _endfn
    3422
    35 /*  Flush R4 cache lines, starting at address in R3.  Each line is */
    36 /* assumed to be R5 bytes wide. */
    37 _exportfn(C(flush_cache_lines))
    38         __(cmpri(cr0,r4,0))
    39         __(mtctr r4)
    40         __(mr r6,r3)
    41         __(beqlr)
    42 1:
    43         __(dcbst 0,r3)
    44         __(add r3,r3,r5)
    45         __(bdnz 1b)
    46         __(sync)                /* wait until dcbst's get to memory */
    47         __(mr r3,r6)
    48         __(mtctr r4)
    49 2:     
    50         __(icbi 0,r3)
    51         __(add r3,r3,r5)
    52         __(bdnz 2b)
    53         __(sync)
    54         __(isync)
    55         __(blr)
    56 /* The strange reference to "exp" is supposed to force the kernel to */
    57 /* load libm, so lisp code can use it.   Under Darwin, the functionality */
    58 /* of libm is contained in libsystem, along with libc & everything else. */
     23/* Force data from r0 to r1 into the icache */       
     24_exportfn(C(_make_data_executable))
     25        __(mov r2,#0)           /* options.  Pass as 0 until we know better */
     26        __(mov r12,r7)          /* preserve r7 ;  r12 saved by syscall */
     27        __(mov r7,0x0f0000)     /* __ARM_NR_cacheflush */
     28        __(add r7,r7,#2)
     29        __(svc #0)
     30        __(mov r7,r12)
     31        __(bx lr)
    5932
    60         __ifndef(`DARWIN')
    61         .data
    62         __ifdef(`PPC64')
    63         .quad exp
    64         __else
    65         .long exp
    66         __endif
    67         .text       
    68         __endif
    69 _endfn
    70 
    71 _exportfn(C(touch_page))
    72         __(str(r3,0(r3)))
    73         __(li r4,0)
    74         __(str(r4,0(r3)))
    75         __(li r3,1) /* can't assume that low 32 bits of r3 are non-zero */
    76         .globl C(touch_page_end)
    77 C(touch_page_end):
    78         __(blr)
    79 _endfn
    8033                               
    8134_exportfn(C(current_stack_pointer))
    82         __(mr r3,sp)
    83         __(blr)
     35        __(mr r0,sp)
     36        __(bx lr)
    8437_endfn
    8538       
     
    9043
    9144_exportfn(C(noop))
    92         __(blr)
     45        __(bx lr)
    9346_endfn
    9447
    95 _exportfn(C(set_fpscr))
    96         __(stru(sp,-32(sp)))
    97         __(stw r3,12(sp))
    98         __(lfd f0,8(sp))
    99         __(mtfsf 0xff,f0)
    100         __(la sp,32(sp))
    101         __(blr)
    102 _endfn
    103 
    104 
    105 _exportfn(C(get_fpscr))
    106         __(stru(sp,-32(sp)))
    107         __(mffs f0)
    108         __(stfd f0,8(sp))
    109         __(lwz r3,12(sp))
    110         __(la sp,32(sp))
    111         __(blr)
    112 _endfn
    113                
    11448
    11549
     
    12054
    12155_exportfn(C(store_conditional))
    122         __(mr r6,r3)
    123 1:      __(lrarx(r3,0,r6))
    124         __(cmpw r3,r4)
    125         __(bne- 2f)
    126         __(strcx(r5,0,r6))
    127         __(bne- 1b)
    128         __(isync)
    129         __(blr)
    130 2:      __(li r0,RESERVATION_DISCHARGE)
    131         __(strcx(r0,0,r0))
    132         __(blr)
     56        __ifdef([LINUX])
     57        /* To deal with different ARM variants, Linux provides
     58           a magic kernel function that does the right thing in
     59           the absence of ldrex/strex/clrex and memory-barrier
     60           functions.  That function takes args in a different
     61           order (r0 = expected oldval, r1 = newval, r2 = addr.)
     62        */
     63        __(stmdb pc!,{r4,lr})
     64        __(eor r0,r0,r2)
     65        __(eor r2,r2,r0)
     66        __(eor r0,r0,r2)
     670:      __(ldr r3,[r2])
     68        __(cmp r3,r0)
     69        __(bne 1f)   
     70        __(mov lr,#0xffff0fff)
     71        __(add lr,lr,#(0xffff0fc0 - 0xffff0fff))
     72        __(blx lr)
     73        __(bcc 0b)
     741:      __(mov r0,r3)
     75        __(ldmia pc!,{r4,lr})
     76        __endif
    13377_endfn
    13478
  • branches/arm/lisp-kernel/arm-constants.s

    r13680 r13687  
    4444/* registers.  These assignments may not be viable. */
    4545
    46 define(`arg_z',`r0')
    47 define(`arg_y',`r1')
    48 define(`arg_x',`r2')
    49 define(`temp0',`r3')
    50 define(`temp1',`r4')
    51 define(`temp2',`r5')
    52 define(`imm0',`r6')             /* even, so ldrd/strd can use imm0/imm1 */
    53 define(`imm1',`r7')
    54 define(`imm2',`r9')
    55 define(`vsp',`r9')
    56 define(`fn',`r10')
    57 define(`rcontext',`r11')
     46define(`imm0',`r0')             /* even, so ldrd/strd can use imm0/imm1 */
     47define(`imm1',`r1')
     48define(`imm2',`r2')
     49/* rcontext = r3 can be used as an imm reg in certain contexts
     50   (its value must be easily recovered, but that value never changes
     51   during a thread's lifetime.)
     52*/       
     53define(`rcontext',`r3')         
     54define(`arg_z',`r4')
     55define(`arg_y',`r5')
     56define(`arg_x',`r6')
     57define(`temp0',`r7')
     58define(`temp1',`r8')
     59define(`temp2',`r9')
     60define(`vsp',`r10')
     61define(`fn',`r11')
    5862define(`allocptr',`r12')
    5963define(`sp',`r13')
     
    658662
    659663define(`whole_reg',`temp1')
    660 define(`arg_reg',`temp3')
     664define(`arg_reg',`temp0')
    661665define(`keyvect_reg',`temp2')
    662666define(`mask_req_start',`24')
  • branches/arm/lisp-kernel/arm-macros.s

    r13680 r13687  
    214214')
    215215
     216define(`vpush_all_argregs',`
     217        __(stmdb vsp!,{arg_z,arg_y,arg_x})
     218        ')
     219
     220define(`vpop_all_argregs',`
     221        __(ldmia vsp!,{arg_z,arg_y,arg_x})
     222        ')
     223                       
     224               
    216225
    217226/* $1 = arg/temp reg for lisp_frame_marker, $2 = value for lisp_frame.savevsp */               
     
    414423')
    415424
     425/* Stack-allocate an ivector; $1 = header, $0 = dnode-aligned
     426   size in bytes. */
     427define(`stack_allocate_ivector',`
     428        __(str $1,[sp,-$2]!)
     429        ')
     430       
     431                       
    416432/* Stack-allocate an ivector and zero its contents; caller may
    417433   change subtag of header after it's zeroed.
    418434   $1 = header (tagged as subtag_u32_vector until zeroed), $2 = dnode-
    419435   aligned size in bytes).  Both $1 and $2 are modified here. */
    420 define(`stack_allocate_zeroed_word_vector',`
     436define(`stack_allocate_zeroed_ivector',`
    421437       new_macro_labels()
    422438        __(str $1,[sp,-$2]!)
     
    442458define(`check_pending_interrupt',`
    443459        new_macro_labels()
    444         __(ldr $1,tcr.tlb_pointer(rcontext))
     460        __(ldr $1,[rcontext,#tcr.tlb_pointer])
    445461        __(ldr $1,[$1,$INTERRUPT_LEVEL_BINDING_INDEX])
    446462        __(cmp $1,#0)
     
    465481        __(cmp $2,#fulltag_immheader)
    466482        __(extract_lowbyte($2,$1))
    467         __(mov $1,$1 lsr #num_subtag_bits)
    468         __(moveq $1,$1 lsl #2)
     483        __(mov $1,$1,lsr #num_subtag_bits)
     484        __(moveq $1,$1,lsl #2)
    469485        __(beq macro_label(bytes))
    470486        __(cmp $2,#max_32_bit_ivector_subtag)
    471         __(movle $1,$1 lsl #2)
     487        __(movle $1,$1,lsl #2)
    472488        __(ble macro_label(bytes))
    473489        __(cmp $2,#max_8_bit_ivector_subtag)
     
    486502        __(add $1,$1,$3)
    487503        ')
     504
     505/* This may need to be inlined.  $1=link, $2=saved sym idx, $3 = tlb, $4 = value */
     506define(`do_unbind_to',`
     507        __(ldr $1,[rcontext,#tcr.db_link])
     508        __(ldr $3,[rcontext,#tcr.tlb_pointer])
     5091:      __(ldr $2,[$1,#binding.sym])
     510        __(ldr $4,[$1,#binding.val])
     511        __(ldr $1,[$1,#binding.link])
     512        __(cmp imm0,$1)
     513        __(str $4,[$3,$2])
     514        __(bne 1b)
     515        __(str $1,[rcontext,#tcr.db_link])
     516        ')               
     517
     518/* Linux provides a weird kernel entrypoint to do cmpxchg on hardware
     519   that may not support it natively.  Darwin only runs on ARMv6 hardware,
     520   which can use ldrex/strex instructions to do cmpxchg inline.  On
     521   SMP hardware, the cmpxchg should be followe by a 'dmb' (data memory
     522   barrier) instruction, which is only available on ARMv7.  Confused yet?
     523   The Linux kernel function clobbers some registers, and we may need
     524   some support in pc_luser_xp() to fix things up at interrupt/suspend
     525   time.
     526   Generally, imm1 = mask with exactly one bit set, *imm2 = address of
     527   refbits word. */
     528
     529define(`set_ref_bit',`
     530        new_macro_labels()
     531        __ifdef(`LINUX')
     532        .globl set_ref_bit_entry_$1
     533set_ref_bit_entry_$1:   
     534        __(build_lisp_frame(imm0))  /* we clobber lr */
     535        __(mov temp1,imm1)
     536        __(mov temp2,rcontext)
     537macro_label(again):     
     538        __(ldr lr,macro_label(linux_kernel_cmpxchg))
     539        __(ldr r0,[r2])
     540        __(orr r1,r0,temp1)
     541        __(blx lr)
     542        .globl set_ref_bit_return_$1
     543set_ref_bit_return_$1:   
     544        __(mov rcontext,temp2)
     545        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     546        __(bcc macro_label(again))
     547        __(restore_lisp_frame(imm0))
     548        __(b macro_label(continue))
     549macro_label(linux_kernel_cmpxchg):
     550        .word 0xffff0fc0        /* magic address */
     551macro_label(continue):
     552        __endif
     553        __ifdef(`DARWIN')
     554macro_label(again):     
     555        __(ldrex r0,[r2])
     556        __(orr r0,r0,r1)
     557        __(strex r0,r0,[r2])
     558        __(cmp r0,#0)
     559        __(bne macro_label(again))
     560        __endif
     561        ')
     562                       
  • branches/arm/lisp-kernel/arm-spentry.s

    r13680 r13687  
    4646')
    4747
     48_spentry(builtin_plus)
     49        __(test_two_fixnums(arg_y,arg_z,imm0))
     50        __(bne 1f)
     51        __(adds arg_z,arg_y,arg_z)
     52        __(bxvc lr)
     53        __(b _SPfix_overflow)
     541:
     55        __(jump_builtin(_builtin_plus,2))
     56       
     57_spentry(builtin_minus)
     58        __(test_two_fixnums(arg_y,arg_z,imm0))
     59        __(bne 1f)
     60        __(subs arg_z,arg_y,arg_z)
     61        __(bxvc lr)
     62        __(b _SPfix_overflow)
     631:
     64        __(jump_builtin(_builtin_minus,2))
     65
     66_spentry(builtin_times)
     67        __(test_two_fixnums(arg_y,arg_z,imm0))
     68        __(bne 1f)
     69        __(unbox_fixnum(imm2,arg_z))
     70        __(smull arg_z,imm1,imm2,arg_y)
     71        /* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */
     72        /* imm1 is just a sign extension of arg_z, return arg_z */
     73        __(cmp imm1,arg_z,asr #(nbits_in_word-1))
     74        __(bxeq lr)
     75        /* Need to ashift the pair imm1:imm0 right fixnumshift bits */
     76        __(mov imm0,imm0,lsr #fixnumshift)
     77        __(and imm2,imm1,#fixnummask)
     78        __(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift))
     79        __(unbox_fixnum(imm1,imm1))
     80        __(b _SPmakes64)
     81
     821: __(jump_builtin(_builtin_times,2))
     83
     84_spentry(builtin_div)
     85        __(jump_builtin(_builtin_div,2))
     86
     87_spentry(builtin_eq)
     88        __(test_two_fixnums(arg_y,arg_z,imm0))
     89        __(bne 1f)
     90        __(cmp arg_y,arg_z)
     91        __(mov arg_z,#nil_value)
     92        __(addeq arg_z,arg_z,#t_offset)
     93        __(bx lr)       
     941:
     95        __(jump_builtin(_builtin_eq,2))
     96                       
     97_spentry(builtin_ne)
     98        __(test_two_fixnums(arg_y,arg_z,imm0))
     99        __(bne 1f)
     100        __(cmp arg_y,arg_z)
     101        __(mov arg_z,#nil_value)
     102        __(addne arg_z,arg_z,#t_offset)
     103        __(bx lr)
     1041:
     105        __(jump_builtin(_builtin_ne,2))
     106
     107_spentry(builtin_gt)
     108        __(test_two_fixnums(arg_y,arg_z,imm0))
     109        __(bne 1f)
     110        __(cmp arg_y,arg_z)
     111        __(mov arg_z,#nil_value)
     112        __(addgt arg_z,arg_z,#t_offset)
     113        __(bx lr)
     1141:
     115        __(jump_builtin(_builtin_gt,2))
     116
     117_spentry(builtin_ge)
     118        __(test_two_fixnums(arg_y,arg_z,imm0))
     119        __(bne 1f)
     120        __(cmp arg_y,arg_z)
     121        __(mov arg_z,#nil_value)
     122        __(addge arg_z,arg_z,#t_offset)
     123        __(bx lr)
     1241:
     125        __(jump_builtin(_builtin_ge,2))
     126
     127_spentry(builtin_lt)
     128        __(test_two_fixnums(arg_y,arg_z,imm0))
     129        __(bne 1f)
     130        __(cmp arg_y,arg_z)
     131        __(mov arg_z,#nil_value)
     132        __(addgt arg_z,arg_z,#t_offset)
     133        __(bx lr)
     1341:
     135        __(jump_builtin(_builtin_lt,2))
     136
     137_spentry(builtin_le)
     138        __(test_two_fixnums(arg_y,arg_z,imm0))
     139        __(bne 1f)
     140        __(cmp arg_y,arg_z)
     141        __(mov arg_z,#nil_value)
     142        __(addle arg_z,arg_z,#t_offset)
     143        __(bx lr)
     1441:
     145        __(jump_builtin(_builtin_le,2))
     146
     147_spentry(builtin_eql)
     148        __(cmp arg_y,arg_z)
     149        __(beq 1f)
     150        __(extract_fulltag(imm0,arg_y))
     151        __(extract_fulltag(imm1,arg_z))
     152        __(cmp imm0,imm1)
     153        __(bne 2f)
     154        __(cmp imm0,#fulltag_misc)
     155        __(bne 2f)
     156        __(jump_builtin(_builtin_eql,2))
     1571:      __(mov arg_z,#nil_value)
     158        __(add arg_z,arg_z,#t_offset)
     159        __(bx lr)
     1602:      __(mov arg_z,#nil_value)
     161        __(bx lr)
     162       
     163_spentry(builtin_length)
     164        __(extract_typecode(imm0,arg_z))
     165        __(cmp imm0,#min_vector_subtag)
     166        __(ldreq arg_z,[arg_z,#vectorH.logsize])
     167        __(bxeq lr)
     168        __(blo 1f)
     169        __(vector_length(arg_z,arg_z,imm0))
     170        __(bx lr)
     1711:      __(cmp imm0,#tag_list)
     172        __(bne 8f)
     173        __(mov temp2,#-1<<fixnum_shift)
     174        __(mov temp0,arg_z) /* fast pointer  */
     175        __(mov temp1,arg_z) /* slow pointer  */
     1762:      __(cmp temp0,#nil_value)
     177        __(add temp2,temp2,#fixnumone)
     178        __(beq 9f)
     179        __(extract_lisptag(imm0,temp0))
     180        __(cmp imm0,#tag_list)
     181        __(bne 8f)
     182        __(_cdr(temp0,temp0))
     183        __(tst temp2,#fixnumone)
     184        __(beq 2b)
     185        __(_cdr(temp1,temp1))
     186        __(cmp temp1,temp0)
     187        __(bne 2b)
     1888:
     189        __(jump_builtin(_builtin_length,1))
     1909:      __(mov arg_z,temp2)
     191        __(bx lr)       
     192
     193_spentry(builtin_seqtype)
     194        __(extract_typecode(imm0,arg_z))
     195        __(cmp imm0,#min_vector_subtag)
     196        __(movge arg_z,#nil_value)
     197        __(bxge lr)
     198        __(cmp imm0,#tag_list)
     199        __(moveq arg_z,#nil_value)
     200        __(addeq arg_z,arg_z,#t_offset)
     201        __(bxeq lr)
     202        __(jump_builtin(_builtin_seqtype,1))
     203
     204/* This is usually inlined these days */
     205_spentry(builtin_assq)
     206        __(b 2f)
     2071:      __(trap_unless_list(arg_z,imm0))
     208        __(_car(arg_x,arg_z))
     209        __(_cdr(arg_z,arg_z))
     210        __(cmp arg_x,#nil_value)
     211        __(beq 2f)
     212        __(trap_unless_list(arg_x,imm0))
     213        __(_car(temp0,arg_x))
     214        __(cmp temp0,arg_y)
     215        __(bne 2f)
     216        __(mov arg_z,arg_x)
     217        __(bx lr)
     2182:      __(cmp arg_z,#nil_value)
     219        __(bne 1b)
     220        __(bx lr)
     221 
     222_spentry(builtin_memq)
     223        __(cmp arg_z,nil_value)
     224        __(b 2f)
     2251:      __(trap_unless_list(arg_z,imm0))
     226        __(_car(arg_x,arg_z))
     227        __(_cdr(temp0,arg_z))
     228        __(cmp arg_x,arg_y)
     229        __(bxeq lr)
     230        __(cmp temp0,nil_value)
     231        __(mov arg_z,temp0)
     2322:      __(bne 1b)
     233        __(bx lr)
     234
     235_spentry(builtin_logbitp)
     236/* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
     237        __(test_two_fixnums(arg_y,arg_z,imm0))
     238        __(bne 1f)
     239        __(uuo_suspend_now(al))
     240        __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
     241        __(bhs 1f)
     242        __(unbox_fixnum(imm0,arg_y))
     243        __(mov imm1,#fixnum1)
     244        __(tst arg_z,imm1,lsl imm0)
     245        __(mov arg_z,#nil_value)
     246        __(addne arg_z,arg_z,#t_offset)
     247        __(bx lr)
     2481:
     249        __(jump_builtin(_builtin_logbitp,2))
     250
     251_spentry(builtin_logior)
     252        __(orr imm0,arg_y,arg_z)
     253        __(test_fixnum(imm0))
     254        __(moveq arg_z,imm0)
     255        __(bxeq lr)
     256        __(jump_builtin(_builtin_logior,2))
     257
     258_spentry(builtin_logand)
     259        __(test_two_fixnums(arg_y,arg_z,imm0))
     260        __(andeq arg_z,arg_y,arg_z)
     261        __(bxeq lr)
     262        __(jump_builtin(_builtin_logand,2))
     263         
     264_spentry(builtin_ash)
     265        __(test_two_fixnums(arg_y,arg_z,imm0))
     266        __(bne 9f)
     267        __(cmp arg_z,#0)
     268        __(bgt 1f)
     269        __(moveq arg_z,arg_y)
     270        __(bxeq lr)
     271        /* Shift right */
     272        __(unbox_fixnum(imm2,arg_z))
     273        __(rsb imm2,imm2,#0)
     274        __(cmp imm2,#32)
     275        __(movge imm2,#31)
     276        __(mov arg_z,#-fixnumone)
     277        __(and arg_z,arg_z,arg_y,lsr imm2)
     278        __(bx lr)
     279        /* shift left */
     2801:      __(unbox_fixnum(imm0,arg_y))
     281        __(unbox_fixnum(imm2,arg_z))
     282        __(cmp imm2,#32)
     283        __(moveq imm1,imm0)
     284        __(moveq imm0,#0)
     285        __(beq _SPmakes64)
     286        __(bgt 9f)
     287        __(mov imm1,imm1,asl imm2)
     288        __(rsb imm2,imm2,#32)
     289        __(orr imm1,imm1,imm0,asr imm2)
     290        __(unbox_fixnum(imm2,arg_z))
     291        __(mov imm0,imm0,asl imm2)
     292        __(b _SPmake64)
     2939: 
     294        __(jump_builtin(_builtin_ash,2))
     295                                       
     296_spentry(builtin_negate)
     297        __(test_fixnum(arg_z))
     298        __(bne 1f)
     299        __(rsbs arg_z,arg_z,#0)
     300        __(bxvc lr)
     301        __(b _SPfix_overflow)
     3021:
     303        __(jump_builtin(_builtin_negate,1))
     304 
     305_spentry(builtin_logxor)
     306        __(test_two_fixnums(arg_y,arg_z,imm0))
     307        __(eoreq arg_z,arg_y,arg_z)
     308        __(bxeq lr)
     309        __(jump_builtin(_builtin_logxor,2))
     310
     311_spentry(builtin_aref1)
     312        __(extract_typecode(imm0,arg_y))
     313        __(cmp imm0,#min_vector_subtag)
     314        __(box_fixnum(arg_x,imm0))
     315        __(bgt _SPsubtag_misc_ref)
     316        __(jump_builtin(_builtin_aref1,2))
     317
     318_spentry(builtin_aset1)
     319        __(extract_typecode(imm0,arg_x))
     320        __(cmp imm0,#min_vector_subtag)
     321        __(box_fixnum(temp0,imm0))
     322        __(bgt _SPsubtag_misc_set)
     323        __(jump_builtin(_builtin_aset1,3))
     324                       
    48325_spentry(jmpsym)
    49326        __(jump_fname())
     
    163440        __(b _SPmakes32)
    164441
    165 _spentry(builtin_plus)
    166         __(test_two_fixnums(arg_y,arg_z,imm0))
    167         __(bne 1f)
    168         __(adds arg_z,arg_y,arg_z)
    169         __(bxvc lr)
    170         __(b _SPfix_overflow)
    171 1:
    172         __(jump_builtin(_builtin_plus,2))
    173 
    174 _spentry(builtin_minus)
    175         __(test_two_fixnums(arg_y,arg_z,imm0))
    176         __(bne 1f)
    177         __(subs arg_z,arg_y,arg_z)
    178         __(bxvc lr)
    179         __(b _SPfix_overflow)
    180 1:
    181         __(jump_builtin(_builtin_minus,2))
     442
    182443
    183444/*  Construct a lisp integer out of the 64-bit unsigned value in */
     
    211472        __(bx lr)
    212473
    213 _spentry(builtin_times)
    214         __(test_two_fixnums(arg_y,arg_z,imm0))
    215         __(bne 1f)
    216         __(unbox_fixnum(imm2,arg_z))
    217         __(smull arg_z,imm1,imm2,arg_y)
    218         /* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */
    219         /* imm1 is just a sign extension of arg_z, return arg_z */
    220         __(cmp imm1,arg_z,asr #(nbits_in_word-1))
    221         __(bxeq lr)
    222         /* Need to ashift the pair imm1:imm0 right fixnumshift bits */
    223         __(mov imm0,imm0,lsr #fixnumshift)
    224         __(and imm2,imm1,#fixnummask)
    225         __(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift))
    226         __(unbox_fixnum(imm1,imm1))
    227         __(b _SPmakes64)
    228 
    229 1: __(jump_builtin(_builtin_times,2))
    230 
    231 _spentry(builtin_eq)
    232         __(test_two_fixnums(arg_y,arg_z,imm0))
    233         __(bne 1f)
    234         __(cmp arg_y,arg_z)
    235         __(mov arg_z,#nil_value)
    236         __(addeq arg_z,arg_z,#t_offset)
    237         __(bx lr)       
    238 1:
    239         __(jump_builtin(_builtin_eq,2))
    240 
    241 _spentry(builtin_ne)
    242         __(test_two_fixnums(arg_y,arg_z,imm0))
    243         __(bne 1f)
    244         __(cmp arg_y,arg_z)
    245         __(mov arg_z,#nil_value)
    246         __(addne arg_z,arg_z,#t_offset)
    247         __(bx lr)
    248 1:
    249         __(jump_builtin(_builtin_ne,2))
    250 
    251 _spentry(builtin_gt)
    252         __(test_two_fixnums(arg_y,arg_z,imm0))
    253         __(bne 1f)
    254         __(cmp arg_y,arg_z)
    255         __(mov arg_z,#nil_value)
    256         __(addgt arg_z,arg_z,#t_offset)
    257         __(bx lr)
    258 1:
    259         __(jump_builtin(_builtin_gt,2))
    260 
    261 _spentry(builtin_ge)
    262         __(test_two_fixnums(arg_y,arg_z,imm0))
    263         __(bne 1f)
    264         __(cmp arg_y,arg_z)
    265         __(mov arg_z,#nil_value)
    266         __(addge arg_z,arg_z,#t_offset)
    267         __(bx lr)
    268 1:
    269         __(jump_builtin(_builtin_ge,2))
    270 
    271 _spentry(builtin_lt)
    272         __(test_two_fixnums(arg_y,arg_z,imm0))
    273         __(bne 1f)
    274         __(cmp arg_y,arg_z)
    275         __(mov arg_z,#nil_value)
    276         __(addgt arg_z,arg_z,#t_offset)
    277         __(bx lr)
    278 1:
    279         __(jump_builtin(_builtin_lt,2))
    280 
    281 _spentry(builtin_le)
    282         __(test_two_fixnums(arg_y,arg_z,imm0))
    283         __(bne 1f)
    284         __(cmp arg_y,arg_z)
    285         __(mov arg_z,#nil_value)
    286         __(addle arg_z,arg_z,#t_offset)
    287         __(bx lr)
    288 1:
    289         __(jump_builtin(_builtin_le,2))
     474
     475
     476
     477
    290478
    291479/* funcall nfn, returning multiple values if it does.  */
     
    365553        __(b local_label(return_values))                         
    366554
    367 dnl /* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
    368 dnl /* Otherwise, process unwind-protects and throw to indicated catch frame.  */
    369 dnl
    370 dnl _spentry(throw)
    371 dnl  __(ldr imm1,[rcontext, #tcr.catch_top])
    372 dnl  __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
    373 dnl  __(cmpri(cr0,imm1,0))
    374 dnl  __(ldr temp0,[vsp,nargs])
    375 dnl  __(beq- cr0,local_label(_throw_tag_not_found))
    376 dnl local_label(_throw_loop):
    377 dnl  __(ldr temp1,[imm1,#catch_frame.catch_tag])
    378 dnl  __(cmpr(cr0,temp0,temp1))
    379 dnl  __(mov imm2,imm1)
    380 dnl  __(ldr imm1,[imm1,#catch_frame.link])
    381 dnl  __(cmpri(cr1,imm1,0))
    382 dnl  __(beq cr0,local_label(_throw_found))
    383 dnl  __(addi imm0,imm0,fixnum_one)
    384 dnl  __(beq- cr1,local_label(_throw_tag_not_found))
    385 dnl  __(b local_label(_throw_loop))
    386 dnl /* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
    387 dnl /* frames. If target isn't a multiple-value receiver, discard extra values */
    388 dnl /* (less hair, maybe.)  */
    389 dnl local_label(_throw_found):
    390 dnl  __(ldr imm1,[imm2,#catch_frame.mvflag])
    391 dnl  __(cmpri(cr0,imm1,0))
    392 dnl  __(cmpri(cr1,nargs,0))
    393 dnl  __(mov fn,#0)
    394 dnl  __(add imm1,vsp,nargs)
    395 dnl  __(add imm1,[imm1,#-node_size])
    396 dnl  __(bne cr0,local_label(_throw_all_values))
    397 dnl  __(set_nargs(1))
    398 dnl  __(beq cr1,local_label(_throw_default_1_val))
    399 dnl  __(mov vsp,imm1)
    400 dnl  __(b local_label(_throw_all_values))
    401 dnl local_label(_throw_default_1_val):
    402 dnl  __(mov imm4,#nil_value)
    403 dnl  __(vpush1(imm4))
    404 dnl local_label(_throw_all_values):
    405 dnl  __(bl _SPnthrowvalues)
    406 dnl  __(ldr imm3,[rcontext,#tcr.catch_top])
    407 dnl  __(ldr imm1,[rcontext,#tcr.db_link])
    408 dnl  __(ldr imm0,[imm3,#catch_frame.db_link])
    409 dnl  __(ldr imm4,[imm3,#catch_frame.mvflag])
    410 dnl  __(cmpr(cr0,imm0,imm1))
    411 dnl  __(cmpri(cr1,imm4,0))
    412 dnl  __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
    413 dnl  __(beq cr0,local_label(_throw_dont_unbind))
    414 dnl         __(bl _SPunbind_to)
    415 dnl local_label(_throw_dont_unbind):
    416 dnl  __(add imm0,vsp,nargs)
    417 dnl  __(cmpri(cr0,nargs,0))
    418 dnl  __(ldr imm1,[imm3,#catch_frame.csp])
    419 dnl  __(ldr imm1,[imm1,#lisp_frame.savevsp])
    420 dnl  __(bne cr1,local_label(_throw_multiple))
    421 dnl         /* Catcher expects single value in arg_z  */
    422 dnl  __(ldr arg_z,[imm0,#-node_size])
    423 dnl  __(b local_label(_throw_pushed_values))
    424 dnl local_label(_throw_multiple):
    425 dnl  __(beq cr0,local_label(_throw_pushed_values))
    426 dnl  __(mov imm2,nargs)
    427 dnl local_label(_throw_mvloop):
    428 dnl  __(subi imm2,imm2,fixnum_one)
    429 dnl  __(cmpri(imm2,0))
    430 dnl  __(ldru(temp0,-node_size(imm0)))
    431 dnl  __(push(temp0,imm1))
    432 dnl  __(bgt local_label(_throw_mvloop))
    433 dnl local_label(_throw_pushed_values):
    434 dnl  __(mov vsp,imm1)
    435 dnl  __(ldr imm1,[imm3,#catch_frame.xframe])
    436 dnl  __(str(imm1,tcr.xframe(rcontext)))
    437 dnl  __(ldr sp,[imm3,#catch_frame.csp])
    438 dnl  __(ldr fn,[sp,#lisp_frame.savefn])
    439 dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
    440 dnl  __(discard_lisp_frame())
    441 dnl  __(mtlr loc_pc)
    442 dnl         __(restore_catch_nvrs(imm3))
    443 dnl  __(ldr imm3,[imm3,#catch_frame.link])
    444 dnl  __(str(imm3,tcr.catch_top(rcontext)))
    445 dnl  __(unlink(tsp))
    446 dnl  __(bx lr)
    447 dnl local_label(_throw_tag_not_found):
    448 dnl  __(uuo_interr(error_throw_tag_missing,temp0))
    449 dnl  __(strux(temp0,vsp,nargs))
    450 dnl  __(b _SPthrow)
    451 dnl
    452 dnl
    453 dnl /* This takes N multiple values atop the vstack.  */
    454 dnl _spentry(nthrowvalues)
     555/* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
     556/* Otherwise, process unwind-protects and throw to indicated catch frame.  */
     557
     558               
     559 _spentry(throw)
     560        __(ldr imm1,[rcontext, #tcr.catch_top])
     561        __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
     562        __(cmp imm1,#0)
     563        __(ldr temp0,[vsp,nargs])
     564        __(beq local_label(_throw_tag_not_found))
     565local_label(_throw_loop):
     566        __(ldr temp1,[imm1,#catch_frame.catch_tag])
     567        __(cmp temp0,temp1)
     568        __(mov imm2,imm1)
     569        __(ldr imm1,[imm1,#catch_frame.link])
     570        __(beq C(_throw_found))
     571        __(cmp imm1,#0)
     572        __(add imm0,imm0,#fixnum_one)
     573        __(bne local_label(_throw_loop))
     574local_label(_throw_tag_not_found):
     575        __(uuo_error_no_throw_tag(al,temp0))
     576        __(str temp0,[vsp,nargs])
     577        __(b _SPthrow)
     578
     579/* This takes N multiple values atop the vstack.  */
     580_spentry(nthrowvalues)
    455581dnl         __(mov imm1,#1)
    456582dnl  __(mov imm4,imm0)
     
    464590dnl  __(ldr imm0,[temp0,#catch_frame.db_link])
    465591dnl  __(ldr imm3,[temp0,#catch_frame.link])
    466 dnl  __(cmpr(cr0,imm0,imm1))
     592dnl  __(cmpr(imm0,imm1))
    467593dnl  __(str(imm3,tcr.catch_top(rcontext)))
    468594dnl  __(ldr temp1,[temp0,#catch_frame.catch_tag])
     
    471597dnl  __(str(first_nvr,tcr.xframe(rcontext)))
    472598dnl  __(ldr sp,[temp0,#catch_frame.csp])
    473 dnl  __(beq cr0,local_label(_nthrowv_dont_unbind))
     599dnl  __(beq local_label(_nthrowv_dont_unbind))
    474600dnl  __(mflr loc_pc)
    475601dnl         __(bl _SPunbind_to)
     
    488614dnl  __(push(temp1,imm0))
    489615dnl local_label(_nthrowv_push_test):
    490 dnl  __(cmpri(imm2,0))
     616dnl  __(cmp imm2,#0))
    491617dnl  __(subi imm2,imm2,fixnum_one)
    492618dnl  __(bne local_label(_nthrowv_push_loop))
     
    529655dnl  __(subi imm2,imm2,fixnum_one)
    530656dnl local_label(_nthrowv_tpushtest):
    531 dnl  __(cmpri(imm2,0))
     657dnl  __(cmp imm2,#0)
    532658dnl  __(bne local_label(_nthrowv_tpushloop))
    533659dnl  __(stru(imm4,node_size(imm0)))
     
    553679dnl  __(subi imm2,imm2,fixnum_one)
    554680dnl local_label(_nthrowv_tpoptest):
    555 dnl  __(cmpri(imm2,0))
     681dnl  __(cmp imm2,#0)
    556682dnl  __(bne local_label(_nthrowv_tpoploop))
    557683dnl  __(ldr imm4,[imm0,#node_size])
     
    567693dnl         __(mov nargs,imm4)
    568694dnl         __(bx lr)
    569 dnl
    570 dnl /* This is a (slight) optimization.  When running an unwind-protect, */
    571 dnl /* save the single value and the throw count in the tstack frame. */
    572 dnl /* Note that this takes a single value in arg_z.  */
    573 dnl _spentry(nthrow1value)
    574 dnl         __(mov imm1,#1)
    575 dnl  __(mov imm4,imm0)
    576 dnl         __(str(imm1,tcr.unwinding(rcontext)))
    577 dnl local_label(_nthrow1v_nextframe):
    578 dnl  __(subi imm4,imm4,fixnum_one)
    579 dnl  __(cmpri(cr1,imm4,0))
    580 dnl  __(ldr temp0,[rcontext,#tcr.catch_top])
    581 dnl  __(ldr imm1,[rcontext,#tcr.db_link])
    582 dnl  __(set_nargs(1))
    583 dnl  __(blt cr1,local_label(_nthrow1v_done))
    584 dnl  __(ldr imm3,[temp0,#catch_frame.link])
    585 dnl  __(ldr imm0,[temp0,#catch_frame.db_link])
    586 dnl  __(cmpr(cr0,imm0,imm1))
    587 dnl  __(str(imm3,tcr.catch_top(rcontext)))
    588 dnl         __(ldr imm3,[temp0,#catch_frame.xframe])
    589 dnl  __(ldr temp1,[temp0,#catch_frame.catch_tag])
    590 dnl  __(cmpri(cr7,temp1,unbound_marker))  /* unwind-protect ?  */
    591 dnl         __(str(imm3,tcr.xframe(rcontext)))
    592 dnl  __(ldr sp,[temp0,#catch_frame.csp])
    593 dnl  __(beq cr0,local_label(_nthrow1v_dont_unbind))
    594 dnl   __(mflr loc_pc)
    595 dnl          __(bl _SPunbind_to)
    596 dnl   __(mtlr loc_pc)
    597 dnl local_label(_nthrow1v_dont_unbind):
    598 dnl  __(beq cr7,local_label(_nthrow1v_do_unwind))
    599 dnl         /* A catch frame.  If the last one, restore context from there.  */
    600 dnl  __(bne cr1,local_label(_nthrow1v_skip))
    601 dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
    602 dnl         __(restore_catch_nvrs(temp0))
    603 dnl local_label(_nthrow1v_skip):
    604 dnl  __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
    605 dnl  __(unlink(tsp))
    606 dnl  __(discard_lisp_frame())
    607 dnl  __(b local_label(_nthrow1v_nextframe))
    608 dnl local_label(_nthrow1v_do_unwind):
    609 dnl         /* This is harder, but not as hard (not as much BLTing) as the  */
    610 dnl         /* multiple-value case.  */
    611 dnl         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
    612 dnl         /* protect.  (Clever, eh ?)  */
    613 dnl
    614 dnl         __(restore_catch_nvrs(temp0))
    615 dnl  __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
    616 dnl  __(unlink(tsp))
    617 dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
    618 dnl  __(ldr nfn,[sp,#lisp_frame.savefn])
    619 dnl  __(mtctr loc_pc)  /* cleanup code address.  */
    620 dnl  __(str(fn,lisp_frame.savefn(sp)))
    621 dnl  __(mflr loc_pc)
    622 dnl  __(mov fn,nfn)
    623 dnl  __(str(loc_pc,lisp_frame.savelr(sp)))
    624 dnl  __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
    625 dnl  __(str(arg_z,tsp_frame.data_offset(tsp)))
    626 dnl  __(str(imm4,tsp_frame.data_offset+node_size(tsp)))
    627 dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
    628 dnl         __(str(rzero,tcr.unwinding(rcontext)))
    629 dnl  __(bctrl)
    630 dnl         __(mov imm1,#1)
    631 dnl  __(ldr arg_z,[tsp,#tsp_frame.data_offset])
    632 dnl         __(str(imm1,tcr.unwinding(rcontext)))
    633 dnl  __(ldr imm4,[tsp,#tsp_frame.data_offset+node_size])
    634 dnl  __(ldr fn,[sp,#lisp_frame.savefn])
    635 dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
    636 dnl  __(discard_lisp_frame())
    637 dnl  __(mtlr loc_pc)
    638 dnl  __(unlink(tsp))
    639 dnl  __(b local_label(_nthrow1v_nextframe))
    640 dnl local_label(_nthrow1v_done):
    641 dnl         __(str(rzero,tcr.unwinding(rcontext)))
    642 dnl         /* nargs has an undefined value here, so we can clobber it while */
    643 dnl         /* polling for a deferred interrupt  */
    644 dnl         __(check_pending_interrupt())
    645 dnl         __(bx lr)
     695
     696/* This is a (slight) optimization.  When running an unwind-protect, */
     697/* save the single value and the throw count in the tstack frame. */
     698/* Note that this takes a single value in arg_z.  */
     699_spentry(nthrow1value)
     700        __(mov imm1,#1)
     701        __(mov temp2,imm0)
     702        __(str imm1,[rcontext,#tcr.unwinding])
     703        __(b C(nthrow1v))
     704
    646705
    647706/* arg_z = symbol: bind it to its current value          */
     
    700759        __(set_nargs(2))
    701760        __(b _SPksignalerr)
    702 dnl
    703 dnl
    704 dnl /* The function pc_luser_xp() - which is used to ensure that suspended threads */
    705 dnl /* are suspended in a GC-safe way - has to treat these subprims (which  */
    706 dnl /* implement the EGC write-barrier) specially.  Specifically, a store that */
    707 dnl /* might introduce an intergenerational reference (a young pointer stored  */
    708 dnl /* in an old object) has to "memoize" that reference by setting a bit in  */
    709 dnl /* the global "refbits" bitmap. */
    710 dnl /* This has to happen atomically, and has to happen atomically wrt GC. */
    711 dnl /* Note that updating a word in a bitmap is itself not atomic, unless we use */
    712 dnl /* interlocked loads and stores. */
    713 dnl
    714 dnl
    715 dnl /* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
    716 dnl /* are in the function, we can do the store (even if it's already been done)  */
    717 dnl /* and calculate whether or not we need to set the bit out-of-line.  (Actually */
    718 dnl /* setting the bit needs to be done atomically, unless we're sure that other */
    719 dnl /* threads are suspended.) */
    720 dnl /* We can unconditionally set the suspended thread's PC to its LR. */
    721 dnl 
    722 dnl         .globl C(egc_write_barrier_start)
    723 dnl _spentry(rplaca)
    724 dnl C(egc_write_barrier_start):
    725 dnl         __(cmplr(cr2,arg_z,arg_y))
    726 dnl         __(_rplaca(arg_y,arg_z))
    727 dnl         __(blelr cr2)
    728 dnl         __(ref_global(imm2,ref_base))
    729 dnl         __(sub imm0,arg_y,imm2)
    730 dnl         __(load_highbit(imm3))
    731 dnl         __(srri(imm0,imm0,dnode_shift))       
    732 dnl         __(ref_global(imm1,oldspace_dnode_count))
    733 dnl         __(extract_bit_shift_count(imm4,imm0))
    734 dnl         __(cmplr(imm0,imm1))
    735 dnl         __(srr(imm3,imm3,imm4))
    736 dnl         __(srri(imm0,imm0,bitmap_shift))       
    737 dnl         __(ref_global(imm2,refbits))
    738 dnl         __(bgelr)
    739 dnl         __(slri(imm0,imm0,word_shift))
    740 dnl         __(ldr imm1,[imm2,imm0])
    741 dnl         __(and. imm1,imm1,imm3)
    742 dnl         __(bnelr)
    743 dnl 1:      __(lrarx(imm1,imm2,imm0))
    744 dnl         __(or imm1,imm1,imm3)
    745 dnl         __(strcx(imm1,imm2,imm0))
    746 dnl         __(bne- 1b)
    747 dnl         __(isync)
    748 dnl         __(bx lr)
    749 dnl
    750 dnl         .globl C(egc_rplacd)
    751 dnl _spentry(rplacd)
    752 dnl C(egc_rplacd):
    753 dnl         __(cmplr(cr2,arg_z,arg_y))
    754 dnl  __(_rplacd(arg_y,arg_z))
    755 dnl         __(blelr cr2)
    756 dnl         __(ref_global(imm2,ref_base))
    757 dnl         __(sub imm0,arg_y,imm2)
    758 dnl         __(load_highbit(imm3))
    759 dnl         __(srri(imm0,imm0,dnode_shift))       
    760 dnl         __(ref_global(imm1,oldspace_dnode_count))
    761 dnl         __(extract_bit_shift_count(imm4,imm0))
    762 dnl         __(cmplr(imm0,imm1))
    763 dnl         __(srr(imm3,imm3,imm4))
    764 dnl         __(srri(imm0,imm0,bitmap_shift))       
    765 dnl         __(ref_global(imm2,refbits))
    766 dnl         __(bgelr)
    767 dnl         __(slri(imm0,imm0,word_shift))
    768 dnl         __(ldr imm1,[imm2,imm0])
    769 dnl         __(and. imm1,imm1,imm3)
    770 dnl         __(bnelr)       
    771 dnl 1:      __(lrarx(imm1,imm2,imm0))
    772 dnl         __(or imm1,imm1,imm3)
    773 dnl         __(strcx(imm1,imm2,imm0))
    774 dnl         __(bne- 1b)
    775 dnl         __(isync)
    776 dnl         __(bx lr)
    777 dnl
     761
     762 
     763/* The function pc_luser_xp() - which is used to ensure that suspended threads */
     764/* are suspended in a GC-safe way - has to treat these subprims (which  */
     765/* implement the EGC write-barrier) specially.  Specifically, a store that */
     766/* might introduce an intergenerational reference (a young pointer stored  */
     767/* in an old object) has to "memoize" that reference by setting a bit in  */
     768/* the global "refbits" bitmap. */
     769/* This has to happen atomically, and has to happen atomically wrt GC. */
     770/* Note that updating a word in a bitmap is itself not atomic, unless we use */
     771/* interlocked loads and stores. */
     772
     773
     774/* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
     775/* are in the function, we can do the store (even if it's already been done)  */
     776/* and calculate whether or not we need to set the bit out-of-line.  (Actually */
     777/* setting the bit needs to be done atomically, unless we're sure that other */
     778/* threads are suspended.) */
     779/* We can unconditionally set the suspended thread's PC to its LR. */
     780
     781        .globl C(egc_write_barrier_start)
     782_spentry(rplaca)
     783C(egc_write_barrier_start):     
     784        __(cmp arg_z,arg_y)
     785        __(_rplaca(arg_y,arg_z))
     786        __(bxls lr)
     787        __(ref_global(temp0,ref_base))
     788        __(sub imm0,arg_y,temp0)
     789        __(mov imm0,imm0,lsr #dnode_shift)
     790        __(ref_global(temp0,oldspace_dnode_count))
     791        __(cmp imm0,temp0)
     792        __(bxhs lr)
     793        __(and imm2,imm0,#31)
     794        __(mov imm1,#0x80000000)
     795        __(mov imm1,imm1,lsr imm2)
     796        __(mov imm0,imm0,lsr #bitmap_shift)
     797        __(ref_global(imm2,refbits))
     798        __(add imm2,imm2,imm0,lsl #word_shift)
     799        __(ldr imm0,[imm2])
     800        __(ands imm0,imm0,imm1)
     801        __(bxne lr)
     802        __(build_lisp_frame(imm0))
     803        __(set_ref_bit(rplaca))
     804        __(bx lr)
     805
     806
     807        .globl C(egc_rplacd)
     808_spentry(rplacd)
     809C(egc_rplacd):
     810        __(cmp arg_z,arg_y)
     811        __(_rplacd(arg_y,arg_z))
     812        __(bxls lr)
     813        __(ref_global(temp0,ref_base))
     814        __(sub imm0,arg_y,temp0)
     815        __(mov imm0,imm0,lsr #dnode_shift)
     816        __(ref_global(temp0,oldspace_dnode_count))
     817        __(cmp imm0,temp0)
     818        __(bxhs lr)
     819        __(and imm2,imm0,#31)
     820        __(mov imm1,#0x80000000)
     821        __(mov imm1,imm1,lsr imm2)
     822        __(mov imm0,imm0,lsr #bitmap_shift)
     823        __(ref_global(imm2,refbits))
     824        __(add imm2,imm2,imm0,lsl #word_shift)
     825        __(ldr imm0,[imm2])
     826        __(ands imm0,imm0,imm1)
     827        __(bxne lr)
     828        __(build_lisp_frame(imm0))
     829        __(set_ref_bit(rplacd))
     830        __(bx lr)
     831       
     832
    778833/* Storing into a gvector can be handled the same way as storing into a CONS. */
    779834
     
    781836_spentry(gvset)
    782837C(egc_gvset):
    783 dnl         __(cmplr(cr2,arg_z,arg_x))
     838        __(cmp arg_z,arg_x)
    784839        __(add imm0,arg_y,#misc_data_offset)
    785840        __(str arg_z,[arg_x,imm0])
    786         __(bx lr)
    787 dnl         __(blelr cr2)
    788 dnl         __(add imm0,imm0,arg_x)
    789 dnl         __(ref_global(imm2,ref_base))
    790 dnl         __(load_highbit(imm3))
    791 dnl         __(ref_global(imm1,oldspace_dnode_count))
    792 dnl         __(sub imm0,imm0,imm2)
    793 dnl         __(srri(imm0,imm0,dnode_shift))       
    794 dnl         __(cmplr(imm0,imm1))
    795 dnl         __(extract_bit_shift_count(imm4,imm0))
    796 dnl         __(srri(imm0,imm0,bitmap_shift))       
    797 dnl         __(srr(imm3,imm3,imm4))
    798 dnl         __(ref_global(imm2,refbits))
    799 dnl         __(bgelr)
    800 dnl         __(slri(imm0,imm0,word_shift))
    801 dnl         __(ldrx(imm1,imm2,imm0))
    802 dnl         __(and. imm1,imm1,imm3)
    803 dnl         __(bnelr)       
    804 dnl 1:      __(lrarx(imm1,imm2,imm0))
    805 dnl         __(or imm1,imm1,imm3)
    806 dnl         __(strcx(imm1,imm2,imm0))
    807 dnl         __(bne- 1b)
    808 dnl         __(isync)
    809 dnl         __(bx lr)
    810 dnl
     841        __(bxls lr)
     842        __(add imm0,imm0,arg_x)
     843        __(ref_global(temp0,ref_base))
     844        __(sub imm0,imm0,temp0)
     845        __(mov imm0,imm0,lsr #dnode_shift)
     846        __(ref_global(temp0,oldspace_dnode_count))
     847        __(cmp imm0,temp0)
     848        __(bxhs lr)
     849        __(and imm2,imm0,#31)
     850        __(mov imm1,#0x80000000)
     851        __(mov imm1,imm1,lsr imm2)
     852        __(mov imm0,imm0,lsr #bitmap_shift)
     853        __(ref_global(imm2,refbits))
     854        __(add imm2,imm2,imm0,lsl #word_shift)
     855        __(ldr imm0,[imm2])
     856        __(ands imm0,imm0,imm1)
     857        __(bxne lr)
     858        __(build_lisp_frame(imm0))
     859        __(set_ref_bit(gvset))
     860        __(bx lr)
     861
     862       
    811863dnl /* This is a special case of storing into a gvector: if we need to memoize  */
    812864dnl /* the store, record the address of the hash-table vector in the refmap,  */
     
    9871039        __(mov imm0,temp2,lsl #num_subtag_bits-word_shift)
    9881040        __(orr imm0,imm0,#subtag_u32_vector)
    989         __(stack_allocate_zeroed_word_vector(imm0,temp2))
     1041        __(stack_allocate_zeroed_ivector(imm0,temp2))
    9901042        __(mov imm0,#subtag_simple_vector)
    9911043        __(strb imm0,[sp,#0])
     
    10141066        __(mov imm0,nargs,lsl #num_subtag_bits-fixnumshift)
    10151067        __(orr imm0,imm0,#subtag_u32_vector)
    1016         __(stack_allocate_zeroed_word_vector(imm0,imm1))
     1068        __(stack_allocate_zeroed_ivector(imm0,imm1))
    10171069        __(mov imm0,#subtag_simple_vector)
    10181070        __(strb imm0,[sp,#0])
     
    10431095dnl  /* but it's better to check now than to crash later. */
    10441096dnl 
    1045 dnl  __(cmpri(arg_z,nil_value))
     1097dnl  __(cmp arg_z,#nil_value)
    10461098dnl  __(mov arg_x,arg_z) /* fast  */
    10471099dnl  __(mov temp1,arg_z) /* slow  */
     
    10671119dnl  __(mov arg_x,arg_y)
    10681120dnl 1:
    1069 dnl  __(cmpri(cr0,arg_x,nil_value))
     1121dnl  __(cmp arg_x,#nil_value)
    10701122dnl  __(la imm0,node_size(imm0))
    10711123dnl  __(_cdr(arg_x,arg_x))
     
    10741126dnl  /* Determine word count, add 1 (to align), and make room.  */
    10751127dnl  /* if count is 0, make an empty tsp frame and exit  */
    1076 dnl  __(cmpri(cr0,imm0,0))
     1128dnl  __(cmp imm0,#0)
    10771129dnl  __(add imm1,imm0,imm0)
    10781130dnl  __(add imm1,imm1,imm0)
    10791131dnl         __(dnode_align(imm1,imm1,node_size))
    1080 dnl  __(bne+ cr0,2f)
     1132dnl  __(bne+ 2f)
    10811133dnl   __(TSP_Alloc_Fixed_Boxed(2*node_size))
    10821134dnl   __(bx lr)
     
    10971149dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer]) /* Need to reload after trap  */
    10981150dnl         __(ldrx(temp3,imm4,imm0))
    1099 dnl  __(cmpri(cr0,arg_x,nil_value))
     1151dnl  __(cmp arg_x,#nil_value)
    11001152dnl         __(mov temp2,#unbound_marker)
    11011153dnl         __(beq cr1,4f)
     
    11071159dnl         __(str temp2,imm4,imm0)
    11081160dnl  __(mov imm1,imm2)
    1109 dnl  __(bne cr0,3b)
     1161dnl  __(bne 3b)
    11101162dnl  __(str(imm2,tcr.db_link(rcontext)))
    11111163dnl  __(bx lr)
     
    11271179        __(mov imm0,#subtag_u32_vector)
    11281180        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
    1129         __(stack_allocate_zeroed_word_vector(imm0,imm1))
     1181        __(stack_allocate_zeroed_ivector(imm0,imm1))
    11301182        __(unbox_fixnum(imm0,arg_z))
    11311183        __(strb imm0,[sp])
     
    11511203        __(cmp imm1,#stack_alloc_limit)
    11521204        __(bhs 9f)
    1153         __(stack_allocate_zeroed_word_vector(imm0,imm1))
     1205        __(stack_allocate_zeroed_ivector(imm0,imm1))
    11541206        __(add arg_z,sp,#fulltag_misc)
    11551207        __(bx lr)
     
    12341286        __(bx lr)
    12351287
    1236 dnl /* Indicate whether &optional arguments were actually supplied.  nargs  */
    1237 dnl /* contains the actual arg count (minus the number of required args);  */
    1238 dnl /* imm0 contains the number of &optional args in the lambda list.  */
    1239 dnl /* Note that nargs may be > imm0 if &rest/&key is involved.  */
    1240 dnl _spentry(opt_supplied_p)
    1241 dnl  __(mov imm1,#0)
    1242 dnl 1:
    1243 dnl  /* (vpush (< imm1 nargs))  */
    1244 dnl   __(xor imm2,imm1,nargs)
    1245 dnl   __(srawi imm2,imm2,31)
    1246 dnl   __(or imm2,imm2,imm1)
    1247 dnl   __(addi imm1,imm1,#fixnumone)
    1248 dnl   __(cmpr(cr0,imm1,imm0))
    1249 dnl   __(subf imm2,nargs,imm2)
    1250 dnl   __(srwi imm2,imm2,31)
    1251 dnl   __(insrwi imm2,imm2,1,27)
    1252 dnl   __(addi imm2,imm2,nil_value)
    1253 dnl   __(vpush1(imm2))
    1254 dnl   __(bne cr0,1b)
    1255 dnl   __(bx lr)
    1256 dnl 
    1257 dnl
    1258 dnl
     1288/* Indicate whether &optional arguments were actually supplied.  nargs  */
     1289/* contains the actual arg count (minus the number of required args);  */
     1290/* imm0 contains the number of &optional args in the lambda list.  */
     1291/* Note that nargs may be > imm0 if &rest/&key is involved.  */
     1292_spentry(opt_supplied_p)
     1293        __(mov imm1,#0)
     1294        __(mov arg_x,#nil_value)
     1295        __(add arg_x,arg_x,#t_offset)       
     12961:     
     1297        /* (vpush (< imm1 nargs))  */
     1298        __(cmp imm1,nargs)
     1299        __(subeq imm1,imm1,#t_offset)
     1300        __(vpush1(imm1))
     1301        __(cmp imm1,imm0)
     1302        __(bne 1b)
     1303        __(bx lr)
     1304
    12591305/* Cons a list of length nargs  and vpush it.  */
    12601306/* Use this entry point to heap-cons a simple &rest arg.  */
     
    13041350        __(vpush1(arg_z))
    13051351        __(bx lr)
    1306 dnl
    1307 dnl 
     1352
     1353
    13081354dnl _spentry(simple_keywords)
    13091355dnl  __(mov imm0,#0)
     
    13451391dnl  /* So, the number of args pushed so far is the larger of nargs  */
    13461392dnl  /* and the (canonical) total of required/&optional args received.  */
    1347 dnl  __(cmpr(cr0,nargs,imm0))
     1393dnl  __(cmpr(nargs,imm0))
    13481394dnl  __(add arg_z,vsp,nargs)
    1349 dnl  __(bge+ cr0,1f)
     1395dnl  __(bge+ 1f)
    13501396dnl  __(add arg_z,vsp,imm0)
    13511397dnl 1:
     
    13581404dnl  /* If there aren't any such pairs, the first step is the last  */
    13591405dnl  /* step.  */
    1360 dnl  __(cmpri(cr0,imm3,0))
     1406dnl  __(cmp imm3,#0)
    13611407dnl  __(mov arg_z,#0)
    13621408dnl  __(sub imm1,nargs,imm0)
     
    13661412dnl 2:
    13671413dnl  __(addi arg_z,arg_z,fixnum_one)
    1368 dnl  __(cmplr(cr0,arg_z,imm3))
     1414dnl  __(cmplr(arg_z,imm3))
    13691415dnl  __(mov imm5,#nil_value)
    13701416dnl  __(vpush1(imm5))
    13711417dnl  __(vpush1(imm5))
    13721418dnl 3:
    1373 dnl  __(bne cr0,2b)
     1419dnl  __(bne 2b)
    13741420dnl  __(andi. arg_z,imm1,fixnum_one)
    13751421dnl  __(blelr cr1) /* no keyword/value pairs to consider.  */
    1376 dnl  __(bne cr0,odd_keywords)
     1422dnl  __(bne odd_keywords)
    13771423dnl  /* We have key/value pairs.  Move them to the top of the vstack,  */
    13781424dnl  /* then set the value/supplied-p vars to NIL.  */
     
    13931439dnl  __(mov imm4,#nil_value)
    13941440dnl  __(subi arg_z,arg_z,2<<fixnumshift)
    1395 dnl  __(cmplri(cr0,arg_z,0))
     1441dnl  __(cmplri(arg_z,0))
    13961442dnl  __(ldr arg_x,[varptr,#node_size*0])
    13971443dnl  __(ldr arg_y,[varptr,#node_size*1])
     
    14021448dnl  __(str(arg_y,node_size*1(valptr)))
    14031449dnl  __(la valptr,node_size*2(valptr))
    1404 dnl  __(bne cr0,4b)
     1450dnl  __(bne 4b)
    14051451dnl
    14061452dnl
     
    14161462dnl  __(mov imm4,valptr)
    14171463dnl 5:
    1418 dnl         __(cmpri(cr0,keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
     1464dnl         __(cmpri(keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
    14191465dnl  __(ldru(arg_z,-node_size(valptr)))
    14201466dnl  __(ldru(arg_y,-node_size(valptr)))
     
    14251471dnl  __(cmpr(cr7,valptr,limit))
    14261472dnl  __(bne cr6,6f)
    1427 dnl         __(bge cr0,6f) /* Already seen :allow-other-keys  */
     1473dnl         __(bge 6f) /* Already seen :allow-other-keys  */
    14281474dnl         __(ori keyword_flags,keyword_flags,16<<fixnumshift)
    14291475dnl  __(beq cr1,6f)
     
    14381484dnl  __(cmpr(cr1,imm0,imm3))
    14391485dnl  __(ldrx(arg_x,keyword_vector,imm1))
    1440 dnl  __(cmpr(cr0,arg_x,arg_z))
     1486dnl  __(cmpr(arg_x,arg_z))
    14411487dnl  __(addi imm1,imm1,fixnum_one)
    1442 dnl  __(bne cr0,8f)
     1488dnl  __(bne 8f)
    14431489dnl  __(add imm0,imm0,imm0)
    14441490dnl  __(sub imm0,varptr,imm0)
    14451491dnl  __(ldr arg_x,[imm0,#0])
    1446 dnl  __(cmpri(cr0,arg_x,nil_value))
     1492dnl  __(cmp arg_x,#nil_value)
    14471493dnl  __(mov arg_z,#t_value)
    1448 dnl  __(bne cr0,9f)
     1494dnl  __(bne 9f)
    14491495dnl  __(str(arg_y,node_size(imm0)))
    14501496dnl  __(str(arg_z,0(imm0)))
     
    14661512dnl  /* keyword/value pairs from the vstack.  */
    14671513dnl  __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift))
    1468 dnl  __(cmpri(cr0,imm0,2<<fixnumshift))
    1469 dnl  __(beq- cr0,badkeys)
     1514dnl  __(cmpri(imm0,2<<fixnumshift))
     1515dnl  __(beq- badkeys)
    14701516dnl  __(andi. imm2,keyword_flags,4<<fixnumshift)
    14711517dnl  __(bnelr cr0)
     
    15021548        __(jump_fname)
    15031549
    1504 dnl /* As in the heap-consed cases, only stack-cons the &rest arg  */
    1505 dnl _spentry(stack_rest_arg)
    1506 dnl  __(mov imm0,#0)
    1507 dnl  __(vpush_argregs())
    1508 dnl         __(b _SPstack_cons_rest_arg)
    1509 dnl
    1510 dnl 
    1511 dnl _spentry(req_stack_rest_arg)
    1512 dnl  __(vpush_argregs())
    1513 dnl         __(b _SPstack_cons_rest_arg)
    1514 dnl 
    1515 dnl _spentry(stack_cons_rest_arg)
    1516 dnl  __(sub imm1,nargs,imm0)
    1517 dnl  __(cmpri(cr0,imm1,0))
    1518 dnl  __(cmpri(cr1,imm1,(4096-dnode_size)/2))
    1519 dnl  __(mov arg_z,#nil_value)
    1520 dnl  __(ble cr0,2f)  /* always temp-push something.  */
    1521 dnl  __(bge cr1,3f)
    1522 dnl  __(add imm1,imm1,imm1)
    1523 dnl  __(dnode_align(imm2,imm1,tsp_frame.fixed_overhead))
    1524 dnl  __(TSP_Alloc_Var_Boxed(imm2,imm3))
    1525 dnl  __(la imm0,tsp_frame.data_offset+fulltag_cons(tsp))
    1526 dnl 1:
    1527 dnl  __(cmpri(cr0,imm1,cons.size)) /* last time through ?  */
    1528 dnl  __(subi imm1,imm1,cons.size)
    1529 dnl  __(vpop(arg_x))
    1530 dnl  __(_rplacd(imm0,arg_z))
    1531 dnl  __(_rplaca(imm0,arg_x))
    1532 dnl  __(mov arg_z,imm0)
    1533 dnl  __(la imm0,cons.size(imm0))
    1534 dnl  __(bne cr0,1b)
    1535 dnl  __(vpush1(arg_z))
    1536 dnl  __(bx lr)
    1537 dnl 2:
    1538 dnl  __(TSP_Alloc_Fixed_Unboxed(0))
    1539 dnl  __(vpush1(arg_z))
    1540 dnl  __(bx lr)
    1541 dnl 3:
    1542 dnl  __(TSP_Alloc_Fixed_Unboxed(0))
    1543 dnl  __(b _SPheap_cons_rest_arg)
    1544 dnl
     1550/* As in the heap-consed cases, only stack-cons the &rest arg  */
     1551_spentry(stack_rest_arg)
     1552        __(mov imm0,#0)
     1553        __(vpush_argregs())
     1554        __(b _SPstack_cons_rest_arg)
     1555
     1556_spentry(req_stack_rest_arg)
     1557        __(vpush_argregs())
     1558        __(b _SPstack_cons_rest_arg)
     1559
     1560_spentry(stack_cons_rest_arg)
     1561        __(sub imm1,nargs,imm0)
     1562        __(cmp imm1,#0)
     1563        __(mov arg_z,#nil_value)
     1564        __(ble 2f)  /* always temp-push something.  */
     1565        __(add imm1,imm1,imm1)
     1566        __(mov temp0,imm1)
     1567        __(add imm1,imm1,#node_size)
     1568        __(dnode_align(imm0,imm1,node_size))
     1569        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
     1570        __(orr imm1,imm1,#subtag_u32_vector)
     1571        __(cmp imm1,#stack_alloc_limit)
     1572        __(bge 3f)
     1573        __(stack_allocate_zeroed_ivector(imm1,imm0))
     1574        __(mov imm0,#subtag_simple_vector)
     1575        __(strb imm0,[sp])
     1576        __(add imm0,sp,#dnode_size+fulltag_cons)
     15771:
     1578        __(subs temp0,temp0,#fixnumone)
     1579        __(vpop1(arg_x))
     1580        __(_rplacd(imm0,arg_z))
     1581        __(_rplaca(imm0,arg_x))
     1582        __(mov arg_z,imm0)
     1583        __(add imm0,imm0,#cons.size)
     1584        __(bne 1b)
     1585        __(vpush1(arg_z))
     1586        __(bx lr)
     15872:
     1588        __(movc16(imm0,make_header(1,subtag_u32_vector)))
     1589        __(mov imm1,#0)
     1590        __(stmdb sp!,{imm0,imm1})
     1591        __(vpush1(arg_z))
     1592        __(bx lr)
     15933:
     1594        __(movc16(imm0,make_header(1,subtag_u32_vector)))
     1595        __(mov imm1,#0)
     1596        __(stmdb sp!,{imm0,imm1})
     1597        __(b _SPheap_cons_rest_arg)
     1598
    15451599       
    1546 dnl /* Prepend all but the first two (closure code, fn) and last two  */
    1547 dnl /* (function name, lfbits) elements of nfn to the "arglist".  */
    1548 dnl /* Doing things this way (the same way that 68K MCL does) lets  */
    1549 dnl /* functions which take "inherited arguments" work consistently  */
    1550 dnl /* even in cases where no closure object is created.  */
    1551 dnl _spentry(call_closure)       
    1552 dnl  __(cmpri(cr0,nargs,nargregs<<fixnumshift))
    1553 dnl  __(cmpri(cr1,nargs,fixnum_one))
    1554 dnl  __(vector_length(imm0,nfn,imm0))
    1555 dnl  __(subi imm0,imm0,4<<fixnumshift) /* imm0 = inherited arg count  */
    1556 dnl  __(mov imm1,#misc_data_offset+(2<<fixnumshift)) /* point to 1st arg  */
    1557 dnl  __(mov imm4,#nil_value)
    1558 dnl  __(ble+ cr0,local_label(no_insert))
    1559 dnl  /* Some arguments have already been vpushed.  Vpush imm0's worth  */
    1560 dnl  /* of NILs, copy those arguments that have already been vpushed from  */
    1561 dnl  /* the old TOS to the new, then insert all of the inerited args  */
    1562 dnl  /* and go to the function.  */
    1563 dnl  __(mov imm2,#0)
    1564 dnl local_label(push_nil_loop):
    1565 dnl  __(addi imm2,imm2,fixnum_one)
    1566 dnl  __(cmpr(cr2,imm2,imm0))
    1567 dnl  __(vpush1(imm4))
    1568 dnl  __(bne cr2,local_label(push_nil_loop))
    1569 dnl
    1570 dnl  __(mov imm3,vsp)
    1571 dnl  __(add imm4,vsp,imm0)
    1572 dnl  __(subi imm2,nargs,nargregs<<fixnumshift)
    1573 dnl local_label(copy_already_loop):
    1574 dnl  __(cmpri(cr2,imm2,fixnum_one))
    1575 dnl  __(subi imm2,imm2,fixnum_one)
    1576 dnl  __(ldr fname,[imm4,#0])
    1577 dnl  __(addi imm4,imm4,fixnum_one)
    1578 dnl  __(str(fname,0(imm3)))
    1579 dnl  __(addi imm3,imm3,fixnum_one)
    1580 dnl  __(bne cr2,local_label(copy_already_loop))
    1581 dnl
    1582 dnl local_label(insert_loop):
    1583 dnl  __(cmpri(cr2,imm0,fixnum_one))
    1584 dnl  __(ldrx(fname,nfn,imm1))
    1585 dnl  __(addi imm1,imm1,fixnum_one)
    1586 dnl  __(addi nargs,nargs,fixnum_one)
    1587 dnl  __(subi imm0,imm0,fixnum_one)
    1588 dnl  __(push(fname,imm4))
    1589 dnl  __(bne cr2,local_label(insert_loop))
    1590 dnl  __(b local_label(go))
    1591 dnl local_label(no_insert):
    1592 dnl  /* nargregs or fewer args were already vpushed.  */
    1593 dnl  /* if exactly nargregs, vpush remaining inherited vars.  */
    1594 dnl  __(add imm2,imm1,imm0)
    1595 dnl  __(bne cr0,local_label(set_regs))
    1596 dnl local_label(vpush_remaining):
    1597 dnl  __(cmpri(cr2,imm0,fixnum_one))
    1598 dnl  __(ldrx(fname,nfn,imm1))
    1599 dnl  __(addi imm1,imm1,fixnum_one)
    1600 dnl  __(vpush1(fname))
    1601 dnl  __(subi imm0,imm0,fixnum_one)
    1602 dnl  __(addi nargs,nargs,fixnum_one)
    1603 dnl  __(bne cr2,local_label(vpush_remaining))
    1604 dnl  __(b local_label(go))
    1605 dnl local_label(set_regs):
    1606 dnl  /* if nargs was > 1 (and we know that it was < 3), it must have  */
    1607 dnl  /* been 2.  Set arg_x, then vpush the remaining args.  */
    1608 dnl  __(ble cr1,local_label(set_y_z))
    1609 dnl local_label(set_arg_x):
    1610 dnl  __(subi imm0,imm0,fixnum_one)
    1611 dnl  __(cmpri(cr0,imm0,0))
    1612 dnl  __(subi imm2,imm2,fixnum_one)
    1613 dnl  __(ldrx(arg_x,nfn,imm2))
    1614 dnl  __(addi nargs,nargs,fixnum_one)
    1615 dnl  __(bne cr0,local_label(vpush_remaining))
    1616 dnl  __(b local_label(go))
    1617 dnl  /* Maybe set arg_y or arg_z, preceding args  */
    1618 dnl local_label(set_y_z):
    1619 dnl  __(bne cr1,local_label(set_arg_z))
    1620 dnl  /* Set arg_y, maybe arg_x, preceding args  */
    1621 dnl local_label(set_arg_y):
    1622 dnl  __(subi imm0,imm0,fixnum_one)
    1623 dnl  __(cmpri(cr0,imm0,0))
    1624 dnl  __(subi imm2,imm2,fixnum_one)
    1625 dnl  __(ldrx(arg_y,nfn,imm2))
    1626 dnl  __(addi nargs,nargs,fixnum_one)
    1627 dnl  __(bne cr0,local_label(set_arg_x))
    1628 dnl  __(b local_label(go))
    1629 dnl local_label(set_arg_z):
    1630 dnl  __(subi imm0,imm0,fixnum_one)
    1631 dnl  __(cmpri(cr0,imm0,0))
    1632 dnl  __(subi imm2,imm2,fixnum_one)
    1633 dnl  __(ldrx(arg_z,nfn,imm2))
    1634 dnl  __(addi nargs,nargs,fixnum_one)
    1635 dnl  __(bne cr0,local_label(set_arg_y))
    1636 dnl
    1637 dnl local_label(go):
    1638 dnl  __(vrefr(nfn,nfn,1))
    1639 dnl  __(ldr loc_pc,[nfn,#_function.codevector])
    1640 dnl  __(mtctr loc_pc)
    1641 dnl  __(bctr)
     1600/* Prepend all but the first three (entrypoint, closure code, fn) and last two  */
     1601/* (function name, lfbits) elements of nfn to the "arglist".  */
     1602/* functions which take "inherited arguments" work consistently  */
     1603/* even in cases where no closure object is created.  */
     1604_spentry(call_closure)       
     1605        __(cmp nargs,nargregs<<fixnumshift)
     1606        __(vector_length(imm0,nfn,imm0))
     1607        __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count  */
     1608        __(ble local_label(no_insert))
     1609        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
     1610        /* of NILs, copy those arguments that have already been vpushed from  */
     1611        /* the old TOS to the new, then insert all of the inerited args  */
     1612        /* and go to the function.  */
     1613        __(vpush_all_argregs())
     1614        __(mov arg_x,imm0)
     1615        __(mov arg_y,#nil_value)
     1616local_label(push_nil_loop):
     1617        __(subs arg_x,arg_x,#fixnumone)
     1618        __(vpush1(arg_y))
     1619        __(bne local_label(push_nil_loop))
     1620        __(add arg_y,vsp,imm0)
     1621        __(mov imm1,#0)
     1622local_label(copy_already_loop):
     1623        __(ldr arg_x,[vsp,imm1])
     1624        __(str arg_x,[arg_y,imm1])
     1625        __(add imm1,imm1,#fixnumone)
     1626        __(cmp imm1,imm0)
     1627        __(bne local_label(copy_already_loop))
     1628        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
     1629        __(add arg_y,vsp,nargs)
     1630        __(add arg_y,arg_y,imm0)
     1631local_label(insert_loop):
     1632        __(subs imm0,imm0,#fixnumone)
     1633        __(ldr fname,[nfn,imm1])
     1634        __(add imm1,imm1,#fixnumone)
     1635        __(add nargs,nargs,#fixnumone)
     1636        __(push1(fname,arg_y))
     1637        __(bne local_label(insert_loop))
     1638        __(vpop_all_argregs())
     1639        __(b local_label(go))
     1640local_label(no_insert):
     1641/* nargregs or fewer args were already vpushed.  */
     1642/* if exactly nargregs, vpush remaining inherited vars.  */
     1643        __(cmp nargs,#nargregs<<fixnumshift)
     1644        __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift))
     1645        __(bne local_label(set_regs))
     1646local_label(vpush_remaining):
     1647        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
     1648local_label(vpush_remaining_loop):             
     1649        __(ldr fname,[nfn,imm1])
     1650        __(add imm1,imm1,#fixnum_one)
     1651        __(vpush1(fname))
     1652        __(subs imm0,imm0,#fixnum_one)
     1653        __(add nargs,nargs,#fixnum_one)
     1654        __(bne  local_label(vpush_remaining_loop))
     1655        __(b local_label(go))
     1656local_label(set_regs):
     1657        /* if nargs was > 1 (and we know that it was < 3), it must have  */
     1658        /* been 2.  Set arg_x, then vpush the remaining args.  */
     1659        __(cmp nargs,#fixnumone)
     1660        __(ble local_label(set_y_z))
     1661local_label(set_arg_x):
     1662        __(subs imm0,imm0,#fixnum_one)
     1663        __(sub imm1,imm1,#fixnum_one)
     1664        __(ldr arg_x,[nfn,imm1])
     1665        __(add nargs,nargs,#fixnum_one)
     1666        __(bne local_label(vpush_remaining))
     1667        __(b local_label(go))
     1668        /* Maybe set arg_y or arg_z, preceding args  */
     1669local_label(set_y_z):
     1670        __(cmp nargs,#fixnumone)
     1671        __(bne local_label(set_arg_z))
     1672        /* Set arg_y, maybe arg_x, preceding args  */
     1673local_label(set_arg_y):
     1674        __(subs imm0,imm0,fixnum_one)
     1675        __(sub imm1,imm1,#fixnum_one)
     1676        __(ldr arg_y,[nfn,imm1])
     1677        __(add nargs,nargs,#fixnum_one)
     1678        __(bne local_label(set_arg_x))
     1679        __(b local_label(go))
     1680local_label(set_arg_z):
     1681        __(subs imm0,imm0,#fixnum_one)
     1682        __(sub imm1,imm1,#fixnum_one)
     1683        __(ldr arg_z,[nfn,imm1])
     1684        __(add nargs,nargs,#fixnum_one)
     1685        __(bne local_label(set_arg_y))
     1686 
     1687local_label(go):
     1688        __(vrefr(nfn,nfn,2))
     1689        __(ldr pc,[nfn,#_function.entrypoint])
    16421690
    16431691
     
    18281876        __(b C(misc_ref_common))
    18291877
    1830 _spentry(builtin_aref1)
    1831         __(extract_typecode(imm0,arg_y))
    1832         __(cmp imm0,#min_vector_subtag)
    1833         __(box_fixnum(arg_x,imm0))
    1834         __(bgt _SPsubtag_misc_ref)
    1835         __(jump_builtin(_builtin_aref1,2))
    1836 
    1837 dnl /* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
    1838 dnl /* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
    1839 dnl /* in arg_z on exit.  */
    1840 dnl _spentry(makestackblock)
    1841 dnl  __(unbox_fixnum(imm0,arg_z))
    1842 dnl         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
    1843 dnl  __(cmplri(cr0,imm0,tstack_alloc_limit))
    1844 dnl  __(bge cr0,1f)
    1845 dnl  __(TSP_Alloc_Var_Unboxed(imm0))
    1846 dnl  __(mov imm0,#macptr_header)
    1847 dnl  __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
    1848 dnl  __(str(imm0,tsp_frame.data_offset(tsp)))
    1849 dnl  __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    1850 dnl  __(str(imm1,macptr.address(arg_z)))
    1851 dnl   __(stfd fp_zero,macptr.domain(arg_z))
    1852 dnl  __(bx lr)
    1853 dnl
    1854 dnl         /* Too big. Heap cons a gcable macptr  */
    1855 dnl 1:
    1856 dnl  __(TSP_Alloc_Fixed_Unboxed(0))
    1857 dnl  __(set_nargs(1))
    1858 dnl  __(mov fname,#nrs.new_gcable_ptr)
    1859 dnl  __(jump_fname())
    1860 dnl
    1861 dnl /* As above, only set the block's contents to 0.  */
    1862 dnl _spentry(makestackblock0)
    1863 dnl  __(unbox_fixnum(imm0,arg_z))
    1864 dnl         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
    1865 dnl  __(cmplri(cr0,imm0,tstack_alloc_limit))
    1866 dnl  __(bge cr0,3f)
    1867 dnl  __(TSP_Alloc_Var_Unboxed(imm0))
    1868 dnl  __(Zero_TSP_Frame(imm0,imm1))
    1869 dnl  __(mov imm0,#macptr_header)
    1870 dnl  __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
    1871 dnl  __(str(imm0,tsp_frame.data_offset(tsp)))
    1872 dnl  __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    1873 dnl  __(str(imm1,macptr.address(arg_z))) /* makestackblock0 expects the address to be in imm1  */
    1874 dnl  __(stfd fp_zero,macptr.domain(arg_z))
    1875 dnl  __(bx lr)
    1876 dnl
    1877 dnl         /* Too big. Heap cons a gcable macptr  */
    1878 dnl 3:
    1879 dnl  __(TSP_Alloc_Fixed_Unboxed(0)) /* "raw" block to make the compiler happy  */
    1880 dnl
    1881 dnl  __(mov arg_y,arg_z) /* save block size  */
    1882 dnl  __(mov arg_z,#t_value) /* clear-p arg to %new-gcable-ptr  */
    1883 dnl  __(set_nargs(2))
    1884 dnl  __(mov fname,#nrs.new_gcable_ptr)
    1885 dnl  __(jump_fname())
     1878
     1879/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
     1880/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
     1881/* in arg_z on exit.  */
     1882_spentry(makestackblock)
     1883        __(unbox_fixnum(imm1,arg_z))
     1884        __(dnode_align(imm1,imm1,0))
     1885        __(add imm1,imm1,#macptr.size+node_size)
     1886        __(add imm0,imm1,#node_size)
     1887        __(mov imm1,imm1,lsl #num_subtag_bits)
     1888        __(orr imm1,imm1,#subtag_u8_vector)
     1889        __(cmp imm0,#stack_alloc_limit)
     1890        __(bhs 1f)
     1891        __(stack_allocate_ivector(imm1,imm0))
     1892        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
     1893        __(str imm1,[sp,#dnode_size])
     1894        __(mov imm0,#0)
     1895        __(str imm0,[sp,#dnode_size+macptr.type-fulltag_misc])
     1896        __(str imm0,[sp,#dnode_size+macptr.domain-fulltag_misc])
     1897        __(add imm0,sp,#macptr.size+dnode_size)
     1898        __(str imm0,[sp,#dnode_size+macptr.address-fulltag_misc])
     1899        __(add arg_z,sp,#dnode_size+fulltag_misc)
     1900        __(bx lr)
     1901
     1902        /* Too big. Heap cons a gcable macptr  */
     19031:
     1904        __(mov imm1,#subtag_u8_vector)
     1905        __(str imm1,[sp,#-dnode_size]!)
     1906        __(set_nargs(1))
     1907        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
     1908        __(jump_fname())
     1909
     1910/* As above, only set the block's contents to 0.  */
     1911_spentry(makestackblock0)
     1912        __(unbox_fixnum(imm1,arg_z))
     1913        __(dnode_align(imm1,imm1,0))
     1914        __(add imm1,imm1,#macptr.size+node_size)
     1915        __(add imm0,imm1,#node_size)
     1916        __(mov imm1,imm1,lsl #num_subtag_bits)
     1917        __(orr imm1,imm1,#subtag_u8_vector)
     1918        __(cmp imm0,#stack_alloc_limit)
     1919        __(bhs 1f)
     1920        __(stack_allocate_zeroed_ivector(imm1,imm0))
     1921        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
     1922        __(str imm1,[sp,#dnode_size])
     1923        __(add imm0,sp,#macptr.size+dnode_size)
     1924        __(str imm0,[sp,#dnode_size+macptr.address-fulltag_misc])
     1925        __(add arg_z,sp,#dnode_size+fulltag_misc)
     1926        __(bx lr)
     1927        /* Too big. Heap cons a gcable macptr  */
     19281:
     1929        __(mov imm1,#subtag_u8_vector)
     1930        __(str imm1,[sp,#-dnode_size]!)
     1931        __(mov arg_y,arg_z) /* save block size  */
     1932        __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr  */
     1933        __(add arg_z,arg_z,#t_offset)
     1934        __(set_nargs(2))
     1935        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
     1936        __(jump_fname())
    18861937
    18871938/* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
     
    18951946        __(cmp imm0,#stack_alloc_limit)
    18961947        __(bge 4f)
    1897         __(stack_allocate_zeroed_word_vector(imm1,imm0))
     1948        __(stack_allocate_zeroed_ivector(imm1,imm0))
    18981949        __(mov imm0,#subtag_simple_vector)
    18991950        __(strb imm0,[sp,#0])
     
    19261977        __(bx lr)
    19271978
    1928 dnl /* subtype (boxed) vpushed before initial values. (Had better be a  */
    1929 dnl /* node header subtag.) Nargs set to count of things vpushed.  */
    1930 dnl
    1931 dnl _spentry(stkgvector)
    1932 dnl  __(la imm0,-fixnum_one(nargs))
    1933 dnl  __(cmpri(cr1,imm0,0))
    1934 dnl  __(add imm1,vsp,nargs)
    1935 dnl  __(ldru(temp0,-node_size(imm1)))
    1936 dnl  __(slri(imm2,imm0,num_subtag_bits-fixnumshift))
    1937 dnl   __(rlwimi imm2,temp0,32-fixnumshift,32-num_subtag_bits,31)
    1938 dnl         __(dnode_align(imm0,imm0,node_size+tsp_frame.fixed_overhead))
    1939 dnl  __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
    1940 dnl  __(str(imm2,tsp_frame.data_offset(tsp)))
    1941 dnl  __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    1942 dnl  __(la imm3,misc_header_offset(arg_z))
    1943 dnl  __(mov imm0,#fixnum1)
    1944 dnl  __(b 2f)
    1945 dnl 1:
    1946 dnl  __(addi imm0,imm0,fixnum1)
    1947 dnl  __(cmpr(cr1,imm0,nargs))
    1948 dnl  __(ldru(temp0,-node_size(imm1)))
    1949 dnl  __(stru(temp0,node_size(imm3)))
    1950 dnl 2:
    1951 dnl  __(bne cr1,1b)
    1952 dnl  __(add vsp,vsp,nargs)
    1953 dnl  __(bx lr)
     1979/* subtype (boxed) vpushed before initial values. (Had better be a  */
     1980/* node header subtag.) Nargs set to count of things vpushed.  */
     1981
     1982_spentry(stkgvector)
     1983        __(sub imm0,nargs,#fixnumone)
     1984        __(ldr temp0,[vsp,imm0])
     1985        __(dnode_align(temp1,imm0,node_size))
     1986        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
     1987        __(orr imm1,imm1,#subtag_u32_vector)
     1988        __(stack_allocate_zeroed_ivector(imm1,temp1))
     1989        __(unbox_fixnum(imm1,temp0))
     1990        __(strb imm1,[sp])
     1991        __(add arg_z,sp,#fulltag_misc)
     1992        __(add imm0,sp,nargs)
     1993        __(b 2f)
     19941:
     1995        __(vpop1(temp0))
     1996        __(push1(temp0,imm0))
     19972:      __(subs nargs,nargs,#fixnumone)
     1998        __(bne 1b)
     1999        __(add vsp,vsp,#fixnumone)
     2000        __(bx lr)
    19542001
    19552002/* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
     
    19942041        __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
    19952042
    1996 dnl         
    1997 dnl
    1998 dnl /* Destructuring-bind, macro-bind.  */
    1999 dnl   
    2000 dnl /* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
    2001 dnl /* likewise immX regs.  */
    2002 dnl /* arg_z preserved, nothing else in particular defined on exit.  */
    2003 dnl /* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
    2004 dnl /* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
    2005 dnl /* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
    2006 dnl /* opt-supplied-p flag in PPC bit mask_initopt,  */
    2007 dnl /* keyp flag in PPC bit mask_keyp,  */
    2008 dnl /* &allow-other-keys flag in PPC bit mask_aok,  */
    2009 dnl /* &rest flag in PPC bit mask_restp.  */
    2010 dnl /* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
    2011 dnl /* length key count.  */
    2012 dnl
    2013 dnl _spentry(macro_bind)
    2014 dnl   __(mov whole_reg,arg_reg)
    2015 dnl   __(extract_lisptag(imm0,arg_reg))
    2016 dnl   __(cmpri(cr0,imm0,tag_list))
    2017 dnl   __(bne- cr0,1f)
    2018 dnl   __(_cdr(arg_reg,arg_reg))
    2019 dnl   __(b (local_label(destbind1)))
    2020 dnl 1:
    2021 dnl  __(mov arg_y,#XCALLNOMATCH)
    2022 dnl  __(mov arg_z,whole_reg)
    2023 dnl  __(set_nargs(2))
    2024 dnl  __(b _SPksignalerr)
    2025 dnl
    2026 dnl
    2027 dnl _spentry(destructuring_bind)
    2028 dnl  __(Mov whole_reg,arg_reg)
    2029 dnl         __(b local_label(destbind1))
    2030 dnl 
    2031 dnl _spentry(destructuring_bind_inner)
    2032 dnl  __(mov whole_reg,arg_z)
    2033 dnl local_label(destbind1):
    2034 dnl  /* Extract required arg count.  */
    2035 dnl  /* A bug in gas: can't handle shift count of "32" (= 0  */
    2036 dnl  ifelse(eval(mask_req_width+mask_req_start),eval(32),`
    2037 dnl  __(clrlwi. imm0,nargs,mask_req_start)
    2038 dnl  ',`
    2039 dnl  __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
    2040 dnl  ')
    2041 dnl  __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
    2042 dnl  __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
    2043 dnl  __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
    2044 dnl  __(cmpri(cr4,imm4,0))
    2045 dnl  __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
    2046 dnl  __(cmpri(cr5,imm4,0))
    2047 dnl  __(cmpri(cr1,imm1,0))
    2048 dnl  __(cmpri(cr2,imm2,0))
    2049 dnl  /* Save entry vsp in case of error.  */
    2050 dnl  __(mov imm4,vsp)
    2051 dnl  __(beq cr0,2f)
    2052 dnl 1:
    2053 dnl  __(cmpri(cr7,arg_reg,nil_value))
    2054 dnl   __(extract_lisptag(imm3,arg_reg))
    2055 dnl   __(cmpri(cr3,imm3,tag_list))
    2056 dnl  __(subi imm0,imm0,1)
    2057 dnl  __(cmpri(cr0,imm0,0))
    2058 dnl  __(beq cr7,toofew)
    2059 dnl  __(bne cr3,badlist)
    2060 dnl  __(ldr arg_x,[arg_reg,#cons.car])
    2061 dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
    2062 dnl  __(vpush1(arg_x))
    2063 dnl  __(bne cr0,1b)
    2064 dnl 2:
    2065 dnl  __(beq cr1,rest_keys)
    2066 dnl  __(bne cr2,opt_supp)
    2067 dnl  /* 'simple' &optionals:  no supplied-p, default to nil.  */
    2068 dnl simple_opt_loop:
    2069 dnl  __(cmpri(cr0,arg_reg,nil_value))
    2070 dnl   __(extract_lisptag(imm3,arg_reg))
    2071 dnl   __(cmpri(cr3,imm3,tag_list))
    2072 dnl  __(subi imm1,imm1,1)
    2073 dnl  __(cmpri(cr1,imm1,0))
    2074 dnl  __(mov imm5,#nil_value)
    2075 dnl  __(beq cr0,default_simple_opt)
    2076 dnl  __(bne cr3,badlist)
    2077 dnl  __(ldr arg_x,[arg_reg,#cons.car])
    2078 dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
    2079 dnl  __(vpush1(arg_x))
    2080 dnl  __(bne cr1,simple_opt_loop)
    2081 dnl  __(b rest_keys)
    2082 dnl default_simple_opt_loop:
    2083 dnl  __(subi imm1,imm1,1)
    2084 dnl  __(cmpri(cr1,imm1,0))
    2085 dnl default_simple_opt:
    2086 dnl  __(vpush1(imm5))
    2087 dnl  __(bne cr1,default_simple_opt_loop)
    2088 dnl  __(b rest_keys)
    2089 dnl  /* Provide supplied-p vars for the &optionals.  */
    2090 dnl opt_supp:
    2091 dnl  __(mov arg_y,#t_value)
    2092 dnl opt_supp_loop:
    2093 dnl  __(cmpri(cr0,arg_reg,nil_value))
    2094 dnl   __(extract_lisptag(imm3,arg_reg))
    2095 dnl   __(cmpri(cr3,imm3,tag_list))
    2096 dnl  __(subi imm1,imm1,1)
    2097 dnl  __(cmpri(cr1,imm1,0))
    2098 dnl  __(beq cr0,default_hard_opt)
    2099 dnl  __(bne cr3,badlist)
    2100 dnl  __(ldr arg_x,[arg_reg,#cons.car])
    2101 dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
    2102 dnl  __(vpush1(arg_x))
    2103 dnl  __(vpush1(arg_y))
    2104 dnl  __(bne cr1,opt_supp_loop)
    2105 dnl  __(b rest_keys)
    2106 dnl default_hard_opt_loop:
    2107 dnl  __(subi imm1,imm1,1)
    2108 dnl  __(cmpri(cr1,imm1,0))
    2109 dnl default_hard_opt:
    2110 dnl  __(vpush1(imm5))
    2111 dnl  __(vpush1(imm5))
    2112 dnl  __(bne cr1,default_hard_opt_loop)
    2113 dnl rest_keys:
    2114 dnl  __(cmpri(cr0,arg_reg,nil_value))
    2115 dnl  __(bne cr5,have_rest)
    2116 dnl  __(bne cr4,have_keys)
    2117 dnl  __(bne cr0,toomany)
    2118 dnl  __(bx lr)
    2119 dnl have_rest:
    2120 dnl  __(vpush1(arg_reg))
    2121 dnl  __(beqlr cr4)
    2122 dnl have_keys:
    2123 dnl  /* Ensure that arg_reg contains a proper,even-length list.  */
    2124 dnl  /* Insist that its length is <= 512 (as a cheap circularity check.)  */
    2125 dnl  __(mov imm0,#256)
    2126 dnl  __(mov arg_x,arg_reg)
    2127 dnl count_keys_loop:
    2128 dnl   __(extract_lisptag(imm3,arg_x))
    2129 dnl   __(cmpri(cr3,imm3,tag_list))
    2130 dnl  __(cmpri(cr0,arg_x,nil_value))
    2131 dnl  __(subi imm0,imm0,1)
    2132 dnl  __(cmpri(cr4,imm0,0))
    2133 dnl  __(beq cr0,counted_keys)
    2134 dnl  __(bne cr3,badlist)
    2135 dnl  __(ldr arg_x,[arg_x,#cons.cdr])
    2136 dnl   __(extract_lisptag(imm3,arg_x))
    2137 dnl   __(cmpri(cr3,imm3,tag_list))
    2138 dnl  __(blt cr4,toomany)
    2139 dnl  __(cmpri(cr0,arg_x,nil_value))
    2140 dnl  __(beq cr0,db_badkeys)
    2141 dnl  __(bne cr3,badlist)
    2142 dnl  __(ldr arg_x,[arg_x,#cons.cdr])
    2143 dnl  __(b count_keys_loop)
    2144 dnl counted_keys:
    2145 dnl  /* We've got a proper, even-length list of key/value pairs in */
    2146 dnl  /* arg_reg. For each keyword var in the lambda-list, push a pair */
    2147 dnl  /* of NILs on the vstack.  */
    2148 dnl  __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
    2149 dnl  __(mov imm2,imm0)  /* save number of keys  */
    2150 dnl  __(mov imm5,#nil_value)
    2151 dnl  __(b push_pair_test)
    2152 dnl push_pair_loop:
    2153 dnl  __(cmpri(cr0,imm0,1))
    2154 dnl  __(subi imm0,imm0,1)
    2155 dnl  __(vpush1(imm5))
    2156 dnl  __(vpush1(imm5))
    2157 dnl push_pair_test:
    2158 dnl  __(bne cr0,push_pair_loop)
    2159 dnl  __(slwi imm2,imm2,dnode_shift)  /* pairs -> bytes  */
    2160 dnl  __(add imm2,vsp,imm2)  /* imm2 points below pairs  */
    2161 dnl  __(mov imm0,#0)   /* count unknown keywords so far  */
    2162 dnl  __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
    2163 dnl  __(extrwi nargs,nargs,mask_key_width,mask_key_start)
    2164 dnl  /* Now, for each keyword/value pair in the list  */
    2165 dnl  /*  a) if the keyword is found in the keyword vector, set the  */
    2166 dnl  /*     corresponding entry on the vstack to the value and the  */
    2167 dnl  /*     associated supplied-p var to T.  */
    2168 dnl  /*  b) Regardless of whether or not the keyword is found,  */
    2169 dnl         /*     if :ALLOW-OTHER-KEYS is provided with a non-nil value, */
    2170 dnl  /*     set the low bit of imm1 to indicate that unknown keywords  */
    2171 dnl  /*     are acceptable. (This bit is pre-set above to the value */
    2172 dnl         /*     the encoded value of &allow_other_keys.) */
    2173 dnl  /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
    2174 dnl  /*     the count of unknown keywords in the high bits of imm1*/
    2175 dnl  /* At the end of the list, signal an error if any unknown keywords were seen  */
    2176 dnl  /* but not allowed.  Otherwise, return.  */
    2177 dnl
    2178 dnl match_keys_loop:
    2179 dnl  __(cmpri(cr0,arg_reg,nil_value))
    2180 dnl  __(mov imm0,#0)
    2181 dnl  __(mov imm3,#misc_data_offset)
    2182 dnl  __(beq cr0,matched_keys)
    2183 dnl  __(ldr arg_x,[arg_reg,#cons.car])
    2184 dnl  __(mov arg_y,#nrs.kallowotherkeys)
    2185 dnl  __(cmpr(cr3,arg_x,arg_y)) /* :ALLOW-OTHER-KEYS ?  */
    2186 dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
    2187 dnl  __(ldr arg_y,[arg_reg,#cons.car])
    2188 dnl  __(cmpr(cr4,imm0,nargs))
    2189 dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
    2190 dnl  __(b match_test)
    2191 dnl match_loop:
    2192 dnl  __(ldrx(temp0,keyvect_reg,imm3))
    2193 dnl  __(cmpr(cr0,arg_x,temp0))
    2194 dnl  __(addi imm0,imm0,1)
    2195 dnl  __(cmpr(cr4,imm0,nargs))
    2196 dnl  __(addi imm3,imm3,node_size)
    2197 dnl  __(bne cr0,match_test)
    2198 dnl  /* Got a hit.  Unless this keyword's been seen already, set it.  */
    2199 dnl  __(slwi imm0,imm0,dnode_shift)
    2200 dnl  __(subf imm0,imm0,imm2)
    2201 dnl  __(ldr temp0,[imm0,#0])
    2202 dnl  __(cmpri(cr0,temp0,nil_value))
    2203 dnl  __(mov temp0,#t_value)
    2204 dnl  __(bne cr0,match_keys_loop) /* already saw this  */
    2205 dnl  __(str(arg_y,node_size*1(imm0)))
    2206 dnl  __(str(temp0,node_size*0(imm0)))
    2207 dnl         __(bne cr3,match_keys_loop)
    2208 dnl  __(b match_keys_check_aok)
    2209 dnl match_test:
    2210 dnl  __(bne cr4,match_loop)
    2211 dnl         __(beq cr3,match_keys_check_aok)
    2212 dnl         __(addi imm1,imm1,node_size)
    2213 dnl         __(b match_keys_loop)
    2214 dnl match_keys_check_aok:
    2215 dnl         __(andi. imm0,imm1,2)  /* check "seen-aok" bit in imm1 */
    2216 dnl         __(cmpri cr1,arg_y,nil_value) /* check value */
    2217 dnl         __(ori imm1,imm1,2)
    2218 dnl         __(bne cr0,match_keys_loop) /* duplicate aok */
    2219 dnl         __(beq cr1,match_keys_loop)
    2220 dnl         __(ori imm1,imm1,1)
    2221 dnl  __(b match_keys_loop)
    2222 dnl matched_keys:
    2223 dnl         __(clrrwi. imm0,imm1,2)
    2224 dnl         __(beqlr)
    2225 dnl         __(andi. imm1,imm1,1)
    2226 dnl         __(bnelr)
    2227 dnl  /* Some unrecognized keywords.  Complain generically about  */
    2228 dnl  /* invalid keywords.  */
    2229 dnl db_badkeys:
    2230 dnl  __(mov arg_y,#XBADKEYS)
    2231 dnl  __(b destructure_error)
    2232 dnl toomany:
    2233 dnl  __(mov arg_y,#XCALLTOOMANY)
    2234 dnl  __(b destructure_error)
    2235 dnl toofew:
    2236 dnl  __(mov arg_y,#XCALLTOOFEW)
    2237 dnl  __(b destructure_error)
    2238 dnl badlist:
    2239 dnl  __(mov arg_y,#XCALLNOMATCH)
    2240 dnl  /* b destructure_error  */
    2241 dnl destructure_error:
    2242 dnl  __(mov vsp,imm4)  /* undo everything done to the stack  */
    2243 dnl  __(mov arg_z,whole_reg)
    2244 dnl  __(set_nargs(2))
    2245 dnl  __(b _SPksignalerr)
    2246 dnl         
     2043
     2044
     2045/* Destructuring-bind, macro-bind.  */
     2046   
     2047/* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
     2048/* likewise immX regs.  */
     2049/* arg_z preserved, nothing else in particular defined on exit.  */
     2050/* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
     2051/* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
     2052/* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
     2053/* opt-supplied-p flag in PPC bit mask_initopt,  */
     2054/* keyp flag in PPC bit mask_keyp,  */
     2055/* &allow-other-keys flag in PPC bit mask_aok,  */
     2056/* &rest flag in PPC bit mask_restp.  */
     2057/* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
     2058/* length key count.  */
     2059
     2060_spentry(macro_bind)
     2061        __(mov whole_reg,arg_reg)
     2062        __(extract_lisptag(imm0,arg_reg))
     2063        __(cmp imm0,#tag_list)
     2064        __(bne 1f)
     2065        __(_cdr(arg_reg,arg_reg))
     2066        __(b C(destbind1))
     20671:
     2068        __(mov arg_y,#XCALLNOMATCH)
     2069        __(mov arg_z,whole_reg)
     2070        __(set_nargs(2))
     2071        __(b _SPksignalerr)
     2072
     2073_spentry(destructuring_bind)
     2074        __(mov whole_reg,arg_reg)
     2075        __(b C(destbind1))
     2076
     2077_spentry(destructuring_bind_inner)
     2078        __(mov whole_reg,arg_z)
     2079        __(b C(destbind1))
     2080
    22472081dnl /* vpush the values in the value set atop the vsp, incrementing nargs.  */
    22482082dnl /* Discard the tsp frame; leave values atop the vsp.  */
     
    22572091dnl local_label(walkloop):
    22582092dnl  __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment  */
    2259 dnl  __(cmpr(cr0,imm0,imm3)) /* last segment?  */
     2093dnl  __(cmpr(imm0,imm3)) /* last segment?  */
    22602094dnl  __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
    22612095dnl  __(mov imm2,imm1) /* last segment <- current segment  */
    22622096dnl  __(mov imm1,imm3) /* current segment <- next segment  */
    2263 dnl  __(bne cr0,local_label(walkloop))
     2097dnl  __(bne local_label(walkloop))
    22642098dnl
    22652099dnl         /* the final segment ptr is now in imm2  */
     
    22672101dnl local_label(pushloop):
    22682102dnl  __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment  */
    2269 dnl  __(cmpri(cr0,imm0,0))
     2103dnl  __(cmpri(imm0,0))
    22702104dnl  __(cmpr(cr1,imm2,tsp))
    22712105dnl  __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
     
    22752109dnl 1:
    22762110dnl  __(ldru(arg_z,-node_size(imm3)))
    2277 dnl  __(cmpri(cr0,imm0,fixnum_one))
     2111dnl  __(cmpri(imm0,fixnum_one))
    22782112dnl  __(subi imm0,imm0,fixnum_one)
    22792113dnl  __(vpush1(arg_z))
    22802114dnl 2:
    2281 dnl  __(bne cr0,1b)
     2115dnl  __(bne 1b)
    22822116dnl  __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment  */
    22832117dnl  __(bne cr1,local_label(pushloop))
     
    23432177dnl  __(cmpri(cr4,imm0,2<<fixnumshift))
    23442178dnl  __(add imm1,arg_z,imm0)
    2345 dnl  __(cmpri(cr0,imm0,0))
     2179dnl  __(cmpri(imm0,0))
    23462180dnl  __(add nargs,nargs,imm0)
    23472181dnl  __(cmpri(cr1,nargs,0))
     
    23502184dnl  __(bge cr3,9f)
    23512185dnl  __(beq cr4,2f)
    2352 dnl  __(bne cr0,1f)
     2186dnl  __(bne 1f)
    23532187dnl  /* lexpr count was 0; vpop the arg regs that  */
    23542188dnl  /* were vpushed by the caller  */
     
    24102244dnl /* the difference between the current VSP and the target.  */
    24112245dnl _spentry(mvslide)
    2412 dnl  __(cmpri(cr0,nargs,0))
     2246dnl  __(cmpri(nargs,0))
    24132247dnl  __(mov imm3,nargs)
    24142248dnl  __(add imm2,vsp,nargs)
     
    24172251dnl  __(beq 2f)
    24182252dnl 1:
    2419 dnl  __(cmpri(cr0,imm3,1<<fixnumshift))
     2253dnl  __(cmpri(imm3,1<<fixnumshift))
    24202254dnl  __(subi imm3,imm3,1<<fixnumshift)
    24212255dnl  __(ldru(temp0,-node_size(imm0)))
    24222256dnl  __(stru(temp0,-node_size(imm2)))
    2423 dnl  __(bne cr0,1b)
     2257dnl  __(bne 1b)
    24242258dnl 2:
    24252259dnl  __(mov vsp,imm2)
     
    24572291dnl  __(add imm3,imm3,nargs)
    24582292dnl  __(add imm0,vsp,nargs)
    2459 dnl  __(cmpr(cr0,imm0,vsp))
     2293dnl  __(cmpr(imm0,vsp))
    24602294dnl  __(b 2f)
    24612295dnl 1:
    24622296dnl  __(ldru(arg_z,-node_size(imm0)))
    2463 dnl  __(cmpr(cr0,imm0,vsp))
     2297dnl  __(cmpr(imm0,vsp))
    24642298dnl  __(stru(arg_z,-node_size(imm3)))
    24652299dnl 2:
    2466 dnl  __(bne cr0,1b)
     2300dnl  __(bne 1b)
    24672301dnl  __(add vsp,vsp,nargs) /*  discard values  */
    24682302dnl  __(bx lr)
     
    24782312dnl
    24792313dnl _spentry(add_values)
    2480 dnl  __(cmpri(cr0,nargs,0))
     2314dnl  __(cmpri(nargs,0))
    24812315dnl  __(ldr imm1,[tsp,#0])
    2482 dnl  __(bne cr0,local_label(save_values_to_tsp))
     2316dnl  __(bne local_label(save_values_to_tsp))
    24832317dnl  __(bx lr)
    24842318dnl         
     
    25472381dnl  __(discard_lisp_frame())
    25482382dnl  __(bctr)
    2549 dnl
    2550 dnl _spentry(savecontextvsp)
    2551 dnl  __(ldr imm0,[rcontext,#tcr.cs_limit])
    2552 dnl  __(build_lisp_frame(fn,loc_pc,vsp))
    2553 dnl  __(mov fn,nfn)
    2554 dnl  __(trllt(sp,imm0))
    2555 dnl  __(bx lr)
    2556 dnl
    2557 dnl _spentry(savecontext0)
    2558 dnl  __(add imm0,vsp,imm0)
    2559 dnl  __(build_lisp_frame(fn,loc_pc,imm0))
    2560 dnl  __(ldr imm0,[rcontext,#tcr.cs_limit])
    2561 dnl  __(mov fn,nfn)
    2562 dnl  __(trllt(sp,imm0))
    2563 dnl  __(bx lr)
    2564 dnl
    2565 dnl
    2566 dnl /* Like .SPrestorefullcontext, only the saved return address  */
    2567 dnl /* winds up in loc-pc instead of getting thrashed around ...  */
    2568 dnl _spentry(restorecontext)
    2569 dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2570 dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
    2571 dnl  __(ldr fn,[sp,#lisp_frame.savefn])
    2572 dnl  __(discard_lisp_frame())
    2573 dnl  __(bx lr)
     2383dnl
     2384
    25742385dnl
    25752386dnl         
     
    25822393dnl _spentry(lexpr_entry)
    25832394dnl  __(ref_global(imm1,ret1val_addr))
    2584 dnl  __(cmpr(cr0,imm1,loc_pc))
     2395dnl  __(cmpr(imm1,loc_pc))
    25852396dnl  __(build_lisp_frame(fn,loc_pc,imm0))
    2586 dnl  __(bne cr0,1f)
     2397dnl  __(bne 1f)
    25872398dnl  __(ref_global(imm0,lexpr_return))
    25882399dnl  __(build_lisp_frame(rzero,imm0,vsp))
     
    26052416
    26062417
    2607 _spentry(builtin_div)
    2608         __(jump_builtin(_builtin_div,2))
    2609 
    2610 _spentry(builtin_eql)
    2611         __(cmp arg_y,arg_z)
    2612         __(beq 1f)
    2613         __(extract_fulltag(imm0,arg_y))
    2614         __(extract_fulltag(imm1,arg_z))
    2615         __(cmp imm0,imm1)
    2616         __(bne 2f)
    2617         __(cmp imm0,#fulltag_misc)
    2618         __(bne 2f)
    2619         __(jump_builtin(_builtin_eql,2))
    2620 1:      __(mov arg_z,#nil_value)
    2621         __(add arg_z,arg_z,#t_offset)
    2622         __(bx lr)
    2623 2:      __(mov arg_z,#nil_value)
    2624         __(bx lr)
    2625 dnl         
    2626 dnl _spentry(builtin_length)
    2627 dnl         __(cmpri(cr1,arg_z,nil_value))
    2628 dnl  __(extract_typecode(imm0,arg_z))
    2629 dnl  __(cmpri(cr0,imm0,min_vector_subtag))
    2630 dnl         __(beq cr1,1f)
    2631 dnl   __(cmpwi cr2,imm0,tag_list)
    2632 dnl  __(beq- cr0,2f)
    2633 dnl  __(blt- cr0,3f)
    2634 dnl  /* (simple-array * (*))  */
    2635 dnl  __(vector_length(arg_z,arg_z,imm0))
    2636 dnl  __(bx lr)
    2637 dnl 1:      __(mov arg_z,#0)
    2638 dnl         __(bx lr)
    2639 dnl 2:
    2640 dnl  __(ldr arg_z,[arg_z,#vectorH.logsize])
    2641 dnl  __(bx lr)       
    2642 dnl 3: __(bne cr2,8f)
    2643 dnl  __(mov temp2,#-1<<fixnum_shift)
    2644 dnl  __(mov temp0,arg_z) /* fast pointer  */
    2645 dnl  __(mov temp1,arg_z) /* slow pointer  */
    2646 dnl 4:  __(extract_lisptag(imm0,temp0))
    2647 dnl   __(cmpri(cr7,temp0,nil_value))
    2648 dnl   __(cmpri(cr1,imm0,tag_list))
    2649 dnl   __(addi temp2,temp2,fixnum_one)
    2650 dnl   __(beq cr7,9f)
    2651 dnl   __(andi. imm0,temp2,1<<fixnum_shift)
    2652 dnl   __(bne cr1,8f)
    2653 dnl   __(extract_lisptag(imm1,temp1))
    2654 dnl   __(_cdr(temp0,temp0))
    2655 dnl   __(cmpri(cr1,imm1,tag_list))
    2656 dnl   __(beq cr0,4b)
    2657 dnl   __(bne cr1,8f)
    2658 dnl   __(_cdr(temp1,temp1))
    2659 dnl   __(cmpr(cr0,temp0,temp1))
    2660 dnl   __(bne cr0,4b)
    2661 
    2662 dnl 8:
    2663 dnl  __(jump_builtin(_builtin_length,1))
    2664 dnl 9:
    2665 dnl  __(mov arg_z,temp2)
    2666 dnl  __(bx lr)
    2667 dnl         
    2668 dnl _spentry(builtin_seqtype)
    2669 dnl   __(extract_typecode(imm0,arg_z))
    2670 dnl    __(cmpri(cr0,imm0,tag_list))
    2671 dnl  __(cmpri(cr1,imm0,min_vector_subtag))
    2672 dnl  __(beq cr0,1f)
    2673 dnl  __(blt- cr1,2f)
    2674 dnl  __(mov arg_z,#nil_value)
    2675 dnl  __(bx lr)
    2676 dnl 1: __(mov arg_z,#t_value)
    2677 dnl  __(bx lr)
    2678 dnl 2:
    2679 dnl  __(jump_builtin(_builtin_seqtype,1))
    2680 
    2681 /* This is                 
    2682 _spentry(builtin_assq)
    2683         __(b 2f)
    2684 1:      __(trap_unless_list(arg_z,imm0))
    2685         __(_car(arg_x,arg_z))
    2686         __(_cdr(arg_z,arg_z))
    2687         __(cmp arg_x,#nil_value)
    2688         __(beq 2f)
    2689         __(trap_unless_list(arg_x,imm0))
    2690         __(_car(temp0,arg_x))
    2691         __(cmp temp0,arg_y)
    2692         __(bne 2f)
    2693         __(mov arg_z,arg_x)
    2694         __(bx lr)
    2695 2:      __(cmp arg_z,#nil_value)
    2696         __(bne 1b)
    2697         __(bx lr)
    2698  
    2699 _spentry(builtin_memq)
    2700         __(cmp arg_z,nil_value)
    2701         __(b 2f)
    2702 1:      __(trap_unless_list(arg_z,imm0))
    2703         __(_car(arg_x,arg_z))
    2704         __(_cdr(temp0,arg_z))
    2705         __(cmp arg_x,arg_y)
    2706         __(bxeq lr)
    2707         __(cmp temp0,nil_value)
    2708         __(mov arg_z,temp0)
    2709 2:      __(bne 1b)
    2710         __(bx lr)
     2418
     2419
    27112420 
    27122421                 
    2713 _spentry(builtin_logbitp)
    2714 /* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
    2715         __(test_two_fixnums(arg_y,arg_z,imm0))
    2716         __(bne 1f)
    2717         __(uuo_suspend_now(al))
    2718         __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
    2719         __(bhs 1f)
    2720         __(unbox_fixnum(imm0,arg_y))
    2721         __(mov imm1,#fixnum1)
    2722         __(tst arg_z,imm1,lsl imm0)
    2723         __(mov arg_z,#nil_value)
    2724         __(addne arg_z,arg_z,#t_offset)
    2725         __(bx lr)
    2726 1:
    2727         __(jump_builtin(_builtin_logbitp,2))
    2728 
    2729 _spentry(builtin_logior)
    2730         __(orr imm0,arg_y,arg_z)
    2731         __(test_fixnum(imm0))
    2732         __(moveq arg_z,imm0)
    2733         __(bxeq lr)
    2734         __(jump_builtin(_builtin_logior,2))
    2735 
    2736 _spentry(builtin_logand)
    2737         __(test_two_fixnums(arg_y,arg_z,imm0))
    2738         __(andeq arg_z,arg_y,arg_z)
    2739         __(bxeq lr)
    2740         __(jump_builtin(_builtin_logand,2))
    2741          
    2742 _spentry(builtin_ash)
    2743         __(test_two_fixnums(arg_y,arg_z,imm0))
    2744         __(bne 9f)
    2745         __(cmp arg_z,#0)
    2746         __(bgt 1f)
    2747         __(moveq arg_z,arg_y)
    2748         __(bxeq lr)
    2749         /* Shift right */
    2750         __(unbox_fixnum(imm2,arg_z))
    2751         __(rsb imm2,imm2,#0)
    2752         __(cmp imm2,#32)
    2753         __(movge imm2,#31)
    2754         __(mov arg_z,#-fixnumone)
    2755         __(and arg_z,arg_z,arg_y,lsr imm2)
    2756         __(bx lr)
    2757         /* shift left */
    2758 1:      __(unbox_fixnum(imm0,arg_y))
    2759         __(mov imm1,imm0,asr #31)
    2760         __(unbox_fixnum(imm2,arg_z))
    2761         __(cmp imm2,#32)
    2762         __(moveq imm1,imm0)
    2763         __(moveq imm0,#0)
    2764         __(beq _SPmakes64)
    2765         __(bgt 9f)
    2766         __(mov imm1,imm1,asl imm2)
    2767         __(rsb imm2,imm2,#32)
    2768         __(orr imm1,imm1,imm0,lsr imm2)
    2769         __(unbox_fixnum(imm2,arg_z))
    2770         __(mov imm0,imm0,asl imm2)
    2771         __(b _SPmake64)
    2772 9: 
    2773         __(jump_builtin(_builtin_ash,2))
    2774 
    2775 _spentry(builtin_negate)
    2776         __(test_fixnum(arg_z))
    2777         __(bne 1f)
    2778         __(rsbs arg_z,arg_z,#0)
    2779         __(bxvc lr)
    2780         __(b _SPfix_overflow)
    2781 1:
    2782         __(jump_builtin(_builtin_negate,1))
    2783 dnl
    2784 dnl _spentry(builtin_logxor)
    2785 dnl         __(extract_lisptag(imm0,arg_y))
    2786 dnl         __(extract_lisptag(imm1,arg_z))
    2787 dnl         __(ands imm0,imm0,imm1)
    2788 dnl  __(eoreq arg_z,arg_y,arg_z)
    2789 dnl  __(bxeq lr)
    2790 dnl  __(jump_builtin(_builtin_logxor,2))
    2791 dnl
    2792 dnl
    2793 dnl
    2794 dnl         
    2795 dnl _spentry(builtin_aset1)
    2796 dnl  __(extract_typecode(imm0,arg_x))
    2797 dnl  __(cmpri(cr0,imm0,min_vector_subtag))
    2798 dnl  __(box_fixnum(temp0,imm0))
    2799 dnl  __(bgt cr0,1f)
    2800 dnl  __(jump_builtin(_builtin_aset1,3))
    2801 dnl 1:
    2802 dnl  __(b _SPsubtag_misc_set)
    2803 dnl
    2804 dnl /* Enter the debugger  */
    2805 dnl _spentry(breakpoint)
    2806 dnl  __(mov r3,#0)
    2807 dnl  __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter)  */
    2808 dnl  __(bx lr)  /* if handler didn't  */
    2809 dnl
    2810 dnl /* */
    2811 dnl /* We're entered with an eabi_c_frame on the C stack.  There's a */
    2812 dnl /* lisp_frame reserved underneath it; we'll link it in in a minute. */
    2813 dnl /* Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
    2814 dnl /* then shrink the eabi_c_frame. */
    2815 dnl /*  */
    2816 dnl 
    2817 dnl _spentry(eabi_ff_call)
    2818 dnl  __(mflr loc_pc)
    2819 dnl  __(str(sp,eabi_c_frame.savelr(sp)))
    2820 dnl  __(vpush_saveregs())  /* Now we can use save0-save7 to point to stacks  */
    2821 dnl  __(mov save0,rcontext) /* or address globals.  */
    2822 dnl  __(extract_typecode(imm0,arg_z))
    2823 dnl  __(cmpri(imm0,subtag_macptr))
    2824 dnl  __(ldr save1,[sp,#0]) /* bottom of reserved lisp frame  */
    2825 dnl  __(la save2,-lisp_frame.size(save1)) /* top of lisp frame */
    2826 dnl         __(zero_doublewords save2,0,lisp_frame.size)
    2827 dnl  __(str(save1,lisp_frame.backlink(save2)))
    2828 dnl  __(str(save2,c_frame.backlink(sp)))
    2829 dnl  __(str(fn,lisp_frame.savefn(save2)))
    2830 dnl  __(str(loc_pc,lisp_frame.savelr(save2)))
    2831 dnl  __(str(vsp,lisp_frame.savevsp(save2)))
    2832 dnl  __(bne 1f)
    2833 dnl  __(ldr arg_z,[arg_z,#macptr.address])
    2834 dnl 1:
    2835 dnl  __(ldr save3,[rcontext,#tcr.cs_area])
    2836 dnl  __(str(save2,area.active(save3)))
    2837 dnl  __(str(allocptr,tcr.save_allocptr(rcontext)))
    2838 dnl  __(str(allocbase,tcr.save_allocbase(rcontext)))
    2839 dnl  __(str(tsp,tcr.save_tsp(rcontext)))
    2840 dnl  __(str(vsp,tcr.save_vsp(rcontext)))
    2841 dnl  __(mtctr arg_z)
    2842 dnl  __(str(rzero,tcr.ffi_exception(rcontext)))
    2843 dnl  __(mffs f0)
    2844 dnl  __(stfd f0,tcr.lisp_fpscr(rcontext)) /* remember lisp's fpscr  */
    2845 dnl  __(mtfsf 0xff,fp_zero) /* zero foreign fpscr  */
    2846 dnl  __(mov imm1,#TCR_STATE_FOREIGN)
    2847 dnl  __(str(imm1,tcr.valence(rcontext)))
    2848 dnl  __(ldr r2,[rcontext,#tcr.native_thread_info])
    2849 dnl  __(ldr r13,[0,#lisp_globals.saveR13])
    2850 dnl  __(ldr r3,[sp,#eabi_c_frame.param0])
    2851 dnl  __(ldr r4,[sp,#eabi_c_frame.param1])
    2852 dnl  __(ldr r5,[sp,#eabi_c_frame.param2])
    2853 dnl  __(ldr r6,[sp,#eabi_c_frame.param3])
    2854 dnl  __(ldr r7,[sp,#eabi_c_frame.param4])
    2855 dnl  __(ldr r8,[sp,#eabi_c_frame.param5])
    2856 dnl  __(ldr r9,[sp,#eabi_c_frame.param6])
    2857 dnl  __(ldr r10,[sp,#eabi_c_frame.param7])
    2858 dnl  __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
    2859 dnl  __(str(rzero,eabi_c_frame.savelr(save1)))
    2860 dnl  __(str(save2,eabi_c_frame.backlink(save1)))
    2861 dnl  __(mov sp,save1)
    2862 dnl  /* If we're calling a varargs C function, it'll want to */
    2863 dnl  /* know whether or not we've passed any args in FP regs. */
    2864 dnl  /* Better to say that we did (and force callee to save FP */
    2865 dnl  /* arg regs on entry) than to say that we didn't and get */
    2866 dnl  /* garbage results  */
    2867 dnl  __(crset 6)
    2868 dnl  __(bctrl)
    2869 dnl  /* C should have preserved save0 (= rcontext) for us.  */
    2870 dnl  __(ldr sp,[sp,#0])
    2871 dnl  __(mov imm2,save0)
    2872 dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
    2873 dnl  __(mov rzero,#0)
    2874 dnl  __(mov loc_pc,rzero)
    2875 dnl  __(mov arg_x,#nil_value)
    2876 dnl  __(mov arg_y,#nil_value)
    2877 dnl  __(mov arg_z,#nil_value)
    2878 dnl  __(mov temp0,#nil_value)
    2879 dnl  __(mov temp1,#nil_value)
    2880 dnl  __(mov temp2,#nil_value)
    2881 dnl  __(mov temp3,#nil_value)
    2882 dnl  __(mov fn,#nil_value)
    2883 dnl  __(mov rcontext,imm2)
    2884 dnl  __(mov imm2,#TCR_STATE_LISP)
    2885 dnl  __(ldr tsp,[rcontext,#tcr.save_tsp])
    2886 dnl         __(mov save0,#0)
    2887 dnl         __(mov save1,#0)
    2888 dnl         __(mov save2,#0)
    2889 dnl         __(mov save3,#0)
    2890 dnl         __(mov save4,#0)
    2891 dnl         __(mov save5,#0)
    2892 dnl         __(mov save6,#0)
    2893 dnl         __(mov save7,#0)
    2894 dnl         __(mov allocptr,#-dnode_size)
    2895 dnl         __(mov allocbase,#-dnode_size)
    2896 dnl  __(str(imm2,tcr.valence(rcontext)))
    2897 dnl  __(vpop_saveregs())
    2898 dnl  __(ldr allocptr,[rcontext,#tcr.save_allocptr])
    2899 dnl  __(ldr allocbase,[rcontext,#tcr.save_allocbase])
    2900 dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2901 dnl  __(mtlr loc_pc)
    2902 dnl  __(ldr fn,[sp,#lisp_frame.savefn])
    2903 dnl  __(mffs f0)
    2904 dnl  __(stfd f0,8(sp))
    2905 dnl  __(lwz imm3,12(sp)) /* imm3 = FPSCR after call  */
    2906 dnl         __(clrrwi imm2,imm3,8)
    2907 dnl  __(discard_lisp_frame())
    2908 dnl  __(str(imm2,tcr.ffi_exception(rcontext)))
    2909 dnl  __(lfd f0,tcr.lisp_fpscr(rcontext))
    2910 dnl  __(mtfsf 0xff,f0)
    2911 dnl  __(check_pending_interrupt(`cr1'))
    2912 dnl         __(mtxer rzero)
    2913 dnl         __(mtctr rzero)
    2914 dnl  __(bx lr)
    2915 
    2916 
     2422
     2423
     2424
     2425/* Enter the debugger  */
     2426_spentry(breakpoint)
     2427        __(mov r3,#0)
     2428        __(uuo_debug_trap(al))
     2429        __(bx lr)  /* if handler didn't  */
    29172430
    29182431
     
    30212534dnl  __(cmpri(cr1,arg_z,0))
    30222535dnl  __(ldr imm0,[rcontext,#tcr.interrupt_pending])
    3023 dnl  __(cmpri(cr0,imm0,0))
     2536dnl  __(cmpri(imm0,0))
    30242537dnl  __(bne cr1,1f)
    3025 dnl  __(beq cr0,1f)
     2538dnl  __(beq 1f)
    30262539dnl  __(str(rzero,tcr.interrupt_pending(rcontext)))
    30272540dnl  __(mov nargs,#fixnum_one)
     
    30342547
    30352548       
    3036 dnl /* Construct a lisp integer out of the 32-bit signed value in imm0 */
    3037 dnl /* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
     2549/* Construct a lisp integer out of the 32-bit signed value in imm0 */
     2550/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
    30382551
    30392552_spentry(gets32)
     
    30962609        __(jump_fname())
    30972610
    3098 dnl _spentry(unbind)
    3099 dnl         __(ldr imm1,[rcontext,#tcr.db_link])
    3100 dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])   
    3101 dnl         __(ldr imm3,[imm1,#binding.sym])
    3102 dnl         __(ldr temp1,[imm1,#binding.val])
    3103 dnl         __(ldr imm1,[imm1,#binding.link])
    3104 dnl         __(str temp1,imm2,imm3)
    3105 dnl         __(str(imm1,tcr.db_link(rcontext)))
    3106 dnl         __(bx lr)
    3107 dnl
    3108 dnl _spentry(unbind_n)
    3109 dnl         __(ldr imm1,[rcontext,#tcr.db_link])
    3110 dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])   
    3111 dnl 1:      __(subi imm0,imm0,1)
    3112 dnl         __(ldr imm3,[imm1,#binding.sym])
    3113 dnl         __(ldr temp1,[imm1,#binding.val])
    3114 dnl         __(cmpri(imm0,0))
    3115 dnl         __(ldr imm1,[imm1,#binding.link])
    3116 dnl         __(str temp1,imm2,imm3)
    3117 dnl         __(bne 1b)
    3118 dnl         __(str(imm1,tcr.db_link(rcontext)))
    3119 dnl         __(bx lr)
    3120 dnl
    3121 dnl /* */
    3122 dnl /* Clobbers imm1,imm2,imm5,arg_x, arg_y */
    3123 dnl
    3124 dnl _spentry(unbind_to)
    3125 dnl         __(ldr imm1,[rcontext,#tcr.db_link])
    3126 dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
    3127 dnl 1:      __(ldr imm5,[imm1,#binding.sym])
    3128 dnl         __(ldr arg_y,[imm1,#binding.val])
    3129 dnl         __(ldr imm1,[imm1,#binding.link])
    3130 dnl         __(cmpr(imm0,imm1))
    3131 dnl         __(str arg_y,imm2,imm5)
    3132 dnl         __(bne 1b)
    3133 dnl         __(str(imm1,tcr.db_link(rcontext)))
    3134 dnl         __(bx lr)
    3135 dnl 
    3136 dnl
    3137 dnl
    3138 dnl /* */
    3139 dnl /* Restore the special bindings from the top of the tstack,  */
    3140 dnl /* leaving the tstack frame allocated.  */
    3141 dnl /* Note that there might be 0 saved bindings, in which case  */
    3142 dnl /* do nothing.  */
    3143 dnl /* Note also that this is -only- called from an unwind-protect  */
    3144 dnl /* cleanup form, and that .SPnthrowXXX is keeping one or more  */
    3145 dnl /* values in a frame on top of the tstack.  */
    3146 dnl /*  */
    3147 dnl                         
    3148 dnl _spentry(progvrestore)
    3149 dnl  __(ldr imm0,[tsp,#tsp_frame.backlink]) /* ignore .SPnthrowXXX values frame  */
    3150 dnl  __(ldr imm0,[imm0,#tsp_frame.data_offset])
    3151 dnl  __(cmpri(cr0,imm0,0))
    3152 dnl  __(unbox_fixnum(imm0,imm0))
    3153 dnl  __(bne+ cr0,_SPunbind_n)
    3154 dnl  __(bx lr)
    3155 dnl
    3156  /* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
     2611_spentry(unbind)
     2612        __(ldr imm1,[rcontext,#tcr.db_link])
     2613        __(ldr temp0,[rcontext,#tcr.tlb_pointer])   
     2614        __(ldr imm0,[imm1,#binding.sym])
     2615        __(ldr temp1,[imm1,#binding.val])
     2616        __(ldr imm1,[imm1,#binding.link])
     2617        __(str temp1,[temp0,imm0])
     2618        __(str imm1,[rcontext,#tcr.db_link])
     2619        __(bx lr)
     2620
     2621/* Clobbers imm1,temp0,arg_x, arg_y */       
     2622_spentry(unbind_n)
     2623        __(ldr imm1,[rcontext,#tcr.db_link])
     2624        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
     26251:      __(ldr temp0,[imm1,#binding.sym])
     2626        __(ldr arg_y,[imm1,#binding.val])
     2627        __(ldr imm1,[imm1,#binding.link])
     2628        __(subs imm0,imm0,#1)
     2629        __(str arg_y,[arg_x,temp0])
     2630        __(bne 1b)
     2631        __(str imm1,[rcontext,#tcr.db_link])
     2632        __(bx lr)
     2633
     2634/* */
     2635/* Clobbers imm1,temp0,arg_x, arg_y */
     2636
     2637_spentry(unbind_to)
     2638        do_unbind_to(imm1,temp1,arg_x,arg_y)
     2639        __(bx lr)
     2640 
     2641
     2642 
     2643/* */
     2644/* Restore the special bindings from the top of the tstack,  */
     2645/* leaving the tstack frame allocated.  */
     2646/* Note that there might be 0 saved bindings, in which case  */
     2647/* do nothing.  */
     2648/* Note also that this is -only- called from an unwind-protect  */
     2649/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
     2650/* values in a frame on top of the tstack.  */
     2651/*  */
     2652                         
     2653_spentry(progvrestore)
     2654        __(skip_stack_vector(imm0,imm1,sp))
     2655        /* There might be a lisp_frame at imm0.  Not sure */
     2656        __(ldr imm0,[imm0,#node_size]) /* or maybe node_size+lisp_frame.size */
     2657        __(cmp imm0,#0)
     2658        __(unbox_fixnum(imm0,imm0))
     2659        __(bne _SPunbind_n)
     2660        __(bx lr)
     2661
     2662/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
    31572663/* for pending interrupts after doing so.  */
    31582664_spentry(bind_interrupt_level_0)
     
    33142820
    33152821
    3316 dnl /* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
    3317 dnl _spentry(aset2)
    3318 dnl         __(extract_typecode(imm2,temp0))
    3319 dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
    3320 dnl         __(cmpri(cr2,imm2,subtag_arrayH))
    3321 dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    3322 dnl         __(bne cr2,1f)
    3323 dnl         __(ldr imm1,[temp0,#arrayH.rank])
    3324 dnl         __(cmpri(imm1,2<<fixnumshift))
    3325 dnl         __(bne 1f)
    3326 dnl         /* It's a 2-dimensional array.  Check bounds */
    3327 dnl         __(ldr imm0,[temp0,#arrayH.dim0])
    3328 dnl         __(trlge(arg_x,imm0))
    3329 dnl         __(ldr imm0,[temp0,#arrayH.dim0+node_size])
    3330 dnl         __(trlge(arg_y,imm0))
    3331 dnl         __(unbox_fixnum(imm0,imm0))
    3332 dnl         __(mullr(arg_x,arg_x,imm0))
    3333 dnl         __(add arg_y,arg_y,arg_x)
    3334 dnl         /* arg_y is now row-major-index; get data vector and
    3335 dnl            add in possible offset */
    3336 dnl         __(mov arg_x,temp0)
    3337 dnl 0:      __(ldr imm0,[arg_x,#arrayH.displacement])
    3338 dnl         __(ldr arg_x,[arg_x,#arrayH.data_vector])
    3339 dnl         __(extract_subtag(imm1,arg_x))
    3340 dnl         __(cmpri(imm1,subtag_vectorH))
    3341 dnl         __(add arg_y,arg_y,imm0)
    3342 dnl         __(bgt C(misc_set_common))
    3343 dnl         __(b 0b)
    3344 dnl 1:             
    3345 dnl         __(uuo_interr(error_object_not_array_2d,temp0))       
    3346 dnl                 
    3347 dnl /* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
    3348 dnl _spentry(aset3)
    3349 dnl         __(extract_typecode(imm2,temp1))
    3350 dnl         __(trap_unless_lisptag_equal(temp0,tag_fixnum,imm0))
    3351 dnl         __(cmpri(cr2,imm2,subtag_arrayH))
    3352 dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
    3353 dnl         __(bne cr2,1f)
    3354 dnl         __(ldr imm1,[temp1,#arrayH.rank])
    3355 dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    3356 dnl         __(cmpri(imm1,3<<fixnumshift))
    3357 dnl         __(bne 1f)
    3358 dnl         /* It's a 3-dimensional array.  Check bounds */
    3359 dnl         __(ldr imm2,arrayH.dim0+(node_size*2)(temp1)))
    3360 dnl         __(ldr imm1,[temp1,#arrayH.dim0+node_size])
    3361 dnl         __(ldr imm0,[temp1,#arrayH.dim0])
    3362 dnl         __(trlge(arg_y,imm2))
    3363 dnl         __(unbox_fixnum(imm2,imm2))
    3364 dnl         __(trlge(arg_x,imm1))
    3365 dnl         __(unbox_fixnum(imm1,imm1))
    3366 dnl         __(trlge(temp0,imm0))
    3367 dnl         __(mullr(arg_x,arg_x,imm2))
    3368 dnl         __(mullr(imm1,imm2,imm1))
    3369 dnl         __(mullr(temp0,imm1,temp0))
    3370 dnl         __(add arg_y,arg_y,arg_x)
    3371 dnl         __(add arg_y,arg_y,temp0)
    3372 dnl         __(mov arg_x,temp1)
    3373 dnl 0:      __(ldr temp0,[arg_x,#arrayH.displacement])
    3374 dnl         __(ldr arg_x,[arg_x,#arrayH.data_vector])
    3375 dnl         __(extract_subtag(imm1,arg_x))
    3376 dnl         __(cmpri(imm1,subtag_vectorH))
    3377 dnl         __(add arg_y,arg_y,temp0)
    3378 dnl         __(bgt C(misc_set_common))
    3379 dnl         __(b 0b)
    3380 dnl 1:             
    3381 dnl         __(uuo_interr(error_object_not_array_3d,temp1))
    3382 dnl
    3383 dnl
    3384 dnl         
    3385 dnl
     2822/* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
     2823_spentry(aset2)
     2824        __(extract_typecode(imm0,temp0))
     2825        __(cmp imm0,#subtag_arrayH)
     2826        __(ldreq imm0,[temp0,#arrayH.rank])
     2827        __(cmpeq imm0,#2<<fixnumshift)
     2828        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array2d))
     2829        __(trap_unless_fixnum(arg_x))
     2830        __(trap_unless_fixnum(arg_y))
     2831        /* It's a 2-dimensional array.  Check bounds */
     2832        __(ldr imm0,[temp0,#arrayH.dim0])
     2833        __(cmp arg_x,imm0)
     2834        __(uuo_error_array_bounds(hs,arg_x,temp0))
     2835        __(ldr imm0,[temp0,#arrayH.dim0+node_size])
     2836        __(cmp arg_y,imm0)
     2837        __(uuo_error_array_bounds(hs,arg_y,temp0))
     2838        __(unbox_fixnum(imm0,imm0))
     2839        __(mul temp1,arg_x,imm0)
     2840        __(add arg_y,arg_y,temp1)
     2841        /* arg_y is now row-major-index; get data vector and
     2842           add in possible offset */
     2843        __(mov arg_x,temp0)
     28440:      __(ldr imm0,[arg_x,#arrayH.displacement])
     2845        __(ldr arg_x,[arg_x,#arrayH.data_vector])
     2846        __(extract_subtag(imm1,arg_x))
     2847        __(cmp imm1,#subtag_vectorH)
     2848        __(add arg_y,arg_y,imm0)
     2849        __(bgt C(misc_set_common))
     2850        __(b 0b)
     2851
     2852                 
     2853/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
     2854_spentry(aset3)
     2855        __(extract_typecode(imm0,temp1))
     2856        __(cmp imm0,#subtag_arrayH)
     2857        __(ldreq imm0,[temp1,#arrayH.rank])
     2858        __(cmpeq imm0,#3<<fixnumshift)
     2859        __(uuo_error_reg_not_xtype(ne,temp1,xtype_array3d))
     2860        __(trap_unless_fixnum(temp0))
     2861        __(trap_unless_fixnum(arg_x))
     2862        __(trap_unless_fixnum(arg_y))
     2863        /* It's a 3-dimensional array.  Check bounds */
     2864        __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)])
     2865        __(ldr imm1,[temp1,#arrayH.dim0+node_size])
     2866        __(ldr imm0,[temp1,#arrayH.dim0])
     2867        __(cmp arg_y,imm2)
     2868        __(uuo_error_array_bounds(hs,arg_y,temp1))
     2869        __(cmp arg_x,imm1)
     2870        __(uuo_error_array_bounds(hs,arg_x,temp1))
     2871        __(unbox_fixnum(imm1,imm1))
     2872        __(cmp temp0,imm0)
     2873        __(uuo_error_array_bounds(hs,temp0,temp1))
     2874        __(mul arg_x,imm2,arg_x)
     2875        __(mul imm1,imm2,imm1)
     2876        __(mul temp0,imm1,temp0)
     2877        __(add arg_y,arg_y,arg_x)
     2878        __(add arg_y,arg_y,temp0)
     2879        __(mov arg_x,temp1)
     28800:      __(ldr temp0,[arg_x,#arrayH.displacement])
     2881        __(ldr arg_x,[arg_x,#arrayH.data_vector])
     2882        __(extract_subtag(imm1,arg_x))
     2883        __(cmp imm1,#subtag_vectorH)
     2884        __(add arg_y,arg_y,temp0)
     2885        __(bgt C(misc_set_common))
     2886        __(b 0b)
     2887
     2888
    33862889_spentry(nmkunwind)
    33872890        __(mov imm2,#-fixnumone)
     
    41993702        __(mov imm2,arg_y,lsl #1)
    42003703        __(add imm2,imm2,#misc_dfloat_offset)
    4201         __(strd imm0,imm1,[arg_z,imm2])
     3704        __(strd imm0,imm1,[arg_x,imm2])
    42023705        __(bx lr)
    42033706local_label(misc_set_invalid): 
     
    42073710        __(b _SPksignalerr)               
    42083711
     3712C(destbind1):
     3713dnl  /* Extract required arg count.  */
     3714dnl  /* A bug in gas: can't handle shift count of "32" (= 0  */
     3715dnl  ifelse(eval(mask_req_width+mask_req_start),eval(32),`
     3716dnl  __(clrlwi. imm0,nargs,mask_req_start)
     3717dnl  ',`
     3718dnl  __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
     3719dnl  ')
     3720dnl  __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
     3721dnl  __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
     3722dnl  __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
     3723dnl  __(cmpri(cr4,imm4,0))
     3724dnl  __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
     3725dnl  __(cmpri(cr5,imm4,0))
     3726dnl  __(cmpri(cr1,imm1,0))
     3727dnl  __(cmpri(cr2,imm2,0))
     3728dnl  /* Save entry vsp in case of error.  */
     3729dnl  __(mov imm4,vsp)
     3730dnl  __(beq 2f)
     3731dnl 1:
     3732dnl  __(cmpri(cr7,arg_reg,nil_value))
     3733dnl   __(extract_lisptag(imm3,arg_reg))
     3734dnl   __(cmpri(cr3,imm3,tag_list))
     3735dnl  __(subi imm0,imm0,1)
     3736dnl  __(cmpri(imm0,0))
     3737dnl  __(beq cr7,toofew)
     3738dnl  __(bne cr3,badlist)
     3739dnl  __(ldr arg_x,[arg_reg,#cons.car])
     3740dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
     3741dnl  __(vpush1(arg_x))
     3742dnl  __(bne 1b)
     3743dnl 2:
     3744dnl  __(beq cr1,rest_keys)
     3745dnl  __(bne cr2,opt_supp)
     3746dnl  /* 'simple' &optionals:  no supplied-p, default to nil.  */
     3747dnl simple_opt_loop:
     3748dnl  __(cmpri(arg_reg,nil_value))
     3749dnl   __(extract_lisptag(imm3,arg_reg))
     3750dnl   __(cmpri(cr3,imm3,tag_list))
     3751dnl  __(subi imm1,imm1,1)
     3752dnl  __(cmpri(cr1,imm1,0))
     3753dnl  __(mov imm5,#nil_value)
     3754dnl  __(beq default_simple_opt)
     3755dnl  __(bne cr3,badlist)
     3756dnl  __(ldr arg_x,[arg_reg,#cons.car])
     3757dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
     3758dnl  __(vpush1(arg_x))
     3759dnl  __(bne cr1,simple_opt_loop)
     3760dnl  __(b rest_keys)
     3761dnl default_simple_opt_loop:
     3762dnl  __(subi imm1,imm1,1)
     3763dnl  __(cmpri(cr1,imm1,0))
     3764dnl default_simple_opt:
     3765dnl  __(vpush1(imm5))
     3766dnl  __(bne cr1,default_simple_opt_loop)
     3767dnl  __(b rest_keys)
     3768dnl  /* Provide supplied-p vars for the &optionals.  */
     3769dnl opt_supp:
     3770dnl  __(mov arg_y,#t_value)
     3771dnl opt_supp_loop:
     3772dnl  __(cmpri(arg_reg,nil_value))
     3773dnl   __(extract_lisptag(imm3,arg_reg))
     3774dnl   __(cmpri(cr3,imm3,tag_list))
     3775dnl  __(subi imm1,imm1,1)
     3776dnl  __(cmpri(cr1,imm1,0))
     3777dnl  __(beq default_hard_opt)
     3778dnl  __(bne cr3,badlist)
     3779dnl  __(ldr arg_x,[arg_reg,#cons.car])
     3780dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
     3781dnl  __(vpush1(arg_x))
     3782dnl  __(vpush1(arg_y))
     3783dnl  __(bne cr1,opt_supp_loop)
     3784dnl  __(b rest_keys)
     3785dnl default_hard_opt_loop:
     3786dnl  __(subi imm1,imm1,1)
     3787dnl  __(cmpri(cr1,imm1,0))
     3788dnl default_hard_opt:
     3789dnl  __(vpush1(imm5))
     3790dnl  __(vpush1(imm5))
     3791dnl  __(bne cr1,default_hard_opt_loop)
     3792dnl rest_keys:
     3793dnl  __(cmpri(arg_reg,nil_value))
     3794dnl  __(bne cr5,have_rest)
     3795dnl  __(bne cr4,have_keys)
     3796dnl  __(bne toomany)
     3797dnl  __(bx lr)
     3798dnl have_rest:
     3799dnl  __(vpush1(arg_reg))
     3800dnl  __(beqlr cr4)
     3801dnl have_keys:
     3802dnl  /* Ensure that arg_reg contains a proper,even-length list.  */
     3803dnl  /* Insist that its length is <= 512 (as a cheap circularity check.)  */
     3804dnl  __(mov imm0,#256)
     3805dnl  __(mov arg_x,arg_reg)
     3806dnl count_keys_loop:
     3807dnl   __(extract_lisptag(imm3,arg_x))
     3808dnl   __(cmpri(cr3,imm3,tag_list))
     3809dnl  __(cmpri(arg_x,nil_value))
     3810dnl  __(subi imm0,imm0,1)
     3811dnl  __(cmpri(cr4,imm0,0))
     3812dnl  __(beq counted_keys)
     3813dnl  __(bne cr3,badlist)
     3814dnl  __(ldr arg_x,[arg_x,#cons.cdr])
     3815dnl   __(extract_lisptag(imm3,arg_x))
     3816dnl   __(cmpri(cr3,imm3,tag_list))
     3817dnl  __(blt cr4,toomany)
     3818dnl  __(cmpri(arg_x,nil_value))
     3819dnl  __(beq db_badkeys)
     3820dnl  __(bne cr3,badlist)
     3821dnl  __(ldr arg_x,[arg_x,#cons.cdr])
     3822dnl  __(b count_keys_loop)
     3823dnl counted_keys:
     3824dnl  /* We've got a proper, even-length list of key/value pairs in */
     3825dnl  /* arg_reg. For each keyword var in the lambda-list, push a pair */
     3826dnl  /* of NILs on the vstack.  */
     3827dnl  __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
     3828dnl  __(mov imm2,imm0)  /* save number of keys  */
     3829dnl  __(mov imm5,#nil_value)
     3830dnl  __(b push_pair_test)
     3831dnl push_pair_loop:
     3832dnl  __(cmpri(imm0,1))
     3833dnl  __(subi imm0,imm0,1)
     3834dnl  __(vpush1(imm5))
     3835dnl  __(vpush1(imm5))
     3836dnl push_pair_test:
     3837dnl  __(bne push_pair_loop)
     3838dnl  __(slwi imm2,imm2,dnode_shift)  /* pairs -> bytes  */
     3839dnl  __(add imm2,vsp,imm2)  /* imm2 points below pairs  */
     3840dnl  __(mov imm0,#0)   /* count unknown keywords so far  */
     3841dnl  __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
     3842dnl  __(extrwi nargs,nargs,mask_key_width,mask_key_start)
     3843dnl  /* Now, for each keyword/value pair in the list  */
     3844dnl  /*  a) if the keyword is found in the keyword vector, set the  */
     3845dnl  /*     corresponding entry on the vstack to the value and the  */
     3846dnl  /*     associated supplied-p var to T.  */
     3847dnl  /*  b) Regardless of whether or not the keyword is found,  */
     3848dnl         /*     if :ALLOW-OTHER-KEYS is provided with a non-nil value, */
     3849dnl  /*     set the low bit of imm1 to indicate that unknown keywords  */
     3850dnl  /*     are acceptable. (This bit is pre-set above to the value */
     3851dnl         /*     the encoded value of &allow_other_keys.) */
     3852dnl  /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
     3853dnl  /*     the count of unknown keywords in the high bits of imm1*/
     3854dnl  /* At the end of the list, signal an error if any unknown keywords were seen  */
     3855dnl  /* but not allowed.  Otherwise, return.  */
     3856dnl
     3857dnl match_keys_loop:
     3858dnl  __(cmpri(arg_reg,nil_value))
     3859dnl  __(mov imm0,#0)
     3860dnl  __(mov imm3,#misc_data_offset)
     3861dnl  __(beq matched_keys)
     3862dnl  __(ldr arg_x,[arg_reg,#cons.car])
     3863dnl  __(mov arg_y,#nrs.kallowotherkeys)
     3864dnl  __(cmpr(cr3,arg_x,arg_y)) /* :ALLOW-OTHER-KEYS ?  */
     3865dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
     3866dnl  __(ldr arg_y,[arg_reg,#cons.car])
     3867dnl  __(cmpr(cr4,imm0,nargs))
     3868dnl  __(ldr arg_reg,[arg_reg,#cons.cdr])
     3869dnl  __(b match_test)
     3870dnl match_loop:
     3871dnl  __(ldrx(temp0,keyvect_reg,imm3))
     3872dnl  __(cmpr(arg_x,temp0))
     3873dnl  __(addi imm0,imm0,1)
     3874dnl  __(cmpr(cr4,imm0,nargs))
     3875dnl  __(addi imm3,imm3,node_size)
     3876dnl  __(bne match_test)
     3877dnl  /* Got a hit.  Unless this keyword's been seen already, set it.  */
     3878dnl  __(slwi imm0,imm0,dnode_shift)
     3879dnl  __(subf imm0,imm0,imm2)
     3880dnl  __(ldr temp0,[imm0,#0])
     3881dnl  __(cmpri(temp0,nil_value))
     3882dnl  __(mov temp0,#t_value)
     3883dnl  __(bne match_keys_loop) /* already saw this  */
     3884dnl  __(str(arg_y,node_size*1(imm0)))
     3885dnl  __(str(temp0,node_size*0(imm0)))
     3886dnl         __(bne cr3,match_keys_loop)
     3887dnl  __(b match_keys_check_aok)
     3888dnl match_test:
     3889dnl  __(bne cr4,match_loop)
     3890dnl         __(beq cr3,match_keys_check_aok)
     3891dnl         __(addi imm1,imm1,node_size)
     3892dnl         __(b match_keys_loop)
     3893dnl match_keys_check_aok:
     3894dnl         __(andi. imm0,imm1,2)  /* check "seen-aok" bit in imm1 */
     3895dnl         __(cmpri cr1,arg_y,nil_value) /* check value */
     3896dnl         __(ori imm1,imm1,2)
     3897dnl         __(bne match_keys_loop) /* duplicate aok */
     3898dnl         __(beq cr1,match_keys_loop)
     3899dnl         __(ori imm1,imm1,1)
     3900dnl  __(b match_keys_loop)
     3901dnl matched_keys:
     3902dnl         __(clrrwi. imm0,imm1,2)
     3903dnl         __(beqlr)
     3904dnl         __(andi. imm1,imm1,1)
     3905dnl         __(bnelr)
     3906dnl  /* Some unrecognized keywords.  Complain generically about  */
     3907dnl  /* invalid keywords.  */
     3908dnl db_badkeys:
     3909dnl  __(mov arg_y,#XBADKEYS)
     3910dnl  __(b destructure_error)
     3911dnl toomany:
     3912dnl  __(mov arg_y,#XCALLTOOMANY)
     3913dnl  __(b destructure_error)
     3914dnl toofew:
     3915dnl  __(mov arg_y,#XCALLTOOFEW)
     3916dnl  __(b destructure_error)
     3917dnl badlist:
     3918dnl  __(mov arg_y,#XCALLNOMATCH)
     3919dnl  /* b destructure_error  */
     3920dnl destructure_error:
     3921dnl  __(mov vsp,imm4)  /* undo everything done to the stack  */
     3922dnl  __(mov arg_z,whole_reg)
     3923dnl  __(set_nargs(2))
     3924dnl  __(b _SPksignalerr)
     3925
     3926/* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
     3927/* frames. If target isn't a multiple-value receiver, discard extra values */
     3928/* (less hair, maybe.)  */
     3929C(_throw_found):
     3930pushdef(`__',`
     3931        .word 0
     3932        ')       
     3933        __(ldr imm1,[imm2,#catch_frame.mvflag])
     3934        __(cmpri(imm1,0))
     3935        __(cmpri(cr1,nargs,0))
     3936        __(mov fn,#0)
     3937        __(add imm1,vsp,nargs)
     3938        __(add imm1,[imm1,#-node_size])
     3939        __(bne local_label(_throw_all_values))
     3940        __(set_nargs(1))
     3941        __(beq cr1,local_label(_throw_default_1_val))
     3942        __(mov vsp,imm1)
     3943        __(b local_label(_throw_all_values))
     3944local_label(_throw_default_1_val):
     3945        __(mov imm4,#nil_value)
     3946        __(vpush1(imm4))
     3947local_label(_throw_all_values):
     3948        __(bl _SPnthrowvalues)
     3949        __(ldr imm3,[rcontext,#tcr.catch_top])
     3950        __(ldr imm1,[rcontext,#tcr.db_link])
     3951        __(ldr imm0,[imm3,#catch_frame.db_link])
     3952        __(ldr imm4,[imm3,#catch_frame.mvflag])
     3953        __(cmpr(imm0,imm1))
     3954        __(cmpri(cr1,imm4,0))
     3955        __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
     3956        __(beq local_label(_throw_dont_unbind))
     3957        __(bl _SPunbind_to)
     3958local_label(_throw_dont_unbind):
     3959        __(add imm0,vsp,nargs)
     3960        __(cmpri(nargs,0))
     3961        __(ldr imm1,[imm3,#catch_frame.csp])
     3962        __(ldr imm1,[imm1,#lisp_frame.savevsp])
     3963        __(bne cr1,local_label(_throw_multiple))
     3964        /* Catcher expects single value in arg_z  */
     3965        __(ldr arg_z,[imm0,#-node_size])
     3966        __(b local_label(_throw_pushed_values))
     3967local_label(_throw_multiple):
     3968        __(beq local_label(_throw_pushed_values))
     3969        __(mov imm2,nargs)
     3970local_label(_throw_mvloop):
     3971        __(sub imm2,imm2,fixnum_one)
     3972        __(cmpri(imm2,0))
     3973        __(ldru(temp0,-node_size(imm0)))
     3974        __(push(temp0,imm1))
     3975        __(bgt local_label(_throw_mvloop))
     3976local_label(_throw_pushed_values):
     3977        __(mov vsp,imm1)
     3978        __(ldr imm1,[imm3,#catch_frame.xframe])
     3979        __(str(imm1,tcr.xframe(rcontext)))
     3980        __(ldr sp,[imm3,#catch_frame.csp])
     3981        __(ldr fn,[sp,#lisp_frame.savefn])
     3982        __(ldr loc_pc,[sp,#lisp_frame.savelr])
     3983        __(discard_lisp_frame())
     3984        __(mtlr loc_pc)
     3985        __(restore_catch_nvrs(imm3))
     3986        __(ldr imm3,[imm3,#catch_frame.link])
     3987        __(str(imm3,tcr.catch_top(rcontext)))
     3988        __(unlink(tsp))
     3989        __(bx lr)
     3990popdef(`__')
     3991
     3992C(nthrow1v):   
     3993local_label(_nthrow1v_nextframe):
     3994        __(subs temp2,temp2,#fixnum_one)
     3995        __(ldr temp0,[rcontext,#tcr.catch_top])
     3996        __(ldr imm1,[rcontext,#tcr.db_link])
     3997        __(set_nargs(1))
     3998        __(blt local_label(_nthrow1v_done))
     3999        __(ldr arg_y,[temp0,#catch_frame.link])
     4000        __(ldr imm0,[temp0,#catch_frame.db_link])
     4001        __(cmp imm0,imm1)
     4002        __(str arg_y,[rcontext,#tcr.catch_top])
     4003        __(ldr arg_y,[temp0,#catch_frame.xframe])
     4004        __(str arg_y,[rcontext,#tcr.xframe])
     4005        __(beq local_label(_nthrow1v_dont_unbind))
     4006        __(do_unbind_to(imm0,temp1,arg_x,arg_y))
     4007local_label(_nthrow1v_dont_unbind):
     4008        __(ldr temp1,[temp0,#catch_frame.catch_tag])
     4009        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
     4010        __(beq local_label(_nthrow1v_do_unwind))
     4011        /* A catch frame.  If the last one, restore context from there.  */
     4012        __(cmp temp2,#0)
     4013        __(ldreq vsp,[sp,#lisp_frame.savevsp])
     4014        __(add sp,sp,#catch_frame.size+lisp_frame.size)
     4015        __(b local_label(_nthrow1v_nextframe))
     4016local_label(_nthrow1v_do_unwind):
     4017pushdef(`__',`
     4018        .word 0
     4019        ')       
     4020        /* This is harder, but not as hard (not as much BLTing) as the  */
     4021        /* multiple-value case.  */
     4022        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
     4023        /* protect.  (Clever, eh ?)  */
     4024
     4025        __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
     4026        __(unlink(tsp))
     4027        __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4028        __(ldr nfn,[sp,#lisp_frame.savefn])
     4029        __(mtctr loc_pc)  /* cleanup code address.  */
     4030        __(str(fn,lisp_frame.savefn(sp)))
     4031        __(mflr loc_pc)
     4032        __(mov fn,nfn)
     4033        __(str(loc_pc,lisp_frame.savelr(sp)))
     4034        __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
     4035        __(str(arg_z,tsp_frame.data_offset(tsp)))
     4036        __(str(temp2,tsp_frame.data_offset+node_size(tsp)))
     4037        __(ldr vsp,[sp,#lisp_frame.savevsp])
     4038        __(str(rzero,tcr.unwinding(rcontext)))
     4039        __(bctrl)
     4040        __(mov imm1,#1)
     4041        __(ldr arg_z,[tsp,#tsp_frame.data_offset])
     4042        __(str(imm1,tcr.unwinding(rcontext)))
     4043        __(ldr temp2,[tsp,#tsp_frame.data_offset+node_size])
     4044        __(ldr fn,[sp,#lisp_frame.savefn])
     4045        __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4046        __(discard_lisp_frame())
     4047        __(mtlr loc_pc)
     4048        __(unlink(tsp))
     4049        __(b local_label(_nthrow1v_nextframe))
     4050popdef(`__')       
     4051local_label(_nthrow1v_done):
     4052        __(mov imm0,#0)
     4053        __(str imm0,[rcontext,#tcr.unwinding])
     4054        /* nargs has an undefined value here, so we can clobber it while */
     4055        /* polling for a deferred interrupt  */
     4056        __(check_pending_interrupt(nargs))
     4057        __(bx lr)
     4058       
     4059       
    42094060        _endfile
  • branches/arm/lisp-kernel/arm-uuo.s

    r13679 r13687  
    8383define(`uuo_error_not_callable',`unaryUUO($1,$2,2)')
    8484define(`uuo_tlb_too_small',`unaryUUO($1,$2,4)')
     85define(`uuo_error_no_throw_tag',`unaryUUO($1,$2,5)')
    8586
    8687/* Binary UUOs */
Note: See TracChangeset for help on using the changeset viewer.