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

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

Start new scheme: maintain a second bitmap with 1 bit for every 256
in the global ephemeral refmap. (According too my calculations, this
should be ... 256X smaller than the refmap and should be easier to
traverse on machines with relatively small caches.

So far, we just allocate it (at overestimated maximum size) and map
it all read/write. Maintain this in the write barrier on x86 (so far)
and in pc_luser_xp's emulation of the write barrier

Todo: map at correct size and associate with managed_static
and tenured areas, and actually traverse this.

Last commit added a kernel global to support this.

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