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

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

Ensure DF is clear before calling foreign code.

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