source: branches/ia32/lisp-kernel/x86-spentry32.s @ 8835

Last change on this file since 8835 was 8835, checked in by rme, 12 years ago

_SPnthrowvalues: actually save %temp1/%nargs (to %mm2) before using
it to build the TSP frame. Now the instruction that restores
%temp1/%nargs from %mm2 afterwards will be much more useful.

File size: 104.4 KB
Line 
1        include(lisp.s)
2        _beginfile
3
4        .align 2
5define([_spentry],[ifdef([__func_name],[_endfn],[])
6        .p2align 3
7        _exportfn(_SP$1)
8])
9
10define([_endsubp],[
11        _endfn(_SP$1)
12])
13
14define([jump_builtin],[
15        ref_nrs_value(builtin_functions,%fname)
16        set_nargs($2)
17        vrefr(%fname,%fname,$1)
18        jump_fname()
19])
20
21_spentry(bad_funcall)
22        .globl C(bad_funcall)
23__(tra(C(bad_funcall)))
24        __(uuo_error_not_callable)
25_endsubp(bad_funcall)
26
27/* %arg_z has overflowed by one bit.  Make a bignum with 1 (32-bit) digit. */
28_spentry(fix_overflow)
29C(fix_one_bit_overflow):
30        __(movl $one_digit_bignum_header,%imm0)
31        __(movd %imm0,%mm0)
32        __(Misc_Alloc_Fixed([],aligned_bignum_size(1)))
33        __(unbox_fixnum(%arg_z,%imm0))
34        __(xor $0xc0000000,%imm0)
35        __(mov %temp0,%arg_z)
36        __(movl %imm0,misc_data_offset(%arg_z))
37        __(ret)
38_endsubp(fix_overflow)
39
40/* %arg_y = vector, %arg_z = unscaled-idx */
41_spentry(misc_ref)
42        __(int $3)
43        __(mov %arg_y,%imm0)
44        __(andb $tagmask,%imm0_b)
45        __(cmpb $tag_misc,%imm0_b)
46        __(je,pt 0f)
47        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
480:      __(testb $fixnummask,%arg_z_b)
49        __(je,pt 1f)
50        __(uuo_error_reg_not_fixnum(Rarg_z))
511:      __(movl misc_header_offset(%arg_y),%imm0)
52        __(xorb %imm0_b,%imm0_b)
53        __(shrl $num_subtag_bits-fixnumshift,%imm0)
54        __(jb,pt 2f)
55        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
56        __(xorl %imm0,%imm0)
57        __(movb misc_subtag_offset(%arg_y),%imm0_b)
58        /* fall through */
59_endsubp(misc_ref)
60
61/* %imm0 = subtag, %arg_y = vector, %arg_z = index. */
62/* Bounds/type-checking done in caller. */
63_startfn(C(misc_ref_common))
64        __(leal local_label(misc_ref_jmp)(,%imm0,4),%imm0)
65        __(jmp *(%imm0))
66        .p2align 2
67local_label(misc_ref_jmp):
68        /* 00-0f */
69        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
70        .long local_label(misc_ref_invalid) /* 01 cons  */
71        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
72        .long local_label(misc_ref_invalid) /* 03 imm  */
73        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
74        .long local_label(misc_ref_invalid) /* 05 tra  */
75        .long local_label(misc_ref_invalid) /* 06 misc  */
76        .long local_label(misc_ref_u32) /* 07 bignum  */
77        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
78        .long local_label(misc_ref_invalid) /* 09 cons  */
79        .long local_label(misc_ref_node) /* 0a ratio  */
80        .long local_label(misc_ref_invalid) /* 0b imm  */
81        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
82        .long local_label(misc_ref_invalid) /* 0d tra  */
83        .long local_label(misc_ref_invalid) /* 0e misc  */
84        .long local_label(misc_ref_u32) /* 0f single_float  */
85        /* 10-1*/
86        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
87        .long local_label(misc_ref_invalid) /* 11 cons  */
88        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
89        .long local_label(misc_ref_invalid) /* 13 imm  */
90        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
91        .long local_label(misc_ref_invalid) /* 15 tra  */
92        .long local_label(misc_ref_invalid) /* 16 misc  */
93        .long local_label(misc_ref_u32) /* 17 double_float  */
94        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
95        .long local_label(misc_ref_invalid) /* 19 cons  */
96        .long local_label(misc_ref_node) /* 1a complex  */
97        .long local_label(misc_ref_invalid) /* 1b imm  */
98        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
99        .long local_label(misc_ref_invalid) /* 1d tra  */
100        .long local_label(misc_ref_invalid) /* 1e misc  */
101        .long local_label(misc_ref_u32) /* 1f macptr  */
102        /* 20-2*/
103        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
104        .long local_label(misc_ref_invalid) /* 21 cons  */
105        .long local_label(misc_ref_invalid) /* 22 catch_frame  */
106        .long local_label(misc_ref_invalid) /* 23 imm  */
107        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
108        .long local_label(misc_ref_invalid) /* 25 tra  */
109        .long local_label(misc_ref_invalid) /* 26 misc  */
110        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
111        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
112        .long local_label(misc_ref_invalid) /* 29 cons  */
113        .long local_label(misc_ref_function) /* 2a function  */
114        .long local_label(misc_ref_invalid) /* 2b imm  */
115        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
116        .long local_label(misc_ref_invalid) /* 2d tra  */
117        .long local_label(misc_ref_invalid) /* 2e misc  */
118        .long local_label(misc_ref_invalid) /* 2f immheader  */
119        /* 30-3*/
120        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
121        .long local_label(misc_ref_invalid) /* 31 cons  */
122        .long local_label(misc_ref_invalid) /* 32 nodeheader  */
123        .long local_label(misc_ref_invalid) /* 33 imm  */
124        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
125        .long local_label(misc_ref_invalid) /* 35 tra  */
126        .long local_label(misc_ref_invalid) /* 36 misc  */
127        .long local_label(misc_ref_invalid) /* 37 immheader  */
128        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
129        .long local_label(misc_ref_invalid) /* 39 cons  */
130        .long local_label(misc_ref_node) /* 3a symbol  */
131        .long local_label(misc_ref_invalid) /* 3b imm  */
132        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
133        .long local_label(misc_ref_invalid) /* 3d tra  */
134        .long local_label(misc_ref_invalid) /* 3e misc  */
135        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
136        /* 40-4*/
137        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
138        .long local_label(misc_ref_invalid) /* 41 cons  */
139        .long local_label(misc_ref_node) /* 42 lock  */
140        .long local_label(misc_ref_invalid) /* 43 imm  */
141        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
142        .long local_label(misc_ref_invalid) /* 45 tra  */
143        .long local_label(misc_ref_invalid) /* 46 misc  */
144        .long local_label(misc_ref_invalid) /* 47 immheader  */
145        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
146        .long local_label(misc_ref_invalid) /* 49 cons  */
147        .long local_label(misc_ref_node) /* 4a hash_vector  */
148        .long local_label(misc_ref_invalid) /* 4b imm  */
149        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
150        .long local_label(misc_ref_invalid) /* 4d tra  */
151        .long local_label(misc_ref_invalid) /* 4e misc  */
152        .long local_label(misc_ref_invalid) /* 4f immheader  */
153        /* 50-5*/
154        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
155        .long local_label(misc_ref_invalid) /* 51 cons  */
156        .long local_label(misc_ref_node) /* 52 pool  */
157        .long local_label(misc_ref_invalid) /* 53 imm  */
158        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
159        .long local_label(misc_ref_invalid) /* 55 tra  */
160        .long local_label(misc_ref_invalid) /* 56 misc  */
161        .long local_label(misc_ref_invalid) /* 57 immheader  */
162        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
163        .long local_label(misc_ref_invalid) /* 59 cons  */
164        .long local_label(misc_ref_node) /* 5a weak  */
165        .long local_label(misc_ref_invalid) /* 5b imm  */
166        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
167        .long local_label(misc_ref_invalid) /* 5d tra  */
168        .long local_label(misc_ref_invalid) /* 5e misc  */
169        .long local_label(misc_ref_invalid) /* 5f immheader  */
170        /* 60-6*/
171        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
172        .long local_label(misc_ref_invalid) /* 61 cons  */
173        .long local_label(misc_ref_node) /* 62 package  */
174        .long local_label(misc_ref_invalid) /* 63 imm  */
175        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
176        .long local_label(misc_ref_invalid) /* 65 tra  */
177        .long local_label(misc_ref_invalid) /* 66 misc  */
178        .long local_label(misc_ref_invalid) /* 67 immheader  */
179        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
180        .long local_label(misc_ref_invalid) /* 69 cons  */
181        .long local_label(misc_ref_node) /* 6a slot_vector  */
182        .long local_label(misc_ref_invalid) /* 6b imm  */
183        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
184        .long local_label(misc_ref_invalid) /* 6d tra  */
185        .long local_label(misc_ref_invalid) /* 6e misc  */
186        .long local_label(misc_ref_invalid) /* 6f immheader  */
187        /* 70-7*/
188        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
189        .long local_label(misc_ref_invalid) /* 71 cons  */
190        .long local_label(misc_ref_node) /* 72 instance  */
191        .long local_label(misc_ref_invalid) /* 73 imm  */
192        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
193        .long local_label(misc_ref_invalid) /* 75 tra  */
194        .long local_label(misc_ref_invalid) /* 76 misc  */
195        .long local_label(misc_ref_invalid) /* 77 immheader  */
196        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
197        .long local_label(misc_ref_invalid) /* 79 cons  */
198        .long local_label(misc_ref_node) /* 7a struct  */
199        .long local_label(misc_ref_invalid) /* 7b imm  */
200        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
201        .long local_label(misc_ref_invalid) /* 7d tra  */
202        .long local_label(misc_ref_invalid) /* 7e misc  */
203        .long local_label(misc_ref_invalid) /* 7f immheader  */
204        /* 80-8*/
205        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
206        .long local_label(misc_ref_invalid) /* 81 cons  */
207        .long local_label(misc_ref_node) /* 82 istruct  */
208        .long local_label(misc_ref_invalid) /* 83 imm  */
209        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
210        .long local_label(misc_ref_invalid) /* 85 tra  */
211        .long local_label(misc_ref_invalid) /* 86 misc  */
212        .long local_label(misc_ref_invalid) /* 87 immheader  */
213        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
214        .long local_label(misc_ref_invalid) /* 89 cons  */
215        .long local_label(misc_ref_node) /* 8a value_cell  */
216        .long local_label(misc_ref_invalid) /* 8b imm  */
217        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
218        .long local_label(misc_ref_invalid) /* 8d tra  */
219        .long local_label(misc_ref_invalid) /* 8e misc  */
220        .long local_label(misc_ref_invalid) /* 8f immheader  */
221        /* 90-9*/
222        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
223        .long local_label(misc_ref_invalid) /* 91 cons  */
224        .long local_label(misc_ref_node) /* 92 xfunction  */
225        .long local_label(misc_ref_invalid) /* 93 imm  */
226        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
227        .long local_label(misc_ref_invalid) /* 95 tra  */
228        .long local_label(misc_ref_invalid) /* 96 misc  */
229        .long local_label(misc_ref_invalid) /* 97 immheader  */
230        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
231        .long local_label(misc_ref_invalid) /* 99 cons  */
232        .long local_label(misc_ref_node) /* 9a arrayH  */
233        .long local_label(misc_ref_invalid) /* 9b imm  */
234        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
235        .long local_label(misc_ref_invalid) /* 9d tra  */
236        .long local_label(misc_ref_invalid) /* 9e misc  */
237        .long local_label(misc_ref_invalid) /* 9f immheader  */
238        /* a0-af  */
239        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
240        .long local_label(misc_ref_invalid) /* a1 cons  */
241        .long local_label(misc_ref_node) /* a2 vectorH  */
242        .long local_label(misc_ref_invalid) /* a3 imm  */
243        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
244        .long local_label(misc_ref_invalid) /* a5 tra  */
245        .long local_label(misc_ref_invalid) /* a6 misc  */
246        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
247        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
248        .long local_label(misc_ref_invalid) /* a9 cons  */
249        .long local_label(misc_ref_node) /* aa simple_vector  */
250        .long local_label(misc_ref_invalid) /* ab imm  */
251        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
252        .long local_label(misc_ref_invalid) /* ad tra  */
253        .long local_label(misc_ref_invalid) /* ae misc  */
254        .long local_label(misc_ref_u32) /* af u32  */
255        /* b0-bf  */
256        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
257        .long local_label(misc_ref_invalid) /* b1 cons  */
258        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
259        .long local_label(misc_ref_invalid) /* b3 imm  */
260        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
261        .long local_label(misc_ref_invalid) /* b5 tra  */
262        .long local_label(misc_ref_invalid) /* b6 misc  */
263        .long local_label(misc_ref_s32) /* b7 s32  */
264        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
265        .long local_label(misc_ref_invalid) /* b9 cons  */
266        .long local_label(misc_ref_invalid) /* ba nodeheader  */
267        .long local_label(misc_ref_invalid) /* bb imm  */
268        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
269        .long local_label(misc_ref_invalid) /* bd tra  */
270        .long local_label(misc_ref_invalid) /* be misc  */
271        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
272        /* c0-cf  */
273        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
274        .long local_label(misc_ref_invalid) /* c1 cons  */
275        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
276        .long local_label(misc_ref_invalid) /* c3 imm  */
277        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
278        .long local_label(misc_ref_invalid) /* c5 tra  */
279        .long local_label(misc_ref_invalid) /* c6 misc  */
280        .long local_label(misc_ref_string) /* c7 simple_base_string  */
281        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
282        .long local_label(misc_ref_invalid) /* c9 cons  */
283        .long local_label(misc_ref_invalid) /* ca nodeheader  */
284        .long local_label(misc_ref_invalid) /* cb imm  */
285        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
286        .long local_label(misc_ref_invalid) /* cd tra  */
287        .long local_label(misc_ref_invalid) /* ce misc  */
288        .long local_label(misc_ref_u8) /* cf u8  */
289        /* d0-df  */
290        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
291        .long local_label(misc_ref_invalid) /* d1 cons  */
292        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
293        .long local_label(misc_ref_invalid) /* d3 imm  */
294        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
295        .long local_label(misc_ref_invalid) /* d5 tra  */
296        .long local_label(misc_ref_invalid) /* d6 misc  */
297        .long local_label(misc_ref_s8)      /* d7 s8  */
298        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
299        .long local_label(misc_ref_invalid) /* d9 cons  */
300        .long local_label(misc_ref_invalid) /* da nodeheader  */
301        .long local_label(misc_ref_invalid) /* db imm  */
302        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
303        .long local_label(misc_ref_invalid) /* dd tra  */
304        .long local_label(misc_ref_invalid) /* de misc  */
305        .long local_label(misc_ref_invalid) /* df immheader  */
306        /* e0-ef  */
307        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
308        .long local_label(misc_ref_invalid) /* e1 cons  */
309        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
310        .long local_label(misc_ref_invalid) /* e3 imm  */
311        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
312        .long local_label(misc_ref_invalid) /* e5 tra  */
313        .long local_label(misc_ref_invalid) /* e6 misc  */
314        .long local_label(misc_ref_u16) /* e7 u16  */
315        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
316        .long local_label(misc_ref_invalid) /* e9 cons  */
317        .long local_label(misc_ref_invalid) /* ea nodeheader  */
318        .long local_label(misc_ref_invalid) /* eb imm  */
319        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
320        .long local_label(misc_ref_invalid) /* ed tra  */
321        .long local_label(misc_ref_invalid) /* ee misc  */
322        .long local_label(misc_ref_s16) /* ef s16  */
323        /* f0-ff  */
324        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
325        .long local_label(misc_ref_invalid) /* f1 cons  */
326        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
327        .long local_label(misc_ref_invalid) /* f3 imm  */
328        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
329        .long local_label(misc_ref_invalid) /* f5 tra  */
330        .long local_label(misc_ref_invalid) /* f6 misc  */
331        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
332        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
333        .long local_label(misc_ref_invalid) /* f9 cons  */
334        .long local_label(misc_ref_invalid) /* fa nodeheader  */
335        .long local_label(misc_ref_invalid) /* fb imm  */
336        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
337        .long local_label(misc_ref_invalid) /* fd tra  */
338        .long local_label(misc_ref_invalid) /* fe misc  */
339        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
340
341/* Functions are funny.  The first N words are treated as */
342/* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
343
344local_label(misc_ref_function):
345        __(movzwl misc_data_offset(%arg_y), %imm0)
346        __(shl $fixnumshift,%imm0)
347        __(rcmpl(%arg_z,%imm0))
348        __(jb local_label(misc_ref_u32))
349local_label(misc_ref_node):
350        __(movl misc_data_offset(%arg_y,%arg_z),%arg_z)
351        __(ret)
352local_label(misc_ref_u32):
353        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
354        __(jmp _SPmakeu32)
355local_label(misc_ref_s32):
356        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
357        __(jmp _SPmakes32)
358local_label(misc_ref_single_float_vector):
359        __(movss misc_data_offset(%arg_y,%arg_z),%fp1)
360        __(movl $single_float_header,%imm0)
361        __(movd %imm0,%mm0)
362        __(Misc_Alloc_Fixed(%arg_z,single_float.size))
363        __(movss %fp1,single_float.value(%arg_z))
364        __(ret)
365local_label(misc_ref_double_float_vector):
366        __(movsd misc_dfloat_offset(%arg_y,%arg_z),%fp1)
367        __(movl $double_float_header,%imm0)
368        __(movd %imm0,%mm0)
369        __(Misc_Alloc_Fixed(%arg_z,double_float.size))
370        __(movsd %fp1,double_float.value(%arg_z))
371        __(ret)
372local_label(misc_ref_fixnum_vector):
373        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
374        __(box_fixnum(%imm0,%arg_z))
375        __(ret)
376local_label(misc_ref_u8):
377        __(movl %arg_z,%imm0)
378        __(shr $2,%imm0)
379        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0)
380        __(box_fixnum(%imm0,%arg_z))
381        __(ret)
382local_label(misc_ref_s8):
383        __(movl %arg_z,%imm0)
384        __(shr $2,%imm0)
385        __(movsbl misc_data_offset(%arg_y,%imm0),%imm0)
386        __(box_fixnum(%imm0,%arg_z))
387        __(ret)
388local_label(misc_ref_string):
389        __(movl %arg_z,%imm0)
390        __(movl misc_data_offset(%arg_y,%imm0),%imm0)
391        __(shll $charcode_shift,%imm0)
392        __(leal subtag_character(%imm0),%arg_z)
393        __(ret)
394local_label(misc_ref_u16):
395        __(movl %arg_z,%imm0)
396        __(shrl $1,%imm0)
397        __(movzwl misc_data_offset(%arg_y,%imm0),%imm0)
398        __(box_fixnum(%imm0,%arg_z))
399        __(ret)
400local_label(misc_ref_s16):
401        __(movl %arg_z,%imm0)
402        __(shrl $1,%imm0)
403        __(movswl misc_data_offset(%arg_y,%imm0),%imm0)
404        __(box_fixnum(%imm0,%arg_z))
405        __(ret)
406local_label(misc_ref_bit_vector):
407        __(unbox_fixnum(%arg_z,%imm0))
408        __(btl %imm0,misc_data_offset(%arg_y))
409        __(setc %imm0_b)
410        __(movzbl %imm0_b,%imm0)
411        __(box_fixnum(%imm0,%arg_z))
412        __(ret)
413local_label(misc_ref_invalid):
414        __(push $reserved_frame_marker)
415        __(push $reserved_frame_marker)
416        __(push $XBADVEC)
417        __(set_nargs(3))
418        __(jmp _SPksignalerr)
419_endfn(C(misc_ref_common))
420
421/* Like misc_ref, only the boxed subtag is in temp0. */
422_spentry(subtag_misc_ref)
423        __(mov %arg_y,%imm0)
424        __(and $tagmask,%imm0)
425        __(cmp $tag_misc,%imm0)
426        __(je,pt 0f)
427        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
4280:      __(testb $fixnummask,%arg_z_b)
429        __(je,pt 1f)
430        __(uuo_error_reg_not_fixnum(Rarg_z))
4311:      __(movl misc_header_offset(%arg_y),%imm0)
432        __(xorb %imm0_b,%imm0_b)
433        __(shrl $num_subtag_bits-fixnumshift,%imm0)
434        __(cmp %imm0,%arg_z)
435        __(jb 2f)
436        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
4372:      __(unbox_fixnum(%temp0,%imm0))
438        __(jmp C(misc_ref_common))
439_endsubp(subtag_misc_ref)
440
441/* Like misc_set, only the boxed subtag is in temp1. */
442_spentry(subtag_misc_set)
443        __(int $3)
444        __(mov %temp0,%imm0)
445        __(andb $tagmask,%imm0_b)
446        __(cmpb $tag_misc,%imm0_b)
447        __(je,pt 0f)
448        __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4490:      __(mov %arg_y,%imm0)
450        __(testb $fixnummask,%imm0_b)
451        __(je,pt 1f)
452        __(uuo_error_reg_not_fixnum(Rarg_y))
4531:      __(movl misc_header_offset(%temp0),%imm0)
454        __(xorb %imm0_b,%imm0_b)
455        __(shrl $num_subtag_bits-fixnumshift,%imm0)
456        __(cmpl %imm0,%arg_y)
457        __(jb 2f)
458        __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
4592:      __(unbox_fixnum(%temp1,%imm0))
460        __(jmp C(misc_set_common))
461_endsubp(subtag_misc_set)
462
463/* %temp0 = vector, %arg_y = unscaled-idx, %arg_z = val */
464_spentry(misc_set)
465        __(mov %temp0,%imm0)
466        __(andb $tagmask,%imm0_b)
467        __(cmpb $tag_misc,%imm0_b)
468        __(je,pt 0f)
469        __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4700:      __(mov %arg_y,%imm0)    /* no byte reg for %arg_y/%esi */
471        __(testb $fixnummask,%imm0_b)
472        __(je,pt 1f)
473        __(uuo_error_reg_not_fixnum(Rarg_y))
4741:      __(movl misc_header_offset(%temp0),%imm0)
475        __(xorb %imm0_b,%imm0_b)
476        __(shrl $num_subtag_bits-fixnumshift,%imm0)
477        __(cmpl %imm0,%arg_y)
478        __(jb 2f)
479        __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
4802:      __(xorl %imm0,%imm0)
481        __(movb misc_subtag_offset(%temp0),%imm0_b)
482        /* fall through */
483_endsubp(misc_set)
484
485/* imm0 = subtag, %temp0 = vector, %arg_y = index, %arg_z = value */
486_startfn(C(misc_set_common))
487        __(leal local_label(misc_set_jmp)(,%imm0,4),%imm0)
488        __(jmp *(%imm0))
489        .p2align 2
490local_label(misc_set_jmp):
491        /* 00-0f */
492        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
493        .long local_label(misc_set_invalid) /* 01 cons  */
494        .long local_label(misc_set_invalid) /* 02 nodeheader  */
495        .long local_label(misc_set_invalid) /* 03 imm  */
496        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
497        .long local_label(misc_set_invalid) /* 05 tra  */
498        .long local_label(misc_set_invalid) /* 06 misc  */
499        .long local_label(misc_set_u32) /* 07 bignum  */
500        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
501        .long local_label(misc_set_invalid) /* 09 cons  */
502        .long _SPgvset /* 0a ratio  */
503        .long local_label(misc_set_invalid) /* 0b imm  */
504        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
505        .long local_label(misc_set_invalid) /* 0d tra  */
506        .long local_label(misc_set_invalid) /* 0e misc  */
507        .long local_label(misc_set_u32) /* 0f single_float  */
508        /* 10-1f  */
509        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
510        .long local_label(misc_set_invalid) /* 11 cons  */
511        .long local_label(misc_set_invalid) /* 12 nodeheader  */
512        .long local_label(misc_set_invalid) /* 13 imm  */
513        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
514        .long local_label(misc_set_invalid) /* 15 tra  */
515        .long local_label(misc_set_invalid) /* 16 misc  */
516        .long local_label(misc_set_u32) /* 17 double_float  */
517        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
518        .long local_label(misc_set_invalid) /* 19 cons  */
519        .long _SPgvset /* 1a complex  */
520        .long local_label(misc_set_invalid) /* 1b imm  */
521        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
522        .long local_label(misc_set_invalid) /* 1d tra  */
523        .long local_label(misc_set_invalid) /* 1e misc  */
524        .long local_label(misc_set_u32) /* 1f macptr  */
525        /* 20-2f  */
526        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
527        .long local_label(misc_set_invalid) /* 21 cons  */
528        .long local_label(misc_set_invalid) /* 22 catch_frame  */
529        .long local_label(misc_set_invalid) /* 23 imm  */
530        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
531        .long local_label(misc_set_invalid) /* 25 tra  */
532        .long local_label(misc_set_invalid) /* 26 misc  */
533        .long local_label(misc_set_u32) /* 27 dead_macptr  */
534        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
535        .long local_label(misc_set_invalid) /* 29 cons  */
536        .long local_label(misc_set_function) /* 2a function  */
537        .long local_label(misc_set_invalid) /* 2b imm  */
538        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
539        .long local_label(misc_set_invalid) /* 2d tra  */
540        .long local_label(misc_set_invalid) /* 2e misc  */
541        .long local_label(misc_set_invalid) /* 2f immheader  */
542        /* 30-3f  */
543        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
544        .long local_label(misc_set_invalid) /* 31 cons  */
545        .long local_label(misc_set_invalid) /* 32 nodeheader  */
546        .long local_label(misc_set_invalid) /* 33 imm  */
547        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
548        .long local_label(misc_set_invalid) /* 35 tra  */
549        .long local_label(misc_set_invalid) /* 36 misc  */
550        .long local_label(misc_set_invalid) /* 37 immheader  */
551        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
552        .long local_label(misc_set_invalid) /* 39 cons  */
553        .long _SPgvset /* 3a symbol  */
554        .long local_label(misc_set_invalid) /* 3b imm  */
555        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
556        .long local_label(misc_set_invalid) /* 3d tra  */
557        .long local_label(misc_set_invalid) /* 3e misc  */
558        .long local_label(misc_set_u32) /* 3f xcode_vector  */
559        /* 40-4f  */
560        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
561        .long local_label(misc_set_invalid) /* 41 cons  */
562        .long _SPgvset /* 42 lock  */
563        .long local_label(misc_set_invalid) /* 43 imm  */
564        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
565        .long local_label(misc_set_invalid) /* 45 tra  */
566        .long local_label(misc_set_invalid) /* 46 misc  */
567        .long local_label(misc_set_invalid) /* 47 immheader  */
568        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
569        .long local_label(misc_set_invalid) /* 49 cons  */
570        .long _SPgvset /* 4a hash_vector  */
571        .long local_label(misc_set_invalid) /* 4b imm  */
572        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
573        .long local_label(misc_set_invalid) /* 4d tra  */
574        .long local_label(misc_set_invalid) /* 4e misc  */
575        .long local_label(misc_set_invalid) /* 4f immheader  */
576        /* 50-5f  */
577        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
578        .long local_label(misc_set_invalid) /* 51 cons  */
579        .long _SPgvset /* 52 pool  */
580        .long local_label(misc_set_invalid) /* 53 imm  */
581        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
582        .long local_label(misc_set_invalid) /* 55 tra  */
583        .long local_label(misc_set_invalid) /* 56 misc  */
584        .long local_label(misc_set_invalid) /* 57 immheader  */
585        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
586        .long local_label(misc_set_invalid) /* 59 cons  */
587        .long _SPgvset /* 5a weak  */
588        .long local_label(misc_set_invalid) /* 5b imm  */
589        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
590        .long local_label(misc_set_invalid) /* 5d tra  */
591        .long local_label(misc_set_invalid) /* 5e misc  */
592        .long local_label(misc_set_invalid) /* 5f immheader  */
593        /* 60-6f  */
594        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
595        .long local_label(misc_set_invalid) /* 61 cons  */
596        .long _SPgvset /* 62 package  */
597        .long local_label(misc_set_invalid) /* 63 imm  */
598        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
599        .long local_label(misc_set_invalid) /* 65 tra  */
600        .long local_label(misc_set_invalid) /* 66 misc  */
601        .long local_label(misc_set_invalid) /* 67 immheader  */
602        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
603        .long local_label(misc_set_invalid) /* 69 cons  */
604        .long _SPgvset /* 6a slot_vector  */
605        .long local_label(misc_set_invalid) /* 6b imm  */
606        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
607        .long local_label(misc_set_invalid) /* 6d tra  */
608        .long local_label(misc_set_invalid) /* 6e misc  */
609        .long local_label(misc_set_invalid) /* 6f immheader  */
610        /* 70-7f  */
611        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
612        .long local_label(misc_set_invalid) /* 71 cons  */
613        .long _SPgvset /* 72 instance  */
614        .long local_label(misc_set_invalid) /* 73 imm  */
615        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
616        .long local_label(misc_set_invalid) /* 75 tra  */
617        .long local_label(misc_set_invalid) /* 76 misc  */
618        .long local_label(misc_set_invalid) /* 77 immheader  */
619        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
620        .long local_label(misc_set_invalid) /* 79 cons  */
621        .long _SPgvset /* 7a struct  */
622        .long local_label(misc_set_invalid) /* 7b imm  */
623        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
624        .long local_label(misc_set_invalid) /* 7d tra  */
625        .long local_label(misc_set_invalid) /* 7e misc  */
626        .long local_label(misc_set_invalid) /* 7f immheader  */
627        /* 80-8f  */
628        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
629        .long local_label(misc_set_invalid) /* 81 cons  */
630        .long _SPgvset /* 82 istruct  */
631        .long local_label(misc_set_invalid) /* 83 imm  */
632        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
633        .long local_label(misc_set_invalid) /* 85 tra  */
634        .long local_label(misc_set_invalid) /* 86 misc  */
635        .long local_label(misc_set_invalid) /* 87 immheader  */
636        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
637        .long local_label(misc_set_invalid) /* 89 cons  */
638        .long _SPgvset /* 8a value_cell  */
639        .long local_label(misc_set_invalid) /* 8b imm  */
640        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
641        .long local_label(misc_set_invalid) /* 8d tra  */
642        .long local_label(misc_set_invalid) /* 8e misc  */
643        .long local_label(misc_set_invalid) /* 8f immheader  */
644        /* 90-9f  */
645        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
646        .long local_label(misc_set_invalid) /* 91 cons  */
647        .long _SPgvset /* 92 xfunction  */
648        .long local_label(misc_set_invalid) /* 93 imm  */
649        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
650        .long local_label(misc_set_invalid) /* 95 tra  */
651        .long local_label(misc_set_invalid) /* 96 misc  */
652        .long local_label(misc_set_invalid) /* 97 immheader  */
653        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
654        .long local_label(misc_set_invalid) /* 99 cons  */
655        .long _SPgvset /* 9a arrayH  */
656        .long local_label(misc_set_invalid) /* 9b imm  */
657        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
658        .long local_label(misc_set_invalid) /* 9d tra  */
659        .long local_label(misc_set_invalid) /* 9e misc  */
660        .long local_label(misc_set_invalid) /* 9f immheader  */
661        /* a0-af  */
662        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
663        .long local_label(misc_set_invalid) /* a1 cons  */
664        .long _SPgvset /* a2 vectorH  */
665        .long local_label(misc_set_invalid) /* a3 imm  */
666        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
667        .long local_label(misc_set_invalid) /* a5 tra  */
668        .long local_label(misc_set_invalid) /* a6 misc  */
669        .long local_label(misc_set_single_float_vector) /* a7 sf_vector  */
670        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
671        .long local_label(misc_set_invalid) /* a9 cons  */
672        .long _SPgvset /* aa simple_vector  */
673        .long local_label(misc_set_invalid) /* ab imm  */
674        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
675        .long local_label(misc_set_invalid) /* ad tra  */
676        .long local_label(misc_set_invalid) /* ae misc  */
677        .long local_label(misc_set_u32) /* af u32  */
678        /* b0-bf  */
679        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
680        .long local_label(misc_set_invalid) /* b1 cons  */
681        .long local_label(misc_set_invalid) /* b2 nodeheader  */
682        .long local_label(misc_set_invalid) /* b3 imm  */
683        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
684        .long local_label(misc_set_invalid) /* b5 tra  */
685        .long local_label(misc_set_invalid) /* b6 misc  */
686        .long local_label(misc_set_s32) /* b7 s32  */
687        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
688        .long local_label(misc_set_invalid) /* b9 cons  */
689        .long local_label(misc_set_invalid) /* ba nodeheader  */
690        .long local_label(misc_set_invalid) /* bb imm  */
691        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
692        .long local_label(misc_set_invalid) /* bd tra  */
693        .long local_label(misc_set_invalid) /* be misc  */
694        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
695        /* c0-cf  */
696        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
697        .long local_label(misc_set_invalid) /* c1 cons  */
698        .long local_label(misc_set_invalid) /* c2 nodeheader  */
699        .long local_label(misc_set_invalid) /* c3 imm  */
700        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
701        .long local_label(misc_set_invalid) /* c5 tra  */
702        .long local_label(misc_set_invalid) /* c6 misc  */
703        .long local_label(misc_set_string) /* c7 simple_base_string  */
704        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
705        .long local_label(misc_set_invalid) /* c9 cons  */
706        .long local_label(misc_set_invalid) /* ca nodeheader  */
707        .long local_label(misc_set_invalid) /* cb imm  */
708        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
709        .long local_label(misc_set_invalid) /* cd tra  */
710        .long local_label(misc_set_invalid) /* ce misc  */
711        .long local_label(misc_set_u8) /* cf u8  */
712        /* d0-df  */
713        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
714        .long local_label(misc_set_invalid) /* d1 cons  */
715        .long local_label(misc_set_invalid) /* d2 nodeheader  */
716        .long local_label(misc_set_invalid) /* d3 imm  */
717        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
718        .long local_label(misc_set_invalid) /* d5 tra  */
719        .long local_label(misc_set_invalid) /* d6 misc  */
720        .long local_label(misc_set_s8)      /* d7 s8  */
721        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
722        .long local_label(misc_set_invalid) /* d9 cons  */
723        .long local_label(misc_set_invalid) /* da nodeheader  */
724        .long local_label(misc_set_invalid) /* db imm  */
725        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
726        .long local_label(misc_set_invalid) /* dd tra  */
727        .long local_label(misc_set_invalid) /* de misc  */
728        .long local_label(misc_set_invalid) /* df immheader  */
729        /* e0-ef  */
730        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
731        .long local_label(misc_set_invalid) /* e1 cons  */
732        .long local_label(misc_set_invalid) /* e2 nodeheader  */
733        .long local_label(misc_set_invalid) /* e3 imm  */
734        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
735        .long local_label(misc_set_invalid) /* e5 tra  */
736        .long local_label(misc_set_invalid) /* e6 misc  */
737        .long local_label(misc_set_u16) /* e7 u16  */
738        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
739        .long local_label(misc_set_invalid) /* e9 cons  */
740        .long local_label(misc_set_invalid) /* ea nodeheader  */
741        .long local_label(misc_set_invalid) /* eb imm  */
742        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
743        .long local_label(misc_set_invalid) /* ed tra  */
744        .long local_label(misc_set_invalid) /* ee misc  */
745        .long local_label(misc_set_s16) /* ef s16  */
746        /* f0-ff  */
747        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
748        .long local_label(misc_set_invalid) /* f1 cons  */
749        .long local_label(misc_set_invalid) /* f2 nodeheader  */
750        .long local_label(misc_set_invalid) /* f3 imm  */
751        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
752        .long local_label(misc_set_invalid) /* f5 tra  */
753        .long local_label(misc_set_invalid) /* f6 misc  */
754        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
755        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
756        .long local_label(misc_set_invalid) /* f9 cons  */
757        .long local_label(misc_set_invalid) /* fa nodeheader  */
758        .long local_label(misc_set_invalid) /* fb imm  */
759        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
760        .long local_label(misc_set_invalid) /* fd tra  */
761        .long local_label(misc_set_invalid) /* fe misc  */
762        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
763
764local_label(misc_set_function):
765        /* Functions are funny: the first N words are treated as */
766        /* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
767        __(movzwl misc_data_offset(%temp0),%imm0)
768        __(shl $fixnumshift,%imm0)
769        __(rcmpl(%arg_y,%imm0))
770        __(jae _SPgvset)
771local_label(misc_set_u32):
772        /* Either a non-negative fixnum, a positive one-digit bignum, or */
773        /* a two-digit bignum whose sign-digit is 0 is OK. */
774        __(movl $~(target_most_positive_fixnum <<fixnumshift),%imm0)
775        __(test %arg_z,%imm0)
776        __(movl %arg_z,%imm0)
777        __(jne 1f)
778        __(sarl $fixnumshift,%imm0)
779        __(jmp 9f)
7801:      __(andb $tagmask,%imm0_b)
781        __(cmpb $tag_misc,%imm0_b)
782        __(jne local_label(misc_set_bad))
783        __(movb misc_subtag_offset(%arg_z),%imm0_b)
784        __(cmpb $subtag_bignum,%imm0_b)
785        __(jne local_label(misc_set_bad))
786        __(movl misc_header_offset(%arg_z),%imm0)
787        __(cmpl $two_digit_bignum_header,%imm0)
788        __(je 3f)
789        __(cmpl $one_digit_bignum_header,%imm0)
790        __(jne local_label(misc_set_bad))
791        __(movl misc_data_offset(%arg_z),%imm0)
792        __(testl %imm0,%imm0)
793        __(js local_label(misc_set_bad))
794        __(jmp 9f)
7953:      __(movl misc_data_offset(%arg_z),%imm0)
796        __(cmpl $0,misc_data_offset+4(%arg_z))
797        __(jne local_label(misc_set_bad))
7989:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
799        __(ret)
800local_label(misc_set_s32):
801        __(unbox_fixnum(%arg_z,%imm0))
802        __(testb $fixnummask,%arg_z_b)
803        __(je 9f)
8041:      __(movb %arg_z_b,%imm0_b)
805        __(andb $tagmask,%imm0_b)
806        __(cmpb $tag_misc,%imm0_b)
807        __(jne local_label(misc_set_bad))
808        __(movl misc_header_offset(%arg_z),%imm0)
809        __(cmpl $one_digit_bignum_header,%imm0)
810        __(jne local_label(misc_set_bad))
811        __(movl misc_data_offset(%arg_z),%imm0)
8129:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
813        __(ret)
814local_label(misc_set_bad):
815        __(movl %arg_z,%arg_y)
816        __(movl %temp0,%arg_z)
817        __(push $reserved_frame_marker)
818        __(push $reserved_frame_marker)
819        __(push $XNOTELT)
820        __(set_nargs(3))
821        __(jmp _SPksignalerr)
822local_label(misc_set_single_float_vector):
823        __(extract_lisptag(%arg_z,%imm0))
824        __(cmpb $tag_misc,%imm0_b)
825        __(jne local_label(misc_set_bad))
826        __(movb misc_subtag_offset(%arg_z),%imm0_b)
827        __(cmpb $subtag_single_float,%imm0_b)
828        __(jne local_label(misc_set_bad))
829        __(movl single_float.value(%arg_z),%imm0)
830        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
831        __(ret)
832local_label(misc_set_double_float_vector):
833        __(extract_lisptag(%arg_z,%imm0))
834        __(cmpb $tag_misc,%imm0_b)
835        __(jne local_label(misc_set_bad))
836        __(movb misc_subtag_offset(%arg_z),%imm0_b)
837        __(cmpb $subtag_double_float,%imm0_b)
838        __(jne local_label(misc_set_bad))
839        __(movsd double_float.value(%arg_z),%fp0)
840        __(movsd %fp0,misc_dfloat_offset(%temp0,%arg_y))
841        __(ret)
842local_label(misc_set_fixnum_vector):
843        __(unbox_fixnum(%arg_z,%imm0))
844        __(testb $fixnummask,%arg_z_b)
845        __(jne local_label(misc_set_bad))
846        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
847        __(ret)
848local_label(misc_set_u8):
849        __(testl $~(0xff<<fixnumshift),%arg_z)
850        __(jne local_label(misc_set_bad))
851        __(unbox_fixnum(%arg_y,%imm0))
852        __(movl %arg_z,%arg_y)
853        __(shll $8-fixnumshift,%arg_z)
854        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
855        __(movl %arg_y,%arg_z)
856        __(ret)
857local_label(misc_set_s8):
858        __(movl %arg_z,%imm0)
859        __(shll $32-(8+fixnumshift),%imm0)
860        __(sarl $32-(8+fixnumshift),%imm0)
861        __(cmpl %arg_z,%imm0)
862        __(jne local_label(misc_set_bad))
863        __(testb $fixnummask,%arg_z_b)
864        __(jne local_label(misc_set_bad))
865        __(unbox_fixnum(%arg_y,%imm0))
866        __(movl %arg_z,%arg_z)
867        __(shll $8-fixnumshift,%arg_z)
868        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
869        __(movl %arg_y,%arg_z)
870        __(ret)
871local_label(misc_set_string):
872        __(cmpb $subtag_character,%arg_z_b)
873        __(jne local_label(misc_set_bad))
874        __(movl %arg_z,%imm0)
875        __(shrl $charcode_shift,%imm0)
876        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
877        __(ret)
878local_label(misc_set_u16):
879        __(testl $~(0xffff<<fixnumshift),%arg_z)
880        __(jne local_label(misc_set_bad))
881        __(movl %arg_y,%imm0)
882        __(shrl $1,%imm0)
883        __(movl %arg_z,%arg_y)
884        /* If there's a better way, I'd be glad to hear of it. */
885        __(shll $8-fixnumshift,%arg_z)
886        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
887        __(xorb %arg_z_bh,%arg_z_bh)
888        __(shrl $8,%arg_z)
889        __(movb %arg_z_bh,misc_data_offset+1(%temp0,%imm0))
890        __(movl %arg_y,%arg_z)
891        __(ret)
892local_label(misc_set_s16):
893        __(movl %arg_z,%imm0)
894        __(shll $32-(16+fixnumshift),%imm0)
895        __(sarl $32-(16+fixnumshift),%imm0)
896        __(cmpl %arg_z,%imm0)
897        __(jne local_label(misc_set_bad))
898        __(testb $fixnummask,%arg_z_b)
899        __(jne local_label(misc_set_bad))
900        __(movl %arg_y,%imm0)
901        __(shrl $1,%imm0)
902        __(movl %arg_z,%arg_y)
903        /* If there's a better way, I'd be glad to hear of it. */
904        __(shll $8-fixnumshift,%arg_z)
905        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
906        __(xorb %arg_z_bh,%arg_z_bh)
907        __(sarl $8,%arg_z)
908        __(movb %arg_z_bh,misc_data_offset+1(%temp0,%imm0))
909        __(movl %arg_y,%arg_z)
910        __(ret)
911local_label(misc_set_bit_vector):
912        __(testl $~fixnumone,%arg_z)
913        __(jne local_label(misc_set_bad))
914        __(unbox_fixnum(%arg_y,%imm0))
915        __(testb %arg_z_b,%arg_z_b)
916        __(je local_label(misc_set_clr_bit))
917local_label(misc_set_set_bit):
918        __(btsl %imm0,misc_data_offset(%temp0))
919        __(ret)
920local_label(misc_set_clr_bit):
921        __(btrl %imm0,misc_data_offset(%temp0))
922        __(ret)
923local_label(misc_set_invalid):
924        __(push $reserved_frame_marker)
925        __(push $reserved_frame_marker)
926        __(push $XSETBADVEC)
927        __(push %temp0)
928        __(set_nargs(4))
929        __(jmp _SPksignalerr)
930_endfn(C(misc_set_common))
931
932_spentry(Fret1valn)
933        .globl C(ret1valn)
934__(tra(C(ret1valn)))
935        __(mov (%esp),%ra0)
936        __(mov %arg_z,(%esp))
937        __(set_nargs(1))
938        __(jmp *%ra0)
939_endsubp(Fret1valn)
940
941_spentry(nvalret)
942        .globl C(nvalret)
943C(nvalret):
944        __(ref_global(ret1val_addr,%temp0))
945        __(cmpl lisp_frame.savera0(%ebp),%temp0)
946        __(je 1f)
947        __(test %nargs,%nargs)
948        __(movl $nil_value,%arg_z)
949        __(cmovnel -node_size(%esp,%nargs),%arg_z)
950        __(leave)
951        __(ret)
952
953/* actually need to return values; always need to copy. */
9541:      __(lea 2*node_size(%ebp),%imm0)
955        __(pushl (%imm0))
956        __(movl 0(%ebp),%ebp)
957        __(addl $node_size,%imm0)
958        __(lea node_size(%esp,%nargs),%temp0)
959        __(xorl %arg_y,%arg_y)
960        __(jmp 3f)
9612:      __(movl -node_size(%temp0),%arg_z)
962        __(subl $node_size,%temp0)
963        __(addl $node_size,%arg_y)
964        __(movl %arg_z,-node_size(%imm0))
965        __(subl $node_size,%imm0)
9663:      __(cmpl %arg_y,%nargs)
967        __(jne 2b)
968        __(pop %ra0)
969        __(movl %imm0,%esp)
970        __(jmp *%ra0)
971_endsubp(nvalret)
972
973_spentry(jmpsym)
974        __(jump_fname())
975_endsubp(jmpsym)
976
977_spentry(jmpnfn)
978        __(mov %temp0,%fn)
979        __(jmp *%fn)
980_endsubp(jmpnfn)
981
982_spentry(funcall)
983        __(do_funcall())
984_endsubp(funcall)
985
986/* Make a lisp integer (fixnum or one-digit bignum) from the value in %imm0 */
987_spentry(makes32)
988        __(imull $fixnumone,%imm0,%arg_z)       /* result is fixnum-tagged */
989        __(jno 0f)                              /* but may have overflowed */
990        __(movd %imm0,%mm1)
991        __(movl $one_digit_bignum_header,%imm0)
992        __(movd %imm0,%mm0)
993        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
994        __(movd %mm1,misc_data_offset(%arg_z))
9950:      __(repret)
996_endsubp(makes32)
997
998/* Make a lisp integer out of the unboxed 64-bit word in %mm0. */
999/* This is a little clumsy, but the alternative requires callers to */
1000/* have already marked %edx as an imm reg (or else store it in memory
1001/* somewhere), and I'm nervous about */
1002/* splitting up the mark-as-imm/mark-as-node between two separate */
1003/* pieces of code. */
1004_spentry(makes64)
1005        __(movq %mm0,%mm2)
1006        __(pshufw $0x4e,%mm0,%mm1)      /* swap hi/lo halves */
1007        __(psrad $31,%mm0)      /* propagate sign */
1008        __(pcmpeqd %mm0,%mm1)   /* all ones if equal */
1009        __(movd %mm1,%imm0)
1010        __(cmpb $-1,%imm0_b)    /* upper half just sign extension? */
1011        __(jne 1f)
1012        __(movd %mm2,%imm0)
1013        __(jmp _SPmakes32)
10141:      __(movl $two_digit_bignum_header,%imm0)
1015        __(movd %imm0,%mm0)
1016        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
1017        __(movq %mm2,misc_data_offset(%arg_z))
1018        __(ret)
1019_endsubp(makes64)
1020
1021_spentry(syscall)
1022        __(int $3)
1023        /* Save lisp registers */
1024        __(push %ebp)
1025        __(movl %esp,%ebp)
1026        __(push %temp0)
1027        __(push %temp1)
1028        __(push %arg_y)
1029        __(push %arg_z)
1030        __(push %fn)
1031        __(movl %esp,%rcontext:tcr.save_vsp)
1032        __(movl %ebp,%rcontext:tcr.save_ebp)
1033        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
1034        __(movl %rcontext:tcr.foreign_sp,%esp)
1035        __(emms)
1036        __(pop %ebp)            /* backlink */
1037        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1038        __(movl $local_label(back_from_sysenter),%edx)
1039        __(push %edx)
1040        __(movl %esp,%ecx)
1041        __(sysenter)
1042local_label(back_from_sysenter):
1043        __(jnc 0f)
1044        __(neg %eax)
10450:     
1046        __(movl %ebp,%esp)
1047        __(movl %esp,%rcontext:tcr.foreign_sp)
1048        __(zero_node_regs)
1049        __(pxor %fpzero,%fpzero)
1050        __(movl %rcontext:tcr.save_vsp,%esp)
1051        __(movl %rcontext:tcr.save_ebp,%ebp)
1052        __(movl $TCR_STATE_LISP,%rcontext:tcr.valence)
1053        __(pop %fn)
1054        __(pop %arg_z)
1055        __(pop %arg_y)
1056        __(pop %temp1)
1057        __(check_pending_interrupt(%temp0))
1058        __(push %temp0)
1059        __(leave)
1060        __(ret)
1061_endsubp(syscall)
1062
1063/* Make system call that returns a doubleword result in %edx:%eax and */
1064/* copy the result into %mm0. */
1065_spentry(syscall2)
1066        __(int $3)
1067        /* Save lisp registers */
1068        __(push %ebp)
1069        __(movl %esp,%ebp)
1070        __(push %temp0)
1071        __(push %temp1)
1072        __(push %arg_y)
1073        __(push %arg_z)
1074        __(push %fn)
1075        __(movl %esp,%rcontext:tcr.save_vsp)
1076        __(movl %ebp,%rcontext:tcr.save_ebp)
1077        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
1078        __(movl %rcontext:tcr.foreign_sp,%esp)
1079        __(emms)
1080        __(pop %ebp)            /* backlink */
1081        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1082        __(pushl $local_label(back_from_syscall))
1083        __(int $0x80)
1084local_label(back_from_syscall):
1085        __(jnc 0f)
1086        __(neg %eax)
1087        __(movl $-1,%edx)
10880:
1089        /* just use memory rather than screwing around with */
1090        /* movd %eax,%mm0, movd %edx,%mm1, psllq $32,%mm1, por %mm1,%mm0 */
1091        __(push %edx)
1092        __(push %eax)
1093        __(movq (%esp),%mm0)
1094        __(movl %ebp,%esp)
1095        __(movl %esp,%rcontext:tcr.foreign_sp)
1096        __(zero_node_regs)
1097        __(pxor %fpzero,%fpzero)
1098        __(movl %rcontext:tcr.save_vsp,%esp)
1099        __(movl %rcontext:tcr.save_ebp,%ebp)
1100        __(movl $TCR_STATE_LISP,%rcontext:tcr.valence)
1101        __(pop %fn)
1102        __(pop %arg_z)
1103        __(pop %arg_y)
1104        __(pop %temp1)
1105        __(check_pending_interrupt(%temp0))
1106        __(push %temp0)
1107        __(leave)
1108        __(ret)
1109_endsubp(syscall2)
1110
1111
1112_spentry(mkcatch1v)
1113        __(nMake_Catch(0))
1114        __(ret)
1115_endsubp(mkcatch1v)
1116
1117_spentry(mkunwind)
1118        __(int $3)
1119_endsubp(mkunwind)
1120
1121/* this takes a return address in %ra0; it's "new" in that it does the */
1122/*   double binding of *interrupt-level* out-of-line */
1123_spentry(nmkunwind)
1124        __(movl %rcontext:tcr.tlb_pointer,%arg_z)
1125        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_z),%arg_y)
1126        __(push %arg_y)
1127        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
1128        __(push %rcontext:tcr.db_link)
1129        __(movl %esp,%rcontext:tcr.db_link)
1130        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_z))
1131        __(movl $undefined,%arg_z)
1132        /* %arg_z = tag, %xfn (%temp1) = pc */
1133        __(Make_Catch(fixnumone))
1134        __(movl %arg_y,%arg_z)
1135        __(jmp _SPbind_interrupt_level)
1136_endsubp(nmkunwind)
1137
1138_spentry(mkcatchmv)
1139        __(int $3)
1140_endsubp(mkcatchmv)
1141
1142_spentry(throw)
1143        __(int $3)
1144_endsubp(throw)
1145
1146        /* This takes N multiple values atop the vstack.   */
1147_spentry(nthrowvalues)
1148        __(movb $1,%rcontext:tcr.unwinding)
1149        __(movl %ra0,%rcontext:tcr.save0) /* %ra0 (aka %temp0) to spill area */
1150local_label(_nthrowv_nextframe):
1151        __(subl $fixnumone,%imm0)
1152        __(js local_label(_nthrowv_done))
1153        __(movd %imm0,%mm1)
1154        __(movl %rcontext:tcr.catch_top,%temp0)
1155        __(movl catch_frame.link(%temp0),%imm0)
1156        __(movl %imm0,%rcontext:tcr.catch_top)
1157        __(movl catch_frame.db_link(%temp0),%imm0)
1158        __(cmpl %imm0,%rcontext:tcr.db_link)
1159        __(jz local_label(_nthrowv_dont_unbind))
1160        __(push %temp1)
1161        __(push %temp0)
1162        __(push $local_label(_nthrowv_back_from_unbind))
1163        __(jmp _SPunbind_to)
1164__(tra(local_label(_nthrowv_back_from_unbind)))
1165        __(pop %temp0)
1166        __(pop %temp1)
1167local_label(_nthrowv_dont_unbind):
1168        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1169        __(je local_label(_nthrowv_do_unwind))
1170/* A catch frame.  If the last one, restore context from there.   */
1171        __(movd %mm1,%imm0)
1172        __(test %imm0,%imm0)    /* last catch frame ?   */
1173        __(jne local_label(_nthrowv_skip))
1174        __(movl catch_frame.xframe(%temp0),%arg_y)
1175        __(movl %arg_y,%rcontext:tcr.xframe)
1176        __(lea (%esp,%nargs),%arg_y)
1177        __(movl catch_frame.esp(%temp0),%arg_z)
1178        __(movd %nargs,%mm2)
1179        __(jmp local_label(_nthrowv_push_test))
1180local_label(_nthrowv_push_loop):
1181        __(subl $node_size,%arg_y)
1182        __(subl $node_size,%arg_z)
1183        __(movd (%arg_y),%mm0)
1184        __(movd %mm0,(%arg_z))
1185local_label(_nthrowv_push_test):
1186        __(subl $node_size,%nargs)
1187        __(jns local_label(_nthrowv_push_loop))
1188        __(movd %mm2,%nargs)
1189        __(movl catch_frame.xframe(%temp0),%arg_y)
1190        __(movl %arg_y,%rcontext:tcr.xframe)
1191        __(movl %arg_z,%esp)
1192        __(movl catch_frame.ebp(%temp0),%ebp)
1193        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1194        __(movd %stack_temp,%rcontext:tcr.foreign_sp)       
1195local_label(_nthrowv_skip):     
1196        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1197        __(movl %imm0,%rcontext:tcr.save_tsp)
1198        __(movl %imm0,%rcontext:tcr.next_tsp)
1199        __(movd %mm1,%imm0)
1200        __(jmp local_label(_nthrowv_nextframe))
1201local_label(_nthrowv_do_unwind):       
1202/* This is harder.  Call the cleanup code with the multiple values and   */
1203/* nargs, the throw count, and the caller's return address in a temp  */
1204/* stack frame.   */
1205        __(leal (%esp,%nargs),%arg_y)
1206        __(push catch_frame.pc(%temp0))
1207        __(movl catch_frame.ebp(%temp0),%ebp)
1208        __(movd catch_frame.xframe(%temp0),%stack_temp)
1209        __(movd %stack_temp,%rcontext:tcr.xframe)
1210        __(movl catch_frame.esp(%temp0),%arg_z)
1211        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1212        __(movd %stack_temp,%rcontext:tcr.foreign_sp)       
1213        /* Discard the catch frame, so we can build a temp frame   */
1214        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1215        __(movl %imm0,%rcontext:tcr.save_tsp)
1216        __(movl %imm0,%rcontext:tcr.next_tsp)
1217        __(movd %temp1,%mm2) /* save %nargs */
1218        /* tsp overhead, nargs, throw count, ra0   */
1219        __(dnode_align(%nargs,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1220        __(movl %imm0,%temp1)
1221        __(TSP_Alloc_Var(%temp1,%imm0))
1222        __(movd %mm2,%temp1) /* aka %nargs */
1223
1224        __(movl %nargs,(%imm0))
1225        __(movl %rcontext:tcr.save0,%ra0)
1226        __(movl %ra0,node_size(%imm0))
1227        __(movd %mm1,node_size*2(%imm0))
1228        __(leal node_size*3(%imm0),%imm0)
1229        __(jmp local_label(_nthrowv_tpushtest))
1230local_label(_nthrowv_tpushloop):
1231        __(movl -node_size(%arg_y),%temp0)
1232        __(subl $node_size,%arg_y)
1233        __(movl %temp0,(%imm0))
1234        __(addl $node_size,%imm0)
1235local_label(_nthrowv_tpushtest):
1236        __(subl $node_size,%nargs)
1237        __(jns local_label(_nthrowv_tpushloop))
1238        __(pop %xfn)    /* aka %temp1/%nargs */
1239        __(movl %arg_z,%esp)
1240/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1241        __(push $local_label(_nthrowv_called_cleanup))
1242        __(movb $0,%rcontext:tcr.unwinding)
1243        __(jmp *%xfn)
1244__(tra(local_label(_nthrowv_called_cleanup)))
1245
1246        __(movb $1,%rcontext:tcr.unwinding)
1247        __(movl %rcontext:tcr.save_tsp,%imm0)
1248        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%nargs)
1249        __(movl tsp_frame.data_offset+(1*node_size)(%imm0),%ra0)
1250        __(movl %ra0,%rcontext:tcr.save0)
1251        __(movd tsp_frame.data_offset+(2*node_size)(%imm0),%mm1)
1252        __(movd %nargs,%mm2)
1253        __(addl $tsp_frame.fixed_overhead+(node_size*3),%imm0)
1254        __(jmp local_label(_nthrowv_tpoptest))
1255local_label(_nthrowv_tpoploop): 
1256        __(push (%imm0))
1257        __(addl $node_size,%imm0)
1258local_label(_nthrowv_tpoptest): 
1259        __(subl $node_size,%nargs)
1260        __(jns local_label(_nthrowv_tpoploop))
1261        __(movd %mm2,%nargs)
1262        __(movl %rcontext:tcr.save_tsp,%imm0)
1263        __(movl (%imm0),%imm0)
1264        __(movl %imm0,%rcontext:tcr.save_tsp)
1265        __(movl %imm0,%rcontext:tcr.next_tsp)
1266        __(movd %mm1,%imm0)
1267        __(jmp local_label(_nthrowv_nextframe))
1268local_label(_nthrowv_done):
1269        __(movb $0,%rcontext:tcr.unwinding)
1270        __(check_pending_interrupt(%imm0))
1271local_label(_nthrowv_return):
1272        __(movl %rcontext:tcr.save0,%ra0)
1273        __(movss %fpzero,%rcontext:tcr.save0)
1274        __(jmp *%ra0)   
1275_endsubp(nthrowvalues)
1276
1277/* This is a (slight) optimization.  When running an unwind-protect,  */
1278/* save the single value and the throw count in the tstack frame.  */
1279/* Note that this takes a single value in arg_z.  */
1280
1281_spentry(nthrow1value)
1282        __(movb $1,%rcontext:tcr.unwinding)
1283local_label(_nthrow1v_nextframe):
1284        __(subl $fixnumone,%imm0)
1285        __(js local_label(_nthrow1v_done))
1286        __(movd %imm0,%mm0)
1287        __(movl %rcontext:tcr.catch_top,%temp1)
1288        __(movl catch_frame.link(%temp1),%imm0)
1289        __(movl %imm0,%rcontext:tcr.catch_top)
1290        __(movl catch_frame.db_link(%temp1),%imm0)
1291        __(cmpl %imm0,%rcontext:tcr.db_link)
1292        __(jz local_label(_nthrow1v_dont_unbind))
1293        __(push %temp1)
1294        __(push %temp0)
1295        __(push %arg_z)
1296        __(push [$]local_label(_nthrow1v_back_from_unbind))
1297        __(jmp _SPunbind_to)
1298__(tra(local_label(_nthrow1v_back_from_unbind)))
1299        __(pop %arg_z)
1300        __(pop %temp0)
1301        __(pop %temp1)
1302local_label(_nthrow1v_dont_unbind):
1303        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp1))
1304        __(je local_label(_nthrow1v_do_unwind))
1305/* A catch frame.  If the last one, restore context from there. */
1306        __(movd %mm0,%imm0)
1307        __(test %imm0,%imm0)    /* last catch frame? */
1308        __(jne local_label(_nthrow1v_skip))
1309        __(movl catch_frame.xframe(%temp1),%arg_y)
1310        __(movl %arg_y,%rcontext:tcr.xframe)
1311        __(movl catch_frame.esp(%temp1),%esp)
1312        __(movl catch_frame.ebp(%temp1),%ebp)
1313        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1314        __(movd %stack_temp,%rcontext:tcr.foreign_sp)
1315local_label(_nthrow1v_skip):
1316        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1317        __(movl %imm0,%rcontext:tcr.save_tsp)
1318        __(movl %imm0,%rcontext:tcr.next_tsp)
1319        __(movd %mm0,%imm0)
1320        __(jmp local_label(_nthrow1v_nextframe))
1321local_label(_nthrow1v_do_unwind):
1322/* This is harder, but not as hard (not as much BLTing) as the */
1323/* multiple-value case. */
1324        __(movl catch_frame.xframe(%temp1),%arg_y)
1325        __(movl %arg_y,%rcontext:tcr.xframe)
1326        __(movl catch_frame.ebp(%temp1),%ebp)
1327        __(movl catch_frame.esp(%temp1),%esp)
1328        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1329        __(movd %stack_temp,%rcontext:tcr.foreign_sp)
1330        /* Discard the catch frame so we can build a temp frame. */
1331        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1332        __(movl %imm0,%rcontext:tcr.save_tsp)
1333        __(movl %imm0,%rcontext:tcr.next_tsp)
1334        __(movl catch_frame.pc(%temp1),%xfn) /* xfn is temp1 */
1335        __(TSP_Alloc_Fixed((3*node_size),%imm0))
1336        __(addl $tsp_frame.fixed_overhead,%imm0)
1337        __(movl %ra0,(%imm0))
1338        __(movd %mm0,node_size*1(%imm0))
1339        __(movl %arg_z,node_size*2(%imm0))
1340/* Ready to call cleanup code.  Set up tra, jmp to %xfn. */
1341        __(push $local_label(_nthrow1v_called_cleanup))
1342        __(movb $0,%rcontext:tcr.unwinding)
1343        __(jmp *%xfn)
1344__(tra(local_label(_nthrow1v_called_cleanup)))
1345        __(movb $1,%rcontext:tcr.unwinding)
1346        __(movl %rcontext:tcr.save_tsp,%imm0)
1347        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%ra0)
1348        __(movd tsp_frame.data_offset+(1*node_size)(%imm0),%mm0)
1349        __(movl tsp_frame.data_offset+(2*node_size)(%imm0),%arg_z)
1350        __(movl (%imm0),%imm0)
1351        __(movl %imm0,%rcontext:tcr.save_tsp)
1352        __(movl %imm0,%rcontext:tcr.next_tsp)
1353        __(movd %mm0,%imm0)
1354        __(jmp local_label(_nthrow1v_nextframe))
1355local_label(_nthrow1v_done):
1356        __(movb $0,%rcontext:tcr.unwinding)
1357        __(check_pending_interrupt(%imm0))
1358local_label(_nthrow1v_return):
1359        __(jmp *%ra0)
1360_endsubp(nthrow1value)
1361
1362/* This never affects the symbol's vcell   */
1363/* Non-null symbol in arg_y, new value in arg_z           */
1364
1365_spentry(bind)
1366        __(int $3)
1367_endsubp(bind)
1368
1369/* arg_z = symbol: bind it to its current value  */
1370
1371_spentry(bind_self)
1372        __(int $3)
1373_endsubp(bind_self)
1374
1375_spentry(bind_nil)
1376        __(int $3)
1377_endsubp(bind_nil)
1378
1379_spentry(bind_self_boundp_check)
1380        __(int $3)
1381_endsubp(bind_self_boundp_check)
1382
1383_spentry(conslist)
1384        __(int $3)
1385_endsubp(conslist)
1386
1387/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1388/* Cons, one cons cell at at time.  Maybe optimize this later.  */
1389
1390_spentry(conslist_star)
1391        __(int $3)
1392_endsubp(conslist_star)
1393
1394/* We always have to create a tsp frame (even if nargs is 0), so the compiler   */
1395/* doesn't get confused.   */
1396_spentry(stkconslist)
1397        __(int $3)
1398_endsubp(stkconslist)
1399
1400/* do list*: last arg in arg_z, all others vpushed,   */
1401/*      nargs set to #args vpushed.  */
1402
1403_spentry(stkconslist_star)
1404        __(int $3)
1405_endsubp(stkconslist_star)
1406
1407
1408/* Make a stack-consed simple-vector out of the NARGS objects   */
1409/*      on top of the vstack; return it in arg_z.  */
1410
1411_spentry(mkstackv)
1412        __(int $3)
1413_endsubp(mkstackv)
1414
1415        .globl C(egc_write_barrier_start)
1416C(egc_write_barrier_start):
1417/*  */
1418/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1419/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1420/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1421/* an intergenerational reference (a young pointer stored in an old object) has  */
1422/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1423/* This has to happen atomically, and has to happen atomically wrt GC.  */
1424
1425/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1426/* interlocked loads and stores.  */
1427
1428/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1429/* in the function, we can do the store (even if it's already been done) and  */
1430/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1431/* setting the bit needs to be done atomically, unless we're sure that other  */
1432/* threads are suspended.)  */
1433/* We can unconditionally set the suspended thread's RIP to the return address.  */
1434
1435_spentry(rplaca)
1436        .globl C(egc_rplaca)
1437C(egc_rplaca):
1438        __(rcmpl(%arg_z,%arg_y))
1439        __(_rplaca(%arg_y,%arg_z))
1440        __(ja 1f)
14410:      __(repret)
14421:      __(movl %arg_y,%imm0)
1443        __(subl lisp_global(heap_start),%imm0)
1444        __(shrl $dnode_shift,%imm0)
1445        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1446        __(jae 0b)
1447        __(andl $~(1<<bitmap_shift-1),%temp0)
1448        __(shrl $bitmap_shift-fixnumshift,%temp0)
1449        __(andl $31,%imm0)
1450        __(addl lisp_global(refbits),%temp0)
1451        __(xorb $31,%imm0_b)
1452        __(lock)
1453        __(btsl %imm0,(%temp0))
1454        __(ret)
1455_endsubp(rplaca)
1456
1457_spentry(rplacd)
1458        .globl C(egc_rplacd)
1459C(egc_rplacd):
1460        __(rcmpl(%arg_z,%arg_y))
1461        __(_rplacd(%arg_y,%arg_z))
1462        __(ja 1f)
14630:      __(repret)
14641:      __(movl %arg_y,%imm0)
1465        __(subl lisp_global(heap_start),%imm0)
1466        __(shrl $dnode_shift,%imm0)
1467        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1468        __(jae 0b)
1469        __(andl $~(1<<bitmap_shift-1),%temp0)
1470        __(shrl $bitmap_shift-fixnumshift,%temp0)
1471        __(andl $31,%imm0)
1472        __(addl lisp_global(refbits),%temp0)
1473        __(xorb $31,%imm0_b)
1474        __(lock)
1475        __(btsl %imm0,(%temp0))
1476        __(ret)
1477_endsubp(rplacd)
1478
1479/* Storing into a gvector can be handles the same way as storing into a CONS. */
1480/* args (src, unscaled-idx, val) in temp0, arg_y, arg_z */
1481_spentry(gvset)
1482        .globl C(egc_gvset)
1483C(egc_gvset):
1484        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1485        __(rcmpl(%arg_z,%temp0))
1486        __(ja 1f)
14870:      __(repret)
14881:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1489        __(subl lisp_global(heap_start),%imm0)
1490        __(shrl $dnode_shift,%imm0)
1491        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1492        __(jae 0b)
1493        __(andl $~(1<<bitmap_shift-1),%temp0)
1494        __(shrl $bitmap_shift-fixnumshift,%temp0)
1495        __(andl $31,%imm0)
1496        __(addl lisp_global(refbits),%temp0)
1497        __(xorb $31,%imm0_b)
1498        __(lock)
1499        __(btsl %imm0,(%temp0))
1500        __(ret)
1501_endsubp(gvset)
1502
1503/* This is a special case of storing into a gvector: if we need to  */
1504/* memoize the store, record the address of the hash-table vector  */
1505/* in the refmap, as well.  */
1506
1507_spentry(set_hash_key)
1508        .globl C(egc_set_hash_key)
1509C(egc_set_hash_key):
1510        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1511        __(rcmpl(%arg_z,%temp0))
1512        __(ja 1f)
15130:      __(repret)
15141:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1515        __(subl lisp_global(heap_start),%imm0)
1516        __(shrl $dnode_shift,%imm0)
1517        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1518        __(jae 0b)
1519        __(push %temp0)
1520        __(andl $~(1<<bitmap_shift-1),%temp0)
1521        __(shrl $bitmap_shift-fixnumshift,%temp0)
1522        __(andl $31,%imm0)
1523        __(addl lisp_global(refbits),%temp0)
1524        __(xorb $31,%imm0_b)
1525        __(lock)
1526        __(btsl %imm0,(%temp0))
1527        /* Now memoize the address of the hash vector */
1528        __(pop %imm0)
1529        __(subl lisp_global(heap_start),%imm0)
1530        __(shrl $dnode_shift,%imm0)
1531        __(andl $~(1<<bitmap_shift-1),%temp0)
1532        __(shrl $bitmap_shift-fixnumshift,%temp0)
1533        __(andl $31,%imm0)
1534        __(addl lisp_global(refbits),%temp0)
1535        __(xorb $31,%imm0_b)
1536        __(lock)
1537        __(btsl %imm0,(%temp0))
1538        __(ret)
1539_endsubp(set_hash_key)
1540
1541/* This is a little trickier: if this is interrupted, we need to know  */
1542/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1543/* If we're interrupted   before the PC has reached the "success_test" label, */
1544/* repeat (luser the PC back to .SPstore_node_conditional.)  If we're at that */
1545/* label with the Z flag set, we won and (may) need to memoize.  */
1546
1547/* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1548_spentry(store_node_conditional)
1549        .globl C(egc_store_node_conditional)
1550C(egc_store_node_conditional):
1551        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1552        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
15530:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
1554        __(movl misc_data_offset(%temp1,%temp0),%imm0)
1555        __(jne 3f)
1556        __(lock)
1557        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1558        .globl C(egc_store_node_conditional_success_test)
1559C(egc_store_node_conditional_success_test):
1560        __(jne 0b)
1561        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1562        __(subl lisp_global(heap_start),%imm0)
1563        __(shrl $dnode_shift,%imm0)
1564        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1565        __(jae 2f)
1566        __(andl $~(1<<bitmap_shift-1),%temp0)
1567        __(shrl $bitmap_shift-fixnumshift,%temp0)
1568        __(andl $31,%imm0)
1569        __(addl lisp_global(refbits),%temp0)
1570        __(xorb $31,%imm0_b)
1571        __(lock)
1572        __(btsl %imm0,(%temp0))
1573        .globl C(egc_write_barrier_end)
1574C(egc_write_barrier_end):
15752:      __(movl $t_value,%arg_z)
1576        __(ret)
15773:      __(movl $nil_value,%arg_z)
1578        __(ret)
1579_endsubp(store_node_conditional)
1580
1581_spentry(setqsym)
1582        __(bt $sym_vbit_const,symbol.flags(%arg_y))
1583        __(jae _SPspecset)
1584        __(mov %arg_y,%arg_z)
1585        __(mov $XCONST,%arg_y)
1586        __(set_nargs(2))
1587        __(jmp _SPksignalerr)
1588_endsubp(setqsym)
1589
1590_spentry(progvsave)
1591        __(int $3)
1592_endsubp(progvsave)
1593
1594/* Allocate node objects on the temp stack, immediate objects on the foreign  */
1595/* stack. (The caller has to know which stack to discard a frame from.)  */
1596/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
1597
1598_spentry(stack_misc_alloc)
1599        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
1600        __(jne local_label(stack_misc_alloc_not_u24))
1601        __(unbox_fixnum(%arg_z,%imm0))
1602        __(mov %arg_y,%temp0)
1603        __(shl $num_subtag_bits-fixnumshift,%temp0)
1604        __(or %temp0,%imm0)     /* %imm0 now = header */
1605        __(movd %imm0,%mm0)     /* cache header in %mm0 */
1606        __(andb $fulltagmask,%imm0_b)
1607        __(cmpb $fulltag_nodeheader,%imm0_b)
1608        __(je local_label(stack_misc_alloc_node))
1609        __(movd %mm0,%imm0)
1610        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
1611        __(jbe local_label(stack_misc_alloc_32))
1612        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
1613        __(jbe local_label(stack_misc_alloc_8))
1614        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
1615        __(jbe local_label(stack_misc_alloc_16))
1616        __(cmpb $subtag_double_float_vector,%imm0_b)
1617        __(jne local_label(stack_misc_alloc_1))
1618        /* double-float vector case */
1619        __(imul $2,%arg_y,%imm0)
1620        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1621local_label(stack_misc_alloc_1):
1622        __(unbox_fixnum(%arg_y,%imm0))
1623        __(addl $7,%imm0)
1624        __(shrl $3,%imm0)
1625        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1626local_label(stack_misc_alloc_8):
1627        __(unbox_fixnum(%arg_y,%imm0))
1628        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1629local_label(stack_misc_alloc_16):
1630        __(unbox_fixnum(%arg_y,%imm0))
1631        __(shl $1,%imm0)
1632        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1633local_label(stack_misc_alloc_32):
1634        __(mov %arg_y,%imm0)
1635local_label(stack_misc_alloc_alloc_ivector):
1636        /* byte count in %imm0 */
1637        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1638        __(cmpl $tstack_alloc_limit,%imm0)
1639        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
1640        __(movd %rcontext:tcr.foreign_sp,%stack_temp)
1641        __(movd %stack_temp,%temp1)
1642        __(subl %imm0,%rcontext:tcr.foreign_sp)
1643        __(movl %rcontext:tcr.foreign_sp,%temp0)
16440:      __(movsd %fpzero,-dnode_size(%temp1))
1645        __(subl $dnode_size,%temp1)
1646        __(cmpl %temp1,%temp0)
1647        __(jnz 0b)
1648        __(movd %stack_temp,(%temp0))
1649        __(movd %mm0,tsp_frame.fixed_overhead(%temp0))
1650        __(lea tsp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
1651        __(ret)
1652local_label(stack_misc_alloc_heap_alloc_ivector):
1653        __(movd %rcontext:tcr.foreign_sp,%stack_temp)
1654        __(subl $dnode_size,%rcontext:tcr.foreign_sp)
1655        __(movl %rcontext:tcr.foreign_sp,%imm0)
1656        __(movd %stack_temp,(%imm0))
1657        __(jmp _SPmisc_alloc)
1658local_label(stack_misc_alloc_node):
1659        __(movl %arg_y,%imm0)
1660        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1661        __(cmpl $tstack_alloc_limit,%imm0)
1662        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
1663        __(TSP_Alloc_Var(%imm0,%temp1))
1664        __(movd %mm0,(%temp1))
1665        __(leal fulltag_misc(%temp1),%arg_z)
1666        __(ret)
1667local_label(stack_misc_alloc_heap_alloc_gvector):
1668        __(TSP_Alloc_Fixed(0,%imm0))
1669        __(jmp _SPmisc_alloc)
1670
1671local_label(stack_misc_alloc_not_u24):
1672        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
1673_endsubp(stack_misc_alloc)
1674
1675/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of */
1676/* initial-contents.  Note that this can be used to cons any type of */
1677/* initialized node-header'ed misc object (symbols, closures, ...) */
1678/* as well as vector-like objects. */
1679_spentry(gvector)
1680        __(subl $node_size,%nargs)      /* off by one in x862-%gvector */
1681        __(movl (%esp,%nargs),%imm0)    /* boxed subtype */
1682        __(sarl $fixnumshift,%imm0)
1683        __(movl %nargs,%arg_z)
1684        __(shll $num_subtag_bits-word_shift,%arg_z)
1685        __(orl %arg_z,%imm0)
1686        __(movd %imm0,%mm0)
1687        __(dnode_align(%nargs,node_size,%imm0))
1688        __(push %ra0)   /* aka %temp0, can't be live while consing */
1689        __(Misc_Alloc(%arg_z))
1690        __(pop %ra0)
1691        __(movl %nargs,%imm0)
1692        __(jmp 2f)
16931:      __(movl %arg_y,misc_data_offset(%arg_z,%imm0))
16942:      __(subl $node_size,%imm0)
1695        __(pop %arg_y)  /* Note the intentional fencepost: */
1696                        /* discard the subtype as well. */
1697        __(jge 1b)
1698        __(jmp *%ra0)
1699_endsubp(gvector)
1700
1701_spentry(mvpass)
1702        __(int $3)
1703_endsubp(mvpass)
1704
1705_spentry(nthvalue)
1706        __(int $3)
1707_endsubp(nthvalue)
1708
1709_spentry(values)
1710        __(int $3)
1711_endsubp(values)
1712
1713_spentry(default_optional_args)
1714        __(int $3)
1715_endsubp(default_optional_args)
1716
1717_spentry(opt_supplied_p)
1718        __(int $3)
1719_endsubp(opt_supplied_p)
1720
1721_spentry(lexpr_entry)
1722        __(int $3)
1723_endsubp(lexpr_entry)
1724
1725_spentry(heap_rest_arg)
1726        __(int $3)
1727_endsubp(heap_rest_arg)
1728
1729/* %imm0 contains the number of fixed args ; make an &rest arg out of the others   */
1730_spentry(req_heap_rest_arg)
1731        __(int $3)
1732_endsubp(req_heap_rest_arg)
1733
1734/* %imm0 bytes of stuff has already been pushed   */
1735/* make an &rest arg out of any others   */
1736_spentry(heap_cons_rest_arg)
1737        __(int $3)
1738_endsubp(heap_cons_rest_arg)
1739
1740_spentry(simple_keywords)
1741        __(xor %imm0,%imm0)
1742        __(push_argregs())
1743        __(jmp _SPkeyword_bind)
1744_endsubp(simple_keywords)
1745
1746_spentry(keyword_args)
1747        __(push_argregs())
1748        __(jmp _SPkeyword_bind)
1749_endsubp(keyword_args)
1750
1751/* There are %nargs words of arguments on the stack; %imm0 contains the */
1752/* number of non-keyword args pushed.  It's possible that we never actually */
1753/* got any keyword args, which would make things much simpler. */
1754
1755/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
1756/* indicating whether &allow-other-keys and/or &rest was present in the */
1757/* lambda list.  We therefore need to access %nargs as a 16-bit register. */
1758
1759/* Once we get here, we can use the arg registers. */
1760
1761/* N.B.: %ra0 is %temp0, and must not be clobbered. */
1762
1763define([keyword_flags_aok_bit],[16])
1764define([keyword_flags_unknown_keys_bit],[17])
1765define([keyword_flags_rest_bit],[18])
1766define([keyword_flags_seen_aok_bit],[19])
1767
1768_spentry(keyword_bind)
1769        __(movzwl %nargs_w,%arg_z)
1770        __(subl %imm0,%arg_z)
1771        __(jbe local_label(no_keyword_values))
1772        __(btl $word_shift,%arg_z)
1773        __(jnc local_label(even))
1774        __(movl $nil_value,%arg_y)
1775        __(movw %arg_z_w,%nargs_w)
1776        __(testw %nargs_w,%nargs_w)
1777        __(jmp 1f)
17780:      __(pop %arg_z)
1779        __(push %ra0) /* aka temp0; temp0 can't be live while consing. */
1780        __(Cons(%arg_z,%arg_y,%arg_y))
1781        __(pop %ra0)  /* the push/pop in a loop is disgusting. */
1782        __(subw $node_size,%nargs_w)
17831:      __(jnz 0b)
1784        __(movl %arg_y,%arg_z)
1785        __(movl $XBADKEYS,%arg_y)
1786        __(set_nargs(2))
1787        __(jmp _SPksignalerr)
1788
1789        /* Now that we're sure that we have an even number of */
1790        /* keywords and values (in %arg_z), move the pairs over */
1791        /* to the temp stack. */
1792local_label(even):
1793        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
1794        __(TSP_Alloc_Var(%arg_y,%imm0))
17952:      __(subl $node_size,%arg_y)
1796        __(pop (%arg_y))
1797        __(cmpl %arg_y,%imm0)
1798        __(jne 2b)
1799
1800        /* Get the keyword vector into %arg_y, and its length into %imm0. */
1801        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
1802        /* for each declared keyword. */
1803        __(movzwl misc_data_offset(%fn),%imm0)
1804        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
1805        __(vector_length(%arg_y,%imm0))
1806        __(jmp 4f)
18073:      __(push $nil_value)
1808        __(push $nil_value)
18094:      __(subl $fixnumone,%imm0)
1810        __(jge 3b)
1811
1812        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
1813        /* in order to get a couple more registers to work with. */
1814        __(push %ra0)
1815        __(push %nargs)
1816
1817        /* At this point we have: */
1818        /* number of supplied keywords and values in %arg_z */
1819        /* keyword vector in %arg_y */
1820        __(vector_length(%arg_y,%imm0))
1821        __(push %imm0)          /* count of declared keywords */
1822        __(push %arg_z)         /* count of supplied keys and values */
1823
1824        /* For each declared keyword, iterate over the supplied k/v pairs */
1825        /* to see if it's supplied and what the value is. */
1826        /* checking to see if any */
1827        /* key-value pairs were unexpectedly supplied. */
1828
1829        __(movl %rcontext:tcr.save_tsp,%temp0)
1830        __(addl $2*node_size,%temp0) /* skip frame overhead */
1831        /* %temp0: top of tstack (skipping frame overhead) */
1832        __(lea 4*node_size(%esp,%imm0,2),%temp1)
1833        /* %temp1: word above 0th value/supplied-p pair on vstack */
1834        /* %arg_y: keyword vector */
1835        __(xorl %imm0,%imm0)
1836        /* %imm0: index */
1837        /* %arg_z: temporary */
1838
1839        /* Iterate over supplied k/v pairs on tstack.  See if key is */
1840        /* in the keyword vector.  Copy value and set supplied-p on */
1841        /* vstack if found. */
1842
1843local_label(tstack_loop):
1844        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
1845        __(push %imm0)
1846        __(xorl %imm0,%imm0)
1847        __(cmpl $nrs.kallowotherkeys,%arg_z)
1848        __(jne local_label(next_keyvect_entry))
1849        __(btsl $keyword_flags_seen_aok_bit,12(%esp))
1850        __(jc local_label(next_keyvect_entry))
1851        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
1852        __(je local_label(next_keyvect_entry))
1853        __(btsl $keyword_flags_aok_bit,12(%esp))
1854        __(jmp local_label(next_keyvect_entry))
1855        /* loop through keyword vector */
18566:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
1857        __(jne 7f)
1858        /* Got a match; have we already seen this keyword? */
1859        __(negl %imm0)
1860        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
1861        __(jne 9f)      /* seen it, ignore this value */
1862        __(movl (%esp),%arg_z)
1863        __(lea (%temp0,%arg_z,2),%arg_z)
1864        __(movl node_size(%arg_z),%arg_z) /* value for this key */
1865        __(movl %arg_z,-node_size(%temp1,%imm0,2))
1866        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
1867        __(jmp 9f)
18687:      __(addl $node_size,%imm0)
1869local_label(next_keyvect_entry):
1870        __(cmpl %imm0,8(%esp))
1871        __(jne 6b)
1872        /* Didn't match anything in the keyword vector.  Is the keyword */
1873        /* :allow-other-keys? */
1874        __(cmpl $nrs.kallowotherkeys,%arg_z)
1875        __(je 9f)       /* :allow-other-keys is never "unknown" */
18768:      __(btsl $keyword_flags_unknown_keys_bit,12(%esp))
18779:      __(pop %imm0)
1878        __(addl $fixnumone,%imm0)
1879        __(movl %imm0,%arg_z)
1880        __(shll $1,%arg_z)      /* pairs of tstack words */
1881        __(cmpl %arg_z,0(%esp))
1882        __(jne local_label(tstack_loop))
1883
1884        __(pop %imm0)   /* count of supplied keys and values */
1885        __(addl $node_size,%esp)
1886        __(pop %nargs)
1887        __(pop %ra0)
1888
1889        /* If the function takes an &rest arg, or if we got an unrecognized */
1890        /* keyword and don't allow that, copy the incoming k/v pairs from */
1891        /* the temp stack back to the value stack. */
1892        __(btl $keyword_flags_rest_bit,%temp1)
1893        __(jc 1f)
1894        __(btl $keyword_flags_unknown_keys_bit,%temp1)
1895        __(jnc 0f)
1896        __(btl $keyword_flags_aok_bit,%temp1)
1897        __(jnc 1f)
1898        /* pop the tstack frame */
18990:      __(discard_temp_frame(%imm0))
1900        __(jmp *%ra0)
1901
1902        /* Copy the k/v pairs from the tstack back to the value stack, */
1903        /* either because the function takes an &rest arg or because */
1904        /* we need to signal an "unknown keywords" error. */
19051:      __(movl %rcontext:tcr.save_tsp,%arg_z)
1906        __(mov (%arg_z),%arg_y)
1907        __(jmp 3f)
19082:      __(push (%arg_z))
1909        __(push node_size(%arg_z))
19103:      __(addl $dnode_size,%arg_z)
1911        __(cmpl %arg_z,%arg_y)
1912        __(jne 2b)
1913        __(discard_temp_frame(%arg_z))
1914        __(btl $keyword_flags_unknown_keys_bit,%temp1)
1915        __(jnc 9f)
1916        __(btl $keyword_flags_aok_bit,%temp1)
1917        __(jc 9f)
1918        /* Signal an "unknown keywords" error */
1919        __(movl %imm0,%nargs)
1920        __(movl $nil_value,%arg_z)
1921        __(test %nargs,%nargs)
1922        __(push %ra0)
1923        __(jmp 5f)
19244:      __(pop %arg_y)
1925        __(Cons(%arg_y,%arg_z,%arg_z))
1926        __(subl $node_size,%nargs)
19275:      __(jnz 4b)
1928        __(movl $XBADKEYS,%arg_y)
1929        __(set_nargs(2))
1930        __(movl 0(%esp),%ra0)
1931        __(jmp _SPksignalerr)
19329:      __(jmp *%ra0)
1933
1934/* No keyword value were provided.  Access the keyword vector (which is the */
1935/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
1936/* N could be 0... */
1937
1938local_label(no_keyword_values):
1939        __(movzwl misc_data_offset(%fn),%imm0)
1940        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
1941        __(vector_length(%arg_y,%arg_z))
1942        __(movl $nil_value,%imm0)
1943        __(jmp 1f)
19440:      __(push %imm0)
1945        __(push %imm0)
19461:      __(subl $fixnumone,%arg_z)
1947        __(jge 0b)
1948        __(jmp *%ra0)
1949_endsubp(keyword_bind)
1950
1951/* Normally, we'd just set %fname (aka %temp0) and do */
1952/* jump_fname().  Sometimes, though, %temp0 is being used */
1953/* as %ra0, and I'm not sure that it's going to be safe to */
1954/* clobber that.  (Note that nil-relative symbols aren't going */
1955/* get moved around by the GC, so we can get away with putting */
1956/* '%err-disp in %imm0.) */
1957_spentry(ksignalerr)
1958        __(mov $nrs.errdisp,%imm0)
1959        __(mov symbol.fcell(%imm0),%fn)
1960        __(jump_fn)
1961_endsubp(ksignalerr)
1962
1963_spentry(stack_rest_arg)
1964        __(xorl %imm0,%imm0)
1965        __(push_argregs())
1966        __(jmp _SPstack_cons_rest_arg)
1967_endsubp(stack_rest_arg)
1968
1969_spentry(req_stack_rest_arg)
1970        __(push_argregs())
1971        __(jmp _SPstack_cons_rest_arg)
1972_endsubp(req_stack_rest_arg)
1973
1974_spentry(stack_cons_rest_arg)
1975_endsubp(stack_cons_rest_arg)
1976
1977_spentry(getxlong)
1978        __(int $3)
1979_endsubp(getxlong)
1980
1981/* Have to be a little careful here: the caller may or may not have pushed  */
1982/* an empty frame, and we may or may not have needed one.  We can't easily  */
1983/* tell whether or not a frame will be needed (if the caller didn't reserve  */
1984/* a frame, whether or not we need one depends on the length of the list  */
1985/* in arg_z.  So, if the caller didn't push a frame, we do so; once */
1986/* everything's been spread, we discard the reserved frame (regardless of
1987/* who pushed it) if all args fit in registers.   */
1988_spentry(spreadargz)
1989        __(test %nargs,%nargs)
1990        __(jne 0f)
1991        __(push $reserved_frame_marker)
1992        __(push $reserved_frame_marker)
19930:      __(movl %arg_z,%rcontext:tcr.save0)     /* save in case of error */
1994        __(movd %nargs,%mm0)    /* now we can use %temp1 */
1995        __(xorl %nargs,%nargs)
1996        __(cmpl $nil_value,%arg_z)
1997        __(je 2f)
19981:      __(extract_fulltag(%arg_z,%imm0))
1999        __(cmpb $fulltag_cons,%imm0_b)
2000        __(jne 9f)
2001        __(_car(%arg_z,%arg_y))
2002        __(_cdr(%arg_z,%arg_z))
2003        __(add $node_size,%nargs)
2004        __(cmpl $call_arguments_limit<<fixnumshift,%nargs)
2005        __(jge 8f)
2006        __(push %arg_y)
2007        __(cmpl $nil_value,%arg_z)
2008        __(jne 1b)
20092:      __(movd %mm0,%imm0)
2010        __(addl %imm0,%nargs)
2011        __(jne 4f)
20123:      __(addl $2*node_size,%esp)
2013        __(movl $0,%rcontext:tcr.save0)
2014        __(jmp *%ra0)
20154:      __(pop %arg_z)
2016        __(cmp $1*node_size,%nargs)
2017        __(je 3b)
2018        __(pop %arg_y)
2019        __(cmp $2*node_size,%nargs)
2020        __(je 3b)
2021        __(movl $0,%rcontext:tcr.save0)
2022        __(jmp *%ra0)
2023/* Discard everything that's been pushed already, complain */
20248:      __(lea (%esp,%nargs),%esp)
2025        __(movl %rcontext:tcr.save0,%arg_z) /* recover original */
2026        __(movl $0,%rcontext:tcr.save0)
2027        __(movl $XTMINPS,%arg_y)
2028        __(set_nargs(2))
2029        __(push %ra0)
2030        __(jmp _SPksignalerr)
20319:      __(lea (%esp,%nargs),%esp)
2032        __(movl %rcontext:tcr.save0,%arg_z) /* recover original */
2033        __(movl $0,%rcontext:tcr.save0)
2034        __(movl $XNOSPREAD,%arg_y)
2035        __(set_nargs(2))
2036        __(push %ra0)
2037        __(jmp _SPksignalerr)
2038_endsubp(spreadargz)
2039
2040
2041/* Caller built its own frame when it was entered.  If all outgoing args  */
2042/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2043/* relative to it and restore %rbp/%ra0   */
2044_spentry(tfuncallgen)
2045        __(int $3)
2046_endsubp(tfuncallgen)
2047
2048/* Some args were pushed; move them down in the frame   */
2049_spentry(tfuncallslide)
2050        __(int $3)
2051_endsubp(tfuncallslide)
2052
2053/* No args were pushed; recover saved context & do funcall        */
2054_spentry(tfuncallvsp)
2055        __(leave)
2056        __(do_funcall())
2057_endsubp(tfuncallvsp)
2058
2059_spentry(tcallsymgen)
2060        __(int $3)
2061_endsubp(tcallsymgen)
2062
2063_spentry(tcallsymslide)
2064        __(movl %ebp,%imm0)
2065        __(subl %nargs,%imm0)
2066        __(addl $nargregs*node_size,%imm0)      /* new tos */
2067        __(push %imm0)
2068        __(push %arg_y)
2069        __(push %arg_z)
2070        __(push %nargs)
2071        __(lea (4-nargregs)*node_size(%esp,%nargs),%arg_y) /* src ptr */
2072        __(movl %ebp,%imm0) /* dst ptr */
2073        __(subl $fixnumone*nargregs,%nargs)
2074        __(jmp 1f)
20750:      __(subl $node_size,%arg_y)
2076        __(movl (%arg_y),%arg_z)
2077        __(subl $node_size,%imm0)
2078        __(movl %arg_z,(%imm0))
20791:      __(subl $fixnumone,%nargs)
2080        __(jge 0b)
2081        __(pop %nargs)
2082        __(pop %arg_z)
2083        __(pop %arg_y)
2084        __(pop %esp)
2085        __(push node_size(%ebp))
2086        __(movl 0(%ebp),%ebp)
2087        __(jump_fname)
2088_endsubp(tcallsymslide)
2089
2090_spentry(tcallsymvsp)
2091        __(leave)
2092        __(jump_fname())
2093_endsubp(tcallsymvsp)
2094
2095_spentry(tcallnfngen)
2096        __(int $3)
2097_endsubp(tcallnfngen)
2098
2099_spentry(tcallnfnslide)
2100        __(int $3)
2101_endsubp(tcallnfnslide)
2102
2103_spentry(tcallnfnvsp)
2104        __(mov %temp0,%fn)
2105        __(leave)
2106        __(jmp *%fn)
2107_endsubp(tcallnfnvsp)
2108
2109/* Make a "raw" area on the foreign stack, stack-cons a macptr to point */
2110/* to it, and return the macptr.  Size (in bytes, boxed) is in arg_z */
2111/* on entry; macptr in arg_z on exit. */
2112_spentry(makestackblock)
2113        __(unbox_fixnum(%arg_z,%imm0))
2114        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2115        __(cmpl $tstack_alloc_limit,%imm0)
2116        __(jae 1f)
2117        __(movd %rcontext:tcr.foreign_sp,%mm0)
2118        __(subl %imm0,%rcontext:tcr.foreign_sp)
2119        __(movl %rcontext:tcr.foreign_sp,%arg_z)
2120        __(movd %mm0,(%arg_z))
2121        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2122        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2123        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2124        __(movl %imm0,macptr.address(%arg_z))
2125        __(movss %fpzero,macptr.domain(%arg_z))
2126        __(movss %fpzero,macptr.type(%arg_z))
2127        __(ret)
21281:      __(movd %rcontext:tcr.foreign_sp,%mm0)
2129        __(subl $dnode_size,%rcontext:tcr.foreign_sp)
2130        __(movl %rcontext:tcr.foreign_sp,%imm0)
2131        __(movd %mm0,(%imm0))
2132        __(set_nargs(1))
2133        __(movl $nrs.new_gcable_ptr,%fname)
2134        __(jump_fname())
2135_endsubp(makestackblock)
2136
2137_spentry(makestackblock0)
2138        __(int $3)
2139_endsubp(makestackblock0)
2140
2141_spentry(makestacklist)
2142        __(int $3)
2143_endsubp(makestacklist)
2144
2145/* subtype (boxed) vpushed before initial values. (Had better be a */
2146/* node header subtag.)  Nargs set to count of things vpushed. */
2147_spentry(stkgvector)
2148        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2149        __(shrl $fixnumshift,%imm0)
2150        __(leal -fixnumone(%nargs),%arg_z)
2151        __(movl %arg_z,%arg_y)
2152        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2153        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2154        __(movd %imm0,%mm0)
2155        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2156        __(TSP_Alloc_Var(%imm0,%arg_z))
2157        __(movd %mm0,(%arg_z))
2158        __(addl $fulltag_misc,%arg_z)
2159        __(lea -node_size(%nargs),%imm0)
2160        __(jmp 2f)
21611:      __(pop misc_data_offset(%arg_z,%imm0))
21622:      __(subl $node_size,%imm0)
2163        __(jge 1b)
2164        __(addl $node_size,%esp)
2165        __(jmp *%ra0)
2166_endsubp(stkgvector)
2167
2168/* Allocate a fulltag-misc object. */
2169/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
2170_spentry(misc_alloc)
2171        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2172        __(jne local_label(misc_alloc_not_u24))
2173        __(unbox_fixnum(%arg_z,%imm0))
2174        __(mov %arg_y,%temp0)
2175        __(shl $num_subtag_bits-fixnumshift,%temp0)
2176        __(or %temp0,%imm0)     /* %imm0 now = header */
2177        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2178        __(andb $fulltagmask,%imm0_b)
2179        __(cmpb $fulltag_nodeheader,%imm0_b)
2180        __(je local_label(misc_alloc_32))
2181        __(movd %mm0,%imm0)
2182        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2183        __(jbe local_label(misc_alloc_32))
2184        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2185        __(jbe local_label(misc_alloc_8))
2186        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2187        __(jbe local_label(misc_alloc_16))
2188        __(cmpb $subtag_double_float_vector,%imm0_b)
2189        __(jne local_label(misc_alloc_1))
2190        /* double-float vector case */
2191        __(imul $2,%arg_y,%imm0)
2192        __(jmp local_label(misc_alloc_alloc_vector))
2193local_label(misc_alloc_1):
2194        __(unbox_fixnum(%arg_y,%imm0))
2195        __(addl $7,%imm0)
2196        __(shrl $3,%imm0)
2197        __(jmp local_label(misc_alloc_alloc_vector))
2198local_label(misc_alloc_8):
2199        __(unbox_fixnum(%arg_y,%imm0))
2200        __(jmp local_label(misc_alloc_alloc_vector))
2201local_label(misc_alloc_16):
2202        __(unbox_fixnum(%arg_y,%imm0))
2203        __(shl $1,%imm0)
2204        __(jmp local_label(misc_alloc_alloc_vector))
2205local_label(misc_alloc_32):
2206        __(movl %arg_y,%imm0)
2207local_label(misc_alloc_alloc_vector):
2208        __(dnode_align(%imm0,node_size,%imm0))
2209        __(Misc_Alloc(%arg_z))
2210        __(ret)
2211local_label(misc_alloc_not_u24):
2212        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2213_endsubp(misc_alloc)
2214
2215_startfn(C(destbind1))
2216        __(jmp *%ra0)
2217_endfn(C(destbind1))
2218
2219_spentry(macro_bind)
2220        __(int $3)
2221_endsubp(macro_bind)
2222
2223_spentry(destructuring_bind)
2224        __(mov %arg_reg,%whole_reg)
2225        __(jmp C(destbind1))
2226_endsubp(destructuring_bind)
2227
2228_spentry(destructuring_bind_inner)
2229        __(mov %arg_z,%whole_reg)
2230        __(jmp C(destbind1))
2231_endsubp(destructuring_bind_inner)
2232
2233_spentry(vpopargregs)
2234        __(int $3)
2235_endsubp(vpopargregs)
2236
2237/* If arg_z is an integer, return in imm0 something whose sign  */
2238/* is the same as arg_z's.  If not an integer, error.   */
2239_spentry(integer_sign)
2240        __(mov %arg_z,%imm0)
2241        __(testb $tagmask,%arg_z_b)
2242        __(je 8f)
2243        __(extract_typecode(%arg_z,%imm0))
2244        __(cmpb $subtag_bignum,%imm0_b)
2245        __(jne 9f)
2246        __(getvheader(%arg_z,%imm0))
2247        __(shr $num_subtag_bits,%imm0)
2248        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
22498:      __(repret)
22509:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
2251_endsubp(integer_sign)
2252
2253/* "slide" nargs worth of values up the stack.  imm0 contains */
2254/* the difference between the current stack pointer and the target. */
2255_spentry(mvslide)
2256        __(movl %nargs,%temp1)
2257        __(lea (%esp,%nargs),%arg_y)
2258        __(lea (%arg_y,%imm0),%imm0)
2259        __(test %temp1,%temp1)
2260        __(je 2f)
22611:
2262        __(subl $node_size,%arg_y)
2263        __(movl (%arg_y),%arg_z)
2264        __(subl $node_size,%imm0)
2265        __(movl %arg_z,(%imm0))
2266        __(subl $node_size,%temp1)
2267        __(jne 1b)
22682:      __(movl %imm0,%esp)
2269        __(jmp *%ra0)
2270_endsubp(mvslide)
2271
2272_spentry(save_values)
2273        __(int $3)
2274_endsubp(save_values)
2275
2276_spentry(add_values)
2277        __(int $3)
2278_endsubp(add_values)
2279
2280_spentry(recover_values)
2281        __(int $3)
2282_endsubp(recover_values)
2283
2284_spentry(recover_values_for_mvcall)
2285        __(int $3)
2286_endsubp(recover_values_for_mvcall)
2287
2288_spentry(reset)
2289        __(int $3)
2290_endsubp(reset)
2291
2292/* temp0 = element-count, arg_y = subtag, arg_z = initval */
2293_spentry(misc_alloc_init)
2294        __(push %ebp)
2295        __(movl %esp,%ebp)
2296        __(push %arg_z)
2297        __(movl %arg_y,%arg_z)
2298        __(movl %temp0,%arg_y)
2299        __(push $local_label(misc_alloc_init_back))
2300        __(jmp _SPmisc_alloc)
2301__(tra(local_label(misc_alloc_init_back)))
2302        __(pop %arg_y)
2303        __(leave)
2304        __(movl $nrs.init_misc,%fname)
2305        __(set_nargs(2))
2306        __(jump_fname())
2307_endsubp(misc_alloc_init)
2308
2309_spentry(stack_misc_alloc_init)
2310        __(int $3)
2311_endsubp(stack_misc_alloc_init)
2312
2313        .globl C(popj)
2314_spentry(popj)
2315C(popj):
2316        __(leave)
2317        __(ret)
2318_endsubp(popj)
2319
2320/* arg_z should be of type (signed-byte 64) */
2321/* return unboxed value in mm0 */
2322_spentry(gets64)
2323        __(testb $fixnummask,%arg_z_b)
2324        __(jne 1f)
2325        __(unbox_fixnum(%arg_z,%imm0))
2326        __(movd %imm0,%mm0)
2327        __(jns 8f)
2328        /* get sign into upper half of %mm0 */
2329        __(pcmpeqd %mm1,%mm1)   /* all ones */
2330        __(psllq $32,%mm1)
2331        __(por %mm1,%mm0)
2332        __(ret)
23331:      __(movb %arg_z_b,%imm0_b)
2334        __(andb $tagmask,%imm0_b)
2335        __(cmpb $tag_misc,%imm0_b)
2336        __(jne 9f)
2337        __(movb misc_subtag_offset(%arg_z),%imm0_b)
2338        __(cmpb $subtag_bignum,%imm0_b)
2339        __(jne 9f)
2340        __(movl misc_header_offset(%arg_z),%imm0)
2341        __(cmpl $two_digit_bignum_header,%imm0)
2342        __(jne 9f)
2343        __(movq misc_data_offset(%arg_z),%mm0)
23448:      __(repret)
23459:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
2346_endsubp(gets64)
2347
2348/* arg_z should be of type (unsigned-byte 64) */
2349/* return unboxed value in mm0 */
2350_spentry(getu64)
2351        __(int $3)
2352        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
2353        __(testl %arg_z,%imm0)
2354        __(movl %arg_z,%imm0)
2355        __(jne 1f)
2356        __(sarl $fixnumshift,%imm0)
2357        __(movd %imm0,%mm0)
2358        __(ret)
23591:      __(andb $tagmask,%imm0_b)
2360        __(cmpb $tag_misc,%imm0_b)
2361        __(jne 9f)
2362        __(movb misc_subtag_offset(%arg_z),%imm0_b)
2363        __(cmpb $subtag_bignum,%imm0_b)
2364        __(jne 9f)
2365        __(movl misc_header_offset(%arg_z),%imm0)
2366        __(cmpl $three_digit_bignum_header,%imm0)
2367        __(je 3f)
2368        __(cmpl $two_digit_bignum_header,%imm0)
2369        __(jne 9f)
2370        __(movl misc_data_offset+4(%arg_z),%imm0)
2371        __(testl %imm0,%imm0)
2372        __(js 9f)
2373        __(movq misc_data_offset(%arg_z),%mm0)
2374        __(ret)
23753:      __(movl misc_data_offset(%arg_z),%imm0)
2376        __(cmpl $0,misc_data_offset+8(%arg_z))
2377        __(jne 9f)
2378        __(movq misc_data_offset(%arg_z),%mm0)
2379        __(repret)
23809:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
2381_endsubp(getu64)
2382
2383_spentry(makeu64)
2384        __(int $3)
2385_endsubp(makeu64)
2386
2387/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
2388/* unbound_marker), arg_y = symbol */
2389_spentry(specref)
2390        __(int $3)
2391_endsubp(specref)
2392
2393/* arg_y = special symbol, arg_z = new value. */
2394_spentry(specset)
2395        __(movl symbol.binding_index(%arg_y),%imm0)
2396        __(cmp %rcontext:tcr.tlb_limit,%imm0)
2397        __(movl %rcontext:tcr.tlb_pointer,%temp1)
2398        __(jae 1f)
2399        __(movl (%temp1,%imm0),%temp0)
2400        __(cmpb $no_thread_local_binding_marker,%temp0_b)
2401        __(je 1f)
2402        __(movl %arg_z,(%temp1,%imm0))
2403        __(ret)
24041:      __(movl %arg_y,%temp0)
2405        __(movl $1<<fixnumshift,%arg_y)
2406        __(jmp _SPgvset)
2407_endsubp(specset)
2408
2409_spentry(specrefcheck)
2410        __(mov %arg_z,%arg_y)
2411        __(movl symbol.binding_index(%arg_z),%imm0)
2412        __(cmp %rcontext:tcr.tlb_limit,%imm0)
2413        __(jae 7f)
2414        __(movl %rcontext:tcr.tlb_pointer,%temp1)
2415        __(movl (%temp1,%imm0),%arg_z)
2416        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
2417        __(jne 8f)
24187:      __(movl symbol.vcell(%arg_y),%arg_z)
24198:      __(cmpb $unbound_marker,%arg_z_b)
2420        __(jne,pt 9f)
2421        __(uuo_error_reg_unbound(Rarg_y))
24229:      __(repret)
2423_endsubp(specrefcheck)
2424
2425_spentry(restoreintlevel)
2426        __(int $3)
2427_endsubp(restoreintlevel)
2428
2429/* Make a lisp integer from the unsigned value in imm0 */
2430_spentry(makeu32)
2431        __(cmpl $(1<<29),%imm0)
2432        __(jae 0f)      /* need to make a bignum */
2433        __(box_fixnum(%imm0,%arg_z))
2434        __(ret)
24350:      __(movd %imm0,%mm1)
2436        __(test %imm0,%imm0)
2437        __(js 1f)
2438        __(movl $one_digit_bignum_header,%imm0)
2439        __(movd %imm0,%mm0)
2440        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
2441        __(movd %mm1,misc_data_offset(%arg_z))
2442        __(ret)
24431:      __(movl $two_digit_bignum_header,%imm0)
2444        __(movd %imm0,%mm0)
2445        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
2446        __(movd %mm1,misc_data_offset(%arg_z))
2447        __(ret)
2448_endsubp(makeu32)
2449
2450_spentry(gets32)
2451        __(int $3)
2452_endsubp(gets32)
2453
2454_spentry(getu32)
2455        __(int $3)
2456_endsubp(getu32)
2457
2458_spentry(mvpasssym)
2459        __(int $3)
2460_endsubp(mvpasssym)
2461
2462/* */
2463_spentry(unbind)
2464        __(int $3)
2465_endsubp(unbind)
2466
2467_spentry(unbind_n)
2468        __(int $3)
2469_endsubp(unbind_n)
2470
2471_spentry(unbind_to)
2472        __(movl %rcontext:tcr.db_link,%temp0)
2473        __(movl %rcontext:tcr.tlb_pointer,%arg_z)
24741:
2475        __(movl binding.sym(%temp0),%temp1)
2476        __(movl binding.val(%temp0),%arg_y)
2477        __(movl binding.link(%temp0),%temp0)
2478        __(movl %arg_y,(%arg_z,%temp1))
2479        __(cmpl %temp0,%imm0)
2480        __(jne 1b)
2481        __(movl %temp0,%rcontext:tcr.db_link)
2482        __(ret)
2483_endsubp(unbind_to)
2484
2485_spentry(bind_interrupt_level_0)
2486        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2487        __(cmpl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2488        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2489        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
2490        __(push %rcontext:tcr.db_link)
2491        __(movl %esp,%rcontext:tcr.db_link)
2492        __(movl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2493        __(js,pn 1f)
24940:      __(jmp *%ra0)
2495        /* Interrupt level was negative; interrupt may be pending */
24961:      __(check_pending_enabled_interrupt(2f))
24972:      __(jmp *%ra0)
2498_endsubp(bind_interrupt_level_0)
2499
2500/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
2501/* of disabling interrupts.)   */
2502_spentry(bind_interrupt_level_m1)
2503        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2504        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2505        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
2506        __(push %rcontext:tcr.db_link)
2507        __(movl %esp,%rcontext:tcr.db_link)
2508        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2509        __(jmp *%ra0)
2510_endsubp(bind_interrupt_level_m1)
2511
2512/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
2513/* do what _SPbind_interrupt_level_0 does. */
2514_spentry(bind_interrupt_level)
2515        __(test %arg_z,%arg_z)
2516        __(jz _SPbind_interrupt_level_0)
2517        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2518        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2519        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
2520        __(push %rcontext:tcr.db_link)
2521        __(movl %esp,%rcontext:tcr.db_link)
2522        __(movl %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2523        __(jmp *%ra0)
2524_endsubp(bind_interrupt_level)
2525
2526/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
2527/* non-negative, check for pending interrupts. */
2528_spentry(unbind_interrupt_level)
2529        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2530        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
2531        __(test %imm0,%imm0)
2532        __(movl %rcontext:tcr.db_link,%imm0)
2533        __(movl binding.val(%imm0),%temp0)
2534        __(movl binding.link(%imm0),%imm0)
2535        __(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2536        __(movl %imm0,%rcontext:tcr.db_link)
2537        __(js,pn 1f)
25380:      __(repret)
25391:      __(test %temp0,%temp0)
2540        __(js 0b)
2541        __(check_pending_enabled_interrupt(2f))
25422:      __(repret)
2543_endsubp(unbind_interrupt_level)
2544
2545_spentry(progvrestore)
2546        __(int $3)
2547_endsubp(progvrestore)
2548
2549/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
2550/* inline.  Call out otherwise.   */
2551_spentry(builtin_plus)
2552        __(movl %arg_y,%imm0)
2553        __(orl %arg_z,%imm0)
2554        __(testb $fixnummask,%imm0_b)
2555        __(jne 1f)
2556        __(addl %arg_y,%arg_z)
2557        __(jo,pn C(fix_one_bit_overflow))
2558        __(repret)
25591:      __(jump_builtin(_builtin_plus,2))
2560_endsubp(builtin_plus)
2561
2562/* %arg_z <- %arg_y - %arg_z.  Do the fixnum case - including overflow -  */
2563/*  inline.  Call out otherwise.   */
2564_spentry(builtin_minus)
2565        __(movl %arg_y,%imm0)
2566        __(orl %arg_z,%imm0)
2567        __(testb $fixnummask,%imm0_b)
2568        __(jne 1f)
2569        __(xchgl %arg_y,%arg_z)
2570        __(subl %arg_y,%arg_z)
2571        __(jo,pn C(fix_one_bit_overflow))
2572        __(repret)
25731:      __(jump_builtin(_builtin_minus,2))
2574_endsubp(builtin_minus)
2575
2576/* %arg_z -< arg_y * arg_z. */
2577/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
2578_spentry(builtin_times)
2579        __(movl %arg_y,%imm0)
2580        __(orb %arg_z_b,%imm0_b)
2581        __(testb $fixnummask,%imm0_b)
2582        __(jne 2f)
2583        __(unbox_fixnum(%arg_z,%imm0))
2584        /* 32-bit fixnum result in %imm0.  Overflow set if it doesn't fit. */
2585        __(imul %arg_y,%imm0)
2586        __(jo 1f)
2587        __(movl %imm0,%arg_z)
2588        __(ret)
25891:      __(unbox_fixnum(%arg_z,%eax))
2590        __(mark_as_imm(%edx))
2591        __(unbox_fixnum(%arg_y,%edx))
2592        __(imul %edx)
2593        __(movd %eax,%mm0)
2594        __(movd %edx,%mm1)
2595        __(mark_as_node(%edx))
2596        __(psllq $32,%mm1)
2597        __(por %mm1,%mm0)
2598        __(jmp _SPmakes64)
25992:      __(jump_builtin(_builtin_times,2))
2600_endsubp(builtin_times)
2601
2602_spentry(builtin_div)
2603        __(jump_builtin(_builtin_div,2))
2604
2605/* %arg_z <- (= %arg_y %arg_z).   */
2606_spentry(builtin_eq)
2607        __(movl %arg_y,%imm0)
2608        __(orb %arg_z_b,%imm0_b)
2609        __(testb $fixnummask,%imm0_b)
2610        __(jne 1f)
2611        __(rcmpl(%arg_z,%arg_y))
2612        __(condition_to_boolean(e,%imm0,%arg_z))
2613        __(ret)
26141:      __(jump_builtin(_builtin_eq,2))
2615_endsubp(builtin_eq)
2616
2617/* %arg_z <- (/= %arg_y %arg_z).          */
2618_spentry(builtin_ne)
2619        __(movl %arg_y,%imm0)
2620        __(orb %arg_z_b,%imm0_b)
2621        __(testb $fixnummask,%imm0_b)
2622        __(jne 1f)
2623        __(rcmpl(%arg_z,%arg_y))
2624        __(condition_to_boolean(ne,%imm0,%arg_z))
2625        __(ret)
26261:      __(jump_builtin(_builtin_ne,2))
2627_endsubp(builtin_ne)
2628
2629/* %arg_z <- (> %arg_y %arg_z).   */
2630_spentry(builtin_gt)
2631        __(movl %arg_y,%imm0)
2632        __(orb %arg_z_b,%imm0_b)
2633        __(testb $fixnummask,%imm0_b)
2634        __(jne 1f)
2635        __(rcmpl(%arg_y,%arg_z))
2636        __(condition_to_boolean(g,%imm0,%arg_z))
2637        __(ret)
26381:      __(jump_builtin(_builtin_gt,2))
2639_endsubp(builtin_gt)
2640
2641/* %arg_z <- (>= %arg_y %arg_z).          */
2642_spentry(builtin_ge)
2643        __(movl %arg_y,%imm0)
2644        __(orb %arg_z_b,%imm0_b)
2645        __(testb $fixnummask,%imm0_b)
2646        __(jne 1f)
2647        __(rcmpl(%arg_y,%arg_z))
2648        __(condition_to_boolean(ge,%imm0,%arg_z))
2649        __(ret)
26501:      __(jump_builtin(_builtin_ge,2))
2651_endsubp(builtin_ge)
2652
2653/* %arg_z <- (< %arg_y %arg_z).   */
2654_spentry(builtin_lt)
2655        __(movl %arg_y,%imm0)
2656        __(orb %arg_z_b,%imm0_b)
2657        __(testb $fixnummask,%imm0_b)
2658        __(jne 1f)
2659        __(rcmpl(%arg_y,%arg_z))
2660        __(condition_to_boolean(l,%imm0,%arg_z))
2661        __(ret)
26621:      __(jump_builtin(_builtin_lt,2))
2663_endsubp(builtin_lt)
2664
2665/* %arg_z <- (<= %arg_y %arg_z).   */
2666_spentry(builtin_le)
2667        __(movl %arg_y,%imm0)
2668        __(orb %arg_z_b,%imm0_b)
2669        __(testb $fixnummask,%imm0_b)
2670        __(jne 1f)
2671        __(rcmpl(%arg_y,%arg_z))
2672        __(condition_to_boolean(le,%imm0,%arg_z))
2673        __(ret)
26741:      __(jump_builtin(_builtin_le,2))
2675_endsubp(builtin_le)
2676
2677_spentry(builtin_eql)
2678        __(cmpl %arg_y,%arg_z)
2679        __(je 1f)
2680        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
2681        /* and both have the same subtag. */
2682        __(movl %arg_y,%imm0)
2683        __(andb $tagmask,%imm0_b)
2684        __(cmpb $tag_misc,%imm0_b)
2685        __(jne 2f)
2686        __(movl %arg_z,%imm0)
2687        __(andb $tagmask,%imm0_b)
2688        __(jne 2f)
2689        __(extract_subtag(%arg_y,%imm0_b))
2690        __(extract_subtag(%arg_z,%imm0_bh))
2691        __(cmpb %imm0_b,%imm0_bh)
2692        __(jne 2f)
2693        __(jump_builtin(_builtin_eql,2))
26941:      __(movl $t_value,%arg_z)
2695        __(ret)
26962:      __(movl $nil_value,%arg_z)
2697        __(ret)
2698_endsubp(builtin_eql)
2699
2700_spentry(builtin_length)
2701        __(extract_fulltag(%arg_z,%imm0))
2702        __(cmpl $tag_list,%imm0)
2703        __(jz 2f)
2704        __(andl $tagmask,%imm0)
2705        __(cmpl $tag_misc,%imm0)
2706        __(jnz 8f)
2707        __(extract_subtag(%arg_z,%imm0_b))
2708        __(rcmpb(%imm0_b,$min_vector_subtag))
2709        __(jb 8f)
2710        __(je 1f)
2711        /* (simple-array * (*)) */
2712        __(movl %arg_z,%arg_y)
2713        __(vector_length(%arg_y,%arg_z))
2714        __(ret)
27151:      /* vector header */
2716        __(movl vectorH.logsize(%arg_z),%arg_z)
2717        __(ret)
27182:      /* list.  Maybe null, maybe dotted or circular. */
2719        __(movl $-fixnumone,%arg_y)
2720        __(movl %arg_z,%temp0)  /* fast pointer */
2721        __(movl %arg_z,%temp1)  /* slow pointer */
27223:      __(movb %temp0_b,%al)
2723        __(andb $fulltagmask,%al)
2724        __(addl $fixnumone,%arg_y)
2725        __(compare_reg_to_nil(%temp0))
2726        __(je 9f)
2727        __(cmpb $fulltag_cons,%al)
2728        __(jne 8f)
2729        __(movb %temp1_b,%ah)
2730        __(andb $fulltagmask,%ah)
2731        __(_cdr(%temp0,%temp0))
2732        __(testl $fixnumone,%arg_y)
2733        __(je 3b)
2734        __(cmpb $fulltag_cons,%ah)
2735        __(jne 8f)
2736        __(_cdr(%temp1,%temp1))
2737        __(cmpl %temp0,%temp1)
2738        __(jne 3b)
27398:
2740        __(jump_builtin(_builtin_length,1))
27419:
2742        __(movl %arg_y,%arg_z)
2743        __(ret)
2744_endsubp(builtin_length)
2745
2746_spentry(builtin_seqtype)
2747        __(int $3)
2748_endsubp(builtin_seqtype)
2749
2750_spentry(builtin_assq)
2751        __(cmpl $nil_value,%arg_z)
2752        __(je 5f)
27531:      __(movl %arg_z,%imm0)
2754        __(andb $fulltagmask,%imm0_b)
2755        __(cmpb $fulltag_cons,%imm0_b)
2756        __(je,pt 2f)
2757        __(uuo_error_reg_not_list(Rarg_z))
27582:      __(_car(%arg_z,%temp0))
2759        __(_cdr(%arg_z,%arg_z))
2760        __(cmpl $nil_value,%temp0)
2761        __(je 4f)
2762        __(movl %temp0,%imm0)
2763        __(andb $fulltagmask,%imm0_b)
2764        __(cmpb $fulltag_cons,%imm0_b)
2765        __(je,pt 3f)
2766        __(uuo_error_reg_not_list(Rtemp0))
27673:      __(_car(%temp0,%temp1))
2768        __(cmpl %temp0,%arg_y)
2769        __(jne 4f)
2770        __(movl %temp0,%arg_z)
2771        __(ret)
27724:      __(cmpl $nil_value,%arg_z)
27735:      __(jnz 1b)
2774        __(repret)
2775_endsubp(builtin_assq)
2776
2777_spentry(builtin_memq)
2778        __(int $3)
2779_endsubp(builtin_memq)
2780
2781logbitp_max_bit = 30
2782
2783_spentry(builtin_logbitp)
2784        /* Call out unless: both args fixnums, arg_y in [0, logbitp_max_bit) */
2785        __(movl %arg_z,%imm0)
2786        __(orl %arg_y,%imm0)
2787        __(testb $fixnummask,%imm0_b)
2788        __(jnz 1f)
2789        __(unbox_fixnum(%arg_y,%imm0))
2790        __(cmpb $logbitp_max_bit,%imm0_b)
2791        __(jae 1f)
2792        __(addb $fixnumshift,%imm0_b)
2793        __(bt %imm0,%arg_z)
2794        __(condition_to_boolean(b,%imm0,%arg_z))
2795        __(ret)
27961:      __(jump_builtin(_builtin_logbitp,2))
2797_endsubp(builtin_logbitp)
2798
2799_spentry(builtin_logior)
2800        __(movl %arg_y,%imm0)
2801        __(orb %arg_z_b,%imm0_b)
2802        __(testb $fixnummask,%imm0_b)
2803        __(jne 1f)
2804        __(orl %arg_y,%arg_z)
2805        __(ret)
28061:
2807        __(jump_builtin(_builtin_logior,2))
2808_endsubp(builtin_logior)
2809
2810_spentry(builtin_logand)
2811        __(movl %arg_y,%imm0)
2812        __(orb %arg_z_b,%imm0_b)
2813        __(testb $fixnummask,%imm0_b)
2814        __(jne 1f)
2815        __(andl %arg_y,%arg_z)
2816        __(ret)
28171:
2818        __(jump_builtin(_builtin_logand,2))
2819_endsubp(builtin_logand)
2820
2821_spentry(builtin_negate)
2822        __(testb $fixnummask,%arg_z_b)
2823        __(jne 1f)
2824        __(negl %arg_z)
2825        __(jo,pn C(fix_one_bit_overflow))
2826        __(repret)
28271:
2828        __(jump_builtin(_builtin_negate,1))
2829_endsubp(builtin_negate)
2830
2831_spentry(builtin_logxor)
2832        __(movl %arg_y,%imm0)
2833        __(orb %arg_z_b,%imm0_b)
2834        __(testb $fixnummask,%imm0_b)
2835        __(jne 1f)
2836        __(xorl %arg_y,%arg_z)
2837        __(ret)
28381:
2839        __(jump_builtin(_builtin_logxor,2))
2840_endsubp(builtin_logxor)
2841
2842_spentry(builtin_aset1)
2843        __(int $3)
2844_endsubp(builtin_aset1)
2845
2846_spentry(builtin_ash)
2847        __(movl %arg_y,%imm0)
2848        __(orb %arg_z_b,%imm0_b)
2849        __(testb $fixnummask,%imm0_b)
2850        __(jne 9f)
2851        __(unbox_fixnum(%arg_z,%imm0))
2852        /* Z flag set if zero ASH shift count */
2853        __(jnz 1f)
2854        __(movl %arg_y,%arg_z) /* shift by 0 */
2855        __(ret)
28561:      __(jns 3f)
2857        __(rcmpl(%imm0,$-31))
2858        __(jg 2f)
2859        __(unbox_fixnum(%arg_y,%imm0))
2860        __(sar $31,%imm0)
2861        __(box_fixnum(%imm0,%arg_z))
2862        __(ret)
28632:      /* Right-shift by small fixnum */
2864        __(negb %imm0_b)
2865        __(movzbl %imm0_b,%ecx)
2866        __(unbox_fixnum(%arg_y,%imm0))
2867        __(sar %cl,%imm0)
2868        __(box_fixnum(%imm0,%arg_z))
2869        __(ret)
28703:      /* Left shift by fixnum.  We can't shift by more than 31 bits, */
2871        /* though shifting by 32 is actually easy. */
2872        __(rcmpl(%imm0,$32))
2873        __(jg 9f)
2874        __(jne 4f)
2875        /* left-shift by 32 bits exactly */
2876        __(unbox_fixnum(%arg_y,%imm0))
2877        __(movd %imm0,%mm0)
2878        __(psllq $32,%mm0)
2879        __(jmp _SPmakes64)
28804:      /* left-shift by 1..31 bits. Safe to move shift count to %cl */
2881        __(movd %imm0,%mm1)     /* shift count */
2882        __(unbox_fixnum(%arg_y,%imm0))
2883        __(movd %imm0,%mm0)
2884        __(sarl $31,%imm0)      /* propagate sign */
2885        __(movd %imm0,%mm2)
2886        __(pshufw $0x4e,%mm2,%mm2) /* swap hi/lo halves */
2887        __(por %mm2,%mm0)
2888        __(psllq %mm1,%mm0)
2889        __(jmp _SPmakes64)
28909:
2891        __(jump_builtin(_builtin_ash,2))
2892_endsubp(builtin_ash)
2893
2894_spentry(builtin_aref1)
2895        __(extract_typecode(%arg_y,%imm0))
2896        __(box_fixnum_no_flags(%imm0,%temp0))
2897        __(cmpb $min_vector_subtag,%imm0_b)
2898        __(ja _SPsubtag_misc_ref)
2899        __(jump_builtin(_builtin_aref1,2))
2900_endsubp(builtin_aref1)
2901
2902/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
2903/* if so.  This might allow us to avoid having to have a priori */
2904/* knowledge of whether a foreign function returns a floating-point result. */
2905/* backlink to saved %esp, below */
2906/* arg n-1 */
2907/* arg n-2 */
2908/* ... */
2909/* arg 0 */
2910/* space for alignment */
2911/* previous %esp */
2912
2913_spentry(ffcall)
2914LocalLabelPrefix[]ffcall:
2915        __(unbox_fixnum(%arg_z,%imm0))
2916        __(testb $fixnummask,%arg_z_b)
2917        __(je 0f)
2918        __(movl macptr.address(%arg_z),%imm0)
29190:
2920        /* Save lisp registers. */
2921        __(push %ebp)
2922        __(mov %esp,%ebp)
2923        __(push %temp0)
2924        __(push %temp1)
2925        __(push %arg_y)
2926        __(push %arg_z)
2927        __(push %fn)
2928        __(movl %esp,%rcontext:tcr.save_vsp)
2929        __(movl %ebp,%rcontext:tcr.save_ebp)
2930        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
2931        __(movl %rcontext:tcr.foreign_sp,%esp)
2932        __(stmxcsr %rcontext:tcr.lisp_mxcsr)
2933        __(emms)
2934        __(ldmxcsr %rcontext:tcr.foreign_mxcsr)
2935        __(movl (%esp),%ebp)
2936LocalLabelPrefix[]ffcall_setup:
2937        __(addl $node_size,%esp)
2938LocalLabelPrefix[]ffcall_call:
2939        __(call *%eax)
2940LocalLabelPrefix[]ffcall_call_end:
2941        __(movl %ebp,%esp)
2942        __(movl %esp,%rcontext:tcr.foreign_sp)
2943        __(clr %arg_z)
2944        __(clr %arg_y)
2945        __(clr %temp1)
2946        __(clr %temp0)
2947        __(clr %fn)
2948        __(pxor %fpzero,%fpzero)
2949        __ifdef([DARWIN])
2950        /* Darwin's math library seems to cause spurious FP exceptions. */
2951        __(movl %arg_z,%rcontext:tcr.ffi_exception)
2952        __else
2953        __(stmxcsr %rcontext:tcr.ffi_exception)
2954        __endif
2955        __(movl %rcontext:tcr.save_vsp,%esp)
2956        __(movl %rcontext:tcr.save_ebp,%ebp)
2957        __(movl $TCR_STATE_LISP,%rcontext:tcr.valence)
2958        __(pop %fn)
2959        __(pop %arg_z)
2960        __(pop %arg_y)
2961        __(pop %temp1)
2962        __(ldmxcsr %rcontext:tcr.lisp_mxcsr)
2963        __(check_pending_interrupt(%temp0))
2964        __(pop %temp0)
2965        __(leave)
2966        __(ret)
2967        /* need to deal with NSExceptions and Objc-2.0 execptions */
2968_endsubp(ffcall)
2969
2970_spentry(ffcall_return_registers)
2971        __(int $3)
2972_endsubp(ffcall_return_registers)
2973
2974_spentry(spread_lexprz)
2975        __(int $3)
2976_endsubp(spread_lexprz)
2977
2978_spentry(callback)
2979        __(int $3)
2980_endsubp(callback)
2981
2982_spentry(aref2)
2983        __(int $3)
2984_endsubp(aref2)
2985
2986_spentry(aref3)
2987        __(int $3)
2988_endsubp(aref3)
2989
2990_spentry(aset2)
2991        __(int $3)
2992_endsubp(aset2)
2993
2994_spentry(aset3)
2995        __(int $3)
2996_endsubp(aset3)
2997
2998/* Prepend all but the first seven (6 words of code & other immediate data,
2999/* plus inner fn) and last (lfbits) elements of %fn to the "arglist". */
3000_spentry(call_closure)
3001        new_local_labels()
3002        __(vector_length(%fn,%imm0))
3003        __(subl $8<<fixnumshift,%imm0)  /* imm0 = inherited arg count */
3004        __(lea (%nargs,%imm0),%temp0)
3005        __(cmpl $nargregs<<fixnumshift,%temp0)
3006        __(jna local_label(regs_only))  /* either: 1 arg, 1 inherited, or */
3007                                        /* no args, 2 inherited */
3008        __(pop %rcontext:tcr.save0)             /* save return address */
3009        __(cmpl $nargregs<<fixnumshift,%nargs)
3010        __(jna local_label(no_insert))
3011
3012/* Some arguments have already been pushed.  Push %imm0's worth */
3013/* of NILs, copy those arguments that have already been vpushed from */
3014/* the old TOS to the new, then insert all of the inherited args */
3015/* and go to the function. */
3016
3017        __(mov %imm0,%temp0)
3018local_label(push_nil_loop):
3019        __(push $nil_value)
3020        __(sub $fixnumone,%temp0)
3021        __(jne local_label(push_nil_loop))
3022
3023        __(int $3)
3024/* Here if no args were pushed by the caller. */
3025/* cases: */
3026/* no args, more than two inherited args */
3027/* a single arg in arg_z, more than one inherited arg */
3028/* two args in arg_y and arg_z, some number of inherited args */
3029
3030/* Therefore, we're always going to have to push something (the sum of
3031/* %nargs and %imm0 will always be greater than $nargregs), and */
3032/* we will have to reserve space for a stack frame. */
3033/* The 0 args, 2 inherited case and the 1 arg, 1 inherited case get */
3034/* handled at local_label(regs_ony). */
3035       
3036local_label(no_insert):
3037        /* Reserve space for a stack frame */
3038        __(push $reserved_frame_marker)
3039        __(push $reserved_frame_marker)
3040        __(lea 7<<fixnumshift(%imm0),%temp0)    /* last inherited arg */
3041        __(rcmpl(%nargs,$fixnumone))
3042        __(je local_label(set_arg_y))
3043        __(jb local_label(set_y_z))
3044        /* %nargs = $nargregs (i.e., 2), vpush remaining inherited vars. */
3045
3046local_label(vpush_remaining):
3047        __(movl $7<<fixnumshift,%temp0)
3048local_label(vpush_remaining_loop):
3049        __(push misc_data_offset(%fn,%temp0))
3050        __(add $node_size,%temp0)
3051        __(add $fixnumone,%nargs)
3052        __(sub $node_size,%imm0)
3053        __(jnz local_label(vpush_remaining_loop))
3054        __(jmp local_label(go))
3055       
3056local_label(set_arg_y):
3057        /* one arg in arg_z.  set arg_y and vpush remaining inherited args */
3058        __(subl $node_size,%temp0)
3059        __(movl misc_data_offset(%fn,%temp0),%arg_y)
3060        __(addl $fixnumone,%nargs)
3061        __(subl $fixnumone,%imm0)
3062        __(jmp local_label(vpush_remaining))
3063local_label(set_y_z):
3064        __(subl $node_size,%temp0)
3065        __(movl misc_data_offset(%fn,%temp0),%arg_z)
3066        __(addl $fixnumone,%nargs)
3067        __(subl $fixnumone,%imm0)
3068        __(jmp local_label(set_arg_y))
3069
3070local_label(go):
3071        __(movl misc_data_offset+(6*node_size)(%fn),%fn)
3072        __(push %rcontext:tcr.save0)    /* restore return addr */
3073        __(movapd %fpzero,%rcontext:tcr.save0)  /* clear out spill area */
3074        __(jmp *%fn)
3075local_label(regs_only):
3076        __(lea 7<<fixnumshift(%imm0),%temp0)
3077        __(test %nargs,%nargs)
3078        __(jne local_label(one_arg))
3079        /* no args passed, two inherited args */
3080        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_z)
3081        __(cmpl $node_size,%imm0)
3082        __(je local_label(rgo))
3083        __(movl misc_data_offset-(node_size*2)(%fn,%temp0),%arg_y)
3084local_label(rgo):
3085        __(addl %imm0,%nargs)
3086        __(jmp *misc_data_offset+(6*node_size)(%fn))
3087local_label(one_arg):
3088        /* one arg was passed, so there's one inherited arg */
3089        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_y)
3090        __(jmp local_label(rgo))
3091_endsubp(call_closure)
3092
3093_spentry(poweropen_callbackX)
3094        __(int $3)
3095_endsubp(poweropen_callbackX)
3096
3097_spentry(poweropen_ffcallX)
3098        __(int $3)
3099_endsubp(poweropen_ffcallX)
3100
3101_spentry(eabi_ff_call)
3102        __(int $3)
3103_endsubp(eabi_ff_call)
3104
3105_spentry(eabi_callback)
3106        __(int $3)
3107_endsubp(eabi_callback)
3108
3109
3110/* Unused, and often not used on PPC either  */
3111_spentry(callbuiltin)
3112        __(int $3)
3113_endsubp(callbuiltin)
3114
3115_spentry(callbuiltin0)
3116        __(int $3)
3117_endsubp(callbuiltin0)
3118
3119_spentry(callbuiltin1)
3120        __(int $3)
3121_endsubp(callbuiltin1)
3122
3123_spentry(callbuiltin2)
3124        __(int $3)
3125_endsubp(callbuiltin2)
3126
3127_spentry(callbuiltin3)
3128        __(int $3)
3129_endsubp(callbuiltin3)
3130
3131_spentry(restorefullcontext)
3132        __(int $3)
3133_endsubp(restorefullcontext)
3134
3135_spentry(savecontextvsp)
3136        __(int $3)
3137_endsubp(savecontextvsp)
3138
3139_spentry(savecontext0)
3140        __(int $3)
3141_endsubp(savecontext0)
3142
3143_spentry(restorecontext)
3144        __(int $3)
3145_endsubp(restorecontext)
3146
3147_spentry(stkconsyz)
3148        __(int $3)
3149_endsubp(stkconsyz)
3150
3151_spentry(stkvcell0)
3152        __(int $3)
3153_endsubp(stkvcell0)
3154
3155_spentry(stkvcellvsp)
3156        __(int $3)
3157_endsubp(stkvcellvsp)
3158
3159_spentry(breakpoint)
3160        __(int $3)
3161_endsubp(breakpoint)
3162
3163_spentry(unused_5)
3164        __(int $3)
3165_endsubp(unused_5)
3166
3167_spentry(unused_6)
3168        __(int $3)
3169_endsubp(unused_6)
3170
Note: See TracBrowser for help on using the repository browser.