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

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

In the destructuring-bind subprims (still used for inlining some cases
involving &KEY, handle :ALLOW-OTHER-KEYS correctly. (See
CL-TEST::LAMBDA.27, CL-TEST::LAMBDA.32 in the test suite.)

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