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

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

ARM-specific changes, mostly.

When running lisp code (in almost all cases), keep the constant 0.0d0
in the d7 register (and therefore 0.0s0 in s14 and s15). We use d7 as
a vector header when saving non-volatile FPRs on the stack; we
actually only modify s14, so we now restore s14 after it's been used
this way. The value used in the header in lisp and kernel code is
loaded from PC-relative memory, which means that we no longer use
fmsr/fmdrr or similar instructions.

When starting a lisp thread or entering one via a callback, initialize
d7.

This all basically means that we can get 0.0[d|s]0 into an FPR (or
exploit the fact that it's already in one) a bit easier, and that's
generally a good thing. It's an ABI change, which means that the
FASL and image versions (for the ARM port only) changed; new binaries
are included in this commit.

The kernel changes to support the use of d7 are mostly pretty obvious.
In working on them, I noticed that "local labels" and "macro labels"
were in the same namespace, and we were only avoiding conflicts by
accident. For 10 years or so. (I also noticed that GAS doesn't fully
support PC-relative operands, so did that by hand.)

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