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

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

Propagate recent trunk changes.

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