source: branches/arm/lisp-kernel/arm-spentry.s @ 13849

Last change on this file since 13849 was 13849, checked in by gb, 10 years ago

Write barrier comparisons of value/location were all backwards.
_SPstack_cons_rest_arg: get list length (in temp0) right.

File size: 144.1 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):
24        .set delta,256
25        .set spnum,0
26        .set sporg,0
27define(`_spentry',`ifdef(`__func_name',`_endfn',`')
28        .org sporg
29        .set sporg,sporg+delta
30        .set spnum,spnum+1
31        .if spnum >= 112
32        .set delta,1024
33        .endif
34        _exportfn(_SP$1)
35        .line  __line__
36')
37
38
39define(`_endsubp',`
40        _endfn(_SP$1)
41# __line__
42')
43
44
45       
46
47define(`jump_builtin',`
48        ref_nrs_value(fname,builtin_functions)
49        set_nargs($2)
50        vrefr(fname,fname,$1)
51        jump_fname()
52')
53
54/* Set the _function.entrypoint locative in nfn - which pointed here -
55   to the address of the first instruction in the _function.codevector.
56   This must be the first ARM subprim. */
57
58_spentry(fix_nfn_entrypoint)
59        __(build_lisp_frame(imm0))
60        __(vpush1(arg_z))
61        __(ldr arg_z,[nfn,#_function.codevector])
62        __(add lr,arg_z,#misc_data_offset)
63        __(str lr,[nfn,#_function.entrypoint])
64        __(vpop1(arg_z))
65        __(restore_lisp_frame(imm0))
66        __(jump_nfn())
67       
68_spentry(builtin_plus)
69        __(test_two_fixnums(arg_y,arg_z,imm0))
70        __(bne 1f)
71        __(adds arg_z,arg_y,arg_z)
72        __(bxvc lr)
73        __(b _SPfix_overflow)
741:
75        __(jump_builtin(_builtin_plus,2))
76       
77_spentry(builtin_minus)
78        __(test_two_fixnums(arg_y,arg_z,imm0))
79        __(bne 1f)
80        __(subs arg_z,arg_y,arg_z)
81        __(bxvc lr)
82        __(b _SPfix_overflow)
831:
84        __(jump_builtin(_builtin_minus,2))
85
86_spentry(builtin_times)
87        __(test_two_fixnums(arg_y,arg_z,imm0))
88        __(bne 1f)
89        __(unbox_fixnum(imm2,arg_z))
90        __(unbox_fixnum(imm0,arg_y))
91        __(smull imm0,imm1,imm2,imm0)
92        __(b _SPmakes64)
93
941: __(jump_builtin(_builtin_times,2))
95
96_spentry(builtin_div)
97        __(jump_builtin(_builtin_div,2))
98
99_spentry(builtin_eq)
100        __(test_two_fixnums(arg_y,arg_z,imm0))
101        __(bne 1f)
102        __(cmp arg_y,arg_z)
103        __(mov arg_z,#nil_value)
104        __(addeq arg_z,arg_z,#t_offset)
105        __(bx lr)       
1061:
107        __(jump_builtin(_builtin_eq,2))
108                       
109_spentry(builtin_ne)
110        __(test_two_fixnums(arg_y,arg_z,imm0))
111        __(bne 1f)
112        __(cmp arg_y,arg_z)
113        __(mov arg_z,#nil_value)
114        __(addne arg_z,arg_z,#t_offset)
115        __(bx lr)
1161:
117        __(jump_builtin(_builtin_ne,2))
118
119_spentry(builtin_gt)
120        __(test_two_fixnums(arg_y,arg_z,imm0))
121        __(bne 1f)
122        __(cmp arg_y,arg_z)
123        __(mov arg_z,#nil_value)
124        __(addgt arg_z,arg_z,#t_offset)
125        __(bx lr)
1261:
127        __(jump_builtin(_builtin_gt,2))
128
129_spentry(builtin_ge)
130        __(test_two_fixnums(arg_y,arg_z,imm0))
131        __(bne 1f)
132        __(cmp arg_y,arg_z)
133        __(mov arg_z,#nil_value)
134        __(addge arg_z,arg_z,#t_offset)
135        __(bx lr)
1361:
137        __(jump_builtin(_builtin_ge,2))
138
139_spentry(builtin_lt)
140        __(test_two_fixnums(arg_y,arg_z,imm0))
141        __(bne 1f)
142        __(cmp arg_y,arg_z)
143        __(mov arg_z,#nil_value)
144        __(addgt arg_z,arg_z,#t_offset)
145        __(bx lr)
1461:
147        __(jump_builtin(_builtin_lt,2))
148
149_spentry(builtin_le)
150        __(test_two_fixnums(arg_y,arg_z,imm0))
151        __(bne 1f)
152        __(cmp arg_y,arg_z)
153        __(mov arg_z,#nil_value)
154        __(addle arg_z,arg_z,#t_offset)
155        __(bx lr)
1561:
157        __(jump_builtin(_builtin_le,2))
158
159_spentry(builtin_eql)
160        __(cmp arg_y,arg_z)
161        __(beq 1f)
162        __(extract_fulltag(imm0,arg_y))
163        __(extract_fulltag(imm1,arg_z))
164        __(cmp imm0,imm1)
165        __(bne 2f)
166        __(cmp imm0,#fulltag_misc)
167        __(bne 2f)
168        __(jump_builtin(_builtin_eql,2))
1691:      __(mov arg_z,#nil_value)
170        __(add arg_z,arg_z,#t_offset)
171        __(bx lr)
1722:      __(mov arg_z,#nil_value)
173        __(bx lr)
174       
175_spentry(builtin_length)
176        __(extract_typecode(imm0,arg_z))
177        __(cmp imm0,#min_vector_subtag)
178        __(ldreq arg_z,[arg_z,#vectorH.logsize])
179        __(bxeq lr)
180        __(blo 1f)
181        __(vector_length(arg_z,arg_z,imm0))
182        __(bx lr)
1831:      __(cmp imm0,#tag_list)
184        __(bne 8f)
185        __(mov temp2,#-1<<fixnum_shift)
186        __(mov temp0,arg_z) /* fast pointer  */
187        __(mov temp1,arg_z) /* slow pointer  */
1882:      __(cmp temp0,#nil_value)
189        __(add temp2,temp2,#fixnumone)
190        __(beq 9f)
191        __(extract_lisptag(imm0,temp0))
192        __(cmp imm0,#tag_list)
193        __(bne 8f)
194        __(_cdr(temp0,temp0))
195        __(tst temp2,#fixnumone)
196        __(beq 2b)
197        __(_cdr(temp1,temp1))
198        __(cmp temp1,temp0)
199        __(bne 2b)
2008:
201        __(jump_builtin(_builtin_length,1))
2029:      __(mov arg_z,temp2)
203        __(bx lr)       
204
205_spentry(builtin_seqtype)
206        __(extract_typecode(imm0,arg_z))
207        __(cmp imm0,#min_vector_subtag)
208        __(movge arg_z,#nil_value)
209        __(bxge lr)
210        __(cmp imm0,#tag_list)
211        __(moveq arg_z,#nil_value)
212        __(addeq arg_z,arg_z,#t_offset)
213        __(bxeq lr)
214        __(jump_builtin(_builtin_seqtype,1))
215
216/* This is usually inlined these days */
217_spentry(builtin_assq)
218        __(b 2f)
2191:      __(trap_unless_list(arg_z,imm0))
220        __(_car(arg_x,arg_z))
221        __(_cdr(arg_z,arg_z))
222        __(cmp arg_x,#nil_value)
223        __(beq 2f)
224        __(trap_unless_list(arg_x,imm0))
225        __(_car(temp0,arg_x))
226        __(cmp temp0,arg_y)
227        __(bne 2f)
228        __(mov arg_z,arg_x)
229        __(bx lr)
2302:      __(cmp arg_z,#nil_value)
231        __(bne 1b)
232        __(bx lr)
233 
234_spentry(builtin_memq)
235        __(cmp arg_z,nil_value)
236        __(b 2f)
2371:      __(trap_unless_list(arg_z,imm0))
238        __(_car(arg_x,arg_z))
239        __(_cdr(temp0,arg_z))
240        __(cmp arg_x,arg_y)
241        __(bxeq lr)
242        __(cmp temp0,nil_value)
243        __(mov arg_z,temp0)
2442:      __(bne 1b)
245        __(bx lr)
246
247_spentry(builtin_logbitp)
248/* Call out unless both fixnums,0 <=  arg_y < logbitp_max_bit  */
249        __(test_two_fixnums(arg_y,arg_z,imm0))
250        __(bne 1f)
251        __(cmp arg_y,#(nbits_in_word-fixnumshift)<<fixnumshift)
252        __(bhs 1f)
253        __(unbox_fixnum(imm0,arg_y))
254        __(mov imm1,#fixnum1)
255        __(tst arg_z,imm1,lsl imm0)
256        __(mov arg_z,#nil_value)
257        __(addne arg_z,arg_z,#t_offset)
258        __(bx lr)
2591:
260        __(jump_builtin(_builtin_logbitp,2))
261
262_spentry(builtin_logior)
263        __(orr imm0,arg_y,arg_z)
264        __(test_fixnum(imm0))
265        __(moveq arg_z,imm0)
266        __(bxeq lr)
267        __(jump_builtin(_builtin_logior,2))
268
269_spentry(builtin_logand)
270        __(test_two_fixnums(arg_y,arg_z,imm0))
271        __(andeq arg_z,arg_y,arg_z)
272        __(bxeq lr)
273        __(jump_builtin(_builtin_logand,2))
274         
275_spentry(builtin_ash)
276        __(test_two_fixnums(arg_y,arg_z,imm0))
277        __(bne 9f)
278        __(cmp arg_z,#0)
279        __(bgt 1f)
280        __(moveq arg_z,arg_y)
281        __(bxeq lr)
282        /* Shift right */
283        __(unbox_fixnum(imm2,arg_z))
284        __(rsb imm2,imm2,#0)
285        __(cmp imm2,#32)
286        __(movge imm2,#31)
287        __(mov arg_z,#-fixnumone)
288        __(and arg_z,arg_z,arg_y,lsr imm2)
289        __(bx lr)
290        /* shift left */
2911:      __(unbox_fixnum(imm0,arg_y))
292        __(unbox_fixnum(imm2,arg_z))
293        __(cmp imm2,#32)
294        __(moveq imm1,imm0)
295        __(moveq imm0,#0)
296        __(beq _SPmakes64)
297        __(bgt 9f)
298        __(rsb imm1,imm2,#32)
299        __(mov imm1,imm0,asr imm1)
300        __(mov imm0,imm0,lsl imm2)
301        __(b _SPmakes64)
3029: 
303        __(jump_builtin(_builtin_ash,2))
304                                       
305_spentry(builtin_negate)
306        __(test_fixnum(arg_z))
307        __(bne 1f)
308        __(rsbs arg_z,arg_z,#0)
309        __(bxvc lr)
310        __(b _SPfix_overflow)
3111:
312        __(jump_builtin(_builtin_negate,1))
313 
314_spentry(builtin_logxor)
315        __(test_two_fixnums(arg_y,arg_z,imm0))
316        __(eoreq arg_z,arg_y,arg_z)
317        __(bxeq lr)
318        __(jump_builtin(_builtin_logxor,2))
319
320_spentry(builtin_aref1)
321        __(extract_typecode(imm0,arg_y))
322        __(cmp imm0,#min_vector_subtag)
323        __(box_fixnum(arg_x,imm0))
324        __(bgt _SPsubtag_misc_ref)
325        __(jump_builtin(_builtin_aref1,2))
326
327_spentry(builtin_aset1)
328        __(extract_typecode(imm0,arg_x))
329        __(cmp imm0,#min_vector_subtag)
330        __(box_fixnum(temp0,imm0))
331        __(bgt _SPsubtag_misc_set)
332        __(jump_builtin(_builtin_aset1,3))
333                       
334
335        /*  Call nfn if it's either a symbol or function */
336_spentry(funcall)
337        __(funcall_nfn())
338
339/* Subprims for catch, throw, unwind_protect.  */
340
341
342_spentry(mkcatch1v)
343        __(mov imm2,#0)
344        __(mkcatch())
345        __(bx lr)
346
347
348_spentry(mkcatchmv)
349        __(mov imm2,#fixnum_one)
350        __(mkcatch())
351        __(bx lr)
352
353_spentry(mkunwind)
354        __(mov imm2,#-fixnumone)
355        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
356        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
357        __(ldr arg_y,[temp0,#INTERRUPT_LEVEL_BINDING_INDEX])
358        __(ldr imm0,[rcontext,#tcr.db_link])
359        __(vpush1(arg_y))
360        __(vpush1(imm1))
361        __(vpush1(imm0))
362        __(str imm2,[temp0,#INTERRUPT_LEVEL_BINDING_INDEX])
363        __(str vsp,[rcontext,#tcr.db_link])
364        __(mov arg_z,#unbound_marker)
365        __(mov imm2,#fixnum_one)
366        __(mkcatch())
367        __(mov arg_z,arg_y)
368        __(b _SPbind_interrupt_level)
369       
370
371/* This never affects the symbol's vcell  */
372/* Non-null symbol in arg_y, new value in arg_z          */
373_spentry(bind)
374        __(ldr imm1,[arg_y,#symbol.binding_index])
375        __(ldr imm0,[rcontext,#tcr.tlb_limit])
376        __(cmp imm0,imm1)
377        __(uuo_tlb_too_small(ls,imm1))
378        __(cmp imm1,#0)
379        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
380        __(ldr imm0,[rcontext,#tcr.db_link])
381        __(ldr temp1,[imm2,imm0])
382        __(beq 9f)
383        __(vpush1(temp1))
384        __(vpush1(imm1))
385        __(vpush1(imm0))
386        __(str arg_z,[imm2,imm1])
387        __(str vsp,[rcontext,#tcr.db_link])
388        __(bx lr)
3899:
390        __(mov arg_z,arg_y)
391        __(mov arg_y,#XSYMNOBIND)
392        __(set_nargs(2))
393        __(b _SPksignalerr)
394
395_spentry(conslist)
396        __(mov arg_z,#nil_value)
397        __(cmp nargs,#0)
398        __(b 2f)
3991:
400        __(vpop1(arg_y))
401        __(Cons(arg_z,arg_z,arg_z))
402        __(subs nargs,nargs,#fixnum_one)
4032:
404        __(bne 1b)
405        __(bx lr)
406
407/* do list*: last arg in arg_z, all others vpushed, nargs set to #args vpushed.  */
408/* Cons, one cons cell at at time.  Maybe optimize this later.  */
409
410_spentry(conslist_star)
411        __(cmp nargs,#0)
412        __(b 2f)
4131:
414        __(vpop1(arg_y))
415        __(Cons(arg_z,arg_y,arg_z))
416        __(subs nargs,nargs,fixnum_one)
4172:
418        __(bne 1b)
419        __(bx lr)
420
421_spentry(makes32)
422        __(adds imm1,imm0,imm0)
423        __(addsvc arg_z,imm1,imm1)
424        __(bxvc lr)
425        __(movc16(imm1,one_digit_bignum_header))
426        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
427        __(str imm0,[arg_z,#misc_data_offset])
428        __(bx lr)
429
430/* Construct a lisp integer out of the 32-bit unsigned value in imm0 */
431
432
433_spentry(makeu32)
434        __(tst imm0,#0xe0000000)
435        __(box_fixnum(arg_z,imm0))
436        __(bxeq lr)
437        __(tst imm0,#0x80000000)
438        __(bne 2f)
439        __(movc16(imm1,one_digit_bignum_header))
440        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(1)))
441        __(str imm0,[arg_z,#misc_data_offset])
442        __(bx lr)
4432:             
444        __(movc16(imm1,two_digit_bignum_header))
445        __(Misc_Alloc_Fixed(arg_z,imm1,aligned_bignum_size(2)))
446        __(str imm0,[arg_z,#misc_data_offset])
447        __(bx lr)
448
449
450/* arg_z has overflowed (by one bit) as the result of an addition or
451   subtraction. */
452/* Make a bignum out of it. */
453
454_spentry(fix_overflow)
455        __(unbox_fixnum(imm0,arg_z))
456        __(eor imm0,imm0,#0xc0000000)
457        __(b _SPmakes32)
458
459
460
461/*  Construct a lisp integer out of the 64-bit unsigned value in */
462/*           imm0 (low 32 bits) and imm1 (high 32 bits) */
463       
464_spentry(makeu64)
465        __(cmp imm1,#0)
466        __(beq _SPmakeu32)
467        __(blt 3f)
468        __(movc16(imm2,two_digit_bignum_header))
469        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
470        __(str imm0,[arg_z,#misc_data_offset])
471        __(str imm1,[arg_z,#misc_data_offset+4])
472        __(bx lr)
4733:             
474        __(movc16(imm2,three_digit_bignum_header))
475        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(3)))
476        __(str imm0,[arg_z,#misc_data_offset])
477        __(str imm1,[arg_z,#misc_data_offset+4])
478        __(bx lr)
479
480/*  Construct a lisp integer out of the 64-bit signed value in */
481/*        imm0 (low 32 bits) and imm1 (high 32 bits). */
482_spentry(makes64)
483        __(cmp imm1,imm0,asr #31) /* is imm1 sign extension of imm0 ? */
484        __(beq _SPmakes32)        /* forget imm1 if so */
485        __(movc16(imm2,two_digit_bignum_header))
486        __(Misc_Alloc_Fixed(arg_z,imm2,aligned_bignum_size(2)))
487        __(str imm0,[arg_z,#misc_data_offset])
488        __(str imm1,[arg_z,#misc_data_offset+4])
489        __(bx lr)
490
491
492
493
494
495
496/* funcall nfn, returning multiple values if it does.  */
497_spentry(mvpass)
498        __(cmp nargs,#node_size*nargregs)
499        __(mov imm1,vsp)
500        __(subgt imm1,imm1,#node_size*nargregs)
501        __(addgt imm1,imm1,nargs)
502        __(build_lisp_frame(imm0,imm1))
503        __(adr lr,C(ret1valn))
504        __(mov fn,#0)
505        __(funcall_nfn())
506
507/* ret1valn returns "1 multiple value" when a called function does not  */
508/* return multiple values.  Its presence on the stack (as a return address)  */
509/* identifies the stack frame to code which returns multiple values.  */
510
511_exportfn(C(ret1valn))
512        __(restore_lisp_frame(imm0))
513        __(vpush1(arg_z))
514        __(set_nargs(1))
515        __(bx lr)
516
517/* Come here to return multiple values when  */
518/* the caller's context isn't saved in a lisp_frame.  */
519/* lr, fn valid; temp0 = entry vsp  */
520
521_spentry(values)
522local_label(return_values): 
523        __(ref_global(imm0,ret1val_addr))
524        __(mov arg_z,#nil_value)
525        __(cmp imm0,lr)
526        __(beq 3f)
527        __(cmp nargs,#fixnum_one)
528        __(add imm0,nargs,vsp)
529        __(ldrge arg_z,[imm0,#-node_size])
530        __(mov vsp,temp0)
531        __(bx lr)
532
533
534/* Return multiple values to real caller.  */
5353:
536        __(ldr lr,[sp,#lisp_frame.savelr])
537        __(add imm1,nargs,vsp)
538        __(ldr imm0,[sp,#lisp_frame.savevsp])
539        __(ldr fn,[sp,#lisp_frame.savefn])
540        __(cmp imm1,imm0) /* a fairly common case  */
541        __(discard_lisp_frame())
542        __(bxeq lr) /* already in the right place  */
543        __(cmp nargs,#fixnum_one) /* sadly, a very common case  */
544        __(bne 4f)
545        __(ldr arg_z,[vsp,#0])
546        __(mov vsp,imm0)
547        __(vpush1(arg_z))
548        __(bx lr)
5494:
550        __(blt 6f)
551        __(mov temp1,#fixnum_one)
5525:
553        __(cmp temp1,nargs)
554        __(add temp1,temp1,#fixnum_one)
555        __(ldr arg_z,[imm1,#-node_size]!)
556        __(push1(arg_z,imm0))
557        __(bne 5b)
5586:
559        __(mov vsp,imm0)
560        __(bx lr)
561
562
563/* Come here with saved context on top of stack.  */
564_spentry(nvalret)
565        .globl C(nvalret)
566C(nvalret):
567        __(ldr lr,[sp,#lisp_frame.savelr])
568        __(ldr temp0,[sp,#lisp_frame.savevsp])
569        __(ldr fn,[sp,#lisp_frame.savefn])
570        __(discard_lisp_frame())
571        __(b local_label(return_values))                         
572
573/* Caller has pushed tag and 0 or more values; nargs = nvalues.  */
574/* Otherwise, process unwind-protects and throw to indicated catch frame.  */
575
576               
577 _spentry(throw)
578        __(ldr imm1,[rcontext, #tcr.catch_top])
579        __(mov imm0,#0) /* count intervening catch/unwind-protect frames.  */
580        __(cmp imm1,#0)
581        __(ldr temp0,[vsp,nargs])
582        __(beq local_label(_throw_tag_not_found))
583local_label(_throw_loop):
584        __(ldr temp1,[imm1,#catch_frame.catch_tag])
585        __(cmp temp0,temp1)
586        __(mov imm2,imm1)
587        __(ldr imm1,[imm1,#catch_frame.link])
588        __(beq C(_throw_found))
589        __(cmp imm1,#0)
590        __(add imm0,imm0,#fixnum_one)
591        __(bne local_label(_throw_loop))
592local_label(_throw_tag_not_found):
593        __(uuo_error_no_throw_tag(al,temp0))
594        __(str temp0,[vsp,nargs])
595        __(b _SPthrow)
596
597/* This takes N multiple values atop the vstack.  */
598_spentry(nthrowvalues)
599dnl         __(mov imm1,#1)
600dnl  __(mov imm4,imm0)
601dnl         __(str(imm1,tcr.unwinding(rcontext)))
602dnl local_label(_nthrowv_nextframe):
603dnl  __(subi imm4,imm4,fixnum_one)
604dnl  __(cmpri(cr1,imm4,0))
605dnl  __(ldr temp0,[rcontext,#tcr.catch_top])
606dnl  __(ldr imm1,[rcontext,#tcr.db_link])
607dnl  __(blt cr1,local_label(_nthrowv_done))
608dnl  __(ldr imm0,[temp0,#catch_frame.db_link])
609dnl  __(ldr imm3,[temp0,#catch_frame.link])
610dnl  __(cmpr(imm0,imm1))
611dnl  __(str(imm3,tcr.catch_top(rcontext)))
612dnl  __(ldr temp1,[temp0,#catch_frame.catch_tag])
613dnl  __(cmpri(cr7,temp1,unbound_marker))  /* unwind-protect ?  */
614dnl  __(ldr first_nvr,[temp0,#catch_frame.xframe])
615dnl  __(str(first_nvr,tcr.xframe(rcontext)))
616dnl  __(ldr sp,[temp0,#catch_frame.csp])
617dnl  __(beq local_label(_nthrowv_dont_unbind))
618dnl  __(mflr loc_pc)
619dnl         __(bl _SPunbind_to)
620dnl  __(mtlr loc_pc)
621dnl local_label(_nthrowv_dont_unbind):
622dnl  __(beq cr7,local_label(_nthrowv_do_unwind))
623dnl /* A catch frame.  If the last one, restore context from there.  */
624dnl  __(bne cr1,local_label(_nthrowv_skip))
625dnl  __(ldr imm0,[sp,#lisp_frame.savevsp])
626dnl  __(str(rzero,lisp_frame.savevsp(sp))) /* marker for stack overflow code  */
627dnl  __(add imm1,vsp,nargs)
628dnl  __(mov imm2,nargs)
629dnl  __(b local_label(_nthrowv_push_test))
630dnl local_label(_nthrowv_push_loop):
631dnl  __(ldru(temp1,-node_size(imm1)))
632dnl  __(push(temp1,imm0))
633dnl local_label(_nthrowv_push_test):
634dnl  __(cmp imm2,#0))
635dnl  __(subi imm2,imm2,fixnum_one)
636dnl  __(bne local_label(_nthrowv_push_loop))
637dnl  __(mov vsp,imm0)
638dnl         __(restore_catch_nvrs(temp0))
639dnl
640dnl local_label(_nthrowv_skip):
641dnl  __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
642dnl  __(unlink(tsp))
643dnl  __(discard_lisp_frame())
644dnl  __(b local_label(_nthrowv_nextframe))
645dnl local_label(_nthrowv_do_unwind):
646dnl         /* This is harder.  Call the cleanup code with the multiple */
647dnl  /* values (and nargs, which is a fixnum.)  Remember the throw count  */
648dnl         /* (also a fixnum) as well.  */
649dnl         /* Save our caller's LR and FN in the csp frame created by the unwind-  */
650dnl         /* protect.  (Clever, eh ?)  */
651dnl  __(ldr first_nvr,[temp0,#catch_frame.xframe])
652dnl  __(str(first_nvr,tcr.xframe(rcontext)))
653dnl         __(restore_catch_nvrs(temp0))
654dnl  __(la tsp,-(tsp_frame.fixed_overhead+fulltag_misc)(temp0))
655dnl  __(unlink(tsp))
656dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
657dnl  __(ldr nfn,[sp,#lisp_frame.savefn])
658dnl  __(mtctr loc_pc) /* cleanup code address.  */
659dnl  __(str(fn,lisp_frame.savefn(sp)))
660dnl  __(mflr loc_pc)
661dnl  __(mov fn,nfn)
662dnl  __(str(loc_pc,lisp_frame.savelr(sp)))
663dnl  __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* tsp overhead, nargs, throw count  */
664dnl  __(TSP_Alloc_Var_Boxed_nz(imm0,imm1))
665dnl  __(mov imm2,nargs)
666dnl  __(add imm1,nargs,vsp)
667dnl  __(la imm0,tsp_frame.data_offset(tsp))
668dnl  __(str(nargs,0(imm0)))
669dnl  __(b local_label(_nthrowv_tpushtest))
670dnl local_label(_nthrowv_tpushloop):
671dnl  __(ldru(temp0,-node_size(imm1)))
672dnl  __(stru(temp0,node_size(imm0)))
673dnl  __(subi imm2,imm2,fixnum_one)
674dnl local_label(_nthrowv_tpushtest):
675dnl  __(cmp imm2,#0)
676dnl  __(bne local_label(_nthrowv_tpushloop))
677dnl  __(stru(imm4,node_size(imm0)))
678dnl  __(ldr vsp,[sp,#lisp_frame.savevsp])
679dnl         /* Interrupts should be disabled here (we're calling and returning */
680dnl         /* from the cleanup form.  Clear the tcr.unwinding flag, so that */
681dnl         /* interrupts can be taken if they're enabled in the cleanup form.  */
682dnl         __(str(rzero,tcr.unwinding(rcontext)))       
683dnl  __(bctrl)
684dnl         __(mov imm1,#1)
685dnl  __(la imm0,tsp_frame.data_offset(tsp))
686dnl         __(str(imm1,tcr.unwinding(rcontext)))
687dnl  __(ldr fn,[sp,#lisp_frame.savefn])
688dnl  __(ldr loc_pc,[sp,#lisp_frame.savelr])
689dnl  __(discard_lisp_frame())
690dnl  __(mtlr loc_pc)
691dnl  __(ldr nargs,[imm0,#0])
692dnl  __(mov imm2,nargs)
693dnl  __(b local_label(_nthrowv_tpoptest))
694dnl local_label(_nthrowv_tpoploop):
695dnl  __(ldru(temp0,node_size(imm0)))
696dnl  __(vpush1(temp0))
697dnl  __(subi imm2,imm2,fixnum_one)
698dnl local_label(_nthrowv_tpoptest):
699dnl  __(cmp imm2,#0)
700dnl  __(bne local_label(_nthrowv_tpoploop))
701dnl  __(ldr imm4,[imm0,#node_size])
702dnl  __(unlink(tsp))
703dnl  __(b local_label(_nthrowv_nextframe))
704dnl local_label(_nthrowv_done):
705dnl         __(str(rzero,tcr.unwinding(rcontext)))
706dnl         /* Poll for a deferred interrupt.  That clobbers nargs (which we've */
707dnl         /* just expended a lot of effort to preserve), so expend a little *
708dnl         /* more effort. */
709dnl         __(mov imm4,nargs)
710dnl         __(check_pending_interrupt())
711dnl         __(mov nargs,imm4)
712dnl         __(bx lr)
713
714/* This is a (slight) optimization.  When running an unwind-protect, */
715/* save the single value and the throw count in the tstack frame. */
716/* Note that this takes a single value in arg_z.  */
717_spentry(nthrow1value)
718        __(mov imm1,#1)
719        __(mov temp2,imm0)
720        __(str imm1,[rcontext,#tcr.unwinding])
721        __(b C(nthrow1v))
722
723
724/* arg_z = symbol: bind it to its current value          */
725 _spentry(bind_self)
726        __(ldr imm1,[arg_z,#symbol.binding_index])
727        __(ldr imm0,[rcontext,#tcr.tlb_limit])
728        __(cmp imm1,#0)
729        __(beq 9f)
730        __(cmp imm0,imm1)
731        __(uuo_tlb_too_small(ls,imm1))
732        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
733        __(ldr imm0,[rcontext,#tcr.db_link])
734        __(ldr temp1,[temp2,imm1])
735        __(cmp temp1,#no_thread_local_binding_marker)
736        __(movne temp0,temp1)
737        __(ldreq temp0,[arg_z,#symbol.vcell])
738        __(vpush1(temp1))   /* old tlb contents */
739        __(vpush1(imm1))    /* tlb index */
740        __(vpush1(imm0))
741        __(str temp0,[temp2,imm1])
742        __(str vsp,[rcontext,#tcr.db_link])
743        __(bx lr)
7449:      __(mov arg_y,#XSYMNOBIND)
745        __(set_nargs(2))
746        __(b _SPksignalerr)
747
748/* Bind symbol in arg_z to NIL                 */
749_spentry(bind_nil)
750        __(mov arg_y,arg_z)
751        __(mov arg_z,#nil_value)
752        __(b _SPbind)
753
754/* Bind symbol in arg_z to its current value;  trap if symbol is unbound */
755_spentry(bind_self_boundp_check)
756        __(ldr imm1,[arg_z,#symbol.binding_index])
757        __(ldr imm0,[rcontext,#tcr.tlb_limit])
758        __(cmp imm1,#0)
759        __(beq 9f)
760        __(cmp imm0,imm1)
761        __(uuo_tlb_too_small(ls,imm1))
762        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
763        __(ldr imm0,[rcontext,#tcr.db_link])
764        __(ldr temp1,[temp2,imm1])
765        __(cmp temp1,#no_thread_local_binding_marker)
766        __(movne temp0,temp1)
767        __(ldreq temp0,[arg_z,#symbol.vcell])
768        __(cmp temp0,#unbound_marker)
769        __(uuo_error_unbound(eq,arg_z))
770        __(vpush1(temp1))   /* old tlb contents */
771        __(vpush1(imm1))    /* tlb index */
772        __(vpush1(imm0))
773        __(str temp0,[temp2,imm1])
774        __(str vsp,[rcontext,#tcr.db_link])
775        __(bx lr)
7769:      __(mov arg_y,#XSYMNOBIND)
777        __(set_nargs(2))
778        __(b _SPksignalerr)
779
780 
781/* The function pc_luser_xp() - which is used to ensure that suspended threads */
782/* are suspended in a GC-safe way - has to treat these subprims (which  */
783/* implement the EGC write-barrier) specially.  Specifically, a store that */
784/* might introduce an intergenerational reference (a young pointer stored  */
785/* in an old object) has to "memoize" that reference by setting a bit in  */
786/* the global "refbits" bitmap. */
787/* This has to happen atomically, and has to happen atomically wrt GC. */
788/* Note that updating a word in a bitmap is itself not atomic, unless we use */
789/* interlocked loads and stores. */
790
791
792/* For RPLACA and RPLACD, things are fairly simple: regardless of where we  */
793/* are in the function, we can do the store (even if it's already been done)  */
794/* and calculate whether or not we need to set the bit out-of-line.  (Actually */
795/* setting the bit needs to be done atomically, unless we're sure that other */
796/* threads are suspended.) */
797/* We can unconditionally set the suspended thread's PC to its LR. */
798
799        .globl C(egc_write_barrier_start)
800_spentry(rplaca)
801C(egc_write_barrier_start):     
802        __(cmp arg_z,arg_y)
803        __(_rplaca(arg_y,arg_z))
804        __(bxlo lr)
805        __(ref_global(temp0,ref_base))
806        __(sub imm0,arg_y,temp0)
807        __(mov imm0,imm0,lsr #dnode_shift)
808        __(ref_global(imm1,oldspace_dnode_count))
809        __(cmp imm0,imm1)
810        __(bxhs lr)
811        __(and imm2,imm0,#31)
812        __(mov imm1,#0x80000000)
813        __(mov imm1,imm1,lsr imm2)
814        __(mov imm0,imm0,lsr #bitmap_shift)
815        __(ref_global(temp0,refbits))
816        __(add temp0,temp0,imm0,lsl #word_shift)
8170:      __(ldrex imm2,[temp0])
818        __(orr imm2,imm2,imm1)
819        __(strex imm0,imm2,[temp0])
820        __(cmp imm0,#0)
821        __(bne 0b)       
822        __(bx lr)
823
824
825        .globl C(egc_rplacd)
826_spentry(rplacd)
827C(egc_rplacd):
828        __(cmp arg_z,arg_y)
829        __(_rplacd(arg_y,arg_z))
830        __(bxlo lr)
831        __(ref_global(temp0,ref_base))
832        __(sub imm0,arg_y,temp0)
833        __(mov imm0,imm0,lsr #dnode_shift)
834        __(ref_global(imm1,oldspace_dnode_count))
835        __(cmp imm0,imm1)
836        __(bxhs lr)
837        __(and imm2,imm0,#31)
838        __(mov imm1,#0x80000000)
839        __(mov imm1,imm1,lsr imm2)
840        __(mov imm0,imm0,lsr #bitmap_shift)
841        __(ref_global(temp0,refbits))
842        __(add temp0,temp0,imm0,lsl #word_shift)
8430:      __(ldrex imm2,[temp0])
844        __(orr imm2,imm2,imm1)
845        __(strex imm0,imm2,[temp0])
846        __(cmp imm0,#0)
847        __(bne 0b)       
848        __(bx lr)
849       
850
851/* Storing into a gvector can be handled the same way as storing into a CONS. */
852
853        .globl C(egc_gvset)
854_spentry(gvset)
855C(egc_gvset):
856        __(cmp arg_z,arg_x)
857        __(add imm0,arg_y,#misc_data_offset)
858        __(str arg_z,[arg_x,imm0])
859        __(bxlo lr)               
860        __(add imm0,imm0,arg_x)
861        __(ref_global(temp0,ref_base))
862        __(sub imm0,imm0,temp0)
863        __(mov imm0,imm0,lsr #dnode_shift)
864        __(ref_global(imm1,oldspace_dnode_count))
865        __(cmp imm0,imm1)
866        __(bxhs lr)
867        __(and imm2,imm0,#31)
868        __(mov imm1,#0x80000000)
869        __(mov imm1,imm1,lsr imm2)
870        __(mov imm0,imm0,lsr #bitmap_shift)
871        __(ref_global(temp0,refbits))
872        __(add temp0,temp0,imm0,lsl #word_shift)
8730:      __(ldrex imm2,[temp0])
874        __(orr imm2,imm2,imm1)
875        __(strex imm0,imm2,[temp0])
876        __(cmp imm0,#0)
877        __(bne 0b)       
878        __(bx lr)
879
880       
881/* This is a special case of storing into a gvector: if we need to memoize  */
882/* the store, record the address of the hash-table vector in the refmap,  */
883/* as well. */
884        .globl C(egc_set_hash_key)       
885_spentry(set_hash_key)
886C(egc_set_hash_key):
887        __(cmp arg_z,arg_x)
888        __(add imm0,arg_y,#misc_data_offset)
889        __(str arg_z,[arg_x,imm0])
890        __(bxlo lr)
891        __(add imm0,imm0,arg_x)
892        __(ref_global(temp0,ref_base))
893        __(sub imm0,imm0,temp0)
894        __(mov imm0,imm0,lsr #dnode_shift)
895        __(ref_global(imm1,oldspace_dnode_count))
896        __(cmp imm0,imm1)
897        __(bxhs lr)
898        __(and imm2,imm0,#31)
899        __(mov imm1,#0x80000000)
900        __(mov imm1,imm1,lsr imm2)
901        __(mov imm0,imm0,lsr #bitmap_shift)
902        __(ref_global(temp0,refbits))
903        __(add temp0,temp0,imm0,lsl #word_shift)
9040:      __(ldrex imm2,[temp0])
905        __(orr imm2,imm2,imm1)
906        __(strex imm0,imm2,[temp0])
907        __(cmp imm0,#0)
908        __(bne 0b)       
909/* Now need to ensure that the hash table itself is in the refmap; we
910   know that it's in bounds, etc. */
911        __(ref_global(temp0,ref_base))
912        __(sub imm0,arg_x,temp0)
913        __(mov imm0,imm0,lsr #dnode_shift)
914        __(and imm2,imm0,#31)
915        __(mov imm1,#0x80000000)
916        __(mov imm1,imm1,lsr imm2)
917        __(mov imm0,imm0,lsr #bitmap_shift)
918        __(ref_global(temp0,refbits))
919        __(add temp0,temp0,imm0,lsl #word_shift)
9201:      __(ldrex imm2,[temp0])
921        __(orr imm2,imm2,imm1)
922        __(strex imm0,imm2,[temp0])
923        __(cmp imm0,#0)
924        __(bne 1b)       
925        __(bx lr)
926       
927
928/*
929   Interrupt handling (in pc_luser_xp()) notes:
930   If we are in this function and before the test which follows the
931   conditional (at egc_store_node_conditional), or at that test
932   and cr0`eq' is clear, pc_luser_xp() should just let this continue
933   (we either haven't done the store conditional yet, or got a
934   possibly transient failure.)  If we're at that test and the
935   cr0`EQ' bit is set, then the conditional store succeeded and
936   we have to atomically memoize the possible intergenerational
937   reference.  Note that the local labels 4 and 5 are in the
938   body of the next subprim (and at or beyond 'egc_write_barrier_end').
939
940   N.B: it's not possible to really understand what's going on just
941   by the state of the cr0`eq' bit.  A transient failure in the
942   conditional stores that handle memoization might clear cr0`eq'
943   without having completed the memoization.
944*/
945
946            .globl C(egc_store_node_conditional)
947            .globl C(egc_write_barrier_end)
948_spentry(store_node_conditional)
949C(egc_store_node_conditional):
950        __(vpop1(temp0))
951         
9521:      __(unbox_fixnum(imm2,temp0))
953        __(add imm2,imm2,arg_x)
954        __(ldrex temp1,[imm2])
955        __(cmp temp1,arg_y)
956        __(bne 5f)
957        __(strex imm0,arg_z,[imm2])
958        .globl C(egc_store_node_conditional_test)
959C(egc_store_node_conditional_test):
960        __(cmp imm0,#0)
961        __(bne 1b)
962        __(cmp arg_z,arg_x)
963        __(blo 4f)
964
965        __(ref_global(imm0,ref_base))
966        __(ref_global(imm1,oldspace_dnode_count))
967        __(sub imm0,imm2,imm0)
968        __(mov imm0,imm0,lsr #dnode_shift)
969        __(cmp imm0,imm1)
970        __(bhs 4f)
971        __(and imm1,imm0,#31)
972        __(mov arg_x,#0x80000000)
973        __(mov imm1,arg_x,lsr imm1)
974        __(ref_global(temp0,refbits))
975        __(mov imm0,imm0,lsr #bitmap_shift)
976        __(add temp0,temp0,imm0,lsl #word_shift)
9772:      __(ldrex imm2,[temp0])
978        __(orr imm2,imm2,imm1)
979        __(strex imm0,imm2,[temp0])
980        .globl C(egc_set_hash_key_conditional_test)
981C(egc_set_hash_key_conditional_test):
982        __(cmp imm0,#0)
983        __(bne 2b)
984        __(b 4f)
985 
986/* arg_z = new value, arg_y = expected old value, arg_x = hash-vector,
987    vsp`0' = (boxed) byte-offset
988    Interrupt-related issues are as in store_node_conditional, but
989    we have to do more work to actually do the memoization.*/
990_spentry(set_hash_key_conditional)
991        .globl C(egc_set_hash_key_conditional)
992C(egc_set_hash_key_conditional):
993        __(vpop1(imm1))
994        __(unbox_fixnum(imm1,imm1))
9950:      __(add imm2,arg_x,imm1)
996        __(ldrex temp1,[imm2])
997        __(cmp temp1,arg_y)
998        __(bne 5f)
999        __(strex imm0,arg_z,[imm2])
1000        __(bne 0b)
1001        __(cmp arg_z,arg_x)
1002        __(blo 4f)
1003        __(ref_global(temp0,ref_base))
1004        __(sub imm0,imm2,temp0)
1005        __(mov imm0,imm0,lsr #dnode_shift)
1006        __(ref_global(imm1,oldspace_dnode_count))
1007        __(cmp imm0,imm1)
1008        __(bhs 4f)
1009        __(and imm2,imm0,#31)
1010        __(mov imm1,#0x80000000)
1011        __(mov imm1,imm1,lsr imm2)
1012        __(mov imm0,imm0,lsr #bitmap_shift)
1013        __(ref_global(temp0,refbits))
1014        __(add temp0,temp0,imm0,lsl #word_shift)
10151:      __(ldrex imm2,[temp0])
1016        __(orr imm2,imm2,imm1)
1017        __(strex imm0,imm2,[temp0])
1018        __(cmp imm0,#0)
1019        __(bne 1b)       
1020/* Now need to ensure that the hash table itself is in the refmap; we
1021   know that it's in bounds, etc. */
1022        __(ref_global(temp0,ref_base))
1023        __(sub imm0,arg_x,temp0)
1024        __(mov imm0,imm0,lsr #dnode_shift)
1025        __(and imm2,imm0,#31)
1026        __(mov imm1,#0x80000000)
1027        __(mov imm1,imm1,lsr imm2)
1028        __(mov imm0,imm0,lsr #bitmap_shift)
1029        __(ref_global(temp0,refbits))
1030        __(add temp0,temp0,imm0,lsl #word_shift)
10311:      __(ldrex imm2,[temp0])
1032        __(orr imm2,imm2,imm1)
1033        __(strex imm0,imm2,[temp0])
1034        __(cmp imm0,#0)
1035        __(bne 1b)       
1036C(egc_write_barrier_end):
10374:      __(mov arg_z,#nil_value)
1038        __(add arg_z,arg_z,#t_offset)
1039        __(bx lr)
10405:      __(clrex)
1041        __(mov arg_z,#nil_value)
1042        __(bx lr)
1043
1044
1045
1046
1047       
1048/* We always have to create a stack frame (even if nargs is 0), so the compiler  */
1049/* doesn't get confused.  */
1050_spentry(stkconslist)
1051        __(mov arg_z,#nil_value)
1052C(stkconslist_star):           
1053        __(mov temp2,nargs,lsl #1)
1054        __(add temp2,temp2,#node_size)
1055        __(mov imm0,temp2,lsl #num_subtag_bits-word_shift)
1056        __(orr imm0,imm0,#subtag_u32_vector)
1057        __(stack_allocate_zeroed_ivector(imm0,temp2))
1058        __(mov imm0,#subtag_simple_vector)
1059        __(strb imm0,[sp,#0])
1060        __(add imm1,sp,#dnode_size+fulltag_cons)
1061        __(cmp nargs,#0)
1062        __(b 4f)
10631:      __(vpop1(temp0))
1064        __(_rplaca(imm1,temp0))
1065        __(_rplacd(imm1,arg_z))
1066        __(mov arg_z,imm1)
1067        __(add imm1,imm1,#cons.size)
1068        __(subs nargs,nargs,#node_size)
10694:
1070        __(bne 1b)
1071        __(bx lr)
1072 
1073/* do list*: last arg in arg_z, all others vpushed,  */
1074/* nargs set to #args vpushed.  */
1075_spentry(stkconslist_star)
1076        __(b C(stkconslist_star))
1077
1078/* Make a stack-consed simple-vector out of the NARGS objects  */
1079/* on top of the vstack; return it in arg_z.  */
1080_spentry(mkstackv)
1081        __(dnode_align(imm1,nargs,node_size))
1082        __(mov imm0,nargs,lsl #num_subtag_bits-fixnumshift)
1083        __(orr imm0,imm0,#subtag_u32_vector)
1084        __(stack_allocate_zeroed_ivector(imm0,imm1))
1085        __(mov imm0,#subtag_simple_vector)
1086        __(strb imm0,[sp,#0])
1087        __(add arg_z,sp,#fulltag_misc)
1088        __(add imm0,arg_z,#misc_data_offset)
1089        __(add imm1,imm0,nargs)
1090        __(b 4f)
10913:      __(vpop1(arg_y))
1092        __(str arg_y,[imm1,#-node_size]!)
1093        __(sub nargs,nargs,#node_size)
10944:      __(cmp nargs,#0)
1095        __(bne 3b)
1096        __(bx lr)
1097       
1098_spentry(setqsym)
1099        __(ldr imm0,[arg_y,#symbol.flags])
1100        __(tst imm0,#sym_vbit_const_mask)
1101        __(beq _SPspecset)
1102        __(mov arg_z,arg_y)
1103        __(mov arg_y,#XCONST)
1104        __(set_nargs(2))
1105        __(b _SPksignalerr)
1106
1107
1108
1109_spentry(progvsave)
1110dnl  /* Error if arg_z isn't a proper list.  That's unlikely, */
1111dnl  /* but it's better to check now than to crash later. */
1112dnl 
1113dnl  __(cmp arg_z,#nil_value)
1114dnl  __(mov arg_x,arg_z) /* fast  */
1115dnl  __(mov temp1,arg_z) /* slow  */
1116dnl  __(beq 9f)  /* Null list is proper  */
1117dnl 0:
1118dnl  __(trap_unless_list(arg_x,imm0))
1119dnl  __(_cdr(temp2,arg_x)) /* (null (cdr fast)) ?  */
1120dnl  __(cmpri(cr3,temp2,nil_value))
1121dnl  __(trap_unless_list(temp2,imm0,cr0))
1122dnl  __(_cdr(arg_x,temp2))
1123dnl  __(beq cr3,9f)
1124dnl  __(_cdr(temp1,temp1))
1125dnl  __(cmpr(arg_x,temp1))
1126dnl  __(bne 0b)
1127dnl  __(mov arg_y,#XIMPROPERLIST)
1128dnl  __(set_nargs(2))
1129dnl  __(b _SPksignalerr)
1130dnl 9: /* Whew   */
1131dnl 
1132dnl         /* Next, determine the length of arg_y.  We  */
1133dnl         /* know that it's a proper list.  */
1134dnl  __(mov imm0,#-node_size)
1135dnl  __(mov arg_x,arg_y)
1136dnl 1:
1137dnl  __(cmp arg_x,#nil_value)
1138dnl  __(la imm0,node_size(imm0))
1139dnl  __(_cdr(arg_x,arg_x))
1140dnl  __(bne 1b)
1141dnl  /* imm0 is now (boxed) triplet count.  */
1142dnl  /* Determine word count, add 1 (to align), and make room.  */
1143dnl  /* if count is 0, make an empty tsp frame and exit  */
1144dnl  __(cmp imm0,#0)
1145dnl  __(add imm1,imm0,imm0)
1146dnl  __(add imm1,imm1,imm0)
1147dnl         __(dnode_align(imm1,imm1,node_size))
1148dnl  __(bne+ 2f)
1149dnl   __(TSP_Alloc_Fixed_Boxed(2*node_size))
1150dnl   __(bx lr)
1151dnl 2:
1152dnl  __(la imm1,tsp_frame.fixed_overhead(imm1)) /* tsp header  */
1153dnl  __(TSP_Alloc_Var_Boxed_nz(imm1,imm2))
1154dnl  __(str(imm0,tsp_frame.data_offset(tsp)))
1155dnl  __(ldr imm2,[tsp,#tsp_frame.backlink])
1156dnl  __(mov arg_x,arg_y)
1157dnl  __(ldr imm1,[rcontext,#tcr.db_link])
1158dnl         __(ldr imm3,[rcontext,#tcr.tlb_limit])
1159dnl 3:
1160dnl         __(cmpri(cr1,arg_z,nil_value))
1161dnl  __(_car(temp0,arg_x))
1162dnl         __(ldr imm0,[temp0,#symbol.binding_index])
1163dnl  __(_cdr(arg_x,arg_x))
1164dnl         __(trlle(imm3,imm0))
1165dnl         __(ldr imm4,[rcontext,#tcr.tlb_pointer]) /* Need to reload after trap  */
1166dnl         __(ldrx(temp3,imm4,imm0))
1167dnl  __(cmp arg_x,#nil_value)
1168dnl         __(mov temp2,#unbound_marker)
1169dnl         __(beq cr1,4f)
1170dnl  __(_car(temp2,arg_z))
1171dnl  __(_cdr(arg_z,arg_z))
1172dnl 4:      __(push(temp3,imm2))
1173dnl  __(push(imm0,imm2))
1174dnl  __(push(imm1,imm2))
1175dnl         __(str temp2,imm4,imm0)
1176dnl  __(mov imm1,imm2)
1177dnl  __(bne 3b)
1178dnl  __(str(imm2,tcr.db_link(rcontext)))
1179dnl  __(bx lr)
1180dnl
1181dnl 
1182       
1183/* Allocate a uvector on the  stack.  (Push a frame on the stack and  */
1184/* heap-cons the object if there's no room on the stack.)  */
1185_spentry(stack_misc_alloc)
1186        __(tst arg_y,#unsigned_byte_24_mask)
1187        __(uuo_error_reg_not_xtype(ne,arg_y,xtype_unsigned_byte_24))
1188        __(unbox_fixnum(imm0,arg_z))
1189        __(extract_fulltag(imm1,imm0))
1190        __(cmp imm1,#fulltag_nodeheader)
1191        __(bne 1f)
1192        __(dnode_align(imm1,arg_y,node_size))
1193        __(cmp imm1,#stack_alloc_limit)
1194        __(bhs stack_misc_alloc_no_room)
1195        __(mov imm0,#subtag_u32_vector)
1196        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1197        __(mov temp0,#stack_alloc_marker)
1198        __(mov temp1,sp)
1199        __(stack_allocate_zeroed_ivector(imm0,imm1))
1200        __(unbox_fixnum(imm0,arg_z))
1201        __(strb imm0,[sp])
1202        __(add arg_z,sp,#fulltag_misc)
1203        __(stmdb sp!,{temp0,temp1})
1204        __(bx lr)
12051:      __(mov imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1206        __(orr imm0,imm0,arg_z,lsr #fixnumshift)
1207        __(cmp arg_z,#max_32_bit_ivector_subtag<<fixnumshift)
1208        __(movle imm1,arg_y)
1209        __(ble 8f)
1210        __(cmp arg_z,#max_8_bit_ivector_subtag<<fixnumshift)
1211        __(movle imm1,arg_y,lsr #fixnumshift)
1212        __(ble 8f)
1213        __(cmp arg_z,#max_16_bit_ivector_subtag<<fixnumshift)
1214        __(movle imm1,arg_y,lsr #1)
1215        __(ble 8f)
1216        __(cmp arg_z,#subtag_double_float)
1217        __(moveq imm1,arg_y,lsl #1)
1218        __(addeq imm1,imm1,#node_size)
1219        __(addne imm1,arg_y,#7<<fixnumshift)
1220        __(movne imm1,imm1,lsr#3+fixnumshift)
12218:      __(dnode_align(imm1,imm1,node_size))
1222        __(cmp imm1,#stack_alloc_limit)
1223        __(bhs stack_misc_alloc_no_room)
1224        __(mov temp0,#stack_alloc_marker)
1225        __(mov temp1,sp)
1226        __(stack_allocate_zeroed_ivector(imm0,imm1))
1227        __(add arg_z,sp,#fulltag_misc)
1228        __(stmdb sp!,{temp0,temp1})
1229        __(bx lr)
1230
1231
1232
1233
1234/* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
1235/* initial-contents.  Note that this can be used to cons any type of initialized  */
1236/* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
1237/* objects.  */
1238
1239_spentry(gvector)
1240        __(sub nargs,nargs,#node_size)
1241        __(ldr arg_z,[vsp,nargs])
1242        __(unbox_fixnum(imm0,arg_z))
1243        __(orr imm0,imm0,nargs,lsl #num_subtag_bits-fixnum_shift)
1244        __(dnode_align(imm1,nargs,node_size))
1245        __(Misc_Alloc(arg_z,imm0,imm1))
1246        __(mov imm1,nargs)
1247        __(add imm2,imm1,#misc_data_offset)
1248        __(b 2f)
12491:
1250        __(str temp0,[arg_z,imm2])
12512:
1252        __(sub imm1,imm1,#node_size)
1253        __(cmp imm1,#0)
1254        __(sub imm2,imm2,#node_size)
1255        __(vpop1(temp0))        /* Note the intentional fencepost: */
1256                                /* discard the subtype as well.  */
1257        __(bge 1b)
1258        __(bx lr)
1259
1260_spentry(fitvals)
1261        __(subs imm0,imm0,nargs)
1262        __(mov imm1,#nil_value)
1263        __(sublt vsp,vsp,imm0)
1264        __(bxlt lr)
1265        __(b 2f)
12661:
1267        __(subs imm0,imm0,#node_size)
1268        __(vpush1(imm1))       
1269        __(add nargs,nargs,#node_size)
12702:
1271        __(bne 1b)
1272        __(bx lr)
1273
1274
1275_spentry(nthvalue)
1276        __(add imm0,vsp,nargs)
1277        __(ldr imm1,[imm0,#0])
1278        __(cmp imm1,nargs) /*  do unsigned compare:  if (n < 0) => nil.  */
1279        __(mov arg_z,#nil_value)
1280        __(rsb imm1,imm1,#0)
1281        __(sub imm1,imm1,#node_size)
1282        __(ldrlo arg_z,[imm0,imm1])
1283        __(add vsp,imm0,#node_size)
1284        __(bx lr)
1285
1286/* Provide default (NIL) values for &optional arguments; imm0 is  */
1287/* the (fixnum) upper limit on the total of required and &optional  */
1288/* arguments.  nargs is preserved, all arguments wind up on the  */
1289/* vstack.  */
1290_spentry(default_optional_args)
1291        __(vpush_argregs())
1292        __(cmp nargs,imm0)
1293        __(mov arg_z,#nil_value)
1294        __(mov imm1,nargs)
1295        __(bxhs lr)
12961: 
1297        __(add imm1,imm1,#fixnum_one)
1298        __(cmp imm1,imm0)
1299        __(vpush1(arg_z))
1300        __(bne 1b)
1301        __(bx lr)
1302
1303/* Indicate whether &optional arguments were actually supplied.  nargs  */
1304/* contains the actual arg count (minus the number of required args);  */
1305/* imm0 contains the number of &optional args in the lambda list.  */
1306/* Note that nargs may be > imm0 if &rest/&key is involved.  */
1307_spentry(opt_supplied_p)
1308        __(mov imm1,#0)
1309        __(mov arg_x,#nil_value)
1310        __(add arg_x,arg_x,#t_offset)       
13111:     
1312        /* (vpush (< imm1 nargs))  */
1313        __(cmp imm1,nargs)
1314        __(add imm1,imm1,#fixnumone)
1315        __(subeq arg_x,arg_x,#t_offset)
1316        __(vpush1(arg_x))
1317        __(cmp imm1,imm0)
1318        __(bne 1b)
1319        __(bx lr)
1320
1321/* Cons a list of length nargs  and vpush it.  */
1322/* Use this entry point to heap-cons a simple &rest arg.  */
1323_spentry(heap_rest_arg)
1324        __(vpush_argregs())
1325        __(movs imm1,nargs)
1326        __(mov arg_z,#nil_value)
1327        __(b 2f)
13281:
1329        __(vpop1(arg_y))
1330        __(Cons(arg_z,arg_y,arg_z))
1331        __(subs imm1,imm1,#fixnum_one)
13322:
1333        __(bne 1b)
1334        __(vpush1(arg_z))
1335        __(bx lr)
1336
1337 
1338/* And this entry point when the argument registers haven't yet been  */
1339/* vpushed (as is typically the case when required/&rest but no  */
1340/* &optional/&key.)  */
1341_spentry(req_heap_rest_arg)
1342        __(vpush_argregs())
1343        __(subs imm1,nargs,imm0)
1344        __(mov arg_z,#nil_value)
1345        __(b 2f)
13461:
1347        __(vpop1(arg_y))
1348        __(Cons(arg_z,arg_y,arg_z))
1349        __(subs imm1,imm1,#fixnum_one)
13502:
1351        __(bgt 1b)
1352        __(vpush1(arg_z))
1353        __(bx lr)
1354
1355/* Here where argregs already pushed */
1356_spentry(heap_cons_rest_arg)
1357        __(subs imm1,nargs,imm0)
1358        __(mov arg_z,#nil_value)
1359        __(b 2f)
13601:
1361        __(vpop1(arg_y))
1362        __(Cons(arg_z,arg_y,arg_z))
1363        __(subs imm1,imm1,#fixnum_one)
13642:
1365        __(bgt 1b)
1366        __(vpush1(arg_z))
1367        __(bx lr)
1368
1369
1370_spentry(check_fpu_exception)
1371
1372_spentry(discard_stack_object)
1373        new_local_labels()       
1374        __(ldr imm0,[sp,#0])
1375        __(cmp imm0,#stack_alloc_marker)
1376        __(ldreq sp,[sp,#node_size])
1377        __(bxeq lr)
1378        __(cmp imm0,#lisp_frame_marker)
1379        __(extract_fulltag(imm1,imm0))
1380        __(addeq sp,sp,#lisp_frame.size)
1381        __(bxeq lr)
1382        __(cmp imm1,#fulltag_immheader)
1383        __(and imm1,imm0,#subtag_mask)
1384        __(bic imm0,imm0,#subtag_mask)
1385        __(beq local_label(ivector))
1386local_label(word):
1387        __(mov imm0,imm0,lsr #num_subtag_bits-word_shift)
1388local_label(out):       
1389        __(dnode_align(imm0,imm0,node_size))
1390        __(add sp,sp,imm0)
1391        __(bx lr)
1392local_label(ivector):     
1393        __(cmp imm1,#max_32_bit_ivector_subtag)
1394        __(bls local_label(word))       
1395        __(cmp imm1,#max_8_bit_ivector_subtag)
1396        __(movls imm0,imm0,lsr #num_subtag_bits)
1397        __(bls local_label(out))
1398        __(cmp imm1,#max_16_bit_ivector_subtag)
1399        __(movls imm0,imm0,lsr #num_subtag_bits-1)
1400        __(bls local_label(out))
1401        __(cmp imm1,#subtag_bit_vector)
1402        __(moveq imm0,imm0,lsr #num_subtag_bits)
1403        __(addeq imm0,imm0,#7)
1404        __(moveq imm0,imm0,lsr #3)
1405        __(beq local_label(out))
1406        /* The infamous 'stack-consed double-float vector' case */
1407        __(mov imm0,imm0,lsr #num_subtag_bits-dnode_shift)
1408        __(b local_label(out))
1409
1410
1411       
1412/* Signal an error synchronously, via %ERR-DISP.  */
1413/* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
1414/* on the C runtime stderr.  */
1415 
1416_spentry(ksignalerr)
1417        __(ref_nrs_symbol(fname,errdisp,imm0))
1418        __(jump_fname)
1419
1420/* As in the heap-consed cases, only stack-cons the &rest arg  */
1421_spentry(stack_rest_arg)
1422        __(mov imm0,#0)
1423        __(vpush_argregs())
1424        __(b _SPstack_cons_rest_arg)
1425
1426_spentry(req_stack_rest_arg)
1427        __(vpush_argregs())
1428        __(b _SPstack_cons_rest_arg)
1429
1430_spentry(stack_cons_rest_arg)
1431        __(subs imm1,nargs,imm0)
1432        __(mov arg_z,#nil_value)
1433        __(ble 2f)  /* always temp-push something.  */
1434        __(mov temp0,imm1)
1435        __(add imm1,imm1,imm1)
1436        __(add imm1,imm1,#node_size)
1437        __(dnode_align(imm0,imm1,node_size))
1438        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
1439        __(orr imm1,imm1,#subtag_u32_vector)
1440        __(cmp imm1,#stack_alloc_limit)
1441        __(bge 3f)
1442        __(stack_allocate_zeroed_ivector(imm1,imm0))
1443        __(mov imm0,#subtag_simple_vector)
1444        __(strb imm0,[sp])
1445        __(add imm0,sp,#dnode_size+fulltag_cons)
14461:
1447        __(subs temp0,temp0,#fixnumone)
1448        __(vpop1(arg_x))
1449        __(_rplacd(imm0,arg_z))
1450        __(_rplaca(imm0,arg_x))
1451        __(mov arg_z,imm0)
1452        __(add imm0,imm0,#cons.size)
1453        __(bne 1b)
1454        __(vpush1(arg_z))
1455        __(bx lr)
14562:
1457        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1458        __(mov imm1,#0)
1459        __(stmdb sp!,{imm0,imm1})
1460        __(vpush1(arg_z))
1461        __(bx lr)
14623:
1463        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1464        __(mov imm1,#0)
1465        __(stmdb sp!,{imm0,imm1})
1466        __(b _SPheap_cons_rest_arg)
1467
1468       
1469/* Prepend all but the first three (entrypoint, closure code, fn) and last two  */
1470/* (function name, lfbits) elements of nfn to the "arglist".  */
1471/* functions which take "inherited arguments" work consistently  */
1472/* even in cases where no closure object is created.  */
1473_spentry(call_closure)       
1474        __(cmp nargs,nargregs<<fixnumshift)
1475        __(vector_length(imm0,nfn,imm0))
1476        __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count  */
1477        __(ble local_label(no_insert))
1478        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
1479        /* of NILs, copy those arguments that have already been vpushed from  */
1480        /* the old TOS to the new, then insert all of the inerited args  */
1481        /* and go to the function.  */
1482        __(vpush_all_argregs())
1483        __(mov arg_x,imm0)
1484        __(mov arg_y,#nil_value)
1485local_label(push_nil_loop):
1486        __(subs arg_x,arg_x,#fixnumone)
1487        __(vpush1(arg_y))
1488        __(bne local_label(push_nil_loop))
1489        __(add arg_y,vsp,imm0)
1490        __(mov imm1,#0)
1491local_label(copy_already_loop): 
1492        __(ldr arg_x,[vsp,imm1])
1493        __(str arg_x,[arg_y,imm1])
1494        __(add imm1,imm1,#fixnumone)
1495        __(cmp imm1,imm0)
1496        __(bne local_label(copy_already_loop))
1497        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1498        __(add arg_y,vsp,nargs)
1499        __(add arg_y,arg_y,imm0)
1500local_label(insert_loop):
1501        __(subs imm0,imm0,#fixnumone)
1502        __(ldr fname,[nfn,imm1])
1503        __(add imm1,imm1,#fixnumone)
1504        __(add nargs,nargs,#fixnumone)
1505        __(push1(fname,arg_y))
1506        __(bne local_label(insert_loop))
1507        __(vpop_all_argregs())
1508        __(b local_label(go))
1509local_label(no_insert):
1510/* nargregs or fewer args were already vpushed.  */
1511/* if exactly nargregs, vpush remaining inherited vars.  */
1512        __(cmp nargs,#nargregs<<fixnumshift)
1513        __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift))
1514        __(bne local_label(set_regs))
1515local_label(vpush_remaining):
1516        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1517local_label(vpush_remaining_loop):             
1518        __(ldr fname,[nfn,imm1])
1519        __(add imm1,imm1,#fixnum_one)
1520        __(vpush1(fname))
1521        __(subs imm0,imm0,#fixnum_one)
1522        __(add nargs,nargs,#fixnum_one)
1523        __(bne  local_label(vpush_remaining_loop))
1524        __(b local_label(go))
1525local_label(set_regs):
1526        /* if nargs was > 1 (and we know that it was < 3), it must have  */
1527        /* been 2.  Set arg_x, then vpush the remaining args.  */
1528        __(cmp nargs,#fixnumone)
1529        __(ble local_label(set_y_z))
1530local_label(set_arg_x):
1531        __(subs imm0,imm0,#fixnum_one)
1532        __(sub imm1,imm1,#fixnum_one)
1533        __(ldr arg_x,[nfn,imm1])
1534        __(add nargs,nargs,#fixnum_one)
1535        __(bne local_label(vpush_remaining))
1536        __(b local_label(go))
1537        /* Maybe set arg_y or arg_z, preceding args  */
1538local_label(set_y_z):
1539        __(cmp nargs,#fixnumone)
1540        __(bne local_label(set_arg_z))
1541        /* Set arg_y, maybe arg_x, preceding args  */
1542local_label(set_arg_y):
1543        __(subs imm0,imm0,fixnum_one)
1544        __(sub imm1,imm1,#fixnum_one)
1545        __(ldr arg_y,[nfn,imm1])
1546        __(add nargs,nargs,#fixnum_one)
1547        __(bne local_label(set_arg_x))
1548        __(b local_label(go))
1549local_label(set_arg_z):
1550        __(subs imm0,imm0,#fixnum_one)
1551        __(sub imm1,imm1,#fixnum_one)
1552        __(ldr arg_z,[nfn,imm1])
1553        __(add nargs,nargs,#fixnum_one)
1554        __(bne local_label(set_arg_y))
1555 
1556local_label(go):
1557        __(vrefr(nfn,nfn,2))
1558        __(ldr pc,[nfn,#_function.entrypoint])
1559
1560
1561/* Everything up to the last arg has been vpushed, nargs is set to  */
1562/* the (boxed) count of things already pushed.  */
1563/* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
1564/* function call (this may require vpopping a few things.)  */
1565/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1566_spentry(spreadargz)
1567        __(extract_lisptag(imm1,arg_z))
1568        __(cmp arg_z,#nil_value)
1569        __(mov imm0,#0)
1570        __(mov arg_y,arg_z)  /*  save in case of error  */
1571        __(beq 2f)
15721:
1573        __(cmp imm1,#tag_list)
1574        __(bne 3f)
1575        __(_car(arg_x,arg_z))
1576        __(_cdr(arg_z,arg_z))
1577        __(cmp arg_z,#nil_value)
1578        __(extract_lisptag(imm1,arg_z))
1579        __(vpush1(arg_x))
1580        __(add imm0,imm0,#fixnum_one)
1581        __(bne 1b)
15822:
1583        __(adds  nargs,nargs,imm0)
1584        __(bxeq lr)
1585        __(vpop_argregs_nz)
1586        __(bx lr)
1587       
1588        /*  Discard whatever's been vpushed already, complain.  */
15893:
1590        __(add vsp,vsp,imm0)
1591        __(mov arg_z,arg_y)  /* recover original arg_z  */
1592        __(mov arg_y,#XNOSPREAD)
1593        __(set_nargs(2))
1594        __(b _SPksignalerr)
1595
1596/* Tail-recursively funcall temp0.  */
1597/* Pretty much the same as the tcallsym* cases above.  */
1598_spentry(tfuncallgen)
1599        __(cmp nargs,#nargregs<<fixnumshift)
1600        __(ldr lr,[sp,#lisp_frame.savelr])
1601        __(ldr fn,[sp,#lisp_frame.savefn])
1602        __(ble 2f)
1603        __(ldr imm0,[sp,#lisp_frame.savevsp])
1604        __(discard_lisp_frame())
1605        /* can use temp0 as a temporary  */
1606        __(sub imm1,nargs,#nargregs<<fixnumshift)
1607        __(add imm1,imm1,vsp)
16081:
1609        __(ldr temp0,[imm1,#-node_size]!)
1610        __(cmp imm1,vsp)
1611        __(push1(temp2,imm0))
1612        __(bne 1b)
1613        __(mov vsp,imm0)
1614        __(funcall_nfn())
16152:
1616        __(ldr vsp,[sp,#lisp_frame.savevsp])
1617        __(discard_lisp_frame())
1618        __(funcall_nfn())
1619
1620
1621/* Some args were vpushed.  Slide them down to the base of  */
1622/* the current frame, then do funcall.  */
1623_spentry(tfuncallslide)
1624        __(ldr fn,[sp,#lisp_frame.savefn])
1625        __(ldr imm0,[sp,#lisp_frame.savevsp])
1626        __(ldr lr,[sp,#lisp_frame.savelr])
1627        __(discard_lisp_frame())
1628        /* can use temp0 as a temporary  */
1629        __(sub imm1,nargs,#nargregs<<fixnumshift)
1630        __(add imm1,imm1,vsp)
16311:
1632        __(ldr temp0,[imm1,#-node_size]!)
1633        __(cmp imm1,vsp)
1634        __(push1(temp0,imm0))
1635        __(bne 1b)
1636        __(mov vsp,imm0)
1637        __(funcall_nfn())
1638
1639/* No args were vpushed; recover saved context & do funcall  */
1640_spentry(tfuncallvsp)
1641        __(restore_lisp_frame(imm0))
1642        __(funcall_nfn())
1643
1644/* Tail-recursively call the (known symbol) in fname.  */
1645/* In the general case, we don't know if any args were  */
1646/* vpushed or not.  If so, we have to "slide" them down  */
1647/* to the base of the frame.  If not, we can just restore  */
1648/* vsp, lr, fn from the saved lisp frame on the control stack.  */
1649_spentry(tcallsymgen)
1650        __(cmp nargs,#nargregs<<fixnumshift)
1651        __(ldr lr,[sp,#lisp_frame.savelr])
1652        __(ldr fn,[sp,#lisp_frame.savefn])
1653        __(ble 2f)
1654
1655        __(ldr imm0,[sp,#lisp_frame.savevsp])
1656        __(discard_lisp_frame())
1657        /* can use nfn (= temp2) as a temporary  */
1658        __(sub imm1,nargs,#nargregs<<fixnumshift)
1659        __(add imm1,imm1,vsp)
16601:
1661        __(ldr temp2,[imm1,#-node_size]!)
1662        __(cmp imm1,vsp)
1663        __(push1(temp2,imm0))
1664        __(bne 1b)
1665        __(mov vsp,imm0)
1666        __(jump_fname)
1667 
16682: 
1669        __(ldr vsp,[sp,#lisp_frame.savevsp])
1670        __(discard_lisp_frame())
1671        __(jump_fname)
1672
1673
1674/* Some args were vpushed.  Slide them down to the base of  */
1675/* the current frame, then do funcall.  */
1676_spentry(tcallsymslide)
1677        __(ldr lr,[sp,#lisp_frame.savelr])
1678        __(ldr fn,[sp,#lisp_frame.savefn])
1679        __(ldr imm0,[sp,#lisp_frame.savevsp])
1680        __(discard_lisp_frame())
1681        /* can use nfn (= temp2) as a temporary  */
1682        __(sub imm1,nargs,#nargregs<<fixnumshift)
1683        __(add imm1,imm1,vsp)
16841:
1685        __(ldr temp2,[imm1,#-node_size]!)
1686        __(cmp imm1,vsp)
1687        __(push1(temp2,imm0))
1688        __(bne 1b)
1689        __(mov vsp,imm0)
1690        __(jump_fname)
1691
1692
1693/* Tail-recursively call the function in nfn.  */
1694/* Pretty much the same as the tcallsym* cases above.  */
1695_spentry(tcallnfngen)
1696        __(cmp nargs,#nargregs<<fixnumshift)
1697        __(bgt _SPtcallnfnslide)
1698        __(restore_lisp_frame(imm0))
1699        __(jump_nfn())
1700         
1701/* Some args were vpushed.  Slide them down to the base of  */
1702/* the current frame, then do funcall.  */
1703_spentry(tcallnfnslide)
1704        __(ldr lr,[sp,#lisp_frame.savelr])
1705        __(ldr fn,[sp,#lisp_frame.savefn])
1706        __(ldr imm0,[sp,#lisp_frame.savevsp])
1707        __(discard_lisp_frame())
1708        /* Since we have a known function, can use fname as a temporary.  */
1709        __(sub imm1,nargs,#nargregs<<fixnumshift)
1710        __(add imm1,imm1,vsp)
17111:
1712        __(ldr fname,[imm1,#-node_size]!)
1713        __(cmp imm1,vsp)
1714        __(push1(fname,imm0))
1715        __(bne 1b)
1716        __(mov vsp,imm0)
1717        __(jump_nfn())
1718
1719
1720/* Reference index arg_z of a misc-tagged object (arg_y).  */
1721/* Note that this conses in some cases.  Return a properly-tagged  */
1722/* lisp object in arg_z.  Do type and bounds-checking.  */
1723
1724_spentry(misc_ref)
1725        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1726        __(trap_unless_fixnum(arg_z))
1727        __(vector_length(imm0,arg_y,imm1))
1728        __(cmp arg_z,imm0)
1729        __(uuo_error_vector_bounds(hs,arg_z,arg_y))
1730        __(extract_lowbyte(imm1,imm1)) /* imm1 = subtag  */
1731        __(b C(misc_ref_common)) 
1732
1733/* like misc_ref, only the boxed subtag is in arg_x.  */
1734
1735_spentry(subtag_misc_ref)
1736        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1737        __(trap_unless_fixnum(arg_z))
1738        __(vector_length(imm0,arg_y,imm1))
1739        __(cmp arg_z,imm0)
1740        __(uuo_error_vector_bounds(hs,arg_z,arg_y))
1741        __(unbox_fixnum(imm1,arg_x))
1742        __(b C(misc_ref_common))
1743
1744
1745/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
1746/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
1747/* in arg_z on exit.  */
1748_spentry(makestackblock)
1749        __(unbox_fixnum(imm1,arg_z))
1750        __(dnode_align(imm1,imm1,0))
1751        __(add imm1,imm1,#node_size)
1752        __(add imm0,imm1,#node_size)
1753        __(cmp imm0,#stack_alloc_limit)
1754        __(mov temp0,sp)
1755        __(bhs 1f)
1756        __(mov imm1,imm1,lsl #num_subtag_bits)
1757        __(orr imm1,imm1,#subtag_u8_vector)
1758        __(stack_allocate_ivector(imm1,imm0))
1759        __(add temp1,sp,#dnode_size)
1760        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1761        __(str imm1,[sp,#-macptr.size]!)
1762        __(add arg_z,sp,#fulltag_misc)
1763        __(str temp1,[arg_z,#macptr.address])
1764        __(mov imm0,#0)
1765        __(mov imm1,#stack_alloc_marker)
1766        __(str imm0,[arg_z,#macptr.type])
1767        __(str imm0,[arg_z,#macptr.domain])
1768        __(stmdb sp!,{imm1,temp0})
1769        __(bx lr)
1770
1771        /* Too big. Heap cons a gcable macptr  */
17721:
1773        __(mov imm1,#stack_alloc_marker)
1774        __(stmdb sp!,{imm1,temp0})
1775        __(set_nargs(1))
1776        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1777        __(jump_fname())
1778
1779/* As above, only set the block's contents to 0.  */
1780_spentry(makestackblock0)
1781        __(unbox_fixnum(imm1,arg_z))
1782        __(dnode_align(imm1,imm1,0))
1783        __(add imm1,imm1,#node_size)
1784        __(add imm0,imm1,#node_size)
1785        __(cmp imm0,#stack_alloc_limit)
1786        __(mov temp0,sp)
1787        __(bhs 1f)
1788        __(mov imm1,imm1,lsl #num_subtag_bits)
1789        __(orr imm1,imm1,#subtag_u8_vector)
1790        __(stack_allocate_ivector(imm1,imm0))
1791        __(add temp1,sp,#dnode_size)
1792        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1793        __(str imm1,[sp,#-macptr.size]!)
1794        __(add arg_z,sp,#fulltag_misc)
1795        __(str temp1,[arg_z,#macptr.address])
1796        __(mov imm0,#0)
1797        __(mov imm1,#stack_alloc_marker)
1798        __(str imm0,[arg_z,#macptr.type])
1799        __(str imm0,[arg_z,#macptr.domain])
1800        __(stmdb sp!,{imm1,temp0})
1801        __(bx lr)
1802       
1803        /* Too big. Heap cons a gcable macptr  */
18041:
1805        __(mov imm1,#stack_alloc_marker)
1806        __(stmdb sp!,{imm1,temp0})
1807        __(mov arg_y,arg_z) /* save block size  */
1808        __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr  */
1809        __(add arg_z,arg_z,#t_offset)
1810        __(set_nargs(2))
1811        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1812        __(jump_fname())
1813
1814/* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
1815/* the tstack.  Return the list in arg_z.  */
1816_spentry(makestacklist)
1817        __(add imm0,arg_y,arg_y)
1818        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1819        __(add imm1,imm1,#4<<num_subtag_bits)
1820        __(orr imm1,imm1,#subtag_u32_vector)
1821        __(add imm0,imm0,#dnode_size)
1822        __(cmp imm0,#stack_alloc_limit)
1823        __(bge 4f)
1824        __(stack_allocate_zeroed_ivector(imm1,imm0))
1825        __(mov imm0,#subtag_simple_vector)
1826        __(strb imm0,[sp,#0])
1827        __(add imm2,sp,#dnode_size+fulltag_cons)
1828        __(movs imm1,arg_y)
1829        __(mov arg_y,arg_z)
1830        __(mov arg_z,#nil_value)
1831        __(b 3f)
18322:
1833        __(_rplacd(imm2,arg_z))
1834        __(_rplaca(imm2,arg_y))
1835        __(mov arg_z,imm2)
1836        __(add imm2,imm2,#cons.size)
1837        __(subs imm1,imm1,#fixnumone)
18383:
1839        __(bne 2b)
1840        __(bx lr)
18414:
1842        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1843        __(str imm0,[sp,#-8]!)
1844        __(movs imm1,arg_y) /* count  */
1845        __(mov arg_y,arg_z) /* initial value  */
1846        __(mov arg_z,#nil_value) /* result  */
1847        __(b 6f)
18485:
1849        __(Cons(arg_z,arg_y,arg_z))
1850        __(subs imm1,imm1,#fixnumone)
18516:
1852        __(bne 5b)
1853        __(bx lr)
1854
1855/* subtype (boxed) vpushed before initial values. (Had better be a  */
1856/* node header subtag.) Nargs set to count of things vpushed.  */
1857
1858_spentry(stkgvector)
1859        __(sub imm0,nargs,#fixnumone)
1860        __(ldr temp0,[vsp,imm0])
1861        __(dnode_align(temp1,imm0,node_size))
1862        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1863        __(orr imm1,imm1,#subtag_u32_vector)
1864        __(mov temp2,sp)
1865        __(mov arg_x,#stack_alloc_marker)
1866        __(stack_allocate_zeroed_ivector(imm1,temp1))
1867        __(unbox_fixnum(imm1,temp0))
1868        __(strb imm1,[sp])
1869        __(add arg_z,sp,#fulltag_misc)
1870        __(add imm0,sp,nargs)
1871        __(stmdb sp!,{arg_x,temp2})
1872        __(b 2f)
18731:
1874        __(vpop1(temp0))
1875        __(push1(temp0,imm0))
18762:      __(subs nargs,nargs,#fixnumone)
1877        __(bne 1b)
1878        __(add vsp,vsp,#fixnumone)
1879        __(bx lr)
1880
1881/* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
1882/* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
1883/* parameters must be "reasonable" (the  subtag must be valid, the element  */
1884/* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
1885/* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
1886/* proper header on it and its contents will be 0.   imm0 contains   */
1887/* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
1888
1889_spentry(misc_alloc)
1890        __(tst arg_y,#unsigned_byte_24_mask)
1891        __(bne 9f)
1892        __(unbox_fixnum(imm0,arg_z))
1893        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1894        __(extract_fulltag(imm1,imm0))
1895        __(cmp imm1,#fulltag_nodeheader)
1896        __(mov imm2,arg_y)      /* imm2 = logical size in bytes */
1897        __(beq 1f)
1898        __(unbox_fixnum(imm1,arg_z))
1899        __(cmp imm1,#max_32_bit_ivector_subtag)
1900        __(ble 1f)
1901        __(mov imm2,arg_y,lsr #2)
1902        __(cmp imm1,#max_8_bit_ivector_subtag)
1903        __(ble 1f)
1904        __(mov imm2,arg_y,lsr #1)
1905        __(cmp imm1,#max_16_bit_ivector_subtag)
1906        __(ble 1f)
1907        __(mov imm2,arg_y,lsl #1)
1908        __(add imm2,imm2,#node_size)
1909        __(cmp imm1,#subtag_double_float_vector)
1910        __(beq 1f)
1911        __(add imm2,arg_y,#7<<fixnumshift)
1912        __(mov imm2,imm2,lsr #3+fixnumshift)
1913        /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
1914        /* low three bits.  */
19151:
1916        __(dnode_align(imm2,imm2,node_size))
1917        __(Misc_Alloc(arg_z,imm0,imm2))
1918        __(bx lr)
19199:
1920        __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
1921
1922
1923
1924/* This doesn't need to memoize anything, but needs pc-lusering support
1925   support because of the locative */
1926_spentry(atomic_incf_node)
1927        __(unbox_fixnum(imm0,arg_z))
19280:      __(add imm2,arg_y,imm0)
1929        __(ldrex arg_z,[imm2])
1930        __(add arg_z,arg_z,arg_x)
1931        __(strex imm0,arg_z,[imm2])
1932        __(cmp imm0,#0)
1933        __(bne 0b)
1934        __(bx lr)
1935       
1936_spentry(unused1)
1937
1938_spentry(unused2)
1939
1940dnl /* vpush the values in the value set atop the vsp, incrementing nargs.  */
1941dnl /* Discard the tsp frame; leave values atop the vsp.  */
1942dnl
1943_spentry(recover_values)
1944dnl
1945dnl /* First, walk the segments reversing the pointer to previous segment pointers  */
1946dnl /* Can tell the end because that previous segment pointer is the prev tsp pointer  */
1947dnl  __(ldr imm0,[tsp,#tsp_frame.backlink]) /* previous tsp  */
1948dnl  __(mov imm1,tsp) /* current segment  */
1949dnl  __(mov imm2,tsp) /* last segment  */
1950dnl local_label(walkloop):
1951dnl  __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment  */
1952dnl  __(cmpr(imm0,imm3)) /* last segment?  */
1953dnl  __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
1954dnl  __(mov imm2,imm1) /* last segment <- current segment  */
1955dnl  __(mov imm1,imm3) /* current segment <- next segment  */
1956dnl  __(bne local_label(walkloop))
1957dnl
1958dnl         /* the final segment ptr is now in imm2  */
1959dnl         /* walk backwards, pushing values on VSP and incrementing NARGS  */
1960dnl local_label(pushloop):
1961dnl  __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment  */
1962dnl  __(cmpri(imm0,0))
1963dnl  __(cmpr(cr1,imm2,tsp))
1964dnl  __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
1965dnl  __(add imm3,imm3,imm0)
1966dnl  __(add nargs,nargs,imm0)
1967dnl  __(b 2f)
1968dnl 1:
1969dnl  __(ldru(arg_z,-node_size(imm3)))
1970dnl  __(cmpri(imm0,fixnum_one))
1971dnl  __(subi imm0,imm0,fixnum_one)
1972dnl  __(vpush1(arg_z))
1973dnl 2:
1974dnl  __(bne 1b)
1975dnl  __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment  */
1976dnl  __(bne cr1,local_label(pushloop))
1977dnl  __(unlink(tsp))
1978dnl  __(bx lr)
1979
1980
1981
1982/* If arg_z is an integer, return in imm0 something whose sign  */
1983/* is the same as arg_z's.  If not an integer, error.  */
1984_spentry(integer_sign)
1985        __(test_fixnum(arg_z))
1986        __(moveq imm0,arg_z)
1987        __(bxeq lr)
1988        __(extract_typecode(imm0,arg_z))
1989        __(cmp imm0,#subtag_bignum)
1990        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_integer))
1991        __(getvheader(imm1,arg_z))
1992        __(header_length(imm0,imm1)) /* boxed length = scaled size  */
1993        __(add imm0,imm0,#misc_data_offset-4) /* bias, less 1 element  */
1994        __(ldr imm0,[arg_z,imm0])
1995        __(cmp imm0,#0)
1996        __(movge imm0,#1)
1997        __(movlt imm0,#-1)
1998        __(bx lr)
1999
2000
2001/* like misc_set, only pass the (boxed) subtag in temp0  */
2002_spentry(subtag_misc_set)
2003        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
2004        __(trap_unless_fixnum(arg_y))
2005        __(vector_length(imm0,arg_x,imm1))
2006        __(cmp arg_y,imm0)
2007        __(uuo_error_vector_bounds(hs,arg_y,arg_x))
2008        __(unbox_fixnum(imm1,temp0))
2009        __(b C(misc_set_common))
2010
2011
2012
2013/* misc_set (vector index newval).  Pretty damned similar to  */
2014/* misc_ref, as one might imagine.  */
2015
2016_spentry(misc_set)
2017        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
2018        __(trap_unless_fixnum(arg_y))
2019        __(vector_length(imm0,arg_x,imm1))
2020        __(cmp arg_y,imm0)
2021        __(uuo_error_vector_bounds(hs,arg_y,arg_x))
2022        __(extract_lowbyte(imm1,imm1))
2023        __(b C(misc_set_common))
2024
2025/* "spread" the lexpr in arg_z.  */
2026/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
2027_spentry(spread_lexprz)
2028        __(ldr imm0,[arg_z,#0])
2029        __(add imm1,arg_z,imm0)
2030        __(add nargs,nargs,imm0)
2031        __(add imm1,imm1,#node_size)
2032        __(cmp imm0,#3<<fixnumshift)
2033        __(bge 9f)
2034        __(cmp imm0,#2<<fixnumshift)
2035        __(beq 2f)
2036        __(cmp imm0,#0)
2037        __(bne 1f)
2038/* lexpr count was 0; vpop the arg regs that  */
2039/* were vpushed by the caller  */
2040        __(cmp nargs,#0)
2041        __(bxeq lr)
2042        __(vpop_argregs_nz)
2043        __(bx lr)
2044
2045/* vpush args from the lexpr until we have only  */
2046/* three left, then assign them to arg_x, arg_y,  */
2047/* and arg_z.  */
20488:
2049        __(cmp imm0,#4<<fixnumshift)
2050        __(sub imm0,imm0,#fixnumone)
2051        __(ldr arg_z,[imm1,#-node_size]!)
2052        __(vpush1(arg_z))
20539:
2054        __(bne 8b)
2055        __(ldr arg_x,[imm1,#-node_size*1])
2056        __(ldr arg_y,[imm1,#-node_size*2])
2057        __(ldr arg_z,[imm1,#-node_size*3])
2058        __(bx lr)
2059
2060/* lexpr count is two: set arg_y, arg_z from the  */
2061/* lexpr, maybe vpop arg_x  */
20622:
2063        __(cmp nargs,#2<<fixnumshift)
2064        __(ldr arg_y,[imm1,#-node_size*1])
2065        __(ldr arg_z,[imm1,#-node_size*2])
2066        __(bxeq lr)  /* return if (new) nargs = 2  */
2067        __(vpop1(arg_x))
2068        __(bx lr)
2069
2070/* lexpr count is one: set arg_z from the lexpr,  */
2071/* maybe vpop arg_y, arg_x  */
20721:
2073        __(cmp nargs,#2<<fixnumshift)
2074        __(ldr arg_z,[imm1,#-node_size])
2075        __(bxlt lr)  /* return if (new) nargs < 2  */
2076        __(vpop1(arg_y))
2077        __(bxeq lr)  /* return if (new) nargs = 2  */
2078        __(vpop1(arg_x))
2079        __(bx lr)
2080
2081
2082_spentry(reset)
2083        __(nop)
2084        __(ref_nrs_value(temp0,toplcatch))
2085        __(mov temp1,#XSTKOVER)
2086        __(vpush1(temp0))
2087        __(vpush1(temp1))
2088        __(set_nargs(1))
2089        __(b _SPthrow)
2090
2091
2092/* "slide" nargs worth of values up the vstack.  IMM0 contains  */
2093/* the difference between the current VSP and the target.  */
2094_spentry(mvslide)
2095        __(cmp nargs,#0)
2096        __(mov temp1,nargs)
2097        __(add imm1,vsp,nargs)
2098        __(add imm1,imm1,imm0)
2099        __(add imm0,vsp,nargs)
2100        __(beq 2f)
21011:
2102        __(subs temp1,temp1,#1<<fixnumshift)
2103        __(ldr temp0,[imm0,#-node_size]!)
2104        __(str temp0,[imm1,#-node_size]!)
2105        __(bne 1b)
2106        2:
2107        __(mov vsp,imm1)
2108        __(bx lr)
2109
2110dnl /* Build a new TSP area to hold nargs worth of multiple-values.  */
2111dnl /* Pop the multiple values off of the vstack.  */
2112dnl /* The new TSP frame will look like this:  */
2113dnl /*  */
2114dnl /*+--------+-------+-------+---------+--------+--------+--------+======+----------+ */
2115dnl /*| ptr to | zero  | nargs | ptr to  | valn-1 | valn-2 | val-0  | ???? | prev TSP |  */
2116dnl /*|  prev  |       |       |  prev   |        |        |        | fill |          |  */
2117dnl /*| TSP    |       |       | segment |        |        |        |      |          | */
2118dnl /*+--------+-------+-------+---------+--------+--------+--------+------+----------+  */
2119dnl /*  */
2120dnl /* e.g., the first multiple value goes in the last cell in the frame, the  */
2121dnl /* count of values goes in the first word, and the word after the value count  */
2122dnl /* is 0 if the number of values is even (for alignment).  */
2123dnl /* Subsequent calls to .SPadd_values preserve this alignment.  */
2124dnl /* .SPrecover_values is therefore pretty simple.  */
2125dnl
2126_spentry(save_values)
2127dnl  __(mov imm1,tsp)
2128dnl
2129dnl         /* common exit: nargs = values in this set, imm1 = ptr to tsp before  */
2130dnl         /* call to save_values  */
2131dnl local_label(save_values_to_tsp):
2132dnl  __(mov imm2,tsp)
2133dnl  __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* count, link  */
2134dnl  __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
2135dnl  __(str(imm1,tsp_frame.backlink(tsp))) /* keep one tsp "frame" as far as rest of lisp is concerned  */
2136dnl  __(str(nargs,tsp_frame.data_offset(tsp)))
2137dnl  __(str(imm2,tsp_frame.data_offset+node_size(tsp))) /* previous tsp  */
2138dnl  __(la imm3,tsp_frame.data_offset+node_size*2(tsp))
2139dnl  __(add imm3,imm3,nargs)
2140dnl  __(add imm0,vsp,nargs)
2141dnl  __(cmpr(imm0,vsp))
2142dnl  __(b 2f)
2143dnl 1:
2144dnl  __(ldru(arg_z,-node_size(imm0)))
2145dnl  __(cmpr(imm0,vsp))
2146dnl  __(stru(arg_z,-node_size(imm3)))
2147dnl 2:
2148dnl  __(bne 1b)
2149dnl  __(add vsp,vsp,nargs) /*  discard values  */
2150dnl  __(bx lr)
2151dnl 
2152dnl
2153dnl /* Add the multiple values that are on top of the vstack to the set  */
2154dnl /* saved in the top tsp frame, popping them off of the vstack in the  */
2155dnl /* process.  It is an error (a bad one) if the TSP contains something  */
2156dnl /* other than a previously saved set of multiple-values.  */
2157dnl /* Since adding to the TSP may cause a new TSP segment to be allocated,  */
2158dnl /* each add_values call adds another linked element to the list of  */
2159dnl /* values. This makes recover_values harder.  */
2160dnl
2161_spentry(add_values)
2162dnl  __(cmpri(nargs,0))
2163dnl  __(ldr imm1,[tsp,#0])
2164dnl  __(bne local_label(save_values_to_tsp))
2165dnl  __(bx lr)
2166dnl         
2167
2168/* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
2169/* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
2170/* Calls out to %init-misc, which does the rest of the work.  */
2171
2172_spentry(misc_alloc_init)
2173        __(build_lisp_frame(imm0))
2174        __(mov fn,#0)
2175        __(mov temp2,arg_z)  /* initval  */
2176        __(mov arg_z,arg_y)  /* subtag  */
2177        __(mov arg_y,arg_x)  /* element-count  */
2178        __(bl _SPmisc_alloc)
2179        __(restore_lisp_frame(imm0))
2180        __(mov arg_y,temp2)
2181initialize_vector:             
2182        __(ref_nrs_symbol(fname,init_misc,imm0))
2183        __(set_nargs(2))
2184        __(jump_fname())
2185
2186/* As in stack_misc_alloc above, only with a non-default initial-value.  */
2187/* Note that this effectively inlines _SPstack_misc_alloc. */               
2188 
2189_spentry(stack_misc_alloc_init)
2190        __(tst arg_x,#unsigned_byte_24_mask)
2191        __(uuo_error_reg_not_xtype(ne,arg_x,xtype_unsigned_byte_24))
2192        __(unbox_fixnum(imm0,arg_y))
2193        __(extract_fulltag(imm1,imm0))
2194        __(cmp imm1,#fulltag_nodeheader)
2195        __(bne 1f)
2196        __(dnode_align(imm1,arg_x,node_size))
2197        __(cmp imm1,#stack_alloc_limit)
2198        __(bge 0f)
2199        __(mov imm0,#subtag_u32_vector)
2200        __(orr imm0,imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
2201        __(mov temp0,#stack_alloc_marker)
2202        __(mov temp1,sp)
2203        __(stack_allocate_zeroed_ivector(imm0,imm1))
2204        __(unbox_fixnum(imm0,arg_y))
2205        __(strb imm0,[sp])
2206        __(mov arg_y,arg_z)
2207        __(add arg_z,sp,#fulltag_misc)
2208        __(stmdb sp!,{temp0,temp1})
2209        __(b initialize_vector)
22101:      __(mov imm0,arg_x,lsl #num_subtag_bits-fixnumshift)
2211        __(orr imm0,imm0,arg_y,lsr #fixnumshift)
2212        __(cmp arg_z,#max_32_bit_ivector_subtag<<fixnumshift)
2213        __(movle imm1,arg_x)
2214        __(ble 8f)
2215        __(cmp arg_z,#max_8_bit_ivector_subtag<<fixnumshift)
2216        __(movle imm1,arg_x,lsr #fixnumshift)
2217        __(ble 8f)
2218        __(cmp arg_z,#max_16_bit_ivector_subtag<<fixnumshift)
2219        __(movle imm1,arg_x,lsr #1)
2220        __(ble 8f)
2221        __(cmp arg_z,#subtag_double_float)
2222        __(moveq imm1,arg_x,lsl #1)
2223        __(addeq imm1,imm1,#node_size)
2224        __(addne imm1,arg_x,#7<<fixnumshift)
2225        __(movne imm1,imm1,lsr#3+fixnumshift)
22268:      __(dnode_align(imm1,imm1,node_size))
2227        __(cmp imm1,#stack_alloc_limit)
2228        __(bhs 0f)
2229        __(mov temp0,#stack_alloc_marker)
2230        __(mov temp1,sp)
2231        __(stack_allocate_zeroed_ivector(imm0,imm1))
2232        __(mov arg_y,arg_z)
2233        __(add arg_z,sp,#fulltag_misc)
2234        __(stmdb sp!,{temp0,temp1})
2235        __(b initialize_vector)
2236
2237 
2238_spentry(popj)
2239        .globl C(popj)
2240C(popj):
2241        __(return_lisp_frame(imm0))
2242       
2243/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
2244/* sure that there's an empty tsp frame to keep the compiler happy.  */
22450:
2246        __(mov imm0,#stack_alloc_marker)
2247        __(mov imm1,sp)
2248        __(stmdb sp!,{imm0,imm1})
2249        __(b _SPmisc_alloc_init)
2250
2251
2252/* Divide the 64 bit unsigned integer in imm0 (low) and imm1 (high) by
2253   the 32-bit unsigned integer in imm2; return the quotient in
2254   imm0:imm1 and remainder in imm2.  We pretty much have to do this
2255   as an ff call; even if we wrote the code ourselves, we'd have to
2256   enter foreign context to use as many imm regs as we'd need.
2257   Moral: don't do integer division on the ARM.
2258*/
2259        .globl C(__aeabi_uldivmod)       
2260_spentry(udiv64by32)
2261        __(cmp imm2,#0)
2262        __(moveq arg_z,#XDIVZRO)
2263        __(moveq nargs,#1<<fixnumshift)
2264        __(beq _SPksignalerr)
2265        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2266        __(str vsp,[rcontext,#tcr.save_vsp])
2267        __(mov arg_z,rcontext)
2268        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2269        __(build_lisp_frame(r3))
2270        __(str sp,[arg_z,#tcr.last_lisp_frame])
2271        __(str allocptr,[arg_z,#tcr.save_allocptr])
2272        __(mov r3,#TCR_STATE_FOREIGN)
2273        __(str r3,[arg_z,#tcr.valence])
2274        __(mov r3,#0)
2275        __(bl C(__aeabi_uldivmod))
2276        __(mov rcontext,arg_z)
2277        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2278        __(mov allocptr,#VOID_ALLOCPTR)
2279        __(mov fn,#0)
2280        __(mov temp2,#0)
2281        __(mov temp1,#0)
2282        __(mov temp0,#0)
2283        __(mov arg_x,#TCR_STATE_LISP)
2284        __(str arg_x,[rcontext,#tcr.valence])
2285        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2286        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2287        __(ldr fn,[sp,#lisp_frame.savefn])
2288        __(ldr lr,[sp,#lisp_frame.savelr])
2289        __(discard_lisp_frame())
2290        __(bx lr)
2291
2292
2293/* arg_z should be of type (UNSIGNED-BYTE 64);  */
2294/* return high 32 bits in imm1, low 32 bits in imm0 */
2295
2296
2297_spentry(getu64)
2298        __(test_fixnum(arg_z))
2299        __(bne 1f)
2300        __(unbox_fixnum(imm0,arg_z))
2301        __(movs imm1,imm0,asr #31)
2302        __(bxeq lr)
23030:             
2304        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
23051:
2306        __(extract_typecode(imm0,arg_z))
2307        __(cmp imm0,#subtag_bignum)
2308        __(bne 0b)
2309        __(movc16(imm1,two_digit_bignum_header))
2310        __(getvheader(imm0,arg_z))
2311        __(cmp imm0,imm1)
2312        __(bne 2f)
2313        __(vrefr(imm0,arg_z,0))
2314        __(vrefr(imm1,arg_z,1))
2315        __(cmp imm1,#0)
2316        __(bxge lr)
2317        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
23182:      __(movc16(imm1,three_digit_bignum_header))
2319        __(cmp imm0,imm1)
2320        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u64))
2321        __(vrefr(imm2,arg_z,2))
2322        __(cmp imm2,#0)
2323        __(vrefr(imm1,arg_z,1))
2324        __(vrefr(imm0,arg_z,0))
2325        __(bxeq lr)
2326        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
2327
2328         
2329/* arg_z should be of type (SIGNED-BYTE 64);  */
2330/*    return high 32 bits  in imm1, low 32 bits in imm0  */
2331
2332_spentry(gets64)
2333        __(test_fixnum(arg_z))
2334        __(moveq imm0,arg_z,asr #fixnumshift)
2335        __(moveq imm1,imm0,asr #31)
2336        __(bxeq lr)
2337        __(mov imm2,#0)
2338        __(extract_lisptag(imm0,arg_z))
2339        __(cmp imm0,#tag_misc)
2340        __(ldreq imm2,[arg_z,#misc_header_offset])
2341        __(movc16(imm1,two_digit_bignum_header))
2342        __(cmp imm1,imm2)
2343        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s64))
2344        __(vrefr(imm1,arg_z,1))
2345        __(vrefr(imm0,arg_z,0))
2346        __(bx lr)
2347
2348
2349/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
2350/* unbound_marker), arg_y = symbol, imm1 = symbol.binding-index  */
2351_spentry(specref)
2352        __(ldr imm1,[arg_z,#symbol.binding_index])
2353        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2354        __(cmp imm1,imm0)
2355        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
2356        __(mov arg_y,arg_z)
2357        __(movhs imm1,#0)
2358        __(ldr arg_z,[temp0,imm1])
2359        __(cmp arg_z,#no_thread_local_binding_marker)
2360        __(ldreq arg_z,[arg_y,#symbol.vcell])
2361        __(bx lr)
2362
2363_spentry(specrefcheck)
2364        __(ldr imm1,[arg_z,#symbol.binding_index])
2365        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2366        __(cmp imm1,imm0)
2367        __(movhs imm1,#0)
2368        __(ldr imm0,[rcontext,#tcr.tlb_pointer])
2369        __(mov arg_y,arg_z)
2370        __(ldr arg_z,[imm0,imm1])
2371        __(cmp arg_z,#no_thread_local_binding_marker)
2372        __(ldreq arg_z,[arg_y,#symbol.vcell])
2373        __(cmp arg_z,#unbound_marker)
2374        __(uuo_error_unbound(eq,arg_y))
2375        __(bx lr)
2376
2377/* arg_y = special symbol, arg_z = new value.          */
2378_spentry(specset)
2379        __(ldr imm1,[arg_y,#symbol.binding_index])
2380        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2381        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
2382        __(cmp imm1,imm0)
2383        __(movge imm1,#0)
2384        __(ldr temp1,[imm2,imm1])
2385        __(cmp temp1,#no_thread_local_binding_marker)
2386        __(strne arg_z,[imm2,imm1])
2387        __(bxne lr)
2388        __(mov arg_x,arg_y)
2389        __(mov arg_y,#symbol.vcell-misc_data_offset)
2390        __(b _SPgvset)
2391
2392
2393       
2394/* Construct a lisp integer out of the 32-bit signed value in imm0 */
2395/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
2396
2397_spentry(gets32)
2398        __(test_fixnum(arg_z))
2399        __(moveq imm0,arg_z,asr #fixnumshift)
2400        __(bxeq lr)
2401        __(extract_lisptag(imm0,arg_z))
2402        __(cmp imm0,#tag_misc)
2403        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s32))
2404        __(getvheader(imm0,arg_z))
2405        __(movc16(imm1,one_digit_bignum_header))
2406        __(cmp imm0,imm1)
2407        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s32))
2408        __(vrefr(imm0,arg_z,0))
2409        __(bx lr)       
2410
2411
2412/*  */
2413/* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
2414/*  */
2415
2416_spentry(getu32)
2417        __(test_fixnum(arg_z))
2418        __(moveq imm0,arg_z,asr #fixnumshift)
2419        __(movseq imm1,imm0,asr #31)
2420        __(bxeq lr)
2421        __(movc16(imm1,one_digit_bignum_header))
2422        __(extract_lisptag(imm0,arg_z))
2423        __(cmp imm0,#tag_misc)
2424        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
2425        __(getvheader(imm0,arg_z))
2426        __(cmp imm0,imm1)
2427        __(ldreq imm0,[arg_z,#misc_data_offset])
2428        __(beq 7f)
2429        __(movc16(imm1,two_digit_bignum_header))
2430        __(cmp imm0,imm1)
2431        __(ldreq imm0,[arg_z,#misc_data_offset])
2432        __(ldreq imm1,[arg_z,#misc_data_offset+4])
2433        __(cmpeq imm1,#0)
2434        __(bxeq lr)
2435        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
24367:             
2437        __(movs imm1,imm0,asr #31)
2438        __(bxeq lr)
2439        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
2440
2441
2442/* */
2443/* As per mvpass above, but in this case fname is known to be a */
2444/* symbol. */
2445
2446_spentry(mvpasssym)
2447        __(cmp nargs,#node_size*nargregs)
2448        __(mov imm1,vsp)
2449        __(subgt imm1,imm1,#node_size*nargregs)
2450        __(addgt imm1,imm1,nargs)
2451        __(build_lisp_frame(imm0,imm1))
2452        __(ref_global(lr,ret1val_addr,imm0))
2453        __(mov fn,#0)
2454        __(jump_fname())
2455
2456_spentry(unbind)
2457        __(ldr imm1,[rcontext,#tcr.db_link])
2458        __(ldr temp0,[rcontext,#tcr.tlb_pointer])   
2459        __(ldr imm0,[imm1,#binding.sym])
2460        __(ldr temp1,[imm1,#binding.val])
2461        __(ldr imm1,[imm1,#binding.link])
2462        __(str temp1,[temp0,imm0])
2463        __(str imm1,[rcontext,#tcr.db_link])
2464        __(bx lr)
2465
2466/* Clobbers imm1,temp0,arg_x, arg_y */       
2467_spentry(unbind_n)
2468        __(ldr imm1,[rcontext,#tcr.db_link])
2469        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
24701:      __(ldr temp0,[imm1,#binding.sym])
2471        __(ldr arg_y,[imm1,#binding.val])
2472        __(ldr imm1,[imm1,#binding.link])
2473        __(subs imm0,imm0,#1)
2474        __(str arg_y,[arg_x,temp0])
2475        __(bne 1b)
2476        __(str imm1,[rcontext,#tcr.db_link])
2477        __(bx lr)
2478
2479/* */
2480/* Clobbers imm1,temp0,arg_x, arg_y */
2481
2482_spentry(unbind_to)
2483        do_unbind_to(imm1,temp1,arg_x,arg_y)
2484        __(bx lr)
2485 
2486
2487 
2488/* */
2489/* Restore the special bindings from the top of the tstack,  */
2490/* leaving the tstack frame allocated.  */
2491/* Note that there might be 0 saved bindings, in which case  */
2492/* do nothing.  */
2493/* Note also that this is -only- called from an unwind-protect  */
2494/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
2495/* values in a frame on top of the tstack.  */
2496/*  */
2497                         
2498_spentry(progvrestore)
2499        __(skip_stack_vector(imm0,imm1,sp))
2500        /* There might be a lisp_frame at imm0.  Not sure */
2501        __(ldr imm0,[imm0,#node_size]) /* or maybe node_size+lisp_frame.size */
2502        __(cmp imm0,#0)
2503        __(unbox_fixnum(imm0,imm0))
2504        __(bne _SPunbind_n)
2505        __(bx lr)
2506
2507/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
2508/* for pending interrupts after doing so.  */
2509_spentry(bind_interrupt_level_0)
2510        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2511        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2512        __(ldr imm0,[rcontext,#tcr.db_link])
2513        __(cmp temp0,#0)
2514        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2515        __(vpush1(temp0))
2516        __(vpush1(imm1))
2517        __(vpush1(imm0))
2518        __(mov imm0,#0)
2519        __(str imm0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2520        __(str vsp,[rcontext,#tcr.db_link])
2521        __(bxeq lr)
2522        __(ldrlt temp0,[rcontext,#tcr.interrupt_pending])
2523        __(cmp temp0,#0)
2524        __(uuo_interrupt_now(gt))
2525        __(bx lr)
2526       
2527/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
2528/* of disabling interrupts.)  */
2529_spentry(bind_interrupt_level_m1)
2530        __(mov imm2,#-fixnumone)
2531        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2532        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2533        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2534        __(ldr imm0,[rcontext,#tcr.db_link])
2535        __(vpush1(temp0))
2536        __(vpush1(imm1))
2537        __(vpush1(imm0))
2538        __(str imm2,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2539        __(str vsp,[rcontext,tcr.db_link])
2540        __(bx lr)
2541       
2542
2543/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
2544/* do what _SPbind_interrupt_level_0 does  */
2545_spentry(bind_interrupt_level)
2546        __(cmp arg_z,#0)
2547        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2548        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2549        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2550        __(ldr imm0,[rcontext,#tcr.db_link])
2551        __(beq _SPbind_interrupt_level_0)
2552        __(vpush1(temp0))
2553        __(vpush1(imm1))
2554        __(vpush1(imm0))
2555        __(str arg_z,[temp1,INTERRUPT_LEVEL_BINDING_INDEX])
2556        __(str vsp,[rcontext,#tcr.db_link])
2557        __(bx lr)
2558
2559/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
2560/* non-negative, check for pending interrupts.  This is often called in */
2561/* a context where nargs is significant, so save and restore nargs around */
2562/* any interrupt polling  */
2563         
2564_spentry(unbind_interrupt_level)
2565        __(ldr imm0,[rcontext,#tcr.flags])
2566        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
2567        __(tst imm0,#1<<TCR_FLAG_BIT_PENDING_SUSPEND)
2568        __(ldr imm0,[rcontext,#tcr.db_link])
2569        __(ldr temp0,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2570        __(bne 5f)
25710:     
2572        __(ldr temp1,[imm0,#binding.val])
2573        __(ldr imm0,[imm0,#binding.link])
2574        __(str temp1,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2575        __(str imm0,[rcontext,#tcr.db_link])
2576        __(cmp temp0,#0)
2577        __(bxge lr)
2578        __(cmp temp1,#0)
2579        __(bxlt lr)
2580        __(check_enabled_pending_interrupt(imm0))
2581        __(bx lr)
25825:       /* Missed a suspend request; force suspend now if we're restoring
2583          interrupt level to -1 or greater */
2584        __(cmp temp0,#-2<<fixnumshift)
2585        __(bne 0b)
2586        __(ldr imm0,[imm1,#binding.val])
2587        __(cmp imm0,temp0)
2588        __(beq 0b)
2589        __(mov imm0,#1<<fixnumshift)
2590        __(str imm0,[temp2,INTERRUPT_LEVEL_BINDING_INDEX])
2591        __(suspend_now())
2592        __(b 0b)
2593 
2594 
2595/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
2596    We don't know whether the array is alleged to be simple or
2597   not, and don't know anythng about the element type.  */
2598_spentry(aref2)
2599        __(trap_unless_fixnum(arg_y))
2600        __(trap_unless_fixnum(arg_z))
2601        __(extract_typecode(imm2,arg_x))
2602        __(cmp imm2,#subtag_arrayH)
2603        __(ldreq imm1,[arg_x,#arrayH.rank])
2604        __(cmpeq imm1,#2<<fixnumshift)
2605        __(uuo_error_reg_not_xtype(ne,arg_x,xtype_array2d))
2606        /* It's a 2-dimensional array.  Check bounds */
2607        __(ldr imm0,[arg_x,#arrayH.dim0])
2608        __(cmp arg_y,imm0)
2609        __(uuo_error_array_bounds(hs,arg_y,arg_x))
2610        __(ldr imm0,[arg_x,#arrayH.dim0+node_size])
2611        __(cmp arg_z,imm0)
2612        __(uuo_error_array_bounds(hs,arg_z,arg_x))
2613        __(unbox_fixnum(imm0,imm0))
2614        __(mul temp0,arg_y,imm0) /* no MLA on ARMv5 */
2615        __(add arg_z,arg_z,temp0)
2616        /* arg_z is now row-major-index; get data vector and
2617           add in possible offset */
2618        __(mov arg_y,arg_x)
26190:      __(ldr imm0,[arg_y,#arrayH.displacement])
2620        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2621        __(extract_subtag(imm1,arg_y))
2622        __(cmp imm1,#subtag_vectorH)
2623        __(add arg_z,arg_z,imm0)
2624        __(bgt C(misc_ref_common))
2625        __(b 0b)
2626 
2627/* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
2628_spentry(aref3)
2629        __(trap_unless_fixnum(arg_x))
2630        __(trap_unless_fixnum(arg_y))
2631        __(trap_unless_fixnum(arg_z))
2632        __(extract_typecode(imm2,temp0))
2633        __(mov imm1,#0)
2634        __(cmp imm2,#subtag_arrayH)
2635        __(ldreq imm1,[temp0,#arrayH.rank])
2636        __(cmp imm1,#3<<fixnumshift)
2637        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array3d))
2638        /* It's a 3-dimensional array.  Check bounds */
2639        __(ldr imm2,[temp0,arrayH.dim0+(node_size*2)])
2640        __(ldr imm1,[temp0,#arrayH.dim0+node_size])
2641        __(ldr imm0,[temp0,#arrayH.dim0])
2642        __(cmp arg_z,imm2)
2643        __(uuo_error_array_bounds(hs,arg_z,temp0))
2644        __(cmp arg_y,imm1)
2645        __(uuo_error_array_bounds(hs,arg_y,temp0))
2646        __(cmp arg_x,imm0)
2647        __(uuo_error_array_bounds(hs,arg_x,temp0))
2648        __(unbox_fixnum(imm2,imm2))
2649        __(unbox_fixnum(imm1,imm1))
2650        __(mul arg_y,imm2,arg_y)
2651        __(mul imm1,imm2,imm1)
2652        __(mul arg_x,imm1,arg_x)
2653        __(add arg_z,arg_z,arg_y)
2654        __(add arg_z,arg_z,arg_x)
2655        __(mov arg_y,temp0)
26560:      __(ldr arg_x,[arg_y,#arrayH.displacement])
2657        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2658        __(extract_subtag(imm1,arg_y))
2659        __(cmp imm1,#subtag_vectorH)
2660        __(add arg_z,arg_x,arg_z)
2661        __(bgt C(misc_ref_common))
2662        __(b 0b)
2663
2664
2665
2666
2667/* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
2668_spentry(aset2)
2669        __(extract_typecode(imm0,temp0))
2670        __(cmp imm0,#subtag_arrayH)
2671        __(ldreq imm0,[temp0,#arrayH.rank])
2672        __(cmpeq imm0,#2<<fixnumshift)
2673        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array2d))
2674        __(trap_unless_fixnum(arg_x))
2675        __(trap_unless_fixnum(arg_y))
2676        /* It's a 2-dimensional array.  Check bounds */
2677        __(ldr imm0,[temp0,#arrayH.dim0])
2678        __(cmp arg_x,imm0)
2679        __(uuo_error_array_bounds(hs,arg_x,temp0))
2680        __(ldr imm0,[temp0,#arrayH.dim0+node_size])
2681        __(cmp arg_y,imm0)
2682        __(uuo_error_array_bounds(hs,arg_y,temp0))
2683        __(unbox_fixnum(imm0,imm0))
2684        __(mul temp1,arg_x,imm0)
2685        __(add arg_y,arg_y,temp1)
2686        /* arg_y is now row-major-index; get data vector and
2687           add in possible offset */
2688        __(mov arg_x,temp0)
26890:      __(ldr imm0,[arg_x,#arrayH.displacement])
2690        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2691        __(extract_subtag(imm1,arg_x))
2692        __(cmp imm1,#subtag_vectorH)
2693        __(add arg_y,arg_y,imm0)
2694        __(bgt C(misc_set_common))
2695        __(b 0b)
2696
2697                 
2698/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
2699_spentry(aset3)
2700        __(extract_typecode(imm0,temp1))
2701        __(cmp imm0,#subtag_arrayH)
2702        __(ldreq imm0,[temp1,#arrayH.rank])
2703        __(cmpeq imm0,#3<<fixnumshift)
2704        __(uuo_error_reg_not_xtype(ne,temp1,xtype_array3d))
2705        __(trap_unless_fixnum(temp0))
2706        __(trap_unless_fixnum(arg_x))
2707        __(trap_unless_fixnum(arg_y))
2708        /* It's a 3-dimensional array.  Check bounds */
2709        __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)])
2710        __(ldr imm1,[temp1,#arrayH.dim0+node_size])
2711        __(ldr imm0,[temp1,#arrayH.dim0])
2712        __(cmp arg_y,imm2)
2713        __(uuo_error_array_bounds(hs,arg_y,temp1))
2714        __(cmp arg_x,imm1)
2715        __(uuo_error_array_bounds(hs,arg_x,temp1))
2716        __(unbox_fixnum(imm1,imm1))
2717        __(cmp temp0,imm0)
2718        __(uuo_error_array_bounds(hs,temp0,temp1))
2719        __(mul arg_x,imm2,arg_x)
2720        __(mul imm1,imm2,imm1)
2721        __(mul temp0,imm1,temp0)
2722        __(add arg_y,arg_y,arg_x)
2723        __(add arg_y,arg_y,temp0)
2724        __(mov arg_x,temp1)
27250:      __(ldr temp0,[arg_x,#arrayH.displacement])
2726        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2727        __(extract_subtag(imm1,arg_x))
2728        __(cmp imm1,#subtag_vectorH)
2729        __(add arg_y,arg_y,temp0)
2730        __(bgt C(misc_set_common))
2731        __(b 0b)
2732
2733
2734/* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
2735/* pairs.  There'll be arg_z keyword arguments.  arg_y contains flags  */
2736/* that indicate whether &allow-other-keys was specified and whether  */
2737/* or not to leave the keyword/value pairs on the vstack for an &rest  */
2738/* argument.  Element 2 of the function in fn contains a vector of keyword.  */
2739/* If the number of arguments is greater than imm0, the difference must  */
2740/* be even.  */
2741/* All arg regs have been vpushed and the calling function has built a */
2742/* stack frame.  next_method_context must be preserved, as must the incoming */
2743/* key/value pairs and their number if we're going to make an &rest arg. */
2744           
2745
2746define(`keyword_flags',`arg_y')
2747define(`key_value_count',`arg_z')
2748
2749define(`keyword_flag_allow_other_keys',`(1<<fixnumshift)')
2750define(`keyword_flag_seen_allow_other_keys',`(2<<fixnumshift)')
2751define(`keyword_flag_unknown_keyword_seen',`(3<<fixnumshift)')
2752define(`keyword_flag_rest',`(4<<fixnumshift)')
2753
2754_spentry(keyword_bind)
2755        new_local_labels()       
2756        __(subs key_value_count,nargs,imm0)
2757        __(movmi key_value_count,#0)
2758        __(tst key_value_count,#fixnumone)
2759        __(bne local_label(odd_keywords))
2760        __(mov imm1,key_value_count,lsl #num_subtag_bits-fixnumshift)
2761        __(orr imm1,imm1,subtag_u32_vector)
2762        __(add imm0,key_value_count,#dnode_size) /* we know  count is even */
2763        __(stack_allocate_zeroed_ivector(imm1,imm0))
2764        __(mov imm0,#subtag_simple_vector)
2765        __(strb imm0,[sp])
2766        /* Copy key/value pairs in reverse order from the vstack to
2767           the gvector we just created on the cstack. */
2768        __(add imm0,vsp,key_value_count) /* src, predecrement */
2769        __(add imm1,sp,#node_size)       /* dest, postincrement */
2770        __(mov temp2,key_value_count)
2771        __(b 1f)
27720:      __(ldr arg_x,[imm0,#-node_size]!)
2773        __(str arg_x,[imm1],#node_size)
27741:      __(subs temp2,temp2,#fixnumone)
2775        __(bge 0b)
2776        /* Discard the key/value pairs from the vstack. */
2777        __(add vsp,vsp,key_value_count)
2778        __(ldr temp2,[fn,#misc_data_offset+(2*node_size)])
2779        __(getvheader(imm0,temp2))
2780        __(mov imm0,imm0,lsr #num_subtag_bits)
2781        __(mov temp0,vsp)
2782        __(mov imm1,#nil_value)
2783        /* Push a pair of NILs (value, supplied-p) for each defined keyword */
2784        __(b 3f)
27852:      __(vpush1(imm1))
2786        __(vpush1(imm1))
27873:      __(subs imm0,imm0,#1)
2788        __(bge 2b)
2789        /* Save nargs and temp1 so that we can use them in the loop(s) */
2790        __(stmdb vsp!,{imm2,temp1})
2791        /* For each provided key/value pair: if the key is :allow-other-keys
2792           and that hasn't been seen before, note that it's been seen and
2793           if the value is non-nil set the allow-other-keys bit in flags.
2794           Then search for the key in the defined keys vector.  If it's
2795           not found, note that an undefined keyword was seen by setting
2796           a bit in keyword_flags ; if it is found, use its position to
2797           index the table of value/supplied-p pairs that we pushed above.
2798           If the supplied-p var is already set, do nothing; otherwise,
2799           set the supplied-p var and value.
2800           When done, signal an error if we got an unknown keyword, or
2801           either copy the supplied key/value pairs back to the vstack
2802           if we're going to cons an &rest arg or discard them if we aren't.
2803        */
2804        __(mov imm2,#0)
2805        __(b local_label(nextvalpairtest))
2806local_label(nextvalpairloop):   
2807        __(add temp1,sp,#4)
2808        __(ldr temp1,[temp1,imm2])
2809        __(ref_nrs_symbol(imm1,kallowotherkeys,imm1))
2810        __(cmp temp1,imm1)
2811        __(tsteq keyword_flags,#keyword_flag_seen_allow_other_keys)
2812        __(bne local_label(current_key_allow_other_keys_handled))
2813        __(orr keyword_flags,keyword_flags,#keyword_flag_seen_allow_other_keys)
2814        /* Fortunately, we know what the keyword is.  Need to check the
2815           value here, and don't have a lot of free registers ... */
2816        __(add temp1,sp,#8)
2817        __(ldr temp1,[temp1,imm2])
2818        __(cmp temp1,#nil_value)
2819        __(orrne keyword_flags,keyword_flags,#keyword_flag_allow_other_keys)
2820        __(mov temp1,imm1)      /* from comparison above */
2821local_label(current_key_allow_other_keys_handled):
2822        __(getvheader(imm0,temp1))
2823        __(header_length(arg_x,imm0))
2824        __(add imm0,arg_x,#misc_data_offset)
2825        __(b local_label(defined_keyword_compare_test))
2826local_label(defined_keyword_compare_loop):     
2827        __(ldr arg_x,[temp2,imm0])
2828        __(cmp arg_x,temp1)
2829        __(subeq imm0,imm0,#misc_data_offset)
2830        __(beq local_label(defined_keyword_found))
2831local_label(defined_keyword_compare_test):     
2832        __(sub imm0,imm0,#node_size)
2833        __(cmp imm0,#misc_data_offset)
2834        __(bge local_label(defined_keyword_compare_loop))
2835        /* keyword wasn't defined.  Note that ... */
2836        __(orr keyword_flags,keyword_flags,#keyword_flag_unknown_keyword_seen)
2837        __(b local_label(nextkeyvalpairnext))
2838local_label(defined_keyword_found):     
2839        __(sub imm0,temp0,imm0,lsl #1)
2840        __(ldr arg_x,[imm0,#-8])
2841        __(cmp arg_x,#nil_value) /* seen this keyword yet ? */
2842        __(bne local_label(nextkeyvalpairnext))
2843        __(add arg_x,arg_x,#t_offset)
2844        __(str arg_x,[imm0,#-8])
2845        __(add temp1,sp,#8)
2846        __(ldr temp1,[temp1,imm2])
2847        __(str temp1,[imm0,#-4])
2848local_label(nextkeyvalpairnext):
2849        __(add imm2,imm2,#8)
2850local_label(nextvalpairtest):   
2851        __(cmp imm2,key_value_count)
2852        __(bne local_label(nextvalpairloop))
2853        __(ldmia vsp!,{imm2,temp1})
2854        /* If unknown keywords and that's not allowed, signal error.
2855           Otherwise, discard the stack-consed vector and return,
2856           possibly after having copied the vector's contents back
2857           to the vstack so that an &rest arg can be constructed.
2858        */
2859        __(tst keyword_flags,#keyword_flag_unknown_keyword_seen)
2860        __(beq 0f)
2861        __(tst keyword_flags,#keyword_flag_allow_other_keys)
2862        __(beq local_label(badkeys))
28630:      __(tst keyword_flags,#keyword_flag_rest)
2864        __(beq local_label(discard_stack_vector))
2865        __(mov nargs,#0)
2866        __(add temp2,sp,#node_size)
2867        __(b 2f)
28681:      __(ldr arg_x,[temp2],#node_size)
2869        __(vpush1(arg_x))
2870        __(add nargs,nargs,#fixnumone)
28712:      __(cmp nargs,key_value_count)
2872        __(bne 1b)
2873local_label(discard_stack_vector):     
2874        __(add key_value_count,key_value_count,#dnode_size)
2875        __(add sp,sp,key_value_count)
2876        __(bx lr)               /* it's finally over ! */
2877
2878local_label(badkeys):   /* Disturbingly similar to the &rest case */
2879        __(mov nargs,#0)
2880        __(add temp2,sp,#node_size)
2881        __(mov vsp,temp0)
2882        __(b 1f)
28830:      __(ldr arg_x,[temp2],#node_size)
2884        __(vpush1(arg_x))
2885        __(add nargs,nargs,#fixnumone)
28861:      __(cmp nargs,key_value_count)
2887        __(bne 0b)
2888        /* Lose the stack vector */
2889        __(add key_value_count,key_value_count,#dnode_size)
2890        __(add sp,sp,key_value_count)
2891local_label(error_exit):               
2892        __(bl _SPconslist)
2893        __(mov arg_y,#XBADKEYS)
2894        __(set_nargs(2))
2895        __(b _SPksignalerr)
2896local_label(odd_keywords):       
2897        __(mov nargs,key_value_count)
2898        __(b local_label(error_exit))
2899
2900        .globl C(__aeabi_uidivmod)               
2901_spentry(udiv32)
2902        __(cmp imm1,#0)
2903        __(moveq arg_z,#XDIVZRO)
2904        __(moveq nargs,#1<<fixnumshift)
2905        __(beq _SPksignalerr)
2906        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2907        __(str vsp,[rcontext,#tcr.save_vsp])
2908        __(mov arg_z,rcontext)
2909        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2910        __(build_lisp_frame(r3))
2911        __(str sp,[arg_z,#tcr.last_lisp_frame])
2912        __(str allocptr,[arg_z,#tcr.save_allocptr])
2913        __(mov r3,#TCR_STATE_FOREIGN)
2914        __(str r3,[arg_z,#tcr.valence])
2915        __(mov r3,#0)
2916        __(bl C(__aeabi_uidivmod))
2917        __(mov rcontext,arg_z)
2918        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2919        __(mov allocptr,#VOID_ALLOCPTR)
2920        __(mov fn,#0)
2921        __(mov temp2,#0)
2922        __(mov temp1,#0)
2923        __(mov temp0,#0)
2924        __(mov arg_x,#TCR_STATE_LISP)
2925        __(str arg_x,[rcontext,#tcr.valence])
2926        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2927        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2928        __(ldr fn,[sp,#lisp_frame.savefn])
2929        __(ldr lr,[sp,#lisp_frame.savelr])
2930        __(discard_lisp_frame())
2931        __(bx lr)
2932
2933_spentry(sdiv32)
2934        __(build_lisp_frame(imm2))
2935pushdef(`sign',`temp0')
2936pushdef(`d',`r0')
2937pushdef(`r',`r1')               
2938        __(ands sign,d,#0x80000000)
2939        __(rsbmi d,d,#0)
2940        __(eors sign,sign,r,asr #32)
2941        __(rsbcs r,r,#0)
2942        __(bl _SPudiv32)
2943        __(movs sign,sign,lsl #1)
2944        __(rsbcs d,d,#0)
2945        __(rsbmi r,r,#0)
2946        __(return_lisp_frame(imm2))
2947popdef(`sign')
2948popdef(`d',)
2949popdef(`r',)               
2950       
2951
2952               
2953_spentry(eabi_ff_call)
2954        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2955        __(stmdb vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2956        __(str vsp,[rcontext,#tcr.save_vsp])
2957/* There's a u32 vector on top of the stack ; its first data word points
2958   to the previous stack object.  The 4 words at the bottom of the vector
2959   are reserved for a lisp frame, which we construct carefully ... */
2960        __(mov imm0,#lisp_frame_marker)
2961        __(mov imm1,#0)
2962        __(ldr temp0,[sp,#4])
2963        __(sub temp0,temp0,#lisp_frame.size)
2964        __(str imm0,[temp0,#lisp_frame.marker])
2965        __(ldr imm0,[sp,#0])       
2966        __(str imm1,[temp0,#lisp_frame.savefn])
2967        __(str imm1,[temp0,#lisp_frame.savelr])
2968        __(sub imm0,imm0,#(lisp_frame.size/4)<<num_subtag_bits)
2969        __(str vsp,[temp0,#lisp_frame.savevsp])
2970        __(str imm0,[sp,#0])
2971        __(str lr,[temp0,#lisp_frame.savelr])
2972        __(str fn,[temp0,#lisp_frame.savefn])
2973        __(str allocptr,[rcontext,#tcr.save_allocptr])
2974        __(str temp0,[rcontext,#tcr.last_lisp_frame])
2975        __(mov temp0,rcontext)
2976        __(test_fixnum(arg_z))
2977        __(moveq imm1,arg_z,asr #fixnumshift)
2978        __(ldrne imm1,[arg_z,#misc_data_offset])
2979        __(mov imm0,#TCR_STATE_FOREIGN)
2980        __(str imm0,[rcontext,#tcr.valence])
2981        __(mov r4,imm1)
2982        __(add sp,sp,#dnode_size)
2983        __(ldmia sp!,{r0,r1,r2,r3})
2984        __(blx r4)
2985        __(mov temp1,#0)
2986        __(mov temp2,#0)
2987        __(mov arg_z,#0)
2988        __(mov arg_y,#0)
2989        __(mov arg_x,#0)
2990        __(mov fn,#0)
2991        __(mov allocptr,#VOID_ALLOCPTR)
2992        __(mov rcontext,temp0)
2993        __(ldr sp,[rcontext,#tcr.last_lisp_frame])
2994        __(str fn,[rcontext,#tcr.valence])
2995        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2996        __(restore_lisp_frame(temp0))
2997        __(ldmia vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2998        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2999        __(bx lr)
3000       
3001       
3002
3003_spentry(debind)
3004        new_local_labels()
3005        __(mov temp0,vsp)
3006        __(mov temp1,arg_z)
3007        __(ands imm0,nargs,#0xff)
3008        __(mov arg_y,#nil_value)
3009        __(b local_label(req_test))
3010local_label(req_loop): 
3011        __(cmp arg_reg,#nil_value)
3012        __(extract_lisptag(imm1,arg_reg))
3013        __(beq local_label(toofew))
3014        __(cmp imm1,#tag_list)
3015        __(bne local_label(badlist))
3016        __(subs imm0,imm0,#1)
3017        __(_car(arg_x,arg_reg))
3018        __(_cdr(arg_reg,arg_reg))
3019        __(vpush1(arg_x))
3020local_label(req_test):
3021        __(bne local_label(req_loop))
3022        __(mov imm0,#0xff)
3023        __(ands imm0,imm0,nargs,lsr #8)
3024        __(beq local_label(rest_keys))
3025        __(tst nargs,#mask_initopt)
3026        __(bne local_label(opt_supp))
3027        /* 'simple' &optionals:  no supplied-p, default to nil.   */
3028local_label(simple_opt_loop):
3029        __(cmp arg_reg,#nil_value)
3030        __(extract_lisptag(imm1,arg_reg))
3031        __(beq local_label(default_simple_opt))
3032        __(cmp imm1,#tag_list)
3033        __(bne local_label(badlist))
3034        __(subs imm0,imm0,#1)
3035        __(_car(arg_x,arg_reg))
3036        __(_cdr(arg_reg,arg_reg))
3037        __(vpush1(arg_x))
3038        __(bne local_label(simple_opt_loop))
3039        __(b local_label(rest_keys))
3040local_label(default_simple_opt):       
3041        __(subs imm0,imm0,#1)
3042        __(vpush1(arg_y))
3043        __(bne local_label(default_simple_opt))
3044        __(b local_label(rest_keys))
3045local_label(opt_supp):   
3046        __(cmp arg_reg,#nil_value)
3047        __(extract_lisptag(imm1,arg_reg))
3048        __(beq local_label(default_hard_opt))
3049        __(cmp imm1,#tag_list)
3050        __(bne local_label(badlist))
3051        __(subs imm0,imm0,#1)
3052        __(_car(arg_x,arg_reg))
3053        __(_cdr(arg_reg,arg_reg))
3054        __(vpush1(arg_x))
3055        __(add arg_x,arg_y,#t_offset)
3056        __(vpush1(arg_x))
3057        __(bne local_label(opt_supp))
3058        __(b local_label(rest_keys))
3059local_label(default_hard_opt): 
3060        __(subs imm0,imm0,#1)
3061        __(vpush1(arg_y))
3062        __(vpush1(arg_y))
3063        __(bne local_label(default_hard_opt))
3064local_label(rest_keys):
3065        __(tst nargs,#mask_restp)
3066        __(bne local_label(have_rest))
3067        __(tst nargs,#mask_keyp)
3068        __(bne local_label(have_keys))
3069        __(cmp arg_reg,#nil_value)
3070        __(bne local_label(toomany))
3071        __(bx lr)
3072local_label(have_rest):
3073        __(vpush1(arg_reg))
3074        __(tst nargs,#mask_keyp)
3075        __(bne local_label(have_keys))
3076        __(bx lr)
3077local_label(have_keys):
3078        __(mov imm0,#256)
3079        __(mov arg_y,arg_reg)
3080local_label(count_keys_loop):   
3081        __(cmp arg_y,#nil_value)
3082        __(beq local_label(counted_keys))
3083        __(subs imm0,imm0,#1)
3084        __(bmi local_label(toomany))
3085        __(extract_lisptag(imm1,arg_y))
3086        __(cmp imm1,#tag_list)
3087        __(bne local_label(badlist))
3088        __(_cdr(arg_y,arg_y))
3089        __(extract_lisptag(imm1,arg_y))
3090        __(cmp imm1,#tag_list)
3091        __(bne local_label(badlist))
3092        __(_cdr(arg_y,arg_y))
3093        __(b local_label(count_keys_loop))
3094local_label(counted_keys):     
3095        /* We've got a proper, even-length list of key/value pairs in  */
3096        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
3097        /* of NILs on the vstack.  (We've also cdred down arg_y until it */
3098        /* contains NIL.) */
3099        __(mov imm0,#0xff)
3100        __(ands imm0,imm0,nargs,lsr #16)
3101        __(mov imm1,vsp)
3102        __(b local_label(push_pair_test))
3103local_label(push_pair_loop):
3104        __(subs imm0,imm0,#1)
3105        __(vpush1(arg_y))
3106        __(vpush1(arg_y))
3107local_label(push_pair_test):   
3108        __(bne local_label(push_pair_loop))
3109        __(b local_label(provided_key_loop))
3110       
3111local_label(next_provided_key):
3112        __(_car(arg_x,arg_reg))
3113        __(ref_nrs_symbol(imm0,kallowotherkeys,imm0))
3114        __(cmp arg_x,imm0)
3115        __(bne local_label(not_aok))
3116        __(tst nargs,#mask_aok_seen)
3117        __(beq local_label(not_aok))
3118        __(_cdr(arg_x,arg_reg))
3119        __(_car(arg_x,arg_x))
3120        __(orr nargs,nargs,#mask_aok_seen)
3121        __(cmp arg_x,#nil_value)
3122        __(orrne nargs,nargs,#mask_aok)
3123        __(_car(arg_x,arg_reg))
3124local_label(not_aok):   
3125        __(getvheader(imm0,keyvect_reg))
3126        __(header_length(arg_y,imm0))
3127        __(add imm0,arg_y,#misc_data_offset)
3128        __(b local_label(match_key_test))
3129local_label(match_key_loop):   
3130        __(ldr arg_y,[keyvect_reg,imm0])
3131        __(cmp arg_x,arg_y)
3132        __(bne local_label(match_key_test))
3133        __(sub imm0,imm0,#misc_data_offset)
3134        __(sub imm0,imm1,imm0,lsl #1)
3135        __(ldr arg_y,[imm0,#-node_size])
3136        __(cmp arg_y,#nil_value)
3137        __(beq local_label(provided_key_done))
3138        __(_cdr(arg_x,arg_reg))
3139        __(_car(arg_x,arg_x))
3140        __(str arg_x,[imm0,#0])
3141        __(mov arg_x,#nil_value)
3142        __(add arg_x,arg_x,#t_offset)
3143        __(str arg_x,[imm0,#-node_size])
3144        __(b local_label(provided_key_done))
3145local_label(match_key_test):   
3146        __(sub imm0,imm0,#node_size)
3147        __(cmp imm0,#misc_data_offset)
3148        __(bge local_label(match_key_loop))
3149        __(orr nargs,nargs,#mask_unknown_keyword_seen)
3150local_label(provided_key_done):
3151        __(_cdr(arg_reg,arg_reg))
3152        __(_cdr(arg_reg,arg_reg))
3153local_label(provided_key_loop):
3154        __(cmp arg_reg,#nil_value)
3155        __(bne local_label(next_provided_key))
3156        __(tst nargs,#mask_unknown_keyword_seen)
3157        __(bxeq lr)
3158        __(tst nargs,#mask_aok)
3159        __(bxne lr)
3160local_label(badkeys):
3161        __(mov arg_y,#XBADKEYS)
3162        __(b local_label(destructure_error))
3163local_label(toomany):   
3164        __(mov arg_y,#XCALLTOOMANY)
3165        __(b local_label(destructure_error))
3166local_label(toofew):   
3167        __(mov arg_y,#XCALLTOOFEW)
3168        __(b local_label(destructure_error))
3169local_label(badlist):   
3170        __(mov arg_y,#XCALLNOMATCH)
3171local_label(destructure_error):
3172        __(mov vsp,temp0)
3173        __(mov arg_z,temp1)       
3174        __(set_nargs(2))
3175        __(b _SPksignalerr)
3176       
3177
3178/*  EOF, basically  */
3179       
3180_exportfn(C(misc_ref_common))
3181        __(adr imm0,(local_label(misc_ref_jmp)))
3182        __(ldr pc,[imm0,imm1,lsl #2])       
3183
3184local_label(misc_ref_jmp):         
3185        /* 00-0f  */
3186        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
3187       
3188        .long local_label(misc_ref_invalid) /* 01 cons  */
3189        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
3190        .long local_label(misc_ref_invalid) /* 03 imm  */
3191        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
3192        .long local_label(misc_ref_invalid) /* 05 nil  */
3193        .long local_label(misc_ref_invalid) /* 06 misc  */
3194        .long local_label(misc_ref_u32) /* 07 bignum  */
3195        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
3196        .long local_label(misc_ref_invalid) /* 09 cons  */
3197        .long local_label(misc_ref_node) /* 0a ratio  */
3198        .long local_label(misc_ref_invalid) /* 0b imm  */
3199        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
3200        .long local_label(misc_ref_invalid) /* 0d nil  */
3201        .long local_label(misc_ref_invalid) /* 0e misc  */
3202        .long local_label(misc_ref_u32) /* 0f single_float  */
3203        /* 10-1f  */
3204        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
3205        .long local_label(misc_ref_invalid) /* 11 cons  */
3206        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
3207        .long local_label(misc_ref_invalid) /* 13 imm  */
3208        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
3209        .long local_label(misc_ref_invalid) /* 15 nil  */
3210        .long local_label(misc_ref_invalid) /* 16 misc  */
3211        .long local_label(misc_ref_u32) /* 17 double_float  */
3212        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
3213        .long local_label(misc_ref_invalid) /* 19 cons  */
3214        .long local_label(misc_ref_node) /* 1a complex  */
3215        .long local_label(misc_ref_invalid) /* 1b imm  */
3216        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
3217        .long local_label(misc_ref_invalid) /* 1d nil  */
3218        .long local_label(misc_ref_invalid) /* 1e misc  */
3219        .long local_label(misc_ref_u32) /* 1f macptr  */
3220        /* 20-2f  */
3221        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
3222        .long local_label(misc_ref_invalid) /* 21 cons  */
3223        .long local_label(misc_ref_node) /* 22 catch_frame  */
3224        .long local_label(misc_ref_invalid) /* 23 imm  */
3225        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
3226        .long local_label(misc_ref_invalid) /* 25 nil  */
3227        .long local_label(misc_ref_invalid) /* 26 misc  */
3228        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
3229        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
3230        .long local_label(misc_ref_invalid) /* 29 cons  */
3231        .long local_label(misc_ref_node) /* 2a function  */
3232        .long local_label(misc_ref_invalid) /* 2b imm  */
3233        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
3234        .long local_label(misc_ref_invalid) /* 2d nil  */
3235        .long local_label(misc_ref_invalid) /* 2e misc  */
3236        .long local_label(misc_ref_u32) /* 2f code_vector  */
3237        /* 30-3f  */
3238        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
3239        .long local_label(misc_ref_invalid) /* 31 cons  */
3240        .long local_label(misc_ref_node) /* 32 lisp_thread  */
3241        .long local_label(misc_ref_invalid) /* 33 imm  */
3242        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
3243        .long local_label(misc_ref_invalid) /* 35 nil  */
3244        .long local_label(misc_ref_invalid) /* 36 misc  */
3245        .long local_label(misc_ref_u32) /* 37 creole  */
3246        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
3247        .long local_label(misc_ref_invalid) /* 39 cons  */
3248        .long local_label(misc_ref_node) /* 3a symbol  */
3249        .long local_label(misc_ref_invalid) /* 3b imm  */
3250        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
3251        .long local_label(misc_ref_invalid) /* 3d nil  */
3252        .long local_label(misc_ref_invalid) /* 3e misc  */
3253        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
3254        /* 40-4f  */
3255        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
3256        .long local_label(misc_ref_invalid) /* 41 cons  */
3257        .long local_label(misc_ref_node) /* 42 lock  */
3258        .long local_label(misc_ref_invalid) /* 43 imm  */
3259        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
3260        .long local_label(misc_ref_invalid) /* 45 nil  */
3261        .long local_label(misc_ref_invalid) /* 46 misc  */
3262        .long local_label(misc_ref_invalid) /* 47 immheader  */
3263        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
3264        .long local_label(misc_ref_invalid) /* 49 cons  */
3265        .long local_label(misc_ref_node) /* 4a hash_vector  */
3266        .long local_label(misc_ref_invalid) /* 4b imm  */
3267        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
3268        .long local_label(misc_ref_invalid) /* 4d nil  */
3269        .long local_label(misc_ref_invalid) /* 4e misc  */
3270        .long local_label(misc_ref_invalid) /* 4f immheader  */
3271        /* 50-5f  */
3272        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
3273        .long local_label(misc_ref_invalid) /* 51 cons  */
3274        .long local_label(misc_ref_node) /* 52 pool  */
3275        .long local_label(misc_ref_invalid) /* 53 imm  */
3276        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
3277        .long local_label(misc_ref_invalid) /* 55 nil  */
3278        .long local_label(misc_ref_invalid) /* 56 misc  */
3279        .long local_label(misc_ref_invalid) /* 57 immheader  */
3280        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
3281        .long local_label(misc_ref_invalid) /* 59 cons  */
3282        .long local_label(misc_ref_node) /* 5a weak  */
3283        .long local_label(misc_ref_invalid) /* 5b imm  */
3284        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
3285        .long local_label(misc_ref_invalid) /* 5d nil  */
3286        .long local_label(misc_ref_invalid) /* 5e misc  */
3287        .long local_label(misc_ref_invalid) /* 5f immheader  */
3288        /* 60-6f  */
3289        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
3290        .long local_label(misc_ref_invalid) /* 61 cons  */
3291        .long local_label(misc_ref_node) /* 62 package  */
3292        .long local_label(misc_ref_invalid) /* 63 imm  */
3293        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
3294        .long local_label(misc_ref_invalid) /* 65 nil  */
3295        .long local_label(misc_ref_invalid) /* 66 misc  */
3296        .long local_label(misc_ref_invalid) /* 67 immheader  */
3297        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
3298        .long local_label(misc_ref_invalid) /* 69 cons  */
3299        .long local_label(misc_ref_node) /* 6a slot_vector  */
3300        .long local_label(misc_ref_invalid) /* 6b imm  */
3301        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
3302        .long local_label(misc_ref_invalid) /* 6d nil  */
3303        .long local_label(misc_ref_invalid) /* 6e misc  */
3304        .long local_label(misc_ref_invalid) /* 6f immheader  */
3305        /* 70-7f  */
3306        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
3307        .long local_label(misc_ref_invalid) /* 71 cons  */
3308        .long local_label(misc_ref_node) /* 72 instance  */
3309        .long local_label(misc_ref_invalid) /* 73 imm  */
3310        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
3311        .long local_label(misc_ref_invalid) /* 75 nil  */
3312        .long local_label(misc_ref_invalid) /* 76 misc  */
3313        .long local_label(misc_ref_invalid) /* 77 immheader  */
3314        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
3315        .long local_label(misc_ref_invalid) /* 79 cons  */
3316        .long local_label(misc_ref_node) /* 7a struct  */
3317        .long local_label(misc_ref_invalid) /* 7b imm  */
3318        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
3319        .long local_label(misc_ref_invalid) /* 7d nil  */
3320        .long local_label(misc_ref_invalid) /* 7e misc  */
3321        .long local_label(misc_ref_invalid) /* 7f immheader  */
3322        /* 80-8f  */
3323        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
3324        .long local_label(misc_ref_invalid) /* 81 cons  */
3325        .long local_label(misc_ref_node) /* 82 istruct  */
3326        .long local_label(misc_ref_invalid) /* 83 imm  */
3327        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
3328        .long local_label(misc_ref_invalid) /* 85 nil  */
3329        .long local_label(misc_ref_invalid) /* 86 misc  */
3330        .long local_label(misc_ref_invalid) /* 87 immheader  */
3331        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
3332        .long local_label(misc_ref_invalid) /* 89 cons  */
3333        .long local_label(misc_ref_node) /* 8a value_cell  */
3334        .long local_label(misc_ref_invalid) /* 8b imm  */
3335        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
3336        .long local_label(misc_ref_invalid) /* 8d nil  */
3337        .long local_label(misc_ref_invalid) /* 8e misc  */
3338        .long local_label(misc_ref_invalid) /* 8f immheader  */
3339        /* 90-9f  */
3340        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
3341        .long local_label(misc_ref_invalid) /* 91 cons  */
3342        .long local_label(misc_ref_node) /* 92 xfunction  */
3343        .long local_label(misc_ref_invalid) /* 93 imm  */
3344        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
3345        .long local_label(misc_ref_invalid) /* 95 nil  */
3346        .long local_label(misc_ref_invalid) /* 96 misc  */
3347        .long local_label(misc_ref_invalid) /* 97 immheader  */
3348        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
3349        .long local_label(misc_ref_invalid) /* 99 cons  */
3350        .long local_label(misc_ref_node) /* 9a arrayN  */
3351        .long local_label(misc_ref_invalid) /* 9b imm  */
3352        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
3353        .long local_label(misc_ref_invalid) /* 9d nil  */
3354        .long local_label(misc_ref_invalid) /* 9e misc  */
3355        .long local_label(misc_ref_invalid) /* 9f immheader  */
3356        /* a0-af  */
3357        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
3358        .long local_label(misc_ref_invalid) /* a1 cons  */
3359        .long local_label(misc_ref_node) /* a2 vectorH  */
3360        .long local_label(misc_ref_invalid) /* a3 imm  */
3361        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
3362        .long local_label(misc_ref_invalid) /* a5 nil  */
3363        .long local_label(misc_ref_invalid) /* a6 misc  */
3364        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
3365        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
3366        .long local_label(misc_ref_invalid) /* a9 cons  */
3367        .long local_label(misc_ref_node) /* aa simple_vector  */
3368        .long local_label(misc_ref_invalid) /* ab imm  */
3369        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
3370        .long local_label(misc_ref_invalid) /* ad nil  */
3371        .long local_label(misc_ref_invalid) /* ae misc  */
3372        .long local_label(misc_ref_u32) /* af u32  */
3373        /* b0-bf  */
3374        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
3375        .long local_label(misc_ref_invalid) /* b1 cons  */
3376        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
3377        .long local_label(misc_ref_invalid) /* b3 imm  */
3378        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
3379        .long local_label(misc_ref_invalid) /* b5 nil  */
3380        .long local_label(misc_ref_invalid) /* b6 misc  */
3381        .long local_label(misc_ref_s32) /* b7 s32  */
3382        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
3383        .long local_label(misc_ref_invalid) /* b9 cons  */
3384        .long local_label(misc_ref_invalid) /* ba nodeheader  */
3385        .long local_label(misc_ref_invalid) /* bb imm  */
3386        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
3387        .long local_label(misc_ref_invalid) /* bd nil  */
3388        .long local_label(misc_ref_invalid) /* be misc  */
3389        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
3390        /* c0-cf  */
3391        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
3392        .long local_label(misc_ref_invalid) /* c1 cons  */
3393        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
3394        .long local_label(misc_ref_invalid) /* c3 imm  */
3395        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
3396        .long local_label(misc_ref_invalid) /* c5 nil  */
3397        .long local_label(misc_ref_invalid) /* c6 misc  */
3398        .long local_label(misc_ref_new_string) /* c7 new_string  */
3399        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
3400        .long local_label(misc_ref_invalid) /* c9 cons  */
3401        .long local_label(misc_ref_invalid) /* ca nodeheader  */
3402        .long local_label(misc_ref_invalid) /* cb imm  */
3403        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
3404        .long local_label(misc_ref_invalid) /* cd nil  */
3405        .long local_label(misc_ref_invalid) /* ce misc  */
3406        .long local_label(misc_ref_u8) /* cf u8  */
3407        /* d0-df  */
3408        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
3409        .long local_label(misc_ref_invalid) /* d1 cons  */
3410        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
3411        .long local_label(misc_ref_invalid) /* d3 imm  */
3412        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
3413        .long local_label(misc_ref_invalid) /* d5 nil  */
3414        .long local_label(misc_ref_invalid) /* d6 misc  */
3415        .long local_label(misc_ref_s8)      /* d7 s8  */
3416        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
3417        .long local_label(misc_ref_invalid) /* d9 cons  */
3418        .long local_label(misc_ref_invalid) /* da nodeheader  */
3419        .long local_label(misc_ref_invalid) /* db imm  */
3420        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
3421        .long local_label(misc_ref_invalid) /* dd nil  */
3422        .long local_label(misc_ref_invalid) /* de misc  */
3423        .long local_label(misc_ref_old_string) /* df (old)subtag_simple_base_string  */
3424        /* e0-ef  */
3425        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
3426        .long local_label(misc_ref_invalid) /* e1 cons  */
3427        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
3428        .long local_label(misc_ref_invalid) /* e3 imm  */
3429        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
3430        .long local_label(misc_ref_invalid) /* e5 nil  */
3431        .long local_label(misc_ref_invalid) /* e6 misc  */
3432        .long local_label(misc_ref_u16) /* e7 u16  */
3433        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
3434        .long local_label(misc_ref_invalid) /* e9 cons  */
3435        .long local_label(misc_ref_invalid) /* ea nodeheader  */
3436        .long local_label(misc_ref_invalid) /* eb imm  */
3437        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
3438        .long local_label(misc_ref_invalid) /* ed nil  */
3439        .long local_label(misc_ref_invalid) /* ee misc  */
3440        .long local_label(misc_ref_s16) /* ef s16  */
3441        /* f0-ff  */
3442        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
3443        .long local_label(misc_ref_invalid) /* f1 cons  */
3444        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
3445        .long local_label(misc_ref_invalid) /* f3 imm  */
3446        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
3447        .long local_label(misc_ref_invalid) /* f5 nil  */
3448        .long local_label(misc_ref_invalid) /* f6 misc  */
3449        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
3450        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
3451        .long local_label(misc_ref_invalid) /* f9 cons  */
3452        .long local_label(misc_ref_invalid) /* fa nodeheader  */
3453        .long local_label(misc_ref_invalid) /* fb imm  */
3454        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
3455        .long local_label(misc_ref_invalid) /* fd nil  */
3456        .long local_label(misc_ref_invalid) /* fe misc  */
3457        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
3458
3459local_label(misc_ref_node):       
3460        /* A node vector.  */
3461        __(add imm0,arg_z,#misc_data_offset)
3462        __(ldr  arg_z,[arg_y,imm0])
3463        __(bx lr)
3464local_label(misc_ref_single_float_vector):       
3465        __(add imm0,arg_z,misc_data_offset)
3466        __(movc16(imm1,single_float_header))
3467        __(ldr imm0,[arg_y,imm0])
3468        __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
3469        __(str imm0,[arg_z,#single_float.value])
3470        __(bx lr)
3471local_label(misc_ref_new_string):       
3472        __(add imm0,arg_z,#misc_data_offset)
3473        __(ldr imm0,[arg_y,imm0])
3474        __(mov arg_z,imm0,lsl #charcode_shift)
3475        __(orr arg_z,arg_z,#subtag_character)
3476        __(bx lr)
3477local_label(misc_ref_s32):       
3478        __(add imm0,arg_z,#misc_data_offset)
3479        __(ldr imm0,[arg_y,imm0])
3480        __(b _SPmakes32)
3481local_label(misc_ref_fixnum_vector):   
3482        __(add imm0,arg_z,#misc_data_offset)
3483        __(ldr imm0,[arg_y,imm0])
3484        __(box_fixnum(arg_z,imm0))
3485        __(bx lr)       
3486local_label(misc_ref_u32):       
3487        __(add imm0,arg_z,#misc_data_offset)
3488        __(ldr imm0,[arg_y,imm0])
3489        __(b _SPmakeu32)
3490local_label(misc_ref_double_float_vector):     
3491        __(mov imm0,arg_z,lsl #1)
3492        __(add imm0,imm0,#misc_dfloat_offset)
3493        __(ldrd imm0,imm1,[arg_y,imm0])
3494        __(movc16(imm2,double_float_header))
3495        __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
3496        __(strd imm0,imm1,[arg_z,#double_float.value])
3497        __(bx lr)
3498local_label(misc_ref_bit_vector):
3499        __(mov imm1,#nbits_in_word-1)
3500        __(and imm1,imm1,arg_z,lsr #2)
3501        __(mov imm2,#1)
3502        __(mov imm2,imm2,lsl imm1)
3503        __(mov imm0,arg_z,lsr #5+fixnumshift)
3504        __(mov imm0,imm0,lsl #2)
3505        __(add imm0,imm0,#misc_data_offset)
3506        __(mov arg_z,#0)
3507        __(ldr imm0,[arg_y,imm0])
3508        __(tst imm0,imm2)
3509        __(addne arg_z,arg_z,#fixnumone)
3510        __(bx lr)
3511local_label(misc_ref_s8):       
3512        __(mov imm0,arg_z,lsr #2)
3513        __(add imm0,imm0,#misc_data_offset)
3514        __(ldsb imm0,[arg_y,imm0])
3515        __(box_fixnum(arg_z,imm0))
3516        __(bx lr)
3517local_label(misc_ref_u8):       
3518        __(mov imm0,arg_z,lsr #2)
3519        __(add imm0,imm0,#misc_data_offset)
3520        __(ldrb imm0,[arg_y,imm0])
3521        __(box_fixnum(arg_z,imm0))
3522        __(bx lr)
3523local_label(misc_ref_old_string):         
3524        __(mov imm0,arg_z,lsr #2)
3525        __(add imm0,imm0,#misc_data_offset)
3526        __(ldrb imm0,[arg_y,imm0])
3527        __(mov arg_z,imm0,lsl #charcode_shift)
3528        __(orr arg_z,arg_z,#subtag_character)
3529        __(bx lr)
3530local_label(misc_ref_u16):       
3531        __(mov imm0,arg_z,lsr #1)     
3532        __(add imm0,imm0,#misc_data_offset)
3533        __(ldrh imm0,[arg_y,imm0])
3534        __(box_fixnum(arg_z,imm0))
3535        __(bx lr)
3536local_label(misc_ref_s16):             
3537        __(mov imm0,arg_z,lsr #1)     
3538        __(add imm0,imm0,#misc_data_offset)
3539        __(ldrsh imm0,[arg_y,imm0])
3540        __(box_fixnum(arg_z,imm0))
3541        __(bx lr)
3542local_label(misc_ref_invalid):
3543        __(mov arg_x,#XBADVEC)
3544        __(set_nargs(3))
3545        __(b _SPksignalerr)       
3546_endfn
3547       
3548_exportfn(C(misc_set_common))
3549        __(adr imm0,local_label(misc_set_jmp))
3550        __(ldr pc,[imm0,imm1,lsl #2])
3551local_label(misc_set_jmp):             
3552        /* 00-0f  */
3553        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
3554        .long local_label(misc_set_invalid) /* 01 cons  */
3555        .long local_label(misc_set_invalid) /* 02 nodeheader  */
3556        .long local_label(misc_set_invalid) /* 03 imm  */
3557        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
3558        .long local_label(misc_set_invalid) /* 05 nil  */
3559        .long local_label(misc_set_invalid) /* 06 misc  */
3560        .long local_label(misc_set_u32) /* 07 bignum  */
3561        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
3562        .long local_label(misc_set_invalid) /* 09 cons  */
3563        .long _SPgvset /* 0a ratio  */
3564        .long local_label(misc_set_invalid) /* 0b imm  */
3565        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
3566        .long local_label(misc_set_invalid) /* 0d nil  */
3567        .long local_label(misc_set_invalid) /* 0e misc  */
3568        .long local_label(misc_set_u32) /* 0f single_float  */
3569        /* 10-1f  */
3570        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
3571        .long local_label(misc_set_invalid) /* 11 cons  */
3572        .long local_label(misc_set_invalid) /* 12 nodeheader  */
3573        .long local_label(misc_set_invalid) /* 13 imm  */
3574        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
3575        .long local_label(misc_set_invalid) /* 15 nil  */
3576        .long local_label(misc_set_invalid) /* 16 misc  */
3577        .long local_label(misc_set_u32) /* 17 double_float  */
3578        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
3579        .long local_label(misc_set_invalid) /* 19 cons  */
3580        .long _SPgvset /* 1a complex  */
3581        .long local_label(misc_set_invalid) /* 1b imm  */
3582        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
3583        .long local_label(misc_set_invalid) /* 1d nil  */
3584        .long local_label(misc_set_invalid) /* 1e misc  */
3585        .long local_label(misc_set_u32) /* 1f macptr  */
3586        /* 20-2f  */
3587        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
3588        .long local_label(misc_set_invalid) /* 21 cons  */
3589        .long _SPgvset /* 22 catch_frame  */
3590        .long local_label(misc_set_invalid) /* 23 imm  */
3591        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
3592        .long local_label(misc_set_invalid) /* 25 nil  */
3593        .long local_label(misc_set_invalid) /* 26 misc  */
3594        .long local_label(misc_set_u32) /* 27 dead_macptr  */
3595        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
3596        .long local_label(misc_set_invalid) /* 29 cons  */
3597        .long _SPgvset /* 2a function  */
3598        .long local_label(misc_set_invalid) /* 2b imm  */
3599        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
3600        .long local_label(misc_set_invalid) /* 2d nil  */
3601        .long local_label(misc_set_invalid) /* 2e misc  */
3602        .long local_label(misc_set_u32) /* 2f code_vector  */
3603        /* 30-3f  */
3604        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
3605        .long local_label(misc_set_invalid) /* 31 cons  */
3606        .long _SPgvset /* 32 lisp_thread  */
3607        .long local_label(misc_set_invalid) /* 33 imm  */
3608        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
3609        .long local_label(misc_set_invalid) /* 35 nil  */
3610        .long local_label(misc_set_invalid) /* 36 misc  */
3611        .long local_label(misc_set_u32) /* 37 creole  */
3612        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
3613        .long local_label(misc_set_invalid) /* 39 cons  */
3614        .long _SPgvset /* 3a symbol  */
3615        .long local_label(misc_set_invalid) /* 3b imm  */
3616        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
3617        .long local_label(misc_set_invalid) /* 3d nil  */
3618        .long local_label(misc_set_invalid) /* 3e misc  */
3619        .long local_label(misc_set_u32) /* 3f xcode_vector  */
3620        /* 40-4f  */
3621        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
3622        .long local_label(misc_set_invalid) /* 41 cons  */
3623        .long _SPgvset /* 42 lock  */
3624        .long local_label(misc_set_invalid) /* 43 imm  */
3625        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
3626        .long local_label(misc_set_invalid) /* 45 nil  */
3627        .long local_label(misc_set_invalid) /* 46 misc  */
3628        .long local_label(misc_set_invalid) /* 47 immheader  */
3629        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
3630        .long local_label(misc_set_invalid) /* 49 cons  */
3631        .long _SPgvset /* 4a hash_vector  */
3632        .long local_label(misc_set_invalid) /* 4b imm  */
3633        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
3634        .long local_label(misc_set_invalid) /* 4d nil  */
3635        .long local_label(misc_set_invalid) /* 4e misc  */
3636        .long local_label(misc_set_invalid) /* 4f immheader  */
3637        /* 50-5f  */
3638        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
3639        .long local_label(misc_set_invalid) /* 51 cons  */
3640        .long _SPgvset /* 52 pool  */
3641        .long local_label(misc_set_invalid) /* 53 imm  */
3642        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
3643        .long local_label(misc_set_invalid) /* 55 nil  */
3644        .long local_label(misc_set_invalid) /* 56 misc  */
3645        .long local_label(misc_set_invalid) /* 57 immheader  */
3646        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
3647        .long local_label(misc_set_invalid) /* 59 cons  */
3648        .long _SPgvset /* 5a weak  */
3649        .long local_label(misc_set_invalid) /* 5b imm  */
3650        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
3651        .long local_label(misc_set_invalid) /* 5d nil  */
3652        .long local_label(misc_set_invalid) /* 5e misc  */
3653        .long local_label(misc_set_invalid) /* 5f immheader  */
3654        /* 60-6f  */
3655        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
3656        .long local_label(misc_set_invalid) /* 61 cons  */
3657        .long _SPgvset /* 62 package  */
3658        .long local_label(misc_set_invalid) /* 63 imm  */
3659        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
3660        .long local_label(misc_set_invalid) /* 65 nil  */
3661        .long local_label(misc_set_invalid) /* 66 misc  */
3662        .long local_label(misc_set_invalid) /* 67 immheader  */
3663        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
3664        .long local_label(misc_set_invalid) /* 69 cons  */
3665        .long _SPgvset /* 6a slot_vector  */
3666        .long local_label(misc_set_invalid) /* 6b imm  */
3667        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
3668        .long local_label(misc_set_invalid) /* 6d nil  */
3669        .long local_label(misc_set_invalid) /* 6e misc  */
3670        .long local_label(misc_set_invalid) /* 6f immheader  */
3671        /* 70-7f  */
3672        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
3673        .long local_label(misc_set_invalid) /* 71 cons  */
3674        .long _SPgvset /* 72 instance  */
3675        .long local_label(misc_set_invalid) /* 73 imm  */
3676        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
3677        .long local_label(misc_set_invalid) /* 75 nil  */
3678        .long local_label(misc_set_invalid) /* 76 misc  */
3679        .long local_label(misc_set_invalid) /* 77 immheader  */
3680        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
3681        .long local_label(misc_set_invalid) /* 79 cons  */
3682        .long _SPgvset /* 7a struct  */
3683        .long local_label(misc_set_invalid) /* 7b imm  */
3684        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
3685        .long local_label(misc_set_invalid) /* 7d nil  */
3686        .long local_label(misc_set_invalid) /* 7e misc  */
3687        .long local_label(misc_set_invalid) /* 7f immheader  */
3688        /* 80-8f  */
3689        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
3690        .long local_label(misc_set_invalid) /* 81 cons  */
3691        .long _SPgvset /* 82 istruct  */
3692        .long local_label(misc_set_invalid) /* 83 imm  */
3693        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
3694        .long local_label(misc_set_invalid) /* 85 nil  */
3695        .long local_label(misc_set_invalid) /* 86 misc  */
3696        .long local_label(misc_set_invalid) /* 87 immheader  */
3697        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
3698        .long local_label(misc_set_invalid) /* 89 cons  */
3699        .long _SPgvset /* 8a value_cell  */
3700        .long local_label(misc_set_invalid) /* 8b imm  */
3701        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
3702        .long local_label(misc_set_invalid) /* 8d nil  */
3703        .long local_label(misc_set_invalid) /* 8e misc  */
3704        .long local_label(misc_set_invalid) /* 8f immheader  */
3705        /* 90-9f  */
3706        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
3707        .long local_label(misc_set_invalid) /* 91 cons  */
3708        .long _SPgvset /* 92 xfunction  */
3709        .long local_label(misc_set_invalid) /* 93 imm  */
3710        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
3711        .long local_label(misc_set_invalid) /* 95 nil  */
3712        .long local_label(misc_set_invalid) /* 96 misc  */
3713        .long local_label(misc_set_invalid) /* 97 immheader  */
3714        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
3715        .long local_label(misc_set_invalid) /* 99 cons  */
3716        .long _SPgvset /* 9a arrayH  */
3717        .long local_label(misc_set_invalid) /* 9b imm  */
3718        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
3719        .long local_label(misc_set_invalid) /* 9d nil  */
3720        .long local_label(misc_set_invalid) /* 9e misc  */
3721        .long local_label(misc_set_invalid) /* 9f immheader  */
3722        /* a0-af  */
3723        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
3724        .long local_label(misc_set_invalid) /* a1 cons  */
3725        .long _SPgvset /* a2 vectorH  */
3726        .long local_label(misc_set_invalid) /* a3 imm  */
3727        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
3728        .long local_label(misc_set_invalid) /* a5 nil  */
3729        .long local_label(misc_set_invalid) /* a6 misc  */
3730        .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
3731        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
3732        .long local_label(misc_set_invalid) /* a9 cons  */
3733        .long _SPgvset /* aa vectorH  */
3734        .long local_label(misc_set_invalid) /* ab imm  */
3735        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
3736        .long local_label(misc_set_invalid) /* ad nil  */
3737        .long local_label(misc_set_invalid) /* ae misc  */
3738        .long local_label(misc_set_u32) /* af u32  */
3739        /* b0-bf  */
3740        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
3741        .long local_label(misc_set_invalid) /* b1 cons  */
3742        .long local_label(misc_set_invalid) /* b2 node  */
3743        .long local_label(misc_set_invalid) /* b3 imm  */
3744        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
3745        .long local_label(misc_set_invalid) /* b5 nil  */
3746        .long local_label(misc_set_invalid) /* b6 misc  */
3747        .long local_label(misc_set_s32) /* b7 s32  */
3748        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
3749        .long local_label(misc_set_invalid) /* b9 cons  */
3750        .long local_label(misc_set_invalid) /* ba nodeheader  */
3751        .long local_label(misc_set_invalid) /* bb imm  */
3752        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
3753        .long local_label(misc_set_invalid) /* bd nil  */
3754        .long local_label(misc_set_invalid) /* be misc  */
3755        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
3756        /* c0-cf  */
3757        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
3758        .long local_label(misc_set_invalid) /* c1 cons  */
3759        .long local_label(misc_set_invalid) /* c2 nodeheader  */
3760        .long local_label(misc_set_invalid) /* c3 imm  */
3761        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
3762        .long local_label(misc_set_invalid) /* c5 nil  */
3763        .long local_label(misc_set_invalid) /* c6 misc  */
3764        .long local_label(misc_set_new_string) /* c7 new_string  */
3765        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
3766        .long local_label(misc_set_invalid) /* c9 cons  */
3767        .long local_label(misc_set_invalid) /* ca nodeheader  */
3768        .long local_label(misc_set_invalid) /* cb imm  */
3769        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
3770        .long local_label(misc_set_invalid) /* cd nil  */
3771        .long local_label(misc_set_invalid) /* ce misc  */
3772        .long local_label(misc_set_u8) /* cf u8  */
3773        /* d0-df  */
3774        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
3775        .long local_label(misc_set_invalid) /* d1 cons  */
3776        .long local_label(misc_set_invalid) /* d2 nodeheader  */
3777        .long local_label(misc_set_invalid) /* d3 imm  */
3778        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
3779        .long local_label(misc_set_invalid) /* d5 nil  */
3780        .long local_label(misc_set_invalid) /* d6 misc  */
3781        .long local_label(misc_set_s8) /* d7 s8  */
3782        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
3783        .long local_label(misc_set_invalid) /* d9 cons  */
3784        .long local_label(misc_set_invalid) /* da nodeheader  */
3785        .long local_label(misc_set_invalid) /* db imm  */
3786        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
3787        .long local_label(misc_set_invalid) /* dd nil  */
3788        .long local_label(misc_set_invalid) /* de misc  */
3789        .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
3790        /* e0-ef  */
3791        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
3792        .long local_label(misc_set_invalid) /* e1 cons  */
3793        .long local_label(misc_set_invalid) /* e2 nodeheader  */
3794        .long local_label(misc_set_invalid) /* e3 imm  */
3795        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
3796        .long local_label(misc_set_invalid) /* e5 nil  */
3797        .long local_label(misc_set_invalid) /* e6 misc  */
3798        .long local_label(misc_set_u16) /* e7 u16  */
3799        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
3800        .long local_label(misc_set_invalid) /* e9 cons  */
3801        .long local_label(misc_set_invalid) /* ea nodeheader  */
3802        .long local_label(misc_set_invalid) /* eb imm  */
3803        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
3804        .long local_label(misc_set_invalid) /* ed nil  */
3805        .long local_label(misc_set_invalid) /* ee misc  */
3806        .long local_label(misc_set_s16) /* ef s16  */
3807        /* f0-ff  */
3808        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
3809        .long local_label(misc_set_invalid) /* f1 cons  */
3810        .long local_label(misc_set_invalid) /* f2 nodeheader  */
3811        .long local_label(misc_set_invalid) /* f3 imm  */
3812        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
3813        .long local_label(misc_set_invalid) /* f5 nil  */
3814        .long local_label(misc_set_invalid) /* f6 misc  */
3815        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
3816        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
3817        .long local_label(misc_set_invalid) /* f9 cons  */
3818        .long local_label(misc_set_invalid) /* fa nodeheader  */
3819        .long local_label(misc_set_invalid) /* fb imm  */
3820        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
3821        .long local_label(misc_set_invalid) /* fd nil  */
3822        .long local_label(misc_set_invalid) /* fe misc  */
3823        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
3824
3825local_label(misc_set_u32):       
3826        /* Either a non-negative fixnum, a positive one-digit bignum, */
3827        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
3828        __(add imm0,arg_y,#misc_data_offset)
3829        __(test_fixnum(arg_z))
3830        __(bne local_label(set_not_fixnum_u32))
3831        __(tst arg_z,#0x80000000)
3832        __(bne local_label(set_bad))
3833        __(unbox_fixnum(imm1,arg_z))
3834local_label(set_set32):         
3835        __(str imm1,[arg_x,imm0])
3836        __(bx lr)
3837local_label(set_not_fixnum_u32):
3838        __(extract_lisptag(imm1,arg_z))
3839        __(cmp imm1,#tag_misc)
3840        __(bne local_label(set_bad))
3841        __(movc16(imm2,one_digit_bignum_header))
3842        __(getvheader(imm1,arg_z))
3843        __(cmp imm1,imm2)
3844        __(bne local_label(set_not_1_digit_u32))
3845        __(ldr imm1,[arg_z,#misc_data_offset])
3846        __(cmp imm1,#0)
3847        __(bge local_label(set_set32))
3848        __(b local_label(set_bad))
3849local_label(set_not_1_digit_u32):
3850        __(movc16(imm2,two_digit_bignum_header))
3851        __(cmp imm1,imm2)
3852        __(bne local_label(set_bad))
3853        __(vrefr(imm2,arg_z,1))
3854        __(vrefr(imm1,arg_z,0))
3855        __(cmp imm2,#0)
3856        __(beq local_label(set_set32))
3857local_label(set_bad):
3858        /* arg_z does not match the array-element-type of arg_x.  */
3859        __(mov arg_y,arg_z)
3860        __(mov arg_z,arg_x)
3861        __(mov arg_x,#XNOTELT)
3862        __(set_nargs(3))
3863        __(b _SPksignalerr)
3864local_label(misc_set_fixnum_vector):   
3865        __(add imm0,arg_z,#misc_data_offset)
3866        __(test_fixnum(arg_z))
3867        __(bne local_label(set_bad))
3868        __(unbox_fixnum(imm1,arg_z))
3869        __(str imm1,[arg_x,imm0])
3870        __(bx lr)
3871local_label(misc_set_new_string):   
3872        __(add imm0,arg_z,#misc_data_offset)
3873        __(extract_lowbyte(imm2,arg_z))
3874        __(cmp imm2,#subtag_character)
3875        __(bne local_label(set_bad))
3876        __(unbox_character(imm1,arg_z))
3877        __(str imm1,[arg_x,imm0])
3878        __(bx lr)
3879local_label(misc_set_s32):
3880        __(add imm0,arg_z,#misc_data_offset)
3881        __(test_fixnum(arg_z))
3882        __(moveq imm1,arg_z,asr #fixnumshift)
3883        __(beq local_label(set_set32))
3884        __(extract_lisptag(imm2,arg_z))
3885        __(cmp imm2,#tag_misc)
3886        __(bne local_label(set_bad))
3887        __(movc16(imm1,one_digit_bignum_header))
3888        __(getvheader(imm2,arg_z))
3889        __(cmp imm2,imm1)
3890        __(vrefr(imm1,arg_z,0))
3891        __(beq local_label(set_set32))
3892        __(b local_label(set_bad))
3893local_label(misc_set_single_float_vector):
3894        __(add imm0,arg_z,#misc_data_offset)
3895        __(extract_typecode(imm2,arg_z))
3896        __(cmp imm2,#subtag_single_float)
3897        __(bne local_label(set_bad))
3898        __(ldr imm1,[arg_z,#single_float.value])
3899        __(str imm1,[arg_x,imm0])
3900        __(bx lr)
3901local_label(misc_set_u8):               
3902        __(mov imm0,arg_y,lsr #2)
3903        __(add imm0,imm0,#misc_data_offset)
3904        __(mov imm2,#~(0xff<<fixnumshift))
3905        __(tst arg_z,imm2)
3906        __(bne local_label(set_bad))
3907        __(unbox_fixnum(imm1,arg_z))
3908        __(strb imm1,[arg_x,imm0])
3909        __(bx lr)
3910local_label(misc_set_old_string):
3911        __(mov imm0,arg_y,lsr #2)
3912        __(add imm0,imm0,#misc_data_offset)
3913        __(extract_lowbyte(imm2,arg_z))
3914        __(cmp imm2,#subtag_character)
3915        __(unbox_character(imm1,arg_z))
3916        __(bne local_label(set_bad))
3917        __(strb imm1,[arg_x,imm0])
3918        __(bx lr)
3919local_label(misc_set_s8):
3920        __(mov imm0,arg_y,lsr #2)
3921        __(add imm0,imm0,#misc_data_offset)
3922        __(test_fixnum(arg_z))
3923        __(bne local_label(set_bad))
3924        __(unbox_fixnum(imm1,arg_z))
3925        __(mov imm2,imm1,lsl #32-8)
3926        __(cmp imm1,imm2,asr #32-8)
3927        __(bne local_label(set_bad))
3928        __(strb imm1,[arg_x,imm0])
3929        __(bx lr)
3930local_label(misc_set_u16):         
3931        __(mov imm0,arg_y,lsr #1)
3932        __(add imm0,imm0,#misc_data_offset)
3933        __(test_fixnum(arg_z))
3934        __(bne local_label(set_bad))
3935        __(unbox_fixnum(imm1,arg_z))
3936        __(mov imm2,imm1,lsl #16)
3937        __(cmp imm1,imm2,lsr #16)
3938        __(bne local_label(set_bad))
3939        __(strh imm1,[arg_x,imm0])
3940        __(bx lr)
3941local_label(misc_set_s16):
3942        __(mov imm0,arg_y,lsr #1)
3943        __(add imm0,imm0,#misc_data_offset)
3944        __(test_fixnum(arg_z))
3945        __(bne local_label(set_bad))
3946        __(unbox_fixnum(imm1,arg_z))
3947        __(mov imm2,imm1,lsl #16)
3948        __(cmp imm1,imm2,asr #16)
3949        __(bne local_label(set_bad))
3950        __(strh imm1,[arg_x,imm0])
3951        __(bx lr)
3952local_label(misc_set_bit_vector):
3953        __(bics imm0,arg_z,#fixnumone)
3954        __(bne local_label(set_bad))
3955        __(mov imm2,#31)
3956        __(and imm2,imm1,arg_y,lsr #2)
3957        __(mov imm1,#1)
3958        __(mov imm1,imm1,lsl imm2)
3959        __(mov imm0,arg_y,lsr #fixnumshift+5)
3960        __(mov imm0,imm0,lsl #2)
3961        __(add imm0,imm0,#misc_data_offset)
3962        __(cmp arg_z,#0)
3963        __(ldr imm2,[arg_x,imm0])
3964        __(orrne imm2,imm2,imm1)
3965        __(biceq imm2,imm2,imm1)
3966        __(str imm2,[arg_x,imm0])
3967        __(bx lr)
3968
3969local_label(misc_set_double_float_vector):
3970        __(extract_subtag(imm2,arg_z))
3971        __(cmp imm2,#subtag_double_float)
3972        __(bne local_label(set_bad))
3973        __(ldrd imm0,imm1,[arg_z,#misc_dfloat_offset])
3974        __(mov imm2,arg_y,lsl #1)
3975        __(add imm2,imm2,#misc_dfloat_offset)
3976        __(strd imm0,imm1,[arg_x,imm2])
3977        __(bx lr)
3978local_label(misc_set_invalid): 
3979        __(mov temp0,#XSETBADVEC)       
3980        __(set_nargs(4))
3981        __(vpush1(temp0))
3982        __(b _SPksignalerr)               
3983
3984       
3985/* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
3986/* frames. If target isn't a multiple-value receiver, discard extra values */
3987/* (less hair, maybe.)  */
3988C(_throw_found):
3989pushdef(`__',`
3990        .word 0
3991        ')       
3992        __(ldr imm1,[imm2,#catch_frame.mvflag])
3993        __(cmpri(imm1,0))
3994        __(cmpri(cr1,nargs,0))
3995        __(mov fn,#0)
3996        __(add imm1,vsp,nargs)
3997        __(add imm1,[imm1,#-node_size])
3998        __(bne local_label(_throw_all_values))
3999        __(set_nargs(1))
4000        __(beq cr1,local_label(_throw_default_1_val))
4001        __(mov vsp,imm1)
4002        __(b local_label(_throw_all_values))
4003local_label(_throw_default_1_val):
4004        __(mov imm4,#nil_value)
4005        __(vpush1(imm4))
4006local_label(_throw_all_values):
4007        __(bl _SPnthrowvalues)
4008        __(ldr imm3,[rcontext,#tcr.catch_top])
4009        __(ldr imm1,[rcontext,#tcr.db_link])
4010        __(ldr imm0,[imm3,#catch_frame.db_link])
4011        __(ldr imm4,[imm3,#catch_frame.mvflag])
4012        __(cmpr(imm0,imm1))
4013        __(cmpri(cr1,imm4,0))
4014        __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
4015        __(beq local_label(_throw_dont_unbind))
4016        __(bl _SPunbind_to)
4017local_label(_throw_dont_unbind):
4018        __(add imm0,vsp,nargs)
4019        __(cmpri(nargs,0))
4020        __(ldr imm1,[imm3,#catch_frame.csp])
4021        __(ldr imm1,[imm1,#lisp_frame.savevsp])
4022        __(bne cr1,local_label(_throw_multiple))
4023        /* Catcher expects single value in arg_z  */
4024        __(ldr arg_z,[imm0,#-node_size])
4025        __(b local_label(_throw_pushed_values))
4026local_label(_throw_multiple):
4027        __(beq local_label(_throw_pushed_values))
4028        __(mov imm2,nargs)
4029local_label(_throw_mvloop):
4030        __(sub imm2,imm2,fixnum_one)
4031        __(cmpri(imm2,0))
4032        __(ldru(temp0,-node_size(imm0)))
4033        __(push(temp0,imm1))
4034        __(bgt local_label(_throw_mvloop))
4035local_label(_throw_pushed_values):
4036        __(mov vsp,imm1)
4037        __(ldr imm1,[imm3,#catch_frame.xframe])
4038        __(str(imm1,tcr.xframe(rcontext)))
4039        __(ldr sp,[imm3,#catch_frame.csp])
4040        __(ldr fn,[sp,#lisp_frame.savefn])
4041        __(ldr loc_pc,[sp,#lisp_frame.savelr])
4042        __(discard_lisp_frame())
4043        __(mtlr loc_pc)
4044        __(restore_catch_nvrs(imm3))
4045        __(ldr imm3,[imm3,#catch_frame.link])
4046        __(str(imm3,tcr.catch_top(rcontext)))
4047        __(unlink(tsp))
4048        __(bx lr)
4049popdef(`__')
4050
4051C(nthrow1v):   
4052local_label(_nthrow1v_nextframe):
4053        __(subs temp2,temp2,#fixnum_one)
4054        __(ldr temp0,[rcontext,#tcr.catch_top])
4055        __(ldr imm1,[rcontext,#tcr.db_link])
4056        __(set_nargs(1))
4057        __(blt local_label(_nthrow1v_done))
4058        __(ldr arg_y,[temp0,#catch_frame.link])
4059        __(ldr imm0,[temp0,#catch_frame.db_link])
4060        __(cmp imm0,imm1)
4061        __(str arg_y,[rcontext,#tcr.catch_top])
4062        __(ldr arg_y,[temp0,#catch_frame.xframe])
4063        __(str arg_y,[rcontext,#tcr.xframe])
4064        __(beq local_label(_nthrow1v_dont_unbind))
4065        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
4066local_label(_nthrow1v_dont_unbind):
4067        __(ldr temp1,[temp0,#catch_frame.catch_tag])
4068        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
4069        __(beq local_label(_nthrow1v_do_unwind))
4070        /* A catch frame.  If the last one, restore context from there.  */
4071        __(cmp temp2,#0)
4072        __(ldreq vsp,[sp,#catch_frame.size+lisp_frame.savevsp])
4073        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4074        __(b local_label(_nthrow1v_nextframe))
4075local_label(_nthrow1v_do_unwind):
4076        /* This is harder, but not as hard (not as much BLTing) as the  */
4077        /* multiple-value case.  */
4078        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
4079        /* protect.  (Clever, eh ?)  */
4080        __(add sp,sp,#catch_frame.size)
4081        /* swp is deprecated on ARMv6+.  It's not useful as a basis
4082           for synchronization, but that's not why we're using it here. */
4083        __(mov imm1,#0)
4084        __(mov temp0,sp)
4085        __(mov imm0,#3<<num_subtag_bits)
4086        __(orr imm0,imm0,#subtag_simple_vector)
4087        __(stmdb sp!,{imm0,imm1,arg_z,temp2})
4088        __(add imm0,temp0,#lisp_frame.savelr)
4089        __(swp lr,lr,[imm0])
4090        __(ldr nfn,[temp0,#lisp_frame.savefn])
4091        __(str fn,[temp0,#lisp_frame.savefn])
4092        __(ldr vsp,[temp0,#lisp_frame.savevsp])
4093        __(mov fn,nfn)
4094        __(str imm1,[rcontext,#tcr.unwinding])
4095        __(blx lr)
4096        __(mov imm1,#1)
4097        __(ldr arg_z,[sp,#8])
4098        __(str imm1,[rcontext,#tcr.unwinding])
4099        __(ldr temp2,[sp,#12])
4100        __(add sp,sp,#4*node_size)
4101        __(restore_lisp_frame(imm0))
4102        __(b local_label(_nthrow1v_nextframe))
4103local_label(_nthrow1v_done):
4104        __(mov imm0,#0)
4105        __(str imm0,[rcontext,#tcr.unwinding])
4106        /* nargs has an undefined value here, so we can clobber it while */
4107        /* polling for a deferred interrupt  */
4108        __(check_pending_interrupt(nargs))
4109        __(bx lr)
4110       
4111/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
4112/* sure that there's an empty tsp frame to keep the compiler happy.  */
4113stack_misc_alloc_no_room:       
4114        __(mov imm0,#stack_alloc_marker)
4115        __(mov imm1,sp)
4116        __(stmdb sp!,{imm0,imm1})
4117        __(b _SPmisc_alloc)
4118       
4119        _endfile
Note: See TracBrowser for help on using the repository browser.