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

Last change on this file since 15294 was 15294, checked in by gb, 8 years ago

Don't call out in .SPbuiltin_eql. Implement #'EQL for ARM in terms
of .SPbuiltin_eql.

Note that running the old kernel with a new image will cause an
infinite loop in EQL in some cases. Don't do that; do
(REBUILD-CCL :FULL T) to avoid the issue.

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