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

Last change on this file since 13827 was 13827, checked in by gb, 9 years ago

Lots of changes and additions.

File size: 142.5 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        __(bxhs 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        __(bxhs 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        __(bxhs 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       
881dnl /* This is a special case of storing into a gvector: if we need to memoize  */
882dnl /* the store, record the address of the hash-table vector in the refmap,  */
883dnl /* 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        __(bxhs 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        __(bhi 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        __(bhi 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        __(bge 9f)
1195        __(mov imm0,#subtag_u32_vector)
1196        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1197        __(stack_allocate_zeroed_ivector(imm0,imm1))
1198        __(unbox_fixnum(imm0,arg_z))
1199        __(strb imm0,[sp])
1200        __(add arg_z,sp,#fulltag_misc)
1201        __(bx lr)
12021:      __(mov imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1203        __(orr imm0,imm0,arg_z,lsr #fixnumshift)
1204        __(cmp arg_z,#max_32_bit_ivector_subtag<<fixnumshift)
1205        __(movle imm1,arg_y)
1206        __(ble 8f)
1207        __(cmp arg_z,#max_8_bit_ivector_subtag<<fixnumshift)
1208        __(movle imm1,arg_y,lsr #fixnumshift)
1209        __(ble 8f)
1210        __(cmp arg_z,#max_16_bit_ivector_subtag<<fixnumshift)
1211        __(movle imm1,arg_y,lsr #1)
1212        __(ble 8f)
1213        __(cmp arg_z,#subtag_double_float)
1214        __(moveq imm1,arg_y,lsl #1)
1215        __(addeq imm1,imm1,#node_size)
1216        __(addne imm1,arg_y,#7<<fixnumshift)
1217        __(movne imm1,imm1,lsr#3+fixnumshift)
12188:      __(dnode_align(imm1,imm1,node_size))
1219        __(cmp imm1,#stack_alloc_limit)
1220        __(bhs 9f)
1221        __(stack_allocate_zeroed_ivector(imm0,imm1))
1222        __(add arg_z,sp,#fulltag_misc)
1223        __(bx lr)
12249:
1225
1226/* Too large to safely fit on tstack.  Heap-cons the vector, but make  */
1227/* sure that there's an empty tsp frame to keep the compiler happy.  */
12280:
1229        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1230        __(mov imm1,#0)
1231        __(stmdb sp!,{imm0,imm1})
1232        __(b _SPmisc_alloc)
1233
1234
1235/* subtype (boxed, of course) is vpushed, followed by nargs bytes worth of  */
1236/* initial-contents.  Note that this can be used to cons any type of initialized  */
1237/* node-header'ed misc object (symbols, closures, ...) as well as vector-like  */
1238/* objects.  */
1239
1240_spentry(gvector)
1241        __(sub nargs,nargs,#node_size)
1242        __(ldr arg_z,[vsp,nargs])
1243        __(unbox_fixnum(imm0,arg_z))
1244        __(orr imm0,imm0,nargs,lsl #num_subtag_bits-fixnum_shift)
1245        __(dnode_align(imm1,nargs,node_size))
1246        __(Misc_Alloc(arg_z,imm0,imm1))
1247        __(mov imm1,nargs)
1248        __(add imm2,imm1,#misc_data_offset)
1249        __(b 2f)
12501:
1251        __(str temp0,[arg_z,imm2])
12522:
1253        __(sub imm1,imm1,#node_size)
1254        __(cmp imm1,#0)
1255        __(sub imm2,imm2,#node_size)
1256        __(vpop1(temp0))        /* Note the intentional fencepost: */
1257                                /* discard the subtype as well.  */
1258        __(bge 1b)
1259        __(bx lr)
1260
1261_spentry(fitvals)
1262        __(subs imm0,imm0,nargs)
1263        __(mov imm1,#nil_value)
1264        __(sublt vsp,vsp,imm0)
1265        __(bxlt lr)
1266        __(b 2f)
12671:
1268        __(subs imm0,imm0,#node_size)
1269        __(vpush1(imm1))       
1270        __(add nargs,nargs,#node_size)
12712:
1272        __(bne 1b)
1273        __(bx lr)
1274
1275
1276_spentry(nthvalue)
1277        __(add imm0,vsp,nargs)
1278        __(ldr imm1,[imm0,#0])
1279        __(cmp imm1,nargs) /*  do unsigned compare:  if (n < 0) => nil.  */
1280        __(mov arg_z,#nil_value)
1281        __(rsb imm1,imm1,#0)
1282        __(sub imm1,imm1,#node_size)
1283        __(ldrlo arg_z,[imm0,imm1])
1284        __(add vsp,imm0,#node_size)
1285        __(bx lr)
1286
1287/* Provide default (NIL) values for &optional arguments; imm0 is  */
1288/* the (fixnum) upper limit on the total of required and &optional  */
1289/* arguments.  nargs is preserved, all arguments wind up on the  */
1290/* vstack.  */
1291_spentry(default_optional_args)
1292        __(vpush_argregs())
1293        __(cmp nargs,imm0)
1294        __(mov arg_z,#nil_value)
1295        __(mov imm1,nargs)
1296        __(bxhs lr)
12971:
1298        __(add imm1,imm1,#fixnum_one)
1299        __(cmp imm1,imm0)
1300        __(vpush1(arg_z))
1301        __(bne 1b)
1302        __(bx lr)
1303
1304/* Indicate whether &optional arguments were actually supplied.  nargs  */
1305/* contains the actual arg count (minus the number of required args);  */
1306/* imm0 contains the number of &optional args in the lambda list.  */
1307/* Note that nargs may be > imm0 if &rest/&key is involved.  */
1308_spentry(opt_supplied_p)
1309        __(mov imm1,#0)
1310        __(mov arg_x,#nil_value)
1311        __(add arg_x,arg_x,#t_offset)       
13121:     
1313        /* (vpush (< imm1 nargs))  */
1314        __(cmp imm1,nargs)
1315        __(add imm1,imm1,#fixnumone)
1316        __(subeq arg_x,arg_x,#t_offset)
1317        __(vpush1(arg_x))
1318        __(cmp imm1,imm0)
1319        __(bne 1b)
1320        __(bx lr)
1321
1322/* Cons a list of length nargs  and vpush it.  */
1323/* Use this entry point to heap-cons a simple &rest arg.  */
1324_spentry(heap_rest_arg)
1325        __(vpush_argregs())
1326        __(movs imm1,nargs)
1327        __(mov arg_z,#nil_value)
1328        __(b 2f)
13291:
1330        __(vpop1(arg_y))
1331        __(Cons(arg_z,arg_y,arg_z))
1332        __(subs imm1,imm1,#fixnum_one)
13332:
1334        __(bne 1b)
1335        __(vpush1(arg_z))
1336        __(bx lr)
1337
1338 
1339/* And this entry point when the argument registers haven't yet been  */
1340/* vpushed (as is typically the case when required/&rest but no  */
1341/* &optional/&key.)  */
1342_spentry(req_heap_rest_arg)
1343        __(vpush_argregs())
1344        __(subs imm1,nargs,imm0)
1345        __(mov arg_z,#nil_value)
1346        __(b 2f)
13471:
1348        __(vpop1(arg_y))
1349        __(Cons(arg_z,arg_y,arg_z))
1350        __(subs imm1,imm1,#fixnum_one)
13512:
1352        __(bgt 1b)
1353        __(vpush1(arg_z))
1354        __(bx lr)
1355
1356/* Here where argregs already pushed */
1357_spentry(heap_cons_rest_arg)
1358        __(subs imm1,nargs,imm0)
1359        __(mov arg_z,#nil_value)
1360        __(b 2f)
13611:
1362        __(vpop1(arg_y))
1363        __(Cons(arg_z,arg_y,arg_z))
1364        __(subs imm1,imm1,#fixnum_one)
13652:
1366        __(bgt 1b)
1367        __(vpush1(arg_z))
1368        __(bx lr)
1369
1370
1371_spentry(check_fpu_exception)
1372
1373_spentry(discard_stack_object)
1374        new_local_labels()       
1375        __(ldr imm0,[sp,#0])
1376        __(cmp imm0,#stack_alloc_marker)
1377        __(ldreq sp,[sp,#node_size])
1378        __(bxeq lr)
1379        __(cmp imm0,#lisp_frame_marker)
1380        __(extract_fulltag(imm1,imm0))
1381        __(addeq sp,sp,#lisp_frame.size)
1382        __(bxeq lr)
1383        __(cmp imm1,#fulltag_immheader)
1384        __(and imm1,imm0,#subtag_mask)
1385        __(bic imm0,imm0,#subtag_mask)
1386        __(beq local_label(ivector))
1387local_label(word):
1388        __(mov imm0,imm0,lsr #num_subtag_bits-word_shift)
1389local_label(out):       
1390        __(dnode_align(imm0,imm0,node_size))
1391        __(add sp,sp,imm0)
1392        __(bx lr)
1393local_label(ivector):     
1394        __(cmp imm1,#max_32_bit_ivector_subtag)
1395        __(bls local_label(word))       
1396        __(cmp imm1,#max_8_bit_ivector_subtag)
1397        __(movls imm0,imm0,lsr #num_subtag_bits)
1398        __(bls local_label(out))
1399        __(cmp imm1,#max_16_bit_ivector_subtag)
1400        __(movls imm0,imm0,lsr #num_subtag_bits-1)
1401        __(bls local_label(out))
1402        __(cmp imm1,#subtag_bit_vector)
1403        __(moveq imm0,imm0,lsr #num_subtag_bits)
1404        __(addeq imm0,imm0,#7)
1405        __(moveq imm0,imm0,lsr #3)
1406        __(beq local_label(out))
1407        /* The infamous 'stack-consed double-float vector' case */
1408        __(mov imm0,imm0,lsr #num_subtag_bits-dnode_shift)
1409        __(b local_label(out))
1410
1411
1412       
1413/* Signal an error synchronously, via %ERR-DISP.  */
1414/* If %ERR-DISP isn't fbound, it'd be nice to print a message  */
1415/* on the C runtime stderr.  */
1416 
1417_spentry(ksignalerr)
1418        __(ref_nrs_symbol(fname,errdisp,imm0))
1419        __(jump_fname)
1420
1421/* As in the heap-consed cases, only stack-cons the &rest arg  */
1422_spentry(stack_rest_arg)
1423        __(mov imm0,#0)
1424        __(vpush_argregs())
1425        __(b _SPstack_cons_rest_arg)
1426
1427_spentry(req_stack_rest_arg)
1428        __(vpush_argregs())
1429        __(b _SPstack_cons_rest_arg)
1430
1431_spentry(stack_cons_rest_arg)
1432        __(sub imm1,nargs,imm0)
1433        __(cmp imm1,#0)
1434        __(mov arg_z,#nil_value)
1435        __(ble 2f)  /* always temp-push something.  */
1436        __(add imm1,imm1,imm1)
1437        __(mov temp0,imm1)
1438        __(add imm1,imm1,#node_size)
1439        __(dnode_align(imm0,imm1,node_size))
1440        __(mov imm1,imm1,lsl #num_subtag_bits-fixnumshift)
1441        __(orr imm1,imm1,#subtag_u32_vector)
1442        __(cmp imm1,#stack_alloc_limit)
1443        __(bge 3f)
1444        __(stack_allocate_zeroed_ivector(imm1,imm0))
1445        __(mov imm0,#subtag_simple_vector)
1446        __(strb imm0,[sp])
1447        __(add imm0,sp,#dnode_size+fulltag_cons)
14481:
1449        __(subs temp0,temp0,#fixnumone)
1450        __(vpop1(arg_x))
1451        __(_rplacd(imm0,arg_z))
1452        __(_rplaca(imm0,arg_x))
1453        __(mov arg_z,imm0)
1454        __(add imm0,imm0,#cons.size)
1455        __(bne 1b)
1456        __(vpush1(arg_z))
1457        __(bx lr)
14582:
1459        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1460        __(mov imm1,#0)
1461        __(stmdb sp!,{imm0,imm1})
1462        __(vpush1(arg_z))
1463        __(bx lr)
14643:
1465        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1466        __(mov imm1,#0)
1467        __(stmdb sp!,{imm0,imm1})
1468        __(b _SPheap_cons_rest_arg)
1469
1470       
1471/* Prepend all but the first three (entrypoint, closure code, fn) and last two  */
1472/* (function name, lfbits) elements of nfn to the "arglist".  */
1473/* functions which take "inherited arguments" work consistently  */
1474/* even in cases where no closure object is created.  */
1475_spentry(call_closure)       
1476        __(cmp nargs,nargregs<<fixnumshift)
1477        __(vector_length(imm0,nfn,imm0))
1478        __(sub imm0,imm0,#5<<fixnumshift) /* imm0 = inherited arg count  */
1479        __(ble local_label(no_insert))
1480        /* Some arguments have already been vpushed.  Vpush imm0's worth  */
1481        /* of NILs, copy those arguments that have already been vpushed from  */
1482        /* the old TOS to the new, then insert all of the inerited args  */
1483        /* and go to the function.  */
1484        __(vpush_all_argregs())
1485        __(mov arg_x,imm0)
1486        __(mov arg_y,#nil_value)
1487local_label(push_nil_loop):
1488        __(subs arg_x,arg_x,#fixnumone)
1489        __(vpush1(arg_y))
1490        __(bne local_label(push_nil_loop))
1491        __(add arg_y,vsp,imm0)
1492        __(mov imm1,#0)
1493local_label(copy_already_loop):
1494        __(ldr arg_x,[vsp,imm1])
1495        __(str arg_x,[arg_y,imm1])
1496        __(add imm1,imm1,#fixnumone)
1497        __(cmp imm1,imm0)
1498        __(bne local_label(copy_already_loop))
1499        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1500        __(add arg_y,vsp,nargs)
1501        __(add arg_y,arg_y,imm0)
1502local_label(insert_loop):
1503        __(subs imm0,imm0,#fixnumone)
1504        __(ldr fname,[nfn,imm1])
1505        __(add imm1,imm1,#fixnumone)
1506        __(add nargs,nargs,#fixnumone)
1507        __(push1(fname,arg_y))
1508        __(bne local_label(insert_loop))
1509        __(vpop_all_argregs())
1510        __(b local_label(go))
1511local_label(no_insert):
1512/* nargregs or fewer args were already vpushed.  */
1513/* if exactly nargregs, vpush remaining inherited vars.  */
1514        __(cmp nargs,#nargregs<<fixnumshift)
1515        __(add imm1,imm0,#misc_data_offset+(3<<fixnumshift))
1516        __(bne local_label(set_regs))
1517local_label(vpush_remaining):
1518        __(mov imm1,#misc_data_offset+(3<<fixnumshift))
1519local_label(vpush_remaining_loop):             
1520        __(ldr fname,[nfn,imm1])
1521        __(add imm1,imm1,#fixnum_one)
1522        __(vpush1(fname))
1523        __(subs imm0,imm0,#fixnum_one)
1524        __(add nargs,nargs,#fixnum_one)
1525        __(bne  local_label(vpush_remaining_loop))
1526        __(b local_label(go))
1527local_label(set_regs):
1528        /* if nargs was > 1 (and we know that it was < 3), it must have  */
1529        /* been 2.  Set arg_x, then vpush the remaining args.  */
1530        __(cmp nargs,#fixnumone)
1531        __(ble local_label(set_y_z))
1532local_label(set_arg_x):
1533        __(subs imm0,imm0,#fixnum_one)
1534        __(sub imm1,imm1,#fixnum_one)
1535        __(ldr arg_x,[nfn,imm1])
1536        __(add nargs,nargs,#fixnum_one)
1537        __(bne local_label(vpush_remaining))
1538        __(b local_label(go))
1539        /* Maybe set arg_y or arg_z, preceding args  */
1540local_label(set_y_z):
1541        __(cmp nargs,#fixnumone)
1542        __(bne local_label(set_arg_z))
1543        /* Set arg_y, maybe arg_x, preceding args  */
1544local_label(set_arg_y):
1545        __(subs imm0,imm0,fixnum_one)
1546        __(sub imm1,imm1,#fixnum_one)
1547        __(ldr arg_y,[nfn,imm1])
1548        __(add nargs,nargs,#fixnum_one)
1549        __(bne local_label(set_arg_x))
1550        __(b local_label(go))
1551local_label(set_arg_z):
1552        __(subs imm0,imm0,#fixnum_one)
1553        __(sub imm1,imm1,#fixnum_one)
1554        __(ldr arg_z,[nfn,imm1])
1555        __(add nargs,nargs,#fixnum_one)
1556        __(bne local_label(set_arg_y))
1557 
1558local_label(go):
1559        __(vrefr(nfn,nfn,2))
1560        __(ldr pc,[nfn,#_function.entrypoint])
1561
1562
1563/* Everything up to the last arg has been vpushed, nargs is set to  */
1564/* the (boxed) count of things already pushed.  */
1565/* On exit, arg_x, arg_y, arg_z, and nargs are set as per a normal  */
1566/* function call (this may require vpopping a few things.)  */
1567/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
1568_spentry(spreadargz)
1569        __(extract_lisptag(imm1,arg_z))
1570        __(cmp arg_z,#nil_value)
1571        __(mov imm0,#0)
1572        __(mov arg_y,arg_z)  /*  save in case of error  */
1573        __(beq 2f)
15741:
1575        __(cmp imm1,#tag_list)
1576        __(bne 3f)
1577        __(_car(arg_x,arg_z))
1578        __(_cdr(arg_z,arg_z))
1579        __(cmp arg_z,#nil_value)
1580        __(extract_lisptag(imm1,arg_z))
1581        __(vpush1(arg_x))
1582        __(add imm0,imm0,#fixnum_one)
1583        __(bne 1b)
15842:
1585        __(adds  nargs,nargs,imm0)
1586        __(bxeq lr)
1587        __(vpop_argregs_nz)
1588        __(bx lr)
1589       
1590        /*  Discard whatever's been vpushed already, complain.  */
15913: 
1592        __(add vsp,vsp,imm0)
1593        __(mov arg_z,arg_y)  /* recover original arg_z  */
1594        __(mov arg_y,#XNOSPREAD)
1595        __(set_nargs(2))
1596        __(b _SPksignalerr)
1597
1598/* Tail-recursively funcall temp0.  */
1599/* Pretty much the same as the tcallsym* cases above.  */
1600_spentry(tfuncallgen)
1601        __(cmp nargs,#nargregs<<fixnumshift)
1602        __(ldr lr,[sp,#lisp_frame.savelr])
1603        __(ldr fn,[sp,#lisp_frame.savefn])
1604        __(ble 2f)
1605        __(ldr imm0,[sp,#lisp_frame.savevsp])
1606        __(discard_lisp_frame())
1607        /* can use temp0 as a temporary  */
1608        __(sub imm1,nargs,#nargregs<<fixnumshift)
1609        __(add imm1,imm1,vsp)
16101:
1611        __(ldr temp0,[imm1,#-node_size]!)
1612        __(cmp imm1,vsp)
1613        __(push1(temp2,imm0))
1614        __(bne 1b)
1615        __(mov vsp,imm0)
1616        __(funcall_nfn())
16172:
1618        __(ldr vsp,[sp,#lisp_frame.savevsp])
1619        __(discard_lisp_frame())
1620        __(funcall_nfn())
1621
1622
1623/* Some args were vpushed.  Slide them down to the base of  */
1624/* the current frame, then do funcall.  */
1625_spentry(tfuncallslide)
1626        __(restore_lisp_frame(imm0))
1627        /* can use temp0 as a temporary  */
1628        __(sub imm1,nargs,#nargregs<<fixnumshift)
1629        __(add imm1,imm1,vsp)
16301:
1631        __(ldr temp0,[imm1,#-node_size]!)
1632        __(cmp imm1,vsp)
1633        __(push1(temp0,imm0))
1634        __(bne 1b)
1635        __(mov vsp,imm0)
1636        __(funcall_nfn())
1637
1638/* No args were vpushed; recover saved context & do funcall  */
1639_spentry(tfuncallvsp)
1640        __(restore_lisp_frame(imm0))
1641        __(funcall_nfn())
1642
1643/* Tail-recursively call the (known symbol) in fname.  */
1644/* In the general case, we don't know if any args were  */
1645/* vpushed or not.  If so, we have to "slide" them down  */
1646/* to the base of the frame.  If not, we can just restore  */
1647/* vsp, lr, fn from the saved lisp frame on the control stack.  */
1648_spentry(tcallsymgen)
1649        __(cmp nargs,#nargregs<<fixnumshift)
1650        __(ldr lr,[sp,#lisp_frame.savelr])
1651        __(ldr fn,[sp,#lisp_frame.savefn])
1652        __(ble 2f)
1653
1654        __(ldr imm0,[sp,#lisp_frame.savevsp])
1655        __(discard_lisp_frame())
1656        /* can use nfn (= temp2) as a temporary  */
1657        __(sub imm1,nargs,#nargregs<<fixnumshift)
1658        __(add imm1,imm1,vsp)
16591:
1660        __(ldr temp2,[imm1,#-node_size]!)
1661        __(cmp imm1,vsp)
1662        __(push1(temp2,imm0))
1663        __(bne 1b)
1664        __(mov vsp,imm0)
1665        __(jump_fname)
1666 
16672: 
1668        __(ldr vsp,[sp,#lisp_frame.savevsp])
1669        __(discard_lisp_frame())
1670        __(jump_fname)
1671
1672
1673/* Some args were vpushed.  Slide them down to the base of  */
1674/* the current frame, then do funcall.  */
1675_spentry(tcallsymslide)
1676        __(ldr lr,[sp,#lisp_frame.savelr])
1677        __(ldr fn,[sp,#lisp_frame.savefn])
1678        __(ldr imm0,[sp,#lisp_frame.savevsp])
1679        __(discard_lisp_frame())
1680        /* can use nfn (= temp2) as a temporary  */
1681        __(sub imm1,nargs,#nargregs<<fixnumshift)
1682        __(add imm1,imm1,vsp)
16831:
1684        __(ldr temp2,[imm1,#-node_size]!)
1685        __(cmp imm1,vsp)
1686        __(push1(temp2,imm0))
1687        __(bne 1b)
1688        __(mov vsp,imm0)
1689        __(jump_fname)
1690
1691
1692/* Tail-recursively call the function in nfn.  */
1693/* Pretty much the same as the tcallsym* cases above.  */
1694_spentry(tcallnfngen)
1695        __(cmp nargs,#nargregs<<fixnumshift)
1696        __(bgt _SPtcallnfnslide)
1697        __(restore_lisp_frame(imm0))
1698        __(jump_nfn())
1699         
1700/* Some args were vpushed.  Slide them down to the base of  */
1701/* the current frame, then do funcall.  */
1702_spentry(tcallnfnslide)
1703        __(ldr lr,[sp,#lisp_frame.savelr])
1704        __(ldr fn,[sp,#lisp_frame.savefn])
1705        __(ldr imm0,[sp,#lisp_frame.savevsp])
1706        __(discard_lisp_frame())
1707        /* Since we have a known function, can use fname as a temporary.  */
1708        __(sub imm1,nargs,#nargregs<<fixnumshift)
1709        __(add imm1,imm1,vsp)
17101:
1711        __(ldr fname,[imm1,#-node_size]!)
1712        __(cmp imm1,vsp)
1713        __(push1(fname,imm0))
1714        __(bne 1b)
1715        __(mov vsp,imm0)
1716        __(jump_nfn())
1717
1718
1719/* Reference index arg_z of a misc-tagged object (arg_y).  */
1720/* Note that this conses in some cases.  Return a properly-tagged  */
1721/* lisp object in arg_z.  Do type and bounds-checking.  */
1722
1723_spentry(misc_ref)
1724        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1725        __(trap_unless_fixnum(arg_z))
1726        __(vector_length(imm0,arg_y,imm1))
1727        __(cmp arg_z,imm0)
1728        __(uuo_error_vector_bounds(hs,arg_z,arg_y))
1729        __(extract_lowbyte(imm1,imm1)) /* imm1 = subtag  */
1730        __(b C(misc_ref_common))
1731
1732/* like misc_ref, only the boxed subtag is in arg_x.  */
1733
1734_spentry(subtag_misc_ref)
1735        __(trap_unless_fulltag_equal(arg_y,fulltag_misc,imm0))
1736        __(trap_unless_fixnum(arg_z))
1737        __(vector_length(imm0,arg_y,imm1))
1738        __(cmp arg_z,imm0)
1739        __(uuo_error_vector_bounds(hs,arg_z,arg_y))
1740        __(unbox_fixnum(imm1,arg_x))
1741        __(b C(misc_ref_common))
1742
1743
1744/* Make a "raw" area on the temp stack, stack-cons a macptr to point to it,  */
1745/* and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr */
1746/* in arg_z on exit.  */
1747_spentry(makestackblock)
1748        __(unbox_fixnum(imm1,arg_z))
1749        __(dnode_align(imm1,imm1,0))
1750        __(add imm1,imm1,#node_size)
1751        __(add imm0,imm1,#node_size)
1752        __(cmp imm0,#stack_alloc_limit)
1753        __(mov temp0,sp)
1754        __(bhs 1f)
1755        __(mov imm1,imm1,lsl #num_subtag_bits)
1756        __(orr imm1,imm1,#subtag_u8_vector)
1757        __(stack_allocate_ivector(imm1,imm0))
1758        __(add temp1,sp,#dnode_size)
1759        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1760        __(str imm1,[sp,#-macptr.size]!)
1761        __(add arg_z,sp,#fulltag_misc)
1762        __(str temp1,[arg_z,#macptr.address])
1763        __(mov imm0,#0)
1764        __(mov imm1,#stack_alloc_marker)
1765        __(str imm0,[arg_z,#macptr.type])
1766        __(str imm0,[arg_z,#macptr.domain])
1767        __(stmdb sp!,{imm1,temp0})
1768        __(bx lr)
1769
1770        /* Too big. Heap cons a gcable macptr  */
17711:
1772        __(mov imm1,#stack_alloc_marker)
1773        __(stmdb sp!,{imm1,temp0})
1774        __(set_nargs(1))
1775        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1776        __(jump_fname())
1777
1778/* As above, only set the block's contents to 0.  */
1779_spentry(makestackblock0)
1780        __(unbox_fixnum(imm1,arg_z))
1781        __(dnode_align(imm1,imm1,0))
1782        __(add imm1,imm1,#node_size)
1783        __(add imm0,imm1,#node_size)
1784        __(cmp imm0,#stack_alloc_limit)
1785        __(mov temp0,sp)
1786        __(bhs 1f)
1787        __(mov imm1,imm1,lsl #num_subtag_bits)
1788        __(orr imm1,imm1,#subtag_u8_vector)
1789        __(stack_allocate_ivector(imm1,imm0))
1790        __(add temp1,sp,#dnode_size)
1791        __(movc16(imm1,make_header(macptr.element_count,subtag_macptr)))
1792        __(str imm1,[sp,#-macptr.size]!)
1793        __(add arg_z,sp,#fulltag_misc)
1794        __(str temp1,[arg_z,#macptr.address])
1795        __(mov imm0,#0)
1796        __(mov imm1,#stack_alloc_marker)
1797        __(str imm0,[arg_z,#macptr.type])
1798        __(str imm0,[arg_z,#macptr.domain])
1799        __(stmdb sp!,{imm1,temp0})
1800        __(bx lr)
1801       
1802        /* Too big. Heap cons a gcable macptr  */
18031:
1804        __(mov imm1,#stack_alloc_marker)
1805        __(stmdb sp!,{imm1,temp0})
1806        __(mov arg_y,arg_z) /* save block size  */
1807        __(mov arg_z,#nil_value) /* clear-p arg to %new-gcable-ptr  */
1808        __(add arg_z,arg_z,#t_offset)
1809        __(set_nargs(2))
1810        __(ref_nrs_symbol(fname,new_gcable_ptr,imm0))
1811        __(jump_fname())
1812
1813/* Make a list of length arg_y (boxed), initial-element arg_z (boxed) on  */
1814/* the tstack.  Return the list in arg_z.  */
1815_spentry(makestacklist)
1816        __(add imm0,arg_y,arg_y)
1817        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1818        __(add imm1,imm1,#4<<num_subtag_bits)
1819        __(orr imm1,imm1,#subtag_u32_vector)
1820        __(add imm0,imm0,#dnode_size)
1821        __(cmp imm0,#stack_alloc_limit)
1822        __(bge 4f)
1823        __(stack_allocate_zeroed_ivector(imm1,imm0))
1824        __(mov imm0,#subtag_simple_vector)
1825        __(strb imm0,[sp,#0])
1826        __(add imm2,sp,#dnode_size+fulltag_cons)
1827        __(movs imm1,arg_y)
1828        __(mov arg_y,arg_z)
1829        __(mov arg_z,#nil_value)
1830        __(b 3f)
18312:
1832        __(_rplacd(imm2,arg_z))
1833        __(_rplaca(imm2,arg_y))
1834        __(mov arg_z,imm2)
1835        __(add imm2,imm2,#cons.size)
1836        __(subs imm1,imm1,#fixnumone)
18373:
1838        __(bne 2b)
1839        __(bx lr)
18404:
1841        __(movc16(imm0,make_header(1,subtag_u32_vector)))
1842        __(str imm0,[sp,#-8]!)
1843        __(movs imm1,arg_y) /* count  */
1844        __(mov arg_y,arg_z) /* initial value  */
1845        __(mov arg_z,#nil_value) /* result  */
1846        __(b 6f)
18475:
1848        __(Cons(arg_z,arg_y,arg_z))
1849        __(subs imm1,imm1,#fixnumone)
18506:
1851        __(bne 5b)
1852        __(bx lr)
1853
1854/* subtype (boxed) vpushed before initial values. (Had better be a  */
1855/* node header subtag.) Nargs set to count of things vpushed.  */
1856
1857_spentry(stkgvector)
1858        __(sub imm0,nargs,#fixnumone)
1859        __(ldr temp0,[vsp,imm0])
1860        __(dnode_align(temp1,imm0,node_size))
1861        __(mov imm1,imm0,lsl #num_subtag_bits-fixnumshift)
1862        __(orr imm1,imm1,#subtag_u32_vector)
1863        __(stack_allocate_zeroed_ivector(imm1,temp1))
1864        __(unbox_fixnum(imm1,temp0))
1865        __(strb imm1,[sp])
1866        __(add arg_z,sp,#fulltag_misc)
1867        __(add imm0,sp,nargs)
1868        __(b 2f)
18691:
1870        __(vpop1(temp0))
1871        __(push1(temp0,imm0))
18722:      __(subs nargs,nargs,#fixnumone)
1873        __(bne 1b)
1874        __(add vsp,vsp,#fixnumone)
1875        __(bx lr)
1876
1877/* Allocate a "fulltag_misc" object.  On entry, arg_y contains the element  */
1878/* count (boxed) and  arg_z contains the subtag (boxed).  Both of these   */
1879/* parameters must be "reasonable" (the  subtag must be valid, the element  */
1880/* count must be of type (unsigned-byte 24)/(unsigned-byte 56).   */
1881/* On exit, arg_z contains the (properly tagged) misc object; it'll have a  */
1882/* proper header on it and its contents will be 0.   imm0 contains   */
1883/* the object's header (fulltag = fulltag_immheader or fulltag_nodeheader.)  */
1884
1885_spentry(misc_alloc)
1886        __(tst arg_y,#unsigned_byte_24_mask)
1887        __(bne 9f)
1888        __(unbox_fixnum(imm0,arg_z))
1889        __(orr imm0,imm0,arg_y,lsl #num_subtag_bits-fixnumshift)
1890        __(extract_fulltag(imm1,imm0))
1891        __(cmp imm1,#fulltag_nodeheader)
1892        __(mov imm2,arg_y)      /* imm2 = logical size in bytes */
1893        __(beq 1f)
1894        __(unbox_fixnum(imm1,arg_z))
1895        __(cmp imm1,#max_32_bit_ivector_subtag)
1896        __(ble 1f)
1897        __(mov imm2,arg_y,lsr #2)
1898        __(cmp imm1,#max_8_bit_ivector_subtag)
1899        __(ble 1f)
1900        __(mov imm2,arg_y,lsr #1)
1901        __(cmp imm1,#max_16_bit_ivector_subtag)
1902        __(ble 1f)
1903        __(mov imm2,arg_y,lsl #1)
1904        __(add imm2,imm2,#node_size)
1905        __(cmp imm1,#subtag_double_float_vector)
1906        __(beq 1f)
1907        __(add imm2,arg_y,#7<<fixnumshift)
1908        __(mov imm2,imm2,lsr #3+fixnumshift)
1909        /* imm2 now = byte count.  Add 4 for header, 7 to align, then clear */
1910        /* low three bits.  */
19111:
1912        __(dnode_align(imm2,imm2,node_size))
1913        __(Misc_Alloc(arg_z,imm0,imm2))
1914        __(bx lr)
19159:
1916        __(uuo_error_reg_not_xtype(al,arg_y,xtype_unsigned_byte_24))
1917
1918
1919
1920/* This doesn't need to memoize anything, but needs pc-lusering support
1921   support because of the locative */
1922_spentry(atomic_incf_node)
1923        __(unbox_fixnum(imm0,arg_z))
19240:      __(add imm2,arg_y,imm0)
1925        __(ldrex arg_z,[imm2])
1926        __(add arg_z,arg_z,arg_x)
1927        __(strex imm0,arg_z,[imm2])
1928        __(cmp imm0,#0)
1929        __(bne 0b)
1930        __(bx lr)
1931       
1932_spentry(unused1)
1933
1934_spentry(unused2)
1935
1936dnl /* vpush the values in the value set atop the vsp, incrementing nargs.  */
1937dnl /* Discard the tsp frame; leave values atop the vsp.  */
1938dnl
1939_spentry(recover_values)
1940dnl
1941dnl /* First, walk the segments reversing the pointer to previous segment pointers  */
1942dnl /* Can tell the end because that previous segment pointer is the prev tsp pointer  */
1943dnl  __(ldr imm0,[tsp,#tsp_frame.backlink]) /* previous tsp  */
1944dnl  __(mov imm1,tsp) /* current segment  */
1945dnl  __(mov imm2,tsp) /* last segment  */
1946dnl local_label(walkloop):
1947dnl  __(ldr imm3,[imm1,#tsp_frame.fixed_overhead+node_size]) /* next segment  */
1948dnl  __(cmpr(imm0,imm3)) /* last segment?  */
1949dnl  __(str(imm2,tsp_frame.fixed_overhead+node_size(imm1))) /* reverse pointer  */
1950dnl  __(mov imm2,imm1) /* last segment <- current segment  */
1951dnl  __(mov imm1,imm3) /* current segment <- next segment  */
1952dnl  __(bne local_label(walkloop))
1953dnl
1954dnl         /* the final segment ptr is now in imm2  */
1955dnl         /* walk backwards, pushing values on VSP and incrementing NARGS  */
1956dnl local_label(pushloop):
1957dnl  __(ldr imm0,[imm2,#tsp_frame.data_offset]) /* nargs in segment  */
1958dnl  __(cmpri(imm0,0))
1959dnl  __(cmpr(cr1,imm2,tsp))
1960dnl  __(la imm3,tsp_frame.data_offset+(2*node_size)(imm2))
1961dnl  __(add imm3,imm3,imm0)
1962dnl  __(add nargs,nargs,imm0)
1963dnl  __(b 2f)
1964dnl 1:
1965dnl  __(ldru(arg_z,-node_size(imm3)))
1966dnl  __(cmpri(imm0,fixnum_one))
1967dnl  __(subi imm0,imm0,fixnum_one)
1968dnl  __(vpush1(arg_z))
1969dnl 2:
1970dnl  __(bne 1b)
1971dnl  __(ldr imm2,[imm2,#tsp_frame.data_offset+node_size]) /* previous segment  */
1972dnl  __(bne cr1,local_label(pushloop))
1973dnl  __(unlink(tsp))
1974dnl  __(bx lr)
1975
1976
1977
1978/* If arg_z is an integer, return in imm0 something whose sign  */
1979/* is the same as arg_z's.  If not an integer, error.  */
1980_spentry(integer_sign)
1981        __(test_fixnum(arg_z))
1982        __(moveq imm0,arg_z)
1983        __(bxeq lr)
1984        __(extract_typecode(imm0,arg_z))
1985        __(cmp imm0,#subtag_bignum)
1986        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_integer))
1987        __(getvheader(imm1,arg_z))
1988        __(header_length(imm0,imm1)) /* boxed length = scaled size  */
1989        __(add imm0,imm0,#misc_data_offset-4) /* bias, less 1 element  */
1990        __(ldr imm0,[arg_z,imm0])
1991        __(cmp imm0,#0)
1992        __(movge imm0,#1)
1993        __(movlt imm0,#-1)
1994        __(bx lr)
1995
1996
1997/* like misc_set, only pass the (boxed) subtag in temp0  */
1998_spentry(subtag_misc_set)
1999        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
2000        __(trap_unless_fixnum(arg_y))
2001        __(vector_length(imm0,arg_x,imm1))
2002        __(cmp arg_y,imm0)
2003        __(uuo_error_vector_bounds(hs,arg_y,arg_x))
2004        __(unbox_fixnum(imm1,temp0))
2005        __(b C(misc_set_common))
2006
2007
2008
2009/* misc_set (vector index newval).  Pretty damned similar to  */
2010/* misc_ref, as one might imagine.  */
2011
2012_spentry(misc_set)
2013        __(trap_unless_fulltag_equal(arg_x,fulltag_misc,imm0))
2014        __(trap_unless_fixnum(arg_y))
2015        __(vector_length(imm0,arg_x,imm1))
2016        __(cmp arg_y,imm0)
2017        __(uuo_error_vector_bounds(hs,arg_y,arg_x))
2018        __(extract_lowbyte(imm1,imm1))
2019        __(b C(misc_set_common))
2020
2021/* "spread" the lexpr in arg_z.  */
2022/* ppc2-invoke-fn assumes that temp1 is preserved here.  */
2023_spentry(spread_lexprz)
2024        __(ldr imm0,[arg_z,#0])
2025        __(add imm1,arg_z,imm0)
2026        __(add nargs,nargs,imm0)
2027        __(add imm1,imm1,#node_size)
2028        __(cmp imm0,#3<<fixnumshift)
2029        __(bge 9f)
2030        __(cmp imm0,#2<<fixnumshift)
2031        __(beq 2f)
2032        __(cmp imm0,#0)
2033        __(bne 1f)
2034/* lexpr count was 0; vpop the arg regs that  */
2035/* were vpushed by the caller  */
2036        __(cmp nargs,#0)
2037        __(bxeq lr)
2038        __(vpop_argregs_nz)
2039        __(bx lr)
2040
2041/* vpush args from the lexpr until we have only  */
2042/* three left, then assign them to arg_x, arg_y,  */
2043/* and arg_z.  */
20448:
2045        __(cmp imm0,#4<<fixnumshift)
2046        __(sub imm0,imm0,#fixnumone)
2047        __(ldr arg_z,[imm1,#-node_size]!)
2048        __(vpush1(arg_z))
20499:
2050        __(bne 8b)
2051        __(ldr arg_x,[imm1,#-node_size*1])
2052        __(ldr arg_y,[imm1,#-node_size*2])
2053        __(ldr arg_z,[imm1,#-node_size*3])
2054        __(bx lr)
2055
2056/* lexpr count is two: set arg_y, arg_z from the  */
2057/* lexpr, maybe vpop arg_x  */
20582:
2059        __(cmp nargs,#2<<fixnumshift)
2060        __(ldr arg_y,[imm1,#-node_size*1])
2061        __(ldr arg_z,[imm1,#-node_size*2])
2062        __(bxeq lr)  /* return if (new) nargs = 2  */
2063        __(vpop1(arg_x))
2064        __(bx lr)
2065
2066/* lexpr count is one: set arg_z from the lexpr,  */
2067/* maybe vpop arg_y, arg_x  */
20681: 
2069        __(cmp nargs,#2<<fixnumshift)
2070        __(ldr arg_z,[imm1,#-node_size])
2071        __(bxlt lr)  /* return if (new) nargs < 2  */
2072        __(vpop1(arg_y))
2073        __(bxeq lr)  /* return if (new) nargs = 2  */
2074        __(vpop1(arg_x))
2075        __(bx lr)
2076
2077
2078_spentry(reset)
2079        __(nop)
2080        __(ref_nrs_value(temp0,toplcatch))
2081        __(mov temp1,#XSTKOVER)
2082        __(vpush1(temp0))
2083        __(vpush1(temp1))
2084        __(set_nargs(1))
2085        __(b _SPthrow)
2086
2087
2088/* "slide" nargs worth of values up the vstack.  IMM0 contains  */
2089/* the difference between the current VSP and the target.  */
2090_spentry(mvslide)
2091        __(cmp nargs,#0)
2092        __(mov temp1,nargs)
2093        __(add imm1,vsp,nargs)
2094        __(add imm1,imm1,imm0)
2095        __(add imm0,vsp,nargs)
2096        __(beq 2f)
20971:
2098        __(subs temp1,temp1,#1<<fixnumshift)
2099        __(ldr temp0,[imm0,#-node_size]!)
2100        __(str temp0,[imm1,#-node_size]!)
2101        __(bne 1b)
2102        2:
2103        __(mov vsp,imm1)
2104        __(bx lr)
2105
2106dnl /* Build a new TSP area to hold nargs worth of multiple-values.  */
2107dnl /* Pop the multiple values off of the vstack.  */
2108dnl /* The new TSP frame will look like this:  */
2109dnl /*  */
2110dnl /*+--------+-------+-------+---------+--------+--------+--------+======+----------+ */
2111dnl /*| ptr to | zero  | nargs | ptr to  | valn-1 | valn-2 | val-0  | ???? | prev TSP |  */
2112dnl /*|  prev  |       |       |  prev   |        |        |        | fill |          |  */
2113dnl /*| TSP    |       |       | segment |        |        |        |      |          | */
2114dnl /*+--------+-------+-------+---------+--------+--------+--------+------+----------+  */
2115dnl /*  */
2116dnl /* e.g., the first multiple value goes in the last cell in the frame, the  */
2117dnl /* count of values goes in the first word, and the word after the value count  */
2118dnl /* is 0 if the number of values is even (for alignment).  */
2119dnl /* Subsequent calls to .SPadd_values preserve this alignment.  */
2120dnl /* .SPrecover_values is therefore pretty simple.  */
2121dnl
2122_spentry(save_values)
2123dnl  __(mov imm1,tsp)
2124dnl
2125dnl         /* common exit: nargs = values in this set, imm1 = ptr to tsp before  */
2126dnl         /* call to save_values  */
2127dnl local_label(save_values_to_tsp):
2128dnl  __(mov imm2,tsp)
2129dnl  __(dnode_align(imm0,nargs,tsp_frame.fixed_overhead+(2*node_size))) /* count, link  */
2130dnl  __(TSP_Alloc_Var_Boxed_nz(imm0,imm3))
2131dnl  __(str(imm1,tsp_frame.backlink(tsp))) /* keep one tsp "frame" as far as rest of lisp is concerned  */
2132dnl  __(str(nargs,tsp_frame.data_offset(tsp)))
2133dnl  __(str(imm2,tsp_frame.data_offset+node_size(tsp))) /* previous tsp  */
2134dnl  __(la imm3,tsp_frame.data_offset+node_size*2(tsp))
2135dnl  __(add imm3,imm3,nargs)
2136dnl  __(add imm0,vsp,nargs)
2137dnl  __(cmpr(imm0,vsp))
2138dnl  __(b 2f)
2139dnl 1:
2140dnl  __(ldru(arg_z,-node_size(imm0)))
2141dnl  __(cmpr(imm0,vsp))
2142dnl  __(stru(arg_z,-node_size(imm3)))
2143dnl 2:
2144dnl  __(bne 1b)
2145dnl  __(add vsp,vsp,nargs) /*  discard values  */
2146dnl  __(bx lr)
2147dnl 
2148dnl
2149dnl /* Add the multiple values that are on top of the vstack to the set  */
2150dnl /* saved in the top tsp frame, popping them off of the vstack in the  */
2151dnl /* process.  It is an error (a bad one) if the TSP contains something  */
2152dnl /* other than a previously saved set of multiple-values.  */
2153dnl /* Since adding to the TSP may cause a new TSP segment to be allocated,  */
2154dnl /* each add_values call adds another linked element to the list of  */
2155dnl /* values. This makes recover_values harder.  */
2156dnl
2157_spentry(add_values)
2158dnl  __(cmpri(nargs,0))
2159dnl  __(ldr imm1,[tsp,#0])
2160dnl  __(bne local_label(save_values_to_tsp))
2161dnl  __(bx lr)
2162dnl         
2163
2164/* Like misc_alloc (a LOT like it, since it does most of the work), but takes  */
2165/* an initial-value arg in arg_z, element_count in arg_x, subtag in arg_y.  */
2166/* Calls out to %init-misc, which does the rest of the work.  */
2167
2168_spentry(misc_alloc_init)
2169        __(build_lisp_frame(imm0))
2170        __(mov fn,#0)
2171        __(mov temp2,arg_z)  /* initval  */
2172        __(mov arg_z,arg_y)  /* subtag  */
2173        __(mov arg_y,arg_x)  /* element-count  */
2174        __(bl _SPmisc_alloc)
2175        __(restore_lisp_frame(imm0))
2176        __(ref_nrs_symbol(fname,init_misc,imm0))
2177        __(set_nargs(2))
2178        __(mov arg_y,temp2)
2179        __(jump_fname())
2180
2181/* As in stack_misc_alloc above, only with a non-default initial-value.  */
2182/* The funny part here is that we build a lisp frame, then push a vector
2183/* on top of it.  Shuffle things around, carefully. */       
2184               
2185 
2186_spentry(stack_misc_alloc_init)
2187        __(build_lisp_frame(imm0))
2188        __(mov arg_x,sp)
2189        __(mov fn,#0)
2190        __(mov temp2,arg_z) /* initval  */
2191        __(mov arg_z,arg_y) /* subtag  */
2192        __(mov arg_y,arg_x) /* element-count  */
2193        __(bl _SPstack_misc_alloc)
2194        __(mov imm0,#0)
2195        __(ldr lr,[arg_x,#lisp_frame.savelr])
2196        __(ldr fn,[arg_x,#lisp_frame.savefn])
2197        __(ldr vsp,[arg_x,#lisp_frame.savevsp])
2198        __(ldr imm1,[sp])
2199        __(add imm2,imm1,#lisp_frame.size)
2200        __(str imm2,[sp])
2201        __(str imm0,[arg_x,#lisp_frame.savelr])
2202        __(str imm0,[arg_x,#lisp_frame.savefn])
2203        __(str imm0,[arg_x,#lisp_frame.savevsp])
2204        __(str imm0,[arg_x,#lisp_frame.marker])
2205        __(str imm1,[sp,#lisp_frame.size]!)
2206        __(add arg_z,arg_z,#lisp_frame.size)
2207        __(ref_nrs_symbol(fname,init_misc,imm0))
2208        __(set_nargs(2))
2209        __(mov arg_y,temp2)
2210        __(jump_fname())
2211 
2212_spentry(popj)
2213        .globl C(popj)
2214C(popj):
2215        __(return_lisp_frame(imm0))
2216
2217
2218/* Divide the 64 bit unsigned integer in imm0 (low) and imm1 (high) by
2219   the 32-bit unsigned integer in imm2; return the quotient in
2220   imm0:imm1 and remainder in imm2.  We pretty much have to do this
2221   as an ff call; even if we wrote the code ourselves, we'd have to
2222   enter foreign context to use as many imm regs as we'd need.
2223   Moral: don't do integer division on the ARM.
2224*/
2225        .globl C(__aeabi_uldivmod)       
2226_spentry(udiv64by32)
2227        __(cmp imm2,#0)
2228        __(moveq arg_z,#XDIVZRO)
2229        __(moveq nargs,#1<<fixnumshift)
2230        __(beq _SPksignalerr)
2231        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2232        __(str vsp,[rcontext,#tcr.save_vsp])
2233        __(mov arg_z,rcontext)
2234        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2235        __(build_lisp_frame(r3))
2236        __(str sp,[arg_z,#tcr.last_lisp_frame])
2237        __(str allocptr,[arg_z,#tcr.save_allocptr])
2238        __(mov r3,#TCR_STATE_FOREIGN)
2239        __(str r3,[arg_z,#tcr.valence])
2240        __(mov r3,#0)
2241        __(bl C(__aeabi_uldivmod))
2242        __(mov rcontext,arg_z)
2243        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2244        __(mov allocptr,#VOID_ALLOCPTR)
2245        __(mov fn,#0)
2246        __(mov temp2,#0)
2247        __(mov temp1,#0)
2248        __(mov temp0,#0)
2249        __(mov arg_x,#TCR_STATE_LISP)
2250        __(str arg_x,[rcontext,#tcr.valence])
2251        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2252        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2253        __(ldr fn,[sp,#lisp_frame.savefn])
2254        __(ldr lr,[sp,#lisp_frame.savelr])
2255        __(discard_lisp_frame())
2256        __(bx lr)
2257
2258
2259/* arg_z should be of type (UNSIGNED-BYTE 64);  */
2260/* return high 32 bits in imm1, low 32 bits in imm0 */
2261
2262
2263_spentry(getu64)
2264        __(test_fixnum(arg_z))
2265        __(bne 1f)
2266        __(unbox_fixnum(imm0,arg_z))
2267        __(movs imm1,imm0,asr #31)
2268        __(bxeq lr)
22690:             
2270        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
22711:
2272        __(extract_typecode(imm0,arg_z))
2273        __(cmp imm0,#subtag_bignum)
2274        __(bne 0b)
2275        __(movc16(imm1,two_digit_bignum_header))
2276        __(getvheader(imm0,arg_z))
2277        __(cmp imm0,imm1)
2278        __(bne 2f)
2279        __(vrefr(imm0,arg_z,0))
2280        __(vrefr(imm1,arg_z,1))
2281        __(cmp imm1,#0)
2282        __(bxge lr)
2283        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
22842:      __(movc16(imm1,three_digit_bignum_header))
2285        __(cmp imm0,imm1)
2286        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u64))
2287        __(vrefr(imm2,arg_z,2))
2288        __(cmp imm2,#0)
2289        __(vrefr(imm1,arg_z,1))
2290        __(vrefr(imm0,arg_z,0))
2291        __(bxeq lr)
2292        __(uuo_error_reg_not_xtype(al,arg_z,xtype_u64))
2293
2294         
2295/* arg_z should be of type (SIGNED-BYTE 64);  */
2296/*    return high 32 bits  in imm1, low 32 bits in imm0  */
2297
2298_spentry(gets64)
2299        __(test_fixnum(arg_z))
2300        __(moveq imm0,arg_z,asr #fixnumshift)
2301        __(moveq imm1,imm0,asr #31)
2302        __(bxeq lr)
2303        __(mov imm2,#0)
2304        __(extract_lisptag(imm0,arg_z))
2305        __(cmp imm0,#tag_misc)
2306        __(ldreq imm2,[arg_z,#misc_header_offset])
2307        __(movc16(imm1,two_digit_bignum_header))
2308        __(cmp imm1,imm2)
2309        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s64))
2310        __(vrefr(imm1,arg_z,1))
2311        __(vrefr(imm0,arg_z,0))
2312        __(bx lr)
2313
2314
2315/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
2316/* unbound_marker), arg_y = symbol, imm1 = symbol.binding-index  */
2317_spentry(specref)
2318        __(ldr imm1,[arg_z,#symbol.binding_index])
2319        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2320        __(cmp imm1,imm0)
2321        __(ldr temp0,[rcontext,#tcr.tlb_pointer])
2322        __(mov arg_y,arg_z)
2323        __(movhs imm1,#0)
2324        __(ldr arg_z,[temp0,imm1])
2325        __(cmp arg_z,#no_thread_local_binding_marker)
2326        __(ldreq arg_z,[arg_y,#symbol.vcell])
2327        __(bx lr)
2328
2329_spentry(specrefcheck)
2330        __(ldr imm1,[arg_z,#symbol.binding_index])
2331        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2332        __(cmp imm1,imm0)
2333        __(movhs imm1,#0)
2334        __(ldr imm0,[rcontext,#tcr.tlb_pointer])
2335        __(mov arg_y,arg_z)
2336        __(ldr arg_z,[imm0,imm1])
2337        __(cmp arg_z,#no_thread_local_binding_marker)
2338        __(ldreq arg_z,[arg_y,#symbol.vcell])
2339        __(cmp arg_z,#unbound_marker)
2340        __(uuo_error_unbound(eq,arg_y))
2341        __(bx lr)
2342
2343/* arg_y = special symbol, arg_z = new value.          */
2344_spentry(specset)
2345        __(ldr imm1,[arg_y,#symbol.binding_index])
2346        __(ldr imm0,[rcontext,#tcr.tlb_limit])
2347        __(ldr imm2,[rcontext,#tcr.tlb_pointer])
2348        __(cmp imm1,imm0)
2349        __(movge imm1,#0)
2350        __(ldr temp1,[imm2,imm1])
2351        __(cmp temp1,#no_thread_local_binding_marker)
2352        __(strne arg_z,[imm2,imm1])
2353        __(bxne lr)
2354        __(mov arg_x,arg_y)
2355        __(mov arg_y,#symbol.vcell-misc_data_offset)
2356        __(b _SPgvset)
2357
2358
2359       
2360/* Construct a lisp integer out of the 32-bit signed value in imm0 */
2361/* arg_z should be of type (SIGNED-BYTE 32); return unboxed result in imm0 */
2362
2363_spentry(gets32)
2364        __(test_fixnum(arg_z))
2365        __(moveq imm0,arg_z,asr #fixnumshift)
2366        __(bxeq lr)
2367        __(extract_lisptag(imm0,arg_z))
2368        __(cmp imm0,#tag_misc)
2369        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s32))
2370        __(getvheader(imm0,arg_z))
2371        __(movc16(imm1,one_digit_bignum_header))
2372        __(cmp imm0,imm1)
2373        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_s32))
2374        __(vrefr(imm0,arg_z,0))
2375        __(bx lr)       
2376
2377
2378/*  */
2379/* arg_z should be of type (UNSIGNED-BYTE 32); return unboxed result in imm0 */
2380/*  */
2381
2382_spentry(getu32)
2383        __(test_fixnum(arg_z))
2384        __(moveq imm0,arg_z,asr #fixnumshift)
2385        __(movseq imm1,imm0,asr #31)
2386        __(bxeq lr)
2387        __(movc16(imm1,one_digit_bignum_header))
2388        __(extract_lisptag(imm0,arg_z))
2389        __(cmp imm0,#tag_misc)
2390        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
2391        __(getvheader(imm0,arg_z))
2392        __(cmp imm0,imm1)
2393        __(ldreq imm0,[arg_z,#misc_data_offset])
2394        __(beq 7f)
2395        __(movc16(imm1,two_digit_bignum_header))
2396        __(cmp imm0,imm1)
2397        __(ldreq imm0,[arg_z,#misc_data_offset])
2398        __(ldreq imm1,[arg_z,#misc_data_offset+4])
2399        __(cmpeq imm1,#0)
2400        __(bxeq lr)
2401        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
24027:             
2403        __(movs imm1,imm0,asr #31)
2404        __(bxeq lr)
2405        __(uuo_error_reg_not_xtype(ne,arg_z,xtype_u32))
2406
2407
2408/* */
2409/* As per mvpass above, but in this case fname is known to be a */
2410/* symbol. */
2411
2412_spentry(mvpasssym)
2413        __(cmp nargs,#node_size*nargregs)
2414        __(mov imm1,vsp)
2415        __(subgt imm1,imm1,#node_size*nargregs)
2416        __(addgt imm1,imm1,nargs)
2417        __(build_lisp_frame(imm0,imm1))
2418        __(ref_global(lr,ret1val_addr,imm0))
2419        __(mov fn,#0)
2420        __(jump_fname())
2421
2422_spentry(unbind)
2423        __(ldr imm1,[rcontext,#tcr.db_link])
2424        __(ldr temp0,[rcontext,#tcr.tlb_pointer])   
2425        __(ldr imm0,[imm1,#binding.sym])
2426        __(ldr temp1,[imm1,#binding.val])
2427        __(ldr imm1,[imm1,#binding.link])
2428        __(str temp1,[temp0,imm0])
2429        __(str imm1,[rcontext,#tcr.db_link])
2430        __(bx lr)
2431
2432/* Clobbers imm1,temp0,arg_x, arg_y */       
2433_spentry(unbind_n)
2434        __(ldr imm1,[rcontext,#tcr.db_link])
2435        __(ldr arg_x,[rcontext,#tcr.tlb_pointer])
24361:      __(ldr temp0,[imm1,#binding.sym])
2437        __(ldr arg_y,[imm1,#binding.val])
2438        __(ldr imm1,[imm1,#binding.link])
2439        __(subs imm0,imm0,#1)
2440        __(str arg_y,[arg_x,temp0])
2441        __(bne 1b)
2442        __(str imm1,[rcontext,#tcr.db_link])
2443        __(bx lr)
2444
2445/* */
2446/* Clobbers imm1,temp0,arg_x, arg_y */
2447
2448_spentry(unbind_to)
2449        do_unbind_to(imm1,temp1,arg_x,arg_y)
2450        __(bx lr)
2451 
2452
2453 
2454/* */
2455/* Restore the special bindings from the top of the tstack,  */
2456/* leaving the tstack frame allocated.  */
2457/* Note that there might be 0 saved bindings, in which case  */
2458/* do nothing.  */
2459/* Note also that this is -only- called from an unwind-protect  */
2460/* cleanup form, and that .SPnthrowXXX is keeping one or more  */
2461/* values in a frame on top of the tstack.  */
2462/*  */
2463                         
2464_spentry(progvrestore)
2465        __(skip_stack_vector(imm0,imm1,sp))
2466        /* There might be a lisp_frame at imm0.  Not sure */
2467        __(ldr imm0,[imm0,#node_size]) /* or maybe node_size+lisp_frame.size */
2468        __(cmp imm0,#0)
2469        __(unbox_fixnum(imm0,imm0))
2470        __(bne _SPunbind_n)
2471        __(bx lr)
2472
2473/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check  */
2474/* for pending interrupts after doing so.  */
2475_spentry(bind_interrupt_level_0)
2476        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2477        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2478        __(ldr imm0,[rcontext,#tcr.db_link])
2479        __(cmp temp0,#0)
2480        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2481        __(vpush1(temp0))
2482        __(vpush1(imm1))
2483        __(vpush1(imm0))
2484        __(mov imm0,#0)
2485        __(str imm0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2486        __(str vsp,[rcontext,#tcr.db_link])
2487        __(bxeq lr)
2488        __(ldrlt temp0,[rcontext,#tcr.interrupt_pending])
2489        __(cmp temp0,#0)
2490        __(uuo_interrupt_now(gt))
2491        __(bx lr)
2492       
2493/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect */
2494/* of disabling interrupts.)  */
2495_spentry(bind_interrupt_level_m1)
2496        __(mov imm2,#-fixnumone)
2497        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2498        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2499        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2500        __(ldr imm0,[rcontext,#tcr.db_link])
2501        __(vpush1(temp0))
2502        __(vpush1(imm1))
2503        __(vpush1(imm0))
2504        __(str imm2,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2505        __(str vsp,[rcontext,tcr.db_link])
2506        __(bx lr)
2507       
2508
2509/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
2510/* do what _SPbind_interrupt_level_0 does  */
2511_spentry(bind_interrupt_level)
2512        __(cmp arg_z,#0)
2513        __(mov imm1,#INTERRUPT_LEVEL_BINDING_INDEX)
2514        __(ldr temp1,[rcontext,#tcr.tlb_pointer])
2515        __(ldr temp0,[temp1,#INTERRUPT_LEVEL_BINDING_INDEX])
2516        __(ldr imm0,[rcontext,#tcr.db_link])
2517        __(beq _SPbind_interrupt_level_0)
2518        __(vpush1(temp0))
2519        __(vpush1(imm1))
2520        __(vpush1(imm0))
2521        __(str arg_z,[temp1,INTERRUPT_LEVEL_BINDING_INDEX])
2522        __(str vsp,[rcontext,#tcr.db_link])
2523        __(bx lr)
2524
2525/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
2526/* non-negative, check for pending interrupts.  This is often called in */
2527/* a context where nargs is significant, so save and restore nargs around */
2528/* any interrupt polling  */
2529         
2530_spentry(unbind_interrupt_level)
2531        __(ldr imm0,[rcontext,#tcr.flags])
2532        __(ldr temp2,[rcontext,#tcr.tlb_pointer])
2533        __(tst imm0,#1<<TCR_FLAG_BIT_PENDING_SUSPEND)
2534        __(ldr imm0,[rcontext,#tcr.db_link])
2535        __(ldr temp0,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2536        __(bne 5f)
25370:     
2538        __(ldr temp1,[imm0,#binding.val])
2539        __(ldr imm0,[imm0,#binding.link])
2540        __(str temp1,[temp2,#INTERRUPT_LEVEL_BINDING_INDEX])
2541        __(str imm0,[rcontext,#tcr.db_link])
2542        __(cmp temp0,#0)
2543        __(bxge lr)
2544        __(cmp temp1,#0)
2545        __(bxlt lr)
2546        __(check_enabled_pending_interrupt(imm0))
2547        __(bx lr)
25485:       /* Missed a suspend request; force suspend now if we're restoring
2549          interrupt level to -1 or greater */
2550        __(cmp temp0,#-2<<fixnumshift)
2551        __(bne 0b)
2552        __(ldr imm0,[imm1,#binding.val])
2553        __(cmp imm0,temp0)
2554        __(beq 0b)
2555        __(mov imm0,#1<<fixnumshift)
2556        __(str imm0,[temp2,INTERRUPT_LEVEL_BINDING_INDEX])
2557        __(suspend_now())
2558        __(b 0b)
2559 
2560 
2561/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
2562    We don't know whether the array is alleged to be simple or
2563   not, and don't know anythng about the element type.  */
2564_spentry(aref2)
2565        __(trap_unless_fixnum(arg_y))
2566        __(trap_unless_fixnum(arg_z))
2567        __(extract_typecode(imm2,arg_x))
2568        __(cmp imm2,#subtag_arrayH)
2569        __(ldreq imm1,[arg_x,#arrayH.rank])
2570        __(cmpeq imm1,#2<<fixnumshift)
2571        __(uuo_error_reg_not_xtype(ne,arg_x,xtype_array2d))
2572        /* It's a 2-dimensional array.  Check bounds */
2573        __(ldr imm0,[arg_x,#arrayH.dim0])
2574        __(cmp arg_y,imm0)
2575        __(uuo_error_array_bounds(hs,arg_y,arg_x))
2576        __(ldr imm0,[arg_x,#arrayH.dim0+node_size])
2577        __(cmp arg_z,imm0)
2578        __(uuo_error_array_bounds(hs,arg_z,arg_x))
2579        __(unbox_fixnum(imm0,imm0))
2580        __(mul temp0,arg_y,imm0) /* no MLA on ARMv5 */
2581        __(add arg_z,arg_z,temp0)
2582        /* arg_z is now row-major-index; get data vector and
2583           add in possible offset */
2584        __(mov arg_y,arg_x)
25850:      __(ldr imm0,[arg_y,#arrayH.displacement])
2586        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2587        __(extract_subtag(imm1,arg_y))
2588        __(cmp imm1,#subtag_vectorH)
2589        __(add arg_z,arg_z,imm0)
2590        __(bgt C(misc_ref_common))
2591        __(b 0b)
2592 
2593/* temp0 = array, arg_x = i, arg_y = j, arg_z = k */
2594_spentry(aref3)
2595        __(trap_unless_fixnum(arg_x))
2596        __(trap_unless_fixnum(arg_y))
2597        __(trap_unless_fixnum(arg_z))
2598        __(extract_typecode(imm2,temp0))
2599        __(mov imm1,#0)
2600        __(cmp imm2,#subtag_arrayH)
2601        __(ldreq imm1,[temp0,#arrayH.rank])
2602        __(cmp imm1,#3<<fixnumshift)
2603        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array3d))
2604        /* It's a 3-dimensional array.  Check bounds */
2605        __(ldr imm2,[temp0,arrayH.dim0+(node_size*2)])
2606        __(ldr imm1,[temp0,#arrayH.dim0+node_size])
2607        __(ldr imm0,[temp0,#arrayH.dim0])
2608        __(cmp arg_z,imm2)
2609        __(uuo_error_array_bounds(hs,arg_z,temp0))
2610        __(cmp arg_y,imm1)
2611        __(uuo_error_array_bounds(hs,arg_y,temp0))
2612        __(cmp arg_x,imm0)
2613        __(uuo_error_array_bounds(hs,arg_x,temp0))
2614        __(unbox_fixnum(imm2,imm2))
2615        __(unbox_fixnum(imm1,imm1))
2616        __(mul arg_y,imm2,arg_y)
2617        __(mul imm1,imm2,imm1)
2618        __(mul arg_x,imm1,arg_x)
2619        __(add arg_z,arg_z,arg_y)
2620        __(add arg_z,arg_z,arg_x)
2621        __(mov arg_y,temp0)
26220:      __(ldr arg_x,[arg_y,#arrayH.displacement])
2623        __(ldr arg_y,[arg_y,#arrayH.data_vector])
2624        __(extract_subtag(imm1,arg_y))
2625        __(cmp imm1,#subtag_vectorH)
2626        __(add arg_z,arg_x,arg_z)
2627        __(bgt C(misc_ref_common))
2628        __(b 0b)
2629
2630
2631
2632
2633/* As for aref2 above, but temp = array, arg_x = i, arg_y = j, arg_z = newval */
2634_spentry(aset2)
2635        __(extract_typecode(imm0,temp0))
2636        __(cmp imm0,#subtag_arrayH)
2637        __(ldreq imm0,[temp0,#arrayH.rank])
2638        __(cmpeq imm0,#2<<fixnumshift)
2639        __(uuo_error_reg_not_xtype(ne,temp0,xtype_array2d))
2640        __(trap_unless_fixnum(arg_x))
2641        __(trap_unless_fixnum(arg_y))
2642        /* It's a 2-dimensional array.  Check bounds */
2643        __(ldr imm0,[temp0,#arrayH.dim0])
2644        __(cmp arg_x,imm0)
2645        __(uuo_error_array_bounds(hs,arg_x,temp0))
2646        __(ldr imm0,[temp0,#arrayH.dim0+node_size])
2647        __(cmp arg_y,imm0)
2648        __(uuo_error_array_bounds(hs,arg_y,temp0))
2649        __(unbox_fixnum(imm0,imm0))
2650        __(mul temp1,arg_x,imm0)
2651        __(add arg_y,arg_y,temp1)
2652        /* arg_y is now row-major-index; get data vector and
2653           add in possible offset */
2654        __(mov arg_x,temp0)
26550:      __(ldr imm0,[arg_x,#arrayH.displacement])
2656        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2657        __(extract_subtag(imm1,arg_x))
2658        __(cmp imm1,#subtag_vectorH)
2659        __(add arg_y,arg_y,imm0)
2660        __(bgt C(misc_set_common))
2661        __(b 0b)
2662
2663                 
2664/* temp1 = array, temp0 = i, arg_x = j, arg_y = k, arg_z = new */       
2665_spentry(aset3)
2666        __(extract_typecode(imm0,temp1))
2667        __(cmp imm0,#subtag_arrayH)
2668        __(ldreq imm0,[temp1,#arrayH.rank])
2669        __(cmpeq imm0,#3<<fixnumshift)
2670        __(uuo_error_reg_not_xtype(ne,temp1,xtype_array3d))
2671        __(trap_unless_fixnum(temp0))
2672        __(trap_unless_fixnum(arg_x))
2673        __(trap_unless_fixnum(arg_y))
2674        /* It's a 3-dimensional array.  Check bounds */
2675        __(ldr imm2,[temp1,#arrayH.dim0+(node_size*2)])
2676        __(ldr imm1,[temp1,#arrayH.dim0+node_size])
2677        __(ldr imm0,[temp1,#arrayH.dim0])
2678        __(cmp arg_y,imm2)
2679        __(uuo_error_array_bounds(hs,arg_y,temp1))
2680        __(cmp arg_x,imm1)
2681        __(uuo_error_array_bounds(hs,arg_x,temp1))
2682        __(unbox_fixnum(imm1,imm1))
2683        __(cmp temp0,imm0)
2684        __(uuo_error_array_bounds(hs,temp0,temp1))
2685        __(mul arg_x,imm2,arg_x)
2686        __(mul imm1,imm2,imm1)
2687        __(mul temp0,imm1,temp0)
2688        __(add arg_y,arg_y,arg_x)
2689        __(add arg_y,arg_y,temp0)
2690        __(mov arg_x,temp1)
26910:      __(ldr temp0,[arg_x,#arrayH.displacement])
2692        __(ldr arg_x,[arg_x,#arrayH.data_vector])
2693        __(extract_subtag(imm1,arg_x))
2694        __(cmp imm1,#subtag_vectorH)
2695        __(add arg_y,arg_y,temp0)
2696        __(bgt C(misc_set_common))
2697        __(b 0b)
2698
2699
2700/* Treat the last (- nargs imm0) values on the vstack as keyword/value  */
2701/* pairs.  There'll be arg_z keyword arguments.  arg_y contains flags  */
2702/* that indicate whether &allow-other-keys was specified and whether  */
2703/* or not to leave the keyword/value pairs on the vstack for an &rest  */
2704/* argument.  Element 2 of the function in fn contains a vector of keyword.  */
2705/* If the number of arguments is greater than imm0, the difference must  */
2706/* be even.  */
2707/* All arg regs have been vpushed and the calling function has built a */
2708/* stack frame.  next_method_context must be preserved, as must the incoming */
2709/* key/value pairs and their number if we're going to make an &rest arg. */
2710           
2711
2712define(`keyword_flags',`arg_y')
2713define(`key_value_count',`arg_z')
2714
2715define(`keyword_flag_allow_other_keys',`(1<<fixnumshift)')
2716define(`keyword_flag_seen_allow_other_keys',`(2<<fixnumshift)')
2717define(`keyword_flag_unknown_keyword_seen',`(3<<fixnumshift)')
2718define(`keyword_flag_rest',`(4<<fixnumshift)')
2719
2720_spentry(keyword_bind)
2721        new_local_labels()       
2722        __(subs key_value_count,nargs,imm0)
2723        __(movmi key_value_count,#0)
2724        __(tst key_value_count,#fixnumone)
2725        __(bne local_label(odd_keywords))
2726        __(mov imm1,key_value_count,lsl #num_subtag_bits-fixnumshift)
2727        __(orr imm1,imm1,subtag_u32_vector)
2728        __(add imm0,key_value_count,#dnode_size) /* we know  count is even */
2729        __(stack_allocate_zeroed_ivector(imm1,imm0))
2730        __(mov imm0,#subtag_simple_vector)
2731        __(strb imm0,[sp])
2732        /* Copy key/value pairs in reverse order from the vstack to
2733           the gvector we just created on the cstack. */
2734        __(add imm0,vsp,key_value_count) /* src, predecrement */
2735        __(add imm1,sp,#node_size)       /* dest, postincrement */
2736        __(mov temp2,key_value_count)
2737        __(b 1f)
27380:      __(ldr arg_x,[imm0,#-node_size]!)
2739        __(str arg_x,[imm1],#node_size)
27401:      __(subs temp2,temp2,#fixnumone)
2741        __(bge 0b)
2742        /* Discard the key/value pairs from the vstack. */
2743        __(add vsp,vsp,key_value_count)
2744        __(ldr temp2,[fn,#misc_data_offset+(2*node_size)])
2745        __(getvheader(imm0,temp2))
2746        __(mov imm0,imm0,lsr #num_subtag_bits)
2747        __(mov temp0,vsp)
2748        __(mov imm1,#nil_value)
2749        /* Push a pair of NILs (value, supplied-p) for each defined keyword */
2750        __(b 3f)
27512:      __(vpush1(imm1))
2752        __(vpush1(imm1))
27533:      __(subs imm0,imm0,#1)
2754        __(bge 2b)
2755        /* Save nargs and temp1 so that we can use them in the loop(s) */
2756        __(stmdb vsp!,{imm2,temp1})
2757        /* For each provided key/value pair: if the key is :allow-other-keys
2758           and that hasn't been seen before, note that it's been seen and
2759           if the value is non-nil set the allow-other-keys bit in flags.
2760           Then search for the key in the defined keys vector.  If it's
2761           not found, note that an undefined keyword was seen by setting
2762           a bit in keyword_flags ; if it is found, use its position to
2763           index the table of value/supplied-p pairs that we pushed above.
2764           If the supplied-p var is already set, do nothing; otherwise,
2765           set the supplied-p var and value.
2766           When done, signal an error if we got an unknown keyword, or
2767           either copy the supplied key/value pairs back to the vstack
2768           if we're going to cons an &rest arg or discard them if we aren't.
2769        */
2770        __(mov imm2,#0)
2771        __(b local_label(nextvalpairtest))
2772local_label(nextvalpairloop):   
2773        __(add temp1,sp,#4)
2774        __(ldr temp1,[temp1,imm2])
2775        __(ref_nrs_symbol(imm1,kallowotherkeys,imm1))
2776        __(cmp temp1,imm1)
2777        __(tsteq keyword_flags,#keyword_flag_seen_allow_other_keys)
2778        __(bne local_label(current_key_allow_other_keys_handled))
2779        __(orr keyword_flags,keyword_flags,#keyword_flag_seen_allow_other_keys)
2780        /* Fortunately, we know what the keyword is.  Need to check the
2781           value here, and don't have a lot of free registers ... */
2782        __(add temp1,sp,#8)
2783        __(ldr temp1,[temp1,imm2])
2784        __(cmp temp1,#nil_value)
2785        __(orrne keyword_flags,keyword_flags,#keyword_flag_allow_other_keys)
2786        __(mov temp1,imm1)      /* from comparison above */
2787local_label(current_key_allow_other_keys_handled):
2788        __(getvheader(imm0,temp1))
2789        __(header_length(arg_x,imm0))
2790        __(add imm0,arg_x,#misc_data_offset)
2791        __(b local_label(defined_keyword_compare_test))
2792local_label(defined_keyword_compare_loop):     
2793        __(ldr arg_x,[temp2,imm0])
2794        __(cmp arg_x,temp1)
2795        __(subeq imm0,imm0,#misc_data_offset)
2796        __(beq local_label(defined_keyword_found))
2797local_label(defined_keyword_compare_test):     
2798        __(sub imm0,imm0,#node_size)
2799        __(cmp imm0,#misc_data_offset)
2800        __(bge local_label(defined_keyword_compare_loop))
2801        /* keyword wasn't defined.  Note that ... */
2802        __(orr keyword_flags,keyword_flags,#keyword_flag_unknown_keyword_seen)
2803        __(b local_label(nextkeyvalpairnext))
2804local_label(defined_keyword_found):     
2805        __(sub imm0,temp0,imm0,lsl #1)
2806        __(ldr arg_x,[imm0,#-8])
2807        __(cmp arg_x,#nil_value) /* seen this keyword yet ? */
2808        __(bne local_label(nextkeyvalpairnext))
2809        __(add arg_x,arg_x,#t_offset)
2810        __(str arg_x,[imm0,#-8])
2811        __(add temp1,sp,#8)
2812        __(ldr temp1,[temp1,imm2])
2813        __(str temp1,[imm0,#-4])
2814local_label(nextkeyvalpairnext):
2815        __(add imm2,imm2,#8)
2816local_label(nextvalpairtest):   
2817        __(cmp imm2,key_value_count)
2818        __(bne local_label(nextvalpairloop))
2819        __(ldmia vsp!,{imm2,temp1})
2820        /* If unknown keywords and that's not allowed, signal error.
2821           Otherwise, discard the stack-consed vector and return,
2822           possibly after having copied the vector's contents back
2823           to the vstack so that an &rest arg can be constructed.
2824        */
2825        __(tst keyword_flags,#keyword_flag_unknown_keyword_seen)
2826        __(beq 0f)
2827        __(tst keyword_flags,#keyword_flag_allow_other_keys)
2828        __(beq local_label(badkeys))
28290:      __(tst keyword_flags,#keyword_flag_rest)
2830        __(beq local_label(discard_stack_vector))
2831        __(mov nargs,#0)
2832        __(add temp2,sp,#node_size)
2833        __(b 2f)
28341:      __(ldr arg_x,[temp2],#node_size)
2835        __(vpush1(arg_x))
2836        __(add nargs,nargs,#fixnumone)
28372:      __(cmp nargs,key_value_count)
2838        __(bne 1b)
2839local_label(discard_stack_vector):     
2840        __(add key_value_count,key_value_count,#dnode_size)
2841        __(add sp,sp,key_value_count)
2842        __(bx lr)               /* it's finally over ! */
2843
2844local_label(badkeys):   /* Disturbingly similar to the &rest case */
2845        __(mov nargs,#0)
2846        __(add temp2,sp,#node_size)
2847        __(mov vsp,temp0)
2848        __(b 1f)
28490:      __(ldr arg_x,[temp2],#node_size)
2850        __(vpush1(arg_x))
2851        __(add nargs,nargs,#fixnumone)
28521:      __(cmp nargs,key_value_count)
2853        __(bne 0b)
2854        /* Lose the stack vector */
2855        __(add key_value_count,key_value_count,#dnode_size)
2856        __(add sp,sp,key_value_count)
2857local_label(error_exit):               
2858        __(bl _SPconslist)
2859        __(mov arg_y,#XBADKEYS)
2860        __(set_nargs(2))
2861        __(b _SPksignalerr)
2862local_label(odd_keywords):       
2863        __(mov nargs,key_value_count)
2864        __(b local_label(error_exit))
2865
2866        .globl C(__aeabi_uidivmod)               
2867_spentry(udiv32)
2868        __(cmp imm1,#0)
2869        __(moveq arg_z,#XDIVZRO)
2870        __(moveq nargs,#1<<fixnumshift)
2871        __(beq _SPksignalerr)
2872        __(stmdb vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2873        __(str vsp,[rcontext,#tcr.save_vsp])
2874        __(mov arg_z,rcontext)
2875        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2876        __(build_lisp_frame(r3))
2877        __(str sp,[arg_z,#tcr.last_lisp_frame])
2878        __(str allocptr,[arg_z,#tcr.save_allocptr])
2879        __(mov r3,#TCR_STATE_FOREIGN)
2880        __(str r3,[arg_z,#tcr.valence])
2881        __(mov r3,#0)
2882        __(bl C(__aeabi_uidivmod))
2883        __(mov rcontext,arg_z)
2884        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2885        __(mov allocptr,#VOID_ALLOCPTR)
2886        __(mov fn,#0)
2887        __(mov temp2,#0)
2888        __(mov temp1,#0)
2889        __(mov temp0,#0)
2890        __(mov arg_x,#TCR_STATE_LISP)
2891        __(str arg_x,[rcontext,#tcr.valence])
2892        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2893        __(ldm vsp!,{arg_z,arg_y,arg_x,temp0,temp1,temp2})
2894        __(ldr fn,[sp,#lisp_frame.savefn])
2895        __(ldr lr,[sp,#lisp_frame.savelr])
2896        __(discard_lisp_frame())
2897        __(bx lr)
2898
2899_spentry(sdiv32)
2900        __(build_lisp_frame(imm2))
2901pushdef(`sign',`temp0')
2902pushdef(`d',`r0')
2903pushdef(`r',`r1')               
2904        __(ands sign,d,#0x80000000)
2905        __(rsbmi d,d,#0)
2906        __(eors sign,sign,r,asr #32)
2907        __(rsbcs r,r,#0)
2908        __(bl _SPudiv32)
2909        __(movs sign,sign,lsl #1)
2910        __(rsbcs d,d,#0)
2911        __(rsbmi r,r,#0)
2912        __(return_lisp_frame(imm2))
2913popdef(`sign')
2914popdef(`d',)
2915popdef(`r',)               
2916       
2917
2918               
2919_spentry(eabi_ff_call)
2920        __(ldr arg_y,[rcontext,#tcr.last_lisp_frame])
2921        __(stmdb vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2922        __(str vsp,[rcontext,#tcr.save_vsp])
2923/* There's a u32 vector on top of the stack ; its first data word points
2924   to the previous stack object.  The 4 words at the bottom of the vector
2925   are reserved for a lisp frame, which we construct carefully ... */
2926        __(mov imm0,#lisp_frame_marker)
2927        __(mov imm1,#0)
2928        __(ldr temp0,[sp,#4])
2929        __(sub temp0,temp0,#lisp_frame.size)
2930        __(str imm0,[temp0,#lisp_frame.marker])
2931        __(ldr imm0,[sp,#0])       
2932        __(str imm1,[temp0,#lisp_frame.savefn])
2933        __(str imm1,[temp0,#lisp_frame.savelr])
2934        __(sub imm0,imm0,#(lisp_frame.size/4)<<num_subtag_bits)
2935        __(str vsp,[temp0,#lisp_frame.savevsp])
2936        __(str imm0,[sp,#0])
2937        __(str lr,[temp0,#lisp_frame.savelr])
2938        __(str fn,[temp0,#lisp_frame.savefn])
2939        __(str allocptr,[rcontext,#tcr.save_allocptr])
2940        __(str temp0,[rcontext,#tcr.last_lisp_frame])
2941        __(mov temp0,rcontext)
2942        __(test_fixnum(arg_z))
2943        __(moveq imm1,arg_z,asr #fixnumshift)
2944        __(ldrne imm1,[arg_z,#misc_data_offset])
2945        __(mov imm0,#TCR_STATE_FOREIGN)
2946        __(str imm0,[rcontext,#tcr.valence])
2947        __(mov r4,imm1)
2948        __(add sp,sp,#dnode_size)
2949        __(ldmia sp!,{r0,r1,r2,r3})
2950        __(blx r4)
2951        __(mov temp1,#0)
2952        __(mov temp2,#0)
2953        __(mov arg_z,#0)
2954        __(mov arg_y,#0)
2955        __(mov arg_x,#0)
2956        __(mov fn,#0)
2957        __(mov allocptr,#VOID_ALLOCPTR)
2958        __(mov rcontext,temp0)
2959        __(ldr sp,[rcontext,#tcr.last_lisp_frame])
2960        __(str fn,[rcontext,#tcr.valence])
2961        __(ldr allocptr,[rcontext,#tcr.save_allocptr])
2962        __(restore_lisp_frame(temp0))
2963        __(ldmia vsp!,{arg_y,arg_x,temp0,temp1,temp2})
2964        __(str arg_y,[rcontext,#tcr.last_lisp_frame])
2965        __(bx lr)
2966       
2967       
2968
2969_spentry(debind)
2970        new_local_labels()
2971        __(mov temp0,vsp)
2972        __(mov temp1,arg_z)
2973        __(ands imm0,nargs,#0xff)
2974        __(mov arg_y,#nil_value)
2975        __(b local_label(req_test))
2976local_label(req_loop): 
2977        __(cmp arg_reg,#nil_value)
2978        __(extract_lisptag(imm1,arg_reg))
2979        __(beq local_label(toofew))
2980        __(cmp imm1,#tag_list)
2981        __(bne local_label(badlist))
2982        __(subs imm0,imm0,#1)
2983        __(_car(arg_x,arg_reg))
2984        __(_cdr(arg_reg,arg_reg))
2985        __(vpush1(arg_x))
2986local_label(req_test):
2987        __(bne local_label(req_loop))
2988        __(mov imm0,#0xff)
2989        __(ands imm0,imm0,nargs,lsr #8)
2990        __(beq local_label(rest_keys))
2991        __(tst nargs,#mask_initopt)
2992        __(bne local_label(opt_supp))
2993        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2994local_label(simple_opt_loop):
2995        __(cmp arg_reg,#nil_value)
2996        __(extract_lisptag(imm1,arg_reg))
2997        __(beq local_label(default_simple_opt))
2998        __(cmp imm1,#tag_list)
2999        __(bne local_label(badlist))
3000        __(subs imm0,imm0,#1)
3001        __(_car(arg_x,arg_reg))
3002        __(_cdr(arg_reg,arg_reg))
3003        __(vpush1(arg_x))
3004        __(bne local_label(simple_opt_loop))
3005        __(b local_label(rest_keys))
3006local_label(default_simple_opt):       
3007        __(subs imm0,imm0,#1)
3008        __(vpush1(arg_y))
3009        __(bne local_label(default_simple_opt))
3010        __(b local_label(rest_keys))
3011local_label(opt_supp):   
3012        __(cmp arg_reg,#nil_value)
3013        __(extract_lisptag(imm1,arg_reg))
3014        __(beq local_label(default_hard_opt))
3015        __(cmp imm1,#tag_list)
3016        __(bne local_label(badlist))
3017        __(subs imm0,imm0,#1)
3018        __(_car(arg_x,arg_reg))
3019        __(_cdr(arg_reg,arg_reg))
3020        __(vpush1(arg_x))
3021        __(add arg_x,arg_y,#t_offset)
3022        __(vpush1(arg_x))
3023        __(bne local_label(opt_supp))
3024        __(b local_label(rest_keys))
3025local_label(default_hard_opt): 
3026        __(subs imm0,imm0,#1)
3027        __(vpush1(arg_y))
3028        __(vpush1(arg_y))
3029        __(bne local_label(default_hard_opt))
3030local_label(rest_keys):
3031        __(tst nargs,#mask_restp)
3032        __(bne local_label(have_rest))
3033        __(tst nargs,#mask_keyp)
3034        __(bne local_label(have_keys))
3035        __(cmp arg_reg,#nil_value)
3036        __(bne local_label(toomany))
3037        __(bx lr)
3038local_label(have_rest):
3039        __(vpush1(arg_reg))
3040        __(tst nargs,#mask_keyp)
3041        __(bne local_label(have_keys))
3042        __(bx lr)
3043local_label(have_keys):
3044        __(mov imm0,#256)
3045        __(mov arg_y,arg_reg)
3046local_label(count_keys_loop):   
3047        __(cmp arg_y,#nil_value)
3048        __(beq local_label(counted_keys))
3049        __(subs imm0,imm0,#1)
3050        __(bmi local_label(toomany))
3051        __(extract_lisptag(imm1,arg_y))
3052        __(cmp imm1,#tag_list)
3053        __(bne local_label(badlist))
3054        __(_cdr(arg_y,arg_y))
3055        __(extract_lisptag(imm1,arg_y))
3056        __(cmp imm1,#tag_list)
3057        __(bne local_label(badlist))
3058        __(_cdr(arg_y,arg_y))
3059        __(b local_label(count_keys_loop))
3060local_label(counted_keys):     
3061        /* We've got a proper, even-length list of key/value pairs in  */
3062        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
3063        /* of NILs on the vstack.  (We've also cdred down arg_y until it */
3064        /* contains NIL.) */
3065        __(mov imm0,#0xff)
3066        __(ands imm0,imm0,nargs,lsr #16)
3067        __(mov imm1,vsp)
3068        __(b local_label(push_pair_test))
3069local_label(push_pair_loop):
3070        __(subs imm0,imm0,#1)
3071        __(vpush1(arg_y))
3072        __(vpush1(arg_y))
3073local_label(push_pair_test):   
3074        __(bne local_label(push_pair_loop))
3075        __(b local_label(provided_key_loop))
3076       
3077local_label(next_provided_key):
3078        __(_car(arg_x,arg_reg))
3079        __(ref_nrs_symbol(imm0,kallowotherkeys,imm0))
3080        __(cmp arg_x,imm0)
3081        __(bne local_label(not_aok))
3082        __(tst nargs,#mask_aok_seen)
3083        __(beq local_label(not_aok))
3084        __(_cdr(arg_x,arg_reg))
3085        __(_car(arg_x,arg_x))
3086        __(orr nargs,nargs,#mask_aok_seen)
3087        __(cmp arg_x,#nil_value)
3088        __(orrne nargs,nargs,#mask_aok)
3089        __(_car(arg_x,arg_reg))
3090local_label(not_aok):   
3091        __(getvheader(imm0,keyvect_reg))
3092        __(header_length(arg_y,imm0))
3093        __(add imm0,arg_y,#misc_data_offset)
3094        __(b local_label(match_key_test))
3095local_label(match_key_loop):   
3096        __(ldr arg_y,[keyvect_reg,imm0])
3097        __(cmp arg_x,arg_y)
3098        __(bne local_label(match_key_test))
3099        __(sub imm0,imm0,#misc_data_offset)
3100        __(sub imm0,imm1,imm0,lsl #1)
3101        __(ldr arg_y,[imm0,#-node_size])
3102        __(cmp arg_y,#nil_value)
3103        __(beq local_label(provided_key_done))
3104        __(_cdr(arg_x,arg_reg))
3105        __(_car(arg_x,arg_x))
3106        __(str arg_x,[imm0,#0])
3107        __(mov arg_x,#nil_value)
3108        __(add arg_x,arg_x,#t_offset)
3109        __(str arg_x,[imm0,#-node_size])
3110        __(b local_label(provided_key_done))
3111local_label(match_key_test):   
3112        __(sub imm0,imm0,#node_size)
3113        __(cmp imm0,#misc_data_offset)
3114        __(bge local_label(match_key_loop))
3115        __(orr nargs,nargs,#mask_unknown_keyword_seen)
3116local_label(provided_key_done):
3117        __(_cdr(arg_reg,arg_reg))
3118        __(_cdr(arg_reg,arg_reg))
3119local_label(provided_key_loop):
3120        __(cmp arg_reg,#nil_value)
3121        __(bne local_label(next_provided_key))
3122        __(tst nargs,#mask_unknown_keyword_seen)
3123        __(bxeq lr)
3124        __(tst nargs,#mask_aok)
3125        __(bxne lr)
3126local_label(badkeys):
3127        __(mov arg_y,#XBADKEYS)
3128        __(b local_label(destructure_error))
3129local_label(toomany):   
3130        __(mov arg_y,#XCALLTOOMANY)
3131        __(b local_label(destructure_error))
3132local_label(toofew):   
3133        __(mov arg_y,#XCALLTOOFEW)
3134        __(b local_label(destructure_error))
3135local_label(badlist):   
3136        __(mov arg_y,#XCALLNOMATCH)
3137local_label(destructure_error):
3138        __(mov vsp,temp0)
3139        __(mov arg_z,temp1)       
3140        __(set_nargs(2))
3141        __(b _SPksignalerr)
3142       
3143
3144/*  EOF, basically  */
3145       
3146_exportfn(C(misc_ref_common))
3147        __(adr imm0,(local_label(misc_ref_jmp)))
3148        __(ldr pc,[imm0,imm1,lsl #2])       
3149
3150local_label(misc_ref_jmp):         
3151        /* 00-0f  */
3152        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
3153       
3154        .long local_label(misc_ref_invalid) /* 01 cons  */
3155        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
3156        .long local_label(misc_ref_invalid) /* 03 imm  */
3157        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
3158        .long local_label(misc_ref_invalid) /* 05 nil  */
3159        .long local_label(misc_ref_invalid) /* 06 misc  */
3160        .long local_label(misc_ref_u32) /* 07 bignum  */
3161        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
3162        .long local_label(misc_ref_invalid) /* 09 cons  */
3163        .long local_label(misc_ref_node) /* 0a ratio  */
3164        .long local_label(misc_ref_invalid) /* 0b imm  */
3165        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
3166        .long local_label(misc_ref_invalid) /* 0d nil  */
3167        .long local_label(misc_ref_invalid) /* 0e misc  */
3168        .long local_label(misc_ref_u32) /* 0f single_float  */
3169        /* 10-1f  */
3170        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
3171        .long local_label(misc_ref_invalid) /* 11 cons  */
3172        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
3173        .long local_label(misc_ref_invalid) /* 13 imm  */
3174        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
3175        .long local_label(misc_ref_invalid) /* 15 nil  */
3176        .long local_label(misc_ref_invalid) /* 16 misc  */
3177        .long local_label(misc_ref_u32) /* 17 double_float  */
3178        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
3179        .long local_label(misc_ref_invalid) /* 19 cons  */
3180        .long local_label(misc_ref_node) /* 1a complex  */
3181        .long local_label(misc_ref_invalid) /* 1b imm  */
3182        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
3183        .long local_label(misc_ref_invalid) /* 1d nil  */
3184        .long local_label(misc_ref_invalid) /* 1e misc  */
3185        .long local_label(misc_ref_u32) /* 1f macptr  */
3186        /* 20-2f  */
3187        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
3188        .long local_label(misc_ref_invalid) /* 21 cons  */
3189        .long local_label(misc_ref_node) /* 22 catch_frame  */
3190        .long local_label(misc_ref_invalid) /* 23 imm  */
3191        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
3192        .long local_label(misc_ref_invalid) /* 25 nil  */
3193        .long local_label(misc_ref_invalid) /* 26 misc  */
3194        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
3195        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
3196        .long local_label(misc_ref_invalid) /* 29 cons  */
3197        .long local_label(misc_ref_node) /* 2a function  */
3198        .long local_label(misc_ref_invalid) /* 2b imm  */
3199        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
3200        .long local_label(misc_ref_invalid) /* 2d nil  */
3201        .long local_label(misc_ref_invalid) /* 2e misc  */
3202        .long local_label(misc_ref_u32) /* 2f code_vector  */
3203        /* 30-3f  */
3204        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
3205        .long local_label(misc_ref_invalid) /* 31 cons  */
3206        .long local_label(misc_ref_node) /* 32 lisp_thread  */
3207        .long local_label(misc_ref_invalid) /* 33 imm  */
3208        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
3209        .long local_label(misc_ref_invalid) /* 35 nil  */
3210        .long local_label(misc_ref_invalid) /* 36 misc  */
3211        .long local_label(misc_ref_u32) /* 37 creole  */
3212        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
3213        .long local_label(misc_ref_invalid) /* 39 cons  */
3214        .long local_label(misc_ref_node) /* 3a symbol  */
3215        .long local_label(misc_ref_invalid) /* 3b imm  */
3216        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
3217        .long local_label(misc_ref_invalid) /* 3d nil  */
3218        .long local_label(misc_ref_invalid) /* 3e misc  */
3219        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
3220        /* 40-4f  */
3221        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
3222        .long local_label(misc_ref_invalid) /* 41 cons  */
3223        .long local_label(misc_ref_node) /* 42 lock  */
3224        .long local_label(misc_ref_invalid) /* 43 imm  */
3225        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
3226        .long local_label(misc_ref_invalid) /* 45 nil  */
3227        .long local_label(misc_ref_invalid) /* 46 misc  */
3228        .long local_label(misc_ref_invalid) /* 47 immheader  */
3229        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
3230        .long local_label(misc_ref_invalid) /* 49 cons  */
3231        .long local_label(misc_ref_node) /* 4a hash_vector  */
3232        .long local_label(misc_ref_invalid) /* 4b imm  */
3233        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
3234        .long local_label(misc_ref_invalid) /* 4d nil  */
3235        .long local_label(misc_ref_invalid) /* 4e misc  */
3236        .long local_label(misc_ref_invalid) /* 4f immheader  */
3237        /* 50-5f  */
3238        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
3239        .long local_label(misc_ref_invalid) /* 51 cons  */
3240        .long local_label(misc_ref_node) /* 52 pool  */
3241        .long local_label(misc_ref_invalid) /* 53 imm  */
3242        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
3243        .long local_label(misc_ref_invalid) /* 55 nil  */
3244        .long local_label(misc_ref_invalid) /* 56 misc  */
3245        .long local_label(misc_ref_invalid) /* 57 immheader  */
3246        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
3247        .long local_label(misc_ref_invalid) /* 59 cons  */
3248        .long local_label(misc_ref_node) /* 5a weak  */
3249        .long local_label(misc_ref_invalid) /* 5b imm  */
3250        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
3251        .long local_label(misc_ref_invalid) /* 5d nil  */
3252        .long local_label(misc_ref_invalid) /* 5e misc  */
3253        .long local_label(misc_ref_invalid) /* 5f immheader  */
3254        /* 60-6f  */
3255        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
3256        .long local_label(misc_ref_invalid) /* 61 cons  */
3257        .long local_label(misc_ref_node) /* 62 package  */
3258        .long local_label(misc_ref_invalid) /* 63 imm  */
3259        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
3260        .long local_label(misc_ref_invalid) /* 65 nil  */
3261        .long local_label(misc_ref_invalid) /* 66 misc  */
3262        .long local_label(misc_ref_invalid) /* 67 immheader  */
3263        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
3264        .long local_label(misc_ref_invalid) /* 69 cons  */
3265        .long local_label(misc_ref_node) /* 6a slot_vector  */
3266        .long local_label(misc_ref_invalid) /* 6b imm  */
3267        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
3268        .long local_label(misc_ref_invalid) /* 6d nil  */
3269        .long local_label(misc_ref_invalid) /* 6e misc  */
3270        .long local_label(misc_ref_invalid) /* 6f immheader  */
3271        /* 70-7f  */
3272        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
3273        .long local_label(misc_ref_invalid) /* 71 cons  */
3274        .long local_label(misc_ref_node) /* 72 instance  */
3275        .long local_label(misc_ref_invalid) /* 73 imm  */
3276        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
3277        .long local_label(misc_ref_invalid) /* 75 nil  */
3278        .long local_label(misc_ref_invalid) /* 76 misc  */
3279        .long local_label(misc_ref_invalid) /* 77 immheader  */
3280        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
3281        .long local_label(misc_ref_invalid) /* 79 cons  */
3282        .long local_label(misc_ref_node) /* 7a struct  */
3283        .long local_label(misc_ref_invalid) /* 7b imm  */
3284        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
3285        .long local_label(misc_ref_invalid) /* 7d nil  */
3286        .long local_label(misc_ref_invalid) /* 7e misc  */
3287        .long local_label(misc_ref_invalid) /* 7f immheader  */
3288        /* 80-8f  */
3289        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
3290        .long local_label(misc_ref_invalid) /* 81 cons  */
3291        .long local_label(misc_ref_node) /* 82 istruct  */
3292        .long local_label(misc_ref_invalid) /* 83 imm  */
3293        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
3294        .long local_label(misc_ref_invalid) /* 85 nil  */
3295        .long local_label(misc_ref_invalid) /* 86 misc  */
3296        .long local_label(misc_ref_invalid) /* 87 immheader  */
3297        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
3298        .long local_label(misc_ref_invalid) /* 89 cons  */
3299        .long local_label(misc_ref_node) /* 8a value_cell  */
3300        .long local_label(misc_ref_invalid) /* 8b imm  */
3301        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
3302        .long local_label(misc_ref_invalid) /* 8d nil  */
3303        .long local_label(misc_ref_invalid) /* 8e misc  */
3304        .long local_label(misc_ref_invalid) /* 8f immheader  */
3305        /* 90-9f  */
3306        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
3307        .long local_label(misc_ref_invalid) /* 91 cons  */
3308        .long local_label(misc_ref_node) /* 92 xfunction  */
3309        .long local_label(misc_ref_invalid) /* 93 imm  */
3310        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
3311        .long local_label(misc_ref_invalid) /* 95 nil  */
3312        .long local_label(misc_ref_invalid) /* 96 misc  */
3313        .long local_label(misc_ref_invalid) /* 97 immheader  */
3314        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
3315        .long local_label(misc_ref_invalid) /* 99 cons  */
3316        .long local_label(misc_ref_node) /* 9a arrayN  */
3317        .long local_label(misc_ref_invalid) /* 9b imm  */
3318        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
3319        .long local_label(misc_ref_invalid) /* 9d nil  */
3320        .long local_label(misc_ref_invalid) /* 9e misc  */
3321        .long local_label(misc_ref_invalid) /* 9f immheader  */
3322        /* a0-af  */
3323        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
3324        .long local_label(misc_ref_invalid) /* a1 cons  */
3325        .long local_label(misc_ref_node) /* a2 vectorH  */
3326        .long local_label(misc_ref_invalid) /* a3 imm  */
3327        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
3328        .long local_label(misc_ref_invalid) /* a5 nil  */
3329        .long local_label(misc_ref_invalid) /* a6 misc  */
3330        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
3331        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
3332        .long local_label(misc_ref_invalid) /* a9 cons  */
3333        .long local_label(misc_ref_node) /* aa simple_vector  */
3334        .long local_label(misc_ref_invalid) /* ab imm  */
3335        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
3336        .long local_label(misc_ref_invalid) /* ad nil  */
3337        .long local_label(misc_ref_invalid) /* ae misc  */
3338        .long local_label(misc_ref_u32) /* af u32  */
3339        /* b0-bf  */
3340        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
3341        .long local_label(misc_ref_invalid) /* b1 cons  */
3342        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
3343        .long local_label(misc_ref_invalid) /* b3 imm  */
3344        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
3345        .long local_label(misc_ref_invalid) /* b5 nil  */
3346        .long local_label(misc_ref_invalid) /* b6 misc  */
3347        .long local_label(misc_ref_s32) /* b7 s32  */
3348        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
3349        .long local_label(misc_ref_invalid) /* b9 cons  */
3350        .long local_label(misc_ref_invalid) /* ba nodeheader  */
3351        .long local_label(misc_ref_invalid) /* bb imm  */
3352        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
3353        .long local_label(misc_ref_invalid) /* bd nil  */
3354        .long local_label(misc_ref_invalid) /* be misc  */
3355        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
3356        /* c0-cf  */
3357        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
3358        .long local_label(misc_ref_invalid) /* c1 cons  */
3359        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
3360        .long local_label(misc_ref_invalid) /* c3 imm  */
3361        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
3362        .long local_label(misc_ref_invalid) /* c5 nil  */
3363        .long local_label(misc_ref_invalid) /* c6 misc  */
3364        .long local_label(misc_ref_new_string) /* c7 new_string  */
3365        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
3366        .long local_label(misc_ref_invalid) /* c9 cons  */
3367        .long local_label(misc_ref_invalid) /* ca nodeheader  */
3368        .long local_label(misc_ref_invalid) /* cb imm  */
3369        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
3370        .long local_label(misc_ref_invalid) /* cd nil  */
3371        .long local_label(misc_ref_invalid) /* ce misc  */
3372        .long local_label(misc_ref_u8) /* cf u8  */
3373        /* d0-df  */
3374        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
3375        .long local_label(misc_ref_invalid) /* d1 cons  */
3376        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
3377        .long local_label(misc_ref_invalid) /* d3 imm  */
3378        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
3379        .long local_label(misc_ref_invalid) /* d5 nil  */
3380        .long local_label(misc_ref_invalid) /* d6 misc  */
3381        .long local_label(misc_ref_s8)      /* d7 s8  */
3382        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
3383        .long local_label(misc_ref_invalid) /* d9 cons  */
3384        .long local_label(misc_ref_invalid) /* da nodeheader  */
3385        .long local_label(misc_ref_invalid) /* db imm  */
3386        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
3387        .long local_label(misc_ref_invalid) /* dd nil  */
3388        .long local_label(misc_ref_invalid) /* de misc  */
3389        .long local_label(misc_ref_old_string) /* df (old)subtag_simple_base_string  */
3390        /* e0-ef  */
3391        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
3392        .long local_label(misc_ref_invalid) /* e1 cons  */
3393        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
3394        .long local_label(misc_ref_invalid) /* e3 imm  */
3395        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
3396        .long local_label(misc_ref_invalid) /* e5 nil  */
3397        .long local_label(misc_ref_invalid) /* e6 misc  */
3398        .long local_label(misc_ref_u16) /* e7 u16  */
3399        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
3400        .long local_label(misc_ref_invalid) /* e9 cons  */
3401        .long local_label(misc_ref_invalid) /* ea nodeheader  */
3402        .long local_label(misc_ref_invalid) /* eb imm  */
3403        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
3404        .long local_label(misc_ref_invalid) /* ed nil  */
3405        .long local_label(misc_ref_invalid) /* ee misc  */
3406        .long local_label(misc_ref_s16) /* ef s16  */
3407        /* f0-ff  */
3408        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
3409        .long local_label(misc_ref_invalid) /* f1 cons  */
3410        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
3411        .long local_label(misc_ref_invalid) /* f3 imm  */
3412        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
3413        .long local_label(misc_ref_invalid) /* f5 nil  */
3414        .long local_label(misc_ref_invalid) /* f6 misc  */
3415        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
3416        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
3417        .long local_label(misc_ref_invalid) /* f9 cons  */
3418        .long local_label(misc_ref_invalid) /* fa nodeheader  */
3419        .long local_label(misc_ref_invalid) /* fb imm  */
3420        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
3421        .long local_label(misc_ref_invalid) /* fd nil  */
3422        .long local_label(misc_ref_invalid) /* fe misc  */
3423        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
3424
3425local_label(misc_ref_node):       
3426        /* A node vector.  */
3427        __(add imm0,arg_z,#misc_data_offset)
3428        __(ldr  arg_z,[arg_y,imm0])
3429        __(bx lr)
3430local_label(misc_ref_single_float_vector):       
3431        __(add imm0,arg_z,misc_data_offset)
3432        __(movc16(imm1,single_float_header))
3433        __(ldr imm0,[arg_y,imm0])
3434        __(Misc_Alloc_Fixed(arg_z,imm1,single_float.size))
3435        __(str imm0,[arg_z,#single_float.value])
3436        __(bx lr)
3437local_label(misc_ref_new_string):       
3438        __(add imm0,arg_z,#misc_data_offset)
3439        __(ldr imm0,[arg_y,imm0])
3440        __(mov arg_z,imm0,lsl #charcode_shift)
3441        __(orr arg_z,arg_z,#subtag_character)
3442        __(bx lr)
3443local_label(misc_ref_s32):       
3444        __(add imm0,arg_z,#misc_data_offset)
3445        __(ldr imm0,[arg_y,imm0])
3446        __(b _SPmakes32)
3447local_label(misc_ref_fixnum_vector):   
3448        __(add imm0,arg_z,#misc_data_offset)
3449        __(ldr imm0,[arg_y,imm0])
3450        __(box_fixnum(arg_z,imm0))
3451        __(bx lr)       
3452local_label(misc_ref_u32):       
3453        __(add imm0,arg_z,#misc_data_offset)
3454        __(ldr imm0,[arg_y,imm0])
3455        __(b _SPmakeu32)
3456local_label(misc_ref_double_float_vector):     
3457        __(mov imm0,arg_z,lsl #1)
3458        __(add imm0,imm0,#misc_dfloat_offset)
3459        __(ldrd imm0,imm1,[arg_y,imm0])
3460        __(movc16(imm2,double_float_header))
3461        __(Misc_Alloc_Fixed(arg_z,imm2,double_float.size))
3462        __(strd imm0,imm1,[arg_z,#double_float.value])
3463        __(bx lr)
3464local_label(misc_ref_bit_vector):
3465        __(mov imm1,#nbits_in_word-1)
3466        __(and imm1,imm1,arg_z,lsr #2)
3467        __(mov imm2,#1)
3468        __(mov imm2,imm2,lsl imm1)
3469        __(mov imm0,arg_z,lsr #5+fixnumshift)
3470        __(mov imm0,imm0,lsl #2)
3471        __(add imm0,imm0,#misc_data_offset)
3472        __(mov arg_z,#0)
3473        __(ldr imm0,[arg_y,imm0])
3474        __(tst imm0,imm2)
3475        __(addne arg_z,arg_z,#fixnumone)
3476        __(bx lr)
3477local_label(misc_ref_s8):       
3478        __(mov imm0,arg_z,lsr #2)
3479        __(add imm0,imm0,#misc_data_offset)
3480        __(ldsb imm0,[arg_y,imm0])
3481        __(box_fixnum(arg_z,imm0))
3482        __(bx lr)
3483local_label(misc_ref_u8):       
3484        __(mov imm0,arg_z,lsr #2)
3485        __(add imm0,imm0,#misc_data_offset)
3486        __(ldrb imm0,[arg_y,imm0])
3487        __(box_fixnum(arg_z,imm0))
3488        __(bx lr)
3489local_label(misc_ref_old_string):         
3490        __(mov imm0,arg_z,lsr #2)
3491        __(add imm0,imm0,#misc_data_offset)
3492        __(ldrb imm0,[arg_y,imm0])
3493        __(mov arg_z,imm0,lsl #charcode_shift)
3494        __(orr arg_z,arg_z,#subtag_character)
3495        __(bx lr)
3496local_label(misc_ref_u16):       
3497        __(mov imm0,arg_z,lsr #1)     
3498        __(add imm0,imm0,#misc_data_offset)
3499        __(ldrh imm0,[arg_y,imm0])
3500        __(box_fixnum(arg_z,imm0))
3501        __(bx lr)
3502local_label(misc_ref_s16):             
3503        __(mov imm0,arg_z,lsr #1)     
3504        __(add imm0,imm0,#misc_data_offset)
3505        __(ldrsh imm0,[arg_y,imm0])
3506        __(box_fixnum(arg_z,imm0))
3507        __(bx lr)
3508local_label(misc_ref_invalid):
3509        __(mov arg_x,#XBADVEC)
3510        __(set_nargs(3))
3511        __(b _SPksignalerr)       
3512_endfn
3513       
3514_exportfn(C(misc_set_common))
3515        __(adr imm0,local_label(misc_set_jmp))
3516        __(ldr pc,[imm0,imm1,lsl #2])
3517local_label(misc_set_jmp):             
3518        /* 00-0f  */
3519        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
3520        .long local_label(misc_set_invalid) /* 01 cons  */
3521        .long local_label(misc_set_invalid) /* 02 nodeheader  */
3522        .long local_label(misc_set_invalid) /* 03 imm  */
3523        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
3524        .long local_label(misc_set_invalid) /* 05 nil  */
3525        .long local_label(misc_set_invalid) /* 06 misc  */
3526        .long local_label(misc_set_u32) /* 07 bignum  */
3527        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
3528        .long local_label(misc_set_invalid) /* 09 cons  */
3529        .long _SPgvset /* 0a ratio  */
3530        .long local_label(misc_set_invalid) /* 0b imm  */
3531        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
3532        .long local_label(misc_set_invalid) /* 0d nil  */
3533        .long local_label(misc_set_invalid) /* 0e misc  */
3534        .long local_label(misc_set_u32) /* 0f single_float  */
3535        /* 10-1f  */
3536        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
3537        .long local_label(misc_set_invalid) /* 11 cons  */
3538        .long local_label(misc_set_invalid) /* 12 nodeheader  */
3539        .long local_label(misc_set_invalid) /* 13 imm  */
3540        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
3541        .long local_label(misc_set_invalid) /* 15 nil  */
3542        .long local_label(misc_set_invalid) /* 16 misc  */
3543        .long local_label(misc_set_u32) /* 17 double_float  */
3544        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
3545        .long local_label(misc_set_invalid) /* 19 cons  */
3546        .long _SPgvset /* 1a complex  */
3547        .long local_label(misc_set_invalid) /* 1b imm  */
3548        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
3549        .long local_label(misc_set_invalid) /* 1d nil  */
3550        .long local_label(misc_set_invalid) /* 1e misc  */
3551        .long local_label(misc_set_u32) /* 1f macptr  */
3552        /* 20-2f  */
3553        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
3554        .long local_label(misc_set_invalid) /* 21 cons  */
3555        .long _SPgvset /* 22 catch_frame  */
3556        .long local_label(misc_set_invalid) /* 23 imm  */
3557        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
3558        .long local_label(misc_set_invalid) /* 25 nil  */
3559        .long local_label(misc_set_invalid) /* 26 misc  */
3560        .long local_label(misc_set_u32) /* 27 dead_macptr  */
3561        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
3562        .long local_label(misc_set_invalid) /* 29 cons  */
3563        .long _SPgvset /* 2a function  */
3564        .long local_label(misc_set_invalid) /* 2b imm  */
3565        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
3566        .long local_label(misc_set_invalid) /* 2d nil  */
3567        .long local_label(misc_set_invalid) /* 2e misc  */
3568        .long local_label(misc_set_u32) /* 2f code_vector  */
3569        /* 30-3f  */
3570        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
3571        .long local_label(misc_set_invalid) /* 31 cons  */
3572        .long _SPgvset /* 32 lisp_thread  */
3573        .long local_label(misc_set_invalid) /* 33 imm  */
3574        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
3575        .long local_label(misc_set_invalid) /* 35 nil  */
3576        .long local_label(misc_set_invalid) /* 36 misc  */
3577        .long local_label(misc_set_u32) /* 37 creole  */
3578        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
3579        .long local_label(misc_set_invalid) /* 39 cons  */
3580        .long _SPgvset /* 3a symbol  */
3581        .long local_label(misc_set_invalid) /* 3b imm  */
3582        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
3583        .long local_label(misc_set_invalid) /* 3d nil  */
3584        .long local_label(misc_set_invalid) /* 3e misc  */
3585        .long local_label(misc_set_u32) /* 3f xcode_vector  */
3586        /* 40-4f  */
3587        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
3588        .long local_label(misc_set_invalid) /* 41 cons  */
3589        .long _SPgvset /* 42 lock  */
3590        .long local_label(misc_set_invalid) /* 43 imm  */
3591        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
3592        .long local_label(misc_set_invalid) /* 45 nil  */
3593        .long local_label(misc_set_invalid) /* 46 misc  */
3594        .long local_label(misc_set_invalid) /* 47 immheader  */
3595        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
3596        .long local_label(misc_set_invalid) /* 49 cons  */
3597        .long _SPgvset /* 4a hash_vector  */
3598        .long local_label(misc_set_invalid) /* 4b imm  */
3599        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
3600        .long local_label(misc_set_invalid) /* 4d nil  */
3601        .long local_label(misc_set_invalid) /* 4e misc  */
3602        .long local_label(misc_set_invalid) /* 4f immheader  */
3603        /* 50-5f  */
3604        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
3605        .long local_label(misc_set_invalid) /* 51 cons  */
3606        .long _SPgvset /* 52 pool  */
3607        .long local_label(misc_set_invalid) /* 53 imm  */
3608        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
3609        .long local_label(misc_set_invalid) /* 55 nil  */
3610        .long local_label(misc_set_invalid) /* 56 misc  */
3611        .long local_label(misc_set_invalid) /* 57 immheader  */
3612        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
3613        .long local_label(misc_set_invalid) /* 59 cons  */
3614        .long _SPgvset /* 5a weak  */
3615        .long local_label(misc_set_invalid) /* 5b imm  */
3616        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
3617        .long local_label(misc_set_invalid) /* 5d nil  */
3618        .long local_label(misc_set_invalid) /* 5e misc  */
3619        .long local_label(misc_set_invalid) /* 5f immheader  */
3620        /* 60-6f  */
3621        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
3622        .long local_label(misc_set_invalid) /* 61 cons  */
3623        .long _SPgvset /* 62 package  */
3624        .long local_label(misc_set_invalid) /* 63 imm  */
3625        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
3626        .long local_label(misc_set_invalid) /* 65 nil  */
3627        .long local_label(misc_set_invalid) /* 66 misc  */
3628        .long local_label(misc_set_invalid) /* 67 immheader  */
3629        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
3630        .long local_label(misc_set_invalid) /* 69 cons  */
3631        .long _SPgvset /* 6a slot_vector  */
3632        .long local_label(misc_set_invalid) /* 6b imm  */
3633        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
3634        .long local_label(misc_set_invalid) /* 6d nil  */
3635        .long local_label(misc_set_invalid) /* 6e misc  */
3636        .long local_label(misc_set_invalid) /* 6f immheader  */
3637        /* 70-7f  */
3638        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
3639        .long local_label(misc_set_invalid) /* 71 cons  */
3640        .long _SPgvset /* 72 instance  */
3641        .long local_label(misc_set_invalid) /* 73 imm  */
3642        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
3643        .long local_label(misc_set_invalid) /* 75 nil  */
3644        .long local_label(misc_set_invalid) /* 76 misc  */
3645        .long local_label(misc_set_invalid) /* 77 immheader  */
3646        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
3647        .long local_label(misc_set_invalid) /* 79 cons  */
3648        .long _SPgvset /* 7a struct  */
3649        .long local_label(misc_set_invalid) /* 7b imm  */
3650        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
3651        .long local_label(misc_set_invalid) /* 7d nil  */
3652        .long local_label(misc_set_invalid) /* 7e misc  */
3653        .long local_label(misc_set_invalid) /* 7f immheader  */
3654        /* 80-8f  */
3655        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
3656        .long local_label(misc_set_invalid) /* 81 cons  */
3657        .long _SPgvset /* 82 istruct  */
3658        .long local_label(misc_set_invalid) /* 83 imm  */
3659        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
3660        .long local_label(misc_set_invalid) /* 85 nil  */
3661        .long local_label(misc_set_invalid) /* 86 misc  */
3662        .long local_label(misc_set_invalid) /* 87 immheader  */
3663        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
3664        .long local_label(misc_set_invalid) /* 89 cons  */
3665        .long _SPgvset /* 8a value_cell  */
3666        .long local_label(misc_set_invalid) /* 8b imm  */
3667        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
3668        .long local_label(misc_set_invalid) /* 8d nil  */
3669        .long local_label(misc_set_invalid) /* 8e misc  */
3670        .long local_label(misc_set_invalid) /* 8f immheader  */
3671        /* 90-9f  */
3672        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
3673        .long local_label(misc_set_invalid) /* 91 cons  */
3674        .long _SPgvset /* 92 xfunction  */
3675        .long local_label(misc_set_invalid) /* 93 imm  */
3676        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
3677        .long local_label(misc_set_invalid) /* 95 nil  */
3678        .long local_label(misc_set_invalid) /* 96 misc  */
3679        .long local_label(misc_set_invalid) /* 97 immheader  */
3680        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
3681        .long local_label(misc_set_invalid) /* 99 cons  */
3682        .long _SPgvset /* 9a arrayH  */
3683        .long local_label(misc_set_invalid) /* 9b imm  */
3684        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
3685        .long local_label(misc_set_invalid) /* 9d nil  */
3686        .long local_label(misc_set_invalid) /* 9e misc  */
3687        .long local_label(misc_set_invalid) /* 9f immheader  */
3688        /* a0-af  */
3689        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
3690        .long local_label(misc_set_invalid) /* a1 cons  */
3691        .long _SPgvset /* a2 vectorH  */
3692        .long local_label(misc_set_invalid) /* a3 imm  */
3693        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
3694        .long local_label(misc_set_invalid) /* a5 nil  */
3695        .long local_label(misc_set_invalid) /* a6 misc  */
3696        .long local_label(misc_set_single_float_vector) /* a7 sf vector  */
3697        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
3698        .long local_label(misc_set_invalid) /* a9 cons  */
3699        .long _SPgvset /* aa vectorH  */
3700        .long local_label(misc_set_invalid) /* ab imm  */
3701        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
3702        .long local_label(misc_set_invalid) /* ad nil  */
3703        .long local_label(misc_set_invalid) /* ae misc  */
3704        .long local_label(misc_set_u32) /* af u32  */
3705        /* b0-bf  */
3706        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
3707        .long local_label(misc_set_invalid) /* b1 cons  */
3708        .long local_label(misc_set_invalid) /* b2 node  */
3709        .long local_label(misc_set_invalid) /* b3 imm  */
3710        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
3711        .long local_label(misc_set_invalid) /* b5 nil  */
3712        .long local_label(misc_set_invalid) /* b6 misc  */
3713        .long local_label(misc_set_s32) /* b7 s32  */
3714        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
3715        .long local_label(misc_set_invalid) /* b9 cons  */
3716        .long local_label(misc_set_invalid) /* ba nodeheader  */
3717        .long local_label(misc_set_invalid) /* bb imm  */
3718        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
3719        .long local_label(misc_set_invalid) /* bd nil  */
3720        .long local_label(misc_set_invalid) /* be misc  */
3721        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
3722        /* c0-cf  */
3723        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
3724        .long local_label(misc_set_invalid) /* c1 cons  */
3725        .long local_label(misc_set_invalid) /* c2 nodeheader  */
3726        .long local_label(misc_set_invalid) /* c3 imm  */
3727        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
3728        .long local_label(misc_set_invalid) /* c5 nil  */
3729        .long local_label(misc_set_invalid) /* c6 misc  */
3730        .long local_label(misc_set_new_string) /* c7 new_string  */
3731        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
3732        .long local_label(misc_set_invalid) /* c9 cons  */
3733        .long local_label(misc_set_invalid) /* ca nodeheader  */
3734        .long local_label(misc_set_invalid) /* cb imm  */
3735        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
3736        .long local_label(misc_set_invalid) /* cd nil  */
3737        .long local_label(misc_set_invalid) /* ce misc  */
3738        .long local_label(misc_set_u8) /* cf u8  */
3739        /* d0-df  */
3740        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
3741        .long local_label(misc_set_invalid) /* d1 cons  */
3742        .long local_label(misc_set_invalid) /* d2 nodeheader  */
3743        .long local_label(misc_set_invalid) /* d3 imm  */
3744        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
3745        .long local_label(misc_set_invalid) /* d5 nil  */
3746        .long local_label(misc_set_invalid) /* d6 misc  */
3747        .long local_label(misc_set_s8) /* d7 s8  */
3748        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
3749        .long local_label(misc_set_invalid) /* d9 cons  */
3750        .long local_label(misc_set_invalid) /* da nodeheader  */
3751        .long local_label(misc_set_invalid) /* db imm  */
3752        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
3753        .long local_label(misc_set_invalid) /* dd nil  */
3754        .long local_label(misc_set_invalid) /* de misc  */
3755        .long local_label(misc_set_old_string) /* df (old) simple_base_string  */
3756        /* e0-ef  */
3757        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
3758        .long local_label(misc_set_invalid) /* e1 cons  */
3759        .long local_label(misc_set_invalid) /* e2 nodeheader  */
3760        .long local_label(misc_set_invalid) /* e3 imm  */
3761        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
3762        .long local_label(misc_set_invalid) /* e5 nil  */
3763        .long local_label(misc_set_invalid) /* e6 misc  */
3764        .long local_label(misc_set_u16) /* e7 u16  */
3765        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
3766        .long local_label(misc_set_invalid) /* e9 cons  */
3767        .long local_label(misc_set_invalid) /* ea nodeheader  */
3768        .long local_label(misc_set_invalid) /* eb imm  */
3769        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
3770        .long local_label(misc_set_invalid) /* ed nil  */
3771        .long local_label(misc_set_invalid) /* ee misc  */
3772        .long local_label(misc_set_s16) /* ef s16  */
3773        /* f0-ff  */
3774        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
3775        .long local_label(misc_set_invalid) /* f1 cons  */
3776        .long local_label(misc_set_invalid) /* f2 nodeheader  */
3777        .long local_label(misc_set_invalid) /* f3 imm  */
3778        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
3779        .long local_label(misc_set_invalid) /* f5 nil  */
3780        .long local_label(misc_set_invalid) /* f6 misc  */
3781        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
3782        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
3783        .long local_label(misc_set_invalid) /* f9 cons  */
3784        .long local_label(misc_set_invalid) /* fa nodeheader  */
3785        .long local_label(misc_set_invalid) /* fb imm  */
3786        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
3787        .long local_label(misc_set_invalid) /* fd nil  */
3788        .long local_label(misc_set_invalid) /* fe misc  */
3789        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
3790
3791local_label(misc_set_u32):       
3792        /* Either a non-negative fixnum, a positive one-digit bignum, */
3793        /* or a two-digit bignum whose sign-digit is 0 is ok.  */
3794        __(add imm0,arg_y,#misc_data_offset)
3795        __(test_fixnum(arg_z))
3796        __(bne local_label(set_not_fixnum_u32))
3797        __(tst arg_z,#0x80000000)
3798        __(bne local_label(set_bad))
3799        __(unbox_fixnum(imm1,arg_z))
3800local_label(set_set32):         
3801        __(str imm1,[arg_x,imm0])
3802        __(bx lr)
3803local_label(set_not_fixnum_u32):
3804        __(extract_lisptag(imm1,arg_z))
3805        __(cmp imm1,#tag_misc)
3806        __(bne local_label(set_bad))
3807        __(movc16(imm2,one_digit_bignum_header))
3808        __(getvheader(imm1,arg_z))
3809        __(cmp imm1,imm2)
3810        __(bne local_label(set_not_1_digit_u32))
3811        __(ldr imm1,[arg_z,#misc_data_offset])
3812        __(cmp imm1,#0)
3813        __(bge local_label(set_set32))
3814        __(b local_label(set_bad))
3815local_label(set_not_1_digit_u32):
3816        __(movc16(imm2,two_digit_bignum_header))
3817        __(cmp imm1,imm2)
3818        __(bne local_label(set_bad))
3819        __(vrefr(imm2,arg_z,1))
3820        __(vrefr(imm1,arg_z,0))
3821        __(cmp imm2,#0)
3822        __(beq local_label(set_set32))
3823local_label(set_bad):
3824        /* arg_z does not match the array-element-type of arg_x.  */
3825        __(mov arg_y,arg_z)
3826        __(mov arg_z,arg_x)
3827        __(mov arg_x,#XNOTELT)
3828        __(set_nargs(3))
3829        __(b _SPksignalerr)
3830local_label(misc_set_fixnum_vector):   
3831        __(add imm0,arg_z,#misc_data_offset)
3832        __(test_fixnum(arg_z))
3833        __(bne local_label(set_bad))
3834        __(unbox_fixnum(imm1,arg_z))
3835        __(str imm1,[arg_x,imm0])
3836        __(bx lr)
3837local_label(misc_set_new_string):   
3838        __(add imm0,arg_z,#misc_data_offset)
3839        __(extract_lowbyte(imm2,arg_z))
3840        __(cmp imm2,#subtag_character)
3841        __(bne local_label(set_bad))
3842        __(unbox_character(imm1,arg_z))
3843        __(str imm1,[arg_x,imm0])
3844        __(bx lr)
3845local_label(misc_set_s32):
3846        __(add imm0,arg_z,#misc_data_offset)
3847        __(test_fixnum(arg_z))
3848        __(moveq imm1,arg_z,asr #fixnumshift)
3849        __(beq local_label(set_set32))
3850        __(extract_lisptag(imm2,arg_z))
3851        __(cmp imm2,#tag_misc)
3852        __(bne local_label(set_bad))
3853        __(movc16(imm1,one_digit_bignum_header))
3854        __(getvheader(imm2,arg_z))
3855        __(cmp imm2,imm1)
3856        __(vrefr(imm1,arg_z,0))
3857        __(beq local_label(set_set32))
3858        __(b local_label(set_bad))
3859local_label(misc_set_single_float_vector):
3860        __(add imm0,arg_z,#misc_data_offset)
3861        __(extract_typecode(imm2,arg_z))
3862        __(cmp imm2,#subtag_single_float)
3863        __(bne local_label(set_bad))
3864        __(ldr imm1,[arg_z,#single_float.value])
3865        __(str imm1,[arg_x,imm0])
3866        __(bx lr)
3867local_label(misc_set_u8):               
3868        __(mov imm0,arg_y,lsr #2)
3869        __(add imm0,imm0,#misc_data_offset)
3870        __(mov imm2,#~(0xff<<fixnumshift))
3871        __(tst arg_z,imm2)
3872        __(bne local_label(set_bad))
3873        __(unbox_fixnum(imm1,arg_z))
3874        __(strb imm1,[arg_x,imm0])
3875        __(bx lr)
3876local_label(misc_set_old_string):
3877        __(mov imm0,arg_y,lsr #2)
3878        __(add imm0,imm0,#misc_data_offset)
3879        __(extract_lowbyte(imm2,arg_z))
3880        __(cmp imm2,#subtag_character)
3881        __(unbox_character(imm1,arg_z))
3882        __(bne local_label(set_bad))
3883        __(strb imm1,[arg_x,imm0])
3884        __(bx lr)
3885local_label(misc_set_s8):
3886        __(mov imm0,arg_y,lsr #2)
3887        __(add imm0,imm0,#misc_data_offset)
3888        __(test_fixnum(arg_z))
3889        __(bne local_label(set_bad))
3890        __(unbox_fixnum(imm1,arg_z))
3891        __(mov imm2,imm1,lsl #32-8)
3892        __(cmp imm1,imm2,asr #32-8)
3893        __(bne local_label(set_bad))
3894        __(strb imm1,[arg_x,imm0])
3895        __(bx lr)
3896local_label(misc_set_u16):         
3897        __(mov imm0,arg_y,lsr #1)
3898        __(add imm0,imm0,#misc_data_offset)
3899        __(test_fixnum(arg_z))
3900        __(bne local_label(set_bad))
3901        __(unbox_fixnum(imm1,arg_z))
3902        __(mov imm2,imm1,lsl #16)
3903        __(cmp imm1,imm2,lsr #16)
3904        __(bne local_label(set_bad))
3905        __(strh imm1,[arg_x,imm0])
3906        __(bx lr)
3907local_label(misc_set_s16):
3908        __(mov imm0,arg_y,lsr #1)
3909        __(add imm0,imm0,#misc_data_offset)
3910        __(test_fixnum(arg_z))
3911        __(bne local_label(set_bad))
3912        __(unbox_fixnum(imm1,arg_z))
3913        __(mov imm2,imm1,lsl #16)
3914        __(cmp imm1,imm2,asr #16)
3915        __(bne local_label(set_bad))
3916        __(strh imm1,[arg_x,imm0])
3917        __(bx lr)
3918local_label(misc_set_bit_vector):
3919        __(bics imm0,arg_z,#fixnumone)
3920        __(bne local_label(set_bad))
3921        __(mov imm2,#31)
3922        __(and imm2,imm1,arg_y,lsr #2)
3923        __(mov imm1,#1)
3924        __(mov imm1,imm1,lsl imm2)
3925        __(mov imm0,arg_y,lsr #fixnumshift+5)
3926        __(mov imm0,imm0,lsl #2)
3927        __(add imm0,imm0,#misc_data_offset)
3928        __(cmp arg_z,#0)
3929        __(ldr imm2,[arg_x,imm0])
3930        __(orrne imm2,imm2,imm1)
3931        __(biceq imm2,imm2,imm1)
3932        __(str imm2,[arg_x,imm0])
3933        __(bx lr)
3934
3935local_label(misc_set_double_float_vector):
3936        __(extract_subtag(imm2,arg_z))
3937        __(cmp imm2,#subtag_double_float)
3938        __(bne local_label(set_bad))
3939        __(ldrd imm0,imm1,[arg_z,#misc_dfloat_offset])
3940        __(mov imm2,arg_y,lsl #1)
3941        __(add imm2,imm2,#misc_dfloat_offset)
3942        __(strd imm0,imm1,[arg_x,imm2])
3943        __(bx lr)
3944local_label(misc_set_invalid): 
3945        __(mov temp0,#XSETBADVEC)       
3946        __(set_nargs(4))
3947        __(vpush1(temp0))
3948        __(b _SPksignalerr)               
3949
3950       
3951/* imm2: (tstack-consed) target catch frame, imm0: count of intervening  */
3952/* frames. If target isn't a multiple-value receiver, discard extra values */
3953/* (less hair, maybe.)  */
3954C(_throw_found):
3955pushdef(`__',`
3956        .word 0
3957        ')       
3958        __(ldr imm1,[imm2,#catch_frame.mvflag])
3959        __(cmpri(imm1,0))
3960        __(cmpri(cr1,nargs,0))
3961        __(mov fn,#0)
3962        __(add imm1,vsp,nargs)
3963        __(add imm1,[imm1,#-node_size])
3964        __(bne local_label(_throw_all_values))
3965        __(set_nargs(1))
3966        __(beq cr1,local_label(_throw_default_1_val))
3967        __(mov vsp,imm1)
3968        __(b local_label(_throw_all_values))
3969local_label(_throw_default_1_val):
3970        __(mov imm4,#nil_value)
3971        __(vpush1(imm4))
3972local_label(_throw_all_values):
3973        __(bl _SPnthrowvalues)
3974        __(ldr imm3,[rcontext,#tcr.catch_top])
3975        __(ldr imm1,[rcontext,#tcr.db_link])
3976        __(ldr imm0,[imm3,#catch_frame.db_link])
3977        __(ldr imm4,[imm3,#catch_frame.mvflag])
3978        __(cmpr(imm0,imm1))
3979        __(cmpri(cr1,imm4,0))
3980        __(add tsp,[imm3,#-((tsp_frame.fixed_overhead+fulltag_misc))])
3981        __(beq local_label(_throw_dont_unbind))
3982        __(bl _SPunbind_to)
3983local_label(_throw_dont_unbind):
3984        __(add imm0,vsp,nargs)
3985        __(cmpri(nargs,0))
3986        __(ldr imm1,[imm3,#catch_frame.csp])
3987        __(ldr imm1,[imm1,#lisp_frame.savevsp])
3988        __(bne cr1,local_label(_throw_multiple))
3989        /* Catcher expects single value in arg_z  */
3990        __(ldr arg_z,[imm0,#-node_size])
3991        __(b local_label(_throw_pushed_values))
3992local_label(_throw_multiple):
3993        __(beq local_label(_throw_pushed_values))
3994        __(mov imm2,nargs)
3995local_label(_throw_mvloop):
3996        __(sub imm2,imm2,fixnum_one)
3997        __(cmpri(imm2,0))
3998        __(ldru(temp0,-node_size(imm0)))
3999        __(push(temp0,imm1))
4000        __(bgt local_label(_throw_mvloop))
4001local_label(_throw_pushed_values):
4002        __(mov vsp,imm1)
4003        __(ldr imm1,[imm3,#catch_frame.xframe])
4004        __(str(imm1,tcr.xframe(rcontext)))
4005        __(ldr sp,[imm3,#catch_frame.csp])
4006        __(ldr fn,[sp,#lisp_frame.savefn])
4007        __(ldr loc_pc,[sp,#lisp_frame.savelr])
4008        __(discard_lisp_frame())
4009        __(mtlr loc_pc)
4010        __(restore_catch_nvrs(imm3))
4011        __(ldr imm3,[imm3,#catch_frame.link])
4012        __(str(imm3,tcr.catch_top(rcontext)))
4013        __(unlink(tsp))
4014        __(bx lr)
4015popdef(`__')
4016
4017C(nthrow1v):   
4018local_label(_nthrow1v_nextframe):
4019        __(subs temp2,temp2,#fixnum_one)
4020        __(ldr temp0,[rcontext,#tcr.catch_top])
4021        __(ldr imm1,[rcontext,#tcr.db_link])
4022        __(set_nargs(1))
4023        __(blt local_label(_nthrow1v_done))
4024        __(ldr arg_y,[temp0,#catch_frame.link])
4025        __(ldr imm0,[temp0,#catch_frame.db_link])
4026        __(cmp imm0,imm1)
4027        __(str arg_y,[rcontext,#tcr.catch_top])
4028        __(ldr arg_y,[temp0,#catch_frame.xframe])
4029        __(str arg_y,[rcontext,#tcr.xframe])
4030        __(beq local_label(_nthrow1v_dont_unbind))
4031        __(do_unbind_to(imm1,temp1,arg_x,arg_y))
4032local_label(_nthrow1v_dont_unbind):
4033        __(ldr temp1,[temp0,#catch_frame.catch_tag])
4034        __(cmp temp1,#unbound_marker)  /* unwind-protect ?  */
4035        __(beq local_label(_nthrow1v_do_unwind))
4036        /* A catch frame.  If the last one, restore context from there.  */
4037        __(cmp temp2,#0)
4038        __(ldreq vsp,[sp,#catch_frame.size+lisp_frame.savevsp])
4039        __(add sp,sp,#catch_frame.size+lisp_frame.size)
4040        __(b local_label(_nthrow1v_nextframe))
4041local_label(_nthrow1v_do_unwind):
4042        /* This is harder, but not as hard (not as much BLTing) as the  */
4043        /* multiple-value case.  */
4044        /* Save our caller's LR and FN in the csp frame created by the unwind-  */
4045        /* protect.  (Clever, eh ?)  */
4046        __(add sp,sp,#catch_frame.size)
4047        /* swp is deprecated on ARMv6+.  It's not useful as a basis
4048           for synchronization, but that's not why we're using it here. */
4049        __(mov imm1,#0)
4050        __(mov temp0,sp)
4051        __(mov imm0,#3<<num_subtag_bits)
4052        __(orr imm0,imm0,#subtag_simple_vector)
4053        __(stmdb sp!,{imm0,imm1,arg_z,temp2})
4054        __(add imm0,temp0,#lisp_frame.savelr)
4055        __(swp lr,lr,[imm0])
4056        __(ldr nfn,[temp0,#lisp_frame.savefn])
4057        __(str fn,[temp0,#lisp_frame.savefn])
4058        __(ldr vsp,[temp0,#lisp_frame.savevsp])
4059        __(mov fn,nfn)
4060        __(str imm1,[rcontext,#tcr.unwinding])
4061        __(blx lr)
4062        __(mov imm1,#1)
4063        __(ldr arg_z,[sp,#8])
4064        __(str imm1,[rcontext,#tcr.unwinding])
4065        __(ldr temp2,[sp,#12])
4066        __(add sp,sp,#4*node_size)
4067        __(restore_lisp_frame(imm0))
4068        __(b local_label(_nthrow1v_nextframe))
4069local_label(_nthrow1v_done):
4070        __(mov imm0,#0)
4071        __(str imm0,[rcontext,#tcr.unwinding])
4072        /* nargs has an undefined value here, so we can clobber it while */
4073        /* polling for a deferred interrupt  */
4074        __(check_pending_interrupt(nargs))
4075        __(bx lr)
4076       
4077       
4078        _endfile
Note: See TracBrowser for help on using the repository browser.