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

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

New subprim .SPeabi_ff_callhf: loads arg fprs from vector on top
of stack, shrinks vector, falls into .SPeabi_ff_call.

TODO: will need hard-float runtime support for callbacks.

File size: 162.9 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_spentry(eabi_ff_callhf)
2942        __(add imm0,sp,#8)
2943        __(fldmfdd imm0,{d0-d7})
2944        __(ldmia sp,{imm0-imm1})
2945        __(sub imm0,imm0,#(16<<num_subtag_bits))
2946        __(add imm2,sp,#16<<2)
2947        __(stm imm2,{imm0-imm1})
2948        __(mov sp,imm2)
2949_spentry(eabi_ff_call)
2950        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2951        __(stmdb vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2952        __(str vsp,[rcontext,#tcr.save_vsp])
2953/* There's a u32 vector on top of the stack ; its first data word points
2954   to the previous stack object.  The 4 words at the bottom of the vector
2955   are reserved for a lisp frame, which we construct carefully ... */
2956        __(mov imm0,#lisp_frame_marker)
2957        __(mov imm1,#0)
2958        __(ldr temp0,[sp,#4])
2959        __(sub temp0,temp0,#lisp_frame.size)
2960        __(str imm0,[temp0,#lisp_frame.marker])
2961        __(ldr imm0,[sp,#0])       
2962        __(str imm1,[temp0,#lisp_frame.savefn])
2963        __(str imm1,[temp0,#lisp_frame.savelr])
2964        __(sub imm0,imm0,#(lisp_frame.size/4)<<num_subtag_bits)
2965        __(str vsp,[temp0,#lisp_frame.savevsp])
2966        __(str imm0,[sp,#0])
2967        __(str lr,[temp0,#lisp_frame.savelr])
2968        __(str fn,[temp0,#lisp_frame.savefn])
2969        __(str allocptr,[rcontext,#tcr.save_allocptr])
2970        __(str temp0,[rcontext,#tcr.last_lisp_frame])
2971        __(mov temp0,rcontext)
2972        __(test_fixnum(arg_z))
2973        __(moveq imm1,arg_z,asr #fixnumshift)
2974        __(ldrne imm1,[arg_z,#misc_data_offset])
2975        __(mov imm0,#TCR_STATE_FOREIGN)
2976        __(str imm0,[rcontext,#tcr.valence])
2977        __(mov r4,imm1)
2978        __(add sp,sp,#dnode_size)
2979        __(ldmia sp!,{r0,r1,r2,r3})
2980        __(blx r4)
2981        __(adr temp1,1f)
2982        __(fldd double_float_zero,[temp1])
2983        __(mov temp1,#0)
2984        __(mov temp2,#0)
2985        __(mov arg_z,#0)
2986        __(mov arg_y,#0)
2987        __(mov arg_x,#0)
2988        __(mov fn,#0)
2989        __(mov allocptr,#VOID_ALLOCPTR)
2990        __(mov rcontext,temp0)
2991        __(ldr sp,[rcontext,#tcr.last_lisp_frame])
2992        __(str fn,[rcontext,#tcr.valence])
2993        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2994        __(restore_lisp_frame(temp0))
2995        __(ldmia vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2996        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2997        __(check_pending_interrupt(temp2))
2998        __(bx lr)
2999        .align 3
30001:      .long 0
3001        .long 0               
3002       
3003
3004_spentry(debind)
3005        new_local_labels()
3006        __(mov temp0,vsp)
3007        __(mov temp1,arg_z)
3008        __(ands imm0,nargs,#0xff)
3009        __(mov arg_y,#nil_value)
3010        __(b local_label(req_test))
3011local_label(req_loop): 
3012        __(cmp arg_reg,#nil_value)
3013        __(extract_lisptag(imm1,arg_reg))
3014        __(beq local_label(toofew))
3015        __(cmp imm1,#tag_list)
3016        __(bne local_label(badlist))
3017        __(subs imm0,imm0,#1)
3018        __(_car(arg_x,arg_reg))
3019        __(_cdr(arg_reg,arg_reg))
3020        __(vpush1(arg_x))
3021local_label(req_test):
3022        __(bne local_label(req_loop))
3023        __(mov imm0,#0xff)
3024        __(ands imm0,imm0,nargs,lsr #8)
3025        __(beq local_label(rest_keys))
3026        __(tst nargs,#mask_initopt)
3027        __(bne local_label(opt_supp))
3028        /* 'simple' &optionals:  no supplied-p, default to nil.   */
3029local_label(simple_opt_loop):
3030        __(cmp arg_reg,#nil_value)
3031        __(extract_lisptag(imm1,arg_reg))
3032        __(beq local_label(default_simple_opt))
3033        __(cmp imm1,#tag_list)
3034        __(bne local_label(badlist))
3035        __(subs imm0,imm0,#1)
3036        __(_car(arg_x,arg_reg))
3037        __(_cdr(arg_reg,arg_reg))
3038        __(vpush1(arg_x))
3039        __(bne local_label(simple_opt_loop))
3040        __(b local_label(rest_keys))
3041local_label(default_simple_opt):       
3042        __(subs imm0,imm0,#1)
3043        __(vpush1(arg_y))
3044        __(bne local_label(default_simple_opt))
3045        __(b local_label(rest_keys))
3046local_label(opt_supp):   
3047        __(cmp arg_reg,#nil_value)
3048        __(extract_lisptag(imm1,arg_reg))
3049        __(beq local_label(default_hard_opt))
3050        __(cmp imm1,#tag_list)
3051        __(bne local_label(badlist))
3052        __(subs imm0,imm0,#1)
3053        __(_car(arg_x,arg_reg))
3054        __(_cdr(arg_reg,arg_reg))
3055        __(vpush1(arg_x))
3056        __(add arg_x,arg_y,#t_offset)
3057        __(vpush1(arg_x))
3058        __(bne local_label(opt_supp))
3059        __(b local_label(rest_keys))
3060local_label(default_hard_opt): 
3061        __(subs imm0,imm0,#1)
3062        __(vpush1(arg_y))
3063        __(vpush1(arg_y))
3064        __(bne local_label(default_hard_opt))
3065local_label(rest_keys):
3066        __(tst nargs,#mask_restp)
3067        __(bne local_label(have_rest))
3068        __(tst nargs,#mask_keyp)
3069        __(bne local_label(have_keys))
3070        __(cmp arg_reg,#nil_value)
3071        __(bne local_label(toomany))
3072        __(bx lr)
3073local_label(have_rest):
3074        __(vpush1(arg_reg))
3075        __(tst nargs,#mask_keyp)
3076        __(bne local_label(have_keys))
3077        __(bx lr)
3078local_label(have_keys):
3079        __(mov imm0,#256)
3080        __(mov arg_y,arg_reg)
3081local_label(count_keys_loop):   
3082        __(cmp arg_y,#nil_value)
3083        __(beq local_label(counted_keys))
3084        __(subs imm0,imm0,#1)
3085        __(bmi local_label(toomany))
3086        __(extract_lisptag(imm1,arg_y))
3087        __(cmp imm1,#tag_list)
3088        __(bne local_label(badlist))
3089        __(_cdr(arg_y,arg_y))
3090        __(cmp arg_y,#nil_value)
3091        __(extract_lisptag(imm1,arg_y))
3092        __(beq local_label(badkeys))
3093        __(cmp imm1,#tag_list)
3094        __(bne local_label(badlist))
3095        __(_cdr(arg_y,arg_y))
3096        __(b local_label(count_keys_loop))
3097local_label(counted_keys):     
3098        /* We've got a proper, even-length list of key/value pairs in  */
3099        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
3100        /* of NILs on the vstack.  (We've also cdred down arg_y until it */
3101        /* contains NIL.) */
3102        __(mov imm0,#0xff)
3103        __(ands imm0,imm0,nargs,lsr #16)
3104        __(mov imm1,vsp)
3105        __(b local_label(push_pair_test))
3106local_label(push_pair_loop):
3107        __(subs imm0,imm0,#1)
3108        __(vpush1(arg_y))
3109        __(vpush1(arg_y))
3110local_label(push_pair_test):   
3111        __(bne local_label(push_pair_loop))
3112        __(b local_label(provided_key_loop))
3113       
3114local_label(next_provided_key):
3115        __(_car(arg_x,arg_reg))
3116        __(ref_nrs_symbol(imm0,kallowotherkeys,imm0))
3117        __(cmp arg_x,imm0)
3118        __(bne local_label(not_aok))
3119        __(orr nargs,nargs,#mask_aok_this)
3120        __(tst nargs,#mask_aok_seen)
3121        __(bne local_label(not_aok))
3122        __(_cdr(arg_x,arg_reg))
3123        __(_car(arg_x,arg_x))
3124        __(orr nargs,nargs,#mask_aok_seen)
3125        __(cmp arg_x,#nil_value)
3126        __(orrne nargs,nargs,#mask_aok)
3127        __(_car(arg_x,arg_reg))
3128local_label(not_aok):   
3129        __(getvheader(imm0,keyvect_reg))
3130        __(header_length(arg_y,imm0))
3131        __(add imm0,arg_y,#misc_data_offset)
3132        __(b local_label(match_key_test))
3133local_label(match_key_loop):   
3134        __(ldr arg_y,[keyvect_reg,imm0])
3135        __(cmp arg_x,arg_y)
3136        __(bne local_label(match_key_test))
3137        __(sub imm0,imm0,#misc_data_offset)
3138        __(sub imm0,imm1,imm0,lsl #1)
3139        __(ldr arg_y,[imm0,#-2*node_size])
3140        __(cmp arg_y,#nil_value)
3141        __(bne local_label(provided_key_done))
3142        __(_cdr(arg_x,arg_reg))
3143        __(_car(arg_x,arg_x))
3144        __(str arg_x,[imm0,#-node_size])
3145        __(mov arg_x,#nil_value)
3146        __(add arg_x,arg_x,#t_offset)
3147        __(str arg_x,[imm0,#-2*node_size])
3148        __(b local_label(provided_key_done))
3149local_label(match_key_test):   
3150        __(sub imm0,imm0,#node_size)
3151        __(cmp imm0,#misc_data_offset)
3152        __(bge local_label(match_key_loop))
3153        __(tst nargs,#mask_aok_this)
3154        __(bic nargs,nargs,#mask_aok_this)
3155        __(orreq nargs,nargs,#mask_unknown_keyword_seen)
3156local_label(provided_key_done):
3157        __(_cdr(arg_reg,arg_reg))
3158        __(_cdr(arg_reg,arg_reg))
3159local_label(provided_key_loop):
3160        __(cmp arg_reg,#nil_value)
3161        __(bne local_label(next_provided_key))
3162        __(tst nargs,#mask_unknown_keyword_seen)
3163        __(bxeq lr)
3164        __(tst nargs,#mask_aok)
3165        __(bxne lr)
3166local_label(badkeys):
3167        __(mov arg_y,#XBADKEYS)
3168        __(b local_label(destructure_error))
3169local_label(toomany):   
3170        __(mov arg_y,#XCALLTOOMANY)
3171        __(b local_label(destructure_error))
3172local_label(toofew):   
3173        __(mov arg_y,#XCALLTOOFEW)
3174        __(b local_label(destructure_error))
3175local_label(badlist):   
3176        __(mov arg_y,#XCALLNOMATCH)
3177local_label(destructure_error):
3178        __(mov vsp,temp0)
3179        __(mov arg_z,temp1)       
3180        __(set_nargs(2))
3181        __(b _SPksignalerr)
3182       
3183_spentry(eabi_callback)
3184        __(stmdb sp!,{r0,r1,r2,r3})
3185        __(mov r0,sp)
3186        __(sub sp,sp,#2*node_size) /* room for result */
3187        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
3188        __(mov r4,r0)
3189        __(box_fixnum(r5,r12))
3190        __(ref_global(r12,get_tcr,r0))
3191        __(mov r0,#1)
3192        __(blx r12)
3193        __(mov rcontext,r0)
3194        __(tst sp,#4)
3195        __(mov imm2,sp)
3196        __(strne imm2,[sp,#-4]!)
3197        __(streq imm2,[sp,#-8]!)
3198        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
3199        __(sub imm0,imm2,sp)
3200        __(add imm0,imm0,#node_size)
3201        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
3202        __(orr imm0,imm0,#subtag_u32_vector)
3203        __(stmdb sp!,{imm0,imm2})
3204        __(push_foreign_fprs())
3205        __(adr imm0,1f)
3206        __(fldd double_float_zero,[imm0])
3207        __(mov arg_x,#0)
3208        __(mov temp0,#0)
3209        __(mov temp1,#0)
3210        __(mov temp2,#0)
3211        __(mov allocptr,#VOID_ALLOCPTR)
3212        __(mov fn,#0)
3213        __(ldr vsp,[rcontext,#tcr.save_vsp])
3214        __(mov imm0,#TCR_STATE_LISP)
3215        __(str imm0,[rcontext,#tcr.valence])
3216        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
3217        __(set_nargs(2))
3218        __(ref_nrs_symbol(fname,callbacks,imm0))
3219        __(ldr nfn,[fname,#symbol.fcell])
3220        __(ldr lr,[nfn,#_function.entrypoint])
3221        __(blx lr)
3222        __(str vsp,[rcontext,#tcr.save_vsp])
3223        __(ldr imm1,[sp,#(9*8)+4])
3224        __(str imm1,[rcontext,#tcr.last_lisp_frame])
3225        __(str allocptr,[rcontext,#tcr.save_allocptr])
3226        __(mov imm0,#TCR_STATE_FOREIGN)
3227        __(str imm0,[rcontext,#tcr.valence])
3228        __(pop_foreign_fprs())
3229        __(ldr sp,[sp,#node_size*2])   /* drop the ivector that hides foreign stack contents and restore (possibly misaligned) sp */
3230        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
3231        __(ldmia sp!,{r0,r1})
3232        __(add sp,sp,#4*node_size)
3233        __(bx lr)
3234        .align 3
32351:     
3236        .long 0
3237        .long 0       
3238                       
3239/*  EOF, basically  */
3240       
3241_startfn(C(misc_ref_common))
3242        __(add pc,pc,imm1,lsl #2)
3243        __(nop)
3244
3245local_label(misc_ref_jmp):         
3246        /* 00-0f  */
3247        __(b local_label(misc_ref_invalid)) /* 00 even_fixnum  */
3248       
3249        __(b local_label(misc_ref_invalid)) /* 01 cons  */
3250        __(b local_label(misc_ref_node))    /* 02 pseudofunction */
3251        __(b local_label(misc_ref_invalid)) /* 03 imm  */
3252        __(b local_label(misc_ref_invalid)) /* 04 odd_fixnum  */
3253        __(b local_label(misc_ref_invalid)) /* 05 nil  */
3254        __(b local_label(misc_ref_invalid)) /* 06 misc  */
3255        __(b local_label(misc_ref_u32)) /* 07 bignum  */
3256        __(b local_label(misc_ref_invalid)) /* 08 even_fixnum  */
3257        __(b local_label(misc_ref_invalid)) /* 09 cons  */
3258        __(b local_label(misc_ref_node)) /* 0a ratio  */
3259        __(b local_label(misc_ref_invalid)) /* 0b imm  */
3260        __(b local_label(misc_ref_invalid)) /* 0c odd_fixnum  */
3261        __(b local_label(misc_ref_invalid)) /* 0d nil  */
3262        __(b local_label(misc_ref_invalid)) /* 0e misc  */
3263        __(b local_label(misc_ref_u32)) /* 0f single_float  */
3264        /* 10-1f  */
3265        __(b local_label(misc_ref_invalid)) /* 10 even_fixnum  */
3266        __(b local_label(misc_ref_invalid)) /* 11 cons  */
3267        __(b local_label(misc_ref_invalid)) /* 12 nodeheader  */
3268        __(b local_label(misc_ref_invalid)) /* 13 imm  */
3269        __(b local_label(misc_ref_invalid)) /* 14 odd_fixnum  */
3270        __(b local_label(misc_ref_invalid)) /* 15 nil  */
3271        __(b local_label(misc_ref_invalid)) /* 16 misc  */
3272        __(b local_label(misc_ref_u32)) /* 17 double_float  */
3273        __(b local_label(misc_ref_invalid)) /* 18 even_fixnum  */
3274        __(b local_label(misc_ref_invalid)) /* 19 cons  */
3275        __(b local_label(misc_ref_node)) /* 1a complex  */
3276        __(b local_label(misc_ref_invalid)) /* 1b imm  */
3277        __(b local_label(misc_ref_invalid)) /* 1c odd_fixnum  */
3278        __(b local_label(misc_ref_invalid)) /* 1d nil  */
3279        __(b local_label(misc_ref_invalid)) /* 1e misc  */
3280        __(b local_label(misc_ref_u32)) /* 1f macptr  */
3281        /* 20-2f  */
3282        __(b local_label(misc_ref_invalid)) /* 20 even_fixnum  */
3283        __(b local_label(misc_ref_invalid)) /* 21 cons  */
3284        __(b local_label(misc_ref_node)) /* 22 catch_frame  */
3285        __(b local_label(misc_ref_invalid)) /* 23 imm  */
3286        __(b local_label(misc_ref_invalid)) /* 24 odd_fixnum  */
3287        __(b local_label(misc_ref_invalid)) /* 25 nil  */
3288        __(b local_label(misc_ref_invalid)) /* 26 misc  */
3289        __(b local_label(misc_ref_u32)) /* 27 dead_macptr  */
3290        __(b local_label(misc_ref_invalid)) /* 28 even_fixnum  */
3291        __(b local_label(misc_ref_invalid)) /* 29 cons  */
3292        __(b local_label(misc_ref_node)) /* 2a function  */
3293        __(b local_label(misc_ref_invalid)) /* 2b imm  */
3294        __(b local_label(misc_ref_invalid)) /* 2c odd_fixnum  */
3295        __(b local_label(misc_ref_invalid)) /* 2d nil  */
3296        __(b local_label(misc_ref_invalid)) /* 2e misc  */
3297        __(b local_label(misc_ref_u32)) /* 2f code_vector  */
3298        /* 30-3f  */
3299        __(b local_label(misc_ref_invalid)) /* 30 even_fixnum  */
3300        __(b local_label(misc_ref_invalid)) /* 31 cons  */
3301        __(b local_label(misc_ref_node)) /* 32 lisp_thread  */
3302        __(b local_label(misc_ref_invalid)) /* 33 imm  */
3303        __(b local_label(misc_ref_invalid)) /* 34 odd_fixnum  */
3304        __(b local_label(misc_ref_invalid)) /* 35 nil  */
3305        __(b local_label(misc_ref_invalid)) /* 36 misc  */
3306        __(b local_label(misc_ref_u32)) /* 37 creole  */
3307        __(b local_label(misc_ref_invalid)) /* 38 even_fixnum  */
3308        __(b local_label(misc_ref_invalid)) /* 39 cons  */
3309        __(b local_label(misc_ref_node)) /* 3a symbol  */
3310        __(b local_label(misc_ref_invalid)) /* 3b imm  */
3311        __(b local_label(misc_ref_invalid)) /* 3c odd_fixnum  */
3312        __(b local_label(misc_ref_invalid)) /* 3d nil  */
3313        __(b local_label(misc_ref_invalid)) /* 3e misc  */
3314        __(b local_label(misc_ref_u32)) /* 3f xcode_vector  */
3315        /* 40-4f  */
3316        __(b local_label(misc_ref_invalid)) /* 40 even_fixnum  */
3317        __(b local_label(misc_ref_invalid)) /* 41 cons  */
3318        __(b local_label(misc_ref_node)) /* 42 lock  */
3319        __(b local_label(misc_ref_invalid)) /* 43 imm  */
3320        __(b local_label(misc_ref_invalid)) /* 44 odd_fixnum  */
3321        __(b local_label(misc_ref_invalid)) /* 45 nil  */
3322        __(b local_label(misc_ref_invalid)) /* 46 misc  */
3323        __(b local_label(misc_ref_invalid)) /* 47 immheader  */
3324        __(b local_label(misc_ref_invalid)) /* 48 even_fixnum  */
3325        __(b local_label(misc_ref_invalid)) /* 49 cons  */
3326        __(b local_label(misc_ref_node)) /* 4a hash_vector  */
3327        __(b local_label(misc_ref_invalid)) /* 4b imm  */
3328        __(b local_label(misc_ref_invalid)) /* 4c odd_fixnum  */
3329        __(b local_label(misc_ref_invalid)) /* 4d nil  */
3330        __(b local_label(misc_ref_invalid)) /* 4e misc  */
3331        __(b local_label(misc_ref_invalid)) /* 4f immheader  */
3332        /* 50-5f  */
3333        __(b local_label(misc_ref_invalid)) /* 50 even_fixnum  */
3334        __(b local_label(misc_ref_invalid)) /* 51 cons  */
3335        __(b local_label(misc_ref_node)) /* 52 pool  */
3336        __(b local_label(misc_ref_invalid)) /* 53 imm  */
3337        __(b local_label(misc_ref_invalid)) /* 54 odd_fixnum  */
3338        __(b local_label(misc_ref_invalid)) /* 55 nil  */
3339        __(b local_label(misc_ref_invalid)) /* 56 misc  */
3340        __(b local_label(misc_ref_invalid)) /* 57 immheader  */
3341        __(b local_label(misc_ref_invalid)) /* 58 even_fixnum  */
3342        __(b local_label(misc_ref_invalid)) /* 59 cons  */
3343        __(b local_label(misc_ref_node)) /* 5a weak  */
3344        __(b local_label(misc_ref_invalid)) /* 5b imm  */
3345        __(b local_label(misc_ref_invalid)) /* 5c odd_fixnum  */
3346        __(b local_label(misc_ref_invalid)) /* 5d nil  */
3347        __(b local_label(misc_ref_invalid)) /* 5e misc  */
3348        __(b local_label(misc_ref_invalid)) /* 5f immheader  */
3349        /* 60-6f  */
3350        __(b local_label(misc_ref_invalid)) /* 60 even_fixnum  */
3351        __(b local_label(misc_ref_invalid)) /* 61 cons  */
3352        __(b local_label(misc_ref_node)) /* 62 package  */
3353        __(b local_label(misc_ref_invalid)) /* 63 imm  */
3354        __(b local_label(misc_ref_invalid)) /* 64 odd_fixnum  */
3355        __(b local_label(misc_ref_invalid)) /* 65 nil  */
3356        __(b local_label(misc_ref_invalid)) /* 66 misc  */
3357        __(b local_label(misc_ref_invalid)) /* 67 immheader  */
3358        __(b local_label(misc_ref_invalid)) /* 68 even_fixnum  */
3359        __(b local_label(misc_ref_invalid)) /* 69 cons  */
3360        __(b local_label(misc_ref_node)) /* 6a slot_vector  */
3361        __(b local_label(misc_ref_invalid)) /* 6b imm  */
3362        __(b local_label(misc_ref_invalid)) /* 6c odd_fixnum  */
3363        __(b local_label(misc_ref_invalid)) /* 6d nil  */
3364        __(b local_label(misc_ref_invalid)) /* 6e misc  */
3365        __(b local_label(misc_ref_invalid)) /* 6f immheader  */
3366        /* 70-7f  */
3367        __(b local_label(misc_ref_invalid)) /* 70 even_fixnum  */
3368        __(b local_label(misc_ref_invalid)) /* 71 cons  */
3369        __(b local_label(misc_ref_node)) /* 72 instance  */
3370        __(b local_label(misc_ref_invalid)) /* 73 imm  */
3371        __(b local_label(misc_ref_invalid)) /* 74 odd_fixnum  */
3372        __(b local_label(misc_ref_invalid)) /* 75 nil  */
3373        __(b local_label(misc_ref_invalid)) /* 76 misc  */
3374        __(b local_label(misc_ref_invalid)) /* 77 immheader  */
3375        __(b local_label(misc_ref_invalid)) /* 78 even_fixnum  */
3376        __(b local_label(misc_ref_invalid)) /* 79 cons  */
3377        __(b local_label(misc_ref_node)) /* 7a struct  */
3378        __(b local_label(misc_ref_invalid)) /* 7b imm  */
3379        __(b local_label(misc_ref_invalid)) /* 7c odd_fixnum  */
3380        __(b local_label(misc_ref_invalid)) /* 7d nil  */
3381        __(b local_label(misc_ref_invalid)) /* 7e misc  */
3382        __(b local_label(misc_ref_invalid)) /* 7f immheader  */
3383        /* 80-8f  */
3384        __(b local_label(misc_ref_invalid)) /* 80 even_fixnum  */
3385        __(b local_label(misc_ref_invalid)) /* 81 cons  */
3386        __(b local_label(misc_ref_node)) /* 82 istruct  */
3387        __(b local_label(misc_ref_invalid)) /* 83 imm  */
3388        __(b local_label(misc_ref_invalid)) /* 84 odd_fixnum  */
3389        __(b local_label(misc_ref_invalid)) /* 85 nil  */
3390        __(b local_label(misc_ref_invalid)) /* 86 misc  */
3391        __(b local_label(misc_ref_invalid)) /* 87 immheader  */
3392        __(b local_label(misc_ref_invalid)) /* 88 even_fixnum  */
3393        __(b local_label(misc_ref_invalid)) /* 89 cons  */
3394        __(b local_label(misc_ref_node)) /* 8a value_cell  */
3395        __(b local_label(misc_ref_invalid)) /* 8b imm  */
3396        __(b local_label(misc_ref_invalid)) /* 8c odd_fixnum  */
3397        __(b local_label(misc_ref_invalid)) /* 8d nil  */
3398        __(b local_label(misc_ref_invalid)) /* 8e misc  */
3399        __(b local_label(misc_ref_invalid)) /* 8f immheader  */
3400        /* 90-9f  */
3401        __(b local_label(misc_ref_invalid)) /* 90 even_fixnum  */
3402        __(b local_label(misc_ref_invalid)) /* 91 cons  */
3403        __(b local_label(misc_ref_node)) /* 92 xfunction  */
3404        __(b local_label(misc_ref_invalid)) /* 93 imm  */
3405        __(b local_label(misc_ref_invalid)) /* 94 odd_fixnum  */
3406        __(b local_label(misc_ref_invalid)) /* 95 nil  */
3407        __(b local_label(misc_ref_invalid)) /* 96 misc  */
3408        __(b local_label(misc_ref_invalid)) /* 97 immheader  */
3409        __(b local_label(misc_ref_invalid)) /* 98 even_fixnum  */
3410        __(b local_label(misc_ref_invalid)) /* 99 cons  */
3411        __(b local_label(misc_ref_node)) /* 9a arrayN  */
3412        __(b local_label(misc_ref_invalid)) /* 9b imm  */
3413        __(b local_label(misc_ref_invalid)) /* 9c odd_fixnum  */
3414        __(b local_label(misc_ref_invalid)) /* 9d nil  */
3415        __(b local_label(misc_ref_invalid)) /* 9e misc  */
3416        __(b local_label(misc_ref_invalid)) /* 9f immheader  */
3417        /* a0-af  */
3418        __(b local_label(misc_ref_invalid)) /* a0 even_fixnum  */
3419        __(b local_label(misc_ref_invalid)) /* a1 cons  */
3420        __(b local_label(misc_ref_node)) /* a2 vectorH  */
3421        __(b local_label(misc_ref_invalid)) /* a3 imm  */
3422        __(b local_label(misc_ref_invalid)) /* a4 odd_fixnum  */
3423        __(b local_label(misc_ref_invalid)) /* a5 nil  */
3424        __(b local_label(misc_ref_invalid)) /* a6 misc  */
3425        __(b local_label(misc_ref_single_float_vector)) /* a7 sf_vector  */
3426        __(b local_label(misc_ref_invalid)) /* a8 even_fixnum  */
3427        __(b local_label(misc_ref_invalid)) /* a9 cons  */
3428        __(b local_label(misc_ref_node)) /* aa simple_vector  */
3429        __(b local_label(misc_ref_invalid)) /* ab imm  */
3430        __(b local_label(misc_ref_invalid)) /* ac odd_fixnum  */
3431        __(b local_label(misc_ref_invalid)) /* ad nil  */
3432        __(b local_label(misc_ref_invalid)) /* ae misc  */
3433        __(b local_label(misc_ref_u32)) /* af u32  */
3434        /* b0-bf  */
3435        __(b local_label(misc_ref_invalid)) /* b0 even_fixnum  */
3436        __(b local_label(misc_ref_invalid)) /* b1 cons  */
3437        __(b local_label(misc_ref_invalid)) /* b2 nodeheader  */
3438        __(b local_label(misc_ref_invalid)) /* b3 imm  */
3439        __(b local_label(misc_ref_invalid)) /* b4 odd_fixnum  */
3440        __(b local_label(misc_ref_invalid)) /* b5 nil  */
3441        __(b local_label(misc_ref_invalid)) /* b6 misc  */
3442        __(b local_label(misc_ref_s32)) /* b7 s32  */
3443        __(b local_label(misc_ref_invalid)) /* b8 even_fixnum  */
3444        __(b local_label(misc_ref_invalid)) /* b9 cons  */
3445        __(b local_label(misc_ref_invalid)) /* ba nodeheader  */
3446        __(b local_label(misc_ref_invalid)) /* bb imm  */
3447        __(b local_label(misc_ref_invalid)) /* bc odd_fixnum  */
3448        __(b local_label(misc_ref_invalid)) /* bd nil  */
3449        __(b local_label(misc_ref_invalid)) /* be misc  */
3450        __(b local_label(misc_ref_fixnum_vector)) /* bf fixnum_vector  */
3451        /* c0-cf  */
3452        __(b local_label(misc_ref_invalid)) /* c0 even_fixnum  */
3453        __(b local_label(misc_ref_invalid)) /* c1 cons  */
3454        __(b local_label(misc_ref_invalid)) /* c2 nodeheader  */
3455        __(b local_label(misc_ref_invalid)) /* c3 imm  */
3456        __(b local_label(misc_ref_invalid)) /* c4 odd_fixnum  */
3457        __(b local_label(misc_ref_invalid)) /* c5 nil  */
3458        __(b local_label(misc_ref_invalid)) /* c6 misc  */
3459        __(b local_label(misc_ref_new_string)) /* c7 new_string  */
3460        __(b local_label(misc_ref_invalid)) /* c8 even_fixnum  */
3461        __(b local_label(misc_ref_invalid)) /* c9 cons  */
3462        __(b local_label(misc_ref_invalid)) /* ca nodeheader  */
3463        __(b local_label(misc_ref_invalid)) /* cb imm  */
3464        __(b local_label(misc_ref_invalid)) /* cc odd_fixnum  */
3465        __(b local_label(misc_ref_invalid)) /* cd nil  */
3466        __(b local_label(misc_ref_invalid)) /* ce misc  */
3467        __(b local_label(misc_ref_u8)) /* cf u8  */
3468        /* d0-df  */
3469        __(b local_label(misc_ref_invalid)) /* d0 even_fixnum  */
3470        __(b local_label(misc_ref_invalid)) /* d1 cons  */
3471        __(b local_label(misc_ref_invalid)) /* d2 nodeheader  */
3472        __(b local_label(misc_ref_invalid)) /* d3 imm  */
3473        __(b local_label(misc_ref_invalid)) /* d4 odd_fixnum  */
3474        __(b local_label(misc_ref_invalid)) /* d5 nil  */
3475        __(b local_label(misc_ref_invalid)) /* d6 misc  */
3476        __(b local_label(misc_ref_s8))      /* d7 s8  */
3477        __(b local_label(misc_ref_invalid)) /* d8 even_fixnum  */
3478        __(b local_label(misc_ref_invalid)) /* d9 cons  */
3479        __(b local_label(misc_ref_invalid)) /* da nodeheader  */
3480        __(b local_label(misc_ref_invalid)) /* db imm  */
3481        __(b local_label(misc_ref_invalid)) /* dc odd_fixnum  */
3482        __(b local_label(misc_ref_invalid)) /* dd nil  */
3483        __(b local_label(misc_ref_invalid)) /* de misc  */
3484        __(b local_label(misc_ref_old_string)) /* df (old)subtag_simple_base_string  */
3485        /* e0-ef  */
3486        __(b local_label(misc_ref_invalid)) /* e0 even_fixnum  */
3487        __(b local_label(misc_ref_invalid)) /* e1 cons  */
3488        __(b local_label(misc_ref_invalid)) /* e2 nodeheader  */
3489        __(b local_label(misc_ref_invalid)) /* e3 imm  */
3490        __(b local_label(misc_ref_invalid)) /* e4 odd_fixnum  */
3491        __(b local_label(misc_ref_invalid)) /* e5 nil  */
3492        __(b local_label(misc_ref_invalid)) /* e6 misc  */
3493        __(b local_label(misc_ref_u16)) /* e7 u16  */
3494        __(b local_label(misc_ref_invalid)) /* e8 even_fixnum  */
3495        __(b local_label(misc_ref_invalid)) /* e9 cons  */
3496        __(b local_label(misc_ref_invalid)) /* ea nodeheader  */
3497        __(b local_label(misc_ref_invalid)) /* eb imm  */
3498        __(b local_label(misc_ref_invalid)) /* ec odd_fixnum  */
3499        __(b local_label(misc_ref_invalid)) /* ed nil  */
3500        __(b local_label(misc_ref_invalid)) /* ee misc  */
3501        __(b local_label(misc_ref_s16)) /* ef s16  */
3502        /* f0-ff  */
3503        __(b local_label(misc_ref_invalid)) /* f0 even_fixnum  */
3504        __(b local_label(misc_ref_invalid)) /* f1 cons  */
3505        __(b local_label(misc_ref_invalid)) /* f2 nodeheader  */
3506        __(b local_label(misc_ref_invalid)) /* f3 imm  */
3507        __(b local_label(misc_ref_invalid)) /* f4 odd_fixnum  */
3508        __(b local_label(misc_ref_invalid)) /* f5 nil  */
3509        __(b local_label(misc_ref_invalid)) /* f6 misc  */
3510        __(b local_label(misc_ref_double_float_vector)) /* f7 df vector  */
3511        __(b local_label(misc_ref_invalid)) /* f8 even_fixnum  */
3512        __(b local_label(misc_ref_invalid)) /* f9 cons  */
3513        __(b local_label(misc_ref_invalid)) /* fa nodeheader  */
3514        __(b local_label(misc_ref_invalid)) /* fb imm  */
3515        __(b local_label(misc_ref_invalid)) /* fc odd_fixnum  */
3516        __(b local_label(misc_ref_invalid)) /* fd nil  */
3517        __(b local_label(misc_ref_invalid)) /* fe misc  */
3518        __(b local_label(misc_ref_bit_vector)) /* ff bit_vector  */
3519
3520local_label(misc_ref_node):       
3521        /* A node vector.  */
3522        __(add imm0,arg_z,#misc_data_offset)
3523        __(ldr  arg_z,[arg_y,imm0])
3524        __(bx lr)
3525local_label(misc_ref_single_float_vector):       
3526        __(add imm0,arg_z,misc_data_offset)
3527        __(movc16(imm1,single_float_header))
3528        __(ldr imm0,[arg_y,imm0])
3529        __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
3530        __(str imm0,[arg_z,#single_float.value])
3531        __(bx lr)
3532local_label(misc_ref_new_string):       
3533        __(add imm0,arg_z,#misc_data_offset)
3534        __(ldr imm0,[arg_y,imm0])
3535        __(mov arg_z,imm0,lsl #charcode_shift)
3536        __(orr arg_z,arg_z,#subtag_character)
3537        __(bx lr)
3538local_label(misc_ref_s32):       
3539        __(add imm0,arg_z,#misc_data_offset)
3540        __(ldr imm0,[arg_y,imm0])
3541        __(b _SPmakes32)
3542local_label(misc_ref_fixnum_vector):   
3543        __(add imm0,arg_z,#misc_data_offset)
3544        __(ldr imm0,[arg_y,imm0])
3545        __(box_fixnum(arg_z,imm0))
3546        __(bx lr)       
3547local_label(misc_ref_u32):       
3548        __(add imm0,arg_z,#misc_data_offset)
3549        __(ldr imm0,[arg_y,imm0])
3550        __(b _SPmakeu32)
3551local_label(misc_ref_double_float_vector):     
3552        __(mov imm2,arg_z,lsl #1)
3553        __(add imm2,imm2,#misc_dfloat_offset)
3554        __(ldrd imm0,imm1,[arg_y,imm2])
3555        __(movc16(imm2,double_float_header))
3556        __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
3557        __(strd imm0,imm1,[arg_z,#double_float.value])
3558        __(bx lr)
3559local_label(misc_ref_bit_vector):
3560        __(mov imm1,#nbits_in_word-1)
3561        __(and imm1,imm1,arg_z,lsr #2)
3562        __(mov imm2,#1)
3563        __(mov imm2,imm2,lsl imm1)
3564        __(mov imm0,arg_z,lsr #5+fixnumshift)
3565        __(mov imm0,imm0,lsl #2)
3566        __(add imm0,imm0,#misc_data_offset)
3567        __(mov arg_z,#0)
3568        __(ldr imm0,[arg_y,imm0])
3569        __(tst imm0,imm2)
3570        __(addne arg_z,arg_z,#fixnumone)
3571        __(bx lr)
3572local_label(misc_ref_s8):       
3573        __(mov imm0,arg_z,lsr #2)
3574        __(add imm0,imm0,#misc_data_offset)
3575        __(ldsb imm0,[arg_y,imm0])
3576        __(box_fixnum(arg_z,imm0))
3577        __(bx lr)
3578local_label(misc_ref_u8):       
3579        __(mov imm0,arg_z,lsr #2)
3580        __(add imm0,imm0,#misc_data_offset)
3581        __(ldrb imm0,[arg_y,imm0])
3582        __(box_fixnum(arg_z,imm0))
3583        __(bx lr)
3584local_label(misc_ref_old_string):         
3585        __(mov imm0,arg_z,lsr #2)
3586        __(add imm0,imm0,#misc_data_offset)
3587        __(ldrb imm0,[arg_y,imm0])
3588        __(mov arg_z,imm0,lsl #charcode_shift)
3589        __(orr arg_z,arg_z,#subtag_character)
3590        __(bx lr)
3591local_label(misc_ref_u16):       
3592        __(mov imm0,arg_z,lsr #1)     
3593        __(add imm0,imm0,#misc_data_offset)
3594        __(ldrh imm0,[arg_y,imm0])
3595        __(box_fixnum(arg_z,imm0))
3596        __(bx lr)
3597local_label(misc_ref_s16):             
3598        __(mov imm0,arg_z,lsr #1)     
3599        __(add imm0,imm0,#misc_data_offset)
3600        __(ldrsh imm0,[arg_y,imm0])
3601        __(box_fixnum(arg_z,imm0))
3602        __(bx lr)
3603local_label(misc_ref_invalid):
3604        __(mov arg_x,#XBADVEC)
3605        __(set_nargs(3))
3606        __(b _SPksignalerr)       
3607_endfn
3608       
3609_startfn(C(misc_set_common))
3610        __(add pc,pc,imm1,lsl #2)
3611        __(nop)
3612local_label(misc_set_jmp):             
3613        /* 00-0f  */
3614        __(b local_label(misc_set_invalid)) /* 00 even_fixnum  */
3615        __(b local_label(misc_set_invalid)) /* 01 cons  */
3616        __(b _SPgvset)                      /* 02 pseudofunction  */
3617        __(b local_label(misc_set_invalid)) /* 03 imm  */
3618        __(b local_label(misc_set_invalid)) /* 04 odd_fixnum  */
3619        __(b local_label(misc_set_invalid)) /* 05 nil  */
3620        __(b local_label(misc_set_invalid)) /* 06 misc  */
3621        __(b local_label(misc_set_u32)) /* 07 bignum  */
3622        __(b local_label(misc_set_invalid)) /* 08 even_fixnum  */
3623        __(b local_label(misc_set_invalid)) /* 09 cons  */
3624        __(b _SPgvset) /* 0a ratio  */
3625        __(b  local_label(misc_set_invalid)) /* 0b imm  */
3626        __(b local_label(misc_set_invalid)) /* 0c odd_fixnum  */
3627        __(b local_label(misc_set_invalid)) /* 0d nil  */
3628        __(b local_label(misc_set_invalid)) /* 0e misc  */
3629        __(b local_label(misc_set_u32)) /* 0f single_float  */
3630        /* 10-1f  */
3631        __(b local_label(misc_set_invalid)) /* 10 even_fixnum  */
3632        __(b local_label(misc_set_invalid)) /* 11 cons  */
3633        __(b local_label(misc_set_invalid)) /* 12 nodeheader  */
3634        __(b local_label(misc_set_invalid)) /* 13 imm  */
3635        __(b local_label(misc_set_invalid)) /* 14 odd_fixnum  */
3636        __(b local_label(misc_set_invalid)) /* 15 nil  */
3637        __(b local_label(misc_set_invalid)) /* 16 misc  */
3638        __(b local_label(misc_set_u32)) /* 17 double_float  */
3639        __(b local_label(misc_set_invalid)) /* 18 even_fixnum  */
3640        __(b local_label(misc_set_invalid)) /* 19 cons  */
3641        __(b _SPgvset) /* 1a complex  */
3642        __(b  local_label(misc_set_invalid)) /* 1b imm  */
3643        __(b local_label(misc_set_invalid)) /* 1c odd_fixnum  */
3644        __(b local_label(misc_set_invalid)) /* 1d nil  */
3645        __(b local_label(misc_set_invalid)) /* 1e misc  */
3646        __(b local_label(misc_set_u32)) /* 1f macptr  */
3647        /* 20-2f  */
3648        __(b local_label(misc_set_invalid)) /* 20 even_fixnum  */
3649        __(b local_label(misc_set_invalid)) /* 21 cons  */
3650        __(b _SPgvset) /* 22 catch_frame  */
3651        __(b  local_label(misc_set_invalid)) /* 23 imm  */
3652        __(b local_label(misc_set_invalid)) /* 24 odd_fixnum  */
3653        __(b local_label(misc_set_invalid)) /* 25 nil  */
3654        __(b local_label(misc_set_invalid)) /* 26 misc  */
3655        __(b local_label(misc_set_u32)) /* 27 dead_macptr  */
3656        __(b local_label(misc_set_invalid)) /* 28 even_fixnum  */
3657        __(b local_label(misc_set_invalid)) /* 29 cons  */
3658        __(b _SPgvset) /* 2a function  */
3659        __(b  local_label(misc_set_invalid)) /* 2b imm  */
3660        __(b local_label(misc_set_invalid)) /* 2c odd_fixnum  */
3661        __(b local_label(misc_set_invalid)) /* 2d nil  */
3662        __(b local_label(misc_set_invalid)) /* 2e misc  */
3663        __(b local_label(misc_set_u32)) /* 2f code_vector  */
3664        /* 30-3f  */
3665        __(b local_label(misc_set_invalid)) /* 30 even_fixnum  */
3666        __(b local_label(misc_set_invalid)) /* 31 cons  */
3667        __(b _SPgvset) /* 32 lisp_thread  */
3668        __(b  local_label(misc_set_invalid)) /* 33 imm  */
3669        __(b local_label(misc_set_invalid)) /* 34 odd_fixnum  */
3670        __(b local_label(misc_set_invalid)) /* 35 nil  */
3671        __(b local_label(misc_set_invalid)) /* 36 misc  */
3672        __(b local_label(misc_set_u32)) /* 37 creole  */
3673        __(b local_label(misc_set_invalid)) /* 38 even_fixnum  */
3674        __(b local_label(misc_set_invalid)) /* 39 cons  */
3675        __(b _SPgvset) /* 3a symbol  */
3676        __(b  local_label(misc_set_invalid)) /* 3b imm  */
3677        __(b local_label(misc_set_invalid)) /* 3c odd_fixnum  */
3678        __(b local_label(misc_set_invalid)) /* 3d nil  */
3679        __(b local_label(misc_set_invalid)) /* 3e misc  */
3680        __(b local_label(misc_set_u32)) /* 3f xcode_vector  */
3681        /* 40-4f  */
3682        __(b local_label(misc_set_invalid)) /* 40 even_fixnum  */
3683        __(b local_label(misc_set_invalid)) /* 41 cons  */
3684        __(b _SPgvset) /* 42 lock  */
3685        __(b  local_label(misc_set_invalid)) /* 43 imm  */
3686        __(b local_label(misc_set_invalid)) /* 44 odd_fixnum  */
3687        __(b local_label(misc_set_invalid)) /* 45 nil  */
3688        __(b local_label(misc_set_invalid)) /* 46 misc  */
3689        __(b local_label(misc_set_invalid)) /* 47 immheader  */
3690        __(b local_label(misc_set_invalid)) /* 48 even_fixnum  */
3691        __(b local_label(misc_set_invalid)) /* 49 cons  */
3692        __(b _SPgvset) /* 4a hash_vector  */
3693        __(b  local_label(misc_set_invalid)) /* 4b imm  */
3694        __(b local_label(misc_set_invalid)) /* 4c odd_fixnum  */
3695        __(b local_label(misc_set_invalid)) /* 4d nil  */
3696        __(b local_label(misc_set_invalid)) /* 4e misc  */
3697        __(b local_label(misc_set_invalid)) /* 4f immheader  */
3698        /* 50-5f  */
3699        __(b local_label(misc_set_invalid)) /* 50 even_fixnum  */
3700        __(b local_label(misc_set_invalid)) /* 51 cons  */
3701        __(b _SPgvset) /* 52 pool  */
3702        __(b  local_label(misc_set_invalid)) /* 53 imm  */
3703        __(b local_label(misc_set_invalid)) /* 54 odd_fixnum  */
3704        __(b local_label(misc_set_invalid)) /* 55 nil  */
3705        __(b local_label(misc_set_invalid)) /* 56 misc  */
3706        __(b local_label(misc_set_invalid)) /* 57 immheader  */
3707        __(b local_label(misc_set_invalid)) /* 58 even_fixnum  */
3708        __(b local_label(misc_set_invalid)) /* 59 cons  */
3709        __(b _SPgvset) /* 5a weak  */
3710        __(b  local_label(misc_set_invalid)) /* 5b imm  */
3711        __(b local_label(misc_set_invalid)) /* 5c odd_fixnum  */
3712        __(b local_label(misc_set_invalid)) /* 5d nil  */
3713        __(b local_label(misc_set_invalid)) /* 5e misc  */
3714        __(b local_label(misc_set_invalid)) /* 5f immheader  */
3715        /* 60-6f  */
3716        __(b local_label(misc_set_invalid)) /* 60 even_fixnum  */
3717        __(b local_label(misc_set_invalid)) /* 61 cons  */
3718        __(b _SPgvset) /* 62 package  */
3719        __(b  local_label(misc_set_invalid)) /* 63 imm  */
3720        __(b local_label(misc_set_invalid)) /* 64 odd_fixnum  */
3721        __(b local_label(misc_set_invalid)) /* 65 nil  */
3722        __(b local_label(misc_set_invalid)) /* 66 misc  */
3723        __(b local_label(misc_set_invalid)) /* 67 immheader  */
3724        __(b local_label(misc_set_invalid)) /* 68 even_fixnum  */
3725        __(b local_label(misc_set_invalid)) /* 69 cons  */
3726        __(b _SPgvset) /* 6a slot_vector  */
3727        __(b  local_label(misc_set_invalid)) /* 6b imm  */
3728        __(b local_label(misc_set_invalid)) /* 6c odd_fixnum  */
3729        __(b local_label(misc_set_invalid)) /* 6d nil  */
3730        __(b local_label(misc_set_invalid)) /* 6e misc  */
3731        __(b local_label(misc_set_invalid)) /* 6f immheader  */
3732        /* 70-7f  */
3733        __(b local_label(misc_set_invalid)) /* 70 even_fixnum  */
3734        __(b local_label(misc_set_invalid)) /* 71 cons  */
3735        __(b _SPgvset) /* 72 instance  */
3736        __(b  local_label(misc_set_invalid)) /* 73 imm  */
3737        __(b local_label(misc_set_invalid)) /* 74 odd_fixnum  */
3738        __(b local_label(misc_set_invalid)) /* 75 nil  */
3739        __(b local_label(misc_set_invalid)) /* 76 misc  */
3740        __(b local_label(misc_set_invalid)) /* 77 immheader  */
3741        __(b local_label(misc_set_invalid)) /* 78 even_fixnum  */
3742        __(b local_label(misc_set_invalid)) /* 79 cons  */
3743        __(b _SPgvset) /* 7a struct  */
3744        __(b  local_label(misc_set_invalid)) /* 7b imm  */
3745        __(b local_label(misc_set_invalid)) /* 7c odd_fixnum  */
3746        __(b local_label(misc_set_invalid)) /* 7d nil  */
3747        __(b local_label(misc_set_invalid)) /* 7e misc  */
3748        __(b local_label(misc_set_invalid)) /* 7f immheader  */
3749        /* 80-8f  */
3750        __(b local_label(misc_set_invalid)) /* 80 even_fixnum  */
3751        __(b local_label(misc_set_invalid)) /* 81 cons  */
3752        __(b _SPgvset) /* 82 istruct  */
3753        __(b  local_label(misc_set_invalid)) /* 83 imm  */
3754        __(b local_label(misc_set_invalid)) /* 84 odd_fixnum  */
3755        __(b local_label(misc_set_invalid)) /* 85 nil  */
3756        __(b local_label(misc_set_invalid)) /* 86 misc  */
3757        __(b local_label(misc_set_invalid)) /* 87 immheader  */
3758        __(b local_label(misc_set_invalid)) /* 88 even_fixnum  */
3759        __(b local_label(misc_set_invalid)) /* 89 cons  */
3760        __(b _SPgvset) /* 8a value_cell  */
3761        __(b  local_label(misc_set_invalid)) /* 8b imm  */
3762        __(b local_label(misc_set_invalid)) /* 8c odd_fixnum  */
3763        __(b local_label(misc_set_invalid)) /* 8d nil  */
3764        __(b local_label(misc_set_invalid)) /* 8e misc  */
3765        __(b local_label(misc_set_invalid)) /* 8f immheader  */
3766        /* 90-9f  */
3767        __(b local_label(misc_set_invalid)) /* 90 even_fixnum  */
3768        __(b local_label(misc_set_invalid)) /* 91 cons  */
3769        __(b _SPgvset) /* 92 xfunction  */
3770        __(b  local_label(misc_set_invalid)) /* 93 imm  */
3771        __(b local_label(misc_set_invalid)) /* 94 odd_fixnum  */
3772        __(b local_label(misc_set_invalid)) /* 95 nil  */
3773        __(b local_label(misc_set_invalid)) /* 96 misc  */
3774        __(b local_label(misc_set_invalid)) /* 97 immheader  */
3775        __(b local_label(misc_set_invalid)) /* 98 even_fixnum  */
3776        __(b local_label(misc_set_invalid)) /* 99 cons  */
3777        __(b _SPgvset) /* 9a arrayH  */
3778        __(b  local_label(misc_set_invalid)) /* 9b imm  */
3779        __(b local_label(misc_set_invalid)) /* 9c odd_fixnum  */
3780        __(b local_label(misc_set_invalid)) /* 9d nil  */
3781        __(b local_label(misc_set_invalid)) /* 9e misc  */
3782        __(b local_label(misc_set_invalid)) /* 9f immheader  */
3783        /* a0-af  */
3784        __(b local_label(misc_set_invalid)) /* a0 even_fixnum  */
3785        __(b local_label(misc_set_invalid)) /* a1 cons  */
3786        __(b _SPgvset) /* a2 vectorH  */
3787        __(b  local_label(misc_set_invalid)) /* a3 imm  */
3788        __(b local_label(misc_set_invalid)) /* a4 odd_fixnum  */
3789        __(b local_label(misc_set_invalid)) /* a5 nil  */
3790        __(b local_label(misc_set_invalid)) /* a6 misc  */
3791        __(b local_label(misc_set_single_float_vector)) /* a7 sf vector  */
3792        __(b local_label(misc_set_invalid)) /* a8 even_fixnum  */
3793        __(b local_label(misc_set_invalid)) /* a9 cons  */
3794        __(b _SPgvset) /* aa vectorH  */
3795        __(b  local_label(misc_set_invalid)) /* ab imm  */
3796        __(b local_label(misc_set_invalid)) /* ac odd_fixnum  */
3797        __(b local_label(misc_set_invalid)) /* ad nil  */
3798        __(b local_label(misc_set_invalid)) /* ae misc  */
3799        __(b local_label(misc_set_u32)) /* af u32  */
3800        /* b0-bf  */
3801        __(b local_label(misc_set_invalid)) /* b0 even_fixnum  */
3802        __(b local_label(misc_set_invalid)) /* b1 cons  */
3803        __(b local_label(misc_set_invalid)) /* b2 node  */
3804        __(b local_label(misc_set_invalid)) /* b3 imm  */
3805        __(b local_label(misc_set_invalid)) /* b4 odd_fixnum  */
3806        __(b local_label(misc_set_invalid)) /* b5 nil  */
3807        __(b local_label(misc_set_invalid)) /* b6 misc  */
3808        __(b local_label(misc_set_s32)) /* b7 s32  */
3809        __(b local_label(misc_set_invalid)) /* b8 even_fixnum  */
3810        __(b local_label(misc_set_invalid)) /* b9 cons  */
3811        __(b local_label(misc_set_invalid)) /* ba nodeheader  */
3812        __(b local_label(misc_set_invalid)) /* bb imm  */
3813        __(b local_label(misc_set_invalid)) /* bc odd_fixnum  */
3814        __(b local_label(misc_set_invalid)) /* bd nil  */
3815        __(b local_label(misc_set_invalid)) /* be misc  */
3816        __(b local_label(misc_set_fixnum_vector)) /* bf fixnum_vector  */
3817        /* c0-cf  */
3818        __(b local_label(misc_set_invalid)) /* c0 even_fixnum  */
3819        __(b local_label(misc_set_invalid)) /* c1 cons  */
3820        __(b local_label(misc_set_invalid)) /* c2 nodeheader  */
3821        __(b local_label(misc_set_invalid)) /* c3 imm  */
3822        __(b local_label(misc_set_invalid)) /* c4 odd_fixnum  */
3823        __(b local_label(misc_set_invalid)) /* c5 nil  */
3824        __(b local_label(misc_set_invalid)) /* c6 misc  */
3825        __(b local_label(misc_set_new_string)) /* c7 new_string  */
3826        __(b local_label(misc_set_invalid)) /* c8 even_fixnum  */
3827        __(b local_label(misc_set_invalid)) /* c9 cons  */
3828        __(b local_label(misc_set_invalid)) /* ca nodeheader  */
3829        __(b local_label(misc_set_invalid)) /* cb imm  */
3830        __(b local_label(misc_set_invalid)) /* cc odd_fixnum  */
3831        __(b local_label(misc_set_invalid)) /* cd nil  */
3832        __(b local_label(misc_set_invalid)) /* ce misc  */
3833        __(b local_label(misc_set_u8)) /* cf u8  */
3834        /* d0-df  */
3835        __(b local_label(misc_set_invalid)) /* d0 even_fixnum  */
3836        __(b local_label(misc_set_invalid)) /* d1 cons  */
3837        __(b local_label(misc_set_invalid)) /* d2 nodeheader  */
3838        __(b local_label(misc_set_invalid)) /* d3 imm  */
3839        __(b local_label(misc_set_invalid)) /* d4 odd_fixnum  */
3840        __(b local_label(misc_set_invalid)) /* d5 nil  */
3841        __(b local_label(misc_set_invalid)) /* d6 misc  */
3842        __(b local_label(misc_set_s8)) /* d7 s8  */
3843        __(b local_label(misc_set_invalid)) /* d8 even_fixnum  */
3844        __(b local_label(misc_set_invalid)) /* d9 cons  */
3845        __(b local_label(misc_set_invalid)) /* da nodeheader  */
3846        __(b local_label(misc_set_invalid)) /* db imm  */
3847        __(b local_label(misc_set_invalid)) /* dc odd_fixnum  */
3848        __(b local_label(misc_set_invalid)) /* dd nil  */
3849        __(b local_label(misc_set_invalid)) /* de misc  */
3850        __(b local_label(misc_set_old_string)) /* df (old) simple_base_string  */
3851        /* e0-ef  */
3852        __(b local_label(misc_set_invalid)) /* e0 even_fixnum  */
3853        __(b local_label(misc_set_invalid)) /* e1 cons  */
3854        __(b local_label(misc_set_invalid)) /* e2 nodeheader  */
3855        __(b local_label(misc_set_invalid)) /* e3 imm  */
3856        __(b local_label(misc_set_invalid)) /* e4 odd_fixnum  */
3857        __(b local_label(misc_set_invalid)) /* e5 nil  */
3858        __(b local_label(misc_set_invalid)) /* e6 misc  */
3859        __(b local_label(misc_set_u16)) /* e7 u16  */
3860        __(b local_label(misc_set_invalid)) /* e8 even_fixnum  */
3861        __(b local_label(misc_set_invalid)) /* e9 cons  */
3862        __(b local_label(misc_set_invalid)) /* ea nodeheader  */
3863        __(b local_label(misc_set_invalid)) /* eb imm  */
3864        __(b local_label(misc_set_invalid)) /* ec odd_fixnum  */
3865        __(b local_label(misc_set_invalid)) /* ed nil  */
3866        __(b local_label(misc_set_invalid)) /* ee misc  */
3867        __(b local_label(misc_set_s16)) /* ef s16  */
3868        /* f0-ff  */
3869        __(b local_label(misc_set_invalid)) /* f0 even_fixnum  */
3870        __(b local_label(misc_set_invalid)) /* f1 cons  */
3871        __(b local_label(misc_set_invalid)) /* f2 nodeheader  */
3872        __(b local_label(misc_set_invalid)) /* f3 imm  */
3873        __(b local_label(misc_set_invalid)) /* f4 odd_fixnum  */
3874        __(b local_label(misc_set_invalid)) /* f5 nil  */
3875        __(b local_label(misc_set_invalid)) /* f6 misc  */
3876        __(b local_label(misc_set_double_float_vector)) /* f7 df vector  */
3877        __(b local_label(misc_set_invalid)) /* f8 even_fixnum  */
3878        __(b local_label(misc_set_invalid)) /* f9 cons  */
3879        __(b local_label(misc_set_invalid)) /* fa nodeheader  */
3880        __(b local_label(misc_set_invalid)) /* fb imm  */
3881        __(b local_label(misc_set_invalid)) /* fc odd_fixnum  */
3882        __(b local_label(misc_set_invalid)) /* fd nil  */
3883        __(b local_label(misc_set_invalid)) /* fe misc  */
3884        __(b local_label(misc_set_bit_vector)) /* ff bit_vector  */
3885
3886local_label(misc_set_u32):       
3887        /* Either a non-negative fixnum, a positive one-digit bignum, */
3888        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
3889        __(add imm0,arg_y,#misc_data_offset)
3890        __(test_fixnum(arg_z))
3891        __(bne local_label(set_not_fixnum_u32))
3892        __(tst arg_z,#0x80000000)
3893        __(bne local_label(set_bad))
3894        __(unbox_fixnum(imm1,arg_z))
3895local_label(set_set32):         
3896        __(str imm1,[arg_x,imm0])
3897        __(bx lr)
3898local_label(set_not_fixnum_u32):
3899        __(extract_lisptag(imm1,arg_z))
3900        __(cmp imm1,#tag_misc)
3901        __(bne local_label(set_bad))
3902        __(movc16(imm2,one_digit_bignum_header))
3903        __(getvheader(imm1,arg_z))
3904        __(cmp imm1,imm2)
3905        __(bne local_label(set_not_1_digit_u32))
3906        __(ldr imm1,[arg_z,#misc_data_offset])
3907        __(cmp imm1,#0)
3908        __(bge local_label(set_set32))
3909        __(b local_label(set_bad))
3910local_label(set_not_1_digit_u32):
3911        __(movc16(imm2,two_digit_bignum_header))
3912        __(cmp imm1,imm2)
3913        __(bne local_label(set_bad))
3914        __(vrefr(imm2,arg_z,1))
3915        __(vrefr(imm1,arg_z,0))
3916        __(cmp imm2,#0)
3917        __(beq local_label(set_set32))
3918local_label(set_bad):
3919        /* arg_z does not match the array-element-type of arg_x.  */
3920        __(mov arg_y,arg_z)
3921        __(mov arg_z,arg_x)
3922        __(mov arg_x,#XNOTELT)
3923        __(set_nargs(3))
3924        __(b _SPksignalerr)
3925local_label(misc_set_fixnum_vector):   
3926        __(add imm0,arg_y,#misc_data_offset)
3927        __(test_fixnum(arg_z))
3928        __(bne local_label(set_bad))
3929        __(unbox_fixnum(imm1,arg_z))
3930        __(str imm1,[arg_x,imm0])
3931        __(bx lr)
3932local_label(misc_set_new_string):   
3933        __(add imm0,arg_y,#misc_data_offset)
3934        __(extract_lowbyte(imm2,arg_z))
3935        __(cmp imm2,#subtag_character)
3936        __(bne local_label(set_bad))
3937        __(unbox_character(imm1,arg_z))
3938        __(str imm1,[arg_x,imm0])
3939        __(bx lr)
3940local_label(misc_set_s32):
3941        __(add imm0,arg_y,#misc_data_offset)
3942        __(test_fixnum(arg_z))
3943        __(moveq imm1,arg_z,asr #fixnumshift)
3944        __(beq local_label(set_set32))
3945        __(extract_lisptag(imm2,arg_z))
3946        __(cmp imm2,#tag_misc)
3947        __(bne local_label(set_bad))
3948        __(movc16(imm1,one_digit_bignum_header))
3949        __(getvheader(imm2,arg_z))
3950        __(cmp imm2,imm1)
3951        __(vrefr(imm1,arg_z,0))
3952        __(beq local_label(set_set32))
3953        __(b local_label(set_bad))
3954local_label(misc_set_single_float_vector):
3955        __(add imm0,arg_y,#misc_data_offset)
3956        __(extract_typecode(imm2,arg_z))
3957        __(cmp imm2,#subtag_single_float)
3958        __(bne local_label(set_bad))
3959        __(ldr imm1,[arg_z,#single_float.value])
3960        __(str imm1,[arg_x,imm0])
3961        __(bx lr)
3962local_label(misc_set_u8):               
3963        __(mov imm0,arg_y,lsr #2)
3964        __(add imm0,imm0,#misc_data_offset)
3965        __(mov imm2,#~(0xff<<fixnumshift))
3966        __(tst arg_z,imm2)
3967        __(bne local_label(set_bad))
3968        __(unbox_fixnum(imm1,arg_z))
3969        __(strb imm1,[arg_x,imm0])
3970        __(bx lr)
3971local_label(misc_set_old_string):
3972        __(mov imm0,arg_y,lsr #2)
3973        __(add imm0,imm0,#misc_data_offset)
3974        __(extract_lowbyte(imm2,arg_z))
3975        __(cmp imm2,#subtag_character)
3976        __(unbox_character(imm1,arg_z))
3977        __(bne local_label(set_bad))
3978        __(strb imm1,[arg_x,imm0])
3979        __(bx lr)
3980local_label(misc_set_s8):
3981        __(mov imm0,arg_y,lsr #2)
3982        __(add imm0,imm0,#misc_data_offset)
3983        __(test_fixnum(arg_z))
3984        __(bne local_label(set_bad))
3985        __(unbox_fixnum(imm1,arg_z))
3986        __(mov imm2,imm1,lsl #32-8)
3987        __(cmp imm1,imm2,asr #32-8)
3988        __(bne local_label(set_bad))
3989        __(strb imm1,[arg_x,imm0])
3990        __(bx lr)
3991local_label(misc_set_u16):         
3992        __(mov imm0,arg_y,lsr #1)
3993        __(add imm0,imm0,#misc_data_offset)
3994        __(test_fixnum(arg_z))
3995        __(bne local_label(set_bad))
3996        __(unbox_fixnum(imm1,arg_z))
3997        __(mov imm2,imm1,lsl #16)
3998        __(cmp imm1,imm2,lsr #16)
3999        __(bne local_label(set_bad))
4000        __(strh imm1,[arg_x,imm0])
4001        __(bx lr)
4002local_label(misc_set_s16):
4003        __(mov imm0,arg_y,lsr #1)
4004        __(add imm0,imm0,#misc_data_offset)
4005        __(test_fixnum(arg_z))
4006        __(bne local_label(set_bad))
4007        __(unbox_fixnum(imm1,arg_z))
4008        __(mov imm2,imm1,lsl #16)
4009        __(cmp imm1,imm2,asr #16)
4010        __(bne local_label(set_bad))
4011        __(strh imm1,[arg_x,imm0])
4012        __(bx lr)
4013local_label(misc_set_bit_vector):
4014        __(bics imm0,arg_z,#fixnumone)
4015        __(bne local_label(set_bad))
4016        __(mov imm2,#31)
4017        __(and imm2,imm2,arg_y,lsr #2)
4018        __(mov imm1,#1)
4019        __(mov imm1,imm1,lsl imm2)
4020        __(mov imm0,arg_y,lsr #fixnumshift+5)
4021        __(mov imm0,imm0,lsl #2)
4022        __(add imm0,imm0,#misc_data_offset)
4023        __(cmp arg_z,#0)
4024        __(ldr imm2,[arg_x,imm0])
4025        __(orrne imm2,imm2,imm1)
4026        __(biceq imm2,imm2,imm1)
4027        __(str imm2,[arg_x,imm0])
4028        __(bx lr)
4029
4030local_label(misc_set_double_float_vector):
4031        __(extract_subtag(imm2,arg_z))
4032        __(cmp imm2,#subtag_double_float)
4033        __(bne local_label(set_bad))
4034        __(ldrd imm0,imm1,[arg_z,#misc_dfloat_offset])
4035        __(mov imm2,arg_y,lsl #1)
4036        __(add imm2,imm2,#misc_dfloat_offset)
4037        __(strd imm0,imm1,[arg_x,imm2])
4038        __(bx lr)
4039local_label(misc_set_invalid): 
4040        __(mov temp0,#XSETBADVEC)       
4041        __(set_nargs(4))
4042        __(vpush1(temp0))
4043        __(b _SPksignalerr)               
4044
4045       
4046/* temp0: (stack-consed) target catch frame, imm0: count of intervening  */
4047/* frames. If target isn't a multiple-value receiver, discard extra values */
4048/* (less hair, maybe.)  */
4049_startfn(C(_throw_found))
4050        new_local_labels()
4051        __(ldr imm1,[temp0,#catch_frame.mvflag])
4052        __(cmp imm1,#0)
4053        __(mov fn,#0)
4054        __(add imm1,vsp,nargs)
4055        __(add imm1,imm1,#-node_size)
4056        __(bne local_label(throw_all_values))
4057        __(cmp nargs,#0)
4058        __(moveq imm1,#nil_value)
4059        __(set_nargs(1))
4060        __(streq imm1,[vsp,#-node_size]!)
4061        __(movne vsp,imm1)
4062local_label(throw_all_values): 
4063        __(bl _SPnthrowvalues)
4064        __(ldr temp0,[rcontext,#tcr.catch_top])
4065        __(ldr imm1,[rcontext,#tcr.db_link])
4066        __(ldr imm0,[temp0,#catch_frame.db_link])
4067        __(cmp imm0,imm1)
4068        __(blne _SPunbind_to)
4069        __(ldr temp1,[temp0,#catch_frame.mvflag])
4070        __(ldr imm0,[temp0,#catch_frame.xframe])       
4071        __(ldr imm1,[temp0,#catch_frame.last_lisp_frame])
4072        __(cmp temp1,#0)
4073        __(str imm0,[rcontext,#tcr.xframe])
4074        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4075        __(add imm0,vsp,nargs)
4076        __(sub sp,temp0,#fulltag_misc)
4077        __(ldr imm1,[sp,#catch_frame.size+lisp_frame.savevsp])
4078        __(ldreq arg_z,[imm0,#-node_size])
4079        __(beq local_label(throw_pushed_values))
4080        __(movs arg_x,nargs)
4081        __(b local_label(throw_push_test))
4082local_label(throw_push_loop):
4083        __(subs arg_x,arg_x,#fixnumone)
4084        __(ldr arg_y,[imm0,#-node_size]!)
4085        __(push1(arg_y,imm1))
4086local_label(throw_push_test):   
4087        __(bne local_label(throw_push_loop))
4088local_label(throw_pushed_values):
4089        __(mov vsp,imm1)
4090        __(ldr imm0,[temp0,#catch_frame.link])
4091        __(str imm0,[rcontext,#tcr.catch_top])
4092        __(ldr fn,[sp,#catch_frame.size+lisp_frame.savefn])
4093        __(ldr lr,[sp,#catch_frame.size+lisp_frame.savelr])
4094        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4095        __(pop_lisp_fprs())
4096        __(bx lr)
4097_endfn(C(_throw_found))       
4098
4099_startfn(C(nthrow1v))
4100        new_local_labels()
4101local_label(_nthrow1v_nextframe):
4102        __(subs temp2,temp2,#fixnum_one)
4103        __(ldr temp0,[rcontext,#tcr.catch_top])
4104        __(ldr imm1,[rcontext,#tcr.db_link])
4105        __(set_nargs(1))
4106        __(blt local_label(_nthrow1v_done))
4107        __(ldr arg_y,[temp0,#catch_frame.link])
4108        __(ldr imm0,[temp0,#catch_frame.db_link])
4109        __(cmp imm0,imm1)
4110        __(str arg_y,[rcontext,#tcr.catch_top])
4111        __(ldr arg_y,[temp0,#catch_frame.xframe])
4112        __(str arg_y,[rcontext,#tcr.xframe])
4113        __(beq local_label(_nthrow1v_dont_unbind))
4114        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
4115local_label(_nthrow1v_dont_unbind):
4116        __(ldr temp1,[temp0,#catch_frame.catch_tag])
4117        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
4118        __(sub sp,temp0,#fulltag_misc)
4119        __(beq local_label(_nthrow1v_do_unwind))
4120        /* A catch frame.  If the last one, restore context from there.  */
4121        __(cmp temp2,#0)
4122        __(ldreq vsp,[sp,#catch_frame.size+lisp_frame.savevsp])
4123        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4124        __(pop_lisp_fprs())
4125        __(b local_label(_nthrow1v_nextframe))
4126local_label(_nthrow1v_do_unwind):
4127        /* This is harder, but not as hard (not as much BLTing) as the  */
4128        /* multiple-value case.  */
4129        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
4130        /* protect.  (Clever, eh ?)  */
4131        __(add sp,sp,#catch_frame.size)
4132        /* We used to use a swp instruction to exchange the lr with
4133        the lisp_frame.savelr field of the lisp frame that temp0 addresses.
4134        Multicore ARMv7 machines include the ability to disable the swp
4135        instruction, and some Linux kernels do so and emulate the instruction.
4136        There seems to be evidence that they sometimes do so incorrectly,
4137        so we stopped using swp.
4138        pc_luser_xp() needs to do some extra work if the thread is interrupted
4139        in the midst of the three-instruction sequence at
4140        swap_lr_lisp_frame_temp0.
4141        */
4142        __(mov imm1,#0)
4143        __(mov temp0,sp)
4144        __(mov imm0,#3<<num_subtag_bits)
4145        __(orr imm0,imm0,#subtag_simple_vector)
4146        __(stmdb sp!,{imm0,imm1,arg_z,temp2})
4147        .globl C(swap_lr_lisp_frame_temp0)
4148        .globl C(swap_lr_lisp_frame_temp0_end)
4149        /* This instruction sequence needs support from pc_luser_xp() */
4150C(swap_lr_lisp_frame_temp0):           
4151        __(ldr imm0,[temp0,#lisp_frame.savelr])
4152        __(str lr,[temp0,#lisp_frame.savelr])
4153        __(mov lr,imm0)
4154C(swap_lr_lisp_frame_temp0_end):           
4155        __(ldr nfn,[temp0,#lisp_frame.savefn])
4156        __(str fn,[temp0,#lisp_frame.savefn])
4157        __(ldr vsp,[temp0,#lisp_frame.savevsp])
4158        __(mov fn,nfn)
4159        __(add temp0,temp0,#lisp_frame.size)
4160        __(restore_lisp_fprs(temp0))
4161        __(str imm1,[rcontext,#tcr.unwinding])
4162        __(blx lr)
4163        __(mov imm1,#1)
4164        __(ldr arg_z,[sp,#8])
4165        __(str imm1,[rcontext,#tcr.unwinding])
4166        __(ldr temp2,[sp,#12])
4167        __(add sp,sp,#4*node_size)
4168        __(restore_lisp_frame(imm0))
4169        __(discard_lisp_fprs())
4170        __(b local_label(_nthrow1v_nextframe))
4171local_label(_nthrow1v_done):
4172        __(mov imm0,#0)
4173        __(str imm0,[rcontext,#tcr.unwinding])
4174        /* nargs has an undefined value here, so we can clobber it while */
4175        /* polling for a deferred interrupt  */
4176        __(check_pending_interrupt(nargs))
4177        __(bx lr)
4178_endfn       
4179
4180_startfn(C(nthrownv))
4181        new_local_labels()
4182local_label(nthrownv_nextframe):
4183        __(subs temp2,temp2,#fixnum_one)
4184        __(ldr temp0,[rcontext,#tcr.catch_top])
4185        __(ldr imm1,[rcontext,#tcr.db_link])
4186        __(blt local_label(nthrownv_done))
4187        __(ldr arg_y,[temp0,#catch_frame.link])
4188        __(ldr imm0,[temp0,#catch_frame.db_link])
4189        __(cmp imm0,imm1)
4190        __(str arg_y,[rcontext,#tcr.catch_top])
4191        __(ldr arg_y,[temp0,#catch_frame.xframe])
4192        __(str arg_y,[rcontext,#tcr.xframe])
4193        __(beq local_label(nthrownv_dont_unbind))
4194        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
4195local_label(nthrownv_dont_unbind):
4196        __(ldr temp1,[temp0,#catch_frame.catch_tag])
4197        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
4198        __(sub sp,temp0,#fulltag_misc)
4199        __(beq local_label(nthrownv_do_unwind))
4200        __(cmp temp2,#0)
4201/* A catch frame.  If the last one, restore context from there.  */
4202        __(bne local_label(nthrownv_skip))
4203        __(ldr imm0,[sp,#catch_frame.size+lisp_frame.savevsp])
4204        __(add imm1,vsp,nargs)
4205        __(movs arg_z,nargs)
4206        __(b local_label(nthrownv_push_test))
4207local_label(nthrownv_push_loop):       
4208        __(subs arg_z,arg_z,#fixnumone)
4209        __(ldr temp1,[imm1,#-node_size]!)
4210        __(push1(temp1,imm0))
4211local_label(nthrownv_push_test):       
4212        __(bne local_label(nthrownv_push_loop))
4213        __(mov vsp,imm0)
4214local_label(nthrownv_skip):     
4215        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4216        __(pop_lisp_fprs())         
4217        __(b local_label(nthrownv_nextframe))               
4218local_label(nthrownv_do_unwind):
4219        __(ldr arg_x,[temp0,#catch_frame.xframe])
4220        __(ldr arg_z,[temp0,#catch_frame.last_lisp_frame])
4221        __(sub sp,temp0,#fulltag_misc)
4222        __(str arg_x,[rcontext,#tcr.xframe])
4223        __(str arg_z,[rcontext,#tcr.last_lisp_frame])
4224        __(add sp,sp,#catch_frame.size)
4225        __(add imm1,nargs,#node_size)
4226        __(mov arg_z,sp)
4227        __(dnode_align(imm0,imm1,node_size))
4228        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
4229        __(orr imm1,imm1,#subtag_u32_vector)
4230        __(stack_allocate_zeroed_ivector(imm1,imm0))
4231        __(mov imm0,#subtag_simple_vector)
4232        __(strb imm0,[sp])
4233        __(str temp2,[sp,#node_size])
4234        __(add temp2,sp,#dnode_size)
4235        __(add temp2,temp2,nargs)
4236        __(add temp1,vsp,nargs)
4237        __(b local_label(nthrownv_tpushtest))
4238local_label(nthrownv_tpushloop):       
4239        __(ldr temp0,[temp1,#-node_size]!)
4240        __(push1(temp0,temp2))
4241local_label(nthrownv_tpushtest):       
4242        __(subs nargs,nargs,#fixnumone)
4243        __(bge local_label(nthrownv_tpushloop))
4244        __(mov imm1,#0)
4245        /* This instruction sequence needs support from pc_luser_xp() */
4246        .globl C(swap_lr_lisp_frame_arg_z)
4247        .globl C(swap_lr_lisp_frame_arg_z_end)
4248C(swap_lr_lisp_frame_arg_z):                   
4249        __(ldr imm0,[arg_z,#lisp_frame.savelr])
4250        __(str lr,[arg_z,#lisp_frame.savelr])
4251        __(mov lr,imm0)
4252C(swap_lr_lisp_frame_arg_z_end):                   
4253        __(ldr nfn,[arg_z,#lisp_frame.savefn])
4254        __(str fn,[arg_z,#lisp_frame.savefn])
4255        __(ldr vsp,[arg_z,#lisp_frame.savevsp])
4256        __(add arg_z,arg_z,#lisp_frame.size)
4257        __(restore_lisp_fprs(arg_z))
4258        __(str imm1,[rcontext,#tcr.unwinding])
4259        __(mov fn,nfn)
4260        __(blx lr)
4261        __(mov imm1,#1)
4262        __(str imm1,[rcontext,#tcr.unwinding])
4263        __(ldr imm0,[sp])
4264        __(header_length(imm0,imm0))
4265        __(subs nargs,imm0,#node_size)
4266        __(add imm0,imm0,#node_size)
4267        __(add temp0,sp,imm0)
4268        __(mov imm0,nargs)
4269        __(add arg_z,temp0,#node_size)
4270        __(bic arg_z,arg_z,#fulltagmask)
4271        __(b local_label(nthrownv_tpoptest))
4272local_label(nthrownv_tpoploop): 
4273        __(subs imm0,imm0,#node_size)       
4274        __(vpush1(temp2))
4275local_label(nthrownv_tpoptest): 
4276        __(ldr temp2,[temp0,#-node_size]!)
4277        __(bne local_label(nthrownv_tpoploop))
4278        __(mov sp,arg_z)
4279        __(ldr fn,[sp,#lisp_frame.savefn])
4280        __(ldr lr,[sp,#lisp_frame.savelr])
4281        __(discard_lisp_frame())
4282        __(discard_lisp_fprs())
4283        __(b local_label(nthrownv_nextframe))
4284local_label(nthrownv_done):     
4285        __(mov imm0,#0)
4286        __(str imm0,[rcontext,#tcr.unwinding])
4287        __(check_pending_interrupt(imm1))
4288        __(bx lr)
4289_endfn               
4290
4291_startfn(C(progvsave))       
4292        /* Error if arg_z isn't a proper list.  That's unlikely, */
4293        /* but it's better to check now than to crash later. */
4294        __(cmp arg_z,#nil_value)
4295        __(mov arg_x,arg_z) /* fast  */
4296        __(mov temp1,arg_z) /* slow  */
4297        __(beq 9f)  /* Null list is proper  */
42980:
4299        __(trap_unless_list(arg_x,imm0))
4300        __(_cdr(temp2,arg_x)) /* (null (cdr fast)) ?  */
4301        __(trap_unless_list(temp2,imm0,cr0))
4302        __(cmp temp2,#nil_value)
4303        __(_cdr(arg_x,temp2))
4304        __(beq 9f)
4305        __(_cdr(temp1,temp1))
4306        __(cmp arg_x,temp1)
4307        __(bne 0b)
4308        __(mov arg_y,#XIMPROPERLIST)
4309        __(set_nargs(2))
4310        __(b _SPksignalerr)
43119:      /* Whew   */
4312 
4313        /* Next, determine the length of arg_y.  We  */
4314        /* know that it's a proper list.  */
4315        __(mov imm0,#0)
4316        __(mov arg_x,arg_y)
43171:
4318        __(cmp arg_x,#nil_value)
4319        __(addne imm0,imm0,#node_size)
4320        __(_cdr(arg_x,arg_x))
4321        __(bne 1b)
4322        /* imm0 is now (boxed) triplet count.  */
4323        /* Determine word count, add 1 (to align), and make room.  */
4324        /* if count is 0, make an empty tsp frame and exit  */
4325        __(cmp imm0,#0)
4326        __(add imm1,imm0,imm0,lsl #1)
4327        __(add imm1,imm1,#node_size) /* Room for binding count */
4328        __(dnode_align(imm2,imm1,node_size))
4329        __(bne 2f)
4330        __(movc16(imm0,make_header(1,subtag_simple_vector)))
4331        __(mov imm1,#0)
4332        __(stmdb sp!,{imm0,imm1})
4333        __(b 9f)
43342:
4335        __(orr imm1,imm1,fixnumone) /* force odd */
4336        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
4337        __(orr imm1,imm1,#subtag_u32_vector)
4338        __(mov temp1,sp)
4339        __(stack_allocate_zeroed_ivector(imm1,imm2))
4340        __(mov imm1,#subtag_simple_vector)
4341        __(strb imm1,[sp])
4342        __(str imm0,[sp,#node_size])
4343        __(ldr imm1,[rcontext,#tcr.db_link])
43443:      __(_car(temp0,arg_y))
4345        __(ldr imm0,[temp0,#symbol.binding_index])
4346        __(ldr imm2,[rcontext,#tcr.tlb_limit])
4347        __(_cdr(arg_y,arg_y))
4348        __(cmp imm2,imm0)
4349        __(bhi 4f)
4350        __(uuo_tlb_too_small(al,imm0))
43514:             
4352        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
4353        __(ldr temp0,[arg_x,imm0])
4354        __(cmp arg_z,#nil_value)
4355        __(mov temp2,#unbound_marker)
4356        __(ldrne temp2,[arg_z,#cons.car])
4357        __(_cdr(arg_z,arg_z))
4358        __(cmp arg_y,#nil_value)
4359        __(push1(temp0,temp1))
4360        __(push1(imm0,temp1))
4361        __(push1(imm1,temp1))
4362        __(mov imm1,temp1)
4363        __(str temp2,[arg_x,imm0])
4364        __(bne 3b)
4365        __(str imm1,[rcontext,#tcr.db_link])
43669:             
4367        __(mov arg_z,#unbound_marker)
4368        __(mov imm2,#fixnum_one)
4369        __(mkcatch())       
4370        __(bx lr)
4371_endfn                               
4372               
4373/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
4374/* sure that there's an empty tsp frame to keep the compiler happy.  */
4375_startfn(stack_misc_alloc_no_room)
4376        __(mov imm0,#stack_alloc_marker)
4377        __(mov imm1,sp)
4378        __(stmdb sp!,{imm0,imm1})
4379        __(b _SPmisc_alloc)
4380_endfn       
4381_startfn(stack_misc_alloc_init_no_room)
4382/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
4383/* sure that there's an empty tsp frame to keep the compiler happy.  */
4384        __(mov imm0,#stack_alloc_marker)
4385        __(mov imm1,sp)
4386        __(stmdb sp!,{imm0,imm1})
4387        __(b _SPmisc_alloc_init)
4388_endfn       
4389_startfn(stack_misc_alloc_init_ivector)
4390        __(mov imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
4391        __(orr imm0,imm0,arg_y,lsr #fixnumshift)
4392        __(cmp arg_y,#max_32_bit_ivector_subtag<<fixnumshift)
4393        __(movle imm1,arg_x)
4394        __(ble 8f)
4395        __(cmp arg_y,#max_8_bit_ivector_subtag<<fixnumshift)
4396        __(movle imm1,arg_x,lsr #fixnumshift)
4397        __(ble 8f)
4398        __(cmp arg_y,#max_16_bit_ivector_subtag<<fixnumshift)
4399        __(movle imm1,arg_x,lsr #1)
4400        __(ble 8f)
4401        __(cmp arg_y,#subtag_double_float)
4402        __(moveq imm1,arg_x,lsl #1)
4403        __(addeq imm1,imm1,#node_size)
4404        __(addne imm1,arg_x,#7<<fixnumshift)
4405        __(movne imm1,imm1,lsr#3+fixnumshift)
44068:      __(dnode_align(imm1,imm1,node_size))
4407        __(ldr temp0,[rcontext,#tcr.cs_limit])
4408        __(sub temp1,sp,imm1)
4409        __(cmp temp1,temp0)
4410        __(bls stack_misc_alloc_init_no_room)
4411        __(mov temp0,#stack_alloc_marker)
4412        __(mov temp1,sp)
4413        __(stack_allocate_zeroed_ivector(imm0,imm1))
4414        __(mov arg_y,arg_z)
4415        __(add arg_z,sp,#fulltag_misc)
4416        __(stmdb sp!,{temp0,temp1})
4417        __(b initialize_vector)
4418_endfn       
4419/* This is called from a lisp-style context and calls a lisp function. */
4420/* This does the moral equivalent of */
4421/*   (loop  */
4422/*      (let* ((fn (%function_on_top_of_lisp_stack))) */
4423/*        (if fn */
4424/*           (catch %toplevel-catch% */
4425/*             (funcall fn)) */
4426/*            (return nil)))) */
4427
4428_startfn(toplevel_loop)
4429        __(build_lisp_frame(imm0))
4430        __(b local_label(test))
4431local_label(loop):
4432        __(ref_nrs_value(arg_z,toplcatch))
4433        __(bl _SPmkcatch1v)
4434        __(b local_label(test)) /* cleanup address, not really a branch */
4435        __(ldr nfn,[vsp,#0])
4436        __(set_nargs(0))
4437        __(bl _SPfuncall)
4438        __(mov arg_z,#nil_value)
4439        __(mov imm0,#fixnum_one)
4440        __(bl _SPnthrow1value)
4441local_label(test):
4442        __(ldr nfn,[vsp,#0])
4443        __(cmp nfn,#nil_value)
4444        __(bne local_label(loop))
4445        __(return_lisp_frame(imm0))
4446        _endfn
4447
4448
4449/* This gets called with R0 pointing to the current TCR. */
4450/* r1 is 0 if we want to start the whole thing rolling, */
4451/* non-zero if we want to reset the current process */
4452/* by throwing to toplevel */
4453
4454        .globl _SPreset
4455_exportfn(C(start_lisp))
4456        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4457        __(mov rcontext,r0)
4458        __(mov r0,sp)
4459        __(tst sp,#4)
4460        __(strne r0,[sp,#-4]!)
4461        __(streq r0,[sp,#-8]!)
4462        __(mov arg_z,#0)
4463        __(mov arg_y,#0)
4464        __(mov arg_x,#0)
4465        __(mov temp0,#0)
4466        __(mov temp1,#0)
4467        __(mov temp2,#0)
4468        __(mov allocptr,#VOID_ALLOCPTR)
4469        __(mov fn,#0)
4470        __(ldr vsp,[rcontext,#tcr.save_vsp])
4471        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
4472        __(sub imm0,imm2,sp)
4473        __(add imm0,imm0,#node_size)
4474        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
4475        __(orr imm0,imm0,#subtag_u32_vector)
4476        __(stmdb sp!,{imm0,imm2})
4477        __(push_foreign_fprs())
4478        __(adr imm0,1f)
4479        __(fldd double_float_zero,[imm0])
4480        __(mov imm0,#TCR_STATE_LISP)
4481        __(str imm0,[rcontext,#tcr.valence])
4482        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
4483        __(bl toplevel_loop)
4484        __(ldr imm1,[sp,#(9*8)+4])
4485        __(mov imm0,#TCR_STATE_FOREIGN)
4486        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4487        __(str imm0,[rcontext,#tcr.valence])
4488        __(pop_foreign_fprs())
4489        __(add sp,sp,#2*node_size)
4490        __(mov imm0,#nil_value)
4491        __(ldr sp,[sp])
4492        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4493        __(bx lr)
4494_endfn
4495       
4496        .align 3
44971:
4498        .long 0
4499        .long 0
4500
4501/* This gets called with r0 = the current thread's TCR.  Should
4502   call RESTORE-LISP-POINTERS and return 0 if it returns normally
4503   and non-0 if it throws. */
4504       
4505_exportfn(C(init_lisp))
4506        new_local_labels()
4507        new_macro_labels()
4508        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4509        __(mov rcontext,r0)
4510        __(mov r0,sp)
4511        __(tst sp,#4)
4512        __(strne r0,[sp,#-4]!)
4513        __(streq r0,[sp,#-8]!)
4514        __(mov arg_z,#0)
4515        __(mov arg_y,#0)
4516        __(mov arg_x,#0)
4517        __(mov temp0,#0)
4518        __(mov temp1,#0)
4519        __(mov temp2,#0)
4520        __(mov allocptr,#VOID_ALLOCPTR)
4521        __(mov fn,#0)
4522        __(ldr vsp,[rcontext,#tcr.save_vsp])
4523        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
4524        __(sub imm0,imm2,sp)
4525        __(add imm0,imm0,#node_size)
4526        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
4527        __(orr imm0,imm0,#subtag_u32_vector)
4528        __(stmdb sp!,{imm0,imm2})
4529        __(push_foreign_fprs())
4530        __(adr imm0,1b)
4531        __(fldd double_float_zero,[imm0])
4532        __(mov imm0,#TCR_STATE_LISP)
4533        __(str imm0,[rcontext,#tcr.valence])
4534        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
4535        __(ref_nrs_function(nfn,restore_lisp_pointers))
4536        __(extract_subtag(imm0,nfn))
4537        __(cmp imm0,#subtag_function)
4538        __(bne local_label(fail))
4539        __(ref_nrs_value(arg_z,toplcatch))
4540        __(bl _SPmkcatch1v)
4541        __(b local_label(fail)) /* cleanup address */
4542        __(ref_nrs_function(nfn,restore_lisp_pointers))
4543        __(set_nargs(0))
4544        __(bl _SPfuncall)
4545        __(mov arg_z,#0)
4546        __(mov imm0,#fixnum_one)
4547        __(bl _SPnthrow1value)
4548        __(b local_label(done))
4549local_label(fail):     
4550        __(mov arg_z,#fixnum_one)
4551local_label(done):                     
4552        __(ldr imm1,[sp,#(9*8)+4])
4553        __(mov imm0,#TCR_STATE_FOREIGN)
4554        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4555        __(str imm0,[rcontext,#tcr.valence])
4556        __(pop_foreign_fprs())
4557        __(add sp,sp,#2*node_size)
4558        __(unbox_fixnum(imm0,arg_z))
4559        __(ldr sp,[sp])
4560        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4561        __(bx lr)
4562_endfn
4563
4564/* Called (on something other than the initial thread) with r0=tcr,
4565   r1 = a (void *) arg.  Returns a null pointer/0, but declared to return
4566   void.
4567*/               
4568_exportfn(C(os_main))
4569        new_local_labels()
4570        new_macro_labels()
4571        __(stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4572        __(mov rcontext,r0)
4573        __(mov r0,sp)
4574        __(tst sp,#4)
4575        __(strne r0,[sp,#-4]!)
4576        __(streq r0,[sp,#-8]!)
4577        __(mov arg_z,#0)
4578        __(mov arg_y,#0)
4579        __(mov arg_x,#0)
4580        __(mov temp0,#0)
4581        __(mov temp1,#0)
4582        __(mov temp2,#0)
4583        __(mov allocptr,#VOID_ALLOCPTR)
4584        __(mov fn,#0)
4585        __(ldr vsp,[rcontext,#tcr.save_vsp])
4586        __(ldr imm2,[rcontext,#tcr.last_lisp_frame])
4587        __(sub imm0,imm2,sp)
4588        __(add imm0,imm0,#node_size)
4589        __(mov imm0,imm0,lsl #num_subtag_bits-word_shift)
4590        __(orr imm0,imm0,#subtag_u32_vector)
4591        __(stmdb sp!,{imm0,imm2})
4592        __(push_foreign_fprs())
4593        __(adr imm0,1b)
4594        __(fldd double_float_zero,[imm0])
4595        __(mov imm0,#TCR_STATE_LISP)
4596        __(str imm0,[rcontext,#tcr.valence])
4597        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
4598        __(movc16(imm0,make_header(macptr.element_count,subtag_macptr)))
4599        __(stmdb sp!,{imm0,imm1,arg_z,arg_y})
4600        __(add arg_z,sp,#fulltag_misc)
4601        __(ref_nrs_function(nfn,os_init_function))
4602        __(set_nargs(1))
4603        __(bl _SPfuncall)
4604        __(add sp,sp,#16)
4605        __(ldr imm1,[sp,#(9*8)+4])
4606        __(mov imm0,#TCR_STATE_FOREIGN)
4607        __(str imm1,[rcontext,#tcr.last_lisp_frame])
4608        __(str imm0,[rcontext,#tcr.valence])
4609        __(pop_foreign_fprs())
4610        __(add sp,sp,#2*node_size)
4611        __(mov imm0,#nil_value)
4612        __(ldr sp,[sp])
4613        __(ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr})
4614        __(bx lr)
4615_endfn
4616                               
4617        .data
4618        .globl C(sptab)
4619        .globl C(sptab_end)
4620        new_local_labels()
4621C(sptab):
4622        .long local_label(start)
4623C(sptab_end):   
4624        .long local_label(end)
4625local_label(start):                     
4626        .long _SPfix_nfn_entrypoint /* must be first */
4627        .long _SPbuiltin_plus
4628        .long _SPbuiltin_minus
4629        .long _SPbuiltin_times
4630        .long _SPbuiltin_div
4631        .long _SPbuiltin_eq
4632        .long _SPbuiltin_ne
4633        .long _SPbuiltin_gt
4634        .long _SPbuiltin_ge
4635        .long _SPbuiltin_lt
4636        .long _SPbuiltin_le
4637        .long _SPbuiltin_eql
4638        .long _SPbuiltin_length
4639        .long _SPbuiltin_seqtype
4640        .long _SPbuiltin_assq
4641        .long _SPbuiltin_memq
4642        .long _SPbuiltin_logbitp
4643        .long _SPbuiltin_logior
4644        .long _SPbuiltin_logand
4645        .long _SPbuiltin_ash
4646        .long _SPbuiltin_negate
4647        .long _SPbuiltin_logxor
4648        .long _SPbuiltin_aref1
4649        .long _SPbuiltin_aset1
4650        .long _SPfuncall
4651        .long _SPmkcatch1v
4652        .long _SPmkcatchmv
4653        .long _SPmkunwind
4654        .long _SPbind
4655        .long _SPconslist
4656        .long _SPconslist_star
4657        .long _SPmakes32
4658        .long _SPmakeu32
4659        .long _SPfix_overflow
4660        .long _SPmakeu64
4661        .long _SPmakes64
4662        .long _SPmvpass
4663        .long _SPvalues
4664        .long _SPnvalret
4665        .long _SPthrow
4666        .long _SPnthrowvalues
4667        .long _SPnthrow1value
4668        .long _SPbind_self
4669        .long _SPbind_nil
4670        .long _SPbind_self_boundp_check
4671        .long _SPrplaca
4672        .long _SPrplacd
4673        .long _SPgvset
4674        .long _SPset_hash_key
4675        .long _SPstore_node_conditional
4676        .long _SPset_hash_key_conditional
4677        .long _SPstkconslist
4678        .long _SPstkconslist_star
4679        .long _SPmkstackv
4680        .long _SPsetqsym
4681        .long _SPprogvsave
4682        .long _SPstack_misc_alloc
4683        .long _SPgvector
4684        .long _SPfitvals
4685        .long _SPnthvalue
4686        .long _SPdefault_optional_args
4687        .long _SPopt_supplied_p
4688        .long _SPheap_rest_arg
4689        .long _SPreq_heap_rest_arg
4690        .long _SPheap_cons_rest_arg
4691        .long _SPcheck_fpu_exception
4692        .long _SPdiscard_stack_object
4693        .long _SPksignalerr
4694        .long _SPstack_rest_arg
4695        .long _SPreq_stack_rest_arg
4696        .long _SPstack_cons_rest_arg
4697        .long _SPcall_closure       
4698        .long _SPspreadargz
4699        .long _SPtfuncallgen
4700        .long _SPtfuncallslide
4701        .long _SPjmpsym
4702        .long _SPtcallsymgen
4703        .long _SPtcallsymslide
4704        .long _SPtcallnfngen
4705        .long _SPtcallnfnslide
4706        .long _SPmisc_ref
4707        .long _SPsubtag_misc_ref
4708        .long _SPmakestackblock
4709        .long _SPmakestackblock0
4710        .long _SPmakestacklist
4711        .long _SPstkgvector
4712        .long _SPmisc_alloc
4713        .long _SPatomic_incf_node
4714        .long _SPunused1
4715        .long _SPunused2
4716        .long _SPrecover_values
4717        .long _SPinteger_sign
4718        .long _SPsubtag_misc_set
4719        .long _SPmisc_set
4720        .long _SPspread_lexprz
4721        .long _SPreset
4722        .long _SPmvslide
4723        .long _SPsave_values
4724        .long _SPadd_values
4725        .long _SPmisc_alloc_init
4726        .long _SPstack_misc_alloc_init
4727        .long _SPpopj
4728        .long _SPudiv64by32
4729        .long _SPgetu64
4730        .long _SPgets64
4731        .long _SPspecref
4732        .long _SPspecrefcheck
4733        .long _SPspecset
4734        .long _SPgets32
4735        .long _SPgetu32
4736        .long _SPmvpasssym
4737        .long _SPunbind
4738        .long _SPunbind_n
4739        .long _SPunbind_to
4740        .long _SPprogvrestore
4741        .long _SPbind_interrupt_level_0
4742        .long _SPbind_interrupt_level_m1
4743        .long _SPbind_interrupt_level
4744        .long _SPunbind_interrupt_level
4745        .long _SParef2
4746        .long _SParef3
4747        .long _SPaset2
4748        .long _SPaset3
4749        .long _SPkeyword_bind
4750        .long _SPudiv32
4751        .long _SPsdiv32
4752        .long _SPeabi_ff_call
4753        .long _SPdebind
4754        .long _SPeabi_callback
4755        .long _SPeabi_ff_callhf
4756local_label(end):       
4757                _endfile
Note: See TracBrowser for help on using the repository browser.