source: trunk/source/lisp-kernel/ppc-spentry.s @ 10623

Last change on this file since 10623 was 10623, checked in by gb, 12 years ago

Use a different set of conventions (the label
egc_store_node_conditional_test and the state of cr0[eq]) to determine
whether or not a store_node_conditional has completed.

If pc_luser_xp interrupts/completes set_hash_key, ensure that it
stores arg_z. (Was storing 0, which, if it ever happened, was
obviously the wrong thing to do.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 245.0 KB
Line 
1/* Copyright (C) 1994-2001 Digitool, Inc */
2/* This file is part of OpenMCL.   */
3
4/* OpenMCL is licensed under the terms of the Lisp Lesser GNU Public */
5/* License , known as the LLGPL and distributed with OpenMCL as the */
6/* file "LICENSE".  The LLGPL consists of a preamble and the LGPL, */
7/* which is distributed with OpenMCL as the file "LGPL".  Where these */
8/* conflict, the preamble takes precedence.   */
9
10/* OpenMCL is referenced in the preamble as the "LIBRARY." */
11
12/* The LLGPL is also available online at */
13/* http://opensource.franz.com/preamble.html */
14
15
16       
17        include(lisp.s)
18        _beginfile
19        .align 2
20       
21local_label(start):     
22define([_spentry],[ifdef([__func_name],[_endfn],[])
23        _exportfn(_SP$1)
24        .line  __line__
25])
26
27             
28define([_endsubp],[
29        _endfn(_SP$1)
30# __line__
31])
32
33
34                       
35               
36define([jump_builtin],[
37        ref_nrs_value(fname,builtin_functions)
38        set_nargs($2)
39        vrefr(fname,fname,$1)
40        jump_fname()
41])
42       
43_spentry(jmpsym)
44        __(jump_fname())
45       
46_spentry(jmpnfn)
47        __(jump_nfn())
48       
49        /*  Call temp0 if it's either a symbol or function */
50_spentry(funcall)
51        __(do_funcall())
52       
53/* Subprims for catch, throw, unwind_protect.  */
54
55/* Push a catch frame on the temp stack (and some of it on the cstack, as well.)  */
56/* The PC in question is 4 bytes past the caller's return address. ALWAYS.  */
57/* The catch tag is in arg_z, the multiple-value flags is in imm2.  */
58/* Bash some of the imm registers and loc_pc.  */
59
60_spentry(mkcatch1v)
61        __(li imm2,0)
62        __(mkcatch())
63        __(blr)
64       
65_spentry(mkunwind)
66        __(lwi(arg_z,unbound_marker))
67        __(li imm2,fixnum_one)
68        __(mkcatch())
69        __(blr)
70       
71_spentry(mkcatchmv)
72        __(li imm2,fixnum_one)
73        __(mkcatch())
74        __(blr)
75       
76/* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
77/* Otherwise, process unwind-protects and throw to indicated catch frame.  */
78       
79_spentry(throw)
80        __(ldr(imm1,tcr.catch_top(rcontext)))
81        __(li imm0,0) /* count intervening catch/unwind-protect frames.  */
82        __(cmpri(cr0,imm1,0))
83        __(ldrx(temp0,vsp,nargs))
84        __(beq- cr0,local_label(_throw_tag_not_found))
85local_label(_throw_loop):
86        __(ldr(temp1,catch_frame.catch_tag(imm1)))
87        __(cmpr(cr0,temp0,temp1))
88        __(mr imm2,imm1)
89        __(ldr(imm1,catch_frame.link(imm1)))
90        __(cmpri(cr1,imm1,0))
91        __(beq cr0,local_label(_throw_found))
92        __(addi imm0,imm0,fixnum_one)
93        __(beq- cr1,local_label(_throw_tag_not_found))
94        __(b local_label(_throw_loop))
95/* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
96/* frames. If target isn't a multiple-value receiver, discard extra values */
97/* (less hair, maybe.)  */
98local_label(_throw_found):
99        __(ldr(imm1,catch_frame.mvflag(imm2)))
100        __(cmpri(cr0,imm1,0))
101        __(cmpri(cr1,nargs,0))
102        __(li fn,0)
103        __(add imm1,vsp,nargs)
104        __(la imm1,-node_size(imm1))
105        __(bne cr0,local_label(_throw_all_values))
106        __(set_nargs(1))
107        __(beq cr1,local_label(_throw_default_1_val))
108        __(mr vsp,imm1)
109        __(b local_label(_throw_all_values))
110local_label(_throw_default_1_val):
111        __(li imm4,nil_value)
112        __(vpush(imm4))
113local_label(_throw_all_values):
114        __(bl _SPnthrowvalues)
115        __(ldr(imm3,tcr.catch_top(rcontext)))
116        __(ldr(imm1,tcr.db_link(rcontext)))
117        __(ldr(imm0,catch_frame.db_link(imm3)))
118        __(ldr(imm4,catch_frame.mvflag(imm3)))
119        __(cmpr(cr0,imm0,imm1))
120        __(cmpri(cr1,imm4,0))
121        __(la tsp,-((tsp_frame.fixed_overhead+fulltag_misc))(imm3))
122        __(beq cr0,local_label(_throw_dont_unbind))
123        __(bl _SPunbind_to)
124local_label(_throw_dont_unbind):
125        __(add imm0,vsp,nargs)
126        __(cmpri(cr0,nargs,0))
127        __(ldr(imm1,catch_frame.csp(imm3)))
128        __(ldr(imm1,lisp_frame.savevsp(imm1)))
129        __(bne cr1,local_label(_throw_multiple))
130        /* Catcher expects single value in arg_z  */
131        __(ldr(arg_z,-node_size(imm0)))
132        __(b local_label(_throw_pushed_values))
133local_label(_throw_multiple):
134        __(beq cr0,local_label(_throw_pushed_values))
135        __(mr imm2,nargs)
136local_label(_throw_mvloop):
137        __(subi imm2,imm2,fixnum_one)
138        __(cmpri(imm2,0))
139        __(ldru(temp0,-node_size(imm0)))
140        __(push(temp0,imm1))
141        __(bgt local_label(_throw_mvloop))
142local_label(_throw_pushed_values):
143        __(mr vsp,imm1)
144        __(ldr(imm1,catch_frame.xframe(imm3)))
145        __(str(imm1,tcr.xframe(rcontext)))
146        __(ldr(sp,catch_frame.csp(imm3)))
147        __(ldr(fn,lisp_frame.savefn(sp)))
148        __(ldr(loc_pc,lisp_frame.savelr(sp)))
149        __(discard_lisp_frame())
150        __(mtlr loc_pc)
151        __(restore_catch_nvrs(imm3))
152        __(ldr(imm3,catch_frame.link(imm3)))
153        __(str(imm3,tcr.catch_top(rcontext)))
154        __(unlink(tsp))
155        __(blr)
156local_label(_throw_tag_not_found):
157        __(uuo_interr(error_throw_tag_missing,temp0))
158        __(strux(temp0,vsp,nargs))
159        __(b _SPthrow)
160
161
162/* This takes N multiple values atop the vstack.  */
163_spentry(nthrowvalues)
164        __(li imm1,1)
165        __(mr imm4,imm0)
166        __(str(imm1,tcr.unwinding(rcontext)))
167local_label(_nthrowv_nextframe):
168        __(subi imm4,imm4,fixnum_one)
169        __(cmpri(cr1,imm4,0))
170        __(ldr(temp0,tcr.catch_top(rcontext)))
171        __(ldr(imm1,tcr.db_link(rcontext)))
172        __(blt cr1,local_label(_nthrowv_done))
173        __(ldr(imm0,catch_frame.db_link(temp0)))
174        __(ldr(imm3,catch_frame.link(temp0)))
175        __(cmpr(cr0,imm0,imm1))
176        __(str(imm3,tcr.catch_top(rcontext)))
177        __(ldr(temp1,catch_frame.catch_tag(temp0)))
178        __(cmpri(cr7,temp1,unbound_marker))             /* unwind-protect ?  */
179        __(ldr(first_nvr,catch_frame.xframe(temp0)))
180        __(str(first_nvr,tcr.xframe(rcontext)))
181        __(ldr(sp,catch_frame.csp(temp0)))
182        __(beq cr0,local_label(_nthrowv_dont_unbind))
183        __(mflr loc_pc)
184        __(bl _SPunbind_to)
185        __(mtlr loc_pc)
186local_label(_nthrowv_dont_unbind):
187        __(beq cr7,local_label(_nthrowv_do_unwind))
188/* A catch frame.  If the last one, restore context from there.  */
189        __(bne cr1,local_label(_nthrowv_skip))
190        __(ldr(imm0,lisp_frame.savevsp(sp)))
191        __(str(rzero,lisp_frame.savevsp(sp)))   /* marker for stack overflow code  */
192        __(add imm1,vsp,nargs)
193        __(mr imm2,nargs)
194        __(b local_label(_nthrowv_push_test))
195local_label(_nthrowv_push_loop):
196        __(ldru(temp1,-node_size(imm1)))
197        __(push(temp1,imm0))
198local_label(_nthrowv_push_test):
199        __(cmpri(imm2,0))
200        __(subi imm2,imm2,fixnum_one)
201        __(bne local_label(_nthrowv_push_loop))
202        __(mr vsp,imm0)
203        __(restore_catch_nvrs(temp0))
204
205local_label(_nthrowv_skip):
206        __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
207        __(unlink(tsp))
208        __(discard_lisp_frame())
209        __(b local_label(_nthrowv_nextframe))
210local_label(_nthrowv_do_unwind):
211        /* This is harder.  Call the cleanup code with the multiple */
212        /* values (and nargs, which is a fixnum.)  Remember the throw count  */
213        /* (also a fixnum) as well.  */
214        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
215        /* protect.  (Clever, eh ?)  */
216        __(ldr(first_nvr,catch_frame.xframe(temp0)))
217        __(str(first_nvr,tcr.xframe(rcontext)))
218        __(restore_catch_nvrs(temp0))
219        __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
220        __(unlink(tsp))
221        __(ldr(loc_pc,lisp_frame.savelr(sp)))
222        __(ldr(nfn,lisp_frame.savefn(sp)))
223        __(mtctr loc_pc)        /* cleanup code address.  */
224        __(str(fn,lisp_frame.savefn(sp)))
225        __(mflr loc_pc)
226        __(mr fn,nfn)
227        __(str(loc_pc,lisp_frame.savelr(sp)))
228        __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* tsp overhead, nargs, throw count  */
229        __(TSP_Alloc_Var_Boxed_nz(imm0,imm1))
230        __(mr imm2,nargs)
231        __(add imm1,nargs,vsp)
232        __(la imm0,tsp_frame.data_offset(tsp))
233        __(str(nargs,0(imm0)))
234        __(b local_label(_nthrowv_tpushtest))
235local_label(_nthrowv_tpushloop):
236        __(ldru(temp0,-node_size(imm1)))
237        __(stru(temp0,node_size(imm0)))
238        __(subi imm2,imm2,fixnum_one)
239local_label(_nthrowv_tpushtest):
240        __(cmpri(imm2,0))
241        __(bne local_label(_nthrowv_tpushloop))
242        __(stru(imm4,node_size(imm0)))
243        __(ldr(vsp,lisp_frame.savevsp(sp)))
244        /* Interrupts should be disabled here (we're calling and returning */
245        /* from the cleanup form.  Clear the tcr.unwinding flag, so that */
246        /* interrupts can be taken if they're enabled in the cleanup form.  */
247        __(str(rzero,tcr.unwinding(rcontext)))       
248        __(bctrl)
249        __(li imm1,1)
250        __(la imm0,tsp_frame.data_offset(tsp))
251        __(str(imm1,tcr.unwinding(rcontext)))
252        __(ldr(fn,lisp_frame.savefn(sp)))
253        __(ldr(loc_pc,lisp_frame.savelr(sp)))
254        __(discard_lisp_frame())
255        __(mtlr loc_pc)
256        __(ldr(nargs,0(imm0)))
257        __(mr imm2,nargs)
258        __(b local_label(_nthrowv_tpoptest))
259local_label(_nthrowv_tpoploop):
260        __(ldru(temp0,node_size(imm0)))
261        __(vpush(temp0))
262        __(subi imm2,imm2,fixnum_one)
263local_label(_nthrowv_tpoptest):
264        __(cmpri(imm2,0))
265        __(bne local_label(_nthrowv_tpoploop))
266        __(ldr(imm4,node_size(imm0)))
267        __(unlink(tsp))
268        __(b local_label(_nthrowv_nextframe))
269local_label(_nthrowv_done):
270        __(str(rzero,tcr.unwinding(rcontext)))
271        /* Poll for a deferred interrupt.  That clobbers nargs (which we've */
272        /* just expended a lot of effort to preserve), so expend a little *
273        /* more effort. */
274        __(mr imm4,nargs)
275        __(check_pending_interrupt())
276        __(mr nargs,imm4)
277        __(blr)
278
279/* This is a (slight) optimization.  When running an unwind-protect, */
280/* save the single value and the throw count in the tstack frame. */
281/* Note that this takes a single value in arg_z.  */
282_spentry(nthrow1value)
283        __(li imm1,1)
284        __(mr imm4,imm0)
285        __(str(imm1,tcr.unwinding(rcontext)))
286local_label(_nthrow1v_nextframe):
287        __(subi imm4,imm4,fixnum_one)
288        __(cmpri(cr1,imm4,0))
289        __(ldr(temp0,tcr.catch_top(rcontext)))
290        __(ldr(imm1,tcr.db_link(rcontext)))
291        __(set_nargs(1))
292        __(blt cr1,local_label(_nthrow1v_done))
293        __(ldr(imm3,catch_frame.link(temp0)))
294        __(ldr(imm0,catch_frame.db_link(temp0)))
295        __(cmpr(cr0,imm0,imm1))
296        __(str(imm3,tcr.catch_top(rcontext)))
297        __(ldr(imm3,catch_frame.xframe(temp0)))
298        __(ldr(temp1,catch_frame.catch_tag(temp0)))
299        __(cmpri(cr7,temp1,unbound_marker))             /* unwind-protect ?  */
300        __(str(imm3,tcr.xframe(rcontext)))
301        __(ldr(sp,catch_frame.csp(temp0)))
302        __(beq cr0,local_label(_nthrow1v_dont_unbind))
303         __(mflr loc_pc)
304         __(bl _SPunbind_to)
305         __(mtlr loc_pc)
306local_label(_nthrow1v_dont_unbind):
307        __(beq cr7,local_label(_nthrow1v_do_unwind))
308        /* A catch frame.  If the last one, restore context from there.  */
309        __(bne cr1,local_label(_nthrow1v_skip))
310        __(ldr(vsp,lisp_frame.savevsp(sp)))
311        __(restore_catch_nvrs(temp0))
312local_label(_nthrow1v_skip):
313        __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
314        __(unlink(tsp))
315        __(discard_lisp_frame())
316        __(b local_label(_nthrow1v_nextframe))
317local_label(_nthrow1v_do_unwind):
318        /* This is harder, but not as hard (not as much BLTing) as the  */
319        /* multiple-value case.  */
320        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
321        /* protect.  (Clever, eh ?)  */
322
323        __(restore_catch_nvrs(temp0))
324        __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
325        __(unlink(tsp))
326        __(ldr(loc_pc,lisp_frame.savelr(sp)))
327        __(ldr(nfn,lisp_frame.savefn(sp)))
328        __(mtctr loc_pc)                /* cleanup code address.  */
329        __(str(fn,lisp_frame.savefn(sp)))
330        __(mflr loc_pc)
331        __(mr fn,nfn)
332        __(str(loc_pc,lisp_frame.savelr(sp)))
333        __(TSP_Alloc_Fixed_Boxed(2*node_size)) /* tsp overhead, value, throw count  */
334        __(str(arg_z,tsp_frame.data_offset(tsp)))
335        __(str(imm4,tsp_frame.data_offset+node_size(tsp)))
336        __(ldr(vsp,lisp_frame.savevsp(sp)))
337        __(str(rzero,tcr.unwinding(rcontext)))
338        __(bctrl)
339        __(li imm1,1)
340        __(ldr(arg_z,tsp_frame.data_offset(tsp)))
341        __(str(imm1,tcr.unwinding(rcontext)))
342        __(ldr(imm4,tsp_frame.data_offset+node_size(tsp)))
343        __(ldr(fn,lisp_frame.savefn(sp)))
344        __(ldr(loc_pc,lisp_frame.savelr(sp)))
345        __(discard_lisp_frame())
346        __(mtlr loc_pc)
347        __(unlink(tsp))
348        __(b local_label(_nthrow1v_nextframe))
349local_label(_nthrow1v_done):
350        __(str(rzero,tcr.unwinding(rcontext)))
351        /* nargs has an undefined value here, so we can clobber it while */
352        /* polling for a deferred interrupt  */
353        __(check_pending_interrupt())
354        __(blr)
355
356/* This never affects the symbol's vcell  */
357/* Non-null symbol in arg_y, new value in arg_z          */
358_spentry(bind)
359        __(ldr(imm3,symbol.binding_index(arg_y)))
360        __(ldr(imm0,tcr.tlb_limit(rcontext)))
361        __(cmpri(imm3,0))
362        __(trlle(imm0,imm3))           /* tlb too small  */
363        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
364        __(ldr(imm1,tcr.db_link(rcontext)))
365        __(ldrx(temp1,imm2,imm3))
366        __(beq 9f)
367        __(vpush(temp1))
368        __(vpush(imm3))
369        __(vpush(imm1))
370        __(strx(arg_z,imm2,imm3))
371        __(str(vsp,tcr.db_link(rcontext)))
372        __(blr)
3739:
374        __(mr arg_z,arg_y)
375        __(lwi(arg_y,XSYMNOBIND))
376        __(set_nargs(2))
377        __(b _SPksignalerr)
378
379/* arg_z = symbol: bind it to its current value          */
380_spentry(bind_self)
381        __(ldr(imm3,symbol.binding_index(arg_z)))
382        __(ldr(imm0,tcr.tlb_limit(rcontext)))
383        __(cmpri(imm3,0))
384        __(trlle(imm0,imm3))           /* tlb too small  */
385        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
386        __(ldr(imm1,tcr.db_link(rcontext)))
387        __(ldrx(temp1,imm2,imm3))
388        __(cmpri(cr1,temp1,no_thread_local_binding_marker))
389        __(beq 9f)
390        __(mr temp0,temp1)
391        __(bne cr1,1f)
392        __(ldr(temp0,symbol.vcell(arg_z)))
3931:             
394        __(vpush(temp1))
395        __(vpush(imm3))
396        __(vpush(imm1))
397        __(strx(temp0,imm2,imm3))
398        __(str(vsp,tcr.db_link(rcontext)))
399        __(blr)
4009:      __(lwi(arg_y,XSYMNOBIND))
401        __(set_nargs(2))
402        __(b _SPksignalerr)
403
404/* Bind symbol in arg_z to NIL                 */
405_spentry(bind_nil)
406        __(ldr(imm3,symbol.binding_index(arg_z)))
407        __(ldr(imm0,tcr.tlb_limit(rcontext)))
408        __(cmpri(imm3,0))
409        __(beq- 9f)
410        __(trlle(imm0,imm3))           /* tlb too small  */
411        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
412        __(ldrx(temp1,imm2,imm3))
413        __(ldr(imm1,tcr.db_link(rcontext)))
414        __(li imm0,nil_value)
415        __(vpush(temp1))
416        __(vpush(imm3))
417        __(vpush(imm1))
418        __(strx(imm0,imm2,imm3))
419        __(str(vsp,tcr.db_link(rcontext)))
420        __(blr)
4219:      __(lwi(arg_y,XSYMNOBIND))
422        __(set_nargs(2))
423        __(b _SPksignalerr)
424
425       
426/* Bind symbol in arg_z to its current value;  trap if symbol is unbound */
427_spentry(bind_self_boundp_check)
428        __(ldr(imm3,symbol.binding_index(arg_z)))
429        __(ldr(imm0,tcr.tlb_limit(rcontext)))
430        __(cmpri(imm3,0))
431        __(trlle(imm0,imm3))           /* tlb too small  */
432        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
433        __(ldrx(temp1,imm2,imm3))
434        __(ldr(imm1,tcr.db_link(rcontext)))
435        __(beq 9f)              /* no real tlb index  */
436        __(cmpri(temp1,no_thread_local_binding_marker))
437        __(mr temp0,temp1)
438        __(bne 1f)
439        __(ldr(temp0,symbol.vcell(arg_z)))
4401:      __(treqi(temp0,unbound_marker))       
441        __(vpush(temp1))
442        __(vpush(imm3))
443        __(vpush(imm1))
444        __(strx(temp0,imm2,imm3))
445        __(str(vsp,tcr.db_link(rcontext)))
446        __(blr)
4479:      __(lwi(arg_y,XSYMNOBIND))
448        __(set_nargs(2))
449        __(b _SPksignalerr)
450
451
452/* The function pc_luser_xp() - which is used to ensure that suspended threads */
453/* are suspended in a GC-safe way - has to treat these subprims (which  */
454/* implement the EGC write-barrier) specially.  Specifically, a store that */
455/* might introduce an intergenerational reference (a young pointer stored  */
456/* in an old object) has to "memoize" that reference by setting a bit in  */
457/* the global "refbits" bitmap. */
458/* This has to happen atomically, and has to happen atomically wrt GC. */
459/* Note that updating a word in a bitmap is itself not atomic, unless we use */
460/* interlocked loads and stores. */
461
462
463/* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
464/* are in the function, we can do the store (even if it's already been done)  */
465/* and calculate whether or not we need to set the bit out-of-line.  (Actually */
466/* setting the bit needs to be done atomically, unless we're sure that other */
467/* threads are suspended.) */
468/* We can unconditionally set the suspended thread's PC to its LR. */
469       
470        .globl C(egc_write_barrier_start)
471_spentry(rplaca)
472C(egc_write_barrier_start):
473        __(cmplr(cr2,arg_z,arg_y))
474        __(_rplaca(arg_y,arg_z))
475        __(blelr cr2)
476        __(ref_global(imm2,heap_start))
477        __(sub imm0,arg_y,imm2)
478        __(load_highbit(imm3))
479        __(srri(imm0,imm0,dnode_shift))       
480        __(ref_global(imm1,oldspace_dnode_count))
481        __(extract_bit_shift_count(imm4,imm0))
482        __(cmplr(imm0,imm1))
483        __(srr(imm3,imm3,imm4))
484        __(srri(imm0,imm0,bitmap_shift))       
485        __(ref_global(imm2,refbits))
486        __(bgelr)
487        __(slri(imm0,imm0,word_shift))
488        __(ldrx(imm1,imm2,imm0))
489        __(and. imm1,imm1,imm3)
490        __(bnelr)
4911:      __(lrarx(imm1,imm2,imm0))
492        __(or imm1,imm1,imm3)
493        __(strcx(imm1,imm2,imm0))
494        __(bne- 1b)
495        __(isync)
496        __(blr)
497
498        .globl C(egc_rplacd)
499_spentry(rplacd)
500C(egc_rplacd):
501        __(cmplr(cr2,arg_z,arg_y))
502        __(_rplacd(arg_y,arg_z))
503        __(blelr cr2)
504        __(ref_global(imm2,heap_start))
505        __(sub imm0,arg_y,imm2)
506        __(load_highbit(imm3))
507        __(srri(imm0,imm0,dnode_shift))       
508        __(ref_global(imm1,oldspace_dnode_count))
509        __(extract_bit_shift_count(imm4,imm0))
510        __(cmplr(imm0,imm1))
511        __(srr(imm3,imm3,imm4))
512        __(srri(imm0,imm0,bitmap_shift))       
513        __(ref_global(imm2,refbits))
514        __(bgelr)
515        __(slri(imm0,imm0,word_shift))
516        __(ldrx(imm1,imm2,imm0))
517        __(and. imm1,imm1,imm3)
518        __(bnelr)       
5191:      __(lrarx(imm1,imm2,imm0))
520        __(or imm1,imm1,imm3)
521        __(strcx(imm1,imm2,imm0))
522        __(bne- 1b)
523        __(isync)
524        __(blr)
525
526/* Storing into a gvector can be handled the same way as storing into a CONS. */
527
528        .globl C(egc_gvset)
529_spentry(gvset)
530C(egc_gvset):
531        __(cmplr(cr2,arg_z,arg_x))
532        __(la imm0,misc_data_offset(arg_y))
533        __(strx(arg_z,arg_x,imm0))
534        __(blelr cr2)
535        __(add imm0,imm0,arg_x)
536        __(ref_global(imm2,heap_start))
537        __(load_highbit(imm3))
538        __(ref_global(imm1,oldspace_dnode_count))
539        __(sub imm0,imm0,imm2)
540        __(srri(imm0,imm0,dnode_shift))       
541        __(cmplr(imm0,imm1))
542        __(extract_bit_shift_count(imm4,imm0))
543        __(srri(imm0,imm0,bitmap_shift))       
544        __(srr(imm3,imm3,imm4))
545        __(ref_global(imm2,refbits))
546        __(bgelr)
547        __(slri(imm0,imm0,word_shift))
548        __(ldrx(imm1,imm2,imm0))
549        __(and. imm1,imm1,imm3)
550        __(bnelr)       
5511:      __(lrarx(imm1,imm2,imm0))
552        __(or imm1,imm1,imm3)
553        __(strcx(imm1,imm2,imm0))
554        __(bne- 1b)
555        __(isync)
556        __(blr)
557
558/* This is a special case of storing into a gvector: if we need to memoize  */
559/* the store, record the address of the hash-table vector in the refmap,  */
560/* as well. */
561        .globl C(egc_set_hash_key)       
562_spentry(set_hash_key)
563C(egc_set_hash_key):
564        __(cmplr(cr2,arg_z,arg_x))
565        __(la imm0,misc_data_offset(arg_y))
566        __(strx(arg_z,arg_x,imm0))
567        __(blelr cr2)
568        __(add imm0,imm0,arg_x)
569        __(ref_global(imm2,heap_start))
570        __(load_highbit(imm3))
571        __(ref_global(imm1,oldspace_dnode_count))
572        __(sub imm0,imm0,imm2)
573        __(srri(imm0,imm0,dnode_shift))       
574        __(cmplr(imm0,imm1))
575        __(extract_bit_shift_count(imm4,imm0))
576        __(srri(imm0,imm0,bitmap_shift))       
577        __(srr(imm3,imm3,imm4))
578        __(ref_global(imm2,refbits))
579        __(bgelr)
580        __(slri(imm0,imm0,word_shift))
581        __(ldrx(imm1,imm2,imm0))
582        __(and. imm1,imm1,imm3)
583        __(bne 2f)       
5841:      __(lrarx(imm1,imm2,imm0))
585        __(or imm1,imm1,imm3)
586        __(strcx(imm1,imm2,imm0))
587        __(bne- 1b)
588        __(isync)
5892:             
590        __(ref_global(imm1,heap_start))
591        __(sub imm0,arg_x,imm1)
592        __(srri(imm0,imm0,dnode_shift))
593        __(load_highbit(imm3))
594        __(extract_bit_shift_count(imm4,imm0))
595        __(srri(imm0,imm0,bitmap_shift))
596        __(srr(imm3,imm3,imm4))
597        __(slri(imm0,imm0,word_shift))
598        __(ldrx(imm1,imm2,imm0))
599        __(and. imm1,imm1,imm3)
600        __(bnelr)
6013:      __(lrarx(imm1,imm2,imm0))
602        __(or imm1,imm1,imm3)
603        __(strcx(imm1,imm2,imm0))
604        __(bne- 3b)
605        __(isync)
606        __(blr)
607       
608/*
609   Interrupt handling (in pc_luser_xp()) notes: 
610   If we are in this function and before the test which follows the
611   conditional (at egc_store_node_conditional), or at that test
612   and cr0[eq] is clear, pc_luser_xp() should just let this continue
613   (we either haven't done the store conditional yet, or got a
614   possibly transient failure.)  If we're at that test and the
615   cr0[EQ] bit is set, then the conditional store succeeded and
616   we have to atomically memoize the possible intergenerational
617   reference.  Note that the local labels 4 and 5 are at or beyond
618  'egc_write_barrier_end'
619
620   N.B: it's not possible to really understand what's going on just
621   by the state of the cr0[eq] bit.  A transient failure in the
622   conditional stores that handle memoization might clear cr0[eq]
623   without having completed the memoization.
624*/
625
626        .globl C(egc_store_node_conditional)
627        .globl C(egc_write_barrier_end)
628_spentry(store_node_conditional)
629C(egc_store_node_conditional):
630        __(crclr 2)              /* 2 = cr0_EQ  */
631        __(cmplr(cr2,arg_z,arg_x))
632        __(vpop(temp0))
633        __(unbox_fixnum(imm4,temp0))
6341:      __(lrarx(temp1,arg_x,imm4))
635        __(cmpr(cr1,temp1,arg_y))
636        __(bne cr1,3f)
637        __(strcx(arg_z,arg_x,imm4))
638        .globl C(egc_store_node_conditional_test)
639C(egc_store_node_conditional_test):     
640        __(bne 1b)
641        __(isync)
642        __(add imm0,imm4,arg_x)
643        __(ref_global(imm2,heap_start))
644        __(ref_global(imm1,oldspace_dnode_count))
645        __(sub imm0,imm0,imm2)
646        __(load_highbit(imm3))
647        __(srri(imm0,imm0,dnode_shift))       
648        __(cmplr(imm0,imm1))
649        __(extract_bit_shift_count(imm2,imm0))
650        __(srri(imm0,imm0,bitmap_shift))       
651        __(srr(imm3,imm3,imm2))
652        __(ref_global(imm2,refbits))
653        __(bge 5f)
654        __(slri(imm0,imm0,word_shift))
6552:      __(lrarx(imm1,imm2,imm0))
656        __(or imm1,imm1,imm3)
657        __(strcx( imm1,imm2,imm0))
658        __(bne- 2b)
659        __(isync)
660        __(b 5f)
661C(egc_write_barrier_end):
6623:      __(li imm0,RESERVATION_DISCHARGE)
663        __(strcx(rzero,0,imm0))
6644:      __(li arg_z,nil_value)
665        __(blr)
6665:      __(li arg_z,t_value)
667        __(blr)
668
669       
670_spentry(conslist)
671        __(li arg_z,nil_value)
672        __(cmpri(nargs,0))
673        __(b 2f)       
6741:
675        __(ldr(temp0,0(vsp)))
676        __(cmpri(nargs,fixnum_one))
677        __(la vsp,node_size(vsp))
678        __(Cons(arg_z,temp0,arg_z))
679        __(subi nargs,nargs,fixnum_one)
6802:
681        __(bne 1b)
682        __(blr)
683       
684/* do list*: last arg in arg_z, all others vpushed, nargs set to #args vpushed.  */
685/* Cons, one cons cell at at time.  Maybe optimize this later.  */
686_spentry(conslist_star)
687        __(cmpri(nargs,0))
688        __(b 2f)       
6891:
690        __(ldr(temp0,0(vsp)))
691        __(cmpri(nargs,fixnum_one))
692        __(la vsp,node_size(vsp))
693        __(Cons(arg_z,temp0,arg_z))
694        __(subi nargs,nargs,fixnum_one)
6952:
696        __(bne 1b)
697        __(blr)
698
699/* We always have to create a tsp frame (even if nargs is 0), so the compiler  */
700/* doesn't get confused.  */
701_spentry(stkconslist)
702        __(li arg_z,nil_value)
703        __(cmpri(cr1,nargs,0))
704        __(add imm1,nargs,nargs)
705        __(addi imm1,imm1,tsp_frame.fixed_overhead)
706        __(TSP_Alloc_Var_Boxed(imm1,imm2))
707        __(la imm1,tsp_frame.data_offset+fulltag_cons(tsp))
708        __(b 2f)
7091:      __(ldr(temp0,0(vsp)))
710        __(cmpri(cr1,nargs,fixnum_one))
711        __(la vsp,node_size(vsp))
712        __(_rplaca(imm1,temp0))
713        __(_rplacd(imm1,arg_z))
714        __(mr arg_z,imm1)
715        __(la imm1,cons.size(imm1))
716        __(la nargs,-fixnum_one(nargs))
7172:
718        __(bne cr1,1b)
719        __(blr)
720
721/* do list*: last arg in arg_z, all others vpushed,  */
722/* nargs set to #args vpushed.  */
723_spentry(stkconslist_star)
724        __(cmpri(cr1,nargs,0))
725        __(add imm1,nargs,nargs)
726        __(addi imm1,imm1,tsp_frame.fixed_overhead)
727        __(TSP_Alloc_Var_Boxed(imm1,imm2))
728        __(la imm1,tsp_frame.data_offset+fulltag_cons(tsp))
729        __(b 2f)
7301:      __(ldr(temp0,0(vsp)))
731        __(cmpri(cr1,nargs,fixnum_one))
732        __(la vsp,node_size(vsp))
733        __(_rplaca(imm1,temp0))
734        __(_rplacd(imm1,arg_z))
735        __(mr arg_z,imm1)
736        __(la imm1,cons.size(imm1))
737        __(la nargs,-fixnum_one(nargs))
7382:
739        __(bne cr1,1b)
740        __(blr)
741
742
743/* Make a stack-consed simple-vector out of the NARGS objects  */
744/* on top of the vstack; return it in arg_z.  */
745_spentry(mkstackv)
746        __(cmpri(cr1,nargs,0))
747        __(dnode_align(imm1,nargs,tsp_frame.fixed_overhead+node_size))
748        __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
749        __(slwi imm0,nargs,num_subtag_bits-fixnumshift)
750        __(ori imm0,imm0,subtag_simple_vector)
751        __(str(imm0,tsp_frame.data_offset(tsp)))
752        __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
753        __(beq- cr1,2f)
754        __(la imm0,misc_data_offset(arg_z))
755        __(add imm1,imm0,nargs)
7561:
757        __(la nargs,-node_size(nargs))
758        __(cmpri(cr1,nargs,0))
759        __(ldr(temp1,0(vsp)))
760        __(la vsp,node_size(vsp))
761        __(stru(temp1,-node_size(imm1)))
762        __(bne cr1,1b)
7632:
764        __(blr)
765
766       
767       
768
769_spentry(setqsym)
770        __(ldr(imm0,symbol.flags(arg_y)))
771        __(andi. imm0,imm0,sym_vbit_const_mask)
772        __(beq _SPspecset)
773        __(mr arg_z,arg_y)
774        __(lwi(arg_y,XCONST))
775        __(set_nargs(2))
776        __(b _SPksignalerr)
777
778
779       
780_spentry(progvsave)
781        /* Error if arg_z isn't a proper list.  That's unlikely, */
782        /* but it's better to check now than to crash later. */
783       
784        __(cmpri(arg_z,nil_value))
785        __(mr arg_x,arg_z)      /* fast  */
786        __(mr temp1,arg_z)      /* slow  */
787        __(beq 9f)              /* Null list is proper  */
7880:     
789        __(trap_unless_list(arg_x,imm0))
790        __(_cdr(temp2,arg_x))   /* (null (cdr fast)) ?  */
791        __(cmpri(cr3,temp2,nil_value))
792        __(trap_unless_list(temp2,imm0,cr0))
793        __(_cdr(arg_x,temp2))
794        __(beq cr3,9f)
795        __(_cdr(temp1,temp1))
796        __(cmpr(arg_x,temp1))
797        __(bne 0b)
798        __(lwi(arg_y,XIMPROPERLIST))
799        __(set_nargs(2))
800        __(b _SPksignalerr)
8019:      /* Whew          */
802       
803        /* Next, determine the length of arg_y.  We  */
804        /* know that it's a proper list.  */
805        __(li imm0,-node_size)
806        __(mr arg_x,arg_y)
8071:
808        __(cmpri(cr0,arg_x,nil_value))
809        __(la imm0,node_size(imm0))
810        __(_cdr(arg_x,arg_x))
811        __(bne 1b)
812        /* imm0 is now (boxed) triplet count.  */
813        /* Determine word count, add 1 (to align), and make room.  */
814        /* if count is 0, make an empty tsp frame and exit  */
815        __(cmpri(cr0,imm0,0))
816        __(add imm1,imm0,imm0)
817        __(add imm1,imm1,imm0)
818        __(dnode_align(imm1,imm1,node_size))
819        __(bne+ cr0,2f)
820         __(TSP_Alloc_Fixed_Boxed(2*node_size))
821         __(blr)
8222:
823        __(la imm1,tsp_frame.fixed_overhead(imm1))      /* tsp header  */
824        __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
825        __(str(imm0,tsp_frame.data_offset(tsp)))
826        __(ldr(imm2,tsp_frame.backlink(tsp)))
827        __(mr arg_x,arg_y)
828        __(ldr(imm1,tcr.db_link(rcontext)))
829        __(ldr(imm3,tcr.tlb_limit(rcontext)))
8303:
831        __(cmpri(cr1,arg_z,nil_value))
832        __(_car(temp0,arg_x))
833        __(ldr(imm0,symbol.binding_index(temp0)))
834        __(_cdr(arg_x,arg_x))
835        __(trlle(imm3,imm0))
836        __(ldr(imm4,tcr.tlb_pointer(rcontext))) /* Need to reload after trap  */
837        __(ldrx(temp3,imm4,imm0))
838        __(cmpri(cr0,arg_x,nil_value))
839        __(li temp2,unbound_marker)
840        __(beq cr1,4f)
841        __(_car(temp2,arg_z))
842        __(_cdr(arg_z,arg_z))
8434:      __(push(temp3,imm2))
844        __(push(imm0,imm2))
845        __(push(imm1,imm2))
846        __(strx(temp2,imm4,imm0))
847        __(mr imm1,imm2)
848        __(bne cr0,3b)
849        __(str(imm2,tcr.db_link(rcontext)))
850        __(blr)
851
852       
853/* Allocate a miscobj on the temp stack.  (Push a frame on the tsp and  */
854/* heap-cons the object if there's no room on the tstack.)  */
855_spentry(stack_misc_alloc)
856        __ifdef([PPC64])
857         __(extract_unsigned_byte_bits_(imm2,arg_y,56))
858         __(unbox_fixnum(imm0,arg_z))
859         __(clrldi imm2,imm0,64-nlowtagbits)
860         __(extract_fulltag(imm1,imm0))
861         __(bne cr0,9f)
862         __(cmpdi cr2,imm2,lowtag_nodeheader)
863         __(cmpdi cr4,imm1,ivector_class_8_bit)
864         __(cmpdi cr1,imm1,ivector_class_64_bit)
865         __(cmpdi cr3,imm1,ivector_class_32_bit)
866         __(cmpdi cr5,imm1,ivector_class_other_bit)
867         __(sldi imm1,arg_y,num_subtag_bits-fixnumshift)
868         __(mr imm2,arg_y)
869         __(beq cr2,3f)
870         __(cmpdi cr2,imm0,subtag_bit_vector)
871         __(beq cr1,3f)
872         __(beq cr3,1f)
873         __(beq cr4,2f)
874         __(beq cr2,0f)
875         /* 2 bytes per element  */
876         __(srdi imm2,imm2,2)
877         __(b 3f)
8780:       /* bit-vector case  */
879         __(addi imm2,imm2,7<<fixnumshift)
880         __(srdi imm2,imm2,3+fixnumshift)
881         __(b 3f)       
882         /* 4 bytes per element  */
8831:       __(srdi imm2,imm2,1)
884         __(b 3f)
8852:       /* 1 byte per element  */
886         __(srdi imm2,imm2,3)
8873:       /* 8 bytes per element  */
888         __(or imm0,imm1,imm0)   /* imm0 = header, imm2 = byte count  */
889         __(dnode_align(imm3,imm2,tsp_frame.fixed_overhead+node_size))
890         __(cmpldi cr0,imm3,tstack_alloc_limit) /* more than limit ?  */
891         __(bgt- cr0,4f)
892         __(TSP_Alloc_Var_Boxed_nz(imm3,imm4))
893        /* Slap the header on the vector, then return.  */
894         __(str(imm0,tsp_frame.data_offset(tsp)))
895         __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
896        __(blr)
897        /* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
898        /* sure that there's an empty tsp frame to keep the compiler happy.  */
8994:       __(TSP_Alloc_Fixed_Unboxed(0))
900         __(b _SPmisc_alloc)
901        __else
902         __(rlwinm. imm2,arg_y,32-fixnumshift,0,(8+fixnumshift)-1)
903         __(unbox_fixnum(imm0,arg_z))
904         __(extract_fulltag(imm1,imm0))
905         __(bne- cr0,9f)
906         __(cmpri(cr0,imm1,fulltag_nodeheader))
907         __(mr imm3,imm0)
908         __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
909         __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits) /* imm0 now = header  */
910         __(mr imm2,arg_y)
911         __(beq cr0,1f) /* do probe if node object  */
912                        /* (fixnum element count = byte count).  */
913         __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
914         __(bng cr1,1f) /* do probe if 32-bit imm object  */
915         __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
916         __(srwi imm2,imm2,1)
917         __(bgt cr0,3f)
918         __(bgt cr1,1f)
919         __(srwi imm2,imm2,1)
920/* imm2 now = byte count.  Add 4 for header, 7 to align, then  */
921/*      clear low three bits.  */
9221:
923         __(dnode_align(imm3,imm2,tsp_frame.fixed_overhead+node_size))
924         __(cmplri(cr0,imm3,tstack_alloc_limit)) /* more than limit ?  */
925         __(bgt- cr0,0f)
926         __(TSP_Alloc_Var_Boxed_nz(imm3,imm4))
927
928/* Slap the header on the vector, then return.  */
929         __(str(imm0,tsp_frame.data_offset(tsp)))
930         __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
931         __(blr)
9329:
933
934
935
936/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
937/* sure that there's an empty tsp frame to keep the compiler happy.  */
9380:
939         __(TSP_Alloc_Fixed_Unboxed(0))
940         __(b _SPmisc_alloc)
9413:
942         __(cmplri(imm3,subtag_double_float_vector))
943         __(slwi imm2,arg_y,1)
944         __(beq 1b)
945         __(addi imm2,arg_y,7<<fixnumshift)
946         __(srwi imm2,imm2,fixnumshift+3)
947         __(b 1b)
948        __endif
949       
950/* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
951/* initial-contents.  Note that this can be used to cons any type of initialized  */
952/* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
953/* objects.  */
954/* Note that we're guaranteed to win (or force GC, or run out of memory)  */
955/* because nargs < 32K.  */
956_spentry(gvector)
957        __(subi nargs,nargs,node_size)
958        __(ldrx(arg_z,vsp,nargs))
959        __(unbox_fixnum(imm0,arg_z))
960        __ifdef([PPC64])
961         __(sldi imm1,nargs,num_subtag_bits-fixnum_shift)
962         __(or imm0,imm0,imm1)
963        __else
964         __(rlwimi imm0,nargs,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits)
965        __endif
966        __(dnode_align(imm1,nargs,node_size))
967        __(Misc_Alloc(arg_z,imm0,imm1))
968        __(mr imm1,nargs)
969        __(la imm2,misc_data_offset(imm1))
970        __(b 2f)
9711:
972        __(strx(temp0,arg_z,imm2))
9732:
974        __(subi imm1,imm1,node_size)
975        __(cmpri(cr0,imm1,0))
976        __(subi imm2,imm2,node_size)
977        __(vpop(temp0))         /* Note the intentional fencepost: */
978                                /* discard the subtype as well.  */
979        __(bge cr0,1b)
980        __(blr)
981       
982       
983/* funcall temp0, returning multiple values if it does.  */
984_spentry(mvpass)
985        __(cmpri(cr0,nargs,node_size*nargregs))
986        __(mflr loc_pc)
987        __(mr imm0,vsp)
988        __(ble+ cr0,1f)
989         __(subi imm0,imm0,node_size*nargregs)
990         __(add imm0,imm0,nargs)
9911:
992        __(build_lisp_frame(fn,loc_pc,imm0))
993        __(ref_global(loc_pc,ret1val_addr))
994        __(li fn,0)
995        __(mtlr loc_pc)
996        __(do_funcall())
997       
998/* ret1valn returns "1 multiple value" when a called function does not  */
999/* return multiple values.  Its presence on the stack (as a return address)  */
1000/* identifies the stack frame to code which returns multiple values.  */
1001
1002_exportfn(C(ret1valn))
1003        __(ldr(loc_pc,lisp_frame.savelr(sp)))
1004        __(ldr(vsp,lisp_frame.savevsp(sp)))
1005        __(mtlr loc_pc)
1006        __(ldr(fn,lisp_frame.savefn(sp)))
1007        __(discard_lisp_frame())
1008        __(vpush(arg_z))
1009        __(set_nargs(1))
1010        __(blr)
1011       
1012_spentry(fitvals)
1013        __(subf. imm0,nargs,imm0)
1014        __(li imm1,nil_value)
1015        __(bge 2f)
1016        __(sub vsp,vsp,imm0)
1017        __(blr)
10181:
1019        __(subic. imm0,imm0,node_size)
1020        __(vpush(imm1))
1021        __(addi nargs,nargs,node_size)
10222:
1023        __(bne 1b)
1024        __(blr)
1025
1026
1027_spentry(nthvalue)
1028        __(add imm0,vsp,nargs)
1029        __(ldr(imm1,0(imm0)))
1030        __(cmplr(imm1,nargs))   /*  do unsigned compare:         if (n < 0) => nil.  */
1031        __(li arg_z,nil_value)
1032        __(neg imm1,imm1)
1033        __(subi imm1,imm1,node_size)
1034        __(bge 1f)
1035        __(ldrx(arg_z,imm0,imm1))
10361:     
1037        __(la vsp,node_size(imm0))
1038        __(blr)
1039       
1040
1041/* Come here to return multiple values when  */
1042/* the caller's context isn't saved in a lisp_frame.  */
1043/* lr, fn valid; temp0 = entry vsp  */
1044
1045_spentry(values)
1046        __(mflr loc_pc)
1047local_label(return_values): 
1048        __(ref_global(imm0,ret1val_addr))
1049        __(li arg_z,nil_value)
1050        /* max tsp frame is 4K. 8+8 is overhead for save_values_to_tsp below  */
1051        /* and @do_unwind in nthrowvalues in "sp_catch.s".  */
1052        __(cmpri(cr2,nargs,4096-(dnode_size+dnode_size)))
1053        __(cmpr(cr1,imm0,loc_pc))
1054        __(cmpri(cr0,nargs,fixnum_one))
1055        __(bge cr2,2f)
1056        __(beq+ cr1,3f)
1057        __(mtlr loc_pc)
1058        __(add imm0,nargs,vsp)
1059        __(blt- cr0,1f)
1060        __(ldr(arg_z,-node_size(imm0)))
10611:
1062        __(mr vsp,temp0)
1063        __(blr)
1064
10652:
1066        __(uuo_interr(error_too_many_values,nargs))
1067        __(b 2b)
1068
1069/* Return multiple values to real caller.  */
10703:
1071        __(ldr(loc_pc,lisp_frame.savelr(sp)))
1072        __(add imm1,nargs,vsp)
1073        __(ldr(imm0,lisp_frame.savevsp(sp)))
1074        __(ldr(fn,lisp_frame.savefn(sp)))
1075        __(cmpr(cr0,imm1,imm0)) /* a fairly common case  */
1076        __(mtlr loc_pc)
1077        __(cmpri(cr1,nargs,fixnum_one)) /* sadly, a very common case  */
1078        __(discard_lisp_frame())
1079        __(beqlr cr0) /* already in the right place  */
1080        __(bne cr1,4f)
1081         __(ldr(arg_z,0(vsp)))
1082         __(mr vsp,imm0)
1083         __(vpush(arg_z))
1084         __(blr)
10854:
1086        __(blt cr1,6f)
1087        __(li imm2,fixnum_one)
10885:
1089        __(cmpr(cr0,imm2,nargs))
1090        __(addi imm2,imm2,fixnum_one)
1091        __(ldru(arg_z,-node_size(imm1)))
1092        __(push(arg_z,imm0))
1093        __(bne cr0,5b)
10946:
1095        __(mr vsp,imm0)
1096        __(blr)
1097
1098        .globl C(nvalret)
1099       
1100/* Come here with saved context on top of stack.  */
1101_spentry(nvalret)
1102C(nvalret):     
1103        __(ldr(loc_pc,lisp_frame.savelr(sp)))
1104        __(ldr(temp0,lisp_frame.savevsp(sp)))
1105        __(ldr(fn,lisp_frame.savefn(sp)))
1106        __(discard_lisp_frame())
1107        __(b local_label(return_values))
1108               
1109/* Provide default (NIL) values for &optional arguments; imm0 is  */
1110/* the (fixnum) upper limit on the total of required and &optional  */
1111/* arguments.  nargs is preserved, all arguments wind up on the  */
1112/* vstack.  */
1113_spentry(default_optional_args)
1114        __(cmplr( cr7,nargs,imm0))
1115        __(li imm5,nil_value)
1116        __(vpush_argregs())
1117        __(mr imm1,nargs)
1118        __(bgelr cr7)
11191:     
1120        __(addi imm1,imm1,fixnum_one)
1121        __(cmpr(cr0,imm1,imm0))
1122        __(vpush(imm5))
1123        __(bne cr0,1b)
1124        __(blr)
1125       
1126/* Indicate whether &optional arguments were actually supplied.  nargs  */
1127/* contains the actual arg count (minus the number of required args);  */
1128/* imm0 contains the number of &optional args in the lambda list.  */
1129/* Note that nargs may be > imm0 if &rest/&key is involved.  */
1130_spentry(opt_supplied_p)
1131        __(li imm1,0)
11321:
1133        /* (vpush (< imm1 nargs))  */
1134        __ifdef([PPC64])
1135         __(xor imm2,imm1,nargs)
1136         __(sradi imm2,imm2,63)
1137         __(or imm2,imm2,imm1)
1138         __(addi imm1,imm1,fixnumone)
1139         __(cmpr(cr0,imm1,imm0))
1140         __(subf imm2,nargs,imm2)
1141         __(srdi imm2,imm2,63)
1142         __(mulli imm2,imm2,t_offset)
1143         __(addi imm2,imm2,nil_value)
1144         __(vpush(imm2))
1145         __(bne cr0,1b)
1146         __(blr)
1147        __else
1148         __(xor imm2,imm1,nargs)
1149         __(srawi imm2,imm2,31)
1150         __(or imm2,imm2,imm1)
1151         __(addi imm1,imm1,fixnumone)
1152         __(cmpr(cr0,imm1,imm0))
1153         __(subf imm2,nargs,imm2)
1154         __(srwi imm2,imm2,31)
1155         __(insrwi imm2,imm2,1,27)
1156         __(addi imm2,imm2,nil_value)
1157         __(vpush(imm2))
1158         __(bne cr0,1b)
1159         __(blr)
1160        __endif
1161       
1162
1163
1164/* If nargs is <= imm0, vpush a nil.  Otherwise, cons a list of length  */
1165/* (- nargs imm0) and vpush it.  */
1166/* Use this entry point to heap-cons a simple &rest arg.  */
1167_spentry(heap_rest_arg)
1168        __(li imm0,0)
1169        __(vpush_argregs())
1170        __(sub imm1,nargs,imm0)
1171        __(cmpri(imm1,0))
1172        __(li arg_z,nil_value)
1173        __(b 2f)
11741:
1175        __(ldr(temp0,0(vsp)))
1176        __(cmpri(imm1,fixnum_one))
1177        __(la vsp,node_size(vsp))
1178        __(Cons(arg_z,temp0,arg_z))
1179        __(subi imm1,imm1,fixnum_one)
11802:
1181        __(bgt 1b)
1182        __(vpush(arg_z))
1183        __(blr)
1184
1185       
1186/* And this entry point when the argument registers haven't yet been  */
1187/* vpushed (as is typically the case when required/&rest but no  */
1188/* &optional/&key.)  */
1189_spentry(req_heap_rest_arg)
1190        __(vpush_argregs())
1191        __(sub imm1,nargs,imm0)
1192        __(cmpri(imm1,0))
1193        __(li arg_z,nil_value)
1194        __(b 2f)
11951:
1196        __(ldr(temp0,0(vsp)))
1197        __(cmpri(imm1,fixnum_one))
1198        __(la vsp,node_size(vsp))
1199        __(Cons(arg_z,temp0,arg_z))
1200        __(subi imm1,imm1,fixnum_one)
12012:
1202        __(bgt 1b)
1203        __(vpush(arg_z))
1204        __(blr)
1205
1206
1207_spentry(heap_cons_rest_arg)
1208        __(sub imm1,nargs,imm0)
1209        __(cmpri(imm1,0))
1210        __(li arg_z,nil_value)
1211        __(b 2f)
12121:
1213        __(ldr(temp0,0(vsp)))
1214        __(cmpri(imm1,fixnum_one))
1215        __(la vsp,node_size(vsp))
1216        __(Cons(arg_z,temp0,arg_z))
1217        __(subi imm1,imm1,fixnum_one)
12182:
1219        __(bgt 1b)
1220        __(vpush(arg_z))
1221        __(blr)
1222
1223       
1224_spentry(simple_keywords)
1225        __(li imm0,0)
1226        __(vpush_argregs())
1227        __(b _SPkeyword_bind)
1228               
1229_spentry(keyword_args)
1230        __(vpush_argregs())
1231        __(b _SPkeyword_bind)
1232
1233/* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
1234/* pairs.  There'll be imm3 keyword arguments.  Imm2 contains flags  */
1235/* that indicate whether &allow-other-keys was specified and whether  */
1236/* or not to leave the keyword/value pairs on the vstack for an &rest  */
1237/* argument.  Temp3 contains a vector of keyword specifiers which we  */
1238/* must (in general) match.  */
1239/* If the number of arguments is greater than imm0, the difference must  */
1240/* be even.  */
1241/* Note that the caller hasn't yet saved its caller's context and that  */
1242/* the temp registers used to pass next_method_context  */
1243/* (temp1) may still have "live" values in them, as does nfn (temp2).  */
1244
1245define([keyword_flags],[imm2])
1246define([keyword_vector],[temp3])
1247define([keyword_count],[imm3])
1248
1249
1250
1251define([varptr],[save0])
1252define([valptr],[save1])
1253define([limit],[save2])
1254
1255_spentry(keyword_bind)
1256        /* Before we can really do anything, we have to  */
1257        /* save the caller's context.  To do so, we need to know  */
1258        /* how many args have actually been pushed.  Ordinarily, that'*/
1259        /* be "nargs", but we may have pushed more args than we received  */
1260        /* if we had to default any &optionals.  */
1261        /* So, the number of args pushed so far is the larger of nargs  */
1262        /* and the (canonical) total of required/&optional args received.  */
1263        __(cmpr(cr0,nargs,imm0))
1264        __(add arg_z,vsp,nargs)
1265        __(bge+ cr0,1f)
1266        __(add arg_z,vsp,imm0)
12671:
1268        __(build_lisp_frame(fn,loc_pc,arg_z))
1269        __(mr fn,nfn)
1270        /* If there are key/value pairs to consider, we slide them down  */
1271        /* the vstack to make room for the value/supplied-p pairs.  */
1272        /* The first step in that operation involves pushing imm3 pairs  */
1273        /* of NILs.  */
1274        /* If there aren't any such pairs, the first step is the last  */
1275        /* step.  */
1276        __(cmpri(cr0,imm3,0))
1277        __(li arg_z,0)
1278        __(sub imm1,nargs,imm0)
1279        __(mr imm4,vsp) /* in case odd keywords error  */
1280        __(cmpri(cr1,imm1,0))
1281        __(b 3f)
12822:
1283        __(addi arg_z,arg_z,fixnum_one)
1284        __(cmplr(cr0,arg_z,imm3))
1285        __(li imm5,nil_value)
1286        __(vpush(imm5))
1287        __(vpush(imm5))
12883:
1289        __(bne cr0,2b)
1290        __(andi. arg_z,imm1,fixnum_one)
1291        __(blelr cr1)   /* no keyword/value pairs to consider.  */
1292        __(bne cr0,odd_keywords)
1293        /* We have key/value pairs.  Move them to the top of the vstack,  */
1294        /* then set the value/supplied-p vars to NIL.  */
1295        /* Have to use some save regs to do this.  */
1296        __(vpush(limit))
1297        __(vpush(valptr))
1298        __(vpush(varptr))
1299        /* recompute ptr to user args in case stack overflowed  */
1300        __(add imm4,vsp,imm3)
1301        __(add imm4,imm4,imm3)
1302        __(addi imm4,imm4,3*node_size)
1303        /* error if odd number of keyword/value args  */
1304        __(mr varptr,imm4)
1305        __(la limit,3*node_size(vsp))
1306        __(mr valptr,limit)
1307        __(mr arg_z,imm1)
13084:
1309        __(li imm4,nil_value)
1310        __(subi arg_z,arg_z,2<<fixnumshift)
1311        __(cmplri(cr0,arg_z,0))
1312        __(ldr(arg_x,node_size*0(varptr)))
1313        __(ldr(arg_y,node_size*1(varptr)))
1314        __(str(imm4,node_size*0(varptr)))
1315        __(str(imm4,node_size*1(varptr)))
1316        __(la varptr,node_size*2(varptr))
1317        __(str(arg_x,node_size*0(valptr)))
1318        __(str(arg_y,node_size*1(valptr)))
1319        __(la valptr,node_size*2(valptr))
1320        __(bne cr0,4b)
1321
1322
1323        /* Now, iterate through each supplied keyword/value pair.  If  */
1324        /* it's :allow-other-keys and the corresponding value is non-nil,  */
1325        /* note that other keys will be allowed.  */
1326        /* Find its position in the function's keywords vector.  If that'*/
1327        /* nil, note that an unknown keyword was encountered.  */
1328        /* Otherwise, if the keyword arg hasn't already had a value supplied,  */
1329        /* supply it.  */
1330        /* When done, complain if any unknown keywords were found and that  */
1331        /* situation was unexpected.  */
1332        __(mr imm4,valptr)
13335:
1334        __(cmpri(cr0,keyword_flags,16<<fixnumshift)) /* seen :a-o-k yet ?  */
1335        __(ldru(arg_z,-node_size(valptr)))
1336        __(ldru(arg_y,-node_size(valptr)))
1337        __(cmpri(cr1,arg_y,nil_value))
1338        __(li arg_x,nrs.kallowotherkeys)
1339        /* cr6_eq <- (eq current-keyword :allow-other-keys)  */
1340        __(cmpr(cr6,arg_x,arg_z))
1341        __(cmpr(cr7,valptr,limit))
1342        __(bne cr6,6f)
1343        __(bge cr0,6f) /* Already seen :allow-other-keys  */
1344        __(ori keyword_flags,keyword_flags,16<<fixnumshift)
1345        __(beq cr1,6f)
1346        __(ori keyword_flags,keyword_flags,fixnum_one)
13476:
1348        __(cmpri(cr1,imm3,0))
1349        __(li imm1,misc_data_offset)
1350        __(li imm0,0)
1351        __(b 8f)
13527:
1353        __(addi imm0,imm0,fixnum_one)
1354        __(cmpr(cr1,imm0,imm3))
1355        __(ldrx(arg_x,keyword_vector,imm1))
1356        __(cmpr(cr0,arg_x,arg_z))
1357        __(addi imm1,imm1,fixnum_one)
1358        __(bne cr0,8f)
1359        __(add imm0,imm0,imm0)
1360        __(sub imm0,varptr,imm0)
1361        __(ldr(arg_x,0(imm0)))
1362        __(cmpri(cr0,arg_x,nil_value))
1363        __(li arg_z,t_value)
1364        __(bne cr0,9f)
1365        __(str(arg_y,node_size(imm0)))
1366        __(str(arg_z,0(imm0)))
1367        __(b 9f)
13688:
1369        __(bne cr1,7b)
1370        /* Unknown keyword. If it was :allow-other-keys, cr6_eq will still */
1371        /* be set.  */
1372        __(beq cr6,9f)
1373        __(ori keyword_flags,keyword_flags,2<<fixnumshift)
13749:
1375        __(bne cr7,5b)
1376        __(vpop(varptr))
1377        __(vpop(valptr))
1378        __(vpop(limit))
1379        /* All keyword/value pairs have been processed.  */
1380        /* If we saw an unknown keyword and didn't expect to, error.  */
1381        /* Unless bit 2 is set in the fixnum in keyword_flags, discard the  */
1382        /* keyword/value pairs from the vstack.  */
1383        __(andi. imm0,keyword_flags,(fixnum_one)|(2<<fixnumshift))
1384        __(cmpri(cr0,imm0,2<<fixnumshift))
1385        __(beq- cr0,badkeys)
1386        __(andi. imm2,keyword_flags,4<<fixnumshift)
1387        __(bnelr cr0)
1388        __(mr vsp,imm4)
1389        __(blr)
1390
1391/* Signal an error.  We saved context on entry, so this thing doesn't  */
1392/* have to.  */
1393/* The "unknown keywords" error could be continuable (ignore them.)  */
1394/* It might be hard to then cons an &rest arg.  */
1395/* In the general case, it's hard to recover the set of args that were  */
1396/* actually supplied to us ...  */
1397/* For now, just cons a list out of the keyword/value pairs */
1398/* that were actually provided, and signal an "invalid keywords" */
1399/* error with that list as an operand.  */
1400odd_keywords:
1401        __(mr vsp,imm4)
1402        __(mr nargs,imm1)
1403        __(b 1f)
1404badkeys:
1405        __(sub nargs,imm4,vsp)
14061:
1407        __(bl _SPconslist)
1408        __(li arg_y,XBADKEYS)
1409        __(set_nargs(2))
1410        __(b _SPksignalerr)
1411
1412/*  A PowerOpen ff-call.  arg_z is either a fixnum (word-aligned entrypoint) */
1413/*  or a macptr (whose address had better be word-aligned as well.)  A */
1414/*  PowerOpen stack frame is on top of the stack; 4 additional words (to */
1415/*  be used a a lisp frame) sit under the C frame. */
1416
1417/*  Since we probably can't deal with FP exceptions in foreign code, we */
1418/*  disable them in the FPSCR, then check on return to see if any previously */
1419/*  enabled FP exceptions occurred. */
1420
1421/*  As it turns out, we can share a lot of code with the eabi version of */
1422/*  ff-call.  Some things that happen up to the point of call differ between */
1423/*  the ABIs, but everything that happens after is the same. */
1424
1425       
1426_spentry(poweropen_ffcall)
1427        __(mflr loc_pc)
1428        __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
1429        __(mr save0,rcontext)   /* or address globals.  */
1430        __(extract_typecode(imm0,arg_z))
1431        __(cmpri(cr7,imm0,subtag_macptr))
1432        __(ldr(save1,0(sp)))    /* bottom of reserved lisp frame  */
1433        __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
1434        __(zero_doublewords save2,0,lisp_frame.size)
1435        __(str(save1,lisp_frame.backlink(save2)))
1436        __(str(save2,c_frame.backlink(sp)))
1437        __(str(fn,lisp_frame.savefn(save2)))
1438        __(str(loc_pc,lisp_frame.savelr(save2)))
1439        __(str(vsp,lisp_frame.savevsp(save2)))
1440        __(mr nargs,arg_z)
1441        __(bne cr7,1f)
1442        __(ldr(nargs,macptr.address(arg_z)))
14431:
1444        __(ldr(save3,tcr.cs_area(rcontext)))
1445        __(str(save2,area.active(save3)))
1446        __(str(allocptr,tcr.save_allocptr(rcontext)))
1447        __(str(allocbase,tcr.save_allocbase(rcontext)))
1448        __(str(tsp,tcr.save_tsp(rcontext)))
1449        __(str(vsp,tcr.save_vsp(rcontext)))
1450        __(str(rzero,tcr.ffi_exception(rcontext)))
1451        __(mffs f0)
1452        __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
1453        __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
1454        __(li r4,TCR_STATE_FOREIGN)
1455        __(str(r4,tcr.valence(rcontext)))
1456        __ifdef([rTOC])
1457         __(ld rTOC,8(nargs))
1458         __(ld nargs,0(nargs))
1459        __else
1460         __(li rcontext,0)
1461        __endif
1462        __(mtctr nargs)
1463        __(ldr(r3,c_frame.param0(sp)))
1464        __(ldr(r4,c_frame.param1(sp)))
1465        __(ldr(r5,c_frame.param2(sp)))
1466        __(ldr(r6,c_frame.param3(sp)))
1467        __(ldr(r7,c_frame.param4(sp)))
1468        __(ldr(r8,c_frame.param5(sp)))
1469        __(ldr(r9,c_frame.param6(sp)))
1470        __(ldr(r10,c_frame.param7(sp)))
1471        /* Darwin is allegedly very picky about what register points */
1472        /* to the function on entry.  */
1473        __(mr r12,nargs)
1474        __(bctrl)
1475        __(b FF_call_return_common)
1476
1477/* Just like poweropen_ffcall, only we save all argument(result)
1478   registers in a buffer passed in arg_y on entry before returning
1479   to lisp.  (We have to do this in the ffcall glue here, because
1480   r9 and r10 - at least - are overloaded as dedicated lisp registers */
1481_spentry(poweropen_ffcall_return_registers)
1482        __(mflr loc_pc)
1483        __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
1484        __(ldr(save7,macptr.address(arg_y)))
1485        __(mr save0,rcontext)   /* or address globals.  */
1486        __(extract_typecode(imm0,arg_z))
1487        __(cmpri(cr7,imm0,subtag_macptr))
1488        __(ldr(save1,0(sp)))    /* bottom of reserved lisp frame  */
1489        __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
1490        __(zero_doublewords save2,0,lisp_frame.size)
1491        __(str(save1,lisp_frame.backlink(save2)))
1492        __(str(save2,c_frame.backlink(sp)))
1493        __(str(fn,lisp_frame.savefn(save2)))
1494        __(str(loc_pc,lisp_frame.savelr(save2)))
1495        __(str(vsp,lisp_frame.savevsp(save2)))
1496        __(mr nargs,arg_z)
1497        __(bne cr7,1f)
1498        __(ldr(nargs,macptr.address(arg_z)))
14991:
1500        __(ldr(save3,tcr.cs_area(rcontext)))
1501        __(str(save2,area.active(save3)))
1502        __(str(allocptr,tcr.save_allocptr(rcontext)))
1503        __(str(allocbase,tcr.save_allocbase(rcontext)))
1504        __(str(tsp,tcr.save_tsp(rcontext)))
1505        __(str(vsp,tcr.save_vsp(rcontext)))
1506        __(str(rzero,tcr.ffi_exception(rcontext)))
1507        __(mffs f0)
1508        __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
1509        __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
1510        __(li r4,TCR_STATE_FOREIGN)
1511        __(str(r4,tcr.valence(rcontext)))
1512        __ifdef([rTOC])
1513         __(ld rTOC,8(nargs))
1514         __(ld nargs,0(nargs))
1515        __else
1516         __(li rcontext,0)
1517        __endif
1518        __(mtctr nargs)
1519        __(ldr(r3,c_frame.param0(sp)))
1520        __(ldr(r4,c_frame.param1(sp)))
1521        __(ldr(r5,c_frame.param2(sp)))
1522        __(ldr(r6,c_frame.param3(sp)))
1523        __(ldr(r7,c_frame.param4(sp)))
1524        __(ldr(r8,c_frame.param5(sp)))
1525        __(ldr(r9,c_frame.param6(sp)))
1526        __(ldr(r10,c_frame.param7(sp)))
1527        /* Darwin is allegedly very picky about what register points */
1528        /* to the function on entry.  */
1529        __(mr r12,nargs)
1530        __(bctrl)
1531        __(str(r3,0*node_size(save7)))       
1532        __(str(r4,1*node_size(save7)))       
1533        __(str(r5,2*node_size(save7)))       
1534        __(str(r6,3*node_size(save7)))       
1535        __(str(r7,4*node_size(save7)))       
1536        __(str(r8,5*node_size(save7)))       
1537        __(str(r9,6*node_size(save7)))       
1538        __(str(r10,7*node_size(save7)))
1539        __(stfd f1,((8*node_size)+(0*8))(save7))
1540        __(stfd f2,((8*node_size)+(1*8))(save7))
1541        __(stfd f3,((8*node_size)+(2*8))(save7))
1542        __(stfd f4,((8*node_size)+(3*8))(save7))
1543        __(stfd f5,((8*node_size)+(4*8))(save7))
1544        __(stfd f6,((8*node_size)+(5*8))(save7))
1545        __(stfd f7,((8*node_size)+(6*8))(save7))
1546        __(stfd f8,((8*node_size)+(7*8))(save7))
1547        __(stfd f9,((8*node_size)+(8*8))(save7))
1548        __(stfd f10,((8*node_size)+(9*8))(save7))
1549        __(stfd f11,((8*node_size)+(10*8))(save7))
1550        __(stfd f12,((8*node_size)+(11*8))(save7))
1551        __(stfd f13,((8*node_size)+(12*8))(save7))
1552        __(b FF_call_return_common)
1553
1554               
1555/* Signal an error synchronously, via %ERR-DISP.  */
1556/* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
1557/* on the C runtime stderr.  */
1558
1559_spentry(ksignalerr)
1560        __(li fname,nrs.errdisp)
1561        __(jump_fname)
1562       
1563/* As in the heap-consed cases, only stack-cons the &rest arg  */
1564_spentry(stack_rest_arg)
1565        __(li imm0,0)
1566        __(vpush_argregs())
1567        __(b _SPstack_cons_rest_arg)
1568
1569       
1570_spentry(req_stack_rest_arg)
1571        __(vpush_argregs())
1572        __(b _SPstack_cons_rest_arg)
1573       
1574_spentry(stack_cons_rest_arg)
1575        __(sub imm1,nargs,imm0)
1576        __(cmpri(cr0,imm1,0))
1577        __(cmpri(cr1,imm1,(4096-dnode_size)/2))
1578        __(li arg_z,nil_value)
1579        __(ble cr0,2f)          /* always temp-push something.  */
1580        __(bge cr1,3f)
1581        __(add imm1,imm1,imm1)
1582        __(dnode_align(imm2,imm1,tsp_frame.fixed_overhead))
1583        __(TSP_Alloc_Var_Boxed(imm2,imm3))
1584        __(la imm0,tsp_frame.data_offset+fulltag_cons(tsp))
15851:
1586        __(cmpri(cr0,imm1,cons.size))   /* last time through ?  */
1587        __(subi imm1,imm1,cons.size)
1588        __(vpop(arg_x))
1589        __(_rplacd(imm0,arg_z))
1590        __(_rplaca(imm0,arg_x))
1591        __(mr arg_z,imm0)
1592        __(la imm0,cons.size(imm0))
1593        __(bne cr0,1b)
1594        __(vpush(arg_z))
1595        __(blr)
15962:
1597        __(TSP_Alloc_Fixed_Unboxed(0))
1598        __(vpush(arg_z))
1599        __(blr)
16003:
1601        __(TSP_Alloc_Fixed_Unboxed(0))
1602        __(b _SPheap_cons_rest_arg)
1603
1604
1605_spentry(poweropen_callbackX)       
1606        /* Save C argument registers  */
1607        __(str(r3,c_frame.param0(sp)))
1608        __(str(r4,c_frame.param1(sp)))
1609        __(str(r5,c_frame.param2(sp)))
1610        __(str(r6,c_frame.param3(sp)))
1611        __(str(r7,c_frame.param4(sp)))
1612        __(str(r8,c_frame.param5(sp)))
1613        __(str(r9,c_frame.param6(sp)))
1614        __(str(r10,c_frame.param7(sp)))
1615        __(mflr imm3)
1616        __(str(imm3,c_frame.savelr(sp)))
1617        __(mfcr imm0)
1618        __(str(imm0,c_frame.crsave(sp)))
1619
1620        /* Save the non-volatile registers on the sp stack  */
1621        /* This is a non-standard stack frame, but noone will ever see it,  */
1622        /* so it doesn't matter. It will look like more of the stack  */
1623        /* frame pushed below.  */
1624        __(stru(sp,-(stack_align(c_reg_save.size))(sp)))
1625        __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
1626        __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
1627        __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
1628        __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
1629        __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
1630        __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
1631        __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
1632        __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
1633        __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
1634        __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
1635        __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
1636        __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
1637        __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
1638        __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
1639        __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
1640        __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
1641        __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
1642        __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
1643        __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
1644        __(stfd f1,c_reg_save.save_fprs+(0*8)(sp))
1645        __(stfd f2,c_reg_save.save_fprs+(1*8)(sp))
1646        __(stfd f3,c_reg_save.save_fprs+(2*8)(sp))
1647        __(stfd f4,c_reg_save.save_fprs+(3*8)(sp))
1648        __(stfd f5,c_reg_save.save_fprs+(4*8)(sp))
1649        __(stfd f6,c_reg_save.save_fprs+(5*8)(sp))
1650        __(stfd f7,c_reg_save.save_fprs+(6*8)(sp))
1651        __(stfd f8,c_reg_save.save_fprs+(7*8)(sp))
1652        __(stfd f9,c_reg_save.save_fprs+(8*8)(sp))
1653        __(stfd f10,c_reg_save.save_fprs+(9*8)(sp))
1654        __(stfd f11,c_reg_save.save_fprs+(10*8)(sp))
1655        __(stfd f12,c_reg_save.save_fprs+(11*8)(sp))
1656        __(stfd f13,c_reg_save.save_fprs+(12*8)(sp))
1657        __(check_stack_alignment(r0))
1658        __(mffs f0)
1659        __(stfd f0,c_reg_save.save_fp_zero(sp))
1660        __(ldr(r31,c_reg_save.save_fp_zero+4(sp)))      /* recover FPSCR image  */
1661        __(str(r31,c_reg_save.save_fpscr(sp)))
1662        __(lwi(r30,0x43300000))
1663        __(lwi(r31,0x80000000))
1664        __(stw r30,c_reg_save.save_fp_zero(sp))
1665        __(stw r31,c_reg_save.save_fp_zero+4(sp))
1666        __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
1667        __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
1668        __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
1669        __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
1670
1671/* Restore rest of Lisp context.  */
1672/* Could spread out the memory references here to gain a little speed  */
1673
1674        __(li loc_pc,0)
1675        __(li fn,0)                     /* subprim, not a lisp function  */
1676        __(li temp3,0)
1677        __(li temp2,0)
1678        __(li temp1,0)
1679        __(li temp0,0)
1680        __(li arg_x,0)
1681        __(box_fixnum(arg_y,r11))       /* callback-index  */
1682        __(la arg_z,c_reg_save.save_fprs(sp))
1683        __(str(arg_z,stack_align(c_reg_save.size)+c_frame.unused(sp)))
1684        __(la arg_z,stack_align(c_reg_save.size)+c_frame.param0(sp))    /* parameters (tagged as a fixnum)  */
1685
1686        /* Recover lisp thread context. Have to call C code to do so.  */
1687        __(ref_global(r12,get_tcr))
1688        __(mtctr r12)
1689        __(li r3,1)
1690        __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
1691        __(bctrl)
1692        __(la rcontext,TCR_BIAS(r3))
1693        /* re-establish lisp exception handling  */
1694        __(ref_global(r12,lisp_return_hook))
1695        __(mtctr r12)
1696        __(bctrl)
1697        __(la sp,(stack_align(c_frame.minsiz))(sp))
1698
1699        __(ldr(vsp,tcr.save_vsp(rcontext)))
1700        __(ldr(tsp,tcr.save_tsp(rcontext)))             
1701        __(li rzero,0)
1702        __(mtxer rzero) /* lisp wants the overflow bit clear  */
1703        __(mtctr rzero)
1704        __(li imm0,TCR_STATE_LISP)
1705        __(li save0,0)
1706        __(li save1,0)
1707        __(li save2,0)
1708        __(li save3,0)
1709        __(li save4,0)
1710        __(li save5,0)
1711        __(li save6,0)
1712        __(li save7,0)
1713        __(lfd f0,tcr.lisp_fpscr(rcontext))
1714        __(mtfsf 0xff,f0)
1715        __(li allocptr,0)
1716        __(li allocbase,0)
1717        __(str(imm0,tcr.valence(rcontext)))
1718        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
1719        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
1720       
1721        __(restore_saveregs(vsp))
1722        /* load nargs and callback to the lisp  */
1723        __(set_nargs(2))
1724        __(ldr(imm2,tcr.cs_area(rcontext)))
1725        __(ldr(imm4,area.active(imm2)))
1726        __(stru(imm4,-lisp_frame.size(sp)))
1727        __(str(imm3,lisp_frame.savelr(sp)))
1728        __(li fname,nrs.callbacks)      /* %pascal-functions%  */
1729        __(call_fname)
1730        __(ldr(imm2,lisp_frame.backlink(sp)))
1731        __(ldr(imm3,tcr.cs_area(rcontext)))
1732        __(str(imm2,area.active(imm3)))
1733        __(discard_lisp_frame())
1734        /* save_vsp will be restored from ff_call's stack frame, but  */
1735        /* I included it here for consistency.  */
1736        /* save_tsp is set below after we exit Lisp context.  */
1737        __(str(allocptr,tcr.save_allocptr(rcontext)))
1738        __(str(allocbase,tcr.save_allocbase(rcontext)))
1739        __(str(vsp,tcr.save_vsp(rcontext)))
1740        __(str(tsp,tcr.save_tsp(rcontext)))
1741
1742        __(li imm1,TCR_STATE_FOREIGN)
1743        __(str(imm1,tcr.valence(rcontext)))
1744        __(mr r3,rcontext)
1745        __(ldr(r4,tcr.foreign_exception_status(rcontext)))
1746        __(cmpri(r4,0))
1747        /* Restore the non-volatile registers & fpscr  */
1748        __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
1749        __(ldr(r31,c_reg_save.save_fpscr(sp)))
1750        __(str(r31,c_reg_save.save_fp_zero+4(sp)))
1751        __(lfd f0,c_reg_save.save_fp_zero(sp))
1752        __(mtfsf 0xff,f0)
1753        __(ldr(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
1754        __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
1755        __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
1756        __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
1757        __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
1758        __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
1759        __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
1760        __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
1761        __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
1762        __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
1763        __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
1764        __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
1765        __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
1766        __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
1767        __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
1768        __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
1769        __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
1770        __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
1771        __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
1772        __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
1773        __(beq 9f)
1774        __(ref_global(r12,lisp_exit_hook))
1775        __(mtctr r12)
1776        __(bctrl)
17779:
1778        __(lfd f1,c_reg_save.save_fprs+(0*8)(sp))
1779        __(lfd f2,c_reg_save.save_fprs+(1*8)(sp))
1780        __(lfd f3,c_reg_save.save_fprs+(2*8)(sp))
1781        __(lfd f4,c_reg_save.save_fprs+(3*8)(sp))
1782        __(lfd f5,c_reg_save.save_fprs+(4*8)(sp))
1783        __(lfd f6,c_reg_save.save_fprs+(5*8)(sp))
1784        __(lfd f7,c_reg_save.save_fprs+(6*8)(sp))
1785        __(lfd f8,c_reg_save.save_fprs+(7*8)(sp))
1786        __(lfd f9,c_reg_save.save_fprs+(8*8)(sp))
1787        __(lfd f10,c_reg_save.save_fprs+(9*8)(sp))
1788        __(lfd f11,c_reg_save.save_fprs+(10*8)(sp))
1789        __(lfd f12,c_reg_save.save_fprs+(11*8)(sp))
1790        __(lfd f13,c_reg_save.save_fprs+(12*8)(sp))
1791        __(ldr(sp,0(sp)))
1792        __(ldr(r3,c_frame.param0(sp)))
1793        __(ldr(r4,c_frame.param1(sp)))
1794        __(ldr(r5,c_frame.param2(sp)))
1795        __(ldr(r6,c_frame.param3(sp)))
1796        __(ldr(r7,c_frame.param4(sp)))
1797        __(ldr(r8,c_frame.param5(sp)))
1798        __(ldr(r9,c_frame.param6(sp)))
1799        __(ldr(r10,c_frame.param7(sp)))
1800        __(ldr(r11,c_frame.savelr(sp)))
1801        __(mtlr r11)
1802        __(ldr(r12,c_frame.crsave(sp)))
1803        __(mtcr r12)
1804        __(blr)
1805       
1806/* Prepend all but the first two (closure code, fn) and last two  */
1807/* (function name, lfbits) elements of nfn to the "arglist".  */
1808/* Doing things this way (the same way that 68K MCL does) lets  */
1809/* functions which take "inherited arguments" work consistently  */
1810/* even in cases where no closure object is created.  */
1811_spentry(call_closure)       
1812        __(cmpri(cr0,nargs,nargregs<<fixnumshift))
1813        __(cmpri(cr1,nargs,fixnum_one))
1814        __(vector_length(imm0,nfn,imm0))
1815        __(subi imm0,imm0,4<<fixnumshift) /* imm0 = inherited arg count  */
1816        __(li imm1,misc_data_offset+(2<<fixnumshift)) /* point to 1st arg  */
1817        __(li imm4,nil_value)
1818        __(ble+ cr0,local_label(no_insert))
1819        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
1820        /* of NILs, copy those arguments that have already been vpushed from  */
1821        /* the old TOS to the new, then insert all of the inerited args  */
1822        /* and go to the function.  */
1823        __(li imm2,0)
1824local_label(push_nil_loop):
1825        __(addi imm2,imm2,fixnum_one)
1826        __(cmpr(cr2,imm2,imm0))
1827        __(vpush(imm4))
1828        __(bne cr2,local_label(push_nil_loop))
1829
1830        __(mr imm3,vsp)
1831        __(add imm4,vsp,imm0)
1832        __(subi imm2,nargs,nargregs<<fixnumshift)
1833local_label(copy_already_loop):
1834        __(cmpri(cr2,imm2,fixnum_one))
1835        __(subi imm2,imm2,fixnum_one)
1836        __(ldr(fname,0(imm4)))
1837        __(addi imm4,imm4,fixnum_one)
1838        __(str(fname,0(imm3)))
1839        __(addi imm3,imm3,fixnum_one)
1840        __(bne cr2,local_label(copy_already_loop))
1841
1842local_label(insert_loop):
1843        __(cmpri(cr2,imm0,fixnum_one))
1844        __(ldrx(fname,nfn,imm1))
1845        __(addi imm1,imm1,fixnum_one)
1846        __(addi nargs,nargs,fixnum_one)
1847        __(subi imm0,imm0,fixnum_one)
1848        __(push(fname,imm4))
1849        __(bne cr2,local_label(insert_loop))
1850        __(b local_label(go))
1851local_label(no_insert):
1852        /* nargregs or fewer args were already vpushed.  */
1853        /* if exactly nargregs, vpush remaining inherited vars.  */
1854        __(add imm2,imm1,imm0)
1855        __(bne cr0,local_label(set_regs))
1856local_label(vpush_remaining):
1857        __(cmpri(cr2,imm0,fixnum_one))
1858        __(ldrx(fname,nfn,imm1))
1859        __(addi imm1,imm1,fixnum_one)
1860        __(vpush(fname))
1861        __(subi imm0,imm0,fixnum_one)
1862        __(addi nargs,nargs,fixnum_one)
1863        __(bne cr2,local_label(vpush_remaining))
1864        __(b local_label(go))
1865local_label(set_regs):
1866        /* if nargs was > 1 (and we know that it was < 3), it must have  */
1867        /* been 2.  Set arg_x, then vpush the remaining args.  */
1868        __(ble cr1,local_label(set_y_z))
1869local_label(set_arg_x):
1870        __(subi imm0,imm0,fixnum_one)
1871        __(cmpri(cr0,imm0,0))
1872        __(subi imm2,imm2,fixnum_one)
1873        __(ldrx(arg_x,nfn,imm2))
1874        __(addi nargs,nargs,fixnum_one)
1875        __(bne cr0,local_label(vpush_remaining))
1876        __(b local_label(go))
1877        /* Maybe set arg_y or arg_z, preceding args  */
1878local_label(set_y_z):
1879        __(bne cr1,local_label(set_arg_z))
1880        /* Set arg_y, maybe arg_x, preceding args  */
1881local_label(set_arg_y):
1882        __(subi imm0,imm0,fixnum_one)
1883        __(cmpri(cr0,imm0,0))
1884        __(subi imm2,imm2,fixnum_one)
1885        __(ldrx(arg_y,nfn,imm2))
1886        __(addi nargs,nargs,fixnum_one)
1887        __(bne cr0,local_label(set_arg_x))
1888        __(b local_label(go))
1889local_label(set_arg_z):
1890        __(subi imm0,imm0,fixnum_one)
1891        __(cmpri(cr0,imm0,0))
1892        __(subi imm2,imm2,fixnum_one)
1893        __(ldrx(arg_z,nfn,imm2))
1894        __(addi nargs,nargs,fixnum_one)
1895        __(bne cr0,local_label(set_arg_y))
1896
1897local_label(go):
1898        __(vrefr(nfn,nfn,1))
1899        __(ldr(loc_pc,_function.codevector(nfn)))
1900        __(mtctr loc_pc)
1901        __(bctr)
1902       
1903/* This  treats anything that's either */
1904/* #+ppc32 (signed-byte 32), (unsigned-byte 32) */
1905/* #+ppc64 (signed-byte 64), (unsigned-byte 64) */
1906/* as if it denoted a "natural-sized" value.  */
1907/* Argument in arg_z, result in imm0.  May use temp0.  */
1908_spentry(getxlong)
1909        __ifdef([PPC64])
1910        __else
1911        __(extract_typecode(imm0,arg_z))
1912        __(cmpri(cr0,imm0,tag_fixnum))
1913        __(cmpri(cr1,imm0,subtag_bignum))
1914        __(unbox_fixnum(imm0,arg_z))
1915        __(beqlr cr0)
1916        __(mr temp0,arg_z)
1917        __(bne- cr1,local_label(error))
1918        __(getvheader(imm0,temp0))
1919        __(cmpri(cr1,imm0,one_digit_bignum_header))
1920        __(cmpri(cr7,imm0,two_digit_bignum_header))
1921        __(beq cr1,local_label(big1))
1922        __(beq cr7,local_label(big2))
1923local_label(error):
1924        __(uuo_interr(error_object_not_integer,arg_z)) /* not quite right but what 68K MCL said  */
1925
1926
1927
1928local_label(big2):
1929        __(vrefr(imm0,temp0,1)) /* sign digit must be 0  */
1930        __(cmpri(imm0,0))
1931        __(bne local_label(error))
1932local_label(big1):
1933        __(vrefr(imm0,temp0,0))
1934        __(blr)
1935
1936
1937        __endif
1938               
1939/* Everything up to the last arg has been vpushed, nargs is set to  */
1940/* the (boxed) count of things already pushed.  */
1941/* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
1942/* function call (this may require vpopping a few things.)  */
1943/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1944_spentry(spreadargz)
1945        __ifdef([PPC64])
1946         __(extract_fulltag(imm1,arg_z))
1947         __(cmpri(cr1,imm1,fulltag_cons))
1948        __else
1949         __(extract_lisptag(imm1,arg_z))
1950         __(cmpri(cr1,imm1,tag_list))
1951        __endif
1952        __(cmpri(cr0,arg_z,nil_value))
1953        __(li imm0,0)
1954        __(mr arg_y,arg_z)              /*  save in case of error  */
1955        __(beq cr0,2f)
19561:
1957        __(bne- cr1,3f)
1958        __(_car(arg_x,arg_z))
1959        __(_cdr(arg_z,arg_z))
1960        __(cmpri(cr0,arg_z,nil_value))
1961        __ifdef([PPC64])
1962         __(extract_fulltag(imm1,arg_z))
1963         __(cmpri(cr1,imm1,fulltag_cons))
1964        __else
1965         __(extract_lisptag(imm1,arg_z))
1966         __(cmpri(cr1,imm1,tag_list))
1967        __endif
1968        __(vpush(arg_x))
1969        __(addi imm0,imm0,fixnum_one)
1970        __(bne cr0,1b)
19712:
1972        __(add. nargs,nargs,imm0)
1973        __(cmpri(cr2,nargs,2<<fixnumshift))
1974        __(beqlr- cr0)
1975        __(vpop(arg_z))
1976        __(bltlr cr2)
1977        __(vpop(arg_y))
1978        __(beqlr cr2)
1979        __(vpop(arg_x))
1980        __(blr)
1981        /*  Discard whatever's been vpushed already, complain.  */
19823:     
1983        __(add vsp,vsp,imm0)
1984        __(mr arg_z,arg_y)              /* recover original arg_z  */
1985        __(li arg_y,XNOSPREAD)
1986        __(set_nargs(2))
1987        __(b _SPksignalerr)
1988       
1989/* Tail-recursively funcall temp0.  */
1990/* Pretty much the same as the tcallsym* cases above.  */
1991_spentry(tfuncallgen)
1992        __(cmpri(cr0,nargs,nargregs<<fixnumshift))
1993        __(ldr(loc_pc,lisp_frame.savelr(sp)))
1994        __(ldr(fn,lisp_frame.savefn(sp)))
1995        __(mtlr loc_pc)
1996        __(ble cr0,2f)
1997        __(ldr(imm0,lisp_frame.savevsp(sp)))
1998        __(discard_lisp_frame())
1999        /* can use nfn (= temp2) as a temporary  */
2000        __(subi imm1,nargs,nargregs<<fixnumshift)
2001        __(add imm1,imm1,vsp)
20021:
2003        __(ldru(temp2,-node_size(imm1)))
2004        __(cmpr(cr0,imm1,vsp))
2005        __(push(temp2,imm0))
2006        __(bne cr0,1b)
2007        __(mr vsp,imm0)
2008        __(do_funcall())
20092:
2010        __(ldr(vsp,lisp_frame.savevsp(sp)))
2011        __(discard_lisp_frame())
2012        __(do_funcall())
2013
2014
2015/* Some args were vpushed.  Slide them down to the base of  */
2016/* the current frame, then do funcall.  */
2017_spentry(tfuncallslide)
2018        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2019        __(ldr(fn,lisp_frame.savefn(sp)))
2020        __(ldr(imm0,lisp_frame.savevsp(sp)))
2021        __(discard_lisp_frame())
2022        /* can use nfn (= temp2) as a temporary  */
2023        __(subi imm1,nargs,nargregs<<fixnumshift)
2024        __(add imm1,imm1,vsp)
2025        __(mtlr loc_pc)
20261:
2027        __(ldru(temp2,-node_size(imm1)))
2028        __(cmpr(cr0,imm1,vsp))
2029        __(push(temp2,imm0))
2030        __(bne cr0,1b)
2031        __(mr vsp,imm0)
2032        __(do_funcall())
2033
2034/* No args were vpushed; recover saved context & do funcall  */
2035_spentry(tfuncallvsp)
2036        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2037        __(ldr(fn,lisp_frame.savefn(sp)))
2038        __(ldr(vsp,lisp_frame.savevsp(sp)))
2039        __(mtlr loc_pc)
2040        __(discard_lisp_frame())
2041        __(do_funcall())
2042       
2043/* Tail-recursively call the (known symbol) in fname.  */
2044/* In the general case, we don't know if any args were  */
2045/* vpushed or not.  If so, we have to "slide" them down  */
2046/* to the base of the frame.  If not, we can just restore  */
2047/* vsp, lr, fn from the saved lisp frame on the control stack.  */
2048_spentry(tcallsymgen)
2049        __(cmpri(cr0,nargs,nargregs<<fixnumshift))
2050        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2051        __(ldr(fn,lisp_frame.savefn(sp)))
2052        __(mtlr loc_pc)
2053        __(ble cr0,2f)
2054
2055        __(ldr(imm0,lisp_frame.savevsp(sp)))
2056        __(discard_lisp_frame())
2057        /* can use nfn (= temp2) as a temporary  */
2058        __(subi imm1,nargs,nargregs<<fixnumshift)
2059        __(add imm1,imm1,vsp)
20601:
2061        __(ldru(temp2,-node_size(imm1)))
2062        __(cmpr(cr0,imm1,vsp))
2063        __(push(temp2,imm0))
2064        __(bne cr0,1b)
2065        __(mr vsp,imm0)
2066        __(jump_fname)
2067       
20682:             
2069        __(ldr(vsp,lisp_frame.savevsp(sp)))
2070        __(discard_lisp_frame())
2071        __(jump_fname)
2072       
2073       
2074/* Some args were vpushed.  Slide them down to the base of  */
2075/* the current frame, then do funcall.  */
2076_spentry(tcallsymslide)
2077        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2078        __(ldr(fn,lisp_frame.savefn(sp)))
2079        __(ldr(imm0,lisp_frame.savevsp(sp)))
2080        __(discard_lisp_frame())
2081        __(mtlr loc_pc)
2082        /* can use nfn (= temp2) as a temporary  */
2083        __(subi imm1,nargs,nargregs<<fixnumshift)
2084        __(add imm1,imm1,vsp)
20851:
2086        __(ldru(temp2,-node_size(imm1)))
2087        __(cmpr(cr0,imm1,vsp))
2088        __(push(temp2,imm0))
2089        __(bne cr0,1b)
2090        __(mr vsp,imm0)
2091        __(jump_fname)
2092
2093/* No args were vpushed; recover saved context & call symbol  */
2094_spentry(tcallsymvsp)
2095        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2096        __(ldr(fn,lisp_frame.savefn(sp)))
2097        __(ldr(vsp,lisp_frame.savevsp(sp)))
2098        __(discard_lisp_frame())
2099        __(mtlr loc_pc)
2100        __(jump_fname)
2101       
2102/* Tail-recursively call the function in nfn.  */
2103/* Pretty much the same as the tcallsym* cases above.  */
2104_spentry(tcallnfngen)
2105        __(cmpri(cr0,nargs,nargregs<<fixnumshift))
2106        __(ble cr0,_SPtcallnfnvsp)
2107        __(b _SPtcallnfnslide)
2108
2109/* Some args were vpushed.  Slide them down to the base of  */
2110/* the current frame, then do funcall.  */
2111_spentry(tcallnfnslide)
2112        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2113        __(ldr(fn,lisp_frame.savefn(sp)))
2114        __(ldr(imm0,lisp_frame.savevsp(sp)))
2115        __(discard_lisp_frame())
2116        __(mtlr loc_pc)
2117        /* Since we have a known function, can use fname as a temporary.  */
2118        __(subi imm1,nargs,nargregs<<fixnumshift)
2119        __(add imm1,imm1,vsp)
21201:
2121        __(ldru(fname,-node_size(imm1)))
2122        __(cmpr(cr0,imm1,vsp))
2123        __(push(fname,imm0))
2124        __(bne cr0,1b)
2125        __(mr vsp,imm0)
2126        __(jump_nfn())
2127       
2128_spentry(tcallnfnvsp)
2129        __(ldr(loc_pc,lisp_frame.savelr(sp)))
2130        __(ldr(fn,lisp_frame.savefn(sp)))
2131        __(ldr(vsp,lisp_frame.savevsp(sp)))
2132        __(discard_lisp_frame())
2133        __(mtlr loc_pc)
2134        __(jump_nfn())
2135       
2136/* Reference index arg_z of a misc-tagged object (arg_y).  */
2137/* Note that this conses in some cases.  Return a properly-tagged  */
2138/* lisp object in arg_z.  Do type and bounds-checking.  */
2139       
2140_spentry(misc_ref)
2141        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
2142        __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
2143        __(vector_length(imm0,arg_y,imm1))
2144        __(trlge(arg_z,imm0))
2145        __(extract_lowbyte(imm1,imm1))  /* imm1 = subtag  */
2146       
2147local_label(misc_ref_common):   
2148        __ifdef([PPC64])
2149         __(slwi imm1,imm1,3)
2150         __(li imm0,LO(local_label(misc_ref_jmp)))
2151         __(addis imm0,imm0,HA(local_label(misc_ref_jmp)))
2152         __(ldx imm0,imm0,imm1)
2153         __(mtctr imm0)
2154         __(bctr)
2155
2156local_label(misc_ref_jmp):             
2157        /* 00-0f  */
2158         .quad local_label(misc_ref_invalid) /* 00 even_fixnum  */
2159         .quad local_label(misc_ref_invalid) /* 01 imm_0  */
2160         .quad local_label(misc_ref_invalid) /* 02 immheader_0  */
2161         .quad local_label(misc_ref_node) /* 03 function  */
2162         .quad local_label(misc_ref_invalid) /* 04 cons  */
2163         .quad local_label(misc_ref_invalid) /* 05 imm_1  */
2164         .quad local_label(misc_ref_invalid) /* 06 immheader_1  */
2165         .quad local_label(misc_ref_node) /* 07 catch_frame  */
2166         .quad local_label(misc_ref_invalid) /* 08 odd_fixnum  */
2167         .quad local_label(misc_ref_invalid) /* 09 imm_2  */
2168         .quad local_label(misc_ref_u32) /* 0a code_vector  */
2169         .quad local_label(misc_ref_node) /* 0b slot_vector  */
2170         .quad local_label(misc_ref_invalid) /* 0c misc  */
2171         .quad local_label(misc_ref_invalid) /* 0d imm3  */
2172         .quad local_label(misc_ref_invalid) /* 0e immheader_3  */
2173         .quad local_label(misc_ref_node) /* 0f ratio  */
2174        /* 10-1f  */
2175         .quad local_label(misc_ref_invalid) /* 10 even_fixnum  */
2176         .quad local_label(misc_ref_invalid) /* 11 imm_0  */
2177         .quad local_label(misc_ref_invalid) /* 12 immheader_0  */
2178         .quad local_label(misc_ref_node) /* 13 symbol_0  */
2179         .quad local_label(misc_ref_invalid) /* 14 cons  */
2180         .quad local_label(misc_ref_invalid) /* 15 imm_1  */
2181         .quad local_label(misc_ref_invalid) /* 16 immheader_1  */
2182         .quad local_label(misc_ref_node) /* 17 lisp_tread  */
2183         .quad local_label(misc_ref_invalid) /* 18 odd_fixnum  */
2184         .quad local_label(misc_ref_invalid) /* 19 imm_2  */
2185         .quad local_label(misc_ref_u32) /* 1a xcode_vector  */
2186         .quad local_label(misc_ref_node) /* 1b instance  */
2187         .quad local_label(misc_ref_invalid) /* 1c misc  */
2188         .quad local_label(misc_ref_invalid) /* 1d imm3  */
2189         .quad local_label(misc_ref_u64) /* 1e macptr  */
2190         .quad local_label(misc_ref_node) /* 1f complex  */
2191        /* 20-2f  */
2192         .quad local_label(misc_ref_invalid) /* 20 even_fixnum  */
2193         .quad local_label(misc_ref_invalid) /* 21 imm_0  */
2194         .quad local_label(misc_ref_invalid) /* 22 immheader_0  */
2195         .quad local_label(misc_ref_invalid) /* 23 nodeheader_0  */
2196         .quad local_label(misc_ref_invalid) /* 24 cons  */
2197         .quad local_label(misc_ref_invalid) /* 25 imm_1  */
2198         .quad local_label(misc_ref_invalid) /* 26 immheader_1  */
2199         .quad local_label(misc_ref_node) /* 27 lock  */
2200         .quad local_label(misc_ref_invalid) /* 28 odd_fixnum  */
2201         .quad local_label(misc_ref_invalid) /* 29 imm_2  */
2202         .quad local_label(misc_ref_u32) /* 2a bignum  */
2203         .quad local_label(misc_ref_node) /* 2b struct  */
2204         .quad local_label(misc_ref_invalid) /* 2c misc  */
2205         .quad local_label(misc_ref_invalid) /* 2d imm3  */
2206         .quad local_label(misc_ref_u64) /* 2e dead_macptr  */
2207         .quad local_label(misc_ref_invalid) /* 2f nodeheader_3  */
2208        /* 30-3f  */
2209         .quad local_label(misc_ref_invalid) /* 30 even_fixnum  */
2210         .quad local_label(misc_ref_invalid) /* 31 imm_0  */
2211         .quad local_label(misc_ref_invalid) /* 32 immheader_0  */
2212         .quad local_label(misc_ref_invalid) /* 33 nodeheader_0  */
2213         .quad local_label(misc_ref_invalid) /* 34 cons  */
2214         .quad local_label(misc_ref_invalid) /* 35 imm_1  */
2215         .quad local_label(misc_ref_invalid) /* 36 immheader_1  */
2216         .quad local_label(misc_ref_node) /* 37 hash_vector  */
2217         .quad local_label(misc_ref_invalid) /* 38 odd_fixnum  */
2218         .quad local_label(misc_ref_invalid) /* 39 imm_2  */
2219         .quad local_label(misc_ref_u32) /* 3a double_float  */
2220         .quad local_label(misc_ref_node) /* 3b istruct  */
2221         .quad local_label(misc_ref_invalid) /* 3c misc  */
2222         .quad local_label(misc_ref_invalid) /* 3d imm3  */
2223         .quad local_label(misc_ref_invalid) /* 3e immheader_3  */
2224         .quad local_label(misc_ref_invalid) /* 3f nodeheader_3  */
2225        /* 40-4f  */
2226         .quad local_label(misc_ref_invalid) /* 40 even_fixnum  */
2227         .quad local_label(misc_ref_invalid) /* 41 imm_0  */
2228         .quad local_label(misc_ref_invalid) /* 42 immheader_0  */
2229         .quad local_label(misc_ref_invalid) /* 43 nodeheader_0  */
2230         .quad local_label(misc_ref_invalid) /* 44 cons  */
2231         .quad local_label(misc_ref_invalid) /* 45 imm_1  */
2232         .quad local_label(misc_ref_invalid) /* 46 immheader_1  */
2233         .quad local_label(misc_ref_node) /* 47 pool  */
2234         .quad local_label(misc_ref_invalid) /* 48 odd_fixnum  */
2235         .quad local_label(misc_ref_invalid) /* 49 imm_2  */
2236         .quad local_label(misc_ref_invalid) /* 4a immheader_2  */
2237         .quad local_label(misc_ref_node) /* 4b value_cell_2  */
2238         .quad local_label(misc_ref_invalid) /* 4c misc  */
2239         .quad local_label(misc_ref_invalid) /* 4d imm3  */
2240         .quad local_label(misc_ref_invalid) /* 4e immheader_3  */
2241         .quad local_label(misc_ref_invalid) /* 4f nodeheader_3  */
2242        /* 50-5f  */
2243         .quad local_label(misc_ref_invalid) /* 50 even_fixnum  */
2244         .quad local_label(misc_ref_invalid) /* 51 imm_0  */
2245         .quad local_label(misc_ref_invalid) /* 52 immheader_0  */
2246         .quad local_label(misc_ref_invalid) /* 53 nodeheader_0  */
2247         .quad local_label(misc_ref_invalid) /* 54 cons  */
2248         .quad local_label(misc_ref_invalid) /* 55 imm_1  */
2249         .quad local_label(misc_ref_invalid) /* 56 immheader_1  */
2250         .quad local_label(misc_ref_node) /* 57 weak  */
2251         .quad local_label(misc_ref_invalid) /* 58 odd_fixnum  */
2252         .quad local_label(misc_ref_invalid) /* 59 imm_2  */
2253         .quad local_label(misc_ref_invalid) /* 5a immheader_2  */
2254         .quad local_label(misc_ref_node) /* 5b xfunction  */
2255         .quad local_label(misc_ref_invalid) /* 5c misc  */
2256         .quad local_label(misc_ref_invalid) /* 5d imm3  */
2257         .quad local_label(misc_ref_invalid) /* 5e immheader_3  */
2258         .quad local_label(misc_ref_invalid) /* 5f nodeheader_3  */
2259        /* 60-6f  */
2260         .quad local_label(misc_ref_invalid) /* 60 even_fixnum  */
2261         .quad local_label(misc_ref_invalid) /* 61 imm_0  */
2262         .quad local_label(misc_ref_invalid) /* 62 immheader_0  */
2263         .quad local_label(misc_ref_invalid) /* 63 nodeheader_0  */
2264         .quad local_label(misc_ref_invalid) /* 64 cons  */
2265         .quad local_label(misc_ref_invalid) /* 65 imm_1  */
2266         .quad local_label(misc_ref_invalid) /* 66 immheader_1  */
2267         .quad local_label(misc_ref_node) /* 67 package  */
2268         .quad local_label(misc_ref_invalid) /* 68 odd_fixnum  */
2269         .quad local_label(misc_ref_invalid) /* 69 imm_2  */
2270         .quad local_label(misc_ref_invalid) /* 6a immheader_2  */
2271         .quad local_label(misc_ref_invalid) /* 6b nodeheader_2  */
2272         .quad local_label(misc_ref_invalid) /* 6c misc  */
2273         .quad local_label(misc_ref_invalid) /* 6d imm3  */
2274         .quad local_label(misc_ref_invalid) /* 6e immheader_3  */
2275         .quad local_label(misc_ref_invalid) /* 6f nodeheader_3  */
2276        /* 70-7f  */
2277         .quad local_label(misc_ref_invalid) /* 70 even_fixnum  */
2278         .quad local_label(misc_ref_invalid) /* 71 imm_0  */
2279         .quad local_label(misc_ref_invalid) /* 72 immheader_0  */
2280         .quad local_label(misc_ref_invalid) /* 73 nodeheader_0  */
2281         .quad local_label(misc_ref_invalid) /* 74 cons  */
2282         .quad local_label(misc_ref_invalid) /* 75 imm_1  */
2283         .quad local_label(misc_ref_invalid) /* 76 immheader_1  */
2284         .quad local_label(misc_ref_invalid) /* 77 nodeheader_1  */
2285         .quad local_label(misc_ref_invalid) /* 78 odd_fixnum  */
2286         .quad local_label(misc_ref_invalid) /* 79 imm_2  */
2287         .quad local_label(misc_ref_invalid) /* 7a immheader_2  */
2288         .quad local_label(misc_ref_invalid) /* 7b nodeheader_2  */
2289         .quad local_label(misc_ref_invalid) /* 7c misc  */
2290         .quad local_label(misc_ref_invalid) /* 7d imm3  */
2291         .quad local_label(misc_ref_invalid) /* 7e immheader_3  */
2292         .quad local_label(misc_ref_invalid) /* 7f nodeheader_3  */
2293        /* 80-8f  */
2294         .quad local_label(misc_ref_invalid) /* 80 even_fixnum  */
2295         .quad local_label(misc_ref_invalid) /* 81 imm_0  */
2296         .quad local_label(misc_ref_invalid) /* 82 immheader_0  */
2297         .quad local_label(misc_ref_invalid) /* 83 nodeheader_0  */
2298         .quad local_label(misc_ref_invalid) /* 84 cons  */
2299         .quad local_label(misc_ref_invalid) /* 85 imm_1  */
2300         .quad local_label(misc_ref_invalid) /* 86 immheader_1  */
2301         .quad local_label(misc_ref_node)    /* 87 arrayH  */
2302         .quad local_label(misc_ref_invalid) /* 88 odd_fixnum  */
2303         .quad local_label(misc_ref_invalid) /* 89 imm_2  */
2304         .quad local_label(misc_ref_invalid) /* 8a immheader_2  */
2305         .quad local_label(misc_ref_node)    /* 8b vectorH  */
2306         .quad local_label(misc_ref_invalid) /* 8c misc  */
2307         .quad local_label(misc_ref_invalid) /* 8d imm3  */
2308         .quad local_label(misc_ref_invalid) /* 8e immheader_3  */
2309         .quad local_label(misc_ref_node) /* 8f simple_vector  */
2310        /* 90-9f  */
2311         .quad local_label(misc_ref_invalid) /* 90 even_fixnum  */
2312         .quad local_label(misc_ref_invalid) /* 91 imm_0  */
2313         .quad local_label(misc_ref_s8) /* 92 s8  */
2314         .quad local_label(misc_ref_invalid) /* 93 nodeheader_0  */
2315         .quad local_label(misc_ref_invalid) /* 94 cons  */
2316         .quad local_label(misc_ref_invalid) /* 95 imm_1  */
2317         .quad local_label(misc_ref_s16) /* 96 immheader_1  */
2318         .quad local_label(misc_ref_invalid) /* 97 nodeheader_1  */
2319         .quad local_label(misc_ref_invalid) /* 98 odd_fixnum  */
2320         .quad local_label(misc_ref_invalid) /* 99 imm_2  */
2321         .quad local_label(misc_ref_s32) /* 9a s32  */
2322         .quad local_label(misc_ref_invalid) /* 9b nodeheader_2  */
2323         .quad local_label(misc_ref_invalid) /* 9c misc  */
2324         .quad local_label(misc_ref_invalid) /* 9d imm3  */
2325         .quad local_label(misc_ref_s64) /* 9e s64  */
2326         .quad local_label(misc_ref_invalid) /* 9f nodeheader_3  */
2327        /* a0-af  */
2328         .quad local_label(misc_ref_invalid) /* a0 even_fixnum  */
2329         .quad local_label(misc_ref_invalid) /* a1 imm_0  */
2330         .quad local_label(misc_ref_u8) /* a2 u8  */
2331         .quad local_label(misc_ref_invalid) /* a3 nodeheader_0  */
2332         .quad local_label(misc_ref_invalid) /* a4 cons  */
2333         .quad local_label(misc_ref_invalid) /* a5 imm_1  */
2334         .quad local_label(misc_ref_u16) /* a6 u16  */
2335         .quad local_label(misc_ref_invalid) /* a7 nodeheader_1  */
2336         .quad local_label(misc_ref_invalid) /* a8 odd_fixnum  */
2337         .quad local_label(misc_ref_invalid) /* a9 imm_2  */
2338         .quad local_label(misc_ref_u32) /* aa u32  */
2339         .quad local_label(misc_ref_invalid) /* ab nodeheader_2  */
2340         .quad local_label(misc_ref_invalid) /* ac misc  */
2341         .quad local_label(misc_ref_invalid) /* ad imm3  */
2342         .quad local_label(misc_ref_u64) /* ae u64  */
2343         .quad local_label(misc_ref_invalid) /* af nodeheader_3  */
2344        /* b0-bf  */
2345         .quad local_label(misc_ref_invalid) /* b0 even_fixnum  */
2346         .quad local_label(misc_ref_invalid) /* b1 imm_0  */
2347         .quad local_label(misc_ref_invalid) /* b2 immheader_0  */
2348         .quad local_label(misc_ref_invalid) /* b3 nodeheader_0  */
2349         .quad local_label(misc_ref_invalid) /* b4 cons  */
2350         .quad local_label(misc_ref_invalid) /* b5 imm_1  */
2351         .quad local_label(misc_ref_invalid) /* b6 immheader_1  */
2352         .quad local_label(misc_ref_invalid) /* b7 nodeheader_1  */
2353         .quad local_label(misc_ref_invalid) /* b8 odd_fixnum  */
2354         .quad local_label(misc_ref_invalid) /* b9 imm_2  */
2355         .quad local_label(misc_ref_single_float_vector) /* ba sf vector  */
2356         .quad local_label(misc_ref_invalid) /* bb nodeheader_2  */
2357         .quad local_label(misc_ref_invalid) /* bc misc  */
2358         .quad local_label(misc_ref_invalid) /* bd imm3  */
2359         .quad local_label(misc_ref_fixnum_vector) /* be fixnum_vector  */
2360         .quad local_label(misc_ref_invalid) /* bf nodeheader_3  */
2361        /* c0-cf  */
2362         .quad local_label(misc_ref_invalid) /* c0 even_fixnum  */
2363         .quad local_label(misc_ref_invalid) /* c1 imm_0  */
2364         .quad local_label(misc_ref_invalid) /* c2 immheader_0  */
2365         .quad local_label(misc_ref_invalid) /* c3 nodeheader_0  */
2366         .quad local_label(misc_ref_invalid) /* c4 cons  */
2367         .quad local_label(misc_ref_invalid) /* c5 imm_1  */
2368         .quad local_label(misc_ref_invalid) /* c6 immheader_1  */
2369         .quad local_label(misc_ref_invalid) /* c7 nodeheader_1  */
2370         .quad local_label(misc_ref_invalid) /* c8 odd_fixnum  */
2371         .quad local_label(misc_ref_invalid) /* c9 imm_2  */
2372         .quad local_label(misc_ref_invalid) /* ca immheader_2  */
2373         .quad local_label(misc_ref_invalid) /* cb nodeheader_2  */
2374         .quad local_label(misc_ref_invalid) /* cc misc  */
2375         .quad local_label(misc_ref_invalid) /* cd imm3  */
2376         .quad local_label(misc_ref_double_float_vector) /* ce double-float vector  */
2377         .quad local_label(misc_ref_invalid) /* cf nodeheader_3  */
2378        /* d0-df  */
2379         .quad local_label(misc_ref_invalid) /* d0 even_fixnum  */
2380         .quad local_label(misc_ref_invalid) /* d1 imm_0  */
2381         .quad local_label(misc_ref_string) /* d2 string  */
2382         .quad local_label(misc_ref_invalid) /* d3 nodeheader_0  */
2383         .quad local_label(misc_ref_invalid) /* d4 cons  */
2384         .quad local_label(misc_ref_invalid) /* d5 imm_1  */
2385         .quad local_label(misc_ref_invalid) /* d6 immheader_1  */
2386         .quad local_label(misc_ref_invalid) /* d7 nodeheader_1  */
2387         .quad local_label(misc_ref_invalid) /* d8 odd_fixnum  */
2388         .quad local_label(misc_ref_invalid) /* d9 imm_2  */
2389         .quad local_label(misc_ref_new_string) /* da new_string  */
2390         .quad local_label(misc_ref_invalid) /* db nodeheader_2  */
2391         .quad local_label(misc_ref_invalid) /* dc misc  */
2392         .quad local_label(misc_ref_invalid) /* dd imm3  */
2393         .quad local_label(misc_ref_invalid) /* de immheader_3  */
2394         .quad local_label(misc_ref_invalid) /* df nodeheader_3  */
2395        /* e0-ef  */
2396         .quad local_label(misc_ref_invalid) /* e0 even_fixnum  */
2397         .quad local_label(misc_ref_invalid) /* e1 imm_0  */
2398         .quad local_label(misc_ref_invalid) /* e2 immheader_0  */
2399         .quad local_label(misc_ref_invalid) /* e3 nodeheader_0  */
2400         .quad local_label(misc_ref_invalid) /* e4 cons  */
2401         .quad local_label(misc_ref_invalid) /* e5 imm_1  */
2402         .quad local_label(misc_ref_invalid) /* e6 immheader_1  */
2403         .quad local_label(misc_ref_invalid) /* e7 nodeheader_1  */
2404         .quad local_label(misc_ref_invalid) /* e8 odd_fixnum  */
2405         .quad local_label(misc_ref_invalid) /* e9 imm_2  */
2406         .quad local_label(misc_ref_invalid) /* ea immheader_2  */
2407         .quad local_label(misc_ref_invalid) /* eb nodeheader_2  */
2408         .quad local_label(misc_ref_invalid) /* ec misc  */
2409         .quad local_label(misc_ref_invalid) /* ed imm3  */
2410         .quad local_label(misc_ref_invalid) /* ee immheader_3  */
2411         .quad local_label(misc_ref_invalid) /* ef nodeheader_3  */
2412        /* f0-ff  */
2413         .quad local_label(misc_ref_invalid) /* f0 even_fixnum  */
2414         .quad local_label(misc_ref_invalid) /* f1 imm_0  */
2415         .quad local_label(misc_ref_invalid) /* f2 immheader_0  */
2416         .quad local_label(misc_ref_invalid) /* f3 nodeheader_0  */
2417         .quad local_label(misc_ref_invalid) /* f4 cons  */
2418         .quad local_label(misc_ref_invalid) /* f5 imm_1  */
2419         .quad local_label(misc_ref_bit_vector) /* f6 bit_vector  */
2420         .quad local_label(misc_ref_invalid) /* f7 nodeheader_1  */
2421         .quad local_label(misc_ref_invalid) /* f8 odd_fixnum  */
2422         .quad local_label(misc_ref_invalid) /* f9 imm_2  */
2423         .quad local_label(misc_ref_invalid) /* fa immheader_2  */
2424         .quad local_label(misc_ref_invalid) /* fb nodeheader_2  */
2425         .quad local_label(misc_ref_invalid) /* fc misc  */
2426         .quad local_label(misc_ref_invalid) /* fd imm3  */
2427         .quad local_label(misc_ref_invalid) /* fe immheader_3  */
2428         .quad local_label(misc_ref_invalid) /* ff nodeheader_3  */
2429       
2430         /* A node vector  */
2431local_label(misc_ref_node):       
2432         __(la imm0,misc_data_offset(arg_z))
2433         __(ldx arg_z,arg_y,imm0)
2434         __(blr)
2435local_label(misc_ref_double_float_vector):       
2436         __(la imm0,misc_data_offset(arg_z))
2437         __(ldx imm0,arg_y,imm0)
2438         __(li imm1,double_float_header)
2439         __(Misc_Alloc_Fixed(arg_z,imm1,double_float.size))
2440         __(std imm0,double_float.value(arg_z))
2441         __(blr)
2442local_label(misc_ref_s64):     
2443         __(la imm0,misc_data_offset(arg_z))
2444         __(ldx imm0,arg_y,imm0)
2445         __(b _SPmakes64)
2446local_label(misc_ref_fixnum_vector):   
2447         __(la imm0,misc_data_offset(arg_z))
2448         __(ldx imm0,arg_y,imm0)
2449         __(box_fixnum(arg_z,imm0))
2450         __(blr)
2451local_label(misc_ref_u64):     
2452         __(la imm0,misc_data_offset(arg_z))
2453         __(ldx imm0,arg_y,imm0)
2454         __(b _SPmakeu64)
2455local_label(misc_ref_new_string):       
2456         __(srdi imm0,arg_z,1)
2457         __(la imm0,misc_data_offset(imm0))
2458         __(lwzx imm0,arg_y,imm0)
2459         __(slwi imm0,imm0,charcode_shift)
2460         __(ori arg_z,imm0,subtag_character)
2461         __(blr)
2462local_label(misc_ref_s32):                     
2463         __(srdi imm0,arg_z,1)
2464         __(la imm0,misc_data_offset(imm0))
2465         __(lwax imm0,arg_y,imm0)
2466         __(box_fixnum(arg_z,imm0))
2467         __(blr)
2468local_label(misc_ref_u32):                     
2469         __(srdi imm0,arg_z,1)
2470         __(la imm0,misc_data_offset(imm0))
2471         __(lwzx imm0,arg_y,imm0)
2472         __(box_fixnum(arg_z,imm0))
2473         __(blr)
2474local_label(misc_ref_single_float_vector):             
2475         __(srdi imm0,arg_z,1)
2476         __(la imm0,misc_data_offset(imm0))
2477         __(lwzx imm0,arg_y,imm0)
2478         __(rldicr arg_z,imm0,32,31)
2479         __(ori arg_z,arg_z,subtag_single_float)
2480         __(blr)
2481local_label(misc_ref_s16):     
2482         __(srdi imm0,arg_z,2)
2483         __(la imm0,misc_data_offset(imm0))
2484         __(lhax imm0,arg_y,imm0)
2485         __(box_fixnum(arg_z,imm0))
2486         __(blr)
2487local_label(misc_ref_u16):
2488         __(srdi imm0,arg_z,2)
2489         __(la imm0,misc_data_offset(imm0))
2490         __(lhzx imm0,arg_y,imm0)
2491         __(box_fixnum(arg_z,imm0))
2492         __(blr)
2493local_label(misc_ref_s8):       
2494         __(srdi imm0,arg_z,3)
2495         __(la imm0,misc_data_offset(imm0))
2496         __(lbzx imm0,arg_y,imm0)
2497         __(extsb imm0,imm0)
2498         __(box_fixnum(arg_z,imm0))
2499         __(blr)
2500local_label(misc_ref_u8):       
2501         __(srdi imm0,arg_z,3)
2502         __(la imm0,misc_data_offset(imm0))
2503         __(lbzx imm0,arg_y,imm0)
2504         __(box_fixnum(arg_z,imm0))
2505         __(blr)
2506local_label(misc_ref_string):             
2507         __(srdi imm0,arg_z,3)
2508         __(la imm0,misc_data_offset(imm0))
2509         __(lbzx imm0,arg_y,imm0)
2510         __(sldi imm0,imm0,charcode_shift)
2511         __(ori arg_z,imm0,subtag_character)
2512         __(blr)
2513local_label(misc_ref_bit_vector):               
2514         __(extrwi imm1,arg_z,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
2515         __(la imm1,1+fixnumshift(imm1))
2516         __(srdi imm0,arg_z,5+fixnumshift)
2517         __(sldi imm0,imm0,2)
2518         __(la imm0,misc_data_offset(imm0))
2519         __(lwzx imm0,arg_y,imm0)
2520         __(rlwnm arg_z,imm0,imm1,31-fixnumshift,31-fixnumshift)
2521         __(blr)
2522local_label(misc_ref_invalid):     
2523         __(li arg_x,XBADVEC)
2524         __(set_nargs(3))
2525         __(b _SPksignalerr)       
2526        __else
2527         __(slwi imm1,imm1,2)
2528         __(li imm0,LO(local_label(misc_ref_jmp)))
2529         __(addis imm0,imm0,HA(local_label(misc_ref_jmp)))
2530         __(lwzx imm0,imm0,imm1)
2531         __(mtctr imm0)
2532         __(bctr)
2533
2534local_label(misc_ref_jmp):           
2535        /* 00-0f  */
2536         .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
2537         .long local_label(misc_ref_invalid) /* 01 cons  */
2538         .long local_label(misc_ref_invalid) /* 02 nodeheader  */
2539         .long local_label(misc_ref_invalid) /* 03 imm  */
2540         .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
2541         .long local_label(misc_ref_invalid) /* 05 nil  */
2542         .long local_label(misc_ref_invalid) /* 06 misc  */
2543         .long local_label(misc_ref_u32) /* 07 bignum  */
2544         .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
2545         .long local_label(misc_ref_invalid) /* 09 cons  */
2546         .long local_label(misc_ref_node) /* 0a ratio  */
2547         .long local_label(misc_ref_invalid) /* 0b imm  */
2548         .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
2549         .long local_label(misc_ref_invalid) /* 0d nil  */
2550         .long local_label(misc_ref_invalid) /* 0e misc  */
2551         .long local_label(misc_ref_u32) /* 0f single_float  */
2552        /* 10-1f  */
2553         .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
2554         .long local_label(misc_ref_invalid) /* 11 cons  */
2555         .long local_label(misc_ref_invalid) /* 12 nodeheader  */
2556         .long local_label(misc_ref_invalid) /* 13 imm  */
2557         .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
2558         .long local_label(misc_ref_invalid) /* 15 nil  */
2559         .long local_label(misc_ref_invalid) /* 16 misc  */
2560         .long local_label(misc_ref_u32) /* 17 double_float  */
2561         .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
2562         .long local_label(misc_ref_invalid) /* 19 cons  */
2563         .long local_label(misc_ref_node) /* 1a complex  */
2564         .long local_label(misc_ref_invalid) /* 1b imm  */
2565         .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
2566         .long local_label(misc_ref_invalid) /* 1d nil  */
2567         .long local_label(misc_ref_invalid) /* 1e misc  */
2568         .long local_label(misc_ref_u32) /* 1f macptr  */
2569        /* 20-2f  */
2570         .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
2571         .long local_label(misc_ref_invalid) /* 21 cons  */
2572         .long local_label(misc_ref_node) /* 22 catch_frame  */
2573         .long local_label(misc_ref_invalid) /* 23 imm  */
2574         .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
2575         .long local_label(misc_ref_invalid) /* 25 nil  */
2576         .long local_label(misc_ref_invalid) /* 26 misc  */
2577         .long local_label(misc_ref_u32) /* 27 dead_macptr  */
2578         .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
2579         .long local_label(misc_ref_invalid) /* 29 cons  */
2580         .long local_label(misc_ref_node) /* 2a function  */
2581         .long local_label(misc_ref_invalid) /* 2b imm  */
2582         .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
2583         .long local_label(misc_ref_invalid) /* 2d nil  */
2584         .long local_label(misc_ref_invalid) /* 2e misc  */
2585         .long local_label(misc_ref_u32) /* 2f code_vector  */
2586        /* 30-3f  */
2587         .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
2588         .long local_label(misc_ref_invalid) /* 31 cons  */
2589         .long local_label(misc_ref_node) /* 32 lisp_thread  */
2590         .long local_label(misc_ref_invalid) /* 33 imm  */
2591         .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
2592         .long local_label(misc_ref_invalid) /* 35 nil  */
2593         .long local_label(misc_ref_invalid) /* 36 misc  */
2594         .long local_label(misc_ref_u32) /* 37 creole  */
2595         .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
2596         .long local_label(misc_ref_invalid) /* 39 cons  */
2597         .long local_label(misc_ref_node) /* 3a symbol  */
2598         .long local_label(misc_ref_invalid) /* 3b imm  */
2599         .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
2600         .long local_label(misc_ref_invalid) /* 3d nil  */
2601         .long local_label(misc_ref_invalid) /* 3e misc  */
2602         .long local_label(misc_ref_u32) /* 3f xcode_vector  */
2603        /* 40-4f  */
2604         .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
2605         .long local_label(misc_ref_invalid) /* 41 cons  */
2606         .long local_label(misc_ref_node) /* 42 lock  */
2607         .long local_label(misc_ref_invalid) /* 43 imm  */
2608         .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
2609         .long local_label(misc_ref_invalid) /* 45 nil  */
2610         .long local_label(misc_ref_invalid) /* 46 misc  */
2611         .long local_label(misc_ref_invalid) /* 47 immheader  */
2612         .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
2613         .long local_label(misc_ref_invalid) /* 49 cons  */
2614         .long local_label(misc_ref_node) /* 4a hash_vector  */
2615         .long local_label(misc_ref_invalid) /* 4b imm  */
2616         .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
2617         .long local_label(misc_ref_invalid) /* 4d nil  */
2618         .long local_label(misc_ref_invalid) /* 4e misc  */
2619         .long local_label(misc_ref_invalid) /* 4f immheader  */
2620        /* 50-5f  */
2621         .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
2622         .long local_label(misc_ref_invalid) /* 51 cons  */
2623         .long local_label(misc_ref_node) /* 52 pool  */
2624         .long local_label(misc_ref_invalid) /* 53 imm  */
2625         .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
2626         .long local_label(misc_ref_invalid) /* 55 nil  */
2627         .long local_label(misc_ref_invalid) /* 56 misc  */
2628         .long local_label(misc_ref_invalid) /* 57 immheader  */
2629         .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
2630         .long local_label(misc_ref_invalid) /* 59 cons  */
2631         .long local_label(misc_ref_node) /* 5a weak  */
2632         .long local_label(misc_ref_invalid) /* 5b imm  */
2633         .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
2634         .long local_label(misc_ref_invalid) /* 5d nil  */
2635         .long local_label(misc_ref_invalid) /* 5e misc  */
2636         .long local_label(misc_ref_invalid) /* 5f immheader  */
2637        /* 60-6f  */
2638         .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
2639         .long local_label(misc_ref_invalid) /* 61 cons  */
2640         .long local_label(misc_ref_node) /* 62 package  */
2641         .long local_label(misc_ref_invalid) /* 63 imm  */
2642         .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
2643         .long local_label(misc_ref_invalid) /* 65 nil  */
2644         .long local_label(misc_ref_invalid) /* 66 misc  */
2645         .long local_label(misc_ref_invalid) /* 67 immheader  */
2646         .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
2647         .long local_label(misc_ref_invalid) /* 69 cons  */
2648         .long local_label(misc_ref_node) /* 6a slot_vector  */
2649         .long local_label(misc_ref_invalid) /* 6b imm  */
2650         .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
2651         .long local_label(misc_ref_invalid) /* 6d nil  */
2652         .long local_label(misc_ref_invalid) /* 6e misc  */
2653         .long local_label(misc_ref_invalid) /* 6f immheader  */
2654        /* 70-7f  */
2655         .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
2656         .long local_label(misc_ref_invalid) /* 71 cons  */
2657         .long local_label(misc_ref_node) /* 72 instance  */
2658         .long local_label(misc_ref_invalid) /* 73 imm  */
2659         .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
2660         .long local_label(misc_ref_invalid) /* 75 nil  */
2661         .long local_label(misc_ref_invalid) /* 76 misc  */
2662         .long local_label(misc_ref_invalid) /* 77 immheader  */
2663         .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
2664         .long local_label(misc_ref_invalid) /* 79 cons  */
2665         .long local_label(misc_ref_node) /* 7a struct  */
2666         .long local_label(misc_ref_invalid) /* 7b imm  */
2667         .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
2668         .long local_label(misc_ref_invalid) /* 7d nil  */
2669         .long local_label(misc_ref_invalid) /* 7e misc  */
2670         .long local_label(misc_ref_invalid) /* 7f immheader  */
2671        /* 80-8f  */
2672         .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
2673         .long local_label(misc_ref_invalid) /* 81 cons  */
2674         .long local_label(misc_ref_node) /* 82 istruct  */
2675         .long local_label(misc_ref_invalid) /* 83 imm  */
2676         .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
2677         .long local_label(misc_ref_invalid) /* 85 nil  */
2678         .long local_label(misc_ref_invalid) /* 86 misc  */
2679         .long local_label(misc_ref_invalid) /* 87 immheader  */
2680         .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
2681         .long local_label(misc_ref_invalid) /* 89 cons  */
2682         .long local_label(misc_ref_node) /* 8a value_cell  */
2683         .long local_label(misc_ref_invalid) /* 8b imm  */
2684         .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
2685         .long local_label(misc_ref_invalid) /* 8d nil  */
2686         .long local_label(misc_ref_invalid) /* 8e misc  */
2687         .long local_label(misc_ref_invalid) /* 8f immheader  */
2688        /* 90-9f  */
2689         .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
2690         .long local_label(misc_ref_invalid) /* 91 cons  */
2691         .long local_label(misc_ref_node) /* 92 xfunction  */
2692         .long local_label(misc_ref_invalid) /* 93 imm  */
2693         .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
2694         .long local_label(misc_ref_invalid) /* 95 nil  */
2695         .long local_label(misc_ref_invalid) /* 96 misc  */
2696         .long local_label(misc_ref_invalid) /* 97 immheader  */
2697         .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
2698         .long local_label(misc_ref_invalid) /* 99 cons  */
2699         .long local_label(misc_ref_node) /* 9a arrayN  */
2700         .long local_label(misc_ref_invalid) /* 9b imm  */
2701         .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
2702         .long local_label(misc_ref_invalid) /* 9d nil  */
2703         .long local_label(misc_ref_invalid) /* 9e misc  */
2704         .long local_label(misc_ref_invalid) /* 9f immheader  */
2705        /* a0-af  */
2706         .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
2707         .long local_label(misc_ref_invalid) /* a1 cons  */
2708         .long local_label(misc_ref_node) /* a2 vectorH  */
2709         .long local_label(misc_ref_invalid) /* a3 imm  */
2710         .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
2711         .long local_label(misc_ref_invalid) /* a5 nil  */
2712         .long local_label(misc_ref_invalid) /* a6 misc  */
2713         .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
2714         .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
2715         .long local_label(misc_ref_invalid) /* a9 cons  */
2716         .long local_label(misc_ref_node) /* aa simple_vector  */
2717         .long local_label(misc_ref_invalid) /* ab imm  */
2718         .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
2719         .long local_label(misc_ref_invalid) /* ad nil  */
2720         .long local_label(misc_ref_invalid) /* ae misc  */
2721         .long local_label(misc_ref_u32) /* af u32  */
2722        /* b0-bf  */
2723         .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
2724         .long local_label(misc_ref_invalid) /* b1 cons  */
2725         .long local_label(misc_ref_invalid) /* b2 nodeheader  */
2726         .long local_label(misc_ref_invalid) /* b3 imm  */
2727         .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
2728         .long local_label(misc_ref_invalid) /* b5 nil  */
2729         .long local_label(misc_ref_invalid) /* b6 misc  */
2730         .long local_label(misc_ref_s32) /* b7 s32  */
2731         .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
2732         .long local_label(misc_ref_invalid) /* b9 cons  */
2733         .long local_label(misc_ref_invalid) /* ba nodeheader  */
2734         .long local_label(misc_ref_invalid) /* bb imm  */
2735         .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
2736         .long local_label(misc_ref_invalid) /* bd nil  */
2737         .long local_label(misc_ref_invalid) /* be misc  */
2738         .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
2739        /* c0-cf  */
2740         .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
2741         .long local_label(misc_ref_invalid) /* c1 cons  */
2742         .long local_label(misc_ref_invalid) /* c2 nodeheader  */
2743         .long local_label(misc_ref_invalid) /* c3 imm  */
2744         .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
2745         .long local_label(misc_ref_invalid) /* c5 nil  */
2746         .long local_label(misc_ref_invalid) /* c6 misc  */
2747         .long local_label(misc_ref_new_string) /* c7 new_string  */
2748         .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
2749         .long local_label(misc_ref_invalid) /* c9 cons  */
2750         .long local_label(misc_ref_invalid) /* ca nodeheader  */
2751         .long local_label(misc_ref_invalid) /* cb imm  */
2752         .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
2753         .long local_label(misc_ref_invalid) /* cd nil  */
2754         .long local_label(misc_ref_invalid) /* ce misc  */
2755         .long local_label(misc_ref_u8) /* cf u8  */
2756        /* d0-df  */
2757         .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
2758         .long local_label(misc_ref_invalid) /* d1 cons  */
2759         .long local_label(misc_ref_invalid) /* d2 nodeheader  */
2760         .long local_label(misc_ref_invalid) /* d3 imm  */
2761         .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
2762         .long local_label(misc_ref_invalid) /* d5 nil  */
2763         .long local_label(misc_ref_invalid) /* d6 misc  */
2764         .long local_label(misc_ref_s8)      /* d7 s8  */
2765         .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
2766         .long local_label(misc_ref_invalid) /* d9 cons  */
2767         .long local_label(misc_ref_invalid) /* da nodeheader  */
2768         .long local_label(misc_ref_invalid) /* db imm  */
2769         .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
2770         .long local_label(misc_ref_invalid) /* dd nil  */
2771         .long local_label(misc_ref_invalid) /* de misc  */
2772         .long local_label(misc_ref_old_string) /* df (old)subtag_simple_base_string  */
2773        /* e0-ef  */
2774         .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
2775         .long local_label(misc_ref_invalid) /* e1 cons  */
2776         .long local_label(misc_ref_invalid) /* e2 nodeheader  */
2777         .long local_label(misc_ref_invalid) /* e3 imm  */
2778         .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
2779         .long local_label(misc_ref_invalid) /* e5 nil  */
2780         .long local_label(misc_ref_invalid) /* e6 misc  */
2781         .long local_label(misc_ref_u16) /* e7 u16  */
2782         .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
2783         .long local_label(misc_ref_invalid) /* e9 cons  */
2784         .long local_label(misc_ref_invalid) /* ea nodeheader  */
2785         .long local_label(misc_ref_invalid) /* eb imm  */
2786         .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
2787         .long local_label(misc_ref_invalid) /* ed nil  */
2788         .long local_label(misc_ref_invalid) /* ee misc  */
2789         .long local_label(misc_ref_s16) /* ef s16  */
2790        /* f0-ff  */
2791         .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
2792         .long local_label(misc_ref_invalid) /* f1 cons  */
2793         .long local_label(misc_ref_invalid) /* f2 nodeheader  */
2794         .long local_label(misc_ref_invalid) /* f3 imm  */
2795         .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
2796         .long local_label(misc_ref_invalid) /* f5 nil  */
2797         .long local_label(misc_ref_invalid) /* f6 misc  */
2798         .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
2799         .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
2800         .long local_label(misc_ref_invalid) /* f9 cons  */
2801         .long local_label(misc_ref_invalid) /* fa nodeheader  */
2802         .long local_label(misc_ref_invalid) /* fb imm  */
2803         .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
2804         .long local_label(misc_ref_invalid) /* fd nil  */
2805         .long local_label(misc_ref_invalid) /* fe misc  */
2806         .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
2807               
2808local_label(misc_ref_node):         
2809         /* A node vector.  */
2810         __(addi imm0,arg_z,misc_data_offset)
2811         __(ldrx(arg_z,arg_y,imm0))
2812         __(blr)
2813local_label(misc_ref_single_float_vector):       
2814         __(addi imm0,arg_z,misc_data_offset)
2815         __(li imm1,single_float_header)
2816         __(ldrx(imm0,arg_y,imm0))
2817         __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
2818         __(str(imm0,single_float.value(arg_z)))
2819         __(blr)
2820local_label(misc_ref_new_string):       
2821         __(addi imm0,arg_z,misc_data_offset)
2822         __(ldrx(imm0,arg_y,imm0))
2823         __(slwi arg_z,imm0,charcode_shift)
2824         __(ori arg_z,arg_z,subtag_character)
2825         __(blr)
2826local_label(misc_ref_s32):       
2827         __(addi imm0,arg_z,misc_data_offset)
2828         __(ldrx(imm0,arg_y,imm0))
2829         __(b _SPmakes32)
2830local_label(misc_ref_fixnum_vector):   
2831         __(addi imm0,arg_z,misc_data_offset)
2832         __(ldrx(imm0,arg_y,imm0))
2833         __(box_fixnum(arg_z,imm0))
2834         __(blr)       
2835local_label(misc_ref_u32):       
2836         __(addi imm0,arg_z,misc_data_offset)
2837         __(ldrx(imm0,arg_y,imm0))
2838         __(b _SPmakeu32)
2839local_label(misc_ref_double_float_vector):     
2840         __(slwi imm0,arg_z,1)
2841         __(la imm0,misc_dfloat_offset(imm0))
2842         __(lfdx f0,arg_y,imm0)
2843         __(li imm2,double_float_header)
2844         __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
2845         __(stfd f0,double_float.value(arg_z))
2846         __(blr)
2847local_label(misc_ref_bit_vector):       
2848         __(extrwi imm1,arg_z,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
2849         __(la imm1,1+fixnumshift(imm1))
2850         __(rlwinm imm0,arg_z,32-5,5,31-fixnumshift)
2851         __(la imm0,misc_data_offset(imm0))
2852         __(ldrx(imm0,arg_y,imm0))
2853         __(rlwnm arg_z,imm0,imm1,31-fixnumshift,31-fixnumshift)
2854         __(blr)
2855local_label(misc_ref_s8):       
2856         __(srwi imm0,arg_z,2)
2857         __(la imm0,misc_data_offset(imm0))
2858         __(lbzx imm0,arg_y,imm0)
2859         __(extsb imm0,imm0)
2860         __(box_fixnum(arg_z,imm0))
2861         __(blr)
2862local_label(misc_ref_u8):       
2863         __(srwi imm0,arg_z,2)
2864         __(la imm0,misc_data_offset(imm0))
2865         __(lbzx imm0,arg_y,imm0)
2866         __(box_fixnum(arg_z,imm0))
2867         __(blr)
2868local_label(misc_ref_old_string):           
2869         __(srwi imm0,arg_z,2)
2870         __(la imm0,misc_data_offset(imm0))
2871         __(lbzx imm0,arg_y,imm0)
2872         __(slwi arg_z,imm0,charcode_shift)
2873         __(ori arg_z,arg_z,subtag_character)
2874         __(blr)
2875local_label(misc_ref_u16):             
2876         __(srwi imm0,arg_z,1)
2877         __(la imm0,misc_data_offset(imm0))
2878         __(lhzx imm0,arg_y,imm0)
2879         __(box_fixnum(arg_z,imm0))
2880         __(blr)
2881local_label(misc_ref_s16):             
2882         __(srwi imm0,arg_z,1)
2883         __(la imm0,misc_data_offset(imm0))
2884         __(lhax imm0,arg_y,imm0)
2885         __(box_fixnum(arg_z,imm0))
2886         __(blr)
2887local_label(misc_ref_invalid):
2888         __(li arg_x,XBADVEC)
2889         __(set_nargs(3))
2890         __(b _SPksignalerr)       
2891
2892        __endif
2893       
2894/* like misc_ref, only the boxed subtag is in arg_x.  */
2895
2896_spentry(subtag_misc_ref)
2897        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
2898        __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
2899        __(vector_length(imm0,arg_y,imm1))
2900        __(trlge(arg_z,imm0))
2901        __(unbox_fixnum(imm1,arg_x))
2902        __(b local_label(misc_ref_common))
2903
2904_spentry(builtin_aref1)
2905        __(extract_typecode(imm0,arg_y))
2906        __(cmpri(cr0,imm0,min_vector_subtag))
2907        __(box_fixnum(arg_x,imm0))
2908        __(bgt cr0,_SPsubtag_misc_ref)
2909        __(jump_builtin(_builtin_aref1,2))
2910               
2911       
2912/* Make a cons cell on the vstack.  Always push 3 words, 'cause we're   */
2913/* not sure how the vstack will be aligned.  */
2914_spentry(stkconsyz)
2915        __(li imm0,nil_value)
2916        __(vpush(imm0))
2917        __(vpush(imm0))
2918        __(vpush(imm0))
2919        __(andi. imm0,vsp,1<<word_shift) /* (oddp vsp ?)  */
2920        __(beq cr0,1f)
2921        __(str(arg_y,node_size*2(vsp))) /* car  */
2922        __(str(arg_z,node_size(vsp))) /* cdr  */
2923        __(la arg_z,fulltag_cons+node_size(vsp))
2924        __(blr)
29251:
2926        __(str(arg_y,node_size(vsp))) /* car, again  */
2927        __(str(arg_z,0(vsp)))
2928        __(la arg_z,fulltag_cons(vsp))
2929        __(blr)
2930
2931/* Make a stack-consed value cell.  Much like the case of */
2932/* stack-allocating a cons cell.  Imm0 points to the closed-over value */
2933/* (already vpushed).  Replace that locative with the vcell.  */
2934_spentry(stkvcell0)
2935        __(sub imm1,imm0,vsp) /* imm1 = delta from vsp to value cell loc  */
2936        __(li arg_z,nil_value)
2937        __(vpush(arg_z))
2938        __(vpush(arg_z))
2939        __(vpush(arg_z))
2940        __(addi imm1,imm1,node_size*3)
2941        __(add imm0,vsp,imm1) /* in case stack overflowed  */
2942        __(andi. imm1,vsp,1<<word_shift) /* (oddp vsp) ?  */
2943        __(li imm1,value_cell_header)
2944        __(ldr(arg_z,0(imm0)))
2945        __(beq cr0,1f)
2946        __(str(arg_z,node_size*2(vsp)))
2947        __(str(imm1,node_size(vsp)))
2948        __(la arg_z,fulltag_misc+node_size(vsp))
2949        __(str(arg_z,0(imm0)))
2950        __(blr)
29511:
2952        __(str(arg_z,node_size(vsp)))
2953        __(str(imm1,0(vsp)))
2954        __(la arg_z,fulltag_misc(vsp))
2955        __(str(arg_z,0(imm0)))
2956        __(blr)
2957
2958       
2959_spentry(stkvcellvsp)     
2960        __(li arg_z,nil_value)
2961        __(vpush(arg_z))
2962        __(vpush(arg_z))
2963        __(vpush(arg_z))
2964        __(li imm1,node_size*3)
2965        __(add imm0,vsp,imm1) /* in case stack overflowed  */
2966        __(andi. imm1,vsp,1<<word_shift) /* (oddp vsp) ?  */
2967        __(li imm1,value_cell_header)
2968        __(ldr(arg_z,0(imm0)))
2969        __(beq cr0,1f)
2970        __(str(arg_z,node_size*2(vsp)))
2971        __(str(imm1,node_size(vsp)))
2972        __(la arg_z,fulltag_misc+node_size(vsp))
2973        __(str(arg_z,0(imm0)))
2974        __(blr)
29751:
2976        __(str(arg_z,node_size(vsp)))
2977        __(str(imm1,0(vsp)))
2978        __(la arg_z,fulltag_misc(vsp))
2979        __(str(arg_z,0(imm0)))
2980        __(blr)
2981
2982/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
2983/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
2984/* in arg_z on exit.  */
2985_spentry(makestackblock)
2986        __(unbox_fixnum(imm0,arg_z))
2987        __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
2988        __(cmplri(cr0,imm0,tstack_alloc_limit))
2989        __(bge cr0,1f)
2990        __(TSP_Alloc_Var_Unboxed(imm0))
2991        __(li imm0,macptr_header)
2992        __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
2993        __(str(imm0,tsp_frame.data_offset(tsp)))
2994        __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
2995        __(str(imm1,macptr.address(arg_z)))
2996        __ifdef([PPC64])
2997         __(std rzero,macptr.domain(arg_z))
2998         __(std rzero,macptr.type(arg_z))
2999        __else
3000         __(stfd fp_zero,macptr.domain(arg_z))
3001        __endif
3002        __(blr)
3003
3004        /* Too big. Heap cons a gcable macptr  */
30051:
3006        __(TSP_Alloc_Fixed_Unboxed(0))
3007        __(set_nargs(1))
3008        __(li fname,nrs.new_gcable_ptr)
3009        __(jump_fname())
3010
3011/* As above, only set the block's contents to 0.  */
3012_spentry(makestackblock0)
3013        __(unbox_fixnum(imm0,arg_z))
3014        __(dnode_align(imm0,imm0,tsp_frame.fixed_overhead+macptr.size))
3015        __(cmplri(cr0,imm0,tstack_alloc_limit))
3016        __(bge cr0,3f)
3017        __(TSP_Alloc_Var_Unboxed(imm0))
3018        __(Zero_TSP_Frame(imm0,imm1))
3019        __(li imm0,macptr_header)
3020        __(la imm1,tsp_frame.data_offset+macptr.size(tsp))
3021        __(str(imm0,tsp_frame.data_offset(tsp)))
3022        __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
3023        __(str(imm1,macptr.address(arg_z))) /* makestackblock0 expects the address to be in imm1  */
3024        __(stfd fp_zero,macptr.domain(arg_z))
3025        __(blr)
3026
3027        /* Too big. Heap cons a gcable macptr  */
30283:
3029        __(TSP_Alloc_Fixed_Unboxed(0)) /* "raw" block to make the compiler happy  */
3030
3031        __(mr arg_y,arg_z) /* save block size  */
3032        __(li arg_z,t_value) /* clear-p arg to %new-gcable-ptr  */
3033        __(set_nargs(2))
3034        __(li fname,nrs.new_gcable_ptr)
3035        __(jump_fname())
3036
3037/* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
3038/* the tstack.  Return the list in arg_z.  */
3039_spentry(makestacklist)
3040        __(add imm0,arg_y,arg_y)
3041        __(cmplri(cr1,imm0,((tstack_alloc_limit+1)-cons.size)))
3042        __(addi imm0,imm0,tsp_frame.fixed_overhead)
3043        __(bge cr1,3f)
3044        __(TSP_Alloc_Var_Boxed(imm0,imm1))
3045        __(mr imm1,arg_y)
3046        __(cmpri(cr1,imm1,0))
3047        __(mr arg_y,arg_z)
3048        __(li arg_z,nil_value)
3049        __(ldr(imm2,tsp_frame.backlink(tsp)))
3050        __(la imm2,-tsp_frame.fixed_overhead+fulltag_cons(imm2))
3051        __(b 2f)
30521:
3053        __(subi imm1,imm1,fixnum1)
3054        __(cmpri(cr1,imm1,0))
3055        __(_rplacd(imm2,arg_z))
3056        __(_rplaca(imm2,arg_y))
3057        __(mr arg_z,imm2)
3058        __(subi imm2,imm2,cons.size)
30592:
3060        __(bne cr1,1b)
3061        __(blr)
3062
30633:
3064        __(cmpri(cr1,arg_y,0))
3065        __(TSP_Alloc_Fixed_Boxed(0))  /* make the compiler happy  */
3066        __(mr imm1,arg_y) /* count  */
3067        __(mr arg_y,arg_z) /* initial value  */
3068        __(li arg_z,nil_value) /* result  */
3069        __(b 5f)
30704:
3071        __(subi imm1,imm1,fixnum1)
3072        __(cmpri(cr1,imm1,0))
3073        __(Cons(arg_z,arg_y,arg_z))
30745:
3075        __(bne cr1,4b)
3076        __(blr)
3077
3078/* subtype (boxed) vpushed before initial values. (Had better be a  */
3079/* node header subtag.) Nargs set to count of things vpushed.  */
3080
3081_spentry(stkgvector)
3082        __(la imm0,-fixnum_one(nargs))
3083        __(cmpri(cr1,imm0,0))
3084        __(add imm1,vsp,nargs)
3085        __(ldru(temp0,-node_size(imm1)))
3086        __(slri(imm2,imm0,num_subtag_bits-fixnumshift))
3087        __ifdef([PPC64])
3088         __(unbox_fixnum(imm3,temp0))
3089         __(or imm2,imm3,imm2)
3090        __else
3091         __(rlwimi imm2,temp0,32-fixnumshift,32-num_subtag_bits,31)
3092        __endif
3093        __(dnode_align(imm0,imm0,node_size+tsp_frame.fixed_overhead))
3094        __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
3095        __(str(imm2,tsp_frame.data_offset(tsp)))
3096        __(la arg_z,tsp_frame.data_offset+fulltag_misc(tsp))
3097        __(la imm3,misc_header_offset(arg_z))
3098        __(li imm0,fixnum1)
3099        __(b 2f)
31001:
3101        __(addi imm0,imm0,fixnum1)
3102        __(cmpr(cr1,imm0,nargs))
3103        __(ldru(temp0,-node_size(imm1)))
3104        __(stru(temp0,node_size(imm3)))
31052:
3106        __(bne cr1,1b)
3107        __(add vsp,vsp,nargs)
3108        __(blr)
3109
3110/* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
3111/* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
3112/* parameters must be "reasonable" (the  subtag must be valid, the element  */
3113/* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
3114/* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
3115/* proper header on it and its contents will be 0.   imm0 contains   */
3116/* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
3117/* This is intended for things like "make-array" and "%make-bignum" and the   */
3118/* like.  Things that involve creating small objects of known size can usually  */
3119/* do so inline with less hair.  */
3120
3121/* If this has to go out-of-line (to GC or whatever), it should do so via a   */
3122/* trap (or should otherwise ensure that both the LR and CTR are preserved   */
3123/* where the GC can find them.)  */
3124
3125
3126_spentry(misc_alloc)
3127        __ifdef([PPC64])
3128         __(extract_unsigned_byte_bits_(imm2,arg_y,56))
3129         __(unbox_fixnum(imm0,arg_z))
3130         __(sldi imm2,arg_y,num_subtag_bits-fixnumshift)
3131         __(clrldi imm1,imm0,64-nlowtagbits)
3132         __(or imm0,imm2,imm0)
3133         __(extract_fulltag(imm2,imm0))
3134         __(cmpdi cr1,imm1,lowtag_nodeheader)
3135         __(cmpdi cr2,imm2,ivector_class_64_bit)
3136         __(bne- cr0,9f)
3137         __(cmpdi cr3,imm2,ivector_class_32_bit)
3138         __(cmpdi cr4,imm2,ivector_class_8_bit)
3139         __(mr imm2,arg_y)
3140         __(cmpdi cr5,imm1,subtag_bit_vector)
3141         __(beq cr1,1f)
3142         __(beq cr2,1f)
3143         __(srdi imm2,imm2,1)
3144         __(beq cr3,1f)
3145         __(beq cr5,2f)
3146         __(srdi imm2,imm2,1)
3147         __(bne cr4,1f)
3148         __(srdi imm2,imm2,1)
3149/* imm2 now = byte count.  Add 8 for header, 15 to align, then clear */
3150/* low four bits. */
31511:
3152         __(dnode_align(imm2,imm2,node_size))
3153
3154         __(Misc_Alloc(arg_z,imm0,imm2))
3155         __(blr)
31562:      /* bit-vector case  */
3157         __(addi imm2,arg_y,7<<fixnumshift)
3158         __(srdi imm2,imm2,3+fixnumshift)
3159         __(b 1b)
31609:                     
3161         __(uuo_interr(error_object_not_unsigned_byte_56,arg_y))
3162        __else
3163         __(extract_unsigned_byte_bits_(imm2,arg_y,24))
3164         __(unbox_fixnum(imm0,arg_z))
3165         __(extract_fulltag(imm1,imm0))
3166         __(bne- cr0,9f)
3167         __(cmpri(cr0,imm1,fulltag_nodeheader))
3168         __(mr imm3,imm0)
3169         __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
3170         __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits )/* imm0 now = header  */
3171         __(mr imm2,arg_y)
3172         __(beq cr0,1f) /* do probe if node object (fixnum element count = byte count).  */
3173         __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
3174         __(bng cr1,1f) /* do probe if 32-bit imm object  */
3175         __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
3176         __(srwi imm2,imm2,1)
3177         __(bgt cr0,2f)
3178         __(bgt cr1,1f)
3179         __(srwi imm2,imm2,1)
3180        /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
3181        /* low three bits.  */
31821:
3183         __(dnode_align(imm2,imm2,node_size))
3184
3185         __(Misc_Alloc(arg_z,imm0,imm2))
3186         __(blr)
31872:
3188         __(cmplri(imm3,subtag_double_float_vector))
3189         __(slwi imm2,arg_y,1)
3190         __(beq 1b)
3191         __(addi imm2,arg_y,7<<fixnumshift)
3192         __(srwi imm2,imm2,fixnumshift+3)
3193         __(b 1b)
31949:
3195         __(uuo_interr(error_object_not_unsigned_byte_24,arg_y))
3196        __endif
3197       
3198/* almost exactly as above, but "swap exception handling info" */
3199/* on exit and return  */
3200_spentry(poweropen_ffcallX)
3201        __(mflr loc_pc)
3202        __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
3203        __(mr save0,rcontext)   /* or address globals.  */
3204        __(extract_typecode(imm0,arg_z))
3205        __(cmpri(cr7,imm0,subtag_macptr))
3206        __(ldr(save1,c_frame.backlink(sp)))     /* bottom of reserved lisp frame  */
3207        __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
3208        __(zero_doublewords save2,0,lisp_frame.size)
3209        __(str(save1,lisp_frame.backlink(save2)))
3210        __(str(save2,c_frame.backlink(sp)))
3211        __(str(fn,lisp_frame.savefn(save2)))
3212        __(str(loc_pc,lisp_frame.savelr(save2)))
3213        __(str(vsp,lisp_frame.savevsp(save2)))
3214        __(bne cr7,1f)
3215        __(ldr(arg_z,macptr.address(arg_z)))
32161:
3217        __(ldr(save3,tcr.cs_area(rcontext)))
3218        __(str(save2,area.active(save3)))
3219        __(str(allocptr,tcr.save_allocptr(rcontext)))
3220        __(str(allocbase,tcr.save_allocbase(rcontext)))
3221        __(str(tsp,tcr.save_tsp(rcontext)))
3222        __(str(vsp,tcr.save_vsp(rcontext)))
3223        __(str(rzero,tcr.ffi_exception(rcontext)))
3224        __(mffs f0)
3225        __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
3226        __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
3227        __(ldr(r3,tcr.foreign_exception_status(rcontext)))
3228        __(cmpri(r3,0))
3229        __(ref_global(r12,lisp_exit_hook))
3230        __(mtctr r12)
3231        __(beq+ 1f)
3232        __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
3233        __(bctrl)
3234        __(la sp,(stack_align(c_frame.minsiz))(sp))
32351:     
3236        __(li rcontext,0)
3237        __(mtctr arg_z)
3238        __(ldr(r3,c_frame.param0(sp)))
3239        __(ldr(r4,c_frame.param1(sp)))
3240        __(ldr(r5,c_frame.param2(sp)))
3241        __(ldr(r6,c_frame.param3(sp)))
3242        __(ldr(r7,c_frame.param4(sp)))
3243        __(ldr(r8,c_frame.param5(sp)))
3244        __(ldr(r9,c_frame.param6(sp)))
3245        __(ldr(r10,c_frame.param7(sp)))
3246        /* Darwin is allegedly very picky about what register points */
3247        /* to the function on entry.  */
3248        __(mr r12,arg_z)
3249        __(bctrl)
3250        __(ref_global(r12,lisp_return_hook))
3251        __(mtctr r12)
3252        __(str(r3,c_frame.param0(sp)))
3253        __(str(r4,c_frame.param1(sp)))
3254        __(stfd f1,c_frame.param2(sp))
3255        __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
3256        __(mr r3,save0)
3257        __(bctrl)
3258        __(la sp,(stack_align(c_frame.minsiz))(sp))
3259        __(ldr(r3,c_frame.param0(sp)))
3260        __(ldr(r4,c_frame.param1(sp)))
3261        __(lfd f1,c_frame.param2(sp))
3262        __(b FF_call_return_common)     
3263       
3264
3265
3266/* Destructuring-bind, macro-bind.  */
3267   
3268/* OK to use arg_x, arg_y for whatever (tagged) purpose;  */
3269/* likewise immX regs.  */
3270/* arg_z preserved, nothing else in particular defined on exit.  */
3271/* nargs contains req count (0-255) in PPC bits mask_req_start/mask_req_width,  */
3272/* opt count (0-255) in PPC bits mask_opt_start/mask_opt_width,  */
3273/* key count (0-255) in PPC bits mask_key_start/mask_key_width,  */
3274/* opt-supplied-p flag in PPC bit mask_initopt,  */
3275/* keyp flag in PPC bit mask_keyp,  */
3276/* &allow-other-keys flag in PPC bit mask_aok,  */
3277/* &rest flag in PPC bit mask_restp.  */
3278/* When mask_keyp bit is set, keyvect contains vector of keyword symbols,  */
3279/* length key count.  */
3280
3281_spentry(macro_bind)
3282        __ifdef([PPC64])
3283         __(mr whole_reg,arg_reg)
3284         __(extract_fulltag(imm0,arg_reg))
3285         __(cmpri(cr1,arg_reg,nil_value))
3286         __(cmpri(cr0,imm0,fulltag_cons))
3287         __(beq cr1,0f)
3288         __(bne- cr0,1f)
32890:             
3290         __(_cdr(arg_reg,arg_reg))
3291         __(b local_label(destbind1))
3292        __else
3293         __(mr whole_reg,arg_reg)
3294         __(extract_lisptag(imm0,arg_reg))
3295         __(cmpri(cr0,imm0,tag_list))
3296         __(bne- cr0,1f)
3297         __(_cdr(arg_reg,arg_reg))
3298         __(b (local_label(destbind1)))
3299        __endif
33001:
3301        __(li arg_y,XCALLNOMATCH)
3302        __(mr arg_z,whole_reg)
3303        __(set_nargs(2))
3304        __(b _SPksignalerr)
3305
3306
3307_spentry(destructuring_bind)
3308        __(mr whole_reg,arg_reg)
3309        __(b local_label(destbind1))
3310       
3311_spentry(destructuring_bind_inner)
3312        __(mr whole_reg,arg_z)
3313local_label(destbind1):
3314        /* Extract required arg count.  */
3315        /* A bug in gas: can't handle shift count of "32" (= 0  */
3316        ifelse(eval(mask_req_width+mask_req_start),eval(32),[
3317        __(clrlwi. imm0,nargs,mask_req_start)
3318        ],[
3319        __(extrwi. imm0,nargs,mask_req_width,mask_req_start)
3320        ])
3321        __(extrwi imm1,nargs,mask_opt_width,mask_opt_start)
3322        __(rlwinm imm2,nargs,0,mask_initopt,mask_initopt)
3323        __(rlwinm imm4,nargs,0,mask_keyp,mask_keyp)
3324        __(cmpri(cr4,imm4,0))
3325        __(rlwinm imm4,nargs,0,mask_restp,mask_restp)
3326        __(cmpri(cr5,imm4,0))
3327        __(cmpri(cr1,imm1,0))
3328        __(cmpri(cr2,imm2,0))
3329        /* Save entry vsp in case of error.  */
3330        __(mr imm4,vsp)
3331        __(beq cr0,2f)
33321:
3333        __(cmpri(cr7,arg_reg,nil_value))
3334        __ifdef([PPC64])
3335         __(extract_fulltag(imm3,arg_reg))
3336         __(cmpri(cr3,imm3,fulltag_cons))
3337        __else       
3338         __(extract_lisptag(imm3,arg_reg))
3339         __(cmpri(cr3,imm3,tag_list))
3340        __endif
3341        __(subi imm0,imm0,1)
3342        __(cmpri(cr0,imm0,0))
3343        __(beq cr7,toofew)
3344        __(bne cr3,badlist)
3345        __(ldr(arg_x,cons.car(arg_reg)))
3346        __(ldr(arg_reg,cons.cdr(arg_reg)))
3347        __(vpush(arg_x))
3348        __(bne cr0,1b)
33492:
3350        __(beq cr1,rest_keys)
3351        __(bne cr2,opt_supp)
3352        /* 'simple' &optionals:  no supplied-p, default to nil.  */
3353simple_opt_loop:
3354        __(cmpri(cr0,arg_reg,nil_value))
3355        __ifdef([PPC64])
3356         __(extract_fulltag(imm3,arg_reg))
3357         __(cmpri(cr3,imm3,fulltag_cons))
3358        __else
3359         __(extract_lisptag(imm3,arg_reg))
3360         __(cmpri(cr3,imm3,tag_list))
3361        __endif
3362        __(subi imm1,imm1,1)
3363        __(cmpri(cr1,imm1,0))
3364        __(li imm5,nil_value)
3365        __(beq cr0,default_simple_opt)
3366        __(bne cr3,badlist)
3367        __(ldr(arg_x,cons.car(arg_reg)))
3368        __(ldr(arg_reg,cons.cdr(arg_reg)))
3369        __(vpush(arg_x))
3370        __(bne cr1,simple_opt_loop)
3371        __(b rest_keys)
3372default_simple_opt_loop:
3373        __(subi imm1,imm1,1)
3374        __(cmpri(cr1,imm1,0))
3375default_simple_opt:
3376        __(vpush(imm5))
3377        __(bne cr1,default_simple_opt_loop)
3378        __(b rest_keys)
3379        /* Provide supplied-p vars for the &optionals.  */
3380opt_supp:
3381        __(li arg_y,t_value)
3382opt_supp_loop:
3383        __(cmpri(cr0,arg_reg,nil_value))
3384        __ifdef([PPC64])
3385         __(extract_fulltag(imm3,arg_reg))
3386         __(cmpri(cr3,imm3,fulltag_cons))
3387        __else       
3388         __(extract_lisptag(imm3,arg_reg))
3389         __(cmpri(cr3,imm3,tag_list))
3390        __endif
3391        __(subi imm1,imm1,1)
3392        __(cmpri(cr1,imm1,0))
3393        __(beq cr0,default_hard_opt)
3394        __(bne cr3,badlist)
3395        __(ldr(arg_x,cons.car(arg_reg)))
3396        __(ldr(arg_reg,cons.cdr(arg_reg)))
3397        __(vpush(arg_x))
3398        __(vpush(arg_y))
3399        __(bne cr1,opt_supp_loop)
3400        __(b rest_keys)
3401default_hard_opt_loop:
3402        __(subi imm1,imm1,1)
3403        __(cmpri(cr1,imm1,0))
3404default_hard_opt:
3405        __(vpush(imm5))
3406        __(vpush(imm5))
3407        __(bne cr1,default_hard_opt_loop)
3408rest_keys:
3409        __(cmpri(cr0,arg_reg,nil_value))
3410        __(bne cr5,have_rest)
3411        __(bne cr4,have_keys)
3412        __(bne cr0,toomany)
3413        __(blr)
3414have_rest:
3415        __(vpush(arg_reg))
3416        __(beqlr cr4)
3417have_keys:
3418        /* Ensure that arg_reg contains a proper,even-length list.  */
3419        /* Insist that its length is <= 512 (as a cheap circularity check.)  */
3420        __(li imm0,256)
3421        __(mr arg_x,arg_reg)
3422count_keys_loop:
3423        __ifdef([PPC64])
3424         __(extract_fulltag(imm3,arg_x))
3425         __(cmpri(cr3,imm3,fulltag_cons))
3426        __else
3427         __(extract_lisptag(imm3,arg_x))
3428         __(cmpri(cr3,imm3,tag_list))
3429        __endif
3430        __(cmpri(cr0,arg_x,nil_value))
3431        __(subi imm0,imm0,1)
3432        __(cmpri(cr4,imm0,0))
3433        __(beq cr0,counted_keys)
3434        __(bne cr3,badlist)
3435        __(ldr(arg_x,cons.cdr(arg_x)))
3436        __ifdef([PPC64])
3437         __(extract_fulltag(imm3,arg_x))
3438         __(cmpri(cr3,imm3,fulltag_cons))
3439        __else
3440         __(extract_lisptag(imm3,arg_x))
3441         __(cmpri(cr3,imm3,tag_list))
3442        __endif
3443        __(blt cr4,toomany)
3444        __(cmpri(cr0,arg_x,nil_value))
3445        __(beq cr0,db_badkeys)
3446        __(bne cr3,badlist)
3447        __(ldr(arg_x,cons.cdr(arg_x)))
3448        __(b count_keys_loop)
3449counted_keys:
3450        /* We've got a proper, even-length list of key/value pairs in */
3451        /* arg_reg. For each keyword var in the lambda-list, push a pair */
3452        /* of NILs on the vstack.  */
3453        __(extrwi. imm0,nargs,mask_key_width,mask_key_start )
3454        __(mr imm2,imm0)        /* save number of keys  */
3455        __(li imm5,nil_value)
3456        __(b push_pair_test)
3457push_pair_loop:
3458        __(cmpri(cr0,imm0,1))
3459        __(subi imm0,imm0,1)
3460        __(vpush(imm5))
3461        __(vpush(imm5))
3462push_pair_test:
3463        __(bne cr0,push_pair_loop)
3464        __(slwi imm2,imm2,3)            /* pairs -> bytes  */
3465        __(add imm2,vsp,imm2)           /* imm2 points below pairs  */
3466        __(li imm0,0)                   /* count unknown keywords so far  */
3467        __(extrwi imm1,nargs,1,mask_aok) /* unknown keywords allowed  */
3468        __(extrwi nargs,nargs,mask_key_width,mask_key_start)
3469        /* Now, for each keyword/value pair in the list  */
3470        /*  a) if the keyword is found in the keyword vector, set the  */
3471        /*     corresponding entry on the vstack to the value and the  */
3472        /*     associated supplied-p var to T.  */
3473        /*  b) Regardless of whether or not the keyword is found,  */
3474        /*     if the keyword is :ALLOW-OTHER-KEYS and the value is non-nil,  */
3475        /*     set imm1 to a non-zero value to indicate that unknown keywords  */
3476        /*     are acceptable.  */
3477        /*  c) If the keyword is not found (and isn't :ALLOW-OTHER-KEYS), increment  */
3478        /*     the count of unknown keywords in imm0.  */
3479        /* At the end of the list, signal an error if any unknown keywords were seen  */
3480        /* but not allowed.  Otherwise, return.  */
3481
3482match_keys_loop:
3483        __(cmpri(cr0,arg_reg,nil_value))
3484        __(li imm0,0)
3485        __(li imm3,misc_data_offset)
3486        __(beq cr0,matched_keys)
3487        __(ldr(arg_x,cons.car(arg_reg)))
3488        __(li arg_y,nrs.kallowotherkeys)
3489        __(cmpr(cr3,arg_x,arg_y))       /* :ALLOW-OTHER-KEYS ?  */
3490        __(ldr(arg_reg,cons.cdr(arg_reg)))
3491        __(ldr(arg_y,cons.car(arg_reg)))
3492        __(cmpri(cr0,arg_y,nil_value))
3493        __(cmpr(cr4,imm0,nargs))
3494        __(ldr(arg_reg,cons.cdr(arg_reg)))
3495        __(bne cr3,match_test)
3496        __(beq cr0,match_test)
3497        __(ori imm1,imm1,1)
3498        __(b match_test)
3499match_loop:
3500        __(ldrx(temp0,keyvect_reg,imm3))
3501        __(cmpr(cr0,arg_x,temp0))
3502        __(addi imm0,imm0,1)
3503        __(cmpr(cr4,imm0,nargs))
3504        __(addi imm3,imm3,4)
3505        __(bne cr0,match_test)
3506        /* Got a hit.  Unless this keyword's been seen already, set it.  */
3507        __(slwi imm0,imm0,3)
3508        __(subf imm0,imm0,imm2)
3509        __(ldr(temp0,0(imm0)))
3510        __(cmpri(cr0,temp0,nil_value))
3511        __(li temp0,t_value)
3512        __(bne cr0,match_keys_loop)     /* already saw this  */
3513        __(str(arg_y,node_size*1(imm0)))
3514        __(str(temp0,node_size*0(imm0)))
3515        __(b match_keys_loop)
3516match_test:
3517        __(bne cr4,match_loop)
3518        __(oris imm1,imm1,0x8000)
3519        __(b match_keys_loop)
3520matched_keys:
3521        __(cmpri(cr1,imm1,0))
3522        __(add imm1,imm1,imm1)
3523        __(cmpri(cr0,imm1,0))
3524        __(bgelr cr1)
3525        __(bnelr cr0)
3526        /* Some unrecognized keywords.  Complain generically about  */
3527        /* invalid keywords.  */
3528db_badkeys:
3529        __(li arg_y,XBADKEYS)
3530        __(b destructure_error)
3531toomany:
3532        __(li arg_y,XCALLTOOMANY)
3533        __(b destructure_error)
3534toofew:
3535        __(li arg_y,XCALLTOOFEW)
3536        __(b destructure_error)
3537badlist:
3538        __(li arg_y,XCALLNOMATCH)
3539        /* b destructure_error  */
3540destructure_error:
3541        __(mr vsp,imm4)         /* undo everything done to the stack  */
3542        __(mr arg_z,whole_reg)
3543        __(set_nargs(2))
3544        __(b _SPksignalerr)
3545       
3546/* vpush the values in the value set atop the vsp, incrementing nargs.  */
3547/* Discard the tsp frame; leave values atop the vsp.  */
3548
3549_spentry(recover_values)
3550
3551/* First, walk the segments reversing the pointer to previous segment pointers  */
3552/* Can tell the end because that previous segment pointer is the prev tsp pointer  */
3553        __(ldr(imm0,tsp_frame.backlink(tsp))) /* previous tsp  */
3554        __(mr imm1,tsp) /* current segment  */
3555        __(mr imm2,tsp) /* last segment  */
3556local_label(walkloop):
3557        __(ldr(imm3,tsp_frame.fixed_overhead+node_size(imm1))) /* next segment  */
3558        __(cmpr(cr0,imm0,imm3)) /* last segment?  */
3559        __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
3560        __(mr imm2,imm1) /* last segment <- current segment  */
3561        __(mr imm1,imm3) /* current segment <- next segment  */
3562        __(bne cr0,local_label(walkloop))
3563
3564        /* the final segment ptr is now in imm2  */
3565        /* walk backwards, pushing values on VSP and incrementing NARGS  */
3566local_label(pushloop):
3567        __(ldr(imm0,tsp_frame.data_offset(imm2))) /* nargs in segment  */
3568        __(cmpri(cr0,imm0,0))
3569        __(cmpr(cr1,imm2,tsp))
3570        __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
3571        __(add imm3,imm3,imm0)
3572        __(add nargs,nargs,imm0)
3573        __(b 2f)
35741:
3575        __(ldru(arg_z,-node_size(imm3)))
3576        __(cmpri(cr0,imm0,fixnum_one))
3577        __(subi imm0,imm0,fixnum_one)
3578        __(vpush(arg_z))
35792:
3580        __(bne cr0,1b)
3581        __(ldr(imm2,tsp_frame.data_offset+node_size(imm2))) /* previous segment  */
3582        __(bne cr1,local_label(pushloop))
3583        __(unlink(tsp))
3584        __(blr)
3585
3586       
3587/* Go out of line to do this.  Sheesh.  */
3588
3589_spentry(vpopargregs)
3590        __(cmpri(cr0,nargs,0))
3591        __(cmpri(cr1,nargs,2<<fixnumshift))
3592        __(beqlr cr0)
3593        __(beq cr1,local_label(yz))
3594        __(blt cr1,local_label(z))
3595        __(ldr(arg_z,node_size*0(vsp)))
3596        __(ldr(arg_y,node_size*1(vsp)))
3597        __(ldr(arg_x,node_size*2(vsp)))
3598        __(la vsp,node_size*3(vsp))
3599        __(blr)
3600local_label(yz):
3601        __(ldr(arg_z,node_size*0(vsp)))
3602        __(ldr(arg_y,node_size*1(vsp)))
3603        __(la vsp,node_size*2(vsp))
3604        __(blr)
3605local_label(z):
3606        __(ldr(arg_z,node_size*0(vsp)))
3607        __(la vsp,node_size*1(vsp))
3608        __(blr)
3609
3610/* If arg_z is an integer, return in imm0 something whose sign  */
3611/* is the same as arg_z's.  If not an integer, error.  */
3612_spentry(integer_sign)
3613        __(extract_typecode(imm0,arg_z))
3614        __(cmpri(cr1,imm0,tag_fixnum))
3615        __(cmpri(cr0,imm0,subtag_bignum))
3616        __(mr imm0,arg_z)
3617        __(beqlr+ cr1)
3618        __(bne- cr0,1f)
3619        __(getvheader(imm0,arg_z))
3620        __ifdef([PPC64])
3621         __(header_size(imm0,imm0))
3622         __(sldi imm0,imm0,2)
3623        __else
3624         __(header_length(imm0,imm0)) /* boxed length = scaled size  */
3625        __endif
3626        __(addi imm0,imm0,misc_data_offset-4) /* bias, less 1 element  */
3627        __(lwzx imm0,arg_z,imm0)
3628        __(cmpwi cr0,imm0,0)
3629        __(li imm0,1)
3630        __(bgelr cr0)
3631        __(li imm0,-1)
3632        __(blr)
36331:
3634        __(uuo_interr(error_object_not_integer,arg_z))
3635
3636/* like misc_set, only pass the (boxed) subtag in temp0  */
3637_spentry(subtag_misc_set)
3638        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
3639        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
3640        __(vector_length(imm0,arg_x,imm1))
3641        __(trlge(arg_y,imm0))
3642        __(unbox_fixnum(imm1,temp0))
3643local_label(misc_set_common):
3644        __ifdef([PPC64])
3645         __(slwi imm1,imm1,3)
3646         __(li imm0,LO(local_label(misc_set_jmp)))
3647         __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
3648         __(ldx imm0,imm0,imm1)
3649         __(mtctr imm0)
3650         __(bctr)
3651local_label(misc_set_jmp):             
3652        /* 00-0f  */
3653         .quad local_label(misc_set_invalid) /* 00 even_fixnum  */
3654         .quad local_label(misc_set_invalid) /* 01 imm_0  */
3655         .quad local_label(misc_set_invalid) /* 02 immheader_0  */
3656         .quad _SPgvset /* 03 function  */
3657         .quad local_label(misc_set_invalid) /* 04 cons  */
3658         .quad local_label(misc_set_invalid) /* 05 imm_1  */
3659         .quad local_label(misc_set_invalid) /* 06 immheader_1  */
3660         .quad _SPgvset /* 07 catch_frame  */
3661         .quad local_label(misc_set_invalid) /* 08 odd_fixnum  */
3662         .quad local_label(misc_set_invalid) /* 09 imm_2  */
3663         .quad local_label(misc_set_u32) /* 0a code_vector  */
3664         .quad _SPgvset /* 0b slot_vector  */
3665         .quad local_label(misc_set_invalid) /* 0c misc  */
3666         .quad local_label(misc_set_invalid) /* 0d imm3  */
3667         .quad local_label(misc_set_invalid) /* 0e immheader_3  */
3668         .quad _SPgvset /* 0f ratio  */
3669        /* 10-1f  */
3670         .quad local_label(misc_set_invalid) /* 10 even_fixnum  */
3671         .quad local_label(misc_set_invalid) /* 11 imm_0  */
3672         .quad local_label(misc_set_invalid) /* 12 immheader_0  */
3673         .quad _SPgvset /* 13 symbol_0  */
3674         .quad local_label(misc_set_invalid) /* 14 cons  */
3675         .quad local_label(misc_set_invalid) /* 15 imm_1  */
3676         .quad local_label(misc_set_invalid) /* 16 immheader_1  */
3677         .quad _SPgvset /* 17 lisp_tread  */
3678         .quad local_label(misc_set_invalid) /* 18 odd_fixnum  */
3679         .quad local_label(misc_set_invalid) /* 19 imm_2  */
3680         .quad local_label(misc_set_u32) /* 1a xcode_vector  */
3681         .quad _SPgvset /* 1b instance  */
3682         .quad local_label(misc_set_invalid) /* 1c misc  */
3683         .quad local_label(misc_set_invalid) /* 1d imm3  */
3684         .quad local_label(misc_set_u64) /* 1e macptr  */
3685         .quad _SPgvset /* 1f complex  */
3686        /* 20-2f  */
3687         .quad local_label(misc_set_invalid) /* 20 even_fixnum  */
3688         .quad local_label(misc_set_invalid) /* 21 imm_0  */
3689         .quad local_label(misc_set_invalid) /* 22 immheader_0  */
3690         .quad local_label(misc_set_invalid) /* 23 nodeheader_0  */
3691         .quad local_label(misc_set_invalid) /* 24 cons  */
3692         .quad local_label(misc_set_invalid) /* 25 imm_1  */
3693         .quad local_label(misc_set_invalid) /* 26 immheader_1  */
3694         .quad _SPgvset /* 27 lock  */
3695         .quad local_label(misc_set_invalid) /* 28 odd_fixnum  */
3696         .quad local_label(misc_set_invalid) /* 29 imm_2  */
3697         .quad local_label(misc_set_u32) /* 2a bignum  */
3698         .quad _SPgvset /* 2b struct  */
3699         .quad local_label(misc_set_invalid) /* 2c misc  */
3700         .quad local_label(misc_set_invalid) /* 2d imm3  */
3701         .quad local_label(misc_set_u64) /* 2e dead_macptr  */
3702         .quad local_label(misc_set_invalid) /* 2f nodeheader_3  */
3703        /* 30-3f  */
3704         .quad local_label(misc_set_invalid) /* 30 even_fixnum  */
3705         .quad local_label(misc_set_invalid) /* 31 imm_0  */
3706         .quad local_label(misc_set_invalid) /* 32 immheader_0  */
3707         .quad local_label(misc_set_invalid) /* 33 nodeheader_0  */
3708         .quad local_label(misc_set_invalid) /* 34 cons  */
3709         .quad local_label(misc_set_invalid) /* 35 imm_1  */
3710         .quad local_label(misc_set_invalid) /* 36 immheader_1  */
3711         .quad _SPgvset /* 37 hash_vector  */
3712         .quad local_label(misc_set_invalid) /* 38 odd_fixnum  */
3713         .quad local_label(misc_set_invalid) /* 39 imm_2  */
3714         .quad local_label(misc_set_u32) /* 3a double_float  */
3715         .quad _SPgvset /* 3b istruct  */
3716         .quad local_label(misc_set_invalid) /* 3c misc  */
3717         .quad local_label(misc_set_invalid) /* 3d imm3  */
3718         .quad local_label(misc_set_invalid) /* 3e immheader_3  */
3719         .quad local_label(misc_set_invalid) /* 3f nodeheader_3  */
3720        /* 40-4f  */
3721         .quad local_label(misc_set_invalid) /* 40 even_fixnum  */
3722         .quad local_label(misc_set_invalid) /* 41 imm_0  */
3723         .quad local_label(misc_set_invalid) /* 42 immheader_0  */
3724         .quad local_label(misc_set_invalid) /* 43 nodeheader_0  */
3725         .quad local_label(misc_set_invalid) /* 44 cons  */
3726         .quad local_label(misc_set_invalid) /* 45 imm_1  */
3727         .quad local_label(misc_set_invalid) /* 46 immheader_1  */
3728         .quad _SPgvset /* 47 pool  */
3729         .quad local_label(misc_set_invalid) /* 48 odd_fixnum  */
3730         .quad local_label(misc_set_invalid) /* 49 imm_2  */
3731         .quad local_label(misc_set_invalid) /* 4a immheader_2  */
3732         .quad _SPgvset /* 4b value_cell_2  */
3733         .quad local_label(misc_set_invalid) /* 4c misc  */
3734         .quad local_label(misc_set_invalid) /* 4d imm3  */
3735         .quad local_label(misc_set_invalid) /* 4e immheader_3  */
3736         .quad local_label(misc_set_invalid) /* 4f nodeheader_3  */
3737        /* 50-5f  */
3738         .quad local_label(misc_set_invalid) /* 50 even_fixnum  */
3739         .quad local_label(misc_set_invalid) /* 51 imm_0  */
3740         .quad local_label(misc_set_invalid) /* 52 immheader_0  */
3741         .quad local_label(misc_set_invalid) /* 53 nodeheader_0  */
3742         .quad local_label(misc_set_invalid) /* 54 cons  */
3743         .quad local_label(misc_set_invalid) /* 55 imm_1  */
3744         .quad local_label(misc_set_invalid) /* 56 immheader_1  */
3745         .quad _SPgvset /* 57 weak  */
3746         .quad local_label(misc_set_invalid) /* 58 odd_fixnum  */
3747         .quad local_label(misc_set_invalid) /* 59 imm_2  */
3748         .quad local_label(misc_set_invalid) /* 5a immheader_2  */
3749         .quad _SPgvset /* 5b xfunction  */
3750         .quad local_label(misc_set_invalid) /* 5c misc  */
3751         .quad local_label(misc_set_invalid) /* 5d imm3  */
3752         .quad local_label(misc_set_invalid) /* 5e immheader_3  */
3753         .quad local_label(misc_set_invalid) /* 5f nodeheader_3  */
3754        /* 60-6f  */
3755         .quad local_label(misc_set_invalid) /* 60 even_fixnum  */
3756         .quad local_label(misc_set_invalid) /* 61 imm_0  */
3757         .quad local_label(misc_set_invalid) /* 62 immheader_0  */
3758         .quad local_label(misc_set_invalid) /* 63 nodeheader_0  */
3759         .quad local_label(misc_set_invalid) /* 64 cons  */
3760         .quad local_label(misc_set_invalid) /* 65 imm_1  */
3761         .quad local_label(misc_set_invalid) /* 66 immheader_1  */
3762         .quad _SPgvset /* 67 package  */
3763         .quad local_label(misc_set_invalid) /* 68 odd_fixnum  */
3764         .quad local_label(misc_set_invalid) /* 69 imm_2  */
3765         .quad local_label(misc_set_invalid) /* 6a immheader_2  */
3766         .quad local_label(misc_set_invalid) /* 6b nodeheader_2  */
3767         .quad local_label(misc_set_invalid) /* 6c misc  */
3768         .quad local_label(misc_set_invalid) /* 6d imm3  */
3769         .quad local_label(misc_set_invalid) /* 6e immheader_3  */
3770         .quad local_label(misc_set_invalid) /* 6f nodeheader_3  */
3771        /* 70-7f  */
3772         .quad local_label(misc_set_invalid) /* 70 even_fixnum  */
3773         .quad local_label(misc_set_invalid) /* 71 imm_0  */
3774         .quad local_label(misc_set_invalid) /* 72 immheader_0  */
3775         .quad local_label(misc_set_invalid) /* 73 nodeheader_0  */
3776         .quad local_label(misc_set_invalid) /* 74 cons  */
3777         .quad local_label(misc_set_invalid) /* 75 imm_1  */
3778         .quad local_label(misc_set_invalid) /* 76 immheader_1  */
3779         .quad local_label(misc_set_invalid) /* 77 nodeheader_1  */
3780         .quad local_label(misc_set_invalid) /* 78 odd_fixnum  */
3781         .quad local_label(misc_set_invalid) /* 79 imm_2  */
3782         .quad local_label(misc_set_invalid) /* 7a immheader_2  */
3783         .quad local_label(misc_set_invalid) /* 7b nodeheader_2  */
3784         .quad local_label(misc_set_invalid) /* 7c misc  */
3785         .quad local_label(misc_set_invalid) /* 7d imm3  */
3786         .quad local_label(misc_set_invalid) /* 7e immheader_3  */
3787         .quad local_label(misc_set_invalid) /* 7f nodeheader_3  */
3788        /* 80-8f  */
3789         .quad local_label(misc_set_invalid) /* 80 even_fixnum  */
3790         .quad local_label(misc_set_invalid) /* 81 imm_0  */
3791         .quad local_label(misc_set_invalid) /* 82 immheader_0  */
3792         .quad local_label(misc_set_invalid) /* 83 nodeheader_0  */
3793         .quad local_label(misc_set_invalid) /* 84 cons  */
3794         .quad local_label(misc_set_invalid) /* 85 imm_1  */
3795         .quad local_label(misc_set_invalid) /* 86 immheader_1  */
3796         .quad _SPgvset /* 87 arrayH  */
3797         .quad local_label(misc_set_invalid) /* 88 odd_fixnum  */
3798         .quad local_label(misc_set_invalid) /* 89 imm_2  */
3799         .quad local_label(misc_set_invalid) /* 8a immheader_2  */
3800         .quad _SPgvset /* 8b vectorH  */
3801         .quad local_label(misc_set_invalid) /* 8c misc  */
3802         .quad local_label(misc_set_invalid) /* 8d imm3  */
3803         .quad local_label(misc_set_invalid) /* 8e immheader_3  */
3804         .quad _SPgvset /* 8f simple_vector  */
3805        /* 90-9f  */
3806         .quad local_label(misc_set_invalid) /* 90 even_fixnum  */
3807         .quad local_label(misc_set_invalid) /* 91 imm_0  */
3808         .quad local_label(misc_set_s8) /* 92 s8  */
3809         .quad local_label(misc_set_invalid) /* 93 nodeheader_0  */
3810         .quad local_label(misc_set_invalid) /* 94 cons  */
3811         .quad local_label(misc_set_invalid) /* 95 imm_1  */
3812         .quad local_label(misc_set_s16) /* 96 immheader_1  */
3813         .quad local_label(misc_set_invalid) /* 97 nodeheader_1  */
3814         .quad local_label(misc_set_invalid) /* 98 odd_fixnum  */
3815         .quad local_label(misc_set_invalid) /* 99 imm_2  */
3816         .quad local_label(misc_set_s32) /* 9a s32  */
3817         .quad local_label(misc_set_invalid) /* 9b nodeheader_2  */
3818         .quad local_label(misc_set_invalid) /* 9c misc  */
3819         .quad local_label(misc_set_invalid) /* 9d imm3  */
3820         .quad local_label(misc_set_s64) /* 9e s64  */
3821         .quad local_label(misc_set_invalid) /* 9f nodeheader_3  */
3822        /* a0-af  */
3823         .quad local_label(misc_set_invalid) /* a0 even_fixnum  */
3824         .quad local_label(misc_set_invalid) /* a1 imm_0  */
3825         .quad local_label(misc_set_u8) /* a2 u8  */
3826         .quad local_label(misc_set_invalid) /* a3 nodeheader_0  */
3827         .quad local_label(misc_set_invalid) /* a4 cons  */
3828         .quad local_label(misc_set_invalid) /* a5 imm_1  */
3829         .quad local_label(misc_set_u16) /* a6 u16  */
3830         .quad local_label(misc_set_invalid) /* a7 nodeheader_1  */
3831         .quad local_label(misc_set_invalid) /* a8 odd_fixnum  */
3832         .quad local_label(misc_set_invalid) /* a9 imm_2  */
3833         .quad local_label(misc_set_u32) /* aa u32  */
3834         .quad local_label(misc_set_invalid) /* ab nodeheader_2  */
3835         .quad local_label(misc_set_invalid) /* ac misc  */
3836         .quad local_label(misc_set_invalid) /* ad imm3  */
3837         .quad local_label(misc_set_u64) /* ae u64  */
3838         .quad local_label(misc_set_invalid) /* af nodeheader_3  */
3839        /* b0-bf  */
3840         .quad local_label(misc_set_invalid) /* b0 even_fixnum  */
3841         .quad local_label(misc_set_invalid) /* b1 imm_0  */
3842         .quad local_label(misc_set_invalid) /* b2 immheader_0  */
3843         .quad local_label(misc_set_invalid) /* b3 nodeheader_0  */
3844         .quad local_label(misc_set_invalid) /* b4 cons  */
3845         .quad local_label(misc_set_invalid) /* b5 imm_1  */
3846         .quad local_label(misc_set_invalid) /* b6 immheader_1  */
3847         .quad local_label(misc_set_invalid) /* b7 nodeheader_1  */
3848         .quad local_label(misc_set_invalid) /* b8 odd_fixnum  */
3849         .quad local_label(misc_set_invalid) /* b9 imm_2  */
3850         .quad local_label(misc_set_single_float_vector) /* ba sf vector  */
3851         .quad local_label(misc_set_invalid) /* bb nodeheader_2  */
3852         .quad local_label(misc_set_invalid) /* bc misc  */
3853         .quad local_label(misc_set_invalid) /* bd imm3  */
3854         .quad local_label(misc_set_fixnum_vector) /* be fixnum_vector  */
3855         .quad local_label(misc_set_invalid) /* bf nodeheader_3  */
3856        /* c0-cf  */
3857         .quad local_label(misc_set_invalid) /* c0 even_fixnum  */
3858         .quad local_label(misc_set_invalid) /* c1 imm_0  */
3859         .quad local_label(misc_set_invalid) /* c2 immheader_0  */
3860         .quad local_label(misc_set_invalid) /* c3 nodeheader_0  */
3861         .quad local_label(misc_set_invalid) /* c4 cons  */
3862         .quad local_label(misc_set_invalid) /* c5 imm_1  */
3863         .quad local_label(misc_set_invalid) /* c6 immheader_1  */
3864         .quad local_label(misc_set_invalid) /* c7 nodeheader_1  */
3865         .quad local_label(misc_set_invalid) /* c8 odd_fixnum  */
3866         .quad local_label(misc_set_invalid) /* c9 imm_2  */
3867         .quad local_label(misc_set_invalid) /* ca immheader_2  */
3868         .quad local_label(misc_set_invalid) /* cb nodeheader_2  */
3869         .quad local_label(misc_set_invalid) /* cc misc  */
3870         .quad local_label(misc_set_invalid) /* cd imm3  */
3871         .quad local_label(misc_set_double_float_vector) /* ce double-float vector  */
3872         .quad local_label(misc_set_invalid) /* cf nodeheader_3  */
3873        /* d0-df  */
3874         .quad local_label(misc_set_invalid) /* d0 even_fixnum  */
3875         .quad local_label(misc_set_invalid) /* d1 imm_0  */
3876         .quad local_label(misc_set_string) /* d2 string  */
3877         .quad local_label(misc_set_invalid) /* d3 nodeheader_0  */
3878         .quad local_label(misc_set_invalid) /* d4 cons  */
3879         .quad local_label(misc_set_invalid) /* d5 imm_1  */
3880         .quad local_label(misc_set_invalid) /* d6 immheader_1  */
3881         .quad local_label(misc_set_invalid) /* d7 nodeheader_1  */
3882         .quad local_label(misc_set_invalid) /* d8 odd_fixnum  */
3883         .quad local_label(misc_set_invalid) /* d9 imm_2  */
3884         .quad local_label(misc_set_new_string) /* da new_string  */
3885         .quad local_label(misc_set_invalid) /* db nodeheader_2  */
3886         .quad local_label(misc_set_invalid) /* dc misc  */
3887         .quad local_label(misc_set_invalid) /* dd imm3  */
3888         .quad local_label(misc_set_invalid) /* de immheader_3  */
3889         .quad local_label(misc_set_invalid) /* df nodeheader_3  */
3890        /* e0-ef  */
3891         .quad local_label(misc_set_invalid) /* e0 even_fixnum  */
3892         .quad local_label(misc_set_invalid) /* e1 imm_0  */
3893         .quad local_label(misc_set_invalid) /* e2 immheader_0  */
3894         .quad local_label(misc_set_invalid) /* e3 nodeheader_0  */
3895         .quad local_label(misc_set_invalid) /* e4 cons  */
3896         .quad local_label(misc_set_invalid) /* e5 imm_1  */
3897         .quad local_label(misc_set_invalid) /* e6 immheader_1  */
3898         .quad local_label(misc_set_invalid) /* e7 nodeheader_1  */
3899         .quad local_label(misc_set_invalid) /* e8 odd_fixnum  */
3900         .quad local_label(misc_set_invalid) /* e9 imm_2  */
3901         .quad local_label(misc_set_invalid) /* ea immheader_2  */
3902         .quad local_label(misc_set_invalid) /* eb nodeheader_2  */
3903         .quad local_label(misc_set_invalid) /* ec misc  */
3904         .quad local_label(misc_set_invalid) /* ed imm3  */
3905         .quad local_label(misc_set_invalid) /* ee immheader_3  */
3906         .quad local_label(misc_set_invalid) /* ef nodeheader_3  */
3907        /* f0-ff  */
3908         .quad local_label(misc_set_invalid) /* f0 even_fixnum  */
3909         .quad local_label(misc_set_invalid) /* f1 imm_0  */
3910         .quad local_label(misc_set_invalid) /* f2 immheader_0  */
3911         .quad local_label(misc_set_invalid) /* f3 nodeheader_0  */
3912         .quad local_label(misc_set_invalid) /* f4 cons  */
3913         .quad local_label(misc_set_invalid) /* f5 imm_1  */
3914         .quad local_label(misc_set_bit_vector) /* f6 bit_vector  */
3915         .quad local_label(misc_set_invalid) /* f7 nodeheader_1  */
3916         .quad local_label(misc_set_invalid) /* f8 odd_fixnum  */
3917         .quad local_label(misc_set_invalid) /* f9 imm_2  */
3918         .quad local_label(misc_set_invalid) /* fa immheader_2  */
3919         .quad local_label(misc_set_invalid) /* fb nodeheader_2  */
3920         .quad local_label(misc_set_invalid) /* fc misc  */
3921         .quad local_label(misc_set_invalid) /* fd imm3  */
3922         .quad local_label(misc_set_invalid) /* fe immheader_3  */
3923         .quad local_label(misc_set_invalid) /* ff nodeheader_3  */
3924
3925local_label(misc_set_bit_vector):               
3926         __(lis imm3,0x8000)
3927         __(extract_unsigned_byte_bits_(imm0,arg_z,1))
3928         __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
3929         __(srdi imm0,arg_y,5+fixnumshift)
3930         __(srw imm3,imm3,imm1)
3931         __(bne local_label(misc_set_bad))
3932         __(cmpdi cr0,arg_z,0)
3933         __(sldi imm0,imm0,2)
3934         __(la imm0,misc_data_offset(imm0))
3935         __(lwzx imm2,arg_x,imm0)
3936         __(beq 1f)
3937         __(or imm2,imm3,imm2)
3938         __(stwx imm2,arg_x,imm0)
3939         __(blr)
39401:       __(andc imm2,imm2,imm3)
3941         __(stwx imm2,arg_x,imm0)
3942         __(blr)
3943local_label(misc_set_s16):
3944         __(extract_lisptag(imm2,arg_z))
3945         __(sldi imm0,arg_z,64-(16+fixnumshift))
3946         __(srdi imm1,arg_y,2)
3947         __(cmpdi cr7,imm2,tag_fixnum)
3948         __(sradi imm0,imm0,64-(16+fixnumshift))
3949         __(cmpd imm0,arg_z)
3950         __(la imm1,misc_data_offset(imm1))
3951         __(unbox_fixnum(imm0,arg_z))
3952         __(bne local_label(misc_set_bad))
3953         __(bne cr7,local_label(misc_set_bad))
3954         __(sthx imm0,arg_x,imm1)
3955         __(blr)
3956local_label(misc_set_u16):
3957         __(extract_unsigned_byte_bits_(imm0,arg_z,16))
3958         __(srdi imm1,arg_y,2)               
3959         __(unbox_fixnum(imm0,arg_z))
3960         __(la imm1,misc_data_offset(imm1))
3961         __(bne local_label(misc_set_bad))
3962         __(sthx imm0,arg_x,imm1)
3963         __(blr)
3964local_label(misc_set_single_float_vector):
3965         __(extract_fulltag(imm3,arg_z))
3966         __(srdi imm4,arg_y,1)
3967         __(cmpdi cr3,imm3,subtag_single_float)
3968         __(la imm4,misc_data_offset(imm4))
3969         __(bne cr3,local_label(misc_set_bad))
3970         __(srdi imm0,arg_z,32)
3971         __(stwx imm0,arg_x,imm4)
3972         __(blr)
3973local_label(misc_set_s32):
3974         __(extract_lisptag(imm2,arg_z))
3975         __(srdi imm4,arg_y,1)
3976         __(unbox_fixnum(imm0,arg_z))
3977         __(cmpdi imm2,tag_fixnum)
3978         __(sldi imm1,imm0,32)
3979         __(sradi imm1,imm1,32)
3980         __(la imm4,misc_data_offset(imm4))
3981         __(bne local_label(misc_set_bad))
3982         __(cmpd imm1,imm0)
3983         __(bne local_label(misc_set_bad))
3984         __(stwx imm0,arg_x,imm4)
3985         __(blr)
3986local_label(misc_set_u32):             
3987         __(extract_unsigned_byte_bits_(imm0,arg_z,32))
3988         __(srdi imm4,arg_y,1)
3989         __(la imm4,misc_data_offset(imm4))
3990         __(unbox_fixnum(imm0,arg_z))
3991         __(bne local_label(misc_set_bad))
3992         __(stwx imm0,arg_x,imm4)
3993         __(blr)
3994local_label(misc_set_new_string):
3995         __(extract_lowbyte(imm0,arg_z))
3996         __(srdi imm4,arg_y,1)
3997         __(cmpdi imm0,subtag_character)
3998         __(la imm4,misc_data_offset(imm4))
3999         __(srwi imm0,arg_z,charcode_shift)
4000         __(bne local_label(misc_set_bad))
4001         __(stwx imm0,arg_x,imm4)
4002         __(blr)
4003local_label(misc_set_string):     
4004         __(extract_lowbyte(imm0,arg_z))               
4005         __(srdi imm4,arg_y,3)
4006         __(cmpdi imm0,subtag_character)
4007         __(la imm4,misc_data_offset(imm4))
4008         __(bne cr0,local_label(misc_set_bad))
4009         __(srwi imm0,arg_z,charcode_shift)
4010         __(stbx imm0,arg_x,imm4)
4011         __(blr)
4012local_label(misc_set_s8):     
4013         __(extract_lisptag(imm2,arg_z))
4014         __(unbox_fixnum(imm0,arg_z))
4015         __(cmpdi cr2,imm2,tag_fixnum)
4016         __(srdi imm4,arg_y,3)
4017         __(sldi imm1,imm0,56)
4018         __(sradi imm1,imm1,56)
4019         __(cmpd imm1,imm0)
4020         __(bne cr2,local_label(misc_set_bad))
4021         __(la imm4,misc_data_offset(imm4))
4022         __(bne local_label(misc_set_bad))
4023         __(stbx imm0,arg_x,imm4)
4024         __(blr)
4025local_label(misc_set_u8):     
4026         __(extract_unsigned_byte_bits_(imm0,arg_z,8))
4027         __(srdi imm4,arg_y,3)
4028         __(unbox_fixnum(imm0,arg_z))
4029         __(la imm4,misc_data_offset(imm4))
4030         __(bne local_label(misc_set_bad))
4031         __(stbx imm0,arg_x,imm4)
4032         __(blr)
4033local_label(misc_set_u64):
4034         __(extract_lisptag(imm0,arg_z))
4035         __(cmpdi cr0,arg_z,0)
4036         __(cmpdi cr7,imm0,0)
4037         __(la imm4,misc_data_offset(arg_y))
4038         __(bne cr7,local_label(setu64_maybe_bignum))
4039         __(unbox_fixnum(imm0,arg_z))
4040         __(blt cr0,local_label(misc_set_bad))
4041         __(stdx imm0,arg_x,imm4)
4042         __(blr)
4043local_label(setu64_maybe_bignum):
4044         __(bne cr6,local_label(misc_set_bad))
4045         __(getvheader(imm1,arg_z))
4046         __(ld imm0,misc_data_offset(arg_z))
4047         __(rotldi imm0,imm0,32)
4048         __(cmpdi cr2,imm1,two_digit_bignum_header)
4049         __(cmpdi cr3,imm1,three_digit_bignum_header)
4050         __(cmpdi cr0,imm0,0)
4051         __(beq cr2,1f)
4052         __(bne cr3,local_label(misc_set_bad))
4053         __(lwz imm3,misc_data_offset+8(arg_z))
4054         __(cmpwi cr0,imm3,0)
4055         __(bne cr0,local_label(misc_set_bad))
4056         __(stdx imm0,arg_x,imm4)
4057         __(blr)
40581:       __(blt cr0,local_label(misc_set_bad))
4059         __(stdx imm0,arg_x,imm4)
4060         __(blr)
4061local_label(misc_set_double_float_vector):
4062         __(extract_typecode(imm0,arg_z))
4063         __(la imm4,misc_data_offset(arg_y))
4064         __(cmpdi imm0,subtag_double_float)
4065         __(bne local_label(misc_set_bad))
4066         __(ld imm0,misc_dfloat_offset(arg_z))
4067         __(stdx imm0,arg_x,imm4)
4068         __(blr)
4069local_label(misc_set_fixnum_vector):
4070         __(extract_lisptag(imm2,arg_z))
4071         __(unbox_fixnum(imm0,arg_z))
4072         __(cmpdi cr2,imm2,tag_fixnum)
4073         __(la imm4,misc_data_offset(arg_y))
4074         __(bne cr2,local_label(misc_set_bad))
4075         __(stdx imm0,arg_x,imm4)
4076         __(blr)
4077local_label(misc_set_s64):
4078         __(extract_lisptag(imm2,arg_z))
4079         __(extract_fulltag(imm3,arg_z))
4080         __(unbox_fixnum(imm0,arg_z))
4081         __(cmpdi cr2,imm2,tag_fixnum)
4082         __(cmpdi cr6,imm3,fulltag_misc)
4083         __(la imm4,misc_data_offset(arg_y))
4084         __(bne cr2,local_label(sets64_maybe_bignum))
4085         __(stdx imm0,arg_x,imm4)
4086         __(blr)
4087local_label(sets64_maybe_bignum):       
4088         __(bne cr6,local_label(misc_set_bad))
4089         __(getvheader(imm1,arg_z))
4090         __(ld imm0,misc_data_offset(arg_z))
4091         __(cmpdi cr1,imm1,two_digit_bignum_header)
4092         __(rotldi imm0,imm0,32)
4093         __(bne cr1,local_label(misc_set_bad))
4094         __(stdx imm0,arg_x,imm4)
4095         __(blr)
4096local_label(misc_set_bad):
4097         __(mr arg_y,arg_z)
4098         __(mr arg_z,arg_x)
4099         __(li arg_x,XNOTELT)
4100         __(set_nargs(3))
4101         __(b _SPksignalerr)
4102local_label(misc_set_invalid): 
4103         __(li temp0,XSETBADVEC)       
4104         __(set_nargs(4))
4105         __(vpush(temp0))
4106         __(b _SPksignalerr)       
4107        __else
4108         __(slwi imm1,imm1,2)
4109         __(li imm0,LO(local_label(misc_set_jmp)))
4110         __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
4111         __(lwzx imm0,imm0,imm1)
4112         __(mtctr imm0)
4113         __(bctr)
4114local_label(misc_set_jmp):             
4115        /* 00-0f  */
4116         .long local_label(misc_set_invalid) /* 00 even_fixnum  */
4117         .long local_label(misc_set_invalid) /* 01 cons  */
4118         .long local_label(misc_set_invalid) /* 02 nodeheader  */
4119         .long local_label(misc_set_invalid) /* 03 imm  */
4120         .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
4121         .long local_label(misc_set_invalid) /* 05 nil  */
4122         .long local_label(misc_set_invalid) /* 06 misc  */
4123         .long local_label(misc_set_u32) /* 07 bignum  */
4124         .long local_label(misc_set_invalid) /* 08 even_fixnum  */
4125         .long local_label(misc_set_invalid) /* 09 cons  */
4126         .long _SPgvset /* 0a ratio  */
4127         .long local_label(misc_set_invalid) /* 0b imm  */
4128         .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
4129         .long local_label(misc_set_invalid) /* 0d nil  */
4130         .long local_label(misc_set_invalid) /* 0e misc  */
4131         .long local_label(misc_set_u32) /* 0f single_float  */
4132        /* 10-1f  */
4133         .long local_label(misc_set_invalid) /* 10 even_fixnum  */
4134         .long local_label(misc_set_invalid) /* 11 cons  */
4135         .long local_label(misc_set_invalid) /* 12 nodeheader  */
4136         .long local_label(misc_set_invalid) /* 13 imm  */
4137         .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
4138         .long local_label(misc_set_invalid) /* 15 nil  */
4139         .long local_label(misc_set_invalid) /* 16 misc  */
4140         .long local_label(misc_set_u32) /* 17 double_float  */
4141         .long local_label(misc_set_invalid) /* 18 even_fixnum  */
4142         .long local_label(misc_set_invalid) /* 19 cons  */
4143         .long _SPgvset /* 1a complex  */
4144         .long local_label(misc_set_invalid) /* 1b imm  */
4145         .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
4146         .long local_label(misc_set_invalid) /* 1d nil  */
4147         .long local_label(misc_set_invalid) /* 1e misc  */
4148         .long local_label(misc_set_u32) /* 1f macptr  */
4149        /* 20-2f  */
4150         .long local_label(misc_set_invalid) /* 20 even_fixnum  */
4151         .long local_label(misc_set_invalid) /* 21 cons  */
4152         .long _SPgvset /* 22 catch_frame  */
4153         .long local_label(misc_set_invalid) /* 23 imm  */
4154         .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
4155         .long local_label(misc_set_invalid) /* 25 nil  */
4156         .long local_label(misc_set_invalid) /* 26 misc  */
4157         .long local_label(misc_set_u32) /* 27 dead_macptr  */
4158         .long local_label(misc_set_invalid) /* 28 even_fixnum  */
4159         .long local_label(misc_set_invalid) /* 29 cons  */
4160         .long _SPgvset /* 2a function  */
4161         .long local_label(misc_set_invalid) /* 2b imm  */
4162         .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
4163         .long local_label(misc_set_invalid) /* 2d nil  */
4164         .long local_label(misc_set_invalid) /* 2e misc  */
4165         .long local_label(misc_set_u32) /* 2f code_vector  */
4166        /* 30-3f  */
4167         .long local_label(misc_set_invalid) /* 30 even_fixnum  */
4168         .long local_label(misc_set_invalid) /* 31 cons  */
4169         .long _SPgvset /* 32 lisp_thread  */
4170         .long local_label(misc_set_invalid) /* 33 imm  */
4171         .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
4172         .long local_label(misc_set_invalid) /* 35 nil  */
4173         .long local_label(misc_set_invalid) /* 36 misc  */
4174         .long local_label(misc_set_u32) /* 37 creole  */
4175         .long local_label(misc_set_invalid) /* 38 even_fixnum  */
4176         .long local_label(misc_set_invalid) /* 39 cons  */
4177         .long _SPgvset /* 3a symbol  */
4178         .long local_label(misc_set_invalid) /* 3b imm  */
4179         .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
4180         .long local_label(misc_set_invalid) /* 3d nil  */
4181         .long local_label(misc_set_invalid) /* 3e misc  */
4182         .long local_label(misc_set_u32) /* 3f xcode_vector  */
4183        /* 40-4f  */
4184         .long local_label(misc_set_invalid) /* 40 even_fixnum  */
4185         .long local_label(misc_set_invalid) /* 41 cons  */
4186         .long _SPgvset /* 42 lock  */
4187         .long local_label(misc_set_invalid) /* 43 imm  */
4188         .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
4189         .long local_label(misc_set_invalid) /* 45 nil  */
4190         .long local_label(misc_set_invalid) /* 46 misc  */
4191         .long local_label(misc_set_invalid) /* 47 immheader  */
4192         .long local_label(misc_set_invalid) /* 48 even_fixnum  */
4193         .long local_label(misc_set_invalid) /* 49 cons  */
4194         .long _SPgvset /* 4a hash_vector  */
4195         .long local_label(misc_set_invalid) /* 4b imm  */
4196         .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
4197         .long local_label(misc_set_invalid) /* 4d nil  */
4198         .long local_label(misc_set_invalid) /* 4e misc  */
4199         .long local_label(misc_set_invalid) /* 4f immheader  */
4200        /* 50-5f  */
4201         .long local_label(misc_set_invalid) /* 50 even_fixnum  */
4202         .long local_label(misc_set_invalid) /* 51 cons  */
4203         .long _SPgvset /* 52 pool  */
4204         .long local_label(misc_set_invalid) /* 53 imm  */
4205         .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
4206         .long local_label(misc_set_invalid) /* 55 nil  */
4207         .long local_label(misc_set_invalid) /* 56 misc  */
4208         .long local_label(misc_set_invalid) /* 57 immheader  */
4209         .long local_label(misc_set_invalid) /* 58 even_fixnum  */
4210         .long local_label(misc_set_invalid) /* 59 cons  */
4211         .long _SPgvset /* 5a weak  */
4212         .long local_label(misc_set_invalid) /* 5b imm  */
4213         .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
4214         .long local_label(misc_set_invalid) /* 5d nil  */
4215         .long local_label(misc_set_invalid) /* 5e misc  */
4216         .long local_label(misc_set_invalid) /* 5f immheader  */
4217        /* 60-6f  */
4218         .long local_label(misc_set_invalid) /* 60 even_fixnum  */
4219         .long local_label(misc_set_invalid) /* 61 cons  */
4220         .long _SPgvset /* 62 package  */
4221         .long local_label(misc_set_invalid) /* 63 imm  */
4222         .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
4223         .long local_label(misc_set_invalid) /* 65 nil  */
4224         .long local_label(misc_set_invalid) /* 66 misc  */
4225         .long local_label(misc_set_invalid) /* 67 immheader  */
4226         .long local_label(misc_set_invalid) /* 68 even_fixnum  */
4227         .long local_label(misc_set_invalid) /* 69 cons  */
4228         .long _SPgvset /* 6a slot_vector  */
4229         .long local_label(misc_set_invalid) /* 6b imm  */
4230         .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
4231         .long local_label(misc_set_invalid) /* 6d nil  */
4232         .long local_label(misc_set_invalid) /* 6e misc  */
4233         .long local_label(misc_set_invalid) /* 6f immheader  */
4234        /* 70-7f  */
4235         .long local_label(misc_set_invalid) /* 70 even_fixnum  */
4236         .long local_label(misc_set_invalid) /* 71 cons  */
4237         .long _SPgvset /* 72 instance  */
4238         .long local_label(misc_set_invalid) /* 73 imm  */
4239         .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
4240         .long local_label(misc_set_invalid) /* 75 nil  */
4241         .long local_label(misc_set_invalid) /* 76 misc  */
4242         .long local_label(misc_set_invalid) /* 77 immheader  */
4243         .long local_label(misc_set_invalid) /* 78 even_fixnum  */
4244         .long local_label(misc_set_invalid) /* 79 cons  */
4245         .long _SPgvset /* 7a struct  */
4246         .long local_label(misc_set_invalid) /* 7b imm  */
4247         .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
4248         .long local_label(misc_set_invalid) /* 7d nil  */
4249         .long local_label(misc_set_invalid) /* 7e misc  */
4250         .long local_label(misc_set_invalid) /* 7f immheader  */
4251        /* 80-8f  */
4252         .long local_label(misc_set_invalid) /* 80 even_fixnum  */
4253         .long local_label(misc_set_invalid) /* 81 cons  */
4254         .long _SPgvset /* 82 istruct  */
4255         .long local_label(misc_set_invalid) /* 83 imm  */
4256         .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
4257         .long local_label(misc_set_invalid) /* 85 nil  */
4258         .long local_label(misc_set_invalid) /* 86 misc  */
4259         .long local_label(misc_set_invalid) /* 87 immheader  */
4260         .long local_label(misc_set_invalid) /* 88 even_fixnum  */
4261         .long local_label(misc_set_invalid) /* 89 cons  */
4262         .long _SPgvset /* 8a value_cell  */
4263         .long local_label(misc_set_invalid) /* 8b imm  */
4264         .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
4265         .long local_label(misc_set_invalid) /* 8d nil  */
4266         .long local_label(misc_set_invalid) /* 8e misc  */
4267         .long local_label(misc_set_invalid) /* 8f immheader  */
4268        /* 90-9f  */
4269         .long local_label(misc_set_invalid) /* 90 even_fixnum  */
4270         .long local_label(misc_set_invalid) /* 91 cons  */
4271         .long _SPgvset /* 92 xfunction  */
4272         .long local_label(misc_set_invalid) /* 93 imm  */
4273         .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
4274         .long local_label(misc_set_invalid) /* 95 nil  */
4275         .long local_label(misc_set_invalid) /* 96 misc  */
4276         .long local_label(misc_set_invalid) /* 97 immheader  */
4277         .long local_label(misc_set_invalid) /* 98 even_fixnum  */
4278         .long local_label(misc_set_invalid) /* 99 cons  */
4279         .long _SPgvset /* 9a arrayH  */
4280         .long local_label(misc_set_invalid) /* 9b imm  */
4281         .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
4282         .long local_label(misc_set_invalid) /* 9d nil  */
4283         .long local_label(misc_set_invalid) /* 9e misc  */
4284         .long local_label(misc_set_invalid) /* 9f immheader  */
4285        /* a0-af  */
4286         .long local_label(misc_set_invalid) /* a0 even_fixnum  */
4287         .long local_label(misc_set_invalid) /* a1 cons  */
4288         .long _SPgvset /* a2 vectorH  */
4289         .long local_label(misc_set_invalid) /* a3 imm  */
4290         .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
4291         .long local_label(misc_set_invalid) /* a5 nil  */
4292         .long local_label(misc_set_invalid) /* a6 misc  */
4293         .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
4294         .long local_label(misc_set_invalid) /* a8 even_fixnum  */
4295         .long local_label(misc_set_invalid) /* a9 cons  */
4296         .long _SPgvset /* aa vectorH  */
4297         .long local_label(misc_set_invalid) /* ab imm  */
4298         .long local_label(misc_set_invalid) /* ac odd_fixnum  */
4299         .long local_label(misc_set_invalid) /* ad nil  */
4300         .long local_label(misc_set_invalid) /* ae misc  */
4301         .long local_label(misc_set_u32) /* af u32  */
4302        /* b0-bf  */
4303         .long local_label(misc_set_invalid) /* b0 even_fixnum  */
4304         .long local_label(misc_set_invalid) /* b1 cons  */
4305         .long local_label(misc_set_invalid) /* b2 node  */
4306         .long local_label(misc_set_invalid) /* b3 imm  */
4307         .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
4308         .long local_label(misc_set_invalid) /* b5 nil  */
4309         .long local_label(misc_set_invalid) /* b6 misc  */
4310         .long local_label(misc_set_s32) /* b7 s32  */
4311         .long local_label(misc_set_invalid) /* b8 even_fixnum  */
4312         .long local_label(misc_set_invalid) /* b9 cons  */
4313         .long local_label(misc_set_invalid) /* ba nodeheader  */
4314         .long local_label(misc_set_invalid) /* bb imm  */
4315         .long local_label(misc_set_invalid) /* bc odd_fixnum  */
4316         .long local_label(misc_set_invalid) /* bd nil  */
4317         .long local_label(misc_set_invalid) /* be misc  */
4318         .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
4319        /* c0-cf  */
4320         .long local_label(misc_set_invalid) /* c0 even_fixnum  */
4321         .long local_label(misc_set_invalid) /* c1 cons  */
4322         .long local_label(misc_set_invalid) /* c2 nodeheader  */
4323         .long local_label(misc_set_invalid) /* c3 imm  */
4324         .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
4325         .long local_label(misc_set_invalid) /* c5 nil  */
4326         .long local_label(misc_set_invalid) /* c6 misc  */
4327         .long local_label(misc_set_new_string) /* c7 new_string  */
4328         .long local_label(misc_set_invalid) /* c8 even_fixnum  */
4329         .long local_label(misc_set_invalid) /* c9 cons  */
4330         .long local_label(misc_set_invalid) /* ca nodeheader  */
4331         .long local_label(misc_set_invalid) /* cb imm  */
4332         .long local_label(misc_set_invalid) /* cc odd_fixnum  */
4333         .long local_label(misc_set_invalid) /* cd nil  */
4334         .long local_label(misc_set_invalid) /* ce misc  */
4335         .long local_label(misc_set_u8) /* cf u8  */
4336        /* d0-df  */
4337         .long local_label(misc_set_invalid) /* d0 even_fixnum  */
4338         .long local_label(misc_set_invalid) /* d1 cons  */
4339         .long local_label(misc_set_invalid) /* d2 nodeheader  */
4340         .long local_label(misc_set_invalid) /* d3 imm  */
4341         .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
4342         .long local_label(misc_set_invalid) /* d5 nil  */
4343         .long local_label(misc_set_invalid) /* d6 misc  */
4344         .long local_label(misc_set_s8) /* d7 s8  */
4345         .long local_label(misc_set_invalid) /* d8 even_fixnum  */
4346         .long local_label(misc_set_invalid) /* d9 cons  */
4347         .long local_label(misc_set_invalid) /* da nodeheader  */
4348         .long local_label(misc_set_invalid) /* db imm  */
4349         .long local_label(misc_set_invalid) /* dc odd_fixnum  */
4350         .long local_label(misc_set_invalid) /* dd nil  */
4351         .long local_label(misc_set_invalid) /* de misc  */
4352         .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
4353        /* e0-ef  */
4354         .long local_label(misc_set_invalid) /* e0 even_fixnum  */
4355         .long local_label(misc_set_invalid) /* e1 cons  */
4356         .long local_label(misc_set_invalid) /* e2 nodeheader  */
4357         .long local_label(misc_set_invalid) /* e3 imm  */
4358         .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
4359         .long local_label(misc_set_invalid) /* e5 nil  */
4360         .long local_label(misc_set_invalid) /* e6 misc  */
4361         .long local_label(misc_set_u16) /* e7 u16  */
4362         .long local_label(misc_set_invalid) /* e8 even_fixnum  */
4363         .long local_label(misc_set_invalid) /* e9 cons  */
4364         .long local_label(misc_set_invalid) /* ea nodeheader  */
4365         .long local_label(misc_set_invalid) /* eb imm  */
4366         .long local_label(misc_set_invalid) /* ec odd_fixnum  */
4367         .long local_label(misc_set_invalid) /* ed nil  */
4368         .long local_label(misc_set_invalid) /* ee misc  */
4369         .long local_label(misc_set_s16) /* ef s16  */
4370        /* f0-ff  */
4371         .long local_label(misc_set_invalid) /* f0 even_fixnum  */
4372         .long local_label(misc_set_invalid) /* f1 cons  */
4373         .long local_label(misc_set_invalid) /* f2 nodeheader  */
4374         .long local_label(misc_set_invalid) /* f3 imm  */
4375         .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
4376         .long local_label(misc_set_invalid) /* f5 nil  */
4377         .long local_label(misc_set_invalid) /* f6 misc  */
4378         .long local_label(misc_set_double_float_vector) /* f7 df vector  */
4379         .long local_label(misc_set_invalid) /* f8 even_fixnum  */
4380         .long local_label(misc_set_invalid) /* f9 cons  */
4381         .long local_label(misc_set_invalid) /* fa nodeheader  */
4382         .long local_label(misc_set_invalid) /* fb imm  */
4383         .long local_label(misc_set_invalid) /* fc odd_fixnum  */
4384         .long local_label(misc_set_invalid) /* fd nil  */
4385         .long local_label(misc_set_invalid) /* fe misc  */
4386         .long local_label(misc_set_bit_vector) /* ff bit_vector  */
4387
4388local_label(misc_set_u32):       
4389        /* Either a non-negative fixnum, a positiveone-digit bignum, */
4390        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
4391         __(extract_lisptag(imm2,arg_z))
4392         __(srawi. imm1,arg_z,fixnum_shift)
4393         __(cmpwi cr5,imm2,tag_fixnum)         
4394         __(la imm0,misc_data_offset(arg_y))
4395         __(cmpwi cr7,imm2,tag_misc)
4396         __(bne cr5,local_label(set_not_fixnum_u32))
4397         __(blt- cr0,local_label(set_bad))
4398local_label(set_set32):         
4399         __(stwx imm1,arg_x,imm0)
4400         __(blr)
4401local_label(set_not_fixnum_u32):
4402         __(bne cr7,local_label(set_bad))
4403         __(extract_header(imm2,arg_z))
4404         __(cmpri(cr0,imm2,one_digit_bignum_header))
4405         __(cmpri(cr1,imm2,two_digit_bignum_header))
4406         __(vrefr(imm1,arg_z,0))
4407         __(cmpri(cr2,imm1,0))
4408         __(bne cr0,local_label(set_not_1_digit_u32))
4409         __(bge cr2,local_label(set_set32))
4410         __(b local_label(set_bad))
4411local_label(set_not_1_digit_u32):
4412         __(bne- cr1,local_label(set_bad))
4413         __(vrefr(imm2,arg_z,1))
4414         __(cmpri(cr0,imm2,0))
4415         __(bne- cr1,local_label(set_bad))
4416         __(beq cr0,local_label(set_set32))
4417local_label(set_bad):
4418        /* arg_z does not match the array-element-type of arg_x.  */
4419         __(mr arg_y,arg_z)
4420         __(mr arg_z,arg_x)
4421         __(li arg_x,XNOTELT)
4422         __(set_nargs(3))
4423         __(b _SPksignalerr)
4424local_label(misc_set_fixnum_vector):   
4425         __(extract_lisptag(imm2,arg_z))
4426         __(la imm0,misc_data_offset(arg_y))
4427         __(cmpwi cr5,imm2,tag_fixnum)
4428         __(unbox_fixnum(imm1,arg_z))
4429         __(bne cr5,local_label(set_bad))
4430         __(stwx imm1,arg_x,imm0)
4431         __(blr)
4432local_label(misc_set_new_string):   
4433         __(clrlwi imm2,arg_z,ncharcodebits)
4434         __(la imm0,misc_data_offset(arg_y))
4435         __(cmpwi cr5,imm2,subtag_character)
4436         __(srwi imm1,arg_z,charcode_shift)
4437         __(bne cr5,local_label(set_bad))
4438         __(stwx imm1,arg_x,imm0)
4439         __(blr)
4440local_label(misc_set_s32):
4441         __(extract_lisptag(imm2,arg_z))
4442         __(cmpwi cr5,imm2,tag_fixnum)
4443         __(cmpwi cr7,imm2,tag_misc)
4444         __(la imm0,misc_data_offset(arg_y))
4445         __(unbox_fixnum(imm1,arg_z))
4446         __(beq cr5,local_label(set_set32))
4447         __(bne cr7,local_label(set_bad))
4448         __(extract_header(imm2,arg_z))
4449         __(cmpri(cr0,imm2,one_digit_bignum_header))
4450         __(vrefr(imm1,arg_z,0))
4451         __(bne- cr0,local_label(set_bad))
4452         __(strx(imm1,arg_x,imm0))
4453         __(blr)
4454local_label(misc_set_single_float_vector):
4455         __(extract_lisptag(imm2,arg_z))
4456         __(cmpwi cr7,imm2,tag_misc)
4457         __(la imm0,misc_data_offset(arg_y))
4458         __(bne- cr7,local_label(set_bad))
4459         __(extract_header(imm2,arg_z))
4460         __(cmpri(cr0,imm2,single_float_header))
4461         __(bne- cr0,local_label(set_bad))
4462         __(ldr(imm1,single_float.value(arg_z)))
4463         __(strx(imm1,arg_x,imm0))
4464         __(blr)
4465local_label(misc_set_u8):               
4466         __(extract_lisptag(imm2,arg_z))
4467         __(srwi imm0,arg_y,2)
4468         __(la imm0,misc_data_offset(imm0))
4469         __(extract_unsigned_byte_bits_(imm1,arg_z,8))
4470         __(unbox_fixnum(imm1,arg_z))
4471         __(bne- cr0,local_label(set_bad))
4472         __(stbx imm1,arg_x,imm0)
4473         __(blr)
4474local_label(misc_set_old_string):
4475         __(srwi imm0,arg_y,2)
4476         __(extract_lowbyte(imm2,arg_z))
4477         __(cmpri(cr2,imm2,subtag_character))
4478         __(la imm0,misc_data_offset(imm0))
4479         __(srwi imm1,arg_z,charcode_shift)
4480         __(bne- cr2,local_label(set_bad))
4481         __(stbx imm1,arg_x,imm0)
4482         __(blr)
4483local_label(misc_set_s8):
4484         __(extract_lisptag(imm2,arg_z))
4485         __(srwi imm0,arg_y,2)
4486         __(unbox_fixnum(imm1,arg_z))
4487         __(la imm0,misc_data_offset(imm0))
4488         __(cmpwi cr5,imm2,tag_fixnum)
4489         __(extsb imm2,imm1)
4490         __(cmpw cr0,imm2,imm1)
4491         __(bne- cr5,local_label(set_bad))
4492         __(bne- cr0,local_label(set_bad))
4493         __(stbx imm1,arg_x,imm0)
4494         __(blr)
4495local_label(misc_set_u16):         
4496         __(srwi imm0,arg_y,1)
4497         __(extract_unsigned_byte_bits_(imm1,arg_z,16))
4498         __(unbox_fixnum(imm1,arg_z))
4499         __(la imm0,misc_data_offset(imm0))
4500         __(bne- cr0,local_label(set_bad))
4501         __(sthx imm1,arg_x,imm0)
4502         __(blr)
4503local_label(misc_set_s16):
4504         __(extract_lisptag(imm2,arg_z))
4505         __(srwi imm0,arg_y,1)
4506         __(unbox_fixnum(imm1,arg_z))
4507         __(cmpwi cr5,imm2,tag_fixnum)
4508         __(la imm0,misc_data_offset(imm0))
4509         __(extsh imm2,imm1)
4510         __(cmpw cr0,imm2,imm1)
4511         __(bne- cr5,local_label(set_bad))
4512         __(bne- cr0,local_label(set_bad))
4513         __(sthx imm1,arg_x,imm0)
4514         __(blr)
4515local_label(misc_set_bit_vector):       
4516         __(cmplwi cr2,arg_z,fixnumone)   /* nothing not a (boxed) bit   */
4517         __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
4518         __(extlwi imm2,arg_z,1,31-fixnumshift)
4519         __(srw imm2,imm2,imm1)
4520         __(lis imm3,0x8000)
4521         __(rlwinm imm0,arg_y,32-5,5,31-fixnumshift)
4522         __(la imm0,misc_data_offset(imm0))
4523         __(srw imm3,imm3,imm1)
4524         __(bgt- cr2,local_label(set_bad))
4525         __(lwzx imm1,arg_x,imm0)
4526         __(andc imm1,imm1,imm3)
4527         __(or imm1,imm1,imm2)
4528         __(stwx imm1,arg_x,imm0)
4529         __(blr)
4530
4531local_label(misc_set_double_float_vector):
4532         __(extract_lisptag(imm2,arg_z))
4533         __(slwi imm0,arg_y,1)
4534         __(cmpwi cr7,imm2,tag_misc)
4535         __(la imm0,misc_dfloat_offset(imm0))
4536         __(bne- cr7,local_label(set_bad))
4537         __(extract_header(imm2,arg_z))
4538         __(cmpri(cr0,imm2,double_float_header))
4539         __(bne- cr0,local_label(set_bad))
4540         __(lwz imm1,double_float.value(arg_z))
4541         __(lwz imm2,double_float.value+4(arg_z))
4542         __(stwx imm1,arg_x,imm0)
4543         __(la imm0,4(imm0))
4544         __(stwx imm2,arg_x,imm0)
4545         __(blr)
4546local_label(misc_set_invalid): 
4547         __(li temp0,XSETBADVEC)       
4548         __(set_nargs(4))
4549         __(vpush(temp0))
4550         __(b _SPksignalerr)               
4551        __endif
4552
4553/* misc_set (vector index newval).  Pretty damned similar to  */
4554/* misc_ref, as one might imagine.  */
4555
4556_spentry(misc_set)
4557        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
4558        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
4559        __(vector_length(imm0,arg_x,imm1))
4560        __(trlge(arg_y,imm0))
4561        __(extract_lowbyte(imm1,imm1))
4562        __(b local_label(misc_set_common))
4563       
4564/* "spread" the lexpr in arg_z.  */
4565/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
4566_spentry(spread_lexprz)
4567        __(ldr(imm0,0(arg_z)))
4568        __(cmpri(cr3,imm0,3<<fixnumshift))
4569        __(cmpri(cr4,imm0,2<<fixnumshift))
4570        __(add imm1,arg_z,imm0)
4571        __(cmpri(cr0,imm0,0))
4572        __(add nargs,nargs,imm0)
4573        __(cmpri(cr1,nargs,0))
4574        __(cmpri(cr2,nargs,2<<fixnumshift))
4575        __(la imm1,node_size(imm1))
4576        __(bge cr3,9f)
4577        __(beq cr4,2f)
4578        __(bne cr0,1f)
4579        /* lexpr count was 0; vpop the arg regs that  */
4580        /* were vpushed by the caller  */
4581        __(beqlr cr1)
4582        __(vpop(arg_z))
4583        __(bltlr cr2)
4584        __(vpop(arg_y))
4585        __(beqlr cr2)
4586        __(vpop(arg_x))
4587        __(blr)
4588
4589        /* vpush args from the lexpr until we have only  */
4590        /* three left, then assign them to arg_x, arg_y,  */
4591        /* and arg_z.  */
45928:
4593        __(cmpri(cr3,imm0,4<<fixnumshift))
4594        __(subi imm0,imm0,fixnumone)
4595        __(ldru(arg_z,-node_size(imm1)))
4596        __(vpush(arg_z))
45979:
4598        __(bne cr3,8b)
4599        __(ldr(arg_x,-node_size*1(imm1)))
4600        __(ldr(arg_y,-node_size*2(imm1)))
4601        __(ldr(arg_z,-node_size*3(imm1)))
4602        __(blr)
4603
4604        /* lexpr count is two: set arg_y, arg_z from the  */
4605        /* lexpr, maybe vpop arg_x  */
46062:     
4607        __(ldr(arg_y,-node_size*1(imm1)))
4608        __(ldr(arg_z,-node_size*2(imm1)))
4609        __(beqlr cr2)           /* return if (new) nargs = 2  */
4610        __(vpop(arg_x))
4611        __(blr)
4612
4613        /* lexpr count is one: set arg_z from the lexpr,  */
4614        /* maybe vpop arg_y, arg_x  */
46151:     
4616        __(ldr(arg_z,-node_size(imm1)))
4617        __(bltlr cr2)           /* return if (new) nargs < 2  */
4618        __(vpop(arg_y))
4619        __(beqlr cr2)           /* return if (new) nargs = 2  */
4620        __(vpop(arg_x))
4621        __(blr)
4622       
4623               
4624_spentry(reset)
4625        .globl _SPthrow
4626        __(nop)
4627        __(ref_nrs_value(temp0,toplcatch))
4628        __(li temp1,XSTKOVER)
4629        __(vpush(temp0))
4630        __(vpush(temp1))
4631        __(set_nargs(1))
4632        __(b _SPthrow)
4633
4634       
4635/* "slide" nargs worth of values up the vstack.  IMM0 contains  */
4636/* the difference between the current VSP and the target.  */
4637_spentry(mvslide)
4638        __(cmpri(cr0,nargs,0))
4639        __(mr imm3,nargs)
4640        __(add imm2,vsp,nargs)
4641        __(add imm2,imm2,imm0)
4642        __(add imm0,vsp,nargs)
4643        __(beq 2f)
46441:
4645        __(cmpri(cr0,imm3,1<<fixnumshift))
4646        __(subi imm3,imm3,1<<fixnumshift)
4647        __(ldru(temp0,-node_size(imm0)))
4648        __(stru(temp0,-node_size(imm2)))
4649        __(bne cr0,1b)
46502:
4651        __(mr vsp,imm2)
4652        __(blr)
4653
4654/* Build a new TSP area to hold nargs worth of multiple-values.  */
4655/* Pop the multiple values off of the vstack.  */
4656/* The new TSP frame will look like this:  */
4657/*  */
4658/*+--------+-------+-------+---------+--------+--------+--------+======+----------+ */
4659/*| ptr to | zero  | nargs | ptr to  | valn-1 | valn-2 | val-0  | ???? | prev TSP |  */
4660/*|  prev  |       |       |  prev   |        |        |        | fill |          |  */
4661/*| TSP    |       |       | segment |        |        |        |      |          | */
4662/*+--------+-------+-------+---------+--------+--------+--------+------+----------+  */
4663/*  */
4664/* e.g., the first multiple value goes in the last cell in the frame, the  */
4665/* count of values goes in the first word, and the word after the value count  */
4666/* is 0 if the number of values is even (for alignment).  */
4667/* Subsequent calls to .SPadd_values preserve this alignment.  */
4668/* .SPrecover_values is therefore pretty simple.  */
4669
4670_spentry(save_values)
4671        __(mr imm1,tsp)
4672
4673        /* common exit: nargs = values in this set, imm1 = ptr to tsp before  */
4674        /* call to save_values  */
4675local_label(save_values_to_tsp):
4676        __(mr imm2,tsp)
4677        __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* count, link  */
4678        __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
4679        __(str(imm1,tsp_frame.backlink(tsp))) /* keep one tsp "frame" as far as rest of lisp is concerned  */
4680        __(str(nargs,tsp_frame.data_offset(tsp)))
4681        __(str(imm2,tsp_frame.data_offset+node_size(tsp))) /* previous tsp  */
4682        __(la imm3,tsp_frame.data_offset+node_size*2(tsp))
4683        __(add imm3,imm3,nargs)
4684        __(add imm0,vsp,nargs)
4685        __(cmpr(cr0,imm0,vsp))
4686        __(b 2f)
46871:
4688        __(ldru(arg_z,-node_size(imm0)))
4689        __(cmpr(cr0,imm0,vsp))
4690        __(stru(arg_z,-node_size(imm3)))
46912:
4692        __(bne cr0,1b)
4693        __(add vsp,vsp,nargs) /*  discard values  */
4694        __(blr)
4695       
4696
4697/* Add the multiple values that are on top of the vstack to the set  */
4698/* saved in the top tsp frame, popping them off of the vstack in the  */
4699/* process.  It is an error (a bad one) if the TSP contains something  */
4700/* other than a previously saved set of multiple-values.  */
4701/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
4702/* each add_values call adds another linked element to the list of  */
4703/* values. This makes recover_values harder.  */
4704
4705_spentry(add_values)
4706        __(cmpri(cr0,nargs,0))
4707        __(ldr(imm1,0(tsp)))
4708        __(bne cr0,local_label(save_values_to_tsp))
4709        __(blr)
4710       
4711/* On entry, R11->callback-index  */
4712/* Restore lisp context, then funcall #'%pascal-functions% with  */
4713/* two args: callback-index, args-ptr (a macptr pointing to the args on the stack)  */
4714_spentry(poweropen_callback)
4715        __ifdef([rTOC])
4716         __(mr r11,rTOC)
4717        __endif
4718        /* Save C argument registers  */
4719        __(str(r3,c_frame.param0(sp)))
4720        __(str(r4,c_frame.param1(sp)))
4721        __(str(r5,c_frame.param2(sp)))
4722        __(str(r6,c_frame.param3(sp)))
4723        __(str(r7,c_frame.param4(sp)))
4724        __(str(r8,c_frame.param5(sp)))
4725        __(str(r9,c_frame.param6(sp)))
4726        __(str(r10,c_frame.param7(sp)))
4727        __(mflr imm3)
4728        __(str(imm3,c_frame.savelr(sp)))
4729        __(mfcr imm0)
4730        __(str(imm0,c_frame.crsave(sp)))
4731
4732        /* Save the non-volatile registers on the sp stack  */
4733        /* This is a non-standard stack frame, but noone will ever see it,  */
4734        /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
4735        __(stru(sp,-(stack_align(c_reg_save.size))(sp)))
4736        __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
4737        __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
4738        __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
4739        __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
4740        __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
4741        __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
4742        __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
4743        __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
4744        __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
4745        __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
4746        __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
4747        __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
4748        __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
4749        __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
4750        __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
4751        __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
4752        __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
4753        __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
4754        __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
4755        __(stfd f1,c_reg_save.save_fprs+(0*8)(sp))
4756        __(stfd f2,c_reg_save.save_fprs+(1*8)(sp))
4757        __(stfd f3,c_reg_save.save_fprs+(2*8)(sp))
4758        __(stfd f4,c_reg_save.save_fprs+(3*8)(sp))
4759        __(stfd f5,c_reg_save.save_fprs+(4*8)(sp))
4760        __(stfd f6,c_reg_save.save_fprs+(5*8)(sp))
4761        __(stfd f7,c_reg_save.save_fprs+(6*8)(sp))
4762        __(stfd f8,c_reg_save.save_fprs+(7*8)(sp))
4763        __(stfd f9,c_reg_save.save_fprs+(8*8)(sp))
4764        __(stfd f10,c_reg_save.save_fprs+(9*8)(sp))
4765        __(stfd f11,c_reg_save.save_fprs+(10*8)(sp))
4766        __(stfd f12,c_reg_save.save_fprs+(11*8)(sp))
4767        __(stfd f13,c_reg_save.save_fprs+(12*8)(sp))
4768        __(check_stack_alignment(r0))
4769        __(mffs f0)
4770        __(stfd f0,c_reg_save.save_fp_zero(sp))
4771        __(lwz r31,c_reg_save.save_fp_zero+4(sp))       /* recover FPSCR image  */
4772        __(stw r31,c_reg_save.save_fpscr(sp))
4773        __(lwi(r30,0x43300000))
4774        __(lwi(r31,0x80000000))
4775        __(stw r30,c_reg_save.save_fp_zero(sp))
4776        __(stw r31,c_reg_save.save_fp_zero+4(sp))
4777        __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
4778        __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
4779        __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
4780        __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
4781
4782/* Restore rest of Lisp context.  */
4783/* Could spread out the memory references here to gain a little speed  */
4784
4785        __(li loc_pc,0)
4786        __(li fn,0)                     /* subprim, not a lisp function  */
4787        __(li temp3,0)
4788        __(li temp2,0)
4789        __(li temp1,0)
4790        __(li temp0,0)
4791        __(li arg_x,0)
4792        __(box_fixnum(arg_y,r11))       /* callback-index  */
4793        __(la arg_z,c_reg_save.save_fprs(sp))
4794        __(str(arg_z,stack_align(c_reg_save.size)+c_frame.unused(sp)))
4795        __(la arg_z,stack_align(c_reg_save.size)+c_frame.param0(sp))    /* parameters (tagged as a fixnum)  */
4796
4797        /* Recover lisp thread context. Have to call C code to do so.  */
4798        __(ref_global(r12,get_tcr))
4799        __ifdef([rTOC])
4800         __(ld rTOC,8(r12))
4801         __(ld r12,0(r12))
4802        __endif
4803        __(mtctr r12)
4804        __(li r3,1)
4805        __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
4806        __(bctrl)
4807        __(la rcontext,TCR_BIAS(r3))
4808        __(la sp,(stack_align(c_frame.minsiz))(sp))
4809
4810        __(ldr(vsp,tcr.save_vsp(rcontext)))
4811        __(ldr(tsp,tcr.save_tsp(rcontext)))             
4812        __(li rzero,0)
4813        __(li imm0,TCR_STATE_LISP)
4814        __(mtxer rzero) /* lisp wants the overflow bit being clear  */
4815        __(mtctr rzero)
4816        __(li save0,0)
4817        __(li save1,0)
4818        __(li save2,0)
4819        __(li save3,0)
4820        __(li save4,0)
4821        __(li save5,0)
4822        __(li save6,0)
4823        __(li save7,0)
4824        __(lfd f0,tcr.lisp_fpscr(rcontext))
4825        __(mtfsf 0xff,f0)
4826        __(li allocbase,0)
4827        __(li allocptr,0)       
4828        __(str(imm0,tcr.valence(rcontext)))
4829        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
4830        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
4831       
4832        __(restore_saveregs(vsp))
4833
4834        /* load nargs and callback to the lisp  */
4835        __(set_nargs(2))
4836        __(ldr(imm2,tcr.cs_area(rcontext)))
4837        __(ldr(imm4,area.active(imm2)))
4838        __(stru(imm4,-lisp_frame.size(sp)))
4839        __(str(imm3,lisp_frame.savelr(sp)))
4840        __(li fname,nrs.callbacks)      /* %pascal-functions%  */
4841        __(call_fname)
4842        __(ldr(imm2,lisp_frame.backlink(sp)))
4843        __(ldr(imm3,tcr.cs_area(rcontext)))
4844        __(str(imm2,area.active(imm3)))
4845        __(discard_lisp_frame())
4846        /* save_vsp will be restored from ff_call's stack frame, but  */
4847        /* I included it here for consistency.  */
4848        /* save_tsp is set below after we exit Lisp context.  */
4849        __(str(allocptr,tcr.save_allocptr(rcontext)))
4850        __(str(allocbase,tcr.save_allocbase(rcontext)))
4851        __(str(vsp,tcr.save_vsp(rcontext)))
4852        __(str(tsp,tcr.save_tsp(rcontext)))
4853        /* Exit lisp context  */
4854        __(li imm1,TCR_STATE_FOREIGN)
4855        __(str(imm1,tcr.valence(rcontext)))
4856        /* Restore the non-volatile registers & fpscr  */
4857        __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
4858        __(lwz r31,c_reg_save.save_fpscr(sp))
4859        __(stw r31,c_reg_save.save_fp_zero+4(sp))
4860        __(lfd f0,c_reg_save.save_fp_zero(sp))
4861        __(mtfsf 0xff,f0)
4862        __(ldr(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
4863        __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
4864        __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
4865        __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
4866        __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
4867        __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
4868        __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
4869        __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
4870        __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
4871        __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
4872        __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
4873        __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
4874        __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
4875        __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
4876        __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
4877        __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
4878        __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
4879        __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
4880        __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
4881        __(lfd f1,c_reg_save.save_fprs+(0*8)(sp))
4882        __(lfd f2,c_reg_save.save_fprs+(1*8)(sp))
4883        __(lfd f3,c_reg_save.save_fprs+(2*8)(sp))
4884        __(lfd f4,c_reg_save.save_fprs+(3*8)(sp))
4885        __(lfd f5,c_reg_save.save_fprs+(4*8)(sp))
4886        __(lfd f6,c_reg_save.save_fprs+(5*8)(sp))
4887        __(lfd f7,c_reg_save.save_fprs+(6*8)(sp))
4888        __(lfd f8,c_reg_save.save_fprs+(7*8)(sp))
4889        __(lfd f9,c_reg_save.save_fprs+(8*8)(sp))
4890        __(lfd f10,c_reg_save.save_fprs+(9*8)(sp))
4891        __(lfd f11,c_reg_save.save_fprs+(10*8)(sp))
4892        __(lfd f12,c_reg_save.save_fprs+(11*8)(sp))
4893        __(lfd f13,c_reg_save.save_fprs+(12*8)(sp))
4894        __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
4895        __(ldr(sp,0(sp)))
4896        __(ldr(r3,c_frame.param0(sp)))
4897        __(ldr(r4,c_frame.param1(sp)))
4898        __(ldr(r5,c_frame.param2(sp)))
4899        __(ldr(r6,c_frame.param3(sp)))
4900        __(ldr(r7,c_frame.param4(sp)))
4901        __(ldr(r8,c_frame.param5(sp)))
4902        __(ldr(r9,c_frame.param6(sp)))
4903        __(ldr(r10,c_frame.param7(sp)))
4904        __(ldr(r11,c_frame.savelr(sp)))
4905        __(mtlr r11)
4906        __(ldr(r11,c_frame.crsave(sp)))
4907        __(mtcr r11)
4908        __(blr)
4909       
4910/* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
4911/* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
4912/* Calls out to %init-misc, which does the rest of the work.  */
4913
4914_spentry(misc_alloc_init)
4915        __(mflr loc_pc)
4916        __(build_lisp_frame(fn,loc_pc,vsp))
4917        __(li fn,0)
4918        __(mr temp0,arg_z)              /* initval  */
4919        __(mr arg_z,arg_y)              /* subtag  */
4920        __(mr arg_y,arg_x)              /* element-count  */
4921        __(bl _SPmisc_alloc)
4922        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4923        __(mtlr loc_pc)
4924        __(ldr(fn,lisp_frame.savefn(sp)))
4925        __(ldr(vsp,lisp_frame.savevsp(sp)))
4926        __(discard_lisp_frame())
4927        __(li fname,nrs.init_misc)
4928        __(set_nargs(2))
4929        __(mr arg_y,temp0)
4930        __(jump_fname())
4931
4932/* As in stack_misc_alloc above, only with a non-default initial-value.  */
4933
4934_spentry(stack_misc_alloc_init)
4935        __(mflr loc_pc)
4936        __(build_lisp_frame(fn,loc_pc,vsp))
4937        __(li fn,0)
4938        __(mr temp0,arg_z) /* initval  */
4939        __(mr arg_z,arg_y) /* subtag  */
4940        __(mr arg_y,arg_x) /* element-count  */
4941        __(bl _SPstack_misc_alloc)
4942        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4943        __(mtlr loc_pc)
4944        __(ldr(fn,lisp_frame.savefn(sp)))
4945        __(ldr(vsp,lisp_frame.savevsp(sp)))
4946        __(discard_lisp_frame())
4947        __(li fname,nrs.init_misc)
4948        __(set_nargs(2))
4949        __(mr arg_y,temp0)
4950        __(jump_fname())
4951
4952       
4953_spentry(callbuiltin)
4954        __(ref_nrs_value(fname,builtin_functions))
4955        __(la imm0,misc_data_offset(imm0))
4956        __(ldrx(fname,fname,imm0))
4957        __(jump_fname())
4958
4959/* the value of the nilreg-relative symbol %builtin-functions% should be  */
4960/* a vector of symbols.  Call the symbol indexed by imm0 (boxed) and  */
4961/* return a single value.  */
4962
4963_spentry(callbuiltin0)
4964        __(set_nargs(0))
4965        __(ref_nrs_value(fname,builtin_functions))
4966        __(la imm0,misc_data_offset(imm0))
4967        __(ldrx(fname,fname,imm0))
4968        __(jump_fname())
4969
4970_spentry(callbuiltin1)
4971        __(ref_nrs_value(fname,builtin_functions))
4972        __(set_nargs(1))
4973        __(la imm0,misc_data_offset(imm0))
4974        __(ldrx(fname,fname,imm0))
4975        __(jump_fname())
4976
4977_spentry(callbuiltin2)
4978        __(set_nargs(2))
4979        __(ref_nrs_value(fname,builtin_functions))
4980        __(la imm0,misc_data_offset(imm0))
4981        __(ldrx(fname,fname,imm0))
4982        __(jump_fname())
4983
4984
4985_spentry(callbuiltin3)
4986        __(set_nargs(3))
4987        __(ref_nrs_value(fname,builtin_functions))
4988        __(la imm0,misc_data_offset(imm0))
4989        __(ldrx(fname,fname,imm0))
4990        __(jump_fname())
4991       
4992
4993_spentry(popj)
4994        .globl C(popj)
4995C(popj):
4996        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4997        __(ldr(vsp,lisp_frame.savevsp(sp)))
4998        __(mtlr loc_pc)
4999        __(ldr(fn,lisp_frame.savefn(sp)))
5000        __(discard_lisp_frame())
5001        __(blr)
5002
5003_spentry(restorefullcontext)
5004        __(mflr loc_pc)
5005        __(mtctr loc_pc)
5006        __(ldr(loc_pc,lisp_frame.savelr(sp)))
5007        __(mtlr loc_pc)
5008        __(ldr(vsp,lisp_frame.savevsp(sp)))
5009        __(ldr(fn,lisp_frame.savefn(sp)))
5010        __(discard_lisp_frame())
5011        __(bctr)
5012
5013_spentry(savecontextvsp)
5014        __(ldr(imm0,tcr.cs_limit(rcontext)))
5015        __(build_lisp_frame(fn,loc_pc,vsp))
5016        __(mr fn,nfn)
5017        __(trllt(sp,imm0))
5018        __(blr)
5019
5020_spentry(savecontext0)
5021        __(add imm0,vsp,imm0)
5022        __(build_lisp_frame(fn,loc_pc,imm0))
5023        __(ldr(imm0,tcr.cs_limit(rcontext)))
5024        __(mr fn,nfn)
5025        __(trllt(sp,imm0))
5026        __(blr)
5027
5028
5029/* Like .SPrestorefullcontext, only the saved return address  */
5030/* winds up in loc-pc instead of getting thrashed around ...  */
5031_spentry(restorecontext)
5032        __(ldr(loc_pc,lisp_frame.savelr(sp)))
5033        __(ldr(vsp,lisp_frame.savevsp(sp)))
5034        __(ldr(fn,lisp_frame.savefn(sp)))
5035        __(discard_lisp_frame())
5036        __(blr)
5037
5038       
5039/* Nargs is valid; all arg regs, lexpr-count pushed by caller.  */
5040/* imm0 = vsp to restore.  */
5041/* Return all values returned by caller to its caller, hiding  */
5042/* the variable-length arglist.  */
5043/* If we can detect that the caller's caller didn't expect  */
5044/* multiple values, then things are even simpler.  */
5045_spentry(lexpr_entry)
5046        __(ref_global(imm1,ret1val_addr))
5047        __(cmpr(cr0,imm1,loc_pc))
5048        __(build_lisp_frame(fn,loc_pc,imm0))
5049        __(bne cr0,1f)
5050        __(ref_global(imm0,lexpr_return))
5051        __(build_lisp_frame(rzero,imm0,vsp))
5052        __(mr loc_pc,imm1)
5053        __(ldr(imm0,tcr.cs_limit(rcontext)))
5054        __(trllt(sp,imm0))
5055        __(li fn,0)
5056        __(blr)
5057
5058        /* The single-value case just needs to return to something that'll pop  */
5059        /* the variable-length frame off of the vstack.  */
50601:
5061        __(ref_global(loc_pc,lexpr_return1v))
5062        __(ldr(imm0,tcr.cs_limit(rcontext)))
5063        __(trllt(sp,imm0))
5064        __(li fn,0)
5065        __(blr)
5066
5067/* */
5068/* Do a system call in Darwin.  The stack is set up much as it would be */
5069/* for a PowerOpen ABI ff-call: register parameters are in the stack */
5070/* frame, and there are 4 extra words at the bottom of the frame that */
5071/* we can carve a lisp frame out of. */
5072/*  */
5073/* System call return conventions are a little funky in Darwin: if "@sc" */
5074/* is the address of the "sc" instruction, errors return to @sc+4 and */
5075/* non-error cases return to @sc+8.  Error values are returned as */
5076/* positive values in r3; this is true even if the system call returns */
5077/* a doubleword (64-bit) result.  Since r3 would ordinarily contain */
5078/* the high half of a doubleword result, this has to be special-cased. */
5079/*  */
5080/* The caller should set the c_frame.crsave field of the stack frame */
5081/* to 0 if the result is to be interpreted as anything but a doubleword */
5082/* and to non-zero otherwise.  (This only matters on an error return.) */
5083
5084       
5085_spentry(poweropen_syscall)
5086        __(mflr loc_pc)
5087        __(vpush_saveregs())
5088        __(ldr(imm1,0(sp)))
5089        __(la imm2,-lisp_frame.size(imm1))
5090        __(zero_doublewords imm2,0,lisp_frame.size)
5091        __(str(imm1,lisp_frame.backlink(imm2)))
5092        __(str(imm2,c_frame.backlink(sp)))
5093        __(str(fn,lisp_frame.savefn(imm2)))
5094        __(str(loc_pc,lisp_frame.savelr(imm2)))
5095        __(str(vsp,lisp_frame.savevsp(imm2)))
5096        __(ldr(imm3,tcr.cs_area(rcontext)))
5097        __(str(imm2,area.active(imm3)))
5098        __(str(allocptr,tcr.save_allocptr(rcontext)))
5099        __(str(allocbase,tcr.save_allocbase(rcontext)))
5100        __(str(tsp,tcr.save_tsp(rcontext)))
5101        __(str(vsp,tcr.save_vsp(rcontext)))
5102        __(str(rzero,tcr.ffi_exception(rcontext)))
5103        __(mr save0,rcontext)
5104        __(li r3,TCR_STATE_FOREIGN)
5105        __(str(r3,tcr.valence(rcontext)))
5106        __(li rcontext,0)
5107        __(ldr(r3,c_frame.param0(sp)))
5108        __(ldr(r4,c_frame.param1(sp)))
5109        __(ldr(r5,c_frame.param2(sp)))
5110        __(ldr(r6,c_frame.param3(sp)))
5111        __(ldr(r7,c_frame.param4(sp)))
5112        __(ldr(r8,c_frame.param5(sp)))
5113        __(ldr(r9,c_frame.param6(sp)))
5114        __(ldr(r10,c_frame.param7(sp)))
5115        __(unbox_fixnum(r0,arg_z))
5116        __(sc)
5117        __ifdef([LINUX])
5118         __(bns+ 9f)
5119        __else
5120         __(b 1f)
5121         __(b 9f)
5122        __endif
51231:
5124        __ifdef([PPC64])
5125         __(neg r3,r3)
5126        __else
5127         __(ldr(imm2,c_frame.crsave(sp)))
5128         __(cmpri(cr0,imm2,0))
5129         __(bne cr0,2f)
5130         /* 32-bit result  */
5131         __(neg r3,r3)
5132         __(b 9f)
51332:
5134         /* 64-bit result  */
5135         __(neg r4,r3)
5136         __(li r3,-1)
5137        __endif
51389:
5139        __(mr imm2,save0)       /* recover context  */
5140        __(ldr(sp,c_frame.backlink(sp)))
5141        __(li imm4,TCR_STATE_LISP)
5142        __(li rzero,0)
5143        __(li loc_pc,0)
5144        __(li arg_x,nil_value)
5145        __(li arg_y,nil_value)
5146        __(li arg_z,nil_value)
5147        __(li temp0,nil_value)
5148        __(li temp1,nil_value)
5149        __(li temp2,nil_value)
5150        __(li temp3,nil_value)
5151        __(li fn,nil_value)
5152        __(mr rcontext,imm2)
5153        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
5154        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
5155        __(ldr(tsp,tcr.save_tsp(rcontext)))
5156        __(li save0,0)
5157        __(li save1,0)
5158        __(li save2,0)
5159        __(li save3,0)
5160        __(li save4,0)
5161        __(li save5,0)
5162        __(li save6,0)
5163        __(li save7,0)       
5164        __(str(imm4,tcr.valence(rcontext)))
5165        __(vpop_saveregs)
5166        __(ldr(loc_pc,lisp_frame.savelr(sp)))
5167        __(mtlr loc_pc)
5168        __(ldr(fn,lisp_frame.savefn(sp)))
5169        __(discard_lisp_frame)
5170        __(mtxer rzero)
5171        __(check_pending_interrupt([cr1]))
5172        __(blr)
5173       
5174       
5175_spentry(builtin_plus)
5176        __(extract_lisptag(imm0,arg_y))
5177        __(extract_lisptag(imm1,arg_z))
5178        __(cmpri(cr0,imm0,tag_fixnum))
5179        __(cmpri(cr1,imm1,tag_fixnum))
5180        __(bne- cr0,1f)
5181        __(bne- cr1,1f)
5182        __(addo. arg_z,arg_y,arg_z)
5183        __(bnslr+)
5184        __(mtxer rzero)
5185        __(unbox_fixnum(imm1,arg_z))
5186        __ifdef([PPC64])
5187         __(li imm0,two_digit_bignum_header)
5188         __(rotldi imm1,imm1,32)
5189         __(xoris imm1,imm1,0xe000)
5190         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
5191         __(str(imm1,misc_data_offset(arg_z)))
5192        __else
5193         __(li imm0,one_digit_bignum_header)
5194         __(xoris imm1,imm1,0xc000)
5195         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
5196         __(str(imm1,misc_data_offset(arg_z)))
5197        __endif
5198        __(blr)
51991:
5200        __(jump_builtin(_builtin_plus,2))
5201_spentry(builtin_minus)
5202        __(extract_lisptag(imm0,arg_y))
5203        __(extract_lisptag(imm1,arg_z))
5204        __(cmpri(cr0,imm0,tag_fixnum))
5205        __(cmpri(cr1,imm1,tag_fixnum))
5206        __(bne- cr0,1f)
5207        __(bne- cr1,1f)
5208        __(subo. arg_z,arg_y,arg_z)
5209        __(bnslr+)
5210        __(mtxer rzero)
5211        __(unbox_fixnum(imm1,arg_z))
5212        __ifdef([PPC64])
5213         __(li imm0,two_digit_bignum_header)
5214         __(rotldi imm1,imm1,32)
5215         __(xoris imm1,imm1,0xe000)
5216         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
5217         __(str(imm1,misc_data_offset(arg_z)))
5218        __else
5219         __(li imm0,one_digit_bignum_header)
5220         __(xoris imm1,imm1,0xc000)
5221         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
5222         __(str(imm1,misc_data_offset(arg_z)))
5223        __endif
5224        __(blr)
52251:
5226        __(jump_builtin(_builtin_minus,2))
5227_spentry(builtin_times)
5228        __(extract_lisptag(imm0,arg_y))
5229        __(extract_lisptag(imm1,arg_z))
5230        __(cmpri(cr0,imm0,tag_fixnum))
5231        __(cmpri(cr1,imm1,tag_fixnum))
5232        __(unbox_fixnum(imm2,arg_y))
5233        __(bne cr0,1f)
5234        __(bne cr1,1f)
5235        __ifdef([PPC64])
5236         __(mulldo. imm3,arg_z,imm2)
5237         __(bso 2f)
5238         __(mr arg_z,imm3)
5239         __(blr)
5240         /* Args are fixnums; result can't be  */
52412:       __(mtxer rzero)
5242         __(unbox_fixnum(imm3,arg_z))
5243         __(mulld imm1,imm3,imm2) /* imm1 = low  64 bits  */
5244         __(mulhd imm0,imm3,imm2) /* imm0 = high 64 bits  */
5245         __(b _SPmakes128)
5246        __else
5247         __(mullwo. imm3,arg_z,imm2)
5248         __(bso 2f)             /*  SO set if result would overflow a fixnum  */
5249         __(mr arg_z,imm3)
5250         __(blr)
5251         /* Args are fixnums; result can't be  */
52522:       __(mtxer rzero)
5253         __(unbox_fixnum(imm3,arg_z))
5254         __(mullw imm1,imm3,imm2) /* imm1 = low  32 bits  */
5255         __(mulhw imm0,imm3,imm2) /* imm0 = high 32 bits  */
5256         __(b _SPmakes64)
5257        __endif
5258
52591:      __(jump_builtin(_builtin_times,2))
5260
5261_spentry(builtin_div)
5262        __(jump_builtin(_builtin_div,2))
5263
5264_spentry(builtin_eq)
5265        __(extract_lisptag(imm0,arg_y))
5266        __(extract_lisptag(imm1,arg_z))
5267        __(cmpri(cr0,imm0,tag_fixnum))
5268        __(cmpri(cr1,imm1,tag_fixnum))
5269        __(cmpr(cr2,arg_y,arg_z))
5270        __(bne- cr0,1f)
5271        __(bne- cr1,1f)
5272        __(li arg_z,nil_value)
5273        __(bnelr cr2)
5274        __(li arg_z,t_value)
5275        __(blr)
52761:
5277        __(jump_builtin(_builtin_eq,2))
5278
5279_spentry(builtin_ne)
5280        __(extract_lisptag(imm0,arg_y))
5281        __(extract_lisptag(imm1,arg_z))
5282        __(cmpri(cr0,imm0,tag_fixnum))
5283        __(cmpri(cr1,imm1,tag_fixnum))
5284        __(cmpr(cr2,arg_y,arg_z))
5285        __(bne- cr0,1f)
5286        __(bne- cr1,1f)
5287        __(li arg_z,nil_value)
5288        __(beqlr cr2)
5289        __(li arg_z,t_value)
5290        __(blr)
52911:
5292        __(jump_builtin(_builtin_ne,2))
5293
5294_spentry(builtin_gt)
5295        __(extract_lisptag(imm0,arg_y))
5296        __(extract_lisptag(imm1,arg_z))
5297        __(cmpri(cr0,imm0,tag_fixnum))
5298        __(cmpri(cr1,imm1,tag_fixnum))
5299        __(cmpr(cr2,arg_y,arg_z))
5300        __(bne- cr0,1f)
5301        __(bne- cr1,1f)
5302        __(li arg_z,nil_value)
5303        __(bnglr cr2)
5304        __(li arg_z,t_value)
5305        __(blr)
53061:
5307        __(jump_builtin(_builtin_gt,2))
5308
5309_spentry(builtin_ge)
5310        __(extract_lisptag(imm0,arg_y))
5311        __(extract_lisptag(imm1,arg_z))
5312        __(cmpri(cr0,imm0,tag_fixnum))
5313        __(cmpri(cr1,imm1,tag_fixnum))
5314        __(cmpr(cr2,arg_y,arg_z))
5315        __(bne- cr0,1f)
5316        __(bne- cr1,1f)
5317        __(li arg_z,nil_value)
5318        __(bltlr cr2)
5319        __(li arg_z,t_value)
5320        __(blr)
53211:
5322        __(jump_builtin(_builtin_ge,2))
5323
5324_spentry(builtin_lt)
5325        __(extract_lisptag(imm0,arg_y))
5326        __(extract_lisptag(imm1,arg_z))
5327        __(cmpri(cr0,imm0,tag_fixnum))
5328        __(cmpri(cr1,imm1,tag_fixnum))
5329        __(cmpr(cr2,arg_y,arg_z))
5330        __(bne- cr0,1f)
5331        __(bne- cr1,1f)
5332        __(li arg_z,nil_value)
5333        __(bnllr cr2)
5334        __(li arg_z,t_value)
5335        __(blr)
53361:
5337        __(jump_builtin(_builtin_lt,2))
5338
5339_spentry(builtin_le)
5340        __(extract_lisptag(imm0,arg_y))
5341        __(extract_lisptag(imm1,arg_z))
5342        __(cmpri(cr0,imm0,tag_fixnum))
5343        __(cmpri(cr1,imm1,tag_fixnum))
5344        __(cmpr(cr2,arg_y,arg_z))
5345        __(bne- cr0,1f)
5346        __(bne- cr1,1f)
5347        __(li arg_z,nil_value)
5348        __(bgtlr cr2)
5349        __(li arg_z,t_value)
5350        __(blr)
53511:
5352        __(jump_builtin(_builtin_le,2))
5353
5354
5355_spentry(builtin_eql)
5356        __(cmpr(cr1,arg_y,arg_z))
5357        __(extract_fulltag(imm2,arg_y))
5358        __(extract_fulltag(imm3,arg_z))
5359        __(beq cr1,1f)
5360        __(cmpri(cr1,imm2,fulltag_misc))
5361        __(cmpri(cr0,imm3,fulltag_misc))
5362        __(bne cr1,2f)
5363        __(extract_subtag(imm0,arg_y))
5364        __(bne cr0,2f)
5365        __(extract_subtag(imm1,arg_z))
5366        __(cmpr(cr0,imm0,imm1))
5367        __(bne cr0,2f)
5368        __(jump_builtin(_builtin_eql,2))
53691:      __(li arg_z,t_value)
5370        __(blr)
53712:      __(li arg_z,nil_value)
5372        __(blr)
5373       
5374_spentry(builtin_length)
5375        __(cmpri(cr1,arg_z,nil_value))
5376        __(extract_typecode(imm0,arg_z))
5377        __(cmpri(cr0,imm0,min_vector_subtag))
5378        __(beq cr1,1f)
5379        __ifdef([PPC64])
5380         __(cmpdi cr2,imm0,fulltag_cons)
5381        __else
5382         __(cmpwi cr2,imm0,tag_list)
5383        __endif
5384        __(beq- cr0,2f)
5385        __(blt- cr0,3f)
5386        /* (simple-array * (*))  */
5387        __(vector_length(arg_z,arg_z,imm0))
5388        __(blr)
53891:      __(li arg_z,0)
5390        __(blr)
53912:
5392        __(ldr(arg_z,vectorH.logsize(arg_z)))
5393        __(blr)       
53943:      __(bne cr2,8f)
5395        __(li temp2,-1<<fixnum_shift)
5396        __(mr temp0,arg_z)      /* fast pointer  */
5397        __(mr temp1,arg_z)      /* slow pointer  */
5398        __ifdef([PPC64])
53994:       __(extract_fulltag(imm0,temp0))
5400         __(cmpdi cr7,temp0,nil_value)
5401         __(cmpdi cr1,imm0,fulltag_cons)
5402         __(addi temp2,temp2,fixnum_one)
5403         __(beq cr7,9f)
5404         __(andi. imm0,temp2,1<<fixnum_shift)
5405         __(bne cr1,8f)
5406         __(extract_fulltag(imm1,temp1))
5407         __(_cdr(temp0,temp0))
5408         __(cmpdi cr1,imm1,fulltag_cons)
5409         __(beq cr0,4b)
5410         __(bne cr1,8f)
5411         __(_cdr(temp1,temp1))
5412         __(cmpd cr0,temp0,temp1)
5413         __(bne cr0,4b)
5414        __else
54154:       __(extract_lisptag(imm0,temp0))
5416         __(cmpri(cr7,temp0,nil_value))
5417         __(cmpri(cr1,imm0,tag_list))
5418         __(addi temp2,temp2,fixnum_one)
5419         __(beq cr7,9f)
5420         __(andi. imm0,temp2,1<<fixnum_shift)
5421         __(bne cr1,8f)
5422         __(extract_lisptag(imm1,temp1))       
5423         __(_cdr(temp0,temp0))
5424         __(cmpri(cr1,imm1,tag_list))
5425         __(beq cr0,4b)
5426         __(bne cr1,8f)
5427         __(_cdr(temp1,temp1))
5428         __(cmpr(cr0,temp0,temp1))
5429         __(bne cr0,4b)
5430        __endif
54318:     
5432        __(jump_builtin(_builtin_length,1))
54339:     
5434        __(mr arg_z,temp2)
5435        __(blr)
5436       
5437_spentry(builtin_seqtype)
5438        __ifdef([PPC64])
5439         __(cmpdi cr2,arg_z,nil_value)
5440         __(extract_typecode(imm0,arg_z))
5441         __(beq cr2,1f)
5442         __(cmpri(cr0,imm0,fulltag_cons))
5443        __else
5444         __(extract_typecode(imm0,arg_z))
5445         __(cmpri(cr0,imm0,tag_list))
5446        __endif
5447        __(cmpri(cr1,imm0,min_vector_subtag))
5448        __(beq cr0,1f)
5449        __(blt- cr1,2f)
5450        __(li arg_z,nil_value)
5451        __(blr)
54521:      __(li arg_z,t_value)
5453        __(blr)
54542:
5455        __(jump_builtin(_builtin_seqtype,1))
5456       
5457_spentry(builtin_assq)
5458        __(cmpri(arg_z,nil_value))
5459        __(beqlr)
54601:      __(trap_unless_list(arg_z,imm0))
5461        __(_car(arg_x,arg_z))
5462        __(_cdr(arg_z,arg_z))
5463        __(cmpri(cr2,arg_x,nil_value))
5464        __(cmpri(cr1,arg_z,nil_value))
5465        __(beq cr2,2f)
5466        __(trap_unless_list(arg_x,imm0))
5467        __(_car(temp0,arg_x))
5468        __(cmpr(temp0,arg_y))
5469        __(bne cr0,2f)
5470        __(mr arg_z,arg_x)
5471        __(blr)
54722:      __(bne cr1,1b)
5473        __(blr)
5474
5475_spentry(builtin_memq)
5476        __(cmpri(cr1,arg_z,nil_value))
5477        __(b 2f)
54781:      __(trap_unless_list(arg_z,imm0))
5479        __(_car(arg_x,arg_z))
5480        __(_cdr(temp0,arg_z))
5481        __(cmpr(arg_x,arg_y))
5482        __(cmpri(cr1,temp0,nil_value))
5483        __(beqlr)
5484        __(mr arg_z,temp0)
54852:      __(bne cr1,1b)
5486        __(blr)
5487
5488        __ifdef([PPC64])
5489logbitp_max_bit = 61
5490        __else
5491logbitp_max_bit = 30
5492        __endif
5493       
5494_spentry(builtin_logbitp)
5495        /* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
5496        __(cmplri(cr2,arg_y,logbitp_max_bit<<fixnum_shift))
5497        __(extract_lisptag(imm0,arg_y))
5498        __(extract_lisptag(imm1,arg_z))
5499        __(cmpri(cr0,imm0,tag_fixnum))
5500        __(cmpri(cr1,imm1,tag_fixnum))
5501        __(unbox_fixnum(imm0,arg_y))
5502        __(subfic imm0,imm0,logbitp_max_bit)
5503        __ifdef([PPC64])
5504         __(rldcl imm0,arg_z,imm0,63)
5505         __(mulli imm0,imm0,t_offset)
5506        __else
5507         __(rlwnm imm0,arg_z,imm0,31,31)
5508         __(rlwimi imm0,imm0,4,27,27)
5509        __endif
5510        __(bnl cr2,1f)
5511        __(bne cr0,1f)
5512        __(bne cr1,1f)
5513        __(addi arg_z,imm0,nil_value)
5514        __(blr)
55151:
5516        __(jump_builtin(_builtin_logbitp,2))
5517
5518_spentry(builtin_logior)
5519        __(extract_lisptag(imm0,arg_y))
5520        __(extract_lisptag(imm1,arg_z))
5521        __(cmpri(cr0,imm0,tag_fixnum))
5522        __(cmpri(cr1,imm1,tag_fixnum))
5523        __(bne- cr0,1f)
5524        __(bne- cr1,1f)
5525        __(or arg_z,arg_y,arg_z)
5526        __(blr)
55271:
5528        __(jump_builtin(_builtin_logior,2))
5529
5530_spentry(builtin_logand)
5531        __(extract_lisptag(imm0,arg_y))
5532        __(extract_lisptag(imm1,arg_z))
5533        __(cmpri(cr0,imm0,tag_fixnum))
5534        __(cmpri(cr1,imm1,tag_fixnum))
5535        __(bne- cr0,1f)
5536        __(bne- cr1,1f)
5537        __(and arg_z,arg_y,arg_z)
5538        __(blr)
55391:
5540        __(jump_builtin(_builtin_logand,2))
5541       
5542_spentry(builtin_ash)
5543        __ifdef([PPC64])
5544         __(cmpdi cr1,arg_z,0)
5545         __(extract_lisptag(imm0,arg_y))
5546         __(extract_lisptag(imm1,arg_z))
5547         __(cmpdi cr0,imm0,tag_fixnum)
5548         __(cmpdi cr3,imm1,tag_fixnum)
5549         __(cmpdi cr2,arg_z,-(63<<3))   /* !! 3 =  fixnumshift  */
5550         __(bne- cr0,9f)
5551         __(bne- cr3,9f)
5552         __(bne cr1,0f)
5553         __(mr arg_z,arg_y)     /* (ash n 0) => n  */
5554         __(blr)
55550:             
5556         __(unbox_fixnum(imm1,arg_y))
5557         __(unbox_fixnum(imm0,arg_z))
5558         __(bgt cr1,2f)
5559         /* (ash n -count) => fixnum  */
5560         __(neg imm2,imm0)
5561         __(bgt cr2,1f)
5562         __(li imm2,63)
55631:     
5564         __(srad imm0,imm1,imm2)
5565         __(box_fixnum(arg_z,imm0))
5566         __(blr)
5567         /* Integer-length of arg_y/imm1 to imm2  */
55682:             
5569         __(cntlzd. imm2,imm1)
5570         __(bne 3f)             /* cr0[eq] set if negative  */
5571         __(not imm2,imm1)
5572         __(cntlzd imm2,imm2)
55733:
5574         __(subfic imm2,imm2,64)
5575         __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
5576         __(cmpdi cr1,imm2,63-fixnumshift)
5577         __(cmpdi cr2,imm0,64)
5578         __(sld imm2,imm1,imm0)
5579         __(bgt cr1,6f)
5580         __(box_fixnum(arg_z,imm2))
5581         __(blr)       
55826:
5583         __(bgt cr2,9f)
5584         __(bne cr2,7f)
5585         /* Shift left by 64 bits exactly  */
5586         __(mr imm0,imm1)
5587         __(li imm1,0)
5588         __(beq _SPmakes128)
5589         __(b _SPmakeu128)
55907:
5591         /* Shift left by fewer than 64 bits, result not a fixnum  */
5592         __(subfic imm0,imm0,64)
5593         __(beq 8f)
5594         __(srd imm0,imm1,imm0)
5595         __(mr imm1,imm2)
5596         __(b _SPmakeu128)
55978:     
5598         __(srad imm0,imm1,imm0)
5599         __(mr imm1,imm2)
5600         __(b _SPmakes128)
5601        __else
5602         __(cmpri(cr1,arg_z,0))
5603         __(extract_lisptag(imm0,arg_y))
5604         __(extract_lisptag(imm1,arg_z))
5605         __(cmpri(cr0,imm0,tag_fixnum))
5606         __(cmpri(cr3,imm1,tag_fixnum))
5607         __(cmpri(cr2,arg_z,-(29<<2)))  /* !! 2 =  fixnumshift  */
5608         __(bne- cr0,9f)
5609         __(bne- cr3,9f)
5610         __(bne cr1,0f)
5611         __(mr arg_z,arg_y)     /* (ash n 0) => n  */
5612         __(blr)
56130:             
5614         __(unbox_fixnum(imm1,arg_y))
5615         __(unbox_fixnum(imm0,arg_z))
5616         __(bgt cr1,2f)
5617         /* (ash n -count) => fixnum  */
5618         __(neg imm2,imm0)
5619         __(bgt cr2,1f)
5620         __(li imm2,31)
56211:     
5622         __(sraw imm0,imm1,imm2)
5623         __(box_fixnum(arg_z,imm0))
5624         __(blr)
5625         /* Integer-length of arg_y/imm1 to imm2  */
56262:             
5627         __(cntlzw. imm2,imm1)
5628         __(bne 3f)             /* cr0[eq] set if negative  */
5629         __(not imm2,imm1)
5630         __(cntlzw imm2,imm2)
56313:
5632         __(subfic imm2,imm2,32)
5633         __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
5634         __(cmpri(cr1,imm2,31-fixnumshift))
5635         __(cmpri(cr2,imm0,32))
5636         __(slw imm2,imm1,imm0)
5637         __(bgt cr1,6f)
5638         __(box_fixnum(arg_z,imm2))
5639         __(blr)       
56406:
5641         __(bgt cr2,9f)
5642         __(bne cr2,7f)
5643         /* Shift left by 32 bits exactly  */
5644         __(mr imm0,imm1)
5645         __(li imm1,0)
5646         __(beq _SPmakes64)
5647         __(b _SPmakeu64)
56487:
5649         /* Shift left by fewer than 32 bits, result not a fixnum  */
5650         __(subfic imm0,imm0,32)
5651         __(beq 8f)
5652         __(srw imm0,imm1,imm0)
5653         __(mr imm1,imm2)
5654         __(b _SPmakeu64)
56558:     
5656         __(sraw imm0,imm1,imm0)
5657         __(mr imm1,imm2)
5658         __(b _SPmakes64)
5659        __endif
56609:             
5661        __(jump_builtin(_builtin_ash,2))
5662
5663_spentry(builtin_negate)
5664        __(extract_lisptag_(imm0,arg_z))
5665        __(bne- cr0,1f)
5666        __(nego. arg_z,arg_z)
5667        __(bnslr+)
5668        __(mtxer rzero)
5669        __(unbox_fixnum(imm1,arg_z))
5670        __ifdef([PPC64])
5671         __(li imm0,two_digit_bignum_header)
5672         __(rotldi imm1,imm1,32)
5673         __(xoris imm1,imm1,0xe000)
5674         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
5675         __(str(imm1,misc_data_offset(arg_z)))
5676        __else
5677         __(li imm0,one_digit_bignum_header)
5678         __(xoris imm1,imm1,0xc000)
5679         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
5680         __(str(imm1,misc_data_offset(arg_z)))
5681        __endif
5682        __(blr)
56831:
5684        __(jump_builtin(_builtin_negate,1))
5685
5686_spentry(builtin_logxor)
5687        __(extract_lisptag(imm0,arg_y))
5688        __(extract_lisptag(imm1,arg_z))
5689        __(cmpri(cr0,imm0,tag_fixnum))
5690        __(cmpri(cr1,imm1,tag_fixnum))
5691        __(bne- cr0,1f)
5692        __(bne- cr1,1f)
5693        __(xor arg_z,arg_y,arg_z)
5694        __(blr)
56951:
5696        __(jump_builtin(_builtin_logxor,2))
5697
5698
5699
5700       
5701_spentry(builtin_aset1)
5702        __(extract_typecode(imm0,arg_x))
5703        __(cmpri(cr0,imm0,min_vector_subtag))
5704        __(box_fixnum(temp0,imm0))
5705        __(bgt cr0,1f)
5706        __(jump_builtin(_builtin_aset1,3))
57071:
5708        __(b _SPsubtag_misc_set)
5709
5710/* Enter the debugger  */
5711_spentry(breakpoint)
5712        __(li r3,0)
5713        __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter)  */
5714        __(blr)         /* if handler didn't  */
5715
5716/* */
5717/* We're entered with an eabi_c_frame on the C stack.  There's a */
5718/* lisp_frame reserved underneath it; we'll link it in in a minute. */
5719/* Load the outgoing GPR arguments from eabi_c_frame.param[0-7], */
5720/* then shrink the eabi_c_frame. */
5721/*  */
5722       
5723_spentry(eabi_ff_call)
5724        __(mflr loc_pc)
5725        __(str(sp,eabi_c_frame.savelr(sp)))
5726        __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
5727        __(mr save0,rcontext)   /* or address globals.  */
5728        __(extract_typecode(imm0,arg_z))
5729        __(cmpri(imm0,subtag_macptr))
5730        __(ldr(save1,0(sp)))    /* bottom of reserved lisp frame  */
5731        __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
5732        __(zero_doublewords save2,0,lisp_frame.size)
5733        __(str(save1,lisp_frame.backlink(save2)))
5734        __(str(save2,c_frame.backlink(sp)))
5735        __(str(fn,lisp_frame.savefn(save2)))
5736        __(str(loc_pc,lisp_frame.savelr(save2)))
5737        __(str(vsp,lisp_frame.savevsp(save2)))
5738        __(bne 1f)
5739        __(ldr(arg_z,macptr.address(arg_z)))
57401:
5741        __(ldr(save3,tcr.cs_area(rcontext)))
5742        __(str(save2,area.active(save3)))
5743        __(str(allocptr,tcr.save_allocptr(rcontext)))
5744        __(str(allocbase,tcr.save_allocbase(rcontext)))
5745        __(str(tsp,tcr.save_tsp(rcontext)))
5746        __(str(vsp,tcr.save_vsp(rcontext)))
5747        __(mtctr arg_z)
5748        __(str(rzero,tcr.ffi_exception(rcontext)))
5749        __(mffs f0)
5750        __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
5751        __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
5752        __(li imm1,TCR_STATE_FOREIGN)
5753        __(str(imm1,tcr.valence(rcontext)))
5754        __(ldr(r2,tcr.native_thread_info(rcontext)))
5755        __(ldr(r13,lisp_globals.saveR13(0)))
5756        __(ldr(r3,eabi_c_frame.param0(sp)))
5757        __(ldr(r4,eabi_c_frame.param1(sp)))
5758        __(ldr(r5,eabi_c_frame.param2(sp)))
5759        __(ldr(r6,eabi_c_frame.param3(sp)))
5760        __(ldr(r7,eabi_c_frame.param4(sp)))
5761        __(ldr(r8,eabi_c_frame.param5(sp)))
5762        __(ldr(r9,eabi_c_frame.param6(sp)))
5763        __(ldr(r10,eabi_c_frame.param7(sp)))
5764        __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
5765        __(str(rzero,eabi_c_frame.savelr(save1)))
5766        __(str(save2,eabi_c_frame.backlink(save1)))
5767        __(mr sp,save1)
5768        /* If we're calling a varargs C function, it'll want to */
5769        /* know whether or not we've passed any args in FP regs. */
5770        /* Better to say that we did (and force callee to save FP */
5771        /* arg regs on entry) than to say that we didn't and get */
5772        /* garbage results  */
5773        __(crset 6)
5774        __(bctrl)
5775        _endsubp(eabi_ff_call)
5776       
5777        _startfn(FF_call_return_common)
5778        /* C should have preserved save0 (= rcontext) for us.  */
5779        __(ldr(sp,0(sp)))
5780        __(mr imm2,save0)
5781        __(ldr(vsp,lisp_frame.savevsp(sp)))
5782        __(li rzero,0)
5783        __(mr loc_pc,rzero)
5784        __(li arg_x,nil_value)
5785        __(li arg_y,nil_value)
5786        __(li arg_z,nil_value)
5787        __(li temp0,nil_value)
5788        __(li temp1,nil_value)
5789        __(li temp2,nil_value)
5790        __(li temp3,nil_value)
5791        __(li fn,nil_value)
5792        __(mr rcontext,imm2)
5793        __(li imm2,TCR_STATE_LISP)
5794        __(ldr(tsp,tcr.save_tsp(rcontext)))
5795        __(li save0,0)
5796        __(li save1,0)
5797        __(li save2,0)
5798        __(li save3,0)
5799        __(li save4,0)
5800        __(li save5,0)
5801        __(li save6,0)
5802        __(li save7,0)
5803        __(li allocptr,-dnode_size)
5804        __(li allocbase,-dnode_size)
5805        __(str(imm2,tcr.valence(rcontext)))     
5806        .globl C(ffcall_return_window)
5807C(ffcall_return_window):               
5808        __(vpop_saveregs())
5809        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
5810        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
5811        .globl C(ffcall_return_window_end)
5812C(ffcall_return_window_end):               
5813        __(ldr(loc_pc,lisp_frame.savelr(sp)))
5814        __(mtlr loc_pc)
5815        __(ldr(fn,lisp_frame.savefn(sp)))
5816        __(mffs f0)
5817        __(stfd f0,8(sp))
5818        __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
5819        __(clrrwi imm2,imm3,8)
5820        __(discard_lisp_frame())
5821        __(str(imm2,tcr.ffi_exception(rcontext)))
5822        __(lfd f0,tcr.lisp_fpscr(rcontext))
5823        __(mtfsf 0xff,f0)
5824        __(check_pending_interrupt([cr1]))
5825        __(mtxer rzero)
5826        __(mtctr rzero)
5827        __(blr)
5828       
5829/*  */
5830/* This gets called with R11 holding the unboxed callback index. */
5831/* */
5832       
5833_spentry(eabi_callback)
5834        /* First, we extend the C frame so that it has room for */
5835        /* incoming arg regs.  */
5836        __(ldr(r0,eabi_c_frame.backlink(sp)))
5837        __(stru(r0,eabi_c_frame.param0-varargs_eabi_c_frame.incoming_stack_args(sp)))
5838        __(mflr r0)
5839        __(str(r0,varargs_eabi_c_frame.savelr(sp)))
5840        __(str(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
5841        __(str(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
5842        __(str(r5,varargs_eabi_c_frame.gp_save+(2*4)(sp)))
5843        __(str(r6,varargs_eabi_c_frame.gp_save+(3*4)(sp)))
5844        __(str(r7,varargs_eabi_c_frame.gp_save+(4*4)(sp)))
5845        __(str(r8,varargs_eabi_c_frame.gp_save+(5*4)(sp)))
5846        __(str(r9,varargs_eabi_c_frame.gp_save+(6*4)(sp)))
5847        __(str(r10,varargs_eabi_c_frame.gp_save+(7*4)(sp)))
5848        /* Could check the appropriate CR bit and skip saving FP regs here  */
5849        __(stfd f1,varargs_eabi_c_frame.fp_save+(0*8)(sp))
5850        __(stfd f2,varargs_eabi_c_frame.fp_save+(1*8)(sp))
5851        __(stfd f3,varargs_eabi_c_frame.fp_save+(2*8)(sp))
5852        __(stfd f4,varargs_eabi_c_frame.fp_save+(3*8)(sp))
5853        __(stfd f5,varargs_eabi_c_frame.fp_save+(4*8)(sp))
5854        __(stfd f6,varargs_eabi_c_frame.fp_save+(5*8)(sp))
5855        __(stfd f7,varargs_eabi_c_frame.fp_save+(6*8)(sp))
5856        __(stfd f8,varargs_eabi_c_frame.fp_save+(7*8)(sp))
5857        __(la r0,varargs_eabi_c_frame.incoming_stack_args(sp))
5858        __(str(r0,varargs_eabi_c_frame.overflow_arg_area(sp)))
5859        __(la r0,varargs_eabi_c_frame.regsave(sp))
5860        __(str(r0,varargs_eabi_c_frame.reg_save_area(sp)))
5861        __(li r0,0)
5862        __(str(r0,varargs_eabi_c_frame.flags(sp)))
5863
5864        /* Save the non-volatile registers on the sp stack  */
5865        /* This is a non-standard stack frame, but noone will ever see it,  */
5866        /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
5867        __(stru(sp,-(c_reg_save.size)(sp)))
5868        __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
5869        __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
5870        __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
5871        __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
5872        __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
5873        __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
5874        __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
5875        __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
5876        __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
5877        __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
5878        __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
5879        __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
5880        __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
5881        __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
5882        __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
5883        __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
5884        __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
5885        __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
5886        __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
5887        __(mffs f0)
5888        __(stfd f0,c_reg_save.save_fp_zero(sp))
5889        __(ldr(r31,c_reg_save.save_fp_zero+4(sp)))      /* recover FPSCR image  */
5890        __(str(r31,c_reg_save.save_fpscr(sp)))
5891        __(lwi(r30,0x43300000))
5892        __(lwi(r31,0x80000000))
5893        __(str(r30,c_reg_save.save_fp_zero(sp)))
5894        __(str(r31,c_reg_save.save_fp_zero+4(sp)))
5895        __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
5896        __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
5897        __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
5898        __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
5899
5900       
5901/* Restore rest of Lisp context.  */
5902/* Could spread out the memory references here to gain a little speed  */
5903        __(li loc_pc,0)
5904        __(li fn,0)                     /* subprim, not a lisp function  */
5905        __(li temp3,0)
5906        __(li temp2,0)
5907        __(li temp1,0)
5908        __(li temp0,0)
5909        __(li arg_x,0)
5910        __(box_fixnum(arg_y,r11))       /* callback-index  */
5911        __(la arg_z,c_reg_save.size+varargs_eabi_c_frame.gp_save(sp))   /* parameters (tagged as a fixnum)  */
5912
5913        /* Recover lisp thread context. Have to call C code to do so.  */
5914        __(ref_global(r12,get_tcr))
5915        __(mtctr r12)
5916        __(li r3,1)
5917        __(stru(sp,-(stack_align(eabi_c_frame.minsiz))(sp)))
5918        __(bctrl)
5919        __(la sp,(stack_align(eabi_c_frame.minsiz))(sp))
5920        __(la rcontext,TCR_BIAS(r3))
5921        __(li allocptr,0)
5922        __(li allocbase,0)
5923        __(ldr(vsp,tcr.save_vsp(rcontext)))
5924        __(ldr(tsp,tcr.save_tsp(rcontext)))             
5925        __(li rzero,0)
5926        __(mtxer rzero) /* lisp wants the overflow bit clear  */
5927        __(li imm0,TCR_STATE_LISP)
5928        __(li save0,0)
5929        __(li save1,0)
5930        __(li save2,0)
5931        __(li save3,0)
5932        __(li save4,0)
5933        __(li save5,0)
5934        __(li save6,0)
5935        __(li save7,0)
5936        __(mtctr rzero)
5937        __(str(imm0,tcr.valence(rcontext)))
5938        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
5939        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
5940        __(lfd f0,tcr.lisp_fpscr(rcontext))
5941        __(mtfsf 0xff,f0)
5942
5943        __(restore_saveregs(vsp))       
5944        /* load nargs and callback to the lisp  */
5945        __(set_nargs(2))
5946        __(ldr(imm2,tcr.cs_area(rcontext)))
5947        __(ldr(imm4,area.active(imm2)))
5948        __(stru(imm4,-lisp_frame.size(sp)))
5949        __(str(imm3,lisp_frame.savelr(sp)))
5950        __(str(vsp,lisp_frame.savevsp(sp)))     /* for stack overflow code  */
5951        __(li fname,nrs.callbacks)      /* %pascal-functions%  */
5952        __(call_fname)
5953        __(ldr(imm2,lisp_frame.backlink(sp)))
5954        __(ldr(imm3,tcr.cs_area(rcontext)))
5955        __(str(imm2,area.active(imm3)))
5956        __(discard_lisp_frame())
5957        /* save_vsp will be restored from ff_call's stack frame, but  */
5958        /* I included it here for consistency.  */
5959        /* save_tsp is set below after we exit Lisp context.  */
5960        __(str(allocptr,tcr.save_allocptr(rcontext)))
5961        __(str(allocbase,tcr.save_allocbase(rcontext)))
5962        __(str(vsp,tcr.save_vsp(rcontext)))
5963        __(str(tsp,tcr.save_tsp(rcontext)))
5964        /* Exit lisp context  */
5965        /* This is not necessary yet, but will be once we can be interrupted  */
5966        __(li imm1,TCR_STATE_FOREIGN)
5967        __(str(imm1,tcr.valence(rcontext)))
5968        /* Restore the non-volatile registers & fpscr  */
5969        __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
5970        __(ldr(r31,c_reg_save.save_fpscr(sp)))
5971        __(str(r31,c_reg_save.save_fp_zero+4(sp)))
5972        __(lfd f0,c_reg_save.save_fp_zero(sp))
5973        __(mtfsf 0xff,f0)
5974        __(ldr(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
5975        __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
5976        __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
5977        __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
5978        __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
5979        __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
5980        __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
5981        __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
5982        __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
5983        __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
5984        __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
5985        __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
5986        __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
5987        __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
5988        __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
5989        __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
5990        __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
5991        __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
5992        __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
5993        __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
5994        __(ldr(sp,0(sp)))
5995
5996        __(ldr(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
5997        __(ldr(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
5998        __(lfd f1,varargs_eabi_c_frame.gp_save+(2*4)(sp))
5999        __(ldr(r5,varargs_eabi_c_frame.savelr(sp)))
6000        __(str(r5,varargs_eabi_c_frame.old_savelr(sp)))
6001        __(mtlr r5)
6002        __(ldr(r5,varargs_eabi_c_frame.backlink(sp)))
6003        __(str(r5,varargs_eabi_c_frame.old_backlink(sp)))
6004        __(la sp,varargs_eabi_c_frame.old_backlink(sp))
6005        __(blr)
6006       
6007
6008/*      Do a linux system call:  the system call index is (boxed) */
6009/*      in arg_z, and other arguments are in an eabi_c_frame on */
6010/*      the C stack.  As is the case with an eabi_ff_call, there's */
6011/*      a lisp frame reserved underneath the eabi_c_frame. */
6012
6013/*      This is a little simpler than eabi_ff_call, because we */
6014/*      can assume that there are no synchronous callbacks to */
6015/*      lisp (that might cause a GC.)  It's also simpler for the */
6016/*      caller, since we return error status atomically. */
6017
6018/*      A system call can clobber any or all of r9-r12, so we need */
6019/*      to save and restore allocptr, allocbase, and tsp. */
6020       
6021_spentry(eabi_syscall)
6022/*      We're entered with an eabi_c_frame on the C stack.  There's a */
6023/*      lisp_frame reserved underneath it; we'll link it in in a minute. */
6024/*      Load the outgoing GPR arguments from eabi_c_frame.param[0-7], */
6025/*      then shrink the eabi_c_frame. */
6026
6027        __(mflr loc_pc)
6028        __(vpush_saveregs())
6029        __(str(sp,eabi_c_frame.savelr(sp)))
6030        __(li arg_x,nil_value)
6031        __(mr temp0,rcontext)
6032        __(ldr(temp1,c_frame.backlink(sp)))     /* bottom of reserved lisp frame  */
6033        __(la temp2,-lisp_frame.size(temp1))    /* top of lisp frame  */
6034        __(zero_doublewords temp2,0,lisp_frame.size)
6035        __(str(temp1,lisp_frame.backlink(temp2)))
6036        __(str(temp2,c_frame.backlink(sp)))
6037        __(str(fn,lisp_frame.savefn(temp2)))
6038        __(str(loc_pc,lisp_frame.savelr(temp2)))
6039        __(str(vsp,lisp_frame.savevsp(temp2)))
6040        __(ldr(temp3,tcr.cs_area(rcontext)))
6041        __(str(temp2,area.active(temp3)))
6042        __(str(allocptr,tcr.save_allocptr(rcontext)))
6043        __(str(allocbase,tcr.save_allocbase(rcontext)))
6044        __(str(tsp,tcr.save_tsp(rcontext)))
6045        __(str(vsp,tcr.save_vsp(rcontext)))
6046        __(str(rzero,tcr.ffi_exception(rcontext)))
6047        __(li imm1,TCR_STATE_FOREIGN)
6048        __(str(imm1,tcr.valence(rcontext)))
6049        __(ldr(r13,lisp_globals.saveR13(0)))
6050        __(ldr(r3,eabi_c_frame.param0(sp)))
6051        __(ldr(r4,eabi_c_frame.param1(sp)))
6052        __(ldr(r5,eabi_c_frame.param2(sp)))
6053        __(ldr(r6,eabi_c_frame.param3(sp)))
6054        __(ldr(r7,eabi_c_frame.param4(sp)))
6055        __(ldr(r8,eabi_c_frame.param5(sp)))
6056        __(ldr(r9,eabi_c_frame.param6(sp)))
6057        __(ldr(r10,eabi_c_frame.param7(sp)))
6058        __(la temp1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
6059        __(str(rzero,eabi_c_frame.savelr(temp1)))
6060        __(str(temp2,eabi_c_frame.backlink(temp1)))
6061        __(mr sp,temp1)
6062        __(unbox_fixnum(r0,arg_z))
6063        __(sc)
6064        __(nop)
6065        /* C should have preserved temp0 (= rcontext) for us.  */
6066        __(ldr(sp,0(sp)))
6067        __(mr imm2,temp0)
6068        __(ldr(vsp,lisp_frame.savevsp(sp)))
6069        __(li rzero,0)
6070        __(mr loc_pc,rzero)
6071        __(mr fn,rzero)
6072        __(li arg_x,nil_value)
6073        __(li arg_y,nil_value)
6074        __(li arg_z,nil_value)
6075        __(li temp0,nil_value)
6076        __(li temp1,nil_value)
6077        __(li temp2,nil_value)
6078        __(li temp3,nil_value)
6079        __(li fn,nil_value)
6080       
6081        __(li imm3,TCR_STATE_LISP)
6082        __(mr rcontext,imm2)
6083        __(li save0,0)
6084        __(li save1,0)
6085        __(li save2,0)
6086        __(li save3,0)
6087        __(li save4,0)
6088        __(li save5,0)
6089        __(li save6,0)
6090        __(li save7,0)       
6091        __(str(imm3,tcr.valence(rcontext)))
6092        __(vpop_saveregs)
6093        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
6094        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
6095        __(ldr(tsp,tcr.save_tsp(rcontext)))
6096        __(ldr(loc_pc,lisp_frame.savelr(sp)))
6097        __(mtlr loc_pc)
6098        __(ldr(fn,lisp_frame.savefn(sp)))
6099        __(discard_lisp_frame())
6100        __(bns 1f)
6101        __(neg r3,r3)
61021:     
6103        __(check_pending_interrupt([cr1]))               
6104        __(mtxer rzero)
6105        __(blr)
6106       
6107/* arg_z should be of type (UNSIGNED-BYTE 64);  */
6108/* On PPC32, return high 32 bits in imm0, low 32 bits in imm1 */
6109/* On PPC64, return unboxed value in imm0  */
6110
6111_spentry(getu64)
6112        __ifdef([PPC64])
6113        __(extract_typecode(imm0,arg_z))
6114        __(cmpdi cr0,imm0,tag_fixnum)
6115        __(cmpdi cr2,arg_z,0)
6116        __(cmpdi cr1,imm0,subtag_bignum)
6117        __(bne cr0,1f)
6118        __(unbox_fixnum(imm0,arg_z))
6119        __(bgelr cr2)
61200:             
6121        __(uuo_interr(error_object_not_u64,arg_z))
6122       
61231:      __(bne cr1,0b)
6124        __(getvheader(imm1,arg_z))
6125        __(ld imm0,misc_data_offset(arg_z))
6126        __(cmpdi cr2,imm1,two_digit_bignum_header)
6127        __(rotldi imm0,imm0,32)
6128        __(cmpdi cr1,imm1,three_digit_bignum_header)
6129        __(cmpdi cr0,imm0,0)
6130        __(beq cr2,2f)
6131        __(lwz imm1,misc_data_offset+8(arg_z))
6132        __(bne cr1,0b)
6133        __(cmpwi imm1,0)
6134        __(bne 0b)
6135        __(blr)
61362:      __(blt 0b)
6137        __(blr)       
6138        __else
6139        __(extract_typecode(imm0,arg_z))
6140        __(cmpri(cr0,imm0,tag_fixnum))
6141        __(cmpri(cr1,arg_z,0))
6142        __(cmpri(cr2,imm0,subtag_bignum))
6143        __(unbox_fixnum(imm1,arg_z))
6144        __(bne cr0,8f)
6145        __(bgelr cr1)
61469:
6147        __(uuo_interr(error_object_not_u64,arg_z))
61488:
6149        __(bne- cr2,9b)
6150        __(getvheader(imm2,arg_z))
6151        __(cmpri(cr2,imm2,two_digit_bignum_header))
6152        __(vrefr(imm1,arg_z,0))
6153        __(cmpri(cr1,imm1,0))
6154        __(li imm0,0)
6155        __(bge cr2,2f)
6156        __(blt- cr1,9b)
6157        __(blr)
61582:
6159        __(cmpri(cr0,imm2,three_digit_bignum_header))
6160        __(vrefr(imm0,arg_z,1))
6161        __(cmpri(cr1,imm0,0))
6162        __(bne cr2,3f)
6163        __(blt- cr1,9b)
6164        __(blr)
61653:
6166        __(vrefr(imm2,arg_z,2))
6167        __(cmpri(cr1,imm2,0))
6168        __(bne- cr0,9b)
6169        __(bne- cr1,9b)
6170        __(blr)
6171        __endif
6172       
6173/* arg_z should be of type (SIGNED-BYTE 64);  */
6174/* PPC32:   return high 32 bits  in imm0, low 32 bits in imm1  */
6175/* PPC64:   return unboxed value in imm0  */
6176
6177_spentry(gets64)
6178        __ifdef([PPC64])
6179         __(extract_typecode(imm1,arg_z))
6180         __(unbox_fixnum(imm0,arg_z))
6181         __(cmpri(cr0,imm1,tag_fixnum))
6182         __(cmpri(cr2,imm1,subtag_bignum))
6183         __(beqlr cr0)
6184         __(bne cr2,9f)
6185         __(ld imm1,misc_header_offset(arg_z))
6186         __(ld imm0,misc_data_offset(arg_z))
6187         __(cmpdi imm1,two_digit_bignum_header)
6188         __(rotldi imm0,imm0,32)
6189         __(beqlr)
6190        __else
6191         __(extract_typecode(imm0,arg_z))
6192         __(cmpri(cr0,imm0,tag_fixnum))
6193         __(cmpri(cr2,imm0,subtag_bignum))
6194         __(unbox_fixnum(imm1,arg_z))
6195         __(srawi imm0,imm1,31)
6196         __(beqlr cr0)
6197         __(bne cr2,9f)
6198         __(getvheader(imm2,arg_z))
6199         __(cmpri(cr2,imm2,two_digit_bignum_header))
6200         __(vrefr(imm1,arg_z,0))
6201         __(srawi imm0,imm1,31)
6202         __(bltlr cr2)
6203         __(vrefr(imm0,arg_z,1))
6204         __(beqlr cr2)
6205        __endif
62069:
6207        __(uuo_interr(error_object_not_s64,arg_z))
6208
6209
6210/*  Construct a lisp integer out of the 64-bit unsigned value in */
6211/*        ppc32:    imm0 (high 32 bits) and imm1 (low 32 bits) */
6212/*        ppc64:    imm0 (64 bits) .  */
6213_spentry(makeu64)
6214        __ifdef([PPC64])
6215         __(clrrdi. imm1,imm0,63-nfixnumtagbits)
6216         __(cmpri(cr1,imm0,0))
6217         __(box_fixnum(arg_z,imm0))
6218         __(beqlr cr0) /* A fixnum  */
6219         __(rotldi imm1,imm0,32)
6220         __(li imm2,two_digit_bignum_header)
6221         __(blt cr1,2f)
6222         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6223         __(str(imm1,misc_data_offset(arg_z)))
6224         __(blr)
62252:
6226         __(li imm2,three_digit_bignum_header)
6227         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6228         __(str(imm1,misc_data_offset(arg_z)))
6229         __(blr)
6230        __else       
6231         __(cmpri(cr1,imm0,0))
6232         __(rlwinm. imm2,imm1,0,0,fixnum_shift)
6233         __(li imm2,three_digit_bignum_header)
6234         __(box_fixnum(arg_z,imm1))
6235         __(blt cr1,3f)
6236         __(bne cr1,2f)
6237         __(beqlr cr0) /* A fixnum  */
6238         __(blt cr0,2f)
6239         __(li imm2,one_digit_bignum_header)
6240         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
6241         __(str(imm1,misc_data_offset(arg_z)))
6242         __(blr)
62432:
6244         __(li imm2,two_digit_bignum_header)
6245         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6246         __(str(imm1,misc_data_offset(arg_z)))
6247         __(str(imm0,misc_data_offset+4(arg_z)))
6248         __(blr)
62493:
6250         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6251         __(str(imm1,misc_data_offset(arg_z)))
6252         __(str(imm0,misc_data_offset+4(arg_z)))
6253         __(blr)
6254        __endif
6255
6256
6257
6258/*  Construct a lisp integer out of the 64-bit signed value in */
6259/*        ppc32:    imm0 (high 32 bits) and imm1 (low 32 bits). */
6260/*        ppc64:    imm0  */
6261_spentry(makes64)
6262        __ifdef([PPC64])
6263         __(addo imm1,imm0,imm0)
6264         __(addo imm1,imm1,imm1)
6265         __(addo. arg_z,imm1,imm1)
6266         __(bnslr+)
6267         __(mtxer rzero)
6268         __(li imm1,two_digit_bignum_header)
6269         __(rotldi imm0,imm0,32)
6270         __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
6271         __(str(imm0,misc_data_offset(arg_z)))
6272         __(blr)
6273        __else
6274         __(srawi imm2,imm1,31)
6275         __(cmpr(cr1,imm2,imm0))
6276         __(addo imm2,imm1,imm1)
6277         __(addo. arg_z,imm2,imm2)
6278         __(bne cr1,2f) /* High word is significant  */
6279         __(li imm2,one_digit_bignum_header)
6280         __(bnslr cr0) /* No overflow:   fixnum  */
6281         __(mtxer rzero)
6282         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
6283         __(str(imm1,misc_data_offset(arg_z)))
6284         __(blr)
62852:
6286         __(mtxer rzero)
6287         __(li imm2,two_digit_bignum_header)
6288         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6289         __(str(imm1,misc_data_offset(arg_z)))
6290         __(str(imm0,misc_data_offset+4(arg_z)))
6291         __(blr)
6292        __endif
6293
6294/* imm0:imm1 constitute an unsigned integer, almost certainly a bignum. */
6295/* Make a lisp integer out of those 128 bits ..  */
6296_spentry(makeu128)
6297        __ifdef([PPC64])
6298         __(cmpdi imm0,0)
6299         __(cmpdi cr1,imm1,0)
6300         __(srdi imm3,imm0,32)
6301         __(srawi imm4,imm0,31)
6302         __(cmpdi cr3,imm3,0)
6303         __(cmpdi cr4,imm4,0)
6304         __(li imm2,five_digit_bignum_header)
6305         __(blt cr1,0f)
6306         __(beq 3f)
63070:             
6308         __(bge 1f)
6309         /* All 128 bits are significant, and the most significant */
6310         /* bit is set.  Allocate a 5-digit bignum (with a zero */
6311         /* sign digit  */
6312         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(5)))
6313         __(rotldi imm0,imm0,32)
6314         __(rotldi imm1,imm1,32)
6315         __(std imm1,misc_data_offset(arg_z))
6316         __(std imm0,misc_data_offset+8(arg_z))
6317         __(blr)
63181:       /* If the high word of imm0 is a zero-extension of the low */
6319         /* word, we only need 3 digits ; otherwise, we need 4.  */
6320         __(li imm2,three_digit_bignum_header)
6321         __(rotldi imm1,imm1,32)
6322         __(bne cr3,2f) /* high word of imm0 is non-zero  */
6323         __(bne cr4,2f) /* sign bit is on in low word of imm0  */
6324         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6325         __(std imm1,misc_data_offset(arg_z))
6326         __(stw imm0,misc_data_offset+8(arg_z))
6327         __(blr)
63282:       __(li imm2,four_digit_bignum_header)
6329         __(rotldi imm0,imm0,32)
6330         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
6331         __(std imm1,misc_data_offset(arg_z))
6332         __(std imm0,misc_data_offset+8(arg_z))
6333         __(blr)
63343:       __(mr imm0,imm1)
6335         __(b _SPmakeu64)             
6336        __else
6337         __(twgei r0,r0)
6338        __endif
6339
6340/* imm0:imm1 constitute a signed integer, almost certainly a bignum. */
6341/* Make a lisp integer out of those 128 bits ..  */
6342_spentry(makes128)
6343        __ifdef([PPC64])
6344         /* Is imm0 just a sign-extension of imm1 ?  */
6345         __(sradi imm2,imm1,63)
6346         /* Is the high word of imm0 just a sign-extension of the low word ?  */
6347         __(extsw imm3,imm0)
6348         __(cmpd imm2,imm0)
6349         __(cmpd cr1,imm3,imm0)
6350         __(beq 2f)
6351         __(rotldi imm0,imm0,32)
6352         __(rotldi imm1,imm1,32)
6353         __(beq cr1,1f)
6354         __(li imm2,four_digit_bignum_header)
6355         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
6356         __(std imm1,misc_data_offset(arg_z))
6357         __(std imm0,misc_data_offset+8(arg_z))
6358         __(blr)
63591:       __(li imm2,three_digit_bignum_header)
6360         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6361         __(std imm1,misc_data_offset(arg_z))
6362         __(stw imm3,misc_data_offset+8(arg_z))
6363         __(blr)
63642:       __(mr imm0,imm1)
6365         __(b _SPmakes64)       
6366        __else
6367         __(twgei r0,r0)
6368        __endif       
6369                       
6370/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
6371/* unbound_marker), arg_y = symbol, imm3 = symbol.binding-index  */
6372_spentry(specref)
6373        __(ldr(imm3,symbol.binding_index(arg_z)))
6374        __(ldr(imm0,tcr.tlb_limit(rcontext)))
6375        __(cmpr(imm3,imm0))
6376        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6377        __(mr arg_y,arg_z)
6378        __(bge 1f)
6379        __(ldrx(arg_z,imm2,imm3))
6380        __(cmpri(arg_z,no_thread_local_binding_marker))
6381        __(bnelr)
63821:      __(ldr(arg_z,symbol.vcell(arg_y)))
6383        __(blr)
6384
6385
6386_spentry(specrefcheck)
6387        __(ldr(imm3,symbol.binding_index(arg_z)))
6388        __(ldr(imm0,tcr.tlb_limit(rcontext)))
6389        __(cmpr(imm3,imm0))
6390        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6391        __(mr arg_y,arg_z)
6392        __(bge 1f)
6393        __(ldrx(arg_z,imm2,imm3))
6394        __(cmpri(arg_z,no_thread_local_binding_marker))
6395        __(bne 2f)
63961:      __(ldr(arg_z,symbol.vcell(arg_y)))
63972:      __(treqi(arg_z,unbound_marker))
6398        __(blr)
6399       
6400/* arg_y = special symbol, arg_z = new value.          */
6401_spentry(specset)
6402        __(ldr(imm3,symbol.binding_index(arg_y)))
6403        __(ldr(imm0,tcr.tlb_limit(rcontext)))
6404        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6405        __(cmpr(imm3,imm0))
6406        __(bge 1f)
6407        __(ldrx(temp1,imm2,imm3))
6408        __(cmpri(temp1,no_thread_local_binding_marker))
6409        __(beq 1f)
6410        __(strx(arg_z,imm2,imm3))
6411        __(blr)
64121:      __(mr arg_x,arg_y)
6413        __(li arg_y,symbol.vcell-misc_data_offset)
6414        __(b _SPgvset)
6415
6416/* Restore current thread's interrupt level to arg_z, */
6417/* noting whether the tcr's interrupt_pending flag was set.  */
6418_spentry(restoreintlevel)
6419        __(cmpri(cr1,arg_z,0))
6420        __(ldr(imm0,tcr.interrupt_pending(rcontext)))
6421        __(cmpri(cr0,imm0,0))
6422        __(bne cr1,1f)
6423        __(beq cr0,1f)
6424        __(str(rzero,tcr.interrupt_pending(rcontext)))
6425        __(li nargs,fixnum_one)
6426        __(trgti(nargs,0))
6427        __(blr)
64281:
6429        __(ldr(nargs,tcr.tlb_pointer(rcontext)))
6430        __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(nargs)))
6431        __(blr)
6432
6433
6434/* Construct a lisp integer out of the 32-bit signed value in imm0 */
6435
6436       
6437_spentry(makes32)
6438        __ifdef([PPC64])
6439         __(box_fixnum(arg_z,imm0))
6440        __else
6441         __(addo imm1,imm0,imm0)
6442         __(addo. arg_z,imm1,imm1)
6443         __(bnslr+)
6444         __(mtxer rzero)
6445         __(li imm1,one_digit_bignum_header)
6446         __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
6447         __(str(imm0,misc_data_offset(arg_z)))
6448        __endif
6449         __(blr)
6450
6451
6452/* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
6453
6454       
6455_spentry(makeu32)
6456        __ifdef([PPC64])
6457         __(box_fixnum(arg_z,imm0))
6458         __(blr)
6459        __else
6460         __(clrrwi. imm1,imm0,31-nfixnumtagbits)
6461         __(cmpri(cr1,imm0,0))
6462         __(box_fixnum(arg_z,imm0))
6463         __(beqlr cr0) /* A fixnum  */
6464         __(blt cr1,2f)
6465         __(li imm2,one_digit_bignum_header)
6466         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
6467         __(str(imm0,misc_data_offset(arg_z)))
6468         __(blr)
64692:
6470         __(li imm2,two_digit_bignum_header)
6471         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6472         __(str(imm0,misc_data_offset(arg_z)))
6473         __(blr)
6474        __endif
6475
6476/*  */
6477/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
6478/*  */
6479_spentry(gets32)
6480        __ifdef([PPC64])
6481         __(sldi imm1,arg_z,32-fixnumshift)
6482         __(extract_lisptag_(imm0,arg_z))
6483         __(sradi imm1,imm1,32-fixnumshift)
6484         __(box_fixnum(imm0,arg_z))
6485         __(cmpd cr1,imm1,arg_z)
6486         __(bne cr0,9f)
6487         __(beqlr cr1)
6488         __(b 9f)
6489        __else
6490         __(extract_typecode(imm1,arg_z))
6491         __(cmpri(cr0,imm1,tag_fixnum))
6492         __(cmpri(cr2,imm1,subtag_bignum))
6493         __(unbox_fixnum(imm0,arg_z))
6494         __(beqlr+ cr0)
6495         __(bne cr2,9f)
6496         __(getvheader(imm1,arg_z))
6497         __(cmpri(cr1,imm1,one_digit_bignum_header))
6498         __(vrefr(imm0,arg_z,0))
6499         __(beqlr+ cr1)
6500        __endif
65019:
6502        __(uuo_interr(error_object_not_signed_byte_32,arg_z))
6503
6504/*  */
6505/* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
6506/*  */
6507
6508_spentry(getu32)
6509        __(extract_typecode(imm1,arg_z))
6510        __(cmpri(cr0,imm1,tag_fixnum))
6511        __(cmpri(cr1,arg_z,0))
6512        __(cmpri(cr2,imm1,subtag_bignum))
6513        __(unbox_fixnum(imm0,arg_z))
6514        __(bne cr0,8f)
6515        __(bgelr cr1)
65168:
6517        __(bne- cr2,9f)
6518        __(getvheader(imm2,arg_z))
6519        __(cmpri(cr2,imm2,two_digit_bignum_header))
6520        __(vrefr(imm0,arg_z,0))
6521        __(cmpri(cr0,imm0,0))
6522        __(bgt cr2,9f)
6523        __(beq cr2,2f)
6524        __(blt cr0,9f)
6525        __(blr)
65262:
6527        __(vrefr(imm1,arg_z,1))
6528        __(cmpri(cr0,imm1,0))
6529        __(beqlr+ cr0)
6530
65319:
6532        __(uuo_interr(error_object_not_unsigned_byte_32,arg_z))
6533
6534/* */
6535/* arg_z has overflowed (by one bit) as the result of an addition or subtraction. */
6536/* Make a bignum out of it. */
6537
6538_spentry(fix_overflow)
6539        __(mtxer rzero)
6540        __(unbox_fixnum(imm1,arg_z))
6541        __ifdef([PPC64])
6542         __(li imm0,two_digit_bignum_header)
6543         __(rotldi imm1,imm1,32)
6544         __(xoris imm1,imm1,0xe000)
6545         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
6546         __(str(imm1,misc_data_offset(arg_z)))
6547        __else
6548         __(li imm0,one_digit_bignum_header)
6549         __(xoris imm1,imm1,0xc000)
6550         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
6551         __(str(imm1,misc_data_offset(arg_z)))
6552        __endif
6553        __(blr)
6554               
6555
6556
6557/* */
6558/* As per mvpass above, but in this case fname is known to be a */
6559/* symbol. */
6560
6561_spentry(mvpasssym)
6562        __(cmpri(cr0,nargs,node_size*nargregs))
6563        __(mflr loc_pc)
6564        __(mr imm0,vsp)
6565        __(ble+ cr0,1f)
6566         __(subi imm0,imm0,node_size*nargregs)
6567         __(add imm0,imm0,nargs)
65681:           
6569        __(build_lisp_frame(fn,loc_pc,imm0))
6570        __(ref_global(loc_pc,ret1val_addr))
6571        __(li fn,0)
6572        __(mtlr loc_pc)
6573        __(jump_fname())
6574
6575
6576
6577_spentry(unbind)
6578        __(ldr(imm1,tcr.db_link(rcontext)))
6579        __(ldr(imm2,tcr.tlb_pointer(rcontext)))   
6580        __(ldr(imm3,binding.sym(imm1)))
6581        __(ldr(temp1,binding.val(imm1)))
6582        __(ldr(imm1,binding.link(imm1)))
6583        __(strx(temp1,imm2,imm3))
6584        __(str(imm1,tcr.db_link(rcontext)))
6585        __(blr)
6586
6587_spentry(unbind_n)
6588        __(ldr(imm1,tcr.db_link(rcontext)))
6589        __(ldr(imm2,tcr.tlb_pointer(rcontext)))   
65901:      __(subi imm0,imm0,1)
6591        __(ldr(imm3,binding.sym(imm1)))
6592        __(ldr(temp1,binding.val(imm1)))
6593        __(cmpri(imm0,0))
6594        __(ldr(imm1,binding.link(imm1)))
6595        __(strx(temp1,imm2,imm3))
6596        __(bne 1b)
6597        __(str(imm1,tcr.db_link(rcontext)))
6598        __(blr)
6599
6600/* */
6601/* Clobbers imm1,imm2,imm5,arg_x, arg_y */
6602
6603_spentry(unbind_to)
6604        __(ldr(imm1,tcr.db_link(rcontext)))
6605        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
66061:      __(ldr(imm5,binding.sym(imm1)))
6607        __(ldr(arg_y,binding.val(imm1)))
6608        __(ldr(imm1,binding.link(imm1)))
6609        __(cmpr(imm0,imm1))
6610        __(strx(arg_y,imm2,imm5))
6611        __(bne 1b)
6612        __(str(imm1,tcr.db_link(rcontext)))
6613        __(blr)
6614       
6615
6616
6617/* */
6618/* Restore the special bindings from the top of the tstack,  */
6619/* leaving the tstack frame allocated.  */
6620/* Note that there might be 0 saved bindings, in which case  */
6621/* do nothing.  */
6622/* Note also that this is -only- called from an unwind-protect  */
6623/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
6624/* values in a frame on top of the tstack.  */
6625/*  */
6626                       
6627_spentry(progvrestore)
6628        __(ldr(imm0,tsp_frame.backlink(tsp)))   /* ignore .SPnthrowXXX values frame  */
6629        __(ldr(imm0,tsp_frame.data_offset(imm0)))
6630        __(cmpri(cr0,imm0,0))
6631        __(unbox_fixnum(imm0,imm0))
6632        __(bne+ cr0,_SPunbind_n)
6633        __(blr)
6634
6635/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
6636/* for pending interrupts after doing so.  "nargs" can be freely used for an */
6637/* interrupt trap in this context.  */
6638_spentry(bind_interrupt_level_0)
6639        __(ldr(imm4,tcr.tlb_pointer(rcontext)))
6640        __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6641        __(ldr(imm1,tcr.db_link(rcontext)))
6642        __(cmpri(temp0,0))
6643        __(li imm3,INTERRUPT_LEVEL_BINDING_INDEX)
6644        __(vpush(temp0))
6645        __(vpush(imm3))
6646        __(vpush(imm1))
6647        __(str(rzero,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6648        __(str(vsp,tcr.db_link(rcontext)))
6649        __(beqlr)
6650        __(mr nargs,temp0)
6651        __(bgt 1f)
6652        __(ldr(nargs,tcr.interrupt_pending(rcontext)))
66531:      __(trgti(nargs,0))       
6654        __(blr)
6655
6656/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
6657/* of disabling interrupts.)  */
6658_spentry(bind_interrupt_level_m1)
6659        __(li imm2,-fixnumone)
6660        __(li imm3,INTERRUPT_LEVEL_BINDING_INDEX)
6661        __(ldr(imm4,tcr.tlb_pointer(rcontext)))
6662        __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6663        __(ldr(imm1,tcr.db_link(rcontext)))
6664        __(vpush(temp0))
6665        __(vpush(imm3))
6666        __(vpush(imm1))
6667        __(str(imm2,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6668        __(str(vsp,tcr.db_link(rcontext)))
6669        __(blr)
6670
6671       
6672/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
6673/* do what _SPbind_interrupt_level_0 does  */
6674_spentry(bind_interrupt_level)
6675        __(cmpri(arg_z,0))
6676        __(li imm3,INTERRUPT_LEVEL_BINDING_INDEX)
6677        __(ldr(imm4,tcr.tlb_pointer(rcontext)))
6678        __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6679        __(ldr(imm1,tcr.db_link(rcontext)))
6680        __(beq _SPbind_interrupt_level_0)
6681        __(vpush(temp0))
6682        __(vpush(imm3))
6683        __(vpush(imm1))
6684        __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6685        __(str(vsp,tcr.db_link(rcontext)))
6686        __(blr)
6687
6688/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
6689/* non-negative, check for pending interrupts.  This is often called in */
6690/* a context where nargs is significant, so save and restore nargs around */
6691/* any interrupt polling  */
6692       
6693_spentry(unbind_interrupt_level)
6694        __(ldr(imm0,tcr.flags(rcontext)))
6695        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6696        __(andi. imm0,imm0,1<<TCR_FLAG_BIT_PENDING_SUSPEND)
6697        __(ldr(imm1,tcr.db_link(rcontext)))
6698        __(ldr(temp1,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
6699        __(bne 5f)
67000:      __(cmpri(cr1,temp1,0))
6701        __(ldr(temp1,binding.val(imm1)))
6702        __(ldr(imm1,binding.link(imm1)))
6703        __(cmpri(cr0,temp1,0))
6704        __(str(temp1,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
6705        __(str(imm1,tcr.db_link(rcontext)))
6706        __(bgelr cr1)
6707        __(bltlr cr0)
6708        __(mr imm2,nargs)
6709        __(check_pending_interrupt([cr1]))
6710        __(mr nargs,imm2)
6711        __(blr)
67125:       /* Missed a suspend request; force suspend now if we're restoring
6713          interrupt level to -1 or greater */
6714        __(cmpri(temp1,-2<<fixnumshift))
6715        __(bne 0b)
6716        __(ldr(imm0,binding.val(imm1)))
6717        __(cmpr(imm0,temp1))
6718        __(beq 0b)
6719        __(li imm0,1<<fixnumshift)
6720        __(str(imm0,INTERRUPT_LEVEL_BINDING_INDEX(imm2)))
6721        __(suspend_now())
6722        __(b 0b)
6723
6724
6725/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
6726   We don't know whether the array is alleged to be simple or
6727   not, and don't know anythng about the element type.  */
6728_spentry(aref2)
6729        __(extract_typecode(imm2,arg_x))
6730        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
6731        __(cmpri(cr2,imm2,subtag_arrayH))
6732        __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
6733        __(bne cr2,1f)
6734        __(ldr(imm1,arrayH.rank(arg_x)))
6735        __(cmpri(imm1,2<<fixnumshift))
6736        __(bne 1f)
6737        /* It's a 2-dimensional array.  Check bounds */
6738        __(ldr(imm0,arrayH.dim0(arg_x)))
6739        __(trlge(arg_y,imm0))
6740        __(ldr(imm0,arrayH.dim0+node_size(arg_x)))
6741        __(trlge(arg_z,imm0))
6742        __(unbox_fixnum(imm0,imm0))
6743        __(mullr(arg_y,arg_y,imm0))
6744        __(add arg_z,arg_z,arg_y)
6745        /* arg_z is now row-major-index; get data vector and
6746           add in possible offset */
6747        __(mr arg_y,arg_x)
67480:      __(ldr(imm0,arrayH.displacement(arg_y)))
6749        __(ldr(arg_y,arrayH.data_vector(arg_y)))
6750        __(extract_subtag(imm1,arg_y))
6751        __(cmpri(imm1,subtag_vectorH))
6752        __(add arg_z,arg_z,imm0)
6753        __(bgt local_label(misc_ref_common))
6754        __(b 0b)
67551:             
6756        __(uuo_interr(error_object_not_array_2d,arg_x))
6757
6758/* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
6759_spentry(aref3)
6760        __(extract_typecode(imm2,temp0))
6761        __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
6762        __(cmpri(cr2,imm2,subtag_arrayH))
6763        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
6764        __(bne cr2,1f)
6765        __(ldr(imm1,arrayH.rank(temp0)))
6766        __(trap_unless_lisptag_equal(arg_z,tag_fixnum,imm0))
6767        __(cmpri(imm1,3<<fixnumshift))
6768        __(bne 1f)
6769        /* It's a 3-dimensional array.  Check bounds */
6770        __(ldr(imm2,arrayH.dim0+(node_size*2)(temp0)))
6771        __(ldr(imm1,arrayH.dim0+node_size(temp0)))
6772        __(ldr(imm0,arrayH.dim0(temp0)))
6773        __(trlge(arg_z,imm2))
6774        __(unbox_fixnum(imm2,imm2))
6775        __(trlge(arg_y,imm1))
6776        __(unbox_fixnum(imm1,imm1))
6777        __(trlge(arg_x,imm0))
6778        __(mullr(arg_y,arg_y,imm2))
6779        __(mullr(imm1,imm2,imm1))
6780        __(mullr(arg_x,imm1,arg_x))
6781        __(add arg_z,arg_z,arg_y)
6782        __(add arg_z,arg_z,arg_x)
6783        __(mr arg_y,temp0)
67840:      __(ldr(arg_x,arrayH.displacement(arg_y)))
6785        __(ldr(arg_y,arrayH.data_vector(arg_y)))
6786        __(extract_subtag(imm1,arg_y))
6787        __(cmpri(imm1,subtag_vectorH))
6788        __(add arg_z,arg_x,arg_z)
6789        __(bgt local_label(misc_ref_common))
6790        __(b 0b)
67911:             
6792        __(uuo_interr(error_object_not_array_3d,temp0))
6793
6794       
6795       
6796
6797/* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
6798_spentry(aset2)
6799        __(extract_typecode(imm2,temp0))
6800        __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
6801        __(cmpri(cr2,imm2,subtag_arrayH))
6802        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
6803        __(bne cr2,1f)
6804        __(ldr(imm1,arrayH.rank(temp0)))
6805        __(cmpri(imm1,2<<fixnumshift))
6806        __(bne 1f)
6807        /* It's a 2-dimensional array.  Check bounds */
6808        __(ldr(imm0,arrayH.dim0(temp0)))
6809        __(trlge(arg_x,imm0))
6810        __(ldr(imm0,arrayH.dim0+node_size(temp0)))
6811        __(trlge(arg_y,imm0))
6812        __(unbox_fixnum(imm0,imm0))
6813        __(mullr(arg_x,arg_x,imm0))
6814        __(add arg_y,arg_y,arg_x)
6815        /* arg_y is now row-major-index; get data vector and
6816           add in possible offset */
6817        __(mr arg_x,temp0)
68180:      __(ldr(imm0,arrayH.displacement(arg_x)))
6819        __(ldr(arg_x,arrayH.data_vector(arg_x)))
6820        __(extract_subtag(imm1,arg_x))
6821        __(cmpri(imm1,subtag_vectorH))
6822        __(add arg_y,arg_y,imm0)
6823        __(bgt local_label(misc_set_common))
6824        __(b 0b)
68251:             
6826        __(uuo_interr(error_object_not_array_2d,temp0))       
6827               
6828/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
6829_spentry(aset3)
6830        __(extract_typecode(imm2,temp1))
6831        __(trap_unless_lisptag_equal(temp0,tag_fixnum,imm0))
6832        __(cmpri(cr2,imm2,subtag_arrayH))
6833        __(trap_unless_lisptag_equal(arg_x,tag_fixnum,imm0))
6834        __(bne cr2,1f)
6835        __(ldr(imm1,arrayH.rank(temp1)))
6836        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
6837        __(cmpri(imm1,3<<fixnumshift))
6838        __(bne 1f)
6839        /* It's a 3-dimensional array.  Check bounds */
6840        __(ldr(imm2,arrayH.dim0+(node_size*2)(temp1)))
6841        __(ldr(imm1,arrayH.dim0+node_size(temp1)))
6842        __(ldr(imm0,arrayH.dim0(temp1)))
6843        __(trlge(arg_y,imm2))
6844        __(unbox_fixnum(imm2,imm2))
6845        __(trlge(arg_x,imm1))
6846        __(unbox_fixnum(imm1,imm1))
6847        __(trlge(temp0,imm0))
6848        __(mullr(arg_x,arg_x,imm2))
6849        __(mullr(imm1,imm2,imm1))
6850        __(mullr(temp0,imm1,temp0))
6851        __(add arg_y,arg_y,arg_x)
6852        __(add arg_y,arg_y,temp0)
6853        __(mr arg_x,temp1)
68540:      __(ldr(temp0,arrayH.displacement(arg_x)))
6855        __(ldr(arg_x,arrayH.data_vector(arg_x)))
6856        __(extract_subtag(imm1,arg_x))
6857        __(cmpri(imm1,subtag_vectorH))
6858        __(add arg_y,arg_y,temp0)
6859        __(bgt local_label(misc_set_common))
6860        __(b 0b)
68611:             
6862        __(uuo_interr(error_object_not_array_3d,temp1))
6863
6864
6865       
6866
6867_spentry(nmkunwind)
6868        __(li imm2,-fixnumone)
6869        __(li imm3,INTERRUPT_LEVEL_BINDING_INDEX)
6870        __(ldr(imm4,tcr.tlb_pointer(rcontext)))
6871        __(ldr(arg_y,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6872        __(ldr(imm1,tcr.db_link(rcontext)))
6873        __(vpush(arg_y))
6874        __(vpush(imm3))
6875        __(vpush(imm1))
6876        __(str(imm2,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6877        __(str(vsp,tcr.db_link(rcontext)))
6878        __(lwi(arg_z,unbound_marker))
6879        __(li imm2,fixnum_one)
6880        __(mkcatch())
6881        __(mr arg_z,arg_y)
6882        __(b _SPbind_interrupt_level)
6883
6884_spentry(unused_6)
6885         __(b _SPbreakpoint)
6886                       
6887       
6888
6889
6890                               
6891/*  EOF, basically  */
6892        .globl _SPsp_end
6893        b _SPsp_end
6894        _endfile
Note: See TracBrowser for help on using the repository browser.