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

Last change on this file since 15703 was 15703, checked in by gb, 7 years ago

If _SPmisc_alloc is called with an "element-count" argument >=
ARRAY-TOTAL-SIZE-LIMIT, call out to lisp rather than executing a type
error UUO. On the lisp side, signal a VECTOR-SIZE-LIMITATION, which
is a kind of STORAGE-CONDITION.

CALL-WITH-STRING-VECTOR takes an ENCODING argument and uses that
character encoding to encode the strings in the vector. (It assumes
an 8-bit encoding; the strings are terminated with single #\NUL bytes.)
On Unix, RUN-PROGRAM calls CALL-WITH-STRING-VECTOR with the encoding from
its EXTERNAL-FORMAT argument.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 241.8 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         __(lri arg_x,XARRLIMIT)
3313         __(set_nargs(3))
3314         __(b _SPksignalerr)
3315        __else
3316         __(extract_unsigned_byte_bits_(imm2,arg_y,24))
3317         __(unbox_fixnum(imm0,arg_z))
3318         __(extract_fulltag(imm1,imm0))
3319         __(bne- cr0,9f)
3320         __(cmpri(cr0,imm1,fulltag_nodeheader))
3321         __(mr imm3,imm0)
3322         __(cmplri(cr1,imm0,max_32_bit_ivector_subtag))
3323         __(rlwimi imm0,arg_y,num_subtag_bits-fixnum_shift,0,31-num_subtag_bits )/* imm0 now = header  */
3324         __(mr imm2,arg_y)
3325         __(beq cr0,1f) /* do probe if node object (fixnum element count = byte count).  */
3326         __(cmplri(cr0,imm3,max_16_bit_ivector_subtag))
3327         __(bng cr1,1f) /* do probe if 32-bit imm object  */
3328         __(cmplri(cr1,imm3,max_8_bit_ivector_subtag))
3329         __(srwi imm2,imm2,1)
3330         __(bgt cr0,2f)
3331         __(bgt cr1,1f)
3332         __(srwi imm2,imm2,1)
3333        /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
3334        /* low three bits.  */
33351:
3336         __(dnode_align(imm2,imm2,node_size))
3337
3338         __(Misc_Alloc(arg_z,imm0,imm2))
3339         __(blr)
33402:
3341         __(cmplri(imm3,subtag_double_float_vector))
3342         __(slwi imm2,arg_y,1)
3343         __(beq 1b)
3344         __(addi imm2,arg_y,7<<fixnumshift)
3345         __(srwi imm2,imm2,fixnumshift+3)
3346         __(b 1b)
33479:
3348         __(lri arg_x,XARRLIMIT)
3349         __(set_nargs(3))
3350         __(b _SPksignalerr)
3351        __endif
3352       
3353/* almost exactly as above, but "swap exception handling info" */
3354/* on exit and return  */
3355/* Deprecated */       
3356_spentry(poweropen_ffcallX)
3357_spentry(macro_bind)
3358_spentry(destructuring_bind)
3359_spentry(destructuring_bind_inner)
3360        .long 0x7c800008        /* debug trap */
3361       
3362/* vpush the values in the value set atop the vsp, incrementing nargs.  */
3363/* Discard the tsp frame; leave values atop the vsp.  */
3364
3365_spentry(recover_values)
3366
3367/* First, walk the segments reversing the pointer to previous segment pointers  */
3368/* Can tell the end because that previous segment pointer is the prev tsp pointer  */
3369        __(ldr(imm0,tsp_frame.backlink(tsp))) /* previous tsp  */
3370        __(mr imm1,tsp) /* current segment  */
3371        __(mr imm2,tsp) /* last segment  */
3372local_label(walkloop):
3373        __(ldr(imm3,tsp_frame.fixed_overhead+node_size(imm1))) /* next segment  */
3374        __(cmpr(cr0,imm0,imm3)) /* last segment?  */
3375        __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
3376        __(mr imm2,imm1) /* last segment <- current segment  */
3377        __(mr imm1,imm3) /* current segment <- next segment  */
3378        __(bne cr0,local_label(walkloop))
3379
3380        /* the final segment ptr is now in imm2  */
3381        /* walk backwards, pushing values on VSP and incrementing NARGS  */
3382local_label(pushloop):
3383        __(ldr(imm0,tsp_frame.data_offset(imm2))) /* nargs in segment  */
3384        __(cmpri(cr0,imm0,0))
3385        __(cmpr(cr1,imm2,tsp))
3386        __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
3387        __(add imm3,imm3,imm0)
3388        __(add nargs,nargs,imm0)
3389        __(b 2f)
33901:
3391        __(ldru(arg_z,-node_size(imm3)))
3392        __(cmpri(cr0,imm0,fixnum_one))
3393        __(subi imm0,imm0,fixnum_one)
3394        __(vpush(arg_z))
33952:
3396        __(bne cr0,1b)
3397        __(ldr(imm2,tsp_frame.data_offset+node_size(imm2))) /* previous segment  */
3398        __(bne cr1,local_label(pushloop))
3399        __(unlink(tsp))
3400        __(blr)
3401
3402       
3403/* Go out of line to do this.  Sheesh.  */
3404
3405_spentry(vpopargregs)
3406        __(cmpri(cr0,nargs,0))
3407        __(cmpri(cr1,nargs,2<<fixnumshift))
3408        __(beqlr cr0)
3409        __(beq cr1,local_label(yz))
3410        __(blt cr1,local_label(z))
3411        __(ldr(arg_z,node_size*0(vsp)))
3412        __(ldr(arg_y,node_size*1(vsp)))
3413        __(ldr(arg_x,node_size*2(vsp)))
3414        __(la vsp,node_size*3(vsp))
3415        __(blr)
3416local_label(yz):
3417        __(ldr(arg_z,node_size*0(vsp)))
3418        __(ldr(arg_y,node_size*1(vsp)))
3419        __(la vsp,node_size*2(vsp))
3420        __(blr)
3421local_label(z):
3422        __(ldr(arg_z,node_size*0(vsp)))
3423        __(la vsp,node_size*1(vsp))
3424        __(blr)
3425
3426/* If arg_z is an integer, return in imm0 something whose sign  */
3427/* is the same as arg_z's.  If not an integer, error.  */
3428_spentry(integer_sign)
3429        __(extract_typecode(imm0,arg_z))
3430        __(cmpri(cr1,imm0,tag_fixnum))
3431        __(cmpri(cr0,imm0,subtag_bignum))
3432        __(mr imm0,arg_z)
3433        __(beqlr+ cr1)
3434        __(bne- cr0,1f)
3435        __(getvheader(imm0,arg_z))
3436        __ifdef(`PPC64')
3437         __(header_size(imm0,imm0))
3438         __(sldi imm0,imm0,2)
3439        __else
3440         __(header_length(imm0,imm0)) /* boxed length = scaled size  */
3441        __endif
3442        __(addi imm0,imm0,misc_data_offset-4) /* bias, less 1 element  */
3443        __(lwzx imm0,arg_z,imm0)
3444        __(cmpwi cr0,imm0,0)
3445        __(li imm0,1)
3446        __(bgelr cr0)
3447        __(li imm0,-1)
3448        __(blr)
34491:
3450        __(uuo_interr(error_object_not_integer,arg_z))
3451
3452/* like misc_set, only pass the (boxed) subtag in temp0  */
3453_spentry(subtag_misc_set)
3454        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
3455        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
3456        __(vector_length(imm0,arg_x,imm1))
3457        __(trlge(arg_y,imm0))
3458        __(unbox_fixnum(imm1,temp0))
3459local_label(misc_set_common):
3460        __ifdef(`PPC64')
3461         __(slwi imm1,imm1,3)
3462         __(li imm0,LO(local_label(misc_set_jmp)))
3463         __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
3464         __(ldx imm0,imm0,imm1)
3465         __(mtctr imm0)
3466         __(bctr)
3467local_label(misc_set_jmp):             
3468        /* 00-0*/
3469         .quad local_label(misc_set_invalid) /* 00 even_fixnum  */
3470         .quad local_label(misc_set_invalid) /* 01 imm_0  */
3471         .quad local_label(misc_set_invalid) /* 02 immheader_0  */
3472         .quad _SPgvset /* 03 function  */
3473         .quad local_label(misc_set_invalid) /* 04 cons  */
3474         .quad local_label(misc_set_invalid) /* 05 imm_1  */
3475         .quad local_label(misc_set_invalid) /* 06 immheader_1  */
3476         .quad _SPgvset /* 07 catch_frame  */
3477         .quad local_label(misc_set_invalid) /* 08 odd_fixnum  */
3478         .quad local_label(misc_set_invalid) /* 09 imm_2  */
3479         .quad local_label(misc_set_u32) /* 0a code_vector  */
3480         .quad _SPgvset /* 0b slot_vector  */
3481         .quad local_label(misc_set_invalid) /* 0c misc  */
3482         .quad local_label(misc_set_invalid) /* 0d imm3  */
3483         .quad local_label(misc_set_invalid) /* 0e immheader_3  */
3484         .quad _SPgvset /* 0f ratio  */
3485        /* 10-1*/
3486         .quad local_label(misc_set_invalid) /* 10 even_fixnum  */
3487         .quad local_label(misc_set_invalid) /* 11 imm_0  */
3488         .quad local_label(misc_set_invalid) /* 12 immheader_0  */
3489         .quad _SPgvset /* 13 symbol_0  */
3490         .quad local_label(misc_set_invalid) /* 14 cons  */
3491         .quad local_label(misc_set_invalid) /* 15 imm_1  */
3492         .quad local_label(misc_set_invalid) /* 16 immheader_1  */
3493         .quad _SPgvset /* 17 lisp_tread  */
3494         .quad local_label(misc_set_invalid) /* 18 odd_fixnum  */
3495         .quad local_label(misc_set_invalid) /* 19 imm_2  */
3496         .quad local_label(misc_set_u32) /* 1a xcode_vector  */
3497         .quad _SPgvset /* 1b instance  */
3498         .quad local_label(misc_set_invalid) /* 1c misc  */
3499         .quad local_label(misc_set_invalid) /* 1d imm3  */
3500         .quad local_label(misc_set_u64) /* 1e macptr  */
3501         .quad _SPgvset /* 1f complex  */
3502        /* 20-2*/
3503         .quad local_label(misc_set_invalid) /* 20 even_fixnum  */
3504         .quad local_label(misc_set_invalid) /* 21 imm_0  */
3505         .quad local_label(misc_set_invalid) /* 22 immheader_0  */
3506         .quad local_label(misc_set_invalid) /* 23 nodeheader_0  */
3507         .quad local_label(misc_set_invalid) /* 24 cons  */
3508         .quad local_label(misc_set_invalid) /* 25 imm_1  */
3509         .quad local_label(misc_set_invalid) /* 26 immheader_1  */
3510         .quad _SPgvset /* 27 lock  */
3511         .quad local_label(misc_set_invalid) /* 28 odd_fixnum  */
3512         .quad local_label(misc_set_invalid) /* 29 imm_2  */
3513         .quad local_label(misc_set_u32) /* 2a bignum  */
3514         .quad _SPgvset /* 2b struct  */
3515         .quad local_label(misc_set_invalid) /* 2c misc  */
3516         .quad local_label(misc_set_invalid) /* 2d imm3  */
3517         .quad local_label(misc_set_u64) /* 2e dead_macptr  */
3518         .quad local_label(misc_set_invalid) /* 2f nodeheader_3  */
3519        /* 30-3*/
3520         .quad local_label(misc_set_invalid) /* 30 even_fixnum  */
3521         .quad local_label(misc_set_invalid) /* 31 imm_0  */
3522         .quad local_label(misc_set_invalid) /* 32 immheader_0  */
3523         .quad local_label(misc_set_invalid) /* 33 nodeheader_0  */
3524         .quad local_label(misc_set_invalid) /* 34 cons  */
3525         .quad local_label(misc_set_invalid) /* 35 imm_1  */
3526         .quad local_label(misc_set_invalid) /* 36 immheader_1  */
3527         .quad _SPgvset /* 37 hash_vector  */
3528         .quad local_label(misc_set_invalid) /* 38 odd_fixnum  */
3529         .quad local_label(misc_set_invalid) /* 39 imm_2  */
3530         .quad local_label(misc_set_u32) /* 3a double_float  */
3531         .quad _SPgvset /* 3b istruct  */
3532         .quad local_label(misc_set_invalid) /* 3c misc  */
3533         .quad local_label(misc_set_invalid) /* 3d imm3  */
3534         .quad local_label(misc_set_invalid) /* 3e immheader_3  */
3535         .quad local_label(misc_set_invalid) /* 3f nodeheader_3  */
3536        /* 40-4*/
3537         .quad local_label(misc_set_invalid) /* 40 even_fixnum  */
3538         .quad local_label(misc_set_invalid) /* 41 imm_0  */
3539         .quad local_label(misc_set_invalid) /* 42 immheader_0  */
3540         .quad local_label(misc_set_invalid) /* 43 nodeheader_0  */
3541         .quad local_label(misc_set_invalid) /* 44 cons  */
3542         .quad local_label(misc_set_invalid) /* 45 imm_1  */
3543         .quad local_label(misc_set_invalid) /* 46 immheader_1  */
3544         .quad _SPgvset /* 47 pool  */
3545         .quad local_label(misc_set_invalid) /* 48 odd_fixnum  */
3546         .quad local_label(misc_set_invalid) /* 49 imm_2  */
3547         .quad local_label(misc_set_invalid) /* 4a immheader_2  */
3548         .quad _SPgvset /* 4b value_cell_2  */
3549         .quad local_label(misc_set_invalid) /* 4c misc  */
3550         .quad local_label(misc_set_invalid) /* 4d imm3  */
3551         .quad local_label(misc_set_invalid) /* 4e immheader_3  */
3552         .quad local_label(misc_set_invalid) /* 4f nodeheader_3  */
3553        /* 50-5*/
3554         .quad local_label(misc_set_invalid) /* 50 even_fixnum  */
3555         .quad local_label(misc_set_invalid) /* 51 imm_0  */
3556         .quad local_label(misc_set_invalid) /* 52 immheader_0  */
3557         .quad local_label(misc_set_invalid) /* 53 nodeheader_0  */
3558         .quad local_label(misc_set_invalid) /* 54 cons  */
3559         .quad local_label(misc_set_invalid) /* 55 imm_1  */
3560         .quad local_label(misc_set_invalid) /* 56 immheader_1  */
3561         .quad _SPgvset /* 57 weak  */
3562         .quad local_label(misc_set_invalid) /* 58 odd_fixnum  */
3563         .quad local_label(misc_set_invalid) /* 59 imm_2  */
3564         .quad local_label(misc_set_invalid) /* 5a immheader_2  */
3565         .quad _SPgvset /* 5b xfunction  */
3566         .quad local_label(misc_set_invalid) /* 5c misc  */
3567         .quad local_label(misc_set_invalid) /* 5d imm3  */
3568         .quad local_label(misc_set_invalid) /* 5e immheader_3  */
3569         .quad local_label(misc_set_invalid) /* 5f nodeheader_3  */
3570        /* 60-6*/
3571         .quad local_label(misc_set_invalid) /* 60 even_fixnum  */
3572         .quad local_label(misc_set_invalid) /* 61 imm_0  */
3573         .quad local_label(misc_set_invalid) /* 62 immheader_0  */
3574         .quad local_label(misc_set_invalid) /* 63 nodeheader_0  */
3575         .quad local_label(misc_set_invalid) /* 64 cons  */
3576         .quad local_label(misc_set_invalid) /* 65 imm_1  */
3577         .quad local_label(misc_set_invalid) /* 66 immheader_1  */
3578         .quad _SPgvset /* 67 package  */
3579         .quad local_label(misc_set_invalid) /* 68 odd_fixnum  */
3580         .quad local_label(misc_set_invalid) /* 69 imm_2  */
3581         .quad local_label(misc_set_invalid) /* 6a immheader_2  */
3582         .quad local_label(misc_set_invalid) /* 6b nodeheader_2  */
3583         .quad local_label(misc_set_invalid) /* 6c misc  */
3584         .quad local_label(misc_set_invalid) /* 6d imm3  */
3585         .quad local_label(misc_set_invalid) /* 6e immheader_3  */
3586         .quad local_label(misc_set_invalid) /* 6f nodeheader_3  */
3587        /* 70-7*/
3588         .quad local_label(misc_set_invalid) /* 70 even_fixnum  */
3589         .quad local_label(misc_set_invalid) /* 71 imm_0  */
3590         .quad local_label(misc_set_invalid) /* 72 immheader_0  */
3591         .quad local_label(misc_set_invalid) /* 73 nodeheader_0  */
3592         .quad local_label(misc_set_invalid) /* 74 cons  */
3593         .quad local_label(misc_set_invalid) /* 75 imm_1  */
3594         .quad local_label(misc_set_invalid) /* 76 immheader_1  */
3595         .quad local_label(misc_set_invalid) /* 77 nodeheader_1  */
3596         .quad local_label(misc_set_invalid) /* 78 odd_fixnum  */
3597         .quad local_label(misc_set_invalid) /* 79 imm_2  */
3598         .quad local_label(misc_set_invalid) /* 7a immheader_2  */
3599         .quad local_label(misc_set_invalid) /* 7b nodeheader_2  */
3600         .quad local_label(misc_set_invalid) /* 7c misc  */
3601         .quad local_label(misc_set_invalid) /* 7d imm3  */
3602         .quad local_label(misc_set_invalid) /* 7e immheader_3  */
3603         .quad local_label(misc_set_invalid) /* 7f nodeheader_3  */
3604        /* 80-8*/
3605         .quad local_label(misc_set_invalid) /* 80 even_fixnum  */
3606         .quad local_label(misc_set_invalid) /* 81 imm_0  */
3607         .quad local_label(misc_set_invalid) /* 82 immheader_0  */
3608         .quad local_label(misc_set_invalid) /* 83 nodeheader_0  */
3609         .quad local_label(misc_set_invalid) /* 84 cons  */
3610         .quad local_label(misc_set_invalid) /* 85 imm_1  */
3611         .quad local_label(misc_set_invalid) /* 86 immheader_1  */
3612         .quad _SPgvset /* 87 arrayH  */
3613         .quad local_label(misc_set_invalid) /* 88 odd_fixnum  */
3614         .quad local_label(misc_set_invalid) /* 89 imm_2  */
3615         .quad local_label(misc_set_invalid) /* 8a immheader_2  */
3616         .quad _SPgvset /* 8b vectorH  */
3617         .quad local_label(misc_set_invalid) /* 8c misc  */
3618         .quad local_label(misc_set_invalid) /* 8d imm3  */
3619         .quad local_label(misc_set_invalid) /* 8e immheader_3  */
3620         .quad _SPgvset /* 8f simple_vector  */
3621        /* 90-9*/
3622         .quad local_label(misc_set_invalid) /* 90 even_fixnum  */
3623         .quad local_label(misc_set_invalid) /* 91 imm_0  */
3624         .quad local_label(misc_set_s8) /* 92 s8  */
3625         .quad local_label(misc_set_invalid) /* 93 nodeheader_0  */
3626         .quad local_label(misc_set_invalid) /* 94 cons  */
3627         .quad local_label(misc_set_invalid) /* 95 imm_1  */
3628         .quad local_label(misc_set_s16) /* 96 immheader_1  */
3629         .quad local_label(misc_set_invalid) /* 97 nodeheader_1  */
3630         .quad local_label(misc_set_invalid) /* 98 odd_fixnum  */
3631         .quad local_label(misc_set_invalid) /* 99 imm_2  */
3632         .quad local_label(misc_set_s32) /* 9a s32  */
3633         .quad local_label(misc_set_invalid) /* 9b nodeheader_2  */
3634         .quad local_label(misc_set_invalid) /* 9c misc  */
3635         .quad local_label(misc_set_invalid) /* 9d imm3  */
3636         .quad local_label(misc_set_s64) /* 9e s64  */
3637         .quad local_label(misc_set_invalid) /* 9f nodeheader_3  */
3638        /* a0-af  */
3639         .quad local_label(misc_set_invalid) /* a0 even_fixnum  */
3640         .quad local_label(misc_set_invalid) /* a1 imm_0  */
3641         .quad local_label(misc_set_u8) /* a2 u8  */
3642         .quad local_label(misc_set_invalid) /* a3 nodeheader_0  */
3643         .quad local_label(misc_set_invalid) /* a4 cons  */
3644         .quad local_label(misc_set_invalid) /* a5 imm_1  */
3645         .quad local_label(misc_set_u16) /* a6 u16  */
3646         .quad local_label(misc_set_invalid) /* a7 nodeheader_1  */
3647         .quad local_label(misc_set_invalid) /* a8 odd_fixnum  */
3648         .quad local_label(misc_set_invalid) /* a9 imm_2  */
3649         .quad local_label(misc_set_u32) /* aa u32  */
3650         .quad local_label(misc_set_invalid) /* ab nodeheader_2  */
3651         .quad local_label(misc_set_invalid) /* ac misc  */
3652         .quad local_label(misc_set_invalid) /* ad imm3  */
3653         .quad local_label(misc_set_u64) /* ae u64  */
3654         .quad local_label(misc_set_invalid) /* af nodeheader_3  */
3655        /* b0-bf  */
3656         .quad local_label(misc_set_invalid) /* b0 even_fixnum  */
3657         .quad local_label(misc_set_invalid) /* b1 imm_0  */
3658         .quad local_label(misc_set_invalid) /* b2 immheader_0  */
3659         .quad local_label(misc_set_invalid) /* b3 nodeheader_0  */
3660         .quad local_label(misc_set_invalid) /* b4 cons  */
3661         .quad local_label(misc_set_invalid) /* b5 imm_1  */
3662         .quad local_label(misc_set_invalid) /* b6 immheader_1  */
3663         .quad local_label(misc_set_invalid) /* b7 nodeheader_1  */
3664         .quad local_label(misc_set_invalid) /* b8 odd_fixnum  */
3665         .quad local_label(misc_set_invalid) /* b9 imm_2  */
3666         .quad local_label(misc_set_single_float_vector) /* ba sf vector  */
3667         .quad local_label(misc_set_invalid) /* bb nodeheader_2  */
3668         .quad local_label(misc_set_invalid) /* bc misc  */
3669         .quad local_label(misc_set_invalid) /* bd imm3  */
3670         .quad local_label(misc_set_fixnum_vector) /* be fixnum_vector  */
3671         .quad local_label(misc_set_invalid) /* bf nodeheader_3  */
3672        /* c0-cf  */
3673         .quad local_label(misc_set_invalid) /* c0 even_fixnum  */
3674         .quad local_label(misc_set_invalid) /* c1 imm_0  */
3675         .quad local_label(misc_set_invalid) /* c2 immheader_0  */
3676         .quad local_label(misc_set_invalid) /* c3 nodeheader_0  */
3677         .quad local_label(misc_set_invalid) /* c4 cons  */
3678         .quad local_label(misc_set_invalid) /* c5 imm_1  */
3679         .quad local_label(misc_set_invalid) /* c6 immheader_1  */
3680         .quad local_label(misc_set_invalid) /* c7 nodeheader_1  */
3681         .quad local_label(misc_set_invalid) /* c8 odd_fixnum  */
3682         .quad local_label(misc_set_invalid) /* c9 imm_2  */
3683         .quad local_label(misc_set_invalid) /* ca immheader_2  */
3684         .quad local_label(misc_set_invalid) /* cb nodeheader_2  */
3685         .quad local_label(misc_set_invalid) /* cc misc  */
3686         .quad local_label(misc_set_invalid) /* cd imm3  */
3687         .quad local_label(misc_set_double_float_vector) /* ce double-float vector  */
3688         .quad local_label(misc_set_invalid) /* cf nodeheader_3  */
3689        /* d0-df  */
3690         .quad local_label(misc_set_invalid) /* d0 even_fixnum  */
3691         .quad local_label(misc_set_invalid) /* d1 imm_0  */
3692         .quad local_label(misc_set_string) /* d2 string  */
3693         .quad local_label(misc_set_invalid) /* d3 nodeheader_0  */
3694         .quad local_label(misc_set_invalid) /* d4 cons  */
3695         .quad local_label(misc_set_invalid) /* d5 imm_1  */
3696         .quad local_label(misc_set_invalid) /* d6 immheader_1  */
3697         .quad local_label(misc_set_invalid) /* d7 nodeheader_1  */
3698         .quad local_label(misc_set_invalid) /* d8 odd_fixnum  */
3699         .quad local_label(misc_set_invalid) /* d9 imm_2  */
3700         .quad local_label(misc_set_new_string) /* da new_string  */
3701         .quad local_label(misc_set_invalid) /* db nodeheader_2  */
3702         .quad local_label(misc_set_invalid) /* dc misc  */
3703         .quad local_label(misc_set_invalid) /* dd imm3  */
3704         .quad local_label(misc_set_invalid) /* de immheader_3  */
3705         .quad local_label(misc_set_invalid) /* df nodeheader_3  */
3706        /* e0-ef  */
3707         .quad local_label(misc_set_invalid) /* e0 even_fixnum  */
3708         .quad local_label(misc_set_invalid) /* e1 imm_0  */
3709         .quad local_label(misc_set_invalid) /* e2 immheader_0  */
3710         .quad local_label(misc_set_invalid) /* e3 nodeheader_0  */
3711         .quad local_label(misc_set_invalid) /* e4 cons  */
3712         .quad local_label(misc_set_invalid) /* e5 imm_1  */
3713         .quad local_label(misc_set_invalid) /* e6 immheader_1  */
3714         .quad local_label(misc_set_invalid) /* e7 nodeheader_1  */
3715         .quad local_label(misc_set_invalid) /* e8 odd_fixnum  */
3716         .quad local_label(misc_set_invalid) /* e9 imm_2  */
3717         .quad local_label(misc_set_invalid) /* ea immheader_2  */
3718         .quad local_label(misc_set_invalid) /* eb nodeheader_2  */
3719         .quad local_label(misc_set_invalid) /* ec misc  */
3720         .quad local_label(misc_set_invalid) /* ed imm3  */
3721         .quad local_label(misc_set_invalid) /* ee immheader_3  */
3722         .quad local_label(misc_set_invalid) /* ef nodeheader_3  */
3723        /* f0-ff  */
3724         .quad local_label(misc_set_invalid) /* f0 even_fixnum  */
3725         .quad local_label(misc_set_invalid) /* f1 imm_0  */
3726         .quad local_label(misc_set_invalid) /* f2 immheader_0  */
3727         .quad local_label(misc_set_invalid) /* f3 nodeheader_0  */
3728         .quad local_label(misc_set_invalid) /* f4 cons  */
3729         .quad local_label(misc_set_invalid) /* f5 imm_1  */
3730         .quad local_label(misc_set_bit_vector) /* f6 bit_vector  */
3731         .quad local_label(misc_set_invalid) /* f7 nodeheader_1  */
3732         .quad local_label(misc_set_invalid) /* f8 odd_fixnum  */
3733         .quad local_label(misc_set_invalid) /* f9 imm_2  */
3734         .quad local_label(misc_set_invalid) /* fa immheader_2  */
3735         .quad local_label(misc_set_invalid) /* fb nodeheader_2  */
3736         .quad local_label(misc_set_invalid) /* fc misc  */
3737         .quad local_label(misc_set_invalid) /* fd imm3  */
3738         .quad local_label(misc_set_invalid) /* fe immheader_3  */
3739         .quad local_label(misc_set_invalid) /* ff nodeheader_3  */
3740
3741local_label(misc_set_bit_vector):               
3742         __(lis imm3,0x8000)
3743         __(extract_unsigned_byte_bits_(imm0,arg_z,1))
3744         __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
3745         __(srdi imm0,arg_y,5+fixnumshift)
3746         __(srw imm3,imm3,imm1)
3747         __(bne local_label(misc_set_bad))
3748         __(cmpdi cr0,arg_z,0)
3749         __(sldi imm0,imm0,2)
3750         __(la imm0,misc_data_offset(imm0))
3751         __(lwzx imm2,arg_x,imm0)
3752         __(beq 1f)
3753         __(or imm2,imm3,imm2)
3754         __(stwx imm2,arg_x,imm0)
3755         __(blr)
37561:       __(andc imm2,imm2,imm3)
3757         __(stwx imm2,arg_x,imm0)
3758         __(blr)
3759local_label(misc_set_s16):
3760         __(extract_lisptag(imm2,arg_z))
3761         __(sldi imm0,arg_z,64-(16+fixnumshift))
3762         __(srdi imm1,arg_y,2)
3763         __(cmpdi cr7,imm2,tag_fixnum)
3764         __(sradi imm0,imm0,64-(16+fixnumshift))
3765         __(cmpd imm0,arg_z)
3766         __(la imm1,misc_data_offset(imm1))
3767         __(unbox_fixnum(imm0,arg_z))
3768         __(bne local_label(misc_set_bad))
3769         __(bne cr7,local_label(misc_set_bad))
3770         __(sthx imm0,arg_x,imm1)
3771         __(blr)
3772local_label(misc_set_u16):
3773         __(extract_unsigned_byte_bits_(imm0,arg_z,16))
3774         __(srdi imm1,arg_y,2)               
3775         __(unbox_fixnum(imm0,arg_z))
3776         __(la imm1,misc_data_offset(imm1))
3777         __(bne local_label(misc_set_bad))
3778         __(sthx imm0,arg_x,imm1)
3779         __(blr)
3780local_label(misc_set_single_float_vector):
3781         __(extract_fulltag(imm3,arg_z))
3782         __(srdi imm4,arg_y,1)
3783         __(cmpdi cr3,imm3,subtag_single_float)
3784         __(la imm4,misc_data_offset(imm4))
3785         __(bne cr3,local_label(misc_set_bad))
3786         __(srdi imm0,arg_z,32)
3787         __(stwx imm0,arg_x,imm4)
3788         __(blr)
3789local_label(misc_set_s32):
3790         __(extract_lisptag(imm2,arg_z))
3791         __(srdi imm4,arg_y,1)
3792         __(unbox_fixnum(imm0,arg_z))
3793         __(cmpdi imm2,tag_fixnum)
3794         __(sldi imm1,imm0,32)
3795         __(sradi imm1,imm1,32)
3796         __(la imm4,misc_data_offset(imm4))
3797         __(bne local_label(misc_set_bad))
3798         __(cmpd imm1,imm0)
3799         __(bne local_label(misc_set_bad))
3800         __(stwx imm0,arg_x,imm4)
3801         __(blr)
3802local_label(misc_set_u32):             
3803         __(extract_unsigned_byte_bits_(imm0,arg_z,32))
3804         __(srdi imm4,arg_y,1)
3805         __(la imm4,misc_data_offset(imm4))
3806         __(unbox_fixnum(imm0,arg_z))
3807         __(bne local_label(misc_set_bad))
3808         __(stwx imm0,arg_x,imm4)
3809         __(blr)
3810local_label(misc_set_new_string):
3811         __(extract_lowbyte(imm0,arg_z))
3812         __(srdi imm4,arg_y,1)
3813         __(cmpdi imm0,subtag_character)
3814         __(la imm4,misc_data_offset(imm4))
3815         __(srwi imm0,arg_z,charcode_shift)
3816         __(bne local_label(misc_set_bad))
3817         __(stwx imm0,arg_x,imm4)
3818         __(blr)
3819local_label(misc_set_string):     
3820         __(extract_lowbyte(imm0,arg_z))               
3821         __(srdi imm4,arg_y,3)
3822         __(cmpdi imm0,subtag_character)
3823         __(la imm4,misc_data_offset(imm4))
3824         __(bne cr0,local_label(misc_set_bad))
3825         __(srwi imm0,arg_z,charcode_shift)
3826         __(stbx imm0,arg_x,imm4)
3827         __(blr)
3828local_label(misc_set_s8):     
3829         __(extract_lisptag(imm2,arg_z))
3830         __(unbox_fixnum(imm0,arg_z))
3831         __(cmpdi cr2,imm2,tag_fixnum)
3832         __(srdi imm4,arg_y,3)
3833         __(sldi imm1,imm0,56)
3834         __(sradi imm1,imm1,56)
3835         __(cmpd imm1,imm0)
3836         __(bne cr2,local_label(misc_set_bad))
3837         __(la imm4,misc_data_offset(imm4))
3838         __(bne local_label(misc_set_bad))
3839         __(stbx imm0,arg_x,imm4)
3840         __(blr)
3841local_label(misc_set_u8):     
3842         __(extract_unsigned_byte_bits_(imm0,arg_z,8))
3843         __(srdi imm4,arg_y,3)
3844         __(unbox_fixnum(imm0,arg_z))
3845         __(la imm4,misc_data_offset(imm4))
3846         __(bne local_label(misc_set_bad))
3847         __(stbx imm0,arg_x,imm4)
3848         __(blr)
3849local_label(misc_set_u64):
3850         __(extract_lisptag(imm0,arg_z))
3851         __(extract_fulltag(imm2,arg_z))
3852         __(cmpdi cr0,arg_z,0)
3853         __(cmpdi cr7,imm0,0)
3854         __(cmpdi cr6,imm2,fulltag_misc)
3855         __(la imm4,misc_data_offset(arg_y))
3856         __(bne cr7,local_label(setu64_maybe_bignum))
3857         __(unbox_fixnum(imm0,arg_z))
3858         __(blt cr0,local_label(misc_set_bad))
3859         __(stdx imm0,arg_x,imm4)
3860         __(blr)
3861local_label(setu64_maybe_bignum):
3862         __(bne cr6,local_label(misc_set_bad))
3863         __(getvheader(imm1,arg_z))
3864         __(ld imm0,misc_data_offset(arg_z))
3865         __(rotldi imm0,imm0,32)
3866         __(cmpdi cr2,imm1,two_digit_bignum_header)
3867         __(cmpdi cr3,imm1,three_digit_bignum_header)
3868         __(cmpdi cr0,imm0,0)
3869         __(beq cr2,1f)
3870         __(bne cr3,local_label(misc_set_bad))
3871         __(lwz imm3,misc_data_offset+8(arg_z))
3872         __(cmpwi cr0,imm3,0)
3873         __(bne cr0,local_label(misc_set_bad))
3874         __(stdx imm0,arg_x,imm4)
3875         __(blr)
38761:       __(blt cr0,local_label(misc_set_bad))
3877         __(stdx imm0,arg_x,imm4)
3878         __(blr)
3879local_label(misc_set_double_float_vector):
3880         __(extract_typecode(imm0,arg_z))
3881         __(la imm4,misc_data_offset(arg_y))
3882         __(cmpdi imm0,subtag_double_float)
3883         __(bne local_label(misc_set_bad))
3884         __(ld imm0,misc_dfloat_offset(arg_z))
3885         __(stdx imm0,arg_x,imm4)
3886         __(blr)
3887local_label(misc_set_fixnum_vector):
3888         __(extract_lisptag(imm2,arg_z))
3889         __(unbox_fixnum(imm0,arg_z))
3890         __(cmpdi cr2,imm2,tag_fixnum)
3891         __(la imm4,misc_data_offset(arg_y))
3892         __(bne cr2,local_label(misc_set_bad))
3893         __(stdx imm0,arg_x,imm4)
3894         __(blr)
3895local_label(misc_set_s64):
3896         __(extract_lisptag(imm2,arg_z))
3897         __(extract_fulltag(imm3,arg_z))
3898         __(unbox_fixnum(imm0,arg_z))
3899         __(cmpdi cr2,imm2,tag_fixnum)
3900         __(cmpdi cr6,imm3,fulltag_misc) 
3901         __(la imm4,misc_data_offset(arg_y))
3902         __(bne cr2,local_label(sets64_maybe_bignum))
3903         __(stdx imm0,arg_x,imm4)
3904         __(blr)
3905local_label(sets64_maybe_bignum):       
3906         __(bne cr6,local_label(misc_set_bad))
3907         __(getvheader(imm1,arg_z))
3908         __(ld imm0,misc_data_offset(arg_z))
3909         __(cmpdi cr1,imm1,two_digit_bignum_header)
3910         __(rotldi imm0,imm0,32)
3911         __(bne cr1,local_label(misc_set_bad))
3912         __(stdx imm0,arg_x,imm4)
3913         __(blr)
3914local_label(misc_set_bad):
3915         __(mr arg_y,arg_z)
3916         __(mr arg_z,arg_x)
3917         __(li arg_x,XNOTELT)
3918         __(set_nargs(3))
3919         __(b _SPksignalerr)
3920local_label(misc_set_invalid): 
3921         __(li temp0,XSETBADVEC)       
3922         __(set_nargs(4))
3923         __(vpush(temp0))
3924         __(b _SPksignalerr)       
3925        __else
3926         __(slwi imm1,imm1,2)
3927         __(li imm0,LO(local_label(misc_set_jmp)))
3928         __(addis imm0,imm0,HA(local_label(misc_set_jmp)))
3929         __(lwzx imm0,imm0,imm1)
3930         __(mtctr imm0)
3931         __(bctr)
3932local_label(misc_set_jmp):             
3933        /* 00-0*/
3934         .long local_label(misc_set_invalid) /* 00 even_fixnum  */
3935         .long local_label(misc_set_invalid) /* 01 cons  */
3936         .long local_label(misc_set_invalid) /* 02 nodeheader  */
3937         .long local_label(misc_set_invalid) /* 03 imm  */
3938         .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
3939         .long local_label(misc_set_invalid) /* 05 nil  */
3940         .long local_label(misc_set_invalid) /* 06 misc  */
3941         .long local_label(misc_set_u32) /* 07 bignum  */
3942         .long local_label(misc_set_invalid) /* 08 even_fixnum  */
3943         .long local_label(misc_set_invalid) /* 09 cons  */
3944         .long _SPgvset /* 0a ratio  */
3945         .long local_label(misc_set_invalid) /* 0b imm  */
3946         .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
3947         .long local_label(misc_set_invalid) /* 0d nil  */
3948         .long local_label(misc_set_invalid) /* 0e misc  */
3949         .long local_label(misc_set_u32) /* 0f single_float  */
3950        /* 10-1*/
3951         .long local_label(misc_set_invalid) /* 10 even_fixnum  */
3952         .long local_label(misc_set_invalid) /* 11 cons  */
3953         .long local_label(misc_set_invalid) /* 12 nodeheader  */
3954         .long local_label(misc_set_invalid) /* 13 imm  */
3955         .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
3956         .long local_label(misc_set_invalid) /* 15 nil  */
3957         .long local_label(misc_set_invalid) /* 16 misc  */
3958         .long local_label(misc_set_u32) /* 17 double_float  */
3959         .long local_label(misc_set_invalid) /* 18 even_fixnum  */
3960         .long local_label(misc_set_invalid) /* 19 cons  */
3961         .long _SPgvset /* 1a complex  */
3962         .long local_label(misc_set_invalid) /* 1b imm  */
3963         .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
3964         .long local_label(misc_set_invalid) /* 1d nil  */
3965         .long local_label(misc_set_invalid) /* 1e misc  */
3966         .long local_label(misc_set_u32) /* 1f macptr  */
3967        /* 20-2*/
3968         .long local_label(misc_set_invalid) /* 20 even_fixnum  */
3969         .long local_label(misc_set_invalid) /* 21 cons  */
3970         .long _SPgvset /* 22 catch_frame  */
3971         .long local_label(misc_set_invalid) /* 23 imm  */
3972         .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
3973         .long local_label(misc_set_invalid) /* 25 nil  */
3974         .long local_label(misc_set_invalid) /* 26 misc  */
3975         .long local_label(misc_set_u32) /* 27 dead_macptr  */
3976         .long local_label(misc_set_invalid) /* 28 even_fixnum  */
3977         .long local_label(misc_set_invalid) /* 29 cons  */
3978         .long _SPgvset /* 2a function  */
3979         .long local_label(misc_set_invalid) /* 2b imm  */
3980         .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
3981         .long local_label(misc_set_invalid) /* 2d nil  */
3982         .long local_label(misc_set_invalid) /* 2e misc  */
3983         .long local_label(misc_set_u32) /* 2f code_vector  */
3984        /* 30-3*/
3985         .long local_label(misc_set_invalid) /* 30 even_fixnum  */
3986         .long local_label(misc_set_invalid) /* 31 cons  */
3987         .long _SPgvset /* 32 lisp_thread  */
3988         .long local_label(misc_set_invalid) /* 33 imm  */
3989         .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
3990         .long local_label(misc_set_invalid) /* 35 nil  */
3991         .long local_label(misc_set_invalid) /* 36 misc  */
3992         .long local_label(misc_set_u32) /* 37 creole  */
3993         .long local_label(misc_set_invalid) /* 38 even_fixnum  */
3994         .long local_label(misc_set_invalid) /* 39 cons  */
3995         .long _SPgvset /* 3a symbol  */
3996         .long local_label(misc_set_invalid) /* 3b imm  */
3997         .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
3998         .long local_label(misc_set_invalid) /* 3d nil  */
3999         .long local_label(misc_set_invalid) /* 3e misc  */
4000         .long local_label(misc_set_u32) /* 3f xcode_vector  */
4001        /* 40-4*/
4002         .long local_label(misc_set_invalid) /* 40 even_fixnum  */
4003         .long local_label(misc_set_invalid) /* 41 cons  */
4004         .long _SPgvset /* 42 lock  */
4005         .long local_label(misc_set_invalid) /* 43 imm  */
4006         .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
4007         .long local_label(misc_set_invalid) /* 45 nil  */
4008         .long local_label(misc_set_invalid) /* 46 misc  */
4009         .long local_label(misc_set_invalid) /* 47 immheader  */
4010         .long local_label(misc_set_invalid) /* 48 even_fixnum  */
4011         .long local_label(misc_set_invalid) /* 49 cons  */
4012         .long _SPgvset /* 4a hash_vector  */
4013         .long local_label(misc_set_invalid) /* 4b imm  */
4014         .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
4015         .long local_label(misc_set_invalid) /* 4d nil  */
4016         .long local_label(misc_set_invalid) /* 4e misc  */
4017         .long local_label(misc_set_invalid) /* 4f immheader  */
4018        /* 50-5*/
4019         .long local_label(misc_set_invalid) /* 50 even_fixnum  */
4020         .long local_label(misc_set_invalid) /* 51 cons  */
4021         .long _SPgvset /* 52 pool  */
4022         .long local_label(misc_set_invalid) /* 53 imm  */
4023         .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
4024         .long local_label(misc_set_invalid) /* 55 nil  */
4025         .long local_label(misc_set_invalid) /* 56 misc  */
4026         .long local_label(misc_set_invalid) /* 57 immheader  */
4027         .long local_label(misc_set_invalid) /* 58 even_fixnum  */
4028         .long local_label(misc_set_invalid) /* 59 cons  */
4029         .long _SPgvset /* 5a weak  */
4030         .long local_label(misc_set_invalid) /* 5b imm  */
4031         .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
4032         .long local_label(misc_set_invalid) /* 5d nil  */
4033         .long local_label(misc_set_invalid) /* 5e misc  */
4034         .long local_label(misc_set_invalid) /* 5f immheader  */
4035        /* 60-6*/
4036         .long local_label(misc_set_invalid) /* 60 even_fixnum  */
4037         .long local_label(misc_set_invalid) /* 61 cons  */
4038         .long _SPgvset /* 62 package  */
4039         .long local_label(misc_set_invalid) /* 63 imm  */
4040         .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
4041         .long local_label(misc_set_invalid) /* 65 nil  */
4042         .long local_label(misc_set_invalid) /* 66 misc  */
4043         .long local_label(misc_set_invalid) /* 67 immheader  */
4044         .long local_label(misc_set_invalid) /* 68 even_fixnum  */
4045         .long local_label(misc_set_invalid) /* 69 cons  */
4046         .long _SPgvset /* 6a slot_vector  */
4047         .long local_label(misc_set_invalid) /* 6b imm  */
4048         .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
4049         .long local_label(misc_set_invalid) /* 6d nil  */
4050         .long local_label(misc_set_invalid) /* 6e misc  */
4051         .long local_label(misc_set_invalid) /* 6f immheader  */
4052        /* 70-7*/
4053         .long local_label(misc_set_invalid) /* 70 even_fixnum  */
4054         .long local_label(misc_set_invalid) /* 71 cons  */
4055         .long _SPgvset /* 72 instance  */
4056         .long local_label(misc_set_invalid) /* 73 imm  */
4057         .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
4058         .long local_label(misc_set_invalid) /* 75 nil  */
4059         .long local_label(misc_set_invalid) /* 76 misc  */
4060         .long local_label(misc_set_invalid) /* 77 immheader  */
4061         .long local_label(misc_set_invalid) /* 78 even_fixnum  */
4062         .long local_label(misc_set_invalid) /* 79 cons  */
4063         .long _SPgvset /* 7a struct  */
4064         .long local_label(misc_set_invalid) /* 7b imm  */
4065         .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
4066         .long local_label(misc_set_invalid) /* 7d nil  */
4067         .long local_label(misc_set_invalid) /* 7e misc  */
4068         .long local_label(misc_set_invalid) /* 7f immheader  */
4069        /* 80-8*/
4070         .long local_label(misc_set_invalid) /* 80 even_fixnum  */
4071         .long local_label(misc_set_invalid) /* 81 cons  */
4072         .long _SPgvset /* 82 istruct  */
4073         .long local_label(misc_set_invalid) /* 83 imm  */
4074         .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
4075         .long local_label(misc_set_invalid) /* 85 nil  */
4076         .long local_label(misc_set_invalid) /* 86 misc  */
4077         .long local_label(misc_set_invalid) /* 87 immheader  */
4078         .long local_label(misc_set_invalid) /* 88 even_fixnum  */
4079         .long local_label(misc_set_invalid) /* 89 cons  */
4080         .long _SPgvset /* 8a value_cell  */
4081         .long local_label(misc_set_invalid) /* 8b imm  */
4082         .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
4083         .long local_label(misc_set_invalid) /* 8d nil  */
4084         .long local_label(misc_set_invalid) /* 8e misc  */
4085         .long local_label(misc_set_invalid) /* 8f immheader  */
4086        /* 90-9*/
4087         .long local_label(misc_set_invalid) /* 90 even_fixnum  */
4088         .long local_label(misc_set_invalid) /* 91 cons  */
4089         .long _SPgvset /* 92 xfunction  */
4090         .long local_label(misc_set_invalid) /* 93 imm  */
4091         .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
4092         .long local_label(misc_set_invalid) /* 95 nil  */
4093         .long local_label(misc_set_invalid) /* 96 misc  */
4094         .long local_label(misc_set_invalid) /* 97 immheader  */
4095         .long local_label(misc_set_invalid) /* 98 even_fixnum  */
4096         .long local_label(misc_set_invalid) /* 99 cons  */
4097         .long _SPgvset /* 9a arrayH  */
4098         .long local_label(misc_set_invalid) /* 9b imm  */
4099         .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
4100         .long local_label(misc_set_invalid) /* 9d nil  */
4101         .long local_label(misc_set_invalid) /* 9e misc  */
4102         .long local_label(misc_set_invalid) /* 9f immheader  */
4103        /* a0-af  */
4104         .long local_label(misc_set_invalid) /* a0 even_fixnum  */
4105         .long local_label(misc_set_invalid) /* a1 cons  */
4106         .long _SPgvset /* a2 vectorH  */
4107         .long local_label(misc_set_invalid) /* a3 imm  */
4108         .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
4109         .long local_label(misc_set_invalid) /* a5 nil  */
4110         .long local_label(misc_set_invalid) /* a6 misc  */
4111         .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
4112         .long local_label(misc_set_invalid) /* a8 even_fixnum  */
4113         .long local_label(misc_set_invalid) /* a9 cons  */
4114         .long _SPgvset /* aa vectorH  */
4115         .long local_label(misc_set_invalid) /* ab imm  */
4116         .long local_label(misc_set_invalid) /* ac odd_fixnum  */
4117         .long local_label(misc_set_invalid) /* ad nil  */
4118         .long local_label(misc_set_invalid) /* ae misc  */
4119         .long local_label(misc_set_u32) /* af u32  */
4120        /* b0-bf  */
4121         .long local_label(misc_set_invalid) /* b0 even_fixnum  */
4122         .long local_label(misc_set_invalid) /* b1 cons  */
4123         .long local_label(misc_set_invalid) /* b2 node  */
4124         .long local_label(misc_set_invalid) /* b3 imm  */
4125         .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
4126         .long local_label(misc_set_invalid) /* b5 nil  */
4127         .long local_label(misc_set_invalid) /* b6 misc  */
4128         .long local_label(misc_set_s32) /* b7 s32  */
4129         .long local_label(misc_set_invalid) /* b8 even_fixnum  */
4130         .long local_label(misc_set_invalid) /* b9 cons  */
4131         .long local_label(misc_set_invalid) /* ba nodeheader  */
4132         .long local_label(misc_set_invalid) /* bb imm  */
4133         .long local_label(misc_set_invalid) /* bc odd_fixnum  */
4134         .long local_label(misc_set_invalid) /* bd nil  */
4135         .long local_label(misc_set_invalid) /* be misc  */
4136         .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
4137        /* c0-cf  */
4138         .long local_label(misc_set_invalid) /* c0 even_fixnum  */
4139         .long local_label(misc_set_invalid) /* c1 cons  */
4140         .long local_label(misc_set_invalid) /* c2 nodeheader  */
4141         .long local_label(misc_set_invalid) /* c3 imm  */
4142         .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
4143         .long local_label(misc_set_invalid) /* c5 nil  */
4144         .long local_label(misc_set_invalid) /* c6 misc  */
4145         .long local_label(misc_set_new_string) /* c7 new_string  */
4146         .long local_label(misc_set_invalid) /* c8 even_fixnum  */
4147         .long local_label(misc_set_invalid) /* c9 cons  */
4148         .long local_label(misc_set_invalid) /* ca nodeheader  */
4149         .long local_label(misc_set_invalid) /* cb imm  */
4150         .long local_label(misc_set_invalid) /* cc odd_fixnum  */
4151         .long local_label(misc_set_invalid) /* cd nil  */
4152         .long local_label(misc_set_invalid) /* ce misc  */
4153         .long local_label(misc_set_u8) /* cf u8  */
4154        /* d0-df  */
4155         .long local_label(misc_set_invalid) /* d0 even_fixnum  */
4156         .long local_label(misc_set_invalid) /* d1 cons  */
4157         .long local_label(misc_set_invalid) /* d2 nodeheader  */
4158         .long local_label(misc_set_invalid) /* d3 imm  */
4159         .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
4160         .long local_label(misc_set_invalid) /* d5 nil  */
4161         .long local_label(misc_set_invalid) /* d6 misc  */
4162         .long local_label(misc_set_s8) /* d7 s8  */
4163         .long local_label(misc_set_invalid) /* d8 even_fixnum  */
4164         .long local_label(misc_set_invalid) /* d9 cons  */
4165         .long local_label(misc_set_invalid) /* da nodeheader  */
4166         .long local_label(misc_set_invalid) /* db imm  */
4167         .long local_label(misc_set_invalid) /* dc odd_fixnum  */
4168         .long local_label(misc_set_invalid) /* dd nil  */
4169         .long local_label(misc_set_invalid) /* de misc  */
4170         .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
4171        /* e0-ef  */
4172         .long local_label(misc_set_invalid) /* e0 even_fixnum  */
4173         .long local_label(misc_set_invalid) /* e1 cons  */
4174         .long local_label(misc_set_invalid) /* e2 nodeheader  */
4175         .long local_label(misc_set_invalid) /* e3 imm  */
4176         .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
4177         .long local_label(misc_set_invalid) /* e5 nil  */
4178         .long local_label(misc_set_invalid) /* e6 misc  */
4179         .long local_label(misc_set_u16) /* e7 u16  */
4180         .long local_label(misc_set_invalid) /* e8 even_fixnum  */
4181         .long local_label(misc_set_invalid) /* e9 cons  */
4182         .long local_label(misc_set_invalid) /* ea nodeheader  */
4183         .long local_label(misc_set_invalid) /* eb imm  */
4184         .long local_label(misc_set_invalid) /* ec odd_fixnum  */
4185         .long local_label(misc_set_invalid) /* ed nil  */
4186         .long local_label(misc_set_invalid) /* ee misc  */
4187         .long local_label(misc_set_s16) /* ef s16  */
4188        /* f0-ff  */
4189         .long local_label(misc_set_invalid) /* f0 even_fixnum  */
4190         .long local_label(misc_set_invalid) /* f1 cons  */
4191         .long local_label(misc_set_invalid) /* f2 nodeheader  */
4192         .long local_label(misc_set_invalid) /* f3 imm  */
4193         .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
4194         .long local_label(misc_set_invalid) /* f5 nil  */
4195         .long local_label(misc_set_invalid) /* f6 misc  */
4196         .long local_label(misc_set_double_float_vector) /* f7 df vector  */
4197         .long local_label(misc_set_invalid) /* f8 even_fixnum  */
4198         .long local_label(misc_set_invalid) /* f9 cons  */
4199         .long local_label(misc_set_invalid) /* fa nodeheader  */
4200         .long local_label(misc_set_invalid) /* fb imm  */
4201         .long local_label(misc_set_invalid) /* fc odd_fixnum  */
4202         .long local_label(misc_set_invalid) /* fd nil  */
4203         .long local_label(misc_set_invalid) /* fe misc  */
4204         .long local_label(misc_set_bit_vector) /* ff bit_vector  */
4205
4206local_label(misc_set_u32):       
4207        /* Either a non-negative fixnum, a positiveone-digit bignum, */
4208        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
4209         __(extract_lisptag(imm2,arg_z))
4210         __(srawi. imm1,arg_z,fixnum_shift)
4211         __(cmpwi cr5,imm2,tag_fixnum)         
4212         __(la imm0,misc_data_offset(arg_y))
4213         __(cmpwi cr7,imm2,tag_misc)
4214         __(bne cr5,local_label(set_not_fixnum_u32))
4215         __(blt- cr0,local_label(set_bad))
4216local_label(set_set32):         
4217         __(stwx imm1,arg_x,imm0)
4218         __(blr)
4219local_label(set_not_fixnum_u32):
4220         __(bne cr7,local_label(set_bad))
4221         __(extract_header(imm2,arg_z))
4222         __(cmpri(cr0,imm2,one_digit_bignum_header))
4223         __(cmpri(cr1,imm2,two_digit_bignum_header))
4224         __(vrefr(imm1,arg_z,0))
4225         __(cmpri(cr2,imm1,0))
4226         __(bne cr0,local_label(set_not_1_digit_u32))
4227         __(bge cr2,local_label(set_set32))
4228         __(b local_label(set_bad))
4229local_label(set_not_1_digit_u32):
4230         __(bne- cr1,local_label(set_bad))
4231         __(vrefr(imm2,arg_z,1))
4232         __(cmpri(cr0,imm2,0))
4233         __(bne- cr1,local_label(set_bad))
4234         __(beq cr0,local_label(set_set32))
4235local_label(set_bad):
4236        /* arg_z does not match the array-element-type of arg_x.  */
4237         __(mr arg_y,arg_z)
4238         __(mr arg_z,arg_x)
4239         __(li arg_x,XNOTELT)
4240         __(set_nargs(3))
4241         __(b _SPksignalerr)
4242local_label(misc_set_fixnum_vector):   
4243         __(extract_lisptag(imm2,arg_z))
4244         __(la imm0,misc_data_offset(arg_y))
4245         __(cmpwi cr5,imm2,tag_fixnum)
4246         __(unbox_fixnum(imm1,arg_z))
4247         __(bne cr5,local_label(set_bad))
4248         __(stwx imm1,arg_x,imm0)
4249         __(blr)
4250local_label(misc_set_new_string):   
4251         __(clrlwi imm2,arg_z,ncharcodebits)
4252         __(la imm0,misc_data_offset(arg_y))
4253         __(cmpwi cr5,imm2,subtag_character)
4254         __(srwi imm1,arg_z,charcode_shift)
4255         __(bne cr5,local_label(set_bad))
4256         __(stwx imm1,arg_x,imm0)
4257         __(blr)
4258local_label(misc_set_s32):
4259         __(extract_lisptag(imm2,arg_z))
4260         __(cmpwi cr5,imm2,tag_fixnum)
4261         __(cmpwi cr7,imm2,tag_misc)
4262         __(la imm0,misc_data_offset(arg_y))
4263         __(unbox_fixnum(imm1,arg_z))
4264         __(beq cr5,local_label(set_set32))
4265         __(bne cr7,local_label(set_bad))
4266         __(extract_header(imm2,arg_z))
4267         __(cmpri(cr0,imm2,one_digit_bignum_header))
4268         __(vrefr(imm1,arg_z,0))
4269         __(bne- cr0,local_label(set_bad))
4270         __(strx(imm1,arg_x,imm0))
4271         __(blr)
4272local_label(misc_set_single_float_vector):
4273         __(extract_lisptag(imm2,arg_z))
4274         __(cmpwi cr7,imm2,tag_misc)
4275         __(la imm0,misc_data_offset(arg_y))
4276         __(bne- cr7,local_label(set_bad))
4277         __(extract_header(imm2,arg_z))
4278         __(cmpri(cr0,imm2,single_float_header))
4279         __(bne- cr0,local_label(set_bad))
4280         __(ldr(imm1,single_float.value(arg_z)))
4281         __(strx(imm1,arg_x,imm0))
4282         __(blr)
4283local_label(misc_set_u8):               
4284         __(extract_lisptag(imm2,arg_z))
4285         __(srwi imm0,arg_y,2)
4286         __(la imm0,misc_data_offset(imm0))
4287         __(extract_unsigned_byte_bits_(imm1,arg_z,8))
4288         __(unbox_fixnum(imm1,arg_z))
4289         __(bne- cr0,local_label(set_bad))
4290         __(stbx imm1,arg_x,imm0)
4291         __(blr)
4292local_label(misc_set_old_string):
4293         __(srwi imm0,arg_y,2)
4294         __(extract_lowbyte(imm2,arg_z))
4295         __(cmpri(cr2,imm2,subtag_character))
4296         __(la imm0,misc_data_offset(imm0))
4297         __(srwi imm1,arg_z,charcode_shift)
4298         __(bne- cr2,local_label(set_bad))
4299         __(stbx imm1,arg_x,imm0)
4300         __(blr)
4301local_label(misc_set_s8):
4302         __(extract_lisptag(imm2,arg_z))
4303         __(srwi imm0,arg_y,2)
4304         __(unbox_fixnum(imm1,arg_z))
4305         __(la imm0,misc_data_offset(imm0))
4306         __(cmpwi cr5,imm2,tag_fixnum)
4307         __(extsb imm2,imm1)
4308         __(cmpw cr0,imm2,imm1)
4309         __(bne- cr5,local_label(set_bad))
4310         __(bne- cr0,local_label(set_bad))
4311         __(stbx imm1,arg_x,imm0)
4312         __(blr)
4313local_label(misc_set_u16):         
4314         __(srwi imm0,arg_y,1)
4315         __(extract_unsigned_byte_bits_(imm1,arg_z,16))
4316         __(unbox_fixnum(imm1,arg_z))
4317         __(la imm0,misc_data_offset(imm0))
4318         __(bne- cr0,local_label(set_bad))
4319         __(sthx imm1,arg_x,imm0)
4320         __(blr)
4321local_label(misc_set_s16):
4322         __(extract_lisptag(imm2,arg_z))
4323         __(srwi imm0,arg_y,1)
4324         __(unbox_fixnum(imm1,arg_z))
4325         __(cmpwi cr5,imm2,tag_fixnum)
4326         __(la imm0,misc_data_offset(imm0))
4327         __(extsh imm2,imm1)
4328         __(cmpw cr0,imm2,imm1)
4329         __(bne- cr5,local_label(set_bad))
4330         __(bne- cr0,local_label(set_bad))
4331         __(sthx imm1,arg_x,imm0)
4332         __(blr)
4333local_label(misc_set_bit_vector):       
4334         __(cmplwi cr2,arg_z,fixnumone)   /* nothing not a (boxed) bit   */
4335         __(extrwi imm1,arg_y,5,32-(fixnumshift+5))     /* imm1 = bitnum  */
4336         __(extlwi imm2,arg_z,1,31-fixnumshift)
4337         __(srw imm2,imm2,imm1)
4338         __(lis imm3,0x8000)
4339         __(rlwinm imm0,arg_y,32-5,5,31-fixnumshift)
4340         __(la imm0,misc_data_offset(imm0))
4341         __(srw imm3,imm3,imm1)
4342         __(bgt- cr2,local_label(set_bad))
4343         __(lwzx imm1,arg_x,imm0)
4344         __(andc imm1,imm1,imm3)
4345         __(or imm1,imm1,imm2)
4346         __(stwx imm1,arg_x,imm0)
4347         __(blr)
4348
4349local_label(misc_set_double_float_vector):
4350         __(extract_lisptag(imm2,arg_z))
4351         __(slwi imm0,arg_y,1)
4352         __(cmpwi cr7,imm2,tag_misc)
4353         __(la imm0,misc_dfloat_offset(imm0))
4354         __(bne- cr7,local_label(set_bad))
4355         __(extract_header(imm2,arg_z))
4356         __(cmpri(cr0,imm2,double_float_header))
4357         __(bne- cr0,local_label(set_bad))
4358         __(lwz imm1,double_float.value(arg_z))
4359         __(lwz imm2,double_float.value+4(arg_z))
4360         __(stwx imm1,arg_x,imm0)
4361         __(la imm0,4(imm0))
4362         __(stwx imm2,arg_x,imm0)
4363         __(blr)
4364local_label(misc_set_invalid): 
4365         __(li temp0,XSETBADVEC)       
4366         __(set_nargs(4))
4367         __(vpush(temp0))
4368         __(b _SPksignalerr)               
4369        __endif
4370
4371/* misc_set (vector index newval).  Pretty damned similar to  */
4372/* misc_ref, as one might imagine.  */
4373
4374_spentry(misc_set)
4375        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
4376        __(trap_unless_lisptag_equal(arg_y,tag_fixnum,imm0))
4377        __(vector_length(imm0,arg_x,imm1))
4378        __(trlge(arg_y,imm0))
4379        __(extract_lowbyte(imm1,imm1))
4380        __(b local_label(misc_set_common))
4381       
4382/* "spread" the lexpr in arg_z.  */
4383/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
4384_spentry(spread_lexprz)
4385        __(ldr(imm0,0(arg_z)))
4386        __(cmpri(cr3,imm0,3<<fixnumshift))
4387        __(cmpri(cr4,imm0,2<<fixnumshift))
4388        __(add imm1,arg_z,imm0)
4389        __(cmpri(cr0,imm0,0))
4390        __(add nargs,nargs,imm0)
4391        __(cmpri(cr1,nargs,0))
4392        __(cmpri(cr2,nargs,2<<fixnumshift))
4393        __(la imm1,node_size(imm1))
4394        __(bge cr3,9f)
4395        __(beq cr4,2f)
4396        __(bne cr0,1f)
4397        /* lexpr count was 0; vpop the arg regs that  */
4398        /* were vpushed by the caller  */
4399        __(beqlr cr1)
4400        __(vpop(arg_z))
4401        __(bltlr cr2)
4402        __(vpop(arg_y))
4403        __(beqlr cr2)
4404        __(vpop(arg_x))
4405        __(blr)
4406
4407        /* vpush args from the lexpr until we have only  */
4408        /* three left, then assign them to arg_x, arg_y,  */
4409        /* and arg_z.  */
44108:
4411        __(cmpri(cr3,imm0,4<<fixnumshift))
4412        __(subi imm0,imm0,fixnumone)
4413        __(ldru(arg_z,-node_size(imm1)))
4414        __(vpush(arg_z))
44159:
4416        __(bne cr3,8b)
4417        __(ldr(arg_x,-node_size*1(imm1)))
4418        __(ldr(arg_y,-node_size*2(imm1)))
4419        __(ldr(arg_z,-node_size*3(imm1)))
4420        __(blr)
4421
4422        /* lexpr count is two: set arg_y, arg_z from the  */
4423        /* lexpr, maybe vpop arg_x  */
44242:     
4425        __(ldr(arg_y,-node_size*1(imm1)))
4426        __(ldr(arg_z,-node_size*2(imm1)))
4427        __(beqlr cr2)           /* return if (new) nargs = 2  */
4428        __(vpop(arg_x))
4429        __(blr)
4430
4431        /* lexpr count is one: set arg_z from the lexpr,  */
4432        /* maybe vpop arg_y, arg_x  */
44331:     
4434        __(ldr(arg_z,-node_size(imm1)))
4435        __(bltlr cr2)           /* return if (new) nargs < 2  */
4436        __(vpop(arg_y))
4437        __(beqlr cr2)           /* return if (new) nargs = 2  */
4438        __(vpop(arg_x))
4439        __(blr)
4440       
4441               
4442_spentry(reset)
4443        .globl _SPthrow
4444        __(nop)
4445        __(ref_nrs_value(temp0,toplcatch))
4446        __(li temp1,XSTKOVER)
4447        __(vpush(temp0))
4448        __(vpush(temp1))
4449        __(set_nargs(1))
4450        __(b _SPthrow)
4451
4452       
4453/* "slide" nargs worth of values up the vstack.  IMM0 contains  */
4454/* the difference between the current VSP and the target.  */
4455_spentry(mvslide)
4456        __(cmpri(cr0,nargs,0))
4457        __(mr imm3,nargs)
4458        __(add imm2,vsp,nargs)
4459        __(add imm2,imm2,imm0)
4460        __(add imm0,vsp,nargs)
4461        __(beq 2f)
44621:
4463        __(cmpri(cr0,imm3,1<<fixnumshift))
4464        __(subi imm3,imm3,1<<fixnumshift)
4465        __(ldru(temp0,-node_size(imm0)))
4466        __(stru(temp0,-node_size(imm2)))
4467        __(bne cr0,1b)
44682:
4469        __(mr vsp,imm2)
4470        __(blr)
4471
4472/* Build a new TSP area to hold nargs worth of multiple-values.  */
4473/* Pop the multiple values off of the vstack.  */
4474/* The new TSP frame will look like this:  */
4475/*  */
4476/*+--------+-------+-------+---------+--------+--------+--------+======+----------+ */
4477/*| ptr to | zero  | nargs | ptr to  | valn-1 | valn-2 | val-0  | ???? | prev TSP |  */
4478/*|  prev  |       |       |  prev   |        |        |        | fill |          |  */
4479/*| TSP    |       |       | segment |        |        |        |      |          | */
4480/*+--------+-------+-------+---------+--------+--------+--------+------+----------+  */
4481/*  */
4482/* e.g., the first multiple value goes in the last cell in the frame, the  */
4483/* count of values goes in the first word, and the word after the value count  */
4484/* is 0 if the number of values is even (for alignment).  */
4485/* Subsequent calls to .SPadd_values preserve this alignment.  */
4486/* .SPrecover_values is therefore pretty simple.  */
4487
4488_spentry(save_values)
4489        __(mr imm1,tsp)
4490
4491        /* common exit: nargs = values in this set, imm1 = ptr to tsp before  */
4492        /* call to save_values  */
4493local_label(save_values_to_tsp):
4494        __(mr imm2,tsp)
4495        __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* count, link  */
4496        __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
4497        __(str(imm1,tsp_frame.backlink(tsp))) /* keep one tsp "frame" as far as rest of lisp is concerned  */
4498        __(str(nargs,tsp_frame.data_offset(tsp)))
4499        __(str(imm2,tsp_frame.data_offset+node_size(tsp))) /* previous tsp  */
4500        __(la imm3,tsp_frame.data_offset+node_size*2(tsp))
4501        __(add imm3,imm3,nargs)
4502        __(add imm0,vsp,nargs)
4503        __(cmpr(cr0,imm0,vsp))
4504        __(b 2f)
45051:
4506        __(ldru(arg_z,-node_size(imm0)))
4507        __(cmpr(cr0,imm0,vsp))
4508        __(stru(arg_z,-node_size(imm3)))
45092:
4510        __(bne cr0,1b)
4511        __(add vsp,vsp,nargs) /*  discard values  */
4512        __(blr)
4513       
4514
4515/* Add the multiple values that are on top of the vstack to the set  */
4516/* saved in the top tsp frame, popping them off of the vstack in the  */
4517/* process.  It is an error (a bad one) if the TSP contains something  */
4518/* other than a previously saved set of multiple-values.  */
4519/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
4520/* each add_values call adds another linked element to the list of  */
4521/* values. This makes recover_values harder.  */
4522
4523_spentry(add_values)
4524        __(cmpri(cr0,nargs,0))
4525        __(ldr(imm1,0(tsp)))
4526        __(bne cr0,local_label(save_values_to_tsp))
4527        __(blr)
4528       
4529/* On entry, R11->callback-index  */
4530/* Restore lisp context, then funcall #'%pascal-functions% with  */
4531/* two args: callback-index, args-ptr (a macptr pointing to the args on the stack)  */
4532_spentry(poweropen_callback)
4533        __ifdef(`rTOC')
4534         __(mr r11,rTOC)
4535        __endif
4536        /* Save C argument registers  */
4537        __(str(r3,c_frame.param0(sp)))
4538        __(str(r4,c_frame.param1(sp)))
4539        __(str(r5,c_frame.param2(sp)))
4540        __(str(r6,c_frame.param3(sp)))
4541        __(str(r7,c_frame.param4(sp)))
4542        __(str(r8,c_frame.param5(sp)))
4543        __(str(r9,c_frame.param6(sp)))
4544        __(str(r10,c_frame.param7(sp)))
4545        __(mflr imm3)
4546        __(str(imm3,c_frame.savelr(sp)))
4547        __(mfcr imm0)
4548        __(str(imm0,c_frame.crsave(sp)))
4549
4550        /* Save the non-volatile registers on the sp stack  */
4551        /* This is a non-standard stack frame, but noone will ever see it,  */
4552        /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
4553        __(stru(sp,-(stack_align(c_reg_save.size))(sp)))
4554        __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
4555        __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
4556        __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
4557        __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
4558        __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
4559        __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
4560        __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
4561        __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
4562        __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
4563        __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
4564        __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
4565        __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
4566        __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
4567        __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
4568        __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
4569        __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
4570        __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
4571        __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
4572        __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
4573        __(stfd f1,c_reg_save.save_fprs+(0*8)(sp))
4574        __(stfd f2,c_reg_save.save_fprs+(1*8)(sp))
4575        __(stfd f3,c_reg_save.save_fprs+(2*8)(sp))
4576        __(stfd f4,c_reg_save.save_fprs+(3*8)(sp))
4577        __(stfd f5,c_reg_save.save_fprs+(4*8)(sp))
4578        __(stfd f6,c_reg_save.save_fprs+(5*8)(sp))
4579        __(stfd f7,c_reg_save.save_fprs+(6*8)(sp))
4580        __(stfd f8,c_reg_save.save_fprs+(7*8)(sp))
4581        __(stfd f9,c_reg_save.save_fprs+(8*8)(sp))
4582        __(stfd f10,c_reg_save.save_fprs+(9*8)(sp))
4583        __(stfd f11,c_reg_save.save_fprs+(10*8)(sp))
4584        __(stfd f12,c_reg_save.save_fprs+(11*8)(sp))
4585        __(stfd f13,c_reg_save.save_fprs+(12*8)(sp))
4586        __(check_stack_alignment(r0))
4587        __(mffs f0)
4588        __(stfd f0,c_reg_save.save_fp_zero(sp))
4589        __(lwz r31,c_reg_save.save_fp_zero+4(sp))       /* recover FPSCR image  */
4590        __(stw r31,c_reg_save.save_fpscr(sp))
4591        __(lwi(r30,0x43300000))
4592        __(lwi(r31,0x80000000))
4593        __(stw r30,c_reg_save.save_fp_zero(sp))
4594        __(stw r31,c_reg_save.save_fp_zero+4(sp))
4595        __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
4596        __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
4597        __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
4598        __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
4599
4600/* Restore rest of Lisp context.  */
4601/* Could spread out the memory references here to gain a little speed  */
4602
4603        __(li loc_pc,0)
4604        __(li fn,0)                     /* subprim, not a lisp function  */
4605        __(li temp3,0)
4606        __(li temp2,0)
4607        __(li temp1,0)
4608        __(li temp0,0)
4609        __(li arg_x,0)
4610        __(box_fixnum(arg_y,r11))       /* callback-index  */
4611        __(la arg_z,c_reg_save.save_fprs(sp))
4612        __(str(arg_z,stack_align(c_reg_save.size)+c_frame.unused(sp)))
4613        __(la arg_z,stack_align(c_reg_save.size)+c_frame.param0(sp))    /* parameters (tagged as a fixnum)  */
4614
4615        /* Recover lisp thread context. Have to call C code to do so.  */
4616        __(ref_global(r12,get_tcr))
4617        __ifdef(`rTOC')
4618         __(ld rTOC,8(r12))
4619         __(ld r12,0(r12))
4620        __endif
4621        __(mtctr r12)
4622        __(li r3,1)
4623        __(stru(sp,-(stack_align(c_frame.minsiz))(sp)))
4624        __(bctrl)
4625        __(la rcontext,TCR_BIAS(r3))
4626        __(la sp,(stack_align(c_frame.minsiz))(sp))
4627
4628        __(ldr(vsp,tcr.save_vsp(rcontext)))
4629        __(ldr(tsp,tcr.save_tsp(rcontext)))             
4630        __(li rzero,0)
4631        __(li imm0,TCR_STATE_LISP)
4632        __(mtxer rzero) /* lisp wants the overflow bit being clear  */
4633        __(mtctr rzero)
4634        __(li save0,0)
4635        __(li save1,0)
4636        __(li save2,0)
4637        __(li save3,0)
4638        __(li save4,0)
4639        __(li save5,0)
4640        __(li save6,0)
4641        __(li save7,0)
4642        __(lfd f0,tcr.lisp_fpscr(rcontext))
4643        __(mtfsf 0xff,f0)
4644        __(li allocbase,0)
4645        __(li allocptr,0)       
4646        __(str(imm0,tcr.valence(rcontext)))
4647        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
4648        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
4649       
4650        __(restore_saveregs(vsp))
4651
4652        /* load nargs and callback to the lisp  */
4653        __(set_nargs(2))
4654        __(ldr(imm2,tcr.cs_area(rcontext)))
4655        __(ldr(imm4,area.active(imm2)))
4656        __(stru(imm4,-lisp_frame.size(sp)))
4657        __(str(imm3,lisp_frame.savelr(sp)))
4658        __(li fname,nrs.callbacks)      /* %pascal-functions%  */
4659        __(call_fname)
4660        __(ldr(imm2,lisp_frame.backlink(sp)))
4661        __(ldr(imm3,tcr.cs_area(rcontext)))
4662        __(str(imm2,area.active(imm3)))
4663        __(discard_lisp_frame())
4664        /* save_vsp will be restored from ff_call's stack frame, but  */
4665        /* I included it here for consistency.  */
4666        /* save_tsp is set below after we exit Lisp context.  */
4667        __(str(allocptr,tcr.save_allocptr(rcontext)))
4668        __(str(allocbase,tcr.save_allocbase(rcontext)))
4669        __(str(vsp,tcr.save_vsp(rcontext)))
4670        __(str(tsp,tcr.save_tsp(rcontext)))
4671        /* Exit lisp context  */
4672        __(li imm1,TCR_STATE_FOREIGN)
4673        __(str(imm1,tcr.valence(rcontext)))
4674        /* Restore the non-volatile registers & fpscr  */
4675        __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
4676        __(lwz r31,c_reg_save.save_fpscr(sp))
4677        __(stw r31,c_reg_save.save_fp_zero+4(sp))
4678        __(lfd f0,c_reg_save.save_fp_zero(sp))
4679        __(mtfsf 0xff,f0)
4680        __(ldr(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
4681        __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
4682        __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
4683        __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
4684        __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
4685        __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
4686        __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
4687        __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
4688        __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
4689        __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
4690        __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
4691        __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
4692        __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
4693        __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
4694        __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
4695        __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
4696        __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
4697        __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
4698        __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
4699        __(lfd f1,c_reg_save.save_fprs+(0*8)(sp))
4700        __(lfd f2,c_reg_save.save_fprs+(1*8)(sp))
4701        __(lfd f3,c_reg_save.save_fprs+(2*8)(sp))
4702        __(lfd f4,c_reg_save.save_fprs+(3*8)(sp))
4703        __(lfd f5,c_reg_save.save_fprs+(4*8)(sp))
4704        __(lfd f6,c_reg_save.save_fprs+(5*8)(sp))
4705        __(lfd f7,c_reg_save.save_fprs+(6*8)(sp))
4706        __(lfd f8,c_reg_save.save_fprs+(7*8)(sp))
4707        __(lfd f9,c_reg_save.save_fprs+(8*8)(sp))
4708        __(lfd f10,c_reg_save.save_fprs+(9*8)(sp))
4709        __(lfd f11,c_reg_save.save_fprs+(10*8)(sp))
4710        __(lfd f12,c_reg_save.save_fprs+(11*8)(sp))
4711        __(lfd f13,c_reg_save.save_fprs+(12*8)(sp))
4712        __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
4713        __(ldr(sp,0(sp)))
4714        __(ldr(r3,c_frame.param0(sp)))
4715        __(ldr(r4,c_frame.param1(sp)))
4716        __(ldr(r5,c_frame.param2(sp)))
4717        __(ldr(r6,c_frame.param3(sp)))
4718        __(ldr(r7,c_frame.param4(sp)))
4719        __(ldr(r8,c_frame.param5(sp)))
4720        __(ldr(r9,c_frame.param6(sp)))
4721        __(ldr(r10,c_frame.param7(sp)))
4722        __(ldr(r11,c_frame.savelr(sp)))
4723        __(mtlr r11)
4724        __(ldr(r11,c_frame.crsave(sp)))
4725        __(mtcr r11)
4726        __(blr)
4727       
4728/* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
4729/* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
4730/* Calls out to %init-misc, which does the rest of the work.  */
4731
4732_spentry(misc_alloc_init)
4733        __(mflr loc_pc)
4734        __(build_lisp_frame(fn,loc_pc,vsp))
4735        __(li fn,0)
4736        __(mr temp0,arg_z)              /* initval  */
4737        __(mr arg_z,arg_y)              /* subtag  */
4738        __(mr arg_y,arg_x)              /* element-count  */
4739        __(bl _SPmisc_alloc)
4740        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4741        __(mtlr loc_pc)
4742        __(ldr(fn,lisp_frame.savefn(sp)))
4743        __(ldr(vsp,lisp_frame.savevsp(sp)))
4744        __(discard_lisp_frame())
4745        __(li fname,nrs.init_misc)
4746        __(set_nargs(2))
4747        __(mr arg_y,temp0)
4748        __(jump_fname())
4749
4750/* As in stack_misc_alloc above, only with a non-default initial-value.  */
4751
4752_spentry(stack_misc_alloc_init)
4753        __(mflr loc_pc)
4754        __(build_lisp_frame(fn,loc_pc,vsp))
4755        __(li fn,0)
4756        __(mr temp0,arg_z) /* initval  */
4757        __(mr arg_z,arg_y) /* subtag  */
4758        __(mr arg_y,arg_x) /* element-count  */
4759        __(bl _SPstack_misc_alloc)
4760        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4761        __(mtlr loc_pc)
4762        __(ldr(fn,lisp_frame.savefn(sp)))
4763        __(ldr(vsp,lisp_frame.savevsp(sp)))
4764        __(discard_lisp_frame())
4765        __(li fname,nrs.init_misc)
4766        __(set_nargs(2))
4767        __(mr arg_y,temp0)
4768        __(jump_fname())
4769
4770       
4771_spentry(callbuiltin)
4772        __(ref_nrs_value(fname,builtin_functions))
4773        __(la imm0,misc_data_offset(imm0))
4774        __(ldrx(fname,fname,imm0))
4775        __(jump_fname())
4776
4777/* the value of the nilreg-relative symbol %builtin-functions% should be  */
4778/* a vector of symbols.  Call the symbol indexed by imm0 (boxed) and  */
4779/* return a single value.  */
4780
4781_spentry(callbuiltin0)
4782        __(set_nargs(0))
4783        __(ref_nrs_value(fname,builtin_functions))
4784        __(la imm0,misc_data_offset(imm0))
4785        __(ldrx(fname,fname,imm0))
4786        __(jump_fname())
4787
4788_spentry(callbuiltin1)
4789        __(ref_nrs_value(fname,builtin_functions))
4790        __(set_nargs(1))
4791        __(la imm0,misc_data_offset(imm0))
4792        __(ldrx(fname,fname,imm0))
4793        __(jump_fname())
4794
4795_spentry(callbuiltin2)
4796        __(set_nargs(2))
4797        __(ref_nrs_value(fname,builtin_functions))
4798        __(la imm0,misc_data_offset(imm0))
4799        __(ldrx(fname,fname,imm0))
4800        __(jump_fname())
4801
4802
4803_spentry(callbuiltin3)
4804        __(set_nargs(3))
4805        __(ref_nrs_value(fname,builtin_functions))
4806        __(la imm0,misc_data_offset(imm0))
4807        __(ldrx(fname,fname,imm0))
4808        __(jump_fname())
4809       
4810
4811_spentry(popj)
4812        .globl C(popj)
4813C(popj):
4814        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4815        __(ldr(vsp,lisp_frame.savevsp(sp)))
4816        __(mtlr loc_pc)
4817        __(ldr(fn,lisp_frame.savefn(sp)))
4818        __(discard_lisp_frame())
4819        __(blr)
4820
4821_spentry(restorefullcontext)
4822        __(mflr loc_pc)
4823        __(mtctr loc_pc)
4824        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4825        __(mtlr loc_pc)
4826        __(ldr(vsp,lisp_frame.savevsp(sp)))
4827        __(ldr(fn,lisp_frame.savefn(sp)))
4828        __(discard_lisp_frame())
4829        __(bctr)
4830
4831_spentry(savecontextvsp)
4832        __(ldr(imm0,tcr.cs_limit(rcontext)))
4833        __(build_lisp_frame(fn,loc_pc,vsp))
4834        __(mr fn,nfn)
4835        __(trllt(sp,imm0))
4836        __(blr)
4837
4838_spentry(savecontext0)
4839        __(add imm0,vsp,imm0)
4840        __(build_lisp_frame(fn,loc_pc,imm0))
4841        __(ldr(imm0,tcr.cs_limit(rcontext)))
4842        __(mr fn,nfn)
4843        __(trllt(sp,imm0))
4844        __(blr)
4845
4846
4847/* Like .SPrestorefullcontext, only the saved return address  */
4848/* winds up in loc-pc instead of getting thrashed around ...  */
4849_spentry(restorecontext)
4850        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4851        __(ldr(vsp,lisp_frame.savevsp(sp)))
4852        __(ldr(fn,lisp_frame.savefn(sp)))
4853        __(discard_lisp_frame())
4854        __(blr)
4855
4856       
4857/* Nargs is valid; all arg regs, lexpr-count pushed by caller.  */
4858/* imm0 = vsp to restore.  */
4859/* Return all values returned by caller to its caller, hiding  */
4860/* the variable-length arglist.  */
4861/* If we can detect that the caller's caller didn't expect  */
4862/* multiple values, then things are even simpler.  */
4863_spentry(lexpr_entry)
4864        __(ref_global(imm1,ret1val_addr))
4865        __(cmpr(cr0,imm1,loc_pc))
4866        __(build_lisp_frame(fn,loc_pc,imm0))
4867        __(bne cr0,1f)
4868        __(ref_global(imm0,lexpr_return))
4869        __(build_lisp_frame(rzero,imm0,vsp))
4870        __(mr loc_pc,imm1)
4871        __(ldr(imm0,tcr.cs_limit(rcontext)))
4872        __(trllt(sp,imm0))
4873        __(li fn,0)
4874        __(blr)
4875
4876        /* The single-value case just needs to return to something that'll pop  */
4877        /* the variable-length frame off of the vstack.  */
48781:
4879        __(ref_global(loc_pc,lexpr_return1v))
4880        __(ldr(imm0,tcr.cs_limit(rcontext)))
4881        __(trllt(sp,imm0))
4882        __(li fn,0)
4883        __(blr)
4884
4885/* */
4886/* Do a system call in Darwin.  The stack is set up much as it would be */
4887/* for a PowerOpen ABI ff-call: register parameters are in the stack */
4888/* frame, and there are 4 extra words at the bottom of the frame that */
4889/* we can carve a lisp frame out of. */
4890/*  */
4891/* System call return conventions are a little funky in Darwin: if "@sc" */
4892/* is the address of the "sc" instruction, errors return to @sc+4 and */
4893/* non-error cases return to @sc+8.  Error values are returned as */
4894/* positive values in r3; this is true even if the system call returns */
4895/* a doubleword (64-bit) result.  Since r3 would ordinarily contain */
4896/* the high half of a doubleword result, this has to be special-cased. */
4897/*  */
4898/* The caller should set the c_frame.crsave field of the stack frame */
4899/* to 0 if the result is to be interpreted as anything but a doubleword */
4900/* and to non-zero otherwise.  (This only matters on an error return.) */
4901
4902       
4903_spentry(poweropen_syscall)
4904        __(mflr loc_pc)
4905        __(vpush_saveregs())
4906        __(ldr(imm1,0(sp)))
4907        __(la imm2,-lisp_frame.size(imm1))
4908        __(zero_doublewords imm2,0,lisp_frame.size)
4909        __(str(imm1,lisp_frame.backlink(imm2)))
4910        __(str(imm2,c_frame.backlink(sp)))
4911        __(str(fn,lisp_frame.savefn(imm2)))
4912        __(str(loc_pc,lisp_frame.savelr(imm2)))
4913        __(str(vsp,lisp_frame.savevsp(imm2)))
4914        __(ldr(imm3,tcr.cs_area(rcontext)))
4915        __(str(imm2,area.active(imm3)))
4916        __(str(allocptr,tcr.save_allocptr(rcontext)))
4917        __(str(allocbase,tcr.save_allocbase(rcontext)))
4918        __(str(tsp,tcr.save_tsp(rcontext)))
4919        __(str(vsp,tcr.save_vsp(rcontext)))
4920        __(str(rzero,tcr.ffi_exception(rcontext)))
4921        __(mr save0,rcontext)
4922        __(li r3,TCR_STATE_FOREIGN)
4923        __(str(r3,tcr.valence(rcontext)))
4924        __(li rcontext,0)
4925        __(ldr(r3,c_frame.param0(sp)))
4926        __(ldr(r4,c_frame.param1(sp)))
4927        __(ldr(r5,c_frame.param2(sp)))
4928        __(ldr(r6,c_frame.param3(sp)))
4929        __(ldr(r7,c_frame.param4(sp)))
4930        __(ldr(r8,c_frame.param5(sp)))
4931        __(ldr(r9,c_frame.param6(sp)))
4932        __(ldr(r10,c_frame.param7(sp)))
4933        __(unbox_fixnum(r0,arg_z))
4934        __(sc)
4935        __ifdef(`LINUX')
4936         __(bns+ 9f)
4937        __else
4938         __(b 1f)
4939         __(b 9f)
4940        __endif
49411:
4942        __ifdef(`PPC64')
4943         __(neg r3,r3)
4944        __else
4945         __(ldr(imm2,c_frame.crsave(sp)))
4946         __(cmpri(cr0,imm2,0))
4947         __(bne cr0,2f)
4948         /* 32-bit result  */
4949         __(neg r3,r3)
4950         __(b 9f)
49512:
4952         /* 64-bit result  */
4953         __(neg r4,r3)
4954         __(li r3,-1)
4955        __endif
49569:
4957        __(mr imm2,save0)       /* recover context  */
4958        __(ldr(sp,c_frame.backlink(sp)))
4959        __(li imm4,TCR_STATE_LISP)
4960        __(li rzero,0)
4961        __(li loc_pc,0)
4962        __(li arg_x,nil_value)
4963        __(li arg_y,nil_value)
4964        __(li arg_z,nil_value)
4965        __(li temp0,nil_value)
4966        __(li temp1,nil_value)
4967        __(li temp2,nil_value)
4968        __(li temp3,nil_value)
4969        __(li fn,nil_value)
4970        __(mr rcontext,imm2)
4971        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
4972        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
4973        __(ldr(tsp,tcr.save_tsp(rcontext)))
4974        __(li save0,0)
4975        __(li save1,0)
4976        __(li save2,0)
4977        __(li save3,0)
4978        __(li save4,0)
4979        __(li save5,0)
4980        __(li save6,0)
4981        __(li save7,0)       
4982        __(str(imm4,tcr.valence(rcontext)))
4983        __(vpop_saveregs)
4984        __(ldr(loc_pc,lisp_frame.savelr(sp)))
4985        __(mtlr loc_pc)
4986        __(ldr(fn,lisp_frame.savefn(sp)))
4987        __(discard_lisp_frame)
4988        __(mtxer rzero)
4989        __(check_pending_interrupt(`cr1'))
4990        __(blr)
4991       
4992       
4993_spentry(builtin_plus)
4994        __(extract_lisptag(imm0,arg_y))
4995        __(extract_lisptag(imm1,arg_z))
4996        __(cmpri(cr0,imm0,tag_fixnum))
4997        __(cmpri(cr1,imm1,tag_fixnum))
4998        __(bne- cr0,1f)
4999        __(bne- cr1,1f)
5000        __(addo. arg_z,arg_y,arg_z)
5001        __(bnslr+)
5002        __(mtxer rzero)
5003        __(unbox_fixnum(imm1,arg_z))
5004        __ifdef(`PPC64')
5005         __(li imm0,two_digit_bignum_header)
5006         __(rotldi imm1,imm1,32)
5007         __(xoris imm1,imm1,0xe000)
5008         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
5009         __(str(imm1,misc_data_offset(arg_z)))
5010        __else
5011         __(li imm0,one_digit_bignum_header)
5012         __(xoris imm1,imm1,0xc000)
5013         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
5014         __(str(imm1,misc_data_offset(arg_z)))
5015        __endif
5016        __(blr)
50171:
5018        __(jump_builtin(_builtin_plus,2))
5019_spentry(builtin_minus)
5020        __(extract_lisptag(imm0,arg_y))
5021        __(extract_lisptag(imm1,arg_z))
5022        __(cmpri(cr0,imm0,tag_fixnum))
5023        __(cmpri(cr1,imm1,tag_fixnum))
5024        __(bne- cr0,1f)
5025        __(bne- cr1,1f)
5026        __(subo. arg_z,arg_y,arg_z)
5027        __(bnslr+)
5028        __(mtxer rzero)
5029        __(unbox_fixnum(imm1,arg_z))
5030        __ifdef(`PPC64')
5031         __(li imm0,two_digit_bignum_header)
5032         __(rotldi imm1,imm1,32)
5033         __(xoris imm1,imm1,0xe000)
5034         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
5035         __(str(imm1,misc_data_offset(arg_z)))
5036        __else
5037         __(li imm0,one_digit_bignum_header)
5038         __(xoris imm1,imm1,0xc000)
5039         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
5040         __(str(imm1,misc_data_offset(arg_z)))
5041        __endif
5042        __(blr)
50431:
5044        __(jump_builtin(_builtin_minus,2))
5045_spentry(builtin_times)
5046        __(extract_lisptag(imm0,arg_y))
5047        __(extract_lisptag(imm1,arg_z))
5048        __(cmpri(cr0,imm0,tag_fixnum))
5049        __(cmpri(cr1,imm1,tag_fixnum))
5050        __(unbox_fixnum(imm2,arg_y))
5051        __(bne cr0,1f)
5052        __(bne cr1,1f)
5053        __ifdef(`PPC64')
5054         __(mulldo. imm3,arg_z,imm2)
5055         __(bso 2f)
5056         __(mr arg_z,imm3)
5057         __(blr)
5058         /* Args are fixnums; result can't be  */
50592:       __(mtxer rzero)
5060         __(unbox_fixnum(imm3,arg_z))
5061         __(mulld imm1,imm3,imm2) /* imm1 = low  64 bits  */
5062         __(mulhd imm0,imm3,imm2) /* imm0 = high 64 bits  */
5063         __(b _SPmakes128)
5064        __else
5065         __(mullwo. imm3,arg_z,imm2)
5066         __(bso 2f)             /*  SO set if result would overflow a fixnum  */
5067         __(mr arg_z,imm3)
5068         __(blr)
5069         /* Args are fixnums; result can't be  */
50702:       __(mtxer rzero)
5071         __(unbox_fixnum(imm3,arg_z))
5072         __(mullw imm1,imm3,imm2) /* imm1 = low  32 bits  */
5073         __(mulhw imm0,imm3,imm2) /* imm0 = high 32 bits  */
5074         __(b _SPmakes64)
5075        __endif
5076
50771:      __(jump_builtin(_builtin_times,2))
5078
5079_spentry(builtin_div)
5080        __(jump_builtin(_builtin_div,2))
5081
5082_spentry(builtin_eq)
5083        __(extract_lisptag(imm0,arg_y))
5084        __(extract_lisptag(imm1,arg_z))
5085        __(cmpri(cr0,imm0,tag_fixnum))
5086        __(cmpri(cr1,imm1,tag_fixnum))
5087        __(cmpr(cr2,arg_y,arg_z))
5088        __(bne- cr0,1f)
5089        __(bne- cr1,1f)
5090        __(li arg_z,nil_value)
5091        __(bnelr cr2)
5092        __(li arg_z,t_value)
5093        __(blr)
50941:
5095        __(jump_builtin(_builtin_eq,2))
5096
5097_spentry(builtin_ne)
5098        __(extract_lisptag(imm0,arg_y))
5099        __(extract_lisptag(imm1,arg_z))
5100        __(cmpri(cr0,imm0,tag_fixnum))
5101        __(cmpri(cr1,imm1,tag_fixnum))
5102        __(cmpr(cr2,arg_y,arg_z))
5103        __(bne- cr0,1f)
5104        __(bne- cr1,1f)
5105        __(li arg_z,nil_value)
5106        __(beqlr cr2)
5107        __(li arg_z,t_value)
5108        __(blr)
51091:
5110        __(jump_builtin(_builtin_ne,2))
5111
5112_spentry(builtin_gt)
5113        __(extract_lisptag(imm0,arg_y))
5114        __(extract_lisptag(imm1,arg_z))
5115        __(cmpri(cr0,imm0,tag_fixnum))
5116        __(cmpri(cr1,imm1,tag_fixnum))
5117        __(cmpr(cr2,arg_y,arg_z))
5118        __(bne- cr0,1f)
5119        __(bne- cr1,1f)
5120        __(li arg_z,nil_value)
5121        __(bnglr cr2)
5122        __(li arg_z,t_value)
5123        __(blr)
51241:
5125        __(jump_builtin(_builtin_gt,2))
5126
5127_spentry(builtin_ge)
5128        __(extract_lisptag(imm0,arg_y))
5129        __(extract_lisptag(imm1,arg_z))
5130        __(cmpri(cr0,imm0,tag_fixnum))
5131        __(cmpri(cr1,imm1,tag_fixnum))
5132        __(cmpr(cr2,arg_y,arg_z))
5133        __(bne- cr0,1f)
5134        __(bne- cr1,1f)
5135        __(li arg_z,nil_value)
5136        __(bltlr cr2)
5137        __(li arg_z,t_value)
5138        __(blr)
51391:
5140        __(jump_builtin(_builtin_ge,2))
5141
5142_spentry(builtin_lt)
5143        __(extract_lisptag(imm0,arg_y))
5144        __(extract_lisptag(imm1,arg_z))
5145        __(cmpri(cr0,imm0,tag_fixnum))
5146        __(cmpri(cr1,imm1,tag_fixnum))
5147        __(cmpr(cr2,arg_y,arg_z))
5148        __(bne- cr0,1f)
5149        __(bne- cr1,1f)
5150        __(li arg_z,nil_value)
5151        __(bnllr cr2)
5152        __(li arg_z,t_value)
5153        __(blr)
51541:
5155        __(jump_builtin(_builtin_lt,2))
5156
5157_spentry(builtin_le)
5158        __(extract_lisptag(imm0,arg_y))
5159        __(extract_lisptag(imm1,arg_z))
5160        __(cmpri(cr0,imm0,tag_fixnum))
5161        __(cmpri(cr1,imm1,tag_fixnum))
5162        __(cmpr(cr2,arg_y,arg_z))
5163        __(bne- cr0,1f)
5164        __(bne- cr1,1f)
5165        __(li arg_z,nil_value)
5166        __(bgtlr cr2)
5167        __(li arg_z,t_value)
5168        __(blr)
51691:
5170        __(jump_builtin(_builtin_le,2))
5171
5172
5173_spentry(builtin_eql)
5174        __(cmpr(cr1,arg_y,arg_z))
5175        __(extract_fulltag(imm2,arg_y))
5176        __(extract_fulltag(imm3,arg_z))
5177        __(beq cr1,1f)
5178        __(cmpri(cr1,imm2,fulltag_misc))
5179        __(cmpri(cr0,imm3,fulltag_misc))
5180        __(bne cr1,2f)
5181        __(extract_subtag(imm0,arg_y))
5182        __(bne cr0,2f)
5183        __(extract_subtag(imm1,arg_z))
5184        __(cmpr(cr0,imm0,imm1))
5185        __(bne cr0,2f)
5186        __(jump_builtin(_builtin_eql,2))
51871:      __(li arg_z,t_value)
5188        __(blr)
51892:      __(li arg_z,nil_value)
5190        __(blr)
5191       
5192_spentry(builtin_length)
5193        __(cmpri(cr1,arg_z,nil_value))
5194        __(extract_typecode(imm0,arg_z))
5195        __(cmpri(cr0,imm0,min_vector_subtag))
5196        __(beq cr1,1f)
5197        __ifdef(`PPC64')
5198         __(cmpdi cr2,imm0,fulltag_cons)
5199        __else
5200         __(cmpwi cr2,imm0,tag_list)
5201        __endif
5202        __(beq- cr0,2f)
5203        __(blt- cr0,3f)
5204        /* (simple-array * (*))  */
5205        __(vector_length(arg_z,arg_z,imm0))
5206        __(blr)
52071:      __(li arg_z,0)
5208        __(blr)
52092:
5210        __(ldr(arg_z,vectorH.logsize(arg_z)))
5211        __(blr)       
52123:      __(bne cr2,8f)
5213        __(li temp2,-1<<fixnum_shift)
5214        __(mr temp0,arg_z)      /* fast pointer  */
5215        __(mr temp1,arg_z)      /* slow pointer  */
5216        __ifdef(`PPC64')
52174:       __(extract_fulltag(imm0,temp0))
5218         __(cmpdi cr7,temp0,nil_value)
5219         __(cmpdi cr1,imm0,fulltag_cons)
5220         __(addi temp2,temp2,fixnum_one)
5221         __(beq cr7,9f)
5222         __(andi. imm0,temp2,1<<fixnum_shift)
5223         __(bne cr1,8f)
5224         __(extract_fulltag(imm1,temp1))
5225         __(_cdr(temp0,temp0))
5226         __(cmpdi cr1,imm1,fulltag_cons)
5227         __(beq cr0,4b)
5228         __(bne cr1,8f)
5229         __(_cdr(temp1,temp1))
5230         __(cmpd cr0,temp0,temp1)
5231         __(bne cr0,4b)
5232        __else
52334:       __(extract_lisptag(imm0,temp0))
5234         __(cmpri(cr7,temp0,nil_value))
5235         __(cmpri(cr1,imm0,tag_list))
5236         __(addi temp2,temp2,fixnum_one)
5237         __(beq cr7,9f)
5238         __(andi. imm0,temp2,1<<fixnum_shift)
5239         __(bne cr1,8f)
5240         __(extract_lisptag(imm1,temp1))       
5241         __(_cdr(temp0,temp0))
5242         __(cmpri(cr1,imm1,tag_list))
5243         __(beq cr0,4b)
5244         __(bne cr1,8f)
5245         __(_cdr(temp1,temp1))
5246         __(cmpr(cr0,temp0,temp1))
5247         __(bne cr0,4b)
5248        __endif
52498:     
5250        __(jump_builtin(_builtin_length,1))
52519:     
5252        __(mr arg_z,temp2)
5253        __(blr)
5254       
5255_spentry(builtin_seqtype)
5256        __ifdef(`PPC64')
5257         __(cmpdi cr2,arg_z,nil_value)
5258         __(extract_typecode(imm0,arg_z))
5259         __(beq cr2,1f)
5260         __(cmpri(cr0,imm0,fulltag_cons))
5261        __else
5262         __(extract_typecode(imm0,arg_z))
5263         __(cmpri(cr0,imm0,tag_list))
5264        __endif
5265        __(cmpri(cr1,imm0,min_vector_subtag))
5266        __(beq cr0,1f)
5267        __(blt- cr1,2f)
5268        __(li arg_z,nil_value)
5269        __(blr)
52701:      __(li arg_z,t_value)
5271        __(blr)
52722:
5273        __(jump_builtin(_builtin_seqtype,1))
5274       
5275_spentry(builtin_assq)
5276        __(cmpri(arg_z,nil_value))
5277        __(beqlr)
52781:      __(trap_unless_list(arg_z,imm0))
5279        __(_car(arg_x,arg_z))
5280        __(_cdr(arg_z,arg_z))
5281        __(cmpri(cr2,arg_x,nil_value))
5282        __(cmpri(cr1,arg_z,nil_value))
5283        __(beq cr2,2f)
5284        __(trap_unless_list(arg_x,imm0))
5285        __(_car(temp0,arg_x))
5286        __(cmpr(temp0,arg_y))
5287        __(bne cr0,2f)
5288        __(mr arg_z,arg_x)
5289        __(blr)
52902:      __(bne cr1,1b)
5291        __(blr)
5292
5293_spentry(builtin_memq)
5294        __(cmpri(cr1,arg_z,nil_value))
5295        __(b 2f)
52961:      __(trap_unless_list(arg_z,imm0))
5297        __(_car(arg_x,arg_z))
5298        __(_cdr(temp0,arg_z))
5299        __(cmpr(arg_x,arg_y))
5300        __(cmpri(cr1,temp0,nil_value))
5301        __(beqlr)
5302        __(mr arg_z,temp0)
53032:      __(bne cr1,1b)
5304        __(blr)
5305
5306        __ifdef(`PPC64')
5307logbitp_max_bit = 61
5308        __else
5309logbitp_max_bit = 30
5310        __endif
5311       
5312_spentry(builtin_logbitp)
5313        /* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
5314        __(cmplri(cr2,arg_y,logbitp_max_bit<<fixnum_shift))
5315        __(extract_lisptag(imm0,arg_y))
5316        __(extract_lisptag(imm1,arg_z))
5317        __(cmpri(cr0,imm0,tag_fixnum))
5318        __(cmpri(cr1,imm1,tag_fixnum))
5319        __(unbox_fixnum(imm0,arg_y))
5320        __(subfic imm0,imm0,logbitp_max_bit)
5321        __ifdef(`PPC64')
5322         __(rldcl imm0,arg_z,imm0,63)
5323         __(mulli imm0,imm0,t_offset)
5324        __else
5325         __(rlwnm imm0,arg_z,imm0,31,31)
5326         __(rlwimi imm0,imm0,4,27,27)
5327        __endif
5328        __(bnl cr2,1f)
5329        __(bne cr0,1f)
5330        __(bne cr1,1f)
5331        __(addi arg_z,imm0,nil_value)
5332        __(blr)
53331:
5334        __(jump_builtin(_builtin_logbitp,2))
5335
5336_spentry(builtin_logior)
5337        __(extract_lisptag(imm0,arg_y))
5338        __(extract_lisptag(imm1,arg_z))
5339        __(cmpri(cr0,imm0,tag_fixnum))
5340        __(cmpri(cr1,imm1,tag_fixnum))
5341        __(bne- cr0,1f)
5342        __(bne- cr1,1f)
5343        __(or arg_z,arg_y,arg_z)
5344        __(blr)
53451:
5346        __(jump_builtin(_builtin_logior,2))
5347
5348_spentry(builtin_logand)
5349        __(extract_lisptag(imm0,arg_y))
5350        __(extract_lisptag(imm1,arg_z))
5351        __(cmpri(cr0,imm0,tag_fixnum))
5352        __(cmpri(cr1,imm1,tag_fixnum))
5353        __(bne- cr0,1f)
5354        __(bne- cr1,1f)
5355        __(and arg_z,arg_y,arg_z)
5356        __(blr)
53571:
5358        __(jump_builtin(_builtin_logand,2))
5359       
5360_spentry(builtin_ash)
5361        __ifdef(`PPC64')
5362         __(cmpdi cr1,arg_z,0)
5363         __(extract_lisptag(imm0,arg_y))
5364         __(extract_lisptag(imm1,arg_z))
5365         __(cmpdi cr0,imm0,tag_fixnum)
5366         __(cmpdi cr3,imm1,tag_fixnum)
5367         __(cmpdi cr2,arg_z,-(63<<3))   /* !! 3 =  fixnumshift  */
5368         __(bne- cr0,9f)
5369         __(bne- cr3,9f)
5370         __(bne cr1,0f)
5371         __(mr arg_z,arg_y)     /* (ash n 0) => n  */
5372         __(blr)
53730:             
5374         __(unbox_fixnum(imm1,arg_y))
5375         __(unbox_fixnum(imm0,arg_z))
5376         __(bgt cr1,2f)
5377         /* (ash n -count) => fixnum  */
5378         __(neg imm2,imm0)
5379         __(bgt cr2,1f)
5380         __(li imm2,63)
53811:     
5382         __(srad imm0,imm1,imm2)
5383         __(box_fixnum(arg_z,imm0))
5384         __(blr)
5385         /* Integer-length of arg_y/imm1 to imm2  */
53862:             
5387         __(cntlzd. imm2,imm1)
5388         __(bne 3f)             /* cr0`eq' set if negative  */
5389         __(not imm2,imm1)
5390         __(cntlzd imm2,imm2)
53913:
5392         __(subfic imm2,imm2,64)
5393         __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
5394         __(cmpdi cr1,imm2,63-fixnumshift)
5395         __(cmpdi cr2,imm0,64)
5396         __(sld imm2,imm1,imm0)
5397         __(bgt cr1,6f)
5398         __(box_fixnum(arg_z,imm2))
5399         __(blr)       
54006:
5401         __(bgt cr2,9f)
5402         __(bne cr2,7f)
5403         /* Shift left by 64 bits exactly  */
5404         __(mr imm0,imm1)
5405         __(li imm1,0)
5406         __(beq _SPmakes128)
5407         __(b _SPmakeu128)
54087:
5409         /* Shift left by fewer than 64 bits, result not a fixnum  */
5410         __(subfic imm0,imm0,64)
5411         __(beq 8f)
5412         __(srd imm0,imm1,imm0)
5413         __(mr imm1,imm2)
5414         __(b _SPmakeu128)
54158:     
5416         __(srad imm0,imm1,imm0)
5417         __(mr imm1,imm2)
5418         __(b _SPmakes128)
5419        __else
5420         __(cmpri(cr1,arg_z,0))
5421         __(extract_lisptag(imm0,arg_y))
5422         __(extract_lisptag(imm1,arg_z))
5423         __(cmpri(cr0,imm0,tag_fixnum))
5424         __(cmpri(cr3,imm1,tag_fixnum))
5425         __(cmpri(cr2,arg_z,-(29<<2)))  /* !! 2 =  fixnumshift  */
5426         __(bne- cr0,9f)
5427         __(bne- cr3,9f)
5428         __(bne cr1,0f)
5429         __(mr arg_z,arg_y)     /* (ash n 0) => n  */
5430         __(blr)
54310:             
5432         __(unbox_fixnum(imm1,arg_y))
5433         __(unbox_fixnum(imm0,arg_z))
5434         __(bgt cr1,2f)
5435         /* (ash n -count) => fixnum  */
5436         __(neg imm2,imm0)
5437         __(bgt cr2,1f)
5438         __(li imm2,31)
54391:     
5440         __(sraw imm0,imm1,imm2)
5441         __(box_fixnum(arg_z,imm0))
5442         __(blr)
5443         /* Integer-length of arg_y/imm1 to imm2  */
54442:             
5445         __(cntlzw. imm2,imm1)
5446         __(bne 3f)             /* cr0`eq' set if negative  */
5447         __(not imm2,imm1)
5448         __(cntlzw imm2,imm2)
54493:
5450         __(subfic imm2,imm2,32)
5451         __(add imm2,imm2,imm0)  /* imm2 <- integer-length(imm1) + count  */
5452         __(cmpri(cr1,imm2,31-fixnumshift))
5453         __(cmpri(cr2,imm0,32))
5454         __(slw imm2,imm1,imm0)
5455         __(bgt cr1,6f)
5456         __(box_fixnum(arg_z,imm2))
5457         __(blr)       
54586:
5459         __(bgt cr2,9f)
5460         __(bne cr2,7f)
5461         /* Shift left by 32 bits exactly  */
5462         __(mr imm0,imm1)
5463         __(li imm1,0)
5464         __(beq _SPmakes64)
5465         __(b _SPmakeu64)
54667:
5467         /* Shift left by fewer than 32 bits, result not a fixnum  */
5468         __(subfic imm0,imm0,32)
5469         __(beq 8f)
5470         __(srw imm0,imm1,imm0)
5471         __(mr imm1,imm2)
5472         __(b _SPmakeu64)
54738:     
5474         __(sraw imm0,imm1,imm0)
5475         __(mr imm1,imm2)
5476         __(b _SPmakes64)
5477        __endif
54789:             
5479        __(jump_builtin(_builtin_ash,2))
5480
5481_spentry(builtin_negate)
5482        __(extract_lisptag_(imm0,arg_z))
5483        __(bne- cr0,1f)
5484        __(nego. arg_z,arg_z)
5485        __(bnslr+)
5486        __(mtxer rzero)
5487        __(unbox_fixnum(imm1,arg_z))
5488        __ifdef(`PPC64')
5489         __(li imm0,two_digit_bignum_header)
5490         __(rotldi imm1,imm1,32)
5491         __(xoris imm1,imm1,0xe000)
5492         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
5493         __(str(imm1,misc_data_offset(arg_z)))
5494        __else
5495         __(li imm0,one_digit_bignum_header)
5496         __(xoris imm1,imm1,0xc000)
5497         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
5498         __(str(imm1,misc_data_offset(arg_z)))
5499        __endif
5500        __(blr)
55011:
5502        __(jump_builtin(_builtin_negate,1))
5503
5504_spentry(builtin_logxor)
5505        __(extract_lisptag(imm0,arg_y))
5506        __(extract_lisptag(imm1,arg_z))
5507        __(cmpri(cr0,imm0,tag_fixnum))
5508        __(cmpri(cr1,imm1,tag_fixnum))
5509        __(bne- cr0,1f)
5510        __(bne- cr1,1f)
5511        __(xor arg_z,arg_y,arg_z)
5512        __(blr)
55131:
5514        __(jump_builtin(_builtin_logxor,2))
5515
5516
5517
5518       
5519_spentry(builtin_aset1)
5520        __(extract_typecode(imm0,arg_x))
5521        __(cmpri(cr0,imm0,min_vector_subtag))
5522        __(box_fixnum(temp0,imm0))
5523        __(bgt cr0,1f)
5524        __(jump_builtin(_builtin_aset1,3))
55251:
5526        __(b _SPsubtag_misc_set)
5527
5528/* Enter the debugger  */
5529_spentry(breakpoint)
5530        __(li r3,0)
5531        __(tw 28,sp,sp) /* 28 = lt|gt|eq (assembler bug for the latter)  */
5532        __(blr)         /* if handler didn't  */
5533
5534/* */
5535/* We're entered with an eabi_c_frame on the C stack.  There's a */
5536/* lisp_frame reserved underneath it; we'll link it in in a minute. */
5537/* Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
5538/* then shrink the eabi_c_frame. */
5539/*  */
5540       
5541_spentry(eabi_ff_call)
5542        __(mflr loc_pc)
5543        __(str(sp,eabi_c_frame.savelr(sp)))
5544        __(vpush_saveregs())            /* Now we can use save0-save7 to point to stacks  */
5545        __(mr save0,rcontext)   /* or address globals.  */
5546        __(extract_typecode(imm0,arg_z))
5547        __(cmpri(imm0,subtag_macptr))
5548        __(ldr(save1,0(sp)))    /* bottom of reserved lisp frame  */
5549        __(la save2,-lisp_frame.size(save1))    /* top of lisp frame */
5550        __(zero_doublewords save2,0,lisp_frame.size)
5551        __(str(save1,lisp_frame.backlink(save2)))
5552        __(str(save2,c_frame.backlink(sp)))
5553        __(str(fn,lisp_frame.savefn(save2)))
5554        __(str(loc_pc,lisp_frame.savelr(save2)))
5555        __(str(vsp,lisp_frame.savevsp(save2)))
5556        __(bne 1f)
5557        __(ldr(arg_z,macptr.address(arg_z)))
55581:
5559        __(ldr(save3,tcr.cs_area(rcontext)))
5560        __(str(save2,area.active(save3)))
5561        __(str(allocptr,tcr.save_allocptr(rcontext)))
5562        __(str(allocbase,tcr.save_allocbase(rcontext)))
5563        __(str(tsp,tcr.save_tsp(rcontext)))
5564        __(str(vsp,tcr.save_vsp(rcontext)))
5565        __(mtctr arg_z)
5566        __(str(rzero,tcr.ffi_exception(rcontext)))
5567        __(mffs f0)
5568        __(stfd f0,tcr.lisp_fpscr(rcontext))    /* remember lisp's fpscr  */
5569        __(mtfsf 0xff,fp_zero)  /* zero foreign fpscr  */
5570        __(li imm1,TCR_STATE_FOREIGN)
5571        __(str(imm1,tcr.valence(rcontext)))
5572        __(ldr(r2,tcr.native_thread_info(rcontext)))
5573        __(ldr(r13,lisp_globals.saver13(0)))
5574        __(ldr(r3,eabi_c_frame.param0(sp)))
5575        __(ldr(r4,eabi_c_frame.param1(sp)))
5576        __(ldr(r5,eabi_c_frame.param2(sp)))
5577        __(ldr(r6,eabi_c_frame.param3(sp)))
5578        __(ldr(r7,eabi_c_frame.param4(sp)))
5579        __(ldr(r8,eabi_c_frame.param5(sp)))
5580        __(ldr(r9,eabi_c_frame.param6(sp)))
5581        __(ldr(r10,eabi_c_frame.param7(sp)))
5582        __(la save1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
5583        __(str(rzero,eabi_c_frame.savelr(save1)))
5584        __(str(save2,eabi_c_frame.backlink(save1)))
5585        __(mr sp,save1)
5586        /* If we're calling a varargs C function, it'll want to */
5587        /* know whether or not we've passed any args in FP regs. */
5588        /* Better to say that we did (and force callee to save FP */
5589        /* arg regs on entry) than to say that we didn't and get */
5590        /* garbage results  */
5591        __(crset 6)
5592        __(bctrl)
5593        /* C should have preserved save0 (= rcontext) for us.  */
5594        __(ldr(sp,0(sp)))
5595        __(mr imm2,save0)
5596        __(ldr(vsp,lisp_frame.savevsp(sp)))
5597        __(li rzero,0)
5598        __(mr loc_pc,rzero)
5599        __(li arg_x,nil_value)
5600        __(li arg_y,nil_value)
5601        __(li arg_z,nil_value)
5602        __(li temp0,nil_value)
5603        __(li temp1,nil_value)
5604        __(li temp2,nil_value)
5605        __(li temp3,nil_value)
5606        __(li fn,nil_value)
5607        __(mr rcontext,imm2)
5608        __(li imm2,TCR_STATE_LISP)
5609        __(ldr(tsp,tcr.save_tsp(rcontext)))
5610        __(li save0,0)
5611        __(li save1,0)
5612        __(li save2,0)
5613        __(li save3,0)
5614        __(li save4,0)
5615        __(li save5,0)
5616        __(li save6,0)
5617        __(li save7,0)
5618        __(li allocptr,-dnode_size)
5619        __(li allocbase,-dnode_size)
5620        __(str(imm2,tcr.valence(rcontext)))     
5621        __(vpop_saveregs())
5622        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
5623        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
5624        __(ldr(loc_pc,lisp_frame.savelr(sp)))
5625        __(mtlr loc_pc)
5626        __(ldr(fn,lisp_frame.savefn(sp)))
5627        __(mffs f0)
5628        __(stfd f0,8(sp))
5629        __(lwz imm3,12(sp))     /* imm3 = FPSCR after call  */
5630        __(clrrwi imm2,imm3,8)
5631        __(discard_lisp_frame())
5632        __(str(imm2,tcr.ffi_exception(rcontext)))
5633        __(lfd f0,tcr.lisp_fpscr(rcontext))
5634        __(mtfsf 0xff,f0)
5635        __(check_pending_interrupt(`cr1'))
5636        __(mtxer rzero)
5637        __(mtctr rzero)
5638        __(blr)
5639       
5640/*  */
5641/* This gets called with R11 holding the unboxed callback index. */
5642/* */
5643       
5644_spentry(eabi_callback)
5645        /* First, we extend the C frame so that it has room for */
5646        /* incoming arg regs.  */
5647        __(ldr(r0,eabi_c_frame.backlink(sp)))
5648        __(stru(r0,eabi_c_frame.param0-varargs_eabi_c_frame.incoming_stack_args(sp)))
5649        __(mflr r0)
5650        __(str(r0,varargs_eabi_c_frame.savelr(sp)))
5651        __(str(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
5652        __(str(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
5653        __(str(r5,varargs_eabi_c_frame.gp_save+(2*4)(sp)))
5654        __(str(r6,varargs_eabi_c_frame.gp_save+(3*4)(sp)))
5655        __(str(r7,varargs_eabi_c_frame.gp_save+(4*4)(sp)))
5656        __(str(r8,varargs_eabi_c_frame.gp_save+(5*4)(sp)))
5657        __(str(r9,varargs_eabi_c_frame.gp_save+(6*4)(sp)))
5658        __(str(r10,varargs_eabi_c_frame.gp_save+(7*4)(sp)))
5659        /* Could check the appropriate CR bit and skip saving FP regs here  */
5660        __(stfd f1,varargs_eabi_c_frame.fp_save+(0*8)(sp))
5661        __(stfd f2,varargs_eabi_c_frame.fp_save+(1*8)(sp))
5662        __(stfd f3,varargs_eabi_c_frame.fp_save+(2*8)(sp))
5663        __(stfd f4,varargs_eabi_c_frame.fp_save+(3*8)(sp))
5664        __(stfd f5,varargs_eabi_c_frame.fp_save+(4*8)(sp))
5665        __(stfd f6,varargs_eabi_c_frame.fp_save+(5*8)(sp))
5666        __(stfd f7,varargs_eabi_c_frame.fp_save+(6*8)(sp))
5667        __(stfd f8,varargs_eabi_c_frame.fp_save+(7*8)(sp))
5668        __(la r0,varargs_eabi_c_frame.incoming_stack_args(sp))
5669        __(str(r0,varargs_eabi_c_frame.overflow_arg_area(sp)))
5670        __(la r0,varargs_eabi_c_frame.regsave(sp))
5671        __(str(r0,varargs_eabi_c_frame.reg_save_area(sp)))
5672        __(li r0,0)
5673        __(str(r0,varargs_eabi_c_frame.flags(sp)))
5674
5675        /* Save the non-volatile registers on the sp stack  */
5676        /* This is a non-standard stack frame, but noone will ever see it,  */
5677        /* so it doesn't matter. It will look like more of the stack frame pushed below.  */
5678        __(stru(sp,-(c_reg_save.size)(sp)))
5679        __(str(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
5680        __(str(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
5681        __(str(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
5682        __(str(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
5683        __(str(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
5684        __(str(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
5685        __(str(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
5686        __(str(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
5687        __(str(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
5688        __(str(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
5689        __(str(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
5690        __(str(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
5691        __(str(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
5692        __(str(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
5693        __(str(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
5694        __(str(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
5695        __(str(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
5696        __(str(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
5697        __(str(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
5698        __(mffs f0)
5699        __(stfd f0,c_reg_save.save_fp_zero(sp))
5700        __(ldr(r31,c_reg_save.save_fp_zero+4(sp)))      /* recover FPSCR image  */
5701        __(str(r31,c_reg_save.save_fpscr(sp)))
5702        __(lwi(r30,0x43300000))
5703        __(lwi(r31,0x80000000))
5704        __(str(r30,c_reg_save.save_fp_zero(sp)))
5705        __(str(r31,c_reg_save.save_fp_zero+4(sp)))
5706        __(stfd fp_s32conv,c_reg_save.save_fps32conv(sp))
5707        __(lfd fp_s32conv,c_reg_save.save_fp_zero(sp))
5708        __(stfd fp_zero,c_reg_save.save_fp_zero(sp))
5709        __(lfs fp_zero,lisp_globals.short_float_zero(0))        /* ensure that fp_zero contains 0.0  */
5710
5711       
5712/* Restore rest of Lisp context.  */
5713/* Could spread out the memory references here to gain a little speed  */
5714        __(li loc_pc,0)
5715        __(li fn,0)                     /* subprim, not a lisp function  */
5716        __(li temp3,0)
5717        __(li temp2,0)
5718        __(li temp1,0)
5719        __(li temp0,0)
5720        __(li arg_x,0)
5721        __(box_fixnum(arg_y,r11))       /* callback-index  */
5722        __(la arg_z,c_reg_save.size+varargs_eabi_c_frame.gp_save(sp))   /* parameters (tagged as a fixnum)  */
5723
5724        /* Recover lisp thread context. Have to call C code to do so.  */
5725        __(ref_global(r12,get_tcr))
5726        __(mtctr r12)
5727        __(li r3,1)
5728        __(stru(sp,-(stack_align(eabi_c_frame.minsiz))(sp)))
5729        __(bctrl)
5730        __(la sp,(stack_align(eabi_c_frame.minsiz))(sp))
5731        __(la rcontext,TCR_BIAS(r3))
5732        __(li allocptr,0)
5733        __(li allocbase,0)
5734        __(ldr(vsp,tcr.save_vsp(rcontext)))
5735        __(ldr(tsp,tcr.save_tsp(rcontext)))             
5736        __(li rzero,0)
5737        __(mtxer rzero) /* lisp wants the overflow bit clear  */
5738        __(li imm0,TCR_STATE_LISP)
5739        __(li save0,0)
5740        __(li save1,0)
5741        __(li save2,0)
5742        __(li save3,0)
5743        __(li save4,0)
5744        __(li save5,0)
5745        __(li save6,0)
5746        __(li save7,0)
5747        __(mtctr rzero)
5748        __(str(imm0,tcr.valence(rcontext)))
5749        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
5750        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
5751        __(lfd f0,tcr.lisp_fpscr(rcontext))
5752        __(mtfsf 0xff,f0)
5753
5754        __(restore_saveregs(vsp))       
5755        /* load nargs and callback to the lisp  */
5756        __(set_nargs(2))
5757        __(ldr(imm2,tcr.cs_area(rcontext)))
5758        __(ldr(imm4,area.active(imm2)))
5759        __(stru(imm4,-lisp_frame.size(sp)))
5760        __(str(imm3,lisp_frame.savelr(sp)))
5761        __(str(vsp,lisp_frame.savevsp(sp)))     /* for stack overflow code  */
5762        __(li fname,nrs.callbacks)      /* %pascal-functions%  */
5763        __(call_fname)
5764        __(ldr(imm2,lisp_frame.backlink(sp)))
5765        __(ldr(imm3,tcr.cs_area(rcontext)))
5766        __(str(imm2,area.active(imm3)))
5767        __(discard_lisp_frame())
5768        /* save_vsp will be restored from ff_call's stack frame, but  */
5769        /* I included it here for consistency.  */
5770        /* save_tsp is set below after we exit Lisp context.  */
5771        __(str(allocptr,tcr.save_allocptr(rcontext)))
5772        __(str(allocbase,tcr.save_allocbase(rcontext)))
5773        __(str(vsp,tcr.save_vsp(rcontext)))
5774        __(str(tsp,tcr.save_tsp(rcontext)))
5775        /* Exit lisp context  */
5776        /* This is not necessary yet, but will be once we can be interrupted  */
5777        __(li imm1,TCR_STATE_FOREIGN)
5778        __(str(imm1,tcr.valence(rcontext)))
5779        /* Restore the non-volatile registers & fpscr  */
5780        __(lfd fp_zero,c_reg_save.save_fp_zero(sp))
5781        __(ldr(r31,c_reg_save.save_fpscr(sp)))
5782        __(str(r31,c_reg_save.save_fp_zero+4(sp)))
5783        __(lfd f0,c_reg_save.save_fp_zero(sp))
5784        __(mtfsf 0xff,f0)
5785        __(ldr(r13,c_reg_save.save_gprs+(0*node_size)(sp)))
5786        __(ldr(r14,c_reg_save.save_gprs+(1*node_size)(sp)))
5787        __(ldr(r15,c_reg_save.save_gprs+(2*node_size)(sp)))
5788        __(ldr(r16,c_reg_save.save_gprs+(3*node_size)(sp)))
5789        __(ldr(r17,c_reg_save.save_gprs+(4*node_size)(sp)))
5790        __(ldr(r18,c_reg_save.save_gprs+(5*node_size)(sp)))
5791        __(ldr(r19,c_reg_save.save_gprs+(6*node_size)(sp)))
5792        __(ldr(r20,c_reg_save.save_gprs+(7*node_size)(sp)))
5793        __(ldr(r21,c_reg_save.save_gprs+(8*node_size)(sp)))
5794        __(ldr(r22,c_reg_save.save_gprs+(9*node_size)(sp)))
5795        __(ldr(r23,c_reg_save.save_gprs+(10*node_size)(sp)))
5796        __(ldr(r24,c_reg_save.save_gprs+(11*node_size)(sp)))
5797        __(ldr(r25,c_reg_save.save_gprs+(12*node_size)(sp)))
5798        __(ldr(r26,c_reg_save.save_gprs+(13*node_size)(sp)))
5799        __(ldr(r27,c_reg_save.save_gprs+(14*node_size)(sp)))
5800        __(ldr(r28,c_reg_save.save_gprs+(15*node_size)(sp)))
5801        __(ldr(r29,c_reg_save.save_gprs+(16*node_size)(sp)))
5802        __(ldr(r30,c_reg_save.save_gprs+(17*node_size)(sp)))
5803        __(ldr(r31,c_reg_save.save_gprs+(18*node_size)(sp)))
5804        __(lfd fp_s32conv,c_reg_save.save_fps32conv(sp))
5805        __(ldr(sp,0(sp)))
5806
5807        __(ldr(r3,varargs_eabi_c_frame.gp_save+(0*4)(sp)))
5808        __(ldr(r4,varargs_eabi_c_frame.gp_save+(1*4)(sp)))
5809        __(lfd f1,varargs_eabi_c_frame.gp_save+(2*4)(sp))
5810        __(ldr(r5,varargs_eabi_c_frame.savelr(sp)))
5811        __(str(r5,varargs_eabi_c_frame.old_savelr(sp)))
5812        __(mtlr r5)
5813        __(ldr(r5,varargs_eabi_c_frame.backlink(sp)))
5814        __(str(r5,varargs_eabi_c_frame.old_backlink(sp)))
5815        __(la sp,varargs_eabi_c_frame.old_backlink(sp))
5816        __(blr)
5817       
5818
5819/*      Do a linux system call:  the system call index is (boxed) */
5820/*      in arg_z, and other arguments are in an eabi_c_frame on */
5821/*      the C stack.  As is the case with an eabi_ff_call, there's */
5822/*      a lisp frame reserved underneath the eabi_c_frame. */
5823
5824/*      This is a little simpler than eabi_ff_call, because we */
5825/*      can assume that there are no synchronous callbacks to */
5826/*      lisp (that might cause a GC.)  It's also simpler for the */
5827/*      caller, since we return error status atomically. */
5828
5829/*      A system call can clobber any or all of r9-r12, so we need */
5830/*      to save and restore allocptr, allocbase, and tsp. */
5831       
5832_spentry(eabi_syscall)
5833/*      We're entered with an eabi_c_frame on the C stack.  There's a */
5834/*      lisp_frame reserved underneath it; we'll link it in in a minute. */
5835/*      Load the outgoing GPR arguments from eabi_c_frame.param`0-7', */
5836/*      then shrink the eabi_c_frame. */
5837
5838        __(mflr loc_pc)
5839        __(vpush_saveregs())
5840        __(str(sp,eabi_c_frame.savelr(sp)))
5841        __(li arg_x,nil_value)
5842        __(mr temp0,rcontext)
5843        __(ldr(temp1,c_frame.backlink(sp)))     /* bottom of reserved lisp frame  */
5844        __(la temp2,-lisp_frame.size(temp1))    /* top of lisp frame  */
5845        __(zero_doublewords temp2,0,lisp_frame.size)
5846        __(str(temp1,lisp_frame.backlink(temp2)))
5847        __(str(temp2,c_frame.backlink(sp)))
5848        __(str(fn,lisp_frame.savefn(temp2)))
5849        __(str(loc_pc,lisp_frame.savelr(temp2)))
5850        __(str(vsp,lisp_frame.savevsp(temp2)))
5851        __(ldr(temp3,tcr.cs_area(rcontext)))
5852        __(str(temp2,area.active(temp3)))
5853        __(str(allocptr,tcr.save_allocptr(rcontext)))
5854        __(str(allocbase,tcr.save_allocbase(rcontext)))
5855        __(str(tsp,tcr.save_tsp(rcontext)))
5856        __(str(vsp,tcr.save_vsp(rcontext)))
5857        __(str(rzero,tcr.ffi_exception(rcontext)))
5858        __(li imm1,TCR_STATE_FOREIGN)
5859        __(str(imm1,tcr.valence(rcontext)))
5860        __(ldr(r13,lisp_globals.saver13(0)))
5861        __(ldr(r3,eabi_c_frame.param0(sp)))
5862        __(ldr(r4,eabi_c_frame.param1(sp)))
5863        __(ldr(r5,eabi_c_frame.param2(sp)))
5864        __(ldr(r6,eabi_c_frame.param3(sp)))
5865        __(ldr(r7,eabi_c_frame.param4(sp)))
5866        __(ldr(r8,eabi_c_frame.param5(sp)))
5867        __(ldr(r9,eabi_c_frame.param6(sp)))
5868        __(ldr(r10,eabi_c_frame.param7(sp)))
5869        __(la temp1,eabi_c_frame.minsiz-eabi_c_frame.param0(sp))
5870        __(str(rzero,eabi_c_frame.savelr(temp1)))
5871        __(str(temp2,eabi_c_frame.backlink(temp1)))
5872        __(mr sp,temp1)
5873        __(unbox_fixnum(r0,arg_z))
5874        __(sc)
5875        __(nop)
5876        /* C should have preserved temp0 (= rcontext) for us.  */
5877        __(ldr(sp,0(sp)))
5878        __(mr imm2,temp0)
5879        __(ldr(vsp,lisp_frame.savevsp(sp)))
5880        __(li rzero,0)
5881        __(mr loc_pc,rzero)
5882        __(mr fn,rzero)
5883        __(li arg_x,nil_value)
5884        __(li arg_y,nil_value)
5885        __(li arg_z,nil_value)
5886        __(li temp0,nil_value)
5887        __(li temp1,nil_value)
5888        __(li temp2,nil_value)
5889        __(li temp3,nil_value)
5890        __(li fn,nil_value)
5891       
5892        __(li imm3,TCR_STATE_LISP)
5893        __(mr rcontext,imm2)
5894        __(li save0,0)
5895        __(li save1,0)
5896        __(li save2,0)
5897        __(li save3,0)
5898        __(li save4,0)
5899        __(li save5,0)
5900        __(li save6,0)
5901        __(li save7,0)       
5902        __(str(imm3,tcr.valence(rcontext)))
5903        __(vpop_saveregs)
5904        __(ldr(allocptr,tcr.save_allocptr(rcontext)))
5905        __(ldr(allocbase,tcr.save_allocbase(rcontext)))
5906        __(ldr(tsp,tcr.save_tsp(rcontext)))
5907        __(ldr(loc_pc,lisp_frame.savelr(sp)))
5908        __(mtlr loc_pc)
5909        __(ldr(fn,lisp_frame.savefn(sp)))
5910        __(discard_lisp_frame())
5911        __(bns 1f)
5912        __(neg r3,r3)
59131:     
5914        __(check_pending_interrupt(`cr1'))               
5915        __(mtxer rzero)
5916        __(blr)
5917       
5918/* arg_z should be of type (UNSIGNED-BYTE 64);  */
5919/* On PPC32, return high 32 bits in imm0, low 32 bits in imm1 */
5920/* On PPC64, return unboxed value in imm0  */
5921
5922_spentry(getu64)
5923        __ifdef(`PPC64')
5924        __(extract_typecode(imm0,arg_z))
5925        __(cmpdi cr0,imm0,tag_fixnum)
5926        __(cmpdi cr2,arg_z,0)
5927        __(cmpdi cr1,imm0,subtag_bignum)
5928        __(bne cr0,1f)
5929        __(unbox_fixnum(imm0,arg_z))
5930        __(bgelr cr2)
59310:             
5932        __(uuo_interr(error_object_not_u64,arg_z))
5933       
59341:      __(bne cr1,0b)
5935        __(getvheader(imm1,arg_z))
5936        __(ld imm0,misc_data_offset(arg_z))
5937        __(cmpdi cr2,imm1,two_digit_bignum_header)
5938        __(rotldi imm0,imm0,32)
5939        __(cmpdi cr1,imm1,three_digit_bignum_header)
5940        __(cmpdi cr0,imm0,0)
5941        __(beq cr2,2f)
5942        __(lwz imm1,misc_data_offset+8(arg_z))
5943        __(bne cr1,0b)
5944        __(cmpwi imm1,0)
5945        __(bne 0b)
5946        __(blr)
59472:      __(blt 0b)
5948        __(blr)       
5949        __else
5950        __(extract_typecode(imm0,arg_z))
5951        __(cmpri(cr0,imm0,tag_fixnum))
5952        __(cmpri(cr1,arg_z,0))
5953        __(cmpri(cr2,imm0,subtag_bignum))
5954        __(unbox_fixnum(imm1,arg_z))
5955        __(bne cr0,8f)
5956        __(bgelr cr1)
59579:
5958        __(uuo_interr(error_object_not_u64,arg_z))
59598:
5960        __(bne- cr2,9b)
5961        __(getvheader(imm2,arg_z))
5962        __(cmpri(cr2,imm2,two_digit_bignum_header))
5963        __(vrefr(imm1,arg_z,0))
5964        __(cmpri(cr1,imm1,0))
5965        __(li imm0,0)
5966        __(bge cr2,2f)
5967        __(blt- cr1,9b)
5968        __(blr)
59692:
5970        __(cmpri(cr0,imm2,three_digit_bignum_header))
5971        __(vrefr(imm0,arg_z,1))
5972        __(cmpri(cr1,imm0,0))
5973        __(bne cr2,3f)
5974        __(blt- cr1,9b)
5975        __(blr)
59763:
5977        __(vrefr(imm2,arg_z,2))
5978        __(cmpri(cr1,imm2,0))
5979        __(bne- cr0,9b)
5980        __(bne- cr1,9b)
5981        __(blr)
5982        __endif
5983       
5984/* arg_z should be of type (SIGNED-BYTE 64);  */
5985/* PPC32:   return high 32 bits  in imm0, low 32 bits in imm1  */
5986/* PPC64:   return unboxed value in imm0  */
5987
5988_spentry(gets64)
5989        __ifdef(`PPC64')
5990         __(extract_typecode(imm1,arg_z))
5991         __(unbox_fixnum(imm0,arg_z))
5992         __(cmpri(cr0,imm1,tag_fixnum))
5993         __(cmpri(cr2,imm1,subtag_bignum))
5994         __(beqlr cr0)
5995         __(bne cr2,9f)
5996         __(ld imm1,misc_header_offset(arg_z))
5997         __(ld imm0,misc_data_offset(arg_z))
5998         __(cmpdi imm1,two_digit_bignum_header)
5999         __(rotldi imm0,imm0,32)
6000         __(beqlr)
6001        __else
6002         __(extract_typecode(imm0,arg_z))
6003         __(cmpri(cr0,imm0,tag_fixnum))
6004         __(cmpri(cr2,imm0,subtag_bignum))
6005         __(unbox_fixnum(imm1,arg_z))
6006         __(srawi imm0,imm1,31)
6007         __(beqlr cr0)
6008         __(bne cr2,9f)
6009         __(getvheader(imm2,arg_z))
6010         __(cmpri(cr2,imm2,two_digit_bignum_header))
6011         __(vrefr(imm1,arg_z,0))
6012         __(srawi imm0,imm1,31)
6013         __(bltlr cr2)
6014         __(vrefr(imm0,arg_z,1))
6015         __(beqlr cr2)
6016        __endif
60179:
6018        __(uuo_interr(error_object_not_s64,arg_z))
6019
6020
6021/*  Construct a lisp integer out of the 64-bit unsigned value in */
6022/*        ppc32:    imm0 (high 32 bits) and imm1 (low 32 bits) */
6023/*        ppc64:    imm0 (64 bits) .  */
6024_spentry(makeu64)
6025        __ifdef(`PPC64')
6026         __(clrrdi. imm1,imm0,63-nfixnumtagbits)
6027         __(cmpri(cr1,imm0,0))
6028         __(box_fixnum(arg_z,imm0))
6029         __(beqlr cr0) /* A fixnum  */
6030         __(rotldi imm1,imm0,32)
6031         __(li imm2,two_digit_bignum_header)
6032         __(blt cr1,2f)
6033         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6034         __(str(imm1,misc_data_offset(arg_z)))
6035         __(blr)
60362:
6037         __(li imm2,three_digit_bignum_header)
6038         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6039         __(str(imm1,misc_data_offset(arg_z)))
6040         __(blr)
6041        __else       
6042         __(cmpri(cr1,imm0,0))
6043         __(rlwinm. imm2,imm1,0,0,fixnum_shift)
6044         __(li imm2,three_digit_bignum_header)
6045         __(box_fixnum(arg_z,imm1))
6046         __(blt cr1,3f)
6047         __(bne cr1,2f)
6048         __(beqlr cr0) /* A fixnum  */
6049         __(blt cr0,2f)
6050         __(li imm2,one_digit_bignum_header)
6051         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
6052         __(str(imm1,misc_data_offset(arg_z)))
6053         __(blr)
60542:
6055         __(li imm2,two_digit_bignum_header)
6056         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6057         __(str(imm1,misc_data_offset(arg_z)))
6058         __(str(imm0,misc_data_offset+4(arg_z)))
6059         __(blr)
60603:
6061         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6062         __(str(imm1,misc_data_offset(arg_z)))
6063         __(str(imm0,misc_data_offset+4(arg_z)))
6064         __(blr)
6065        __endif
6066
6067
6068
6069/*  Construct a lisp integer out of the 64-bit signed value in */
6070/*        ppc32:    imm0 (high 32 bits) and imm1 (low 32 bits). */
6071/*        ppc64:    imm0  */
6072_spentry(makes64)
6073        __ifdef(`PPC64')
6074         __(addo imm1,imm0,imm0)
6075         __(addo imm1,imm1,imm1)
6076         __(addo. arg_z,imm1,imm1)
6077         __(bnslr+)
6078         __(mtxer rzero)
6079         __(li imm1,two_digit_bignum_header)
6080         __(rotldi imm0,imm0,32)
6081         __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
6082         __(str(imm0,misc_data_offset(arg_z)))
6083         __(blr)
6084        __else
6085         __(srawi imm2,imm1,31)
6086         __(cmpr(cr1,imm2,imm0))
6087         __(addo imm2,imm1,imm1)
6088         __(addo. arg_z,imm2,imm2)
6089         __(bne cr1,2f) /* High word is significant  */
6090         __(li imm2,one_digit_bignum_header)
6091         __(bnslr cr0) /* No overflow:   fixnum  */
6092         __(mtxer rzero)
6093         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
6094         __(str(imm1,misc_data_offset(arg_z)))
6095         __(blr)
60962:
6097         __(mtxer rzero)
6098         __(li imm2,two_digit_bignum_header)
6099         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6100         __(str(imm1,misc_data_offset(arg_z)))
6101         __(str(imm0,misc_data_offset+4(arg_z)))
6102         __(blr)
6103        __endif
6104
6105/* imm0:imm1 constitute an unsigned integer, almost certainly a bignum. */
6106/* Make a lisp integer out of those 128 bits ..  */
6107_spentry(makeu128)
6108        __ifdef(`PPC64')
6109         __(cmpdi imm0,0)
6110         __(cmpdi cr1,imm1,0)
6111         __(srdi imm3,imm0,32)
6112         __(srawi imm4,imm0,31)
6113         __(cmpdi cr3,imm3,0)
6114         __(cmpdi cr4,imm4,0)
6115         __(li imm2,five_digit_bignum_header)
6116         __(blt cr1,0f)
6117         __(beq 3f)
61180:             
6119         __(bge 1f)
6120         /* All 128 bits are significant, and the most significant */
6121         /* bit is set.  Allocate a 5-digit bignum (with a zero */
6122         /* sign digit  */
6123         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(5)))
6124         __(rotldi imm0,imm0,32)
6125         __(rotldi imm1,imm1,32)
6126         __(std imm1,misc_data_offset(arg_z))
6127         __(std imm0,misc_data_offset+8(arg_z))
6128         __(blr)
61291:       /* If the high word of imm0 is a zero-extension of the low */
6130         /* word, we only need 3 digits ; otherwise, we need 4.  */
6131         __(li imm2,three_digit_bignum_header)
6132         __(rotldi imm1,imm1,32)
6133         __(bne cr3,2f) /* high word of imm0 is non-zero  */
6134         __(bne cr4,2f) /* sign bit is on in low word of imm0  */
6135         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6136         __(std imm1,misc_data_offset(arg_z))
6137         __(stw imm0,misc_data_offset+8(arg_z))
6138         __(blr)
61392:       __(li imm2,four_digit_bignum_header)
6140         __(rotldi imm0,imm0,32)
6141         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
6142         __(std imm1,misc_data_offset(arg_z))
6143         __(std imm0,misc_data_offset+8(arg_z))
6144         __(blr)
61453:       __(mr imm0,imm1)
6146         __(b _SPmakeu64)             
6147        __else
6148         __(twgei r0,r0)
6149        __endif
6150
6151/* imm0:imm1 constitute a signed integer, almost certainly a bignum. */
6152/* Make a lisp integer out of those 128 bits ..  */
6153_spentry(makes128)
6154        __ifdef(`PPC64')
6155         /* Is imm0 just a sign-extension of imm1 ?  */
6156         __(sradi imm2,imm1,63)
6157         /* Is the high word of imm0 just a sign-extension of the low word ?  */
6158         __(extsw imm3,imm0)
6159         __(cmpd imm2,imm0)
6160         __(cmpd cr1,imm3,imm0)
6161         __(beq 2f)
6162         __(rotldi imm0,imm0,32)
6163         __(rotldi imm1,imm1,32)
6164         __(beq cr1,1f)
6165         __(li imm2,four_digit_bignum_header)
6166         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(4)))
6167         __(std imm1,misc_data_offset(arg_z))
6168         __(std imm0,misc_data_offset+8(arg_z))
6169         __(blr)
61701:       __(li imm2,three_digit_bignum_header)
6171         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
6172         __(std imm1,misc_data_offset(arg_z))
6173         __(stw imm3,misc_data_offset+8(arg_z))
6174         __(blr)
61752:       __(mr imm0,imm1)
6176         __(b _SPmakes64)       
6177        __else
6178         __(twgei r0,r0)
6179        __endif       
6180                       
6181/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
6182/* unbound_marker), arg_y = symbol, imm3 = symbol.binding-index  */
6183_spentry(specref)
6184        __(ldr(imm3,symbol.binding_index(arg_z)))
6185        __(ldr(imm0,tcr.tlb_limit(rcontext)))
6186        __(cmpr(imm3,imm0))
6187        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6188        __(mr arg_y,arg_z)
6189        __(bge 1f)
6190        __(ldrx(arg_z,imm2,imm3))
6191        __(cmpri(arg_z,no_thread_local_binding_marker))
6192        __(bnelr)
61931:      __(ldr(arg_z,symbol.vcell(arg_y)))
6194        __(blr)
6195
6196
6197_spentry(specrefcheck)
6198        __(ldr(imm3,symbol.binding_index(arg_z)))
6199        __(ldr(imm0,tcr.tlb_limit(rcontext)))
6200        __(cmpr(imm3,imm0))
6201        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6202        __(mr arg_y,arg_z)
6203        __(bge 1f)
6204        __(ldrx(arg_z,imm2,imm3))
6205        __(cmpri(arg_z,no_thread_local_binding_marker))
6206        __(bne 2f)
62071:      __(ldr(arg_z,symbol.vcell(arg_y)))
62082:      __(treqi(arg_z,unbound_marker))
6209        __(blr)
6210       
6211/* arg_y = special symbol, arg_z = new value.          */
6212_spentry(specset)
6213        __(ldr(imm3,symbol.binding_index(arg_y)))
6214        __(ldr(imm0,tcr.tlb_limit(rcontext)))
6215        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
6216        __(cmpr(imm3,imm0))
6217        __(bge 1f)
6218        __(ldrx(temp1,imm2,imm3))
6219        __(cmpri(temp1,no_thread_local_binding_marker))
6220        __(beq 1f)
6221        __(strx(arg_z,imm2,imm3))
6222        __(blr)
62231:      __(mr arg_x,arg_y)
6224        __(li arg_y,symbol.vcell-misc_data_offset)
6225        __(b _SPgvset)
6226
6227/* Restore current thread's interrupt level to arg_z, */
6228/* noting whether the tcr's interrupt_pending flag was set.  */
6229_spentry(restoreintlevel)
6230        __(cmpri(cr1,arg_z,0))
6231        __(ldr(imm0,tcr.interrupt_pending(rcontext)))
6232        __(cmpri(cr0,imm0,0))
6233        __(bne cr1,1f)
6234        __(beq cr0,1f)
6235        __(str(rzero,tcr.interrupt_pending(rcontext)))
6236        __(li nargs,fixnum_one)
6237        __(trgti(nargs,0))
6238        __(blr)
62391:
6240        __(ldr(nargs,tcr.tlb_pointer(rcontext)))
6241        __(str(arg_z,INTERRUPT_LEVEL_BINDING_INDEX(nargs)))
6242        __(blr)
6243
6244
6245/* Construct a lisp integer out of the 32-bit signed value in imm0 */
6246
6247       
6248_spentry(makes32)
6249        __ifdef(`PPC64')
6250         __(box_fixnum(arg_z,imm0))
6251        __else
6252         __(addo imm1,imm0,imm0)
6253         __(addo. arg_z,imm1,imm1)
6254         __(bnslr+)
6255         __(mtxer rzero)
6256         __(li imm1,one_digit_bignum_header)
6257         __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
6258         __(str(imm0,misc_data_offset(arg_z)))
6259        __endif
6260         __(blr)
6261
6262
6263/* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
6264
6265       
6266_spentry(makeu32)
6267        __ifdef(`PPC64')
6268         __(box_fixnum(arg_z,imm0))
6269         __(blr)
6270        __else
6271         __(clrrwi. imm1,imm0,31-nfixnumtagbits)
6272         __(cmpri(cr1,imm0,0))
6273         __(box_fixnum(arg_z,imm0))
6274         __(beqlr cr0) /* A fixnum  */
6275         __(blt cr1,2f)
6276         __(li imm2,one_digit_bignum_header)
6277         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(1)))
6278         __(str(imm0,misc_data_offset(arg_z)))
6279         __(blr)
62802:
6281         __(li imm2,two_digit_bignum_header)
6282         __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
6283         __(str(imm0,misc_data_offset(arg_z)))
6284         __(blr)
6285        __endif
6286
6287/*  */
6288/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
6289/*  */
6290_spentry(gets32)
6291        __ifdef(`PPC64')
6292         __(sldi imm1,arg_z,32-fixnumshift)
6293         __(extract_lisptag_(imm0,arg_z))
6294         __(sradi imm1,imm1,32-fixnumshift)
6295         __(box_fixnum(imm0,arg_z))
6296         __(cmpd cr1,imm1,arg_z)
6297         __(bne cr0,9f)
6298         __(beqlr cr1)
6299         __(b 9f)
6300        __else
6301         __(extract_typecode(imm1,arg_z))
6302         __(cmpri(cr0,imm1,tag_fixnum))
6303         __(cmpri(cr2,imm1,subtag_bignum))
6304         __(unbox_fixnum(imm0,arg_z))
6305         __(beqlr+ cr0)
6306         __(bne cr2,9f)
6307         __(getvheader(imm1,arg_z))
6308         __(cmpri(cr1,imm1,one_digit_bignum_header))
6309         __(vrefr(imm0,arg_z,0))
6310         __(beqlr+ cr1)
6311        __endif
63129:
6313        __(uuo_interr(error_object_not_signed_byte_32,arg_z))
6314
6315/*  */
6316/* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
6317/*  */
6318
6319_spentry(getu32)
6320        __(extract_typecode(imm1,arg_z))
6321        __(cmpri(cr0,imm1,tag_fixnum))
6322        __(cmpri(cr1,arg_z,0))
6323        __(cmpri(cr2,imm1,subtag_bignum))
6324        __(unbox_fixnum(imm0,arg_z))
6325        __(bne cr0,8f)
6326        __(bgelr cr1)
63278:
6328        __(bne- cr2,9f)
6329        __(getvheader(imm2,arg_z))
6330        __(cmpri(cr2,imm2,two_digit_bignum_header))
6331        __(vrefr(imm0,arg_z,0))
6332        __(cmpri(cr0,imm0,0))
6333        __(bgt cr2,9f)
6334        __(beq cr2,2f)
6335        __(blt cr0,9f)
6336        __(blr)
63372:
6338        __(vrefr(imm1,arg_z,1))
6339        __(cmpri(cr0,imm1,0))
6340        __(beqlr+ cr0)
6341
63429:
6343        __(uuo_interr(error_object_not_unsigned_byte_32,arg_z))
6344
6345/* */
6346/* arg_z has overflowed (by one bit) as the result of an addition or subtraction. */
6347/* Make a bignum out of it. */
6348
6349_spentry(fix_overflow)
6350        __(mtxer rzero)
6351        __(unbox_fixnum(imm1,arg_z))
6352        __ifdef(`PPC64')
6353         __(li imm0,two_digit_bignum_header)
6354         __(rotldi imm1,imm1,32)
6355         __(xoris imm1,imm1,0xe000)
6356         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(2)))
6357         __(str(imm1,misc_data_offset(arg_z)))
6358        __else
6359         __(li imm0,one_digit_bignum_header)
6360         __(xoris imm1,imm1,0xc000)
6361         __(Misc_Alloc_Fixed(arg_z,imm0,aligned_bignum_size(1)))
6362         __(str(imm1,misc_data_offset(arg_z)))
6363        __endif
6364        __(blr)
6365               
6366
6367
6368/* */
6369/* As per mvpass above, but in this case fname is known to be a */
6370/* symbol. */
6371
6372_spentry(mvpasssym)
6373        __(cmpri(cr0,nargs,node_size*nargregs))
6374        __(mflr loc_pc)
6375        __(mr imm0,vsp)
6376        __(ble+ cr0,1f)
6377         __(subi imm0,imm0,node_size*nargregs)
6378         __(add imm0,imm0,nargs)
63791:           
6380        __(build_lisp_frame(fn,loc_pc,imm0))
6381        __(ref_global(loc_pc,ret1val_addr))
6382        __(li fn,0)
6383        __(mtlr loc_pc)
6384        __(jump_fname())
6385
6386
6387
6388_spentry(unbind)
6389        __(ldr(imm1,tcr.db_link(rcontext)))
6390        __(ldr(imm2,tcr.tlb_pointer(rcontext)))   
6391        __(ldr(imm3,binding.sym(imm1)))
6392        __(ldr(temp1,binding.val(imm1)))
6393        __(ldr(imm1,binding.link(imm1)))
6394        __(strx(temp1,imm2,imm3))
6395        __(str(imm1,tcr.db_link(rcontext)))
6396        __(blr)
6397
6398_spentry(unbind_n)
6399        __(ldr(imm1,tcr.db_link(rcontext)))
6400        __(ldr(imm2,tcr.tlb_pointer(rcontext)))   
64011:      __(subi imm0,imm0,1)
6402        __(ldr(imm3,binding.sym(imm1)))
6403        __(ldr(temp1,binding.val(imm1)))
6404        __(cmpri(imm0,0))
6405        __(ldr(imm1,binding.link(imm1)))
6406        __(strx(temp1,imm2,imm3))
6407        __(bne 1b)
6408        __(str(imm1,tcr.db_link(rcontext)))
6409        __(blr)
6410
6411/* */
6412/* Clobbers imm1,imm2,imm5,arg_x, arg_y */
6413
6414_spentry(unbind_to)
6415        __(ldr(imm1,tcr.db_link(rcontext)))
6416        __(ldr(imm2,tcr.tlb_pointer(rcontext)))
64171:      __(ldr(imm5,binding.sym(imm1)))
6418        __(ldr(arg_y,binding.val(imm1)))
6419        __(ldr(imm1,binding.link(imm1)))
6420        __(cmpr(imm0,imm1))
6421        __(strx(arg_y,imm2,imm5))
6422        __(bne 1b)
6423        __(str(imm1,tcr.db_link(rcontext)))
6424        __(blr)
6425       
6426
6427
6428/* */
6429/* Restore the special bindings from the top of the tstack,  */
6430/* leaving the tstack frame allocated.  */
6431/* Note that there might be 0 saved bindings, in which case  */
6432/* do nothing.  */
6433/* Note also that this is -only- called from an unwind-protect  */
6434/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
6435/* values in a frame on top of the tstack.  */
6436/*  */
6437                       
6438_spentry(progvrestore)
6439        __(ldr(imm0,tsp_frame.backlink(tsp)))   /* ignore .SPnthrowXXX values frame  */
6440        __(ldr(imm0,tsp_frame.data_offset(imm0)))
6441        __(cmpri(cr0,imm0,0))
6442        __(unbox_fixnum(imm0,imm0))
6443        __(bne+ cr0,_SPunbind_n)
6444        __(blr)
6445
6446/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
6447/* for pending interrupts after doing so.  "nargs" can be freely used for an */
6448/* interrupt trap in this context.  */
6449_spentry(bind_interrupt_level_0)
6450        __(ldr(imm4,tcr.tlb_pointer(rcontext)))
6451        __(ldr(temp0,INTERRUPT_LEVEL_BINDING_INDEX(imm4)))
6452        __(ldr(imm1,tcr.db_link(rcontext)))
6453        __(cmpri(temp0,0))
6454        __(li imm3,INTERRUPT_LEVEL_BINDING_INDEX)
6455        __(vpush(temp0))