source: trunk/source/lisp-kernel/arm-spentry.s @ 15541

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

Don't need pc_luser_xp() support for .SPatomic_incf_node if we use
the lr hack, so use the lr hack.

File size: 163.0 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):
24define(`_spentry',`ifdef(`__func_name',`_endfn',`')
25        _startfn(_SP$1)
26L__SP$1:                       
27        .line  __line__
28')
29
30
31define(`_endsubp',`
32        _endfn(_SP$1)
33# __line__
34')
35
36
37       
38
39define(`jump_builtin',`
40        ref_nrs_value(fname,builtin_functions)
41        set_nargs($2)
42        vrefr(fname,fname,$1)
43        jump_fname()
44')
45
46/* Set the _function.entrypoint locative in nfn - which pointed here -
47   to the address of the first instruction in the _function.codevector.
48   This must be the first ARM subprim. */
49
50_spentry(fix_nfn_entrypoint)
51        __(build_lisp_frame(imm0))
52        __(vpush1(arg_z))
53        __(ldr arg_z,[nfn,#_function.codevector])
54        __(add lr,arg_z,#misc_data_offset)
55        __(str lr,[nfn,#_function.entrypoint])
56        __(vpop1(arg_z))
57        __(restore_lisp_frame(imm0))
58        __(jump_nfn())
59
60       
61_spentry(builtin_plus)
62        __(test_two_fixnums(arg_y,arg_z,imm0))
63        __(bne 1f)
64        __(adds arg_z,arg_y,arg_z)
65        __(bxvc lr)
66        __(b _SPfix_overflow)
671:
68        __(jump_builtin(_builtin_plus,2))
69       
70_spentry(builtin_minus)
71        __(test_two_fixnums(arg_y,arg_z,imm0))
72        __(bne 1f)
73        __(subs arg_z,arg_y,arg_z)
74        __(bxvc lr)
75        __(b _SPfix_overflow)
761:
77        __(jump_builtin(_builtin_minus,2))
78
79_spentry(builtin_times)
80        __(test_two_fixnums(arg_y,arg_z,imm0))
81        __(bne 1f)
82        __(unbox_fixnum(imm2,arg_z))
83        __(unbox_fixnum(imm0,arg_y))
84        __(smull imm0,imm1,imm2,imm0)
85        __(b _SPmakes64)
86
871: __(jump_builtin(_builtin_times,2))
88
89_spentry(builtin_div)
90        __(jump_builtin(_builtin_div,2))
91
92_spentry(builtin_eq)
93        __(test_two_fixnums(arg_y,arg_z,imm0))
94        __(bne 1f)
95        __(cmp arg_y,arg_z)
96        __(mov arg_z,#nil_value)
97        __(addeq arg_z,arg_z,#t_offset)
98        __(bx lr)       
991:
100        __(jump_builtin(_builtin_eq,2))
101                       
102_spentry(builtin_ne)
103        __(test_two_fixnums(arg_y,arg_z,imm0))
104        __(bne 1f)
105        __(cmp arg_y,arg_z)
106        __(mov arg_z,#nil_value)
107        __(addne arg_z,arg_z,#t_offset)
108        __(bx lr)
1091:
110        __(jump_builtin(_builtin_ne,2))
111
112_spentry(builtin_gt)
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        __(addgt arg_z,arg_z,#t_offset)
118        __(bx lr)
1191:
120        __(jump_builtin(_builtin_gt,2))
121
122_spentry(builtin_ge)
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        __(addge arg_z,arg_z,#t_offset)
128        __(bx lr)
1291:
130        __(jump_builtin(_builtin_ge,2))
131
132_spentry(builtin_lt)
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        __(addlt arg_z,arg_z,#t_offset)
138        __(bx lr)
1391:
140        __(jump_builtin(_builtin_lt,2))
141
142_spentry(builtin_le)
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        __(addle arg_z,arg_z,#t_offset)
148        __(bx lr)
1491:
150        __(jump_builtin(_builtin_le,2))
151
152_spentry(builtin_eql)
1530:      __(cmp arg_y,arg_z)
154        __(beq 8f)
155        __(extract_fulltag(imm0,arg_y))
156        __(extract_fulltag(imm1,arg_z))
157        __(cmp imm0,imm1)
158        __(bne 9f)
159        __(cmp imm0,#fulltag_misc)
160        __(bne 9f)
161        __(extract_subtag(imm0,arg_y))
162        __(extract_subtag(imm1,arg_z))
163        __(cmp imm0,imm1)
164        __(bne 9f)
165        __(cmp imm0,#subtag_macptr)
166        __(cmpne imm0,#subtag_single_float)
167        __(bne 1f)
168        __(ldr imm0,[arg_y,#misc_data_offset])
169        __(ldr imm1,[arg_z,#misc_data_offset])
170        __(cmp imm0,imm1)
171        __(mov arg_z,#nil_value)
172        __(addeq arg_z,arg_z,#t_offset)
173        __(bx lr)
1741:      __(cmp imm0,#subtag_double_float)
175        __(bne 2f)
176        __(ldr imm0,[arg_y,#misc_dfloat_offset])
177        __(ldr imm1,[arg_z,#misc_dfloat_offset])
178        __(cmp imm0,imm1)
179        __(ldreq imm0,[arg_y,#misc_dfloat_offset+node_size])
180        __(ldreq imm1,[arg_z,#misc_dfloat_offset+node_size])
181        __(cmpeq imm0,imm1)
182        __(mov arg_z,#nil_value)
183        __(addeq arg_z,arg_z,#t_offset)
184        __(bx lr)
1852:      __(cmp imm0,#subtag_ratio)
186        __(cmpne imm0,#subtag_complex)
187        __(bne 3f)
188        __(ldr temp0,[arg_y,#ratio.denom])
189        __(ldr temp1,[arg_z,#ratio.denom])
190        __(stmdb vsp!,{temp0,temp1})
191        __(ldr arg_y,[arg_y,#ratio.numer])
192        __(ldr arg_z,[arg_z,#ratio.numer])
193        __(build_lisp_frame(imm0))
194        __(bl 0b)
195        __(cmp arg_z,#nil_value)
196        __(restore_lisp_frame(imm0))
197        __(ldmia vsp!,{arg_z,arg_y})
198        __(bne 0b)
199        __(mov arg_z,#nil_value)
200        __(bx lr)
2013:      __(cmp imm0,#subtag_bignum)
202        __(bne 9f)
203        __(getvheader(imm0,arg_y))
204        __(getvheader(imm1,arg_z))
205        __(cmp imm0,imm1)
206        __(bne 9f)
207        __(header_length(temp0,imm0))
208        __(mov imm2,#misc_data_offset)
2094:      __(ldr imm0,[arg_y,imm2])
210        __(ldr imm1,[arg_z,imm2])
211        __(cmp imm0,imm1)
212        __(bne 9f)
213        __(add imm2,imm2,#node_size)
214        __(subs temp0,temp0,#fixnumone)
215        __(bne 4b)               
2168:      __(mov arg_z,#nil_value)
217        __(add arg_z,arg_z,#t_offset)
218        __(bx lr)
2199:      __(mov arg_z,#nil_value)
220        __(bx lr)
221       
222_spentry(builtin_length)
223        __(extract_typecode(imm0,arg_z))
224        __(cmp imm0,#min_vector_subtag)
225        __(ldreq arg_z,[arg_z,#vectorH.logsize])
226        __(bxeq lr)
227        __(blo 1f)
228        __(vector_length(arg_z,arg_z,imm0))
229        __(bx lr)
2301:      __(cmp imm0,#tag_list)
231        __(bne 8f)
232        __(mov temp2,#-1<<fixnum_shift)
233        __(mov temp0,arg_z) /* fast pointer  */
234        __(mov temp1,arg_z) /* slow pointer  */
2352:      __(cmp temp0,#nil_value)
236        __(add temp2,temp2,#fixnumone)
237        __(beq 9f)
238        __(extract_lisptag(imm0,temp0))
239        __(cmp imm0,#tag_list)
240        __(bne 8f)
241        __(_cdr(temp0,temp0))
242        __(tst temp2,#fixnumone)
243        __(beq 2b)
244        __(_cdr(temp1,temp1))
245        __(cmp temp1,temp0)
246        __(bne 2b)
2478:
248        __(jump_builtin(_builtin_length,1))
2499:      __(mov arg_z,temp2)
250        __(bx lr)       
251
252_spentry(builtin_seqtype)
253        __(extract_typecode(imm0,arg_z))
254        __(cmp imm0,#min_vector_subtag)
255        __(movge arg_z,#nil_value)
256        __(bxge lr)
257        __(cmp imm0,#tag_list)
258        __(moveq arg_z,#nil_value)
259        __(addeq arg_z,arg_z,#t_offset)
260        __(bxeq lr)
261        __(jump_builtin(_builtin_seqtype,1))
262
263/* This is usually inlined these days */
264_spentry(builtin_assq)
265        __(b 2f)
2661:      __(trap_unless_list(arg_z,imm0))
267        __(_car(arg_x,arg_z))
268        __(_cdr(arg_z,arg_z))
269        __(cmp arg_x,#nil_value)
270        __(beq 2f)
271        __(trap_unless_list(arg_x,imm0))
272        __(_car(temp0,arg_x))
273        __(cmp temp0,arg_y)
274        __(bne 2f)
275        __(mov arg_z,arg_x)
276        __(bx lr)
2772:      __(cmp arg_z,#nil_value)
278        __(bne 1b)
279        __(bx lr)
280 
281_spentry(builtin_memq)
282        __(cmp arg_z,nil_value)
283        __(b 2f)
2841:      __(trap_unless_list(arg_z,imm0))
285        __(_car(arg_x,arg_z))
286        __(_cdr(temp0,arg_z))
287        __(cmp arg_x,arg_y)
288        __(bxeq lr)
289        __(cmp temp0,nil_value)
290        __(mov arg_z,temp0)
2912:      __(bne 1b)
292        __(bx lr)
293
294_spentry(builtin_logbitp)
295/* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
296        __(test_two_fixnums(arg_y,arg_z,imm0))
297        __(bne 1f)
298        __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
299        __(bhs 1f)
300        __(unbox_fixnum(imm0,arg_y))
301        __(mov imm1,#fixnum1)
302        __(tst arg_z,imm1,lsl imm0)
303        __(mov arg_z,#nil_value)
304        __(addne arg_z,arg_z,#t_offset)
305        __(bx lr)
3061:
307        __(jump_builtin(_builtin_logbitp,2))
308
309_spentry(builtin_logior)
310        __(orr imm0,arg_y,arg_z)
311        __(test_fixnum(imm0))
312        __(moveq arg_z,imm0)
313        __(bxeq lr)
314        __(jump_builtin(_builtin_logior,2))
315
316_spentry(builtin_logand)
317        __(test_two_fixnums(arg_y,arg_z,imm0))
318        __(andeq arg_z,arg_y,arg_z)
319        __(bxeq lr)
320        __(jump_builtin(_builtin_logand,2))
321         
322_spentry(builtin_ash)
323        __(test_two_fixnums(arg_y,arg_z,imm0))
324        __(bne 9f)
325        __(cmp arg_z,#0)
326        __(bgt 1f)
327        __(moveq arg_z,arg_y)
328        __(bxeq lr)
329        /* Shift right */
330        __(unbox_fixnum(imm2,arg_z))
331        __(rsb imm2,imm2,#0)
332        __(cmp imm2,#32)
333        __(movge imm2,#31)
334        __(mov arg_z,#-fixnumone)
335        __(and arg_z,arg_z,arg_y,asr imm2)
336        __(bx lr)
337        /* shift left */
3381:      __(unbox_fixnum(imm0,arg_y))
339        __(unbox_fixnum(imm2,arg_z))
340        __(cmp imm2,#32)
341        __(moveq imm1,imm0)
342        __(moveq imm0,#0)
343        __(beq _SPmakes64)
344        __(bgt 9f)
345        __(rsb imm1,imm2,#32)
346        __(mov imm1,imm0,asr imm1)
347        __(mov imm0,imm0,lsl imm2)
348        __(b _SPmakes64)
3499: 
350        __(jump_builtin(_builtin_ash,2))
351                                       
352_spentry(builtin_negate)
353        __(test_fixnum(arg_z))
354        __(bne 1f)
355        __(rsbs arg_z,arg_z,#0)
356        __(bxvc lr)
357        __(b _SPfix_overflow)
3581:
359        __(jump_builtin(_builtin_negate,1))
360 
361_spentry(builtin_logxor)
362        __(test_two_fixnums(arg_y,arg_z,imm0))
363        __(eoreq arg_z,arg_y,arg_z)
364        __(bxeq lr)
365        __(jump_builtin(_builtin_logxor,2))
366
367_spentry(builtin_aref1)
368        __(extract_typecode(imm0,arg_y))
369        __(cmp imm0,#min_vector_subtag)
370        __(box_fixnum(arg_x,imm0))
371        __(bgt _SPsubtag_misc_ref)
372        __(jump_builtin(_builtin_aref1,2))
373
374_spentry(builtin_aset1)
375        __(extract_typecode(imm0,arg_x))
376        __(cmp imm0,#min_vector_subtag)
377        __(box_fixnum(temp0,imm0))
378        __(bgt _SPsubtag_misc_set)
379        __(jump_builtin(_builtin_aset1,3))
380                       
381
382        /*  Call nfn if it's either a symbol or function */
383_spentry(funcall)
384        __(funcall_nfn())
385
386/* Subprims for catch, throw, unwind_protect.  */
387
388
389_spentry(mkcatch1v)
390        __(mov imm2,#0)
391        __(mkcatch())
392        __(bx lr)
393
394
395_spentry(mkcatchmv)
396        __(mov imm2,#fixnum_one)
397        __(mkcatch())
398        __(bx lr)
399
400_spentry(mkunwind)
401        __(mov imm2,#-fixnumone)
402        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
403        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
404        __(ldr arg_y,[temp0,#INTERRUPT_LEVEL_BINDING_INDEX])
405        __(ldr imm0,[rcontext,#tcr.db_link])
406        __(vpush1(arg_y))
407        __(vpush1(imm1))
408        __(vpush1(imm0))
409        __(str imm2,[temp0,#INTERRUPT_LEVEL_BINDING_INDEX])
410        __(str vsp,[rcontext,#tcr.db_link])
411        __(mov arg_z,#unbound_marker)
412        __(mov imm2,#fixnum_one)
413        __(mkcatch())
414        __(mov arg_z,arg_y)
415        __(b _SPbind_interrupt_level)
416       
417
418/* This never affects the symbol's vcell  */
419/* Non-null symbol in arg_y, new value in arg_z          */
420_spentry(bind)
421        __(ldr imm1,[arg_y,#symbol.binding_index])
422        __(ldr imm0,[rcontext,#tcr.tlb_limit])
423        __(cmp imm0,imm1)
424        __(bhi 1f)
425        __(uuo_tlb_too_small(al,imm1))
4261:             
427        __(cmp imm1,#0)
428        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
429        __(ldr imm0,[rcontext,#tcr.db_link])
430        __(ldr temp1,[imm2,imm1])
431        __(beq 9f)
432        __(vpush1(temp1))
433        __(vpush1(imm1))
434        __(vpush1(imm0))
435        __(str arg_z,[imm2,imm1])
436        __(str vsp,[rcontext,#tcr.db_link])
437        __(bx lr)
4389:
439        __(mov arg_z,arg_y)
440        __(mov arg_y,#XSYMNOBIND)
441        __(set_nargs(2))
442        __(b _SPksignalerr)
443
444_spentry(conslist)
445        __(mov arg_z,#nil_value)
446        __(cmp nargs,#0)
447        __(b 2f)
4481:
449        __(vpop1(arg_y))
450        __(Cons(arg_z,arg_y,arg_z))
451        __(subs nargs,nargs,#fixnum_one)
4522:
453        __(bne 1b)
454        __(bx lr)
455
456/* do list*: last arg in arg_z, all others vpushed, nargs set to #args vpushed.  */
457/* Cons, one cons cell at at time.  Maybe optimize this later.  */
458
459_spentry(conslist_star)
460        __(cmp nargs,#0)
461        __(b 2f)
4621:
463        __(vpop1(arg_y))
464        __(Cons(arg_z,arg_y,arg_z))
465        __(subs nargs,nargs,fixnum_one)
4662:
467        __(bne 1b)
468        __(bx lr)
469
470_spentry(makes32)
471        __(adds imm1,imm0,imm0)
472        __(addsvc arg_z,imm1,imm1)
473        __(bxvc lr)
474        __(movc16(imm1,one_digit_bignum_header))
475        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
476        __(str imm0,[arg_z,#misc_data_offset])
477        __(bx lr)
478
479/* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
480
481
482_spentry(makeu32)
483        __(tst imm0,#0xe0000000)
484        __(box_fixnum(arg_z,imm0))
485        __(bxeq lr)
486        __(tst imm0,#0x80000000)
487        __(bne 2f)
488        __(movc16(imm1,one_digit_bignum_header))
489        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
490        __(str imm0,[arg_z,#misc_data_offset])
491        __(bx lr)
4922:             
493        __(movc16(imm1,two_digit_bignum_header))
494        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
495        __(str imm0,[arg_z,#misc_data_offset])
496        __(bx lr)
497
498
499/* arg_z has overflowed (by one bit) as the result of an addition or
500   subtraction. */
501/* Make a bignum out of it. */
502
503_spentry(fix_overflow)
504        __(unbox_fixnum(imm0,arg_z))
505        __(eor imm0,imm0,#0xc0000000)
506        __(b _SPmakes32)
507
508
509
510/*  Construct a lisp integer out of the 64-bit unsigned value in */
511/*           imm0 (low 32 bits) and imm1 (high 32 bits) */
512       
513_spentry(makeu64)
514        __(cmp imm1,#0)
515        __(beq _SPmakeu32)
516        __(blt 3f)
517        __(movc16(imm2,two_digit_bignum_header))
518        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
519        __(str imm0,[arg_z,#misc_data_offset])
520        __(str imm1,[arg_z,#misc_data_offset+4])
521        __(bx lr)
5223:             
523        __(movc16(imm2,three_digit_bignum_header))
524        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
525        __(str imm0,[arg_z,#misc_data_offset])
526        __(str imm1,[arg_z,#misc_data_offset+4])
527        __(bx lr)
528
529/*  Construct a lisp integer out of the 64-bit signed value in */
530/*        imm0 (low 32 bits) and imm1 (high 32 bits). */
531_spentry(makes64)
532        __(cmp imm1,imm0,asr #31) /* is imm1 sign extension of imm0 ? */
533        __(beq _SPmakes32)        /* forget imm1 if so */
534        __(movc16(imm2,two_digit_bignum_header))
535        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
536        __(str imm0,[arg_z,#misc_data_offset])
537        __(str imm1,[arg_z,#misc_data_offset+4])
538        __(bx lr)
539
540
541
542
543
544
545/* funcall nfn, returning multiple values if it does.  */
546_spentry(mvpass)
547        __(cmp nargs,#node_size*nargregs)
548        __(mov imm1,vsp)
549        __(subgt imm1,imm1,#node_size*nargregs)
550        __(addgt imm1,imm1,nargs)
551        __(build_lisp_frame(imm0,imm1))
552        __(adr lr,C(ret1valn))
553        __(mov fn,#0)
554        __(funcall_nfn())
555
556/* ret1valn returns "1 multiple value" when a called function does not  */
557/* return multiple values.  Its presence on the stack (as a return address)  */
558/* identifies the stack frame to code which returns multiple values.  */
559
560_exportfn(C(ret1valn))
561        __(restore_lisp_frame(imm0))
562        __(vpush1(arg_z))
563        __(set_nargs(1))
564        __(bx lr)
565
566/* Come here to return multiple values when  */
567/* the caller's context isn't saved in a lisp_frame.  */
568/* lr, fn valid; temp0 = entry vsp  */
569
570_spentry(values)
571local_label(return_values): 
572        __(ref_global(imm0,ret1val_addr))
573        __(mov arg_z,#nil_value)
574        __(cmp imm0,lr)
575        __(beq 3f)
576        __(cmp nargs,#fixnum_one)
577        __(add imm0,nargs,vsp)
578        __(ldrge arg_z,[imm0,#-node_size])
579        __(mov vsp,temp0)
580        __(bx lr)
581
582
583/* Return multiple values to real caller.  */
5843:
585        __(ldr lr,[sp,#lisp_frame.savelr])
586        __(add imm1,nargs,vsp)
587        __(ldr imm0,[sp,#lisp_frame.savevsp])
588        __(ldr fn,[sp,#lisp_frame.savefn])
589        __(cmp imm1,imm0) /* a fairly common case  */
590        __(discard_lisp_frame())
591        __(bxeq lr) /* already in the right place  */
592        __(cmp nargs,#fixnum_one) /* sadly, a very common case  */
593        __(bne 4f)
594        __(ldr arg_z,[vsp,#0])
595        __(mov vsp,imm0)
596        __(vpush1(arg_z))
597        __(bx lr)
5984:
599        __(blt 6f)
600        __(mov temp1,#fixnum_one)
6015:
602        __(cmp temp1,nargs)
603        __(add temp1,temp1,#fixnum_one)
604        __(ldr arg_z,[imm1,#-node_size]!)
605        __(push1(arg_z,imm0))
606        __(bne 5b)
6076:
608        __(mov vsp,imm0)
609        __(bx lr)
610
611
612/* Come here with saved context on top of stack.  */
613_spentry(nvalret)
614        .globl C(nvalret)
615C(nvalret):
616        __(ldr lr,[sp,#lisp_frame.savelr])
617        __(ldr temp0,[sp,#lisp_frame.savevsp])
618        __(ldr fn,[sp,#lisp_frame.savefn])
619        __(discard_lisp_frame())
620        __(b local_label(return_values))                         
621
622/* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
623/* Otherwise, process unwind-protects and throw to indicated catch frame.  */
624
625               
626 _spentry(throw)
627        __(ldr temp0,[rcontext, #tcr.catch_top])
628        __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
629        __(cmp temp0,#0)
630        __(ldr temp2,[vsp,nargs])
631        __(beq local_label(_throw_tag_not_found))
632local_label(_throw_loop):
633        __(ldr temp1,[temp0,#catch_frame.catch_tag])
634        __(cmp temp2,temp1)
635        __(ldrne temp0,[temp0,#catch_frame.link])
636        __(beq C(_throw_found))
637        __(cmp temp0,#0)
638        __(add imm0,imm0,#fixnum_one)
639        __(bne local_label(_throw_loop))
640local_label(_throw_tag_not_found):
641        __(uuo_error_no_throw_tag(al,temp2))
642        __(str temp2,[vsp,nargs])
643        __(b _SPthrow)
644
645/* This takes N multiple values atop the vstack.  */
646_spentry(nthrowvalues)
647        __(mov imm1,#1)
648        __(mov temp2,imm0)
649        __(str imm1,[rcontext,#tcr.unwinding])
650        __(b C(nthrownv))
651
652/* This is a (slight) optimization.  When running an unwind-protect, */
653/* save the single value and the throw count in the tstack frame. */
654/* Note that this takes a single value in arg_z.  */
655_spentry(nthrow1value)
656        __(mov imm1,#1)
657        __(mov temp2,imm0)
658        __(str imm1,[rcontext,#tcr.unwinding])
659        __(b C(nthrow1v))
660
661
662/* arg_z = symbol: bind it to its current value          */
663 _spentry(bind_self)
664        __(ldr imm1,[arg_z,#symbol.binding_index])
665        __(ldr imm0,[rcontext,#tcr.tlb_limit])
666        __(cmp imm1,#0)
667        __(beq 9f)
668        __(cmp imm0,imm1)
669        __(bhi 1f)
670        __(uuo_tlb_too_small(al,imm1))
6711:             
672        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
673        __(ldr imm0,[rcontext,#tcr.db_link])
674        __(ldr temp1,[temp2,imm1])
675        __(cmp temp1,#no_thread_local_binding_marker)
676        __(movne temp0,temp1)
677        __(ldreq temp0,[arg_z,#symbol.vcell])
678        __(vpush1(temp1))   /* old tlb contents */
679        __(vpush1(imm1))    /* tlb index */
680        __(vpush1(imm0))
681        __(str temp0,[temp2,imm1])
682        __(str vsp,[rcontext,#tcr.db_link])
683        __(bx lr)
6849:      __(mov arg_y,#XSYMNOBIND)
685        __(set_nargs(2))
686        __(b _SPksignalerr)
687
688/* Bind symbol in arg_z to NIL                 */
689_spentry(bind_nil)
690        __(mov arg_y,arg_z)
691        __(mov arg_z,#nil_value)
692        __(b _SPbind)
693
694/* Bind symbol in arg_z to its current value;  trap if symbol is unbound */
695_spentry(bind_self_boundp_check)
696        __(ldr imm1,[arg_z,#symbol.binding_index])
697        __(ldr imm0,[rcontext,#tcr.tlb_limit])
698        __(cmp imm1,#0)
699        __(beq 9f)
700        __(cmp imm0,imm1)
701        __(bhi 1f)
702        __(uuo_tlb_too_small(al,imm1))
7031:             
704        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
705        __(ldr imm0,[rcontext,#tcr.db_link])
706        __(ldr temp1,[temp2,imm1])
707        __(cmp temp1,#no_thread_local_binding_marker)
708        __(movne temp0,temp1)
709        __(ldreq temp0,[arg_z,#symbol.vcell])
710        __(cmp temp0,#unbound_marker)
711        __(bne 2f)
712        __(uuo_error_unbound(al,arg_z))
7132:             
714        __(vpush1(temp1))   /* old tlb contents */
715        __(vpush1(imm1))    /* tlb index */
716        __(vpush1(imm0))
717        __(str temp0,[temp2,imm1])
718        __(str vsp,[rcontext,#tcr.db_link])
719        __(bx lr)
7209:      __(mov arg_y,#XSYMNOBIND)
721        __(set_nargs(2))
722        __(b _SPksignalerr)
723
724 
725/* The function pc_luser_xp() - which is used to ensure that suspended threads */
726/* are suspended in a GC-safe way - has to treat these subprims (which  */
727/* implement the EGC write-barrier) specially.  Specifically, a store that */
728/* might introduce an intergenerational reference (a young pointer stored  */
729/* in an old object) has to "memoize" that reference by setting a bit in  */
730/* the global "refbits" bitmap. */
731/* This has to happen atomically, and has to happen atomically wrt GC. */
732/* Note that updating a word in a bitmap is itself not atomic, unless we use */
733/* interlocked loads and stores. */
734
735
736/* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
737/* are in the function, we can do the store (even if it's already been done)  */
738/* and calculate whether or not we need to set the bit out-of-line.  (Actually */
739/* setting the bit needs to be done atomically, unless we're sure that other */
740/* threads are suspended.) */
741/* We can unconditionally set the suspended thread's PC to its LR. */
742
743        .globl C(egc_write_barrier_start)
744_spentry(rplaca)
745C(egc_write_barrier_start):     
746        __(cmp arg_z,arg_y)
747        __(_rplaca(arg_y,arg_z))
748        __(bxlo lr)
749        __(ref_global(temp0,ref_base))
750        __(sub imm0,arg_y,temp0)
751        __(mov imm0,imm0,lsr #dnode_shift)
752        __(ref_global(imm1,oldspace_dnode_count))
753        __(cmp imm0,imm1)
754        __(bxhs lr)
755        __(and imm2,imm0,#31)
756        __(mov imm1,#0x80000000)
757        __(mov imm1,imm1,lsr imm2)
758        __(mov imm0,imm0,lsr #bitmap_shift)
759        __(ref_global(temp0,refbits))
760        __(add temp0,temp0,imm0,lsl #word_shift)
761        __(ldr imm2,[temp0])
762        __(tst imm2,imm1)
763        __(bxne lr)
7640:      __(ldrex imm2,[temp0])
765        __(orr imm2,imm2,imm1)
766        __(strex imm0,imm2,[temp0])
767        __(cmp imm0,#0)
768        __(bne 0b)       
769        __(bx lr)
770
771
772        .globl C(egc_rplacd)
773_spentry(rplacd)
774C(egc_rplacd):
775        __(cmp arg_z,arg_y)
776        __(_rplacd(arg_y,arg_z))
777        __(bxlo lr)
778        __(ref_global(temp0,ref_base))
779        __(sub imm0,arg_y,temp0)
780        __(mov imm0,imm0,lsr #dnode_shift)
781        __(ref_global(imm1,oldspace_dnode_count))
782        __(cmp imm0,imm1)
783        __(bxhs lr)
784        __(and imm2,imm0,#31)
785        __(mov imm1,#0x80000000)
786        __(mov imm1,imm1,lsr imm2)
787        __(mov imm0,imm0,lsr #bitmap_shift)
788        __(ref_global(temp0,refbits))
789        __(add temp0,temp0,imm0,lsl #word_shift)
790        __(ldr imm2,[temp0])
791        __(tst imm2,imm1)
792        __(bxne lr)
7930:      __(ldrex imm2,[temp0])
794        __(orr imm2,imm2,imm1)
795        __(strex imm0,imm2,[temp0])
796        __(cmp imm0,#0)
797        __(bne 0b)       
798        __(bx lr)
799       
800
801/* Storing into a gvector can be handled the same way as storing into a CONS. */
802
803        .globl C(egc_gvset)
804_spentry(gvset)
805C(egc_gvset):
806        __(cmp arg_z,arg_x)
807        __(add imm0,arg_y,#misc_data_offset)
808        __(str arg_z,[arg_x,imm0])
809        __(bxlo lr)               
810        __(add imm0,imm0,arg_x)
811        __(ref_global(temp0,ref_base))
812        __(sub imm0,imm0,temp0)
813        __(mov imm0,imm0,lsr #dnode_shift)
814        __(ref_global(imm1,oldspace_dnode_count))
815        __(cmp imm0,imm1)
816        __(bxhs lr)
817        __(and imm2,imm0,#31)
818        __(mov imm1,#0x80000000)
819        __(mov imm1,imm1,lsr imm2)
820        __(mov imm0,imm0,lsr #bitmap_shift)
821        __(ref_global(temp0,refbits))
822        __(add temp0,temp0,imm0,lsl #word_shift)
823        __(ldr imm2,[temp0])
824        __(tst imm2,imm1)
825        __(bxne lr)     
8260:      __(ldrex imm2,[temp0])
827        __(orr imm2,imm2,imm1)
828        __(strex imm0,imm2,[temp0])
829        __(cmp imm0,#0)
830        __(bne 0b)       
831        __(bx lr)
832
833       
834/* This is a special case of storing into a gvector: if we need to memoize  */
835/* the store, record the address of the hash-table vector in the refmap,  */
836/* as well. */
837        .globl C(egc_set_hash_key)       
838_spentry(set_hash_key)
839C(egc_set_hash_key):
840        __(cmp arg_z,arg_x)
841        __(add imm0,arg_y,#misc_data_offset)
842        __(str arg_z,[arg_x,imm0])
843        __(bxlo lr)
844        __(add imm0,imm0,arg_x)
845        __(ref_global(temp0,ref_base))
846        __(sub imm0,imm0,temp0)
847        __(mov imm0,imm0,lsr #dnode_shift)
848        __(ref_global(imm1,oldspace_dnode_count))
849        __(cmp imm0,imm1)
850        __(bxhs lr)
851        __(and imm2,imm0,#31)
852        __(mov imm1,#0x80000000)
853        __(mov imm1,imm1,lsr imm2)
854        __(mov imm0,imm0,lsr #bitmap_shift)
855        __(ref_global(temp0,refbits))
856        __(add temp0,temp0,imm0,lsl #word_shift)
857        __(ldr imm2,[temp0])
858        __(tst imm2,imm1)
859        __(bxne lr)
8600:      __(ldrex imm2,[temp0])
861        __(orr imm2,imm2,imm1)
862        __(strex imm0,imm2,[temp0])
863        __(cmp imm0,#0)
864        __(bne 0b)       
865/* Now need to ensure that the hash table itself is in the refmap; we
866   know that it's in bounds, etc. */
867        __(ref_global(temp0,ref_base))
868        __(sub imm0,arg_x,temp0)
869        __(mov imm0,imm0,lsr #dnode_shift)
870        __(and imm2,imm0,#31)
871        __(mov imm1,#0x80000000)
872        __(mov imm1,imm1,lsr imm2)
873        __(mov imm0,imm0,lsr #bitmap_shift)
874        __(ref_global(temp0,refbits))
875        __(add temp0,temp0,imm0,lsl #word_shift)
876        __(ldr imm2,[temp0])
877        __(tst imm2,imm1)
878        __(bxne lr)
8791:      __(ldrex imm2,[temp0])
880        __(orr imm2,imm2,imm1)
881        __(strex imm0,imm2,[temp0])
882        __(cmp imm0,#0)
883        __(bne 1b)       
884        __(bx lr)
885       
886
887/*
888   Interrupt handling (in pc_luser_xp()) notes:
889   If we are in this function and before the test which follows the
890   conditional (at egc_store_node_conditional), or at that test
891   and cr0`eq' is clear, pc_luser_xp() should just let this continue
892   (we either haven't done the store conditional yet, or got a
893   possibly transient failure.)  If we're at that test and the
894   cr0`EQ' bit is set, then the conditional store succeeded and
895   we have to atomically memoize the possible intergenerational
896   reference.  Note that the local labels 4 and 5 are in the
897   body of the next subprim (and at or beyond 'egc_write_barrier_end').
898
899   N.B: it's not possible to really understand what's going on just
900   by the state of the cr0`eq' bit.  A transient failure in the
901   conditional stores that handle memoization might clear cr0`eq'
902   without having completed the memoization.
903*/
904
905            .globl C(egc_store_node_conditional)
906            .globl C(egc_write_barrier_end)
907_spentry(store_node_conditional)
908C(egc_store_node_conditional):
909        __(vpop1(temp0))
910         
9111:      __(unbox_fixnum(imm2,temp0))
912        __(add imm2,imm2,arg_x)
913        __(ldrex temp1,[imm2])
914        __(cmp temp1,arg_y)
915        __(bne 5f)
916        __(strex imm0,arg_z,[imm2])
917        .globl C(egc_store_node_conditional_test)
918C(egc_store_node_conditional_test):
919        __(cmp imm0,#0)
920        __(bne 1b)
921        __(cmp arg_z,arg_x)
922        __(blo 4f)
923
924        __(ref_global(imm0,ref_base))
925        __(ref_global(imm1,oldspace_dnode_count))
926        __(sub imm0,imm2,imm0)
927        __(mov imm0,imm0,lsr #dnode_shift)
928        __(cmp imm0,imm1)
929        __(bhs 4f)
930        __(and imm1,imm0,#31)
931        __(mov arg_x,#0x80000000)
932        __(mov imm1,arg_x,lsr imm1)
933        __(ref_global(temp0,refbits))
934        __(mov imm0,imm0,lsr #bitmap_shift)
935        __(add temp0,temp0,imm0,lsl #word_shift)
936        __(ldr imm2,[temp0])
937        __(tst imm2,imm1)
938        __(bxne lr)
9392:      __(ldrex imm2,[temp0])
940        __(orr imm2,imm2,imm1)
941        __(strex imm0,imm2,[temp0])
942        .globl C(egc_set_hash_key_conditional_test)
943C(egc_set_hash_key_conditional_test):
944        __(cmp imm0,#0)
945        __(bne 2b)
946        __(b 4f)
947 
948/* arg_z = new value, arg_y = expected old value, arg_x = hash-vector,
949    vsp`0' = (boxed) byte-offset
950    Interrupt-related issues are as in store_node_conditional, but
951    we have to do more work to actually do the memoization.*/
952_spentry(set_hash_key_conditional)
953        .globl C(egc_set_hash_key_conditional)
954C(egc_set_hash_key_conditional):
955        __(vpop1(imm1))
956        __(unbox_fixnum(imm1,imm1))
9570:      __(add imm2,arg_x,imm1)
958        __(ldrex temp1,[imm2])
959        __(cmp temp1,arg_y)
960        __(bne 5f)
961        __(strex imm0,arg_z,[imm2])
962        __(cmp imm0,#0)
963        __(bne 0b)
964        __(cmp arg_z,arg_x)
965        __(blo 4f)
966        __(ref_global(temp0,ref_base))
967        __(sub imm0,imm2,temp0)
968        __(mov imm0,imm0,lsr #dnode_shift)
969        __(ref_global(imm1,oldspace_dnode_count))
970        __(cmp imm0,imm1)
971        __(bhs 4f)
972        __(and imm2,imm0,#31)
973        __(mov imm1,#0x80000000)
974        __(mov imm1,imm1,lsr imm2)
975        __(mov imm0,imm0,lsr #bitmap_shift)
976        __(ref_global(temp0,refbits))
977        __(add temp0,temp0,imm0,lsl #word_shift)
978        __(ldr imm2,[temp0])
979        __(tst imm2,imm1)
980        __(bxne lr)
9811:      __(ldrex imm2,[temp0])
982        __(orr imm2,imm2,imm1)
983        __(strex imm0,imm2,[temp0])
984        __(cmp imm0,#0)
985        __(bne 1b)       
986/* Now need to ensure that the hash table itself is in the refmap; we
987   know that it's in bounds, etc. */
988        __(ref_global(temp0,ref_base))
989        __(sub imm0,arg_x,temp0)
990        __(mov imm0,imm0,lsr #dnode_shift)
991        __(and imm2,imm0,#31)
992        __(mov imm1,#0x80000000)
993        __(mov imm1,imm1,lsr imm2)
994        __(mov imm0,imm0,lsr #bitmap_shift)
995        __(ref_global(temp0,refbits))
996        __(add temp0,temp0,imm0,lsl #word_shift)
997        __(ldr imm2,[temp0])
998        __(tst imm2,imm1)
999        __(bxne lr)
10001:      __(ldrex imm2,[temp0])
1001        __(orr imm2,imm2,imm1)
1002        __(strex imm0,imm2,[temp0])
1003        __(cmp imm0,#0)
1004        __(bne 1b)       
1005C(egc_write_barrier_end):
10064:      __(mov arg_z,#nil_value)
1007        __(add arg_z,arg_z,#t_offset)
1008        __(bx lr)
10095:      __(_clrex(arg_z))
1010        __(mov arg_z,#nil_value)
1011        __(bx lr)
1012
1013
1014
1015
1016       
1017/* We always have to create a stack frame (even if nargs is 0), so the compiler  */
1018/* doesn't get confused.  */
1019_spentry(stkconslist)
1020        __(mov arg_z,#nil_value)
1021C(stkconslist_star):           
1022        __(mov temp2,nargs,lsl #1)
1023        __(add temp2,temp2,#node_size)
1024        __(mov imm0,temp2,lsl #num_subtag_bits-word_shift)
1025        __(add temp2,temp2,#node_size)
1026        __(orr imm0,imm0,#subtag_u32_vector)
1027        __(stack_allocate_zeroed_ivector(imm0,temp2))
1028        __(mov imm0,#subtag_simple_vector)
1029        __(strb imm0,[sp,#0])
1030        __(add imm1,sp,#dnode_size+fulltag_cons)
1031        __(cmp nargs,#0)
1032        __(b 4f)
10331:      __(vpop1(temp0))
1034        __(_rplaca(imm1,temp0))
1035        __(_rplacd(imm1,arg_z))
1036        __(mov arg_z,imm1)
1037        __(add imm1,imm1,#cons.size)
1038        __(subs nargs,nargs,#node_size)
10394:
1040        __(bne 1b)
1041        __(bx lr)
1042 
1043/* do list*: last arg in arg_z, all others vpushed,  */
1044/* nargs set to #args vpushed.  */
1045_spentry(stkconslist_star)
1046        __(b C(stkconslist_star))
1047
1048/* Make a stack-consed simple-vector out of the NARGS objects  */
1049/* on top of the vstack; return it in arg_z.  */
1050_spentry(mkstackv)
1051        __(dnode_align(imm1,nargs,node_size))
1052        __(mov imm0,nargs,lsl #num_subtag_bits-fixnumshift)
1053        __(orr imm0,imm0,#subtag_u32_vector)
1054        __(stack_allocate_zeroed_ivector(imm0,imm1))
1055        __(mov imm0,#subtag_simple_vector)
1056        __(strb imm0,[sp,#0])
1057        __(add arg_z,sp,#fulltag_misc)
1058        __(add imm0,arg_z,#misc_data_offset)
1059        __(add imm1,imm0,nargs)
1060        __(b 4f)
10613:      __(vpop1(arg_y))
1062        __(str arg_y,[imm1,#-node_size]!)
1063        __(sub nargs,nargs,#node_size)
10644:      __(cmp nargs,#0)
1065        __(bne 3b)
1066        __(bx lr)
1067       
1068_spentry(setqsym)
1069        __(ldr imm0,[arg_y,#symbol.flags])
1070        __(tst imm0,#sym_vbit_const_mask)
1071        __(beq _SPspecset)
1072        __(mov arg_z,arg_y)
1073        __(mov arg_y,#XCONST)
1074        __(set_nargs(2))
1075        __(b _SPksignalerr)
1076
1077
1078
1079_spentry(progvsave)
1080        __(b (C(progvsave)))
1081 
1082       
1083/* Allocate a uvector on the  stack.  (Push a frame on the stack and  */
1084/* heap-cons the object if there's no room on the stack.)  */
1085_spentry(stack_misc_alloc)
1086        __(tst arg_y,#unsigned_byte_24_mask)
1087        __(beq 1f)
1088        __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
10891:             
1090        __(unbox_fixnum(imm2,arg_z))
1091        __(extract_fulltag(imm1,imm2))
1092        __(cmp imm1,#fulltag_nodeheader)
1093        __(bne 1f)
1094        __(dnode_align(imm1,arg_y,node_size))
1095        __(mov imm0,#subtag_u32_vector)
1096        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1097        __(b 9f)
10981:      __(mov imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1099        __(orr imm0,imm0,arg_z,lsr #fixnumshift)
1100        __(cmp arg_z,#max_32_bit_ivector_subtag<<fixnumshift)
1101        __(movle imm1,arg_y)
1102        __(ble 8f)
1103        __(cmp arg_z,#max_8_bit_ivector_subtag<<fixnumshift)
1104        __(movle imm1,arg_y,lsr #fixnumshift)
1105        __(ble 8f)
1106        __(cmp arg_z,#max_16_bit_ivector_subtag<<fixnumshift)
1107        __(movle imm1,arg_y,lsr #1)
1108        __(ble 8f)
1109        __(cmp arg_z,#subtag_double_float_vector<<fixnumshift)
1110        __(moveq imm1,arg_y,lsl #1)
1111        __(addeq imm1,imm1,#node_size)
1112        __(addne imm1,arg_y,#7<<fixnumshift)
1113        __(movne imm1,imm1,lsr#3+fixnumshift)
11148:      __(dnode_align(imm1,imm1,node_size))
11159:     
1116        __(ldr temp0,[rcontext,tcr.cs_limit])
1117        __(sub temp1,sp,imm1)
1118        __(cmp temp1,temp0)
1119        __(bls stack_misc_alloc_no_room)
1120        __(mov temp0,#stack_alloc_marker)
1121        __(mov temp1,sp)
1122        __(stack_allocate_zeroed_ivector(imm0,imm1))
1123        __(add arg_z,sp,#fulltag_misc)
1124        __(strb imm2,[sp])
1125        __(stmdb sp!,{temp0,temp1})
1126        __(bx lr)
1127
1128
1129
1130
1131/* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
1132/* initial-contents.  Note that this can be used to cons any type of initialized  */
1133/* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
1134/* objects.  */
1135
1136_spentry(gvector)
1137        __(sub nargs,nargs,#node_size)
1138        __(ldr arg_z,[vsp,nargs])
1139        __(unbox_fixnum(imm0,arg_z))
1140        __(orr imm0,imm0,nargs,lsl #num_subtag_bits-fixnum_shift)
1141        __(dnode_align(imm1,nargs,node_size))
1142        __(Misc_Alloc(arg_z,imm0,imm1))
1143        __(mov imm1,nargs)
1144        __(add imm2,imm1,#misc_data_offset)
1145        __(b 2f)
11461:
1147        __(str temp0,[arg_z,imm2])
11482:
1149        __(sub imm1,imm1,#node_size)
1150        __(cmp imm1,#0)
1151        __(sub imm2,imm2,#node_size)
1152        __(vpop1(temp0))        /* Note the intentional fencepost: */
1153                                /* discard the subtype as well.  */
1154        __(bge 1b)
1155        __(bx lr)
1156
1157_spentry(fitvals)
1158        __(subs imm0,imm0,nargs)
1159        __(mov imm1,#nil_value)
1160        __(sublt vsp,vsp,imm0)
1161        __(bxlt lr)
1162        __(b 2f)
11631:
1164        __(subs imm0,imm0,#node_size)
1165        __(vpush1(imm1))       
1166        __(add nargs,nargs,#node_size)
11672:
1168        __(bne 1b)
1169        __(bx lr)
1170
1171
1172_spentry(nthvalue)
1173        __(add imm0,vsp,nargs)
1174        __(ldr imm1,[imm0,#0])
1175        __(cmp imm1,nargs) /*  do unsigned compare:  if (n < 0) => nil.  */
1176        __(mov arg_z,#nil_value)
1177        __(rsb imm1,imm1,#0)
1178        __(sub imm1,imm1,#node_size)
1179        __(ldrlo arg_z,[imm0,imm1])
1180        __(add vsp,imm0,#node_size)
1181        __(bx lr)
1182
1183/* Provide default (NIL) values for &optional arguments; imm0 is  */
1184/* the (fixnum) upper limit on the total of required and &optional  */
1185/* arguments.  nargs is preserved, all arguments wind up on the  */
1186/* vstack.  */
1187_spentry(default_optional_args)
1188        __(vpush_argregs())
1189        __(cmp nargs,imm0)
1190        __(mov arg_z,#nil_value)
1191        __(mov imm1,nargs)
1192        __(bxhs lr)
11931: 
1194        __(add imm1,imm1,#fixnum_one)
1195        __(cmp imm1,imm0)
1196        __(vpush1(arg_z))
1197        __(bne 1b)
1198        __(bx lr)
1199
1200/* Indicate whether &optional arguments were actually supplied.  nargs  */
1201/* contains the actual arg count (minus the number of required args);  */
1202/* imm0 contains the number of &optional args in the lambda list.  */
1203/* Note that nargs may be > imm0 if &rest/&key is involved.  */
1204_spentry(opt_supplied_p)
1205        __(mov imm1,#0)
1206        __(mov arg_x,#nil_value)
1207        __(add arg_x,arg_x,#t_offset)       
12081:     
1209        /* (vpush (< imm1 nargs))  */
1210        __(cmp imm1,nargs)
1211        __(add imm1,imm1,#fixnumone)
1212        __(subeq arg_x,arg_x,#t_offset)
1213        __(vpush1(arg_x))
1214        __(cmp imm1,imm0)
1215        __(bne 1b)
1216        __(bx lr)
1217
1218/* Cons a list of length nargs  and vpush it.  */
1219/* Use this entry point to heap-cons a simple &rest arg.  */
1220_spentry(heap_rest_arg)
1221        __(vpush_argregs())
1222        __(movs imm1,nargs)
1223        __(mov arg_z,#nil_value)
1224        __(b 2f)
12251:
1226        __(vpop1(arg_y))
1227        __(Cons(arg_z,arg_y,arg_z))
1228        __(subs imm1,imm1,#fixnum_one)
12292:
1230        __(bne 1b)
1231        __(vpush1(arg_z))
1232        __(bx lr)
1233
1234 
1235/* And this entry point when the argument registers haven't yet been  */
1236/* vpushed (as is typically the case when required/&rest but no  */
1237/* &optional/&key.)  */
1238_spentry(req_heap_rest_arg)
1239        __(vpush_argregs())
1240        __(subs imm1,nargs,imm0)
1241        __(mov arg_z,#nil_value)
1242        __(b 2f)
12431:
1244        __(vpop1(arg_y))
1245        __(Cons(arg_z,arg_y,arg_z))
1246        __(subs imm1,imm1,#fixnum_one)
12472:
1248        __(bgt 1b)
1249        __(vpush1(arg_z))
1250        __(bx lr)
1251
1252/* Here where argregs already pushed */
1253_spentry(heap_cons_rest_arg)
1254        __(subs imm1,nargs,imm0)
1255        __(mov arg_z,#nil_value)
1256        __(b 2f)
12571:
1258        __(vpop1(arg_y))
1259        __(Cons(arg_z,arg_y,arg_z))
1260        __(subs imm1,imm1,#fixnum_one)
12612:
1262        __(bgt 1b)
1263        __(vpush1(arg_z))
1264        __(bx lr)
1265
1266
1267_spentry(check_fpu_exception)
1268        __(fmrx imm0,fpscr)
1269        __(mov imm2,imm0)
1270        __(ldr imm1,[rcontext,#tcr.lisp_fpscr])
1271        __(ands imm0,imm0,imm1,lsr #8)
1272        __(bxeq lr)
1273        __(bic imm2,imm2,#0xff)
1274        __(fmxr fpscr,imm2)
1275        __(build_lisp_frame(imm2))
1276        __(mov imm2,#34<<fixnumshift)
1277        __(movc16(imm1,make_header(33,subtag_u32_vector)))
1278        __(stack_allocate_ivector(imm1,imm2))
1279        __(add arg_z,sp,#fulltag_misc)
1280        __(str imm0,[arg_z,#misc_data_offset])
1281        __(add imm0,sp,#dnode_size)
1282        __(fstmiad imm0,{d0-d15})
1283        __(ldr imm1,[lr,#-12])
1284        __(uuo_error_fpu_exception(al,arg_z,imm1))
1285        __(add imm0,sp,#dnode_size)
1286        __(fldmiad imm0,{d0-d15})
1287        __(add sp,sp,#34<<fixnumshift)
1288        __(return_lisp_frame(imm0))
1289
1290_spentry(discard_stack_object)
1291        new_local_labels()       
1292        __(ldr imm0,[sp,#0])
1293        __(cmp imm0,#stack_alloc_marker)
1294        __(ldreq sp,[sp,#node_size])
1295        __(bxeq lr)
1296        __(cmp imm0,#lisp_frame_marker)
1297        __(extract_fulltag(imm1,imm0))
1298        __(addeq sp,sp,#lisp_frame.size)
1299        __(bxeq lr)
1300        __(cmp imm1,#fulltag_immheader)
1301        __(and imm1,imm0,#subtag_mask)
1302        __(bic imm0,imm0,#subtag_mask)
1303        __(beq local_label(ivector))
1304local_label(word):
1305        __(mov imm0,imm0,lsr #num_subtag_bits-word_shift)
1306local_label(out):       
1307        __(dnode_align(imm0,imm0,node_size))
1308        __(add sp,sp,imm0)
1309        __(bx lr)
1310local_label(ivector):     
1311        __(cmp imm1,#max_32_bit_ivector_subtag)
1312        __(bls local_label(word))       
1313        __(cmp imm1,#max_8_bit_ivector_subtag)
1314        __(movls imm0,imm0,lsr #num_subtag_bits)
1315        __(bls local_label(out))
1316        __(cmp imm1,#max_16_bit_ivector_subtag)
1317        __(movls imm0,imm0,lsr #num_subtag_bits-1)
1318        __(bls local_label(out))
1319        __(cmp imm1,#subtag_bit_vector)
1320        __(moveq imm0,imm0,lsr #num_subtag_bits)
1321        __(addeq imm0,imm0,#7)
1322        __(moveq imm0,imm0,lsr #3)
1323        __(beq local_label(out))
1324        /* The infamous 'stack-consed double-float vector' case */
1325        __(mov imm0,imm0,lsr #num_subtag_bits-dnode_shift)
1326        __(b local_label(out))
1327
1328
1329       
1330/* Signal an error synchronously, via %ERR-DISP.  */
1331/* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
1332/* on the C runtime stderr.  */
1333 
1334_spentry(ksignalerr)
1335        __(ref_nrs_symbol(fname,errdisp,imm0))
1336        __(jump_fname)
1337
1338/* As in the heap-consed cases, only stack-cons the &rest arg  */
1339_spentry(stack_rest_arg)
1340        __(mov imm0,#0)
1341        __(vpush_argregs())
1342        __(b _SPstack_cons_rest_arg)
1343
1344_spentry(req_stack_rest_arg)
1345        __(vpush_argregs())
1346        __(b _SPstack_cons_rest_arg)
1347
1348_spentry(stack_cons_rest_arg)
1349        __(subs imm1,nargs,imm0)
1350        __(mov arg_z,#nil_value)
1351        __(ble 2f)  /* always temp-push something.  */
1352        __(mov temp0,imm1)
1353        __(add imm1,imm1,imm1)
1354        __(add imm1,imm1,#node_size)
1355        __(dnode_align(imm0,imm1,node_size))
1356        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
1357        __(orr imm1,imm1,#subtag_u32_vector)
1358        __(sub arg_x,sp,imm0)
1359        __(ldr arg_y,[rcontext,#tcr.cs_limit])
1360        __(cmp arg_x,arg_y)
1361        __(blo 3f)
1362        __(stack_allocate_zeroed_ivector(imm1,imm0))
1363        __(mov imm0,#subtag_simple_vector)
1364        __(strb imm0,[sp])
1365        __(add imm0,sp,#dnode_size+fulltag_cons)
13661:
1367        __(subs temp0,temp0,#fixnumone)
1368        __(vpop1(arg_x))
1369        __(_rplacd(imm0,arg_z))
1370        __(_rplaca(imm0,arg_x))
1371        __(mov arg_z,imm0)
1372        __(add imm0,imm0,#cons.size)
1373        __(bne 1b)
1374        __(vpush1(arg_z))
1375        __(bx lr)
13762:
1377        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1378        __(mov imm1,#0)
1379        __(stmdb sp!,{imm0,imm1})
1380        __(vpush1(arg_z))
1381        __(bx lr)
13823:
1383        __(mov arg_z,#stack_alloc_marker)
1384        __(mov arg_y,sp)
1385        __(stmdb sp!,{arg_z,arg_y})
1386        __(b _SPheap_cons_rest_arg)
1387
1388       
1389/* Prepend all but the first three (entrypoint, closure code, fn) and last two  */
1390/* (function name, lfbits) elements of nfn to the "arglist".  */
1391/* functions which take "inherited arguments" work consistently  */
1392/* even in cases where no closure object is created.  */
1393_spentry(call_closure)       
1394        __(cmp nargs,nargregs<<fixnumshift)
1395        __(vector_length(imm0,nfn,imm0))
1396        __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count  */
1397        __(ble local_label(no_insert))
1398        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
1399        /* of NILs, copy those arguments that have already been vpushed from  */
1400        /* the old TOS to the new, then insert all of the inerited args  */
1401        /* and go to the function.  */
1402        __(vpush_all_argregs())
1403        __(mov arg_x,imm0)
1404        __(mov arg_y,#nil_value)
1405local_label(push_nil_loop):
1406        __(subs arg_x,arg_x,#fixnumone)
1407        __(vpush1(arg_y))
1408        __(bne local_label(push_nil_loop))
1409        __(add arg_y,vsp,imm0)
1410        __(mov imm1,#0)
1411local_label(copy_already_loop): 
1412        __(ldr arg_x,[arg_y,imm1])
1413        __(str arg_x,[vsp,imm1])
1414        __(add imm1,imm1,#fixnumone)
1415        __(cmp imm1,nargs)
1416        __(bne local_label(copy_already_loop))
1417        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1418        __(add arg_y,vsp,nargs)
1419        __(add arg_y,arg_y,imm0)
1420local_label(insert_loop):
1421        __(subs imm0,imm0,#fixnumone)
1422        __(ldr fname,[nfn,imm1])
1423        __(add imm1,imm1,#fixnumone)
1424        __(add nargs,nargs,#fixnumone)
1425        __(push1(fname,arg_y))
1426        __(bne local_label(insert_loop))
1427        __(vpop_all_argregs())
1428        __(b local_label(go))
1429local_label(no_insert):
1430/* nargregs or fewer args were already vpushed.  */
1431/* if exactly nargregs, vpush remaining inherited vars.  */
1432        __(cmp nargs,#nargregs<<fixnumshift)
1433        __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift))
1434        __(bne local_label(set_regs))
1435local_label(vpush_remaining):
1436        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1437local_label(vpush_remaining_loop):             
1438        __(ldr fname,[nfn,imm1])
1439        __(add imm1,imm1,#fixnum_one)
1440        __(vpush1(fname))
1441        __(subs imm0,imm0,#fixnum_one)
1442        __(add nargs,nargs,#fixnum_one)
1443        __(bne  local_label(vpush_remaining_loop))
1444        __(b local_label(go))
1445local_label(set_regs):
1446        /* if nargs was > 1 (and we know that it was < 3), it must have  */
1447        /* been 2.  Set arg_x, then vpush the remaining args.  */
1448        __(cmp nargs,#fixnumone)
1449        __(ble local_label(set_y_z))
1450local_label(set_arg_x):
1451        __(subs imm0,imm0,#fixnum_one)
1452        __(sub imm1,imm1,#fixnum_one)
1453        __(ldr arg_x,[nfn,imm1])
1454        __(add nargs,nargs,#fixnum_one)
1455        __(bne local_label(vpush_remaining))
1456        __(b local_label(go))
1457        /* Maybe set arg_y or arg_z, preceding args  */
1458local_label(set_y_z):
1459        __(cmp nargs,#fixnumone)
1460        __(bne local_label(set_arg_z))
1461        /* Set arg_y, maybe arg_x, preceding args  */
1462local_label(set_arg_y):
1463        __(subs imm0,imm0,fixnum_one)
1464        __(sub imm1,imm1,#fixnum_one)
1465        __(ldr arg_y,[nfn,imm1])
1466        __(add nargs,nargs,#fixnum_one)
1467        __(bne local_label(set_arg_x))
1468        __(b local_label(go))
1469local_label(set_arg_z):
1470        __(subs imm0,imm0,#fixnum_one)
1471        __(sub imm1,imm1,#fixnum_one)
1472        __(ldr arg_z,[nfn,imm1])
1473        __(add nargs,nargs,#fixnum_one)
1474        __(bne local_label(set_arg_y))
1475 
1476local_label(go):
1477        __(vrefr(nfn,nfn,2))
1478        __(ldr pc,[nfn,#_function.entrypoint])
1479
1480
1481/* Everything up to the last arg has been vpushed, nargs is set to  */
1482/* the (boxed) count of things already pushed.  */
1483/* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
1484/* function call (this may require vpopping a few things.)  */
1485/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1486_spentry(spreadargz)
1487        __(extract_lisptag(imm1,arg_z))
1488        __(cmp arg_z,#nil_value)
1489        __(mov imm0,#0)
1490        __(mov arg_y,arg_z)  /*  save in case of error  */
1491        __(beq 2f)
14921:
1493        __(cmp imm1,#tag_list)
1494        __(bne 3f)
1495        __(_car(arg_x,arg_z))
1496        __(_cdr(arg_z,arg_z))
1497        __(cmp arg_z,#nil_value)
1498        __(extract_lisptag(imm1,arg_z))
1499        __(vpush1(arg_x))
1500        __(add imm0,imm0,#fixnum_one)
1501        __(bne 1b)
15022:
1503        __(adds  nargs,nargs,imm0)
1504        __(bxeq lr)
1505        __(vpop_argregs_nz)
1506        __(bx lr)
1507       
1508        /*  Discard whatever's been vpushed already, complain.  */
15093:
1510        __(add vsp,vsp,imm0)
1511        __(mov arg_z,arg_y)  /* recover original arg_z  */
1512        __(mov arg_y,#XNOSPREAD)
1513        __(set_nargs(2))
1514        __(b _SPksignalerr)
1515
1516/* Tail-recursively funcall temp0.  */
1517/* Pretty much the same as the tcallsym* cases above.  */
1518_spentry(tfuncallgen)
1519        __(cmp nargs,#nargregs<<fixnumshift)
1520        __(ldr lr,[sp,#lisp_frame.savelr])
1521        __(ldr fn,[sp,#lisp_frame.savefn])
1522        __(ble 2f)
1523        __(ldr imm0,[sp,#lisp_frame.savevsp])
1524        __(discard_lisp_frame())
1525        /* can use temp0 as a temporary  */
1526        __(sub imm1,nargs,#nargregs<<fixnumshift)
1527        __(add imm1,imm1,vsp)
15281:
1529        __(ldr temp0,[imm1,#-node_size]!)
1530        __(cmp imm1,vsp)
1531        __(push1(temp0,imm0))
1532        __(bne 1b)
1533        __(mov vsp,imm0)
1534        __(funcall_nfn())
15352:
1536        __(ldr vsp,[sp,#lisp_frame.savevsp])
1537        __(discard_lisp_frame())
1538        __(funcall_nfn())
1539
1540
1541/* Some args were vpushed.  Slide them down to the base of  */
1542/* the current frame, then do funcall.  */
1543_spentry(tfuncallslide)
1544        __(ldr fn,[sp,#lisp_frame.savefn])
1545        __(ldr imm0,[sp,#lisp_frame.savevsp])
1546        __(ldr lr,[sp,#lisp_frame.savelr])
1547        __(discard_lisp_frame())
1548        /* can use temp0 as a temporary  */
1549        __(sub imm1,nargs,#nargregs<<fixnumshift)
1550        __(add imm1,imm1,vsp)
15511:
1552        __(ldr temp0,[imm1,#-node_size]!)
1553        __(cmp imm1,vsp)
1554        __(push1(temp0,imm0))
1555        __(bne 1b)
1556        __(mov vsp,imm0)
1557        __(funcall_nfn())
1558
1559
1560_spentry(jmpsym)
1561        __(jump_fname)
1562
1563/* Tail-recursively call the (known symbol) in fname.  */
1564/* In the general case, we don't know if any args were  */
1565/* vpushed or not.  If so, we have to "slide" them down  */
1566/* to the base of the frame.  If not, we can just restore  */
1567/* vsp, lr, fn from the saved lisp frame on the control stack.  */
1568_spentry(tcallsymgen)
1569        __(cmp nargs,#nargregs<<fixnumshift)
1570        __(ldr lr,[sp,#lisp_frame.savelr])
1571        __(ldr fn,[sp,#lisp_frame.savefn])
1572        __(ble 2f)
1573
1574        __(ldr imm0,[sp,#lisp_frame.savevsp])
1575        __(discard_lisp_frame())
1576        /* can use nfn (= temp2) as a temporary  */
1577        __(sub imm1,nargs,#nargregs<<fixnumshift)
1578        __(add imm1,imm1,vsp)
15791:
1580        __(ldr temp2,[imm1,#-node_size]!)
1581        __(cmp imm1,vsp)
1582        __(push1(temp2,imm0))
1583        __(bne 1b)
1584        __(mov vsp,imm0)
1585        __(jump_fname)
1586 
15872: 
1588        __(ldr vsp,[sp,#lisp_frame.savevsp])
1589        __(discard_lisp_frame())
1590        __(jump_fname)
1591
1592
1593/* Some args were vpushed.  Slide them down to the base of  */
1594/* the current frame, then do funcall.  */
1595_spentry(tcallsymslide)
1596        __(ldr lr,[sp,#lisp_frame.savelr])
1597        __(ldr fn,[sp,#lisp_frame.savefn])
1598        __(ldr imm0,[sp,#lisp_frame.savevsp])
1599        __(discard_lisp_frame())
1600        /* can use nfn (= temp2) as a temporary  */
1601        __(sub imm1,nargs,#nargregs<<fixnumshift)
1602        __(add imm1,imm1,vsp)
16031:
1604        __(ldr temp2,[imm1,#-node_size]!)
1605        __(cmp imm1,vsp)
1606        __(push1(temp2,imm0))
1607        __(bne 1b)
1608        __(mov vsp,imm0)
1609        __(jump_fname)
1610
1611
1612/* Tail-recursively call the function in nfn.  */
1613/* Pretty much the same as the tcallsym* cases above.  */
1614_spentry(tcallnfngen)
1615        __(cmp nargs,#nargregs<<fixnumshift)
1616        __(bgt _SPtcallnfnslide)
1617        __(restore_lisp_frame(imm0))
1618        __(jump_nfn())
1619         
1620/* Some args were vpushed.  Slide them down to the base of  */
1621/* the current frame, then do funcall.  */
1622_spentry(tcallnfnslide)
1623        __(ldr lr,[sp,#lisp_frame.savelr])
1624        __(ldr fn,[sp,#lisp_frame.savefn])
1625        __(ldr imm0,[sp,#lisp_frame.savevsp])
1626        __(discard_lisp_frame())
1627        /* Since we have a known function, can use fname as a temporary.  */
1628        __(sub imm1,nargs,#nargregs<<fixnumshift)
1629        __(add imm1,imm1,vsp)
16301:
1631        __(ldr fname,[imm1,#-node_size]!)
1632        __(cmp imm1,vsp)
1633        __(push1(fname,imm0))
1634        __(bne 1b)
1635        __(mov vsp,imm0)
1636        __(jump_nfn())
1637
1638
1639/* Reference index arg_z of a misc-tagged object (arg_y).  */
1640/* Note that this conses in some cases.  Return a properly-tagged  */
1641/* lisp object in arg_z.  Do type and bounds-checking.  */
1642
1643_spentry(misc_ref)
1644        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1645        __(trap_unless_fixnum(arg_z))
1646        __(vector_length(imm0,arg_y,imm1))
1647        __(cmp arg_z,imm0)
1648        __(blo 1f)
1649        __(uuo_error_vector_bounds(al,arg_z,arg_y))
16501:             
1651        __(extract_lowbyte(imm1,imm1)) /* imm1 = subtag  */
1652        __(b C(misc_ref_common)) 
1653
1654/* like misc_ref, only the boxed subtag is in arg_x.  */
1655
1656_spentry(subtag_misc_ref)
1657        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1658        __(trap_unless_fixnum(arg_z))
1659        __(vector_length(imm0,arg_y,imm1))
1660        __(cmp arg_z,imm0)
1661        __(blo 1f)
1662        __(uuo_error_vector_bounds(al,arg_z,arg_y))
16631:             
1664        __(unbox_fixnum(imm1,arg_x))
1665        __(b C(misc_ref_common))
1666
1667
1668/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
1669/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
1670/* in arg_z on exit.  */
1671_spentry(makestackblock)
1672        __(unbox_fixnum(imm1,arg_z))
1673        __(dnode_align(imm1,imm1,0))
1674        __(add imm1,imm1,#node_size)
1675        __(add imm0,imm1,#node_size)
1676        __(sub imm2,sp,imm0)
1677        __(ldr temp0,[rcontext,#tcr.cs_limit])
1678        __(cmp imm2,temp0)
1679        __(mov temp0,sp)
1680        __(bls 1f)
1681        __(mov imm1,imm1,lsl #num_subtag_bits)
1682        __(orr imm1,imm1,#subtag_u8_vector)
1683        __(stack_allocate_ivector(imm1,imm0))
1684        __(add temp1,sp,#dnode_size)
1685        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1686        __(str imm1,[sp,#-macptr.size]!)
1687        __(add arg_z,sp,#fulltag_misc)
1688        __(str temp1,[arg_z,#macptr.address])
1689        __(mov imm0,#0)
1690        __(mov imm1,#stack_alloc_marker)
1691        __(str imm0,[arg_z,#macptr.type])
1692        __(str imm0,[arg_z,#macptr.domain])
1693        __(stmdb sp!,{imm1,temp0})
1694        __(bx lr)
1695
1696        /* Too big. Heap cons a gcable macptr  */
16971:
1698        __(mov imm1,#stack_alloc_marker)
1699        __(stmdb sp!,{imm1,temp0})
1700        __(set_nargs(1))
1701        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1702        __(jump_fname())
1703
1704/* As above, only set the block's contents to 0.  */
1705_spentry(makestackblock0)
1706        __(unbox_fixnum(imm1,arg_z))
1707        __(dnode_align(imm1,imm1,0))
1708        __(add imm1,imm1,#node_size)
1709        __(add imm0,imm1,#node_size)
1710        __(sub imm2,sp,imm0)
1711        __(ldr temp0,[rcontext,#tcr.cs_limit])
1712        __(cmp imm2,temp0)
1713        __(mov temp0,sp)
1714        __(bls 1f)
1715        __(mov imm1,imm1,lsl #num_subtag_bits)
1716        __(orr imm1,imm1,#subtag_u8_vector)
1717        __(stack_allocate_zeroed_ivector(imm1,imm0))
1718        __(add temp1,sp,#dnode_size)
1719        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1720        __(str imm1,[sp,#-macptr.size]!)
1721        __(add arg_z,sp,#fulltag_misc)
1722        __(str temp1,[arg_z,#macptr.address])
1723        __(mov imm0,#0)
1724        __(mov imm1,#stack_alloc_marker)
1725        __(str imm0,[arg_z,#macptr.type])
1726        __(str imm0,[arg_z,#macptr.domain])
1727        __(stmdb sp!,{imm1,temp0})
1728        __(bx lr)
1729       
1730        /* Too big. Heap cons a gcable macptr  */
17311:
1732        __(mov imm1,#stack_alloc_marker)
1733        __(stmdb sp!,{imm1,temp0})
1734        __(mov arg_y,arg_z) /* save block size  */
1735        __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr  */
1736        __(add arg_z,arg_z,#t_offset)
1737        __(set_nargs(2))
1738        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1739        __(jump_fname())
1740
1741/* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
1742/* the tstack.  Return the list in arg_z.  */
1743_spentry(makestacklist)
1744        __(add imm0,arg_y,arg_y)
1745        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1746        __(add imm1,imm1,#1<<num_subtag_bits)
1747        __(orr imm1,imm1,#subtag_u32_vector)
1748        __(add imm0,imm0,#dnode_size)
1749        __(ldr temp0,[rcontext,#tcr.cs_limit])
1750        __(sub imm2,sp,imm0)
1751        __(cmp imm2,temp0)
1752        __(bls 4f)
1753        __(stack_allocate_zeroed_ivector(imm1,imm0))
1754        __(mov imm0,#subtag_simple_vector)
1755        __(strb imm0,[sp,#0])
1756        __(add imm2,sp,#dnode_size+fulltag_cons)
1757        __(movs imm1,arg_y)
1758        __(mov arg_y,arg_z)
1759        __(mov arg_z,#nil_value)
1760        __(b 3f)
17612:
1762        __(_rplacd(imm2,arg_z))
1763        __(_rplaca(imm2,arg_y))
1764        __(mov arg_z,imm2)
1765        __(add imm2,imm2,#cons.size)
1766        __(subs imm1,imm1,#fixnumone)
17673:
1768        __(bne 2b)
1769        __(bx lr)
17704:
1771        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1772        __(str imm0,[sp,#-8]!)
1773        __(movs imm1,arg_y) /* count  */
1774        __(mov arg_y,arg_z) /* initial value  */
1775        __(mov arg_z,#nil_value) /* result  */
1776        __(b 6f)
17775:
1778        __(Cons(arg_z,arg_y,arg_z))
1779        __(subs imm1,imm1,#fixnumone)
17806:
1781        __(bne 5b)
1782        __(bx lr)
1783
1784/* subtype (boxed) vpushed before initial values. (Had better be a  */
1785/* node header subtag.) Nargs set to count of things vpushed.  */
1786
1787_spentry(stkgvector)
1788        __(sub imm0,nargs,#fixnumone)
1789        __(ldr temp0,[vsp,imm0])
1790        __(dnode_align(temp1,imm0,node_size))
1791        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1792        __(orr imm1,imm1,#subtag_u32_vector)
1793        __(sub temp2,sp,imm1)
1794        __(ldr arg_x,[rcontext,#tcr.cs_limit])
1795        __(cmp temp2,arg_x)       
1796        __(mov temp2,sp)
1797        __(mov arg_x,#stack_alloc_marker)
1798        __(bls 3f)
1799        __(stack_allocate_zeroed_ivector(imm1,temp1))
1800        __(unbox_fixnum(imm1,temp0))
1801        __(strb imm1,[sp])
1802        __(add arg_z,sp,#fulltag_misc)
1803        __(add imm0,sp,nargs)
1804        __(stmdb sp!,{arg_x,temp2})
1805        __(b 2f)
18061:
1807        __(vpop1(temp0))
1808        __(push1(temp0,imm0))
18092:      __(subs nargs,nargs,#fixnumone)
1810        __(bne 1b)
1811        __(add vsp,vsp,#fixnumone)
1812        __(bx lr)
18133:      /* Have to heap-cons. */       
1814        __(stmdb sp!,{arg_x,temp2})
1815        __(vpush1(nargs))
1816        __(mov arg_y,nargs)
1817        __(mov arg_z,temp0)
1818        __(build_lisp_frame(imm0))
1819        __(bl _SPmisc_alloc)
1820        __(restore_lisp_frame(imm0))
1821        __(vpop1(nargs))
1822        __(add imm0,nargs,#misc_data_offset)
1823        __(b 5f)
18244:      __(vpop1(temp0))
1825        __(subs imm0,imm0,#fixnumone)
1826        __(str temp0,[arg_z,imm0])
18275:      __(subs nargs,nargs,#fixnumone)
1828        __(bne 4b)
1829        __(add vsp,vsp,#fixnumone)
1830        __(bx lr)
1831       
1832/* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
1833/* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
1834/* parameters must be "reasonable" (the  subtag must be valid, the element  */
1835/* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
1836/* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
1837/* proper header on it and its contents will be 0.   imm0 contains   */
1838/* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
1839
1840_spentry(misc_alloc)
1841        __(tst arg_y,#unsigned_byte_24_mask)
1842        __(bne 9f)
1843        __(unbox_fixnum(imm0,arg_z))
1844        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1845        __(extract_fulltag(imm1,imm0))
1846        __(cmp imm1,#fulltag_nodeheader)
1847        __(mov imm2,arg_y)      /* imm2 = logical size in bytes */
1848        __(beq 1f)
1849        __(unbox_fixnum(imm1,arg_z))
1850        __(cmp imm1,#max_32_bit_ivector_subtag)
1851        __(ble 1f)
1852        __(mov imm2,arg_y,lsr #2)
1853        __(cmp imm1,#max_8_bit_ivector_subtag)
1854        __(ble 1f)
1855        __(mov imm2,arg_y,lsr #1)
1856        __(cmp imm1,#max_16_bit_ivector_subtag)
1857        __(ble 1f)
1858        __(mov imm2,arg_y,lsl #1)
1859        __(add imm2,imm2,#node_size)
1860        __(cmp imm1,#subtag_double_float_vector)
1861        __(beq 1f)
1862        __(add imm2,arg_y,#7<<fixnumshift)
1863        __(mov imm2,imm2,lsr #3+fixnumshift)
1864        /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
1865        /* low three bits.  */
18661:
1867        __(dnode_align(imm2,imm2,node_size))
1868        __(Misc_Alloc(arg_z,imm0,imm2))
1869        __(bx lr)
18709:
1871        __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
1872
1873
1874
1875_spentry(atomic_incf_node)
1876        __(build_lisp_frame(imm0))
1877        __(add lr,arg_y,arg_z,asr #fixnumshift)
18780:      __(ldrex arg_z,[lr])
1879        __(add arg_z,arg_z,arg_x)
1880        __(strex imm0,arg_z,[lr])
1881        __(cmp imm0,#0)
1882        __(bne 0b)
1883       /* Return this way, to get something else in the lr */
1884        __(restore_lisp_frame(imm0))
1885        __(bx lr)
1886       
1887_spentry(unused1)
1888
1889_spentry(unused2)
1890
1891/* vpush the values in the value set atop the stack, incrementing nargs.  */
1892
1893define(`mvcall_older_value_set',`node_size')
1894define(`mvcall_younger_value_set',`node_size+4')
1895       
1896
1897_spentry(recover_values)
1898        __(add temp0,sp,#dnode_size)
1899        /* Find the oldest set of values by walking links from the newest */
19000:             
1901        __(ldr temp1,[temp0,#mvcall_older_value_set])
1902        __(cmp temp1,#0)
1903        __(movne temp0,temp1)
1904        __(bne 0b)
19051:      __(ldr imm0,[temp0])
1906        __(header_length(imm0,imm0))
1907        __(subs imm0,imm0,#2<<fixnumshift)
1908        __(add temp1,temp0,#node_size+8)
1909        __(add temp1,temp1,imm0)
1910        __(b 3f)
19112:      __(subs imm0,imm0,#fixnumone)       
1912        __(ldr arg_z,[temp1,#-node_size]!)
1913        __(vpush1(arg_z))
1914        __(add nargs,nargs,#fixnumone)
19153:      __(bne 2b)
1916        __(ldr temp0,[temp0,#mvcall_younger_value_set])
1917        __(cmp temp0,#0)
1918        __(bne 1b)
1919        __(ldr sp,[sp,#node_size])
1920        __(bx lr)
1921
1922
1923/* If arg_z is an integer, return in imm0 something whose sign  */
1924/* is the same as arg_z's.  If not an integer, error.  */
1925_spentry(integer_sign)
1926        __(test_fixnum(arg_z))
1927        __(moveq imm0,arg_z)
1928        __(bxeq lr)
1929        __(extract_typecode(imm0,arg_z))
1930        __(cmp imm0,#subtag_bignum)
1931        __(beq 1f)
1932        __(uuo_error_reg_not_xtype(al,arg_z,xtype_integer))
19331:             
1934        __(getvheader(imm1,arg_z))
1935        __(header_length(imm0,imm1)) /* boxed length = scaled size  */
1936        __(add imm0,imm0,#misc_data_offset-4) /* bias, less 1 element  */
1937        __(ldr imm0,[arg_z,imm0])
1938        __(cmp imm0,#0)
1939        __(movge imm0,#1)
1940        __(movlt imm0,#-1)
1941        __(bx lr)
1942
1943
1944/* like misc_set, only pass the (boxed) subtag in temp0  */
1945_spentry(subtag_misc_set)
1946        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
1947        __(trap_unless_fixnum(arg_y))
1948        __(vector_length(imm0,arg_x,imm1))
1949        __(cmp arg_y,imm0)
1950        __(blo 1f)
1951        __(uuo_error_vector_bounds(al,arg_y,arg_x))
19521:             
1953        __(unbox_fixnum(imm1,temp0))
1954        __(b C(misc_set_common))
1955
1956
1957
1958/* misc_set (vector index newval).  Pretty damned similar to  */
1959/* misc_ref, as one might imagine.  */
1960
1961_spentry(misc_set)
1962        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
1963        __(trap_unless_fixnum(arg_y))
1964        __(vector_length(imm0,arg_x,imm1))
1965        __(cmp arg_y,imm0)
1966        __(blo 1f)
1967        __(uuo_error_vector_bounds(al,arg_y,arg_x))
19681:             
1969        __(extract_lowbyte(imm1,imm1))
1970        __(b C(misc_set_common))
1971
1972/* "spread" the lexpr in arg_z.  */
1973/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1974_spentry(spread_lexprz)
1975        __(ldr imm0,[arg_z,#0])
1976        __(add imm1,arg_z,imm0)
1977        __(add nargs,nargs,imm0)
1978        __(add imm1,imm1,#node_size)
1979        __(cmp imm0,#3<<fixnumshift)
1980        __(bge 9f)
1981        __(cmp imm0,#2<<fixnumshift)
1982        __(beq 2f)
1983        __(cmp imm0,#0)
1984        __(bne 1f)
1985/* lexpr count was 0; vpop the arg regs that  */
1986/* were vpushed by the caller  */
1987        __(cmp nargs,#0)
1988        __(bxeq lr)
1989        __(vpop_argregs_nz)
1990        __(bx lr)
1991
1992/* vpush args from the lexpr until we have only  */
1993/* three left, then assign them to arg_x, arg_y,  */
1994/* and arg_z.  */
19958:
1996        __(cmp imm0,#4<<fixnumshift)
1997        __(sub imm0,imm0,#fixnumone)
1998        __(ldr arg_z,[imm1,#-node_size]!)
1999        __(vpush1(arg_z))
20009:
2001        __(bne 8b)
2002        __(ldr arg_x,[imm1,#-node_size*1])
2003        __(ldr arg_y,[imm1,#-node_size*2])
2004        __(ldr arg_z,[imm1,#-node_size*3])
2005        __(bx lr)
2006
2007/* lexpr count is two: set arg_y, arg_z from the  */
2008/* lexpr, maybe vpop arg_x  */
20092:
2010        __(cmp nargs,#2<<fixnumshift)
2011        __(ldr arg_y,[imm1,#-node_size*1])
2012        __(ldr arg_z,[imm1,#-node_size*2])
2013        __(bxeq lr)  /* return if (new) nargs = 2  */
2014        __(vpop1(arg_x))
2015        __(bx lr)
2016
2017/* lexpr count is one: set arg_z from the lexpr,  */
2018/* maybe vpop arg_y, arg_x  */
20191: 
2020        __(cmp nargs,#2<<fixnumshift)
2021        __(ldr arg_z,[imm1,#-node_size])
2022        __(bxlt lr)  /* return if (new) nargs < 2  */
2023        __(vpop1(arg_y))
2024        __(bxeq lr)  /* return if (new) nargs = 2  */
2025        __(vpop1(arg_x))
2026        __(bx lr)
2027
2028
2029_spentry(reset)
2030        __(nop)
2031        __(ref_nrs_value(temp0,toplcatch))
2032        __(mov temp1,#XSTKOVER)
2033        __(vpush1(temp0))
2034        __(vpush1(temp1))
2035        __(set_nargs(1))
2036        __(b _SPthrow)
2037
2038
2039/* "slide" nargs worth of values up the vstack.  IMM0 contains  */
2040/* the difference between the current VSP and the target.  */
2041_spentry(mvslide)
2042        __(cmp nargs,#0)
2043        __(mov temp1,nargs)
2044        __(add imm1,vsp,nargs)
2045        __(add imm1,imm1,imm0)
2046        __(add imm0,vsp,nargs)
2047        __(beq 2f)
20481:
2049        __(subs temp1,temp1,#1<<fixnumshift)
2050        __(ldr temp0,[imm0,#-node_size]!)
2051        __(str temp0,[imm1,#-node_size]!)
2052        __(bne 1b)
20532:
2054        __(mov vsp,imm1)
2055        __(bx lr)
2056
2057                     
2058_spentry(save_values)
2059        __(mov temp1,#0)
2060        __(mov arg_x,sp)
2061local_label(save_values_to_tsp):
2062        __(add imm1,nargs,#node_size*2)
2063        __(dnode_align(imm0,imm1,node_size))
2064        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
2065        __(orr imm1,imm1,#subtag_u32_vector)
2066        __(stack_allocate_zeroed_ivector(imm1,imm0))
2067        __(cmp temp1,$0)
2068        __(mov imm1,#subtag_simple_vector)
2069        __(mov arg_y,#stack_alloc_marker)
2070        __(strb imm1,[sp])
2071        __(mov temp0,sp)
2072        __(stmdb sp!,{arg_y,arg_x})
2073        __(str temp1,[temp0,#mvcall_older_value_set])
2074        __(strne temp0,[temp1,#mvcall_younger_value_set])
2075        __(add temp0,temp0,#node_size+8)
2076        __(mov imm0,#0)
2077        __(b 2f)
20781:      __(vpop1(temp1))
2079        __(str temp1,[temp0],#node_size)
2080        __(add imm0,imm0,#node_size)
20812:      __(cmp imm0,nargs)
2082        __(bne 1b)
2083        __(bx lr)
2084       
2085_spentry(add_values)
2086        __(cmp nargs,#0)
2087        __(ldr arg_x,[sp,#node_size])
2088        __(bxeq lr)
2089        __(add sp,sp,#dnode_size)
2090        __(mov temp1,sp)
2091        __(b local_label(save_values_to_tsp))
2092
2093
2094/* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
2095/* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
2096/* Calls out to %init-misc, which does the rest of the work.  */
2097
2098_spentry(misc_alloc_init)
2099        __(build_lisp_frame(imm0))
2100        __(mov fn,#0)
2101        __(mov temp2,arg_z)  /* initval  */
2102        __(mov arg_z,arg_y)  /* subtag  */
2103        __(mov arg_y,arg_x)  /* element-count  */
2104        __(bl _SPmisc_alloc)
2105        __(restore_lisp_frame(imm0))
2106        __(mov arg_y,temp2)
2107initialize_vector:             
2108        __(ref_nrs_symbol(fname,init_misc,imm0))
2109        __(set_nargs(2))
2110        __(jump_fname())
2111
2112/* As in stack_misc_alloc above, only with a non-default initial-value.  */
2113/* Note that this effectively inlines _SPstack_misc_alloc. */               
2114 
2115_spentry(stack_misc_alloc_init)
2116        __(tst arg_x,#unsigned_byte_24_mask)
2117        __(beq 1f)
2118        __(uuo_error_reg_not_xtype(al,arg_x,xtype_unsigned_byte_24))
21191:             
2120        __(unbox_fixnum(imm0,arg_y))
2121        __(extract_fulltag(imm1,imm0))
2122        __(cmp imm1,#fulltag_nodeheader)
2123        __(bne stack_misc_alloc_init_ivector)
2124        __(dnode_align(imm1,arg_x,node_size))
2125        __(ldr temp1,[rcontext,#tcr.cs_limit])
2126        __(sub temp0,sp,imm1)
2127        __(cmp temp0,temp1)
2128        __(bls stack_misc_alloc_init_no_room)
2129        __(mov imm0,#subtag_u32_vector)
2130        __(orr imm0,imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
2131        __(mov temp0,#stack_alloc_marker)
2132        __(mov temp1,sp)
2133        __(stack_allocate_zeroed_ivector(imm0,imm1))
2134        __(unbox_fixnum(imm0,arg_y))
2135        __(strb imm0,[sp])
2136        __(mov arg_y,arg_z)
2137        __(add arg_z,sp,#fulltag_misc)
2138        __(stmdb sp!,{temp0,temp1})
2139        __(b initialize_vector)
2140
2141 
2142_spentry(popj)
2143        .globl C(popj)
2144C(popj):
2145        __(return_lisp_frame(imm0))
2146
2147
2148
2149/* Divide the 64 bit unsigned integer in imm0 (low) and imm1 (high) by
2150   the 32-bit unsigned integer in imm2; return the quotient in
2151   imm0:imm1 and remainder in imm2.  We pretty much have to do this
2152   as an ff call; even if we wrote the code ourselves, we'd have to
2153   enter foreign context to use as many imm regs as we'd need.
2154   Moral: don't do integer division on the ARM.
2155*/
2156        .globl C(__aeabi_uldivmod)       
2157_spentry(udiv64by32)
2158        __(cmp imm2,#0)
2159        __(bne 1f)
2160        __(build_lisp_frame(imm2))
2161        __(bl _SPmakeu64)
2162        __(mov arg_y,#XDIVZRO)
2163        __(mov nargs,#2<<fixnumshift)
2164        __(restore_lisp_frame(imm0))
2165        __(b _SPksignalerr)
21661:             
2167        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2168        __(str vsp,[rcontext,#tcr.save_vsp])
2169        __(mov arg_z,rcontext)
2170        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2171        __(build_lisp_frame(r3))
2172        __(str sp,[arg_z,#tcr.last_lisp_frame])
2173        __(str allocptr,[arg_z,#tcr.save_allocptr])
2174        __(mov r3,#TCR_STATE_FOREIGN)
2175        __(str r3,[arg_z,#tcr.valence])
2176        __(mov r3,#0)
2177        __(bl C(__aeabi_uldivmod))
2178        __(mov rcontext,arg_z)
2179        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2180        __(mov allocptr,#VOID_ALLOCPTR)
2181        __(mov fn,#0)
2182        __(mov temp2,#0)
2183        __(mov temp1,#0)
2184        __(mov temp0,#0)
2185        __(mov arg_x,#TCR_STATE_LISP)
2186        __(str arg_x,[rcontext,#tcr.valence])
2187        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2188        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2189        __(ldr fn,[sp,#lisp_frame.savefn])
2190        __(ldr lr,[sp,#lisp_frame.savelr])
2191        __(discard_lisp_frame())
2192        __(bx lr)
2193
2194
2195/* arg_z should be of type (UNSIGNED-BYTE 64);  */
2196/* return high 32 bits in imm1, low 32 bits in imm0 */
2197
2198
2199_spentry(getu64)
2200        __(test_fixnum(arg_z))
2201        __(bne 1f)
2202        __(unbox_fixnum(imm0,arg_z))
2203        __(movs imm1,imm0,asr #31)
2204        __(bxeq lr)
22050:             
2206        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
22071:
2208        __(extract_typecode(imm0,arg_z))
2209        __(cmp imm0,#subtag_bignum)
2210        __(bne 0b)
2211        __(movc16(imm1,two_digit_bignum_header))
2212        __(getvheader(imm0,arg_z))
2213        __(cmp imm0,imm1)
2214        __(bne 2f)
2215        __(vrefr(imm0,arg_z,0))
2216        __(vrefr(imm1,arg_z,1))
2217        __(cmp imm1,#0)
2218        __(bxge lr)
2219        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
22202:      __(movc16(imm1,three_digit_bignum_header))
2221        __(cmp imm0,imm1)
2222        __(bne 3f)
2223        __(vrefr(imm2,arg_z,2))
2224        __(cmp imm2,#0)
2225        __(vrefr(imm1,arg_z,1))
2226        __(vrefr(imm0,arg_z,0))
2227        __(bxeq lr)
2228        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
22293:      __(movc16(imm1,one_digit_bignum_header))
2230        __(cmp imm0,imm1)
2231        __(bne 0b)
2232        __(vrefr(imm0,arg_z,0))
2233        __(mov imm1,#0)
2234        __(cmp imm0,#0)
2235        __(bxgt lr)
2236        __(b 0b)
2237        __
2238         
2239/* arg_z should be of type (SIGNED-BYTE 64);  */
2240/*    return high 32 bits  in imm1, low 32 bits in imm0  */
2241
2242_spentry(gets64)
2243        __(test_fixnum(arg_z))
2244        __(moveq imm0,arg_z,asr #fixnumshift)
2245        __(moveq imm1,imm0,asr #31)
2246        __(bxeq lr)
2247        __(mov imm2,#0)
2248        __(extract_lisptag(imm0,arg_z))
2249        __(cmp imm0,#tag_misc)
2250        __(movc16(imm1,one_digit_bignum_header))
2251        __(ldreq imm2,[arg_z,#misc_header_offset])
2252        __(cmp imm1,imm2)
2253        __(bne 0f)
2254        __(vrefr(imm0,arg_z,0))
2255        __(mov imm1,imm0,asr #31)
2256        __(bx lr)
22570:     
2258        __(movc16(imm1,two_digit_bignum_header))
2259        __(cmp imm1,imm2)
2260        __(beq 1f)
2261        __(uuo_error_reg_not_xtype(al,arg_z,xtype_s64))
22621:             
2263        __(vrefr(imm1,arg_z,1))
2264        __(vrefr(imm0,arg_z,0))
2265        __(bx lr)
2266
2267
2268/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
2269/* unbound_marker), arg_y = symbol, imm1 = symbol.binding-index  */
2270_spentry(specref)
2271        __(ldr imm1,[arg_z,#symbol.binding_index])
2272        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2273        __(cmp imm1,imm0)
2274        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
2275        __(mov arg_y,arg_z)
2276        __(movhs imm1,#0)
2277        __(ldr arg_z,[temp0,imm1])
2278        __(cmp arg_z,#no_thread_local_binding_marker)
2279        __(ldreq arg_z,[arg_y,#symbol.vcell])
2280        __(bx lr)
2281
2282_spentry(specrefcheck)
2283        __(ldr imm1,[arg_z,#symbol.binding_index])
2284        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2285        __(cmp imm1,imm0)
2286        __(movhs imm1,#0)
2287        __(ldr imm0,[rcontext,#tcr.tlb_pointer])
2288        __(mov arg_y,arg_z)
2289        __(ldr arg_z,[imm0,imm1])
2290        __(cmp arg_z,#no_thread_local_binding_marker)
2291        __(ldreq arg_z,[arg_y,#symbol.vcell])
2292        __(cmp arg_z,#unbound_marker)
2293        __(bxne lr)
2294        __(uuo_error_unbound(al,arg_y))
2295        __(bx lr)
2296
2297/* arg_y = special symbol, arg_z = new value.          */
2298_spentry(specset)
2299        __(ldr imm1,[arg_y,#symbol.binding_index])
2300        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2301        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
2302        __(cmp imm1,imm0)
2303        __(movge imm1,#0)
2304        __(ldr temp1,[imm2,imm1])
2305        __(cmp temp1,#no_thread_local_binding_marker)
2306        __(strne arg_z,[imm2,imm1])
2307        __(bxne lr)
2308        __(mov arg_x,arg_y)
2309        __(mov arg_y,#symbol.vcell-misc_data_offset)
2310        __(b _SPgvset)
2311
2312
2313       
2314/* Construct a lisp integer out of the 32-bit signed value in imm0 */
2315/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
2316
2317_spentry(gets32)
2318        __(test_fixnum(arg_z))
2319        __(moveq imm0,arg_z,asr #fixnumshift)
2320        __(bxeq lr)
2321        __(extract_lisptag(imm0,arg_z))
2322        __(cmp imm0,#tag_misc)
2323        __(beq 1f)
2324        __(uuo_error_reg_not_xtype(al,arg_z,xtype_s32))
23251:             
2326        __(getvheader(imm0,arg_z))
2327        __(movc16(imm1,one_digit_bignum_header))
2328        __(cmp imm0,imm1)
2329        __(beq 2f)
2330        __(uuo_error_reg_not_xtype(al,arg_z,xtype_s32))
23312:             
2332        __(vrefr(imm0,arg_z,0))
2333        __(bx lr)       
2334
2335
2336/*  */
2337/* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
2338/*  */
2339
2340_spentry(getu32)
2341        __(test_fixnum(arg_z))
2342        __(moveq imm0,arg_z,asr #fixnumshift)
2343        __(movseq imm1,imm0,asr #31)
2344        __(bxeq lr)
2345        __(movc16(imm1,one_digit_bignum_header))
2346        __(extract_lisptag(imm0,arg_z))
2347        __(cmp imm0,#tag_misc)
2348        __(beq 1f)
2349        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u32))
23501:             
2351        __(getvheader(imm0,arg_z))
2352        __(cmp imm0,imm1)
2353        __(ldreq imm0,[arg_z,#misc_data_offset])
2354        __(beq 7f)
2355        __(movc16(imm1,two_digit_bignum_header))
2356        __(cmp imm0,imm1)
2357        __(ldreq imm0,[arg_z,#misc_data_offset])
2358        __(ldreq imm1,[arg_z,#misc_data_offset+4])
2359        __(cmpeq imm1,#0)
2360        __(bxeq lr)
2361        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u32))
23627:             
2363        __(movs imm1,imm0,asr #31)
2364        __(bxeq lr)
2365        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u32))
2366
2367
2368/* */
2369/* As per mvpass above, but in this case fname is known to be a */
2370/* symbol. */
2371
2372_spentry(mvpasssym)
2373        __(cmp nargs,#node_size*nargregs)
2374        __(mov imm1,vsp)
2375        __(subgt imm1,imm1,#node_size*nargregs)
2376        __(addgt imm1,imm1,nargs)
2377        __(build_lisp_frame(imm0,imm1))
2378        __(ref_global(lr,ret1val_addr,imm0))
2379        __(mov fn,#0)
2380        __(jump_fname())
2381
2382_spentry(unbind)
2383        __(ldr imm1,[rcontext,#tcr.db_link])
2384        __(ldr temp0,[rcontext,#tcr.tlb_pointer])   
2385        __(ldr imm0,[imm1,#binding.sym])
2386        __(ldr temp1,[imm1,#binding.val])
2387        __(ldr imm1,[imm1,#binding.link])
2388        __(str temp1,[temp0,imm0])
2389        __(str imm1,[rcontext,#tcr.db_link])
2390        __(bx lr)
2391
2392/* Clobbers imm1,temp0,arg_x, arg_y */       
2393_spentry(unbind_n)
2394        __(ldr imm1,[rcontext,#tcr.db_link])
2395        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
23961:      __(ldr temp0,[imm1,#binding.sym])
2397        __(ldr arg_y,[imm1,#binding.val])
2398        __(ldr imm1,[imm1,#binding.link])
2399        __(subs imm0,imm0,#1)
2400        __(str arg_y,[arg_x,temp0])
2401        __(bne 1b)
2402        __(str imm1,[rcontext,#tcr.db_link])
2403        __(bx lr)
2404
2405/* */
2406/* Clobbers imm1,temp0,arg_x, arg_y */
2407
2408_spentry(unbind_to)
2409        do_unbind_to(imm1,temp1,arg_x,arg_y)
2410        __(bx lr)
2411 
2412
2413 
2414/* */
2415/* Restore the special bindings from the top of the tstack,  */
2416/* leaving the tstack frame allocated.  */
2417/* Note that there might be 0 saved bindings, in which case  */
2418/* do nothing.  */
2419/* Note also that this is -only- called from an unwind-protect  */
2420/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
2421/* values in a frame on top of the tstack.  */
2422/*  */
2423                         
2424_spentry(progvrestore)
2425        __(skip_stack_vector(imm0,imm1,sp))
2426        __(ldr imm0,[imm0,#lisp_frame.size+(9*8)+node_size]) /* 7*8 = size of saved FPR vector, with header */
2427        __(cmp imm0,#0)
2428        __(unbox_fixnum(imm0,imm0))
2429        __(bne _SPunbind_n)
2430        __(bx lr)
2431
2432/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
2433/* for pending interrupts after doing so.  */
2434_spentry(bind_interrupt_level_0)
2435        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2436        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2437        __(ldr imm0,[rcontext,#tcr.db_link])
2438        __(cmp temp0,#0)
2439        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2440        __(vpush1(temp0))
2441        __(vpush1(imm1))
2442        __(vpush1(imm0))
2443        __(mov imm0,#0)
2444        __(str imm0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2445        __(str vsp,[rcontext,#tcr.db_link])
2446        __(bxeq lr)
2447        __(ldrlt temp0,[rcontext,#tcr.interrupt_pending])
2448        __(cmp temp0,#0)
2449        __(bxle lr)
2450        __(uuo_interrupt_now(al))
2451        __(bx lr)
2452       
2453/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
2454/* of disabling interrupts.)  */
2455_spentry(bind_interrupt_level_m1)
2456        __(mov imm2,#-fixnumone)
2457        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2458        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2459        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2460        __(ldr imm0,[rcontext,#tcr.db_link])
2461        __(vpush1(temp0))
2462        __(vpush1(imm1))
2463        __(vpush1(imm0))
2464        __(str imm2,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2465        __(str vsp,[rcontext,tcr.db_link])
2466        __(bx lr)
2467       
2468
2469/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
2470/* do what _SPbind_interrupt_level_0 does  */
2471_spentry(bind_interrupt_level)
2472        __(cmp arg_z,#0)
2473        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2474        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2475        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2476        __(ldr imm0,[rcontext,#tcr.db_link])
2477        __(beq _SPbind_interrupt_level_0)
2478        __(vpush1(temp0))
2479        __(vpush1(imm1))
2480        __(vpush1(imm0))
2481        __(str arg_z,[temp1,INTERRUPT_LEVEL_BINDING_INDEX])
2482        __(str vsp,[rcontext,#tcr.db_link])
2483        __(bx lr)
2484
2485/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
2486/* non-negative, check for pending interrupts.  This is often called in */
2487/* a context where nargs is significant, so save and restore nargs around */
2488/* any interrupt polling  */
2489         
2490_spentry(unbind_interrupt_level)
2491        __(ldr imm0,[rcontext,#tcr.flags])
2492        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
2493        __(tst imm0,#1<<TCR_FLAG_BIT_PENDING_SUSPEND)
2494        __(ldr imm0,[rcontext,#tcr.db_link])
2495        __(ldr temp0,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2496        __(bne 5f)
24970:     
2498        __(ldr temp1,[imm0,#binding.val])
2499        __(ldr imm0,[imm0,#binding.link])
2500        __(str temp1,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2501        __(str imm0,[rcontext,#tcr.db_link])
2502        __(cmp temp0,#0)
2503        __(bxge lr)
2504        __(cmp temp1,#0)
2505        __(bxlt lr)
2506        __(check_enabled_pending_interrupt(imm0,1f))
25071:             
2508        __(bx lr)
25095:       /* Missed a suspend request; force suspend now if we're restoring
2510          interrupt level to -1 or greater */
2511        __(cmp temp0,#-2<<fixnumshift)
2512        __(bne 0b)
2513        __(ldr imm0,[imm1,#binding.val])
2514        __(cmp imm0,temp0)
2515        __(beq 0b)
2516        __(mov imm0,#1<<fixnumshift)
2517        __(str imm0,[temp2,INTERRUPT_LEVEL_BINDING_INDEX])
2518        __(suspend_now())
2519        __(b 0b)
2520 
2521 
2522/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
2523    We don't know whether the array is alleged to be simple or
2524   not, and don't know anythng about the element type.  */
2525_spentry(aref2)
2526        __(trap_unless_fixnum(arg_y))
2527        __(trap_unless_fixnum(arg_z))
2528        __(extract_typecode(imm2,arg_x))
2529        __(cmp imm2,#subtag_arrayH)
2530        __(ldreq imm1,[arg_x,#arrayH.rank])
2531        __(cmpeq imm1,#2<<fixnumshift)
2532        __(beq 1f)
2533        __(uuo_error_reg_not_xtype(al,arg_x,xtype_array2d))
25341:             
2535        /* It's a 2-dimensional array.  Check bounds */
2536        __(ldr imm0,[arg_x,#arrayH.dim0])
2537        __(cmp arg_y,imm0)
2538        __(blo 2f)
2539        __(mov temp0,#0)
2540        __(uuo_error_array_axis_bounds(al,arg_y,temp0,arg_x))
25412:             
2542        __(ldr imm0,[arg_x,#arrayH.dim0+node_size])
2543        __(cmp arg_z,imm0)
2544        __(blo 3f)
2545        __(mov temp0,#fixnumone)
2546        __(uuo_error_array_axis_bounds(al,arg_z,temp0,arg_x))
25473:             
2548        __(unbox_fixnum(imm0,imm0))
2549        __(mla arg_z,arg_y,imm0,arg_z)
2550        /* arg_z is now row-major-index; get data vector and
2551           add in possible offset */
2552        __(mov arg_y,arg_x)
25530:      __(ldr imm0,[arg_y,#arrayH.displacement])
2554        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2555        __(extract_subtag(imm1,arg_y))
2556        __(cmp imm1,#subtag_vectorH)
2557        __(add arg_z,arg_z,imm0)
2558        __(bgt C(misc_ref_common))
2559        __(b 0b)
2560 
2561/* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
2562_spentry(aref3)
2563        __(trap_unless_fixnum(arg_x))
2564        __(trap_unless_fixnum(arg_y))
2565        __(trap_unless_fixnum(arg_z))
2566        __(extract_typecode(imm2,temp0))
2567        __(mov imm1,#0)
2568        __(cmp imm2,#subtag_arrayH)
2569        __(ldreq imm1,[temp0,#arrayH.rank])
2570        __(cmp imm1,#3<<fixnumshift)
2571        __(beq 1f)
2572        __(uuo_error_reg_not_xtype(al,temp0,xtype_array3d))
25731:             
2574        /* It's a 3-dimensional array.  Check bounds */
2575        __(ldr imm2,[temp0,arrayH.dim0+(node_size*2)])
2576        __(ldr imm1,[temp0,#arrayH.dim0+node_size])
2577        __(ldr imm0,[temp0,#arrayH.dim0])
2578        __(cmp arg_z,imm2)
2579        __(blo 2f)
2580        __(mov imm0,#2<<fixnumshift)
2581        __(uuo_error_array_axis_bounds(al,arg_z,imm0,temp0))
25822:             
2583        __(cmp arg_y,imm1)
2584        __(blo 3f)
2585        __(mov imm0,#fixnumone)
2586        __(uuo_error_array_axis_bounds(al,arg_y,imm0,temp0))
25873:             
2588        __(cmp arg_x,imm0)
2589        __(blo 4f)
2590        __(mov imm0,#0<<fixnumshift)
2591        __(uuo_error_array_axis_bounds(al,arg_x,imm0,temp0))
25924:             
2593        __(unbox_fixnum(imm2,imm2))
2594        __(unbox_fixnum(imm1,imm1))
2595        /* (+ (* i dim1 dim2) (* j dim2) k) */
2596        __(mul imm1,imm2,imm1)
2597        __(mla imm2,arg_y,imm2,arg_z)   /* imm2 now a fixnum */
2598        __(mla arg_z,arg_x,imm1,imm2)
2599        __(mov arg_y,temp0)
26000:      __(ldr arg_x,[arg_y,#arrayH.displacement])
2601        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2602        __(extract_subtag(imm1,arg_y))
2603        __(cmp imm1,#subtag_vectorH)
2604        __(add arg_z,arg_x,arg_z)
2605        __(bgt C(misc_ref_common))
2606        __(b 0b)
2607
2608
2609
2610
2611/* As for aref2 above, but temp0 = array, arg_x = i, arg_y = j, arg_z = newval */
2612_spentry(aset2)
2613        __(extract_typecode(imm0,temp0))
2614        __(cmp imm0,#subtag_arrayH)
2615        __(ldreq imm0,[temp0,#arrayH.rank])
2616        __(cmpeq imm0,#2<<fixnumshift)
2617        __(beq 1f)
2618        __(uuo_error_reg_not_xtype(al,temp0,xtype_array2d))
26191:             
2620        __(trap_unless_fixnum(arg_x))
2621        __(trap_unless_fixnum(arg_y))
2622        /* It's a 2-dimensional array.  Check bounds */
2623        __(ldr imm0,[temp0,#arrayH.dim0])
2624        __(cmp arg_x,imm0)
2625        __(blo 2f)
2626        __(mov imm0,#0)
2627        __(uuo_error_array_axis_bounds(al,arg_x,imm0,temp0))
26282:             
2629        __(ldr imm0,[temp0,#arrayH.dim0+node_size])
2630        __(cmp arg_y,imm0)
2631        __(blo 3f)
2632        __(mov imm0,#1<<fixnumshift)
2633        __(uuo_error_array_axis_bounds(al,arg_y,imm0,temp0))
26343:             
2635        __(unbox_fixnum(imm0,imm0))
2636        __(mla arg_y,arg_x,imm0,arg_y)
2637        /* arg_y is now row-major-index; get data vector and
2638           add in possible offset */
2639        __(mov arg_x,temp0)
26400:      __(ldr imm0,[arg_x,#arrayH.displacement])
2641        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2642        __(extract_subtag(imm1,arg_x))
2643        __(cmp imm1,#subtag_vectorH)
2644        __(add arg_y,arg_y,imm0)
2645        __(bgt C(misc_set_common))
2646        __(b 0b)
2647
2648                 
2649/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
2650_spentry(aset3)
2651        __(extract_typecode(imm0,temp1))
2652        __(cmp imm0,#subtag_arrayH)
2653        __(ldreq imm0,[temp1,#arrayH.rank])
2654        __(cmpeq imm0,#3<<fixnumshift)
2655        __(beq 1f)
2656        __(uuo_error_reg_not_xtype(al,temp1,xtype_array3d))
26571:             
2658        __(trap_unless_fixnum(temp0))
2659        __(trap_unless_fixnum(arg_x))
2660        __(trap_unless_fixnum(arg_y))
2661        /* It's a 3-dimensional array.  Check bounds */
2662        __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)])
2663        __(ldr imm1,[temp1,#arrayH.dim0+node_size])
2664        __(ldr imm0,[temp1,#arrayH.dim0])
2665        __(cmp arg_y,imm2)
2666        __(blo 2f)
2667        __(mov imm0,#2<<fixnumshift)
2668        __(uuo_error_array_axis_bounds(al,arg_y,imm0,temp1))
26692:             
2670        __(cmp arg_x,imm1)
2671        __(blo 3f)
2672        __(mov imm0,#1<<fixnumshift)
2673        __(uuo_error_array_axis_bounds(al,arg_x,imm0,temp1))
26743:             
2675        __(cmp temp0,imm0)
2676        __(blo 4f)
2677        __(mov imm0,#0)
2678        __(uuo_error_array_axis_bounds(al,temp0,imm0,temp1))
26794:             
2680        __(unbox_fixnum(imm1,imm1))
2681        __(unbox_fixnum(imm2,imm2))
2682        /* (+ (* i dim1 dim2) (* j dim2) k) */
2683        __(mul imm1,imm2,imm1)
2684        __(mla imm2,arg_x,imm2,arg_y)   /* imm2 now a fixnum */
2685        __(mla arg_y,temp0,imm1,imm2)
2686        __(mov arg_x,temp1)
26870:      __(ldr temp0,[arg_x,#arrayH.displacement])
2688        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2689        __(extract_subtag(imm1,arg_x))
2690        __(cmp imm1,#subtag_vectorH)
2691        __(add arg_y,arg_y,temp0)
2692        __(bgt C(misc_set_common))
2693        __(b 0b)
2694
2695
2696/* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
2697/* pairs.  There'll be arg_z keyword arguments.  arg_y contains flags  */
2698/* that indicate whether &allow-other-keys was specified and whether  */
2699/* or not to leave the keyword/value pairs on the vstack for an &rest  */
2700/* argument.  Element 2 of the function in fn contains a vector of keyword.  */
2701/* If the number of arguments is greater than imm0, the difference must  */
2702/* be even.  */
2703/* All arg regs have been vpushed and the calling function has built a */
2704/* stack frame.  next_method_context must be preserved, as must the incoming */
2705/* key/value pairs and their number if we're going to make an &rest arg. */
2706           
2707
2708define(`keyword_flags',`arg_y')
2709define(`key_value_count',`arg_z')
2710
2711define(`keyword_flag_allow_other_keys',`(fixnumone<<0)')
2712define(`keyword_flag_seen_allow_other_keys',`(fixnumone<<1)')
2713define(`keyword_flag_rest',`(fixnumone<<2)')
2714define(`keyword_flag_unknown_keyword_seen',`(fixnumone<<3)')
2715define(`keyword_flag_current_aok',`(fixnumone<<4)')
2716
2717_spentry(keyword_bind)
2718        new_local_labels()       
2719        __(subs key_value_count,nargs,imm0)
2720        __(movmi key_value_count,#0)
2721        __(tst key_value_count,#fixnumone)
2722        __(bne local_label(odd_keywords))
2723        __(mov imm1,key_value_count,lsl #num_subtag_bits-fixnumshift)
2724        __(orr imm1,imm1,subtag_u32_vector)
2725        __(add imm0,key_value_count,#dnode_size) /* we know  count is even */
2726        __(stack_allocate_zeroed_ivector(imm1,imm0))
2727        __(mov imm0,#subtag_simple_vector)
2728        __(strb imm0,[sp])
2729        /* Copy key/value pairs in reverse order from the vstack to
2730           the gvector we just created on the cstack. */
2731        __(add imm0,vsp,key_value_count) /* src, predecrement */
2732        __(add imm1,sp,#node_size)       /* dest, postincrement */
2733        __(mov temp2,key_value_count)
2734        __(b 1f)
27350:      __(ldr arg_x,[imm0,#-node_size]!)
2736        __(str arg_x,[imm1],#node_size)
27371:      __(subs temp2,temp2,#fixnumone)
2738        __(bge 0b)
2739        /* Discard the key/value pairs from the vstack. */
2740        __(add vsp,vsp,key_value_count)
2741        __(ldr temp2,[fn,#misc_data_offset+(2*node_size)])
2742        __(getvheader(imm0,temp2))
2743        __(mov imm0,imm0,lsr #num_subtag_bits)
2744        __(mov temp0,vsp)
2745        __(mov imm1,#nil_value)
2746        /* Push a pair of NILs (value, supplied-p) for each defined keyword */
2747        __(b 3f)
27482:      __(vpush1(imm1))
2749        __(vpush1(imm1))
27503:      __(subs imm0,imm0,#1)
2751        __(bge 2b)
2752        /* Save nargs and temp1 so that we can use them in the loop(s) */
2753        __(stmdb vsp!,{imm2,temp1})
2754        /* For each provided key/value pair: if the key is :allow-other-keys
2755           and that hasn't been seen before, note that it's been seen and
2756           if the value is non-nil set the allow-other-keys bit in flags.
2757           Then search for the key in the defined keys vector.  If it's
2758           not found, note that an undefined keyword was seen by setting
2759           a bit in keyword_flags ; if it is found, use its position to
2760           index the table of value/supplied-p pairs that we pushed above.
2761           If the supplied-p var is already set, do nothing; otherwise,
2762           set the supplied-p var and value.
2763           When done, signal an error if we got an unknown keyword, or
2764           either copy the supplied key/value pairs back to the vstack
2765           if we're going to cons an &rest arg or discard them if we aren't.
2766        */
2767        __(mov imm2,#0)
2768        __(b local_label(nextvalpairtest))
2769local_label(nextvalpairloop):   
2770        __(add temp1,sp,#4)
2771        __(ldr temp1,[temp1,imm2])
2772        __(ref_nrs_symbol(imm1,kallowotherkeys,imm1))
2773        __(cmp temp1,imm1)
2774        __(orreq keyword_flags,keyword_flags,#keyword_flag_current_aok)
2775        __(tsteq keyword_flags,#keyword_flag_seen_allow_other_keys)
2776        __(bne local_label(current_key_allow_other_keys_handled))
2777        __(orr keyword_flags,keyword_flags,#keyword_flag_seen_allow_other_keys)
2778        /* Fortunately, we know what the keyword is.  Need to check the
2779           value here, and don't have a lot of free registers ... */
2780        __(add temp1,sp,#8)
2781        __(ldr temp1,[temp1,imm2])
2782        __(cmp temp1,#nil_value)
2783        __(orrne keyword_flags,keyword_flags,#keyword_flag_allow_other_keys)
2784        __(mov temp1,imm1)      /* from comparison above */
2785local_label(current_key_allow_other_keys_handled):
2786        __(getvheader(imm0,temp2))
2787        __(header_length(arg_x,imm0))
2788        __(add imm0,arg_x,#misc_data_offset)
2789        __(b local_label(defined_keyword_compare_test))
2790local_label(defined_keyword_compare_loop):     
2791        __(ldr arg_x,[temp2,imm0])
2792        __(cmp arg_x,temp1)
2793        __(subeq imm0,imm0,#misc_data_offset)
2794        __(beq local_label(defined_keyword_found))
2795local_label(defined_keyword_compare_test):     
2796        __(sub imm0,imm0,#node_size)
2797        __(cmp imm0,#misc_data_offset)
2798        __(bge local_label(defined_keyword_compare_loop))
2799        /* keyword wasn't defined.  Note that ... */
2800        __(tst keyword_flags,#keyword_flag_current_aok)
2801        __(bicne keyword_flags,#keyword_flag_current_aok)
2802        __(orreq keyword_flags,keyword_flags,#keyword_flag_unknown_keyword_seen)
2803        __(b local_label(nextkeyvalpairnext))
2804local_label(defined_keyword_found):     
2805        __(sub imm0,temp0,imm0,lsl #1)
2806        __(ldr arg_x,[imm0,#-8])
2807        __(cmp arg_x,#nil_value) /* seen this keyword yet ? */
2808        __(bne local_label(nextkeyvalpairnext))
2809        __(add arg_x,arg_x,#t_offset)
2810        __(str arg_x,[imm0,#-8])
2811        __(add temp1,sp,#8)
2812        __(ldr temp1,[temp1,imm2])
2813        __(str temp1,[imm0,#-4])
2814local_label(nextkeyvalpairnext):
2815        __(add imm2,imm2,#8)
2816local_label(nextvalpairtest):   
2817        __(cmp imm2,key_value_count)
2818        __(bne local_label(nextvalpairloop))
2819        __(ldmia vsp!,{imm2,temp1})
2820        /* If unknown keywords and that's not allowed, signal error.
2821           Otherwise, discard the stack-consed vector and return,
2822           possibly after having copied the vector's contents back
2823           to the vstack so that an &rest arg can be constructed.
2824        */
2825        __(tst keyword_flags,#keyword_flag_unknown_keyword_seen)
2826        __(beq 0f)
2827        __(tst keyword_flags,#keyword_flag_allow_other_keys)
2828        __(beq local_label(badkeys))
28290:      __(tst keyword_flags,#keyword_flag_rest)
2830        __(beq local_label(discard_stack_vector))
2831        __(mov imm0,#0)
2832        __(add temp2,sp,#node_size)
2833        __(b 2f)
28341:      __(ldr arg_x,[temp2],#node_size)
2835        __(vpush1(arg_x))
2836        __(add imm0,imm0,#fixnumone)
28372:      __(cmp imm0,key_value_count)
2838        __(bne 1b)
2839local_label(discard_stack_vector):     
2840        __(add key_value_count,key_value_count,#dnode_size)
2841        __(add sp,sp,key_value_count)
2842        __(bx lr)               /* it's finally over ! */
2843
2844local_label(badkeys):   /* Disturbingly similar to the &rest case */
2845        __(mov nargs,#0)
2846        __(add temp2,sp,#node_size)
2847        __(mov vsp,temp0)
2848        __(b 1f)
28490:      __(ldr arg_x,[temp2],#node_size)
2850        __(vpush1(arg_x))
2851        __(add nargs,nargs,#fixnumone)
28521:      __(cmp nargs,key_value_count)
2853        __(bne 0b)
2854        /* Lose the stack vector */
2855        __(add key_value_count,key_value_count,#dnode_size)
2856        __(add sp,sp,key_value_count)
2857local_label(error_exit):               
2858        __(bl _SPconslist)
2859        __(mov arg_y,#XBADKEYS)
2860        __(set_nargs(2))
2861        __(b _SPksignalerr)
2862local_label(odd_keywords):       
2863        __(mov nargs,key_value_count)
2864        __(b local_label(error_exit))
2865
2866        .globl C(__aeabi_uidivmod)               
2867_spentry(udiv32)
2868        __(cmp imm1,#0)
2869        __(bne 1f)
2870        __(build_lisp_frame(imm1))
2871        __(bl _SPmakeu32)
2872        __(mov arg_y,#XDIVZRO)
2873        __(mov nargs,#2<<fixnumshift)
2874        __(restore_lisp_frame(imm0))
2875        __(b _SPksignalerr)
28761:             
2877        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2878        __(str vsp,[rcontext,#tcr.save_vsp])
2879        __(mov arg_z,rcontext)
2880        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2881        __(build_lisp_frame(r3))
2882        __(str sp,[arg_z,#tcr.last_lisp_frame])
2883        __(str allocptr,[arg_z,#tcr.save_allocptr])
2884        __(mov r3,#TCR_STATE_FOREIGN)
2885        __(str r3,[arg_z,#tcr.valence])
2886        __(mov r3,#0)
2887        __(bl C(__aeabi_uidivmod))
2888        __(mov rcontext,arg_z)
2889        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2890        __(mov allocptr,#VOID_ALLOCPTR)
2891        __(mov fn,#0)
2892        __(mov temp2,#0)
2893        __(mov temp1,#0)
2894        __(mov temp0,#0)
2895        __(mov arg_x,#TCR_STATE_LISP)
2896        __(str arg_x,[rcontext,#tcr.valence])
2897        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2898        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2899        __(ldr fn,[sp,#lisp_frame.savefn])
2900        __(ldr lr,[sp,#lisp_frame.savelr])
2901        __(discard_lisp_frame())
2902        __(bx lr)
2903
2904_spentry(sdiv32)
2905        __(cmp imm1,#0)
2906        __(bne 1f)
2907        __(build_lisp_frame(imm1))
2908        __(bl _SPmakes32)
2909        __(mov arg_y,#XDIVZRO)
2910        __(mov nargs,#2<<fixnumshift)
2911        __(restore_lisp_frame(imm0))
2912        __(b _SPksignalerr)
29131:             
2914        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2915        __(str vsp,[rcontext,#tcr.save_vsp])
2916        __(mov arg_z,rcontext)
2917        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2918        __(build_lisp_frame(r3))
2919        __(str sp,[arg_z,#tcr.last_lisp_frame])
2920        __(str allocptr,[arg_z,#tcr.save_allocptr])
2921        __(mov r3,#TCR_STATE_FOREIGN)
2922        __(str r3,[arg_z,#tcr.valence])
2923        __(mov r3,#0)
2924        __(bl C(__aeabi_idivmod))
2925        __(mov rcontext,arg_z)
2926        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2927        __(mov allocptr,#VOID_ALLOCPTR)
2928        __(mov fn,#0)
2929        __(mov temp2,#0)
2930        __(mov temp1,#0)
2931        __(mov temp0,#0)
2932        __(mov arg_x,#TCR_STATE_LISP)
2933        __(str arg_x,[rcontext,#tcr.valence])
2934        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2935        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2936        __(ldr fn,[sp,#lisp_frame.savefn])
2937        __(ldr lr,[sp,#lisp_frame.savelr])
2938        __(discard_lisp_frame())
2939        __(bx lr)
2940       
2941
2942_spentry(eabi_ff_callhf)
2943        __(add imm0,sp,#8)
2944        __(fldmfdd imm0,{d0-d7})
2945        __(ldmia sp,{imm0-imm1})
2946        __(sub imm0,imm0,#(16<<num_subtag_bits))
2947        __(add imm2,sp,#16<<2)
2948        __(stm imm2,{imm0-imm1})
2949        __(mov sp,imm2)
2950_spentry(eabi_ff_call)
2951        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2952        __(stmdb vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2953        __(str vsp,[rcontext,#tcr.save_vsp])
2954/* There's a u32 vector on top of the stack ; its first data word points
2955   to the previous stack object.  The 4 words at the bottom of the vector
2956   are reserved for a lisp frame, which we construct carefully ... */
2957        __(mov imm0,#lisp_frame_marker)
2958        __(mov imm1,#0)
2959        __(ldr temp0,[sp,#4])
2960        __(sub temp0,temp0,#lisp_frame.size)
2961        __(str imm0,[temp0,#lisp_frame.marker])
2962        __(ldr imm0,[sp,#0])       
2963        __(str imm1,[temp0,#lisp_frame.savefn])
2964        __(str imm1,[temp0,#lisp_frame.savelr])
2965        __(sub imm0,imm0,#(lisp_frame.size/4)<<num_subtag_bits)
2966        __(str vsp,[temp0,#lisp_frame.savevsp])
2967        __(str imm0,[sp,#0])
2968        __(str lr,[temp0,#lisp_frame.savelr])
2969        __(str fn,[temp0,#lisp_frame.savefn])
2970        __(str allocptr,[rcontext,#tcr.save_allocptr])
2971        __(str temp0,[rcontext,#tcr.last_lisp_frame])
2972        __(mov temp0,rcontext)
2973        __(test_fixnum(arg_z))
2974        __(moveq imm1,arg_z,asr #fixnumshift)
2975        __(ldrne imm1,[arg_z,#misc_data_offset])
2976        __(mov imm0,#TCR_STATE_FOREIGN)
2977        __(str imm0,[rcontext,#tcr.valence])
2978        __(mov r4,imm1)
2979        __(add sp,sp,#dnode_size)
2980        __(ldmia sp!,{r0,r1,r2,r3})
2981        __(blx r4)
2982        __(adr temp1,1f)
2983        __(fldd double_float_zero,[temp1])
2984        __(mov temp1,#0)
2985        __(mov temp2,#0)
2986        __(mov arg_z,#0)
2987        __(mov arg_y,#0)
2988        __(mov arg_x,#0)
2989        __(mov fn,#0)
2990        __(mov allocptr,#VOID_ALLOCPTR)
2991        __(mov rcontext,temp0)
2992        __(ldr sp,[rcontext,#tcr.last_lisp_frame])
2993        __(str fn,[rcontext,#tcr.valence])
2994        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2995        __(restore_lisp_frame(temp0))
2996        __(ldmia vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2997        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2998        __(check_pending_interrupt(temp2))
2999        __(bx lr)
3000        .align 3
30011:      .long 0
3002        .long 0               
3003       
3004
3005_spentry(debind)
3006        new_local_labels()
3007        __(mov temp0,vsp)
3008        __(mov temp1,arg_z)
3009        __(ands imm0,nargs,#0xff)
3010        __(mov arg_y,#nil_value)
3011        __(b local_label(req_test))
3012local_label(req_loop): 
3013        __(cmp arg_reg,#nil_value)
3014        __(extract_lisptag(imm1,arg_reg))
3015        __(beq local_label(toofew))
3016        __(cmp imm1,#tag_list)
3017        __(bne local_label(badlist))
3018        __(subs imm0,imm0,#1)
3019        __(_car(arg_x,arg_reg))
3020        __(_cdr(arg_reg,arg_reg))
3021        __(vpush1(arg_x))
3022local_label(req_test):
3023        __(bne local_label(req_loop))
3024        __(mov imm0,#0xff)
3025        __(ands imm0,imm0,nargs,lsr #8)
3026        __(beq local_label(rest_keys))
3027        __(tst nargs,#mask_initopt)
3028        __(bne local_label(opt_supp))
3029        /* 'simple' &optionals:  no supplied-p, default to nil.   */
3030local_label(simple_opt_loop):
3031        __(cmp arg_reg,#nil_value)
3032        __(extract_lisptag(imm1,arg_reg))
3033        __(beq local_label(default_simple_opt))
3034        __(cmp imm1,#tag_list)
3035        __(bne local_label(badlist))
3036        __(subs imm0,imm0,#1)
3037        __(_car(arg_x,arg_reg))
3038        __(_cdr(arg_reg,arg_reg))
3039        __(vpush1(arg_x))
3040        __(bne local_label(simple_opt_loop))
3041        __(b local_label(rest_keys))
3042local_label(default_simple_opt):       
3043        __(subs imm0,imm0,#1)
3044        __(vpush1(arg_y))
3045        __(bne local_label(default_simple_opt))
3046        __(b local_label(rest_keys))
3047local_label(opt_supp):   
3048        __(cmp arg_reg,#nil_value)
3049        __(extract_lisptag(imm1,arg_reg))
3050        __(beq local_label(default_hard_opt))
3051        __(cmp imm1,#tag_list)
3052        __(bne local_label(badlist))
3053        __(subs imm0,imm0,#1)
3054        __(_car(arg_x,arg_reg))
3055        __(_cdr(arg_reg,arg_reg))
3056        __(vpush1(arg_x))
3057        __(add arg_x,arg_y,#t_offset)
3058        __(vpush1(arg_x))
3059        __(bne local_label(opt_supp))
3060        __(b local_label(rest_keys))
3061local_label(default_hard_opt): 
3062        __(subs imm0,imm0,#1)
3063        __(vpush1(arg_y))
3064        __(vpush1(arg_y))
3065        __(bne local_label(default_hard_opt))
3066local_label(rest_keys):
3067        __(tst nargs,#mask_restp)
3068        __(bne local_label(have_rest))
3069        __(tst nargs,#mask_keyp)
3070        __(bne local_label(have_keys))
3071        __(cmp arg_reg,#nil_value)
3072        __(bne local_label(toomany))
3073        __(bx lr)
3074local_label(have_rest):
3075        __(vpush1(arg_reg))
3076        __(tst nargs,#mask_keyp)
3077        __(bne local_label(have_keys))
3078        __(bx lr)
3079local_label(have_keys):
3080        __(mov imm0,#256)
3081        __(mov arg_y,arg_reg)
3082local_label(count_keys_loop):   
3083        __(cmp arg_y,#nil_value)
3084        __(beq local_label(counted_keys))
3085        __(subs imm0,imm0,#1)
3086        __(bmi local_label(toomany))
3087        __(extract_lisptag(imm1,arg_y))
3088        __(cmp imm1,#tag_list)
3089        __(bne local_label(badlist))
3090        __(_cdr(arg_y,arg_y))
3091        __(cmp arg_y,#nil_value)
3092        __(extract_lisptag(imm1,arg_y))
3093        __(beq local_label(badkeys))
3094        __(cmp imm1,#tag_list)
3095        __(bne local_label(badlist))
3096        __(_cdr(arg_y,arg_y))
3097        __(b local_label(count_keys_loop))
3098local_label(counted_keys):     
3099        /* We've got a proper, even-length list of key/value pairs in  */
3100        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
3101        /* of NILs on the vstack.  (We've also cdred down arg_y until it */
3102        /* contains NIL.) */
3103        __(mov imm0,#0xff)
3104        __(ands imm0,imm0,nargs,lsr #16)
3105        __(mov imm1,vsp)
3106        __(b local_label(push_pair_test))
3107local_label(push_pair_loop):
3108        __(subs imm0,imm0,#1)
3109        __(vpush1(arg_y))
3110        __(vpush1(arg_y))
3111local_label(push_pair_test):   
3112        __(bne local_label(push_pair_loop))
3113        __(b local_label(provided_key_loop))
3114       
3115local_label(next_provided_key):
3116        __(_car(arg_x,arg_reg))
3117        __(ref_nrs_symbol(imm0,kallowotherkeys,imm0))
3118        __(cmp arg_x,imm0)
3119        __(bne local_label(not_aok))
3120        __(orr nargs,nargs,#mask_aok_this)
3121        __(tst nargs,#mask_aok_seen)
3122        __(bne local_label(not_aok))
3123        __(_cdr(arg_x,arg_reg))
3124        __(_car(arg_x,arg_x))
3125        __(orr nargs,nargs,#mask_aok_seen)
3126        __(cmp arg_x,#nil_value)
3127        __(orrne nargs,nargs,#mask_aok)
3128        __(_car(arg_x,arg_reg))
3129local_label(not_aok):   
3130        __(getvheader(imm0,keyvect_reg))
3131        __(header_length(arg_y,imm0))
3132        __(add imm0,arg_y,#misc_data_offset)
3133        __(b local_label(match_key_test))
3134local_label(match_key_loop):   
3135        __(ldr arg_y,[keyvect_reg,imm0])
3136        __(cmp arg_x,arg_y)
3137        __(bne local_label(match_key_test))
3138        __(sub imm0,imm0,#misc_data_offset)
3139        __(sub imm0,imm1,imm0,lsl #1)
3140        __(ldr arg_y,[imm0,#-2*node_size])
3141        __(cmp arg_y,#nil_value)
3142        __(bne local_label(provided_key_done))
3143        __(_cdr(arg_x,arg_reg))
3144        __(_car(arg_x,arg_x))
3145        __(str arg_x,[imm0,#-node_size])
3146        __(mov arg_x,#nil_value)
3147        __(add arg_x,arg_x,#t_offset)
3148        __(str arg_x,[imm0,#-2*node_size])
3149        __(b local_label(provided_key_done))
3150local_label(match_key_test):   
3151        __(sub imm0,imm0,#node_size)
3152        __(cmp imm0,#misc_data_offset)
3153        __(bge local_label(match_key_loop))
3154        __(tst nargs,#mask_aok_this)
3155        __(bic nargs,nargs,#mask_aok_this)
3156        __(orreq nargs,nargs,#mask_unknown_keyword_seen)
3157local_label(provided_key_done):
3158        __(_cdr(arg_reg,arg_reg))
3159        __(_cdr(arg_reg,arg_reg))
3160local_label(provided_key_loop):
3161        __(cmp arg_reg,#nil_value)
3162        __(bne local_label(next_provided_key))
3163        __(tst nargs,#mask_unknown_keyword_seen)
3164        __(bxeq lr)
3165        __(tst nargs,#mask_aok)
3166        __(bxne lr)
3167local_label(badkeys):
3168        __(mov arg_y,#XBADKEYS)
3169        __(b local_label(destructure_error))
3170local_label(toomany):   
3171        __(mov arg_y,#XCALLTOOMANY)
3172        __(b local_label(destructure_error))
3173local_label(toofew):   
3174        __(mov arg_y,#XCALLTOOFEW)
3175        __(b local_label(destructure_error))
3176local_label(badlist):   
3177        __(mov arg_y,#XCALLNOMATCH)
3178local_label(destructure_error):
3179        __(mov vsp,temp0)
3180        __(mov arg_z,temp1)       
3181        __(set_nargs(2))
3182        __(b _SPksignalerr)
3183       
3184_spentry(eabi_callback)
3185        __(stmdb sp!,{r0,r1,r2,r3})
3186        __(mov r0,sp)
3187        __(sub sp,sp,#2*node_size) /* room for result */
3188        __(fstmdbd sp!,{d0-d7})
3189        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
3190        __(mov r4,r0)
3191        __(box_fixnum(r5,r12))
3192        __(ref_global(r12,get_tcr,r0))
3193        __(mov r0,#1)
3194        __(blx r12)
3195        __(mov rcontext,r0)
3196        __(tst sp,#4)
3197        __(mov imm2,sp)
3198        __(strne imm2,[sp,#-4]!)
3199        __(streq imm2,[sp,#-8]!)
3200        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
3201        __(sub imm0,imm2,sp)
3202        __(add imm0,imm0,#node_size)
3203        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
3204        __(orr imm0,imm0,#subtag_u32_vector)
3205        __(stmdb sp!,{imm0,imm2})
3206        __(push_foreign_fprs())
3207        __(adr imm0,1f)
3208        __(fldd double_float_zero,[imm0])
3209        __(mov arg_x,#0)
3210        __(mov temp0,#0)
3211        __(mov temp1,#0)
3212        __(mov temp2,#0)
3213        __(mov allocptr,#VOID_ALLOCPTR)
3214        __(mov fn,#0)
3215        __(ldr vsp,[rcontext,#tcr.save_vsp])
3216        __(mov imm0,#TCR_STATE_LISP)
3217        __(str imm0,[rcontext,#tcr.valence])
3218        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
3219        __(set_nargs(2))
3220        __(ref_nrs_symbol(fname,callbacks,imm0))
3221        __(ldr nfn,[fname,#symbol.fcell])
3222        __(ldr lr,[nfn,#_function.entrypoint])
3223        __(blx lr)
3224        __(str vsp,[rcontext,#tcr.save_vsp])
3225        __(ldr imm1,[sp,#(9*8)+4])
3226        __(str imm1,[rcontext,#tcr.last_lisp_frame])
3227        __(str allocptr,[rcontext,#tcr.save_allocptr])
3228        __(mov imm0,#TCR_STATE_FOREIGN)
3229        __(str imm0,[rcontext,#tcr.valence])
3230        __(pop_foreign_fprs())
3231        __(ldr sp,[sp,#node_size*2])   /* drop the ivector that hides foreign stack contents and restore (possibly misaligned) sp */
3232        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
3233        __(add sp,sp,#8*8)
3234        __(fldd d0,[sp,#0])
3235        __(ldmia sp!,{r0,r1})
3236        __(add sp,sp,#4*node_size)
3237        __(bx lr)
3238        .align 3
32391:     
3240        .long 0
3241        .long 0       
3242                       
3243/*  EOF, basically  */
3244       
3245_startfn(C(misc_ref_common))
3246        __(add pc,pc,imm1,lsl #2)
3247        __(nop)
3248
3249local_label(misc_ref_jmp):         
3250        /* 00-0f  */
3251        __(b local_label(misc_ref_invalid)) /* 00 even_fixnum  */
3252       
3253        __(b local_label(misc_ref_invalid)) /* 01 cons  */
3254        __(b local_label(misc_ref_node))    /* 02 pseudofunction */
3255        __(b local_label(misc_ref_invalid)) /* 03 imm  */
3256        __(b local_label(misc_ref_invalid)) /* 04 odd_fixnum  */
3257        __(b local_label(misc_ref_invalid)) /* 05 nil  */
3258        __(b local_label(misc_ref_invalid)) /* 06 misc  */
3259        __(b local_label(misc_ref_u32)) /* 07 bignum  */
3260        __(b local_label(misc_ref_invalid)) /* 08 even_fixnum  */
3261        __(b local_label(misc_ref_invalid)) /* 09 cons  */
3262        __(b local_label(misc_ref_node)) /* 0a ratio  */
3263        __(b local_label(misc_ref_invalid)) /* 0b imm  */
3264        __(b local_label(misc_ref_invalid)) /* 0c odd_fixnum  */
3265        __(b local_label(misc_ref_invalid)) /* 0d nil  */
3266        __(b local_label(misc_ref_invalid)) /* 0e misc  */
3267        __(b local_label(misc_ref_u32)) /* 0f single_float  */
3268        /* 10-1f  */
3269        __(b local_label(misc_ref_invalid)) /* 10 even_fixnum  */
3270        __(b local_label(misc_ref_invalid)) /* 11 cons  */
3271        __(b local_label(misc_ref_invalid)) /* 12 nodeheader  */
3272        __(b local_label(misc_ref_invalid)) /* 13 imm  */
3273        __(b local_label(misc_ref_invalid)) /* 14 odd_fixnum  */
3274        __(b local_label(misc_ref_invalid)) /* 15 nil  */
3275        __(b local_label(misc_ref_invalid)) /* 16 misc  */
3276        __(b local_label(misc_ref_u32)) /* 17 double_float  */
3277        __(b local_label(misc_ref_invalid)) /* 18 even_fixnum  */
3278        __(b local_label(misc_ref_invalid)) /* 19 cons  */
3279        __(b local_label(misc_ref_node)) /* 1a complex  */
3280        __(b local_label(misc_ref_invalid)) /* 1b imm  */
3281        __(b local_label(misc_ref_invalid)) /* 1c odd_fixnum  */
3282        __(b local_label(misc_ref_invalid)) /* 1d nil  */
3283        __(b local_label(misc_ref_invalid)) /* 1e misc  */
3284        __(b local_label(misc_ref_u32)) /* 1f macptr  */
3285        /* 20-2f  */
3286        __(b local_label(misc_ref_invalid)) /* 20 even_fixnum  */
3287        __(b local_label(misc_ref_invalid)) /* 21 cons  */
3288        __(b local_label(misc_ref_node)) /* 22 catch_frame  */
3289        __(b local_label(misc_ref_invalid)) /* 23 imm  */
3290        __(b local_label(misc_ref_invalid)) /* 24 odd_fixnum  */
3291        __(b local_label(misc_ref_invalid)) /* 25 nil  */
3292        __(b local_label(misc_ref_invalid)) /* 26 misc  */
3293        __(b local_label(misc_ref_u32)) /* 27 dead_macptr  */
3294        __(b local_label(misc_ref_invalid)) /* 28 even_fixnum  */
3295        __(b local_label(misc_ref_invalid)) /* 29 cons  */
3296        __(b local_label(misc_ref_node)) /* 2a function  */
3297        __(b local_label(misc_ref_invalid)) /* 2b imm  */
3298        __(b local_label(misc_ref_invalid)) /* 2c odd_fixnum  */
3299        __(b local_label(misc_ref_invalid)) /* 2d nil  */
3300        __(b local_label(misc_ref_invalid)) /* 2e misc  */
3301        __(b local_label(misc_ref_u32)) /* 2f code_vector  */
3302        /* 30-3f  */
3303        __(b local_label(misc_ref_invalid)) /* 30 even_fixnum  */
3304        __(b local_label(misc_ref_invalid)) /* 31 cons  */
3305        __(b local_label(misc_ref_node)) /* 32 lisp_thread  */
3306        __(b local_label(misc_ref_invalid)) /* 33 imm  */
3307        __(b local_label(misc_ref_invalid)) /* 34 odd_fixnum  */
3308        __(b local_label(misc_ref_invalid)) /* 35 nil  */
3309        __(b local_label(misc_ref_invalid)) /* 36 misc  */
3310        __(b local_label(misc_ref_u32)) /* 37 creole  */
3311        __(b local_label(misc_ref_invalid)) /* 38 even_fixnum  */
3312        __(b local_label(misc_ref_invalid)) /* 39 cons  */
3313        __(b local_label(misc_ref_node)) /* 3a symbol  */
3314        __(b local_label(misc_ref_invalid)) /* 3b imm  */
3315        __(b local_label(misc_ref_invalid)) /* 3c odd_fixnum  */
3316        __(b local_label(misc_ref_invalid)) /* 3d nil  */
3317        __(b local_label(misc_ref_invalid)) /* 3e misc  */
3318        __(b local_label(misc_ref_u32)) /* 3f xcode_vector  */
3319        /* 40-4f  */
3320        __(b local_label(misc_ref_invalid)) /* 40 even_fixnum  */
3321        __(b local_label(misc_ref_invalid)) /* 41 cons  */
3322        __(b local_label(misc_ref_node)) /* 42 lock  */
3323        __(b local_label(misc_ref_invalid)) /* 43 imm  */
3324        __(b local_label(misc_ref_invalid)) /* 44 odd_fixnum  */
3325        __(b local_label(misc_ref_invalid)) /* 45 nil  */
3326        __(b local_label(misc_ref_invalid)) /* 46 misc  */
3327        __(b local_label(misc_ref_invalid)) /* 47 immheader  */
3328        __(b local_label(misc_ref_invalid)) /* 48 even_fixnum  */
3329        __(b local_label(misc_ref_invalid)) /* 49 cons  */
3330        __(b local_label(misc_ref_node)) /* 4a hash_vector  */
3331        __(b local_label(misc_ref_invalid)) /* 4b imm  */
3332        __(b local_label(misc_ref_invalid)) /* 4c odd_fixnum  */
3333        __(b local_label(misc_ref_invalid)) /* 4d nil  */
3334        __(b local_label(misc_ref_invalid)) /* 4e misc  */
3335        __(b local_label(misc_ref_invalid)) /* 4f immheader  */
3336        /* 50-5f  */
3337        __(b local_label(misc_ref_invalid)) /* 50 even_fixnum  */
3338        __(b local_label(misc_ref_invalid)) /* 51 cons  */
3339        __(b local_label(misc_ref_node)) /* 52 pool  */
3340        __(b local_label(misc_ref_invalid)) /* 53 imm  */
3341        __(b local_label(misc_ref_invalid)) /* 54 odd_fixnum  */
3342        __(b local_label(misc_ref_invalid)) /* 55 nil  */
3343        __(b local_label(misc_ref_invalid)) /* 56 misc  */
3344        __(b local_label(misc_ref_invalid)) /* 57 immheader  */
3345        __(b local_label(misc_ref_invalid)) /* 58 even_fixnum  */
3346        __(b local_label(misc_ref_invalid)) /* 59 cons  */
3347        __(b local_label(misc_ref_node)) /* 5a weak  */
3348        __(b local_label(misc_ref_invalid)) /* 5b imm  */
3349        __(b local_label(misc_ref_invalid)) /* 5c odd_fixnum  */
3350        __(b local_label(misc_ref_invalid)) /* 5d nil  */
3351        __(b local_label(misc_ref_invalid)) /* 5e misc  */
3352        __(b local_label(misc_ref_invalid)) /* 5f immheader  */
3353        /* 60-6f  */
3354        __(b local_label(misc_ref_invalid)) /* 60 even_fixnum  */
3355        __(b local_label(misc_ref_invalid)) /* 61 cons  */
3356        __(b local_label(misc_ref_node)) /* 62 package  */
3357        __(b local_label(misc_ref_invalid)) /* 63 imm  */
3358        __(b local_label(misc_ref_invalid)) /* 64 odd_fixnum  */
3359        __(b local_label(misc_ref_invalid)) /* 65 nil  */
3360        __(b local_label(misc_ref_invalid)) /* 66 misc  */
3361        __(b local_label(misc_ref_invalid)) /* 67 immheader  */
3362        __(b local_label(misc_ref_invalid)) /* 68 even_fixnum  */
3363        __(b local_label(misc_ref_invalid)) /* 69 cons  */
3364        __(b local_label(misc_ref_node)) /* 6a slot_vector  */
3365        __(b local_label(misc_ref_invalid)) /* 6b imm  */
3366        __(b local_label(misc_ref_invalid)) /* 6c odd_fixnum  */
3367        __(b local_label(misc_ref_invalid)) /* 6d nil  */
3368        __(b local_label(misc_ref_invalid)) /* 6e misc  */
3369        __(b local_label(misc_ref_invalid)) /* 6f immheader  */
3370        /* 70-7f  */
3371        __(b local_label(misc_ref_invalid)) /* 70 even_fixnum  */
3372        __(b local_label(misc_ref_invalid)) /* 71 cons  */
3373        __(b local_label(misc_ref_node)) /* 72 instance  */
3374        __(b local_label(misc_ref_invalid)) /* 73 imm  */
3375        __(b local_label(misc_ref_invalid)) /* 74 odd_fixnum  */
3376        __(b local_label(misc_ref_invalid)) /* 75 nil  */
3377        __(b local_label(misc_ref_invalid)) /* 76 misc  */
3378        __(b local_label(misc_ref_invalid)) /* 77 immheader  */
3379        __(b local_label(misc_ref_invalid)) /* 78 even_fixnum  */
3380        __(b local_label(misc_ref_invalid)) /* 79 cons  */
3381        __(b local_label(misc_ref_node)) /* 7a struct  */
3382        __(b local_label(misc_ref_invalid)) /* 7b imm  */
3383        __(b local_label(misc_ref_invalid)) /* 7c odd_fixnum  */
3384        __(b local_label(misc_ref_invalid)) /* 7d nil  */
3385        __(b local_label(misc_ref_invalid)) /* 7e misc  */
3386        __(b local_label(misc_ref_invalid)) /* 7f immheader  */
3387        /* 80-8f  */
3388        __(b local_label(misc_ref_invalid)) /* 80 even_fixnum  */
3389        __(b local_label(misc_ref_invalid)) /* 81 cons  */
3390        __(b local_label(misc_ref_node)) /* 82 istruct  */
3391        __(b local_label(misc_ref_invalid)) /* 83 imm  */
3392        __(b local_label(misc_ref_invalid)) /* 84 odd_fixnum  */
3393        __(b local_label(misc_ref_invalid)) /* 85 nil  */
3394        __(b local_label(misc_ref_invalid)) /* 86 misc  */
3395        __(b local_label(misc_ref_invalid)) /* 87 immheader  */
3396        __(b local_label(misc_ref_invalid)) /* 88 even_fixnum  */
3397        __(b local_label(misc_ref_invalid)) /* 89 cons  */
3398        __(b local_label(misc_ref_node)) /* 8a value_cell  */
3399        __(b local_label(misc_ref_invalid)) /* 8b imm  */
3400        __(b local_label(misc_ref_invalid)) /* 8c odd_fixnum  */
3401        __(b local_label(misc_ref_invalid)) /* 8d nil  */
3402        __(b local_label(misc_ref_invalid)) /* 8e misc  */
3403        __(b local_label(misc_ref_invalid)) /* 8f immheader  */
3404        /* 90-9f  */
3405        __(b local_label(misc_ref_invalid)) /* 90 even_fixnum  */
3406        __(b local_label(misc_ref_invalid)) /* 91 cons  */
3407        __(b local_label(misc_ref_node)) /* 92 xfunction  */
3408        __(b local_label(misc_ref_invalid)) /* 93 imm  */
3409        __(b local_label(misc_ref_invalid)) /* 94 odd_fixnum  */
3410        __(b local_label(misc_ref_invalid)) /* 95 nil  */
3411        __(b local_label(misc_ref_invalid)) /* 96 misc  */
3412        __(b local_label(misc_ref_invalid)) /* 97 immheader  */
3413        __(b local_label(misc_ref_invalid)) /* 98 even_fixnum  */
3414        __(b local_label(misc_ref_invalid)) /* 99 cons  */
3415        __(b local_label(misc_ref_node)) /* 9a arrayN  */
3416        __(b local_label(misc_ref_invalid)) /* 9b imm  */
3417        __(b local_label(misc_ref_invalid)) /* 9c odd_fixnum  */
3418        __(b local_label(misc_ref_invalid)) /* 9d nil  */
3419        __(b local_label(misc_ref_invalid)) /* 9e misc  */
3420        __(b local_label(misc_ref_invalid)) /* 9f immheader  */
3421        /* a0-af  */
3422        __(b local_label(misc_ref_invalid)) /* a0 even_fixnum  */
3423        __(b local_label(misc_ref_invalid)) /* a1 cons  */
3424        __(b local_label(misc_ref_node)) /* a2 vectorH  */
3425        __(b local_label(misc_ref_invalid)) /* a3 imm  */
3426        __(b local_label(misc_ref_invalid)) /* a4 odd_fixnum  */
3427        __(b local_label(misc_ref_invalid)) /* a5 nil  */
3428        __(b local_label(misc_ref_invalid)) /* a6 misc  */
3429        __(b local_label(misc_ref_single_float_vector)) /* a7 sf_vector  */
3430        __(b local_label(misc_ref_invalid)) /* a8 even_fixnum  */
3431        __(b local_label(misc_ref_invalid)) /* a9 cons  */
3432        __(b local_label(misc_ref_node)) /* aa simple_vector  */
3433        __(b local_label(misc_ref_invalid)) /* ab imm  */
3434        __(b local_label(misc_ref_invalid)) /* ac odd_fixnum  */
3435        __(b local_label(misc_ref_invalid)) /* ad nil  */
3436        __(b local_label(misc_ref_invalid)) /* ae misc  */
3437        __(b local_label(misc_ref_u32)) /* af u32  */
3438        /* b0-bf  */
3439        __(b local_label(misc_ref_invalid)) /* b0 even_fixnum  */
3440        __(b local_label(misc_ref_invalid)) /* b1 cons  */
3441        __(b local_label(misc_ref_invalid)) /* b2 nodeheader  */
3442        __(b local_label(misc_ref_invalid)) /* b3 imm  */
3443        __(b local_label(misc_ref_invalid)) /* b4 odd_fixnum  */
3444        __(b local_label(misc_ref_invalid)) /* b5 nil  */
3445        __(b local_label(misc_ref_invalid)) /* b6 misc  */
3446        __(b local_label(misc_ref_s32)) /* b7 s32  */
3447        __(b local_label(misc_ref_invalid)) /* b8 even_fixnum  */
3448        __(b local_label(misc_ref_invalid)) /* b9 cons  */
3449        __(b local_label(misc_ref_invalid)) /* ba nodeheader  */
3450        __(b local_label(misc_ref_invalid)) /* bb imm  */
3451        __(b local_label(misc_ref_invalid)) /* bc odd_fixnum  */
3452        __(b local_label(misc_ref_invalid)) /* bd nil  */
3453        __(b local_label(misc_ref_invalid)) /* be misc  */
3454        __(b local_label(misc_ref_fixnum_vector)) /* bf fixnum_vector  */
3455        /* c0-cf  */
3456        __(b local_label(misc_ref_invalid)) /* c0 even_fixnum  */
3457        __(b local_label(misc_ref_invalid)) /* c1 cons  */
3458        __(b local_label(misc_ref_invalid)) /* c2 nodeheader  */
3459        __(b local_label(misc_ref_invalid)) /* c3 imm  */
3460        __(b local_label(misc_ref_invalid)) /* c4 odd_fixnum  */
3461        __(b local_label(misc_ref_invalid)) /* c5 nil  */
3462        __(b local_label(misc_ref_invalid)) /* c6 misc  */
3463        __(b local_label(misc_ref_new_string)) /* c7 new_string  */
3464        __(b local_label(misc_ref_invalid)) /* c8 even_fixnum  */
3465        __(b local_label(misc_ref_invalid)) /* c9 cons  */
3466        __(b local_label(misc_ref_invalid)) /* ca nodeheader  */
3467        __(b local_label(misc_ref_invalid)) /* cb imm  */
3468        __(b local_label(misc_ref_invalid)) /* cc odd_fixnum  */
3469        __(b local_label(misc_ref_invalid)) /* cd nil  */
3470        __(b local_label(misc_ref_invalid)) /* ce misc  */
3471        __(b local_label(misc_ref_u8)) /* cf u8  */
3472        /* d0-df  */
3473        __(b local_label(misc_ref_invalid)) /* d0 even_fixnum  */
3474        __(b local_label(misc_ref_invalid)) /* d1 cons  */
3475        __(b local_label(misc_ref_invalid)) /* d2 nodeheader  */
3476        __(b local_label(misc_ref_invalid)) /* d3 imm  */
3477        __(b local_label(misc_ref_invalid)) /* d4 odd_fixnum  */
3478        __(b local_label(misc_ref_invalid)) /* d5 nil  */
3479        __(b local_label(misc_ref_invalid)) /* d6 misc  */
3480        __(b local_label(misc_ref_s8))      /* d7 s8  */
3481        __(b local_label(misc_ref_invalid)) /* d8 even_fixnum  */
3482        __(b local_label(misc_ref_invalid)) /* d9 cons  */
3483        __(b local_label(misc_ref_invalid)) /* da nodeheader  */
3484        __(b local_label(misc_ref_invalid)) /* db imm  */
3485        __(b local_label(misc_ref_invalid)) /* dc odd_fixnum  */
3486        __(b local_label(misc_ref_invalid)) /* dd nil  */
3487        __(b local_label(misc_ref_invalid)) /* de misc  */
3488        __(b local_label(misc_ref_old_string)) /* df (old)subtag_simple_base_string  */
3489        /* e0-ef  */
3490        __(b local_label(misc_ref_invalid)) /* e0 even_fixnum  */
3491        __(b local_label(misc_ref_invalid)) /* e1 cons  */
3492        __(b local_label(misc_ref_invalid)) /* e2 nodeheader  */
3493        __(b local_label(misc_ref_invalid)) /* e3 imm  */
3494        __(b local_label(misc_ref_invalid)) /* e4 odd_fixnum  */
3495        __(b local_label(misc_ref_invalid)) /* e5 nil  */
3496        __(b local_label(misc_ref_invalid)) /* e6 misc  */
3497        __(b local_label(misc_ref_u16)) /* e7 u16  */
3498        __(b local_label(misc_ref_invalid)) /* e8 even_fixnum  */
3499        __(b local_label(misc_ref_invalid)) /* e9 cons  */
3500        __(b local_label(misc_ref_invalid)) /* ea nodeheader  */
3501        __(b local_label(misc_ref_invalid)) /* eb imm  */
3502        __(b local_label(misc_ref_invalid)) /* ec odd_fixnum  */
3503        __(b local_label(misc_ref_invalid)) /* ed nil  */
3504        __(b local_label(misc_ref_invalid)) /* ee misc  */
3505        __(b local_label(misc_ref_s16)) /* ef s16  */
3506        /* f0-ff  */
3507        __(b local_label(misc_ref_invalid)) /* f0 even_fixnum  */
3508        __(b local_label(misc_ref_invalid)) /* f1 cons  */
3509        __(b local_label(misc_ref_invalid)) /* f2 nodeheader  */
3510        __(b local_label(misc_ref_invalid)) /* f3 imm  */
3511        __(b local_label(misc_ref_invalid)) /* f4 odd_fixnum  */
3512        __(b local_label(misc_ref_invalid)) /* f5 nil  */
3513        __(b local_label(misc_ref_invalid)) /* f6 misc  */
3514        __(b local_label(misc_ref_double_float_vector)) /* f7 df vector  */
3515        __(b local_label(misc_ref_invalid)) /* f8 even_fixnum  */
3516        __(b local_label(misc_ref_invalid)) /* f9 cons  */
3517        __(b local_label(misc_ref_invalid)) /* fa nodeheader  */
3518        __(b local_label(misc_ref_invalid)) /* fb imm  */
3519        __(b local_label(misc_ref_invalid)) /* fc odd_fixnum  */
3520        __(b local_label(misc_ref_invalid)) /* fd nil  */
3521        __(b local_label(misc_ref_invalid)) /* fe misc  */
3522        __(b local_label(misc_ref_bit_vector)) /* ff bit_vector  */
3523
3524local_label(misc_ref_node):       
3525        /* A node vector.  */
3526        __(add imm0,arg_z,#misc_data_offset)
3527        __(ldr  arg_z,[arg_y,imm0])
3528        __(bx lr)
3529local_label(misc_ref_single_float_vector):       
3530        __(add imm0,arg_z,misc_data_offset)
3531        __(movc16(imm1,single_float_header))
3532        __(ldr imm0,[arg_y,imm0])
3533        __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
3534        __(str imm0,[arg_z,#single_float.value])
3535        __(bx lr)
3536local_label(misc_ref_new_string):       
3537        __(add imm0,arg_z,#misc_data_offset)
3538        __(ldr imm0,[arg_y,imm0])
3539        __(mov arg_z,imm0,lsl #charcode_shift)
3540        __(orr arg_z,arg_z,#subtag_character)
3541        __(bx lr)
3542local_label(misc_ref_s32):       
3543        __(add imm0,arg_z,#misc_data_offset)
3544        __(ldr imm0,[arg_y,imm0])
3545        __(b _SPmakes32)
3546local_label(misc_ref_fixnum_vector):   
3547        __(add imm0,arg_z,#misc_data_offset)
3548        __(ldr imm0,[arg_y,imm0])
3549        __(box_fixnum(arg_z,imm0))
3550        __(bx lr)       
3551local_label(misc_ref_u32):       
3552        __(add imm0,arg_z,#misc_data_offset)
3553        __(ldr imm0,[arg_y,imm0])
3554        __(b _SPmakeu32)
3555local_label(misc_ref_double_float_vector):     
3556        __(mov imm2,arg_z,lsl #1)
3557        __(add imm2,imm2,#misc_dfloat_offset)
3558        __(ldrd imm0,imm1,[arg_y,imm2])
3559        __(movc16(imm2,double_float_header))
3560        __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
3561        __(strd imm0,imm1,[arg_z,#double_float.value])
3562        __(bx lr)
3563local_label(misc_ref_bit_vector):
3564        __(mov imm1,#nbits_in_word-1)
3565        __(and imm1,imm1,arg_z,lsr #2)
3566        __(mov imm2,#1)
3567        __(mov imm2,imm2,lsl imm1)
3568        __(mov imm0,arg_z,lsr #5+fixnumshift)
3569        __(mov imm0,imm0,lsl #2)
3570        __(add imm0,imm0,#misc_data_offset)
3571        __(mov arg_z,#0)
3572        __(ldr imm0,[arg_y,imm0])
3573        __(tst imm0,imm2)
3574        __(addne arg_z,arg_z,#fixnumone)
3575        __(bx lr)
3576local_label(misc_ref_s8):       
3577        __(mov imm0,arg_z,lsr #2)
3578        __(add imm0,imm0,#misc_data_offset)
3579        __(ldsb imm0,[arg_y,imm0])
3580        __(box_fixnum(arg_z,imm0))
3581        __(bx lr)
3582local_label(misc_ref_u8):       
3583        __(mov imm0,arg_z,lsr #2)
3584        __(add imm0,imm0,#misc_data_offset)
3585        __(ldrb imm0,[arg_y,imm0])
3586        __(box_fixnum(arg_z,imm0))
3587        __(bx lr)
3588local_label(misc_ref_old_string):         
3589        __(mov imm0,arg_z,lsr #2)
3590        __(add imm0,imm0,#misc_data_offset)
3591        __(ldrb imm0,[arg_y,imm0])
3592        __(mov arg_z,imm0,lsl #charcode_shift)
3593        __(orr arg_z,arg_z,#subtag_character)
3594        __(bx lr)
3595local_label(misc_ref_u16):       
3596        __(mov imm0,arg_z,lsr #1)     
3597        __(add imm0,imm0,#misc_data_offset)
3598        __(ldrh imm0,[arg_y,imm0])
3599        __(box_fixnum(arg_z,imm0))
3600        __(bx lr)
3601local_label(misc_ref_s16):             
3602        __(mov imm0,arg_z,lsr #1)     
3603        __(add imm0,imm0,#misc_data_offset)
3604        __(ldrsh imm0,[arg_y,imm0])
3605        __(box_fixnum(arg_z,imm0))
3606        __(bx lr)
3607local_label(misc_ref_invalid):
3608        __(mov arg_x,#XBADVEC)
3609        __(set_nargs(3))
3610        __(b _SPksignalerr)       
3611_endfn
3612       
3613_startfn(C(misc_set_common))
3614        __(add pc,pc,imm1,lsl #2)
3615        __(nop)
3616local_label(misc_set_jmp):             
3617        /* 00-0f  */
3618        __(b local_label(misc_set_invalid)) /* 00 even_fixnum  */
3619        __(b local_label(misc_set_invalid)) /* 01 cons  */
3620        __(b _SPgvset)                      /* 02 pseudofunction  */
3621        __(b local_label(misc_set_invalid)) /* 03 imm  */
3622        __(b local_label(misc_set_invalid)) /* 04 odd_fixnum  */
3623        __(b local_label(misc_set_invalid)) /* 05 nil  */
3624        __(b local_label(misc_set_invalid)) /* 06 misc  */
3625        __(b local_label(misc_set_u32)) /* 07 bignum  */
3626        __(b local_label(misc_set_invalid)) /* 08 even_fixnum  */
3627        __(b local_label(misc_set_invalid)) /* 09 cons  */
3628        __(b _SPgvset) /* 0a ratio  */
3629        __(b  local_label(misc_set_invalid)) /* 0b imm  */
3630        __(b local_label(misc_set_invalid)) /* 0c odd_fixnum  */
3631        __(b local_label(misc_set_invalid)) /* 0d nil  */
3632        __(b local_label(misc_set_invalid)) /* 0e misc  */
3633        __(b local_label(misc_set_u32)) /* 0f single_float  */
3634        /* 10-1f  */
3635        __(b local_label(misc_set_invalid)) /* 10 even_fixnum  */
3636        __(b local_label(misc_set_invalid)) /* 11 cons  */
3637        __(b local_label(misc_set_invalid)) /* 12 nodeheader  */
3638        __(b local_label(misc_set_invalid)) /* 13 imm  */
3639        __(b local_label(misc_set_invalid)) /* 14 odd_fixnum  */
3640        __(b local_label(misc_set_invalid)) /* 15 nil  */
3641        __(b local_label(misc_set_invalid)) /* 16 misc  */
3642        __(b local_label(misc_set_u32)) /* 17 double_float  */
3643        __(b local_label(misc_set_invalid)) /* 18 even_fixnum  */
3644        __(b local_label(misc_set_invalid)) /* 19 cons  */
3645        __(b _SPgvset) /* 1a complex  */
3646        __(b  local_label(misc_set_invalid)) /* 1b imm  */
3647        __(b local_label(misc_set_invalid)) /* 1c odd_fixnum  */
3648        __(b local_label(misc_set_invalid)) /* 1d nil  */
3649        __(b local_label(misc_set_invalid)) /* 1e misc  */
3650        __(b local_label(misc_set_u32)) /* 1f macptr  */
3651        /* 20-2f  */
3652        __(b local_label(misc_set_invalid)) /* 20 even_fixnum  */
3653        __(b local_label(misc_set_invalid)) /* 21 cons  */
3654        __(b _SPgvset) /* 22 catch_frame  */
3655        __(b  local_label(misc_set_invalid)) /* 23 imm  */
3656        __(b local_label(misc_set_invalid)) /* 24 odd_fixnum  */
3657        __(b local_label(misc_set_invalid)) /* 25 nil  */
3658        __(b local_label(misc_set_invalid)) /* 26 misc  */
3659        __(b local_label(misc_set_u32)) /* 27 dead_macptr  */
3660        __(b local_label(misc_set_invalid)) /* 28 even_fixnum  */
3661        __(b local_label(misc_set_invalid)) /* 29 cons  */
3662        __(b _SPgvset) /* 2a function  */
3663        __(b  local_label(misc_set_invalid)) /* 2b imm  */
3664        __(b local_label(misc_set_invalid)) /* 2c odd_fixnum  */
3665        __(b local_label(misc_set_invalid)) /* 2d nil  */
3666        __(b local_label(misc_set_invalid)) /* 2e misc  */
3667        __(b local_label(misc_set_u32)) /* 2f code_vector  */
3668        /* 30-3f  */
3669        __(b local_label(misc_set_invalid)) /* 30 even_fixnum  */
3670        __(b local_label(misc_set_invalid)) /* 31 cons  */
3671        __(b _SPgvset) /* 32 lisp_thread  */
3672        __(b  local_label(misc_set_invalid)) /* 33 imm  */
3673        __(b local_label(misc_set_invalid)) /* 34 odd_fixnum  */
3674        __(b local_label(misc_set_invalid)) /* 35 nil  */
3675        __(b local_label(misc_set_invalid)) /* 36 misc  */
3676        __(b local_label(misc_set_u32)) /* 37 creole  */
3677        __(b local_label(misc_set_invalid)) /* 38 even_fixnum  */
3678        __(b local_label(misc_set_invalid)) /* 39 cons  */
3679        __(b _SPgvset) /* 3a symbol  */
3680        __(b  local_label(misc_set_invalid)) /* 3b imm  */
3681        __(b local_label(misc_set_invalid)) /* 3c odd_fixnum  */
3682        __(b local_label(misc_set_invalid)) /* 3d nil  */
3683        __(b local_label(misc_set_invalid)) /* 3e misc  */
3684        __(b local_label(misc_set_u32)) /* 3f xcode_vector  */
3685        /* 40-4f  */
3686        __(b local_label(misc_set_invalid)) /* 40 even_fixnum  */
3687        __(b local_label(misc_set_invalid)) /* 41 cons  */
3688        __(b _SPgvset) /* 42 lock  */
3689        __(b  local_label(misc_set_invalid)) /* 43 imm  */
3690        __(b local_label(misc_set_invalid)) /* 44 odd_fixnum  */
3691        __(b local_label(misc_set_invalid)) /* 45 nil  */
3692        __(b local_label(misc_set_invalid)) /* 46 misc  */
3693        __(b local_label(misc_set_invalid)) /* 47 immheader  */
3694        __(b local_label(misc_set_invalid)) /* 48 even_fixnum  */
3695        __(b local_label(misc_set_invalid)) /* 49 cons  */
3696        __(b _SPgvset) /* 4a hash_vector  */
3697        __(b  local_label(misc_set_invalid)) /* 4b imm  */
3698        __(b local_label(misc_set_invalid)) /* 4c odd_fixnum  */
3699        __(b local_label(misc_set_invalid)) /* 4d nil  */
3700        __(b local_label(misc_set_invalid)) /* 4e misc  */
3701        __(b local_label(misc_set_invalid)) /* 4f immheader  */
3702        /* 50-5f  */
3703        __(b local_label(misc_set_invalid)) /* 50 even_fixnum  */
3704        __(b local_label(misc_set_invalid)) /* 51 cons  */
3705        __(b _SPgvset) /* 52 pool  */
3706        __(b  local_label(misc_set_invalid)) /* 53 imm  */
3707        __(b local_label(misc_set_invalid)) /* 54 odd_fixnum  */
3708        __(b local_label(misc_set_invalid)) /* 55 nil  */
3709        __(b local_label(misc_set_invalid)) /* 56 misc  */
3710        __(b local_label(misc_set_invalid)) /* 57 immheader  */
3711        __(b local_label(misc_set_invalid)) /* 58 even_fixnum  */
3712        __(b local_label(misc_set_invalid)) /* 59 cons  */
3713        __(b _SPgvset) /* 5a weak  */
3714        __(b  local_label(misc_set_invalid)) /* 5b imm  */
3715        __(b local_label(misc_set_invalid)) /* 5c odd_fixnum  */
3716        __(b local_label(misc_set_invalid)) /* 5d nil  */
3717        __(b local_label(misc_set_invalid)) /* 5e misc  */
3718        __(b local_label(misc_set_invalid)) /* 5f immheader  */
3719        /* 60-6f  */
3720        __(b local_label(misc_set_invalid)) /* 60 even_fixnum  */
3721        __(b local_label(misc_set_invalid)) /* 61 cons  */
3722        __(b _SPgvset) /* 62 package  */
3723        __(b  local_label(misc_set_invalid)) /* 63 imm  */
3724        __(b local_label(misc_set_invalid)) /* 64 odd_fixnum  */
3725        __(b local_label(misc_set_invalid)) /* 65 nil  */
3726        __(b local_label(misc_set_invalid)) /* 66 misc  */
3727        __(b local_label(misc_set_invalid)) /* 67 immheader  */
3728        __(b local_label(misc_set_invalid)) /* 68 even_fixnum  */
3729        __(b local_label(misc_set_invalid)) /* 69 cons  */
3730        __(b _SPgvset) /* 6a slot_vector  */
3731        __(b  local_label(misc_set_invalid)) /* 6b imm  */
3732        __(b local_label(misc_set_invalid)) /* 6c odd_fixnum  */
3733        __(b local_label(misc_set_invalid)) /* 6d nil  */
3734        __(b local_label(misc_set_invalid)) /* 6e misc  */
3735        __(b local_label(misc_set_invalid)) /* 6f immheader  */
3736        /* 70-7f  */
3737        __(b local_label(misc_set_invalid)) /* 70 even_fixnum  */
3738        __(b local_label(misc_set_invalid)) /* 71 cons  */
3739        __(b _SPgvset) /* 72 instance  */
3740        __(b  local_label(misc_set_invalid)) /* 73 imm  */
3741        __(b local_label(misc_set_invalid)) /* 74 odd_fixnum  */
3742        __(b local_label(misc_set_invalid)) /* 75 nil  */
3743        __(b local_label(misc_set_invalid)) /* 76 misc  */
3744        __(b local_label(misc_set_invalid)) /* 77 immheader  */
3745        __(b local_label(misc_set_invalid)) /* 78 even_fixnum  */
3746        __(b local_label(misc_set_invalid)) /* 79 cons  */
3747        __(b _SPgvset) /* 7a struct  */
3748        __(b  local_label(misc_set_invalid)) /* 7b imm  */
3749        __(b local_label(misc_set_invalid)) /* 7c odd_fixnum  */
3750        __(b local_label(misc_set_invalid)) /* 7d nil  */
3751        __(b local_label(misc_set_invalid)) /* 7e misc  */
3752        __(b local_label(misc_set_invalid)) /* 7f immheader  */
3753        /* 80-8f  */
3754        __(b local_label(misc_set_invalid)) /* 80 even_fixnum  */
3755        __(b local_label(misc_set_invalid)) /* 81 cons  */
3756        __(b _SPgvset) /* 82 istruct  */
3757        __(b  local_label(misc_set_invalid)) /* 83 imm  */
3758        __(b local_label(misc_set_invalid)) /* 84 odd_fixnum  */
3759        __(b local_label(misc_set_invalid)) /* 85 nil  */
3760        __(b local_label(misc_set_invalid)) /* 86 misc  */
3761        __(b local_label(misc_set_invalid)) /* 87 immheader  */
3762        __(b local_label(misc_set_invalid)) /* 88 even_fixnum  */
3763        __(b local_label(misc_set_invalid)) /* 89 cons  */
3764        __(b _SPgvset) /* 8a value_cell  */
3765        __(b  local_label(misc_set_invalid)) /* 8b imm  */
3766        __(b local_label(misc_set_invalid)) /* 8c odd_fixnum  */
3767        __(b local_label(misc_set_invalid)) /* 8d nil  */
3768        __(b local_label(misc_set_invalid)) /* 8e misc  */
3769        __(b local_label(misc_set_invalid)) /* 8f immheader  */
3770        /* 90-9f  */
3771        __(b local_label(misc_set_invalid)) /* 90 even_fixnum  */
3772        __(b local_label(misc_set_invalid)) /* 91 cons  */
3773        __(b _SPgvset) /* 92 xfunction  */
3774        __(b  local_label(misc_set_invalid)) /* 93 imm  */
3775        __(b local_label(misc_set_invalid)) /* 94 odd_fixnum  */
3776        __(b local_label(misc_set_invalid)) /* 95 nil  */
3777        __(b local_label(misc_set_invalid)) /* 96 misc  */
3778        __(b local_label(misc_set_invalid)) /* 97 immheader  */
3779        __(b local_label(misc_set_invalid)) /* 98 even_fixnum  */
3780        __(b local_label(misc_set_invalid)) /* 99 cons  */
3781        __(b _SPgvset) /* 9a arrayH  */
3782        __(b  local_label(misc_set_invalid)) /* 9b imm  */
3783        __(b local_label(misc_set_invalid)) /* 9c odd_fixnum  */
3784        __(b local_label(misc_set_invalid)) /* 9d nil  */
3785        __(b local_label(misc_set_invalid)) /* 9e misc  */
3786        __(b local_label(misc_set_invalid)) /* 9f immheader  */
3787        /* a0-af  */
3788        __(b local_label(misc_set_invalid)) /* a0 even_fixnum  */
3789        __(b local_label(misc_set_invalid)) /* a1 cons  */
3790        __(b _SPgvset) /* a2 vectorH  */
3791        __(b  local_label(misc_set_invalid)) /* a3 imm  */
3792        __(b local_label(misc_set_invalid)) /* a4 odd_fixnum  */
3793        __(b local_label(misc_set_invalid)) /* a5 nil  */
3794        __(b local_label(misc_set_invalid)) /* a6 misc  */
3795        __(b local_label(misc_set_single_float_vector)) /* a7 sf vector  */
3796        __(b local_label(misc_set_invalid)) /* a8 even_fixnum  */
3797        __(b local_label(misc_set_invalid)) /* a9 cons  */
3798        __(b _SPgvset) /* aa vectorH  */
3799        __(b  local_label(misc_set_invalid)) /* ab imm  */
3800        __(b local_label(misc_set_invalid)) /* ac odd_fixnum  */
3801        __(b local_label(misc_set_invalid)) /* ad nil  */
3802        __(b local_label(misc_set_invalid)) /* ae misc  */
3803        __(b local_label(misc_set_u32)) /* af u32  */
3804        /* b0-bf  */
3805        __(b local_label(misc_set_invalid)) /* b0 even_fixnum  */
3806        __(b local_label(misc_set_invalid)) /* b1 cons  */
3807        __(b local_label(misc_set_invalid)) /* b2 node  */
3808        __(b local_label(misc_set_invalid)) /* b3 imm  */
3809        __(b local_label(misc_set_invalid)) /* b4 odd_fixnum  */
3810        __(b local_label(misc_set_invalid)) /* b5 nil  */
3811        __(b local_label(misc_set_invalid)) /* b6 misc  */
3812        __(b local_label(misc_set_s32)) /* b7 s32  */
3813        __(b local_label(misc_set_invalid)) /* b8 even_fixnum  */
3814        __(b local_label(misc_set_invalid)) /* b9 cons  */
3815        __(b local_label(misc_set_invalid)) /* ba nodeheader  */
3816        __(b local_label(misc_set_invalid)) /* bb imm  */
3817        __(b local_label(misc_set_invalid)) /* bc odd_fixnum  */
3818        __(b local_label(misc_set_invalid)) /* bd nil  */
3819        __(b local_label(misc_set_invalid)) /* be misc  */
3820        __(b local_label(misc_set_fixnum_vector)) /* bf fixnum_vector  */
3821        /* c0-cf  */
3822        __(b local_label(misc_set_invalid)) /* c0 even_fixnum  */
3823        __(b local_label(misc_set_invalid)) /* c1 cons  */
3824        __(b local_label(misc_set_invalid)) /* c2 nodeheader  */
3825        __(b local_label(misc_set_invalid)) /* c3 imm  */
3826        __(b local_label(misc_set_invalid)) /* c4 odd_fixnum  */
3827        __(b local_label(misc_set_invalid)) /* c5 nil  */
3828        __(b local_label(misc_set_invalid)) /* c6 misc  */
3829        __(b local_label(misc_set_new_string)) /* c7 new_string  */
3830        __(b local_label(misc_set_invalid)) /* c8 even_fixnum  */
3831        __(b local_label(misc_set_invalid)) /* c9 cons  */
3832        __(b local_label(misc_set_invalid)) /* ca nodeheader  */
3833        __(b local_label(misc_set_invalid)) /* cb imm  */
3834        __(b local_label(misc_set_invalid)) /* cc odd_fixnum  */
3835        __(b local_label(misc_set_invalid)) /* cd nil  */
3836        __(b local_label(misc_set_invalid)) /* ce misc  */
3837        __(b local_label(misc_set_u8)) /* cf u8  */
3838        /* d0-df  */
3839        __(b local_label(misc_set_invalid)) /* d0 even_fixnum  */
3840        __(b local_label(misc_set_invalid)) /* d1 cons  */
3841        __(b local_label(misc_set_invalid)) /* d2 nodeheader  */
3842        __(b local_label(misc_set_invalid)) /* d3 imm  */
3843        __(b local_label(misc_set_invalid)) /* d4 odd_fixnum  */
3844        __(b local_label(misc_set_invalid)) /* d5 nil  */
3845        __(b local_label(misc_set_invalid)) /* d6 misc  */
3846        __(b local_label(misc_set_s8)) /* d7 s8  */
3847        __(b local_label(misc_set_invalid)) /* d8 even_fixnum  */
3848        __(b local_label(misc_set_invalid)) /* d9 cons  */
3849        __(b local_label(misc_set_invalid)) /* da nodeheader  */
3850        __(b local_label(misc_set_invalid)) /* db imm  */
3851        __(b local_label(misc_set_invalid)) /* dc odd_fixnum  */
3852        __(b local_label(misc_set_invalid)) /* dd nil  */
3853        __(b local_label(misc_set_invalid)) /* de misc  */
3854        __(b local_label(misc_set_old_string)) /* df (old) simple_base_string  */
3855        /* e0-ef  */
3856        __(b local_label(misc_set_invalid)) /* e0 even_fixnum  */
3857        __(b local_label(misc_set_invalid)) /* e1 cons  */
3858        __(b local_label(misc_set_invalid)) /* e2 nodeheader  */
3859        __(b local_label(misc_set_invalid)) /* e3 imm  */
3860        __(b local_label(misc_set_invalid)) /* e4 odd_fixnum  */
3861        __(b local_label(misc_set_invalid)) /* e5 nil  */
3862        __(b local_label(misc_set_invalid)) /* e6 misc  */
3863        __(b local_label(misc_set_u16)) /* e7 u16  */
3864        __(b local_label(misc_set_invalid)) /* e8 even_fixnum  */
3865        __(b local_label(misc_set_invalid)) /* e9 cons  */
3866        __(b local_label(misc_set_invalid)) /* ea nodeheader  */
3867        __(b local_label(misc_set_invalid)) /* eb imm  */
3868        __(b local_label(misc_set_invalid)) /* ec odd_fixnum  */
3869        __(b local_label(misc_set_invalid)) /* ed nil  */
3870        __(b local_label(misc_set_invalid)) /* ee misc  */
3871        __(b local_label(misc_set_s16)) /* ef s16  */
3872        /* f0-ff  */
3873        __(b local_label(misc_set_invalid)) /* f0 even_fixnum  */
3874        __(b local_label(misc_set_invalid)) /* f1 cons  */
3875        __(b local_label(misc_set_invalid)) /* f2 nodeheader  */
3876        __(b local_label(misc_set_invalid)) /* f3 imm  */
3877        __(b local_label(misc_set_invalid)) /* f4 odd_fixnum  */
3878        __(b local_label(misc_set_invalid)) /* f5 nil  */
3879        __(b local_label(misc_set_invalid)) /* f6 misc  */
3880        __(b local_label(misc_set_double_float_vector)) /* f7 df vector  */
3881        __(b local_label(misc_set_invalid)) /* f8 even_fixnum  */
3882        __(b local_label(misc_set_invalid)) /* f9 cons  */
3883        __(b local_label(misc_set_invalid)) /* fa nodeheader  */
3884        __(b local_label(misc_set_invalid)) /* fb imm  */
3885        __(b local_label(misc_set_invalid)) /* fc odd_fixnum  */
3886        __(b local_label(misc_set_invalid)) /* fd nil  */
3887        __(b local_label(misc_set_invalid)) /* fe misc  */
3888        __(b local_label(misc_set_bit_vector)) /* ff bit_vector  */
3889
3890local_label(misc_set_u32):       
3891        /* Either a non-negative fixnum, a positive one-digit bignum, */
3892        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
3893        __(add imm0,arg_y,#misc_data_offset)
3894        __(test_fixnum(arg_z))
3895        __(bne local_label(set_not_fixnum_u32))
3896        __(tst arg_z,#0x80000000)
3897        __(bne local_label(set_bad))
3898        __(unbox_fixnum(imm1,arg_z))
3899local_label(set_set32):         
3900        __(str imm1,[arg_x,imm0])
3901        __(bx lr)
3902local_label(set_not_fixnum_u32):
3903        __(extract_lisptag(imm1,arg_z))
3904        __(cmp imm1,#tag_misc)
3905        __(bne local_label(set_bad))
3906        __(movc16(imm2,one_digit_bignum_header))
3907        __(getvheader(imm1,arg_z))
3908        __(cmp imm1,imm2)
3909        __(bne local_label(set_not_1_digit_u32))
3910        __(ldr imm1,[arg_z,#misc_data_offset])
3911        __(cmp imm1,#0)
3912        __(bge local_label(set_set32))
3913        __(b local_label(set_bad))
3914local_label(set_not_1_digit_u32):
3915        __(movc16(imm2,two_digit_bignum_header))
3916        __(cmp imm1,imm2)
3917        __(bne local_label(set_bad))
3918        __(vrefr(imm2,arg_z,1))
3919        __(vrefr(imm1,arg_z,0))
3920        __(cmp imm2,#0)
3921        __(beq local_label(set_set32))
3922local_label(set_bad):
3923        /* arg_z does not match the array-element-type of arg_x.  */
3924        __(mov arg_y,arg_z)
3925        __(mov arg_z,arg_x)
3926        __(mov arg_x,#XNOTELT)
3927        __(set_nargs(3))
3928        __(b _SPksignalerr)
3929local_label(misc_set_fixnum_vector):   
3930        __(add imm0,arg_y,#misc_data_offset)
3931        __(test_fixnum(arg_z))
3932        __(bne local_label(set_bad))
3933        __(unbox_fixnum(imm1,arg_z))
3934        __(str imm1,[arg_x,imm0])
3935        __(bx lr)
3936local_label(misc_set_new_string):   
3937        __(add imm0,arg_y,#misc_data_offset)
3938        __(extract_lowbyte(imm2,arg_z))
3939        __(cmp imm2,#subtag_character)
3940        __(bne local_label(set_bad))
3941        __(unbox_character(imm1,arg_z))
3942        __(str imm1,[arg_x,imm0])
3943        __(bx lr)
3944local_label(misc_set_s32):
3945        __(add imm0,arg_y,#misc_data_offset)
3946        __(test_fixnum(arg_z))
3947        __(moveq imm1,arg_z,asr #fixnumshift)
3948        __(beq local_label(set_set32))
3949        __(extract_lisptag(imm2,arg_z))
3950        __(cmp imm2,#tag_misc)
3951        __(bne local_label(set_bad))
3952        __(movc16(imm1,one_digit_bignum_header))
3953        __(getvheader(imm2,arg_z))
3954        __(cmp imm2,imm1)
3955        __(vrefr(imm1,arg_z,0))
3956        __(beq local_label(set_set32))
3957        __(b local_label(set_bad))
3958local_label(misc_set_single_float_vector):
3959        __(add imm0,arg_y,#misc_data_offset)
3960        __(extract_typecode(imm2,arg_z))
3961        __(cmp imm2,#subtag_single_float)
3962        __(bne local_label(set_bad))
3963        __(ldr imm1,[arg_z,#single_float.value])
3964        __(str imm1,[arg_x,imm0])
3965        __(bx lr)
3966local_label(misc_set_u8):               
3967        __(mov imm0,arg_y,lsr #2)
3968        __(add imm0,imm0,#misc_data_offset)
3969        __(mov imm2,#~(0xff<<fixnumshift))
3970        __(tst arg_z,imm2)
3971        __(bne local_label(set_bad))
3972        __(unbox_fixnum(imm1,arg_z))
3973        __(strb imm1,[arg_x,imm0])
3974        __(bx lr)
3975local_label(misc_set_old_string):
3976        __(mov imm0,arg_y,lsr #2)
3977        __(add imm0,imm0,#misc_data_offset)
3978        __(extract_lowbyte(imm2,arg_z))
3979        __(cmp imm2,#subtag_character)
3980        __(unbox_character(imm1,arg_z))
3981        __(bne local_label(set_bad))
3982        __(strb imm1,[arg_x,imm0])
3983        __(bx lr)
3984local_label(misc_set_s8):
3985        __(mov imm0,arg_y,lsr #2)
3986        __(add imm0,imm0,#misc_data_offset)
3987        __(test_fixnum(arg_z))
3988        __(bne local_label(set_bad))
3989        __(unbox_fixnum(imm1,arg_z))
3990        __(mov imm2,imm1,lsl #32-8)
3991        __(cmp imm1,imm2,asr #32-8)
3992        __(bne local_label(set_bad))
3993        __(strb imm1,[arg_x,imm0])
3994        __(bx lr)
3995local_label(misc_set_u16):         
3996        __(mov imm0,arg_y,lsr #1)
3997        __(add imm0,imm0,#misc_data_offset)
3998        __(test_fixnum(arg_z))
3999        __(bne local_label(set_bad))
4000        __(unbox_fixnum(imm1,arg_z))
4001        __(mov imm2,imm1,lsl #16)
4002        __(cmp imm1,imm2,lsr #16)
4003        __(bne local_label(set_bad))
4004        __(strh imm1,[arg_x,imm0])
4005        __(bx lr)
4006local_label(misc_set_s16):
4007        __(mov imm0,arg_y,lsr #1)
4008        __(add imm0,imm0,#misc_data_offset)
4009        __(test_fixnum(arg_z))
4010        __(bne local_label(set_bad))
4011        __(unbox_fixnum(imm1,arg_z))
4012        __(mov imm2,imm1,lsl #16)
4013        __(cmp imm1,imm2,asr #16)
4014        __(bne local_label(set_bad))
4015        __(strh imm1,[arg_x,imm0])
4016        __(bx lr)
4017local_label(misc_set_bit_vector):
4018        __(bics imm0,arg_z,#fixnumone)
4019        __(bne local_label(set_bad))
4020        __(mov imm2,#31)
4021        __(and imm2,imm2,arg_y,lsr #2)
4022        __(mov imm1,#1)
4023        __(mov imm1,imm1,lsl imm2)
4024        __(mov imm0,arg_y,lsr #fixnumshift+5)
4025        __(mov imm0,imm0,lsl #2)
4026        __(add imm0,imm0,#misc_data_offset)
4027        __(cmp arg_z,#0)
4028        __(ldr imm2,[arg_x,imm0])
4029        __(orrne imm2,imm2,imm1)
4030        __(biceq imm2,imm2,imm1)
4031        __(str imm2,[arg_x,imm0])
4032        __(bx lr)
4033
4034local_label(misc_set_double_float_vector):
4035        __(extract_subtag(imm2,arg_z))
4036        __(cmp imm2,#subtag_double_float)
4037        __(bne local_label(set_bad))
4038        __(ldrd imm0,imm1,[arg_z,#misc_dfloat_offset])
4039        __(mov imm2,arg_y,lsl #1)
4040        __(add imm2,imm2,#misc_dfloat_offset)
4041        __(strd imm0,imm1,[arg_x,imm2])
4042        __(bx lr)
4043local_label(misc_set_invalid): 
4044        __(mov temp0,#XSETBADVEC)       
4045        __(set_nargs(4))
4046        __(vpush1(temp0))
4047        __(b _SPksignalerr)               
4048
4049       
4050/* temp0: (stack-consed) target catch frame, imm0: count of intervening  */
4051/* frames. If target isn't a multiple-value receiver, discard extra values */
4052/* (less hair, maybe.)  */
4053_startfn(C(_throw_found))
4054        new_local_labels()
4055        __(ldr imm1,[temp0,#catch_frame.mvflag])
4056        __(cmp imm1,#0)
4057        __(mov fn,#0)
4058        __(add imm1,vsp,nargs)
4059        __(add imm1,imm1,#-node_size)
4060        __(bne local_label(throw_all_values))
4061        __(cmp nargs,#0)
4062        __(moveq imm1,#nil_value)
4063        __(set_nargs(1))
4064        __(streq imm1,[vsp,#-node_size]!)
4065        __(movne vsp,imm1)
4066local_label(throw_all_values): 
4067        __(bl _SPnthrowvalues)
4068        __(ldr temp0,[rcontext,#tcr.catch_top])
4069        __(ldr imm1,[rcontext,#tcr.db_link])
4070        __(ldr imm0,[temp0,#catch_frame.db_link])
4071        __(cmp imm0,imm1)
4072        __(blne _SPunbind_to)
4073        __(ldr temp1,[temp0,#catch_frame.mvflag])
4074        __(ldr imm0,[temp0,#catch_frame.xframe])       
4075        __(ldr imm1,[temp0,#catch_frame.last_lisp_frame])
4076        __(cmp temp1,#0)
4077        __(str imm0,[rcontext,#tcr.xframe])
4078        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4079        __(add imm0,vsp,nargs)
4080        __(sub sp,temp0,#fulltag_misc)
4081        __(ldr imm1,[sp,#catch_frame.size+lisp_frame.savevsp])
4082        __(ldreq arg_z,[imm0,#-node_size])
4083        __(beq local_label(throw_pushed_values))
4084        __(movs arg_x,nargs)
4085        __(b local_label(throw_push_test))
4086local_label(throw_push_loop):
4087        __(subs arg_x,arg_x,#fixnumone)
4088        __(ldr arg_y,[imm0,#-node_size]!)
4089        __(push1(arg_y,imm1))
4090local_label(throw_push_test):   
4091        __(bne local_label(throw_push_loop))
4092local_label(throw_pushed_values):
4093        __(mov vsp,imm1)
4094        __(ldr imm0,[temp0,#catch_frame.link])
4095        __(str imm0,[rcontext,#tcr.catch_top])
4096        __(ldr fn,[sp,#catch_frame.size+lisp_frame.savefn])
4097        __(ldr lr,[sp,#catch_frame.size+lisp_frame.savelr])
4098        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4099        __(pop_lisp_fprs())
4100        __(bx lr)
4101_endfn(C(_throw_found))       
4102
4103_startfn(C(nthrow1v))
4104        new_local_labels()
4105local_label(_nthrow1v_nextframe):
4106        __(subs temp2,temp2,#fixnum_one)
4107        __(ldr temp0,[rcontext,#tcr.catch_top])
4108        __(ldr imm1,[rcontext,#tcr.db_link])
4109        __(set_nargs(1))
4110        __(blt local_label(_nthrow1v_done))
4111        __(ldr arg_y,[temp0,#catch_frame.link])
4112        __(ldr imm0,[temp0,#catch_frame.db_link])
4113        __(cmp imm0,imm1)
4114        __(str arg_y,[rcontext,#tcr.catch_top])
4115        __(ldr arg_y,[temp0,#catch_frame.xframe])
4116        __(str arg_y,[rcontext,#tcr.xframe])
4117        __(beq local_label(_nthrow1v_dont_unbind))
4118        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
4119local_label(_nthrow1v_dont_unbind):
4120        __(ldr temp1,[temp0,#catch_frame.catch_tag])
4121        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
4122        __(sub sp,temp0,#fulltag_misc)
4123        __(beq local_label(_nthrow1v_do_unwind))
4124        /* A catch frame.  If the last one, restore context from there.  */
4125        __(cmp temp2,#0)
4126        __(ldreq vsp,[sp,#catch_frame.size+lisp_frame.savevsp])
4127        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4128        __(pop_lisp_fprs())
4129        __(b local_label(_nthrow1v_nextframe))
4130local_label(_nthrow1v_do_unwind):
4131        /* This is harder, but not as hard (not as much BLTing) as the  */
4132        /* multiple-value case.  */
4133        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
4134        /* protect.  (Clever, eh ?)  */
4135        __(add sp,sp,#catch_frame.size)
4136        /* We used to use a swp instruction to exchange the lr with
4137        the lisp_frame.savelr field of the lisp frame that temp0 addresses.
4138        Multicore ARMv7 machines include the ability to disable the swp
4139        instruction, and some Linux kernels do so and emulate the instruction.
4140        There seems to be evidence that they sometimes do so incorrectly,
4141        so we stopped using swp.
4142        pc_luser_xp() needs to do some extra work if the thread is interrupted
4143        in the midst of the three-instruction sequence at
4144        swap_lr_lisp_frame_temp0.
4145        */
4146        __(mov imm1,#0)
4147        __(mov temp0,sp)
4148        __(mov imm0,#3<<num_subtag_bits)
4149        __(orr imm0,imm0,#subtag_simple_vector)
4150        __(stmdb sp!,{imm0,imm1,arg_z,temp2})
4151        .globl C(swap_lr_lisp_frame_temp0)
4152        .globl C(swap_lr_lisp_frame_temp0_end)
4153        /* This instruction sequence needs support from pc_luser_xp() */
4154C(swap_lr_lisp_frame_temp0):           
4155        __(ldr imm0,[temp0,#lisp_frame.savelr])
4156        __(str lr,[temp0,#lisp_frame.savelr])
4157        __(mov lr,imm0)
4158C(swap_lr_lisp_frame_temp0_end):           
4159        __(ldr nfn,[temp0,#lisp_frame.savefn])
4160        __(str fn,[temp0,#lisp_frame.savefn])
4161        __(ldr vsp,[temp0,#lisp_frame.savevsp])
4162        __(mov fn,nfn)
4163        __(add temp0,temp0,#lisp_frame.size)
4164        __(restore_lisp_fprs(temp0))
4165        __(str imm1,[rcontext,#tcr.unwinding])
4166        __(blx lr)
4167        __(mov imm1,#1)
4168        __(ldr arg_z,[sp,#8])
4169        __(str imm1,[rcontext,#tcr.unwinding])
4170        __(ldr temp2,[sp,#12])
4171        __(add sp,sp,#4*node_size)
4172        __(restore_lisp_frame(imm0))
4173        __(discard_lisp_fprs())
4174        __(b local_label(_nthrow1v_nextframe))
4175local_label(_nthrow1v_done):
4176        __(mov imm0,#0)
4177        __(str imm0,[rcontext,#tcr.unwinding])
4178        /* nargs has an undefined value here, so we can clobber it while */
4179        /* polling for a deferred interrupt  */
4180        __(check_pending_interrupt(nargs))
4181        __(bx lr)
4182_endfn       
4183
4184_startfn(C(nthrownv))
4185        new_local_labels()
4186local_label(nthrownv_nextframe):
4187        __(subs temp2,temp2,#fixnum_one)
4188        __(ldr temp0,[rcontext,#tcr.catch_top])
4189        __(ldr imm1,[rcontext,#tcr.db_link])
4190        __(blt local_label(nthrownv_done))
4191        __(ldr arg_y,[temp0,#catch_frame.link])
4192        __(ldr imm0,[temp0,#catch_frame.db_link])
4193        __(cmp imm0,imm1)
4194        __(str arg_y,[rcontext,#tcr.catch_top])
4195        __(ldr arg_y,[temp0,#catch_frame.xframe])
4196        __(str arg_y,[rcontext,#tcr.xframe])
4197        __(beq local_label(nthrownv_dont_unbind))
4198        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
4199local_label(nthrownv_dont_unbind):
4200        __(ldr temp1,[temp0,#catch_frame.catch_tag])
4201        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
4202        __(sub sp,temp0,#fulltag_misc)
4203        __(beq local_label(nthrownv_do_unwind))
4204        __(cmp temp2,#0)
4205/* A catch frame.  If the last one, restore context from there.  */
4206        __(bne local_label(nthrownv_skip))
4207        __(ldr imm0,[sp,#catch_frame.size+lisp_frame.savevsp])
4208        __(add imm1,vsp,nargs)
4209        __(movs arg_z,nargs)
4210        __(b local_label(nthrownv_push_test))
4211local_label(nthrownv_push_loop):       
4212        __(subs arg_z,arg_z,#fixnumone)
4213        __(ldr temp1,[imm1,#-node_size]!)
4214        __(push1(temp1,imm0))
4215local_label(nthrownv_push_test):       
4216        __(bne local_label(nthrownv_push_loop))
4217        __(mov vsp,imm0)
4218local_label(nthrownv_skip):     
4219        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4220        __(pop_lisp_fprs())         
4221        __(b local_label(nthrownv_nextframe))               
4222local_label(nthrownv_do_unwind):
4223        __(ldr arg_x,[temp0,#catch_frame.xframe])
4224        __(ldr arg_z,[temp0,#catch_frame.last_lisp_frame])
4225        __(sub sp,temp0,#fulltag_misc)
4226        __(str arg_x,[rcontext,#tcr.xframe])
4227        __(str arg_z,[rcontext,#tcr.last_lisp_frame])
4228        __(add sp,sp,#catch_frame.size)
4229        __(add imm1,nargs,#node_size)
4230        __(mov arg_z,sp)
4231        __(dnode_align(imm0,imm1,node_size))
4232        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
4233        __(orr imm1,imm1,#subtag_u32_vector)
4234        __(stack_allocate_zeroed_ivector(imm1,imm0))
4235        __(mov imm0,#subtag_simple_vector)
4236        __(strb imm0,[sp])
4237        __(str temp2,[sp,#node_size])
4238        __(add temp2,sp,#dnode_size)
4239        __(add temp2,temp2,nargs)
4240        __(add temp1,vsp,nargs)
4241        __(b local_label(nthrownv_tpushtest))
4242local_label(nthrownv_tpushloop):       
4243        __(ldr temp0,[temp1,#-node_size]!)
4244        __(push1(temp0,temp2))
4245local_label(nthrownv_tpushtest):       
4246        __(subs nargs,nargs,#fixnumone)
4247        __(bge local_label(nthrownv_tpushloop))
4248        __(mov imm1,#0)
4249        /* This instruction sequence needs support from pc_luser_xp() */
4250        .globl C(swap_lr_lisp_frame_arg_z)
4251        .globl C(swap_lr_lisp_frame_arg_z_end)
4252C(swap_lr_lisp_frame_arg_z):                   
4253        __(ldr imm0,[arg_z,#lisp_frame.savelr])
4254        __(str lr,[arg_z,#lisp_frame.savelr])
4255        __(mov lr,imm0)
4256C(swap_lr_lisp_frame_arg_z_end):                   
4257        __(ldr nfn,[arg_z,#lisp_frame.savefn])
4258        __(str fn,[arg_z,#lisp_frame.savefn])
4259        __(ldr vsp,[arg_z,#lisp_frame.savevsp])
4260        __(add arg_z,arg_z,#lisp_frame.size)
4261        __(restore_lisp_fprs(arg_z))
4262        __(str imm1,[rcontext,#tcr.unwinding])
4263        __(mov fn,nfn)
4264        __(blx lr)
4265        __(mov imm1,#1)
4266        __(str imm1,[rcontext,#tcr.unwinding])
4267        __(ldr imm0,[sp])
4268        __(header_length(imm0,imm0))
4269        __(subs nargs,imm0,#node_size)
4270        __(add imm0,imm0,#node_size)
4271        __(add temp0,sp,imm0)
4272        __(mov imm0,nargs)
4273        __(add arg_z,temp0,#node_size)
4274        __(bic arg_z,arg_z,#fulltagmask)
4275        __(b local_label(nthrownv_tpoptest))
4276local_label(nthrownv_tpoploop): 
4277        __(subs imm0,imm0,#node_size)       
4278        __(vpush1(temp2))
4279local_label(nthrownv_tpoptest): 
4280        __(ldr temp2,[temp0,#-node_size]!)
4281        __(bne local_label(nthrownv_tpoploop))
4282        __(mov sp,arg_z)
4283        __(ldr fn,[sp,#lisp_frame.savefn])
4284        __(ldr lr,[sp,#lisp_frame.savelr])
4285        __(discard_lisp_frame())
4286        __(discard_lisp_fprs())
4287        __(b local_label(nthrownv_nextframe))
4288local_label(nthrownv_done):     
4289        __(mov imm0,#0)
4290        __(str imm0,[rcontext,#tcr.unwinding])
4291        __(check_pending_interrupt(imm1))
4292        __(bx lr)
4293_endfn               
4294
4295_startfn(C(progvsave))       
4296        /* Error if arg_z isn't a proper list.  That's unlikely, */
4297        /* but it's better to check now than to crash later. */
4298        __(cmp arg_z,#nil_value)
4299        __(mov arg_x,arg_z) /* fast  */
4300        __(mov temp1,arg_z) /* slow  */
4301        __(beq 9f)  /* Null list is proper  */
43020:
4303        __(trap_unless_list(arg_x,imm0))
4304        __(_cdr(temp2,arg_x)) /* (null (cdr fast)) ?  */
4305        __(trap_unless_list(temp2,imm0,cr0))
4306        __(cmp temp2,#nil_value)
4307        __(_cdr(arg_x,temp2))
4308        __(beq 9f)
4309        __(_cdr(temp1,temp1))
4310        __(cmp arg_x,temp1)
4311        __(bne 0b)
4312        __(mov arg_y,#XIMPROPERLIST)
4313        __(set_nargs(2))
4314        __(b _SPksignalerr)
43159:      /* Whew   */
4316 
4317        /* Next, determine the length of arg_y.  We  */
4318        /* know that it's a proper list.  */
4319        __(mov imm0,#0)
4320        __(mov arg_x,arg_y)
43211:
4322        __(cmp arg_x,#nil_value)
4323        __(addne imm0,imm0,#node_size)
4324        __(_cdr(arg_x,arg_x))
4325        __(bne 1b)
4326        /* imm0 is now (boxed) triplet count.  */
4327        /* Determine word count, add 1 (to align), and make room.  */
4328        /* if count is 0, make an empty tsp frame and exit  */
4329        __(cmp imm0,#0)
4330        __(add imm1,imm0,imm0,lsl #1)
4331        __(add imm1,imm1,#node_size) /* Room for binding count */
4332        __(dnode_align(imm2,imm1,node_size))
4333        __(bne 2f)
4334        __(movc16(imm0,make_header(1,subtag_simple_vector)))
4335        __(mov imm1,#0)
4336        __(stmdb sp!,{imm0,imm1})
4337        __(b 9f)
43382:
4339        __(orr imm1,imm1,fixnumone) /* force odd */
4340        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
4341        __(orr imm1,imm1,#subtag_u32_vector)
4342        __(mov temp1,sp)
4343        __(stack_allocate_zeroed_ivector(imm1,imm2))
4344        __(mov imm1,#subtag_simple_vector)
4345        __(strb imm1,[sp])
4346        __(str imm0,[sp,#node_size])
4347        __(ldr imm1,[rcontext,#tcr.db_link])
43483:      __(_car(temp0,arg_y))
4349        __(ldr imm0,[temp0,#symbol.binding_index])
4350        __(ldr imm2,[rcontext,#tcr.tlb_limit])
4351        __(_cdr(arg_y,arg_y))
4352        __(cmp imm2,imm0)
4353        __(bhi 4f)
4354        __(uuo_tlb_too_small(al,imm0))
43554:             
4356        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
4357        __(ldr temp0,[arg_x,imm0])
4358        __(cmp arg_z,#nil_value)
4359        __(mov temp2,#unbound_marker)
4360        __(ldrne temp2,[arg_z,#cons.car])
4361        __(_cdr(arg_z,arg_z))
4362        __(cmp arg_y,#nil_value)
4363        __(push1(temp0,temp1))
4364        __(push1(imm0,temp1))
4365        __(push1(imm1,temp1))
4366        __(mov imm1,temp1)
4367        __(str temp2,[arg_x,imm0])
4368        __(bne 3b)
4369        __(str imm1,[rcontext,#tcr.db_link])
43709:             
4371        __(mov arg_z,#unbound_marker)
4372        __(mov imm2,#fixnum_one)
4373        __(mkcatch())       
4374        __(bx lr)
4375_endfn                               
4376               
4377/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
4378/* sure that there's an empty tsp frame to keep the compiler happy.  */
4379_startfn(stack_misc_alloc_no_room)
4380        __(mov imm0,#stack_alloc_marker)
4381        __(mov imm1,sp)
4382        __(stmdb sp!,{imm0,imm1})
4383        __(b _SPmisc_alloc)
4384_endfn       
4385_startfn(stack_misc_alloc_init_no_room)
4386/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
4387/* sure that there's an empty tsp frame to keep the compiler happy.  */
4388        __(mov imm0,#stack_alloc_marker)
4389        __(mov imm1,sp)
4390        __(stmdb sp!,{imm0,imm1})
4391        __(b _SPmisc_alloc_init)
4392_endfn       
4393_startfn(stack_misc_alloc_init_ivector)
4394        __(mov imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
4395        __(orr imm0,imm0,arg_y,lsr #fixnumshift)
4396        __(cmp arg_y,#max_32_bit_ivector_subtag<<fixnumshift)
4397        __(movle imm1,arg_x)
4398        __(ble 8f)
4399        __(cmp arg_y,#max_8_bit_ivector_subtag<<fixnumshift)
4400        __(movle imm1,arg_x,lsr #fixnumshift)
4401        __(ble 8f)
4402        __(cmp arg_y,#max_16_bit_ivector_subtag<<fixnumshift)
4403        __(movle imm1,arg_x,lsr #1)
4404        __(ble 8f)
4405        __(cmp arg_y,#subtag_double_float)
4406        __(moveq imm1,arg_x,lsl #1)
4407        __(addeq imm1,imm1,#node_size)
4408        __(addne imm1,arg_x,#7<<fixnumshift)
4409        __(movne imm1,imm1,lsr#3+fixnumshift)
44108:      __(dnode_align(imm1,imm1,node_size))
4411        __(ldr temp0,[rcontext,#tcr.cs_limit])
4412        __(sub temp1,sp,imm1)
4413        __(cmp temp1,temp0)
4414        __(bls stack_misc_alloc_init_no_room)
4415        __(mov temp0,#stack_alloc_marker)
4416        __(mov temp1,sp)
4417        __(stack_allocate_zeroed_ivector(imm0,imm1))
4418        __(mov arg_y,arg_z)
4419        __(add arg_z,sp,#fulltag_misc)
4420        __(stmdb sp!,{temp0,temp1})
4421        __(b initialize_vector)
4422_endfn       
4423/* This is called from a lisp-style context and calls a lisp function. */
4424/* This does the moral equivalent of */
4425/*   (loop  */
4426/*      (let* ((fn (%function_on_top_of_lisp_stack))) */
4427/*        (if fn */
4428/*           (catch %toplevel-catch% */
4429/*             (funcall fn)) */
4430/*            (return nil)))) */
4431
4432_startfn(toplevel_loop)
4433        __(build_lisp_frame(imm0))
4434        __(b local_label(test))
4435local_label(loop):
4436        __(ref_nrs_value(arg_z,toplcatch))
4437        __(bl _SPmkcatch1v)
4438        __(b local_label(test)) /* cleanup address, not really a branch */
4439        __(ldr nfn,[vsp,#0])
4440        __(set_nargs(0))
4441        __(bl _SPfuncall)
4442        __(mov arg_z,#nil_value)
4443        __(mov imm0,#fixnum_one)
4444        __(bl _SPnthrow1value)
4445local_label(test):
4446        __(ldr nfn,[vsp,#0])
4447        __(cmp nfn,#nil_value)
4448        __(bne local_label(loop))
4449        __(return_lisp_frame(imm0))
4450        _endfn
4451
4452
4453/* This gets called with R0 pointing to the current TCR. */
4454/* r1 is 0 if we want to start the whole thing rolling, */
4455/* non-zero if we want to reset the current process */
4456/* by throwing to toplevel */
4457
4458        .globl _SPreset
4459_exportfn(C(start_lisp))
4460        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4461        __(mov rcontext,r0)
4462        __(mov r0,sp)
4463        __(tst sp,#4)
4464        __(strne r0,[sp,#-4]!)
4465        __(streq r0,[sp,#-8]!)
4466        __(mov arg_z,#0)
4467        __(mov arg_y,#0)
4468        __(mov arg_x,#0)
4469        __(mov temp0,#0)
4470        __(mov temp1,#0)
4471        __(mov temp2,#0)
4472        __(mov allocptr,#VOID_ALLOCPTR)
4473        __(mov fn,#0)
4474        __(ldr vsp,[rcontext,#tcr.save_vsp])
4475        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
4476        __(sub imm0,imm2,sp)
4477        __(add imm0,imm0,#node_size)
4478        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
4479        __(orr imm0,imm0,#subtag_u32_vector)
4480        __(stmdb sp!,{imm0,imm2})
4481        __(push_foreign_fprs())
4482        __(adr imm0,1f)
4483        __(fldd double_float_zero,[imm0])
4484        __(mov imm0,#TCR_STATE_LISP)
4485        __(str imm0,[rcontext,#tcr.valence])
4486        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
4487        __(bl toplevel_loop)
4488        __(ldr imm1,[sp,#(9*8)+4])
4489        __(mov imm0,#TCR_STATE_FOREIGN)
4490        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4491        __(str imm0,[rcontext,#tcr.valence])
4492        __(pop_foreign_fprs())
4493        __(add sp,sp,#2*node_size)
4494        __(mov imm0,#nil_value)
4495        __(ldr sp,[sp])
4496        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4497        __(bx lr)
4498_endfn
4499       
4500        .align 3
45011:
4502        .long 0
4503        .long 0
4504
4505/* This gets called with r0 = the current thread's TCR.  Should
4506   call RESTORE-LISP-POINTERS and return 0 if it returns normally
4507   and non-0 if it throws. */
4508       
4509_exportfn(C(init_lisp))
4510        new_local_labels()
4511        new_macro_labels()
4512        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4513        __(mov rcontext,r0)
4514        __(mov r0,sp)
4515        __(tst sp,#4)
4516        __(strne r0,[sp,#-4]!)
4517        __(streq r0,[sp,#-8]!)
4518        __(mov arg_z,#0)
4519        __(mov arg_y,#0)
4520        __(mov arg_x,#0)
4521        __(mov temp0,#0)
4522        __(mov temp1,#0)
4523        __(mov temp2,#0)
4524        __(mov allocptr,#VOID_ALLOCPTR)
4525        __(mov fn,#0)
4526        __(ldr vsp,[rcontext,#tcr.save_vsp])
4527        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
4528        __(sub imm0,imm2,sp)
4529        __(add imm0,imm0,#node_size)
4530        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
4531        __(orr imm0,imm0,#subtag_u32_vector)
4532        __(stmdb sp!,{imm0,imm2})
4533        __(push_foreign_fprs())
4534        __(adr imm0,1b)
4535        __(fldd double_float_zero,[imm0])
4536        __(mov imm0,#TCR_STATE_LISP)
4537        __(str imm0,[rcontext,#tcr.valence])
4538        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
4539        __(ref_nrs_function(nfn,restore_lisp_pointers))
4540        __(extract_subtag(imm0,nfn))
4541        __(cmp imm0,#subtag_function)
4542        __(bne local_label(fail))
4543        __(ref_nrs_value(arg_z,toplcatch))
4544        __(bl _SPmkcatch1v)
4545        __(b local_label(fail)) /* cleanup address */
4546        __(ref_nrs_function(nfn,restore_lisp_pointers))
4547        __(set_nargs(0))
4548        __(bl _SPfuncall)
4549        __(mov arg_z,#0)
4550        __(mov imm0,#fixnum_one)
4551        __(bl _SPnthrow1value)
4552        __(b local_label(done))
4553local_label(fail):     
4554        __(mov arg_z,#fixnum_one)
4555local_label(done):                     
4556        __(ldr imm1,[sp,#(9*8)+4])
4557        __(mov imm0,#TCR_STATE_FOREIGN)
4558        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4559        __(str imm0,[rcontext,#tcr.valence])
4560        __(pop_foreign_fprs())
4561        __(add sp,sp,#2*node_size)
4562        __(unbox_fixnum(imm0,arg_z))
4563        __(ldr sp,[sp])
4564        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4565        __(bx lr)
4566_endfn
4567
4568/* Called (on something other than the initial thread) with r0=tcr,
4569   r1 = a (void *) arg.  Returns a null pointer/0, but declared to return
4570   void.
4571*/               
4572_exportfn(C(os_main))
4573        new_local_labels()
4574        new_macro_labels()
4575        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4576        __(mov rcontext,r0)
4577        __(mov r0,sp)
4578        __(tst sp,#4)
4579        __(strne r0,[sp,#-4]!)
4580        __(streq r0,[sp,#-8]!)
4581        __(mov arg_z,#0)
4582        __(mov arg_y,#0)
4583        __(mov arg_x,#0)
4584        __(mov temp0,#0)
4585        __(mov temp1,#0)
4586        __(mov temp2,#0)
4587        __(mov allocptr,#VOID_ALLOCPTR)
4588        __(mov fn,#0)
4589        __(ldr vsp,[rcontext,#tcr.save_vsp])
4590        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
4591        __(sub imm0,imm2,sp)
4592        __(add imm0,imm0,#node_size)
4593        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
4594        __(orr imm0,imm0,#subtag_u32_vector)
4595        __(stmdb sp!,{imm0,imm2})
4596        __(push_foreign_fprs())
4597        __(adr imm0,1b)
4598        __(fldd double_float_zero,[imm0])
4599        __(mov imm0,#TCR_STATE_LISP)
4600        __(str imm0,[rcontext,#tcr.valence])
4601        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
4602        __(movc16(imm0,make_header(macptr.element_count,subtag_macptr)))
4603        __(stmdb sp!,{imm0,imm1,arg_z,arg_y})
4604        __(add arg_z,sp,#fulltag_misc)
4605        __(ref_nrs_function(nfn,os_init_function))
4606        __(set_nargs(1))
4607        __(bl _SPfuncall)
4608        __(add sp,sp,#16)
4609        __(ldr imm1,[sp,#(9*8)+4])
4610        __(mov imm0,#TCR_STATE_FOREIGN)
4611        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4612        __(str imm0,[rcontext,#tcr.valence])
4613        __(pop_foreign_fprs())
4614        __(add sp,sp,#2*node_size)
4615        __(mov imm0,#nil_value)
4616        __(ldr sp,[sp])
4617        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4618        __(bx lr)
4619_endfn
4620                               
4621        .data
4622        .globl C(sptab)
4623        .globl C(sptab_end)
4624        new_local_labels()
4625C(sptab):
4626        .long local_label(start)
4627C(sptab_end):   
4628        .long local_label(end)
4629local_label(start):                     
4630        .long _SPfix_nfn_entrypoint /* must be first */
4631        .long _SPbuiltin_plus
4632        .long _SPbuiltin_minus
4633        .long _SPbuiltin_times
4634        .long _SPbuiltin_div
4635        .long _SPbuiltin_eq
4636        .long _SPbuiltin_ne
4637        .long _SPbuiltin_gt
4638        .long _SPbuiltin_ge
4639        .long _SPbuiltin_lt
4640        .long _SPbuiltin_le
4641        .long _SPbuiltin_eql
4642        .long _SPbuiltin_length
4643        .long _SPbuiltin_seqtype
4644        .long _SPbuiltin_assq
4645        .long _SPbuiltin_memq
4646        .long _SPbuiltin_logbitp
4647        .long _SPbuiltin_logior
4648        .long _SPbuiltin_logand
4649        .long _SPbuiltin_ash
4650        .long _SPbuiltin_negate
4651        .long _SPbuiltin_logxor
4652        .long _SPbuiltin_aref1
4653        .long _SPbuiltin_aset1
4654        .long _SPfuncall
4655        .long _SPmkcatch1v
4656        .long _SPmkcatchmv
4657        .long _SPmkunwind
4658        .long _SPbind
4659        .long _SPconslist
4660        .long _SPconslist_star
4661        .long _SPmakes32
4662        .long _SPmakeu32
4663        .long _SPfix_overflow
4664        .long _SPmakeu64
4665        .long _SPmakes64
4666        .long _SPmvpass
4667        .long _SPvalues
4668        .long _SPnvalret
4669        .long _SPthrow
4670        .long _SPnthrowvalues
4671        .long _SPnthrow1value
4672        .long _SPbind_self
4673        .long _SPbind_nil
4674        .long _SPbind_self_boundp_check
4675        .long _SPrplaca
4676        .long _SPrplacd
4677        .long _SPgvset
4678        .long _SPset_hash_key
4679        .long _SPstore_node_conditional
4680        .long _SPset_hash_key_conditional
4681        .long _SPstkconslist
4682        .long _SPstkconslist_star
4683        .long _SPmkstackv
4684        .long _SPsetqsym
4685        .long _SPprogvsave
4686        .long _SPstack_misc_alloc
4687        .long _SPgvector
4688        .long _SPfitvals
4689        .long _SPnthvalue
4690        .long _SPdefault_optional_args
4691        .long _SPopt_supplied_p
4692        .long _SPheap_rest_arg
4693        .long _SPreq_heap_rest_arg
4694        .long _SPheap_cons_rest_arg
4695        .long _SPcheck_fpu_exception
4696        .long _SPdiscard_stack_object
4697        .long _SPksignalerr
4698        .long _SPstack_rest_arg
4699        .long _SPreq_stack_rest_arg
4700        .long _SPstack_cons_rest_arg
4701        .long _SPcall_closure       
4702        .long _SPspreadargz
4703        .long _SPtfuncallgen
4704        .long _SPtfuncallslide
4705        .long _SPjmpsym
4706        .long _SPtcallsymgen
4707        .long _SPtcallsymslide
4708        .long _SPtcallnfngen
4709        .long _SPtcallnfnslide
4710        .long _SPmisc_ref
4711        .long _SPsubtag_misc_ref
4712        .long _SPmakestackblock
4713        .long _SPmakestackblock0
4714        .long _SPmakestacklist
4715        .long _SPstkgvector
4716        .long _SPmisc_alloc
4717        .long _SPatomic_incf_node
4718        .long _SPunused1
4719        .long _SPunused2
4720        .long _SPrecover_values
4721        .long _SPinteger_sign
4722        .long _SPsubtag_misc_set
4723        .long _SPmisc_set
4724        .long _SPspread_lexprz
4725        .long _SPreset
4726        .long _SPmvslide
4727        .long _SPsave_values
4728        .long _SPadd_values
4729        .long _SPmisc_alloc_init
4730        .long _SPstack_misc_alloc_init
4731        .long _SPpopj
4732        .long _SPudiv64by32
4733        .long _SPgetu64
4734        .long _SPgets64
4735        .long _SPspecref
4736        .long _SPspecrefcheck
4737        .long _SPspecset
4738        .long _SPgets32
4739        .long _SPgetu32
4740        .long _SPmvpasssym
4741        .long _SPunbind
4742        .long _SPunbind_n
4743        .long _SPunbind_to
4744        .long _SPprogvrestore
4745        .long _SPbind_interrupt_level_0
4746        .long _SPbind_interrupt_level_m1
4747        .long _SPbind_interrupt_level
4748        .long _SPunbind_interrupt_level
4749        .long _SParef2
4750        .long _SParef3
4751        .long _SPaset2
4752        .long _SPaset3
4753        .long _SPkeyword_bind
4754        .long _SPudiv32
4755        .long _SPsdiv32
4756        .long _SPeabi_ff_call
4757        .long _SPdebind
4758        .long _SPeabi_callback
4759        .long _SPeabi_ff_callhf
4760local_label(end):       
4761                _endfile
Note: See TracBrowser for help on using the repository browser.