source: trunk/source/lisp-kernel/x86-spentry64.s @ 14347

Last change on this file since 14347 was 13994, checked in by rme, 9 years ago

Clear tcr.ffi_exception in .SPffcall/.SPffcall_return_registers
before calling foreign code.

If foreign code generates an fp exception, we put the MXCSR into
tcr.ffi_exception. This value hangs around until another foreign fp
exception takes place, or something from lisp calls
%get-post-ffi-exception, which clears tcr.ffi_exception as a
side-effect.

This was causing lisp functions (e.g., LOG, COS, etc.) to signal
spurious floating-point errors: even though the call out to the C
library function (e.g., log) produced no exception, the lisp code that
looks for a post-ffi fp exception would sometimes see one anyway, left
over from some ff-call.

See ticket:707.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 165.2 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 $0,rcontext(tcr.ffi_exception))
3993        __(movq rcontext(tcr.foreign_sp),%rsp)
3994        __(emms)
3995        __(movq (%rsp),%rbp)
3996        __ifdef(`DARWIN_GS_HACK')
3997         /* At this point, %imm1=%rdx is live (contains
3998            the entrypoint) and %imm0.b=%al contains
3999            info about xmm register arguments; the lisp registers are
4000            all saved, and the foreign arguments are
4001            on the foreign stack (about to be popped
4002            off).  Save the linear TCR address in %save0/%r15
4003            so that we can restore it later, and preserve
4004            the entrypoint somewhere where C won't bash it.
4005            Note that dereferencing the entrypoint from
4006            foreign code has never been safe (unless it's
4007            a fixnum */
4008         __(save_tcr_linear(%csave0))
4009         __(movq %imm1,%csave1)
4010         __(movq %imm0,%csave2)
4011         __(set_foreign_gs_base())
4012         __(movq %csave1,%imm1)
4013         __(movq %csave2,%imm0)
4014        __endif
4015        __ifdef(`TCR_IN_GPR')
4016        /* Preserve TCR pointer */
4017        __(movq %rcontext_reg, %csave0)
4018        __endif
4019LocalLabelPrefix`'ffcall_setup:
4020        __(addq $2*node_size,%rsp)
4021        __(movq %imm1,%r11)
4022        __ifdef(`WINDOWS')
4023         /* Leave 0x20 bytes of register spill area on stack */
4024         __(movq (%rsp),%carg0)
4025         __(movq 8(%rsp),%carg1)
4026         __(movq 16(%rsp),%carg2)
4027         __(movq 24(%rsp),%carg3)
4028        __else
4029         __(pop %carg0)
4030         __(pop %carg1)
4031         __(pop %carg2)
4032         __(pop %carg3)
4033         __(pop %carg4)
4034         __(pop %carg5)
4035        __endif
4036LocalLabelPrefix`'ffcall_setup_end:
4037LocalLabelPrefix`'ffcall_call:
4038        __(call *%r11)
4039LocalLabelPrefix`'ffcall_call_end:               
4040        __ifdef(`WINDOWS')
4041        __(add $0x20,%rsp)
4042        __endif
4043        __(movq %rbp,%rsp)
4044        __ifdef(`DARWIN_GS_HACK')
4045         /* %rax/%rdx contains the return value (maybe), %csave1 still
4046            contains the linear tcr address.  Preserve %rax/%rdx here. */
4047         __(movq %rax,%csave1)
4048         __(movq %rdx,%csave2)
4049         __(set_gs_base(%csave0))
4050         __(movq %csave1,%rax)
4051         __(movq %csave2,%rdx)
4052        __endif
4053        __ifdef(`TCR_IN_GPR')
4054        __(movq %csave0, %rcontext_reg)
4055        __endif
4056        __(movq %rsp,rcontext(tcr.foreign_sp))
4057        __ifndef(`TCR_IN_GPR')
4058        __(clr %save3)
4059        __endif
4060        __(clr %save2)
4061        __(clr %save1)
4062        __(clr %save0)
4063        __(clr %arg_z)
4064        __(clr %arg_y)
4065        __(clr %arg_x)
4066        __(clr %temp2)
4067        __(clr %temp1)
4068        __(clr %temp0)
4069        __(clr %fn)
4070        __(pxor %fpzero,%fpzero)
4071
4072        /* If we got a floating-point exception during the ff-call,
4073           our handler will have set a flag, preserved lisp's MXCSR,
4074           and resumed execution with fp exceptions masked. */
4075        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
4076        __(jnc 1f)
4077        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
4078        __(je 0f)
4079        __(movl %arg_x_l,rcontext(tcr.ffi_exception))
4080        __(jmp 1f)
40810:      __(stmxcsr rcontext(tcr.ffi_exception))
4082        __(ldmxcsr rcontext(tcr.lisp_mxcsr)) /* preserved by the handler */
40831:      __(movq rcontext(tcr.save_vsp),%rsp)
4084        __(movq rcontext(tcr.save_rbp),%rbp)
4085        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4086        __(pop %save0)
4087        __(pop %save1)
4088        __(pop %save2)
4089        __ifndef(`TCR_IN_GPR')
4090        __(pop %save3)
4091        __endif
4092        __(pop %fn)
4093        __(pop %arg_z)
4094        __(pop %arg_y)
4095        __(pop %arg_x)
4096        __(pop %temp2)
4097        __(pop %temp1)
4098        __(check_pending_interrupt(%temp0))
4099        __(pop %temp0)
4100        __(leave)
4101        __ifdef(`DARWIN')
4102        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,rcontext(tcr.flags))
4103        __(jc 0f)
4104        __endif
4105        __(ret)
4106        __ifdef(`DARWIN')
41070:
4108        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4109        /* Box it, then signal a lisp error. */
4110        __(movq %imm0,%imm2)
4111        __(movq $macptr_header,%rax)
4112        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4113        __(movq %imm2,macptr.address(%arg_z))
4114        __(movq $XFOREIGNEXCEPTION,%arg_y)
4115        __(set_nargs(2))
4116        __(jmp _SPksignalerr)
4117        __endif
4118        __ifdef(`DARWIN')       
4119        /* Handle exceptions, for ObjC 2.0 */
4120LocalLabelPrefix`'ffcallLandingPad:     
4121        __(movq %rax,%save1)
4122        __(cmpq $1,%rdx)
4123        __(je 1f)
4124        __(movq %rax,%rdi)
4125LocalLabelPrefix`'ffcallUnwindResume:           
4126        __(call *lisp_global(unwind_resume))
4127LocalLabelPrefix`'ffcallUnwindResume_end:         
41281:      __(movq %save1,%rdi)
4129LocalLabelPrefix`'ffcallBeginCatch:             
4130        __(call *lisp_global(objc2_begin_catch))
4131LocalLabelPrefix`'ffcallBeginCatch_end:         
4132        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4133LocalLabelPrefix`'ffcallEndCatch:               
4134        __(call *lisp_global(objc2_end_catch))
4135LocalLabelPrefix`'ffcallEndCatch_end:           
4136        __(ref_global(get_tcr,%rax))
4137        __(movq $1,%rdi)
4138        __(call *%rax)
4139        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4140        __(movq %save1,%rax)
4141        __(jmp LocalLabelPrefix`'ffcall_call_end)
4142LocalLabelPrefix`'ffcall_end:   
4143        __endif
4144_endsubp(ffcall)
4145
4146        __ifdef(`DARWIN')
4147        .section __DATA,__gcc_except_tab
4148GCC_except_table0:
4149        .align 3
4150LLSDA1:
4151        .byte   0xff    /* @LPStart format (omit) */
4152        .byte   0x0     /* @TType format (absolute) */
4153        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4154        .byte   0x3     /* call-site format (udata4) */
4155        .byte   0x41    /* uleb128 0x41; Call-site table length */
4156       
4157        .long Lffcall_setup-Lffcall     /* region 0 start */
4158        .long Lffcall_setup_end-Lffcall_setup   /* length */
4159        .long   0x0     /* landing pad */
4160        .byte   0x0     /* uleb128 0x0; action */
4161       
4162        .long Lffcall_call-Lffcall      /* region 1 start */
4163        .long Lffcall_call_end-Lffcall_call     /* length */
4164        .long LffcallLandingPad-Lffcall /* landing pad */
4165        .byte   0x1     /* uleb128 0x1; action */
4166       
4167        .long LffcallUnwindResume-Lffcall       /* region 2 start */
4168        .long LffcallUnwindResume_end-LffcallUnwindResume       /* length */
4169        .long   0x0     /* landing pad */
4170        .byte   0x0     /* uleb128 0x0; action */
4171       
4172        .long LffcallBeginCatch-Lffcall /* region 3 start */
4173        .long LffcallBeginCatch_end-LffcallBeginCatch   /* length */
4174        .long 0 /* landing pad */
4175        .byte   0x0     /* uleb128 0x0; action */
4176       
4177        .long LffcallEndCatch-Lffcall
4178        .long LffcallEndCatch_end-LffcallEndCatch       /* length */
4179        .long   0x0     /* landing pad */
4180        .byte   0x0     /* uleb128 0x0; action */
4181        .byte   0x1     /* Action record table */
4182        .byte   0x0
4183        .align 3
4184        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4185        .text
4186        __endif
4187
4188_spentry(ffcall_return_registers)
4189LocalLabelPrefix`'ffcall_return_registers:               
4190        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
4191          if not a fixnum, get the first word */
4192        __(unbox_fixnum(%arg_z,%imm1))
4193        __(testb $fixnummask,%arg_z_b)
4194        __(je 0f)
4195        __(movq macptr.address(%arg_z),%imm1)
41960:             
4197        /* Save lisp registers   */
4198        __(push %rbp)
4199        __(movq %rsp,%rbp)
4200        __(push %temp0)
4201        __(push %temp1)
4202        __(push %temp2)
4203        __(push %arg_x)
4204        __(push %arg_y)
4205        __(push %arg_z)
4206        __ifndef(`TCR_IN_GPR')
4207        __(push %save3)
4208        __endif
4209        __(push %save2)
4210        __(push %save1)
4211        __(push %save0)
4212        __(movq macptr.address(%arg_y),%csave0)  /* %rbx non-volatile */
4213        __(push %fn)
4214        __(movq %rsp,rcontext(tcr.save_vsp))
4215        __(movq %rbp,rcontext(tcr.save_rbp))
4216        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4217        __(movq $0,rcontext(tcr.ffi_exception))
4218        __(movq rcontext(tcr.foreign_sp),%rsp)
4219        __(emms)
4220        __(movq (%rsp),%rbp)
4221        __ifdef(`DARWIN_GS_HACK')
4222         /* At this point, %imm1=%rdx is live (contains
4223            the entrypoint) and %imm0.b=%al contains
4224            xmm argument info; the lisp registers are
4225            all saved, and the foreign arguments are
4226            on the foreign stack (about to be popped
4227            off).  Save the linear TCR address in %csave1/%r12
4228            so that we can restore it later, and preserve
4229            the entrypoint somewhere where C won't bash it.
4230            Note that dereferencing the entrypoint from
4231            foreign code has never been safe (unless it's
4232            a fixnum */
4233         __(save_tcr_linear(%csave1))
4234         __(movq %imm0,%csave2)
4235         __(movq %imm1,%csave3)
4236         __(set_foreign_gs_base())
4237         __(movq %csave2,%imm0)
4238         __(movq %csave3,%imm1)
4239        __endif
4240        __ifdef(`TCR_IN_GPR')
4241        /* Preserve TCR pointer */
4242        __(movq %rcontext_reg, %csave1)
4243        __endif
4244        __(movq %imm1,%r11)
4245LocalLabelPrefix`'ffcall_return_registers_setup:
4246        __(addq $2*node_size,%rsp)
4247        __(pop %carg0)
4248        __(pop %carg1)
4249        __(pop %carg2)
4250        __(pop %carg3)
4251        __ifdef(`WINDOWS')
4252        __(sub $0x20, %rsp) /* Make room for arg register spill */
4253        __else
4254        __(pop %carg4)
4255        __(pop %carg5)
4256        __endif
4257LocalLabelPrefix`'ffcall_return_registers_setup_end: 
4258LocalLabelPrefix`'ffcall_return_registers_call:
4259        __(call *%r11)
4260LocalLabelPrefix`'ffcall_return_registers_call_end:
4261        __ifdef(`WINDOWS')
4262        __(add $0x20, %rsp)
4263        __endif
4264        __(movq %rax,(%csave0))
4265        __(movq %rdx,8(%csave0))
4266        __(movsd %xmm0,16(%csave0))
4267        __(movsd %xmm1,24(%csave0))
4268        __(movq %rbp,%rsp)
4269        __ifdef(`DARWIN_GS_HACK')
4270         /* %rax/%rdx contains the return value (maybe), %save0 still
4271            contains the linear tcr address.  Preserve %rax/%rdx here. */
4272         __(set_gs_base(%csave1))
4273         __(movq (%csave0),%rax)
4274         __(movq 8(%csave0),%rdx)
4275         __(movsd 16(%csave0),%xmm0)
4276         __(movsd 24(%csave0),%xmm1)
4277        __endif
4278        __ifdef(`TCR_IN_GPR')
4279        __(movq %csave1, %rcontext_reg)
4280        __endif
4281        __(movq %rsp,rcontext(tcr.foreign_sp))       
4282        __ifndef(`TCR_IN_GPR')
4283        __(clr %save3)
4284        __endif
4285        __(clr %save2)
4286        __(clr %save1)
4287        __(clr %save0)
4288        __(clr %arg_z)
4289        __(clr %arg_y)
4290        __(clr %arg_x)
4291        __(clr %temp2)
4292        __(clr %temp1)
4293        __(clr %temp0)
4294        __(clr %fn)
4295        __(pxor %fpzero,%fpzero)
4296        /* Check for fp exceptions as in .SPffcall, above. */
4297        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
4298        __(jnc 1f)
4299        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
4300        __(je 0f)
4301        __(movl %arg_x_l,rcontext(tcr.ffi_exception))
4302        __(jmp 1f)
43030:      __(stmxcsr rcontext(tcr.ffi_exception))
4304        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
43051:      __(movq rcontext(tcr.save_vsp),%rsp)
4306        __(movq rcontext(tcr.save_rbp),%rbp)
4307        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4308        __(pop %fn)
4309        __(pop %save0)
4310        __(pop %save1)
4311        __(pop %save2)
4312        __ifndef(`TCR_IN_GPR')
4313        __(pop %save3)
4314        __endif
4315        __(pop %arg_z)
4316        __(pop %arg_y)
4317        __(pop %arg_x)
4318        __(pop %temp2)
4319        __(pop %temp1)
4320        __(check_pending_interrupt(%temp0))
4321        __(pop %temp0)
4322        __(leave)
4323        __ifdef(`DARWIN')
4324        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,rcontext(tcr.flags))
4325        __(jc 0f)
4326        __endif
4327        __(ret)
4328        __ifdef(`DARWIN')
43290:
4330        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4331        /* Box it, then signal a lisp error. */
4332        __(movq %imm0,%imm2)
4333        __(movq $macptr_header,%rax)
4334        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4335        __(movq %imm2,macptr.address(%arg_z))
4336        __(movq $XFOREIGNEXCEPTION,%arg_y)
4337        __(set_nargs(2))
4338        __(jmp _SPksignalerr)
4339        __endif
4340        __ifdef(`DARWIN')       
4341        /* Handle exceptions, for ObjC 2.0 */
4342LocalLabelPrefix`'ffcall_return_registersLandingPad:     
4343        __(movq %rax,%save1)
4344        __(cmpq $1,%rdx)
4345        __(je 1f)
4346        __(movq %rax,%rdi)
4347LocalLabelPrefix`'ffcall_return_registersUnwindResume:           
4348        __(call *lisp_global(unwind_resume))
4349LocalLabelPrefix`'ffcall_return_registersUnwindResume_end:         
43501:      __(movq %save1,%rdi)
4351LocalLabelPrefix`'ffcall_return_registersBeginCatch:             
4352        __(call *lisp_global(objc2_begin_catch))
4353LocalLabelPrefix`'ffcall_return_registersBeginCatch_end:         
4354        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4355LocalLabelPrefix`'ffcall_return_registersEndCatch:               
4356        __(call *lisp_global(objc2_end_catch))
4357LocalLabelPrefix`'ffcall_return_registersEndCatch_end:           
4358        __(ref_global(get_tcr,%rax))
4359        __(movq $1,%rdi)
4360        __(call *%rax)
4361        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4362        __(movq %save1,%rax)
4363        __(jmp LocalLabelPrefix`'ffcall_return_registers_call_end)
4364LocalLabelPrefix`'ffcall_return_registers_end:   
4365        __endif
4366_endsubp(ffcall_returning_registers)
4367
4368        __ifdef(`DARWIN')
4369        .section __DATA,__gcc_except_tab
4370GCC_except_table1:
4371        .align 3
4372LLSDA2:
4373        .byte   0xff    /* @LPStart format (omit) */
4374        .byte   0x0     /* @TType format (absolute) */
4375        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4376        .byte   0x3     /* call-site format (udata4) */
4377        .byte   0x41    /* uleb128 0x41; Call-site table length */
4378       
4379        .long Lffcall_return_registers_setup-Lffcall_return_registers   /* region 0 start */
4380        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup /* length */
4381        .long   0x0     /* landing pad */
4382        .byte   0x0     /* uleb128 0x0; action */
4383       
4384        .long Lffcall_return_registers_call-Lffcall_return_registers    /* region 1 start */
4385        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call   /* length */
4386        .long Lffcall_return_registersLandingPad-Lffcall_return_registers       /* landing pad */
4387        .byte   0x1     /* uleb128 0x1; action */
4388       
4389        .long Lffcall_return_registersUnwindResume-Lffcall_return_registers     /* region 2 start */
4390        .long Lffcall_return_registersUnwindResume_end-Lffcall_return_registersUnwindResume     /* length */
4391        .long   0x0     /* landing pad */
4392        .byte   0x0     /* uleb128 0x0; action */
4393       
4394        .long Lffcall_return_registersBeginCatch-Lffcall_return_registers       /* region 3 start */
4395        .long Lffcall_return_registersBeginCatch_end-Lffcall_return_registersBeginCatch /* length */
4396        .long 0 /* landing pad */
4397        .byte   0x0     /* uleb128 0x0; action */
4398       
4399        .long Lffcall_return_registersEndCatch-Lffcall_return_registers
4400        .long Lffcall_return_registersEndCatch_end-Lffcall_return_registersEndCatch     /* length */
4401        .long   0x0     /* landing pad */
4402        .byte   0x0     /* uleb128 0x0; action */
4403        .byte   0x1     /* Action record table */
4404        .byte   0x0
4405        .align 3
4406        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4407        .text
4408        __endif
4409               
4410_spentry(syscall)
4411        /* Save lisp registers   */
4412        __(push %rbp)
4413        __(movq %rsp,%rbp)
4414        __(push %temp0)
4415        __(push %temp1)
4416        __(push %temp2)
4417        __(push %arg_x)
4418        __(push %arg_y)
4419        __(push %arg_z)
4420        __ifndef(`TCR_IN_GPR')
4421         __(push %save3)
4422        __endif
4423        __(push %save2)
4424        __(push %save1)
4425        __(push %save0)
4426        __(push %fn)
4427        __(movq %rsp,rcontext(tcr.save_vsp))
4428        __(movq %rbp,rcontext(tcr.save_rbp))
4429        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4430        __(movq rcontext(tcr.foreign_sp),%rsp)
4431        __(emms)
4432        __(movq (%rsp),%rbp)
4433        __(addq $2*node_size,%rsp)
4434        __ifdef(`TCR_IN_GPR')
4435         __(movq %rcontext_reg,%csave0)
4436        __endif
4437        __ifdef(`WINDOWS')
4438         __(pop %carg0)
4439         __(pop %carg1)
4440         __(pop %carg2)
4441         __(pop %carg3)
4442         __(subq $0x20,%rsp)
4443         __(orq $-1,%cret)
4444         __(addq $0x20,%rsp)
4445        __else
4446         __(unbox_fixnum(%arg_z,%rax))
4447         __(pop %rdi)
4448         __(pop %rsi)
4449         __(pop %rdx)
4450         __(pop %r10)           /*  syscalls take 4th param in %r10, not %rcx   */
4451         __(pop %r8)
4452         __(pop %r9)
4453         __(syscall)
4454         __ifdef(`SYSCALL_SETS_CARRY_ON_ERROR')
4455          __(jnc 0f)
4456          __(negq %rax)
44570:     
4458         __endif
4459        __endif
4460        __ifdef(`TCR_IN_GPR')
4461         __(movq %csave0,%rcontext_reg)
4462        __endif
4463        __(movq %rbp,%rsp)
4464        __(movq %rsp,rcontext(tcr.foreign_sp))
4465        __ifndef(`TCR_IN_GPR')
4466         __(clr %save3)
4467        __endif
4468        __(clr %save2)
4469        __(clr %save1)
4470        __(clr %save0)
4471        __(clr %arg_z)
4472        __(clr %arg_y)
4473        __(clr %arg_x)
4474        __(clr %temp2)
4475        __(clr %temp1)
4476        __(clr %temp0)
4477        __(clr %fn)
4478        __(pxor %fpzero,%fpzero)
4479        __(movq rcontext(tcr.save_vsp),%rsp)
4480        __(movq rcontext(tcr.save_rbp),%rbp)
4481        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4482        __(pop %fn)
4483        __(pop %save0)
4484        __(pop %save1)
4485        __(pop %save2)
4486        __ifndef(`TCR_IN_GPR')
4487         __(pop %save3)
4488        __endif
4489        __(pop %arg_z)
4490        __(pop %arg_y)
4491        __(pop %arg_x)
4492        __(pop %temp2)
4493        __(pop %temp1)
4494        __(check_pending_interrupt(%temp0))
4495        __(pop %temp0)
4496        __(leave)
4497        __(ret)
4498_endsubp(syscall)               
4499
4500/* We need to reserve a frame here if (a) nothing else was already pushed and (b) */
4501/*   we push something (e.g., more than 3 args in the lexpr)      */
4502_spentry(spread_lexprz)
4503        new_local_labels()
4504        __(movq (%arg_z),%imm0)
4505        __(testl %nargs,%nargs) /* anything pushed by caller ? */
4506        __(leaq node_size(%arg_z,%imm0),%imm1)
4507        __(jne 0f)              /* yes, caller has already created frame. */
4508        __(cmpw $(nargregs*node_size),%imm0_w) /* will we push anything ? */
4509        __(jbe 0f)
4510        __(push $reserved_frame_marker)
4511        __(push $reserved_frame_marker)
45120:      __(addw %imm0_w,%nargs_w)
4513        __(cmpw $(nargregs*node_size),%imm0_w)
4514        __(jae 9f)
4515        __(cmpw $(2*node_size),%imm0_w)
4516        __(je 2f)
4517        __(testw %imm0_w,%imm0_w)
4518        __(jne 1f)
4519        /* lexpr count was 0; vpop the args that */
4520        /* were pushed by the caller */
4521        __(testl %nargs,%nargs)
4522        __(je local_label(all_args_popped))
4523        __(pop %arg_z)
4524local_label(maybe_pop_yx):             
4525        __(cmpl $(1*node_size),%nargs)
4526        __(je local_label(all_args_popped))
4527        __(pop %arg_y)
4528        __(cmpl $(2*node_size),%nargs)
4529        __(je local_label(all_args_popped))
4530local_label(pop_arg_x):         
4531        __(pop %arg_x)
4532local_label(all_args_popped):   
4533        /* If all args fit in registers but some were pushed */
4534        /* by the caller, discard the reserved frame that the caller */
4535        /* pushed.         */
4536        __(cmpw %imm0_w,%nargs_w)
4537        __(je local_label(go))
4538        __(cmpl $(nargregs*node_size),%nargs)
4539        __(ja local_label(go))
4540        __(addq $(2*node_size),%rsp)
4541local_label(go):       
4542        __(jmp *%ra0)       
4543        /* vpush args from the lexpr until we have only */
4544        /* three left, then assign them to arg_x, arg_y, */
4545        /* and arg_z. */
45468:      __(cmpw $(4*node_size),%imm0_w)
4547        __(lea -1*node_size(%imm0),%imm0)
4548        __(push -node_size(%imm1))
4549        __(lea -1*node_size(%imm1),%imm1)
45509:      __(jne 8b)
4551        __(movq -node_size*1(%imm1),%arg_x)
4552        __(movq -node_size*2(%imm1),%arg_y)
4553        __(movq -node_size*3(%imm1),%arg_z)
4554        __(jmp *%ra0)
4555
4556        /* lexpr count is two: set arg_y, arg_z from the */
4557        /* lexpr, maybe vpop arg_x */
45582:      __(cmpl $(2*node_size),%nargs)
4559        __(movq -node_size*1(%imm1),%arg_y)
4560        __(movq -node_size*2(%imm1),%arg_z)
4561        __(jne local_label(pop_arg_x))
4562        __(jmp *%ra0)
4563        /* lexpr count is one: set arg_z from the lexpr, */
4564        /* maybe vpop arg_y, arg_x  */
45651:      __(movq -node_size*1(%imm1),%arg_z)
4566        __(jmp local_label(maybe_pop_yx))
4567_endsubp(spread_lexprz)
4568       
4569
4570
4571
4572/* Callback index in %r11 */
4573_spentry(callback)
4574        __(push %rbp)
4575        __(movq %rsp,%rbp)
4576        /* C scalar args   */
4577        __(push %carg0) /* -8(%rbp)   */
4578        __(push %carg1)
4579        __(push %carg2)
4580        __(push %carg3)
4581        __ifndef(`WINDOWS')
4582        __(push %carg4)
4583        __(push %carg5)
4584        __endif
4585        /* FP arg regs   */
4586        __ifdef(`WINDOWS')
4587        __(subq $4*8,%rsp)
4588        __(movq %xmm0,3*8(%rsp))        /* -40(%rbp) */
4589        __(movq %xmm1,2*8(%rsp))
4590        __(movq %xmm2,1*8(%rsp))
4591        __(movq %xmm3,0*8(%rsp))
4592        __else
4593        __(subq $8*8,%rsp)
4594        __(movq %xmm0,7*8(%rsp))        /* -56(%rbp) */
4595        __(movq %xmm1,6*8(%rsp))
4596        __(movq %xmm2,5*8(%rsp))
4597        __(movq %xmm3,4*8(%rsp))
4598        __(movq %xmm4,3*8(%rsp))
4599        __(movq %xmm5,2*8(%rsp))
4600        __(movq %xmm6,1*8(%rsp))
4601        __(movq %xmm7,0*8(%rsp))
4602        __endif
4603        __ifndef(`WINDOWS')
4604        __endif
4605        /* C NVRs   */
4606        __(push %csave0)
4607        __(push %csave1)
4608        __(push %csave2)
4609        __(push %csave3)
4610        __(push %csave4)
4611        __ifdef(`WINDOWS')
4612        __(push %csave5)
4613        __(push %csave6)
4614        __endif
4615        __(push %rbp)
4616        __(movq %r11,%csave0)
4617        __ifdef(`HAVE_TLS')
4618         /* TCR initialized for lisp ?   */
4619         __ifndef(`TCR_IN_GPR') /* FIXME */
4620         __(movq %fs:current_tcr@TPOFF+tcr.linear,%rax)
4621         __(testq %rax,%rax)
4622         __(jne 1f)
4623         __endif
4624        __endif
4625        __(ref_global(get_tcr,%rax))
4626        __(movq $1,%carg0)
4627        __ifdef(`WINDOWS')
4628        __(sub $0x20, %rsp)
4629        __endif
4630        __(call *%rax)
4631        __ifdef(`WINDOWS')
4632        __(add $0x20, %rsp)
4633        __endif
4634        __ifdef(`TCR_IN_GPR')
4635        __(movq %rax, %rcontext_reg)
4636        __endif
4637        __ifdef(`DARWIN_GS_HACK')
4638         /* linear TCR address in now in %rax; callback index was
4639            saved in %r12 a moment ago. */
4640         __(set_gs_base(%rax))
4641        __endif
46421:      /* Align foreign stack for lisp   */
4643        __(pushq rcontext(tcr.save_rbp)) /* mark cstack frame's "owner" */
4644        __(pushq rcontext(tcr.foreign_sp))
4645        /* init lisp registers   */
4646        __(movq %csave0,%rax)
4647        __(movq %rsp,rcontext(tcr.foreign_sp))
4648        __ifndef(`TCR_IN_GPR')
4649        __(clr %save3)
4650        __endif
4651        __(clr %save2)
4652        __(clr %save1)
4653        __(clr %save0)
4654        __(clr %arg_z)
4655        __(clr %arg_y)
4656        __(clr %arg_x)
4657        __(clr %temp2)
4658        __(clr %temp1)
4659        __(clr %temp0)
4660        __(clr %fn)
4661        __(pxor %fpzero,%fpzero)
4662        __(movq rcontext(tcr.save_vsp),%rsp)
4663        __(box_fixnum(%rax,%arg_y))
4664        __(movq %rbp,%arg_z)
4665        __(movq rcontext(tcr.save_rbp),%rbp)
4666        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4667        __(movq (%rsp),%save0)
4668        __(movq 8(%rsp),%save1)
4669        __(movq 16(%rsp),%save2)
4670        __ifndef(`TCR_IN_GPR')
4671         __(movq 24(%rsp),%save3)
4672        __endif
4673        __(stmxcsr rcontext(tcr.foreign_mxcsr))
4674        __(andb $~mxcsr_all_exceptions,rcontext(tcr.foreign_mxcsr))
4675        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4676        __(movq $nrs.callbacks,%fname)
4677        __(lea local_label(back_from_callback)(%rip),%ra0)
4678        __(set_nargs(2))
4679        __(push %ra0)
4680        __(jump_fname())
4681__(tra(local_label(back_from_callback)))
4682        __(movq %rsp,rcontext(tcr.save_vsp))
4683        __(movq %rbp,rcontext(tcr.save_rbp))
4684        __(movq rcontext(tcr.foreign_sp),%rsp)
4685        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4686        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4687        __(emms)
4688        __(pop rcontext(tcr.foreign_sp))
4689        __(addq $node_size,%rsp)
4690        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4691        __ifdef(`DARWIN_GS_HACK')
4692         /* Lucky us; nothing is live here */
4693         __(set_foreign_gs_base())
4694        __endif
4695        __(pop %rbp)
4696        __ifdef(`WINDOWS')
4697        __(pop %csave6)
4698        __(pop %csave5)
4699        __endif
4700        __(pop %csave4)
4701        __(pop %csave3)
4702        __(pop %csave2)
4703        __(pop %csave1)
4704        __(pop %csave0)
4705        __(movq -8(%rbp),%rax)
4706        __(movq -16(%rbp),%rdx)
4707        __(movq -24(%rbp),%xmm0)
4708        __(movq -32(%rbp),%xmm1)
4709        __(leave)
4710        __(ret)         
4711_endsubp(callback)
4712
4713/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
4714   We don't know whether the array is alleged to be simple or
4715   not, and don't know anythng about the element type.  */
4716               
4717_spentry(aref2)
4718        __(testb $fixnummask,%arg_y_b)
4719        __(jne 0f)
4720       
4721        __(testb $fixnummask,%arg_z_b)
4722        __(jne 1f)
4723        __(extract_typecode(%arg_x,%imm0))
4724        __(cmpb $subtag_arrayH,%imm0_b)
4725        __(jne 2f)
4726        __(cmpq $2<<fixnumshift,arrayH.rank(%arg_x))
4727        __(jne 2f)
4728        __(cmpq arrayH.dim0(%arg_x),%arg_y)
4729        __(jae 3f)
4730        __(movq arrayH.dim0+node_size(%arg_x),%imm0)
4731        __(cmpq %imm0,%arg_z)
4732        __(jae 4f)
4733        __(unbox_fixnum(%imm0,%imm0))
4734        __(mulq %arg_y)         /* imm0 <- imm0 * arg_y */
4735        __(addq %imm0,%arg_z)
4736        __(movq %arg_x,%arg_y)
47376:      __(addq arrayH.displacement(%arg_y),%arg_z)
4738        __(movq arrayH.data_vector(%arg_y),%arg_y)
4739        __(extract_subtag(%arg_y,%imm1_b))
4740        __(cmpb $subtag_vectorH,%imm1_b)
4741        __(ja C(misc_ref_common))
4742        __(jmp 6b)
47430:      __(uuo_error_reg_not_fixnum(Rarg_y))
47441:      __(uuo_error_reg_not_fixnum(Rarg_z))
47452:      __(uuo_error_reg_not_type(Rarg_x,error_object_not_array_2d))
47463:      __(uuo_error_array_bounds(Rarg_y,Rarg_x))
47474:      __(uuo_error_array_bounds(Rarg_z,Rarg_x))
4748       
4749_endsubp(aref2)
4750
4751/* %temp0 = array, %arg_x = i,%arg_y = j, %arg_z = k */
4752_spentry(aref3)
4753        __(testb $fixnummask,%arg_x_b)
4754        __(jne 0f)
4755        __(testb $fixnummask,%arg_y_b)
4756        __(jne 1f)
4757        __(testb $fixnummask,%arg_z_b)
4758        __(jne 2f)
4759        __(extract_typecode(%temp0,%imm0))
4760        __(cmpb $subtag_arrayH,%imm0_b)
4761        __(jne 3f)
4762        __(cmpq $3<<fixnumshift,arrayH.rank(%temp0))
4763        __(jne 3f)
4764        __(cmpq arrayH.dim0(%temp0),%arg_x)
4765        __(jae 5f)
4766        __(movq arrayH.dim0+node_size(%temp0),%imm0)
4767        __(cmpq %imm0,%arg_y)
4768        __(jae 6f)
4769        __(unbox_fixnum(%imm0,%imm0))
4770        __(movq arrayH.dim0+(node_size*2)(%temp0),%imm1)
4771        __(cmpq %imm1,%arg_z)
4772        __(jae 7f)
4773        __(unbox_fixnum(%imm1,%imm1))
4774        __(imulq %imm1,%arg_y)
4775        __(mulq %imm1)
4776        __(imulq %imm0,%arg_x)
4777        __(addq %arg_x,%arg_z)
4778        __(addq %arg_y,%arg_z)
4779        __(movq %temp0,%arg_y)
47808:      __(addq arrayH.displacement(%arg_y),%arg_z)
4781        __(movq arrayH.data_vector(%arg_y),%arg_y)
4782        __(extract_subtag(%arg_y,%imm1_b))
4783        __(cmpb $subtag_vectorH,%imm1_b)
4784        __(ja C(misc_ref_common))
4785        __(jmp 8b)
47860:      __(uuo_error_reg_not_fixnum(Rarg_x))
47871:      __(uuo_error_reg_not_fixnum(Rarg_y))   
47882:      __(uuo_error_reg_not_fixnum(Rarg_z))
47893:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_3d))
47905:      __(uuo_error_array_bounds(Rarg_x,Rtemp0))
47916:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
47927:      __(uuo_error_array_bounds(Rarg_z,Rtemp0))
4793       
4794_endsubp(aref3)
4795       
4796/* As with aref2, but temp0 = array, arg_x = i, arg_y = j, arg_z = new_value */
4797_spentry(aset2)
4798        __(testb $fixnummask,%arg_x_b)
4799        __(jne 0f)
4800        __(testb $fixnummask,%arg_y_b)
4801        __(jne 1f)
4802        __(extract_typecode(%temp0,%imm0))
4803        __(cmpb $subtag_arrayH,%imm0_b)
4804        __(jne 2f)
4805        __(cmpq $2<<fixnumshift,arrayH.rank(%temp0))
4806        __(jne 2f)
4807        __(cmpq arrayH.dim0(%temp0),%arg_x)
4808        __(jae 4f)
4809        __(movq arrayH.dim0+node_size(%temp0),%imm0)
4810        __(cmpq %imm0,%arg_y)
4811        __(jae 5f)
4812        __(unbox_fixnum(%imm0,%imm0))
4813        __(mulq %arg_x)         /* imm0 <- imm0 * arg_x */
4814        __(addq %imm0,%arg_y)
4815        __(movq %temp0,%arg_x)
48166:      __(addq arrayH.displacement(%arg_x),%arg_y)
4817        __(movq arrayH.data_vector(%arg_x),%arg_x)
4818        __(extract_subtag(%arg_x,%imm1_b))
4819        __(cmpb $subtag_vectorH,%imm1_b)
4820        __(ja C(misc_set_common))
4821        __(jmp 6b)
48220:      __(uuo_error_reg_not_fixnum(Rarg_x))
48231:      __(uuo_error_reg_not_fixnum(Rarg_y))
48242:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
48254:      __(uuo_error_array_bounds(Rarg_x,Rtemp0))
48265:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
4827_endsubp(aset2)
4828
4829/* %temp1 = array, %temp0 = i, %arg_x = j, %arg_y = k, %arg_y = newval. */
4830
4831_spentry(aset3)
4832        __(testb $fixnummask,%temp0_b)
4833        __(jne 0f)
4834        __(testb $fixnummask,%arg_x_b)
4835        __(jne 1f)
4836        __(testb $fixnummask,%arg_y_b)
4837        __(jne 2f)
4838        __(extract_typecode(%temp1,%imm0))
4839        __(cmpb $subtag_arrayH,%imm0_b)
4840        __(jne 3f)
4841        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4842        __(jne 3f)
4843        __(cmpq arrayH.dim0(%temp1),%temp0)
4844        __(jae 5f)
4845        __(movq arrayH.dim0+node_size(%temp1),%imm0)
4846        __(cmpq %imm0,%arg_x)
4847        __(jae 6f)
4848        __(unbox_fixnum(%imm0,%imm0))
4849        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4850        __(cmpq %imm1,%arg_y)
4851        __(jae 7f)
4852        __(unbox_fixnum(%imm1,%imm1))
4853        __(imulq %imm1,%arg_x)
4854        __(mulq %imm1)
4855        __(imulq %imm0,%temp0)
4856        __(addq %temp0,%arg_y)
4857        __(addq %arg_x,%arg_y)
4858        __(movq %temp1,%arg_x)
48598:      __(addq arrayH.displacement(%arg_x),%arg_y)
4860        __(movq arrayH.data_vector(%arg_x),%arg_x)
4861        __(extract_subtag(%arg_x,%imm1_b))
4862        __(cmpb $subtag_vectorH,%imm1_b)
4863        __(ja C(misc_set_common))
4864        __(jmp 8b)
4865       
48660:      __(uuo_error_reg_not_fixnum(Rtemp0))
48671:      __(uuo_error_reg_not_fixnum(Rarg_x))
48682:      __(uuo_error_reg_not_fixnum(Rarg_y))
48693:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
48705:      __(uuo_error_array_bounds(Rtemp0,Rtemp1))
48716:      __(uuo_error_array_bounds(Rarg_x,Rtemp1))
48726:      __(uuo_error_array_bounds(Rarg_x,Rtemp1))
48737:      __(uuo_error_array_bounds(Rarg_y,Rtemp1))
4874       
4875_endsubp(aset3)
4876
4877       
4878
4879
4880/* Prepend all but the first five (4 words of code, inner fn) and last   */
4881/* (lfbits) elements of %fn to the "arglist".   */
4882       
4883_spentry(call_closure)
4884        new_local_labels()
4885        __(subq $fulltag_function-fulltag_misc,%fn)
4886        __(vector_length(%fn,%imm0))
4887       
4888        __(subq $6<<fixnumshift,%imm0)  /* imm0 = inherited arg count   */
4889        __(lea (%nargs_q,%imm0),%imm1)
4890        __(cmpl $nargregs<<fixnumshift,%imm1_l)
4891        __(jna local_label(regs_only))
4892        __(pop %ra0)
4893        __(cmpl $nargregs<<fixnumshift,%nargs)
4894        __(jna local_label(no_insert))
4895       
4896/* Some arguments have already been pushed.  Push imm0's worth   */
4897/* of NILs, copy those arguments that have already been vpushed from   */
4898/* the old TOS to the new, then insert all of the inerited args   */
4899/* and go to the function.  */
4900       
4901        __(movq %imm0,%imm1)
4902local_label(push_nil_loop):     
4903        __(push $nil_value)
4904        __(sub $fixnumone,%imm1)
4905        __(jne local_label(push_nil_loop))
4906       
4907/* Need to use arg regs as temporaries here.    */
4908        __(movq %rsp,%temp1)
4909        __(push %arg_z)
4910        __(push %arg_y)
4911        __(push %arg_x)
4912        __(lea 3*node_size(%rsp,%imm0),%arg_x)
4913        __(lea -nargregs<<fixnumshift(%nargs_q),%arg_y)
4914local_label(copy_already_loop):
4915        __(movq (%arg_x),%arg_z)
4916        __(addq $fixnumone,%arg_x)
4917        __(movq %arg_z,(%temp1))
4918        __(addq $fixnumone,%temp1)
4919        __(subq $fixnumone,%arg_y)
4920        __(jne local_label(copy_already_loop))
4921       
4922        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4923local_label(insert_loop):               
4924        __(movq misc_data_offset(%fn,%imm1),%arg_z)
4925        __(addq $node_size,%imm1)
4926        __(addl $fixnum_one,%nargs)
4927        __(subq $node_size,%arg_x)
4928        __(movq %arg_z,(%arg_x))
4929        __(subq $fixnum_one,%imm0)
4930        __(jne local_label(insert_loop))
4931
4932        /* Recover the argument registers, pushed earlier   */
4933        __(pop %arg_x)
4934        __(pop %arg_y)
4935        __(pop %arg_z)
4936        __(jmp local_label(go))
4937
4938/* Here if nothing was pushed by the caller.  If we're  */
4939/* going to push anything, we have to reserve a stack  */
4940/* frame first. (We'll need to push something if the  */
4941/* sum of %nargs and %imm0 is greater than nargregs)   */
4942       
4943local_label(no_insert):
4944        __(lea (%nargs_q,%imm0),%imm1)
4945        __(cmpq $nargregs<<fixnumshift,%imm1)
4946        __(jna local_label(no_insert_no_frame))
4947        /* Reserve space for a stack frame   */
4948        __(push $reserved_frame_marker)
4949        __(push $reserved_frame_marker)
4950local_label(no_insert_no_frame):       
4951        /* nargregs or fewer args were already vpushed.   */
4952        /* if exactly nargregs, vpush remaining inherited vars.   */
4953        __(cmpl $nargregs<<fixnumshift,%nargs)
4954        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4955        __(leaq 5<<fixnumshift(%imm0),%temp1)
4956        __(jnz local_label(set_regs))
4957local_label(vpush_remaining): 
4958        __(push misc_data_offset(%fn,%imm1))
4959        __(addq $node_size,%imm1)
4960        __(addl $fixnumone,%nargs)
4961        __(subq $node_size,%imm0)
4962        __(jnz local_label(vpush_remaining))
4963        __(jmp local_label(go))
4964local_label(set_regs):
4965        /* if nargs was > 1 (and we know that it was < 3), it must have   */
4966        /* been 2.  Set arg_x, then vpush the remaining args.   */
4967        __(cmpl $fixnumone,%nargs)
4968        __(jle local_label(set_y_z))
4969local_label(set_arg_x):
4970        __(subq $node_size,%temp1)
4971        __(movq misc_data_offset(%fn,%temp1),%arg_x)
4972        __(addl $fixnumone,%nargs)
4973        __(subq $fixnumone,%imm0)
4974        __(jne local_label(vpush_remaining))
4975        __(jmp local_label(go))
4976        /* Maybe set arg_y or arg_z, preceding args   */
4977local_label(set_y_z):
4978        __(jne local_label(set_arg_z))
4979        /* Set arg_y, maybe arg_x, preceding args   */
4980local_label(set_arg_y):
4981        __(subq $node_size,%temp1)
4982        __(movq misc_data_offset(%fn,%temp1),%arg_y)
4983        __(addl $fixnumone,%nargs)
4984        __(subq $fixnum_one,%imm0)
4985        __(jnz local_label(set_arg_x))
4986        __(jmp local_label(go))
4987local_label(set_arg_z):
4988        __(subq $node_size,%temp1)
4989        __(movq misc_data_offset(%fn,%temp1),%arg_z)
4990        __(addl $fixnumone,%nargs)
4991        __(subq $fixnum_one,%imm0)
4992        __(jne local_label(set_arg_y))
4993local_label(go):       
4994        __(movq misc_data_offset+(4*node_size)(%fn),%fn)
4995        __(push %ra0)
4996        __(jmp *%fn)
4997local_label(regs_only):
4998        __(leaq 5<<fixnumshift(%imm0),%temp1)
4999        __(testl %nargs,%nargs)
5000        __(jne local_label(some_args))
5001        __(cmpw $node_size,%imm0)
5002        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_z)
5003        __(je local_label(rgo))
5004        __(cmpw $2*node_size,%imm0)
5005        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_y)
5006        __(je local_label(rgo))
5007        __(movq misc_data_offset-(node_size*3)(%fn,%temp1),%arg_x)
5008local_label(rgo):
5009        __(addw %imm0_w,%nargs_w)
5010        __(jmp *misc_data_offset+(4*node_size)(%fn))
5011local_label(some_args):         
5012        __(cmpl $2*node_size,%nargs)
5013        __(jz local_label(rtwo))
5014        /* One arg was passed, could be one or two inherited args */
5015        __(cmpw $node_size,%imm0)
5016        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_y)
5017        __(je local_label(rgo))
5018        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_x)
5019        __(jmp local_label(rgo))
5020local_label(rtwo):     
5021        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_x)
5022        __(jmp local_label(rgo))
5023_endsubp(call_closure)
5024                                       
5025       
5026_spentry(poweropen_callbackX)
5027_endsubp(poweropen_callbackX)
5028       
5029       
5030_spentry(poweropen_ffcallX)
5031_endsubp(poweropen_ffcallX)
5032               
5033_spentry(poweropen_syscall)
5034_endsubp(poweropen_syscall)
5035
5036_spentry(eabi_ff_call)
5037_endsubp(eabi_ff_call)
5038
5039_spentry(eabi_callback)
5040_endsubp(eabi_callback)
5041
5042
5043/* Unused, and often not used on PPC either  */
5044_spentry(callbuiltin)
5045        __(hlt)
5046_endsubp(callbuiltin)
5047
5048_spentry(callbuiltin0)
5049        __(hlt)
5050_endsubp(callbuiltin0)
5051
5052_spentry(callbuiltin1)
5053        __(hlt)
5054_endsubp(callbuiltin1)
5055
5056_spentry(callbuiltin2)
5057        __(hlt)
5058_endsubp(callbuiltin2)
5059
5060_spentry(callbuiltin3)
5061        __(hlt)
5062_endsubp(callbuiltin3)
5063       
5064_spentry(restorefullcontext)
5065        __(hlt)
5066_endsubp(restorefullcontext)
5067
5068_spentry(savecontextvsp)
5069        __(hlt)
5070_endsubp(savecontextvsp)
5071
5072_spentry(savecontext0)
5073        __(hlt)
5074_endsubp(savecontext0)
5075
5076_spentry(restorecontext)
5077        __(hlt)
5078_endsubp(restorecontext)
5079
5080_spentry(stkconsyz)
5081        __(hlt)
5082_endsubp(stkconsyz)
5083
5084_spentry(stkvcell0)
5085        __(hlt)
5086_endsubp(stkvcell0)
5087
5088_spentry(stkvcellvsp)
5089        __(hlt)
5090_endsubp(stkvcellvsp)
5091
5092_spentry(breakpoint)
5093        __(hlt)
5094_endsubp(breakpoint)
5095
5096
5097        __ifdef(`DARWIN')
5098        .if 1
5099        .globl  C(lisp_objc_personality)
5100C(lisp_objc_personality):
5101        jmp *lisp_global(objc_2_personality)
5102       
5103        .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
5104EH_frame1:
5105        .set L$set$12,LECIE1-LSCIE1
5106        .long L$set$12  /* Length of Common Information Entry */
5107LSCIE1:
5108        .long   0x0     /* CIE Identifier Tag */
5109        .byte   0x1     /* CIE Version */
5110        .ascii "zPLR\0" /* CIE Augmentation */
5111        .byte   0x1     /* uleb128 0x1; CIE Code Alignment Factor */
5112        .byte   0x78    /* sleb128 -8; CIE Data Alignment Factor */
5113        .byte   0x10    /* CIE RA Column */
5114        .byte   0x7
5115        .byte   0x9b
5116        .long   _lisp_objc_personality+4@GOTPCREL
5117        .byte   0x10    /* LSDA Encoding (pcrel) */
5118        .byte   0x10    /* FDE Encoding (pcrel) */
5119        .byte   0xc     /* DW_CFA_def_cfa */
5120        .byte   0x7     /* uleb128 0x7 */
5121        .byte   0x8     /* uleb128 0x8 */
5122        .byte   0x90    /* DW_CFA_offset, column 0x10 */
5123        .byte   0x1     /* uleb128 0x1 */
5124        .align 3
5125LECIE1:
5126        .globl _SPffcall.eh
5127_SPffcall.eh:
5128        .long LEFDEffcall-LSFDEffcall
5129LSFDEffcall:     
5130        .long LSFDEffcall-EH_frame1 /* FDE CIE offset */
5131        .quad Lffcall-. /* FDE Initial Location */
5132        .quad Lffcall_end-Lffcall /* FDE address range */
5133        .byte 8 /* uleb128 0x8; Augmentation size */
5134        .quad LLSDA1-.           /* Language Specific Data Area */
5135        .byte   0x4     /* DW_CFA_advance_loc4 */
5136        .long Lffcall_setup-Lffcall
5137        .byte   0xe     /* DW_CFA_def_cfa_offset */
5138        .byte   0x10    /* uleb128 0x10 */
5139        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5140        .byte   0x2     /* uleb128 0x2 */
5141        .byte   0x4     /* DW_CFA_advance_loc4 */
5142        .long Lffcall_setup_end-Lffcall_setup
5143        .byte   0xd     /* DW_CFA_def_cfa_register */
5144        .byte   0x6     /* uleb128 0x6 */
5145        .byte   0x4     /* DW_CFA_advance_loc4 */
5146        .long Lffcall_call_end-Lffcall_call
5147        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5148        .byte   0x3     /* uleb128 0x3 */
5149        .align 3
5150LEFDEffcall:
5151        .globl _SPffcall_return_registers.eh
5152_SPffcall_return_registers.eh:
5153        .long LEFDEffcall_return_registers-LSFDEffcall_return_registers
5154LSFDEffcall_return_registers:     
5155        .long LSFDEffcall_return_registers-EH_frame1 /* FDE CIE offset */
5156        .quad Lffcall_return_registers-. /* FDE Initial Location */
5157        .quad Lffcall_return_registers_end-Lffcall_return_registers /* FDE address range */
5158        .byte 8 /* uleb128 0x8; Augmentation size */
5159        .quad LLSDA2-.           /* Language Specific Data Area */
5160        .byte   0x4     /* DW_CFA_advance_loc4 */
5161        .long Lffcall_return_registers_setup-Lffcall_return_registers
5162        .byte   0xe     /* DW_CFA_def_cfa_offset */
5163        .byte   0x10    /* uleb128 0x10 */
5164        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5165        .byte   0x2     /* uleb128 0x2 */
5166        .byte   0x4     /* DW_CFA_advance_loc4 */
5167        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup
5168        .byte   0xd     /* DW_CFA_def_cfa_register */
5169        .byte   0x6     /* uleb128 0x6 */
5170        .byte   0x4     /* DW_CFA_advance_loc4 */
5171        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call
5172        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5173        .byte   0x3     /* uleb128 0x3 */
5174        .align 3
5175LEFDEffcall_return_registers:
5176        .text
5177        .endif
5178        __endif
5179       
5180_spentry(unused_5)
5181        __(hlt)
5182Xspentry_end:           
5183_endsubp(unused_5)
5184       
5185        .data
5186        .globl C(spentry_start)
5187        .globl C(spentry_end)
5188C(spentry_start):       .quad Xspentry_start
5189C(spentry_end):         .quad Xspentry_end
Note: See TracBrowser for help on using the repository browser.