source: trunk/source/lisp-kernel/x86-spentry32.s @ 11794

Last change on this file since 11794 was 11794, checked in by gb, 10 years ago

Need to be careful about pc-lusring in .SPstore-node-conditional too;
need a new label to restart reliably.

File size: 154.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        __(jne 0f)
47        __(testb $fixnummask,%arg_z_b)
48        __(jne 1f)
49        __(movl misc_header_offset(%arg_y),%imm0)
50        __(xorb %imm0_b,%imm0_b)
51        __(shrl $num_subtag_bits-fixnumshift,%imm0)
52        __(cmpl %imm0,%arg_z)
53        __(jae 2f)
54        __(movb misc_subtag_offset(%arg_y),%imm0_b)
55        __(jmp C(misc_ref_common))
56
570:      __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
581:      __(uuo_error_reg_not_fixnum(Rarg_z))
592:      __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
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        __(pop %temp1)  /* return addr */
417        __(push $reserved_frame_marker)
418        __(push $reserved_frame_marker)
419        __(push $XBADVEC)
420        __(push %temp1)
421        __(set_nargs(3))
422        __(jmp _SPksignalerr)
423_endfn(C(misc_ref_common))
424
425/* Like misc_ref, only the boxed subtag is in temp0. */
426_spentry(subtag_misc_ref)
427        __(mov %arg_y,%imm0)
428        __(and $tagmask,%imm0)
429        __(cmp $tag_misc,%imm0)
430        __(jne 0f)
431        __(testb $fixnummask,%arg_z_b)
432        __(jne 1f)
433        __(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        __(jae 2f)
438        __(unbox_fixnum(%temp0,%imm0))
439        __(jmp C(misc_ref_common))
4400:      __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
4411:      __(uuo_error_reg_not_fixnum(Rarg_z))
4422:      __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
443_endsubp(subtag_misc_ref)
444
445/* Like misc_set, only the boxed subtag is in temp1. */
446_spentry(subtag_misc_set)
447        __(mov %temp0,%imm0)
448        __(andb $tagmask,%imm0_b)
449        __(cmpb $tag_misc,%imm0_b)
450        __(jne 0f)
451        __(mov %arg_y,%imm0)
452        __(testb $fixnummask,%imm0_b)
453        __(jne 1f)
454        __(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        __(jae 2f)
459        __(unbox_fixnum(%temp1,%imm0))
460        __(jmp C(misc_set_common))
4610:      __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4621:      __(uuo_error_reg_not_fixnum(Rarg_y))
4632:      __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
464_endsubp(subtag_misc_set)
465
466/* %temp0 = vector, %arg_y = unscaled-idx, %arg_z = val */
467_spentry(misc_set)
468        __(mov %temp0,%imm0)
469        __(andb $tagmask,%imm0_b)
470        __(cmpb $tag_misc,%imm0_b)
471        __(jne 0f)
472        __(test $fixnummask,%arg_y)
473        __(jne 1f)
474        __(movl misc_header_offset(%temp0),%imm0)
475        __(xorb %imm0_b,%imm0_b)
476        __(shrl $num_subtag_bits-fixnumshift,%imm0)
477        __(cmpl %imm0,%arg_y)
478        __(jae 2f)
479        __(xorl %imm0,%imm0)
480        __(movb misc_subtag_offset(%temp0),%imm0_b)
481        __(jmp C(misc_set_common))
4820:      __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4831:      __(uuo_error_reg_not_fixnum(Rarg_y))
4842:      __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
485_endsubp(misc_set)
486
487/* imm0_b = subtag, %temp0 = vector, %arg_y = index, %arg_z = value */
488_startfn(C(misc_set_common))
489        __(movzbl %imm0_b,%imm0)
490        __(leal local_label(misc_set_jmp)(,%imm0,4),%imm0)
491        __(jmp *(%imm0))
492        .p2align 2
493local_label(misc_set_jmp):
494        /* 00-0f */
495        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
496        .long local_label(misc_set_invalid) /* 01 cons  */
497        .long local_label(misc_set_invalid) /* 02 nodeheader  */
498        .long local_label(misc_set_invalid) /* 03 imm  */
499        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
500        .long local_label(misc_set_invalid) /* 05 tra  */
501        .long local_label(misc_set_invalid) /* 06 misc  */
502        .long local_label(misc_set_u32) /* 07 bignum  */
503        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
504        .long local_label(misc_set_invalid) /* 09 cons  */
505        .long _SPgvset /* 0a ratio  */
506        .long local_label(misc_set_invalid) /* 0b imm  */
507        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
508        .long local_label(misc_set_invalid) /* 0d tra  */
509        .long local_label(misc_set_invalid) /* 0e misc  */
510        .long local_label(misc_set_u32) /* 0f single_float  */
511        /* 10-1f  */
512        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
513        .long local_label(misc_set_invalid) /* 11 cons  */
514        .long local_label(misc_set_invalid) /* 12 nodeheader  */
515        .long local_label(misc_set_invalid) /* 13 imm  */
516        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
517        .long local_label(misc_set_invalid) /* 15 tra  */
518        .long local_label(misc_set_invalid) /* 16 misc  */
519        .long local_label(misc_set_u32) /* 17 double_float  */
520        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
521        .long local_label(misc_set_invalid) /* 19 cons  */
522        .long _SPgvset /* 1a complex  */
523        .long local_label(misc_set_invalid) /* 1b imm  */
524        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
525        .long local_label(misc_set_invalid) /* 1d tra  */
526        .long local_label(misc_set_invalid) /* 1e misc  */
527        .long local_label(misc_set_u32) /* 1f macptr  */
528        /* 20-2f  */
529        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
530        .long local_label(misc_set_invalid) /* 21 cons  */
531        .long local_label(misc_set_invalid) /* 22 catch_frame  */
532        .long local_label(misc_set_invalid) /* 23 imm  */
533        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
534        .long local_label(misc_set_invalid) /* 25 tra  */
535        .long local_label(misc_set_invalid) /* 26 misc  */
536        .long local_label(misc_set_u32) /* 27 dead_macptr  */
537        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
538        .long local_label(misc_set_invalid) /* 29 cons  */
539        .long local_label(misc_set_function) /* 2a function  */
540        .long local_label(misc_set_invalid) /* 2b imm  */
541        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
542        .long local_label(misc_set_invalid) /* 2d tra  */
543        .long local_label(misc_set_invalid) /* 2e misc  */
544        .long local_label(misc_set_invalid) /* 2f immheader  */
545        /* 30-3f  */
546        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
547        .long local_label(misc_set_invalid) /* 31 cons  */
548        .long local_label(misc_set_invalid) /* 32 nodeheader  */
549        .long local_label(misc_set_invalid) /* 33 imm  */
550        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
551        .long local_label(misc_set_invalid) /* 35 tra  */
552        .long local_label(misc_set_invalid) /* 36 misc  */
553        .long local_label(misc_set_invalid) /* 37 immheader  */
554        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
555        .long local_label(misc_set_invalid) /* 39 cons  */
556        .long _SPgvset /* 3a symbol  */
557        .long local_label(misc_set_invalid) /* 3b imm  */
558        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
559        .long local_label(misc_set_invalid) /* 3d tra  */
560        .long local_label(misc_set_invalid) /* 3e misc  */
561        .long local_label(misc_set_u32) /* 3f xcode_vector  */
562        /* 40-4f  */
563        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
564        .long local_label(misc_set_invalid) /* 41 cons  */
565        .long _SPgvset /* 42 lock  */
566        .long local_label(misc_set_invalid) /* 43 imm  */
567        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
568        .long local_label(misc_set_invalid) /* 45 tra  */
569        .long local_label(misc_set_invalid) /* 46 misc  */
570        .long local_label(misc_set_invalid) /* 47 immheader  */
571        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
572        .long local_label(misc_set_invalid) /* 49 cons  */
573        .long _SPgvset /* 4a hash_vector  */
574        .long local_label(misc_set_invalid) /* 4b imm  */
575        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
576        .long local_label(misc_set_invalid) /* 4d tra  */
577        .long local_label(misc_set_invalid) /* 4e misc  */
578        .long local_label(misc_set_invalid) /* 4f immheader  */
579        /* 50-5f  */
580        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
581        .long local_label(misc_set_invalid) /* 51 cons  */
582        .long _SPgvset /* 52 pool  */
583        .long local_label(misc_set_invalid) /* 53 imm  */
584        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
585        .long local_label(misc_set_invalid) /* 55 tra  */
586        .long local_label(misc_set_invalid) /* 56 misc  */
587        .long local_label(misc_set_invalid) /* 57 immheader  */
588        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
589        .long local_label(misc_set_invalid) /* 59 cons  */
590        .long _SPgvset /* 5a weak  */
591        .long local_label(misc_set_invalid) /* 5b imm  */
592        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
593        .long local_label(misc_set_invalid) /* 5d tra  */
594        .long local_label(misc_set_invalid) /* 5e misc  */
595        .long local_label(misc_set_invalid) /* 5f immheader  */
596        /* 60-6f  */
597        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
598        .long local_label(misc_set_invalid) /* 61 cons  */
599        .long _SPgvset /* 62 package  */
600        .long local_label(misc_set_invalid) /* 63 imm  */
601        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
602        .long local_label(misc_set_invalid) /* 65 tra  */
603        .long local_label(misc_set_invalid) /* 66 misc  */
604        .long local_label(misc_set_invalid) /* 67 immheader  */
605        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
606        .long local_label(misc_set_invalid) /* 69 cons  */
607        .long _SPgvset /* 6a slot_vector  */
608        .long local_label(misc_set_invalid) /* 6b imm  */
609        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
610        .long local_label(misc_set_invalid) /* 6d tra  */
611        .long local_label(misc_set_invalid) /* 6e misc  */
612        .long local_label(misc_set_invalid) /* 6f immheader  */
613        /* 70-7f  */
614        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
615        .long local_label(misc_set_invalid) /* 71 cons  */
616        .long _SPgvset /* 72 instance  */
617        .long local_label(misc_set_invalid) /* 73 imm  */
618        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
619        .long local_label(misc_set_invalid) /* 75 tra  */
620        .long local_label(misc_set_invalid) /* 76 misc  */
621        .long local_label(misc_set_invalid) /* 77 immheader  */
622        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
623        .long local_label(misc_set_invalid) /* 79 cons  */
624        .long _SPgvset /* 7a struct  */
625        .long local_label(misc_set_invalid) /* 7b imm  */
626        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
627        .long local_label(misc_set_invalid) /* 7d tra  */
628        .long local_label(misc_set_invalid) /* 7e misc  */
629        .long local_label(misc_set_invalid) /* 7f immheader  */
630        /* 80-8f  */
631        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
632        .long local_label(misc_set_invalid) /* 81 cons  */
633        .long _SPgvset /* 82 istruct  */
634        .long local_label(misc_set_invalid) /* 83 imm  */
635        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
636        .long local_label(misc_set_invalid) /* 85 tra  */
637        .long local_label(misc_set_invalid) /* 86 misc  */
638        .long local_label(misc_set_invalid) /* 87 immheader  */
639        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
640        .long local_label(misc_set_invalid) /* 89 cons  */
641        .long _SPgvset /* 8a value_cell  */
642        .long local_label(misc_set_invalid) /* 8b imm  */
643        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
644        .long local_label(misc_set_invalid) /* 8d tra  */
645        .long local_label(misc_set_invalid) /* 8e misc  */
646        .long local_label(misc_set_invalid) /* 8f immheader  */
647        /* 90-9f  */
648        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
649        .long local_label(misc_set_invalid) /* 91 cons  */
650        .long _SPgvset /* 92 xfunction  */
651        .long local_label(misc_set_invalid) /* 93 imm  */
652        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
653        .long local_label(misc_set_invalid) /* 95 tra  */
654        .long local_label(misc_set_invalid) /* 96 misc  */
655        .long local_label(misc_set_invalid) /* 97 immheader  */
656        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
657        .long local_label(misc_set_invalid) /* 99 cons  */
658        .long _SPgvset /* 9a arrayH  */
659        .long local_label(misc_set_invalid) /* 9b imm  */
660        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
661        .long local_label(misc_set_invalid) /* 9d tra  */
662        .long local_label(misc_set_invalid) /* 9e misc  */
663        .long local_label(misc_set_invalid) /* 9f immheader  */
664        /* a0-af  */
665        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
666        .long local_label(misc_set_invalid) /* a1 cons  */
667        .long _SPgvset /* a2 vectorH  */
668        .long local_label(misc_set_invalid) /* a3 imm  */
669        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
670        .long local_label(misc_set_invalid) /* a5 tra  */
671        .long local_label(misc_set_invalid) /* a6 misc  */
672        .long local_label(misc_set_single_float_vector) /* a7 sf_vector  */
673        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
674        .long local_label(misc_set_invalid) /* a9 cons  */
675        .long _SPgvset /* aa simple_vector  */
676        .long local_label(misc_set_invalid) /* ab imm  */
677        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
678        .long local_label(misc_set_invalid) /* ad tra  */
679        .long local_label(misc_set_invalid) /* ae misc  */
680        .long local_label(misc_set_u32) /* af u32  */
681        /* b0-bf  */
682        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
683        .long local_label(misc_set_invalid) /* b1 cons  */
684        .long local_label(misc_set_invalid) /* b2 nodeheader  */
685        .long local_label(misc_set_invalid) /* b3 imm  */
686        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
687        .long local_label(misc_set_invalid) /* b5 tra  */
688        .long local_label(misc_set_invalid) /* b6 misc  */
689        .long local_label(misc_set_s32) /* b7 s32  */
690        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
691        .long local_label(misc_set_invalid) /* b9 cons  */
692        .long local_label(misc_set_invalid) /* ba nodeheader  */
693        .long local_label(misc_set_invalid) /* bb imm  */
694        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
695        .long local_label(misc_set_invalid) /* bd tra  */
696        .long local_label(misc_set_invalid) /* be misc  */
697        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
698        /* c0-cf  */
699        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
700        .long local_label(misc_set_invalid) /* c1 cons  */
701        .long local_label(misc_set_invalid) /* c2 nodeheader  */
702        .long local_label(misc_set_invalid) /* c3 imm  */
703        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
704        .long local_label(misc_set_invalid) /* c5 tra  */
705        .long local_label(misc_set_invalid) /* c6 misc  */
706        .long local_label(misc_set_string) /* c7 simple_base_string  */
707        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
708        .long local_label(misc_set_invalid) /* c9 cons  */
709        .long local_label(misc_set_invalid) /* ca nodeheader  */
710        .long local_label(misc_set_invalid) /* cb imm  */
711        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
712        .long local_label(misc_set_invalid) /* cd tra  */
713        .long local_label(misc_set_invalid) /* ce misc  */
714        .long local_label(misc_set_u8) /* cf u8  */
715        /* d0-df  */
716        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
717        .long local_label(misc_set_invalid) /* d1 cons  */
718        .long local_label(misc_set_invalid) /* d2 nodeheader  */
719        .long local_label(misc_set_invalid) /* d3 imm  */
720        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
721        .long local_label(misc_set_invalid) /* d5 tra  */
722        .long local_label(misc_set_invalid) /* d6 misc  */
723        .long local_label(misc_set_s8)      /* d7 s8  */
724        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
725        .long local_label(misc_set_invalid) /* d9 cons  */
726        .long local_label(misc_set_invalid) /* da nodeheader  */
727        .long local_label(misc_set_invalid) /* db imm  */
728        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
729        .long local_label(misc_set_invalid) /* dd tra  */
730        .long local_label(misc_set_invalid) /* de misc  */
731        .long local_label(misc_set_invalid) /* df immheader  */
732        /* e0-ef  */
733        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
734        .long local_label(misc_set_invalid) /* e1 cons  */
735        .long local_label(misc_set_invalid) /* e2 nodeheader  */
736        .long local_label(misc_set_invalid) /* e3 imm  */
737        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
738        .long local_label(misc_set_invalid) /* e5 tra  */
739        .long local_label(misc_set_invalid) /* e6 misc  */
740        .long local_label(misc_set_u16) /* e7 u16  */
741        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
742        .long local_label(misc_set_invalid) /* e9 cons  */
743        .long local_label(misc_set_invalid) /* ea nodeheader  */
744        .long local_label(misc_set_invalid) /* eb imm  */
745        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
746        .long local_label(misc_set_invalid) /* ed tra  */
747        .long local_label(misc_set_invalid) /* ee misc  */
748        .long local_label(misc_set_s16) /* ef s16  */
749        /* f0-ff  */
750        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
751        .long local_label(misc_set_invalid) /* f1 cons  */
752        .long local_label(misc_set_invalid) /* f2 nodeheader  */
753        .long local_label(misc_set_invalid) /* f3 imm  */
754        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
755        .long local_label(misc_set_invalid) /* f5 tra  */
756        .long local_label(misc_set_invalid) /* f6 misc  */
757        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
758        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
759        .long local_label(misc_set_invalid) /* f9 cons  */
760        .long local_label(misc_set_invalid) /* fa nodeheader  */
761        .long local_label(misc_set_invalid) /* fb imm  */
762        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
763        .long local_label(misc_set_invalid) /* fd tra  */
764        .long local_label(misc_set_invalid) /* fe misc  */
765        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
766
767local_label(misc_set_function):
768        /* Functions are funny: the first N words are treated as */
769        /* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
770        __(movzwl misc_data_offset(%temp0),%imm0)
771        __(shl $fixnumshift,%imm0)
772        __(rcmpl(%arg_y,%imm0))
773        __(jae _SPgvset)
774local_label(misc_set_u32):
775        /* Either a non-negative fixnum, a positive one-digit bignum, or */
776        /* a two-digit bignum whose sign-digit is 0 is OK. */
777        __(movl $~(target_most_positive_fixnum <<fixnumshift),%imm0)
778        __(test %arg_z,%imm0)
779        __(movl %arg_z,%imm0)
780        __(jne 1f)
781        __(sarl $fixnumshift,%imm0)
782        __(jmp 9f)
7831:      __(andb $tagmask,%imm0_b)
784        __(cmpb $tag_misc,%imm0_b)
785        __(jne local_label(misc_set_bad))
786        __(movb misc_subtag_offset(%arg_z),%imm0_b)
787        __(cmpb $subtag_bignum,%imm0_b)
788        __(jne local_label(misc_set_bad))
789        __(movl misc_header_offset(%arg_z),%imm0)
790        __(cmpl $two_digit_bignum_header,%imm0)
791        __(je 3f)
792        __(cmpl $one_digit_bignum_header,%imm0)
793        __(jne local_label(misc_set_bad))
794        __(movl misc_data_offset(%arg_z),%imm0)
795        __(testl %imm0,%imm0)
796        __(js local_label(misc_set_bad))
797        __(jmp 9f)
7983:      __(movl misc_data_offset(%arg_z),%imm0)
799        __(cmpl $0,misc_data_offset+4(%arg_z))
800        __(jne local_label(misc_set_bad))
8019:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
802        __(ret)
803local_label(misc_set_s32):
804        __(unbox_fixnum(%arg_z,%imm0))
805        __(testb $fixnummask,%arg_z_b)
806        __(je 9f)
8071:      __(movb %arg_z_b,%imm0_b)
808        __(andb $tagmask,%imm0_b)
809        __(cmpb $tag_misc,%imm0_b)
810        __(jne local_label(misc_set_bad))
811        __(movl misc_header_offset(%arg_z),%imm0)
812        __(cmpl $one_digit_bignum_header,%imm0)
813        __(jne local_label(misc_set_bad))
814        __(movl misc_data_offset(%arg_z),%imm0)
8159:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
816        __(ret)
817local_label(misc_set_bad):
818        __(movl %arg_z,%arg_y)
819        __(movl %temp0,%arg_z)
820        __(pop %temp1)  /* return addr */
821        __(push $reserved_frame_marker)
822        __(push $reserved_frame_marker)
823        __(push $XNOTELT)
824        __(push %temp1)
825        __(set_nargs(3))
826        __(jmp _SPksignalerr)
827local_label(misc_set_single_float_vector):
828        __(extract_lisptag(%arg_z,%imm0))
829        __(cmpb $tag_misc,%imm0_b)
830        __(jne local_label(misc_set_bad))
831        __(movb misc_subtag_offset(%arg_z),%imm0_b)
832        __(cmpb $subtag_single_float,%imm0_b)
833        __(jne local_label(misc_set_bad))
834        __(movl single_float.value(%arg_z),%imm0)
835        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
836        __(ret)
837local_label(misc_set_double_float_vector):
838        __(extract_lisptag(%arg_z,%imm0))
839        __(cmpb $tag_misc,%imm0_b)
840        __(jne local_label(misc_set_bad))
841        __(movb misc_subtag_offset(%arg_z),%imm0_b)
842        __(cmpb $subtag_double_float,%imm0_b)
843        __(jne local_label(misc_set_bad))
844        __(movsd double_float.value(%arg_z),%fp0)
845        __(movsd %fp0,misc_dfloat_offset(%temp0,%arg_y,2))
846        __(ret)
847local_label(misc_set_fixnum_vector):
848        __(unbox_fixnum(%arg_z,%imm0))
849        __(testb $fixnummask,%arg_z_b)
850        __(jne local_label(misc_set_bad))
851        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
852        __(ret)
853local_label(misc_set_u8):
854        __(testl $~(0xff<<fixnumshift),%arg_z)
855        __(jne local_label(misc_set_bad))
856        __(unbox_fixnum(%arg_y,%imm0))
857        __(movl %arg_z,%arg_y)
858        __(shll $8-fixnumshift,%arg_z)
859        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
860        __(movl %arg_y,%arg_z)
861        __(ret)
862local_label(misc_set_s8):
863        __(movl %arg_z,%imm0)
864        __(shll $32-(8+fixnumshift),%imm0)
865        __(sarl $32-(8+fixnumshift),%imm0)
866        __(cmpl %arg_z,%imm0)
867        __(jne local_label(misc_set_bad))
868        __(testb $fixnummask,%arg_z_b)
869        __(jne local_label(misc_set_bad))
870        __(unbox_fixnum(%arg_y,%imm0))
871        __(movl %arg_z,%arg_z)
872        __(shll $8-fixnumshift,%arg_z)
873        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
874        __(movl %arg_y,%arg_z)
875        __(ret)
876local_label(misc_set_string):
877        __(cmpb $subtag_character,%arg_z_b)
878        __(jne local_label(misc_set_bad))
879        __(movl %arg_z,%imm0)
880        __(shrl $charcode_shift,%imm0)
881        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
882        __(ret)
883local_label(misc_set_u16):
884        __(testl $~(0xffff<<fixnumshift),%arg_z)
885        __(jne local_label(misc_set_bad))
886        __(movl %arg_y,%imm0)
887        __(shrl $1,%imm0)
888        __(mark_as_imm(%temp1))
889        __(unbox_fixnum(%arg_z,%temp1))
890        __(movw %temp1_w,misc_data_offset(%temp0,%imm0))
891        __(mark_as_node(%temp1))
892        __(ret)
893local_label(misc_set_s16):
894        __(movl %arg_z,%imm0)
895        __(shll $32-(16+fixnumshift),%imm0)
896        __(sarl $32-(16+fixnumshift),%imm0)
897        __(cmpl %arg_z,%imm0)
898        __(jne local_label(misc_set_bad))
899        __(testb $fixnummask,%arg_z_b)
900        __(jne local_label(misc_set_bad))
901        __(movl %arg_y,%imm0)
902        __(shrl $1,%imm0)
903        __(mark_as_imm(%temp1))
904        __(unbox_fixnum(%arg_z,%temp1))
905        __(movw %temp1_w,misc_data_offset(%temp0,%imm0))
906        __(mark_as_node(%temp1))
907        __(ret)
908local_label(misc_set_bit_vector):
909        __(testl $~fixnumone,%arg_z)
910        __(jne local_label(misc_set_bad))
911        __(unbox_fixnum(%arg_y,%imm0))
912        __(testb %arg_z_b,%arg_z_b)
913        __(je local_label(misc_set_clr_bit))
914local_label(misc_set_set_bit):
915        __(btsl %imm0,misc_data_offset(%temp0))
916        __(ret)
917local_label(misc_set_clr_bit):
918        __(btrl %imm0,misc_data_offset(%temp0))
919        __(ret)
920local_label(misc_set_invalid):
921        __(pop %temp1)  /* return addr */
922        __(push $reserved_frame_marker)
923        __(push $reserved_frame_marker)
924        __(push $XSETBADVEC)
925        __(push %temp0)
926        __(push %temp1)
927        __(set_nargs(4))
928        __(jmp _SPksignalerr)
929_endfn(C(misc_set_common))
930
931_spentry(Fret1valn)
932        .globl C(ret1valn)
933__(tra(C(ret1valn)))
934        __(mov (%esp),%ra0)
935        __(mov %arg_z,(%esp))
936        __(set_nargs(1))
937        __(jmp *%ra0)
938_endsubp(Fret1valn)
939
940_spentry(nvalret)
941        .globl C(nvalret)
942C(nvalret):
943        __(ref_global(ret1val_addr,%temp0))
944        __(cmpl lisp_frame.savera0(%ebp),%temp0)
945        __(je 1f)
946        __(test %nargs,%nargs)
947        __(movl $nil_value,%arg_z)
948        __(cmovnel -node_size(%esp,%nargs),%arg_z)
949        __(leave)
950        __(ret)
951
952/* actually need to return values; always need to copy. */
9531:      __(lea 2*node_size(%ebp),%imm0)
954        __(pushl (%imm0))
955        __(movl 0(%ebp),%ebp)
956        __(addl $node_size,%imm0)
957        __(lea node_size(%esp,%nargs),%temp0)
958        __(xorl %arg_y,%arg_y)
959        __(jmp 3f)
9602:      __(movl -node_size(%temp0),%arg_z)
961        __(subl $node_size,%temp0)
962        __(addl $node_size,%arg_y)
963        __(movl %arg_z,-node_size(%imm0))
964        __(subl $node_size,%imm0)
9653:      __(cmpl %arg_y,%nargs)
966        __(jne 2b)
967        __(pop %ra0)
968        __(movl %imm0,%esp)
969        __(jmp *%ra0)
970_endsubp(nvalret)
971
972_spentry(jmpsym)
973        __(jump_fname())
974_endsubp(jmpsym)
975
976_spentry(jmpnfn)
977        __(mov %temp0,%fn)
978        __(jmp *%fn)
979_endsubp(jmpnfn)
980
981_spentry(funcall)
982        __(do_funcall())
983_endsubp(funcall)
984
985/* Make a lisp integer (fixnum or one-digit bignum) from the value in %imm0 */
986_spentry(makes32)
987        __(imull $fixnumone,%imm0,%arg_z)       /* result is fixnum-tagged */
988        __(jno 0f)                              /* but may have overflowed */
989        __(movd %imm0,%mm1)
990        __(movl $one_digit_bignum_header,%imm0)
991        __(movd %imm0,%mm0)
992        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
993        __(movd %mm1,misc_data_offset(%arg_z))
9940:      __(repret)
995_endsubp(makes32)
996
997/* Make a lisp integer out of the unboxed 64-bit word in %mm0. */
998/* This is a little clumsy, but the alternative requires callers to */
999/* have already marked %edx as an imm reg (or else store it in memory
1000/* somewhere), and I'm nervous about */
1001/* splitting up the mark-as-imm/mark-as-node between two separate */
1002/* pieces of code. */
1003_spentry(makes64)
1004        __(movq %mm0,%mm2)
1005        __(pshufw $0x4e,%mm0,%mm1)      /* swap hi/lo halves */
1006        __(psrad $31,%mm0)      /* propagate sign */
1007        __(pcmpeqd %mm0,%mm1)   /* all ones if equal */
1008        __(movd %mm1,%imm0)
1009        __(cmpb $-1,%imm0_b)    /* upper half just sign extension? */
1010        __(jne 1f)
1011        __(movd %mm2,%imm0)
1012        __(jmp _SPmakes32)
10131:      __(movl $two_digit_bignum_header,%imm0)
1014        __(movd %imm0,%mm0)
1015        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
1016        __(movq %mm2,misc_data_offset(%arg_z))
1017        __(ret)
1018_endsubp(makes64)
1019
1020_spentry(syscall)
1021        /* Save lisp registers */
1022        __(push %ebp)
1023        __(movl %esp,%ebp)
1024        __(push %temp0)
1025        __(push %temp1)
1026        __(push %arg_y)
1027        __(push %arg_z)
1028        __(push %fn)
1029        __(movl %esp,rcontext(tcr.save_vsp))
1030        __(movl %ebp,rcontext(tcr.save_ebp))
1031        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
1032        __(movl rcontext(tcr.foreign_sp),%esp)
1033        /* preserve state of direction flag */
1034        __(pushfl)
1035        __(popl rcontext(tcr.save_eflags))
1036        __(cld)
1037        __(emms)
1038        __(pop %ebp)            /* backlink */
1039        __(lea 15(%esp),%edx)
1040        __(andl $-16,%edx)
1041        __(movl %edx,%esp)
1042        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1043        __(movl $local_label(back_from_sysenter),%edx)
1044        __(push %edx)
1045        __(movl %esp,%ecx)
1046        __(sysenter)
1047local_label(back_from_sysenter):
1048        __(jnc 0f)
1049        __(neg %eax)
10500:     
1051        __(movl %ebp,%esp)
1052        __(movl %esp,rcontext(tcr.foreign_sp))
1053        __(clr %arg_z)
1054        __(clr %arg_y)
1055        __(clr %temp1)
1056        __(clr %temp0)
1057        __(clr %fn)
1058        __(pxor %fpzero,%fpzero)
1059        __(pushl rcontext(tcr.save_eflags))
1060        __(popfl)
1061        __(movl rcontext(tcr.save_vsp),%esp)
1062        __(movl rcontext(tcr.save_ebp),%ebp)
1063        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
1064        __(pop %fn)
1065        __(pop %arg_z)
1066        __(pop %arg_y)
1067        __(pop %temp1)
1068        __(check_pending_interrupt(%temp0))
1069        __(pop %temp0)
1070        __(leave)
1071        __(ret)
1072_endsubp(syscall)
1073
1074/* Make system call that returns a doubleword result in %edx:%eax and */
1075/* copy the result into %mm0. */
1076_spentry(syscall2)
1077        /* Save lisp registers */
1078        __(push %ebp)
1079        __(movl %esp,%ebp)
1080        __(push %temp0)
1081        __(push %temp1)
1082        __(push %arg_y)
1083        __(push %arg_z)
1084        __(push %fn)
1085        __(movl %esp,rcontext(tcr.save_vsp))
1086        __(movl %ebp,rcontext(tcr.save_ebp))
1087        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
1088        __(movl rcontext(tcr.foreign_sp),%esp)
1089        /* preserve state of direction flag */
1090        __(pushfl)
1091        __(popl rcontext(tcr.save_eflags))
1092        __(cld)
1093        __(emms)
1094        __(pop %ebp)            /* backlink */
1095        __(lea 15(%esp),%edx)
1096        __(andl $-16,%edx)
1097        __(movl %edx,%esp)
1098        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1099        __(pushl $local_label(back_from_syscall))
1100        __(int $0x80)
1101local_label(back_from_syscall):
1102        __(jnc 0f)
1103        __(neg %eax)
1104        __(movl $-1,%edx)
11050:
1106        /* just use memory rather than screwing around with */
1107        /* movd %eax,%mm0, movd %edx,%mm1, psllq $32,%mm1, por %mm1,%mm0 */
1108        __(push %edx)
1109        __(push %eax)
1110        __(movq (%esp),%mm0)
1111        __(movl %ebp,%esp)
1112        __(movl %esp,rcontext(tcr.foreign_sp))
1113        __(clr %arg_z)
1114        __(clr %arg_y)
1115        __(clr %temp1)
1116        __(clr %temp0)
1117        __(clr %fn)
1118        __(pxor %fpzero,%fpzero)
1119        __(pushl rcontext(tcr.save_eflags))
1120        __(popf)
1121        __(movl rcontext(tcr.save_vsp),%esp)
1122        __(movl rcontext(tcr.save_ebp),%ebp)
1123        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
1124        __(pop %fn)
1125        __(pop %arg_z)
1126        __(pop %arg_y)
1127        __(pop %temp1)
1128        __(check_pending_interrupt(%temp0))
1129        __(pop %temp0)
1130        __(leave)
1131        __(ret)
1132_endsubp(syscall2)
1133
1134
1135_spentry(mkcatch1v)
1136        __(nMake_Catch(0))
1137        __(ret)
1138_endsubp(mkcatch1v)
1139
1140_spentry(mkunwind)
1141        __(movl $undefined,%arg_z)
1142        __(Make_Catch(fixnumone))
1143        __(jmp *%ra0)
1144_endsubp(mkunwind)
1145
1146/* this takes a return address in %ra0; it's "new" in that it does the */
1147/*   double binding of *interrupt-level* out-of-line */
1148_spentry(nmkunwind)
1149        __(movl rcontext(tcr.tlb_pointer),%arg_z)
1150        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_z),%arg_y)
1151        __(push %arg_y)
1152        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
1153        __(push rcontext(tcr.db_link))
1154        __(movl %esp,rcontext(tcr.db_link))
1155        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_z))
1156        __(movl $undefined,%arg_z)
1157        /* %arg_z = tag, %xfn (%temp1) = pc */
1158        __(Make_Catch(fixnumone))
1159        __(movl %arg_y,%arg_z)
1160        __(jmp _SPbind_interrupt_level)
1161_endsubp(nmkunwind)
1162
1163_spentry(mkcatchmv)
1164        __(nMake_Catch(fixnumone))
1165        __(ret)
1166_endsubp(mkcatchmv)
1167
1168_spentry(throw)
1169        __(movl rcontext(tcr.catch_top),%imm0)
1170        __(movl (%esp,%nargs),%arg_y)   /* arg_y = tag   */
1171        __(movd %nargs,%mm0)
1172        __(xorl %temp1,%temp1)
1173        __(jmp local_label(_throw_test))
1174local_label(_throw_loop):
1175        __(cmpl %arg_y,catch_frame.catch_tag(%imm0))
1176        __(je local_label(_throw_found))
1177        __(movl catch_frame.link(%imm0),%imm0)
1178        __(addl $fixnum_one,%temp1)
1179local_label(_throw_test):
1180        __(test %imm0,%imm0)
1181        __(jne local_label(_throw_loop))
1182        __(push %ra0)
1183        __(uuo_error_reg_not_tag(Rarg_y,subtag_catch_frame))
1184        __(pop %ra0)
1185        __(jmp _SPthrow)
1186local_label(_throw_found):
1187        __(testb $fulltagmask,catch_frame.mvflag(%imm0))
1188        __(movl %temp1,%imm0)
1189        __(movd %mm0,%nargs)
1190        __(jne local_label(_throw_multiple))
1191        __(movl $nil_value,%arg_z)
1192        __(test %nargs,%nargs)
1193        __(je local_label(_throw_one_value))
1194        __(movl -node_size(%esp,%nargs),%arg_z)
1195        __(add %nargs,%esp)
1196local_label(_throw_one_value):
1197        __(movl $local_label(_threw_one_value),%ra0)
1198        __(jmp _SPnthrow1value)
1199__(tra(local_label(_threw_one_value)))
1200        __(movl rcontext(tcr.catch_top),%arg_y)
1201        __(movl catch_frame.db_link(%arg_y),%imm0)
1202        __(cmpl %imm0,rcontext(tcr.db_link))
1203        __(jz local_label(_threw_one_value_dont_unbind))
1204        __(push $local_label(_threw_one_value_dont_unbind))
1205        __(jmp _SPunbind_to)    /* preserves registers */
1206__(tra(local_label(_threw_one_value_dont_unbind)))
1207        __(movl catch_frame.ebp(%arg_y),%ebp)
1208        __(movl catch_frame.foreign_sp(%arg_y),%imm0)
1209        __(movl %imm0,rcontext(tcr.foreign_sp))
1210        __(movl catch_frame.xframe(%arg_y),%imm0)
1211        __(movl %imm0,rcontext(tcr.xframe))
1212        __(movl catch_frame.esp(%arg_y),%esp)
1213        __(movl catch_frame.link(%arg_y),%imm0)
1214        __(movl %imm0,rcontext(tcr.catch_top))
1215        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%arg_y),%imm0)
1216        __(movl (%imm0),%imm0)
1217        __(movl %imm0,rcontext(tcr.save_tsp))
1218        __(movl %imm0,rcontext(tcr.next_tsp))
1219        __(movl catch_frame.pc(%arg_y),%ra0)
1220        __(jmp *%ra0)
1221local_label(_throw_multiple):
1222        __(movl $local_label(_threw_multiple),%ra0)
1223        __(jmp _SPnthrowvalues)
1224__(tra(local_label(_threw_multiple)))
1225        __(movl rcontext(tcr.catch_top),%arg_y)
1226        __(movl catch_frame.db_link(%arg_y),%imm0)
1227        __(cmpl %imm0,rcontext(tcr.db_link))
1228        __(je local_label(_threw_multiple_dont_unbind))
1229        __(push $local_label(_threw_multiple_dont_unbind))
1230        __(jmp _SPunbind_to)    /* preserves registers */
1231__(tra(local_label(_threw_multiple_dont_unbind)))
1232        /* Copy multiple values from the current %esp to the target %esp   */
1233        __(lea (%esp,%nargs),%imm0)
1234        __(movd %nargs,%mm0)    /* nargs is aka temp1 */
1235        __(movl catch_frame.esp(%arg_y),%temp1)
1236        __(jmp local_label(_threw_multiple_push_test))
1237local_label(_threw_multiple_push_loop):
1238        __(subl $node_size,%imm0)
1239        __(subl $node_size,%temp1)
1240        __(movl (%imm0),%arg_z)
1241        __(movl %arg_z,(%temp1))
1242local_label(_threw_multiple_push_test):
1243        __(cmpl %imm0,%esp)
1244        __(jne local_label(_threw_multiple_push_loop))
1245        /* target %esp is now in %temp1   */
1246        __(movl catch_frame.ebp(%arg_y),%ebp)
1247        __(movl catch_frame.foreign_sp(%arg_y),%imm0)
1248        __(movl %imm0,rcontext(tcr.foreign_sp))       
1249        __(movl catch_frame.xframe(%arg_y),%imm0)
1250        __(movl %imm0,rcontext(tcr.xframe))
1251        __(movl %temp1,%esp)
1252        __(movl catch_frame.link(%arg_y),%temp1)
1253        __(movl %temp1,rcontext(tcr.catch_top))
1254        __(movd %mm0,%nargs)
1255        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%arg_y),%imm0)
1256        __(movl catch_frame.pc(%arg_y),%ra0)
1257        __(movl (%imm0),%imm0)
1258        __(movl %imm0,rcontext(tcr.save_tsp))
1259        __(movl %imm0,rcontext(tcr.next_tsp))
1260        __(jmp *%ra0)
1261_endsubp(throw)
1262
1263        /* This takes N multiple values atop the vstack.   */
1264_spentry(nthrowvalues)
1265        __(movb $1,rcontext(tcr.unwinding))
1266        __(movl %ra0,rcontext(tcr.save0)) /* %ra0 (aka %temp0) to spill area */
1267local_label(_nthrowv_nextframe):
1268        __(subl $fixnumone,%imm0)
1269        __(js local_label(_nthrowv_done))
1270        __(movd %imm0,%mm1)
1271        __(movl rcontext(tcr.catch_top),%temp0)
1272        __(movl catch_frame.link(%temp0),%imm0)
1273        __(movl %imm0,rcontext(tcr.catch_top))
1274        __(movl catch_frame.db_link(%temp0),%imm0)
1275        __(cmpl %imm0,rcontext(tcr.db_link))
1276        __(jz local_label(_nthrowv_dont_unbind))
1277        __(push %temp1)
1278        __(push %temp0)
1279        __(push $local_label(_nthrowv_back_from_unbind))
1280        __(jmp _SPunbind_to)
1281__(tra(local_label(_nthrowv_back_from_unbind)))
1282        __(pop %temp0)
1283        __(pop %temp1)
1284local_label(_nthrowv_dont_unbind):
1285        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1286        __(je local_label(_nthrowv_do_unwind))
1287/* A catch frame.  If the last one, restore context from there.   */
1288        __(movd %mm1,%imm0)
1289        __(test %imm0,%imm0)    /* last catch frame ?   */
1290        __(jne local_label(_nthrowv_skip))
1291        __(movl catch_frame.xframe(%temp0),%arg_y)
1292        __(movl %arg_y,rcontext(tcr.xframe))
1293        __(lea (%esp,%nargs),%arg_y)
1294        __(movl catch_frame.esp(%temp0),%arg_z)
1295        __(movd %nargs,%mm2)
1296        __(jmp local_label(_nthrowv_push_test))
1297local_label(_nthrowv_push_loop):
1298        __(subl $node_size,%arg_y)
1299        __(subl $node_size,%arg_z)
1300        __(movd (%arg_y),%mm0)
1301        __(movd %mm0,(%arg_z))
1302local_label(_nthrowv_push_test):
1303        __(subl $node_size,%nargs)
1304        __(jns local_label(_nthrowv_push_loop))
1305        __(movd %mm2,%nargs)
1306        __(movl catch_frame.xframe(%temp0),%arg_y)
1307        __(movl %arg_y,rcontext(tcr.xframe))
1308        __(movl %arg_z,%esp)
1309        __(movl catch_frame.ebp(%temp0),%ebp)
1310        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1311        __(movd %stack_temp,rcontext(tcr.foreign_sp))       
1312local_label(_nthrowv_skip):     
1313        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1314        __(movl %imm0,rcontext(tcr.save_tsp))
1315        __(movl %imm0,rcontext(tcr.next_tsp))
1316        __(movd %mm1,%imm0)
1317        __(jmp local_label(_nthrowv_nextframe))
1318local_label(_nthrowv_do_unwind):       
1319/* This is harder.  Call the cleanup code with the multiple values and   */
1320/* nargs, the throw count, and the caller's return address in a temp  */
1321/* stack frame.   */
1322        __(leal (%esp,%nargs),%arg_y)
1323        __(push catch_frame.pc(%temp0))
1324        __(movl catch_frame.ebp(%temp0),%ebp)
1325        __(movd catch_frame.xframe(%temp0),%stack_temp)
1326        __(movd %stack_temp,rcontext(tcr.xframe))
1327        __(movl catch_frame.esp(%temp0),%arg_z)
1328        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1329        __(movd %stack_temp,rcontext(tcr.foreign_sp))       
1330        /* Discard the catch frame, so we can build a temp frame   */
1331        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1332        __(movl %imm0,rcontext(tcr.save_tsp))
1333        __(movl %imm0,rcontext(tcr.next_tsp))
1334        __(movd %temp1,%mm2) /* save %nargs */
1335        /* tsp overhead, nargs, throw count, ra0   */
1336        __(dnode_align(%nargs,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1337        __(movl %imm0,%temp1)
1338        __(TSP_Alloc_Var(%temp1,%imm0))
1339        __(movd %mm2,%temp1) /* aka %nargs */
1340
1341        __(movl %nargs,(%imm0))
1342        __(movl rcontext(tcr.save0),%ra0)
1343        __(movl %ra0,node_size(%imm0))
1344        __(movd %mm1,node_size*2(%imm0))
1345        __(leal node_size*3(%imm0),%imm0)
1346        __(jmp local_label(_nthrowv_tpushtest))
1347local_label(_nthrowv_tpushloop):
1348        __(movl -node_size(%arg_y),%temp0)
1349        __(subl $node_size,%arg_y)
1350        __(movl %temp0,(%imm0))
1351        __(addl $node_size,%imm0)
1352local_label(_nthrowv_tpushtest):
1353        __(subl $node_size,%nargs)
1354        __(jns local_label(_nthrowv_tpushloop))
1355        __(pop %xfn)    /* aka %temp1/%nargs */
1356        __(movl %arg_z,%esp)
1357/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1358        __(push $local_label(_nthrowv_called_cleanup))
1359        __(movb $0,rcontext(tcr.unwinding))
1360        __(jmp *%xfn)
1361__(tra(local_label(_nthrowv_called_cleanup)))
1362
1363        __(movb $1,rcontext(tcr.unwinding))
1364        __(movl rcontext(tcr.save_tsp),%imm0)
1365        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%nargs)
1366        __(movl tsp_frame.data_offset+(1*node_size)(%imm0),%ra0)
1367        __(movl %ra0,rcontext(tcr.save0))
1368        __(movd tsp_frame.data_offset+(2*node_size)(%imm0),%mm1)
1369        __(movd %nargs,%mm2)
1370        __(addl $tsp_frame.fixed_overhead+(node_size*3),%imm0)
1371        __(jmp local_label(_nthrowv_tpoptest))
1372local_label(_nthrowv_tpoploop):
1373        __(push (%imm0))
1374        __(addl $node_size,%imm0)
1375local_label(_nthrowv_tpoptest):
1376        __(subl $node_size,%nargs)
1377        __(jns local_label(_nthrowv_tpoploop))
1378        __(movd %mm2,%nargs)
1379        __(movl rcontext(tcr.save_tsp),%imm0)
1380        __(movl (%imm0),%imm0)
1381        __(movl %imm0,rcontext(tcr.save_tsp))
1382        __(movl %imm0,rcontext(tcr.next_tsp))
1383        __(movd %mm1,%imm0)
1384        __(jmp local_label(_nthrowv_nextframe))
1385local_label(_nthrowv_done):
1386        __(movb $0,rcontext(tcr.unwinding))
1387        __(check_pending_interrupt(%imm0))
1388local_label(_nthrowv_return):
1389        __(movl rcontext(tcr.save0),%ra0)
1390        __(movss %fpzero,rcontext(tcr.save0))
1391        __(jmp *%ra0)   
1392_endsubp(nthrowvalues)
1393
1394/* This is a (slight) optimization.  When running an unwind-protect,  */
1395/* save the single value and the throw count in the tstack frame.  */
1396/* Note that this takes a single value in arg_z.  */
1397
1398_spentry(nthrow1value)
1399        __(movb $1,rcontext(tcr.unwinding))
1400local_label(_nthrow1v_nextframe):
1401        __(subl $fixnumone,%imm0)
1402        __(js local_label(_nthrow1v_done))
1403        __(movd %imm0,%mm0)
1404        __(movl rcontext(tcr.catch_top),%temp1)
1405        __(movl catch_frame.link(%temp1),%imm0)
1406        __(movl %imm0,rcontext(tcr.catch_top))
1407        __(movl catch_frame.db_link(%temp1),%imm0)
1408        __(cmpl %imm0,rcontext(tcr.db_link))
1409        __(jz local_label(_nthrow1v_dont_unbind))
1410        __(push %temp1)
1411        __(push %temp0)
1412        __(push %arg_z)
1413        __(push [$]local_label(_nthrow1v_back_from_unbind))
1414        __(jmp _SPunbind_to)
1415__(tra(local_label(_nthrow1v_back_from_unbind)))
1416        __(pop %arg_z)
1417        __(pop %temp0)
1418        __(pop %temp1)
1419local_label(_nthrow1v_dont_unbind):
1420        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp1))
1421        __(je local_label(_nthrow1v_do_unwind))
1422/* A catch frame.  If the last one, restore context from there. */
1423        __(movd %mm0,%imm0)
1424        __(test %imm0,%imm0)    /* last catch frame? */
1425        __(jne local_label(_nthrow1v_skip))
1426        __(movl catch_frame.xframe(%temp1),%arg_y)
1427        __(movl %arg_y,rcontext(tcr.xframe))
1428        __(movl catch_frame.esp(%temp1),%esp)
1429        __(movl catch_frame.ebp(%temp1),%ebp)
1430        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1431        __(movd %stack_temp,rcontext(tcr.foreign_sp))
1432local_label(_nthrow1v_skip):
1433        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1434        __(movl %imm0,rcontext(tcr.save_tsp))
1435        __(movl %imm0,rcontext(tcr.next_tsp))
1436        __(movd %mm0,%imm0)
1437        __(jmp local_label(_nthrow1v_nextframe))
1438local_label(_nthrow1v_do_unwind):
1439/* This is harder, but not as hard (not as much BLTing) as the */
1440/* multiple-value case. */
1441        __(movl catch_frame.xframe(%temp1),%arg_y)
1442        __(movl %arg_y,rcontext(tcr.xframe))
1443        __(movl catch_frame.ebp(%temp1),%ebp)
1444        __(movl catch_frame.esp(%temp1),%esp)
1445        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1446        __(movd %stack_temp,rcontext(tcr.foreign_sp))
1447        /* Discard the catch frame so we can build a temp frame. */
1448        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1449        __(movl %imm0,rcontext(tcr.save_tsp))
1450        __(movl %imm0,rcontext(tcr.next_tsp))
1451        __(movl catch_frame.pc(%temp1),%xfn) /* xfn is temp1 */
1452        __(TSP_Alloc_Fixed((3*node_size),%imm0))
1453        __(addl $tsp_frame.fixed_overhead,%imm0)
1454        __(movl %ra0,(%imm0))
1455        __(movd %mm0,node_size*1(%imm0))
1456        __(movl %arg_z,node_size*2(%imm0))
1457/* Ready to call cleanup code.  Set up tra, jmp to %xfn. */
1458        __(push $local_label(_nthrow1v_called_cleanup))
1459        __(movb $0,rcontext(tcr.unwinding))
1460        __(jmp *%xfn)
1461__(tra(local_label(_nthrow1v_called_cleanup)))
1462        __(movb $1,rcontext(tcr.unwinding))
1463        __(movl rcontext(tcr.save_tsp),%imm0)
1464        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%ra0)
1465        __(movd tsp_frame.data_offset+(1*node_size)(%imm0),%mm0)
1466        __(movl tsp_frame.data_offset+(2*node_size)(%imm0),%arg_z)
1467        __(movl (%imm0),%imm0)
1468        __(movl %imm0,rcontext(tcr.save_tsp))
1469        __(movl %imm0,rcontext(tcr.next_tsp))
1470        __(movd %mm0,%imm0)
1471        __(jmp local_label(_nthrow1v_nextframe))
1472local_label(_nthrow1v_done):
1473        __(movb $0,rcontext(tcr.unwinding))
1474        __(check_pending_interrupt(%imm0))
1475local_label(_nthrow1v_return):
1476        __(jmp *%ra0)
1477_endsubp(nthrow1value)
1478
1479/* This never affects the symbol's vcell   */
1480/* Non-null symbol in arg_y, new value in arg_z           */
1481
1482_spentry(bind)
1483        __(movl symbol.binding_index(%arg_y),%imm0)
1484        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1485        __(jb 0f)
1486        __(push %imm0)
1487        __(tlb_too_small())
14880:      __(test %imm0,%imm0)
1489        __(jz 9f)
1490        __(movl rcontext(tcr.tlb_pointer),%temp1)
1491        __(push (%temp1,%imm0))
1492        __(push %imm0)
1493        __(push rcontext(tcr.db_link))
1494        __(movl %esp,rcontext(tcr.db_link))
1495        __(movl %arg_z,(%temp1,%imm0))
1496        __(jmp *%ra0)
14979:     
1498        __(movl %arg_y,%arg_z)
1499        __(movl $XSYMNOBIND,%arg_y)
1500        __(set_nargs(2))
1501        __(push %ra0)
1502        __(jmp _SPksignalerr)
1503_endsubp(bind)
1504
1505/* arg_z = symbol: bind it to its current value  */
1506
1507_spentry(bind_self)
1508        __(movl symbol.binding_index(%arg_z),%imm0)
1509        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1510        __(jb 0f)
1511        __(push %imm0)
1512        __(tlb_too_small())
15130:      __(test %imm0,%imm0)
1514        __(jz 9f)
1515        __(movl rcontext(tcr.tlb_pointer),%temp1)
1516        __(cmpb $no_thread_local_binding_marker,(%temp1,%imm0))
1517        __(jz 2f)
1518        __(push (%temp1,%imm0))
1519        __(push %imm0)
1520        __(push rcontext(tcr.db_link))
1521        __(movl %esp,rcontext(tcr.db_link))
1522        __(jmp *%ra0)
15232:      __(movl symbol.vcell(%arg_z),%arg_y)
1524        __(push (%temp1,%imm0))
1525        __(push %imm0)
1526        __(push rcontext(tcr.db_link))
1527        __(movl %arg_y,(%temp1,%imm0))
1528        __(movl %esp,rcontext(tcr.db_link))
1529        __(jmp *%ra0)
15309:      __(movl $XSYMNOBIND,%arg_y)
1531        __(set_nargs(2))
1532        __(push %ra0)
1533        __(jmp _SPksignalerr)
1534_endsubp(bind_self)
1535
1536_spentry(bind_nil)
1537        __(movl symbol.binding_index(%arg_z),%imm0)
1538        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1539        __(jb 0f)
1540        __(push %imm0)
1541        __(tlb_too_small())
15420:      __(test %imm0,%imm0)
1543        __(jz 9f)
1544        __(movl rcontext(tcr.tlb_pointer),%temp1)
1545        __(push (%temp1,%imm0))
1546        __(push %imm0)
1547        __(push rcontext(tcr.db_link))
1548        __(movl %esp,rcontext(tcr.db_link))
1549        __(movl $nil_value,(%temp1,%imm0))
1550        __(jmp *%ra0)
15519:      __(movl $XSYMNOBIND,%arg_y)
1552        __(set_nargs(2))
1553        __(push %ra0)
1554        __(jmp _SPksignalerr)
1555_endsubp(bind_nil)
1556
1557_spentry(bind_self_boundp_check)
1558        __(movl symbol.binding_index(%arg_z),%imm0)
1559        __(cmpl rcontext(tcr.tlb_limit),%imm0)
1560        __(jb 0f)
1561        __(push %imm0)
1562        __(tlb_too_small())
15630:      __(test %imm0,%imm0)
1564        __(jz 9f)
1565        __(movl rcontext(tcr.tlb_pointer),%temp1)
1566        __(cmpb $no_thread_local_binding_marker,(%temp1,%imm0))
1567        __(je 2f)
1568        __(cmpb $unbound_marker,(%temp1,%imm0))
1569        __(je 8f)
1570        __(push (%temp1,%imm0))
1571        __(push %imm0)
1572        __(push rcontext(tcr.db_link))
1573        __(movl %esp,rcontext(tcr.db_link))
1574        __(jmp *%ra0)
15752:      __(movl symbol.vcell(%arg_z),%arg_y)
1576        __(cmpl $unbound_marker,%arg_y)
1577        __(jz 8f)
1578        __(push (%temp1,%imm0))
1579        __(push %imm0)
1580        __(push rcontext(tcr.db_link))
1581        __(movl %esp,rcontext(tcr.db_link))
1582        __(movl %arg_y,(%temp1,%imm0))
1583        __(jmp *%ra0)
15848:      __(push %ra0)
1585        __(uuo_error_reg_unbound(Rarg_z))
1586       
15879:      __(movl $XSYMNOBIND,%arg_y)
1588        __(set_nargs(2))
1589        __(push %ra0)
1590        __(jmp _SPksignalerr)
1591_endsubp(bind_self_boundp_check)
1592
1593_spentry(conslist)
1594        __(movl %nargs,%imm0)
1595        __(movl %temp0,%temp1)  /* have to use temp0 for consing */
1596        __(movl $nil_value,%arg_z)
1597        __(test %imm0,%imm0)
1598        __(jmp 2f)
15991:      __(pop %arg_y)
1600        __(Cons(%arg_y,%arg_z,%arg_z))
1601        __(subl $node_size,%imm0)
16022:      __(jnz 1b)
1603        __(jmp *%temp1)
1604_endsubp(conslist)
1605
1606/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1607/* Cons, one cons cell at at time.  Maybe optimize this later.  */
1608
1609_spentry(conslist_star)
1610        __(movl %nargs,%imm0)
1611        __(test %imm0,%imm0)
1612        __(movl %ra0,%temp1)
1613        __(jmp 2f)
16141:      __(pop %arg_y)
1615        __(Cons(%arg_y,%arg_z,%arg_z))
1616        __(subl $node_size,%imm0)
16172:      __(jnz 1b)
1618        __(jmp *%temp1)
1619_endsubp(conslist_star)
1620
1621/* We always have to create a tsp frame (even if nargs is 0), so the compiler */
1622/* doesn't get confused. */
1623_spentry(stkconslist)
1624        __(movl $nil_value,%arg_z)
1625C(stkconslist_common):               
1626        __(movl %ra0,rcontext(tcr.save0))
1627        __(movd %nargs,%mm0)
1628        __(movl %nargs,%temp0)
1629        __(addl %temp0,%temp0)
1630        __(dnode_align(%temp0,tsp_frame.fixed_overhead,%temp0))
1631        __(TSP_Alloc_Var(%temp0,%imm0))
1632        __(addl $fulltag_cons,%imm0)
1633        __(test %nargs,%nargs)
1634        __(jmp 2f)
16351:      __(pop %arg_y)
1636        __(_rplaca(%imm0,%arg_y))
1637        __(_rplacd(%imm0,%arg_z))
1638        __(movl %imm0,%arg_z)
1639        __(add $cons.size,%imm0)
1640        __(subl $node_size,%nargs)
16412:      __(jne 1b)
1642        __(movl rcontext(tcr.save0),%ra0)
1643        __(movl $0,rcontext(tcr.save0))
1644        __(jmp *%ra0)
1645_endsubp(stkconslist)
1646
1647/* do list*: last arg in arg_z, all others vpushed,   */
1648/*      nargs set to #args vpushed.  */
1649
1650_spentry(stkconslist_star)
1651        __(jmp C(stkconslist_common))
1652_endsubp(stkconslist_star)
1653
1654
1655/* Make a stack-consed simple-vector out of the NARGS objects   */
1656/*      on top of the vstack; return it in arg_z.  */
1657
1658_spentry(mkstackv)
1659        __(dnode_align(%nargs,tsp_frame.fixed_overhead+node_size,%imm0))
1660        __(TSP_Alloc_Var(%imm0,%arg_y))
1661        __(movl %nargs,%imm0)
1662        __(shll $(num_subtag_bits-fixnumshift),%imm0)
1663        __(movb $subtag_simple_vector,%imm0_b)
1664        __(movl %imm0,(%arg_y))
1665        __(leal fulltag_misc(%arg_y),%arg_z)
1666        __(test %nargs,%nargs)
1667        __(leal misc_data_offset(%arg_z,%nargs),%imm0)
1668        __(jmp 2f)
16691:      __(pop -node_size(%imm0))
1670        __(subl $node_size,%nargs)
1671        __(leal -node_size(%imm0),%imm0)
16722:      __(jne 1b)
1673        __(jmp *%ra0)   
1674_endsubp(mkstackv)
1675
1676        .globl C(egc_write_barrier_start)
1677C(egc_write_barrier_start):
1678/*  */
1679/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1680/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1681/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1682/* an intergenerational reference (a young pointer stored in an old object) has  */
1683/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1684/* This has to happen atomically, and has to happen atomically wrt GC.  */
1685
1686/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1687/* interlocked loads and stores.  */
1688
1689/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1690/* in the function, we can do the store (even if it's already been done) and  */
1691/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1692/* setting the bit needs to be done atomically, unless we're sure that other  */
1693/* threads are suspended.)  */
1694/* We can unconditionally set the suspended thread's RIP to the return address.  */
1695
1696_spentry(rplaca)
1697        .globl C(egc_rplaca)
1698C(egc_rplaca):
1699        __(rcmpl(%arg_z,%arg_y))
1700        __(_rplaca(%arg_y,%arg_z))
1701        __(ja 1f)
17020:      __(repret)
17031:      __(movl %arg_y,%imm0)
1704        __(subl lisp_global(heap_start),%imm0)
1705        __(shrl $dnode_shift,%imm0)
1706        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1707        __(jae 0b)
1708        __(ref_global(refbits,%temp0))
1709        __(xorb $31,%imm0_b)
1710        __(lock)
1711        __(btsl %imm0,(%temp0))
1712        __(ret)
1713_endsubp(rplaca)
1714
1715_spentry(rplacd)
1716        .globl C(egc_rplacd)
1717C(egc_rplacd):
1718        __(rcmpl(%arg_z,%arg_y))
1719        __(_rplacd(%arg_y,%arg_z))
1720        __(ja 1f)
17210:      __(repret)
17221:      __(movl %arg_y,%imm0)
1723        __(subl lisp_global(heap_start),%imm0)
1724        __(shrl $dnode_shift,%imm0)
1725        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1726        __(jae 0b)
1727        __(ref_global(refbits,%temp0))
1728        __(xorb $31,%imm0_b)
1729        __(lock)
1730        __(btsl %imm0,(%temp0))
1731        __(ret)
1732_endsubp(rplacd)
1733
1734/* Storing into a gvector can be handled the same way as storing into a CONS. */
1735/* args (src, unscaled-idx, val) in temp0, arg_y, arg_z */
1736_spentry(gvset)
1737        .globl C(egc_gvset)
1738C(egc_gvset):
1739        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1740        __(rcmpl(%arg_z,%temp0))
1741        __(ja 1f)
17420:      __(repret)
17431:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1744        __(subl lisp_global(heap_start),%imm0)
1745        __(shrl $dnode_shift,%imm0)
1746        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1747        __(jae 0b)
1748        __(ref_global(refbits,%temp1))
1749        __(xorb $31,%imm0_b)
1750        __(lock)
1751        __(btsl %imm0,(%temp1))
1752        __(ret)
1753_endsubp(gvset)
1754
1755/* This is a special case of storing into a gvector: if we need to  */
1756/* memoize the store, record the address of the hash-table vector  */
1757/* in the refmap, as well.  */
1758
1759_spentry(set_hash_key)
1760        .globl C(egc_set_hash_key)
1761C(egc_set_hash_key):
1762        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1763        __(rcmpl(%arg_z,%temp0))
1764        __(ja 1f)
17650:      __(repret)
17661:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1767        __(subl lisp_global(heap_start),%imm0)
1768        __(shrl $dnode_shift,%imm0)
1769        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1770        __(jae 0b)
1771        __(ref_global(refbits,%temp1))
1772        __(xorb $31,%imm0_b)
1773        __(lock)
1774        __(btsl %imm0,(%temp1))
1775        /* Now memoize the address of the hash vector */
1776        __(movl %temp0,%imm0)
1777        __(subl lisp_global(heap_start),%imm0)
1778        __(shrl $dnode_shift,%imm0)
1779        __(xorb $31,%imm0_b)
1780        __(lock)
1781        __(btsl %imm0,(%temp1))
1782        __(ret)
1783_endsubp(set_hash_key)
1784
1785/* This is a little trickier: if this is interrupted, we need to know  */
1786/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1787/* If we're interrupted   before the PC has reached the "success_test" label, */
1788/* repeat (luser the PC back to store_node_conditional_retry.)  If
1789        we're at that */
1790/* label with the Z flag set, we won and (may) need to memoize.  */
1791
1792/* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1793_spentry(store_node_conditional)
1794        .globl C(egc_store_node_conditional)
1795C(egc_store_node_conditional):
1796        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1797        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
1798        .globl C(egc_store_node_conditional_retry)
1799C(egc_store_node_conditional_retry):     
18000:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
1801        __(movl misc_data_offset(%temp1,%temp0),%imm0)
1802        __(jne 3f)
1803        __(lock)
1804        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1805        .globl C(egc_store_node_conditional_success_test)
1806C(egc_store_node_conditional_success_test):
1807        __(jne 0b)
1808        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1809        __(subl lisp_global(heap_start),%imm0)
1810        __(shrl $dnode_shift,%imm0)
1811        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1812        __(jae 2f)
1813        __(ref_global(refbits,%temp1))
1814        __(xorb $31,%imm0_b)
1815        __(lock)
1816        __(btsl %imm0,(%temp1))
1817        .globl C(egc_store_node_conditional_success_end)
1818C(egc_store_node_conditional_success_end):
18192:      __(movl $t_value,%arg_z)
1820        __(ret)
18213:      __(movl $nil_value,%arg_z)
1822        __(ret)
1823_endsubp(store_node_conditional)
1824
1825        /* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1826_spentry(set_hash_key_conditional)
1827        .globl C(egc_set_hash_key_conditional)
1828C(egc_set_hash_key_conditional):
1829        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1830        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
1831        .globl C(egc_set_hash_key_conditional_retry)
1832C(egc_set_hash_key_conditional_retry):         
18330:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
1834        __(movl misc_data_offset(%temp1,%temp0),%imm0)
1835        __(jne 3f)
1836        __(lock)
1837        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1838        .globl C(egc_set_hash_key_conditional_success_test)
1839C(egc_set_hash_key_conditional_success_test):
1840        __(jne 0b)
1841        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1842        __(subl lisp_global(heap_start),%imm0)
1843        __(shrl $dnode_shift,%imm0)
1844        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1845        __(jae 2f)
1846        __(ref_global(refbits,%temp0))
1847        __(xorb $31,%imm0_b)
1848        __(lock)
1849        __(btsl %imm0,(%temp0))
1850        /* Now memoize the address of the hash vector */
1851        __(movl %temp1,%imm0)
1852        __(subl lisp_global(heap_start),%imm0)
1853        __(shrl $dnode_shift,%imm0)
1854        __(xorb $31,%imm0_b)
1855        __(lock)
1856        __(btsl %imm0,(%temp0))
1857        .globl C(egc_write_barrier_end)
1858C(egc_write_barrier_end):
18592:      __(movl $t_value,%arg_z)
1860        __(ret)
18613:      __(movl $nil_value,%arg_z)
1862        __(ret)
1863_endsubp(store_node_conditional)
1864
1865_spentry(setqsym)
1866        __(bt $sym_vbit_const,symbol.flags(%arg_y))
1867        __(jae _SPspecset)
1868        __(mov %arg_y,%arg_z)
1869        __(mov $XCONST,%arg_y)
1870        __(set_nargs(2))
1871        __(jmp _SPksignalerr)
1872_endsubp(setqsym)
1873
1874_spentry(progvsave)
1875        __(push %arg_y)
1876       
1877        /* Error if arg_z isn't a proper list.  That's unlikely,  */
1878        /* but it's better to check now than to crash later.  */
1879       
1880        __(compare_reg_to_nil(%arg_z))
1881        __(movl %arg_z,%temp0)  /* fast   */
1882        __(movl %arg_z,%temp1)  /* slow   */
1883        __(je 9f)               /* Null list is proper   */
18840:
1885        __(extract_lisptag(%temp0,%imm0))
1886        __(cmpb $tag_list,%imm0_b)
1887        __(jne 8f)
1888        __(compare_reg_to_nil(%temp0))
1889        __(je 9f)
1890        __(_cdr(%temp0,%arg_y)) /* (null (cdr fast)) ?   */
1891        __(compare_reg_to_nil(%arg_y))
1892        __(je 9f)
1893        __(extract_lisptag(%arg_y,%imm0))
1894        __(cmpb $tag_list,%imm0_b)
1895        __(jne 8f)
1896        __(_cdr(%arg_y,%temp0))
1897        __(_cdr(%temp1,%temp1))
1898        __(cmpl %temp1,%temp0)
1899        __(jne 0b)
1900
19018:      __(add $node_size,%esp) /* discard pushed arg_y */
1902        __(movl $XIMPROPERLIST,%arg_y)
1903        __(set_nargs(2))
1904        __(jmp _SPksignalerr)
19059:      /* Whew           */
1906
1907        /* Next, determine the length of arg_y.  We   */
1908        /* know that it's a proper list.   */
1909        __(pop %arg_y)
1910       
1911        __(movl $-fixnumone,%imm0)
1912        __(movl %arg_y,%temp0)
19131:      __(compare_reg_to_nil(%temp0))
1914        __(_cdr(%temp0,%temp0))
1915        __(leal fixnumone(%imm0),%imm0)
1916        __(jne 1b)
1917       
1918        /* imm0 is now (boxed) triplet count.  */
1919        /* Determine word count, add 1 (to align), and make room.  */
1920        /*  if count is 0, make an empty tsp frame and exit   */
1921        __(testl %imm0,%imm0)
1922        __(jne 2f)
1923        __(TSP_Alloc_Fixed(2*node_size,%imm0))
1924        __(ret)
19252:      __(movl %imm0,%temp1)
1926        __(add %imm0,%imm0)
1927        __(add %temp1,%imm0)
1928        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1929        __(TSP_Alloc_Var(%imm0,%temp0))
1930        __(movl %temp1,(%temp0))
1931        __(movd rcontext(tcr.db_link),%mm0)
19323:      __(movl $unbound_marker,%temp0)
1933        __(compare_reg_to_nil(%arg_z))
1934        __(cmovnel cons.car(%arg_z),%temp0)
1935        __(cmovnel cons.cdr(%arg_z),%arg_z)
1936        __(_car(%arg_y,%temp1))
1937        __(_cdr(%arg_y,%arg_y))
1938        __(movl symbol.binding_index(%temp1),%temp1)
1939        __(cmp rcontext(tcr.tlb_limit),%temp1)
1940        __(jb 4f)
1941        __(push %temp1)
1942        __(tlb_too_small())
19434:      __(push %arg_z)
1944        __(movl rcontext(tcr.tlb_pointer),%arg_z)
1945        __(subl $binding.size,%imm0)
1946        __(movl %temp1,binding.sym(%imm0))
1947        __(push (%arg_z,%temp1))
1948        __(pop binding.val(%imm0))
1949        __(movl %temp0,(%arg_z,%temp1))
1950        __(pop %arg_z)
1951        __(movd %mm0,binding.link(%imm0))
1952        __(movd %imm0,%mm0)
1953        __(compare_reg_to_nil(%arg_y))
1954        __(jne 3b)
1955        __(movd %mm0,rcontext(tcr.db_link))
1956        __(ret)
1957_endsubp(progvsave)
1958
1959/* Allocate node objects on the temp stack, immediate objects on the foreign  */
1960/* stack. (The caller has to know which stack to discard a frame from.)  */
1961/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
1962
1963_spentry(stack_misc_alloc)
1964        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
1965        __(jne local_label(stack_misc_alloc_not_u24))
1966        __(unbox_fixnum(%arg_z,%imm0))
1967        __(mov %arg_y,%temp0)
1968        __(shl $num_subtag_bits-fixnumshift,%temp0)
1969        __(or %temp0,%imm0)     /* %imm0 now = header */
1970        __(movd %imm0,%mm0)     /* cache header in %mm0 */
1971        __(andb $fulltagmask,%imm0_b)
1972        __(cmpb $fulltag_nodeheader,%imm0_b)
1973        __(je local_label(stack_misc_alloc_node))
1974        __(movd %mm0,%imm0)
1975        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
1976        __(jbe local_label(stack_misc_alloc_32))
1977        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
1978        __(jbe local_label(stack_misc_alloc_8))
1979        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
1980        __(jbe local_label(stack_misc_alloc_16))
1981        __(cmpb $subtag_double_float_vector,%imm0_b)
1982        __(jne local_label(stack_misc_alloc_1))
1983        /* double-float vector case */
1984        __(imul $2,%arg_y,%imm0)
1985        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1986local_label(stack_misc_alloc_1):
1987        __(unbox_fixnum(%arg_y,%imm0))
1988        __(addl $7,%imm0)
1989        __(shrl $3,%imm0)
1990        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1991local_label(stack_misc_alloc_8):
1992        __(unbox_fixnum(%arg_y,%imm0))
1993        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1994local_label(stack_misc_alloc_16):
1995        __(unbox_fixnum(%arg_y,%imm0))
1996        __(shl $1,%imm0)
1997        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1998local_label(stack_misc_alloc_32):
1999        __(mov %arg_y,%imm0)
2000local_label(stack_misc_alloc_alloc_ivector):
2001        /* byte count in %imm0 */
2002        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
2003        __(cmpl $tstack_alloc_limit,%imm0)
2004        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
2005        __(movd rcontext(tcr.foreign_sp),%stack_temp)
2006        __(movd %stack_temp,%temp1)
2007        __(subl %imm0,rcontext(tcr.foreign_sp))
2008        __(movl rcontext(tcr.foreign_sp),%temp0)
20090:      __(movsd %fpzero,-dnode_size(%temp1))
2010        __(subl $dnode_size,%temp1)
2011        __(cmpl %temp1,%temp0)
2012        __(jnz 0b)
2013        __(movd %stack_temp,(%temp0))
2014        __(movl %ebp,csp_frame.save_ebp(%temp0))
2015        __(movd %mm0,csp_frame.fixed_overhead(%temp0))
2016        __(lea csp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
2017        __(ret)
2018local_label(stack_misc_alloc_heap_alloc_ivector):
2019        __(movd rcontext(tcr.foreign_sp),%stack_temp)
2020        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2021        __(movl rcontext(tcr.foreign_sp),%imm0)
2022        __(movd %stack_temp,(%imm0))
2023        __(jmp _SPmisc_alloc)
2024local_label(stack_misc_alloc_node):
2025        __(movl %arg_y,%imm0)
2026        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
2027        __(cmpl $tstack_alloc_limit,%imm0)
2028        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
2029        __(TSP_Alloc_Var(%imm0,%temp1))
2030        __(movd %mm0,(%temp1))
2031        __(leal fulltag_misc(%temp1),%arg_z)
2032        __(ret)
2033local_label(stack_misc_alloc_heap_alloc_gvector):
2034        __(TSP_Alloc_Fixed(0,%imm0))
2035        __(jmp _SPmisc_alloc)
2036
2037local_label(stack_misc_alloc_not_u24):
2038        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2039_endsubp(stack_misc_alloc)
2040
2041/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of */
2042/* initial-contents.  Note that this can be used to cons any type of */
2043/* initialized node-header'ed misc object (symbols, closures, ...) */
2044/* as well as vector-like objects. */
2045_spentry(gvector)
2046        __(subl $node_size,%nargs)      /* off by one in x862-%gvector */
2047        __(movl (%esp,%nargs),%imm0)    /* boxed subtype */
2048        __(sarl $fixnumshift,%imm0)
2049        __(movl %nargs,%arg_z)
2050        __(shll $num_subtag_bits-word_shift,%arg_z)
2051        __(orl %arg_z,%imm0)
2052        __(movd %imm0,%mm0)
2053        __(dnode_align(%nargs,node_size,%imm0))
2054        __(push %ra0)   /* aka %temp0, can't be live while consing */
2055        __(Misc_Alloc(%arg_z))
2056        __(pop %ra0)
2057        __(movl %nargs,%imm0)
2058        __(jmp 2f)
20591:      __(movl %arg_y,misc_data_offset(%arg_z,%imm0))
20602:      __(subl $node_size,%imm0)
2061        __(pop %arg_y)  /* Note the intentional fencepost: */
2062                        /* discard the subtype as well. */
2063        __(jge 1b)
2064        __(jmp *%ra0)
2065_endsubp(gvector)
2066
2067_spentry(mvpass)
2068        __(hlt)
2069_endsubp(mvpass)
2070
2071_spentry(nthvalue)
2072        __(hlt)
2073_endsubp(nthvalue)
2074
2075_spentry(values)
2076        __(movl (%temp0),%arg_y)        /* return address */
2077        __(ref_global(ret1val_addr,%imm0))
2078        __(movl $nil_value,%arg_z)
2079        __(cmpl %imm0,%arg_y)
2080        __(je 0f)
2081        __(test %nargs,%nargs)
2082        __(cmovne -node_size(%esp,%nargs),%arg_z)
2083        __(movl %temp0,%esp)
2084        __(ret)
20850:      __(movl 4(%temp0),%arg_y)
2086        __(addl $2*node_size,%temp0)
2087        __(lea (%esp,%nargs),%imm0)
2088        __(movd %nargs,%mm0)
2089        __(jmp 2f)
20901:      __(subl $node_size,%imm0)
2091        __(movl (%imm0),%temp1)
2092        __(subl $node_size,%temp0)
2093        __(movl %temp1,(%temp0))
20942:      __(cmp %imm0,%esp)
2095        __(jne 1b)
2096        __(movl %temp0,%esp)
2097        __(movd %mm0,%nargs)
2098        __(jmp *%arg_y)
2099
2100_endsubp(values)
2101
2102_spentry(default_optional_args)
2103        __(hlt)
2104_endsubp(default_optional_args)
2105
2106_spentry(opt_supplied_p)
2107        __(hlt)
2108_endsubp(opt_supplied_p)
2109
2110_spentry(lexpr_entry)
2111        __(hlt)
2112_endsubp(lexpr_entry)
2113
2114_spentry(heap_rest_arg)
2115        __(push_argregs())
2116        __(movl %temp0,%arg_y)
2117        __(movl %nargs,%imm0)
2118        __(testl %imm0,%imm0)
2119        __(movl $nil_value,%arg_z)
2120        __(jmp 2f)
2121        .p2align 4
21221:      __(pop %temp1)
2123        __(Cons(%temp1,%arg_z,%arg_z))
2124        __(subl $node_size,%imm0)
21252:      __(jg 1b)
2126        __(push %arg_z)
2127        __(movl %arg_y,%temp0)
2128        __(jmp *%ra0)
2129
2130_endsubp(heap_rest_arg)
2131
2132/* %imm0 contains the number of fixed args; make an &rest arg out of */
2133/* the others. */
2134_spentry(req_heap_rest_arg)
2135        __(push_argregs())
2136        __(movd %nargs,%mm0)
2137        __(subl %imm0,%nargs)
2138        __(movl %nargs,%imm0)
2139        __(movl %temp0,%temp1)
2140        __(movl $nil_value,%arg_z)
2141        __(jmp 2f)
2142        .p2align 4
21431:      __(pop %arg_y)
2144        __(Cons(%arg_y,%arg_z,%arg_z))
2145        __(subl $node_size,%imm0)
21462:      __(jg 1b)
2147        __(push %arg_z)
2148        __(movl %temp1,%temp0)
2149        __(movd %mm0,%nargs)
2150        __(jmp *%ra0)
2151_endsubp(req_heap_rest_arg)
2152
2153/* %imm0 bytes of stuff has already been pushed   */
2154/* make an &rest arg out of any others   */
2155_spentry(heap_cons_rest_arg)
2156        __(movd %nargs,%mm0)
2157        __(subl %imm0,%nargs)
2158        __(movl %nargs,%imm0)
2159        __(movl $nil_value,%arg_z)
2160        __(movl %ra0,%arg_y)    /* temp0 can't be live while consing */
2161        __(jmp 2f)              /* (did I mention that already?) */
2162        .p2align 4
21631:      __(pop %temp1)
2164        __(Cons(%temp1,%arg_z,%arg_z))
2165        __(subl $node_size,%imm0)
21662:      __(jg 1b)
2167        __(push %arg_z)
2168        __(movd %mm0,%nargs)
2169        __(jmp *%arg_y)
2170_endsubp(heap_cons_rest_arg)
2171
2172_spentry(simple_keywords)
2173        __(xor %imm0,%imm0)
2174        __(push_argregs())
2175        __(jmp _SPkeyword_bind)
2176_endsubp(simple_keywords)
2177
2178_spentry(keyword_args)
2179        __(push_argregs())
2180        __(jmp _SPkeyword_bind)
2181_endsubp(keyword_args)
2182
2183/* There are %nargs words of arguments on the stack; %imm0 contains the */
2184/* number of non-keyword args pushed.  It's possible that we never actually */
2185/* got any keyword args, which would make things much simpler. */
2186
2187/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
2188/* indicating whether &allow-other-keys and/or &rest was present in the */
2189/* lambda list. */
2190
2191/* Once we get here, we can use the arg registers. */
2192
2193/* N.B.: %ra0 is %temp0, and must not be clobbered. */
2194
2195define([keyword_flags_aok_bit],[16])
2196define([keyword_flags_unknown_keys_bit],[17])
2197define([keyword_flags_rest_bit],[18])
2198define([keyword_flags_seen_aok_bit],[19])
2199
2200_spentry(keyword_bind)
2201        __(movl %temp1,rcontext(tcr.unboxed0))  /* save keyword flags */
2202        __(movzwl %nargs_w,%nargs)
2203        __(movl %nargs,%arg_z)
2204        __(subl %imm0,%arg_z)
2205        __(jbe local_label(no_keyword_values))
2206        __(btl $word_shift,%arg_z)
2207        __(jnc local_label(even))
2208        __(movl $nil_value,%arg_y)
2209        __(movl %arg_z,%nargs)
2210        __(test %nargs,%nargs)
2211        __(movl %ra0,rcontext(tcr.save0))       /* save temp0 while consing */
2212        __(jmp 1f)
22130:      __(pop %arg_z)
2214        __(Cons(%arg_z,%arg_y,%arg_y))
2215        __(subl $node_size,%nargs)
22161:      __(jnz 0b)
2217        __(movl rcontext(tcr.save0),%ra0)
2218        __(movapd %fpzero,rcontext(tcr.save0))
2219        __(movl %arg_y,%arg_z)
2220        __(movl $XBADKEYS,%arg_y)
2221        __(set_nargs(2))
2222        __(jmp _SPksignalerr)
2223
2224        /* Now that we're sure that we have an even number of */
2225        /* keywords and values (in %arg_z), move the pairs over */
2226        /* to the temp stack. */
2227local_label(even):
2228        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
2229        __(TSP_Alloc_Var(%arg_y,%imm0))
22302:      __(subl $node_size,%arg_y)
2231        __(pop (%arg_y))
2232        __(cmpl %arg_y,%imm0)
2233        __(jne 2b)
2234
2235        /* Get the keyword vector into %arg_y, and its length into %imm0. */
2236        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
2237        /* for each declared keyword. */
2238        __(movzwl misc_data_offset(%fn),%imm0)
2239        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2240        __(vector_length(%arg_y,%imm0))
2241        __(jmp 4f)
22423:      __(push $nil_value)
2243        __(push $nil_value)
22444:      __(subl $fixnumone,%imm0)
2245        __(jge 3b)
2246
2247        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
2248        /* in order to get a couple more registers to work with. */
2249        __(push %ra0)
2250        __(push %nargs)
2251
2252        /* At this point we have: */
2253        /* number of supplied keywords and values in %arg_z */
2254        /* keyword vector in %arg_y */
2255        __(vector_length(%arg_y,%imm0))
2256        __(push %imm0)          /* count of declared keywords */
2257        __(push %arg_z)         /* count of supplied keys and values */
2258
2259        /* For each declared keyword, iterate over the supplied k/v pairs */
2260        /* to see if it's supplied and what the value is. */
2261        /* checking to see if any */
2262        /* key-value pairs were unexpectedly supplied. */
2263
2264        __(movl rcontext(tcr.save_tsp),%temp0)
2265        __(addl $2*node_size,%temp0) /* skip frame overhead */
2266        /* %temp0: top of tstack (skipping frame overhead) */
2267        __(lea 4*node_size(%esp,%imm0,2),%temp1)
2268        /* %temp1: word above 0th value/supplied-p pair on vstack */
2269        /* %arg_y: keyword vector */
2270        __(xorl %imm0,%imm0)
2271        /* %imm0: index */
2272        /* %arg_z: temporary */
2273
2274        /* Iterate over supplied k/v pairs on tstack.  See if key is */
2275        /* in the keyword vector.  Copy value and set supplied-p on */
2276        /* vstack if found. */
2277
2278local_label(tstack_loop):
2279        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
2280        __(push %imm0)
2281        __(xorl %imm0,%imm0)
2282        __(cmpl $nrs.kallowotherkeys,%arg_z)
2283        __(jne local_label(next_keyvect_entry))
2284        __(btsl $keyword_flags_seen_aok_bit,rcontext(tcr.unboxed0))
2285        __(jc local_label(next_keyvect_entry))
2286        __(push %imm0)
2287        __(movl 4(%esp),%imm0)
2288        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
2289        __(pop %imm0)
2290        __(je local_label(next_keyvect_entry))
2291        __(btsl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2292        __(jmp local_label(next_keyvect_entry))
2293        /* loop through keyword vector */
22946:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
2295        __(jne 7f)
2296        /* Got a match; have we already seen this keyword? */
2297        __(negl %imm0)
2298        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
2299        __(jne 9f)      /* seen it, ignore this value */
2300        __(movl (%esp),%arg_z)
2301        __(lea (%temp0,%arg_z,2),%arg_z)
2302        __(movl node_size(%arg_z),%arg_z) /* value for this key */
2303        __(movl %arg_z,-node_size(%temp1,%imm0,2))
2304        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
2305        __(jmp 9f)
23067:      __(addl $node_size,%imm0)
2307local_label(next_keyvect_entry):
2308        __(cmpl %imm0,8(%esp))
2309        __(jne 6b)
2310        /* Didn't match anything in the keyword vector.  Is the keyword */
2311        /* :allow-other-keys? */
2312        __(cmpl $nrs.kallowotherkeys,%arg_z)
2313        __(je 9f)       /* :allow-other-keys is never "unknown" */
23148:      __(btsl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
23159:      __(pop %imm0)
2316        __(addl $fixnumone,%imm0)
2317        __(movl %imm0,%arg_z)
2318        __(shll $1,%arg_z)      /* pairs of tstack words */
2319        __(cmpl %arg_z,0(%esp))
2320        __(jne local_label(tstack_loop))
2321
2322        __(pop %imm0)   /* count of supplied keys and values */
2323        __(addl $node_size,%esp)
2324        __(pop %nargs)
2325        __(pop %ra0)
2326
2327        /* If the function takes an &rest arg, or if we got an unrecognized */
2328        /* keyword and don't allow that, copy the incoming k/v pairs from */
2329        /* the temp stack back to the value stack. */
2330        __(btl $keyword_flags_rest_bit,rcontext(tcr.unboxed0))
2331        __(jc 1f)
2332        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
2333        __(jnc 0f)
2334        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2335        __(jnc 1f)
2336        /* pop the tstack frame */
23370:      __(discard_temp_frame(%imm0))
2338        __(jmp *%ra0)
2339
2340        /* Copy the k/v pairs from the tstack back to the value stack, */
2341        /* either because the function takes an &rest arg or because */
2342        /* we need to signal an "unknown keywords" error. */
23431:      __(movl rcontext(tcr.save_tsp),%arg_z)
2344        __(mov (%arg_z),%arg_y)
2345        __(jmp 3f)
23462:      __(push (%arg_z))
2347        __(push node_size(%arg_z))
23483:      __(addl $dnode_size,%arg_z)
2349        __(cmpl %arg_z,%arg_y)
2350        __(jne 2b)
2351        __(discard_temp_frame(%arg_z))
2352        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
2353        __(jnc 9f)
2354        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2355        __(jc 9f)
2356        /* Signal an "unknown keywords" error */
2357        __(movl %imm0,%nargs)
2358        __(movl $nil_value,%arg_z)
2359        __(test %nargs,%nargs)
2360        __(movl %ra0,rcontext(tcr.save0))
2361        __(jmp 5f)
23624:      __(pop %arg_y)
2363        __(Cons(%arg_y,%arg_z,%arg_z))
2364        __(subl $node_size,%nargs)
23655:      __(jnz 4b)
2366        __(movl $XBADKEYS,%arg_y)
2367        __(set_nargs(2))
2368        __(movl rcontext(tcr.save0),%ra0)
2369        __(movl $0,rcontext(tcr.save0))
2370        __(jmp _SPksignalerr)
23719:      __(jmp *%ra0)
2372
2373/* No keyword value were provided.  Access the keyword vector (which is the */
2374/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
2375/* N could be 0... */
2376
2377local_label(no_keyword_values):
2378        __(movzwl misc_data_offset(%fn),%imm0)
2379        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2380        __(vector_length(%arg_y,%arg_z))
2381        __(movl $nil_value,%imm0)
2382        __(jmp 1f)
23830:      __(push %imm0)
2384        __(push %imm0)
23851:      __(subl $fixnumone,%arg_z)
2386        __(jge 0b)
2387        __(jmp *%ra0)
2388_endsubp(keyword_bind)
2389
2390/* Normally, we'd just set %fname (aka %temp0) and do */
2391/* jump_fname().  Sometimes, though, %temp0 is being used */
2392/* as %ra0, and I'm not sure that it's going to be safe to */
2393/* clobber that.  (Note that nil-relative symbols aren't going */
2394/* get moved around by the GC, so we can get away with putting */
2395/* '%err-disp in %imm0.) */
2396_spentry(ksignalerr)
2397        __(mov $nrs.errdisp,%imm0)
2398        __(mov symbol.fcell(%imm0),%fn)
2399        __(jump_fn)
2400_endsubp(ksignalerr)
2401
2402_spentry(stack_rest_arg)
2403        __(xorl %imm0,%imm0)
2404        __(push_argregs())
2405        __(jmp _SPstack_cons_rest_arg)
2406_endsubp(stack_rest_arg)
2407
2408_spentry(req_stack_rest_arg)
2409        __(push_argregs())
2410        __(jmp _SPstack_cons_rest_arg)
2411_endsubp(req_stack_rest_arg)
2412
2413_spentry(stack_cons_rest_arg)
2414        __(movd %nargs,%mm2)
2415        __(movl %temp0,rcontext(tcr.save0))
2416        __(subl %imm0,%temp1)
2417        __(movl $nil_value,%arg_z)
2418        __(jle 2f)      /* empty list; make an empty TSP frame */
2419        __(addl %temp1,%temp1)
2420        __(cmpl $(tstack_alloc_limit-dnode_size),%temp1)
2421        __(ja 3f)       /* make empty frame, then heap-cons */
2422        __(dnode_align(%temp1,tsp_frame.fixed_overhead,%imm0))
2423        __(TSP_Alloc_Var(%imm0,%temp0))
2424        __(addl $fulltag_cons,%temp0)
24251:      __(pop %arg_y)
2426        __(_rplacd(%temp0,%arg_z))
2427        __(_rplaca(%temp0,%arg_y))
2428        __(movl %temp0,%arg_z)
2429        __(addl $cons.size,%temp0)
2430        __(subl $dnode_size,%temp1)
2431        __(jne 1b)
2432        __(push %arg_z)
2433        __(movd %mm2,%nargs)
2434        __(movl rcontext(tcr.save0),%temp0)
2435        __(movss %fpzero,rcontext(tcr.save0))
2436        __(jmp *%temp0)
2437/* Length 0, make empty frame */
24382:
2439        __(TSP_Alloc_Fixed(0,%temp0))
2440        __(push %arg_z)
2441        __(movd %mm2,%nargs)
2442        __(movl rcontext(tcr.save0),%temp0)
2443        __(movss %fpzero,rcontext(tcr.save0))
2444        __(jmp *%temp0)
2445/* Too big to stack-cons, but make an empty frame before heap-consing */
2446        __(TSP_Alloc_Fixed(0,%temp0))
2447        __(movd %mm2,%nargs)
2448        __(movl rcontext(tcr.save0),%temp0)
2449        __(movss %fpzero,rcontext(tcr.save0))
2450        __(jmp _SPheap_cons_rest_arg)
2451_endsubp(stack_cons_rest_arg)
2452
2453_spentry(getxlong)
2454        __(hlt)
2455_endsubp(getxlong)
2456
2457/* Have to be a little careful here: the caller may or may not have pushed  */
2458/* an empty frame, and we may or may not have needed one.  We can't easily  */
2459/* tell whether or not a frame will be needed (if the caller didn't reserve  */
2460/* a frame, whether or not we need one depends on the length of the list  */
2461/* in arg_z.  So, if the caller didn't push a frame, we do so; once */
2462/* everything's been spread, we discard the reserved frame (regardless of
2463/* who pushed it) if all args fit in registers.   */
2464
2465/* xxx preserve temp1 somehow? cf. comment in x862-invoke-fn */
2466_spentry(spreadargz)
2467        __(test %nargs,%nargs)
2468        __(jne 0f)
2469        __(push $reserved_frame_marker)
2470        __(push $reserved_frame_marker)
24710:      __(movl %arg_z,rcontext(tcr.save0))     /* save in case of error */
2472        __(movd %nargs,%mm0)    /* now we can use %temp1 */
2473        __(xorl %nargs,%nargs)
2474        __(cmpl $nil_value,%arg_z)
2475        __(je 2f)
24761:      __(extract_fulltag(%arg_z,%imm0))
2477        __(cmpb $fulltag_cons,%imm0_b)
2478        __(jne 9f)
2479        __(_car(%arg_z,%arg_y))
2480        __(_cdr(%arg_z,%arg_z))
2481        __(add $node_size,%nargs)
2482        __(cmpl $call_arguments_limit<<fixnumshift,%nargs)
2483        __(jge 8f)
2484        __(push %arg_y)
2485        __(cmpl $nil_value,%arg_z)
2486        __(jne 1b)
24872:      __(movd %mm0,%imm0)
2488        __(addl %imm0,%nargs)
2489        __(jne 4f)
24903:      __(addl $2*node_size,%esp)
2491        __(movl $0,rcontext(tcr.save0))
2492        __(jmp *%ra0)
24934:      __(pop %arg_z)
2494        __(cmp $1*node_size,%nargs)
2495        __(je 3b)
2496        __(pop %arg_y)
2497        __(cmp $2*node_size,%nargs)
2498        __(je 3b)
2499        __(movl $0,rcontext(tcr.save0))
2500        __(jmp *%ra0)
2501/* Discard everything that's been pushed already, complain */
25028:      __(lea (%esp,%nargs),%esp)
2503        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2504        __(movl $0,rcontext(tcr.save0))
2505        __(movl $XTMINPS,%arg_y)
2506        __(set_nargs(2))
2507        __(push %ra0)
2508        __(jmp _SPksignalerr)
25099:      __(lea (%esp,%nargs),%esp)
2510        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2511        __(movl $0,rcontext(tcr.save0))
2512        __(movl $XNOSPREAD,%arg_y)
2513        __(set_nargs(2))
2514        __(push %ra0)
2515        __(jmp _SPksignalerr)
2516_endsubp(spreadargz)
2517
2518
2519/* Caller built its own frame when it was entered.  If all outgoing args  */
2520/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2521/* relative to it and restore %rbp/%ra0   */
2522_spentry(tfuncallgen)
2523        __(cmpl $nargregs*node_size,%nargs)
2524        __(jbe 9f)
2525        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2526        __(movl %temp0,rcontext(tcr.save0))
2527        __(movd %nargs,%mm0)
2528        __(xorl %temp1,%temp1)
2529        /* We can use %ra0 as a temporary here, since the real return address */
2530        /* is on the stack   */
25310:      __(movl -node_size(%imm0),%ra0)
2532        __(movl %ra0,-node_size(%ebp,%temp1))
2533        __(subl $node_size,%imm0)
2534        __(subl $node_size,%temp1)
2535        __(cmpl %imm0,%esp)
2536        __(jne 0b)
2537        __(lea (%ebp,%temp1),%esp)
2538        __(movl 4(%ebp),%ra0)
2539        __(movl (%ebp),%ebp)
2540        __(pushl %ra0)
2541        __(movd %mm0,%nargs)
2542        __(movl rcontext(tcr.save0),%temp0)
2543        __(movss %fpzero,rcontext(tcr.save0))
2544        __(do_funcall())
2545        /* All args in regs; exactly the same as the tfuncallvsp case   */
25469:             
2547        __(leave)
2548        __(do_funcall())
2549
2550_endsubp(tfuncallgen)
2551
2552/* Some args were pushed; move them down in the frame   */
2553_spentry(tfuncallslide)
2554        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2555        __(movd %nargs,%mm0)
2556        __(xorl %temp1,%temp1)
2557        __(movl %temp0,rcontext(tcr.save0))
25580:      __(movl -node_size(%imm0),%temp0)
2559        __(movl %temp0,-node_size(%ebp,%temp1))
2560        __(subl $node_size,%imm0)
2561        __(subl $node_size,%temp1)
2562        __(cmpl %imm0,%esp)
2563        __(jne 0b)
2564        __(lea (%ebp,%temp1),%esp)
2565        __(push 4(%ebp))        /* return address */
2566        __(movl (%ebp),%ebp)
2567        __(movd %mm0,%nargs)
2568        __(movl rcontext(tcr.save0),%temp0)
2569        __(movss %fpzero,rcontext(tcr.save0))
2570        __(do_funcall())
2571_endsubp(tfuncallslide)
2572
2573/* No args were pushed; recover saved context & do funcall        */
2574_spentry(tfuncallvsp)
2575        __(leave)
2576        __(do_funcall())
2577_endsubp(tfuncallvsp)
2578
2579_spentry(tcallsymgen)
2580        __(cmpl $nargregs*node_size,%nargs)
2581        __(jbe 9f)
2582        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2583        __(movd %nargs,%mm0)
2584        __(movl %temp0,rcontext(tcr.save0))
2585        __(xorl %temp1,%temp1)  /* aka nargs */
25860:      __(movl -node_size(%imm0),%temp0)
2587        __(movl %temp0,-node_size(%ebp,%temp1))
2588        __(subl $node_size,%imm0)
2589        __(subl $node_size,%temp1)
2590        __(cmpl %imm0,%esp)
2591        __(jne 0b)
2592        __(lea (%ebp,%temp1),%esp)
2593        __(movl 4(%ebp),%temp0)
2594        __(movl (%ebp),%ebp)
2595        __(push %temp0)
2596        __(movl rcontext(tcr.save0),%temp0)
2597        __(movss %fpzero,rcontext(tcr.save0))
2598        __(movd %mm0,%nargs)
2599        __(jump_fname())
2600/* All args in regs; exactly the same as the tcallsymvsp case. */
26019:
2602        __(leave)
2603        __(jump_fname())
2604_endsubp(tcallsymgen)
2605
2606_spentry(tcallsymslide)
2607        __(movl %ebp,%imm0)
2608        __(subl %nargs,%imm0)
2609        __(addl $nargregs*node_size,%imm0)      /* new tos */
2610        __(push %imm0)
2611        __(push %arg_y)
2612        __(push %arg_z)
2613        __(push %nargs)
2614        __(lea (4-nargregs)*node_size(%esp,%nargs),%arg_y) /* src ptr */
2615        __(movl %ebp,%imm0) /* dst ptr */
2616        __(subl $fixnumone*nargregs,%nargs)
2617        __(jmp 1f)
26180:      __(subl $node_size,%arg_y)
2619        __(movl (%arg_y),%arg_z)
2620        __(subl $node_size,%imm0)
2621        __(movl %arg_z,(%imm0))
26221:      __(subl $fixnumone,%nargs)
2623        __(jge 0b)
2624        __(pop %nargs)
2625        __(pop %arg_z)
2626        __(pop %arg_y)
2627        __(pop %esp)
2628        __(push node_size(%ebp))
2629        __(movl 0(%ebp),%ebp)
2630        __(jump_fname)
2631_endsubp(tcallsymslide)
2632
2633_spentry(tcallsymvsp)
2634        __(leave)
2635        __(jump_fname())
2636_endsubp(tcallsymvsp)
2637
2638_spentry(tcallnfngen)
2639        __(cmpl $nargregs*node_size,%nargs)
2640        __(jbe 9f)
2641        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2642        __(movd %nargs,%mm0)    /* stash nargs aka temp1 */
2643        __(xorl %temp1,%temp1)
2644        __(movl %temp0,rcontext(tcr.save0))
2645        /* It's OK to use %ra0 (%temp0) as an temp here, since the */
2646        /* real return address is on the stack. */
26470:      __(movl -node_size(%imm0),%ra0)
2648        __(movl %ra0,-node_size(%ebp,%temp1))
2649        __(subl $node_size,%imm0)
2650        __(subl $node_size,%temp1)
2651        __(cmpl %imm0,%esp)
2652        __(jne 0b)
2653        __(movl rcontext(tcr.save0),%fn)
2654        __(movss %fpzero,rcontext(tcr.save0))
2655        __(lea (%ebp,%temp1),%esp)
2656        __(movl lisp_frame.savera0(%ebp),%ra0)
2657        __(movl lisp_frame.backlink(%ebp),%ebp)
2658        __(push %ra0)
2659        __(movd %mm0,%nargs)
2660        __(jmp *%fn)
26619:      /* All args in regs; exactly the same as the tcallnfnvsp case */
2662        __(movl %temp0,%fn)
2663        __(leave)
2664        __(jmp *%fn)
2665_endsubp(tcallnfngen)
2666
2667_spentry(tcallnfnslide)
2668        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2669        __(movd %nargs,%mm0)    /* save nargs aka temp1 */
2670        __(xorl %temp1,%temp1)
2671        __(movl %temp0,rcontext(tcr.save0))
2672        /* We can use %ra0 as a temporary here, since the real return address */
2673        /* is on the stack   */
26740:      __(movl -node_size(%imm0),%ra0)
2675        __(movl %ra0,-node_size(%ebp,%temp1))
2676        __(subl $node_size,%imm0)
2677        __(subl $node_size,%temp1)
2678        __(cmpl %imm0,%esp)
2679        __(jne 0b)
2680        __(movl rcontext(tcr.save0),%fn)
2681        __(lea (%ebp,%temp1),%esp)
2682        __(movl lisp_frame.savera0(%ebp),%ra0)
2683        __(movl lisp_frame.backlink(%ebp),%ebp)
2684        __(push %ra0)
2685        __(movapd %fpzero,rcontext(tcr.save0))
2686        __(movd %mm0,%nargs)
2687        __(jmp *%fn)
2688_endsubp(tcallnfnslide)
2689
2690_spentry(tcallnfnvsp)
2691        __(mov %temp0,%fn)
2692        __(leave)
2693        __(jmp *%fn)
2694_endsubp(tcallnfnvsp)
2695
2696/* Make a "raw" area on the foreign stack, stack-cons a macptr to point */
2697/* to it, and return the macptr.  Size (in bytes, boxed) is in arg_z */
2698/* on entry; macptr in arg_z on exit. */
2699_spentry(makestackblock)
2700        __(check_cstack_alignment())
2701        __(unbox_fixnum(%arg_z,%imm0))
2702        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2703        __(cmpl $tstack_alloc_limit,%imm0)
2704        __(jae 1f)
2705        __(movd rcontext(tcr.foreign_sp),%mm0)
2706        __(subl %imm0,rcontext(tcr.foreign_sp))
2707        __(movl rcontext(tcr.foreign_sp),%arg_z)
2708        __(movd %mm0,(%arg_z))
2709        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2710        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2711        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2712        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2713        __(movl %imm0,macptr.address(%arg_z))
2714        __(movss %fpzero,macptr.domain(%arg_z))
2715        __(movss %fpzero,macptr.type(%arg_z))
2716        __(ret)
27171:      __(movd rcontext(tcr.foreign_sp),%mm0)
2718        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2719        __(movl rcontext(tcr.foreign_sp),%imm0)
2720        __(movd %mm0,(%imm0))
2721        __(movl %ebp,csp_frame.save_ebp(%imm0))
2722        __(set_nargs(1))
2723        __(movl $nrs.new_gcable_ptr,%fname)
2724        __(jump_fname())
2725_endsubp(makestackblock)
2726
2727_spentry(makestackblock0)
2728        __(unbox_fixnum(%arg_z,%imm0))
2729        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2730        __(cmpl $tstack_alloc_limit,%imm0)
2731        __(jae 9f)
2732        __(movl rcontext(tcr.foreign_sp),%temp0)
2733        __(subl %imm0,rcontext(tcr.foreign_sp))
2734        __(movl rcontext(tcr.foreign_sp),%arg_z)
2735        __(movl %temp0,(%arg_z))
2736        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2737        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2738        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2739        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2740        __(movl %imm0,macptr.address(%arg_z))
2741        __(movss %fpzero,macptr.domain(%arg_z))
2742        __(movss %fpzero,macptr.type(%arg_z))
2743        __(jmp 2f)
27441:      __(movsd %fpzero,(%imm0))
2745        __(addl $dnode_size,%imm0)
27462:      __(cmpl %imm0,%temp0)
2747        __(jne 1b)
2748        __(repret)
27499:      __(movd rcontext(tcr.foreign_sp),%mm0)
2750        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2751        __(movl rcontext(tcr.foreign_sp),%imm0)
2752        __(movd %mm0,(%imm0))
2753        __(movl %ebp,csp_frame.save_ebp(%imm0))
2754        __(set_nargs(1))
2755        __(movl $nrs.new_gcable_ptr,%fname)
2756        __(jump_fname())
2757_endsubp(makestackblock0)
2758
2759_spentry(makestacklist)
2760        __(test %arg_y,%arg_y)
2761        __(js 9f)
2762        __(movl %arg_y,%imm0)
2763        __(testb $fixnummask,%imm0_b)
2764        __(jne 9f)
2765        __(addl %imm0,%imm0)
2766        __(rcmpl(%imm0,$tstack_alloc_limit))
2767        __(movl $nil_value,%temp1) 
2768        __(jae 2f)
2769        __(addl $tsp_frame.fixed_overhead,%imm0)
2770        __(TSP_Alloc_Var(%imm0,%temp0))
2771        __(addl $fulltag_cons,%temp0)
2772        __(jmp 1f)
27730:      __(_rplaca(%temp0,%arg_z))
2774        __(_rplacd(%temp0,%temp1))
2775        __(movl %temp0,%temp1)
2776        __(addl $cons.size,%temp0)
27771:      __(subl $fixnumone,%arg_y)
2778        __(jge 0b)
2779        __(movl %temp1,%arg_z)
2780        __(ret)
27812:      __(TSP_Alloc_Fixed(0,%imm0))
2782        __(jmp 4f)
27833:      __(Cons(%arg_z,%temp1,%temp1))
27844:      __(subl $fixnumone,%arg_y)                             
2785        __(jge 3b)
2786        __(movl %temp1,%arg_z)
2787        __(ret)
27889:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
2789_endsubp(makestacklist)
2790
2791/* subtype (boxed) vpushed before initial values. (Had better be a */
2792/* node header subtag.)  Nargs set to count of things vpushed. */
2793_spentry(stkgvector)
2794        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2795        __(shrl $fixnumshift,%imm0)
2796        __(leal -fixnumone(%nargs),%arg_z)
2797        __(movl %arg_z,%arg_y)
2798        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2799        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2800        __(movd %imm0,%mm0)
2801        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2802        __(TSP_Alloc_Var(%imm0,%arg_z))
2803        __(movd %mm0,(%arg_z))
2804        __(addl $fulltag_misc,%arg_z)
2805        __(lea -node_size(%nargs),%imm0)
2806        __(jmp 2f)
28071:      __(pop misc_data_offset(%arg_z,%imm0))
28082:      __(subl $node_size,%imm0)
2809        __(jge 1b)
2810        __(addl $node_size,%esp)
2811        __(jmp *%ra0)
2812_endsubp(stkgvector)
2813
2814/* Allocate a fulltag-misc object. */
2815/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
2816_spentry(misc_alloc)
2817        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2818        __(jne local_label(misc_alloc_not_u24))
2819        __(unbox_fixnum(%arg_z,%imm0))
2820        __(mov %arg_y,%temp0)
2821        __(shl $num_subtag_bits-fixnumshift,%temp0)
2822        __(or %temp0,%imm0)     /* %imm0 now = header */
2823        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2824        __(andb $fulltagmask,%imm0_b)
2825        __(cmpb $fulltag_nodeheader,%imm0_b)
2826        __(je local_label(misc_alloc_32))
2827        __(movd %mm0,%imm0)
2828        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2829        __(jbe local_label(misc_alloc_32))
2830        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2831        __(jbe local_label(misc_alloc_8))
2832        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2833        __(jbe local_label(misc_alloc_16))
2834        __(cmpb $subtag_double_float_vector,%imm0_b)
2835        __(jne local_label(misc_alloc_1))
2836        /* double-float vector case */
2837        __(imul $2,%arg_y,%imm0)
2838        __(jmp local_label(misc_alloc_alloc_vector))
2839local_label(misc_alloc_1):
2840        __(unbox_fixnum(%arg_y,%imm0))
2841        __(addl $7,%imm0)
2842        __(shrl $3,%imm0)
2843        __(jmp local_label(misc_alloc_alloc_vector))
2844local_label(misc_alloc_8):
2845        __(unbox_fixnum(%arg_y,%imm0))
2846        __(jmp local_label(misc_alloc_alloc_vector))
2847local_label(misc_alloc_16):
2848        __(unbox_fixnum(%arg_y,%imm0))
2849        __(shl $1,%imm0)
2850        __(jmp local_label(misc_alloc_alloc_vector))
2851local_label(misc_alloc_32):
2852        __(movl %arg_y,%imm0)
2853local_label(misc_alloc_alloc_vector):
2854        __(dnode_align(%imm0,node_size,%imm0))
2855        __(Misc_Alloc(%arg_z))
2856        __(ret)
2857local_label(misc_alloc_not_u24):
2858        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2859_endsubp(misc_alloc)
2860
2861/* N.B. arg count word in %imm0, not %nargs */
2862/* no %whole_reg;  it's in rcontext(tcr.save0) */
2863/* %arg_reg is %temp1, key vector in %arg_y */
2864_startfn(C(destbind1))
2865        __(movl %ra0,rcontext(tcr.save1))
2866        /* Save entry %esp in case of error   */
2867        __(movd %esp,%mm0)
2868        /* Save arg count word */
2869        __(movd %imm0,%mm1)
2870        /* Extract required arg count.   */
2871        __(testb %imm0_b,%imm0_b)
2872        __(je local_label(opt))         /* skip if no required args   */
2873        __(movzbl %imm0_b,%imm0)
2874local_label(req_loop): 
2875        __(compare_reg_to_nil(%arg_reg))
2876        __(je local_label(toofew))
2877        __(movb $fulltagmask,%imm0_bh)
2878        __(andb %arg_reg_b,%imm0_bh)
2879        __(cmpb $fulltag_cons,%imm0_bh)
2880        __(jne local_label(badlist))
2881        __(subb $1,%imm0_b)
2882        __(pushl cons.car(%arg_reg))
2883        __(_cdr(%arg_reg,%arg_reg))
2884        __(jne local_label(req_loop))
2885        __(movd %mm1,%imm0)
2886local_label(opt):
2887        __(testb %imm0_bh,%imm0_bh)
2888        __(je local_label(rest_keys))
2889        __(btl $initopt_bit,%imm0)
2890        __(jc local_label(opt_supp))
2891        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2892local_label(simple_opt_loop):
2893        __(compare_reg_to_nil(%arg_reg))
2894        __(je local_label(default_simple_opt))
2895        __(movb $fulltagmask,%imm0_bh)
2896        __(andb %arg_reg_b,%imm0_bh)
2897        __(cmpb $fulltag_cons,%imm0_bh)
2898        __(jne local_label(badlist))
2899        __(subb $1,%imm0_b)
2900        __(pushl cons.car(%arg_reg))
2901        __(_cdr(%arg_reg,%arg_reg))
2902        __(jne local_label(simple_opt_loop))
2903        __(jmp local_label(rest_keys))
2904local_label(default_simple_opt):
2905        __(subb $1,%imm0_b)
2906        __(pushl $nil_value)
2907        __(jne local_label(default_simple_opt))
2908        __(jmp local_label(rest_keys))
2909local_label(opt_supp):
2910        __(movb $fulltagmask,%imm0_bh)
2911        __(andb %arg_reg_b,%imm0_bh)
2912        __(compare_reg_to_nil(%arg_z))
2913        __(je local_label(default_hard_opt))
2914        __(cmpb $fulltag_cons,%imm0_bh)
2915        __(jne local_label(badlist))
2916        __(subb $1,%imm0_b)
2917        __(pushl cons.car(%arg_reg))
2918        __(_cdr(%arg_reg,%arg_reg))
2919        __(push $t_value)
2920        __(jne local_label(opt_supp))
2921        __(jmp local_label(rest_keys))
2922local_label(default_hard_opt):
2923        __(subb $1,%imm0_b)
2924        __(push $nil_value)
2925        __(push $nil_value)
2926        __(jne local_label(default_hard_opt))
2927local_label(rest_keys):
2928        __(btl $restp_bit,%imm0)
2929        __(jc local_label(have_rest))
2930        __(btl $keyp_bit,%imm0)
2931        __(jc local_label(have_keys))
2932        __(compare_reg_to_nil(%arg_reg))
2933        __(jne local_label(toomany))
2934        __(movss %fpzero,rcontext(tcr.save0))
2935        __(jmp *%ra0)
2936local_label(have_rest):
2937        __(pushl %arg_reg)
2938        __(btl $keyp_bit,%imm0)
2939        __(jc local_label(have_keys))
2940        __(movss %fpzero,rcontext(tcr.save0))
2941        __(jmp *%ra0)
2942        /* Ensure that arg_reg contains a proper,even-length list.  */
2943        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2944local_label(have_keys):
2945        __(movb $255,%imm0_b)
2946        __(push %arg_reg)
2947        __(push %arg_z)
2948        __(xorl %arg_z,%arg_z)
2949local_label(count_keys_loop):
2950        __(compare_reg_to_nil(%arg_reg))
2951        __(je local_label(counted_keys))
2952        __(subb $1,%imm0_b)
2953        __(jb local_label(toomany))
2954        __(movb $fulltagmask,%arg_z_bh)
2955        __(andb %arg_reg_b,%arg_z_bh)
2956        __(cmpb $fulltag_cons,%arg_z_bh)
2957        __(jne local_label(badlist))
2958        __(_cdr(%arg_reg,%arg_reg))
2959        __(movb $fulltagmask,%arg_z_bh)
2960        __(andb %arg_reg_b,%arg_z_bh)
2961        __(cmpb $fulltag_cons,%arg_z_bh)
2962        __(jne local_label(badlist))
2963        __(_cdr(%arg_reg,%arg_reg))
2964        __(jmp local_label(count_keys_loop))
2965local_label(counted_keys):             
2966        /* We've got a proper, even-length list of key/value pairs in  */
2967        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2968        /* of NILs on the vstack.   */
2969        __(pop %arg_z)
2970        __(pop %arg_reg)
2971        __(movd %mm1,%imm0)
2972        __(shrl $16,%imm0)
2973        __(movzbl %imm0_b,%imm0)
2974        __(movl %esp,rcontext(tcr.unboxed0))    /* 0th value/supplied-p pair */
2975        __(jmp local_label(push_pair_test))
2976local_label(push_pair_loop):
2977        __(push $nil_value)
2978        __(push $nil_value)
2979local_label(push_pair_test):   
2980        __(subb $1,%imm0_b)
2981        __(jge local_label(push_pair_loop))
2982        __(push %temp0) /* keyword */
2983        __(push %arg_z) /* value */
2984        __(vector_length(%arg_y,%imm0))
2985        __(push %arg_reg)
2986        __(push %imm0)  /* keyword vector length */
2987        __(movd %mm1,%imm0)
2988        __(movl $0,rcontext(tcr.unboxed1)) /* count of unknown keywords seen */
2989local_label(match_keys_loop):
2990        __(movl 4(%esp),%arg_reg)
2991        __(compare_reg_to_nil(%arg_reg))
2992        __(je local_label(matched_keys))
2993        __(_car(%arg_reg,%temp0))
2994        __(_cdr(%arg_reg,%arg_reg))
2995        __(_car(%arg_reg,%arg_z))
2996        __(_cdr(%arg_reg,%arg_reg))
2997        __(movl %arg_reg,4(%esp))
2998        __(xorl %temp1,%temp1)
2999        __(jmp local_label(match_test))
3000local_label(match_loop):
3001        __(cmpl misc_data_offset(%arg_y,%temp1),%temp0)
3002        __(je local_label(matched))
3003        __(addl $node_size,%temp1)
3004local_label(match_test):
3005        __(cmpl %temp1,(%esp))  /* compare index, keyword vector length */
3006        __(jne local_label(match_loop))
3007        /* No match.  Note unknown keyword, check for :allow-other-keys   */
3008        __(addl $1,rcontext(tcr.unboxed1))
3009        __(cmpl $nrs.kallowotherkeys,%temp0)
3010        __(jne local_label(match_keys_loop))
3011        __(subl $1,rcontext(tcr.unboxed1))
3012        __(btsl $seen_aok_bit,%imm0)
3013        __(jc local_label(match_keys_loop))
3014        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
3015        __(compare_reg_to_nil(%arg_z))
3016        __(je local_label(match_keys_loop))
3017        __(btsl $aok_bit,%imm0)
3018        __(jmp local_label(match_keys_loop))
3019        /* Got a match.  Worry about :allow-other-keys here, too.   */
3020local_label(matched):
3021        __(negl %temp1)
3022        __(shll $1,%temp1)
3023        __(addl rcontext(tcr.unboxed0),%temp1)
3024        __(cmpl $nil_value,-node_size*2(%temp1))
3025        __(jne local_label(match_keys_loop))
3026        __(movl %arg_z,-node_size(%temp1))
3027        __(movl $t_value,-node_size*2(%temp1))
3028        __(cmpl $nrs.kallowotherkeys,%temp0)
3029        __(jne local_label(match_keys_loop))
3030        __(btsl $seen_aok_bit,%imm0)
3031        __(jnc local_label(match_keys_loop))
3032        __(compare_reg_to_nil(%arg_z))
3033        __(je local_label(match_keys_loop))
3034        __(btsl $aok_bit,%imm0)
3035        __(jmp local_label(match_keys_loop))
3036local_label(matched_keys):     
3037        __(cmpl $0,rcontext(tcr.unboxed1))      /* any unknown keys seen? */
3038        __(je local_label(keys_ok))
3039        __(btl $aok_bit,%imm0)
3040        __(jnc local_label(badkeys))
3041local_label(keys_ok):
3042        __(addl $(3*node_size),%esp)
3043        __(pop %ra0)
3044        __(movss %fpzero,rcontext(tcr.save0))
3045        __(jmp *%ra0)
3046        /* Some unrecognized keywords.  Complain generically about   */
3047        /* invalid keywords.   */
3048local_label(badkeys):
3049        __(movl $XBADKEYS,%arg_y)
3050        __(jmp local_label(destructure_error))
3051local_label(toomany):
3052        __(movl $XCALLTOOMANY,%arg_y)
3053        __(jmp local_label(destructure_error))
3054local_label(toofew):
3055        __(movl $XCALLTOOFEW,%arg_y)
3056        __(jmp local_label(destructure_error))
3057local_label(badlist):
3058        __(movl $XCALLNOMATCH,%arg_y)
3059local_label(destructure_error):
3060        __(movd %mm0,%esp)              /* undo everything done to the stack */
3061        __(movl rcontext(tcr.save0),%arg_z)     /* %whole_reg */
3062        __(movss %fpzero,rcontext(tcr.save0))
3063        __(set_nargs(2))
3064        __(push %ra0)
3065        __(jmp _SPksignalerr)
3066_endfn(C(destbind1))
3067
3068_spentry(macro_bind)
3069        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3070        __(extract_fulltag(%arg_reg,%imm0))
3071        __(cmpb $fulltag_cons,%imm0_b)
3072        __(jne 1f)
3073        __(_cdr(%arg_reg,%arg_reg))
3074        __(jmp C(destbind1))
30751:      __(movl $XCALLNOMATCH,%arg_y)
3076        __(movl rcontext(tcr.save0),%arg_z)
3077        __(movss %fpzero,rcontext(tcr.save0))
3078        __(set_nargs(2))
3079        __(push %ra0)       
3080        __(jmp _SPksignalerr)
3081
3082_endsubp(macro_bind)
3083
3084_spentry(destructuring_bind)
3085        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3086        __(jmp C(destbind1))
3087_endsubp(destructuring_bind)
3088
3089_spentry(destructuring_bind_inner)
3090        __(movl %arg_z,rcontext(tcr.save0))     /* %whole_reg */
3091        __(jmp C(destbind1))
3092_endsubp(destructuring_bind_inner)
3093
3094_spentry(vpopargregs)
3095        __(hlt)
3096_endsubp(vpopargregs)
3097
3098/* If arg_z is an integer, return in imm0 something whose sign  */
3099/* is the same as arg_z's.  If not an integer, error.   */
3100_spentry(integer_sign)
3101        __(mov %arg_z,%imm0)
3102        __(testb $tagmask,%arg_z_b)
3103        __(je 8f)
3104        __(extract_typecode(%arg_z,%imm0))
3105        __(cmpb $subtag_bignum,%imm0_b)
3106        __(jne 9f)
3107        __(getvheader(%arg_z,%imm0))
3108        __(shr $num_subtag_bits,%imm0)
3109        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
31108:      __(repret)
31119:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3112_endsubp(integer_sign)
3113
3114/* "slide" nargs worth of values up the stack.  imm0 contains */
3115/* the difference between the current stack pointer and the target. */
3116_spentry(mvslide)
3117        __(movd %nargs,%mm0)
3118        __(lea (%esp,%nargs),%arg_y)
3119        __(lea (%arg_y,%imm0),%imm0)
3120        __(test %nargs,%nargs)
3121        __(je 2f)
31221:
3123        __(subl $node_size,%arg_y)
3124        __(movl (%arg_y),%arg_z)
3125        __(subl $node_size,%imm0)
3126        __(movl %arg_z,(%imm0))
3127        __(subl $node_size,%nargs)
3128        __(jne 1b)
31292:      __(movl %imm0,%esp)
3130        __(movd %mm0,%nargs)
3131        __(jmp *%ra0)
3132_endsubp(mvslide)
3133
3134_spentry(save_values)
3135        __(movd rcontext(tcr.save_tsp),%mm1)
3136/* common exit: nargs = values in this set, mm1 = ptr to tsp before call to save_values   */
3137local_label(save_values_to_tsp):
3138        __(movl %ra0,rcontext(tcr.save0))
3139        __(movl rcontext(tcr.save_tsp),%temp0)
3140        __(dnode_align(%nargs,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3141        __(TSP_Alloc_Var(%imm0,%arg_z))
3142        __(movl rcontext(tcr.save_tsp),%imm0)
3143        __(movd %mm1,(%imm0))
3144        __(movl %nargs,(%arg_z))
3145        __(movl %temp0,node_size(%arg_z))
3146        __(leal 2*node_size(%arg_z,%nargs),%arg_y)
3147        __(leal (%esp,%nargs),%imm0)
3148        __(cmpl %imm0,%esp)
3149        __(jmp 2f)
31501:      __(subl $node_size,%imm0)
3151        __(movl (%imm0),%arg_z)
3152        __(subl $node_size,%arg_y)
3153        __(cmpl %imm0,%esp)
3154        __(movl %arg_z,(%arg_y))
31552:      __(jne 1b)
3156        __(addl %nargs,%esp)
3157        __(movl rcontext(tcr.save0),%ra0)
3158        __(movl $0,rcontext(tcr.save0))
3159        __(jmp *%ra0)
3160_endsubp(save_values)
3161
3162/* Add the multiple values that are on top of the vstack to the set  */
3163/* saved in the top tsp frame, popping them off of the vstack in the  */
3164/* process.  It is an error (a bad one) if the TSP contains something  */
3165/* other than a previously saved set of multiple-values.  */
3166/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3167/* each add_values call adds another linked element to the list of  */
3168/* values. This makes recover_values harder.   */
3169_spentry(add_values)
3170        /* do we need to preserve imm0? */
3171        __(test %nargs,%nargs)
3172        __(movl rcontext(tcr.save_tsp),%imm0)
3173        __(movl (%imm0),%imm0)
3174        __(movd %imm0,%mm1)     /* for the benefit of save_values_to_tsp */
3175        __(jne local_label(save_values_to_tsp))
3176        __(jmp *%ra0)
3177_endsubp(add_values)
3178
3179/* push the values in the value set atop the sp, incrementing nargs.  */
3180/* Discard the tsp frame; leave values atop the sp.   */
3181_spentry(recover_values)
3182        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3183        __(movd %nargs,%mm0)              /* temp1 */
3184        /* First, walk the segments reversing the pointer to previous  */
3185        /* segment pointers Can tell the end because that previous  */
3186        /* segment pointer is the prev tsp pointer   */
3187        __(movl rcontext(tcr.save_tsp),%temp1)
3188        __(movl %temp1,%temp0)  /* current segment   */
3189        __(movl %temp1,%arg_y)  /* last segment   */
3190        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3191local_label(walkloop):
3192        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3193        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3194        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3195        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3196        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3197        __(jne local_label(walkloop))
3198
3199        __(movl %temp1,%arg_z)
3200        __(movd %mm0,%nargs)
3201        /* the final segment pointer is now in %arg_y  */
3202        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3203local_label(pushloop):
3204        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3205        __(test %imm0,%imm0)
3206        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3207        __(leal (%nargs,%imm0),%nargs)
3208        __(jmp 2f)
32091:      __(push -node_size(%temp0))
3210        __(subl $node_size,%temp0)
3211        __(subl $fixnum_one,%imm0)
32122:      __(jne 1b)
3213        __(cmpl %arg_y,%arg_z)
3214        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3215        __(jne local_label(pushloop))
3216        __(movl (%arg_z),%arg_z)
3217        __(movl %arg_z,rcontext(tcr.save_tsp))
3218        __(movl %arg_z,rcontext(tcr.next_tsp))
3219        __(movl rcontext(tcr.save0),%ra0)
3220        __(movl $0,rcontext(tcr.save0))
3221        __(jmp *%ra0)           
3222_endsubp(recover_values)
3223
3224/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3225/* frame if any values (which will be used as outgoing arguments) will  */
3226/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3227/* that no other arguments have been pushed) on entry.   */
3228
3229_spentry(recover_values_for_mvcall)
3230        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3231        /* First, walk the segments reversing the pointer to previous  */
3232        /* segment pointers Can tell the end because that previous  */
3233        /* segment pointer is the prev tsp pointer   */
3234        __(xorl %nargs,%nargs)
3235        __(push %nargs)
3236        __(movl rcontext(tcr.save_tsp),%temp1)
3237        __(movl %temp1,%temp0)  /* current segment   */
3238        __(movl %temp1,%arg_y)  /* last segment   */
3239        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3240local_label(walkloop_mvcall):
3241        __(movl tsp_frame.data_offset(%temp0),%imm0)
3242        __(addl %imm0,(%esp))
3243        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3244        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3245        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3246        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3247        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3248        __(jne local_label(walkloop_mvcall))
3249
3250        __(movl %temp1,%arg_z)
3251        __(pop %nargs)
3252
3253        __(cmpl $nargregs*node_size,%nargs)
3254        __(jbe local_label(pushloop_mvcall))
3255        __(push $reserved_frame_marker)
3256        __(push $reserved_frame_marker)
3257
3258        /* the final segment pointer is now in %arg_y  */
3259        /* walk backwards, pushing values on the stack and incrementing %nargs*/
3260local_label(pushloop_mvcall):
3261        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment */
3262        __(test %imm0,%imm0)
3263        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3264        __(jmp 2f)
32651:      __(push -node_size(%temp0))
3266        __(subl $node_size,%temp0)
3267        __(subl $fixnum_one,%imm0)
32682:      __(jne 1b)
3269        __(cmpl %arg_y,%arg_z)
3270        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3271        __(jne local_label(pushloop_mvcall))
3272        __(movl (%arg_z),%arg_z)
3273        __(movl %arg_z,rcontext(tcr.save_tsp))
3274        __(movl %arg_z,rcontext(tcr.next_tsp))
3275        __(movl rcontext(tcr.save0),%ra0)
3276        __(movl $0,rcontext(tcr.save0))
3277        __(jmp *%ra0)           
3278_endsubp(recover_values_for_mvcall)
3279
3280_spentry(reset)
3281        __(hlt)
3282_endsubp(reset)
3283
3284/* temp0 = element-count, arg_y = subtag, arg_z = initval */
3285_spentry(misc_alloc_init)
3286        __(push %ebp)
3287        __(movl %esp,%ebp)
3288        __(push %arg_z)
3289        __(movl %arg_y,%arg_z)
3290        __(movl %temp0,%arg_y)
3291        __(push $local_label(misc_alloc_init_back))
3292        __(jmp _SPmisc_alloc)
3293__(tra(local_label(misc_alloc_init_back)))
3294        __(pop %arg_y)
3295        __(leave)
3296        __(movl $nrs.init_misc,%fname)
3297        __(set_nargs(2))
3298        __(jump_fname())
3299_endsubp(misc_alloc_init)
3300
3301/* %temp1 = element-count, %arg_y = subtag, %arg_z = initial-value */       
3302_spentry(stack_misc_alloc_init)
3303        __(push %ebp)
3304        __(movl %esp,%ebp)
3305        __(push %arg_z)
3306        __(movl %arg_y,%arg_z)
3307        __(movl %temp1,%arg_y)
3308        __(pushl $local_label(stack_misc_alloc_init_back))
3309        __(jmp _SPstack_misc_alloc)
3310__(tra(local_label(stack_misc_alloc_init_back)))
3311        __(popl %arg_y)
3312        __(leave)
3313        __(movl $nrs.init_misc,%fname)
3314        __(set_nargs(2))
3315        __(jump_fname())
3316_endsubp(stack_misc_alloc_init)
3317
3318        .globl C(popj)
3319_spentry(popj)
3320C(popj):
3321        __(leave)
3322        __(ret)
3323_endsubp(popj)
3324
3325/* arg_z should be of type (signed-byte 64) */
3326/* return unboxed value in mm0 */
3327_spentry(gets64)
3328        __(testb $fixnummask,%arg_z_b)
3329        __(jne 1f)
3330        __(unbox_fixnum(%arg_z,%imm0))
3331        __(movd %imm0,%mm0)
3332        __(jns 8f)
3333        /* get sign into upper half of %mm0 */
3334        __(pcmpeqd %mm1,%mm1)   /* all ones */
3335        __(psllq $32,%mm1)
3336        __(por %mm1,%mm0)
3337        __(ret)
33381:      __(movb %arg_z_b,%imm0_b)
3339        __(andb $tagmask,%imm0_b)
3340        __(cmpb $tag_misc,%imm0_b)
3341        __(jne 9f)
3342        __(movl misc_header_offset(%arg_z),%imm0)
3343        __(cmpb $subtag_bignum,%imm0_b)
3344        __(jne 9f)
3345        __(cmpl $two_digit_bignum_header,%imm0)
3346        __(ja 9f)
3347        __(movd misc_data_offset(%arg_z),%mm0)
3348        __(jne 8f)
3349        __(movq misc_data_offset(%arg_z),%mm0)
33508:      __(repret)
33519:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_s64))
3352_endsubp(gets64)
3353
3354/* arg_z should be of type (unsigned-byte 64) */
3355/* return unboxed value in mm0 */
3356_spentry(getu64)
3357        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3358        __(testl %arg_z,%imm0)
3359        __(movl %arg_z,%imm0)
3360        __(jne 1f)
3361        __(sarl $fixnumshift,%imm0)
3362        __(movd %imm0,%mm0)
3363        __(ret)
33641:      __(andb $tagmask,%imm0_b)
3365        __(cmpb $tag_misc,%imm0_b)
3366        __(jne 9f)
3367        __(movl misc_header_offset(%arg_z),%imm0)
3368        __(cmpb $subtag_bignum,%imm0_b)
3369        __(jne 9f)
3370        __(cmpl $three_digit_bignum_header,%imm0)
3371        __(ja 9f)
3372        __(je 3f)
3373        __(cmpl $two_digit_bignum_header,%imm0)
3374        __(je 2f)
3375        /* must be a one digit bignum */
3376        __(movl misc_data_offset(%arg_z),%imm0)
3377        __(test %imm0,%imm0)
3378        __(js 9f)
3379        __(movd %imm0,%mm0)
3380        __(ret)
33812:      __(movl misc_data_offset+4(%arg_z),%imm0)
3382        __(testl %imm0,%imm0)
3383        __(js 9f)
3384        __(movq misc_data_offset(%arg_z),%mm0)
3385        __(ret)
33863:      __(movl misc_data_offset(%arg_z),%imm0)
3387        __(cmpl $0,misc_data_offset+8(%arg_z))
3388        __(jne 9f)
3389        __(movq misc_data_offset(%arg_z),%mm0)
3390        __(repret)
33919:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3392_endsubp(getu64)
3393
3394/* Make unsigned integer from value in mm0 */
3395_spentry(makeu64)
3396        __(movq %mm0,%mm1)
3397        __(psrlq $32,%mm0)
3398        __(movd %mm0,%imm0)
3399        __(test %imm0,%imm0)
3400        __(js 3f)
3401        __(jnz 2f)
3402        __(movd %mm1,%imm0)
3403        __(cmpl $target_most_positive_fixnum,%imm0)
3404        __(ja 1f)
3405        __(box_fixnum(%imm0,%arg_z))
3406        __(ret)
34071:      /* maybe make a 1 digit bignum */
3408        __(test %imm0,%imm0)
3409        __(js 2f)
3410        __(movl $one_digit_bignum_header,%imm0)
3411        __(movd %imm0,%mm0)
3412        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3413        __(movd %mm1,misc_data_offset(%arg_z))
3414        __(ret)
3415        /* make a 2 digit bignum */
34162:      __(movl $two_digit_bignum_header,%imm0)
3417        __(movd %imm0,%mm0)
3418        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3419        __(movq %mm1,misc_data_offset(%arg_z))
3420        __(ret)
3421        /* make a 3 digit bignum */
34223:      __(movl $three_digit_bignum_header,%imm0)
3423        __(movd %imm0,%mm0)
3424        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
3425        __(movq %mm1,misc_data_offset(%arg_z))
3426        __(ret)
3427_endsubp(makeu64)
3428
3429/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
3430/* unbound_marker), arg_y = symbol */
3431_spentry(specref)
3432        __(movl symbol.binding_index(%arg_z),%imm0)
3433        __(cmp rcontext(tcr.tlb_limit),%imm0)
3434        __(movl rcontext(tcr.tlb_pointer),%temp1)
3435        __(movl %arg_z,%arg_y)
3436        __(jae 7f)
3437        __(movl (%temp1,%imm0),%arg_z)
3438        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3439        __(jne 8f)
34407:      __(movl symbol.vcell(%arg_y),%arg_z)
34418:      __(repret)             
3442_endsubp(specref)
3443
3444/* arg_y = special symbol, arg_z = new value. */
3445_spentry(specset)
3446        __(movl symbol.binding_index(%arg_y),%imm0)
3447        __(cmp rcontext(tcr.tlb_limit),%imm0)
3448        __(movl rcontext(tcr.tlb_pointer),%temp1)
3449        __(jae 1f)
3450        __(movl (%temp1,%imm0),%temp0)
3451        __(cmpb $no_thread_local_binding_marker,%temp0_b)
3452        __(je 1f)
3453        __(movl %arg_z,(%temp1,%imm0))
3454        __(ret)
34551:      __(movl %arg_y,%temp0)
3456        __(movl $1<<fixnumshift,%arg_y)
3457        __(jmp _SPgvset)
3458_endsubp(specset)
3459
3460_spentry(specrefcheck)
3461        __(mov %arg_z,%arg_y)
3462        __(movl symbol.binding_index(%arg_z),%imm0)
3463        __(cmp rcontext(tcr.tlb_limit),%imm0)
3464        __(jae 7f)
3465        __(movl rcontext(tcr.tlb_pointer),%temp1)
3466        __(movl (%temp1,%imm0),%arg_z)
3467        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3468        __(cmovel symbol.vcell(%arg_y),%arg_z)
3469        __(cmpb $unbound_marker,%arg_z_b)
3470        __(je 9f)
34718:      __(repret)
34727:      __(movl symbol.vcell(%arg_y),%arg_z)
3473        __(cmpb $unbound_marker,symbol.vcell(%arg_y))
3474        __(je 9f)
3475        __(repret)
34769:      __(uuo_error_reg_unbound(Rarg_y))
3477_endsubp(specrefcheck)
3478
3479_spentry(restoreintlevel)
3480        __(hlt)
3481_endsubp(restoreintlevel)
3482
3483/* Make a lisp integer from the unsigned value in imm0 */
3484_spentry(makeu32)
3485        __(cmpl $target_most_positive_fixnum,%imm0)
3486        __(ja 0f)       /* need to make a bignum */
3487        __(box_fixnum(%imm0,%arg_z))
3488        __(ret)
34890:      __(movd %imm0,%mm1)
3490        __(test %imm0,%imm0)
3491        __(js 1f)
3492        __(movl $one_digit_bignum_header,%imm0)
3493        __(movd %imm0,%mm0)
3494        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3495        __(movd %mm1,misc_data_offset(%arg_z))
3496        __(ret)
34971:      __(movl $two_digit_bignum_header,%imm0)
3498        __(movd %imm0,%mm0)
3499        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3500        __(movd %mm1,misc_data_offset(%arg_z))
3501        __(ret)
3502_endsubp(makeu32)
3503
3504/* arg_z is of type (signed-byte 32) */
3505/* return unboxed value in %imm0 */
3506_spentry(gets32)
3507        __(testb $fixnummask,%arg_z_b)
3508        __(jne 1f)
3509        __(unbox_fixnum(%arg_z,%imm0))
3510        __(ret)
35111:      __(movb %arg_z_b,%imm0_b)
3512        __(andb $tagmask,%imm0_b)
3513        __(cmpb $tag_misc,%imm0_b)
3514        __(jne 9f)
3515        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3516        __(cmpb $subtag_bignum,%imm0_b)
3517        __(jne 9f)
3518        __(movl misc_header_offset(%arg_z),%imm0)
3519        __(cmpl $one_digit_bignum_header,%imm0)
3520        __(jne 9f)
3521        __(movl misc_data_offset(%arg_z),%imm0)
3522        __(ret)
35239:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_signed_byte_32))
3524_endsubp(gets32)
3525
3526/* arg_z is of type (unsigned-byte 32) */
3527/* return unboxed value in %imm0 */
3528_spentry(getu32)
3529        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3530        __(testl %arg_z,%imm0)
3531        __(movl %arg_z,%imm0)
3532        __(jne 1f)
3533        __(sarl $fixnumshift,%imm0)
3534        __(ret)
35351:      __(andb $tagmask,%imm0_b)
3536        __(cmpb $tag_misc,%imm0_b)
3537        __(jne 9f)
3538        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3539        __(cmpb $subtag_bignum,%imm0_b)
3540        __(jne 9f)
3541        __(movl misc_header_offset(%arg_z),%imm0)
3542        __(cmpl $two_digit_bignum_header,%imm0)
3543        __(je 2f)
3544        __(cmpl $one_digit_bignum_header,%imm0)
3545        __(jne 9f)
3546        __(movl misc_data_offset(%arg_z),%imm0)
3547        __(ret)
35482:      __(movl misc_data_offset(%arg_z),%imm0)
3549        __(cmpl $0,misc_data_offset+4(%arg_z))
3550        __(jne 9f)
3551        __(ret)
35529:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_unsigned_byte_32))
3553_endsubp(getu32)
3554
3555_spentry(mvpasssym)
3556        __(hlt)
3557_endsubp(mvpasssym)
3558
3559/* don't smash arg_z */
3560_spentry(unbind)
3561        __(push %arg_z)
3562        __(movl rcontext(tcr.db_link),%imm0)
3563        __(movl rcontext(tcr.tlb_pointer),%arg_z)
3564        __(movl binding.sym(%imm0),%temp0)
3565        __(movl binding.val(%imm0),%arg_y)
3566        __(movl binding.link(%imm0),%imm0)
3567        __(movl %arg_y,(%arg_z,%temp0))
3568        __(movl %imm0,rcontext(tcr.db_link))
3569        __(pop %arg_z)
3570        __(ret)
3571_endsubp(unbind)
3572
3573_spentry(unbind_n)
3574        __(push %temp1)         /* preserve temp1/nargs */
3575        __(push %arg_z)
3576        __(xorl %arg_z,%arg_z)
3577        __(movl rcontext(tcr.db_link),%temp1)
3578        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35791:             
3580        __(movl binding.sym(%temp1),%temp0)
3581        __(movl binding.val(%temp1),%arg_y)
3582        __(movl binding.link(%temp1),%temp1)
3583        __(movl %arg_y,(%arg_z,%temp0))
3584        __(decl %imm0)
3585        __(jne 1b)
3586        __(movl %temp1,rcontext(tcr.db_link))
3587        __(pop %arg_z)
3588        __(pop %temp1)
3589        __(ret) 
3590_endsubp(unbind_n)
3591
3592_spentry(unbind_to)
3593        __(push %arg_y)
3594        __(push %arg_z)
3595        __(push %temp0)
3596        __(push %temp1)
3597       
3598        __(movl rcontext(tcr.db_link),%temp0)
3599        __(movl rcontext(tcr.tlb_pointer),%arg_z)
36001:
3601        __(movl binding.sym(%temp0),%temp1)
3602        __(movl binding.val(%temp0),%arg_y)
3603        __(movl binding.link(%temp0),%temp0)
3604        __(movl %arg_y,(%arg_z,%temp1))
3605        __(cmpl %temp0,%imm0)
3606        __(jne 1b)
3607        __(movl %temp0,rcontext(tcr.db_link))
3608
3609        __(pop %temp1)
3610        __(pop %temp0)
3611        __(pop %arg_z)
3612        __(pop %arg_y)
3613        __(ret)
3614_endsubp(unbind_to)
3615
3616_spentry(bind_interrupt_level_0)
3617        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3618        __(cmpl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3619        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3620        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3621        __(push rcontext(tcr.db_link))
3622        __(movl %esp,rcontext(tcr.db_link))
3623        __(movl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3624        __(js 1f)
36250:      __(jmp *%ra0)
3626        /* Interrupt level was negative; interrupt may be pending */
36271:      __(check_pending_enabled_interrupt(2f))
36282:      __(jmp *%ra0)
3629_endsubp(bind_interrupt_level_0)
3630
3631/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3632/* of disabling interrupts.)   */
3633_spentry(bind_interrupt_level_m1)
3634        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3635        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3636        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3637        __(push rcontext(tcr.db_link))
3638        __(movl %esp,rcontext(tcr.db_link))
3639        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3640        __(jmp *%ra0)
3641_endsubp(bind_interrupt_level_m1)
3642
3643/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
3644/* do what _SPbind_interrupt_level_0 does. */
3645_spentry(bind_interrupt_level)
3646        __(test %arg_z,%arg_z)
3647        __(jz _SPbind_interrupt_level_0)
3648        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3649        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3650        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3651        __(push rcontext(tcr.db_link))
3652        __(movl %esp,rcontext(tcr.db_link))
3653        __(movl %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3654        __(jmp *%ra0)
3655_endsubp(bind_interrupt_level)
3656
3657/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
3658/* non-negative, check for pending interrupts. */
3659_spentry(unbind_interrupt_level)
3660        __(btl $TCR_FLAG_BIT_PENDING_SUSPEND,rcontext(tcr.flags))
3661        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3662        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
3663        __(jc 5f)
36640:      __(test %imm0,%imm0)
3665        __(movl rcontext(tcr.db_link),%imm0)
3666        __(movl binding.val(%imm0),%temp0)
3667        __(movl binding.link(%imm0),%imm0)
3668        __(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3669        __(movl %imm0,rcontext(tcr.db_link))
3670        __(js 3f)
36712:      __(repret)
36723:      __(test %temp0,%temp0)
3673        __(js 2b)
3674        __(check_pending_enabled_interrupt(4f))
36754:      __(repret)
36765:       /* Missed a suspend request; force suspend now if we're restoring
3677          interrupt level to -1 or greater */
3678        __(cmpl $-2<<fixnumshift,%imm0)
3679        __(jne 0b)
3680        __(movl rcontext(tcr.db_link),%temp0)
3681        __(movl binding.val(%temp0),%temp0)
3682        __(cmpl %imm0,%temp0)
3683        __(je 0b)
3684        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3685        __(suspend_now())
3686        __(jmp 0b)
3687_endsubp(unbind_interrupt_level)
3688
3689_spentry(progvrestore)
3690        __(movl rcontext(tcr.save_tsp),%imm0)
3691        __(movl tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3692        __(movl tsp_frame.data_offset(%imm0),%imm0)
3693        __(shrl $fixnumshift,%imm0)
3694        __(jne _SPunbind_n)
3695        __(repret)
3696_endsubp(progvrestore)
3697
3698/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3699/* inline.  Call out otherwise.   */
3700_spentry(builtin_plus)
3701        __(movl %arg_y,%imm0)
3702        __(orl %arg_z,%imm0)
3703        __(testb $fixnummask,%imm0_b)
3704        __(jne 1f)
3705        __(addl %arg_y,%arg_z)
3706        __(jo C(fix_one_bit_overflow))
3707        __(repret)
37081:      __(jump_builtin(_builtin_plus,2))
3709_endsubp(builtin_plus)
3710
3711/* %arg_z <- %arg_y - %arg_z.  Do the fixnum case - including overflow -  */
3712/*  inline.  Call out otherwise.   */
3713_spentry(builtin_minus)
3714        __(movl %arg_y,%imm0)
3715        __(orl %arg_z,%imm0)
3716        __(testb $fixnummask,%imm0_b)
3717        __(jne 1f)
3718        __(xchgl %arg_y,%arg_z)
3719        __(subl %arg_y,%arg_z)
3720        __(jo C(fix_one_bit_overflow))
3721        __(repret)
37221:      __(jump_builtin(_builtin_minus,2))
3723_endsubp(builtin_minus)
3724
3725/* %arg_z -< arg_y * arg_z. */
3726/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
3727_spentry(builtin_times)
3728        __(movl %arg_y,%imm0)
3729        __(orb %arg_z_b,%imm0_b)
3730        __(testb $fixnummask,%imm0_b)
3731        __(jne 2f)
3732        __(unbox_fixnum(%arg_z,%imm0))
3733        /* 32-bit fixnum result in %imm0.  Overflow set if it doesn't fit. */
3734        __(imul %arg_y,%imm0)
3735        __(jo 1f)
3736        __(movl %imm0,%arg_z)
3737        __(ret)
37381:      __(unbox_fixnum(%arg_z,%eax))
3739        __(mark_as_imm(%edx))
3740        __(unbox_fixnum(%arg_y,%edx))
3741        __(imul %edx)
3742        __(movd %eax,%mm0)
3743        __(movd %edx,%mm1)
3744        __(mark_as_node(%edx))
3745        __(psllq $32,%mm1)
3746        __(por %mm1,%mm0)
3747        __(jmp _SPmakes64)
37482:      __(jump_builtin(_builtin_times,2))
3749_endsubp(builtin_times)
3750
3751_spentry(builtin_div)
3752        __(jump_builtin(_builtin_div,2))
3753
3754/* %arg_z <- (= %arg_y %arg_z).   */
3755_spentry(builtin_eq)
3756        __(movl %arg_y,%imm0)
3757        __(orb %arg_z_b,%imm0_b)
3758        __(testb $fixnummask,%imm0_b)
3759        __(jne 1f)
3760        __(rcmpl(%arg_z,%arg_y))
3761        __(condition_to_boolean(e,%imm0,%arg_z))
3762        __(ret)
37631:      __(jump_builtin(_builtin_eq,2))
3764_endsubp(builtin_eq)
3765
3766/* %arg_z <- (/= %arg_y %arg_z).          */
3767_spentry(builtin_ne)
3768        __(movl %arg_y,%imm0)
3769        __(orb %arg_z_b,%imm0_b)
3770        __(testb $fixnummask,%imm0_b)
3771        __(jne 1f)
3772        __(rcmpl(%arg_z,%arg_y))
3773        __(condition_to_boolean(ne,%imm0,%arg_z))
3774        __(ret)
37751:      __(jump_builtin(_builtin_ne,2))
3776_endsubp(builtin_ne)
3777
3778/* %arg_z <- (> %arg_y %arg_z).   */
3779_spentry(builtin_gt)
3780        __(movl %arg_y,%imm0)
3781        __(orb %arg_z_b,%imm0_b)
3782        __(testb $fixnummask,%imm0_b)
3783        __(jne 1f)
3784        __(rcmpl(%arg_y,%arg_z))
3785        __(condition_to_boolean(g,%imm0,%arg_z))
3786        __(ret)
37871:      __(jump_builtin(_builtin_gt,2))
3788_endsubp(builtin_gt)
3789
3790/* %arg_z <- (>= %arg_y %arg_z).          */
3791_spentry(builtin_ge)
3792        __(movl %arg_y,%imm0)
3793        __(orb %arg_z_b,%imm0_b)
3794        __(testb $fixnummask,%imm0_b)
3795        __(jne 1f)
3796        __(rcmpl(%arg_y,%arg_z))
3797        __(condition_to_boolean(ge,%imm0,%arg_z))
3798        __(ret)
37991:      __(jump_builtin(_builtin_ge,2))
3800_endsubp(builtin_ge)
3801
3802/* %arg_z <- (< %arg_y %arg_z).   */
3803_spentry(builtin_lt)
3804        __(movl %arg_y,%imm0)
3805        __(orb %arg_z_b,%imm0_b)
3806        __(testb $fixnummask,%imm0_b)
3807        __(jne 1f)
3808        __(rcmpl(%arg_y,%arg_z))
3809        __(condition_to_boolean(l,%imm0,%arg_z))
3810        __(ret)
38111:      __(jump_builtin(_builtin_lt,2))
3812_endsubp(builtin_lt)
3813
3814/* %arg_z <- (<= %arg_y %arg_z).   */
3815_spentry(builtin_le)
3816        __(movl %arg_y,%imm0)
3817        __(orb %arg_z_b,%imm0_b)
3818        __(testb $fixnummask,%imm0_b)
3819        __(jne 1f)
3820        __(rcmpl(%arg_y,%arg_z))
3821        __(condition_to_boolean(le,%imm0,%arg_z))
3822        __(ret)
38231:      __(jump_builtin(_builtin_le,2))
3824_endsubp(builtin_le)
3825
3826_spentry(builtin_eql)
3827        __(cmpl %arg_y,%arg_z)
3828        __(je 1f)
3829        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3830        /* and both have the same subtag. */
3831        __(movl %arg_y,%imm0)
3832        __(andb $tagmask,%imm0_b)
3833        __(cmpb $tag_misc,%imm0_b)
3834        __(jne 2f)
3835        __(movb %arg_z_b,%imm0_bh)
3836        __(andb $tagmask,%imm0_bh)
3837        __(cmpb %imm0_bh,%imm0_b)
3838        __(jne 2f)
3839        __(extract_subtag(%arg_y,%imm0_b))
3840        __(extract_subtag(%arg_z,%imm0_bh))
3841        __(cmpb %imm0_b,%imm0_bh)
3842        __(jne 2f)
3843        __(jump_builtin(_builtin_eql,2))
38441:      __(movl $t_value,%arg_z)
3845        __(ret)
38462:      __(movl $nil_value,%arg_z)
3847        __(ret)
3848_endsubp(builtin_eql)
3849
3850_spentry(builtin_length)
3851        __(extract_fulltag(%arg_z,%imm0))
3852        __(cmpl $tag_list,%imm0)
3853        __(jz 2f)
3854        __(andl $tagmask,%imm0)
3855        __(cmpl $tag_misc,%imm0)
3856        __(jnz 8f)
3857        __(extract_subtag(%arg_z,%imm0_b))
3858        __(rcmpb(%imm0_b,$min_vector_subtag))
3859        __(jb 8f)
3860        __(je 1f)
3861        /* (simple-array * (*)) */
3862        __(movl %arg_z,%arg_y)
3863        __(vector_length(%arg_y,%arg_z))
3864        __(ret)
38651:      /* vector header */
3866        __(movl vectorH.logsize(%arg_z),%arg_z)
3867        __(ret)
38682:      /* list.  Maybe null, maybe dotted or circular. */
3869        __(movl $-fixnumone,%arg_y)
3870        __(movl %arg_z,%temp0)  /* fast pointer */
3871        __(movl %arg_z,%temp1)  /* slow pointer */
38723:      __(movb %temp0_b,%al)
3873        __(andb $fulltagmask,%al)
3874        __(addl $fixnumone,%arg_y)
3875        __(compare_reg_to_nil(%temp0))
3876        __(je 9f)
3877        __(cmpb $fulltag_cons,%al)
3878        __(jne 8f)
3879        __(movb %temp1_b,%ah)
3880        __(andb $fulltagmask,%ah)
3881        __(_cdr(%temp0,%temp0))
3882        __(testl $fixnumone,%arg_y)
3883        __(je 3b)
3884        __(cmpb $fulltag_cons,%ah)
3885        __(jne 8f)
3886        __(_cdr(%temp1,%temp1))
3887        __(cmpl %temp0,%temp1)
3888        __(jne 3b)
38898:
3890        __(jump_builtin(_builtin_length,1))
38919:
3892        __(movl %arg_y,%arg_z)
3893        __(ret)
3894_endsubp(builtin_length)
3895
3896_spentry(builtin_seqtype)
3897        __(extract_fulltag(%arg_z,%imm0))
3898        __(cmpb $fulltag_cons,%imm0_b)
3899        __(jz 1f)
3900        __(cmpb $tag_misc,%imm0_b)
3901        __(jne 2f)
3902        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3903        __(rcmpb(%imm0_b,$min_vector_subtag))
3904        __(jb 2f)
3905        __(movl $nil_value,%arg_z)
3906        __(ret)
39071:      __(movl $t_value,%arg_z)
3908        __(ret)
39092:
3910        __(jump_builtin(_builtin_seqtype,1))
3911_endsubp(builtin_seqtype)
3912
3913_spentry(builtin_assq)
3914        __(cmpl $nil_value,%arg_z)
3915        __(je 5f)
39161:      __(movl %arg_z,%imm0)
3917        __(andb $fulltagmask,%imm0_b)
3918        __(cmpb $fulltag_cons,%imm0_b)
3919        __(jne 2f)
3920        __(_car(%arg_z,%temp0))
3921        __(_cdr(%arg_z,%arg_z))
3922        __(cmpl $nil_value,%temp0)
3923        __(je 4f)
3924        __(movl %temp0,%imm0)
3925        __(andb $fulltagmask,%imm0_b)
3926        __(cmpb $fulltag_cons,%imm0_b)
3927        __(jne 3f)
3928        __(_car(%temp0,%temp1))
3929        __(cmpl %temp1,%arg_y)
3930        __(jne 4f)
3931        __(movl %temp0,%arg_z)
3932        __(ret)
39334:      __(cmpl $nil_value,%arg_z)
39345:      __(jnz 1b)
3935        __(repret)
39362:      __(uuo_error_reg_not_list(Rarg_z))
39373:      __(uuo_error_reg_not_list(Rtemp0))
3938_endsubp(builtin_assq)
3939
3940_spentry(builtin_memq)
3941        __(cmpl $nil_value,%arg_z)
3942        __(jmp 3f)
39431:      __(movb $fulltagmask,%imm0_b)
3944        __(andb %arg_z_b,%imm0_b)
3945        __(cmpb $fulltag_cons,%imm0_b)
3946        __(jne 2f)
3947        __(_car(%arg_z,%temp1))
3948        __(_cdr(%arg_z,%temp0))
3949        __(cmpl %temp1,%arg_y)
3950        __(jz 4f)
3951        __(cmpl $nil_value,%temp0)
3952        __(movl %temp0,%arg_z)
39533:      __(jnz 1b)
39544:      __(repret)
39552:      __(uuo_error_reg_not_list(Rarg_z))
3956_endsubp(builtin_memq)
3957
3958logbitp_max_bit = 30
3959
3960_spentry(builtin_logbitp)
3961        /* Call out unless: both args fixnums, arg_y in [0, logbitp_max_bit) */
3962        __(movl %arg_z,%imm0)
3963        __(orl %arg_y,%imm0)
3964        __(testb $fixnummask,%imm0_b)
3965        __(jnz 1f)
3966        __(unbox_fixnum(%arg_y,%imm0))
3967        __(js 1f)       /* bit number negative */
3968        __(addb $fixnumshift,%imm0_b)
3969        __(cmpl $logbitp_max_bit<<fixnumshift,%arg_y)
3970        __(jb 2f)
3971        __(movl $logbitp_max_bit-1+fixnumshift,%imm0)
39722:      __(bt %imm0,%arg_z)
3973        __(condition_to_boolean(b,%imm0,%arg_z))
3974        __(ret)
39751:      __(jump_builtin(_builtin_logbitp,2))
3976_endsubp(builtin_logbitp)
3977
3978_spentry(builtin_logior)
3979        __(movl %arg_y,%imm0)
3980        __(orb %arg_z_b,%imm0_b)
3981        __(testb $fixnummask,%imm0_b)
3982        __(jne 1f)
3983        __(orl %arg_y,%arg_z)
3984        __(ret)
39851:
3986        __(jump_builtin(_builtin_logior,2))
3987_endsubp(builtin_logior)
3988
3989_spentry(builtin_logand)
3990        __(movl %arg_y,%imm0)
3991        __(orb %arg_z_b,%imm0_b)
3992        __(testb $fixnummask,%imm0_b)
3993        __(jne 1f)
3994        __(andl %arg_y,%arg_z)
3995        __(ret)
39961:
3997        __(jump_builtin(_builtin_logand,2))
3998_endsubp(builtin_logand)
3999
4000_spentry(builtin_negate)
4001        __(testb $fixnummask,%arg_z_b)
4002        __(jne 1f)
4003        __(negl %arg_z)
4004        __(jo C(fix_one_bit_overflow))
4005        __(repret)
40061:
4007        __(jump_builtin(_builtin_negate,1))
4008_endsubp(builtin_negate)
4009
4010_spentry(builtin_logxor)
4011        __(movl %arg_y,%imm0)
4012        __(orb %arg_z_b,%imm0_b)
4013        __(testb $fixnummask,%imm0_b)
4014        __(jne 1f)
4015        __(xorl %arg_y,%arg_z)
4016        __(ret)
40171:
4018        __(jump_builtin(_builtin_logxor,2))
4019_endsubp(builtin_logxor)
4020
4021/* temp0 = vector, arg_y = index, arg_z = newval */
4022_spentry(aset1)
4023        __(extract_typecode(%temp0,%imm0))
4024        __(box_fixnum(%imm0,%temp1))
4025        __(cmpb $min_vector_subtag,%imm0_b)
4026        __(ja _SPsubtag_misc_set)
4027        /* push frame... */
4028        __(pop %temp1)
4029        __(push $reserved_frame_marker)
4030        __(push $reserved_frame_marker)
4031        __(push %temp0)
4032        __(push %temp1)
4033        /* and fall through... */
4034_endsubp(aset1)
4035
4036_spentry(builtin_aset1)
4037        __(jump_builtin(_builtin_aset1,3))
4038_endsubp(builtin_aset1)
4039
4040_spentry(builtin_ash)
4041        __(movl %arg_y,%imm0)
4042        __(orb %arg_z_b,%imm0_b)
4043        __(testb $fixnummask,%imm0_b)
4044        __(jne 9f)
4045        __(unbox_fixnum(%arg_z,%imm0))
4046        /* Z flag set if zero ASH shift count */
4047        __(jnz 1f)
4048        __(movl %arg_y,%arg_z) /* shift by 0 */
4049        __(ret)
40501:      __(jns 3f)
4051        __(rcmpl(%imm0,$-31))
4052        __(jg 2f)
4053        __(unbox_fixnum(%arg_y,%imm0))
4054        __(sar $31,%imm0)
4055        __(box_fixnum(%imm0,%arg_z))
4056        __(ret)
40572:      /* Right-shift by small fixnum */
4058        __(negb %imm0_b)
4059        __(movzbl %imm0_b,%ecx)
4060        __(unbox_fixnum(%arg_y,%imm0))
4061        __(sar %cl,%imm0)
4062        __(box_fixnum(%imm0,%arg_z))
4063        __(ret)
40643:      /* Left shift by fixnum.  We can't shift by more than 31 bits, */
4065        /* though shifting by 32 is actually easy. */
4066        __(rcmpl(%imm0,$32))
4067        __(jg 9f)
4068        __(jne 4f)
4069        /* left-shift by 32 bits exactly */
4070        __(unbox_fixnum(%arg_y,%imm0))
4071        __(movd %imm0,%mm0)
4072        __(psllq $32,%mm0)
4073        __(jmp _SPmakes64)
40744:      /* left-shift by 1..31 bits. Safe to move shift count to %cl */
4075        __(movd %imm0,%mm1)     /* shift count */
4076        __(unbox_fixnum(%arg_y,%imm0))
4077        __(movd %imm0,%mm0)
4078        __(sarl $31,%imm0)      /* propagate sign */
4079        __(movd %imm0,%mm2)
4080        __(pshufw $0x4e,%mm2,%mm2) /* swap hi/lo halves */
4081        __(por %mm2,%mm0)
4082        __(psllq %mm1,%mm0)
4083        __(jmp _SPmakes64)
40849:
4085        __(jump_builtin(_builtin_ash,2))
4086_endsubp(builtin_ash)
4087
4088_spentry(builtin_aref1)
4089        __(extract_typecode(%arg_y,%imm0))
4090        __(box_fixnum_no_flags(%imm0,%temp0))
4091        __(cmpb $min_vector_subtag,%imm0_b)
4092        __(ja _SPsubtag_misc_ref)
4093        __(jump_builtin(_builtin_aref1,2))
4094_endsubp(builtin_aref1)
4095
4096/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
4097/* if so.  This might allow us to avoid having to have a priori */
4098/* knowledge of whether a foreign function returns a floating-point result. */
4099/* backlink to saved %esp, below */
4100/* arg n-1 */
4101/* arg n-2 */
4102/* ... */
4103/* arg 0 */
4104/* space for alignment */
4105/* previous %esp */
4106
4107_spentry(ffcall)
4108LocalLabelPrefix[]ffcall:
4109        __(unbox_fixnum(%arg_z,%imm0))
4110        __(testb $fixnummask,%arg_z_b)
4111        __(je 0f)
4112        __(movl macptr.address(%arg_z),%imm0)
41130:
4114        /* Save lisp registers. */
4115        __(push %ebp)
4116        __(mov %esp,%ebp)
4117        __(push %temp0)                 
4118        __(push %temp1)                 
4119        __(push %arg_y)                 
4120        __(push %arg_z)                 
4121        __(push %fn)         
4122        __ifdef([WIN32_ES_HACK])
4123         __(movl rcontext(tcr.linear),%ebx)
4124        __endif
4125        __(movl %esp,rcontext(tcr.save_vsp))
4126        __(movl %ebp,rcontext(tcr.save_ebp))
4127        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4128        __(movl rcontext(tcr.foreign_sp),%esp)
4129        /* preserve state of direction flag */
4130        __(pushfl)
4131        __(popl rcontext(tcr.save_eflags))
4132        __(cld)       
4133        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4134        __(emms)
4135        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4136        __(movl (%esp),%ebp)
4137LocalLabelPrefix[]ffcall_setup:
4138        __(lea 15(%esp),%ecx)
4139        __(andl $-16,%ecx)
4140        __(movl %ecx,%esp)
4141/*      __(addl $node_size,%esp) */
4142        __ifdef([WIN32_ES_HACK])
4143         __(push %ds)
4144         __(pop %es)
4145        __endif
4146LocalLabelPrefix[]ffcall_call:
4147        __(call *%eax)
4148        __ifdef([WIN32_ES_HACK])
4149         __(movw tcr.ldt_selector(%ebx),%rcontext_reg)
4150        __endif
4151LocalLabelPrefix[]ffcall_call_end:
4152        __(movl %ebp,%esp)
4153        __(movl %esp,rcontext(tcr.foreign_sp))
4154        /* The high word of a 64-bit result would be in %edx right now.
4155           There doesn't seem to be any other good place to put this,
4156           though %edx is often undefined at this point. */
4157        __(mov %edx,rcontext(tcr.unboxed1))
4158        __(clr %arg_z)
4159        __(clr %arg_y)
4160        __(clr %temp1)
4161        __(clr %temp0)
4162        __(clr %fn)
4163        __(pxor %fpzero,%fpzero)
4164        __(cmpb $0,C(bogus_fp_exceptions))
4165        __(je 0f)
4166        __(movl %arg_z,rcontext(tcr.ffi_exception))
4167        __(jmp 1f)
41680:
4169        __ifdef([SSE2_MATH_LIB])
4170        __(stmxcsr rcontext(tcr.ffi_exception))
4171        __else
4172        __(fnstsw rcontext(tcr.ffi_exception))
4173        __endif
41741:      __(pushl rcontext(tcr.save_eflags))
4175        __(popfl)
4176        __(movl rcontext(tcr.save_vsp),%esp)
4177        __(movl rcontext(tcr.save_ebp),%ebp)
4178        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4179        __(pop %fn)             
4180        __(pop %arg_z)           
4181        __(pop %arg_y)           
4182        __(pop %temp1)
4183        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4184        __(check_pending_interrupt(%temp0))
4185        __(pop %temp0)
4186        __(leave)
4187        __(ret)
4188        /* need to deal with NSExceptions and Objc-2.0 execptions */
4189_endsubp(ffcall)
4190
4191_spentry(ffcall_return_registers)
4192        __(hlt)
4193_endsubp(ffcall_return_registers)
4194
4195/* We need to reserve a frame here if (a) nothing else was already pushed
4196/* and (b) we push something (e.g., more than 2 args in the lexpr) */
4197_spentry(spread_lexprz)
4198        new_local_labels()
4199        __(movl (%arg_z),%imm0) /* lexpr count */
4200        __(leal node_size(%arg_z,%imm0),%arg_y)
4201        __(movd %arg_y,%mm1)
4202        __(test %nargs,%nargs) /* anything pushed by caller ? */
4203        __(jne 0f)              /* yes, caller has already created frame. */
4204        __(cmpl $(nargregs*node_size),%imm0) /* will we push anything ? */
4205        __(jbe 0f)
4206        __(push $reserved_frame_marker)
4207        __(push $reserved_frame_marker)
42080:      __(addl %imm0,%nargs)
4209        __(cmpl $(1*node_size),%imm0)
4210        __(ja 2f)
4211        __(je 1f)
4212        /* lexpr count was 0; vpop the args that */
4213        /* were pushed by the caller */
4214        __(test %nargs,%nargs)
4215        __(je local_label(all_args_popped))
4216        __(pop %arg_z)
4217local_label(maybe_pop_y):
4218        __(cmpl $(1*node_size),%nargs)
4219        __(je local_label(all_args_popped))
4220        __(pop %arg_y)
4221local_label(all_args_popped):   
4222        /* If all args fit in registers but some were pushed */
4223        /* by the caller, discard the reserved frame that the caller */
4224        /* pushed.         */
4225        __(cmpl %imm0,%nargs)
4226        __(je local_label(go))
4227        __(cmpl $(nargregs*node_size),%nargs)
4228        __(ja local_label(go))
4229        __(addl $(2*node_size),%esp)
4230local_label(go):
4231        __(jmp *%ra0)
4232
4233        /* lexpr count is two or more: vpush args from the lexpr until */
4234        /* we have only two left, then assign them to arg_y and arg_z */
42352:      __(cmpl $(2*node_size),%imm0)
4236        __(je local_label(push_loop_end))
4237local_label(push_loop):
4238        __(lea -1*node_size(%imm0),%imm0)
4239        __(push -node_size(%arg_y))
4240        __(lea -1*node_size(%arg_y),%arg_y)
4241        __(cmpl $(2*node_size),%imm0)
4242        __(jne 2b)
4243local_label(push_loop_end):
4244        __(movl -node_size*2(%arg_y),%arg_z)
4245        __(movl -node_size*1(%arg_y),%arg_y)
4246        __(jmp *%ra0)
4247        /* lexpr count is one: set arg_z from the lexpr, */
4248        /* maybe vpop arg_y  */
42491:      __(movl -node_size*1(%arg_y),%arg_z)
4250        __(jmp local_label(maybe_pop_y))
4251_endsubp(spread_lexprz)
4252
4253_spentry(callback)
4254        __(push %ebp)
4255        __(movl %esp,%ebp)
4256        /* C scalar args are already on the stack. */
4257        /* arg word 0 at 8(%ebp), word 1 at 12(%ebp), etc. */
4258
4259        /* %eax is passed to us via the callback trampoline.
4260           bits 0-22: callback index
4261           bit 23: flag, set if we need to discard hidden arg on return
4262                   (ignored when upper 8 bits are non-zero)
4263           bits 24-31: arg words to discard on return (_stdcall for win32) */
4264       
4265        /* Reserve some space for results, relative to the
4266           current %ebp.  We may need quite a bit of it. */
4267        __(subl $20,%esp)
4268        __(movl $0,-16(%ebp)) /* No FP result */
4269        __(btl $23,%eax)      /* set CF if we need to discard hidden arg */
4270        __(pushfl)            /* and save for later */
4271        __(movl %eax,%ecx)    /* extract args-discard count */
4272        __(shrl $24,%ecx)
4273        __(andl $0x007fffff,%eax) /* callback index */
4274        __(movl %ecx,-12(%ebp))
4275        /* If the C stack is 16-byte aligned by convention,
4276           it should still be, and this'll be a NOP. */
4277        __(andl $~15,%esp)
4278        /* C NVRs */
4279        __(push %edi)
4280        __(push %esi)
4281        __(push %ebx)
4282        __(push %ebp)
4283        __(box_fixnum(%eax,%esi))       /* put callback index in arg_y */
4284        __(cmpb $0,C(rcontext_readonly))
4285        __(jne 0f)
4286        __(ref_global(get_tcr,%eax))
4287        __(subl $12,%esp)               /* alignment */
4288        __(push $1)                     /* stack now 16-byte aligned */
4289        __(call *%eax)
4290        __(addl $16,%esp)               /* discard arg, alignment words */
4291        /* linear TCR addr now in %eax */
4292        __(movw tcr.ldt_selector(%eax), %rcontext_reg)
42930:     
4294
4295        /* ebp is 16-byte aligned, and we've pushed 4 words.  Make
4296          sure that when we push old foreign_sp, %esp will be 16-byte
4297          aligned again */
4298        __(subl $8,%esp)
4299        __(pushl rcontext(tcr.save_ebp))  /* mark cstack frame's "owner" */
4300        __(push rcontext(tcr.foreign_sp))
4301        __(movl %esp,rcontext(tcr.foreign_sp))
4302        __(clr %arg_z)
4303        /* arg_y contains callback index */
4304        __(clr %temp1)
4305        __(clr %temp0)
4306        __(clr %fn)
4307        __(pxor %fpzero,%fpzero)
4308        __(movl rcontext(tcr.save_vsp),%esp)
4309        __(movl %ebp,%arg_z)
4310        __(movl rcontext(tcr.save_ebp),%ebp)
4311        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4312        __(stmxcsr rcontext(tcr.foreign_mxcsr))
4313        __(andb $~mxcsr_all_exceptions,rcontext(tcr.foreign_mxcsr))
4314        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4315        __(movl $nrs.callbacks,%fname)
4316        __(check_cstack_alignment())
4317        __(push $local_label(back_from_callback))
4318        __(set_nargs(2))
4319        __(jump_fname())
4320__(tra(local_label(back_from_callback)))
4321        __(movl %esp,rcontext(tcr.save_vsp))
4322        __(movl %ebp,rcontext(tcr.save_ebp))
4323        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4324        __(movl rcontext(tcr.foreign_sp),%esp)
4325        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4326        __(emms)
4327        __(pop rcontext(tcr.foreign_sp))
4328        __(addl $12,%esp)       /* discard alignment padding */
4329        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4330        __ifdef([WIN32_ES_HACK])
4331         __(push %ds)
4332         __(pop %es)
4333        __endif
4334        __(pop %ebp)
4335        __(pop %ebx)
4336        __(pop %esi)
4337        __(pop %edi)
4338        __(cmpb $1,-16(%ebp))
4339        __(movl -12(%ebp),%ecx) /* magic value for ObjC bridge or winapi */
4340        __(jae 1f)
4341        __(movl -8(%ebp),%eax)
4342        __(movl -4(%ebp),%edx)
4343        __ifdef([WIN_32])
4344         __(testl %ecx,%ecx)
4345         __(jne local_label(winapi_return))
4346        __endif
4347        __(popfl)       /* flags from bt way back when */
4348        __(jc local_label(discard_first_arg))
4349        __(leave)
4350        __(ret)
43511:      __(jne 2f)
4352        /* single float return in x87 */
4353        __(flds -8(%ebp))
4354        __ifdef([WIN_32])
4355         __(testl %ecx,%ecx)
4356         __(jne local_label(winapi_return))
4357        __endif
4358        __(leave)
4359        __(ret)
43602:      /* double-float return in x87 */
4361        __(fldl -8(%ebp))
4362        __ifdef([WIN_32])
4363         __(testl %ecx,%ecx)
4364         __(jne local_label(winapi_return))
4365        __endif
4366        __(leave)
4367        __(ret)
4368        __ifdef([WIN_32])
4369local_label(winapi_return):
4370          __(leave)
4371         /* %ecx is non-zero and contains count of arg words to pop */
4372          __(popl -4(%esp,%ecx,4))
4373          __(leal -4(%esp,%ecx,4),%esp)
4374          __(ret)
4375        __endif
4376local_label(discard_first_arg):
4377        __(leave)
4378        __(ret $4)
4379_endsubp(callback)
4380
4381/* temp0 = array, arg_y = i, arg_z = j. Typecheck everything.
4382   We don't know whether the array is alleged to be simple or
4383   not, and don't know anythng about the element type.  */
4384
4385_spentry(aref2)
4386        __(testl $fixnummask,%arg_y)
4387        __(jne 0f)
4388        __(testb $fixnummask,%arg_z_b)
4389        __(jne 1f)
4390        __(extract_typecode(%temp0,%imm0))
4391        __(cmpb $subtag_arrayH,%imm0_b)
4392        __(jne 2f)
4393        __(cmpl $2<<fixnumshift,arrayH.rank(%temp0))
4394        __(jne 2f)
4395        __(cmpl arrayH.dim0(%temp0),%arg_y)
4396        __(jae 3f)
4397        __(movl arrayH.dim0+node_size(%temp0),%imm0)
4398        __(cmpl %imm0,%arg_z)
4399        __(jae 4f)
4400        __(sarl $fixnumshift,%imm0)
4401        __(imull %arg_y,%imm0)
4402        __(addl %imm0,%arg_z)
4403        __(movl %temp0,%arg_y)
4404        __(xorl %temp1,%temp1)
44056:      __(addl arrayH.displacement(%arg_y),%arg_z)
4406        __(movl arrayH.data_vector(%arg_y),%arg_y)
4407        __(extract_subtag(%arg_y,%imm0_b))
4408        __(cmpb $subtag_vectorH,%imm0_b)
4409        __(ja C(misc_ref_common))
4410        __(jmp 6b)
44110:      __(uuo_error_reg_not_fixnum(Rarg_y))
44121:      __(uuo_error_reg_not_fixnum(Rarg_z))
44132:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
44143:      __(uuo_error_array_bounds(Rarg_y,Rtemp0))
44154:      __(uuo_error_array_bounds(Rarg_z,Rtemp0))
4416
4417_endsubp(aref2)
4418
4419/* Like aref2, but temp1 = array, temp0 = i, arg_y = j, arg_z = k */
4420_spentry(aref3)
4421        __(testb $fixnummask,%temp0_b)
4422        __(jne 0f)
4423        __(testl $fixnummask,%arg_y)
4424        __(jne 1f)
4425        __(testb $fixnummask,%arg_z_b)
4426        __(jne 2f)
4427        __(extract_typecode(%temp1,%imm0))
4428        __(cmpb $subtag_arrayH,%imm0_b)
4429        __(jne 3f)
4430        __(cmpl $3<<fixnumshift,arrayH.rank(%temp1))
4431        __(jne 3f)
4432        __(cmpl arrayH.dim0(%temp1),%temp0)
4433        __(jae 4f)
4434        __(movl arrayH.dim0+node_size(%temp1),%imm0)
4435        __(cmpl %imm0,%arg_y)
4436        __(jae 5f)
4437        __(cmpl arrayH.dim0+(node_size*2)(%temp1),%arg_z)
4438        __(jae 6f)
4439        /* index computation: k + dim2 * (j + dim1 * i) */
4440        /* (plus minor fussing for fixnum scaling) */
4441        __(sarl $fixnumshift,%imm0)
4442        __(imull %imm0,%temp0)
4443        __(addl %arg_y,%temp0)
4444        __(movl arrayH.dim0+(node_size*2)(%temp1),%imm0)
4445        __(sarl $fixnumshift,%imm0)
4446        __(imull %imm0,%temp0)
4447        __(addl %temp0,%arg_z)
4448        __(movl %temp1,%arg_y)
44498:      __(addl arrayH.displacement(%arg_y),%arg_z)
4450        __(movl arrayH.data_vector(%arg_y),%arg_y)
4451        __(extract_subtag(%arg_y,%imm0_b))
4452        __(cmpb $subtag_vectorH,%imm0_b)
4453        __(ja C(misc_ref_common))
4454        __(jmp 8b)
44550:      __(uuo_error_reg_not_fixnum(Rtemp0))
44561:      __(uuo_error_reg_not_fixnum(Rarg_y))
44572:      __(uuo_error_reg_not_fixnum(Rarg_z))
44583:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
44594:      __(uuo_error_array_bounds(Rtemp0,Rtemp1))
44605:      __(uuo_error_array_bounds(Rarg_y,Rtemp1))
44616:      __(uuo_error_array_bounds(Rarg_z,Rtemp1))
4462_endsubp(aref3)
4463
4464/* As with aref2, but temp1 = array, temp0 = i, arg_y = j, arg_z = new_value */
4465_spentry(aset2)
4466        __(testb $fixnummask,%temp0_b)
4467        __(jne 0f)
4468        __(testl $fixnummask,%arg_y)
4469        __(jne 1f)
4470        __(extract_typecode(%temp1,%imm0))
4471        __(cmpb $subtag_arrayH,%imm0_b)
4472        __(jne 2f)
4473        __(cmpl $2<<fixnumshift,arrayH.rank(%temp1))
4474        __(jne 2f)
4475        __(cmpl arrayH.dim0(%temp1),%temp0)
4476        __(jae 3f)
4477        __(movl arrayH.dim0+node_size(%temp1),%imm0)
4478        __(cmpl %imm0,%arg_y)
4479        __(jae 4f)
4480        __(sarl $fixnumshift,%imm0)
4481        __(imull %temp0,%imm0)
4482        __(addl %imm0,%arg_y)
4483        __(movl %temp1,%temp0)
4484        __(xorl %temp1,%temp1)
44856:      __(addl arrayH.displacement(%temp0),%arg_y)
4486        __(movl arrayH.data_vector(%temp0),%temp0)
4487        __(extract_subtag(%temp0,%imm0_b))
4488        __(cmpb $subtag_vectorH,%imm0_b)
4489        __(ja C(misc_set_common))
4490        __(jmp 6b)
44910:      __(uuo_error_reg_not_fixnum(Rtemp0))
44921:      __(uuo_error_reg_not_fixnum(Rarg_y))
44932:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_2d))
44943:      __(uuo_error_array_bounds(Rtemp0,Rtemp1))
44954:      __(uuo_error_array_bounds(Rarg_y,Rtemp1))
4496_endsubp(aset2)
4497
4498/* temp1 = array, (%esp) = i, temp0 = j, arg_y = k, arg_z = newval */
4499_spentry(aset3)
4500        __(testb $fixnummask,(%esp))
4501        __(jne 0f)
4502        __(testb $fixnummask,%temp0_b)
4503        __(jne 1f)
4504        __(testl $fixnummask,%arg_y)
4505        __(jne 2f)
4506        __(extract_typecode(%temp1,%imm0))
4507        __(cmpb $subtag_arrayH,%imm0_b)
4508        __(jne 3f)
4509        __(cmpl $3<<fixnumshift,arrayH.rank(%temp1))
4510        __(jne 3f)
4511        __(movl arrayH.dim0(%temp1),%imm0)
4512        __(cmpl %imm0,(%esp))   /* i on stack */
4513        __(jae 4f)
4514        __(movl arrayH.dim0+node_size(%temp1),%imm0)
4515        __(cmpl %imm0,%temp0)
4516        __(jae 5f)
4517        __(cmpl arrayH.dim0+(node_size*2)(%temp1),%arg_y)
4518        __(jae 6f)
4519        /* index computation: k + dim2 * (j + dim1 * i) */
4520        /* (plus minor fussing for fixnum scaling) */
4521        __(sarl $fixnumshift,%imm0)
4522        __(imull (%esp),%imm0)  /* i on stack */
4523        __(addl %imm0,%temp0)
4524        __(addl $node_size,%esp)
4525        __(movl arrayH.dim0+(node_size*2)(%temp1),%imm0)
4526        __(sarl $fixnumshift,%imm0)
4527        __(imull %imm0,%temp0)
4528        __(addl %temp0,%arg_y)
4529        __(movl %temp1,%temp0)
45308:      __(addl arrayH.displacement(%temp0),%arg_y)
4531        __(movl arrayH.data_vector(%temp0),%temp0)
4532        __(extract_subtag(%temp0,%imm0_b))
4533        __(cmpb $subtag_vectorH,%imm0_b)
4534        __(ja C(misc_set_common))
4535        __(jmp 8b)
45360:      __(pop %temp0)  /* supplied i */
4537        __(uuo_error_reg_not_fixnum(Rtemp0))
45381:      __(uuo_error_reg_not_fixnum(Rtemp0))
45392:      __(uuo_error_reg_not_fixnum(Rarg_y))
45403:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
45414:      __(pop %imm0)   /* supplied i is on stack */
4542        __(uuo_error_array_bounds(Rimm0,Rtemp1))
45435:      __(uuo_error_array_bounds(Rtemp0,Rtemp1))
45446:      __(uuo_error_array_bounds(Rarg_y,Rtemp1))
4545_endsubp(aset3)
4546
4547/* Prepend all but the first seven (6 words of code & other immediate data,
4548/* plus inner fn) and last (lfbits) elements of %fn to the "arglist". */
4549_spentry(call_closure)
4550        new_local_labels()
4551        __(vector_length(%fn,%imm0))
4552        __(subl $8<<fixnumshift,%imm0)  /* imm0 = inherited arg count */
4553        __(lea (%nargs,%imm0),%temp0)
4554        __(cmpl $nargregs<<fixnumshift,%temp0)
4555        __(jna local_label(regs_only))  /* either: 1 arg, 1 inherited, or */
4556                                        /* no args, 2 inherited */
4557        __(pop rcontext(tcr.save0))             /* save return address */
4558        __(cmpl $nargregs<<fixnumshift,%nargs)
4559        __(jna local_label(no_insert))
4560
4561/* Some arguments have already been pushed.  Push %imm0's worth */
4562/* of NILs, copy those arguments that have already been vpushed from */
4563/* the old TOS to the new, then insert all of the inherited args */
4564/* and go to the function. */
4565
4566        __(mov %imm0,%temp0)
4567local_label(push_nil_loop):
4568        __(push $nil_value)
4569        __(sub $fixnumone,%temp0)
4570        __(jne local_label(push_nil_loop))
4571
4572/* Need to use arg regs as temporaries.  Stash them in the spill area. */
4573        __(movl %arg_y,rcontext(tcr.save1))
4574        __(movl %arg_z,rcontext(tcr.save2))
4575
4576        __(leal (%esp,%imm0),%temp0)    /* start of already-pushed args */
4577        __(leal -nargregs<<fixnumshift(%nargs),%arg_y) /* args pushed */
4578        __(movd %imm0,%mm0)     /* save inherited arg count */
4579        __(xorl %imm0,%imm0)
4580local_label(copy_already_loop):
4581        __(movl (%temp0,%imm0),%arg_z)
4582        __(movl %arg_z,(%esp,%imm0))
4583        __(addl $fixnumone,%imm0)
4584        __(cmpl %imm0,%arg_y)
4585        __(jne local_label(copy_already_loop))
4586
4587        __(lea -node_size(%temp0,%imm0),%arg_y) /* start of args on stack */
4588        __(movl $7<<fixnumshift,%temp0) /* skip code, new fn */
4589        __(movd %mm0,%imm0)
4590local_label(insert_loop):
4591        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4592        __(addl $node_size,%temp0)
4593        __(addl $fixnumone,%nargs)
4594        __(movl %arg_z,(%arg_y))
4595        __(subl $node_size,%arg_y)
4596        __(subl $fixnumone,%imm0)
4597        __(jne local_label(insert_loop))
4598
4599        /* Recover arg regs, saved earlier */
4600        __(movl rcontext(tcr.save1),%arg_y)
4601        __(movl rcontext(tcr.save2),%arg_z)
4602        __(jmp local_label(go))
4603       
4604/* Here if no args were pushed by the caller. */
4605/* cases: */
4606/* no args, more than two inherited args */
4607/* a single arg in arg_z, more than one inherited arg */
4608/* two args in arg_y and arg_z, some number of inherited args */
4609
4610/* Therefore, we're always going to have to push something (the sum of */
4611/* %nargs and %imm0 will always be greater than $nargregs), and */
4612/* we will have to reserve space for a stack frame. */
4613/* The 0 args, 2 inherited case and the 1 arg, 1 inherited case get */
4614/* handled at local_label(regs_ony). */
4615       
4616local_label(no_insert):
4617        /* Reserve space for a stack frame */
4618        __(push $reserved_frame_marker)
4619        __(push $reserved_frame_marker)
4620        __(lea 7<<fixnumshift(%imm0),%temp0)    /* last inherited arg */
4621        __(rcmpl(%nargs,$fixnumone))
4622        __(je local_label(set_arg_y))
4623        __(jb local_label(set_y_z))
4624        /* %nargs = $nargregs (i.e., 2), vpush remaining inherited vars. */
4625
4626local_label(vpush_remaining):
4627        __(movl $7<<fixnumshift,%temp0)
4628local_label(vpush_remaining_loop):
4629        __(push misc_data_offset(%fn,%temp0))
4630        __(add $node_size,%temp0)
4631        __(add $fixnumone,%nargs)
4632        __(sub $node_size,%imm0)
4633        __(jnz local_label(vpush_remaining_loop))
4634        __(jmp local_label(go))
4635       
4636local_label(set_arg_y):
4637        /* one arg in arg_z.  set arg_y and vpush remaining inherited args */
4638        __(subl $node_size,%temp0)
4639        __(movl misc_data_offset(%fn,%temp0),%arg_y)
4640        __(addl $fixnumone,%nargs)
4641        __(subl $fixnumone,%imm0)
4642        __(jmp local_label(vpush_remaining))
4643local_label(set_y_z):
4644        __(subl $node_size,%temp0)
4645        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4646        __(addl $fixnumone,%nargs)
4647        __(subl $fixnumone,%imm0)
4648        __(jmp local_label(set_arg_y))
4649
4650local_label(go):
4651        __(movl misc_data_offset+(6*node_size)(%fn),%fn)
4652        __(push rcontext(tcr.save0))    /* restore return addr */
4653        __(movapd %fpzero,rcontext(tcr.save0))  /* clear out spill area */
4654        __(jmp *%fn)
4655local_label(regs_only):
4656        __(lea 7<<fixnumshift(%imm0),%temp0)
4657        __(test %nargs,%nargs)
4658        __(jne local_label(one_arg))
4659        /* no args passed, two inherited args */
4660        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_z)
4661        __(cmpl $node_size,%imm0)
4662        __(je local_label(rgo))
4663        __(movl misc_data_offset-(node_size*2)(%fn,%temp0),%arg_y)
4664local_label(rgo):
4665        __(addl %imm0,%nargs)
4666        __(jmp *misc_data_offset+(6*node_size)(%fn))
4667local_label(one_arg):
4668        /* one arg was passed, so there's one inherited arg */
4669        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_y)
4670        __(jmp local_label(rgo))
4671_endsubp(call_closure)
4672
4673_spentry(poweropen_callbackX)
4674        __(hlt)
4675_endsubp(poweropen_callbackX)
4676
4677_spentry(poweropen_ffcallX)
4678        __(hlt)
4679_endsubp(poweropen_ffcallX)
4680
4681_spentry(eabi_ff_call)
4682        __(hlt)
4683_endsubp(eabi_ff_call)
4684
4685_spentry(eabi_callback)
4686        __(hlt)
4687_endsubp(eabi_callback)
4688
4689
4690/* Unused, and often not used on PPC either  */
4691_spentry(callbuiltin)
4692        __(hlt)
4693_endsubp(callbuiltin)
4694
4695_spentry(callbuiltin0)
4696        __(hlt)
4697_endsubp(callbuiltin0)
4698
4699_spentry(callbuiltin1)
4700        __(hlt)
4701_endsubp(callbuiltin1)
4702
4703_spentry(callbuiltin2)
4704        __(hlt)
4705_endsubp(callbuiltin2)
4706
4707_spentry(callbuiltin3)
4708        __(hlt)
4709_endsubp(callbuiltin3)
4710
4711_spentry(restorefullcontext)
4712        __(hlt)
4713_endsubp(restorefullcontext)
4714
4715_spentry(savecontextvsp)
4716        __(hlt)
4717_endsubp(savecontextvsp)
4718
4719_spentry(savecontext0)
4720        __(hlt)
4721_endsubp(savecontext0)
4722
4723_spentry(restorecontext)
4724        __(hlt)
4725_endsubp(restorecontext)
4726
4727_spentry(stkconsyz)
4728        __(hlt)
4729_endsubp(stkconsyz)
4730
4731_spentry(stkvcell0)
4732        __(hlt)
4733_endsubp(stkvcell0)
4734
4735_spentry(stkvcellvsp)
4736        __(hlt)
4737_endsubp(stkvcellvsp)
4738
4739_spentry(breakpoint)
4740        __(hlt)
4741_endsubp(breakpoint)
4742
4743_spentry(unused_6)
4744        __(hlt)
4745Xspentry_end:
4746_endsubp(unused_6)
4747        .data
4748        .globl C(spentry_start)
4749        .globl C(spentry_end)
4750C(spentry_start):       .long Xspentry_start
4751C(spentry_end):         .long Xspentry_end
4752       
Note: See TracBrowser for help on using the repository browser.