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

Last change on this file since 15823 was 15823, checked in by gb, 7 years ago

Still not working; may not be for another few days.
Will create a branch for this and revert trunk.

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