Changeset 13672


Ignore:
Timestamp:
Apr 26, 2010, 6:08:20 AM (10 years ago)
Author:
gb
Message:

Get some stuff (maybe around 10%) to assemble; that which does looks
OK, but it's mostly relatively simple.

Stuff that's currently hopeless (pidgin PPC code) is commented out
via 'dnl'.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/arm/lisp-kernel/arm-spentry.s

    r13664 r13672  
    11/* Copyright (C) 2010 Clozure Associates */
    2 /* Copyright (C) 1994-2001 Digitool, Inc */
    32/* This file is part of Clozure CL.   */
    43
     
    1918        _beginfile
    2019        .align 2
     20        .arm
     21        .syntax unified
    2122       
    2223local_label(start):
    2324        .set sporg,0       
    2425define(`_spentry',`ifdef(`__func_name',`_endfn',`')
     26        .org sporg
    2527        _exportfn(_SP$1)
    26         .org sporg
    2728        .set sporg,sporg+256       
    2829        .line  __line__
     
    5758/* Subprims for catch, throw, unwind_protect.  */
    5859
    59 /* Push a catch frame on the temp stack (and some of it on the cstack, as well.)  */
    60 /* The PC in question is 4 bytes past the caller's return address. ALWAYS.  */
    61 /* The catch tag is in arg_z, the multiple-value flags is in imm2.  */
    62 
    6360
    6461_spentry(mkcatch1v)
     
    7774        __(mkcatch())
    7875        __(bx lr)
    79        
    80 /* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
    81 /* Otherwise, process unwind-protects and throw to indicated catch frame.  */
    82        
    83 _spentry(throw)
    84         __(ldr imm1,[rcontext, #tcr.catch_top])
    85         __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
    86         __(cmpri(cr0,imm1,0))
    87         __(ldr temp0,[vsp,nargs])
    88         __(beq- cr0,local_label(_throw_tag_not_found))
    89 local_label(_throw_loop):
    90         __(ldr temp1,[imm1,#catch_frame.catch_tag])
    91         __(cmpr(cr0,temp0,temp1))
    92         __(mov imm2,imm1)
    93         __(ldr imm1,[imm1,#catch_frame.link])
    94         __(cmpri(cr1,imm1,0))
    95         __(beq cr0,local_label(_throw_found))
    96         __(addi imm0,imm0,fixnum_one)
    97         __(beq- cr1,local_label(_throw_tag_not_found))
    98         __(b local_label(_throw_loop))
    99 /* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
    100 /* frames. If target isn't a multiple-value receiver, discard extra values */
    101 /* (less hair, maybe.)  */
    102 local_label(_throw_found):
    103         __(ldr imm1,[imm2,#catch_frame.mvflag])
    104         __(cmpri(cr0,imm1,0))
    105         __(cmpri(cr1,nargs,0))
    106         __(mov fn,#0)
    107         __(add imm1,vsp,nargs)
    108         __(la imm1,-node_size(imm1))
    109         __(bne cr0,local_label(_throw_all_values))
    110         __(set_nargs(1))
    111         __(beq cr1,local_label(_throw_default_1_val))
    112         __(mov vsp,imm1)
    113         __(b local_label(_throw_all_values))
    114 local_label(_throw_default_1_val):
    115         __(mov imm4,#nil_value)
    116         __(vpush1(imm4))
    117 local_label(_throw_all_values):
    118         __(bl _SPnthrowvalues)
    119         __(ldr imm3,[rcontext,#tcr.catch_top])
    120         __(ldr imm1,[rcontext,#tcr.db_link])
    121         __(ldr imm0,[imm3,#catch_frame.db_link])
    122         __(ldr imm4,[imm3,#catch_frame.mvflag])
    123         __(cmpr(cr0,imm0,imm1))
    124         __(cmpri(cr1,imm4,0))
    125         __(la tsp,-((tsp_frame.fixed_overhead+fulltag_misc))(imm3))
    126         __(beq cr0,local_label(_throw_dont_unbind))
    127         __(bl _SPunbind_to)
    128 local_label(_throw_dont_unbind):
    129         __(add imm0,vsp,nargs)
    130         __(cmpri(cr0,nargs,0))
    131         __(ldr imm1,[imm3,#catch_frame.csp])
    132         __(ldr imm1,[imm1,#lisp_frame.savevsp])
    133         __(bne cr1,local_label(_throw_multiple))
    134         /* Catcher expects single value in arg_z  */
    135         __(ldr arg_z,[imm0,#-node_size])
    136         __(b local_label(_throw_pushed_values))
    137 local_label(_throw_multiple):
    138         __(beq cr0,local_label(_throw_pushed_values))
    139         __(mov imm2,nargs)
    140 local_label(_throw_mvloop):
    141         __(subi imm2,imm2,fixnum_one)
    142         __(cmpri(imm2,0))
    143         __(ldru(temp0,-node_size(imm0)))
    144         __(push(temp0,imm1))
    145         __(bgt local_label(_throw_mvloop))
    146 local_label(_throw_pushed_values):
    147         __(mov vsp,imm1)
    148         __(ldr imm1,[imm3,#catch_frame.xframe])
    149         __(str(imm1,tcr.xframe(rcontext)))
    150         __(ldr sp,[imm3,#catch_frame.csp])
    151         __(ldr fn,[sp,#lisp_frame.savefn])
    152         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    153         __(discard_lisp_frame())
    154         __(mtlr loc_pc)
    155         __(restore_catch_nvrs(imm3))
    156         __(ldr imm3,[imm3,#catch_frame.link])
    157         __(str(imm3,tcr.catch_top(rcontext)))
    158         __(unlink(tsp))
    159         __(bx lr)
    160 local_label(_throw_tag_not_found):
    161         __(uuo_interr(error_throw_tag_missing,temp0))
    162         __(strux(temp0,vsp,nargs))
    163         __(b _SPthrow)
    164 
    165 
    166 /* This takes N multiple values atop the vstack.  */
    167 _spentry(nthrowvalues)
    168         __(mov imm1,#1)
    169         __(mov imm4,imm0)
    170         __(str(imm1,tcr.unwinding(rcontext)))
    171 local_label(_nthrowv_nextframe):
    172         __(subi imm4,imm4,fixnum_one)
    173         __(cmpri(cr1,imm4,0))
    174         __(ldr temp0,[rcontext,#tcr.catch_top])
    175         __(ldr imm1,[rcontext,#tcr.db_link])
    176         __(blt cr1,local_label(_nthrowv_done))
    177         __(ldr imm0,[temp0,#catch_frame.db_link])
    178         __(ldr imm3,[temp0,#catch_frame.link])
    179         __(cmpr(cr0,imm0,imm1))
    180         __(str(imm3,tcr.catch_top(rcontext)))
    181         __(ldr temp1,[temp0,#catch_frame.catch_tag])
    182         __(cmpri(cr7,temp1,unbound_marker))             /* unwind-protect ?  */
    183         __(ldr first_nvr,[temp0,#catch_frame.xframe])
    184         __(str(first_nvr,tcr.xframe(rcontext)))
    185         __(ldr sp,[temp0,#catch_frame.csp])
    186         __(beq cr0,local_label(_nthrowv_dont_unbind))
    187         __(mflr loc_pc)
    188         __(bl _SPunbind_to)
    189         __(mtlr loc_pc)
    190 local_label(_nthrowv_dont_unbind):
    191         __(beq cr7,local_label(_nthrowv_do_unwind))
    192 /* A catch frame.  If the last one, restore context from there.  */
    193         __(bne cr1,local_label(_nthrowv_skip))
    194         __(ldr imm0,[sp,#lisp_frame.savevsp])
    195         __(str(rzero,lisp_frame.savevsp(sp)))   /* marker for stack overflow code  */
    196         __(add imm1,vsp,nargs)
    197         __(mov imm2,nargs)
    198         __(b local_label(_nthrowv_push_test))
    199 local_label(_nthrowv_push_loop):
    200         __(ldru(temp1,-node_size(imm1)))
    201         __(push(temp1,imm0))
    202 local_label(_nthrowv_push_test):
    203         __(cmpri(imm2,0))
    204         __(subi imm2,imm2,fixnum_one)
    205         __(bne local_label(_nthrowv_push_loop))
    206         __(mov vsp,imm0)
    207         __(restore_catch_nvrs(temp0))
    208 
    209 local_label(_nthrowv_skip):
    210         __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
    211         __(unlink(tsp))
    212         __(discard_lisp_frame())
    213         __(b local_label(_nthrowv_nextframe))
    214 local_label(_nthrowv_do_unwind):
    215         /* This is harder.  Call the cleanup code with the multiple */
    216         /* values (and nargs, which is a fixnum.)  Remember the throw count  */
    217         /* (also a fixnum) as well.  */
    218         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
    219         /* protect.  (Clever, eh ?)  */
    220         __(ldr first_nvr,[temp0,#catch_frame.xframe])
    221         __(str(first_nvr,tcr.xframe(rcontext)))
    222         __(restore_catch_nvrs(temp0))
    223         __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
    224         __(unlink(tsp))
    225         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    226         __(ldr nfn,[sp,#lisp_frame.savefn])
    227         __(mtctr loc_pc)        /* cleanup code address.  */
    228         __(str(fn,lisp_frame.savefn(sp)))
    229         __(mflr loc_pc)
    230         __(mov fn,nfn)
    231         __(str(loc_pc,lisp_frame.savelr(sp)))
    232         __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* tsp overhead, nargs, throw count  */
    233         __(TSP_Alloc_Var_Boxed_nz(imm0,imm1))
    234         __(mov imm2,nargs)
    235         __(add imm1,nargs,vsp)
    236         __(la imm0,tsp_frame.data_offset(tsp))
    237         __(str(nargs,0(imm0)))
    238         __(b local_label(_nthrowv_tpushtest))
    239 local_label(_nthrowv_tpushloop):
    240         __(ldru(temp0,-node_size(imm1)))
    241         __(stru(temp0,node_size(imm0)))
    242         __(subi imm2,imm2,fixnum_one)
    243 local_label(_nthrowv_tpushtest):
    244         __(cmpri(imm2,0))
    245         __(bne local_label(_nthrowv_tpushloop))
    246         __(stru(imm4,node_size(imm0)))
    247         __(ldr vsp,[sp,#lisp_frame.savevsp])
    248         /* Interrupts should be disabled here (we're calling and returning */
    249         /* from the cleanup form.  Clear the tcr.unwinding flag, so that */
    250         /* interrupts can be taken if they're enabled in the cleanup form.  */
    251         __(str(rzero,tcr.unwinding(rcontext)))       
    252         __(bctrl)
    253         __(mov imm1,#1)
    254         __(la imm0,tsp_frame.data_offset(tsp))
    255         __(str(imm1,tcr.unwinding(rcontext)))
    256         __(ldr fn,[sp,#lisp_frame.savefn])
    257         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    258         __(discard_lisp_frame())
    259         __(mtlr loc_pc)
    260         __(ldr nargs,[imm0,#0])
    261         __(mov imm2,nargs)
    262         __(b local_label(_nthrowv_tpoptest))
    263 local_label(_nthrowv_tpoploop):
    264         __(ldru(temp0,node_size(imm0)))
    265         __(vpush1(temp0))
    266         __(subi imm2,imm2,fixnum_one)
    267 local_label(_nthrowv_tpoptest):
    268         __(cmpri(imm2,0))
    269         __(bne local_label(_nthrowv_tpoploop))
    270         __(ldr imm4,[imm0,#node_size])
    271         __(unlink(tsp))
    272         __(b local_label(_nthrowv_nextframe))
    273 local_label(_nthrowv_done):
    274         __(str(rzero,tcr.unwinding(rcontext)))
    275         /* Poll for a deferred interrupt.  That clobbers nargs (which we've */
    276         /* just expended a lot of effort to preserve), so expend a little *
    277         /* more effort. */
    278         __(mov imm4,nargs)
    279         __(check_pending_interrupt())
    280         __(mov nargs,imm4)
    281         __(bx lr)
    282 
    283 /* This is a (slight) optimization.  When running an unwind-protect, */
    284 /* save the single value and the throw count in the tstack frame. */
    285 /* Note that this takes a single value in arg_z.  */
    286 _spentry(nthrow1value)
    287         __(mov imm1,#1)
    288         __(mov imm4,imm0)
    289         __(str(imm1,tcr.unwinding(rcontext)))
    290 local_label(_nthrow1v_nextframe):
    291         __(subi imm4,imm4,fixnum_one)
    292         __(cmpri(cr1,imm4,0))
    293         __(ldr temp0,[rcontext,#tcr.catch_top])
    294         __(ldr imm1,[rcontext,#tcr.db_link])
    295         __(set_nargs(1))
    296         __(blt cr1,local_label(_nthrow1v_done))
    297         __(ldr imm3,[temp0,#catch_frame.link])
    298         __(ldr imm0,[temp0,#catch_frame.db_link])
    299         __(cmpr(cr0,imm0,imm1))
    300         __(str(imm3,tcr.catch_top(rcontext)))
    301         __(ldr imm3,[temp0,#catch_frame.xframe])
    302         __(ldr temp1,[temp0,#catch_frame.catch_tag])
    303         __(cmpri(cr7,temp1,unbound_marker))             /* unwind-protect ?  */
    304         __(str(imm3,tcr.xframe(rcontext)))
    305         __(ldr sp,[temp0,#catch_frame.csp])
    306         __(beq cr0,local_label(_nthrow1v_dont_unbind))
    307          __(mflr loc_pc)
    308          __(bl _SPunbind_to)
    309          __(mtlr loc_pc)
    310 local_label(_nthrow1v_dont_unbind):
    311         __(beq cr7,local_label(_nthrow1v_do_unwind))
    312         /* A catch frame.  If the last one, restore context from there.  */
    313         __(bne cr1,local_label(_nthrow1v_skip))
    314         __(ldr vsp,[sp,#lisp_frame.savevsp])
    315         __(restore_catch_nvrs(temp0))
    316 local_label(_nthrow1v_skip):
    317         __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
    318         __(unlink(tsp))
    319         __(discard_lisp_frame())
    320         __(b local_label(_nthrow1v_nextframe))
    321 local_label(_nthrow1v_do_unwind):
    322         /* This is harder, but not as hard (not as much BLTing) as the  */
    323         /* multiple-value case.  */
    324         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
    325         /* protect.  (Clever, eh ?)  */
    326 
    327         __(restore_catch_nvrs(temp0))
    328         __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
    329         __(unlink(tsp))
    330         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    331         __(ldr nfn,[sp,#lisp_frame.savefn])
    332         __(mtctr loc_pc)                /* cleanup code address.  */
    333         __(str(fn,lisp_frame.savefn(sp)))
    334         __(mflr loc_pc)
    335         __(mov fn,nfn)
    336         __(str(loc_pc,lisp_frame.savelr(sp)))
    337         __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
    338         __(str(arg_z,tsp_frame.data_offset(tsp)))
    339         __(str(imm4,tsp_frame.data_offset+node_size(tsp)))
    340         __(ldr vsp,[sp,#lisp_frame.savevsp])
    341         __(str(rzero,tcr.unwinding(rcontext)))
    342         __(bctrl)
    343         __(mov imm1,#1)
    344         __(ldr arg_z,[tsp,#tsp_frame.data_offset])
    345         __(str(imm1,tcr.unwinding(rcontext)))
    346         __(ldr imm4,[tsp,#tsp_frame.data_offset+node_size])
    347         __(ldr fn,[sp,#lisp_frame.savefn])
    348         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    349         __(discard_lisp_frame())
    350         __(mtlr loc_pc)
    351         __(unlink(tsp))
    352         __(b local_label(_nthrow1v_nextframe))
    353 local_label(_nthrow1v_done):
    354         __(str(rzero,tcr.unwinding(rcontext)))
    355         /* nargs has an undefined value here, so we can clobber it while */
    356         /* polling for a deferred interrupt  */
    357         __(check_pending_interrupt())
    358         __(bx lr)
    35976
    36077/* This never affects the symbol's vcell  */
    36178/* Non-null symbol in arg_y, new value in arg_z          */
    36279_spentry(bind)
    363         __(ldr imm3,[arg_y,#symbol.binding_index])
     80        __(ldr imm1,[arg_y,#symbol.binding_index])
    36481        __(ldr imm0,[rcontext,#tcr.tlb_limit])
    365         __(trlle(imm0,imm3))           /* tlb too small  */
    366         __(cmpri(imm3,0))
     82        __(cmp imm0,imm1)
     83        __(uuo_tlb_too_small(hs))
     84        __(cmp imm1,#0)
    36785        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
    368         __(ldr imm1,[rcontext,#tcr.db_link])
    369         __(ldr temp1,[imm2,imm3])
     86        __(ldr imm0,[rcontext,#tcr.db_link])
     87        __(ldr temp1,[imm2,imm0])
    37088        __(beq 9f)
    37189        __(vpush1(temp1))
    372         __(vpush1(imm3))
    37390        __(vpush1(imm1))
    374         __(strx(arg_z,imm2,imm3))
    375         __(str(vsp,tcr.db_link(rcontext)))
     91        __(vpush1(imm0))
     92        __(str arg_z,[imm2,imm1])
     93        __(str vsp,[rcontext,#tcr.db_link])
    37694        __(bx lr)
    377959:
    37896        __(mov arg_z,arg_y)
    379         __(lwi(arg_y,XSYMNOBIND))
     97        __(mov arg_y,#XSYMNOBIND)
    38098        __(set_nargs(2))
    38199        __(b _SPksignalerr)
    382100
    383 /* arg_z = symbol: bind it to its current value          */
    384 _spentry(bind_self)
    385         __(ldr imm3,[arg_z,#symbol.binding_index])
    386         __(ldr imm0,[rcontext,#tcr.tlb_limit])
    387         __(cmpri(imm3,0))
    388         __(trlle(imm0,imm3))           /* tlb too small  */
    389         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
    390         __(ldr imm1,[rcontext,#tcr.db_link])
    391         __(ldr temp1,[imm2,imm3])
    392         __(cmpri(cr1,temp1,no_thread_local_binding_marker))
    393         __(beq 9f)
    394         __(mov temp0,temp1)
    395         __(bne cr1,1f)
    396         __(ldr temp0,[arg_z,#symbol.vcell])
    397 1:             
    398         __(vpush1(temp1))
    399         __(vpush1(imm3))
    400         __(vpush1(imm1))
    401         __(strx(temp0,imm2,imm3))
    402         __(str(vsp,tcr.db_link(rcontext)))
    403         __(bx lr)
    404 9:      __(lwi(arg_y,XSYMNOBIND))
    405         __(set_nargs(2))
    406         __(b _SPksignalerr)
    407 
    408 /* Bind symbol in arg_z to NIL                 */
    409 _spentry(bind_nil)
    410         __(ldr imm3,[arg_z,#symbol.binding_index])
    411         __(ldr imm0,[rcontext,#tcr.tlb_limit])
    412         __(cmpri(imm3,0))
    413         __(beq- 9f)
    414         __(trlle(imm0,imm3))           /* tlb too small  */
    415         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
    416         __(ldr temp1,[imm2,imm3])
    417         __(ldr imm1,[rcontext,#tcr.db_link])
    418         __(mov imm0,#nil_value)
    419         __(vpush1(temp1))
    420         __(vpush1(imm3))
    421         __(vpush1(imm1))
    422         __(strx(imm0,imm2,imm3))
    423         __(str(vsp,tcr.db_link(rcontext)))
    424         __(bx lr)
    425 9:      __(lwi(arg_y,XSYMNOBIND))
    426         __(set_nargs(2))
    427         __(b _SPksignalerr)
    428 
    429        
    430 /* Bind symbol in arg_z to its current value;  trap if symbol is unbound */
    431 _spentry(bind_self_boundp_check)
    432         __(ldr imm3,[arg_z,#symbol.binding_index])
    433         __(ldr imm0,[rcontext,#tcr.tlb_limit])
    434         __(cmpri(imm3,0))
    435         __(trlle(imm0,imm3))           /* tlb too small  */
    436         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
    437         __(ldr temp1,[imm2,imm3])
    438         __(ldr imm1,[rcontext,#tcr.db_link])
    439         __(beq 9f)              /* no real tlb index  */
    440         __(cmpri(temp1,no_thread_local_binding_marker))
    441         __(mov temp0,temp1)
    442         __(bne 1f)
    443         __(ldr temp0,[arg_z,#symbol.vcell])
    444 1:      __(treqi(temp0,unbound_marker))       
    445         __(vpush1(temp1))
    446         __(vpush1(imm3))
    447         __(vpush1(imm1))
    448         __(strx(temp0,imm2,imm3))
    449         __(str(vsp,tcr.db_link(rcontext)))
    450         __(bx lr)
    451 9:      __(lwi(arg_y,XSYMNOBIND))
    452         __(set_nargs(2))
    453         __(b _SPksignalerr)
    454 
    455 
    456 /* The function pc_luser_xp() - which is used to ensure that suspended threads */
    457 /* are suspended in a GC-safe way - has to treat these subprims (which  */
    458 /* implement the EGC write-barrier) specially.  Specifically, a store that */
    459 /* might introduce an intergenerational reference (a young pointer stored  */
    460 /* in an old object) has to "memoize" that reference by setting a bit in  */
    461 /* the global "refbits" bitmap. */
    462 /* This has to happen atomically, and has to happen atomically wrt GC. */
    463 /* Note that updating a word in a bitmap is itself not atomic, unless we use */
    464 /* interlocked loads and stores. */
    465 
    466 
    467 /* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
    468 /* are in the function, we can do the store (even if it's already been done)  */
    469 /* and calculate whether or not we need to set the bit out-of-line.  (Actually */
    470 /* setting the bit needs to be done atomically, unless we're sure that other */
    471 /* threads are suspended.) */
    472 /* We can unconditionally set the suspended thread's PC to its LR. */
    473        
    474         .globl C(egc_write_barrier_start)
    475 _spentry(rplaca)
    476 C(egc_write_barrier_start):
    477         __(cmplr(cr2,arg_z,arg_y))
    478         __(_rplaca(arg_y,arg_z))
    479         __(blelr cr2)
    480         __(ref_global(imm2,ref_base))
    481         __(sub imm0,arg_y,imm2)
    482         __(load_highbit(imm3))
    483         __(srri(imm0,imm0,dnode_shift))       
    484         __(ref_global(imm1,oldspace_dnode_count))
    485         __(extract_bit_shift_count(imm4,imm0))
    486         __(cmplr(imm0,imm1))
    487         __(srr(imm3,imm3,imm4))
    488         __(srri(imm0,imm0,bitmap_shift))       
    489         __(ref_global(imm2,refbits))
    490         __(bgelr)
    491         __(slri(imm0,imm0,word_shift))
    492         __(ldr imm1,[imm2,imm0])
    493         __(and. imm1,imm1,imm3)
    494         __(bnelr)
    495 1:      __(lrarx(imm1,imm2,imm0))
    496         __(or imm1,imm1,imm3)
    497         __(strcx(imm1,imm2,imm0))
    498         __(bne- 1b)
    499         __(isync)
    500         __(bx lr)
    501 
    502         .globl C(egc_rplacd)
    503 _spentry(rplacd)
    504 C(egc_rplacd):
    505         __(cmplr(cr2,arg_z,arg_y))
    506         __(_rplacd(arg_y,arg_z))
    507         __(blelr cr2)
    508         __(ref_global(imm2,ref_base))
    509         __(sub imm0,arg_y,imm2)
    510         __(load_highbit(imm3))
    511         __(srri(imm0,imm0,dnode_shift))       
    512         __(ref_global(imm1,oldspace_dnode_count))
    513         __(extract_bit_shift_count(imm4,imm0))
    514         __(cmplr(imm0,imm1))
    515         __(srr(imm3,imm3,imm4))
    516         __(srri(imm0,imm0,bitmap_shift))       
    517         __(ref_global(imm2,refbits))
    518         __(bgelr)
    519         __(slri(imm0,imm0,word_shift))
    520         __(ldr imm1,[imm2,imm0])
    521         __(and. imm1,imm1,imm3)
    522         __(bnelr)       
    523 1:      __(lrarx(imm1,imm2,imm0))
    524         __(or imm1,imm1,imm3)
    525         __(strcx(imm1,imm2,imm0))
    526         __(bne- 1b)
    527         __(isync)
    528         __(bx lr)
    529 
    530 /* Storing into a gvector can be handled the same way as storing into a CONS. */
    531 
    532         .globl C(egc_gvset)
    533 _spentry(gvset)
    534 C(egc_gvset):
    535         __(cmplr(cr2,arg_z,arg_x))
    536         __(la imm0,misc_data_offset(arg_y))
    537         __(strx(arg_z,arg_x,imm0))
    538         __(blelr cr2)
    539         __(add imm0,imm0,arg_x)
    540         __(ref_global(imm2,ref_base))
    541         __(load_highbit(imm3))
    542         __(ref_global(imm1,oldspace_dnode_count))
    543         __(sub imm0,imm0,imm2)
    544         __(srri(imm0,imm0,dnode_shift))       
    545         __(cmplr(imm0,imm1))
    546         __(extract_bit_shift_count(imm4,imm0))
    547         __(srri(imm0,imm0,bitmap_shift))       
    548         __(srr(imm3,imm3,imm4))
    549         __(ref_global(imm2,refbits))
    550         __(bgelr)
    551         __(slri(imm0,imm0,word_shift))
    552         __(ldrx(imm1,imm2,imm0))
    553         __(and. imm1,imm1,imm3)
    554         __(bnelr)       
    555 1:      __(lrarx(imm1,imm2,imm0))
    556         __(or imm1,imm1,imm3)
    557         __(strcx(imm1,imm2,imm0))
    558         __(bne- 1b)
    559         __(isync)
    560         __(bx lr)
    561 
    562 /* This is a special case of storing into a gvector: if we need to memoize  */
    563 /* the store, record the address of the hash-table vector in the refmap,  */
    564 /* as well. */
    565         .globl C(egc_set_hash_key)       
    566 _spentry(set_hash_key)
    567 C(egc_set_hash_key):
    568         __(cmplr(cr2,arg_z,arg_x))
    569         __(la imm0,misc_data_offset(arg_y))
    570         __(strx(arg_z,arg_x,imm0))
    571         __(blelr cr2)
    572         __(add imm0,imm0,arg_x)
    573         __(ref_global(imm2,ref_base))
    574         __(load_highbit(imm3))
    575         __(ref_global(imm1,oldspace_dnode_count))
    576         __(sub imm0,imm0,imm2)
    577         __(srri(imm0,imm0,dnode_shift))       
    578         __(cmplr(imm0,imm1))
    579         __(extract_bit_shift_count(imm4,imm0))
    580         __(srri(imm0,imm0,bitmap_shift))       
    581         __(srr(imm3,imm3,imm4))
    582         __(ref_global(imm2,refbits))
    583         __(bgelr)
    584         __(slri(imm0,imm0,word_shift))
    585         __(ldrx(imm1,imm2,imm0))
    586         __(and. imm1,imm1,imm3)
    587         __(bne 2f)       
    588 1:      __(lrarx(imm1,imm2,imm0))
    589         __(or imm1,imm1,imm3)
    590         __(strcx(imm1,imm2,imm0))
    591         __(bne- 1b)
    592         __(isync)
    593 2:             
    594         __(ref_global(imm1,ref_base))
    595         __(sub imm0,arg_x,imm1)
    596         __(srri(imm0,imm0,dnode_shift))
    597         __(load_highbit(imm3))
    598         __(extract_bit_shift_count(imm4,imm0))
    599         __(srri(imm0,imm0,bitmap_shift))
    600         __(srr(imm3,imm3,imm4))
    601         __(slri(imm0,imm0,word_shift))
    602         __(ldrx(imm1,imm2,imm0))
    603         __(and. imm1,imm1,imm3)
    604         __(bnelr)
    605 3:      __(lrarx(imm1,imm2,imm0))
    606         __(or imm1,imm1,imm3)
    607         __(strcx(imm1,imm2,imm0))
    608         __(bne- 3b)
    609         __(isync)
    610         __(bx lr)
    611        
    612 /*
    613    Interrupt handling (in pc_luser_xp()) notes:
    614    If we are in this function and before the test which follows the
    615    conditional (at egc_store_node_conditional), or at that test
    616    and cr0`eq' is clear, pc_luser_xp() should just let this continue
    617    (we either haven't done the store conditional yet, or got a
    618    possibly transient failure.)  If we're at that test and the
    619    cr0`EQ' bit is set, then the conditional store succeeded and
    620    we have to atomically memoize the possible intergenerational
    621    reference.  Note that the local labels 4 and 5 are in the
    622    body of the next subprim (and at or beyond 'egc_write_barrier_end').
    623 
    624    N.B: it's not possible to really understand what's going on just
    625    by the state of the cr0`eq' bit.  A transient failure in the
    626    conditional stores that handle memoization might clear cr0`eq'
    627    without having completed the memoization.
    628 */
    629 
    630         .globl C(egc_store_node_conditional)
    631         .globl C(egc_write_barrier_end)
    632 _spentry(store_node_conditional)
    633 C(egc_store_node_conditional):
    634         __(cmplr(cr2,arg_z,arg_x))
    635         __(vpop(temp0))
    636         __(unbox_fixnum(imm4,temp0))
    637 1:      __(lrarx(temp1,arg_x,imm4))
    638         __(cmpr(cr1,temp1,arg_y))
    639         __(bne cr1,5f)
    640         __(strcx(arg_z,arg_x,imm4))
    641         .globl C(egc_store_node_conditional_test)
    642 C(egc_store_node_conditional_test):     
    643         __(bne 1b)
    644         __(isync)
    645         __(add imm0,imm4,arg_x)
    646         __(ref_global(imm2,ref_base))
    647         __(ref_global(imm1,oldspace_dnode_count))
    648         __(sub imm0,imm0,imm2)
    649         __(load_highbit(imm3))
    650         __(srri(imm0,imm0,dnode_shift))       
    651         __(cmplr(imm0,imm1))
    652         __(extract_bit_shift_count(imm2,imm0))
    653         __(srri(imm0,imm0,bitmap_shift))       
    654         __(srr(imm3,imm3,imm2))
    655         __(ref_global(imm2,refbits))
    656         __(bge 4f)
    657         __(slri(imm0,imm0,word_shift))
    658 2:      __(lrarx(imm1,imm2,imm0))
    659         __(or imm1,imm1,imm3)
    660         __(strcx( imm1,imm2,imm0))
    661         __(bne- 2b)
    662         __(isync)
    663         __(b 4f)
    664 
    665 /* arg_z = new value, arg_y = expected old value, arg_x = hash-vector,
    666    vsp`0' = (boxed) byte-offset
    667    Interrupt-related issues are as in store_node_conditional, but
    668    we have to do more work to actually do the memoization.*/
    669 _spentry(set_hash_key_conditional)
    670         .globl C(egc_set_hash_key_conditional)
    671 C(egc_set_hash_key_conditional):
    672         __(cmplr(cr2,arg_z,arg_x))
    673         __(vpop(imm4))
    674         __(unbox_fixnum(imm4,imm4))
    675 1:      __(lrarx(temp1,arg_x,imm4))
    676         __(cmpr(cr1,temp1,arg_y))
    677         __(bne cr1,5f)
    678         __(strcx(arg_z,arg_x,imm4))
    679         .globl C(egc_set_hash_key_conditional_test)
    680 C(egc_set_hash_key_conditional_test):   
    681         __(bne 1b)
    682         __(isync)
    683         __(add imm0,imm4,arg_x)
    684         __(ref_global(imm2,ref_base))
    685         __(ref_global(imm1,oldspace_dnode_count))
    686         __(sub imm0,imm0,imm2)
    687         __(load_highbit(imm3))
    688         __(srri(imm0,imm0,dnode_shift))
    689         __(cmplr(imm0,imm1))
    690         __(extract_bit_shift_count(imm2,imm0))
    691         __(srri(imm0,imm0,bitmap_shift))
    692         __(srr(imm3,imm3,imm2))
    693         __(ref_global(imm2,refbits))
    694         __(bge 4f)
    695         __(slri(imm0,imm0,word_shift))
    696 2:      __(lrarx(imm1,imm2,imm0))
    697         __(or imm1,imm1,imm3)
    698         __(strcx(imm1,imm2,imm0))
    699         __(bne- 2b)
    700         __(isync)
    701         /* Memoize hash table header */         
    702         __(ref_global(imm1,ref_base))
    703         __(sub imm0,arg_x,imm1)
    704         __(srri(imm0,imm0,dnode_shift))
    705         __(load_highbit(imm3))
    706         __(extract_bit_shift_count(imm4,imm0))
    707         __(srri(imm0,imm0,bitmap_shift))
    708         __(srr(imm3,imm3,imm4))
    709         __(slri(imm0,imm0,word_shift))
    710         __(ldrx(imm1,imm2,imm0))
    711         __(and. imm1,imm1,imm3)
    712         __(bne 4f)
    713 3:      __(lrarx(imm1,imm2,imm0))
    714         __(or imm1,imm1,imm3)
    715         __(strcx(imm1,imm2,imm0))
    716         __(bne- 3b)
    717         __(isync)
    718 C(egc_write_barrier_end):
    719 4:      __(mov arg_z,#t_value)
    720         __(bx lr)
    721 5:      __(mov imm0,#RESERVATION_DISCHARGE)
    722         __(strcx(rzero,0,imm0))
    723         __(mov arg_z,#nil_value)
    724         __(bx lr)
    725        
    726        
    727                
    728101_spentry(conslist)
    729102        __(mov arg_z,#nil_value)
    730         __(cmpri(nargs,0))
     103        __(cmp nargs,#0)
    731104        __(b 2f)       
    7321051:
    733         __(ldr temp0,[vsp,#0])
    734         __(cmpri(nargs,fixnum_one))
    735         __(la vsp,node_size(vsp))
    736         __(Cons(arg_z,temp0,arg_z))
    737         __(subi nargs,nargs,fixnum_one)
     106        __(vpop1(arg_y))
     107        __(Cons(arg_z,arg_z,arg_z))
     108        __(subs nargs,nargs,#fixnum_one)
    7381092:
    739110        __(bne 1b)
     
    742113/* do list*: last arg in arg_z, all others vpushed, nargs set to #args vpushed.  */
    743114/* Cons, one cons cell at at time.  Maybe optimize this later.  */
     115       
    744116_spentry(conslist_star)
    745         __(cmpri(nargs,0))
     117        __(cmp nargs,#0)
    746118        __(b 2f)       
    7471191:
    748         __(ldr temp0,[vsp,#0])
    749         __(cmpri(nargs,fixnum_one))
    750         __(la vsp,node_size(vsp))
    751         __(Cons(arg_z,temp0,arg_z))
    752         __(subi nargs,nargs,fixnum_one)
     120        __(vpop1(arg_y))
     121        __(Cons(arg_z,arg_y,arg_z))
     122        __(subs nargs,nargs,fixnum_one)
    7531232:
    754124        __(bne 1b)
    755125        __(bx lr)
    756 
    757 /* We always have to create a tsp frame (even if nargs is 0), so the compiler  */
    758 /* doesn't get confused.  */
    759 _spentry(stkconslist)
    760         __(mov arg_z,#nil_value)
    761         __(cmpri(cr1,nargs,0))
    762         __(add imm1,nargs,nargs)
    763         __(addi imm1,imm1,tsp_frame.fixed_overhead)
    764         __(TSP_Alloc_Var_Boxed(imm1,imm2))
    765         __(la imm1,tsp_frame.data_offset+fulltag_cons(tsp))
    766         __(b 2f)
    767 1:      __(ldr temp0,[vsp,#0])
    768         __(cmpri(cr1,nargs,fixnum_one))
    769         __(la vsp,node_size(vsp))
    770         __(_rplaca(imm1,temp0))
    771         __(_rplacd(imm1,arg_z))
    772         __(mov arg_z,imm1)
    773         __(la imm1,cons.size(imm1))
    774         __(la nargs,-fixnum_one(nargs))
    775 2:
    776         __(bne cr1,1b)
     126       
     127_spentry(makes32)
     128        __(adds imm1,imm0,imm0)
     129        __(addsvc arg_z,imm1,imm1)
     130        __(bxvc lr)
     131        __(movc16(imm1,one_digit_bignum_header))
     132        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
     133        __(str imm0,[arg_z,#misc_data_offset])
    777134        __(bx lr)
    778135
    779 /* do list*: last arg in arg_z, all others vpushed,  */
    780 /* nargs set to #args vpushed.  */
    781 _spentry(stkconslist_star)
    782         __(cmpri(cr1,nargs,0))
    783         __(add imm1,nargs,nargs)
    784         __(addi imm1,imm1,tsp_frame.fixed_overhead)
    785         __(TSP_Alloc_Var_Boxed(imm1,imm2))
    786         __(la imm1,tsp_frame.data_offset+fulltag_cons(tsp))
    787         __(b 2f)
    788 1:      __(ldr temp0,[vsp,#0])
    789         __(cmpri(cr1,nargs,fixnum_one))
    790         __(la vsp,node_size(vsp))
    791         __(_rplaca(imm1,temp0))
    792         __(_rplacd(imm1,arg_z))
    793         __(mov arg_z,imm1)
    794         __(la imm1,cons.size(imm1))
    795         __(la nargs,-fixnum_one(nargs))
    796 2:
    797         __(bne cr1,1b)
     136/* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
     137
     138       
     139_spentry(makeu32)
     140        __(tst imm0,#0xe0000000)
     141        __(box_fixnum(arg_z,imm0))
     142        __(bxeq lr)
     143        __(tst imm0,#0x80000000)
     144        __(bne 2f)
     145        __(movc16(imm1,one_digit_bignum_header))
     146        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
     147        __(str imm0,[arg_z,#misc_data_offset])
     148        __(bx lr)
     1492:             
     150        __(movc16(imm1,two_digit_bignum_header))
     151        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
     152        __(str imm0,[arg_z,#misc_data_offset])
    798153        __(bx lr)
    799154
     155       
     156/* arg_z has overflowed (by one bit) as the result of an addition or subtraction. */
     157/* Make a bignum out of it. */
    800158
    801 /* Make a stack-consed simple-vector out of the NARGS objects  */
    802 /* on top of the vstack; return it in arg_z.  */
    803 _spentry(mkstackv)
    804         __(cmpri(cr1,nargs,0))
    805         __(dnode_align(imm1,nargs,tsp_frame.fixed_overhead+node_size))
    806         __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
    807         __(slwi imm0,nargs,num_subtag_bits-fixnumshift)
    808         __(ori imm0,imm0,subtag_simple_vector)
    809         __(str(imm0,tsp_frame.data_offset(tsp)))
    810         __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    811         __(beq- cr1,2f)
    812         __(la imm0,misc_data_offset(arg_z))
    813         __(add imm1,imm0,nargs)
     159_spentry(fix_overflow)
     160        __(unbox_fixnum(imm0,arg_z))
     161        __(eor imm0,imm0,#0xc0000000)
     162        __(b _SPmakes32)
     163
     164_spentry(builtin_plus)
     165        __(test_two_fixnums(arg_y,arg_z,imm0))
     166        __(bne 1f)
     167        __(adds arg_z,arg_y,arg_z)
     168        __(bxvc lr)
     169        __(b _SPfix_overflow)
    8141701:
    815         __(la nargs,-node_size(nargs))
    816         __(cmpri(cr1,nargs,0))
    817         __(ldr temp1,[vsp,#0])
    818         __(la vsp,node_size(vsp))
    819         __(stru(temp1,-node_size(imm1)))
    820         __(bne cr1,1b)
    821 2:
     171        __(jump_builtin(_builtin_plus,2))
     172       
     173_spentry(builtin_minus)
     174        __(test_two_fixnums(arg_y,arg_z,imm0))
     175        __(bne 1f)
     176        __(subs arg_z,arg_y,arg_z)
     177        __(bxvc lr)
     178        __(b _SPfix_overflow)
     1791:
     180        __(jump_builtin(_builtin_minus,2))
     181
     182/*  Construct a lisp integer out of the 64-bit unsigned value in */
     183/*           imm0 (low 32 bits) and imm1 (high 32 bits) */
     184               
     185_spentry(makeu64)
     186        __(cmp imm1,0)
     187        __(beq _SPmakeu32)
     188        __(blt 3f)
     189        __(movc16(imm2,two_digit_bignum_header))
     190        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
     191        __(str imm0,[arg_z,#misc_data_offset])
     192        __(str imm1,[arg_z,#misc_data_offset+4])
     193        __(bx lr)
     1943:             
     195        __(movc16(imm2,three_digit_bignum_header))
     196        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
     197        __(str imm0,[arg_z,#misc_data_offset])
     198        __(str imm1,[arg_z,#misc_data_offset+4])
    822199        __(bx lr)
    823200
    824        
     201/*  Construct a lisp integer out of the 64-bit signed value in */
     202/*        imm0 (low 32 bits) and imm1 (high 32 bits). */
     203_spentry(makes64)
     204        __(cmp imm1,imm0,asr #31) /* is imm1 sign extension of imm0 ? */
     205        __(beq _SPmakes32)        /* forget imm1 if so */
     206        __(movc16(imm2,two_digit_bignum_header))
     207        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
     208        __(str imm0,[arg_z,#misc_data_offset])
     209        __(str imm1,[arg_z,#misc_data_offset+4])
     210        __(bx lr)
    825211       
     212_spentry(builtin_times)
     213        __(test_two_fixnums(arg_y,arg_z,imm0))
     214        __(bne 1f)
     215        __(unbox_fixnum(imm2,arg_z))
     216        __(smull arg_z,imm1,imm2,arg_y)
     217        /* Now have a "64-bit fixnum" in imm1(high) and arg_z(low). If */
     218        /* imm1 is just a sign extension of arg_z, return arg_z */
     219        __(cmp imm1,arg_z,asr #(nbits_in_word-1))
     220        __(bxeq lr)
     221        /* Need to ashift the pair imm1:imm0 right fixnumshift bits */
     222        __(mov imm0,imm0,lsr #fixnumshift)
     223        __(and imm2,imm1,#fixnummask)
     224        __(orr imm0,imm0,imm2,lsl #(nbits_in_word-fixnumshift))
     225        __(unbox_fixnum(imm1,imm1))
     226        __(b _SPmakes64)
    826227
    827 _spentry(setqsym)
    828         __(ldr imm0,[arg_y,#symbol.flags])
    829         __(andi. imm0,imm0,sym_vbit_const_mask)
    830         __(beq _SPspecset)
    831         __(mov arg_z,arg_y)
    832         __(lwi(arg_y,XCONST))
    833         __(set_nargs(2))
    834         __(b _SPksignalerr)
     2281:      __(jump_builtin(_builtin_times,2))
    835229
     230_spentry(builtin_eq)
     231        __(test_two_fixnums(arg_y,arg_z,imm0))
     232        __(bne 1f)
     233        __(cmp arg_y,arg_z)
     234        __(mov arg_z,#nil_value)
     235        __(addeq arg_z,arg_z,#t_offset)
     236        __(bx lr)       
     2371:
     238        __(jump_builtin(_builtin_eq,2))
    836239
    837        
    838 _spentry(progvsave)
    839         /* Error if arg_z isn't a proper list.  That's unlikely, */
    840         /* but it's better to check now than to crash later. */
    841        
    842         __(cmpri(arg_z,nil_value))
    843         __(mov arg_x,arg_z)     /* fast  */
    844         __(mov temp1,arg_z)     /* slow  */
    845         __(beq 9f)              /* Null list is proper  */
    846 0:     
    847         __(trap_unless_list(arg_x,imm0))
    848         __(_cdr(temp2,arg_x))   /* (null (cdr fast)) ?  */
    849         __(cmpri(cr3,temp2,nil_value))
    850         __(trap_unless_list(temp2,imm0,cr0))
    851         __(_cdr(arg_x,temp2))
    852         __(beq cr3,9f)
    853         __(_cdr(temp1,temp1))
    854         __(cmpr(arg_x,temp1))
    855         __(bne 0b)
    856         __(lwi(arg_y,XIMPROPERLIST))
    857         __(set_nargs(2))
    858         __(b _SPksignalerr)
    859 9:      /* Whew          */
    860        
    861         /* Next, determine the length of arg_y.  We  */
    862         /* know that it's a proper list.  */
    863         __(mov imm0,#-node_size)
    864         __(mov arg_x,arg_y)
     240_spentry(builtin_ne)
     241        __(test_two_fixnums(arg_y,arg_z,imm0))
     242        __(bne 1f)
     243        __(cmp arg_y,arg_z)
     244        __(mov arg_z,#nil_value)
     245        __(addne arg_z,arg_z,#t_offset)
     246        __(bx lr)
    8652471:
    866         __(cmpri(cr0,arg_x,nil_value))
    867         __(la imm0,node_size(imm0))
    868         __(_cdr(arg_x,arg_x))
    869         __(bne 1b)
    870         /* imm0 is now (boxed) triplet count.  */
    871         /* Determine word count, add 1 (to align), and make room.  */
    872         /* if count is 0, make an empty tsp frame and exit  */
    873         __(cmpri(cr0,imm0,0))
    874         __(add imm1,imm0,imm0)
    875         __(add imm1,imm1,imm0)
    876         __(dnode_align(imm1,imm1,node_size))
    877         __(bne+ cr0,2f)
    878          __(TSP_Alloc_Fixed_Boxed(2*node_size))
    879          __(bx lr)
    880 2:
    881         __(la imm1,tsp_frame.fixed_overhead(imm1))      /* tsp header  */
    882         __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
    883         __(str(imm0,tsp_frame.data_offset(tsp)))
    884         __(ldr imm2,[tsp,#tsp_frame.backlink])
    885         __(mov arg_x,arg_y)
    886         __(ldr imm1,[rcontext,#tcr.db_link])
    887         __(ldr imm3,[rcontext,#tcr.tlb_limit])
    888 3:
    889         __(cmpri(cr1,arg_z,nil_value))
    890         __(_car(temp0,arg_x))
    891         __(ldr imm0,[temp0,#symbol.binding_index])
    892         __(_cdr(arg_x,arg_x))
    893         __(trlle(imm3,imm0))
    894         __(ldr imm4,[rcontext,#tcr.tlb_pointer]) /* Need to reload after trap  */
    895         __(ldrx(temp3,imm4,imm0))
    896         __(cmpri(cr0,arg_x,nil_value))
    897         __(mov temp2,#unbound_marker)
    898         __(beq cr1,4f)
    899         __(_car(temp2,arg_z))
    900         __(_cdr(arg_z,arg_z))
    901 4:      __(push(temp3,imm2))
    902         __(push(imm0,imm2))
    903         __(push(imm1,imm2))
    904         __(strx(temp2,imm4,imm0))
    905         __(mov imm1,imm2)
    906         __(bne cr0,3b)
    907         __(str(imm2,tcr.db_link(rcontext)))
     248        __(jump_builtin(_builtin_ne,2))
     249
     250_spentry(builtin_gt)
     251        __(test_two_fixnums(arg_y,arg_z,imm0))
     252        __(bne 1f)
     253        __(cmp arg_y,arg_z)
     254        __(mov arg_z,#nil_value)
     255        __(addgt arg_z,arg_z,#t_offset)
    908256        __(bx lr)
     2571:
     258        __(jump_builtin(_builtin_gt,2))
    909259
    910        
    911 /* Allocate a miscobj on the temp stack.  (Push a frame on the tsp and  */
    912 /* heap-cons the object if there's no room on the tstack.)  */
    913 _spentry(stack_misc_alloc)
    914         __ifdef(`PPC64')
    915          __(extract_unsigned_byte_bits_(imm2,arg_y,56))
    916          __(unbox_fixnum(imm0,arg_z))
    917          __(clrldi imm2,imm0,64-nlowtagbits)
    918          __(extract_fulltag(imm1,imm0))
    919          __(bne cr0,9f)
    920          __(cmpdi cr2,imm2,lowtag_nodeheader)
    921          __(cmpdi cr4,imm1,ivector_class_8_bit)
    922          __(cmpdi cr1,imm1,ivector_class_64_bit)
    923          __(cmpdi cr3,imm1,ivector_class_32_bit)
    924          __(cmpdi cr5,imm1,ivector_class_other_bit)
    925          __(sldi imm1,arg_y,num_subtag_bits-fixnumshift)
    926          __(mov imm2,arg_y)
    927          __(beq cr2,3f)
    928          __(cmpdi cr2,imm0,subtag_bit_vector)
    929          __(beq cr1,3f)
    930          __(beq cr3,1f)
    931          __(beq cr4,2f)
    932          __(beq cr2,0f)
    933          /* 2 bytes per element  */
    934          __(srdi imm2,imm2,2)
    935          __(b 3f)
    936 0:       /* bit-vector case  */
    937          __(addi imm2,imm2,7<<fixnumshift)
    938          __(srdi imm2,imm2,3+fixnumshift)
    939          __(b 3f)       
    940          /* 4 bytes per element  */
    941 1:       __(srdi imm2,imm2,1)
    942          __(b 3f)
    943 2:       /* 1 byte per element  */
    944          __(srdi imm2,imm2,3)
    945 3:       /* 8 bytes per element  */
    946          __(or imm0,imm1,imm0)   /* imm0 = header, imm2 = byte count  */
    947          __(dnode_align(imm3,imm2,tsp_frame.fixed_overhead+node_size))
    948          __(cmpldi cr0,imm3,tstack_alloc_limit) /* more than limit ?  */
    949          __(bgt- cr0,4f)
    950          __(TSP_Alloc_Var_Boxed_nz(imm3,imm4))
    951         /* Slap the header on the vector, then return.  */
    952          __(str(imm0,tsp_frame.data_offset(tsp)))
    953          __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
     260_spentry(builtin_ge)
     261        __(test_two_fixnums(arg_y,arg_z,imm0))
     262        __(bne 1f)
     263        __(cmp arg_y,arg_z)
     264        __(mov arg_z,#nil_value)
     265        __(addge arg_z,arg_z,#t_offset)
    954266        __(bx lr)
    955         /* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
    956         /* sure that there's an empty tsp frame to keep the compiler happy.  */
    957 4:       __(TSP_Alloc_Fixed_Unboxed(0))
    958          __(b _SPmisc_alloc)
    959         __else
    960          __(rlwinm. imm2,arg_y,32-fixnumshift,0,(8+fixnumshift)-1)
    961          __(unbox_fixnum(imm0,arg_z))
    962          __(extract_fulltag(imm1,imm0))
    963          __(bne- cr0,9f)
    964          __(cmpri(cr0,imm1,fulltag_nodeheader))
    965          __(mov imm3,imm0)
    966          __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
    967          __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits) /* imm0 now = header  */
    968          __(mov imm2,arg_y)
    969          __(beq cr0,1f) /* do probe if node object  */
    970                         /* (fixnum element count = byte count).  */
    971          __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
    972          __(bng cr1,1f) /* do probe if 32-bit imm object  */
    973          __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
    974          __(srwi imm2,imm2,1)
    975          __(bgt cr0,3f)
    976          __(bgt cr1,1f)
    977          __(srwi imm2,imm2,1)
    978 /* imm2 now = byte count.  Add 4 for header, 7 to align, then  */
    979 /*      clear low three bits.  */
    9802671:
    981          __(dnode_align(imm3,imm2,tsp_frame.fixed_overhead+node_size))
    982          __(cmplri(cr0,imm3,tstack_alloc_limit)) /* more than limit ?  */
    983          __(bgt- cr0,0f)
    984          __(TSP_Alloc_Var_Boxed_nz(imm3,imm4))
     268        __(jump_builtin(_builtin_ge,2))
    985269
    986 /* Slap the header on the vector, then return.  */
    987          __(str(imm0,tsp_frame.data_offset(tsp)))
    988          __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    989          __(bx lr)
    990 9:
     270_spentry(builtin_lt)
     271        __(test_two_fixnums(arg_y,arg_z,imm0))
     272        __(bne 1f)
     273        __(cmp arg_y,arg_z)
     274        __(mov arg_z,#nil_value)
     275        __(addgt arg_z,arg_z,#t_offset)
     276        __(bx lr)
     2771:
     278        __(jump_builtin(_builtin_lt,2))
    991279
     280_spentry(builtin_le)
     281        __(test_two_fixnums(arg_y,arg_z,imm0))
     282        __(bne 1f)
     283        __(cmp arg_y,arg_z)
     284        __(mov arg_z,#nil_value)
     285        __(addle arg_z,arg_z,#t_offset)
     286        __(bx lr)
     2871:
     288        __(jump_builtin(_builtin_le,2))
    992289
     290/* funcall nfn, returning multiple values if it does.  */
     291_spentry(mvpass)
     292        __(subs imm0,nargs,#node_size*nargregs)
     293        __(movge imm0,#0)
     294        __(add imm0,vsp,imm0)
     295        __(build_lisp_frame(temp1,imm0))
     296        __(adr lr,C(ret1valn))
     297        __(mov fn,#0)
     298        __(funcall_nfn())
    993299
    994 /* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
    995 /* sure that there's an empty tsp frame to keep the compiler happy.  */
    996 0:
    997          __(TSP_Alloc_Fixed_Unboxed(0))
    998          __(b _SPmisc_alloc)
    999 3:
    1000          __(cmplri(imm3,subtag_double_float_vector))
    1001          __(slwi imm2,arg_y,1)
    1002          __(beq 1b)
    1003          __(addi imm2,arg_y,7<<fixnumshift)
    1004          __(srwi imm2,imm2,fixnumshift+3)
    1005          __(b 1b)
    1006         __endif
    1007        
    1008 /* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
    1009 /* initial-contents.  Note that this can be used to cons any type of initialized  */
    1010 /* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
    1011 /* objects.  */
    1012 /* Note that we're guaranteed to win (or force GC, or run out of memory)  */
    1013 /* because nargs < 32K.  */
    1014 _spentry(gvector)
    1015         __(subi nargs,nargs,node_size)
    1016         __(ldrx(arg_z,vsp,nargs))
    1017         __(unbox_fixnum(imm0,arg_z))
    1018         __ifdef(`PPC64')
    1019          __(sldi imm1,nargs,num_subtag_bits-fixnum_shift)
    1020          __(or imm0,imm0,imm1)
    1021         __else
    1022          __(rlwimi imm0,nargs,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits)
    1023         __endif
    1024         __(dnode_align(imm1,nargs,node_size))
    1025         __(Misc_Alloc(arg_z,imm0,imm1))
    1026         __(mov imm1,nargs)
    1027         __(la imm2,misc_data_offset(imm1))
    1028         __(b 2f)
    1029 1:
    1030         __(strx(temp0,arg_z,imm2))
    1031 2:
    1032         __(subi imm1,imm1,node_size)
    1033         __(cmpri(cr0,imm1,0))
    1034         __(subi imm2,imm2,node_size)
    1035         __(vpop(temp0))         /* Note the intentional fencepost: */
    1036                                 /* discard the subtype as well.  */
    1037         __(bge cr0,1b)
    1038         __(bx lr)
    1039        
    1040        
    1041 /* funcall temp0, returning multiple values if it does.  */
    1042 _spentry(mvpass)
    1043         __(cmpri(cr0,nargs,node_size*nargregs))
    1044         __(mflr loc_pc)
    1045         __(mov imm0,vsp)
    1046         __(ble+ cr0,1f)
    1047          __(subi imm0,imm0,node_size*nargregs)
    1048          __(add imm0,imm0,nargs)
    1049 1:
    1050         __(build_lisp_frame(fn,loc_pc,imm0))
    1051         __(ref_global(loc_pc,ret1val_addr))
    1052         __(mov fn,#0)
    1053         __(mtlr loc_pc)
    1054         __(do_funcall())
    1055        
    1056300/* ret1valn returns "1 multiple value" when a called function does not  */
    1057301/* return multiple values.  Its presence on the stack (as a return address)  */
     
    1059303
    1060304_exportfn(C(ret1valn))
    1061         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    1062         __(ldr vsp,[sp,#lisp_frame.savevsp])
    1063         __(mtlr loc_pc)
    1064         __(ldr fn,[sp,#lisp_frame.savefn])
    1065         __(discard_lisp_frame())
     305        __(restore_lisp_frame(imm0))
    1066306        __(vpush1(arg_z))
    1067307        __(set_nargs(1))
    1068308        __(bx lr)
    1069        
    1070 _spentry(fitvals)
    1071         __(subf. imm0,nargs,imm0)
    1072         __(mov imm1,#nil_value)
    1073         __(bge 2f)
    1074         __(sub vsp,vsp,imm0)
    1075         __(bx lr)
    1076 1:
    1077         __(subic. imm0,imm0,node_size)
    1078         __(vpush1(imm1))
    1079         __(addi nargs,nargs,node_size)
    1080 2:
    1081         __(bne 1b)
    1082         __(bx lr)
    1083 
    1084 
    1085 _spentry(nthvalue)
    1086         __(add imm0,vsp,nargs)
    1087         __(ldr imm1,[imm0,#0])
    1088         __(cmplr(imm1,nargs))   /*  do unsigned compare:         if (n < 0) => nil.  */
    1089         __(mov arg_z,#nil_value)
    1090         __(neg imm1,imm1)
    1091         __(subi imm1,imm1,node_size)
    1092         __(bge 1f)
    1093         __(ldrx(arg_z,imm0,imm1))
    1094 1:     
    1095         __(la vsp,node_size(imm0))
    1096         __(bx lr)
    1097        
    1098309
    1099310/* Come here to return multiple values when  */
     
    1102313
    1103314_spentry(values)
    1104         __(mflr loc_pc)
    1105315local_label(return_values): 
    1106316        __(ref_global(imm0,ret1val_addr))
    1107317        __(mov arg_z,#nil_value)
    1108         /* max tsp frame is 4K. 8+8 is overhead for save_values_to_tsp below  */
    1109         /* and @do_unwind in nthrowvalues in "sp_catch.s".  */
    1110         __(cmpri(cr2,nargs,4096-(dnode_size+dnode_size)))
    1111         __(cmpr(cr1,imm0,loc_pc))
    1112         __(cmpri(cr0,nargs,fixnum_one))
    1113         __(bge cr2,2f)
    1114         __(beq+ cr1,3f)
    1115         __(mtlr loc_pc)
     318        __(cmp imm0,lr)
     319        __(beq 3f)
     320        __(cmp nargs,#fixnum_one)
    1116321        __(add imm0,nargs,vsp)
    1117         __(blt- cr0,1f)
    1118         __(ldr arg_z,[imm0,#-node_size])
    1119 1:
     322        __(ldrge arg_z,[imm0,#-node_size])
    1120323        __(mov vsp,temp0)
    1121324        __(bx lr)
    1122325
    1123 2:
    1124         __(uuo_interr(error_too_many_values,nargs))
    1125         __(b 2b)
    1126326
    1127327/* Return multiple values to real caller.  */
    11283283:
    1129         __(ldr loc_pc,[sp,#lisp_frame.savelr])
     329        __(ldr lr,[sp,#lisp_frame.savelr])
    1130330        __(add imm1,nargs,vsp)
    1131331        __(ldr imm0,[sp,#lisp_frame.savevsp])
    1132332        __(ldr fn,[sp,#lisp_frame.savefn])
    1133         __(cmpr(cr0,imm1,imm0)) /* a fairly common case  */
    1134         __(mtlr loc_pc)
    1135         __(cmpri(cr1,nargs,fixnum_one)) /* sadly, a very common case  */
     333        __(cmp imm1,imm0) /* a fairly common case  */
    1136334        __(discard_lisp_frame())
    1137         __(beqlr cr0) /* already in the right place  */
    1138         __(bne cr1,4f)
     335        __(bxeq lr) /* already in the right place  */
     336        __(cmp nargs,#fixnum_one) /* sadly, a very common case  */
     337        __(bne 4f)
    1139338         __(ldr arg_z,[vsp,#0])
    1140339         __(mov vsp,imm0)
     
    1142341         __(bx lr)
    11433424:
    1144         __(blt cr1,6f)
    1145         __(mov imm2,#fixnum_one)
     343        __(blt 6f)
     344        __(mov temp1,#fixnum_one)
    11463455:
    1147         __(cmpr(cr0,imm2,nargs))
    1148         __(addi imm2,imm2,fixnum_one)
    1149         __(ldru(arg_z,-node_size(imm1)))
    1150         __(push(arg_z,imm0))
    1151         __(bne cr0,5b)
     346        __(cmp temp1,nargs)
     347        __(add temp1,temp1,#fixnum_one)
     348        __(ldr arg_z,[imm1,#-node_size]!)
     349        __(push1(imm0,arg_z))
     350        __(bne 5b)
    11523516:
    1153352        __(mov vsp,imm0)
    1154353        __(bx lr)
    1155354
    1156         .globl C(nvalret)
    1157355       
    1158356/* Come here with saved context on top of stack.  */
    1159357_spentry(nvalret)
     358        .globl C(nvalret)
    1160359C(nvalret):     
    1161         __(ldr loc_pc,[sp,#lisp_frame.savelr])
     360        __(ldr lr,[sp,#lisp_frame.savelr])
    1162361        __(ldr temp0,[sp,#lisp_frame.savevsp])
    1163362        __(ldr fn,[sp,#lisp_frame.savefn])
    1164363        __(discard_lisp_frame())
    1165364        __(b local_label(return_values))
    1166                
    1167 /* Provide default (NIL) values for &optional arguments; imm0 is  */
    1168 /* the (fixnum) upper limit on the total of required and &optional  */
    1169 /* arguments.  nargs is preserved, all arguments wind up on the  */
    1170 /* vstack.  */
    1171 _spentry(default_optional_args)
    1172         __(cmplr( cr7,nargs,imm0))
    1173         __(mov imm5,#nil_value)
    1174         __(vpush_argregs())
    1175         __(mov imm1,nargs)
    1176         __(bgelr cr7)
    1177 1:     
    1178         __(addi imm1,imm1,fixnum_one)
    1179         __(cmpr(cr0,imm1,imm0))
    1180         __(vpush1(imm5))
    1181         __(bne cr0,1b)
    1182         __(bx lr)
     365                                               
    1183366       
    1184 /* Indicate whether &optional arguments were actually supplied.  nargs  */
    1185 /* contains the actual arg count (minus the number of required args);  */
    1186 /* imm0 contains the number of &optional args in the lambda list.  */
    1187 /* Note that nargs may be > imm0 if &rest/&key is involved.  */
    1188 _spentry(opt_supplied_p)
    1189         __(mov imm1,#0)
    1190 1:
    1191         /* (vpush (< imm1 nargs))  */
    1192         __ifdef(`PPC64')
    1193          __(xor imm2,imm1,nargs)
    1194          __(sradi imm2,imm2,63)
    1195          __(or imm2,imm2,imm1)
    1196          __(addi imm1,imm1,fixnumone)
    1197          __(cmpr(cr0,imm1,imm0))
    1198          __(subf imm2,nargs,imm2)
    1199          __(srdi imm2,imm2,63)
    1200          __(mulli imm2,imm2,t_offset)
    1201          __(addi imm2,imm2,nil_value)
    1202          __(vpush1(imm2))
    1203          __(bne cr0,1b)
    1204          __(bx lr)
    1205         __else
    1206          __(xor imm2,imm1,nargs)
    1207          __(srawi imm2,imm2,31)
    1208          __(or imm2,imm2,imm1)
    1209          __(addi imm1,imm1,fixnumone)
    1210          __(cmpr(cr0,imm1,imm0))
    1211          __(subf imm2,nargs,imm2)
    1212          __(srwi imm2,imm2,31)
    1213          __(insrwi imm2,imm2,1,27)
    1214          __(addi imm2,imm2,nil_value)
    1215          __(vpush1(imm2))
    1216          __(bne cr0,1b)
    1217          __(bx lr)
    1218         __endif
    1219        
    1220 
    1221 
    1222 /* If nargs is <= imm0, vpush a nil.  Otherwise, cons a list of length  */
    1223 /* (- nargs imm0) and vpush it.  */
    1224 /* Use this entry point to heap-cons a simple &rest arg.  */
    1225 _spentry(heap_rest_arg)
    1226         __(mov imm0,#0)
    1227         __(vpush_argregs())
    1228         __(sub imm1,nargs,imm0)
    1229         __(cmpri(imm1,0))
    1230         __(mov arg_z,#nil_value)
    1231         __(b 2f)
    1232 1:
    1233         __(ldr temp0,[vsp,#0])
    1234         __(cmpri(imm1,fixnum_one))
    1235         __(la vsp,node_size(vsp))
    1236         __(Cons(arg_z,temp0,arg_z))
    1237         __(subi imm1,imm1,fixnum_one)
    1238 2:
    1239         __(bgt 1b)
    1240         __(vpush1(arg_z))
    1241         __(bx lr)
    1242 
    1243        
    1244 /* And this entry point when the argument registers haven't yet been  */
    1245 /* vpushed (as is typically the case when required/&rest but no  */
    1246 /* &optional/&key.)  */
    1247 _spentry(req_heap_rest_arg)
    1248         __(vpush_argregs())
    1249         __(sub imm1,nargs,imm0)
    1250         __(cmpri(imm1,0))
    1251         __(mov arg_z,#nil_value)
    1252         __(b 2f)
    1253 1:
    1254         __(ldr temp0,[vsp,#0])
    1255         __(cmpri(imm1,fixnum_one))
    1256         __(la vsp,node_size(vsp))
    1257         __(Cons(arg_z,temp0,arg_z))
    1258         __(subi imm1,imm1,fixnum_one)
    1259 2:
    1260         __(bgt 1b)
    1261         __(vpush1(arg_z))
    1262         __(bx lr)
    1263 
    1264 
    1265 _spentry(heap_cons_rest_arg)
    1266         __(sub imm1,nargs,imm0)
    1267         __(cmpri(imm1,0))
    1268         __(mov arg_z,#nil_value)
    1269         __(b 2f)
    1270 1:
    1271         __(ldr temp0,[vsp,#0])
    1272         __(cmpri(imm1,fixnum_one))
    1273         __(la vsp,node_size(vsp))
    1274         __(Cons(arg_z,temp0,arg_z))
    1275         __(subi imm1,imm1,fixnum_one)
    1276 2:
    1277         __(bgt 1b)
    1278         __(vpush1(arg_z))
    1279         __(bx lr)
    1280 
    1281        
    1282 _spentry(simple_keywords)
    1283         __(mov imm0,#0)
    1284         __(vpush_argregs())
    1285         __(b _SPkeyword_bind)
    1286                
    1287 _spentry(keyword_args)
    1288         __(vpush_argregs())
    1289         __(b _SPkeyword_bind)
    1290 
    1291 /* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
    1292 /* pairs.  There'll be imm3 keyword arguments.  Imm2 contains flags  */
    1293 /* that indicate whether &allow-other-keys was specified and whether  */
    1294 /* or not to leave the keyword/value pairs on the vstack for an &rest  */
    1295 /* argument.  Temp3 contains a vector of keyword specifiers which we  */
    1296 /* must (in general) match.  */
    1297 /* If the number of arguments is greater than imm0, the difference must  */
    1298 /* be even.  */
    1299 /* Note that the caller hasn't yet saved its caller's context and that  */
    1300 /* the temp registers used to pass next_method_context  */
    1301 /* (temp1) may still have "live" values in them, as does nfn (temp2).  */
    1302 
    1303 define(`keyword_flags',`imm2')
    1304 define(`keyword_vector',`temp3')
    1305 define(`keyword_count',`imm3')
    1306 
    1307 
    1308 
    1309 define(`varptr',`save0')
    1310 define(`valptr',`save1')
    1311 define(`limit',`save2')
    1312 
    1313 _spentry(keyword_bind)
    1314         /* Before we can really do anything, we have to  */
    1315         /* save the caller's context.  To do so, we need to know  */
    1316         /* how many args have actually been pushed.  Ordinarily, that'd  */
    1317         /* be "nargs", but we may have pushed more args than we received  */
    1318         /* if we had to default any &optionals.  */
    1319         /* So, the number of args pushed so far is the larger of nargs  */
    1320         /* and the (canonical) total of required/&optional args received.  */
    1321         __(cmpr(cr0,nargs,imm0))
    1322         __(add arg_z,vsp,nargs)
    1323         __(bge+ cr0,1f)
    1324         __(add arg_z,vsp,imm0)
    1325 1:
    1326         __(build_lisp_frame(fn,loc_pc,arg_z))
    1327         __(mov fn,nfn)
    1328         /* If there are key/value pairs to consider, we slide them down  */
    1329         /* the vstack to make room for the value/supplied-p pairs.  */
    1330         /* The first step in that operation involves pushing imm3 pairs  */
    1331         /* of NILs.  */
    1332         /* If there aren't any such pairs, the first step is the last  */
    1333         /* step.  */
    1334         __(cmpri(cr0,imm3,0))
    1335         __(mov arg_z,#0)
    1336         __(sub imm1,nargs,imm0)
    1337         __(mov imm4,vsp)        /* in case odd keywords error  */
    1338         __(cmpri(cr1,imm1,0))
    1339         __(b 3f)
    1340 2:
    1341         __(addi arg_z,arg_z,fixnum_one)
    1342         __(cmplr(cr0,arg_z,imm3))
    1343         __(mov imm5,#nil_value)
    1344         __(vpush1(imm5))
    1345         __(vpush1(imm5))
    1346 3:
    1347         __(bne cr0,2b)
    1348         __(andi. arg_z,imm1,fixnum_one)
    1349         __(blelr cr1)   /* no keyword/value pairs to consider.  */
    1350         __(bne cr0,odd_keywords)
    1351         /* We have key/value pairs.  Move them to the top of the vstack,  */
    1352         /* then set the value/supplied-p vars to NIL.  */
    1353         /* Have to use some save regs to do this.  */
    1354         __(vpush1(limit))
    1355         __(vpush1(valptr))
    1356         __(vpush1(varptr))
    1357         /* recompute ptr to user args in case stack overflowed  */
    1358         __(add imm4,vsp,imm3)
    1359         __(add imm4,imm4,imm3)
    1360         __(addi imm4,imm4,3*node_size)
    1361         /* error if odd number of keyword/value args  */
    1362         __(mov varptr,imm4)
    1363         __(la limit,3*node_size(vsp))
    1364         __(mov valptr,limit)
    1365         __(mov arg_z,imm1)
    1366 4:
    1367         __(mov imm4,#nil_value)
    1368         __(subi arg_z,arg_z,2<<fixnumshift)
    1369         __(cmplri(cr0,arg_z,0))
    1370         __(ldr arg_x,[varptr,#node_size*0])
    1371         __(ldr arg_y,[varptr,#node_size*1])
    1372         __(str(imm4,node_size*0(varptr)))
    1373         __(str(imm4,node_size*1(varptr)))
    1374         __(la varptr,node_size*2(varptr))
    1375         __(str(arg_x,node_size*0(valptr)))
    1376         __(str(arg_y,node_size*1(valptr)))
    1377         __(la valptr,node_size*2(valptr))
    1378         __(bne cr0,4b)
    1379 
    1380 
    1381         /* Now, iterate through each supplied keyword/value pair.  If  */
    1382         /* it's :allow-other-keys and the corresponding value is non-nil,  */
    1383         /* note that other keys will be allowed.  */
    1384         /* Find its position in the function's keywords vector.  If that's  */
    1385         /* nil, note that an unknown keyword was encountered.  */
    1386         /* Otherwise, if the keyword arg hasn't already had a value supplied,  */
    1387         /* supply it.  */
    1388         /* When done, complain if any unknown keywords were found and that  */
    1389         /* situation was unexpected.  */
    1390         __(mov imm4,valptr)
    1391 5:
    1392         __(cmpri(cr0,keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
    1393         __(ldru(arg_z,-node_size(valptr)))
    1394         __(ldru(arg_y,-node_size(valptr)))
    1395         __(cmpri(cr1,arg_y,nil_value))
    1396         __(mov arg_x,#nrs.kallowotherkeys)
    1397         /* cr6_eq <- (eq current-keyword :allow-other-keys)  */
    1398         __(cmpr(cr6,arg_x,arg_z))
    1399         __(cmpr(cr7,valptr,limit))
    1400         __(bne cr6,6f)
    1401         __(bge cr0,6f) /* Already seen :allow-other-keys  */
    1402         __(ori keyword_flags,keyword_flags,16<<fixnumshift)
    1403         __(beq cr1,6f)
    1404         __(ori keyword_flags,keyword_flags,fixnum_one)
    1405 6:
    1406         __(cmpri(cr1,imm3,0))
    1407         __(mov imm1,#misc_data_offset)
    1408         __(mov imm0,#0)
    1409         __(b 8f)
    1410 7:
    1411         __(addi imm0,imm0,fixnum_one)
    1412         __(cmpr(cr1,imm0,imm3))
    1413         __(ldrx(arg_x,keyword_vector,imm1))
    1414         __(cmpr(cr0,arg_x,arg_z))
    1415         __(addi imm1,imm1,fixnum_one)
    1416         __(bne cr0,8f)
    1417         __(add imm0,imm0,imm0)
    1418         __(sub imm0,varptr,imm0)
    1419         __(ldr arg_x,[imm0,#0])
    1420         __(cmpri(cr0,arg_x,nil_value))
    1421         __(mov arg_z,#t_value)
    1422         __(bne cr0,9f)
    1423         __(str(arg_y,node_size(imm0)))
    1424         __(str(arg_z,0(imm0)))
    1425         __(b 9f)
    1426 8:
    1427         __(bne cr1,7b)
    1428         /* Unknown keyword. If it was :allow-other-keys, cr6_eq will still */
    1429         /* be set.  */
    1430         __(beq cr6,9f)
    1431         __(ori keyword_flags,keyword_flags,2<<fixnumshift)
    1432 9:
    1433         __(bne cr7,5b)
    1434         __(vpop(varptr))
    1435         __(vpop(valptr))
    1436         __(vpop(limit))
    1437         /* All keyword/value pairs have been processed.  */
    1438         /* If we saw an unknown keyword and didn't expect to, error.  */
    1439         /* Unless bit 2 is set in the fixnum in keyword_flags, discard the  */
    1440         /* keyword/value pairs from the vstack.  */
    1441         __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift))
    1442         __(cmpri(cr0,imm0,2<<fixnumshift))
    1443         __(beq- cr0,badkeys)
    1444         __(andi. imm2,keyword_flags,4<<fixnumshift)
    1445         __(bnelr cr0)
    1446         __(mov vsp,imm4)
    1447         __(bx lr)
    1448 
    1449 /* Signal an error.  We saved context on entry, so this thing doesn't  */
    1450 /* have to.  */
    1451 /* The "unknown keywords" error could be continuable (ignore them.)  */
    1452 /* It might be hard to then cons an &rest arg.  */
    1453 /* In the general case, it's hard to recover the set of args that were  */
    1454 /* actually supplied to us ...  */
    1455 /* For now, just cons a list out of the keyword/value pairs */
    1456 /* that were actually provided, and signal an "invalid keywords" */
    1457 /* error with that list as an operand.  */
    1458 odd_keywords:
    1459         __(mov vsp,imm4)
    1460         __(mov nargs,imm1)
    1461         __(b 1f)
    1462 badkeys:
    1463         __(sub nargs,imm4,vsp)
    1464 1:
    1465         __(bl _SPconslist)
    1466         __(mov arg_y,#XBADKEYS)
    1467         __(set_nargs(2))
    1468         __(b _SPksignalerr)
    1469 
    1470 /*  A PowerOpen ff-call.  arg_z is either a fixnum (word-aligned entrypoint) */
    1471 /*  or a macptr (whose address had better be word-aligned as well.)  A */
    1472 /*  PowerOpen stack frame is on top of the stack; 4 additional words (to */
    1473 /*  be used a a lisp frame) sit under the C frame. */
    1474 
    1475 /*  Since we probably can't deal with FP exceptions in foreign code, we */
    1476 /*  disable them in the FPSCR, then check on return to see if any previously */
    1477 /*  enabled FP exceptions occurred. */
    1478 
    1479 /*  As it turns out, we can share a lot of code with the eabi version of */
    1480 /*  ff-call.  Some things that happen up to the point of call differ between */
    1481 /*  the ABIs, but everything that happens after is the same. */
    1482 
    1483        
    1484 _spentry(poweropen_ffcall)
    1485 LocalLabelPrefix`'ffcall:               
    1486         __(mflr loc_pc)
    1487         __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
    1488         __(mov save0,rcontext)  /* or address globals.  */
    1489         __(extract_typecode(imm0,arg_z))
    1490         __(cmpri(cr7,imm0,subtag_macptr))
    1491         __(ldr save1,[sp,#0])   /* bottom of reserved lisp frame  */
    1492         __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
    1493         __(zero_doublewords save2,0,lisp_frame.size)
    1494         __(str(save1,lisp_frame.backlink(save2)))
    1495         __(str(save2,c_frame.backlink(sp)))
    1496         __(str(fn,lisp_frame.savefn(save2)))
    1497         __(str(loc_pc,lisp_frame.savelr(save2)))
    1498         __(str(vsp,lisp_frame.savevsp(save2)))
    1499         __(mov nargs,arg_z)
    1500         __(bne cr7,1f)
    1501         __(ldr nargs,[arg_z,#macptr.address])
    1502 1:
    1503         __(ldr save3,[rcontext,#tcr.cs_area])
    1504         __(str(save2,area.active(save3)))
    1505         __(str(allocptr,tcr.save_allocptr(rcontext)))
    1506         __(str(allocbase,tcr.save_allocbase(rcontext)))
    1507         __(str(tsp,tcr.save_tsp(rcontext)))
    1508         __(str(vsp,tcr.save_vsp(rcontext)))
    1509         __(str(rzero,tcr.ffi_exception(rcontext)))
    1510         __(mffs f0)
    1511         __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
    1512         __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
    1513         __(mov r4,#TCR_STATE_FOREIGN)
    1514         __(str(r4,tcr.valence(rcontext)))
    1515         __ifdef(`rTOC')
    1516          __(ld rTOC,8(nargs))
    1517          __(ld nargs,0(nargs))
    1518         __else
    1519          __(mov rcontext,#0)
    1520         __endif
    1521 LocalLabelPrefix`'ffcall_setup:
    1522         __(mtctr nargs)
    1523         __(ldr r3,[sp,#c_frame.param0])
    1524         __(ldr r4,[sp,#c_frame.param1])
    1525         __(ldr r5,[sp,#c_frame.param2])
    1526         __(ldr r6,[sp,#c_frame.param3])
    1527         __(ldr r7,[sp,#c_frame.param4])
    1528         __(ldr r8,[sp,#c_frame.param5])
    1529         __(ldr r9,[sp,#c_frame.param6])
    1530         __(ldr r10,[sp,#c_frame.param7])
    1531         /* Darwin is allegedly very picky about what register points */
    1532         /* to the function on entry.  */
    1533         __(mov r12,nargs)
    1534 LocalLabelPrefix`'ffcall_setup_end:
    1535 LocalLabelPrefix`'ffcall_call:
    1536         __(bctrl)
    1537 LocalLabelPrefix`'ffcall_call_end:
    1538         /* C should have preserved save0 (= rcontext) for us.  */
    1539         __(ldr sp,[sp,#0])
    1540         __(mov imm2,save0)
    1541         __(ldr vsp,[sp,#lisp_frame.savevsp])
    1542         __(mov rzero,#0)
    1543         __(mov loc_pc,rzero)
    1544         __(mov arg_x,#nil_value)
    1545         __(mov arg_y,#nil_value)
    1546         __(mov arg_z,#nil_value)
    1547         __(mov temp0,#nil_value)
    1548         __(mov temp1,#nil_value)
    1549         __(mov temp2,#nil_value)
    1550         __(mov temp3,#nil_value)
    1551         __(mov fn,#nil_value)
    1552         __(mov rcontext,imm2)
    1553         __(mov imm2,#TCR_STATE_LISP)
    1554         __(ldr tsp,[rcontext,#tcr.save_tsp])
    1555         __(mov save0,#0)
    1556         __(mov save1,#0)
    1557         __(mov save2,#0)
    1558         __(mov save3,#0)
    1559         __(mov save4,#0)
    1560         __(mov save5,#0)
    1561         __(mov save6,#0)
    1562         __(mov save7,#0)
    1563         __(mov allocptr,#-dnode_size)
    1564         __(mov allocbase,#-dnode_size)
    1565         __(str(imm2,tcr.valence(rcontext)))     
    1566         __(vpop_saveregs())
    1567         __(ldr allocptr,[rcontext,#tcr.save_allocptr])
    1568         __(ldr allocbase,[rcontext,#tcr.save_allocbase])
    1569         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    1570         __(mtlr loc_pc)
    1571         __(ldr fn,[sp,#lisp_frame.savefn])
    1572         __(mffs f0)
    1573         __(stfd f0,8(sp))
    1574         __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
    1575         __(clrrwi imm2,imm3,8)
    1576         __(discard_lisp_frame())
    1577         __(str(imm2,tcr.ffi_exception(rcontext)))
    1578         __(lfd f0,tcr.lisp_fpscr(rcontext))
    1579         __(mtfsf 0xff,f0)
    1580         __(check_pending_interrupt(`cr1'))
    1581         __(mtxer rzero)
    1582         __(mtctr rzero)
    1583         __ifdef(`PPC64')
    1584          __ifdef(`DARWIN')
    1585           __(mov imm3,#1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
    1586           __(ld imm4,tcr.flags(rcontext))
    1587           __(and. imm3,imm3,imm4)
    1588           __(bne cr0,0f)
    1589          __endif
    1590         __endif
    1591         __(bx lr)
    1592         __ifdef(`PPC64')
    1593          __ifdef(`DARWIN')
    1594 0:        /* Got here because TCR_FLAG_BIT_FOREIGN_EXCEPTION */
    1595           /* was set in tcr.flags.  Clear that bit. */
    1596           __(andc imm4,imm4,imm3)
    1597           __(std imm4,tcr.flags(rcontext))
    1598           /* Unboxed foreign exception (likely an NSException) in %imm0. */
    1599           /* Box it, then signal a lisp error. */
    1600           __(mov imm1,#macptr_header)
    1601           __(Misc_Alloc_Fixed(arg_z,imm1,macptr.size))
    1602           __(std imm0,macptr.address(arg_z))
    1603           __(mov arg_y,#XFOREIGNEXCEPTION)
    1604           __(set_nargs(2))
    1605           __(b _SPksignalerr)
    1606         /* Handle exceptions, for ObjC 2.0 */
    1607 LocalLabelPrefix`'ffcallLandingPad:     
    1608           __(mov save1,r3)
    1609           __(cmpdi r4,1)
    1610           __(beq 1f)
    1611 LocalLabelPrefix`'ffcallUnwindResume:
    1612           __(ref_global(r12,unwind_resume))
    1613           __(mtctr r12)
    1614           __(bctrl)
    1615 LocalLabelPrefix`'ffcallUnwindResume_end:         
    1616 1:        __(mov r3,save1)
    1617 LocalLabelPrefix`'ffcallBeginCatch:
    1618           __(ref_global(r12,objc2_begin_catch))
    1619           __(mtctr r12)
    1620           __(bctrl)
    1621 LocalLabelPrefix`'ffcallBeginCatch_end:         
    1622           __(ld save1,0(r3)) /* indirection is necessary because we don't provide type info in lsda */
    1623 LocalLabelPrefix`'ffcallEndCatch: 
    1624           __(ref_global(r12,objc2_end_catch))
    1625           __(mtctr r12)
    1626           __(bctrl)             
    1627 LocalLabelPrefix`'ffcallEndCatch_end:     
    1628           __(ref_global(r12,get_tcr))
    1629           __(mtctr r12)
    1630           __(mov imm0,#1)       
    1631           __(bctrl)
    1632           __(ld imm2,tcr.flags(imm0))
    1633           __(ori imm2,imm2,1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
    1634           __(std imm2,tcr.flags(imm0))
    1635           __(mov imm0,save1)
    1636           __(b LocalLabelPrefix`'ffcall_call_end)
    1637 LocalLabelPrefix`'ffcall_end:   
    1638 
    1639                 .section __DATA,__gcc_except_tab
    1640           .align 3
    1641 LLSDA1:
    1642           .byte 0xff    /* @LPStart format (omit) */
    1643           .byte 0x0     /* @TType format (absolute) */
    1644           .byte 0x4d    /* uleb128 0x4d; @TType base offset */
    1645           .byte 0x3     /* call-site format (udata4) */
    1646           .byte 0x41    /* uleb128 0x41; Call-site table length */
    1647        
    1648           .long Lffcall_setup-Lffcall   /* region 0 start */
    1649           .long Lffcall_setup_end-Lffcall_setup /* length */
    1650           .long 0x0     /* landing pad */
    1651           .byte 0x0     /* uleb128 0x0; action */
    1652        
    1653           .long Lffcall_call-Lffcall    /* region 1 start */
    1654           .long Lffcall_call_end-Lffcall_call   /* length */
    1655           .long LffcallLandingPad-Lffcall       /* landing pad */
    1656           .byte 0x1     /* uleb128 0x1; action */
    1657        
    1658           .long LffcallUnwindResume-Lffcall     /* region 2 start */
    1659           .long LffcallUnwindResume_end-LffcallUnwindResume     /* length */
    1660           .long 0x0     /* landing pad */
    1661           .byte 0x0     /* uleb128 0x0; action */
    1662        
    1663           .long LffcallBeginCatch-Lffcall       /* region 3 start */
    1664           .long LffcallBeginCatch_end-LffcallBeginCatch /* length */
    1665           .long 0       /* landing pad */
    1666           .byte 0x0     /* uleb128 0x0; action */
    1667        
    1668           .long LffcallEndCatch-Lffcall
    1669           .long LffcallEndCatch_end-LffcallEndCatch     /* length */
    1670           .long 0x0     /* landing pad */
    1671           .byte 0x0     /* uleb128 0x0; action */
    1672        
    1673           .byte 0x1     /* Action record table */
    1674           .byte 0x0
    1675           .align 3
    1676           .quad 0       /* _OBJC_EHTYPE_$_NSException */
    1677           .text
    1678          __endif
    1679         __endif
    1680 
    1681 /* Just like poweropen_ffcall, only we save all argument(result)
    1682    registers in a buffer passed in arg_y on entry before returning
    1683    to lisp.  (We have to do this in the ffcall glue here, because
    1684    r9 and r10 - at least - are overloaded as dedicated lisp registers */
    1685 _spentry(poweropen_ffcall_return_registers)
    1686 LocalLabelPrefix`'ffcall_return_registers:               
    1687         __(mflr loc_pc)
    1688         __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
    1689         __(ldr save7,[arg_y,#macptr.address])
    1690         __(mov save0,rcontext)  /* or address globals.  */
    1691         __(extract_typecode(imm0,arg_z))
    1692         __(cmpri(cr7,imm0,subtag_macptr))
    1693         __(ldr save1,[sp,#0])   /* bottom of reserved lisp frame  */
    1694         __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
    1695         __(zero_doublewords save2,0,lisp_frame.size)
    1696         __(str(save1,lisp_frame.backlink(save2)))
    1697         __(str(save2,c_frame.backlink(sp)))
    1698         __(str(fn,lisp_frame.savefn(save2)))
    1699         __(str(loc_pc,lisp_frame.savelr(save2)))
    1700         __(str(vsp,lisp_frame.savevsp(save2)))
    1701         __(mov nargs,arg_z)
    1702         __(bne cr7,1f)
    1703         __(ldr nargs,[arg_z,#macptr.address])
    1704 1:
    1705         __(ldr save3,[rcontext,#tcr.cs_area])
    1706         __(str(save2,area.active(save3)))
    1707         __(str(allocptr,tcr.save_allocptr(rcontext)))
    1708         __(str(allocbase,tcr.save_allocbase(rcontext)))
    1709         __(str(tsp,tcr.save_tsp(rcontext)))
    1710         __(str(vsp,tcr.save_vsp(rcontext)))
    1711         __(str(rzero,tcr.ffi_exception(rcontext)))
    1712         __(mffs f0)
    1713         __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
    1714         __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
    1715         __(mov r4,#TCR_STATE_FOREIGN)
    1716         __(str(r4,tcr.valence(rcontext)))
    1717         __ifdef(`rTOC')
    1718          __(ld rTOC,8(nargs))
    1719          __(ld nargs,0(nargs))
    1720         __else
    1721          __(mov rcontext,#0)
    1722         __endif
    1723 LocalLabelPrefix`'ffcall_return_registers_setup:
    1724         __(mtctr nargs)
    1725         __(ldr r3,[sp,#c_frame.param0])
    1726         __(ldr r4,[sp,#c_frame.param1])
    1727         __(ldr r5,[sp,#c_frame.param2])
    1728         __(ldr r6,[sp,#c_frame.param3])
    1729         __(ldr r7,[sp,#c_frame.param4])
    1730         __(ldr r8,[sp,#c_frame.param5])
    1731         __(ldr r9,[sp,#c_frame.param6])
    1732         __(ldr r10,[sp,#c_frame.param7])
    1733         /* Darwin is allegedly very picky about what register points */
    1734         /* to the function on entry.  */
    1735         __(mov r12,nargs)
    1736 LocalLabelPrefix`'ffcall_return_registers_setup_end:
    1737 LocalLabelPrefix`'ffcall_return_registers_call:
    1738         __(bctrl)
    1739 LocalLabelPrefix`'ffcall_return_registers_call_end:
    1740         __(str(r3,0*node_size(save7)))       
    1741         __(str(r4,1*node_size(save7)))       
    1742         __(str(r5,2*node_size(save7)))       
    1743         __(str(r6,3*node_size(save7)))       
    1744         __(str(r7,4*node_size(save7)))       
    1745         __(str(r8,5*node_size(save7)))       
    1746         __(str(r9,6*node_size(save7)))       
    1747         __(str(r10,7*node_size(save7)))
    1748         __(stfd f1,((8*node_size)+(0*8))(save7))
    1749         __(stfd f2,((8*node_size)+(1*8))(save7))
    1750         __(stfd f3,((8*node_size)+(2*8))(save7))
    1751         __(stfd f4,((8*node_size)+(3*8))(save7))
    1752         __(stfd f5,((8*node_size)+(4*8))(save7))
    1753         __(stfd f6,((8*node_size)+(5*8))(save7))
    1754         __(stfd f7,((8*node_size)+(6*8))(save7))
    1755         __(stfd f8,((8*node_size)+(7*8))(save7))
    1756         __(stfd f9,((8*node_size)+(8*8))(save7))
    1757         __(stfd f10,((8*node_size)+(9*8))(save7))
    1758         __(stfd f11,((8*node_size)+(10*8))(save7))
    1759         __(stfd f12,((8*node_size)+(11*8))(save7))
    1760         __(stfd f13,((8*node_size)+(12*8))(save7))
    1761         /* C should have preserved save0 (= rcontext) for us.  */
    1762         __(ldr sp,[sp,#0])
    1763         __(mov imm2,save0)
    1764         __(ldr vsp,[sp,#lisp_frame.savevsp])
    1765         __(mov rzero,#0)
    1766         __(mov loc_pc,rzero)
    1767         __(mov arg_x,#nil_value)
    1768         __(mov arg_y,#nil_value)
    1769         __(mov arg_z,#nil_value)
    1770         __(mov temp0,#nil_value)
    1771         __(mov temp1,#nil_value)
    1772         __(mov temp2,#nil_value)
    1773         __(mov temp3,#nil_value)
    1774         __(mov fn,#nil_value)
    1775         __(mov rcontext,imm2)
    1776         __(mov imm2,#TCR_STATE_LISP)
    1777         __(ldr tsp,[rcontext,#tcr.save_tsp])
    1778         __(mov save0,#0)
    1779         __(mov save1,#0)
    1780         __(mov save2,#0)
    1781         __(mov save3,#0)
    1782         __(mov save4,#0)
    1783         __(mov save5,#0)
    1784         __(mov save6,#0)
    1785         __(mov save7,#0)
    1786         __(mov allocptr,#-dnode_size)
    1787         __(mov allocbase,#-dnode_size)
    1788         __(str(imm2,tcr.valence(rcontext)))     
    1789         __(vpop_saveregs())
    1790         __(ldr allocptr,[rcontext,#tcr.save_allocptr])
    1791         __(ldr allocbase,[rcontext,#tcr.save_allocbase])
    1792         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    1793         __(mtlr loc_pc)
    1794         __(ldr fn,[sp,#lisp_frame.savefn])
    1795         __(mffs f0)
    1796         __(stfd f0,8(sp))
    1797         __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
    1798         __(clrrwi imm2,imm3,8)
    1799         __(discard_lisp_frame())
    1800         __(str(imm2,tcr.ffi_exception(rcontext)))
    1801         __(lfd f0,tcr.lisp_fpscr(rcontext))
    1802         __(mtfsf 0xff,f0)
    1803         __(check_pending_interrupt(`cr1'))
    1804         __(mtxer rzero)
    1805         __(mtctr rzero)
    1806         __ifdef(`DARWIN')
    1807          __ifdef(`PPC64')
    1808           __(mov imm3,#1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
    1809           __(ld imm4,tcr.flags(rcontext))
    1810           __(and. imm3,imm3,imm4)
    1811           __(bne 0f)
    1812          __endif
    1813         __endif
    1814         __(bx lr)
    1815 
    1816         __ifdef(`DARWIN')
    1817          __ifdef(`PPC64')
    1818 0:        /* Got here because TCR_FLAG_BIT_FOREIGN_EXCEPTION */
    1819           /* was set in tcr.flags.  Clear that bit. */
    1820           __(andc imm4,imm4,imm3)
    1821           __(std imm4,tcr.flags(rcontext))
    1822           /* Unboxed foreign exception (likely an NSException) in %imm0. */
    1823           /* Box it, then signal a lisp error. */
    1824           __(mov imm1,#macptr_header)
    1825           __(Misc_Alloc_Fixed(arg_z,imm1,macptr.size))
    1826           __(std imm0,macptr.address(arg_z))
    1827           __(mov arg_y,#XFOREIGNEXCEPTION)
    1828           __(set_nargs(2))
    1829           __(b _SPksignalerr)
    1830         /* Handle exceptions, for ObjC 2.0 */
    1831 LocalLabelPrefix`'ffcall_return_registersLandingPad:     
    1832           __(mov save1,r3)
    1833           __(cmpdi r4,1)
    1834           __(beq 1f)
    1835 LocalLabelPrefix`'ffcall_return_registersUnwindResume:
    1836           __(ref_global(r12,unwind_resume))
    1837           __(mtctr r12)
    1838           __(bctrl)
    1839 LocalLabelPrefix`'ffcall_return_registersUnwindResume_end:         
    1840 1:        __(mov r3,save1)
    1841 LocalLabelPrefix`'ffcall_return_registersBeginCatch:
    1842           __(ref_global(r12,objc2_begin_catch))
    1843           __(mtctr r12)
    1844           __(bctrl)
    1845 LocalLabelPrefix`'ffcall_return_registersBeginCatch_end:         
    1846           __(ld save1,0(r3)) /* indirection is necessary because we don't provide type info in lsda */
    1847 LocalLabelPrefix`'ffcall_return_registersEndCatch: 
    1848           __(ref_global(r12,objc2_end_catch))
    1849           __(mtctr r12)
    1850           __(bctrl)             
    1851 LocalLabelPrefix`'ffcall_return_registersEndCatch_end:     
    1852           __(ref_global(r12,get_tcr))
    1853           __(mtctr r12)
    1854           __(mov imm0,#1)       
    1855           __(bctrl)
    1856           __(ld imm2,tcr.flags(imm0))
    1857           __(ori imm2,imm2,1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
    1858           __(std imm2,tcr.flags(imm0))
    1859           __(mov imm0,save1)
    1860           __(b LocalLabelPrefix`'ffcall_return_registers_call_end)
    1861 LocalLabelPrefix`'ffcall_return_registers_end:
    1862           .section __DATA,__gcc_except_tab
    1863           .align 3
    1864 LLSDA2:
    1865           .byte 0xff    /* @LPStart format (omit) */
    1866           .byte 0x0     /* @TType format (absolute) */
    1867           .byte 0x4d    /* uleb128 0x4d; @TType base offset */
    1868           .byte 0x3     /* call-site format (udata4) */
    1869           .byte 0x41    /* uleb128 0x41; Call-site table length */
    1870        
    1871           .long Lffcall_return_registers_setup-Lffcall_return_registers /* region 0 start */
    1872           .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup       /* length */
    1873           .long 0x0     /* landing pad */
    1874           .byte 0x0     /* uleb128 0x0; action */
    1875        
    1876           .long Lffcall_return_registers_call-Lffcall_return_registers  /* region 1 start */
    1877           .long Lffcall_return_registers_call_end-Lffcall_return_registers_call /* length */
    1878           .long Lffcall_return_registersLandingPad-Lffcall_return_registers     /* landing pad */
    1879           .byte 0x1     /* uleb128 0x1; action */
    1880        
    1881           .long Lffcall_return_registersUnwindResume-Lffcall_return_registers   /* region 2 start */
    1882           .long Lffcall_return_registersUnwindResume_end-Lffcall_return_registersUnwindResume   /* length */
    1883           .long 0x0     /* landing pad */
    1884           .byte 0x0     /* uleb128 0x0; action */
    1885        
    1886           .long Lffcall_return_registersBeginCatch-Lffcall_return_registers     /* region 3 start */
    1887           .long Lffcall_return_registersBeginCatch_end-Lffcall_return_registersBeginCatch       /* length */
    1888           .long 0       /* landing pad */
    1889           .byte 0x0     /* uleb128 0x0; action */
    1890        
    1891           .long Lffcall_return_registersEndCatch-Lffcall_return_registers
    1892           .long Lffcall_return_registersEndCatch_end-Lffcall_return_registersEndCatch   /* length */
    1893           .long 0x0     /* landing pad */
    1894           .byte 0x0     /* uleb128 0x0; action */
    1895           .byte 0x1     /* Action record table */
    1896           .byte 0x0
    1897           .align 3
    1898           .quad 0       /* _OBJC_EHTYPE_$_NSException */
    1899           .text
    1900          __endif
    1901         __endif
    1902                      
    1903 
    1904                
    1905 /* Signal an error synchronously, via %ERR-DISP.  */
    1906 /* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
    1907 /* on the C runtime stderr.  */
    1908 
    1909 _spentry(ksignalerr)
    1910         __(mov fname,#nrs.errdisp)
    1911         __(jump_fname)
    1912        
    1913 /* As in the heap-consed cases, only stack-cons the &rest arg  */
    1914 _spentry(stack_rest_arg)
    1915         __(mov imm0,#0)
    1916         __(vpush_argregs())
    1917         __(b _SPstack_cons_rest_arg)
    1918 
    1919        
    1920 _spentry(req_stack_rest_arg)
    1921         __(vpush_argregs())
    1922         __(b _SPstack_cons_rest_arg)
    1923        
    1924 _spentry(stack_cons_rest_arg)
    1925         __(sub imm1,nargs,imm0)
    1926         __(cmpri(cr0,imm1,0))
    1927         __(cmpri(cr1,imm1,(4096-dnode_size)/2))
    1928         __(mov arg_z,#nil_value)
    1929         __(ble cr0,2f)          /* always temp-push something.  */
    1930         __(bge cr1,3f)
    1931         __(add imm1,imm1,imm1)
    1932         __(dnode_align(imm2,imm1,tsp_frame.fixed_overhead))
    1933         __(TSP_Alloc_Var_Boxed(imm2,imm3))
    1934         __(la imm0,tsp_frame.data_offset+fulltag_cons(tsp))
    1935 1:
    1936         __(cmpri(cr0,imm1,cons.size))   /* last time through ?  */
    1937         __(subi imm1,imm1,cons.size)
    1938         __(vpop(arg_x))
    1939         __(_rplacd(imm0,arg_z))
    1940         __(_rplaca(imm0,arg_x))
    1941         __(mov arg_z,imm0)
    1942         __(la imm0,cons.size(imm0))
    1943         __(bne cr0,1b)
    1944         __(vpush1(arg_z))
    1945         __(bx lr)
    1946 2:
    1947         __(TSP_Alloc_Fixed_Unboxed(0))
    1948         __(vpush1(arg_z))
    1949         __(bx lr)
    1950 3:
    1951         __(TSP_Alloc_Fixed_Unboxed(0))
    1952         __(b _SPheap_cons_rest_arg)
    1953 
    1954 /* This was trying to swap exception ports to work around Darwin JNI lossage.
    1955    It's tended to bitrot, and we have another way to do that now.
    1956 */       
    1957 _spentry(poweropen_callbackX)
    1958         .long 0x7c800008        /* debug trap */
    1959        
    1960 /* Prepend all but the first two (closure code, fn) and last two  */
    1961 /* (function name, lfbits) elements of nfn to the "arglist".  */
    1962 /* Doing things this way (the same way that 68K MCL does) lets  */
    1963 /* functions which take "inherited arguments" work consistently  */
    1964 /* even in cases where no closure object is created.  */
    1965 _spentry(call_closure)       
    1966         __(cmpri(cr0,nargs,nargregs<<fixnumshift))
    1967         __(cmpri(cr1,nargs,fixnum_one))
    1968         __(vector_length(imm0,nfn,imm0))
    1969         __(subi imm0,imm0,4<<fixnumshift) /* imm0 = inherited arg count  */
    1970         __(mov imm1,#misc_data_offset+(2<<fixnumshift)) /* point to 1st arg  */
    1971         __(mov imm4,#nil_value)
    1972         __(ble+ cr0,local_label(no_insert))
    1973         /* Some arguments have already been vpushed.  Vpush imm0's worth  */
    1974         /* of NILs, copy those arguments that have already been vpushed from  */
    1975         /* the old TOS to the new, then insert all of the inerited args  */
    1976         /* and go to the function.  */
    1977         __(mov imm2,#0)
    1978 local_label(push_nil_loop):
    1979         __(addi imm2,imm2,fixnum_one)
    1980         __(cmpr(cr2,imm2,imm0))
    1981         __(vpush1(imm4))
    1982         __(bne cr2,local_label(push_nil_loop))
    1983 
    1984         __(mov imm3,vsp)
    1985         __(add imm4,vsp,imm0)
    1986         __(subi imm2,nargs,nargregs<<fixnumshift)
    1987 local_label(copy_already_loop):
    1988         __(cmpri(cr2,imm2,fixnum_one))
    1989         __(subi imm2,imm2,fixnum_one)
    1990         __(ldr fname,[imm4,#0])
    1991         __(addi imm4,imm4,fixnum_one)
    1992         __(str(fname,0(imm3)))
    1993         __(addi imm3,imm3,fixnum_one)
    1994         __(bne cr2,local_label(copy_already_loop))
    1995 
    1996 local_label(insert_loop):
    1997         __(cmpri(cr2,imm0,fixnum_one))
    1998         __(ldrx(fname,nfn,imm1))
    1999         __(addi imm1,imm1,fixnum_one)
    2000         __(addi nargs,nargs,fixnum_one)
    2001         __(subi imm0,imm0,fixnum_one)
    2002         __(push(fname,imm4))
    2003         __(bne cr2,local_label(insert_loop))
    2004         __(b local_label(go))
    2005 local_label(no_insert):
    2006         /* nargregs or fewer args were already vpushed.  */
    2007         /* if exactly nargregs, vpush remaining inherited vars.  */
    2008         __(add imm2,imm1,imm0)
    2009         __(bne cr0,local_label(set_regs))
    2010 local_label(vpush_remaining):
    2011         __(cmpri(cr2,imm0,fixnum_one))
    2012         __(ldrx(fname,nfn,imm1))
    2013         __(addi imm1,imm1,fixnum_one)
    2014         __(vpush1(fname))
    2015         __(subi imm0,imm0,fixnum_one)
    2016         __(addi nargs,nargs,fixnum_one)
    2017         __(bne cr2,local_label(vpush_remaining))
    2018         __(b local_label(go))
    2019 local_label(set_regs):
    2020         /* if nargs was > 1 (and we know that it was < 3), it must have  */
    2021         /* been 2.  Set arg_x, then vpush the remaining args.  */
    2022         __(ble cr1,local_label(set_y_z))
    2023 local_label(set_arg_x):
    2024         __(subi imm0,imm0,fixnum_one)
    2025         __(cmpri(cr0,imm0,0))
    2026         __(subi imm2,imm2,fixnum_one)
    2027         __(ldrx(arg_x,nfn,imm2))
    2028         __(addi nargs,nargs,fixnum_one)
    2029         __(bne cr0,local_label(vpush_remaining))
    2030         __(b local_label(go))
    2031         /* Maybe set arg_y or arg_z, preceding args  */
    2032 local_label(set_y_z):
    2033         __(bne cr1,local_label(set_arg_z))
    2034         /* Set arg_y, maybe arg_x, preceding args  */
    2035 local_label(set_arg_y):
    2036         __(subi imm0,imm0,fixnum_one)
    2037         __(cmpri(cr0,imm0,0))
    2038         __(subi imm2,imm2,fixnum_one)
    2039         __(ldrx(arg_y,nfn,imm2))
    2040         __(addi nargs,nargs,fixnum_one)
    2041         __(bne cr0,local_label(set_arg_x))
    2042         __(b local_label(go))
    2043 local_label(set_arg_z):
    2044         __(subi imm0,imm0,fixnum_one)
    2045         __(cmpri(cr0,imm0,0))
    2046         __(subi imm2,imm2,fixnum_one)
    2047         __(ldrx(arg_z,nfn,imm2))
    2048         __(addi nargs,nargs,fixnum_one)
    2049         __(bne cr0,local_label(set_arg_y))
    2050 
    2051 local_label(go):
    2052         __(vrefr(nfn,nfn,1))
    2053         __(ldr loc_pc,[nfn,#_function.codevector])
    2054         __(mtctr loc_pc)
    2055         __(bctr)
    2056        
    2057 /* This  treats anything that's either */
    2058 /* #+ppc32 (signed-byte 32), (unsigned-byte 32) */
    2059 /* #+ppc64 (signed-byte 64), (unsigned-byte 64) */
    2060 /* as if it denoted a "natural-sized" value.  */
    2061 /* Argument in arg_z, result in imm0.  May use temp0.  */
    2062 _spentry(getxlong)
    2063         __ifdef(`PPC64')
    2064         __else
    2065         __(extract_typecode(imm0,arg_z))
    2066         __(cmpri(cr0,imm0,tag_fixnum))
    2067         __(cmpri(cr1,imm0,subtag_bignum))
    2068         __(unbox_fixnum(imm0,arg_z))
    2069         __(beqlr cr0)
    2070         __(mov temp0,arg_z)
    2071         __(bne- cr1,local_label(error))
    2072         __(getvheader(imm0,temp0))
    2073         __(cmpri(cr1,imm0,one_digit_bignum_header))
    2074         __(cmpri(cr7,imm0,two_digit_bignum_header))
    2075         __(beq cr1,local_label(big1))
    2076         __(beq cr7,local_label(big2))
    2077 local_label(error):
    2078         __(uuo_interr(error_object_not_integer,arg_z)) /* not quite right but what 68K MCL said  */
    2079 
    2080 
    2081 
    2082 local_label(big2):
    2083         __(vrefr(imm0,temp0,1)) /* sign digit must be 0  */
    2084         __(cmpri(imm0,0))
    2085         __(bne local_label(error))
    2086 local_label(big1):
    2087         __(vrefr(imm0,temp0,0))
    2088         __(bx lr)
    2089 
    2090 
    2091         __endif
    2092                
    2093 /* Everything up to the last arg has been vpushed, nargs is set to  */
    2094 /* the (boxed) count of things already pushed.  */
    2095 /* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
    2096 /* function call (this may require vpopping a few things.)  */
    2097 /* ppc2-invoke-fn assumes that temp1 is preserved here.  */
    2098 _spentry(spreadargz)
    2099         __ifdef(`PPC64')
    2100          __(extract_fulltag(imm1,arg_z))
    2101          __(cmpri(cr1,imm1,fulltag_cons))
    2102         __else
    2103          __(extract_lisptag(imm1,arg_z))
    2104          __(cmpri(cr1,imm1,tag_list))
    2105         __endif
    2106         __(cmpri(cr0,arg_z,nil_value))
    2107         __(mov imm0,#0)
    2108         __(mov arg_y,arg_z)             /*  save in case of error  */
    2109         __(beq cr0,2f)
    2110 1:
    2111         __(bne- cr1,3f)
    2112         __(_car(arg_x,arg_z))
    2113         __(_cdr(arg_z,arg_z))
    2114         __(cmpri(cr0,arg_z,nil_value))
    2115         __ifdef(`PPC64')
    2116          __(extract_fulltag(imm1,arg_z))
    2117          __(cmpri(cr1,imm1,fulltag_cons))
    2118         __else
    2119          __(extract_lisptag(imm1,arg_z))
    2120          __(cmpri(cr1,imm1,tag_list))
    2121         __endif
    2122         __(vpush1(arg_x))
    2123         __(addi imm0,imm0,fixnum_one)
    2124         __(bne cr0,1b)
    2125 2:
    2126         __(add. nargs,nargs,imm0)
    2127         __(cmpri(cr2,nargs,2<<fixnumshift))
    2128         __(beqlr- cr0)
    2129         __(vpop(arg_z))
    2130         __(bltlr cr2)
    2131         __(vpop(arg_y))
    2132         __(beqlr cr2)
    2133         __(vpop(arg_x))
    2134         __(bx lr)
    2135         /*  Discard whatever's been vpushed already, complain.  */
    2136 3:     
    2137         __(add vsp,vsp,imm0)
    2138         __(mov arg_z,arg_y)             /* recover original arg_z  */
    2139         __(mov arg_y,#XNOSPREAD)
    2140         __(set_nargs(2))
    2141         __(b _SPksignalerr)
    2142        
    2143 /* Tail-recursively funcall temp0.  */
    2144 /* Pretty much the same as the tcallsym* cases above.  */
    2145 _spentry(tfuncallgen)
    2146         __(cmpri(cr0,nargs,nargregs<<fixnumshift))
    2147         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2148         __(ldr fn,[sp,#lisp_frame.savefn])
    2149         __(mtlr loc_pc)
    2150         __(ble cr0,2f)
    2151         __(ldr imm0,[sp,#lisp_frame.savevsp])
    2152         __(discard_lisp_frame())
    2153         /* can use nfn (= temp2) as a temporary  */
    2154         __(subi imm1,nargs,nargregs<<fixnumshift)
    2155         __(add imm1,imm1,vsp)
    2156 1:
    2157         __(ldru(temp2,-node_size(imm1)))
    2158         __(cmpr(cr0,imm1,vsp))
    2159         __(push(temp2,imm0))
    2160         __(bne cr0,1b)
    2161         __(mov vsp,imm0)
    2162         __(do_funcall())
    2163 2:
    2164         __(ldr vsp,[sp,#lisp_frame.savevsp])
    2165         __(discard_lisp_frame())
    2166         __(do_funcall())
    2167 
    2168 
    2169 /* Some args were vpushed.  Slide them down to the base of  */
    2170 /* the current frame, then do funcall.  */
    2171 _spentry(tfuncallslide)
    2172         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2173         __(ldr fn,[sp,#lisp_frame.savefn])
    2174         __(ldr imm0,[sp,#lisp_frame.savevsp])
    2175         __(discard_lisp_frame())
    2176         /* can use nfn (= temp2) as a temporary  */
    2177         __(subi imm1,nargs,nargregs<<fixnumshift)
    2178         __(add imm1,imm1,vsp)
    2179         __(mtlr loc_pc)
    2180 1:
    2181         __(ldru(temp2,-node_size(imm1)))
    2182         __(cmpr(cr0,imm1,vsp))
    2183         __(push(temp2,imm0))
    2184         __(bne cr0,1b)
    2185         __(mov vsp,imm0)
    2186         __(do_funcall())
    2187 
    2188 /* No args were vpushed; recover saved context & do funcall  */
    2189 _spentry(tfuncallvsp)
    2190         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2191         __(ldr fn,[sp,#lisp_frame.savefn])
    2192         __(ldr vsp,[sp,#lisp_frame.savevsp])
    2193         __(mtlr loc_pc)
    2194         __(discard_lisp_frame())
    2195         __(do_funcall())
    2196        
    2197 /* Tail-recursively call the (known symbol) in fname.  */
    2198 /* In the general case, we don't know if any args were  */
    2199 /* vpushed or not.  If so, we have to "slide" them down  */
    2200 /* to the base of the frame.  If not, we can just restore  */
    2201 /* vsp, lr, fn from the saved lisp frame on the control stack.  */
    2202 _spentry(tcallsymgen)
    2203         __(cmpri(cr0,nargs,nargregs<<fixnumshift))
    2204         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2205         __(ldr fn,[sp,#lisp_frame.savefn])
    2206         __(mtlr loc_pc)
    2207         __(ble cr0,2f)
    2208 
    2209         __(ldr imm0,[sp,#lisp_frame.savevsp])
    2210         __(discard_lisp_frame())
    2211         /* can use nfn (= temp2) as a temporary  */
    2212         __(subi imm1,nargs,nargregs<<fixnumshift)
    2213         __(add imm1,imm1,vsp)
    2214 1:
    2215         __(ldru(temp2,-node_size(imm1)))
    2216         __(cmpr(cr0,imm1,vsp))
    2217         __(push(temp2,imm0))
    2218         __(bne cr0,1b)
    2219         __(mov vsp,imm0)
    2220         __(jump_fname)
    2221        
    2222 2:             
    2223         __(ldr vsp,[sp,#lisp_frame.savevsp])
    2224         __(discard_lisp_frame())
    2225         __(jump_fname)
    2226        
    2227        
    2228 /* Some args were vpushed.  Slide them down to the base of  */
    2229 /* the current frame, then do funcall.  */
    2230 _spentry(tcallsymslide)
    2231         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2232         __(ldr fn,[sp,#lisp_frame.savefn])
    2233         __(ldr imm0,[sp,#lisp_frame.savevsp])
    2234         __(discard_lisp_frame())
    2235         __(mtlr loc_pc)
    2236         /* can use nfn (= temp2) as a temporary  */
    2237         __(subi imm1,nargs,nargregs<<fixnumshift)
    2238         __(add imm1,imm1,vsp)
    2239 1:
    2240         __(ldru(temp2,-node_size(imm1)))
    2241         __(cmpr(cr0,imm1,vsp))
    2242         __(push(temp2,imm0))
    2243         __(bne cr0,1b)
    2244         __(mov vsp,imm0)
    2245         __(jump_fname)
    2246 
    2247 /* No args were vpushed; recover saved context & call symbol  */
    2248 _spentry(tcallsymvsp)
    2249         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2250         __(ldr fn,[sp,#lisp_frame.savefn])
    2251         __(ldr vsp,[sp,#lisp_frame.savevsp])
    2252         __(discard_lisp_frame())
    2253         __(mtlr loc_pc)
    2254         __(jump_fname)
    2255        
    2256 /* Tail-recursively call the function in nfn.  */
    2257 /* Pretty much the same as the tcallsym* cases above.  */
    2258 _spentry(tcallnfngen)
    2259         __(cmpri(cr0,nargs,nargregs<<fixnumshift))
    2260         __(ble cr0,_SPtcallnfnvsp)
    2261         __(b _SPtcallnfnslide)
    2262 
    2263 /* Some args were vpushed.  Slide them down to the base of  */
    2264 /* the current frame, then do funcall.  */
    2265 _spentry(tcallnfnslide)
    2266         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2267         __(ldr fn,[sp,#lisp_frame.savefn])
    2268         __(ldr imm0,[sp,#lisp_frame.savevsp])
    2269         __(discard_lisp_frame())
    2270         __(mtlr loc_pc)
    2271         /* Since we have a known function, can use fname as a temporary.  */
    2272         __(subi imm1,nargs,nargregs<<fixnumshift)
    2273         __(add imm1,imm1,vsp)
    2274 1:
    2275         __(ldru(fname,-node_size(imm1)))
    2276         __(cmpr(cr0,imm1,vsp))
    2277         __(push(fname,imm0))
    2278         __(bne cr0,1b)
    2279         __(mov vsp,imm0)
    2280         __(jump_nfn())
    2281        
    2282 _spentry(tcallnfnvsp)
    2283         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    2284         __(ldr fn,[sp,#lisp_frame.savefn])
    2285         __(ldr vsp,[sp,#lisp_frame.savevsp])
    2286         __(discard_lisp_frame())
    2287         __(mtlr loc_pc)
    2288         __(jump_nfn())
    2289        
    2290 /* Reference index arg_z of a misc-tagged object (arg_y).  */
    2291 /* Note that this conses in some cases.  Return a properly-tagged  */
    2292 /* lisp object in arg_z.  Do type and bounds-checking.  */
    2293        
    2294 _spentry(misc_ref)
    2295         __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
    2296         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
    2297         __(vector_length(imm0,arg_y,imm1))
    2298         __(trlge(arg_z,imm0))
    2299         __(extract_lowbyte(imm1,imm1))  /* imm1 = subtag  */
    2300        
    2301 local_label(misc_ref_common):   
    2302         __ifdef(`PPC64')
    2303          __(slwi imm1,imm1,3)
    2304          __(mov imm0,#LO(local_label(misc_ref_jmp)))
    2305          __(addis imm0,imm0,HA(local_label(misc_ref_jmp)))
    2306          __(ldx imm0,imm0,imm1)
    2307          __(mtctr imm0)
    2308          __(bctr)
    2309 
    2310 local_label(misc_ref_jmp):             
    2311         /* 00-0f  */
    2312          .quad local_label(misc_ref_invalid) /* 00 even_fixnum  */
    2313          .quad local_label(misc_ref_invalid) /* 01 imm_0  */
    2314          .quad local_label(misc_ref_invalid) /* 02 immheader_0  */
    2315          .quad local_label(misc_ref_node) /* 03 function  */
    2316          .quad local_label(misc_ref_invalid) /* 04 cons  */
    2317          .quad local_label(misc_ref_invalid) /* 05 imm_1  */
    2318          .quad local_label(misc_ref_invalid) /* 06 immheader_1  */
    2319          .quad local_label(misc_ref_node) /* 07 catch_frame  */
    2320          .quad local_label(misc_ref_invalid) /* 08 odd_fixnum  */
    2321          .quad local_label(misc_ref_invalid) /* 09 imm_2  */
    2322          .quad local_label(misc_ref_u32) /* 0a code_vector  */
    2323          .quad local_label(misc_ref_node) /* 0b slot_vector  */
    2324          .quad local_label(misc_ref_invalid) /* 0c misc  */
    2325          .quad local_label(misc_ref_invalid) /* 0d imm3  */
    2326          .quad local_label(misc_ref_invalid) /* 0e immheader_3  */
    2327          .quad local_label(misc_ref_node) /* 0f ratio  */
    2328         /* 10-1f  */
    2329          .quad local_label(misc_ref_invalid) /* 10 even_fixnum  */
    2330          .quad local_label(misc_ref_invalid) /* 11 imm_0  */
    2331          .quad local_label(misc_ref_invalid) /* 12 immheader_0  */
    2332          .quad local_label(misc_ref_node) /* 13 symbol_0  */
    2333          .quad local_label(misc_ref_invalid) /* 14 cons  */
    2334          .quad local_label(misc_ref_invalid) /* 15 imm_1  */
    2335          .quad local_label(misc_ref_invalid) /* 16 immheader_1  */
    2336          .quad local_label(misc_ref_node) /* 17 lisp_tread  */
    2337          .quad local_label(misc_ref_invalid) /* 18 odd_fixnum  */
    2338          .quad local_label(misc_ref_invalid) /* 19 imm_2  */
    2339          .quad local_label(misc_ref_u32) /* 1a xcode_vector  */
    2340          .quad local_label(misc_ref_node) /* 1b instance  */
    2341          .quad local_label(misc_ref_invalid) /* 1c misc  */
    2342          .quad local_label(misc_ref_invalid) /* 1d imm3  */
    2343          .quad local_label(misc_ref_u64) /* 1e macptr  */
    2344          .quad local_label(misc_ref_node) /* 1f complex  */
    2345         /* 20-2f  */
    2346          .quad local_label(misc_ref_invalid) /* 20 even_fixnum  */
    2347          .quad local_label(misc_ref_invalid) /* 21 imm_0  */
    2348          .quad local_label(misc_ref_invalid) /* 22 immheader_0  */
    2349          .quad local_label(misc_ref_invalid) /* 23 nodeheader_0  */
    2350          .quad local_label(misc_ref_invalid) /* 24 cons  */
    2351          .quad local_label(misc_ref_invalid) /* 25 imm_1  */
    2352          .quad local_label(misc_ref_invalid) /* 26 immheader_1  */
    2353          .quad local_label(misc_ref_node) /* 27 lock  */
    2354          .quad local_label(misc_ref_invalid) /* 28 odd_fixnum  */
    2355          .quad local_label(misc_ref_invalid) /* 29 imm_2  */
    2356          .quad local_label(misc_ref_u32) /* 2a bignum  */
    2357          .quad local_label(misc_ref_node) /* 2b struct  */
    2358          .quad local_label(misc_ref_invalid) /* 2c misc  */
    2359          .quad local_label(misc_ref_invalid) /* 2d imm3  */
    2360          .quad local_label(misc_ref_u64) /* 2e dead_macptr  */
    2361          .quad local_label(misc_ref_invalid) /* 2f nodeheader_3  */
    2362         /* 30-3f  */
    2363          .quad local_label(misc_ref_invalid) /* 30 even_fixnum  */
    2364          .quad local_label(misc_ref_invalid) /* 31 imm_0  */
    2365          .quad local_label(misc_ref_invalid) /* 32 immheader_0  */
    2366          .quad local_label(misc_ref_invalid) /* 33 nodeheader_0  */
    2367          .quad local_label(misc_ref_invalid) /* 34 cons  */
    2368          .quad local_label(misc_ref_invalid) /* 35 imm_1  */
    2369          .quad local_label(misc_ref_invalid) /* 36 immheader_1  */
    2370          .quad local_label(misc_ref_node) /* 37 hash_vector  */
    2371          .quad local_label(misc_ref_invalid) /* 38 odd_fixnum  */
    2372          .quad local_label(misc_ref_invalid) /* 39 imm_2  */
    2373          .quad local_label(misc_ref_u32) /* 3a double_float  */
    2374          .quad local_label(misc_ref_node) /* 3b istruct  */
    2375          .quad local_label(misc_ref_invalid) /* 3c misc  */
    2376          .quad local_label(misc_ref_invalid) /* 3d imm3  */
    2377          .quad local_label(misc_ref_invalid) /* 3e immheader_3  */
    2378          .quad local_label(misc_ref_invalid) /* 3f nodeheader_3  */
    2379         /* 40-4f  */
    2380          .quad local_label(misc_ref_invalid) /* 40 even_fixnum  */
    2381          .quad local_label(misc_ref_invalid) /* 41 imm_0  */
    2382          .quad local_label(misc_ref_invalid) /* 42 immheader_0  */
    2383          .quad local_label(misc_ref_invalid) /* 43 nodeheader_0  */
    2384          .quad local_label(misc_ref_invalid) /* 44 cons  */
    2385          .quad local_label(misc_ref_invalid) /* 45 imm_1  */
    2386          .quad local_label(misc_ref_invalid) /* 46 immheader_1  */
    2387          .quad local_label(misc_ref_node) /* 47 pool  */
    2388          .quad local_label(misc_ref_invalid) /* 48 odd_fixnum  */
    2389          .quad local_label(misc_ref_invalid) /* 49 imm_2  */
    2390          .quad local_label(misc_ref_invalid) /* 4a immheader_2  */
    2391          .quad local_label(misc_ref_node) /* 4b value_cell_2  */
    2392          .quad local_label(misc_ref_invalid) /* 4c misc  */
    2393          .quad local_label(misc_ref_invalid) /* 4d imm3  */
    2394          .quad local_label(misc_ref_invalid) /* 4e immheader_3  */
    2395          .quad local_label(misc_ref_invalid) /* 4f nodeheader_3  */
    2396         /* 50-5f  */
    2397          .quad local_label(misc_ref_invalid) /* 50 even_fixnum  */
    2398          .quad local_label(misc_ref_invalid) /* 51 imm_0  */
    2399          .quad local_label(misc_ref_invalid) /* 52 immheader_0  */
    2400          .quad local_label(misc_ref_invalid) /* 53 nodeheader_0  */
    2401          .quad local_label(misc_ref_invalid) /* 54 cons  */
    2402          .quad local_label(misc_ref_invalid) /* 55 imm_1  */
    2403          .quad local_label(misc_ref_invalid) /* 56 immheader_1  */
    2404          .quad local_label(misc_ref_node) /* 57 weak  */
    2405          .quad local_label(misc_ref_invalid) /* 58 odd_fixnum  */
    2406          .quad local_label(misc_ref_invalid) /* 59 imm_2  */
    2407          .quad local_label(misc_ref_invalid) /* 5a immheader_2  */
    2408          .quad local_label(misc_ref_node) /* 5b xfunction  */
    2409          .quad local_label(misc_ref_invalid) /* 5c misc  */
    2410          .quad local_label(misc_ref_invalid) /* 5d imm3  */
    2411          .quad local_label(misc_ref_invalid) /* 5e immheader_3  */
    2412          .quad local_label(misc_ref_invalid) /* 5f nodeheader_3  */
    2413         /* 60-6f  */
    2414          .quad local_label(misc_ref_invalid) /* 60 even_fixnum  */
    2415          .quad local_label(misc_ref_invalid) /* 61 imm_0  */
    2416          .quad local_label(misc_ref_invalid) /* 62 immheader_0  */
    2417          .quad local_label(misc_ref_invalid) /* 63 nodeheader_0  */
    2418          .quad local_label(misc_ref_invalid) /* 64 cons  */
    2419          .quad local_label(misc_ref_invalid) /* 65 imm_1  */
    2420          .quad local_label(misc_ref_invalid) /* 66 immheader_1  */
    2421          .quad local_label(misc_ref_node) /* 67 package  */
    2422          .quad local_label(misc_ref_invalid) /* 68 odd_fixnum  */
    2423          .quad local_label(misc_ref_invalid) /* 69 imm_2  */
    2424          .quad local_label(misc_ref_invalid) /* 6a immheader_2  */
    2425          .quad local_label(misc_ref_invalid) /* 6b nodeheader_2  */
    2426          .quad local_label(misc_ref_invalid) /* 6c misc  */
    2427          .quad local_label(misc_ref_invalid) /* 6d imm3  */
    2428          .quad local_label(misc_ref_invalid) /* 6e immheader_3  */
    2429          .quad local_label(misc_ref_invalid) /* 6f nodeheader_3  */
    2430         /* 70-7f  */
    2431          .quad local_label(misc_ref_invalid) /* 70 even_fixnum  */
    2432          .quad local_label(misc_ref_invalid) /* 71 imm_0  */
    2433          .quad local_label(misc_ref_invalid) /* 72 immheader_0  */
    2434          .quad local_label(misc_ref_invalid) /* 73 nodeheader_0  */
    2435          .quad local_label(misc_ref_invalid) /* 74 cons  */
    2436          .quad local_label(misc_ref_invalid) /* 75 imm_1  */
    2437          .quad local_label(misc_ref_invalid) /* 76 immheader_1  */
    2438          .quad local_label(misc_ref_invalid) /* 77 nodeheader_1  */
    2439          .quad local_label(misc_ref_invalid) /* 78 odd_fixnum  */
    2440          .quad local_label(misc_ref_invalid) /* 79 imm_2  */
    2441          .quad local_label(misc_ref_invalid) /* 7a immheader_2  */
    2442          .quad local_label(misc_ref_invalid) /* 7b nodeheader_2  */
    2443          .quad local_label(misc_ref_invalid) /* 7c misc  */
    2444          .quad local_label(misc_ref_invalid) /* 7d imm3  */
    2445          .quad local_label(misc_ref_invalid) /* 7e immheader_3  */
    2446          .quad local_label(misc_ref_invalid) /* 7f nodeheader_3  */
    2447         /* 80-8f  */
    2448          .quad local_label(misc_ref_invalid) /* 80 even_fixnum  */
    2449          .quad local_label(misc_ref_invalid) /* 81 imm_0  */
    2450          .quad local_label(misc_ref_invalid) /* 82 immheader_0  */
    2451          .quad local_label(misc_ref_invalid) /* 83 nodeheader_0  */
    2452          .quad local_label(misc_ref_invalid) /* 84 cons  */
    2453          .quad local_label(misc_ref_invalid) /* 85 imm_1  */
    2454          .quad local_label(misc_ref_invalid) /* 86 immheader_1  */
    2455          .quad local_label(misc_ref_node)    /* 87 arrayH  */
    2456          .quad local_label(misc_ref_invalid) /* 88 odd_fixnum  */
    2457          .quad local_label(misc_ref_invalid) /* 89 imm_2  */
    2458          .quad local_label(misc_ref_invalid) /* 8a immheader_2  */
    2459          .quad local_label(misc_ref_node)    /* 8b vectorH  */
    2460          .quad local_label(misc_ref_invalid) /* 8c misc  */
    2461          .quad local_label(misc_ref_invalid) /* 8d imm3  */
    2462          .quad local_label(misc_ref_invalid) /* 8e immheader_3  */
    2463          .quad local_label(misc_ref_node) /* 8f simple_vector  */
    2464         /* 90-9f  */
    2465          .quad local_label(misc_ref_invalid) /* 90 even_fixnum  */
    2466          .quad local_label(misc_ref_invalid) /* 91 imm_0  */
    2467          .quad local_label(misc_ref_s8) /* 92 s8  */
    2468          .quad local_label(misc_ref_invalid) /* 93 nodeheader_0  */
    2469          .quad local_label(misc_ref_invalid) /* 94 cons  */
    2470          .quad local_label(misc_ref_invalid) /* 95 imm_1  */
    2471          .quad local_label(misc_ref_s16) /* 96 immheader_1  */
    2472          .quad local_label(misc_ref_invalid) /* 97 nodeheader_1  */
    2473          .quad local_label(misc_ref_invalid) /* 98 odd_fixnum  */
    2474          .quad local_label(misc_ref_invalid) /* 99 imm_2  */
    2475          .quad local_label(misc_ref_s32) /* 9a s32  */
    2476          .quad local_label(misc_ref_invalid) /* 9b nodeheader_2  */
    2477          .quad local_label(misc_ref_invalid) /* 9c misc  */
    2478          .quad local_label(misc_ref_invalid) /* 9d imm3  */
    2479          .quad local_label(misc_ref_s64) /* 9e s64  */
    2480          .quad local_label(misc_ref_invalid) /* 9f nodeheader_3  */
    2481         /* a0-af  */
    2482          .quad local_label(misc_ref_invalid) /* a0 even_fixnum  */
    2483          .quad local_label(misc_ref_invalid) /* a1 imm_0  */
    2484          .quad local_label(misc_ref_u8) /* a2 u8  */
    2485          .quad local_label(misc_ref_invalid) /* a3 nodeheader_0  */
    2486          .quad local_label(misc_ref_invalid) /* a4 cons  */
    2487          .quad local_label(misc_ref_invalid) /* a5 imm_1  */
    2488          .quad local_label(misc_ref_u16) /* a6 u16  */
    2489          .quad local_label(misc_ref_invalid) /* a7 nodeheader_1  */
    2490          .quad local_label(misc_ref_invalid) /* a8 odd_fixnum  */
    2491          .quad local_label(misc_ref_invalid) /* a9 imm_2  */
    2492          .quad local_label(misc_ref_u32) /* aa u32  */
    2493          .quad local_label(misc_ref_invalid) /* ab nodeheader_2  */
    2494          .quad local_label(misc_ref_invalid) /* ac misc  */
    2495          .quad local_label(misc_ref_invalid) /* ad imm3  */
    2496          .quad local_label(misc_ref_u64) /* ae u64  */
    2497          .quad local_label(misc_ref_invalid) /* af nodeheader_3  */
    2498         /* b0-bf  */
    2499          .quad local_label(misc_ref_invalid) /* b0 even_fixnum  */
    2500          .quad local_label(misc_ref_invalid) /* b1 imm_0  */
    2501          .quad local_label(misc_ref_invalid) /* b2 immheader_0  */
    2502          .quad local_label(misc_ref_invalid) /* b3 nodeheader_0  */
    2503          .quad local_label(misc_ref_invalid) /* b4 cons  */
    2504          .quad local_label(misc_ref_invalid) /* b5 imm_1  */
    2505          .quad local_label(misc_ref_invalid) /* b6 immheader_1  */
    2506          .quad local_label(misc_ref_invalid) /* b7 nodeheader_1  */
    2507          .quad local_label(misc_ref_invalid) /* b8 odd_fixnum  */
    2508          .quad local_label(misc_ref_invalid) /* b9 imm_2  */
    2509          .quad local_label(misc_ref_single_float_vector) /* ba sf vector  */
    2510          .quad local_label(misc_ref_invalid) /* bb nodeheader_2  */
    2511          .quad local_label(misc_ref_invalid) /* bc misc  */
    2512          .quad local_label(misc_ref_invalid) /* bd imm3  */
    2513          .quad local_label(misc_ref_fixnum_vector) /* be fixnum_vector  */
    2514          .quad local_label(misc_ref_invalid) /* bf nodeheader_3  */
    2515         /* c0-cf  */
    2516          .quad local_label(misc_ref_invalid) /* c0 even_fixnum  */
    2517          .quad local_label(misc_ref_invalid) /* c1 imm_0  */
    2518          .quad local_label(misc_ref_invalid) /* c2 immheader_0  */
    2519          .quad local_label(misc_ref_invalid) /* c3 nodeheader_0  */
    2520          .quad local_label(misc_ref_invalid) /* c4 cons  */
    2521          .quad local_label(misc_ref_invalid) /* c5 imm_1  */
    2522          .quad local_label(misc_ref_invalid) /* c6 immheader_1  */
    2523          .quad local_label(misc_ref_invalid) /* c7 nodeheader_1  */
    2524          .quad local_label(misc_ref_invalid) /* c8 odd_fixnum  */
    2525          .quad local_label(misc_ref_invalid) /* c9 imm_2  */
    2526          .quad local_label(misc_ref_invalid) /* ca immheader_2  */
    2527          .quad local_label(misc_ref_invalid) /* cb nodeheader_2  */
    2528          .quad local_label(misc_ref_invalid) /* cc misc  */
    2529          .quad local_label(misc_ref_invalid) /* cd imm3  */
    2530          .quad local_label(misc_ref_double_float_vector) /* ce double-float vector  */
    2531          .quad local_label(misc_ref_invalid) /* cf nodeheader_3  */
    2532         /* d0-df  */
    2533          .quad local_label(misc_ref_invalid) /* d0 even_fixnum  */
    2534          .quad local_label(misc_ref_invalid) /* d1 imm_0  */
    2535          .quad local_label(misc_ref_string) /* d2 string  */
    2536          .quad local_label(misc_ref_invalid) /* d3 nodeheader_0  */
    2537          .quad local_label(misc_ref_invalid) /* d4 cons  */
    2538          .quad local_label(misc_ref_invalid) /* d5 imm_1  */
    2539          .quad local_label(misc_ref_invalid) /* d6 immheader_1  */
    2540          .quad local_label(misc_ref_invalid) /* d7 nodeheader_1  */
    2541          .quad local_label(misc_ref_invalid) /* d8 odd_fixnum  */
    2542          .quad local_label(misc_ref_invalid) /* d9 imm_2  */
    2543          .quad local_label(misc_ref_new_string) /* da new_string  */
    2544          .quad local_label(misc_ref_invalid) /* db nodeheader_2  */
    2545          .quad local_label(misc_ref_invalid) /* dc misc  */
    2546          .quad local_label(misc_ref_invalid) /* dd imm3  */
    2547          .quad local_label(misc_ref_invalid) /* de immheader_3  */
    2548          .quad local_label(misc_ref_invalid) /* df nodeheader_3  */
    2549         /* e0-ef  */
    2550          .quad local_label(misc_ref_invalid) /* e0 even_fixnum  */
    2551          .quad local_label(misc_ref_invalid) /* e1 imm_0  */
    2552          .quad local_label(misc_ref_invalid) /* e2 immheader_0  */
    2553          .quad local_label(misc_ref_invalid) /* e3 nodeheader_0  */
    2554          .quad local_label(misc_ref_invalid) /* e4 cons  */
    2555          .quad local_label(misc_ref_invalid) /* e5 imm_1  */
    2556          .quad local_label(misc_ref_invalid) /* e6 immheader_1  */
    2557          .quad local_label(misc_ref_invalid) /* e7 nodeheader_1  */
    2558          .quad local_label(misc_ref_invalid) /* e8 odd_fixnum  */
    2559          .quad local_label(misc_ref_invalid) /* e9 imm_2  */
    2560          .quad local_label(misc_ref_invalid) /* ea immheader_2  */
    2561          .quad local_label(misc_ref_invalid) /* eb nodeheader_2  */
    2562          .quad local_label(misc_ref_invalid) /* ec misc  */
    2563          .quad local_label(misc_ref_invalid) /* ed imm3  */
    2564          .quad local_label(misc_ref_invalid) /* ee immheader_3  */
    2565          .quad local_label(misc_ref_invalid) /* ef nodeheader_3  */
    2566         /* f0-ff  */
    2567          .quad local_label(misc_ref_invalid) /* f0 even_fixnum  */
    2568          .quad local_label(misc_ref_invalid) /* f1 imm_0  */
    2569          .quad local_label(misc_ref_invalid) /* f2 immheader_0  */
    2570          .quad local_label(misc_ref_invalid) /* f3 nodeheader_0  */
    2571          .quad local_label(misc_ref_invalid) /* f4 cons  */
    2572          .quad local_label(misc_ref_invalid) /* f5 imm_1  */
    2573          .quad local_label(misc_ref_bit_vector) /* f6 bit_vector  */
    2574          .quad local_label(misc_ref_invalid) /* f7 nodeheader_1  */
    2575          .quad local_label(misc_ref_invalid) /* f8 odd_fixnum  */
    2576          .quad local_label(misc_ref_invalid) /* f9 imm_2  */
    2577          .quad local_label(misc_ref_invalid) /* fa immheader_2  */
    2578          .quad local_label(misc_ref_invalid) /* fb nodeheader_2  */
    2579          .quad local_label(misc_ref_invalid) /* fc misc  */
    2580          .quad local_label(misc_ref_invalid) /* fd imm3  */
    2581          .quad local_label(misc_ref_invalid) /* fe immheader_3  */
    2582          .quad local_label(misc_ref_invalid) /* ff nodeheader_3  */
    2583        
    2584          /* A node vector  */
    2585 local_label(misc_ref_node):       
    2586          __(la imm0,misc_data_offset(arg_z))
    2587          __(ldx arg_z,arg_y,imm0)
    2588          __(bx lr)
    2589 local_label(misc_ref_double_float_vector):       
    2590          __(la imm0,misc_data_offset(arg_z))
    2591          __(ldx imm0,arg_y,imm0)
    2592          __(mov imm1,#double_float_header)
    2593          __(Misc_Alloc_Fixed(arg_z,imm1,double_float.size))
    2594          __(std imm0,double_float.value(arg_z))
    2595          __(bx lr)
    2596 local_label(misc_ref_s64):     
    2597          __(la imm0,misc_data_offset(arg_z))
    2598          __(ldx imm0,arg_y,imm0)
    2599          __(b _SPmakes64)
    2600 local_label(misc_ref_fixnum_vector):   
    2601          __(la imm0,misc_data_offset(arg_z))
    2602          __(ldx imm0,arg_y,imm0)
    2603          __(box_fixnum(arg_z,imm0))
    2604          __(bx lr)
    2605 local_label(misc_ref_u64):     
    2606          __(la imm0,misc_data_offset(arg_z))
    2607          __(ldx imm0,arg_y,imm0)
    2608          __(b _SPmakeu64)
    2609 local_label(misc_ref_new_string):       
    2610          __(srdi imm0,arg_z,1)
    2611          __(la imm0,misc_data_offset(imm0))
    2612          __(lwzx imm0,arg_y,imm0)
    2613          __(slwi imm0,imm0,charcode_shift)
    2614          __(ori arg_z,imm0,subtag_character)
    2615          __(bx lr)
    2616 local_label(misc_ref_s32):                     
    2617          __(srdi imm0,arg_z,1)
    2618          __(la imm0,misc_data_offset(imm0))
    2619          __(lwax imm0,arg_y,imm0)
    2620          __(box_fixnum(arg_z,imm0))
    2621          __(bx lr)
    2622 local_label(misc_ref_u32):                     
    2623          __(srdi imm0,arg_z,1)
    2624          __(la imm0,misc_data_offset(imm0))
    2625          __(lwzx imm0,arg_y,imm0)
    2626          __(box_fixnum(arg_z,imm0))
    2627          __(bx lr)
    2628 local_label(misc_ref_single_float_vector):             
    2629          __(srdi imm0,arg_z,1)
    2630          __(la imm0,misc_data_offset(imm0))
    2631          __(lwzx imm0,arg_y,imm0)
    2632          __(rldicr arg_z,imm0,32,31)
    2633          __(ori arg_z,arg_z,subtag_single_float)
    2634          __(bx lr)
    2635 local_label(misc_ref_s16):     
    2636          __(srdi imm0,arg_z,2)
    2637          __(la imm0,misc_data_offset(imm0))
    2638          __(lhax imm0,arg_y,imm0)
    2639          __(box_fixnum(arg_z,imm0))
    2640          __(bx lr)
    2641 local_label(misc_ref_u16):
    2642          __(srdi imm0,arg_z,2)
    2643          __(la imm0,misc_data_offset(imm0))
    2644          __(lhzx imm0,arg_y,imm0)
    2645          __(box_fixnum(arg_z,imm0))
    2646          __(bx lr)
    2647 local_label(misc_ref_s8):       
    2648          __(srdi imm0,arg_z,3)
    2649          __(la imm0,misc_data_offset(imm0))
    2650          __(lbzx imm0,arg_y,imm0)
    2651          __(extsb imm0,imm0)
    2652          __(box_fixnum(arg_z,imm0))
    2653          __(bx lr)
    2654 local_label(misc_ref_u8):       
    2655          __(srdi imm0,arg_z,3)
    2656          __(la imm0,misc_data_offset(imm0))
    2657          __(lbzx imm0,arg_y,imm0)
    2658          __(box_fixnum(arg_z,imm0))
    2659          __(bx lr)
    2660 local_label(misc_ref_string):             
    2661          __(srdi imm0,arg_z,3)
    2662          __(la imm0,misc_data_offset(imm0))
    2663          __(lbzx imm0,arg_y,imm0)
    2664          __(sldi imm0,imm0,charcode_shift)
    2665          __(ori arg_z,imm0,subtag_character)
    2666          __(bx lr)
    2667 local_label(misc_ref_bit_vector):               
    2668          __(extrwi imm1,arg_z,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
    2669          __(la imm1,1+fixnumshift(imm1))
    2670          __(srdi imm0,arg_z,5+fixnumshift)
    2671          __(sldi imm0,imm0,2)
    2672          __(la imm0,misc_data_offset(imm0))
    2673          __(lwzx imm0,arg_y,imm0)
    2674          __(rlwnm arg_z,imm0,imm1,31-fixnumshift,31-fixnumshift)
    2675          __(bx lr)
    2676 local_label(misc_ref_invalid):     
    2677          __(mov arg_x,#XBADVEC)
    2678          __(set_nargs(3))
    2679          __(b _SPksignalerr)       
    2680         __else
    2681          __(slwi imm1,imm1,2)
    2682          __(mov imm0,#LO(local_label(misc_ref_jmp)))
    2683          __(addis imm0,imm0,HA(local_label(misc_ref_jmp)))
    2684          __(lwzx imm0,imm0,imm1)
    2685          __(mtctr imm0)
    2686          __(bctr)
    2687 
    2688 local_label(misc_ref_jmp):           
    2689         /* 00-0f  */
     367dnl /* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
     368dnl /* Otherwise, process unwind-protects and throw to indicated catch frame.  */
     369dnl
     370dnl _spentry(throw)
     371dnl     __(ldr imm1,[rcontext, #tcr.catch_top])
     372dnl     __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
     373dnl     __(cmpri(cr0,imm1,0))
     374dnl     __(ldr temp0,[vsp,nargs])
     375dnl     __(beq- cr0,local_label(_throw_tag_not_found))
     376dnl local_label(_throw_loop):
     377dnl     __(ldr temp1,[imm1,#catch_frame.catch_tag])
     378dnl     __(cmpr(cr0,temp0,temp1))
     379dnl     __(mov imm2,imm1)
     380dnl     __(ldr imm1,[imm1,#catch_frame.link])
     381dnl     __(cmpri(cr1,imm1,0))
     382dnl     __(beq cr0,local_label(_throw_found))
     383dnl     __(addi imm0,imm0,fixnum_one)
     384dnl     __(beq- cr1,local_label(_throw_tag_not_found))
     385dnl     __(b local_label(_throw_loop))
     386dnl /* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
     387dnl /* frames. If target isn't a multiple-value receiver, discard extra values */
     388dnl /* (less hair, maybe.)  */
     389dnl local_label(_throw_found):
     390dnl     __(ldr imm1,[imm2,#catch_frame.mvflag])
     391dnl     __(cmpri(cr0,imm1,0))
     392dnl     __(cmpri(cr1,nargs,0))
     393dnl     __(mov fn,#0)
     394dnl     __(add imm1,vsp,nargs)
     395dnl     __(add imm1,[imm1,#-node_size])
     396dnl     __(bne cr0,local_label(_throw_all_values))
     397dnl     __(set_nargs(1))
     398dnl     __(beq cr1,local_label(_throw_default_1_val))
     399dnl     __(mov vsp,imm1)
     400dnl     __(b local_label(_throw_all_values))
     401dnl local_label(_throw_default_1_val):
     402dnl     __(mov imm4,#nil_value)
     403dnl     __(vpush1(imm4))
     404dnl local_label(_throw_all_values):
     405dnl     __(bl _SPnthrowvalues)
     406dnl     __(ldr imm3,[rcontext,#tcr.catch_top])
     407dnl     __(ldr imm1,[rcontext,#tcr.db_link])
     408dnl     __(ldr imm0,[imm3,#catch_frame.db_link])
     409dnl     __(ldr imm4,[imm3,#catch_frame.mvflag])
     410dnl     __(cmpr(cr0,imm0,imm1))
     411dnl     __(cmpri(cr1,imm4,0))
     412dnl     __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
     413dnl     __(beq cr0,local_label(_throw_dont_unbind))
     414dnl         __(bl _SPunbind_to)
     415dnl local_label(_throw_dont_unbind):
     416dnl     __(add imm0,vsp,nargs)
     417dnl     __(cmpri(cr0,nargs,0))
     418dnl     __(ldr imm1,[imm3,#catch_frame.csp])
     419dnl     __(ldr imm1,[imm1,#lisp_frame.savevsp])
     420dnl     __(bne cr1,local_label(_throw_multiple))
     421dnl         /* Catcher expects single value in arg_z  */
     422dnl     __(ldr arg_z,[imm0,#-node_size])
     423dnl     __(b local_label(_throw_pushed_values))
     424dnl local_label(_throw_multiple):
     425dnl     __(beq cr0,local_label(_throw_pushed_values))
     426dnl     __(mov imm2,nargs)
     427dnl local_label(_throw_mvloop):
     428dnl     __(subi imm2,imm2,fixnum_one)
     429dnl     __(cmpri(imm2,0))
     430dnl     __(ldru(temp0,-node_size(imm0)))
     431dnl     __(push(temp0,imm1))
     432dnl     __(bgt local_label(_throw_mvloop))
     433dnl local_label(_throw_pushed_values):
     434dnl     __(mov vsp,imm1)
     435dnl     __(ldr imm1,[imm3,#catch_frame.xframe])
     436dnl     __(str(imm1,tcr.xframe(rcontext)))
     437dnl     __(ldr sp,[imm3,#catch_frame.csp])
     438dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     439dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     440dnl     __(discard_lisp_frame())
     441dnl     __(mtlr loc_pc)
     442dnl         __(restore_catch_nvrs(imm3))
     443dnl     __(ldr imm3,[imm3,#catch_frame.link])
     444dnl     __(str(imm3,tcr.catch_top(rcontext)))
     445dnl     __(unlink(tsp))
     446dnl     __(bx lr)
     447dnl local_label(_throw_tag_not_found):
     448dnl     __(uuo_interr(error_throw_tag_missing,temp0))
     449dnl     __(strux(temp0,vsp,nargs))
     450dnl     __(b _SPthrow)
     451dnl
     452dnl
     453dnl /* This takes N multiple values atop the vstack.  */
     454dnl _spentry(nthrowvalues)
     455dnl         __(mov imm1,#1)
     456dnl     __(mov imm4,imm0)
     457dnl         __(str(imm1,tcr.unwinding(rcontext)))
     458dnl local_label(_nthrowv_nextframe):
     459dnl     __(subi imm4,imm4,fixnum_one)
     460dnl     __(cmpri(cr1,imm4,0))
     461dnl     __(ldr temp0,[rcontext,#tcr.catch_top])
     462dnl     __(ldr imm1,[rcontext,#tcr.db_link])
     463dnl     __(blt cr1,local_label(_nthrowv_done))
     464dnl     __(ldr imm0,[temp0,#catch_frame.db_link])
     465dnl     __(ldr imm3,[temp0,#catch_frame.link])
     466dnl     __(cmpr(cr0,imm0,imm1))
     467dnl     __(str(imm3,tcr.catch_top(rcontext)))
     468dnl     __(ldr temp1,[temp0,#catch_frame.catch_tag])
     469dnl     __(cmpri(cr7,temp1,unbound_marker))             /* unwind-protect ?  */
     470dnl     __(ldr first_nvr,[temp0,#catch_frame.xframe])
     471dnl     __(str(first_nvr,tcr.xframe(rcontext)))
     472dnl     __(ldr sp,[temp0,#catch_frame.csp])
     473dnl     __(beq cr0,local_label(_nthrowv_dont_unbind))
     474dnl     __(mflr loc_pc)
     475dnl         __(bl _SPunbind_to)
     476dnl     __(mtlr loc_pc)
     477dnl local_label(_nthrowv_dont_unbind):
     478dnl     __(beq cr7,local_label(_nthrowv_do_unwind))
     479dnl /* A catch frame.  If the last one, restore context from there.  */
     480dnl     __(bne cr1,local_label(_nthrowv_skip))
     481dnl     __(ldr imm0,[sp,#lisp_frame.savevsp])
     482dnl     __(str(rzero,lisp_frame.savevsp(sp)))   /* marker for stack overflow code  */
     483dnl     __(add imm1,vsp,nargs)
     484dnl     __(mov imm2,nargs)
     485dnl     __(b local_label(_nthrowv_push_test))
     486dnl local_label(_nthrowv_push_loop):
     487dnl     __(ldru(temp1,-node_size(imm1)))
     488dnl     __(push(temp1,imm0))
     489dnl local_label(_nthrowv_push_test):
     490dnl     __(cmpri(imm2,0))
     491dnl     __(subi imm2,imm2,fixnum_one)
     492dnl     __(bne local_label(_nthrowv_push_loop))
     493dnl     __(mov vsp,imm0)
     494dnl         __(restore_catch_nvrs(temp0))
     495dnl
     496dnl local_label(_nthrowv_skip):
     497dnl     __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
     498dnl     __(unlink(tsp))
     499dnl     __(discard_lisp_frame())
     500dnl     __(b local_label(_nthrowv_nextframe))
     501dnl local_label(_nthrowv_do_unwind):
     502dnl         /* This is harder.  Call the cleanup code with the multiple */
     503dnl     /* values (and nargs, which is a fixnum.)  Remember the throw count  */
     504dnl         /* (also a fixnum) as well.  */
     505dnl         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
     506dnl         /* protect.  (Clever, eh ?)  */
     507dnl     __(ldr first_nvr,[temp0,#catch_frame.xframe])
     508dnl     __(str(first_nvr,tcr.xframe(rcontext)))
     509dnl         __(restore_catch_nvrs(temp0))
     510dnl     __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
     511dnl     __(unlink(tsp))
     512dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     513dnl     __(ldr nfn,[sp,#lisp_frame.savefn])
     514dnl     __(mtctr loc_pc)        /* cleanup code address.  */
     515dnl     __(str(fn,lisp_frame.savefn(sp)))
     516dnl     __(mflr loc_pc)
     517dnl     __(mov fn,nfn)
     518dnl     __(str(loc_pc,lisp_frame.savelr(sp)))
     519dnl     __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* tsp overhead, nargs, throw count  */
     520dnl     __(TSP_Alloc_Var_Boxed_nz(imm0,imm1))
     521dnl     __(mov imm2,nargs)
     522dnl     __(add imm1,nargs,vsp)
     523dnl     __(la imm0,tsp_frame.data_offset(tsp))
     524dnl     __(str(nargs,0(imm0)))
     525dnl     __(b local_label(_nthrowv_tpushtest))
     526dnl local_label(_nthrowv_tpushloop):
     527dnl     __(ldru(temp0,-node_size(imm1)))
     528dnl     __(stru(temp0,node_size(imm0)))
     529dnl     __(subi imm2,imm2,fixnum_one)
     530dnl local_label(_nthrowv_tpushtest):
     531dnl     __(cmpri(imm2,0))
     532dnl     __(bne local_label(_nthrowv_tpushloop))
     533dnl     __(stru(imm4,node_size(imm0)))
     534dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     535dnl         /* Interrupts should be disabled here (we're calling and returning */
     536dnl         /* from the cleanup form.  Clear the tcr.unwinding flag, so that */
     537dnl         /* interrupts can be taken if they're enabled in the cleanup form.  */
     538dnl         __(str(rzero,tcr.unwinding(rcontext)))       
     539dnl     __(bctrl)
     540dnl         __(mov imm1,#1)
     541dnl     __(la imm0,tsp_frame.data_offset(tsp))
     542dnl         __(str(imm1,tcr.unwinding(rcontext)))
     543dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     544dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     545dnl     __(discard_lisp_frame())
     546dnl     __(mtlr loc_pc)
     547dnl     __(ldr nargs,[imm0,#0])
     548dnl     __(mov imm2,nargs)
     549dnl     __(b local_label(_nthrowv_tpoptest))
     550dnl local_label(_nthrowv_tpoploop):
     551dnl     __(ldru(temp0,node_size(imm0)))
     552dnl     __(vpush1(temp0))
     553dnl     __(subi imm2,imm2,fixnum_one)
     554dnl local_label(_nthrowv_tpoptest):
     555dnl     __(cmpri(imm2,0))
     556dnl     __(bne local_label(_nthrowv_tpoploop))
     557dnl     __(ldr imm4,[imm0,#node_size])
     558dnl     __(unlink(tsp))
     559dnl     __(b local_label(_nthrowv_nextframe))
     560dnl local_label(_nthrowv_done):
     561dnl         __(str(rzero,tcr.unwinding(rcontext)))
     562dnl         /* Poll for a deferred interrupt.  That clobbers nargs (which we've */
     563dnl         /* just expended a lot of effort to preserve), so expend a little *
     564dnl         /* more effort. */
     565dnl         __(mov imm4,nargs)
     566dnl         __(check_pending_interrupt())
     567dnl         __(mov nargs,imm4)
     568dnl         __(bx lr)
     569dnl
     570dnl /* This is a (slight) optimization.  When running an unwind-protect, */
     571dnl /* save the single value and the throw count in the tstack frame. */
     572dnl /* Note that this takes a single value in arg_z.  */
     573dnl _spentry(nthrow1value)
     574dnl         __(mov imm1,#1)
     575dnl     __(mov imm4,imm0)
     576dnl         __(str(imm1,tcr.unwinding(rcontext)))
     577dnl local_label(_nthrow1v_nextframe):
     578dnl     __(subi imm4,imm4,fixnum_one)
     579dnl     __(cmpri(cr1,imm4,0))
     580dnl     __(ldr temp0,[rcontext,#tcr.catch_top])
     581dnl     __(ldr imm1,[rcontext,#tcr.db_link])
     582dnl     __(set_nargs(1))
     583dnl     __(blt cr1,local_label(_nthrow1v_done))
     584dnl     __(ldr imm3,[temp0,#catch_frame.link])
     585dnl     __(ldr imm0,[temp0,#catch_frame.db_link])
     586dnl     __(cmpr(cr0,imm0,imm1))
     587dnl     __(str(imm3,tcr.catch_top(rcontext)))
     588dnl         __(ldr imm3,[temp0,#catch_frame.xframe])
     589dnl     __(ldr temp1,[temp0,#catch_frame.catch_tag])
     590dnl     __(cmpri(cr7,temp1,unbound_marker))             /* unwind-protect ?  */
     591dnl         __(str(imm3,tcr.xframe(rcontext)))
     592dnl     __(ldr sp,[temp0,#catch_frame.csp])
     593dnl     __(beq cr0,local_label(_nthrow1v_dont_unbind))
     594dnl      __(mflr loc_pc)
     595dnl          __(bl _SPunbind_to)
     596dnl      __(mtlr loc_pc)
     597dnl local_label(_nthrow1v_dont_unbind):
     598dnl     __(beq cr7,local_label(_nthrow1v_do_unwind))
     599dnl         /* A catch frame.  If the last one, restore context from there.  */
     600dnl     __(bne cr1,local_label(_nthrow1v_skip))
     601dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     602dnl         __(restore_catch_nvrs(temp0))
     603dnl local_label(_nthrow1v_skip):
     604dnl     __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
     605dnl     __(unlink(tsp))
     606dnl     __(discard_lisp_frame())
     607dnl     __(b local_label(_nthrow1v_nextframe))
     608dnl local_label(_nthrow1v_do_unwind):
     609dnl         /* This is harder, but not as hard (not as much BLTing) as the  */
     610dnl         /* multiple-value case.  */
     611dnl         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
     612dnl         /* protect.  (Clever, eh ?)  */
     613dnl
     614dnl         __(restore_catch_nvrs(temp0))
     615dnl     __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
     616dnl     __(unlink(tsp))
     617dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     618dnl     __(ldr nfn,[sp,#lisp_frame.savefn])
     619dnl     __(mtctr loc_pc)                /* cleanup code address.  */
     620dnl     __(str(fn,lisp_frame.savefn(sp)))
     621dnl     __(mflr loc_pc)
     622dnl     __(mov fn,nfn)
     623dnl     __(str(loc_pc,lisp_frame.savelr(sp)))
     624dnl     __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
     625dnl     __(str(arg_z,tsp_frame.data_offset(tsp)))
     626dnl     __(str(imm4,tsp_frame.data_offset+node_size(tsp)))
     627dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     628dnl         __(str(rzero,tcr.unwinding(rcontext)))
     629dnl     __(bctrl)
     630dnl         __(mov imm1,#1)
     631dnl     __(ldr arg_z,[tsp,#tsp_frame.data_offset])
     632dnl         __(str(imm1,tcr.unwinding(rcontext)))
     633dnl     __(ldr imm4,[tsp,#tsp_frame.data_offset+node_size])
     634dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     635dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     636dnl     __(discard_lisp_frame())
     637dnl     __(mtlr loc_pc)
     638dnl     __(unlink(tsp))
     639dnl     __(b local_label(_nthrow1v_nextframe))
     640dnl local_label(_nthrow1v_done):
     641dnl         __(str(rzero,tcr.unwinding(rcontext)))
     642dnl         /* nargs has an undefined value here, so we can clobber it while */
     643dnl         /* polling for a deferred interrupt  */
     644dnl         __(check_pending_interrupt())
     645dnl         __(bx lr)
     646dnl
     647dnl /* arg_z = symbol: bind it to its current value          */
     648dnl _spentry(bind_self)
     649dnl         __(ldr imm3,[arg_z,#symbol.binding_index])
     650dnl         __(ldr imm0,[rcontext,#tcr.tlb_limit])
     651dnl         __(cmpri(imm3,0))
     652dnl         __(trlle(imm0,imm3))           /* tlb too small  */
     653dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
     654dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     655dnl         __(ldr temp1,[imm2,imm3])
     656dnl         __(cmpri(cr1,temp1,no_thread_local_binding_marker))
     657dnl         __(beq 9f)
     658dnl         __(mov temp0,temp1)
     659dnl         __(bne cr1,1f)
     660dnl         __(ldr temp0,[arg_z,#symbol.vcell])
     661dnl 1:             
     662dnl         __(vpush1(temp1))
     663dnl         __(vpush1(imm3))
     664dnl         __(vpush1(imm1))
     665dnl         __(str temp0,imm2,imm3)
     666dnl         __(str(vsp,tcr.db_link(rcontext)))
     667dnl         __(bx lr)
     668dnl 9:      __(mov arg_y,#XSYMNOBIND)
     669dnl         __(set_nargs(2))
     670dnl         __(b _SPksignalerr)
     671dnl
     672dnl /* Bind symbol in arg_z to NIL                 */
     673dnl _spentry(bind_nil)
     674dnl         __(ldr imm3,[arg_z,#symbol.binding_index])
     675dnl         __(ldr imm0,[rcontext,#tcr.tlb_limit])
     676dnl         __(cmpri(imm3,0))
     677dnl         __(beq- 9f)
     678dnl         __(trlle(imm0,imm3))           /* tlb too small  */
     679dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
     680dnl         __(ldr temp1,[imm2,imm3])
     681dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     682dnl         __(mov imm0,#nil_value)
     683dnl         __(vpush1(temp1))
     684dnl         __(vpush1(imm3))
     685dnl         __(vpush1(imm1))
     686dnl         __(str imm0,imm2,imm3)
     687dnl         __(str(vsp,tcr.db_link(rcontext)))
     688dnl         __(bx lr)
     689dnl 9:      __(mov arg_y,#XSYMNOBIND)
     690dnl         __(set_nargs(2))
     691dnl         __(b _SPksignalerr)
     692dnl
     693dnl       
     694dnl /* Bind symbol in arg_z to its current value;  trap if symbol is unbound */
     695dnl _spentry(bind_self_boundp_check)
     696dnl         __(ldr imm3,[arg_z,#symbol.binding_index])
     697dnl         __(ldr imm0,[rcontext,#tcr.tlb_limit])
     698dnl         __(cmpri(imm3,0))
     699dnl         __(trlle(imm0,imm3))           /* tlb too small  */
     700dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
     701dnl         __(ldr temp1,[imm2,imm3])
     702dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     703dnl         __(beq 9f)              /* no real tlb index  */
     704dnl         __(cmpri(temp1,no_thread_local_binding_marker))
     705dnl         __(mov temp0,temp1)
     706dnl         __(bne 1f)
     707dnl         __(ldr temp0,[arg_z,#symbol.vcell])
     708dnl 1:      __(treqi(temp0,unbound_marker))       
     709dnl         __(vpush1(temp1))
     710dnl         __(vpush1(imm3))
     711dnl         __(vpush1(imm1))
     712dnl         __(str temp0,imm2,imm3)
     713dnl         __(str(vsp,tcr.db_link(rcontext)))
     714dnl         __(bx lr)
     715dnl 9:      __(mov arg_y,#XSYMNOBIND)
     716dnl         __(set_nargs(2))
     717dnl         __(b _SPksignalerr)
     718dnl
     719dnl
     720dnl /* The function pc_luser_xp() - which is used to ensure that suspended threads */
     721dnl /* are suspended in a GC-safe way - has to treat these subprims (which  */
     722dnl /* implement the EGC write-barrier) specially.  Specifically, a store that */
     723dnl /* might introduce an intergenerational reference (a young pointer stored  */
     724dnl /* in an old object) has to "memoize" that reference by setting a bit in  */
     725dnl /* the global "refbits" bitmap. */
     726dnl /* This has to happen atomically, and has to happen atomically wrt GC. */
     727dnl /* Note that updating a word in a bitmap is itself not atomic, unless we use */
     728dnl /* interlocked loads and stores. */
     729dnl
     730dnl
     731dnl /* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
     732dnl /* are in the function, we can do the store (even if it's already been done)  */
     733dnl /* and calculate whether or not we need to set the bit out-of-line.  (Actually */
     734dnl /* setting the bit needs to be done atomically, unless we're sure that other */
     735dnl /* threads are suspended.) */
     736dnl /* We can unconditionally set the suspended thread's PC to its LR. */
     737dnl     
     738dnl         .globl C(egc_write_barrier_start)
     739dnl _spentry(rplaca)
     740dnl C(egc_write_barrier_start):
     741dnl         __(cmplr(cr2,arg_z,arg_y))
     742dnl         __(_rplaca(arg_y,arg_z))
     743dnl         __(blelr cr2)
     744dnl         __(ref_global(imm2,ref_base))
     745dnl         __(sub imm0,arg_y,imm2)
     746dnl         __(load_highbit(imm3))
     747dnl         __(srri(imm0,imm0,dnode_shift))       
     748dnl         __(ref_global(imm1,oldspace_dnode_count))
     749dnl         __(extract_bit_shift_count(imm4,imm0))
     750dnl         __(cmplr(imm0,imm1))
     751dnl         __(srr(imm3,imm3,imm4))
     752dnl         __(srri(imm0,imm0,bitmap_shift))       
     753dnl         __(ref_global(imm2,refbits))
     754dnl         __(bgelr)
     755dnl         __(slri(imm0,imm0,word_shift))
     756dnl         __(ldr imm1,[imm2,imm0])
     757dnl         __(and. imm1,imm1,imm3)
     758dnl         __(bnelr)
     759dnl 1:      __(lrarx(imm1,imm2,imm0))
     760dnl         __(or imm1,imm1,imm3)
     761dnl         __(strcx(imm1,imm2,imm0))
     762dnl         __(bne- 1b)
     763dnl         __(isync)
     764dnl         __(bx lr)
     765dnl
     766dnl         .globl C(egc_rplacd)
     767dnl _spentry(rplacd)
     768dnl C(egc_rplacd):
     769dnl         __(cmplr(cr2,arg_z,arg_y))
     770dnl     __(_rplacd(arg_y,arg_z))
     771dnl         __(blelr cr2)
     772dnl         __(ref_global(imm2,ref_base))
     773dnl         __(sub imm0,arg_y,imm2)
     774dnl         __(load_highbit(imm3))
     775dnl         __(srri(imm0,imm0,dnode_shift))       
     776dnl         __(ref_global(imm1,oldspace_dnode_count))
     777dnl         __(extract_bit_shift_count(imm4,imm0))
     778dnl         __(cmplr(imm0,imm1))
     779dnl         __(srr(imm3,imm3,imm4))
     780dnl         __(srri(imm0,imm0,bitmap_shift))       
     781dnl         __(ref_global(imm2,refbits))
     782dnl         __(bgelr)
     783dnl         __(slri(imm0,imm0,word_shift))
     784dnl         __(ldr imm1,[imm2,imm0])
     785dnl         __(and. imm1,imm1,imm3)
     786dnl         __(bnelr)       
     787dnl 1:      __(lrarx(imm1,imm2,imm0))
     788dnl         __(or imm1,imm1,imm3)
     789dnl         __(strcx(imm1,imm2,imm0))
     790dnl         __(bne- 1b)
     791dnl         __(isync)
     792dnl         __(bx lr)
     793dnl
     794dnl /* Storing into a gvector can be handled the same way as storing into a CONS. */
     795dnl
     796dnl         .globl C(egc_gvset)
     797dnl _spentry(gvset)
     798dnl C(egc_gvset):
     799dnl         __(cmplr(cr2,arg_z,arg_x))
     800dnl         __(la imm0,misc_data_offset(arg_y))
     801dnl         __(str arg_z,arg_x,imm0)
     802dnl         __(blelr cr2)
     803dnl         __(add imm0,imm0,arg_x)
     804dnl         __(ref_global(imm2,ref_base))
     805dnl         __(load_highbit(imm3))
     806dnl         __(ref_global(imm1,oldspace_dnode_count))
     807dnl         __(sub imm0,imm0,imm2)
     808dnl         __(srri(imm0,imm0,dnode_shift))       
     809dnl         __(cmplr(imm0,imm1))
     810dnl         __(extract_bit_shift_count(imm4,imm0))
     811dnl         __(srri(imm0,imm0,bitmap_shift))       
     812dnl         __(srr(imm3,imm3,imm4))
     813dnl         __(ref_global(imm2,refbits))
     814dnl         __(bgelr)
     815dnl         __(slri(imm0,imm0,word_shift))
     816dnl         __(ldrx(imm1,imm2,imm0))
     817dnl         __(and. imm1,imm1,imm3)
     818dnl         __(bnelr)       
     819dnl 1:      __(lrarx(imm1,imm2,imm0))
     820dnl         __(or imm1,imm1,imm3)
     821dnl         __(strcx(imm1,imm2,imm0))
     822dnl         __(bne- 1b)
     823dnl         __(isync)
     824dnl         __(bx lr)
     825dnl
     826dnl /* This is a special case of storing into a gvector: if we need to memoize  */
     827dnl /* the store, record the address of the hash-table vector in the refmap,  */
     828dnl /* as well. */
     829dnl         .globl C(egc_set_hash_key)       
     830dnl _spentry(set_hash_key)
     831dnl C(egc_set_hash_key):
     832dnl         __(cmplr(cr2,arg_z,arg_x))
     833dnl         __(la imm0,misc_data_offset(arg_y))
     834dnl         __(str arg_z,arg_x,imm0)
     835dnl         __(blelr cr2)
     836dnl         __(add imm0,imm0,arg_x)
     837dnl         __(ref_global(imm2,ref_base))
     838dnl         __(load_highbit(imm3))
     839dnl         __(ref_global(imm1,oldspace_dnode_count))
     840dnl         __(sub imm0,imm0,imm2)
     841dnl         __(srri(imm0,imm0,dnode_shift))       
     842dnl         __(cmplr(imm0,imm1))
     843dnl         __(extract_bit_shift_count(imm4,imm0))
     844dnl         __(srri(imm0,imm0,bitmap_shift))       
     845dnl         __(srr(imm3,imm3,imm4))
     846dnl         __(ref_global(imm2,refbits))
     847dnl         __(bgelr)
     848dnl         __(slri(imm0,imm0,word_shift))
     849dnl         __(ldrx(imm1,imm2,imm0))
     850dnl         __(and. imm1,imm1,imm3)
     851dnl         __(bne 2f)       
     852dnl 1:      __(lrarx(imm1,imm2,imm0))
     853dnl         __(or imm1,imm1,imm3)
     854dnl         __(strcx(imm1,imm2,imm0))
     855dnl         __(bne- 1b)
     856dnl         __(isync)
     857dnl 2:             
     858dnl         __(ref_global(imm1,ref_base))
     859dnl         __(sub imm0,arg_x,imm1)
     860dnl         __(srri(imm0,imm0,dnode_shift))
     861dnl         __(load_highbit(imm3))
     862dnl         __(extract_bit_shift_count(imm4,imm0))
     863dnl         __(srri(imm0,imm0,bitmap_shift))
     864dnl         __(srr(imm3,imm3,imm4))
     865dnl         __(slri(imm0,imm0,word_shift))
     866dnl         __(ldrx(imm1,imm2,imm0))
     867dnl         __(and. imm1,imm1,imm3)
     868dnl         __(bnelr)
     869dnl 3:      __(lrarx(imm1,imm2,imm0))
     870dnl         __(or imm1,imm1,imm3)
     871dnl         __(strcx(imm1,imm2,imm0))
     872dnl         __(bne- 3b)
     873dnl         __(isync)
     874dnl         __(bx lr)
     875dnl         
     876dnl /*
     877dnl    Interrupt handling (in pc_luser_xp()) notes:     
     878dnl    If we are in this function and before the test which follows the
     879dnl    conditional (at egc_store_node_conditional), or at that test
     880dnl    and cr0`eq' is clear, pc_luser_xp() should just let this continue
     881dnl    (we either haven't done the store conditional yet, or got a
     882dnl    possibly transient failure.)  If we're at that test and the
     883dnl    cr0`EQ' bit is set, then the conditional store succeeded and
     884dnl    we have to atomically memoize the possible intergenerational
     885dnl    reference.  Note that the local labels 4 and 5 are in the
     886dnl    body of the next subprim (and at or beyond 'egc_write_barrier_end').
     887dnl
     888dnl    N.B:     it's not possible to really understand what's going on just
     889dnl    by the state of the cr0`eq' bit.  A transient failure in the
     890dnl    conditional stores that handle memoization might clear cr0`eq'
     891dnl    without having completed the memoization.
     892dnl */
     893dnl
     894dnl         .globl C(egc_store_node_conditional)
     895dnl         .globl C(egc_write_barrier_end)
     896dnl _spentry(store_node_conditional)
     897dnl C(egc_store_node_conditional):
     898dnl         __(cmplr(cr2,arg_z,arg_x))
     899dnl         __(vpop(temp0))
     900dnl         __(unbox_fixnum(imm4,temp0))
     901dnl 1:      __(lrarx(temp1,arg_x,imm4))
     902dnl         __(cmpr(cr1,temp1,arg_y))
     903dnl         __(bne cr1,5f)
     904dnl         __(strcx(arg_z,arg_x,imm4))
     905dnl     .globl C(egc_store_node_conditional_test)
     906dnl C(egc_store_node_conditional_test):
     907dnl         __(bne 1b)
     908dnl         __(isync)
     909dnl         __(add imm0,imm4,arg_x)
     910dnl         __(ref_global(imm2,ref_base))
     911dnl         __(ref_global(imm1,oldspace_dnode_count))
     912dnl         __(sub imm0,imm0,imm2)
     913dnl         __(load_highbit(imm3))
     914dnl         __(srri(imm0,imm0,dnode_shift))       
     915dnl         __(cmplr(imm0,imm1))
     916dnl         __(extract_bit_shift_count(imm2,imm0))
     917dnl         __(srri(imm0,imm0,bitmap_shift))       
     918dnl         __(srr(imm3,imm3,imm2))
     919dnl         __(ref_global(imm2,refbits))
     920dnl         __(bge 4f)
     921dnl         __(slri(imm0,imm0,word_shift))
     922dnl 2:      __(lrarx(imm1,imm2,imm0))
     923dnl         __(or imm1,imm1,imm3)
     924dnl         __(strcx( imm1,imm2,imm0))
     925dnl         __(bne- 2b)
     926dnl         __(isync)
     927dnl         __(b 4f)
     928dnl
     929dnl /* arg_z = new value, arg_y = expected old value, arg_x = hash-vector,
     930dnl    vsp`0' = (boxed) byte-offset
     931dnl    Interrupt-related issues are as in store_node_conditional, but
     932dnl    we have to do more work to actually do the memoization.*/
     933dnl _spentry(set_hash_key_conditional)
     934dnl     .globl C(egc_set_hash_key_conditional)
     935dnl C(egc_set_hash_key_conditional):
     936dnl     __(cmplr(cr2,arg_z,arg_x))
     937dnl     __(vpop(imm4))
     938dnl     __(unbox_fixnum(imm4,imm4))
     939dnl 1:  __(lrarx(temp1,arg_x,imm4))
     940dnl     __(cmpr(cr1,temp1,arg_y))
     941dnl     __(bne cr1,5f)
     942dnl     __(strcx(arg_z,arg_x,imm4))
     943dnl     .globl C(egc_set_hash_key_conditional_test)
     944dnl C(egc_set_hash_key_conditional_test):       
     945dnl     __(bne 1b)
     946dnl     __(isync)
     947dnl     __(add imm0,imm4,arg_x)
     948dnl     __(ref_global(imm2,ref_base))
     949dnl     __(ref_global(imm1,oldspace_dnode_count))
     950dnl     __(sub imm0,imm0,imm2)
     951dnl     __(load_highbit(imm3))
     952dnl     __(srri(imm0,imm0,dnode_shift))
     953dnl     __(cmplr(imm0,imm1))
     954dnl     __(extract_bit_shift_count(imm2,imm0))
     955dnl     __(srri(imm0,imm0,bitmap_shift))
     956dnl     __(srr(imm3,imm3,imm2))
     957dnl     __(ref_global(imm2,refbits))
     958dnl     __(bge 4f)
     959dnl     __(slri(imm0,imm0,word_shift))
     960dnl 2:  __(lrarx(imm1,imm2,imm0))
     961dnl     __(or imm1,imm1,imm3)
     962dnl     __(strcx(imm1,imm2,imm0))
     963dnl     __(bne- 2b)
     964dnl     __(isync)
     965dnl     /* Memoize hash table header */         
     966dnl         __(ref_global(imm1,ref_base))
     967dnl         __(sub imm0,arg_x,imm1)
     968dnl         __(srri(imm0,imm0,dnode_shift))
     969dnl         __(load_highbit(imm3))
     970dnl         __(extract_bit_shift_count(imm4,imm0))
     971dnl         __(srri(imm0,imm0,bitmap_shift))
     972dnl         __(srr(imm3,imm3,imm4))
     973dnl         __(slri(imm0,imm0,word_shift))
     974dnl         __(ldrx(imm1,imm2,imm0))
     975dnl         __(and. imm1,imm1,imm3)
     976dnl         __(bne 4f)
     977dnl 3:      __(lrarx(imm1,imm2,imm0))
     978dnl         __(or imm1,imm1,imm3)
     979dnl         __(strcx(imm1,imm2,imm0))
     980dnl         __(bne- 3b)
     981dnl         __(isync)
     982dnl C(egc_write_barrier_end):
     983dnl 4:  __(mov arg_z,#t_value)
     984dnl     __(bx lr)
     985dnl 5:      __(mov imm0,#RESERVATION_DISCHARGE)
     986dnl         __(strcx(rzero,0,imm0))
     987dnl     __(mov arg_z,#nil_value)
     988dnl     __(bx lr)
     989dnl     
     990dnl     
     991dnl           
     992dnl     
     993dnl
     994dnl /* We always have to create a tsp frame (even if nargs is 0), so the compiler  */
     995dnl /* doesn't get confused.  */
     996dnl _spentry(stkconslist)
     997dnl     __(mov arg_z,#nil_value)
     998dnl     __(cmpri(cr1,nargs,0))
     999dnl     __(add imm1,nargs,nargs)
     1000dnl     __(addi imm1,imm1,tsp_frame.fixed_overhead)
     1001dnl     __(TSP_Alloc_Var_Boxed(imm1,imm2))
     1002dnl     __(la imm1,tsp_frame.data_offset+fulltag_cons(tsp))
     1003dnl     __(b 2f)
     1004dnl 1:  __(ldr temp0,[vsp,#0])
     1005dnl     __(cmpri(cr1,nargs,fixnum_one))
     1006dnl     __(la vsp,node_size(vsp))
     1007dnl     __(_rplaca(imm1,temp0))
     1008dnl     __(_rplacd(imm1,arg_z))
     1009dnl     __(mov arg_z,imm1)
     1010dnl     __(la imm1,cons.size(imm1))
     1011dnl     __(la nargs,-fixnum_one(nargs))
     1012dnl 2:
     1013dnl     __(bne cr1,1b)
     1014dnl     __(bx lr)
     1015dnl
     1016dnl /* do list*: last arg in arg_z, all others vpushed,  */
     1017dnl /* nargs set to #args vpushed.  */
     1018dnl _spentry(stkconslist_star)
     1019dnl     __(cmpri(cr1,nargs,0))
     1020dnl     __(add imm1,nargs,nargs)
     1021dnl     __(addi imm1,imm1,tsp_frame.fixed_overhead)
     1022dnl     __(TSP_Alloc_Var_Boxed(imm1,imm2))
     1023dnl     __(la imm1,tsp_frame.data_offset+fulltag_cons(tsp))
     1024dnl     __(b 2f)
     1025dnl 1:  __(ldr temp0,[vsp,#0])
     1026dnl     __(cmpri(cr1,nargs,fixnum_one))
     1027dnl     __(la vsp,node_size(vsp))
     1028dnl     __(_rplaca(imm1,temp0))
     1029dnl     __(_rplacd(imm1,arg_z))
     1030dnl     __(mov arg_z,imm1)
     1031dnl     __(la imm1,cons.size(imm1))
     1032dnl     __(la nargs,-fixnum_one(nargs))
     1033dnl 2:
     1034dnl     __(bne cr1,1b)
     1035dnl     __(bx lr)
     1036dnl
     1037dnl
     1038dnl /* Make a stack-consed simple-vector out of the NARGS objects  */
     1039dnl /* on top of the vstack; return it in arg_z.  */
     1040dnl _spentry(mkstackv)
     1041dnl     __(cmpri(cr1,nargs,0))
     1042dnl     __(dnode_align(imm1,nargs,tsp_frame.fixed_overhead+node_size))
     1043dnl     __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
     1044dnl     __(slwi imm0,nargs,num_subtag_bits-fixnumshift)
     1045dnl     __(ori imm0,imm0,subtag_simple_vector)
     1046dnl     __(str(imm0,tsp_frame.data_offset(tsp)))
     1047dnl     __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
     1048dnl     __(beq- cr1,2f)
     1049dnl     __(la imm0,misc_data_offset(arg_z))
     1050dnl     __(add imm1,imm0,nargs)
     1051dnl 1:
     1052dnl     __(la nargs,-node_size(nargs))
     1053dnl     __(cmpri(cr1,nargs,0))
     1054dnl     __(ldr temp1,[vsp,#0])
     1055dnl     __(la vsp,node_size(vsp))
     1056dnl     __(stru(temp1,-node_size(imm1)))
     1057dnl     __(bne cr1,1b)
     1058dnl 2:
     1059dnl     __(bx lr)
     1060dnl
     1061dnl     
     1062dnl         
     1063dnl
     1064dnl _spentry(setqsym)
     1065dnl     __(ldr imm0,[arg_y,#symbol.flags])
     1066dnl     __(andi. imm0,imm0,sym_vbit_const_mask)
     1067dnl     __(beq _SPspecset)
     1068dnl     __(mov arg_z,arg_y)
     1069dnl     __(mov arg_y,#XCONST)
     1070dnl     __(set_nargs(2))
     1071dnl     __(b _SPksignalerr)
     1072dnl
     1073dnl
     1074dnl     
     1075dnl _spentry(progvsave)
     1076dnl     /* Error if arg_z isn't a proper list.  That's unlikely, */
     1077dnl     /* but it's better to check now than to crash later. */
     1078dnl     
     1079dnl     __(cmpri(arg_z,nil_value))
     1080dnl     __(mov arg_x,arg_z)     /* fast  */
     1081dnl     __(mov temp1,arg_z)     /* slow  */
     1082dnl     __(beq 9f)              /* Null list is proper  */
     1083dnl 0: 
     1084dnl     __(trap_unless_list(arg_x,imm0))
     1085dnl     __(_cdr(temp2,arg_x))   /* (null (cdr fast)) ?  */
     1086dnl     __(cmpri(cr3,temp2,nil_value))
     1087dnl     __(trap_unless_list(temp2,imm0,cr0))
     1088dnl     __(_cdr(arg_x,temp2))
     1089dnl     __(beq cr3,9f)
     1090dnl     __(_cdr(temp1,temp1))
     1091dnl     __(cmpr(arg_x,temp1))
     1092dnl     __(bne 0b)
     1093dnl     __(mov arg_y,#XIMPROPERLIST)
     1094dnl     __(set_nargs(2))
     1095dnl     __(b _SPksignalerr)
     1096dnl 9:  /* Whew          */
     1097dnl     
     1098dnl         /* Next, determine the length of arg_y.  We  */
     1099dnl         /* know that it's a proper list.  */
     1100dnl     __(mov imm0,#-node_size)
     1101dnl     __(mov arg_x,arg_y)
     1102dnl 1:
     1103dnl     __(cmpri(cr0,arg_x,nil_value))
     1104dnl     __(la imm0,node_size(imm0))
     1105dnl     __(_cdr(arg_x,arg_x))
     1106dnl     __(bne 1b)
     1107dnl     /* imm0 is now (boxed) triplet count.  */
     1108dnl     /* Determine word count, add 1 (to align), and make room.  */
     1109dnl     /* if count is 0, make an empty tsp frame and exit  */
     1110dnl     __(cmpri(cr0,imm0,0))
     1111dnl     __(add imm1,imm0,imm0)
     1112dnl     __(add imm1,imm1,imm0)
     1113dnl         __(dnode_align(imm1,imm1,node_size))
     1114dnl     __(bne+ cr0,2f)
     1115dnl      __(TSP_Alloc_Fixed_Boxed(2*node_size))
     1116dnl      __(bx lr)
     1117dnl 2:
     1118dnl     __(la imm1,tsp_frame.fixed_overhead(imm1))      /* tsp header  */
     1119dnl     __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
     1120dnl     __(str(imm0,tsp_frame.data_offset(tsp)))
     1121dnl     __(ldr imm2,[tsp,#tsp_frame.backlink])
     1122dnl     __(mov arg_x,arg_y)
     1123dnl     __(ldr imm1,[rcontext,#tcr.db_link])
     1124dnl         __(ldr imm3,[rcontext,#tcr.tlb_limit])
     1125dnl 3:
     1126dnl         __(cmpri(cr1,arg_z,nil_value))
     1127dnl     __(_car(temp0,arg_x))
     1128dnl         __(ldr imm0,[temp0,#symbol.binding_index])
     1129dnl     __(_cdr(arg_x,arg_x))
     1130dnl         __(trlle(imm3,imm0))
     1131dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer]) /* Need to reload after trap  */
     1132dnl         __(ldrx(temp3,imm4,imm0))
     1133dnl     __(cmpri(cr0,arg_x,nil_value))
     1134dnl         __(mov temp2,#unbound_marker)
     1135dnl         __(beq cr1,4f)
     1136dnl     __(_car(temp2,arg_z))
     1137dnl     __(_cdr(arg_z,arg_z))
     1138dnl 4:      __(push(temp3,imm2))
     1139dnl     __(push(imm0,imm2))
     1140dnl     __(push(imm1,imm2))
     1141dnl         __(str temp2,imm4,imm0)
     1142dnl     __(mov imm1,imm2)
     1143dnl     __(bne cr0,3b)
     1144dnl     __(str(imm2,tcr.db_link(rcontext)))
     1145dnl     __(bx lr)
     1146dnl
     1147dnl     
     1148dnl /* Allocate a miscobj on the temp stack.  (Push a frame on the tsp and  */
     1149dnl /* heap-cons the object if there's no room on the tstack.)  */
     1150dnl _spentry(stack_misc_alloc)
     1151dnl      __(rlwinm. imm2,arg_y,32-fixnumshift,0,(8+fixnumshift)-1)
     1152dnl      __(unbox_fixnum(imm0,arg_z))
     1153dnl      __(extract_fulltag(imm1,imm0))
     1154dnl      __(bne- cr0,9f)
     1155dnl      __(cmpri(cr0,imm1,fulltag_nodeheader))
     1156dnl      __(mov imm3,imm0)
     1157dnl      __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
     1158dnl      __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits) /* imm0 now = header  */
     1159dnl      __(mov imm2,arg_y)
     1160dnl      __(beq cr0,1f) /* do probe if node object  */
     1161dnl                     /* (fixnum element count = byte count).  */
     1162dnl      __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
     1163dnl      __(bng cr1,1f) /* do probe if 32-bit imm object  */
     1164dnl      __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
     1165dnl      __(srwi imm2,imm2,1)
     1166dnl      __(bgt cr0,3f)
     1167dnl      __(bgt cr1,1f)
     1168dnl      __(srwi imm2,imm2,1)
     1169dnl /* imm2 now = byte count.  Add 4 for header, 7 to align, then  */
     1170dnl /*  clear low three bits.  */
     1171dnl 1:
     1172dnl          __(dnode_align(imm3,imm2,tsp_frame.fixed_overhead+node_size))
     1173dnl      __(cmplri(cr0,imm3,tstack_alloc_limit)) /* more than limit ?  */
     1174dnl      __(bgt- cr0,0f)
     1175dnl      __(TSP_Alloc_Var_Boxed_nz(imm3,imm4))
     1176dnl
     1177dnl /* Slap the header on the vector, then return.  */
     1178dnl      __(str(imm0,tsp_frame.data_offset(tsp)))
     1179dnl      __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
     1180dnl      __(bx lr)
     1181dnl 9:
     1182dnl
     1183dnl
     1184dnl
     1185dnl /* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
     1186dnl /* sure that there's an empty tsp frame to keep the compiler happy.  */
     1187dnl 0:
     1188dnl      __(TSP_Alloc_Fixed_Unboxed(0))
     1189dnl      __(b _SPmisc_alloc)
     1190dnl 3:
     1191dnl      __(cmplri(imm3,subtag_double_float_vector))
     1192dnl      __(slwi imm2,arg_y,1)
     1193dnl      __(beq 1b)
     1194dnl      __(addi imm2,arg_y,7<<fixnumshift)
     1195dnl      __(srwi imm2,imm2,fixnumshift+3)
     1196dnl      __(b 1b)
     1197dnl
     1198dnl         
     1199dnl /* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
     1200dnl /* initial-contents.  Note that this can be used to cons any type of initialized  */
     1201dnl /* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
     1202dnl /* objects.  */
     1203dnl /* Note that we're guaranteed to win (or force GC, or run out of memory)  */
     1204dnl /* because nargs < 32K.  */
     1205dnl _spentry(gvector)
     1206dnl         __(subi nargs,nargs,node_size)
     1207dnl     __(ldrx(arg_z,vsp,nargs))
     1208dnl     __(unbox_fixnum(imm0,arg_z))
     1209dnl         __ifdef(`PPC64')
     1210dnl          __(sldi imm1,nargs,num_subtag_bits-fixnum_shift)
     1211dnl          __(or imm0,imm0,imm1)
     1212dnl         __else
     1213dnl      __(rlwimi imm0,nargs,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits)
     1214dnl         __endif
     1215dnl         __(dnode_align(imm1,nargs,node_size))
     1216dnl     __(Misc_Alloc(arg_z,imm0,imm1))
     1217dnl     __(mov imm1,nargs)
     1218dnl     __(la imm2,misc_data_offset(imm1))
     1219dnl     __(b 2f)
     1220dnl 1:
     1221dnl     __(str temp0,arg_z,imm2)
     1222dnl 2:
     1223dnl     __(subi imm1,imm1,node_size)
     1224dnl     __(cmpri(cr0,imm1,0))
     1225dnl     __(subi imm2,imm2,node_size)
     1226dnl     __(vpop(temp0))         /* Note the intentional fencepost: */
     1227dnl                             /* discard the subtype as well.  */
     1228dnl     __(bge cr0,1b)
     1229dnl     __(bx lr)
     1230dnl     
     1231dnl     
     1232dnl     
     1233dnl     
     1234dnl _spentry(fitvals)
     1235dnl     __(subf. imm0,nargs,imm0)
     1236dnl     __(mov imm1,#nil_value)
     1237dnl     __(bge 2f)
     1238dnl     __(sub vsp,vsp,imm0)
     1239dnl     __(bx lr)
     1240dnl 1:
     1241dnl     __(subic. imm0,imm0,node_size)
     1242dnl     __(vpush1(imm1))
     1243dnl     __(addi nargs,nargs,node_size)
     1244dnl 2:
     1245dnl     __(bne 1b)
     1246dnl     __(bx lr)
     1247dnl
     1248dnl
     1249dnl _spentry(nthvalue)
     1250dnl     __(add imm0,vsp,nargs)
     1251dnl     __(ldr imm1,[imm0,#0])
     1252dnl     __(cmplr(imm1,nargs))   /*  do unsigned compare:         if (n < 0) => nil.  */
     1253dnl     __(mov arg_z,#nil_value)
     1254dnl     __(neg imm1,imm1)
     1255dnl     __(subi imm1,imm1,node_size)
     1256dnl     __(bge 1f)
     1257dnl     __(ldrx(arg_z,imm0,imm1))
     1258dnl 1: 
     1259dnl     __(la vsp,node_size(imm0))
     1260dnl     __(bx lr)
     1261dnl         
     1262dnl
     1263dnl             
     1264dnl /* Provide default (NIL) values for &optional arguments; imm0 is  */
     1265dnl /* the (fixnum) upper limit on the total of required and &optional  */
     1266dnl /* arguments.  nargs is preserved, all arguments wind up on the  */
     1267dnl /* vstack.  */
     1268dnl _spentry(default_optional_args)
     1269dnl     __(cmplr( cr7,nargs,imm0))
     1270dnl     __(mov imm5,#nil_value)
     1271dnl     __(vpush_argregs())
     1272dnl     __(mov imm1,nargs)
     1273dnl     __(bgelr cr7)
     1274dnl 1: 
     1275dnl     __(addi imm1,imm1,fixnum_one)
     1276dnl     __(cmpr(cr0,imm1,imm0))
     1277dnl     __(vpush1(imm5))
     1278dnl     __(bne cr0,1b)
     1279dnl     __(bx lr)
     1280dnl     
     1281dnl /* Indicate whether &optional arguments were actually supplied.  nargs  */
     1282dnl /* contains the actual arg count (minus the number of required args);  */
     1283dnl /* imm0 contains the number of &optional args in the lambda list.  */
     1284dnl /* Note that nargs may be > imm0 if &rest/&key is involved.  */
     1285dnl _spentry(opt_supplied_p)
     1286dnl     __(mov imm1,#0)
     1287dnl 1:
     1288dnl     /* (vpush (< imm1 nargs))  */
     1289dnl         __ifdef(`PPC64')
     1290dnl      __(xor imm2,imm1,nargs)
     1291dnl      __(sradi imm2,imm2,63)
     1292dnl      __(or imm2,imm2,imm1)
     1293dnl      __(addi imm1,imm1,fixnumone)
     1294dnl      __(cmpr(cr0,imm1,imm0))
     1295dnl      __(subf imm2,nargs,imm2)
     1296dnl      __(srdi imm2,imm2,63)
     1297dnl          __(mulli imm2,imm2,t_offset)
     1298dnl      __(addi imm2,imm2,nil_value)
     1299dnl      __(vpush1(imm2))
     1300dnl      __(bne cr0,1b)
     1301dnl      __(bx lr)
     1302dnl         __else
     1303dnl      __(xor imm2,imm1,nargs)
     1304dnl      __(srawi imm2,imm2,31)
     1305dnl      __(or imm2,imm2,imm1)
     1306dnl      __(addi imm1,imm1,fixnumone)
     1307dnl      __(cmpr(cr0,imm1,imm0))
     1308dnl      __(subf imm2,nargs,imm2)
     1309dnl      __(srwi imm2,imm2,31)
     1310dnl      __(insrwi imm2,imm2,1,27)
     1311dnl      __(addi imm2,imm2,nil_value)
     1312dnl      __(vpush1(imm2))
     1313dnl      __(bne cr0,1b)
     1314dnl      __(bx lr)
     1315dnl         __endif
     1316dnl     
     1317dnl
     1318dnl
     1319dnl /* If nargs is <= imm0, vpush a nil.  Otherwise, cons a list of length  */
     1320dnl /* (- nargs imm0) and vpush it.  */
     1321dnl /* Use this entry point to heap-cons a simple &rest arg.  */
     1322dnl _spentry(heap_rest_arg)
     1323dnl     __(mov imm0,#0)
     1324dnl     __(vpush_argregs())
     1325dnl     __(sub imm1,nargs,imm0)
     1326dnl     __(cmpri(imm1,0))
     1327dnl     __(mov arg_z,#nil_value)
     1328dnl     __(b 2f)
     1329dnl 1:
     1330dnl     __(ldr temp0,[vsp,#0])
     1331dnl     __(cmpri(imm1,fixnum_one))
     1332dnl     __(la vsp,node_size(vsp))
     1333dnl     __(Cons(arg_z,temp0,arg_z))
     1334dnl     __(subi imm1,imm1,fixnum_one)
     1335dnl 2:
     1336dnl     __(bgt 1b)
     1337dnl     __(vpush1(arg_z))
     1338dnl     __(bx lr)
     1339dnl
     1340dnl     
     1341dnl /* And this entry point when the argument registers haven't yet been  */
     1342dnl /* vpushed (as is typically the case when required/&rest but no  */
     1343dnl /* &optional/&key.)  */
     1344dnl _spentry(req_heap_rest_arg)
     1345dnl     __(vpush_argregs())
     1346dnl     __(sub imm1,nargs,imm0)
     1347dnl     __(cmpri(imm1,0))
     1348dnl     __(mov arg_z,#nil_value)
     1349dnl     __(b 2f)
     1350dnl 1:
     1351dnl     __(ldr temp0,[vsp,#0])
     1352dnl     __(cmpri(imm1,fixnum_one))
     1353dnl     __(la vsp,node_size(vsp))
     1354dnl     __(Cons(arg_z,temp0,arg_z))
     1355dnl     __(subi imm1,imm1,fixnum_one)
     1356dnl 2:
     1357dnl     __(bgt 1b)
     1358dnl     __(vpush1(arg_z))
     1359dnl     __(bx lr)
     1360dnl
     1361dnl
     1362dnl _spentry(heap_cons_rest_arg)
     1363dnl     __(sub imm1,nargs,imm0)
     1364dnl     __(cmpri(imm1,0))
     1365dnl     __(mov arg_z,#nil_value)
     1366dnl     __(b 2f)
     1367dnl 1:
     1368dnl     __(ldr temp0,[vsp,#0])
     1369dnl     __(cmpri(imm1,fixnum_one))
     1370dnl     __(la vsp,node_size(vsp))
     1371dnl     __(Cons(arg_z,temp0,arg_z))
     1372dnl     __(subi imm1,imm1,fixnum_one)
     1373dnl 2:
     1374dnl     __(bgt 1b)
     1375dnl     __(vpush1(arg_z))
     1376dnl     __(bx lr)
     1377dnl
     1378dnl     
     1379dnl _spentry(simple_keywords)
     1380dnl     __(mov imm0,#0)
     1381dnl         __(vpush_argregs())
     1382dnl         __(b _SPkeyword_bind)
     1383dnl                 
     1384dnl _spentry(keyword_args)
     1385dnl     __(vpush_argregs())
     1386dnl         __(b _SPkeyword_bind)
     1387dnl
     1388dnl /* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
     1389dnl /* pairs.  There'll be imm3 keyword arguments.  Imm2 contains flags  */
     1390dnl /* that indicate whether &allow-other-keys was specified and whether  */
     1391dnl /* or not to leave the keyword/value pairs on the vstack for an &rest  */
     1392dnl /* argument.  Temp3 contains a vector of keyword specifiers which we  */
     1393dnl /* must (in general) match.  */
     1394dnl /* If the number of arguments is greater than imm0, the difference must  */
     1395dnl /* be even.  */
     1396dnl /* Note that the caller hasn't yet saved its caller's context and that  */
     1397dnl /* the temp registers used to pass next_method_context  */
     1398dnl /* (temp1) may still have "live" values in them, as does nfn (temp2).  */
     1399dnl
     1400dnl define(`keyword_flags',`imm2')
     1401dnl define(`keyword_vector',`temp3')
     1402dnl define(`keyword_count',`imm3')
     1403dnl
     1404dnl
     1405dnl
     1406dnl define(`varptr',`save0')
     1407dnl define(`valptr',`save1')
     1408dnl define(`limit',`save2')
     1409dnl
     1410dnl _spentry(keyword_bind)
     1411dnl         /* Before we can really do anything, we have to  */
     1412dnl         /* save the caller's context.  To do so, we need to know  */
     1413dnl         /* how many args have actually been pushed.  Ordinarily, that'd  */
     1414dnl         /* be "nargs", but we may have pushed more args than we received  */
     1415dnl     /* if we had to default any &optionals.  */
     1416dnl     /* So, the number of args pushed so far is the larger of nargs  */
     1417dnl     /* and the (canonical) total of required/&optional args received.  */
     1418dnl     __(cmpr(cr0,nargs,imm0))
     1419dnl     __(add arg_z,vsp,nargs)
     1420dnl     __(bge+ cr0,1f)
     1421dnl     __(add arg_z,vsp,imm0)
     1422dnl 1:
     1423dnl     __(build_lisp_frame(fn,loc_pc,arg_z))
     1424dnl     __(mov fn,nfn)
     1425dnl     /* If there are key/value pairs to consider, we slide them down  */
     1426dnl     /* the vstack to make room for the value/supplied-p pairs.  */
     1427dnl     /* The first step in that operation involves pushing imm3 pairs  */
     1428dnl     /* of NILs.  */
     1429dnl     /* If there aren't any such pairs, the first step is the last  */
     1430dnl     /* step.  */
     1431dnl     __(cmpri(cr0,imm3,0))
     1432dnl     __(mov arg_z,#0)
     1433dnl     __(sub imm1,nargs,imm0)
     1434dnl     __(mov imm4,vsp)        /* in case odd keywords error  */
     1435dnl     __(cmpri(cr1,imm1,0))
     1436dnl     __(b 3f)
     1437dnl 2:
     1438dnl     __(addi arg_z,arg_z,fixnum_one)
     1439dnl     __(cmplr(cr0,arg_z,imm3))
     1440dnl     __(mov imm5,#nil_value)
     1441dnl     __(vpush1(imm5))
     1442dnl     __(vpush1(imm5))
     1443dnl 3:
     1444dnl     __(bne cr0,2b)
     1445dnl     __(andi. arg_z,imm1,fixnum_one)
     1446dnl     __(blelr cr1)   /* no keyword/value pairs to consider.  */
     1447dnl     __(bne cr0,odd_keywords)
     1448dnl     /* We have key/value pairs.  Move them to the top of the vstack,  */
     1449dnl     /* then set the value/supplied-p vars to NIL.  */
     1450dnl     /* Have to use some save regs to do this.  */
     1451dnl     __(vpush1(limit))
     1452dnl     __(vpush1(valptr))
     1453dnl     __(vpush1(varptr))
     1454dnl     /* recompute ptr to user args in case stack overflowed  */
     1455dnl     __(add imm4,vsp,imm3)
     1456dnl     __(add imm4,imm4,imm3)
     1457dnl     __(addi imm4,imm4,3*node_size)
     1458dnl     /* error if odd number of keyword/value args  */
     1459dnl     __(mov varptr,imm4)
     1460dnl     __(la limit,3*node_size(vsp))
     1461dnl     __(mov valptr,limit)
     1462dnl     __(mov arg_z,imm1)
     1463dnl 4:
     1464dnl     __(mov imm4,#nil_value)
     1465dnl     __(subi arg_z,arg_z,2<<fixnumshift)
     1466dnl     __(cmplri(cr0,arg_z,0))
     1467dnl     __(ldr arg_x,[varptr,#node_size*0])
     1468dnl     __(ldr arg_y,[varptr,#node_size*1])
     1469dnl     __(str(imm4,node_size*0(varptr)))
     1470dnl     __(str(imm4,node_size*1(varptr)))
     1471dnl     __(la varptr,node_size*2(varptr))
     1472dnl     __(str(arg_x,node_size*0(valptr)))
     1473dnl     __(str(arg_y,node_size*1(valptr)))
     1474dnl     __(la valptr,node_size*2(valptr))
     1475dnl     __(bne cr0,4b)
     1476dnl
     1477dnl
     1478dnl         /* Now, iterate through each supplied keyword/value pair.  If  */
     1479dnl         /* it's :allow-other-keys and the corresponding value is non-nil,  */
     1480dnl         /* note that other keys will be allowed.  */
     1481dnl         /* Find its position in the function's keywords vector.  If that's  */
     1482dnl         /* nil, note that an unknown keyword was encountered.  */
     1483dnl         /* Otherwise, if the keyword arg hasn't already had a value supplied,  */
     1484dnl         /* supply it.  */
     1485dnl         /* When done, complain if any unknown keywords were found and that  */
     1486dnl         /* situation was unexpected.  */
     1487dnl     __(mov imm4,valptr)
     1488dnl 5:
     1489dnl         __(cmpri(cr0,keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
     1490dnl     __(ldru(arg_z,-node_size(valptr)))
     1491dnl     __(ldru(arg_y,-node_size(valptr)))
     1492dnl     __(cmpri(cr1,arg_y,nil_value))
     1493dnl     __(mov arg_x,#nrs.kallowotherkeys)
     1494dnl         /* cr6_eq <- (eq current-keyword :allow-other-keys)  */
     1495dnl     __(cmpr(cr6,arg_x,arg_z))
     1496dnl     __(cmpr(cr7,valptr,limit))
     1497dnl     __(bne cr6,6f)
     1498dnl         __(bge cr0,6f) /* Already seen :allow-other-keys  */
     1499dnl         __(ori keyword_flags,keyword_flags,16<<fixnumshift)
     1500dnl     __(beq cr1,6f)
     1501dnl     __(ori keyword_flags,keyword_flags,fixnum_one)
     1502dnl 6:
     1503dnl     __(cmpri(cr1,imm3,0))
     1504dnl     __(mov imm1,#misc_data_offset)
     1505dnl     __(mov imm0,#0)
     1506dnl     __(b 8f)
     1507dnl 7:
     1508dnl     __(addi imm0,imm0,fixnum_one)
     1509dnl     __(cmpr(cr1,imm0,imm3))
     1510dnl     __(ldrx(arg_x,keyword_vector,imm1))
     1511dnl     __(cmpr(cr0,arg_x,arg_z))
     1512dnl     __(addi imm1,imm1,fixnum_one)
     1513dnl     __(bne cr0,8f)
     1514dnl     __(add imm0,imm0,imm0)
     1515dnl     __(sub imm0,varptr,imm0)
     1516dnl     __(ldr arg_x,[imm0,#0])
     1517dnl     __(cmpri(cr0,arg_x,nil_value))
     1518dnl     __(mov arg_z,#t_value)
     1519dnl     __(bne cr0,9f)
     1520dnl     __(str(arg_y,node_size(imm0)))
     1521dnl     __(str(arg_z,0(imm0)))
     1522dnl     __(b 9f)
     1523dnl 8:
     1524dnl     __(bne cr1,7b)
     1525dnl     /* Unknown keyword. If it was :allow-other-keys, cr6_eq will still */
     1526dnl         /* be set.  */
     1527dnl         __(beq cr6,9f)
     1528dnl     __(ori keyword_flags,keyword_flags,2<<fixnumshift)
     1529dnl 9:
     1530dnl     __(bne cr7,5b)
     1531dnl     __(vpop(varptr))
     1532dnl     __(vpop(valptr))
     1533dnl     __(vpop(limit))
     1534dnl     /* All keyword/value pairs have been processed.  */
     1535dnl     /* If we saw an unknown keyword and didn't expect to, error.  */
     1536dnl     /* Unless bit 2 is set in the fixnum in keyword_flags, discard the  */
     1537dnl     /* keyword/value pairs from the vstack.  */
     1538dnl     __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift))
     1539dnl     __(cmpri(cr0,imm0,2<<fixnumshift))
     1540dnl     __(beq- cr0,badkeys)
     1541dnl     __(andi. imm2,keyword_flags,4<<fixnumshift)
     1542dnl     __(bnelr cr0)
     1543dnl     __(mov vsp,imm4)
     1544dnl     __(bx lr)
     1545dnl
     1546dnl /* Signal an error.  We saved context on entry, so this thing doesn't  */
     1547dnl /* have to.  */
     1548dnl /* The "unknown keywords" error could be continuable (ignore them.)  */
     1549dnl /* It might be hard to then cons an &rest arg.  */
     1550dnl /* In the general case, it's hard to recover the set of args that were  */
     1551dnl /* actually supplied to us ...  */
     1552dnl /* For now, just cons a list out of the keyword/value pairs */
     1553dnl /* that were actually provided, and signal an "invalid keywords" */
     1554dnl /* error with that list as an operand.  */
     1555dnl odd_keywords:
     1556dnl     __(mov vsp,imm4)
     1557dnl     __(mov nargs,imm1)
     1558dnl     __(b 1f)
     1559dnl badkeys:
     1560dnl     __(sub nargs,imm4,vsp)
     1561dnl 1:
     1562dnl     __(bl _SPconslist)
     1563dnl     __(mov arg_y,#XBADKEYS)
     1564dnl     __(set_nargs(2))
     1565dnl     __(b _SPksignalerr)
     1566dnl
     1567dnl /*  A PowerOpen ff-call.  arg_z is either a fixnum (word-aligned entrypoint) */
     1568dnl /*  or a macptr (whose address had better be word-aligned as well.)  A */
     1569dnl /*  PowerOpen stack frame is on top of the stack; 4 additional words (to */
     1570dnl /*  be used a a lisp frame) sit under the C frame. */
     1571dnl
     1572dnl /*  Since we probably can't deal with FP exceptions in foreign code, we */
     1573dnl /*  disable them in the FPSCR, then check on return to see if any previously */
     1574dnl /*  enabled FP exceptions occurred. */
     1575dnl
     1576dnl /*  As it turns out, we can share a lot of code with the eabi version of */
     1577dnl /*  ff-call.  Some things that happen up to the point of call differ between */
     1578dnl /*  the ABIs, but everything that happens after is the same. */
     1579dnl
     1580dnl         
     1581dnl _spentry(poweropen_ffcall)
     1582dnl LocalLabelPrefix`'ffcall:               
     1583dnl     __(mflr loc_pc)
     1584dnl     __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
     1585dnl     __(mov save0,rcontext)  /* or address globals.  */
     1586dnl     __(extract_typecode(imm0,arg_z))
     1587dnl     __(cmpri(cr7,imm0,subtag_macptr))
     1588dnl     __(ldr save1,[sp,#0])   /* bottom of reserved lisp frame  */
     1589dnl     __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
     1590dnl         __(zero_doublewords save2,0,lisp_frame.size)
     1591dnl     __(str(save1,lisp_frame.backlink(save2)))
     1592dnl     __(str(save2,c_frame.backlink(sp)))
     1593dnl     __(str(fn,lisp_frame.savefn(save2)))
     1594dnl     __(str(loc_pc,lisp_frame.savelr(save2)))
     1595dnl     __(str(vsp,lisp_frame.savevsp(save2)))
     1596dnl         __(mov nargs,arg_z)
     1597dnl             __(bne cr7,1f)
     1598dnl     __(ldr nargs,[arg_z,#macptr.address])
     1599dnl 1:
     1600dnl     __(ldr save3,[rcontext,#tcr.cs_area])
     1601dnl     __(str(save2,area.active(save3)))
     1602dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     1603dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     1604dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     1605dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     1606dnl     __(str(rzero,tcr.ffi_exception(rcontext)))
     1607dnl     __(mffs f0)
     1608dnl     __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
     1609dnl     __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
     1610dnl     __(mov r4,#TCR_STATE_FOREIGN)
     1611dnl     __(str(r4,tcr.valence(rcontext)))
     1612dnl         __ifdef(`rTOC')
     1613dnl          __(ld rTOC,8(nargs))
     1614dnl          __(ld nargs,0(nargs))
     1615dnl         __else
     1616dnl      __(mov rcontext,#0)
     1617dnl         __endif
     1618dnl LocalLabelPrefix`'ffcall_setup:
     1619dnl     __(mtctr nargs)
     1620dnl     __(ldr r3,[sp,#c_frame.param0])
     1621dnl     __(ldr r4,[sp,#c_frame.param1])
     1622dnl     __(ldr r5,[sp,#c_frame.param2])
     1623dnl     __(ldr r6,[sp,#c_frame.param3])
     1624dnl     __(ldr r7,[sp,#c_frame.param4])
     1625dnl     __(ldr r8,[sp,#c_frame.param5])
     1626dnl     __(ldr r9,[sp,#c_frame.param6])
     1627dnl     __(ldr r10,[sp,#c_frame.param7])
     1628dnl     /* Darwin is allegedly very picky about what register points */
     1629dnl     /* to the function on entry.  */
     1630dnl     __(mov r12,nargs)
     1631dnl LocalLabelPrefix`'ffcall_setup_end:
     1632dnl LocalLabelPrefix`'ffcall_call:
     1633dnl     __(bctrl)
     1634dnl LocalLabelPrefix`'ffcall_call_end:
     1635dnl     /* C should have preserved save0 (= rcontext) for us.  */
     1636dnl     __(ldr sp,[sp,#0])
     1637dnl     __(mov imm2,save0)
     1638dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     1639dnl     __(mov rzero,#0)
     1640dnl     __(mov loc_pc,rzero)
     1641dnl     __(mov arg_x,#nil_value)
     1642dnl     __(mov arg_y,#nil_value)
     1643dnl     __(mov arg_z,#nil_value)
     1644dnl     __(mov temp0,#nil_value)
     1645dnl     __(mov temp1,#nil_value)
     1646dnl     __(mov temp2,#nil_value)
     1647dnl     __(mov temp3,#nil_value)
     1648dnl     __(mov fn,#nil_value)
     1649dnl     __(mov rcontext,imm2)
     1650dnl     __(mov imm2,#TCR_STATE_LISP)
     1651dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])
     1652dnl         __(mov save0,#0)
     1653dnl         __(mov save1,#0)
     1654dnl         __(mov save2,#0)
     1655dnl         __(mov save3,#0)
     1656dnl         __(mov save4,#0)
     1657dnl         __(mov save5,#0)
     1658dnl         __(mov save6,#0)
     1659dnl         __(mov save7,#0)
     1660dnl         __(mov allocptr,#-dnode_size)
     1661dnl         __(mov allocbase,#-dnode_size)
     1662dnl     __(str(imm2,tcr.valence(rcontext)))     
     1663dnl     __(vpop_saveregs())
     1664dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     1665dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     1666dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     1667dnl     __(mtlr loc_pc)
     1668dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     1669dnl     __(mffs f0)
     1670dnl     __(stfd f0,8(sp))
     1671dnl     __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
     1672dnl         __(clrrwi imm2,imm3,8)
     1673dnl     __(discard_lisp_frame())
     1674dnl     __(str(imm2,tcr.ffi_exception(rcontext)))
     1675dnl     __(lfd f0,tcr.lisp_fpscr(rcontext))
     1676dnl     __(mtfsf 0xff,f0)
     1677dnl     __(check_pending_interrupt(`cr1'))
     1678dnl         __(mtxer rzero)
     1679dnl         __(mtctr rzero)
     1680dnl         __ifdef(`PPC64')
     1681dnl          __ifdef(`DARWIN')
     1682dnl           __(mov imm3,#1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
     1683dnl           __(ld imm4,tcr.flags(rcontext))
     1684dnl           __(and. imm3,imm3,imm4)
     1685dnl           __(bne cr0,0f)
     1686dnl          __endif
     1687dnl         __endif
     1688dnl     __(bx lr)
     1689dnl         __ifdef(`PPC64')
     1690dnl          __ifdef(`DARWIN')
     1691dnl 0:        /* Got here because TCR_FLAG_BIT_FOREIGN_EXCEPTION */
     1692dnl           /* was set in tcr.flags.  Clear that bit. */
     1693dnl           __(andc imm4,imm4,imm3)
     1694dnl           __(std imm4,tcr.flags(rcontext))
     1695dnl       /* Unboxed foreign exception (likely an NSException) in %imm0. */
     1696dnl       /* Box it, then signal a lisp error. */
     1697dnl           __(mov imm1,#macptr_header)
     1698dnl           __(Misc_Alloc_Fixed(arg_z,imm1,macptr.size))
     1699dnl           __(std imm0,macptr.address(arg_z))
     1700dnl           __(mov arg_y,#XFOREIGNEXCEPTION)
     1701dnl           __(set_nargs(2))
     1702dnl           __(b _SPksignalerr)
     1703dnl         /* Handle exceptions, for ObjC 2.0 */
     1704dnl LocalLabelPrefix`'ffcallLandingPad:     
     1705dnl           __(mov save1,r3)
     1706dnl           __(cmpdi r4,1)
     1707dnl           __(beq 1f)
     1708dnl LocalLabelPrefix`'ffcallUnwindResume:
     1709dnl           __(ref_global(r12,unwind_resume))
     1710dnl           __(mtctr r12)
     1711dnl           __(bctrl)
     1712dnl LocalLabelPrefix`'ffcallUnwindResume_end:         
     1713dnl 1:        __(mov r3,save1)
     1714dnl LocalLabelPrefix`'ffcallBeginCatch:
     1715dnl           __(ref_global(r12,objc2_begin_catch))
     1716dnl           __(mtctr r12)
     1717dnl           __(bctrl)
     1718dnl LocalLabelPrefix`'ffcallBeginCatch_end:         
     1719dnl           __(ld save1,0(r3)) /* indirection is necessary because we don't provide type info in lsda */
     1720dnl LocalLabelPrefix`'ffcallEndCatch: 
     1721dnl           __(ref_global(r12,objc2_end_catch))
     1722dnl           __(mtctr r12)
     1723dnl           __(bctrl)             
     1724dnl LocalLabelPrefix`'ffcallEndCatch_end:     
     1725dnl           __(ref_global(r12,get_tcr))
     1726dnl           __(mtctr r12)
     1727dnl           __(mov imm0,#1)       
     1728dnl       __(bctrl)
     1729dnl           __(ld imm2,tcr.flags(imm0))
     1730dnl           __(ori imm2,imm2,1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
     1731dnl           __(std imm2,tcr.flags(imm0))
     1732dnl           __(mov imm0,save1)
     1733dnl       __(b LocalLabelPrefix`'ffcall_call_end)
     1734dnl LocalLabelPrefix`'ffcall_end:   
     1735dnl
     1736dnl             .section __DATA,__gcc_except_tab
     1737dnl       .align 3
     1738dnl LLSDA1:
     1739dnl       .byte 0xff    /* @LPStart format (omit) */
     1740dnl       .byte 0x0     /* @TType format (absolute) */
     1741dnl       .byte 0x4d    /* uleb128 0x4d; @TType base offset */
     1742dnl       .byte 0x3     /* call-site format (udata4) */
     1743dnl       .byte 0x41    /* uleb128 0x41; Call-site table length */
     1744dnl     
     1745dnl       .long Lffcall_setup-Lffcall   /* region 0 start */
     1746dnl       .long Lffcall_setup_end-Lffcall_setup /* length */
     1747dnl       .long 0x0     /* landing pad */
     1748dnl       .byte 0x0     /* uleb128 0x0; action */
     1749dnl         
     1750dnl       .long Lffcall_call-Lffcall    /* region 1 start */
     1751dnl       .long Lffcall_call_end-Lffcall_call   /* length */
     1752dnl       .long LffcallLandingPad-Lffcall       /* landing pad */
     1753dnl       .byte 0x1     /* uleb128 0x1; action */
     1754dnl         
     1755dnl       .long LffcallUnwindResume-Lffcall     /* region 2 start */
     1756dnl       .long LffcallUnwindResume_end-LffcallUnwindResume     /* length */
     1757dnl       .long 0x0     /* landing pad */
     1758dnl       .byte 0x0     /* uleb128 0x0; action */
     1759dnl     
     1760dnl       .long LffcallBeginCatch-Lffcall       /* region 3 start */
     1761dnl       .long LffcallBeginCatch_end-LffcallBeginCatch /* length */
     1762dnl       .long 0       /* landing pad */
     1763dnl       .byte 0x0     /* uleb128 0x0; action */
     1764dnl         
     1765dnl       .long LffcallEndCatch-Lffcall
     1766dnl       .long LffcallEndCatch_end-LffcallEndCatch     /* length */
     1767dnl       .long 0x0     /* landing pad */
     1768dnl       .byte 0x0     /* uleb128 0x0; action */
     1769dnl         
     1770dnl       .byte 0x1     /* Action record table */
     1771dnl       .byte 0x0
     1772dnl       .align 3
     1773dnl       .quad 0       /* _OBJC_EHTYPE_$_NSException */
     1774dnl           .text
     1775dnl          __endif
     1776dnl         __endif
     1777dnl
     1778dnl /* Just like poweropen_ffcall, only we save all argument(result)
     1779dnl    registers in a buffer passed in arg_y on entry before returning
     1780dnl    to lisp.  (We have to do this in the ffcall glue here, because
     1781dnl    r9 and r10 - at least - are overloaded as dedicated lisp registers */
     1782dnl _spentry(poweropen_ffcall_return_registers)
     1783dnl LocalLabelPrefix`'ffcall_return_registers:               
     1784dnl     __(mflr loc_pc)
     1785dnl     __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
     1786dnl         __(ldr save7,[arg_y,#macptr.address])
     1787dnl     __(mov save0,rcontext)  /* or address globals.  */
     1788dnl     __(extract_typecode(imm0,arg_z))
     1789dnl     __(cmpri(cr7,imm0,subtag_macptr))
     1790dnl     __(ldr save1,[sp,#0])   /* bottom of reserved lisp frame  */
     1791dnl     __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
     1792dnl         __(zero_doublewords save2,0,lisp_frame.size)
     1793dnl     __(str(save1,lisp_frame.backlink(save2)))
     1794dnl     __(str(save2,c_frame.backlink(sp)))
     1795dnl     __(str(fn,lisp_frame.savefn(save2)))
     1796dnl     __(str(loc_pc,lisp_frame.savelr(save2)))
     1797dnl     __(str(vsp,lisp_frame.savevsp(save2)))
     1798dnl         __(mov nargs,arg_z)
     1799dnl             __(bne cr7,1f)
     1800dnl     __(ldr nargs,[arg_z,#macptr.address])
     1801dnl 1:
     1802dnl     __(ldr save3,[rcontext,#tcr.cs_area])
     1803dnl     __(str(save2,area.active(save3)))
     1804dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     1805dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     1806dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     1807dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     1808dnl     __(str(rzero,tcr.ffi_exception(rcontext)))
     1809dnl     __(mffs f0)
     1810dnl     __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
     1811dnl     __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
     1812dnl     __(mov r4,#TCR_STATE_FOREIGN)
     1813dnl     __(str(r4,tcr.valence(rcontext)))
     1814dnl         __ifdef(`rTOC')
     1815dnl          __(ld rTOC,8(nargs))
     1816dnl          __(ld nargs,0(nargs))
     1817dnl         __else
     1818dnl      __(mov rcontext,#0)
     1819dnl         __endif
     1820dnl LocalLabelPrefix`'ffcall_return_registers_setup:
     1821dnl     __(mtctr nargs)
     1822dnl     __(ldr r3,[sp,#c_frame.param0])
     1823dnl     __(ldr r4,[sp,#c_frame.param1])
     1824dnl     __(ldr r5,[sp,#c_frame.param2])
     1825dnl     __(ldr r6,[sp,#c_frame.param3])
     1826dnl     __(ldr r7,[sp,#c_frame.param4])
     1827dnl     __(ldr r8,[sp,#c_frame.param5])
     1828dnl     __(ldr r9,[sp,#c_frame.param6])
     1829dnl     __(ldr r10,[sp,#c_frame.param7])
     1830dnl     /* Darwin is allegedly very picky about what register points */
     1831dnl     /* to the function on entry.  */
     1832dnl     __(mov r12,nargs)
     1833dnl LocalLabelPrefix`'ffcall_return_registers_setup_end:
     1834dnl LocalLabelPrefix`'ffcall_return_registers_call:
     1835dnl     __(bctrl)
     1836dnl LocalLabelPrefix`'ffcall_return_registers_call_end:
     1837dnl         __(str(r3,0*node_size(save7)))       
     1838dnl         __(str(r4,1*node_size(save7)))       
     1839dnl         __(str(r5,2*node_size(save7)))       
     1840dnl         __(str(r6,3*node_size(save7)))       
     1841dnl         __(str(r7,4*node_size(save7)))       
     1842dnl         __(str(r8,5*node_size(save7)))       
     1843dnl         __(str(r9,6*node_size(save7)))       
     1844dnl         __(str(r10,7*node_size(save7)))
     1845dnl         __(stfd f1,((8*node_size)+(0*8))(save7))
     1846dnl         __(stfd f2,((8*node_size)+(1*8))(save7))
     1847dnl         __(stfd f3,((8*node_size)+(2*8))(save7))
     1848dnl         __(stfd f4,((8*node_size)+(3*8))(save7))
     1849dnl         __(stfd f5,((8*node_size)+(4*8))(save7))
     1850dnl         __(stfd f6,((8*node_size)+(5*8))(save7))
     1851dnl         __(stfd f7,((8*node_size)+(6*8))(save7))
     1852dnl         __(stfd f8,((8*node_size)+(7*8))(save7))
     1853dnl         __(stfd f9,((8*node_size)+(8*8))(save7))
     1854dnl         __(stfd f10,((8*node_size)+(9*8))(save7))
     1855dnl         __(stfd f11,((8*node_size)+(10*8))(save7))
     1856dnl         __(stfd f12,((8*node_size)+(11*8))(save7))
     1857dnl         __(stfd f13,((8*node_size)+(12*8))(save7))
     1858dnl     /* C should have preserved save0 (= rcontext) for us.  */
     1859dnl     __(ldr sp,[sp,#0])
     1860dnl     __(mov imm2,save0)
     1861dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     1862dnl     __(mov rzero,#0)
     1863dnl     __(mov loc_pc,rzero)
     1864dnl     __(mov arg_x,#nil_value)
     1865dnl     __(mov arg_y,#nil_value)
     1866dnl     __(mov arg_z,#nil_value)
     1867dnl     __(mov temp0,#nil_value)
     1868dnl     __(mov temp1,#nil_value)
     1869dnl     __(mov temp2,#nil_value)
     1870dnl     __(mov temp3,#nil_value)
     1871dnl     __(mov fn,#nil_value)
     1872dnl     __(mov rcontext,imm2)
     1873dnl     __(mov imm2,#TCR_STATE_LISP)
     1874dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])
     1875dnl         __(mov save0,#0)
     1876dnl         __(mov save1,#0)
     1877dnl         __(mov save2,#0)
     1878dnl         __(mov save3,#0)
     1879dnl         __(mov save4,#0)
     1880dnl         __(mov save5,#0)
     1881dnl         __(mov save6,#0)
     1882dnl         __(mov save7,#0)
     1883dnl         __(mov allocptr,#-dnode_size)
     1884dnl         __(mov allocbase,#-dnode_size)
     1885dnl     __(str(imm2,tcr.valence(rcontext)))     
     1886dnl     __(vpop_saveregs())
     1887dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     1888dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     1889dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     1890dnl     __(mtlr loc_pc)
     1891dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     1892dnl     __(mffs f0)
     1893dnl     __(stfd f0,8(sp))
     1894dnl     __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
     1895dnl         __(clrrwi imm2,imm3,8)
     1896dnl     __(discard_lisp_frame())
     1897dnl     __(str(imm2,tcr.ffi_exception(rcontext)))
     1898dnl     __(lfd f0,tcr.lisp_fpscr(rcontext))
     1899dnl     __(mtfsf 0xff,f0)
     1900dnl     __(check_pending_interrupt(`cr1'))
     1901dnl         __(mtxer rzero)
     1902dnl         __(mtctr rzero)
     1903dnl         __ifdef(`DARWIN')
     1904dnl          __ifdef(`PPC64')
     1905dnl           __(mov imm3,#1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
     1906dnl           __(ld imm4,tcr.flags(rcontext))
     1907dnl           __(and. imm3,imm3,imm4)
     1908dnl           __(bne 0f)
     1909dnl          __endif
     1910dnl         __endif
     1911dnl     __(bx lr)
     1912dnl
     1913dnl         __ifdef(`DARWIN')
     1914dnl          __ifdef(`PPC64')
     1915dnl 0:        /* Got here because TCR_FLAG_BIT_FOREIGN_EXCEPTION */
     1916dnl           /* was set in tcr.flags.  Clear that bit. */
     1917dnl           __(andc imm4,imm4,imm3)
     1918dnl           __(std imm4,tcr.flags(rcontext))
     1919dnl       /* Unboxed foreign exception (likely an NSException) in %imm0. */
     1920dnl       /* Box it, then signal a lisp error. */
     1921dnl           __(mov imm1,#macptr_header)
     1922dnl           __(Misc_Alloc_Fixed(arg_z,imm1,macptr.size))
     1923dnl           __(std imm0,macptr.address(arg_z))
     1924dnl           __(mov arg_y,#XFOREIGNEXCEPTION)
     1925dnl           __(set_nargs(2))
     1926dnl           __(b _SPksignalerr)
     1927dnl         /* Handle exceptions, for ObjC 2.0 */
     1928dnl LocalLabelPrefix`'ffcall_return_registersLandingPad:     
     1929dnl           __(mov save1,r3)
     1930dnl           __(cmpdi r4,1)
     1931dnl           __(beq 1f)
     1932dnl LocalLabelPrefix`'ffcall_return_registersUnwindResume:
     1933dnl           __(ref_global(r12,unwind_resume))
     1934dnl           __(mtctr r12)
     1935dnl           __(bctrl)
     1936dnl LocalLabelPrefix`'ffcall_return_registersUnwindResume_end:         
     1937dnl 1:        __(mov r3,save1)
     1938dnl LocalLabelPrefix`'ffcall_return_registersBeginCatch:
     1939dnl           __(ref_global(r12,objc2_begin_catch))
     1940dnl           __(mtctr r12)
     1941dnl           __(bctrl)
     1942dnl LocalLabelPrefix`'ffcall_return_registersBeginCatch_end:         
     1943dnl           __(ld save1,0(r3)) /* indirection is necessary because we don't provide type info in lsda */
     1944dnl LocalLabelPrefix`'ffcall_return_registersEndCatch: 
     1945dnl           __(ref_global(r12,objc2_end_catch))
     1946dnl           __(mtctr r12)
     1947dnl           __(bctrl)             
     1948dnl LocalLabelPrefix`'ffcall_return_registersEndCatch_end:     
     1949dnl           __(ref_global(r12,get_tcr))
     1950dnl           __(mtctr r12)
     1951dnl           __(mov imm0,#1)       
     1952dnl       __(bctrl)
     1953dnl           __(ld imm2,tcr.flags(imm0))
     1954dnl           __(ori imm2,imm2,1<<TCR_FLAG_BIT_FOREIGN_EXCEPTION)
     1955dnl           __(std imm2,tcr.flags(imm0))
     1956dnl           __(mov imm0,save1)
     1957dnl       __(b LocalLabelPrefix`'ffcall_return_registers_call_end)
     1958dnl LocalLabelPrefix`'ffcall_return_registers_end:
     1959dnl       .section __DATA,__gcc_except_tab
     1960dnl       .align 3
     1961dnl LLSDA2:
     1962dnl       .byte 0xff    /* @LPStart format (omit) */
     1963dnl       .byte 0x0     /* @TType format (absolute) */
     1964dnl       .byte 0x4d    /* uleb128 0x4d; @TType base offset */
     1965dnl       .byte 0x3     /* call-site format (udata4) */
     1966dnl       .byte 0x41    /* uleb128 0x41; Call-site table length */
     1967dnl     
     1968dnl       .long Lffcall_return_registers_setup-Lffcall_return_registers /* region 0 start */
     1969dnl       .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup       /* length */
     1970dnl       .long 0x0     /* landing pad */
     1971dnl       .byte 0x0     /* uleb128 0x0; action */
     1972dnl         
     1973dnl       .long Lffcall_return_registers_call-Lffcall_return_registers  /* region 1 start */
     1974dnl       .long Lffcall_return_registers_call_end-Lffcall_return_registers_call /* length */
     1975dnl       .long Lffcall_return_registersLandingPad-Lffcall_return_registers     /* landing pad */
     1976dnl       .byte 0x1     /* uleb128 0x1; action */
     1977dnl         
     1978dnl       .long Lffcall_return_registersUnwindResume-Lffcall_return_registers   /* region 2 start */
     1979dnl       .long Lffcall_return_registersUnwindResume_end-Lffcall_return_registersUnwindResume   /* length */
     1980dnl       .long 0x0     /* landing pad */
     1981dnl       .byte 0x0     /* uleb128 0x0; action */
     1982dnl     
     1983dnl       .long Lffcall_return_registersBeginCatch-Lffcall_return_registers     /* region 3 start */
     1984dnl       .long Lffcall_return_registersBeginCatch_end-Lffcall_return_registersBeginCatch       /* length */
     1985dnl       .long 0       /* landing pad */
     1986dnl       .byte 0x0     /* uleb128 0x0; action */
     1987dnl         
     1988dnl       .long Lffcall_return_registersEndCatch-Lffcall_return_registers
     1989dnl       .long Lffcall_return_registersEndCatch_end-Lffcall_return_registersEndCatch   /* length */
     1990dnl       .long 0x0     /* landing pad */
     1991dnl       .byte 0x0     /* uleb128 0x0; action */
     1992dnl       .byte 0x1     /* Action record table */
     1993dnl       .byte 0x0
     1994dnl       .align 3
     1995dnl       .quad 0       /* _OBJC_EHTYPE_$_NSException */
     1996dnl           .text
     1997dnl          __endif
     1998dnl         __endif
     1999dnl                       
     2000dnl
     2001dnl             
     2002dnl /* Signal an error synchronously, via %ERR-DISP.  */
     2003dnl /* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
     2004dnl /* on the C runtime stderr.  */
     2005dnl
     2006dnl _spentry(ksignalerr)
     2007dnl     __(mov fname,#nrs.errdisp)
     2008dnl     __(jump_fname)
     2009dnl         
     2010dnl /* As in the heap-consed cases, only stack-cons the &rest arg  */
     2011dnl _spentry(stack_rest_arg)
     2012dnl     __(mov imm0,#0)
     2013dnl     __(vpush_argregs())
     2014dnl         __(b _SPstack_cons_rest_arg)
     2015dnl
     2016dnl     
     2017dnl _spentry(req_stack_rest_arg)
     2018dnl     __(vpush_argregs())
     2019dnl         __(b _SPstack_cons_rest_arg)
     2020dnl     
     2021dnl _spentry(stack_cons_rest_arg)
     2022dnl     __(sub imm1,nargs,imm0)
     2023dnl     __(cmpri(cr0,imm1,0))
     2024dnl     __(cmpri(cr1,imm1,(4096-dnode_size)/2))
     2025dnl     __(mov arg_z,#nil_value)
     2026dnl     __(ble cr0,2f)          /* always temp-push something.  */
     2027dnl     __(bge cr1,3f)
     2028dnl     __(add imm1,imm1,imm1)
     2029dnl     __(dnode_align(imm2,imm1,tsp_frame.fixed_overhead))
     2030dnl     __(TSP_Alloc_Var_Boxed(imm2,imm3))
     2031dnl     __(la imm0,tsp_frame.data_offset+fulltag_cons(tsp))
     2032dnl 1:
     2033dnl     __(cmpri(cr0,imm1,cons.size))   /* last time through ?  */
     2034dnl     __(subi imm1,imm1,cons.size)
     2035dnl     __(vpop(arg_x))
     2036dnl     __(_rplacd(imm0,arg_z))
     2037dnl     __(_rplaca(imm0,arg_x))
     2038dnl     __(mov arg_z,imm0)
     2039dnl     __(la imm0,cons.size(imm0))
     2040dnl     __(bne cr0,1b)
     2041dnl     __(vpush1(arg_z))
     2042dnl     __(bx lr)
     2043dnl 2:
     2044dnl     __(TSP_Alloc_Fixed_Unboxed(0))
     2045dnl     __(vpush1(arg_z))
     2046dnl     __(bx lr)
     2047dnl 3:
     2048dnl     __(TSP_Alloc_Fixed_Unboxed(0))
     2049dnl     __(b _SPheap_cons_rest_arg)
     2050dnl
     2051dnl /* This was trying to swap exception ports to work around Darwin JNI lossage.
     2052dnl    It's tended to bitrot, and we have another way to do that now.
     2053dnl */       
     2054dnl _spentry(poweropen_callbackX)
     2055dnl         .long 0x7c800008        /* debug trap */
     2056dnl     
     2057dnl /* Prepend all but the first two (closure code, fn) and last two  */
     2058dnl /* (function name, lfbits) elements of nfn to the "arglist".  */
     2059dnl /* Doing things this way (the same way that 68K MCL does) lets  */
     2060dnl /* functions which take "inherited arguments" work consistently  */
     2061dnl /* even in cases where no closure object is created.  */
     2062dnl _spentry(call_closure)       
     2063dnl     __(cmpri(cr0,nargs,nargregs<<fixnumshift))
     2064dnl     __(cmpri(cr1,nargs,fixnum_one))
     2065dnl     __(vector_length(imm0,nfn,imm0))
     2066dnl     __(subi imm0,imm0,4<<fixnumshift) /* imm0 = inherited arg count  */
     2067dnl     __(mov imm1,#misc_data_offset+(2<<fixnumshift)) /* point to 1st arg  */
     2068dnl     __(mov imm4,#nil_value)
     2069dnl     __(ble+ cr0,local_label(no_insert))
     2070dnl     /* Some arguments have already been vpushed.  Vpush imm0's worth  */
     2071dnl     /* of NILs, copy those arguments that have already been vpushed from  */
     2072dnl     /* the old TOS to the new, then insert all of the inerited args  */
     2073dnl     /* and go to the function.  */
     2074dnl     __(mov imm2,#0)
     2075dnl local_label(push_nil_loop):
     2076dnl     __(addi imm2,imm2,fixnum_one)
     2077dnl     __(cmpr(cr2,imm2,imm0))
     2078dnl     __(vpush1(imm4))
     2079dnl     __(bne cr2,local_label(push_nil_loop))
     2080dnl
     2081dnl     __(mov imm3,vsp)
     2082dnl     __(add imm4,vsp,imm0)
     2083dnl     __(subi imm2,nargs,nargregs<<fixnumshift)
     2084dnl local_label(copy_already_loop):
     2085dnl     __(cmpri(cr2,imm2,fixnum_one))
     2086dnl     __(subi imm2,imm2,fixnum_one)
     2087dnl     __(ldr fname,[imm4,#0])
     2088dnl     __(addi imm4,imm4,fixnum_one)
     2089dnl     __(str(fname,0(imm3)))
     2090dnl     __(addi imm3,imm3,fixnum_one)
     2091dnl     __(bne cr2,local_label(copy_already_loop))
     2092dnl
     2093dnl local_label(insert_loop):
     2094dnl     __(cmpri(cr2,imm0,fixnum_one))
     2095dnl     __(ldrx(fname,nfn,imm1))
     2096dnl     __(addi imm1,imm1,fixnum_one)
     2097dnl     __(addi nargs,nargs,fixnum_one)
     2098dnl     __(subi imm0,imm0,fixnum_one)
     2099dnl     __(push(fname,imm4))
     2100dnl     __(bne cr2,local_label(insert_loop))
     2101dnl     __(b local_label(go))
     2102dnl local_label(no_insert):
     2103dnl     /* nargregs or fewer args were already vpushed.  */
     2104dnl     /* if exactly nargregs, vpush remaining inherited vars.  */
     2105dnl     __(add imm2,imm1,imm0)
     2106dnl     __(bne cr0,local_label(set_regs))
     2107dnl local_label(vpush_remaining):
     2108dnl     __(cmpri(cr2,imm0,fixnum_one))
     2109dnl     __(ldrx(fname,nfn,imm1))
     2110dnl     __(addi imm1,imm1,fixnum_one)
     2111dnl     __(vpush1(fname))
     2112dnl     __(subi imm0,imm0,fixnum_one)
     2113dnl     __(addi nargs,nargs,fixnum_one)
     2114dnl     __(bne cr2,local_label(vpush_remaining))
     2115dnl     __(b local_label(go))
     2116dnl local_label(set_regs):
     2117dnl     /* if nargs was > 1 (and we know that it was < 3), it must have  */
     2118dnl     /* been 2.  Set arg_x, then vpush the remaining args.  */
     2119dnl     __(ble cr1,local_label(set_y_z))
     2120dnl local_label(set_arg_x):
     2121dnl     __(subi imm0,imm0,fixnum_one)
     2122dnl     __(cmpri(cr0,imm0,0))
     2123dnl     __(subi imm2,imm2,fixnum_one)
     2124dnl     __(ldrx(arg_x,nfn,imm2))
     2125dnl     __(addi nargs,nargs,fixnum_one)
     2126dnl     __(bne cr0,local_label(vpush_remaining))
     2127dnl     __(b local_label(go))
     2128dnl     /* Maybe set arg_y or arg_z, preceding args  */
     2129dnl local_label(set_y_z):
     2130dnl     __(bne cr1,local_label(set_arg_z))
     2131dnl     /* Set arg_y, maybe arg_x, preceding args  */
     2132dnl local_label(set_arg_y):
     2133dnl     __(subi imm0,imm0,fixnum_one)
     2134dnl     __(cmpri(cr0,imm0,0))
     2135dnl     __(subi imm2,imm2,fixnum_one)
     2136dnl     __(ldrx(arg_y,nfn,imm2))
     2137dnl     __(addi nargs,nargs,fixnum_one)
     2138dnl     __(bne cr0,local_label(set_arg_x))
     2139dnl     __(b local_label(go))
     2140dnl local_label(set_arg_z):
     2141dnl     __(subi imm0,imm0,fixnum_one)
     2142dnl     __(cmpri(cr0,imm0,0))
     2143dnl     __(subi imm2,imm2,fixnum_one)
     2144dnl     __(ldrx(arg_z,nfn,imm2))
     2145dnl     __(addi nargs,nargs,fixnum_one)
     2146dnl     __(bne cr0,local_label(set_arg_y))
     2147dnl
     2148dnl local_label(go):
     2149dnl     __(vrefr(nfn,nfn,1))
     2150dnl     __(ldr loc_pc,[nfn,#_function.codevector])
     2151dnl     __(mtctr loc_pc)
     2152dnl     __(bctr)
     2153dnl         
     2154dnl /* This  treats anything that's either */
     2155dnl /* #+ppc32 (signed-byte 32), (unsigned-byte 32) */
     2156dnl /* #+ppc64 (signed-byte 64), (unsigned-byte 64) */
     2157dnl /* as if it denoted a "natural-sized" value.  */
     2158dnl /* Argument in arg_z, result in imm0.  May use temp0.  */
     2159dnl _spentry(getxlong)
     2160dnl         __ifdef(`PPC64')
     2161dnl         __else
     2162dnl         __(extract_typecode(imm0,arg_z))
     2163dnl     __(cmpri(cr0,imm0,tag_fixnum))
     2164dnl     __(cmpri(cr1,imm0,subtag_bignum))
     2165dnl     __(unbox_fixnum(imm0,arg_z))
     2166dnl     __(beqlr cr0)
     2167dnl     __(mov temp0,arg_z)
     2168dnl     __(bne- cr1,local_label(error))
     2169dnl     __(getvheader(imm0,temp0))
     2170dnl     __(cmpri(cr1,imm0,one_digit_bignum_header))
     2171dnl     __(cmpri(cr7,imm0,two_digit_bignum_header))
     2172dnl     __(beq cr1,local_label(big1))
     2173dnl         __(beq cr7,local_label(big2))
     2174dnl local_label(error):
     2175dnl     __(uuo_interr(error_object_not_integer,arg_z)) /* not quite right but what 68K MCL said  */
     2176dnl
     2177dnl
     2178dnl
     2179dnl local_label(big2):
     2180dnl     __(vrefr(imm0,temp0,1)) /* sign digit must be 0  */
     2181dnl     __(cmpri(imm0,0))
     2182dnl     __(bne local_label(error))
     2183dnl local_label(big1):
     2184dnl     __(vrefr(imm0,temp0,0))
     2185dnl     __(bx lr)
     2186dnl
     2187dnl
     2188dnl         __endif
     2189dnl                 
     2190dnl /* Everything up to the last arg has been vpushed, nargs is set to  */
     2191dnl /* the (boxed) count of things already pushed.  */
     2192dnl /* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
     2193dnl /* function call (this may require vpopping a few things.)  */
     2194dnl /* ppc2-invoke-fn assumes that temp1 is preserved here.  */
     2195dnl _spentry(spreadargz)
     2196dnl         __ifdef(`PPC64')
     2197dnl      __(extract_fulltag(imm1,arg_z))
     2198dnl      __(cmpri(cr1,imm1,fulltag_cons))
     2199dnl         __else
     2200dnl      __(extract_lisptag(imm1,arg_z))
     2201dnl      __(cmpri(cr1,imm1,tag_list))
     2202dnl         __endif
     2203dnl     __(cmpri(cr0,arg_z,nil_value))
     2204dnl     __(mov imm0,#0)
     2205dnl     __(mov arg_y,arg_z)             /*  save in case of error  */
     2206dnl     __(beq cr0,2f)
     2207dnl 1:
     2208dnl     __(bne- cr1,3f)
     2209dnl     __(_car(arg_x,arg_z))
     2210dnl     __(_cdr(arg_z,arg_z))
     2211dnl     __(cmpri(cr0,arg_z,nil_value))
     2212dnl         __ifdef(`PPC64')
     2213dnl      __(extract_fulltag(imm1,arg_z))
     2214dnl      __(cmpri(cr1,imm1,fulltag_cons))
     2215dnl         __else
     2216dnl      __(extract_lisptag(imm1,arg_z))
     2217dnl      __(cmpri(cr1,imm1,tag_list))
     2218dnl         __endif
     2219dnl     __(vpush1(arg_x))
     2220dnl     __(addi imm0,imm0,fixnum_one)
     2221dnl     __(bne cr0,1b)
     2222dnl 2:
     2223dnl     __(add. nargs,nargs,imm0)
     2224dnl     __(cmpri(cr2,nargs,2<<fixnumshift))
     2225dnl     __(beqlr- cr0)
     2226dnl     __(vpop(arg_z))
     2227dnl     __(bltlr cr2)
     2228dnl     __(vpop(arg_y))
     2229dnl     __(beqlr cr2)
     2230dnl     __(vpop(arg_x))
     2231dnl     __(bx lr)
     2232dnl         /*  Discard whatever's been vpushed already, complain.  */
     2233dnl 3: 
     2234dnl     __(add vsp,vsp,imm0)
     2235dnl     __(mov arg_z,arg_y)             /* recover original arg_z  */
     2236dnl     __(mov arg_y,#XNOSPREAD)
     2237dnl     __(set_nargs(2))
     2238dnl     __(b _SPksignalerr)
     2239dnl         
     2240dnl /* Tail-recursively funcall temp0.  */
     2241dnl /* Pretty much the same as the tcallsym* cases above.  */
     2242dnl _spentry(tfuncallgen)
     2243dnl     __(cmpri(cr0,nargs,nargregs<<fixnumshift))
     2244dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2245dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2246dnl     __(mtlr loc_pc)
     2247dnl     __(ble cr0,2f)
     2248dnl     __(ldr imm0,[sp,#lisp_frame.savevsp])
     2249dnl     __(discard_lisp_frame())
     2250dnl     /* can use nfn (= temp2) as a temporary  */
     2251dnl     __(subi imm1,nargs,nargregs<<fixnumshift)
     2252dnl     __(add imm1,imm1,vsp)
     2253dnl 1:
     2254dnl     __(ldru(temp2,-node_size(imm1)))
     2255dnl     __(cmpr(cr0,imm1,vsp))
     2256dnl     __(push(temp2,imm0))
     2257dnl     __(bne cr0,1b)
     2258dnl     __(mov vsp,imm0)
     2259dnl     __(do_funcall())
     2260dnl 2:
     2261dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     2262dnl     __(discard_lisp_frame())
     2263dnl     __(do_funcall())
     2264dnl
     2265dnl
     2266dnl /* Some args were vpushed.  Slide them down to the base of  */
     2267dnl /* the current frame, then do funcall.  */
     2268dnl _spentry(tfuncallslide)
     2269dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2270dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2271dnl     __(ldr imm0,[sp,#lisp_frame.savevsp])
     2272dnl     __(discard_lisp_frame())
     2273dnl     /* can use nfn (= temp2) as a temporary  */
     2274dnl     __(subi imm1,nargs,nargregs<<fixnumshift)
     2275dnl     __(add imm1,imm1,vsp)
     2276dnl     __(mtlr loc_pc)
     2277dnl 1:
     2278dnl     __(ldru(temp2,-node_size(imm1)))
     2279dnl     __(cmpr(cr0,imm1,vsp))
     2280dnl     __(push(temp2,imm0))
     2281dnl     __(bne cr0,1b)
     2282dnl     __(mov vsp,imm0)
     2283dnl     __(do_funcall())
     2284dnl
     2285dnl /* No args were vpushed; recover saved context & do funcall  */
     2286dnl _spentry(tfuncallvsp)
     2287dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2288dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2289dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     2290dnl     __(mtlr loc_pc)
     2291dnl     __(discard_lisp_frame())
     2292dnl     __(do_funcall())
     2293dnl         
     2294dnl /* Tail-recursively call the (known symbol) in fname.  */
     2295dnl /* In the general case, we don't know if any args were  */
     2296dnl /* vpushed or not.  If so, we have to "slide" them down  */
     2297dnl /* to the base of the frame.  If not, we can just restore  */
     2298dnl /* vsp, lr, fn from the saved lisp frame on the control stack.  */
     2299dnl _spentry(tcallsymgen)
     2300dnl     __(cmpri(cr0,nargs,nargregs<<fixnumshift))
     2301dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2302dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2303dnl     __(mtlr loc_pc)
     2304dnl     __(ble cr0,2f)
     2305dnl
     2306dnl     __(ldr imm0,[sp,#lisp_frame.savevsp])
     2307dnl     __(discard_lisp_frame())
     2308dnl     /* can use nfn (= temp2) as a temporary  */
     2309dnl     __(subi imm1,nargs,nargregs<<fixnumshift)
     2310dnl     __(add imm1,imm1,vsp)
     2311dnl 1:
     2312dnl     __(ldru(temp2,-node_size(imm1)))
     2313dnl     __(cmpr(cr0,imm1,vsp))
     2314dnl     __(push(temp2,imm0))
     2315dnl     __(bne cr0,1b)
     2316dnl     __(mov vsp,imm0)
     2317dnl     __(jump_fname)
     2318dnl     
     2319dnl 2:         
     2320dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     2321dnl     __(discard_lisp_frame())
     2322dnl     __(jump_fname)
     2323dnl     
     2324dnl     
     2325dnl /* Some args were vpushed.  Slide them down to the base of  */
     2326dnl /* the current frame, then do funcall.  */
     2327dnl _spentry(tcallsymslide)
     2328dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2329dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2330dnl     __(ldr imm0,[sp,#lisp_frame.savevsp])
     2331dnl     __(discard_lisp_frame())
     2332dnl     __(mtlr loc_pc)
     2333dnl     /* can use nfn (= temp2) as a temporary  */
     2334dnl     __(subi imm1,nargs,nargregs<<fixnumshift)
     2335dnl     __(add imm1,imm1,vsp)
     2336dnl 1:
     2337dnl     __(ldru(temp2,-node_size(imm1)))
     2338dnl     __(cmpr(cr0,imm1,vsp))
     2339dnl     __(push(temp2,imm0))
     2340dnl     __(bne cr0,1b)
     2341dnl     __(mov vsp,imm0)
     2342dnl     __(jump_fname)
     2343dnl
     2344dnl /* No args were vpushed; recover saved context & call symbol  */
     2345dnl _spentry(tcallsymvsp)
     2346dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2347dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2348dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     2349dnl     __(discard_lisp_frame())
     2350dnl     __(mtlr loc_pc)
     2351dnl     __(jump_fname)
     2352dnl     
     2353dnl /* Tail-recursively call the function in nfn.  */
     2354dnl /* Pretty much the same as the tcallsym* cases above.  */
     2355dnl _spentry(tcallnfngen)
     2356dnl     __(cmpri(cr0,nargs,nargregs<<fixnumshift))
     2357dnl     __(ble cr0,_SPtcallnfnvsp)
     2358dnl         __(b _SPtcallnfnslide)
     2359dnl
     2360dnl /* Some args were vpushed.  Slide them down to the base of  */
     2361dnl /* the current frame, then do funcall.  */
     2362dnl _spentry(tcallnfnslide)
     2363dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2364dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2365dnl     __(ldr imm0,[sp,#lisp_frame.savevsp])
     2366dnl     __(discard_lisp_frame())
     2367dnl     __(mtlr loc_pc)
     2368dnl     /* Since we have a known function, can use fname as a temporary.  */
     2369dnl     __(subi imm1,nargs,nargregs<<fixnumshift)
     2370dnl     __(add imm1,imm1,vsp)
     2371dnl 1:
     2372dnl     __(ldru(fname,-node_size(imm1)))
     2373dnl     __(cmpr(cr0,imm1,vsp))
     2374dnl     __(push(fname,imm0))
     2375dnl     __(bne cr0,1b)
     2376dnl     __(mov vsp,imm0)
     2377dnl             __(jump_nfn())
     2378dnl         
     2379dnl _spentry(tcallnfnvsp)
     2380dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     2381dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     2382dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     2383dnl     __(discard_lisp_frame())
     2384dnl     __(mtlr loc_pc)
     2385dnl             __(jump_nfn())
     2386dnl     
     2387dnl /* Reference index arg_z of a misc-tagged object (arg_y).  */
     2388dnl /* Note that this conses in some cases.  Return a properly-tagged  */
     2389dnl /* lisp object in arg_z.  Do type and bounds-checking.  */
     2390dnl     
     2391dnl _spentry(misc_ref)
     2392dnl     __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
     2393dnl     __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
     2394dnl     __(vector_length(imm0,arg_y,imm1))
     2395dnl     __(trlge(arg_z,imm0))
     2396dnl     __(extract_lowbyte(imm1,imm1))  /* imm1 = subtag  */
     2397dnl         __(b local_label(misc_ref_common)) 
     2398dnl     
     2399dnl
     2400dnl         
     2401dnl /* like misc_ref, only the boxed subtag is in arg_x.  */
     2402dnl
     2403dnl _spentry(subtag_misc_ref)
     2404dnl     __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
     2405dnl         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
     2406dnl     __(vector_length(imm0,arg_y,imm1))
     2407dnl     __(trlge(arg_z,imm0))
     2408dnl     __(unbox_fixnum(imm1,arg_x))
     2409dnl         __(b local_label(misc_ref_common))
     2410dnl
     2411dnl _spentry(builtin_aref1)
     2412dnl     __(extract_typecode(imm0,arg_y))
     2413dnl     __(cmpri(cr0,imm0,min_vector_subtag))
     2414dnl     __(box_fixnum(arg_x,imm0))
     2415dnl     __(bgt cr0,_SPsubtag_misc_ref)
     2416dnl     __(jump_builtin(_builtin_aref1,2))
     2417dnl             
     2418dnl     
     2419dnl /* Make a cons cell on the vstack.  Always push 3 words, 'cause we're   */
     2420dnl /* not sure how the vstack will be aligned.  */
     2421dnl _spentry(stkconsyz)
     2422dnl     __(mov imm0,#nil_value)
     2423dnl     __(vpush1(imm0))
     2424dnl     __(vpush1(imm0))
     2425dnl     __(vpush1(imm0))
     2426dnl     __(andi. imm0,vsp,1<<word_shift) /* (oddp vsp ?)  */
     2427dnl     __(beq cr0,1f)
     2428dnl     __(str(arg_y,node_size*2(vsp))) /* car  */
     2429dnl     __(str(arg_z,node_size(vsp))) /* cdr  */
     2430dnl     __(la arg_z,fulltag_cons+node_size(vsp))
     2431dnl     __(bx lr)
     2432dnl 1:
     2433dnl     __(str(arg_y,node_size(vsp))) /* car, again  */
     2434dnl     __(str(arg_z,0(vsp)))
     2435dnl     __(la arg_z,fulltag_cons(vsp))
     2436dnl     __(bx lr)
     2437dnl
     2438dnl /* Make a stack-consed value cell.  Much like the case of */
     2439dnl /* stack-allocating a cons cell.  Imm0 points to the closed-over value */
     2440dnl /* (already vpushed).  Replace that locative with the vcell.  */
     2441dnl _spentry(stkvcell0)
     2442dnl     __(sub imm1,imm0,vsp) /* imm1 = delta from vsp to value cell loc  */
     2443dnl     __(mov arg_z,#nil_value)
     2444dnl     __(vpush1(arg_z))
     2445dnl     __(vpush1(arg_z))
     2446dnl     __(vpush1(arg_z))
     2447dnl     __(addi imm1,imm1,node_size*3)
     2448dnl     __(add imm0,vsp,imm1) /* in case stack overflowed  */
     2449dnl     __(andi. imm1,vsp,1<<word_shift) /* (oddp vsp) ?  */
     2450dnl     __(mov imm1,#value_cell_header)
     2451dnl     __(ldr arg_z,[imm0,#0])
     2452dnl     __(beq cr0,1f)
     2453dnl     __(str(arg_z,node_size*2(vsp)))
     2454dnl     __(str(imm1,node_size(vsp)))
     2455dnl     __(la arg_z,fulltag_misc+node_size(vsp))
     2456dnl     __(str(arg_z,0(imm0)))
     2457dnl     __(bx lr)
     2458dnl 1:
     2459dnl     __(str(arg_z,node_size(vsp)))
     2460dnl     __(str(imm1,0(vsp)))
     2461dnl     __(la arg_z,fulltag_misc(vsp))
     2462dnl     __(str(arg_z,0(imm0)))
     2463dnl     __(bx lr)
     2464dnl
     2465dnl         
     2466dnl _spentry(stkvcellvsp)     
     2467dnl     __(mov arg_z,#nil_value)
     2468dnl     __(vpush1(arg_z))
     2469dnl     __(vpush1(arg_z))
     2470dnl     __(vpush1(arg_z))
     2471dnl     __(mov imm1,#node_size*3)
     2472dnl     __(add imm0,vsp,imm1) /* in case stack overflowed  */
     2473dnl     __(andi. imm1,vsp,1<<word_shift) /* (oddp vsp) ?  */
     2474dnl     __(mov imm1,#value_cell_header)
     2475dnl     __(ldr arg_z,[imm0,#0])
     2476dnl     __(beq cr0,1f)
     2477dnl     __(str(arg_z,node_size*2(vsp)))
     2478dnl     __(str(imm1,node_size(vsp)))
     2479dnl     __(la arg_z,fulltag_misc+node_size(vsp))
     2480dnl     __(str(arg_z,0(imm0)))
     2481dnl     __(bx lr)
     2482dnl 1:
     2483dnl     __(str(arg_z,node_size(vsp)))
     2484dnl     __(str(imm1,0(vsp)))
     2485dnl     __(la arg_z,fulltag_misc(vsp))
     2486dnl     __(str(arg_z,0(imm0)))
     2487dnl     __(bx lr)
     2488dnl
     2489dnl /* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
     2490dnl /* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
     2491dnl /* in arg_z on exit.  */
     2492dnl _spentry(makestackblock)
     2493dnl     __(unbox_fixnum(imm0,arg_z))
     2494dnl         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
     2495dnl     __(cmplri(cr0,imm0,tstack_alloc_limit))
     2496dnl     __(bge cr0,1f)
     2497dnl     __(TSP_Alloc_Var_Unboxed(imm0))
     2498dnl     __(mov imm0,#macptr_header)
     2499dnl     __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
     2500dnl     __(str(imm0,tsp_frame.data_offset(tsp)))
     2501dnl     __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
     2502dnl     __(str(imm1,macptr.address(arg_z)))
     2503dnl         __ifdef(`PPC64')
     2504dnl          __(std rzero,macptr.domain(arg_z))
     2505dnl          __(std rzero,macptr.type(arg_z))
     2506dnl         __else
     2507dnl      __(stfd fp_zero,macptr.domain(arg_z))
     2508dnl         __endif
     2509dnl     __(bx lr)
     2510dnl
     2511dnl         /* Too big. Heap cons a gcable macptr  */
     2512dnl 1:
     2513dnl     __(TSP_Alloc_Fixed_Unboxed(0))
     2514dnl     __(set_nargs(1))
     2515dnl     __(mov fname,#nrs.new_gcable_ptr)
     2516dnl     __(jump_fname())
     2517dnl
     2518dnl /* As above, only set the block's contents to 0.  */
     2519dnl _spentry(makestackblock0)
     2520dnl     __(unbox_fixnum(imm0,arg_z))
     2521dnl         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
     2522dnl     __(cmplri(cr0,imm0,tstack_alloc_limit))
     2523dnl     __(bge cr0,3f)
     2524dnl     __(TSP_Alloc_Var_Unboxed(imm0))
     2525dnl     __(Zero_TSP_Frame(imm0,imm1))
     2526dnl     __(mov imm0,#macptr_header)
     2527dnl     __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
     2528dnl     __(str(imm0,tsp_frame.data_offset(tsp)))
     2529dnl     __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
     2530dnl     __(str(imm1,macptr.address(arg_z))) /* makestackblock0 expects the address to be in imm1  */
     2531dnl     __(stfd fp_zero,macptr.domain(arg_z))
     2532dnl     __(bx lr)
     2533dnl
     2534dnl         /* Too big. Heap cons a gcable macptr  */
     2535dnl 3:
     2536dnl     __(TSP_Alloc_Fixed_Unboxed(0)) /* "raw" block to make the compiler happy  */
     2537dnl
     2538dnl     __(mov arg_y,arg_z) /* save block size  */
     2539dnl     __(mov arg_z,#t_value) /* clear-p arg to %new-gcable-ptr  */
     2540dnl     __(set_nargs(2))
     2541dnl     __(mov fname,#nrs.new_gcable_ptr)
     2542dnl     __(jump_fname())
     2543dnl
     2544dnl /* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
     2545dnl /* the tstack.  Return the list in arg_z.  */
     2546dnl _spentry(makestacklist)
     2547dnl     __(add imm0,arg_y,arg_y)
     2548dnl     __(cmplri(cr1,imm0,((tstack_alloc_limit+1)-cons.size)))
     2549dnl     __(addi imm0,imm0,tsp_frame.fixed_overhead)
     2550dnl     __(bge cr1,3f)
     2551dnl     __(TSP_Alloc_Var_Boxed(imm0,imm1))
     2552dnl     __(mov imm1,arg_y)
     2553dnl     __(cmpri(cr1,imm1,0))
     2554dnl     __(mov arg_y,arg_z)
     2555dnl     __(mov arg_z,#nil_value)
     2556dnl     __(ldr imm2,[tsp,#tsp_frame.backlink])
     2557dnl     __(la imm2,-tsp_frame.fixed_overhead+fulltag_cons(imm2))
     2558dnl     __(b 2f)
     2559dnl 1:
     2560dnl     __(subi imm1,imm1,fixnum1)
     2561dnl     __(cmpri(cr1,imm1,0))
     2562dnl     __(_rplacd(imm2,arg_z))
     2563dnl     __(_rplaca(imm2,arg_y))
     2564dnl     __(mov arg_z,imm2)
     2565dnl     __(subi imm2,imm2,cons.size)
     2566dnl 2:
     2567dnl     __(bne cr1,1b)
     2568dnl     __(bx lr)
     2569dnl
     2570dnl 3:
     2571dnl     __(cmpri(cr1,arg_y,0))
     2572dnl     __(TSP_Alloc_Fixed_Boxed(0))  /* make the compiler happy  */
     2573dnl     __(mov imm1,arg_y) /* count  */
     2574dnl     __(mov arg_y,arg_z) /* initial value  */
     2575dnl     __(mov arg_z,#nil_value) /* result  */
     2576dnl     __(b 5f)
     2577dnl 4:
     2578dnl     __(subi imm1,imm1,fixnum1)
     2579dnl     __(cmpri(cr1,imm1,0))
     2580dnl     __(Cons(arg_z,arg_y,arg_z))
     2581dnl 5:
     2582dnl     __(bne cr1,4b)
     2583dnl     __(bx lr)
     2584dnl
     2585dnl /* subtype (boxed) vpushed before initial values. (Had better be a  */
     2586dnl /* node header subtag.) Nargs set to count of things vpushed.  */
     2587dnl
     2588dnl _spentry(stkgvector)
     2589dnl     __(la imm0,-fixnum_one(nargs))
     2590dnl     __(cmpri(cr1,imm0,0))
     2591dnl     __(add imm1,vsp,nargs)
     2592dnl     __(ldru(temp0,-node_size(imm1)))
     2593dnl     __(slri(imm2,imm0,num_subtag_bits-fixnumshift))
     2594dnl         __ifdef(`PPC64')
     2595dnl          __(unbox_fixnum(imm3,temp0))
     2596dnl          __(or imm2,imm3,imm2)
     2597dnl         __else
     2598dnl      __(rlwimi imm2,temp0,32-fixnumshift,32-num_subtag_bits,31)
     2599dnl         __endif
     2600dnl         __(dnode_align(imm0,imm0,node_size+tsp_frame.fixed_overhead))
     2601dnl     __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
     2602dnl     __(str(imm2,tsp_frame.data_offset(tsp)))
     2603dnl     __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
     2604dnl     __(la imm3,misc_header_offset(arg_z))
     2605dnl     __(mov imm0,#fixnum1)
     2606dnl     __(b 2f)
     2607dnl 1:
     2608dnl     __(addi imm0,imm0,fixnum1)
     2609dnl     __(cmpr(cr1,imm0,nargs))
     2610dnl     __(ldru(temp0,-node_size(imm1)))
     2611dnl     __(stru(temp0,node_size(imm3)))
     2612dnl 2:
     2613dnl     __(bne cr1,1b)
     2614dnl     __(add vsp,vsp,nargs)
     2615dnl     __(bx lr)
     2616dnl
     2617dnl /* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
     2618dnl /* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
     2619dnl /* parameters must be "reasonable" (the  subtag must be valid, the element  */
     2620dnl /* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
     2621dnl /* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
     2622dnl /* proper header on it and its contents will be 0.   imm0 contains   */
     2623dnl /* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
     2624dnl /* This is intended for things like "make-array" and "%make-bignum" and the   */
     2625dnl /* like.  Things that involve creating small objects of known size can usually  */
     2626dnl /* do so inline with less hair.  */
     2627dnl
     2628dnl /* If this has to go out-of-line (to GC or whatever), it should do so via a   */
     2629dnl /* trap (or should otherwise ensure that both the LR and CTR are preserved   */
     2630dnl /* where the GC can find them.)  */
     2631dnl
     2632dnl
     2633dnl _spentry(misc_alloc)
     2634dnl         __ifdef(`PPC64')
     2635dnl          __(extract_unsigned_byte_bits_(imm2,arg_y,56))
     2636dnl          __(unbox_fixnum(imm0,arg_z))
     2637dnl          __(sldi imm2,arg_y,num_subtag_bits-fixnumshift)
     2638dnl          __(clrldi imm1,imm0,64-nlowtagbits)
     2639dnl          __(or imm0,imm2,imm0)
     2640dnl          __(extract_fulltag(imm2,imm0))
     2641dnl          __(cmpdi cr1,imm1,lowtag_nodeheader)
     2642dnl          __(cmpdi cr2,imm2,ivector_class_64_bit)
     2643dnl          __(bne- cr0,9f)
     2644dnl          __(cmpdi cr3,imm2,ivector_class_32_bit)
     2645dnl          __(cmpdi cr4,imm2,ivector_class_8_bit)
     2646dnl          __(mov imm2,arg_y)
     2647dnl          __(cmpdi cr5,imm1,subtag_bit_vector)
     2648dnl          __(beq cr1,1f)
     2649dnl          __(beq cr2,1f)
     2650dnl          __(srdi imm2,imm2,1)
     2651dnl          __(beq cr3,1f)
     2652dnl          __(beq cr5,2f)
     2653dnl          __(srdi imm2,imm2,1)
     2654dnl          __(bne cr4,1f)
     2655dnl          __(srdi imm2,imm2,1)
     2656dnl /* imm2 now = byte count.  Add 8 for header, 15 to align, then clear */
     2657dnl /* low four bits. */
     2658dnl 1:
     2659dnl          __(dnode_align(imm2,imm2,node_size))
     2660dnl
     2661dnl      __(Misc_Alloc(arg_z,imm0,imm2))
     2662dnl      __(bx lr)
     2663dnl 2:      /* bit-vector case  */
     2664dnl          __(addi imm2,arg_y,7<<fixnumshift)
     2665dnl          __(srdi imm2,imm2,3+fixnumshift)
     2666dnl          __(b 1b)
     2667dnl 9:                     
     2668dnl      __(uuo_interr(error_object_not_unsigned_byte_56,arg_y))
     2669dnl         __else
     2670dnl      __(extract_unsigned_byte_bits_(imm2,arg_y,24))
     2671dnl      __(unbox_fixnum(imm0,arg_z))
     2672dnl      __(extract_fulltag(imm1,imm0))
     2673dnl      __(bne- cr0,9f)
     2674dnl      __(cmpri(cr0,imm1,fulltag_nodeheader))
     2675dnl      __(mov imm3,imm0)
     2676dnl      __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
     2677dnl      __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits )/* imm0 now = header  */
     2678dnl      __(mov imm2,arg_y)
     2679dnl      __(beq cr0,1f) /* do probe if node object (fixnum element count = byte count).  */
     2680dnl      __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
     2681dnl      __(bng cr1,1f) /* do probe if 32-bit imm object  */
     2682dnl      __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
     2683dnl      __(srwi imm2,imm2,1)
     2684dnl      __(bgt cr0,2f)
     2685dnl      __(bgt cr1,1f)
     2686dnl      __(srwi imm2,imm2,1)
     2687dnl         /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
     2688dnl         /* low three bits.  */
     2689dnl 1:
     2690dnl          __(dnode_align(imm2,imm2,node_size))
     2691dnl
     2692dnl      __(Misc_Alloc(arg_z,imm0,imm2))
     2693dnl      __(bx lr)
     2694dnl 2:
     2695dnl      __(cmplri(imm3,subtag_double_float_vector))
     2696dnl      __(slwi imm2,arg_y,1)
     2697dnl      __(beq 1b)
     2698dnl      __(addi imm2,arg_y,7<<fixnumshift)
     2699dnl      __(srwi imm2,imm2,fixnumshift+3)
     2700dnl      __(b 1b)
     2701dnl 9:
     2702dnl      __(uuo_interr(error_object_not_unsigned_byte_24,arg_y))
     2703dnl         __endif
     2704dnl         
     2705dnl /* almost exactly as above, but "swap exception handling info" */
     2706dnl /* on exit and return  */
     2707dnl /* Deprecated */       
     2708dnl _spentry(poweropen_ffcallX)
     2709dnl         .long 0x7c800008        /* debug trap */
     2710dnl
     2711dnl
     2712dnl /* Destructuring-bind, macro-bind.  */
     2713dnl   
     2714dnl /* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
     2715dnl /* likewise immX regs.  */
     2716dnl /* arg_z preserved, nothing else in particular defined on exit.  */
     2717dnl /* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
     2718dnl /* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
     2719dnl /* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
     2720dnl /* opt-supplied-p flag in PPC bit mask_initopt,  */
     2721dnl /* keyp flag in PPC bit mask_keyp,  */
     2722dnl /* &allow-other-keys flag in PPC bit mask_aok,  */
     2723dnl /* &rest flag in PPC bit mask_restp.  */
     2724dnl /* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
     2725dnl /* length key count.  */
     2726dnl
     2727dnl _spentry(macro_bind)
     2728dnl         __ifdef(`PPC64')
     2729dnl      __(mov whole_reg,arg_reg)
     2730dnl      __(extract_fulltag(imm0,arg_reg))
     2731dnl          __(cmpri(cr1,arg_reg,nil_value))
     2732dnl      __(cmpri(cr0,imm0,fulltag_cons))
     2733dnl          __(beq cr1,0f)
     2734dnl      __(bne- cr0,1f)
     2735dnl 0:             
     2736dnl      __(_cdr(arg_reg,arg_reg))
     2737dnl      __(b local_label(destbind1))
     2738dnl         __else
     2739dnl      __(mov whole_reg,arg_reg)
     2740dnl      __(extract_lisptag(imm0,arg_reg))
     2741dnl      __(cmpri(cr0,imm0,tag_list))
     2742dnl      __(bne- cr0,1f)
     2743dnl      __(_cdr(arg_reg,arg_reg))
     2744dnl      __(b (local_label(destbind1)))
     2745dnl         __endif
     2746dnl 1:
     2747dnl     __(mov arg_y,#XCALLNOMATCH)
     2748dnl     __(mov arg_z,whole_reg)
     2749dnl     __(set_nargs(2))
     2750dnl     __(b _SPksignalerr)
     2751dnl
     2752dnl
     2753dnl _spentry(destructuring_bind)
     2754dnl     __(mov whole_reg,arg_reg)
     2755dnl         __(b local_label(destbind1))
     2756dnl     
     2757dnl _spentry(destructuring_bind_inner)
     2758dnl     __(mov whole_reg,arg_z)
     2759dnl local_label(destbind1):
     2760dnl     /* Extract required arg count.  */
     2761dnl     /* A bug in gas: can't handle shift count of "32" (= 0  */
     2762dnl     ifelse(eval(mask_req_width+mask_req_start),eval(32),`
     2763dnl     __(clrlwi. imm0,nargs,mask_req_start)
     2764dnl     ',`
     2765dnl     __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
     2766dnl     ')
     2767dnl     __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
     2768dnl     __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
     2769dnl     __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
     2770dnl     __(cmpri(cr4,imm4,0))
     2771dnl     __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
     2772dnl     __(cmpri(cr5,imm4,0))
     2773dnl     __(cmpri(cr1,imm1,0))
     2774dnl     __(cmpri(cr2,imm2,0))
     2775dnl     /* Save entry vsp in case of error.  */
     2776dnl     __(mov imm4,vsp)
     2777dnl     __(beq cr0,2f)
     2778dnl 1:
     2779dnl     __(cmpri(cr7,arg_reg,nil_value))
     2780dnl         __ifdef(`PPC64')
     2781dnl          __(extract_fulltag(imm3,arg_reg))
     2782dnl          __(cmpri(cr3,imm3,fulltag_cons))
     2783dnl         __else       
     2784dnl      __(extract_lisptag(imm3,arg_reg))
     2785dnl      __(cmpri(cr3,imm3,tag_list))
     2786dnl         __endif
     2787dnl     __(subi imm0,imm0,1)
     2788dnl     __(cmpri(cr0,imm0,0))
     2789dnl     __(beq cr7,toofew)
     2790dnl     __(bne cr3,badlist)
     2791dnl     __(ldr arg_x,[arg_reg,#cons.car])
     2792dnl     __(ldr arg_reg,[arg_reg,#cons.cdr])
     2793dnl     __(vpush1(arg_x))
     2794dnl     __(bne cr0,1b)
     2795dnl 2:
     2796dnl     __(beq cr1,rest_keys)
     2797dnl     __(bne cr2,opt_supp)
     2798dnl     /* 'simple' &optionals:  no supplied-p, default to nil.  */
     2799dnl simple_opt_loop:
     2800dnl     __(cmpri(cr0,arg_reg,nil_value))
     2801dnl         __ifdef(`PPC64')
     2802dnl          __(extract_fulltag(imm3,arg_reg))
     2803dnl          __(cmpri(cr3,imm3,fulltag_cons))
     2804dnl         __else
     2805dnl      __(extract_lisptag(imm3,arg_reg))
     2806dnl      __(cmpri(cr3,imm3,tag_list))
     2807dnl         __endif
     2808dnl     __(subi imm1,imm1,1)
     2809dnl     __(cmpri(cr1,imm1,0))
     2810dnl     __(mov imm5,#nil_value)
     2811dnl     __(beq cr0,default_simple_opt)
     2812dnl     __(bne cr3,badlist)
     2813dnl     __(ldr arg_x,[arg_reg,#cons.car])
     2814dnl     __(ldr arg_reg,[arg_reg,#cons.cdr])
     2815dnl     __(vpush1(arg_x))
     2816dnl     __(bne cr1,simple_opt_loop)
     2817dnl     __(b rest_keys)
     2818dnl default_simple_opt_loop:
     2819dnl     __(subi imm1,imm1,1)
     2820dnl     __(cmpri(cr1,imm1,0))
     2821dnl default_simple_opt:
     2822dnl     __(vpush1(imm5))
     2823dnl     __(bne cr1,default_simple_opt_loop)
     2824dnl     __(b rest_keys)
     2825dnl     /* Provide supplied-p vars for the &optionals.  */
     2826dnl opt_supp:
     2827dnl     __(mov arg_y,#t_value)
     2828dnl opt_supp_loop:
     2829dnl     __(cmpri(cr0,arg_reg,nil_value))
     2830dnl         __ifdef(`PPC64')
     2831dnl          __(extract_fulltag(imm3,arg_reg))
     2832dnl          __(cmpri(cr3,imm3,fulltag_cons))
     2833dnl         __else       
     2834dnl      __(extract_lisptag(imm3,arg_reg))
     2835dnl      __(cmpri(cr3,imm3,tag_list))
     2836dnl         __endif
     2837dnl     __(subi imm1,imm1,1)
     2838dnl     __(cmpri(cr1,imm1,0))
     2839dnl     __(beq cr0,default_hard_opt)
     2840dnl     __(bne cr3,badlist)
     2841dnl     __(ldr arg_x,[arg_reg,#cons.car])
     2842dnl     __(ldr arg_reg,[arg_reg,#cons.cdr])
     2843dnl     __(vpush1(arg_x))
     2844dnl     __(vpush1(arg_y))
     2845dnl     __(bne cr1,opt_supp_loop)
     2846dnl     __(b rest_keys)
     2847dnl default_hard_opt_loop:
     2848dnl     __(subi imm1,imm1,1)
     2849dnl     __(cmpri(cr1,imm1,0))
     2850dnl default_hard_opt:
     2851dnl     __(vpush1(imm5))
     2852dnl     __(vpush1(imm5))
     2853dnl     __(bne cr1,default_hard_opt_loop)
     2854dnl rest_keys:
     2855dnl     __(cmpri(cr0,arg_reg,nil_value))
     2856dnl     __(bne cr5,have_rest)
     2857dnl     __(bne cr4,have_keys)
     2858dnl     __(bne cr0,toomany)
     2859dnl     __(bx lr)
     2860dnl have_rest:
     2861dnl     __(vpush1(arg_reg))
     2862dnl     __(beqlr cr4)
     2863dnl have_keys:
     2864dnl     /* Ensure that arg_reg contains a proper,even-length list.  */
     2865dnl     /* Insist that its length is <= 512 (as a cheap circularity check.)  */
     2866dnl     __(mov imm0,#256)
     2867dnl     __(mov arg_x,arg_reg)
     2868dnl count_keys_loop:
     2869dnl         __ifdef(`PPC64')
     2870dnl          __(extract_fulltag(imm3,arg_x))
     2871dnl          __(cmpri(cr3,imm3,fulltag_cons))
     2872dnl         __else
     2873dnl      __(extract_lisptag(imm3,arg_x))
     2874dnl      __(cmpri(cr3,imm3,tag_list))
     2875dnl         __endif
     2876dnl     __(cmpri(cr0,arg_x,nil_value))
     2877dnl     __(subi imm0,imm0,1)
     2878dnl     __(cmpri(cr4,imm0,0))
     2879dnl     __(beq cr0,counted_keys)
     2880dnl     __(bne cr3,badlist)
     2881dnl     __(ldr arg_x,[arg_x,#cons.cdr])
     2882dnl         __ifdef(`PPC64')
     2883dnl          __(extract_fulltag(imm3,arg_x))
     2884dnl          __(cmpri(cr3,imm3,fulltag_cons))
     2885dnl         __else
     2886dnl      __(extract_lisptag(imm3,arg_x))
     2887dnl      __(cmpri(cr3,imm3,tag_list))
     2888dnl         __endif
     2889dnl     __(blt cr4,toomany)
     2890dnl     __(cmpri(cr0,arg_x,nil_value))
     2891dnl     __(beq cr0,db_badkeys)
     2892dnl     __(bne cr3,badlist)
     2893dnl     __(ldr arg_x,[arg_x,#cons.cdr])
     2894dnl     __(b count_keys_loop)
     2895dnl counted_keys:
     2896dnl     /* We've got a proper, even-length list of key/value pairs in */
     2897dnl     /* arg_reg. For each keyword var in the lambda-list, push a pair */
     2898dnl     /* of NILs on the vstack.  */
     2899dnl     __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
     2900dnl     __(mov imm2,imm0)       /* save number of keys  */
     2901dnl     __(mov imm5,#nil_value)
     2902dnl     __(b push_pair_test)
     2903dnl push_pair_loop:
     2904dnl     __(cmpri(cr0,imm0,1))
     2905dnl     __(subi imm0,imm0,1)
     2906dnl     __(vpush1(imm5))
     2907dnl     __(vpush1(imm5))
     2908dnl push_pair_test:
     2909dnl     __(bne cr0,push_pair_loop)
     2910dnl     __(slwi imm2,imm2,dnode_shift)  /* pairs -> bytes  */
     2911dnl     __(add imm2,vsp,imm2)           /* imm2 points below pairs  */
     2912dnl     __(mov imm0,#0)                 /* count unknown keywords so far  */
     2913dnl     __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
     2914dnl     __(extrwi nargs,nargs,mask_key_width,mask_key_start)
     2915dnl     /* Now, for each keyword/value pair in the list  */
     2916dnl     /*  a) if the keyword is found in the keyword vector, set the  */
     2917dnl     /*     corresponding entry on the vstack to the value and the  */
     2918dnl     /*     associated supplied-p var to T.  */
     2919dnl     /*  b) Regardless of whether or not the keyword is found,  */
     2920dnl         /*     if :ALLOW-OTHER-KEYS is provided with a non-nil value, */
     2921dnl     /*     set the low bit of imm1 to indicate that unknown keywords  */
     2922dnl     /*     are acceptable. (This bit is pre-set above to the value */
     2923dnl         /*     the encoded value of &allow_other_keys.) */
     2924dnl     /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
     2925dnl     /*     the count of unknown keywords in the high bits of imm1*/
     2926dnl     /* At the end of the list, signal an error if any unknown keywords were seen  */
     2927dnl     /* but not allowed.  Otherwise, return.  */
     2928dnl
     2929dnl match_keys_loop:
     2930dnl     __(cmpri(cr0,arg_reg,nil_value))
     2931dnl     __(mov imm0,#0)
     2932dnl     __(mov imm3,#misc_data_offset)
     2933dnl     __(beq cr0,matched_keys)
     2934dnl     __(ldr arg_x,[arg_reg,#cons.car])
     2935dnl     __(mov arg_y,#nrs.kallowotherkeys)
     2936dnl     __(cmpr(cr3,arg_x,arg_y))       /* :ALLOW-OTHER-KEYS ?  */
     2937dnl     __(ldr arg_reg,[arg_reg,#cons.cdr])
     2938dnl     __(ldr arg_y,[arg_reg,#cons.car])
     2939dnl     __(cmpr(cr4,imm0,nargs))
     2940dnl     __(ldr arg_reg,[arg_reg,#cons.cdr])
     2941dnl     __(b match_test)
     2942dnl match_loop:
     2943dnl     __(ldrx(temp0,keyvect_reg,imm3))
     2944dnl     __(cmpr(cr0,arg_x,temp0))
     2945dnl     __(addi imm0,imm0,1)
     2946dnl     __(cmpr(cr4,imm0,nargs))
     2947dnl     __(addi imm3,imm3,node_size)
     2948dnl     __(bne cr0,match_test)
     2949dnl     /* Got a hit.  Unless this keyword's been seen already, set it.  */
     2950dnl     __(slwi imm0,imm0,dnode_shift)
     2951dnl     __(subf imm0,imm0,imm2)
     2952dnl     __(ldr temp0,[imm0,#0])
     2953dnl     __(cmpri(cr0,temp0,nil_value))
     2954dnl     __(mov temp0,#t_value)
     2955dnl     __(bne cr0,match_keys_loop)     /* already saw this  */
     2956dnl     __(str(arg_y,node_size*1(imm0)))
     2957dnl     __(str(temp0,node_size*0(imm0)))
     2958dnl         __(bne cr3,match_keys_loop)
     2959dnl     __(b match_keys_check_aok)
     2960dnl match_test:
     2961dnl     __(bne cr4,match_loop)
     2962dnl         __(beq cr3,match_keys_check_aok)
     2963dnl         __(addi imm1,imm1,node_size)
     2964dnl         __(b match_keys_loop)
     2965dnl match_keys_check_aok:
     2966dnl         __(andi. imm0,imm1,2)  /* check "seen-aok" bit in imm1 */
     2967dnl         __(cmpri cr1,arg_y,nil_value) /* check value */
     2968dnl         __(ori imm1,imm1,2)
     2969dnl         __(bne cr0,match_keys_loop) /* duplicate aok */
     2970dnl         __(beq cr1,match_keys_loop)
     2971dnl         __(ori imm1,imm1,1)
     2972dnl     __(b match_keys_loop)
     2973dnl matched_keys:
     2974dnl         __(clrrwi. imm0,imm1,2)
     2975dnl         __(beqlr)
     2976dnl         __(andi. imm1,imm1,1)
     2977dnl         __(bnelr)
     2978dnl     /* Some unrecognized keywords.  Complain generically about  */
     2979dnl     /* invalid keywords.  */
     2980dnl db_badkeys:
     2981dnl     __(mov arg_y,#XBADKEYS)
     2982dnl     __(b destructure_error)
     2983dnl toomany:
     2984dnl     __(mov arg_y,#XCALLTOOMANY)
     2985dnl     __(b destructure_error)
     2986dnl toofew:
     2987dnl     __(mov arg_y,#XCALLTOOFEW)
     2988dnl     __(b destructure_error)
     2989dnl badlist:
     2990dnl     __(mov arg_y,#XCALLNOMATCH)
     2991dnl     /* b destructure_error  */
     2992dnl destructure_error:
     2993dnl     __(mov vsp,imm4)                /* undo everything done to the stack  */
     2994dnl     __(mov arg_z,whole_reg)
     2995dnl     __(set_nargs(2))
     2996dnl     __(b _SPksignalerr)
     2997dnl         
     2998dnl /* vpush the values in the value set atop the vsp, incrementing nargs.  */
     2999dnl /* Discard the tsp frame; leave values atop the vsp.  */
     3000dnl
     3001dnl _spentry(recover_values)
     3002dnl
     3003dnl /* First, walk the segments reversing the pointer to previous segment pointers  */
     3004dnl /* Can tell the end because that previous segment pointer is the prev tsp pointer  */
     3005dnl     __(ldr imm0,[tsp,#tsp_frame.backlink]) /* previous tsp  */
     3006dnl     __(mov imm1,tsp) /* current segment  */
     3007dnl     __(mov imm2,tsp) /* last segment  */
     3008dnl local_label(walkloop):
     3009dnl     __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment  */
     3010dnl     __(cmpr(cr0,imm0,imm3)) /* last segment?  */
     3011dnl     __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
     3012dnl     __(mov imm2,imm1) /* last segment <- current segment  */
     3013dnl     __(mov imm1,imm3) /* current segment <- next segment  */
     3014dnl     __(bne cr0,local_label(walkloop))
     3015dnl
     3016dnl         /* the final segment ptr is now in imm2  */
     3017dnl         /* walk backwards, pushing values on VSP and incrementing NARGS  */
     3018dnl local_label(pushloop):
     3019dnl     __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment  */
     3020dnl     __(cmpri(cr0,imm0,0))
     3021dnl     __(cmpr(cr1,imm2,tsp))
     3022dnl     __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
     3023dnl     __(add imm3,imm3,imm0)
     3024dnl     __(add nargs,nargs,imm0)
     3025dnl     __(b 2f)
     3026dnl 1:
     3027dnl     __(ldru(arg_z,-node_size(imm3)))
     3028dnl     __(cmpri(cr0,imm0,fixnum_one))
     3029dnl     __(subi imm0,imm0,fixnum_one)
     3030dnl     __(vpush1(arg_z))
     3031dnl 2:
     3032dnl     __(bne cr0,1b)
     3033dnl     __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment  */
     3034dnl     __(bne cr1,local_label(pushloop))
     3035dnl     __(unlink(tsp))
     3036dnl     __(bx lr)
     3037dnl
     3038dnl     
     3039dnl /* Go out of line to do this.  Sheesh.  */
     3040dnl
     3041dnl _spentry(vpopargregs)
     3042dnl     __(cmpri(cr0,nargs,0))
     3043dnl     __(cmpri(cr1,nargs,2<<fixnumshift))
     3044dnl     __(beqlr cr0)
     3045dnl     __(beq cr1,local_label(yz))
     3046dnl     __(blt cr1,local_label(z))
     3047dnl     __(ldr arg_z,[vsp,#node_size*0])
     3048dnl     __(ldr arg_y,[vsp,#node_size*1])
     3049dnl     __(ldr arg_x,[vsp,#node_size*2])
     3050dnl     __(la vsp,node_size*3(vsp))
     3051dnl     __(bx lr)
     3052dnl local_label(yz):
     3053dnl     __(ldr arg_z,[vsp,#node_size*0])
     3054dnl     __(ldr arg_y,[vsp,#node_size*1])
     3055dnl     __(la vsp,node_size*2(vsp))
     3056dnl     __(bx lr)
     3057dnl local_label(z):
     3058dnl     __(ldr arg_z,[vsp,#node_size*0])
     3059dnl     __(la vsp,node_size*1(vsp))
     3060dnl     __(bx lr)
     3061dnl
     3062dnl /* If arg_z is an integer, return in imm0 something whose sign  */
     3063dnl /* is the same as arg_z's.  If not an integer, error.  */
     3064dnl _spentry(integer_sign)
     3065dnl     __(extract_typecode(imm0,arg_z))
     3066dnl     __(cmpri(cr1,imm0,tag_fixnum))
     3067dnl     __(cmpri(cr0,imm0,subtag_bignum))
     3068dnl     __(mov imm0,arg_z)
     3069dnl     __(beqlr+ cr1)
     3070dnl     __(bne- cr0,1f)
     3071dnl     __(getvheader(imm0,arg_z))
     3072dnl         __ifdef(`PPC64')
     3073dnl          __(header_size(imm0,imm0))
     3074dnl          __(sldi imm0,imm0,2)
     3075dnl         __else
     3076dnl          __(header_length(imm0,imm0)) /* boxed length = scaled size  */
     3077dnl         __endif
     3078dnl         __(addi imm0,imm0,misc_data_offset-4) /* bias, less 1 element  */
     3079dnl     __(lwzx imm0,arg_z,imm0)
     3080dnl     __(cmpwi cr0,imm0,0)
     3081dnl     __(mov imm0,#1)
     3082dnl     __(bgelr cr0)
     3083dnl     __(mov imm0,#-1)
     3084dnl     __(bx lr)
     3085dnl 1:
     3086dnl     __(uuo_interr(error_object_not_integer,arg_z))
     3087dnl
     3088dnl /* like misc_set, only pass the (boxed) subtag in temp0  */
     3089dnl _spentry(subtag_misc_set)
     3090dnl     __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
     3091dnl     __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
     3092dnl     __(vector_length(imm0,arg_x,imm1))
     3093dnl     __(trlge(arg_y,imm0))
     3094dnl     __(unbox_fixnum(imm1,temp0))
     3095dnl local_label(misc_set_common):
     3096dnl         __ifdef(`PPC64')
     3097dnl          __(slwi imm1,imm1,3)
     3098dnl          __(mov imm0,#LO(local_label(misc_set_jmp)))
     3099dnl          __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
     3100dnl          __(ldx imm0,imm0,imm1)
     3101dnl          __(mtctr imm0)
     3102dnl          __(bctr)
     3103dnl local_label(misc_set_jmp):             
     3104dnl         /* 00-0f  */
     3105dnl          .quad local_label(misc_set_invalid) /* 00 even_fixnum  */
     3106dnl          .quad local_label(misc_set_invalid) /* 01 imm_0  */
     3107dnl          .quad local_label(misc_set_invalid) /* 02 immheader_0  */
     3108dnl          .quad _SPgvset /* 03 function  */
     3109dnl          .quad local_label(misc_set_invalid) /* 04 cons  */
     3110dnl          .quad local_label(misc_set_invalid) /* 05 imm_1  */
     3111dnl          .quad local_label(misc_set_invalid) /* 06 immheader_1  */
     3112dnl          .quad _SPgvset /* 07 catch_frame  */
     3113dnl          .quad local_label(misc_set_invalid) /* 08 odd_fixnum  */
     3114dnl          .quad local_label(misc_set_invalid) /* 09 imm_2  */
     3115dnl          .quad local_label(misc_set_u32) /* 0a code_vector  */
     3116dnl          .quad _SPgvset /* 0b slot_vector  */
     3117dnl          .quad local_label(misc_set_invalid) /* 0c misc  */
     3118dnl          .quad local_label(misc_set_invalid) /* 0d imm3  */
     3119dnl          .quad local_label(misc_set_invalid) /* 0e immheader_3  */
     3120dnl          .quad _SPgvset /* 0f ratio  */
     3121dnl         /* 10-1f  */
     3122dnl          .quad local_label(misc_set_invalid) /* 10 even_fixnum  */
     3123dnl          .quad local_label(misc_set_invalid) /* 11 imm_0  */
     3124dnl          .quad local_label(misc_set_invalid) /* 12 immheader_0  */
     3125dnl          .quad _SPgvset /* 13 symbol_0  */
     3126dnl          .quad local_label(misc_set_invalid) /* 14 cons  */
     3127dnl          .quad local_label(misc_set_invalid) /* 15 imm_1  */
     3128dnl          .quad local_label(misc_set_invalid) /* 16 immheader_1  */
     3129dnl          .quad _SPgvset /* 17 lisp_tread  */
     3130dnl          .quad local_label(misc_set_invalid) /* 18 odd_fixnum  */
     3131dnl          .quad local_label(misc_set_invalid) /* 19 imm_2  */
     3132dnl          .quad local_label(misc_set_u32) /* 1a xcode_vector  */
     3133dnl          .quad _SPgvset /* 1b instance  */
     3134dnl          .quad local_label(misc_set_invalid) /* 1c misc  */
     3135dnl          .quad local_label(misc_set_invalid) /* 1d imm3  */
     3136dnl          .quad local_label(misc_set_u64) /* 1e macptr  */
     3137dnl          .quad _SPgvset /* 1f complex  */
     3138dnl         /* 20-2f  */
     3139dnl          .quad local_label(misc_set_invalid) /* 20 even_fixnum  */
     3140dnl          .quad local_label(misc_set_invalid) /* 21 imm_0  */
     3141dnl          .quad local_label(misc_set_invalid) /* 22 immheader_0  */
     3142dnl          .quad local_label(misc_set_invalid) /* 23 nodeheader_0  */
     3143dnl          .quad local_label(misc_set_invalid) /* 24 cons  */
     3144dnl          .quad local_label(misc_set_invalid) /* 25 imm_1  */
     3145dnl          .quad local_label(misc_set_invalid) /* 26 immheader_1  */
     3146dnl          .quad _SPgvset /* 27 lock  */
     3147dnl          .quad local_label(misc_set_invalid) /* 28 odd_fixnum  */
     3148dnl          .quad local_label(misc_set_invalid) /* 29 imm_2  */
     3149dnl          .quad local_label(misc_set_u32) /* 2a bignum  */
     3150dnl          .quad _SPgvset /* 2b struct  */
     3151dnl          .quad local_label(misc_set_invalid) /* 2c misc  */
     3152dnl          .quad local_label(misc_set_invalid) /* 2d imm3  */
     3153dnl          .quad local_label(misc_set_u64) /* 2e dead_macptr  */
     3154dnl          .quad local_label(misc_set_invalid) /* 2f nodeheader_3  */
     3155dnl         /* 30-3f  */
     3156dnl          .quad local_label(misc_set_invalid) /* 30 even_fixnum  */
     3157dnl          .quad local_label(misc_set_invalid) /* 31 imm_0  */
     3158dnl          .quad local_label(misc_set_invalid) /* 32 immheader_0  */
     3159dnl          .quad local_label(misc_set_invalid) /* 33 nodeheader_0  */
     3160dnl          .quad local_label(misc_set_invalid) /* 34 cons  */
     3161dnl          .quad local_label(misc_set_invalid) /* 35 imm_1  */
     3162dnl          .quad local_label(misc_set_invalid) /* 36 immheader_1  */
     3163dnl          .quad _SPgvset /* 37 hash_vector  */
     3164dnl          .quad local_label(misc_set_invalid) /* 38 odd_fixnum  */
     3165dnl          .quad local_label(misc_set_invalid) /* 39 imm_2  */
     3166dnl          .quad local_label(misc_set_u32) /* 3a double_float  */
     3167dnl          .quad _SPgvset /* 3b istruct  */
     3168dnl          .quad local_label(misc_set_invalid) /* 3c misc  */
     3169dnl          .quad local_label(misc_set_invalid) /* 3d imm3  */
     3170dnl          .quad local_label(misc_set_invalid) /* 3e immheader_3  */
     3171dnl          .quad local_label(misc_set_invalid) /* 3f nodeheader_3  */
     3172dnl         /* 40-4f  */
     3173dnl          .quad local_label(misc_set_invalid) /* 40 even_fixnum  */
     3174dnl          .quad local_label(misc_set_invalid) /* 41 imm_0  */
     3175dnl          .quad local_label(misc_set_invalid) /* 42 immheader_0  */
     3176dnl          .quad local_label(misc_set_invalid) /* 43 nodeheader_0  */
     3177dnl          .quad local_label(misc_set_invalid) /* 44 cons  */
     3178dnl          .quad local_label(misc_set_invalid) /* 45 imm_1  */
     3179dnl          .quad local_label(misc_set_invalid) /* 46 immheader_1  */
     3180dnl          .quad _SPgvset /* 47 pool  */
     3181dnl          .quad local_label(misc_set_invalid) /* 48 odd_fixnum  */
     3182dnl          .quad local_label(misc_set_invalid) /* 49 imm_2  */
     3183dnl          .quad local_label(misc_set_invalid) /* 4a immheader_2  */
     3184dnl          .quad _SPgvset /* 4b value_cell_2  */
     3185dnl          .quad local_label(misc_set_invalid) /* 4c misc  */
     3186dnl          .quad local_label(misc_set_invalid) /* 4d imm3  */
     3187dnl          .quad local_label(misc_set_invalid) /* 4e immheader_3  */
     3188dnl          .quad local_label(misc_set_invalid) /* 4f nodeheader_3  */
     3189dnl         /* 50-5f  */
     3190dnl          .quad local_label(misc_set_invalid) /* 50 even_fixnum  */
     3191dnl          .quad local_label(misc_set_invalid) /* 51 imm_0  */
     3192dnl          .quad local_label(misc_set_invalid) /* 52 immheader_0  */
     3193dnl          .quad local_label(misc_set_invalid) /* 53 nodeheader_0  */
     3194dnl          .quad local_label(misc_set_invalid) /* 54 cons  */
     3195dnl          .quad local_label(misc_set_invalid) /* 55 imm_1  */
     3196dnl          .quad local_label(misc_set_invalid) /* 56 immheader_1  */
     3197dnl          .quad _SPgvset /* 57 weak  */
     3198dnl          .quad local_label(misc_set_invalid) /* 58 odd_fixnum  */
     3199dnl          .quad local_label(misc_set_invalid) /* 59 imm_2  */
     3200dnl          .quad local_label(misc_set_invalid) /* 5a immheader_2  */
     3201dnl          .quad _SPgvset /* 5b xfunction  */
     3202dnl          .quad local_label(misc_set_invalid) /* 5c misc  */
     3203dnl          .quad local_label(misc_set_invalid) /* 5d imm3  */
     3204dnl          .quad local_label(misc_set_invalid) /* 5e immheader_3  */
     3205dnl          .quad local_label(misc_set_invalid) /* 5f nodeheader_3  */
     3206dnl         /* 60-6f  */
     3207dnl          .quad local_label(misc_set_invalid) /* 60 even_fixnum  */
     3208dnl          .quad local_label(misc_set_invalid) /* 61 imm_0  */
     3209dnl          .quad local_label(misc_set_invalid) /* 62 immheader_0  */
     3210dnl          .quad local_label(misc_set_invalid) /* 63 nodeheader_0  */
     3211dnl          .quad local_label(misc_set_invalid) /* 64 cons  */
     3212dnl          .quad local_label(misc_set_invalid) /* 65 imm_1  */
     3213dnl          .quad local_label(misc_set_invalid) /* 66 immheader_1  */
     3214dnl          .quad _SPgvset /* 67 package  */
     3215dnl          .quad local_label(misc_set_invalid) /* 68 odd_fixnum  */
     3216dnl          .quad local_label(misc_set_invalid) /* 69 imm_2  */
     3217dnl          .quad local_label(misc_set_invalid) /* 6a immheader_2  */
     3218dnl          .quad local_label(misc_set_invalid) /* 6b nodeheader_2  */
     3219dnl          .quad local_label(misc_set_invalid) /* 6c misc  */
     3220dnl          .quad local_label(misc_set_invalid) /* 6d imm3  */
     3221dnl          .quad local_label(misc_set_invalid) /* 6e immheader_3  */
     3222dnl          .quad local_label(misc_set_invalid) /* 6f nodeheader_3  */
     3223dnl         /* 70-7f  */
     3224dnl          .quad local_label(misc_set_invalid) /* 70 even_fixnum  */
     3225dnl          .quad local_label(misc_set_invalid) /* 71 imm_0  */
     3226dnl          .quad local_label(misc_set_invalid) /* 72 immheader_0  */
     3227dnl          .quad local_label(misc_set_invalid) /* 73 nodeheader_0  */
     3228dnl          .quad local_label(misc_set_invalid) /* 74 cons  */
     3229dnl          .quad local_label(misc_set_invalid) /* 75 imm_1  */
     3230dnl          .quad local_label(misc_set_invalid) /* 76 immheader_1  */
     3231dnl          .quad local_label(misc_set_invalid) /* 77 nodeheader_1  */
     3232dnl          .quad local_label(misc_set_invalid) /* 78 odd_fixnum  */
     3233dnl          .quad local_label(misc_set_invalid) /* 79 imm_2  */
     3234dnl          .quad local_label(misc_set_invalid) /* 7a immheader_2  */
     3235dnl          .quad local_label(misc_set_invalid) /* 7b nodeheader_2  */
     3236dnl          .quad local_label(misc_set_invalid) /* 7c misc  */
     3237dnl          .quad local_label(misc_set_invalid) /* 7d imm3  */
     3238dnl          .quad local_label(misc_set_invalid) /* 7e immheader_3  */
     3239dnl          .quad local_label(misc_set_invalid) /* 7f nodeheader_3  */
     3240dnl         /* 80-8f  */
     3241dnl          .quad local_label(misc_set_invalid) /* 80 even_fixnum  */
     3242dnl          .quad local_label(misc_set_invalid) /* 81 imm_0  */
     3243dnl          .quad local_label(misc_set_invalid) /* 82 immheader_0  */
     3244dnl          .quad local_label(misc_set_invalid) /* 83 nodeheader_0  */
     3245dnl          .quad local_label(misc_set_invalid) /* 84 cons  */
     3246dnl          .quad local_label(misc_set_invalid) /* 85 imm_1  */
     3247dnl          .quad local_label(misc_set_invalid) /* 86 immheader_1  */
     3248dnl          .quad _SPgvset /* 87 arrayH  */
     3249dnl          .quad local_label(misc_set_invalid) /* 88 odd_fixnum  */
     3250dnl          .quad local_label(misc_set_invalid) /* 89 imm_2  */
     3251dnl          .quad local_label(misc_set_invalid) /* 8a immheader_2  */
     3252dnl          .quad _SPgvset /* 8b vectorH  */
     3253dnl          .quad local_label(misc_set_invalid) /* 8c misc  */
     3254dnl          .quad local_label(misc_set_invalid) /* 8d imm3  */
     3255dnl          .quad local_label(misc_set_invalid) /* 8e immheader_3  */
     3256dnl          .quad _SPgvset /* 8f simple_vector  */
     3257dnl         /* 90-9f  */
     3258dnl          .quad local_label(misc_set_invalid) /* 90 even_fixnum  */
     3259dnl          .quad local_label(misc_set_invalid) /* 91 imm_0  */
     3260dnl          .quad local_label(misc_set_s8) /* 92 s8  */
     3261dnl          .quad local_label(misc_set_invalid) /* 93 nodeheader_0  */
     3262dnl          .quad local_label(misc_set_invalid) /* 94 cons  */
     3263dnl          .quad local_label(misc_set_invalid) /* 95 imm_1  */
     3264dnl          .quad local_label(misc_set_s16) /* 96 immheader_1  */
     3265dnl          .quad local_label(misc_set_invalid) /* 97 nodeheader_1  */
     3266dnl          .quad local_label(misc_set_invalid) /* 98 odd_fixnum  */
     3267dnl          .quad local_label(misc_set_invalid) /* 99 imm_2  */
     3268dnl          .quad local_label(misc_set_s32) /* 9a s32  */
     3269dnl          .quad local_label(misc_set_invalid) /* 9b nodeheader_2  */
     3270dnl          .quad local_label(misc_set_invalid) /* 9c misc  */
     3271dnl          .quad local_label(misc_set_invalid) /* 9d imm3  */
     3272dnl          .quad local_label(misc_set_s64) /* 9e s64  */
     3273dnl          .quad local_label(misc_set_invalid) /* 9f nodeheader_3  */
     3274dnl         /* a0-af  */
     3275dnl          .quad local_label(misc_set_invalid) /* a0 even_fixnum  */
     3276dnl          .quad local_label(misc_set_invalid) /* a1 imm_0  */
     3277dnl          .quad local_label(misc_set_u8) /* a2 u8  */
     3278dnl          .quad local_label(misc_set_invalid) /* a3 nodeheader_0  */
     3279dnl          .quad local_label(misc_set_invalid) /* a4 cons  */
     3280dnl          .quad local_label(misc_set_invalid) /* a5 imm_1  */
     3281dnl          .quad local_label(misc_set_u16) /* a6 u16  */
     3282dnl          .quad local_label(misc_set_invalid) /* a7 nodeheader_1  */
     3283dnl          .quad local_label(misc_set_invalid) /* a8 odd_fixnum  */
     3284dnl          .quad local_label(misc_set_invalid) /* a9 imm_2  */
     3285dnl          .quad local_label(misc_set_u32) /* aa u32  */
     3286dnl          .quad local_label(misc_set_invalid) /* ab nodeheader_2  */
     3287dnl          .quad local_label(misc_set_invalid) /* ac misc  */
     3288dnl          .quad local_label(misc_set_invalid) /* ad imm3  */
     3289dnl          .quad local_label(misc_set_u64) /* ae u64  */
     3290dnl          .quad local_label(misc_set_invalid) /* af nodeheader_3  */
     3291dnl         /* b0-bf  */
     3292dnl          .quad local_label(misc_set_invalid) /* b0 even_fixnum  */
     3293dnl          .quad local_label(misc_set_invalid) /* b1 imm_0  */
     3294dnl          .quad local_label(misc_set_invalid) /* b2 immheader_0  */
     3295dnl          .quad local_label(misc_set_invalid) /* b3 nodeheader_0  */
     3296dnl          .quad local_label(misc_set_invalid) /* b4 cons  */
     3297dnl          .quad local_label(misc_set_invalid) /* b5 imm_1  */
     3298dnl          .quad local_label(misc_set_invalid) /* b6 immheader_1  */
     3299dnl          .quad local_label(misc_set_invalid) /* b7 nodeheader_1  */
     3300dnl          .quad local_label(misc_set_invalid) /* b8 odd_fixnum  */
     3301dnl          .quad local_label(misc_set_invalid) /* b9 imm_2  */
     3302dnl          .quad local_label(misc_set_single_float_vector) /* ba sf vector  */
     3303dnl          .quad local_label(misc_set_invalid) /* bb nodeheader_2  */
     3304dnl          .quad local_label(misc_set_invalid) /* bc misc  */
     3305dnl          .quad local_label(misc_set_invalid) /* bd imm3  */
     3306dnl          .quad local_label(misc_set_fixnum_vector) /* be fixnum_vector  */
     3307dnl          .quad local_label(misc_set_invalid) /* bf nodeheader_3  */
     3308dnl         /* c0-cf  */
     3309dnl          .quad local_label(misc_set_invalid) /* c0 even_fixnum  */
     3310dnl          .quad local_label(misc_set_invalid) /* c1 imm_0  */
     3311dnl          .quad local_label(misc_set_invalid) /* c2 immheader_0  */
     3312dnl          .quad local_label(misc_set_invalid) /* c3 nodeheader_0  */
     3313dnl          .quad local_label(misc_set_invalid) /* c4 cons  */
     3314dnl          .quad local_label(misc_set_invalid) /* c5 imm_1  */
     3315dnl          .quad local_label(misc_set_invalid) /* c6 immheader_1  */
     3316dnl          .quad local_label(misc_set_invalid) /* c7 nodeheader_1  */
     3317dnl          .quad local_label(misc_set_invalid) /* c8 odd_fixnum  */
     3318dnl          .quad local_label(misc_set_invalid) /* c9 imm_2  */
     3319dnl          .quad local_label(misc_set_invalid) /* ca immheader_2  */
     3320dnl          .quad local_label(misc_set_invalid) /* cb nodeheader_2  */
     3321dnl          .quad local_label(misc_set_invalid) /* cc misc  */
     3322dnl          .quad local_label(misc_set_invalid) /* cd imm3  */
     3323dnl          .quad local_label(misc_set_double_float_vector) /* ce double-float vector  */
     3324dnl          .quad local_label(misc_set_invalid) /* cf nodeheader_3  */
     3325dnl         /* d0-df  */
     3326dnl          .quad local_label(misc_set_invalid) /* d0 even_fixnum  */
     3327dnl          .quad local_label(misc_set_invalid) /* d1 imm_0  */
     3328dnl          .quad local_label(misc_set_string) /* d2 string  */
     3329dnl          .quad local_label(misc_set_invalid) /* d3 nodeheader_0  */
     3330dnl          .quad local_label(misc_set_invalid) /* d4 cons  */
     3331dnl          .quad local_label(misc_set_invalid) /* d5 imm_1  */
     3332dnl          .quad local_label(misc_set_invalid) /* d6 immheader_1  */
     3333dnl          .quad local_label(misc_set_invalid) /* d7 nodeheader_1  */
     3334dnl          .quad local_label(misc_set_invalid) /* d8 odd_fixnum  */
     3335dnl          .quad local_label(misc_set_invalid) /* d9 imm_2  */
     3336dnl          .quad local_label(misc_set_new_string) /* da new_string  */
     3337dnl          .quad local_label(misc_set_invalid) /* db nodeheader_2  */
     3338dnl          .quad local_label(misc_set_invalid) /* dc misc  */
     3339dnl          .quad local_label(misc_set_invalid) /* dd imm3  */
     3340dnl          .quad local_label(misc_set_invalid) /* de immheader_3  */
     3341dnl          .quad local_label(misc_set_invalid) /* df nodeheader_3  */
     3342dnl         /* e0-ef  */
     3343dnl          .quad local_label(misc_set_invalid) /* e0 even_fixnum  */
     3344dnl          .quad local_label(misc_set_invalid) /* e1 imm_0  */
     3345dnl          .quad local_label(misc_set_invalid) /* e2 immheader_0  */
     3346dnl          .quad local_label(misc_set_invalid) /* e3 nodeheader_0  */
     3347dnl          .quad local_label(misc_set_invalid) /* e4 cons  */
     3348dnl          .quad local_label(misc_set_invalid) /* e5 imm_1  */
     3349dnl          .quad local_label(misc_set_invalid) /* e6 immheader_1  */
     3350dnl          .quad local_label(misc_set_invalid) /* e7 nodeheader_1  */
     3351dnl          .quad local_label(misc_set_invalid) /* e8 odd_fixnum  */
     3352dnl          .quad local_label(misc_set_invalid) /* e9 imm_2  */
     3353dnl          .quad local_label(misc_set_invalid) /* ea immheader_2  */
     3354dnl          .quad local_label(misc_set_invalid) /* eb nodeheader_2  */
     3355dnl          .quad local_label(misc_set_invalid) /* ec misc  */
     3356dnl          .quad local_label(misc_set_invalid) /* ed imm3  */
     3357dnl          .quad local_label(misc_set_invalid) /* ee immheader_3  */
     3358dnl          .quad local_label(misc_set_invalid) /* ef nodeheader_3  */
     3359dnl         /* f0-ff  */
     3360dnl          .quad local_label(misc_set_invalid) /* f0 even_fixnum  */
     3361dnl          .quad local_label(misc_set_invalid) /* f1 imm_0  */
     3362dnl          .quad local_label(misc_set_invalid) /* f2 immheader_0  */
     3363dnl          .quad local_label(misc_set_invalid) /* f3 nodeheader_0  */
     3364dnl          .quad local_label(misc_set_invalid) /* f4 cons  */
     3365dnl          .quad local_label(misc_set_invalid) /* f5 imm_1  */
     3366dnl          .quad local_label(misc_set_bit_vector) /* f6 bit_vector  */
     3367dnl          .quad local_label(misc_set_invalid) /* f7 nodeheader_1  */
     3368dnl          .quad local_label(misc_set_invalid) /* f8 odd_fixnum  */
     3369dnl          .quad local_label(misc_set_invalid) /* f9 imm_2  */
     3370dnl          .quad local_label(misc_set_invalid) /* fa immheader_2  */
     3371dnl          .quad local_label(misc_set_invalid) /* fb nodeheader_2  */
     3372dnl          .quad local_label(misc_set_invalid) /* fc misc  */
     3373dnl          .quad local_label(misc_set_invalid) /* fd imm3  */
     3374dnl          .quad local_label(misc_set_invalid) /* fe immheader_3  */
     3375dnl          .quad local_label(misc_set_invalid) /* ff nodeheader_3  */
     3376dnl
     3377dnl local_label(misc_set_bit_vector):               
     3378dnl          __(lis imm3,0x8000)
     3379dnl          __(extract_unsigned_byte_bits_(imm0,arg_z,1))
     3380dnl      __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
     3381dnl          __(srdi imm0,arg_y,5+fixnumshift)
     3382dnl      __(srw imm3,imm3,imm1)
     3383dnl          __(bne local_label(misc_set_bad))
     3384dnl          __(cmpdi cr0,arg_z,0)
     3385dnl          __(sldi imm0,imm0,2)
     3386dnl      __(la imm0,misc_data_offset(imm0))
     3387dnl      __(lwzx imm2,arg_x,imm0)
     3388dnl          __(beq 1f)
     3389dnl          __(or imm2,imm3,imm2)
     3390dnl          __(stwx imm2,arg_x,imm0)
     3391dnl          __(bx lr)
     3392dnl 1:       __(andc imm2,imm2,imm3)
     3393dnl          __(stwx imm2,arg_x,imm0)
     3394dnl          __(bx lr)
     3395dnl local_label(misc_set_s16):
     3396dnl          __(extract_lisptag(imm2,arg_z))
     3397dnl          __(sldi imm0,arg_z,64-(16+fixnumshift))
     3398dnl          __(srdi imm1,arg_y,2)
     3399dnl          __(cmpdi cr7,imm2,tag_fixnum)
     3400dnl          __(sradi imm0,imm0,64-(16+fixnumshift))
     3401dnl          __(cmpd imm0,arg_z)
     3402dnl          __(la imm1,misc_data_offset(imm1))
     3403dnl          __(unbox_fixnum(imm0,arg_z))
     3404dnl          __(bne local_label(misc_set_bad))
     3405dnl          __(bne cr7,local_label(misc_set_bad))
     3406dnl          __(sthx imm0,arg_x,imm1)
     3407dnl          __(bx lr)
     3408dnl local_label(misc_set_u16):
     3409dnl          __(extract_unsigned_byte_bits_(imm0,arg_z,16))
     3410dnl          __(srdi imm1,arg_y,2)               
     3411dnl          __(unbox_fixnum(imm0,arg_z))
     3412dnl          __(la imm1,misc_data_offset(imm1))
     3413dnl          __(bne local_label(misc_set_bad))
     3414dnl          __(sthx imm0,arg_x,imm1)
     3415dnl          __(bx lr)
     3416dnl local_label(misc_set_single_float_vector):
     3417dnl          __(extract_fulltag(imm3,arg_z))
     3418dnl          __(srdi imm4,arg_y,1)
     3419dnl          __(cmpdi cr3,imm3,subtag_single_float)
     3420dnl          __(la imm4,misc_data_offset(imm4))
     3421dnl          __(bne cr3,local_label(misc_set_bad))
     3422dnl          __(srdi imm0,arg_z,32)
     3423dnl          __(stwx imm0,arg_x,imm4)
     3424dnl          __(bx lr)
     3425dnl local_label(misc_set_s32):
     3426dnl          __(extract_lisptag(imm2,arg_z))
     3427dnl          __(srdi imm4,arg_y,1)
     3428dnl          __(unbox_fixnum(imm0,arg_z))
     3429dnl          __(cmpdi imm2,tag_fixnum)
     3430dnl          __(sldi imm1,imm0,32)
     3431dnl          __(sradi imm1,imm1,32)
     3432dnl          __(la imm4,misc_data_offset(imm4))
     3433dnl          __(bne local_label(misc_set_bad))
     3434dnl          __(cmpd imm1,imm0)
     3435dnl          __(bne local_label(misc_set_bad))
     3436dnl          __(stwx imm0,arg_x,imm4)
     3437dnl          __(bx lr)
     3438dnl local_label(misc_set_u32):             
     3439dnl          __(extract_unsigned_byte_bits_(imm0,arg_z,32))
     3440dnl          __(srdi imm4,arg_y,1)
     3441dnl      __(la imm4,misc_data_offset(imm4))
     3442dnl          __(unbox_fixnum(imm0,arg_z))
     3443dnl          __(bne local_label(misc_set_bad))
     3444dnl          __(stwx imm0,arg_x,imm4)
     3445dnl          __(bx lr)
     3446dnl local_label(misc_set_new_string):
     3447dnl          __(extract_lowbyte(imm0,arg_z))
     3448dnl          __(srdi imm4,arg_y,1)
     3449dnl          __(cmpdi imm0,subtag_character)
     3450dnl      __(la imm4,misc_data_offset(imm4))
     3451dnl          __(srwi imm0,arg_z,charcode_shift)
     3452dnl          __(bne local_label(misc_set_bad))
     3453dnl          __(stwx imm0,arg_x,imm4)
     3454dnl          __(bx lr)
     3455dnl local_label(misc_set_string):     
     3456dnl          __(extract_lowbyte(imm0,arg_z))               
     3457dnl          __(srdi imm4,arg_y,3)
     3458dnl          __(cmpdi imm0,subtag_character)
     3459dnl          __(la imm4,misc_data_offset(imm4))
     3460dnl          __(bne cr0,local_label(misc_set_bad))
     3461dnl          __(srwi imm0,arg_z,charcode_shift)
     3462dnl          __(stbx imm0,arg_x,imm4)
     3463dnl          __(bx lr)
     3464dnl local_label(misc_set_s8):     
     3465dnl          __(extract_lisptag(imm2,arg_z))
     3466dnl          __(unbox_fixnum(imm0,arg_z))
     3467dnl          __(cmpdi cr2,imm2,tag_fixnum)
     3468dnl          __(srdi imm4,arg_y,3)
     3469dnl          __(sldi imm1,imm0,56)
     3470dnl          __(sradi imm1,imm1,56)
     3471dnl          __(cmpd imm1,imm0)
     3472dnl          __(bne cr2,local_label(misc_set_bad))
     3473dnl          __(la imm4,misc_data_offset(imm4))
     3474dnl          __(bne local_label(misc_set_bad))
     3475dnl          __(stbx imm0,arg_x,imm4)
     3476dnl          __(bx lr)
     3477dnl local_label(misc_set_u8):     
     3478dnl          __(extract_unsigned_byte_bits_(imm0,arg_z,8))
     3479dnl          __(srdi imm4,arg_y,3)
     3480dnl          __(unbox_fixnum(imm0,arg_z))
     3481dnl          __(la imm4,misc_data_offset(imm4))
     3482dnl          __(bne local_label(misc_set_bad))
     3483dnl          __(stbx imm0,arg_x,imm4)
     3484dnl          __(bx lr)
     3485dnl local_label(misc_set_u64):
     3486dnl          __(extract_lisptag(imm0,arg_z))
     3487dnl          __(extract_fulltag(imm2,arg_z))
     3488dnl          __(cmpdi cr0,arg_z,0)
     3489dnl          __(cmpdi cr7,imm0,0)
     3490dnl          __(cmpdi cr6,imm2,fulltag_misc)
     3491dnl          __(la imm4,misc_data_offset(arg_y))
     3492dnl          __(bne cr7,local_label(setu64_maybe_bignum))
     3493dnl          __(unbox_fixnum(imm0,arg_z))
     3494dnl          __(blt cr0,local_label(misc_set_bad))
     3495dnl          __(stdx imm0,arg_x,imm4)
     3496dnl          __(bx lr)
     3497dnl local_label(setu64_maybe_bignum):
     3498dnl          __(bne cr6,local_label(misc_set_bad))
     3499dnl          __(getvheader(imm1,arg_z))
     3500dnl          __(ld imm0,misc_data_offset(arg_z))
     3501dnl          __(rotldi imm0,imm0,32)
     3502dnl          __(cmpdi cr2,imm1,two_digit_bignum_header)
     3503dnl          __(cmpdi cr3,imm1,three_digit_bignum_header)
     3504dnl          __(cmpdi cr0,imm0,0)
     3505dnl          __(beq cr2,1f)
     3506dnl          __(bne cr3,local_label(misc_set_bad))
     3507dnl          __(lwz imm3,misc_data_offset+8(arg_z))
     3508dnl          __(cmpwi cr0,imm3,0)
     3509dnl          __(bne cr0,local_label(misc_set_bad))
     3510dnl          __(stdx imm0,arg_x,imm4)
     3511dnl          __(bx lr)
     3512dnl 1:       __(blt cr0,local_label(misc_set_bad))
     3513dnl          __(stdx imm0,arg_x,imm4)
     3514dnl          __(bx lr)
     3515dnl local_label(misc_set_double_float_vector):
     3516dnl          __(extract_typecode(imm0,arg_z))
     3517dnl          __(la imm4,misc_data_offset(arg_y))
     3518dnl          __(cmpdi imm0,subtag_double_float)
     3519dnl          __(bne local_label(misc_set_bad))
     3520dnl          __(ld imm0,misc_dfloat_offset(arg_z))
     3521dnl          __(stdx imm0,arg_x,imm4)
     3522dnl          __(bx lr)
     3523dnl local_label(misc_set_fixnum_vector):
     3524dnl          __(extract_lisptag(imm2,arg_z))
     3525dnl          __(unbox_fixnum(imm0,arg_z))
     3526dnl          __(cmpdi cr2,imm2,tag_fixnum)
     3527dnl          __(la imm4,misc_data_offset(arg_y))
     3528dnl          __(bne cr2,local_label(misc_set_bad))
     3529dnl          __(stdx imm0,arg_x,imm4)
     3530dnl          __(bx lr)
     3531dnl local_label(misc_set_s64):
     3532dnl          __(extract_lisptag(imm2,arg_z))
     3533dnl          __(extract_fulltag(imm3,arg_z))
     3534dnl          __(unbox_fixnum(imm0,arg_z))
     3535dnl          __(cmpdi cr2,imm2,tag_fixnum)
     3536dnl          __(cmpdi cr6,imm3,fulltag_misc)
     3537dnl          __(la imm4,misc_data_offset(arg_y))
     3538dnl          __(bne cr2,local_label(sets64_maybe_bignum))
     3539dnl          __(stdx imm0,arg_x,imm4)
     3540dnl          __(bx lr)
     3541dnl local_label(sets64_maybe_bignum):       
     3542dnl          __(bne cr6,local_label(misc_set_bad))
     3543dnl          __(getvheader(imm1,arg_z))
     3544dnl          __(ld imm0,misc_data_offset(arg_z))
     3545dnl          __(cmpdi cr1,imm1,two_digit_bignum_header)
     3546dnl          __(rotldi imm0,imm0,32)
     3547dnl          __(bne cr1,local_label(misc_set_bad))
     3548dnl          __(stdx imm0,arg_x,imm4)
     3549dnl          __(bx lr)
     3550dnl local_label(misc_set_bad):
     3551dnl      __(mov arg_y,arg_z)
     3552dnl      __(mov arg_z,arg_x)
     3553dnl      __(mov arg_x,#XNOTELT)
     3554dnl      __(set_nargs(3))
     3555dnl      __(b _SPksignalerr)
     3556dnl local_label(misc_set_invalid): 
     3557dnl          __(mov temp0,#XSETBADVEC)       
     3558dnl          __(set_nargs(4))
     3559dnl          __(vpush1(temp0))
     3560dnl          __(b _SPksignalerr)       
     3561dnl         __else
     3562dnl          __(slwi imm1,imm1,2)
     3563dnl          __(mov imm0,#LO(local_label(misc_set_jmp)))
     3564dnl          __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
     3565dnl          __(lwzx imm0,imm0,imm1)
     3566dnl          __(mtctr imm0)
     3567dnl          __(bctr)
     3568dnl local_label(misc_set_jmp):             
     3569dnl         /* 00-0f  */
     3570dnl          .long local_label(misc_set_invalid) /* 00 even_fixnum  */
     3571dnl          .long local_label(misc_set_invalid) /* 01 cons  */
     3572dnl          .long local_label(misc_set_invalid) /* 02 nodeheader  */
     3573dnl          .long local_label(misc_set_invalid) /* 03 imm  */
     3574dnl          .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
     3575dnl          .long local_label(misc_set_invalid) /* 05 nil  */
     3576dnl          .long local_label(misc_set_invalid) /* 06 misc  */
     3577dnl          .long local_label(misc_set_u32) /* 07 bignum  */
     3578dnl          .long local_label(misc_set_invalid) /* 08 even_fixnum  */
     3579dnl          .long local_label(misc_set_invalid) /* 09 cons  */
     3580dnl          .long _SPgvset /* 0a ratio  */
     3581dnl          .long local_label(misc_set_invalid) /* 0b imm  */
     3582dnl          .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
     3583dnl          .long local_label(misc_set_invalid) /* 0d nil  */
     3584dnl          .long local_label(misc_set_invalid) /* 0e misc  */
     3585dnl          .long local_label(misc_set_u32) /* 0f single_float  */
     3586dnl         /* 10-1f  */
     3587dnl          .long local_label(misc_set_invalid) /* 10 even_fixnum  */
     3588dnl          .long local_label(misc_set_invalid) /* 11 cons  */
     3589dnl          .long local_label(misc_set_invalid) /* 12 nodeheader  */
     3590dnl          .long local_label(misc_set_invalid) /* 13 imm  */
     3591dnl          .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
     3592dnl          .long local_label(misc_set_invalid) /* 15 nil  */