source: release/1.9/source/lisp-kernel/arm-spentry.s @ 16083

Last change on this file since 16083 was 15755, checked in by gb, 6 years ago

Recent changes from trunk.

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