source: branches/working-0710/ccl/lisp-kernel/x86-spentry64.s @ 7523

Last change on this file since 7523 was 7523, checked in by gb, 13 years ago

Try to ensure that rsp/rsp are lisp's whenever tcr->valence claims
to be in TCR_STATE_LISP.

(It's OK if they're also pointing to the lisp stack when in a foreign
context, as long as tcr->save_vsp and tcr->save_rbp are pointing to
the right values.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 161.3 KB
Line 
1/*   Copyright (C) 2005-2006 Clozure Associates and contributors  */
2/*   This file is part of OpenMCL.    */
3
4/*   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public  */
5/*   License , known as the LLGPL and distributed with OpenMCL as the  */
6/*   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,  */
7/*   which is distributed with OpenMCL as the file "LGPL".  Where these  */
8/*   conflict, the preamble takes precedence.    */
9
10/*   OpenMCL 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       
20        .align 2
21define([_spentry],[ifdef([__func_name],[_endfn],[])
22        .p2align 3
23        _exportfn(_SP$1)
24        .line  __line__
25])
26
27             
28define([_endsubp],[
29        _endfn(_SP$1)
30#  __line__
31])
32
33define([jump_builtin],[
34        ref_nrs_value(builtin_functions,%fname)
35        set_nargs($2)
36        vrefr(%fname,%fname,$1)
37        jump_fname()
38])
39
40       
41
42_spentry(bad_funcall)   
43        .globl C(bad_funcall)   
44__(tra(C(bad_funcall)))
45        __(uuo_error_not_callable)
46_endsubp(bad_funcall)
47       
48/* %arg_z has overflowed by one bit.  Make a bignum with 2 (32-bit) digits.  */
49       
50_spentry(fix_overflow)
51C(fix_one_bit_overflow):       
52        __(movq $two_digit_bignum_header,%imm0)
53        __(Misc_Alloc_Fixed([],aligned_bignum_size(2)))
54        __(unbox_fixnum(%arg_z,%imm0))
55        __(movq $0xe000000000000000,%imm1)
56        __(mov %temp0,%arg_z)
57        __(xorq %imm1,%imm0)
58        __(movq %imm0,misc_data_offset(%arg_z))
59        __(ret) 
60_endsubp(fix_overflow)
61
62
63/* Make a lisp integer (fixnum or two-digit bignum) from the signed  */
64/* 64-bit value in %imm0.   */
65
66_spentry(makes64)
67        __(movq %imm0,%imm1)
68        __(shlq $fixnumshift,%imm1)
69        __(movq %imm1,%arg_z)
70        __(sarq $fixnumshift,%imm1)
71        __(cmpq %imm1,%imm0)
72        __(jz,pt 0f)
73        __(movd %imm0,%mm0)
74        __(movq $two_digit_bignum_header,%imm0)
75        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
76        __(movq %mm0,misc_data_offset(%arg_z))
770:      __(repret)
78_endsubp(makes64)       
79
80                                       
81
82/* %imm1:%imm0 constitute a signed integer, almost certainly a bignum.  */
83/* Make a lisp integer out of those 128 bits ..   */
84       
85_startfn(C(makes128))
86       
87        /*  We're likely to have to make a bignum out of the integer in %imm1 and  */
88        /*  %imm0. We'll need to use %imm0 and %imm1 to cons the bignum, and  */
89        /*  will need to do some arithmetic (determining significant bigits)  */
90        /*  on %imm0 and %imm1 in order to know how large that bignum needs to be.  */
91        /*  Cache %imm0 and %imm1 in %mm0 and %mm1.   */
92   
93        __(movd %imm0,%mm0)
94        __(movd %imm1,%mm1)
95       
96        /* If %imm1 is just a sign extension of %imm0, make a 64-bit signed integer.   */
97       
98        __(sarq $63,%imm0) 
99        __(cmpq %imm0,%imm1)
100        __(movd %mm0,%imm0)
101        __(je _SPmakes64)
102       
103        /* Otherwise, if the high 32 bits of %imm1 are a sign-extension of the  */
104        /* low 32 bits of %imm1, make a 3-digit bignum.  If the upper 32 bits  */
105        /* of %imm1 are significant, make a 4 digit bignum   */
106       
107        __(movq %imm1,%imm0)
108        __(shlq $32,%imm0)
109        __(sarq $32,%imm0)
110        __(cmpq %imm0,%imm1)
111        __(jz 3f)
112        __(mov $four_digit_bignum_header,%imm0)
113        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(4)))
114        __(movq %mm0,misc_data_offset(%arg_z))
115        __(movq %mm1,misc_data_offset+8(%arg_z))
116        __(ret)
1173:      __(mov $three_digit_bignum_header,%imm0)
118        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
119        __(movq %mm0,misc_data_offset(%arg_z))
120        __(movd %mm1,misc_data_offset+8(%arg_z))
121        __(ret)
122_endfn
123
124       
125/* %imm1:%imm0 constitute an unsigned integer, almost certainly a bignum.  */
126/* Make a lisp integer out of those 128 bits ..  */
127       
128_startfn(C(makeu128))
129       
130        /* We're likely to have to make a bignum out of the integer in %imm1 and  */
131        /* %imm0. We'll need to use %imm0 and %imm1 to cons the bignum, and  */
132        /* will need to do some arithmetic (determining significant bigits)  */
133        /* on %imm0 and %imm1 in order to know how large that bignum needs to be.  */
134        /* Cache %imm0 and %imm1 in %mm0 and %mm1.   */
135
136        /* If the high word is 0, make an unsigned-byte 64 ...    */
137       
138        __(testq %imm1,%imm1)
139        __(jz _SPmakeu64)
140       
141        __(movd %imm0,%mm0)
142        __(movd %imm1,%mm1)
143
144        __(js 5f)               /* Sign bit set in %imm1. Need 5 digits   */
145        __(bsrq %imm1,%imm0)
146        __(rcmpb(%imm0_b,$31))
147        __(jae 4f)              /* Some high bits in %imm1.  Need 4 digits   */
148        __(testl %imm1_l,%imm1_l)
149        __(movd %mm0,%imm0)
150        __(jz _SPmakeu64)
151       
152        /* Need 3 digits   */
153       
154        __(movq $three_digit_bignum_header,%imm0)
155        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
156        __(movq %mm0,misc_data_offset(%arg_z))
157        __(movd %mm1,misc_data_offset+8(%arg_z))
158        __(ret)
1594:      __(movq $four_digit_bignum_header,%imm0)
160        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(4)))
161        __(jmp 6f)
1625:      __(movq $five_digit_bignum_header,%imm0)
163        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(5)))
1646:      __(movq %mm0,misc_data_offset(%arg_z))
165        __(movq %mm0,misc_data_offset+8(%arg_z))
166        __(ret)
167_endfn
168
169_spentry(misc_ref)
170        __(movb $tagmask,%imm0_b)
171        __(andb %arg_y_b,%imm0_b)
172        __(cmpb $tag_misc,%imm0_b)
173        __(je,pt 0f)
174        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
1750:      __(testb $fixnummask,%arg_z_b)
176        __(je,pt 1f)
177        __(uuo_error_reg_not_fixnum(Rarg_z))
1781:      __(movq misc_header_offset(%arg_y),%imm0)
179        __(xorb %imm0_b,%imm0_b)
180        __(shrq $num_subtag_bits-fixnumshift,%imm0)
181        __(cmpq %imm0,%arg_z)
182        __(jb,pt 2f)
183        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
1842:      __(movb misc_subtag_offset(%arg_y),%imm1_b)
185_endsubp(misc_ref)
186       
187/* %imm1.b = subtag, %arg_y = uvector, %arg_z = index.  */
188/* Bounds/type-checking done in caller  */
189       
190_startfn(C(misc_ref_common))
191        __(movzbl %imm1_b,%imm1_l)
192        __(lea local_label(misc_ref_jmp)(%rip),%imm2)
193        __(jmp *(%imm2,%imm1,8))
194        .p2align 3
195local_label(misc_ref_jmp):     
196        /* 00-0f   */
197        .quad local_label(misc_ref_invalid) /* 00 even_fixnum   */
198        .quad local_label(misc_ref_invalid) /* 01 imm_1   */
199        .quad local_label(misc_ref_invalid) /* 02 imm_2   */
200        .quad local_label(misc_ref_invalid) /* 03 cons   */
201        .quad local_label(misc_ref_invalid) /* 04 tra_0   */
202        .quad local_label(misc_ref_invalid) /* 05 nodeheader_0   */
203        .quad local_label(misc_ref_invalid) /* 06 nodeheader_1   */
204        .quad local_label(misc_ref_invalid) /* 07 immheader_0   */
205        .quad local_label(misc_ref_invalid) /* 08 odd_fixnum   */
206        .quad local_label(misc_ref_invalid) /* 09 immheader_1   */
207        .quad local_label(misc_ref_invalid) /* 0a immheader_2   */
208        .quad local_label(misc_ref_invalid) /* 0b nil   */
209        .quad local_label(misc_ref_invalid) /* 0c tra_1   */
210        .quad local_label(misc_ref_invalid) /* 0d misc   */
211        .quad local_label(misc_ref_invalid) /* 0e symbol   */
212        .quad local_label(misc_ref_invalid) /* 0f function   */
213        /* 10-1f   */
214        .quad local_label(misc_ref_invalid) /* 10 even_fixnum   */
215        .quad local_label(misc_ref_invalid) /* 11 imm_1   */
216        .quad local_label(misc_ref_invalid) /* 12 imm_2   */
217        .quad local_label(misc_ref_invalid) /* 13 cons   */
218        .quad local_label(misc_ref_invalid) /* 14 tra_0   */
219        .quad local_label(misc_ref_node) /* 15 symbol_vector   */
220        .quad local_label(misc_ref_node) /* 16 ratio   */
221        .quad local_label(misc_ref_invalid) /* 17 immheader_0   */
222        .quad local_label(misc_ref_invalid) /* 18 odd_fixnum   */
223        .quad local_label(misc_ref_u32) /* 19 bignum   */
224        .quad local_label(misc_ref_u64) /* 1a macptr   */
225        .quad local_label(misc_ref_invalid) /* 1b nil   */
226        .quad local_label(misc_ref_invalid) /* 1c tra_1   */
227        .quad local_label(misc_ref_invalid) /* 1d misc   */
228        .quad local_label(misc_ref_invalid) /* 1e symbol   */
229        .quad local_label(misc_ref_invalid) /* 1f function   */
230        /* 20-2f   */
231        .quad local_label(misc_ref_invalid) /* 20 even_fixnum   */
232        .quad local_label(misc_ref_invalid) /* 21 imm_1   */
233        .quad local_label(misc_ref_invalid) /* 22 imm_2   */
234        .quad local_label(misc_ref_invalid) /* 23 cons   */
235        .quad local_label(misc_ref_invalid) /* 24 tra_0   */
236        .quad local_label(misc_ref_node) /* 25 catch_frame   */
237        .quad local_label(misc_ref_node) /* 26 complex   */
238        .quad local_label(misc_ref_invalid) /* 27 immheader_0   */
239        .quad local_label(misc_ref_invalid) /* 28 odd_fixnum   */
240        .quad local_label(misc_ref_u32) /* 29 double_float   */
241        .quad local_label(misc_ref_u64)  /* 2a dead_macptr   */
242        .quad local_label(misc_ref_invalid) /* 2b nil   */
243        .quad local_label(misc_ref_invalid) /* 2c tra_1   */
244        .quad local_label(misc_ref_invalid) /* 2d misc   */
245        .quad local_label(misc_ref_invalid) /* 2e symbol   */
246        .quad local_label(misc_ref_invalid) /* 2f function   */
247        /* 30-3f   */
248        .quad local_label(misc_ref_invalid) /* 30 even_fixnum   */
249        .quad local_label(misc_ref_invalid) /* 31 imm_1   */
250        .quad local_label(misc_ref_invalid) /* 32 imm_2   */
251        .quad local_label(misc_ref_invalid) /* 33 cons   */
252        .quad local_label(misc_ref_invalid) /* 34 tra_0   */
253        .quad local_label(misc_ref_node) /* 35 hash_vector   */
254        .quad local_label(misc_ref_node) /* 36 struct   */
255        .quad local_label(misc_ref_invalid) /* 37 immheader_0   */
256        .quad local_label(misc_ref_invalid) /* 38 odd_fixnum   */
257        .quad local_label(misc_ref_u32) /* 39 xcode_vector   */
258        .quad local_label(misc_ref_invalid) /* 3a immheader_2   */
259        .quad local_label(misc_ref_invalid) /* 3b nil   */
260        .quad local_label(misc_ref_invalid) /* 3c tra_1   */
261        .quad local_label(misc_ref_invalid) /* 3d misc   */
262        .quad local_label(misc_ref_invalid) /* 3e symbol   */
263        .quad local_label(misc_ref_invalid) /* 3f function   */
264        /* 40-4f   */
265        .quad local_label(misc_ref_invalid) /* 40 even_fixnum   */
266        .quad local_label(misc_ref_invalid) /* 41 imm_1   */
267        .quad local_label(misc_ref_invalid) /* 42 imm_2   */
268        .quad local_label(misc_ref_invalid) /* 43 cons   */
269        .quad local_label(misc_ref_invalid) /* 44 tra_0   */
270        .quad local_label(misc_ref_node) /* 45 pool   */
271        .quad local_label(misc_ref_node) /* 46 istruct   */
272        .quad local_label(misc_ref_invalid) /* 47 immheader_0   */
273        .quad local_label(misc_ref_invalid) /* 48 odd_fixnum   */
274        .quad local_label(misc_ref_invalid) /* 49 immheader_1   */
275        .quad local_label(misc_ref_invalid) /* 4a immheader_2   */
276        .quad local_label(misc_ref_invalid) /* 4b nil   */
277        .quad local_label(misc_ref_invalid) /* 4c tra_1   */
278        .quad local_label(misc_ref_invalid) /* 4d misc   */
279        .quad local_label(misc_ref_invalid) /* 4e symbol   */
280        .quad local_label(misc_ref_invalid) /* 4f function   */
281        /* 50-5f   */
282        .quad local_label(misc_ref_invalid) /* 50 even_fixnum   */
283        .quad local_label(misc_ref_invalid) /* 51 imm_1   */
284        .quad local_label(misc_ref_invalid) /* 52 imm_2   */
285        .quad local_label(misc_ref_invalid) /* 53 cons   */
286        .quad local_label(misc_ref_invalid) /* 54 tra_0   */
287        .quad local_label(misc_ref_node) /* 55 weak   */
288        .quad local_label(misc_ref_node) /* 56 value_cell   */
289        .quad local_label(misc_ref_invalid) /* 57 immheader_0   */
290        .quad local_label(misc_ref_invalid) /* 58 odd_fixnum   */
291        .quad local_label(misc_ref_invalid) /* 59 immheader_1   */
292        .quad local_label(misc_ref_invalid) /* 5a immheader_2   */
293        .quad local_label(misc_ref_invalid) /* 5b nil   */
294        .quad local_label(misc_ref_invalid) /* 5c tra_1   */
295        .quad local_label(misc_ref_invalid) /* 5d misc   */
296        .quad local_label(misc_ref_invalid) /* 5e symbol   */
297        .quad local_label(misc_ref_invalid) /* 5f function   */
298        /* 60-6f   */
299        .quad local_label(misc_ref_invalid) /* 60 even_fixnum   */
300        .quad local_label(misc_ref_invalid) /* 61 imm_1   */
301        .quad local_label(misc_ref_invalid) /* 62 imm_2   */
302        .quad local_label(misc_ref_invalid) /* 63 cons   */
303        .quad local_label(misc_ref_invalid) /* 64 tra_0   */
304        .quad local_label(misc_ref_node) /* 65 package   */
305        .quad local_label(misc_ref_node) /* 66 xfunction   */
306        .quad local_label(misc_ref_invalid) /* 67 immheader_0   */
307        .quad local_label(misc_ref_invalid) /* 68 odd_fixnum   */
308        .quad local_label(misc_ref_invalid) /* 69 immheader_1   */
309        .quad local_label(misc_ref_invalid) /* 6a immheader_2   */
310        .quad local_label(misc_ref_invalid) /* 6b nil   */
311        .quad local_label(misc_ref_invalid) /* 6c tra_1   */
312        .quad local_label(misc_ref_invalid) /* 6d misc   */
313        .quad local_label(misc_ref_invalid) /* 6e symbol   */
314        .quad local_label(misc_ref_invalid) /* 6f function   */
315        /* 70-7f   */
316        .quad local_label(misc_ref_invalid) /* 70 even_fixnum   */
317        .quad local_label(misc_ref_invalid) /* 71 imm_1   */
318        .quad local_label(misc_ref_invalid) /* 72 imm_2   */
319        .quad local_label(misc_ref_invalid) /* 73 cons   */
320        .quad local_label(misc_ref_invalid) /* 74 tra_0   */
321        .quad local_label(misc_ref_node) /* 75 slot_vector   */
322        .quad local_label(misc_ref_node) /* 76 lock   */
323        .quad local_label(misc_ref_invalid) /* 77 immheader_0   */
324        .quad local_label(misc_ref_invalid) /* 78 odd_fixnum   */
325        .quad local_label(misc_ref_invalid) /* 79 immheader_1   */
326        .quad local_label(misc_ref_invalid) /* 7a immheader_2   */
327        .quad local_label(misc_ref_invalid) /* 7b nil   */
328        .quad local_label(misc_ref_invalid) /* 7c tra_1   */
329        .quad local_label(misc_ref_invalid) /* 7d misc   */
330        .quad local_label(misc_ref_invalid) /* 7e symbol   */
331        .quad local_label(misc_ref_invalid) /* 7f function   */
332        /* 80-8f   */
333        .quad local_label(misc_ref_invalid) /* 80 even_fixnum   */
334        .quad local_label(misc_ref_invalid) /* 81 imm_1   */
335        .quad local_label(misc_ref_invalid) /* 82 imm_2   */
336        .quad local_label(misc_ref_invalid) /* 83 cons   */
337        .quad local_label(misc_ref_invalid) /* 84 tra_0   */
338        .quad local_label(misc_ref_node) /* 85 lisp_thread   */
339        .quad local_label(misc_ref_node) /* 86 instance   */
340        .quad local_label(misc_ref_invalid) /* 87 immheader_0   */
341        .quad local_label(misc_ref_invalid) /* 88 odd_fixnum   */
342        .quad local_label(misc_ref_invalid) /* 89 immheader_1   */
343        .quad local_label(misc_ref_invalid) /* 8a immheader_2   */
344        .quad local_label(misc_ref_invalid) /* 8b nil   */
345        .quad local_label(misc_ref_invalid) /* 8c tra_1   */
346        .quad local_label(misc_ref_invalid) /* 8d misc   */
347        .quad local_label(misc_ref_invalid) /* 8e symbol   */
348        .quad local_label(misc_ref_invalid) /* 8f function   */
349        /* 90-9f   */
350        .quad local_label(misc_ref_invalid) /* 90 even_fixnum   */
351        .quad local_label(misc_ref_invalid) /* 91 imm_1   */
352        .quad local_label(misc_ref_invalid) /* 92 imm_2   */
353        .quad local_label(misc_ref_invalid) /* 93 cons   */
354        .quad local_label(misc_ref_invalid) /* 94 tra_0   */
355        .quad local_label(misc_ref_function) /* 95 function_vector   */
356        .quad local_label(misc_ref_invalid) /* 96 nodeheader_1   */
357        .quad local_label(misc_ref_invalid) /* 97 immheader_0   */
358        .quad local_label(misc_ref_invalid) /* 98 odd_fixnum   */
359        .quad local_label(misc_ref_invalid) /* 99 immheader_1   */
360        .quad local_label(misc_ref_invalid) /* 9a immheader_2   */
361        .quad local_label(misc_ref_invalid) /* 9b nil   */
362        .quad local_label(misc_ref_invalid) /* 9c tra_1   */
363        .quad local_label(misc_ref_invalid) /* 9d misc   */
364        .quad local_label(misc_ref_invalid) /* 9e symbol   */
365        .quad local_label(misc_ref_invalid) /* 9f function   */
366        /* a0-af   */
367        .quad local_label(misc_ref_invalid) /* a0 even_fixnum   */
368        .quad local_label(misc_ref_invalid) /* a1 imm_1   */
369        .quad local_label(misc_ref_invalid) /* a2 imm_2   */
370        .quad local_label(misc_ref_invalid) /* a3 cons   */
371        .quad local_label(misc_ref_invalid) /* a4 tra_0   */
372        .quad local_label(misc_ref_node) /* a5 arrayH   */
373        .quad local_label(misc_ref_node) /* a6 vectorH   */
374        .quad local_label(misc_ref_s16) /* a7 s16   */
375        .quad local_label(misc_ref_invalid) /* a8 odd_fixnum   */
376        .quad local_label(misc_ref_invalid) /* a9 immheader_1   */
377        .quad local_label(misc_ref_invalid) /* aa immheader_2   */
378        .quad local_label(misc_ref_invalid) /* ab nil   */
379        .quad local_label(misc_ref_invalid) /* ac tra_1   */
380        .quad local_label(misc_ref_invalid) /* ad misc   */
381        .quad local_label(misc_ref_invalid) /* ae symbol   */
382        .quad local_label(misc_ref_invalid) /* af function   */
383        /* b0-bf   */
384        .quad local_label(misc_ref_invalid) /* b0 even_fixnum   */
385        .quad local_label(misc_ref_invalid) /* b1 imm_1   */
386        .quad local_label(misc_ref_invalid) /* b2 imm_2   */
387        .quad local_label(misc_ref_invalid) /* b3 cons   */
388        .quad local_label(misc_ref_invalid) /* b4 tra_0   */
389        .quad local_label(misc_ref_invalid) /* b5 nodeheader_0   */
390        .quad local_label(misc_ref_node) /* b6 simple_vector   */
391        .quad local_label(misc_ref_u16) /* b7 immheader_0   */
392        .quad local_label(misc_ref_invalid) /* b8 odd_fixnum   */
393        .quad local_label(misc_ref_invalid) /* b9 immheader_1   */
394        .quad local_label(misc_ref_invalid) /* ba immheader_2   */
395        .quad local_label(misc_ref_invalid) /* bb nil   */
396        .quad local_label(misc_ref_invalid) /* bc tra_1   */
397        .quad local_label(misc_ref_invalid) /* bd misc   */
398        .quad local_label(misc_ref_invalid) /* be symbol   */
399        .quad local_label(misc_ref_invalid) /* bf function   */
400        /* c0-cf   */
401        .quad local_label(misc_ref_invalid) /* c0 even_fixnum   */
402        .quad local_label(misc_ref_invalid) /* c1 imm_1   */
403        .quad local_label(misc_ref_invalid) /* c2 imm_2   */
404        .quad local_label(misc_ref_invalid) /* c3 cons   */
405        .quad local_label(misc_ref_invalid) /* c4 tra_0   */
406        .quad local_label(misc_ref_invalid) /* c5 nodeheader_0   */
407        .quad local_label(misc_ref_invalid) /* c6 nodeheader_1   */
408        .quad local_label(misc_ref_string) /* c7 simple_base_string   */
409        .quad local_label(misc_ref_invalid) /* c8 odd_fixnum   */
410        .quad local_label(misc_ref_new_string) /* c9 new_string_1   */
411        .quad local_label(misc_ref_fixnum_vector) /* ca fixnum_vector   */
412        .quad local_label(misc_ref_invalid) /* cb nil   */
413        .quad local_label(misc_ref_invalid) /* cc tra_1   */
414        .quad local_label(misc_ref_invalid) /* cd misc   */
415        .quad local_label(misc_ref_invalid) /* ce symbol   */
416        .quad local_label(misc_ref_invalid) /* cf function   */
417        /* d0-df   */
418        .quad local_label(misc_ref_invalid) /* d0 even_fixnum   */
419        .quad local_label(misc_ref_invalid) /* d1 imm_1   */
420        .quad local_label(misc_ref_invalid) /* d2 imm_2   */
421        .quad local_label(misc_ref_invalid) /* d3 cons   */
422        .quad local_label(misc_ref_invalid) /* d4 tra_0   */
423        .quad local_label(misc_ref_invalid) /* d5 nodeheader_0   */
424        .quad local_label(misc_ref_invalid) /* d6 nodeheader_1   */
425        .quad local_label(misc_ref_s8)  /* d7 s8   */
426        .quad local_label(misc_ref_invalid) /* d8 odd_fixnum   */
427        .quad local_label(misc_ref_s32) /* d9 s32   */
428        .quad local_label(misc_ref_s64) /* da s64   */
429        .quad local_label(misc_ref_invalid) /* db nil   */
430        .quad local_label(misc_ref_invalid) /* dc tra_1   */
431        .quad local_label(misc_ref_invalid) /* dd misc   */
432        .quad local_label(misc_ref_invalid) /* de symbol   */
433        .quad local_label(misc_ref_invalid) /* df function   */
434        /* e0-ef   */
435        .quad local_label(misc_ref_invalid) /* e0 even_fixnum   */
436        .quad local_label(misc_ref_invalid) /* e1 imm_1   */
437        .quad local_label(misc_ref_invalid) /* e2 imm_2   */
438        .quad local_label(misc_ref_invalid) /* e3 cons   */
439        .quad local_label(misc_ref_invalid) /* e4 tra_0   */
440        .quad local_label(misc_ref_invalid) /* e5 nodeheader_0   */
441        .quad local_label(misc_ref_invalid) /* e6 nodeheader_1   */
442        .quad local_label(misc_ref_u8)  /* e7 u8   */
443        .quad local_label(misc_ref_invalid) /* e8 odd_fixnum   */
444        .quad local_label(misc_ref_u32) /* e9 u32   */
445        .quad local_label(misc_ref_u64) /* ea u64   */
446        .quad local_label(misc_ref_invalid) /* eb nil   */
447        .quad local_label(misc_ref_invalid) /* ec tra_1   */
448        .quad local_label(misc_ref_invalid) /* ed misc   */
449        .quad local_label(misc_ref_invalid) /* ee symbol   */
450        .quad local_label(misc_ref_invalid) /* ef function   */
451        /* f0-ff   */
452        .quad local_label(misc_ref_invalid) /* f0 even_fixnum   */
453        .quad local_label(misc_ref_invalid) /* f1 imm_1   */
454        .quad local_label(misc_ref_invalid) /* f2 imm_2   */
455        .quad local_label(misc_ref_invalid) /* f3 cons   */
456        .quad local_label(misc_ref_invalid) /* f4 tra_0   */
457        .quad local_label(misc_ref_invalid) /* f5 nodeheader_0   */
458        .quad local_label(misc_ref_invalid) /* f6 nodeheader_1   */
459        .quad local_label(misc_ref_bit_vector) /* f7 bitvector   */
460        .quad local_label(misc_ref_invalid) /* f8 odd_fixnum   */
461        .quad local_label(misc_ref_single_float_vector) /* f9 single_float   */
462        .quad local_label(misc_ref_double_float_vector) /* fa double_float   */
463        .quad local_label(misc_ref_invalid) /* fb nil   */
464        .quad local_label(misc_ref_invalid) /* fc tra_1   */
465        .quad local_label(misc_ref_invalid) /* fd misc   */
466        .quad local_label(misc_ref_invalid) /* fe symbol   */
467        .quad local_label(misc_ref_invalid) /* ff function   */
468       
469       
470        /* Node vector.  Functions are funny: the first  N words  */
471        /* are treated as (UNSIGNED-BYTE 64), where N is the low  */
472        /* 32 bits of the first word.  */
473       
474local_label(misc_ref_function):         
475        __(movl misc_data_offset(%arg_y),%imm0_l)
476        __(shl $fixnumshift,%imm0)
477        __(rcmpq(%arg_z,%imm0))
478        __(jb local_label(misc_ref_u64))
479local_label(misc_ref_node):
480        __(movq misc_data_offset(%arg_y,%arg_z),%arg_z)
481        __(ret)
482local_label(misc_ref_u64):
483        __(movq misc_data_offset(%arg_y,%arg_z),%imm0)
484        __(jmp _SPmakeu64)
485local_label(misc_ref_double_float_vector):
486        __(movsd misc_data_offset(%arg_y,%arg_z),%fp1)
487        __(movq $double_float_header,%imm0)
488        __(Misc_Alloc_Fixed(%arg_z,double_float.size))
489        __(movsd %fp1,double_float.value(%arg_z))
490        __(ret)
491local_label(misc_ref_fixnum_vector):   
492        __(movq misc_data_offset(%arg_y,%arg_z),%imm0)
493        __(box_fixnum(%imm0,%arg_z))
494        __(ret)
495local_label(misc_ref_s64):     
496        __(movq misc_data_offset(%arg_y,%arg_z),%imm0)
497        __(jmp _SPmakes64)
498local_label(misc_ref_u32):
499        __(movq %arg_z,%imm0)
500        __(shr $1,%imm0)
501        __(movl misc_data_offset(%arg_y,%imm0),%imm0_l)
502        __(box_fixnum(%imm0,%arg_z))
503        __(ret)
504local_label(misc_ref_s32):
505        __(movq %arg_z,%imm0)
506        __(shr $1,%imm0)
507        __(movslq misc_data_offset(%arg_y,%imm0),%imm0)
508        __(box_fixnum(%imm0,%arg_z))
509        __(ret)
510local_label(misc_ref_single_float_vector):
511        __(movq %arg_z,%imm0)
512        __(shr $1,%imm0)
513        __(movsd misc_data_offset(%arg_y,%imm0),%fp1)
514        __(movd %fp1,%imm0_l)
515        __(shl $32,%imm0)
516        __(lea subtag_single_float(%imm0),%arg_z)
517        __(ret)
518local_label(misc_ref_u8):
519        __(movq %arg_z,%imm0)
520        __(shr $3,%imm0)
521        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0_l)
522        __(box_fixnum(%imm0,%arg_z))
523        __(ret)
524local_label(misc_ref_s8):       
525        __(movq %arg_z,%imm0)
526        __(shr $3,%imm0)
527        __(movsbq misc_data_offset(%arg_y,%imm0),%imm0)
528        __(box_fixnum(%imm0,%arg_z))
529        __(ret)
530local_label(misc_ref_string):
531        __(movq %arg_z,%imm0)
532        __(shr $3,%imm0)
533        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0_l)
534        __(shlq $charcode_shift,%imm0)
535        __(leaq subtag_character(%imm0),%arg_z)
536        __(ret)
537local_label(misc_ref_new_string):
538        __(movq %arg_z,%imm0)
539        __(shr $1,%imm0)
540        __(movl misc_data_offset(%arg_y,%imm0),%imm0_l)
541        __(shlq $charcode_shift,%imm0)
542        __(leaq subtag_character(%imm0),%arg_z)
543        __(ret)       
544local_label(misc_ref_u16):     
545        __(movq %arg_z,%imm0)
546        __(shrq $2,%imm0)
547        __(movzwl misc_data_offset(%arg_y,%imm0),%imm0_l)
548        __(box_fixnum(%imm0,%arg_z))
549        __(ret)
550local_label(misc_ref_s16):     
551        __(movq %arg_z,%imm0)
552        __(shrq $2,%imm0)
553        __(movswq misc_data_offset(%arg_y,%imm0),%imm0)
554        __(box_fixnum(%imm0,%arg_z))
555        __(ret)
556local_label(misc_ref_bit_vector):
557        __(unbox_fixnum(%arg_z,%imm0))
558        __(movl $63,%imm1_l)
559        __(andb %imm0_b,%imm1_b)
560        __(shrq $6,%imm0)
561        __(btq %imm1,misc_data_offset(%arg_y,%imm0,8))
562        __(setc %imm0_b)
563        __(negb %imm0_b)
564        __(andl $fixnum_one,%imm0_l)
565        __(movq %imm0,%arg_z)
566        __(ret)
567local_label(misc_ref_invalid):
568        __(movq $XBADVEC,%arg_x)
569        __(set_nargs(3))
570        __(jmp _SPksignalerr)
571_endfn(C(misc_ref_common))
572
573/* like misc_ref, only the boxed subtag is in arg_x.   */
574                                       
575_spentry(subtag_misc_ref)
576        __(movb $tagmask,%imm0_b)
577        __(andb %arg_y_b,%imm0_b)
578        __(cmpb $tag_misc,%imm0_b)
579        __(je,pt 0f)
580        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
5810:      __(testb $fixnummask,%arg_z_b)
582        __(je,pt 1f)
583        __(uuo_error_reg_not_fixnum(Rarg_z))
5841:      __(movq misc_header_offset(%arg_y),%imm0)
585        __(xorb %imm0_b,%imm0_b)
586        __(shrq $num_subtag_bits-fixnumshift,%imm0)
587        __(cmpq %imm0,%arg_z)
588        __(jb 2f)
589        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
5902:      __(unbox_fixnum(%arg_x,%imm1))
591        __(jmp C(misc_ref_common))
592_endsubp(subtag_misc_ref)
593
594_spentry(subtag_misc_set)
595        __(movb $tagmask,%imm0_b)
596        __(andb %arg_x_b,%imm0_b)
597        __(cmpb $tag_misc,%imm0_b)
598        __(je,pt 0f)
599        __(uuo_error_reg_not_tag(Rarg_x,tag_misc))
6000:      __(testb $fixnummask,%arg_y_b)
601        __(je,pt 1f)
602        __(uuo_error_reg_not_fixnum(Rarg_y))
6031:      __(movq misc_header_offset(%arg_x),%imm0)
604        __(xorb %imm0_b,%imm0_b)
605        __(shrq $num_subtag_bits-fixnumshift,%imm0)
606        __(cmpq %imm0,%arg_y)
607        __(jb 2f)
608        __(uuo_error_vector_bounds(Rarg_y,Rarg_x))
6092:      __(unbox_fixnum(%temp0,%imm1))
610        __(jmp C(misc_set_common))
611_endsubp(subtag_misc_set)
612
613_spentry(misc_set)
614        __(movb $tagmask,%imm0_b)
615        __(andb %arg_x_b,%imm0_b)
616        __(cmpb $tag_misc,%imm0_b)
617        __(je,pt 0f)
618        __(uuo_error_reg_not_tag(Rarg_x,tag_misc))
6190:      __(testb $fixnummask,%arg_y_b)
620        __(je,pt 1f)
621        __(uuo_error_reg_not_fixnum(Rarg_y))
6221:      __(movq misc_header_offset(%arg_x),%imm0)
623        __(xorb %imm0_b,%imm0_b)
624        __(shrq $num_subtag_bits-fixnumshift,%imm0)
625        __(cmpq %imm0,%arg_y)
626        __(jb 2f)
627        __(uuo_error_vector_bounds(Rarg_y,Rarg_x))
6282:      __(movb misc_subtag_offset(%arg_x),%imm1_b)
629        /* __(jmp C(misc_set_common))   */
630_endsubp(misc_set)
631               
632_startfn(C(misc_set_common))
633        __(movzbl %imm1_b,%imm1_l)
634        __(lea local_label(misc_set_jmp)(%rip),%imm2)
635        __(jmp *(%imm2,%imm1,8))
636        .p2align 3
637local_label(misc_set_jmp):             
638        /* 00-0f   */
639        .quad local_label(misc_set_invalid) /* 00 even_fixnum   */
640        .quad local_label(misc_set_invalid) /* 01 imm_1   */
641        .quad local_label(misc_set_invalid) /* 02 imm_2   */
642        .quad local_label(misc_set_invalid) /* 03 cons   */
643        .quad local_label(misc_set_invalid) /* 04 tra_0   */
644        .quad local_label(misc_set_invalid) /* 05 nodeheader_0   */
645        .quad local_label(misc_set_invalid) /* 06 nodeheader_1   */
646        .quad local_label(misc_set_invalid) /* 07 immheader_0   */
647        .quad local_label(misc_set_invalid) /* 08 odd_fixnum   */
648        .quad local_label(misc_set_invalid) /* 09 immheader_1   */
649        .quad local_label(misc_set_invalid) /* 0a immheader_2   */
650        .quad local_label(misc_set_invalid) /* 0b nil   */
651        .quad local_label(misc_set_invalid) /* 0c tra_1   */
652        .quad local_label(misc_set_invalid) /* 0d misc   */
653        .quad local_label(misc_set_invalid) /* 0e symbol   */
654        .quad local_label(misc_set_invalid) /* 0f function   */
655        /* 10-1f   */
656        .quad local_label(misc_set_invalid)     /* 10 even_fixnum   */
657        .quad local_label(misc_set_invalid) /* 11 imm_1   */
658        .quad local_label(misc_set_invalid) /* 12 imm_2   */
659        .quad local_label(misc_set_invalid) /* 13 cons   */
660        .quad local_label(misc_set_invalid)     /* 14 tra_0   */
661        .quad _SPgvset /* 15 symbol_vector   */
662        .quad _SPgvset /* 16 ratio   */
663        .quad local_label(misc_set_invalid) /* 17 immheader_0   */
664        .quad local_label(misc_set_invalid)     /* 18 odd_fixnum   */
665        .quad local_label(misc_set_u32) /* 19 bignum   */
666        .quad local_label(misc_set_u64) /* 1a macptr   */
667        .quad local_label(misc_set_invalid) /* 1b nil   */
668        .quad local_label(misc_set_invalid)     /* 1c tra_1   */
669        .quad local_label(misc_set_invalid)     /* 1d misc   */
670        .quad local_label(misc_set_invalid)     /* 1e symbol   */
671        .quad local_label(misc_set_invalid)     /* 1f function   */
672        /* 20-2f   */
673        .quad local_label(misc_set_invalid)     /* 20 even_fixnum   */
674        .quad local_label(misc_set_invalid) /* 21 imm_1   */
675        .quad local_label(misc_set_invalid) /* 22 imm_2   */
676        .quad local_label(misc_set_invalid) /* 23 cons   */
677        .quad local_label(misc_set_invalid)     /* 24 tra_0   */
678        .quad _SPgvset /* 25 catch_frame   */
679        .quad _SPgvset /* 26 complex   */
680        .quad local_label(misc_set_invalid) /* 27 immheader_0   */
681        .quad local_label(misc_set_invalid)     /* 28 odd_fixnum   */
682        .quad local_label(misc_set_u32) /* 29 double_float   */
683        .quad local_label(misc_set_u64)  /* 2a dead_macptr   */
684        .quad local_label(misc_set_invalid) /* 2b nil   */
685        .quad local_label(misc_set_invalid)     /* 2c tra_1   */
686        .quad local_label(misc_set_invalid)     /* 2d misc   */
687        .quad local_label(misc_set_invalid)     /* 2e symbol   */
688        .quad local_label(misc_set_invalid)     /* 2f function   */
689        /* 30-3f   */
690        .quad local_label(misc_set_invalid)     /* 30 even_fixnum   */
691        .quad local_label(misc_set_invalid) /* 31 imm_1   */
692        .quad local_label(misc_set_invalid) /* 32 imm_2   */
693        .quad local_label(misc_set_invalid) /* 33 cons   */
694        .quad local_label(misc_set_invalid)     /* 34 tra_0   */
695        .quad _SPgvset /* 35 hash_vector   */
696        .quad _SPgvset /* 36 struct   */
697        .quad local_label(misc_set_invalid) /* 37 immheader_0   */
698        .quad local_label(misc_set_invalid)     /* 38 odd_fixnum   */
699        .quad local_label(misc_set_u32) /* 39 xcode_vector   */
700        .quad local_label(misc_set_invalid)  /* 3a immheader_2   */
701        .quad local_label(misc_set_invalid) /* 3b nil   */
702        .quad local_label(misc_set_invalid)     /* 3c tra_1   */
703        .quad local_label(misc_set_invalid)     /* 3d misc   */
704        .quad local_label(misc_set_invalid)     /* 3e symbol   */
705        .quad local_label(misc_set_invalid)     /* 3f function   */
706        /* 40-4f   */
707        .quad local_label(misc_set_invalid)     /* 40 even_fixnum   */
708        .quad local_label(misc_set_invalid) /* 41 imm_1   */
709        .quad local_label(misc_set_invalid) /* 42 imm_2   */
710        .quad local_label(misc_set_invalid) /* 43 cons   */
711        .quad local_label(misc_set_invalid)     /* 44 tra_0   */
712        .quad _SPgvset /* 45 pool   */
713        .quad _SPgvset /* 46 istruct   */
714        .quad local_label(misc_set_invalid) /* 47 immheader_0   */
715        .quad local_label(misc_set_invalid)     /* 48 odd_fixnum   */
716        .quad local_label(misc_set_invalid)     /* 49 immheader_1   */
717        .quad local_label(misc_set_invalid)  /* 4a immheader_2   */
718        .quad local_label(misc_set_invalid) /* 4b nil   */
719        .quad local_label(misc_set_invalid)     /* 4c tra_1   */
720        .quad local_label(misc_set_invalid)     /* 4d misc   */
721        .quad local_label(misc_set_invalid)     /* 4e symbol   */
722        .quad local_label(misc_set_invalid)     /* 4f function   */
723        /* 50-5f   */
724        .quad local_label(misc_set_invalid)     /* 50 even_fixnum   */
725        .quad local_label(misc_set_invalid) /* 51 imm_1   */
726        .quad local_label(misc_set_invalid) /* 52 imm_2   */
727        .quad local_label(misc_set_invalid) /* 53 cons   */
728        .quad local_label(misc_set_invalid)     /* 54 tra_0   */
729        .quad _SPgvset /* 55 weak   */
730        .quad _SPgvset /* 56 value_cell   */
731        .quad local_label(misc_set_invalid) /* 57 immheader_0   */
732        .quad local_label(misc_set_invalid)     /* 58 odd_fixnum   */
733        .quad local_label(misc_set_invalid)     /* 59 immheader_1   */
734        .quad local_label(misc_set_invalid)  /* 5a immheader_2   */
735        .quad local_label(misc_set_invalid) /* 5b nil   */
736        .quad local_label(misc_set_invalid)     /* 5c tra_1   */
737        .quad local_label(misc_set_invalid)     /* 5d misc   */
738        .quad local_label(misc_set_invalid)     /* 5e symbol   */
739        .quad local_label(misc_set_invalid)     /* 5f function   */
740        /* 60-6f   */
741        .quad local_label(misc_set_invalid)     /* 60 even_fixnum   */
742        .quad local_label(misc_set_invalid) /* 61 imm_1   */
743        .quad local_label(misc_set_invalid) /* 62 imm_2   */
744        .quad local_label(misc_set_invalid) /* 63 cons   */
745        .quad local_label(misc_set_invalid)     /* 64 tra_0   */
746        .quad _SPgvset /* 65 package   */
747        .quad _SPgvset /* 66 xfunction   */
748        .quad local_label(misc_set_invalid) /* 67 immheader_0   */
749        .quad local_label(misc_set_invalid)     /* 68 odd_fixnum   */
750        .quad local_label(misc_set_invalid)     /* 69 immheader_1   */
751        .quad local_label(misc_set_invalid)  /* 6a immheader_2   */
752        .quad local_label(misc_set_invalid) /* 6b nil   */
753        .quad local_label(misc_set_invalid)     /* 6c tra_1   */
754        .quad local_label(misc_set_invalid)     /* 6d misc   */
755        .quad local_label(misc_set_invalid)     /* 6e symbol   */
756        .quad local_label(misc_set_invalid)     /* 6f function   */
757        /* 70-7f   */
758        .quad local_label(misc_set_invalid)     /* 70 even_fixnum   */
759        .quad local_label(misc_set_invalid) /* 71 imm_1   */
760        .quad local_label(misc_set_invalid) /* 72 imm_2   */
761        .quad local_label(misc_set_invalid) /* 73 cons   */
762        .quad local_label(misc_set_invalid)     /* 74 tra_0   */
763        .quad _SPgvset /* 75 slot_vector   */
764        .quad _SPgvset /* 76 lock   */
765        .quad local_label(misc_set_invalid) /* 77 immheader_0   */
766        .quad local_label(misc_set_invalid)     /* 78 odd_fixnum   */
767        .quad local_label(misc_set_invalid)     /* 79 immheader_1   */
768        .quad local_label(misc_set_invalid)  /* 7a immheader_2   */
769        .quad local_label(misc_set_invalid) /* 7b nil   */
770        .quad local_label(misc_set_invalid)     /* 7c tra_1   */
771        .quad local_label(misc_set_invalid)     /* 7d misc   */
772        .quad local_label(misc_set_invalid)     /* 7e symbol   */
773        .quad local_label(misc_set_invalid)     /* 7f function   */
774        /* 80-8f   */
775        .quad local_label(misc_set_invalid)     /* 80 even_fixnum   */
776        .quad local_label(misc_set_invalid) /* 81 imm_1   */
777        .quad local_label(misc_set_invalid) /* 82 imm_2   */
778        .quad local_label(misc_set_invalid) /* 83 cons   */
779        .quad local_label(misc_set_invalid)     /* 84 tra_0   */
780        .quad _SPgvset /* 85 lisp_thread   */
781        .quad _SPgvset /* 86 instance   */
782        .quad local_label(misc_set_invalid) /* 87 immheader_0   */
783        .quad local_label(misc_set_invalid)     /* 88 odd_fixnum   */
784        .quad local_label(misc_set_invalid)     /* 89 immheader_1   */
785        .quad local_label(misc_set_invalid)  /* 8a immheader_2   */
786        .quad local_label(misc_set_invalid) /* 8b nil   */
787        .quad local_label(misc_set_invalid)     /* 8c tra_1   */
788        .quad local_label(misc_set_invalid)     /* 8d misc   */
789        .quad local_label(misc_set_invalid)     /* 8e symbol   */
790        .quad local_label(misc_set_invalid)     /* 8f function   */
791        /* 90-9f   */
792        .quad local_label(misc_set_invalid)     /* 90 even_fixnum   */
793        .quad local_label(misc_set_invalid) /* 91 imm_1   */
794        .quad local_label(misc_set_invalid) /* 92 imm_2   */
795        .quad local_label(misc_set_invalid) /* 93 cons   */
796        .quad local_label(misc_set_invalid)     /* 94 tra_0   */
797        .quad local_label(misc_set_function) /* 95 function_vector   */
798        .quad local_label(misc_set_invalid) /* 96 nodeheader_1   */
799        .quad local_label(misc_set_invalid) /* 97 immheader_0   */
800        .quad local_label(misc_set_invalid)     /* 98 odd_fixnum   */
801        .quad local_label(misc_set_invalid)     /* 99 immheader_1   */
802        .quad local_label(misc_set_invalid)  /* 9a immheader_2   */
803        .quad local_label(misc_set_invalid) /* 9b nil   */
804        .quad local_label(misc_set_invalid)     /* 9c tra_1   */
805        .quad local_label(misc_set_invalid)     /* 9d misc   */
806        .quad local_label(misc_set_invalid)     /* 9e symbol   */
807        .quad local_label(misc_set_invalid)     /* 9f function   */
808        /* a0-af   */
809        .quad local_label(misc_set_invalid)     /* a0 even_fixnum   */
810        .quad local_label(misc_set_invalid) /* a1 imm_1   */
811        .quad local_label(misc_set_invalid) /* a2 imm_2   */
812        .quad local_label(misc_set_invalid) /* a3 cons   */
813        .quad local_label(misc_set_invalid)     /* a4 tra_0   */
814        .quad _SPgvset /* a5 arrayH   */
815        .quad _SPgvset /* a6 vectorH   */
816        .quad local_label(misc_set_s16) /* a7 s16   */
817        .quad local_label(misc_set_invalid)     /* a8 odd_fixnum   */
818        .quad local_label(misc_set_invalid)     /* a9 immheader_1   */
819        .quad local_label(misc_set_invalid)  /* aa immheader_2   */
820        .quad local_label(misc_set_invalid) /* ab nil   */
821        .quad local_label(misc_set_invalid)     /* ac tra_1   */
822        .quad local_label(misc_set_invalid)     /* ad misc   */
823        .quad local_label(misc_set_invalid)     /* ae symbol   */
824        .quad local_label(misc_set_invalid)     /* af function   */
825        /* b0-bf   */
826        .quad local_label(misc_set_invalid)     /* b0 even_fixnum   */
827        .quad local_label(misc_set_invalid) /* b1 imm_1   */
828        .quad local_label(misc_set_invalid) /* b2 imm_2   */
829        .quad local_label(misc_set_invalid) /* b3 cons   */
830        .quad local_label(misc_set_invalid)     /* b4 tra_0   */
831        .quad local_label(misc_set_invalid) /* b5 nodeheader_0   */
832        .quad _SPgvset /* b6 simple_vector   */
833        .quad local_label(misc_set_u16) /* b7 immheader_0   */
834        .quad local_label(misc_set_invalid)     /* b8 odd_fixnum   */
835        .quad local_label(misc_set_invalid)     /* b9 immheader_1   */
836        .quad local_label(misc_set_invalid) /* ba immheader_2   */
837        .quad local_label(misc_set_invalid) /* bb nil   */
838        .quad local_label(misc_set_invalid)     /* bc tra_1   */
839        .quad local_label(misc_set_invalid)     /* bd misc   */
840        .quad local_label(misc_set_invalid)     /* be symbol   */
841        .quad local_label(misc_set_invalid)     /* bf function   */
842        /* c0-cf   */
843        .quad local_label(misc_set_invalid)     /* c0 even_fixnum   */
844        .quad local_label(misc_set_invalid) /* c1 imm_1   */
845        .quad local_label(misc_set_invalid) /* c2 imm_2   */
846        .quad local_label(misc_set_invalid) /* c3 cons   */
847        .quad local_label(misc_set_invalid)     /* c4 tra_0   */
848        .quad local_label(misc_set_invalid) /* c5 nodeheader_0   */
849        .quad local_label(misc_set_invalid) /* c6 nodeheader_1   */
850        .quad local_label(misc_set_string) /* c7 simple_base_string   */
851        .quad local_label(misc_set_invalid)     /* c8 odd_fixnum   */
852        .quad local_label(misc_set_new_string)  /* c9 new_strin   */
853        .quad local_label(misc_set_fixnum_vector)  /* ca fixnum_vector   */
854        .quad local_label(misc_set_invalid) /* cb nil   */
855        .quad local_label(misc_set_invalid)     /* cc tra_1   */
856        .quad local_label(misc_set_invalid)     /* cd misc   */
857        .quad local_label(misc_set_invalid)     /* ce symbol   */
858        .quad local_label(misc_set_invalid)     /* cf function   */
859        /* d0-df   */
860        .quad local_label(misc_set_invalid)     /* d0 even_fixnum   */
861        .quad local_label(misc_set_invalid) /* d1 imm_1   */
862        .quad local_label(misc_set_invalid) /* d2 imm_2   */
863        .quad local_label(misc_set_invalid) /* d3 cons   */
864        .quad local_label(misc_set_invalid)     /* d4 tra_0   */
865        .quad local_label(misc_set_invalid) /* d5 nodeheader_0   */
866        .quad local_label(misc_set_invalid) /* d6 nodeheader_1   */
867        .quad local_label(misc_set_s8)  /* d7 s8   */
868        .quad local_label(misc_set_invalid)     /* d8 odd_fixnum   */
869        .quad local_label(misc_set_s32) /* d9 s32   */
870        .quad local_label(misc_set_s64) /* da s64   */
871        .quad local_label(misc_set_invalid) /* db nil   */
872        .quad local_label(misc_set_invalid)     /* dc tra_1   */
873        .quad local_label(misc_set_invalid)     /* dd misc   */
874        .quad local_label(misc_set_invalid)     /* de symbol   */
875        .quad local_label(misc_set_invalid)     /* df function   */
876        /* e0-ef   */
877        .quad local_label(misc_set_invalid)     /* e0 even_fixnum   */
878        .quad local_label(misc_set_invalid) /* e1 imm_1   */
879        .quad local_label(misc_set_invalid) /* e2 imm_2   */
880        .quad local_label(misc_set_invalid) /* e3 cons   */
881        .quad local_label(misc_set_invalid)     /* e4 tra_0   */
882        .quad local_label(misc_set_invalid) /* e5 nodeheader_0   */
883        .quad local_label(misc_set_invalid) /* e6 nodeheader_1   */
884        .quad local_label(misc_set_u8)  /* e7 u8   */
885        .quad local_label(misc_set_invalid)     /* e8 odd_fixnum   */
886        .quad local_label(misc_set_u32) /* e9 u32   */
887        .quad local_label(misc_set_u64) /* ea u64   */
888        .quad local_label(misc_set_invalid) /* eb nil   */
889        .quad local_label(misc_set_invalid)     /* ec tra_1   */
890        .quad local_label(misc_set_invalid)     /* ed misc   */
891        .quad local_label(misc_set_invalid)     /* ee symbol   */
892        .quad local_label(misc_set_invalid)     /* ef function   */
893        /* f0-ff   */
894        .quad local_label(misc_set_invalid)     /* f0 even_fixnum   */
895        .quad local_label(misc_set_invalid) /* f1 imm_1   */
896        .quad local_label(misc_set_invalid) /* f2 imm_2   */
897        .quad local_label(misc_set_invalid) /* f3 cons   */
898        .quad local_label(misc_set_invalid)     /* f4 tra_0   */
899        .quad local_label(misc_set_invalid) /* f5 nodeheader_0   */
900        .quad local_label(misc_set_invalid) /* f6 nodeheader_1   */
901        .quad local_label(misc_set_bit_vector) /* f7 bitvector   */
902        .quad local_label(misc_set_invalid)     /* f8 odd_fixnum   */
903        .quad local_label(misc_set_single_float_vector) /* f9 single_float   */
904        .quad local_label(misc_set_double_float_vector) /* fa double_float   */
905        .quad local_label(misc_set_invalid) /* fb nil   */
906        .quad local_label(misc_set_invalid)     /* fc tra_1   */
907        .quad local_label(misc_set_invalid)     /* fd misc   */
908        .quad local_label(misc_set_invalid)     /* fe symbol   */
909        .quad local_label(misc_set_invalid)     /* ff function   */
910
911local_label(misc_set_function):                 
912        /* Functions are funny: the first  N words  */
913        /* are treated as (UNSIGNED-BYTE 64), where N is the low  */
914        /* 32 bits of the first word.   */
915        __(movl misc_data_offset(%arg_x),%imm0_l)
916        __(shl $fixnumshift,%imm0)
917        __(rcmpq(%arg_y,%imm0))
918        __(jae _SPgvset)
919local_label(misc_set_u64):
920        __(movq $~(target_most_positive_fixnum << fixnumshift),%imm0)
921        __(testq %arg_z,%imm0)
922        __(movq %arg_z,%imm0)
923        __(jne 1f)
924        __(sarq $fixnumshift,%imm0)
925        __(jmp 9f)
9261:      __(andb $tagmask,%imm0_b)
927        __(cmpb $tag_misc,%imm0_b)
928        __(jne local_label(misc_set_bad))
929        __(movb misc_subtag_offset(%arg_z),%imm0_b)
930        __(cmpb $subtag_bignum,%imm0_b)
931        __(jne local_label(misc_set_bad))
932        __(movq misc_header_offset(%arg_z),%imm0)
933        __(cmpq $three_digit_bignum_header,%imm0)
934        __(je 3f)
935        __(cmpq $two_digit_bignum_header,%imm0)
936        __(jne local_label(misc_set_bad))
937        __(movq misc_data_offset(%arg_z),%imm0)
938        __(testq %imm0,%imm0)
939        __(js local_label(misc_set_bad))
940        __(jmp 9f)
9413:      __(movq misc_data_offset(%arg_z),%imm0)
942        __(cmpl $0,misc_data_offset+8(%arg_z))
943        __(jne local_label(misc_set_bad))
9449:      __(movq %imm0,misc_data_offset(%arg_x,%arg_y))
945        __(ret)
946local_label(misc_set_fixnum_vector):
947        __(movq %arg_z,%imm0)
948        __(sarq $fixnumshift,%imm0)
949        __(testb $fixnummask,%arg_z_b)
950        __(jne local_label(misc_set_bad))
951        __(movq %imm0,misc_data_offset(%arg_x,%arg_y))
952        __(ret) 
953local_label(misc_set_s64):
954        __(movq %arg_z,%imm0)
955        __(sarq $fixnumshift,%imm0)
956        __(testb $fixnummask,%arg_z_b)
957        __(je 9f)
9581:      __(movb %arg_z_b,%imm0_b)
959        __(andb $tagmask,%imm0_b)
960        __(cmpb $tag_misc,%imm0_b)
961        __(jne local_label(misc_set_bad))
962        __(movb misc_subtag_offset(%arg_z),%imm0_b)
963        __(cmpb $subtag_bignum,%imm0_b)
964        __(jne local_label(misc_set_bad))
965        __(movq misc_header_offset(%arg_z),%imm0)
966        __(cmpq $two_digit_bignum_header,%imm0)
967        __(movq misc_data_offset(%arg_z),%imm0)
968        __(jne local_label(misc_set_bad))
9699:      __(movq %imm0,misc_data_offset(%arg_x,%arg_y))
970        __(ret)
971local_label(misc_set_bad):
972        __(movq %arg_z,%arg_y)
973        __(movq %arg_x,%arg_z)
974        __(movq $XNOTELT,%arg_x)
975        __(set_nargs(3))
976        __(jmp _SPksignalerr)
977local_label(misc_set_double_float_vector):     
978        __(extract_lisptag(%arg_z,%imm0))
979        __(cmpb $tag_misc,%imm0_b)
980        __(jne local_label(misc_set_bad))
981        __(movb misc_subtag_offset(%arg_z),%imm0_b)
982        __(cmpb $subtag_double_float,%imm0_b)
983        __(jne local_label(misc_set_bad))
984        __(movq double_float.value(%arg_z),%imm0)
985        __(movq %imm0,misc_dfloat_offset(%arg_x,%arg_y))
986        __(ret)
987local_label(misc_set_s32):     
988        __(movq %arg_z,%imm0)
989        __(movq %arg_y,%imm1)
990        __(shlq $64-(32+fixnumshift),%imm0)
991        __(shrq $1,%imm1)
992        __(sarq $64-(32+fixnumshift),%imm0)
993        __(cmpq %imm0,%arg_z)
994        __(jne local_label(misc_set_bad))
995        __(testb $fixnummask,%arg_z_b)
996        __(jne local_label(misc_set_bad))
997        __(shr $fixnumshift,%imm0)
998        __(movl %imm0_l,misc_data_offset(%arg_x,%imm1))
999        __(ret)
1000local_label(misc_set_single_float_vector):
1001        __(cmpb $tag_single_float,%arg_z_b)
1002        __(movq %arg_z,%imm0)
1003        __(movq %arg_y,%imm1)
1004        __(jne local_label(misc_set_bad))
1005        __(shrq $1,%imm1)
1006        __(shr $32,%imm0)
1007        __(movl %imm0_l,misc_data_offset(%arg_x,%imm1))
1008        __(ret)
1009local_label(misc_set_u32):
1010        __(movq %arg_y,%imm1)   
1011        __(movq $~(0xffffffff<<fixnumshift),%imm0)
1012        __(shrq $1,%imm1)
1013        __(testq %imm0,%arg_z)
1014        __(jne local_label(misc_set_bad))
1015        __(unbox_fixnum(%arg_z,%imm0))
1016        __(movl %imm0_l,misc_data_offset(%arg_x,%imm1))
1017        __(ret)
1018local_label(misc_set_bit_vector):       
1019        __(testq $~fixnumone,%arg_z)
1020        __(jne local_label(misc_set_bad))
1021        __(unbox_fixnum(%arg_y,%imm1))
1022        __(movzbl %imm1_b,%imm0_l)
1023        __(andb $63,%imm0_b)
1024        __(shrq $6,%imm1)
1025        __(testb %arg_z_b,%arg_z_b)
1026        __(je local_label(misc_set_clr_bit))
1027local_label(misc_set_set_bit): 
1028        __(btsq %imm0,misc_data_offset(%arg_x,%imm1,8))
1029        __(ret)
1030local_label(misc_set_clr_bit): 
1031        __(btrq %imm0,misc_data_offset(%arg_x,%imm1,8))
1032        __(ret)
1033local_label(misc_set_u8):       
1034        __(testq $~(0xff<<fixnumshift),%arg_z)
1035        __(jne local_label(misc_set_bad))
1036        __(movq %arg_y,%imm1)
1037        __(unbox_fixnum(%arg_z,%imm0))
1038        __(shrq $3,%imm1)
1039        __(movb %imm0_b,misc_data_offset(%arg_x,%imm1))
1040        __(ret)
1041local_label(misc_set_s8):
1042        __(movq %arg_z,%imm0)
1043        __(shlq $64-(8+fixnumshift),%imm0)     
1044        __(sarq $64-(8+fixnumshift),%imm0)
1045        __(cmpq %arg_z,%imm0)
1046        __(jne local_label(misc_set_bad))
1047        __(testb $fixnummask,%arg_z_b)
1048        __(jne local_label(misc_set_bad))
1049        __(movq %arg_y,%imm1)
1050        __(shrq $fixnumshift,%imm0)
1051        __(shrq $3,%imm1)
1052        __(movb %imm0_b,misc_data_offset(%arg_x,%imm1))
1053        __(ret)
1054local_label(misc_set_string):
1055        __(cmpb $subtag_character,%arg_z_b)
1056        __(movq %arg_z,%imm0)
1057        __(jne local_label(misc_set_bad))
1058        __(movq %arg_y,%imm1)
1059        __(shrq $charcode_shift,%imm0)
1060        __(shrq $3,%imm1)
1061        __(movb %imm0_b,misc_data_offset(%arg_x,%imm1))
1062        __(ret)
1063local_label(misc_set_new_string):
1064        __(cmpb $subtag_character,%arg_z_b)
1065        __(movq %arg_z,%imm0)
1066        __(jne local_label(misc_set_bad))
1067        __(movq %arg_y,%imm1)
1068        __(shrq $charcode_shift,%imm0)
1069        __(shrq $1,%imm1)
1070        __(movl %imm0_l,misc_data_offset(%arg_x,%imm1))
1071        __(ret)       
1072local_label(misc_set_s16):     
1073        __(movq %arg_z,%imm0)
1074        __(movq %arg_y,%imm1)
1075        __(shlq $64-(16+fixnumshift),%imm0)     
1076        __(shrq $2,%imm1)
1077        __(sarq $64-(16+fixnumshift),%imm0)
1078        __(cmpq %arg_z,%imm0)
1079        __(jne local_label(misc_set_bad))
1080        __(testb $fixnummask,%arg_z_b)
1081        __(jne local_label(misc_set_bad))
1082        __(shrq $fixnumshift,%imm0)
1083        __(movw %imm0_w,misc_data_offset(%arg_x,%imm1))
1084        __(ret)
1085local_label(misc_set_u16):
1086        __(movq %arg_y,%imm1)
1087        __(testq $~(0xffff<<fixnumshift),%arg_z)
1088        __(jne local_label(misc_set_bad))
1089        __(shrq $2,%imm1)
1090        __(unbox_fixnum(%arg_z,%imm0))
1091        __(movw %imm0_w,misc_data_offset(%arg_x,%imm1))
1092        __(ret)
1093local_label(misc_set_invalid):
1094        __(push $XSETBADVEC)
1095        __(set_nargs(4))
1096        __(jmp _SPksignalerr)
1097_endfn(C(misc_set_common))
1098       
1099/* ret1valn returns "1 multiple value" when a called function does not   */
1100/* return multiple values.  Its presence on the stack (as a return address)   */
1101/* identifies the stack frame to code which returns multiple values.   */
1102
1103_spentry(Fret1valn)
1104        .globl C(ret1valn)
1105__(tra(C(ret1valn)))
1106        __(movq (%rsp),%ra0)
1107        __(movq %arg_z,(%rsp))
1108        __(set_nargs(1))
1109        __(jmpq *%ra0)
1110_endsubp(Fret1valn)
1111       
1112
1113_spentry(nvalret)
1114        .globl C(nvalret)                       
1115C(nvalret):     
1116        __(ref_global(ret1val_addr,%temp1))
1117        __(cmpq lisp_frame.savera0(%rbp),%temp1)
1118        __(je 1f)
1119        __(testw %nargs,%nargs)
1120        __(movzwl %nargs,%nargs_l)
1121        __(movl $nil_value,%arg_z_l)
1122        __(cmovneq -node_size(%rsp,%nargs_q),%arg_z)
1123        __(leaveq)
1124        __(ret)
1125
1126       
1127/* actually need to return values ; always need to copy   */
11281:      __(leaq 2*node_size(%rbp),%imm1)
1129        __(movzwl %nargs,%nargs_l)
1130        __(movq (%imm1),%ra0)
1131        __(addq $node_size,%imm1)
1132        __(movq 0(%rbp),%rbp)
1133        __(leaq (%rsp,%nargs_q),%temp0)
1134        __(xorl %imm0_l,%imm0_l)
1135        __(jmp 3f)
11362:      __(movq -node_size(%temp0),%temp1)
1137        __(subq $node_size,%temp0)
1138        __(addq $node_size,%imm0)
1139        __(movq %temp1,-node_size(%imm1))
1140        __(subq $node_size,%imm1)
11413:      __(cmpw %imm0_w,%nargs)
1142        __(jne 2b)
1143        __(movq %imm1,%rsp)
1144        __(jmp *%ra0)   
1145_endsubp(nvalret)
1146       
1147_spentry(jmpsym)
1148        __(jump_fname())
1149_endsubp(jmpsym)
1150
1151_spentry(jmpnfn)
1152        __(movq %temp0,%fn)
1153        __(jmp *%fn)
1154_endsubp(jmpnfn)
1155
1156_spentry(funcall)
1157        __(do_funcall())
1158_endsubp(funcall)
1159
1160_spentry(mkcatch1v)
1161        __(nMake_Catch(0))
1162        __(ret)
1163_endsubp(mkcatch1v)
1164
1165_spentry(mkunwind)
1166        __(movq $undefined,%arg_z)
1167        __(Make_Catch(fixnumone))
1168        __(jmp *%ra0)
1169_endsubp(mkunwind)
1170       
1171/* this takes a return address in %ra0; it's "new" in that it does the
1172   double binding of *interrupt-level* out-of-line */
1173_spentry(nmkunwind)
1174        __(movq %rcontext:tcr.tlb_pointer,%arg_x)
1175        __(movq INTERRUPT_LEVEL_BINDING_INDEX(%arg_x),%arg_y)
1176        __(push %arg_y)
1177        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
1178        __(push %rcontext:tcr.db_link)
1179        __(movq %rsp,%rcontext:tcr.db_link)
1180        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
1181        __(movq $undefined,%arg_z)
1182        __(Make_Catch(fixnumone))
1183        __(movq %arg_y,%arg_z)
1184        __(jmp _SPbind_interrupt_level)
1185_endsubp(nmkunwind)
1186
1187_spentry(mkcatchmv)
1188        __(nMake_Catch(fixnumone))
1189        __(ret)
1190_endsubp(mkcatchmv)
1191       
1192_spentry(throw)
1193        __(movq %rcontext:tcr.catch_top,%imm1)
1194        __(xorl %imm0_l,%imm0_l)
1195        __(movzwl %nargs,%nargs_l)
1196        __(movq (%rsp,%nargs_q),%temp0) /* temp0 = tag   */
1197        __(jmp local_label(_throw_test))
1198local_label(_throw_loop):
1199        __(cmpq %temp0,catch_frame.catch_tag(%imm1))
1200        __(je local_label(_throw_found))
1201        __(movq catch_frame.link(%imm1),%imm1)
1202        __(addq $fixnum_one,%imm0)
1203local_label(_throw_test):
1204        __(testq %imm1,%imm1)
1205        __(jne local_label(_throw_loop))
1206        __(push %ra0)
1207        __(uuo_error_reg_not_tag(Rtemp0,subtag_catch_frame))
1208        __(pop %ra0)
1209        __(jmp _SPthrow)
1210local_label(_throw_found):     
1211        __(testb $fulltagmask,catch_frame.mvflag(%imm1))
1212        __(jne local_label(_throw_multiple))
1213        __(testw %nargs,%nargs)
1214        __(movl $nil_value,%arg_z_l)
1215        __(je local_label(_throw_one_value))
1216        __(movq -node_size(%rsp,%nargs_q),%arg_z)
1217        __(add %nargs_q,%rsp)
1218local_label(_throw_one_value):
1219        __(lea local_label(_threw_one_value)(%rip),%ra0)
1220        __(jmp _SPnthrow1value)
1221__(tra(local_label(_threw_one_value)))
1222        __(movq %rcontext:tcr.catch_top,%temp0)
1223        __(movq catch_frame.db_link(%temp0),%imm0)
1224        __(movq %rcontext:tcr.db_link,%imm1)
1225        __(cmpq %imm0,%imm1)
1226        __(jz local_label(_threw_one_value_dont_unbind))
1227        __(lea local_label(_threw_one_value_dont_unbind)(%rip),%ra0)
1228        __(push %ra0)
1229        __(jmp _SPunbind_to)
1230__(tra(local_label(_threw_one_value_dont_unbind)))
1231        __(movq catch_frame.rbp(%temp0),%rbp)
1232        __(movq catch_frame.foreign_sp(%temp0),%imm0)
1233        __(movq catch_frame.xframe(%temp0),%imm1)
1234        __(movq %imm0,%rcontext:tcr.foreign_sp)
1235        __(movq %imm1,%rcontext:tcr.xframe)
1236        __(movq catch_frame.rsp(%temp0),%rsp)
1237        __(movq catch_frame.link(%temp0),%imm1)
1238        __(movq catch_frame._save0(%temp0),%save0)
1239        __(movq catch_frame._save1(%temp0),%save1)
1240        __(movq catch_frame._save2(%temp0),%save2)
1241        __(movq catch_frame._save3(%temp0),%save3)
1242        __(movq %imm1,%rcontext:tcr.catch_top)
1243        __(movq catch_frame.pc(%temp0),%ra0)
1244        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1245        __(movq (%imm1),%imm1)
1246        __(movq %imm1,%rcontext:tcr.save_tsp)
1247        __(movq %imm1,%rcontext:tcr.next_tsp)
1248        __(jmp *%ra0)
1249local_label(_throw_multiple):
1250        __(lea local_label(_threw_multiple)(%rip),%ra0)
1251        __(jmp _SPnthrowvalues)
1252__(tra(local_label(_threw_multiple)))
1253        __(movq %rcontext:tcr.catch_top,%temp0)
1254        __(movq catch_frame.db_link(%temp0),%imm0)
1255        __(movq %rcontext:tcr.db_link,%imm1)
1256        __(cmpq %imm0,%imm1)
1257        __(je local_label(_threw_multiple_dont_unbind))
1258        __(leaq local_label(_threw_multiple_dont_unbind)(%rip),%ra0)
1259        __(push %ra0)
1260        __(jmp _SPunbind_to)
1261__(tra(local_label(_threw_multiple_dont_unbind)))
1262        /* Copy multiple values from the current %rsp to the target %rsp   */
1263        __(lea (%rsp,%nargs_q),%imm0)
1264        __(movq catch_frame.rsp(%temp0),%imm1)
1265        __(jmp local_label(_threw_multiple_push_test))
1266local_label(_threw_multiple_push_loop):
1267        __(subq $node_size,%imm0)
1268        __(subq $node_size,%imm1)
1269        __(movq (%imm0),%arg_z)
1270        __(movq %arg_z,(%imm1))
1271local_label(_threw_multiple_push_test):         
1272        __(cmpq %imm0,%rsp)
1273        __(jne local_label(_threw_multiple_push_loop))
1274        /* target %rsp is now in %imm1   */
1275        __(movq catch_frame.rbp(%temp0),%rbp)
1276        __(movq catch_frame.foreign_sp(%temp0),%imm0)
1277        __(movq %imm0,%rcontext:tcr.foreign_sp)       
1278        __(movq catch_frame.xframe(%temp0),%imm0)
1279        __(movq %imm0,%rcontext:tcr.xframe)
1280        __(movq %imm1,%rsp)
1281        __(movq catch_frame.link(%temp0),%imm1)         
1282        __(movq catch_frame._save0(%temp0),%save0)
1283        __(movq catch_frame._save1(%temp0),%save1)
1284        __(movq catch_frame._save2(%temp0),%save2)
1285        __(movq catch_frame._save3(%temp0),%save3)
1286        __(movq %imm1,%rcontext:tcr.catch_top)
1287        __(movq catch_frame.pc(%temp0),%ra0)
1288        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1289        __(movq (%imm1),%imm1)
1290        __(movq %imm1,%rcontext:tcr.save_tsp)
1291        __(movq %imm1,%rcontext:tcr.next_tsp)
1292        __(jmp *%ra0)
1293_endsubp(throw)
1294
1295/* This takes N multiple values atop the vstack.   */
1296_spentry(nthrowvalues)
1297        __(movb $1,%rcontext:tcr.unwinding)
1298        __(movzwl %nargs,%nargs_l)
1299local_label(_nthrowv_nextframe):
1300        __(subq $fixnumone,%imm0)
1301        __(js local_label(_nthrowv_done))
1302        __(movd %imm0,%mm1)
1303        __(movq %rcontext:tcr.catch_top,%temp0)
1304        __(movq catch_frame.link(%temp0),%imm1)
1305        __(movq catch_frame.db_link(%temp0),%imm0)
1306        __(movq %imm1,%rcontext:tcr.catch_top)
1307        __(cmpq %imm0,%rcontext:tcr.db_link)
1308        __(jz local_label(_nthrowv_dont_unbind))
1309        __(push %ra0)
1310        __(leaq local_label(_nthrowv_back_from_unbind)(%rip),%ra0)
1311        __(push %ra0)
1312        __(jmp _SPunbind_to)
1313__(tra(local_label(_nthrowv_back_from_unbind)))
1314
1315        __(pop %ra0)
1316local_label(_nthrowv_dont_unbind):
1317        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1318        __(je local_label(_nthrowv_do_unwind))
1319/* A catch frame.  If the last one, restore context from there.   */
1320        __(movd %mm1,%imm0)
1321        __(testq %imm0,%imm0)   /* last catch frame ?   */
1322        __(jne local_label(_nthrowv_skip))
1323        __(movq catch_frame.xframe(%temp0),%save0)
1324        __(movq %save0,%rcontext:tcr.xframe)
1325        __(leaq (%rsp,%nargs_q),%save1)
1326        __(movq catch_frame.rsp(%temp0),%save2)
1327        __(movq %nargs_q,%save0)
1328        __(jmp local_label(_nthrowv_push_test))
1329local_label(_nthrowv_push_loop):
1330        __(subq $node_size,%save1)
1331        __(subq $node_size,%save2)
1332        __(movq (%save1),%temp1)
1333        __(movq %temp1,(%save2))
1334local_label(_nthrowv_push_test):
1335        __(subq $node_size,%save0)
1336        __(jns local_label(_nthrowv_push_loop))
1337        __(movq catch_frame.xframe(%temp0),%save0)
1338        __(movq %save0,%rcontext:tcr.xframe)
1339        __(movq %save2,%rsp)
1340        __(movq catch_frame.rbp(%temp0),%rbp)
1341        __(movq catch_frame._save3(%temp0),%save3)
1342        __(movq catch_frame._save2(%temp0),%save2)
1343        __(movq catch_frame._save1(%temp0),%save1)
1344        __(movq catch_frame._save0(%temp0),%save0)
1345        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1346        __(movq %stack_temp,%rcontext:tcr.foreign_sp)       
1347local_label(_nthrowv_skip):     
1348        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1349        __(movq %imm1,%rcontext:tcr.save_tsp)       
1350        __(movq %imm1,%rcontext:tcr.next_tsp)
1351        __(movd %mm1,%imm0)
1352        __(jmp local_label(_nthrowv_nextframe))
1353local_label(_nthrowv_do_unwind):       
1354/* This is harder.  Call the cleanup code with the multiple values and   */
1355/* nargs, the throw count, and the caller's return address in a temp  */
1356/* stack frame.   */
1357        __(leaq (%rsp,%nargs_q),%save1)
1358        __(push catch_frame._save0(%temp0))
1359        __(push catch_frame._save1(%temp0))
1360        __(push catch_frame._save2(%temp0))
1361        __(push catch_frame._save3(%temp0))
1362        __(push catch_frame.pc(%temp0))
1363        __(movq catch_frame.rbp(%temp0),%rbp)
1364        __(movq catch_frame.xframe(%temp0),%stack_temp)
1365        __(movq catch_frame.rsp(%temp0),%arg_x)
1366        __(movq %stack_temp,%rcontext:tcr.xframe)
1367        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1368        __(movq %stack_temp,%rcontext:tcr.foreign_sp)       
1369        /* Discard the catch frame, so we can build a temp frame   */
1370        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1371        __(movq %imm1,%rcontext:tcr.save_tsp)
1372        __(movq %imm1,%rcontext:tcr.next_tsp)
1373        /* tsp overhead, nargs, throw count, ra0   */
1374        __(dnode_align(%nargs_q,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1375        __(TSP_Alloc_Var(%imm0,%imm1))
1376
1377        __(movq %nargs_q,(%imm1))
1378        __(movq %ra0,node_size(%imm1))
1379        __(movq %mm1,node_size*2(%imm1))
1380        __(leaq node_size*3(%imm1),%imm1)
1381        __(jmp local_label(_nthrowv_tpushtest))
1382local_label(_nthrowv_tpushloop):
1383        __(movq -node_size(%save1),%temp0)
1384        __(subq $node_size,%save1)
1385        __(movq %temp0,(%imm1))
1386        __(addq $node_size,%imm1)
1387local_label(_nthrowv_tpushtest):
1388        __(subw $node_size,%nargs)
1389        __(jns local_label(_nthrowv_tpushloop))
1390        __(pop %xfn)
1391        __(pop %save3)
1392        __(pop %save2)
1393        __(pop %save1)
1394        __(pop %save0)
1395        __(movq %arg_x,%rsp)
1396/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1397        __(leaq local_label(_nthrowv_called_cleanup)(%rip),%ra0)
1398        __(push %ra0)
1399        __(movb $0,%rcontext:tcr.unwinding)
1400        __(jmp *%xfn)
1401__(tra(local_label(_nthrowv_called_cleanup)))
1402
1403        __(movb $1,%rcontext:tcr.unwinding)
1404        __(movq %rcontext:tcr.save_tsp,%imm1)
1405        __(movq tsp_frame.data_offset+(0*node_size)(%imm1),%nargs_q)
1406        __(movq tsp_frame.data_offset+(1*node_size)(%imm1),%ra0)
1407        __(movq tsp_frame.data_offset+(2*node_size)(%imm1),%mm1)
1408        __(movq %nargs_q,%imm0)
1409        __(addq $tsp_frame.fixed_overhead+(node_size*3),%imm1)
1410        __(jmp local_label(_nthrowv_tpoptest))
1411local_label(_nthrowv_tpoploop):
1412        __(push (%imm1))
1413        __(addq $node_size,%imm1)
1414local_label(_nthrowv_tpoptest):
1415        __(subq $node_size,%imm0)
1416        __(jns local_label(_nthrowv_tpoploop))
1417        __(movq %rcontext:tcr.save_tsp,%imm1)
1418        __(movq (%imm1),%imm1)
1419        __(movq %imm1,%rcontext:tcr.save_tsp)
1420        __(movq %imm1,%rcontext:tcr.next_tsp)
1421        __(movd %mm1,%imm0)
1422        __(jmp local_label(_nthrowv_nextframe))
1423local_label(_nthrowv_done):
1424        __(movb $0,%rcontext:tcr.unwinding)
1425        __(check_pending_interrupt(%imm0))
1426local_label(_nthrowv_return):   
1427        __(jmp *%ra0)   
1428_endsubp(nthrowvalues)
1429
1430/* This is a (slight) optimization.  When running an unwind-protect,  */
1431/* save the single value and the throw count in the tstack frame.  */
1432/* Note that this takes a single value in arg_z.  */
1433       
1434_spentry(nthrow1value)
1435        __(movb $1,%rcontext:tcr.unwinding)
1436        __(movzwl %nargs,%nargs_l)
1437local_label(_nthrow1v_nextframe):
1438        __(subq $fixnumone,%imm0)
1439        __(js local_label(_nthrow1v_done))
1440        __(movd %imm0,%mm1)
1441        __(movq %rcontext:tcr.catch_top,%temp0)
1442        __(movq catch_frame.link(%temp0),%imm1)
1443        __(movq catch_frame.db_link(%temp0),%imm0)
1444        __(movq %imm1,%rcontext:tcr.catch_top)
1445        __(cmpq %imm0,%rcontext:tcr.db_link)
1446        __(jz local_label(_nthrow1v_dont_unbind))
1447        __(push %ra0)
1448        __(leaq local_label(_nthrow1v_back_from_unbind)(%rip),%ra0)
1449        __(push %ra0)
1450        __(jmp _SPunbind_to)
1451__(tra(local_label(_nthrow1v_back_from_unbind)))
1452
1453        __(pop %ra0)
1454local_label(_nthrow1v_dont_unbind):
1455        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1456        __(je local_label(_nthrow1v_do_unwind))
1457/* A catch frame.  If the last one, restore context from there.   */
1458        __(movd %mm1,%imm0)
1459        __(testq %imm0,%imm0)   /* last catch frame ?   */
1460        __(jne local_label(_nthrow1v_skip))
1461        __(movq catch_frame.xframe(%temp0),%save0)
1462        __(movq %save0,%rcontext:tcr.xframe)
1463        __(leaq (%rsp,%nargs_q),%save1)
1464        __(movq catch_frame.xframe(%temp0),%save0)
1465        __(movq %save0,%rcontext:tcr.xframe)
1466        __(movq catch_frame.rsp(%temp0),%rsp)
1467        __(movq catch_frame.rbp(%temp0),%rbp)
1468        __(movq catch_frame._save3(%temp0),%save3)
1469        __(movq catch_frame._save2(%temp0),%save2)
1470        __(movq catch_frame._save1(%temp0),%save1)
1471        __(movq catch_frame._save0(%temp0),%save0)
1472        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1473        __(movq %stack_temp,%rcontext:tcr.foreign_sp)       
1474local_label(_nthrow1v_skip):   
1475        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1476        __(movq %imm1,%rcontext:tcr.save_tsp)
1477        __(movq %imm1,%rcontext:tcr.next_tsp)       
1478        __(movd %mm1,%imm0)
1479        __(jmp local_label(_nthrow1v_nextframe))
1480local_label(_nthrow1v_do_unwind):
1481       
1482/* This is harder, but not as hard (not as much BLTing) as the  */
1483/* multiple-value case.  */
1484       
1485        __(movq catch_frame.xframe(%temp0),%save0)
1486        __(movq %save0,%rcontext:tcr.xframe)
1487        __(movq catch_frame._save0(%temp0),%save0)
1488        __(movq catch_frame._save1(%temp0),%save1)
1489        __(movq catch_frame._save2(%temp0),%save2)
1490        __(movq catch_frame._save3(%temp0),%save3)
1491        __(movq catch_frame.pc(%temp0),%xfn)
1492        __(movq catch_frame.rbp(%temp0),%rbp)
1493        __(movq catch_frame.rsp(%temp0),%rsp)
1494        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1495        __(movq %stack_temp,%rcontext:tcr.foreign_sp)       
1496        /* Discard the catch frame, so we can build a temp frame   */
1497        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1498        __(movq %imm1,%rcontext:tcr.save_tsp)
1499        __(movq %imm1,%rcontext:tcr.next_tsp)       
1500        __(TSP_Alloc_Fixed((3*node_size),%imm1))
1501        __(addq $tsp_frame.fixed_overhead,%imm1)
1502        __(movq %ra0,(%imm1))
1503        __(movq %mm1,node_size*1(%imm1))
1504        __(movq %arg_z,node_size*2(%imm1))
1505/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1506        __(leaq local_label(_nthrow1v_called_cleanup)(%rip),%ra0)
1507        __(movb $0,%rcontext:tcr.unwinding)
1508        __(push %ra0)
1509        __(jmp *%xfn)
1510__(tra(local_label(_nthrow1v_called_cleanup)))
1511
1512        __(movb $1,%rcontext:tcr.unwinding)
1513        __(movq %rcontext:tcr.save_tsp,%imm1)
1514        __(movq tsp_frame.data_offset+(0*node_size)(%imm1),%ra0)
1515        __(movq tsp_frame.data_offset+(1*node_size)(%imm1),%mm1)
1516        __(movq tsp_frame.data_offset+(2*node_size)(%imm1),%arg_z)
1517
1518        __(movq (%imm1),%imm1)
1519        __(movq %imm1,%rcontext:tcr.save_tsp)
1520        __(movq %imm1,%rcontext:tcr.next_tsp)       
1521        __(movd %mm1,%imm0)
1522        __(jmp local_label(_nthrow1v_nextframe))
1523local_label(_nthrow1v_done):
1524        __(movb $0,%rcontext:tcr.unwinding)
1525        __(check_pending_interrupt(%imm0))
1526local_label(_nthrow1v_return): 
1527        __(jmp *%ra0)   
1528_endsubp(nthrow1value)
1529
1530/* This never affects the symbol's vcell   */
1531/* Non-null symbol in arg_y, new value in arg_z           */
1532       
1533_spentry(bind)
1534        __(movq symbol.binding_index(%arg_y),%temp0)
1535        __(cmpq %rcontext:tcr.tlb_limit,%temp0)
1536        __(jb,pt 0f)
1537        __(push %temp0)
1538        __(tlb_too_small())
15390:      __(testq %temp0,%temp0)
1540        __(jz 9f)
1541        __(movq %rcontext:tcr.tlb_pointer,%temp1)
1542        __(push (%temp1,%temp0))
1543        __(push %temp0)
1544        __(push %rcontext:tcr.db_link)
1545        __(movq %rsp,%rcontext:tcr.db_link)
1546        __(movq %arg_z,(%temp1,%temp0))
1547        __(jmp *%ra0)
15489:     
1549        __(movq %arg_y,%arg_z)
1550        __(movq $XSYMNOBIND,%arg_y)
1551        __(set_nargs(2))
1552        __(push %ra0)
1553        __(jmp _SPksignalerr)   
1554_endsubp(bind)
1555
1556/* arg_z = symbol: bind it to its current value  */
1557       
1558_spentry(bind_self)
1559        __(movq symbol.binding_index(%arg_z),%temp0)
1560        __(cmpq %rcontext:tcr.tlb_limit,%temp0)
1561        __(jb,pt 0f)
1562        __(push %temp0)
1563        __(tlb_too_small())
15640:      __(testq %temp0,%temp0)
1565        __(jz 9f)
1566        __(movq %rcontext:tcr.tlb_pointer,%temp1)
1567        __(cmpb $no_thread_local_binding_marker,(%temp0,%temp1))
1568        __(jz 2f)
1569        __(push (%temp1,%temp0))
1570        __(push %temp0)
1571        __(push %rcontext:tcr.db_link)
1572        __(movq %rsp,%rcontext:tcr.db_link)
1573        __(jmp *%ra0)
15742:      __(movq symbol.vcell(%arg_z),%arg_y)
1575        __(push (%temp1,%temp0))
1576        __(push %temp0)
1577        __(push %rcontext:tcr.db_link)
1578        __(movq %arg_y,(%temp1,%temp0))
1579        __(movq %rsp,%rcontext:tcr.db_link)
1580        __(jmp *%ra0)
15819:      __(movq $XSYMNOBIND,%arg_y)
1582        __(set_nargs(2))
1583        __(push %ra0)
1584        __(jmp _SPksignalerr)
1585_endsubp(bind_self)
1586
1587_spentry(bind_nil)
1588        __(movq symbol.binding_index(%arg_z),%temp0)
1589        __(cmpq %rcontext:tcr.tlb_limit,%temp0)
1590        __(jb,pt 0f)
1591        __(push %temp0)
1592        __(tlb_too_small())
15930:      __(testq %temp0,%temp0)
1594        __(jz 9f)
1595        __(movq %rcontext:tcr.tlb_pointer,%temp1)
1596        __(push (%temp1,%temp0))
1597        __(push %temp0)
1598        __(push %rcontext:tcr.db_link)
1599        __(movq %rsp,%rcontext:tcr.db_link)
1600        __(movq $nil_value,(%temp0,%temp1))
1601        __(jmp *%ra0)
16029:      __(movq $XSYMNOBIND,%arg_y)
1603        __(set_nargs(2))
1604        __(push %ra0)
1605        __(jmp _SPksignalerr)
1606_endsubp(bind_nil)
1607
1608_spentry(bind_self_boundp_check)
1609        __(movq symbol.binding_index(%arg_z),%temp0)
1610        __(cmpq %rcontext:tcr.tlb_limit,%temp0)
1611        __(jb,pt 0f)
1612        __(push %temp0)
1613        __(tlb_too_small())
16140:      __(testq %temp0,%temp0)
1615        __(jz 9f)
1616        __(movq %rcontext:tcr.tlb_pointer,%temp1)
1617        __(cmpb $no_thread_local_binding_marker,(%temp1,%temp0))
1618        __(je 2f)
1619        __(cmpb $unbound_marker,(%temp1,%temp0))
1620        __(je 8f)
1621        __(push (%temp1,%temp0))
1622        __(push %temp0)
1623        __(push %rcontext:tcr.db_link)
1624        __(movq %rsp,%rcontext:tcr.db_link)
1625        __(jmp *%ra0)
16262:      __(movq symbol.vcell(%arg_z),%arg_y)
1627        __(cmpb $unbound_marker,%arg_y_b)
1628        __(jz 8f)
1629        __(push (%temp1,%temp0))
1630        __(push %temp0)
1631        __(push %rcontext:tcr.db_link)
1632        __(movq %rsp,%rcontext:tcr.db_link)
1633        __(movq %arg_y,(%temp1,%temp0))
1634        __(jmp *%ra0)
16358:      __(push %ra0)
1636        __(uuo_error_reg_unbound(Rarg_z))
1637       
16389:      __(movq $XSYMNOBIND,%arg_y)
1639        __(set_nargs(2))
1640        __(push %ra0)
1641        __(jmp _SPksignalerr)
1642_endsubp(bind_self_boundp_check)
1643
1644_spentry(conslist)
1645        __(movl $nil_value,%arg_z_l)
1646        __(testw %nargs,%nargs)
1647        __(jmp 2f)
16481:      __(pop %arg_y)
1649        __(Cons(%arg_y,%arg_z,%arg_z))
1650        __(subw $node_size,%nargs)
16512:      __(jnz 1b)
1652        __(jmp *%ra0)           
1653_endsubp(conslist)
1654
1655/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1656/* Cons, one cons cell at at time.  Maybe optimize this later.  */
1657       
1658_spentry(conslist_star)
1659        __(testw %nargs,%nargs)
1660        __(jmp 2f)
16611:      __(pop %arg_y)
1662        __(Cons(%arg_y,%arg_z,%arg_z))
1663        __(subw $node_size,%nargs)
16642:      __(jnz 1b)
1665        __(jmp *%ra0)           
1666_endsubp(conslist_star)
1667
1668/* We always have to create a tsp frame (even if nargs is 0), so the compiler   */
1669/* doesn't get confused.   */
1670_spentry(stkconslist)
1671        __(movzwl %nargs,%nargs_l)
1672        __(movq %nargs_q,%imm1)
1673        __(addq %imm1,%imm1)
1674        __(movl $nil_value,%arg_z_l)
1675        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm1))
1676        __(TSP_Alloc_Var(%imm1,%imm0))
1677        __(addq $fulltag_cons,%imm0)
1678        __(testw %nargs,%nargs)
1679        __(jmp 2f)
16801:      __(pop %temp0)
1681        __(_rplaca(%imm0,%temp0))
1682        __(_rplacd(%imm0,%arg_z))
1683        __(movq %imm0,%arg_z)
1684        __(add $cons.size,%imm0)
1685        __(subw $node_size,%nargs)
16862:      __(jne 1b)
1687        __(jmp *%ra0)
1688_endsubp(stkconslist)
1689
1690/* do list*: last arg in arg_z, all others vpushed,   */
1691/*      nargs set to #args vpushed.  */
1692       
1693_spentry(stkconslist_star)
1694        __(movzwl %nargs,%nargs_l)
1695        __(movq %nargs_q,%imm1)
1696        __(addq %imm1,%imm1)
1697        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm1))
1698        __(TSP_Alloc_Var(%imm1,%imm0))
1699        __(addq $fulltag_cons,%imm0)
1700        __(testw %nargs,%nargs)
1701        __(jmp 2f)
17021:      __(pop %temp0)
1703        __(_rplaca(%imm0,%temp0))
1704        __(_rplacd(%imm0,%arg_z))
1705        __(movq %imm0,%arg_z)
1706        __(addq $cons.size,%imm0)
1707        __(subw $node_size,%nargs)
17082:      __(jne 1b)
1709        __(jmp *%ra0)
1710_endsubp(stkconslist_star)
1711
1712/* Make a stack-consed simple-vector out of the NARGS objects   */
1713/*      on top of the vstack; return it in arg_z.  */
1714       
1715_spentry(mkstackv)
1716        __(movzwl %nargs,%nargs_l)
1717        __(dnode_align(%nargs_q,tsp_frame.fixed_overhead+node_size,%imm1))
1718        __(TSP_Alloc_Var(%imm1,%temp0))
1719        __(movl %nargs_l,%imm0_l)
1720        __(shlq $(num_subtag_bits-fixnumshift),%imm0)
1721        __(movb $subtag_simple_vector,%imm0_b)
1722        __(movq %imm0,(%temp0))
1723        __(leaq fulltag_misc(%temp0),%arg_z)
1724        __(testw %nargs,%nargs)
1725        __(leaq misc_data_offset(%arg_z,%nargs_q),%imm1)
1726        __(jmp 2f)
17271:      __(pop -node_size(%imm1))
1728        __(subw $node_size,%nargs)
1729        __(leaq -node_size(%imm1),%imm1)
17302:      __(jne 1b)
1731        __(jmp *%ra0)   
1732_endsubp(mkstackv)
1733
1734       
1735        .globl C(egc_write_barrier_start)
1736C(egc_write_barrier_start):
1737/*  */
1738/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1739/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1740/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1741/* an intergenerational reference (a young pointer stored in an old object) has  */
1742/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1743/* This has to happen atomically, and has to happen atomically wrt GC.  */
1744
1745/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1746/* interlocked loads and stores.  */
1747
1748
1749
1750/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1751/* in the function, we can do the store (even if it's already been done) and  */
1752/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1753/* setting the bit needs to be done atomically, unless we're sure that other  */
1754/* threads are suspended.)  */
1755/* We can unconditionally set the suspended thread's RIP to the return address.  */
1756
1757       
1758_spentry(rplaca)
1759        .globl C(egc_rplaca)
1760C(egc_rplaca):
1761        __(rcmpq(%arg_z,%arg_y))
1762        __(_rplaca(%arg_y,%arg_z))
1763        __(ja 1f)
17640:      __(repret)
17651:      __(movq %arg_y,%imm0)
1766        __(subq lisp_global(heap_start),%imm0)
1767        __(shrq $dnode_shift,%imm0)
1768        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1769        __(jae 0b)
1770        __(ref_global(refbits,%temp0))
1771        __(movq %imm0,%imm1)
1772        __(andl $63,%imm0_l)
1773        __(shrq $bitmap_shift,%imm1)
1774        __(xorb $63,%imm0_b)
1775        __(lock)
1776        __(btsq %imm0,(%temp0,%imm1,8))
1777        __(ret)
1778_endsubp(rplaca)
1779
1780_spentry(rplacd)
1781        .globl C(egc_rplacd)
1782C(egc_rplacd):         
1783        __(rcmpq(%arg_z,%arg_y))
1784        __(_rplacd(%arg_y,%arg_z))
1785        __(ja 1f)
17860:      __(repret)
17871:      __(movq %arg_y,%imm0)
1788        __(subq lisp_global(heap_start),%imm0)
1789        __(shrq $dnode_shift,%imm0)
1790        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1791        __(jae 0b)
1792        __(ref_global(refbits,%temp0))
1793        __(movq %imm0,%imm1)
1794        __(andl $63,%imm0_l)
1795        __(shrq $bitmap_shift,%imm1)
1796        __(xorb $63,%imm0_b)
1797        __(lock)
1798        __(btsq %imm0,(%temp0,%imm1,8))
1799        __(ret)
1800_endsubp(rplacd)
1801
1802/* Storing into a gvector can be handled the same way as storing into a CONS.  */
1803
1804
1805_spentry(gvset)
1806        .globl C(egc_gvset)
1807C(egc_gvset):
1808        __(rcmpq(%arg_z,%arg_x))
1809        __(movq %arg_z,misc_data_offset(%arg_x,%arg_y))
1810        __(ja 1f)
18110:      __(repret)
18121:      __(lea misc_data_offset(%arg_x,%arg_y),%imm0)
1813        __(subq lisp_global(heap_start),%imm0)
1814        __(shrq $dnode_shift,%imm0)
1815        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1816        __(jae 0b)
1817        __(ref_global(refbits,%temp0))
1818        __(movq %imm0,%imm1)
1819        __(andl $63,%imm0_l)
1820        __(shrq $bitmap_shift,%imm1)
1821        __(xorb $63,%imm0_b)
1822        __(lock) 
1823        __(btsq %imm0,(%temp0,%imm1,8))
1824        __(ret)               
1825_endsubp(gvset)
1826
1827/* This is a special case of storing into a gvector: if we need to  */
1828/* memoize the store, record the address of the hash-table vector  */
1829/* in the refmap, as well.  */
1830       
1831
1832_spentry(set_hash_key)
1833        .globl C(egc_set_hash_key)
1834C(egc_set_hash_key): 
1835        __(rcmpq(%arg_z,%arg_x))
1836        __(movq %arg_z,misc_data_offset(%arg_x,%arg_y))
1837        __(ja 1f)
18380:      __(repret)
18391:      __(lea misc_data_offset(%arg_x,%arg_y),%imm0)
1840        __(subq lisp_global(heap_start),%imm0)
1841        __(shrq $dnode_shift,%imm0)
1842        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1843        __(jae 0b)
1844        __(ref_global(refbits,%temp0))
1845        __(movq %imm0,%imm1)
1846        __(andl $63,%imm0_l)
1847        __(shrq $bitmap_shift,%imm1)
1848        __(xorb $63,%imm0_b)
1849        __(lock)
1850        __( btsq %imm0,(%temp0,%imm1,8))
1851        /* Now memoize the address of the hash vector   */
1852        __(movq %arg_x,%imm0)
1853        __(subq lisp_global(heap_start),%imm0)
1854        __(shrq $dnode_shift,%imm0)
1855        __(movq %imm0,%imm1)
1856        __(andl $63,%imm0_l)
1857        __(shrq $bitmap_shift,%imm1)
1858        __(xorb $63,%imm0_b)
1859        __(lock)
1860        __(btsq %imm0,(%temp0,%imm1,8))
1861        __(ret)               
1862_endsubp(set_hash_key)
1863
1864/* This is a little trickier: if this is interrupted, we need to know  */
1865/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1866/* If we're interrupted   before the PC has reached the "success_test" label,   */
1867/* repeat (luser the PC back to .SPstore_node_conditional.)  If we're at that  */
1868/* label with the Z flag set, we won and (may) need to memoize.  */
1869
1870_spentry(store_node_conditional)
1871        .globl C(egc_store_node_conditional)
1872C(egc_store_node_conditional):
1873        __(unbox_fixnum(%temp0,%imm1))
18740:      __(movq (%arg_x,%imm1),%temp1)
1875        __(cmpq %arg_y,%temp1)
1876        __(movq %temp1,%imm0)
1877        __(jne 3f)
1878        __(lock)
1879        __(cmpxchgq %arg_z,(%arg_x,%imm1))
1880        .globl C(egc_store_node_conditional_success_test)
1881C(egc_store_node_conditional_success_test):
1882        __(jne 0b)
1883        __(lea (%arg_x,%imm1),%imm0)
1884        __(subq lisp_global(heap_start),%imm0)
1885        __(shrq $dnode_shift,%imm0)
1886        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1887        __(ref_global(refbits,%temp1))
1888        __(jae 2f)
1889        __(movq %imm0,%imm1)
1890        __(andl $63,%imm0_l)
1891        __(shrq $bitmap_shift,%imm1)
1892        __(xorb $63,%imm0_b)
1893        __(lock)
1894        __(btsq %imm0,(%temp1,%imm1,8))
1895        .globl C(egc_write_barrier_end)
1896C(egc_write_barrier_end):
18972:      __(movl $t_value,%arg_z_l)
1898        __(ret)
18993:      __(movl $nil_value,%arg_z_l)
1900        __(ret)
1901_endsubp(store_node_conditional)
1902                               
1903_spentry(setqsym)
1904        __(btq $sym_vbit_const,symbol.flags(%arg_y))
1905        __(jae _SPspecset)
1906        __(movq %arg_y,%arg_z)
1907        __(movq $XCONST,%arg_y)
1908        __(set_nargs(2))
1909        __(jmp _SPksignalerr)
1910_endsubp(setqsym)
1911
1912_spentry(progvsave)
1913        /* Error if arg_z isn't a proper list.  That's unlikely,  */
1914        /* but it's better to check now than to crash later.  */
1915       
1916        __(compare_reg_to_nil(%arg_z))
1917        __(movq %arg_z,%arg_x)  /* fast   */
1918        __(movq %arg_z,%temp1)  /* slow   */
1919        __(je 9f)               /* Null list is proper   */
19200:
1921        __(extract_lisptag(%arg_x,%imm0))
1922        __(cmpb $tag_list,%imm0_b)
1923        __(jne 8f)
1924        __(compare_reg_to_nil(%arg_x))
1925        __(je 9f)
1926        __(_cdr(%arg_x,%temp0)) /* (null (cdr fast)) ?   */
1927        __(compare_reg_to_nil(%temp0))
1928        __(je 9f)
1929        __(extract_lisptag(%temp0,%imm0))
1930        __(cmpb $tag_list,%imm0_b)
1931        __(jne 8f)
1932        __(_cdr(%temp0,%arg_x))
1933        __(_cdr(%temp1,%temp1))
1934        __(cmpq %temp1,%arg_x)
1935        __(jne 0b)
1936
19378:      __(movq $XIMPROPERLIST,%arg_y)
1938        __(set_nargs(2))
1939        __(push %ra0)
1940        __(jmp _SPksignalerr)
19419:      /* Whew           */
1942
1943        /* Next, determine the length of arg_y.  We   */
1944        /* know that it's a proper list.   */
1945        __(movq $-fixnumone,%imm0)
1946        __(movq %arg_y,%arg_x)
19471:      __(compare_reg_to_nil(%arg_x))
1948        __(_cdr(%arg_x,%arg_x))
1949        __(leaq fixnumone(%imm0),%imm0)
1950        __(jne 1b)
1951       
1952        /* imm0 is now (boxed) triplet count.  */
1953        /* Determine word count, add 1 (to align), and make room.  */
1954        /*  if count is 0, make an empty tsp frame and exit   */
1955        __(testq %imm0,%imm0)
1956        __(jne 2f)
1957        __(TSP_Alloc_Fixed(2*node_size,%imm0))
1958        __(ret)
19592:      __(movq %imm0,%imm1)
1960        __(add %imm1,%imm1)
1961        __(add %imm0,%imm1)
1962        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
1963        __(TSP_Alloc_Var(%imm1,%temp0))
1964        __(movq %imm0,(%temp0))
1965        __(movq %rcontext:tcr.db_link,%temp1)
19663:      __(movl $unbound_marker,%temp0_l)
1967        __(compare_reg_to_nil(%arg_z))
1968        __(cmovneq cons.car(%arg_z),%temp0)
1969        __(cmovneq cons.cdr(%arg_z),%arg_z)
1970        __(_car(%arg_y,%arg_x))
1971        __(_cdr(%arg_y,%arg_y))
1972        __(movq symbol.binding_index(%arg_x),%arg_x)
1973        __(cmp %rcontext:tcr.tlb_limit,%arg_x)
1974        __(jb,pt 4f)
1975        __(push %arg_x)
1976        __(tlb_too_small())
19774:      __(movq %rcontext:tcr.tlb_pointer,%imm0)
1978        __(subq $binding.size,%imm1)
1979        __(compare_reg_to_nil(%arg_y))
1980        __(movq %arg_x,binding.sym(%imm1))
1981        __(push (%imm0,%arg_x))
1982        __(pop binding.val(%imm1))
1983        __(movq %temp0,(%imm0,%arg_x))
1984        __(movq %temp1,binding.link(%imm1))
1985        __(movq %imm1,%temp1)
1986        __(jne 3b)
1987        __(movq %temp1,%rcontext:tcr.db_link)
1988        __(ret)
1989_endsubp(progvsave)
1990
1991/* Allocate node objects on the temp stack, immediate objects on the foreign  */
1992/* stack. (The caller has to know which stack to discard a frame from.)  */
1993/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
1994       
1995_spentry(stack_misc_alloc)
1996        __(movq $~(((1<<56)-1)<<fixnumshift),%temp0)
1997        __(testq %temp0,%arg_y)
1998        __(jne local_label(stack_misc_alloc_not_u56))
1999        __(unbox_fixnum(%arg_z,%imm0))
2000        __(movq %arg_y,%temp0)
2001        __(shl $num_subtag_bits-fixnumshift,%temp0)
2002        __(orq %temp0,%imm0)            /* %imm0 now = header   */
2003        __(movb $fulltagmask,%imm1_b)
2004        __(andb %imm0_b,%imm1_b)
2005        __(cmpb $fulltag_nodeheader_0,%imm1_b)
2006        __(je local_label(stack_misc_alloc_node))
2007        __(cmpb $fulltag_nodeheader_1,%imm1_b)
2008        __(je local_label(stack_misc_alloc_node))
2009        __(cmpb $ivector_class_64_bit,%imm1_b)
2010        __(jz local_label(stack_misc_alloc_64))
2011        __(cmpb $ivector_class_32_bit,%imm1_b)
2012        __(jz local_label(stack_misc_alloc_32))
2013        __(unbox_fixnum(%arg_y,%imm1))
2014        /* ivector_class_other_bit: 16, 8, or 1 ...   */
2015        __(cmpb $subtag_bit_vector,%imm0_b)
2016        __(jne local_label(stack_misc_alloc_8))
2017        __(addq $7,%imm1)
2018        __(shrq $3,%imm1)
2019        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2020local_label(stack_misc_alloc_8):       
2021        __(cmpb $subtag_simple_base_string,%imm0_b)
2022        __(jb local_label(stack_misc_alloc_16))
2023        __(unbox_fixnum(%arg_y,%imm1))
2024        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2025local_label(stack_misc_alloc_16):       
2026        __(unbox_fixnum(%arg_y,%imm1))
2027        __(shlq %imm1)
2028        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2029local_label(stack_misc_alloc_32):
2030        /* 32-bit ivector   */
2031        __(unbox_fixnum(%arg_y,%imm1))
2032        __(shlq $2,%imm1)
2033        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2034local_label(stack_misc_alloc_64):
2035        /* 64-bit ivector         */
2036        __(movq %arg_y,%imm1)
2037local_label(stack_misc_alloc_alloc_ivector):   
2038        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2039        __(cmpq $tstack_alloc_limit,%imm1)
2040        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
2041        __(movq %rcontext:tcr.foreign_sp,%stack_temp)
2042        __(movd %stack_temp,%temp1)
2043        __(subq %imm1,%rcontext:tcr.foreign_sp)
2044        __(movq %rcontext:tcr.foreign_sp,%temp0)
20450:      __(movapd %fpzero,-dnode_size(%temp1))
2046        __(subq $dnode_size,%temp1)
2047        __(cmpq %temp1,%temp0)
2048        __(jnz 0b)     
2049        __(movq %stack_temp,(%temp0))
2050        __(movq %imm0,tsp_frame.fixed_overhead(%temp0))
2051        __(leaq tsp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
2052        __(ret)
2053local_label(stack_misc_alloc_heap_alloc_ivector):
2054        __(movq %rcontext:tcr.foreign_sp,%imm1)
2055        __(subq $dnode_size,%rcontext:tcr.foreign_sp)
2056        __(movq %rcontext:tcr.foreign_sp,%imm0)
2057        __(movq %imm1,(%imm0))
2058        __(jmp _SPmisc_alloc)   
2059local_label(stack_misc_alloc_node):
2060        __(movq %arg_y,%imm1)
2061        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2062        __(cmpq $tstack_alloc_limit,%imm1)
2063        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
2064        __(TSP_Alloc_Var(%imm1,%temp0))
2065        __(movq %imm0,(%temp0))
2066        __(leaq fulltag_misc(%temp0),%arg_z)
2067        __(ret)
2068local_label(stack_misc_alloc_heap_alloc_gvector):       
2069        __(TSP_Alloc_Fixed(0,%imm0))
2070        __(jmp _SPmisc_alloc)   
2071               
2072local_label(stack_misc_alloc_not_u56):                         
2073        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_56))   
2074_endsubp(stack_misc_alloc)
2075
2076/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of   */
2077/* initial-contents.  Note that this can be used to cons any type of initialized   */
2078/* node-header'ed misc object (symbols, closures, ...) as well as vector-like   */
2079/* objects.   */
2080_spentry(gvector)
2081        __(movzwl %nargs,%nargs_l)
2082        __(movq (%rsp,%nargs_q),%imm0)  /* boxed subtype   */
2083        __(sarq $fixnumshift,%imm0)
2084        __(movq %nargs_q,%imm1)
2085        __(shlq $num_subtag_bits-word_shift,%imm1)
2086        __(orq %imm1,%imm0)
2087        __(dnode_align(%nargs_q,node_size,%imm1))
2088        __(Misc_Alloc(%arg_z))
2089        __(movq %nargs_q,%imm1)
2090        __(jmp 2f)
20911:      __(movq %temp0,misc_data_offset(%arg_z,%imm1))
20922:      __(subq $node_size,%imm1)
2093        __(pop %temp0)  /* Note the intentional fencepost:  */
2094                        /* discard the subtype as well.  */
2095        __(jge 1b)
2096        __(jmp *%ra0)
2097_endsubp(gvector)
2098
2099_spentry(mvpass)
2100        __(int $3)
2101_endsubp(mvpass)
2102
2103
2104
2105_spentry(nthvalue)
2106        __(int $3)
2107_endsubp(nthvalue)
2108
2109_spentry(values)
2110        __(movq (%temp0),%ra0)
2111        __(ref_global(ret1val_addr,%imm1))
2112        __(cmpq %imm1,%ra0)
2113        __(movzwl %nargs,%nargs_l)
2114        __(movl $nil_value,%arg_z_l)
2115        __(je 0f)
2116        __(testw %nargs,%nargs)
2117        __(cmovneq -node_size(%rsp,%nargs_q),%arg_z)
2118        __(movq %temp0,%rsp)
2119        __(ret)
21200:      __(movq 8(%temp0),%ra0)
2121        __(addq $2*node_size,%temp0)
2122        __(lea (%rsp,%nargs_q),%imm0)
2123        __(jmp 2f)
21241:      __(subq $node_size,%imm0)
2125        __(movq (%imm0),%temp1)
2126        __(subq $node_size,%temp0)
2127        __(movq %temp1,(%temp0))
21282:      __(cmpq %imm0,%rsp)
2129        __(jne 1b)
2130        __(movq %temp0,%rsp)
2131        __(jmp *%ra0)   
2132_endsubp(values)
2133
2134_spentry(default_optional_args)
2135        __(int $3)
2136_endsubp(default_optional_args)
2137
2138_spentry(opt_supplied_p)
2139        __(int $3)
2140_endsubp(opt_supplied_p)
2141
2142_spentry(lexpr_entry)
2143        __(int $3)
2144_endsubp(lexpr_entry)
2145       
2146_spentry(heap_rest_arg)
2147        __(push_argregs())
2148        __(movq %next_method_context,%arg_y)
2149        __(movzwl %nargs,%nargs_l)
2150        __(movl %nargs_l,%imm1_l)
2151        __(testl %imm1_l,%imm1_l)
2152        __(movl $nil_value,%arg_z_l)
2153        __(jmp 2f)
2154        .p2align 4
21551:      __(pop %temp1)
2156        __(Cons(%temp1,%arg_z,%arg_z))
2157        __(subl $node_size,%imm1_l)
21582:      __(jg 1b)
2159        __(push %arg_z)
2160        __(movq %arg_y,%next_method_context)
2161        __(jmp *%ra0)           
2162_endsubp(heap_rest_arg)
2163
2164/* %imm0 contains the number of fixed args ; make an &rest arg out of the others   */
2165_spentry(req_heap_rest_arg)
2166        __(push_argregs())
2167        __(movq %next_method_context,%arg_y)
2168        __(movzwl %nargs,%nargs_l)
2169        __(movl %nargs_l,%imm1_l)
2170        __(subl %imm0_l,%imm1_l)
2171        __(movl $nil_value,%arg_z_l)
2172        __(jmp 2f)
2173        .p2align 4
21741:      __(pop %temp1)
2175        __(Cons(%temp1,%arg_z,%arg_z))
2176        __(subl $node_size,%imm1_l)
21772:      __(jg 1b)
2178        __(push %arg_z)
2179        __(movq %arg_y,%next_method_context)
2180        __(jmp *%ra0)           
2181_endsubp(req_heap_rest_arg)
2182
2183/* %imm0 bytes of stuff has already been pushed   */
2184/* make an &rest arg out of any others   */
2185_spentry(heap_cons_rest_arg)
2186        __(movzwl %nargs,%nargs_l)
2187        __(movl %nargs_l,%imm1_l)
2188        __(subl %imm0_l,%imm1_l)
2189        __(movq %next_method_context,%arg_y)
2190        __(movl $nil_value,%arg_z_l)
2191        __(jmp 2f)
2192        .p2align 4
21931:      __(pop %temp1)
2194        __(Cons(%temp1,%arg_z,%arg_z))
2195        __(subl $node_size,%imm1_l)
21962:      __(jg 1b)
2197        __(push %arg_z)
2198        __(movq %arg_y,%next_method_context)
2199        __(jmp *%ra0)           
2200_endsubp(heap_cons_rest_arg)
2201
2202_spentry(simple_keywords)
2203        __(xorl %imm0_l,%imm0_l)
2204        __(push_argregs())
2205        __(jmp _SPkeyword_bind)
2206_endsubp(simple_keywords)
2207
2208_spentry(keyword_args)
2209        __(push_argregs())
2210        __(jmp _SPkeyword_bind)
2211_endsubp(keyword_args)
2212
2213/* There are %nargs words of arguments on the stack; %imm0 contains the number  */
2214/* of non-keyword args pushed.  It's possible that we never actually got  */
2215/* any keyword args, which would make things much simpler.   */
2216
2217/* On entry, temp1 contains a fixnum with bits indicating whether   */
2218/* &allow-other-keys and/or &rest was present in the lambda list.  */
2219/* Once we get here, we can use the arg registers.  */
2220
2221define([keyword_flags_aok_bit],[fixnumshift])
2222define([keyword_flags_unknown_keys_bit],[fixnumshift+1])
2223define([keyword_flags_rest_bit],[fixnumshift+2])
2224define([keyword_flags_seen_aok_bit],[fixnumshift+3])       
2225       
2226_spentry(keyword_bind)
2227        __(movzwl %nargs,%imm1_l)
2228        __(subq %imm0,%imm1)
2229        __(jbe local_label(no_keyword_values))
2230        __(btq $word_shift,%imm1)
2231        __(jnc local_label(even))
2232        __(movl $nil_value,%arg_z_l)
2233        __(movq %imm1,%nargs_q)
2234        __(testw %nargs,%nargs)
2235        __(jmp 1f)
22360:      __(pop %arg_y)
2237        __(Cons(%arg_y,%arg_z,%arg_z))
2238        __(subw $node_size,%nargs)
22391:      __(jnz 0b)
2240        __(movl $XBADKEYS,%arg_y_l)
2241        __(set_nargs(2))
2242        __(jmp _SPksignalerr)
2243        /* Now that we're sure that we have an even number of keywords and values  */
2244        /* (in %imm1), copy all pairs to the temp stack   */
2245local_label(even):
2246        __(lea tsp_frame.fixed_overhead(%imm1),%arg_z)
2247        __(TSP_Alloc_Var(%arg_z,%imm0))
22482:      __(subq $node_size,%arg_z)
2249        __(pop (%arg_z))
2250        __(cmpq %arg_z,%imm0)
2251        __(jne 2b)
2252        /* Get the keyword vector into arg_x, and its length into arg_y.  */
2253        /* Push arg_y pairs of NILs.   */
2254        __(movl function_data_offset(%fn),%imm0_l)
2255        __(movq function_data_offset(%fn,%imm0,node_size),%arg_x)
2256        __(vector_length(%arg_x,%arg_y))
2257        __(movq %arg_y,%imm0)
2258        __(jmp 4f)
22593:      __(push $nil_value)
2260        __(push $nil_value)
22614:      __(subq $fixnumone,%arg_y)
2262        __(jge 3b)
2263        /* Push the %saveN registers, so that we can use them in this loop   */
2264        __(push %save3)
2265        __(push %save2)
2266        __(push %save1)
2267        __(push %save0)
2268        __(leaq 4*node_size(%rsp,%imm0,2),%save0)
2269        /* %save0 points to the 0th value/supplied-p pair   */
2270        __(leaq (%arg_z,%imm1),%save1)
2271        /* %save1 is the end of the provided keyword/value pairs (the old %tsp).   */
2272        __(movq %imm0,%save2)
2273        /* %save2 is the length of the keyword vector   */
22745:      __(movq (%arg_z),%save3)        /* %save3 is current keyword   */
2275        __(xorl %imm0_l,%imm0_l)
2276        __(cmpq $nrs.kallowotherkeys,%save3)
2277        __(jne local_label(next_keyvect_entry))
2278        __(btsq $keyword_flags_seen_aok_bit,%temp1)
2279        __(jc local_label(next_keyvect_entry))
2280        __(cmpb $fulltag_nil,node_size(%arg_z))
2281        __(je local_label(next_keyvect_entry))
2282        __(btsq $keyword_flags_aok_bit,%temp1)
2283        __(jmp local_label(next_keyvect_entry))
22846:      __(cmpq misc_data_offset(%arg_x,%imm0),%save3)
2285        __(jne 7f)
2286        /* Got a match; have we already seen this keyword ?   */
2287        __(negq %imm0)
2288        __(cmpb $fulltag_nil,-node_size*2(%save0,%imm0,2))
2289        __(jne 9f)      /* already seen keyword, ignore this value   */
2290        __(movq node_size(%arg_z),%save3)
2291        __(movq %save3,-node_size(%save0,%imm0,2))
2292        __(movl $t_value,-node_size*2(%save0,%imm0,2))
2293        __(jmp 9f)
22947:      __(addq $node_size,%imm0)
2295local_label(next_keyvect_entry):       
2296        __(cmpq %imm0,%save2)
2297        __(jne 6b)
2298        /* Didn't match anything in the keyword vector. Is the keyword  */
2299        /* :allow-other-keys ?   */
2300        __(cmpq $nrs.kallowotherkeys,%save3)
2301        __(je 9f)               /* :allow-other-keys is never "unknown" */
23028:      __(btsq $keyword_flags_unknown_keys_bit,%temp1)
23039:      __(addq $dnode_size,%arg_z)
2304        __(cmpq %arg_z,%save1)
2305        __(jne 5b)
2306        __(pop %save0)
2307        __(pop %save1)
2308        __(pop %save2)
2309        __(pop %save3)
2310        /* If the function takes an &rest arg, or if we got an unrecognized  */
2311        /* keyword and don't allow that, copy the incoming keyword/value  */
2312        /* pairs from the temp stack back to the value stack   */
2313        __(btq $keyword_flags_rest_bit,%temp1)
2314        __(jc 1f)
2315        __(btq $keyword_flags_unknown_keys_bit,%temp1)
2316        __(jnc 0f)
2317        __(btq $keyword_flags_aok_bit,%temp1)
2318        __(jnc 1f)
2319        /* pop the temp frame   */
23200:      __(discard_temp_frame(%imm1))
2321        __(jmp *%ra0)
2322        /* Copy the keyword/value pairs from the tsp back to sp, either because  */
2323        /* the function takes an &rest arg or because we need to signal an  */
2324        /* "unknown keywords" error   */
23251:      __(movq %rcontext:tcr.save_tsp,%arg_z)
2326        __(mov (%arg_z),%arg_y)
2327        __(jmp 3f)
23282:      __(push (%arg_z))
2329        __(push node_size(%arg_z))
23303:      __(addq $dnode_size,%arg_z)
2331        __(cmpq %arg_z,%arg_y)
2332        __(jne 2b)
2333        __(discard_temp_frame(%imm0))
2334        __(btq $keyword_flags_unknown_keys_bit,%temp1)
2335        __(jnc,pt 9f)
2336        __(btq $keyword_flags_aok_bit,%temp1)
2337        __(jc,pt 9f)
2338        /* Signal an "unknown keywords" error   */
2339        __(movq %imm1,%nargs_q)
2340        __(testw %nargs,%nargs)
2341        __(movl $nil_value,%arg_z_l)
2342        __(jmp 5f)
23434:      __(pop %arg_y)
2344        __(Cons(%arg_y,%arg_z,%arg_z))
2345        __(subw $node_size,%nargs)
23465:      __(jnz 4b)
2347        __(movl $XBADKEYS,%arg_y_l)
2348        __(set_nargs(2))
2349        __(push %ra0)
2350        __(jmp _SPksignalerr)
23519:      __(jmp *%ra0)
2352       
2353/* No keyword values were provided.  Access the keyword vector (which is the 0th  */
2354/*  constant in %fn), determine its length N, and push N        pairs of NILs.   */
2355/* N could be 0 ...  */
2356       
2357local_label(no_keyword_values):         
2358        __(movl function_data_offset(%fn),%imm0_l)
2359        __(movq function_data_offset(%fn,%imm0,node_size),%arg_x)
2360        __(movl $nil_value,%arg_z_l)
2361        __(vector_length(%arg_x,%arg_y))
2362        __(jmp 1f)
23630:      __(push %arg_z)
2364        __(push %arg_z)
23651:      __(subq $fixnumone,%arg_y)
2366        __(jge 0b)
2367        __(jmp *%ra0)           
2368_endsubp(keyword_bind)
2369
2370
2371
2372_spentry(ksignalerr)
2373        __(movq $nrs.errdisp,%fname)
2374        __(jump_fname) 
2375_endsubp(ksignalerr)
2376
2377_spentry(stack_rest_arg)
2378        __(xorl %imm0_l,%imm0_l)
2379        __(push_argregs())
2380        __(jmp _SPstack_cons_rest_arg)
2381_endsubp(stack_rest_arg)
2382
2383_spentry(req_stack_rest_arg)
2384        __(push_argregs())
2385        __(jmp _SPstack_cons_rest_arg)
2386_endsubp(req_stack_rest_arg)
2387
2388_spentry(stack_cons_rest_arg)
2389        __(movzwl %nargs,%nargs_l)
2390        __(movl %nargs_l,%imm1_l)
2391        __(subl %imm0_l,%imm1_l)
2392        __(movl $nil_value,%arg_z_l)
2393        __(je 2f)       /* empty list ; make an empty TSP frame   */
2394        __(addq %imm1,%imm1)
2395        __(cmpq $(tstack_alloc_limit-dnode_size),%imm1)
2396        __(ja 3f)       /* make empty frame, then heap-cons   */
2397        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm0))
2398        __(TSP_Alloc_Var(%imm0,%temp1))
2399        __(addq $fulltag_cons,%temp1)
24001:      __(pop %arg_x)
2401        __(_rplacd(%temp1,%arg_z))
2402        __(_rplaca(%temp1,%arg_x))
2403        __(movq %temp1,%arg_z)
2404        __(addq $cons.size,%temp1)
2405        __(subq $dnode_size,%imm1)
2406        __(jne 1b)
2407        __(push %arg_z)
2408        __(jmp *%ra0)
2409       
2410/* Length 0, make empty frame  */
2411       
24122:
2413        __(TSP_Alloc_Fixed(0,%temp1))
2414        __(push %arg_z)
2415        __(jmp *%ra0)
2416       
2417/* Too big to stack-cons, but make an empty frame before heap-consing  */
2418       
24193:             
2420        __(TSP_Alloc_Fixed(0,%temp1))
2421        __(jmp _SPheap_cons_rest_arg)
2422_endsubp(stack_cons_rest_arg)
2423
2424
2425
2426_spentry(getxlong)
2427_endsubp(getxlong)
2428
2429/* Have to be a little careful here: the caller may or may not have pushed  */
2430/*   an empty frame, and we may or may not have needed one.  We can't easily  */
2431/*   tell whether or not a frame will be needed (if the caller didn't reserve  */
2432/*   a frame, whether or not we need one depends on the length of the list  */
2433/*   in arg_z.  So, if the caller didn't push a frame, we do so ; once everything'*/
2434/*   been spread, we discard the reserved frame (regardless of who pushed it)  */
2435/*   if all args fit in registers.   */
2436_spentry(spreadargz)
2437        __(testw %nargs,%nargs)
2438        __(jne 0f)
2439        __(push $reserved_frame_marker)
2440        __(push $reserved_frame_marker)
24410:      __(movq %arg_z,%arg_y)  /* save in case of error   */
2442        __(xorl %imm0_l,%imm0_l)
2443        __(compare_reg_to_nil(%arg_z))
2444        __(je 2f)
24451:      __(extract_fulltag(%arg_z,%imm1))
2446        __(cmpb $fulltag_cons,%imm1_b)
2447        __(jne 9f)
2448        __(_car(%arg_z,%arg_x))
2449        __(_cdr(%arg_z,%arg_z))
2450        __(addl $node_size,%imm0_l)
2451        __(compare_reg_to_nil(%arg_z))
2452        __(push %arg_x)
2453        __(jne 1b)
24542:      __(addw %imm0_w,%nargs)
2455        __(jne 4f)
24563:      __(addq $2*node_size,%rsp)
2457        __(jmp *%ra0)
24584:      __(cmpw $1*node_size,%nargs)
2459        __(pop %arg_z)
2460        __(je 3b)
2461        __(cmpw $2*node_size,%nargs)
2462        __(pop %arg_y)
2463        __(je 3b)
2464        __(cmpw $3*node_size,%nargs)
2465        __(pop %arg_x)
2466        __(je 3b)
2467        __(jmp *%ra0)
2468/* Discard everything that's been pushed already, complain   */
24698:      __(lea (%rsp,%imm0),%rsp)
2470        __(movq %arg_y,%arg_z)  /* recover original   */
2471        __(movq $XTMINPS,%arg_y)
2472        __(set_nargs(2))
2473        __(push %ra0)
2474        __(jmp _SPksignalerr)
2475/* Discard everything that's been pushed already, complain   */
24769:      __(lea (%rsp,%imm0),%rsp)
2477        __(movq %arg_y,%arg_z)  /* recover original   */
2478        __(movq $XNOSPREAD,%arg_y)
2479        __(set_nargs(2))
2480        __(push %ra0)
2481        __(jmp _SPksignalerr)
2482_endsubp(spreadargz)
2483
2484/* Caller built it's own frame when it was entered.  If all outgoing args  */
2485/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2486/* relative to it and restore %rbp/%ra0   */
2487_spentry(tfuncallgen)
2488        __(cmpw $nargregs*node_size,%nargs)
2489        __(jbe 9f)
2490        __(movzwl %nargs,%nargs_l)
2491        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2492        __(xorl %imm1_l,%imm1_l)
2493        /* We can use %ra0 as a temporary here, since the real return address  */
2494        /* is on the stack   */
24950:      __(movq -node_size(%imm0),%ra0)
2496        __(movq %ra0,-node_size(%rbp,%imm1))
2497        __(subq $node_size,%imm0)
2498        __(subq $node_size,%imm1)
2499        __(cmpq %imm0,%rsp)
2500        __(jne 0b)
2501        __(lea (%rbp,%imm1),%rsp)
2502        __(movq 8(%rbp),%ra0)
2503        __(movq (%rbp),%rbp)
2504        __(pushq %ra0)
2505        __(do_funcall())
2506        /* All args in regs; exactly the same as the tfuncallvsp case   */
25079:             
2508        __(leave)
2509        __(do_funcall())
2510_endsubp(tfuncallgen)
2511
2512/* Some args were pushed; move them down in the frame   */
2513_spentry(tfuncallslide)
2514        __(movzwl %nargs,%nargs_l)
2515        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2516        __(xorl %imm1_l,%imm1_l)
2517        /* We can use %ra0 as a temporary here, since the real return address  */
2518        /* is on the stack   */
25190:      __(movq -node_size(%imm0),%ra0)
2520        __(movq %ra0,-node_size(%rbp,%imm1))
2521        __(subq $node_size,%imm0)
2522        __(subq $node_size,%imm1)
2523        __(cmpq %imm0,%rsp)
2524        __(jne 0b)
2525        __(lea (%rbp,%imm1),%rsp)
2526        __(movq 8(%rbp),%ra0)
2527        __(movq (%rbp),%rbp)
2528        __(push %ra0)
2529        __(do_funcall())       
2530_endsubp(tfuncallslide)
2531
2532/* No args were pushed; recover saved context & do funcall        */
2533_spentry(tfuncallvsp)
2534        __(leave)
2535        __(do_funcall())
2536_endsubp(tfuncallvsp)
2537
2538_spentry(tcallsymgen)
2539        __(cmpw $nargregs*node_size,%nargs)
2540        __(jbe 9f)
2541        __(movzwl %nargs,%nargs_l)
2542        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2543        __(xorl %imm1_l,%imm1_l)
2544        /* We can use %ra0 as a temporary here, since the real return address  */
2545        /* is on the stack   */
25460:      __(movq -node_size(%imm0),%ra0)
2547        __(movq %ra0,-node_size(%rbp,%imm1))
2548        __(subq $node_size,%imm0)
2549        __(subq $node_size,%imm1)
2550        __(cmpq %imm0,%rsp)
2551        __(jne 0b)
2552        __(lea (%rbp,%imm1),%rsp)
2553        __(movq 8(%rbp),%ra0)
2554        __(movq (%rbp),%rbp)
2555        __(pushq %ra0)
2556        __(jump_fname())
2557/* All args in regs; exactly the same as the tcallsymvsp case   */
25589:             
2559        __(leave)
2560        __(jump_fname())
2561_endsubp(tcallsymgen)
2562
2563_spentry(tcallsymslide)
2564        __(movzwl %nargs,%nargs_l)
2565        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2566        __(xorl %imm1_l,%imm1_l)
2567        /* We can use %ra0 as a temporary here, since the real return address  */
2568        /* is on the stack   */
25690:      __(movq -node_size(%imm0),%ra0)
2570        __(movq %ra0,-node_size(%rbp,%imm1))
2571        __(subq $node_size,%imm0)
2572        __(subq $node_size,%imm1)
2573        __(cmpq %imm0,%rsp)
2574        __(jne 0b)
2575        __(lea (%rbp,%imm1),%rsp)
2576        __(movq 8(%rbp),%ra0)
2577        __(movq 0(%rbp),%rbp)
2578        __(pushq %ra0)
2579        __(jump_fname())
2580_endsubp(tcallsymslide)
2581
2582_spentry(tcallsymvsp)
2583        __(leave)
2584        __(jump_fname())
2585_endsubp(tcallsymvsp)
2586
2587_spentry(tcallnfngen)
2588        __(cmpw $nargregs*node_size,%nargs)
2589        __(jbe 9f)
2590        __(movzwl %nargs,%nargs_l)
2591        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2592        __(xorl %imm1_l,%imm1_l)
2593        /* We can use %ra0 as a temporary here, since the real return address  */
2594        /* is on the stack   */
25950:      __(movq -node_size(%imm0),%ra0)
2596        __(movq %ra0,-node_size(%rbp,%imm1))
2597        __(subq $node_size,%imm0)
2598        __(subq $node_size,%imm1)
2599        __(cmpq %imm0,%rsp)
2600        __(jne 0b)
2601        __(movq %temp0,%fn)
2602        __(lea (%rbp,%imm1),%rsp)
2603        __(movq lisp_frame.savera0(%rbp),%ra0)
2604        __(movq lisp_frame.backlink(%rbp),%rbp)
2605        __(pushq %ra0)
2606        __(jmp *%fn)
2607/* All args in regs; exactly the same as the tcallnfnvsp case   */
26089:             
2609        __(movq %temp0,%fn)
2610        __(leave)
2611        __(jmp *%fn)
2612_endsubp(tcallnfngen)
2613
2614_spentry(tcallnfnslide)
2615        __(movzwl %nargs,%nargs_l)
2616        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2617        __(xorl %imm1_l,%imm1_l)
2618        /* We can use %ra0 as a temporary here, since the real return address  */
2619        /* is on the stack   */
26200:      __(movq -node_size(%imm0),%ra0)
2621        __(movq %ra0,-node_size(%rbp,%imm1))
2622        __(subq $node_size,%imm0)
2623        __(subq $node_size,%imm1)
2624        __(cmpq %imm0,%rsp)
2625        __(jne 0b)
2626        __(movq %temp0,%fn)
2627        __(lea (%rbp,%imm1),%rsp)
2628        __(movq lisp_frame.savera0(%rbp),%ra0)
2629        __(movq lisp_frame.backlink(%rbp),%rbp)
2630        __(pushq %ra0)
2631        __(jmp *%fn)
2632_endsubp(tcallnfnslide)
2633
2634_spentry(tcallnfnvsp)
2635        __(movq %temp0,%fn)
2636        __(leave)
2637        __(jmp *%fn)
2638_endsubp(tcallnfnvsp)
2639
2640
2641/* Make a "raw" area on the foreign stack, stack-cons a macptr to point to it,   */
2642/*   and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr  */
2643/*   in arg_z on exit.   */
2644_spentry(makestackblock)
2645        __(unbox_fixnum(%arg_z,%imm0))
2646        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2647        __(cmpq $tstack_alloc_limit,%imm0)
2648        __(jae 1f)
2649        __(movq %rcontext:tcr.foreign_sp,%imm1)
2650        __(subq %imm0,%rcontext:tcr.foreign_sp)
2651        __(movq %rcontext:tcr.foreign_sp,%arg_z)
2652        __(movq %imm1,(%arg_z))
2653        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2654        __(movq $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2655        __(addq $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2656        __(movq %imm0,macptr.address(%arg_z))
2657        __(movsd %fpzero,macptr.domain(%arg_z))
2658        __(movsd %fpzero,macptr.type(%arg_z))
2659        __(ret)
26601:      __(movq %rcontext:tcr.foreign_sp,%imm1)
2661        __(subq $dnode_size,%rcontext:tcr.foreign_sp)
2662        __(movq %rcontext:tcr.foreign_sp,%imm0)
2663        __(movq %imm1,(%imm0))
2664        __(set_nargs(1))
2665        __(movq $nrs.new_gcable_ptr,%fname)
2666        __(jump_fname())
2667_endsubp(makestackblock)
2668
2669_spentry(makestackblock0)
2670        __(unbox_fixnum(%arg_z,%imm0))
2671        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2672        __(cmpq $tstack_alloc_limit,%imm0)
2673        __(jae 9f)
2674        __(movq %rcontext:tcr.foreign_sp,%imm1)
2675        __(subq %imm0,%rcontext:tcr.foreign_sp)
2676        __(movq %rcontext:tcr.foreign_sp,%arg_z)
2677        __(movq %imm1,(%arg_z))
2678        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2679        __(movq $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2680        __(addq $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2681        __(movq %imm0,macptr.address(%arg_z))
2682        __(movsd %fpzero,macptr.domain(%arg_z))
2683        __(movsd %fpzero,macptr.type(%arg_z))
2684        __(jmp 2f)
26851:      __(movapd %fpzero,(%imm0))
2686        __(addq $dnode_size,%imm0)
26872:      __(cmpq %imm0,%imm1)
2688        __(jne 1b)             
2689        __(repret)
26909:      __(movq %rcontext:tcr.foreign_sp,%imm1)
2691        __(subq $dnode_size,%rcontext:tcr.foreign_sp)
2692        __(movq %rcontext:tcr.foreign_sp,%imm0)
2693        __(movq %imm1,(%imm0))
2694        __(set_nargs(1))
2695        __(movq $nrs.new_gcable_ptr,%fname)
2696        __(jump_fname())
2697_endsubp(makestackblock0)
2698
2699_spentry(makestacklist)
2700        __(movq %arg_y,%imm0)
2701        __(addq %imm0,%imm0)
2702        __(rcmpq(%imm0,$tstack_alloc_limit))
2703        __(movl $nil_value,%temp1_l)
2704        __(jae 2f)
2705        __(addq $tsp_frame.fixed_overhead,%imm0)
2706        __(TSP_Alloc_Var(%imm0,%temp0))
2707        __(addq $fulltag_cons,%temp0)
2708        __(jmp 1f)
27090:      __(_rplaca(%temp0,%arg_z))
2710        __(_rplacd(%temp0,%temp1))
2711        __(movq %temp0,%temp1)
2712        __(addq $cons.size,%temp0)
27131:      __(subq $fixnumone,%arg_y)
2714        __(jge 0b)
2715        __(movq %temp1,%arg_z)
2716        __(ret)
27172:      __(TSP_Alloc_Fixed(0,%imm0))
2718        __(jmp 4f)
27193:      __(Cons(%arg_z,%temp1,%temp1))
27204:      __(subq $fixnumone,%arg_y)                             
2721        __(jge 3b)
2722        __(movq %temp1,%arg_z)
2723        __(ret)
2724_endsubp(makestacklist)
2725
2726/* subtype (boxed) vpushed before initial values. (Had better be a   */
2727/* node header subtag.) Nargs set to count of things vpushed.     */
2728_spentry(stkgvector)
2729        __(movzwl %nargs,%nargs_l)
2730        __(lea -fixnum_one(%nargs_q),%imm0)
2731        __(lea (%rsp,%imm0),%arg_x)
2732        __(movq %imm0,%arg_y)
2733        __(shlq $num_subtag_bits-fixnumshift,%imm0)
2734        __(movq (%arg_x), %imm1)
2735        __(shrq $fixnumshift,%imm1)
2736        __(orq %imm1,%imm0)     /* imm0 = header, %arg_y = unaligned size   */
2737        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm1))
2738        __(TSP_Alloc_Var(%imm1,%arg_z))
2739        __(movq %imm0,(%arg_z))
2740        __(addq $fulltag_misc,%arg_z)
2741        __(lea -node_size(%nargs_q),%imm0)
2742        __(jmp 2f)
27431:      __(pop misc_data_offset(%arg_z,%imm0))
27442:      __(subq $node_size,%imm0)
2745        __(jge 1b)
2746        __(addq $node_size,%rsp)
2747        __(jmp *%ra0)   
2748_endsubp(stkgvector)
2749
2750_spentry(misc_alloc)
2751        __(movq $~(((1<<56)-1)<<fixnumshift),%imm0)
2752        __(testq %imm0,%arg_y)
2753        __(jne local_label(misc_alloc_not_u56))
2754        __(unbox_fixnum(%arg_z,%imm0))
2755        __(movq %arg_y,%temp0)
2756        __(shl $num_subtag_bits-fixnumshift,%temp0)
2757        __(orq %temp0,%imm0)            /* %imm0 now = header   */
2758        __(movb $fulltagmask,%imm1_b)
2759        __(andb %imm0_b,%imm1_b)
2760        __(cmpb $fulltag_nodeheader_0,%imm1_b)
2761        __(je local_label(misc_alloc_64))
2762        __(cmpb $fulltag_nodeheader_1,%imm1_b)
2763        __(je local_label(misc_alloc_64))
2764        __(cmpb $ivector_class_64_bit,%imm1_b)
2765        __(jz local_label(misc_alloc_64))
2766        __(cmpb $ivector_class_32_bit,%imm1_b)
2767        __(jz local_label(misc_alloc_32))
2768        __(unbox_fixnum(%arg_y,%imm1))
2769        /* ivector_class_other_bit: 16, 8, or 1 ...   */
2770        __(cmpb $subtag_bit_vector,%imm0_b)
2771        __(jne local_label(misc_alloc_8))
2772        __(addq $7,%imm1)
2773        __(shrq $3,%imm1)
2774        __(jmp local_label(misc_alloc_alloc_vector))
2775local_label(misc_alloc_8):     
2776        __(cmpb $subtag_simple_base_string,%imm0_b)
2777        __(jae local_label(misc_alloc_alloc_vector))
2778local_label(misc_alloc_16):     
2779        __(shlq %imm1)
2780        __(jmp local_label(misc_alloc_alloc_vector))
2781local_label(misc_alloc_32):
2782        /* 32-bit ivector   */
2783        __(unbox_fixnum(%arg_y,%imm1))
2784        __(shlq $2,%imm1)
2785        __(jmp local_label(misc_alloc_alloc_vector))
2786local_label(misc_alloc_64):
2787        /* 64-bit ivector or gvector      */
2788        __(movq %arg_y,%imm1)
2789local_label(misc_alloc_alloc_vector):   
2790        __(dnode_align(%imm1,node_size,%imm1))
2791        __(Misc_Alloc(%arg_z))
2792        __(ret)
2793local_label(misc_alloc_not_u56):
2794        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_56))
2795_endsubp(misc_alloc)
2796
2797
2798_startfn(C(destbind1))
2799        /* Save entry %rsp in case of error   */
2800        __(movd %rsp,%mm0)
2801        /* Extract required arg count.   */
2802        __(movzbl %nargs_b,%imm0_l)
2803        __(testl %imm0_l,%imm0_l)
2804        __(je local_label(opt))         /* skip if no required args   */
2805local_label(req_loop): 
2806        __(compare_reg_to_nil(%arg_reg))
2807        __(je local_label(toofew))
2808        __(extract_lisptag(%arg_reg,%imm1))
2809        __(cmpb $tag_list,%imm1_b)
2810        __(jne local_label(badlist))
2811        __(subb $1,%imm0_b)
2812        __(pushq cons.car(%arg_reg))
2813        __(_cdr(%arg_reg,%arg_reg))
2814        __(jne local_label(req_loop))
2815local_label(opt):       
2816        __(movw %nargs,%imm0_w)
2817        __(shrw $8,%imm0_w)
2818        __(je local_label(rest_keys))
2819        __(btl $initopt_bit,%nargs_l)
2820        __(jc local_label(opt_supp))
2821        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2822local_label(simple_opt_loop):
2823        __(compare_reg_to_nil(%arg_reg))
2824        __(je local_label(default_simple_opt))
2825        __(extract_lisptag(%arg_reg,%imm1))
2826        __(cmpb $tag_list,%imm1_b)
2827        __(jne local_label(badlist))
2828        __(subb $1,%imm0_b)
2829        __(pushq cons.car(%arg_reg))
2830        __(_cdr(%arg_reg,%arg_reg))
2831        __(jne local_label(simple_opt_loop))
2832        __(jmp local_label(rest_keys))
2833local_label(default_simple_opt):
2834        __(subb $1,%imm0_b)
2835        __(pushq $nil_value)
2836        __(jne local_label(default_simple_opt))
2837        __(jmp local_label(rest_keys))
2838local_label(opt_supp):
2839        __(extract_lisptag(%arg_reg,%imm1))
2840        __(compare_reg_to_nil(%arg_z))
2841        __(je local_label(default_hard_opt))
2842        __(cmpb $tag_list,%imm1_b)
2843        __(jne local_label(badlist))
2844        __(subb $1,%imm0_b)
2845        __(pushq cons.car(%arg_reg))
2846        __(_cdr(%arg_reg,%arg_reg))
2847        __(push $t_value)
2848        __(jne local_label(opt_supp))
2849        __(jmp local_label(rest_keys))
2850local_label(default_hard_opt):
2851        __(subb $1,%imm0_b)
2852        __(push $nil_value)
2853        __(push $nil_value)
2854        __(jne local_label(default_hard_opt))   
2855local_label(rest_keys): 
2856        __(btl $restp_bit,%nargs_l)
2857        __(jc local_label(have_rest))
2858        __(btl $keyp_bit,%nargs_l)
2859        __(jc local_label(have_keys))
2860        __(compare_reg_to_nil(%arg_reg))
2861        __(jne local_label(toomany))
2862        __(jmp *%ra0)
2863local_label(have_rest):
2864        __(pushq %arg_reg)
2865        __(btl $keyp_bit,%nargs_l)
2866        __(jc local_label(have_keys))
2867        __(jmp *%ra0)           
2868        /* Ensure that arg_reg contains a proper,even-length list.  */
2869        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2870local_label(have_keys):
2871        __(movw $256,%imm0_w)
2872        __(movq %arg_reg,%arg_y)
2873local_label(count_keys_loop):   
2874        __(compare_reg_to_nil(%arg_y))
2875        __(je local_label(counted_keys))
2876        __(subw $1,%imm0_w)
2877        __(jl local_label(toomany))
2878        __(extract_lisptag(%arg_y,%imm1))
2879        __(cmpb $tag_list,%imm1_b)
2880        __(jne local_label(badlist))
2881        __(_cdr(%arg_y,%arg_y))
2882        __(extract_fulltag(%arg_y,%imm1))
2883        __(cmpb $fulltag_cons,%imm1_b)
2884        __(jne local_label(badlist))
2885        __(_cdr(%arg_y,%arg_y))
2886        __(jmp local_label(count_keys_loop))
2887local_label(counted_keys):             
2888        /* We've got a proper, even-length list of key/value pairs in  */
2889        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2890        /* of NILs on the vstack.   */
2891       
2892        __(movl %nargs_l,%imm1_l)
2893        __(shrl $16,%imm1_l)
2894        __(movzbl %imm1_b,%imm0_l)
2895        __(movq %rsp,%arg_y)
2896        __(jmp local_label(push_pair_test))     
2897local_label(push_pair_loop):
2898        __(push $nil_value)
2899        __(push $nil_value)
2900local_label(push_pair_test):   
2901        __(subb $1,%imm1_b)
2902        __(jge local_label(push_pair_loop))
2903        /* Push the %saveN registers, so that we can use them in this loop   */
2904        __(push %save0)
2905        __(push %save1)
2906        __(push %save2)
2907        __(push %save3)
2908        /* save0 points to the 0th value/supplied-p pair   */
2909        __(movq %arg_y,%save0)
2910        /* save1 is the length of the keyword vector   */
2911        __(vector_length(%arg_x,%save1))
2912        /* save2 is the current keyword   */
2913        /* save3 is the value of the current keyword   */
2914        __(xorl %imm0_l,%imm0_l)        /* count unknown keywords seen   */
2915local_label(match_keys_loop):
2916        __(compare_reg_to_nil(%arg_reg))
2917        __(je local_label(matched_keys))
2918        __(_car(%arg_reg,%save2))
2919        __(_cdr(%arg_reg,%arg_reg))
2920        __(_car(%arg_reg,%save3))
2921        __(_cdr(%arg_reg,%arg_reg))
2922        __(xorl %arg_y_l,%arg_y_l)
2923        __(jmp local_label(match_test))
2924local_label(match_loop):
2925        __(cmpq misc_data_offset(%arg_x,%arg_y),%save2)
2926        __(je local_label(matched))
2927        __(addq $node_size,%arg_y)
2928local_label(match_test):
2929        __(cmpq %arg_y,%save1)
2930        __(jne local_label(match_loop))
2931        /* No match.  Note unknown keyword, check for :allow-other-keys   */
2932        __(addl $1,%imm0_l)
2933        __(cmpq $nrs.kallowotherkeys,%save2)
2934        __(jne local_label(match_keys_loop))
2935        __(subl $1,%imm0_l)
2936        __(btsl $seen_aok_bit,%nargs_l)
2937        __(jc local_label(match_keys_loop))
2938        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
2939        __(compare_reg_to_nil(%save3))
2940        __(je local_label(match_keys_loop))
2941        __(btsl $aok_bit,%nargs_l)
2942        __(jmp local_label(match_keys_loop))
2943        /* Got a match.  Worry about :allow-other-keys here, too.   */
2944local_label(matched):
2945        __(negq %arg_y)
2946        __(cmpb $fulltag_nil,-node_size*2(%save0,%arg_y,2))
2947        __(jne local_label(match_keys_loop))
2948        __(movq %save3,-node_size(%save0,%arg_y,2))
2949        __(movl $t_value,-node_size*2(%save0,%arg_y,2))
2950        __(cmpq $nrs.kallowotherkeys,%save2)
2951        __(jne local_label(match_keys_loop))
2952        __(btsl $seen_aok_bit,%nargs_l)
2953        __(jnc local_label(match_keys_loop))
2954        __(compare_reg_to_nil(%save3))
2955        __(je local_label(match_keys_loop))
2956        __(btsl $aok_bit,%nargs_l)
2957        __(jmp local_label(match_keys_loop))
2958local_label(matched_keys):             
2959        __(pop %save3)
2960        __(pop %save2)
2961        __(pop %save1)
2962        __(pop %save0)
2963        __(testl %imm0_l,%imm0_l)
2964        __(je local_label(keys_ok)) 
2965        __(btl $aok_bit,%nargs_l)
2966        __(jnc local_label(badkeys))
2967local_label(keys_ok):   
2968        __(jmp *%ra0)
2969        /* Some unrecognized keywords.  Complain generically about   */
2970        /* invalid keywords.   */
2971local_label(badkeys):
2972        __(movq $XBADKEYS,%arg_y)
2973        __(jmp local_label(destructure_error))
2974local_label(toomany):
2975        __(movq $XCALLTOOMANY,%arg_y)
2976        __(jmp local_label(destructure_error))
2977local_label(toofew):
2978        __(movq $XCALLTOOFEW,%arg_y)
2979        __(jmp local_label(destructure_error))
2980local_label(badlist):
2981        __(movq $XCALLNOMATCH,%arg_y)
2982        /* jmp local_label(destructure_error)   */
2983local_label(destructure_error):
2984        __(movd %mm0,%rsp)              /* undo everything done to the stack   */
2985        __(movq %whole_reg,%arg_z)
2986        __(set_nargs(2))
2987        __(push %ra0)
2988        __(jmp _SPksignalerr)
2989_endfn(C(destbind1))   
2990
2991_spentry(macro_bind)
2992        __(movq %arg_reg,%whole_reg)
2993        __(extract_lisptag(%arg_reg,%imm0))
2994        __(cmpb $tag_list,%imm0_b)
2995        __(jne 1f)
2996        __(_cdr(%arg_reg,%arg_reg))
2997        __(jmp C(destbind1))
29981:      __(movq $XCALLNOMATCH,%arg_y)
2999        __(movq %whole_reg,%arg_z)
3000        __(set_nargs(2))
3001        __(push %ra0)       
3002        __(jmp _SPksignalerr)
3003_endsubp(macro_bind)
3004
3005_spentry(destructuring_bind)
3006        __(movq %arg_reg,%whole_reg)
3007        __(jmp C(destbind1))
3008_endsubp(destructuring_bind)
3009
3010_spentry(destructuring_bind_inner)
3011        __(movq %arg_z,%whole_reg)
3012        __(jmp C(destbind1))
3013_endsubp(destructuring_bind_inner)
3014
3015       
3016
3017
3018_spentry(vpopargregs)
3019_endsubp(vpopargregs)
3020
3021/* If arg_z is an integer, return in imm0 something whose sign  */
3022/* is the same as arg_z's.  If not an integer, error.   */
3023_spentry(integer_sign)
3024        __(testb $tagmask,%arg_z_b)
3025        __(movq %arg_z,%imm0)
3026        __(je 8f)
3027        __(extract_typecode(%arg_z,%imm0))
3028        __(cmpb $subtag_bignum,%imm0_b)
3029        __(jne 9f)
3030        __(getvheader(%arg_z,%imm0))
3031        __(shr $num_subtag_bits,%imm0)
3032        __(movslq misc_data_offset-4(%arg_z,%imm0,4),%imm0)
30338:      __(repret)
30349:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3035_endsubp(integer_sign)
3036
3037/* "slide" nargs worth of values up the stack.  IMM0 contains   */
3038/* the difference between the current RSP and the target.   */
3039_spentry(mvslide)
3040        __(movzwl %nargs,%nargs_l)
3041        __(movl %nargs_l,%imm1_l)
3042        __(lea (%rsp,%nargs_q),%temp0)
3043        __(testq %imm1,%imm1)
3044        __(lea (%temp0,%imm0),%imm0)
3045        __(je 2f)
30461:     
3047        __(subq $node_size,%temp0)
3048        __(movq (%temp0),%temp1)
3049        __(subq $node_size,%imm0)
3050        __(movq %temp1,(%imm0))
3051        __(subq $node_size,%imm1)
3052        __(jne 1b)
30532:      __(movq %imm0,%rsp)
3054        __(jmp *%ra0)   
3055_endsubp(mvslide)
3056
3057_spentry(save_values)
3058        __(movq %rcontext:tcr.save_tsp,%imm1)
3059/* common exit: nargs = values in this set, imm1 = ptr to tsp before call to save_values   */
3060local_label(save_values_to_tsp):
3061        __(movzwl %nargs,%nargs_l)
3062        __(movq %rcontext:tcr.save_tsp,%arg_x)
3063        __(dnode_align(%nargs_q,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3064        __(TSP_Alloc_Var(%imm0,%arg_z))
3065        __(movq %rcontext:tcr.save_tsp,%imm0)
3066        __(movq %imm1,(%imm0))
3067        __(movq %nargs_q,(%arg_z))
3068        __(movq %arg_x,node_size(%arg_z))
3069        __(leaq 2*node_size(%arg_z,%nargs_q),%arg_y)
3070        __(leaq (%rsp,%nargs_q),%imm0)
3071        __(cmpq %imm0,%rsp)
3072        __(jmp 2f)
30731:      __(subq $node_size,%imm0)
3074        __(movq (%imm0),%arg_z)
3075        __(subq $node_size,%arg_y)
3076        __(cmpq %imm0,%rsp)
3077        __(movq %arg_z,(%arg_y))
30782:      __(jne 1b)
3079        __(add %nargs_q,%rsp)
3080        __(jmp *%ra0)                   
3081_endsubp(save_values)
3082
3083/* Add the multiple values that are on top of the vstack to the set  */
3084/* saved in the top tsp frame, popping them off of the vstack in the  */
3085/* process.  It is an error (a bad one) if the TSP contains something  */
3086/* other than a previously saved set of multiple-values.  */
3087/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3088/* each add_values call adds another linked element to the list of  */
3089/* values. This makes recover_values harder.   */
3090_spentry(add_values)
3091        __(testw %nargs,%nargs)
3092        __(movq %rcontext:tcr.save_tsp,%imm1)
3093        __(movq (%imm1),%imm1)
3094        __(jne local_label(save_values_to_tsp))
3095        __(jmp *%ra0)
3096_endsubp(add_values)
3097
3098/* push the values in the value set atop the sp, incrementing nargs.  */
3099/* Discard the tsp frame; leave values atop the sp.   */
3100       
3101_spentry(recover_values)
3102        /* First, walk the segments reversing the pointer to previous  */
3103        /* segment pointers Can tell the end because that previous  */
3104        /* segment pointer is the prev tsp pointer   */
3105        __(movq %rcontext:tcr.save_tsp,%temp1)
3106        __(movq %temp1,%arg_x)  /* current segment   */
3107        __(movq %temp1,%arg_y)  /* last segment   */
3108        __(movq tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3109local_label(walkloop):
3110        __(movq tsp_frame.fixed_overhead+node_size(%arg_x),%temp0)
3111        __(cmpq %temp0,%arg_z)  /* last segment ?   */
3112        __(movq %arg_y,tsp_frame.fixed_overhead+node_size(%arg_x))
3113        __(movq %arg_x,%arg_y)  /* last segment <- current segment   */
3114        __(movq %temp0,%arg_x)  /* current segment <- next segment   */
3115        __(jne local_label(walkloop))
3116
3117        __(movzwl %nargs,%nargs_l)
3118        /* the final segment pointer is now in %arg_y  */
3119        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3120local_label(pushloop):
3121        __(movq tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3122        __(testq %imm0,%imm0)
3123        __(leaq tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3124        __(leaq (%nargs_q,%imm0),%nargs_q)
3125        __(jmp 2f)
31261:      __(pushq -node_size(%temp0))
3127        __(subq $node_size,%temp0)
3128        __(subq $fixnum_one,%imm0)
31292:      __(jne 1b)
3130        __(cmpq %arg_y,%temp1)
3131        __(movq tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3132        __(jne local_label(pushloop))
3133        __(movq (%temp1),%temp1)
3134        __(movq %temp1,%rcontext:tcr.save_tsp)
3135        __(movq %temp1,%rcontext:tcr.next_tsp)       
3136        __(jmp *%ra0)           
3137_endsubp(recover_values)
3138
3139/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3140/* frame if any values (which will be used as outgoing arguments) will  */
3141/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3142/* that no other arguments have been pushed) on entry.   */
3143               
3144_spentry(recover_values_for_mvcall)
3145        /* First, walk the segments reversing the pointer to previous  */
3146        /* segment pointers Can tell the end because that previous  */
3147        /* segment pointer is the prev tsp pointer   */
3148        __(xorl %nargs_l,%nargs_l)
3149        __(movq %rcontext:tcr.save_tsp,%temp1)
3150        __(movq %temp1,%arg_x)  /* current segment   */
3151        __(movq %temp1,%arg_y)  /* last segment   */
3152        __(movq tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3153local_label(walkloop_mvcall):
3154        __(movq tsp_frame.fixed_overhead+node_size(%arg_x),%temp0)
3155        __(addq tsp_frame.data_offset(%arg_x),%nargs_q)
3156        __(cmpq %temp0,%arg_z)  /* last segment ?   */
3157        __(movq %arg_y,tsp_frame.fixed_overhead+node_size(%arg_x))
3158        __(movq %arg_x,%arg_y)  /* last segment <- current segment   */
3159        __(movq %temp0,%arg_x)  /* current segment <- next segment   */
3160        __(jne local_label(walkloop_mvcall))
3161
3162        __(cmpw $nargregs*node_size,%nargs)
3163        __(jbe local_label(pushloop_mvcall))
3164        __(push $reserved_frame_marker)
3165        __(push $reserved_frame_marker)
3166
3167        /* the final segment pointer is now in %arg_y  */
3168        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3169local_label(pushloop_mvcall):
3170        __(movq tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3171        __(testq %imm0,%imm0)
3172        __(leaq tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3173        __(jmp 2f)
31741:      __(pushq -node_size(%temp0))
3175        __(subq $node_size,%temp0)
3176        __(subq $fixnum_one,%imm0)
31772:      __(jne 1b)
3178        __(cmpq %arg_y,%temp1)
3179        __(movq tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3180        __(jne local_label(pushloop_mvcall))
3181        __(movq (%temp1),%temp1)
3182        __(movq %temp1,%rcontext:tcr.save_tsp)
3183        __(movq %temp1,%rcontext:tcr.next_tsp)       
3184        __(jmp *%ra0)           
3185_endsubp(recover_values_for_mvcall)
3186                                       
3187_spentry(reset)
3188        __(int $3)
3189_endsubp(reset)
3190
3191
3192
3193_spentry(misc_alloc_init)
3194        __(push %rbp)
3195        __(movq %rsp,%rbp)
3196        __(push %arg_z)
3197        __(movq %arg_y,%arg_z)
3198        __(movq %arg_x,%arg_y)
3199        __(lea local_label(misc_alloc_init_back)(%rip),%ra0)
3200        __(push %ra0)
3201        __(jmp _SPmisc_alloc)
3202__(tra(local_label(misc_alloc_init_back)))
3203        __(pop %arg_y)
3204        __(leave)
3205        __(movq $nrs.init_misc,%fname)
3206        __(set_nargs(2))
3207        __(jump_fname())       
3208_endsubp(misc_alloc_init)
3209
3210_spentry(stack_misc_alloc_init)
3211        __(push %rbp)
3212        __(movq %rsp,%rbp)
3213        __(push %arg_z)
3214        __(movq %arg_y,%arg_z)
3215        __(movq %arg_x,%arg_y)
3216        __(lea local_label(stack_misc_alloc_init_back)(%rip),%ra0)
3217        __(push %ra0)
3218        __(jmp _SPstack_misc_alloc)
3219__(tra(local_label(stack_misc_alloc_init_back)))
3220        __(pop %arg_y)
3221        __(leave)
3222        __(movq $nrs.init_misc,%fname)
3223        __(set_nargs(2))
3224        __(jump_fname())       
3225_endsubp(stack_misc_alloc_init)
3226
3227
3228
3229        .globl C(popj)
3230_spentry(popj)
3231C(popj):
3232        __(leave)
3233        __(ret)
3234_endsubp(popj)
3235
3236
3237
3238_spentry(getu64)
3239        __(movq $~(target_most_positive_fixnum << fixnumshift),%imm0)
3240        __(testq %arg_z,%imm0)
3241        __(movq %arg_z,%imm0)
3242        __(jne 1f)
3243        __(sarq $fixnumshift,%imm0)
3244        __(ret)
32451:      __(andb $tagmask,%imm0_b)
3246        __(cmpb $tag_misc,%imm0_b)
3247        __(jne 9f)
3248        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3249        __(cmpb $subtag_bignum,%imm0_b)
3250        __(jne 9f)
3251        __(movq misc_header_offset(%arg_z),%imm0)
3252        __(cmpq $three_digit_bignum_header,%imm0)
3253        __(je 3f)
3254        __(cmpq $two_digit_bignum_header,%imm0)
3255        __(jne 9f)
3256        __(movq misc_data_offset(%arg_z),%imm0)
3257        __(testq %imm0,%imm0)
3258        __(js 9f)
3259        __(repret)
32603:      __(movq misc_data_offset(%arg_z),%imm0)
3261        __(cmpl $0,misc_data_offset+8(%arg_z))
3262        __(jne 9f)
3263        __(repret)
32649:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3265_endsubp(getu64)
3266
3267_spentry(gets64)
3268        __(movq %arg_z,%imm0)
3269        __(sarq $fixnumshift,%imm0)
3270        __(testb $fixnummask,%arg_z_b)
3271        __(je 8f)
32721:      __(movb %arg_z_b,%imm0_b)
3273        __(andb $tagmask,%imm0_b)
3274        __(cmpb $tag_misc,%imm0_b)
3275        __(jne 9f)
3276        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3277        __(cmpb $subtag_bignum,%imm0_b)
3278        __(jne 9f)
3279        __(movq misc_header_offset(%arg_z),%imm0)
3280        __(cmpq $two_digit_bignum_header,%imm0)
3281        __(movq misc_data_offset(%arg_z),%imm0)
3282        __(jne 9f)
32838:      __(repret)
32849:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3285_endsubp(gets64)
3286
3287_spentry(makeu64)
3288        __(movq %imm0,%imm1)
3289        __(shlq $fixnumshift+1,%imm1)
3290        __(movq %imm1,%arg_z)   /* Tagged as a fixnum, 2x    */
3291        __(shrq $fixnumshift+1,%imm1)
3292        __(shrq %arg_z)
3293        __(cmpq %imm0,%imm1)
3294        __(je 9f)
3295        __(testq %imm0,%imm0)
3296        __(movd %imm0,%mm0)
3297        __(js 3f)
3298        /* Make a 2-digit bignum.   */
3299        __(movl $two_digit_bignum_header,%imm0_l)
3300        __(movl $aligned_bignum_size(2),%imm1_l)
3301        __(Misc_Alloc(%arg_z))
3302        __(movq %mm0,misc_data_offset(%arg_z))
3303        __(ret)
33043:      __(movl $three_digit_bignum_header,%imm0_l)
3305        __(movl $aligned_bignum_size(3),%imm1_l)
3306        __(Misc_Alloc(%arg_z))
3307        __(movq %mm0,misc_data_offset(%arg_z))
33089:      __(repret)
3309_endsubp(makeu64)
3310
3311/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly  */
3312/* unbound_marker), arg_y = symbol   */
3313_spentry(specref)
3314        __(movq symbol.binding_index(%arg_z),%imm0)
3315        __(cmp %rcontext:tcr.tlb_limit,%imm0)
3316        __(movq %rcontext:tcr.tlb_pointer,%imm1)
3317        __(movq %arg_z,%arg_y)
3318        __(jae 7f)
3319        __(movq (%imm1,%imm0),%arg_z)
3320        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3321        __(jne 8f)
33227:      __(movq symbol.vcell(%arg_y),%arg_z)
33238:      __(repret)             
3324_endsubp(specref)
3325
3326/* arg_y = special symbol, arg_z = new value.           */
3327_spentry(specset)
3328        __(movq symbol.binding_index(%arg_y),%imm0)
3329        __(cmp %rcontext:tcr.tlb_limit,%imm0)
3330        __(movq %rcontext:tcr.tlb_pointer,%imm1)
3331        __(jae 1f)
3332        __(movq (%imm1,%imm0),%arg_x)
3333        __(cmpb $no_thread_local_binding_marker,%arg_x_b)
3334        __(je 1f)
3335        __(movq %arg_z,(%imm1,%imm0))
3336        __(ret)
33371:      __(lea fulltag_misc-fulltag_symbol(%arg_y),%arg_x)
3338        __(movq $1<<fixnumshift,%arg_y)
3339        __(jmp _SPgvset)
3340_endsubp(specset)
3341
3342_spentry(specrefcheck)
3343        __(movq symbol.binding_index(%arg_z),%imm0)
3344        __(cmp %rcontext:tcr.tlb_limit,%imm0)
3345        __(movq %rcontext:tcr.tlb_pointer,%imm1)
3346        __(movq %arg_z,%arg_y)
3347        __(jae 7f)
3348        __(movq (%imm1,%imm0),%arg_z)
3349        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3350        __(jne 8f)
33517:      __(movq symbol.vcell(%arg_y),%arg_z)
33528:      __(cmpb $unbound_marker,%arg_z_b)
3353        __(jne,pt 9f)
3354        __(uuo_error_reg_unbound(Rarg_y))
33559:      __(repret)             
3356_endsubp(specrefcheck)
3357
3358_spentry(restoreintlevel)
3359_endsubp(restoreintlevel)
3360
3361_spentry(makes32)
3362        __(int $3)
3363_endsubp(makes32)
3364
3365_spentry(makeu32)
3366        __(int $3)
3367_endsubp(makeu32)
3368
3369_spentry(gets32)
3370        __(int $3)
3371_endsubp(gets32)
3372
3373_spentry(getu32)
3374        __(int $3)
3375_endsubp(getu32)
3376
3377
3378_spentry(mvpasssym)
3379_endsubp(mvpasssym)
3380
3381
3382_spentry(unbind)
3383        __(movq %rcontext:tcr.db_link,%imm1)
3384        __(movq %rcontext:tcr.tlb_pointer,%arg_x)
3385        __(movq binding.sym(%imm1),%temp1)
3386        __(movq binding.val(%imm1),%arg_y)
3387        __(movq binding.link(%imm1),%imm1)
3388        __(movq %arg_y,(%arg_x,%temp1))
3389        __(movq %imm1,%rcontext:tcr.db_link)
3390        __(ret) 
3391_endsubp(unbind)
3392
3393_spentry(unbind_n)
3394        __(movq %rcontext:tcr.db_link,%imm1)
3395        __(movq %rcontext:tcr.tlb_pointer,%arg_x)
33961:             
3397        __(movq binding.sym(%imm1),%temp1)
3398        __(movq binding.val(%imm1),%arg_y)
3399        __(movq binding.link(%imm1),%imm1)
3400        __(movq %arg_y,(%arg_x,%temp1))
3401        __(subq $1,%imm0)
3402        __(jne 1b)
3403        __(movq %imm1,%rcontext:tcr.db_link)
3404        __(ret) 
3405_endsubp(unbind_n)
3406
3407_spentry(unbind_to)
3408        __(movq %rcontext:tcr.db_link,%imm1)
3409        __(movq %rcontext:tcr.tlb_pointer,%arg_x)
34101:             
3411        __(movq binding.sym(%imm1),%temp1)
3412        __(movq binding.val(%imm1),%arg_y)
3413        __(movq binding.link(%imm1),%imm1)
3414        __(movq %arg_y,(%arg_x,%temp1))
3415        __(cmpq %imm1,%imm0)
3416        __(jne 1b)
3417        __(movq %imm1,%rcontext:tcr.db_link)
3418        __(ret)
3419_endsubp(unbind_to)
3420
3421
3422/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check   */
3423/* for pending interrupts after doing so.   */
3424       
3425_spentry(bind_interrupt_level_0)
3426        __(movq %rcontext:tcr.tlb_pointer,%temp1)
3427        __(cmpq $0,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3428        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3429        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3430        __(push %rcontext:tcr.db_link)
3431        __(movq %rsp,%rcontext:tcr.db_link)
3432        __(movq $0,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3433        __(js,pn 1f)
34340:      __(jmp *%ra0)
3435        /* Interrupt level was negative; interrupt may be pending   */
34361:      __(check_pending_enabled_interrupt(2f))
34372:      __(jmp *%ra0)
3438_endsubp(bind_interrupt_level_0)
3439       
3440
3441/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3442/* of disabling interrupts.)   */
3443
3444_spentry(bind_interrupt_level_m1)
3445        __(movq %rcontext:tcr.tlb_pointer,%temp1)
3446        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3447        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3448        __(push %rcontext:tcr.db_link)
3449        __(movq %rsp,%rcontext:tcr.db_link)
3450        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3451        __(jmp *%ra0)
3452_endsubp(bind_interrupt_level_m1)
3453
3454/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0,  */
3455/* do what _SPbind_interrupt_level_0 does   */
3456_spentry(bind_interrupt_level)
3457        __(testq %arg_z,%arg_z)
3458        __(movq %rcontext:tcr.tlb_pointer,%temp1)
3459        __(jz _SPbind_interrupt_level_0)
3460        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3461        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3462        __(push %rcontext:tcr.db_link)
3463        __(movq %rsp,%rcontext:tcr.db_link)
3464        __(movq %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3465        __(jmp *%ra0)
3466_endsubp(bind_interrupt_level)
3467
3468/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to  */
3469/* non-negative, check for pending interrupts.    */
3470       
3471_spentry(unbind_interrupt_level)
3472        __(btq $TCR_FLAG_BIT_PENDING_SUSPEND,%rcontext:tcr.flags)
3473        __(movq %rcontext:tcr.db_link,%imm1)
3474        __(movq %rcontext:tcr.tlb_pointer,%arg_x)
3475        __(movq INTERRUPT_LEVEL_BINDING_INDEX(%arg_x),%imm0)
3476        __(jc 5f)
34770:      __(testq %imm0,%imm0)
3478        __(movq binding.val(%imm1),%temp0)
3479        __(movq binding.link(%imm1),%imm1)
3480        __(movq %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
3481        __(movq %imm1,%rcontext:tcr.db_link)
3482        __(js,pn 3f)
34832:      __(repret)
34843:      __(testq %temp0,%temp0)
3485        __(js 2b)
3486        __(check_pending_enabled_interrupt(4f))
34874:      __(repret)
34885:       /* Missed a suspend request; force suspend now if we're restoring
3489          interrupt level to -1 or greater */
3490        __(cmpq $-2<<fixnumshift,%imm0)
3491        __(jne 0b)
3492        __(movq binding.val(%imm1),%temp0)
3493        __(cmpq %imm0,%temp0)
3494        __(je 0b)
3495        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
3496        __(suspend_now())
3497        __(jmp 0b)
3498_endsubp(unbind_interrupt_level)
3499
3500       
3501_spentry(progvrestore)
3502        __(movq %rcontext:tcr.save_tsp,%imm0)
3503        __(movq tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3504        __(movq tsp_frame.data_offset(%imm0),%imm0)
3505        __(shrq $fixnumshift,%imm0)
3506        __(jne _SPunbind_n)
3507        __(repret)
3508_endsubp(progvrestore)
3509       
3510
3511/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3512/* inline.  Call out otherwise.   */
3513_spentry(builtin_plus)
3514        __(movb %arg_z_b,%imm0_b)
3515        __(orb %arg_y_b,%imm0_b)
3516        __(testb $fixnummask,%imm0_b)
3517        __(jne 1f)
3518        __(addq %arg_y,%arg_z)
3519        __(jo,pn C(fix_one_bit_overflow))
3520        __(repret)
35211:      __(jump_builtin(_builtin_plus,2))
3522_endsubp(builtin_plus)
3523       
3524
3525/* %arg_z <- %arg_z - %arg_y.  Do the fixnum case - including overflow -  */
3526/*  inline.  Call out otherwise.   */
3527_spentry(builtin_minus)                 
3528        __(movb %arg_z_b,%imm0_b)
3529        __(orb %arg_y_b,%imm0_b)
3530        __(testb $fixnummask,%imm0_b)
3531        __(jne 1f)
3532        __(xchgq %arg_y,%arg_z)
3533        __(subq %arg_y,%arg_z)
3534        __(jo,pn C(fix_one_bit_overflow))
3535        __(repret)
35361:      __(jump_builtin(_builtin_minus,2))
3537_endsubp(builtin_minus)
3538
3539/* %arg_z <- %arg_z * %arg_y.  Do the fixnum case - including overflow -  */
3540/* inline.  Call out otherwise.   */
3541_spentry(builtin_times)
3542        __(movb %arg_z_b,%imm0_b)
3543        __(orb %arg_y_b,%imm0_b)
3544        __(testb $fixnummask,%imm0_b)
3545        __(jne 2f)
3546        __(unbox_fixnum(%arg_z,%imm0))
3547        /* 128-bit fixnum result in %imm1:%imm0. Overflow set if %imm1  */
3548        /* is significant   */
3549        __(imul %arg_y)
3550        __(jo 1f)
3551        __(mov %imm0,%arg_z)
3552        __(ret)
35531:      __(unbox_fixnum(%arg_z,%imm0))
3554        __(unbox_fixnum(%arg_y,%imm1))
3555        __(imul %imm1)
3556        __(jmp C(makes128))
35572:      __(jump_builtin(_builtin_times,2))
3558_endsubp(builtin_times)
3559
3560_spentry(builtin_div)
3561        __(jump_builtin(_builtin_div,2))
3562
3563/* %arg_z <- (= %arg_y %arg_z).   */
3564_spentry(builtin_eq)
3565        __(movb %arg_z_b,%imm0_b)
3566        __(orb %arg_y_b,%imm0_b)
3567        __(testb $fixnummask,%imm0_b)
3568        __(jne 1f)
3569        __(rcmpq(%arg_z,%arg_y))
3570        __(condition_to_boolean(e,%imm0,%arg_z))
3571        __(ret)
35721:      __(jump_builtin(_builtin_eq,2))
3573_endsubp(builtin_eq)
3574       
3575/* %arg_z <- (/= %arg_y %arg_z).          */
3576_spentry(builtin_ne)
3577        __(movb %arg_z_b,%imm0_b)
3578        __(orb %arg_y_b,%imm0_b)
3579        __(testb $fixnummask,%imm0_b)
3580        __(jne 1f)
3581        __(rcmpq(%arg_z,%arg_y))
3582        __(condition_to_boolean(ne,%imm0,%arg_z))
3583        __(ret)
35841:      __(jump_builtin(_builtin_ne,2))
3585_endsubp(builtin_ne)
3586       
3587/* %arg_z <- (> %arg_y %arg_z).   */
3588_spentry(builtin_gt)
3589        __(movb %arg_z_b,%imm0_b)
3590        __(orb %arg_y_b,%imm0_b)
3591        __(testb $fixnummask,%imm0_b)
3592        __(jne 1f)
3593        __(rcmpq(%arg_y,%arg_z))
3594        __(condition_to_boolean(g,%imm0,%arg_z))
3595        __(ret)
35961:      __(jump_builtin(_builtin_gt,2))
3597_endsubp(builtin_gt)
3598
3599/* %arg_z <- (>= %arg_y %arg_z).          */
3600_spentry(builtin_ge)
3601        __(movb %arg_z_b,%imm0_b)
3602        __(orb %arg_y_b,%imm0_b)
3603        __(testb $fixnummask,%imm0_b)
3604        __(jne 1f)
3605        __(rcmpq(%arg_y,%arg_z))
3606        __(condition_to_boolean(ge,%imm0,%arg_z))
3607        __(ret)
36081:      __(jump_builtin(_builtin_ge,2))
3609_endsubp(builtin_ge)
3610       
3611/* %arg_z <- (< %arg_y %arg_z).   */
3612_spentry(builtin_lt)
3613        __(movb %arg_z_b,%imm0_b)
3614        __(orb %arg_y_b,%imm0_b)
3615        __(testb $fixnummask,%imm0_b)
3616        __(jne 1f)
3617        __(rcmpq(%arg_y,%arg_z))
3618        __(condition_to_boolean(l,%imm0,%arg_z))
3619        __(ret)
36201:      __(jump_builtin(_builtin_lt,2))
3621_endsubp(builtin_lt)
3622
3623/* %arg_z <- (<= %arg_y %arg_z).   */
3624_spentry(builtin_le)
3625        __(movb %arg_z_b,%imm0_b)
3626        __(orb %arg_y_b,%imm0_b)
3627        __(testb $fixnummask,%imm0_b)
3628        __(jne 1f)
3629        __(rcmpq(%arg_y,%arg_z))
3630        __(condition_to_boolean(le,%imm0,%arg_z))
3631        __(ret)
36321:      __(jump_builtin(_builtin_le,2))
3633_endsubp(builtin_le)
3634
3635_spentry(builtin_eql)
3636        __(cmpq %arg_y,%arg_z)
3637        __(je 1f)
3638        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3639        /* and both have the same subtag   */
3640        __(extract_lisptag(%arg_y,%imm0))
3641        __(extract_lisptag(%arg_z,%imm1))
3642        __(cmpb $tag_misc,%imm0_b)
3643        __(jne 2f)
3644        __(cmpb %imm0_b,%imm1_b)
3645        __(jne 2f)
3646        __(extract_subtag(%arg_y,%imm0_b))
3647        __(extract_subtag(%arg_z,%imm1_b))
3648        __(cmpb %imm0_b,%imm1_b)
3649        __(jne 2f)
3650        __(jump_builtin(_builtin_eql,2))
36511:      __(movl $t_value,%arg_z_l)
3652        __(ret)
36532:      __(movl $nil_value,%arg_z_l)
3654        __(ret) 
3655_endsubp(builtin_eql)
3656
3657_spentry(builtin_length)
3658        __(extract_lisptag(%arg_z,%imm0))
3659        __(cmpb $tag_list,%imm0_b)
3660        __(jz 2f)
3661        __(cmpb $tag_misc,%imm0_b)
3662        __(jnz 8f)
3663        __(extract_subtag(%arg_z,%imm0_b))
3664        __(rcmpb(%imm0_b,$min_vector_subtag))
3665        __(jb 8f)
3666        __(je 1f)
3667        /* (simple-array * (*))   */
3668        __(movq %arg_z,%arg_y)
3669        __(vector_length(%arg_y,%arg_z))
3670        __(ret)
36711:      /* vector header   */
3672        __(movq vectorH.logsize(%arg_z),%arg_z)
3673        __(ret)
36742:      /* list.  Maybe null, maybe dotted or circular.   */
3675        __(movq $-fixnumone,%imm2)
3676        __(movq %arg_z,%temp0)  /* fast pointer   */
3677        __(movq %arg_z,%temp1)  /* slow pointer   */
36783:      __(extract_lisptag(%temp0,%imm0))       
3679        __(compare_reg_to_nil(%temp0))
3680        __(leaq fixnumone(%imm2),%imm2)
3681        __(je 9f)
3682        __(cmpb $tag_list,%imm0_b)
3683        __(jne 8f)
3684        __(extract_lisptag(%temp1,%imm1))
3685        __(testb $fixnumone,%imm2_b)
3686        __(_cdr(%temp0,%temp0))
3687        __(je 3b)
3688        __(cmpb $tag_list,%imm1_b)
3689        __(jne 8f)
3690        __(_cdr(%temp1,%temp1))
3691        __(cmpq %temp0,%temp1)
3692        __(jne 3b)
36938:     
3694        __(jump_builtin(_builtin_length,1))
36959:     
3696        __(movq %imm2,%arg_z)
3697        __(ret)         
3698_endsubp(builtin_length)
3699
3700       
3701_spentry(builtin_seqtype)
3702        __(extract_lisptag(%arg_z,%imm0))
3703        __(cmpb $tag_list,%imm0_b)
3704        __(jz 1f)
3705        __(cmpb $tag_misc,%imm0_b)
3706        __(jne 2f)
3707        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3708        __(rcmpb(%imm0_b,$min_vector_subtag))
3709        __(jb 2f)
3710        __(movl $nil_value,%arg_z_l)
3711        __(ret)
37121:      __(movl $t_value,%arg_z_l)
3713        __(ret)
37142:     
3715        __(jump_builtin(_builtin_seqtype,1))
3716_endsubp(builtin_seqtype)
3717
3718_spentry(builtin_assq)
3719        __(cmpb $fulltag_nil,%arg_z_b)
3720        __(jz 5f)
37211:      __(movb $tagmask,%imm0_b)
3722        __(andb %arg_z_b,%imm0_b)
3723        __(cmpb $tag_list,%imm0_b)
3724        __(jz,pt 2f)
3725        __(uuo_error_reg_not_list(Rarg_z))
37262:      __(_car(%arg_z,%arg_x))
3727        __(_cdr(%arg_z,%arg_z))
3728        __(cmpb $fulltag_nil,%arg_x_b)
3729        __(jz 4f)
3730        __(movb $tagmask,%imm0_b)
3731        __(andb %arg_x_b,%imm0_b)
3732        __(cmpb $tag_list,%imm0_b)
3733        __(jz,pt 3f)
3734        __(uuo_error_reg_not_list(Rarg_x))
37353:      __(_car(%arg_x,%temp0))
3736        __(cmpq %temp0,%arg_y)
3737        __(jnz 4f)
3738        __(movq %arg_x,%arg_z)
3739        __(ret)
37404:      __(cmpb $fulltag_nil,%arg_z_b)
37415:      __(jnz 1b)
3742        __(repret)                     
3743_endsubp(builtin_assq) 
3744
3745_spentry(builtin_memq)
3746        __(cmpb $fulltag_nil,%arg_z_b)
3747        __(jmp 3f)
37481:      __(movb $tagmask,%imm0_b)
3749        __(andb %arg_z_b,%imm0_b)
3750        __(cmpb $tag_list,%imm0_b)
3751        __(jz,pt 2f)
3752        __(uuo_error_reg_not_list(Rarg_z))
37532:      __(_car(%arg_z,%arg_x))
3754        __(_cdr(%arg_z,%temp0))
3755        __(cmpq %arg_x,%arg_y)
3756        __(jz 4f)
3757        __(cmpb $fulltag_nil,%temp0_b)
3758        __(movq %temp0,%arg_z)
37593:      __(jnz 1b)
37604:      __(repret)                             
3761_endsubp(builtin_memq)
3762
3763        __ifdef([X8664])
3764logbitp_max_bit = 61
3765        __else
3766logbitp_max_bit = 30
3767        __endif
3768       
3769_spentry(builtin_logbitp)
3770        __(movb %arg_z_b,%imm0_b)
3771        __(orb %arg_y_b,%imm0_b)
3772        __(testb $fixnummask,%imm0_b)
3773        __(jnz 1f)
3774        __(unbox_fixnum(%arg_y,%imm0))
3775        __(movl $logbitp_max_bit-1+fixnumshift,%imm1_l)
3776        __(js 1f)               /* bit number negative */
3777        __(addb $fixnumshift,%imm0_b)
3778        __(cmpq $logbitp_max_bit<<fixnumshift,%arg_y)
3779        __(cmovael %imm1_l,%imm0_l)
3780        __(bt %imm0,%arg_z)
3781        __(condition_to_boolean(b,%imm0,%arg_z))
3782        __(ret)
37831:      __(jump_builtin(_builtin_logbitp,2))
3784_endsubp(builtin_logbitp)
3785
3786_spentry(builtin_logior)
3787        __(movb %arg_y_b,%imm0_b)
3788        __(orb %arg_z_b,%imm0_b)
3789        __(testb $fixnummask,%imm0_b)
3790        __(jne 1f)
3791        __(orq %arg_y,%arg_z)
3792        __(ret)
37931:     
3794        __(jump_builtin(_builtin_logior,2))
3795               
3796_endsubp(builtin_logior)
3797
3798_spentry(builtin_logand)
3799        __(movb %arg_y_b,%imm0_b)
3800        __(orb %arg_z_b,%imm0_b)
3801        __(testb $fixnummask,%imm0_b)
3802        __(jne 1f)
3803        __(andq %arg_y,%arg_z)
3804        __(ret)
38051:             
3806        __(jump_builtin(_builtin_logand,2))
3807_endsubp(builtin_logand)
3808
3809_spentry(builtin_negate)
3810        __(testb $fixnummask,%arg_z_b)
3811        __(jne 1f)
3812        __(negq %arg_z)
3813        __(jo,pn C(fix_one_bit_overflow))
3814        __(repret)
38151:             
3816        __(jump_builtin(_builtin_negate,1))     
3817_endsubp(builtin_negate)
3818
3819_spentry(builtin_logxor)
3820        __(movb %arg_y_b,%imm0_b)
3821        __(orb %arg_z_b,%imm0_b)
3822        __(testb $fixnummask,%imm0_b)
3823        __(jne 1f)
3824        __(xorq %arg_y,%arg_z)
3825        __(ret)
38261:             
3827        __(jump_builtin(_builtin_logxor,2))
3828_endsubp(builtin_logxor)
3829
3830
3831_spentry(builtin_aset1)
3832        __(extract_typecode(%arg_x,%imm0))
3833        __(box_fixnum(%imm0,%temp0))
3834        __(cmpb $min_vector_subtag,%imm0_b)
3835        __(ja _SPsubtag_misc_set)
3836        __(jump_builtin(_builtin_aset1,3))
3837_endsubp(builtin_aset1)
3838
3839
3840_spentry(builtin_ash)
3841        __(movb %arg_y_b,%imm0_b)
3842        __(orb %arg_z_b,%imm0_b)
3843        __(testb $fixnummask,%imm0_b)
3844        __(jne 9f)
3845        __(unbox_fixnum(%arg_y,%imm1))
3846        __(unbox_fixnum(%arg_z,%imm0))
3847        /* Z flag set if zero ASH shift count   */
3848        __(jnz 1f)
3849        __(movq %arg_y,%arg_z)  /* shift by 0   */
3850        __(ret)
38511:      __(jns 3f)
3852        __(rcmpq(%imm0,$-63))
3853        __(jg 2f)
3854        __(sar $63,%imm1)
3855        __(box_fixnum(%imm1,%arg_z))
3856        __(ret)
38572:      /* Right-shift by small fixnum   */
3858        __(negb %imm0_b)
3859        __(movzbl %imm0_b,%ecx)
3860        __(sar %cl,%imm1)
3861        __(box_fixnum(%imm1,%arg_z))
3862        __(ret)
38633:      /* Left shift by fixnum. We cant shift by more than 63 bits, though  */
3864        /* shifting by 64 is actually easy.   */
3865        __(rcmpq(%imm0,$64))
3866        __(jg 9f)
3867        __(jne 4f)
3868        /* left-shift by 64-bits exactly   */
3869        __(xorl %imm0_l,%imm0_l)
3870        __(jmp C(makes128))
38714:      /* left-shift by 1..63 bits.  Safe to move shift count to %rcx/%cl   */
3872        __(movzbl %imm0_b,%ecx)  /* zero-extending mov   */
3873        __(movq %imm1,%imm0)
3874        __(sarq $63,%imm1)
3875        __(js 5f)
3876        __(shld %cl,%imm0,%imm1)
3877        __(shl %cl,%imm0)
3878        __(jmp C(makes128))
38795:      __(shld %cl,%imm0,%imm1)
3880        __(shl %cl,%imm0)
3881        __(jmp C(makes128))
38829:     
3883        __(jump_builtin(_builtin_ash,2))
3884_endsubp(builtin_ash)
3885
3886_spentry(builtin_aref1)
3887        __(extract_typecode(%arg_y,%imm0))
3888        __(cmpb $min_vector_subtag,%imm0_b)
3889        __(box_fixnum_no_flags(%imm0,%arg_x))
3890        __(ja _SPsubtag_misc_ref)
3891        __(jump_builtin(_builtin_aref1,2))
3892_endsubp(builtin_aref1)
3893
3894/* Arg_z is either a MACPTR containing the function address or a boxed fixnum.  */
3895/*   %imm0.b (aka %al) contains the number (0-7) of args passed in FP regs.  */
3896/*   On entry, the foreign stack contains a frame containing at least 8 words:  */
3897
3898/*   * -> aligned on 16-byte boundary  */
3899/*  *backlink   <-      foreign %rsp              */
3900/*   unused  */
3901/*   scalar arg 0               passed in %rdi  */
3902/*   scalar arg 1         passed in %rsi  */
3903/*   scalar arg 2               passed in %rdx  */
3904/*   scalar arg 3               passed in %rcx  */
3905/*   scalar arg 4               passed in %r8  */
3906/*   scalar arg 5               passed in %r9  */
3907/*  *address of first memory arg  */
3908/*   ...  */
3909/*   possible scratch space  */
3910/*  *previous %rsp value  */
3911
3912/*   Any floating-point args will have been loaded into %xmm0-%xmm7 by the caller.  */
3913/*   When this returns, the foreign %rsp will contain its previous value, and  */
3914/*   the function result will be in %rax (and possibly %rdx) or %xmm0 (+ %xmm1).  */
3915
3916_spentry(ffcall)
3917LocalLabelPrefix[]ffcall:               
3918        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
3919          if not a fixnum, get the first word */
3920        __(unbox_fixnum(%arg_z,%imm1))
3921        __(testb $fixnummask,%arg_z_b)
3922        __(je 0f)
3923        __(movq macptr.address(%arg_z),%imm1)
39240:             
3925        /* Save lisp registers   */
3926        __(push %rbp)
3927        __(movq %rsp,%rbp)
3928        __(push %temp0)
3929        __(push %temp1)
3930        __(push %temp2)
3931        __(push %arg_x)
3932        __(push %arg_y)
3933        __(push %arg_z)
3934        __(push %fn)
3935        __(push %save0)
3936        __(push %save1)
3937        __(push %save2)
3938        __(push %save3)         /* 10 registers pushed after %rbp */
3939        __(movq %rsp,%rcontext:tcr.save_vsp)
3940        __(movq %rbp,%rcontext:tcr.save_rbp)
3941        __(movq $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
3942        __(movq %rcontext:tcr.foreign_sp,%rsp)
3943        __(stmxcsr %rcontext:tcr.lisp_mxcsr)
3944        __(emms)
3945        __(ldmxcsr %rcontext:tcr.foreign_mxcsr)
3946        __(movq (%rsp),%rbp)
3947        __ifdef([DARWIN_GS_HACK])
3948         /* At this point, %imm1=%rdx is live (contains
3949            the entrypoint) and %imm0.b=%al contains
3950            info about xmm register arguments; the lisp registers are
3951            all saved, and the foreign arguments are
3952            on the foreign stack (about to be popped
3953            off).  Save the linear TCR address in %save0/%r15
3954            so that we can restore it later, and preserve
3955            the entrypoint somewhere where C won't bash it.
3956            Note that dereferencing the entrypoint from
3957            foreign code has never been safe (unless it's
3958            a fixnum */
3959         __(save_tcr_linear(%save0))
3960         __(movq %imm1,%save1)
3961         __(movq %imm0,%save2)
3962         __(set_foreign_gs_base())
3963         __(movq %save1,%imm1)
3964         __(movq %save2,%imm0)
3965        __endif
3966LocalLabelPrefix[]ffcall_setup:
3967        __(addq $2*node_size,%rsp)
3968        __(movq %imm1,%r11)
3969        __(pop %rdi)
3970        __(pop %rsi)
3971        __(pop %rdx)
3972        __(pop %rcx)
3973        __(pop %r8)
3974        __(pop %r9)
3975LocalLabelPrefix[]ffcall_setup_end: 
3976LocalLabelPrefix[]ffcall_call:
3977        __(call *%r11)
3978LocalLabelPrefix[]ffcall_call_end:               
3979        __(movq %rbp,%rsp)
3980        __ifdef([DARWIN_GS_HACK])
3981         /* %rax/%rdx contains the return value (maybe), %save0 still
3982            contains the linear tcr address.  Preserve %rax/%rdx here. */
3983         __(movq %rax,%save1)
3984         __(movq %rdx,%save2)
3985         __(set_gs_base(%save0))
3986         __(movq %save1,%rax)
3987         __(movq %save2,%rdx)
3988        __endif
3989        __(movq %rsp,%rcontext:tcr.foreign_sp)       
3990        __(clr %save3)
3991        __(clr %save2)
3992        __(clr %save1)
3993        __(clr %save0)
3994        __(clr %arg_z)
3995        __(clr %arg_y)
3996        __(clr %arg_x)
3997        __(clr %temp2)
3998        __(clr %temp1)
3999        __(clr %temp0)
4000        __(clr %fn)
4001        __(pxor %fpzero,%fpzero)
4002        /* Darwin's math library seems to be pretty casual
4003           about causing spurious FP exceptions */
4004        __ifdef([DARWIN])
4005         __(movl %arg_x_l,%rcontext:tcr.ffi_exception)
4006        __else
4007         __(stmxcsr %rcontext:tcr.ffi_exception)
4008        __endif
4009        __(movq %rcontext:tcr.save_vsp,%rsp)
4010        __(movq %rcontext:tcr.save_rbp,%rbp)
4011        __(movq $TCR_STATE_LISP,%rcontext:tcr.valence)
4012        __(pop %save3)
4013        __(pop %save2)
4014        __(pop %save1)
4015        __(pop %save0)
4016        __(pop %fn)
4017        __(pop %arg_z)
4018        __(pop %arg_y)
4019        __(pop %arg_x)
4020        __(pop %temp2)
4021        __(pop %temp1)
4022        __(ldmxcsr %rcontext:tcr.lisp_mxcsr)
4023        __(check_pending_interrupt(%temp0))
4024        __(pop %temp0)
4025        __(leave)
4026        __ifdef([DARWIN])
4027        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,%rcontext:tcr.flags)
4028        __(jc,pn 0f)
4029        __endif
4030        __(ret)
4031        __ifdef([DARWIN])
40320:
4033        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4034        /* Box it, then signal a lisp error. */
4035        __(movq %imm0,%imm2)
4036        __(movq $macptr_header,%rax)
4037        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4038        __(movq %imm2,macptr.address(%arg_z))
4039        __(movq $XFOREIGNEXCEPTION,%arg_y)
4040        __(set_nargs(2))
4041        __(jmp _SPksignalerr)
4042        __endif
4043        __ifdef([DARWIN])       
4044        /* Handle exceptions, for ObjC 2.0 */
4045LocalLabelPrefix[]ffcallLandingPad:     
4046        __(movq %rax,%save1)
4047        __(cmpq $1,%rdx)
4048        __(je 1f)
4049        __(movq %rax,%rdi)
4050LocalLabelPrefix[]ffcallUnwindResume:           
4051        __(call *lisp_global(unwind_resume))
4052LocalLabelPrefix[]ffcallUnwindResume_end:         
40531:      __(movq %save1,%rdi)
4054LocalLabelPrefix[]ffcallBeginCatch:             
4055        __(call *lisp_global(objc2_begin_catch))
4056LocalLabelPrefix[]ffcallBeginCatch_end:         
4057        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4058LocalLabelPrefix[]ffcallEndCatch:               
4059        __(call *lisp_global(objc2_end_catch))
4060LocalLabelPrefix[]ffcallEndCatch_end:           
4061        __(ref_global(get_tcr,%rax))
4062        __(movq $1,%rdi)
4063        __(call *%rax)
4064        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4065        __(movq %save1,%rax)
4066        __(jmp LocalLabelPrefix[]ffcall_call_end)
4067LocalLabelPrefix[]ffcall_end:   
4068        __endif
4069_endsubp(ffcall)
4070
4071        __ifdef([DARWIN])
4072        .section __DATA,__gcc_except_tab
4073GCC_except_table0:
4074        .align 3
4075LLSDA1:
4076        .byte   0xff    /* @LPStart format (omit) */
4077        .byte   0x0     /* @TType format (absolute) */
4078        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4079        .byte   0x3     /* call-site format (udata4) */
4080        .byte   0x41    /* uleb128 0x41; Call-site table length */
4081       
4082        .long Lffcall_setup-Lffcall     /* region 0 start */
4083        .long Lffcall_setup_end-Lffcall_setup   /* length */
4084        .long   0x0     /* landing pad */
4085        .byte   0x0     /* uleb128 0x0; action */
4086       
4087        .long Lffcall_call-Lffcall      /* region 1 start */
4088        .long Lffcall_call_end-Lffcall_call     /* length */
4089        .long LffcallLandingPad-Lffcall /* landing pad */
4090        .byte   0x1     /* uleb128 0x1; action */
4091       
4092        .long LffcallUnwindResume-Lffcall       /* region 2 start */
4093        .long LffcallUnwindResume_end-LffcallUnwindResume       /* length */
4094        .long   0x0     /* landing pad */
4095        .byte   0x0     /* uleb128 0x0; action */
4096       
4097        .long LffcallBeginCatch-Lffcall /* region 3 start */
4098        .long LffcallBeginCatch_end-LffcallBeginCatch   /* length */
4099        .long 0 /* landing pad */
4100        .byte   0x0     /* uleb128 0x0; action */
4101       
4102        .long LffcallEndCatch-Lffcall
4103        .long LffcallEndCatch_end-LffcallEndCatch       /* length */
4104        .long   0x0     /* landing pad */
4105        .byte   0x0     /* uleb128 0x0; action */
4106        .byte   0x1     /* Action record table */
4107        .byte   0x0
4108        .align 3
4109        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4110        .text
4111        __endif
4112
4113_spentry(ffcall_return_registers)
4114LocalLabelPrefix[]ffcall_return_registers:               
4115        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
4116          if not a fixnum, get the first word */
4117        __(unbox_fixnum(%arg_z,%imm1))
4118        __(testb $fixnummask,%arg_z_b)
4119        __(je 0f)
4120        __(movq macptr.address(%arg_z),%imm1)
41210:             
4122        /* Save lisp registers   */
4123        __(push %rbp)
4124        __(movq %rsp,%rbp)
4125        __(push %temp0)
4126        __(push %temp1)
4127        __(push %temp2)
4128        __(push %arg_x)
4129        __(push %arg_y)
4130        __(push %arg_z)
4131        __(push %save0)
4132        __(push %save1)
4133        __(push %save2)
4134        __(push %save3)
4135        __(movq macptr.address(%arg_y),%rbx)  /* %rbx non-volatile */
4136        __(push %fn)
4137        __(movq %rsp,%rcontext:tcr.save_vsp)
4138        __(movq %rbp,%rcontext:tcr.save_rbp)
4139        __(movq $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
4140        __(movq %rcontext:tcr.foreign_sp,%rsp)
4141        __(stmxcsr %rcontext:tcr.lisp_mxcsr)
4142        __(emms)
4143        __(ldmxcsr %rcontext:tcr.foreign_mxcsr)
4144        __(movq (%rsp),%rbp)
4145        __ifdef([DARWIN_GS_HACK])
4146         /* At this point, %imm1=%rdx is live (contains
4147            the entrypoint) and %imm0.b=%al contains
4148            xmm argument info; the lisp registers are
4149            all saved, and the foreign arguments are
4150            on the foreign stack (about to be popped
4151            off).  Save the linear TCR address in %save0/%r15
4152            so that we can restore it later, and preserve
4153            the entrypoint somewhere where C won't bash it.
4154            Note that dereferencing the entrypoint from
4155            foreign code has never been safe (unless it's
4156            a fixnum */
4157         __(save_tcr_linear(%save0))
4158         __(movq %imm0,%save1)
4159         __(movq %imm1,%save2)
4160         __(set_foreign_gs_base())
4161         __(movq %save1,%imm0)
4162         __(movq %save2,%imm1)
4163        __endif
4164        __(movq %imm1,%r11)
4165LocalLabelPrefix[]ffcall_return_registers_setup:
4166        __(addq $2*node_size,%rsp)
4167        __(pop %rdi)
4168        __(pop %rsi)
4169        __(pop %rdx)
4170        __(pop %rcx)
4171        __(pop %r8)
4172        __(pop %r9)
4173LocalLabelPrefix[]ffcall_return_registers_setup_end: 
4174LocalLabelPrefix[]ffcall_return_registers_call:
4175        __(call *%r11)
4176LocalLabelPrefix[]ffcall_return_registers_call_end:               
4177        __(movq %rax,(%rbx))
4178        __(movq %rdx,8(%rbx))
4179        __(movsd %xmm0,16(%rbx))
4180        __(movsd %xmm1,24(%rbx))
4181        __(movq %rbp,%rsp)
4182        __ifdef([DARWIN_GS_HACK])
4183         /* %rax/%rdx contains the return value (maybe), %save0 still
4184            contains the linear tcr address.  Preserve %rax/%rdx here. */
4185         __(set_gs_base(%save0))
4186         __(movq (%save2),%rax)
4187         __(movq 8(%save2),%rdx)
4188         __(movsd 16(%save2),%xmm0)
4189         __(movsd 24(%save2),%xmm1)
4190        __endif
4191        __(movq %rsp,%rcontext:tcr.foreign_sp)       
4192        __(clr %save3)
4193        __(clr %save2)
4194        __(clr %save1)
4195        __(clr %save0)
4196        __(clr %arg_z)
4197        __(clr %arg_y)
4198        __(clr %arg_x)
4199        __(clr %temp2)
4200        __(clr %temp1)
4201        __(clr %temp0)
4202        __(clr %fn)
4203        __(pxor %fpzero,%fpzero)
4204        /* Darwin's math library seems to be pretty casual
4205           about causing spurious FP exceptions */
4206        __ifdef([DARWIN])
4207         __(movl %arg_x_l,%rcontext:tcr.ffi_exception)
4208        __else
4209         __(stmxcsr %rcontext:tcr.ffi_exception)
4210        __endif
4211        __(movq %rcontext:tcr.save_vsp,%rsp)
4212        __(movq %rcontext:tcr.save_rbp,%rbp)
4213        __(movq $TCR_STATE_LISP,%rcontext:tcr.valence)
4214        __(pop %fn)
4215        __(pop %save3)
4216        __(pop %save2)
4217        __(pop %save1)
4218        __(pop %save0)
4219        __(pop %arg_z)
4220        __(pop %arg_y)
4221        __(pop %arg_x)
4222        __(pop %temp2)
4223        __(pop %temp1)
4224        __(ldmxcsr %rcontext:tcr.lisp_mxcsr)
4225        __(check_pending_interrupt(%temp0))
4226        __(pop %temp0)
4227        __(leave)
4228        __ifdef([DARWIN])
4229        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,%rcontext:tcr.flags)
4230        __(jc,pn 0f)
4231        __endif
4232        __(ret)
4233        __ifdef([DARWIN])
42340:
4235        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4236        /* Box it, then signal a lisp error. */
4237        __(movq %imm0,%imm2)
4238        __(movq $macptr_header,%rax)
4239        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4240        __(movq %imm2,macptr.address(%arg_z))
4241        __(movq $XFOREIGNEXCEPTION,%arg_y)
4242        __(set_nargs(2))
4243        __(jmp _SPksignalerr)
4244        __endif
4245        __ifdef([DARWIN])       
4246        /* Handle exceptions, for ObjC 2.0 */
4247LocalLabelPrefix[]ffcall_return_registersLandingPad:     
4248        __(movq %rax,%save1)
4249        __(cmpq $1,%rdx)
4250        __(je 1f)
4251        __(movq %rax,%rdi)
4252LocalLabelPrefix[]ffcall_return_registersUnwindResume:           
4253        __(call *lisp_global(unwind_resume))
4254LocalLabelPrefix[]ffcall_return_registersUnwindResume_end:         
42551:      __(movq %save1,%rdi)
4256LocalLabelPrefix[]ffcall_return_registersBeginCatch:             
4257        __(call *lisp_global(objc2_begin_catch))
4258LocalLabelPrefix[]ffcall_return_registersBeginCatch_end:         
4259        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4260LocalLabelPrefix[]ffcall_return_registersEndCatch:               
4261        __(call *lisp_global(objc2_end_catch))
4262LocalLabelPrefix[]ffcall_return_registersEndCatch_end:           
4263        __(ref_global(get_tcr,%rax))
4264        __(movq $1,%rdi)
4265        __(call *%rax)
4266        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4267        __(movq %save1,%rax)
4268        __(jmp LocalLabelPrefix[]ffcall_return_registers_call_end)
4269LocalLabelPrefix[]ffcall_return_registers_end:   
4270        __endif
4271_endsubp(ffcall_returning_registers)
4272
4273        __ifdef([DARWIN])
4274        .section __DATA,__gcc_except_tab
4275GCC_except_table1:
4276        .align 3
4277LLSDA2:
4278        .byte   0xff    /* @LPStart format (omit) */
4279        .byte   0x0     /* @TType format (absolute) */
4280        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4281        .byte   0x3     /* call-site format (udata4) */
4282        .byte   0x41    /* uleb128 0x41; Call-site table length */
4283       
4284        .long Lffcall_return_registers_setup-Lffcall_return_registers   /* region 0 start */
4285        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup /* length */
4286        .long   0x0     /* landing pad */
4287        .byte   0x0     /* uleb128 0x0; action */
4288       
4289        .long Lffcall_return_registers_call-Lffcall_return_registers    /* region 1 start */
4290        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call   /* length */
4291        .long Lffcall_return_registersLandingPad-Lffcall_return_registers       /* landing pad */
4292        .byte   0x1     /* uleb128 0x1; action */
4293       
4294        .long Lffcall_return_registersUnwindResume-Lffcall_return_registers     /* region 2 start */
4295        .long Lffcall_return_registersUnwindResume_end-Lffcall_return_registersUnwindResume     /* length */
4296        .long   0x0     /* landing pad */
4297        .byte   0x0     /* uleb128 0x0; action */
4298       
4299        .long Lffcall_return_registersBeginCatch-Lffcall_return_registers       /* region 3 start */
4300        .long Lffcall_return_registersBeginCatch_end-Lffcall_return_registersBeginCatch /* length */
4301        .long 0 /* landing pad */
4302        .byte   0x0     /* uleb128 0x0; action */
4303       
4304        .long Lffcall_return_registersEndCatch-Lffcall_return_registers
4305        .long Lffcall_return_registersEndCatch_end-Lffcall_return_registersEndCatch     /* length */
4306        .long   0x0     /* landing pad */
4307        .byte   0x0     /* uleb128 0x0; action */
4308        .byte   0x1     /* Action record table */
4309        .byte   0x0
4310        .align 3
4311        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4312        .text
4313        __endif
4314               
4315_spentry(syscall)
4316        /* Save lisp registers   */
4317        __(push %rbp)
4318        __(movq %rsp,%rbp)
4319        __(push %temp0)
4320        __(push %temp1)
4321        __(push %temp2)
4322        __(push %arg_x)
4323        __(push %arg_y)
4324        __(push %arg_z)
4325        __(push %save0)
4326        __(push %save1)
4327        __(push %save2)
4328        __(push %save3)
4329        __(push %fn)
4330        __(movq %rsp,%rcontext:tcr.save_vsp)
4331        __(movq %rbp,%rcontext:tcr.save_rbp)
4332        __(movq $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
4333        __(movq %rcontext:tcr.foreign_sp,%rsp)
4334        __(emms)
4335        __(movq (%rsp),%rbp)
4336        __(addq $2*node_size,%rsp)
4337        __(unbox_fixnum(%arg_z,%rax))
4338        __(pop %rdi)
4339        __(pop %rsi)
4340        __(pop %rdx)
4341        __(pop %r10)            /*  syscalls take 4th param in %r10, not %rcx   */
4342        __(pop %r8)
4343        __(pop %r9)
4344        __(syscall)
4345        __ifdef([SYSCALL_SETS_CARRY_ON_ERROR])
4346         __(jnc 0f)
4347         __(negq %rax)
43480:     
4349        __endif       
4350        __(movq %rbp,%rsp)
4351        __(movq %rsp,%rcontext:tcr.foreign_sp)       
4352        __(clr %save3)
4353        __(clr %save2)
4354        __(clr %save1)
4355        __(clr %save0)
4356        __(clr %arg_z)
4357        __(clr %arg_y)
4358        __(clr %arg_x)
4359        __(clr %temp2)
4360        __(clr %temp1)
4361        __(clr %temp0)
4362        __(clr %fn)
4363        __(pxor %fpzero,%fpzero)
4364        __(movq %rcontext:tcr.save_vsp,%rsp)
4365        __(movq %rcontext:tcr.save_rbp,%rbp)
4366        __(movq $TCR_STATE_LISP,%rcontext:tcr.valence)
4367        __(pop %fn)
4368        __(pop %save3)
4369        __(pop %save2)
4370        __(pop %save1)
4371        __(pop %save0)
4372        __(pop %arg_z)
4373        __(pop %arg_y)
4374        __(pop %arg_x)
4375        __(pop %temp2)
4376        __(pop %temp1)
4377        __(check_pending_interrupt(%temp0))
4378        __(pop %temp0)
4379        __(leave)
4380        __(ret)
4381_endsubp(syscall)               
4382
4383/* We need to reserve a frame here if (a) nothing else was already pushed and (b) */
4384/*   we push something (e.g., more than 3 args in the lexpr)      */
4385_spentry(spread_lexprz)
4386        new_local_labels()
4387        __(movq (%arg_z),%imm0)
4388        __(testw %nargs,%nargs) /* anything pushed by caller ? */
4389        __(leaq node_size(%arg_z,%imm0),%imm1)
4390        __(jne 0f)              /* yes, caller has already created frame. */
4391        __(cmpw $(nargregs*node_size),%imm0_w) /* will we push anything ? */
4392        __(jbe 0f)
4393        __(push $reserved_frame_marker)
4394        __(push $reserved_frame_marker)
43950:      __(addw %imm0_w,%nargs)
4396        __(cmpw $(nargregs*node_size),%imm0_w)
4397        __(jae 9f)
4398        __(cmpw $(2*node_size),%imm0_w)
4399        __(je 2f)
4400        __(testw %imm0_w,%imm0_w)
4401        __(jne 1f)
4402        /* lexpr count was 0; vpop the args that */
4403        /* were pushed by the caller */
4404        __(testw %nargs,%nargs)
4405        __(je local_label(all_args_popped))
4406        __(pop %arg_z)
4407local_label(maybe_pop_yx):             
4408        __(cmpw $(1*node_size),%nargs)
4409        __(je local_label(all_args_popped))
4410        __(pop %arg_y)
4411        __(cmp $(2*node_size),%nargs)
4412        __(je local_label(all_args_popped))
4413local_label(pop_arg_x):         
4414        __(pop %arg_x)
4415local_label(all_args_popped):   
4416        /* If all args fit in registers but some were pushed */
4417        /* by the caller, discard the reserved frame that the caller */
4418        /* pushed.         */
4419        __(cmpw %imm0_w,%nargs)
4420        __(je local_label(go))
4421        __(cmpw $(nargregs*node_size),%nargs)
4422        __(ja local_label(go))
4423        __(addq $(2*node_size),%rsp)
4424local_label(go):       
4425        __(jmp *%ra0)       
4426        /* vpush args from the lexpr until we have only */
4427        /* three left, then assign them to arg_x, arg_y, */
4428        /* and arg_z. */
44298:      __(cmpw $(4*node_size),%imm0_w)
4430        __(lea -1*node_size(%imm0),%imm0)
4431        __(push -node_size(%imm1))
4432        __(lea -1*node_size(%imm1),%imm1)
44339:      __(jne 8b)
4434        __(movq -node_size*1(%imm1),%arg_x)
4435        __(movq -node_size*2(%imm1),%arg_y)
4436        __(movq -node_size*3(%imm1),%arg_z)
4437        __(jmp *%ra0)
4438
4439        /* lexpr count is two: set arg_y, arg_z from the */
4440        /* lexpr, maybe vpop arg_x */
44412:      __(cmpw $(2*node_size),%nargs)
4442        __(movq -node_size*1(%imm1),%arg_y)
4443        __(movq -node_size*2(%imm1),%arg_z)
4444        __(jne local_label(pop_arg_x))
4445        __(jmp *%ra0)
4446        /* lexpr count is one: set arg_z from the lexpr, */
4447        /* maybe vpop arg_y, arg_x  */
44481:      __(movq -node_size*1(%imm1),%arg_z)
4449        __(jmp local_label(maybe_pop_yx))
4450_endsubp(spread_lexprz)
4451       
4452
4453
4454
4455/* Callback index in %r11         */
4456_spentry(callback)
4457        __(push %rbp)
4458        __(movq %rsp,%rbp)
4459        /* C scalar args   */
4460        __(push %rdi)   /* -8(%rbp)   */
4461        __(push %rsi)
4462        __(push %rdx)
4463        __(push %rcx)
4464        __(push %r8)
4465        __(push %r9)
4466        /* FP arg regs   */
4467        __(subq $8*8,%rsp)
4468        __(movq %xmm0,7*8(%rsp))        /* -56(%rbp)   */
4469        __(movq %xmm1,6*8(%rsp))
4470        __(movq %xmm2,5*8(%rsp))
4471        __(movq %xmm3,4*8(%rsp))
4472        __(movq %xmm4,3*8(%rsp))
4473        __(movq %xmm5,2*8(%rsp))
4474        __(movq %xmm6,1*8(%rsp))
4475        __(movq %xmm7,0*8(%rsp))
4476        /* C NVRs   */
4477        __(push %r12)
4478        __(push %r13)
4479        __(push %r14)
4480        __(push %r15)
4481        __(push %rbx)
4482        __(push %rbp)
4483        __ifdef([HAVE_TLS])
4484         /* TCR initialized for lisp ?   */
4485         __(movq %fs:current_tcr@TPOFF+tcr.linear,%rax)
4486         __(testq %rax,%rax)
4487         __(jne 1f)
4488        __endif
4489        __(movq %r11,%r12)
4490        __(ref_global(get_tcr,%rax))
4491        __(movq $1,%rdi)
4492        __(call *%rax)
4493        __ifdef([DARWIN_GS_HACK])
4494         /* linear TCR address in now in %rax; callback index was
4495            saved in %r12 a moment ago. */
4496         __(set_gs_base(%rax))
4497        __endif
4498        __(movq %r12,%r11)
44991:      /* Align foreign stack for lisp   */
4500        __(subq $node_size,%rsp)
4501        __(pushq %rcontext:tcr.foreign_sp)
4502        /* init lisp registers   */
4503        __(movq %r11,%rax)
4504        __(movq %rsp,%rcontext:tcr.foreign_sp)
4505        __(clr %save3)
4506        __(clr %save2)
4507        __(clr %save1)
4508        __(clr %save0)
4509        __(clr %arg_z)
4510        __(clr %arg_y)
4511        __(clr %arg_x)
4512        __(clr %temp2)
4513        __(clr %temp1)
4514        __(clr %temp0)
4515        __(clr %fn)
4516        __(pxor %fpzero,%fpzero)
4517        __(movq %rcontext:tcr.save_vsp,%rsp)
4518        __(box_fixnum(%rax,%arg_y))
4519        __(movq %rbp,%arg_z)
4520        __(movq %rcontext:tcr.save_rbp,%rbp)
4521        __(movq $TCR_STATE_LISP,%rcontext:tcr.valence)
4522        __(movq (%rsp),%save3)
4523        __(movq 8(%rsp),%save2)
4524        __(movq 16(%rsp),%save1)
4525        __(movq 24(%rsp),%save0)
4526        __(stmxcsr %rcontext:tcr.foreign_mxcsr)
4527        __(andb $~mxcsr_all_exceptions,%rcontext:tcr.foreign_mxcsr)
4528        __(ldmxcsr %rcontext:tcr.lisp_mxcsr)
4529        __(movq $nrs.callbacks,%fname)
4530        __(lea local_label(back_from_callback)(%rip),%ra0)
4531        __(set_nargs(2))
4532        __(push %ra0)
4533        __(jump_fname())
4534__(tra(local_label(back_from_callback)))
4535        __(movq %rsp,%rcontext:tcr.save_vsp)
4536        __(movq %rbp,%rcontext:tcr.save_rbp)
4537        __(movq %rcontext:tcr.foreign_sp,%rsp)
4538        __(stmxcsr %rcontext:tcr.lisp_mxcsr)
4539        __(movq $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
4540        __(emms)
4541        __(pop %rcontext:tcr.foreign_sp)
4542        __(addq $node_size,%rsp)
4543        __(ldmxcsr %rcontext:tcr.foreign_mxcsr)
4544        __ifdef([DARWIN_GS_HACK])
4545         /* Lucky us; nothing is live here */
4546         __(set_foreign_gs_base())
4547        __endif
4548        __(pop %rbp)
4549        __(pop %rbx)
4550        __(pop %r15)
4551        __(pop %r14)
4552        __(pop %r13)
4553        __(pop %r12)
4554        __(movq -8(%rbp),%rax)
4555        __(movq -16(%rbp),%rdx)
4556        __(movq -24(%rbp),%xmm0)
4557        __(movq -32(%rbp),%xmm1)
4558        __(leave)
4559        __(ret)         
4560_endsubp(callback)
4561
4562/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
4563   We don't know whether the array is alleged to be simple or
4564   not, and don't know anythng about the element type.  */
4565               
4566_spentry(aref2)
4567        __(testb $fixnummask,%arg_y_b)
4568        __(je,pt 0f)
4569        __(uuo_error_reg_not_fixnum(Rarg_y))
45700:      __(testb $fixnummask,%arg_z_b)
4571        __(je,pt 1f)
4572        __(uuo_error_reg_not_fixnum(Rarg_z))
45731:      __(extract_typecode(%arg_x,%imm0))
4574        __(cmpb $subtag_arrayH,%imm0_b)
4575        __(jne 2f)
4576        __(cmpq $2<<fixnumshift,arrayH.rank(%arg_x))
4577        __(je,pt 3f)
45782:      __(uuo_error_reg_not_type(Rarg_x,error_object_not_array_2d))
45793:      __(cmpq arrayH.dim0(%arg_x),%arg_y)
4580        __(jb,pt 4f)
4581        __(uuo_error_array_bounds(Rarg_y,Rarg_x))
45824:      __(movq arrayH.dim0+node_size(%arg_x),%imm0)
4583        __(cmpq %imm0,%arg_z)
4584        __(jb,pt 5f)
4585        __(uuo_error_array_bounds(Rarg_z,Rarg_x))
45865:      __(unbox_fixnum(%imm0,%imm0))
4587        __(mulq %arg_y)         /* imm0 <- imm0 * arg_y */
4588        __(addq %imm0,%arg_z)
4589        __(movq %arg_x,%arg_y)
45906:      __(addq arrayH.displacement(%arg_y),%arg_z)
4591        __(movq arrayH.data_vector(%arg_y),%arg_y)
4592        __(extract_subtag(%arg_y,%imm1_b))
4593        __(cmpb $subtag_vectorH,%imm1_b)
4594        __(ja C(misc_ref_common))
4595        __(jmp 6b)
4596_endsubp(aref2)
4597
4598/* %temp0 = array, %arg_x = i,%arg_y = j, %arg_z = k */
4599_spentry(aref3)
4600        __(testb $fixnummask,%arg_x_b)
4601        __(je,pt 0f)
4602        __(uuo_error_reg_not_fixnum(Rarg_x))
46030:      __(testb $fixnummask,%arg_y_b)
4604        __(je,pt 1f)
4605        __(uuo_error_reg_not_fixnum(Rarg_y))
46061:      __(testb $fixnummask,%arg_z_b)
4607        __(je,pt 2f)
4608        __(uuo_error_reg_not_fixnum(Rarg_z))
46092:      __(extract_typecode(%temp0,%imm0))
4610        __(cmpb $subtag_arrayH,%imm0_b)
4611        __(jne 3f)
4612        __(cmpq $3<<fixnumshift,arrayH.rank(%temp0))
4613        __(je,pt 4f)
46143:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_3d))
46154:      __(cmpq arrayH.dim0(%temp0),%arg_x)
4616        __(jb,pt 5f)
4617        __(uuo_error_array_bounds(Rarg_x,Rtemp0))
46185:      __(movq arrayH.dim0+node_size(%temp0),%imm0)
4619        __(cmpq %imm0,%arg_y)
4620        __(jb,pt 6f)
4621        __(uuo_error_array_bounds(Rarg_y,Rtemp0))
46226:      __(unbox_fixnum(%imm0,%imm0))
4623        __(movq arrayH.dim0+(node_size*2)(%temp0),%imm1)
4624        __(cmpq %imm1,%arg_z)
4625        __(jb,pt 7f)
4626        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
46277:      __(unbox_fixnum(%imm1,%imm1))
4628        __(imulq %imm1,%arg_y)
4629        __(mulq %imm1)
4630        __(imulq %imm0,%arg_x)
4631        __(addq %arg_x,%arg_z)
4632        __(addq %arg_y,%arg_z)
4633        __(movq %temp0,%arg_y)
46348:      __(addq arrayH.displacement(%arg_y),%arg_z)
4635        __(movq arrayH.data_vector(%arg_y),%arg_y)
4636        __(extract_subtag(%arg_y,%imm1_b))
4637        __(cmpb $subtag_vectorH,%imm1_b)
4638        __(ja C(misc_ref_common))
4639        __(jmp 8b)
4640_endsubp(aref3)
4641       
4642/* As with aref2, but temp0 = array, arg_x = i, arg_y = j, arg_z = new_value */
4643_spentry(aset2)
4644        __(testb $fixnummask,%arg_x_b)
4645        __(je,pt 0f)
4646        __(uuo_error_reg_not_fixnum(Rarg_x))
46470:      __(testb $fixnummask,%arg_y_b)
4648        __(je,pt 1f)
4649        __(uuo_error_reg_not_fixnum(Rarg_y))
46501:      __(extract_typecode(%temp0,%imm0))
4651        __(cmpb $subtag_arrayH,%imm0_b)
4652        __(jne 2f)
4653        __(cmpq $2<<fixnumshift,arrayH.rank(%temp0))
4654        __(je,pt 3f)
46552:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
46563:      __(cmpq arrayH.dim0(%temp0),%arg_x)
4657        __(jb,pt 4f)
4658        __(uuo_error_array_bounds(Rarg_x,Rtemp0))
46594:      __(movq arrayH.dim0+node_size(%temp0),%imm0)
4660        __(cmpq %imm0,%arg_y)
4661        __(jb,pt 5f)
4662        __(uuo_error_array_bounds(Rarg_y,Rtemp0))
46635:      __(unbox_fixnum(%imm0,%imm0))
4664        __(mulq %arg_x)         /* imm0 <- imm0 * arg_x */
4665        __(addq %imm0,%arg_y)
4666        __(movq %temp0,%arg_x)
46676:      __(addq arrayH.displacement(%arg_x),%arg_y)
4668        __(movq arrayH.data_vector(%arg_x),%arg_x)
4669        __(extract_subtag(%arg_x,%imm1_b))
4670        __(cmpb $subtag_vectorH,%imm1_b)
4671        __(ja C(misc_set_common))
4672        __(jmp 6b)
4673_endsubp(aset2)
4674
4675/* %temp1 = array, %temp0 = i, %arg_x = j, %arg_y = k, %arg_y = newval. */
4676
4677_spentry(aset3)
4678        __(testb $fixnummask,%temp0_b)
4679        __(je,pt 0f)
4680        __(uuo_error_reg_not_fixnum(Rtemp0))
46810:      __(testb $fixnummask,%arg_x_b)
4682        __(je,pt 1f)
4683        __(uuo_error_reg_not_fixnum(Rarg_x))
46841:      __(testb $fixnummask,%arg_y_b)
4685        __(je,pt 2f)
4686        __(uuo_error_reg_not_fixnum(Rarg_y))
46872:      __(extract_typecode(%temp1,%imm0))
4688        __(cmpb $subtag_arrayH,%imm0_b)
4689        __(jne 3f)
4690        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4691        __(je,pt 4f)
46923:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
46934:      __(cmpq arrayH.dim0(%temp1),%temp0)
4694        __(jb,pt 5f)
4695        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
46965:      __(movq arrayH.dim0+node_size(%temp1),%imm0)
4697        __(cmpq %imm0,%arg_x)
4698        __(jb,pt 6f)
4699        __(uuo_error_array_bounds(Rarg_x,Rtemp1))
47006:      __(unbox_fixnum(%imm0,%imm0))
4701        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4702        __(cmpq %imm1,%arg_y)
4703        __(jb,pt 7f)
4704        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
47057:      __(unbox_fixnum(%imm1,%imm1))
4706        __(imulq %imm1,%arg_x)
4707        __(mulq %imm1)
4708        __(imulq %imm0,%temp0)
4709        __(addq %temp0,%arg_y)
4710        __(addq %arg_x,%arg_y)
4711        __(movq %temp1,%arg_x)
47128:      __(addq arrayH.displacement(%arg_x),%arg_y)
4713        __(movq arrayH.data_vector(%arg_x),%arg_x)
4714        __(extract_subtag(%arg_x,%imm1_b))
4715        __(cmpb $subtag_vectorH,%imm1_b)
4716        __(ja C(misc_set_common))
4717        __(jmp 8b)
4718_endsubp(aset3)
4719
4720       
4721
4722
4723/* Prepend all but the first five (4 words of code, inner fn) and last   */
4724/* (lfbits) elements of %fn to the "arglist".   */
4725       
4726_spentry(call_closure)
4727        new_local_labels()
4728        __(subq $fulltag_function-fulltag_misc,%fn)
4729        __(vector_length(%fn,%imm0))
4730        __(movzwl %nargs,%nargs_l)
4731       
4732        __(subq $6<<fixnumshift,%imm0)  /* imm0 = inherited arg count   */
4733        __(lea (%nargs_q,%imm0),%imm1)
4734        __(cmpw $nargregs<<fixnumshift,%imm1_w)
4735        __(jna,pt local_label(regs_only))
4736        __(pop %ra0)
4737        __(cmpw $nargregs<<fixnumshift,%nargs)
4738        __(jna,pt local_label(no_insert))
4739       
4740/* Some arguments have already been pushed.  Push imm0's worth   */
4741/* of NILs, copy those arguments that have already been vpushed from   */
4742/* the old TOS to the new, then insert all of the inerited args   */
4743/* and go to the function.  */
4744       
4745        __(movq %imm0,%imm1)
4746local_label(push_nil_loop):     
4747        __(push $nil_value)
4748        __(sub $fixnumone,%imm1)
4749        __(jne local_label(push_nil_loop))
4750       
4751/* Need to use arg regs as temporaries here.    */
4752        __(movq %rsp,%temp1)
4753        __(push %arg_z)
4754        __(push %arg_y)
4755        __(push %arg_x)
4756        __(lea 3*node_size(%rsp,%imm0),%arg_x)
4757        __(lea -nargregs<<fixnumshift(%nargs_q),%arg_y)
4758local_label(copy_already_loop): 
4759        __(movq (%arg_x),%arg_z)
4760        __(addq $fixnumone,%arg_x)
4761        __(movq %arg_z,(%temp1))
4762        __(addq $fixnumone,%temp1)
4763        __(subq $fixnumone,%arg_y)
4764        __(jne local_label(copy_already_loop))
4765       
4766        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4767local_label(insert_loop):               
4768        __(movq misc_data_offset(%fn,%imm1),%arg_z)
4769        __(addq $node_size,%imm1)
4770        __(addw $fixnum_one,%nargs)
4771        __(subq $node_size,%arg_x)
4772        __(movq %arg_z,(%arg_x))
4773        __(subq $fixnum_one,%imm0)
4774        __(jne local_label(insert_loop))
4775
4776        /* Recover the argument registers, pushed earlier   */
4777        __(pop %arg_x)
4778        __(pop %arg_y)
4779        __(pop %arg_z)
4780        __(jmp local_label(go))
4781
4782/* Here if nothing was pushed by the caller.  If we're  */
4783/* going to push anything, we have to reserve a stack  */
4784/* frame first. (We'll need to push something if the  */
4785/* sum of %nargs and %imm0 is greater than nargregs)   */
4786       
4787local_label(no_insert):
4788        __(lea (%nargs_q,%imm0),%imm1)
4789        __(cmpq $nargregs<<fixnumshift,%imm1)
4790        __(jna local_label(no_insert_no_frame))
4791        /* Reserve space for a stack frame   */
4792        __(push $reserved_frame_marker)
4793        __(push $reserved_frame_marker)
4794local_label(no_insert_no_frame):       
4795        /* nargregs or fewer args were already vpushed.   */
4796        /* if exactly nargregs, vpush remaining inherited vars.   */
4797        __(cmpw $nargregs<<fixnumshift,%nargs)
4798        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4799        __(leaq 5<<fixnumshift(%imm0),%temp1)
4800        __(jnz local_label(set_regs))
4801local_label(vpush_remaining): 
4802        __(push misc_data_offset(%fn,%imm1))
4803        __(addq $node_size,%imm1)
4804        __(addw $fixnumone,%nargs)
4805        __(subq $node_size,%imm0)
4806        __(jnz local_label(vpush_remaining))
4807        __(jmp local_label(go))
4808local_label(set_regs):
4809        /* if nargs was > 1 (and we know that it was < 3), it must have   */
4810        /* been 2.  Set arg_x, then vpush the remaining args.   */
4811        __(cmpw $fixnumone,%nargs)
4812        __(jle local_label(set_y_z))
4813local_label(set_arg_x): 
4814        __(subq $node_size,%temp1)
4815        __(movq misc_data_offset(%fn,%temp1),%arg_x)
4816        __(addw $fixnumone,%nargs)
4817        __(subq $fixnumone,%imm0)
4818        __(jne local_label(vpush_remaining))
4819        __(jmp local_label(go))
4820        /* Maybe set arg_y or arg_z, preceding args   */
4821local_label(set_y_z):
4822        __(jne local_label(set_arg_z))
4823        /* Set arg_y, maybe arg_x, preceding args   */
4824local_label(set_arg_y): 
4825        __(subq $node_size,%temp1)
4826        __(movq misc_data_offset(%fn,%temp1),%arg_y)
4827        __(addw $fixnumone,%nargs)
4828        __(subq $fixnum_one,%imm0)
4829        __(jnz local_label(set_arg_x))
4830        __(jmp local_label(go))
4831local_label(set_arg_z): 
4832        __(subq $node_size,%temp1)
4833        __(movq misc_data_offset(%fn,%temp1),%arg_z)
4834        __(addw $fixnumone,%nargs)
4835        __(subq $fixnum_one,%imm0)
4836        __(jne local_label(set_arg_y))
4837local_label(go):       
4838        __(movq misc_data_offset+(4*node_size)(%fn),%fn)
4839        __(push %ra0)
4840        __(jmp *%fn)
4841local_label(regs_only):
4842        __(leaq 5<<fixnumshift(%imm0),%temp1)
4843        __(testw %nargs,%nargs)
4844        __(jne local_label(some_args))
4845        __(cmpw $node_size,%imm0)
4846        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_z)
4847        __(je local_label(rgo))
4848        __(cmpw $2*node_size,%imm0)
4849        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_y)
4850        __(je local_label(rgo))
4851        __(movq misc_data_offset-(node_size*3)(%fn,%temp1),%arg_x)
4852local_label(rgo):
4853        __(addw %imm0_w,%nargs)
4854        __(jmp *misc_data_offset+(4*node_size)(%fn))
4855local_label(some_args):         
4856        __(cmpw $2*node_size,%nargs)
4857        __(jz local_label(rtwo))
4858        /* One arg was passed, could be one or two inherited args */
4859        __(cmpw $node_size,%imm0)
4860        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_y)
4861        __(je local_label(rgo))
4862        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_x)
4863        __(jmp local_label(rgo))
4864local_label(rtwo):     
4865        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_x)
4866        __(jmp local_label(rgo))
4867_endsubp(call_closure)
4868                                       
4869       
4870_spentry(poweropen_callbackX)
4871_endsubp(poweropen_callbackX)
4872       
4873       
4874_spentry(poweropen_ffcallX)
4875_endsubp(poweropen_ffcallX)
4876               
4877_spentry(poweropen_syscall)
4878_endsubp(poweropen_syscall)
4879
4880_spentry(eabi_ff_call)
4881_endsubp(eabi_ff_call)
4882
4883_spentry(eabi_callback)
4884_endsubp(eabi_callback)
4885
4886
4887/* Unused, and often not used on PPC either  */
4888_spentry(callbuiltin)
4889        __(int $3)
4890_endsubp(callbuiltin)
4891
4892_spentry(callbuiltin0)
4893        __(int $3)
4894_endsubp(callbuiltin0)
4895
4896_spentry(callbuiltin1)
4897        __(int $3)
4898_endsubp(callbuiltin1)
4899
4900_spentry(callbuiltin2)
4901        __(int $3)
4902_endsubp(callbuiltin2)
4903
4904_spentry(callbuiltin3)
4905        __(int $3)
4906_endsubp(callbuiltin3)
4907       
4908_spentry(restorefullcontext)
4909        __(int $3)
4910_endsubp(restorefullcontext)
4911
4912_spentry(savecontextvsp)
4913        __(int $3)
4914_endsubp(savecontextvsp)
4915
4916_spentry(savecontext0)
4917        __(int $3)
4918_endsubp(savecontext0)
4919
4920_spentry(restorecontext)
4921        __(int $3)
4922_endsubp(restorecontext)
4923
4924_spentry(stkconsyz)
4925        __(int $3)
4926_endsubp(stkconsyz)
4927
4928_spentry(stkvcell0)
4929        __(int $3)
4930_endsubp(stkvcell0)
4931
4932_spentry(stkvcellvsp)
4933        __(int $3)
4934_endsubp(stkvcellvsp)
4935
4936_spentry(breakpoint)
4937        __(int $3)
4938_endsubp(breakpoint)
4939
4940               
4941
4942
4943_spentry(unused_5)
4944        __(int $3)
4945_endsubp(unused_5)
4946
4947_spentry(unused_6)
4948        __(int $3)
4949_endsubp(unused_6)
4950
4951        __ifdef([DARWIN])
4952        .if 1
4953        .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
4954EH_frame1:
4955        .set L$set$12,LECIE1-LSCIE1
4956        .long L$set$12  /* Length of Common Information Entry */
4957LSCIE1:
4958        .long   0x0     /* CIE Identifier Tag */
4959        .byte   0x1     /* CIE Version */
4960        .ascii "zPLR\0" /* CIE Augmentation */
4961        .byte   0x1     /* uleb128 0x1; CIE Code Alignment Factor */
4962        .byte   0x78    /* sleb128 -8; CIE Data Alignment Factor */
4963        .byte   0x10    /* CIE RA Column */
4964        .byte   0xb     /* uleb128 0xb; Augmentation size */
4965        .byte   0x8c    /* Personality (indirect  sdata8) */
4966        .quad   lisp_global(objc_2_personality)
4967        .byte   0x10    /* LSDA Encoding (pcrel) */
4968        .byte   0x10    /* FDE Encoding (pcrel) */
4969        .byte   0xc     /* DW_CFA_def_cfa */
4970        .byte   0x7     /* uleb128 0x7 */
4971        .byte   0x8     /* uleb128 0x8 */
4972        .byte   0x90    /* DW_CFA_offset, column 0x10 */
4973        .byte   0x1     /* uleb128 0x1 */
4974        .align 3
4975LECIE1:
4976        .globl _SPffcall.eh
4977_SPffcall.eh:
4978        .long LEFDEffcall-LSFDEffcall
4979LSFDEffcall:     
4980        .long LSFDEffcall-EH_frame1 /* FDE CIE offset */
4981        .quad Lffcall-. /* FDE Initial Location */
4982        .quad Lffcall_end-Lffcall /* FDE address range */
4983        .byte 8 /* uleb128 0x8; Augmentation size */
4984        .quad LLSDA1-.           /* Language Specific Data Area */
4985        .byte   0x4     /* DW_CFA_advance_loc4 */
4986        .long Lffcall_setup-Lffcall
4987        .byte   0xe     /* DW_CFA_def_cfa_offset */
4988        .byte   0x10    /* uleb128 0x10 */
4989        .byte   0x86    /* DW_CFA_offset, column 0x6 */
4990        .byte   0x2     /* uleb128 0x2 */
4991        .byte   0x4     /* DW_CFA_advance_loc4 */
4992        .long Lffcall_setup_end-Lffcall_setup
4993        .byte   0xd     /* DW_CFA_def_cfa_register */
4994        .byte   0x6     /* uleb128 0x6 */
4995        .byte   0x4     /* DW_CFA_advance_loc4 */
4996        .long Lffcall_call_end-Lffcall_call
4997        .byte   0x83    /* DW_CFA_offset, column 0x3 */
4998        .byte   0x3     /* uleb128 0x3 */
4999        .align 3
5000LEFDEffcall:
5001        .globl _SPffcall_return_registers.eh
5002_SPffcall_return_registers.eh:
5003        .long LEFDEffcall_return_registers-LSFDEffcall_return_registers
5004LSFDEffcall_return_registers:     
5005        .long LSFDEffcall_return_registers-EH_frame1 /* FDE CIE offset */
5006        .quad Lffcall_return_registers-. /* FDE Initial Location */
5007        .quad Lffcall_return_registers_end-Lffcall_return_registers /* FDE address range */
5008        .byte 8 /* uleb128 0x8; Augmentation size */
5009        .quad LLSDA2-.           /* Language Specific Data Area */
5010        .byte   0x4     /* DW_CFA_advance_loc4 */
5011        .long Lffcall_return_registers_setup-Lffcall_return_registers
5012        .byte   0xe     /* DW_CFA_def_cfa_offset */
5013        .byte   0x10    /* uleb128 0x10 */
5014        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5015        .byte   0x2     /* uleb128 0x2 */
5016        .byte   0x4     /* DW_CFA_advance_loc4 */
5017        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup
5018        .byte   0xd     /* DW_CFA_def_cfa_register */
5019        .byte   0x6     /* uleb128 0x6 */
5020        .byte   0x4     /* DW_CFA_advance_loc4 */
5021        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call
5022        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5023        .byte   0x3     /* uleb128 0x3 */
5024        .align 3
5025LEFDEffcall_return_registers:
5026        .text
5027        .endif
5028        __endif
5029       
5030       
Note: See TracBrowser for help on using the repository browser.