source: release/1.2/source/lisp-kernel/x86-spentry64.s @ 9853

Last change on this file since 9853 was 9853, checked in by gb, 11 years ago

From rme's changes to trunk: use CISC-y bitvector instructions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 161.7 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        __(jne 0f)
174        __(testb $fixnummask,%arg_z_b)
175        __(jne 1f)
176        __(movq misc_header_offset(%arg_y),%imm0)
177        __(xorb %imm0_b,%imm0_b)
178        __(shrq $num_subtag_bits-fixnumshift,%imm0)
179        __(cmpq %imm0,%arg_z)
180        __(jae 2f)
181        __(movb misc_subtag_offset(%arg_y),%imm1_b)
182        __(jmp C(misc_ref_common))
183       
1840:      __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
1851:      __(uuo_error_reg_not_fixnum(Rarg_z))
1862:      __(uuo_error_vector_bounds(Rarg_z,Rarg_y))       
187_endsubp(misc_ref)
188       
189/* %imm1.b = subtag, %arg_y = uvector, %arg_z = index.  */
190/* Bounds/type-checking done in caller  */
191       
192_startfn(C(misc_ref_common))
193        __(movzbl %imm1_b,%imm1_l)
194        __(lea local_label(misc_ref_jmp)(%rip),%imm2)
195        __(jmp *(%imm2,%imm1,8))
196        .p2align 3
197local_label(misc_ref_jmp):     
198        /* 00-0f   */
199        .quad local_label(misc_ref_invalid) /* 00 even_fixnum   */
200        .quad local_label(misc_ref_invalid) /* 01 imm_1   */
201        .quad local_label(misc_ref_invalid) /* 02 imm_2   */
202        .quad local_label(misc_ref_invalid) /* 03 cons   */
203        .quad local_label(misc_ref_invalid) /* 04 tra_0   */
204        .quad local_label(misc_ref_invalid) /* 05 nodeheader_0   */
205        .quad local_label(misc_ref_invalid) /* 06 nodeheader_1   */
206        .quad local_label(misc_ref_invalid) /* 07 immheader_0   */
207        .quad local_label(misc_ref_invalid) /* 08 odd_fixnum   */
208        .quad local_label(misc_ref_invalid) /* 09 immheader_1   */
209        .quad local_label(misc_ref_invalid) /* 0a immheader_2   */
210        .quad local_label(misc_ref_invalid) /* 0b nil   */
211        .quad local_label(misc_ref_invalid) /* 0c tra_1   */
212        .quad local_label(misc_ref_invalid) /* 0d misc   */
213        .quad local_label(misc_ref_invalid) /* 0e symbol   */
214        .quad local_label(misc_ref_invalid) /* 0f function   */
215        /* 10-1f   */
216        .quad local_label(misc_ref_invalid) /* 10 even_fixnum   */
217        .quad local_label(misc_ref_invalid) /* 11 imm_1   */
218        .quad local_label(misc_ref_invalid) /* 12 imm_2   */
219        .quad local_label(misc_ref_invalid) /* 13 cons   */
220        .quad local_label(misc_ref_invalid) /* 14 tra_0   */
221        .quad local_label(misc_ref_node) /* 15 symbol_vector   */
222        .quad local_label(misc_ref_node) /* 16 ratio   */
223        .quad local_label(misc_ref_invalid) /* 17 immheader_0   */
224        .quad local_label(misc_ref_invalid) /* 18 odd_fixnum   */
225        .quad local_label(misc_ref_u32) /* 19 bignum   */
226        .quad local_label(misc_ref_u64) /* 1a macptr   */
227        .quad local_label(misc_ref_invalid) /* 1b nil   */
228        .quad local_label(misc_ref_invalid) /* 1c tra_1   */
229        .quad local_label(misc_ref_invalid) /* 1d misc   */
230        .quad local_label(misc_ref_invalid) /* 1e symbol   */
231        .quad local_label(misc_ref_invalid) /* 1f function   */
232        /* 20-2f   */
233        .quad local_label(misc_ref_invalid) /* 20 even_fixnum   */
234        .quad local_label(misc_ref_invalid) /* 21 imm_1   */
235        .quad local_label(misc_ref_invalid) /* 22 imm_2   */
236        .quad local_label(misc_ref_invalid) /* 23 cons   */
237        .quad local_label(misc_ref_invalid) /* 24 tra_0   */
238        .quad local_label(misc_ref_node) /* 25 catch_frame   */
239        .quad local_label(misc_ref_node) /* 26 complex   */
240        .quad local_label(misc_ref_invalid) /* 27 immheader_0   */
241        .quad local_label(misc_ref_invalid) /* 28 odd_fixnum   */
242        .quad local_label(misc_ref_u32) /* 29 double_float   */
243        .quad local_label(misc_ref_u64)  /* 2a dead_macptr   */
244        .quad local_label(misc_ref_invalid) /* 2b nil   */
245        .quad local_label(misc_ref_invalid) /* 2c tra_1   */
246        .quad local_label(misc_ref_invalid) /* 2d misc   */
247        .quad local_label(misc_ref_invalid) /* 2e symbol   */
248        .quad local_label(misc_ref_invalid) /* 2f function   */
249        /* 30-3f   */
250        .quad local_label(misc_ref_invalid) /* 30 even_fixnum   */
251        .quad local_label(misc_ref_invalid) /* 31 imm_1   */
252        .quad local_label(misc_ref_invalid) /* 32 imm_2   */
253        .quad local_label(misc_ref_invalid) /* 33 cons   */
254        .quad local_label(misc_ref_invalid) /* 34 tra_0   */
255        .quad local_label(misc_ref_node) /* 35 hash_vector   */
256        .quad local_label(misc_ref_node) /* 36 struct   */
257        .quad local_label(misc_ref_invalid) /* 37 immheader_0   */
258        .quad local_label(misc_ref_invalid) /* 38 odd_fixnum   */
259        .quad local_label(misc_ref_u32) /* 39 xcode_vector   */
260        .quad local_label(misc_ref_invalid) /* 3a immheader_2   */
261        .quad local_label(misc_ref_invalid) /* 3b nil   */
262        .quad local_label(misc_ref_invalid) /* 3c tra_1   */
263        .quad local_label(misc_ref_invalid) /* 3d misc   */
264        .quad local_label(misc_ref_invalid) /* 3e symbol   */
265        .quad local_label(misc_ref_invalid) /* 3f function   */
266        /* 40-4f   */
267        .quad local_label(misc_ref_invalid) /* 40 even_fixnum   */
268        .quad local_label(misc_ref_invalid) /* 41 imm_1   */
269        .quad local_label(misc_ref_invalid) /* 42 imm_2   */
270        .quad local_label(misc_ref_invalid) /* 43 cons   */
271        .quad local_label(misc_ref_invalid) /* 44 tra_0   */
272        .quad local_label(misc_ref_node) /* 45 pool   */
273        .quad local_label(misc_ref_node) /* 46 istruct   */
274        .quad local_label(misc_ref_invalid) /* 47 immheader_0   */
275        .quad local_label(misc_ref_invalid) /* 48 odd_fixnum   */
276        .quad local_label(misc_ref_invalid) /* 49 immheader_1   */
277        .quad local_label(misc_ref_invalid) /* 4a immheader_2   */
278        .quad local_label(misc_ref_invalid) /* 4b nil   */
279        .quad local_label(misc_ref_invalid) /* 4c tra_1   */
280        .quad local_label(misc_ref_invalid) /* 4d misc   */
281        .quad local_label(misc_ref_invalid) /* 4e symbol   */
282        .quad local_label(misc_ref_invalid) /* 4f function   */
283        /* 50-5f   */
284        .quad local_label(misc_ref_invalid) /* 50 even_fixnum   */
285        .quad local_label(misc_ref_invalid) /* 51 imm_1   */
286        .quad local_label(misc_ref_invalid) /* 52 imm_2   */
287        .quad local_label(misc_ref_invalid) /* 53 cons   */
288        .quad local_label(misc_ref_invalid) /* 54 tra_0   */
289        .quad local_label(misc_ref_node) /* 55 weak   */
290        .quad local_label(misc_ref_node) /* 56 value_cell   */
291        .quad local_label(misc_ref_invalid) /* 57 immheader_0   */
292        .quad local_label(misc_ref_invalid) /* 58 odd_fixnum   */
293        .quad local_label(misc_ref_invalid) /* 59 immheader_1   */
294        .quad local_label(misc_ref_invalid) /* 5a immheader_2   */
295        .quad local_label(misc_ref_invalid) /* 5b nil   */
296        .quad local_label(misc_ref_invalid) /* 5c tra_1   */
297        .quad local_label(misc_ref_invalid) /* 5d misc   */
298        .quad local_label(misc_ref_invalid) /* 5e symbol   */
299        .quad local_label(misc_ref_invalid) /* 5f function   */
300        /* 60-6f   */
301        .quad local_label(misc_ref_invalid) /* 60 even_fixnum   */
302        .quad local_label(misc_ref_invalid) /* 61 imm_1   */
303        .quad local_label(misc_ref_invalid) /* 62 imm_2   */
304        .quad local_label(misc_ref_invalid) /* 63 cons   */
305        .quad local_label(misc_ref_invalid) /* 64 tra_0   */
306        .quad local_label(misc_ref_node) /* 65 package   */
307        .quad local_label(misc_ref_node) /* 66 xfunction   */
308        .quad local_label(misc_ref_invalid) /* 67 immheader_0   */
309        .quad local_label(misc_ref_invalid) /* 68 odd_fixnum   */
310        .quad local_label(misc_ref_invalid) /* 69 immheader_1   */
311        .quad local_label(misc_ref_invalid) /* 6a immheader_2   */
312        .quad local_label(misc_ref_invalid) /* 6b nil   */
313        .quad local_label(misc_ref_invalid) /* 6c tra_1   */
314        .quad local_label(misc_ref_invalid) /* 6d misc   */
315        .quad local_label(misc_ref_invalid) /* 6e symbol   */
316        .quad local_label(misc_ref_invalid) /* 6f function   */
317        /* 70-7f   */
318        .quad local_label(misc_ref_invalid) /* 70 even_fixnum   */
319        .quad local_label(misc_ref_invalid) /* 71 imm_1   */
320        .quad local_label(misc_ref_invalid) /* 72 imm_2   */
321        .quad local_label(misc_ref_invalid) /* 73 cons   */
322        .quad local_label(misc_ref_invalid) /* 74 tra_0   */
323        .quad local_label(misc_ref_node) /* 75 slot_vector   */
324        .quad local_label(misc_ref_node) /* 76 lock   */
325        .quad local_label(misc_ref_invalid) /* 77 immheader_0   */
326        .quad local_label(misc_ref_invalid) /* 78 odd_fixnum   */
327        .quad local_label(misc_ref_invalid) /* 79 immheader_1   */
328        .quad local_label(misc_ref_invalid) /* 7a immheader_2   */
329        .quad local_label(misc_ref_invalid) /* 7b nil   */
330        .quad local_label(misc_ref_invalid) /* 7c tra_1   */
331        .quad local_label(misc_ref_invalid) /* 7d misc   */
332        .quad local_label(misc_ref_invalid) /* 7e symbol   */
333        .quad local_label(misc_ref_invalid) /* 7f function   */
334        /* 80-8f   */
335        .quad local_label(misc_ref_invalid) /* 80 even_fixnum   */
336        .quad local_label(misc_ref_invalid) /* 81 imm_1   */
337        .quad local_label(misc_ref_invalid) /* 82 imm_2   */
338        .quad local_label(misc_ref_invalid) /* 83 cons   */
339        .quad local_label(misc_ref_invalid) /* 84 tra_0   */
340        .quad local_label(misc_ref_node) /* 85 lisp_thread   */
341        .quad local_label(misc_ref_node) /* 86 instance   */
342        .quad local_label(misc_ref_invalid) /* 87 immheader_0   */
343        .quad local_label(misc_ref_invalid) /* 88 odd_fixnum   */
344        .quad local_label(misc_ref_invalid) /* 89 immheader_1   */
345        .quad local_label(misc_ref_invalid) /* 8a immheader_2   */
346        .quad local_label(misc_ref_invalid) /* 8b nil   */
347        .quad local_label(misc_ref_invalid) /* 8c tra_1   */
348        .quad local_label(misc_ref_invalid) /* 8d misc   */
349        .quad local_label(misc_ref_invalid) /* 8e symbol   */
350        .quad local_label(misc_ref_invalid) /* 8f function   */
351        /* 90-9f   */
352        .quad local_label(misc_ref_invalid) /* 90 even_fixnum   */
353        .quad local_label(misc_ref_invalid) /* 91 imm_1   */
354        .quad local_label(misc_ref_invalid) /* 92 imm_2   */
355        .quad local_label(misc_ref_invalid) /* 93 cons   */
356        .quad local_label(misc_ref_invalid) /* 94 tra_0   */
357        .quad local_label(misc_ref_function) /* 95 function_vector   */
358        .quad local_label(misc_ref_invalid) /* 96 nodeheader_1   */
359        .quad local_label(misc_ref_invalid) /* 97 immheader_0   */
360        .quad local_label(misc_ref_invalid) /* 98 odd_fixnum   */
361        .quad local_label(misc_ref_invalid) /* 99 immheader_1   */
362        .quad local_label(misc_ref_invalid) /* 9a immheader_2   */
363        .quad local_label(misc_ref_invalid) /* 9b nil   */
364        .quad local_label(misc_ref_invalid) /* 9c tra_1   */
365        .quad local_label(misc_ref_invalid) /* 9d misc   */
366        .quad local_label(misc_ref_invalid) /* 9e symbol   */
367        .quad local_label(misc_ref_invalid) /* 9f function   */
368        /* a0-af   */
369        .quad local_label(misc_ref_invalid) /* a0 even_fixnum   */
370        .quad local_label(misc_ref_invalid) /* a1 imm_1   */
371        .quad local_label(misc_ref_invalid) /* a2 imm_2   */
372        .quad local_label(misc_ref_invalid) /* a3 cons   */
373        .quad local_label(misc_ref_invalid) /* a4 tra_0   */
374        .quad local_label(misc_ref_node) /* a5 arrayH   */
375        .quad local_label(misc_ref_node) /* a6 vectorH   */
376        .quad local_label(misc_ref_s16) /* a7 s16   */
377        .quad local_label(misc_ref_invalid) /* a8 odd_fixnum   */
378        .quad local_label(misc_ref_invalid) /* a9 immheader_1   */
379        .quad local_label(misc_ref_invalid) /* aa immheader_2   */
380        .quad local_label(misc_ref_invalid) /* ab nil   */
381        .quad local_label(misc_ref_invalid) /* ac tra_1   */
382        .quad local_label(misc_ref_invalid) /* ad misc   */
383        .quad local_label(misc_ref_invalid) /* ae symbol   */
384        .quad local_label(misc_ref_invalid) /* af function   */
385        /* b0-bf   */
386        .quad local_label(misc_ref_invalid) /* b0 even_fixnum   */
387        .quad local_label(misc_ref_invalid) /* b1 imm_1   */
388        .quad local_label(misc_ref_invalid) /* b2 imm_2   */
389        .quad local_label(misc_ref_invalid) /* b3 cons   */
390        .quad local_label(misc_ref_invalid) /* b4 tra_0   */
391        .quad local_label(misc_ref_invalid) /* b5 nodeheader_0   */
392        .quad local_label(misc_ref_node) /* b6 simple_vector   */
393        .quad local_label(misc_ref_u16) /* b7 immheader_0   */
394        .quad local_label(misc_ref_invalid) /* b8 odd_fixnum   */
395        .quad local_label(misc_ref_invalid) /* b9 immheader_1   */
396        .quad local_label(misc_ref_invalid) /* ba immheader_2   */
397        .quad local_label(misc_ref_invalid) /* bb nil   */
398        .quad local_label(misc_ref_invalid) /* bc tra_1   */
399        .quad local_label(misc_ref_invalid) /* bd misc   */
400        .quad local_label(misc_ref_invalid) /* be symbol   */
401        .quad local_label(misc_ref_invalid) /* bf function   */
402        /* c0-cf   */
403        .quad local_label(misc_ref_invalid) /* c0 even_fixnum   */
404        .quad local_label(misc_ref_invalid) /* c1 imm_1   */
405        .quad local_label(misc_ref_invalid) /* c2 imm_2   */
406        .quad local_label(misc_ref_invalid) /* c3 cons   */
407        .quad local_label(misc_ref_invalid) /* c4 tra_0   */
408        .quad local_label(misc_ref_invalid) /* c5 nodeheader_0   */
409        .quad local_label(misc_ref_invalid) /* c6 nodeheader_1   */
410        .quad local_label(misc_ref_string) /* c7 simple_base_string   */
411        .quad local_label(misc_ref_invalid) /* c8 odd_fixnum   */
412        .quad local_label(misc_ref_new_string) /* c9 new_string_1   */
413        .quad local_label(misc_ref_fixnum_vector) /* ca fixnum_vector   */
414        .quad local_label(misc_ref_invalid) /* cb nil   */
415        .quad local_label(misc_ref_invalid) /* cc tra_1   */
416        .quad local_label(misc_ref_invalid) /* cd misc   */
417        .quad local_label(misc_ref_invalid) /* ce symbol   */
418        .quad local_label(misc_ref_invalid) /* cf function   */
419        /* d0-df   */
420        .quad local_label(misc_ref_invalid) /* d0 even_fixnum   */
421        .quad local_label(misc_ref_invalid) /* d1 imm_1   */
422        .quad local_label(misc_ref_invalid) /* d2 imm_2   */
423        .quad local_label(misc_ref_invalid) /* d3 cons   */
424        .quad local_label(misc_ref_invalid) /* d4 tra_0   */
425        .quad local_label(misc_ref_invalid) /* d5 nodeheader_0   */
426        .quad local_label(misc_ref_invalid) /* d6 nodeheader_1   */
427        .quad local_label(misc_ref_s8)  /* d7 s8   */
428        .quad local_label(misc_ref_invalid) /* d8 odd_fixnum   */
429        .quad local_label(misc_ref_s32) /* d9 s32   */
430        .quad local_label(misc_ref_s64) /* da s64   */
431        .quad local_label(misc_ref_invalid) /* db nil   */
432        .quad local_label(misc_ref_invalid) /* dc tra_1   */
433        .quad local_label(misc_ref_invalid) /* dd misc   */
434        .quad local_label(misc_ref_invalid) /* de symbol   */
435        .quad local_label(misc_ref_invalid) /* df function   */
436        /* e0-ef   */
437        .quad local_label(misc_ref_invalid) /* e0 even_fixnum   */
438        .quad local_label(misc_ref_invalid) /* e1 imm_1   */
439        .quad local_label(misc_ref_invalid) /* e2 imm_2   */
440        .quad local_label(misc_ref_invalid) /* e3 cons   */
441        .quad local_label(misc_ref_invalid) /* e4 tra_0   */
442        .quad local_label(misc_ref_invalid) /* e5 nodeheader_0   */
443        .quad local_label(misc_ref_invalid) /* e6 nodeheader_1   */
444        .quad local_label(misc_ref_u8)  /* e7 u8   */
445        .quad local_label(misc_ref_invalid) /* e8 odd_fixnum   */
446        .quad local_label(misc_ref_u32) /* e9 u32   */
447        .quad local_label(misc_ref_u64) /* ea u64   */
448        .quad local_label(misc_ref_invalid) /* eb nil   */
449        .quad local_label(misc_ref_invalid) /* ec tra_1   */
450        .quad local_label(misc_ref_invalid) /* ed misc   */
451        .quad local_label(misc_ref_invalid) /* ee symbol   */
452        .quad local_label(misc_ref_invalid) /* ef function   */
453        /* f0-ff   */
454        .quad local_label(misc_ref_invalid) /* f0 even_fixnum   */
455        .quad local_label(misc_ref_invalid) /* f1 imm_1   */
456        .quad local_label(misc_ref_invalid) /* f2 imm_2   */
457        .quad local_label(misc_ref_invalid) /* f3 cons   */
458        .quad local_label(misc_ref_invalid) /* f4 tra_0   */
459        .quad local_label(misc_ref_invalid) /* f5 nodeheader_0   */
460        .quad local_label(misc_ref_invalid) /* f6 nodeheader_1   */
461        .quad local_label(misc_ref_bit_vector) /* f7 bitvector   */
462        .quad local_label(misc_ref_invalid) /* f8 odd_fixnum   */
463        .quad local_label(misc_ref_single_float_vector) /* f9 single_float   */
464        .quad local_label(misc_ref_double_float_vector) /* fa double_float   */
465        .quad local_label(misc_ref_invalid) /* fb nil   */
466        .quad local_label(misc_ref_invalid) /* fc tra_1   */
467        .quad local_label(misc_ref_invalid) /* fd misc   */
468        .quad local_label(misc_ref_invalid) /* fe symbol   */
469        .quad local_label(misc_ref_invalid) /* ff function   */
470       
471       
472        /* Node vector.  Functions are funny: the first  N words  */
473        /* are treated as (UNSIGNED-BYTE 64), where N is the low  */
474        /* 32 bits of the first word.  */
475       
476local_label(misc_ref_function):         
477        __(movl misc_data_offset(%arg_y),%imm0_l)
478        __(shl $fixnumshift,%imm0)
479        __(rcmpq(%arg_z,%imm0))
480        __(jb local_label(misc_ref_u64))
481local_label(misc_ref_node):
482        __(movq misc_data_offset(%arg_y,%arg_z),%arg_z)
483        __(ret)
484local_label(misc_ref_u64):
485        __(movq misc_data_offset(%arg_y,%arg_z),%imm0)
486        __(jmp _SPmakeu64)
487local_label(misc_ref_double_float_vector):
488        __(movsd misc_data_offset(%arg_y,%arg_z),%fp1)
489        __(movq $double_float_header,%imm0)
490        __(Misc_Alloc_Fixed(%arg_z,double_float.size))
491        __(movsd %fp1,double_float.value(%arg_z))
492        __(ret)
493local_label(misc_ref_fixnum_vector):   
494        __(movq misc_data_offset(%arg_y,%arg_z),%imm0)
495        __(box_fixnum(%imm0,%arg_z))
496        __(ret)
497local_label(misc_ref_s64):     
498        __(movq misc_data_offset(%arg_y,%arg_z),%imm0)
499        __(jmp _SPmakes64)
500local_label(misc_ref_u32):
501        __(movq %arg_z,%imm0)
502        __(shr $1,%imm0)
503        __(movl misc_data_offset(%arg_y,%imm0),%imm0_l)
504        __(box_fixnum(%imm0,%arg_z))
505        __(ret)
506local_label(misc_ref_s32):
507        __(movq %arg_z,%imm0)
508        __(shr $1,%imm0)
509        __(movslq misc_data_offset(%arg_y,%imm0),%imm0)
510        __(box_fixnum(%imm0,%arg_z))
511        __(ret)
512local_label(misc_ref_single_float_vector):
513        __(movq %arg_z,%imm0)
514        __(shr $1,%imm0)
515        __(movsd misc_data_offset(%arg_y,%imm0),%fp1)
516        __(movd %fp1,%imm0_l)
517        __(shl $32,%imm0)
518        __(lea subtag_single_float(%imm0),%arg_z)
519        __(ret)
520local_label(misc_ref_u8):
521        __(movq %arg_z,%imm0)
522        __(shr $3,%imm0)
523        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0_l)
524        __(box_fixnum(%imm0,%arg_z))
525        __(ret)
526local_label(misc_ref_s8):       
527        __(movq %arg_z,%imm0)
528        __(shr $3,%imm0)
529        __(movsbq misc_data_offset(%arg_y,%imm0),%imm0)
530        __(box_fixnum(%imm0,%arg_z))
531        __(ret)
532local_label(misc_ref_string):
533        __(movq %arg_z,%imm0)
534        __(shr $3,%imm0)
535        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0_l)
536        __(shlq $charcode_shift,%imm0)
537        __(leaq subtag_character(%imm0),%arg_z)
538        __(ret)
539local_label(misc_ref_new_string):
540        __(movq %arg_z,%imm0)
541        __(shr $1,%imm0)
542        __(movl misc_data_offset(%arg_y,%imm0),%imm0_l)
543        __(shlq $charcode_shift,%imm0)
544        __(leaq subtag_character(%imm0),%arg_z)
545        __(ret)       
546local_label(misc_ref_u16):     
547        __(movq %arg_z,%imm0)
548        __(shrq $2,%imm0)
549        __(movzwl misc_data_offset(%arg_y,%imm0),%imm0_l)
550        __(box_fixnum(%imm0,%arg_z))
551        __(ret)
552local_label(misc_ref_s16):     
553        __(movq %arg_z,%imm0)
554        __(shrq $2,%imm0)
555        __(movswq misc_data_offset(%arg_y,%imm0),%imm0)
556        __(box_fixnum(%imm0,%arg_z))
557        __(ret)
558local_label(misc_ref_bit_vector):
559        __(unbox_fixnum(%arg_z,%imm0))
560        __(btq %imm0,misc_data_offset(%arg_y))
561        __(setc %imm0_b)
562        __(movzbl %imm0_b,%imm0_l)
563        __(imull $fixnumone,%imm0_l,%arg_z_l)
564        __(ret)
565local_label(misc_ref_invalid):
566        __(movq $XBADVEC,%arg_x)
567        __(set_nargs(3))
568        __(jmp _SPksignalerr)
569_endfn(C(misc_ref_common))
570
571/* like misc_ref, only the boxed subtag is in arg_x.   */
572                                       
573_spentry(subtag_misc_ref)
574        __(movb $tagmask,%imm0_b)
575        __(andb %arg_y_b,%imm0_b)
576        __(cmpb $tag_misc,%imm0_b)
577        __(jne 0f)
578        __(testb $fixnummask,%arg_z_b)
579        __(jne 1f)
580        __(movq misc_header_offset(%arg_y),%imm0)
581        __(xorb %imm0_b,%imm0_b)
582        __(shrq $num_subtag_bits-fixnumshift,%imm0)
583        __(cmpq %imm0,%arg_z)
584        __(jae 2f)
585        __(unbox_fixnum(%arg_x,%imm1))
586        __(jmp C(misc_ref_common))
5870:      __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
5881:      __(uuo_error_reg_not_fixnum(Rarg_z))
5892:      __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
590                       
591_endsubp(subtag_misc_ref)
592
593_spentry(subtag_misc_set)
594        __(movb $tagmask,%imm0_b)
595        __(andb %arg_x_b,%imm0_b)
596        __(cmpb $tag_misc,%imm0_b)
597        __(jne 0f)
598        __(testb $fixnummask,%arg_y_b)
599        __(jne 1f)
600        __(movq misc_header_offset(%arg_x),%imm0)
601        __(xorb %imm0_b,%imm0_b)
602        __(shrq $num_subtag_bits-fixnumshift,%imm0)
603        __(cmpq %imm0,%arg_y)
604        __(jae 2f)
605        __(unbox_fixnum(%temp0,%imm1))
606        __(jmp C(misc_set_common))
6070:      __(uuo_error_reg_not_tag(Rarg_x,tag_misc))
6081:      __(uuo_error_reg_not_fixnum(Rarg_y))
6092:      __(uuo_error_vector_bounds(Rarg_y,Rarg_x))                       
610_endsubp(subtag_misc_set)
611
612_spentry(misc_set)
613        __(movb $tagmask,%imm0_b)
614        __(andb %arg_x_b,%imm0_b)
615        __(cmpb $tag_misc,%imm0_b)
616        __(jne 0f)
617        __(testb $fixnummask,%arg_y_b)
618        __(jne 1f)
619        __(movq misc_header_offset(%arg_x),%imm0)
620        __(xorb %imm0_b,%imm0_b)
621        __(shrq $num_subtag_bits-fixnumshift,%imm0)
622        __(cmpq %imm0,%arg_y)
623        __(jae 2f)
624        __(movb misc_subtag_offset(%arg_x),%imm1_b)
625        __(jmp C(misc_set_common))
626       
6270:      __(uuo_error_reg_not_tag(Rarg_x,tag_misc))
6281:      __(uuo_error_reg_not_fixnum(Rarg_y))
6292:      __(uuo_error_vector_bounds(Rarg_y,Rarg_x))                       
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,%imm0))
1022        __(testb %arg_z_b,%arg_z_b)
1023        __(je local_label(misc_set_clr_bit))
1024local_label(misc_set_set_bit): 
1025        __(btsq %imm0,misc_data_offset(%arg_x))
1026        __(ret)
1027local_label(misc_set_clr_bit): 
1028        __(btrq %imm0,misc_data_offset(%arg_x))
1029        __(ret)
1030local_label(misc_set_u8):       
1031        __(testq $~(0xff<<fixnumshift),%arg_z)
1032        __(jne local_label(misc_set_bad))
1033        __(movq %arg_y,%imm1)
1034        __(unbox_fixnum(%arg_z,%imm0))
1035        __(shrq $3,%imm1)
1036        __(movb %imm0_b,misc_data_offset(%arg_x,%imm1))
1037        __(ret)
1038local_label(misc_set_s8):
1039        __(movq %arg_z,%imm0)
1040        __(shlq $64-(8+fixnumshift),%imm0)     
1041        __(sarq $64-(8+fixnumshift),%imm0)
1042        __(cmpq %arg_z,%imm0)
1043        __(jne local_label(misc_set_bad))
1044        __(testb $fixnummask,%arg_z_b)
1045        __(jne local_label(misc_set_bad))
1046        __(movq %arg_y,%imm1)
1047        __(shrq $fixnumshift,%imm0)
1048        __(shrq $3,%imm1)
1049        __(movb %imm0_b,misc_data_offset(%arg_x,%imm1))
1050        __(ret)
1051local_label(misc_set_string):
1052        __(cmpb $subtag_character,%arg_z_b)
1053        __(movq %arg_z,%imm0)
1054        __(jne local_label(misc_set_bad))
1055        __(movq %arg_y,%imm1)
1056        __(shrq $charcode_shift,%imm0)
1057        __(shrq $3,%imm1)
1058        __(movb %imm0_b,misc_data_offset(%arg_x,%imm1))
1059        __(ret)
1060local_label(misc_set_new_string):
1061        __(cmpb $subtag_character,%arg_z_b)
1062        __(movq %arg_z,%imm0)
1063        __(jne local_label(misc_set_bad))
1064        __(movq %arg_y,%imm1)
1065        __(shrq $charcode_shift,%imm0)
1066        __(shrq $1,%imm1)
1067        __(movl %imm0_l,misc_data_offset(%arg_x,%imm1))
1068        __(ret)       
1069local_label(misc_set_s16):     
1070        __(movq %arg_z,%imm0)
1071        __(movq %arg_y,%imm1)
1072        __(shlq $64-(16+fixnumshift),%imm0)     
1073        __(shrq $2,%imm1)
1074        __(sarq $64-(16+fixnumshift),%imm0)
1075        __(cmpq %arg_z,%imm0)
1076        __(jne local_label(misc_set_bad))
1077        __(testb $fixnummask,%arg_z_b)
1078        __(jne local_label(misc_set_bad))
1079        __(shrq $fixnumshift,%imm0)
1080        __(movw %imm0_w,misc_data_offset(%arg_x,%imm1))
1081        __(ret)
1082local_label(misc_set_u16):
1083        __(movq %arg_y,%imm1)
1084        __(testq $~(0xffff<<fixnumshift),%arg_z)
1085        __(jne local_label(misc_set_bad))
1086        __(shrq $2,%imm1)
1087        __(unbox_fixnum(%arg_z,%imm0))
1088        __(movw %imm0_w,misc_data_offset(%arg_x,%imm1))
1089        __(ret)
1090local_label(misc_set_invalid):
1091        __(push $XSETBADVEC)
1092        __(set_nargs(4))
1093        __(jmp _SPksignalerr)
1094_endfn(C(misc_set_common))
1095       
1096/* ret1valn returns "1 multiple value" when a called function does not   */
1097/* return multiple values.  Its presence on the stack (as a return address)   */
1098/* identifies the stack frame to code which returns multiple values.   */
1099
1100_spentry(Fret1valn)
1101        .globl C(ret1valn)
1102__(tra(C(ret1valn)))
1103        __(movq (%rsp),%ra0)
1104        __(movq %arg_z,(%rsp))
1105        __(set_nargs(1))
1106        __(jmpq *%ra0)
1107_endsubp(Fret1valn)
1108       
1109
1110_spentry(nvalret)
1111        .globl C(nvalret)                       
1112C(nvalret):     
1113        __(ref_global(ret1val_addr,%temp1))
1114        __(cmpq lisp_frame.savera0(%rbp),%temp1)
1115        __(je 1f)
1116        __(testl %nargs,%nargs)
1117        __(movl $nil_value,%arg_z_l)
1118        __(cmovneq -node_size(%rsp,%nargs_q),%arg_z)
1119        __(leaveq)
1120        __(ret)
1121
1122       
1123/* actually need to return values ; always need to copy   */
11241:      __(leaq 2*node_size(%rbp),%imm1)
1125        __(movq (%imm1),%ra0)
1126        __(addq $node_size,%imm1)
1127        __(movq 0(%rbp),%rbp)
1128        __(leaq (%rsp,%nargs_q),%temp0)
1129        __(xorl %imm0_l,%imm0_l)
1130        __(jmp 3f)
11312:      __(movq -node_size(%temp0),%temp1)
1132        __(subq $node_size,%temp0)
1133        __(addl $node_size,%imm0_l)
1134        __(movq %temp1,-node_size(%imm1))
1135        __(subq $node_size,%imm1)
11363:      __(cmpl %imm0_l,%nargs)  ;
1137        __(jne 2b)
1138        __(movq %imm1,%rsp)
1139        __(jmp *%ra0)   
1140_endsubp(nvalret)
1141       
1142_spentry(jmpsym)
1143        __(jump_fname())
1144_endsubp(jmpsym)
1145
1146_spentry(jmpnfn)
1147        __(movq %temp0,%fn)
1148        __(jmp *%fn)
1149_endsubp(jmpnfn)
1150
1151_spentry(funcall)
1152        __(do_funcall())
1153_endsubp(funcall)
1154
1155_spentry(mkcatch1v)
1156        __(nMake_Catch(0))
1157        __(ret)
1158_endsubp(mkcatch1v)
1159
1160_spentry(mkunwind)
1161        __(movq $undefined,%arg_z)
1162        __(Make_Catch(fixnumone))
1163        __(jmp *%ra0)
1164_endsubp(mkunwind)
1165       
1166/* this takes a return address in %ra0; it's "new" in that it does the
1167   double binding of *interrupt-level* out-of-line */
1168_spentry(nmkunwind)
1169        __(movq rcontext(tcr.tlb_pointer),%arg_x)
1170        __(movq INTERRUPT_LEVEL_BINDING_INDEX(%arg_x),%arg_y)
1171        __(push %arg_y)
1172        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
1173        __(push rcontext(tcr.db_link))
1174        __(movq %rsp,rcontext(tcr.db_link))
1175        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
1176        __(movq $undefined,%arg_z)
1177        __(Make_Catch(fixnumone))
1178        __(movq %arg_y,%arg_z)
1179        __(jmp _SPbind_interrupt_level)
1180_endsubp(nmkunwind)
1181
1182_spentry(mkcatchmv)
1183        __(nMake_Catch(fixnumone))
1184        __(ret)
1185_endsubp(mkcatchmv)
1186       
1187_spentry(throw)
1188        __(movq rcontext(tcr.catch_top),%imm1)
1189        __(xorl %imm0_l,%imm0_l)
1190        __(movq (%rsp,%nargs_q),%temp0) /* temp0 = tag   */
1191        __(jmp local_label(_throw_test))
1192local_label(_throw_loop):
1193        __(cmpq %temp0,catch_frame.catch_tag(%imm1))
1194        __(je local_label(_throw_found))
1195        __(movq catch_frame.link(%imm1),%imm1)
1196        __(addq $fixnum_one,%imm0)
1197local_label(_throw_test):
1198        __(testq %imm1,%imm1)
1199        __(jne local_label(_throw_loop))
1200        __(push %ra0)
1201        __(uuo_error_reg_not_tag(Rtemp0,subtag_catch_frame))
1202        __(pop %ra0)
1203        __(jmp _SPthrow)
1204local_label(_throw_found):     
1205        __(testb $fulltagmask,catch_frame.mvflag(%imm1))
1206        __(jne local_label(_throw_multiple))
1207        __(testl %nargs,%nargs)
1208        __(movl $nil_value,%arg_z_l)
1209        __(je local_label(_throw_one_value))
1210        __(movq -node_size(%rsp,%nargs_q),%arg_z)
1211        __(add %nargs_q,%rsp)
1212local_label(_throw_one_value):
1213        __(lea local_label(_threw_one_value)(%rip),%ra0)
1214        __(jmp _SPnthrow1value)
1215__(tra(local_label(_threw_one_value)))
1216        __(movq rcontext(tcr.catch_top),%temp0)
1217        __(movq catch_frame.db_link(%temp0),%imm0)
1218        __(movq rcontext(tcr.db_link),%imm1)
1219        __(cmpq %imm0,%imm1)
1220        __(jz local_label(_threw_one_value_dont_unbind))
1221        __(lea local_label(_threw_one_value_dont_unbind)(%rip),%ra0)
1222        __(push %ra0)
1223        __(jmp _SPunbind_to)
1224__(tra(local_label(_threw_one_value_dont_unbind)))
1225        __(movq catch_frame.rbp(%temp0),%rbp)
1226        __(movq catch_frame.foreign_sp(%temp0),%imm0)
1227        __(movq catch_frame.xframe(%temp0),%imm1)
1228        __(movq %imm0,rcontext(tcr.foreign_sp))
1229        __(movq %imm1,rcontext(tcr.xframe))
1230        __(movq catch_frame.rsp(%temp0),%rsp)
1231        __(movq catch_frame.link(%temp0),%imm1)
1232        __(movq catch_frame._save0(%temp0),%save0)
1233        __(movq catch_frame._save1(%temp0),%save1)
1234        __(movq catch_frame._save2(%temp0),%save2)
1235        __ifndef([WINDOWS])
1236        __(movq catch_frame._save3(%temp0),%save3)
1237        __endif
1238        __(movq %imm1,rcontext(tcr.catch_top))
1239        __(movq catch_frame.pc(%temp0),%ra0)
1240        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1241        __(movq (%imm1),%imm1)
1242        __(movq %imm1,rcontext(tcr.save_tsp))
1243        __(movq %imm1,rcontext(tcr.next_tsp))
1244        __(jmp *%ra0)
1245local_label(_throw_multiple):
1246        __(lea local_label(_threw_multiple)(%rip),%ra0)
1247        __(jmp _SPnthrowvalues)
1248__(tra(local_label(_threw_multiple)))
1249        __(movq rcontext(tcr.catch_top),%temp0)
1250        __(movq catch_frame.db_link(%temp0),%imm0)
1251        __(movq rcontext(tcr.db_link),%imm1)
1252        __(cmpq %imm0,%imm1)
1253        __(je local_label(_threw_multiple_dont_unbind))
1254        __(leaq local_label(_threw_multiple_dont_unbind)(%rip),%ra0)
1255        __(push %ra0)
1256        __(jmp _SPunbind_to)
1257__(tra(local_label(_threw_multiple_dont_unbind)))
1258        /* Copy multiple values from the current %rsp to the target %rsp   */
1259        __(lea (%rsp,%nargs_q),%imm0)
1260        __(movq catch_frame.rsp(%temp0),%imm1)
1261        __(jmp local_label(_threw_multiple_push_test))
1262local_label(_threw_multiple_push_loop):
1263        __(subq $node_size,%imm0)
1264        __(subq $node_size,%imm1)
1265        __(movq (%imm0),%arg_z)
1266        __(movq %arg_z,(%imm1))
1267local_label(_threw_multiple_push_test):         
1268        __(cmpq %imm0,%rsp)
1269        __(jne local_label(_threw_multiple_push_loop))
1270        /* target %rsp is now in %imm1   */
1271        __(movq catch_frame.rbp(%temp0),%rbp)
1272        __(movq catch_frame.foreign_sp(%temp0),%imm0)
1273        __(movq %imm0,rcontext(tcr.foreign_sp))       
1274        __(movq catch_frame.xframe(%temp0),%imm0)
1275        __(movq %imm0,rcontext(tcr.xframe))
1276        __(movq %imm1,%rsp)
1277        __(movq catch_frame.link(%temp0),%imm1)         
1278        __(movq catch_frame._save0(%temp0),%save0)
1279        __(movq catch_frame._save1(%temp0),%save1)
1280        __(movq catch_frame._save2(%temp0),%save2)
1281        __ifndef([WINDOWS])
1282        __(movq catch_frame._save3(%temp0),%save3)
1283        __endif
1284        __(movq %imm1,rcontext(tcr.catch_top))
1285        __(movq catch_frame.pc(%temp0),%ra0)
1286        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1287        __(movq (%imm1),%imm1)
1288        __(movq %imm1,rcontext(tcr.save_tsp))
1289        __(movq %imm1,rcontext(tcr.next_tsp))
1290        __(jmp *%ra0)
1291_endsubp(throw)
1292
1293/* This takes N multiple values atop the vstack.   */
1294_spentry(nthrowvalues)
1295        __(movb $1,rcontext(tcr.unwinding))
1296local_label(_nthrowv_nextframe):
1297        __(subq $fixnumone,%imm0)
1298        __(js local_label(_nthrowv_done))
1299        __(movd %imm0,%mm1)
1300        __(movq rcontext(tcr.catch_top),%temp0)
1301        __(movq catch_frame.link(%temp0),%imm1)
1302        __(movq catch_frame.db_link(%temp0),%imm0)
1303        __(movq %imm1,rcontext(tcr.catch_top))
1304        __(cmpq %imm0,rcontext(tcr.db_link))
1305        __(jz local_label(_nthrowv_dont_unbind))
1306        __(push %ra0)
1307        __(leaq local_label(_nthrowv_back_from_unbind)(%rip),%ra0)
1308        __(push %ra0)
1309        __(jmp _SPunbind_to)
1310__(tra(local_label(_nthrowv_back_from_unbind)))
1311
1312        __(pop %ra0)
1313local_label(_nthrowv_dont_unbind):
1314        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1315        __(je local_label(_nthrowv_do_unwind))
1316/* A catch frame.  If the last one, restore context from there.   */
1317        __(movd %mm1,%imm0)
1318        __(testq %imm0,%imm0)   /* last catch frame ?   */
1319        __(jne local_label(_nthrowv_skip))
1320        __(movq catch_frame.xframe(%temp0),%save0)
1321        __(movq %save0,rcontext(tcr.xframe))
1322        __(leaq (%rsp,%nargs_q),%save1)
1323        __(movq catch_frame.rsp(%temp0),%save2)
1324        __(movq %nargs_q,%save0)
1325        __(jmp local_label(_nthrowv_push_test))
1326local_label(_nthrowv_push_loop):
1327        __(subq $node_size,%save1)
1328        __(subq $node_size,%save2)
1329        __(movq (%save1),%temp1)
1330        __(movq %temp1,(%save2))
1331local_label(_nthrowv_push_test):
1332        __(subq $node_size,%save0)
1333        __(jns local_label(_nthrowv_push_loop))
1334        __(movq catch_frame.xframe(%temp0),%save0)
1335        __(movq %save0,rcontext(tcr.xframe))
1336        __(movq %save2,%rsp)
1337        __(movq catch_frame.rbp(%temp0),%rbp)
1338        __ifndef([WINDOWS])
1339        __(movq catch_frame._save3(%temp0),%save3)
1340        __endif
1341        __(movq catch_frame._save2(%temp0),%save2)
1342        __(movq catch_frame._save1(%temp0),%save1)
1343        __(movq catch_frame._save0(%temp0),%save0)
1344        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1345        __(movq %stack_temp,rcontext(tcr.foreign_sp))       
1346local_label(_nthrowv_skip):     
1347        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1348        __(movq %imm1,rcontext(tcr.save_tsp))       
1349        __(movq %imm1,rcontext(tcr.next_tsp))
1350        __(movd %mm1,%imm0)
1351        __(jmp local_label(_nthrowv_nextframe))
1352local_label(_nthrowv_do_unwind):       
1353/* This is harder.  Call the cleanup code with the multiple values and   */
1354/* nargs, the throw count, and the caller's return address in a temp  */
1355/* stack frame.   */
1356        __(leaq (%rsp,%nargs_q),%save1)
1357        __(push catch_frame._save0(%temp0))
1358        __(push catch_frame._save1(%temp0))
1359        __(push catch_frame._save2(%temp0))
1360        __ifndef([WINDOWS])
1361        __(push catch_frame._save3(%temp0))
1362        __endif
1363        __(push catch_frame.pc(%temp0))
1364        __(movq catch_frame.rbp(%temp0),%rbp)
1365        __(movq catch_frame.xframe(%temp0),%stack_temp)
1366        __(movq catch_frame.rsp(%temp0),%arg_x)
1367        __(movq %stack_temp,rcontext(tcr.xframe))
1368        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1369        __(movq %stack_temp,rcontext(tcr.foreign_sp))       
1370        /* Discard the catch frame, so we can build a temp frame   */
1371        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1372        __(movq %imm1,rcontext(tcr.save_tsp))
1373        __(movq %imm1,rcontext(tcr.next_tsp))
1374        /* tsp overhead, nargs, throw count, ra0   */
1375        __(dnode_align(%nargs_q,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1376        __(TSP_Alloc_Var(%imm0,%imm1))
1377
1378        __(movq %nargs_q,(%imm1))
1379        __(movq %ra0,node_size(%imm1))
1380        __(movq %mm1,node_size*2(%imm1))
1381        __(leaq node_size*3(%imm1),%imm1)
1382        __(jmp local_label(_nthrowv_tpushtest))
1383local_label(_nthrowv_tpushloop):
1384        __(movq -node_size(%save1),%temp0)
1385        __(subq $node_size,%save1)
1386        __(movq %temp0,(%imm1))
1387        __(addq $node_size,%imm1)
1388local_label(_nthrowv_tpushtest):
1389        __(subl $node_size,%nargs)
1390        __(jns local_label(_nthrowv_tpushloop))
1391        __(pop %xfn)
1392        __ifndef([WINDOWS])
1393        __(pop %save3)
1394        __endif
1395        __(pop %save2)
1396        __(pop %save1)
1397        __(pop %save0)
1398        __(movq %arg_x,%rsp)
1399/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1400        __(leaq local_label(_nthrowv_called_cleanup)(%rip),%ra0)
1401        __(push %ra0)
1402        __(movb $0,rcontext(tcr.unwinding))
1403        __(jmp *%xfn)
1404__(tra(local_label(_nthrowv_called_cleanup)))
1405
1406        __(movb $1,rcontext(tcr.unwinding))
1407        __(movq rcontext(tcr.save_tsp),%imm1)
1408        __(movq tsp_frame.data_offset+(0*node_size)(%imm1),%nargs_q)
1409        __(movq tsp_frame.data_offset+(1*node_size)(%imm1),%ra0)
1410        __(movq tsp_frame.data_offset+(2*node_size)(%imm1),%mm1)
1411        __(movq %nargs_q,%imm0)
1412        __(addq $tsp_frame.fixed_overhead+(node_size*3),%imm1)
1413        __(jmp local_label(_nthrowv_tpoptest))
1414local_label(_nthrowv_tpoploop):
1415        __(push (%imm1))
1416        __(addq $node_size,%imm1)
1417local_label(_nthrowv_tpoptest):
1418        __(subq $node_size,%imm0)
1419        __(jns local_label(_nthrowv_tpoploop))
1420        __(movq rcontext(tcr.save_tsp),%imm1)
1421        __(movq (%imm1),%imm1)
1422        __(movq %imm1,rcontext(tcr.save_tsp))
1423        __(movq %imm1,rcontext(tcr.next_tsp))
1424        __(movd %mm1,%imm0)
1425        __(jmp local_label(_nthrowv_nextframe))
1426local_label(_nthrowv_done):
1427        __(movb $0,rcontext(tcr.unwinding))
1428        __(check_pending_interrupt(%imm0))
1429local_label(_nthrowv_return):   
1430        __(jmp *%ra0)   
1431_endsubp(nthrowvalues)
1432
1433/* This is a (slight) optimization.  When running an unwind-protect,  */
1434/* save the single value and the throw count in the tstack frame.  */
1435/* Note that this takes a single value in arg_z.  */
1436       
1437_spentry(nthrow1value)
1438        __(movb $1,rcontext(tcr.unwinding))
1439local_label(_nthrow1v_nextframe):
1440        __(subq $fixnumone,%imm0)
1441        __(js local_label(_nthrow1v_done))
1442        __(movd %imm0,%mm1)
1443        __(movq rcontext(tcr.catch_top),%temp0)
1444        __(movq catch_frame.link(%temp0),%imm1)
1445        __(movq catch_frame.db_link(%temp0),%imm0)
1446        __(movq %imm1,rcontext(tcr.catch_top))
1447        __(cmpq %imm0,rcontext(tcr.db_link))
1448        __(jz local_label(_nthrow1v_dont_unbind))
1449        __(push %ra0)
1450        __(leaq local_label(_nthrow1v_back_from_unbind)(%rip),%ra0)
1451        __(push %ra0)
1452        __(jmp _SPunbind_to)
1453__(tra(local_label(_nthrow1v_back_from_unbind)))
1454
1455        __(pop %ra0)
1456local_label(_nthrow1v_dont_unbind):
1457        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1458        __(je local_label(_nthrow1v_do_unwind))
1459/* A catch frame.  If the last one, restore context from there.   */
1460        __(movd %mm1,%imm0)
1461        __(testq %imm0,%imm0)   /* last catch frame ?   */
1462        __(jne local_label(_nthrow1v_skip))
1463        __(movq catch_frame.xframe(%temp0),%save0)
1464        __(movq %save0,rcontext(tcr.xframe))
1465        __(leaq (%rsp,%nargs_q),%save1)
1466        __(movq catch_frame.xframe(%temp0),%save0)
1467        __(movq %save0,rcontext(tcr.xframe))
1468        __(movq catch_frame.rsp(%temp0),%rsp)
1469        __(movq catch_frame.rbp(%temp0),%rbp)
1470        __ifndef([WINDOWS])
1471        __(movq catch_frame._save3(%temp0),%save3)
1472        __endif
1473        __(movq catch_frame._save2(%temp0),%save2)
1474        __(movq catch_frame._save1(%temp0),%save1)
1475        __(movq catch_frame._save0(%temp0),%save0)
1476        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1477        __(movq %stack_temp,rcontext(tcr.foreign_sp))       
1478local_label(_nthrow1v_skip):   
1479        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1480        __(movq %imm1,rcontext(tcr.save_tsp))
1481        __(movq %imm1,rcontext(tcr.next_tsp))       
1482        __(movd %mm1,%imm0)
1483        __(jmp local_label(_nthrow1v_nextframe))
1484local_label(_nthrow1v_do_unwind):
1485       
1486/* This is harder, but not as hard (not as much BLTing) as the  */
1487/* multiple-value case.  */
1488       
1489        __(movq catch_frame.xframe(%temp0),%save0)
1490        __(movq %save0,rcontext(tcr.xframe))
1491        __(movq catch_frame._save0(%temp0),%save0)
1492        __(movq catch_frame._save1(%temp0),%save1)
1493        __(movq catch_frame._save2(%temp0),%save2)
1494        __ifndef([WINDOWS])
1495        __(movq catch_frame._save3(%temp0),%save3)
1496        __endif
1497        __(movq catch_frame.pc(%temp0),%xfn)
1498        __(movq catch_frame.rbp(%temp0),%rbp)
1499        __(movq catch_frame.rsp(%temp0),%rsp)
1500        __(movq catch_frame.foreign_sp(%temp0),%stack_temp)
1501        __(movq %stack_temp,rcontext(tcr.foreign_sp))       
1502        /* Discard the catch frame, so we can build a temp frame   */
1503        __(movq -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm1)
1504        __(movq %imm1,rcontext(tcr.save_tsp))
1505        __(movq %imm1,rcontext(tcr.next_tsp))       
1506        __(TSP_Alloc_Fixed((3*node_size),%imm1))
1507        __(addq $tsp_frame.fixed_overhead,%imm1)
1508        __(movq %ra0,(%imm1))
1509        __(movq %mm1,node_size*1(%imm1))
1510        __(movq %arg_z,node_size*2(%imm1))
1511/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1512        __(leaq local_label(_nthrow1v_called_cleanup)(%rip),%ra0)
1513        __(movb $0,rcontext(tcr.unwinding))
1514        __(push %ra0)
1515        __(jmp *%xfn)
1516__(tra(local_label(_nthrow1v_called_cleanup)))
1517
1518        __(movb $1,rcontext(tcr.unwinding))
1519        __(movq rcontext(tcr.save_tsp),%imm1)
1520        __(movq tsp_frame.data_offset+(0*node_size)(%imm1),%ra0)
1521        __(movq tsp_frame.data_offset+(1*node_size)(%imm1),%mm1)
1522        __(movq tsp_frame.data_offset+(2*node_size)(%imm1),%arg_z)
1523
1524        __(movq (%imm1),%imm1)
1525        __(movq %imm1,rcontext(tcr.save_tsp))
1526        __(movq %imm1,rcontext(tcr.next_tsp))       
1527        __(movd %mm1,%imm0)
1528        __(jmp local_label(_nthrow1v_nextframe))
1529local_label(_nthrow1v_done):
1530        __(movb $0,rcontext(tcr.unwinding))
1531        __(check_pending_interrupt(%imm0))
1532local_label(_nthrow1v_return): 
1533        __(jmp *%ra0)   
1534_endsubp(nthrow1value)
1535
1536/* This never affects the symbol's vcell   */
1537/* Non-null symbol in arg_y, new value in arg_z           */
1538       
1539_spentry(bind)
1540        __(movq symbol.binding_index(%arg_y),%temp0)
1541        __(cmpq rcontext(tcr.tlb_limit),%temp0)
1542        __(jb,pt 0f)
1543        __(push %temp0)
1544        __(tlb_too_small())
15450:      __(testq %temp0,%temp0)
1546        __(jz 9f)
1547        __(movq rcontext(tcr.tlb_pointer),%temp1)
1548        __(push (%temp1,%temp0))
1549        __(push %temp0)
1550        __(push rcontext(tcr.db_link))
1551        __(movq %rsp,rcontext(tcr.db_link))
1552        __(movq %arg_z,(%temp1,%temp0))
1553        __(jmp *%ra0)
15549:     
1555        __(movq %arg_y,%arg_z)
1556        __(movq $XSYMNOBIND,%arg_y)
1557        __(set_nargs(2))
1558        __(push %ra0)
1559        __(jmp _SPksignalerr)   
1560_endsubp(bind)
1561
1562/* arg_z = symbol: bind it to its current value  */
1563       
1564_spentry(bind_self)
1565        __(movq symbol.binding_index(%arg_z),%temp0)
1566        __(cmpq rcontext(tcr.tlb_limit),%temp0)
1567        __(jb,pt 0f)
1568        __(push %temp0)
1569        __(tlb_too_small())
15700:      __(testq %temp0,%temp0)
1571        __(jz 9f)
1572        __(movq rcontext(tcr.tlb_pointer),%temp1)
1573        __(cmpb $no_thread_local_binding_marker,(%temp0,%temp1))
1574        __(jz 2f)
1575        __(push (%temp1,%temp0))
1576        __(push %temp0)
1577        __(push rcontext(tcr.db_link))
1578        __(movq %rsp,rcontext(tcr.db_link))
1579        __(jmp *%ra0)
15802:      __(movq symbol.vcell(%arg_z),%arg_y)
1581        __(push (%temp1,%temp0))
1582        __(push %temp0)
1583        __(push rcontext(tcr.db_link))
1584        __(movq %arg_y,(%temp1,%temp0))
1585        __(movq %rsp,rcontext(tcr.db_link))
1586        __(jmp *%ra0)
15879:      __(movq $XSYMNOBIND,%arg_y)
1588        __(set_nargs(2))
1589        __(push %ra0)
1590        __(jmp _SPksignalerr)
1591_endsubp(bind_self)
1592
1593_spentry(bind_nil)
1594        __(movq symbol.binding_index(%arg_z),%temp0)
1595        __(cmpq rcontext(tcr.tlb_limit),%temp0)
1596        __(jb,pt 0f)
1597        __(push %temp0)
1598        __(tlb_too_small())
15990:      __(testq %temp0,%temp0)
1600        __(jz 9f)
1601        __(movq rcontext(tcr.tlb_pointer),%temp1)
1602        __(push (%temp1,%temp0))
1603        __(push %temp0)
1604        __(push rcontext(tcr.db_link))
1605        __(movq %rsp,rcontext(tcr.db_link))
1606        __(movq $nil_value,(%temp1,%temp0))
1607        __(jmp *%ra0)
16089:      __(movq $XSYMNOBIND,%arg_y)
1609        __(set_nargs(2))
1610        __(push %ra0)
1611        __(jmp _SPksignalerr)
1612_endsubp(bind_nil)
1613
1614_spentry(bind_self_boundp_check)
1615        __(movq symbol.binding_index(%arg_z),%temp0)
1616        __(cmpq rcontext(tcr.tlb_limit),%temp0)
1617        __(jb,pt 0f)
1618        __(push %temp0)
1619        __(tlb_too_small())
16200:      __(testq %temp0,%temp0)
1621        __(jz 9f)
1622        __(movq rcontext(tcr.tlb_pointer),%temp1)
1623        __(cmpb $no_thread_local_binding_marker,(%temp1,%temp0))
1624        __(je 2f)
1625        __(cmpb $unbound_marker,(%temp1,%temp0))
1626        __(je 8f)
1627        __(push (%temp1,%temp0))
1628        __(push %temp0)
1629        __(push rcontext(tcr.db_link))
1630        __(movq %rsp,rcontext(tcr.db_link))
1631        __(jmp *%ra0)
16322:      __(movq symbol.vcell(%arg_z),%arg_y)
1633        __(cmpb $unbound_marker,%arg_y_b)
1634        __(jz 8f)
1635        __(push (%temp1,%temp0))
1636        __(push %temp0)
1637        __(push rcontext(tcr.db_link))
1638        __(movq %rsp,rcontext(tcr.db_link))
1639        __(movq %arg_y,(%temp1,%temp0))
1640        __(jmp *%ra0)
16418:      __(push %ra0)
1642        __(uuo_error_reg_unbound(Rarg_z))
1643       
16449:      __(movq $XSYMNOBIND,%arg_y)
1645        __(set_nargs(2))
1646        __(push %ra0)
1647        __(jmp _SPksignalerr)
1648_endsubp(bind_self_boundp_check)
1649
1650_spentry(conslist)
1651        __(movl $nil_value,%arg_z_l)
1652        __(testl %nargs,%nargs)
1653        __(jmp 2f)
16541:      __(pop %arg_y)
1655        __(Cons(%arg_y,%arg_z,%arg_z))
1656        __(subl $node_size,%nargs)
16572:      __(jnz 1b)
1658        __(jmp *%ra0)           
1659_endsubp(conslist)
1660
1661/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1662/* Cons, one cons cell at at time.  Maybe optimize this later.  */
1663       
1664_spentry(conslist_star)
1665        __(testl %nargs,%nargs)
1666        __(jmp 2f)
16671:      __(pop %arg_y)
1668        __(Cons(%arg_y,%arg_z,%arg_z))
1669        __(subl $node_size,%nargs)
16702:      __(jnz 1b)
1671        __(jmp *%ra0)           
1672_endsubp(conslist_star)
1673
1674/* We always have to create a tsp frame (even if nargs is 0), so the compiler   */
1675/* doesn't get confused.   */
1676_spentry(stkconslist)
1677        __(movq %nargs_q,%imm1)
1678        __(addq %imm1,%imm1)
1679        __(movl $nil_value,%arg_z_l)
1680        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm1))
1681        __(TSP_Alloc_Var(%imm1,%imm0))
1682        __(addq $fulltag_cons,%imm0)
1683        __(testl %nargs,%nargs)
1684        __(jmp 2f)
16851:      __(pop %temp0)
1686        __(_rplaca(%imm0,%temp0))
1687        __(_rplacd(%imm0,%arg_z))
1688        __(movq %imm0,%arg_z)
1689        __(add $cons.size,%imm0)
1690        __(subl $node_size,%nargs)
16912:      __(jne 1b)
1692        __(jmp *%ra0)
1693_endsubp(stkconslist)
1694
1695/* do list*: last arg in arg_z, all others vpushed,   */
1696/*      nargs set to #args vpushed.  */
1697       
1698_spentry(stkconslist_star)
1699        __(movq %nargs_q,%imm1)
1700        __(addq %imm1,%imm1)
1701        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm1))
1702        __(TSP_Alloc_Var(%imm1,%imm0))
1703        __(addq $fulltag_cons,%imm0)
1704        __(testl %nargs,%nargs)
1705        __(jmp 2f)
17061:      __(pop %temp0)
1707        __(_rplaca(%imm0,%temp0))
1708        __(_rplacd(%imm0,%arg_z))
1709        __(movq %imm0,%arg_z)
1710        __(addq $cons.size,%imm0)
1711        __(subl $node_size,%nargs)
17122:      __(jne 1b)
1713        __(jmp *%ra0)
1714_endsubp(stkconslist_star)
1715
1716/* Make a stack-consed simple-vector out of the NARGS objects   */
1717/*      on top of the vstack; return it in arg_z.  */
1718       
1719_spentry(mkstackv)
1720        __(dnode_align(%nargs_q,tsp_frame.fixed_overhead+node_size,%imm1))
1721        __(TSP_Alloc_Var(%imm1,%temp0))
1722        __(movl %nargs,%imm0_l)
1723        __(shlq $(num_subtag_bits-fixnumshift),%imm0)
1724        __(movb $subtag_simple_vector,%imm0_b)
1725        __(movq %imm0,(%temp0))
1726        __(leaq fulltag_misc(%temp0),%arg_z)
1727        __(testl %nargs,%nargs)
1728        __(leaq misc_data_offset(%arg_z,%nargs_q),%imm1)
1729        __(jmp 2f)
17301:      __(pop -node_size(%imm1))
1731        __(subl $node_size,%nargs)
1732        __(leaq -node_size(%imm1),%imm1)
17332:      __(jne 1b)
1734        __(jmp *%ra0)   
1735_endsubp(mkstackv)
1736
1737       
1738        .globl C(egc_write_barrier_start)
1739C(egc_write_barrier_start):
1740/*  */
1741/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1742/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1743/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1744/* an intergenerational reference (a young pointer stored in an old object) has  */
1745/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1746/* This has to happen atomically, and has to happen atomically wrt GC.  */
1747
1748/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1749/* interlocked loads and stores.  */
1750
1751
1752
1753/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1754/* in the function, we can do the store (even if it's already been done) and  */
1755/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1756/* setting the bit needs to be done atomically, unless we're sure that other  */
1757/* threads are suspended.)  */
1758/* We can unconditionally set the suspended thread's RIP to the return address.  */
1759
1760       
1761_spentry(rplaca)
1762        .globl C(egc_rplaca)
1763C(egc_rplaca):
1764        __(rcmpq(%arg_z,%arg_y))
1765        __(_rplaca(%arg_y,%arg_z))
1766        __(ja 1f)
17670:      __(repret)
17681:      __(movq %arg_y,%imm0)
1769        __(subq lisp_global(heap_start),%imm0)
1770        __(shrq $dnode_shift,%imm0)
1771        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1772        __(jae 0b)
1773        __(ref_global(refbits,%temp0))
1774        __(xorb $63,%imm0_b)
1775        __(lock)
1776        __(btsq %imm0,(%temp0))
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        __(xorb $63,%imm0_b)
1794        __(lock)
1795        __(btsq %imm0,(%temp0))
1796        __(ret)
1797_endsubp(rplacd)
1798
1799/* Storing into a gvector can be handled the same way as storing into a CONS.  */
1800
1801
1802_spentry(gvset)
1803        .globl C(egc_gvset)
1804C(egc_gvset):
1805        __(rcmpq(%arg_z,%arg_x))
1806        __(movq %arg_z,misc_data_offset(%arg_x,%arg_y))
1807        __(ja 1f)
18080:      __(repret)
18091:      __(lea misc_data_offset(%arg_x,%arg_y),%imm0)
1810        __(subq lisp_global(heap_start),%imm0)
1811        __(shrq $dnode_shift,%imm0)
1812        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1813        __(jae 0b)
1814        __(ref_global(refbits,%temp0))
1815        __(xorb $63,%imm0_b)
1816        __(lock)
1817        __(btsq %imm0,(%temp0))
1818        __(ret)               
1819_endsubp(gvset)
1820
1821/* This is a special case of storing into a gvector: if we need to  */
1822/* memoize the store, record the address of the hash-table vector  */
1823/* in the refmap, as well.  */
1824       
1825
1826_spentry(set_hash_key)
1827        .globl C(egc_set_hash_key)
1828C(egc_set_hash_key): 
1829        __(rcmpq(%arg_z,%arg_x))
1830        __(movq %arg_z,misc_data_offset(%arg_x,%arg_y))
1831        __(ja 1f)
18320:      __(repret)
18331:      __(lea misc_data_offset(%arg_x,%arg_y),%imm0)
1834        __(subq lisp_global(heap_start),%imm0)
1835        __(shrq $dnode_shift,%imm0)
1836        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1837        __(jae 0b)
1838        __(ref_global(refbits,%temp0))
1839        __(xorb $63,%imm0_b)
1840        __(lock)
1841        __(btsq %imm0,(%temp0))
1842        /* Now memoize the address of the hash vector   */
1843        __(movq %arg_x,%imm0)
1844        __(subq lisp_global(heap_start),%imm0)
1845        __(shrq $dnode_shift,%imm0)
1846        __(xorb $63,%imm0_b)
1847        __(lock)
1848        __(btsq %imm0,(%temp0))
1849        __(ret)               
1850_endsubp(set_hash_key)
1851
1852/* This is a little trickier: if this is interrupted, we need to know  */
1853/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1854/* If we're interrupted   before the PC has reached the "success_test" label,   */
1855/* repeat (luser the PC back to .SPstore_node_conditional.)  If we're at that  */
1856/* label with the Z flag set, we won and (may) need to memoize.  */
1857
1858_spentry(store_node_conditional)
1859        .globl C(egc_store_node_conditional)
1860C(egc_store_node_conditional):
1861        __(unbox_fixnum(%temp0,%imm1))
18620:      __(movq (%arg_x,%imm1),%temp1)
1863        __(cmpq %arg_y,%temp1)
1864        __(movq %temp1,%imm0)
1865        __(jne 3f)
1866        __(lock)
1867        __(cmpxchgq %arg_z,(%arg_x,%imm1))
1868        .globl C(egc_store_node_conditional_success_test)
1869C(egc_store_node_conditional_success_test):
1870        __(jne 0b)
1871        __(lea (%arg_x,%imm1),%imm0)
1872        __(subq lisp_global(heap_start),%imm0)
1873        __(shrq $dnode_shift,%imm0)
1874        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1875        __(ref_global(refbits,%temp1))
1876        __(jae 2f)
1877        __(xorb $63,%imm0_b)
1878        __(lock)
1879        __(btsq %imm0,(%temp1))
1880        .globl C(egc_write_barrier_end)
1881C(egc_write_barrier_end):
18822:      __(movl $t_value,%arg_z_l)
1883        __(ret)
18843:      __(movl $nil_value,%arg_z_l)
1885        __(ret)
1886_endsubp(store_node_conditional)
1887                               
1888_spentry(setqsym)
1889        __(btq $sym_vbit_const,symbol.flags(%arg_y))
1890        __(jae _SPspecset)
1891        __(movq %arg_y,%arg_z)
1892        __(movq $XCONST,%arg_y)
1893        __(set_nargs(2))
1894        __(jmp _SPksignalerr)
1895_endsubp(setqsym)
1896
1897_spentry(progvsave)
1898        /* Error if arg_z isn't a proper list.  That's unlikely,  */
1899        /* but it's better to check now than to crash later.  */
1900       
1901        __(compare_reg_to_nil(%arg_z))
1902        __(movq %arg_z,%arg_x)  /* fast   */
1903        __(movq %arg_z,%temp1)  /* slow   */
1904        __(je 9f)               /* Null list is proper   */
19050:
1906        __(extract_lisptag(%arg_x,%imm0))
1907        __(cmpb $tag_list,%imm0_b)
1908        __(jne 8f)
1909        __(compare_reg_to_nil(%arg_x))
1910        __(je 9f)
1911        __(_cdr(%arg_x,%temp0)) /* (null (cdr fast)) ?   */
1912        __(compare_reg_to_nil(%temp0))
1913        __(je 9f)
1914        __(extract_lisptag(%temp0,%imm0))
1915        __(cmpb $tag_list,%imm0_b)
1916        __(jne 8f)
1917        __(_cdr(%temp0,%arg_x))
1918        __(_cdr(%temp1,%temp1))
1919        __(cmpq %temp1,%arg_x)
1920        __(jne 0b)
1921
19228:      __(movq $XIMPROPERLIST,%arg_y)
1923        __(set_nargs(2))
1924        __(jmp _SPksignalerr)
19259:      /* Whew           */
1926
1927        /* Next, determine the length of arg_y.  We   */
1928        /* know that it's a proper list.   */
1929        __(movq $-fixnumone,%imm0)
1930        __(movq %arg_y,%arg_x)
19311:      __(compare_reg_to_nil(%arg_x))
1932        __(_cdr(%arg_x,%arg_x))
1933        __(leaq fixnumone(%imm0),%imm0)
1934        __(jne 1b)
1935       
1936        /* imm0 is now (boxed) triplet count.  */
1937        /* Determine word count, add 1 (to align), and make room.  */
1938        /*  if count is 0, make an empty tsp frame and exit   */
1939        __(testq %imm0,%imm0)
1940        __(jne 2f)
1941        __(TSP_Alloc_Fixed(2*node_size,%imm0))
1942        __(ret)
19432:      __(movq %imm0,%imm1)
1944        __(add %imm1,%imm1)
1945        __(add %imm0,%imm1)
1946        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
1947        __(TSP_Alloc_Var(%imm1,%temp0))
1948        __(movq %imm0,(%temp0))
1949        __(movq rcontext(tcr.db_link),%temp1)
19503:      __(movl $unbound_marker,%temp0_l)
1951        __(compare_reg_to_nil(%arg_z))
1952        __(cmovneq cons.car(%arg_z),%temp0)
1953        __(cmovneq cons.cdr(%arg_z),%arg_z)
1954        __(_car(%arg_y,%arg_x))
1955        __(_cdr(%arg_y,%arg_y))
1956        __(movq symbol.binding_index(%arg_x),%arg_x)
1957        __(cmp rcontext(tcr.tlb_limit),%arg_x)
1958        __(jb,pt 4f)
1959        __(push %arg_x)
1960        __(tlb_too_small())
19614:      __(movq rcontext(tcr.tlb_pointer),%imm0)
1962        __(subq $binding.size,%imm1)
1963        __(compare_reg_to_nil(%arg_y))
1964        __(movq %arg_x,binding.sym(%imm1))
1965        __(push (%imm0,%arg_x))
1966        __(pop binding.val(%imm1))
1967        __(movq %temp0,(%imm0,%arg_x))
1968        __(movq %temp1,binding.link(%imm1))
1969        __(movq %imm1,%temp1)
1970        __(jne 3b)
1971        __(movq %temp1,rcontext(tcr.db_link))
1972        __(ret)
1973_endsubp(progvsave)
1974
1975/* Allocate node objects on the temp stack, immediate objects on the foreign  */
1976/* stack. (The caller has to know which stack to discard a frame from.)  */
1977/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
1978       
1979_spentry(stack_misc_alloc)
1980        __(movq $~(((1<<56)-1)<<fixnumshift),%temp0)
1981        __(testq %temp0,%arg_y)
1982        __(jne local_label(stack_misc_alloc_not_u56))
1983        __(unbox_fixnum(%arg_z,%imm0))
1984        __(movq %arg_y,%temp0)
1985        __(shl $num_subtag_bits-fixnumshift,%temp0)
1986        __(orq %temp0,%imm0)            /* %imm0 now = header   */
1987        __(movb $fulltagmask,%imm1_b)
1988        __(andb %imm0_b,%imm1_b)
1989        __(cmpb $fulltag_nodeheader_0,%imm1_b)
1990        __(je local_label(stack_misc_alloc_node))
1991        __(cmpb $fulltag_nodeheader_1,%imm1_b)
1992        __(je local_label(stack_misc_alloc_node))
1993        __(cmpb $ivector_class_64_bit,%imm1_b)
1994        __(jz local_label(stack_misc_alloc_64))
1995        __(cmpb $ivector_class_32_bit,%imm1_b)
1996        __(jz local_label(stack_misc_alloc_32))
1997        __(unbox_fixnum(%arg_y,%imm1))
1998        /* ivector_class_other_bit: 16, 8, or 1 ...   */
1999        __(cmpb $subtag_bit_vector,%imm0_b)
2000        __(jne local_label(stack_misc_alloc_8))
2001        __(addq $7,%imm1)
2002        __(shrq $3,%imm1)
2003        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2004local_label(stack_misc_alloc_8):       
2005        __(cmpb $subtag_simple_base_string,%imm0_b)
2006        __(jb local_label(stack_misc_alloc_16))
2007        __(unbox_fixnum(%arg_y,%imm1))
2008        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2009local_label(stack_misc_alloc_16):       
2010        __(unbox_fixnum(%arg_y,%imm1))
2011        __(shlq %imm1)
2012        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2013local_label(stack_misc_alloc_32):
2014        /* 32-bit ivector   */
2015        __(unbox_fixnum(%arg_y,%imm1))
2016        __(shlq $2,%imm1)
2017        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2018local_label(stack_misc_alloc_64):
2019        /* 64-bit ivector         */
2020        __(movq %arg_y,%imm1)
2021local_label(stack_misc_alloc_alloc_ivector):   
2022        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2023        __(cmpq $tstack_alloc_limit,%imm1)
2024        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
2025        __(movq rcontext(tcr.foreign_sp),%stack_temp)
2026        __(movd %stack_temp,%temp1)
2027        __(subq %imm1,rcontext(tcr.foreign_sp))
2028        __(movq rcontext(tcr.foreign_sp),%temp0)
20290:      __(movapd %fpzero,-dnode_size(%temp1))
2030        __(subq $dnode_size,%temp1)
2031        __(cmpq %temp1,%temp0)
2032        __(jnz 0b)     
2033        __(movq %stack_temp,(%temp0))
2034        __(movq %rbp,csp_frame.save_rbp(%temp0))
2035        __(movq %imm0,csp_frame.fixed_overhead(%temp0))
2036        __(leaq csp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
2037        __(ret)
2038local_label(stack_misc_alloc_heap_alloc_ivector):
2039        __(movq rcontext(tcr.foreign_sp),%imm1)
2040        __(subq $dnode_size,rcontext(tcr.foreign_sp))
2041        __(movq rcontext(tcr.foreign_sp),%imm0)
2042        __(movq %imm1,(%imm0))
2043        __(jmp _SPmisc_alloc)   
2044local_label(stack_misc_alloc_node):
2045        __(movq %arg_y,%imm1)
2046        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2047        __(cmpq $tstack_alloc_limit,%imm1)
2048        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
2049        __(TSP_Alloc_Var(%imm1,%temp0))
2050        __(movq %imm0,(%temp0))
2051        __(leaq fulltag_misc(%temp0),%arg_z)
2052        __(ret)
2053local_label(stack_misc_alloc_heap_alloc_gvector):       
2054        __(TSP_Alloc_Fixed(0,%imm0))
2055        __(jmp _SPmisc_alloc)   
2056               
2057local_label(stack_misc_alloc_not_u56):                         
2058        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_56))   
2059_endsubp(stack_misc_alloc)
2060
2061/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of   */
2062/* initial-contents.  Note that this can be used to cons any type of initialized   */
2063/* node-header'ed misc object (symbols, closures, ...) as well as vector-like   */
2064/* objects.   */
2065_spentry(gvector)
2066        __(subl $node_size,%nargs)
2067        __(movq (%rsp,%nargs_q),%imm0)  /* boxed subtype   */
2068        __(sarq $fixnumshift,%imm0)
2069        __(movq %nargs_q,%imm1)
2070        __(shlq $num_subtag_bits-word_shift,%imm1)
2071        __(orq %imm1,%imm0)
2072        __(dnode_align(%nargs_q,node_size,%imm1))
2073        __(Misc_Alloc(%arg_z))
2074        __(movq %nargs_q,%imm1)
2075        __(jmp 2f)
20761:      __(movq %temp0,misc_data_offset(%arg_z,%imm1))
20772:      __(subq $node_size,%imm1)
2078        __(pop %temp0)  /* Note the intentional fencepost:  */
2079                        /* discard the subtype as well.  */
2080        __(jge 1b)
2081        __(jmp *%ra0)
2082_endsubp(gvector)
2083
2084_spentry(mvpass)
2085        __(int $3)
2086_endsubp(mvpass)
2087
2088
2089
2090_spentry(nthvalue)
2091        __(int $3)
2092_endsubp(nthvalue)
2093
2094_spentry(values)
2095        __(movq (%temp0),%ra0)
2096        __(ref_global(ret1val_addr,%imm1))
2097        __(cmpq %imm1,%ra0)
2098        __(movl $nil_value,%arg_z_l)
2099        __(je 0f)
2100        __(testl %nargs,%nargs)
2101        __(cmovneq -node_size(%rsp,%nargs_q),%arg_z)
2102        __(movq %temp0,%rsp)
2103        __(ret)
21040:      __(movq 8(%temp0),%ra0)
2105        __(addq $2*node_size,%temp0)
2106        __(lea (%rsp,%nargs_q),%imm0)
2107        __(jmp 2f)
21081:      __(subq $node_size,%imm0)
2109        __(movq (%imm0),%temp1)
2110        __(subq $node_size,%temp0)
2111        __(movq %temp1,(%temp0))
21122:      __(cmpq %imm0,%rsp)
2113        __(jne 1b)
2114        __(movq %temp0,%rsp)
2115        __(jmp *%ra0)   
2116_endsubp(values)
2117
2118_spentry(default_optional_args)
2119        __(int $3)
2120_endsubp(default_optional_args)
2121
2122_spentry(opt_supplied_p)
2123        __(int $3)
2124_endsubp(opt_supplied_p)
2125
2126_spentry(lexpr_entry)
2127        __(int $3)
2128_endsubp(lexpr_entry)
2129       
2130_spentry(heap_rest_arg)
2131        __(push_argregs())
2132        __(movq %next_method_context,%arg_y)
2133        __(movl %nargs,%imm1_l)
2134        __(testl %imm1_l,%imm1_l)
2135        __(movl $nil_value,%arg_z_l)
2136        __(jmp 2f)
2137        .p2align 4
21381:      __(pop %temp1)
2139        __(Cons(%temp1,%arg_z,%arg_z))
2140        __(subl $node_size,%imm1_l)
21412:      __(jg 1b)
2142        __(push %arg_z)
2143        __(movq %arg_y,%next_method_context)
2144        __(jmp *%ra0)           
2145_endsubp(heap_rest_arg)
2146
2147/* %imm0 contains the number of fixed args ; make an &rest arg out of the others   */
2148_spentry(req_heap_rest_arg)
2149        __(push_argregs())
2150        __(movq %next_method_context,%arg_y)
2151        __(movl %nargs,%imm1_l)
2152        __(subl %imm0_l,%imm1_l)
2153        __(movl $nil_value,%arg_z_l)
2154        __(jmp 2f)
2155        .p2align 4
21561:      __(pop %temp1)
2157        __(Cons(%temp1,%arg_z,%arg_z))
2158        __(subl $node_size,%imm1_l)
21592:      __(jg 1b)
2160        __(push %arg_z)
2161        __(movq %arg_y,%next_method_context)
2162        __(jmp *%ra0)           
2163_endsubp(req_heap_rest_arg)
2164
2165/* %imm0 bytes of stuff has already been pushed   */
2166/* make an &rest arg out of any others   */
2167_spentry(heap_cons_rest_arg)
2168        __(movl %nargs,%imm1_l)
2169        __(subl %imm0_l,%imm1_l)
2170        __(movq %next_method_context,%arg_y)
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(heap_cons_rest_arg)
2182
2183_spentry(simple_keywords)
2184        __(xorl %imm0_l,%imm0_l)
2185        __(push_argregs())
2186        __(jmp _SPkeyword_bind)
2187_endsubp(simple_keywords)
2188
2189_spentry(keyword_args)
2190        __(push_argregs())
2191        __(jmp _SPkeyword_bind)
2192_endsubp(keyword_args)
2193
2194/* There are %nargs words of arguments on the stack; %imm0 contains the number  */
2195/* of non-keyword args pushed.  It's possible that we never actually got  */
2196/* any keyword args, which would make things much simpler.   */
2197
2198/* On entry, temp1 contains a fixnum with bits indicating whether   */
2199/* &allow-other-keys and/or &rest was present in the lambda list.  */
2200/* Once we get here, we can use the arg registers.  */
2201
2202define([keyword_flags_aok_bit],[fixnumshift])
2203define([keyword_flags_unknown_keys_bit],[fixnumshift+1])
2204define([keyword_flags_rest_bit],[fixnumshift+2])
2205define([keyword_flags_seen_aok_bit],[fixnumshift+3])       
2206       
2207_spentry(keyword_bind)
2208        __(movl %nargs,%imm1_l)
2209        __(subq %imm0,%imm1)
2210        __(jbe local_label(no_keyword_values))
2211        __(btq $word_shift,%imm1)
2212        __(jnc local_label(even))
2213        __(movl $nil_value,%arg_z_l)
2214        __(movq %imm1,%nargs_q)
2215        __(testl %nargs,%nargs)
2216        __(jmp 1f)
22170:      __(pop %arg_y)
2218        __(Cons(%arg_y,%arg_z,%arg_z))
2219        __(subl $node_size,%nargs)
22201:      __(jnz 0b)
2221        __(movl $XBADKEYS,%arg_y_l)
2222        __(set_nargs(2))
2223        __(jmp _SPksignalerr)
2224        /* Now that we're sure that we have an even number of keywords and values  */
2225        /* (in %imm1), copy all pairs to the temp stack   */
2226local_label(even):
2227        /* Get the keyword vector into arg_x, and its length into arg_y.  */
2228        __(movl function_data_offset(%fn),%imm0_l)
2229        __(movq function_data_offset(%fn,%imm0,node_size),%arg_x)
2230        __(vector_length(%arg_x,%arg_y))
2231        __(testq %arg_y,%arg_y)
2232        __(jne 1f)
2233        __(btq $keyword_flags_aok_bit,%temp1)
2234        __(jnc 1f)
2235
2236        __(btq $keyword_flags_rest_bit,%temp1)
2237        __(jc 0f)
2238        __(addq %imm1,%rsp)
22390:     
2240        __(jmp *%ra0)
22411:     
2242        __(lea tsp_frame.fixed_overhead(%imm1),%arg_z)
2243        __(TSP_Alloc_Var(%arg_z,%imm0))
22442:      __(subq $node_size,%arg_z)
2245        __(pop (%arg_z))
2246        __(cmpq %arg_z,%imm0)
2247        __(jne 2b)
2248        /* Push arg_y pairs of NILs.   */
2249        __(movq %arg_y,%imm0)
2250        __(jmp 4f)
22513:      __(push $nil_value)
2252        __(push $nil_value)
22534:      __(subq $fixnumone,%arg_y)
2254        __(jge 3b)
2255        /* Push the %saveN registers, so that we can use them in this loop   */
2256        /* Also, borrow %arg_y for a bit */
2257        __(push %arg_y)
2258        __(push %save2)
2259        __(push %save1)
2260        __(push %save0)
2261        __(leaq 4*node_size(%rsp,%imm0,2),%save0)
2262        /* %save0 points to the 0th value/supplied-p pair   */
2263        __(leaq (%arg_z,%imm1),%save1)
2264        /* %save1 is the end of the provided keyword/value pairs (the old %tsp).   */
2265        __(movq %imm0,%save2)
2266        /* %save2 is the length of the keyword vector   */
22675:      __(movq (%arg_z),%arg_y)        /* %arg_y is current keyword   */
2268        __(xorl %imm0_l,%imm0_l)
2269        __(cmpq $nrs.kallowotherkeys,%arg_y)
2270        __(jne local_label(next_keyvect_entry))
2271        __(btsq $keyword_flags_seen_aok_bit,%temp1)
2272        __(jc local_label(next_keyvect_entry))
2273        __(cmpb $fulltag_nil,node_size(%arg_z))
2274        __(je local_label(next_keyvect_entry))
2275        __(btsq $keyword_flags_aok_bit,%temp1)
2276        __(jmp local_label(next_keyvect_entry))
22776:      __(cmpq misc_data_offset(%arg_x,%imm0),%arg_y)
2278        __(jne 7f)
2279        /* Got a match; have we already seen this keyword ?   */
2280        __(negq %imm0)
2281        __(cmpb $fulltag_nil,-node_size*2(%save0,%imm0,2))
2282        __(jne 9f)      /* already seen keyword, ignore this value   */
2283        __(movq node_size(%arg_z),%arg_y)
2284        __(movq %arg_y,-node_size(%save0,%imm0,2))
2285        __(movl $t_value,-node_size*2(%save0,%imm0,2))
2286        __(jmp 9f)
22877:      __(addq $node_size,%imm0)
2288local_label(next_keyvect_entry):       
2289        __(cmpq %imm0,%save2)
2290        __(jne 6b)
2291        /* Didn't match anything in the keyword vector. Is the keyword  */
2292        /* :allow-other-keys ?   */
2293        __(cmpq $nrs.kallowotherkeys,%arg_y)
2294        __(je 9f)               /* :allow-other-keys is never "unknown" */
22958:      __(btsq $keyword_flags_unknown_keys_bit,%temp1)
22969:      __(addq $dnode_size,%arg_z)
2297        __(cmpq %arg_z,%save1)
2298        __(jne 5b)
2299        __(pop %save0)
2300        __(pop %save1)
2301        __(pop %save2)
2302        __(pop %arg_y)
2303        /* If the function takes an &rest arg, or if we got an unrecognized  */
2304        /* keyword and don't allow that, copy the incoming keyword/value  */
2305        /* pairs from the temp stack back to the value stack   */
2306        __(btq $keyword_flags_rest_bit,%temp1)
2307        __(jc 1f)
2308        __(btq $keyword_flags_unknown_keys_bit,%temp1)
2309        __(jnc 0f)
2310        __(btq $keyword_flags_aok_bit,%temp1)
2311        __(jnc 1f)
2312        /* pop the temp frame   */
23130:      __(discard_temp_frame(%imm1))
2314        __(jmp *%ra0)
2315        /* Copy the keyword/value pairs from the tsp back to sp, either because  */
2316        /* the function takes an &rest arg or because we need to signal an  */
2317        /* "unknown keywords" error   */
23181:      __(movq rcontext(tcr.save_tsp),%arg_z)
2319        __(mov (%arg_z),%arg_y)
2320        __(jmp 3f)
23212:      __(push (%arg_z))
2322        __(push node_size(%arg_z))
23233:      __(addq $dnode_size,%arg_z)
2324        __(cmpq %arg_z,%arg_y)
2325        __(jne 2b)
2326        __(discard_temp_frame(%imm0))
2327        __(btq $keyword_flags_unknown_keys_bit,%temp1)
2328        __(jnc,pt 9f)
2329        __(btq $keyword_flags_aok_bit,%temp1)
2330        __(jc,pt 9f)
2331        /* Signal an "unknown keywords" error   */
2332        __(movq %imm1,%nargs_q)
2333        __(testl %nargs,%nargs)
2334        __(movl $nil_value,%arg_z_l)
2335        __(jmp 5f)
23364:      __(pop %arg_y)
2337        __(Cons(%arg_y,%arg_z,%arg_z))
2338        __(subl $node_size,%nargs)
23395:      __(jnz 4b)
2340        __(movl $XBADKEYS,%arg_y_l)
2341        __(set_nargs(2))
2342        __(push %ra0)
2343        __(jmp _SPksignalerr)
23449:      __(jmp *%ra0)
2345       
2346/* No keyword values were provided.  Access the keyword vector (which is the 0th  */
2347/*  constant in %fn), determine its length N, and push N        pairs of NILs.   */
2348/* N could be 0 ...  */
2349       
2350local_label(no_keyword_values):         
2351        __(movl function_data_offset(%fn),%imm0_l)
2352        __(movq function_data_offset(%fn,%imm0,node_size),%arg_x)
2353        __(movl $nil_value,%arg_z_l)
2354        __(vector_length(%arg_x,%arg_y))
2355        __(jmp 1f)
23560:      __(push %arg_z)
2357        __(push %arg_z)
23581:      __(subq $fixnumone,%arg_y)
2359        __(jge 0b)
2360        __(jmp *%ra0)           
2361_endsubp(keyword_bind)
2362
2363
2364
2365_spentry(ksignalerr)
2366        __(movq $nrs.errdisp,%fname)
2367        __(jump_fname) 
2368_endsubp(ksignalerr)
2369
2370_spentry(stack_rest_arg)
2371        __(xorl %imm0_l,%imm0_l)
2372        __(push_argregs())
2373        __(jmp _SPstack_cons_rest_arg)
2374_endsubp(stack_rest_arg)
2375
2376_spentry(req_stack_rest_arg)
2377        __(push_argregs())
2378        __(jmp _SPstack_cons_rest_arg)
2379_endsubp(req_stack_rest_arg)
2380
2381_spentry(stack_cons_rest_arg)
2382        __(movl %nargs,%imm1_l)
2383        __(subl %imm0_l,%imm1_l)
2384        __(movl $nil_value,%arg_z_l)
2385        __(jle 2f)      /* empty list ; make an empty TSP frame   */
2386        __(addq %imm1,%imm1)
2387        __(cmpq $(tstack_alloc_limit-dnode_size),%imm1)
2388        __(ja 3f)       /* make empty frame, then heap-cons   */
2389        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm0))
2390        __(TSP_Alloc_Var(%imm0,%temp1))
2391        __(addq $fulltag_cons,%temp1)
23921:      __(pop %arg_x)
2393        __(_rplacd(%temp1,%arg_z))
2394        __(_rplaca(%temp1,%arg_x))
2395        __(movq %temp1,%arg_z)
2396        __(addq $cons.size,%temp1)
2397        __(subq $dnode_size,%imm1)
2398        __(jne 1b)
2399        __(push %arg_z)
2400        __(jmp *%ra0)
2401       
2402/* Length 0, make empty frame  */
2403       
24042:
2405        __(TSP_Alloc_Fixed(0,%temp1))
2406        __(push %arg_z)
2407        __(jmp *%ra0)
2408       
2409/* Too big to stack-cons, but make an empty frame before heap-consing  */
2410       
24113:             
2412        __(TSP_Alloc_Fixed(0,%temp1))
2413        __(jmp _SPheap_cons_rest_arg)
2414_endsubp(stack_cons_rest_arg)
2415
2416
2417
2418_spentry(getxlong)
2419_endsubp(getxlong)
2420
2421/* Have to be a little careful here: the caller may or may not have pushed  */
2422/*   an empty frame, and we may or may not have needed one.  We can't easily  */
2423/*   tell whether or not a frame will be needed (if the caller didn't reserve  */
2424/*   a frame, whether or not we need one depends on the length of the list  */
2425/*   in arg_z.  So, if the caller didn't push a frame, we do so ; once everything's  */
2426/*   been spread, we discard the reserved frame (regardless of who pushed it)  */
2427/*   if all args fit in registers.   */
2428_spentry(spreadargz)
2429        __(testl %nargs,%nargs)
2430        __(jne 0f)
2431        __(push $reserved_frame_marker)
2432        __(push $reserved_frame_marker)
24330:      __(movq %arg_z,%arg_y)  /* save in case of error   */
2434        __(xorl %imm0_l,%imm0_l)
2435        __(compare_reg_to_nil(%arg_z))
2436        __(je 2f)
24371:      __(extract_fulltag(%arg_z,%imm1))
2438        __(cmpb $fulltag_cons,%imm1_b)
2439        __(jne 9f)
2440        __(addw $node_size,%imm0_w)
2441        __(_car(%arg_z,%arg_x))
2442        __(_cdr(%arg_z,%arg_z))
2443        __(js 8f)
2444        __(compare_reg_to_nil(%arg_z))
2445        __(push %arg_x)
2446        __(jne 1b)
24472:      __(addw %imm0_w,%nargs_w)
2448        __(jne 4f)
24493:      __(addq $2*node_size,%rsp)
2450        __(jmp *%ra0)
24514:      __(cmpl $1*node_size,%nargs)
2452        __(pop %arg_z)
2453        __(je 3b)
2454        __(cmpl $2*node_size,%nargs)
2455        __(pop %arg_y)
2456        __(je 3b)
2457        __(cmpl $3*node_size,%nargs)
2458        __(pop %arg_x)
2459        __(je 3b)
2460        __(jmp *%ra0)
2461/* Discard everything that's been pushed already, complain   */
2462
24638:      __(lea (%rsp,%imm0),%rsp)
2464        __(movq %arg_y,%arg_z)  /* recover original   */
2465        __(movq $XTMINPS,%arg_y)
2466        __(set_nargs(2))
2467        __(push %ra0)
2468        __(jmp _SPksignalerr)
2469/* Discard everything that's been pushed already, complain   */
24709:      __(lea (%rsp,%imm0),%rsp)
2471        __(movq %arg_y,%arg_z)  /* recover original   */
2472        __(movq $XNOSPREAD,%arg_y)
2473        __(set_nargs(2))
2474        __(push %ra0)
2475        __(jmp _SPksignalerr)
2476_endsubp(spreadargz)
2477
2478/* Caller built it's own frame when it was entered.  If all outgoing args  */
2479/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2480/* relative to it and restore %rbp/%ra0   */
2481_spentry(tfuncallgen)
2482        __(cmpl $nargregs*node_size,%nargs)
2483        __(jbe 9f)
2484        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2485        __(xorl %imm1_l,%imm1_l)
2486        /* We can use %ra0 as a temporary here, since the real return address  */
2487        /* is on the stack   */
24880:      __(movq -node_size(%imm0),%ra0)
2489        __(movq %ra0,-node_size(%rbp,%imm1))
2490        __(subq $node_size,%imm0)
2491        __(subq $node_size,%imm1)
2492        __(cmpq %imm0,%rsp)
2493        __(jne 0b)
2494        __(lea (%rbp,%imm1),%rsp)
2495        __(movq 8(%rbp),%ra0)
2496        __(movq (%rbp),%rbp)
2497        __(pushq %ra0)
2498        __(do_funcall())
2499        /* All args in regs; exactly the same as the tfuncallvsp case   */
25009:             
2501        __(leave)
2502        __(do_funcall())
2503_endsubp(tfuncallgen)
2504
2505/* Some args were pushed; move them down in the frame   */
2506_spentry(tfuncallslide)
2507        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2508        __(xorl %imm1_l,%imm1_l)
2509        /* We can use %ra0 as a temporary here, since the real return address  */
2510        /* is on the stack   */
25110:      __(movq -node_size(%imm0),%ra0)
2512        __(movq %ra0,-node_size(%rbp,%imm1))
2513        __(subq $node_size,%imm0)
2514        __(subq $node_size,%imm1)
2515        __(cmpq %imm0,%rsp)
2516        __(jne 0b)
2517        __(lea (%rbp,%imm1),%rsp)
2518        __(movq 8(%rbp),%ra0)
2519        __(movq (%rbp),%rbp)
2520        __(push %ra0)
2521        __(do_funcall())       
2522_endsubp(tfuncallslide)
2523
2524/* No args were pushed; recover saved context & do funcall        */
2525_spentry(tfuncallvsp)
2526        __(leave)
2527        __(do_funcall())
2528_endsubp(tfuncallvsp)
2529
2530_spentry(tcallsymgen)
2531        __(cmpl $nargregs*node_size,%nargs)
2532        __(jbe 9f)
2533        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2534        __(xorl %imm1_l,%imm1_l)
2535        /* We can use %ra0 as a temporary here, since the real return address  */
2536        /* is on the stack   */
25370:      __(movq -node_size(%imm0),%ra0)
2538        __(movq %ra0,-node_size(%rbp,%imm1))
2539        __(subq $node_size,%imm0)
2540        __(subq $node_size,%imm1)
2541        __(cmpq %imm0,%rsp)
2542        __(jne 0b)
2543        __(lea (%rbp,%imm1),%rsp)
2544        __(movq 8(%rbp),%ra0)
2545        __(movq (%rbp),%rbp)
2546        __(pushq %ra0)
2547        __(jump_fname())
2548/* All args in regs; exactly the same as the tcallsymvsp case   */
25499:             
2550        __(leave)
2551        __(jump_fname())
2552_endsubp(tcallsymgen)
2553
2554_spentry(tcallsymslide)
2555        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2556        __(xorl %imm1_l,%imm1_l)
2557        /* We can use %ra0 as a temporary here, since the real return address  */
2558        /* is on the stack   */
25590:      __(movq -node_size(%imm0),%ra0)
2560        __(movq %ra0,-node_size(%rbp,%imm1))
2561        __(subq $node_size,%imm0)
2562        __(subq $node_size,%imm1)
2563        __(cmpq %imm0,%rsp)
2564        __(jne 0b)
2565        __(lea (%rbp,%imm1),%rsp)
2566        __(movq 8(%rbp),%ra0)
2567        __(movq 0(%rbp),%rbp)
2568        __(pushq %ra0)
2569        __(jump_fname())
2570_endsubp(tcallsymslide)
2571
2572_spentry(tcallsymvsp)
2573        __(leave)
2574        __(jump_fname())
2575_endsubp(tcallsymvsp)
2576
2577_spentry(tcallnfngen)
2578        __(cmpl $nargregs*node_size,%nargs)
2579        __(jbe 9f)
2580        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2581        __(xorl %imm1_l,%imm1_l)
2582        /* We can use %ra0 as a temporary here, since the real return address  */
2583        /* is on the stack   */
25840:      __(movq -node_size(%imm0),%ra0)
2585        __(movq %ra0,-node_size(%rbp,%imm1))
2586        __(subq $node_size,%imm0)
2587        __(subq $node_size,%imm1)
2588        __(cmpq %imm0,%rsp)
2589        __(jne 0b)
2590        __(movq %temp0,%fn)
2591        __(lea (%rbp,%imm1),%rsp)
2592        __(movq lisp_frame.savera0(%rbp),%ra0)
2593        __(movq lisp_frame.backlink(%rbp),%rbp)
2594        __(pushq %ra0)
2595        __(jmp *%fn)
2596/* All args in regs; exactly the same as the tcallnfnvsp case   */
25979:             
2598        __(movq %temp0,%fn)
2599        __(leave)
2600        __(jmp *%fn)
2601_endsubp(tcallnfngen)
2602
2603_spentry(tcallnfnslide)
2604        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2605        __(xorl %imm1_l,%imm1_l)
2606        /* We can use %ra0 as a temporary here, since the real return address  */
2607        /* is on the stack   */
26080:      __(movq -node_size(%imm0),%ra0)
2609        __(movq %ra0,-node_size(%rbp,%imm1))
2610        __(subq $node_size,%imm0)
2611        __(subq $node_size,%imm1)
2612        __(cmpq %imm0,%rsp)
2613        __(jne 0b)
2614        __(movq %temp0,%fn)
2615        __(lea (%rbp,%imm1),%rsp)
2616        __(movq lisp_frame.savera0(%rbp),%ra0)
2617        __(movq lisp_frame.backlink(%rbp),%rbp)
2618        __(pushq %ra0)
2619        __(jmp *%fn)
2620_endsubp(tcallnfnslide)
2621
2622_spentry(tcallnfnvsp)
2623        __(movq %temp0,%fn)
2624        __(leave)
2625        __(jmp *%fn)
2626_endsubp(tcallnfnvsp)
2627
2628
2629/* Make a "raw" area on the foreign stack, stack-cons a macptr to point to it,   */
2630/*   and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr  */
2631/*   in arg_z on exit.   */
2632_spentry(makestackblock)
2633        __(unbox_fixnum(%arg_z,%imm0))
2634        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2635        __(cmpq $tstack_alloc_limit,%imm0)
2636        __(jae 1f)
2637        __(movq rcontext(tcr.foreign_sp),%imm1)
2638        __(subq %imm0,rcontext(tcr.foreign_sp))
2639        __(movq rcontext(tcr.foreign_sp),%arg_z)
2640        __(movq %imm1,(%arg_z))
2641        __(movq %rbp,csp_frame.save_rbp(%arg_z))
2642        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2643        __(movq $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2644        __(addq $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2645        __(movq %imm0,macptr.address(%arg_z))
2646        __(movsd %fpzero,macptr.domain(%arg_z))
2647        __(movsd %fpzero,macptr.type(%arg_z))
2648        __(ret)
26491:      __(movq rcontext(tcr.foreign_sp),%imm1)
2650        __(subq $dnode_size,rcontext(tcr.foreign_sp))
2651        __(movq rcontext(tcr.foreign_sp),%imm0)
2652        __(movq %imm1,(%imm0))
2653        __(movq %rbp,csp_frame.save_rbp(%imm0))
2654        __(set_nargs(1))
2655        __(movq $nrs.new_gcable_ptr,%fname)
2656        __(jump_fname())
2657_endsubp(makestackblock)
2658
2659_spentry(makestackblock0)
2660        __(unbox_fixnum(%arg_z,%imm0))
2661        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2662        __(cmpq $tstack_alloc_limit,%imm0)
2663        __(jae 9f)
2664        __(movq rcontext(tcr.foreign_sp),%imm1)
2665        __(subq %imm0,rcontext(tcr.foreign_sp))
2666        __(movq rcontext(tcr.foreign_sp),%arg_z)
2667        __(movq %imm1,(%arg_z))
2668        __(movq %rbp,csp_frame.save_rbp(%arg_z))
2669        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2670        __(movq $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2671        __(addq $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2672        __(movq %imm0,macptr.address(%arg_z))
2673        __(movsd %fpzero,macptr.domain(%arg_z))
2674        __(movsd %fpzero,macptr.type(%arg_z))
2675        __(jmp 2f)
26761:      __(movapd %fpzero,(%imm0))
2677        __(addq $dnode_size,%imm0)
26782:      __(cmpq %imm0,%imm1)
2679        __(jne 1b)             
2680        __(repret)
26819:      __(movq rcontext(tcr.foreign_sp),%imm1)
2682        __(subq $dnode_size,rcontext(tcr.foreign_sp))
2683        __(movq rcontext(tcr.foreign_sp),%imm0)
2684        __(movq %imm1,(%imm0))
2685        __(movq %rbp,csp_frame.save_rbp(%imm0))
2686        __(set_nargs(1))
2687        __(movq $nrs.new_gcable_ptr,%fname)
2688        __(jump_fname())
2689_endsubp(makestackblock0)
2690
2691_spentry(makestacklist)
2692        __(movq $((1<<63)|fixnummask),%imm0)
2693        __(testq %imm0,%arg_y)
2694        __(jne 9f)
2695        __(movq %arg_y,%imm0)
2696        __(addq %imm0,%imm0)
2697        __(rcmpq(%imm0,$tstack_alloc_limit))
2698        __(movl $nil_value,%temp1_l)
2699        __(jae 2f)
2700        __(addq $tsp_frame.fixed_overhead,%imm0)
2701        __(TSP_Alloc_Var(%imm0,%temp0))
2702        __(addq $fulltag_cons,%temp0)
2703        __(jmp 1f)
27040:      __(_rplaca(%temp0,%arg_z))
2705        __(_rplacd(%temp0,%temp1))
2706        __(movq %temp0,%temp1)
2707        __(addq $cons.size,%temp0)
27081:      __(subq $fixnumone,%arg_y)
2709        __(jge 0b)
2710        __(movq %temp1,%arg_z)
2711        __(ret)
27122:      __(TSP_Alloc_Fixed(0,%imm0))
2713        __(jmp 4f)
27143:      __(Cons(%arg_z,%temp1,%temp1))
27154:      __(subq $fixnumone,%arg_y)                             
2716        __(jge 3b)
2717        __(movq %temp1,%arg_z)
2718        __(ret)
27199:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
2720_endsubp(makestacklist)
2721
2722/* subtype (boxed) vpushed before initial values. (Had better be a   */
2723/* node header subtag.) Nargs set to count of things vpushed.     */
2724_spentry(stkgvector)
2725        __(lea -fixnum_one(%nargs_q),%imm0)
2726        __(lea (%rsp,%imm0),%arg_x)
2727        __(movq %imm0,%arg_y)
2728        __(shlq $num_subtag_bits-fixnumshift,%imm0)
2729        __(movq (%arg_x), %imm1)
2730        __(shrq $fixnumshift,%imm1)
2731        __(orq %imm1,%imm0)     /* imm0 = header, %arg_y = unaligned size   */
2732        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm1))
2733        __(TSP_Alloc_Var(%imm1,%arg_z))
2734        __(movq %imm0,(%arg_z))
2735        __(addq $fulltag_misc,%arg_z)
2736        __(lea -node_size(%nargs_q),%imm0)
2737        __(jmp 2f)
27381:      __(pop misc_data_offset(%arg_z,%imm0))
27392:      __(subq $node_size,%imm0)
2740        __(jge 1b)
2741        __(addq $node_size,%rsp)
2742        __(jmp *%ra0)   
2743_endsubp(stkgvector)
2744
2745_spentry(misc_alloc)
2746        __(movq $~(((1<<56)-1)<<fixnumshift),%imm0)
2747        __(testq %imm0,%arg_y)
2748        __(jne local_label(misc_alloc_not_u56))
2749        __(unbox_fixnum(%arg_z,%imm0))
2750        __(movq %arg_y,%temp0)
2751        __(shl $num_subtag_bits-fixnumshift,%temp0)
2752        __(orq %temp0,%imm0)            /* %imm0 now = header   */
2753        __(movb $fulltagmask,%imm1_b)
2754        __(andb %imm0_b,%imm1_b)
2755        __(cmpb $fulltag_nodeheader_0,%imm1_b)
2756        __(je local_label(misc_alloc_64))
2757        __(cmpb $fulltag_nodeheader_1,%imm1_b)
2758        __(je local_label(misc_alloc_64))
2759        __(cmpb $ivector_class_64_bit,%imm1_b)
2760        __(jz local_label(misc_alloc_64))
2761        __(cmpb $ivector_class_32_bit,%imm1_b)
2762        __(jz local_label(misc_alloc_32))
2763        __(unbox_fixnum(%arg_y,%imm1))
2764        /* ivector_class_other_bit: 16, 8, or 1 ...   */
2765        __(cmpb $subtag_bit_vector,%imm0_b)
2766        __(jne local_label(misc_alloc_8))
2767        __(addq $7,%imm1)
2768        __(shrq $3,%imm1)
2769        __(jmp local_label(misc_alloc_alloc_vector))
2770local_label(misc_alloc_8):     
2771        __(cmpb $subtag_simple_base_string,%imm0_b)
2772        __(jae local_label(misc_alloc_alloc_vector))
2773local_label(misc_alloc_16):     
2774        __(shlq %imm1)
2775        __(jmp local_label(misc_alloc_alloc_vector))
2776local_label(misc_alloc_32):
2777        /* 32-bit ivector   */
2778        __(unbox_fixnum(%arg_y,%imm1))
2779        __(shlq $2,%imm1)
2780        __(jmp local_label(misc_alloc_alloc_vector))
2781local_label(misc_alloc_64):
2782        /* 64-bit ivector or gvector      */
2783        __(movq %arg_y,%imm1)
2784local_label(misc_alloc_alloc_vector):   
2785        __(dnode_align(%imm1,node_size,%imm1))
2786        __(Misc_Alloc(%arg_z))
2787        __(ret)
2788local_label(misc_alloc_not_u56):
2789        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_56))
2790_endsubp(misc_alloc)
2791
2792
2793_startfn(C(destbind1))
2794        /* Save entry %rsp in case of error   */
2795        __(movd %rsp,%mm0)
2796        /* Extract required arg count.   */
2797        __(movzbl %nargs_b,%imm0_l)
2798        __(testl %imm0_l,%imm0_l)
2799        __(je local_label(opt))         /* skip if no required args   */
2800local_label(req_loop): 
2801        __(compare_reg_to_nil(%arg_reg))
2802        __(je local_label(toofew))
2803        __(extract_lisptag(%arg_reg,%imm1))
2804        __(cmpb $tag_list,%imm1_b)
2805        __(jne local_label(badlist))
2806        __(subb $1,%imm0_b)
2807        __(pushq cons.car(%arg_reg))
2808        __(_cdr(%arg_reg,%arg_reg))
2809        __(jne local_label(req_loop))
2810local_label(opt):       
2811        __(movw %nargs_w,%imm0_w)
2812        __(shrw $8,%imm0_w)
2813        __(je local_label(rest_keys))
2814        __(btl $initopt_bit,%nargs)
2815        __(jc local_label(opt_supp))
2816        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2817local_label(simple_opt_loop):
2818        __(compare_reg_to_nil(%arg_reg))
2819        __(je local_label(default_simple_opt))
2820        __(extract_lisptag(%arg_reg,%imm1))
2821        __(cmpb $tag_list,%imm1_b)
2822        __(jne local_label(badlist))
2823        __(subb $1,%imm0_b)
2824        __(pushq cons.car(%arg_reg))
2825        __(_cdr(%arg_reg,%arg_reg))
2826        __(jne local_label(simple_opt_loop))
2827        __(jmp local_label(rest_keys))
2828local_label(default_simple_opt):
2829        __(subb $1,%imm0_b)
2830        __(pushq $nil_value)
2831        __(jne local_label(default_simple_opt))
2832        __(jmp local_label(rest_keys))
2833local_label(opt_supp):
2834        __(extract_lisptag(%arg_reg,%imm1))
2835        __(compare_reg_to_nil(%arg_z))
2836        __(je local_label(default_hard_opt))
2837        __(cmpb $tag_list,%imm1_b)
2838        __(jne local_label(badlist))
2839        __(subb $1,%imm0_b)
2840        __(pushq cons.car(%arg_reg))
2841        __(_cdr(%arg_reg,%arg_reg))
2842        __(push $t_value)
2843        __(jne local_label(opt_supp))
2844        __(jmp local_label(rest_keys))
2845local_label(default_hard_opt):
2846        __(subb $1,%imm0_b)
2847        __(push $nil_value)
2848        __(push $nil_value)
2849        __(jne local_label(default_hard_opt))   
2850local_label(rest_keys): 
2851        __(btl $restp_bit,%nargs)
2852        __(jc local_label(have_rest))
2853        __(btl $keyp_bit,%nargs)
2854        __(jc local_label(have_keys))
2855        __(compare_reg_to_nil(%arg_reg))
2856        __(jne local_label(toomany))
2857        __(jmp *%ra0)
2858local_label(have_rest):
2859        __(pushq %arg_reg)
2860        __(btl $keyp_bit,%nargs)
2861        __(jc local_label(have_keys))
2862        __(jmp *%ra0)           
2863        /* Ensure that arg_reg contains a proper,even-length list.  */
2864        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2865local_label(have_keys):
2866        __(movw $256,%imm0_w)
2867        __(movq %arg_reg,%arg_y)
2868local_label(count_keys_loop):   
2869        __(compare_reg_to_nil(%arg_y))
2870        __(je local_label(counted_keys))
2871        __(subw $1,%imm0_w)
2872        __(jl local_label(toomany))
2873        __(extract_lisptag(%arg_y,%imm1))
2874        __(cmpb $tag_list,%imm1_b)
2875        __(jne local_label(badlist))
2876        __(_cdr(%arg_y,%arg_y))
2877        __(extract_fulltag(%arg_y,%imm1))
2878        __(cmpb $fulltag_cons,%imm1_b)
2879        __(jne local_label(badlist))
2880        __(_cdr(%arg_y,%arg_y))
2881        __(jmp local_label(count_keys_loop))
2882local_label(counted_keys):             
2883        /* We've got a proper, even-length list of key/value pairs in  */
2884        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2885        /* of NILs on the vstack.   */
2886       
2887        __(movl %nargs,%imm1_l)
2888        __(shrl $16,%imm1_l)
2889        __(movzbl %imm1_b,%imm0_l)
2890        __(movq %rsp,%arg_y)
2891        __(jmp local_label(push_pair_test))     
2892local_label(push_pair_loop):
2893        __(push $nil_value)
2894        __(push $nil_value)
2895local_label(push_pair_test):   
2896        __(subb $1,%imm1_b)
2897        __(jge local_label(push_pair_loop))
2898        /* Push the %saveN registers, so that we can use them in this loop   */
2899        /* Also, borrow %arg_z */
2900        __(push %save0)
2901        __(push %save1)
2902        __(push %save2)
2903        __(push %arg_z)
2904        /* save0 points to the 0th value/supplied-p pair   */
2905        __(movq %arg_y,%save0)
2906        /* save1 is the length of the keyword vector   */
2907        __(vector_length(%arg_x,%save1))
2908        /* save2 is the current keyword   */
2909        /* arg_z is the value of the current keyword   */
2910        __(xorl %imm0_l,%imm0_l)        /* count unknown keywords seen   */
2911local_label(match_keys_loop):
2912        __(compare_reg_to_nil(%arg_reg))
2913        __(je local_label(matched_keys))
2914        __(_car(%arg_reg,%save2))
2915        __(_cdr(%arg_reg,%arg_reg))
2916        __(_car(%arg_reg,%arg_z))
2917        __(_cdr(%arg_reg,%arg_reg))
2918        __(xorl %arg_y_l,%arg_y_l)
2919        __(jmp local_label(match_test))
2920local_label(match_loop):
2921        __(cmpq misc_data_offset(%arg_x,%arg_y),%save2)
2922        __(je local_label(matched))
2923        __(addq $node_size,%arg_y)
2924local_label(match_test):
2925        __(cmpq %arg_y,%save1)
2926        __(jne local_label(match_loop))
2927        /* No match.  Note unknown keyword, check for :allow-other-keys   */
2928        __(addl $1,%imm0_l)
2929        __(cmpq $nrs.kallowotherkeys,%save2)
2930        __(jne local_label(match_keys_loop))
2931        __(subl $1,%imm0_l)
2932        __(btsl $seen_aok_bit,%nargs)
2933        __(jc local_label(match_keys_loop))
2934        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
2935        __(compare_reg_to_nil(%arg_z))
2936        __(je local_label(match_keys_loop))
2937        __(btsl $aok_bit,%nargs)
2938        __(jmp local_label(match_keys_loop))
2939        /* Got a match.  Worry about :allow-other-keys here, too.   */
2940local_label(matched):
2941        __(negq %arg_y)
2942        __(cmpb $fulltag_nil,-node_size*2(%save0,%arg_y,2))
2943        __(jne local_label(match_keys_loop))
2944        __(movq %arg_z,-node_size(%save0,%arg_y,2))
2945        __(movl $t_value,-node_size*2(%save0,%arg_y,2))
2946        __(cmpq $nrs.kallowotherkeys,%save2)
2947        __(jne local_label(match_keys_loop))
2948        __(btsl $seen_aok_bit,%nargs)
2949        __(jnc local_label(match_keys_loop))
2950        __(compare_reg_to_nil(%arg_z))
2951        __(je local_label(match_keys_loop))
2952        __(btsl $aok_bit,%nargs)
2953        __(jmp local_label(match_keys_loop))
2954local_label(matched_keys):             
2955        __(pop %arg_z)
2956        __(pop %save2)
2957        __(pop %save1)
2958        __(pop %save0)
2959        __(testl %imm0_l,%imm0_l)
2960        __(je local_label(keys_ok)) 
2961        __(btl $aok_bit,%nargs)
2962        __(jnc local_label(badkeys))
2963local_label(keys_ok):   
2964        __(jmp *%ra0)
2965        /* Some unrecognized keywords.  Complain generically about   */
2966        /* invalid keywords.   */
2967local_label(badkeys):
2968        __(movq $XBADKEYS,%arg_y)
2969        __(jmp local_label(destructure_error))
2970local_label(toomany):
2971        __(movq $XCALLTOOMANY,%arg_y)
2972        __(jmp local_label(destructure_error))
2973local_label(toofew):
2974        __(movq $XCALLTOOFEW,%arg_y)
2975        __(jmp local_label(destructure_error))
2976local_label(badlist):
2977        __(movq $XCALLNOMATCH,%arg_y)
2978        /* jmp local_label(destructure_error)   */
2979local_label(destructure_error):
2980        __(movd %mm0,%rsp)              /* undo everything done to the stack   */
2981        __(movq %whole_reg,%arg_z)
2982        __(set_nargs(2))
2983        __(push %ra0)
2984        __(jmp _SPksignalerr)
2985_endfn(C(destbind1))   
2986
2987_spentry(macro_bind)
2988        __(movq %arg_reg,%whole_reg)
2989        __(extract_lisptag(%arg_reg,%imm0))
2990        __(cmpb $tag_list,%imm0_b)
2991        __(jne 1f)
2992        __(_cdr(%arg_reg,%arg_reg))
2993        __(jmp C(destbind1))
29941:      __(movq $XCALLNOMATCH,%arg_y)
2995        __(movq %whole_reg,%arg_z)
2996        __(set_nargs(2))
2997        __(push %ra0)       
2998        __(jmp _SPksignalerr)
2999_endsubp(macro_bind)
3000
3001_spentry(destructuring_bind)
3002        __(movq %arg_reg,%whole_reg)
3003        __(jmp C(destbind1))
3004_endsubp(destructuring_bind)
3005
3006_spentry(destructuring_bind_inner)
3007        __(movq %arg_z,%whole_reg)
3008        __(jmp C(destbind1))
3009_endsubp(destructuring_bind_inner)
3010
3011       
3012
3013
3014_spentry(vpopargregs)
3015_endsubp(vpopargregs)
3016
3017/* If arg_z is an integer, return in imm0 something whose sign  */
3018/* is the same as arg_z's.  If not an integer, error.   */
3019_spentry(integer_sign)
3020        __(testb $tagmask,%arg_z_b)
3021        __(movq %arg_z,%imm0)
3022        __(je 8f)
3023        __(extract_typecode(%arg_z,%imm0))
3024        __(cmpb $subtag_bignum,%imm0_b)
3025        __(jne 9f)
3026        __(getvheader(%arg_z,%imm0))
3027        __(shr $num_subtag_bits,%imm0)
3028        __(movslq misc_data_offset-4(%arg_z,%imm0,4),%imm0)
30298:      __(repret)
30309:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3031_endsubp(integer_sign)
3032
3033/* "slide" nargs worth of values up the stack.  IMM0 contains   */
3034/* the difference between the current RSP and the target.   */
3035_spentry(mvslide)
3036        __(movl %nargs,%imm1_l)
3037        __(lea (%rsp,%nargs_q),%temp0)
3038        __(testq %imm1,%imm1)
3039        __(lea (%temp0,%imm0),%imm0)
3040        __(je 2f)
30411:     
3042        __(subq $node_size,%temp0)
3043        __(movq (%temp0),%temp1)
3044        __(subq $node_size,%imm0)
3045        __(movq %temp1,(%imm0))
3046        __(subq $node_size,%imm1)
3047        __(jne 1b)
30482:      __(movq %imm0,%rsp)
3049        __(jmp *%ra0)   
3050_endsubp(mvslide)
3051
3052_spentry(save_values)
3053        __(movq rcontext(tcr.save_tsp),%imm1)
3054/* common exit: nargs = values in this set, imm1 = ptr to tsp before call to save_values   */
3055local_label(save_values_to_tsp):
3056        __(movq rcontext(tcr.save_tsp),%arg_x)
3057        __(dnode_align(%nargs_q,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3058        __(TSP_Alloc_Var(%imm0,%arg_z))
3059        __(movq rcontext(tcr.save_tsp),%imm0)
3060        __(movq %imm1,(%imm0))
3061        __(movq %nargs_q,(%arg_z))
3062        __(movq %arg_x,node_size(%arg_z))
3063        __(leaq 2*node_size(%arg_z,%nargs_q),%arg_y)
3064        __(leaq (%rsp,%nargs_q),%imm0)
3065        __(cmpq %imm0,%rsp)
3066        __(jmp 2f)
30671:      __(subq $node_size,%imm0)
3068        __(movq (%imm0),%arg_z)
3069        __(subq $node_size,%arg_y)
3070        __(cmpq %imm0,%rsp)
3071        __(movq %arg_z,(%arg_y))
30722:      __(jne 1b)
3073        __(add %nargs_q,%rsp)
3074        __(jmp *%ra0)                   
3075_endsubp(save_values)
3076
3077/* Add the multiple values that are on top of the vstack to the set  */
3078/* saved in the top tsp frame, popping them off of the vstack in the  */
3079/* process.  It is an error (a bad one) if the TSP contains something  */
3080/* other than a previously saved set of multiple-values.  */
3081/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3082/* each add_values call adds another linked element to the list of  */
3083/* values. This makes recover_values harder.   */
3084_spentry(add_values)
3085        __(testl %nargs,%nargs)
3086        __(movq rcontext(tcr.save_tsp),%imm1)
3087        __(movq (%imm1),%imm1)
3088        __(jne local_label(save_values_to_tsp))
3089        __(jmp *%ra0)
3090_endsubp(add_values)
3091
3092/* push the values in the value set atop the sp, incrementing nargs.  */
3093/* Discard the tsp frame; leave values atop the sp.   */
3094       
3095_spentry(recover_values)
3096        /* First, walk the segments reversing the pointer to previous  */
3097        /* segment pointers Can tell the end because that previous  */
3098        /* segment pointer is the prev tsp pointer   */
3099        __(movq rcontext(tcr.save_tsp),%temp1)
3100        __(movq %temp1,%arg_x)  /* current segment   */
3101        __(movq %temp1,%arg_y)  /* last segment   */
3102        __(movq tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3103local_label(walkloop):
3104        __(movq tsp_frame.fixed_overhead+node_size(%arg_x),%temp0)
3105        __(cmpq %temp0,%arg_z)  /* last segment ?   */
3106        __(movq %arg_y,tsp_frame.fixed_overhead+node_size(%arg_x))
3107        __(movq %arg_x,%arg_y)  /* last segment <- current segment   */
3108        __(movq %temp0,%arg_x)  /* current segment <- next segment   */
3109        __(jne local_label(walkloop))
3110
3111        /* the final segment pointer is now in %arg_y  */
3112        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3113local_label(pushloop):
3114        __(movq tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3115        __(testq %imm0,%imm0)
3116        __(leaq tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3117        __(leaq (%nargs_q,%imm0),%nargs_q)
3118        __(jmp 2f)
31191:      __(pushq -node_size(%temp0))
3120        __(subq $node_size,%temp0)
3121        __(subq $fixnum_one,%imm0)
31222:      __(jne 1b)
3123        __(cmpq %arg_y,%temp1)
3124        __(movq tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3125        __(jne local_label(pushloop))
3126        __(movq (%temp1),%temp1)
3127        __(movq %temp1,rcontext(tcr.save_tsp))
3128        __(movq %temp1,rcontext(tcr.next_tsp))       
3129        __(jmp *%ra0)           
3130_endsubp(recover_values)
3131
3132/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3133/* frame if any values (which will be used as outgoing arguments) will  */
3134/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3135/* that no other arguments have been pushed) on entry.   */
3136               
3137_spentry(recover_values_for_mvcall)
3138        /* First, walk the segments reversing the pointer to previous  */
3139        /* segment pointers Can tell the end because that previous  */
3140        /* segment pointer is the prev tsp pointer   */
3141        __(xorl %nargs,%nargs)
3142        __(movq rcontext(tcr.save_tsp),%temp1)
3143        __(movq %temp1,%arg_x)  /* current segment   */
3144        __(movq %temp1,%arg_y)  /* last segment   */
3145        __(movq tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3146local_label(walkloop_mvcall):
3147        __(movq tsp_frame.fixed_overhead+node_size(%arg_x),%temp0)
3148        __(addq tsp_frame.data_offset(%arg_x),%nargs_q) 
3149        __(cmpq %temp0,%arg_z)  /* last segment ?   */
3150        __(movq %arg_y,tsp_frame.fixed_overhead+node_size(%arg_x))
3151        __(movq %arg_x,%arg_y)  /* last segment <- current segment   */
3152        __(movq %temp0,%arg_x)  /* current segment <- next segment   */
3153        __(jne local_label(walkloop_mvcall))
3154
3155        __(cmpl $nargregs*node_size,%nargs)
3156        __(jbe local_label(pushloop_mvcall))
3157        __(push $reserved_frame_marker)
3158        __(push $reserved_frame_marker)
3159
3160        /* the final segment pointer is now in %arg_y  */
3161        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3162local_label(pushloop_mvcall):
3163        __(movq tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3164        __(testq %imm0,%imm0)
3165        __(leaq tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3166        __(jmp 2f)
31671:      __(pushq -node_size(%temp0))
3168        __(subq $node_size,%temp0)
3169        __(subq $fixnum_one,%imm0)
31702:      __(jne 1b)
3171        __(cmpq %arg_y,%temp1)
3172        __(movq tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3173        __(jne local_label(pushloop_mvcall))
3174        __(movq (%temp1),%temp1)
3175        __(movq %temp1,rcontext(tcr.save_tsp))
3176        __(movq %temp1,rcontext(tcr.next_tsp))       
3177        __(jmp *%ra0)           
3178_endsubp(recover_values_for_mvcall)
3179                                       
3180_spentry(reset)
3181        __(int $3)
3182_endsubp(reset)
3183
3184
3185
3186_spentry(misc_alloc_init)
3187        __(push %rbp)
3188        __(movq %rsp,%rbp)
3189        __(push %arg_z)
3190        __(movq %arg_y,%arg_z)
3191        __(movq %arg_x,%arg_y)
3192        __(lea local_label(misc_alloc_init_back)(%rip),%ra0)
3193        __(push %ra0)
3194        __(jmp _SPmisc_alloc)
3195__(tra(local_label(misc_alloc_init_back)))
3196        __(pop %arg_y)
3197        __(leave)
3198        __(movq $nrs.init_misc,%fname)
3199        __(set_nargs(2))
3200        __(jump_fname())       
3201_endsubp(misc_alloc_init)
3202
3203_spentry(stack_misc_alloc_init)
3204        __(push %rbp)
3205        __(movq %rsp,%rbp)
3206        __(push %arg_z)
3207        __(movq %arg_y,%arg_z)
3208        __(movq %arg_x,%arg_y)
3209        __(lea local_label(stack_misc_alloc_init_back)(%rip),%ra0)
3210        __(push %ra0)
3211        __(jmp _SPstack_misc_alloc)
3212__(tra(local_label(stack_misc_alloc_init_back)))
3213        __(pop %arg_y)
3214        __(leave)
3215        __(movq $nrs.init_misc,%fname)
3216        __(set_nargs(2))
3217        __(jump_fname())       
3218_endsubp(stack_misc_alloc_init)
3219
3220
3221
3222        .globl C(popj)
3223_spentry(popj)
3224C(popj):
3225        __(leave)
3226        __(ret)
3227_endsubp(popj)
3228
3229
3230
3231_spentry(getu64)
3232        __(movq $~(target_most_positive_fixnum << fixnumshift),%imm0)
3233        __(testq %arg_z,%imm0)
3234        __(movq %arg_z,%imm0)
3235        __(jne 1f)
3236        __(sarq $fixnumshift,%imm0)
3237        __(ret)
32381:      __(andb $tagmask,%imm0_b)
3239        __(cmpb $tag_misc,%imm0_b)
3240        __(jne 9f)
3241        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3242        __(cmpb $subtag_bignum,%imm0_b)
3243        __(jne 9f)
3244        __(movq misc_header_offset(%arg_z),%imm0)
3245        __(cmpq $three_digit_bignum_header,%imm0)
3246        __(je 3f)
3247        __(cmpq $two_digit_bignum_header,%imm0)
3248        __(jne 9f)
3249        __(movq misc_data_offset(%arg_z),%imm0)
3250        __(testq %imm0,%imm0)
3251        __(js 9f)
3252        __(repret)
32533:      __(movq misc_data_offset(%arg_z),%imm0)
3254        __(cmpl $0,misc_data_offset+8(%arg_z))
3255        __(jne 9f)
3256        __(repret)
32579:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3258_endsubp(getu64)
3259
3260_spentry(gets64)
3261        __(movq %arg_z,%imm0)
3262        __(sarq $fixnumshift,%imm0)
3263        __(testb $fixnummask,%arg_z_b)
3264        __(je 8f)
32651:      __(movb %arg_z_b,%imm0_b)
3266        __(andb $tagmask,%imm0_b)
3267        __(cmpb $tag_misc,%imm0_b)
3268        __(jne 9f)
3269        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3270        __(cmpb $subtag_bignum,%imm0_b)
3271        __(jne 9f)
3272        __(movq misc_header_offset(%arg_z),%imm0)
3273        __(cmpq $two_digit_bignum_header,%imm0)
3274        __(movq misc_data_offset(%arg_z),%imm0)
3275        __(jne 9f)
32768:      __(repret)
32779:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3278_endsubp(gets64)
3279
3280_spentry(makeu64)
3281        __(movq %imm0,%imm1)
3282        __(shlq $fixnumshift+1,%imm1)
3283        __(movq %imm1,%arg_z)   /* Tagged as a fixnum, 2x    */
3284        __(shrq $fixnumshift+1,%imm1)
3285        __(shrq %arg_z)
3286        __(cmpq %imm0,%imm1)
3287        __(je 9f)
3288        __(testq %imm0,%imm0)
3289        __(movd %imm0,%mm0)
3290        __(js 3f)
3291        /* Make a 2-digit bignum.   */
3292        __(movl $two_digit_bignum_header,%imm0_l)
3293        __(movl $aligned_bignum_size(2),%imm1_l)
3294        __(Misc_Alloc(%arg_z))
3295        __(movq %mm0,misc_data_offset(%arg_z))
3296        __(ret)
32973:      __(movl $three_digit_bignum_header,%imm0_l)
3298        __(movl $aligned_bignum_size(3),%imm1_l)
3299        __(Misc_Alloc(%arg_z))
3300        __(movq %mm0,misc_data_offset(%arg_z))
33019:      __(repret)
3302_endsubp(makeu64)
3303
3304/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly  */
3305/* unbound_marker), arg_y = symbol   */
3306_spentry(specref)
3307        __(movq symbol.binding_index(%arg_z),%imm0)
3308        __(cmp rcontext(tcr.tlb_limit),%imm0)
3309        __(movq rcontext(tcr.tlb_pointer),%imm1)
3310        __(movq %arg_z,%arg_y)
3311        __(jae 7f)
3312        __(movq (%imm1,%imm0),%arg_z)
3313        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3314        __(jne 8f)
33157:      __(movq symbol.vcell(%arg_y),%arg_z)
33168:      __(repret)             
3317_endsubp(specref)
3318
3319/* arg_y = special symbol, arg_z = new value.           */
3320_spentry(specset)
3321        __(movq symbol.binding_index(%arg_y),%imm0)
3322        __(cmp rcontext(tcr.tlb_limit),%imm0)
3323        __(movq rcontext(tcr.tlb_pointer),%imm1)
3324        __(jae 1f)
3325        __(movq (%imm1,%imm0),%arg_x)
3326        __(cmpb $no_thread_local_binding_marker,%arg_x_b)
3327        __(je 1f)
3328        __(movq %arg_z,(%imm1,%imm0))
3329        __(ret)
33301:      __(lea fulltag_misc-fulltag_symbol(%arg_y),%arg_x)
3331        __(movq $1<<fixnumshift,%arg_y)
3332        __(jmp _SPgvset)
3333_endsubp(specset)
3334
3335_spentry(specrefcheck)
3336        __(movq symbol.binding_index(%arg_z),%imm0)
3337        __(cmp rcontext(tcr.tlb_limit),%imm0)
3338        __(movq rcontext(tcr.tlb_pointer),%imm1)
3339        __(movq %arg_z,%arg_y)
3340        __(jae 7f)
3341        __(movq (%imm1,%imm0),%arg_z)
3342        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3343        __(cmoveq symbol.vcell(%arg_y),%arg_z)
3344        __(cmpb $unbound_marker,%arg_z_b)
3345        __(je 9f)
33468:      __(repret)
33477:      __(cmpb $unbound_marker,symbol.vcell(%arg_y))
3348        __(movq symbol.vcell(%arg_y),%arg_z)
3349        __(je 9f)
3350        __(repret)
33519:      __(uuo_error_reg_unbound(Rarg_y))
3352_endsubp(specrefcheck)
3353
3354_spentry(restoreintlevel)
3355_endsubp(restoreintlevel)
3356
3357_spentry(makes32)
3358        __(int $3)
3359_endsubp(makes32)
3360
3361_spentry(makeu32)
3362        __(int $3)
3363_endsubp(makeu32)
3364
3365_spentry(gets32)
3366        __(int $3)
3367_endsubp(gets32)
3368
3369_spentry(getu32)
3370        __(int $3)
3371_endsubp(getu32)
3372
3373
3374_spentry(mvpasssym)
3375_endsubp(mvpasssym)
3376
3377
3378_spentry(unbind)
3379        __(movq rcontext(tcr.db_link),%imm1)
3380        __(movq rcontext(tcr.tlb_pointer),%arg_x)
3381        __(movq binding.sym(%imm1),%temp1)
3382        __(movq binding.val(%imm1),%arg_y)
3383        __(movq binding.link(%imm1),%imm1)
3384        __(movq %arg_y,(%arg_x,%temp1))
3385        __(movq %imm1,rcontext(tcr.db_link))
3386        __(ret)
3387_endsubp(unbind)
3388
3389_spentry(unbind_n)
3390        __(movq rcontext(tcr.db_link),%imm1)
3391        __(movq rcontext(tcr.tlb_pointer),%arg_x)
33921:             
3393        __(movq binding.sym(%imm1),%temp1)
3394        __(movq binding.val(%imm1),%arg_y)
3395        __(movq binding.link(%imm1),%imm1)
3396        __(movq %arg_y,(%arg_x,%temp1))
3397        __(subq $1,%imm0)
3398        __(jne 1b)
3399        __(movq %imm1,rcontext(tcr.db_link))
3400        __(ret) 
3401_endsubp(unbind_n)
3402
3403_spentry(unbind_to)
3404        __(movq rcontext(tcr.db_link),%imm1)
3405        __(movq rcontext(tcr.tlb_pointer),%arg_x)
34061:             
3407        __(movq binding.sym(%imm1),%temp1)
3408        __(movq binding.val(%imm1),%arg_y)
3409        __(movq binding.link(%imm1),%imm1)
3410        __(movq %arg_y,(%arg_x,%temp1))
3411        __(cmpq %imm1,%imm0)
3412        __(jne 1b)
3413        __(movq %imm1,rcontext(tcr.db_link))
3414        __(ret) 
3415_endsubp(unbind_to)
3416
3417
3418/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check   */
3419/* for pending interrupts after doing so.   */
3420       
3421_spentry(bind_interrupt_level_0)
3422        __(movq rcontext(tcr.tlb_pointer),%temp1)
3423        __(cmpq $0,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3424        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3425        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3426        __(push rcontext(tcr.db_link))
3427        __(movq %rsp,rcontext(tcr.db_link))
3428        __(movq $0,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3429        __(js,pn 1f)
34300:      __(jmp *%ra0)
3431        /* Interrupt level was negative; interrupt may be pending   */
34321:      __(check_pending_enabled_interrupt(2f))
34332:      __(jmp *%ra0)
3434_endsubp(bind_interrupt_level_0)
3435       
3436
3437/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3438/* of disabling interrupts.)   */
3439
3440_spentry(bind_interrupt_level_m1)
3441        __(movq rcontext(tcr.tlb_pointer),%temp1)
3442        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3443        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3444        __(push rcontext(tcr.db_link))
3445        __(movq %rsp,rcontext(tcr.db_link))
3446        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3447        __(jmp *%ra0)
3448_endsubp(bind_interrupt_level_m1)
3449
3450/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0,  */
3451/* do what _SPbind_interrupt_level_0 does   */
3452_spentry(bind_interrupt_level)
3453        __(testq %arg_z,%arg_z)
3454        __(movq rcontext(tcr.tlb_pointer),%temp1)
3455        __(jz _SPbind_interrupt_level_0)
3456        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3457        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3458        __(push rcontext(tcr.db_link))
3459        __(movq %rsp,rcontext(tcr.db_link))
3460        __(movq %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3461        __(jmp *%ra0)
3462_endsubp(bind_interrupt_level)
3463
3464/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to  */
3465/* non-negative, check for pending interrupts.    */
3466       
3467_spentry(unbind_interrupt_level)
3468        __(btq $TCR_FLAG_BIT_PENDING_SUSPEND,rcontext(tcr.flags))
3469        __(movq rcontext(tcr.db_link),%imm1)
3470        __(movq rcontext(tcr.tlb_pointer),%arg_x)
3471        __(movq INTERRUPT_LEVEL_BINDING_INDEX(%arg_x),%imm0)
3472        __(jc 5f)
34730:      __(testq %imm0,%imm0)
3474        __(movq binding.val(%imm1),%temp0)
3475        __(movq binding.link(%imm1),%imm1)
3476        __(movq %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
3477        __(movq %imm1,rcontext(tcr.db_link))
3478        __(js,pn 3f)
34792:      __(repret)
34803:      __(testq %temp0,%temp0)
3481        __(js 2b)
3482        __(check_pending_enabled_interrupt(4f))
34834:      __(repret)
34845:       /* Missed a suspend request; force suspend now if we're restoring
3485          interrupt level to -1 or greater */
3486        __(cmpq $-2<<fixnumshift,%imm0)
3487        __(jne 0b)
3488        __(movq binding.val(%imm1),%temp0)
3489        __(cmpq %imm0,%temp0)
3490        __(je 0b)
3491        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
3492        __(suspend_now())
3493        __(jmp 0b)
3494_endsubp(unbind_interrupt_level)
3495
3496       
3497_spentry(progvrestore)
3498        __(movq rcontext(tcr.save_tsp),%imm0)
3499        __(movq tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3500        __(movq tsp_frame.data_offset(%imm0),%imm0)
3501        __(shrq $fixnumshift,%imm0)
3502        __(jne _SPunbind_n)
3503        __(repret)
3504_endsubp(progvrestore)
3505       
3506
3507/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3508/* inline.  Call out otherwise.   */
3509_spentry(builtin_plus)
3510        __(movb %arg_z_b,%imm0_b)
3511        __(orb %arg_y_b,%imm0_b)
3512        __(testb $fixnummask,%imm0_b)
3513        __(jne 1f)
3514        __(addq %arg_y,%arg_z)
3515        __(jo,pn C(fix_one_bit_overflow))
3516        __(repret)
35171:      __(jump_builtin(_builtin_plus,2))
3518_endsubp(builtin_plus)
3519       
3520
3521/* %arg_z <- %arg_z - %arg_y.  Do the fixnum case - including overflow -  */
3522/*  inline.  Call out otherwise.   */
3523_spentry(builtin_minus)                 
3524        __(movb %arg_z_b,%imm0_b)
3525        __(orb %arg_y_b,%imm0_b)
3526        __(testb $fixnummask,%imm0_b)
3527        __(jne 1f)
3528        __(xchgq %arg_y,%arg_z)
3529        __(subq %arg_y,%arg_z)
3530        __(jo,pn C(fix_one_bit_overflow))
3531        __(repret)
35321:      __(jump_builtin(_builtin_minus,2))
3533_endsubp(builtin_minus)
3534
3535/* %arg_z <- %arg_z * %arg_y.  Do the fixnum case - including overflow -  */
3536/* inline.  Call out otherwise.   */
3537_spentry(builtin_times)
3538        __(movb %arg_z_b,%imm0_b)
3539        __(orb %arg_y_b,%imm0_b)
3540        __(testb $fixnummask,%imm0_b)
3541        __(jne 2f)
3542        __(unbox_fixnum(%arg_z,%imm0))
3543        /* 128-bit fixnum result in %imm1:%imm0. Overflow set if %imm1  */
3544        /* is significant   */
3545        __(imul %arg_y)
3546        __(jo 1f)
3547        __(mov %imm0,%arg_z)
3548        __(ret)
35491:      __(unbox_fixnum(%arg_z,%imm0))
3550        __(unbox_fixnum(%arg_y,%imm1))
3551        __(imul %imm1)
3552        __(jmp C(makes128))
35532:      __(jump_builtin(_builtin_times,2))
3554_endsubp(builtin_times)
3555
3556_spentry(builtin_div)
3557        __(jump_builtin(_builtin_div,2))
3558
3559/* %arg_z <- (= %arg_y %arg_z).   */
3560_spentry(builtin_eq)
3561        __(movb %arg_z_b,%imm0_b)
3562        __(orb %arg_y_b,%imm0_b)
3563        __(testb $fixnummask,%imm0_b)
3564        __(jne 1f)
3565        __(rcmpq(%arg_z,%arg_y))
3566        __(condition_to_boolean(e,%imm0,%arg_z))
3567        __(ret)
35681:      __(jump_builtin(_builtin_eq,2))
3569_endsubp(builtin_eq)
3570       
3571/* %arg_z <- (/= %arg_y %arg_z).          */
3572_spentry(builtin_ne)
3573        __(movb %arg_z_b,%imm0_b)
3574        __(orb %arg_y_b,%imm0_b)
3575        __(testb $fixnummask,%imm0_b)
3576        __(jne 1f)
3577        __(rcmpq(%arg_z,%arg_y))
3578        __(condition_to_boolean(ne,%imm0,%arg_z))
3579        __(ret)
35801:      __(jump_builtin(_builtin_ne,2))
3581_endsubp(builtin_ne)
3582       
3583/* %arg_z <- (> %arg_y %arg_z).   */
3584_spentry(builtin_gt)
3585        __(movb %arg_z_b,%imm0_b)
3586        __(orb %arg_y_b,%imm0_b)
3587        __(testb $fixnummask,%imm0_b)
3588        __(jne 1f)
3589        __(rcmpq(%arg_y,%arg_z))
3590        __(condition_to_boolean(g,%imm0,%arg_z))
3591        __(ret)
35921:      __(jump_builtin(_builtin_gt,2))
3593_endsubp(builtin_gt)
3594
3595/* %arg_z <- (>= %arg_y %arg_z).          */
3596_spentry(builtin_ge)
3597        __(movb %arg_z_b,%imm0_b)
3598        __(orb %arg_y_b,%imm0_b)
3599        __(testb $fixnummask,%imm0_b)
3600        __(jne 1f)
3601        __(rcmpq(%arg_y,%arg_z))
3602        __(condition_to_boolean(ge,%imm0,%arg_z))
3603        __(ret)
36041:      __(jump_builtin(_builtin_ge,2))
3605_endsubp(builtin_ge)
3606       
3607/* %arg_z <- (< %arg_y %arg_z).   */
3608_spentry(builtin_lt)
3609        __(movb %arg_z_b,%imm0_b)
3610        __(orb %arg_y_b,%imm0_b)
3611        __(testb $fixnummask,%imm0_b)
3612        __(jne 1f)
3613        __(rcmpq(%arg_y,%arg_z))
3614        __(condition_to_boolean(l,%imm0,%arg_z))
3615        __(ret)
36161:      __(jump_builtin(_builtin_lt,2))
3617_endsubp(builtin_lt)
3618
3619/* %arg_z <- (<= %arg_y %arg_z).   */
3620_spentry(builtin_le)
3621        __(movb %arg_z_b,%imm0_b)
3622        __(orb %arg_y_b,%imm0_b)
3623        __(testb $fixnummask,%imm0_b)
3624        __(jne 1f)
3625        __(rcmpq(%arg_y,%arg_z))
3626        __(condition_to_boolean(le,%imm0,%arg_z))
3627        __(ret)
36281:      __(jump_builtin(_builtin_le,2))
3629_endsubp(builtin_le)
3630
3631_spentry(builtin_eql)
3632        __(cmpq %arg_y,%arg_z)
3633        __(je 1f)
3634        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3635        /* and both have the same subtag   */
3636        __(extract_lisptag(%arg_y,%imm0))
3637        __(extract_lisptag(%arg_z,%imm1))
3638        __(cmpb $tag_misc,%imm0_b)
3639        __(jne 2f)
3640        __(cmpb %imm0_b,%imm1_b)
3641        __(jne 2f)
3642        __(extract_subtag(%arg_y,%imm0_b))
3643        __(extract_subtag(%arg_z,%imm1_b))
3644        __(cmpb %imm0_b,%imm1_b)
3645        __(jne 2f)
3646        __(jump_builtin(_builtin_eql,2))
36471:      __(movl $t_value,%arg_z_l)
3648        __(ret)
36492:      __(movl $nil_value,%arg_z_l)
3650        __(ret) 
3651_endsubp(builtin_eql)
3652
3653_spentry(builtin_length)
3654        __(extract_lisptag(%arg_z,%imm0))
3655        __(cmpb $tag_list,%imm0_b)
3656        __(jz 2f)
3657        __(cmpb $tag_misc,%imm0_b)
3658        __(jnz 8f)
3659        __(extract_subtag(%arg_z,%imm0_b))
3660        __(rcmpb(%imm0_b,$min_vector_subtag))
3661        __(jb 8f)
3662        __(je 1f)
3663        /* (simple-array * (*))   */
3664        __(movq %arg_z,%arg_y)
3665        __(vector_length(%arg_y,%arg_z))
3666        __(ret)
36671:      /* vector header   */
3668        __(movq vectorH.logsize(%arg_z),%arg_z)
3669        __(ret)
36702:      /* list.  Maybe null, maybe dotted or circular.   */
3671        __(movq $-fixnumone,%imm2)
3672        __(movq %arg_z,%temp0)  /* fast pointer   */
3673        __(movq %arg_z,%temp1)  /* slow pointer   */
36743:      __(extract_lisptag(%temp0,%imm0))       
3675        __(compare_reg_to_nil(%temp0))
3676        __(leaq fixnumone(%imm2),%imm2)
3677        __(je 9f)
3678        __(cmpb $tag_list,%imm0_b)
3679        __(jne 8f)
3680        __(extract_lisptag(%temp1,%imm1))
3681        __(testb $fixnumone,%imm2_b)
3682        __(_cdr(%temp0,%temp0))
3683        __(je 3b)
3684        __(cmpb $tag_list,%imm1_b)
3685        __(jne 8f)
3686        __(_cdr(%temp1,%temp1))
3687        __(cmpq %temp0,%temp1)
3688        __(jne 3b)
36898:     
3690        __(jump_builtin(_builtin_length,1))
36919:     
3692        __(movq %imm2,%arg_z)
3693        __(ret)         
3694_endsubp(builtin_length)
3695
3696       
3697_spentry(builtin_seqtype)
3698        __(extract_lisptag(%arg_z,%imm0))
3699        __(cmpb $tag_list,%imm0_b)
3700        __(jz 1f)
3701        __(cmpb $tag_misc,%imm0_b)
3702        __(jne 2f)
3703        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3704        __(rcmpb(%imm0_b,$min_vector_subtag))
3705        __(jb 2f)
3706        __(movl $nil_value,%arg_z_l)
3707        __(ret)
37081:      __(movl $t_value,%arg_z_l)
3709        __(ret)
37102:     
3711        __(jump_builtin(_builtin_seqtype,1))
3712_endsubp(builtin_seqtype)
3713
3714_spentry(builtin_assq)
3715        __(cmpb $fulltag_nil,%arg_z_b)
3716        __(jz 5f)
37171:      __(movb $tagmask,%imm0_b)
3718        __(andb %arg_z_b,%imm0_b)
3719        __(cmpb $tag_list,%imm0_b)
3720        __(jnz 2f)
3721        __(_car(%arg_z,%arg_x))
3722        __(_cdr(%arg_z,%arg_z))
3723        __(cmpb $fulltag_nil,%arg_x_b)
3724        __(jz 4f)
3725        __(movb $tagmask,%imm0_b)
3726        __(andb %arg_x_b,%imm0_b)
3727        __(cmpb $tag_list,%imm0_b)
3728        __(jnz 3f)
3729        __(_car(%arg_x,%temp0))
3730        __(cmpq %temp0,%arg_y)
3731        __(jnz 4f)
3732        __(movq %arg_x,%arg_z)
3733        __(ret)
37344:      __(cmpb $fulltag_nil,%arg_z_b)
37355:      __(jnz 1b)
3736        __(repret)
37372:      __(uuo_error_reg_not_list(Rarg_z))
37383:      __(uuo_error_reg_not_list(Rarg_x))       
3739_endsubp(builtin_assq) 
3740
3741_spentry(builtin_memq)
3742        __(cmpb $fulltag_nil,%arg_z_b)
3743        __(jmp 3f)
37441:      __(movb $tagmask,%imm0_b)
3745        __(andb %arg_z_b,%imm0_b)
3746        __(cmpb $tag_list,%imm0_b)
3747        __(jnz 2f)
3748        __(_car(%arg_z,%arg_x))
3749        __(_cdr(%arg_z,%temp0))
3750        __(cmpq %arg_x,%arg_y)
3751        __(jz 4f)
3752        __(cmpb $fulltag_nil,%temp0_b)
3753        __(movq %temp0,%arg_z)
37543:      __(jnz 1b)
37554:      __(repret)                             
37562:      __(uuo_error_reg_not_list(Rarg_z))
3757_endsubp(builtin_memq)
3758
3759        __ifdef([X8664])
3760logbitp_max_bit = 61
3761        __else
3762logbitp_max_bit = 30
3763        __endif
3764       
3765_spentry(builtin_logbitp)
3766        __(movb %arg_z_b,%imm0_b)
3767        __(orb %arg_y_b,%imm0_b)
3768        __(testb $fixnummask,%imm0_b)
3769        __(jnz 1f)
3770        __(unbox_fixnum(%arg_y,%imm0))
3771        __(movl $logbitp_max_bit-1+fixnumshift,%imm1_l)
3772        __(js 1f)               /* bit number negative */
3773        __(addb $fixnumshift,%imm0_b)
3774        __(cmpq $logbitp_max_bit<<fixnumshift,%arg_y)
3775        __(cmovael %imm1_l,%imm0_l)
3776        __(bt %imm0,%arg_z)
3777        __(condition_to_boolean(b,%imm0,%arg_z))
3778        __(ret)
37791:      __(jump_builtin(_builtin_logbitp,2))
3780_endsubp(builtin_logbitp)
3781
3782_spentry(builtin_logior)
3783        __(movb %arg_y_b,%imm0_b)
3784        __(orb %arg_z_b,%imm0_b)
3785        __(testb $fixnummask,%imm0_b)
3786        __(jne 1f)
3787        __(orq %arg_y,%arg_z)
3788        __(ret)
37891:     
3790        __(jump_builtin(_builtin_logior,2))
3791               
3792_endsubp(builtin_logior)
3793
3794_spentry(builtin_logand)
3795        __(movb %arg_y_b,%imm0_b)
3796        __(orb %arg_z_b,%imm0_b)
3797        __(testb $fixnummask,%imm0_b)
3798        __(jne 1f)
3799        __(andq %arg_y,%arg_z)
3800        __(ret)
38011:             
3802        __(jump_builtin(_builtin_logand,2))
3803_endsubp(builtin_logand)
3804
3805_spentry(builtin_negate)
3806        __(testb $fixnummask,%arg_z_b)
3807        __(jne 1f)
3808        __(negq %arg_z)
3809        __(jo,pn C(fix_one_bit_overflow))
3810        __(repret)
38111:             
3812        __(jump_builtin(_builtin_negate,1))     
3813_endsubp(builtin_negate)
3814
3815_spentry(builtin_logxor)
3816        __(movb %arg_y_b,%imm0_b)
3817        __(orb %arg_z_b,%imm0_b)
3818        __(testb $fixnummask,%imm0_b)
3819        __(jne 1f)
3820        __(xorq %arg_y,%arg_z)
3821        __(ret)
38221:             
3823        __(jump_builtin(_builtin_logxor,2))
3824_endsubp(builtin_logxor)
3825
3826
3827_spentry(builtin_aset1)
3828        __(extract_typecode(%arg_x,%imm0))
3829        __(box_fixnum(%imm0,%temp0))
3830        __(cmpb $min_vector_subtag,%imm0_b)
3831        __(ja _SPsubtag_misc_set)
3832        __(jump_builtin(_builtin_aset1,3))
3833_endsubp(builtin_aset1)
3834
3835
3836_spentry(builtin_ash)
3837        __(movb %arg_y_b,%imm0_b)
3838        __(orb %arg_z_b,%imm0_b)
3839        __(testb $fixnummask,%imm0_b)
3840        __(jne 9f)
3841        __(unbox_fixnum(%arg_y,%imm1))
3842        __(unbox_fixnum(%arg_z,%imm0))
3843        /* Z flag set if zero ASH shift count   */
3844        __(jnz 1f)
3845        __(movq %arg_y,%arg_z)  /* shift by 0   */
3846        __(ret)
38471:      __(jns 3f)
3848        __(rcmpq(%imm0,$-63))
3849        __(jg 2f)
3850        __(sar $63,%imm1)
3851        __(box_fixnum(%imm1,%arg_z))
3852        __(ret)
38532:      /* Right-shift by small fixnum   */
3854        __(negb %imm0_b)
3855        __(movzbl %imm0_b,%ecx)
3856        __(sar %cl,%imm1)
3857        __(box_fixnum(%imm1,%arg_z))
3858        __(ret)
38593:      /* Left shift by fixnum. We cant shift by more than 63 bits, though  */
3860        /* shifting by 64 is actually easy.   */
3861        __(rcmpq(%imm0,$64))
3862        __(jg 9f)
3863        __(jne 4f)
3864        /* left-shift by 64-bits exactly   */
3865        __(xorl %imm0_l,%imm0_l)
3866        __(jmp C(makes128))
38674:      /* left-shift by 1..63 bits.  Safe to move shift count to %rcx/%cl   */
3868        __(movzbl %imm0_b,%ecx)  /* zero-extending mov   */
3869        __(movq %imm1,%imm0)
3870        __(sarq $63,%imm1)
3871        __(js 5f)
3872        __(shld %cl,%imm0,%imm1)
3873        __(shl %cl,%imm0)
3874        __(jmp C(makes128))
38755:      __(shld %cl,%imm0,%imm1)
3876        __(shl %cl,%imm0)
3877        __(jmp C(makes128))
38789:     
3879        __(jump_builtin(_builtin_ash,2))
3880_endsubp(builtin_ash)
3881
3882_spentry(builtin_aref1)
3883        __(extract_typecode(%arg_y,%imm0))
3884        __(cmpb $min_vector_subtag,%imm0_b)
3885        __(box_fixnum_no_flags(%imm0,%arg_x))
3886        __(ja _SPsubtag_misc_ref)
3887        __(jump_builtin(_builtin_aref1,2))
3888_endsubp(builtin_aref1)
3889
3890/* Arg_z is either a MACPTR containing the function address or a boxed fixnum.  */
3891/*   %imm0.b (aka %al) contains the number (0-7) of args passed in FP regs.  */
3892/*   On entry, the foreign stack contains a frame containing at least 8 words:  */
3893
3894/*   * -> aligned on 16-byte boundary  */
3895/*  *backlink   <-      foreign %rsp              */
3896/*   unused  */
3897/*   scalar arg 0               passed in %rdi  */
3898/*   scalar arg 1         passed in %rsi  */
3899/*   scalar arg 2               passed in %rdx  */
3900/*   scalar arg 3               passed in %rcx  */
3901/*   scalar arg 4               passed in %r8  */
3902/*   scalar arg 5               passed in %r9  */
3903/*  *address of first memory arg  */
3904/*   ...  */
3905/*   possible scratch space  */
3906/*  *previous %rsp value  */
3907
3908/*   Any floating-point args will have been loaded into %xmm0-%xmm7 by the caller.  */
3909/*   When this returns, the foreign %rsp will contain its previous value, and  */
3910/*   the function result will be in %rax (and possibly %rdx) or %xmm0 (+ %xmm1).  */
3911
3912_spentry(ffcall)
3913LocalLabelPrefix[]ffcall:               
3914        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
3915          if not a fixnum, get the first word */
3916        __(unbox_fixnum(%arg_z,%imm1))
3917        __(testb $fixnummask,%arg_z_b)
3918        __(je 0f)
3919        __(movq macptr.address(%arg_z),%imm1)
39200:             
3921        /* Save lisp registers   */
3922        __(push %rbp)
3923        __(movq %rsp,%rbp)
3924        __(push %temp0)
3925        __(push %temp1)
3926        __(push %temp2)
3927        __(push %arg_x)
3928        __(push %arg_y)
3929        __(push %arg_z)
3930        __(push %fn)
3931        __(push %save0)
3932        __(push %save1)
3933        __(push %save2)
3934        __ifndef([WINDOWS])
3935        __(push %save3)         /* 11 registers pushed after %rbp */
3936        __endif
3937        __(movq %rsp,rcontext(tcr.save_vsp))
3938        __(movq %rbp,rcontext(tcr.save_rbp))
3939        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
3940        __(movq rcontext(tcr.foreign_sp),%rsp)
3941        __(stmxcsr rcontext(tcr.lisp_mxcsr))
3942        __(emms)
3943        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
3944        __(movq (%rsp),%rbp)
3945        __ifdef([DARWIN_GS_HACK])
3946         /* At this point, %imm1=%rdx is live (contains
3947            the entrypoint) and %imm0.b=%al contains
3948            info about xmm register arguments; the lisp registers are
3949            all saved, and the foreign arguments are
3950            on the foreign stack (about to be popped
3951            off).  Save the linear TCR address in %save0/%r15
3952            so that we can restore it later, and preserve
3953            the entrypoint somewhere where C won't bash it.
3954            Note that dereferencing the entrypoint from
3955            foreign code has never been safe (unless it's
3956            a fixnum */
3957         __(save_tcr_linear(%save0))
3958         __(movq %imm1,%save1)
3959         __(movq %imm0,%save2)
3960         __(set_foreign_gs_base())
3961         __(movq %save1,%imm1)
3962         __(movq %save2,%imm0)
3963        __endif
3964        __ifdef([WINDOWS])
3965        /* Preserve TCR pointer */
3966        __(movq %rcontext_reg, %save0)
3967        __endif
3968LocalLabelPrefix[]ffcall_setup:
3969        __(addq $2*node_size,%rsp)
3970        __(movq %imm1,%r11)
3971        __(pop %carg0)
3972        __(pop %carg1)
3973        __(pop %carg2)
3974        __(pop %carg3)
3975        __ifdef([WINDOWS])
3976        __(sub $20, %rsp) /* Make room for arg register spill */
3977        __else
3978        __(pop %carg4)
3979        __(pop %carg5)
3980        __endif
3981LocalLabelPrefix[]ffcall_setup_end:
3982LocalLabelPrefix[]ffcall_call:
3983        __(call *%r11)
3984LocalLabelPrefix[]ffcall_call_end:               
3985        __(movq %rbp,%rsp)
3986        __ifdef([DARWIN_GS_HACK])
3987         /* %rax/%rdx contains the return value (maybe), %save0 still
3988            contains the linear tcr address.  Preserve %rax/%rdx here. */
3989         __(movq %rax,%save1)
3990         __(movq %rdx,%save2)
3991         __(set_gs_base(%save0))
3992         __(movq %save1,%rax)
3993         __(movq %save2,%rdx)
3994        __endif
3995        __ifdef([WINDOWS])
3996        __(movq %save0, %rcontext_reg)
3997        __endif
3998        __(movq %rsp,rcontext(tcr.foreign_sp))
3999        __ifndef([WINDOWS])
4000        __(clr %save3)
4001        __endif
4002        __(clr %save2)
4003        __(clr %save1)
4004        __(clr %save0)
4005        __(clr %arg_z)
4006        __(clr %arg_y)
4007        __(clr %arg_x)
4008        __(clr %temp2)
4009        __(clr %temp1)
4010        __(clr %temp0)
4011        __(clr %fn)
4012        __(pxor %fpzero,%fpzero)
4013        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
4014        __(je 0f)
4015        __(movl %arg_x_l,rcontext(tcr.ffi_exception))
4016        __(jmp 1f)
40170:      __(stmxcsr rcontext(tcr.ffi_exception))
40181:      __(movq rcontext(tcr.save_vsp),%rsp)
4019        __(movq rcontext(tcr.save_rbp),%rbp)
4020        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4021        __ifndef([WINDOWS])
4022        __(pop %save3)
4023        __endif
4024        __(pop %save2)
4025        __(pop %save1)
4026        __(pop %save0)
4027        __(pop %fn)
4028        __(pop %arg_z)
4029        __(pop %arg_y)
4030        __(pop %arg_x)
4031        __(pop %temp2)
4032        __(pop %temp1)
4033        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4034        __(check_pending_interrupt(%temp0))
4035        __(pop %temp0)
4036        __(leave)
4037        __ifdef([DARWIN])
4038        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,rcontext(tcr.flags))
4039        __(jc,pn 0f)
4040        __endif
4041        __(ret)
4042        __ifdef([DARWIN])
40430:
4044        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4045        /* Box it, then signal a lisp error. */
4046        __(movq %imm0,%imm2)
4047        __(movq $macptr_header,%rax)
4048        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4049        __(movq %imm2,macptr.address(%arg_z))
4050        __(movq $XFOREIGNEXCEPTION,%arg_y)
4051        __(set_nargs(2))
4052        __(jmp _SPksignalerr)
4053        __endif
4054        __ifdef([DARWIN])       
4055        /* Handle exceptions, for ObjC 2.0 */
4056LocalLabelPrefix[]ffcallLandingPad:     
4057        __(movq %rax,%save1)
4058        __(cmpq $1,%rdx)
4059        __(je 1f)
4060        __(movq %rax,%rdi)
4061LocalLabelPrefix[]ffcallUnwindResume:           
4062        __(call *lisp_global(unwind_resume))
4063LocalLabelPrefix[]ffcallUnwindResume_end:         
40641:      __(movq %save1,%rdi)
4065LocalLabelPrefix[]ffcallBeginCatch:             
4066        __(call *lisp_global(objc2_begin_catch))
4067LocalLabelPrefix[]ffcallBeginCatch_end:         
4068        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4069LocalLabelPrefix[]ffcallEndCatch:               
4070        __(call *lisp_global(objc2_end_catch))
4071LocalLabelPrefix[]ffcallEndCatch_end:           
4072        __(ref_global(get_tcr,%rax))
4073        __(movq $1,%rdi)
4074        __(call *%rax)
4075        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4076        __(movq %save1,%rax)
4077        __(jmp LocalLabelPrefix[]ffcall_call_end)
4078LocalLabelPrefix[]ffcall_end:   
4079        __endif
4080_endsubp(ffcall)
4081
4082        __ifdef([DARWIN])
4083        .section __DATA,__gcc_except_tab
4084GCC_except_table0:
4085        .align 3
4086LLSDA1:
4087        .byte   0xff    /* @LPStart format (omit) */
4088        .byte   0x0     /* @TType format (absolute) */
4089        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4090        .byte   0x3     /* call-site format (udata4) */
4091        .byte   0x41    /* uleb128 0x41; Call-site table length */
4092       
4093        .long Lffcall_setup-Lffcall     /* region 0 start */
4094        .long Lffcall_setup_end-Lffcall_setup   /* length */
4095        .long   0x0     /* landing pad */
4096        .byte   0x0     /* uleb128 0x0; action */
4097       
4098        .long Lffcall_call-Lffcall      /* region 1 start */
4099        .long Lffcall_call_end-Lffcall_call     /* length */
4100        .long LffcallLandingPad-Lffcall /* landing pad */
4101        .byte   0x1     /* uleb128 0x1; action */
4102       
4103        .long LffcallUnwindResume-Lffcall       /* region 2 start */
4104        .long LffcallUnwindResume_end-LffcallUnwindResume       /* length */
4105        .long   0x0     /* landing pad */
4106        .byte   0x0     /* uleb128 0x0; action */
4107       
4108        .long LffcallBeginCatch-Lffcall /* region 3 start */
4109        .long LffcallBeginCatch_end-LffcallBeginCatch   /* length */
4110        .long 0 /* landing pad */
4111        .byte   0x0     /* uleb128 0x0; action */
4112       
4113        .long LffcallEndCatch-Lffcall
4114        .long LffcallEndCatch_end-LffcallEndCatch       /* length */
4115        .long   0x0     /* landing pad */
4116        .byte   0x0     /* uleb128 0x0; action */
4117        .byte   0x1     /* Action record table */
4118        .byte   0x0
4119        .align 3
4120        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4121        .text
4122        __endif
4123
4124_spentry(ffcall_return_registers)
4125LocalLabelPrefix[]ffcall_return_registers:               
4126        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
4127          if not a fixnum, get the first word */
4128        __(unbox_fixnum(%arg_z,%imm1))
4129        __(testb $fixnummask,%arg_z_b)
4130        __(je 0f)
4131        __(movq macptr.address(%arg_z),%imm1)
41320:             
4133        /* Save lisp registers   */
4134        __(push %rbp)
4135        __(movq %rsp,%rbp)
4136        __(push %temp0)
4137        __(push %temp1)
4138        __(push %temp2)
4139        __(push %arg_x)
4140        __(push %arg_y)
4141        __(push %arg_z)
4142        __(push %save0)
4143        __(push %save1)
4144        __(push %save2)
4145        __ifndef([WINDOWS])
4146        __(push %save3)
4147        __endif
4148        __(movq macptr.address(%arg_y),%rbx)  /* %rbx non-volatile */
4149        __(push %fn)
4150        __(movq %rsp,rcontext(tcr.save_vsp))
4151        __(movq %rbp,rcontext(tcr.save_rbp))
4152        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4153        __(movq rcontext(tcr.foreign_sp),%rsp)
4154        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4155        __(emms)
4156        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4157        __(movq (%rsp),%rbp)
4158        __ifdef([DARWIN_GS_HACK])
4159         /* At this point, %imm1=%rdx is live (contains
4160            the entrypoint) and %imm0.b=%al contains
4161            xmm argument info; the lisp registers are
4162            all saved, and the foreign arguments are
4163            on the foreign stack (about to be popped
4164            off).  Save the linear TCR address in %save0/%r15
4165            so that we can restore it later, and preserve
4166            the entrypoint somewhere where C won't bash it.
4167            Note that dereferencing the entrypoint from
4168            foreign code has never been safe (unless it's
4169            a fixnum */
4170         __(save_tcr_linear(%save0))
4171         __(movq %imm0,%save1)
4172         __(movq %imm1,%save2)
4173         __(set_foreign_gs_base())
4174         __(movq %save1,%imm0)
4175         __(movq %save2,%imm1)
4176        __endif
4177        __ifdef([WINDOWS])
4178        /* Preserve TCR pointer */
4179        __(movq %rcontext_reg, %save0)
4180        __endif
4181        __(movq %imm1,%r11)
4182LocalLabelPrefix[]ffcall_return_registers_setup:
4183        __(addq $2*node_size,%rsp)
4184        __(pop %carg0)
4185        __(pop %carg1)
4186        __(pop %carg2)
4187        __(pop %carg3)
4188        __ifdef([WINDOWS])
4189        __(sub $20, %rsp) /* Make room for arg register spill */
4190        __else
4191        __(pop %carg4)
4192        __(pop %carg5)
4193        __endif
4194LocalLabelPrefix[]ffcall_return_registers_setup_end:
4195LocalLabelPrefix[]ffcall_return_registers_call:
4196        __(call *%r11)
4197LocalLabelPrefix[]ffcall_return_registers_call_end:               
4198        __(movq %rax,(%rbx))
4199        __(movq %rdx,8(%rbx))
4200        __(movsd %xmm0,16(%rbx))
4201        __(movsd %xmm1,24(%rbx))
4202        __(movq %rbp,%rsp)
4203        __ifdef([DARWIN_GS_HACK])
4204         /* %rax/%rdx contains the return value (maybe), %save0 still
4205            contains the linear tcr address.  Preserve %rax/%rdx here. */
4206         __(set_gs_base(%save0))
4207         __(movq (%save2),%rax)
4208         __(movq 8(%save2),%rdx)
4209         __(movsd 16(%save2),%xmm0)
4210         __(movsd 24(%save2),%xmm1)
4211        __endif
4212        __ifdef([WINDOWS])
4213        __(movq %save0, %rcontext_reg)
4214        __endif
4215        __(movq %rsp,rcontext(tcr.foreign_sp))       
4216        __ifndef([WINDOWS])
4217        __(clr %save3)
4218        __endif
4219        __(clr %save2)
4220        __(clr %save1)
4221        __(clr %save0)
4222        __(clr %arg_z)
4223        __(clr %arg_y)
4224        __(clr %arg_x)
4225        __(clr %temp2)
4226        __(clr %temp1)
4227        __(clr %temp0)
4228        __(clr %fn)
4229        __(pxor %fpzero,%fpzero)
4230        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
4231        __(je 0f)
4232        __(movl %arg_x_l,rcontext(tcr.ffi_exception))
4233        __(jmp 1f)
42340:      __(stmxcsr rcontext(tcr.ffi_exception))
42351:      __(movq rcontext(tcr.save_vsp),%rsp)
4236        __(movq rcontext(tcr.save_rbp),%rbp)
4237        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4238        __(pop %fn)
4239        __ifndef([WINDOWS])
4240        __(pop %save3)
4241        __endif
4242        __(pop %save2)
4243        __(pop %save1)
4244        __(pop %save0)
4245        __(pop %arg_z)
4246        __(pop %arg_y)
4247        __(pop %arg_x)
4248        __(pop %temp2)
4249        __(pop %temp1)
4250        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4251        __(check_pending_interrupt(%temp0))
4252        __(pop %temp0)
4253        __(leave)
4254        __ifdef([DARWIN])
4255        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,rcontext(tcr.flags))
4256        __(jc,pn 0f)
4257        __endif
4258        __(ret)
4259        __ifdef([DARWIN])
42600:
4261        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4262        /* Box it, then signal a lisp error. */
4263        __(movq %imm0,%imm2)
4264        __(movq $macptr_header,%rax)
4265        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4266        __(movq %imm2,macptr.address(%arg_z))
4267        __(movq $XFOREIGNEXCEPTION,%arg_y)
4268        __(set_nargs(2))
4269        __(jmp _SPksignalerr)
4270        __endif
4271        __ifdef([DARWIN])       
4272        /* Handle exceptions, for ObjC 2.0 */
4273LocalLabelPrefix[]ffcall_return_registersLandingPad:     
4274        __(movq %rax,%save1)
4275        __(cmpq $1,%rdx)
4276        __(je 1f)
4277        __(movq %rax,%rdi)
4278LocalLabelPrefix[]ffcall_return_registersUnwindResume:           
4279        __(call *lisp_global(unwind_resume))
4280LocalLabelPrefix[]ffcall_return_registersUnwindResume_end:         
42811:      __(movq %save1,%rdi)
4282LocalLabelPrefix[]ffcall_return_registersBeginCatch:             
4283        __(call *lisp_global(objc2_begin_catch))
4284LocalLabelPrefix[]ffcall_return_registersBeginCatch_end:         
4285        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4286LocalLabelPrefix[]ffcall_return_registersEndCatch:               
4287        __(call *lisp_global(objc2_end_catch))
4288LocalLabelPrefix[]ffcall_return_registersEndCatch_end:           
4289        __(ref_global(get_tcr,%rax))
4290        __(movq $1,%rdi)
4291        __(call *%rax)
4292        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4293        __(movq %save1,%rax)
4294        __(jmp LocalLabelPrefix[]ffcall_return_registers_call_end)
4295LocalLabelPrefix[]ffcall_return_registers_end:   
4296        __endif
4297_endsubp(ffcall_returning_registers)
4298
4299        __ifdef([DARWIN])
4300        .section __DATA,__gcc_except_tab
4301GCC_except_table1:
4302        .align 3
4303LLSDA2:
4304        .byte   0xff    /* @LPStart format (omit) */
4305        .byte   0x0     /* @TType format (absolute) */
4306        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4307        .byte   0x3     /* call-site format (udata4) */
4308        .byte   0x41    /* uleb128 0x41; Call-site table length */
4309       
4310        .long Lffcall_return_registers_setup-Lffcall_return_registers   /* region 0 start */
4311        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup /* length */
4312        .long   0x0     /* landing pad */
4313        .byte   0x0     /* uleb128 0x0; action */
4314       
4315        .long Lffcall_return_registers_call-Lffcall_return_registers    /* region 1 start */
4316        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call   /* length */
4317        .long Lffcall_return_registersLandingPad-Lffcall_return_registers       /* landing pad */
4318        .byte   0x1     /* uleb128 0x1; action */
4319       
4320        .long Lffcall_return_registersUnwindResume-Lffcall_return_registers     /* region 2 start */
4321        .long Lffcall_return_registersUnwindResume_end-Lffcall_return_registersUnwindResume     /* length */
4322        .long   0x0     /* landing pad */
4323        .byte   0x0     /* uleb128 0x0; action */
4324       
4325        .long Lffcall_return_registersBeginCatch-Lffcall_return_registers       /* region 3 start */
4326        .long Lffcall_return_registersBeginCatch_end-Lffcall_return_registersBeginCatch /* length */
4327        .long 0 /* landing pad */
4328        .byte   0x0     /* uleb128 0x0; action */
4329       
4330        .long Lffcall_return_registersEndCatch-Lffcall_return_registers
4331        .long Lffcall_return_registersEndCatch_end-Lffcall_return_registersEndCatch     /* length */
4332        .long   0x0     /* landing pad */
4333        .byte   0x0     /* uleb128 0x0; action */
4334        .byte   0x1     /* Action record table */
4335        .byte   0x0
4336        .align 3
4337        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4338        .text
4339        __endif
4340               
4341_spentry(syscall)
4342        /* Save lisp registers   */
4343        __(push %rbp)
4344        __(movq %rsp,%rbp)
4345        __(push %temp0)
4346        __(push %temp1)
4347        __(push %temp2)
4348        __(push %arg_x)
4349        __(push %arg_y)
4350        __(push %arg_z)
4351        __(push %save0)
4352        __(push %save1)
4353        __(push %save2)
4354        __(push %save3)
4355        __(push %fn)
4356        __(movq %rsp,rcontext(tcr.save_vsp))
4357        __(movq %rbp,rcontext(tcr.save_rbp))
4358        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4359        __(movq rcontext(tcr.foreign_sp),%rsp)
4360        __(emms)
4361        __(movq (%rsp),%rbp)
4362        __(addq $2*node_size,%rsp)
4363        __(unbox_fixnum(%arg_z,%rax))
4364        __(pop %rdi)
4365        __(pop %rsi)
4366        __(pop %rdx)
4367        __(pop %r10)            /*  syscalls take 4th param in %r10, not %rcx   */
4368        __(pop %r8)
4369        __(pop %r9)
4370        __(syscall)
4371        __ifdef([SYSCALL_SETS_CARRY_ON_ERROR])
4372         __(jnc 0f)
4373         __(negq %rax)
43740:     
4375        __endif       
4376        __(movq %rbp,%rsp)
4377        __(movq %rsp,rcontext(tcr.foreign_sp))       
4378        __(clr %save3)
4379        __(clr %save2)
4380        __(clr %save1)
4381        __(clr %save0)
4382        __(clr %arg_z)
4383        __(clr %arg_y)
4384        __(clr %arg_x)
4385        __(clr %temp2)
4386        __(clr %temp1)
4387        __(clr %temp0)
4388        __(clr %fn)
4389        __(pxor %fpzero,%fpzero)
4390        __(movq rcontext(tcr.save_vsp),%rsp)
4391        __(movq rcontext(tcr.save_rbp),%rbp)
4392        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4393        __(pop %fn)
4394        __(pop %save3)
4395        __(pop %save2)
4396        __(pop %save1)
4397        __(pop %save0)
4398        __(pop %arg_z)
4399        __(pop %arg_y)
4400        __(pop %arg_x)
4401        __(pop %temp2)
4402        __(pop %temp1)
4403        __(check_pending_interrupt(%temp0))
4404        __(pop %temp0)
4405        __(leave)
4406        __(ret)
4407_endsubp(syscall)               
4408
4409/* We need to reserve a frame here if (a) nothing else was already pushed and (b) */
4410/*   we push something (e.g., more than 3 args in the lexpr)      */
4411_spentry(spread_lexprz)
4412        new_local_labels()
4413        __(movq (%arg_z),%imm0)
4414        __(testl %nargs,%nargs) /* anything pushed by caller ? */
4415        __(leaq node_size(%arg_z,%imm0),%imm1)
4416        __(jne 0f)              /* yes, caller has already created frame. */
4417        __(cmpw $(nargregs*node_size),%imm0_w) /* will we push anything ? */
4418        __(jbe 0f)
4419        __(push $reserved_frame_marker)
4420        __(push $reserved_frame_marker)
44210:      __(addw %imm0_w,%nargs_w)
4422        __(cmpw $(nargregs*node_size),%imm0_w)
4423        __(jae 9f)
4424        __(cmpw $(2*node_size),%imm0_w)
4425        __(je 2f)
4426        __(testw %imm0_w,%imm0_w)
4427        __(jne 1f)
4428        /* lexpr count was 0; vpop the args that */
4429        /* were pushed by the caller */
4430        __(testl %nargs,%nargs)
4431        __(je local_label(all_args_popped))
4432        __(pop %arg_z)
4433local_label(maybe_pop_yx):             
4434        __(cmpl $(1*node_size),%nargs)
4435        __(je local_label(all_args_popped))
4436        __(pop %arg_y)
4437        __(cmpl $(2*node_size),%nargs)
4438        __(je local_label(all_args_popped))
4439local_label(pop_arg_x):         
4440        __(pop %arg_x)
4441local_label(all_args_popped):   
4442        /* If all args fit in registers but some were pushed */
4443        /* by the caller, discard the reserved frame that the caller */
4444        /* pushed.         */
4445        __(cmpw %imm0_w,%nargs_w)
4446        __(je local_label(go))
4447        __(cmpl $(nargregs*node_size),%nargs)
4448        __(ja local_label(go))
4449        __(addq $(2*node_size),%rsp)
4450local_label(go):       
4451        __(jmp *%ra0)       
4452        /* vpush args from the lexpr until we have only */
4453        /* three left, then assign them to arg_x, arg_y, */
4454        /* and arg_z. */
44558:      __(cmpw $(4*node_size),%imm0_w)
4456        __(lea -1*node_size(%imm0),%imm0)
4457        __(push -node_size(%imm1))
4458        __(lea -1*node_size(%imm1),%imm1)
44599:      __(jne 8b)
4460        __(movq -node_size*1(%imm1),%arg_x)
4461        __(movq -node_size*2(%imm1),%arg_y)
4462        __(movq -node_size*3(%imm1),%arg_z)
4463        __(jmp *%ra0)
4464
4465        /* lexpr count is two: set arg_y, arg_z from the */
4466        /* lexpr, maybe vpop arg_x */
44672:      __(cmpl $(2*node_size),%nargs)
4468        __(movq -node_size*1(%imm1),%arg_y)
4469        __(movq -node_size*2(%imm1),%arg_z)
4470        __(jne local_label(pop_arg_x))
4471        __(jmp *%ra0)
4472        /* lexpr count is one: set arg_z from the lexpr, */
4473        /* maybe vpop arg_y, arg_x  */
44741:      __(movq -node_size*1(%imm1),%arg_z)
4475        __(jmp local_label(maybe_pop_yx))
4476_endsubp(spread_lexprz)
4477       
4478
4479
4480
4481/* Callback index in %r11         */
4482_spentry(callback)
4483        __(push %rbp)
4484        __(movq %rsp,%rbp)
4485        /* C scalar args   */
4486        __(push %rdi)   /* -8(%rbp)   */
4487        __(push %rsi)
4488        __(push %rdx)
4489        __(push %rcx)
4490        __(push %r8)
4491        __(push %r9)
4492        /* FP arg regs   */
4493        __(subq $8*8,%rsp)
4494        __(movq %xmm0,7*8(%rsp))        /* -56(%rbp)   */
4495        __(movq %xmm1,6*8(%rsp))
4496        __(movq %xmm2,5*8(%rsp))
4497        __(movq %xmm3,4*8(%rsp))
4498        __(movq %xmm4,3*8(%rsp))
4499        __(movq %xmm5,2*8(%rsp))
4500        __(movq %xmm6,1*8(%rsp))
4501        __(movq %xmm7,0*8(%rsp))
4502        /* C NVRs   */
4503        __(push %r12)
4504        __(push %r13)
4505        __(push %r14)
4506        __(push %r15)
4507        __(push %rbx)
4508        __(push %rbp)
4509        __ifdef([HAVE_TLS])
4510         /* TCR initialized for lisp ?   */
4511         __ifndef([WINDOWS]) /* FIXME */
4512         __(movq %fs:current_tcr@TPOFF+tcr.linear,%rax)
4513         __endif
4514         __(testq %rax,%rax)
4515         __(jne 1f)
4516        __endif
4517        __(movq %r11,%r12)
4518        __(ref_global(get_tcr,%rax))
4519        __(movq $1,%rdi)
4520        __(call *%rax)
4521        __ifdef([DARWIN_GS_HACK])
4522         /* linear TCR address in now in %rax; callback index was
4523            saved in %r12 a moment ago. */
4524         __(set_gs_base(%rax))
4525        __endif
4526        __(movq %r12,%r11)
45271:      /* Align foreign stack for lisp   */
4528        __(pushq rcontext(tcr.save_rbp)) /* mark cstack frame's "owner" */
4529        __(pushq rcontext(tcr.foreign_sp))
4530        /* init lisp registers   */
4531        __(movq %r11,%rax)
4532        __(movq %rsp,rcontext(tcr.foreign_sp))
4533        __(clr %save3)
4534        __(clr %save2)
4535        __(clr %save1)
4536        __(clr %save0)
4537        __(clr %arg_z)
4538        __(clr %arg_y)
4539        __(clr %arg_x)
4540        __(clr %temp2)
4541        __(clr %temp1)
4542        __(clr %temp0)
4543        __(clr %fn)
4544        __(pxor %fpzero,%fpzero)
4545        __(movq rcontext(tcr.save_vsp),%rsp)
4546        __(box_fixnum(%rax,%arg_y))
4547        __(movq %rbp,%arg_z)
4548        __(movq rcontext(tcr.save_rbp),%rbp)
4549        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4550        __(movq (%rsp),%save3)
4551        __(movq 8(%rsp),%save2)
4552        __(movq 16(%rsp),%save1)
4553        __(movq 24(%rsp),%save0)
4554        __(stmxcsr rcontext(tcr.foreign_mxcsr))
4555        __(andb $~mxcsr_all_exceptions,rcontext(tcr.foreign_mxcsr))
4556        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4557        __(movq $nrs.callbacks,%fname)
4558        __(lea local_label(back_from_callback)(%rip),%ra0)
4559        __(set_nargs(2))
4560        __(push %ra0)
4561        __(jump_fname())
4562__(tra(local_label(back_from_callback)))
4563        __(movq %rsp,rcontext(tcr.save_vsp))
4564        __(movq %rbp,rcontext(tcr.save_rbp))
4565        __(movq rcontext(tcr.foreign_sp),%rsp)
4566        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4567        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4568        __(emms)
4569        __(pop rcontext(tcr.foreign_sp))
4570        __(addq $node_size,%rsp)
4571        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4572        __ifdef([DARWIN_GS_HACK])
4573         /* Lucky us; nothing is live here */
4574         __(set_foreign_gs_base())
4575        __endif
4576        __(pop %rbp)
4577        __(pop %rbx)
4578        __(pop %r15)
4579        __(pop %r14)
4580        __(pop %r13)
4581        __(pop %r12)
4582        __(movq -8(%rbp),%rax)
4583        __(movq -16(%rbp),%rdx)
4584        __(movq -24(%rbp),%xmm0)
4585        __(movq -32(%rbp),%xmm1)
4586        __(leave)
4587        __(ret)         
4588_endsubp(callback)
4589
4590/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
4591   We don't know whether the array is alleged to be simple or
4592   not, and don't know anythng about the element type.  */
4593               
4594_spentry(aref2)
4595        __(testb $fixnummask,%arg_y_b)
4596        __(jne 0f)
4597       
4598        __(testb $fixnummask,%arg_z_b)
4599        __(jne 1f)
4600        __(extract_typecode(%arg_x,%imm0))
4601        __(cmpb $subtag_arrayH,%imm0_b)
4602        __(jne 2f)
4603        __(cmpq $2<<fixnumshift,arrayH.rank(%arg_x))
4604        __(jne 2f)
4605        __(cmpq arrayH.dim0(%arg_x),%arg_y)
4606        __(jae 3f)
4607        __(movq arrayH.dim0+node_size(%arg_x),%imm0)
4608        __(cmpq %imm0,%arg_z)
4609        __(jae 4f)
4610        __(unbox_fixnum(%imm0,%imm0))
4611        __(mulq %arg_y)         /* imm0 <- imm0 * arg_y */
4612        __(addq %imm0,%arg_z)
4613        __(movq %arg_x,%arg_y)
46146:      __(addq arrayH.displacement(%arg_y),%arg_z)
4615        __(movq arrayH.data_vector(%arg_y),%arg_y)
4616        __(extract_subtag(%arg_y,%imm1_b))
4617        __(cmpb $subtag_vectorH,%imm1_b)
4618        __(ja C(misc_ref_common))
4619        __(jmp 6b)
46200:      __(uuo_error_reg_not_fixnum(Rarg_y))
46211:      __(uuo_error_reg_not_fixnum(Rarg_z))
46222:      __(uuo_error_reg_not_type(Rarg_x,error_object_not_array_2d))
46233:      __(uuo_error_array_bounds(Rarg_y,Rarg_x))
46244:      __(uuo_error_array_bounds(Rarg_z,Rarg_x))
4625       
4626_endsubp(aref2)
4627
4628/* %temp0 = array, %arg_x = i,%arg_y = j, %arg_z = k */
4629_spentry(aref3)
4630        __(testb $fixnummask,%arg_x_b)
4631        __(jne 0f)
4632        __(testb $fixnummask,%arg_y_b)
4633        __(jne 1f)
4634        __(testb $fixnummask,%arg_z_b)
4635        __(jne 2f)
4636        __(extract_typecode(%temp0,%imm0))
4637        __(cmpb $subtag_arrayH,%imm0_b)
4638        __(jne 3f)
4639        __(cmpq $3<<fixnumshift,arrayH.rank(%temp0))
4640        __(jne 3f)
4641        __(cmpq arrayH.dim0(%temp0),%arg_x)
4642        __(jae 5f)
4643        __(movq arrayH.dim0+node_size(%temp0),%imm0)
4644        __(cmpq %imm0,%arg_y)
4645        __(jae 6f)
4646        __(unbox_fixnum(%imm0,%imm0))
4647        __(movq arrayH.dim0+(node_size*2)(%temp0),%imm1)
4648        __(cmpq %imm1,%arg_z)
4649        __(jae 7f)
4650        __(unbox_fixnum(%imm1,%imm1))
4651        __(imulq %imm1,%arg_y)
4652        __(mulq %imm1)
4653        __(imulq %imm0,%arg_x)
4654        __(addq %arg_x,%arg_z)
4655        __(addq %arg_y,%arg_z)
4656        __(movq %temp0,%arg_y)
46578:      __(addq arrayH.displacement(%arg_y),%arg_z)
4658        __(movq arrayH.data_vector(%arg_y),%arg_y)
4659        __(extract_subtag(%arg_y,%imm1_b))
4660        __(cmpb $subtag_vectorH,%imm1_b)
4661        __(ja C(misc_ref_common))
4662        __(jmp 8b)
46630:      __(uuo_error_reg_not_fixnum(Rarg_x))
46641:      __(uuo_error_reg_not_fixnum(Rarg_y))   
46652:      __(uuo_error_reg_not_fixnum(Rarg_z))
46663:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_3d))
46675:      __(uuo_error_array_bounds(Rarg_x,Rtemp0))
46686:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
46697:      __(uuo_error_array_bounds(Rarg_z,Rtemp0))
4670       
4671_endsubp(aref3)
4672       
4673/* As with aref2, but temp0 = array, arg_x = i, arg_y = j, arg_z = new_value */
4674_spentry(aset2)
4675        __(testb $fixnummask,%arg_x_b)
4676        __(jne 0f)
4677        __(testb $fixnummask,%arg_y_b)
4678        __(jne 1f)
4679        __(extract_typecode(%temp0,%imm0))
4680        __(cmpb $subtag_arrayH,%imm0_b)
4681        __(jne 2f)
4682        __(cmpq $2<<fixnumshift,arrayH.rank(%temp0))
4683        __(jne 2f)
4684        __(cmpq arrayH.dim0(%temp0),%arg_x)
4685        __(jae 4f)
4686        __(movq arrayH.dim0+node_size(%temp0),%imm0)
4687        __(cmpq %imm0,%arg_y)
4688        __(jae 5f)
4689        __(unbox_fixnum(%imm0,%imm0))
4690        __(mulq %arg_x)         /* imm0 <- imm0 * arg_x */
4691        __(addq %imm0,%arg_y)
4692        __(movq %temp0,%arg_x)
46936:      __(addq arrayH.displacement(%arg_x),%arg_y)
4694        __(movq arrayH.data_vector(%arg_x),%arg_x)
4695        __(extract_subtag(%arg_x,%imm1_b))
4696        __(cmpb $subtag_vectorH,%imm1_b)
4697        __(ja C(misc_set_common))
4698        __(jmp 6b)
46990:      __(uuo_error_reg_not_fixnum(Rarg_x))
47001:      __(uuo_error_reg_not_fixnum(Rarg_y))
47012:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
47024:      __(uuo_error_array_bounds(Rarg_x,Rtemp0))
47035:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
4704_endsubp(aset2)
4705
4706/* %temp1 = array, %temp0 = i, %arg_x = j, %arg_y = k, %arg_y = newval. */
4707
4708_spentry(aset3)
4709        __(testb $fixnummask,%temp0_b)
4710        __(jne 0f)
4711        __(testb $fixnummask,%arg_x_b)
4712        __(jne 1f)
4713        __(testb $fixnummask,%arg_y_b)
4714        __(jne 2f)
4715        __(extract_typecode(%temp1,%imm0))
4716        __(cmpb $subtag_arrayH,%imm0_b)
4717        __(jne 3f)
4718        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4719        __(jne 3f)
4720        __(cmpq arrayH.dim0(%temp1),%temp0)
4721        __(jae 5f)
4722        __(movq arrayH.dim0+node_size(%temp1),%imm0)
4723        __(cmpq %imm0,%arg_x)
4724        __(jae 6f)
4725        __(unbox_fixnum(%imm0,%imm0))
4726        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4727        __(cmpq %imm1,%arg_y)
4728        __(jae 7f)
4729        __(unbox_fixnum(%imm1,%imm1))
4730        __(imulq %imm1,%arg_x)
4731        __(mulq %imm1)
4732        __(imulq %imm0,%temp0)
4733        __(addq %temp0,%arg_y)
4734        __(addq %arg_x,%arg_y)
4735        __(movq %temp1,%arg_x)
47368:      __(addq arrayH.displacement(%arg_x),%arg_y)
4737        __(movq arrayH.data_vector(%arg_x),%arg_x)
4738        __(extract_subtag(%arg_x,%imm1_b))
4739        __(cmpb $subtag_vectorH,%imm1_b)
4740        __(ja C(misc_set_common))
4741        __(jmp 8b)
4742       
47430:      __(uuo_error_reg_not_fixnum(Rtemp0))
47441:      __(uuo_error_reg_not_fixnum(Rarg_x))
47452:      __(uuo_error_reg_not_fixnum(Rarg_y))
47463:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
47475:      __(uuo_error_array_bounds(Rtemp0,Rtemp1))
47486:      __(uuo_error_array_bounds(Rarg_x,Rtemp1))
47496:      __(uuo_error_array_bounds(Rarg_x,Rtemp1))
47507:      __(uuo_error_array_bounds(Rarg_y,Rtemp1))
4751       
4752_endsubp(aset3)
4753
4754       
4755
4756
4757/* Prepend all but the first five (4 words of code, inner fn) and last   */
4758/* (lfbits) elements of %fn to the "arglist".   */
4759       
4760_spentry(call_closure)
4761        new_local_labels()
4762        __(subq $fulltag_function-fulltag_misc,%fn)
4763        __(vector_length(%fn,%imm0))
4764       
4765        __(subq $6<<fixnumshift,%imm0)  /* imm0 = inherited arg count   */
4766        __(lea (%nargs_q,%imm0),%imm1)
4767        __(cmpl $nargregs<<fixnumshift,%imm1_l)
4768        __(jna,pt local_label(regs_only))
4769        __(pop %ra0)
4770        __(cmpl $nargregs<<fixnumshift,%nargs)
4771        __(jna,pt local_label(no_insert))
4772       
4773/* Some arguments have already been pushed.  Push imm0's worth   */
4774/* of NILs, copy those arguments that have already been vpushed from   */
4775/* the old TOS to the new, then insert all of the inerited args   */
4776/* and go to the function.  */
4777       
4778        __(movq %imm0,%imm1)
4779local_label(push_nil_loop):     
4780        __(push $nil_value)
4781        __(sub $fixnumone,%imm1)
4782        __(jne local_label(push_nil_loop))
4783       
4784/* Need to use arg regs as temporaries here.    */
4785        __(movq %rsp,%temp1)
4786        __(push %arg_z)
4787        __(push %arg_y)
4788        __(push %arg_x)
4789        __(lea 3*node_size(%rsp,%imm0),%arg_x)
4790        __(lea -nargregs<<fixnumshift(%nargs_q),%arg_y)
4791local_label(copy_already_loop): 
4792        __(movq (%arg_x),%arg_z)
4793        __(addq $fixnumone,%arg_x)
4794        __(movq %arg_z,(%temp1))
4795        __(addq $fixnumone,%temp1)
4796        __(subq $fixnumone,%arg_y)
4797        __(jne local_label(copy_already_loop))
4798       
4799        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4800local_label(insert_loop):               
4801        __(movq misc_data_offset(%fn,%imm1),%arg_z)
4802        __(addq $node_size,%imm1)
4803        __(addl $fixnum_one,%nargs)
4804        __(subq $node_size,%arg_x)
4805        __(movq %arg_z,(%arg_x))
4806        __(subq $fixnum_one,%imm0)
4807        __(jne local_label(insert_loop))
4808
4809        /* Recover the argument registers, pushed earlier   */
4810        __(pop %arg_x)
4811        __(pop %arg_y)
4812        __(pop %arg_z)
4813        __(jmp local_label(go))
4814
4815/* Here if nothing was pushed by the caller.  If we're  */
4816/* going to push anything, we have to reserve a stack  */
4817/* frame first. (We'll need to push something if the  */
4818/* sum of %nargs and %imm0 is greater than nargregs)   */
4819       
4820local_label(no_insert):
4821        __(lea (%nargs_q,%imm0),%imm1)
4822        __(cmpq $nargregs<<fixnumshift,%imm1)
4823        __(jna local_label(no_insert_no_frame))
4824        /* Reserve space for a stack frame   */
4825        __(push $reserved_frame_marker)
4826        __(push $reserved_frame_marker)
4827local_label(no_insert_no_frame):       
4828        /* nargregs or fewer args were already vpushed.   */
4829        /* if exactly nargregs, vpush remaining inherited vars.   */
4830        __(cmpl $nargregs<<fixnumshift,%nargs)
4831        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4832        __(leaq 5<<fixnumshift(%imm0),%temp1)
4833        __(jnz local_label(set_regs))
4834local_label(vpush_remaining): 
4835        __(push misc_data_offset(%fn,%imm1))
4836        __(addq $node_size,%imm1)
4837        __(addl $fixnumone,%nargs)
4838        __(subq $node_size,%imm0)
4839        __(jnz local_label(vpush_remaining))
4840        __(jmp local_label(go))
4841local_label(set_regs):
4842        /* if nargs was > 1 (and we know that it was < 3), it must have   */
4843        /* been 2.  Set arg_x, then vpush the remaining args.   */
4844        __(cmpl $fixnumone,%nargs)
4845        __(jle local_label(set_y_z))
4846local_label(set_arg_x): 
4847        __(subq $node_size,%temp1)
4848        __(movq misc_data_offset(%fn,%temp1),%arg_x)
4849        __(addl $fixnumone,%nargs)
4850        __(subq $fixnumone,%imm0)
4851        __(jne local_label(vpush_remaining))
4852        __(jmp local_label(go))
4853        /* Maybe set arg_y or arg_z, preceding args   */
4854local_label(set_y_z):
4855        __(jne local_label(set_arg_z))
4856        /* Set arg_y, maybe arg_x, preceding args   */
4857local_label(set_arg_y): 
4858        __(subq $node_size,%temp1)
4859        __(movq misc_data_offset(%fn,%temp1),%arg_y)
4860        __(addl $fixnumone,%nargs)
4861        __(subq $fixnum_one,%imm0)
4862        __(jnz local_label(set_arg_x))
4863        __(jmp local_label(go))
4864local_label(set_arg_z): 
4865        __(subq $node_size,%temp1)
4866        __(movq misc_data_offset(%fn,%temp1),%arg_z)
4867        __(addl $fixnumone,%nargs)
4868        __(subq $fixnum_one,%imm0)
4869        __(jne local_label(set_arg_y))
4870local_label(go):       
4871        __(movq misc_data_offset+(4*node_size)(%fn),%fn)
4872        __(push %ra0)
4873        __(jmp *%fn)
4874local_label(regs_only):
4875        __(leaq 5<<fixnumshift(%imm0),%temp1)
4876        __(testl %nargs,%nargs)
4877        __(jne local_label(some_args))
4878        __(cmpw $node_size,%imm0)
4879        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_z)
4880        __(je local_label(rgo))
4881        __(cmpw $2*node_size,%imm0)
4882        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_y)
4883        __(je local_label(rgo))
4884        __(movq misc_data_offset-(node_size*3)(%fn,%temp1),%arg_x)
4885local_label(rgo):
4886        __(addw %imm0_w,%nargs_w)
4887        __(jmp *misc_data_offset+(4*node_size)(%fn))
4888local_label(some_args):         
4889        __(cmpl $2*node_size,%nargs)
4890        __(jz local_label(rtwo))
4891        /* One arg was passed, could be one or two inherited args */
4892        __(cmpw $node_size,%imm0)
4893        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_y)
4894        __(je local_label(rgo))
4895        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_x)
4896        __(jmp local_label(rgo))
4897local_label(rtwo):     
4898        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_x)
4899        __(jmp local_label(rgo))
4900_endsubp(call_closure)
4901                                       
4902       
4903_spentry(poweropen_callbackX)
4904_endsubp(poweropen_callbackX)
4905       
4906       
4907_spentry(poweropen_ffcallX)
4908_endsubp(poweropen_ffcallX)
4909               
4910_spentry(poweropen_syscall)
4911_endsubp(poweropen_syscall)
4912
4913_spentry(eabi_ff_call)
4914_endsubp(eabi_ff_call)
4915
4916_spentry(eabi_callback)
4917_endsubp(eabi_callback)
4918
4919
4920/* Unused, and often not used on PPC either  */
4921_spentry(callbuiltin)
4922        __(int $3)
4923_endsubp(callbuiltin)
4924
4925_spentry(callbuiltin0)
4926        __(int $3)
4927_endsubp(callbuiltin0)
4928
4929_spentry(callbuiltin1)
4930        __(int $3)
4931_endsubp(callbuiltin1)
4932
4933_spentry(callbuiltin2)
4934        __(int $3)
4935_endsubp(callbuiltin2)
4936
4937_spentry(callbuiltin3)
4938        __(int $3)
4939_endsubp(callbuiltin3)
4940       
4941_spentry(restorefullcontext)
4942        __(int $3)
4943_endsubp(restorefullcontext)
4944
4945_spentry(savecontextvsp)
4946        __(int $3)
4947_endsubp(savecontextvsp)
4948
4949_spentry(savecontext0)
4950        __(int $3)
4951_endsubp(savecontext0)
4952
4953_spentry(restorecontext)
4954        __(int $3)
4955_endsubp(restorecontext)
4956
4957_spentry(stkconsyz)
4958        __(int $3)
4959_endsubp(stkconsyz)
4960
4961_spentry(stkvcell0)
4962        __(int $3)
4963_endsubp(stkvcell0)
4964
4965_spentry(stkvcellvsp)
4966        __(int $3)
4967_endsubp(stkvcellvsp)
4968
4969_spentry(breakpoint)
4970        __(int $3)
4971_endsubp(breakpoint)
4972
4973               
4974
4975
4976_spentry(unused_5)
4977        __(int $3)
4978_endsubp(unused_5)
4979
4980_spentry(unused_6)
4981        __(int $3)
4982_endsubp(unused_6)
4983
4984        __ifdef([DARWIN])
4985        .if 1
4986        .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
4987EH_frame1:
4988        .set L$set$12,LECIE1-LSCIE1
4989        .long L$set$12  /* Length of Common Information Entry */
4990LSCIE1:
4991        .long   0x0     /* CIE Identifier Tag */
4992        .byte   0x1     /* CIE Version */
4993        .ascii "zPLR\0" /* CIE Augmentation */
4994        .byte   0x1     /* uleb128 0x1; CIE Code Alignment Factor */
4995        .byte   0x78    /* sleb128 -8; CIE Data Alignment Factor */
4996        .byte   0x10    /* CIE RA Column */
4997        .byte   0xb     /* uleb128 0xb; Augmentation size */
4998        .byte   0x8c    /* Personality (indirect  sdata8) */
4999        .quad   lisp_global(objc_2_personality)
5000        .byte   0x10    /* LSDA Encoding (pcrel) */
5001        .byte   0x10    /* FDE Encoding (pcrel) */
5002        .byte   0xc     /* DW_CFA_def_cfa */
5003        .byte   0x7     /* uleb128 0x7 */
5004        .byte   0x8     /* uleb128 0x8 */
5005        .byte   0x90    /* DW_CFA_offset, column 0x10 */
5006        .byte   0x1     /* uleb128 0x1 */
5007        .align 3
5008LECIE1:
5009        .globl _SPffcall.eh
5010_SPffcall.eh:
5011        .long LEFDEffcall-LSFDEffcall
5012LSFDEffcall:     
5013        .long LSFDEffcall-EH_frame1 /* FDE CIE offset */
5014        .quad Lffcall-. /* FDE Initial Location */
5015        .quad Lffcall_end-Lffcall /* FDE address range */
5016        .byte 8 /* uleb128 0x8; Augmentation size */
5017        .quad LLSDA1-.           /* Language Specific Data Area */
5018        .byte   0x4     /* DW_CFA_advance_loc4 */
5019        .long Lffcall_setup-Lffcall
5020        .byte   0xe     /* DW_CFA_def_cfa_offset */
5021        .byte   0x10    /* uleb128 0x10 */
5022        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5023        .byte   0x2     /* uleb128 0x2 */
5024        .byte   0x4     /* DW_CFA_advance_loc4 */
5025        .long Lffcall_setup_end-Lffcall_setup
5026        .byte   0xd     /* DW_CFA_def_cfa_register */
5027        .byte   0x6     /* uleb128 0x6 */
5028        .byte   0x4     /* DW_CFA_advance_loc4 */
5029        .long Lffcall_call_end-Lffcall_call
5030        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5031        .byte   0x3     /* uleb128 0x3 */
5032        .align 3
5033LEFDEffcall:
5034        .globl _SPffcall_return_registers.eh
5035_SPffcall_return_registers.eh:
5036        .long LEFDEffcall_return_registers-LSFDEffcall_return_registers
5037LSFDEffcall_return_registers:     
5038        .long LSFDEffcall_return_registers-EH_frame1 /* FDE CIE offset */
5039        .quad Lffcall_return_registers-. /* FDE Initial Location */
5040        .quad Lffcall_return_registers_end-Lffcall_return_registers /* FDE address range */
5041        .byte 8 /* uleb128 0x8; Augmentation size */
5042        .quad LLSDA2-.           /* Language Specific Data Area */
5043        .byte   0x4     /* DW_CFA_advance_loc4 */
5044        .long Lffcall_return_registers_setup-Lffcall_return_registers
5045        .byte   0xe     /* DW_CFA_def_cfa_offset */
5046        .byte   0x10    /* uleb128 0x10 */
5047        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5048        .byte   0x2     /* uleb128 0x2 */
5049        .byte   0x4     /* DW_CFA_advance_loc4 */
5050        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup
5051        .byte   0xd     /* DW_CFA_def_cfa_register */
5052        .byte   0x6     /* uleb128 0x6 */
5053        .byte   0x4     /* DW_CFA_advance_loc4 */
5054        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call
5055        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5056        .byte   0x3     /* uleb128 0x3 */
5057        .align 3
5058LEFDEffcall_return_registers:
5059        .text
5060        .endif
5061        __endif
5062       
5063       
Note: See TracBrowser for help on using the repository browser.