source: release/1.9/source/lisp-kernel/ppc-spentry.s @ 16083

Last change on this file since 16083 was 15851, checked in by gb, 6 years ago

Reinstate old destructuring subprims, which were removed prematurely.

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