source: release/1.9/source/lisp-kernel/x86-spentry64.s @ 16083

Last change on this file since 16083 was 16070, checked in by rme, 5 years ago

Merge operand size fix (r16061) from trunk.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 167.4 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        /* pc_luser_xp() expects the store to be the first instruction here */
1766        __(_rplaca(%arg_y,%arg_z))
1767        __(rcmpq(%arg_z,%arg_y))
1768        __(ja 1f)
17690:      __(repret)
17701:      __(movq %arg_y,%imm0)
1771        __(subq lisp_global(ref_base),%imm0)
1772        __(shrq $dnode_shift,%imm0)
1773        __(movq %imm0,%imm1)
1774        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1775        __(jae 2f)
1776        __(ref_global(refbits,%temp0))
1777        __(xorb $63,%imm0_b)
1778        __(lock)
1779        __(btsq %imm0,(%temp0))
17802:      __(cmpq lisp_global(managed_static_dnodes),%imm1)
1781        __(jae 0b)
1782        __(ref_global(managed_static_refbits,%temp0))
1783        __(xorb $63,%imm1_b)
1784        __(lock)
1785        __(btsq %imm1,(%temp0))
1786        __(ret)
1787_endsubp(rplaca)
1788
1789_spentry(rplacd)
1790        .globl C(egc_rplacd)
1791C(egc_rplacd):         
1792        /* pc_luser_xp() expects the store to be the first instruction here */
1793        __(_rplacd(%arg_y,%arg_z))
1794        __(rcmpq(%arg_z,%arg_y))
1795        __(ja 1f)
17960:      __(repret)
17971:      __(movq %arg_y,%imm0)
1798        __(subq lisp_global(ref_base),%imm0)
1799        __(shrq $dnode_shift,%imm0)
1800        __(movq %imm0,%imm1)
1801        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1802        __(jae 2f)
1803        __(ref_global(refbits,%temp0))
1804        __(xorb $63,%imm0_b)
1805        __(lock)
1806        __(btsq %imm0,(%temp0))
1807        __(ret)
18082:      __(cmpq lisp_global(managed_static_dnodes),%imm1)
1809        __(jae 0b)
1810        __(ref_global(managed_static_refbits,%temp0))
1811        __(xorb $63,%imm1_b)
1812        __(lock)
1813        __(btsq %imm1,(%temp0))
1814        __(ret)       
1815_endsubp(rplacd)
1816
1817/* Storing into a gvector can be handled the same way as storing into a CONS.  */
1818
1819
1820_spentry(gvset)
1821        .globl C(egc_gvset)
1822C(egc_gvset):
1823        /* pc_luser_xp() expects the store to be the first instruction here */
1824        __(movq %arg_z,misc_data_offset(%arg_x,%arg_y))
1825        __(rcmpq(%arg_z,%arg_x))
1826        __(ja 1f)
18270:      __(repret)
18281:      __(lea misc_data_offset(%arg_x,%arg_y),%imm0)
1829        __(subq lisp_global(ref_base),%imm0)
1830        __(shrq $dnode_shift,%imm0)
1831        __(movq %imm0,%imm1)
1832        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1833        __(jae 2f)
1834        __(ref_global(refbits,%temp0))
1835        __(xorb $63,%imm0_b)
1836        __(lock)
1837        __(btsq %imm0,(%temp0))
18382:      __(cmpq lisp_global(managed_static_dnodes),%imm1)
1839        __(jae 0b)
1840        __(ref_global(managed_static_refbits,%temp0))
1841        __(xorb $63,%imm1_b)
1842        __(lock)
1843        __(btsq %imm1,(%temp0))       
1844        __(ret)               
1845_endsubp(gvset)
1846
1847/* This is a special case of storing into a gvector: if we need to  */
1848/* memoize the store, record the address of the hash-table vector  */
1849/* in the refmap, as well.  */
1850       
1851
1852_spentry(set_hash_key)
1853        .globl C(egc_set_hash_key)
1854C(egc_set_hash_key): 
1855        /* pc_luser_xp() expects the store to be the first instruction here */
1856        __(movq %arg_z,misc_data_offset(%arg_x,%arg_y))
1857        __(rcmpq(%arg_z,%arg_x))
1858        __(ja 1f)
18590:      __(repret)
18601:      __(lea misc_data_offset(%arg_x,%arg_y),%imm0)
1861        __(subq lisp_global(ref_base),%imm0)
1862        __(shrq $dnode_shift,%imm0)
1863        __(movq %imm0,%imm1)
1864        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1865        __(jae 2f)
1866        __(ref_global(refbits,%temp0))
1867        __(xorb $63,%imm0_b)
1868        __(lock)
1869        __(btsq %imm0,(%temp0))
1870        /* Now memoize the address of the hash vector   */
1871        __(movq %arg_x,%imm0)
1872        __(subq lisp_global(ref_base),%imm0)
1873        __(shrq $dnode_shift,%imm0)
1874        __(xorb $63,%imm0_b)
1875        __(lock)
1876        __(btsq %imm0,(%temp0))
18772:      __(cmpq lisp_global(managed_static_dnodes),%imm1)
1878        __(jae 0b)
1879        __(ref_global(managed_static_refbits,%temp0))
1880        __(xorb $63,%imm1_b)
1881        __(lock)
1882        __(btsq %imm1,(%temp0))
1883        /* Now memoize the address of the hash vector   */
1884        __(movq %arg_x,%imm0)
1885        __(subq lisp_global(ref_base),%imm0)
1886        __(shrq $dnode_shift,%imm0)
1887        __(xorb $63,%imm0_b)
1888        __(lock)
1889        __(btsq %imm0,(%temp0))
1890        __(ret)
1891_endsubp(set_hash_key)
1892
1893/* This is a little trickier: if this is interrupted, we need to know  */
1894/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1895/* If we're interrupted   before the PC has reached the "success_test" label,   */
1896/* repeat (luser the PC back to store_node_conditional_retry.)  If we're at that  */
1897/* label with the Z flag set, we won and (may) need to memoize.  */
1898
1899_spentry(store_node_conditional)
1900        .globl C(egc_store_node_conditional)
1901C(egc_store_node_conditional):
1902        __(unbox_fixnum(%temp0,%imm1))
1903        .globl C(egc_store_node_conditional_retry)
1904C(egc_store_node_conditional_retry):     
19050:      __(movq %arg_y,%imm0)
1906        __(lock)
1907        __(cmpxchgq %arg_z,(%arg_x,%imm1))
1908        .globl C(egc_store_node_conditional_success_test)
1909C(egc_store_node_conditional_success_test):
1910        __(jne 9f)
1911        __(lea (%arg_x,%imm1),%imm0)
1912        __(subq lisp_global(ref_base),%imm0)
1913        __(shrq $dnode_shift,%imm0)
1914        __(movq %imm0,%imm1)
1915        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1916        __(ref_global(refbits,%temp1))
1917        __(jae 2f)
1918        __(xorb $63,%imm0_b)
1919        __(lock)
1920        __(btsq %imm0,(%temp1))
19212:      __(cmpq lisp_global(managed_static_dnodes),%imm1)
1922        __(jae 8f)
1923        __(ref_global(managed_static_refbits,%temp1))
1924        __(xorb $63,%imm1_b)
1925        __(lock)
1926        __(btsq %imm1,(%temp1))       
1927        .globl C(egc_store_node_conditional_success_end)
1928C(egc_store_node_conditional_success_end):
19298:      __(movl $t_value,%arg_z_l)
1930        __(ret)
19319:      __(movl $nil_value,%arg_z_l)
1932        __(ret)
1933_endsubp(store_node_conditional)
1934                               
1935        _spentry(set_hash_key_conditional)
1936        .globl C(egc_set_hash_key_conditional)
1937C(egc_set_hash_key_conditional):
1938        .globl C(egc_set_hash_key_conditional_retry)
1939C(egc_set_hash_key_conditional_retry):         
1940        __(unbox_fixnum(%temp0,%imm1))
19410:      __(movq %arg_y,%imm0)
1942        __(lock)
1943        __(cmpxchgq %arg_z,(%arg_x,%imm1))
1944        .globl C(egc_set_hash_key_conditional_success_test)
1945C(egc_set_hash_key_conditional_success_test):
1946        __(jne 9f)
1947        __(lea (%arg_x,%imm1),%imm0)
1948        __(subq lisp_global(ref_base),%imm0)
1949        __(shrq $dnode_shift,%imm0)
1950        __(movq %imm0,%imm1)
1951        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
1952        __(ref_global(refbits,%temp1))
1953        __(jae 2f)
1954        __(xorb $63,%imm0_b)
1955        __(lock)
1956        __(btsq %imm0,(%temp1))
1957        /* Now memoize the address of the hash vector   */
1958        __(movq %arg_x,%imm0)
1959        __(subq lisp_global(ref_base),%imm0)
1960        __(shrq $dnode_shift,%imm0)
1961        __(xorb $63,%imm0_b)
1962        __(lock)
1963        __(btsq %imm0,(%temp1))
19642:      __(cmpq lisp_global(managed_static_dnodes),%imm1)
1965        __(jae 8f)
1966        __(ref_global(managed_static_refbits,%temp1))
1967        __(xorb $63,%imm1_b)
1968        __(lock)
1969        __(btsq %imm1,(%temp1))
1970        /* Now memoize the address of the hash vector   */
1971        __(movq %arg_x,%imm0)
1972        __(subq lisp_global(ref_base),%imm0)
1973        __(shrq $dnode_shift,%imm0)
1974        __(xorb $63,%imm0_b)
1975        __(lock)
1976        __(btsq %imm0,(%temp1))
1977        .globl C(egc_write_barrier_end)
1978C(egc_write_barrier_end):
19798:      __(movl $t_value,%arg_z_l)
1980        __(ret)
19819:      __(movl $nil_value,%arg_z_l)
1982        __(ret)
1983_endsubp(set_hash_key_conditional)
1984
1985       
1986
1987
1988_spentry(setqsym)
1989        __(btq $sym_vbit_const,symbol.flags(%arg_y))
1990        __(jae _SPspecset)
1991        __(movq %arg_y,%arg_z)
1992        __(movq $XCONST,%arg_y)
1993        __(set_nargs(2))
1994        __(jmp _SPksignalerr)
1995_endsubp(setqsym)
1996
1997_spentry(progvsave)
1998        /* Error if arg_z isn't a proper list.  That's unlikely,  */
1999        /* but it's better to check now than to crash later.  */
2000       
2001        __(compare_reg_to_nil(%arg_z))
2002        __(movq %arg_z,%arg_x)  /* fast   */
2003        __(movq %arg_z,%temp1)  /* slow   */
2004        __(je 9f)               /* Null list is proper   */
20050:
2006        __(extract_lisptag(%arg_x,%imm0))
2007        __(cmpb $tag_list,%imm0_b)
2008        __(jne 8f)
2009        __(compare_reg_to_nil(%arg_x))
2010        __(je 9f)
2011        __(_cdr(%arg_x,%temp0)) /* (null (cdr fast)) ?   */
2012        __(compare_reg_to_nil(%temp0))
2013        __(je 9f)
2014        __(extract_lisptag(%temp0,%imm0))
2015        __(cmpb $tag_list,%imm0_b)
2016        __(jne 8f)
2017        __(_cdr(%temp0,%arg_x))
2018        __(_cdr(%temp1,%temp1))
2019        __(cmpq %temp1,%arg_x)
2020        __(jne 0b)
2021
20228:      __(movq $XIMPROPERLIST,%arg_y)
2023        __(set_nargs(2))
2024        __(jmp _SPksignalerr)
20259:      /* Whew           */
2026
2027        /* Next, determine the length of arg_y.  We   */
2028        /* know that it's a proper list.   */
2029        __(movq $-fixnumone,%imm0)
2030        __(movq %arg_y,%arg_x)
20311:      __(compare_reg_to_nil(%arg_x))
2032        __(_cdr(%arg_x,%arg_x))
2033        __(leaq fixnumone(%imm0),%imm0)
2034        __(jne 1b)
2035       
2036        /* imm0 is now (boxed) triplet count.  */
2037        /* Determine word count, add 1 (to align), and make room.  */
2038        /*  if count is 0, make an empty tsp frame and exit   */
2039        __(testq %imm0,%imm0)
2040        __(jne 2f)
2041        __(TSP_Alloc_Fixed(2*node_size,%imm0))
2042        __(ret)
20432:      __(movq %imm0,%imm1)
2044        __(add %imm1,%imm1)
2045        __(add %imm0,%imm1)
2046        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2047        __(TSP_Alloc_Var(%imm1,%temp0))
2048        __(movq %imm0,(%temp0))
2049        __(movq rcontext(tcr.db_link),%temp1)
20503:      __(movl $unbound_marker,%temp0_l)
2051        __(compare_reg_to_nil(%arg_z))
2052        __(cmovneq cons.car(%arg_z),%temp0)
2053        __(cmovneq cons.cdr(%arg_z),%arg_z)
2054        __(_car(%arg_y,%arg_x))
2055        __(_cdr(%arg_y,%arg_y))
2056        __(movq symbol.binding_index(%arg_x),%arg_x)
2057        __(cmp rcontext(tcr.tlb_limit),%arg_x)
2058        __(jb 4f)
2059        __(push %arg_x)
2060        __(tlb_too_small())
20614:      __(movq rcontext(tcr.tlb_pointer),%imm0)
2062        __(subq $binding.size,%imm1)
2063        __(compare_reg_to_nil(%arg_y))
2064        __(movq %arg_x,binding.sym(%imm1))
2065        __(push (%imm0,%arg_x))
2066        __(pop binding.val(%imm1))
2067        __(movq %temp0,(%imm0,%arg_x))
2068        __(movq %temp1,binding.link(%imm1))
2069        __(movq %imm1,%temp1)
2070        __(jne 3b)
2071        __(movq %temp1,rcontext(tcr.db_link))
2072        __(ret)
2073_endsubp(progvsave)
2074
2075/* Allocate node objects on the temp stack, immediate objects on the foreign  */
2076/* stack. (The caller has to know which stack to discard a frame from.)  */
2077/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
2078       
2079_spentry(stack_misc_alloc)
2080        __(movq $~(((1<<56)-1)<<fixnumshift),%temp0)
2081        __(testq %temp0,%arg_y)
2082        __(jne local_label(stack_misc_alloc_not_u56))
2083        __(unbox_fixnum(%arg_z,%imm0))
2084        __(movq %arg_y,%temp0)
2085        __(shl $num_subtag_bits-fixnumshift,%temp0)
2086        __(orq %temp0,%imm0)            /* %imm0 now = header   */
2087        __(movb $fulltagmask,%imm1_b)
2088        __(andb %imm0_b,%imm1_b)
2089        __(cmpb $fulltag_nodeheader_0,%imm1_b)
2090        __(je local_label(stack_misc_alloc_node))
2091        __(cmpb $fulltag_nodeheader_1,%imm1_b)
2092        __(je local_label(stack_misc_alloc_node))
2093        __(cmpb $ivector_class_64_bit,%imm1_b)
2094        __(jz local_label(stack_misc_alloc_64))
2095        __(cmpb $ivector_class_32_bit,%imm1_b)
2096        __(jz local_label(stack_misc_alloc_32))
2097        __(unbox_fixnum(%arg_y,%imm1))
2098        /* ivector_class_other_bit: 16, 8, or 1 ...   */
2099        __(cmpb $subtag_bit_vector,%imm0_b)
2100        __(jne local_label(stack_misc_alloc_8))
2101        __(addq $7,%imm1)
2102        __(shrq $3,%imm1)
2103        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2104local_label(stack_misc_alloc_8):       
2105        __(cmpb $subtag_simple_base_string,%imm0_b)
2106        __(jb local_label(stack_misc_alloc_16))
2107        __(unbox_fixnum(%arg_y,%imm1))
2108        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2109local_label(stack_misc_alloc_16):       
2110        __(unbox_fixnum(%arg_y,%imm1))
2111        __(shlq %imm1)
2112        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2113local_label(stack_misc_alloc_32):
2114        /* 32-bit ivector   */
2115        __(unbox_fixnum(%arg_y,%imm1))
2116        __(shlq $2,%imm1)
2117        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2118local_label(stack_misc_alloc_64):
2119        /* 64-bit ivector         */
2120        __(movq %arg_y,%imm1)
2121local_label(stack_misc_alloc_alloc_ivector):   
2122        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2123        __(cmpq $tstack_alloc_limit,%imm1)
2124        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
2125        __ifdef(`WINDOWS')
2126         __(windows_cstack_probe(%imm1,%temp0))
2127        __endif
2128        __(movq rcontext(tcr.foreign_sp),%stack_temp)
2129        __(movd %stack_temp,%temp1)
2130        __(subq %imm1,rcontext(tcr.foreign_sp))
2131        __(movq rcontext(tcr.foreign_sp),%temp0)
21320:      __(movapd %fpzero,-dnode_size(%temp1))
2133        __(subq $dnode_size,%temp1)
2134        __(cmpq %temp1,%temp0)
2135        __(jnz 0b)     
2136        __(movq %stack_temp,(%temp0))
2137        __(movq %rbp,csp_frame.save_rbp(%temp0))
2138        __(movq %imm0,csp_frame.fixed_overhead(%temp0))
2139        __(leaq csp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
2140        __(ret)
2141local_label(stack_misc_alloc_heap_alloc_ivector):
2142        __(movq rcontext(tcr.foreign_sp),%imm1)
2143        __(subq $dnode_size,rcontext(tcr.foreign_sp))
2144        __(movq rcontext(tcr.foreign_sp),%imm0)
2145        __(movq %imm1,(%imm0))
2146        __(jmp _SPmisc_alloc)   
2147local_label(stack_misc_alloc_node):
2148        __(movq %arg_y,%imm1)
2149        __(dnode_align(%imm1,tsp_frame.fixed_overhead+node_size,%imm1))
2150        __(cmpq $tstack_alloc_limit,%imm1)
2151        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
2152        __(TSP_Alloc_Var(%imm1,%temp0))
2153        __(movq %imm0,(%temp0))
2154        __(leaq fulltag_misc(%temp0),%arg_z)
2155        __(ret)
2156local_label(stack_misc_alloc_heap_alloc_gvector):       
2157        __(TSP_Alloc_Fixed(0,%imm0))
2158        __(jmp _SPmisc_alloc)   
2159               
2160local_label(stack_misc_alloc_not_u56):                         
2161        __(movl $XARRLIMIT,%arg_x_l)
2162        __(set_nargs(3))
2163        __(jmp _SPksignalerr)
2164_endsubp(stack_misc_alloc)
2165
2166/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of   */
2167/* initial-contents.  Note that this can be used to cons any type of initialized   */
2168/* node-header'ed misc object (symbols, closures, ...) as well as vector-like   */
2169/* objects.   */
2170_spentry(gvector)
2171        __(subl $node_size,%nargs)
2172        __(movq (%rsp,%nargs_q),%imm0)  /* boxed subtype   */
2173        __(sarq $fixnumshift,%imm0)
2174        __(movq %nargs_q,%imm1)
2175        __(shlq $num_subtag_bits-word_shift,%imm1)
2176        __(orq %imm1,%imm0)
2177        __(dnode_align(%nargs_q,node_size,%imm1))
2178        __(Misc_Alloc(%arg_z))
2179        __(movq %nargs_q,%imm1)
2180        __(jmp 2f)
21811:      __(movq %temp0,misc_data_offset(%arg_z,%imm1))
21822:      __(subq $node_size,%imm1)
2183        __(pop %temp0)  /* Note the intentional fencepost:  */
2184                        /* discard the subtype as well.  */
2185        __(jge 1b)
2186        __(jmp *%ra0)
2187_endsubp(gvector)
2188
2189_spentry(mvpass)
2190        __(hlt)
2191_endsubp(mvpass)
2192
2193
2194
2195_spentry(nthvalue)
2196        __(hlt)
2197_endsubp(nthvalue)
2198
2199_spentry(values)
2200        __(movq (%temp0),%ra0)
2201        __(ref_global(ret1val_addr,%imm1))
2202        __(cmpq %imm1,%ra0)
2203        __(movl $nil_value,%arg_z_l)
2204        __(je 0f)
2205        __(testl %nargs,%nargs)
2206        __(cmovneq -node_size(%rsp,%nargs_q),%arg_z)
2207        __(movq %temp0,%rsp)
2208        __(ret)
22090:      __(movq 8(%temp0),%ra0)
2210        __(addq $2*node_size,%temp0)
2211        __(lea (%rsp,%nargs_q),%imm0)
2212        __(jmp 2f)
22131:      __(subq $node_size,%imm0)
2214        __(movq (%imm0),%temp1)
2215        __(subq $node_size,%temp0)
2216        __(movq %temp1,(%temp0))
22172:      __(cmpq %imm0,%rsp)
2218        __(jne 1b)
2219        __(movq %temp0,%rsp)
2220        __(jmp *%ra0)   
2221_endsubp(values)
2222
2223_spentry(default_optional_args)
2224        __(hlt)
2225_endsubp(default_optional_args)
2226
2227_spentry(opt_supplied_p)
2228        __(hlt)
2229_endsubp(opt_supplied_p)
2230
2231_spentry(lexpr_entry)
2232        __(hlt)
2233_endsubp(lexpr_entry)
2234       
2235_spentry(heap_rest_arg)
2236        __(push_argregs())
2237        __(movq %next_method_context,%arg_y)
2238        __(movl %nargs,%imm1_l)
2239        __(testl %imm1_l,%imm1_l)
2240        __(movl $nil_value,%arg_z_l)
2241        __(jmp 2f)
2242        .p2align 4
22431:      __(pop %temp1)
2244        __(Cons(%temp1,%arg_z,%arg_z))
2245        __(subl $node_size,%imm1_l)
22462:      __(jg 1b)
2247        __(push %arg_z)
2248        __(movq %arg_y,%next_method_context)
2249        __(jmp *%ra0)           
2250_endsubp(heap_rest_arg)
2251
2252/* %imm0 contains the number of fixed args ; make an &rest arg out of the others   */
2253_spentry(req_heap_rest_arg)
2254        __(push_argregs())
2255        __(movq %next_method_context,%arg_y)
2256        __(movl %nargs,%imm1_l)
2257        __(subl %imm0_l,%imm1_l)
2258        __(movl $nil_value,%arg_z_l)
2259        __(jmp 2f)
2260        .p2align 4
22611:      __(pop %temp1)
2262        __(Cons(%temp1,%arg_z,%arg_z))
2263        __(subl $node_size,%imm1_l)
22642:      __(jg 1b)
2265        __(push %arg_z)
2266        __(movq %arg_y,%next_method_context)
2267        __(jmp *%ra0)           
2268_endsubp(req_heap_rest_arg)
2269
2270/* %imm0 bytes of stuff has already been pushed   */
2271/* make an &rest arg out of any others   */
2272_spentry(heap_cons_rest_arg)
2273        __(movl %nargs,%imm1_l)
2274        __(subl %imm0_l,%imm1_l)
2275        __(movq %next_method_context,%arg_y)
2276        __(movl $nil_value,%arg_z_l)
2277        __(jmp 2f)
2278        .p2align 4
22791:      __(pop %temp1)
2280        __(Cons(%temp1,%arg_z,%arg_z))
2281        __(subl $node_size,%imm1_l)
22822:      __(jg 1b)
2283        __(push %arg_z)
2284        __(movq %arg_y,%next_method_context)
2285        __(jmp *%ra0)           
2286_endsubp(heap_cons_rest_arg)
2287
2288_spentry(simple_keywords)
2289        __(xorl %imm0_l,%imm0_l)
2290        __(push_argregs())
2291        __(jmp _SPkeyword_bind)
2292_endsubp(simple_keywords)
2293
2294_spentry(keyword_args)
2295        __(push_argregs())
2296        __(jmp _SPkeyword_bind)
2297_endsubp(keyword_args)
2298
2299/* There are %nargs words of arguments on the stack; %imm0 contains the number  */
2300/* of non-keyword args pushed.  It's possible that we never actually got  */
2301/* any keyword args, which would make things much simpler.   */
2302
2303/* On entry, temp1 contains a fixnum with bits indicating whether   */
2304/* &allow-other-keys and/or &rest was present in the lambda list.  */
2305/* Once we get here, we can use the arg registers.  */
2306
2307define(`keyword_flags_aok_bit',`fixnumshift')
2308define(`keyword_flags_unknown_keys_bit',`fixnumshift+1')
2309define(`keyword_flags_rest_bit',`fixnumshift+2')
2310define(`keyword_flags_seen_aok_bit',`fixnumshift+3')       
2311       
2312_spentry(keyword_bind)
2313        __(movl %nargs,%imm1_l)
2314        __(subq %imm0,%imm1)
2315        __(jbe local_label(no_keyword_values))
2316        __(btq $word_shift,%imm1)
2317        __(jnc local_label(even))
2318        __(movl $nil_value,%arg_z_l)
2319        __(movq %imm1,%nargs_q)
2320        __(testl %nargs,%nargs)
2321        __(jmp 1f)
23220:      __(pop %arg_y)
2323        __(Cons(%arg_y,%arg_z,%arg_z))
2324        __(subl $node_size,%nargs)
23251:      __(jnz 0b)
2326        __(movl $XBADKEYS,%arg_y_l)
2327        __(set_nargs(2))
2328        __(jmp _SPksignalerr)
2329        /* Now that we're sure that we have an even number of keywords and values  */
2330        /* (in %imm1), copy all pairs to the temp stack   */
2331local_label(even):
2332        /* Get the keyword vector into arg_x, and its length into arg_y.  */
2333        __(movl function_data_offset(%fn),%imm0_l)
2334        __(movq function_data_offset(%fn,%imm0,node_size),%arg_x)
2335        __(vector_length(%arg_x,%arg_y))
2336        __(testq %arg_y,%arg_y)
2337        __(jne 1f)
2338        __(btq $keyword_flags_aok_bit,%temp1)
2339        __(jnc 1f)
2340
2341        __(btq $keyword_flags_rest_bit,%temp1)
2342        __(jc 0f)
2343        __(addq %imm1,%rsp)
23440:     
2345        __(jmp *%ra0)
23461:     
2347        __(lea tsp_frame.fixed_overhead(%imm1),%arg_z)
2348        __(TSP_Alloc_Var(%arg_z,%imm0))
23492:      __(subq $node_size,%arg_z)
2350        __(pop (%arg_z))
2351        __(cmpq %arg_z,%imm0)
2352        __(jne 2b)
2353        /* Push arg_y pairs of NILs.   */
2354        __(movq %arg_y,%imm0)
2355        __(jmp 4f)
23563:      __(push $nil_value)
2357        __(push $nil_value)
23584:      __(subq $fixnumone,%arg_y)
2359        __(jge 3b)
2360        /* Push the %saveN registers, so that we can use them in this loop   */
2361        /* Also, borrow %arg_y for a bit */
2362        __(push %arg_y)
2363        __(push %save2)
2364        __(push %save1)
2365        __(push %save0)
2366        __(leaq 4*node_size(%rsp,%imm0,2),%save0)
2367        /* %save0 points to the 0th value/supplied-p pair   */
2368        __(leaq (%arg_z,%imm1),%save1)
2369        /* %save1 is the end of the provided keyword/value pairs (the old %tsp).   */
2370        __(movq %imm0,%save2)
2371        /* %save2 is the length of the keyword vector   */
23725:      __(movq (%arg_z),%arg_y)        /* %arg_y is current keyword   */
2373        __(xorl %imm0_l,%imm0_l)
2374        __(cmpq $nrs.kallowotherkeys,%arg_y)
2375        __(jne local_label(next_keyvect_entry))
2376        __(btsq $keyword_flags_seen_aok_bit,%temp1)
2377        __(jc local_label(next_keyvect_entry))
2378        __(cmpb $fulltag_nil,node_size(%arg_z))
2379        __(je local_label(next_keyvect_entry))
2380        __(btsq $keyword_flags_aok_bit,%temp1)
2381        __(jmp local_label(next_keyvect_entry))
23826:      __(cmpq misc_data_offset(%arg_x,%imm0),%arg_y)
2383        __(jne 7f)
2384        /* Got a match; have we already seen this keyword ?   */
2385        __(negq %imm0)
2386        __(cmpb $fulltag_nil,-node_size*2(%save0,%imm0,2))
2387        __(jne 9f)      /* already seen keyword, ignore this value   */
2388        __(movq node_size(%arg_z),%arg_y)
2389        __(movq %arg_y,-node_size(%save0,%imm0,2))
2390        __(movl $t_value,-node_size*2(%save0,%imm0,2))
2391        __(jmp 9f)
23927:      __(addq $node_size,%imm0)
2393local_label(next_keyvect_entry):       
2394        __(cmpq %imm0,%save2)
2395        __(jne 6b)
2396        /* Didn't match anything in the keyword vector. Is the keyword  */
2397        /* :allow-other-keys ?   */
2398        __(cmpq $nrs.kallowotherkeys,%arg_y)
2399        __(je 9f)               /* :allow-other-keys is never "unknown" */
24008:      __(btsq $keyword_flags_unknown_keys_bit,%temp1)
24019:      __(addq $dnode_size,%arg_z)
2402        __(cmpq %arg_z,%save1)
2403        __(jne 5b)
2404        __(pop %save0)
2405        __(pop %save1)
2406        __(pop %save2)
2407        __(pop %arg_y)
2408        /* If the function takes an &rest arg, or if we got an unrecognized  */
2409        /* keyword and don't allow that, copy the incoming keyword/value  */
2410        /* pairs from the temp stack back to the value stack   */
2411        __(btq $keyword_flags_rest_bit,%temp1)
2412        __(jc 1f)
2413        __(btq $keyword_flags_unknown_keys_bit,%temp1)
2414        __(jnc 0f)
2415        __(btq $keyword_flags_aok_bit,%temp1)
2416        __(jnc 1f)
2417        /* pop the temp frame   */
24180:      __(discard_temp_frame(%imm1))
2419        __(jmp *%ra0)
2420        /* Copy the keyword/value pairs from the tsp back to sp, either because  */
2421        /* the function takes an &rest arg or because we need to signal an  */
2422        /* "unknown keywords" error   */
24231:      __(movq rcontext(tcr.save_tsp),%arg_z)
2424        __(mov (%arg_z),%arg_y)
2425        __(jmp 3f)
24262:      __(push (%arg_z))
2427        __(push node_size(%arg_z))
24283:      __(addq $dnode_size,%arg_z)
2429        __(cmpq %arg_z,%arg_y)
2430        __(jne 2b)
2431        __(discard_temp_frame(%imm0))
2432        __(btq $keyword_flags_unknown_keys_bit,%temp1)
2433        __(jnc 9f)
2434        __(btq $keyword_flags_aok_bit,%temp1)
2435        __(jc 9f)
2436        /* Signal an "unknown keywords" error   */
2437        __(movq %imm1,%nargs_q)
2438        __(testl %nargs,%nargs)
2439        __(movl $nil_value,%arg_z_l)
2440        __(jmp 5f)
24414:      __(pop %arg_y)
2442        __(Cons(%arg_y,%arg_z,%arg_z))
2443        __(subl $node_size,%nargs)
24445:      __(jnz 4b)
2445        __(movl $XBADKEYS,%arg_y_l)
2446        __(set_nargs(2))
2447        __(push %ra0)
2448        __(jmp _SPksignalerr)
24499:      __(jmp *%ra0)
2450       
2451/* No keyword values were provided.  Access the keyword vector (which is the 0th  */
2452/*  constant in %fn), determine its length N, and push N        pairs of NILs.   */
2453/* N could be 0 ...  */
2454       
2455local_label(no_keyword_values):         
2456        __(movl function_data_offset(%fn),%imm0_l)
2457        __(movq function_data_offset(%fn,%imm0,node_size),%arg_x)
2458        __(movl $nil_value,%arg_z_l)
2459        __(vector_length(%arg_x,%arg_y))
2460        __(jmp 1f)
24610:      __(push %arg_z)
2462        __(push %arg_z)
24631:      __(subq $fixnumone,%arg_y)
2464        __(jge 0b)
2465        __(jmp *%ra0)           
2466_endsubp(keyword_bind)
2467
2468
2469
2470_spentry(ksignalerr)
2471        __(movq $nrs.errdisp,%fname)
2472        __(jump_fname) 
2473_endsubp(ksignalerr)
2474
2475_spentry(stack_rest_arg)
2476        __(xorl %imm0_l,%imm0_l)
2477        __(push_argregs())
2478        __(jmp _SPstack_cons_rest_arg)
2479_endsubp(stack_rest_arg)
2480
2481_spentry(req_stack_rest_arg)
2482        __(push_argregs())
2483        __(jmp _SPstack_cons_rest_arg)
2484_endsubp(req_stack_rest_arg)
2485
2486_spentry(stack_cons_rest_arg)
2487        __(movl %nargs,%imm1_l)
2488        __(subl %imm0_l,%imm1_l)
2489        __(movl $nil_value,%arg_z_l)
2490        __(jle 2f)      /* empty list ; make an empty TSP frame   */
2491        __(addq %imm1,%imm1)
2492        __(cmpq $(tstack_alloc_limit-dnode_size),%imm1)
2493        __(ja 3f)       /* make empty frame, then heap-cons   */
2494        __(dnode_align(%imm1,tsp_frame.fixed_overhead,%imm0))
2495        __(TSP_Alloc_Var(%imm0,%temp1))
2496        __(addq $fulltag_cons,%temp1)
24971:      __(pop %arg_x)
2498        __(_rplacd(%temp1,%arg_z))
2499        __(_rplaca(%temp1,%arg_x))
2500        __(movq %temp1,%arg_z)
2501        __(addq $cons.size,%temp1)
2502        __(subq $dnode_size,%imm1)
2503        __(jne 1b)
2504        __(push %arg_z)
2505        __(jmp *%ra0)
2506       
2507/* Length 0, make empty frame  */
2508       
25092:
2510        __(TSP_Alloc_Fixed(0,%temp1))
2511        __(push %arg_z)
2512        __(jmp *%ra0)
2513       
2514/* Too big to stack-cons, but make an empty frame before heap-consing  */
2515       
25163:             
2517        __(TSP_Alloc_Fixed(0,%temp1))
2518        __(jmp _SPheap_cons_rest_arg)
2519_endsubp(stack_cons_rest_arg)
2520
2521
2522
2523_spentry(getxlong)
2524_endsubp(getxlong)
2525
2526/* Have to be a little careful here: the caller may or may not have pushed  */
2527/*   an empty frame, and we may or may not have needed one.  We can't easily  */
2528/*   tell whether or not a frame will be needed (if the caller didn't reserve  */
2529/*   a frame, whether or not we need one depends on the length of the list  */
2530/*   in arg_z.  So, if the caller didn't push a frame, we do so ; once everything's  */
2531/*   been spread, we discard the reserved frame (regardless of who pushed it)  */
2532/*   if all args fit in registers.   */
2533_spentry(spreadargz)
2534        __(testl %nargs,%nargs)
2535        __(jne 0f)
2536        __(push $reserved_frame_marker)
2537        __(push $reserved_frame_marker)
25380:      __(movq %arg_z,%arg_y)  /* save in case of error   */
2539        __(xorl %imm0_l,%imm0_l)
2540        __(compare_reg_to_nil(%arg_z))
2541        __(je 2f)
25421:      __(extract_fulltag(%arg_z,%imm1))
2543        __(cmpb $fulltag_cons,%imm1_b)
2544        __(jne 9f)
2545        __(_car(%arg_z,%arg_x))
2546        __(_cdr(%arg_z,%arg_z))
2547        __(addl $node_size,%imm0_l)
2548        __(cmpl $call_arguments_limit<<fixnumshift, %imm0_l)
2549        __(jae 8f)
2550        __(compare_reg_to_nil(%arg_z))
2551        __(push %arg_x)
2552        __(jne 1b)
25532:      __(addl %imm0_l,%nargs)
2554        __(jne 4f)
25553:      __(addq $2*node_size,%rsp)
2556        __(jmp *%ra0)
25574:      __(cmpl $1*node_size,%nargs)
2558        __(pop %arg_z)
2559        __(je 3b)
2560        __(cmpl $2*node_size,%nargs)
2561        __(pop %arg_y)
2562        __(je 3b)
2563        __(cmpl $3*node_size,%nargs)
2564        __(pop %arg_x)
2565        __(je 3b)
2566        __(jmp *%ra0)
2567/* Discard everything that's been pushed already, complain   */
2568
25698:      __(lea (%rsp,%imm0),%rsp)
2570        __(movq %arg_y,%arg_z)  /* recover original   */
2571        __(movq $XTMINPS,%arg_y)
2572        __(set_nargs(2))
2573        __(push %ra0)
2574        __(jmp _SPksignalerr)
2575/* Discard everything that's been pushed already, complain   */
25769:      __(lea (%rsp,%imm0),%rsp)
2577        __(movq %arg_y,%arg_z)  /* recover original   */
2578        __(movq $XNOSPREAD,%arg_y)
2579        __(set_nargs(2))
2580        __(push %ra0)
2581        __(jmp _SPksignalerr)
2582_endsubp(spreadargz)
2583
2584/* Caller built it's own frame when it was entered.  If all outgoing args  */
2585/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2586/* relative to it and restore %rbp/%ra0   */
2587_spentry(tfuncallgen)
2588        __(cmpl $nargregs*node_size,%nargs)
2589        __(jbe 9f)
2590        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2591        __(xorl %imm1_l,%imm1_l)
2592        /* We can use %ra0 as a temporary here, since the real return address  */
2593        /* is on the stack   */
25940:      __(movq -node_size(%imm0),%ra0)
2595        __(movq %ra0,-node_size(%rbp,%imm1))
2596        __(subq $node_size,%imm0)
2597        __(subq $node_size,%imm1)
2598        __(cmpq %imm0,%rsp)
2599        __(jne 0b)
2600        __(lea (%rbp,%imm1),%rsp)
2601        __(movq 8(%rbp),%ra0)
2602        __(movq (%rbp),%rbp)
2603        __(pushq %ra0)
2604        __(do_funcall())
2605        /* All args in regs; exactly the same as the tfuncallvsp case   */
26069:             
2607        __(leave)
2608        __(do_funcall())
2609_endsubp(tfuncallgen)
2610
2611/* Some args were pushed; move them down in the frame   */
2612_spentry(tfuncallslide)
2613        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2614        __(xorl %imm1_l,%imm1_l)
2615        /* We can use %ra0 as a temporary here, since the real return address  */
2616        /* is on the stack   */
26170:      __(movq -node_size(%imm0),%ra0)
2618        __(movq %ra0,-node_size(%rbp,%imm1))
2619        __(subq $node_size,%imm0)
2620        __(subq $node_size,%imm1)
2621        __(cmpq %imm0,%rsp)
2622        __(jne 0b)
2623        __(lea (%rbp,%imm1),%rsp)
2624        __(movq 8(%rbp),%ra0)
2625        __(movq (%rbp),%rbp)
2626        __(push %ra0)
2627        __(do_funcall())       
2628_endsubp(tfuncallslide)
2629
2630/* No args were pushed; recover saved context & do funcall        */
2631_spentry(tfuncallvsp)
2632        __(leave)
2633        __(do_funcall())
2634_endsubp(tfuncallvsp)
2635
2636_spentry(tcallsymgen)
2637        __(cmpl $nargregs*node_size,%nargs)
2638        __(jbe 9f)
2639        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2640        __(xorl %imm1_l,%imm1_l)
2641        /* We can use %ra0 as a temporary here, since the real return address  */
2642        /* is on the stack   */
26430:      __(movq -node_size(%imm0),%ra0)
2644        __(movq %ra0,-node_size(%rbp,%imm1))
2645        __(subq $node_size,%imm0)
2646        __(subq $node_size,%imm1)
2647        __(cmpq %imm0,%rsp)
2648        __(jne 0b)
2649        __(lea (%rbp,%imm1),%rsp)
2650        __(movq 8(%rbp),%ra0)
2651        __(movq (%rbp),%rbp)
2652        __(pushq %ra0)
2653        __(jump_fname())
2654/* All args in regs; exactly the same as the tcallsymvsp case   */
26559:             
2656        __(leave)
2657        __(jump_fname())
2658_endsubp(tcallsymgen)
2659
2660_spentry(tcallsymslide)
2661        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2662        __(xorl %imm1_l,%imm1_l)
2663        /* We can use %ra0 as a temporary here, since the real return address  */
2664        /* is on the stack   */
26650:      __(movq -node_size(%imm0),%ra0)
2666        __(movq %ra0,-node_size(%rbp,%imm1))
2667        __(subq $node_size,%imm0)
2668        __(subq $node_size,%imm1)
2669        __(cmpq %imm0,%rsp)
2670        __(jne 0b)
2671        __(lea (%rbp,%imm1),%rsp)
2672        __(movq 8(%rbp),%ra0)
2673        __(movq 0(%rbp),%rbp)
2674        __(pushq %ra0)
2675        __(jump_fname())
2676_endsubp(tcallsymslide)
2677
2678_spentry(tcallsymvsp)
2679        __(leave)
2680        __(jump_fname())
2681_endsubp(tcallsymvsp)
2682
2683_spentry(tcallnfngen)
2684        __(cmpl $nargregs*node_size,%nargs)
2685        __(jbe 9f)
2686        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2687        __(xorl %imm1_l,%imm1_l)
2688        /* We can use %ra0 as a temporary here, since the real return address  */
2689        /* is on the stack   */
26900:      __(movq -node_size(%imm0),%ra0)
2691        __(movq %ra0,-node_size(%rbp,%imm1))
2692        __(subq $node_size,%imm0)
2693        __(subq $node_size,%imm1)
2694        __(cmpq %imm0,%rsp)
2695        __(jne 0b)
2696        __(movq %temp0,%fn)
2697        __(lea (%rbp,%imm1),%rsp)
2698        __(movq lisp_frame.savera0(%rbp),%ra0)
2699        __(movq lisp_frame.backlink(%rbp),%rbp)
2700        __(pushq %ra0)
2701        __(jmp *%fn)
2702/* All args in regs; exactly the same as the tcallnfnvsp case   */
27039:             
2704        __(movq %temp0,%fn)
2705        __(leave)
2706        __(jmp *%fn)
2707_endsubp(tcallnfngen)
2708
2709_spentry(tcallnfnslide)
2710        __(lea -nargregs*node_size(%rsp,%nargs_q),%imm0)
2711        __(xorl %imm1_l,%imm1_l)
2712        /* We can use %ra0 as a temporary here, since the real return address  */
2713        /* is on the stack   */
27140:      __(movq -node_size(%imm0),%ra0)
2715        __(movq %ra0,-node_size(%rbp,%imm1))
2716        __(subq $node_size,%imm0)
2717        __(subq $node_size,%imm1)
2718        __(cmpq %imm0,%rsp)
2719        __(jne 0b)
2720        __(movq %temp0,%fn)
2721        __(lea (%rbp,%imm1),%rsp)
2722        __(movq lisp_frame.savera0(%rbp),%ra0)
2723        __(movq lisp_frame.backlink(%rbp),%rbp)
2724        __(pushq %ra0)
2725        __(jmp *%fn)
2726_endsubp(tcallnfnslide)
2727
2728_spentry(tcallnfnvsp)
2729        __(movq %temp0,%fn)
2730        __(leave)
2731        __(jmp *%fn)
2732_endsubp(tcallnfnvsp)
2733
2734
2735/* Make a "raw" area on the foreign stack, stack-cons a macptr to point to it,   */
2736/*   and return the macptr.  Size (in bytes, boxed) is in arg_z on entry; macptr  */
2737/*   in arg_z on exit.   */
2738_spentry(makestackblock)
2739        __(unbox_fixnum(%arg_z,%imm0))
2740        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2741        __(cmpq $tstack_alloc_limit,%imm0)
2742        __(jae 1f)
2743        __ifdef(`WINDOWS')
2744         __(windows_cstack_probe(%imm0,%arg_z))
2745        __endif
2746        __(movq rcontext(tcr.foreign_sp),%imm1)
2747        __(subq %imm0,rcontext(tcr.foreign_sp))
2748        __(movq rcontext(tcr.foreign_sp),%arg_z)
2749        __(movq %imm1,(%arg_z))
2750        __(movq %rbp,csp_frame.save_rbp(%arg_z))
2751        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2752        __(movq $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2753        __(addq $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2754        __(movq %imm0,macptr.address(%arg_z))
2755        __(movsd %fpzero,macptr.domain(%arg_z))
2756        __(movsd %fpzero,macptr.type(%arg_z))
2757        __(ret)
27581:      __(movq rcontext(tcr.foreign_sp),%imm1)
2759        __(subq $dnode_size,rcontext(tcr.foreign_sp))
2760        __(movq rcontext(tcr.foreign_sp),%imm0)
2761        __(movq %imm1,(%imm0))
2762        __(movq %rbp,csp_frame.save_rbp(%imm0))
2763        __(set_nargs(1))
2764        __(movq $nrs.new_gcable_ptr,%fname)
2765        __(jump_fname())
2766_endsubp(makestackblock)
2767
2768_spentry(makestackblock0)
2769        __(unbox_fixnum(%arg_z,%imm0))
2770        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2771        __(cmpq $tstack_alloc_limit,%imm0)
2772        __(jae 9f)
2773        __ifdef(`WINDOWS')
2774         __(windows_cstack_probe(%imm0,%arg_z))
2775        __endif       
2776        __(movq rcontext(tcr.foreign_sp),%imm1)
2777        __(subq %imm0,rcontext(tcr.foreign_sp))
2778        __(movq rcontext(tcr.foreign_sp),%arg_z)
2779        __(movq %imm1,(%arg_z))
2780        __(movq %rbp,csp_frame.save_rbp(%arg_z))
2781        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2782        __(movq $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2783        __(addq $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2784        __(movq %imm0,macptr.address(%arg_z))
2785        __(movsd %fpzero,macptr.domain(%arg_z))
2786        __(movsd %fpzero,macptr.type(%arg_z))
2787        __(jmp 2f)
27881:      __(movapd %fpzero,(%imm0))
2789        __(addq $dnode_size,%imm0)
27902:      __(cmpq %imm0,%imm1)
2791        __(jne 1b)             
2792        __(repret)
27939:      __(movq rcontext(tcr.foreign_sp),%imm1)
2794        __(subq $dnode_size,rcontext(tcr.foreign_sp))
2795        __(movq rcontext(tcr.foreign_sp),%imm0)
2796        __(movq %imm1,(%imm0))
2797        __(movq %rbp,csp_frame.save_rbp(%imm0))
2798        __(movq %arg_z,%arg_y)
2799        __(movl $t_value,%arg_z_l) /* clear-p arg to %new-gcable-ptr */
2800        __(set_nargs(2))
2801        __(movq $nrs.new_gcable_ptr,%fname)
2802        __(jump_fname())
2803_endsubp(makestackblock0)
2804
2805_spentry(makestacklist)
2806        __(movq $((1<<63)|fixnummask),%imm0)
2807        __(testq %imm0,%arg_y)
2808        __(jne 9f)
2809        __(movq %arg_y,%imm0)
2810        __(addq %imm0,%imm0)
2811        __(rcmpq(%imm0,$tstack_alloc_limit))
2812        __(movl $nil_value,%temp1_l)
2813        __(jae 2f)
2814        __(addq $tsp_frame.fixed_overhead,%imm0)
2815        __(TSP_Alloc_Var(%imm0,%temp0))
2816        __(addq $fulltag_cons,%temp0)
2817        __(jmp 1f)
28180:      __(_rplaca(%temp0,%arg_z))
2819        __(_rplacd(%temp0,%temp1))
2820        __(movq %temp0,%temp1)
2821        __(addq $cons.size,%temp0)
28221:      __(subq $fixnumone,%arg_y)
2823        __(jge 0b)
2824        __(movq %temp1,%arg_z)
2825        __(ret)
28262:      __(TSP_Alloc_Fixed(0,%imm0))
2827        __(jmp 4f)
28283:      __(Cons(%arg_z,%temp1,%temp1))
28294:      __(subq $fixnumone,%arg_y)                             
2830        __(jge 3b)
2831        __(movq %temp1,%arg_z)
2832        __(ret)
28339:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
2834_endsubp(makestacklist)
2835
2836/* subtype (boxed) vpushed before initial values. (Had better be a   */
2837/* node header subtag.) Nargs set to count of things vpushed.     */
2838_spentry(stkgvector)
2839        __(lea -fixnum_one(%nargs_q),%imm0)
2840        __(lea (%rsp,%imm0),%arg_x)
2841        __(movq %imm0,%arg_y)
2842        __(shlq $num_subtag_bits-fixnumshift,%imm0)
2843        __(movq (%arg_x), %imm1)
2844        __(shrq $fixnumshift,%imm1)
2845        __(orq %imm1,%imm0)     /* imm0 = header, %arg_y = unaligned size   */
2846        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm1))
2847        __(TSP_Alloc_Var(%imm1,%arg_z))
2848        __(movq %imm0,(%arg_z))
2849        __(addq $fulltag_misc,%arg_z)
2850        __(lea -node_size(%nargs_q),%imm0)
2851        __(jmp 2f)
28521:      __(pop misc_data_offset(%arg_z,%imm0))
28532:      __(subq $node_size,%imm0)
2854        __(jge 1b)
2855        __(addq $node_size,%rsp)
2856        __(jmp *%ra0)   
2857_endsubp(stkgvector)
2858
2859_spentry(misc_alloc)
2860        __(movq $~(((1<<56)-1)<<fixnumshift),%imm0)
2861        __(testq %imm0,%arg_y)
2862        __(jne local_label(misc_alloc_not_u56))
2863        __(unbox_fixnum(%arg_z,%imm0))
2864        __(movq %arg_y,%temp0)
2865        __(shl $num_subtag_bits-fixnumshift,%temp0)
2866        __(orq %temp0,%imm0)            /* %imm0 now = header   */
2867        __(movb $fulltagmask,%imm1_b)
2868        __(andb %imm0_b,%imm1_b)
2869        __(cmpb $fulltag_nodeheader_0,%imm1_b)
2870        __(je local_label(misc_alloc_64))
2871        __(cmpb $fulltag_nodeheader_1,%imm1_b)
2872        __(je local_label(misc_alloc_64))
2873        __(cmpb $ivector_class_64_bit,%imm1_b)
2874        __(jz local_label(misc_alloc_64))
2875        __(cmpb $ivector_class_32_bit,%imm1_b)
2876        __(jz local_label(misc_alloc_32))
2877        __(unbox_fixnum(%arg_y,%imm1))
2878        /* ivector_class_other_bit: 16, 8, or 1 ...   */
2879        __(cmpb $subtag_bit_vector,%imm0_b)
2880        __(jne local_label(misc_alloc_8))
2881        __(addq $7,%imm1)
2882        __(shrq $3,%imm1)
2883        __(jmp local_label(misc_alloc_alloc_vector))
2884local_label(misc_alloc_8):     
2885        __(cmpb $subtag_simple_base_string,%imm0_b)
2886        __(jae local_label(misc_alloc_alloc_vector))
2887local_label(misc_alloc_16):     
2888        __(shlq %imm1)
2889        __(jmp local_label(misc_alloc_alloc_vector))
2890local_label(misc_alloc_32):
2891        /* 32-bit ivector   */
2892        __(unbox_fixnum(%arg_y,%imm1))
2893        __(shlq $2,%imm1)
2894        __(jmp local_label(misc_alloc_alloc_vector))
2895local_label(misc_alloc_64):
2896        /* 64-bit ivector or gvector      */
2897        __(movq %arg_y,%imm1)
2898local_label(misc_alloc_alloc_vector):   
2899        __(dnode_align(%imm1,node_size,%imm1))
2900        __(ref_global(tenured_area,%arg_x))
2901        __(cmpq area.low(%arg_x),%imm1)
2902        __(ja local_label(misc_alloc_large))
2903        __(Misc_Alloc(%arg_z))
2904        __(ret)
2905local_label(misc_alloc_not_u56):
2906        __(movl $XARRLIMIT,%arg_x_l)
2907        __(set_nargs(3))
2908        __(jmp _SPksignalerr)
2909local_label(misc_alloc_large):
2910        /* If we tried to subtract %imm1 from tcr.allocptr, it
2911           might become negative ; we treat addresses as being unsigned,
2912           so that negative value would look like a very large unsigned
2913           value and we'd think that the allocation succeeded.
2914           If we reach this point, we're trying to allocate something
2915           very large indeed.  Depending on the platform, that's anywhere
2916           from hundreds of GB to hundreds of TB.  Someday, it might be
2917           worth trying that (using a special "large allocation" UUO);
2918           for now, it's probably safe to just report that a memory
2919           allocation attempt failed.
2920        */
2921        __(movq $XMEMFULL,%arg_z)
2922        __(set_nargs(1))
2923        __(jmp _SPksignalerr)
2924_endsubp(misc_alloc)
2925
2926
2927_startfn(C(destbind1))
2928        /* Save entry %rsp in case of error   */
2929        __(movd %rsp,%mm0)
2930        /* Extract required arg count.   */
2931        __(movzbl %nargs_b,%imm0_l)
2932        __(testl %imm0_l,%imm0_l)
2933        __(je local_label(opt))         /* skip if no required args   */
2934local_label(req_loop): 
2935        __(compare_reg_to_nil(%arg_reg))
2936        __(je local_label(toofew))
2937        __(extract_lisptag(%arg_reg,%imm1))
2938        __(cmpb $tag_list,%imm1_b)
2939        __(jne local_label(badlist))
2940        __(subb $1,%imm0_b)
2941        __(pushq cons.car(%arg_reg))
2942        __(_cdr(%arg_reg,%arg_reg))
2943        __(jne local_label(req_loop))
2944local_label(opt):       
2945        __(movw %nargs_w,%imm0_w)
2946        __(shrw $8,%imm0_w)
2947        __(je local_label(rest_keys))
2948        __(btl $initopt_bit,%nargs)
2949        __(jc local_label(opt_supp))
2950        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2951local_label(simple_opt_loop):
2952        __(compare_reg_to_nil(%arg_reg))
2953        __(je local_label(default_simple_opt))
2954        __(extract_lisptag(%arg_reg,%imm1))
2955        __(cmpb $tag_list,%imm1_b)
2956        __(jne local_label(badlist))
2957        __(subb $1,%imm0_b)
2958        __(pushq cons.car(%arg_reg))
2959        __(_cdr(%arg_reg,%arg_reg))
2960        __(jne local_label(simple_opt_loop))
2961        __(jmp local_label(rest_keys))
2962local_label(default_simple_opt):
2963        __(subb $1,%imm0_b)
2964        __(pushq $nil_value)
2965        __(jne local_label(default_simple_opt))
2966        __(jmp local_label(rest_keys))
2967local_label(opt_supp):
2968        __(extract_lisptag(%arg_reg,%imm1))
2969        __(compare_reg_to_nil(%arg_reg))
2970        __(je local_label(default_hard_opt))
2971        __(cmpb $tag_list,%imm1_b)
2972        __(jne local_label(badlist))
2973        __(subb $1,%imm0_b)
2974        __(pushq cons.car(%arg_reg))
2975        __(_cdr(%arg_reg,%arg_reg))
2976        __(push $t_value)
2977        __(jne local_label(opt_supp))
2978        __(jmp local_label(rest_keys))
2979local_label(default_hard_opt):
2980        __(subb $1,%imm0_b)
2981        __(push $nil_value)
2982        __(push $nil_value)
2983        __(jne local_label(default_hard_opt))   
2984local_label(rest_keys):
2985        __(btl $restp_bit,%nargs)
2986        __(jc local_label(have_rest))
2987        __(btl $keyp_bit,%nargs)
2988        __(jc local_label(have_keys))
2989        __(compare_reg_to_nil(%arg_reg))
2990        __(jne local_label(toomany))
2991        __(jmp *%ra0)
2992local_label(have_rest):
2993        __(pushq %arg_reg)
2994        __(btl $keyp_bit,%nargs)
2995        __(jc local_label(have_keys))
2996        __(jmp *%ra0)           
2997        /* Ensure that arg_reg contains a proper,even-length list.  */
2998        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2999local_label(have_keys):
3000        __(movw $256,%imm0_w)
3001        __(movq %arg_reg,%arg_y)
3002local_label(count_keys_loop):   
3003        __(compare_reg_to_nil(%arg_y))
3004        __(je local_label(counted_keys))
3005        __(subw $1,%imm0_w)
3006        __(jl local_label(toomany))
3007        __(extract_lisptag(%arg_y,%imm1))
3008        __(cmpb $tag_list,%imm1_b)
3009        __(jne local_label(badlist))
3010        __(_cdr(%arg_y,%arg_y))
3011        __(extract_fulltag(%arg_y,%imm1))
3012        __(cmpb $fulltag_cons,%imm1_b)
3013        __(jne local_label(badlist))
3014        __(_cdr(%arg_y,%arg_y))
3015        __(jmp local_label(count_keys_loop))
3016local_label(counted_keys):             
3017        /* We've got a proper, even-length list of key/value pairs in  */
3018        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
3019        /* of NILs on the vstack.   */
3020       
3021        __(movl %nargs,%imm1_l)
3022        __(shrl $16,%imm1_l)
3023        __(movzbl %imm1_b,%imm0_l)
3024        __(movq %rsp,%arg_y)
3025        __(jmp local_label(push_pair_test))     
3026local_label(push_pair_loop):
3027        __(push $nil_value)
3028        __(push $nil_value)
3029local_label(push_pair_test):   
3030        __(subb $1,%imm1_b)
3031        __(jge local_label(push_pair_loop))
3032        /* Push the %saveN registers, so that we can use them in this loop   */
3033        /* Also, borrow %arg_z */
3034        __(push %save0)
3035        __(push %save1)
3036        __(push %save2)
3037        __(push %arg_z)
3038        /* save0 points to the 0th value/supplied-p pair   */
3039        __(movq %arg_y,%save0)
3040        /* save1 is the length of the keyword vector   */
3041        __(vector_length(%arg_x,%save1))
3042        /* save2 is the current keyword   */
3043        /* arg_z is the value of the current keyword   */
3044        __(xorl %imm0_l,%imm0_l)        /* count unknown keywords seen   */
3045local_label(match_keys_loop):
3046        __(compare_reg_to_nil(%arg_reg))
3047        __(je local_label(matched_keys))
3048        __(_car(%arg_reg,%save2))
3049        __(_cdr(%arg_reg,%arg_reg))
3050        __(_car(%arg_reg,%arg_z))
3051        __(_cdr(%arg_reg,%arg_reg))
3052        __(xorl %arg_y_l,%arg_y_l)
3053        __(jmp local_label(match_test))
3054local_label(match_loop):
3055        __(cmpq misc_data_offset(%arg_x,%arg_y),%save2)
3056        __(je local_label(matched))
3057        __(addq $node_size,%arg_y)
3058local_label(match_test):
3059        __(cmpq %arg_y,%save1)
3060        __(jne local_label(match_loop))
3061        /* No match.  Note unknown keyword, check for :allow-other-keys   */
3062        __(addl $1,%imm0_l)
3063        __(cmpq $nrs.kallowotherkeys,%save2)
3064        __(jne local_label(match_keys_loop))
3065        __(subl $1,%imm0_l)
3066        __(btsl $seen_aok_bit,%nargs)
3067        __(jc local_label(match_keys_loop))
3068        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
3069        __(compare_reg_to_nil(%arg_z))
3070        __(je local_label(match_keys_loop))
3071        __(btsl $aok_bit,%nargs)
3072        __(jmp local_label(match_keys_loop))
3073        /* Got a match.  Worry about :allow-other-keys here, too.   */
3074local_label(matched):
3075        __(negq %arg_y)
3076        __(cmpb $fulltag_nil,-node_size*2(%save0,%arg_y,2))
3077        __(jne local_label(match_keys_loop))
3078        __(movq %arg_z,-node_size(%save0,%arg_y,2))
3079        __(movl $t_value,-node_size*2(%save0,%arg_y,2))
3080        __(cmpq $nrs.kallowotherkeys,%save2)
3081        __(jne local_label(match_keys_loop))
3082        __(btsl $seen_aok_bit,%nargs)
3083        __(jnc local_label(match_keys_loop))
3084        __(compare_reg_to_nil(%arg_z))
3085        __(je local_label(match_keys_loop))
3086        __(btsl $aok_bit,%nargs)
3087        __(jmp local_label(match_keys_loop))
3088local_label(matched_keys):             
3089        __(pop %arg_z)
3090        __(pop %save2)
3091        __(pop %save1)
3092        __(pop %save0)
3093        __(testl %imm0_l,%imm0_l)
3094        __(je local_label(keys_ok))
3095        __(btl $aok_bit,%nargs)
3096        __(jnc local_label(badkeys))
3097local_label(keys_ok):   
3098        __(jmp *%ra0)
3099        /* Some unrecognized keywords.  Complain generically about   */
3100        /* invalid keywords.   */
3101local_label(badkeys):
3102        __(movq $XBADKEYS,%arg_y)
3103        __(jmp local_label(destructure_error))
3104local_label(toomany):
3105        __(movq $XCALLTOOMANY,%arg_y)
3106        __(jmp local_label(destructure_error))
3107local_label(toofew):
3108        __(movq $XCALLTOOFEW,%arg_y)
3109        __(jmp local_label(destructure_error))
3110local_label(badlist):
3111        __(movq $XCALLNOMATCH,%arg_y)
3112        /* jmp local_label(destructure_error)   */
3113local_label(destructure_error):
3114        __(movd %mm0,%rsp)              /* undo everything done to the stack   */
3115        __(movq %whole_reg,%arg_z)
3116        __(set_nargs(2))
3117        __(push %ra0)
3118        __(jmp _SPksignalerr)
3119_endfn(C(destbind1))   
3120
3121_spentry(macro_bind)
3122        __(movq %arg_reg,%whole_reg)
3123        __(extract_lisptag(%arg_reg,%imm0))
3124        __(cmpb $tag_list,%imm0_b)
3125        __(jne 1f)
3126        __(_cdr(%arg_reg,%arg_reg))
3127        __(jmp C(destbind1))
31281:      __(movq $XCALLNOMATCH,%arg_y)
3129        __(movq %whole_reg,%arg_z)
3130        __(set_nargs(2))
3131        __(push %ra0)       
3132        __(jmp _SPksignalerr)
3133_endsubp(macro_bind)
3134
3135_spentry(destructuring_bind)
3136        __(movq %arg_reg,%whole_reg)
3137        __(jmp C(destbind1))
3138_endsubp(destructuring_bind)
3139
3140_spentry(destructuring_bind_inner)
3141        __(movq %arg_z,%whole_reg)
3142        __(jmp C(destbind1))
3143_endsubp(destructuring_bind_inner)
3144
3145       
3146
3147
3148_spentry(vpopargregs)
3149_endsubp(vpopargregs)
3150
3151/* If arg_z is an integer, return in imm0 something whose sign  */
3152/* is the same as arg_z's.  If not an integer, error.   */
3153_spentry(integer_sign)
3154        __(testb $tagmask,%arg_z_b)
3155        __(movq %arg_z,%imm0)
3156        __(je 8f)
3157        __(extract_typecode(%arg_z,%imm0))
3158        __(cmpb $subtag_bignum,%imm0_b)
3159        __(jne 9f)
3160        __(getvheader(%arg_z,%imm0))
3161        __(shr $num_subtag_bits,%imm0)
3162        __(movslq misc_data_offset-4(%arg_z,%imm0,4),%imm0)
31638:      __(repret)
31649:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3165_endsubp(integer_sign)
3166
3167/* "slide" nargs worth of values up the stack.  IMM0 contains   */
3168/* the difference between the current RSP and the target.   */
3169_spentry(mvslide)
3170        __(movl %nargs,%imm1_l)
3171        __(lea (%rsp,%nargs_q),%temp0)
3172        __(testq %imm1,%imm1)
3173        __(lea (%temp0,%imm0),%imm0)
3174        __(je 2f)
31751:     
3176        __(subq $node_size,%temp0)
3177        __(movq (%temp0),%temp1)
3178        __(subq $node_size,%imm0)
3179        __(movq %temp1,(%imm0))
3180        __(subq $node_size,%imm1)
3181        __(jne 1b)
31822:      __(movq %imm0,%rsp)
3183        __(jmp *%ra0)   
3184_endsubp(mvslide)
3185
3186_spentry(save_values)
3187        __(movq rcontext(tcr.save_tsp),%imm1)
3188/* common exit: nargs = values in this set, imm1 = ptr to tsp before call to save_values   */
3189local_label(save_values_to_tsp):
3190        __(movq rcontext(tcr.save_tsp),%arg_x)
3191        __(dnode_align(%nargs_q,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3192        __(TSP_Alloc_Var(%imm0,%arg_z))
3193        __(movq rcontext(tcr.save_tsp),%imm0)
3194        __(movq %imm1,(%imm0))
3195        __(movq %nargs_q,(%arg_z))
3196        __(movq %arg_x,node_size(%arg_z))
3197        __(leaq 2*node_size(%arg_z,%nargs_q),%arg_y)
3198        __(leaq (%rsp,%nargs_q),%imm0)
3199        __(cmpq %imm0,%rsp)
3200        __(jmp 2f)
32011:      __(subq $node_size,%imm0)
3202        __(movq (%imm0),%arg_z)
3203        __(subq $node_size,%arg_y)
3204        __(cmpq %imm0,%rsp)
3205        __(movq %arg_z,(%arg_y))
32062:      __(jne 1b)
3207        __(add %nargs_q,%rsp)
3208        __(jmp *%ra0)                   
3209_endsubp(save_values)
3210
3211/* Add the multiple values that are on top of the vstack to the set  */
3212/* saved in the top tsp frame, popping them off of the vstack in the  */
3213/* process.  It is an error (a bad one) if the TSP contains something  */
3214/* other than a previously saved set of multiple-values.  */
3215/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3216/* each add_values call adds another linked element to the list of  */
3217/* values. This makes recover_values harder.   */
3218_spentry(add_values)
3219        __(testl %nargs,%nargs)
3220        __(movq rcontext(tcr.save_tsp),%imm1)
3221        __(movq (%imm1),%imm1)
3222        __(jne local_label(save_values_to_tsp))
3223        __(jmp *%ra0)
3224_endsubp(add_values)
3225
3226/* push the values in the value set atop the sp, incrementing nargs.  */
3227/* Discard the tsp frame; leave values atop the sp.   */
3228       
3229_spentry(recover_values)
3230        /* First, walk the segments reversing the pointer to previous  */
3231        /* segment pointers Can tell the end because that previous  */
3232        /* segment pointer is the prev tsp pointer   */
3233        __(movq rcontext(tcr.save_tsp),%temp1)
3234        __(movq %temp1,%arg_x)  /* current segment   */
3235        __(movq %temp1,%arg_y)  /* last segment   */
3236        __(movq tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3237local_label(walkloop):
3238        __(movq tsp_frame.fixed_overhead+node_size(%arg_x),%temp0)
3239        __(cmpq %temp0,%arg_z)  /* last segment ?   */
3240        __(movq %arg_y,tsp_frame.fixed_overhead+node_size(%arg_x))
3241        __(movq %arg_x,%arg_y)  /* last segment <- current segment   */
3242        __(movq %temp0,%arg_x)  /* current segment <- next segment   */
3243        __(jne local_label(walkloop))
3244
3245        /* the final segment pointer is now in %arg_y  */
3246        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3247local_label(pushloop):
3248        __(movq tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3249        __(testq %imm0,%imm0)
3250        __(leaq tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3251        __(leaq (%nargs_q,%imm0),%nargs_q)
3252        __(jmp 2f)
32531:      __(pushq -node_size(%temp0))
3254        __(subq $node_size,%temp0)
3255        __(subq $fixnum_one,%imm0)
32562:      __(jne 1b)
3257        __(cmpq %arg_y,%temp1)
3258        __(movq tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3259        __(jne local_label(pushloop))
3260        __(movq (%temp1),%temp1)
3261        __(movq %temp1,rcontext(tcr.save_tsp))
3262        __(movq %temp1,rcontext(tcr.next_tsp))       
3263        __(jmp *%ra0)           
3264_endsubp(recover_values)
3265
3266/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3267/* frame if any values (which will be used as outgoing arguments) will  */
3268/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3269/* that no other arguments have been pushed) on entry.   */
3270               
3271_spentry(recover_values_for_mvcall)
3272        /* First, walk the segments reversing the pointer to previous  */
3273        /* segment pointers Can tell the end because that previous  */
3274        /* segment pointer is the prev tsp pointer   */
3275        __(xorl %nargs,%nargs)
3276        __(movq rcontext(tcr.save_tsp),%temp1)
3277        __(movq %temp1,%arg_x)  /* current segment   */
3278        __(movq %temp1,%arg_y)  /* last segment   */
3279        __(movq tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3280local_label(walkloop_mvcall):
3281        __(movq tsp_frame.fixed_overhead+node_size(%arg_x),%temp0)
3282        __(addq tsp_frame.data_offset(%arg_x),%nargs_q)
3283        __(cmpq %temp0,%arg_z)  /* last segment ?   */
3284        __(movq %arg_y,tsp_frame.fixed_overhead+node_size(%arg_x))
3285        __(movq %arg_x,%arg_y)  /* last segment <- current segment   */
3286        __(movq %temp0,%arg_x)  /* current segment <- next segment   */
3287        __(jne local_label(walkloop_mvcall))
3288
3289        __(cmpl $nargregs*node_size,%nargs)
3290        __(jbe local_label(pushloop_mvcall))
3291        __(push $reserved_frame_marker)
3292        __(push $reserved_frame_marker)
3293
3294        /* the final segment pointer is now in %arg_y  */
3295        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3296local_label(pushloop_mvcall):
3297        __(movq tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3298        __(testq %imm0,%imm0)
3299        __(leaq tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3300        __(jmp 2f)
33011:      __(pushq -node_size(%temp0))
3302        __(subq $node_size,%temp0)
3303        __(subq $fixnum_one,%imm0)
33042:      __(jne 1b)
3305        __(cmpq %arg_y,%temp1)
3306        __(movq tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3307        __(jne local_label(pushloop_mvcall))
3308        __(movq (%temp1),%temp1)
3309        __(movq %temp1,rcontext(tcr.save_tsp))
3310        __(movq %temp1,rcontext(tcr.next_tsp))       
3311        __(jmp *%ra0)           
3312_endsubp(recover_values_for_mvcall)
3313                                       
3314_spentry(reset)
3315        __(hlt)
3316_endsubp(reset)
3317
3318
3319
3320_spentry(misc_alloc_init)
3321        __(push %rbp)
3322        __(movq %rsp,%rbp)
3323        __(push %arg_z)
3324        __(movq %arg_y,%arg_z)
3325        __(movq %arg_x,%arg_y)
3326        __(lea local_label(misc_alloc_init_back)(%rip),%ra0)
3327        __(push %ra0)
3328        __(jmp _SPmisc_alloc)
3329__(tra(local_label(misc_alloc_init_back)))
3330        __(pop %arg_y)
3331        __(leave)
3332        __(movq $nrs.init_misc,%fname)
3333        __(set_nargs(2))
3334        __(jump_fname())       
3335_endsubp(misc_alloc_init)
3336
3337_spentry(stack_misc_alloc_init)
3338        __(push %rbp)
3339        __(movq %rsp,%rbp)
3340        __(push %arg_z)
3341        __(movq %arg_y,%arg_z)
3342        __(movq %arg_x,%arg_y)
3343        __(lea local_label(stack_misc_alloc_init_back)(%rip),%ra0)
3344        __(push %ra0)
3345        __(jmp _SPstack_misc_alloc)
3346__(tra(local_label(stack_misc_alloc_init_back)))
3347        __(pop %arg_y)
3348        __(leave)
3349        __(movq $nrs.init_misc,%fname)
3350        __(set_nargs(2))
3351        __(jump_fname())       
3352_endsubp(stack_misc_alloc_init)
3353
3354
3355
3356        .globl C(popj)
3357_spentry(popj)
3358C(popj):
3359        __(leave)
3360        __(ret)
3361_endsubp(popj)
3362
3363
3364
3365_spentry(getu64)
3366        __(movq $~(target_most_positive_fixnum << fixnumshift),%imm0)
3367        __(testq %arg_z,%imm0)
3368        __(movq %arg_z,%imm0)
3369        __(jne 1f)
3370        __(sarq $fixnumshift,%imm0)
3371        __(ret)
33721:      __(andb $tagmask,%imm0_b)
3373        __(cmpb $tag_misc,%imm0_b)
3374        __(jne 9f)
3375        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3376        __(cmpb $subtag_bignum,%imm0_b)
3377        __(jne 9f)
3378        __(movq misc_header_offset(%arg_z),%imm0)
3379        __(cmpq $three_digit_bignum_header,%imm0)
3380        __(je 3f)
3381        __(cmpq $two_digit_bignum_header,%imm0)
3382        __(jne 9f)
3383        __(movq misc_data_offset(%arg_z),%imm0)
3384        __(testq %imm0,%imm0)
3385        __(js 9f)
3386        __(repret)
33873:      __(movq misc_data_offset(%arg_z),%imm0)
3388        __(cmpl $0,misc_data_offset+8(%arg_z))
3389        __(jne 9f)
3390        __(repret)
33919:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3392_endsubp(getu64)
3393
3394_spentry(gets64)
3395        __(movq %arg_z,%imm0)
3396        __(sarq $fixnumshift,%imm0)
3397        __(testb $fixnummask,%arg_z_b)
3398        __(je 8f)
33991:      __(movb %arg_z_b,%imm0_b)
3400        __(andb $tagmask,%imm0_b)
3401        __(cmpb $tag_misc,%imm0_b)
3402        __(jne 9f)
3403        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3404        __(cmpb $subtag_bignum,%imm0_b)
3405        __(jne 9f)
3406        __(movq misc_header_offset(%arg_z),%imm0)
3407        __(cmpq $two_digit_bignum_header,%imm0)
3408        __(movq misc_data_offset(%arg_z),%imm0)
3409        __(jne 9f)
34108:      __(repret)
34119:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_s64))
3412_endsubp(gets64)
3413
3414_spentry(makeu64)
3415        __(movq %imm0,%imm1)
3416        __(shlq $fixnumshift+1,%imm1)
3417        __(movq %imm1,%arg_z)   /* Tagged as a fixnum, 2x    */
3418        __(shrq $fixnumshift+1,%imm1)
3419        __(shrq %arg_z)
3420        __(cmpq %imm0,%imm1)
3421        __(je 9f)
3422        __(testq %imm0,%imm0)
3423        __(movd %imm0,%mm0)
3424        __(js 3f)
3425        /* Make a 2-digit bignum.   */
3426        __(movl $two_digit_bignum_header,%imm0_l)
3427        __(movl $aligned_bignum_size(2),%imm1_l)
3428        __(Misc_Alloc(%arg_z))
3429        __(movq %mm0,misc_data_offset(%arg_z))
3430        __(ret)
34313:      __(movl $three_digit_bignum_header,%imm0_l)
3432        __(movl $aligned_bignum_size(3),%imm1_l)
3433        __(Misc_Alloc(%arg_z))
3434        __(movq %mm0,misc_data_offset(%arg_z))
34359:      __(repret)
3436_endsubp(makeu64)
3437
3438/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly  */
3439/* unbound_marker), arg_y = symbol   */
3440_spentry(specref)
3441        __(movq symbol.binding_index(%arg_z),%imm0)
3442        __(xorl %imm2_l,%imm2_l)
3443        __(cmp rcontext(tcr.tlb_limit),%imm0)
3444        __(movq rcontext(tcr.tlb_pointer),%imm1)
3445        __(movq %arg_z,%arg_y)
3446        __(cmovael %imm2_l,%imm0_l)
3447        __(movq (%imm1,%imm0),%arg_z)
3448        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3449        __(cmoveq symbol.vcell(%arg_y),%arg_z)
3450        __(ret)
3451_endsubp(specref)
3452
3453/* arg_y = special symbol, arg_z = new value.           */
3454_spentry(specset)
3455        __(movq symbol.binding_index(%arg_y),%imm0)
3456        __(cmp rcontext(tcr.tlb_limit),%imm0)
3457        __(movq rcontext(tcr.tlb_pointer),%imm1)
3458        __(jae 1f)
3459        __(movq (%imm1,%imm0),%arg_x)
3460        __(cmpb $no_thread_local_binding_marker,%arg_x_b)
3461        __(je 1f)
3462        __(movq %arg_z,(%imm1,%imm0))
3463        __(ret)
34641:      __(lea fulltag_misc-fulltag_symbol(%arg_y),%arg_x)
3465        __(movq $1<<fixnumshift,%arg_y)
3466        __(jmp _SPgvset)
3467_endsubp(specset)
3468
3469_spentry(specrefcheck)
3470        __(movq symbol.binding_index(%arg_z),%imm0)
3471        __(xorl %imm2_l,%imm2_l)
3472        __(cmp rcontext(tcr.tlb_limit),%imm0)
3473        __(movq rcontext(tcr.tlb_pointer),%imm1)
3474        __(movq %arg_z,%arg_y)
3475        __(cmovaeq %imm2,%imm0)
3476        __(movq (%imm1,%imm0),%arg_z)
3477        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3478        __(cmoveq symbol.vcell(%arg_y),%arg_z)
3479        __(cmpb $unbound_marker,%arg_z_b)
3480        __(je 9f)
3481        __(repret)
34829:      __(uuo_error_reg_unbound(Rarg_y))
3483_endsubp(specrefcheck)
3484
3485_spentry(restoreintlevel)
3486_endsubp(restoreintlevel)
3487
3488_spentry(makes32)
3489        __(hlt)
3490_endsubp(makes32)
3491
3492_spentry(makeu32)
3493        __(hlt)
3494_endsubp(makeu32)
3495
3496_spentry(gets32)
3497        __(hlt)
3498_endsubp(gets32)
3499
3500_spentry(getu32)
3501        __(hlt)
3502_endsubp(getu32)
3503
3504
3505_spentry(mvpasssym)
3506_endsubp(mvpasssym)
3507
3508
3509_spentry(unbind)
3510        __(movq rcontext(tcr.db_link),%imm1)
3511        __(movq rcontext(tcr.tlb_pointer),%arg_x)
3512        __(movq binding.sym(%imm1),%temp1)
3513        __(movq binding.val(%imm1),%arg_y)
3514        __(movq binding.link(%imm1),%imm1)
3515        __(movq %arg_y,(%arg_x,%temp1))
3516        __(movq %imm1,rcontext(tcr.db_link))
3517        __(ret)
3518_endsubp(unbind)
3519
3520_spentry(unbind_n)
3521        __(movq rcontext(tcr.db_link),%imm1)
3522        __(movq rcontext(tcr.tlb_pointer),%arg_x)
35231:             
3524        __(movq binding.sym(%imm1),%temp1)
3525        __(movq binding.val(%imm1),%arg_y)
3526        __(movq binding.link(%imm1),%imm1)
3527        __(movq %arg_y,(%arg_x,%temp1))
3528        __(subq $1,%imm0)
3529        __(jne 1b)
3530        __(movq %imm1,rcontext(tcr.db_link))
3531        __(ret)
3532_endsubp(unbind_n)
3533
3534_spentry(unbind_to)
3535        __(movq rcontext(tcr.db_link),%imm1)
3536        __(movq rcontext(tcr.tlb_pointer),%arg_x)
35371:             
3538        __(movq binding.sym(%imm1),%temp1)
3539        __(movq binding.val(%imm1),%arg_y)
3540        __(movq binding.link(%imm1),%imm1)
3541        __(movq %arg_y,(%arg_x,%temp1))
3542        __(cmpq %imm1,%imm0)
3543        __(jne 1b)
3544        __(movq %imm1,rcontext(tcr.db_link))
3545        __(ret)
3546_endsubp(unbind_to)
3547
3548
3549/* Bind CCL::*INTERRUPT-LEVEL* to 0.  If its value had been negative, check   */
3550/* for pending interrupts after doing so.   */
3551       
3552_spentry(bind_interrupt_level_0)
3553        __(movq rcontext(tcr.tlb_pointer),%temp1)
3554        __(cmpq $0,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3555        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3556        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3557        __(push rcontext(tcr.db_link))
3558        __(movq %rsp,rcontext(tcr.db_link))
3559        __(movq $0,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3560        __(js 1f)
35610:      __(jmp *%ra0)
3562        /* Interrupt level was negative; interrupt may be pending   */
35631:      __(check_pending_enabled_interrupt(2f))
35642:      __(jmp *%ra0)
3565_endsubp(bind_interrupt_level_0)
3566       
3567
3568/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3569/* of disabling interrupts.)   */
3570
3571_spentry(bind_interrupt_level_m1)
3572        __(movq rcontext(tcr.tlb_pointer),%temp1)
3573        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3574        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3575        __(push rcontext(tcr.db_link))
3576        __(movq %rsp,rcontext(tcr.db_link))
3577        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3578        __(jmp *%ra0)
3579_endsubp(bind_interrupt_level_m1)
3580
3581/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0,  */
3582/* do what _SPbind_interrupt_level_0 does   */
3583_spentry(bind_interrupt_level)
3584        __(testq %arg_z,%arg_z)
3585        __(movq rcontext(tcr.tlb_pointer),%temp1)
3586        __(jz _SPbind_interrupt_level_0)
3587        __(push INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3588        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3589        __(push rcontext(tcr.db_link))
3590        __(movq %rsp,rcontext(tcr.db_link))
3591        __(movq %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%temp1))
3592        __(jmp *%ra0)
3593_endsubp(bind_interrupt_level)
3594
3595/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to  */
3596/* non-negative, check for pending interrupts.    */
3597       
3598_spentry(unbind_interrupt_level)
3599        __(btq $TCR_FLAG_BIT_PENDING_SUSPEND,rcontext(tcr.flags))
3600        __(movq rcontext(tcr.db_link),%imm1)
3601        __(movq rcontext(tcr.tlb_pointer),%arg_x)
3602        __(movq INTERRUPT_LEVEL_BINDING_INDEX(%arg_x),%imm0)
3603        __(jc 5f)
36040:      __(testq %imm0,%imm0)
3605        __(movq binding.val(%imm1),%temp0)
3606        __(movq binding.link(%imm1),%imm1)
3607        __(movq %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
3608        __(movq %imm1,rcontext(tcr.db_link))
3609        __(js 3f)
36102:      __(repret)
36113:      __(testq %temp0,%temp0)
3612        __(js 2b)
3613        __(check_pending_enabled_interrupt(4f))
36144:      __(repret)
36155:       /* Missed a suspend request; force suspend now if we're restoring
3616          interrupt level to -1 or greater */
3617        __(cmpq $-2<<fixnumshift,%imm0)
3618        __(jne 0b)
3619        __(movq binding.val(%imm1),%temp0)
3620        __(cmpq %imm0,%temp0)
3621        __(je 0b)
3622        __(movq $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_x))
3623        __(suspend_now())
3624        __(jmp 0b)
3625_endsubp(unbind_interrupt_level)
3626
3627       
3628_spentry(progvrestore)
3629        __(movq rcontext(tcr.save_tsp),%imm0)
3630        __(movq tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3631        __(movq tsp_frame.data_offset(%imm0),%imm0)
3632        __(shrq $fixnumshift,%imm0)
3633        __(jne _SPunbind_n)
3634        __(repret)
3635_endsubp(progvrestore)
3636       
3637
3638/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3639/* inline.  Call out otherwise.   */
3640_spentry(builtin_plus)
3641        __(movb %arg_z_b,%imm0_b)
3642        __(orb %arg_y_b,%imm0_b)
3643        __(testb $fixnummask,%imm0_b)
3644        __(jne 1f)
3645        __(addq %arg_y,%arg_z)
3646        __(jo C(fix_one_bit_overflow))
3647        __(repret)
36481:      __(jump_builtin(_builtin_plus,2))
3649_endsubp(builtin_plus)
3650       
3651
3652/* %arg_z <- %arg_z - %arg_y.  Do the fixnum case - including overflow -  */
3653/*  inline.  Call out otherwise.   */
3654_spentry(builtin_minus)                 
3655        __(movb %arg_z_b,%imm0_b)
3656        __(orb %arg_y_b,%imm0_b)
3657        __(testb $fixnummask,%imm0_b)
3658        __(jne 1f)
3659        __(xchgq %arg_y,%arg_z)
3660        __(subq %arg_y,%arg_z)
3661        __(jo C(fix_one_bit_overflow))
3662        __(repret)
36631:      __(jump_builtin(_builtin_minus,2))
3664_endsubp(builtin_minus)
3665
3666/* %arg_z <- %arg_z * %arg_y.  Do the fixnum case - including overflow -  */
3667/* inline.  Call out otherwise.   */
3668_spentry(builtin_times)
3669        __(movb %arg_z_b,%imm0_b)
3670        __(orb %arg_y_b,%imm0_b)
3671        __(testb $fixnummask,%imm0_b)
3672        __(jne 2f)
3673        __(unbox_fixnum(%arg_z,%imm0))
3674        /* 128-bit fixnum result in %imm1:%imm0. Overflow set if %imm1  */
3675        /* is significant   */
3676        __(imul %arg_y)
3677        __(jo 1f)
3678        __(mov %imm0,%arg_z)
3679        __(ret)
36801:      __(unbox_fixnum(%arg_z,%imm0))
3681        __(unbox_fixnum(%arg_y,%imm1))
3682        __(imul %imm1)
3683        __(jmp C(makes128))
36842:      __(jump_builtin(_builtin_times,2))
3685_endsubp(builtin_times)
3686
3687_spentry(builtin_div)
3688        __(jump_builtin(_builtin_div,2))
3689
3690/* %arg_z <- (= %arg_y %arg_z).   */
3691_spentry(builtin_eq)
3692        __(movb %arg_z_b,%imm0_b)
3693        __(orb %arg_y_b,%imm0_b)
3694        __(testb $fixnummask,%imm0_b)
3695        __(jne 1f)
3696        __(rcmpq(%arg_z,%arg_y))
3697        __(condition_to_boolean(e,%imm0,%arg_z))
3698        __(ret)
36991:      __(jump_builtin(_builtin_eq,2))
3700_endsubp(builtin_eq)
3701       
3702/* %arg_z <- (/= %arg_y %arg_z).          */
3703_spentry(builtin_ne)
3704        __(movb %arg_z_b,%imm0_b)
3705        __(orb %arg_y_b,%imm0_b)
3706        __(testb $fixnummask,%imm0_b)
3707        __(jne 1f)
3708        __(rcmpq(%arg_z,%arg_y))
3709        __(condition_to_boolean(ne,%imm0,%arg_z))
3710        __(ret)
37111:      __(jump_builtin(_builtin_ne,2))
3712_endsubp(builtin_ne)
3713       
3714/* %arg_z <- (> %arg_y %arg_z).   */
3715_spentry(builtin_gt)
3716        __(movb %arg_z_b,%imm0_b)
3717        __(orb %arg_y_b,%imm0_b)
3718        __(testb $fixnummask,%imm0_b)
3719        __(jne 1f)
3720        __(rcmpq(%arg_y,%arg_z))
3721        __(condition_to_boolean(g,%imm0,%arg_z))
3722        __(ret)
37231:      __(jump_builtin(_builtin_gt,2))
3724_endsubp(builtin_gt)
3725
3726/* %arg_z <- (>= %arg_y %arg_z).          */
3727_spentry(builtin_ge)
3728        __(movb %arg_z_b,%imm0_b)
3729        __(orb %arg_y_b,%imm0_b)
3730        __(testb $fixnummask,%imm0_b)
3731        __(jne 1f)
3732        __(rcmpq(%arg_y,%arg_z))
3733        __(condition_to_boolean(ge,%imm0,%arg_z))
3734        __(ret)
37351:      __(jump_builtin(_builtin_ge,2))
3736_endsubp(builtin_ge)
3737       
3738/* %arg_z <- (< %arg_y %arg_z).   */
3739_spentry(builtin_lt)
3740        __(movb %arg_z_b,%imm0_b)
3741        __(orb %arg_y_b,%imm0_b)
3742        __(testb $fixnummask,%imm0_b)
3743        __(jne 1f)
3744        __(rcmpq(%arg_y,%arg_z))
3745        __(condition_to_boolean(l,%imm0,%arg_z))
3746        __(ret)
37471:      __(jump_builtin(_builtin_lt,2))
3748_endsubp(builtin_lt)
3749
3750/* %arg_z <- (<= %arg_y %arg_z).   */
3751_spentry(builtin_le)
3752        __(movb %arg_z_b,%imm0_b)
3753        __(orb %arg_y_b,%imm0_b)
3754        __(testb $fixnummask,%imm0_b)
3755        __(jne 1f)
3756        __(rcmpq(%arg_y,%arg_z))
3757        __(condition_to_boolean(le,%imm0,%arg_z))
3758        __(ret)
37591:      __(jump_builtin(_builtin_le,2))
3760_endsubp(builtin_le)
3761
3762_spentry(builtin_eql)
37630:      __(cmpq %arg_y,%arg_z)
3764        __(je 8f)
3765        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3766        /* and both have the same subtag   */
3767        __(extract_lisptag(%arg_y,%imm0))
3768        __(extract_lisptag(%arg_z,%imm1))
3769        __(cmpb $tag_misc,%imm0_b)
3770        __(jne 9f)
3771        __(cmpb %imm0_b,%imm1_b)
3772        __(jne 9f)
3773        __(extract_subtag(%arg_y,%imm0))
3774        __(extract_subtag(%arg_z,%imm1))
3775        __(cmpb %imm0_b,%imm1_b)
3776        __(jne 9f)
3777        __(cmpb $subtag_macptr,%imm0_b)
3778        __(je 1f)
3779        __(cmpb $subtag_double_float,%imm0_b)
3780        __(jne 2f)
37811:      __(movq misc_data_offset(%arg_y),%imm0)
3782        __(cmpq misc_data_offset(%arg_z),%imm0)
3783        __(movl $t_value,%arg_z_l)
3784        __(movl $nil_value,%imm0_l)
3785        __(cmovnel %imm0_l,%arg_z_l)
3786        __(ret)
37872:      __(cmpb $subtag_ratio,%imm0_b)
3788        __(je 3f)
3789        __(cmpb $subtag_complex,%imm0_b)
3790        __(jne 5f)
37913:      __(pushq %rbp)
3792        __(movq %rsp,%rsp)
3793        __(pushq ratio.denom(%arg_y))
3794        __(pushq ratio.denom(%arg_z))
3795        __(movq ratio.numer(%arg_y),%arg_y)
3796        __(movq ratio.numer(%arg_z),%arg_z)
3797        __(lea 4f(%rip),%ra0)
3798        __(pushq %ra0)
3799        __(jmp 0b)
3800__(tra(4))
3801        __(compare_reg_to_nil(%arg_z))
3802        __(popq %arg_z)
3803        __(popq %arg_y)
3804        __(popq %rbp)
3805        __(je 9f)
3806        __(jmp 0b)
38075:      __(cmpb $subtag_bignum,%imm0_b)
3808        __(jne 9f)
3809        __(getvheader(%arg_y,%imm2))
3810        __(cmpq misc_header_offset(%arg_z),%imm2)
3811        __(jne 9f)
3812        __(shrq $num_subtag_bits,%imm2)
3813        __(xorl %imm1_l,%imm1_l)
38146:      __(movl misc_data_offset(%arg_y,%imm1,4),%imm0_l)
3815        __(cmpl misc_data_offset(%arg_z,%imm1,4),%imm0_l)
3816        __(jne 9f)
3817        __(addq $1,%imm1)
3818        __(cmpq %imm1,%imm2)
3819        __(jne 6b)
38208:      __(movl $t_value,%arg_z_l)
3821        __(ret)
38229:      __(movl $nil_value,%arg_z_l)
3823        __(ret) 
3824_endsubp(builtin_eql)
3825
3826_spentry(builtin_length)
3827        __(extract_lisptag(%arg_z,%imm0))
3828        __(cmpb $tag_list,%imm0_b)
3829        __(jz 2f)
3830        __(cmpb $tag_misc,%imm0_b)
3831        __(jnz 8f)
3832        __(extract_subtag(%arg_z,%imm0))
3833        __(rcmpb(%imm0_b,$min_vector_subtag))
3834        __(jb 8f)
3835        __(je 1f)
3836        /* (simple-array * (*))   */
3837        __(movq %arg_z,%arg_y)
3838        __(vector_length(%arg_y,%arg_z))
3839        __(ret)
38401:      /* vector header   */
3841        __(movq vectorH.logsize(%arg_z),%arg_z)
3842        __(ret)
38432:      /* list.  Maybe null, maybe dotted or circular.   */
3844        __(movq $-fixnumone,%imm2)
3845        __(movq %arg_z,%temp0)  /* fast pointer   */
3846        __(movq %arg_z,%temp1)  /* slow pointer   */
38473:      __(extract_lisptag(%temp0,%imm0))       
3848        __(compare_reg_to_nil(%temp0))
3849        __(leaq fixnumone(%imm2),%imm2)
3850        __(je 9f)
3851        __(cmpb $tag_list,%imm0_b)
3852        __(jne 8f)
3853        __(extract_lisptag(%temp1,%imm1))
3854        __(testb $fixnumone,%imm2_b)
3855        __(_cdr(%temp0,%temp0))
3856        __(je 3b)
3857        __(cmpb $tag_list,%imm1_b)
3858        __(jne 8f)
3859        __(_cdr(%temp1,%temp1))
3860        __(cmpq %temp0,%temp1)
3861        __(jne 3b)
38628:     
3863        __(jump_builtin(_builtin_length,1))
38649:     
3865        __(movq %imm2,%arg_z)
3866        __(ret)         
3867_endsubp(builtin_length)
3868
3869       
3870_spentry(builtin_seqtype)
3871        __(extract_lisptag(%arg_z,%imm0))
3872        __(cmpb $tag_list,%imm0_b)
3873        __(jz 1f)
3874        __(cmpb $tag_misc,%imm0_b)
3875        __(jne 2f)
3876        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3877        __(rcmpb(%imm0_b,$min_vector_subtag))
3878        __(jb 2f)
3879        __(movl $nil_value,%arg_z_l)
3880        __(ret)
38811:      __(movl $t_value,%arg_z_l)
3882        __(ret)
38832:     
3884        __(jump_builtin(_builtin_seqtype,1))
3885_endsubp(builtin_seqtype)
3886
3887_spentry(builtin_assq)
3888        __(cmpb $fulltag_nil,%arg_z_b)
3889        __(jz 5f)
38901:      __(movb $tagmask,%imm0_b)
3891        __(andb %arg_z_b,%imm0_b)
3892        __(cmpb $tag_list,%imm0_b)
3893        __(jnz 2f)
3894        __(_car(%arg_z,%arg_x))
3895        __(_cdr(%arg_z,%arg_z))
3896        __(cmpb $fulltag_nil,%arg_x_b)
3897        __(jz 4f)
3898        __(movb $tagmask,%imm0_b)
3899        __(andb %arg_x_b,%imm0_b)
3900        __(cmpb $tag_list,%imm0_b)
3901        __(jnz 3f)
3902        __(_car(%arg_x,%temp0))
3903        __(cmpq %temp0,%arg_y)
3904        __(jnz 4f)
3905        __(movq %arg_x,%arg_z)
3906        __(ret)
39074:      __(cmpb $fulltag_nil,%arg_z_b)
39085:      __(jnz 1b)
3909        __(repret)
39102:      __(uuo_error_reg_not_list(Rarg_z))
39113:      __(uuo_error_reg_not_list(Rarg_x))       
3912_endsubp(builtin_assq) 
3913
3914_spentry(builtin_memq)
3915        __(cmpb $fulltag_nil,%arg_z_b)
3916        __(jmp 3f)
39171:      __(movb $tagmask,%imm0_b)
3918        __(andb %arg_z_b,%imm0_b)
3919        __(cmpb $tag_list,%imm0_b)
3920        __(jnz 2f)
3921        __(_car(%arg_z,%arg_x))
3922        __(_cdr(%arg_z,%temp0))
3923        __(cmpq %arg_x,%arg_y)
3924        __(jz 4f)
3925        __(cmpb $fulltag_nil,%temp0_b)
3926        __(movq %temp0,%arg_z)
39273:      __(jnz 1b)
39284:      __(repret)                             
39292:      __(uuo_error_reg_not_list(Rarg_z))
3930_endsubp(builtin_memq)
3931
3932        __ifdef(`X8664')
3933logbitp_max_bit = 61
3934        __else
3935logbitp_max_bit = 30
3936        __endif
3937       
3938_spentry(builtin_logbitp)
3939        __(movb %arg_z_b,%imm0_b)
3940        __(orb %arg_y_b,%imm0_b)
3941        __(testb $fixnummask,%imm0_b)
3942        __(jnz 1f)
3943        __(unbox_fixnum(%arg_y,%imm0))
3944        __(movl $logbitp_max_bit-1+fixnumshift,%imm1_l)
3945        __(js 1f)               /* bit number negative */
3946        __(addb $fixnumshift,%imm0_b)
3947        __(cmpq $logbitp_max_bit<<fixnumshift,%arg_y)
3948        __(cmovael %imm1_l,%imm0_l)
3949        __(bt %imm0,%arg_z)
3950        __(condition_to_boolean(b,%imm0,%arg_z))
3951        __(ret)
39521:      __(jump_builtin(_builtin_logbitp,2))
3953_endsubp(builtin_logbitp)
3954
3955_spentry(builtin_logior)
3956        __(movb %arg_y_b,%imm0_b)
3957        __(orb %arg_z_b,%imm0_b)
3958        __(testb $fixnummask,%imm0_b)
3959        __(jne 1f)
3960        __(orq %arg_y,%arg_z)
3961        __(ret)
39621:     
3963        __(jump_builtin(_builtin_logior,2))
3964               
3965_endsubp(builtin_logior)
3966
3967_spentry(builtin_logand)
3968        __(movb %arg_y_b,%imm0_b)
3969        __(orb %arg_z_b,%imm0_b)
3970        __(testb $fixnummask,%imm0_b)
3971        __(jne 1f)
3972        __(andq %arg_y,%arg_z)
3973        __(ret)
39741:             
3975        __(jump_builtin(_builtin_logand,2))
3976_endsubp(builtin_logand)
3977
3978_spentry(builtin_negate)
3979        __(testb $fixnummask,%arg_z_b)
3980        __(jne 1f)
3981        __(negq %arg_z)
3982        __(jo C(fix_one_bit_overflow))
3983        __(repret)
39841:             
3985        __(jump_builtin(_builtin_negate,1))     
3986_endsubp(builtin_negate)
3987
3988_spentry(builtin_logxor)
3989        __(movb %arg_y_b,%imm0_b)
3990        __(orb %arg_z_b,%imm0_b)
3991        __(testb $fixnummask,%imm0_b)
3992        __(jne 1f)
3993        __(xorq %arg_y,%arg_z)
3994        __(ret)
39951:             
3996        __(jump_builtin(_builtin_logxor,2))
3997_endsubp(builtin_logxor)
3998
3999
4000_spentry(builtin_aset1)
4001        __(extract_typecode(%arg_x,%imm0))
4002        __(box_fixnum(%imm0,%temp0))
4003        __(cmpb $min_vector_subtag,%imm0_b)
4004        __(ja _SPsubtag_misc_set)
4005        __(jump_builtin(_builtin_aset1,3))
4006_endsubp(builtin_aset1)
4007
4008
4009_spentry(builtin_ash)
4010        __(movb %arg_y_b,%imm0_b)
4011        __(orb %arg_z_b,%imm0_b)
4012        __(testb $fixnummask,%imm0_b)
4013        __(jne 9f)
4014        __(unbox_fixnum(%arg_y,%imm1))
4015        __(unbox_fixnum(%arg_z,%imm0))
4016        /* Z flag set if zero ASH shift count   */
4017        __(jnz 1f)
4018        __(movq %arg_y,%arg_z)  /* shift by 0   */
4019        __(ret)
40201:      __(jns 3f)
4021        __(rcmpq(%imm0,$-63))
4022        __(jg 2f)
4023        __(sar $63,%imm1)
4024        __(box_fixnum(%imm1,%arg_z))
4025        __(ret)
40262:      /* Right-shift by small fixnum   */
4027        __(negb %imm0_b)
4028        __(movzbl %imm0_b,%ecx)
4029        __(sar %cl,%imm1)
4030        __(box_fixnum(%imm1,%arg_z))
4031        __(ret)
40323:      /* Left shift by fixnum. We cant shift by more than 63 bits, though  */
4033        /* shifting by 64 is actually easy.   */
4034        __(rcmpq(%imm0,$64))
4035        __(jg 9f)
4036        __(jne 4f)
4037        /* left-shift by 64-bits exactly   */
4038        __(xorl %imm0_l,%imm0_l)
4039        __(jmp C(makes128))
40404:      /* left-shift by 1..63 bits.  Safe to move shift count to %rcx/%cl   */
4041        __(movzbl %imm0_b,%ecx)  /* zero-extending mov   */
4042        __(movq %imm1,%imm0)
4043        __(sarq $63,%imm1)
4044        __(js 5f)
4045        __(shld %cl,%imm0,%imm1)
4046        __(shl %cl,%imm0)
4047        __(jmp C(makes128))
40485:      __(shld %cl,%imm0,%imm1)
4049        __(shl %cl,%imm0)
4050        __(jmp C(makes128))
40519:     
4052        __(jump_builtin(_builtin_ash,2))
4053_endsubp(builtin_ash)
4054
4055_spentry(builtin_aref1)
4056        __(extract_typecode(%arg_y,%imm0))
4057        __(cmpb $min_vector_subtag,%imm0_b)
4058        __(box_fixnum_no_flags(%imm0,%arg_x))
4059        __(ja _SPsubtag_misc_ref)
4060        __(jump_builtin(_builtin_aref1,2))
4061_endsubp(builtin_aref1)
4062
4063/* Arg_z is either a MACPTR containing the function address or a boxed fixnum.  */
4064/*   %imm0.b (aka %al) contains the number (0-7) of args passed in FP regs.  */
4065/*   On entry, the foreign stack contains a frame containing at least 8 words:  */
4066
4067/*   * -> aligned on 16-byte boundary  */
4068/*  *backlink   <-      foreign %rsp              */
4069/*   unused  */
4070/*   scalar arg 0               passed in %rdi  */
4071/*   scalar arg 1         passed in %rsi  */
4072/*   scalar arg 2               passed in %rdx  */
4073/*   scalar arg 3               passed in %rcx  */
4074/*   scalar arg 4               passed in %r8  */
4075/*   scalar arg 5               passed in %r9  */
4076/*  *address of first memory arg  */
4077/*   ...  */
4078/*   possible scratch space  */
4079/*  *previous %rsp value  */
4080
4081/*   Any floating-point args will have been loaded into %xmm0-%xmm7 by the caller.  */
4082/*   When this returns, the foreign %rsp will contain its previous value, and  */
4083/*   the function result will be in %rax (and possibly %rdx) or %xmm0 (+ %xmm1).  */
4084
4085        .globl C(ffcall_return)
4086_spentry(ffcall)
4087LocalLabelPrefix`'ffcall:               
4088        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
4089          if not a fixnum, get the first word */
4090        __(unbox_fixnum(%arg_z,%imm1))
4091        __(testb $fixnummask,%arg_z_b)
4092        __(je 0f)
4093        __(movq macptr.address(%arg_z),%imm1)
40940:             
4095        /* Save lisp registers   */
4096        __(push %rbp)
4097        __(movq %rsp,%rbp)
4098        __(push %temp0)
4099        __(push %temp1)
4100        __(push %temp2)
4101        __(push %arg_x)
4102        __(push %arg_y)
4103        __(push %arg_z)
4104        __(push %fn)
4105        __ifndef(`TCR_IN_GPR')
4106        __(push %save3) 
4107        __endif
4108        __(push %save2)
4109        __(push %save1)
4110        __(push %save0)       /* 10 or 11 registers pushed after %rbp */
4111        __(movq %rsp,rcontext(tcr.save_vsp))
4112        __(movq %rbp,rcontext(tcr.save_rbp))
4113        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4114        __(movq rcontext(tcr.foreign_sp),%rsp)
4115        __ifdef(`WINDOWS')
4116        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4117        __else
4118        __(movq $0,rcontext(tcr.ffi_exception))
4119        __endif
4120        __(emms)
4121        __ifdef(`WINDOWS')
4122        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4123        __endif
4124        __(movq (%rsp),%rbp)
4125        __ifdef(`TCR_IN_GPR')
4126        /* Preserve TCR pointer */
4127        __(movq %rcontext_reg, %csave0)
4128        __endif
4129LocalLabelPrefix`'ffcall_setup:
4130        __(addq $2*node_size,%rsp)
4131        __(movq %imm1,%r11)
4132        __ifdef(`WINDOWS')
4133         /* Leave 0x20 bytes of register spill area on stack */
4134         __(movq (%rsp),%carg0)
4135         __(movq 8(%rsp),%carg1)
4136         __(movq 16(%rsp),%carg2)
4137         __(movq 24(%rsp),%carg3)
4138        __else
4139         __(pop %carg0)
4140         __(pop %carg1)
4141         __(pop %carg2)
4142         __(pop %carg3)
4143         __(pop %carg4)
4144         __(pop %carg5)
4145        __endif
4146LocalLabelPrefix`'ffcall_setup_end:
4147LocalLabelPrefix`'ffcall_call:
4148        __(call *%r11)
4149C(ffcall_return):               
4150LocalLabelPrefix`'ffcall_call_end:               
4151        __ifdef(`WINDOWS')
4152        __(add $0x20,%rsp)
4153        __endif
4154        __(movq %rbp,%rsp)
4155        __ifdef(`TCR_IN_GPR')
4156        __(movq %csave0, %rcontext_reg)
4157        __endif
4158        __(movq %rsp,rcontext(tcr.foreign_sp))
4159        __ifndef(`TCR_IN_GPR')
4160        __(clr %save3)
4161        __endif
4162        __(clr %save2)
4163        __(clr %save1)
4164        __(clr %save0)
4165        __(clr %arg_z)
4166        __(clr %arg_y)
4167        __(clr %arg_x)
4168        __(clr %temp2)
4169        __(clr %temp1)
4170        __(clr %temp0)
4171        __(clr %fn)
4172        __(pxor %fpzero,%fpzero)
4173
4174        __ifndef(`WINDOWS')
4175        /* If we got a floating-point exception during the ff-call,
4176           our handler will have set a flag, preserved lisp's MXCSR,
4177           and resumed execution with fp exceptions masked. */
4178        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
4179        __(jnc 1f)
4180        __endif
4181        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
4182        __(je 0f)
4183        __(movl %arg_x_l,rcontext(tcr.ffi_exception))
4184        __(jmp 1f)
41850:      __(stmxcsr rcontext(tcr.ffi_exception))
4186        __ifndef(`WINDOWS')
4187        __(ldmxcsr rcontext(tcr.lisp_mxcsr)) /* preserved by the handler */
4188        __endif
41891:      __(movq rcontext(tcr.save_vsp),%rsp)
4190        __(movq rcontext(tcr.save_rbp),%rbp)
4191        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4192        __(pop %save0)
4193        __(pop %save1)
4194        __(pop %save2)
4195        __ifndef(`TCR_IN_GPR')
4196        __(pop %save3)
4197        __endif
4198        __(pop %fn)
4199        __(pop %arg_z)
4200        __(pop %arg_y)
4201        __(pop %arg_x)
4202        __(pop %temp2)
4203        __(pop %temp1)
4204        __ifdef(`WINDOWS')
4205        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4206        __endif
4207        __(check_pending_interrupt(%temp0))
4208        __(pop %temp0)
4209        __(leave)
4210        __ifdef(`DARWIN')
4211        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,rcontext(tcr.flags))
4212        __(jc 0f)
4213        __endif
4214        __(ret)
4215        __ifdef(`DARWIN')
42160:
4217        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4218        /* Box it, then signal a lisp error. */
4219        __(movq %imm0,%imm2)
4220        __(movq $macptr_header,%rax)
4221        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4222        __(movq %imm2,macptr.address(%arg_z))
4223        __(movq $XFOREIGNEXCEPTION,%arg_y)
4224        __(set_nargs(2))
4225        __(jmp _SPksignalerr)
4226        __endif
4227        __ifdef(`DARWIN')       
4228        /* Handle exceptions, for ObjC 2.0 */
4229LocalLabelPrefix`'ffcallLandingPad:     
4230        __(movq %rax,%save1)
4231        __(cmpq $1,%rdx)
4232        __(je 1f)
4233        __(movq %rax,%rdi)
4234LocalLabelPrefix`'ffcallUnwindResume:           
4235        __(call *lisp_global(unwind_resume))
4236LocalLabelPrefix`'ffcallUnwindResume_end:         
42371:      __(movq %save1,%rdi)
4238LocalLabelPrefix`'ffcallBeginCatch:             
4239        __(call *lisp_global(objc_2_begin_catch))
4240LocalLabelPrefix`'ffcallBeginCatch_end:         
4241        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4242LocalLabelPrefix`'ffcallEndCatch:               
4243        __(call *lisp_global(objc_2_end_catch))
4244LocalLabelPrefix`'ffcallEndCatch_end:           
4245        __(ref_global(get_tcr,%rax))
4246        __(movq $1,%rdi)
4247        __(call *%rax)
4248        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4249        __(movq %save1,%rax)
4250        __(jmp LocalLabelPrefix`'ffcall_call_end)
4251LocalLabelPrefix`'ffcall_end:   
4252        __endif
4253_endsubp(ffcall)
4254
4255        __ifdef(`DARWIN')
4256        .section __DATA,__gcc_except_tab
4257GCC_except_table0:
4258        .align 3
4259LLSDA1:
4260        .byte   0xff    /* @LPStart format (omit) */
4261        .byte   0x0     /* @TType format (absolute) */
4262        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4263        .byte   0x3     /* call-site format (udata4) */
4264        .byte   0x41    /* uleb128 0x41; Call-site table length */
4265       
4266        .long Lffcall_setup-Lffcall     /* region 0 start */
4267        .long Lffcall_setup_end-Lffcall_setup   /* length */
4268        .long   0x0     /* landing pad */
4269        .byte   0x0     /* uleb128 0x0; action */
4270       
4271        .long Lffcall_call-Lffcall      /* region 1 start */
4272        .long Lffcall_call_end-Lffcall_call     /* length */
4273        .long LffcallLandingPad-Lffcall /* landing pad */
4274        .byte   0x1     /* uleb128 0x1; action */
4275       
4276        .long LffcallUnwindResume-Lffcall       /* region 2 start */
4277        .long LffcallUnwindResume_end-LffcallUnwindResume       /* length */
4278        .long   0x0     /* landing pad */
4279        .byte   0x0     /* uleb128 0x0; action */
4280       
4281        .long LffcallBeginCatch-Lffcall /* region 3 start */
4282        .long LffcallBeginCatch_end-LffcallBeginCatch   /* length */
4283        .long 0 /* landing pad */
4284        .byte   0x0     /* uleb128 0x0; action */
4285       
4286        .long LffcallEndCatch-Lffcall
4287        .long LffcallEndCatch_end-LffcallEndCatch       /* length */
4288        .long   0x0     /* landing pad */
4289        .byte   0x0     /* uleb128 0x0; action */
4290        .byte   0x1     /* Action record table */
4291        .byte   0x0
4292        .align 3
4293        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4294        .text
4295        __endif
4296
4297_spentry(ffcall_return_registers)
4298LocalLabelPrefix`'ffcall_return_registers:               
4299        /* Unbox %arg_z.  It's either a fixnum or macptr (or bignum) ;
4300          if not a fixnum, get the first word */
4301        __(unbox_fixnum(%arg_z,%imm1))
4302        __(testb $fixnummask,%arg_z_b)
4303        __(je 0f)
4304        __(movq macptr.address(%arg_z),%imm1)
43050:             
4306        /* Save lisp registers   */
4307        __(push %rbp)
4308        __(movq %rsp,%rbp)
4309        __(push %temp0)
4310        __(push %temp1)
4311        __(push %temp2)
4312        __(push %arg_x)
4313        __(push %arg_y)
4314        __(push %arg_z)
4315        __ifndef(`TCR_IN_GPR')
4316        __(push %save3)
4317        __endif
4318        __(push %save2)
4319        __(push %save1)
4320        __(push %save0)
4321        __(movq macptr.address(%arg_y),%csave0)  /* %rbx non-volatile */
4322        __(push %fn)
4323        __(movq %rsp,rcontext(tcr.save_vsp))
4324        __(movq %rbp,rcontext(tcr.save_rbp))
4325        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4326        __(movq $0,rcontext(tcr.ffi_exception))
4327        __(movq rcontext(tcr.foreign_sp),%rsp)
4328        __(emms)
4329        __(movq (%rsp),%rbp)
4330        __ifdef(`TCR_IN_GPR')
4331        /* Preserve TCR pointer */
4332        __(movq %rcontext_reg, %csave1)
4333        __endif
4334        __(movq %imm1,%r11)
4335LocalLabelPrefix`'ffcall_return_registers_setup:
4336        __(addq $2*node_size,%rsp)
4337        __(pop %carg0)
4338        __(pop %carg1)
4339        __(pop %carg2)
4340        __(pop %carg3)
4341        __ifdef(`WINDOWS')
4342        __(sub $0x20, %rsp) /* Make room for arg register spill */
4343        __else
4344        __(pop %carg4)
4345        __(pop %carg5)
4346        __endif
4347LocalLabelPrefix`'ffcall_return_registers_setup_end: 
4348LocalLabelPrefix`'ffcall_return_registers_call:
4349        __(call *%r11)
4350LocalLabelPrefix`'ffcall_return_registers_call_end:
4351        __ifdef(`WINDOWS')
4352        __(add $0x20, %rsp)
4353        __endif
4354        __(movq %rax,(%csave0))
4355        __(movq %rdx,8(%csave0))
4356        __(movsd %xmm0,16(%csave0))
4357        __(movsd %xmm1,24(%csave0))
4358        __(movq %rbp,%rsp)
4359        __ifdef(`TCR_IN_GPR')
4360        __(movq %csave1, %rcontext_reg)
4361        __endif
4362        __(movq %rsp,rcontext(tcr.foreign_sp))       
4363        __ifndef(`TCR_IN_GPR')
4364        __(clr %save3)
4365        __endif
4366        __(clr %save2)
4367        __(clr %save1)
4368        __(clr %save0)
4369        __(clr %arg_z)
4370        __(clr %arg_y)
4371        __(clr %arg_x)
4372        __(clr %temp2)
4373        __(clr %temp1)
4374        __(clr %temp0)
4375        __(clr %fn)
4376        __(pxor %fpzero,%fpzero)
4377        /* Check for fp exceptions as in .SPffcall, above. */
4378        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
4379        __(jnc 1f)
4380        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
4381        __(je 0f)
4382        __(movl %arg_x_l,rcontext(tcr.ffi_exception))
4383        __(jmp 1f)
43840:      __(stmxcsr rcontext(tcr.ffi_exception))
4385        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
43861:      __(movq rcontext(tcr.save_vsp),%rsp)
4387        __(movq rcontext(tcr.save_rbp),%rbp)
4388        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4389        __(pop %fn)
4390        __(pop %save0)
4391        __(pop %save1)
4392        __(pop %save2)
4393        __ifndef(`TCR_IN_GPR')
4394        __(pop %save3)
4395        __endif
4396        __(pop %arg_z)
4397        __(pop %arg_y)
4398        __(pop %arg_x)
4399        __(pop %temp2)
4400        __(pop %temp1)
4401        __(check_pending_interrupt(%temp0))
4402        __(pop %temp0)
4403        __(leave)
4404        __ifdef(`DARWIN')
4405        __(btrq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,rcontext(tcr.flags))
4406        __(jc 0f)
4407        __endif
4408        __(ret)
4409        __ifdef(`DARWIN')
44100:
4411        /* Unboxed foreign exception (likely an NSException) in %imm0. */
4412        /* Box it, then signal a lisp error. */
4413        __(movq %imm0,%imm2)
4414        __(movq $macptr_header,%rax)
4415        __(Misc_Alloc_Fixed(%arg_z,macptr.size))
4416        __(movq %imm2,macptr.address(%arg_z))
4417        __(movq $XFOREIGNEXCEPTION,%arg_y)
4418        __(set_nargs(2))
4419        __(jmp _SPksignalerr)
4420        __endif
4421        __ifdef(`DARWIN')       
4422        /* Handle exceptions, for ObjC 2.0 */
4423LocalLabelPrefix`'ffcall_return_registersLandingPad:     
4424        __(movq %rax,%save1)
4425        __(cmpq $1,%rdx)
4426        __(je 1f)
4427        __(movq %rax,%rdi)
4428LocalLabelPrefix`'ffcall_return_registersUnwindResume:           
4429        __(call *lisp_global(unwind_resume))
4430LocalLabelPrefix`'ffcall_return_registersUnwindResume_end:         
44311:      __(movq %save1,%rdi)
4432LocalLabelPrefix`'ffcall_return_registersBeginCatch:             
4433        __(call *lisp_global(objc_2_begin_catch))
4434LocalLabelPrefix`'ffcall_return_registersBeginCatch_end:         
4435        __(movq (%rax),%save1) /* indirection is necessary because we don't provide type info in lsda */
4436LocalLabelPrefix`'ffcall_return_registersEndCatch:               
4437        __(call *lisp_global(objc_2_end_catch))
4438LocalLabelPrefix`'ffcall_return_registersEndCatch_end:           
4439        __(ref_global(get_tcr,%rax))
4440        __(movq $1,%rdi)
4441        __(call *%rax)
4442        __(btsq $TCR_FLAG_BIT_FOREIGN_EXCEPTION,tcr.flags(%rax))
4443        __(movq %save1,%rax)
4444        __(jmp LocalLabelPrefix`'ffcall_return_registers_call_end)
4445LocalLabelPrefix`'ffcall_return_registers_end:   
4446        __endif
4447_endsubp(ffcall_returning_registers)
4448
4449        __ifdef(`DARWIN')
4450        .section __DATA,__gcc_except_tab
4451GCC_except_table1:
4452        .align 3
4453LLSDA2:
4454        .byte   0xff    /* @LPStart format (omit) */
4455        .byte   0x0     /* @TType format (absolute) */
4456        .byte   0x4d    /* uleb128 0x4d; @TType base offset */
4457        .byte   0x3     /* call-site format (udata4) */
4458        .byte   0x41    /* uleb128 0x41; Call-site table length */
4459       
4460        .long Lffcall_return_registers_setup-Lffcall_return_registers   /* region 0 start */
4461        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup /* length */
4462        .long   0x0     /* landing pad */
4463        .byte   0x0     /* uleb128 0x0; action */
4464       
4465        .long Lffcall_return_registers_call-Lffcall_return_registers    /* region 1 start */
4466        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call   /* length */
4467        .long Lffcall_return_registersLandingPad-Lffcall_return_registers       /* landing pad */
4468        .byte   0x1     /* uleb128 0x1; action */
4469       
4470        .long Lffcall_return_registersUnwindResume-Lffcall_return_registers     /* region 2 start */
4471        .long Lffcall_return_registersUnwindResume_end-Lffcall_return_registersUnwindResume     /* length */
4472        .long   0x0     /* landing pad */
4473        .byte   0x0     /* uleb128 0x0; action */
4474       
4475        .long Lffcall_return_registersBeginCatch-Lffcall_return_registers       /* region 3 start */
4476        .long Lffcall_return_registersBeginCatch_end-Lffcall_return_registersBeginCatch /* length */
4477        .long 0 /* landing pad */
4478        .byte   0x0     /* uleb128 0x0; action */
4479       
4480        .long Lffcall_return_registersEndCatch-Lffcall_return_registers
4481        .long Lffcall_return_registersEndCatch_end-Lffcall_return_registersEndCatch     /* length */
4482        .long   0x0     /* landing pad */
4483        .byte   0x0     /* uleb128 0x0; action */
4484        .byte   0x1     /* Action record table */
4485        .byte   0x0
4486        .align 3
4487        .quad   0       /* _OBJC_EHTYPE_$_NSException */
4488        .text
4489        __endif
4490               
4491_spentry(syscall)
4492        /* Save lisp registers   */
4493        __(push %rbp)
4494        __(movq %rsp,%rbp)
4495        __(push %temp0)
4496        __(push %temp1)
4497        __(push %temp2)
4498        __(push %arg_x)
4499        __(push %arg_y)
4500        __(push %arg_z)
4501        __ifndef(`TCR_IN_GPR')
4502         __(push %save3)
4503        __endif
4504        __(push %save2)
4505        __(push %save1)
4506        __(push %save0)
4507        __(push %fn)
4508        __(movq %rsp,rcontext(tcr.save_vsp))
4509        __(movq %rbp,rcontext(tcr.save_rbp))
4510        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4511        __(movq rcontext(tcr.foreign_sp),%rsp)
4512        __(emms)
4513        __(movq (%rsp),%rbp)
4514        __(addq $2*node_size,%rsp)
4515        __ifdef(`TCR_IN_GPR')
4516         __(movq %rcontext_reg,%csave0)
4517        __endif
4518        __ifdef(`WINDOWS')
4519         __(pop %carg0)
4520         __(pop %carg1)
4521         __(pop %carg2)
4522         __(pop %carg3)
4523         __(subq $0x20,%rsp)
4524         __(orq $-1,%cret)
4525         __(addq $0x20,%rsp)
4526        __else
4527         __(unbox_fixnum(%arg_z,%rax))
4528         __(pop %rdi)
4529         __(pop %rsi)
4530         __(pop %rdx)
4531         __(pop %r10)           /*  syscalls take 4th param in %r10, not %rcx   */
4532         __(pop %r8)
4533         __(pop %r9)
4534         __(syscall)
4535         __ifdef(`SYSCALL_SETS_CARRY_ON_ERROR')
4536          __(jnc 0f)
4537          __(negq %rax)
45380:     
4539         __endif
4540        __endif
4541        __ifdef(`TCR_IN_GPR')
4542         __(movq %csave0,%rcontext_reg)
4543        __endif
4544        __(movq %rbp,%rsp)
4545        __(movq %rsp,rcontext(tcr.foreign_sp))
4546        __ifndef(`TCR_IN_GPR')
4547         __(clr %save3)
4548        __endif
4549        __(clr %save2)
4550        __(clr %save1)
4551        __(clr %save0)
4552        __(clr %arg_z)
4553        __(clr %arg_y)
4554        __(clr %arg_x)
4555        __(clr %temp2)
4556        __(clr %temp1)
4557        __(clr %temp0)
4558        __(clr %fn)
4559        __(pxor %fpzero,%fpzero)
4560        __(movq rcontext(tcr.save_vsp),%rsp)
4561        __(movq rcontext(tcr.save_rbp),%rbp)
4562        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4563        __(pop %fn)
4564        __(pop %save0)
4565        __(pop %save1)
4566        __(pop %save2)
4567        __ifndef(`TCR_IN_GPR')
4568         __(pop %save3)
4569        __endif
4570        __(pop %arg_z)
4571        __(pop %arg_y)
4572        __(pop %arg_x)
4573        __(pop %temp2)
4574        __(pop %temp1)
4575        __(check_pending_interrupt(%temp0))
4576        __(pop %temp0)
4577        __(leave)
4578        __(ret)
4579_endsubp(syscall)               
4580
4581/* We need to reserve a frame here if (a) nothing else was already pushed and (b) */
4582/*   we push something (e.g., more than 3 args in the lexpr)      */
4583_spentry(spread_lexprz)
4584        new_local_labels()
4585        __(movq (%arg_z),%imm0)
4586        __(testl %nargs,%nargs) /* anything pushed by caller ? */
4587        __(leaq node_size(%arg_z,%imm0),%imm1)
4588        __(jne 0f)              /* yes, caller has already created frame. */
4589        __(cmpw $(nargregs*node_size),%imm0_w) /* will we push anything ? */
4590        __(jbe 0f)
4591        __(push $reserved_frame_marker)
4592        __(push $reserved_frame_marker)
45930:      __(addw %imm0_w,%nargs_w)
4594        __(cmpw $(nargregs*node_size),%imm0_w)
4595        __(jae 9f)
4596        __(cmpw $(2*node_size),%imm0_w)
4597        __(je 2f)
4598        __(testw %imm0_w,%imm0_w)
4599        __(jne 1f)
4600        /* lexpr count was 0; vpop the args that */
4601        /* were pushed by the caller */
4602        __(testl %nargs,%nargs)
4603        __(je local_label(all_args_popped))
4604        __(pop %arg_z)
4605local_label(maybe_pop_yx):             
4606        __(cmpl $(1*node_size),%nargs)
4607        __(je local_label(all_args_popped))
4608        __(pop %arg_y)
4609        __(cmpl $(2*node_size),%nargs)
4610        __(je local_label(all_args_popped))
4611local_label(pop_arg_x):         
4612        __(pop %arg_x)
4613local_label(all_args_popped):   
4614        /* If all args fit in registers but some were pushed */
4615        /* by the caller, discard the reserved frame that the caller */
4616        /* pushed.         */
4617        __(cmpw %imm0_w,%nargs_w)
4618        __(je local_label(go))
4619        __(cmpl $(nargregs*node_size),%nargs)
4620        __(ja local_label(go))
4621        __(addq $(2*node_size),%rsp)
4622local_label(go):       
4623        __(jmp *%ra0)       
4624        /* vpush args from the lexpr until we have only */
4625        /* three left, then assign them to arg_x, arg_y, */
4626        /* and arg_z. */
46278:      __(cmpw $(4*node_size),%imm0_w)
4628        __(lea -1*node_size(%imm0),%imm0)
4629        __(push -node_size(%imm1))
4630        __(lea -1*node_size(%imm1),%imm1)
46319:      __(jne 8b)
4632        __(movq -node_size*1(%imm1),%arg_x)
4633        __(movq -node_size*2(%imm1),%arg_y)
4634        __(movq -node_size*3(%imm1),%arg_z)
4635        __(jmp *%ra0)
4636
4637        /* lexpr count is two: set arg_y, arg_z from the */
4638        /* lexpr, maybe vpop arg_x */
46392:      __(cmpl $(2*node_size),%nargs)
4640        __(movq -node_size*1(%imm1),%arg_y)
4641        __(movq -node_size*2(%imm1),%arg_z)
4642        __(jne local_label(pop_arg_x))
4643        __(jmp *%ra0)
4644        /* lexpr count is one: set arg_z from the lexpr, */
4645        /* maybe vpop arg_y, arg_x  */
46461:      __(movq -node_size*1(%imm1),%arg_z)
4647        __(jmp local_label(maybe_pop_yx))
4648_endsubp(spread_lexprz)
4649       
4650
4651
4652
4653/* Callback index in %r11 */
4654_spentry(callback)
4655        __(push %rbp)
4656        __(movq %rsp,%rbp)
4657        /* C scalar args   */
4658        __(push %carg0) /* -8(%rbp)   */
4659        __(push %carg1)
4660        __(push %carg2)
4661        __(push %carg3)
4662        __ifndef(`WINDOWS')
4663        __(push %carg4)
4664        __(push %carg5)
4665        __endif
4666        /* FP arg regs   */
4667        __ifdef(`WINDOWS')
4668        __(subq $4*8,%rsp)
4669        __(movq %xmm0,3*8(%rsp))        /* -40(%rbp) */
4670        __(movq %xmm1,2*8(%rsp))
4671        __(movq %xmm2,1*8(%rsp))
4672        __(movq %xmm3,0*8(%rsp))
4673        __else
4674        __(subq $8*8,%rsp)
4675        __(movq %xmm0,7*8(%rsp))        /* -56(%rbp) */
4676        __(movq %xmm1,6*8(%rsp))
4677        __(movq %xmm2,5*8(%rsp))
4678        __(movq %xmm3,4*8(%rsp))
4679        __(movq %xmm4,3*8(%rsp))
4680        __(movq %xmm5,2*8(%rsp))
4681        __(movq %xmm6,1*8(%rsp))
4682        __(movq %xmm7,0*8(%rsp))
4683        __endif
4684        __ifndef(`WINDOWS')
4685        __endif
4686        /* Save caller's mxcsr */
4687        __(subq $16,%rsp)
4688        __(stmxcsr (%rsp))
4689        __(andb $~mxcsr_all_exceptions,(%rsp))
4690        /* C NVRs   */
4691        __(push %csave0)
4692        __(push %csave1)
4693        __(push %csave2)
4694        __(push %csave3)
4695        __(push %csave4)
4696        __ifdef(`WINDOWS')
4697        __(push %csave5)
4698        __(push %csave6)
4699        __endif
4700        __(push %rbp)
4701        __(movq %r11,%csave0)
4702        __ifdef(`HAVE_TLS')
4703         /* TCR initialized for lisp ?   */
4704         __ifndef(`TCR_IN_GPR') /* FIXME */
4705         __(movq %fs:current_tcr@TPOFF,%rax)
4706         __(testq %rax,%rax)
4707         __(jne 1f)
4708         __endif
4709        __endif
4710        __(ref_global(get_tcr,%rax))
4711        __(movq $1,%carg0)
4712        __ifdef(`WINDOWS')
4713        __(sub $0x20, %rsp)
4714        __endif
4715        __(call *%rax)
4716        __ifdef(`WINDOWS')
4717        __(add $0x20, %rsp)
4718        __endif
4719        __ifdef(`TCR_IN_GPR')
4720        __(movq %rax, %rcontext_reg)
4721        __endif
47221:      /* Align foreign stack for lisp   */
4723        __(pushq rcontext(tcr.save_rbp)) /* mark cstack frame's "owner" */
4724        __(pushq rcontext(tcr.foreign_sp))
4725        /* init lisp registers   */
4726        __(movq %csave0,%rax)
4727        __(movq %rsp,rcontext(tcr.foreign_sp))
4728        __ifndef(`TCR_IN_GPR')
4729        __(clr %save3)
4730        __endif
4731        __(clr %save2)
4732        __(clr %save1)
4733        __(clr %save0)
4734        __(clr %arg_z)
4735        __(clr %arg_y)
4736        __(clr %arg_x)
4737        __(clr %temp2)
4738        __(clr %temp1)
4739        __(clr %temp0)
4740        __(clr %fn)
4741        __(pxor %fpzero,%fpzero)
4742        __(movq rcontext(tcr.save_vsp),%rsp)
4743        __(box_fixnum(%rax,%arg_y))
4744        __(movq %rbp,%arg_z)
4745        __(movq rcontext(tcr.save_rbp),%rbp)
4746        __(movq $TCR_STATE_LISP,rcontext(tcr.valence))
4747        __(movq (%rsp),%save0)
4748        __(movq 8(%rsp),%save1)
4749        __(movq 16(%rsp),%save2)
4750        __ifndef(`TCR_IN_GPR')
4751         __(movq 24(%rsp),%save3)
4752        __endif
4753        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4754        __(movq $nrs.callbacks,%fname)
4755        __(lea local_label(back_from_callback)(%rip),%ra0)
4756        __(set_nargs(2))
4757        __(push %ra0)
4758        __(jump_fname())
4759__(tra(local_label(back_from_callback)))
4760        __(movq %rsp,rcontext(tcr.save_vsp))
4761        __(movq %rbp,rcontext(tcr.save_rbp))
4762        __(movq rcontext(tcr.foreign_sp),%rsp)
4763        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4764        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4765        __(emms)
4766        __(pop rcontext(tcr.foreign_sp))
4767        __(addq $node_size,%rsp)
4768        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4769        __(pop %rbp)
4770        __ifdef(`WINDOWS')
4771        __(pop %csave6)
4772        __(pop %csave5)
4773        __endif
4774        __(pop %csave4)
4775        __(pop %csave3)
4776        __(pop %csave2)
4777        __(pop %csave1)
4778        __(pop %csave0)
4779        __(ldmxcsr (%rsp))
4780        __(addq $16,%rsp)
4781        __(movq -8(%rbp),%rax)
4782        __(movq -16(%rbp),%rdx)
4783        __(movq -24(%rbp),%xmm0)
4784        __(movq -32(%rbp),%xmm1)
4785        __(leave)
4786        __(ret)         
4787_endsubp(callback)
4788
4789/* arg_x = array, arg_y = i, arg_z = j. Typecheck everything.
4790   We don't know whether the array is alleged to be simple or
4791   not, and don't know anythng about the element type.  */
4792               
4793_spentry(aref2)
4794        __(testb $fixnummask,%arg_y_b)
4795        __(jne 0f)
4796       
4797        __(testb $fixnummask,%arg_z_b)
4798        __(jne 1f)
4799        __(extract_typecode(%arg_x,%imm0))
4800        __(cmpb $subtag_arrayH,%imm0_b)
4801        __(jne 2f)
4802        __(cmpq $2<<fixnumshift,arrayH.rank(%arg_x))
4803        __(jne 2f)
4804        __(cmpq arrayH.dim0(%arg_x),%arg_y)
4805        __(jae 3f)
4806        __(movq arrayH.dim0+node_size(%arg_x),%imm0)
4807        __(cmpq %imm0,%arg_z)
4808        __(jae 4f)
4809        __(unbox_fixnum(%imm0,%imm0))
4810        __(mulq %arg_y)         /* imm0 <- imm0 * arg_y */
4811        __(addq %imm0,%arg_z)
4812        __(movq %arg_x,%arg_y)
48136:      __(addq arrayH.displacement(%arg_y),%arg_z)
4814        __(movq arrayH.data_vector(%arg_y),%arg_y)
4815        __(extract_subtag(%arg_y,%imm1))
4816        __(cmpb $subtag_vectorH,%imm1_b)
4817        __(ja C(misc_ref_common))
4818        __(jmp 6b)
48190:      __(uuo_error_reg_not_fixnum(Rarg_y))
48201:      __(uuo_error_reg_not_fixnum(Rarg_z))
48212:      __(uuo_error_reg_not_type(Rarg_x,error_object_not_array_2d))
48223:      __(uuo_error_array_bounds(Rarg_y,Rarg_x))
48234:      __(uuo_error_array_bounds(Rarg_z,Rarg_x))
4824       
4825_endsubp(aref2)
4826
4827/* %temp0 = array, %arg_x = i,%arg_y = j, %arg_z = k */
4828_spentry(aref3)
4829        __(testb $fixnummask,%arg_x_b)
4830        __(jne 0f)
4831        __(testb $fixnummask,%arg_y_b)
4832        __(jne 1f)
4833        __(testb $fixnummask,%arg_z_b)
4834        __(jne 2f)
4835        __(extract_typecode(%temp0,%imm0))
4836        __(cmpb $subtag_arrayH,%imm0_b)
4837        __(jne 3f)
4838        __(cmpq $3<<fixnumshift,arrayH.rank(%temp0))
4839        __(jne 3f)
4840        __(cmpq arrayH.dim0(%temp0),%arg_x)
4841        __(jae 5f)
4842        __(movq arrayH.dim0+node_size(%temp0),%imm0)
4843        __(cmpq %imm0,%arg_y)
4844        __(jae 6f)
4845        __(unbox_fixnum(%imm0,%imm0))
4846        __(movq arrayH.dim0+(node_size*2)(%temp0),%imm1)
4847        __(cmpq %imm1,%arg_z)
4848        __(jae 7f)
4849        __(unbox_fixnum(%imm1,%imm1))
4850        __(imulq %imm1,%arg_y)
4851        __(mulq %imm1)
4852        __(imulq %imm0,%arg_x)
4853        __(addq %arg_x,%arg_z)
4854        __(addq %arg_y,%arg_z)
4855        __(movq %temp0,%arg_y)
48568:      __(addq arrayH.displacement(%arg_y),%arg_z)
4857        __(movq arrayH.data_vector(%arg_y),%arg_y)
4858        __(extract_subtag(%arg_y,%imm1))
4859        __(cmpb $subtag_vectorH,%imm1_b)
4860        __(ja C(misc_ref_common))
4861        __(jmp 8b)
48620:      __(uuo_error_reg_not_fixnum(Rarg_x))
48631:      __(uuo_error_reg_not_fixnum(Rarg_y))   
48642:      __(uuo_error_reg_not_fixnum(Rarg_z))
48653:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_3d))
48665:      __(uuo_error_array_bounds(Rarg_x,Rtemp0))
48676:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
48687:      __(uuo_error_array_bounds(Rarg_z,Rtemp0))
4869       
4870_endsubp(aref3)
4871       
4872/* As with aref2, but temp0 = array, arg_x = i, arg_y = j, arg_z = new_value */
4873_spentry(aset2)
4874        __(testb $fixnummask,%arg_x_b)
4875        __(jne 0f)
4876        __(testb $fixnummask,%arg_y_b)
4877        __(jne 1f)
4878        __(extract_typecode(%temp0,%imm0))
4879        __(cmpb $subtag_arrayH,%imm0_b)
4880        __(jne 2f)
4881        __(cmpq $2<<fixnumshift,arrayH.rank(%temp0))
4882        __(jne 2f)
4883        __(cmpq arrayH.dim0(%temp0),%arg_x)
4884        __(jae 4f)
4885        __(movq arrayH.dim0+node_size(%temp0),%imm0)
4886        __(cmpq %imm0,%arg_y)
4887        __(jae 5f)
4888        __(unbox_fixnum(%imm0,%imm0))
4889        __(mulq %arg_x)         /* imm0 <- imm0 * arg_x */
4890        __(addq %imm0,%arg_y)
4891        __(movq %temp0,%arg_x)
48926:      __(addq arrayH.displacement(%arg_x),%arg_y)
4893        __(movq arrayH.data_vector(%arg_x),%arg_x)
4894        __(extract_subtag(%arg_x,%imm1))
4895        __(cmpb $subtag_vectorH,%imm1_b)
4896        __(ja C(misc_set_common))
4897        __(jmp 6b)
48980:      __(uuo_error_reg_not_fixnum(Rarg_x))
48991:      __(uuo_error_reg_not_fixnum(Rarg_y))
49002:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
49014:      __(uuo_error_array_bounds(Rarg_x,Rtemp0))
49025:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
4903_endsubp(aset2)
4904
4905/* %temp1 = array, %temp0 = i, %arg_x = j, %arg_y = k, %arg_y = newval. */
4906
4907_spentry(aset3)
4908        __(testb $fixnummask,%temp0_b)
4909        __(jne 0f)
4910        __(testb $fixnummask,%arg_x_b)
4911        __(jne 1f)
4912        __(testb $fixnummask,%arg_y_b)
4913        __(jne 2f)
4914        __(extract_typecode(%temp1,%imm0))
4915        __(cmpb $subtag_arrayH,%imm0_b)
4916        __(jne 3f)
4917        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4918        __(jne 3f)
4919        __(cmpq arrayH.dim0(%temp1),%temp0)
4920        __(jae 5f)
4921        __(movq arrayH.dim0+node_size(%temp1),%imm0)
4922        __(cmpq %imm0,%arg_x)
4923        __(jae 6f)
4924        __(unbox_fixnum(%imm0,%imm0))
4925        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4926        __(cmpq %imm1,%arg_y)
4927        __(jae 7f)
4928        __(unbox_fixnum(%imm1,%imm1))
4929        __(imulq %imm1,%arg_x)
4930        __(mulq %imm1)
4931        __(imulq %imm0,%temp0)
4932        __(addq %temp0,%arg_y)
4933        __(addq %arg_x,%arg_y)
4934        __(movq %temp1,%arg_x)
49358:      __(addq arrayH.displacement(%arg_x),%arg_y)
4936        __(movq arrayH.data_vector(%arg_x),%arg_x)
4937        __(extract_subtag(%arg_x,%imm1))
4938        __(cmpb $subtag_vectorH,%imm1_b)
4939        __(ja C(misc_set_common))
4940        __(jmp 8b)
4941       
49420:      __(uuo_error_reg_not_fixnum(Rtemp0))
49431:      __(uuo_error_reg_not_fixnum(Rarg_x))
49442:      __(uuo_error_reg_not_fixnum(Rarg_y))
49453:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
49465:      __(uuo_error_array_bounds(Rtemp0,Rtemp1))
49476:      __(uuo_error_array_bounds(Rarg_x,Rtemp1))
49486:      __(uuo_error_array_bounds(Rarg_x,Rtemp1))
49497:      __(uuo_error_array_bounds(Rarg_y,Rtemp1))
4950       
4951_endsubp(aset3)
4952
4953       
4954
4955
4956/* Prepend all but the first five (4 words of code, inner fn) and last   */
4957/* (lfbits) elements of %fn to the "arglist".   */
4958       
4959_spentry(call_closure)
4960        new_local_labels()
4961        __(subq $fulltag_function-fulltag_misc,%fn)
4962        __(vector_length(%fn,%imm0))
4963       
4964        __(subq $6<<fixnumshift,%imm0)  /* imm0 = inherited arg count   */
4965        __(lea (%nargs_q,%imm0),%imm1)
4966        __(cmpl $nargregs<<fixnumshift,%imm1_l)
4967        __(jna local_label(regs_only))
4968        __(pop %ra0)
4969        __(cmpl $nargregs<<fixnumshift,%nargs)
4970        __(jna local_label(no_insert))
4971       
4972/* Some arguments have already been pushed.  Push imm0's worth   */
4973/* of NILs, copy those arguments that have already been vpushed from   */
4974/* the old TOS to the new, then insert all of the inerited args   */
4975/* and go to the function.  */
4976       
4977        __(movq %imm0,%imm1)
4978local_label(push_nil_loop):     
4979        __(push $nil_value)
4980        __(sub $fixnumone,%imm1)
4981        __(jne local_label(push_nil_loop))
4982       
4983/* Need to use arg regs as temporaries here.    */
4984        __(movq %rsp,%temp1)
4985        __(push %arg_z)
4986        __(push %arg_y)
4987        __(push %arg_x)
4988        __(lea 3*node_size(%rsp,%imm0),%arg_x)
4989        __(lea -nargregs<<fixnumshift(%nargs_q),%arg_y)
4990local_label(copy_already_loop): 
4991        __(movq (%arg_x),%arg_z)
4992        __(addq $fixnumone,%arg_x)
4993        __(movq %arg_z,(%temp1))
4994        __(addq $fixnumone,%temp1)
4995        __(subq $fixnumone,%arg_y)
4996        __(jne local_label(copy_already_loop))
4997       
4998        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
4999local_label(insert_loop):               
5000        __(movq misc_data_offset(%fn,%imm1),%arg_z)
5001        __(addq $node_size,%imm1)
5002        __(addl $fixnum_one,%nargs)
5003        __(subq $node_size,%arg_x)
5004        __(movq %arg_z,(%arg_x))
5005        __(subq $fixnum_one,%imm0)
5006        __(jne local_label(insert_loop))
5007
5008        /* Recover the argument registers, pushed earlier   */
5009        __(pop %arg_x)
5010        __(pop %arg_y)
5011        __(pop %arg_z)
5012        __(jmp local_label(go))
5013
5014/* Here if nothing was pushed by the caller.  If we're  */
5015/* going to push anything, we have to reserve a stack  */
5016/* frame first. (We'll need to push something if the  */
5017/* sum of %nargs and %imm0 is greater than nargregs)   */
5018       
5019local_label(no_insert):
5020        __(lea (%nargs_q,%imm0),%imm1)
5021        __(cmpq $nargregs<<fixnumshift,%imm1)
5022        __(jna local_label(no_insert_no_frame))
5023        /* Reserve space for a stack frame   */
5024        __(push $reserved_frame_marker)
5025        __(push $reserved_frame_marker)
5026local_label(no_insert_no_frame):       
5027        /* nargregs or fewer args were already vpushed.   */
5028        /* if exactly nargregs, vpush remaining inherited vars.   */
5029        __(cmpl $nargregs<<fixnumshift,%nargs)
5030        __(movl $5<<fixnumshift,%imm1_l) /* skip code, new fn   */
5031        __(leaq 5<<fixnumshift(%imm0),%temp1)
5032        __(jnz local_label(set_regs))
5033local_label(vpush_remaining): 
5034        __(push misc_data_offset(%fn,%imm1))
5035        __(addq $node_size,%imm1)
5036        __(addl $fixnumone,%nargs)
5037        __(subq $node_size,%imm0)
5038        __(jnz local_label(vpush_remaining))
5039        __(jmp local_label(go))
5040local_label(set_regs):
5041        /* if nargs was > 1 (and we know that it was < 3), it must have   */
5042        /* been 2.  Set arg_x, then vpush the remaining args.   */
5043        __(cmpl $fixnumone,%nargs)
5044        __(jle local_label(set_y_z))
5045local_label(set_arg_x): 
5046        __(subq $node_size,%temp1)
5047        __(movq misc_data_offset(%fn,%temp1),%arg_x)
5048        __(addl $fixnumone,%nargs)
5049        __(subq $fixnumone,%imm0)
5050        __(jne local_label(vpush_remaining))
5051        __(jmp local_label(go))
5052        /* Maybe set arg_y or arg_z, preceding args   */
5053local_label(set_y_z):
5054        __(jne local_label(set_arg_z))
5055        /* Set arg_y, maybe arg_x, preceding args   */
5056local_label(set_arg_y): 
5057        __(subq $node_size,%temp1)
5058        __(movq misc_data_offset(%fn,%temp1),%arg_y)
5059        __(addl $fixnumone,%nargs)
5060        __(subq $fixnum_one,%imm0)
5061        __(jnz local_label(set_arg_x))
5062        __(jmp local_label(go))
5063local_label(set_arg_z): 
5064        __(subq $node_size,%temp1)
5065        __(movq misc_data_offset(%fn,%temp1),%arg_z)
5066        __(addl $fixnumone,%nargs)
5067        __(subq $fixnum_one,%imm0)
5068        __(jne local_label(set_arg_y))
5069local_label(go):       
5070        __(movq misc_data_offset+(4*node_size)(%fn),%fn)
5071        __(push %ra0)
5072        __(jmp *%fn)
5073local_label(regs_only):
5074        __(leaq 5<<fixnumshift(%imm0),%temp1)
5075        __(testl %nargs,%nargs)
5076        __(jne local_label(some_args))
5077        __(cmpw $node_size,%imm0_w)
5078        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_z)
5079        __(je local_label(rgo))
5080        __(cmpw $2*node_size,%imm0_w)
5081        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_y)
5082        __(je local_label(rgo))
5083        __(movq misc_data_offset-(node_size*3)(%fn,%temp1),%arg_x)
5084local_label(rgo):
5085        __(addw %imm0_w,%nargs_w)
5086        __(jmp *misc_data_offset+(4*node_size)(%fn))
5087local_label(some_args):         
5088        __(cmpl $2*node_size,%nargs)
5089        __(jz local_label(rtwo))
5090        /* One arg was passed, could be one or two inherited args */
5091        __(cmpw $node_size,%imm0_w)
5092        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_y)
5093        __(je local_label(rgo))
5094        __(movq misc_data_offset-(node_size*2)(%fn,%temp1),%arg_x)
5095        __(jmp local_label(rgo))
5096local_label(rtwo):     
5097        __(movq misc_data_offset-node_size(%fn,%temp1),%arg_x)
5098        __(jmp local_label(rgo))
5099_endsubp(call_closure)
5100                                       
5101       
5102_spentry(poweropen_callbackX)
5103_endsubp(poweropen_callbackX)
5104       
5105       
5106_spentry(poweropen_ffcallX)
5107_endsubp(poweropen_ffcallX)
5108               
5109_spentry(poweropen_syscall)
5110_endsubp(poweropen_syscall)
5111
5112_spentry(eabi_ff_call)
5113_endsubp(eabi_ff_call)
5114
5115_spentry(eabi_callback)
5116_endsubp(eabi_callback)
5117
5118
5119/* Unused, and often not used on PPC either  */
5120_spentry(callbuiltin)
5121        __(hlt)
5122_endsubp(callbuiltin)
5123
5124_spentry(callbuiltin0)
5125        __(hlt)
5126_endsubp(callbuiltin0)
5127
5128_spentry(callbuiltin1)
5129        __(hlt)
5130_endsubp(callbuiltin1)
5131
5132_spentry(callbuiltin2)
5133        __(hlt)
5134_endsubp(callbuiltin2)
5135
5136_spentry(callbuiltin3)
5137        __(hlt)
5138_endsubp(callbuiltin3)
5139       
5140_spentry(restorefullcontext)
5141        __(hlt)
5142_endsubp(restorefullcontext)
5143
5144_spentry(savecontextvsp)
5145        __(hlt)
5146_endsubp(savecontextvsp)
5147
5148_spentry(savecontext0)
5149        __(hlt)
5150_endsubp(savecontext0)
5151
5152_spentry(restorecontext)
5153        __(hlt)
5154_endsubp(restorecontext)
5155
5156_spentry(stkconsyz)
5157        __(hlt)
5158_endsubp(stkconsyz)
5159
5160_spentry(stkvcell0)
5161        __(hlt)
5162_endsubp(stkvcell0)
5163
5164_spentry(stkvcellvsp)
5165        __(hlt)
5166_endsubp(stkvcellvsp)
5167
5168_spentry(breakpoint)
5169        __(hlt)
5170_endsubp(breakpoint)
5171
5172
5173        __ifdef(`DARWIN')
5174        .if 1
5175        .globl  C(lisp_objc_personality)
5176C(lisp_objc_personality):
5177        jmp *lisp_global(objc_2_personality)
5178       
5179        .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
5180EH_frame1:
5181        .set L$set$12,LECIE1-LSCIE1
5182        .long L$set$12  /* Length of Common Information Entry */
5183LSCIE1:
5184        .long   0x0     /* CIE Identifier Tag */
5185        .byte   0x1     /* CIE Version */
5186        .ascii "zPLR\0" /* CIE Augmentation */
5187        .byte   0x1     /* uleb128 0x1; CIE Code Alignment Factor */
5188        .byte   0x78    /* sleb128 -8; CIE Data Alignment Factor */
5189        .byte   0x10    /* CIE RA Column */
5190        .byte   0x7
5191        .byte   0x9b
5192        .long   _lisp_objc_personality+4@GOTPCREL
5193        .byte   0x10    /* LSDA Encoding (pcrel) */
5194        .byte   0x10    /* FDE Encoding (pcrel) */
5195        .byte   0xc     /* DW_CFA_def_cfa */
5196        .byte   0x7     /* uleb128 0x7 */
5197        .byte   0x8     /* uleb128 0x8 */
5198        .byte   0x90    /* DW_CFA_offset, column 0x10 */
5199        .byte   0x1     /* uleb128 0x1 */
5200        .align 3
5201LECIE1:
5202        .globl _SPffcall.eh
5203_SPffcall.eh:
5204        .long LEFDEffcall-LSFDEffcall
5205LSFDEffcall:     
5206        .long LSFDEffcall-EH_frame1 /* FDE CIE offset */
5207        .quad Lffcall-. /* FDE Initial Location */
5208        .quad Lffcall_end-Lffcall /* FDE address range */
5209        .byte 8 /* uleb128 0x8; Augmentation size */
5210        .quad LLSDA1-.           /* Language Specific Data Area */
5211        .byte   0x4     /* DW_CFA_advance_loc4 */
5212        .long Lffcall_setup-Lffcall
5213        .byte   0xe     /* DW_CFA_def_cfa_offset */
5214        .byte   0x10    /* uleb128 0x10 */
5215        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5216        .byte   0x2     /* uleb128 0x2 */
5217        .byte   0x4     /* DW_CFA_advance_loc4 */
5218        .long Lffcall_setup_end-Lffcall_setup
5219        .byte   0xd     /* DW_CFA_def_cfa_register */
5220        .byte   0x6     /* uleb128 0x6 */
5221        .byte   0x4     /* DW_CFA_advance_loc4 */
5222        .long Lffcall_call_end-Lffcall_call
5223        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5224        .byte   0x3     /* uleb128 0x3 */
5225        .align 3
5226LEFDEffcall:
5227        .globl _SPffcall_return_registers.eh
5228_SPffcall_return_registers.eh:
5229        .long LEFDEffcall_return_registers-LSFDEffcall_return_registers
5230LSFDEffcall_return_registers:     
5231        .long LSFDEffcall_return_registers-EH_frame1 /* FDE CIE offset */
5232        .quad Lffcall_return_registers-. /* FDE Initial Location */
5233        .quad Lffcall_return_registers_end-Lffcall_return_registers /* FDE address range */
5234        .byte 8 /* uleb128 0x8; Augmentation size */
5235        .quad LLSDA2-.           /* Language Specific Data Area */
5236        .byte   0x4     /* DW_CFA_advance_loc4 */
5237        .long Lffcall_return_registers_setup-Lffcall_return_registers
5238        .byte   0xe     /* DW_CFA_def_cfa_offset */
5239        .byte   0x10    /* uleb128 0x10 */
5240        .byte   0x86    /* DW_CFA_offset, column 0x6 */
5241        .byte   0x2     /* uleb128 0x2 */
5242        .byte   0x4     /* DW_CFA_advance_loc4 */
5243        .long Lffcall_return_registers_setup_end-Lffcall_return_registers_setup
5244        .byte   0xd     /* DW_CFA_def_cfa_register */
5245        .byte   0x6     /* uleb128 0x6 */
5246        .byte   0x4     /* DW_CFA_advance_loc4 */
5247        .long Lffcall_return_registers_call_end-Lffcall_return_registers_call
5248        .byte   0x83    /* DW_CFA_offset, column 0x3 */
5249        .byte   0x3     /* uleb128 0x3 */
5250        .align 3
5251LEFDEffcall_return_registers:
5252        .text
5253        .endif
5254        __endif
5255       
5256_spentry(unused_5)
5257        __(hlt)
5258Xspentry_end:           
5259_endsubp(unused_5)
5260       
5261        .data
5262        .globl C(spentry_start)
5263        .globl C(spentry_end)
5264C(spentry_start):       .quad Xspentry_start
5265C(spentry_end):         .quad Xspentry_end
Note: See TracBrowser for help on using the repository browser.