source: branches/working-0711/ccl/lisp-kernel/x86-spentry32.s @ 11164

Last change on this file since 11164 was 11164, checked in by gz, 12 years ago

Another batch of changes from the trunk, some bug fixes, optimizations, as well as formatting unification

File size: 152.1 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)
22Xspentry_start:                 
23        .globl C(bad_funcall)
24__(tra(C(bad_funcall)))
25        __(uuo_error_not_callable)
26_endsubp(bad_funcall)
27
28/* %arg_z has overflowed by one bit.  Make a bignum with 1 (32-bit) digit. */
29_spentry(fix_overflow)
30C(fix_one_bit_overflow):
31        __(movl $one_digit_bignum_header,%imm0)
32        __(movd %imm0,%mm0)
33        __(Misc_Alloc_Fixed([],aligned_bignum_size(1)))
34        __(unbox_fixnum(%arg_z,%imm0))
35        __(xor $0xc0000000,%imm0)
36        __(mov %temp0,%arg_z)
37        __(movl %imm0,misc_data_offset(%arg_z))
38        __(ret)
39_endsubp(fix_overflow)
40
41/* %arg_y = vector, %arg_z = unscaled-idx */
42_spentry(misc_ref)
43        __(mov %arg_y,%imm0)
44        __(andb $tagmask,%imm0_b)
45        __(cmpb $tag_misc,%imm0_b)
46        __(je 0f)
47        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
480:      __(testb $fixnummask,%arg_z_b)
49        __(je 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        __(cmpl %imm0,%arg_z)
55        __(jb 2f)
56        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
572:      __(xorl %imm0,%imm0)
58        __(movb misc_subtag_offset(%arg_y),%imm0_b)
59        /* fall through */
60_endsubp(misc_ref)
61
62/* %imm0_b = subtag, %arg_y = vector, %arg_z = index. */
63/* Bounds/type-checking done in caller. */
64_startfn(C(misc_ref_common))
65        __(movzbl %imm0_b,%imm0)
66        __(leal local_label(misc_ref_jmp)(,%imm0,4),%imm0)
67        __(jmp *(%imm0))
68        .p2align 2
69local_label(misc_ref_jmp):
70        /* 00-0f */
71        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
72        .long local_label(misc_ref_invalid) /* 01 cons  */
73        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
74        .long local_label(misc_ref_invalid) /* 03 imm  */
75        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
76        .long local_label(misc_ref_invalid) /* 05 tra  */
77        .long local_label(misc_ref_invalid) /* 06 misc  */
78        .long local_label(misc_ref_u32) /* 07 bignum  */
79        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
80        .long local_label(misc_ref_invalid) /* 09 cons  */
81        .long local_label(misc_ref_node) /* 0a ratio  */
82        .long local_label(misc_ref_invalid) /* 0b imm  */
83        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
84        .long local_label(misc_ref_invalid) /* 0d tra  */
85        .long local_label(misc_ref_invalid) /* 0e misc  */
86        .long local_label(misc_ref_u32) /* 0f single_float  */
87        /* 10-1*/
88        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
89        .long local_label(misc_ref_invalid) /* 11 cons  */
90        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
91        .long local_label(misc_ref_invalid) /* 13 imm  */
92        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
93        .long local_label(misc_ref_invalid) /* 15 tra  */
94        .long local_label(misc_ref_invalid) /* 16 misc  */
95        .long local_label(misc_ref_u32) /* 17 double_float  */
96        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
97        .long local_label(misc_ref_invalid) /* 19 cons  */
98        .long local_label(misc_ref_node) /* 1a complex  */
99        .long local_label(misc_ref_invalid) /* 1b imm  */
100        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
101        .long local_label(misc_ref_invalid) /* 1d tra  */
102        .long local_label(misc_ref_invalid) /* 1e misc  */
103        .long local_label(misc_ref_u32) /* 1f macptr  */
104        /* 20-2*/
105        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
106        .long local_label(misc_ref_invalid) /* 21 cons  */
107        .long local_label(misc_ref_invalid) /* 22 catch_frame  */
108        .long local_label(misc_ref_invalid) /* 23 imm  */
109        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
110        .long local_label(misc_ref_invalid) /* 25 tra  */
111        .long local_label(misc_ref_invalid) /* 26 misc  */
112        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
113        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
114        .long local_label(misc_ref_invalid) /* 29 cons  */
115        .long local_label(misc_ref_function) /* 2a function  */
116        .long local_label(misc_ref_invalid) /* 2b imm  */
117        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
118        .long local_label(misc_ref_invalid) /* 2d tra  */
119        .long local_label(misc_ref_invalid) /* 2e misc  */
120        .long local_label(misc_ref_invalid) /* 2f immheader  */
121        /* 30-3*/
122        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
123        .long local_label(misc_ref_invalid) /* 31 cons  */
124        .long local_label(misc_ref_invalid) /* 32 nodeheader  */
125        .long local_label(misc_ref_invalid) /* 33 imm  */
126        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
127        .long local_label(misc_ref_invalid) /* 35 tra  */
128        .long local_label(misc_ref_invalid) /* 36 misc  */
129        .long local_label(misc_ref_invalid) /* 37 immheader  */
130        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
131        .long local_label(misc_ref_invalid) /* 39 cons  */
132        .long local_label(misc_ref_node) /* 3a symbol  */
133        .long local_label(misc_ref_invalid) /* 3b imm  */
134        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
135        .long local_label(misc_ref_invalid) /* 3d tra  */
136        .long local_label(misc_ref_invalid) /* 3e misc  */
137        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
138        /* 40-4*/
139        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
140        .long local_label(misc_ref_invalid) /* 41 cons  */
141        .long local_label(misc_ref_node) /* 42 lock  */
142        .long local_label(misc_ref_invalid) /* 43 imm  */
143        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
144        .long local_label(misc_ref_invalid) /* 45 tra  */
145        .long local_label(misc_ref_invalid) /* 46 misc  */
146        .long local_label(misc_ref_invalid) /* 47 immheader  */
147        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
148        .long local_label(misc_ref_invalid) /* 49 cons  */
149        .long local_label(misc_ref_node) /* 4a hash_vector  */
150        .long local_label(misc_ref_invalid) /* 4b imm  */
151        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
152        .long local_label(misc_ref_invalid) /* 4d tra  */
153        .long local_label(misc_ref_invalid) /* 4e misc  */
154        .long local_label(misc_ref_invalid) /* 4f immheader  */
155        /* 50-5*/
156        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
157        .long local_label(misc_ref_invalid) /* 51 cons  */
158        .long local_label(misc_ref_node) /* 52 pool  */
159        .long local_label(misc_ref_invalid) /* 53 imm  */
160        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
161        .long local_label(misc_ref_invalid) /* 55 tra  */
162        .long local_label(misc_ref_invalid) /* 56 misc  */
163        .long local_label(misc_ref_invalid) /* 57 immheader  */
164        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
165        .long local_label(misc_ref_invalid) /* 59 cons  */
166        .long local_label(misc_ref_node) /* 5a weak  */
167        .long local_label(misc_ref_invalid) /* 5b imm  */
168        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
169        .long local_label(misc_ref_invalid) /* 5d tra  */
170        .long local_label(misc_ref_invalid) /* 5e misc  */
171        .long local_label(misc_ref_invalid) /* 5f immheader  */
172        /* 60-6*/
173        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
174        .long local_label(misc_ref_invalid) /* 61 cons  */
175        .long local_label(misc_ref_node) /* 62 package  */
176        .long local_label(misc_ref_invalid) /* 63 imm  */
177        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
178        .long local_label(misc_ref_invalid) /* 65 tra  */
179        .long local_label(misc_ref_invalid) /* 66 misc  */
180        .long local_label(misc_ref_invalid) /* 67 immheader  */
181        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
182        .long local_label(misc_ref_invalid) /* 69 cons  */
183        .long local_label(misc_ref_node) /* 6a slot_vector  */
184        .long local_label(misc_ref_invalid) /* 6b imm  */
185        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
186        .long local_label(misc_ref_invalid) /* 6d tra  */
187        .long local_label(misc_ref_invalid) /* 6e misc  */
188        .long local_label(misc_ref_invalid) /* 6f immheader  */
189        /* 70-7*/
190        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
191        .long local_label(misc_ref_invalid) /* 71 cons  */
192        .long local_label(misc_ref_node) /* 72 instance  */
193        .long local_label(misc_ref_invalid) /* 73 imm  */
194        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
195        .long local_label(misc_ref_invalid) /* 75 tra  */
196        .long local_label(misc_ref_invalid) /* 76 misc  */
197        .long local_label(misc_ref_invalid) /* 77 immheader  */
198        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
199        .long local_label(misc_ref_invalid) /* 79 cons  */
200        .long local_label(misc_ref_node) /* 7a struct  */
201        .long local_label(misc_ref_invalid) /* 7b imm  */
202        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
203        .long local_label(misc_ref_invalid) /* 7d tra  */
204        .long local_label(misc_ref_invalid) /* 7e misc  */
205        .long local_label(misc_ref_invalid) /* 7f immheader  */
206        /* 80-8*/
207        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
208        .long local_label(misc_ref_invalid) /* 81 cons  */
209        .long local_label(misc_ref_node) /* 82 istruct  */
210        .long local_label(misc_ref_invalid) /* 83 imm  */
211        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
212        .long local_label(misc_ref_invalid) /* 85 tra  */
213        .long local_label(misc_ref_invalid) /* 86 misc  */
214        .long local_label(misc_ref_invalid) /* 87 immheader  */
215        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
216        .long local_label(misc_ref_invalid) /* 89 cons  */
217        .long local_label(misc_ref_node) /* 8a value_cell  */
218        .long local_label(misc_ref_invalid) /* 8b imm  */
219        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
220        .long local_label(misc_ref_invalid) /* 8d tra  */
221        .long local_label(misc_ref_invalid) /* 8e misc  */
222        .long local_label(misc_ref_invalid) /* 8f immheader  */
223        /* 90-9*/
224        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
225        .long local_label(misc_ref_invalid) /* 91 cons  */
226        .long local_label(misc_ref_node) /* 92 xfunction  */
227        .long local_label(misc_ref_invalid) /* 93 imm  */
228        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
229        .long local_label(misc_ref_invalid) /* 95 tra  */
230        .long local_label(misc_ref_invalid) /* 96 misc  */
231        .long local_label(misc_ref_invalid) /* 97 immheader  */
232        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
233        .long local_label(misc_ref_invalid) /* 99 cons  */
234        .long local_label(misc_ref_node) /* 9a arrayH  */
235        .long local_label(misc_ref_invalid) /* 9b imm  */
236        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
237        .long local_label(misc_ref_invalid) /* 9d tra  */
238        .long local_label(misc_ref_invalid) /* 9e misc  */
239        .long local_label(misc_ref_invalid) /* 9f immheader  */
240        /* a0-af  */
241        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
242        .long local_label(misc_ref_invalid) /* a1 cons  */
243        .long local_label(misc_ref_node) /* a2 vectorH  */
244        .long local_label(misc_ref_invalid) /* a3 imm  */
245        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
246        .long local_label(misc_ref_invalid) /* a5 tra  */
247        .long local_label(misc_ref_invalid) /* a6 misc  */
248        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
249        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
250        .long local_label(misc_ref_invalid) /* a9 cons  */
251        .long local_label(misc_ref_node) /* aa simple_vector  */
252        .long local_label(misc_ref_invalid) /* ab imm  */
253        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
254        .long local_label(misc_ref_invalid) /* ad tra  */
255        .long local_label(misc_ref_invalid) /* ae misc  */
256        .long local_label(misc_ref_u32) /* af u32  */
257        /* b0-bf  */
258        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
259        .long local_label(misc_ref_invalid) /* b1 cons  */
260        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
261        .long local_label(misc_ref_invalid) /* b3 imm  */
262        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
263        .long local_label(misc_ref_invalid) /* b5 tra  */
264        .long local_label(misc_ref_invalid) /* b6 misc  */
265        .long local_label(misc_ref_s32) /* b7 s32  */
266        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
267        .long local_label(misc_ref_invalid) /* b9 cons  */
268        .long local_label(misc_ref_invalid) /* ba nodeheader  */
269        .long local_label(misc_ref_invalid) /* bb imm  */
270        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
271        .long local_label(misc_ref_invalid) /* bd tra  */
272        .long local_label(misc_ref_invalid) /* be misc  */
273        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
274        /* c0-cf  */
275        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
276        .long local_label(misc_ref_invalid) /* c1 cons  */
277        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
278        .long local_label(misc_ref_invalid) /* c3 imm  */
279        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
280        .long local_label(misc_ref_invalid) /* c5 tra  */
281        .long local_label(misc_ref_invalid) /* c6 misc  */
282        .long local_label(misc_ref_string) /* c7 simple_base_string  */
283        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
284        .long local_label(misc_ref_invalid) /* c9 cons  */
285        .long local_label(misc_ref_invalid) /* ca nodeheader  */
286        .long local_label(misc_ref_invalid) /* cb imm  */
287        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
288        .long local_label(misc_ref_invalid) /* cd tra  */
289        .long local_label(misc_ref_invalid) /* ce misc  */
290        .long local_label(misc_ref_u8) /* cf u8  */
291        /* d0-df  */
292        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
293        .long local_label(misc_ref_invalid) /* d1 cons  */
294        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
295        .long local_label(misc_ref_invalid) /* d3 imm  */
296        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
297        .long local_label(misc_ref_invalid) /* d5 tra  */
298        .long local_label(misc_ref_invalid) /* d6 misc  */
299        .long local_label(misc_ref_s8)      /* d7 s8  */
300        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
301        .long local_label(misc_ref_invalid) /* d9 cons  */
302        .long local_label(misc_ref_invalid) /* da nodeheader  */
303        .long local_label(misc_ref_invalid) /* db imm  */
304        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
305        .long local_label(misc_ref_invalid) /* dd tra  */
306        .long local_label(misc_ref_invalid) /* de misc  */
307        .long local_label(misc_ref_invalid) /* df immheader  */
308        /* e0-ef  */
309        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
310        .long local_label(misc_ref_invalid) /* e1 cons  */
311        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
312        .long local_label(misc_ref_invalid) /* e3 imm  */
313        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
314        .long local_label(misc_ref_invalid) /* e5 tra  */
315        .long local_label(misc_ref_invalid) /* e6 misc  */
316        .long local_label(misc_ref_u16) /* e7 u16  */
317        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
318        .long local_label(misc_ref_invalid) /* e9 cons  */
319        .long local_label(misc_ref_invalid) /* ea nodeheader  */
320        .long local_label(misc_ref_invalid) /* eb imm  */
321        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
322        .long local_label(misc_ref_invalid) /* ed tra  */
323        .long local_label(misc_ref_invalid) /* ee misc  */
324        .long local_label(misc_ref_s16) /* ef s16  */
325        /* f0-ff  */
326        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
327        .long local_label(misc_ref_invalid) /* f1 cons  */
328        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
329        .long local_label(misc_ref_invalid) /* f3 imm  */
330        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
331        .long local_label(misc_ref_invalid) /* f5 tra  */
332        .long local_label(misc_ref_invalid) /* f6 misc  */
333        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
334        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
335        .long local_label(misc_ref_invalid) /* f9 cons  */
336        .long local_label(misc_ref_invalid) /* fa nodeheader  */
337        .long local_label(misc_ref_invalid) /* fb imm  */
338        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
339        .long local_label(misc_ref_invalid) /* fd tra  */
340        .long local_label(misc_ref_invalid) /* fe misc  */
341        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
342
343/* Functions are funny.  The first N words are treated as */
344/* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
345
346local_label(misc_ref_function):
347        __(movzwl misc_data_offset(%arg_y), %imm0)
348        __(shl $fixnumshift,%imm0)
349        __(rcmpl(%arg_z,%imm0))
350        __(jb local_label(misc_ref_u32))
351local_label(misc_ref_node):
352        __(movl misc_data_offset(%arg_y,%arg_z),%arg_z)
353        __(ret)
354local_label(misc_ref_u32):
355        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
356        __(jmp _SPmakeu32)
357local_label(misc_ref_s32):
358        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
359        __(jmp _SPmakes32)
360local_label(misc_ref_single_float_vector):
361        __(movss misc_data_offset(%arg_y,%arg_z),%fp1)
362        __(movl $single_float_header,%imm0)
363        __(movd %imm0,%mm0)
364        __(Misc_Alloc_Fixed(%arg_z,single_float.size))
365        __(movss %fp1,single_float.value(%arg_z))
366        __(ret)
367local_label(misc_ref_double_float_vector):
368        __(movsd misc_dfloat_offset(%arg_y,%arg_z,2),%fp1)
369        __(movl $double_float_header,%imm0)
370        __(movd %imm0,%mm0)
371        __(Misc_Alloc_Fixed(%arg_z,double_float.size))
372        __(movsd %fp1,double_float.value(%arg_z))
373        __(ret)
374local_label(misc_ref_fixnum_vector):
375        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
376        __(box_fixnum(%imm0,%arg_z))
377        __(ret)
378local_label(misc_ref_u8):
379        __(movl %arg_z,%imm0)
380        __(shr $2,%imm0)
381        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0)
382        __(box_fixnum(%imm0,%arg_z))
383        __(ret)
384local_label(misc_ref_s8):
385        __(movl %arg_z,%imm0)
386        __(shr $2,%imm0)
387        __(movsbl misc_data_offset(%arg_y,%imm0),%imm0)
388        __(box_fixnum(%imm0,%arg_z))
389        __(ret)
390local_label(misc_ref_string):
391        __(movl %arg_z,%imm0)
392        __(movl misc_data_offset(%arg_y,%imm0),%imm0)
393        __(shll $charcode_shift,%imm0)
394        __(leal subtag_character(%imm0),%arg_z)
395        __(ret)
396local_label(misc_ref_u16):
397        __(movl %arg_z,%imm0)
398        __(shrl $1,%imm0)
399        __(movzwl misc_data_offset(%arg_y,%imm0),%imm0)
400        __(box_fixnum(%imm0,%arg_z))
401        __(ret)
402local_label(misc_ref_s16):
403        __(movl %arg_z,%imm0)
404        __(shrl $1,%imm0)
405        __(movswl misc_data_offset(%arg_y,%imm0),%imm0)
406        __(box_fixnum(%imm0,%arg_z))
407        __(ret)
408local_label(misc_ref_bit_vector):
409        __(unbox_fixnum(%arg_z,%imm0))
410        __(btl %imm0,misc_data_offset(%arg_y))
411        __(setc %imm0_b)
412        __(movzbl %imm0_b,%imm0)
413        __(box_fixnum(%imm0,%arg_z))
414        __(ret)
415local_label(misc_ref_invalid):
416        __(push $reserved_frame_marker)
417        __(push $reserved_frame_marker)
418        __(push $XBADVEC)
419        __(set_nargs(3))
420        __(jmp _SPksignalerr)
421_endfn(C(misc_ref_common))
422
423/* Like misc_ref, only the boxed subtag is in temp0. */
424_spentry(subtag_misc_ref)
425        __(mov %arg_y,%imm0)
426        __(and $tagmask,%imm0)
427        __(cmp $tag_misc,%imm0)
428        __(je 0f)
429        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
4300:      __(testb $fixnummask,%arg_z_b)
431        __(je 1f)
432        __(uuo_error_reg_not_fixnum(Rarg_z))
4331:      __(movl misc_header_offset(%arg_y),%imm0)
434        __(xorb %imm0_b,%imm0_b)
435        __(shrl $num_subtag_bits-fixnumshift,%imm0)
436        __(cmp %imm0,%arg_z)
437        __(jb 2f)
438        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
4392:      __(unbox_fixnum(%temp0,%imm0))
440        __(jmp C(misc_ref_common))
441_endsubp(subtag_misc_ref)
442
443/* Like misc_set, only the boxed subtag is in temp1. */
444_spentry(subtag_misc_set)
445        __(mov %temp0,%imm0)
446        __(andb $tagmask,%imm0_b)
447        __(cmpb $tag_misc,%imm0_b)
448        __(je 0f)
449        __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4500:      __(mov %arg_y,%imm0)
451        __(testb $fixnummask,%imm0_b)
452        __(je 1f)
453        __(uuo_error_reg_not_fixnum(Rarg_y))
4541:      __(movl misc_header_offset(%temp0),%imm0)
455        __(xorb %imm0_b,%imm0_b)
456        __(shrl $num_subtag_bits-fixnumshift,%imm0)
457        __(cmpl %imm0,%arg_y)
458        __(jb 2f)
459        __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
4602:      __(unbox_fixnum(%temp1,%imm0))
461        __(jmp C(misc_set_common))
462_endsubp(subtag_misc_set)
463
464/* %temp0 = vector, %arg_y = unscaled-idx, %arg_z = val */
465_spentry(misc_set)
466        __(mov %temp0,%imm0)
467        __(andb $tagmask,%imm0_b)
468        __(cmpb $tag_misc,%imm0_b)
469        __(je 0f)
470        __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4710:      __(mov %arg_y,%imm0)    /* no byte reg for %arg_y/%esi */
472        __(testb $fixnummask,%imm0_b)
473        __(je 1f)
474        __(uuo_error_reg_not_fixnum(Rarg_y))
4751:      __(movl misc_header_offset(%temp0),%imm0)
476        __(xorb %imm0_b,%imm0_b)
477        __(shrl $num_subtag_bits-fixnumshift,%imm0)
478        __(cmpl %imm0,%arg_y)
479        __(jb 2f)
480        __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
4812:      __(xorl %imm0,%imm0)
482        __(movb misc_subtag_offset(%temp0),%imm0_b)
483        /* fall through */
484_endsubp(misc_set)
485
486/* imm0_b = subtag, %temp0 = vector, %arg_y = index, %arg_z = value */
487_startfn(C(misc_set_common))
488        __(movzbl %imm0_b,%imm0)
489        __(leal local_label(misc_set_jmp)(,%imm0,4),%imm0)
490        __(jmp *(%imm0))
491        .p2align 2
492local_label(misc_set_jmp):
493        /* 00-0f */
494        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
495        .long local_label(misc_set_invalid) /* 01 cons  */
496        .long local_label(misc_set_invalid) /* 02 nodeheader  */
497        .long local_label(misc_set_invalid) /* 03 imm  */
498        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
499        .long local_label(misc_set_invalid) /* 05 tra  */
500        .long local_label(misc_set_invalid) /* 06 misc  */
501        .long local_label(misc_set_u32) /* 07 bignum  */
502        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
503        .long local_label(misc_set_invalid) /* 09 cons  */
504        .long _SPgvset /* 0a ratio  */
505        .long local_label(misc_set_invalid) /* 0b imm  */
506        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
507        .long local_label(misc_set_invalid) /* 0d tra  */
508        .long local_label(misc_set_invalid) /* 0e misc  */
509        .long local_label(misc_set_u32) /* 0f single_float  */
510        /* 10-1f  */
511        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
512        .long local_label(misc_set_invalid) /* 11 cons  */
513        .long local_label(misc_set_invalid) /* 12 nodeheader  */
514        .long local_label(misc_set_invalid) /* 13 imm  */
515        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
516        .long local_label(misc_set_invalid) /* 15 tra  */
517        .long local_label(misc_set_invalid) /* 16 misc  */
518        .long local_label(misc_set_u32) /* 17 double_float  */
519        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
520        .long local_label(misc_set_invalid) /* 19 cons  */
521        .long _SPgvset /* 1a complex  */
522        .long local_label(misc_set_invalid) /* 1b imm  */
523        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
524        .long local_label(misc_set_invalid) /* 1d tra  */
525        .long local_label(misc_set_invalid) /* 1e misc  */
526        .long local_label(misc_set_u32) /* 1f macptr  */
527        /* 20-2f  */
528        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
529        .long local_label(misc_set_invalid) /* 21 cons  */
530        .long local_label(misc_set_invalid) /* 22 catch_frame  */
531        .long local_label(misc_set_invalid) /* 23 imm  */
532        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
533        .long local_label(misc_set_invalid) /* 25 tra  */
534        .long local_label(misc_set_invalid) /* 26 misc  */
535        .long local_label(misc_set_u32) /* 27 dead_macptr  */
536        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
537        .long local_label(misc_set_invalid) /* 29 cons  */
538        .long local_label(misc_set_function) /* 2a function  */
539        .long local_label(misc_set_invalid) /* 2b imm  */
540        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
541        .long local_label(misc_set_invalid) /* 2d tra  */
542        .long local_label(misc_set_invalid) /* 2e misc  */
543        .long local_label(misc_set_invalid) /* 2f immheader  */
544        /* 30-3f  */
545        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
546        .long local_label(misc_set_invalid) /* 31 cons  */
547        .long local_label(misc_set_invalid) /* 32 nodeheader  */
548        .long local_label(misc_set_invalid) /* 33 imm  */
549        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
550        .long local_label(misc_set_invalid) /* 35 tra  */
551        .long local_label(misc_set_invalid) /* 36 misc  */
552        .long local_label(misc_set_invalid) /* 37 immheader  */
553        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
554        .long local_label(misc_set_invalid) /* 39 cons  */
555        .long _SPgvset /* 3a symbol  */
556        .long local_label(misc_set_invalid) /* 3b imm  */
557        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
558        .long local_label(misc_set_invalid) /* 3d tra  */
559        .long local_label(misc_set_invalid) /* 3e misc  */
560        .long local_label(misc_set_u32) /* 3f xcode_vector  */
561        /* 40-4f  */
562        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
563        .long local_label(misc_set_invalid) /* 41 cons  */
564        .long _SPgvset /* 42 lock  */
565        .long local_label(misc_set_invalid) /* 43 imm  */
566        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
567        .long local_label(misc_set_invalid) /* 45 tra  */
568        .long local_label(misc_set_invalid) /* 46 misc  */
569        .long local_label(misc_set_invalid) /* 47 immheader  */
570        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
571        .long local_label(misc_set_invalid) /* 49 cons  */
572        .long _SPgvset /* 4a hash_vector  */
573        .long local_label(misc_set_invalid) /* 4b imm  */
574        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
575        .long local_label(misc_set_invalid) /* 4d tra  */
576        .long local_label(misc_set_invalid) /* 4e misc  */
577        .long local_label(misc_set_invalid) /* 4f immheader  */
578        /* 50-5f  */
579        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
580        .long local_label(misc_set_invalid) /* 51 cons  */
581        .long _SPgvset /* 52 pool  */
582        .long local_label(misc_set_invalid) /* 53 imm  */
583        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
584        .long local_label(misc_set_invalid) /* 55 tra  */
585        .long local_label(misc_set_invalid) /* 56 misc  */
586        .long local_label(misc_set_invalid) /* 57 immheader  */
587        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
588        .long local_label(misc_set_invalid) /* 59 cons  */
589        .long _SPgvset /* 5a weak  */
590        .long local_label(misc_set_invalid) /* 5b imm  */
591        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
592        .long local_label(misc_set_invalid) /* 5d tra  */
593        .long local_label(misc_set_invalid) /* 5e misc  */
594        .long local_label(misc_set_invalid) /* 5f immheader  */
595        /* 60-6f  */
596        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
597        .long local_label(misc_set_invalid) /* 61 cons  */
598        .long _SPgvset /* 62 package  */
599        .long local_label(misc_set_invalid) /* 63 imm  */
600        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
601        .long local_label(misc_set_invalid) /* 65 tra  */
602        .long local_label(misc_set_invalid) /* 66 misc  */
603        .long local_label(misc_set_invalid) /* 67 immheader  */
604        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
605        .long local_label(misc_set_invalid) /* 69 cons  */
606        .long _SPgvset /* 6a slot_vector  */
607        .long local_label(misc_set_invalid) /* 6b imm  */
608        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
609        .long local_label(misc_set_invalid) /* 6d tra  */
610        .long local_label(misc_set_invalid) /* 6e misc  */
611        .long local_label(misc_set_invalid) /* 6f immheader  */
612        /* 70-7f  */
613        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
614        .long local_label(misc_set_invalid) /* 71 cons  */
615        .long _SPgvset /* 72 instance  */
616        .long local_label(misc_set_invalid) /* 73 imm  */
617        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
618        .long local_label(misc_set_invalid) /* 75 tra  */
619        .long local_label(misc_set_invalid) /* 76 misc  */
620        .long local_label(misc_set_invalid) /* 77 immheader  */
621        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
622        .long local_label(misc_set_invalid) /* 79 cons  */
623        .long _SPgvset /* 7a struct  */
624        .long local_label(misc_set_invalid) /* 7b imm  */
625        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
626        .long local_label(misc_set_invalid) /* 7d tra  */
627        .long local_label(misc_set_invalid) /* 7e misc  */
628        .long local_label(misc_set_invalid) /* 7f immheader  */
629        /* 80-8f  */
630        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
631        .long local_label(misc_set_invalid) /* 81 cons  */
632        .long _SPgvset /* 82 istruct  */
633        .long local_label(misc_set_invalid) /* 83 imm  */
634        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
635        .long local_label(misc_set_invalid) /* 85 tra  */
636        .long local_label(misc_set_invalid) /* 86 misc  */
637        .long local_label(misc_set_invalid) /* 87 immheader  */
638        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
639        .long local_label(misc_set_invalid) /* 89 cons  */
640        .long _SPgvset /* 8a value_cell  */
641        .long local_label(misc_set_invalid) /* 8b imm  */
642        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
643        .long local_label(misc_set_invalid) /* 8d tra  */
644        .long local_label(misc_set_invalid) /* 8e misc  */
645        .long local_label(misc_set_invalid) /* 8f immheader  */
646        /* 90-9f  */
647        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
648        .long local_label(misc_set_invalid) /* 91 cons  */
649        .long _SPgvset /* 92 xfunction  */
650        .long local_label(misc_set_invalid) /* 93 imm  */
651        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
652        .long local_label(misc_set_invalid) /* 95 tra  */
653        .long local_label(misc_set_invalid) /* 96 misc  */
654        .long local_label(misc_set_invalid) /* 97 immheader  */
655        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
656        .long local_label(misc_set_invalid) /* 99 cons  */
657        .long _SPgvset /* 9a arrayH  */
658        .long local_label(misc_set_invalid) /* 9b imm  */
659        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
660        .long local_label(misc_set_invalid) /* 9d tra  */
661        .long local_label(misc_set_invalid) /* 9e misc  */
662        .long local_label(misc_set_invalid) /* 9f immheader  */
663        /* a0-af  */
664        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
665        .long local_label(misc_set_invalid) /* a1 cons  */
666        .long _SPgvset /* a2 vectorH  */
667        .long local_label(misc_set_invalid) /* a3 imm  */
668        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
669        .long local_label(misc_set_invalid) /* a5 tra  */
670        .long local_label(misc_set_invalid) /* a6 misc  */
671        .long local_label(misc_set_single_float_vector) /* a7 sf_vector  */
672        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
673        .long local_label(misc_set_invalid) /* a9 cons  */
674        .long _SPgvset /* aa simple_vector  */
675        .long local_label(misc_set_invalid) /* ab imm  */
676        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
677        .long local_label(misc_set_invalid) /* ad tra  */
678        .long local_label(misc_set_invalid) /* ae misc  */
679        .long local_label(misc_set_u32) /* af u32  */
680        /* b0-bf  */
681        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
682        .long local_label(misc_set_invalid) /* b1 cons  */
683        .long local_label(misc_set_invalid) /* b2 nodeheader  */
684        .long local_label(misc_set_invalid) /* b3 imm  */
685        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
686        .long local_label(misc_set_invalid) /* b5 tra  */
687        .long local_label(misc_set_invalid) /* b6 misc  */
688        .long local_label(misc_set_s32) /* b7 s32  */
689        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
690        .long local_label(misc_set_invalid) /* b9 cons  */
691        .long local_label(misc_set_invalid) /* ba nodeheader  */
692        .long local_label(misc_set_invalid) /* bb imm  */
693        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
694        .long local_label(misc_set_invalid) /* bd tra  */
695        .long local_label(misc_set_invalid) /* be misc  */
696        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
697        /* c0-cf  */
698        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
699        .long local_label(misc_set_invalid) /* c1 cons  */
700        .long local_label(misc_set_invalid) /* c2 nodeheader  */
701        .long local_label(misc_set_invalid) /* c3 imm  */
702        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
703        .long local_label(misc_set_invalid) /* c5 tra  */
704        .long local_label(misc_set_invalid) /* c6 misc  */
705        .long local_label(misc_set_string) /* c7 simple_base_string  */
706        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
707        .long local_label(misc_set_invalid) /* c9 cons  */
708        .long local_label(misc_set_invalid) /* ca nodeheader  */
709        .long local_label(misc_set_invalid) /* cb imm  */
710        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
711        .long local_label(misc_set_invalid) /* cd tra  */
712        .long local_label(misc_set_invalid) /* ce misc  */
713        .long local_label(misc_set_u8) /* cf u8  */
714        /* d0-df  */
715        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
716        .long local_label(misc_set_invalid) /* d1 cons  */
717        .long local_label(misc_set_invalid) /* d2 nodeheader  */
718        .long local_label(misc_set_invalid) /* d3 imm  */
719        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
720        .long local_label(misc_set_invalid) /* d5 tra  */
721        .long local_label(misc_set_invalid) /* d6 misc  */
722        .long local_label(misc_set_s8)      /* d7 s8  */
723        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
724        .long local_label(misc_set_invalid) /* d9 cons  */
725        .long local_label(misc_set_invalid) /* da nodeheader  */
726        .long local_label(misc_set_invalid) /* db imm  */
727        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
728        .long local_label(misc_set_invalid) /* dd tra  */
729        .long local_label(misc_set_invalid) /* de misc  */
730        .long local_label(misc_set_invalid) /* df immheader  */
731        /* e0-ef  */
732        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
733        .long local_label(misc_set_invalid) /* e1 cons  */
734        .long local_label(misc_set_invalid) /* e2 nodeheader  */
735        .long local_label(misc_set_invalid) /* e3 imm  */
736        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
737        .long local_label(misc_set_invalid) /* e5 tra  */
738        .long local_label(misc_set_invalid) /* e6 misc  */
739        .long local_label(misc_set_u16) /* e7 u16  */
740        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
741        .long local_label(misc_set_invalid) /* e9 cons  */
742        .long local_label(misc_set_invalid) /* ea nodeheader  */
743        .long local_label(misc_set_invalid) /* eb imm  */
744        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
745        .long local_label(misc_set_invalid) /* ed tra  */
746        .long local_label(misc_set_invalid) /* ee misc  */
747        .long local_label(misc_set_s16) /* ef s16  */
748        /* f0-ff  */
749        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
750        .long local_label(misc_set_invalid) /* f1 cons  */
751        .long local_label(misc_set_invalid) /* f2 nodeheader  */
752        .long local_label(misc_set_invalid) /* f3 imm  */
753        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
754        .long local_label(misc_set_invalid) /* f5 tra  */
755        .long local_label(misc_set_invalid) /* f6 misc  */
756        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
757        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
758        .long local_label(misc_set_invalid) /* f9 cons  */
759        .long local_label(misc_set_invalid) /* fa nodeheader  */
760        .long local_label(misc_set_invalid) /* fb imm  */
761        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
762        .long local_label(misc_set_invalid) /* fd tra  */
763        .long local_label(misc_set_invalid) /* fe misc  */
764        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
765
766local_label(misc_set_function):
767        /* Functions are funny: the first N words are treated as */
768        /* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
769        __(movzwl misc_data_offset(%temp0),%imm0)
770        __(shl $fixnumshift,%imm0)
771        __(rcmpl(%arg_y,%imm0))
772        __(jae _SPgvset)
773local_label(misc_set_u32):
774        /* Either a non-negative fixnum, a positive one-digit bignum, or */
775        /* a two-digit bignum whose sign-digit is 0 is OK. */
776        __(movl $~(target_most_positive_fixnum <<fixnumshift),%imm0)
777        __(test %arg_z,%imm0)
778        __(movl %arg_z,%imm0)
779        __(jne 1f)
780        __(sarl $fixnumshift,%imm0)
781        __(jmp 9f)
7821:      __(andb $tagmask,%imm0_b)
783        __(cmpb $tag_misc,%imm0_b)
784        __(jne local_label(misc_set_bad))
785        __(movb misc_subtag_offset(%arg_z),%imm0_b)
786        __(cmpb $subtag_bignum,%imm0_b)
787        __(jne local_label(misc_set_bad))
788        __(movl misc_header_offset(%arg_z),%imm0)
789        __(cmpl $two_digit_bignum_header,%imm0)
790        __(je 3f)
791        __(cmpl $one_digit_bignum_header,%imm0)
792        __(jne local_label(misc_set_bad))
793        __(movl misc_data_offset(%arg_z),%imm0)
794        __(testl %imm0,%imm0)
795        __(js local_label(misc_set_bad))
796        __(jmp 9f)
7973:      __(movl misc_data_offset(%arg_z),%imm0)
798        __(cmpl $0,misc_data_offset+4(%arg_z))
799        __(jne local_label(misc_set_bad))
8009:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
801        __(ret)
802local_label(misc_set_s32):
803        __(unbox_fixnum(%arg_z,%imm0))
804        __(testb $fixnummask,%arg_z_b)
805        __(je 9f)
8061:      __(movb %arg_z_b,%imm0_b)
807        __(andb $tagmask,%imm0_b)
808        __(cmpb $tag_misc,%imm0_b)
809        __(jne local_label(misc_set_bad))
810        __(movl misc_header_offset(%arg_z),%imm0)
811        __(cmpl $one_digit_bignum_header,%imm0)
812        __(jne local_label(misc_set_bad))
813        __(movl misc_data_offset(%arg_z),%imm0)
8149:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
815        __(ret)
816local_label(misc_set_bad):
817        __(movl %arg_z,%arg_y)
818        __(movl %temp0,%arg_z)
819        __(push $reserved_frame_marker)
820        __(push $reserved_frame_marker)
821        __(push $XNOTELT)
822        __(set_nargs(3))
823        __(jmp _SPksignalerr)
824local_label(misc_set_single_float_vector):
825        __(extract_lisptag(%arg_z,%imm0))
826        __(cmpb $tag_misc,%imm0_b)
827        __(jne local_label(misc_set_bad))
828        __(movb misc_subtag_offset(%arg_z),%imm0_b)
829        __(cmpb $subtag_single_float,%imm0_b)
830        __(jne local_label(misc_set_bad))
831        __(movl single_float.value(%arg_z),%imm0)
832        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
833        __(ret)
834local_label(misc_set_double_float_vector):
835        __(extract_lisptag(%arg_z,%imm0))
836        __(cmpb $tag_misc,%imm0_b)
837        __(jne local_label(misc_set_bad))
838        __(movb misc_subtag_offset(%arg_z),%imm0_b)
839        __(cmpb $subtag_double_float,%imm0_b)
840        __(jne local_label(misc_set_bad))
841        __(movsd double_float.value(%arg_z),%fp0)
842        __(movsd %fp0,misc_dfloat_offset(%temp0,%arg_y,2))
843        __(ret)
844local_label(misc_set_fixnum_vector):
845        __(unbox_fixnum(%arg_z,%imm0))
846        __(testb $fixnummask,%arg_z_b)
847        __(jne local_label(misc_set_bad))
848        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
849        __(ret)
850local_label(misc_set_u8):
851        __(testl $~(0xff<<fixnumshift),%arg_z)
852        __(jne local_label(misc_set_bad))
853        __(unbox_fixnum(%arg_y,%imm0))
854        __(movl %arg_z,%arg_y)
855        __(shll $8-fixnumshift,%arg_z)
856        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
857        __(movl %arg_y,%arg_z)
858        __(ret)
859local_label(misc_set_s8):
860        __(movl %arg_z,%imm0)
861        __(shll $32-(8+fixnumshift),%imm0)
862        __(sarl $32-(8+fixnumshift),%imm0)
863        __(cmpl %arg_z,%imm0)
864        __(jne local_label(misc_set_bad))
865        __(testb $fixnummask,%arg_z_b)
866        __(jne local_label(misc_set_bad))
867        __(unbox_fixnum(%arg_y,%imm0))
868        __(movl %arg_z,%arg_z)
869        __(shll $8-fixnumshift,%arg_z)
870        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
871        __(movl %arg_y,%arg_z)
872        __(ret)
873local_label(misc_set_string):
874        __(cmpb $subtag_character,%arg_z_b)
875        __(jne local_label(misc_set_bad))
876        __(movl %arg_z,%imm0)
877        __(shrl $charcode_shift,%imm0)
878        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
879        __(ret)
880local_label(misc_set_u16):
881        __(testl $~(0xffff<<fixnumshift),%arg_z)
882        __(jne local_label(misc_set_bad))
883        __(movl %arg_y,%imm0)
884        __(shrl $1,%imm0)
885        __(mark_as_imm(%temp1))
886        __(unbox_fixnum(%arg_z,%temp1))
887        __(movw %temp1_w,misc_data_offset(%temp0,%imm0))
888        __(mark_as_node(%temp1))
889        __(ret)
890local_label(misc_set_s16):
891        __(movl %arg_z,%imm0)
892        __(shll $32-(16+fixnumshift),%imm0)
893        __(sarl $32-(16+fixnumshift),%imm0)
894        __(cmpl %arg_z,%imm0)
895        __(jne local_label(misc_set_bad))
896        __(testb $fixnummask,%arg_z_b)
897        __(jne local_label(misc_set_bad))
898        __(movl %arg_y,%imm0)
899        __(shrl $1,%imm0)
900        __(mark_as_imm(%temp1))
901        __(unbox_fixnum(%arg_z,%temp1))
902        __(movw %temp1_w,misc_data_offset(%temp0,%imm0))
903        __(mark_as_node(%temp1))
904        __(ret)
905local_label(misc_set_bit_vector):
906        __(testl $~fixnumone,%arg_z)
907        __(jne local_label(misc_set_bad))
908        __(unbox_fixnum(%arg_y,%imm0))
909        __(testb %arg_z_b,%arg_z_b)
910        __(je local_label(misc_set_clr_bit))
911local_label(misc_set_set_bit):
912        __(btsl %imm0,misc_data_offset(%temp0))
913        __(ret)
914local_label(misc_set_clr_bit):
915        __(btrl %imm0,misc_data_offset(%temp0))
916        __(ret)
917local_label(misc_set_invalid):
918        __(push $reserved_frame_marker)
919        __(push $reserved_frame_marker)
920        __(push $XSETBADVEC)
921        __(push %temp0)
922        __(set_nargs(4))
923        __(jmp _SPksignalerr)
924_endfn(C(misc_set_common))
925
926_spentry(Fret1valn)
927        .globl C(ret1valn)
928__(tra(C(ret1valn)))
929        __(mov (%esp),%ra0)
930        __(mov %arg_z,(%esp))
931        __(set_nargs(1))
932        __(jmp *%ra0)
933_endsubp(Fret1valn)
934
935_spentry(nvalret)
936        .globl C(nvalret)
937C(nvalret):
938        __(ref_global(ret1val_addr,%temp0))
939        __(cmpl lisp_frame.savera0(%ebp),%temp0)
940        __(je 1f)
941        __(test %nargs,%nargs)
942        __(movl $nil_value,%arg_z)
943        __(cmovnel -node_size(%esp,%nargs),%arg_z)
944        __(leave)
945        __(ret)
946
947/* actually need to return values; always need to copy. */
9481:      __(lea 2*node_size(%ebp),%imm0)
949        __(pushl (%imm0))
950        __(movl 0(%ebp),%ebp)
951        __(addl $node_size,%imm0)
952        __(lea node_size(%esp,%nargs),%temp0)
953        __(xorl %arg_y,%arg_y)
954        __(jmp 3f)
9552:      __(movl -node_size(%temp0),%arg_z)
956        __(subl $node_size,%temp0)
957        __(addl $node_size,%arg_y)
958        __(movl %arg_z,-node_size(%imm0))
959        __(subl $node_size,%imm0)
9603:      __(cmpl %arg_y,%nargs)
961        __(jne 2b)
962        __(pop %ra0)
963        __(movl %imm0,%esp)
964        __(jmp *%ra0)
965_endsubp(nvalret)
966
967_spentry(jmpsym)
968        __(jump_fname())
969_endsubp(jmpsym)
970
971_spentry(jmpnfn)
972        __(mov %temp0,%fn)
973        __(jmp *%fn)
974_endsubp(jmpnfn)
975
976_spentry(funcall)
977        __(do_funcall())
978_endsubp(funcall)
979
980/* Make a lisp integer (fixnum or one-digit bignum) from the value in %imm0 */
981_spentry(makes32)
982        __(imull $fixnumone,%imm0,%arg_z)       /* result is fixnum-tagged */
983        __(jno 0f)                              /* but may have overflowed */
984        __(movd %imm0,%mm1)
985        __(movl $one_digit_bignum_header,%imm0)
986        __(movd %imm0,%mm0)
987        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
988        __(movd %mm1,misc_data_offset(%arg_z))
9890:      __(repret)
990_endsubp(makes32)
991
992/* Make a lisp integer out of the unboxed 64-bit word in %mm0. */
993/* This is a little clumsy, but the alternative requires callers to */
994/* have already marked %edx as an imm reg (or else store it in memory
995/* somewhere), and I'm nervous about */
996/* splitting up the mark-as-imm/mark-as-node between two separate */
997/* pieces of code. */
998_spentry(makes64)
999        __(movq %mm0,%mm2)
1000        __(pshufw $0x4e,%mm0,%mm1)      /* swap hi/lo halves */
1001        __(psrad $31,%mm0)      /* propagate sign */
1002        __(pcmpeqd %mm0,%mm1)   /* all ones if equal */
1003        __(movd %mm1,%imm0)
1004        __(cmpb $-1,%imm0_b)    /* upper half just sign extension? */
1005        __(jne 1f)
1006        __(movd %mm2,%imm0)
1007        __(jmp _SPmakes32)
10081:      __(movl $two_digit_bignum_header,%imm0)
1009        __(movd %imm0,%mm0)
1010        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
1011        __(movq %mm2,misc_data_offset(%arg_z))
1012        __(ret)
1013_endsubp(makes64)
1014
1015_spentry(syscall)
1016        /* Save lisp registers */
1017        __(push %ebp)
1018        __(movl %esp,%ebp)
1019        __(push %temp0)
1020        __(push %temp1)
1021        __(push %arg_y)
1022        __(push %arg_z)
1023        __(push %fn)
1024        __(movl %esp,rcontext(tcr.save_vsp))
1025        __(movl %ebp,rcontext(tcr.save_ebp))
1026        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
1027        __(movl rcontext(tcr.foreign_sp),%esp)
1028        /* preserve state of direction flag */
1029        __(pushfl)
1030        __(popl rcontext(tcr.save_eflags))
1031        __(cld)
1032        __(emms)
1033        __(pop %ebp)            /* backlink */
1034        __(lea 15(%esp),%edx)
1035        __(andl $-16,%edx)
1036        __(movl %edx,%esp)
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        __(clr %arg_z)
1049        __(clr %arg_y)
1050        __(clr %temp1)
1051        __(clr %temp0)
1052        __(clr %fn)
1053        __(pxor %fpzero,%fpzero)
1054        __(pushl rcontext(tcr.save_eflags))
1055        __(popfl)
1056        __(movl rcontext(tcr.save_vsp),%esp)
1057        __(movl rcontext(tcr.save_ebp),%ebp)
1058        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
1059        __(pop %fn)
1060        __(pop %arg_z)
1061        __(pop %arg_y)
1062        __(pop %temp1)
1063        __(check_pending_interrupt(%temp0))
1064        __(pop %temp0)
1065        __(leave)
1066        __(ret)
1067_endsubp(syscall)
1068
1069/* Make system call that returns a doubleword result in %edx:%eax and */
1070/* copy the result into %mm0. */
1071_spentry(syscall2)
1072        /* Save lisp registers */
1073        __(push %ebp)
1074        __(movl %esp,%ebp)
1075        __(push %temp0)
1076        __(push %temp1)
1077        __(push %arg_y)
1078        __(push %arg_z)
1079        __(push %fn)
1080        __(movl %esp,rcontext(tcr.save_vsp))
1081        __(movl %ebp,rcontext(tcr.save_ebp))
1082        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
1083        __(movl rcontext(tcr.foreign_sp),%esp)
1084        /* preserve state of direction flag */
1085        __(pushfl)
1086        __(popl rcontext(tcr.save_eflags))
1087        __(cld)
1088        __(emms)
1089        __(pop %ebp)            /* backlink */
1090        __(lea 15(%esp),%edx)
1091        __(andl $-16,%edx)
1092        __(movl %edx,%esp)
1093        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1094        __(pushl $local_label(back_from_syscall))
1095        __(int $0x80)
1096local_label(back_from_syscall):
1097        __(jnc 0f)
1098        __(neg %eax)
1099        __(movl $-1,%edx)
11000:
1101        /* just use memory rather than screwing around with */
1102        /* movd %eax,%mm0, movd %edx,%mm1, psllq $32,%mm1, por %mm1,%mm0 */
1103        __(push %edx)
1104        __(push %eax)
1105        __(movq (%esp),%mm0)
1106        __(movl %ebp,%esp)
1107        __(movl %esp,rcontext(tcr.foreign_sp))
1108        __(clr %arg_z)
1109        __(clr %arg_y)
1110        __(clr %temp1)
1111        __(clr %temp0)
1112        __(clr %fn)
1113        __(pxor %fpzero,%fpzero)
1114        __(pushl rcontext(tcr.save_eflags))
1115        __(popf)
1116        __(movl rcontext(tcr.save_vsp),%esp)
1117        __(movl rcontext(tcr.save_ebp),%ebp)
1118        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
1119        __(pop %fn)
1120        __(pop %arg_z)
1121        __(pop %arg_y)
1122        __(pop %temp1)
1123        __(check_pending_interrupt(%temp0))
1124        __(pop %temp0)
1125        __(leave)
1126        __(ret)
1127_endsubp(syscall2)
1128
1129
1130_spentry(mkcatch1v)
1131        __(nMake_Catch(0))
1132        __(ret)
1133_endsubp(mkcatch1v)
1134
1135_spentry(mkunwind)
1136        __(movl $undefined,%arg_z)
1137        __(Make_Catch(fixnumone))
1138        __(jmp *%ra0)
1139_endsubp(mkunwind)
1140
1141/* this takes a return address in %ra0; it's "new" in that it does the */
1142/*   double binding of *interrupt-level* out-of-line */
1143_spentry(nmkunwind)
1144        __(movl rcontext(tcr.tlb_pointer),%arg_z)
1145        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_z),%arg_y)
1146        __(push %arg_y)
1147        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
1148        __(push rcontext(tcr.db_link))
1149        __(movl %esp,rcontext(tcr.db_link))
1150        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_z))
1151        __(movl $undefined,%arg_z)
1152        /* %arg_z = tag, %xfn (%temp1) = pc */
1153        __(Make_Catch(fixnumone))
1154        __(movl %arg_y,%arg_z)
1155        __(jmp _SPbind_interrupt_level)
1156_endsubp(nmkunwind)
1157
1158_spentry(mkcatchmv)
1159        __(nMake_Catch(fixnumone))
1160        __(ret)
1161_endsubp(mkcatchmv)
1162
1163_spentry(throw)
1164        __(movl rcontext(tcr.catch_top),%imm0)
1165        __(movl (%esp,%nargs),%arg_y)   /* arg_y = tag   */
1166        __(movd %nargs,%mm0)
1167        __(xorl %temp1,%temp1)
1168        __(jmp local_label(_throw_test))
1169local_label(_throw_loop):
1170        __(cmpl %arg_y,catch_frame.catch_tag(%imm0))
1171        __(je local_label(_throw_found))
1172        __(movl catch_frame.link(%imm0),%imm0)
1173        __(addl $fixnum_one,%temp1)
1174local_label(_throw_test):
1175        __(test %imm0,%imm0)
1176        __(jne local_label(_throw_loop))
1177        __(push %ra0)
1178        __(uuo_error_reg_not_tag(Rarg_y,subtag_catch_frame))
1179        __(pop %ra0)
1180        __(jmp _SPthrow)
1181local_label(_throw_found):
1182        __(testb $fulltagmask,catch_frame.mvflag(%imm0))
1183        __(movl %temp1,%imm0)
1184        __(movd %mm0,%nargs)
1185        __(jne local_label(_throw_multiple))
1186        __(movl $nil_value,%arg_z)
1187        __(test %nargs,%nargs)
1188        __(je local_label(_throw_one_value))
1189        __(movl -node_size(%esp,%nargs),%arg_z)
1190        __(add %nargs,%esp)
1191local_label(_throw_one_value):
1192        __(movl $local_label(_threw_one_value),%ra0)
1193        __(jmp _SPnthrow1value)
1194__(tra(local_label(_threw_one_value)))
1195        __(movl rcontext(tcr.catch_top),%arg_y)
1196        __(movl catch_frame.db_link(%arg_y),%imm0)
1197        __(cmpl %imm0,rcontext(tcr.db_link))
1198        __(jz local_label(_threw_one_value_dont_unbind))
1199        __(push $local_label(_threw_one_value_dont_unbind))
1200        __(jmp _SPunbind_to)    /* preserves registers */
1201__(tra(local_label(_threw_one_value_dont_unbind)))
1202        __(movl catch_frame.ebp(%arg_y),%ebp)
1203        __(movl catch_frame.foreign_sp(%arg_y),%imm0)
1204        __(movl %imm0,rcontext(tcr.foreign_sp))
1205        __(movl catch_frame.xframe(%arg_y),%imm0)
1206        __(movl %imm0,rcontext(tcr.xframe))
1207        __(movl catch_frame.esp(%arg_y),%esp)
1208        __(movl catch_frame.link(%arg_y),%imm0)
1209        __(movl %imm0,rcontext(tcr.catch_top))
1210        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%arg_y),%imm0)
1211        __(movl (%imm0),%imm0)
1212        __(movl %imm0,rcontext(tcr.save_tsp))
1213        __(movl %imm0,rcontext(tcr.next_tsp))
1214        __(movl catch_frame.pc(%arg_y),%ra0)
1215        __(jmp *%ra0)
1216local_label(_throw_multiple):
1217        __(movl $local_label(_threw_multiple),%ra0)
1218        __(jmp _SPnthrowvalues)
1219__(tra(local_label(_threw_multiple)))
1220        __(movl rcontext(tcr.catch_top),%arg_y)
1221        __(movl catch_frame.db_link(%arg_y),%imm0)
1222        __(cmpl %imm0,rcontext(tcr.db_link))
1223        __(je local_label(_threw_multiple_dont_unbind))
1224        __(push $local_label(_threw_multiple_dont_unbind))
1225        __(jmp _SPunbind_to)    /* preserves registers */
1226__(tra(local_label(_threw_multiple_dont_unbind)))
1227        /* Copy multiple values from the current %esp to the target %esp   */
1228        __(lea (%esp,%nargs),%imm0)
1229        __(movd %nargs,%mm0)    /* nargs is aka temp1 */
1230        __(movl catch_frame.esp(%arg_y),%temp1)
1231        __(jmp local_label(_threw_multiple_push_test))
1232local_label(_threw_multiple_push_loop):
1233        __(subl $node_size,%imm0)
1234        __(subl $node_size,%temp1)
1235        __(movl (%imm0),%arg_z)
1236        __(movl %arg_z,(%temp1))
1237local_label(_threw_multiple_push_test):
1238        __(cmpl %imm0,%esp)
1239        __(jne local_label(_threw_multiple_push_loop))
1240        /* target %esp is now in %temp1   */
1241        __(movl catch_frame.ebp(%arg_y),%ebp)
1242        __(movl catch_frame.foreign_sp(%arg_y),%imm0)
1243        __(movl %imm0,rcontext(tcr.foreign_sp))       
1244        __(movl catch_frame.xframe(%arg_y),%imm0)
1245        __(movl %imm0,rcontext(tcr.xframe))
1246        __(movl %temp1,%esp)
1247        __(movl catch_frame.link(%arg_y),%temp1)
1248        __(movl %temp1,rcontext(tcr.catch_top))
1249        __(movd %mm0,%nargs)
1250        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%arg_y),%imm0)
1251        __(movl catch_frame.pc(%arg_y),%ra0)
1252        __(movl (%imm0),%imm0)
1253        __(movl %imm0,rcontext(tcr.save_tsp))
1254        __(movl %imm0,rcontext(tcr.next_tsp))
1255        __(jmp *%ra0)
1256_endsubp(throw)
1257
1258        /* This takes N multiple values atop the vstack.   */
1259_spentry(nthrowvalues)
1260        __(movb $1,rcontext(tcr.unwinding))
1261        __(movl %ra0,rcontext(tcr.save0)) /* %ra0 (aka %temp0) to spill area */
1262local_label(_nthrowv_nextframe):
1263        __(subl $fixnumone,%imm0)
1264        __(js local_label(_nthrowv_done))
1265        __(movd %imm0,%mm1)
1266        __(movl rcontext(tcr.catch_top),%temp0)
1267        __(movl catch_frame.link(%temp0),%imm0)
1268        __(movl %imm0,rcontext(tcr.catch_top))
1269        __(movl catch_frame.db_link(%temp0),%imm0)
1270        __(cmpl %imm0,rcontext(tcr.db_link))
1271        __(jz local_label(_nthrowv_dont_unbind))
1272        __(push %temp1)
1273        __(push %temp0)
1274        __(push $local_label(_nthrowv_back_from_unbind))
1275        __(jmp _SPunbind_to)
1276__(tra(local_label(_nthrowv_back_from_unbind)))
1277        __(pop %temp0)
1278        __(pop %temp1)
1279local_label(_nthrowv_dont_unbind):
1280        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1281        __(je local_label(_nthrowv_do_unwind))
1282/* A catch frame.  If the last one, restore context from there.   */
1283        __(movd %mm1,%imm0)
1284        __(test %imm0,%imm0)    /* last catch frame ?   */
1285        __(jne local_label(_nthrowv_skip))
1286        __(movl catch_frame.xframe(%temp0),%arg_y)
1287        __(movl %arg_y,rcontext(tcr.xframe))
1288        __(lea (%esp,%nargs),%arg_y)
1289        __(movl catch_frame.esp(%temp0),%arg_z)
1290        __(movd %nargs,%mm2)
1291        __(jmp local_label(_nthrowv_push_test))
1292local_label(_nthrowv_push_loop):
1293        __(subl $node_size,%arg_y)
1294        __(subl $node_size,%arg_z)
1295        __(movd (%arg_y),%mm0)
1296        __(movd %mm0,(%arg_z))
1297local_label(_nthrowv_push_test):
1298        __(subl $node_size,%nargs)
1299        __(jns local_label(_nthrowv_push_loop))
1300        __(movd %mm2,%nargs)
1301        __(movl catch_frame.xframe(%temp0),%arg_y)
1302        __(movl %arg_y,rcontext(tcr.xframe))
1303        __(movl %arg_z,%esp)
1304        __(movl catch_frame.ebp(%temp0),%ebp)
1305        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1306        __(movd %stack_temp,rcontext(tcr.foreign_sp))       
1307local_label(_nthrowv_skip):     
1308        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1309        __(movl %imm0,rcontext(tcr.save_tsp))
1310        __(movl %imm0,rcontext(tcr.next_tsp))
1311        __(movd %mm1,%imm0)
1312        __(jmp local_label(_nthrowv_nextframe))
1313local_label(_nthrowv_do_unwind):       
1314/* This is harder.  Call the cleanup code with the multiple values and   */
1315/* nargs, the throw count, and the caller's return address in a temp  */
1316/* stack frame.   */
1317        __(leal (%esp,%nargs),%arg_y)
1318        __(push catch_frame.pc(%temp0))
1319        __(movl catch_frame.ebp(%temp0),%ebp)
1320        __(movd catch_frame.xframe(%temp0),%stack_temp)
1321        __(movd %stack_temp,rcontext(tcr.xframe))
1322        __(movl catch_frame.esp(%temp0),%arg_z)
1323        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1324        __(movd %stack_temp,rcontext(tcr.foreign_sp))       
1325        /* Discard the catch frame, so we can build a temp frame   */
1326        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1327        __(movl %imm0,rcontext(tcr.save_tsp))
1328        __(movl %imm0,rcontext(tcr.next_tsp))
1329        __(movd %temp1,%mm2) /* save %nargs */
1330        /* tsp overhead, nargs, throw count, ra0   */
1331        __(dnode_align(%nargs,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1332        __(movl %imm0,%temp1)
1333        __(TSP_Alloc_Var(%temp1,%imm0))
1334        __(movd %mm2,%temp1) /* aka %nargs */
1335
1336        __(movl %nargs,(%imm0))
1337        __(movl rcontext(tcr.save0),%ra0)
1338        __(movl %ra0,node_size(%imm0))
1339        __(movd %mm1,node_size*2(%imm0))
1340        __(leal node_size*3(%imm0),%imm0)
1341        __(jmp local_label(_nthrowv_tpushtest))
1342local_label(_nthrowv_tpushloop):
1343        __(movl -node_size(%arg_y),%temp0)
1344        __(subl $node_size,%arg_y)
1345        __(movl %temp0,(%imm0))
1346        __(addl $node_size,%imm0)
1347local_label(_nthrowv_tpushtest):
1348        __(subl $node_size,%nargs)
1349        __(jns local_label(_nthrowv_tpushloop))
1350        __(pop %xfn)    /* aka %temp1/%nargs */
1351        __(movl %arg_z,%esp)
1352/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1353        __(push $local_label(_nthrowv_called_cleanup))
1354        __(movb $0,rcontext(tcr.unwinding))
1355        __(jmp *%xfn)
1356__(tra(local_label(_nthrowv_called_cleanup)))
1357
1358        __(movb $1,rcontext(tcr.unwinding))
1359        __(movl rcontext(tcr.save_tsp),%imm0)
1360        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%nargs)
1361        __(movl tsp_frame.data_offset+(1*node_size)(%imm0),%ra0)
1362        __(movl %ra0,rcontext(tcr.save0))
1363        __(movd tsp_frame.data_offset+(2*node_size)(%imm0),%mm1)
1364        __(movd %nargs,%mm2)
1365        __(addl $tsp_frame.fixed_overhead+(node_size*3),%imm0)
1366        __(jmp local_label(_nthrowv_tpoptest))
1367local_label(_nthrowv_tpoploop):
1368        __(push (%imm0))
1369        __(addl $node_size,%imm0)
1370local_label(_nthrowv_tpoptest):
1371        __(subl $node_size,%nargs)
1372        __(jns local_label(_nthrowv_tpoploop))
1373        __(movd %mm2,%nargs)
1374        __(movl rcontext(tcr.save_tsp),%imm0)
1375        __(movl (%imm0),%imm0)
1376        __(movl %imm0,rcontext(tcr.save_tsp))
1377        __(movl %imm0,rcontext(tcr.next_tsp))
1378        __(movd %mm1,%imm0)
1379        __(jmp local_label(_nthrowv_nextframe))
1380local_label(_nthrowv_done):
1381        __(movb $0,rcontext(tcr.unwinding))
1382        __(check_pending_interrupt(%imm0))
1383local_label(_nthrowv_return):
1384        __(movl rcontext(tcr.save0),%ra0)
1385        __(movss %fpzero,rcontext(tcr.save0))
1386        __(jmp *%ra0)   
1387_endsubp(nthrowvalues)
1388
1389/* This is a (slight) optimization.  When running an unwind-protect,  */
1390/* save the single value and the throw count in the tstack frame.  */
1391/* Note that this takes a single value in arg_z.  */
1392
1393_spentry(nthrow1value)
1394        __(movb $1,rcontext(tcr.unwinding))
1395local_label(_nthrow1v_nextframe):
1396        __(subl $fixnumone,%imm0)
1397        __(js local_label(_nthrow1v_done))
1398        __(movd %imm0,%mm0)
1399        __(movl rcontext(tcr.catch_top),%temp1)
1400        __(movl catch_frame.link(%temp1),%imm0)
1401        __(movl %imm0,rcontext(tcr.catch_top))
1402        __(movl catch_frame.db_link(%temp1),%imm0)
1403        __(cmpl %imm0,rcontext(tcr.db_link))
1404        __(jz local_label(_nthrow1v_dont_unbind))
1405        __(push %temp1)
1406        __(push %temp0)
1407        __(push %arg_z)
1408        __(push [$]local_label(_nthrow1v_back_from_unbind))
1409        __(jmp _SPunbind_to)
1410__(tra(local_label(_nthrow1v_back_from_unbind)))
1411        __(pop %arg_z)
1412        __(pop %temp0)
1413        __(pop %temp1)
1414local_label(_nthrow1v_dont_unbind):
1415        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp1))
1416        __(je local_label(_nthrow1v_do_unwind))
1417/* A catch frame.  If the last one, restore context from there. */
1418        __(movd %mm0,%imm0)
1419        __(test %imm0,%imm0)    /* last catch frame? */
1420        __(jne local_label(_nthrow1v_skip))
1421        __(movl catch_frame.xframe(%temp1),%arg_y)
1422        __(movl %arg_y,rcontext(tcr.xframe))
1423        __(movl catch_frame.esp(%temp1),%esp)
1424        __(movl catch_frame.ebp(%temp1),%ebp)
1425        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1426        __(movd %stack_temp,rcontext(tcr.foreign_sp))
1427local_label(_nthrow1v_skip):
1428        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1429        __(movl %imm0,rcontext(tcr.save_tsp))
1430        __(movl %imm0,rcontext(tcr.next_tsp))
1431        __(movd %mm0,%imm0)
1432        __(jmp local_label(_nthrow1v_nextframe))
1433local_label(_nthrow1v_do_unwind):
1434/* This is harder, but not as hard (not as much BLTing) as the */
1435/* multiple-value case. */
1436        __(movl catch_frame.xframe(%temp1),%arg_y)
1437        __(movl %arg_y,rcontext(tcr.xframe))
1438        __(movl catch_frame.ebp(%temp1),%ebp)
1439        __(movl catch_frame.esp(%temp1),%esp)
1440        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1441        __(movd %stack_temp,rcontext(tcr.foreign_sp))
1442        /* Discard the catch frame so we can build a temp frame. */
1443        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1444        __(movl %imm0,rcontext(tcr.save_tsp))
1445        __(movl %imm0,rcontext(tcr.next_tsp))
1446        __(movl catch_frame.pc(%temp1),%xfn) /* xfn is temp1 */
1447        __(TSP_Alloc_Fixed((3*node_size),%imm0))
1448        __(addl $tsp_frame.fixed_overhead,%imm0)
1449        __(movl %ra0,(%imm0))
1450        __(movd %mm0,node_size*1(%imm0))
1451        __(movl %arg_z,node_size*2(%imm0))
1452/* Ready to call cleanup code.  Set up tra, jmp to %xfn. */
1453        __(push $local_label(_nthrow1v_called_cleanup))
1454        __(movb $0,rcontext(tcr.unwinding))
1455        __(jmp *%xfn)
1456__(tra(local_label(_nthrow1v_called_cleanup)))
1457        __(movb $1,rcontext(tcr.unwinding))
1458        __(movl rcontext(tcr.save_tsp),%imm0)
1459        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%ra0)
1460        __(movd tsp_frame.data_offset+(1*node_size)(%imm0),%mm0)
1461        __(movl tsp_frame.data_offset+(2*node_size)(%imm0),%arg_z)
1462        __(movl (%imm0),%imm0)
1463        __(movl %imm0,rcontext(tcr.save_tsp))
1464        __(movl %imm0,rcontext(tcr.next_tsp))
1465        __(movd %mm0,%imm0)
1466        __(jmp local_label(_nthrow1v_nextframe))
1467local_label(_nthrow1v_done):
1468        __(movb $0,rcontext(tcr.unwinding))
1469        __(check_pending_interrupt(%imm0))
1470local_label(_nthrow1v_return):
1471        __(jmp *%ra0)
1472_endsubp(nthrow1value)
1473
1474/* This never affects the symbol's vcell   */
1475/* Non-null symbol in arg_y, new value in arg_z           */
1476
1477_spentry(bind)
1478        __(movl symbol.binding_index(%arg_y),%imm0)
1479        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1480        __(jb 0f)
1481        __(push %imm0)
1482        __(tlb_too_small())
14830:      __(test %imm0,%imm0)
1484        __(jz 9f)
1485        __(movl rcontext(tcr.tlb_pointer),%temp1)
1486        __(push (%temp1,%imm0))
1487        __(push %imm0)
1488        __(push rcontext(tcr.db_link))
1489        __(movl %esp,rcontext(tcr.db_link))
1490        __(movl %arg_z,(%temp1,%imm0))
1491        __(jmp *%ra0)
14929:     
1493        __(movl %arg_y,%arg_z)
1494        __(movl $XSYMNOBIND,%arg_y)
1495        __(set_nargs(2))
1496        __(push %ra0)
1497        __(jmp _SPksignalerr)
1498_endsubp(bind)
1499
1500/* arg_z = symbol: bind it to its current value  */
1501
1502_spentry(bind_self)
1503        __(movl symbol.binding_index(%arg_z),%imm0)
1504        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1505        __(jb 0f)
1506        __(push %imm0)
1507        __(tlb_too_small())
15080:      __(test %imm0,%imm0)
1509        __(jz 9f)
1510        __(movl rcontext(tcr.tlb_pointer),%temp1)
1511        __(cmpb $no_thread_local_binding_marker,(%temp1,%imm0))
1512        __(jz 2f)
1513        __(push (%temp1,%imm0))
1514        __(push %imm0)
1515        __(push rcontext(tcr.db_link))
1516        __(movl %esp,rcontext(tcr.db_link))
1517        __(jmp *%ra0)
15182:      __(movl symbol.vcell(%arg_z),%arg_y)
1519        __(push (%temp1,%imm0))
1520        __(push %imm0)
1521        __(push rcontext(tcr.db_link))
1522        __(movl %arg_y,(%temp1,%imm0))
1523        __(movl %esp,rcontext(tcr.db_link))
1524        __(jmp *%ra0)
15259:      __(movl $XSYMNOBIND,%arg_y)
1526        __(set_nargs(2))
1527        __(push %ra0)
1528        __(jmp _SPksignalerr)
1529_endsubp(bind_self)
1530
1531_spentry(bind_nil)
1532        __(movl symbol.binding_index(%arg_z),%imm0)
1533        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1534        __(jb 0f)
1535        __(push %imm0)
1536        __(tlb_too_small())
15370:      __(test %imm0,%imm0)
1538        __(jz 9f)
1539        __(movl rcontext(tcr.tlb_pointer),%temp1)
1540        __(push (%temp1,%imm0))
1541        __(push %imm0)
1542        __(push rcontext(tcr.db_link))
1543        __(movl %esp,rcontext(tcr.db_link))
1544        __(movl $nil_value,(%temp1,%imm0))
1545        __(jmp *%ra0)
15469:      __(movl $XSYMNOBIND,%arg_y)
1547        __(set_nargs(2))
1548        __(push %ra0)
1549        __(jmp _SPksignalerr)
1550_endsubp(bind_nil)
1551
1552_spentry(bind_self_boundp_check)
1553        __(movl symbol.binding_index(%arg_z),%imm0)
1554        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1555        __(jb 0f)
1556        __(push %imm0)
1557        __(tlb_too_small())
15580:      __(test %imm0,%imm0)
1559        __(jz 9f)
1560        __(movl rcontext(tcr.tlb_pointer),%temp1)
1561        __(cmpb $no_thread_local_binding_marker,(%temp1,%imm0))
1562        __(je 2f)
1563        __(cmpb $unbound_marker,(%temp1,%imm0))
1564        __(je 8f)
1565        __(push (%temp1,%imm0))
1566        __(push %imm0)
1567        __(push rcontext(tcr.db_link))
1568        __(movl %esp,rcontext(tcr.db_link))
1569        __(jmp *%ra0)
15702:      __(movl symbol.vcell(%arg_z),%arg_y)
1571        __(cmpl $unbound_marker,%arg_y)
1572        __(jz 8f)
1573        __(push (%temp1,%imm0))
1574        __(push %imm0)
1575        __(push rcontext(tcr.db_link))
1576        __(movl %esp,rcontext(tcr.db_link))
1577        __(movl %arg_y,(%temp1,%imm0))
1578        __(jmp *%ra0)
15798:      __(push %ra0)
1580        __(uuo_error_reg_unbound(Rarg_z))
1581       
15829:      __(movl $XSYMNOBIND,%arg_y)
1583        __(set_nargs(2))
1584        __(push %ra0)
1585        __(jmp _SPksignalerr)
1586_endsubp(bind_self_boundp_check)
1587
1588_spentry(conslist)
1589        __(movl %nargs,%imm0)
1590        __(movl %temp0,%temp1)  /* have to use temp0 for consing */
1591        __(movl $nil_value,%arg_z)
1592        __(test %imm0,%imm0)
1593        __(jmp 2f)
15941:      __(pop %arg_y)
1595        __(Cons(%arg_y,%arg_z,%arg_z))
1596        __(subl $node_size,%imm0)
15972:      __(jnz 1b)
1598        __(jmp *%temp1)
1599_endsubp(conslist)
1600
1601/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1602/* Cons, one cons cell at at time.  Maybe optimize this later.  */
1603
1604_spentry(conslist_star)
1605        __(movl %nargs,%imm0)
1606        __(test %imm0,%imm0)
1607        __(movl %ra0,%temp1)
1608        __(jmp 2f)
16091:      __(pop %arg_y)
1610        __(Cons(%arg_y,%arg_z,%arg_z))
1611        __(subl $node_size,%imm0)
16122:      __(jnz 1b)
1613        __(jmp *%temp1)
1614_endsubp(conslist_star)
1615
1616/* We always have to create a tsp frame (even if nargs is 0), so the compiler */
1617/* doesn't get confused. */
1618_spentry(stkconslist)
1619        __(movl %ra0,rcontext(tcr.save0))
1620        __(movd %nargs,%mm0)
1621        __(movl %nargs,%temp0)
1622        __(addl %temp0,%temp0)
1623        __(movl $nil_value,%arg_z)
1624        __(dnode_align(%temp0,tsp_frame.fixed_overhead,%temp0))
1625        __(TSP_Alloc_Var(%temp0,%imm0))
1626        __(addl $fulltag_cons,%imm0)
1627        __(test %nargs,%nargs)
1628        __(jmp 2f)
16291:      __(pop %arg_y)
1630        __(_rplaca(%imm0,%arg_y))
1631        __(_rplacd(%imm0,%arg_z))
1632        __(movl %imm0,%arg_z)
1633        __(add $cons.size,%imm0)
1634        __(subl $node_size,%nargs)
16352:      __(jne 1b)
1636        __(movl rcontext(tcr.save0),%ra0)
1637        __(movl $0,rcontext(tcr.save0))
1638        __(jmp *%ra0)
1639_endsubp(stkconslist)
1640
1641/* do list*: last arg in arg_z, all others vpushed,   */
1642/*      nargs set to #args vpushed.  */
1643
1644_spentry(stkconslist_star)
1645        __(int $3)
1646        __(nop)
1647_endsubp(stkconslist_star)
1648
1649
1650/* Make a stack-consed simple-vector out of the NARGS objects   */
1651/*      on top of the vstack; return it in arg_z.  */
1652
1653_spentry(mkstackv)
1654        __(dnode_align(%nargs,tsp_frame.fixed_overhead+node_size,%imm0))
1655        __(TSP_Alloc_Var(%imm0,%arg_y))
1656        __(movl %nargs,%imm0)
1657        __(shll $(num_subtag_bits-fixnumshift),%imm0)
1658        __(movb $subtag_simple_vector,%imm0_b)
1659        __(movl %imm0,(%arg_y))
1660        __(leal fulltag_misc(%arg_y),%arg_z)
1661        __(test %nargs,%nargs)
1662        __(leal misc_data_offset(%arg_z,%nargs),%imm0)
1663        __(jmp 2f)
16641:      __(pop -node_size(%imm0))
1665        __(subl $node_size,%nargs)
1666        __(leal -node_size(%imm0),%imm0)
16672:      __(jne 1b)
1668        __(jmp *%ra0)   
1669_endsubp(mkstackv)
1670
1671        .globl C(egc_write_barrier_start)
1672C(egc_write_barrier_start):
1673/*  */
1674/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1675/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1676/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1677/* an intergenerational reference (a young pointer stored in an old object) has  */
1678/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1679/* This has to happen atomically, and has to happen atomically wrt GC.  */
1680
1681/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1682/* interlocked loads and stores.  */
1683
1684/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1685/* in the function, we can do the store (even if it's already been done) and  */
1686/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1687/* setting the bit needs to be done atomically, unless we're sure that other  */
1688/* threads are suspended.)  */
1689/* We can unconditionally set the suspended thread's RIP to the return address.  */
1690
1691_spentry(rplaca)
1692        .globl C(egc_rplaca)
1693C(egc_rplaca):
1694        __(rcmpl(%arg_z,%arg_y))
1695        __(_rplaca(%arg_y,%arg_z))
1696        __(ja 1f)
16970:      __(repret)
16981:      __(movl %arg_y,%imm0)
1699        __(subl lisp_global(heap_start),%imm0)
1700        __(shrl $dnode_shift,%imm0)
1701        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1702        __(jae 0b)
1703        __(ref_global(refbits,%temp0))
1704        __(xorb $31,%imm0_b)
1705        __(lock)
1706        __(btsl %imm0,(%temp0))
1707        __(ret)
1708_endsubp(rplaca)
1709
1710_spentry(rplacd)
1711        .globl C(egc_rplacd)
1712C(egc_rplacd):
1713        __(rcmpl(%arg_z,%arg_y))
1714        __(_rplacd(%arg_y,%arg_z))
1715        __(ja 1f)
17160:      __(repret)
17171:      __(movl %arg_y,%imm0)
1718        __(subl lisp_global(heap_start),%imm0)
1719        __(shrl $dnode_shift,%imm0)
1720        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1721        __(jae 0b)
1722        __(ref_global(refbits,%temp0))
1723        __(xorb $31,%imm0_b)
1724        __(lock)
1725        __(btsl %imm0,(%temp0))
1726        __(ret)
1727_endsubp(rplacd)
1728
1729/* Storing into a gvector can be handles the same way as storing into a CONS. */
1730/* args (src, unscaled-idx, val) in temp0, arg_y, arg_z */
1731_spentry(gvset)
1732        .globl C(egc_gvset)
1733C(egc_gvset):
1734        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1735        __(rcmpl(%arg_z,%temp0))
1736        __(ja 1f)
17370:      __(repret)
17381:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1739        __(subl lisp_global(heap_start),%imm0)
1740        __(shrl $dnode_shift,%imm0)
1741        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1742        __(jae 0b)
1743        __(ref_global(refbits,%temp0))
1744        __(xorb $31,%imm0_b)
1745        __(lock)
1746        __(btsl %imm0,(%temp0))
1747        __(ret)
1748_endsubp(gvset)
1749
1750/* This is a special case of storing into a gvector: if we need to  */
1751/* memoize the store, record the address of the hash-table vector  */
1752/* in the refmap, as well.  */
1753
1754_spentry(set_hash_key)
1755        .globl C(egc_set_hash_key)
1756C(egc_set_hash_key):
1757        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1758        __(rcmpl(%arg_z,%temp0))
1759        __(ja 1f)
17600:      __(repret)
17611:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1762        __(subl lisp_global(heap_start),%imm0)
1763        __(shrl $dnode_shift,%imm0)
1764        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1765        __(jae 0b)
1766        __(ref_global(refbits,%temp1))
1767        __(xorb $31,%imm0_b)
1768        __(lock)
1769        __(btsl %imm0,(%temp1))
1770        /* Now memoize the address of the hash vector */
1771        __(movl %temp0,%imm0)
1772        __(subl lisp_global(heap_start),%imm0)
1773        __(shrl $dnode_shift,%imm0)
1774        __(xorb $31,%imm0_b)
1775        __(lock)
1776        __(btsl %imm0,(%temp1))
1777        __(ret)
1778_endsubp(set_hash_key)
1779
1780/* This is a little trickier: if this is interrupted, we need to know  */
1781/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1782/* If we're interrupted   before the PC has reached the "success_test" label, */
1783/* repeat (luser the PC back to .SPstore_node_conditional.)  If we're at that */
1784/* label with the Z flag set, we won and (may) need to memoize.  */
1785
1786/* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1787_spentry(store_node_conditional)
1788        .globl C(egc_store_node_conditional)
1789C(egc_store_node_conditional):
1790        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1791        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
17920:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
1793        __(movl misc_data_offset(%temp1,%temp0),%imm0)
1794        __(jne 3f)
1795        __(lock)
1796        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1797        .globl C(egc_store_node_conditional_success_test)
1798C(egc_store_node_conditional_success_test):
1799        __(jne 0b)
1800        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1801        __(subl lisp_global(heap_start),%imm0)
1802        __(shrl $dnode_shift,%imm0)
1803        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1804        __(jae 2f)
1805        __(ref_global(refbits,%temp1))
1806        __(xorb $31,%imm0_b)
1807        __(lock)
1808        __(btsl %imm0,(%temp1))
1809        .globl C(egc_store_node_conditional_success_end)
1810C(egc_store_node_conditional_success_end):
18112:      __(movl $t_value,%arg_z)
1812        __(ret)
18133:      __(movl $nil_value,%arg_z)
1814        __(ret)
1815_endsubp(store_node_conditional)
1816
1817        /* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1818_spentry(set_hash_key_conditional)
1819        .globl C(egc_set_hash_key_conditional)
1820C(egc_set_hash_key_conditional):
1821        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1822        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
18230:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
1824        __(movl misc_data_offset(%temp1,%temp0),%imm0)
1825        __(jne 3f)
1826        __(lock)
1827        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1828        .globl C(egc_set_hash_key_conditional_success_test)
1829C(egc_set_hash_key_conditional_success_test):
1830        __(jne 0b)
1831        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1832        __(subl lisp_global(heap_start),%imm0)
1833        __(shrl $dnode_shift,%imm0)
1834        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1835        __(jae 2f)
1836        __(ref_global(refbits,%temp0))
1837        __(xorb $31,%imm0_b)
1838        __(lock)
1839        __(btsl %imm0,(%temp0))
1840        /* Now memoize the address of the hash vector */
1841        __(movl %temp1,%imm0)
1842        __(subl lisp_global(heap_start),%imm0)
1843        __(shrl $dnode_shift,%imm0)
1844        __(xorb $31,%imm0_b)
1845        __(lock)
1846        __(btsl %imm0,(%temp0))
1847        .globl C(egc_write_barrier_end)
1848C(egc_write_barrier_end):
18492:      __(movl $t_value,%arg_z)
1850        __(ret)
18513:      __(movl $nil_value,%arg_z)
1852        __(ret)
1853_endsubp(store_node_conditional)
1854
1855_spentry(setqsym)
1856        __(bt $sym_vbit_const,symbol.flags(%arg_y))
1857        __(jae _SPspecset)
1858        __(mov %arg_y,%arg_z)
1859        __(mov $XCONST,%arg_y)
1860        __(set_nargs(2))
1861        __(jmp _SPksignalerr)
1862_endsubp(setqsym)
1863
1864_spentry(progvsave)
1865        __(push %arg_y)
1866       
1867        /* Error if arg_z isn't a proper list.  That's unlikely,  */
1868        /* but it's better to check now than to crash later.  */
1869       
1870        __(compare_reg_to_nil(%arg_z))
1871        __(movl %arg_z,%temp0)  /* fast   */
1872        __(movl %arg_z,%temp1)  /* slow   */
1873        __(je 9f)               /* Null list is proper   */
18740:
1875        __(extract_lisptag(%temp0,%imm0))
1876        __(cmpb $tag_list,%imm0_b)
1877        __(jne 8f)
1878        __(compare_reg_to_nil(%temp0))
1879        __(je 9f)
1880        __(_cdr(%temp0,%arg_y)) /* (null (cdr fast)) ?   */
1881        __(compare_reg_to_nil(%arg_y))
1882        __(je 9f)
1883        __(extract_lisptag(%arg_y,%imm0))
1884        __(cmpb $tag_list,%imm0_b)
1885        __(jne 8f)
1886        __(_cdr(%arg_y,%temp0))
1887        __(_cdr(%temp1,%temp1))
1888        __(cmpl %temp1,%temp0)
1889        __(jne 0b)
1890
18918:      __(add $node_size,%esp) /* discard pushed arg_y */
1892        __(movl $XIMPROPERLIST,%arg_y)
1893        __(set_nargs(2))
1894        __(jmp _SPksignalerr)
18959:      /* Whew           */
1896
1897        /* Next, determine the length of arg_y.  We   */
1898        /* know that it's a proper list.   */
1899        __(pop %arg_y)
1900       
1901        __(movl $-fixnumone,%imm0)
1902        __(movl %arg_y,%temp0)
19031:      __(compare_reg_to_nil(%temp0))
1904        __(_cdr(%temp0,%temp0))
1905        __(leal fixnumone(%imm0),%imm0)
1906        __(jne 1b)
1907       
1908        /* imm0 is now (boxed) triplet count.  */
1909        /* Determine word count, add 1 (to align), and make room.  */
1910        /*  if count is 0, make an empty tsp frame and exit   */
1911        __(testl %imm0,%imm0)
1912        __(jne 2f)
1913        __(TSP_Alloc_Fixed(2*node_size,%imm0))
1914        __(ret)
19152:      __(movl %imm0,%temp1)
1916        __(add %imm0,%imm0)
1917        __(add %temp1,%imm0)
1918        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1919        __(TSP_Alloc_Var(%imm0,%temp0))
1920        __(movl %temp1,(%temp0))
1921        __(movd rcontext(tcr.db_link),%mm0)
19223:      __(movl $unbound_marker,%temp0)
1923        __(compare_reg_to_nil(%arg_z))
1924        __(cmovnel cons.car(%arg_z),%temp0)
1925        __(cmovnel cons.cdr(%arg_z),%arg_z)
1926        __(_car(%arg_y,%temp1))
1927        __(_cdr(%arg_y,%arg_y))
1928        __(movl symbol.binding_index(%temp1),%temp1)
1929        __(cmp rcontext(tcr.tlb_limit),%temp1)
1930        __(jb 4f)
1931        __(push %temp1)
1932        __(tlb_too_small())
19334:      __(push %arg_z)
1934        __(movl rcontext(tcr.tlb_pointer),%arg_z)
1935        __(subl $binding.size,%imm0)
1936        __(movl %temp1,binding.sym(%imm0))
1937        __(push (%arg_z,%temp1))
1938        __(pop binding.val(%imm0))
1939        __(movl %temp0,(%arg_z,%temp1))
1940        __(pop %arg_z)
1941        __(movd %mm0,binding.link(%imm0))
1942        __(movd %imm0,%mm0)
1943        __(compare_reg_to_nil(%arg_y))
1944        __(jne 3b)
1945        __(movd %mm0,rcontext(tcr.db_link))
1946        __(ret)
1947_endsubp(progvsave)
1948
1949/* Allocate node objects on the temp stack, immediate objects on the foreign  */
1950/* stack. (The caller has to know which stack to discard a frame from.)  */
1951/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
1952
1953_spentry(stack_misc_alloc)
1954        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
1955        __(jne local_label(stack_misc_alloc_not_u24))
1956        __(unbox_fixnum(%arg_z,%imm0))
1957        __(mov %arg_y,%temp0)
1958        __(shl $num_subtag_bits-fixnumshift,%temp0)
1959        __(or %temp0,%imm0)     /* %imm0 now = header */
1960        __(movd %imm0,%mm0)     /* cache header in %mm0 */
1961        __(andb $fulltagmask,%imm0_b)
1962        __(cmpb $fulltag_nodeheader,%imm0_b)
1963        __(je local_label(stack_misc_alloc_node))
1964        __(movd %mm0,%imm0)
1965        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
1966        __(jbe local_label(stack_misc_alloc_32))
1967        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
1968        __(jbe local_label(stack_misc_alloc_8))
1969        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
1970        __(jbe local_label(stack_misc_alloc_16))
1971        __(cmpb $subtag_double_float_vector,%imm0_b)
1972        __(jne local_label(stack_misc_alloc_1))
1973        /* double-float vector case */
1974        __(imul $2,%arg_y,%imm0)
1975        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1976local_label(stack_misc_alloc_1):
1977        __(unbox_fixnum(%arg_y,%imm0))
1978        __(addl $7,%imm0)
1979        __(shrl $3,%imm0)
1980        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1981local_label(stack_misc_alloc_8):
1982        __(unbox_fixnum(%arg_y,%imm0))
1983        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1984local_label(stack_misc_alloc_16):
1985        __(unbox_fixnum(%arg_y,%imm0))
1986        __(shl $1,%imm0)
1987        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1988local_label(stack_misc_alloc_32):
1989        __(mov %arg_y,%imm0)
1990local_label(stack_misc_alloc_alloc_ivector):
1991        /* byte count in %imm0 */
1992        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1993        __(cmpl $tstack_alloc_limit,%imm0)
1994        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
1995        __(movd rcontext(tcr.foreign_sp),%stack_temp)
1996        __(movd %stack_temp,%temp1)
1997        __(subl %imm0,rcontext(tcr.foreign_sp))
1998        __(movl rcontext(tcr.foreign_sp),%temp0)
19990:      __(movsd %fpzero,-dnode_size(%temp1))
2000        __(subl $dnode_size,%temp1)
2001        __(cmpl %temp1,%temp0)
2002        __(jnz 0b)
2003        __(movd %stack_temp,(%temp0))
2004        __(movl %ebp,csp_frame.save_ebp(%temp0))
2005        __(movd %mm0,csp_frame.fixed_overhead(%temp0))
2006        __(lea csp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
2007        __(ret)
2008local_label(stack_misc_alloc_heap_alloc_ivector):
2009        __(movd rcontext(tcr.foreign_sp),%stack_temp)
2010        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2011        __(movl rcontext(tcr.foreign_sp),%imm0)
2012        __(movd %stack_temp,(%imm0))
2013        __(jmp _SPmisc_alloc)
2014local_label(stack_misc_alloc_node):
2015        __(movl %arg_y,%imm0)
2016        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
2017        __(cmpl $tstack_alloc_limit,%imm0)
2018        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
2019        __(TSP_Alloc_Var(%imm0,%temp1))
2020        __(movd %mm0,(%temp1))
2021        __(leal fulltag_misc(%temp1),%arg_z)
2022        __(ret)
2023local_label(stack_misc_alloc_heap_alloc_gvector):
2024        __(TSP_Alloc_Fixed(0,%imm0))
2025        __(jmp _SPmisc_alloc)
2026
2027local_label(stack_misc_alloc_not_u24):
2028        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2029_endsubp(stack_misc_alloc)
2030
2031/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of */
2032/* initial-contents.  Note that this can be used to cons any type of */
2033/* initialized node-header'ed misc object (symbols, closures, ...) */
2034/* as well as vector-like objects. */
2035_spentry(gvector)
2036        __(subl $node_size,%nargs)      /* off by one in x862-%gvector */
2037        __(movl (%esp,%nargs),%imm0)    /* boxed subtype */
2038        __(sarl $fixnumshift,%imm0)
2039        __(movl %nargs,%arg_z)
2040        __(shll $num_subtag_bits-word_shift,%arg_z)
2041        __(orl %arg_z,%imm0)
2042        __(movd %imm0,%mm0)
2043        __(dnode_align(%nargs,node_size,%imm0))
2044        __(push %ra0)   /* aka %temp0, can't be live while consing */
2045        __(Misc_Alloc(%arg_z))
2046        __(pop %ra0)
2047        __(movl %nargs,%imm0)
2048        __(jmp 2f)
20491:      __(movl %arg_y,misc_data_offset(%arg_z,%imm0))
20502:      __(subl $node_size,%imm0)
2051        __(pop %arg_y)  /* Note the intentional fencepost: */
2052                        /* discard the subtype as well. */
2053        __(jge 1b)
2054        __(jmp *%ra0)
2055_endsubp(gvector)
2056
2057_spentry(mvpass)
2058        __(int $3)
2059_endsubp(mvpass)
2060
2061_spentry(nthvalue)
2062        __(int $3)
2063_endsubp(nthvalue)
2064
2065_spentry(values)
2066        __(movl (%temp0),%arg_y)        /* return address */
2067        __(ref_global(ret1val_addr,%imm0))
2068        __(movl $nil_value,%arg_z)
2069        __(cmpl %imm0,%arg_y)
2070        __(je 0f)
2071        __(test %nargs,%nargs)
2072        __(cmovne -node_size(%esp,%nargs),%arg_z)
2073        __(movl %temp0,%esp)
2074        __(ret)
20750:      __(movl 4(%temp0),%arg_y)
2076        __(addl $2*node_size,%temp0)
2077        __(lea (%esp,%nargs),%imm0)
2078        __(movd %nargs,%mm0)
2079        __(jmp 2f)
20801:      __(subl $node_size,%imm0)
2081        __(movl (%imm0),%temp1)
2082        __(subl $node_size,%temp0)
2083        __(movl %temp1,(%temp0))
20842:      __(cmp %imm0,%esp)
2085        __(jne 1b)
2086        __(movl %temp0,%esp)
2087        __(movd %mm0,%nargs)
2088        __(jmp *%arg_y)
2089
2090_endsubp(values)
2091
2092_spentry(default_optional_args)
2093        __(int $3)
2094_endsubp(default_optional_args)
2095
2096_spentry(opt_supplied_p)
2097        __(int $3)
2098_endsubp(opt_supplied_p)
2099
2100_spentry(lexpr_entry)
2101        __(int $3)
2102_endsubp(lexpr_entry)
2103
2104_spentry(heap_rest_arg)
2105        __(push_argregs())
2106        __(movl %temp0,%arg_y)
2107        __(movl %nargs,%imm0)
2108        __(testl %imm0,%imm0)
2109        __(movl $nil_value,%arg_z)
2110        __(jmp 2f)
2111        .p2align 4
21121:      __(pop %temp1)
2113        __(Cons(%temp1,%arg_z,%arg_z))
2114        __(subl $node_size,%imm0)
21152:      __(jg 1b)
2116        __(push %arg_z)
2117        __(movl %arg_y,%temp0)
2118        __(jmp *%ra0)
2119
2120_endsubp(heap_rest_arg)
2121
2122/* %imm0 contains the number of fixed args; make an &rest arg out of */
2123/* the others. */
2124_spentry(req_heap_rest_arg)
2125        __(push_argregs())
2126        __(movd %nargs,%mm0)
2127        __(subl %imm0,%nargs)
2128        __(movl %nargs,%imm0)
2129        __(movl %temp0,%temp1)
2130        __(movl $nil_value,%arg_z)
2131        __(jmp 2f)
2132        .p2align 4
21331:      __(pop %arg_y)
2134        __(Cons(%arg_y,%arg_z,%arg_z))
2135        __(subl $node_size,%imm0)
21362:      __(jg 1b)
2137        __(push %arg_z)
2138        __(movl %temp1,%temp0)
2139        __(movd %mm0,%nargs)
2140        __(jmp *%ra0)
2141_endsubp(req_heap_rest_arg)
2142
2143/* %imm0 bytes of stuff has already been pushed   */
2144/* make an &rest arg out of any others   */
2145_spentry(heap_cons_rest_arg)
2146        __(movd %nargs,%mm0)
2147        __(subl %imm0,%nargs)
2148        __(movl %nargs,%imm0)
2149        __(movl $nil_value,%arg_z)
2150        __(movl %ra0,%arg_y)    /* temp0 can't be live while consing */
2151        __(jmp 2f)              /* (did I mention that already?) */
2152        .p2align 4
21531:      __(pop %temp1)
2154        __(Cons(%temp1,%arg_z,%arg_z))
2155        __(subl $node_size,%imm0)
21562:      __(jg 1b)
2157        __(push %arg_z)
2158        __(movd %mm0,%nargs)
2159        __(jmp *%arg_y)
2160_endsubp(heap_cons_rest_arg)
2161
2162_spentry(simple_keywords)
2163        __(xor %imm0,%imm0)
2164        __(push_argregs())
2165        __(jmp _SPkeyword_bind)
2166_endsubp(simple_keywords)
2167
2168_spentry(keyword_args)
2169        __(push_argregs())
2170        __(jmp _SPkeyword_bind)
2171_endsubp(keyword_args)
2172
2173/* There are %nargs words of arguments on the stack; %imm0 contains the */
2174/* number of non-keyword args pushed.  It's possible that we never actually */
2175/* got any keyword args, which would make things much simpler. */
2176
2177/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
2178/* indicating whether &allow-other-keys and/or &rest was present in the */
2179/* lambda list. */
2180
2181/* Once we get here, we can use the arg registers. */
2182
2183/* N.B.: %ra0 is %temp0, and must not be clobbered. */
2184
2185define([keyword_flags_aok_bit],[16])
2186define([keyword_flags_unknown_keys_bit],[17])
2187define([keyword_flags_rest_bit],[18])
2188define([keyword_flags_seen_aok_bit],[19])
2189
2190_spentry(keyword_bind)
2191        __(movl %temp1,rcontext(tcr.unboxed0))  /* save keyword flags */
2192        __(movzwl %nargs_w,%nargs)
2193        __(movl %nargs,%arg_z)
2194        __(subl %imm0,%arg_z)
2195        __(jbe local_label(no_keyword_values))
2196        __(btl $word_shift,%arg_z)
2197        __(jnc local_label(even))
2198        __(movl $nil_value,%arg_y)
2199        __(movl %arg_z,%nargs)
2200        __(test %nargs,%nargs)
2201        __(movl %ra0,rcontext(tcr.save0))       /* save temp0 while consing */
2202        __(jmp 1f)
22030:      __(pop %arg_z)
2204        __(Cons(%arg_z,%arg_y,%arg_y))
2205        __(subl $node_size,%nargs)
22061:      __(jnz 0b)
2207        __(movl rcontext(tcr.save0),%ra0)
2208        __(movapd %fpzero,rcontext(tcr.save0))
2209        __(movl %arg_y,%arg_z)
2210        __(movl $XBADKEYS,%arg_y)
2211        __(set_nargs(2))
2212        __(jmp _SPksignalerr)
2213
2214        /* Now that we're sure that we have an even number of */
2215        /* keywords and values (in %arg_z), move the pairs over */
2216        /* to the temp stack. */
2217local_label(even):
2218        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
2219        __(TSP_Alloc_Var(%arg_y,%imm0))
22202:      __(subl $node_size,%arg_y)
2221        __(pop (%arg_y))
2222        __(cmpl %arg_y,%imm0)
2223        __(jne 2b)
2224
2225        /* Get the keyword vector into %arg_y, and its length into %imm0. */
2226        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
2227        /* for each declared keyword. */
2228        __(movzwl misc_data_offset(%fn),%imm0)
2229        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2230        __(vector_length(%arg_y,%imm0))
2231        __(jmp 4f)
22323:      __(push $nil_value)
2233        __(push $nil_value)
22344:      __(subl $fixnumone,%imm0)
2235        __(jge 3b)
2236
2237        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
2238        /* in order to get a couple more registers to work with. */
2239        __(push %ra0)
2240        __(push %nargs)
2241
2242        /* At this point we have: */
2243        /* number of supplied keywords and values in %arg_z */
2244        /* keyword vector in %arg_y */
2245        __(vector_length(%arg_y,%imm0))
2246        __(push %imm0)          /* count of declared keywords */
2247        __(push %arg_z)         /* count of supplied keys and values */
2248
2249        /* For each declared keyword, iterate over the supplied k/v pairs */
2250        /* to see if it's supplied and what the value is. */
2251        /* checking to see if any */
2252        /* key-value pairs were unexpectedly supplied. */
2253
2254        __(movl rcontext(tcr.save_tsp),%temp0)
2255        __(addl $2*node_size,%temp0) /* skip frame overhead */
2256        /* %temp0: top of tstack (skipping frame overhead) */
2257        __(lea 4*node_size(%esp,%imm0,2),%temp1)
2258        /* %temp1: word above 0th value/supplied-p pair on vstack */
2259        /* %arg_y: keyword vector */
2260        __(xorl %imm0,%imm0)
2261        /* %imm0: index */
2262        /* %arg_z: temporary */
2263
2264        /* Iterate over supplied k/v pairs on tstack.  See if key is */
2265        /* in the keyword vector.  Copy value and set supplied-p on */
2266        /* vstack if found. */
2267
2268local_label(tstack_loop):
2269        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
2270        __(push %imm0)
2271        __(xorl %imm0,%imm0)
2272        __(cmpl $nrs.kallowotherkeys,%arg_z)
2273        __(jne local_label(next_keyvect_entry))
2274        __(btsl $keyword_flags_seen_aok_bit,rcontext(tcr.unboxed0))
2275        __(jc local_label(next_keyvect_entry))
2276        __(push %imm0)
2277        __(movl 4(%esp),%imm0)
2278        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
2279        __(pop %imm0)
2280        __(je local_label(next_keyvect_entry))
2281        __(btsl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2282        __(jmp local_label(next_keyvect_entry))
2283        /* loop through keyword vector */
22846:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
2285        __(jne 7f)
2286        /* Got a match; have we already seen this keyword? */
2287        __(negl %imm0)
2288        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
2289        __(jne 9f)      /* seen it, ignore this value */
2290        __(movl (%esp),%arg_z)
2291        __(lea (%temp0,%arg_z,2),%arg_z)
2292        __(movl node_size(%arg_z),%arg_z) /* value for this key */
2293        __(movl %arg_z,-node_size(%temp1,%imm0,2))
2294        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
2295        __(jmp 9f)
22967:      __(addl $node_size,%imm0)
2297local_label(next_keyvect_entry):
2298        __(cmpl %imm0,8(%esp))
2299        __(jne 6b)
2300        /* Didn't match anything in the keyword vector.  Is the keyword */
2301        /* :allow-other-keys? */
2302        __(cmpl $nrs.kallowotherkeys,%arg_z)
2303        __(je 9f)       /* :allow-other-keys is never "unknown" */
23048:      __(btsl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
23059:      __(pop %imm0)
2306        __(addl $fixnumone,%imm0)
2307        __(movl %imm0,%arg_z)
2308        __(shll $1,%arg_z)      /* pairs of tstack words */
2309        __(cmpl %arg_z,0(%esp))
2310        __(jne local_label(tstack_loop))
2311
2312        __(pop %imm0)   /* count of supplied keys and values */
2313        __(addl $node_size,%esp)
2314        __(pop %nargs)
2315        __(pop %ra0)
2316
2317        /* If the function takes an &rest arg, or if we got an unrecognized */
2318        /* keyword and don't allow that, copy the incoming k/v pairs from */
2319        /* the temp stack back to the value stack. */
2320        __(btl $keyword_flags_rest_bit,rcontext(tcr.unboxed0))
2321        __(jc 1f)
2322        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
2323        __(jnc 0f)
2324        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2325        __(jnc 1f)
2326        /* pop the tstack frame */
23270:      __(discard_temp_frame(%imm0))
2328        __(jmp *%ra0)
2329
2330        /* Copy the k/v pairs from the tstack back to the value stack, */
2331        /* either because the function takes an &rest arg or because */
2332        /* we need to signal an "unknown keywords" error. */
23331:      __(movl rcontext(tcr.save_tsp),%arg_z)
2334        __(mov (%arg_z),%arg_y)
2335        __(jmp 3f)
23362:      __(push (%arg_z))
2337        __(push node_size(%arg_z))
23383:      __(addl $dnode_size,%arg_z)
2339        __(cmpl %arg_z,%arg_y)
2340        __(jne 2b)
2341        __(discard_temp_frame(%arg_z))
2342        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
2343        __(jnc 9f)
2344        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2345        __(jc 9f)
2346        /* Signal an "unknown keywords" error */
2347        __(movl %imm0,%nargs)
2348        __(movl $nil_value,%arg_z)
2349        __(test %nargs,%nargs)
2350        __(movl %ra0,rcontext(tcr.save0))
2351        __(jmp 5f)
23524:      __(pop %arg_y)
2353        __(Cons(%arg_y,%arg_z,%arg_z))
2354        __(subl $node_size,%nargs)
23555:      __(jnz 4b)
2356        __(movl $XBADKEYS,%arg_y)
2357        __(set_nargs(2))
2358        __(movl rcontext(tcr.save0),%ra0)
2359        __(movl $0,rcontext(tcr.save0))
2360        __(jmp _SPksignalerr)
23619:      __(jmp *%ra0)
2362
2363/* No keyword value were provided.  Access the keyword vector (which is the */
2364/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
2365/* N could be 0... */
2366
2367local_label(no_keyword_values):
2368        __(movzwl misc_data_offset(%fn),%imm0)
2369        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2370        __(vector_length(%arg_y,%arg_z))
2371        __(movl $nil_value,%imm0)
2372        __(jmp 1f)
23730:      __(push %imm0)
2374        __(push %imm0)
23751:      __(subl $fixnumone,%arg_z)
2376        __(jge 0b)
2377        __(jmp *%ra0)
2378_endsubp(keyword_bind)
2379
2380/* Normally, we'd just set %fname (aka %temp0) and do */
2381/* jump_fname().  Sometimes, though, %temp0 is being used */
2382/* as %ra0, and I'm not sure that it's going to be safe to */
2383/* clobber that.  (Note that nil-relative symbols aren't going */
2384/* get moved around by the GC, so we can get away with putting */
2385/* '%err-disp in %imm0.) */
2386_spentry(ksignalerr)
2387        __(mov $nrs.errdisp,%imm0)
2388        __(mov symbol.fcell(%imm0),%fn)
2389        __(jump_fn)
2390_endsubp(ksignalerr)
2391
2392_spentry(stack_rest_arg)
2393        __(xorl %imm0,%imm0)
2394        __(push_argregs())
2395        __(jmp _SPstack_cons_rest_arg)
2396_endsubp(stack_rest_arg)
2397
2398_spentry(req_stack_rest_arg)
2399        __(push_argregs())
2400        __(jmp _SPstack_cons_rest_arg)
2401_endsubp(req_stack_rest_arg)
2402
2403_spentry(stack_cons_rest_arg)
2404        __(movd %nargs,%mm2)
2405        __(movl %temp0,rcontext(tcr.save0))
2406        __(subl %imm0,%temp1)
2407        __(movl $nil_value,%arg_z)
2408        __(jle 2f)      /* empty list; make an empty TSP frame */
2409        __(addl %temp1,%temp1)
2410        __(cmpl $(tstack_alloc_limit-dnode_size),%temp1)
2411        __(ja 3f)       /* make empty frame, then heap-cons */
2412        __(dnode_align(%temp1,tsp_frame.fixed_overhead,%imm0))
2413        __(TSP_Alloc_Var(%imm0,%temp0))
2414        __(addl $fulltag_cons,%temp0)
24151:      __(pop %arg_y)
2416        __(_rplacd(%temp0,%arg_z))
2417        __(_rplaca(%temp0,%arg_y))
2418        __(movl %temp0,%arg_z)
2419        __(addl $cons.size,%temp0)
2420        __(subl $dnode_size,%temp1)
2421        __(jne 1b)
2422        __(push %arg_z)
2423        __(movd %mm2,%nargs)
2424        __(movl rcontext(tcr.save0),%temp0)
2425        __(movss %fpzero,rcontext(tcr.save0))
2426        __(jmp *%temp0)
2427/* Length 0, make empty frame */
24282:
2429        __(TSP_Alloc_Fixed(0,%temp0))
2430        __(push %arg_z)
2431        __(movd %mm2,%nargs)
2432        __(movl rcontext(tcr.save0),%temp0)
2433        __(movss %fpzero,rcontext(tcr.save0))
2434        __(jmp *%temp0)
2435/* Too big to stack-cons, but make an empty frame before heap-consing */
2436        __(TSP_Alloc_Fixed(0,%temp0))
2437        __(movd %mm2,%nargs)
2438        __(movl rcontext(tcr.save0),%temp0)
2439        __(movss %fpzero,rcontext(tcr.save0))
2440        __(jmp _SPheap_cons_rest_arg)
2441_endsubp(stack_cons_rest_arg)
2442
2443_spentry(getxlong)
2444        __(int $3)
2445_endsubp(getxlong)
2446
2447/* Have to be a little careful here: the caller may or may not have pushed  */
2448/* an empty frame, and we may or may not have needed one.  We can't easily  */
2449/* tell whether or not a frame will be needed (if the caller didn't reserve  */
2450/* a frame, whether or not we need one depends on the length of the list  */
2451/* in arg_z.  So, if the caller didn't push a frame, we do so; once */
2452/* everything's been spread, we discard the reserved frame (regardless of
2453/* who pushed it) if all args fit in registers.   */
2454
2455/* xxx preserve temp1 somehow? cf. comment in x862-invoke-fn */
2456_spentry(spreadargz)
2457        __(test %nargs,%nargs)
2458        __(jne 0f)
2459        __(push $reserved_frame_marker)
2460        __(push $reserved_frame_marker)
24610:      __(movl %arg_z,rcontext(tcr.save0))     /* save in case of error */
2462        __(movd %nargs,%mm0)    /* now we can use %temp1 */
2463        __(xorl %nargs,%nargs)
2464        __(cmpl $nil_value,%arg_z)
2465        __(je 2f)
24661:      __(extract_fulltag(%arg_z,%imm0))
2467        __(cmpb $fulltag_cons,%imm0_b)
2468        __(jne 9f)
2469        __(_car(%arg_z,%arg_y))
2470        __(_cdr(%arg_z,%arg_z))
2471        __(add $node_size,%nargs)
2472        __(cmpl $call_arguments_limit<<fixnumshift,%nargs)
2473        __(jge 8f)
2474        __(push %arg_y)
2475        __(cmpl $nil_value,%arg_z)
2476        __(jne 1b)
24772:      __(movd %mm0,%imm0)
2478        __(addl %imm0,%nargs)
2479        __(jne 4f)
24803:      __(addl $2*node_size,%esp)
2481        __(movl $0,rcontext(tcr.save0))
2482        __(jmp *%ra0)
24834:      __(pop %arg_z)
2484        __(cmp $1*node_size,%nargs)
2485        __(je 3b)
2486        __(pop %arg_y)
2487        __(cmp $2*node_size,%nargs)
2488        __(je 3b)
2489        __(movl $0,rcontext(tcr.save0))
2490        __(jmp *%ra0)
2491/* Discard everything that's been pushed already, complain */
24928:      __(lea (%esp,%nargs),%esp)
2493        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2494        __(movl $0,rcontext(tcr.save0))
2495        __(movl $XTMINPS,%arg_y)
2496        __(set_nargs(2))
2497        __(push %ra0)
2498        __(jmp _SPksignalerr)
24999:      __(lea (%esp,%nargs),%esp)
2500        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2501        __(movl $0,rcontext(tcr.save0))
2502        __(movl $XNOSPREAD,%arg_y)
2503        __(set_nargs(2))
2504        __(push %ra0)
2505        __(jmp _SPksignalerr)
2506_endsubp(spreadargz)
2507
2508
2509/* Caller built its own frame when it was entered.  If all outgoing args  */
2510/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2511/* relative to it and restore %rbp/%ra0   */
2512_spentry(tfuncallgen)
2513        __(cmpl $nargregs*node_size,%nargs)
2514        __(jbe 9f)
2515        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2516        __(movl %temp0,rcontext(tcr.save0))
2517        __(movd %nargs,%mm0)
2518        __(xorl %temp1,%temp1)
2519        /* We can use %ra0 as a temporary here, since the real return address */
2520        /* is on the stack   */
25210:      __(movl -node_size(%imm0),%ra0)
2522        __(movl %ra0,-node_size(%ebp,%temp1))
2523        __(subl $node_size,%imm0)
2524        __(subl $node_size,%temp1)
2525        __(cmpl %imm0,%esp)
2526        __(jne 0b)
2527        __(lea (%ebp,%temp1),%esp)
2528        __(movl 4(%ebp),%ra0)
2529        __(movl (%ebp),%ebp)
2530        __(pushl %ra0)
2531        __(movd %mm0,%nargs)
2532        __(movl rcontext(tcr.save0),%temp0)
2533        __(movss %fpzero,rcontext(tcr.save0))
2534        __(do_funcall())
2535        /* All args in regs; exactly the same as the tfuncallvsp case   */
25369:             
2537        __(leave)
2538        __(do_funcall())
2539
2540_endsubp(tfuncallgen)
2541
2542/* Some args were pushed; move them down in the frame   */
2543_spentry(tfuncallslide)
2544        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2545        __(movd %nargs,%mm0)
2546        __(xorl %temp1,%temp1)
2547        __(movl %temp0,rcontext(tcr.save0))
25480:      __(movl -node_size(%imm0),%temp0)
2549        __(movl %temp0,-node_size(%ebp,%temp1))
2550        __(subl $node_size,%imm0)
2551        __(subl $node_size,%temp1)
2552        __(cmpl %imm0,%esp)
2553        __(jne 0b)
2554        __(lea (%ebp,%temp1),%esp)
2555        __(push 4(%ebp))        /* return address */
2556        __(movl (%ebp),%ebp)
2557        __(movd %mm0,%nargs)
2558        __(movl rcontext(tcr.save0),%temp0)
2559        __(movss %fpzero,rcontext(tcr.save0))
2560        __(do_funcall())
2561_endsubp(tfuncallslide)
2562
2563/* No args were pushed; recover saved context & do funcall        */
2564_spentry(tfuncallvsp)
2565        __(leave)
2566        __(do_funcall())
2567_endsubp(tfuncallvsp)
2568
2569_spentry(tcallsymgen)
2570        __(cmpl $nargregs*node_size,%nargs)
2571        __(jbe 9f)
2572        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2573        __(movd %nargs,%mm0)
2574        __(movl %temp0,rcontext(tcr.save0))
2575        __(xorl %temp1,%temp1)  /* aka nargs */
25760:      __(movl -node_size(%imm0),%temp0)
2577        __(movl %temp0,-node_size(%ebp,%temp1))
2578        __(subl $node_size,%imm0)
2579        __(subl $node_size,%temp1)
2580        __(cmpl %imm0,%esp)
2581        __(jne 0b)
2582        __(lea (%ebp,%temp1),%esp)
2583        __(movl 4(%ebp),%temp0)
2584        __(movl (%ebp),%ebp)
2585        __(push %temp0)
2586        __(movl rcontext(tcr.save0),%temp0)
2587        __(movss %fpzero,rcontext(tcr.save0))
2588        __(movd %mm0,%nargs)
2589        __(jump_fname())
2590/* All args in regs; exactly the same as the tcallsymvsp case. */
25919:
2592        __(leave)
2593        __(jump_fname())
2594_endsubp(tcallsymgen)
2595
2596_spentry(tcallsymslide)
2597        __(movl %ebp,%imm0)
2598        __(subl %nargs,%imm0)
2599        __(addl $nargregs*node_size,%imm0)      /* new tos */
2600        __(push %imm0)
2601        __(push %arg_y)
2602        __(push %arg_z)
2603        __(push %nargs)
2604        __(lea (4-nargregs)*node_size(%esp,%nargs),%arg_y) /* src ptr */
2605        __(movl %ebp,%imm0) /* dst ptr */
2606        __(subl $fixnumone*nargregs,%nargs)
2607        __(jmp 1f)
26080:      __(subl $node_size,%arg_y)
2609        __(movl (%arg_y),%arg_z)
2610        __(subl $node_size,%imm0)
2611        __(movl %arg_z,(%imm0))
26121:      __(subl $fixnumone,%nargs)
2613        __(jge 0b)
2614        __(pop %nargs)
2615        __(pop %arg_z)
2616        __(pop %arg_y)
2617        __(pop %esp)
2618        __(push node_size(%ebp))
2619        __(movl 0(%ebp),%ebp)
2620        __(jump_fname)
2621_endsubp(tcallsymslide)
2622
2623_spentry(tcallsymvsp)
2624        __(leave)
2625        __(jump_fname())
2626_endsubp(tcallsymvsp)
2627
2628_spentry(tcallnfngen)
2629        __(cmpl $nargregs*node_size,%nargs)
2630        __(jbe 9f)
2631        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2632        __(movd %nargs,%mm0)    /* stash nargs aka temp1 */
2633        __(xorl %temp1,%temp1)
2634        __(movl %temp0,rcontext(tcr.save0))
2635        /* It's OK to use %ra0 (%temp0) as an temp here, since the */
2636        /* real return address is on the stack. */
26370:      __(movl -node_size(%imm0),%ra0)
2638        __(movl %ra0,-node_size(%ebp,%temp1))
2639        __(subl $node_size,%imm0)
2640        __(subl $node_size,%temp1)
2641        __(cmpl %imm0,%esp)
2642        __(jne 0b)
2643        __(movl rcontext(tcr.save0),%fn)
2644        __(movss %fpzero,rcontext(tcr.save0))
2645        __(lea (%ebp,%temp1),%esp)
2646        __(movl lisp_frame.savera0(%ebp),%ra0)
2647        __(movl lisp_frame.backlink(%ebp),%ebp)
2648        __(push %ra0)
2649        __(movd %mm0,%nargs)
2650        __(jmp *%fn)
26519:      /* All args in regs; exactly the same as the tcallnfnvsp case */
2652        __(movl %temp0,%fn)
2653        __(leave)
2654        __(jmp *%fn)
2655_endsubp(tcallnfngen)
2656
2657_spentry(tcallnfnslide)
2658        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2659        __(movd %nargs,%mm0)    /* save nargs aka temp1 */
2660        __(xorl %temp1,%temp1)
2661        __(movl %temp0,rcontext(tcr.save0))
2662        /* We can use %ra0 as a temporary here, since the real return address */
2663        /* is on the stack   */
26640:      __(movl -node_size(%imm0),%ra0)
2665        __(movl %ra0,-node_size(%ebp,%temp1))
2666        __(subl $node_size,%imm0)
2667        __(subl $node_size,%temp1)
2668        __(cmpl %imm0,%esp)
2669        __(jne 0b)
2670        __(movl rcontext(tcr.save0),%fn)
2671        __(lea (%ebp,%temp1),%esp)
2672        __(movl lisp_frame.savera0(%ebp),%ra0)
2673        __(movl lisp_frame.backlink(%ebp),%ebp)
2674        __(push %ra0)
2675        __(movapd %fpzero,rcontext(tcr.save0))
2676        __(movd %mm0,%nargs)
2677        __(jmp *%fn)
2678_endsubp(tcallnfnslide)
2679
2680_spentry(tcallnfnvsp)
2681        __(mov %temp0,%fn)
2682        __(leave)
2683        __(jmp *%fn)
2684_endsubp(tcallnfnvsp)
2685
2686/* Make a "raw" area on the foreign stack, stack-cons a macptr to point */
2687/* to it, and return the macptr.  Size (in bytes, boxed) is in arg_z */
2688/* on entry; macptr in arg_z on exit. */
2689_spentry(makestackblock)
2690        __(check_cstack_alignment())
2691        __(unbox_fixnum(%arg_z,%imm0))
2692        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2693        __(cmpl $tstack_alloc_limit,%imm0)
2694        __(jae 1f)
2695        __(movd rcontext(tcr.foreign_sp),%mm0)
2696        __(subl %imm0,rcontext(tcr.foreign_sp))
2697        __(movl rcontext(tcr.foreign_sp),%arg_z)
2698        __(movd %mm0,(%arg_z))
2699        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2700        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2701        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2702        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2703        __(movl %imm0,macptr.address(%arg_z))
2704        __(movss %fpzero,macptr.domain(%arg_z))
2705        __(movss %fpzero,macptr.type(%arg_z))
2706        __(ret)
27071:      __(movd rcontext(tcr.foreign_sp),%mm0)
2708        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2709        __(movl rcontext(tcr.foreign_sp),%imm0)
2710        __(movd %mm0,(%imm0))
2711        __(movl %ebp,csp_frame.save_ebp(%imm0))
2712        __(set_nargs(1))
2713        __(movl $nrs.new_gcable_ptr,%fname)
2714        __(jump_fname())
2715_endsubp(makestackblock)
2716
2717_spentry(makestackblock0)
2718        __(unbox_fixnum(%arg_z,%imm0))
2719        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2720        __(cmpl $tstack_alloc_limit,%imm0)
2721        __(jae 9f)
2722        __(movl rcontext(tcr.foreign_sp),%temp0)
2723        __(subl %imm0,rcontext(tcr.foreign_sp))
2724        __(movl rcontext(tcr.foreign_sp),%arg_z)
2725        __(movl %temp0,(%arg_z))
2726        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2727        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2728        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2729        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2730        __(movl %imm0,macptr.address(%arg_z))
2731        __(movss %fpzero,macptr.domain(%arg_z))
2732        __(movss %fpzero,macptr.type(%arg_z))
2733        __(jmp 2f)
27341:      __(movsd %fpzero,(%imm0))
2735        __(addl $dnode_size,%imm0)
27362:      __(cmpl %imm0,%temp0)
2737        __(jne 1b)
2738        __(repret)
27399:      __(movd rcontext(tcr.foreign_sp),%mm0)
2740        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2741        __(movl rcontext(tcr.foreign_sp),%imm0)
2742        __(movd %mm0,(%imm0))
2743        __(movl %ebp,csp_frame.save_ebp(%imm0))
2744        __(set_nargs(1))
2745        __(movl $nrs.new_gcable_ptr,%fname)
2746        __(jump_fname())
2747_endsubp(makestackblock0)
2748
2749_spentry(makestacklist)
2750        __(test %arg_y,%arg_y)
2751        __(js 9f)
2752        __(movl %arg_y,%imm0)
2753        __(testb $fixnummask,%imm0_b)
2754        __(jne 9f)
2755        __(addl %imm0,%imm0)
2756        __(rcmpl(%imm0,$tstack_alloc_limit))
2757        __(movl $nil_value,%temp1) 
2758        __(jae 2f)
2759        __(addl $tsp_frame.fixed_overhead,%imm0)
2760        __(TSP_Alloc_Var(%imm0,%temp0))
2761        __(addl $fulltag_cons,%temp0)
2762        __(jmp 1f)
27630:      __(_rplaca(%temp0,%arg_z))
2764        __(_rplacd(%temp0,%temp1))
2765        __(movl %temp0,%temp1)
2766        __(addl $cons.size,%temp0)
27671:      __(subl $fixnumone,%arg_y)
2768        __(jge 0b)
2769        __(movl %temp1,%arg_z)
2770        __(ret)
27712:      __(TSP_Alloc_Fixed(0,%imm0))
2772        __(jmp 4f)
27733:      __(Cons(%arg_z,%temp1,%temp1))
27744:      __(subl $fixnumone,%arg_y)                             
2775        __(jge 3b)
2776        __(movl %temp1,%arg_z)
2777        __(ret)
27789:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
2779_endsubp(makestacklist)
2780
2781/* subtype (boxed) vpushed before initial values. (Had better be a */
2782/* node header subtag.)  Nargs set to count of things vpushed. */
2783_spentry(stkgvector)
2784        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2785        __(shrl $fixnumshift,%imm0)
2786        __(leal -fixnumone(%nargs),%arg_z)
2787        __(movl %arg_z,%arg_y)
2788        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2789        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2790        __(movd %imm0,%mm0)
2791        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2792        __(TSP_Alloc_Var(%imm0,%arg_z))
2793        __(movd %mm0,(%arg_z))
2794        __(addl $fulltag_misc,%arg_z)
2795        __(lea -node_size(%nargs),%imm0)
2796        __(jmp 2f)
27971:      __(pop misc_data_offset(%arg_z,%imm0))
27982:      __(subl $node_size,%imm0)
2799        __(jge 1b)
2800        __(addl $node_size,%esp)
2801        __(jmp *%ra0)
2802_endsubp(stkgvector)
2803
2804/* Allocate a fulltag-misc object. */
2805/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
2806_spentry(misc_alloc)
2807        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2808        __(jne local_label(misc_alloc_not_u24))
2809        __(unbox_fixnum(%arg_z,%imm0))
2810        __(mov %arg_y,%temp0)
2811        __(shl $num_subtag_bits-fixnumshift,%temp0)
2812        __(or %temp0,%imm0)     /* %imm0 now = header */
2813        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2814        __(andb $fulltagmask,%imm0_b)
2815        __(cmpb $fulltag_nodeheader,%imm0_b)
2816        __(je local_label(misc_alloc_32))
2817        __(movd %mm0,%imm0)
2818        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2819        __(jbe local_label(misc_alloc_32))
2820        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2821        __(jbe local_label(misc_alloc_8))
2822        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2823        __(jbe local_label(misc_alloc_16))
2824        __(cmpb $subtag_double_float_vector,%imm0_b)
2825        __(jne local_label(misc_alloc_1))
2826        /* double-float vector case */
2827        __(imul $2,%arg_y,%imm0)
2828        __(jmp local_label(misc_alloc_alloc_vector))
2829local_label(misc_alloc_1):
2830        __(unbox_fixnum(%arg_y,%imm0))
2831        __(addl $7,%imm0)
2832        __(shrl $3,%imm0)
2833        __(jmp local_label(misc_alloc_alloc_vector))
2834local_label(misc_alloc_8):
2835        __(unbox_fixnum(%arg_y,%imm0))
2836        __(jmp local_label(misc_alloc_alloc_vector))
2837local_label(misc_alloc_16):
2838        __(unbox_fixnum(%arg_y,%imm0))
2839        __(shl $1,%imm0)
2840        __(jmp local_label(misc_alloc_alloc_vector))
2841local_label(misc_alloc_32):
2842        __(movl %arg_y,%imm0)
2843local_label(misc_alloc_alloc_vector):
2844        __(dnode_align(%imm0,node_size,%imm0))
2845        __(Misc_Alloc(%arg_z))
2846        __(ret)
2847local_label(misc_alloc_not_u24):
2848        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2849_endsubp(misc_alloc)
2850
2851/* N.B. arg count word in %imm0, not %nargs */
2852/* no %whole_reg;  it's in rcontext(tcr.save0) */
2853/* %arg_reg is %temp1, key vector in %arg_y */
2854_startfn(C(destbind1))
2855        __(movl %ra0,rcontext(tcr.save1))
2856        /* Save entry %esp in case of error   */
2857        __(movd %esp,%mm0)
2858        /* Save arg count word */
2859        __(movd %imm0,%mm1)
2860        /* Extract required arg count.   */
2861        __(testb %imm0_b,%imm0_b)
2862        __(je local_label(opt))         /* skip if no required args   */
2863        __(movzbl %imm0_b,%imm0)
2864local_label(req_loop): 
2865        __(compare_reg_to_nil(%arg_reg))
2866        __(je local_label(toofew))
2867        __(movb $fulltagmask,%imm0_bh)
2868        __(andb %arg_reg_b,%imm0_bh)
2869        __(cmpb $fulltag_cons,%imm0_bh)
2870        __(jne local_label(badlist))
2871        __(subb $1,%imm0_b)
2872        __(pushl cons.car(%arg_reg))
2873        __(_cdr(%arg_reg,%arg_reg))
2874        __(jne local_label(req_loop))
2875        __(movd %mm1,%imm0)
2876local_label(opt):
2877        __(testb %imm0_bh,%imm0_bh)
2878        __(je local_label(rest_keys))
2879        __(btl $initopt_bit,%imm0)
2880        __(jc local_label(opt_supp))
2881        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2882local_label(simple_opt_loop):
2883        __(compare_reg_to_nil(%arg_reg))
2884        __(je local_label(default_simple_opt))
2885        __(movb $fulltagmask,%imm0_bh)
2886        __(andb %arg_reg_b,%imm0_bh)
2887        __(cmpb $fulltag_cons,%imm0_bh)
2888        __(jne local_label(badlist))
2889        __(subb $1,%imm0_b)
2890        __(pushl cons.car(%arg_reg))
2891        __(_cdr(%arg_reg,%arg_reg))
2892        __(jne local_label(simple_opt_loop))
2893        __(jmp local_label(rest_keys))
2894local_label(default_simple_opt):
2895        __(subb $1,%imm0_b)
2896        __(pushl $nil_value)
2897        __(jne local_label(default_simple_opt))
2898        __(jmp local_label(rest_keys))
2899local_label(opt_supp):
2900        __(movb $fulltagmask,%imm0_bh)
2901        __(andb %arg_reg_b,%imm0_bh)
2902        __(compare_reg_to_nil(%arg_z))
2903        __(je local_label(default_hard_opt))
2904        __(cmpb $fulltag_cons,%imm0_bh)
2905        __(jne local_label(badlist))
2906        __(subb $1,%imm0_b)
2907        __(pushl cons.car(%arg_reg))
2908        __(_cdr(%arg_reg,%arg_reg))
2909        __(push $t_value)
2910        __(jne local_label(opt_supp))
2911        __(jmp local_label(rest_keys))
2912local_label(default_hard_opt):
2913        __(subb $1,%imm0_b)
2914        __(push $nil_value)
2915        __(push $nil_value)
2916        __(jne local_label(default_hard_opt))
2917local_label(rest_keys):
2918        __(btl $restp_bit,%imm0)
2919        __(jc local_label(have_rest))
2920        __(btl $keyp_bit,%imm0)
2921        __(jc local_label(have_keys))
2922        __(compare_reg_to_nil(%arg_reg))
2923        __(jne local_label(toomany))
2924        __(movss %fpzero,rcontext(tcr.save0))
2925        __(jmp *%ra0)
2926local_label(have_rest):
2927        __(pushl %arg_reg)
2928        __(btl $keyp_bit,%imm0)
2929        __(jc local_label(have_keys))
2930        __(movss %fpzero,rcontext(tcr.save0))
2931        __(jmp *%ra0)
2932        /* Ensure that arg_reg contains a proper,even-length list.  */
2933        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2934local_label(have_keys):
2935        __(movb $255,%imm0_b)
2936        __(push %arg_reg)
2937        __(push %arg_z)
2938        __(xorl %arg_z,%arg_z)
2939local_label(count_keys_loop):
2940        __(compare_reg_to_nil(%arg_reg))
2941        __(je local_label(counted_keys))
2942        __(subb $1,%imm0_b)
2943        __(jb local_label(toomany))
2944        __(movb $fulltagmask,%arg_z_bh)
2945        __(andb %arg_reg_b,%arg_z_bh)
2946        __(cmpb $fulltag_cons,%arg_z_bh)
2947        __(jne local_label(badlist))
2948        __(_cdr(%arg_reg,%arg_reg))
2949        __(movb $fulltagmask,%arg_z_bh)
2950        __(andb %arg_reg_b,%arg_z_bh)
2951        __(cmpb $fulltag_cons,%arg_z_bh)
2952        __(jne local_label(badlist))
2953        __(_cdr(%arg_reg,%arg_reg))
2954        __(jmp local_label(count_keys_loop))
2955local_label(counted_keys):             
2956        /* We've got a proper, even-length list of key/value pairs in  */
2957        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2958        /* of NILs on the vstack.   */
2959        __(pop %arg_z)
2960        __(pop %arg_reg)
2961        __(movd %mm1,%imm0)
2962        __(shrl $16,%imm0)
2963        __(movzbl %imm0_b,%imm0)
2964        __(movl %esp,rcontext(tcr.unboxed0))    /* 0th value/supplied-p pair */
2965        __(jmp local_label(push_pair_test))
2966local_label(push_pair_loop):
2967        __(push $nil_value)
2968        __(push $nil_value)
2969local_label(push_pair_test):   
2970        __(subb $1,%imm0_b)
2971        __(jge local_label(push_pair_loop))
2972        __(push %temp0) /* keyword */
2973        __(push %arg_z) /* value */
2974        __(vector_length(%arg_y,%imm0))
2975        __(push %arg_reg)
2976        __(push %imm0)  /* keyword vector length */
2977        __(movd %mm1,%imm0)
2978        __(movl $0,rcontext(tcr.unboxed1)) /* count of unknown keywords seen */
2979local_label(match_keys_loop):
2980        __(movl 4(%esp),%arg_reg)
2981        __(compare_reg_to_nil(%arg_reg))
2982        __(je local_label(matched_keys))
2983        __(_car(%arg_reg,%temp0))
2984        __(_cdr(%arg_reg,%arg_reg))
2985        __(_car(%arg_reg,%arg_z))
2986        __(_cdr(%arg_reg,%arg_reg))
2987        __(movl %arg_reg,4(%esp))
2988        __(xorl %temp1,%temp1)
2989        __(jmp local_label(match_test))
2990local_label(match_loop):
2991        __(cmpl misc_data_offset(%arg_y,%temp1),%arg_z)
2992        __(je local_label(matched))
2993        __(addl $node_size,%temp1)
2994local_label(match_test):
2995        __(cmpl %temp1,(%esp))  /* compare index, keyword vector length */
2996        __(jne local_label(match_loop))
2997        /* No match.  Note unknown keyword, check for :allow-other-keys   */
2998        __(addl $1,rcontext(tcr.unboxed1))
2999        __(cmpl $nrs.kallowotherkeys,%temp0)
3000        __(jne local_label(match_keys_loop))
3001        __(subl $1,rcontext(tcr.unboxed1))
3002        __(btsl $seen_aok_bit,%imm0)
3003        __(jc local_label(match_keys_loop))
3004        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
3005        __(compare_reg_to_nil(%arg_z))
3006        __(je local_label(match_keys_loop))
3007        __(btsl $aok_bit,%imm0)
3008        __(jmp local_label(match_keys_loop))
3009        /* Got a match.  Worry about :allow-other-keys here, too.   */
3010local_label(matched):
3011        __(negl %temp1)
3012        __(shll $1,%temp1)
3013        __(addl rcontext(tcr.unboxed0),%temp1)
3014        __(cmpl $nil_value,-node_size*2(%temp1))
3015        __(jne local_label(match_keys_loop))
3016        __(movl %arg_z,-node_size(%temp1))
3017        __(movl $t_value,-node_size*2(%temp1))
3018        __(cmpl $nrs.kallowotherkeys,%temp0)
3019        __(jne local_label(match_keys_loop))
3020        __(btsl $seen_aok_bit,%imm0)
3021        __(jnc local_label(match_keys_loop))
3022        __(compare_reg_to_nil(%arg_z))
3023        __(je local_label(match_keys_loop))
3024        __(btsl $aok_bit,%imm0)
3025        __(jmp local_label(match_keys_loop))
3026local_label(matched_keys):     
3027        __(cmpl $0,rcontext(tcr.unboxed1))      /* any unknown keys seen? */
3028        __(je local_label(keys_ok))
3029        __(btl $aok_bit,%imm0)
3030        __(jnc local_label(badkeys))
3031local_label(keys_ok):
3032        __(addl $(3*node_size),%esp)
3033        __(pop %ra0)
3034        __(movss %fpzero,rcontext(tcr.save0))
3035        __(jmp *%ra0)
3036        /* Some unrecognized keywords.  Complain generically about   */
3037        /* invalid keywords.   */
3038local_label(badkeys):
3039        __(movl $XBADKEYS,%arg_y)
3040        __(jmp local_label(destructure_error))
3041local_label(toomany):
3042        __(movl $XCALLTOOMANY,%arg_y)
3043        __(jmp local_label(destructure_error))
3044local_label(toofew):
3045        __(movl $XCALLTOOFEW,%arg_y)
3046        __(jmp local_label(destructure_error))
3047local_label(badlist):
3048        __(movl $XCALLNOMATCH,%arg_y)
3049local_label(destructure_error):
3050        __(movd %mm0,%esp)              /* undo everything done to the stack */
3051        __(movl rcontext(tcr.save0),%arg_z)     /* %whole_reg */
3052        __(movss %fpzero,rcontext(tcr.save0))
3053        __(set_nargs(2))
3054        __(push %ra0)
3055        __(jmp _SPksignalerr)
3056_endfn(C(destbind1))
3057
3058_spentry(macro_bind)
3059        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3060        __(extract_fulltag(%arg_reg,%imm0))
3061        __(cmpb $fulltag_cons,%imm0_b)
3062        __(jne 1f)
3063        __(_cdr(%arg_reg,%arg_reg))
3064        __(jmp C(destbind1))
30651:      __(movl $XCALLNOMATCH,%arg_y)
3066        __(movl rcontext(tcr.save0),%arg_z)
3067        __(movss %fpzero,rcontext(tcr.save0))
3068        __(set_nargs(2))
3069        __(push %ra0)       
3070        __(jmp _SPksignalerr)
3071
3072_endsubp(macro_bind)
3073
3074_spentry(destructuring_bind)
3075        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3076        __(jmp C(destbind1))
3077_endsubp(destructuring_bind)
3078
3079_spentry(destructuring_bind_inner)
3080        __(movl %arg_z,rcontext(tcr.save0))     /* %whole_reg */
3081        __(jmp C(destbind1))
3082_endsubp(destructuring_bind_inner)
3083
3084_spentry(vpopargregs)
3085        __(int $3)
3086_endsubp(vpopargregs)
3087
3088/* If arg_z is an integer, return in imm0 something whose sign  */
3089/* is the same as arg_z's.  If not an integer, error.   */
3090_spentry(integer_sign)
3091        __(mov %arg_z,%imm0)
3092        __(testb $tagmask,%arg_z_b)
3093        __(je 8f)
3094        __(extract_typecode(%arg_z,%imm0))
3095        __(cmpb $subtag_bignum,%imm0_b)
3096        __(jne 9f)
3097        __(getvheader(%arg_z,%imm0))
3098        __(shr $num_subtag_bits,%imm0)
3099        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
31008:      __(repret)
31019:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3102_endsubp(integer_sign)
3103
3104/* "slide" nargs worth of values up the stack.  imm0 contains */
3105/* the difference between the current stack pointer and the target. */
3106_spentry(mvslide)
3107        __(movd %nargs,%mm0)
3108        __(lea (%esp,%nargs),%arg_y)
3109        __(lea (%arg_y,%imm0),%imm0)
3110        __(test %nargs,%nargs)
3111        __(je 2f)
31121:
3113        __(subl $node_size,%arg_y)
3114        __(movl (%arg_y),%arg_z)
3115        __(subl $node_size,%imm0)
3116        __(movl %arg_z,(%imm0))
3117        __(subl $node_size,%nargs)
3118        __(jne 1b)
31192:      __(movl %imm0,%esp)
3120        __(movd %mm0,%nargs)
3121        __(jmp *%ra0)
3122_endsubp(mvslide)
3123
3124_spentry(save_values)
3125        __(movd rcontext(tcr.save_tsp),%mm1)
3126/* common exit: nargs = values in this set, mm1 = ptr to tsp before call to save_values   */
3127local_label(save_values_to_tsp):
3128        __(movl %ra0,rcontext(tcr.save0))
3129        __(movl rcontext(tcr.save_tsp),%temp0)
3130        __(dnode_align(%nargs,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3131        __(TSP_Alloc_Var(%imm0,%arg_z))
3132        __(movl rcontext(tcr.save_tsp),%imm0)
3133        __(movd %mm1,(%imm0))
3134        __(movl %nargs,(%arg_z))
3135        __(movl %temp0,node_size(%arg_z))
3136        __(leal 2*node_size(%arg_z,%nargs),%arg_y)
3137        __(leal (%esp,%nargs),%imm0)
3138        __(cmpl %imm0,%esp)
3139        __(jmp 2f)
31401:      __(subl $node_size,%imm0)
3141        __(movl (%imm0),%arg_z)
3142        __(subl $node_size,%arg_y)
3143        __(cmpl %imm0,%esp)
3144        __(movl %arg_z,(%arg_y))
31452:      __(jne 1b)
3146        __(addl %nargs,%esp)
3147        __(movl rcontext(tcr.save0),%ra0)
3148        __(movl $0,rcontext(tcr.save0))
3149        __(jmp *%ra0)
3150_endsubp(save_values)
3151
3152/* Add the multiple values that are on top of the vstack to the set  */
3153/* saved in the top tsp frame, popping them off of the vstack in the  */
3154/* process.  It is an error (a bad one) if the TSP contains something  */
3155/* other than a previously saved set of multiple-values.  */
3156/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3157/* each add_values call adds another linked element to the list of  */
3158/* values. This makes recover_values harder.   */
3159_spentry(add_values)
3160        /* do we need to preserve imm0? */
3161        __(test %nargs,%nargs)
3162        __(movl rcontext(tcr.save_tsp),%imm0)
3163        __(movl (%imm0),%imm0)
3164        __(movd %imm0,%mm1)     /* for the benefit of save_values_to_tsp */
3165        __(jne local_label(save_values_to_tsp))
3166        __(jmp *%ra0)
3167_endsubp(add_values)
3168
3169/* push the values in the value set atop the sp, incrementing nargs.  */
3170/* Discard the tsp frame; leave values atop the sp.   */
3171_spentry(recover_values)
3172        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3173        __(movd %nargs,%mm0)              /* temp1 */
3174        /* First, walk the segments reversing the pointer to previous  */
3175        /* segment pointers Can tell the end because that previous  */
3176        /* segment pointer is the prev tsp pointer   */
3177        __(movl rcontext(tcr.save_tsp),%temp1)
3178        __(movl %temp1,%temp0)  /* current segment   */
3179        __(movl %temp1,%arg_y)  /* last segment   */
3180        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3181local_label(walkloop):
3182        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3183        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3184        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3185        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3186        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3187        __(jne local_label(walkloop))
3188
3189        __(movl %temp1,%arg_z)
3190        __(movd %mm0,%nargs)
3191        /* the final segment pointer is now in %arg_y  */
3192        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3193local_label(pushloop):
3194        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3195        __(test %imm0,%imm0)
3196        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3197        __(leal (%nargs,%imm0),%nargs)
3198        __(jmp 2f)
31991:      __(push -node_size(%temp0))
3200        __(subl $node_size,%temp0)
3201        __(subl $fixnum_one,%imm0)
32022:      __(jne 1b)
3203        __(cmpl %arg_y,%arg_z)
3204        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3205        __(jne local_label(pushloop))
3206        __(movl (%arg_z),%arg_z)
3207        __(movl %arg_z,rcontext(tcr.save_tsp))
3208        __(movl %arg_z,rcontext(tcr.next_tsp))
3209        __(movl rcontext(tcr.save0),%ra0)
3210        __(movl $0,rcontext(tcr.save0))
3211        __(jmp *%ra0)           
3212_endsubp(recover_values)
3213
3214/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3215/* frame if any values (which will be used as outgoing arguments) will  */
3216/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3217/* that no other arguments have been pushed) on entry.   */
3218
3219_spentry(recover_values_for_mvcall)
3220        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3221        /* First, walk the segments reversing the pointer to previous  */
3222        /* segment pointers Can tell the end because that previous  */
3223        /* segment pointer is the prev tsp pointer   */
3224        __(xorl %nargs,%nargs)
3225        __(push %nargs)
3226        __(movl rcontext(tcr.save_tsp),%temp1)
3227        __(movl %temp1,%temp0)  /* current segment   */
3228        __(movl %temp1,%arg_y)  /* last segment   */
3229        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3230local_label(walkloop_mvcall):
3231        __(movl tsp_frame.data_offset(%temp0),%imm0)
3232        __(addl %imm0,(%esp))
3233        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3234        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3235        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3236        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3237        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3238        __(jne local_label(walkloop_mvcall))
3239
3240        __(movl %temp1,%arg_z)
3241        __(pop %nargs)
3242
3243        __(cmpl $nargregs*node_size,%nargs)
3244        __(jbe local_label(pushloop_mvcall))
3245        __(push $reserved_frame_marker)
3246        __(push $reserved_frame_marker)
3247
3248        /* the final segment pointer is now in %arg_y  */
3249        /* walk backwards, pushing values on the stack and incrementing %nargs*/
3250local_label(pushloop_mvcall):
3251        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment */
3252        __(test %imm0,%imm0)
3253        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3254        __(jmp 2f)
32551:      __(push -node_size(%temp0))
3256        __(subl $node_size,%temp0)
3257        __(subl $fixnum_one,%imm0)
32582:      __(jne 1b)
3259        __(cmpl %arg_y,%arg_z)
3260        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3261        __(jne local_label(pushloop_mvcall))
3262        __(movl (%arg_z),%arg_z)
3263        __(movl %arg_z,rcontext(tcr.save_tsp))
3264        __(movl %arg_z,rcontext(tcr.next_tsp))
3265        __(movl rcontext(tcr.save0),%ra0)
3266        __(movl $0,rcontext(tcr.save0))
3267        __(jmp *%ra0)           
3268_endsubp(recover_values_for_mvcall)
3269
3270_spentry(reset)
3271        __(int $3)
3272_endsubp(reset)
3273
3274/* temp0 = element-count, arg_y = subtag, arg_z = initval */
3275_spentry(misc_alloc_init)
3276        __(push %ebp)
3277        __(movl %esp,%ebp)
3278        __(push %arg_z)
3279        __(movl %arg_y,%arg_z)
3280        __(movl %temp0,%arg_y)
3281        __(push $local_label(misc_alloc_init_back))
3282        __(jmp _SPmisc_alloc)
3283__(tra(local_label(misc_alloc_init_back)))
3284        __(pop %arg_y)
3285        __(leave)
3286        __(movl $nrs.init_misc,%fname)
3287        __(set_nargs(2))
3288        __(jump_fname())
3289_endsubp(misc_alloc_init)
3290
3291_spentry(stack_misc_alloc_init)
3292        __(int $3)
3293_endsubp(stack_misc_alloc_init)
3294
3295        .globl C(popj)
3296_spentry(popj)
3297C(popj):
3298        __(leave)
3299        __(ret)
3300_endsubp(popj)
3301
3302/* arg_z should be of type (signed-byte 64) */
3303/* return unboxed value in mm0 */
3304_spentry(gets64)
3305        __(testb $fixnummask,%arg_z_b)
3306        __(jne 1f)
3307        __(unbox_fixnum(%arg_z,%imm0))
3308        __(movd %imm0,%mm0)
3309        __(jns 8f)
3310        /* get sign into upper half of %mm0 */
3311        __(pcmpeqd %mm1,%mm1)   /* all ones */
3312        __(psllq $32,%mm1)
3313        __(por %mm1,%mm0)
3314        __(ret)
33151:      __(movb %arg_z_b,%imm0_b)
3316        __(andb $tagmask,%imm0_b)
3317        __(cmpb $tag_misc,%imm0_b)
3318        __(jne 9f)
3319        __(movl misc_header_offset(%arg_z),%imm0)
3320        __(cmpb $subtag_bignum,%imm0_b)
3321        __(jne 9f)
3322        __(cmpl $two_digit_bignum_header,%imm0)
3323        __(ja 9f)
3324        __(movd misc_data_offset(%arg_z),%mm0)
3325        __(jne 8f)
3326        __(movq misc_data_offset(%arg_z),%mm0)
33278:      __(repret)
33289:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_s64))
3329_endsubp(gets64)
3330
3331/* arg_z should be of type (unsigned-byte 64) */
3332/* return unboxed value in mm0 */
3333_spentry(getu64)
3334        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3335        __(testl %arg_z,%imm0)
3336        __(movl %arg_z,%imm0)
3337        __(jne 1f)
3338        __(sarl $fixnumshift,%imm0)
3339        __(movd %imm0,%mm0)
3340        __(ret)
33411:      __(andb $tagmask,%imm0_b)
3342        __(cmpb $tag_misc,%imm0_b)
3343        __(jne 9f)
3344        __(movl misc_header_offset(%arg_z),%imm0)
3345        __(cmpb $subtag_bignum,%imm0_b)
3346        __(jne 9f)
3347        __(cmpl $three_digit_bignum_header,%imm0)
3348        __(ja 9f)
3349        __(je 3f)
3350        __(cmpl $two_digit_bignum_header,%imm0)
3351        __(je 2f)
3352        /* must be a one digit bignum */
3353        __(movl misc_data_offset(%arg_z),%imm0)
3354        __(test %imm0,%imm0)
3355        __(js 9f)
3356        __(movd %imm0,%mm0)
3357        __(ret)
33582:      __(movl misc_data_offset+4(%arg_z),%imm0)
3359        __(testl %imm0,%imm0)
3360        __(js 9f)
3361        __(movq misc_data_offset(%arg_z),%mm0)
3362        __(ret)
33633:      __(movl misc_data_offset(%arg_z),%imm0)
3364        __(cmpl $0,misc_data_offset+8(%arg_z))
3365        __(jne 9f)
3366        __(movq misc_data_offset(%arg_z),%mm0)
3367        __(repret)
33689:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3369_endsubp(getu64)
3370
3371/* Make unsigned integer from value in mm0 */
3372_spentry(makeu64)
3373        __(movq %mm0,%mm1)
3374        __(psrlq $32,%mm0)
3375        __(movd %mm0,%imm0)
3376        __(test %imm0,%imm0)
3377        __(js 3f)
3378        __(jnz 2f)
3379        __(movd %mm1,%imm0)
3380        __(cmpl $target_most_positive_fixnum,%imm0)
3381        __(ja 1f)
3382        __(box_fixnum(%imm0,%arg_z))
3383        __(ret)
33841:      /* maybe make a 1 digit bignum */
3385        __(test %imm0,%imm0)
3386        __(js 2f)
3387        __(movl $one_digit_bignum_header,%imm0)
3388        __(movd %imm0,%mm0)
3389        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3390        __(movd %mm1,misc_data_offset(%arg_z))
3391        __(ret)
3392        /* make a 2 digit bignum */
33932:      __(movl $two_digit_bignum_header,%imm0)
3394        __(movd %imm0,%mm0)
3395        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3396        __(movq %mm1,misc_data_offset(%arg_z))
3397        __(ret)
3398        /* make a 3 digit bignum */
33993:      __(movl $three_digit_bignum_header,%imm0)
3400        __(movd %imm0,%mm0)
3401        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
3402        __(movq %mm1,misc_data_offset(%arg_z))
3403        __(ret)
3404_endsubp(makeu64)
3405
3406/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
3407/* unbound_marker), arg_y = symbol */
3408_spentry(specref)
3409        __(movl symbol.binding_index(%arg_z),%imm0)
3410        __(cmp rcontext(tcr.tlb_limit),%imm0)
3411        __(movl rcontext(tcr.tlb_pointer),%temp1)
3412        __(movl %arg_z,%arg_y)
3413        __(jae 7f)
3414        __(movl (%temp1,%imm0),%arg_z)
3415        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3416        __(jne 8f)
34177:      __(movl symbol.vcell(%arg_y),%arg_z)
34188:      __(repret)             
3419_endsubp(specref)
3420
3421/* arg_y = special symbol, arg_z = new value. */
3422_spentry(specset)
3423        __(movl symbol.binding_index(%arg_y),%imm0)
3424        __(cmp rcontext(tcr.tlb_limit),%imm0)
3425        __(movl rcontext(tcr.tlb_pointer),%temp1)
3426        __(jae 1f)
3427        __(movl (%temp1,%imm0),%temp0)
3428        __(cmpb $no_thread_local_binding_marker,%temp0_b)
3429        __(je 1f)
3430        __(movl %arg_z,(%temp1,%imm0))
3431        __(ret)
34321:      __(movl %arg_y,%temp0)
3433        __(movl $1<<fixnumshift,%arg_y)
3434        __(jmp _SPgvset)
3435_endsubp(specset)
3436
3437_spentry(specrefcheck)
3438        __(mov %arg_z,%arg_y)
3439        __(movl symbol.binding_index(%arg_z),%imm0)
3440        __(cmp rcontext(tcr.tlb_limit),%imm0)
3441        __(jae 7f)
3442        __(movl rcontext(tcr.tlb_pointer),%temp1)
3443        __(movl (%temp1,%imm0),%arg_z)
3444        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3445        __(jne 8f)
34467:      __(movl symbol.vcell(%arg_y),%arg_z)
34478:      __(cmpb $unbound_marker,%arg_z_b)
3448        __(jne 9f)
3449        __(uuo_error_reg_unbound(Rarg_y))
34509:      __(repret)
3451_endsubp(specrefcheck)
3452
3453_spentry(restoreintlevel)
3454        __(int $3)
3455_endsubp(restoreintlevel)
3456
3457/* Make a lisp integer from the unsigned value in imm0 */
3458_spentry(makeu32)
3459        __(cmpl $target_most_positive_fixnum,%imm0)
3460        __(ja 0f)       /* need to make a bignum */
3461        __(box_fixnum(%imm0,%arg_z))
3462        __(ret)
34630:      __(movd %imm0,%mm1)
3464        __(test %imm0,%imm0)
3465        __(js 1f)
3466        __(movl $one_digit_bignum_header,%imm0)
3467        __(movd %imm0,%mm0)
3468        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3469        __(movd %mm1,misc_data_offset(%arg_z))
3470        __(ret)
34711:      __(movl $two_digit_bignum_header,%imm0)
3472        __(movd %imm0,%mm0)
3473        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3474        __(movd %mm1,misc_data_offset(%arg_z))
3475        __(ret)
3476_endsubp(makeu32)
3477
3478/* arg_z is of type (signed-byte 32) */
3479/* return unboxed value in %imm0 */
3480_spentry(gets32)
3481        __(testb $fixnummask,%arg_z_b)
3482        __(jne 1f)
3483        __(unbox_fixnum(%arg_z,%imm0))
3484        __(ret)
34851:      __(movb %arg_z_b,%imm0_b)
3486        __(andb $tagmask,%imm0_b)
3487        __(cmpb $tag_misc,%imm0_b)
3488        __(jne 9f)
3489        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3490        __(cmpb $subtag_bignum,%imm0_b)
3491        __(jne 9f)
3492        __(movl misc_header_offset(%arg_z),%imm0)
3493        __(cmpl $one_digit_bignum_header,%imm0)
3494        __(jne 9f)
3495        __(movl misc_data_offset(%arg_z),%imm0)
3496        __(ret)
34979:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_signed_byte_32))
3498_endsubp(gets32)
3499
3500/* arg_z is of type (unsigned-byte 32) */
3501/* return unboxed value in %imm0 */
3502_spentry(getu32)
3503        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3504        __(testl %arg_z,%imm0)
3505        __(movl %arg_z,%imm0)
3506        __(jne 1f)
3507        __(sarl $fixnumshift,%imm0)
3508        __(ret)
35091:      __(andb $tagmask,%imm0_b)
3510        __(cmpb $tag_misc,%imm0_b)
3511        __(jne 9f)
3512        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3513        __(cmpb $subtag_bignum,%imm0_b)
3514        __(jne 9f)
3515        __(movl misc_header_offset(%arg_z),%imm0)
3516        __(cmpl $two_digit_bignum_header,%imm0)
3517        __(je 2f)
3518        __(cmpl $one_digit_bignum_header,%imm0)
3519        __(jne 9f)
3520        __(movl misc_data_offset(%arg_z),%imm0)
3521        __(ret)
35222:      __(movl misc_data_offset(%arg_z),%imm0)
3523        __(cmpl $0,misc_data_offset+4(%arg_z))
3524        __(jne 9f)
3525        __(ret)
35269:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_unsigned_byte_32))
3527_endsubp(getu32)
3528
3529_spentry(mvpasssym)
3530        __(int $3)
3531_endsubp(mvpasssym)
3532
3533/* don't smash arg_z */
3534_spentry(unbind)
3535        __(push %arg_z)
3536        __(movl rcontext(tcr.db_link),%imm0)
3537        __(movl rcontext(tcr.tlb_pointer),%arg_z)
3538        __(movl binding.sym(%imm0),%temp0)
3539        __(movl binding.val(%imm0),%arg_y)
3540        __(movl binding.link(%imm0),%imm0)
3541        __(movl %arg_y,(%arg_z,%temp0))
3542        __(movl %imm0,rcontext(tcr.db_link))
3543        __(pop %arg_z)
3544        __(ret)
3545_endsubp(unbind)
3546
3547_spentry(unbind_n)
3548        __(push %temp1)         /* preserve temp1/nargs */
3549        __(push %arg_z)
3550        __(xorl %arg_z,%arg_z)
3551        __(movl rcontext(tcr.db_link),%temp1)
3552        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35531:             
3554        __(movl binding.sym(%temp1),%temp0)
3555        __(movl binding.val(%temp1),%arg_y)
3556        __(movl binding.link(%temp1),%temp1)
3557        __(movl %arg_y,(%arg_z,%temp0))
3558        __(decl %imm0)
3559        __(jne 1b)
3560        __(movl %temp1,rcontext(tcr.db_link))
3561        __(pop %arg_z)
3562        __(pop %temp1)
3563        __(ret) 
3564_endsubp(unbind_n)
3565
3566_spentry(unbind_to)
3567        __(push %arg_y)
3568        __(push %arg_z)
3569        __(push %temp0)
3570        __(push %temp1)
3571       
3572        __(movl rcontext(tcr.db_link),%temp0)
3573        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35741:
3575        __(movl binding.sym(%temp0),%temp1)
3576        __(movl binding.val(%temp0),%arg_y)
3577        __(movl binding.link(%temp0),%temp0)
3578        __(movl %arg_y,(%arg_z,%temp1))
3579        __(cmpl %temp0,%imm0)
3580        __(jne 1b)
3581        __(movl %temp0,rcontext(tcr.db_link))
3582
3583        __(pop %temp1)
3584        __(pop %temp0)
3585        __(pop %arg_z)
3586        __(pop %arg_y)
3587        __(ret)
3588_endsubp(unbind_to)
3589
3590_spentry(bind_interrupt_level_0)
3591        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3592        __(cmpl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3593        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3594        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3595        __(push rcontext(tcr.db_link))
3596        __(movl %esp,rcontext(tcr.db_link))
3597        __(movl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3598        __(js 1f)
35990:      __(jmp *%ra0)
3600        /* Interrupt level was negative; interrupt may be pending */
36011:      __(check_pending_enabled_interrupt(2f))
36022:      __(jmp *%ra0)
3603_endsubp(bind_interrupt_level_0)
3604
3605/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3606/* of disabling interrupts.)   */
3607_spentry(bind_interrupt_level_m1)
3608        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3609        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3610        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3611        __(push rcontext(tcr.db_link))
3612        __(movl %esp,rcontext(tcr.db_link))
3613        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3614        __(jmp *%ra0)
3615_endsubp(bind_interrupt_level_m1)
3616
3617/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
3618/* do what _SPbind_interrupt_level_0 does. */
3619_spentry(bind_interrupt_level)
3620        __(test %arg_z,%arg_z)
3621        __(jz _SPbind_interrupt_level_0)
3622        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3623        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3624        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3625        __(push rcontext(tcr.db_link))
3626        __(movl %esp,rcontext(tcr.db_link))
3627        __(movl %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3628        __(jmp *%ra0)
3629_endsubp(bind_interrupt_level)
3630
3631/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
3632/* non-negative, check for pending interrupts. */
3633_spentry(unbind_interrupt_level)
3634        __(btl $TCR_FLAG_BIT_PENDING_SUSPEND,rcontext(tcr.flags))
3635        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3636        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
3637        __(jc 5f)
36380:      __(test %imm0,%imm0)
3639        __(movl rcontext(tcr.db_link),%imm0)
3640        __(movl binding.val(%imm0),%temp0)
3641        __(movl binding.link(%imm0),%imm0)
3642        __(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3643        __(movl %imm0,rcontext(tcr.db_link))
3644        __(js 3f)
36452:      __(repret)
36463:      __(test %temp0,%temp0)
3647        __(js 2b)
3648        __(check_pending_enabled_interrupt(4f))
36494:      __(repret)
36505:       /* Missed a suspend request; force suspend now if we're restoring
3651          interrupt level to -1 or greater */
3652        __(cmpl $-2<<fixnumshift,%imm0)
3653        __(jne 0b)
3654        __(movl rcontext(tcr.db_link),%temp0)
3655        __(movl binding.val(%temp0),%temp0)
3656        __(cmpl %imm0,%temp0)
3657        __(je 0b)
3658        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3659        __(suspend_now())
3660        __(jmp 0b)
3661_endsubp(unbind_interrupt_level)
3662
3663_spentry(progvrestore)
3664        __(movl rcontext(tcr.save_tsp),%imm0)
3665        __(movl tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3666        __(movl tsp_frame.data_offset(%imm0),%imm0)
3667        __(shrl $fixnumshift,%imm0)
3668        __(jne _SPunbind_n)
3669        __(repret)
3670_endsubp(progvrestore)
3671
3672/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3673/* inline.  Call out otherwise.   */
3674_spentry(builtin_plus)
3675        __(movl %arg_y,%imm0)
3676        __(orl %arg_z,%imm0)
3677        __(testb $fixnummask,%imm0_b)
3678        __(jne 1f)
3679        __(addl %arg_y,%arg_z)
3680        __(jo C(fix_one_bit_overflow))
3681        __(repret)
36821:      __(jump_builtin(_builtin_plus,2))
3683_endsubp(builtin_plus)
3684
3685/* %arg_z <- %arg_y - %arg_z.  Do the fixnum case - including overflow -  */
3686/*  inline.  Call out otherwise.   */
3687_spentry(builtin_minus)
3688        __(movl %arg_y,%imm0)
3689        __(orl %arg_z,%imm0)
3690        __(testb $fixnummask,%imm0_b)
3691        __(jne 1f)
3692        __(xchgl %arg_y,%arg_z)
3693        __(subl %arg_y,%arg_z)
3694        __(jo C(fix_one_bit_overflow))
3695        __(repret)
36961:      __(jump_builtin(_builtin_minus,2))
3697_endsubp(builtin_minus)
3698
3699/* %arg_z -< arg_y * arg_z. */
3700/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
3701_spentry(builtin_times)
3702        __(movl %arg_y,%imm0)
3703        __(orb %arg_z_b,%imm0_b)
3704        __(testb $fixnummask,%imm0_b)
3705        __(jne 2f)
3706        __(unbox_fixnum(%arg_z,%imm0))
3707        /* 32-bit fixnum result in %imm0.  Overflow set if it doesn't fit. */
3708        __(imul %arg_y,%imm0)
3709        __(jo 1f)
3710        __(movl %imm0,%arg_z)
3711        __(ret)
37121:      __(unbox_fixnum(%arg_z,%eax))
3713        __(mark_as_imm(%edx))
3714        __(unbox_fixnum(%arg_y,%edx))
3715        __(imul %edx)
3716        __(movd %eax,%mm0)
3717        __(movd %edx,%mm1)
3718        __(mark_as_node(%edx))
3719        __(psllq $32,%mm1)
3720        __(por %mm1,%mm0)
3721        __(jmp _SPmakes64)
37222:      __(jump_builtin(_builtin_times,2))
3723_endsubp(builtin_times)
3724
3725_spentry(builtin_div)
3726        __(jump_builtin(_builtin_div,2))
3727
3728/* %arg_z <- (= %arg_y %arg_z).   */
3729_spentry(builtin_eq)
3730        __(movl %arg_y,%imm0)
3731        __(orb %arg_z_b,%imm0_b)
3732        __(testb $fixnummask,%imm0_b)
3733        __(jne 1f)
3734        __(rcmpl(%arg_z,%arg_y))
3735        __(condition_to_boolean(e,%imm0,%arg_z))
3736        __(ret)
37371:      __(jump_builtin(_builtin_eq,2))
3738_endsubp(builtin_eq)
3739
3740/* %arg_z <- (/= %arg_y %arg_z).          */
3741_spentry(builtin_ne)
3742        __(movl %arg_y,%imm0)
3743        __(orb %arg_z_b,%imm0_b)
3744        __(testb $fixnummask,%imm0_b)
3745        __(jne 1f)
3746        __(rcmpl(%arg_z,%arg_y))
3747        __(condition_to_boolean(ne,%imm0,%arg_z))
3748        __(ret)
37491:      __(jump_builtin(_builtin_ne,2))
3750_endsubp(builtin_ne)
3751
3752/* %arg_z <- (> %arg_y %arg_z).   */
3753_spentry(builtin_gt)
3754        __(movl %arg_y,%imm0)
3755        __(orb %arg_z_b,%imm0_b)
3756        __(testb $fixnummask,%imm0_b)
3757        __(jne 1f)
3758        __(rcmpl(%arg_y,%arg_z))
3759        __(condition_to_boolean(g,%imm0,%arg_z))
3760        __(ret)
37611:      __(jump_builtin(_builtin_gt,2))
3762_endsubp(builtin_gt)
3763
3764/* %arg_z <- (>= %arg_y %arg_z).          */
3765_spentry(builtin_ge)
3766        __(movl %arg_y,%imm0)
3767        __(orb %arg_z_b,%imm0_b)
3768        __(testb $fixnummask,%imm0_b)
3769        __(jne 1f)
3770        __(rcmpl(%arg_y,%arg_z))
3771        __(condition_to_boolean(ge,%imm0,%arg_z))
3772        __(ret)
37731:      __(jump_builtin(_builtin_ge,2))
3774_endsubp(builtin_ge)
3775
3776/* %arg_z <- (< %arg_y %arg_z).   */
3777_spentry(builtin_lt)
3778        __(movl %arg_y,%imm0)
3779        __(orb %arg_z_b,%imm0_b)
3780        __(testb $fixnummask,%imm0_b)
3781        __(jne 1f)
3782        __(rcmpl(%arg_y,%arg_z))
3783        __(condition_to_boolean(l,%imm0,%arg_z))
3784        __(ret)
37851:      __(jump_builtin(_builtin_lt,2))
3786_endsubp(builtin_lt)
3787
3788/* %arg_z <- (<= %arg_y %arg_z).   */
3789_spentry(builtin_le)
3790        __(movl %arg_y,%imm0)
3791        __(orb %arg_z_b,%imm0_b)
3792        __(testb $fixnummask,%imm0_b)
3793        __(jne 1f)
3794        __(rcmpl(%arg_y,%arg_z))
3795        __(condition_to_boolean(le,%imm0,%arg_z))
3796        __(ret)
37971:      __(jump_builtin(_builtin_le,2))
3798_endsubp(builtin_le)
3799
3800_spentry(builtin_eql)
3801        __(cmpl %arg_y,%arg_z)
3802        __(je 1f)
3803        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3804        /* and both have the same subtag. */
3805        __(movl %arg_y,%imm0)
3806        __(andb $tagmask,%imm0_b)
3807        __(cmpb $tag_misc,%imm0_b)
3808        __(jne 2f)
3809        __(movb %arg_z_b,%imm0_bh)
3810        __(andb $tagmask,%imm0_bh)
3811        __(cmpb %imm0_bh,%imm0_b)
3812        __(jne 2f)
3813        __(extract_subtag(%arg_y,%imm0_b))
3814        __(extract_subtag(%arg_z,%imm0_bh))
3815        __(cmpb %imm0_b,%imm0_bh)
3816        __(jne 2f)
3817        __(jump_builtin(_builtin_eql,2))
38181:      __(movl $t_value,%arg_z)
3819        __(ret)
38202:      __(movl $nil_value,%arg_z)
3821        __(ret)
3822_endsubp(builtin_eql)
3823
3824_spentry(builtin_length)
3825        __(extract_fulltag(%arg_z,%imm0))
3826        __(cmpl $tag_list,%imm0)
3827        __(jz 2f)
3828        __(andl $tagmask,%imm0)
3829        __(cmpl $tag_misc,%imm0)
3830        __(jnz 8f)
3831        __(extract_subtag(%arg_z,%imm0_b))
3832        __(rcmpb(%imm0_b,$min_vector_subtag))
3833        __(jb 8f)
3834        __(je 1f)
3835        /* (simple-array * (*)) */
3836        __(movl %arg_z,%arg_y)
3837        __(vector_length(%arg_y,%arg_z))
3838        __(ret)
38391:      /* vector header */
3840        __(movl vectorH.logsize(%arg_z),%arg_z)
3841        __(ret)
38422:      /* list.  Maybe null, maybe dotted or circular. */
3843        __(movl $-fixnumone,%arg_y)
3844        __(movl %arg_z,%temp0)  /* fast pointer */
3845        __(movl %arg_z,%temp1)  /* slow pointer */
38463:      __(movb %temp0_b,%al)
3847        __(andb $fulltagmask,%al)
3848        __(addl $fixnumone,%arg_y)
3849        __(compare_reg_to_nil(%temp0))
3850        __(je 9f)
3851        __(cmpb $fulltag_cons,%al)
3852        __(jne 8f)
3853        __(movb %temp1_b,%ah)
3854        __(andb $fulltagmask,%ah)
3855        __(_cdr(%temp0,%temp0))
3856        __(testl $fixnumone,%arg_y)
3857        __(je 3b)
3858        __(cmpb $fulltag_cons,%ah)
3859        __(jne 8f)
3860        __(_cdr(%temp1,%temp1))
3861        __(cmpl %temp0,%temp1)
3862        __(jne 3b)
38638:
3864        __(jump_builtin(_builtin_length,1))
38659:
3866        __(movl %arg_y,%arg_z)
3867        __(ret)
3868_endsubp(builtin_length)
3869
3870_spentry(builtin_seqtype)
3871        __(extract_fulltag(%arg_z,%imm0))
3872        __(cmpb $fulltag_cons,%imm0_b)
3873        __(jz 1f)
3874        __(cmpb $tag_misc,%imm0_b)
3875        __(jne 2f)
3876        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3877        __(rcmpb(%imm0_b,$min_vector_subtag))
3878        __(jb 2f)
3879        __(movl $nil_value,%arg_z)
3880        __(ret)
38811:      __(movl $t_value,%arg_z)
3882        __(ret)
38832:
3884        __(jump_builtin(_builtin_seqtype,1))
3885_endsubp(builtin_seqtype)
3886
3887_spentry(builtin_assq)
3888        __(cmpl $nil_value,%arg_z)
3889        __(je 5f)
38901:      __(movl %arg_z,%imm0)
3891        __(andb $fulltagmask,%imm0_b)
3892        __(cmpb $fulltag_cons,%imm0_b)
3893        __(je 2f)
3894        __(uuo_error_reg_not_list(Rarg_z))
38952:      __(_car(%arg_z,%temp0))
3896        __(_cdr(%arg_z,%arg_z))
3897        __(cmpl $nil_value,%temp0)
3898        __(je 4f)
3899        __(movl %temp0,%imm0)
3900        __(andb $fulltagmask,%imm0_b)
3901        __(cmpb $fulltag_cons,%imm0_b)
3902        __(je 3f)
3903        __(uuo_error_reg_not_list(Rtemp0))
39043:      __(_car(%temp0,%temp1))
3905        __(cmpl %temp1,%arg_y)
3906        __(jne 4f)
3907        __(movl %temp0,%arg_z)
3908        __(ret)
39094:      __(cmpl $nil_value,%arg_z)
39105:      __(jnz 1b)
3911        __(repret)
3912_endsubp(builtin_assq)
3913
3914_spentry(builtin_memq)
3915        __(cmpl $nil_value,%arg_z)
3916        __(jmp 3f)
39171:      __(movb $fulltagmask,%imm0_b)
3918        __(andb %arg_z_b,%imm0_b)
3919        __(cmpb $fulltag_cons,%imm0_b)
3920        __(jz 2f)
3921        __(uuo_error_reg_not_list(Rarg_z))
39222:      __(_car(%arg_z,%temp1))
3923        __(_cdr(%arg_z,%temp0))
3924        __(cmpl %temp1,%arg_y)
3925        __(jz 4f)
3926        __(cmpl $nil_value,%temp0)
3927        __(movl %temp0,%arg_z)
39283:      __(jnz 1b)
39294:      __(repret)
3930_endsubp(builtin_memq)
3931
3932logbitp_max_bit = 30
3933
3934_spentry(builtin_logbitp)
3935        /* Call out unless: both args fixnums, arg_y in [0, logbitp_max_bit) */
3936        __(movl %arg_z,%imm0)
3937        __(orl %arg_y,%imm0)
3938        __(testb $fixnummask,%imm0_b)
3939        __(jnz 1f)
3940        __(unbox_fixnum(%arg_y,%imm0))
3941        __(js 1f)       /* bit number negative */
3942        __(addb $fixnumshift,%imm0_b)
3943        __(cmpl $logbitp_max_bit<<fixnumshift,%arg_y)
3944        __(jb 2f)
3945        __(movl $logbitp_max_bit-1+fixnumshift,%imm0)
39462:      __(bt %imm0,%arg_z)
3947        __(condition_to_boolean(b,%imm0,%arg_z))
3948        __(ret)
39491:      __(jump_builtin(_builtin_logbitp,2))
3950_endsubp(builtin_logbitp)
3951
3952_spentry(builtin_logior)
3953        __(movl %arg_y,%imm0)
3954        __(orb %arg_z_b,%imm0_b)
3955        __(testb $fixnummask,%imm0_b)
3956        __(jne 1f)
3957        __(orl %arg_y,%arg_z)
3958        __(ret)
39591:
3960        __(jump_builtin(_builtin_logior,2))
3961_endsubp(builtin_logior)
3962
3963_spentry(builtin_logand)
3964        __(movl %arg_y,%imm0)
3965        __(orb %arg_z_b,%imm0_b)
3966        __(testb $fixnummask,%imm0_b)
3967        __(jne 1f)
3968        __(andl %arg_y,%arg_z)
3969        __(ret)
39701:
3971        __(jump_builtin(_builtin_logand,2))
3972_endsubp(builtin_logand)
3973
3974_spentry(builtin_negate)
3975        __(testb $fixnummask,%arg_z_b)
3976        __(jne 1f)
3977        __(negl %arg_z)
3978        __(jo C(fix_one_bit_overflow))
3979        __(repret)
39801:
3981        __(jump_builtin(_builtin_negate,1))
3982_endsubp(builtin_negate)
3983
3984_spentry(builtin_logxor)
3985        __(movl %arg_y,%imm0)
3986        __(orb %arg_z_b,%imm0_b)
3987        __(testb $fixnummask,%imm0_b)
3988        __(jne 1f)
3989        __(xorl %arg_y,%arg_z)
3990        __(ret)
39911:
3992        __(jump_builtin(_builtin_logxor,2))
3993_endsubp(builtin_logxor)
3994
3995/* temp0 = vector, arg_y = index, arg_z = newval */
3996_spentry(aset1)
3997        __(extract_typecode(%temp0,%imm0))
3998        __(box_fixnum(%imm0,%temp1))
3999        __(cmpb $min_vector_subtag,%imm0_b)
4000        __(ja _SPsubtag_misc_set)
4001        /* push frame... */
4002        __(pop %temp1)
4003        __(push $reserved_frame_marker)
4004        __(push $reserved_frame_marker)
4005        __(push %temp0)
4006        __(push %temp1)
4007        /* and fall through... */
4008_endsubp(aset1)
4009
4010_spentry(builtin_aset1)
4011        __(jump_builtin(_builtin_aset1,3))
4012_endsubp(builtin_aset1)
4013
4014_spentry(builtin_ash)
4015        __(movl %arg_y,%imm0)
4016        __(orb %arg_z_b,%imm0_b)
4017        __(testb $fixnummask,%imm0_b)
4018        __(jne 9f)
4019        __(unbox_fixnum(%arg_z,%imm0))
4020        /* Z flag set if zero ASH shift count */
4021        __(jnz 1f)
4022        __(movl %arg_y,%arg_z) /* shift by 0 */
4023        __(ret)
40241:      __(jns 3f)
4025        __(rcmpl(%imm0,$-31))
4026        __(jg 2f)
4027        __(unbox_fixnum(%arg_y,%imm0))
4028        __(sar $31,%imm0)
4029        __(box_fixnum(%imm0,%arg_z))
4030        __(ret)
40312:      /* Right-shift by small fixnum */
4032        __(negb %imm0_b)
4033        __(movzbl %imm0_b,%ecx)
4034        __(unbox_fixnum(%arg_y,%imm0))
4035        __(sar %cl,%imm0)
4036        __(box_fixnum(%imm0,%arg_z))
4037        __(ret)
40383:      /* Left shift by fixnum.  We can't shift by more than 31 bits, */
4039        /* though shifting by 32 is actually easy. */
4040        __(rcmpl(%imm0,$32))
4041        __(jg 9f)
4042        __(jne 4f)
4043        /* left-shift by 32 bits exactly */
4044        __(unbox_fixnum(%arg_y,%imm0))
4045        __(movd %imm0,%mm0)
4046        __(psllq $32,%mm0)
4047        __(jmp _SPmakes64)
40484:      /* left-shift by 1..31 bits. Safe to move shift count to %cl */
4049        __(movd %imm0,%mm1)     /* shift count */
4050        __(unbox_fixnum(%arg_y,%imm0))
4051        __(movd %imm0,%mm0)
4052        __(sarl $31,%imm0)      /* propagate sign */
4053        __(movd %imm0,%mm2)
4054        __(pshufw $0x4e,%mm2,%mm2) /* swap hi/lo halves */
4055        __(por %mm2,%mm0)
4056        __(psllq %mm1,%mm0)
4057        __(jmp _SPmakes64)
40589:
4059        __(jump_builtin(_builtin_ash,2))
4060_endsubp(builtin_ash)
4061
4062_spentry(builtin_aref1)
4063        __(extract_typecode(%arg_y,%imm0))
4064        __(box_fixnum_no_flags(%imm0,%temp0))
4065        __(cmpb $min_vector_subtag,%imm0_b)
4066        __(ja _SPsubtag_misc_ref)
4067        __(jump_builtin(_builtin_aref1,2))
4068_endsubp(builtin_aref1)
4069
4070/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
4071/* if so.  This might allow us to avoid having to have a priori */
4072/* knowledge of whether a foreign function returns a floating-point result. */
4073/* backlink to saved %esp, below */
4074/* arg n-1 */
4075/* arg n-2 */
4076/* ... */
4077/* arg 0 */
4078/* space for alignment */
4079/* previous %esp */
4080
4081_spentry(ffcall)
4082LocalLabelPrefix[]ffcall:
4083        __(unbox_fixnum(%arg_z,%imm0))
4084        __(testb $fixnummask,%arg_z_b)
4085        __(je 0f)
4086        __(movl macptr.address(%arg_z),%imm0)
40870:
4088        /* Save lisp registers. */
4089        __(push %ebp)
4090        __(mov %esp,%ebp)
4091        __(push %temp0)
4092        __(push %temp1)
4093        __(push %arg_y)
4094        __(push %arg_z)
4095        __(push %fn)
4096        __ifdef([WIN32_ES_HACK])
4097         __(movl rcontext(tcr.linear),%ebx)
4098        __endif
4099        __(movl %esp,rcontext(tcr.save_vsp))
4100        __(movl %ebp,rcontext(tcr.save_ebp))
4101        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4102        __(movl rcontext(tcr.foreign_sp),%esp)
4103        /* preserve state of direction flag */
4104        __(pushfl)
4105        __(popl rcontext(tcr.save_eflags))
4106        __(cld)       
4107        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4108        __(emms)
4109        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4110        __(movl (%esp),%ebp)
4111LocalLabelPrefix[]ffcall_setup:
4112        __(lea 15(%esp),%ecx)
4113        __(andl $-16,%ecx)
4114        __(movl %ecx,%esp)
4115/*      __(addl $node_size,%esp) */
4116        __ifdef([WIN32_ES_HACK])
4117         __(push %ds)
4118         __(pop %es)
4119        __endif
4120LocalLabelPrefix[]ffcall_call:
4121        __(call *%eax)
4122        __ifdef([WIN32_ES_HACK])
4123         __(movw tcr.ldt_selector(%ebx),%rcontext_reg)
4124        __endif
4125LocalLabelPrefix[]ffcall_call_end:
4126        __(movl %ebp,%esp)
4127        __(movl %esp,rcontext(tcr.foreign_sp))
4128        /* The high word of a 64-bit result would be in %edx right now.
4129           There doesn't seem to be any other good place to put this,
4130           though %edx is often undefined at this point. */
4131        __(mov %edx,rcontext(tcr.unboxed1))
4132        __(clr %arg_z)
4133        __(clr %arg_y)
4134        __(clr %temp1)
4135        __(clr %temp0)
4136        __(clr %fn)
4137        __(pxor %fpzero,%fpzero)
4138        __(cmpb $0,C(bogus_fp_exceptions))
4139        __(je 0f)
4140        __(movl %arg_z,rcontext(tcr.ffi_exception))
4141        __(jmp 1f)
41420:      __(stmxcsr rcontext(tcr.ffi_exception))
41431:      __(pushl rcontext(tcr.save_eflags))
4144        __(popfl)
4145        __(movl rcontext(tcr.save_vsp),%esp)
4146        __(movl rcontext(tcr.save_ebp),%ebp)
4147        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4148        __(pop %fn)
4149        __(pop %arg_z)
4150        __(pop %arg_y)
4151        __(pop %temp1)
4152        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4153        __(check_pending_interrupt(%temp0))
4154        __(pop %temp0)
4155        __(leave)
4156        __(ret)
4157        /* need to deal with NSExceptions and Objc-2.0 execptions */
4158_endsubp(ffcall)
4159
4160_spentry(ffcall_return_registers)
4161        __(int $3)
4162_endsubp(ffcall_return_registers)
4163
4164/* We need to reserve a frame here if (a) nothing else was already pushed
4165/* and (b) we push something (e.g., more than 2 args in the lexpr) */
4166_spentry(spread_lexprz)
4167        new_local_labels()
4168        __(movl (%arg_z),%imm0) /* lexpr count */
4169        __(leal node_size(%arg_z,%imm0),%arg_y)
4170        __(movd %arg_y,%mm1)
4171        __(test %nargs,%nargs) /* anything pushed by caller ? */
4172        __(jne 0f)              /* yes, caller has already created frame. */
4173        __(cmpl $(nargregs*node_size),%imm0) /* will we push anything ? */
4174        __(jbe 0f)
4175        __(push $reserved_frame_marker)
4176        __(push $reserved_frame_marker)
41770:      __(addl %imm0,%nargs)
4178        __(cmpl $(1*node_size),%imm0)
4179        __(ja 2f)
4180        __(je 1f)
4181        /* lexpr count was 0; vpop the args that */
4182        /* were pushed by the caller */
4183        __(test %nargs,%nargs)
4184        __(je local_label(all_args_popped))
4185        __(pop %arg_z)
4186local_label(maybe_pop_y):
4187        __(cmpl $(1*node_size),%nargs)
4188        __(je local_label(all_args_popped))
4189        __(pop %arg_y)
4190local_label(all_args_popped):   
4191        /* If all args fit in registers but some were pushed */
4192        /* by the caller, discard the reserved frame that the caller */
4193        /* pushed.         */
4194        __(cmpl %imm0,%nargs)
4195        __(je local_label(go))
4196        __(cmpl $(nargregs*node_size),%nargs)
4197        __(ja local_label(go))
4198        __(addl $(2*node_size),%esp)
4199local_label(go):
4200        __(jmp *%ra0)
4201
4202        /* lexpr count is two or more: vpush args from the lexpr until */
4203        /* we have only two left, then assign them to arg_y and arg_z */
42042:      __(cmpl $(2*node_size),%imm0)
4205        __(je local_label(push_loop_end))
4206local_label(push_loop):
4207        __(lea -1*node_size(%imm0),%imm0)
4208        __(push -node_size(%arg_y))
4209        __(lea -1*node_size(%arg_y),%arg_y)
4210        __(cmpl $(2*node_size),%imm0)
4211        __(jne 2b)
4212local_label(push_loop_end):
4213        __(movl -node_size*2(%arg_y),%arg_z)
4214        __(movl -node_size*1(%arg_y),%arg_y)
4215        __(jmp *%ra0)
4216        /* lexpr count is one: set arg_z from the lexpr, */
4217        /* maybe vpop arg_y  */
42181:      __(movl -node_size*1(%arg_y),%arg_z)
4219        __(jmp local_label(maybe_pop_y))
4220_endsubp(spread_lexprz)
4221
4222_spentry(callback)
4223        __(push %ebp)
4224        __(movl %esp,%ebp)
4225        /* C scalar args are already on the stack. */
4226        /* arg word 0 at 8(%ebp), word 1 at 12(%ebp), etc. */
4227
4228        /* Reserve some space for results, relative to the
4229           current %ebp.  We may need quite a bit of it. */
4230        __(subl $24,%esp)
4231        __(movl $0,-16(%ebp)) /* No FP result */
4232        /* If the C stack is 16-byte aligned by convention,
4233           it should still be, and this'll be a NOP. */
4234        __(andl $~15,%esp)
4235        /* C NVRs */
4236        __(push %edi)
4237        __(push %esi)
4238        __(push %ebx)
4239        __(push %ebp)
4240       
4241        __(box_fixnum(%eax,%esi))       /* put callback index in arg_y */
4242        __(ref_global(get_tcr,%eax))
4243        __(push $1)
4244        __(call *%eax)
4245        __(addl $node_size,%esp)
4246        /* linear TCR addr now in %eax */
4247        __(movw tcr.ldt_selector(%eax), %rcontext_reg)
4248
4249        /* ebp is 16-byte aligned, and we've pushed 4 words.  Make
4250          sure that when we push old foreign_sp, %esp will be 16-byte
4251          aligned again */
4252        __(subl $8,%esp)
4253        __(pushl rcontext(tcr.save_ebp))  /* mark cstack frame's "owner" */
4254        __(push rcontext(tcr.foreign_sp))
4255        __(movl %esp,rcontext(tcr.foreign_sp))
4256        __(clr %arg_z)
4257        /* arg_y contains callback index */
4258        __(clr %temp1)
4259        __(clr %temp0)
4260        __(clr %fn)
4261        __(pxor %fpzero,%fpzero)
4262        __(movl rcontext(tcr.save_vsp),%esp)
4263        __(movl %ebp,%arg_z)
4264        __(movl rcontext(tcr.save_ebp),%ebp)
4265        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4266        __(stmxcsr rcontext(tcr.foreign_mxcsr))
4267        __(andb $~mxcsr_all_exceptions,rcontext(tcr.foreign_mxcsr))
4268        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4269        __(movl $nrs.callbacks,%fname)
4270        __(check_cstack_alignment())
4271        __(push $local_label(back_from_callback))
4272        __(set_nargs(2))
4273        __(jump_fname())
4274__(tra(local_label(back_from_callback)))
4275        __(movl %esp,rcontext(tcr.save_vsp))
4276        __(movl %ebp,rcontext(tcr.save_ebp))
4277        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4278        __(movl rcontext(tcr.foreign_sp),%esp)
4279        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4280        __(emms)
4281        __(pop rcontext(tcr.foreign_sp))
4282        __(addl $12,%esp)       /* discard alignment padding */
4283        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4284        __ifdef([WIN32_ES_HACK])
4285         __(push %ds)
4286         __(pop %es)
4287        __endif
4288        __(pop %ebp)
4289        __(pop %ebx)
4290        __(pop %esi)
4291        __(pop %edi)
4292        __(cmpb $1,-16(%ebp))
4293        __(movl -12(%ebp),%ecx) /* magic value for ObjC bridge */
4294        __(jae 1f)
4295        __(movl -8(%ebp),%eax)
4296        __(movl -4(%ebp),%edx)
4297        __(leave)
4298        __(ret)
42991:      __(jne 2f)
4300        /* single float return in x87 */
4301        __(flds -8(%ebp))
4302        __(leave)
4303        __(ret)
43042:      /* double-float return in x87 */
4305        __(fldl -8(%ebp))
4306        __(leave)
4307        __(ret)         
4308_endsubp(callback)
4309
4310/* temp0 = array, arg_y = i, arg_z = j. Typecheck everything.
4311   We don't know whether the array is alleged to be simple or
4312   not, and don't know anythng about the element type.  */
4313
4314_spentry(aref2)
4315        __(testl $fixnummask,%arg_y)
4316        __(je 0f)
4317        __(uuo_error_reg_not_fixnum(Rarg_y))
43180:      __(testb $fixnummask,%arg_z_b)
4319        __(je 1f)
4320        __(uuo_error_reg_not_fixnum(Rarg_z))
43211:      __(extract_typecode(%temp0,%imm0))
4322        __(cmpb $subtag_arrayH,%imm0_b)
4323        __(jne 2f)
4324        __(cmpl $2<<fixnumshift,arrayH.rank(%temp0))
4325        __(je 3f)
43262:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
43273:      __(cmpl arrayH.dim0(%temp0),%arg_y)
4328        __(jb 4f)
4329        __(uuo_error_array_bounds(Rarg_y,Rtemp0))
43304:      __(movl arrayH.dim0+node_size(%temp0),%imm0)
4331        __(cmpl %imm0,%arg_z)
4332        __(jb 5f)
4333        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
43345:      __(sarl $fixnumshift,%imm0)
4335        __(imull %arg_y,%imm0)
4336        __(addl %imm0,%arg_z)
4337        __(movl %temp0,%arg_y)
4338        __(xorl %temp1,%temp1)
43396:      __(addl arrayH.displacement(%arg_y),%arg_z)
4340        __(movl arrayH.data_vector(%arg_y),%arg_y)
4341        __(extract_subtag(%arg_y,%imm0_b))
4342        __(cmpb $subtag_vectorH,%imm0_b)
4343        __(ja C(misc_ref_common))
4344        __(jmp 6b)
4345_endsubp(aref2)
4346
4347_spentry(aref3)
4348        __(int $3)
4349_endsubp(aref3)
4350
4351/* As with aref2, but temp1 = array, temp0 = i, arg_y = j, arg_z = new_value */
4352_spentry(aset2)
4353        __(testb $fixnummask,%temp0_b)
4354        __(je 0f)
4355        __(uuo_error_reg_not_fixnum(Rtemp0))
43560:      __(testl $fixnummask,%arg_y)
4357        __(je 1f)
4358        __(uuo_error_reg_not_fixnum(Rarg_y))
43591:      __(extract_typecode(%temp1,%imm0))
4360        __(cmpb $subtag_arrayH,%imm0_b)
4361        __(jne 2f)
4362        __(cmpl $2<<fixnumshift,arrayH.rank(%temp1))
4363        __(je 3f)
43642:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_2d))
43653:      __(cmpl arrayH.dim0(%temp1),%temp0)
4366        __(jb 4f)
4367        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
43684:      __(movl arrayH.dim0+node_size(%temp1),%imm0)
4369        __(cmpl %imm0,%arg_y)
4370        __(jb 5f)
4371        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
43725:      __(sarl $fixnumshift,%imm0)
4373        __(imull %temp0,%imm0)
4374        __(addl %imm0,%arg_y)
4375        __(movl %temp1,%temp0)
4376        __(xorl %temp1,%temp1)
43776:      __(addl arrayH.displacement(%temp0),%arg_y)
4378        __(movl arrayH.data_vector(%temp0),%temp0)
4379        __(extract_subtag(%temp0,%imm0_b))
4380        __(cmpb $subtag_vectorH,%imm0_b)
4381        __(ja C(misc_set_common))
4382        __(jmp 6b)
4383_endsubp(aset2)
4384
4385_spentry(aset3)
4386        __(int $3)
4387_endsubp(aset3)
4388
4389/* Prepend all but the first seven (6 words of code & other immediate data,
4390/* plus inner fn) and last (lfbits) elements of %fn to the "arglist". */
4391_spentry(call_closure)
4392        new_local_labels()
4393        __(vector_length(%fn,%imm0))
4394        __(subl $8<<fixnumshift,%imm0)  /* imm0 = inherited arg count */
4395        __(lea (%nargs,%imm0),%temp0)
4396        __(cmpl $nargregs<<fixnumshift,%temp0)
4397        __(jna local_label(regs_only))  /* either: 1 arg, 1 inherited, or */
4398                                        /* no args, 2 inherited */
4399        __(pop rcontext(tcr.save0))             /* save return address */
4400        __(cmpl $nargregs<<fixnumshift,%nargs)
4401        __(jna local_label(no_insert))
4402
4403/* Some arguments have already been pushed.  Push %imm0's worth */
4404/* of NILs, copy those arguments that have already been vpushed from */
4405/* the old TOS to the new, then insert all of the inherited args */
4406/* and go to the function. */
4407
4408        __(mov %imm0,%temp0)
4409local_label(push_nil_loop):
4410        __(push $nil_value)
4411        __(sub $fixnumone,%temp0)
4412        __(jne local_label(push_nil_loop))
4413
4414/* Need to use arg regs as temporaries.  Stash them in the spill area. */
4415        __(movl %arg_y,rcontext(tcr.save1))
4416        __(movl %arg_z,rcontext(tcr.save2))
4417
4418        __(leal (%esp,%imm0),%temp0)    /* start of already-pushed args */
4419        __(leal -nargregs<<fixnumshift(%nargs),%arg_y) /* args pushed */
4420        __(movd %imm0,%mm0)     /* save inherited arg count */
4421        __(xorl %imm0,%imm0)
4422local_label(copy_already_loop):
4423        __(movl (%temp0,%imm0),%arg_z)
4424        __(movl %arg_z,(%esp,%imm0))
4425        __(addl $fixnumone,%imm0)
4426        __(cmpl %imm0,%arg_y)
4427        __(jne local_label(copy_already_loop))
4428
4429        __(lea -node_size(%temp0,%imm0),%arg_y) /* start of args on stack */
4430        __(movl $7<<fixnumshift,%temp0) /* skip code, new fn */
4431        __(movd %mm0,%imm0)
4432local_label(insert_loop):
4433        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4434        __(addl $node_size,%temp0)
4435        __(addl $fixnumone,%nargs)
4436        __(movl %arg_z,(%arg_y))
4437        __(subl $node_size,%arg_y)
4438        __(subl $fixnumone,%imm0)
4439        __(jne local_label(insert_loop))
4440
4441        /* Recover arg regs, saved earlier */
4442        __(movl rcontext(tcr.save1),%arg_y)
4443        __(movl rcontext(tcr.save2),%arg_z)
4444        __(jmp local_label(go))
4445       
4446/* Here if no args were pushed by the caller. */
4447/* cases: */
4448/* no args, more than two inherited args */
4449/* a single arg in arg_z, more than one inherited arg */
4450/* two args in arg_y and arg_z, some number of inherited args */
4451
4452/* Therefore, we're always going to have to push something (the sum of */
4453/* %nargs and %imm0 will always be greater than $nargregs), and */
4454/* we will have to reserve space for a stack frame. */
4455/* The 0 args, 2 inherited case and the 1 arg, 1 inherited case get */
4456/* handled at local_label(regs_ony). */
4457       
4458local_label(no_insert):
4459        /* Reserve space for a stack frame */
4460        __(push $reserved_frame_marker)
4461        __(push $reserved_frame_marker)
4462        __(lea 7<<fixnumshift(%imm0),%temp0)    /* last inherited arg */
4463        __(rcmpl(%nargs,$fixnumone))
4464        __(je local_label(set_arg_y))
4465        __(jb local_label(set_y_z))
4466        /* %nargs = $nargregs (i.e., 2), vpush remaining inherited vars. */
4467
4468local_label(vpush_remaining):
4469        __(movl $7<<fixnumshift,%temp0)
4470local_label(vpush_remaining_loop):
4471        __(push misc_data_offset(%fn,%temp0))
4472        __(add $node_size,%temp0)
4473        __(add $fixnumone,%nargs)
4474        __(sub $node_size,%imm0)
4475        __(jnz local_label(vpush_remaining_loop))
4476        __(jmp local_label(go))
4477       
4478local_label(set_arg_y):
4479        /* one arg in arg_z.  set arg_y and vpush remaining inherited args */
4480        __(subl $node_size,%temp0)
4481        __(movl misc_data_offset(%fn,%temp0),%arg_y)
4482        __(addl $fixnumone,%nargs)
4483        __(subl $fixnumone,%imm0)
4484        __(jmp local_label(vpush_remaining))
4485local_label(set_y_z):
4486        __(subl $node_size,%temp0)
4487        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4488        __(addl $fixnumone,%nargs)
4489        __(subl $fixnumone,%imm0)
4490        __(jmp local_label(set_arg_y))
4491
4492local_label(go):
4493        __(movl misc_data_offset+(6*node_size)(%fn),%fn)
4494        __(push rcontext(tcr.save0))    /* restore return addr */
4495        __(movapd %fpzero,rcontext(tcr.save0))  /* clear out spill area */
4496        __(jmp *%fn)
4497local_label(regs_only):
4498        __(lea 7<<fixnumshift(%imm0),%temp0)
4499        __(test %nargs,%nargs)
4500        __(jne local_label(one_arg))
4501        /* no args passed, two inherited args */
4502        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_z)
4503        __(cmpl $node_size,%imm0)
4504        __(je local_label(rgo))
4505        __(movl misc_data_offset-(node_size*2)(%fn,%temp0),%arg_y)
4506local_label(rgo):
4507        __(addl %imm0,%nargs)
4508        __(jmp *misc_data_offset+(6*node_size)(%fn))
4509local_label(one_arg):
4510        /* one arg was passed, so there's one inherited arg */
4511        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_y)
4512        __(jmp local_label(rgo))
4513_endsubp(call_closure)
4514
4515_spentry(poweropen_callbackX)
4516        __(int $3)
4517_endsubp(poweropen_callbackX)
4518
4519_spentry(poweropen_ffcallX)
4520        __(int $3)
4521_endsubp(poweropen_ffcallX)
4522
4523_spentry(eabi_ff_call)
4524        __(int $3)
4525_endsubp(eabi_ff_call)
4526
4527_spentry(eabi_callback)
4528        __(int $3)
4529_endsubp(eabi_callback)
4530
4531
4532/* Unused, and often not used on PPC either  */
4533_spentry(callbuiltin)
4534        __(int $3)
4535_endsubp(callbuiltin)
4536
4537_spentry(callbuiltin0)
4538        __(int $3)
4539_endsubp(callbuiltin0)
4540
4541_spentry(callbuiltin1)
4542        __(int $3)
4543_endsubp(callbuiltin1)
4544
4545_spentry(callbuiltin2)
4546        __(int $3)
4547_endsubp(callbuiltin2)
4548
4549_spentry(callbuiltin3)
4550        __(int $3)
4551_endsubp(callbuiltin3)
4552
4553_spentry(restorefullcontext)
4554        __(int $3)
4555_endsubp(restorefullcontext)
4556
4557_spentry(savecontextvsp)
4558        __(int $3)
4559_endsubp(savecontextvsp)
4560
4561_spentry(savecontext0)
4562        __(int $3)
4563_endsubp(savecontext0)
4564
4565_spentry(restorecontext)
4566        __(int $3)
4567_endsubp(restorecontext)
4568
4569_spentry(stkconsyz)
4570        __(int $3)
4571_endsubp(stkconsyz)
4572
4573_spentry(stkvcell0)
4574        __(int $3)
4575_endsubp(stkvcell0)
4576
4577_spentry(stkvcellvsp)
4578        __(int $3)
4579_endsubp(stkvcellvsp)
4580
4581_spentry(breakpoint)
4582        __(int $3)
4583_endsubp(breakpoint)
4584
4585
4586/* %temp1 = array, %temp0 = i,%arg_y = j, %arg_z = k */
4587/*
4588_spentry(aref3)
4589        __(testb $fixnummask,%temp0_b)
4590        __(je 0f)
4591        __(uuo_error_reg_not_fixnum(Rtemp0))
45920:      __(testl $fixnummask,%arg_y)
4593        __(je 1f)
4594        __(uuo_error_reg_not_fixnum(Rarg_y))
45951:      __(testb $fixnummask,%arg_z_b)
4596        __(je 2f)
4597        __(uuo_error_reg_not_fixnum(Rarg_z))
45982:      __(extract_typecode(%temp1,%imm0))
4599        __(cmpb $subtag_arrayH,%imm0_b)
4600        __(jne 3f)
4601        __(cmpl $3<<fixnumshift,arrayH.rank(%temp1))
4602        __(je 4f)
46033:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
46044:      __(cmpl arrayH.dim0(%temp1),%temp0)
4605        __(jb 5f)
4606        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
46075:      __(movl arrayH.dim0+node_size(%temp1),%imm0)
4608        __(cmpl %imm0,%arg_y)
4609        __(jb 6f)
4610        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
46116:      __(unbox_fixnum(%imm0,%imm0))
4612        __(movl arrayH.dim0+(node_size*2)(%temp1),%imm1)
4613        __(cmpq %imm1,%arg_z)
4614        __(jb 7f)
4615        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
46167:      __(unbox_fixnum(%imm1,%imm1))
4617        __(imulq %imm1,%arg_y)
4618        __(mulq %imm1)
4619        __(imulq %imm0,%arg_x)
4620        __(addq %arg_x,%arg_z)
4621        __(addq %arg_y,%arg_z)
4622        __(movq %temp0,%arg_y)
46238:      __(addq arrayH.displacement(%arg_y),%arg_z)
4624        __(movq arrayH.data_vector(%arg_y),%arg_y)
4625        __(extract_subtag(%arg_y,%imm1_b))
4626        __(cmpb $subtag_vectorH,%imm1_b)
4627        __(ja C(misc_ref_common))
4628        __(jmp 8b)
4629_endsubp(aref3)
4630*/       
4631
4632/* %temp1 = array, %imm0 = i, %temp0 = j, %arg_y = k, %arg_z = newval. */
4633/*
4634_spentry(aset3)
4635        __(testb $fixnummask,%temp0_b)
4636        __(je 0f)
4637        __(uuo_error_reg_not_fixnum(Rtemp0))
46380:      __(testb $fixnummask,%arg_x_b)
4639        __(je 1f)
4640        __(uuo_error_reg_not_fixnum(Rarg_x))
46411:      __(testb $fixnummask,%arg_y_b)
4642        __(je 2f)
4643        __(uuo_error_reg_not_fixnum(Rarg_y))
46442:      __(extract_typecode(%temp1,%imm0))
4645        __(cmpb $subtag_arrayH,%imm0_b)
4646        __(jne 3f)
4647        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4648        __(je 4f)
46493:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
46504:      __(cmpq arrayH.dim0(%temp1),%temp0)
4651        __(jb 5f)
4652        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
46535:      __(movq arrayH.dim0+node_size(%temp1),%imm0)
4654        __(cmpq %imm0,%arg_x)
4655        __(jb 6f)
4656        __(uuo_error_array_bounds(Rarg_x,Rtemp1))
46576:      __(unbox_fixnum(%imm0,%imm0))
4658        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4659        __(cmpq %imm1,%arg_y)
4660        __(jb 7f)
4661        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
46627:      __(unbox_fixnum(%imm1,%imm1))
4663        __(imulq %imm1,%arg_x)
4664        __(mulq %imm1)
4665        __(imulq %imm0,%temp0)
4666        __(addq %temp0,%arg_y)
4667        __(addq %arg_x,%arg_y)
4668        __(movq %temp1,%arg_x)
46698:      __(addq arrayH.displacement(%arg_x),%arg_y)
4670        __(movq arrayH.data_vector(%arg_x),%arg_x)
4671        __(extract_subtag(%arg_x,%imm1_b))
4672        __(cmpb $subtag_vectorH,%imm1_b)
4673        __(ja C(misc_set_common))
4674        __(jmp 8b)
4675_endsubp(aset3)
4676*/
4677
4678_spentry(unused_6)
4679        __(int $3)
4680Xspentry_end:
4681_endsubp(unused_6)
4682        .data
4683        .globl C(spentry_start)
4684        .globl C(spentry_end)
4685C(spentry_start):       .long Xspentry_start
4686C(spentry_end):         .long Xspentry_end
4687       
Note: See TracBrowser for help on using the repository browser.