Changeset 13672


Ignore:
Timestamp:
Apr 25, 2010, 11:08:20 PM (15 years ago)
Author:
Gary Byers
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  */
     3593dnl          .long local_label(misc_set_invalid) /* 16 misc  */
     3594dnl          .long local_label(misc_set_u32) /* 17 double_float  */
     3595dnl          .long local_label(misc_set_invalid) /* 18 even_fixnum  */
     3596dnl          .long local_label(misc_set_invalid) /* 19 cons  */
     3597dnl          .long _SPgvset /* 1a complex  */
     3598dnl          .long local_label(misc_set_invalid) /* 1b imm  */
     3599dnl          .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
     3600dnl          .long local_label(misc_set_invalid) /* 1d nil  */
     3601dnl          .long local_label(misc_set_invalid) /* 1e misc  */
     3602dnl          .long local_label(misc_set_u32) /* 1f macptr  */
     3603dnl         /* 20-2f  */
     3604dnl          .long local_label(misc_set_invalid) /* 20 even_fixnum  */
     3605dnl          .long local_label(misc_set_invalid) /* 21 cons  */
     3606dnl          .long _SPgvset /* 22 catch_frame  */
     3607dnl          .long local_label(misc_set_invalid) /* 23 imm  */
     3608dnl          .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
     3609dnl          .long local_label(misc_set_invalid) /* 25 nil  */
     3610dnl          .long local_label(misc_set_invalid) /* 26 misc  */
     3611dnl          .long local_label(misc_set_u32) /* 27 dead_macptr  */
     3612dnl          .long local_label(misc_set_invalid) /* 28 even_fixnum  */
     3613dnl          .long local_label(misc_set_invalid) /* 29 cons  */
     3614dnl          .long _SPgvset /* 2a function  */
     3615dnl          .long local_label(misc_set_invalid) /* 2b imm  */
     3616dnl          .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
     3617dnl          .long local_label(misc_set_invalid) /* 2d nil  */
     3618dnl          .long local_label(misc_set_invalid) /* 2e misc  */
     3619dnl          .long local_label(misc_set_u32) /* 2f code_vector  */
     3620dnl         /* 30-3f  */
     3621dnl          .long local_label(misc_set_invalid) /* 30 even_fixnum  */
     3622dnl          .long local_label(misc_set_invalid) /* 31 cons  */
     3623dnl          .long _SPgvset /* 32 lisp_thread  */
     3624dnl          .long local_label(misc_set_invalid) /* 33 imm  */
     3625dnl          .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
     3626dnl          .long local_label(misc_set_invalid) /* 35 nil  */
     3627dnl          .long local_label(misc_set_invalid) /* 36 misc  */
     3628dnl          .long local_label(misc_set_u32) /* 37 creole  */
     3629dnl          .long local_label(misc_set_invalid) /* 38 even_fixnum  */
     3630dnl          .long local_label(misc_set_invalid) /* 39 cons  */
     3631dnl          .long _SPgvset /* 3a symbol  */
     3632dnl          .long local_label(misc_set_invalid) /* 3b imm  */
     3633dnl          .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
     3634dnl          .long local_label(misc_set_invalid) /* 3d nil  */
     3635dnl          .long local_label(misc_set_invalid) /* 3e misc  */
     3636dnl          .long local_label(misc_set_u32) /* 3f xcode_vector  */
     3637dnl         /* 40-4f  */
     3638dnl          .long local_label(misc_set_invalid) /* 40 even_fixnum  */
     3639dnl          .long local_label(misc_set_invalid) /* 41 cons  */
     3640dnl          .long _SPgvset /* 42 lock  */
     3641dnl          .long local_label(misc_set_invalid) /* 43 imm  */
     3642dnl          .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
     3643dnl          .long local_label(misc_set_invalid) /* 45 nil  */
     3644dnl          .long local_label(misc_set_invalid) /* 46 misc  */
     3645dnl          .long local_label(misc_set_invalid) /* 47 immheader  */
     3646dnl          .long local_label(misc_set_invalid) /* 48 even_fixnum  */
     3647dnl          .long local_label(misc_set_invalid) /* 49 cons  */
     3648dnl          .long _SPgvset /* 4a hash_vector  */
     3649dnl          .long local_label(misc_set_invalid) /* 4b imm  */
     3650dnl          .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
     3651dnl          .long local_label(misc_set_invalid) /* 4d nil  */
     3652dnl          .long local_label(misc_set_invalid) /* 4e misc  */
     3653dnl          .long local_label(misc_set_invalid) /* 4f immheader  */
     3654dnl         /* 50-5f  */
     3655dnl          .long local_label(misc_set_invalid) /* 50 even_fixnum  */
     3656dnl          .long local_label(misc_set_invalid) /* 51 cons  */
     3657dnl          .long _SPgvset /* 52 pool  */
     3658dnl          .long local_label(misc_set_invalid) /* 53 imm  */
     3659dnl          .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
     3660dnl          .long local_label(misc_set_invalid) /* 55 nil  */
     3661dnl          .long local_label(misc_set_invalid) /* 56 misc  */
     3662dnl          .long local_label(misc_set_invalid) /* 57 immheader  */
     3663dnl          .long local_label(misc_set_invalid) /* 58 even_fixnum  */
     3664dnl          .long local_label(misc_set_invalid) /* 59 cons  */
     3665dnl          .long _SPgvset /* 5a weak  */
     3666dnl          .long local_label(misc_set_invalid) /* 5b imm  */
     3667dnl          .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
     3668dnl          .long local_label(misc_set_invalid) /* 5d nil  */
     3669dnl          .long local_label(misc_set_invalid) /* 5e misc  */
     3670dnl          .long local_label(misc_set_invalid) /* 5f immheader  */
     3671dnl         /* 60-6f  */
     3672dnl          .long local_label(misc_set_invalid) /* 60 even_fixnum  */
     3673dnl          .long local_label(misc_set_invalid) /* 61 cons  */
     3674dnl          .long _SPgvset /* 62 package  */
     3675dnl          .long local_label(misc_set_invalid) /* 63 imm  */
     3676dnl          .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
     3677dnl          .long local_label(misc_set_invalid) /* 65 nil  */
     3678dnl          .long local_label(misc_set_invalid) /* 66 misc  */
     3679dnl          .long local_label(misc_set_invalid) /* 67 immheader  */
     3680dnl          .long local_label(misc_set_invalid) /* 68 even_fixnum  */
     3681dnl          .long local_label(misc_set_invalid) /* 69 cons  */
     3682dnl          .long _SPgvset /* 6a slot_vector  */
     3683dnl          .long local_label(misc_set_invalid) /* 6b imm  */
     3684dnl          .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
     3685dnl          .long local_label(misc_set_invalid) /* 6d nil  */
     3686dnl          .long local_label(misc_set_invalid) /* 6e misc  */
     3687dnl          .long local_label(misc_set_invalid) /* 6f immheader  */
     3688dnl         /* 70-7f  */
     3689dnl          .long local_label(misc_set_invalid) /* 70 even_fixnum  */
     3690dnl          .long local_label(misc_set_invalid) /* 71 cons  */
     3691dnl          .long _SPgvset /* 72 instance  */
     3692dnl          .long local_label(misc_set_invalid) /* 73 imm  */
     3693dnl          .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
     3694dnl          .long local_label(misc_set_invalid) /* 75 nil  */
     3695dnl          .long local_label(misc_set_invalid) /* 76 misc  */
     3696dnl          .long local_label(misc_set_invalid) /* 77 immheader  */
     3697dnl          .long local_label(misc_set_invalid) /* 78 even_fixnum  */
     3698dnl          .long local_label(misc_set_invalid) /* 79 cons  */
     3699dnl          .long _SPgvset /* 7a struct  */
     3700dnl          .long local_label(misc_set_invalid) /* 7b imm  */
     3701dnl          .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
     3702dnl          .long local_label(misc_set_invalid) /* 7d nil  */
     3703dnl          .long local_label(misc_set_invalid) /* 7e misc  */
     3704dnl          .long local_label(misc_set_invalid) /* 7f immheader  */
     3705dnl         /* 80-8f  */
     3706dnl          .long local_label(misc_set_invalid) /* 80 even_fixnum  */
     3707dnl          .long local_label(misc_set_invalid) /* 81 cons  */
     3708dnl          .long _SPgvset /* 82 istruct  */
     3709dnl          .long local_label(misc_set_invalid) /* 83 imm  */
     3710dnl          .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
     3711dnl          .long local_label(misc_set_invalid) /* 85 nil  */
     3712dnl          .long local_label(misc_set_invalid) /* 86 misc  */
     3713dnl          .long local_label(misc_set_invalid) /* 87 immheader  */
     3714dnl          .long local_label(misc_set_invalid) /* 88 even_fixnum  */
     3715dnl          .long local_label(misc_set_invalid) /* 89 cons  */
     3716dnl          .long _SPgvset /* 8a value_cell  */
     3717dnl          .long local_label(misc_set_invalid) /* 8b imm  */
     3718dnl          .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
     3719dnl          .long local_label(misc_set_invalid) /* 8d nil  */
     3720dnl          .long local_label(misc_set_invalid) /* 8e misc  */
     3721dnl          .long local_label(misc_set_invalid) /* 8f immheader  */
     3722dnl         /* 90-9f  */
     3723dnl          .long local_label(misc_set_invalid) /* 90 even_fixnum  */
     3724dnl          .long local_label(misc_set_invalid) /* 91 cons  */
     3725dnl          .long _SPgvset /* 92 xfunction  */
     3726dnl          .long local_label(misc_set_invalid) /* 93 imm  */
     3727dnl          .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
     3728dnl          .long local_label(misc_set_invalid) /* 95 nil  */
     3729dnl          .long local_label(misc_set_invalid) /* 96 misc  */
     3730dnl          .long local_label(misc_set_invalid) /* 97 immheader  */
     3731dnl          .long local_label(misc_set_invalid) /* 98 even_fixnum  */
     3732dnl          .long local_label(misc_set_invalid) /* 99 cons  */
     3733dnl          .long _SPgvset /* 9a arrayH  */
     3734dnl          .long local_label(misc_set_invalid) /* 9b imm  */
     3735dnl          .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
     3736dnl          .long local_label(misc_set_invalid) /* 9d nil  */
     3737dnl          .long local_label(misc_set_invalid) /* 9e misc  */
     3738dnl          .long local_label(misc_set_invalid) /* 9f immheader  */
     3739dnl         /* a0-af  */
     3740dnl          .long local_label(misc_set_invalid) /* a0 even_fixnum  */
     3741dnl          .long local_label(misc_set_invalid) /* a1 cons  */
     3742dnl          .long _SPgvset /* a2 vectorH  */
     3743dnl          .long local_label(misc_set_invalid) /* a3 imm  */
     3744dnl          .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
     3745dnl          .long local_label(misc_set_invalid) /* a5 nil  */
     3746dnl          .long local_label(misc_set_invalid) /* a6 misc  */
     3747dnl          .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
     3748dnl          .long local_label(misc_set_invalid) /* a8 even_fixnum  */
     3749dnl          .long local_label(misc_set_invalid) /* a9 cons  */
     3750dnl          .long _SPgvset /* aa vectorH  */
     3751dnl          .long local_label(misc_set_invalid) /* ab imm  */
     3752dnl          .long local_label(misc_set_invalid) /* ac odd_fixnum  */
     3753dnl          .long local_label(misc_set_invalid) /* ad nil  */
     3754dnl          .long local_label(misc_set_invalid) /* ae misc  */
     3755dnl          .long local_label(misc_set_u32) /* af u32  */
     3756dnl         /* b0-bf  */
     3757dnl          .long local_label(misc_set_invalid) /* b0 even_fixnum  */
     3758dnl          .long local_label(misc_set_invalid) /* b1 cons  */
     3759dnl          .long local_label(misc_set_invalid) /* b2 node  */
     3760dnl          .long local_label(misc_set_invalid) /* b3 imm  */
     3761dnl          .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
     3762dnl          .long local_label(misc_set_invalid) /* b5 nil  */
     3763dnl          .long local_label(misc_set_invalid) /* b6 misc  */
     3764dnl          .long local_label(misc_set_s32) /* b7 s32  */
     3765dnl          .long local_label(misc_set_invalid) /* b8 even_fixnum  */
     3766dnl          .long local_label(misc_set_invalid) /* b9 cons  */
     3767dnl          .long local_label(misc_set_invalid) /* ba nodeheader  */
     3768dnl          .long local_label(misc_set_invalid) /* bb imm  */
     3769dnl          .long local_label(misc_set_invalid) /* bc odd_fixnum  */
     3770dnl          .long local_label(misc_set_invalid) /* bd nil  */
     3771dnl          .long local_label(misc_set_invalid) /* be misc  */
     3772dnl          .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
     3773dnl         /* c0-cf  */
     3774dnl          .long local_label(misc_set_invalid) /* c0 even_fixnum  */
     3775dnl          .long local_label(misc_set_invalid) /* c1 cons  */
     3776dnl          .long local_label(misc_set_invalid) /* c2 nodeheader  */
     3777dnl          .long local_label(misc_set_invalid) /* c3 imm  */
     3778dnl          .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
     3779dnl          .long local_label(misc_set_invalid) /* c5 nil  */
     3780dnl          .long local_label(misc_set_invalid) /* c6 misc  */
     3781dnl          .long local_label(misc_set_new_string) /* c7 new_string  */
     3782dnl          .long local_label(misc_set_invalid) /* c8 even_fixnum  */
     3783dnl          .long local_label(misc_set_invalid) /* c9 cons  */
     3784dnl          .long local_label(misc_set_invalid) /* ca nodeheader  */
     3785dnl          .long local_label(misc_set_invalid) /* cb imm  */
     3786dnl          .long local_label(misc_set_invalid) /* cc odd_fixnum  */
     3787dnl          .long local_label(misc_set_invalid) /* cd nil  */
     3788dnl          .long local_label(misc_set_invalid) /* ce misc  */
     3789dnl          .long local_label(misc_set_u8) /* cf u8  */
     3790dnl         /* d0-df  */
     3791dnl          .long local_label(misc_set_invalid) /* d0 even_fixnum  */
     3792dnl          .long local_label(misc_set_invalid) /* d1 cons  */
     3793dnl          .long local_label(misc_set_invalid) /* d2 nodeheader  */
     3794dnl          .long local_label(misc_set_invalid) /* d3 imm  */
     3795dnl          .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
     3796dnl          .long local_label(misc_set_invalid) /* d5 nil  */
     3797dnl          .long local_label(misc_set_invalid) /* d6 misc  */
     3798dnl          .long local_label(misc_set_s8) /* d7 s8  */
     3799dnl          .long local_label(misc_set_invalid) /* d8 even_fixnum  */
     3800dnl          .long local_label(misc_set_invalid) /* d9 cons  */
     3801dnl          .long local_label(misc_set_invalid) /* da nodeheader  */
     3802dnl          .long local_label(misc_set_invalid) /* db imm  */
     3803dnl          .long local_label(misc_set_invalid) /* dc odd_fixnum  */
     3804dnl          .long local_label(misc_set_invalid) /* dd nil  */
     3805dnl          .long local_label(misc_set_invalid) /* de misc  */
     3806dnl          .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
     3807dnl         /* e0-ef  */
     3808dnl          .long local_label(misc_set_invalid) /* e0 even_fixnum  */
     3809dnl          .long local_label(misc_set_invalid) /* e1 cons  */
     3810dnl          .long local_label(misc_set_invalid) /* e2 nodeheader  */
     3811dnl          .long local_label(misc_set_invalid) /* e3 imm  */
     3812dnl          .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
     3813dnl          .long local_label(misc_set_invalid) /* e5 nil  */
     3814dnl          .long local_label(misc_set_invalid) /* e6 misc  */
     3815dnl          .long local_label(misc_set_u16) /* e7 u16  */
     3816dnl          .long local_label(misc_set_invalid) /* e8 even_fixnum  */
     3817dnl          .long local_label(misc_set_invalid) /* e9 cons  */
     3818dnl          .long local_label(misc_set_invalid) /* ea nodeheader  */
     3819dnl          .long local_label(misc_set_invalid) /* eb imm  */
     3820dnl          .long local_label(misc_set_invalid) /* ec odd_fixnum  */
     3821dnl          .long local_label(misc_set_invalid) /* ed nil  */
     3822dnl          .long local_label(misc_set_invalid) /* ee misc  */
     3823dnl          .long local_label(misc_set_s16) /* ef s16  */
     3824dnl         /* f0-ff  */
     3825dnl          .long local_label(misc_set_invalid) /* f0 even_fixnum  */
     3826dnl          .long local_label(misc_set_invalid) /* f1 cons  */
     3827dnl          .long local_label(misc_set_invalid) /* f2 nodeheader  */
     3828dnl          .long local_label(misc_set_invalid) /* f3 imm  */
     3829dnl          .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
     3830dnl          .long local_label(misc_set_invalid) /* f5 nil  */
     3831dnl          .long local_label(misc_set_invalid) /* f6 misc  */
     3832dnl          .long local_label(misc_set_double_float_vector) /* f7 df vector  */
     3833dnl          .long local_label(misc_set_invalid) /* f8 even_fixnum  */
     3834dnl          .long local_label(misc_set_invalid) /* f9 cons  */
     3835dnl          .long local_label(misc_set_invalid) /* fa nodeheader  */
     3836dnl          .long local_label(misc_set_invalid) /* fb imm  */
     3837dnl          .long local_label(misc_set_invalid) /* fc odd_fixnum  */
     3838dnl          .long local_label(misc_set_invalid) /* fd nil  */
     3839dnl          .long local_label(misc_set_invalid) /* fe misc  */
     3840dnl          .long local_label(misc_set_bit_vector) /* ff bit_vector  */
     3841dnl
     3842dnl local_label(misc_set_u32):       
     3843dnl     /* Either a non-negative fixnum, a positiveone-digit bignum, */
     3844dnl     /* or a two-digit bignum whose sign-digit is 0 is ok.  */
     3845dnl      __(extract_lisptag(imm2,arg_z))
     3846dnl      __(srawi. imm1,arg_z,fixnum_shift)
     3847dnl          __(cmpwi cr5,imm2,tag_fixnum)         
     3848dnl          __(la imm0,misc_data_offset(arg_y))
     3849dnl          __(cmpwi cr7,imm2,tag_misc)
     3850dnl      __(bne cr5,local_label(set_not_fixnum_u32))
     3851dnl      __(blt- cr0,local_label(set_bad))
     3852dnl local_label(set_set32):         
     3853dnl      __(stwx imm1,arg_x,imm0)
     3854dnl      __(bx lr)
     3855dnl local_label(set_not_fixnum_u32):
     3856dnl      __(bne cr7,local_label(set_bad))
     3857dnl      __(extract_header(imm2,arg_z))
     3858dnl      __(cmpri(cr0,imm2,one_digit_bignum_header))
     3859dnl      __(cmpri(cr1,imm2,two_digit_bignum_header))
     3860dnl      __(vrefr(imm1,arg_z,0))
     3861dnl      __(cmpri(cr2,imm1,0))
     3862dnl      __(bne cr0,local_label(set_not_1_digit_u32))
     3863dnl      __(bge cr2,local_label(set_set32))
     3864dnl      __(b local_label(set_bad))
     3865dnl local_label(set_not_1_digit_u32):
     3866dnl      __(bne- cr1,local_label(set_bad))
     3867dnl      __(vrefr(imm2,arg_z,1))
     3868dnl      __(cmpri(cr0,imm2,0))
     3869dnl      __(bne- cr1,local_label(set_bad))
     3870dnl      __(beq cr0,local_label(set_set32))
     3871dnl local_label(set_bad):
     3872dnl     /* arg_z does not match the array-element-type of arg_x.  */
     3873dnl      __(mov arg_y,arg_z)
     3874dnl      __(mov arg_z,arg_x)
     3875dnl      __(mov arg_x,#XNOTELT)
     3876dnl      __(set_nargs(3))
     3877dnl      __(b _SPksignalerr)
     3878dnl local_label(misc_set_fixnum_vector):   
     3879dnl          __(extract_lisptag(imm2,arg_z))
     3880dnl          __(la imm0,misc_data_offset(arg_y))
     3881dnl          __(cmpwi cr5,imm2,tag_fixnum)
     3882dnl          __(unbox_fixnum(imm1,arg_z))
     3883dnl          __(bne cr5,local_label(set_bad))
     3884dnl          __(stwx imm1,arg_x,imm0)
     3885dnl          __(bx lr)
     3886dnl local_label(misc_set_new_string):   
     3887dnl          __(clrlwi imm2,arg_z,ncharcodebits)
     3888dnl          __(la imm0,misc_data_offset(arg_y))
     3889dnl          __(cmpwi cr5,imm2,subtag_character)
     3890dnl          __(srwi imm1,arg_z,charcode_shift)
     3891dnl          __(bne cr5,local_label(set_bad))
     3892dnl          __(stwx imm1,arg_x,imm0)
     3893dnl          __(bx lr)
     3894dnl local_label(misc_set_s32):
     3895dnl          __(extract_lisptag(imm2,arg_z))
     3896dnl          __(cmpwi cr5,imm2,tag_fixnum)
     3897dnl          __(cmpwi cr7,imm2,tag_misc)
     3898dnl          __(la imm0,misc_data_offset(arg_y))
     3899dnl      __(unbox_fixnum(imm1,arg_z))
     3900dnl      __(beq cr5,local_label(set_set32))
     3901dnl      __(bne cr7,local_label(set_bad))
     3902dnl      __(extract_header(imm2,arg_z))
     3903dnl      __(cmpri(cr0,imm2,one_digit_bignum_header))
     3904dnl      __(vrefr(imm1,arg_z,0))
     3905dnl      __(bne- cr0,local_label(set_bad))
     3906dnl      __(str imm1,arg_x,imm0)
     3907dnl      __(bx lr)
     3908dnl local_label(misc_set_single_float_vector):
     3909dnl          __(extract_lisptag(imm2,arg_z))
     3910dnl          __(cmpwi cr7,imm2,tag_misc)
     3911dnl          __(la imm0,misc_data_offset(arg_y))
     3912dnl      __(bne- cr7,local_label(set_bad))
     3913dnl      __(extract_header(imm2,arg_z))
     3914dnl      __(cmpri(cr0,imm2,single_float_header))
     3915dnl      __(bne- cr0,local_label(set_bad))
     3916dnl      __(ldr imm1,[arg_z,#single_float.value])
     3917dnl      __(str imm1,arg_x,imm0)
     3918dnl      __(bx lr)
     3919dnl local_label(misc_set_u8):               
     3920dnl      __(extract_lisptag(imm2,arg_z))
     3921dnl      __(srwi imm0,arg_y,2)
     3922dnl      __(la imm0,misc_data_offset(imm0))
     3923dnl      __(extract_unsigned_byte_bits_(imm1,arg_z,8))
     3924dnl      __(unbox_fixnum(imm1,arg_z))
     3925dnl      __(bne- cr0,local_label(set_bad))
     3926dnl      __(stbx imm1,arg_x,imm0)
     3927dnl      __(bx lr)
     3928dnl local_label(misc_set_old_string):
     3929dnl      __(srwi imm0,arg_y,2)
     3930dnl      __(extract_lowbyte(imm2,arg_z))
     3931dnl      __(cmpri(cr2,imm2,subtag_character))
     3932dnl      __(la imm0,misc_data_offset(imm0))
     3933dnl      __(srwi imm1,arg_z,charcode_shift)
     3934dnl      __(bne- cr2,local_label(set_bad))
     3935dnl      __(stbx imm1,arg_x,imm0)
     3936dnl      __(bx lr)
     3937dnl local_label(misc_set_s8):
     3938dnl      __(extract_lisptag(imm2,arg_z))
     3939dnl          __(srwi imm0,arg_y,2)
     3940dnl      __(unbox_fixnum(imm1,arg_z))
     3941dnl          __(la imm0,misc_data_offset(imm0))
     3942dnl          __(cmpwi cr5,imm2,tag_fixnum)
     3943dnl      __(extsb imm2,imm1)
     3944dnl      __(cmpw cr0,imm2,imm1)
     3945dnl      __(bne- cr5,local_label(set_bad))
     3946dnl      __(bne- cr0,local_label(set_bad))
     3947dnl      __(stbx imm1,arg_x,imm0)
     3948dnl      __(bx lr)
     3949dnl local_label(misc_set_u16):         
     3950dnl      __(srwi imm0,arg_y,1)
     3951dnl      __(extract_unsigned_byte_bits_(imm1,arg_z,16))
     3952dnl      __(unbox_fixnum(imm1,arg_z))
     3953dnl      __(la imm0,misc_data_offset(imm0))
     3954dnl      __(bne- cr0,local_label(set_bad))
     3955dnl      __(sthx imm1,arg_x,imm0)
     3956dnl      __(bx lr)
     3957dnl local_label(misc_set_s16):
     3958dnl          __(extract_lisptag(imm2,arg_z))
     3959dnl          __(srwi imm0,arg_y,1)
     3960dnl      __(unbox_fixnum(imm1,arg_z))
     3961dnl          __(cmpwi cr5,imm2,tag_fixnum)
     3962dnl          __(la imm0,misc_data_offset(imm0))
     3963dnl      __(extsh imm2,imm1)
     3964dnl      __(cmpw cr0,imm2,imm1)
     3965dnl      __(bne- cr5,local_label(set_bad))
     3966dnl      __(bne- cr0,local_label(set_bad))
     3967dnl      __(sthx imm1,arg_x,imm0)
     3968dnl      __(bx lr)
     3969dnl local_label(misc_set_bit_vector):   
     3970dnl      __(cmplwi cr2,arg_z,fixnumone)   /* nothing not a (boxed) bit   */
     3971dnl      __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
     3972dnl      __(extlwi imm2,arg_z,1,31-fixnumshift)
     3973dnl      __(srw imm2,imm2,imm1)
     3974dnl      __(lis imm3,0x8000)
     3975dnl      __(rlwinm imm0,arg_y,32-5,5,31-fixnumshift)
     3976dnl      __(la imm0,misc_data_offset(imm0))
     3977dnl      __(srw imm3,imm3,imm1)
     3978dnl      __(bgt- cr2,local_label(set_bad))
     3979dnl      __(lwzx imm1,arg_x,imm0)
     3980dnl      __(andc imm1,imm1,imm3)
     3981dnl      __(or imm1,imm1,imm2)
     3982dnl      __(stwx imm1,arg_x,imm0)
     3983dnl      __(bx lr)
     3984dnl
     3985dnl local_label(misc_set_double_float_vector):
     3986dnl          __(extract_lisptag(imm2,arg_z))
     3987dnl      __(slwi imm0,arg_y,1)
     3988dnl          __(cmpwi cr7,imm2,tag_misc)
     3989dnl      __(la imm0,misc_dfloat_offset(imm0))
     3990dnl          __(bne- cr7,local_label(set_bad))
     3991dnl      __(extract_header(imm2,arg_z))
     3992dnl      __(cmpri(cr0,imm2,double_float_header))
     3993dnl      __(bne- cr0,local_label(set_bad))
     3994dnl      __(lwz imm1,double_float.value(arg_z))
     3995dnl      __(lwz imm2,double_float.value+4(arg_z))
     3996dnl      __(stwx imm1,arg_x,imm0)
     3997dnl      __(la imm0,4(imm0))
     3998dnl      __(stwx imm2,arg_x,imm0)
     3999dnl      __(bx lr)
     4000dnl local_label(misc_set_invalid): 
     4001dnl          __(mov temp0,#XSETBADVEC)       
     4002dnl          __(set_nargs(4))
     4003dnl          __(vpush1(temp0))
     4004dnl          __(b _SPksignalerr)               
     4005dnl         __endif
     4006dnl
     4007dnl /* misc_set (vector index newval).  Pretty damned similar to  */
     4008dnl /* misc_ref, as one might imagine.  */
     4009dnl
     4010dnl _spentry(misc_set)
     4011dnl     __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
     4012dnl     __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
     4013dnl     __(vector_length(imm0,arg_x,imm1))
     4014dnl     __(trlge(arg_y,imm0))
     4015dnl     __(extract_lowbyte(imm1,imm1))
     4016dnl         __(b local_label(misc_set_common))
     4017dnl         
     4018dnl /* "spread" the lexpr in arg_z.  */
     4019dnl /* ppc2-invoke-fn assumes that temp1 is preserved here.  */
     4020dnl _spentry(spread_lexprz)
     4021dnl     __(ldr imm0,[arg_z,#0])
     4022dnl     __(cmpri(cr3,imm0,3<<fixnumshift))
     4023dnl     __(cmpri(cr4,imm0,2<<fixnumshift))
     4024dnl     __(add imm1,arg_z,imm0)
     4025dnl     __(cmpri(cr0,imm0,0))
     4026dnl     __(add nargs,nargs,imm0)
     4027dnl     __(cmpri(cr1,nargs,0))
     4028dnl     __(cmpri(cr2,nargs,2<<fixnumshift))
     4029dnl     __(la imm1,node_size(imm1))
     4030dnl     __(bge cr3,9f)
     4031dnl     __(beq cr4,2f)
     4032dnl     __(bne cr0,1f)
     4033dnl     /* lexpr count was 0; vpop the arg regs that  */
     4034dnl     /* were vpushed by the caller  */
     4035dnl     __(beqlr cr1)
     4036dnl     __(vpop(arg_z))
     4037dnl     __(bltlr cr2)
     4038dnl     __(vpop(arg_y))
     4039dnl     __(beqlr cr2)
     4040dnl     __(vpop(arg_x))
     4041dnl     __(bx lr)
     4042dnl
     4043dnl     /* vpush args from the lexpr until we have only  */
     4044dnl     /* three left, then assign them to arg_x, arg_y,  */
     4045dnl     /* and arg_z.  */
     4046dnl 8:
     4047dnl     __(cmpri(cr3,imm0,4<<fixnumshift))
     4048dnl     __(subi imm0,imm0,fixnumone)
     4049dnl     __(ldru(arg_z,-node_size(imm1)))
     4050dnl     __(vpush1(arg_z))
     4051dnl 9:
     4052dnl     __(bne cr3,8b)
     4053dnl     __(ldr arg_x,[imm1,#-node_size*1])
     4054dnl     __(ldr arg_y,[imm1,#-node_size*2])
     4055dnl     __(ldr arg_z,[imm1,#-node_size*3])
     4056dnl     __(bx lr)
     4057dnl
     4058dnl     /* lexpr count is two: set arg_y, arg_z from the  */
     4059dnl     /* lexpr, maybe vpop arg_x  */
     4060dnl 2: 
     4061dnl     __(ldr arg_y,[imm1,#-node_size*1])
     4062dnl     __(ldr arg_z,[imm1,#-node_size*2])
     4063dnl     __(beqlr cr2)           /* return if (new) nargs = 2  */
     4064dnl     __(vpop(arg_x))
     4065dnl     __(bx lr)
     4066dnl
     4067dnl     /* lexpr count is one: set arg_z from the lexpr,  */
     4068dnl     /* maybe vpop arg_y, arg_x  */
     4069dnl 1: 
     4070dnl     __(ldr arg_z,[imm1,#-node_size])
     4071dnl     __(bltlr cr2)           /* return if (new) nargs < 2  */
     4072dnl     __(vpop(arg_y))
     4073dnl     __(beqlr cr2)           /* return if (new) nargs = 2  */
     4074dnl     __(vpop(arg_x))
     4075dnl     __(bx lr)
     4076dnl         
     4077dnl             
     4078dnl _spentry(reset)
     4079dnl     .globl _SPthrow
     4080dnl     __(nop)
     4081dnl     __(ref_nrs_value(temp0,toplcatch))
     4082dnl     __(mov temp1,#XSTKOVER)
     4083dnl     __(vpush1(temp0))
     4084dnl     __(vpush1(temp1))
     4085dnl     __(set_nargs(1))
     4086dnl     __(b _SPthrow)
     4087dnl
     4088dnl     
     4089dnl /* "slide" nargs worth of values up the vstack.  IMM0 contains  */
     4090dnl /* the difference between the current VSP and the target.  */
     4091dnl _spentry(mvslide)
     4092dnl     __(cmpri(cr0,nargs,0))
     4093dnl     __(mov imm3,nargs)
     4094dnl     __(add imm2,vsp,nargs)
     4095dnl     __(add imm2,imm2,imm0)
     4096dnl     __(add imm0,vsp,nargs)
     4097dnl     __(beq 2f)
     4098dnl 1:
     4099dnl     __(cmpri(cr0,imm3,1<<fixnumshift))
     4100dnl     __(subi imm3,imm3,1<<fixnumshift)
     4101dnl     __(ldru(temp0,-node_size(imm0)))
     4102dnl     __(stru(temp0,-node_size(imm2)))
     4103dnl     __(bne cr0,1b)
     4104dnl 2:
     4105dnl     __(mov vsp,imm2)
     4106dnl     __(bx lr)
     4107dnl
     4108dnl /* Build a new TSP area to hold nargs worth of multiple-values.  */
     4109dnl /* Pop the multiple values off of the vstack.  */
     4110dnl /* The new TSP frame will look like this:  */
     4111dnl /*  */
     4112dnl /*+--------+-------+-------+---------+--------+--------+--------+======+----------+ */
     4113dnl /*| ptr to | zero  | nargs | ptr to  | valn-1 | valn-2 | val-0  | ???? | prev TSP |  */
     4114dnl /*|  prev  |       |       |  prev   |        |        |        | fill |          |  */
     4115dnl /*| TSP    |       |       | segment |        |        |        |      |          | */
     4116dnl /*+--------+-------+-------+---------+--------+--------+--------+------+----------+  */
     4117dnl /*  */
     4118dnl /* e.g., the first multiple value goes in the last cell in the frame, the  */
     4119dnl /* count of values goes in the first word, and the word after the value count  */
     4120dnl /* is 0 if the number of values is even (for alignment).  */
     4121dnl /* Subsequent calls to .SPadd_values preserve this alignment.  */
     4122dnl /* .SPrecover_values is therefore pretty simple.  */
     4123dnl
     4124dnl _spentry(save_values)
     4125dnl     __(mov imm1,tsp)
     4126dnl
     4127dnl         /* common exit: nargs = values in this set, imm1 = ptr to tsp before  */
     4128dnl         /* call to save_values  */
     4129dnl local_label(save_values_to_tsp):
     4130dnl     __(mov imm2,tsp)
     4131dnl     __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* count, link  */
     4132dnl     __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
     4133dnl     __(str(imm1,tsp_frame.backlink(tsp))) /* keep one tsp "frame" as far as rest of lisp is concerned  */
     4134dnl     __(str(nargs,tsp_frame.data_offset(tsp)))
     4135dnl     __(str(imm2,tsp_frame.data_offset+node_size(tsp))) /* previous tsp  */
     4136dnl     __(la imm3,tsp_frame.data_offset+node_size*2(tsp))
     4137dnl     __(add imm3,imm3,nargs)
     4138dnl     __(add imm0,vsp,nargs)
     4139dnl     __(cmpr(cr0,imm0,vsp))
     4140dnl     __(b 2f)
     4141dnl 1:
     4142dnl     __(ldru(arg_z,-node_size(imm0)))
     4143dnl     __(cmpr(cr0,imm0,vsp))
     4144dnl     __(stru(arg_z,-node_size(imm3)))
     4145dnl 2:
     4146dnl     __(bne cr0,1b)
     4147dnl     __(add vsp,vsp,nargs) /*  discard values  */
     4148dnl     __(bx lr)
     4149dnl     
     4150dnl
     4151dnl /* Add the multiple values that are on top of the vstack to the set  */
     4152dnl /* saved in the top tsp frame, popping them off of the vstack in the  */
     4153dnl /* process.  It is an error (a bad one) if the TSP contains something  */
     4154dnl /* other than a previously saved set of multiple-values.  */
     4155dnl /* Since adding to the TSP may cause a new TSP segment to be allocated,  */
     4156dnl /* each add_values call adds another linked element to the list of  */
     4157dnl /* values. This makes recover_values harder.  */
     4158dnl
     4159dnl _spentry(add_values)
     4160dnl     __(cmpri(cr0,nargs,0))
     4161dnl     __(ldr imm1,[tsp,#0])
     4162dnl     __(bne cr0,local_label(save_values_to_tsp))
     4163dnl     __(bx lr)
     4164dnl         
     4165dnl /* On entry, R11->callback-index  */
     4166dnl /* Restore lisp context, then funcall #'%pascal-functions% with  */
     4167dnl /* two args: callback-index, args-ptr (a macptr pointing to the args on the stack)  */
     4168dnl _spentry(poweropen_callback)
     4169dnl         __ifdef(`rTOC')
     4170dnl          __(mov r11,rTOC)
     4171dnl         __endif
     4172dnl     /* Save C argument registers  */
     4173dnl     __(str(r3,c_frame.param0(sp)))
     4174dnl     __(str(r4,c_frame.param1(sp)))
     4175dnl     __(str(r5,c_frame.param2(sp)))
     4176dnl     __(str(r6,c_frame.param3(sp)))
     4177dnl     __(str(r7,c_frame.param4(sp)))
     4178dnl     __(str(r8,c_frame.param5(sp)))
     4179dnl     __(str(r9,c_frame.param6(sp)))
     4180dnl     __(str(r10,c_frame.param7(sp)))
     4181dnl     __(mflr imm3)
     4182dnl     __(str(imm3,c_frame.savelr(sp)))
     4183dnl     __(mfcr imm0)
     4184dnl     __(str(imm0,c_frame.crsave(sp)))
     4185dnl
     4186dnl     /* Save the non-volatile registers on the sp stack  */
     4187dnl     /* This is a non-standard stack frame, but noone will ever see it,  */
     4188dnl         /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
     4189dnl     __(stru(sp,-(stack_align(c_reg_save.size))(sp)))
     4190dnl         __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
     4191dnl         __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
     4192dnl         __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
     4193dnl         __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
     4194dnl         __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
     4195dnl         __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
     4196dnl         __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
     4197dnl         __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
     4198dnl         __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
     4199dnl         __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
     4200dnl         __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
     4201dnl         __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
     4202dnl         __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
     4203dnl         __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
     4204dnl         __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
     4205dnl         __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
     4206dnl         __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
     4207dnl         __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
     4208dnl         __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
     4209dnl         __(stfd f1,c_reg_save.save_fprs+(0*8)(sp))
     4210dnl         __(stfd f2,c_reg_save.save_fprs+(1*8)(sp))
     4211dnl         __(stfd f3,c_reg_save.save_fprs+(2*8)(sp))
     4212dnl         __(stfd f4,c_reg_save.save_fprs+(3*8)(sp))
     4213dnl         __(stfd f5,c_reg_save.save_fprs+(4*8)(sp))
     4214dnl         __(stfd f6,c_reg_save.save_fprs+(5*8)(sp))
     4215dnl         __(stfd f7,c_reg_save.save_fprs+(6*8)(sp))
     4216dnl         __(stfd f8,c_reg_save.save_fprs+(7*8)(sp))
     4217dnl         __(stfd f9,c_reg_save.save_fprs+(8*8)(sp))
     4218dnl         __(stfd f10,c_reg_save.save_fprs+(9*8)(sp))
     4219dnl         __(stfd f11,c_reg_save.save_fprs+(10*8)(sp))
     4220dnl         __(stfd f12,c_reg_save.save_fprs+(11*8)(sp))
     4221dnl         __(stfd f13,c_reg_save.save_fprs+(12*8)(sp))
     4222dnl     __(check_stack_alignment(r0))
     4223dnl     __(mffs f0)
     4224dnl     __(stfd f0,c_reg_save.save_fp_zero(sp))
     4225dnl     __(lwz r31,c_reg_save.save_fp_zero+4(sp))       /* recover FPSCR image  */
     4226dnl     __(stw r31,c_reg_save.save_fpscr(sp))
     4227dnl     __(mov r30,#0x43300000)
     4228dnl     __(mov r31,#0x80000000)
     4229dnl     __(stw r30,c_reg_save.save_fp_zero(sp))
     4230dnl     __(stw r31,c_reg_save.save_fp_zero+4(sp))
     4231dnl     __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
     4232dnl     __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
     4233dnl     __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
     4234dnl     __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
     4235dnl
     4236dnl /* Restore rest of Lisp context.  */
     4237dnl /* Could spread out the memory references here to gain a little speed  */
     4238dnl
     4239dnl     __(mov loc_pc,#0)
     4240dnl     __(mov fn,#0)                     /* subprim, not a lisp function  */
     4241dnl     __(mov temp3,#0)
     4242dnl     __(mov temp2,#0)
     4243dnl     __(mov temp1,#0)
     4244dnl     __(mov temp0,#0)
     4245dnl     __(mov arg_x,#0)
     4246dnl     __(box_fixnum(arg_y,r11))       /* callback-index  */
     4247dnl         __(la arg_z,c_reg_save.save_fprs(sp))
     4248dnl         __(str(arg_z,stack_align(c_reg_save.size)+c_frame.unused(sp)))
     4249dnl     __(la arg_z,stack_align(c_reg_save.size)+c_frame.param0(sp))    /* parameters (tagged as a fixnum)  */
     4250dnl
     4251dnl     /* Recover lisp thread context. Have to call C code to do so.  */
     4252dnl     __(ref_global(r12,get_tcr))
     4253dnl         __ifdef(`rTOC')
     4254dnl          __(ld rTOC,8(r12))
     4255dnl          __(ld r12,0(r12))
     4256dnl         __endif
     4257dnl     __(mtctr r12)
     4258dnl         __(mov r3,#1)
     4259dnl     __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
     4260dnl     __(bctrl)
     4261dnl     __(la rcontext,TCR_BIAS(r3))
     4262dnl     __(la sp,(stack_align(c_frame.minsiz))(sp))
     4263dnl
     4264dnl     __(ldr vsp,[rcontext,#tcr.save_vsp])
     4265dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])           
     4266dnl     __(mov rzero,#0)
     4267dnl     __(mov imm0,#TCR_STATE_LISP)
     4268dnl     __(mtxer rzero) /* lisp wants the overflow bit being clear  */
     4269dnl         __(mtctr rzero)
     4270dnl     __(mov save0,#0)
     4271dnl     __(mov save1,#0)
     4272dnl     __(mov save2,#0)
     4273dnl     __(mov save3,#0)
     4274dnl     __(mov save4,#0)
     4275dnl     __(mov save5,#0)
     4276dnl     __(mov save6,#0)
     4277dnl     __(mov save7,#0)
     4278dnl     __(lfd f0,tcr.lisp_fpscr(rcontext))
     4279dnl     __(mtfsf 0xff,f0)
     4280dnl     __(mov allocbase,#0)
     4281dnl     __(mov allocptr,#0)     
     4282dnl     __(str(imm0,tcr.valence(rcontext)))
     4283dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     4284dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     4285dnl     
     4286dnl         __(restore_saveregs(vsp))
     4287dnl
     4288dnl     /* load nargs and callback to the lisp  */
     4289dnl     __(set_nargs(2))
     4290dnl     __(ldr imm2,[rcontext,#tcr.cs_area])
     4291dnl     __(ldr imm4,[imm2,#area.active])
     4292dnl     __(stru(imm4,-lisp_frame.size(sp)))
     4293dnl     __(str(imm3,lisp_frame.savelr(sp)))
     4294dnl     __(mov fname,#nrs.callbacks)    /* %pascal-functions%  */
     4295dnl     __(call_fname)
     4296dnl     __(ldr imm2,[sp,#lisp_frame.backlink])
     4297dnl     __(ldr imm3,[rcontext,#tcr.cs_area])
     4298dnl     __(str(imm2,area.active(imm3)))
     4299dnl     __(discard_lisp_frame())
     4300dnl     /* save_vsp will be restored from ff_call's stack frame, but  */
     4301dnl     /* I included it here for consistency.  */
     4302dnl     /* save_tsp is set below after we exit Lisp context.  */
     4303dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     4304dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     4305dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     4306dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     4307dnl     /* Exit lisp context  */
     4308dnl     __(mov imm1,#TCR_STATE_FOREIGN)
     4309dnl     __(str(imm1,tcr.valence(rcontext)))
     4310dnl     /* Restore the non-volatile registers & fpscr  */
     4311dnl     __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
     4312dnl     __(lwz r31,c_reg_save.save_fpscr(sp))
     4313dnl     __(stw r31,c_reg_save.save_fp_zero+4(sp))
     4314dnl     __(lfd f0,c_reg_save.save_fp_zero(sp))
     4315dnl     __(mtfsf 0xff,f0)
     4316dnl     __(ldr r13,c_reg_save.save_gprs+(0*node_size)(sp)))
     4317dnl     __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
     4318dnl     __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
     4319dnl     __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
     4320dnl     __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
     4321dnl     __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
     4322dnl     __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
     4323dnl     __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
     4324dnl     __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
     4325dnl     __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
     4326dnl     __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
     4327dnl     __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
     4328dnl     __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
     4329dnl     __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
     4330dnl     __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
     4331dnl     __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
     4332dnl     __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
     4333dnl     __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
     4334dnl     __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
     4335dnl         __(lfd f1,c_reg_save.save_fprs+(0*8)(sp))
     4336dnl         __(lfd f2,c_reg_save.save_fprs+(1*8)(sp))
     4337dnl         __(lfd f3,c_reg_save.save_fprs+(2*8)(sp))
     4338dnl         __(lfd f4,c_reg_save.save_fprs+(3*8)(sp))
     4339dnl         __(lfd f5,c_reg_save.save_fprs+(4*8)(sp))
     4340dnl         __(lfd f6,c_reg_save.save_fprs+(5*8)(sp))
     4341dnl         __(lfd f7,c_reg_save.save_fprs+(6*8)(sp))
     4342dnl         __(lfd f8,c_reg_save.save_fprs+(7*8)(sp))
     4343dnl         __(lfd f9,c_reg_save.save_fprs+(8*8)(sp))
     4344dnl         __(lfd f10,c_reg_save.save_fprs+(9*8)(sp))
     4345dnl         __(lfd f11,c_reg_save.save_fprs+(10*8)(sp))
     4346dnl         __(lfd f12,c_reg_save.save_fprs+(11*8)(sp))
     4347dnl         __(lfd f13,c_reg_save.save_fprs+(12*8)(sp))
     4348dnl     __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
     4349dnl     __(ldr(sp,0(sp)))
     4350dnl     __(ldr r3,[sp,#c_frame.param0])
     4351dnl     __(ldr r4,[sp,#c_frame.param1])
     4352dnl     __(ldr r5,[sp,#c_frame.param2])
     4353dnl     __(ldr r6,[sp,#c_frame.param3])
     4354dnl     __(ldr r7,[sp,#c_frame.param4])
     4355dnl     __(ldr r8,[sp,#c_frame.param5])
     4356dnl     __(ldr r9,[sp,#c_frame.param6])
     4357dnl     __(ldr r10,[sp,#c_frame.param7])
     4358dnl     __(ldr r11,[sp,#c_frame.savelr])
     4359dnl     __(mtlr r11)
     4360dnl     __(ldr r11,[sp,#c_frame.crsave])
     4361dnl     __(mtcr r11)
     4362dnl     __(bx lr)
     4363dnl         
     4364dnl /* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
     4365dnl /* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
     4366dnl /* Calls out to %init-misc, which does the rest of the work.  */
     4367dnl
     4368dnl _spentry(misc_alloc_init)
     4369dnl     __(mflr loc_pc)
     4370dnl     __(build_lisp_frame(fn,loc_pc,vsp))
     4371dnl     __(mov fn,#0)
     4372dnl     __(mov temp0,arg_z)             /* initval  */
     4373dnl     __(mov arg_z,arg_y)             /* subtag  */
     4374dnl     __(mov arg_y,arg_x)             /* element-count  */
     4375dnl     __(bl _SPmisc_alloc)
     4376dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4377dnl     __(mtlr loc_pc)
     4378dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     4379dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     4380dnl     __(discard_lisp_frame())
     4381dnl     __(mov fname,#nrs.init_misc)
     4382dnl     __(set_nargs(2))
     4383dnl     __(mov arg_y,temp0)
     4384dnl     __(jump_fname())
     4385dnl
     4386dnl /* As in stack_misc_alloc above, only with a non-default initial-value.  */
     4387dnl
     4388dnl _spentry(stack_misc_alloc_init)
     4389dnl     __(mflr loc_pc)
     4390dnl     __(build_lisp_frame(fn,loc_pc,vsp))
     4391dnl     __(mov fn,#0)
     4392dnl     __(mov temp0,arg_z) /* initval  */
     4393dnl     __(mov arg_z,arg_y) /* subtag  */
     4394dnl     __(mov arg_y,arg_x) /* element-count  */
     4395dnl     __(bl _SPstack_misc_alloc)
     4396dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4397dnl     __(mtlr loc_pc)
     4398dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     4399dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     4400dnl     __(discard_lisp_frame())
     4401dnl     __(mov fname,#nrs.init_misc)
     4402dnl     __(set_nargs(2))
     4403dnl     __(mov arg_y,temp0)
     4404dnl     __(jump_fname())
     4405dnl
     4406dnl     
     4407dnl _spentry(callbuiltin)
     4408dnl     __(ref_nrs_value(fname,builtin_functions))
     4409dnl     __(la imm0,misc_data_offset(imm0))
     4410dnl     __(ldrx(fname,fname,imm0))
     4411dnl     __(jump_fname())
     4412dnl
     4413dnl /* the value of the nilreg-relative symbol %builtin-functions% should be  */
     4414dnl /* a vector of symbols.  Call the symbol indexed by imm0 (boxed) and  */
     4415dnl /* return a single value.  */
     4416dnl
     4417dnl _spentry(callbuiltin0)
     4418dnl     __(set_nargs(0))
     4419dnl     __(ref_nrs_value(fname,builtin_functions))
     4420dnl     __(la imm0,misc_data_offset(imm0))
     4421dnl     __(ldrx(fname,fname,imm0))
     4422dnl     __(jump_fname())
     4423dnl
     4424dnl _spentry(callbuiltin1)
     4425dnl     __(ref_nrs_value(fname,builtin_functions))
     4426dnl     __(set_nargs(1))
     4427dnl     __(la imm0,misc_data_offset(imm0))
     4428dnl     __(ldrx(fname,fname,imm0))
     4429dnl     __(jump_fname())
     4430dnl
     4431dnl _spentry(callbuiltin2)
     4432dnl     __(set_nargs(2))
     4433dnl     __(ref_nrs_value(fname,builtin_functions))
     4434dnl     __(la imm0,misc_data_offset(imm0))
     4435dnl     __(ldrx(fname,fname,imm0))
     4436dnl     __(jump_fname())
     4437dnl
     4438dnl
     4439dnl _spentry(callbuiltin3)
     4440dnl     __(set_nargs(3))
     4441dnl     __(ref_nrs_value(fname,builtin_functions))
     4442dnl     __(la imm0,misc_data_offset(imm0))
     4443dnl     __(ldrx(fname,fname,imm0))
     4444dnl     __(jump_fname())
     4445dnl     
     4446dnl
     4447dnl _spentry(popj)
     4448dnl     .globl C(popj)
     4449dnl C(popj):
     4450dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4451dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     4452dnl     __(mtlr loc_pc)
     4453dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     4454dnl     __(discard_lisp_frame())
     4455dnl     __(bx lr)
     4456dnl
     4457dnl _spentry(restorefullcontext)
     4458dnl     __(mflr loc_pc)
     4459dnl     __(mtctr loc_pc)
     4460dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4461dnl     __(mtlr loc_pc)
     4462dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     4463dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     4464dnl     __(discard_lisp_frame())
     4465dnl     __(bctr)
     4466dnl
     4467dnl _spentry(savecontextvsp)
     4468dnl     __(ldr imm0,[rcontext,#tcr.cs_limit])
     4469dnl     __(build_lisp_frame(fn,loc_pc,vsp))
     4470dnl     __(mov fn,nfn)
     4471dnl     __(trllt(sp,imm0))
     4472dnl     __(bx lr)
     4473dnl
     4474dnl _spentry(savecontext0)
     4475dnl     __(add imm0,vsp,imm0)
     4476dnl     __(build_lisp_frame(fn,loc_pc,imm0))
     4477dnl     __(ldr imm0,[rcontext,#tcr.cs_limit])
     4478dnl     __(mov fn,nfn)
     4479dnl     __(trllt(sp,imm0))
     4480dnl     __(bx lr)
     4481dnl
     4482dnl
     4483dnl /* Like .SPrestorefullcontext, only the saved return address  */
     4484dnl /* winds up in loc-pc instead of getting thrashed around ...  */
     4485dnl _spentry(restorecontext)
     4486dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4487dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     4488dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     4489dnl     __(discard_lisp_frame())
     4490dnl     __(bx lr)
     4491dnl
     4492dnl         
     4493dnl /* Nargs is valid; all arg regs, lexpr-count pushed by caller.  */
     4494dnl /* imm0 = vsp to restore.  */
     4495dnl /* Return all values returned by caller to its caller, hiding  */
     4496dnl /* the variable-length arglist.  */
     4497dnl /* If we can detect that the caller's caller didn't expect  */
     4498dnl /* multiple values, then things are even simpler.  */
     4499dnl _spentry(lexpr_entry)
     4500dnl     __(ref_global(imm1,ret1val_addr))
     4501dnl     __(cmpr(cr0,imm1,loc_pc))
     4502dnl     __(build_lisp_frame(fn,loc_pc,imm0))
     4503dnl     __(bne cr0,1f)
     4504dnl     __(ref_global(imm0,lexpr_return))
     4505dnl     __(build_lisp_frame(rzero,imm0,vsp))
     4506dnl     __(mov loc_pc,imm1)
     4507dnl     __(ldr imm0,[rcontext,#tcr.cs_limit])
     4508dnl     __(trllt(sp,imm0))
     4509dnl     __(mov fn,#0)
     4510dnl     __(bx lr)
     4511dnl
     4512dnl         /* The single-value case just needs to return to something that'll pop  */
     4513dnl         /* the variable-length frame off of the vstack.  */
     4514dnl 1:
     4515dnl     __(ref_global(loc_pc,lexpr_return1v))
     4516dnl     __(ldr imm0,[rcontext,#tcr.cs_limit])
     4517dnl     __(trllt(sp,imm0))
     4518dnl     __(mov fn,#0)
     4519dnl     __(bx lr)
     4520dnl
     4521dnl /* */
     4522dnl /* Do a system call in Darwin.  The stack is set up much as it would be */
     4523dnl /* for a PowerOpen ABI ff-call:     register parameters are in the stack */
     4524dnl /* frame, and there are 4 extra words at the bottom of the frame that */
     4525dnl /* we can carve a lisp frame out of. */
     4526dnl /*  */
     4527dnl /* System call return conventions are a little funky in Darwin: if "@sc" */
     4528dnl /* is the address of the "sc" instruction, errors return to @sc+4 and */
     4529dnl /* non-error cases return to @sc+8.  Error values are returned as */
     4530dnl /* positive values in r3; this is true even if the system call returns */
     4531dnl /* a doubleword (64-bit) result.  Since r3 would ordinarily contain */
     4532dnl /* the high half of a doubleword result, this has to be special-cased. */
     4533dnl /*  */
     4534dnl /* The caller should set the c_frame.crsave field of the stack frame */
     4535dnl /* to 0 if the result is to be interpreted as anything but a doubleword */
     4536dnl /* and to non-zero otherwise.  (This only matters on an error return.) */
     4537dnl
     4538dnl         
     4539dnl _spentry(poweropen_syscall)
     4540dnl     __(mflr loc_pc)
     4541dnl     __(vpush_saveregs())
     4542dnl     __(ldr imm1,[sp,#0])
     4543dnl     __(la imm2,-lisp_frame.size(imm1))
     4544dnl         __(zero_doublewords imm2,0,lisp_frame.size)
     4545dnl     __(str(imm1,lisp_frame.backlink(imm2)))
     4546dnl     __(str(imm2,c_frame.backlink(sp)))
     4547dnl     __(str(fn,lisp_frame.savefn(imm2)))
     4548dnl     __(str(loc_pc,lisp_frame.savelr(imm2)))
     4549dnl     __(str(vsp,lisp_frame.savevsp(imm2)))
     4550dnl     __(ldr imm3,[rcontext,#tcr.cs_area])
     4551dnl     __(str(imm2,area.active(imm3)))
     4552dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     4553dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     4554dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     4555dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     4556dnl     __(str(rzero,tcr.ffi_exception(rcontext)))
     4557dnl     __(mov save0,rcontext)
     4558dnl     __(mov r3,#TCR_STATE_FOREIGN)
     4559dnl     __(str(r3,tcr.valence(rcontext)))
     4560dnl     __(mov rcontext,#0)
     4561dnl     __(ldr r3,[sp,#c_frame.param0])
     4562dnl     __(ldr r4,[sp,#c_frame.param1])
     4563dnl     __(ldr r5,[sp,#c_frame.param2])
     4564dnl     __(ldr r6,[sp,#c_frame.param3])
     4565dnl     __(ldr r7,[sp,#c_frame.param4])
     4566dnl     __(ldr r8,[sp,#c_frame.param5])
     4567dnl     __(ldr r9,[sp,#c_frame.param6])
     4568dnl     __(ldr r10,[sp,#c_frame.param7])
     4569dnl     __(unbox_fixnum(r0,arg_z))
     4570dnl     __(sc)
     4571dnl         __ifdef(`LINUX')
     4572dnl          __(bns+ 9f)
     4573dnl         __else
     4574dnl      __(b 1f)
     4575dnl      __(b 9f)
     4576dnl         __endif
     4577dnl 1:
     4578dnl         __ifdef(`PPC64')
     4579dnl          __(neg r3,r3)
     4580dnl         __else
     4581dnl      __(ldr imm2,[sp,#c_frame.crsave])
     4582dnl      __(cmpri(cr0,imm2,0))
     4583dnl      __(bne cr0,2f)
     4584dnl      /* 32-bit result  */
     4585dnl      __(neg r3,r3)
     4586dnl      __(b 9f)
     4587dnl 2:
     4588dnl      /* 64-bit result  */
     4589dnl      __(neg r4,r3)
     4590dnl      __(mov r3,#-1)
     4591dnl         __endif
     4592dnl 9:
     4593dnl     __(mov imm2,save0)      /* recover context  */
     4594dnl     __(ldr sp,[sp,#c_frame.backlink])
     4595dnl     __(mov imm4,#TCR_STATE_LISP)
     4596dnl     __(mov rzero,#0)
     4597dnl     __(mov loc_pc,#0)
     4598dnl     __(mov arg_x,#nil_value)
     4599dnl     __(mov arg_y,#nil_value)
     4600dnl     __(mov arg_z,#nil_value)
     4601dnl     __(mov temp0,#nil_value)
     4602dnl     __(mov temp1,#nil_value)
     4603dnl     __(mov temp2,#nil_value)
     4604dnl     __(mov temp3,#nil_value)
     4605dnl     __(mov fn,#nil_value)
     4606dnl     __(mov rcontext,imm2)
     4607dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     4608dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     4609dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])
     4610dnl         __(mov save0,#0)
     4611dnl         __(mov save1,#0)
     4612dnl         __(mov save2,#0)
     4613dnl         __(mov save3,#0)
     4614dnl         __(mov save4,#0)
     4615dnl         __(mov save5,#0)
     4616dnl         __(mov save6,#0)
     4617dnl         __(mov save7,#0)       
     4618dnl     __(str(imm4,tcr.valence(rcontext)))
     4619dnl     __(vpop_saveregs)
     4620dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     4621dnl     __(mtlr loc_pc)
     4622dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     4623dnl     __(discard_lisp_frame)
     4624dnl         __(mtxer rzero)
     4625dnl     __(check_pending_interrupt(`cr1'))
     4626dnl     __(bx lr)
     4627dnl         
     4628dnl         
     4629dnl
     4630dnl _spentry(builtin_div)
     4631dnl     __(jump_builtin(_builtin_div,2))
     4632dnl
     4633dnl
     4634dnl
     4635dnl _spentry(builtin_eql)
     4636dnl         __(cmpr(cr1,arg_y,arg_z))
     4637dnl         __(extract_fulltag(imm2,arg_y))
     4638dnl         __(extract_fulltag(imm3,arg_z))
     4639dnl         __(beq cr1,1f)
     4640dnl         __(cmpri(cr1,imm2,fulltag_misc))
     4641dnl         __(cmpri(cr0,imm3,fulltag_misc))
     4642dnl         __(bne cr1,2f)
     4643dnl         __(extract_subtag(imm0,arg_y))
     4644dnl         __(bne cr0,2f)
     4645dnl         __(extract_subtag(imm1,arg_z))
     4646dnl         __(cmpr(cr0,imm0,imm1))
     4647dnl         __(bne cr0,2f)
     4648dnl     __(jump_builtin(_builtin_eql,2))
     4649dnl 1:  __(mov arg_z,#t_value)
     4650dnl     __(bx lr)
     4651dnl 2:  __(mov arg_z,#nil_value)
     4652dnl     __(bx lr)
     4653dnl         
     4654dnl _spentry(builtin_length)
     4655dnl         __(cmpri(cr1,arg_z,nil_value))
     4656dnl     __(extract_typecode(imm0,arg_z))
     4657dnl     __(cmpri(cr0,imm0,min_vector_subtag))
     4658dnl         __(beq cr1,1f)
     4659dnl         __ifdef(`PPC64')
     4660dnl          __(cmpdi cr2,imm0,fulltag_cons)
     4661dnl         __else
     4662dnl      __(cmpwi cr2,imm0,tag_list)
     4663dnl         __endif
     4664dnl     __(beq- cr0,2f)
     4665dnl     __(blt- cr0,3f)
     4666dnl     /* (simple-array * (*))  */
     4667dnl     __(vector_length(arg_z,arg_z,imm0))
     4668dnl     __(bx lr)
     4669dnl 1:      __(mov arg_z,#0)
     4670dnl         __(bx lr)
     4671dnl 2:
     4672dnl     __(ldr arg_z,[arg_z,#vectorH.logsize])
     4673dnl     __(bx lr)       
     4674dnl 3:  __(bne cr2,8f)
     4675dnl     __(mov temp2,#-1<<fixnum_shift)
     4676dnl     __(mov temp0,arg_z)     /* fast pointer  */
     4677dnl     __(mov temp1,arg_z)     /* slow pointer  */
     4678dnl         __ifdef(`PPC64')
     4679dnl 4:       __(extract_fulltag(imm0,temp0))
     4680dnl          __(cmpdi cr7,temp0,nil_value)
     4681dnl          __(cmpdi cr1,imm0,fulltag_cons)
     4682dnl          __(addi temp2,temp2,fixnum_one)
     4683dnl          __(beq cr7,9f)
     4684dnl          __(andi. imm0,temp2,1<<fixnum_shift)
     4685dnl          __(bne cr1,8f)
     4686dnl          __(extract_fulltag(imm1,temp1))
     4687dnl          __(_cdr(temp0,temp0))
     4688dnl          __(cmpdi cr1,imm1,fulltag_cons)
     4689dnl      __(beq cr0,4b)
     4690dnl      __(bne cr1,8f)
     4691dnl      __(_cdr(temp1,temp1))
     4692dnl      __(cmpd cr0,temp0,temp1)
     4693dnl      __(bne cr0,4b)
     4694dnl         __else
     4695dnl 4:   __(extract_lisptag(imm0,temp0))
     4696dnl      __(cmpri(cr7,temp0,nil_value))
     4697dnl      __(cmpri(cr1,imm0,tag_list))
     4698dnl      __(addi temp2,temp2,fixnum_one)
     4699dnl      __(beq cr7,9f)
     4700dnl      __(andi. imm0,temp2,1<<fixnum_shift)
     4701dnl      __(bne cr1,8f)
     4702dnl      __(extract_lisptag(imm1,temp1))       
     4703dnl      __(_cdr(temp0,temp0))
     4704dnl      __(cmpri(cr1,imm1,tag_list))
     4705dnl      __(beq cr0,4b)
     4706dnl      __(bne cr1,8f)
     4707dnl      __(_cdr(temp1,temp1))
     4708dnl      __(cmpr(cr0,temp0,temp1))
     4709dnl      __(bne cr0,4b)
     4710dnl         __endif
     4711dnl 8: 
     4712dnl     __(jump_builtin(_builtin_length,1))
     4713dnl 9: 
     4714dnl     __(mov arg_z,temp2)
     4715dnl     __(bx lr)
     4716dnl         
     4717dnl _spentry(builtin_seqtype)
     4718dnl         __ifdef(`PPC64')
     4719dnl          __(cmpdi cr2,arg_z,nil_value)
     4720dnl          __(extract_typecode(imm0,arg_z))
     4721dnl          __(beq cr2,1f)
     4722dnl      __(cmpri(cr0,imm0,fulltag_cons))
     4723dnl         __else
     4724dnl      __(extract_typecode(imm0,arg_z))
     4725dnl      __(cmpri(cr0,imm0,tag_list))
     4726dnl         __endif
     4727dnl     __(cmpri(cr1,imm0,min_vector_subtag))
     4728dnl     __(beq cr0,1f)
     4729dnl     __(blt- cr1,2f)
     4730dnl     __(mov arg_z,#nil_value)
     4731dnl     __(bx lr)
     4732dnl 1:  __(mov arg_z,#t_value)
     4733dnl     __(bx lr)
     4734dnl 2:
     4735dnl     __(jump_builtin(_builtin_seqtype,1))
     4736dnl         
     4737dnl _spentry(builtin_assq)
     4738dnl     __(cmpri(arg_z,nil_value))
     4739dnl     __(beqlr)
     4740dnl 1:  __(trap_unless_list(arg_z,imm0))
     4741dnl     __(_car(arg_x,arg_z))
     4742dnl     __(_cdr(arg_z,arg_z))
     4743dnl     __(cmpri(cr2,arg_x,nil_value))
     4744dnl     __(cmpri(cr1,arg_z,nil_value))
     4745dnl     __(beq cr2,2f)
     4746dnl     __(trap_unless_list(arg_x,imm0))
     4747dnl     __(_car(temp0,arg_x))
     4748dnl     __(cmpr(temp0,arg_y))
     4749dnl     __(bne cr0,2f)
     4750dnl     __(mov arg_z,arg_x)
     4751dnl     __(bx lr)
     4752dnl 2:  __(bne cr1,1b)
     4753dnl     __(bx lr)
     4754dnl
     4755dnl _spentry(builtin_memq)
     4756dnl     __(cmpri(cr1,arg_z,nil_value))
     4757dnl     __(b 2f)
     4758dnl 1:  __(trap_unless_list(arg_z,imm0))
     4759dnl     __(_car(arg_x,arg_z))
     4760dnl     __(_cdr(temp0,arg_z))
     4761dnl     __(cmpr(arg_x,arg_y))
     4762dnl     __(cmpri(cr1,temp0,nil_value))
     4763dnl     __(beqlr)
     4764dnl     __(mov arg_z,temp0)
     4765dnl 2:  __(bne cr1,1b)
     4766dnl     __(bx lr)
     4767dnl
     4768dnl logbitp_max_bit = 30
     4769dnl         
     4770dnl _spentry(builtin_logbitp)
     4771dnl     /* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
     4772dnl         __(cmplri(cr2,arg_y,logbitp_max_bit<<fixnum_shift))
     4773dnl         __(extract_lisptag(imm0,arg_y))
     4774dnl         __(extract_lisptag(imm1,arg_z))
     4775dnl         __(cmpri(cr0,imm0,tag_fixnum))
     4776dnl         __(cmpri(cr1,imm1,tag_fixnum))
     4777dnl     __(unbox_fixnum(imm0,arg_y))
     4778dnl     __(subfic imm0,imm0,logbitp_max_bit)
     4779dnl         __ifdef(`PPC64')
     4780dnl          __(rldcl imm0,arg_z,imm0,63)
     4781dnl          __(mulli imm0,imm0,t_offset)
     4782dnl         __else
     4783dnl      __(rlwnm imm0,arg_z,imm0,31,31)
     4784dnl      __(rlwimi imm0,imm0,4,27,27)
     4785dnl         __endif
     4786dnl     __(bnl cr2,1f)
     4787dnl     __(bne cr0,1f)
     4788dnl         __(bne cr1,1f)
     4789dnl     __(addi arg_z,imm0,nil_value)
     4790dnl     __(bx lr)
     4791dnl 1:
     4792dnl     __(jump_builtin(_builtin_logbitp,2))
     4793dnl
     4794dnl _spentry(builtin_logior)
     4795dnl         __(orr imm0,arg_y,arg_z)
     4796dnl         __(test_fixnum(imm0))
     4797dnl         __(moveq arg_z,imm0)
     4798dnl         __(bxeq lr)
     4799dnl 1:
     4800dnl     __(jump_builtin(_builtin_logior,2))
     4801dnl
     4802dnl _spentry(builtin_logand)
     4803dnl         __(orr imm0,arg_y,arg_z)
     4804dnl         __(test_fixnum(imm0))
     4805dnl     __(andeq arg_z,arg_y,arg_z)
     4806dnl     __(bxeq lr)
     4807dnl     __(jump_builtin(_builtin_logand,2))
     4808dnl     
     4809dnl _spentry(builtin_ash)
     4810dnl         __ifdef(`PPC64')
     4811dnl      __(cmpdi cr1,arg_z,0)
     4812dnl          __(extract_lisptag(imm0,arg_y))
     4813dnl          __(extract_lisptag(imm1,arg_z))
     4814dnl          __(cmpdi cr0,imm0,tag_fixnum)
     4815dnl          __(cmpdi cr3,imm1,tag_fixnum)
     4816dnl      __(cmpdi cr2,arg_z,-(63<<3))   /* !! 3 =  fixnumshift  */
     4817dnl      __(bne- cr0,9f)
     4818dnl          __(bne- cr3,9f)
     4819dnl      __(bne cr1,0f)
     4820dnl      __(mov arg_z,arg_y)    /* (ash n 0) => n  */
     4821dnl      __(bx lr)
     4822dnl 0:         
     4823dnl      __(unbox_fixnum(imm1,arg_y))
     4824dnl      __(unbox_fixnum(imm0,arg_z))
     4825dnl      __(bgt cr1,2f)
     4826dnl      /* (ash n -count) => fixnum  */
     4827dnl      __(neg imm2,imm0)
     4828dnl      __(bgt cr2,1f)
     4829dnl      __(mov imm2,#63)
     4830dnl 1: 
     4831dnl      __(srad imm0,imm1,imm2)
     4832dnl      __(box_fixnum(arg_z,imm0))
     4833dnl      __(bx lr)
     4834dnl      /* Integer-length of arg_y/imm1 to imm2  */
     4835dnl 2:         
     4836dnl      __(cntlzd. imm2,imm1)
     4837dnl      __(bne 3f)             /* cr0`eq' set if negative  */
     4838dnl      __(not imm2,imm1)
     4839dnl      __(cntlzd imm2,imm2)
     4840dnl 3:
     4841dnl      __(subfic imm2,imm2,64)
     4842dnl      __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
     4843dnl      __(cmpdi cr1,imm2,63-fixnumshift)
     4844dnl      __(cmpdi cr2,imm0,64)
     4845dnl      __(sld imm2,imm1,imm0)
     4846dnl      __(bgt cr1,6f)
     4847dnl      __(box_fixnum(arg_z,imm2))
     4848dnl      __(bx lr)     
     4849dnl 6:
     4850dnl      __(bgt cr2,9f)
     4851dnl      __(bne cr2,7f)
     4852dnl      /* Shift left by 64 bits exactly  */
     4853dnl      __(mov imm0,imm1)
     4854dnl      __(mov imm1,#0)
     4855dnl      __(beq _SPmakes128)
     4856dnl      __(b _SPmakeu128)
     4857dnl 7:
     4858dnl      /* Shift left by fewer than 64 bits, result not a fixnum  */
     4859dnl      __(subfic imm0,imm0,64)
     4860dnl      __(beq 8f)
     4861dnl      __(srd imm0,imm1,imm0)
     4862dnl      __(mov imm1,imm2)
     4863dnl      __(b _SPmakeu128)
     4864dnl 8: 
     4865dnl      __(srad imm0,imm1,imm0)
     4866dnl      __(mov imm1,imm2)
     4867dnl      __(b _SPmakes128)
     4868dnl         __else
     4869dnl      __(cmpri(cr1,arg_z,0))
     4870dnl          __(extract_lisptag(imm0,arg_y))
     4871dnl          __(extract_lisptag(imm1,arg_z))
     4872dnl          __(cmpri(cr0,imm0,tag_fixnum))
     4873dnl          __(cmpri(cr3,imm1,tag_fixnum))
     4874dnl      __(cmpri(cr2,arg_z,-(29<<2)))  /* !! 2 =  fixnumshift  */
     4875dnl      __(bne- cr0,9f)
     4876dnl          __(bne- cr3,9f)
     4877dnl      __(bne cr1,0f)
     4878dnl      __(mov arg_z,arg_y)    /* (ash n 0) => n  */
     4879dnl      __(bx lr)
     4880dnl 0:         
     4881dnl      __(unbox_fixnum(imm1,arg_y))
     4882dnl      __(unbox_fixnum(imm0,arg_z))
     4883dnl      __(bgt cr1,2f)
     4884dnl      /* (ash n -count) => fixnum  */
     4885dnl      __(neg imm2,imm0)
     4886dnl      __(bgt cr2,1f)
     4887dnl      __(mov imm2,#31)
     4888dnl 1: 
     4889dnl      __(sraw imm0,imm1,imm2)
     4890dnl      __(box_fixnum(arg_z,imm0))
     4891dnl      __(bx lr)
     4892dnl      /* Integer-length of arg_y/imm1 to imm2  */
     4893dnl 2:         
     4894dnl      __(cntlzw. imm2,imm1)
     4895dnl      __(bne 3f)             /* cr0`eq' set if negative  */
     4896dnl      __(not imm2,imm1)
     4897dnl      __(cntlzw imm2,imm2)
     4898dnl 3:
     4899dnl      __(subfic imm2,imm2,32)
     4900dnl      __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
     4901dnl      __(cmpri(cr1,imm2,31-fixnumshift))
     4902dnl      __(cmpri(cr2,imm0,32))
     4903dnl      __(slw imm2,imm1,imm0)
     4904dnl      __(bgt cr1,6f)
     4905dnl      __(box_fixnum(arg_z,imm2))
     4906dnl      __(bx lr)     
     4907dnl 6:
     4908dnl      __(bgt cr2,9f)
     4909dnl      __(bne cr2,7f)
     4910dnl      /* Shift left by 32 bits exactly  */
     4911dnl      __(mov imm0,imm1)
     4912dnl      __(mov imm1,#0)
     4913dnl      __(beq _SPmakes64)
     4914dnl      __(b _SPmakeu64)
     4915dnl 7:
     4916dnl      /* Shift left by fewer than 32 bits, result not a fixnum  */
     4917dnl      __(subfic imm0,imm0,32)
     4918dnl      __(beq 8f)
     4919dnl      __(srw imm0,imm1,imm0)
     4920dnl      __(mov imm1,imm2)
     4921dnl      __(b _SPmakeu64)
     4922dnl 8: 
     4923dnl      __(sraw imm0,imm1,imm0)
     4924dnl      __(mov imm1,imm2)
     4925dnl      __(b _SPmakes64)
     4926dnl         __endif
     4927dnl 9:         
     4928dnl     __(jump_builtin(_builtin_ash,2))
     4929dnl
     4930dnl _spentry(builtin_negate)
     4931dnl         __(test_fixnum(arg_z))
     4932dnl         __(bne 1f)
     4933dnl         __(rsbs arg_z,arg_z,#0)
     4934dnl         __(bxvc lr)
     4935dnl     __(unbox_fixnum(imm1,arg_z))
     4936dnl         __ifdef(`PPC64')
     4937dnl      __(mov imm0,#two_digit_bignum_header)
     4938dnl          __(rotldi imm1,imm1,32)
     4939dnl      __(xoris imm1,imm1,0xe000)
     4940dnl      __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
     4941dnl      __(str(imm1,misc_data_offset(arg_z)))
     4942dnl         __else
     4943dnl      __(mov imm0,#one_digit_bignum_header)
     4944dnl      __(xoris imm1,imm1,0xc000)
     4945dnl      __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
     4946dnl      __(str(imm1,misc_data_offset(arg_z)))
     4947dnl         __endif
     4948dnl     __(bx lr)
     4949dnl 1:
     4950dnl     __(jump_builtin(_builtin_negate,1))
     4951dnl
     4952dnl _spentry(builtin_logxor)
     4953dnl         __(extract_lisptag(imm0,arg_y))
     4954dnl         __(extract_lisptag(imm1,arg_z))
     4955dnl         __(ands imm0,imm0,imm1)
     4956dnl     __(eoreq arg_z,arg_y,arg_z)
     4957dnl     __(bxeq lr)
     4958dnl     __(jump_builtin(_builtin_logxor,2))
     4959dnl
     4960dnl
     4961dnl
     4962dnl         
     4963dnl _spentry(builtin_aset1)
     4964dnl     __(extract_typecode(imm0,arg_x))
     4965dnl     __(cmpri(cr0,imm0,min_vector_subtag))
     4966dnl     __(box_fixnum(temp0,imm0))
     4967dnl     __(bgt cr0,1f)
     4968dnl     __(jump_builtin(_builtin_aset1,3))
     4969dnl 1:
     4970dnl     __(b _SPsubtag_misc_set)
     4971dnl
     4972dnl /* Enter the debugger  */
     4973dnl _spentry(breakpoint)
     4974dnl     __(mov r3,#0)
     4975dnl     __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter)  */
     4976dnl     __(bx lr)               /* if handler didn't  */
     4977dnl
     4978dnl /* */
     4979dnl /* We're entered with an eabi_c_frame on the C stack.  There's a */
     4980dnl /* lisp_frame reserved underneath it; we'll link it in in a minute. */
     4981dnl /* Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
     4982dnl /* then shrink the eabi_c_frame. */
     4983dnl /*  */
     4984dnl     
     4985dnl _spentry(eabi_ff_call)
     4986dnl     __(mflr loc_pc)
     4987dnl     __(str(sp,eabi_c_frame.savelr(sp)))
     4988dnl     __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
     4989dnl     __(mov save0,rcontext)  /* or address globals.  */
     4990dnl     __(extract_typecode(imm0,arg_z))
     4991dnl     __(cmpri(imm0,subtag_macptr))
     4992dnl     __(ldr save1,[sp,#0])   /* bottom of reserved lisp frame  */
     4993dnl     __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
     4994dnl         __(zero_doublewords save2,0,lisp_frame.size)
     4995dnl     __(str(save1,lisp_frame.backlink(save2)))
     4996dnl     __(str(save2,c_frame.backlink(sp)))
     4997dnl     __(str(fn,lisp_frame.savefn(save2)))
     4998dnl     __(str(loc_pc,lisp_frame.savelr(save2)))
     4999dnl     __(str(vsp,lisp_frame.savevsp(save2)))
     5000dnl     __(bne 1f)
     5001dnl     __(ldr arg_z,[arg_z,#macptr.address])
     5002dnl 1:
     5003dnl     __(ldr save3,[rcontext,#tcr.cs_area])
     5004dnl     __(str(save2,area.active(save3)))
     5005dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     5006dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     5007dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     5008dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     5009dnl     __(mtctr arg_z)
     5010dnl     __(str(rzero,tcr.ffi_exception(rcontext)))
     5011dnl     __(mffs f0)
     5012dnl     __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
     5013dnl     __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
     5014dnl     __(mov imm1,#TCR_STATE_FOREIGN)
     5015dnl     __(str(imm1,tcr.valence(rcontext)))
     5016dnl     __(ldr r2,[rcontext,#tcr.native_thread_info])
     5017dnl     __(ldr r13,[0,#lisp_globals.saveR13])
     5018dnl     __(ldr r3,[sp,#eabi_c_frame.param0])
     5019dnl     __(ldr r4,[sp,#eabi_c_frame.param1])
     5020dnl     __(ldr r5,[sp,#eabi_c_frame.param2])
     5021dnl     __(ldr r6,[sp,#eabi_c_frame.param3])
     5022dnl     __(ldr r7,[sp,#eabi_c_frame.param4])
     5023dnl     __(ldr r8,[sp,#eabi_c_frame.param5])
     5024dnl     __(ldr r9,[sp,#eabi_c_frame.param6])
     5025dnl     __(ldr r10,[sp,#eabi_c_frame.param7])
     5026dnl     __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
     5027dnl     __(str(rzero,eabi_c_frame.savelr(save1)))
     5028dnl     __(str(save2,eabi_c_frame.backlink(save1)))
     5029dnl     __(mov sp,save1)
     5030dnl     /* If we're calling a varargs C function, it'll want to */
     5031dnl     /* know whether or not we've passed any args in FP regs. */
     5032dnl     /* Better to say that we did (and force callee to save FP */
     5033dnl     /* arg regs on entry) than to say that we didn't and get */
     5034dnl     /* garbage results  */
     5035dnl     __(crset 6)
     5036dnl     __(bctrl)
     5037dnl     /* C should have preserved save0 (= rcontext) for us.  */
     5038dnl     __(ldr sp,[sp,#0])
     5039dnl     __(mov imm2,save0)
     5040dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     5041dnl     __(mov rzero,#0)
     5042dnl     __(mov loc_pc,rzero)
     5043dnl     __(mov arg_x,#nil_value)
     5044dnl     __(mov arg_y,#nil_value)
     5045dnl     __(mov arg_z,#nil_value)
     5046dnl     __(mov temp0,#nil_value)
     5047dnl     __(mov temp1,#nil_value)
     5048dnl     __(mov temp2,#nil_value)
     5049dnl     __(mov temp3,#nil_value)
     5050dnl     __(mov fn,#nil_value)
     5051dnl     __(mov rcontext,imm2)
     5052dnl     __(mov imm2,#TCR_STATE_LISP)
     5053dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])
     5054dnl         __(mov save0,#0)
     5055dnl         __(mov save1,#0)
     5056dnl         __(mov save2,#0)
     5057dnl         __(mov save3,#0)
     5058dnl         __(mov save4,#0)
     5059dnl         __(mov save5,#0)
     5060dnl         __(mov save6,#0)
     5061dnl         __(mov save7,#0)
     5062dnl         __(mov allocptr,#-dnode_size)
     5063dnl         __(mov allocbase,#-dnode_size)
     5064dnl     __(str(imm2,tcr.valence(rcontext)))     
     5065dnl     __(vpop_saveregs())
     5066dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     5067dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     5068dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     5069dnl     __(mtlr loc_pc)
     5070dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     5071dnl     __(mffs f0)
     5072dnl     __(stfd f0,8(sp))
     5073dnl     __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
     5074dnl         __(clrrwi imm2,imm3,8)
     5075dnl     __(discard_lisp_frame())
     5076dnl     __(str(imm2,tcr.ffi_exception(rcontext)))
     5077dnl     __(lfd f0,tcr.lisp_fpscr(rcontext))
     5078dnl     __(mtfsf 0xff,f0)
     5079dnl     __(check_pending_interrupt(`cr1'))
     5080dnl         __(mtxer rzero)
     5081dnl         __(mtctr rzero)
     5082dnl     __(bx lr)
     5083dnl         
     5084dnl /*  */
     5085dnl /* This gets called with R11 holding the unboxed callback index. */
     5086dnl /* */
     5087dnl         
     5088dnl _spentry(eabi_callback)
     5089dnl     /* First, we extend the C frame so that it has room for */
     5090dnl         /* incoming arg regs.  */
     5091dnl     __(ldr r0,[sp,#eabi_c_frame.backlink])
     5092dnl     __(stru(r0,eabi_c_frame.param0-varargs_eabi_c_frame.incoming_stack_args(sp)))
     5093dnl     __(mflr r0)
     5094dnl     __(str(r0,varargs_eabi_c_frame.savelr(sp)))
     5095dnl     __(str(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
     5096dnl     __(str(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
     5097dnl     __(str(r5,varargs_eabi_c_frame.gp_save+(2*4)(sp)))
     5098dnl     __(str(r6,varargs_eabi_c_frame.gp_save+(3*4)(sp)))
     5099dnl     __(str(r7,varargs_eabi_c_frame.gp_save+(4*4)(sp)))
     5100dnl     __(str(r8,varargs_eabi_c_frame.gp_save+(5*4)(sp)))
     5101dnl     __(str(r9,varargs_eabi_c_frame.gp_save+(6*4)(sp)))
     5102dnl     __(str(r10,varargs_eabi_c_frame.gp_save+(7*4)(sp)))
     5103dnl     /* Could check the appropriate CR bit and skip saving FP regs here  */
     5104dnl     __(stfd f1,varargs_eabi_c_frame.fp_save+(0*8)(sp))
     5105dnl     __(stfd f2,varargs_eabi_c_frame.fp_save+(1*8)(sp))
     5106dnl     __(stfd f3,varargs_eabi_c_frame.fp_save+(2*8)(sp))
     5107dnl     __(stfd f4,varargs_eabi_c_frame.fp_save+(3*8)(sp))
     5108dnl     __(stfd f5,varargs_eabi_c_frame.fp_save+(4*8)(sp))
     5109dnl     __(stfd f6,varargs_eabi_c_frame.fp_save+(5*8)(sp))
     5110dnl     __(stfd f7,varargs_eabi_c_frame.fp_save+(6*8)(sp))
     5111dnl     __(stfd f8,varargs_eabi_c_frame.fp_save+(7*8)(sp))
     5112dnl     __(la r0,varargs_eabi_c_frame.incoming_stack_args(sp))
     5113dnl     __(str(r0,varargs_eabi_c_frame.overflow_arg_area(sp)))
     5114dnl     __(la r0,varargs_eabi_c_frame.regsave(sp))
     5115dnl     __(str(r0,varargs_eabi_c_frame.reg_save_area(sp)))
     5116dnl     __(mov r0,#0)
     5117dnl     __(str(r0,varargs_eabi_c_frame.flags(sp)))
     5118dnl
     5119dnl     /* Save the non-volatile registers on the sp stack  */
     5120dnl     /* This is a non-standard stack frame, but noone will ever see it,  */
     5121dnl         /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
     5122dnl     __(stru(sp,-(c_reg_save.size)(sp)))
     5123dnl         __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
     5124dnl         __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
     5125dnl         __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
     5126dnl         __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
     5127dnl         __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
     5128dnl         __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
     5129dnl         __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
     5130dnl         __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
     5131dnl         __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
     5132dnl         __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
     5133dnl         __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
     5134dnl         __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
     5135dnl         __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
     5136dnl         __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
     5137dnl         __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
     5138dnl         __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
     5139dnl         __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
     5140dnl         __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
     5141dnl         __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
     5142dnl     __(mffs f0)
     5143dnl     __(stfd f0,c_reg_save.save_fp_zero(sp))
     5144dnl     __(ldr r31,[sp,#c_reg_save.save_fp_zero+4])     /* recover FPSCR image  */
     5145dnl     __(str(r31,c_reg_save.save_fpscr(sp)))
     5146dnl     __(mov r30,#0x43300000)
     5147dnl     __(mov r31,#0x80000000)
     5148dnl     __(str(r30,c_reg_save.save_fp_zero(sp)))
     5149dnl     __(str(r31,c_reg_save.save_fp_zero+4(sp)))
     5150dnl     __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
     5151dnl     __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
     5152dnl     __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
     5153dnl     __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
     5154dnl
     5155dnl     
     5156dnl /* Restore rest of Lisp context.  */
     5157dnl /* Could spread out the memory references here to gain a little speed  */
     5158dnl     __(mov loc_pc,#0)
     5159dnl     __(mov fn,#0)                     /* subprim, not a lisp function  */
     5160dnl     __(mov temp3,#0)
     5161dnl     __(mov temp2,#0)
     5162dnl     __(mov temp1,#0)
     5163dnl     __(mov temp0,#0)
     5164dnl     __(mov arg_x,#0)
     5165dnl     __(box_fixnum(arg_y,r11))       /* callback-index  */
     5166dnl     __(la arg_z,c_reg_save.size+varargs_eabi_c_frame.gp_save(sp))   /* parameters (tagged as a fixnum)  */
     5167dnl
     5168dnl     /* Recover lisp thread context. Have to call C code to do so.  */
     5169dnl     __(ref_global(r12,get_tcr))
     5170dnl     __(mtctr r12)
     5171dnl         __(mov r3,#1)
     5172dnl     __(stru(sp,-(stack_align(eabi_c_frame.minsiz))(sp)))
     5173dnl     __(bctrl)
     5174dnl     __(la sp,(stack_align(eabi_c_frame.minsiz))(sp))
     5175dnl     __(la rcontext,TCR_BIAS(r3))
     5176dnl     __(mov allocptr,#0)
     5177dnl     __(mov allocbase,#0)
     5178dnl     __(ldr vsp,[rcontext,#tcr.save_vsp])
     5179dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])           
     5180dnl     __(mov rzero,#0)
     5181dnl     __(mtxer rzero) /* lisp wants the overflow bit clear  */
     5182dnl     __(mov imm0,#TCR_STATE_LISP)
     5183dnl     __(mov save0,#0)
     5184dnl     __(mov save1,#0)
     5185dnl     __(mov save2,#0)
     5186dnl     __(mov save3,#0)
     5187dnl     __(mov save4,#0)
     5188dnl     __(mov save5,#0)
     5189dnl     __(mov save6,#0)
     5190dnl     __(mov save7,#0)
     5191dnl         __(mtctr rzero)
     5192dnl     __(str(imm0,tcr.valence(rcontext)))
     5193dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     5194dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     5195dnl     __(lfd f0,tcr.lisp_fpscr(rcontext))
     5196dnl     __(mtfsf 0xff,f0)
     5197dnl
     5198dnl         __(restore_saveregs(vsp))       
     5199dnl     /* load nargs and callback to the lisp  */
     5200dnl     __(set_nargs(2))
     5201dnl     __(ldr imm2,[rcontext,#tcr.cs_area])
     5202dnl     __(ldr imm4,[imm2,#area.active])
     5203dnl     __(stru(imm4,-lisp_frame.size(sp)))
     5204dnl     __(str(imm3,lisp_frame.savelr(sp)))
     5205dnl     __(str(vsp,lisp_frame.savevsp(sp)))     /* for stack overflow code  */
     5206dnl     __(mov fname,#nrs.callbacks)    /* %pascal-functions%  */
     5207dnl     __(call_fname)
     5208dnl     __(ldr imm2,[sp,#lisp_frame.backlink])
     5209dnl     __(ldr imm3,[rcontext,#tcr.cs_area])
     5210dnl     __(str(imm2,area.active(imm3)))
     5211dnl     __(discard_lisp_frame())
     5212dnl     /* save_vsp will be restored from ff_call's stack frame, but  */
     5213dnl     /* I included it here for consistency.  */
     5214dnl     /* save_tsp is set below after we exit Lisp context.  */
     5215dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     5216dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     5217dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     5218dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     5219dnl     /* Exit lisp context  */
     5220dnl     /* This is not necessary yet, but will be once we can be interrupted  */
     5221dnl     __(mov imm1,#TCR_STATE_FOREIGN)
     5222dnl     __(str(imm1,tcr.valence(rcontext)))
     5223dnl     /* Restore the non-volatile registers & fpscr  */
     5224dnl     __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
     5225dnl     __(ldr r31,[sp,#c_reg_save.save_fpscr])
     5226dnl     __(str(r31,c_reg_save.save_fp_zero+4(sp)))
     5227dnl     __(lfd f0,c_reg_save.save_fp_zero(sp))
     5228dnl     __(mtfsf 0xff,f0)
     5229dnl     __(ldr r13,c_reg_save.save_gprs+(0*node_size)(sp)))
     5230dnl     __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
     5231dnl     __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
     5232dnl     __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
     5233dnl     __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
     5234dnl     __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
     5235dnl     __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
     5236dnl     __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
     5237dnl     __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
     5238dnl     __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
     5239dnl     __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
     5240dnl     __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
     5241dnl     __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
     5242dnl     __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
     5243dnl     __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
     5244dnl     __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
     5245dnl     __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
     5246dnl     __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
     5247dnl     __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
     5248dnl     __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
     5249dnl     __(ldr(sp,0(sp)))
     5250dnl
     5251dnl     __(ldr(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
     5252dnl     __(ldr(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
     5253dnl     __(lfd f1,varargs_eabi_c_frame.gp_save+(2*4)(sp))
     5254dnl     __(ldr(r5,varargs_eabi_c_frame.savelr(sp)))
     5255dnl     __(str(r5,varargs_eabi_c_frame.old_savelr(sp)))
     5256dnl     __(mtlr r5)
     5257dnl     __(ldr(r5,varargs_eabi_c_frame.backlink(sp)))
     5258dnl     __(str(r5,varargs_eabi_c_frame.old_backlink(sp)))
     5259dnl     __(la sp,varargs_eabi_c_frame.old_backlink(sp))
     5260dnl     __(bx lr)
     5261dnl     
     5262dnl
     5263dnl /*  Do a linux system call:  the system call index is (boxed) */
     5264dnl /*  in arg_z, and other arguments are in an eabi_c_frame on */
     5265dnl /*  the C stack.  As is the case with an eabi_ff_call, there's */
     5266dnl /*  a lisp frame reserved underneath the eabi_c_frame. */
     5267dnl
     5268dnl /*  This is a little simpler than eabi_ff_call, because we */
     5269dnl /*  can assume that there are no synchronous callbacks to */
     5270dnl /*  lisp (that might cause a GC.)  It's also simpler for the */
     5271dnl /*  caller, since we return error status atomically. */
     5272dnl
     5273dnl /*  A system call can clobber any or all of r9-r12, so we need */
     5274dnl /*  to save and restore allocptr, allocbase, and tsp. */
     5275dnl     
     5276dnl _spentry(eabi_syscall)
     5277dnl /*  We're entered with an eabi_c_frame on the C stack.  There's a */
     5278dnl /*  lisp_frame reserved underneath it; we'll link it in in a minute. */
     5279dnl /*  Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
     5280dnl /*  then shrink the eabi_c_frame. */
     5281dnl
     5282dnl     __(mflr loc_pc)
     5283dnl         __(vpush_saveregs())
     5284dnl     __(str(sp,eabi_c_frame.savelr(sp)))
     5285dnl     __(mov arg_x,#nil_value)
     5286dnl     __(mov temp0,rcontext)
     5287dnl     __(ldr temp1,[sp,#c_frame.backlink])    /* bottom of reserved lisp frame  */
     5288dnl     __(la temp2,-lisp_frame.size(temp1))    /* top of lisp frame  */
     5289dnl         __(zero_doublewords temp2,0,lisp_frame.size)
     5290dnl     __(str(temp1,lisp_frame.backlink(temp2)))
     5291dnl     __(str(temp2,c_frame.backlink(sp)))
     5292dnl     __(str(fn,lisp_frame.savefn(temp2)))
     5293dnl     __(str(loc_pc,lisp_frame.savelr(temp2)))
     5294dnl     __(str(vsp,lisp_frame.savevsp(temp2)))
     5295dnl     __(ldr temp3,[rcontext,#tcr.cs_area])
     5296dnl     __(str(temp2,area.active(temp3)))
     5297dnl     __(str(allocptr,tcr.save_allocptr(rcontext)))
     5298dnl     __(str(allocbase,tcr.save_allocbase(rcontext)))
     5299dnl     __(str(tsp,tcr.save_tsp(rcontext)))
     5300dnl     __(str(vsp,tcr.save_vsp(rcontext)))
     5301dnl     __(str(rzero,tcr.ffi_exception(rcontext)))
     5302dnl     __(mov imm1,#TCR_STATE_FOREIGN)
     5303dnl     __(str(imm1,tcr.valence(rcontext)))
     5304dnl     __(ldr r13,[0,#lisp_globals.saveR13])
     5305dnl     __(ldr r3,[sp,#eabi_c_frame.param0])
     5306dnl     __(ldr r4,[sp,#eabi_c_frame.param1])
     5307dnl     __(ldr r5,[sp,#eabi_c_frame.param2])
     5308dnl     __(ldr r6,[sp,#eabi_c_frame.param3])
     5309dnl     __(ldr r7,[sp,#eabi_c_frame.param4])
     5310dnl     __(ldr r8,[sp,#eabi_c_frame.param5])
     5311dnl     __(ldr r9,[sp,#eabi_c_frame.param6])
     5312dnl     __(ldr r10,[sp,#eabi_c_frame.param7])
     5313dnl     __(la temp1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
     5314dnl     __(str(rzero,eabi_c_frame.savelr(temp1)))
     5315dnl     __(str(temp2,eabi_c_frame.backlink(temp1)))
     5316dnl     __(mov sp,temp1)
     5317dnl     __(unbox_fixnum(r0,arg_z))
     5318dnl     __(sc)
     5319dnl     __(nop)
     5320dnl     /* C should have preserved temp0 (= rcontext) for us.  */
     5321dnl     __(ldr sp,[sp,#0])
     5322dnl     __(mov imm2,temp0)
     5323dnl     __(ldr vsp,[sp,#lisp_frame.savevsp])
     5324dnl     __(mov rzero,#0)
     5325dnl     __(mov loc_pc,rzero)
     5326dnl     __(mov fn,rzero)
     5327dnl     __(mov arg_x,#nil_value)
     5328dnl     __(mov arg_y,#nil_value)
     5329dnl     __(mov arg_z,#nil_value)
     5330dnl     __(mov temp0,#nil_value)
     5331dnl     __(mov temp1,#nil_value)
     5332dnl     __(mov temp2,#nil_value)
     5333dnl     __(mov temp3,#nil_value)
     5334dnl     __(mov fn,#nil_value)
     5335dnl         
     5336dnl     __(mov imm3,#TCR_STATE_LISP)
     5337dnl     __(mov rcontext,imm2)
     5338dnl         __(mov save0,#0)
     5339dnl         __(mov save1,#0)
     5340dnl         __(mov save2,#0)
     5341dnl         __(mov save3,#0)
     5342dnl         __(mov save4,#0)
     5343dnl         __(mov save5,#0)
     5344dnl         __(mov save6,#0)
     5345dnl         __(mov save7,#0)       
     5346dnl     __(str(imm3,tcr.valence(rcontext)))
     5347dnl     __(vpop_saveregs)
     5348dnl     __(ldr allocptr,[rcontext,#tcr.save_allocptr])
     5349dnl     __(ldr allocbase,[rcontext,#tcr.save_allocbase])
     5350dnl     __(ldr tsp,[rcontext,#tcr.save_tsp])
     5351dnl     __(ldr loc_pc,[sp,#lisp_frame.savelr])
     5352dnl     __(mtlr loc_pc)
     5353dnl     __(ldr fn,[sp,#lisp_frame.savefn])
     5354dnl     __(discard_lisp_frame())
     5355dnl     __(bns 1f)
     5356dnl     __(neg r3,r3)
     5357dnl 1:     
     5358dnl     __(check_pending_interrupt(`cr1'))               
     5359dnl     __(mtxer rzero)
     5360dnl     __(bx lr)
     5361dnl         
     5362dnl /* arg_z should be of type (UNSIGNED-BYTE 64);  */
     5363dnl /* On PPC32, return high 32 bits in imm0, low 32 bits in imm1 */
     5364dnl /* On PPC64, return unboxed value in imm0  */
     5365dnl
     5366dnl _spentry(getu64)
     5367dnl         __ifdef(`PPC64')
     5368dnl         __(extract_typecode(imm0,arg_z))
     5369dnl         __(cmpdi cr0,imm0,tag_fixnum)
     5370dnl         __(cmpdi cr2,arg_z,0)
     5371dnl         __(cmpdi cr1,imm0,subtag_bignum)
     5372dnl         __(bne cr0,1f)
     5373dnl         __(unbox_fixnum(imm0,arg_z))
     5374dnl         __(bgelr cr2)
     5375dnl 0:             
     5376dnl     __(uuo_interr(error_object_not_u64,arg_z))
     5377dnl         
     5378dnl 1:      __(bne cr1,0b)
     5379dnl         __(getvheader(imm1,arg_z))
     5380dnl         __(ld imm0,misc_data_offset(arg_z))
     5381dnl         __(cmpdi cr2,imm1,two_digit_bignum_header)
     5382dnl         __(rotldi imm0,imm0,32)
     5383dnl         __(cmpdi cr1,imm1,three_digit_bignum_header)
     5384dnl         __(cmpdi cr0,imm0,0)
     5385dnl         __(beq cr2,2f)
     5386dnl         __(lwz imm1,misc_data_offset+8(arg_z))
     5387dnl         __(bne cr1,0b)
     5388dnl         __(cmpwi imm1,0)
     5389dnl         __(bne 0b)
     5390dnl         __(bx lr)
     5391dnl 2:      __(blt 0b)
     5392dnl         __(bx lr)       
     5393dnl         __else
     5394dnl     __(extract_typecode(imm0,arg_z))
     5395dnl     __(cmpri(cr0,imm0,tag_fixnum))
     5396dnl     __(cmpri(cr1,arg_z,0))
     5397dnl     __(cmpri(cr2,imm0,subtag_bignum))
     5398dnl     __(unbox_fixnum(imm1,arg_z))
     5399dnl     __(bne cr0,8f)
     5400dnl     __(bgelr cr1)
     5401dnl 9:
     5402dnl     __(uuo_interr(error_object_not_u64,arg_z))
     5403dnl 8:
     5404dnl     __(bne- cr2,9b)
     5405dnl     __(getvheader(imm2,arg_z))
     5406dnl     __(cmpri(cr2,imm2,two_digit_bignum_header))
     5407dnl     __(vrefr(imm1,arg_z,0))
     5408dnl     __(cmpri(cr1,imm1,0))
     5409dnl     __(mov imm0,#0)
     5410dnl     __(bge cr2,2f)
     5411dnl     __(blt- cr1,9b)
     5412dnl     __(bx lr)
     5413dnl 2:
     5414dnl     __(cmpri(cr0,imm2,three_digit_bignum_header))
     5415dnl     __(vrefr(imm0,arg_z,1))
     5416dnl     __(cmpri(cr1,imm0,0))
     5417dnl     __(bne cr2,3f)
     5418dnl     __(blt- cr1,9b)
     5419dnl     __(bx lr)
     5420dnl 3:
     5421dnl     __(vrefr(imm2,arg_z,2))
     5422dnl     __(cmpri(cr1,imm2,0))
     5423dnl     __(bne- cr0,9b)
     5424dnl     __(bne- cr1,9b)
     5425dnl     __(bx lr)
     5426dnl         __endif
     5427dnl         
     5428dnl /* arg_z should be of type (SIGNED-BYTE 64);  */
     5429dnl /* PPC32:   return high 32 bits  in imm0, low 32 bits in imm1  */
     5430dnl /* PPC64:   return unboxed value in imm0  */
     5431dnl
     5432dnl _spentry(gets64)
     5433dnl         __ifdef(`PPC64')
     5434dnl      __(extract_typecode(imm1,arg_z))
     5435dnl          __(unbox_fixnum(imm0,arg_z))
     5436dnl      __(cmpri(cr0,imm1,tag_fixnum))
     5437dnl      __(cmpri(cr2,imm1,subtag_bignum))
     5438dnl          __(beqlr cr0)
     5439dnl          __(bne cr2,9f)
     5440dnl          __(ld imm1,misc_header_offset(arg_z))
     5441dnl          __(ld imm0,misc_data_offset(arg_z))
     5442dnl          __(cmpdi imm1,two_digit_bignum_header)
     5443dnl          __(rotldi imm0,imm0,32)
     5444dnl          __(beqlr)
     5445dnl         __else
     5446dnl      __(extract_typecode(imm0,arg_z))
     5447dnl      __(cmpri(cr0,imm0,tag_fixnum))
     5448dnl      __(cmpri(cr2,imm0,subtag_bignum))
     5449dnl      __(unbox_fixnum(imm1,arg_z))
     5450dnl      __(srawi imm0,imm1,31)
     5451dnl      __(beqlr cr0)
     5452dnl      __(bne cr2,9f)
     5453dnl      __(getvheader(imm2,arg_z))
     5454dnl      __(cmpri(cr2,imm2,two_digit_bignum_header))
     5455dnl      __(vrefr(imm1,arg_z,0))
     5456dnl      __(srawi imm0,imm1,31)
     5457dnl      __(bltlr cr2)
     5458dnl      __(vrefr(imm0,arg_z,1))
     5459dnl      __(beqlr cr2)
     5460dnl         __endif
     5461dnl 9:
     5462dnl     __(uuo_interr(error_object_not_s64,arg_z))
     5463dnl
     5464dnl
     5465dnl
     5466dnl     
     5467dnl
     5468dnl
     5469dnl
     5470dnl
     5471dnl
     5472dnl /* imm0:imm1 constitute an unsigned integer, almost certainly a bignum. */
     5473dnl /* Make a lisp integer out of those 128 bits ..  */
     5474dnl _spentry(makeu128)
     5475dnl         __ifdef(`PPC64')
     5476dnl          __(cmpdi imm0,0)
     5477dnl          __(cmpdi cr1,imm1,0)
     5478dnl          __(srdi imm3,imm0,32)
     5479dnl          __(srawi imm4,imm0,31)
     5480dnl          __(cmpdi cr3,imm3,0)
     5481dnl          __(cmpdi cr4,imm4,0)
     5482dnl          __(mov imm2,#five_digit_bignum_header)
     5483dnl          __(blt cr1,0f)
     5484dnl          __(beq 3f)
     5485dnl 0:             
     5486dnl          __(bge 1f)
     5487dnl          /* All 128 bits are significant, and the most significant */
     5488dnl          /* bit is set.  Allocate a 5-digit bignum (with a zero */
     5489dnl          /* sign digit  */
     5490dnl          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(5)))
     5491dnl          __(rotldi imm0,imm0,32)
     5492dnl          __(rotldi imm1,imm1,32)
     5493dnl          __(std imm1,misc_data_offset(arg_z))
     5494dnl          __(std imm0,misc_data_offset+8(arg_z))
     5495dnl          __(bx lr)
     5496dnl 1:       /* If the high word of imm0 is a zero-extension of the low */
     5497dnl          /* word, we only need 3 digits ; otherwise, we need 4.  */
     5498dnl          __(mov imm2,#three_digit_bignum_header)
     5499dnl          __(rotldi imm1,imm1,32)
     5500dnl          __(bne cr3,2f) /* high word of imm0 is non-zero  */
     5501dnl          __(bne cr4,2f) /* sign bit is on in low word of imm0  */
     5502dnl          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
     5503dnl          __(std imm1,misc_data_offset(arg_z))
     5504dnl          __(stw imm0,misc_data_offset+8(arg_z))
     5505dnl          __(bx lr)
     5506dnl 2:       __(mov imm2,#four_digit_bignum_header)
     5507dnl          __(rotldi imm0,imm0,32)
     5508dnl          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
     5509dnl          __(std imm1,misc_data_offset(arg_z))
     5510dnl          __(std imm0,misc_data_offset+8(arg_z))
     5511dnl          __(bx lr)
     5512dnl 3:       __(mov imm0,imm1)
     5513dnl          __(b _SPmakeu64)             
     5514dnl         __else
     5515dnl          __(twgei r0,r0)
     5516dnl         __endif
     5517dnl
     5518dnl /* imm0:imm1 constitute a signed integer, almost certainly a bignum. */
     5519dnl /* Make a lisp integer out of those 128 bits ..  */
     5520dnl _spentry(makes128)
     5521dnl         __ifdef(`PPC64')
     5522dnl          /* Is imm0 just a sign-extension of imm1 ?  */
     5523dnl          __(sradi imm2,imm1,63)
     5524dnl          /* Is the high word of imm0 just a sign-extension of the low word ?  */
     5525dnl          __(extsw imm3,imm0)
     5526dnl          __(cmpd imm2,imm0)
     5527dnl          __(cmpd cr1,imm3,imm0)
     5528dnl          __(beq 2f)
     5529dnl          __(rotldi imm0,imm0,32)
     5530dnl          __(rotldi imm1,imm1,32)
     5531dnl          __(beq cr1,1f)
     5532dnl          __(mov imm2,#four_digit_bignum_header)
     5533dnl          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
     5534dnl          __(std imm1,misc_data_offset(arg_z))
     5535dnl          __(std imm0,misc_data_offset+8(arg_z))
     5536dnl          __(bx lr)
     5537dnl 1:       __(mov imm2,#three_digit_bignum_header)
     5538dnl          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
     5539dnl          __(std imm1,misc_data_offset(arg_z))
     5540dnl          __(stw imm3,misc_data_offset+8(arg_z))
     5541dnl          __(bx lr)
     5542dnl 2:       __(mov imm0,imm1)
     5543dnl          __(b _SPmakes64)       
     5544dnl         __else
     5545dnl          __(twgei r0,r0)
     5546dnl         __endif       
     5547dnl                         
     5548dnl /* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
     5549dnl /* unbound_marker), arg_y = symbol, imm3 = symbol.binding-index  */
     5550dnl _spentry(specref)
     5551dnl         __(ldr imm1,[arg_z,#symbol.binding_index])
     5552dnl         __(ldr imm0,[rcontext,#tcr.tlb_limit])
     5553dnl         __(cmp imm1,imm0)
     5554dnl         __(ldr temp0,[rcontext,#tcr.tlb_pointer])
     5555dnl         __(mov arg_y,arg_z)
     5556dnl         __(movhs imm1,#0)
     5557dnl         __(ldr arg_z,[temp0,imm1])
     5558dnl         __(cmp arg_z,#no_thread_local_binding_marker)
     5559dnl             __(ldreq arg_z,[arg_y,#symbol.vcell])
     5560dnl         __(bx lr)
     5561dnl
     5562dnl
     5563dnl _spentry(specrefcheck)
     5564dnl         __(ldr imm1,[arg_z,#symbol.binding_index])
     5565dnl         __(ldr imm0,[rcontext,#tcr.tlb_limit])
     5566dnl         __(cmp imm1,imm0)
     5567dnl         __(movhs imm1,#0)
     5568dnl         __(ldr imm0,[rcontext,#tcr.tlb_pointer])
     5569dnl         __(mov arg_y,arg_z)
     5570dnl         __(ldrx arg_z,[imm0,imm1])
     5571dnl         __(cmp arg_z,#no_thread_local_binding_marker)
     5572dnl             __(ldreq arg_z,[arg_y,#symbol.vcell])
     5573dnl         __(cmp arg_z,#unbound_marker)
     5574dnl         __(uuo_error_unbound(eq,arg_y)
     5575dnl         __(bx lr)
     5576dnl     
     5577dnl /* arg_y = special symbol, arg_z = new value.          */
     5578dnl _spentry(specset)
     5579dnl         __(ldr imm3,[arg_y,#symbol.binding_index])
     5580dnl         __(ldr imm0,[rcontext,#tcr.tlb_limit])
     5581dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
     5582dnl         __(cmpr(imm3,imm0))
     5583dnl         __(bge 1f)
     5584dnl         __(ldrx(temp1,imm2,imm3))
     5585dnl         __(cmpri(temp1,no_thread_local_binding_marker))
     5586dnl         __(beq 1f)
     5587dnl         __(str arg_z,imm2,imm3)
     5588dnl         __(bx lr)
     5589dnl 1:          __(mov arg_x,arg_y)
     5590dnl         __(mov arg_y,#symbol.vcell-misc_data_offset)
     5591dnl         __(b _SPgvset)
     5592dnl
     5593dnl /* Restore current thread's interrupt level to arg_z, */
     5594dnl /* noting whether the tcr's interrupt_pending flag was set.  */
     5595dnl _spentry(restoreintlevel)
     5596dnl     __(cmpri(cr1,arg_z,0))
     5597dnl     __(ldr imm0,[rcontext,#tcr.interrupt_pending])
     5598dnl     __(cmpri(cr0,imm0,0))
     5599dnl     __(bne cr1,1f)
     5600dnl     __(beq cr0,1f)
     5601dnl     __(str(rzero,tcr.interrupt_pending(rcontext)))
     5602dnl     __(mov nargs,#fixnum_one)
     5603dnl     __(trgti(nargs,0))
     5604dnl     __(bx lr)
     5605dnl 1:
     5606dnl         __(ldr nargs,[rcontext,#tcr.tlb_pointer])
     5607dnl     __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(nargs)))
     5608dnl     __(bx lr)
     5609dnl
     5610dnl
     5611dnl /* Construct a lisp integer out of the 32-bit signed value in imm0 */
     5612dnl
     5613dnl         
     5614dnl
     5615dnl
     5616dnl
     5617dnl /*  */
     5618dnl /* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
     5619dnl /*  */
     5620dnl _spentry(gets32)
     5621dnl         __ifdef(`PPC64')
     5622dnl          __(sldi imm1,arg_z,32-fixnumshift)
     5623dnl          __(extract_lisptag_(imm0,arg_z))
     5624dnl          __(sradi imm1,imm1,32-fixnumshift)
     5625dnl          __(box_fixnum(imm0,arg_z))
     5626dnl          __(cmpd cr1,imm1,arg_z)
     5627dnl          __(bne cr0,9f)
     5628dnl          __(beqlr cr1)
     5629dnl          __(b 9f)
     5630dnl         __else
     5631dnl      __(extract_typecode(imm1,arg_z))
     5632dnl      __(cmpri(cr0,imm1,tag_fixnum))
     5633dnl      __(cmpri(cr2,imm1,subtag_bignum))
     5634dnl      __(unbox_fixnum(imm0,arg_z))
     5635dnl      __(beqlr+ cr0)
     5636dnl      __(bne cr2,9f)
     5637dnl      __(getvheader(imm1,arg_z))
     5638dnl      __(cmpri(cr1,imm1,one_digit_bignum_header))
     5639dnl      __(vrefr(imm0,arg_z,0))
     5640dnl      __(beqlr+ cr1)
     5641dnl         __endif
     5642dnl 9:
     5643dnl     __(uuo_interr(error_object_not_signed_byte_32,arg_z))
     5644dnl
     5645dnl /*  */
     5646dnl /* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
     5647dnl /*  */
     5648dnl
     5649dnl _spentry(getu32)
     5650dnl     __(extract_typecode(imm1,arg_z))
     5651dnl     __(cmpri(cr0,imm1,tag_fixnum))
     5652dnl     __(cmpri(cr1,arg_z,0))
     5653dnl     __(cmpri(cr2,imm1,subtag_bignum))
     5654dnl     __(unbox_fixnum(imm0,arg_z))
     5655dnl     __(bne cr0,8f)
     5656dnl     __(bgelr cr1)
     5657dnl 8:
     5658dnl     __(bne- cr2,9f)
     5659dnl     __(getvheader(imm2,arg_z))
     5660dnl     __(cmpri(cr2,imm2,two_digit_bignum_header))
     5661dnl     __(vrefr(imm0,arg_z,0))
     5662dnl     __(cmpri(cr0,imm0,0))
     5663dnl     __(bgt cr2,9f)
     5664dnl     __(beq cr2,2f)
     5665dnl     __(blt cr0,9f)
     5666dnl     __(bx lr)
     5667dnl 2:
     5668dnl     __(vrefr(imm1,arg_z,1))
     5669dnl     __(cmpri(cr0,imm1,0))
     5670dnl     __(beqlr+ cr0)
     5671dnl
     5672dnl 9:
     5673dnl     __(uuo_interr(error_object_not_unsigned_byte_32,arg_z))
     5674dnl
     5675dnl             
     5676dnl
     5677dnl
     5678dnl /* */
     5679dnl /* As per mvpass above, but in this case fname is known to be a */
     5680dnl /* symbol. */
     5681dnl
     5682dnl _spentry(mvpasssym)
     5683dnl     __(cmpri(cr0,nargs,node_size*nargregs))
     5684dnl     __(mflr loc_pc)
     5685dnl     __(mov imm0,vsp)
     5686dnl     __(ble+ cr0,1f)
     5687dnl      __(subi imm0,imm0,node_size*nargregs)
     5688dnl      __(add imm0,imm0,nargs)
     5689dnl 1:           
     5690dnl     __(build_lisp_frame(fn,loc_pc,imm0))
     5691dnl     __(ref_global(loc_pc,ret1val_addr))
     5692dnl     __(mov fn,#0)
     5693dnl     __(mtlr loc_pc)
     5694dnl     __(jump_fname())
     5695dnl
     5696dnl
     5697dnl
     5698dnl _spentry(unbind)
     5699dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5700dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])   
     5701dnl         __(ldr imm3,[imm1,#binding.sym])
     5702dnl         __(ldr temp1,[imm1,#binding.val])
     5703dnl         __(ldr imm1,[imm1,#binding.link])
     5704dnl         __(str temp1,imm2,imm3)
     5705dnl         __(str(imm1,tcr.db_link(rcontext)))
     5706dnl         __(bx lr)
     5707dnl
     5708dnl _spentry(unbind_n)
     5709dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5710dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])   
     5711dnl 1:      __(subi imm0,imm0,1)
     5712dnl         __(ldr imm3,[imm1,#binding.sym])
     5713dnl         __(ldr temp1,[imm1,#binding.val])
     5714dnl         __(cmpri(imm0,0))
     5715dnl         __(ldr imm1,[imm1,#binding.link])
     5716dnl         __(str temp1,imm2,imm3)
     5717dnl         __(bne 1b)
     5718dnl         __(str(imm1,tcr.db_link(rcontext)))
     5719dnl         __(bx lr)
     5720dnl
     5721dnl /* */
     5722dnl /* Clobbers imm1,imm2,imm5,arg_x, arg_y */
     5723dnl
     5724dnl _spentry(unbind_to)
     5725dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5726dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
     5727dnl 1:      __(ldr imm5,[imm1,#binding.sym])
     5728dnl         __(ldr arg_y,[imm1,#binding.val])
     5729dnl         __(ldr imm1,[imm1,#binding.link])
     5730dnl         __(cmpr(imm0,imm1))
     5731dnl         __(str arg_y,imm2,imm5)
     5732dnl         __(bne 1b)
     5733dnl         __(str(imm1,tcr.db_link(rcontext)))
     5734dnl         __(bx lr)
     5735dnl     
     5736dnl
     5737dnl
     5738dnl /* */
     5739dnl /* Restore the special bindings from the top of the tstack,  */
     5740dnl /* leaving the tstack frame allocated.  */
     5741dnl /* Note that there might be 0 saved bindings, in which case  */
     5742dnl /* do nothing.  */
     5743dnl /* Note also that this is -only- called from an unwind-protect  */
     5744dnl /* cleanup form, and that .SPnthrowXXX is keeping one or more  */
     5745dnl /* values in a frame on top of the tstack.  */
     5746dnl /*  */
     5747dnl                         
     5748dnl _spentry(progvrestore)
     5749dnl     __(ldr imm0,[tsp,#tsp_frame.backlink])  /* ignore .SPnthrowXXX values frame  */
     5750dnl     __(ldr imm0,[imm0,#tsp_frame.data_offset])
     5751dnl     __(cmpri(cr0,imm0,0))
     5752dnl     __(unbox_fixnum(imm0,imm0))
     5753dnl     __(bne+ cr0,_SPunbind_n)
     5754dnl     __(bx lr)
     5755dnl
     5756dnl /* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
     5757dnl /* for pending interrupts after doing so.  "nargs" can be freely used for an */
     5758dnl /* interrupt trap in this context.  */
     5759dnl _spentry(bind_interrupt_level_0)
     5760dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer])
     5761dnl         __(ldr temp0,[imm4,#INTERRUPT_LEVEL_BINDING_INDEX])
     5762dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5763dnl         __(cmpri(temp0,0))
     5764dnl         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
     5765dnl         __(vpush1(temp0))
     5766dnl         __(vpush1(imm3))
     5767dnl         __(vpush1(imm1))
     5768dnl         __(str(rzero,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
     5769dnl         __(str(vsp,tcr.db_link(rcontext)))
     5770dnl         __(beqlr)
     5771dnl         __(mov nargs,temp0)
     5772dnl         __(bgt 1f)
     5773dnl         __(ldr nargs,[rcontext,#tcr.interrupt_pending])
     5774dnl 1:      __(trgti(nargs,0))       
     5775dnl         __(bx lr)
     5776dnl
     5777dnl /* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
     5778dnl /* of disabling interrupts.)  */
     5779dnl _spentry(bind_interrupt_level_m1)
     5780dnl         __(mov imm2,#-fixnumone)
     5781dnl         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
     5782dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer])
     5783dnl         __(ldr temp0,[imm4,#INTERRUPT_LEVEL_BINDING_INDEX])
     5784dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5785dnl         __(vpush1(temp0))
     5786dnl         __(vpush1(imm3))
     5787dnl         __(vpush1(imm1))
     5788dnl         __(str(imm2,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
     5789dnl         __(str(vsp,tcr.db_link(rcontext)))
     5790dnl         __(bx lr)
     5791dnl
     5792dnl         
     5793dnl /* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
     5794dnl /* do what _SPbind_interrupt_level_0 does  */
     5795dnl _spentry(bind_interrupt_level)
     5796dnl         __(cmpri(arg_z,0))
     5797dnl         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
     5798dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer])
     5799dnl         __(ldr temp0,[imm4,#INTERRUPT_LEVEL_BINDING_INDEX])
     5800dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5801dnl         __(beq _SPbind_interrupt_level_0)
     5802dnl         __(vpush1(temp0))
     5803dnl         __(vpush1(imm3))
     5804dnl         __(vpush1(imm1))
     5805dnl         __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
     5806dnl         __(str(vsp,tcr.db_link(rcontext)))
     5807dnl         __(bx lr)
     5808dnl
     5809dnl /* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
     5810dnl /* non-negative, check for pending interrupts.  This is often called in */
     5811dnl /* a context where nargs is significant, so save and restore nargs around */
     5812dnl /* any interrupt polling  */
     5813dnl         
     5814dnl _spentry(unbind_interrupt_level)
     5815dnl         __(ldr imm0,[rcontext,#tcr.flags])
     5816dnl         __(ldr imm2,[rcontext,#tcr.tlb_pointer])
     5817dnl         __(andi. imm0,imm0,1<<TCR_FLAG_BIT_PENDING_SUSPEND)
     5818dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5819dnl         __(ldr temp1,[imm2,#INTERRUPT_LEVEL_BINDING_INDEX])
     5820dnl         __(bne 5f)
     5821dnl 0:      __(cmpri(cr1,temp1,0))
     5822dnl         __(ldr temp1,[imm1,#binding.val])
     5823dnl         __(ldr imm1,[imm1,#binding.link])
     5824dnl         __(cmpri(cr0,temp1,0))
     5825dnl         __(str(temp1,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
     5826dnl         __(str(imm1,tcr.db_link(rcontext)))
     5827dnl         __(bgelr cr1)
     5828dnl         __(bltlr cr0)
     5829dnl         __(mov imm2,nargs)
     5830dnl         __(check_pending_interrupt(`cr1'))
     5831dnl         __(mov nargs,imm2)
     5832dnl         __(bx lr)
     5833dnl 5:       /* Missed a suspend request; force suspend now if we're restoring
     5834dnl           interrupt level to -1 or greater */
     5835dnl         __(cmpri(temp1,-2<<fixnumshift))
     5836dnl         __(bne 0b)
     5837dnl         __(ldr imm0,[imm1,#binding.val])
     5838dnl         __(cmpr(imm0,temp1))
     5839dnl         __(beq 0b)
     5840dnl         __(mov imm0,#1<<fixnumshift)
     5841dnl         __(str(imm0,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
     5842dnl         __(suspend_now())
     5843dnl         __(b 0b)
     5844dnl
     5845dnl
     5846dnl /* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
     5847dnl    We don't know whether the array is alleged to be simple or
     5848dnl    not, and don't know anythng about the element type.  */
     5849dnl _spentry(aref2)
     5850dnl         __(extract_typecode(imm2,arg_x))
     5851dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
     5852dnl         __(cmpri(cr2,imm2,subtag_arrayH))
     5853dnl         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
     5854dnl         __(bne cr2,1f)
     5855dnl         __(ldr imm1,[arg_x,#arrayH.rank])
     5856dnl         __(cmpri(imm1,2<<fixnumshift))
     5857dnl         __(bne 1f)
     5858dnl         /* It's a 2-dimensional array.  Check bounds */
     5859dnl         __(ldr imm0,[arg_x,#arrayH.dim0])
     5860dnl         __(trlge(arg_y,imm0))
     5861dnl         __(ldr imm0,[arg_x,#arrayH.dim0+node_size])
     5862dnl         __(trlge(arg_z,imm0))
     5863dnl         __(unbox_fixnum(imm0,imm0))
     5864dnl         __(mullr(arg_y,arg_y,imm0))
     5865dnl         __(add arg_z,arg_z,arg_y)
     5866dnl         /* arg_z is now row-major-index; get data vector and
     5867dnl            add in possible offset */
     5868dnl         __(mov arg_y,arg_x)
     5869dnl 0:      __(ldr imm0,[arg_y,#arrayH.displacement])
     5870dnl         __(ldr arg_y,[arg_y,#arrayH.data_vector])
     5871dnl         __(extract_subtag(imm1,arg_y))
     5872dnl         __(cmpri(imm1,subtag_vectorH))
     5873dnl         __(add arg_z,arg_z,imm0)
     5874dnl         __(bgt local_label(misc_ref_common))
     5875dnl         __(b 0b)
     5876dnl 1:             
     5877dnl         __(uuo_interr(error_object_not_array_2d,arg_x))
     5878dnl
     5879dnl /* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
     5880dnl _spentry(aref3)
     5881dnl         __(extract_typecode(imm2,temp0))
     5882dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
     5883dnl         __(cmpri(cr2,imm2,subtag_arrayH))
     5884dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
     5885dnl         __(bne cr2,1f)
     5886dnl         __(ldr imm1,[temp0,#arrayH.rank])
     5887dnl         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
     5888dnl         __(cmpri(imm1,3<<fixnumshift))
     5889dnl         __(bne 1f)
     5890dnl         /* It's a 3-dimensional array.  Check bounds */
     5891dnl         __(ldr imm2,arrayH.dim0+(node_size*2)(temp0)))
     5892dnl         __(ldr imm1,[temp0,#arrayH.dim0+node_size])
     5893dnl         __(ldr imm0,[temp0,#arrayH.dim0])
     5894dnl         __(trlge(arg_z,imm2))
     5895dnl         __(unbox_fixnum(imm2,imm2))
     5896dnl         __(trlge(arg_y,imm1))
     5897dnl         __(unbox_fixnum(imm1,imm1))
     5898dnl         __(trlge(arg_x,imm0))
     5899dnl         __(mullr(arg_y,arg_y,imm2))
     5900dnl         __(mullr(imm1,imm2,imm1))
     5901dnl         __(mullr(arg_x,imm1,arg_x))
     5902dnl         __(add arg_z,arg_z,arg_y)
     5903dnl         __(add arg_z,arg_z,arg_x)
     5904dnl         __(mov arg_y,temp0)
     5905dnl 0:      __(ldr arg_x,[arg_y,#arrayH.displacement])
     5906dnl         __(ldr arg_y,[arg_y,#arrayH.data_vector])
     5907dnl         __(extract_subtag(imm1,arg_y))
     5908dnl         __(cmpri(imm1,subtag_vectorH))
     5909dnl         __(add arg_z,arg_x,arg_z)
     5910dnl         __(bgt local_label(misc_ref_common))
     5911dnl         __(b 0b)
     5912dnl 1:             
     5913dnl         __(uuo_interr(error_object_not_array_3d,temp0))
     5914dnl
     5915dnl         
     5916dnl         
     5917dnl
     5918dnl /* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
     5919dnl _spentry(aset2)
     5920dnl         __(extract_typecode(imm2,temp0))
     5921dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
     5922dnl         __(cmpri(cr2,imm2,subtag_arrayH))
     5923dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
     5924dnl         __(bne cr2,1f)
     5925dnl         __(ldr imm1,[temp0,#arrayH.rank])
     5926dnl         __(cmpri(imm1,2<<fixnumshift))
     5927dnl         __(bne 1f)
     5928dnl         /* It's a 2-dimensional array.  Check bounds */
     5929dnl         __(ldr imm0,[temp0,#arrayH.dim0])
     5930dnl         __(trlge(arg_x,imm0))
     5931dnl         __(ldr imm0,[temp0,#arrayH.dim0+node_size])
     5932dnl         __(trlge(arg_y,imm0))
     5933dnl         __(unbox_fixnum(imm0,imm0))
     5934dnl         __(mullr(arg_x,arg_x,imm0))
     5935dnl         __(add arg_y,arg_y,arg_x)
     5936dnl         /* arg_y is now row-major-index; get data vector and
     5937dnl            add in possible offset */
     5938dnl         __(mov arg_x,temp0)
     5939dnl 0:      __(ldr imm0,[arg_x,#arrayH.displacement])
     5940dnl         __(ldr arg_x,[arg_x,#arrayH.data_vector])
     5941dnl         __(extract_subtag(imm1,arg_x))
     5942dnl         __(cmpri(imm1,subtag_vectorH))
     5943dnl         __(add arg_y,arg_y,imm0)
     5944dnl         __(bgt local_label(misc_set_common))
     5945dnl         __(b 0b)
     5946dnl 1:             
     5947dnl         __(uuo_interr(error_object_not_array_2d,temp0))       
     5948dnl                 
     5949dnl /* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
     5950dnl _spentry(aset3)
     5951dnl         __(extract_typecode(imm2,temp1))
     5952dnl         __(trap_unless_lisptag_equal(temp0,tag_fixnum,imm0))
     5953dnl         __(cmpri(cr2,imm2,subtag_arrayH))
     5954dnl         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
     5955dnl         __(bne cr2,1f)
     5956dnl         __(ldr imm1,[temp1,#arrayH.rank])
     5957dnl         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
     5958dnl         __(cmpri(imm1,3<<fixnumshift))
     5959dnl         __(bne 1f)
     5960dnl         /* It's a 3-dimensional array.  Check bounds */
     5961dnl         __(ldr imm2,arrayH.dim0+(node_size*2)(temp1)))
     5962dnl         __(ldr imm1,[temp1,#arrayH.dim0+node_size])
     5963dnl         __(ldr imm0,[temp1,#arrayH.dim0])
     5964dnl         __(trlge(arg_y,imm2))
     5965dnl         __(unbox_fixnum(imm2,imm2))
     5966dnl         __(trlge(arg_x,imm1))
     5967dnl         __(unbox_fixnum(imm1,imm1))
     5968dnl         __(trlge(temp0,imm0))
     5969dnl         __(mullr(arg_x,arg_x,imm2))
     5970dnl         __(mullr(imm1,imm2,imm1))
     5971dnl         __(mullr(temp0,imm1,temp0))
     5972dnl         __(add arg_y,arg_y,arg_x)
     5973dnl         __(add arg_y,arg_y,temp0)
     5974dnl         __(mov arg_x,temp1)
     5975dnl 0:      __(ldr temp0,[arg_x,#arrayH.displacement])
     5976dnl         __(ldr arg_x,[arg_x,#arrayH.data_vector])
     5977dnl         __(extract_subtag(imm1,arg_x))
     5978dnl         __(cmpri(imm1,subtag_vectorH))
     5979dnl         __(add arg_y,arg_y,temp0)
     5980dnl         __(bgt local_label(misc_set_common))
     5981dnl         __(b 0b)
     5982dnl 1:             
     5983dnl         __(uuo_interr(error_object_not_array_3d,temp1))
     5984dnl
     5985dnl
     5986dnl         
     5987dnl
     5988dnl _spentry(nmkunwind)
     5989dnl         __(mov imm2,#-fixnumone)
     5990dnl         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
     5991dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer])
     5992dnl         __(ldr arg_y,[imm4,#INTERRUPT_LEVEL_BINDING_INDEX])
     5993dnl         __(ldr imm1,[rcontext,#tcr.db_link])
     5994dnl         __(vpush1(arg_y))
     5995dnl         __(vpush1(imm3))
     5996dnl         __(vpush1(imm1))
     5997dnl         __(str(imm2,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
     5998dnl         __(str(vsp,tcr.db_link(rcontext)))
     5999dnl     __(mov arg_z,#unbound_marker)
     6000dnl     __(mov imm2,#fixnum_one)
     6001dnl     __(mkcatch())
     6002dnl         __(mov arg_z,arg_y)
     6003dnl         __(b _SPbind_interrupt_level)
     6004dnl
     6005dnl
     6006dnl                                 
     6007dnl /*  EOF, basically  */
     6008dnl         .globl _SPsp_end
     6009dnl         b _SPsp_end
     6010dnl     
     6011 local_label(misc_ref_common):   
     6012         __(adr imm0,(local_label(misc_ref_jmp)))
     6013         __(ldr pc,[imm0,imm1,lsl #2])       
     6014 
     6015 local_label(misc_ref_jmp):         
     6016         /* 00-0f  */
    26906017         .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
     6018       
    26916019         .long local_label(misc_ref_invalid) /* 01 cons  */
    26926020         .long local_label(misc_ref_invalid) /* 02 nodeheader  */
     
    27046032         .long local_label(misc_ref_invalid) /* 0e misc  */
    27056033         .long local_label(misc_ref_u32) /* 0f single_float  */
    2706         /* 10-1f  */
     6034         /* 10-1f  */
    27076035         .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
    27086036         .long local_label(misc_ref_invalid) /* 11 cons  */
     
    27216049         .long local_label(misc_ref_invalid) /* 1e misc  */
    27226050         .long local_label(misc_ref_u32) /* 1f macptr  */
    2723         /* 20-2f  */
     6051         /* 20-2f  */
    27246052         .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
    27256053         .long local_label(misc_ref_invalid) /* 21 cons  */
     
    27386066         .long local_label(misc_ref_invalid) /* 2e misc  */
    27396067         .long local_label(misc_ref_u32) /* 2f code_vector  */
    2740         /* 30-3f  */
     6068         /* 30-3f  */
    27416069         .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
    27426070         .long local_label(misc_ref_invalid) /* 31 cons  */
     
    27556083         .long local_label(misc_ref_invalid) /* 3e misc  */
    27566084         .long local_label(misc_ref_u32) /* 3f xcode_vector  */
    2757         /* 40-4f  */
     6085         /* 40-4f  */
    27586086         .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
    27596087         .long local_label(misc_ref_invalid) /* 41 cons  */
     
    27726100         .long local_label(misc_ref_invalid) /* 4e misc  */
    27736101         .long local_label(misc_ref_invalid) /* 4f immheader  */
    2774         /* 50-5f  */
     6102         /* 50-5f  */
    27756103         .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
    27766104         .long local_label(misc_ref_invalid) /* 51 cons  */
     
    27896117         .long local_label(misc_ref_invalid) /* 5e misc  */
    27906118         .long local_label(misc_ref_invalid) /* 5f immheader  */
    2791         /* 60-6f  */
     6119         /* 60-6f  */
    27926120         .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
    27936121         .long local_label(misc_ref_invalid) /* 61 cons  */
     
    28066134         .long local_label(misc_ref_invalid) /* 6e misc  */
    28076135         .long local_label(misc_ref_invalid) /* 6f immheader  */
    2808         /* 70-7f  */
     6136         /* 70-7f  */
    28096137         .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
    28106138         .long local_label(misc_ref_invalid) /* 71 cons  */
     
    28236151         .long local_label(misc_ref_invalid) /* 7e misc  */
    28246152         .long local_label(misc_ref_invalid) /* 7f immheader  */
    2825         /* 80-8f  */
     6153         /* 80-8f  */
    28266154         .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
    28276155         .long local_label(misc_ref_invalid) /* 81 cons  */
     
    28406168         .long local_label(misc_ref_invalid) /* 8e misc  */
    28416169         .long local_label(misc_ref_invalid) /* 8f immheader  */
    2842         /* 90-9f  */
     6170         /* 90-9f  */
    28436171         .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
    28446172         .long local_label(misc_ref_invalid) /* 91 cons  */
     
    28576185         .long local_label(misc_ref_invalid) /* 9e misc  */
    28586186         .long local_label(misc_ref_invalid) /* 9f immheader  */
    2859         /* a0-af  */
     6187         /* a0-af  */
    28606188         .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
    28616189         .long local_label(misc_ref_invalid) /* a1 cons  */
     
    28746202         .long local_label(misc_ref_invalid) /* ae misc  */
    28756203         .long local_label(misc_ref_u32) /* af u32  */
    2876         /* b0-bf  */
     6204         /* b0-bf  */
    28776205         .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
    28786206         .long local_label(misc_ref_invalid) /* b1 cons  */
     
    28916219         .long local_label(misc_ref_invalid) /* be misc  */
    28926220         .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
    2893         /* c0-cf  */
     6221         /* c0-cf  */
    28946222         .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
    28956223         .long local_label(misc_ref_invalid) /* c1 cons  */
     
    29086236         .long local_label(misc_ref_invalid) /* ce misc  */
    29096237         .long local_label(misc_ref_u8) /* cf u8  */
    2910         /* d0-df  */
     6238         /* d0-df  */
    29116239         .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
    29126240         .long local_label(misc_ref_invalid) /* d1 cons  */
     
    29256253         .long local_label(misc_ref_invalid) /* de misc  */
    29266254         .long local_label(misc_ref_old_string) /* df (old)subtag_simple_base_string  */
    2927         /* e0-ef  */
     6255         /* e0-ef  */
    29286256         .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
    29296257         .long local_label(misc_ref_invalid) /* e1 cons  */
     
    29426270         .long local_label(misc_ref_invalid) /* ee misc  */
    29436271         .long local_label(misc_ref_s16) /* ef s16  */
    2944         /* f0-ff  */
     6272         /* f0-ff  */
    29456273         .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
    29466274         .long local_label(misc_ref_invalid) /* f1 cons  */
     
    29606288         .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
    29616289               
    2962 local_label(misc_ref_node):        
    2963          /* A node vector.  */
    2964          __(addi imm0,arg_z,misc_data_offset)
    2965          __(ldrx(arg_z,arg_y,imm0))
    2966          __(bx lr)
    2967 local_label(misc_ref_single_float_vector):       
    2968          __(addi imm0,arg_z,misc_data_offset)
    2969          __(mov imm1,#single_float_header)
    2970          __(ldrx(imm0,arg_y,imm0))
    2971          __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
    2972          __(str(imm0,single_float.value(arg_z)))
    2973          __(bx lr)
    2974 local_label(misc_ref_new_string):       
    2975          __(addi imm0,arg_z,misc_data_offset)
    2976          __(ldrx(imm0,arg_y,imm0))
    2977          __(slwi arg_z,imm0,charcode_shift)
    2978          __(ori arg_z,arg_z,subtag_character)
     6290 local_label(misc_ref_node):       
     6291        /* A node vector.  */
     6292        __(add imm0,arg_z,#misc_data_offset)
     6293        __(ldr  arg_z,[arg_y,imm0])
     6294        __(bx lr)
     6295 local_label(misc_ref_single_float_vector):       
     6296        __(add imm0,arg_z,misc_data_offset)
     6297        __(movc16(imm1,single_float_header))
     6298        __(ldr imm0,[arg_y,imm0])
     6299        __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
     6300        __(str imm0,[arg_z,#single_float.value])
     6301        __(bx lr)
     6302 local_label(misc_ref_new_string):       
     6303        __(add imm0,arg_z,#misc_data_offset)
     6304        __(ldr imm0,[arg_y,imm0])
     6305         __(mov arg_z,imm0,lsl #charcode_shift)
     6306         __(orr arg_z,arg_z,#subtag_character)
    29796307         __(bx lr)
    2980 local_label(misc_ref_s32):       
    2981          __(addi imm0,arg_z,misc_data_offset)
    2982          __(ldrx(imm0,arg_y,imm0))
     6308 local_label(misc_ref_s32):       
     6309        __(add imm0,arg_z,#misc_data_offset)
     6310        __(ldr imm0,[arg_y,imm0])
    29836311         __(b _SPmakes32)
    2984 local_label(misc_ref_fixnum_vector):   
    2985          __(addi imm0,arg_z,misc_data_offset)
    2986          __(ldrx(imm0,arg_y,imm0))
     6312 local_label(misc_ref_fixnum_vector):   
     6313        __(add imm0,arg_z,#misc_data_offset)
     6314        __(ldr imm0,[arg_y,imm0])
    29876315         __(box_fixnum(arg_z,imm0))
    29886316         __(bx lr)       
    2989 local_label(misc_ref_u32):       
    2990          __(addi imm0,arg_z,misc_data_offset)
    2991          __(ldrx(imm0,arg_y,imm0))
     6317 local_label(misc_ref_u32):       
     6318        __(add imm0,arg_z,#misc_data_offset)
     6319        __(ldr imm0,[arg_y,imm0])
    29926320         __(b _SPmakeu32)
    2993 local_label(misc_ref_double_float_vector):     
    2994          __(slwi imm0,arg_z,1)
    2995          __(la imm0,misc_dfloat_offset(imm0))
    2996          __(lfdx f0,arg_y,imm0)
    2997          __(mov imm2,#double_float_header)
    2998          __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
    2999          __(stfd f0,double_float.value(arg_z))
    3000          __(bx lr)
    3001 local_label(misc_ref_bit_vector):       
    3002          __(extrwi imm1,arg_z,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
    3003          __(la imm1,1+fixnumshift(imm1))
    3004          __(rlwinm imm0,arg_z,32-5,5,31-fixnumshift)
    3005          __(la imm0,misc_data_offset(imm0))
    3006          __(ldrx(imm0,arg_y,imm0))
    3007          __(rlwnm arg_z,imm0,imm1,31-fixnumshift,31-fixnumshift)
    3008          __(bx lr)
    3009 local_label(misc_ref_s8):       
    3010          __(srwi imm0,arg_z,2)
    3011          __(la imm0,misc_data_offset(imm0))
    3012          __(lbzx imm0,arg_y,imm0)
    3013          __(extsb imm0,imm0)
     6321 local_label(misc_ref_double_float_vector):     
     6322         __(mov imm0,arg_z,lsl #1)
     6323        __(add imm0,imm0,#misc_dfloat_offset)
     6324         __(ldrd imm0,imm1,[arg_y,imm0])
     6325        __(movc16(imm2,double_float_header))
     6326        __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
     6327        __(strd imm0,imm1,[arg_z,#double_float.value])
     6328        __(bx lr)
     6329 local_label(misc_ref_bit_vector):
     6330         __(mov imm1,#nbits_in_word-1)
     6331         __(and imm1,imm1,arg_z,lsr #2)
     6332         __(mov imm2,#1)
     6333         __(mov imm2,imm2,lsl imm1)
     6334         __(mov imm0,arg_z,lsr #5+fixnumshift)
     6335         __(mov imm0,imm0,lsl #2)
     6336         __(add imm0,imm0,#misc_data_offset)
     6337         __(mov arg_z,#0)
     6338         __(ldr imm0,[arg_y,imm0])
     6339         __(tst imm0,imm2)
     6340         __(addne arg_z,arg_z,#fixnumone)
     6341        __(bx lr)
     6342 local_label(misc_ref_s8):       
     6343         __(mov imm0,arg_z,lsr #2)
     6344         __(add imm0,imm0,#misc_data_offset)
     6345         __(ldsb imm0,[arg_y,imm0])
    30146346         __(box_fixnum(arg_z,imm0))
    30156347         __(bx lr)
    3016 local_label(misc_ref_u8):       
    3017          __(srwi imm0,arg_z,2)
    3018          __(la imm0,misc_data_offset(imm0))
    3019          __(lbzx imm0,arg_y,imm0)
     6348 local_label(misc_ref_u8):       
     6349         __(mov imm0,arg_z,lsr #2)
     6350         __(add imm0,imm0,#misc_data_offset)
     6351         __(ldrb imm0,[arg_y,imm0])
    30206352         __(box_fixnum(arg_z,imm0))
    30216353         __(bx lr)
    3022 local_label(misc_ref_old_string):          
    3023          __(srwi imm0,arg_z,2)
    3024          __(la imm0,misc_data_offset(imm0))
    3025          __(lbzx imm0,arg_y,imm0)
    3026          __(slwi arg_z,imm0,charcode_shift)
    3027          __(ori arg_z,arg_z,subtag_character)
    3028         __(bx lr)
    3029 local_label(misc_ref_u16):             
    3030          __(srwi imm0,arg_z,1)
    3031          __(la imm0,misc_data_offset(imm0))
    3032          __(lhzx imm0,arg_y,imm0)
     6354 local_label(misc_ref_old_string):         
     6355         __(mov imm0,arg_z,lsr #2)
     6356         __(add imm0,imm0,#misc_data_offset)
     6357         __(ldrb imm0,[arg_y,imm0])
     6358        __(mov arg_z,imm0,lsl #charcode_shift)
     6359        __(orr arg_z,arg_z,#subtag_character)
     6360        __(bx lr)
     6361 local_label(misc_ref_u16):       
     6362         __(mov imm0,arg_z,lsr #1)     
     6363         __(add imm0,imm0,#misc_data_offset)
     6364         __(ldrh imm0,[arg_y,imm0])
    30336365         __(box_fixnum(arg_z,imm0))
    30346366         __(bx lr)
    3035 local_label(misc_ref_s16):              
    3036          __(srwi imm0,arg_z,1)
    3037          __(la imm0,misc_data_offset(imm0))
    3038          __(lhax imm0,arg_y,imm0)
     6367 local_label(misc_ref_s16):             
     6368         __(mov imm0,arg_z,lsr #1)     
     6369         __(add imm0,imm0,#misc_data_offset)
     6370         __(ldrsh imm0,[arg_y,imm0])
    30396371         __(box_fixnum(arg_z,imm0))
    30406372         __(bx lr)
    3041 local_label(misc_ref_invalid):
     6373 local_label(misc_ref_invalid):
    30426374         __(mov arg_x,#XBADVEC)
    30436375         __(set_nargs(3))
    30446376         __(b _SPksignalerr)       
    3045 
    3046         __endif
    3047        
    3048 /* like misc_ref, only the boxed subtag is in arg_x.  */
    3049 
    3050 _spentry(subtag_misc_ref)
    3051         __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
    3052         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
    3053         __(vector_length(imm0,arg_y,imm1))
    3054         __(trlge(arg_z,imm0))
    3055         __(unbox_fixnum(imm1,arg_x))
    3056         __(b local_label(misc_ref_common))
    3057 
    3058 _spentry(builtin_aref1)
    3059         __(extract_typecode(imm0,arg_y))
    3060         __(cmpri(cr0,imm0,min_vector_subtag))
    3061         __(box_fixnum(arg_x,imm0))
    3062         __(bgt cr0,_SPsubtag_misc_ref)
    3063         __(jump_builtin(_builtin_aref1,2))
    3064                
    3065        
    3066 /* Make a cons cell on the vstack.  Always push 3 words, 'cause we're   */
    3067 /* not sure how the vstack will be aligned.  */
    3068 _spentry(stkconsyz)
    3069         __(mov imm0,#nil_value)
    3070         __(vpush1(imm0))
    3071         __(vpush1(imm0))
    3072         __(vpush1(imm0))
    3073         __(andi. imm0,vsp,1<<word_shift) /* (oddp vsp ?)  */
    3074         __(beq cr0,1f)
    3075         __(str(arg_y,node_size*2(vsp))) /* car  */
    3076         __(str(arg_z,node_size(vsp))) /* cdr  */
    3077         __(la arg_z,fulltag_cons+node_size(vsp))
    3078         __(bx lr)
    3079 1:
    3080         __(str(arg_y,node_size(vsp))) /* car, again  */
    3081         __(str(arg_z,0(vsp)))
    3082         __(la arg_z,fulltag_cons(vsp))
    3083         __(bx lr)
    3084 
    3085 /* Make a stack-consed value cell.  Much like the case of */
    3086 /* stack-allocating a cons cell.  Imm0 points to the closed-over value */
    3087 /* (already vpushed).  Replace that locative with the vcell.  */
    3088 _spentry(stkvcell0)
    3089         __(sub imm1,imm0,vsp) /* imm1 = delta from vsp to value cell loc  */
    3090         __(mov arg_z,#nil_value)
    3091         __(vpush1(arg_z))
    3092         __(vpush1(arg_z))
    3093         __(vpush1(arg_z))
    3094         __(addi imm1,imm1,node_size*3)
    3095         __(add imm0,vsp,imm1) /* in case stack overflowed  */
    3096         __(andi. imm1,vsp,1<<word_shift) /* (oddp vsp) ?  */
    3097         __(mov imm1,#value_cell_header)
    3098         __(ldr arg_z,[imm0,#0])
    3099         __(beq cr0,1f)
    3100         __(str(arg_z,node_size*2(vsp)))
    3101         __(str(imm1,node_size(vsp)))
    3102         __(la arg_z,fulltag_misc+node_size(vsp))
    3103         __(str(arg_z,0(imm0)))
    3104         __(bx lr)
    3105 1:
    3106         __(str(arg_z,node_size(vsp)))
    3107         __(str(imm1,0(vsp)))
    3108         __(la arg_z,fulltag_misc(vsp))
    3109         __(str(arg_z,0(imm0)))
    3110         __(bx lr)
    3111 
    3112        
    3113 _spentry(stkvcellvsp)     
    3114         __(mov arg_z,#nil_value)
    3115         __(vpush1(arg_z))
    3116         __(vpush1(arg_z))
    3117         __(vpush1(arg_z))
    3118         __(mov imm1,#node_size*3)
    3119         __(add imm0,vsp,imm1) /* in case stack overflowed  */
    3120         __(andi. imm1,vsp,1<<word_shift) /* (oddp vsp) ?  */
    3121         __(mov imm1,#value_cell_header)
    3122         __(ldr arg_z,[imm0,#0])
    3123         __(beq cr0,1f)
    3124         __(str(arg_z,node_size*2(vsp)))
    3125         __(str(imm1,node_size(vsp)))
    3126         __(la arg_z,fulltag_misc+node_size(vsp))
    3127         __(str(arg_z,0(imm0)))
    3128         __(bx lr)
    3129 1:
    3130         __(str(arg_z,node_size(vsp)))
    3131         __(str(imm1,0(vsp)))
    3132         __(la arg_z,fulltag_misc(vsp))
    3133         __(str(arg_z,0(imm0)))
    3134         __(bx lr)
    3135 
    3136 /* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
    3137 /* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
    3138 /* in arg_z on exit.  */
    3139 _spentry(makestackblock)
    3140         __(unbox_fixnum(imm0,arg_z))
    3141         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
    3142         __(cmplri(cr0,imm0,tstack_alloc_limit))
    3143         __(bge cr0,1f)
    3144         __(TSP_Alloc_Var_Unboxed(imm0))
    3145         __(mov imm0,#macptr_header)
    3146         __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
    3147         __(str(imm0,tsp_frame.data_offset(tsp)))
    3148         __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    3149         __(str(imm1,macptr.address(arg_z)))
    3150         __ifdef(`PPC64')
    3151          __(std rzero,macptr.domain(arg_z))
    3152          __(std rzero,macptr.type(arg_z))
    3153         __else
    3154          __(stfd fp_zero,macptr.domain(arg_z))
    3155         __endif
    3156         __(bx lr)
    3157 
    3158         /* Too big. Heap cons a gcable macptr  */
    3159 1:
    3160         __(TSP_Alloc_Fixed_Unboxed(0))
    3161         __(set_nargs(1))
    3162         __(mov fname,#nrs.new_gcable_ptr)
    3163         __(jump_fname())
    3164 
    3165 /* As above, only set the block's contents to 0.  */
    3166 _spentry(makestackblock0)
    3167         __(unbox_fixnum(imm0,arg_z))
    3168         __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
    3169         __(cmplri(cr0,imm0,tstack_alloc_limit))
    3170         __(bge cr0,3f)
    3171         __(TSP_Alloc_Var_Unboxed(imm0))
    3172         __(Zero_TSP_Frame(imm0,imm1))
    3173         __(mov imm0,#macptr_header)
    3174         __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
    3175         __(str(imm0,tsp_frame.data_offset(tsp)))
    3176         __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    3177         __(str(imm1,macptr.address(arg_z))) /* makestackblock0 expects the address to be in imm1  */
    3178         __(stfd fp_zero,macptr.domain(arg_z))
    3179         __(bx lr)
    3180 
    3181         /* Too big. Heap cons a gcable macptr  */
    3182 3:
    3183         __(TSP_Alloc_Fixed_Unboxed(0)) /* "raw" block to make the compiler happy  */
    3184 
    3185         __(mov arg_y,arg_z) /* save block size  */
    3186         __(mov arg_z,#t_value) /* clear-p arg to %new-gcable-ptr  */
    3187         __(set_nargs(2))
    3188         __(mov fname,#nrs.new_gcable_ptr)
    3189         __(jump_fname())
    3190 
    3191 /* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
    3192 /* the tstack.  Return the list in arg_z.  */
    3193 _spentry(makestacklist)
    3194         __(add imm0,arg_y,arg_y)
    3195         __(cmplri(cr1,imm0,((tstack_alloc_limit+1)-cons.size)))
    3196         __(addi imm0,imm0,tsp_frame.fixed_overhead)
    3197         __(bge cr1,3f)
    3198         __(TSP_Alloc_Var_Boxed(imm0,imm1))
    3199         __(mov imm1,arg_y)
    3200         __(cmpri(cr1,imm1,0))
    3201         __(mov arg_y,arg_z)
    3202         __(mov arg_z,#nil_value)
    3203         __(ldr imm2,[tsp,#tsp_frame.backlink])
    3204         __(la imm2,-tsp_frame.fixed_overhead+fulltag_cons(imm2))
    3205         __(b 2f)
    3206 1:
    3207         __(subi imm1,imm1,fixnum1)
    3208         __(cmpri(cr1,imm1,0))
    3209         __(_rplacd(imm2,arg_z))
    3210         __(_rplaca(imm2,arg_y))
    3211         __(mov arg_z,imm2)
    3212         __(subi imm2,imm2,cons.size)
    3213 2:
    3214         __(bne cr1,1b)
    3215         __(bx lr)
    3216 
    3217 3:
    3218         __(cmpri(cr1,arg_y,0))
    3219         __(TSP_Alloc_Fixed_Boxed(0))  /* make the compiler happy  */
    3220         __(mov imm1,arg_y) /* count  */
    3221         __(mov arg_y,arg_z) /* initial value  */
    3222         __(mov arg_z,#nil_value) /* result  */
    3223         __(b 5f)
    3224 4:
    3225         __(subi imm1,imm1,fixnum1)
    3226         __(cmpri(cr1,imm1,0))
    3227         __(Cons(arg_z,arg_y,arg_z))
    3228 5:
    3229         __(bne cr1,4b)
    3230         __(bx lr)
    3231 
    3232 /* subtype (boxed) vpushed before initial values. (Had better be a  */
    3233 /* node header subtag.) Nargs set to count of things vpushed.  */
    3234 
    3235 _spentry(stkgvector)
    3236         __(la imm0,-fixnum_one(nargs))
    3237         __(cmpri(cr1,imm0,0))
    3238         __(add imm1,vsp,nargs)
    3239         __(ldru(temp0,-node_size(imm1)))
    3240         __(slri(imm2,imm0,num_subtag_bits-fixnumshift))
    3241         __ifdef(`PPC64')
    3242          __(unbox_fixnum(imm3,temp0))
    3243          __(or imm2,imm3,imm2)
    3244         __else
    3245          __(rlwimi imm2,temp0,32-fixnumshift,32-num_subtag_bits,31)
    3246         __endif
    3247         __(dnode_align(imm0,imm0,node_size+tsp_frame.fixed_overhead))
    3248         __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
    3249         __(str(imm2,tsp_frame.data_offset(tsp)))
    3250         __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
    3251         __(la imm3,misc_header_offset(arg_z))
    3252         __(mov imm0,#fixnum1)
    3253         __(b 2f)
    3254 1:
    3255         __(addi imm0,imm0,fixnum1)
    3256         __(cmpr(cr1,imm0,nargs))
    3257         __(ldru(temp0,-node_size(imm1)))
    3258         __(stru(temp0,node_size(imm3)))
    3259 2:
    3260         __(bne cr1,1b)
    3261         __(add vsp,vsp,nargs)
    3262         __(bx lr)
    3263 
    3264 /* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
    3265 /* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
    3266 /* parameters must be "reasonable" (the  subtag must be valid, the element  */
    3267 /* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
    3268 /* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
    3269 /* proper header on it and its contents will be 0.   imm0 contains   */
    3270 /* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
    3271 /* This is intended for things like "make-array" and "%make-bignum" and the   */
    3272 /* like.  Things that involve creating small objects of known size can usually  */
    3273 /* do so inline with less hair.  */
    3274 
    3275 /* If this has to go out-of-line (to GC or whatever), it should do so via a   */
    3276 /* trap (or should otherwise ensure that both the LR and CTR are preserved   */
    3277 /* where the GC can find them.)  */
    3278 
    3279 
    3280 _spentry(misc_alloc)
    3281         __ifdef(`PPC64')
    3282          __(extract_unsigned_byte_bits_(imm2,arg_y,56))
    3283          __(unbox_fixnum(imm0,arg_z))
    3284          __(sldi imm2,arg_y,num_subtag_bits-fixnumshift)
    3285          __(clrldi imm1,imm0,64-nlowtagbits)
    3286          __(or imm0,imm2,imm0)
    3287          __(extract_fulltag(imm2,imm0))
    3288          __(cmpdi cr1,imm1,lowtag_nodeheader)
    3289          __(cmpdi cr2,imm2,ivector_class_64_bit)
    3290          __(bne- cr0,9f)
    3291          __(cmpdi cr3,imm2,ivector_class_32_bit)
    3292          __(cmpdi cr4,imm2,ivector_class_8_bit)
    3293          __(mov imm2,arg_y)
    3294          __(cmpdi cr5,imm1,subtag_bit_vector)
    3295          __(beq cr1,1f)
    3296          __(beq cr2,1f)
    3297          __(srdi imm2,imm2,1)
    3298          __(beq cr3,1f)
    3299          __(beq cr5,2f)
    3300          __(srdi imm2,imm2,1)
    3301          __(bne cr4,1f)
    3302          __(srdi imm2,imm2,1)
    3303 /* imm2 now = byte count.  Add 8 for header, 15 to align, then clear */
    3304 /* low four bits. */
    3305 1:
    3306          __(dnode_align(imm2,imm2,node_size))
    3307 
    3308          __(Misc_Alloc(arg_z,imm0,imm2))
    3309          __(bx lr)
    3310 2:      /* bit-vector case  */
    3311          __(addi imm2,arg_y,7<<fixnumshift)
    3312          __(srdi imm2,imm2,3+fixnumshift)
    3313          __(b 1b)
    3314 9:                     
    3315          __(uuo_interr(error_object_not_unsigned_byte_56,arg_y))
    3316         __else
    3317          __(extract_unsigned_byte_bits_(imm2,arg_y,24))
    3318          __(unbox_fixnum(imm0,arg_z))
    3319          __(extract_fulltag(imm1,imm0))
    3320          __(bne- cr0,9f)
    3321          __(cmpri(cr0,imm1,fulltag_nodeheader))
    3322          __(mov imm3,imm0)
    3323          __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
    3324          __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits )/* imm0 now = header  */
    3325          __(mov imm2,arg_y)
    3326          __(beq cr0,1f) /* do probe if node object (fixnum element count = byte count).  */
    3327          __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
    3328          __(bng cr1,1f) /* do probe if 32-bit imm object  */
    3329          __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
    3330          __(srwi imm2,imm2,1)
    3331          __(bgt cr0,2f)
    3332          __(bgt cr1,1f)
    3333          __(srwi imm2,imm2,1)
    3334         /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
    3335         /* low three bits.  */
    3336 1:
    3337          __(dnode_align(imm2,imm2,node_size))
    3338 
    3339          __(Misc_Alloc(arg_z,imm0,imm2))
    3340          __(bx lr)
    3341 2:
    3342          __(cmplri(imm3,subtag_double_float_vector))
    3343          __(slwi imm2,arg_y,1)
    3344          __(beq 1b)
    3345          __(addi imm2,arg_y,7<<fixnumshift)
    3346          __(srwi imm2,imm2,fixnumshift+3)
    3347          __(b 1b)
    3348 9:
    3349          __(uuo_interr(error_object_not_unsigned_byte_24,arg_y))
    3350         __endif
    3351        
    3352 /* almost exactly as above, but "swap exception handling info" */
    3353 /* on exit and return  */
    3354 /* Deprecated */       
    3355 _spentry(poweropen_ffcallX)
    3356         .long 0x7c800008        /* debug trap */
    3357 
    3358 
    3359 /* Destructuring-bind, macro-bind.  */
    3360    
    3361 /* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
    3362 /* likewise immX regs.  */
    3363 /* arg_z preserved, nothing else in particular defined on exit.  */
    3364 /* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
    3365 /* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
    3366 /* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
    3367 /* opt-supplied-p flag in PPC bit mask_initopt,  */
    3368 /* keyp flag in PPC bit mask_keyp,  */
    3369 /* &allow-other-keys flag in PPC bit mask_aok,  */
    3370 /* &rest flag in PPC bit mask_restp.  */
    3371 /* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
    3372 /* length key count.  */
    3373 
    3374 _spentry(macro_bind)
    3375         __ifdef(`PPC64')
    3376          __(mov whole_reg,arg_reg)
    3377          __(extract_fulltag(imm0,arg_reg))
    3378          __(cmpri(cr1,arg_reg,nil_value))
    3379          __(cmpri(cr0,imm0,fulltag_cons))
    3380          __(beq cr1,0f)
    3381          __(bne- cr0,1f)
    3382 0:             
    3383          __(_cdr(arg_reg,arg_reg))
    3384          __(b local_label(destbind1))
    3385         __else
    3386          __(mov whole_reg,arg_reg)
    3387          __(extract_lisptag(imm0,arg_reg))
    3388          __(cmpri(cr0,imm0,tag_list))
    3389          __(bne- cr0,1f)
    3390          __(_cdr(arg_reg,arg_reg))
    3391          __(b (local_label(destbind1)))
    3392         __endif
    3393 1:
    3394         __(mov arg_y,#XCALLNOMATCH)
    3395         __(mov arg_z,whole_reg)
    3396         __(set_nargs(2))
    3397         __(b _SPksignalerr)
    3398 
    3399 
    3400 _spentry(destructuring_bind)
    3401         __(mov whole_reg,arg_reg)
    3402         __(b local_label(destbind1))
    3403        
    3404 _spentry(destructuring_bind_inner)
    3405         __(mov whole_reg,arg_z)
    3406 local_label(destbind1):
    3407         /* Extract required arg count.  */
    3408         /* A bug in gas: can't handle shift count of "32" (= 0  */
    3409         ifelse(eval(mask_req_width+mask_req_start),eval(32),`
    3410         __(clrlwi. imm0,nargs,mask_req_start)
    3411         ',`
    3412         __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
    3413         ')
    3414         __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
    3415         __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
    3416         __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
    3417         __(cmpri(cr4,imm4,0))
    3418         __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
    3419         __(cmpri(cr5,imm4,0))
    3420         __(cmpri(cr1,imm1,0))
    3421         __(cmpri(cr2,imm2,0))
    3422         /* Save entry vsp in case of error.  */
    3423         __(mov imm4,vsp)
    3424         __(beq cr0,2f)
    3425 1:
    3426         __(cmpri(cr7,arg_reg,nil_value))
    3427         __ifdef(`PPC64')
    3428          __(extract_fulltag(imm3,arg_reg))
    3429          __(cmpri(cr3,imm3,fulltag_cons))
    3430         __else       
    3431          __(extract_lisptag(imm3,arg_reg))
    3432          __(cmpri(cr3,imm3,tag_list))
    3433         __endif
    3434         __(subi imm0,imm0,1)
    3435         __(cmpri(cr0,imm0,0))
    3436         __(beq cr7,toofew)
    3437         __(bne cr3,badlist)
    3438         __(ldr arg_x,[arg_reg,#cons.car])
    3439         __(ldr arg_reg,[arg_reg,#cons.cdr])
    3440         __(vpush1(arg_x))
    3441         __(bne cr0,1b)
    3442 2:
    3443         __(beq cr1,rest_keys)
    3444         __(bne cr2,opt_supp)
    3445         /* 'simple' &optionals:  no supplied-p, default to nil.  */
    3446 simple_opt_loop:
    3447         __(cmpri(cr0,arg_reg,nil_value))
    3448         __ifdef(`PPC64')
    3449          __(extract_fulltag(imm3,arg_reg))
    3450          __(cmpri(cr3,imm3,fulltag_cons))
    3451         __else
    3452          __(extract_lisptag(imm3,arg_reg))
    3453          __(cmpri(cr3,imm3,tag_list))
    3454         __endif
    3455         __(subi imm1,imm1,1)
    3456         __(cmpri(cr1,imm1,0))
    3457         __(mov imm5,#nil_value)
    3458         __(beq cr0,default_simple_opt)
    3459         __(bne cr3,badlist)
    3460         __(ldr arg_x,[arg_reg,#cons.car])
    3461         __(ldr arg_reg,[arg_reg,#cons.cdr])
    3462         __(vpush1(arg_x))
    3463         __(bne cr1,simple_opt_loop)
    3464         __(b rest_keys)
    3465 default_simple_opt_loop:
    3466         __(subi imm1,imm1,1)
    3467         __(cmpri(cr1,imm1,0))
    3468 default_simple_opt:
    3469         __(vpush1(imm5))
    3470         __(bne cr1,default_simple_opt_loop)
    3471         __(b rest_keys)
    3472         /* Provide supplied-p vars for the &optionals.  */
    3473 opt_supp:
    3474         __(mov arg_y,#t_value)
    3475 opt_supp_loop:
    3476         __(cmpri(cr0,arg_reg,nil_value))
    3477         __ifdef(`PPC64')
    3478          __(extract_fulltag(imm3,arg_reg))
    3479          __(cmpri(cr3,imm3,fulltag_cons))
    3480         __else       
    3481          __(extract_lisptag(imm3,arg_reg))
    3482          __(cmpri(cr3,imm3,tag_list))
    3483         __endif
    3484         __(subi imm1,imm1,1)
    3485         __(cmpri(cr1,imm1,0))
    3486         __(beq cr0,default_hard_opt)
    3487         __(bne cr3,badlist)
    3488         __(ldr arg_x,[arg_reg,#cons.car])
    3489         __(ldr arg_reg,[arg_reg,#cons.cdr])
    3490         __(vpush1(arg_x))
    3491         __(vpush1(arg_y))
    3492         __(bne cr1,opt_supp_loop)
    3493         __(b rest_keys)
    3494 default_hard_opt_loop:
    3495         __(subi imm1,imm1,1)
    3496         __(cmpri(cr1,imm1,0))
    3497 default_hard_opt:
    3498         __(vpush1(imm5))
    3499         __(vpush1(imm5))
    3500         __(bne cr1,default_hard_opt_loop)
    3501 rest_keys:
    3502         __(cmpri(cr0,arg_reg,nil_value))
    3503         __(bne cr5,have_rest)
    3504         __(bne cr4,have_keys)
    3505         __(bne cr0,toomany)
    3506         __(bx lr)
    3507 have_rest:
    3508         __(vpush1(arg_reg))
    3509         __(beqlr cr4)
    3510 have_keys:
    3511         /* Ensure that arg_reg contains a proper,even-length list.  */
    3512         /* Insist that its length is <= 512 (as a cheap circularity check.)  */
    3513         __(mov imm0,#256)
    3514         __(mov arg_x,arg_reg)
    3515 count_keys_loop:
    3516         __ifdef(`PPC64')
    3517          __(extract_fulltag(imm3,arg_x))
    3518          __(cmpri(cr3,imm3,fulltag_cons))
    3519         __else
    3520          __(extract_lisptag(imm3,arg_x))
    3521          __(cmpri(cr3,imm3,tag_list))
    3522         __endif
    3523         __(cmpri(cr0,arg_x,nil_value))
    3524         __(subi imm0,imm0,1)
    3525         __(cmpri(cr4,imm0,0))
    3526         __(beq cr0,counted_keys)
    3527         __(bne cr3,badlist)
    3528         __(ldr arg_x,[arg_x,#cons.cdr])
    3529         __ifdef(`PPC64')
    3530          __(extract_fulltag(imm3,arg_x))
    3531          __(cmpri(cr3,imm3,fulltag_cons))
    3532         __else
    3533          __(extract_lisptag(imm3,arg_x))
    3534          __(cmpri(cr3,imm3,tag_list))
    3535         __endif
    3536         __(blt cr4,toomany)
    3537         __(cmpri(cr0,arg_x,nil_value))
    3538         __(beq cr0,db_badkeys)
    3539         __(bne cr3,badlist)
    3540         __(ldr arg_x,[arg_x,#cons.cdr])
    3541         __(b count_keys_loop)
    3542 counted_keys:
    3543         /* We've got a proper, even-length list of key/value pairs in */
    3544         /* arg_reg. For each keyword var in the lambda-list, push a pair */
    3545         /* of NILs on the vstack.  */
    3546         __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
    3547         __(mov imm2,imm0)       /* save number of keys  */
    3548         __(mov imm5,#nil_value)
    3549         __(b push_pair_test)
    3550 push_pair_loop:
    3551         __(cmpri(cr0,imm0,1))
    3552         __(subi imm0,imm0,1)
    3553         __(vpush1(imm5))
    3554         __(vpush1(imm5))
    3555 push_pair_test:
    3556         __(bne cr0,push_pair_loop)
    3557         __(slwi imm2,imm2,dnode_shift)  /* pairs -> bytes  */
    3558         __(add imm2,vsp,imm2)           /* imm2 points below pairs  */
    3559         __(mov imm0,#0)                 /* count unknown keywords so far  */
    3560         __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
    3561         __(extrwi nargs,nargs,mask_key_width,mask_key_start)
    3562         /* Now, for each keyword/value pair in the list  */
    3563         /*  a) if the keyword is found in the keyword vector, set the  */
    3564         /*     corresponding entry on the vstack to the value and the  */
    3565         /*     associated supplied-p var to T.  */
    3566         /*  b) Regardless of whether or not the keyword is found,  */
    3567         /*     if :ALLOW-OTHER-KEYS is provided with a non-nil value, */
    3568         /*     set the low bit of imm1 to indicate that unknown keywords  */
    3569         /*     are acceptable. (This bit is pre-set above to the value */
    3570         /*     the encoded value of &allow_other_keys.) */
    3571         /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
    3572         /*     the count of unknown keywords in the high bits of imm1*/
    3573         /* At the end of the list, signal an error if any unknown keywords were seen  */
    3574         /* but not allowed.  Otherwise, return.  */
    3575 
    3576 match_keys_loop:
    3577         __(cmpri(cr0,arg_reg,nil_value))
    3578         __(mov imm0,#0)
    3579         __(mov imm3,#misc_data_offset)
    3580         __(beq cr0,matched_keys)
    3581         __(ldr arg_x,[arg_reg,#cons.car])
    3582         __(mov arg_y,#nrs.kallowotherkeys)
    3583         __(cmpr(cr3,arg_x,arg_y))       /* :ALLOW-OTHER-KEYS ?  */
    3584         __(ldr arg_reg,[arg_reg,#cons.cdr])
    3585         __(ldr arg_y,[arg_reg,#cons.car])
    3586         __(cmpr(cr4,imm0,nargs))
    3587         __(ldr arg_reg,[arg_reg,#cons.cdr])
    3588         __(b match_test)
    3589 match_loop:
    3590         __(ldrx(temp0,keyvect_reg,imm3))
    3591         __(cmpr(cr0,arg_x,temp0))
    3592         __(addi imm0,imm0,1)
    3593         __(cmpr(cr4,imm0,nargs))
    3594         __(addi imm3,imm3,node_size)
    3595         __(bne cr0,match_test)
    3596         /* Got a hit.  Unless this keyword's been seen already, set it.  */
    3597         __(slwi imm0,imm0,dnode_shift)
    3598         __(subf imm0,imm0,imm2)
    3599         __(ldr temp0,[imm0,#0])
    3600         __(cmpri(cr0,temp0,nil_value))
    3601         __(mov temp0,#t_value)
    3602         __(bne cr0,match_keys_loop)     /* already saw this  */
    3603         __(str(arg_y,node_size*1(imm0)))
    3604         __(str(temp0,node_size*0(imm0)))
    3605         __(bne cr3,match_keys_loop)
    3606         __(b match_keys_check_aok)
    3607 match_test:
    3608         __(bne cr4,match_loop)
    3609         __(beq cr3,match_keys_check_aok)
    3610         __(addi imm1,imm1,node_size)
    3611         __(b match_keys_loop)
    3612 match_keys_check_aok:
    3613         __(andi. imm0,imm1,2)  /* check "seen-aok" bit in imm1 */
    3614         __(cmpri cr1,arg_y,nil_value) /* check value */
    3615         __(ori imm1,imm1,2)
    3616         __(bne cr0,match_keys_loop) /* duplicate aok */
    3617         __(beq cr1,match_keys_loop)
    3618         __(ori imm1,imm1,1)
    3619         __(b match_keys_loop)
    3620 matched_keys:
    3621         __(clrrwi. imm0,imm1,2)
    3622         __(beqlr)
    3623         __(andi. imm1,imm1,1)
    3624         __(bnelr)
    3625         /* Some unrecognized keywords.  Complain generically about  */
    3626         /* invalid keywords.  */
    3627 db_badkeys:
    3628         __(mov arg_y,#XBADKEYS)
    3629         __(b destructure_error)
    3630 toomany:
    3631         __(mov arg_y,#XCALLTOOMANY)
    3632         __(b destructure_error)
    3633 toofew:
    3634         __(mov arg_y,#XCALLTOOFEW)
    3635         __(b destructure_error)
    3636 badlist:
    3637         __(mov arg_y,#XCALLNOMATCH)
    3638         /* b destructure_error  */
    3639 destructure_error:
    3640         __(mov vsp,imm4)                /* undo everything done to the stack  */
    3641         __(mov arg_z,whole_reg)
    3642         __(set_nargs(2))
    3643         __(b _SPksignalerr)
    3644        
    3645 /* vpush the values in the value set atop the vsp, incrementing nargs.  */
    3646 /* Discard the tsp frame; leave values atop the vsp.  */
    3647 
    3648 _spentry(recover_values)
    3649 
    3650 /* First, walk the segments reversing the pointer to previous segment pointers  */
    3651 /* Can tell the end because that previous segment pointer is the prev tsp pointer  */
    3652         __(ldr imm0,[tsp,#tsp_frame.backlink]) /* previous tsp  */
    3653         __(mov imm1,tsp) /* current segment  */
    3654         __(mov imm2,tsp) /* last segment  */
    3655 local_label(walkloop):
    3656         __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment  */
    3657         __(cmpr(cr0,imm0,imm3)) /* last segment?  */
    3658         __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
    3659         __(mov imm2,imm1) /* last segment <- current segment  */
    3660         __(mov imm1,imm3) /* current segment <- next segment  */
    3661         __(bne cr0,local_label(walkloop))
    3662 
    3663         /* the final segment ptr is now in imm2  */
    3664         /* walk backwards, pushing values on VSP and incrementing NARGS  */
    3665 local_label(pushloop):
    3666         __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment  */
    3667         __(cmpri(cr0,imm0,0))
    3668         __(cmpr(cr1,imm2,tsp))
    3669         __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
    3670         __(add imm3,imm3,imm0)
    3671         __(add nargs,nargs,imm0)
    3672         __(b 2f)
    3673 1:
    3674         __(ldru(arg_z,-node_size(imm3)))
    3675         __(cmpri(cr0,imm0,fixnum_one))
    3676         __(subi imm0,imm0,fixnum_one)
    3677         __(vpush1(arg_z))
    3678 2:
    3679         __(bne cr0,1b)
    3680         __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment  */
    3681         __(bne cr1,local_label(pushloop))
    3682         __(unlink(tsp))
    3683         __(bx lr)
    3684 
    3685        
    3686 /* Go out of line to do this.  Sheesh.  */
    3687 
    3688 _spentry(vpopargregs)
    3689         __(cmpri(cr0,nargs,0))
    3690         __(cmpri(cr1,nargs,2<<fixnumshift))
    3691         __(beqlr cr0)
    3692         __(beq cr1,local_label(yz))
    3693         __(blt cr1,local_label(z))
    3694         __(ldr arg_z,[vsp,#node_size*0])
    3695         __(ldr arg_y,[vsp,#node_size*1])
    3696         __(ldr arg_x,[vsp,#node_size*2])
    3697         __(la vsp,node_size*3(vsp))
    3698         __(bx lr)
    3699 local_label(yz):
    3700         __(ldr arg_z,[vsp,#node_size*0])
    3701         __(ldr arg_y,[vsp,#node_size*1])
    3702         __(la vsp,node_size*2(vsp))
    3703         __(bx lr)
    3704 local_label(z):
    3705         __(ldr arg_z,[vsp,#node_size*0])
    3706         __(la vsp,node_size*1(vsp))
    3707         __(bx lr)
    3708 
    3709 /* If arg_z is an integer, return in imm0 something whose sign  */
    3710 /* is the same as arg_z's.  If not an integer, error.  */
    3711 _spentry(integer_sign)
    3712         __(extract_typecode(imm0,arg_z))
    3713         __(cmpri(cr1,imm0,tag_fixnum))
    3714         __(cmpri(cr0,imm0,subtag_bignum))
    3715         __(mov imm0,arg_z)
    3716         __(beqlr+ cr1)
    3717         __(bne- cr0,1f)
    3718         __(getvheader(imm0,arg_z))
    3719         __ifdef(`PPC64')
    3720          __(header_size(imm0,imm0))
    3721          __(sldi imm0,imm0,2)
    3722         __else
    3723          __(header_length(imm0,imm0)) /* boxed length = scaled size  */
    3724         __endif
    3725         __(addi imm0,imm0,misc_data_offset-4) /* bias, less 1 element  */
    3726         __(lwzx imm0,arg_z,imm0)
    3727         __(cmpwi cr0,imm0,0)
    3728         __(mov imm0,#1)
    3729         __(bgelr cr0)
    3730         __(mov imm0,#-1)
    3731         __(bx lr)
    3732 1:
    3733         __(uuo_interr(error_object_not_integer,arg_z))
    3734 
    3735 /* like misc_set, only pass the (boxed) subtag in temp0  */
    3736 _spentry(subtag_misc_set)
    3737         __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
    3738         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    3739         __(vector_length(imm0,arg_x,imm1))
    3740         __(trlge(arg_y,imm0))
    3741         __(unbox_fixnum(imm1,temp0))
    3742 local_label(misc_set_common):
    3743         __ifdef(`PPC64')
    3744          __(slwi imm1,imm1,3)
    3745          __(mov imm0,#LO(local_label(misc_set_jmp)))
    3746          __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
    3747          __(ldx imm0,imm0,imm1)
    3748          __(mtctr imm0)
    3749          __(bctr)
    3750 local_label(misc_set_jmp):             
    3751         /* 00-0f  */
    3752          .quad local_label(misc_set_invalid) /* 00 even_fixnum  */
    3753          .quad local_label(misc_set_invalid) /* 01 imm_0  */
    3754          .quad local_label(misc_set_invalid) /* 02 immheader_0  */
    3755          .quad _SPgvset /* 03 function  */
    3756          .quad local_label(misc_set_invalid) /* 04 cons  */
    3757          .quad local_label(misc_set_invalid) /* 05 imm_1  */
    3758          .quad local_label(misc_set_invalid) /* 06 immheader_1  */
    3759          .quad _SPgvset /* 07 catch_frame  */
    3760          .quad local_label(misc_set_invalid) /* 08 odd_fixnum  */
    3761          .quad local_label(misc_set_invalid) /* 09 imm_2  */
    3762          .quad local_label(misc_set_u32) /* 0a code_vector  */
    3763          .quad _SPgvset /* 0b slot_vector  */
    3764          .quad local_label(misc_set_invalid) /* 0c misc  */
    3765          .quad local_label(misc_set_invalid) /* 0d imm3  */
    3766          .quad local_label(misc_set_invalid) /* 0e immheader_3  */
    3767          .quad _SPgvset /* 0f ratio  */
    3768         /* 10-1f  */
    3769          .quad local_label(misc_set_invalid) /* 10 even_fixnum  */
    3770          .quad local_label(misc_set_invalid) /* 11 imm_0  */
    3771          .quad local_label(misc_set_invalid) /* 12 immheader_0  */
    3772          .quad _SPgvset /* 13 symbol_0  */
    3773          .quad local_label(misc_set_invalid) /* 14 cons  */
    3774          .quad local_label(misc_set_invalid) /* 15 imm_1  */
    3775          .quad local_label(misc_set_invalid) /* 16 immheader_1  */
    3776          .quad _SPgvset /* 17 lisp_tread  */
    3777          .quad local_label(misc_set_invalid) /* 18 odd_fixnum  */
    3778          .quad local_label(misc_set_invalid) /* 19 imm_2  */
    3779          .quad local_label(misc_set_u32) /* 1a xcode_vector  */
    3780          .quad _SPgvset /* 1b instance  */
    3781          .quad local_label(misc_set_invalid) /* 1c misc  */
    3782          .quad local_label(misc_set_invalid) /* 1d imm3  */
    3783          .quad local_label(misc_set_u64) /* 1e macptr  */
    3784          .quad _SPgvset /* 1f complex  */
    3785         /* 20-2f  */
    3786          .quad local_label(misc_set_invalid) /* 20 even_fixnum  */
    3787          .quad local_label(misc_set_invalid) /* 21 imm_0  */
    3788          .quad local_label(misc_set_invalid) /* 22 immheader_0  */
    3789          .quad local_label(misc_set_invalid) /* 23 nodeheader_0  */
    3790          .quad local_label(misc_set_invalid) /* 24 cons  */
    3791          .quad local_label(misc_set_invalid) /* 25 imm_1  */
    3792          .quad local_label(misc_set_invalid) /* 26 immheader_1  */
    3793          .quad _SPgvset /* 27 lock  */
    3794          .quad local_label(misc_set_invalid) /* 28 odd_fixnum  */
    3795          .quad local_label(misc_set_invalid) /* 29 imm_2  */
    3796          .quad local_label(misc_set_u32) /* 2a bignum  */
    3797          .quad _SPgvset /* 2b struct  */
    3798          .quad local_label(misc_set_invalid) /* 2c misc  */
    3799          .quad local_label(misc_set_invalid) /* 2d imm3  */
    3800          .quad local_label(misc_set_u64) /* 2e dead_macptr  */
    3801          .quad local_label(misc_set_invalid) /* 2f nodeheader_3  */
    3802         /* 30-3f  */
    3803          .quad local_label(misc_set_invalid) /* 30 even_fixnum  */
    3804          .quad local_label(misc_set_invalid) /* 31 imm_0  */
    3805          .quad local_label(misc_set_invalid) /* 32 immheader_0  */
    3806          .quad local_label(misc_set_invalid) /* 33 nodeheader_0  */
    3807          .quad local_label(misc_set_invalid) /* 34 cons  */
    3808          .quad local_label(misc_set_invalid) /* 35 imm_1  */
    3809          .quad local_label(misc_set_invalid) /* 36 immheader_1  */
    3810          .quad _SPgvset /* 37 hash_vector  */
    3811          .quad local_label(misc_set_invalid) /* 38 odd_fixnum  */
    3812          .quad local_label(misc_set_invalid) /* 39 imm_2  */
    3813          .quad local_label(misc_set_u32) /* 3a double_float  */
    3814          .quad _SPgvset /* 3b istruct  */
    3815          .quad local_label(misc_set_invalid) /* 3c misc  */
    3816          .quad local_label(misc_set_invalid) /* 3d imm3  */
    3817          .quad local_label(misc_set_invalid) /* 3e immheader_3  */
    3818          .quad local_label(misc_set_invalid) /* 3f nodeheader_3  */
    3819         /* 40-4f  */
    3820          .quad local_label(misc_set_invalid) /* 40 even_fixnum  */
    3821          .quad local_label(misc_set_invalid) /* 41 imm_0  */
    3822          .quad local_label(misc_set_invalid) /* 42 immheader_0  */
    3823          .quad local_label(misc_set_invalid) /* 43 nodeheader_0  */
    3824          .quad local_label(misc_set_invalid) /* 44 cons  */
    3825          .quad local_label(misc_set_invalid) /* 45 imm_1  */
    3826          .quad local_label(misc_set_invalid) /* 46 immheader_1  */
    3827          .quad _SPgvset /* 47 pool  */
    3828          .quad local_label(misc_set_invalid) /* 48 odd_fixnum  */
    3829          .quad local_label(misc_set_invalid) /* 49 imm_2  */
    3830          .quad local_label(misc_set_invalid) /* 4a immheader_2  */
    3831          .quad _SPgvset /* 4b value_cell_2  */
    3832          .quad local_label(misc_set_invalid) /* 4c misc  */
    3833          .quad local_label(misc_set_invalid) /* 4d imm3  */
    3834          .quad local_label(misc_set_invalid) /* 4e immheader_3  */
    3835          .quad local_label(misc_set_invalid) /* 4f nodeheader_3  */
    3836         /* 50-5f  */
    3837          .quad local_label(misc_set_invalid) /* 50 even_fixnum  */
    3838          .quad local_label(misc_set_invalid) /* 51 imm_0  */
    3839          .quad local_label(misc_set_invalid) /* 52 immheader_0  */
    3840          .quad local_label(misc_set_invalid) /* 53 nodeheader_0  */
    3841          .quad local_label(misc_set_invalid) /* 54 cons  */
    3842          .quad local_label(misc_set_invalid) /* 55 imm_1  */
    3843          .quad local_label(misc_set_invalid) /* 56 immheader_1  */
    3844          .quad _SPgvset /* 57 weak  */
    3845          .quad local_label(misc_set_invalid) /* 58 odd_fixnum  */
    3846          .quad local_label(misc_set_invalid) /* 59 imm_2  */
    3847          .quad local_label(misc_set_invalid) /* 5a immheader_2  */
    3848          .quad _SPgvset /* 5b xfunction  */
    3849          .quad local_label(misc_set_invalid) /* 5c misc  */
    3850          .quad local_label(misc_set_invalid) /* 5d imm3  */
    3851          .quad local_label(misc_set_invalid) /* 5e immheader_3  */
    3852          .quad local_label(misc_set_invalid) /* 5f nodeheader_3  */
    3853         /* 60-6f  */
    3854          .quad local_label(misc_set_invalid) /* 60 even_fixnum  */
    3855          .quad local_label(misc_set_invalid) /* 61 imm_0  */
    3856          .quad local_label(misc_set_invalid) /* 62 immheader_0  */
    3857          .quad local_label(misc_set_invalid) /* 63 nodeheader_0  */
    3858          .quad local_label(misc_set_invalid) /* 64 cons  */
    3859          .quad local_label(misc_set_invalid) /* 65 imm_1  */
    3860          .quad local_label(misc_set_invalid) /* 66 immheader_1  */
    3861          .quad _SPgvset /* 67 package  */
    3862          .quad local_label(misc_set_invalid) /* 68 odd_fixnum  */
    3863          .quad local_label(misc_set_invalid) /* 69 imm_2  */
    3864          .quad local_label(misc_set_invalid) /* 6a immheader_2  */
    3865          .quad local_label(misc_set_invalid) /* 6b nodeheader_2  */
    3866          .quad local_label(misc_set_invalid) /* 6c misc  */
    3867          .quad local_label(misc_set_invalid) /* 6d imm3  */
    3868          .quad local_label(misc_set_invalid) /* 6e immheader_3  */
    3869          .quad local_label(misc_set_invalid) /* 6f nodeheader_3  */
    3870         /* 70-7f  */
    3871          .quad local_label(misc_set_invalid) /* 70 even_fixnum  */
    3872          .quad local_label(misc_set_invalid) /* 71 imm_0  */
    3873          .quad local_label(misc_set_invalid) /* 72 immheader_0  */
    3874          .quad local_label(misc_set_invalid) /* 73 nodeheader_0  */
    3875          .quad local_label(misc_set_invalid) /* 74 cons  */
    3876          .quad local_label(misc_set_invalid) /* 75 imm_1  */
    3877          .quad local_label(misc_set_invalid) /* 76 immheader_1  */
    3878          .quad local_label(misc_set_invalid) /* 77 nodeheader_1  */
    3879          .quad local_label(misc_set_invalid) /* 78 odd_fixnum  */
    3880          .quad local_label(misc_set_invalid) /* 79 imm_2  */
    3881          .quad local_label(misc_set_invalid) /* 7a immheader_2  */
    3882          .quad local_label(misc_set_invalid) /* 7b nodeheader_2  */
    3883          .quad local_label(misc_set_invalid) /* 7c misc  */
    3884          .quad local_label(misc_set_invalid) /* 7d imm3  */
    3885          .quad local_label(misc_set_invalid) /* 7e immheader_3  */
    3886          .quad local_label(misc_set_invalid) /* 7f nodeheader_3  */
    3887         /* 80-8f  */
    3888          .quad local_label(misc_set_invalid) /* 80 even_fixnum  */
    3889          .quad local_label(misc_set_invalid) /* 81 imm_0  */
    3890          .quad local_label(misc_set_invalid) /* 82 immheader_0  */
    3891          .quad local_label(misc_set_invalid) /* 83 nodeheader_0  */
    3892          .quad local_label(misc_set_invalid) /* 84 cons  */
    3893          .quad local_label(misc_set_invalid) /* 85 imm_1  */
    3894          .quad local_label(misc_set_invalid) /* 86 immheader_1  */
    3895          .quad _SPgvset /* 87 arrayH  */
    3896          .quad local_label(misc_set_invalid) /* 88 odd_fixnum  */
    3897          .quad local_label(misc_set_invalid) /* 89 imm_2  */
    3898          .quad local_label(misc_set_invalid) /* 8a immheader_2  */
    3899          .quad _SPgvset /* 8b vectorH  */
    3900          .quad local_label(misc_set_invalid) /* 8c misc  */
    3901          .quad local_label(misc_set_invalid) /* 8d imm3  */
    3902          .quad local_label(misc_set_invalid) /* 8e immheader_3  */
    3903          .quad _SPgvset /* 8f simple_vector  */
    3904         /* 90-9f  */
    3905          .quad local_label(misc_set_invalid) /* 90 even_fixnum  */
    3906          .quad local_label(misc_set_invalid) /* 91 imm_0  */
    3907          .quad local_label(misc_set_s8) /* 92 s8  */
    3908          .quad local_label(misc_set_invalid) /* 93 nodeheader_0  */
    3909          .quad local_label(misc_set_invalid) /* 94 cons  */
    3910          .quad local_label(misc_set_invalid) /* 95 imm_1  */
    3911          .quad local_label(misc_set_s16) /* 96 immheader_1  */
    3912          .quad local_label(misc_set_invalid) /* 97 nodeheader_1  */
    3913          .quad local_label(misc_set_invalid) /* 98 odd_fixnum  */
    3914          .quad local_label(misc_set_invalid) /* 99 imm_2  */
    3915          .quad local_label(misc_set_s32) /* 9a s32  */
    3916          .quad local_label(misc_set_invalid) /* 9b nodeheader_2  */
    3917          .quad local_label(misc_set_invalid) /* 9c misc  */
    3918          .quad local_label(misc_set_invalid) /* 9d imm3  */
    3919          .quad local_label(misc_set_s64) /* 9e s64  */
    3920          .quad local_label(misc_set_invalid) /* 9f nodeheader_3  */
    3921         /* a0-af  */
    3922          .quad local_label(misc_set_invalid) /* a0 even_fixnum  */
    3923          .quad local_label(misc_set_invalid) /* a1 imm_0  */
    3924          .quad local_label(misc_set_u8) /* a2 u8  */
    3925          .quad local_label(misc_set_invalid) /* a3 nodeheader_0  */
    3926          .quad local_label(misc_set_invalid) /* a4 cons  */
    3927          .quad local_label(misc_set_invalid) /* a5 imm_1  */
    3928          .quad local_label(misc_set_u16) /* a6 u16  */
    3929          .quad local_label(misc_set_invalid) /* a7 nodeheader_1  */
    3930          .quad local_label(misc_set_invalid) /* a8 odd_fixnum  */
    3931          .quad local_label(misc_set_invalid) /* a9 imm_2  */
    3932          .quad local_label(misc_set_u32) /* aa u32  */
    3933          .quad local_label(misc_set_invalid) /* ab nodeheader_2  */
    3934          .quad local_label(misc_set_invalid) /* ac misc  */
    3935          .quad local_label(misc_set_invalid) /* ad imm3  */
    3936          .quad local_label(misc_set_u64) /* ae u64  */
    3937          .quad local_label(misc_set_invalid) /* af nodeheader_3  */
    3938         /* b0-bf  */
    3939          .quad local_label(misc_set_invalid) /* b0 even_fixnum  */
    3940          .quad local_label(misc_set_invalid) /* b1 imm_0  */
    3941          .quad local_label(misc_set_invalid) /* b2 immheader_0  */
    3942          .quad local_label(misc_set_invalid) /* b3 nodeheader_0  */
    3943          .quad local_label(misc_set_invalid) /* b4 cons  */
    3944          .quad local_label(misc_set_invalid) /* b5 imm_1  */
    3945          .quad local_label(misc_set_invalid) /* b6 immheader_1  */
    3946          .quad local_label(misc_set_invalid) /* b7 nodeheader_1  */
    3947          .quad local_label(misc_set_invalid) /* b8 odd_fixnum  */
    3948          .quad local_label(misc_set_invalid) /* b9 imm_2  */
    3949          .quad local_label(misc_set_single_float_vector) /* ba sf vector  */
    3950          .quad local_label(misc_set_invalid) /* bb nodeheader_2  */
    3951          .quad local_label(misc_set_invalid) /* bc misc  */
    3952          .quad local_label(misc_set_invalid) /* bd imm3  */
    3953          .quad local_label(misc_set_fixnum_vector) /* be fixnum_vector  */
    3954          .quad local_label(misc_set_invalid) /* bf nodeheader_3  */
    3955         /* c0-cf  */
    3956          .quad local_label(misc_set_invalid) /* c0 even_fixnum  */
    3957          .quad local_label(misc_set_invalid) /* c1 imm_0  */
    3958          .quad local_label(misc_set_invalid) /* c2 immheader_0  */
    3959          .quad local_label(misc_set_invalid) /* c3 nodeheader_0  */
    3960          .quad local_label(misc_set_invalid) /* c4 cons  */
    3961          .quad local_label(misc_set_invalid) /* c5 imm_1  */
    3962          .quad local_label(misc_set_invalid) /* c6 immheader_1  */
    3963          .quad local_label(misc_set_invalid) /* c7 nodeheader_1  */
    3964          .quad local_label(misc_set_invalid) /* c8 odd_fixnum  */
    3965          .quad local_label(misc_set_invalid) /* c9 imm_2  */
    3966          .quad local_label(misc_set_invalid) /* ca immheader_2  */
    3967          .quad local_label(misc_set_invalid) /* cb nodeheader_2  */
    3968          .quad local_label(misc_set_invalid) /* cc misc  */
    3969          .quad local_label(misc_set_invalid) /* cd imm3  */
    3970          .quad local_label(misc_set_double_float_vector) /* ce double-float vector  */
    3971          .quad local_label(misc_set_invalid) /* cf nodeheader_3  */
    3972         /* d0-df  */
    3973          .quad local_label(misc_set_invalid) /* d0 even_fixnum  */
    3974          .quad local_label(misc_set_invalid) /* d1 imm_0  */
    3975          .quad local_label(misc_set_string) /* d2 string  */
    3976          .quad local_label(misc_set_invalid) /* d3 nodeheader_0  */
    3977          .quad local_label(misc_set_invalid) /* d4 cons  */
    3978          .quad local_label(misc_set_invalid) /* d5 imm_1  */
    3979          .quad local_label(misc_set_invalid) /* d6 immheader_1  */
    3980          .quad local_label(misc_set_invalid) /* d7 nodeheader_1  */
    3981          .quad local_label(misc_set_invalid) /* d8 odd_fixnum  */
    3982          .quad local_label(misc_set_invalid) /* d9 imm_2  */
    3983          .quad local_label(misc_set_new_string) /* da new_string  */
    3984          .quad local_label(misc_set_invalid) /* db nodeheader_2  */
    3985          .quad local_label(misc_set_invalid) /* dc misc  */
    3986          .quad local_label(misc_set_invalid) /* dd imm3  */
    3987          .quad local_label(misc_set_invalid) /* de immheader_3  */
    3988          .quad local_label(misc_set_invalid) /* df nodeheader_3  */
    3989         /* e0-ef  */
    3990          .quad local_label(misc_set_invalid) /* e0 even_fixnum  */
    3991          .quad local_label(misc_set_invalid) /* e1 imm_0  */
    3992          .quad local_label(misc_set_invalid) /* e2 immheader_0  */
    3993          .quad local_label(misc_set_invalid) /* e3 nodeheader_0  */
    3994          .quad local_label(misc_set_invalid) /* e4 cons  */
    3995          .quad local_label(misc_set_invalid) /* e5 imm_1  */
    3996          .quad local_label(misc_set_invalid) /* e6 immheader_1  */
    3997          .quad local_label(misc_set_invalid) /* e7 nodeheader_1  */
    3998          .quad local_label(misc_set_invalid) /* e8 odd_fixnum  */
    3999          .quad local_label(misc_set_invalid) /* e9 imm_2  */
    4000          .quad local_label(misc_set_invalid) /* ea immheader_2  */
    4001          .quad local_label(misc_set_invalid) /* eb nodeheader_2  */
    4002          .quad local_label(misc_set_invalid) /* ec misc  */
    4003          .quad local_label(misc_set_invalid) /* ed imm3  */
    4004          .quad local_label(misc_set_invalid) /* ee immheader_3  */
    4005          .quad local_label(misc_set_invalid) /* ef nodeheader_3  */
    4006         /* f0-ff  */
    4007          .quad local_label(misc_set_invalid) /* f0 even_fixnum  */
    4008          .quad local_label(misc_set_invalid) /* f1 imm_0  */
    4009          .quad local_label(misc_set_invalid) /* f2 immheader_0  */
    4010          .quad local_label(misc_set_invalid) /* f3 nodeheader_0  */
    4011          .quad local_label(misc_set_invalid) /* f4 cons  */
    4012          .quad local_label(misc_set_invalid) /* f5 imm_1  */
    4013          .quad local_label(misc_set_bit_vector) /* f6 bit_vector  */
    4014          .quad local_label(misc_set_invalid) /* f7 nodeheader_1  */
    4015          .quad local_label(misc_set_invalid) /* f8 odd_fixnum  */
    4016          .quad local_label(misc_set_invalid) /* f9 imm_2  */
    4017          .quad local_label(misc_set_invalid) /* fa immheader_2  */
    4018          .quad local_label(misc_set_invalid) /* fb nodeheader_2  */
    4019          .quad local_label(misc_set_invalid) /* fc misc  */
    4020          .quad local_label(misc_set_invalid) /* fd imm3  */
    4021          .quad local_label(misc_set_invalid) /* fe immheader_3  */
    4022          .quad local_label(misc_set_invalid) /* ff nodeheader_3  */
    4023 
    4024 local_label(misc_set_bit_vector):               
    4025          __(lis imm3,0x8000)
    4026          __(extract_unsigned_byte_bits_(imm0,arg_z,1))
    4027          __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
    4028          __(srdi imm0,arg_y,5+fixnumshift)
    4029          __(srw imm3,imm3,imm1)
    4030          __(bne local_label(misc_set_bad))
    4031          __(cmpdi cr0,arg_z,0)
    4032          __(sldi imm0,imm0,2)
    4033          __(la imm0,misc_data_offset(imm0))
    4034          __(lwzx imm2,arg_x,imm0)
    4035          __(beq 1f)
    4036          __(or imm2,imm3,imm2)
    4037          __(stwx imm2,arg_x,imm0)
    4038          __(bx lr)
    4039 1:       __(andc imm2,imm2,imm3)
    4040          __(stwx imm2,arg_x,imm0)
    4041          __(bx lr)
    4042 local_label(misc_set_s16):
    4043          __(extract_lisptag(imm2,arg_z))
    4044          __(sldi imm0,arg_z,64-(16+fixnumshift))
    4045          __(srdi imm1,arg_y,2)
    4046          __(cmpdi cr7,imm2,tag_fixnum)
    4047          __(sradi imm0,imm0,64-(16+fixnumshift))
    4048          __(cmpd imm0,arg_z)
    4049          __(la imm1,misc_data_offset(imm1))
    4050          __(unbox_fixnum(imm0,arg_z))
    4051          __(bne local_label(misc_set_bad))
    4052          __(bne cr7,local_label(misc_set_bad))
    4053          __(sthx imm0,arg_x,imm1)
    4054          __(bx lr)
    4055 local_label(misc_set_u16):
    4056          __(extract_unsigned_byte_bits_(imm0,arg_z,16))
    4057          __(srdi imm1,arg_y,2)               
    4058          __(unbox_fixnum(imm0,arg_z))
    4059          __(la imm1,misc_data_offset(imm1))
    4060          __(bne local_label(misc_set_bad))
    4061          __(sthx imm0,arg_x,imm1)
    4062          __(bx lr)
    4063 local_label(misc_set_single_float_vector):
    4064          __(extract_fulltag(imm3,arg_z))
    4065          __(srdi imm4,arg_y,1)
    4066          __(cmpdi cr3,imm3,subtag_single_float)
    4067          __(la imm4,misc_data_offset(imm4))
    4068          __(bne cr3,local_label(misc_set_bad))
    4069          __(srdi imm0,arg_z,32)
    4070          __(stwx imm0,arg_x,imm4)
    4071          __(bx lr)
    4072 local_label(misc_set_s32):
    4073          __(extract_lisptag(imm2,arg_z))
    4074          __(srdi imm4,arg_y,1)
    4075          __(unbox_fixnum(imm0,arg_z))
    4076          __(cmpdi imm2,tag_fixnum)
    4077          __(sldi imm1,imm0,32)
    4078          __(sradi imm1,imm1,32)
    4079          __(la imm4,misc_data_offset(imm4))
    4080          __(bne local_label(misc_set_bad))
    4081          __(cmpd imm1,imm0)
    4082          __(bne local_label(misc_set_bad))
    4083          __(stwx imm0,arg_x,imm4)
    4084          __(bx lr)
    4085 local_label(misc_set_u32):             
    4086          __(extract_unsigned_byte_bits_(imm0,arg_z,32))
    4087          __(srdi imm4,arg_y,1)
    4088          __(la imm4,misc_data_offset(imm4))
    4089          __(unbox_fixnum(imm0,arg_z))
    4090          __(bne local_label(misc_set_bad))
    4091          __(stwx imm0,arg_x,imm4)
    4092          __(bx lr)
    4093 local_label(misc_set_new_string):
    4094          __(extract_lowbyte(imm0,arg_z))
    4095          __(srdi imm4,arg_y,1)
    4096          __(cmpdi imm0,subtag_character)
    4097          __(la imm4,misc_data_offset(imm4))
    4098          __(srwi imm0,arg_z,charcode_shift)
    4099          __(bne local_label(misc_set_bad))
    4100          __(stwx imm0,arg_x,imm4)
    4101          __(bx lr)
    4102 local_label(misc_set_string):     
    4103          __(extract_lowbyte(imm0,arg_z))               
    4104          __(srdi imm4,arg_y,3)
    4105          __(cmpdi imm0,subtag_character)
    4106          __(la imm4,misc_data_offset(imm4))
    4107          __(bne cr0,local_label(misc_set_bad))
    4108          __(srwi imm0,arg_z,charcode_shift)
    4109          __(stbx imm0,arg_x,imm4)
    4110          __(bx lr)
    4111 local_label(misc_set_s8):     
    4112          __(extract_lisptag(imm2,arg_z))
    4113          __(unbox_fixnum(imm0,arg_z))
    4114          __(cmpdi cr2,imm2,tag_fixnum)
    4115          __(srdi imm4,arg_y,3)
    4116          __(sldi imm1,imm0,56)
    4117          __(sradi imm1,imm1,56)
    4118          __(cmpd imm1,imm0)
    4119          __(bne cr2,local_label(misc_set_bad))
    4120          __(la imm4,misc_data_offset(imm4))
    4121          __(bne local_label(misc_set_bad))
    4122          __(stbx imm0,arg_x,imm4)
    4123          __(bx lr)
    4124 local_label(misc_set_u8):     
    4125          __(extract_unsigned_byte_bits_(imm0,arg_z,8))
    4126          __(srdi imm4,arg_y,3)
    4127          __(unbox_fixnum(imm0,arg_z))
    4128          __(la imm4,misc_data_offset(imm4))
    4129          __(bne local_label(misc_set_bad))
    4130          __(stbx imm0,arg_x,imm4)
    4131          __(bx lr)
    4132 local_label(misc_set_u64):
    4133          __(extract_lisptag(imm0,arg_z))
    4134          __(extract_fulltag(imm2,arg_z))
    4135          __(cmpdi cr0,arg_z,0)
    4136          __(cmpdi cr7,imm0,0)
    4137          __(cmpdi cr6,imm2,fulltag_misc)
    4138          __(la imm4,misc_data_offset(arg_y))
    4139          __(bne cr7,local_label(setu64_maybe_bignum))
    4140          __(unbox_fixnum(imm0,arg_z))
    4141          __(blt cr0,local_label(misc_set_bad))
    4142          __(stdx imm0,arg_x,imm4)
    4143          __(bx lr)
    4144 local_label(setu64_maybe_bignum):
    4145          __(bne cr6,local_label(misc_set_bad))
    4146          __(getvheader(imm1,arg_z))
    4147          __(ld imm0,misc_data_offset(arg_z))
    4148          __(rotldi imm0,imm0,32)
    4149          __(cmpdi cr2,imm1,two_digit_bignum_header)
    4150          __(cmpdi cr3,imm1,three_digit_bignum_header)
    4151          __(cmpdi cr0,imm0,0)
    4152          __(beq cr2,1f)
    4153          __(bne cr3,local_label(misc_set_bad))
    4154          __(lwz imm3,misc_data_offset+8(arg_z))
    4155          __(cmpwi cr0,imm3,0)
    4156          __(bne cr0,local_label(misc_set_bad))
    4157          __(stdx imm0,arg_x,imm4)
    4158          __(bx lr)
    4159 1:       __(blt cr0,local_label(misc_set_bad))
    4160          __(stdx imm0,arg_x,imm4)
    4161          __(bx lr)
    4162 local_label(misc_set_double_float_vector):
    4163          __(extract_typecode(imm0,arg_z))
    4164          __(la imm4,misc_data_offset(arg_y))
    4165          __(cmpdi imm0,subtag_double_float)
    4166          __(bne local_label(misc_set_bad))
    4167          __(ld imm0,misc_dfloat_offset(arg_z))
    4168          __(stdx imm0,arg_x,imm4)
    4169          __(bx lr)
    4170 local_label(misc_set_fixnum_vector):
    4171          __(extract_lisptag(imm2,arg_z))
    4172          __(unbox_fixnum(imm0,arg_z))
    4173          __(cmpdi cr2,imm2,tag_fixnum)
    4174          __(la imm4,misc_data_offset(arg_y))
    4175          __(bne cr2,local_label(misc_set_bad))
    4176          __(stdx imm0,arg_x,imm4)
    4177          __(bx lr)
    4178 local_label(misc_set_s64):
    4179          __(extract_lisptag(imm2,arg_z))
    4180          __(extract_fulltag(imm3,arg_z))
    4181          __(unbox_fixnum(imm0,arg_z))
    4182          __(cmpdi cr2,imm2,tag_fixnum)
    4183          __(cmpdi cr6,imm3,fulltag_misc)
    4184          __(la imm4,misc_data_offset(arg_y))
    4185          __(bne cr2,local_label(sets64_maybe_bignum))
    4186          __(stdx imm0,arg_x,imm4)
    4187          __(bx lr)
    4188 local_label(sets64_maybe_bignum):       
    4189          __(bne cr6,local_label(misc_set_bad))
    4190          __(getvheader(imm1,arg_z))
    4191          __(ld imm0,misc_data_offset(arg_z))
    4192          __(cmpdi cr1,imm1,two_digit_bignum_header)
    4193          __(rotldi imm0,imm0,32)
    4194          __(bne cr1,local_label(misc_set_bad))
    4195          __(stdx imm0,arg_x,imm4)
    4196          __(bx lr)
    4197 local_label(misc_set_bad):
    4198          __(mov arg_y,arg_z)
    4199          __(mov arg_z,arg_x)
    4200          __(mov arg_x,#XNOTELT)
    4201          __(set_nargs(3))
    4202          __(b _SPksignalerr)
    4203 local_label(misc_set_invalid): 
    4204          __(mov temp0,#XSETBADVEC)       
    4205          __(set_nargs(4))
    4206          __(vpush1(temp0))
    4207          __(b _SPksignalerr)       
    4208         __else
    4209          __(slwi imm1,imm1,2)
    4210          __(mov imm0,#LO(local_label(misc_set_jmp)))
    4211          __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
    4212          __(lwzx imm0,imm0,imm1)
    4213          __(mtctr imm0)
    4214          __(bctr)
    4215 local_label(misc_set_jmp):             
    4216         /* 00-0f  */
    4217          .long local_label(misc_set_invalid) /* 00 even_fixnum  */
    4218          .long local_label(misc_set_invalid) /* 01 cons  */
    4219          .long local_label(misc_set_invalid) /* 02 nodeheader  */
    4220          .long local_label(misc_set_invalid) /* 03 imm  */
    4221          .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
    4222          .long local_label(misc_set_invalid) /* 05 nil  */
    4223          .long local_label(misc_set_invalid) /* 06 misc  */
    4224          .long local_label(misc_set_u32) /* 07 bignum  */
    4225          .long local_label(misc_set_invalid) /* 08 even_fixnum  */
    4226          .long local_label(misc_set_invalid) /* 09 cons  */
    4227          .long _SPgvset /* 0a ratio  */
    4228          .long local_label(misc_set_invalid) /* 0b imm  */
    4229          .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
    4230          .long local_label(misc_set_invalid) /* 0d nil  */
    4231          .long local_label(misc_set_invalid) /* 0e misc  */
    4232          .long local_label(misc_set_u32) /* 0f single_float  */
    4233         /* 10-1f  */
    4234          .long local_label(misc_set_invalid) /* 10 even_fixnum  */
    4235          .long local_label(misc_set_invalid) /* 11 cons  */
    4236          .long local_label(misc_set_invalid) /* 12 nodeheader  */
    4237          .long local_label(misc_set_invalid) /* 13 imm  */
    4238          .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
    4239          .long local_label(misc_set_invalid) /* 15 nil  */
    4240          .long local_label(misc_set_invalid) /* 16 misc  */
    4241          .long local_label(misc_set_u32) /* 17 double_float  */
    4242          .long local_label(misc_set_invalid) /* 18 even_fixnum  */
    4243          .long local_label(misc_set_invalid) /* 19 cons  */
    4244          .long _SPgvset /* 1a complex  */
    4245          .long local_label(misc_set_invalid) /* 1b imm  */
    4246          .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
    4247          .long local_label(misc_set_invalid) /* 1d nil  */
    4248          .long local_label(misc_set_invalid) /* 1e misc  */
    4249          .long local_label(misc_set_u32) /* 1f macptr  */
    4250         /* 20-2f  */
    4251          .long local_label(misc_set_invalid) /* 20 even_fixnum  */
    4252          .long local_label(misc_set_invalid) /* 21 cons  */
    4253          .long _SPgvset /* 22 catch_frame  */
    4254          .long local_label(misc_set_invalid) /* 23 imm  */
    4255          .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
    4256          .long local_label(misc_set_invalid) /* 25 nil  */
    4257          .long local_label(misc_set_invalid) /* 26 misc  */
    4258          .long local_label(misc_set_u32) /* 27 dead_macptr  */
    4259          .long local_label(misc_set_invalid) /* 28 even_fixnum  */
    4260          .long local_label(misc_set_invalid) /* 29 cons  */
    4261          .long _SPgvset /* 2a function  */
    4262          .long local_label(misc_set_invalid) /* 2b imm  */
    4263          .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
    4264          .long local_label(misc_set_invalid) /* 2d nil  */
    4265          .long local_label(misc_set_invalid) /* 2e misc  */
    4266          .long local_label(misc_set_u32) /* 2f code_vector  */
    4267         /* 30-3f  */
    4268          .long local_label(misc_set_invalid) /* 30 even_fixnum  */
    4269          .long local_label(misc_set_invalid) /* 31 cons  */
    4270          .long _SPgvset /* 32 lisp_thread  */
    4271          .long local_label(misc_set_invalid) /* 33 imm  */
    4272          .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
    4273          .long local_label(misc_set_invalid) /* 35 nil  */
    4274          .long local_label(misc_set_invalid) /* 36 misc  */
    4275          .long local_label(misc_set_u32) /* 37 creole  */
    4276          .long local_label(misc_set_invalid) /* 38 even_fixnum  */
    4277          .long local_label(misc_set_invalid) /* 39 cons  */
    4278          .long _SPgvset /* 3a symbol  */
    4279          .long local_label(misc_set_invalid) /* 3b imm  */
    4280          .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
    4281          .long local_label(misc_set_invalid) /* 3d nil  */
    4282          .long local_label(misc_set_invalid) /* 3e misc  */
    4283          .long local_label(misc_set_u32) /* 3f xcode_vector  */
    4284         /* 40-4f  */
    4285          .long local_label(misc_set_invalid) /* 40 even_fixnum  */
    4286          .long local_label(misc_set_invalid) /* 41 cons  */
    4287          .long _SPgvset /* 42 lock  */
    4288          .long local_label(misc_set_invalid) /* 43 imm  */
    4289          .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
    4290          .long local_label(misc_set_invalid) /* 45 nil  */
    4291          .long local_label(misc_set_invalid) /* 46 misc  */
    4292          .long local_label(misc_set_invalid) /* 47 immheader  */
    4293          .long local_label(misc_set_invalid) /* 48 even_fixnum  */
    4294          .long local_label(misc_set_invalid) /* 49 cons  */
    4295          .long _SPgvset /* 4a hash_vector  */
    4296          .long local_label(misc_set_invalid) /* 4b imm  */
    4297          .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
    4298          .long local_label(misc_set_invalid) /* 4d nil  */
    4299          .long local_label(misc_set_invalid) /* 4e misc  */
    4300          .long local_label(misc_set_invalid) /* 4f immheader  */
    4301         /* 50-5f  */
    4302          .long local_label(misc_set_invalid) /* 50 even_fixnum  */
    4303          .long local_label(misc_set_invalid) /* 51 cons  */
    4304          .long _SPgvset /* 52 pool  */
    4305          .long local_label(misc_set_invalid) /* 53 imm  */
    4306          .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
    4307          .long local_label(misc_set_invalid) /* 55 nil  */
    4308          .long local_label(misc_set_invalid) /* 56 misc  */
    4309          .long local_label(misc_set_invalid) /* 57 immheader  */
    4310          .long local_label(misc_set_invalid) /* 58 even_fixnum  */
    4311          .long local_label(misc_set_invalid) /* 59 cons  */
    4312          .long _SPgvset /* 5a weak  */
    4313          .long local_label(misc_set_invalid) /* 5b imm  */
    4314          .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
    4315          .long local_label(misc_set_invalid) /* 5d nil  */
    4316          .long local_label(misc_set_invalid) /* 5e misc  */
    4317          .long local_label(misc_set_invalid) /* 5f immheader  */
    4318         /* 60-6f  */
    4319          .long local_label(misc_set_invalid) /* 60 even_fixnum  */
    4320          .long local_label(misc_set_invalid) /* 61 cons  */
    4321          .long _SPgvset /* 62 package  */
    4322          .long local_label(misc_set_invalid) /* 63 imm  */
    4323          .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
    4324          .long local_label(misc_set_invalid) /* 65 nil  */
    4325          .long local_label(misc_set_invalid) /* 66 misc  */
    4326          .long local_label(misc_set_invalid) /* 67 immheader  */
    4327          .long local_label(misc_set_invalid) /* 68 even_fixnum  */
    4328          .long local_label(misc_set_invalid) /* 69 cons  */
    4329          .long _SPgvset /* 6a slot_vector  */
    4330          .long local_label(misc_set_invalid) /* 6b imm  */
    4331          .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
    4332          .long local_label(misc_set_invalid) /* 6d nil  */
    4333          .long local_label(misc_set_invalid) /* 6e misc  */
    4334          .long local_label(misc_set_invalid) /* 6f immheader  */
    4335         /* 70-7f  */
    4336          .long local_label(misc_set_invalid) /* 70 even_fixnum  */
    4337          .long local_label(misc_set_invalid) /* 71 cons  */
    4338          .long _SPgvset /* 72 instance  */
    4339          .long local_label(misc_set_invalid) /* 73 imm  */
    4340          .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
    4341          .long local_label(misc_set_invalid) /* 75 nil  */
    4342          .long local_label(misc_set_invalid) /* 76 misc  */
    4343          .long local_label(misc_set_invalid) /* 77 immheader  */
    4344          .long local_label(misc_set_invalid) /* 78 even_fixnum  */
    4345          .long local_label(misc_set_invalid) /* 79 cons  */
    4346          .long _SPgvset /* 7a struct  */
    4347          .long local_label(misc_set_invalid) /* 7b imm  */
    4348          .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
    4349          .long local_label(misc_set_invalid) /* 7d nil  */
    4350          .long local_label(misc_set_invalid) /* 7e misc  */
    4351          .long local_label(misc_set_invalid) /* 7f immheader  */
    4352         /* 80-8f  */
    4353          .long local_label(misc_set_invalid) /* 80 even_fixnum  */
    4354          .long local_label(misc_set_invalid) /* 81 cons  */
    4355          .long _SPgvset /* 82 istruct  */
    4356          .long local_label(misc_set_invalid) /* 83 imm  */
    4357          .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
    4358          .long local_label(misc_set_invalid) /* 85 nil  */
    4359          .long local_label(misc_set_invalid) /* 86 misc  */
    4360          .long local_label(misc_set_invalid) /* 87 immheader  */
    4361          .long local_label(misc_set_invalid) /* 88 even_fixnum  */
    4362          .long local_label(misc_set_invalid) /* 89 cons  */
    4363          .long _SPgvset /* 8a value_cell  */
    4364          .long local_label(misc_set_invalid) /* 8b imm  */
    4365          .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
    4366          .long local_label(misc_set_invalid) /* 8d nil  */
    4367          .long local_label(misc_set_invalid) /* 8e misc  */
    4368          .long local_label(misc_set_invalid) /* 8f immheader  */
    4369         /* 90-9f  */
    4370          .long local_label(misc_set_invalid) /* 90 even_fixnum  */
    4371          .long local_label(misc_set_invalid) /* 91 cons  */
    4372          .long _SPgvset /* 92 xfunction  */
    4373          .long local_label(misc_set_invalid) /* 93 imm  */
    4374          .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
    4375          .long local_label(misc_set_invalid) /* 95 nil  */
    4376          .long local_label(misc_set_invalid) /* 96 misc  */
    4377          .long local_label(misc_set_invalid) /* 97 immheader  */
    4378          .long local_label(misc_set_invalid) /* 98 even_fixnum  */
    4379          .long local_label(misc_set_invalid) /* 99 cons  */
    4380          .long _SPgvset /* 9a arrayH  */
    4381          .long local_label(misc_set_invalid) /* 9b imm  */
    4382          .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
    4383          .long local_label(misc_set_invalid) /* 9d nil  */
    4384          .long local_label(misc_set_invalid) /* 9e misc  */
    4385          .long local_label(misc_set_invalid) /* 9f immheader  */
    4386         /* a0-af  */
    4387          .long local_label(misc_set_invalid) /* a0 even_fixnum  */
    4388          .long local_label(misc_set_invalid) /* a1 cons  */
    4389          .long _SPgvset /* a2 vectorH  */
    4390          .long local_label(misc_set_invalid) /* a3 imm  */
    4391          .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
    4392          .long local_label(misc_set_invalid) /* a5 nil  */
    4393          .long local_label(misc_set_invalid) /* a6 misc  */
    4394          .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
    4395          .long local_label(misc_set_invalid) /* a8 even_fixnum  */
    4396          .long local_label(misc_set_invalid) /* a9 cons  */
    4397          .long _SPgvset /* aa vectorH  */
    4398          .long local_label(misc_set_invalid) /* ab imm  */
    4399          .long local_label(misc_set_invalid) /* ac odd_fixnum  */
    4400          .long local_label(misc_set_invalid) /* ad nil  */
    4401          .long local_label(misc_set_invalid) /* ae misc  */
    4402          .long local_label(misc_set_u32) /* af u32  */
    4403         /* b0-bf  */
    4404          .long local_label(misc_set_invalid) /* b0 even_fixnum  */
    4405          .long local_label(misc_set_invalid) /* b1 cons  */
    4406          .long local_label(misc_set_invalid) /* b2 node  */
    4407          .long local_label(misc_set_invalid) /* b3 imm  */
    4408          .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
    4409          .long local_label(misc_set_invalid) /* b5 nil  */
    4410          .long local_label(misc_set_invalid) /* b6 misc  */
    4411          .long local_label(misc_set_s32) /* b7 s32  */
    4412          .long local_label(misc_set_invalid) /* b8 even_fixnum  */
    4413          .long local_label(misc_set_invalid) /* b9 cons  */
    4414          .long local_label(misc_set_invalid) /* ba nodeheader  */
    4415          .long local_label(misc_set_invalid) /* bb imm  */
    4416          .long local_label(misc_set_invalid) /* bc odd_fixnum  */
    4417          .long local_label(misc_set_invalid) /* bd nil  */
    4418          .long local_label(misc_set_invalid) /* be misc  */
    4419          .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
    4420         /* c0-cf  */
    4421          .long local_label(misc_set_invalid) /* c0 even_fixnum  */
    4422          .long local_label(misc_set_invalid) /* c1 cons  */
    4423          .long local_label(misc_set_invalid) /* c2 nodeheader  */
    4424          .long local_label(misc_set_invalid) /* c3 imm  */
    4425          .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
    4426          .long local_label(misc_set_invalid) /* c5 nil  */
    4427          .long local_label(misc_set_invalid) /* c6 misc  */
    4428          .long local_label(misc_set_new_string) /* c7 new_string  */
    4429          .long local_label(misc_set_invalid) /* c8 even_fixnum  */
    4430          .long local_label(misc_set_invalid) /* c9 cons  */
    4431          .long local_label(misc_set_invalid) /* ca nodeheader  */
    4432          .long local_label(misc_set_invalid) /* cb imm  */
    4433          .long local_label(misc_set_invalid) /* cc odd_fixnum  */
    4434          .long local_label(misc_set_invalid) /* cd nil  */
    4435          .long local_label(misc_set_invalid) /* ce misc  */
    4436          .long local_label(misc_set_u8) /* cf u8  */
    4437         /* d0-df  */
    4438          .long local_label(misc_set_invalid) /* d0 even_fixnum  */
    4439          .long local_label(misc_set_invalid) /* d1 cons  */
    4440          .long local_label(misc_set_invalid) /* d2 nodeheader  */
    4441          .long local_label(misc_set_invalid) /* d3 imm  */
    4442          .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
    4443          .long local_label(misc_set_invalid) /* d5 nil  */
    4444          .long local_label(misc_set_invalid) /* d6 misc  */
    4445          .long local_label(misc_set_s8) /* d7 s8  */
    4446          .long local_label(misc_set_invalid) /* d8 even_fixnum  */
    4447          .long local_label(misc_set_invalid) /* d9 cons  */
    4448          .long local_label(misc_set_invalid) /* da nodeheader  */
    4449          .long local_label(misc_set_invalid) /* db imm  */
    4450          .long local_label(misc_set_invalid) /* dc odd_fixnum  */
    4451          .long local_label(misc_set_invalid) /* dd nil  */
    4452          .long local_label(misc_set_invalid) /* de misc  */
    4453          .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
    4454         /* e0-ef  */
    4455          .long local_label(misc_set_invalid) /* e0 even_fixnum  */
    4456          .long local_label(misc_set_invalid) /* e1 cons  */
    4457          .long local_label(misc_set_invalid) /* e2 nodeheader  */
    4458          .long local_label(misc_set_invalid) /* e3 imm  */
    4459          .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
    4460          .long local_label(misc_set_invalid) /* e5 nil  */
    4461          .long local_label(misc_set_invalid) /* e6 misc  */
    4462          .long local_label(misc_set_u16) /* e7 u16  */
    4463          .long local_label(misc_set_invalid) /* e8 even_fixnum  */
    4464          .long local_label(misc_set_invalid) /* e9 cons  */
    4465          .long local_label(misc_set_invalid) /* ea nodeheader  */
    4466          .long local_label(misc_set_invalid) /* eb imm  */
    4467          .long local_label(misc_set_invalid) /* ec odd_fixnum  */
    4468          .long local_label(misc_set_invalid) /* ed nil  */
    4469          .long local_label(misc_set_invalid) /* ee misc  */
    4470          .long local_label(misc_set_s16) /* ef s16  */
    4471         /* f0-ff  */
    4472          .long local_label(misc_set_invalid) /* f0 even_fixnum  */
    4473          .long local_label(misc_set_invalid) /* f1 cons  */
    4474          .long local_label(misc_set_invalid) /* f2 nodeheader  */
    4475          .long local_label(misc_set_invalid) /* f3 imm  */
    4476          .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
    4477          .long local_label(misc_set_invalid) /* f5 nil  */
    4478          .long local_label(misc_set_invalid) /* f6 misc  */
    4479          .long local_label(misc_set_double_float_vector) /* f7 df vector  */
    4480          .long local_label(misc_set_invalid) /* f8 even_fixnum  */
    4481          .long local_label(misc_set_invalid) /* f9 cons  */
    4482          .long local_label(misc_set_invalid) /* fa nodeheader  */
    4483          .long local_label(misc_set_invalid) /* fb imm  */
    4484          .long local_label(misc_set_invalid) /* fc odd_fixnum  */
    4485          .long local_label(misc_set_invalid) /* fd nil  */
    4486          .long local_label(misc_set_invalid) /* fe misc  */
    4487          .long local_label(misc_set_bit_vector) /* ff bit_vector  */
    4488 
    4489 local_label(misc_set_u32):       
    4490         /* Either a non-negative fixnum, a positiveone-digit bignum, */
    4491         /* or a two-digit bignum whose sign-digit is 0 is ok.  */
    4492          __(extract_lisptag(imm2,arg_z))
    4493          __(srawi. imm1,arg_z,fixnum_shift)
    4494          __(cmpwi cr5,imm2,tag_fixnum)         
    4495          __(la imm0,misc_data_offset(arg_y))
    4496          __(cmpwi cr7,imm2,tag_misc)
    4497          __(bne cr5,local_label(set_not_fixnum_u32))
    4498          __(blt- cr0,local_label(set_bad))
    4499 local_label(set_set32):         
    4500          __(stwx imm1,arg_x,imm0)
    4501          __(bx lr)
    4502 local_label(set_not_fixnum_u32):
    4503          __(bne cr7,local_label(set_bad))
    4504          __(extract_header(imm2,arg_z))
    4505          __(cmpri(cr0,imm2,one_digit_bignum_header))
    4506          __(cmpri(cr1,imm2,two_digit_bignum_header))
    4507          __(vrefr(imm1,arg_z,0))
    4508          __(cmpri(cr2,imm1,0))
    4509          __(bne cr0,local_label(set_not_1_digit_u32))
    4510          __(bge cr2,local_label(set_set32))
    4511          __(b local_label(set_bad))
    4512 local_label(set_not_1_digit_u32):
    4513          __(bne- cr1,local_label(set_bad))
    4514          __(vrefr(imm2,arg_z,1))
    4515          __(cmpri(cr0,imm2,0))
    4516          __(bne- cr1,local_label(set_bad))
    4517          __(beq cr0,local_label(set_set32))
    4518 local_label(set_bad):
    4519         /* arg_z does not match the array-element-type of arg_x.  */
    4520          __(mov arg_y,arg_z)
    4521          __(mov arg_z,arg_x)
    4522          __(mov arg_x,#XNOTELT)
    4523          __(set_nargs(3))
    4524          __(b _SPksignalerr)
    4525 local_label(misc_set_fixnum_vector):   
    4526          __(extract_lisptag(imm2,arg_z))
    4527          __(la imm0,misc_data_offset(arg_y))
    4528          __(cmpwi cr5,imm2,tag_fixnum)
    4529          __(unbox_fixnum(imm1,arg_z))
    4530          __(bne cr5,local_label(set_bad))
    4531          __(stwx imm1,arg_x,imm0)
    4532          __(bx lr)
    4533 local_label(misc_set_new_string):   
    4534          __(clrlwi imm2,arg_z,ncharcodebits)
    4535          __(la imm0,misc_data_offset(arg_y))
    4536          __(cmpwi cr5,imm2,subtag_character)
    4537          __(srwi imm1,arg_z,charcode_shift)
    4538          __(bne cr5,local_label(set_bad))
    4539          __(stwx imm1,arg_x,imm0)
    4540          __(bx lr)
    4541 local_label(misc_set_s32):
    4542          __(extract_lisptag(imm2,arg_z))
    4543          __(cmpwi cr5,imm2,tag_fixnum)
    4544          __(cmpwi cr7,imm2,tag_misc)
    4545          __(la imm0,misc_data_offset(arg_y))
    4546          __(unbox_fixnum(imm1,arg_z))
    4547          __(beq cr5,local_label(set_set32))
    4548          __(bne cr7,local_label(set_bad))
    4549          __(extract_header(imm2,arg_z))
    4550          __(cmpri(cr0,imm2,one_digit_bignum_header))
    4551          __(vrefr(imm1,arg_z,0))
    4552          __(bne- cr0,local_label(set_bad))
    4553          __(strx(imm1,arg_x,imm0))
    4554          __(bx lr)
    4555 local_label(misc_set_single_float_vector):
    4556          __(extract_lisptag(imm2,arg_z))
    4557          __(cmpwi cr7,imm2,tag_misc)
    4558          __(la imm0,misc_data_offset(arg_y))
    4559          __(bne- cr7,local_label(set_bad))
    4560          __(extract_header(imm2,arg_z))
    4561          __(cmpri(cr0,imm2,single_float_header))
    4562          __(bne- cr0,local_label(set_bad))
    4563          __(ldr imm1,[arg_z,#single_float.value])
    4564          __(strx(imm1,arg_x,imm0))
    4565          __(bx lr)
    4566 local_label(misc_set_u8):               
    4567          __(extract_lisptag(imm2,arg_z))
    4568          __(srwi imm0,arg_y,2)
    4569          __(la imm0,misc_data_offset(imm0))
    4570          __(extract_unsigned_byte_bits_(imm1,arg_z,8))
    4571          __(unbox_fixnum(imm1,arg_z))
    4572          __(bne- cr0,local_label(set_bad))
    4573          __(stbx imm1,arg_x,imm0)
    4574          __(bx lr)
    4575 local_label(misc_set_old_string):
    4576          __(srwi imm0,arg_y,2)
    4577          __(extract_lowbyte(imm2,arg_z))
    4578          __(cmpri(cr2,imm2,subtag_character))
    4579          __(la imm0,misc_data_offset(imm0))
    4580          __(srwi imm1,arg_z,charcode_shift)
    4581          __(bne- cr2,local_label(set_bad))
    4582          __(stbx imm1,arg_x,imm0)
    4583          __(bx lr)
    4584 local_label(misc_set_s8):
    4585          __(extract_lisptag(imm2,arg_z))
    4586          __(srwi imm0,arg_y,2)
    4587          __(unbox_fixnum(imm1,arg_z))
    4588          __(la imm0,misc_data_offset(imm0))
    4589          __(cmpwi cr5,imm2,tag_fixnum)
    4590          __(extsb imm2,imm1)
    4591          __(cmpw cr0,imm2,imm1)
    4592          __(bne- cr5,local_label(set_bad))
    4593          __(bne- cr0,local_label(set_bad))
    4594          __(stbx imm1,arg_x,imm0)
    4595          __(bx lr)
    4596 local_label(misc_set_u16):         
    4597          __(srwi imm0,arg_y,1)
    4598          __(extract_unsigned_byte_bits_(imm1,arg_z,16))
    4599          __(unbox_fixnum(imm1,arg_z))
    4600          __(la imm0,misc_data_offset(imm0))
    4601          __(bne- cr0,local_label(set_bad))
    4602          __(sthx imm1,arg_x,imm0)
    4603          __(bx lr)
    4604 local_label(misc_set_s16):
    4605          __(extract_lisptag(imm2,arg_z))
    4606          __(srwi imm0,arg_y,1)
    4607          __(unbox_fixnum(imm1,arg_z))
    4608          __(cmpwi cr5,imm2,tag_fixnum)
    4609          __(la imm0,misc_data_offset(imm0))
    4610          __(extsh imm2,imm1)
    4611          __(cmpw cr0,imm2,imm1)
    4612          __(bne- cr5,local_label(set_bad))
    4613          __(bne- cr0,local_label(set_bad))
    4614          __(sthx imm1,arg_x,imm0)
    4615          __(bx lr)
    4616 local_label(misc_set_bit_vector):       
    4617          __(cmplwi cr2,arg_z,fixnumone)   /* nothing not a (boxed) bit   */
    4618          __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
    4619          __(extlwi imm2,arg_z,1,31-fixnumshift)
    4620          __(srw imm2,imm2,imm1)
    4621          __(lis imm3,0x8000)
    4622          __(rlwinm imm0,arg_y,32-5,5,31-fixnumshift)
    4623          __(la imm0,misc_data_offset(imm0))
    4624          __(srw imm3,imm3,imm1)
    4625          __(bgt- cr2,local_label(set_bad))
    4626          __(lwzx imm1,arg_x,imm0)
    4627          __(andc imm1,imm1,imm3)
    4628          __(or imm1,imm1,imm2)
    4629          __(stwx imm1,arg_x,imm0)
    4630          __(bx lr)
    4631 
    4632 local_label(misc_set_double_float_vector):
    4633          __(extract_lisptag(imm2,arg_z))
    4634          __(slwi imm0,arg_y,1)
    4635          __(cmpwi cr7,imm2,tag_misc)
    4636          __(la imm0,misc_dfloat_offset(imm0))
    4637          __(bne- cr7,local_label(set_bad))
    4638          __(extract_header(imm2,arg_z))
    4639          __(cmpri(cr0,imm2,double_float_header))
    4640          __(bne- cr0,local_label(set_bad))
    4641          __(lwz imm1,double_float.value(arg_z))
    4642          __(lwz imm2,double_float.value+4(arg_z))
    4643          __(stwx imm1,arg_x,imm0)
    4644          __(la imm0,4(imm0))
    4645          __(stwx imm2,arg_x,imm0)
    4646          __(bx lr)
    4647 local_label(misc_set_invalid): 
    4648          __(mov temp0,#XSETBADVEC)       
    4649          __(set_nargs(4))
    4650          __(vpush1(temp0))
    4651          __(b _SPksignalerr)               
    4652         __endif
    4653 
    4654 /* misc_set (vector index newval).  Pretty damned similar to  */
    4655 /* misc_ref, as one might imagine.  */
    4656 
    4657 _spentry(misc_set)
    4658         __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
    4659         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    4660         __(vector_length(imm0,arg_x,imm1))
    4661         __(trlge(arg_y,imm0))
    4662         __(extract_lowbyte(imm1,imm1))
    4663         __(b local_label(misc_set_common))
    4664        
    4665 /* "spread" the lexpr in arg_z.  */
    4666 /* ppc2-invoke-fn assumes that temp1 is preserved here.  */
    4667 _spentry(spread_lexprz)
    4668         __(ldr imm0,[arg_z,#0])
    4669         __(cmpri(cr3,imm0,3<<fixnumshift))
    4670         __(cmpri(cr4,imm0,2<<fixnumshift))
    4671         __(add imm1,arg_z,imm0)
    4672         __(cmpri(cr0,imm0,0))
    4673         __(add nargs,nargs,imm0)
    4674         __(cmpri(cr1,nargs,0))
    4675         __(cmpri(cr2,nargs,2<<fixnumshift))
    4676         __(la imm1,node_size(imm1))
    4677         __(bge cr3,9f)
    4678         __(beq cr4,2f)
    4679         __(bne cr0,1f)
    4680         /* lexpr count was 0; vpop the arg regs that  */
    4681         /* were vpushed by the caller  */
    4682         __(beqlr cr1)
    4683         __(vpop(arg_z))
    4684         __(bltlr cr2)
    4685         __(vpop(arg_y))
    4686         __(beqlr cr2)
    4687         __(vpop(arg_x))
    4688         __(bx lr)
    4689 
    4690         /* vpush args from the lexpr until we have only  */
    4691         /* three left, then assign them to arg_x, arg_y,  */
    4692         /* and arg_z.  */
    4693 8:
    4694         __(cmpri(cr3,imm0,4<<fixnumshift))
    4695         __(subi imm0,imm0,fixnumone)
    4696         __(ldru(arg_z,-node_size(imm1)))
    4697         __(vpush1(arg_z))
    4698 9:
    4699         __(bne cr3,8b)
    4700         __(ldr arg_x,[imm1,#-node_size*1])
    4701         __(ldr arg_y,[imm1,#-node_size*2])
    4702         __(ldr arg_z,[imm1,#-node_size*3])
    4703         __(bx lr)
    4704 
    4705         /* lexpr count is two: set arg_y, arg_z from the  */
    4706         /* lexpr, maybe vpop arg_x  */
    4707 2:     
    4708         __(ldr arg_y,[imm1,#-node_size*1])
    4709         __(ldr arg_z,[imm1,#-node_size*2])
    4710         __(beqlr cr2)           /* return if (new) nargs = 2  */
    4711         __(vpop(arg_x))
    4712         __(bx lr)
    4713 
    4714         /* lexpr count is one: set arg_z from the lexpr,  */
    4715         /* maybe vpop arg_y, arg_x  */
    4716 1:     
    4717         __(ldr arg_z,[imm1,#-node_size])
    4718         __(bltlr cr2)           /* return if (new) nargs < 2  */
    4719         __(vpop(arg_y))
    4720         __(beqlr cr2)           /* return if (new) nargs = 2  */
    4721         __(vpop(arg_x))
    4722         __(bx lr)
    4723        
    4724                
    4725 _spentry(reset)
    4726         .globl _SPthrow
    4727         __(nop)
    4728         __(ref_nrs_value(temp0,toplcatch))
    4729         __(mov temp1,#XSTKOVER)
    4730         __(vpush1(temp0))
    4731         __(vpush1(temp1))
    4732         __(set_nargs(1))
    4733         __(b _SPthrow)
    4734 
    4735        
    4736 /* "slide" nargs worth of values up the vstack.  IMM0 contains  */
    4737 /* the difference between the current VSP and the target.  */
    4738 _spentry(mvslide)
    4739         __(cmpri(cr0,nargs,0))
    4740         __(mov imm3,nargs)
    4741         __(add imm2,vsp,nargs)
    4742         __(add imm2,imm2,imm0)
    4743         __(add imm0,vsp,nargs)
    4744         __(beq 2f)
    4745 1:
    4746         __(cmpri(cr0,imm3,1<<fixnumshift))
    4747         __(subi imm3,imm3,1<<fixnumshift)
    4748         __(ldru(temp0,-node_size(imm0)))
    4749         __(stru(temp0,-node_size(imm2)))
    4750         __(bne cr0,1b)
    4751 2:
    4752         __(mov vsp,imm2)
    4753         __(bx lr)
    4754 
    4755 /* Build a new TSP area to hold nargs worth of multiple-values.  */
    4756 /* Pop the multiple values off of the vstack.  */
    4757 /* The new TSP frame will look like this:  */
    4758 /*  */
    4759 /*+--------+-------+-------+---------+--------+--------+--------+======+----------+ */
    4760 /*| ptr to | zero  | nargs | ptr to  | valn-1 | valn-2 | val-0  | ???? | prev TSP |  */
    4761 /*|  prev  |       |       |  prev   |        |        |        | fill |          |  */
    4762 /*| TSP    |       |       | segment |        |        |        |      |          | */
    4763 /*+--------+-------+-------+---------+--------+--------+--------+------+----------+  */
    4764 /*  */
    4765 /* e.g., the first multiple value goes in the last cell in the frame, the  */
    4766 /* count of values goes in the first word, and the word after the value count  */
    4767 /* is 0 if the number of values is even (for alignment).  */
    4768 /* Subsequent calls to .SPadd_values preserve this alignment.  */
    4769 /* .SPrecover_values is therefore pretty simple.  */
    4770 
    4771 _spentry(save_values)
    4772         __(mov imm1,tsp)
    4773 
    4774         /* common exit: nargs = values in this set, imm1 = ptr to tsp before  */
    4775         /* call to save_values  */
    4776 local_label(save_values_to_tsp):
    4777         __(mov imm2,tsp)
    4778         __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* count, link  */
    4779         __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
    4780         __(str(imm1,tsp_frame.backlink(tsp))) /* keep one tsp "frame" as far as rest of lisp is concerned  */
    4781         __(str(nargs,tsp_frame.data_offset(tsp)))
    4782         __(str(imm2,tsp_frame.data_offset+node_size(tsp))) /* previous tsp  */
    4783         __(la imm3,tsp_frame.data_offset+node_size*2(tsp))
    4784         __(add imm3,imm3,nargs)
    4785         __(add imm0,vsp,nargs)
    4786         __(cmpr(cr0,imm0,vsp))
    4787         __(b 2f)
    4788 1:
    4789         __(ldru(arg_z,-node_size(imm0)))
    4790         __(cmpr(cr0,imm0,vsp))
    4791         __(stru(arg_z,-node_size(imm3)))
    4792 2:
    4793         __(bne cr0,1b)
    4794         __(add vsp,vsp,nargs) /*  discard values  */
    4795         __(bx lr)
    4796        
    4797 
    4798 /* Add the multiple values that are on top of the vstack to the set  */
    4799 /* saved in the top tsp frame, popping them off of the vstack in the  */
    4800 /* process.  It is an error (a bad one) if the TSP contains something  */
    4801 /* other than a previously saved set of multiple-values.  */
    4802 /* Since adding to the TSP may cause a new TSP segment to be allocated,  */
    4803 /* each add_values call adds another linked element to the list of  */
    4804 /* values. This makes recover_values harder.  */
    4805 
    4806 _spentry(add_values)
    4807         __(cmpri(cr0,nargs,0))
    4808         __(ldr imm1,[tsp,#0])
    4809         __(bne cr0,local_label(save_values_to_tsp))
    4810         __(bx lr)
    4811        
    4812 /* On entry, R11->callback-index  */
    4813 /* Restore lisp context, then funcall #'%pascal-functions% with  */
    4814 /* two args: callback-index, args-ptr (a macptr pointing to the args on the stack)  */
    4815 _spentry(poweropen_callback)
    4816         __ifdef(`rTOC')
    4817          __(mov r11,rTOC)
    4818         __endif
    4819         /* Save C argument registers  */
    4820         __(str(r3,c_frame.param0(sp)))
    4821         __(str(r4,c_frame.param1(sp)))
    4822         __(str(r5,c_frame.param2(sp)))
    4823         __(str(r6,c_frame.param3(sp)))
    4824         __(str(r7,c_frame.param4(sp)))
    4825         __(str(r8,c_frame.param5(sp)))
    4826         __(str(r9,c_frame.param6(sp)))
    4827         __(str(r10,c_frame.param7(sp)))
    4828         __(mflr imm3)
    4829         __(str(imm3,c_frame.savelr(sp)))
    4830         __(mfcr imm0)
    4831         __(str(imm0,c_frame.crsave(sp)))
    4832 
    4833         /* Save the non-volatile registers on the sp stack  */
    4834         /* This is a non-standard stack frame, but noone will ever see it,  */
    4835         /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
    4836         __(stru(sp,-(stack_align(c_reg_save.size))(sp)))
    4837         __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
    4838         __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
    4839         __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
    4840         __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
    4841         __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
    4842         __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
    4843         __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
    4844         __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
    4845         __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
    4846         __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
    4847         __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
    4848         __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
    4849         __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
    4850         __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
    4851         __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
    4852         __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
    4853         __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
    4854         __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
    4855         __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
    4856         __(stfd f1,c_reg_save.save_fprs+(0*8)(sp))
    4857         __(stfd f2,c_reg_save.save_fprs+(1*8)(sp))
    4858         __(stfd f3,c_reg_save.save_fprs+(2*8)(sp))
    4859         __(stfd f4,c_reg_save.save_fprs+(3*8)(sp))
    4860         __(stfd f5,c_reg_save.save_fprs+(4*8)(sp))
    4861         __(stfd f6,c_reg_save.save_fprs+(5*8)(sp))
    4862         __(stfd f7,c_reg_save.save_fprs+(6*8)(sp))
    4863         __(stfd f8,c_reg_save.save_fprs+(7*8)(sp))
    4864         __(stfd f9,c_reg_save.save_fprs+(8*8)(sp))
    4865         __(stfd f10,c_reg_save.save_fprs+(9*8)(sp))
    4866         __(stfd f11,c_reg_save.save_fprs+(10*8)(sp))
    4867         __(stfd f12,c_reg_save.save_fprs+(11*8)(sp))
    4868         __(stfd f13,c_reg_save.save_fprs+(12*8)(sp))
    4869         __(check_stack_alignment(r0))
    4870         __(mffs f0)
    4871         __(stfd f0,c_reg_save.save_fp_zero(sp))
    4872         __(lwz r31,c_reg_save.save_fp_zero+4(sp))       /* recover FPSCR image  */
    4873         __(stw r31,c_reg_save.save_fpscr(sp))
    4874         __(lwi(r30,0x43300000))
    4875         __(lwi(r31,0x80000000))
    4876         __(stw r30,c_reg_save.save_fp_zero(sp))
    4877         __(stw r31,c_reg_save.save_fp_zero+4(sp))
    4878         __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
    4879         __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
    4880         __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
    4881         __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
    4882 
    4883 /* Restore rest of Lisp context.  */
    4884 /* Could spread out the memory references here to gain a little speed  */
    4885 
    4886         __(mov loc_pc,#0)
    4887         __(mov fn,#0)                     /* subprim, not a lisp function  */
    4888         __(mov temp3,#0)
    4889         __(mov temp2,#0)
    4890         __(mov temp1,#0)
    4891         __(mov temp0,#0)
    4892         __(mov arg_x,#0)
    4893         __(box_fixnum(arg_y,r11))       /* callback-index  */
    4894         __(la arg_z,c_reg_save.save_fprs(sp))
    4895         __(str(arg_z,stack_align(c_reg_save.size)+c_frame.unused(sp)))
    4896         __(la arg_z,stack_align(c_reg_save.size)+c_frame.param0(sp))    /* parameters (tagged as a fixnum)  */
    4897 
    4898         /* Recover lisp thread context. Have to call C code to do so.  */
    4899         __(ref_global(r12,get_tcr))
    4900         __ifdef(`rTOC')
    4901          __(ld rTOC,8(r12))
    4902          __(ld r12,0(r12))
    4903         __endif
    4904         __(mtctr r12)
    4905         __(mov r3,#1)
    4906         __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
    4907         __(bctrl)
    4908         __(la rcontext,TCR_BIAS(r3))
    4909         __(la sp,(stack_align(c_frame.minsiz))(sp))
    4910 
    4911         __(ldr vsp,[rcontext,#tcr.save_vsp])
    4912         __(ldr tsp,[rcontext,#tcr.save_tsp])           
    4913         __(mov rzero,#0)
    4914         __(mov imm0,#TCR_STATE_LISP)
    4915         __(mtxer rzero) /* lisp wants the overflow bit being clear  */
    4916         __(mtctr rzero)
    4917         __(mov save0,#0)
    4918         __(mov save1,#0)
    4919         __(mov save2,#0)
    4920         __(mov save3,#0)
    4921         __(mov save4,#0)
    4922         __(mov save5,#0)
    4923         __(mov save6,#0)
    4924         __(mov save7,#0)
    4925         __(lfd f0,tcr.lisp_fpscr(rcontext))
    4926         __(mtfsf 0xff,f0)
    4927         __(mov allocbase,#0)
    4928         __(mov allocptr,#0)     
    4929         __(str(imm0,tcr.valence(rcontext)))
    4930         __(ldr allocptr,[rcontext,#tcr.save_allocptr])
    4931         __(ldr allocbase,[rcontext,#tcr.save_allocbase])
    4932        
    4933         __(restore_saveregs(vsp))
    4934 
    4935         /* load nargs and callback to the lisp  */
    4936         __(set_nargs(2))
    4937         __(ldr imm2,[rcontext,#tcr.cs_area])
    4938         __(ldr imm4,[imm2,#area.active])
    4939         __(stru(imm4,-lisp_frame.size(sp)))
    4940         __(str(imm3,lisp_frame.savelr(sp)))
    4941         __(mov fname,#nrs.callbacks)    /* %pascal-functions%  */
    4942         __(call_fname)
    4943         __(ldr imm2,[sp,#lisp_frame.backlink])
    4944         __(ldr imm3,[rcontext,#tcr.cs_area])
    4945         __(str(imm2,area.active(imm3)))
    4946         __(discard_lisp_frame())
    4947         /* save_vsp will be restored from ff_call's stack frame, but  */
    4948         /* I included it here for consistency.  */
    4949         /* save_tsp is set below after we exit Lisp context.  */
    4950         __(str(allocptr,tcr.save_allocptr(rcontext)))
    4951         __(str(allocbase,tcr.save_allocbase(rcontext)))
    4952         __(str(vsp,tcr.save_vsp(rcontext)))
    4953         __(str(tsp,tcr.save_tsp(rcontext)))
    4954         /* Exit lisp context  */
    4955         __(mov imm1,#TCR_STATE_FOREIGN)
    4956         __(str(imm1,tcr.valence(rcontext)))
    4957         /* Restore the non-volatile registers & fpscr  */
    4958         __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
    4959         __(lwz r31,c_reg_save.save_fpscr(sp))
    4960         __(stw r31,c_reg_save.save_fp_zero+4(sp))
    4961         __(lfd f0,c_reg_save.save_fp_zero(sp))
    4962         __(mtfsf 0xff,f0)
    4963         __(ldr r13,c_reg_save.save_gprs+(0*node_size)(sp)))
    4964         __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
    4965         __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
    4966         __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
    4967         __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
    4968         __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
    4969         __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
    4970         __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
    4971         __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
    4972         __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
    4973         __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
    4974         __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
    4975         __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
    4976         __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
    4977         __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
    4978         __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
    4979         __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
    4980         __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
    4981         __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
    4982         __(lfd f1,c_reg_save.save_fprs+(0*8)(sp))
    4983         __(lfd f2,c_reg_save.save_fprs+(1*8)(sp))
    4984         __(lfd f3,c_reg_save.save_fprs+(2*8)(sp))
    4985         __(lfd f4,c_reg_save.save_fprs+(3*8)(sp))
    4986         __(lfd f5,c_reg_save.save_fprs+(4*8)(sp))
    4987         __(lfd f6,c_reg_save.save_fprs+(5*8)(sp))
    4988         __(lfd f7,c_reg_save.save_fprs+(6*8)(sp))
    4989         __(lfd f8,c_reg_save.save_fprs+(7*8)(sp))
    4990         __(lfd f9,c_reg_save.save_fprs+(8*8)(sp))
    4991         __(lfd f10,c_reg_save.save_fprs+(9*8)(sp))
    4992         __(lfd f11,c_reg_save.save_fprs+(10*8)(sp))
    4993         __(lfd f12,c_reg_save.save_fprs+(11*8)(sp))
    4994         __(lfd f13,c_reg_save.save_fprs+(12*8)(sp))
    4995         __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
    4996         __(ldr(sp,0(sp)))
    4997         __(ldr r3,[sp,#c_frame.param0])
    4998         __(ldr r4,[sp,#c_frame.param1])
    4999         __(ldr r5,[sp,#c_frame.param2])
    5000         __(ldr r6,[sp,#c_frame.param3])
    5001         __(ldr r7,[sp,#c_frame.param4])
    5002         __(ldr r8,[sp,#c_frame.param5])
    5003         __(ldr r9,[sp,#c_frame.param6])
    5004         __(ldr r10,[sp,#c_frame.param7])
    5005         __(ldr r11,[sp,#c_frame.savelr])
    5006         __(mtlr r11)
    5007         __(ldr r11,[sp,#c_frame.crsave])
    5008         __(mtcr r11)
    5009         __(bx lr)
    5010        
    5011 /* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
    5012 /* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
    5013 /* Calls out to %init-misc, which does the rest of the work.  */
    5014 
    5015 _spentry(misc_alloc_init)
    5016         __(mflr loc_pc)
    5017         __(build_lisp_frame(fn,loc_pc,vsp))
    5018         __(mov fn,#0)
    5019         __(mov temp0,arg_z)             /* initval  */
    5020         __(mov arg_z,arg_y)             /* subtag  */
    5021         __(mov arg_y,arg_x)             /* element-count  */
    5022         __(bl _SPmisc_alloc)
    5023         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    5024         __(mtlr loc_pc)
    5025         __(ldr fn,[sp,#lisp_frame.savefn])
    5026         __(ldr vsp,[sp,#lisp_frame.savevsp])
    5027         __(discard_lisp_frame())
    5028         __(mov fname,#nrs.init_misc)
    5029         __(set_nargs(2))
    5030         __(mov arg_y,temp0)
    5031         __(jump_fname())
    5032 
    5033 /* As in stack_misc_alloc above, only with a non-default initial-value.  */
    5034 
    5035 _spentry(stack_misc_alloc_init)
    5036         __(mflr loc_pc)
    5037         __(build_lisp_frame(fn,loc_pc,vsp))
    5038         __(mov fn,#0)
    5039         __(mov temp0,arg_z) /* initval  */
    5040         __(mov arg_z,arg_y) /* subtag  */
    5041         __(mov arg_y,arg_x) /* element-count  */
    5042         __(bl _SPstack_misc_alloc)
    5043         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    5044         __(mtlr loc_pc)
    5045         __(ldr fn,[sp,#lisp_frame.savefn])
    5046         __(ldr vsp,[sp,#lisp_frame.savevsp])
    5047         __(discard_lisp_frame())
    5048         __(mov fname,#nrs.init_misc)
    5049         __(set_nargs(2))
    5050         __(mov arg_y,temp0)
    5051         __(jump_fname())
    5052 
    5053        
    5054 _spentry(callbuiltin)
    5055         __(ref_nrs_value(fname,builtin_functions))
    5056         __(la imm0,misc_data_offset(imm0))
    5057         __(ldrx(fname,fname,imm0))
    5058         __(jump_fname())
    5059 
    5060 /* the value of the nilreg-relative symbol %builtin-functions% should be  */
    5061 /* a vector of symbols.  Call the symbol indexed by imm0 (boxed) and  */
    5062 /* return a single value.  */
    5063 
    5064 _spentry(callbuiltin0)
    5065         __(set_nargs(0))
    5066         __(ref_nrs_value(fname,builtin_functions))
    5067         __(la imm0,misc_data_offset(imm0))
    5068         __(ldrx(fname,fname,imm0))
    5069         __(jump_fname())
    5070 
    5071 _spentry(callbuiltin1)
    5072         __(ref_nrs_value(fname,builtin_functions))
    5073         __(set_nargs(1))
    5074         __(la imm0,misc_data_offset(imm0))
    5075         __(ldrx(fname,fname,imm0))
    5076         __(jump_fname())
    5077 
    5078 _spentry(callbuiltin2)
    5079         __(set_nargs(2))
    5080         __(ref_nrs_value(fname,builtin_functions))
    5081         __(la imm0,misc_data_offset(imm0))
    5082         __(ldrx(fname,fname,imm0))
    5083         __(jump_fname())
    5084 
    5085 
    5086 _spentry(callbuiltin3)
    5087         __(set_nargs(3))
    5088         __(ref_nrs_value(fname,builtin_functions))
    5089         __(la imm0,misc_data_offset(imm0))
    5090         __(ldrx(fname,fname,imm0))
    5091         __(jump_fname())
    5092        
    5093 
    5094 _spentry(popj)
    5095         .globl C(popj)
    5096 C(popj):
    5097         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    5098         __(ldr vsp,[sp,#lisp_frame.savevsp])
    5099         __(mtlr loc_pc)
    5100         __(ldr fn,[sp,#lisp_frame.savefn])
    5101         __(discard_lisp_frame())
    5102         __(bx lr)
    5103 
    5104 _spentry(restorefullcontext)
    5105         __(mflr loc_pc)
    5106         __(mtctr loc_pc)
    5107         __(ldr loc_pc,[sp,#lisp_frame.savelr])
    5108         __(mtlr loc_pc)
    5109         __(ldr vsp,[sp,#lisp_frame.savevsp])
    5110         __(ldr fn,[sp,#lisp_frame.savefn])
    5111         __(discard_lisp_frame())
    5112         __(bctr)
    5113 
    5114 _spentry(savecontextvsp)
    5115         __(ldr(imm0,tcr.cs_limit(rcontext)))
    5116         __(build_lisp_frame(fn,loc_pc,vsp))
    5117         __(mov fn,nfn)
    5118         __(trllt(sp,imm0))
    5119         __(bx lr)
    5120 
    5121 _spentry(savecontext0)
    5122         __(add imm0,vsp,imm0)
    5123         __(build_lisp_frame(fn,loc_pc,imm0))
    5124         __(ldr(imm0,tcr.cs_limit(rcontext)))
    5125         __(mov fn,nfn)
    5126         __(trllt(sp,imm0))
    5127         __(bx lr)
    5128 
    5129 
    5130 /* Like .SPrestorefullcontext, only the saved return address  */
    5131 /* winds up in loc-pc instead of getting thrashed around ...  */
    5132 _spentry(restorecontext)
    5133         __(ldr(loc_pc,lisp_frame.savelr(sp)))
    5134         __(ldr(vsp,lisp_frame.savevsp(sp)))
    5135         __(ldr(fn,lisp_frame.savefn(sp)))
    5136         __(discard_lisp_frame())
    5137         __(bx lr)
    5138 
    5139        
    5140 /* Nargs is valid; all arg regs, lexpr-count pushed by caller.  */
    5141 /* imm0 = vsp to restore.  */
    5142 /* Return all values returned by caller to its caller, hiding  */
    5143 /* the variable-length arglist.  */
    5144 /* If we can detect that the caller's caller didn't expect  */
    5145 /* multiple values, then things are even simpler.  */
    5146 _spentry(lexpr_entry)
    5147         __(ref_global(imm1,ret1val_addr))
    5148         __(cmpr(cr0,imm1,loc_pc))
    5149         __(build_lisp_frame(fn,loc_pc,imm0))
    5150         __(bne cr0,1f)
    5151         __(ref_global(imm0,lexpr_return))
    5152         __(build_lisp_frame(rzero,imm0,vsp))
    5153         __(mov loc_pc,imm1)
    5154         __(ldr(imm0,tcr.cs_limit(rcontext)))
    5155         __(trllt(sp,imm0))
    5156         __(mov fn,#0)
    5157         __(bx lr)
    5158 
    5159         /* The single-value case just needs to return to something that'll pop  */
    5160         /* the variable-length frame off of the vstack.  */
    5161 1:
    5162         __(ref_global(loc_pc,lexpr_return1v))
    5163         __(ldr(imm0,tcr.cs_limit(rcontext)))
    5164         __(trllt(sp,imm0))
    5165         __(mov fn,#0)
    5166         __(bx lr)
    5167 
    5168 /* */
    5169 /* Do a system call in Darwin.  The stack is set up much as it would be */
    5170 /* for a PowerOpen ABI ff-call: register parameters are in the stack */
    5171 /* frame, and there are 4 extra words at the bottom of the frame that */
    5172 /* we can carve a lisp frame out of. */
    5173 /*  */
    5174 /* System call return conventions are a little funky in Darwin: if "@sc" */
    5175 /* is the address of the "sc" instruction, errors return to @sc+4 and */
    5176 /* non-error cases return to @sc+8.  Error values are returned as */
    5177 /* positive values in r3; this is true even if the system call returns */
    5178 /* a doubleword (64-bit) result.  Since r3 would ordinarily contain */
    5179 /* the high half of a doubleword result, this has to be special-cased. */
    5180 /*  */
    5181 /* The caller should set the c_frame.crsave field of the stack frame */
    5182 /* to 0 if the result is to be interpreted as anything but a doubleword */
    5183 /* and to non-zero otherwise.  (This only matters on an error return.) */
    5184 
    5185        
    5186 _spentry(poweropen_syscall)
    5187         __(mflr loc_pc)
    5188         __(vpush_saveregs())
    5189         __(ldr(imm1,0(sp)))
    5190         __(la imm2,-lisp_frame.size(imm1))
    5191         __(zero_doublewords imm2,0,lisp_frame.size)
    5192         __(str(imm1,lisp_frame.backlink(imm2)))
    5193         __(str(imm2,c_frame.backlink(sp)))
    5194         __(str(fn,lisp_frame.savefn(imm2)))
    5195         __(str(loc_pc,lisp_frame.savelr(imm2)))
    5196         __(str(vsp,lisp_frame.savevsp(imm2)))
    5197         __(ldr(imm3,tcr.cs_area(rcontext)))
    5198         __(str(imm2,area.active(imm3)))
    5199         __(str(allocptr,tcr.save_allocptr(rcontext)))
    5200         __(str(allocbase,tcr.save_allocbase(rcontext)))
    5201         __(str(tsp,tcr.save_tsp(rcontext)))
    5202         __(str(vsp,tcr.save_vsp(rcontext)))
    5203         __(str(rzero,tcr.ffi_exception(rcontext)))
    5204         __(mov save0,rcontext)
    5205         __(mov r3,#TCR_STATE_FOREIGN)
    5206         __(str(r3,tcr.valence(rcontext)))
    5207         __(mov rcontext,#0)
    5208         __(ldr(r3,c_frame.param0(sp)))
    5209         __(ldr(r4,c_frame.param1(sp)))
    5210         __(ldr(r5,c_frame.param2(sp)))
    5211         __(ldr(r6,c_frame.param3(sp)))
    5212         __(ldr(r7,c_frame.param4(sp)))
    5213         __(ldr(r8,c_frame.param5(sp)))
    5214         __(ldr(r9,c_frame.param6(sp)))
    5215         __(ldr(r10,c_frame.param7(sp)))
    5216         __(unbox_fixnum(r0,arg_z))
    5217         __(sc)
    5218         __ifdef(`LINUX')
    5219          __(bns+ 9f)
    5220         __else
    5221          __(b 1f)
    5222          __(b 9f)
    5223         __endif
    5224 1:
    5225         __ifdef(`PPC64')
    5226          __(neg r3,r3)
    5227         __else
    5228          __(ldr(imm2,c_frame.crsave(sp)))
    5229          __(cmpri(cr0,imm2,0))
    5230          __(bne cr0,2f)
    5231          /* 32-bit result  */
    5232          __(neg r3,r3)
    5233          __(b 9f)
    5234 2:
    5235          /* 64-bit result  */
    5236          __(neg r4,r3)
    5237          __(mov r3,#-1)
    5238         __endif
    5239 9:
    5240         __(mov imm2,save0)      /* recover context  */
    5241         __(ldr(sp,c_frame.backlink(sp)))
    5242         __(mov imm4,#TCR_STATE_LISP)
    5243         __(mov rzero,#0)
    5244         __(mov loc_pc,#0)
    5245         __(mov arg_x,#nil_value)
    5246         __(mov arg_y,#nil_value)
    5247         __(mov arg_z,#nil_value)
    5248         __(mov temp0,#nil_value)
    5249         __(mov temp1,#nil_value)
    5250         __(mov temp2,#nil_value)
    5251         __(mov temp3,#nil_value)
    5252         __(mov fn,#nil_value)
    5253         __(mov rcontext,imm2)
    5254         __(ldr(allocptr,tcr.save_allocptr(rcontext)))
    5255         __(ldr(allocbase,tcr.save_allocbase(rcontext)))
    5256         __(ldr(tsp,tcr.save_tsp(rcontext)))
    5257         __(mov save0,#0)
    5258         __(mov save1,#0)
    5259         __(mov save2,#0)
    5260         __(mov save3,#0)
    5261         __(mov save4,#0)
    5262         __(mov save5,#0)
    5263         __(mov save6,#0)
    5264         __(mov save7,#0)       
    5265         __(str(imm4,tcr.valence(rcontext)))
    5266         __(vpop_saveregs)
    5267         __(ldr(loc_pc,lisp_frame.savelr(sp)))
    5268         __(mtlr loc_pc)
    5269         __(ldr(fn,lisp_frame.savefn(sp)))
    5270         __(discard_lisp_frame)
    5271         __(mtxer rzero)
    5272         __(check_pending_interrupt(`cr1'))
    5273         __(bx lr)
    5274        
    5275        
    5276 _spentry(builtin_plus)
    5277         __(extract_lisptag(imm0,arg_y))
    5278         __(extract_lisptag(imm1,arg_z))
    5279         __(cmpri(cr0,imm0,tag_fixnum))
    5280         __(cmpri(cr1,imm1,tag_fixnum))
    5281         __(bne- cr0,1f)
    5282         __(bne- cr1,1f)
    5283         __(addo. arg_z,arg_y,arg_z)
    5284         __(bnslr+)
    5285         __(mtxer rzero)
    5286         __(unbox_fixnum(imm1,arg_z))
    5287         __ifdef(`PPC64')
    5288          __(mov imm0,#two_digit_bignum_header)
    5289          __(rotldi imm1,imm1,32)
    5290          __(xoris imm1,imm1,0xe000)
    5291          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
    5292          __(str(imm1,misc_data_offset(arg_z)))
    5293         __else
    5294          __(mov imm0,#one_digit_bignum_header)
    5295          __(xoris imm1,imm1,0xc000)
    5296          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
    5297          __(str(imm1,misc_data_offset(arg_z)))
    5298         __endif
    5299         __(bx lr)
    5300 1:
    5301         __(jump_builtin(_builtin_plus,2))
    5302 _spentry(builtin_minus)
    5303         __(extract_lisptag(imm0,arg_y))
    5304         __(extract_lisptag(imm1,arg_z))
    5305         __(cmpri(cr0,imm0,tag_fixnum))
    5306         __(cmpri(cr1,imm1,tag_fixnum))
    5307         __(bne- cr0,1f)
    5308         __(bne- cr1,1f)
    5309         __(subo. arg_z,arg_y,arg_z)
    5310         __(bnslr+)
    5311         __(mtxer rzero)
    5312         __(unbox_fixnum(imm1,arg_z))
    5313         __ifdef(`PPC64')
    5314          __(mov imm0,#two_digit_bignum_header)
    5315          __(rotldi imm1,imm1,32)
    5316          __(xoris imm1,imm1,0xe000)
    5317          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
    5318          __(str(imm1,misc_data_offset(arg_z)))
    5319         __else
    5320          __(mov imm0,#one_digit_bignum_header)
    5321          __(xoris imm1,imm1,0xc000)
    5322          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
    5323          __(str(imm1,misc_data_offset(arg_z)))
    5324         __endif
    5325         __(bx lr)
    5326 1:
    5327         __(jump_builtin(_builtin_minus,2))
    5328 _spentry(builtin_times)
    5329         __(extract_lisptag(imm0,arg_y))
    5330         __(extract_lisptag(imm1,arg_z))
    5331         __(cmpri(cr0,imm0,tag_fixnum))
    5332         __(cmpri(cr1,imm1,tag_fixnum))
    5333         __(unbox_fixnum(imm2,arg_y))
    5334         __(bne cr0,1f)
    5335         __(bne cr1,1f)
    5336         __ifdef(`PPC64')
    5337          __(mulldo. imm3,arg_z,imm2)
    5338          __(bso 2f)
    5339          __(mov arg_z,imm3)
    5340          __(bx lr)
    5341          /* Args are fixnums; result can't be  */
    5342 2:       __(mtxer rzero)
    5343          __(unbox_fixnum(imm3,arg_z))
    5344          __(mulld imm1,imm3,imm2) /* imm1 = low  64 bits  */
    5345          __(mulhd imm0,imm3,imm2) /* imm0 = high 64 bits  */
    5346          __(b _SPmakes128)
    5347         __else
    5348          __(mullwo. imm3,arg_z,imm2)
    5349          __(bso 2f)             /*  SO set if result would overflow a fixnum  */
    5350          __(mov arg_z,imm3)
    5351          __(bx lr)
    5352          /* Args are fixnums; result can't be  */
    5353 2:       __(mtxer rzero)
    5354          __(unbox_fixnum(imm3,arg_z))
    5355          __(mullw imm1,imm3,imm2) /* imm1 = low  32 bits  */
    5356          __(mulhw imm0,imm3,imm2) /* imm0 = high 32 bits  */
    5357          __(b _SPmakes64)
    5358         __endif
    5359 
    5360 1:      __(jump_builtin(_builtin_times,2))
    5361 
    5362 _spentry(builtin_div)
    5363         __(jump_builtin(_builtin_div,2))
    5364 
    5365 _spentry(builtin_eq)
    5366         __(extract_lisptag(imm0,arg_y))
    5367         __(extract_lisptag(imm1,arg_z))
    5368         __(cmpri(cr0,imm0,tag_fixnum))
    5369         __(cmpri(cr1,imm1,tag_fixnum))
    5370         __(cmpr(cr2,arg_y,arg_z))
    5371         __(bne- cr0,1f)
    5372         __(bne- cr1,1f)
    5373         __(mov arg_z,#nil_value)
    5374         __(bnelr cr2)
    5375         __(mov arg_z,#t_value)
    5376         __(bx lr)
    5377 1:
    5378         __(jump_builtin(_builtin_eq,2))
    5379 
    5380 _spentry(builtin_ne)
    5381         __(extract_lisptag(imm0,arg_y))
    5382         __(extract_lisptag(imm1,arg_z))
    5383         __(cmpri(cr0,imm0,tag_fixnum))
    5384         __(cmpri(cr1,imm1,tag_fixnum))
    5385         __(cmpr(cr2,arg_y,arg_z))
    5386         __(bne- cr0,1f)
    5387         __(bne- cr1,1f)
    5388         __(mov arg_z,#nil_value)
    5389         __(beqlr cr2)
    5390         __(mov arg_z,#t_value)
    5391         __(bx lr)
    5392 1:
    5393         __(jump_builtin(_builtin_ne,2))
    5394 
    5395 _spentry(builtin_gt)
    5396         __(extract_lisptag(imm0,arg_y))
    5397         __(extract_lisptag(imm1,arg_z))
    5398         __(cmpri(cr0,imm0,tag_fixnum))
    5399         __(cmpri(cr1,imm1,tag_fixnum))
    5400         __(cmpr(cr2,arg_y,arg_z))
    5401         __(bne- cr0,1f)
    5402         __(bne- cr1,1f)
    5403         __(mov arg_z,#nil_value)
    5404         __(bnglr cr2)
    5405         __(mov arg_z,#t_value)
    5406         __(bx lr)
    5407 1:
    5408         __(jump_builtin(_builtin_gt,2))
    5409 
    5410 _spentry(builtin_ge)
    5411         __(extract_lisptag(imm0,arg_y))
    5412         __(extract_lisptag(imm1,arg_z))
    5413         __(cmpri(cr0,imm0,tag_fixnum))
    5414         __(cmpri(cr1,imm1,tag_fixnum))
    5415         __(cmpr(cr2,arg_y,arg_z))
    5416         __(bne- cr0,1f)
    5417         __(bne- cr1,1f)
    5418         __(mov arg_z,#nil_value)
    5419         __(bltlr cr2)
    5420         __(mov arg_z,#t_value)
    5421         __(bx lr)
    5422 1:
    5423         __(jump_builtin(_builtin_ge,2))
    5424 
    5425 _spentry(builtin_lt)
    5426         __(extract_lisptag(imm0,arg_y))
    5427         __(extract_lisptag(imm1,arg_z))
    5428         __(cmpri(cr0,imm0,tag_fixnum))
    5429         __(cmpri(cr1,imm1,tag_fixnum))
    5430         __(cmpr(cr2,arg_y,arg_z))
    5431         __(bne- cr0,1f)
    5432         __(bne- cr1,1f)
    5433         __(mov arg_z,#nil_value)
    5434         __(bnllr cr2)
    5435         __(mov arg_z,#t_value)
    5436         __(bx lr)
    5437 1:
    5438         __(jump_builtin(_builtin_lt,2))
    5439 
    5440 _spentry(builtin_le)
    5441         __(extract_lisptag(imm0,arg_y))
    5442         __(extract_lisptag(imm1,arg_z))
    5443         __(cmpri(cr0,imm0,tag_fixnum))
    5444         __(cmpri(cr1,imm1,tag_fixnum))
    5445         __(cmpr(cr2,arg_y,arg_z))
    5446         __(bne- cr0,1f)
    5447         __(bne- cr1,1f)
    5448         __(mov arg_z,#nil_value)
    5449         __(bgtlr cr2)
    5450         __(mov arg_z,#t_value)
    5451         __(bx lr)
    5452 1:
    5453         __(jump_builtin(_builtin_le,2))
    5454 
    5455 
    5456 _spentry(builtin_eql)
    5457         __(cmpr(cr1,arg_y,arg_z))
    5458         __(extract_fulltag(imm2,arg_y))
    5459         __(extract_fulltag(imm3,arg_z))
    5460         __(beq cr1,1f)
    5461         __(cmpri(cr1,imm2,fulltag_misc))
    5462         __(cmpri(cr0,imm3,fulltag_misc))
    5463         __(bne cr1,2f)
    5464         __(extract_subtag(imm0,arg_y))
    5465         __(bne cr0,2f)
    5466         __(extract_subtag(imm1,arg_z))
    5467         __(cmpr(cr0,imm0,imm1))
    5468         __(bne cr0,2f)
    5469         __(jump_builtin(_builtin_eql,2))
    5470 1:      __(mov arg_z,#t_value)
    5471         __(bx lr)
    5472 2:      __(mov arg_z,#nil_value)
    5473         __(bx lr)
    5474        
    5475 _spentry(builtin_length)
    5476         __(cmpri(cr1,arg_z,nil_value))
    5477         __(extract_typecode(imm0,arg_z))
    5478         __(cmpri(cr0,imm0,min_vector_subtag))
    5479         __(beq cr1,1f)
    5480         __ifdef(`PPC64')
    5481          __(cmpdi cr2,imm0,fulltag_cons)
    5482         __else
    5483          __(cmpwi cr2,imm0,tag_list)
    5484         __endif
    5485         __(beq- cr0,2f)
    5486         __(blt- cr0,3f)
    5487         /* (simple-array * (*))  */
    5488         __(vector_length(arg_z,arg_z,imm0))
    5489         __(bx lr)
    5490 1:      __(mov arg_z,#0)
    5491         __(bx lr)
    5492 2:
    5493         __(ldr(arg_z,vectorH.logsize(arg_z)))
    5494         __(bx lr)       
    5495 3:      __(bne cr2,8f)
    5496         __(mov temp2,#-1<<fixnum_shift)
    5497         __(mov temp0,arg_z)     /* fast pointer  */
    5498         __(mov temp1,arg_z)     /* slow pointer  */
    5499         __ifdef(`PPC64')
    5500 4:       __(extract_fulltag(imm0,temp0))
    5501          __(cmpdi cr7,temp0,nil_value)
    5502          __(cmpdi cr1,imm0,fulltag_cons)
    5503          __(addi temp2,temp2,fixnum_one)
    5504          __(beq cr7,9f)
    5505          __(andi. imm0,temp2,1<<fixnum_shift)
    5506          __(bne cr1,8f)
    5507          __(extract_fulltag(imm1,temp1))
    5508          __(_cdr(temp0,temp0))
    5509          __(cmpdi cr1,imm1,fulltag_cons)
    5510          __(beq cr0,4b)
    5511          __(bne cr1,8f)
    5512          __(_cdr(temp1,temp1))
    5513          __(cmpd cr0,temp0,temp1)
    5514          __(bne cr0,4b)
    5515         __else
    5516 4:       __(extract_lisptag(imm0,temp0))
    5517          __(cmpri(cr7,temp0,nil_value))
    5518          __(cmpri(cr1,imm0,tag_list))
    5519          __(addi temp2,temp2,fixnum_one)
    5520          __(beq cr7,9f)
    5521          __(andi. imm0,temp2,1<<fixnum_shift)
    5522          __(bne cr1,8f)
    5523          __(extract_lisptag(imm1,temp1))       
    5524          __(_cdr(temp0,temp0))
    5525          __(cmpri(cr1,imm1,tag_list))
    5526          __(beq cr0,4b)
    5527          __(bne cr1,8f)
    5528          __(_cdr(temp1,temp1))
    5529          __(cmpr(cr0,temp0,temp1))
    5530          __(bne cr0,4b)
    5531         __endif
    5532 8:     
    5533         __(jump_builtin(_builtin_length,1))
    5534 9:     
    5535         __(mov arg_z,temp2)
    5536         __(bx lr)
    5537        
    5538 _spentry(builtin_seqtype)
    5539         __ifdef(`PPC64')
    5540          __(cmpdi cr2,arg_z,nil_value)
    5541          __(extract_typecode(imm0,arg_z))
    5542          __(beq cr2,1f)
    5543          __(cmpri(cr0,imm0,fulltag_cons))
    5544         __else
    5545          __(extract_typecode(imm0,arg_z))
    5546          __(cmpri(cr0,imm0,tag_list))
    5547         __endif
    5548         __(cmpri(cr1,imm0,min_vector_subtag))
    5549         __(beq cr0,1f)
    5550         __(blt- cr1,2f)
    5551         __(mov arg_z,#nil_value)
    5552         __(bx lr)
    5553 1:      __(mov arg_z,#t_value)
    5554         __(bx lr)
    5555 2:
    5556         __(jump_builtin(_builtin_seqtype,1))
    5557        
    5558 _spentry(builtin_assq)
    5559         __(cmpri(arg_z,nil_value))
    5560         __(beqlr)
    5561 1:      __(trap_unless_list(arg_z,imm0))
    5562         __(_car(arg_x,arg_z))
    5563         __(_cdr(arg_z,arg_z))
    5564         __(cmpri(cr2,arg_x,nil_value))
    5565         __(cmpri(cr1,arg_z,nil_value))
    5566         __(beq cr2,2f)
    5567         __(trap_unless_list(arg_x,imm0))
    5568         __(_car(temp0,arg_x))
    5569         __(cmpr(temp0,arg_y))
    5570         __(bne cr0,2f)
    5571         __(mov arg_z,arg_x)
    5572         __(bx lr)
    5573 2:      __(bne cr1,1b)
    5574         __(bx lr)
    5575 
    5576 _spentry(builtin_memq)
    5577         __(cmpri(cr1,arg_z,nil_value))
    5578         __(b 2f)
    5579 1:      __(trap_unless_list(arg_z,imm0))
    5580         __(_car(arg_x,arg_z))
    5581         __(_cdr(temp0,arg_z))
    5582         __(cmpr(arg_x,arg_y))
    5583         __(cmpri(cr1,temp0,nil_value))
    5584         __(beqlr)
    5585         __(mov arg_z,temp0)
    5586 2:      __(bne cr1,1b)
    5587         __(bx lr)
    5588 
    5589         __ifdef(`PPC64')
    5590 logbitp_max_bit = 61
    5591         __else
    5592 logbitp_max_bit = 30
    5593         __endif
    5594        
    5595 _spentry(builtin_logbitp)
    5596         /* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
    5597         __(cmplri(cr2,arg_y,logbitp_max_bit<<fixnum_shift))
    5598         __(extract_lisptag(imm0,arg_y))
    5599         __(extract_lisptag(imm1,arg_z))
    5600         __(cmpri(cr0,imm0,tag_fixnum))
    5601         __(cmpri(cr1,imm1,tag_fixnum))
    5602         __(unbox_fixnum(imm0,arg_y))
    5603         __(subfic imm0,imm0,logbitp_max_bit)
    5604         __ifdef(`PPC64')
    5605          __(rldcl imm0,arg_z,imm0,63)
    5606          __(mulli imm0,imm0,t_offset)
    5607         __else
    5608          __(rlwnm imm0,arg_z,imm0,31,31)
    5609          __(rlwimi imm0,imm0,4,27,27)
    5610         __endif
    5611         __(bnl cr2,1f)
    5612         __(bne cr0,1f)
    5613         __(bne cr1,1f)
    5614         __(addi arg_z,imm0,nil_value)
    5615         __(bx lr)
    5616 1:
    5617         __(jump_builtin(_builtin_logbitp,2))
    5618 
    5619 _spentry(builtin_logior)
    5620         __(extract_lisptag(imm0,arg_y))
    5621         __(extract_lisptag(imm1,arg_z))
    5622         __(cmpri(cr0,imm0,tag_fixnum))
    5623         __(cmpri(cr1,imm1,tag_fixnum))
    5624         __(bne- cr0,1f)
    5625         __(bne- cr1,1f)
    5626         __(or arg_z,arg_y,arg_z)
    5627         __(bx lr)
    5628 1:
    5629         __(jump_builtin(_builtin_logior,2))
    5630 
    5631 _spentry(builtin_logand)
    5632         __(extract_lisptag(imm0,arg_y))
    5633         __(extract_lisptag(imm1,arg_z))
    5634         __(cmpri(cr0,imm0,tag_fixnum))
    5635         __(cmpri(cr1,imm1,tag_fixnum))
    5636         __(bne- cr0,1f)
    5637         __(bne- cr1,1f)
    5638         __(and arg_z,arg_y,arg_z)
    5639         __(bx lr)
    5640 1:
    5641         __(jump_builtin(_builtin_logand,2))
    5642        
    5643 _spentry(builtin_ash)
    5644         __ifdef(`PPC64')
    5645          __(cmpdi cr1,arg_z,0)
    5646          __(extract_lisptag(imm0,arg_y))
    5647          __(extract_lisptag(imm1,arg_z))
    5648          __(cmpdi cr0,imm0,tag_fixnum)
    5649          __(cmpdi cr3,imm1,tag_fixnum)
    5650          __(cmpdi cr2,arg_z,-(63<<3))   /* !! 3 =  fixnumshift  */
    5651          __(bne- cr0,9f)
    5652          __(bne- cr3,9f)
    5653          __(bne cr1,0f)
    5654          __(mov arg_z,arg_y)    /* (ash n 0) => n  */
    5655          __(bx lr)
    5656 0:             
    5657          __(unbox_fixnum(imm1,arg_y))
    5658          __(unbox_fixnum(imm0,arg_z))
    5659          __(bgt cr1,2f)
    5660          /* (ash n -count) => fixnum  */
    5661          __(neg imm2,imm0)
    5662          __(bgt cr2,1f)
    5663          __(mov imm2,#63)
    5664 1:     
    5665          __(srad imm0,imm1,imm2)
    5666          __(box_fixnum(arg_z,imm0))
    5667          __(bx lr)
    5668          /* Integer-length of arg_y/imm1 to imm2  */
    5669 2:             
    5670          __(cntlzd. imm2,imm1)
    5671          __(bne 3f)             /* cr0`eq' set if negative  */
    5672          __(not imm2,imm1)
    5673          __(cntlzd imm2,imm2)
    5674 3:
    5675          __(subfic imm2,imm2,64)
    5676          __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
    5677          __(cmpdi cr1,imm2,63-fixnumshift)
    5678          __(cmpdi cr2,imm0,64)
    5679          __(sld imm2,imm1,imm0)
    5680          __(bgt cr1,6f)
    5681          __(box_fixnum(arg_z,imm2))
    5682          __(bx lr)     
    5683 6:
    5684          __(bgt cr2,9f)
    5685          __(bne cr2,7f)
    5686          /* Shift left by 64 bits exactly  */
    5687          __(mov imm0,imm1)
    5688          __(mov imm1,#0)
    5689          __(beq _SPmakes128)
    5690          __(b _SPmakeu128)
    5691 7:
    5692          /* Shift left by fewer than 64 bits, result not a fixnum  */
    5693          __(subfic imm0,imm0,64)
    5694          __(beq 8f)
    5695          __(srd imm0,imm1,imm0)
    5696          __(mov imm1,imm2)
    5697          __(b _SPmakeu128)
    5698 8:     
    5699          __(srad imm0,imm1,imm0)
    5700          __(mov imm1,imm2)
    5701          __(b _SPmakes128)
    5702         __else
    5703          __(cmpri(cr1,arg_z,0))
    5704          __(extract_lisptag(imm0,arg_y))
    5705          __(extract_lisptag(imm1,arg_z))
    5706          __(cmpri(cr0,imm0,tag_fixnum))
    5707          __(cmpri(cr3,imm1,tag_fixnum))
    5708          __(cmpri(cr2,arg_z,-(29<<2)))  /* !! 2 =  fixnumshift  */
    5709          __(bne- cr0,9f)
    5710          __(bne- cr3,9f)
    5711          __(bne cr1,0f)
    5712          __(mov arg_z,arg_y)    /* (ash n 0) => n  */
    5713          __(bx lr)
    5714 0:             
    5715          __(unbox_fixnum(imm1,arg_y))
    5716          __(unbox_fixnum(imm0,arg_z))
    5717          __(bgt cr1,2f)
    5718          /* (ash n -count) => fixnum  */
    5719          __(neg imm2,imm0)
    5720          __(bgt cr2,1f)
    5721          __(mov imm2,#31)
    5722 1:     
    5723          __(sraw imm0,imm1,imm2)
    5724          __(box_fixnum(arg_z,imm0))
    5725          __(bx lr)
    5726          /* Integer-length of arg_y/imm1 to imm2  */
    5727 2:             
    5728          __(cntlzw. imm2,imm1)
    5729          __(bne 3f)             /* cr0`eq' set if negative  */
    5730          __(not imm2,imm1)
    5731          __(cntlzw imm2,imm2)
    5732 3:
    5733          __(subfic imm2,imm2,32)
    5734          __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
    5735          __(cmpri(cr1,imm2,31-fixnumshift))
    5736          __(cmpri(cr2,imm0,32))
    5737          __(slw imm2,imm1,imm0)
    5738          __(bgt cr1,6f)
    5739          __(box_fixnum(arg_z,imm2))
    5740          __(bx lr)     
    5741 6:
    5742          __(bgt cr2,9f)
    5743          __(bne cr2,7f)
    5744          /* Shift left by 32 bits exactly  */
    5745          __(mov imm0,imm1)
    5746          __(mov imm1,#0)
    5747          __(beq _SPmakes64)
    5748          __(b _SPmakeu64)
    5749 7:
    5750          /* Shift left by fewer than 32 bits, result not a fixnum  */
    5751          __(subfic imm0,imm0,32)
    5752          __(beq 8f)
    5753          __(srw imm0,imm1,imm0)
    5754          __(mov imm1,imm2)
    5755          __(b _SPmakeu64)
    5756 8:     
    5757          __(sraw imm0,imm1,imm0)
    5758          __(mov imm1,imm2)
    5759          __(b _SPmakes64)
    5760         __endif
    5761 9:             
    5762         __(jump_builtin(_builtin_ash,2))
    5763 
    5764 _spentry(builtin_negate)
    5765         __(extract_lisptag_(imm0,arg_z))
    5766         __(bne- cr0,1f)
    5767         __(nego. arg_z,arg_z)
    5768         __(bnslr+)
    5769         __(mtxer rzero)
    5770         __(unbox_fixnum(imm1,arg_z))
    5771         __ifdef(`PPC64')
    5772          __(mov imm0,#two_digit_bignum_header)
    5773          __(rotldi imm1,imm1,32)
    5774          __(xoris imm1,imm1,0xe000)
    5775          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
    5776          __(str(imm1,misc_data_offset(arg_z)))
    5777         __else
    5778          __(mov imm0,#one_digit_bignum_header)
    5779          __(xoris imm1,imm1,0xc000)
    5780          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
    5781          __(str(imm1,misc_data_offset(arg_z)))
    5782         __endif
    5783         __(bx lr)
    5784 1:
    5785         __(jump_builtin(_builtin_negate,1))
    5786 
    5787 _spentry(builtin_logxor)
    5788         __(extract_lisptag(imm0,arg_y))
    5789         __(extract_lisptag(imm1,arg_z))
    5790         __(cmpri(cr0,imm0,tag_fixnum))
    5791         __(cmpri(cr1,imm1,tag_fixnum))
    5792         __(bne- cr0,1f)
    5793         __(bne- cr1,1f)
    5794         __(xor arg_z,arg_y,arg_z)
    5795         __(bx lr)
    5796 1:
    5797         __(jump_builtin(_builtin_logxor,2))
    5798 
    5799 
    5800 
    5801        
    5802 _spentry(builtin_aset1)
    5803         __(extract_typecode(imm0,arg_x))
    5804         __(cmpri(cr0,imm0,min_vector_subtag))
    5805         __(box_fixnum(temp0,imm0))
    5806         __(bgt cr0,1f)
    5807         __(jump_builtin(_builtin_aset1,3))
    5808 1:
    5809         __(b _SPsubtag_misc_set)
    5810 
    5811 /* Enter the debugger  */
    5812 _spentry(breakpoint)
    5813         __(mov r3,#0)
    5814         __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter)  */
    5815         __(bx lr)               /* if handler didn't  */
    5816 
    5817 /* */
    5818 /* We're entered with an eabi_c_frame on the C stack.  There's a */
    5819 /* lisp_frame reserved underneath it; we'll link it in in a minute. */
    5820 /* Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
    5821 /* then shrink the eabi_c_frame. */
    5822 /*  */
    5823        
    5824 _spentry(eabi_ff_call)
    5825         __(mflr loc_pc)
    5826         __(str(sp,eabi_c_frame.savelr(sp)))
    5827         __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
    5828         __(mov save0,rcontext)  /* or address globals.  */
    5829         __(extract_typecode(imm0,arg_z))
    5830         __(cmpri(imm0,subtag_macptr))
    5831         __(ldr(save1,0(sp)))    /* bottom of reserved lisp frame  */
    5832         __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
    5833         __(zero_doublewords save2,0,lisp_frame.size)
    5834         __(str(save1,lisp_frame.backlink(save2)))
    5835         __(str(save2,c_frame.backlink(sp)))
    5836         __(str(fn,lisp_frame.savefn(save2)))
    5837         __(str(loc_pc,lisp_frame.savelr(save2)))
    5838         __(str(vsp,lisp_frame.savevsp(save2)))
    5839         __(bne 1f)
    5840         __(ldr(arg_z,macptr.address(arg_z)))
    5841 1:
    5842         __(ldr(save3,tcr.cs_area(rcontext)))
    5843         __(str(save2,area.active(save3)))
    5844         __(str(allocptr,tcr.save_allocptr(rcontext)))
    5845         __(str(allocbase,tcr.save_allocbase(rcontext)))
    5846         __(str(tsp,tcr.save_tsp(rcontext)))
    5847         __(str(vsp,tcr.save_vsp(rcontext)))
    5848         __(mtctr arg_z)
    5849         __(str(rzero,tcr.ffi_exception(rcontext)))
    5850         __(mffs f0)
    5851         __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
    5852         __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
    5853         __(mov imm1,#TCR_STATE_FOREIGN)
    5854         __(str(imm1,tcr.valence(rcontext)))
    5855         __(ldr(r2,tcr.native_thread_info(rcontext)))
    5856         __(ldr(r13,lisp_globals.saveR13(0)))
    5857         __(ldr(r3,eabi_c_frame.param0(sp)))
    5858         __(ldr(r4,eabi_c_frame.param1(sp)))
    5859         __(ldr(r5,eabi_c_frame.param2(sp)))
    5860         __(ldr(r6,eabi_c_frame.param3(sp)))
    5861         __(ldr(r7,eabi_c_frame.param4(sp)))
    5862         __(ldr(r8,eabi_c_frame.param5(sp)))
    5863         __(ldr(r9,eabi_c_frame.param6(sp)))
    5864         __(ldr(r10,eabi_c_frame.param7(sp)))
    5865         __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
    5866         __(str(rzero,eabi_c_frame.savelr(save1)))
    5867         __(str(save2,eabi_c_frame.backlink(save1)))
    5868         __(mov sp,save1)
    5869         /* If we're calling a varargs C function, it'll want to */
    5870         /* know whether or not we've passed any args in FP regs. */
    5871         /* Better to say that we did (and force callee to save FP */
    5872         /* arg regs on entry) than to say that we didn't and get */
    5873         /* garbage results  */
    5874         __(crset 6)
    5875         __(bctrl)
    5876         /* C should have preserved save0 (= rcontext) for us.  */
    5877         __(ldr(sp,0(sp)))
    5878         __(mov imm2,save0)
    5879         __(ldr(vsp,lisp_frame.savevsp(sp)))
    5880         __(mov rzero,#0)
    5881         __(mov loc_pc,rzero)
    5882         __(mov arg_x,#nil_value)
    5883         __(mov arg_y,#nil_value)
    5884         __(mov arg_z,#nil_value)
    5885         __(mov temp0,#nil_value)
    5886         __(mov temp1,#nil_value)
    5887         __(mov temp2,#nil_value)
    5888         __(mov temp3,#nil_value)
    5889         __(mov fn,#nil_value)
    5890         __(mov rcontext,imm2)
    5891         __(mov imm2,#TCR_STATE_LISP)
    5892         __(ldr(tsp,tcr.save_tsp(rcontext)))
    5893         __(mov save0,#0)
    5894         __(mov save1,#0)
    5895         __(mov save2,#0)
    5896         __(mov save3,#0)
    5897         __(mov save4,#0)
    5898         __(mov save5,#0)
    5899         __(mov save6,#0)
    5900         __(mov save7,#0)
    5901         __(mov allocptr,#-dnode_size)
    5902         __(mov allocbase,#-dnode_size)
    5903         __(str(imm2,tcr.valence(rcontext)))     
    5904         __(vpop_saveregs())
    5905         __(ldr(allocptr,tcr.save_allocptr(rcontext)))
    5906         __(ldr(allocbase,tcr.save_allocbase(rcontext)))
    5907         __(ldr(loc_pc,lisp_frame.savelr(sp)))
    5908         __(mtlr loc_pc)
    5909         __(ldr(fn,lisp_frame.savefn(sp)))
    5910         __(mffs f0)
    5911         __(stfd f0,8(sp))
    5912         __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
    5913         __(clrrwi imm2,imm3,8)
    5914         __(discard_lisp_frame())
    5915         __(str(imm2,tcr.ffi_exception(rcontext)))
    5916         __(lfd f0,tcr.lisp_fpscr(rcontext))
    5917         __(mtfsf 0xff,f0)
    5918         __(check_pending_interrupt(`cr1'))
    5919         __(mtxer rzero)
    5920         __(mtctr rzero)
    5921         __(bx lr)
    5922        
    5923 /*  */
    5924 /* This gets called with R11 holding the unboxed callback index. */
    5925 /* */
    5926        
    5927 _spentry(eabi_callback)
    5928         /* First, we extend the C frame so that it has room for */
    5929         /* incoming arg regs.  */
    5930         __(ldr(r0,eabi_c_frame.backlink(sp)))
    5931         __(stru(r0,eabi_c_frame.param0-varargs_eabi_c_frame.incoming_stack_args(sp)))
    5932         __(mflr r0)
    5933         __(str(r0,varargs_eabi_c_frame.savelr(sp)))
    5934         __(str(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
    5935         __(str(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
    5936         __(str(r5,varargs_eabi_c_frame.gp_save+(2*4)(sp)))
    5937         __(str(r6,varargs_eabi_c_frame.gp_save+(3*4)(sp)))
    5938         __(str(r7,varargs_eabi_c_frame.gp_save+(4*4)(sp)))
    5939         __(str(r8,varargs_eabi_c_frame.gp_save+(5*4)(sp)))
    5940         __(str(r9,varargs_eabi_c_frame.gp_save+(6*4)(sp)))
    5941         __(str(r10,varargs_eabi_c_frame.gp_save+(7*4)(sp)))
    5942         /* Could check the appropriate CR bit and skip saving FP regs here  */
    5943         __(stfd f1,varargs_eabi_c_frame.fp_save+(0*8)(sp))
    5944         __(stfd f2,varargs_eabi_c_frame.fp_save+(1*8)(sp))
    5945         __(stfd f3,varargs_eabi_c_frame.fp_save+(2*8)(sp))
    5946         __(stfd f4,varargs_eabi_c_frame.fp_save+(3*8)(sp))
    5947         __(stfd f5,varargs_eabi_c_frame.fp_save+(4*8)(sp))
    5948         __(stfd f6,varargs_eabi_c_frame.fp_save+(5*8)(sp))
    5949         __(stfd f7,varargs_eabi_c_frame.fp_save+(6*8)(sp))
    5950         __(stfd f8,varargs_eabi_c_frame.fp_save+(7*8)(sp))
    5951         __(la r0,varargs_eabi_c_frame.incoming_stack_args(sp))
    5952         __(str(r0,varargs_eabi_c_frame.overflow_arg_area(sp)))
    5953         __(la r0,varargs_eabi_c_frame.regsave(sp))
    5954         __(str(r0,varargs_eabi_c_frame.reg_save_area(sp)))
    5955         __(mov r0,#0)
    5956         __(str(r0,varargs_eabi_c_frame.flags(sp)))
    5957 
    5958         /* Save the non-volatile registers on the sp stack  */
    5959         /* This is a non-standard stack frame, but noone will ever see it,  */
    5960         /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
    5961         __(stru(sp,-(c_reg_save.size)(sp)))
    5962         __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
    5963         __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
    5964         __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
    5965         __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
    5966         __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
    5967         __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
    5968         __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
    5969         __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
    5970         __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
    5971         __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
    5972         __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
    5973         __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
    5974         __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
    5975         __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
    5976         __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
    5977         __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
    5978         __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
    5979         __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
    5980         __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
    5981         __(mffs f0)
    5982         __(stfd f0,c_reg_save.save_fp_zero(sp))
    5983         __(ldr(r31,c_reg_save.save_fp_zero+4(sp)))      /* recover FPSCR image  */
    5984         __(str(r31,c_reg_save.save_fpscr(sp)))
    5985         __(lwi(r30,0x43300000))
    5986         __(lwi(r31,0x80000000))
    5987         __(str(r30,c_reg_save.save_fp_zero(sp)))
    5988         __(str(r31,c_reg_save.save_fp_zero+4(sp)))
    5989         __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
    5990         __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
    5991         __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
    5992         __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
    5993 
    5994        
    5995 /* Restore rest of Lisp context.  */
    5996 /* Could spread out the memory references here to gain a little speed  */
    5997         __(mov loc_pc,#0)
    5998         __(mov fn,#0)                     /* subprim, not a lisp function  */
    5999         __(mov temp3,#0)
    6000         __(mov temp2,#0)
    6001         __(mov temp1,#0)
    6002         __(mov temp0,#0)
    6003         __(mov arg_x,#0)
    6004         __(box_fixnum(arg_y,r11))       /* callback-index  */
    6005         __(la arg_z,c_reg_save.size+varargs_eabi_c_frame.gp_save(sp))   /* parameters (tagged as a fixnum)  */
    6006 
    6007         /* Recover lisp thread context. Have to call C code to do so.  */
    6008         __(ref_global(r12,get_tcr))
    6009         __(mtctr r12)
    6010         __(mov r3,#1)
    6011         __(stru(sp,-(stack_align(eabi_c_frame.minsiz))(sp)))
    6012         __(bctrl)
    6013         __(la sp,(stack_align(eabi_c_frame.minsiz))(sp))
    6014         __(la rcontext,TCR_BIAS(r3))
    6015         __(mov allocptr,#0)
    6016         __(mov allocbase,#0)
    6017         __(ldr(vsp,tcr.save_vsp(rcontext)))
    6018         __(ldr(tsp,tcr.save_tsp(rcontext)))             
    6019         __(mov rzero,#0)
    6020         __(mtxer rzero) /* lisp wants the overflow bit clear  */
    6021         __(mov imm0,#TCR_STATE_LISP)
    6022         __(mov save0,#0)
    6023         __(mov save1,#0)
    6024         __(mov save2,#0)
    6025         __(mov save3,#0)
    6026         __(mov save4,#0)
    6027         __(mov save5,#0)
    6028         __(mov save6,#0)
    6029         __(mov save7,#0)
    6030         __(mtctr rzero)
    6031         __(str(imm0,tcr.valence(rcontext)))
    6032         __(ldr(allocptr,tcr.save_allocptr(rcontext)))
    6033         __(ldr(allocbase,tcr.save_allocbase(rcontext)))
    6034         __(lfd f0,tcr.lisp_fpscr(rcontext))
    6035         __(mtfsf 0xff,f0)
    6036 
    6037         __(restore_saveregs(vsp))       
    6038         /* load nargs and callback to the lisp  */
    6039         __(set_nargs(2))
    6040         __(ldr(imm2,tcr.cs_area(rcontext)))
    6041         __(ldr(imm4,area.active(imm2)))
    6042         __(stru(imm4,-lisp_frame.size(sp)))
    6043         __(str(imm3,lisp_frame.savelr(sp)))
    6044         __(str(vsp,lisp_frame.savevsp(sp)))     /* for stack overflow code  */
    6045         __(mov fname,#nrs.callbacks)    /* %pascal-functions%  */
    6046         __(call_fname)
    6047         __(ldr(imm2,lisp_frame.backlink(sp)))
    6048         __(ldr(imm3,tcr.cs_area(rcontext)))
    6049         __(str(imm2,area.active(imm3)))
    6050         __(discard_lisp_frame())
    6051         /* save_vsp will be restored from ff_call's stack frame, but  */
    6052         /* I included it here for consistency.  */
    6053         /* save_tsp is set below after we exit Lisp context.  */
    6054         __(str(allocptr,tcr.save_allocptr(rcontext)))
    6055         __(str(allocbase,tcr.save_allocbase(rcontext)))
    6056         __(str(vsp,tcr.save_vsp(rcontext)))
    6057         __(str(tsp,tcr.save_tsp(rcontext)))
    6058         /* Exit lisp context  */
    6059         /* This is not necessary yet, but will be once we can be interrupted  */
    6060         __(mov imm1,#TCR_STATE_FOREIGN)
    6061         __(str(imm1,tcr.valence(rcontext)))
    6062         /* Restore the non-volatile registers & fpscr  */
    6063         __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
    6064         __(ldr(r31,c_reg_save.save_fpscr(sp)))
    6065         __(str(r31,c_reg_save.save_fp_zero+4(sp)))
    6066         __(lfd f0,c_reg_save.save_fp_zero(sp))
    6067         __(mtfsf 0xff,f0)
    6068         __(ldr(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
    6069         __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
    6070         __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
    6071         __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
    6072         __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
    6073         __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
    6074         __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
    6075         __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
    6076         __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
    6077         __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
    6078         __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
    6079         __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
    6080         __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
    6081         __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
    6082         __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
    6083         __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
    6084         __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
    6085         __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
    6086         __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
    6087         __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
    6088         __(ldr(sp,0(sp)))
    6089 
    6090         __(ldr(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
    6091         __(ldr(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
    6092         __(lfd f1,varargs_eabi_c_frame.gp_save+(2*4)(sp))
    6093         __(ldr(r5,varargs_eabi_c_frame.savelr(sp)))
    6094         __(str(r5,varargs_eabi_c_frame.old_savelr(sp)))
    6095         __(mtlr r5)
    6096         __(ldr(r5,varargs_eabi_c_frame.backlink(sp)))
    6097         __(str(r5,varargs_eabi_c_frame.old_backlink(sp)))
    6098         __(la sp,varargs_eabi_c_frame.old_backlink(sp))
    6099         __(bx lr)
    6100        
    6101 
    6102 /*      Do a linux system call:  the system call index is (boxed) */
    6103 /*      in arg_z, and other arguments are in an eabi_c_frame on */
    6104 /*      the C stack.  As is the case with an eabi_ff_call, there's */
    6105 /*      a lisp frame reserved underneath the eabi_c_frame. */
    6106 
    6107 /*      This is a little simpler than eabi_ff_call, because we */
    6108 /*      can assume that there are no synchronous callbacks to */
    6109 /*      lisp (that might cause a GC.)  It's also simpler for the */
    6110 /*      caller, since we return error status atomically. */
    6111 
    6112 /*      A system call can clobber any or all of r9-r12, so we need */
    6113 /*      to save and restore allocptr, allocbase, and tsp. */
    6114        
    6115 _spentry(eabi_syscall)
    6116 /*      We're entered with an eabi_c_frame on the C stack.  There's a */
    6117 /*      lisp_frame reserved underneath it; we'll link it in in a minute. */
    6118 /*      Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
    6119 /*      then shrink the eabi_c_frame. */
    6120 
    6121         __(mflr loc_pc)
    6122         __(vpush_saveregs())
    6123         __(str(sp,eabi_c_frame.savelr(sp)))
    6124         __(mov arg_x,#nil_value)
    6125         __(mov temp0,rcontext)
    6126         __(ldr(temp1,c_frame.backlink(sp)))     /* bottom of reserved lisp frame  */
    6127         __(la temp2,-lisp_frame.size(temp1))    /* top of lisp frame  */
    6128         __(zero_doublewords temp2,0,lisp_frame.size)
    6129         __(str(temp1,lisp_frame.backlink(temp2)))
    6130         __(str(temp2,c_frame.backlink(sp)))
    6131         __(str(fn,lisp_frame.savefn(temp2)))
    6132         __(str(loc_pc,lisp_frame.savelr(temp2)))
    6133         __(str(vsp,lisp_frame.savevsp(temp2)))
    6134         __(ldr(temp3,tcr.cs_area(rcontext)))
    6135         __(str(temp2,area.active(temp3)))
    6136         __(str(allocptr,tcr.save_allocptr(rcontext)))
    6137         __(str(allocbase,tcr.save_allocbase(rcontext)))
    6138         __(str(tsp,tcr.save_tsp(rcontext)))
    6139         __(str(vsp,tcr.save_vsp(rcontext)))
    6140         __(str(rzero,tcr.ffi_exception(rcontext)))
    6141         __(mov imm1,#TCR_STATE_FOREIGN)
    6142         __(str(imm1,tcr.valence(rcontext)))
    6143         __(ldr(r13,lisp_globals.saveR13(0)))
    6144         __(ldr(r3,eabi_c_frame.param0(sp)))
    6145         __(ldr(r4,eabi_c_frame.param1(sp)))
    6146         __(ldr(r5,eabi_c_frame.param2(sp)))
    6147         __(ldr(r6,eabi_c_frame.param3(sp)))
    6148         __(ldr(r7,eabi_c_frame.param4(sp)))
    6149         __(ldr(r8,eabi_c_frame.param5(sp)))
    6150         __(ldr(r9,eabi_c_frame.param6(sp)))
    6151         __(ldr(r10,eabi_c_frame.param7(sp)))
    6152         __(la temp1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
    6153         __(str(rzero,eabi_c_frame.savelr(temp1)))
    6154         __(str(temp2,eabi_c_frame.backlink(temp1)))
    6155         __(mov sp,temp1)
    6156         __(unbox_fixnum(r0,arg_z))
    6157         __(sc)
    6158         __(nop)
    6159         /* C should have preserved temp0 (= rcontext) for us.  */
    6160         __(ldr(sp,0(sp)))
    6161         __(mov imm2,temp0)
    6162         __(ldr(vsp,lisp_frame.savevsp(sp)))
    6163         __(mov rzero,#0)
    6164         __(mov loc_pc,rzero)
    6165         __(mov fn,rzero)
    6166         __(mov arg_x,#nil_value)
    6167         __(mov arg_y,#nil_value)
    6168         __(mov arg_z,#nil_value)
    6169         __(mov temp0,#nil_value)
    6170         __(mov temp1,#nil_value)
    6171         __(mov temp2,#nil_value)
    6172         __(mov temp3,#nil_value)
    6173         __(mov fn,#nil_value)
    6174        
    6175         __(mov imm3,#TCR_STATE_LISP)
    6176         __(mov rcontext,imm2)
    6177         __(mov save0,#0)
    6178         __(mov save1,#0)
    6179         __(mov save2,#0)
    6180         __(mov save3,#0)
    6181         __(mov save4,#0)
    6182         __(mov save5,#0)
    6183         __(mov save6,#0)
    6184         __(mov save7,#0)       
    6185         __(str(imm3,tcr.valence(rcontext)))
    6186         __(vpop_saveregs)
    6187         __(ldr(allocptr,tcr.save_allocptr(rcontext)))
    6188         __(ldr(allocbase,tcr.save_allocbase(rcontext)))
    6189         __(ldr(tsp,tcr.save_tsp(rcontext)))
    6190         __(ldr(loc_pc,lisp_frame.savelr(sp)))
    6191         __(mtlr loc_pc)
    6192         __(ldr(fn,lisp_frame.savefn(sp)))
    6193         __(discard_lisp_frame())
    6194         __(bns 1f)
    6195         __(neg r3,r3)
    6196 1:     
    6197         __(check_pending_interrupt(`cr1'))               
    6198         __(mtxer rzero)
    6199         __(bx lr)
    6200        
    6201 /* arg_z should be of type (UNSIGNED-BYTE 64);  */
    6202 /* On PPC32, return high 32 bits in imm0, low 32 bits in imm1 */
    6203 /* On PPC64, return unboxed value in imm0  */
    6204 
    6205 _spentry(getu64)
    6206         __ifdef(`PPC64')
    6207         __(extract_typecode(imm0,arg_z))
    6208         __(cmpdi cr0,imm0,tag_fixnum)
    6209         __(cmpdi cr2,arg_z,0)
    6210         __(cmpdi cr1,imm0,subtag_bignum)
    6211         __(bne cr0,1f)
    6212         __(unbox_fixnum(imm0,arg_z))
    6213         __(bgelr cr2)
    6214 0:             
    6215         __(uuo_interr(error_object_not_u64,arg_z))
    6216        
    6217 1:      __(bne cr1,0b)
    6218         __(getvheader(imm1,arg_z))
    6219         __(ld imm0,misc_data_offset(arg_z))
    6220         __(cmpdi cr2,imm1,two_digit_bignum_header)
    6221         __(rotldi imm0,imm0,32)
    6222         __(cmpdi cr1,imm1,three_digit_bignum_header)
    6223         __(cmpdi cr0,imm0,0)
    6224         __(beq cr2,2f)
    6225         __(lwz imm1,misc_data_offset+8(arg_z))
    6226         __(bne cr1,0b)
    6227         __(cmpwi imm1,0)
    6228         __(bne 0b)
    6229         __(bx lr)
    6230 2:      __(blt 0b)
    6231         __(bx lr)       
    6232         __else
    6233         __(extract_typecode(imm0,arg_z))
    6234         __(cmpri(cr0,imm0,tag_fixnum))
    6235         __(cmpri(cr1,arg_z,0))
    6236         __(cmpri(cr2,imm0,subtag_bignum))
    6237         __(unbox_fixnum(imm1,arg_z))
    6238         __(bne cr0,8f)
    6239         __(bgelr cr1)
    6240 9:
    6241         __(uuo_interr(error_object_not_u64,arg_z))
    6242 8:
    6243         __(bne- cr2,9b)
    6244         __(getvheader(imm2,arg_z))
    6245         __(cmpri(cr2,imm2,two_digit_bignum_header))
    6246         __(vrefr(imm1,arg_z,0))
    6247         __(cmpri(cr1,imm1,0))
    6248         __(mov imm0,#0)
    6249         __(bge cr2,2f)
    6250         __(blt- cr1,9b)
    6251         __(bx lr)
    6252 2:
    6253         __(cmpri(cr0,imm2,three_digit_bignum_header))
    6254         __(vrefr(imm0,arg_z,1))
    6255         __(cmpri(cr1,imm0,0))
    6256         __(bne cr2,3f)
    6257         __(blt- cr1,9b)
    6258         __(bx lr)
    6259 3:
    6260         __(vrefr(imm2,arg_z,2))
    6261         __(cmpri(cr1,imm2,0))
    6262         __(bne- cr0,9b)
    6263         __(bne- cr1,9b)
    6264         __(bx lr)
    6265         __endif
    6266        
    6267 /* arg_z should be of type (SIGNED-BYTE 64);  */
    6268 /* PPC32:   return high 32 bits  in imm0, low 32 bits in imm1  */
    6269 /* PPC64:   return unboxed value in imm0  */
    6270 
    6271 _spentry(gets64)
    6272         __ifdef(`PPC64')
    6273          __(extract_typecode(imm1,arg_z))
    6274          __(unbox_fixnum(imm0,arg_z))
    6275          __(cmpri(cr0,imm1,tag_fixnum))
    6276          __(cmpri(cr2,imm1,subtag_bignum))
    6277          __(beqlr cr0)
    6278          __(bne cr2,9f)
    6279          __(ld imm1,misc_header_offset(arg_z))
    6280          __(ld imm0,misc_data_offset(arg_z))
    6281          __(cmpdi imm1,two_digit_bignum_header)
    6282          __(rotldi imm0,imm0,32)
    6283          __(beqlr)
    6284         __else
    6285          __(extract_typecode(imm0,arg_z))
    6286          __(cmpri(cr0,imm0,tag_fixnum))
    6287          __(cmpri(cr2,imm0,subtag_bignum))
    6288          __(unbox_fixnum(imm1,arg_z))
    6289          __(srawi imm0,imm1,31)
    6290          __(beqlr cr0)
    6291          __(bne cr2,9f)
    6292          __(getvheader(imm2,arg_z))
    6293          __(cmpri(cr2,imm2,two_digit_bignum_header))
    6294          __(vrefr(imm1,arg_z,0))
    6295          __(srawi imm0,imm1,31)
    6296          __(bltlr cr2)
    6297          __(vrefr(imm0,arg_z,1))
    6298          __(beqlr cr2)
    6299         __endif
    6300 9:
    6301         __(uuo_interr(error_object_not_s64,arg_z))
    6302 
    6303 
    6304 /*  Construct a lisp integer out of the 64-bit unsigned value in */
    6305 /*        ppc32:    imm0 (high 32 bits) and imm1 (low 32 bits) */
    6306 /*        ppc64:    imm0 (64 bits) .  */
    6307 _spentry(makeu64)
    6308         __ifdef(`PPC64')
    6309          __(clrrdi. imm1,imm0,63-nfixnumtagbits)
    6310          __(cmpri(cr1,imm0,0))
    6311          __(box_fixnum(arg_z,imm0))
    6312          __(beqlr cr0) /* A fixnum  */
    6313          __(rotldi imm1,imm0,32)
    6314          __(mov imm2,#two_digit_bignum_header)
    6315          __(blt cr1,2f)
    6316          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
    6317          __(str(imm1,misc_data_offset(arg_z)))
    6318          __(bx lr)
    6319 2:
    6320          __(mov imm2,#three_digit_bignum_header)
    6321          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
    6322          __(str(imm1,misc_data_offset(arg_z)))
    6323          __(bx lr)
    6324         __else       
    6325          __(cmpri(cr1,imm0,0))
    6326          __(rlwinm. imm2,imm1,0,0,fixnum_shift)
    6327          __(mov imm2,#three_digit_bignum_header)
    6328          __(box_fixnum(arg_z,imm1))
    6329          __(blt cr1,3f)
    6330          __(bne cr1,2f)
    6331          __(beqlr cr0) /* A fixnum  */
    6332          __(blt cr0,2f)
    6333          __(mov imm2,#one_digit_bignum_header)
    6334          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
    6335          __(str(imm1,misc_data_offset(arg_z)))
    6336          __(bx lr)
    6337 2:
    6338          __(mov imm2,#two_digit_bignum_header)
    6339          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
    6340          __(str(imm1,misc_data_offset(arg_z)))
    6341          __(str(imm0,misc_data_offset+4(arg_z)))
    6342          __(bx lr)
    6343 3:
    6344          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
    6345          __(str(imm1,misc_data_offset(arg_z)))
    6346          __(str(imm0,misc_data_offset+4(arg_z)))
    6347          __(bx lr)
    6348         __endif
    6349 
    6350 
    6351 
    6352 /*  Construct a lisp integer out of the 64-bit signed value in */
    6353 /*        ppc32:    imm0 (high 32 bits) and imm1 (low 32 bits). */
    6354 /*        ppc64:    imm0  */
    6355 _spentry(makes64)
    6356         __ifdef(`PPC64')
    6357          __(addo imm1,imm0,imm0)
    6358          __(addo imm1,imm1,imm1)
    6359          __(addo. arg_z,imm1,imm1)
    6360          __(bnslr+)
    6361          __(mtxer rzero)
    6362          __(mov imm1,#two_digit_bignum_header)
    6363          __(rotldi imm0,imm0,32)
    6364          __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
    6365          __(str(imm0,misc_data_offset(arg_z)))
    6366          __(bx lr)
    6367         __else
    6368          __(srawi imm2,imm1,31)
    6369          __(cmpr(cr1,imm2,imm0))
    6370          __(addo imm2,imm1,imm1)
    6371          __(addo. arg_z,imm2,imm2)
    6372          __(bne cr1,2f) /* High word is significant  */
    6373          __(mov imm2,#one_digit_bignum_header)
    6374          __(bnslr cr0) /* No overflow:   fixnum  */
    6375          __(mtxer rzero)
    6376          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
    6377          __(str(imm1,misc_data_offset(arg_z)))
    6378          __(bx lr)
    6379 2:
    6380          __(mtxer rzero)
    6381          __(mov imm2,#two_digit_bignum_header)
    6382          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
    6383          __(str(imm1,misc_data_offset(arg_z)))
    6384          __(str(imm0,misc_data_offset+4(arg_z)))
    6385          __(bx lr)
    6386         __endif
    6387 
    6388 /* imm0:imm1 constitute an unsigned integer, almost certainly a bignum. */
    6389 /* Make a lisp integer out of those 128 bits ..  */
    6390 _spentry(makeu128)
    6391         __ifdef(`PPC64')
    6392          __(cmpdi imm0,0)
    6393          __(cmpdi cr1,imm1,0)
    6394          __(srdi imm3,imm0,32)
    6395          __(srawi imm4,imm0,31)
    6396          __(cmpdi cr3,imm3,0)
    6397          __(cmpdi cr4,imm4,0)
    6398          __(mov imm2,#five_digit_bignum_header)
    6399          __(blt cr1,0f)
    6400          __(beq 3f)
    6401 0:             
    6402          __(bge 1f)
    6403          /* All 128 bits are significant, and the most significant */
    6404          /* bit is set.  Allocate a 5-digit bignum (with a zero */
    6405          /* sign digit  */
    6406          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(5)))
    6407          __(rotldi imm0,imm0,32)
    6408          __(rotldi imm1,imm1,32)
    6409          __(std imm1,misc_data_offset(arg_z))
    6410          __(std imm0,misc_data_offset+8(arg_z))
    6411          __(bx lr)
    6412 1:       /* If the high word of imm0 is a zero-extension of the low */
    6413          /* word, we only need 3 digits ; otherwise, we need 4.  */
    6414          __(mov imm2,#three_digit_bignum_header)
    6415          __(rotldi imm1,imm1,32)
    6416          __(bne cr3,2f) /* high word of imm0 is non-zero  */
    6417          __(bne cr4,2f) /* sign bit is on in low word of imm0  */
    6418          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
    6419          __(std imm1,misc_data_offset(arg_z))
    6420          __(stw imm0,misc_data_offset+8(arg_z))
    6421          __(bx lr)
    6422 2:       __(mov imm2,#four_digit_bignum_header)
    6423          __(rotldi imm0,imm0,32)
    6424          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
    6425          __(std imm1,misc_data_offset(arg_z))
    6426          __(std imm0,misc_data_offset+8(arg_z))
    6427          __(bx lr)
    6428 3:       __(mov imm0,imm1)
    6429          __(b _SPmakeu64)             
    6430         __else
    6431          __(twgei r0,r0)
    6432         __endif
    6433 
    6434 /* imm0:imm1 constitute a signed integer, almost certainly a bignum. */
    6435 /* Make a lisp integer out of those 128 bits ..  */
    6436 _spentry(makes128)
    6437         __ifdef(`PPC64')
    6438          /* Is imm0 just a sign-extension of imm1 ?  */
    6439          __(sradi imm2,imm1,63)
    6440          /* Is the high word of imm0 just a sign-extension of the low word ?  */
    6441          __(extsw imm3,imm0)
    6442          __(cmpd imm2,imm0)
    6443          __(cmpd cr1,imm3,imm0)
    6444          __(beq 2f)
    6445          __(rotldi imm0,imm0,32)
    6446          __(rotldi imm1,imm1,32)
    6447          __(beq cr1,1f)
    6448          __(mov imm2,#four_digit_bignum_header)
    6449          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
    6450          __(std imm1,misc_data_offset(arg_z))
    6451          __(std imm0,misc_data_offset+8(arg_z))
    6452          __(bx lr)
    6453 1:       __(mov imm2,#three_digit_bignum_header)
    6454          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
    6455          __(std imm1,misc_data_offset(arg_z))
    6456          __(stw imm3,misc_data_offset+8(arg_z))
    6457          __(bx lr)
    6458 2:       __(mov imm0,imm1)
    6459          __(b _SPmakes64)       
    6460         __else
    6461          __(twgei r0,r0)
    6462         __endif       
    6463                        
    6464 /* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
    6465 /* unbound_marker), arg_y = symbol, imm3 = symbol.binding-index  */
    6466 _spentry(specref)
    6467         __(ldr(imm3,symbol.binding_index(arg_z)))
    6468         __(ldr(imm0,tcr.tlb_limit(rcontext)))
    6469         __(cmpr(imm3,imm0))
    6470         __(ldr(imm2,tcr.tlb_pointer(rcontext)))
    6471         __(mov arg_y,arg_z)
    6472         __(bge 1f)
    6473         __(ldrx(arg_z,imm2,imm3))
    6474         __(cmpri(arg_z,no_thread_local_binding_marker))
    6475         __(bnelr)
    6476 1:      __(ldr(arg_z,symbol.vcell(arg_y)))
    6477         __(bx lr)
    6478 
    6479 
    6480 _spentry(specrefcheck)
    6481         __(ldr(imm3,symbol.binding_index(arg_z)))
    6482         __(ldr(imm0,tcr.tlb_limit(rcontext)))
    6483         __(cmpr(imm3,imm0))
    6484         __(ldr(imm2,tcr.tlb_pointer(rcontext)))
    6485         __(mov arg_y,arg_z)
    6486         __(bge 1f)
    6487         __(ldrx(arg_z,imm2,imm3))
    6488         __(cmpri(arg_z,no_thread_local_binding_marker))
    6489         __(bne 2f)
    6490 1:      __(ldr(arg_z,symbol.vcell(arg_y)))
    6491 2:      __(treqi(arg_z,unbound_marker))
    6492         __(bx lr)
    6493        
    6494 /* arg_y = special symbol, arg_z = new value.          */
    6495 _spentry(specset)
    6496         __(ldr(imm3,symbol.binding_index(arg_y)))
    6497         __(ldr(imm0,tcr.tlb_limit(rcontext)))
    6498         __(ldr(imm2,tcr.tlb_pointer(rcontext)))
    6499         __(cmpr(imm3,imm0))
    6500         __(bge 1f)
    6501         __(ldrx(temp1,imm2,imm3))
    6502         __(cmpri(temp1,no_thread_local_binding_marker))
    6503         __(beq 1f)
    6504         __(strx(arg_z,imm2,imm3))
    6505         __(bx lr)
    6506 1:      __(mov arg_x,arg_y)
    6507         __(mov arg_y,#symbol.vcell-misc_data_offset)
    6508         __(b _SPgvset)
    6509 
    6510 /* Restore current thread's interrupt level to arg_z, */
    6511 /* noting whether the tcr's interrupt_pending flag was set.  */
    6512 _spentry(restoreintlevel)
    6513         __(cmpri(cr1,arg_z,0))
    6514         __(ldr(imm0,tcr.interrupt_pending(rcontext)))
    6515         __(cmpri(cr0,imm0,0))
    6516         __(bne cr1,1f)
    6517         __(beq cr0,1f)
    6518         __(str(rzero,tcr.interrupt_pending(rcontext)))
    6519         __(mov nargs,#fixnum_one)
    6520         __(trgti(nargs,0))
    6521         __(bx lr)
    6522 1:
    6523         __(ldr(nargs,tcr.tlb_pointer(rcontext)))
    6524         __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(nargs)))
    6525         __(bx lr)
    6526 
    6527 
    6528 /* Construct a lisp integer out of the 32-bit signed value in imm0 */
    6529 
    6530        
    6531 _spentry(makes32)
    6532         __ifdef(`PPC64')
    6533          __(box_fixnum(arg_z,imm0))
    6534         __else
    6535          __(addo imm1,imm0,imm0)
    6536          __(addo. arg_z,imm1,imm1)
    6537          __(bnslr+)
    6538          __(mtxer rzero)
    6539          __(mov imm1,#one_digit_bignum_header)
    6540          __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
    6541          __(str(imm0,misc_data_offset(arg_z)))
    6542         __endif
    6543          __(bx lr)
    6544 
    6545 
    6546 /* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
    6547 
    6548        
    6549 _spentry(makeu32)
    6550         __ifdef(`PPC64')
    6551          __(box_fixnum(arg_z,imm0))
    6552          __(bx lr)
    6553         __else
    6554          __(clrrwi. imm1,imm0,31-nfixnumtagbits)
    6555          __(cmpri(cr1,imm0,0))
    6556          __(box_fixnum(arg_z,imm0))
    6557          __(beqlr cr0) /* A fixnum  */
    6558          __(blt cr1,2f)
    6559          __(mov imm2,#one_digit_bignum_header)
    6560          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
    6561          __(str(imm0,misc_data_offset(arg_z)))
    6562          __(bx lr)
    6563 2:
    6564          __(mov imm2,#two_digit_bignum_header)
    6565          __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
    6566          __(str(imm0,misc_data_offset(arg_z)))
    6567          __(bx lr)
    6568         __endif
    6569 
    6570 /*  */
    6571 /* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
    6572 /*  */
    6573 _spentry(gets32)
    6574         __ifdef(`PPC64')
    6575          __(sldi imm1,arg_z,32-fixnumshift)
    6576          __(extract_lisptag_(imm0,arg_z))
    6577          __(sradi imm1,imm1,32-fixnumshift)
    6578          __(box_fixnum(imm0,arg_z))
    6579          __(cmpd cr1,imm1,arg_z)
    6580          __(bne cr0,9f)
    6581          __(beqlr cr1)
    6582          __(b 9f)
    6583         __else
    6584          __(extract_typecode(imm1,arg_z))
    6585          __(cmpri(cr0,imm1,tag_fixnum))
    6586          __(cmpri(cr2,imm1,subtag_bignum))
    6587          __(unbox_fixnum(imm0,arg_z))
    6588          __(beqlr+ cr0)
    6589          __(bne cr2,9f)
    6590          __(getvheader(imm1,arg_z))
    6591          __(cmpri(cr1,imm1,one_digit_bignum_header))
    6592          __(vrefr(imm0,arg_z,0))
    6593          __(beqlr+ cr1)
    6594         __endif
    6595 9:
    6596         __(uuo_interr(error_object_not_signed_byte_32,arg_z))
    6597 
    6598 /*  */
    6599 /* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
    6600 /*  */
    6601 
    6602 _spentry(getu32)
    6603         __(extract_typecode(imm1,arg_z))
    6604         __(cmpri(cr0,imm1,tag_fixnum))
    6605         __(cmpri(cr1,arg_z,0))
    6606         __(cmpri(cr2,imm1,subtag_bignum))
    6607         __(unbox_fixnum(imm0,arg_z))
    6608         __(bne cr0,8f)
    6609         __(bgelr cr1)
    6610 8:
    6611         __(bne- cr2,9f)
    6612         __(getvheader(imm2,arg_z))
    6613         __(cmpri(cr2,imm2,two_digit_bignum_header))
    6614         __(vrefr(imm0,arg_z,0))
    6615         __(cmpri(cr0,imm0,0))
    6616         __(bgt cr2,9f)
    6617         __(beq cr2,2f)
    6618         __(blt cr0,9f)
    6619         __(bx lr)
    6620 2:
    6621         __(vrefr(imm1,arg_z,1))
    6622         __(cmpri(cr0,imm1,0))
    6623         __(beqlr+ cr0)
    6624 
    6625 9:
    6626         __(uuo_interr(error_object_not_unsigned_byte_32,arg_z))
    6627 
    6628 /* */
    6629 /* arg_z has overflowed (by one bit) as the result of an addition or subtraction. */
    6630 /* Make a bignum out of it. */
    6631 
    6632 _spentry(fix_overflow)
    6633         __(mtxer rzero)
    6634         __(unbox_fixnum(imm1,arg_z))
    6635         __ifdef(`PPC64')
    6636          __(mov imm0,#two_digit_bignum_header)
    6637          __(rotldi imm1,imm1,32)
    6638          __(xoris imm1,imm1,0xe000)
    6639          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
    6640          __(str(imm1,misc_data_offset(arg_z)))
    6641         __else
    6642          __(mov imm0,#one_digit_bignum_header)
    6643          __(xoris imm1,imm1,0xc000)
    6644          __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
    6645          __(str(imm1,misc_data_offset(arg_z)))
    6646         __endif
    6647         __(bx lr)
    6648                
    6649 
    6650 
    6651 /* */
    6652 /* As per mvpass above, but in this case fname is known to be a */
    6653 /* symbol. */
    6654 
    6655 _spentry(mvpasssym)
    6656         __(cmpri(cr0,nargs,node_size*nargregs))
    6657         __(mflr loc_pc)
    6658         __(mov imm0,vsp)
    6659         __(ble+ cr0,1f)
    6660          __(subi imm0,imm0,node_size*nargregs)
    6661          __(add imm0,imm0,nargs)
    6662 1:           
    6663         __(build_lisp_frame(fn,loc_pc,imm0))
    6664         __(ref_global(loc_pc,ret1val_addr))
    6665         __(mov fn,#0)
    6666         __(mtlr loc_pc)
    6667         __(jump_fname())
    6668 
    6669 
    6670 
    6671 _spentry(unbind)
    6672         __(ldr(imm1,tcr.db_link(rcontext)))
    6673         __(ldr(imm2,tcr.tlb_pointer(rcontext)))   
    6674         __(ldr(imm3,binding.sym(imm1)))
    6675         __(ldr(temp1,binding.val(imm1)))
    6676         __(ldr(imm1,binding.link(imm1)))
    6677         __(strx(temp1,imm2,imm3))
    6678         __(str(imm1,tcr.db_link(rcontext)))
    6679         __(bx lr)
    6680 
    6681 _spentry(unbind_n)
    6682         __(ldr(imm1,tcr.db_link(rcontext)))
    6683         __(ldr(imm2,tcr.tlb_pointer(rcontext)))   
    6684 1:      __(subi imm0,imm0,1)
    6685         __(ldr(imm3,binding.sym(imm1)))
    6686         __(ldr(temp1,binding.val(imm1)))
    6687         __(cmpri(imm0,0))
    6688         __(ldr(imm1,binding.link(imm1)))
    6689         __(strx(temp1,imm2,imm3))
    6690         __(bne 1b)
    6691         __(str(imm1,tcr.db_link(rcontext)))
    6692         __(bx lr)
    6693 
    6694 /* */
    6695 /* Clobbers imm1,imm2,imm5,arg_x, arg_y */
    6696 
    6697 _spentry(unbind_to)
    6698         __(ldr(imm1,tcr.db_link(rcontext)))
    6699         __(ldr(imm2,tcr.tlb_pointer(rcontext)))
    6700 1:      __(ldr(imm5,binding.sym(imm1)))
    6701         __(ldr(arg_y,binding.val(imm1)))
    6702         __(ldr(imm1,binding.link(imm1)))
    6703         __(cmpr(imm0,imm1))
    6704         __(strx(arg_y,imm2,imm5))
    6705         __(bne 1b)
    6706         __(str(imm1,tcr.db_link(rcontext)))
    6707         __(bx lr)
    6708        
    6709 
    6710 
    6711 /* */
    6712 /* Restore the special bindings from the top of the tstack,  */
    6713 /* leaving the tstack frame allocated.  */
    6714 /* Note that there might be 0 saved bindings, in which case  */
    6715 /* do nothing.  */
    6716 /* Note also that this is -only- called from an unwind-protect  */
    6717 /* cleanup form, and that .SPnthrowXXX is keeping one or more  */
    6718 /* values in a frame on top of the tstack.  */
    6719 /*  */
    6720                        
    6721 _spentry(progvrestore)
    6722         __(ldr(imm0,tsp_frame.backlink(tsp)))   /* ignore .SPnthrowXXX values frame  */
    6723         __(ldr(imm0,tsp_frame.data_offset(imm0)))
    6724         __(cmpri(cr0,imm0,0))
    6725         __(unbox_fixnum(imm0,imm0))
    6726         __(bne+ cr0,_SPunbind_n)
    6727         __(bx lr)
    6728 
    6729 /* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
    6730 /* for pending interrupts after doing so.  "nargs" can be freely used for an */
    6731 /* interrupt trap in this context.  */
    6732 _spentry(bind_interrupt_level_0)
    6733         __(ldr(imm4,tcr.tlb_pointer(rcontext)))
    6734         __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6735         __(ldr(imm1,tcr.db_link(rcontext)))
    6736         __(cmpri(temp0,0))
    6737         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
    6738         __(vpush1(temp0))
    6739         __(vpush1(imm3))
    6740         __(vpush1(imm1))
    6741         __(str(rzero,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6742         __(str(vsp,tcr.db_link(rcontext)))
    6743         __(beqlr)
    6744         __(mov nargs,temp0)
    6745         __(bgt 1f)
    6746         __(ldr(nargs,tcr.interrupt_pending(rcontext)))
    6747 1:      __(trgti(nargs,0))       
    6748         __(bx lr)
    6749 
    6750 /* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
    6751 /* of disabling interrupts.)  */
    6752 _spentry(bind_interrupt_level_m1)
    6753         __(mov imm2,#-fixnumone)
    6754         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
    6755         __(ldr(imm4,tcr.tlb_pointer(rcontext)))
    6756         __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6757         __(ldr(imm1,tcr.db_link(rcontext)))
    6758         __(vpush1(temp0))
    6759         __(vpush1(imm3))
    6760         __(vpush1(imm1))
    6761         __(str(imm2,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6762         __(str(vsp,tcr.db_link(rcontext)))
    6763         __(bx lr)
    6764 
    6765        
    6766 /* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
    6767 /* do what _SPbind_interrupt_level_0 does  */
    6768 _spentry(bind_interrupt_level)
    6769         __(cmpri(arg_z,0))
    6770         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
    6771         __(ldr(imm4,tcr.tlb_pointer(rcontext)))
    6772         __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6773         __(ldr(imm1,tcr.db_link(rcontext)))
    6774         __(beq _SPbind_interrupt_level_0)
    6775         __(vpush1(temp0))
    6776         __(vpush1(imm3))
    6777         __(vpush1(imm1))
    6778         __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6779         __(str(vsp,tcr.db_link(rcontext)))
    6780         __(bx lr)
    6781 
    6782 /* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
    6783 /* non-negative, check for pending interrupts.  This is often called in */
    6784 /* a context where nargs is significant, so save and restore nargs around */
    6785 /* any interrupt polling  */
    6786        
    6787 _spentry(unbind_interrupt_level)
    6788         __(ldr(imm0,tcr.flags(rcontext)))
    6789         __(ldr(imm2,tcr.tlb_pointer(rcontext)))
    6790         __(andi. imm0,imm0,1<<TCR_FLAG_BIT_PENDING_SUSPEND)
    6791         __(ldr(imm1,tcr.db_link(rcontext)))
    6792         __(ldr(temp1,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
    6793         __(bne 5f)
    6794 0:      __(cmpri(cr1,temp1,0))
    6795         __(ldr(temp1,binding.val(imm1)))
    6796         __(ldr(imm1,binding.link(imm1)))
    6797         __(cmpri(cr0,temp1,0))
    6798         __(str(temp1,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
    6799         __(str(imm1,tcr.db_link(rcontext)))
    6800         __(bgelr cr1)
    6801         __(bltlr cr0)
    6802         __(mov imm2,nargs)
    6803         __(check_pending_interrupt(`cr1'))
    6804         __(mov nargs,imm2)
    6805         __(bx lr)
    6806 5:       /* Missed a suspend request; force suspend now if we're restoring
    6807           interrupt level to -1 or greater */
    6808         __(cmpri(temp1,-2<<fixnumshift))
    6809         __(bne 0b)
    6810         __(ldr(imm0,binding.val(imm1)))
    6811         __(cmpr(imm0,temp1))
    6812         __(beq 0b)
    6813         __(mov imm0,#1<<fixnumshift)
    6814         __(str(imm0,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
    6815         __(suspend_now())
    6816         __(b 0b)
    6817 
    6818 
    6819 /* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
    6820    We don't know whether the array is alleged to be simple or
    6821    not, and don't know anythng about the element type.  */
    6822 _spentry(aref2)
    6823         __(extract_typecode(imm2,arg_x))
    6824         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    6825         __(cmpri(cr2,imm2,subtag_arrayH))
    6826         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
    6827         __(bne cr2,1f)
    6828         __(ldr(imm1,arrayH.rank(arg_x)))
    6829         __(cmpri(imm1,2<<fixnumshift))
    6830         __(bne 1f)
    6831         /* It's a 2-dimensional array.  Check bounds */
    6832         __(ldr(imm0,arrayH.dim0(arg_x)))
    6833         __(trlge(arg_y,imm0))
    6834         __(ldr(imm0,arrayH.dim0+node_size(arg_x)))
    6835         __(trlge(arg_z,imm0))
    6836         __(unbox_fixnum(imm0,imm0))
    6837         __(mullr(arg_y,arg_y,imm0))
    6838         __(add arg_z,arg_z,arg_y)
    6839         /* arg_z is now row-major-index; get data vector and
    6840            add in possible offset */
    6841         __(mov arg_y,arg_x)
    6842 0:      __(ldr(imm0,arrayH.displacement(arg_y)))
    6843         __(ldr(arg_y,arrayH.data_vector(arg_y)))
    6844         __(extract_subtag(imm1,arg_y))
    6845         __(cmpri(imm1,subtag_vectorH))
    6846         __(add arg_z,arg_z,imm0)
    6847         __(bgt local_label(misc_ref_common))
    6848         __(b 0b)
    6849 1:             
    6850         __(uuo_interr(error_object_not_array_2d,arg_x))
    6851 
    6852 /* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
    6853 _spentry(aref3)
    6854         __(extract_typecode(imm2,temp0))
    6855         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
    6856         __(cmpri(cr2,imm2,subtag_arrayH))
    6857         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    6858         __(bne cr2,1f)
    6859         __(ldr(imm1,arrayH.rank(temp0)))
    6860         __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
    6861         __(cmpri(imm1,3<<fixnumshift))
    6862         __(bne 1f)
    6863         /* It's a 3-dimensional array.  Check bounds */
    6864         __(ldr(imm2,arrayH.dim0+(node_size*2)(temp0)))
    6865         __(ldr(imm1,arrayH.dim0+node_size(temp0)))
    6866         __(ldr(imm0,arrayH.dim0(temp0)))
    6867         __(trlge(arg_z,imm2))
    6868         __(unbox_fixnum(imm2,imm2))
    6869         __(trlge(arg_y,imm1))
    6870         __(unbox_fixnum(imm1,imm1))
    6871         __(trlge(arg_x,imm0))
    6872         __(mullr(arg_y,arg_y,imm2))
    6873         __(mullr(imm1,imm2,imm1))
    6874         __(mullr(arg_x,imm1,arg_x))
    6875         __(add arg_z,arg_z,arg_y)
    6876         __(add arg_z,arg_z,arg_x)
    6877         __(mov arg_y,temp0)
    6878 0:      __(ldr(arg_x,arrayH.displacement(arg_y)))
    6879         __(ldr(arg_y,arrayH.data_vector(arg_y)))
    6880         __(extract_subtag(imm1,arg_y))
    6881         __(cmpri(imm1,subtag_vectorH))
    6882         __(add arg_z,arg_x,arg_z)
    6883         __(bgt local_label(misc_ref_common))
    6884         __(b 0b)
    6885 1:             
    6886         __(uuo_interr(error_object_not_array_3d,temp0))
    6887 
    6888        
    6889        
    6890 
    6891 /* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
    6892 _spentry(aset2)
    6893         __(extract_typecode(imm2,temp0))
    6894         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
    6895         __(cmpri(cr2,imm2,subtag_arrayH))
    6896         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    6897         __(bne cr2,1f)
    6898         __(ldr(imm1,arrayH.rank(temp0)))
    6899         __(cmpri(imm1,2<<fixnumshift))
    6900         __(bne 1f)
    6901         /* It's a 2-dimensional array.  Check bounds */
    6902         __(ldr(imm0,arrayH.dim0(temp0)))
    6903         __(trlge(arg_x,imm0))
    6904         __(ldr(imm0,arrayH.dim0+node_size(temp0)))
    6905         __(trlge(arg_y,imm0))
    6906         __(unbox_fixnum(imm0,imm0))
    6907         __(mullr(arg_x,arg_x,imm0))
    6908         __(add arg_y,arg_y,arg_x)
    6909         /* arg_y is now row-major-index; get data vector and
    6910            add in possible offset */
    6911         __(mov arg_x,temp0)
    6912 0:      __(ldr(imm0,arrayH.displacement(arg_x)))
    6913         __(ldr(arg_x,arrayH.data_vector(arg_x)))
    6914         __(extract_subtag(imm1,arg_x))
    6915         __(cmpri(imm1,subtag_vectorH))
    6916         __(add arg_y,arg_y,imm0)
    6917         __(bgt local_label(misc_set_common))
    6918         __(b 0b)
    6919 1:             
    6920         __(uuo_interr(error_object_not_array_2d,temp0))       
    6921                
    6922 /* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
    6923 _spentry(aset3)
    6924         __(extract_typecode(imm2,temp1))
    6925         __(trap_unless_lisptag_equal(temp0,tag_fixnum,imm0))
    6926         __(cmpri(cr2,imm2,subtag_arrayH))
    6927         __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
    6928         __(bne cr2,1f)
    6929         __(ldr(imm1,arrayH.rank(temp1)))
    6930         __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
    6931         __(cmpri(imm1,3<<fixnumshift))
    6932         __(bne 1f)
    6933         /* It's a 3-dimensional array.  Check bounds */
    6934         __(ldr(imm2,arrayH.dim0+(node_size*2)(temp1)))
    6935         __(ldr(imm1,arrayH.dim0+node_size(temp1)))
    6936         __(ldr(imm0,arrayH.dim0(temp1)))
    6937         __(trlge(arg_y,imm2))
    6938         __(unbox_fixnum(imm2,imm2))
    6939         __(trlge(arg_x,imm1))
    6940         __(unbox_fixnum(imm1,imm1))
    6941         __(trlge(temp0,imm0))
    6942         __(mullr(arg_x,arg_x,imm2))
    6943         __(mullr(imm1,imm2,imm1))
    6944         __(mullr(temp0,imm1,temp0))
    6945         __(add arg_y,arg_y,arg_x)
    6946         __(add arg_y,arg_y,temp0)
    6947         __(mov arg_x,temp1)
    6948 0:      __(ldr(temp0,arrayH.displacement(arg_x)))
    6949         __(ldr(arg_x,arrayH.data_vector(arg_x)))
    6950         __(extract_subtag(imm1,arg_x))
    6951         __(cmpri(imm1,subtag_vectorH))
    6952         __(add arg_y,arg_y,temp0)
    6953         __(bgt local_label(misc_set_common))
    6954         __(b 0b)
    6955 1:             
    6956         __(uuo_interr(error_object_not_array_3d,temp1))
    6957 
    6958 
    6959        
    6960 
    6961 _spentry(nmkunwind)
    6962         __(mov imm2,#-fixnumone)
    6963         __(mov imm3,#INTERRUPT_LEVEL_BINDING_INDEX)
    6964         __(ldr(imm4,tcr.tlb_pointer(rcontext)))
    6965         __(ldr(arg_y,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6966         __(ldr(imm1,tcr.db_link(rcontext)))
    6967         __(vpush1(arg_y))
    6968         __(vpush1(imm3))
    6969         __(vpush1(imm1))
    6970         __(str(imm2,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
    6971         __(str(vsp,tcr.db_link(rcontext)))
    6972         __(lwi(arg_z,unbound_marker))
    6973         __(mov imm2,#fixnum_one)
    6974         __(mkcatch())
    6975         __(mov arg_z,arg_y)
    6976         __(b _SPbind_interrupt_level)
    6977 
    6978         .if 1
    6979         __ifdef(`DARWIN')
    6980          __ifdef(`PPC64')
    6981 L_lisp_objc2_personality:       
    6982         __(ref_global(r12,objc_2_personality))
    6983         __(mtctr r12)
    6984         __(bctr)
    6985         .data
    6986         .globl _lisp_objc2_personality
    6987 _lisp_objc2_personality:
    6988         .quad L_lisp_objc2_personality
    6989        
    6990         .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
    6991 EH_frame1:
    6992         .set L$set$12,LECIE1-LSCIE1
    6993         .long L$set$12  /* Length of Common Information Entry */
    6994 LSCIE1:
    6995         .long   0x0     /* CIE Identifier Tag */
    6996         .byte   0x1     /* CIE Version */
    6997         .ascii "zPLR\0" /* CIE Augmentation */
    6998         .byte   0x1     /* uleb128 0x1; CIE Code Alignment Factor */
    6999         .byte   0x78    /* sleb128 -8; CIE Data Alignment Factor */
    7000         .byte   0x41    /* CIE RA Column */
    7001         .byte   0x7
    7002         .byte   0x9b
    7003         .long   _lisp_objc2_personality-.
    7004         .byte   0x10    /* LSDA Encoding (pcrel) */
    7005         .byte   0x10    /* FDE Encoding (pcrel) */
    7006         .byte   0xc
    7007         .byte   0x1
    7008         .byte   0x0
    7009         .align 3
    7010 LECIE1:
    7011         .globl _SPffcall.eh
    7012 _SPffcall.eh:
    7013         .set assembler_nonsense,LEFDEffcall-LSFDEffcall
    7014         .long assembler_nonsense
    7015 LSFDEffcall:     
    7016         .long LSFDEffcall-EH_frame1 /* FDE CIE offset */
    7017         .quad Lffcall-. /* FDE Initial Location */
    7018         .quad Lffcall_end-Lffcall /* FDE address range */
    7019         .byte 8 /* uleb128 0x8; Augmentation size */
    7020         .quad LLSDA1-.           /* Language Specific Data Area */
    7021         .byte DW_CFA_def_cfa_offset
    7022         .byte 0xc0,0x1 /* uleb128 0xc0.  A lie:  the frame is variable-length */
    7023         .byte DW_CFA_offset_extended_sf
    7024         .byte   0x41   
    7025         .byte   0x7e    /* sleb128 -2 */
    7026         .byte DW_CFA_advance_loc4
    7027         .long Lffcall_setup-Lffcall
    7028         .byte DW_CFA_advance_loc4
    7029         .long Lffcall_setup_end-Lffcall_setup
    7030         .byte DW_CFA_advance_loc4
    7031         .long Lffcall_call_end-Lffcall_call
    7032         .align 3
    7033 LEFDEffcall:
    7034        
    7035         .globl _SPffcall_return_registers.eh
    7036 _SPffcall_return_registers.eh:
    7037         .set Lfmh,LEFDEffcall_return_registers-LSFDEffcall_return_registers
    7038         .long Lfmh
    7039 LSFDEffcall_return_registers:     
    7040         .long LSFDEffcall_return_registers-EH_frame1 /* FDE CIE offset */
    7041         .quad Lffcall_return_registers-. /* FDE Initial Location */
    7042         .quad Lffcall_return_registers_end-Lffcall_return_registers /* FDE address range */
    7043         .byte 8 /* uleb128 0x8; Augmentation size */
    7044         .quad LLSDA2-.           /* Language Specific Data Area */
    7045         .byte DW_CFA_def_cfa_offset
    7046         .byte 0xc0,0x1 /* uleb128 0xc0.  A lie:  the frame is variable-length */
    7047         .byte DW_CFA_offset_extended_sf
    7048         .byte 0x41     
    7049         .byte 0x7e      /* sleb128 -2 */
    7050         .byte DW_CFA_advance_loc4
    7051         .long Lffcall_return_registers_setup-Lffcall_return_registers
    7052         .byte DW_CFA_advance_loc4
    7053         .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup
    7054         .byte DW_CFA_advance_loc4
    7055         .long Lffcall_return_registers_call_end-Lffcall_return_registers_call
    7056         .align 3
    7057 LEFDEffcall_return_registers:
    7058         .text
    7059          __endif
    7060         __endif
    7061         .endif
    7062 
    7063                                
    7064 /*  EOF, basically  */
    7065         .globl _SPsp_end
    7066         b _SPsp_end
    7067         _endfile
     6377         
     6378        _endfile
     6379 
Note: See TracChangeset for help on using the changeset viewer.