source: branches/arm/lisp-kernel/arm-spentry.s @ 13958

Last change on this file since 13958 was 13958, checked in by gb, 9 years ago

Get the kernel to compile/link/run enough to complain about a missing
image on ios.

File size: 143.3 KB
Line 
1/* Copyright (C) 2010 Clozure Associates */
2/* This file is part of Clozure CL.   */
3
4/* Clozure CL is licensed under the terms of the Lisp Lesser GNU Public */
5/* License , known as the LLGPL and distributed with Clozure CL as the */
6/* file "LICENSE".  The LLGPL consists of a preamble and the LGPL, */
7/* which is distributed with Clozure CL as the file "LGPL".  Where these */
8/* conflict, the preamble takes precedence.   */
9
10/* Clozure CL 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        .arm
21        .syntax unified
22
23local_label(start):
24        .set delta,256
25        .set spnum,0
26        .set sporg,0
27define(`_spentry',`ifdef(`__func_name',`_endfn',`')
28        .org sporg
29        .set sporg,sporg+delta
30        .set spnum,spnum+1
31        .if spnum >= 112
32        .set delta,1024
33        .endif
34        _exportfn(_SP$1)
35        .line  __line__
36')
37
38
39define(`_endsubp',`
40        _endfn(_SP$1)
41# __line__
42')
43
44
45       
46
47define(`jump_builtin',`
48        ref_nrs_value(fname,builtin_functions)
49        set_nargs($2)
50        vrefr(fname,fname,$1)
51        jump_fname()
52')
53
54/* Set the _function.entrypoint locative in nfn - which pointed here -
55   to the address of the first instruction in the _function.codevector.
56   This must be the first ARM subprim. */
57
58_spentry(fix_nfn_entrypoint)
59        __(build_lisp_frame(imm0))
60        __(vpush1(arg_z))
61        __(ldr arg_z,[nfn,#_function.codevector])
62        __(add lr,arg_z,#misc_data_offset)
63        __(str lr,[nfn,#_function.entrypoint])
64        __(vpop1(arg_z))
65        __(restore_lisp_frame(imm0))
66        __(jump_nfn())
67
68        /* This isn't a subprim - we never have to MOV this address
69        to the PC, but it gets LDRed into the PC as part of the
70        standard calling sequence.  Ensuring that that happens -
71        without having to deal with updating the entrypoint associated
72        with a relocatable code-vector stored in a non-function -
73        is easiest if we use a fixed address here. */
74       
75        .org sporg-delta+0x40
76_exportfn(udfcall)
77        __(uuo_error_udf_call(al,fname))
78        __(jump_fname)
79_endfn               
80       
81_spentry(builtin_plus)
82        __(test_two_fixnums(arg_y,arg_z,imm0))
83        __(bne 1f)
84        __(adds arg_z,arg_y,arg_z)
85        __(bxvc lr)
86        __(b _SPfix_overflow)
871:
88        __(jump_builtin(_builtin_plus,2))
89       
90_spentry(builtin_minus)
91        __(test_two_fixnums(arg_y,arg_z,imm0))
92        __(bne 1f)
93        __(subs arg_z,arg_y,arg_z)
94        __(bxvc lr)
95        __(b _SPfix_overflow)
961:
97        __(jump_builtin(_builtin_minus,2))
98
99_spentry(builtin_times)
100        __(test_two_fixnums(arg_y,arg_z,imm0))
101        __(bne 1f)
102        __(unbox_fixnum(imm2,arg_z))
103        __(unbox_fixnum(imm0,arg_y))
104        __(smull imm0,imm1,imm2,imm0)
105        __(b _SPmakes64)
106
1071: __(jump_builtin(_builtin_times,2))
108
109_spentry(builtin_div)
110        __(jump_builtin(_builtin_div,2))
111
112_spentry(builtin_eq)
113        __(test_two_fixnums(arg_y,arg_z,imm0))
114        __(bne 1f)
115        __(cmp arg_y,arg_z)
116        __(mov arg_z,#nil_value)
117        __(addeq arg_z,arg_z,#t_offset)
118        __(bx lr)       
1191:
120        __(jump_builtin(_builtin_eq,2))
121                       
122_spentry(builtin_ne)
123        __(test_two_fixnums(arg_y,arg_z,imm0))
124        __(bne 1f)
125        __(cmp arg_y,arg_z)
126        __(mov arg_z,#nil_value)
127        __(addne arg_z,arg_z,#t_offset)
128        __(bx lr)
1291:
130        __(jump_builtin(_builtin_ne,2))
131
132_spentry(builtin_gt)
133        __(test_two_fixnums(arg_y,arg_z,imm0))
134        __(bne 1f)
135        __(cmp arg_y,arg_z)
136        __(mov arg_z,#nil_value)
137        __(addgt arg_z,arg_z,#t_offset)
138        __(bx lr)
1391:
140        __(jump_builtin(_builtin_gt,2))
141
142_spentry(builtin_ge)
143        __(test_two_fixnums(arg_y,arg_z,imm0))
144        __(bne 1f)
145        __(cmp arg_y,arg_z)
146        __(mov arg_z,#nil_value)
147        __(addge arg_z,arg_z,#t_offset)
148        __(bx lr)
1491:
150        __(jump_builtin(_builtin_ge,2))
151
152_spentry(builtin_lt)
153        __(test_two_fixnums(arg_y,arg_z,imm0))
154        __(bne 1f)
155        __(cmp arg_y,arg_z)
156        __(mov arg_z,#nil_value)
157        __(addgt arg_z,arg_z,#t_offset)
158        __(bx lr)
1591:
160        __(jump_builtin(_builtin_lt,2))
161
162_spentry(builtin_le)
163        __(test_two_fixnums(arg_y,arg_z,imm0))
164        __(bne 1f)
165        __(cmp arg_y,arg_z)
166        __(mov arg_z,#nil_value)
167        __(addle arg_z,arg_z,#t_offset)
168        __(bx lr)
1691:
170        __(jump_builtin(_builtin_le,2))
171
172_spentry(builtin_eql)
173        __(cmp arg_y,arg_z)
174        __(beq 1f)
175        __(extract_fulltag(imm0,arg_y))
176        __(extract_fulltag(imm1,arg_z))
177        __(cmp imm0,imm1)
178        __(bne 2f)
179        __(cmp imm0,#fulltag_misc)
180        __(bne 2f)
181        __(jump_builtin(_builtin_eql,2))
1821:      __(mov arg_z,#nil_value)
183        __(add arg_z,arg_z,#t_offset)
184        __(bx lr)
1852:      __(mov arg_z,#nil_value)
186        __(bx lr)
187       
188_spentry(builtin_length)
189        __(extract_typecode(imm0,arg_z))
190        __(cmp imm0,#min_vector_subtag)
191        __(ldreq arg_z,[arg_z,#vectorH.logsize])
192        __(bxeq lr)
193        __(blo 1f)
194        __(vector_length(arg_z,arg_z,imm0))
195        __(bx lr)
1961:      __(cmp imm0,#tag_list)
197        __(bne 8f)
198        __(mov temp2,#-1<<fixnum_shift)
199        __(mov temp0,arg_z) /* fast pointer  */
200        __(mov temp1,arg_z) /* slow pointer  */
2012:      __(cmp temp0,#nil_value)
202        __(add temp2,temp2,#fixnumone)
203        __(beq 9f)
204        __(extract_lisptag(imm0,temp0))
205        __(cmp imm0,#tag_list)
206        __(bne 8f)
207        __(_cdr(temp0,temp0))
208        __(tst temp2,#fixnumone)
209        __(beq 2b)
210        __(_cdr(temp1,temp1))
211        __(cmp temp1,temp0)
212        __(bne 2b)
2138: 
214        __(jump_builtin(_builtin_length,1))
2159:      __(mov arg_z,temp2)
216        __(bx lr)       
217
218_spentry(builtin_seqtype)
219        __(extract_typecode(imm0,arg_z))
220        __(cmp imm0,#min_vector_subtag)
221        __(movge arg_z,#nil_value)
222        __(bxge lr)
223        __(cmp imm0,#tag_list)
224        __(moveq arg_z,#nil_value)
225        __(addeq arg_z,arg_z,#t_offset)
226        __(bxeq lr)
227        __(jump_builtin(_builtin_seqtype,1))
228
229/* This is usually inlined these days */
230_spentry(builtin_assq)
231        __(b 2f)
2321:      __(trap_unless_list(arg_z,imm0))
233        __(_car(arg_x,arg_z))
234        __(_cdr(arg_z,arg_z))
235        __(cmp arg_x,#nil_value)
236        __(beq 2f)
237        __(trap_unless_list(arg_x,imm0))
238        __(_car(temp0,arg_x))
239        __(cmp temp0,arg_y)
240        __(bne 2f)
241        __(mov arg_z,arg_x)
242        __(bx lr)
2432:      __(cmp arg_z,#nil_value)
244        __(bne 1b)
245        __(bx lr)
246 
247_spentry(builtin_memq)
248        __(cmp arg_z,nil_value)
249        __(b 2f)
2501:      __(trap_unless_list(arg_z,imm0))
251        __(_car(arg_x,arg_z))
252        __(_cdr(temp0,arg_z))
253        __(cmp arg_x,arg_y)
254        __(bxeq lr)
255        __(cmp temp0,nil_value)
256        __(mov arg_z,temp0)
2572:      __(bne 1b)
258        __(bx lr)
259
260_spentry(builtin_logbitp)
261/* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
262        __(test_two_fixnums(arg_y,arg_z,imm0))
263        __(bne 1f)
264        __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
265        __(bhs 1f)
266        __(unbox_fixnum(imm0,arg_y))
267        __(mov imm1,#fixnum1)
268        __(tst arg_z,imm1,lsl imm0)
269        __(mov arg_z,#nil_value)
270        __(addne arg_z,arg_z,#t_offset)
271        __(bx lr)
2721:
273        __(jump_builtin(_builtin_logbitp,2))
274
275_spentry(builtin_logior)
276        __(orr imm0,arg_y,arg_z)
277        __(test_fixnum(imm0))
278        __(moveq arg_z,imm0)
279        __(bxeq lr)
280        __(jump_builtin(_builtin_logior,2))
281
282_spentry(builtin_logand)
283        __(test_two_fixnums(arg_y,arg_z,imm0))
284        __(andeq arg_z,arg_y,arg_z)
285        __(bxeq lr)
286        __(jump_builtin(_builtin_logand,2))
287         
288_spentry(builtin_ash)
289        __(test_two_fixnums(arg_y,arg_z,imm0))
290        __(bne 9f)
291        __(cmp arg_z,#0)
292        __(bgt 1f)
293        __(moveq arg_z,arg_y)
294        __(bxeq lr)
295        /* Shift right */
296        __(unbox_fixnum(imm2,arg_z))
297        __(rsb imm2,imm2,#0)
298        __(cmp imm2,#32)
299        __(movge imm2,#31)
300        __(mov arg_z,#-fixnumone)
301        __(and arg_z,arg_z,arg_y,lsr imm2)
302        __(bx lr)
303        /* shift left */
3041:      __(unbox_fixnum(imm0,arg_y))
305        __(unbox_fixnum(imm2,arg_z))
306        __(cmp imm2,#32)
307        __(moveq imm1,imm0)
308        __(moveq imm0,#0)
309        __(beq _SPmakes64)
310        __(bgt 9f)
311        __(rsb imm1,imm2,#32)
312        __(mov imm1,imm0,asr imm1)
313        __(mov imm0,imm0,lsl imm2)
314        __(b _SPmakes64)
3159: 
316        __(jump_builtin(_builtin_ash,2))
317                                       
318_spentry(builtin_negate)
319        __(test_fixnum(arg_z))
320        __(bne 1f)
321        __(rsbs arg_z,arg_z,#0)
322        __(bxvc lr)
323        __(b _SPfix_overflow)
3241:
325        __(jump_builtin(_builtin_negate,1))
326 
327_spentry(builtin_logxor)
328        __(test_two_fixnums(arg_y,arg_z,imm0))
329        __(eoreq arg_z,arg_y,arg_z)
330        __(bxeq lr)
331        __(jump_builtin(_builtin_logxor,2))
332
333_spentry(builtin_aref1)
334        __(extract_typecode(imm0,arg_y))
335        __(cmp imm0,#min_vector_subtag)
336        __(box_fixnum(arg_x,imm0))
337        __(bgt _SPsubtag_misc_ref)
338        __(jump_builtin(_builtin_aref1,2))
339
340_spentry(builtin_aset1)
341        __(extract_typecode(imm0,arg_x))
342        __(cmp imm0,#min_vector_subtag)
343        __(box_fixnum(temp0,imm0))
344        __(bgt _SPsubtag_misc_set)
345        __(jump_builtin(_builtin_aset1,3))
346                       
347
348        /*  Call nfn if it's either a symbol or function */
349_spentry(funcall)
350        __(funcall_nfn())
351
352/* Subprims for catch, throw, unwind_protect.  */
353
354
355_spentry(mkcatch1v)
356        __(mov imm2,#0)
357        __(mkcatch())
358        __(bx lr)
359
360
361_spentry(mkcatchmv)
362        __(mov imm2,#fixnum_one)
363        __(mkcatch())
364        __(bx lr)
365
366_spentry(mkunwind)
367        __(mov imm2,#-fixnumone)
368        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
369        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
370        __(ldr arg_y,[temp0,#INTERRUPT_LEVEL_BINDING_INDEX])
371        __(ldr imm0,[rcontext,#tcr.db_link])
372        __(vpush1(arg_y))
373        __(vpush1(imm1))
374        __(vpush1(imm0))
375        __(str imm2,[temp0,#INTERRUPT_LEVEL_BINDING_INDEX])
376        __(str vsp,[rcontext,#tcr.db_link])
377        __(mov arg_z,#unbound_marker)
378        __(mov imm2,#fixnum_one)
379        __(mkcatch())
380        __(mov arg_z,arg_y)
381        __(b _SPbind_interrupt_level)
382       
383
384/* This never affects the symbol's vcell  */
385/* Non-null symbol in arg_y, new value in arg_z          */
386_spentry(bind)
387        __(ldr imm1,[arg_y,#symbol.binding_index])
388        __(ldr imm0,[rcontext,#tcr.tlb_limit])
389        __(cmp imm0,imm1)
390        __(uuo_tlb_too_small(ls,imm1))
391        __(cmp imm1,#0)
392        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
393        __(ldr imm0,[rcontext,#tcr.db_link])
394        __(ldr temp1,[imm2,imm1])
395        __(beq 9f)
396        __(vpush1(temp1))
397        __(vpush1(imm1))
398        __(vpush1(imm0))
399        __(str arg_z,[imm2,imm1])
400        __(str vsp,[rcontext,#tcr.db_link])
401        __(bx lr)
4029:
403        __(mov arg_z,arg_y)
404        __(mov arg_y,#XSYMNOBIND)
405        __(set_nargs(2))
406        __(b _SPksignalerr)
407
408_spentry(conslist)
409        __(mov arg_z,#nil_value)
410        __(cmp nargs,#0)
411        __(b 2f) 
4121:
413        __(vpop1(arg_y))
414        __(Cons(arg_z,arg_y,arg_z))
415        __(subs nargs,nargs,#fixnum_one)
4162:
417        __(bne 1b)
418        __(bx lr)
419
420/* do list*: last arg in arg_z, all others vpushed, nargs set to #args vpushed.  */
421/* Cons, one cons cell at at time.  Maybe optimize this later.  */
422
423_spentry(conslist_star)
424        __(cmp nargs,#0)
425        __(b 2f) 
4261:
427        __(vpop1(arg_y))
428        __(Cons(arg_z,arg_y,arg_z))
429        __(subs nargs,nargs,fixnum_one)
4302:
431        __(bne 1b)
432        __(bx lr)
433
434_spentry(makes32)
435        __(adds imm1,imm0,imm0)
436        __(addsvc arg_z,imm1,imm1)
437        __(bxvc lr)
438        __(movc16(imm1,one_digit_bignum_header))
439        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
440        __(str imm0,[arg_z,#misc_data_offset])
441        __(bx lr)
442
443/* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
444
445
446_spentry(makeu32)
447        __(tst imm0,#0xe0000000)
448        __(box_fixnum(arg_z,imm0))
449        __(bxeq lr)
450        __(tst imm0,#0x80000000)
451        __(bne 2f)
452        __(movc16(imm1,one_digit_bignum_header))
453        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
454        __(str imm0,[arg_z,#misc_data_offset])
455        __(bx lr)
4562:             
457        __(movc16(imm1,two_digit_bignum_header))
458        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
459        __(str imm0,[arg_z,#misc_data_offset])
460        __(bx lr)
461
462
463/* arg_z has overflowed (by one bit) as the result of an addition or
464   subtraction. */
465/* Make a bignum out of it. */
466
467_spentry(fix_overflow)
468        __(unbox_fixnum(imm0,arg_z))
469        __(eor imm0,imm0,#0xc0000000)
470        __(b _SPmakes32)
471
472
473
474/*  Construct a lisp integer out of the 64-bit unsigned value in */
475/*           imm0 (low 32 bits) and imm1 (high 32 bits) */
476       
477_spentry(makeu64)
478        __(cmp imm1,#0)
479        __(beq _SPmakeu32)
480        __(blt 3f)
481        __(movc16(imm2,two_digit_bignum_header))
482        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
483        __(str imm0,[arg_z,#misc_data_offset])
484        __(str imm1,[arg_z,#misc_data_offset+4])
485        __(bx lr)
4863:             
487        __(movc16(imm2,three_digit_bignum_header))
488        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
489        __(str imm0,[arg_z,#misc_data_offset])
490        __(str imm1,[arg_z,#misc_data_offset+4])
491        __(bx lr)
492
493/*  Construct a lisp integer out of the 64-bit signed value in */
494/*        imm0 (low 32 bits) and imm1 (high 32 bits). */
495_spentry(makes64)
496        __(cmp imm1,imm0,asr #31) /* is imm1 sign extension of imm0 ? */
497        __(beq _SPmakes32)        /* forget imm1 if so */
498        __(movc16(imm2,two_digit_bignum_header))
499        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
500        __(str imm0,[arg_z,#misc_data_offset])
501        __(str imm1,[arg_z,#misc_data_offset+4])
502        __(bx lr)
503
504
505
506
507
508
509/* funcall nfn, returning multiple values if it does.  */
510_spentry(mvpass)
511        __(cmp nargs,#node_size*nargregs)
512        __(mov imm1,vsp)
513        __(subgt imm1,imm1,#node_size*nargregs)
514        __(addgt imm1,imm1,nargs)
515        __(build_lisp_frame(imm0,imm1))
516        __(adr lr,C(ret1valn))
517        __(mov fn,#0)
518        __(funcall_nfn())
519
520/* ret1valn returns "1 multiple value" when a called function does not  */
521/* return multiple values.  Its presence on the stack (as a return address)  */
522/* identifies the stack frame to code which returns multiple values.  */
523
524_exportfn(C(ret1valn))
525        __(restore_lisp_frame(imm0))
526        __(vpush1(arg_z))
527        __(set_nargs(1))
528        __(bx lr)
529
530/* Come here to return multiple values when  */
531/* the caller's context isn't saved in a lisp_frame.  */
532/* lr, fn valid; temp0 = entry vsp  */
533
534_spentry(values)
535local_label(return_values): 
536        __(ref_global(imm0,ret1val_addr))
537        __(mov arg_z,#nil_value)
538        __(cmp imm0,lr)
539        __(beq 3f)
540        __(cmp nargs,#fixnum_one)
541        __(add imm0,nargs,vsp)
542        __(ldrge arg_z,[imm0,#-node_size])
543        __(mov vsp,temp0)
544        __(bx lr)
545
546
547/* Return multiple values to real caller.  */
5483:
549        __(ldr lr,[sp,#lisp_frame.savelr])
550        __(add imm1,nargs,vsp)
551        __(ldr imm0,[sp,#lisp_frame.savevsp])
552        __(ldr fn,[sp,#lisp_frame.savefn])
553        __(cmp imm1,imm0) /* a fairly common case  */
554        __(discard_lisp_frame())
555        __(bxeq lr) /* already in the right place  */
556        __(cmp nargs,#fixnum_one) /* sadly, a very common case  */
557        __(bne 4f)
558        __(ldr arg_z,[vsp,#0])
559        __(mov vsp,imm0)
560        __(vpush1(arg_z))
561        __(bx lr)
5624:
563        __(blt 6f)
564        __(mov temp1,#fixnum_one)
5655:
566        __(cmp temp1,nargs)
567        __(add temp1,temp1,#fixnum_one)
568        __(ldr arg_z,[imm1,#-node_size]!)
569        __(push1(arg_z,imm0))
570        __(bne 5b)
5716:
572        __(mov vsp,imm0)
573        __(bx lr)
574
575
576/* Come here with saved context on top of stack.  */
577_spentry(nvalret)
578        .globl C(nvalret)
579C(nvalret): 
580        __(ldr lr,[sp,#lisp_frame.savelr])
581        __(ldr temp0,[sp,#lisp_frame.savevsp])
582        __(ldr fn,[sp,#lisp_frame.savefn])
583        __(discard_lisp_frame())
584        __(b local_label(return_values))                         
585
586/* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
587/* Otherwise, process unwind-protects and throw to indicated catch frame.  */
588
589               
590 _spentry(throw)
591        __(ldr temp0,[rcontext, #tcr.catch_top])
592        __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
593        __(cmp temp0,#0)
594        __(ldr temp2,[vsp,nargs])
595        __(beq local_label(_throw_tag_not_found))
596local_label(_throw_loop):
597        __(ldr temp1,[temp0,#catch_frame.catch_tag])
598        __(cmp temp2,temp1)
599        __(ldrne temp0,[temp0,#catch_frame.link])
600        __(beq C(_throw_found))
601        __(cmp temp0,#0)
602        __(add imm0,imm0,#fixnum_one)
603        __(bne local_label(_throw_loop))
604local_label(_throw_tag_not_found):
605        __(uuo_error_no_throw_tag(al,temp2))
606        __(str temp2,[vsp,nargs])
607        __(b _SPthrow)
608
609/* This takes N multiple values atop the vstack.  */
610_spentry(nthrowvalues)
611        __(mov imm1,#1)
612        __(mov temp2,imm0)
613        __(str imm1,[rcontext,#tcr.unwinding])
614        __(b C(nthrownv))
615
616/* This is a (slight) optimization.  When running an unwind-protect, */
617/* save the single value and the throw count in the tstack frame. */
618/* Note that this takes a single value in arg_z.  */
619_spentry(nthrow1value)
620        __(mov imm1,#1)
621        __(mov temp2,imm0)
622        __(str imm1,[rcontext,#tcr.unwinding])
623        __(b C(nthrow1v))
624
625
626/* arg_z = symbol: bind it to its current value          */
627 _spentry(bind_self)
628        __(ldr imm1,[arg_z,#symbol.binding_index])
629        __(ldr imm0,[rcontext,#tcr.tlb_limit])
630        __(cmp imm1,#0)
631        __(beq 9f)
632        __(cmp imm0,imm1)
633        __(uuo_tlb_too_small(ls,imm1))
634        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
635        __(ldr imm0,[rcontext,#tcr.db_link])
636        __(ldr temp1,[temp2,imm1])
637        __(cmp temp1,#no_thread_local_binding_marker)
638        __(movne temp0,temp1)
639        __(ldreq temp0,[arg_z,#symbol.vcell])
640        __(vpush1(temp1))   /* old tlb contents */
641        __(vpush1(imm1))    /* tlb index */
642        __(vpush1(imm0))
643        __(str temp0,[temp2,imm1])
644        __(str vsp,[rcontext,#tcr.db_link])
645        __(bx lr)
6469:      __(mov arg_y,#XSYMNOBIND)
647        __(set_nargs(2))
648        __(b _SPksignalerr)
649
650/* Bind symbol in arg_z to NIL                 */
651_spentry(bind_nil)
652        __(mov arg_y,arg_z)
653        __(mov arg_z,#nil_value)
654        __(b _SPbind)
655
656/* Bind symbol in arg_z to its current value;  trap if symbol is unbound */
657_spentry(bind_self_boundp_check)
658        __(ldr imm1,[arg_z,#symbol.binding_index])
659        __(ldr imm0,[rcontext,#tcr.tlb_limit])
660        __(cmp imm1,#0)
661        __(beq 9f)
662        __(cmp imm0,imm1)
663        __(uuo_tlb_too_small(ls,imm1))
664        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
665        __(ldr imm0,[rcontext,#tcr.db_link])
666        __(ldr temp1,[temp2,imm1])
667        __(cmp temp1,#no_thread_local_binding_marker)
668        __(movne temp0,temp1)
669        __(ldreq temp0,[arg_z,#symbol.vcell])
670        __(cmp temp0,#unbound_marker)
671        __(uuo_error_unbound(eq,arg_z))
672        __(vpush1(temp1))   /* old tlb contents */
673        __(vpush1(imm1))    /* tlb index */
674        __(vpush1(imm0))
675        __(str temp0,[temp2,imm1])
676        __(str vsp,[rcontext,#tcr.db_link])
677        __(bx lr)
6789:      __(mov arg_y,#XSYMNOBIND)
679        __(set_nargs(2))
680        __(b _SPksignalerr)
681
682 
683/* The function pc_luser_xp() - which is used to ensure that suspended threads */
684/* are suspended in a GC-safe way - has to treat these subprims (which  */
685/* implement the EGC write-barrier) specially.  Specifically, a store that */
686/* might introduce an intergenerational reference (a young pointer stored  */
687/* in an old object) has to "memoize" that reference by setting a bit in  */
688/* the global "refbits" bitmap. */
689/* This has to happen atomically, and has to happen atomically wrt GC. */
690/* Note that updating a word in a bitmap is itself not atomic, unless we use */
691/* interlocked loads and stores. */
692
693
694/* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
695/* are in the function, we can do the store (even if it's already been done)  */
696/* and calculate whether or not we need to set the bit out-of-line.  (Actually */
697/* setting the bit needs to be done atomically, unless we're sure that other */
698/* threads are suspended.) */
699/* We can unconditionally set the suspended thread's PC to its LR. */
700
701        .globl C(egc_write_barrier_start)
702_spentry(rplaca)
703C(egc_write_barrier_start):     
704        __(cmp arg_z,arg_y)
705        __(_rplaca(arg_y,arg_z))
706        __(bxlo lr)
707        __(ref_global(temp0,ref_base))
708        __(sub imm0,arg_y,temp0)
709        __(mov imm0,imm0,lsr #dnode_shift)
710        __(ref_global(imm1,oldspace_dnode_count))
711        __(cmp imm0,imm1)
712        __(bxhs lr)
713        __(and imm2,imm0,#31)
714        __(mov imm1,#0x80000000)
715        __(mov imm1,imm1,lsr imm2)
716        __(mov imm0,imm0,lsr #bitmap_shift)
717        __(ref_global(temp0,refbits))
718        __(add temp0,temp0,imm0,lsl #word_shift)
7190:      __(ldrex imm2,[temp0])
720        __(orr imm2,imm2,imm1)
721        __(strex imm0,imm2,[temp0])
722        __(cmp imm0,#0)
723        __(bne 0b)       
724        __(bx lr)
725
726
727        .globl C(egc_rplacd)
728_spentry(rplacd)
729C(egc_rplacd):
730        __(cmp arg_z,arg_y)
731        __(_rplacd(arg_y,arg_z))
732        __(bxlo lr)
733        __(ref_global(temp0,ref_base))
734        __(sub imm0,arg_y,temp0)
735        __(mov imm0,imm0,lsr #dnode_shift)
736        __(ref_global(imm1,oldspace_dnode_count))
737        __(cmp imm0,imm1)
738        __(bxhs lr)
739        __(and imm2,imm0,#31)
740        __(mov imm1,#0x80000000)
741        __(mov imm1,imm1,lsr imm2)
742        __(mov imm0,imm0,lsr #bitmap_shift)
743        __(ref_global(temp0,refbits))
744        __(add temp0,temp0,imm0,lsl #word_shift)
7450:      __(ldrex imm2,[temp0])
746        __(orr imm2,imm2,imm1)
747        __(strex imm0,imm2,[temp0])
748        __(cmp imm0,#0)
749        __(bne 0b)       
750        __(bx lr)
751       
752
753/* Storing into a gvector can be handled the same way as storing into a CONS. */
754
755        .globl C(egc_gvset)
756_spentry(gvset)
757C(egc_gvset):
758        __(cmp arg_z,arg_x)
759        __(add imm0,arg_y,#misc_data_offset)
760        __(str arg_z,[arg_x,imm0])
761        __(bxlo lr)               
762        __(add imm0,imm0,arg_x)
763        __(ref_global(temp0,ref_base))
764        __(sub imm0,imm0,temp0)
765        __(mov imm0,imm0,lsr #dnode_shift)
766        __(ref_global(imm1,oldspace_dnode_count))
767        __(cmp imm0,imm1)
768        __(bxhs lr)
769        __(and imm2,imm0,#31)
770        __(mov imm1,#0x80000000)
771        __(mov imm1,imm1,lsr imm2)
772        __(mov imm0,imm0,lsr #bitmap_shift)
773        __(ref_global(temp0,refbits))
774        __(add temp0,temp0,imm0,lsl #word_shift)
7750:      __(ldrex imm2,[temp0])
776        __(orr imm2,imm2,imm1)
777        __(strex imm0,imm2,[temp0])
778        __(cmp imm0,#0)
779        __(bne 0b)       
780        __(bx lr)
781
782       
783/* This is a special case of storing into a gvector: if we need to memoize  */
784/* the store, record the address of the hash-table vector in the refmap,  */
785/* as well. */
786        .globl C(egc_set_hash_key)       
787_spentry(set_hash_key)
788C(egc_set_hash_key):
789        __(cmp arg_z,arg_x)
790        __(add imm0,arg_y,#misc_data_offset)
791        __(str arg_z,[arg_x,imm0])
792        __(bxlo lr)
793        __(add imm0,imm0,arg_x)
794        __(ref_global(temp0,ref_base))
795        __(sub imm0,imm0,temp0)
796        __(mov imm0,imm0,lsr #dnode_shift)
797        __(ref_global(imm1,oldspace_dnode_count))
798        __(cmp imm0,imm1)
799        __(bxhs lr)
800        __(and imm2,imm0,#31)
801        __(mov imm1,#0x80000000)
802        __(mov imm1,imm1,lsr imm2)
803        __(mov imm0,imm0,lsr #bitmap_shift)
804        __(ref_global(temp0,refbits))
805        __(add temp0,temp0,imm0,lsl #word_shift)
8060:      __(ldrex imm2,[temp0])
807        __(orr imm2,imm2,imm1)
808        __(strex imm0,imm2,[temp0])
809        __(cmp imm0,#0)
810        __(bne 0b)       
811/* Now need to ensure that the hash table itself is in the refmap; we
812   know that it's in bounds, etc. */
813        __(ref_global(temp0,ref_base))
814        __(sub imm0,arg_x,temp0)
815        __(mov imm0,imm0,lsr #dnode_shift)
816        __(and imm2,imm0,#31)
817        __(mov imm1,#0x80000000)
818        __(mov imm1,imm1,lsr imm2)
819        __(mov imm0,imm0,lsr #bitmap_shift)
820        __(ref_global(temp0,refbits))
821        __(add temp0,temp0,imm0,lsl #word_shift)
8221:      __(ldrex imm2,[temp0])
823        __(orr imm2,imm2,imm1)
824        __(strex imm0,imm2,[temp0])
825        __(cmp imm0,#0)
826        __(bne 1b)       
827        __(bx lr)
828       
829
830/*
831   Interrupt handling (in pc_luser_xp()) notes: 
832   If we are in this function and before the test which follows the
833   conditional (at egc_store_node_conditional), or at that test
834   and cr0`eq' is clear, pc_luser_xp() should just let this continue
835   (we either haven't done the store conditional yet, or got a
836   possibly transient failure.)  If we're at that test and the
837   cr0`EQ' bit is set, then the conditional store succeeded and
838   we have to atomically memoize the possible intergenerational
839   reference.  Note that the local labels 4 and 5 are in the
840   body of the next subprim (and at or beyond 'egc_write_barrier_end').
841
842   N.B: it's not possible to really understand what's going on just
843   by the state of the cr0`eq' bit.  A transient failure in the
844   conditional stores that handle memoization might clear cr0`eq'
845   without having completed the memoization.
846*/
847
848            .globl C(egc_store_node_conditional)
849            .globl C(egc_write_barrier_end)
850_spentry(store_node_conditional)
851C(egc_store_node_conditional):
852        __(vpop1(temp0))
853         
8541:      __(unbox_fixnum(imm2,temp0))
855        __(add imm2,imm2,arg_x)
856        __(ldrex temp1,[imm2])
857        __(cmp temp1,arg_y)
858        __(bne 5f)
859        __(strex imm0,arg_z,[imm2])
860        .globl C(egc_store_node_conditional_test)
861C(egc_store_node_conditional_test): 
862        __(cmp imm0,#0)
863        __(bne 1b)
864        __(cmp arg_z,arg_x)
865        __(blo 4f)
866
867        __(ref_global(imm0,ref_base))
868        __(ref_global(imm1,oldspace_dnode_count))
869        __(sub imm0,imm2,imm0)
870        __(mov imm0,imm0,lsr #dnode_shift)
871        __(cmp imm0,imm1)
872        __(bhs 4f)
873        __(and imm1,imm0,#31)
874        __(mov arg_x,#0x80000000)
875        __(mov imm1,arg_x,lsr imm1)
876        __(ref_global(temp0,refbits))
877        __(mov imm0,imm0,lsr #bitmap_shift)
878        __(add temp0,temp0,imm0,lsl #word_shift)
8792:      __(ldrex imm2,[temp0])
880        __(orr imm2,imm2,imm1)
881        __(strex imm0,imm2,[temp0])
882        .globl C(egc_set_hash_key_conditional_test)
883C(egc_set_hash_key_conditional_test): 
884        __(cmp imm0,#0)
885        __(bne 2b)
886        __(b 4f)
887 
888/* arg_z = new value, arg_y = expected old value, arg_x = hash-vector,
889    vsp`0' = (boxed) byte-offset
890    Interrupt-related issues are as in store_node_conditional, but
891    we have to do more work to actually do the memoization.*/
892_spentry(set_hash_key_conditional)
893        .globl C(egc_set_hash_key_conditional)
894C(egc_set_hash_key_conditional):
895        __(vpop1(imm1))
896        __(unbox_fixnum(imm1,imm1))
8970:      __(add imm2,arg_x,imm1)
898        __(ldrex temp1,[imm2])
899        __(cmp temp1,arg_y)
900        __(bne 5f)
901        __(strex imm0,arg_z,[imm2])
902        __(bne 0b)
903        __(cmp arg_z,arg_x)
904        __(blo 4f)
905        __(ref_global(temp0,ref_base))
906        __(sub imm0,imm2,temp0)
907        __(mov imm0,imm0,lsr #dnode_shift)
908        __(ref_global(imm1,oldspace_dnode_count))
909        __(cmp imm0,imm1)
910        __(bhs 4f)
911        __(and imm2,imm0,#31)
912        __(mov imm1,#0x80000000)
913        __(mov imm1,imm1,lsr imm2)
914        __(mov imm0,imm0,lsr #bitmap_shift)
915        __(ref_global(temp0,refbits))
916        __(add temp0,temp0,imm0,lsl #word_shift)
9171:      __(ldrex imm2,[temp0])
918        __(orr imm2,imm2,imm1)
919        __(strex imm0,imm2,[temp0])
920        __(cmp imm0,#0)
921        __(bne 1b)       
922/* Now need to ensure that the hash table itself is in the refmap; we
923   know that it's in bounds, etc. */
924        __(ref_global(temp0,ref_base))
925        __(sub imm0,arg_x,temp0)
926        __(mov imm0,imm0,lsr #dnode_shift)
927        __(and imm2,imm0,#31)
928        __(mov imm1,#0x80000000)
929        __(mov imm1,imm1,lsr imm2)
930        __(mov imm0,imm0,lsr #bitmap_shift)
931        __(ref_global(temp0,refbits))
932        __(add temp0,temp0,imm0,lsl #word_shift)
9331:      __(ldrex imm2,[temp0])
934        __(orr imm2,imm2,imm1)
935        __(strex imm0,imm2,[temp0])
936        __(cmp imm0,#0)
937        __(bne 1b)       
938C(egc_write_barrier_end):
9394:      __(mov arg_z,#nil_value)
940        __(add arg_z,arg_z,#t_offset)
941        __(bx lr)
9425:      __(clrex)
943        __(mov arg_z,#nil_value)
944        __(bx lr)
945
946
947
948
949       
950/* We always have to create a stack frame (even if nargs is 0), so the compiler  */
951/* doesn't get confused.  */
952_spentry(stkconslist)
953        __(mov arg_z,#nil_value)
954C(stkconslist_star):           
955        __(mov temp2,nargs,lsl #1)
956        __(add temp2,temp2,#node_size)
957        __(mov imm0,temp2,lsl #num_subtag_bits-word_shift)
958        __(add temp2,temp2,#node_size)
959        __(orr imm0,imm0,#subtag_u32_vector)
960        __(stack_allocate_zeroed_ivector(imm0,temp2))
961        __(mov imm0,#subtag_simple_vector)
962        __(strb imm0,[sp,#0])
963        __(add imm1,sp,#dnode_size+fulltag_cons)
964        __(cmp nargs,#0)
965        __(b 4f)
9661:      __(vpop1(temp0))
967        __(_rplaca(imm1,temp0))
968        __(_rplacd(imm1,arg_z))
969        __(mov arg_z,imm1)
970        __(add imm1,imm1,#cons.size)
971        __(subs nargs,nargs,#node_size)
9724:
973        __(bne 1b)
974        __(bx lr)
975 
976/* do list*: last arg in arg_z, all others vpushed,  */
977/* nargs set to #args vpushed.  */
978_spentry(stkconslist_star)
979        __(b C(stkconslist_star))
980
981/* Make a stack-consed simple-vector out of the NARGS objects  */
982/* on top of the vstack; return it in arg_z.  */
983_spentry(mkstackv)
984        __(dnode_align(imm1,nargs,node_size))
985        __(mov imm0,nargs,lsl #num_subtag_bits-fixnumshift)
986        __(orr imm0,imm0,#subtag_u32_vector)
987        __(stack_allocate_zeroed_ivector(imm0,imm1))
988        __(mov imm0,#subtag_simple_vector)
989        __(strb imm0,[sp,#0])
990        __(add arg_z,sp,#fulltag_misc)
991        __(add imm0,arg_z,#misc_data_offset)
992        __(add imm1,imm0,nargs)
993        __(b 4f)
9943:      __(vpop1(arg_y))
995        __(str arg_y,[imm1,#-node_size]!)
996        __(sub nargs,nargs,#node_size)
9974:      __(cmp nargs,#0)
998        __(bne 3b)
999        __(bx lr)
1000       
1001_spentry(setqsym)
1002        __(ldr imm0,[arg_y,#symbol.flags])
1003        __(tst imm0,#sym_vbit_const_mask)
1004        __(beq _SPspecset)
1005        __(mov arg_z,arg_y)
1006        __(mov arg_y,#XCONST)
1007        __(set_nargs(2))
1008        __(b _SPksignalerr)
1009
1010
1011
1012_spentry(progvsave)
1013        __(b (C(progvsave)))
1014 
1015       
1016/* Allocate a uvector on the  stack.  (Push a frame on the stack and  */
1017/* heap-cons the object if there's no room on the stack.)  */
1018_spentry(stack_misc_alloc)
1019        __(tst arg_y,#unsigned_byte_24_mask)
1020        __(uuo_error_reg_not_xtype(ne,arg_y,xtype_unsigned_byte_24))
1021        __(unbox_fixnum(imm0,arg_z))
1022        __(extract_fulltag(imm1,imm0))
1023        __(cmp imm1,#fulltag_nodeheader)
1024        __(bne 1f)
1025        __(dnode_align(imm1,arg_y,node_size))
1026        __(cmp imm1,#stack_alloc_limit)
1027        __(bhs stack_misc_alloc_no_room)
1028        __(mov imm0,#subtag_u32_vector)
1029        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1030        __(mov temp0,#stack_alloc_marker)
1031        __(mov temp1,sp)
1032        __(stack_allocate_zeroed_ivector(imm0,imm1))
1033        __(unbox_fixnum(imm0,arg_z))
1034        __(strb imm0,[sp])
1035        __(add arg_z,sp,#fulltag_misc)
1036        __(stmdb sp!,{temp0,temp1})
1037        __(bx lr)
10381:      __(mov imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1039        __(orr imm0,imm0,arg_z,lsr #fixnumshift)
1040        __(cmp arg_z,#max_32_bit_ivector_subtag<<fixnumshift)
1041        __(movle imm1,arg_y)
1042        __(ble 8f)
1043        __(cmp arg_z,#max_8_bit_ivector_subtag<<fixnumshift)
1044        __(movle imm1,arg_y,lsr #fixnumshift)
1045        __(ble 8f)
1046        __(cmp arg_z,#max_16_bit_ivector_subtag<<fixnumshift)
1047        __(movle imm1,arg_y,lsr #1)
1048        __(ble 8f)
1049        __(cmp arg_z,#subtag_double_float)
1050        __(moveq imm1,arg_y,lsl #1)
1051        __(addeq imm1,imm1,#node_size)
1052        __(addne imm1,arg_y,#7<<fixnumshift)
1053        __(movne imm1,imm1,lsr#3+fixnumshift)
10548:      __(dnode_align(imm1,imm1,node_size))
1055        __(cmp imm1,#stack_alloc_limit)
1056        __(bhs stack_misc_alloc_no_room)
1057        __(mov temp0,#stack_alloc_marker)
1058        __(mov temp1,sp)
1059        __(stack_allocate_zeroed_ivector(imm0,imm1))
1060        __(add arg_z,sp,#fulltag_misc)
1061        __(stmdb sp!,{temp0,temp1})
1062        __(bx lr)
1063
1064
1065
1066
1067/* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
1068/* initial-contents.  Note that this can be used to cons any type of initialized  */
1069/* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
1070/* objects.  */
1071
1072_spentry(gvector)
1073        __(sub nargs,nargs,#node_size)
1074        __(ldr arg_z,[vsp,nargs])
1075        __(unbox_fixnum(imm0,arg_z))
1076        __(orr imm0,imm0,nargs,lsl #num_subtag_bits-fixnum_shift)
1077        __(dnode_align(imm1,nargs,node_size))
1078        __(Misc_Alloc(arg_z,imm0,imm1))
1079        __(mov imm1,nargs)
1080        __(add imm2,imm1,#misc_data_offset)
1081        __(b 2f)
10821:
1083        __(str temp0,[arg_z,imm2])
10842:
1085        __(sub imm1,imm1,#node_size)
1086        __(cmp imm1,#0)
1087        __(sub imm2,imm2,#node_size)
1088        __(vpop1(temp0))        /* Note the intentional fencepost: */
1089                                /* discard the subtype as well.  */
1090        __(bge 1b)
1091        __(bx lr)
1092
1093_spentry(fitvals)
1094        __(subs imm0,imm0,nargs)
1095        __(mov imm1,#nil_value)
1096        __(sublt vsp,vsp,imm0)
1097        __(bxlt lr)
1098        __(b 2f)
10991:
1100        __(subs imm0,imm0,#node_size)
1101        __(vpush1(imm1))       
1102        __(add nargs,nargs,#node_size)
11032:
1104        __(bne 1b)
1105        __(bx lr)
1106
1107
1108_spentry(nthvalue)
1109        __(add imm0,vsp,nargs)
1110        __(ldr imm1,[imm0,#0])
1111        __(cmp imm1,nargs) /*  do unsigned compare:  if (n < 0) => nil.  */
1112        __(mov arg_z,#nil_value)
1113        __(rsb imm1,imm1,#0)
1114        __(sub imm1,imm1,#node_size)
1115        __(ldrlo arg_z,[imm0,imm1])
1116        __(add vsp,imm0,#node_size)
1117        __(bx lr)
1118
1119/* Provide default (NIL) values for &optional arguments; imm0 is  */
1120/* the (fixnum) upper limit on the total of required and &optional  */
1121/* arguments.  nargs is preserved, all arguments wind up on the  */
1122/* vstack.  */
1123_spentry(default_optional_args)
1124        __(vpush_argregs())
1125        __(cmp nargs,imm0)
1126        __(mov arg_z,#nil_value)
1127        __(mov imm1,nargs)
1128        __(bxhs lr)
11291:
1130        __(add imm1,imm1,#fixnum_one)
1131        __(cmp imm1,imm0)
1132        __(vpush1(arg_z))
1133        __(bne 1b)
1134        __(bx lr)
1135
1136/* Indicate whether &optional arguments were actually supplied.  nargs  */
1137/* contains the actual arg count (minus the number of required args);  */
1138/* imm0 contains the number of &optional args in the lambda list.  */
1139/* Note that nargs may be > imm0 if &rest/&key is involved.  */
1140_spentry(opt_supplied_p)
1141        __(mov imm1,#0)
1142        __(mov arg_x,#nil_value)
1143        __(add arg_x,arg_x,#t_offset)       
11441:     
1145        /* (vpush (< imm1 nargs))  */
1146        __(cmp imm1,nargs)
1147        __(add imm1,imm1,#fixnumone)
1148        __(subeq arg_x,arg_x,#t_offset)
1149        __(vpush1(arg_x))
1150        __(cmp imm1,imm0)
1151        __(bne 1b)
1152        __(bx lr)
1153
1154/* Cons a list of length nargs  and vpush it.  */
1155/* Use this entry point to heap-cons a simple &rest arg.  */
1156_spentry(heap_rest_arg)
1157        __(vpush_argregs())
1158        __(movs imm1,nargs)
1159        __(mov arg_z,#nil_value)
1160        __(b 2f)
11611:
1162        __(vpop1(arg_y))
1163        __(Cons(arg_z,arg_y,arg_z))
1164        __(subs imm1,imm1,#fixnum_one)
11652:
1166        __(bne 1b)
1167        __(vpush1(arg_z))
1168        __(bx lr)
1169
1170 
1171/* And this entry point when the argument registers haven't yet been  */
1172/* vpushed (as is typically the case when required/&rest but no  */
1173/* &optional/&key.)  */
1174_spentry(req_heap_rest_arg)
1175        __(vpush_argregs())
1176        __(subs imm1,nargs,imm0)
1177        __(mov arg_z,#nil_value)
1178        __(b 2f)
11791:
1180        __(vpop1(arg_y))
1181        __(Cons(arg_z,arg_y,arg_z))
1182        __(subs imm1,imm1,#fixnum_one)
11832:
1184        __(bgt 1b)
1185        __(vpush1(arg_z))
1186        __(bx lr)
1187
1188/* Here where argregs already pushed */
1189_spentry(heap_cons_rest_arg)
1190        __(subs imm1,nargs,imm0)
1191        __(mov arg_z,#nil_value)
1192        __(b 2f)
11931:
1194        __(vpop1(arg_y))
1195        __(Cons(arg_z,arg_y,arg_z))
1196        __(subs imm1,imm1,#fixnum_one)
11972:
1198        __(bgt 1b)
1199        __(vpush1(arg_z))
1200        __(bx lr)
1201
1202
1203_spentry(check_fpu_exception)
1204
1205_spentry(discard_stack_object)
1206        new_local_labels()       
1207        __(ldr imm0,[sp,#0])
1208        __(cmp imm0,#stack_alloc_marker)
1209        __(ldreq sp,[sp,#node_size])
1210        __(bxeq lr)
1211        __(cmp imm0,#lisp_frame_marker)
1212        __(extract_fulltag(imm1,imm0))
1213        __(addeq sp,sp,#lisp_frame.size)
1214        __(bxeq lr)
1215        __(cmp imm1,#fulltag_immheader)
1216        __(and imm1,imm0,#subtag_mask)
1217        __(bic imm0,imm0,#subtag_mask)
1218        __(beq local_label(ivector))
1219local_label(word):
1220        __(mov imm0,imm0,lsr #num_subtag_bits-word_shift)
1221local_label(out):       
1222        __(dnode_align(imm0,imm0,node_size))
1223        __(add sp,sp,imm0)
1224        __(bx lr)
1225local_label(ivector):     
1226        __(cmp imm1,#max_32_bit_ivector_subtag)
1227        __(bls local_label(word))       
1228        __(cmp imm1,#max_8_bit_ivector_subtag)
1229        __(movls imm0,imm0,lsr #num_subtag_bits)
1230        __(bls local_label(out))
1231        __(cmp imm1,#max_16_bit_ivector_subtag)
1232        __(movls imm0,imm0,lsr #num_subtag_bits-1)
1233        __(bls local_label(out))
1234        __(cmp imm1,#subtag_bit_vector)
1235        __(moveq imm0,imm0,lsr #num_subtag_bits)
1236        __(addeq imm0,imm0,#7)
1237        __(moveq imm0,imm0,lsr #3)
1238        __(beq local_label(out))
1239        /* The infamous 'stack-consed double-float vector' case */
1240        __(mov imm0,imm0,lsr #num_subtag_bits-dnode_shift)
1241        __(b local_label(out))
1242
1243
1244       
1245/* Signal an error synchronously, via %ERR-DISP.  */
1246/* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
1247/* on the C runtime stderr.  */
1248 
1249_spentry(ksignalerr)
1250        __(ref_nrs_symbol(fname,errdisp,imm0))
1251        __(jump_fname)
1252
1253/* As in the heap-consed cases, only stack-cons the &rest arg  */
1254_spentry(stack_rest_arg)
1255        __(mov imm0,#0)
1256        __(vpush_argregs())
1257        __(b _SPstack_cons_rest_arg)
1258
1259_spentry(req_stack_rest_arg)
1260        __(vpush_argregs())
1261        __(b _SPstack_cons_rest_arg)
1262
1263_spentry(stack_cons_rest_arg)
1264        __(subs imm1,nargs,imm0)
1265        __(mov arg_z,#nil_value)
1266        __(ble 2f)  /* always temp-push something.  */
1267        __(mov temp0,imm1)
1268        __(add imm1,imm1,imm1)
1269        __(add imm1,imm1,#node_size)
1270        __(dnode_align(imm0,imm1,node_size))
1271        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
1272        __(orr imm1,imm1,#subtag_u32_vector)
1273        __(cmp imm0,#stack_alloc_limit)
1274        __(bge 3f)
1275        __(stack_allocate_zeroed_ivector(imm1,imm0))
1276        __(mov imm0,#subtag_simple_vector)
1277        __(strb imm0,[sp])
1278        __(add imm0,sp,#dnode_size+fulltag_cons)
12791:
1280        __(subs temp0,temp0,#fixnumone)
1281        __(vpop1(arg_x))
1282        __(_rplacd(imm0,arg_z))
1283        __(_rplaca(imm0,arg_x))
1284        __(mov arg_z,imm0)
1285        __(add imm0,imm0,#cons.size)
1286        __(bne 1b)
1287        __(vpush1(arg_z))
1288        __(bx lr)
12892:
1290        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1291        __(mov imm1,#0)
1292        __(stmdb sp!,{imm0,imm1})
1293        __(vpush1(arg_z))
1294        __(bx lr)
12953:
1296        __(mov arg_z,#stack_alloc_marker)
1297        __(mov arg_y,sp)
1298        __(stmdb sp!,{arg_z,arg_y})
1299        __(b _SPheap_cons_rest_arg)
1300
1301       
1302/* Prepend all but the first three (entrypoint, closure code, fn) and last two  */
1303/* (function name, lfbits) elements of nfn to the "arglist".  */
1304/* functions which take "inherited arguments" work consistently  */
1305/* even in cases where no closure object is created.  */
1306_spentry(call_closure)       
1307        __(cmp nargs,nargregs<<fixnumshift)
1308        __(vector_length(imm0,nfn,imm0))
1309        __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count  */
1310        __(ble local_label(no_insert))
1311        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
1312        /* of NILs, copy those arguments that have already been vpushed from  */
1313        /* the old TOS to the new, then insert all of the inerited args  */
1314        /* and go to the function.  */
1315        __(vpush_all_argregs())
1316        __(mov arg_x,imm0)
1317        __(mov arg_y,#nil_value)
1318local_label(push_nil_loop):
1319        __(subs arg_x,arg_x,#fixnumone)
1320        __(vpush1(arg_y))
1321        __(bne local_label(push_nil_loop))
1322        __(add arg_y,vsp,imm0)
1323        __(mov imm1,#0)
1324local_label(copy_already_loop):
1325        __(ldr arg_x,[vsp,imm1])
1326        __(str arg_x,[arg_y,imm1])
1327        __(add imm1,imm1,#fixnumone)
1328        __(cmp imm1,imm0)
1329        __(bne local_label(copy_already_loop))
1330        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1331        __(add arg_y,vsp,nargs)
1332        __(add arg_y,arg_y,imm0)
1333local_label(insert_loop):
1334        __(subs imm0,imm0,#fixnumone)
1335        __(ldr fname,[nfn,imm1])
1336        __(add imm1,imm1,#fixnumone)
1337        __(add nargs,nargs,#fixnumone)
1338        __(push1(fname,arg_y))
1339        __(bne local_label(insert_loop))
1340        __(vpop_all_argregs())
1341        __(b local_label(go))
1342local_label(no_insert):
1343/* nargregs or fewer args were already vpushed.  */
1344/* if exactly nargregs, vpush remaining inherited vars.  */
1345        __(cmp nargs,#nargregs<<fixnumshift)
1346        __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift))
1347        __(bne local_label(set_regs))
1348local_label(vpush_remaining):
1349        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1350local_label(vpush_remaining_loop):             
1351        __(ldr fname,[nfn,imm1])
1352        __(add imm1,imm1,#fixnum_one)
1353        __(vpush1(fname))
1354        __(subs imm0,imm0,#fixnum_one)
1355        __(add nargs,nargs,#fixnum_one)
1356        __(bne  local_label(vpush_remaining_loop))
1357        __(b local_label(go))
1358local_label(set_regs):
1359        /* if nargs was > 1 (and we know that it was < 3), it must have  */
1360        /* been 2.  Set arg_x, then vpush the remaining args.  */
1361        __(cmp nargs,#fixnumone)
1362        __(ble local_label(set_y_z))
1363local_label(set_arg_x):
1364        __(subs imm0,imm0,#fixnum_one)
1365        __(sub imm1,imm1,#fixnum_one)
1366        __(ldr arg_x,[nfn,imm1])
1367        __(add nargs,nargs,#fixnum_one)
1368        __(bne local_label(vpush_remaining))
1369        __(b local_label(go))
1370        /* Maybe set arg_y or arg_z, preceding args  */
1371local_label(set_y_z):
1372        __(cmp nargs,#fixnumone)
1373        __(bne local_label(set_arg_z))
1374        /* Set arg_y, maybe arg_x, preceding args  */
1375local_label(set_arg_y):
1376        __(subs imm0,imm0,fixnum_one)
1377        __(sub imm1,imm1,#fixnum_one)
1378        __(ldr arg_y,[nfn,imm1])
1379        __(add nargs,nargs,#fixnum_one)
1380        __(bne local_label(set_arg_x))
1381        __(b local_label(go))
1382local_label(set_arg_z):
1383        __(subs imm0,imm0,#fixnum_one)
1384        __(sub imm1,imm1,#fixnum_one)
1385        __(ldr arg_z,[nfn,imm1])
1386        __(add nargs,nargs,#fixnum_one)
1387        __(bne local_label(set_arg_y))
1388 
1389local_label(go):
1390        __(vrefr(nfn,nfn,2))
1391        __(ldr pc,[nfn,#_function.entrypoint])
1392
1393
1394/* Everything up to the last arg has been vpushed, nargs is set to  */
1395/* the (boxed) count of things already pushed.  */
1396/* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
1397/* function call (this may require vpopping a few things.)  */
1398/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1399_spentry(spreadargz)
1400        __(extract_lisptag(imm1,arg_z))
1401        __(cmp arg_z,#nil_value)
1402        __(mov imm0,#0)
1403        __(mov arg_y,arg_z)  /*  save in case of error  */
1404        __(beq 2f)
14051:
1406        __(cmp imm1,#tag_list)
1407        __(bne 3f)
1408        __(_car(arg_x,arg_z))
1409        __(_cdr(arg_z,arg_z))
1410        __(cmp arg_z,#nil_value)
1411        __(extract_lisptag(imm1,arg_z))
1412        __(vpush1(arg_x))
1413        __(add imm0,imm0,#fixnum_one)
1414        __(bne 1b)
14152:
1416        __(adds  nargs,nargs,imm0)
1417        __(bxeq lr)
1418        __(vpop_argregs_nz)
1419        __(bx lr)
1420       
1421        /*  Discard whatever's been vpushed already, complain.  */
14223: 
1423        __(add vsp,vsp,imm0)
1424        __(mov arg_z,arg_y)  /* recover original arg_z  */
1425        __(mov arg_y,#XNOSPREAD)
1426        __(set_nargs(2))
1427        __(b _SPksignalerr)
1428
1429/* Tail-recursively funcall temp0.  */
1430/* Pretty much the same as the tcallsym* cases above.  */
1431_spentry(tfuncallgen)
1432        __(cmp nargs,#nargregs<<fixnumshift)
1433        __(ldr lr,[sp,#lisp_frame.savelr])
1434        __(ldr fn,[sp,#lisp_frame.savefn])
1435        __(ble 2f)
1436        __(ldr imm0,[sp,#lisp_frame.savevsp])
1437        __(discard_lisp_frame())
1438        /* can use temp0 as a temporary  */
1439        __(sub imm1,nargs,#nargregs<<fixnumshift)
1440        __(add imm1,imm1,vsp)
14411:
1442        __(ldr temp0,[imm1,#-node_size]!)
1443        __(cmp imm1,vsp)
1444        __(push1(temp0,imm0))
1445        __(bne 1b)
1446        __(mov vsp,imm0)
1447        __(funcall_nfn())
14482:
1449        __(ldr vsp,[sp,#lisp_frame.savevsp])
1450        __(discard_lisp_frame())
1451        __(funcall_nfn())
1452
1453
1454/* Some args were vpushed.  Slide them down to the base of  */
1455/* the current frame, then do funcall.  */
1456_spentry(tfuncallslide)
1457        __(ldr fn,[sp,#lisp_frame.savefn])
1458        __(ldr imm0,[sp,#lisp_frame.savevsp])
1459        __(ldr lr,[sp,#lisp_frame.savelr])
1460        __(discard_lisp_frame())
1461        /* can use temp0 as a temporary  */
1462        __(sub imm1,nargs,#nargregs<<fixnumshift)
1463        __(add imm1,imm1,vsp)
14641:
1465        __(ldr temp0,[imm1,#-node_size]!)
1466        __(cmp imm1,vsp)
1467        __(push1(temp0,imm0))
1468        __(bne 1b)
1469        __(mov vsp,imm0)
1470        __(funcall_nfn())
1471
1472
1473_spentry(unused0)
1474
1475/* Tail-recursively call the (known symbol) in fname.  */
1476/* In the general case, we don't know if any args were  */
1477/* vpushed or not.  If so, we have to "slide" them down  */
1478/* to the base of the frame.  If not, we can just restore  */
1479/* vsp, lr, fn from the saved lisp frame on the control stack.  */
1480_spentry(tcallsymgen)
1481        __(cmp nargs,#nargregs<<fixnumshift)
1482        __(ldr lr,[sp,#lisp_frame.savelr])
1483        __(ldr fn,[sp,#lisp_frame.savefn])
1484        __(ble 2f)
1485
1486        __(ldr imm0,[sp,#lisp_frame.savevsp])
1487        __(discard_lisp_frame())
1488        /* can use nfn (= temp2) as a temporary  */
1489        __(sub imm1,nargs,#nargregs<<fixnumshift)
1490        __(add imm1,imm1,vsp)
14911:
1492        __(ldr temp2,[imm1,#-node_size]!)
1493        __(cmp imm1,vsp)
1494        __(push1(temp2,imm0))
1495        __(bne 1b)
1496        __(mov vsp,imm0)
1497        __(jump_fname)
1498 
14992: 
1500        __(ldr vsp,[sp,#lisp_frame.savevsp])
1501        __(discard_lisp_frame())
1502        __(jump_fname)
1503
1504
1505/* Some args were vpushed.  Slide them down to the base of  */
1506/* the current frame, then do funcall.  */
1507_spentry(tcallsymslide)
1508        __(ldr lr,[sp,#lisp_frame.savelr])
1509        __(ldr fn,[sp,#lisp_frame.savefn])
1510        __(ldr imm0,[sp,#lisp_frame.savevsp])
1511        __(discard_lisp_frame())
1512        /* can use nfn (= temp2) as a temporary  */
1513        __(sub imm1,nargs,#nargregs<<fixnumshift)
1514        __(add imm1,imm1,vsp)
15151:
1516        __(ldr temp2,[imm1,#-node_size]!)
1517        __(cmp imm1,vsp)
1518        __(push1(temp2,imm0))
1519        __(bne 1b)
1520        __(mov vsp,imm0)
1521        __(jump_fname)
1522
1523
1524/* Tail-recursively call the function in nfn.  */
1525/* Pretty much the same as the tcallsym* cases above.  */
1526_spentry(tcallnfngen)
1527        __(cmp nargs,#nargregs<<fixnumshift)
1528        __(bgt _SPtcallnfnslide)
1529        __(restore_lisp_frame(imm0))
1530        __(jump_nfn())
1531         
1532/* Some args were vpushed.  Slide them down to the base of  */
1533/* the current frame, then do funcall.  */
1534_spentry(tcallnfnslide)
1535        __(ldr lr,[sp,#lisp_frame.savelr])
1536        __(ldr fn,[sp,#lisp_frame.savefn])
1537        __(ldr imm0,[sp,#lisp_frame.savevsp])
1538        __(discard_lisp_frame())
1539        /* Since we have a known function, can use fname as a temporary.  */
1540        __(sub imm1,nargs,#nargregs<<fixnumshift)
1541        __(add imm1,imm1,vsp)
15421:
1543        __(ldr fname,[imm1,#-node_size]!)
1544        __(cmp imm1,vsp)
1545        __(push1(fname,imm0))
1546        __(bne 1b)
1547        __(mov vsp,imm0)
1548        __(jump_nfn())
1549
1550
1551/* Reference index arg_z of a misc-tagged object (arg_y).  */
1552/* Note that this conses in some cases.  Return a properly-tagged  */
1553/* lisp object in arg_z.  Do type and bounds-checking.  */
1554
1555_spentry(misc_ref)
1556        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1557        __(trap_unless_fixnum(arg_z))
1558        __(vector_length(imm0,arg_y,imm1))
1559        __(cmp arg_z,imm0)
1560        __(uuo_error_vector_bounds(hs,arg_z,arg_y))
1561        __(extract_lowbyte(imm1,imm1)) /* imm1 = subtag  */
1562        __(b C(misc_ref_common))
1563
1564/* like misc_ref, only the boxed subtag is in arg_x.  */
1565
1566_spentry(subtag_misc_ref)
1567        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1568        __(trap_unless_fixnum(arg_z))
1569        __(vector_length(imm0,arg_y,imm1))
1570        __(cmp arg_z,imm0)
1571        __(uuo_error_vector_bounds(hs,arg_z,arg_y))
1572        __(unbox_fixnum(imm1,arg_x))
1573        __(b C(misc_ref_common))
1574
1575
1576/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
1577/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
1578/* in arg_z on exit.  */
1579_spentry(makestackblock)
1580        __(unbox_fixnum(imm1,arg_z))
1581        __(dnode_align(imm1,imm1,0))
1582        __(add imm1,imm1,#node_size)
1583        __(add imm0,imm1,#node_size)
1584        __(cmp imm0,#stack_alloc_limit)
1585        __(mov temp0,sp)
1586        __(bhs 1f)
1587        __(mov imm1,imm1,lsl #num_subtag_bits)
1588        __(orr imm1,imm1,#subtag_u8_vector)
1589        __(stack_allocate_ivector(imm1,imm0))
1590        __(add temp1,sp,#dnode_size)
1591        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1592        __(str imm1,[sp,#-macptr.size]!)
1593        __(add arg_z,sp,#fulltag_misc)
1594        __(str temp1,[arg_z,#macptr.address])
1595        __(mov imm0,#0)
1596        __(mov imm1,#stack_alloc_marker)
1597        __(str imm0,[arg_z,#macptr.type])
1598        __(str imm0,[arg_z,#macptr.domain])
1599        __(stmdb sp!,{imm1,temp0})
1600        __(bx lr)
1601
1602        /* Too big. Heap cons a gcable macptr  */
16031:
1604        __(mov imm1,#stack_alloc_marker)
1605        __(stmdb sp!,{imm1,temp0})
1606        __(set_nargs(1))
1607        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1608        __(jump_fname())
1609
1610/* As above, only set the block's contents to 0.  */
1611_spentry(makestackblock0)
1612        __(unbox_fixnum(imm1,arg_z))
1613        __(dnode_align(imm1,imm1,0))
1614        __(add imm1,imm1,#node_size)
1615        __(add imm0,imm1,#node_size)
1616        __(cmp imm0,#stack_alloc_limit)
1617        __(mov temp0,sp)
1618        __(bhs 1f)
1619        __(mov imm1,imm1,lsl #num_subtag_bits)
1620        __(orr imm1,imm1,#subtag_u8_vector)
1621        __(stack_allocate_zeroed_ivector(imm1,imm0))
1622        __(add temp1,sp,#dnode_size)
1623        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1624        __(str imm1,[sp,#-macptr.size]!)
1625        __(add arg_z,sp,#fulltag_misc)
1626        __(str temp1,[arg_z,#macptr.address])
1627        __(mov imm0,#0)
1628        __(mov imm1,#stack_alloc_marker)
1629        __(str imm0,[arg_z,#macptr.type])
1630        __(str imm0,[arg_z,#macptr.domain])
1631        __(stmdb sp!,{imm1,temp0})
1632        __(bx lr)
1633       
1634        /* Too big. Heap cons a gcable macptr  */
16351:
1636        __(mov imm1,#stack_alloc_marker)
1637        __(stmdb sp!,{imm1,temp0})
1638        __(mov arg_y,arg_z) /* save block size  */
1639        __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr  */
1640        __(add arg_z,arg_z,#t_offset)
1641        __(set_nargs(2))
1642        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1643        __(jump_fname())
1644
1645/* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
1646/* the tstack.  Return the list in arg_z.  */
1647_spentry(makestacklist)
1648        __(add imm0,arg_y,arg_y)
1649        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1650        __(add imm1,imm1,#1<<num_subtag_bits)
1651        __(orr imm1,imm1,#subtag_u32_vector)
1652        __(add imm0,imm0,#dnode_size)
1653        __(cmp imm0,#stack_alloc_limit)
1654        __(bge 4f)
1655        __(stack_allocate_zeroed_ivector(imm1,imm0))
1656        __(mov imm0,#subtag_simple_vector)
1657        __(strb imm0,[sp,#0])
1658        __(add imm2,sp,#dnode_size+fulltag_cons)
1659        __(movs imm1,arg_y)
1660        __(mov arg_y,arg_z)
1661        __(mov arg_z,#nil_value)
1662        __(b 3f)
16632:
1664        __(_rplacd(imm2,arg_z))
1665        __(_rplaca(imm2,arg_y))
1666        __(mov arg_z,imm2)
1667        __(add imm2,imm2,#cons.size)
1668        __(subs imm1,imm1,#fixnumone)
16693:
1670        __(bne 2b)
1671        __(bx lr)
16724:
1673        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1674        __(str imm0,[sp,#-8]!)
1675        __(movs imm1,arg_y) /* count  */
1676        __(mov arg_y,arg_z) /* initial value  */
1677        __(mov arg_z,#nil_value) /* result  */
1678        __(b 6f)
16795:
1680        __(Cons(arg_z,arg_y,arg_z))
1681        __(subs imm1,imm1,#fixnumone)
16826:
1683        __(bne 5b)
1684        __(bx lr)
1685
1686/* subtype (boxed) vpushed before initial values. (Had better be a  */
1687/* node header subtag.) Nargs set to count of things vpushed.  */
1688
1689_spentry(stkgvector)
1690        __(sub imm0,nargs,#fixnumone)
1691        __(ldr temp0,[vsp,imm0])
1692        __(dnode_align(temp1,imm0,node_size))
1693        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1694        __(orr imm1,imm1,#subtag_u32_vector)
1695        __(mov temp2,sp)
1696        __(mov arg_x,#stack_alloc_marker)
1697        __(stack_allocate_zeroed_ivector(imm1,temp1))
1698        __(unbox_fixnum(imm1,temp0))
1699        __(strb imm1,[sp])
1700        __(add arg_z,sp,#fulltag_misc)
1701        __(add imm0,sp,nargs)
1702        __(stmdb sp!,{arg_x,temp2})
1703        __(b 2f)
17041:
1705        __(vpop1(temp0))
1706        __(push1(temp0,imm0))
17072:      __(subs nargs,nargs,#fixnumone)
1708        __(bne 1b)
1709        __(add vsp,vsp,#fixnumone)
1710        __(bx lr)
1711
1712/* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
1713/* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
1714/* parameters must be "reasonable" (the  subtag must be valid, the element  */
1715/* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
1716/* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
1717/* proper header on it and its contents will be 0.   imm0 contains   */
1718/* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
1719
1720_spentry(misc_alloc)
1721        __(tst arg_y,#unsigned_byte_24_mask)
1722        __(bne 9f)
1723        __(unbox_fixnum(imm0,arg_z))
1724        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1725        __(extract_fulltag(imm1,imm0))
1726        __(cmp imm1,#fulltag_nodeheader)
1727        __(mov imm2,arg_y)      /* imm2 = logical size in bytes */
1728        __(beq 1f)
1729        __(unbox_fixnum(imm1,arg_z))
1730        __(cmp imm1,#max_32_bit_ivector_subtag)
1731        __(ble 1f)
1732        __(mov imm2,arg_y,lsr #2)
1733        __(cmp imm1,#max_8_bit_ivector_subtag)
1734        __(ble 1f)
1735        __(mov imm2,arg_y,lsr #1)
1736        __(cmp imm1,#max_16_bit_ivector_subtag)
1737        __(ble 1f)
1738        __(mov imm2,arg_y,lsl #1)
1739        __(add imm2,imm2,#node_size)
1740        __(cmp imm1,#subtag_double_float_vector)
1741        __(beq 1f)
1742        __(add imm2,arg_y,#7<<fixnumshift)
1743        __(mov imm2,imm2,lsr #3+fixnumshift)
1744        /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
1745        /* low three bits.  */
17461:
1747        __(dnode_align(imm2,imm2,node_size))
1748        __(Misc_Alloc(arg_z,imm0,imm2))
1749        __(bx lr)
17509:
1751        __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
1752
1753
1754
1755/* This doesn't need to memoize anything, but needs pc-lusering support
1756   support because of the locative */
1757_spentry(atomic_incf_node)
1758        __(unbox_fixnum(imm1,arg_z))
17590:      __(add imm2,arg_y,imm1)
1760        __(ldrex arg_z,[imm2])
1761        __(add arg_z,arg_z,arg_x)
1762        __(strex imm0,arg_z,[imm2])
1763        __(cmp imm0,#0)
1764        __(bne 0b)
1765        __(bx lr)
1766       
1767_spentry(unused1)
1768
1769_spentry(unused2)
1770
1771/* vpush the values in the value set atop the stack, incrementing nargs.  */
1772
1773
1774_spentry(recover_values)
1775        __(add temp0,sp,#dnode_size)
1776        /* Find the oldest set of values by walking links from the newest */
17770:             
1778        __(ldr temp1,[temp0,#node_size+4])
1779        __(cmp temp1,#0)
1780        __(movne temp0,temp1)
1781        __(bne 0b)
17821:      __(ldr imm0,[temp0])
1783        __(header_length(imm0,imm0))
1784        __(subs imm0,imm0,#2<<fixnumshift)
1785        __(add temp1,temp0,#node_size+8)
1786        __(add temp1,temp1,imm0)
1787        __(b 3f)
17882:      __(subs imm0,imm0,#fixnumone)       
1789        __(ldr arg_z,[temp1,#-node_size]!)
1790        __(vpush1(arg_z))
1791        __(add nargs,nargs,#fixnumone)
17923:      __(bne 2b)
1793        __(ldr temp0,[temp0,#node_size+4])
1794        __(cmp temp0,#0)
1795        __(bne 1b)
1796        __(ldr sp,[sp,#node_size])
1797        __(bx lr)
1798
1799
1800/* If arg_z is an integer, return in imm0 something whose sign  */
1801/* is the same as arg_z's.  If not an integer, error.  */
1802_spentry(integer_sign)
1803        __(test_fixnum(arg_z))
1804        __(moveq imm0,arg_z)
1805        __(bxeq lr)
1806        __(extract_typecode(imm0,arg_z))
1807        __(cmp imm0,#subtag_bignum)
1808        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_integer))
1809        __(getvheader(imm1,arg_z))
1810        __(header_length(imm0,imm1)) /* boxed length = scaled size  */
1811        __(add imm0,imm0,#misc_data_offset-4) /* bias, less 1 element  */
1812        __(ldr imm0,[arg_z,imm0])
1813        __(cmp imm0,#0)
1814        __(movge imm0,#1)
1815        __(movlt imm0,#-1)
1816        __(bx lr)
1817
1818
1819/* like misc_set, only pass the (boxed) subtag in temp0  */
1820_spentry(subtag_misc_set)
1821        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
1822        __(trap_unless_fixnum(arg_y))
1823        __(vector_length(imm0,arg_x,imm1))
1824        __(cmp arg_y,imm0)
1825        __(uuo_error_vector_bounds(hs,arg_y,arg_x))
1826        __(unbox_fixnum(imm1,temp0))
1827        __(b C(misc_set_common))
1828
1829
1830
1831/* misc_set (vector index newval).  Pretty damned similar to  */
1832/* misc_ref, as one might imagine.  */
1833
1834_spentry(misc_set)
1835        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
1836        __(trap_unless_fixnum(arg_y))
1837        __(vector_length(imm0,arg_x,imm1))
1838        __(cmp arg_y,imm0)
1839        __(uuo_error_vector_bounds(hs,arg_y,arg_x))
1840        __(extract_lowbyte(imm1,imm1))
1841        __(b C(misc_set_common))
1842
1843/* "spread" the lexpr in arg_z.  */
1844/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1845_spentry(spread_lexprz)
1846        __(ldr imm0,[arg_z,#0])
1847        __(add imm1,arg_z,imm0)
1848        __(add nargs,nargs,imm0)
1849        __(add imm1,imm1,#node_size)
1850        __(cmp imm0,#3<<fixnumshift)
1851        __(bge 9f)
1852        __(cmp imm0,#2<<fixnumshift)
1853        __(beq 2f)
1854        __(cmp imm0,#0)
1855        __(bne 1f)
1856/* lexpr count was 0; vpop the arg regs that  */
1857/* were vpushed by the caller  */
1858        __(cmp nargs,#0)
1859        __(bxeq lr)
1860        __(vpop_argregs_nz)
1861        __(bx lr)
1862
1863/* vpush args from the lexpr until we have only  */
1864/* three left, then assign them to arg_x, arg_y,  */
1865/* and arg_z.  */
18668:
1867        __(cmp imm0,#4<<fixnumshift)
1868        __(sub imm0,imm0,#fixnumone)
1869        __(ldr arg_z,[imm1,#-node_size]!)
1870        __(vpush1(arg_z))
18719:
1872        __(bne 8b)
1873        __(ldr arg_x,[imm1,#-node_size*1])
1874        __(ldr arg_y,[imm1,#-node_size*2])
1875        __(ldr arg_z,[imm1,#-node_size*3])
1876        __(bx lr)
1877
1878/* lexpr count is two: set arg_y, arg_z from the  */
1879/* lexpr, maybe vpop arg_x  */
18802:
1881        __(cmp nargs,#2<<fixnumshift)
1882        __(ldr arg_y,[imm1,#-node_size*1])
1883        __(ldr arg_z,[imm1,#-node_size*2])
1884        __(bxeq lr)  /* return if (new) nargs = 2  */
1885        __(vpop1(arg_x))
1886        __(bx lr)
1887
1888/* lexpr count is one: set arg_z from the lexpr,  */
1889/* maybe vpop arg_y, arg_x  */
18901: 
1891        __(cmp nargs,#2<<fixnumshift)
1892        __(ldr arg_z,[imm1,#-node_size])
1893        __(bxlt lr)  /* return if (new) nargs < 2  */
1894        __(vpop1(arg_y))
1895        __(bxeq lr)  /* return if (new) nargs = 2  */
1896        __(vpop1(arg_x))
1897        __(bx lr)
1898
1899
1900_spentry(reset)
1901        __(nop)
1902        __(ref_nrs_value(temp0,toplcatch))
1903        __(mov temp1,#XSTKOVER)
1904        __(vpush1(temp0))
1905        __(vpush1(temp1))
1906        __(set_nargs(1))
1907        __(b _SPthrow)
1908
1909
1910/* "slide" nargs worth of values up the vstack.  IMM0 contains  */
1911/* the difference between the current VSP and the target.  */
1912_spentry(mvslide)
1913        __(cmp nargs,#0)
1914        __(mov temp1,nargs)
1915        __(add imm1,vsp,nargs)
1916        __(add imm1,imm1,imm0)
1917        __(add imm0,vsp,nargs)
1918        __(beq 2f)
19191:
1920        __(subs temp1,temp1,#1<<fixnumshift)
1921        __(ldr temp0,[imm0,#-node_size]!)
1922        __(str temp0,[imm1,#-node_size]!)
1923        __(bne 1b)
19242:
1925        __(mov vsp,imm1)
1926        __(bx lr)
1927
1928_spentry(save_values)
1929        __(mov temp1,#0)
1930        __(mov arg_x,sp)
1931local_label(save_values_to_tsp):
1932        __(add imm1,nargs,#node_size*2)
1933        __(dnode_align(imm0,imm1,node_size))
1934        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
1935        __(orr imm1,imm1,#subtag_u32_vector)
1936        __(stack_allocate_zeroed_ivector(imm1,imm0))
1937        __(cmp temp1,$0)
1938        __(mov imm1,#subtag_simple_vector)
1939        __(mov arg_y,#stack_alloc_marker)
1940        __(strb imm1,[sp])
1941        __(mov temp0,sp)
1942        __(stmdb sp!,{arg_y,arg_x})
1943        __(str temp1,[temp0,#node_size])
1944        __(strne temp0,[temp1,#node_size+4])
1945        __(add temp0,temp0,#node_size+8)
1946        __(mov imm0,#0)
1947        __(b 2f)
19481:      __(vpop1(temp1))
1949        __(str temp1,[temp0],#node_size)
1950        __(add imm0,imm0,#node_size)
19512:      __(cmp imm0,nargs)
1952        __(bne 1b)
1953        __(bx lr)
1954       
1955_spentry(add_values)
1956        __(cmp nargs,#0)
1957        __(ldr arg_x,[sp,#node_size])
1958        __(bxeq lr)
1959        __(add sp,sp,#dnode_size)
1960        __(mov temp1,sp)
1961        __(b local_label(save_values_to_tsp))
1962
1963
1964/* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
1965/* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
1966/* Calls out to %init-misc, which does the rest of the work.  */
1967
1968_spentry(misc_alloc_init)
1969        __(build_lisp_frame(imm0))
1970        __(mov fn,#0)
1971        __(mov temp2,arg_z)  /* initval  */
1972        __(mov arg_z,arg_y)  /* subtag  */
1973        __(mov arg_y,arg_x)  /* element-count  */
1974        __(bl _SPmisc_alloc)
1975        __(restore_lisp_frame(imm0))
1976        __(mov arg_y,temp2)
1977initialize_vector:             
1978        __(ref_nrs_symbol(fname,init_misc,imm0))
1979        __(set_nargs(2))
1980        __(jump_fname())
1981
1982/* As in stack_misc_alloc above, only with a non-default initial-value.  */
1983/* Note that this effectively inlines _SPstack_misc_alloc. */               
1984 
1985_spentry(stack_misc_alloc_init)
1986        __(tst arg_x,#unsigned_byte_24_mask)
1987        __(uuo_error_reg_not_xtype(ne,arg_x,xtype_unsigned_byte_24))
1988        __(unbox_fixnum(imm0,arg_y))
1989        __(extract_fulltag(imm1,imm0))
1990        __(cmp imm1,#fulltag_nodeheader)
1991        __(bne 1f)
1992        __(dnode_align(imm1,arg_x,node_size))
1993        __(cmp imm1,#stack_alloc_limit)
1994        __(bge 0f)
1995        __(mov imm0,#subtag_u32_vector)
1996        __(orr imm0,imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
1997        __(mov temp0,#stack_alloc_marker)
1998        __(mov temp1,sp)
1999        __(stack_allocate_zeroed_ivector(imm0,imm1))
2000        __(unbox_fixnum(imm0,arg_y))
2001        __(strb imm0,[sp])
2002        __(mov arg_y,arg_z)
2003        __(add arg_z,sp,#fulltag_misc)
2004        __(stmdb sp!,{temp0,temp1})
2005        __(b initialize_vector)
20061:      __(mov imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
2007        __(orr imm0,imm0,arg_y,lsr #fixnumshift)
2008        __(cmp arg_z,#max_32_bit_ivector_subtag<<fixnumshift)
2009        __(movle imm1,arg_x)
2010        __(ble 8f)
2011        __(cmp arg_z,#max_8_bit_ivector_subtag<<fixnumshift)
2012        __(movle imm1,arg_x,lsr #fixnumshift)
2013        __(ble 8f)
2014        __(cmp arg_z,#max_16_bit_ivector_subtag<<fixnumshift)
2015        __(movle imm1,arg_x,lsr #1)
2016        __(ble 8f)
2017        __(cmp arg_z,#subtag_double_float)
2018        __(moveq imm1,arg_x,lsl #1)
2019        __(addeq imm1,imm1,#node_size)
2020        __(addne imm1,arg_x,#7<<fixnumshift)
2021        __(movne imm1,imm1,lsr#3+fixnumshift)
20228:      __(dnode_align(imm1,imm1,node_size))
2023        __(cmp imm1,#stack_alloc_limit)
2024        __(bhs 0f)
2025        __(mov temp0,#stack_alloc_marker)
2026        __(mov temp1,sp)
2027        __(stack_allocate_zeroed_ivector(imm0,imm1))
2028        __(mov arg_y,arg_z)
2029        __(add arg_z,sp,#fulltag_misc)
2030        __(stmdb sp!,{temp0,temp1})
2031        __(b initialize_vector)
2032
2033 
2034_spentry(popj)
2035        .globl C(popj)
2036C(popj):
2037        __(return_lisp_frame(imm0))
2038       
2039/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
2040/* sure that there's an empty tsp frame to keep the compiler happy.  */
20410:
2042        __(mov imm0,#stack_alloc_marker)
2043        __(mov imm1,sp)
2044        __(stmdb sp!,{imm0,imm1})
2045        __(b _SPmisc_alloc_init)
2046
2047
2048/* Divide the 64 bit unsigned integer in imm0 (low) and imm1 (high) by
2049   the 32-bit unsigned integer in imm2; return the quotient in
2050   imm0:imm1 and remainder in imm2.  We pretty much have to do this
2051   as an ff call; even if we wrote the code ourselves, we'd have to
2052   enter foreign context to use as many imm regs as we'd need.
2053   Moral: don't do integer division on the ARM.
2054*/
2055        .globl C(__aeabi_uldivmod)       
2056_spentry(udiv64by32)
2057        __(cmp imm2,#0)
2058        __(moveq arg_z,#XDIVZRO)
2059        __(moveq nargs,#1<<fixnumshift)
2060        __(beq _SPksignalerr)
2061        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2062        __(str vsp,[rcontext,#tcr.save_vsp])
2063        __(mov arg_z,rcontext)
2064        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2065        __(build_lisp_frame(r3))
2066        __(str sp,[arg_z,#tcr.last_lisp_frame])
2067        __(str allocptr,[arg_z,#tcr.save_allocptr])
2068        __(mov r3,#TCR_STATE_FOREIGN)
2069        __(str r3,[arg_z,#tcr.valence])
2070        __(mov r3,#0)
2071        __(bl C(__aeabi_uldivmod))
2072        __(mov rcontext,arg_z)
2073        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2074        __(mov allocptr,#VOID_ALLOCPTR)
2075        __(mov fn,#0)
2076        __(mov temp2,#0)
2077        __(mov temp1,#0)
2078        __(mov temp0,#0)
2079        __(mov arg_x,#TCR_STATE_LISP)
2080        __(str arg_x,[rcontext,#tcr.valence])
2081        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2082        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2083        __(ldr fn,[sp,#lisp_frame.savefn])
2084        __(ldr lr,[sp,#lisp_frame.savelr])
2085        __(discard_lisp_frame())
2086        __(bx lr)
2087
2088
2089/* arg_z should be of type (UNSIGNED-BYTE 64);  */
2090/* return high 32 bits in imm1, low 32 bits in imm0 */
2091
2092
2093_spentry(getu64)
2094        __(test_fixnum(arg_z))
2095        __(bne 1f)
2096        __(unbox_fixnum(imm0,arg_z))
2097        __(movs imm1,imm0,asr #31)
2098        __(bxeq lr)
20990:             
2100        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
21011:
2102        __(extract_typecode(imm0,arg_z))
2103        __(cmp imm0,#subtag_bignum)
2104        __(bne 0b)
2105        __(movc16(imm1,two_digit_bignum_header))
2106        __(getvheader(imm0,arg_z))
2107        __(cmp imm0,imm1)
2108        __(bne 2f)
2109        __(vrefr(imm0,arg_z,0))
2110        __(vrefr(imm1,arg_z,1))
2111        __(cmp imm1,#0)
2112        __(bxge lr)
2113        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
21142:      __(movc16(imm1,three_digit_bignum_header))
2115        __(cmp imm0,imm1)
2116        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u64))
2117        __(vrefr(imm2,arg_z,2))
2118        __(cmp imm2,#0)
2119        __(vrefr(imm1,arg_z,1))
2120        __(vrefr(imm0,arg_z,0))
2121        __(bxeq lr)
2122        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
2123
2124         
2125/* arg_z should be of type (SIGNED-BYTE 64);  */
2126/*    return high 32 bits  in imm1, low 32 bits in imm0  */
2127
2128_spentry(gets64)
2129        __(test_fixnum(arg_z))
2130        __(moveq imm0,arg_z,asr #fixnumshift)
2131        __(moveq imm1,imm0,asr #31)
2132        __(bxeq lr)
2133        __(mov imm2,#0)
2134        __(extract_lisptag(imm0,arg_z))
2135        __(cmp imm0,#tag_misc)
2136        __(ldreq imm2,[arg_z,#misc_header_offset])
2137        __(movc16(imm1,two_digit_bignum_header))
2138        __(cmp imm1,imm2)
2139        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s64))
2140        __(vrefr(imm1,arg_z,1))
2141        __(vrefr(imm0,arg_z,0))
2142        __(bx lr)
2143
2144
2145/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
2146/* unbound_marker), arg_y = symbol, imm1 = symbol.binding-index  */
2147_spentry(specref)
2148        __(ldr imm1,[arg_z,#symbol.binding_index])
2149        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2150        __(cmp imm1,imm0)
2151        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
2152        __(mov arg_y,arg_z)
2153        __(movhs imm1,#0)
2154        __(ldr arg_z,[temp0,imm1])
2155        __(cmp arg_z,#no_thread_local_binding_marker)
2156        __(ldreq arg_z,[arg_y,#symbol.vcell])
2157        __(bx lr)
2158
2159_spentry(specrefcheck)
2160        __(ldr imm1,[arg_z,#symbol.binding_index])
2161        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2162        __(cmp imm1,imm0)
2163        __(movhs imm1,#0)
2164        __(ldr imm0,[rcontext,#tcr.tlb_pointer])
2165        __(mov arg_y,arg_z)
2166        __(ldr arg_z,[imm0,imm1])
2167        __(cmp arg_z,#no_thread_local_binding_marker)
2168        __(ldreq arg_z,[arg_y,#symbol.vcell])
2169        __(cmp arg_z,#unbound_marker)
2170        __(uuo_error_unbound(eq,arg_y))
2171        __(bx lr)
2172
2173/* arg_y = special symbol, arg_z = new value.          */
2174_spentry(specset)
2175        __(ldr imm1,[arg_y,#symbol.binding_index])
2176        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2177        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
2178        __(cmp imm1,imm0)
2179        __(movge imm1,#0)
2180        __(ldr temp1,[imm2,imm1])
2181        __(cmp temp1,#no_thread_local_binding_marker)
2182        __(strne arg_z,[imm2,imm1])
2183        __(bxne lr)
2184        __(mov arg_x,arg_y)
2185        __(mov arg_y,#symbol.vcell-misc_data_offset)
2186        __(b _SPgvset)
2187
2188
2189       
2190/* Construct a lisp integer out of the 32-bit signed value in imm0 */
2191/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
2192
2193_spentry(gets32)
2194        __(test_fixnum(arg_z))
2195        __(moveq imm0,arg_z,asr #fixnumshift)
2196        __(bxeq lr)
2197        __(extract_lisptag(imm0,arg_z))
2198        __(cmp imm0,#tag_misc)
2199        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s32))
2200        __(getvheader(imm0,arg_z))
2201        __(movc16(imm1,one_digit_bignum_header))
2202        __(cmp imm0,imm1)
2203        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s32))
2204        __(vrefr(imm0,arg_z,0))
2205        __(bx lr)       
2206
2207
2208/*  */
2209/* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
2210/*  */
2211
2212_spentry(getu32)
2213        __(test_fixnum(arg_z))
2214        __(moveq imm0,arg_z,asr #fixnumshift)
2215        __(movseq imm1,imm0,asr #31)
2216        __(bxeq lr)
2217        __(movc16(imm1,one_digit_bignum_header))
2218        __(extract_lisptag(imm0,arg_z))
2219        __(cmp imm0,#tag_misc)
2220        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
2221        __(getvheader(imm0,arg_z))
2222        __(cmp imm0,imm1)
2223        __(ldreq imm0,[arg_z,#misc_data_offset])
2224        __(beq 7f)
2225        __(movc16(imm1,two_digit_bignum_header))
2226        __(cmp imm0,imm1)
2227        __(ldreq imm0,[arg_z,#misc_data_offset])
2228        __(ldreq imm1,[arg_z,#misc_data_offset+4])
2229        __(cmpeq imm1,#0)
2230        __(bxeq lr)
2231        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
22327:             
2233        __(movs imm1,imm0,asr #31)
2234        __(bxeq lr)
2235        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
2236
2237
2238/* */
2239/* As per mvpass above, but in this case fname is known to be a */
2240/* symbol. */
2241
2242_spentry(mvpasssym)
2243        __(cmp nargs,#node_size*nargregs)
2244        __(mov imm1,vsp)
2245        __(subgt imm1,imm1,#node_size*nargregs)
2246        __(addgt imm1,imm1,nargs)
2247        __(build_lisp_frame(imm0,imm1))
2248        __(ref_global(lr,ret1val_addr,imm0))
2249        __(mov fn,#0)
2250        __(jump_fname())
2251
2252_spentry(unbind)
2253        __(ldr imm1,[rcontext,#tcr.db_link])
2254        __(ldr temp0,[rcontext,#tcr.tlb_pointer])   
2255        __(ldr imm0,[imm1,#binding.sym])
2256        __(ldr temp1,[imm1,#binding.val])
2257        __(ldr imm1,[imm1,#binding.link])
2258        __(str temp1,[temp0,imm0])
2259        __(str imm1,[rcontext,#tcr.db_link])
2260        __(bx lr)
2261
2262/* Clobbers imm1,temp0,arg_x, arg_y */       
2263_spentry(unbind_n)
2264        __(ldr imm1,[rcontext,#tcr.db_link])
2265        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
22661:      __(ldr temp0,[imm1,#binding.sym])
2267        __(ldr arg_y,[imm1,#binding.val])
2268        __(ldr imm1,[imm1,#binding.link])
2269        __(subs imm0,imm0,#1)
2270        __(str arg_y,[arg_x,temp0])
2271        __(bne 1b)
2272        __(str imm1,[rcontext,#tcr.db_link])
2273        __(bx lr)
2274
2275/* */
2276/* Clobbers imm1,temp0,arg_x, arg_y */
2277
2278_spentry(unbind_to)
2279        do_unbind_to(imm1,temp1,arg_x,arg_y)
2280        __(bx lr)
2281 
2282
2283 
2284/* */
2285/* Restore the special bindings from the top of the tstack,  */
2286/* leaving the tstack frame allocated.  */
2287/* Note that there might be 0 saved bindings, in which case  */
2288/* do nothing.  */
2289/* Note also that this is -only- called from an unwind-protect  */
2290/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
2291/* values in a frame on top of the tstack.  */
2292/*  */
2293                         
2294_spentry(progvrestore)
2295        __(skip_stack_vector(imm0,imm1,sp))
2296        __(ldr imm0,[imm0,#lisp_frame.size+node_size])
2297        __(cmp imm0,#0)
2298        __(unbox_fixnum(imm0,imm0))
2299        __(bne _SPunbind_n)
2300        __(bx lr)
2301
2302/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
2303/* for pending interrupts after doing so.  */
2304_spentry(bind_interrupt_level_0)
2305        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2306        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2307        __(ldr imm0,[rcontext,#tcr.db_link])
2308        __(cmp temp0,#0)
2309        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2310        __(vpush1(temp0))
2311        __(vpush1(imm1))
2312        __(vpush1(imm0))
2313        __(mov imm0,#0)
2314        __(str imm0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2315        __(str vsp,[rcontext,#tcr.db_link])
2316        __(bxeq lr)
2317        __(ldrlt temp0,[rcontext,#tcr.interrupt_pending])
2318        __(cmp temp0,#0)
2319        __(uuo_interrupt_now(gt))
2320        __(bx lr)
2321       
2322/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
2323/* of disabling interrupts.)  */
2324_spentry(bind_interrupt_level_m1)
2325        __(mov imm2,#-fixnumone)
2326        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2327        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2328        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2329        __(ldr imm0,[rcontext,#tcr.db_link])
2330        __(vpush1(temp0))
2331        __(vpush1(imm1))
2332        __(vpush1(imm0))
2333        __(str imm2,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2334        __(str vsp,[rcontext,tcr.db_link])
2335        __(bx lr)
2336       
2337
2338/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
2339/* do what _SPbind_interrupt_level_0 does  */
2340_spentry(bind_interrupt_level)
2341        __(cmp arg_z,#0)
2342        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2343        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2344        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2345        __(ldr imm0,[rcontext,#tcr.db_link])
2346        __(beq _SPbind_interrupt_level_0)
2347        __(vpush1(temp0))
2348        __(vpush1(imm1))
2349        __(vpush1(imm0))
2350        __(str arg_z,[temp1,INTERRUPT_LEVEL_BINDING_INDEX])
2351        __(str vsp,[rcontext,#tcr.db_link])
2352        __(bx lr)
2353
2354/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
2355/* non-negative, check for pending interrupts.  This is often called in */
2356/* a context where nargs is significant, so save and restore nargs around */
2357/* any interrupt polling  */
2358         
2359_spentry(unbind_interrupt_level)
2360        __(ldr imm0,[rcontext,#tcr.flags])
2361        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
2362        __(tst imm0,#1<<TCR_FLAG_BIT_PENDING_SUSPEND)
2363        __(ldr imm0,[rcontext,#tcr.db_link])
2364        __(ldr temp0,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2365        __(bne 5f)
23660:     
2367        __(ldr temp1,[imm0,#binding.val])
2368        __(ldr imm0,[imm0,#binding.link])
2369        __(str temp1,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2370        __(str imm0,[rcontext,#tcr.db_link])
2371        __(cmp temp0,#0)
2372        __(bxge lr)
2373        __(cmp temp1,#0)
2374        __(bxlt lr)
2375        __(check_enabled_pending_interrupt(imm0))
2376        __(bx lr)
23775:       /* Missed a suspend request; force suspend now if we're restoring
2378          interrupt level to -1 or greater */
2379        __(cmp temp0,#-2<<fixnumshift)
2380        __(bne 0b)
2381        __(ldr imm0,[imm1,#binding.val])
2382        __(cmp imm0,temp0)
2383        __(beq 0b)
2384        __(mov imm0,#1<<fixnumshift)
2385        __(str imm0,[temp2,INTERRUPT_LEVEL_BINDING_INDEX])
2386        __(suspend_now())
2387        __(b 0b)
2388 
2389 
2390/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
2391    We don't know whether the array is alleged to be simple or
2392   not, and don't know anythng about the element type.  */
2393_spentry(aref2)
2394        __(trap_unless_fixnum(arg_y))
2395        __(trap_unless_fixnum(arg_z))
2396        __(extract_typecode(imm2,arg_x))
2397        __(cmp imm2,#subtag_arrayH)
2398        __(ldreq imm1,[arg_x,#arrayH.rank])
2399        __(cmpeq imm1,#2<<fixnumshift)
2400        __(uuo_error_reg_not_xtype(ne,arg_x,xtype_array2d))
2401        /* It's a 2-dimensional array.  Check bounds */
2402        __(ldr imm0,[arg_x,#arrayH.dim0])
2403        __(cmp arg_y,imm0)
2404        __(uuo_error_array_bounds(hs,arg_y,arg_x))
2405        __(ldr imm0,[arg_x,#arrayH.dim0+node_size])
2406        __(cmp arg_z,imm0)
2407        __(uuo_error_array_bounds(hs,arg_z,arg_x))
2408        __(unbox_fixnum(imm0,imm0))
2409        __(mul temp0,arg_y,imm0) /* no MLA on ARMv5 */
2410        __(add arg_z,arg_z,temp0)
2411        /* arg_z is now row-major-index; get data vector and
2412           add in possible offset */
2413        __(mov arg_y,arg_x)
24140:      __(ldr imm0,[arg_y,#arrayH.displacement])
2415        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2416        __(extract_subtag(imm1,arg_y))
2417        __(cmp imm1,#subtag_vectorH)
2418        __(add arg_z,arg_z,imm0)
2419        __(bgt C(misc_ref_common))
2420        __(b 0b)
2421 
2422/* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
2423_spentry(aref3)
2424        __(trap_unless_fixnum(arg_x))
2425        __(trap_unless_fixnum(arg_y))
2426        __(trap_unless_fixnum(arg_z))
2427        __(extract_typecode(imm2,temp0))
2428        __(mov imm1,#0)
2429        __(cmp imm2,#subtag_arrayH)
2430        __(ldreq imm1,[temp0,#arrayH.rank])
2431        __(cmp imm1,#3<<fixnumshift)
2432        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array3d))
2433        /* It's a 3-dimensional array.  Check bounds */
2434        __(ldr imm2,[temp0,arrayH.dim0+(node_size*2)])
2435        __(ldr imm1,[temp0,#arrayH.dim0+node_size])
2436        __(ldr imm0,[temp0,#arrayH.dim0])
2437        __(cmp arg_z,imm2)
2438        __(uuo_error_array_bounds(hs,arg_z,temp0))
2439        __(cmp arg_y,imm1)
2440        __(uuo_error_array_bounds(hs,arg_y,temp0))
2441        __(cmp arg_x,imm0)
2442        __(uuo_error_array_bounds(hs,arg_x,temp0))
2443        __(unbox_fixnum(imm2,imm2))
2444        __(unbox_fixnum(imm1,imm1))
2445        __(mul arg_y,imm2,arg_y)
2446        __(mul imm1,imm2,imm1)
2447        __(mul arg_x,imm1,arg_x)
2448        __(add arg_z,arg_z,arg_y)
2449        __(add arg_z,arg_z,arg_x)
2450        __(mov arg_y,temp0)
24510:      __(ldr arg_x,[arg_y,#arrayH.displacement])
2452        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2453        __(extract_subtag(imm1,arg_y))
2454        __(cmp imm1,#subtag_vectorH)
2455        __(add arg_z,arg_x,arg_z)
2456        __(bgt C(misc_ref_common))
2457        __(b 0b)
2458
2459
2460
2461
2462/* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
2463_spentry(aset2)
2464        __(extract_typecode(imm0,temp0))
2465        __(cmp imm0,#subtag_arrayH)
2466        __(ldreq imm0,[temp0,#arrayH.rank])
2467        __(cmpeq imm0,#2<<fixnumshift)
2468        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array2d))
2469        __(trap_unless_fixnum(arg_x))
2470        __(trap_unless_fixnum(arg_y))
2471        /* It's a 2-dimensional array.  Check bounds */
2472        __(ldr imm0,[temp0,#arrayH.dim0])
2473        __(cmp arg_x,imm0)
2474        __(uuo_error_array_bounds(hs,arg_x,temp0))
2475        __(ldr imm0,[temp0,#arrayH.dim0+node_size])
2476        __(cmp arg_y,imm0)
2477        __(uuo_error_array_bounds(hs,arg_y,temp0))
2478        __(unbox_fixnum(imm0,imm0))
2479        __(mul temp1,arg_x,imm0)
2480        __(add arg_y,arg_y,temp1)
2481        /* arg_y is now row-major-index; get data vector and
2482           add in possible offset */
2483        __(mov arg_x,temp0)
24840:      __(ldr imm0,[arg_x,#arrayH.displacement])
2485        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2486        __(extract_subtag(imm1,arg_x))
2487        __(cmp imm1,#subtag_vectorH)
2488        __(add arg_y,arg_y,imm0)
2489        __(bgt C(misc_set_common))
2490        __(b 0b)
2491
2492                 
2493/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
2494_spentry(aset3)
2495        __(extract_typecode(imm0,temp1))
2496        __(cmp imm0,#subtag_arrayH)
2497        __(ldreq imm0,[temp1,#arrayH.rank])
2498        __(cmpeq imm0,#3<<fixnumshift)
2499        __(uuo_error_reg_not_xtype(ne,temp1,xtype_array3d))
2500        __(trap_unless_fixnum(temp0))
2501        __(trap_unless_fixnum(arg_x))
2502        __(trap_unless_fixnum(arg_y))
2503        /* It's a 3-dimensional array.  Check bounds */
2504        __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)])
2505        __(ldr imm1,[temp1,#arrayH.dim0+node_size])
2506        __(ldr imm0,[temp1,#arrayH.dim0])
2507        __(cmp arg_y,imm2)
2508        __(uuo_error_array_bounds(hs,arg_y,temp1))
2509        __(cmp arg_x,imm1)
2510        __(uuo_error_array_bounds(hs,arg_x,temp1))
2511        __(unbox_fixnum(imm1,imm1))
2512        __(cmp temp0,imm0)
2513        __(uuo_error_array_bounds(hs,temp0,temp1))
2514        __(mul arg_x,imm2,arg_x)
2515        __(mul imm1,imm2,imm1)
2516        __(mul temp0,imm1,temp0)
2517        __(add arg_y,arg_y,arg_x)
2518        __(add arg_y,arg_y,temp0)
2519        __(mov arg_x,temp1)
25200:      __(ldr temp0,[arg_x,#arrayH.displacement])
2521        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2522        __(extract_subtag(imm1,arg_x))
2523        __(cmp imm1,#subtag_vectorH)
2524        __(add arg_y,arg_y,temp0)
2525        __(bgt C(misc_set_common))
2526        __(b 0b)
2527
2528
2529/* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
2530/* pairs.  There'll be arg_z keyword arguments.  arg_y contains flags  */
2531/* that indicate whether &allow-other-keys was specified and whether  */
2532/* or not to leave the keyword/value pairs on the vstack for an &rest  */
2533/* argument.  Element 2 of the function in fn contains a vector of keyword.  */
2534/* If the number of arguments is greater than imm0, the difference must  */
2535/* be even.  */
2536/* All arg regs have been vpushed and the calling function has built a */
2537/* stack frame.  next_method_context must be preserved, as must the incoming */
2538/* key/value pairs and their number if we're going to make an &rest arg. */
2539           
2540
2541define(`keyword_flags',`arg_y')
2542define(`key_value_count',`arg_z')
2543
2544define(`keyword_flag_allow_other_keys',`(1<<fixnumshift)')
2545define(`keyword_flag_seen_allow_other_keys',`(2<<fixnumshift)')
2546define(`keyword_flag_unknown_keyword_seen',`(3<<fixnumshift)')
2547define(`keyword_flag_rest',`(4<<fixnumshift)')
2548
2549_spentry(keyword_bind)
2550        new_local_labels()       
2551        __(subs key_value_count,nargs,imm0)
2552        __(movmi key_value_count,#0)
2553        __(tst key_value_count,#fixnumone)
2554        __(bne local_label(odd_keywords))
2555        __(mov imm1,key_value_count,lsl #num_subtag_bits-fixnumshift)
2556        __(orr imm1,imm1,subtag_u32_vector)
2557        __(add imm0,key_value_count,#dnode_size) /* we know  count is even */
2558        __(stack_allocate_zeroed_ivector(imm1,imm0))
2559        __(mov imm0,#subtag_simple_vector)
2560        __(strb imm0,[sp])
2561        /* Copy key/value pairs in reverse order from the vstack to
2562           the gvector we just created on the cstack. */
2563        __(add imm0,vsp,key_value_count) /* src, predecrement */
2564        __(add imm1,sp,#node_size)       /* dest, postincrement */
2565        __(mov temp2,key_value_count)
2566        __(b 1f)
25670:      __(ldr arg_x,[imm0,#-node_size]!)
2568        __(str arg_x,[imm1],#node_size)
25691:      __(subs temp2,temp2,#fixnumone)
2570        __(bge 0b)
2571        /* Discard the key/value pairs from the vstack. */
2572        __(add vsp,vsp,key_value_count)
2573        __(ldr temp2,[fn,#misc_data_offset+(2*node_size)])
2574        __(getvheader(imm0,temp2))
2575        __(mov imm0,imm0,lsr #num_subtag_bits)
2576        __(mov temp0,vsp)
2577        __(mov imm1,#nil_value)
2578        /* Push a pair of NILs (value, supplied-p) for each defined keyword */
2579        __(b 3f)
25802:      __(vpush1(imm1))
2581        __(vpush1(imm1))
25823:      __(subs imm0,imm0,#1)
2583        __(bge 2b)
2584        /* Save nargs and temp1 so that we can use them in the loop(s) */
2585        __(stmdb vsp!,{imm2,temp1})
2586        /* For each provided key/value pair: if the key is :allow-other-keys
2587           and that hasn't been seen before, note that it's been seen and
2588           if the value is non-nil set the allow-other-keys bit in flags.
2589           Then search for the key in the defined keys vector.  If it's
2590           not found, note that an undefined keyword was seen by setting
2591           a bit in keyword_flags ; if it is found, use its position to
2592           index the table of value/supplied-p pairs that we pushed above.
2593           If the supplied-p var is already set, do nothing; otherwise,
2594           set the supplied-p var and value.
2595           When done, signal an error if we got an unknown keyword, or
2596           either copy the supplied key/value pairs back to the vstack
2597           if we're going to cons an &rest arg or discard them if we aren't.
2598        */
2599        __(mov imm2,#0)
2600        __(b local_label(nextvalpairtest))
2601local_label(nextvalpairloop):   
2602        __(add temp1,sp,#4)
2603        __(ldr temp1,[temp1,imm2])
2604        __(ref_nrs_symbol(imm1,kallowotherkeys,imm1))
2605        __(cmp temp1,imm1)
2606        __(tsteq keyword_flags,#keyword_flag_seen_allow_other_keys)
2607        __(bne local_label(current_key_allow_other_keys_handled))
2608        __(orr keyword_flags,keyword_flags,#keyword_flag_seen_allow_other_keys)
2609        /* Fortunately, we know what the keyword is.  Need to check the
2610           value here, and don't have a lot of free registers ... */
2611        __(add temp1,sp,#8)
2612        __(ldr temp1,[temp1,imm2])
2613        __(cmp temp1,#nil_value)
2614        __(orrne keyword_flags,keyword_flags,#keyword_flag_allow_other_keys)
2615        __(mov temp1,imm1)      /* from comparison above */
2616local_label(current_key_allow_other_keys_handled):
2617        __(getvheader(imm0,temp2))
2618        __(header_length(arg_x,imm0))
2619        __(add imm0,arg_x,#misc_data_offset)
2620        __(b local_label(defined_keyword_compare_test))
2621local_label(defined_keyword_compare_loop):     
2622        __(ldr arg_x,[temp2,imm0])
2623        __(cmp arg_x,temp1)
2624        __(subeq imm0,imm0,#misc_data_offset)
2625        __(beq local_label(defined_keyword_found))
2626local_label(defined_keyword_compare_test):     
2627        __(sub imm0,imm0,#node_size)
2628        __(cmp imm0,#misc_data_offset)
2629        __(bge local_label(defined_keyword_compare_loop))
2630        /* keyword wasn't defined.  Note that ... */
2631        __(orr keyword_flags,keyword_flags,#keyword_flag_unknown_keyword_seen)
2632        __(b local_label(nextkeyvalpairnext))
2633local_label(defined_keyword_found):     
2634        __(sub imm0,temp0,imm0,lsl #1)
2635        __(ldr arg_x,[imm0,#-8])
2636        __(cmp arg_x,#nil_value) /* seen this keyword yet ? */
2637        __(bne local_label(nextkeyvalpairnext))
2638        __(add arg_x,arg_x,#t_offset)
2639        __(str arg_x,[imm0,#-8])
2640        __(add temp1,sp,#8)
2641        __(ldr temp1,[temp1,imm2])
2642        __(str temp1,[imm0,#-4])
2643local_label(nextkeyvalpairnext):
2644        __(add imm2,imm2,#8)
2645local_label(nextvalpairtest):   
2646        __(cmp imm2,key_value_count)
2647        __(bne local_label(nextvalpairloop))
2648        __(ldmia vsp!,{imm2,temp1})
2649        /* If unknown keywords and that's not allowed, signal error.
2650           Otherwise, discard the stack-consed vector and return,
2651           possibly after having copied the vector's contents back
2652           to the vstack so that an &rest arg can be constructed.
2653        */
2654        __(tst keyword_flags,#keyword_flag_unknown_keyword_seen)
2655        __(beq 0f)
2656        __(tst keyword_flags,#keyword_flag_allow_other_keys)
2657        __(beq local_label(badkeys))
26580:      __(tst keyword_flags,#keyword_flag_rest)
2659        __(beq local_label(discard_stack_vector))
2660        __(mov imm0,#0)
2661        __(add temp2,sp,#node_size)
2662        __(b 2f)
26631:      __(ldr arg_x,[temp2],#node_size)
2664        __(vpush1(arg_x))
2665        __(add imm0,imm0,#fixnumone)
26662:      __(cmp imm0,key_value_count)
2667        __(bne 1b)
2668local_label(discard_stack_vector):     
2669        __(add key_value_count,key_value_count,#dnode_size)
2670        __(add sp,sp,key_value_count)
2671        __(bx lr)               /* it's finally over ! */
2672
2673local_label(badkeys):   /* Disturbingly similar to the &rest case */
2674        __(mov nargs,#0)
2675        __(add temp2,sp,#node_size)
2676        __(mov vsp,temp0)
2677        __(b 1f)
26780:      __(ldr arg_x,[temp2],#node_size)
2679        __(vpush1(arg_x))
2680        __(add nargs,nargs,#fixnumone)
26811:      __(cmp nargs,key_value_count)
2682        __(bne 0b)
2683        /* Lose the stack vector */
2684        __(add key_value_count,key_value_count,#dnode_size)
2685        __(add sp,sp,key_value_count)
2686local_label(error_exit):               
2687        __(bl _SPconslist)
2688        __(mov arg_y,#XBADKEYS)
2689        __(set_nargs(2))
2690        __(b _SPksignalerr)
2691local_label(odd_keywords):       
2692        __(mov nargs,key_value_count)
2693        __(b local_label(error_exit))
2694
2695        .globl C(__aeabi_uidivmod)               
2696_spentry(udiv32)
2697        __(cmp imm1,#0)
2698        __(moveq arg_z,#XDIVZRO)
2699        __(moveq nargs,#1<<fixnumshift)
2700        __(beq _SPksignalerr)
2701        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2702        __(str vsp,[rcontext,#tcr.save_vsp])
2703        __(mov arg_z,rcontext)
2704        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2705        __(build_lisp_frame(r3))
2706        __(str sp,[arg_z,#tcr.last_lisp_frame])
2707        __(str allocptr,[arg_z,#tcr.save_allocptr])
2708        __(mov r3,#TCR_STATE_FOREIGN)
2709        __(str r3,[arg_z,#tcr.valence])
2710        __(mov r3,#0)
2711        __(bl C(__aeabi_uidivmod))
2712        __(mov rcontext,arg_z)
2713        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2714        __(mov allocptr,#VOID_ALLOCPTR)
2715        __(mov fn,#0)
2716        __(mov temp2,#0)
2717        __(mov temp1,#0)
2718        __(mov temp0,#0)
2719        __(mov arg_x,#TCR_STATE_LISP)
2720        __(str arg_x,[rcontext,#tcr.valence])
2721        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2722        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2723        __(ldr fn,[sp,#lisp_frame.savefn])
2724        __(ldr lr,[sp,#lisp_frame.savelr])
2725        __(discard_lisp_frame())
2726        __(bx lr)
2727
2728_spentry(sdiv32)
2729        __(build_lisp_frame(imm2))
2730pushdef(`sign',`temp0')
2731pushdef(`d',`r0')
2732pushdef(`r',`r1')               
2733        __(ands sign,d,#0x80000000)
2734        __(rsbmi d,d,#0)
2735        __(eors sign,sign,r,asr #32)
2736        __(rsbcs r,r,#0)
2737        __(bl _SPudiv32)
2738        __(movs sign,sign,lsl #1)
2739        __(rsbcs d,d,#0)
2740        __(rsbmi r,r,#0)
2741        __(return_lisp_frame(imm2))
2742popdef(`sign')
2743popdef(`d',)
2744popdef(`r',)               
2745       
2746
2747               
2748_spentry(eabi_ff_call)
2749        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2750        __(stmdb vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2751        __(str vsp,[rcontext,#tcr.save_vsp])
2752/* There's a u32 vector on top of the stack ; its first data word points
2753   to the previous stack object.  The 4 words at the bottom of the vector
2754   are reserved for a lisp frame, which we construct carefully ... */
2755        __(mov imm0,#lisp_frame_marker)
2756        __(mov imm1,#0)
2757        __(ldr temp0,[sp,#4])
2758        __(sub temp0,temp0,#lisp_frame.size)
2759        __(str imm0,[temp0,#lisp_frame.marker])
2760        __(ldr imm0,[sp,#0])       
2761        __(str imm1,[temp0,#lisp_frame.savefn])
2762        __(str imm1,[temp0,#lisp_frame.savelr])
2763        __(sub imm0,imm0,#(lisp_frame.size/4)<<num_subtag_bits)
2764        __(str vsp,[temp0,#lisp_frame.savevsp])
2765        __(str imm0,[sp,#0])
2766        __(str lr,[temp0,#lisp_frame.savelr])
2767        __(str fn,[temp0,#lisp_frame.savefn])
2768        __(str allocptr,[rcontext,#tcr.save_allocptr])
2769        __(str temp0,[rcontext,#tcr.last_lisp_frame])
2770        __(mov temp0,rcontext)
2771        __(test_fixnum(arg_z))
2772        __(moveq imm1,arg_z,asr #fixnumshift)
2773        __(ldrne imm1,[arg_z,#misc_data_offset])
2774        __(mov imm0,#TCR_STATE_FOREIGN)
2775        __(str imm0,[rcontext,#tcr.valence])
2776        __(mov r4,imm1)
2777        __(add sp,sp,#dnode_size)
2778        __(ldmia sp!,{r0,r1,r2,r3})
2779        __(blx r4)
2780        __(mov temp1,#0)
2781        __(mov temp2,#0)
2782        __(mov arg_z,#0)
2783        __(mov arg_y,#0)
2784        __(mov arg_x,#0)
2785        __(mov fn,#0)
2786        __(mov allocptr,#VOID_ALLOCPTR)
2787        __(mov rcontext,temp0)
2788        __(ldr sp,[rcontext,#tcr.last_lisp_frame])
2789        __(str fn,[rcontext,#tcr.valence])
2790        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2791        __(restore_lisp_frame(temp0))
2792        __(ldmia vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2793        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2794        __(check_pending_interrupt(temp2))
2795        __(bx lr)
2796       
2797       
2798
2799_spentry(debind)
2800        new_local_labels()
2801        __(mov temp0,vsp)
2802        __(mov temp1,arg_z)
2803        __(ands imm0,nargs,#0xff)
2804        __(mov arg_y,#nil_value)
2805        __(b local_label(req_test))
2806local_label(req_loop): 
2807        __(cmp arg_reg,#nil_value)
2808        __(extract_lisptag(imm1,arg_reg))
2809        __(beq local_label(toofew))
2810        __(cmp imm1,#tag_list)
2811        __(bne local_label(badlist))
2812        __(subs imm0,imm0,#1)
2813        __(_car(arg_x,arg_reg))
2814        __(_cdr(arg_reg,arg_reg))
2815        __(vpush1(arg_x))
2816local_label(req_test):
2817        __(bne local_label(req_loop))
2818        __(mov imm0,#0xff)
2819        __(ands imm0,imm0,nargs,lsr #8)
2820        __(beq local_label(rest_keys))
2821        __(tst nargs,#mask_initopt)
2822        __(bne local_label(opt_supp))
2823        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2824local_label(simple_opt_loop):
2825        __(cmp arg_reg,#nil_value)
2826        __(extract_lisptag(imm1,arg_reg))
2827        __(beq local_label(default_simple_opt))
2828        __(cmp imm1,#tag_list)
2829        __(bne local_label(badlist))
2830        __(subs imm0,imm0,#1)
2831        __(_car(arg_x,arg_reg))
2832        __(_cdr(arg_reg,arg_reg))
2833        __(vpush1(arg_x))
2834        __(bne local_label(simple_opt_loop))
2835        __(b local_label(rest_keys))
2836local_label(default_simple_opt):       
2837        __(subs imm0,imm0,#1)
2838        __(vpush1(arg_y))
2839        __(bne local_label(default_simple_opt))
2840        __(b local_label(rest_keys))
2841local_label(opt_supp):   
2842        __(cmp arg_reg,#nil_value)
2843        __(extract_lisptag(imm1,arg_reg))
2844        __(beq local_label(default_hard_opt))
2845        __(cmp imm1,#tag_list)
2846        __(bne local_label(badlist))
2847        __(subs imm0,imm0,#1)
2848        __(_car(arg_x,arg_reg))
2849        __(_cdr(arg_reg,arg_reg))
2850        __(vpush1(arg_x))
2851        __(add arg_x,arg_y,#t_offset)
2852        __(vpush1(arg_x))
2853        __(bne local_label(opt_supp))
2854        __(b local_label(rest_keys))
2855local_label(default_hard_opt): 
2856        __(subs imm0,imm0,#1)
2857        __(vpush1(arg_y))
2858        __(vpush1(arg_y))
2859        __(bne local_label(default_hard_opt))
2860local_label(rest_keys):
2861        __(tst nargs,#mask_restp)
2862        __(bne local_label(have_rest))
2863        __(tst nargs,#mask_keyp)
2864        __(bne local_label(have_keys))
2865        __(cmp arg_reg,#nil_value)
2866        __(bne local_label(toomany))
2867        __(bx lr)
2868local_label(have_rest):
2869        __(vpush1(arg_reg))
2870        __(tst nargs,#mask_keyp)
2871        __(bne local_label(have_keys))
2872        __(bx lr)
2873local_label(have_keys):
2874        __(mov imm0,#256)
2875        __(mov arg_y,arg_reg)
2876local_label(count_keys_loop):   
2877        __(cmp arg_y,#nil_value)
2878        __(beq local_label(counted_keys))
2879        __(subs imm0,imm0,#1)
2880        __(bmi local_label(toomany))
2881        __(extract_lisptag(imm1,arg_y))
2882        __(cmp imm1,#tag_list)
2883        __(bne local_label(badlist))
2884        __(_cdr(arg_y,arg_y))
2885        __(extract_lisptag(imm1,arg_y))
2886        __(cmp imm1,#tag_list)
2887        __(bne local_label(badlist))
2888        __(_cdr(arg_y,arg_y))
2889        __(b local_label(count_keys_loop))
2890local_label(counted_keys):     
2891        /* We've got a proper, even-length list of key/value pairs in  */
2892        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2893        /* of NILs on the vstack.  (We've also cdred down arg_y until it */
2894        /* contains NIL.) */
2895        __(mov imm0,#0xff)
2896        __(ands imm0,imm0,nargs,lsr #16)
2897        __(mov imm1,vsp)
2898        __(b local_label(push_pair_test))
2899local_label(push_pair_loop):
2900        __(subs imm0,imm0,#1)
2901        __(vpush1(arg_y))
2902        __(vpush1(arg_y))
2903local_label(push_pair_test):   
2904        __(bne local_label(push_pair_loop))
2905        __(b local_label(provided_key_loop))
2906       
2907local_label(next_provided_key):
2908        __(_car(arg_x,arg_reg))
2909        __(ref_nrs_symbol(imm0,kallowotherkeys,imm0))
2910        __(cmp arg_x,imm0)
2911        __(bne local_label(not_aok))
2912        __(tst nargs,#mask_aok_seen)
2913        __(beq local_label(not_aok))
2914        __(_cdr(arg_x,arg_reg))
2915        __(_car(arg_x,arg_x))
2916        __(orr nargs,nargs,#mask_aok_seen)
2917        __(cmp arg_x,#nil_value)
2918        __(orrne nargs,nargs,#mask_aok)
2919        __(_car(arg_x,arg_reg))
2920local_label(not_aok):   
2921        __(getvheader(imm0,keyvect_reg))
2922        __(header_length(arg_y,imm0))
2923        __(add imm0,arg_y,#misc_data_offset)
2924        __(b local_label(match_key_test))
2925local_label(match_key_loop):   
2926        __(ldr arg_y,[keyvect_reg,imm0])
2927        __(cmp arg_x,arg_y)
2928        __(bne local_label(match_key_test))
2929        __(sub imm0,imm0,#misc_data_offset)
2930        __(sub imm0,imm1,imm0,lsl #1)
2931        __(ldr arg_y,[imm0,#-node_size])
2932        __(cmp arg_y,#nil_value)
2933        __(beq local_label(provided_key_done))
2934        __(_cdr(arg_x,arg_reg))
2935        __(_car(arg_x,arg_x))
2936        __(str arg_x,[imm0,#0])
2937        __(mov arg_x,#nil_value)
2938        __(add arg_x,arg_x,#t_offset)
2939        __(str arg_x,[imm0,#-node_size])
2940        __(b local_label(provided_key_done))
2941local_label(match_key_test):   
2942        __(sub imm0,imm0,#node_size)
2943        __(cmp imm0,#misc_data_offset)
2944        __(bge local_label(match_key_loop))
2945        __(orr nargs,nargs,#mask_unknown_keyword_seen)
2946local_label(provided_key_done):
2947        __(_cdr(arg_reg,arg_reg))
2948        __(_cdr(arg_reg,arg_reg))
2949local_label(provided_key_loop):
2950        __(cmp arg_reg,#nil_value)
2951        __(bne local_label(next_provided_key))
2952        __(tst nargs,#mask_unknown_keyword_seen)
2953        __(bxeq lr)
2954        __(tst nargs,#mask_aok)
2955        __(bxne lr)
2956local_label(badkeys):
2957        __(mov arg_y,#XBADKEYS)
2958        __(b local_label(destructure_error))
2959local_label(toomany):   
2960        __(mov arg_y,#XCALLTOOMANY)
2961        __(b local_label(destructure_error))
2962local_label(toofew):   
2963        __(mov arg_y,#XCALLTOOFEW)
2964        __(b local_label(destructure_error))
2965local_label(badlist):   
2966        __(mov arg_y,#XCALLNOMATCH)
2967local_label(destructure_error):
2968        __(mov vsp,temp0)
2969        __(mov arg_z,temp1)       
2970        __(set_nargs(2))
2971        __(b _SPksignalerr)
2972       
2973_spentry(eabi_callback)
2974        __(stmdb sp!,{r0,r1,r2,r3})
2975        __(mov r0,sp)
2976        __(sub sp,sp,#2*node_size) /* room for result */
2977        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
2978        __(mov r4,r0)
2979        __(box_fixnum(r5,r12))
2980        __(ref_global(r12,get_tcr,r0))
2981        __(mov r0,#1)
2982        __(blx r12)
2983        __(mov rcontext,r0)
2984        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
2985        __(sub imm0,imm2,sp)
2986        __(add imm0,imm0,#node_size)
2987        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
2988        __(orr imm0,imm0,#subtag_u32_vector)
2989        __(stmdb sp!,{imm0,imm2})
2990        __(mov arg_x,#0)
2991        __(mov temp0,#0)
2992        __(mov temp1,#0)
2993        __(mov temp2,#0)
2994        __(mov allocptr,#VOID_ALLOCPTR)
2995        __(mov fn,#0)
2996        __(ldr vsp,[rcontext,#tcr.save_vsp])
2997        __(mov imm0,#TCR_STATE_LISP)
2998        __(str imm0,[rcontext,#tcr.valence])
2999        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
3000        __(set_nargs(2))
3001        __(ref_nrs_symbol(fname,callbacks,imm0))
3002        __(ldr nfn,[fname,#symbol.fcell])
3003        __(ldr lr,[nfn,#_function.entrypoint])
3004        __(blx lr)
3005        __(str vsp,[rcontext,#tcr.save_vsp])
3006        __(ldr imm1,[sp,#4])
3007        __(str vsp,[rcontext,#tcr.last_lisp_frame])
3008        __(str allocptr,[rcontext,#tcr.save_allocptr])
3009        __(mov imm0,#TCR_STATE_FOREIGN)
3010        __(str imm0,[rcontext,#tcr.valence])
3011        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
3012        __(ldmia sp!,{r0,r1})
3013        __(add sp,sp,#4*node_size)
3014        __(bx lr)
3015       
3016/*  EOF, basically  */
3017       
3018_exportfn(C(misc_ref_common))
3019        __(adr imm0,(local_label(misc_ref_jmp)))
3020        __(ldr pc,[imm0,imm1,lsl #2])
3021
3022local_label(misc_ref_jmp):         
3023        /* 00-0f  */
3024        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
3025       
3026        .long local_label(misc_ref_invalid) /* 01 cons  */
3027        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
3028        .long local_label(misc_ref_invalid) /* 03 imm  */
3029        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
3030        .long local_label(misc_ref_invalid) /* 05 nil  */
3031        .long local_label(misc_ref_invalid) /* 06 misc  */
3032        .long local_label(misc_ref_u32) /* 07 bignum  */
3033        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
3034        .long local_label(misc_ref_invalid) /* 09 cons  */
3035        .long local_label(misc_ref_node) /* 0a ratio  */
3036        .long local_label(misc_ref_invalid) /* 0b imm  */
3037        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
3038        .long local_label(misc_ref_invalid) /* 0d nil  */
3039        .long local_label(misc_ref_invalid) /* 0e misc  */
3040        .long local_label(misc_ref_u32) /* 0f single_float  */
3041        /* 10-1f  */
3042        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
3043        .long local_label(misc_ref_invalid) /* 11 cons  */
3044        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
3045        .long local_label(misc_ref_invalid) /* 13 imm  */
3046        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
3047        .long local_label(misc_ref_invalid) /* 15 nil  */
3048        .long local_label(misc_ref_invalid) /* 16 misc  */
3049        .long local_label(misc_ref_u32) /* 17 double_float  */
3050        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
3051        .long local_label(misc_ref_invalid) /* 19 cons  */
3052        .long local_label(misc_ref_node) /* 1a complex  */
3053        .long local_label(misc_ref_invalid) /* 1b imm  */
3054        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
3055        .long local_label(misc_ref_invalid) /* 1d nil  */
3056        .long local_label(misc_ref_invalid) /* 1e misc  */
3057        .long local_label(misc_ref_u32) /* 1f macptr  */
3058        /* 20-2f  */
3059        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
3060        .long local_label(misc_ref_invalid) /* 21 cons  */
3061        .long local_label(misc_ref_node) /* 22 catch_frame  */
3062        .long local_label(misc_ref_invalid) /* 23 imm  */
3063        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
3064        .long local_label(misc_ref_invalid) /* 25 nil  */
3065        .long local_label(misc_ref_invalid) /* 26 misc  */
3066        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
3067        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
3068        .long local_label(misc_ref_invalid) /* 29 cons  */
3069        .long local_label(misc_ref_node) /* 2a function  */
3070        .long local_label(misc_ref_invalid) /* 2b imm  */
3071        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
3072        .long local_label(misc_ref_invalid) /* 2d nil  */
3073        .long local_label(misc_ref_invalid) /* 2e misc  */
3074        .long local_label(misc_ref_u32) /* 2f code_vector  */
3075        /* 30-3f  */
3076        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
3077        .long local_label(misc_ref_invalid) /* 31 cons  */
3078        .long local_label(misc_ref_node) /* 32 lisp_thread  */
3079        .long local_label(misc_ref_invalid) /* 33 imm  */
3080        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
3081        .long local_label(misc_ref_invalid) /* 35 nil  */
3082        .long local_label(misc_ref_invalid) /* 36 misc  */
3083        .long local_label(misc_ref_u32) /* 37 creole  */
3084        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
3085        .long local_label(misc_ref_invalid) /* 39 cons  */
3086        .long local_label(misc_ref_node) /* 3a symbol  */
3087        .long local_label(misc_ref_invalid) /* 3b imm  */
3088        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
3089        .long local_label(misc_ref_invalid) /* 3d nil  */
3090        .long local_label(misc_ref_invalid) /* 3e misc  */
3091        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
3092        /* 40-4f  */
3093        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
3094        .long local_label(misc_ref_invalid) /* 41 cons  */
3095        .long local_label(misc_ref_node) /* 42 lock  */
3096        .long local_label(misc_ref_invalid) /* 43 imm  */
3097        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
3098        .long local_label(misc_ref_invalid) /* 45 nil  */
3099        .long local_label(misc_ref_invalid) /* 46 misc  */
3100        .long local_label(misc_ref_invalid) /* 47 immheader  */
3101        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
3102        .long local_label(misc_ref_invalid) /* 49 cons  */
3103        .long local_label(misc_ref_node) /* 4a hash_vector  */
3104        .long local_label(misc_ref_invalid) /* 4b imm  */
3105        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
3106        .long local_label(misc_ref_invalid) /* 4d nil  */
3107        .long local_label(misc_ref_invalid) /* 4e misc  */
3108        .long local_label(misc_ref_invalid) /* 4f immheader  */
3109        /* 50-5f  */
3110        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
3111        .long local_label(misc_ref_invalid) /* 51 cons  */
3112        .long local_label(misc_ref_node) /* 52 pool  */
3113        .long local_label(misc_ref_invalid) /* 53 imm  */
3114        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
3115        .long local_label(misc_ref_invalid) /* 55 nil  */
3116        .long local_label(misc_ref_invalid) /* 56 misc  */
3117        .long local_label(misc_ref_invalid) /* 57 immheader  */
3118        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
3119        .long local_label(misc_ref_invalid) /* 59 cons  */
3120        .long local_label(misc_ref_node) /* 5a weak  */
3121        .long local_label(misc_ref_invalid) /* 5b imm  */
3122        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
3123        .long local_label(misc_ref_invalid) /* 5d nil  */
3124        .long local_label(misc_ref_invalid) /* 5e misc  */
3125        .long local_label(misc_ref_invalid) /* 5f immheader  */
3126        /* 60-6f  */
3127        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
3128        .long local_label(misc_ref_invalid) /* 61 cons  */
3129        .long local_label(misc_ref_node) /* 62 package  */
3130        .long local_label(misc_ref_invalid) /* 63 imm  */
3131        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
3132        .long local_label(misc_ref_invalid) /* 65 nil  */
3133        .long local_label(misc_ref_invalid) /* 66 misc  */
3134        .long local_label(misc_ref_invalid) /* 67 immheader  */
3135        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
3136        .long local_label(misc_ref_invalid) /* 69 cons  */
3137        .long local_label(misc_ref_node) /* 6a slot_vector  */
3138        .long local_label(misc_ref_invalid) /* 6b imm  */
3139        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
3140        .long local_label(misc_ref_invalid) /* 6d nil  */
3141        .long local_label(misc_ref_invalid) /* 6e misc  */
3142        .long local_label(misc_ref_invalid) /* 6f immheader  */
3143        /* 70-7f  */
3144        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
3145        .long local_label(misc_ref_invalid) /* 71 cons  */
3146        .long local_label(misc_ref_node) /* 72 instance  */
3147        .long local_label(misc_ref_invalid) /* 73 imm  */
3148        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
3149        .long local_label(misc_ref_invalid) /* 75 nil  */
3150        .long local_label(misc_ref_invalid) /* 76 misc  */
3151        .long local_label(misc_ref_invalid) /* 77 immheader  */
3152        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
3153        .long local_label(misc_ref_invalid) /* 79 cons  */
3154        .long local_label(misc_ref_node) /* 7a struct  */
3155        .long local_label(misc_ref_invalid) /* 7b imm  */
3156        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
3157        .long local_label(misc_ref_invalid) /* 7d nil  */
3158        .long local_label(misc_ref_invalid) /* 7e misc  */
3159        .long local_label(misc_ref_invalid) /* 7f immheader  */
3160        /* 80-8f  */
3161        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
3162        .long local_label(misc_ref_invalid) /* 81 cons  */
3163        .long local_label(misc_ref_node) /* 82 istruct  */
3164        .long local_label(misc_ref_invalid) /* 83 imm  */
3165        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
3166        .long local_label(misc_ref_invalid) /* 85 nil  */
3167        .long local_label(misc_ref_invalid) /* 86 misc  */
3168        .long local_label(misc_ref_invalid) /* 87 immheader  */
3169        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
3170        .long local_label(misc_ref_invalid) /* 89 cons  */
3171        .long local_label(misc_ref_node) /* 8a value_cell  */
3172        .long local_label(misc_ref_invalid) /* 8b imm  */
3173        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
3174        .long local_label(misc_ref_invalid) /* 8d nil  */
3175        .long local_label(misc_ref_invalid) /* 8e misc  */
3176        .long local_label(misc_ref_invalid) /* 8f immheader  */
3177        /* 90-9f  */
3178        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
3179        .long local_label(misc_ref_invalid) /* 91 cons  */
3180        .long local_label(misc_ref_node) /* 92 xfunction  */
3181        .long local_label(misc_ref_invalid) /* 93 imm  */
3182        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
3183        .long local_label(misc_ref_invalid) /* 95 nil  */
3184        .long local_label(misc_ref_invalid) /* 96 misc  */
3185        .long local_label(misc_ref_invalid) /* 97 immheader  */
3186        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
3187        .long local_label(misc_ref_invalid) /* 99 cons  */
3188        .long local_label(misc_ref_node) /* 9a arrayN  */
3189        .long local_label(misc_ref_invalid) /* 9b imm  */
3190        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
3191        .long local_label(misc_ref_invalid) /* 9d nil  */
3192        .long local_label(misc_ref_invalid) /* 9e misc  */
3193        .long local_label(misc_ref_invalid) /* 9f immheader  */
3194        /* a0-af  */
3195        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
3196        .long local_label(misc_ref_invalid) /* a1 cons  */
3197        .long local_label(misc_ref_node) /* a2 vectorH  */
3198        .long local_label(misc_ref_invalid) /* a3 imm  */
3199        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
3200        .long local_label(misc_ref_invalid) /* a5 nil  */
3201        .long local_label(misc_ref_invalid) /* a6 misc  */
3202        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
3203        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
3204        .long local_label(misc_ref_invalid) /* a9 cons  */
3205        .long local_label(misc_ref_node) /* aa simple_vector  */
3206        .long local_label(misc_ref_invalid) /* ab imm  */
3207        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
3208        .long local_label(misc_ref_invalid) /* ad nil  */
3209        .long local_label(misc_ref_invalid) /* ae misc  */
3210        .long local_label(misc_ref_u32) /* af u32  */
3211        /* b0-bf  */
3212        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
3213        .long local_label(misc_ref_invalid) /* b1 cons  */
3214        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
3215        .long local_label(misc_ref_invalid) /* b3 imm  */
3216        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
3217        .long local_label(misc_ref_invalid) /* b5 nil  */
3218        .long local_label(misc_ref_invalid) /* b6 misc  */
3219        .long local_label(misc_ref_s32) /* b7 s32  */
3220        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
3221        .long local_label(misc_ref_invalid) /* b9 cons  */
3222        .long local_label(misc_ref_invalid) /* ba nodeheader  */
3223        .long local_label(misc_ref_invalid) /* bb imm  */
3224        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
3225        .long local_label(misc_ref_invalid) /* bd nil  */
3226        .long local_label(misc_ref_invalid) /* be misc  */
3227        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
3228        /* c0-cf  */
3229        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
3230        .long local_label(misc_ref_invalid) /* c1 cons  */
3231        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
3232        .long local_label(misc_ref_invalid) /* c3 imm  */
3233        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
3234        .long local_label(misc_ref_invalid) /* c5 nil  */
3235        .long local_label(misc_ref_invalid) /* c6 misc  */
3236        .long local_label(misc_ref_new_string) /* c7 new_string  */
3237        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
3238        .long local_label(misc_ref_invalid) /* c9 cons  */
3239        .long local_label(misc_ref_invalid) /* ca nodeheader  */
3240        .long local_label(misc_ref_invalid) /* cb imm  */
3241        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
3242        .long local_label(misc_ref_invalid) /* cd nil  */
3243        .long local_label(misc_ref_invalid) /* ce misc  */
3244        .long local_label(misc_ref_u8) /* cf u8  */
3245        /* d0-df  */
3246        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
3247        .long local_label(misc_ref_invalid) /* d1 cons  */
3248        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
3249        .long local_label(misc_ref_invalid) /* d3 imm  */
3250        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
3251        .long local_label(misc_ref_invalid) /* d5 nil  */
3252        .long local_label(misc_ref_invalid) /* d6 misc  */
3253        .long local_label(misc_ref_s8)      /* d7 s8  */
3254        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
3255        .long local_label(misc_ref_invalid) /* d9 cons  */
3256        .long local_label(misc_ref_invalid) /* da nodeheader  */
3257        .long local_label(misc_ref_invalid) /* db imm  */
3258        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
3259        .long local_label(misc_ref_invalid) /* dd nil  */
3260        .long local_label(misc_ref_invalid) /* de misc  */
3261        .long local_label(misc_ref_old_string) /* df (old)subtag_simple_base_string  */
3262        /* e0-ef  */
3263        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
3264        .long local_label(misc_ref_invalid) /* e1 cons  */
3265        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
3266        .long local_label(misc_ref_invalid) /* e3 imm  */
3267        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
3268        .long local_label(misc_ref_invalid) /* e5 nil  */
3269        .long local_label(misc_ref_invalid) /* e6 misc  */
3270        .long local_label(misc_ref_u16) /* e7 u16  */
3271        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
3272        .long local_label(misc_ref_invalid) /* e9 cons  */
3273        .long local_label(misc_ref_invalid) /* ea nodeheader  */
3274        .long local_label(misc_ref_invalid) /* eb imm  */
3275        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
3276        .long local_label(misc_ref_invalid) /* ed nil  */
3277        .long local_label(misc_ref_invalid) /* ee misc  */
3278        .long local_label(misc_ref_s16) /* ef s16  */
3279        /* f0-ff  */
3280        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
3281        .long local_label(misc_ref_invalid) /* f1 cons  */
3282        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
3283        .long local_label(misc_ref_invalid) /* f3 imm  */
3284        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
3285        .long local_label(misc_ref_invalid) /* f5 nil  */
3286        .long local_label(misc_ref_invalid) /* f6 misc  */
3287        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
3288        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
3289        .long local_label(misc_ref_invalid) /* f9 cons  */
3290        .long local_label(misc_ref_invalid) /* fa nodeheader  */
3291        .long local_label(misc_ref_invalid) /* fb imm  */
3292        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
3293        .long local_label(misc_ref_invalid) /* fd nil  */
3294        .long local_label(misc_ref_invalid) /* fe misc  */
3295        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
3296
3297local_label(misc_ref_node):       
3298        /* A node vector.  */
3299        __(add imm0,arg_z,#misc_data_offset)
3300        __(ldr  arg_z,[arg_y,imm0])
3301        __(bx lr)
3302local_label(misc_ref_single_float_vector):       
3303        __(add imm0,arg_z,misc_data_offset)
3304        __(movc16(imm1,single_float_header))
3305        __(ldr imm0,[arg_y,imm0])
3306        __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
3307        __(str imm0,[arg_z,#single_float.value])
3308        __(bx lr)
3309local_label(misc_ref_new_string):       
3310        __(add imm0,arg_z,#misc_data_offset)
3311        __(ldr imm0,[arg_y,imm0])
3312        __(mov arg_z,imm0,lsl #charcode_shift)
3313        __(orr arg_z,arg_z,#subtag_character)
3314        __(bx lr)
3315local_label(misc_ref_s32):       
3316        __(add imm0,arg_z,#misc_data_offset)
3317        __(ldr imm0,[arg_y,imm0])
3318        __(b _SPmakes32)
3319local_label(misc_ref_fixnum_vector):   
3320        __(add imm0,arg_z,#misc_data_offset)
3321        __(ldr imm0,[arg_y,imm0])
3322        __(box_fixnum(arg_z,imm0))
3323        __(bx lr)       
3324local_label(misc_ref_u32):       
3325        __(add imm0,arg_z,#misc_data_offset)
3326        __(ldr imm0,[arg_y,imm0])
3327        __(b _SPmakeu32)
3328local_label(misc_ref_double_float_vector):     
3329        __(mov imm0,arg_z,lsl #1)
3330        __(add imm0,imm0,#misc_dfloat_offset)
3331        __(ldrd imm0,imm1,[arg_y,imm0])
3332        __(movc16(imm2,double_float_header))
3333        __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
3334        __(strd imm0,imm1,[arg_z,#double_float.value])
3335        __(bx lr)
3336local_label(misc_ref_bit_vector):
3337        __(mov imm1,#nbits_in_word-1)
3338        __(and imm1,imm1,arg_z,lsr #2)
3339        __(mov imm2,#1)
3340        __(mov imm2,imm2,lsl imm1)
3341        __(mov imm0,arg_z,lsr #5+fixnumshift)
3342        __(mov imm0,imm0,lsl #2)
3343        __(add imm0,imm0,#misc_data_offset)
3344        __(mov arg_z,#0)
3345        __(ldr imm0,[arg_y,imm0])
3346        __(tst imm0,imm2)
3347        __(addne arg_z,arg_z,#fixnumone)
3348        __(bx lr)
3349local_label(misc_ref_s8):       
3350        __(mov imm0,arg_z,lsr #2)
3351        __(add imm0,imm0,#misc_data_offset)
3352        __(ldsb imm0,[arg_y,imm0])
3353        __(box_fixnum(arg_z,imm0))
3354        __(bx lr)
3355local_label(misc_ref_u8):       
3356        __(mov imm0,arg_z,lsr #2)
3357        __(add imm0,imm0,#misc_data_offset)
3358        __(ldrb imm0,[arg_y,imm0])
3359        __(box_fixnum(arg_z,imm0))
3360        __(bx lr)
3361local_label(misc_ref_old_string):         
3362        __(mov imm0,arg_z,lsr #2)
3363        __(add imm0,imm0,#misc_data_offset)
3364        __(ldrb imm0,[arg_y,imm0])
3365        __(mov arg_z,imm0,lsl #charcode_shift)
3366        __(orr arg_z,arg_z,#subtag_character)
3367        __(bx lr)
3368local_label(misc_ref_u16):       
3369        __(mov imm0,arg_z,lsr #1)     
3370        __(add imm0,imm0,#misc_data_offset)
3371        __(ldrh imm0,[arg_y,imm0])
3372        __(box_fixnum(arg_z,imm0))
3373        __(bx lr)
3374local_label(misc_ref_s16):             
3375        __(mov imm0,arg_z,lsr #1)     
3376        __(add imm0,imm0,#misc_data_offset)
3377        __(ldrsh imm0,[arg_y,imm0])
3378        __(box_fixnum(arg_z,imm0))
3379        __(bx lr)
3380local_label(misc_ref_invalid):
3381        __(mov arg_x,#XBADVEC)
3382        __(set_nargs(3))
3383        __(b _SPksignalerr)       
3384_endfn
3385       
3386_exportfn(C(misc_set_common))
3387        __(adr imm0,local_label(misc_set_jmp))
3388        __(ldr pc,[imm0,imm1,lsl #2])
3389local_label(misc_set_jmp):             
3390        /* 00-0f  */
3391        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
3392        .long local_label(misc_set_invalid) /* 01 cons  */
3393        .long local_label(misc_set_invalid) /* 02 nodeheader  */
3394        .long local_label(misc_set_invalid) /* 03 imm  */
3395        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
3396        .long local_label(misc_set_invalid) /* 05 nil  */
3397        .long local_label(misc_set_invalid) /* 06 misc  */
3398        .long local_label(misc_set_u32) /* 07 bignum  */
3399        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
3400        .long local_label(misc_set_invalid) /* 09 cons  */
3401        .long _SPgvset /* 0a ratio  */
3402        .long local_label(misc_set_invalid) /* 0b imm  */
3403        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
3404        .long local_label(misc_set_invalid) /* 0d nil  */
3405        .long local_label(misc_set_invalid) /* 0e misc  */
3406        .long local_label(misc_set_u32) /* 0f single_float  */
3407        /* 10-1f  */
3408        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
3409        .long local_label(misc_set_invalid) /* 11 cons  */
3410        .long local_label(misc_set_invalid) /* 12 nodeheader  */
3411        .long local_label(misc_set_invalid) /* 13 imm  */
3412        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
3413        .long local_label(misc_set_invalid) /* 15 nil  */
3414        .long local_label(misc_set_invalid) /* 16 misc  */
3415        .long local_label(misc_set_u32) /* 17 double_float  */
3416        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
3417        .long local_label(misc_set_invalid) /* 19 cons  */
3418        .long _SPgvset /* 1a complex  */
3419        .long local_label(misc_set_invalid) /* 1b imm  */
3420        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
3421        .long local_label(misc_set_invalid) /* 1d nil  */
3422        .long local_label(misc_set_invalid) /* 1e misc  */
3423        .long local_label(misc_set_u32) /* 1f macptr  */
3424        /* 20-2f  */
3425        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
3426        .long local_label(misc_set_invalid) /* 21 cons  */
3427        .long _SPgvset /* 22 catch_frame  */
3428        .long local_label(misc_set_invalid) /* 23 imm  */
3429        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
3430        .long local_label(misc_set_invalid) /* 25 nil  */
3431        .long local_label(misc_set_invalid) /* 26 misc  */
3432        .long local_label(misc_set_u32) /* 27 dead_macptr  */
3433        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
3434        .long local_label(misc_set_invalid) /* 29 cons  */
3435        .long _SPgvset /* 2a function  */
3436        .long local_label(misc_set_invalid) /* 2b imm  */
3437        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
3438        .long local_label(misc_set_invalid) /* 2d nil  */
3439        .long local_label(misc_set_invalid) /* 2e misc  */
3440        .long local_label(misc_set_u32) /* 2f code_vector  */
3441        /* 30-3f  */
3442        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
3443        .long local_label(misc_set_invalid) /* 31 cons  */
3444        .long _SPgvset /* 32 lisp_thread  */
3445        .long local_label(misc_set_invalid) /* 33 imm  */
3446        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
3447        .long local_label(misc_set_invalid) /* 35 nil  */
3448        .long local_label(misc_set_invalid) /* 36 misc  */
3449        .long local_label(misc_set_u32) /* 37 creole  */
3450        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
3451        .long local_label(misc_set_invalid) /* 39 cons  */
3452        .long _SPgvset /* 3a symbol  */
3453        .long local_label(misc_set_invalid) /* 3b imm  */
3454        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
3455        .long local_label(misc_set_invalid) /* 3d nil  */
3456        .long local_label(misc_set_invalid) /* 3e misc  */
3457        .long local_label(misc_set_u32) /* 3f xcode_vector  */
3458        /* 40-4f  */
3459        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
3460        .long local_label(misc_set_invalid) /* 41 cons  */
3461        .long _SPgvset /* 42 lock  */
3462        .long local_label(misc_set_invalid) /* 43 imm  */
3463        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
3464        .long local_label(misc_set_invalid) /* 45 nil  */
3465        .long local_label(misc_set_invalid) /* 46 misc  */
3466        .long local_label(misc_set_invalid) /* 47 immheader  */
3467        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
3468        .long local_label(misc_set_invalid) /* 49 cons  */
3469        .long _SPgvset /* 4a hash_vector  */
3470        .long local_label(misc_set_invalid) /* 4b imm  */
3471        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
3472        .long local_label(misc_set_invalid) /* 4d nil  */
3473        .long local_label(misc_set_invalid) /* 4e misc  */
3474        .long local_label(misc_set_invalid) /* 4f immheader  */
3475        /* 50-5f  */
3476        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
3477        .long local_label(misc_set_invalid) /* 51 cons  */
3478        .long _SPgvset /* 52 pool  */
3479        .long local_label(misc_set_invalid) /* 53 imm  */
3480        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
3481        .long local_label(misc_set_invalid) /* 55 nil  */
3482        .long local_label(misc_set_invalid) /* 56 misc  */
3483        .long local_label(misc_set_invalid) /* 57 immheader  */
3484        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
3485        .long local_label(misc_set_invalid) /* 59 cons  */
3486        .long _SPgvset /* 5a weak  */
3487        .long local_label(misc_set_invalid) /* 5b imm  */
3488        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
3489        .long local_label(misc_set_invalid) /* 5d nil  */
3490        .long local_label(misc_set_invalid) /* 5e misc  */
3491        .long local_label(misc_set_invalid) /* 5f immheader  */
3492        /* 60-6f  */
3493        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
3494        .long local_label(misc_set_invalid) /* 61 cons  */
3495        .long _SPgvset /* 62 package  */
3496        .long local_label(misc_set_invalid) /* 63 imm  */
3497        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
3498        .long local_label(misc_set_invalid) /* 65 nil  */
3499        .long local_label(misc_set_invalid) /* 66 misc  */
3500        .long local_label(misc_set_invalid) /* 67 immheader  */
3501        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
3502        .long local_label(misc_set_invalid) /* 69 cons  */
3503        .long _SPgvset /* 6a slot_vector  */
3504        .long local_label(misc_set_invalid) /* 6b imm  */
3505        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
3506        .long local_label(misc_set_invalid) /* 6d nil  */
3507        .long local_label(misc_set_invalid) /* 6e misc  */
3508        .long local_label(misc_set_invalid) /* 6f immheader  */
3509        /* 70-7f  */
3510        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
3511        .long local_label(misc_set_invalid) /* 71 cons  */
3512        .long _SPgvset /* 72 instance  */
3513        .long local_label(misc_set_invalid) /* 73 imm  */
3514        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
3515        .long local_label(misc_set_invalid) /* 75 nil  */
3516        .long local_label(misc_set_invalid) /* 76 misc  */
3517        .long local_label(misc_set_invalid) /* 77 immheader  */
3518        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
3519        .long local_label(misc_set_invalid) /* 79 cons  */
3520        .long _SPgvset /* 7a struct  */
3521        .long local_label(misc_set_invalid) /* 7b imm  */
3522        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
3523        .long local_label(misc_set_invalid) /* 7d nil  */
3524        .long local_label(misc_set_invalid) /* 7e misc  */
3525        .long local_label(misc_set_invalid) /* 7f immheader  */
3526        /* 80-8f  */
3527        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
3528        .long local_label(misc_set_invalid) /* 81 cons  */
3529        .long _SPgvset /* 82 istruct  */
3530        .long local_label(misc_set_invalid) /* 83 imm  */
3531        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
3532        .long local_label(misc_set_invalid) /* 85 nil  */
3533        .long local_label(misc_set_invalid) /* 86 misc  */
3534        .long local_label(misc_set_invalid) /* 87 immheader  */
3535        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
3536        .long local_label(misc_set_invalid) /* 89 cons  */
3537        .long _SPgvset /* 8a value_cell  */
3538        .long local_label(misc_set_invalid) /* 8b imm  */
3539        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
3540        .long local_label(misc_set_invalid) /* 8d nil  */
3541        .long local_label(misc_set_invalid) /* 8e misc  */
3542        .long local_label(misc_set_invalid) /* 8f immheader  */
3543        /* 90-9f  */
3544        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
3545        .long local_label(misc_set_invalid) /* 91 cons  */
3546        .long _SPgvset /* 92 xfunction  */
3547        .long local_label(misc_set_invalid) /* 93 imm  */
3548        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
3549        .long local_label(misc_set_invalid) /* 95 nil  */
3550        .long local_label(misc_set_invalid) /* 96 misc  */
3551        .long local_label(misc_set_invalid) /* 97 immheader  */
3552        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
3553        .long local_label(misc_set_invalid) /* 99 cons  */
3554        .long _SPgvset /* 9a arrayH  */
3555        .long local_label(misc_set_invalid) /* 9b imm  */
3556        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
3557        .long local_label(misc_set_invalid) /* 9d nil  */
3558        .long local_label(misc_set_invalid) /* 9e misc  */
3559        .long local_label(misc_set_invalid) /* 9f immheader  */
3560        /* a0-af  */
3561        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
3562        .long local_label(misc_set_invalid) /* a1 cons  */
3563        .long _SPgvset /* a2 vectorH  */
3564        .long local_label(misc_set_invalid) /* a3 imm  */
3565        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
3566        .long local_label(misc_set_invalid) /* a5 nil  */
3567        .long local_label(misc_set_invalid) /* a6 misc  */
3568        .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
3569        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
3570        .long local_label(misc_set_invalid) /* a9 cons  */
3571        .long _SPgvset /* aa vectorH  */
3572        .long local_label(misc_set_invalid) /* ab imm  */
3573        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
3574        .long local_label(misc_set_invalid) /* ad nil  */
3575        .long local_label(misc_set_invalid) /* ae misc  */
3576        .long local_label(misc_set_u32) /* af u32  */
3577        /* b0-bf  */
3578        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
3579        .long local_label(misc_set_invalid) /* b1 cons  */
3580        .long local_label(misc_set_invalid) /* b2 node  */
3581        .long local_label(misc_set_invalid) /* b3 imm  */
3582        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
3583        .long local_label(misc_set_invalid) /* b5 nil  */
3584        .long local_label(misc_set_invalid) /* b6 misc  */
3585        .long local_label(misc_set_s32) /* b7 s32  */
3586        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
3587        .long local_label(misc_set_invalid) /* b9 cons  */
3588        .long local_label(misc_set_invalid) /* ba nodeheader  */
3589        .long local_label(misc_set_invalid) /* bb imm  */
3590        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
3591        .long local_label(misc_set_invalid) /* bd nil  */
3592        .long local_label(misc_set_invalid) /* be misc  */
3593        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
3594        /* c0-cf  */
3595        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
3596        .long local_label(misc_set_invalid) /* c1 cons  */
3597        .long local_label(misc_set_invalid) /* c2 nodeheader  */
3598        .long local_label(misc_set_invalid) /* c3 imm  */
3599        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
3600        .long local_label(misc_set_invalid) /* c5 nil  */
3601        .long local_label(misc_set_invalid) /* c6 misc  */
3602        .long local_label(misc_set_new_string) /* c7 new_string  */
3603        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
3604        .long local_label(misc_set_invalid) /* c9 cons  */
3605        .long local_label(misc_set_invalid) /* ca nodeheader  */
3606        .long local_label(misc_set_invalid) /* cb imm  */
3607        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
3608        .long local_label(misc_set_invalid) /* cd nil  */
3609        .long local_label(misc_set_invalid) /* ce misc  */
3610        .long local_label(misc_set_u8) /* cf u8  */
3611        /* d0-df  */
3612        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
3613        .long local_label(misc_set_invalid) /* d1 cons  */
3614        .long local_label(misc_set_invalid) /* d2 nodeheader  */
3615        .long local_label(misc_set_invalid) /* d3 imm  */
3616        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
3617        .long local_label(misc_set_invalid) /* d5 nil  */
3618        .long local_label(misc_set_invalid) /* d6 misc  */
3619        .long local_label(misc_set_s8) /* d7 s8  */
3620        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
3621        .long local_label(misc_set_invalid) /* d9 cons  */
3622        .long local_label(misc_set_invalid) /* da nodeheader  */
3623        .long local_label(misc_set_invalid) /* db imm  */
3624        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
3625        .long local_label(misc_set_invalid) /* dd nil  */
3626        .long local_label(misc_set_invalid) /* de misc  */
3627        .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
3628        /* e0-ef  */
3629        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
3630        .long local_label(misc_set_invalid) /* e1 cons  */
3631        .long local_label(misc_set_invalid) /* e2 nodeheader  */
3632        .long local_label(misc_set_invalid) /* e3 imm  */
3633        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
3634        .long local_label(misc_set_invalid) /* e5 nil  */
3635        .long local_label(misc_set_invalid) /* e6 misc  */
3636        .long local_label(misc_set_u16) /* e7 u16  */
3637        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
3638        .long local_label(misc_set_invalid) /* e9 cons  */
3639        .long local_label(misc_set_invalid) /* ea nodeheader  */
3640        .long local_label(misc_set_invalid) /* eb imm  */
3641        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
3642        .long local_label(misc_set_invalid) /* ed nil  */
3643        .long local_label(misc_set_invalid) /* ee misc  */
3644        .long local_label(misc_set_s16) /* ef s16  */
3645        /* f0-ff  */
3646        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
3647        .long local_label(misc_set_invalid) /* f1 cons  */
3648        .long local_label(misc_set_invalid) /* f2 nodeheader  */
3649        .long local_label(misc_set_invalid) /* f3 imm  */
3650        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
3651        .long local_label(misc_set_invalid) /* f5 nil  */
3652        .long local_label(misc_set_invalid) /* f6 misc  */
3653        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
3654        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
3655        .long local_label(misc_set_invalid) /* f9 cons  */
3656        .long local_label(misc_set_invalid) /* fa nodeheader  */
3657        .long local_label(misc_set_invalid) /* fb imm  */
3658        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
3659        .long local_label(misc_set_invalid) /* fd nil  */
3660        .long local_label(misc_set_invalid) /* fe misc  */
3661        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
3662
3663local_label(misc_set_u32):       
3664        /* Either a non-negative fixnum, a positive one-digit bignum, */
3665        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
3666        __(add imm0,arg_y,#misc_data_offset)
3667        __(test_fixnum(arg_z))
3668        __(bne local_label(set_not_fixnum_u32))
3669        __(tst arg_z,#0x80000000)
3670        __(bne local_label(set_bad))
3671        __(unbox_fixnum(imm1,arg_z))
3672local_label(set_set32):         
3673        __(str imm1,[arg_x,imm0])
3674        __(bx lr)
3675local_label(set_not_fixnum_u32):
3676        __(extract_lisptag(imm1,arg_z))
3677        __(cmp imm1,#tag_misc)
3678        __(bne local_label(set_bad))
3679        __(movc16(imm2,one_digit_bignum_header))
3680        __(getvheader(imm1,arg_z))
3681        __(cmp imm1,imm2)
3682        __(bne local_label(set_not_1_digit_u32))
3683        __(ldr imm1,[arg_z,#misc_data_offset])
3684        __(cmp imm1,#0)
3685        __(bge local_label(set_set32))
3686        __(b local_label(set_bad))
3687local_label(set_not_1_digit_u32):
3688        __(movc16(imm2,two_digit_bignum_header))
3689        __(cmp imm1,imm2)
3690        __(bne local_label(set_bad))
3691        __(vrefr(imm2,arg_z,1))
3692        __(vrefr(imm1,arg_z,0))
3693        __(cmp imm2,#0)
3694        __(beq local_label(set_set32))
3695local_label(set_bad):
3696        /* arg_z does not match the array-element-type of arg_x.  */
3697        __(mov arg_y,arg_z)
3698        __(mov arg_z,arg_x)
3699        __(mov arg_x,#XNOTELT)
3700        __(set_nargs(3))
3701        __(b _SPksignalerr)
3702local_label(misc_set_fixnum_vector):   
3703        __(add imm0,arg_y,#misc_data_offset)
3704        __(test_fixnum(arg_z))
3705        __(bne local_label(set_bad))
3706        __(unbox_fixnum(imm1,arg_z))
3707        __(str imm1,[arg_x,imm0])
3708        __(bx lr)
3709local_label(misc_set_new_string):   
3710        __(add imm0,arg_y,#misc_data_offset)
3711        __(extract_lowbyte(imm2,arg_z))
3712        __(cmp imm2,#subtag_character)
3713        __(bne local_label(set_bad))
3714        __(unbox_character(imm1,arg_z))
3715        __(str imm1,[arg_x,imm0])
3716        __(bx lr)
3717local_label(misc_set_s32):
3718        __(add imm0,arg_y,#misc_data_offset)
3719        __(test_fixnum(arg_z))
3720        __(moveq imm1,arg_z,asr #fixnumshift)
3721        __(beq local_label(set_set32))
3722        __(extract_lisptag(imm2,arg_z))
3723        __(cmp imm2,#tag_misc)
3724        __(bne local_label(set_bad))
3725        __(movc16(imm1,one_digit_bignum_header))
3726        __(getvheader(imm2,arg_z))
3727        __(cmp imm2,imm1)
3728        __(vrefr(imm1,arg_z,0))
3729        __(beq local_label(set_set32))
3730        __(b local_label(set_bad))
3731local_label(misc_set_single_float_vector):
3732        __(add imm0,arg_y,#misc_data_offset)
3733        __(extract_typecode(imm2,arg_z))
3734        __(cmp imm2,#subtag_single_float)
3735        __(bne local_label(set_bad))
3736        __(ldr imm1,[arg_z,#single_float.value])
3737        __(str imm1,[arg_x,imm0])
3738        __(bx lr)
3739local_label(misc_set_u8):               
3740        __(mov imm0,arg_y,lsr #2)
3741        __(add imm0,imm0,#misc_data_offset)
3742        __(mov imm2,#~(0xff<<fixnumshift))
3743        __(tst arg_z,imm2)
3744        __(bne local_label(set_bad))
3745        __(unbox_fixnum(imm1,arg_z))
3746        __(strb imm1,[arg_x,imm0])
3747        __(bx lr)
3748local_label(misc_set_old_string):
3749        __(mov imm0,arg_y,lsr #2)
3750        __(add imm0,imm0,#misc_data_offset)
3751        __(extract_lowbyte(imm2,arg_z))
3752        __(cmp imm2,#subtag_character)
3753        __(unbox_character(imm1,arg_z))
3754        __(bne local_label(set_bad))
3755        __(strb imm1,[arg_x,imm0])
3756        __(bx lr)
3757local_label(misc_set_s8):
3758        __(mov imm0,arg_y,lsr #2)
3759        __(add imm0,imm0,#misc_data_offset)
3760        __(test_fixnum(arg_z))
3761        __(bne local_label(set_bad))
3762        __(unbox_fixnum(imm1,arg_z))
3763        __(mov imm2,imm1,lsl #32-8)
3764        __(cmp imm1,imm2,asr #32-8)
3765        __(bne local_label(set_bad))
3766        __(strb imm1,[arg_x,imm0])
3767        __(bx lr)
3768local_label(misc_set_u16):         
3769        __(mov imm0,arg_y,lsr #1)
3770        __(add imm0,imm0,#misc_data_offset)
3771        __(test_fixnum(arg_z))
3772        __(bne local_label(set_bad))
3773        __(unbox_fixnum(imm1,arg_z))
3774        __(mov imm2,imm1,lsl #16)
3775        __(cmp imm1,imm2,lsr #16)
3776        __(bne local_label(set_bad))
3777        __(strh imm1,[arg_x,imm0])
3778        __(bx lr)
3779local_label(misc_set_s16):
3780        __(mov imm0,arg_y,lsr #1)
3781        __(add imm0,imm0,#misc_data_offset)
3782        __(test_fixnum(arg_z))
3783        __(bne local_label(set_bad))
3784        __(unbox_fixnum(imm1,arg_z))
3785        __(mov imm2,imm1,lsl #16)
3786        __(cmp imm1,imm2,asr #16)
3787        __(bne local_label(set_bad))
3788        __(strh imm1,[arg_x,imm0])
3789        __(bx lr)
3790local_label(misc_set_bit_vector):
3791        __(bics imm0,arg_z,#fixnumone)
3792        __(bne local_label(set_bad))
3793        __(mov imm2,#31)
3794        __(and imm2,imm1,arg_y,lsr #2)
3795        __(mov imm1,#1)
3796        __(mov imm1,imm1,lsl imm2)
3797        __(mov imm0,arg_y,lsr #fixnumshift+5)
3798        __(mov imm0,imm0,lsl #2)
3799        __(add imm0,imm0,#misc_data_offset)
3800        __(cmp arg_z,#0)
3801        __(ldr imm2,[arg_x,imm0])
3802        __(orrne imm2,imm2,imm1)
3803        __(biceq imm2,imm2,imm1)
3804        __(str imm2,[arg_x,imm0])
3805        __(bx lr)
3806
3807local_label(misc_set_double_float_vector):
3808        __(extract_subtag(imm2,arg_z))
3809        __(cmp imm2,#subtag_double_float)
3810        __(bne local_label(set_bad))
3811        __(ldrd imm0,imm1,[arg_z,#misc_dfloat_offset])
3812        __(mov imm2,arg_y,lsl #1)
3813        __(add imm2,imm2,#misc_dfloat_offset)
3814        __(strd imm0,imm1,[arg_x,imm2])
3815        __(bx lr)
3816local_label(misc_set_invalid): 
3817        __(mov temp0,#XSETBADVEC)       
3818        __(set_nargs(4))
3819        __(vpush1(temp0))
3820        __(b _SPksignalerr)               
3821
3822       
3823/* temp0: (stack-consed) target catch frame, imm0: count of intervening  */
3824/* frames. If target isn't a multiple-value receiver, discard extra values */
3825/* (less hair, maybe.)  */
3826_exportfn(C(_throw_found))
3827        new_local_labels()
3828        __(ldr imm1,[temp0,#catch_frame.mvflag])
3829        __(cmp imm1,#0)
3830        __(mov fn,#0)
3831        __(add imm1,vsp,nargs)
3832        __(add imm1,imm1,#-node_size)
3833        __(bne local_label(throw_all_values))
3834        __(cmp nargs,#0)
3835        __(moveq imm1,#nil_value)
3836        __(set_nargs(1))
3837        __(streq imm1,[vsp,#-node_size]!)
3838        __(movne vsp,imm1)
3839local_label(throw_all_values): 
3840        __(bl _SPnthrowvalues) 
3841        __(ldr temp0,[rcontext,#tcr.catch_top])
3842        __(ldr imm1,[rcontext,#tcr.db_link])
3843        __(ldr imm0,[temp0,#catch_frame.db_link])
3844        __(cmp imm0,imm1)
3845        __(blne _SPunbind_to)
3846        __(ldr temp1,[temp0,#catch_frame.mvflag])
3847        __(ldr imm0,[temp0,#catch_frame.xframe])       
3848        __(ldr imm1,[temp0,#catch_frame.last_lisp_frame])
3849        __(cmp temp1,#0)
3850        __(str imm0,[rcontext,#tcr.xframe])
3851        __(str imm1,[rcontext,#tcr.last_lisp_frame])
3852        __(add imm0,vsp,nargs)
3853        __(sub sp,temp0,#fulltag_misc)
3854        __(ldr imm1,[sp,#catch_frame.size+lisp_frame.savevsp])
3855        __(ldreq arg_z,[imm0,#-node_size])
3856        __(beq local_label(throw_pushed_values))
3857        __(movs arg_x,nargs)
3858        __(b local_label(throw_push_test))
3859local_label(throw_push_loop):
3860        __(subs arg_x,arg_x,#fixnumone)
3861        __(ldr arg_y,[imm0,#-node_size]!)
3862        __(push1(arg_y,imm1))
3863local_label(throw_push_test):   
3864        __(bne local_label(throw_push_loop))
3865local_label(throw_pushed_values):
3866        __(mov vsp,imm1)
3867        __(ldr imm0,[temp0,#catch_frame.link])
3868        __(str imm0,[rcontext,#tcr.catch_top])
3869        __(ldr fn,[sp,#catch_frame.size+lisp_frame.savefn])
3870        __(ldr lr,[sp,#catch_frame.size+lisp_frame.savelr])
3871        __(add sp,sp,#catch_frame.size+lisp_frame.size)
3872        __(bx lr)
3873_endfn(C(_throw_found))       
3874
3875_exportfn(C(nthrow1v))
3876        new_local_labels()
3877local_label(_nthrow1v_nextframe):
3878        __(subs temp2,temp2,#fixnum_one)
3879        __(ldr temp0,[rcontext,#tcr.catch_top])
3880        __(ldr imm1,[rcontext,#tcr.db_link])
3881        __(set_nargs(1))
3882        __(blt local_label(_nthrow1v_done))
3883        __(ldr arg_y,[temp0,#catch_frame.link])
3884        __(ldr imm0,[temp0,#catch_frame.db_link])
3885        __(cmp imm0,imm1)
3886        __(str arg_y,[rcontext,#tcr.catch_top])
3887        __(ldr arg_y,[temp0,#catch_frame.xframe])
3888        __(str arg_y,[rcontext,#tcr.xframe])
3889        __(beq local_label(_nthrow1v_dont_unbind))
3890        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
3891local_label(_nthrow1v_dont_unbind):
3892        __(ldr temp1,[temp0,#catch_frame.catch_tag])
3893        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
3894        __(sub sp,temp0,#fulltag_misc)
3895        __(beq local_label(_nthrow1v_do_unwind))
3896        /* A catch frame.  If the last one, restore context from there.  */
3897        __(cmp temp2,#0)
3898        __(ldreq vsp,[sp,#catch_frame.size+lisp_frame.savevsp])
3899        __(add sp,sp,#catch_frame.size+lisp_frame.size)
3900        __(b local_label(_nthrow1v_nextframe))
3901local_label(_nthrow1v_do_unwind):
3902        /* This is harder, but not as hard (not as much BLTing) as the  */
3903        /* multiple-value case.  */
3904        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
3905        /* protect.  (Clever, eh ?)  */
3906        __(add sp,sp,#catch_frame.size)
3907        /* swp is deprecated on ARMv6+.  It's not useful as a basis
3908           for synchronization, but that's not why we're using it here. */
3909        __(mov imm1,#0)
3910        __(mov temp0,sp)
3911        __(mov imm0,#3<<num_subtag_bits)
3912        __(orr imm0,imm0,#subtag_simple_vector)
3913        __(stmdb sp!,{imm0,imm1,arg_z,temp2})
3914        __(add imm0,temp0,#lisp_frame.savelr)
3915        __(swp lr,lr,[imm0])
3916        __(ldr nfn,[temp0,#lisp_frame.savefn])
3917        __(str fn,[temp0,#lisp_frame.savefn])
3918        __(ldr vsp,[temp0,#lisp_frame.savevsp])
3919        __(mov fn,nfn)
3920        __(str imm1,[rcontext,#tcr.unwinding])
3921        __(blx lr)
3922        __(mov imm1,#1)
3923        __(ldr arg_z,[sp,#8])
3924        __(str imm1,[rcontext,#tcr.unwinding])
3925        __(ldr temp2,[sp,#12])
3926        __(add sp,sp,#4*node_size)
3927        __(restore_lisp_frame(imm0))
3928        __(b local_label(_nthrow1v_nextframe))
3929local_label(_nthrow1v_done):
3930        __(mov imm0,#0)
3931        __(str imm0,[rcontext,#tcr.unwinding])
3932        /* nargs has an undefined value here, so we can clobber it while */
3933        /* polling for a deferred interrupt  */
3934        __(check_pending_interrupt(nargs))
3935        __(bx lr)
3936_endfn       
3937
3938_exportfn(C(nthrownv))
3939        new_local_labels()
3940local_label(nthrownv_nextframe):
3941        __(subs temp2,temp2,#fixnum_one)
3942        __(ldr temp0,[rcontext,#tcr.catch_top])
3943        __(ldr imm1,[rcontext,#tcr.db_link])
3944        __(blt local_label(nthrownv_done))
3945        __(ldr arg_y,[temp0,#catch_frame.link])
3946        __(ldr imm0,[temp0,#catch_frame.db_link])
3947        __(cmp imm0,imm1)
3948        __(str arg_y,[rcontext,#tcr.catch_top])
3949        __(ldr arg_y,[temp0,#catch_frame.xframe])
3950        __(str arg_y,[rcontext,#tcr.xframe])
3951        __(beq local_label(nthrownv_dont_unbind))
3952        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
3953local_label(nthrownv_dont_unbind):
3954        __(ldr temp1,[temp0,#catch_frame.catch_tag])
3955        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
3956        __(sub sp,temp0,#fulltag_misc)
3957        __(beq local_label(nthrownv_do_unwind))
3958        __(cmp temp2,#0)
3959/* A catch frame.  If the last one, restore context from there.  */
3960        __(bne local_label(nthrownv_skip))
3961        __(ldr imm0,[sp,#catch_frame.size+lisp_frame.savevsp])
3962        __(add imm1,vsp,nargs)
3963        __(movs arg_z,nargs)
3964        __(b local_label(nthrownv_push_test))
3965local_label(nthrownv_push_loop):       
3966        __(subs arg_z,arg_z,#fixnumone)
3967        __(ldr temp1,[imm1,#-node_size]!)
3968        __(push1(temp1,imm0))
3969local_label(nthrownv_push_test):       
3970        __(bne local_label(nthrownv_push_loop))
3971        __(mov vsp,imm0)
3972local_label(nthrownv_skip):     
3973        __(add sp,sp,#catch_frame.size+lisp_frame.size)
3974        __(b local_label(nthrownv_nextframe))               
3975local_label(nthrownv_do_unwind):
3976        __(ldr arg_x,[temp0,#catch_frame.xframe])
3977        __(ldr arg_z,[temp0,#catch_frame.last_lisp_frame])
3978        __(sub sp,temp0,#fulltag_misc)
3979        __(str arg_x,[rcontext,#tcr.xframe])
3980        __(str arg_z,[rcontext,#tcr.last_lisp_frame])
3981        __(add sp,sp,#catch_frame.size)
3982        __(add imm1,nargs,#node_size)
3983        __(mov arg_z,sp)
3984        __(dnode_align(imm0,imm1,node_size))
3985        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
3986        __(orr imm1,imm1,#subtag_u32_vector)
3987        __(stack_allocate_zeroed_ivector(imm1,imm0))
3988        __(mov imm0,#subtag_simple_vector)
3989        __(strb imm0,[sp])
3990        __(str temp2,[sp,#node_size])
3991        __(add temp2,sp,#dnode_size)
3992        __(add temp2,temp2,nargs)
3993        __(add temp1,vsp,nargs)
3994        __(b local_label(nthrownv_tpushtest))
3995local_label(nthrownv_tpushloop):       
3996        __(ldr temp0,[temp1,#-node_size]!)
3997        __(push1(temp0,temp2))
3998local_label(nthrownv_tpushtest):       
3999        __(subs nargs,nargs,#fixnumone)
4000        __(bge local_label(nthrownv_tpushloop))
4001        __(mov imm1,#0)
4002        __(add imm0,arg_z,#lisp_frame.savelr)
4003        __(swp lr,lr,[imm0])
4004        __(ldr nfn,[arg_z,#lisp_frame.savefn])
4005        __(str fn,[arg_z,#lisp_frame.savefn])
4006        __(ldr vsp,[arg_z,#lisp_frame.savevsp])
4007        __(str imm1,[rcontext,#tcr.unwinding])
4008        __(mov fn,nfn)
4009        __(blx lr)
4010        __(mov imm1,#1)
4011        __(str imm1,[rcontext,#tcr.unwinding])
4012        __(ldr imm0,[sp])
4013        __(header_length(imm0,imm0))
4014        __(subs nargs,imm0,#node_size)
4015        __(add imm0,imm0,#node_size)
4016        __(add temp0,sp,imm0)
4017        __(mov imm0,nargs)
4018        __(add arg_z,temp0,#node_size)
4019        __(bic arg_z,arg_z,#fulltagmask)
4020        __(b local_label(nthrownv_tpoptest))
4021local_label(nthrownv_tpoploop): 
4022        __(subs imm0,imm0,#node_size)       
4023        __(vpush1(temp2))
4024local_label(nthrownv_tpoptest): 
4025        __(ldr temp2,[temp0,#-node_size]!)
4026        __(bne local_label(nthrownv_tpoploop))
4027        __(mov sp,arg_z)
4028        __(ldr fn,[sp,#lisp_frame.savefn])
4029        __(ldr lr,[sp,#lisp_frame.savelr])
4030        __(discard_lisp_frame())
4031        __(b local_label(nthrownv_nextframe))
4032local_label(nthrownv_done):     
4033        __(mov imm0,#0)
4034        __(str imm0,[rcontext,#tcr.unwinding])
4035        __(check_pending_interrupt(imm1))
4036        __(bx lr)
4037_endfn               
4038
4039_exportfn(C(progvsave))       
4040        /* Error if arg_z isn't a proper list.  That's unlikely, */
4041        /* but it's better to check now than to crash later. */
4042        __(cmp arg_z,#nil_value)
4043        __(mov arg_x,arg_z) /* fast  */
4044        __(mov temp1,arg_z) /* slow  */
4045        __(beq 9f)  /* Null list is proper  */
40460:
4047        __(trap_unless_list(arg_x,imm0))
4048        __(_cdr(temp2,arg_x)) /* (null (cdr fast)) ?  */
4049        __(trap_unless_list(temp2,imm0,cr0))
4050        __(cmp temp2,#nil_value)
4051        __(_cdr(arg_x,temp2))
4052        __(beq 9f)
4053        __(_cdr(temp1,temp1))
4054        __(cmp arg_x,temp1)
4055        __(bne 0b)
4056        __(mov arg_y,#XIMPROPERLIST)
4057        __(set_nargs(2))
4058        __(b _SPksignalerr)
40599:      /* Whew   */
4060 
4061        /* Next, determine the length of arg_y.  We  */
4062        /* know that it's a proper list.  */
4063        __(mov imm0,#0)
4064        __(mov arg_x,arg_y)
40651:
4066        __(cmp arg_x,#nil_value)
4067        __(addne imm0,imm0,#node_size)
4068        __(_cdr(arg_x,arg_x))
4069        __(bne 1b)
4070        /* imm0 is now (boxed) triplet count.  */
4071        /* Determine word count, add 1 (to align), and make room.  */
4072        /* if count is 0, make an empty tsp frame and exit  */
4073        __(cmp imm0,#0)
4074        __(add imm1,imm0,imm0,lsl #1)
4075        __(add imm1,imm1,#node_size) /* Room for binding count */
4076        __(dnode_align(imm2,imm1,node_size))
4077        __(bne 2f)
4078        __(movc16(imm0,make_header(1,subtag_simple_vector)))
4079        __(mov imm1,#0)
4080        __(stmdb sp!,{imm0,imm1})
4081        __(b 9f)
40822:
4083        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
4084        __(orr imm1,imm1,#subtag_u32_vector)
4085        __(mov temp1,sp)
4086        __(stack_allocate_zeroed_ivector(imm1,imm2))
4087        __(mov imm1,#subtag_simple_vector)
4088        __(strb imm1,[sp])
4089        __(str imm0,[sp,#node_size])
4090        __(ldr imm1,[rcontext,#tcr.db_link])
40913:      __(_car(temp0,arg_y))
4092        __(ldr imm0,[temp0,#symbol.binding_index])
4093        __(ldr imm2,[rcontext,#tcr.tlb_limit])
4094        __(_cdr(arg_y,arg_y))
4095        __(cmp imm2,imm0)
4096        __(uuo_tlb_too_small(ls,imm0))
4097        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
4098        __(ldr temp0,[arg_x,imm0])
4099        __(cmp arg_z,#nil_value)
4100        __(mov temp2,#unbound_marker)
4101        __(ldrne temp2,[arg_z,#cons.car])
4102        __(_cdr(arg_z,arg_z))
4103        __(cmp arg_y,#nil_value)
4104        __(push1(temp0,temp1))
4105        __(push1(imm0,temp1))
4106        __(push1(imm1,temp1))
4107        __(mov imm1,temp1)
4108        __(str temp2,[arg_x,imm0])
4109        __(bne 3b)
4110        __(str imm1,[rcontext,#tcr.db_link])
41119:             
4112        __(mov arg_z,#unbound_marker)
4113        __(mov imm2,#fixnum_one)
4114        __(mkcatch())       
4115        __(bx lr)
4116_endfn                               
4117               
4118/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
4119/* sure that there's an empty tsp frame to keep the compiler happy.  */
4120_exportfn(stack_misc_alloc_no_room)
4121        __(mov imm0,#stack_alloc_marker)
4122        __(mov imm1,sp)
4123        __(stmdb sp!,{imm0,imm1})
4124        __(b _SPmisc_alloc)
4125_endfn       
4126        _endfile
Note: See TracBrowser for help on using the repository browser.