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

Last change on this file since 14347 was 13337, checked in by plkrueger, 10 years ago

Don't change the m4 quoting characters from their defaults (`').
(On the ARM, square brackets are used to denote memory operands, curly
braces surround register lists, and multicharacter quoting delimeters
look funny ...)

Some versions (at least) of m4 are confused by quoting characters in
comments, so try to refrain from using contractions ...

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