source: branches/arm/lisp-kernel/x86-spentry64.s @ 13923

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

In the vinsns and subprims for special variable reference, try to
use CMOVs rather than branches.

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