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

Last change on this file since 16341 was 16341, checked in by gb, 5 years ago

pc_luser_xp(): if we interrupt a conditional store, detect its success/failure correctly.

_SPeabi_ff_call_simple: store the vsp in tcr.save_vsp when exiting lisp. This seems to fix ticket:1257 in the trunk.

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