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

Last change on this file since 10500 was 10500, checked in by gb, 11 years ago

Use check_cstack_alignment() in a few places. It caught a case
where cstack was not aligned when entering lisp code in _SPcallback,
so fix that (align to 16-byte boundary there.)

File size: 148.9 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        __(movl %ebp,csp_frame.save_ebp(%temp0))
1960        __(movd %mm0,csp_frame.fixed_overhead(%temp0))
1961        __(lea csp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
1962        __(ret)
1963local_label(stack_misc_alloc_heap_alloc_ivector):
1964        __(movd rcontext(tcr.foreign_sp),%stack_temp)
1965        __(subl $dnode_size,rcontext(tcr.foreign_sp))
1966        __(movl rcontext(tcr.foreign_sp),%imm0)
1967        __(movd %stack_temp,(%imm0))
1968        __(jmp _SPmisc_alloc)
1969local_label(stack_misc_alloc_node):
1970        __(movl %arg_y,%imm0)
1971        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1972        __(cmpl $tstack_alloc_limit,%imm0)
1973        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
1974        __(TSP_Alloc_Var(%imm0,%temp1))
1975        __(movd %mm0,(%temp1))
1976        __(leal fulltag_misc(%temp1),%arg_z)
1977        __(ret)
1978local_label(stack_misc_alloc_heap_alloc_gvector):
1979        __(TSP_Alloc_Fixed(0,%imm0))
1980        __(jmp _SPmisc_alloc)
1981
1982local_label(stack_misc_alloc_not_u24):
1983        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
1984_endsubp(stack_misc_alloc)
1985
1986/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of */
1987/* initial-contents.  Note that this can be used to cons any type of */
1988/* initialized node-header'ed misc object (symbols, closures, ...) */
1989/* as well as vector-like objects. */
1990_spentry(gvector)
1991        __(subl $node_size,%nargs)      /* off by one in x862-%gvector */
1992        __(movl (%esp,%nargs),%imm0)    /* boxed subtype */
1993        __(sarl $fixnumshift,%imm0)
1994        __(movl %nargs,%arg_z)
1995        __(shll $num_subtag_bits-word_shift,%arg_z)
1996        __(orl %arg_z,%imm0)
1997        __(movd %imm0,%mm0)
1998        __(dnode_align(%nargs,node_size,%imm0))
1999        __(push %ra0)   /* aka %temp0, can't be live while consing */
2000        __(Misc_Alloc(%arg_z))
2001        __(pop %ra0)
2002        __(movl %nargs,%imm0)
2003        __(jmp 2f)
20041:      __(movl %arg_y,misc_data_offset(%arg_z,%imm0))
20052:      __(subl $node_size,%imm0)
2006        __(pop %arg_y)  /* Note the intentional fencepost: */
2007                        /* discard the subtype as well. */
2008        __(jge 1b)
2009        __(jmp *%ra0)
2010_endsubp(gvector)
2011
2012_spentry(mvpass)
2013        __(int $3)
2014_endsubp(mvpass)
2015
2016_spentry(nthvalue)
2017        __(int $3)
2018_endsubp(nthvalue)
2019
2020_spentry(values)
2021        __(movl (%temp0),%arg_y)        /* return address */
2022        __(ref_global(ret1val_addr,%imm0))
2023        __(movl $nil_value,%arg_z)
2024        __(cmpl %imm0,%arg_y)
2025        __(je 0f)
2026        __(test %nargs,%nargs)
2027        __(cmovne -node_size(%esp,%nargs),%arg_z)
2028        __(movl %temp0,%esp)
2029        __(ret)
20300:      __(movl 4(%temp0),%arg_y)
2031        __(addl $2*node_size,%temp0)
2032        __(lea (%esp,%nargs),%imm0)
2033        __(movd %nargs,%mm0)
2034        __(jmp 2f)
20351:      __(subl $node_size,%imm0)
2036        __(movl (%imm0),%temp1)
2037        __(subl $node_size,%temp0)
2038        __(movl %temp1,(%temp0))
20392:      __(cmp %imm0,%esp)
2040        __(jne 1b)
2041        __(movl %temp0,%esp)
2042        __(movd %mm0,%nargs)
2043        __(jmp *%arg_y)
2044
2045_endsubp(values)
2046
2047_spentry(default_optional_args)
2048        __(int $3)
2049_endsubp(default_optional_args)
2050
2051_spentry(opt_supplied_p)
2052        __(int $3)
2053_endsubp(opt_supplied_p)
2054
2055_spentry(lexpr_entry)
2056        __(int $3)
2057_endsubp(lexpr_entry)
2058
2059_spentry(heap_rest_arg)
2060        __(push_argregs())
2061        __(movl %temp0,%arg_y)
2062        __(movl %nargs,%imm0)
2063        __(testl %imm0,%imm0)
2064        __(movl $nil_value,%arg_z)
2065        __(jmp 2f)
2066        .p2align 4
20671:      __(pop %temp1)
2068        __(Cons(%temp1,%arg_z,%arg_z))
2069        __(subl $node_size,%imm0)
20702:      __(jg 1b)
2071        __(push %arg_z)
2072        __(movl %arg_y,%temp0)
2073        __(jmp *%ra0)
2074
2075_endsubp(heap_rest_arg)
2076
2077/* %imm0 contains the number of fixed args; make an &rest arg out of */
2078/* the others. */
2079_spentry(req_heap_rest_arg)
2080        __(push_argregs())
2081        __(movd %nargs,%mm0)
2082        __(subl %imm0,%nargs)
2083        __(movl %nargs,%imm0)
2084        __(movl %temp0,%temp1)
2085        __(movl $nil_value,%arg_z)
2086        __(jmp 2f)
2087        .p2align 4
20881:      __(pop %arg_y)
2089        __(Cons(%arg_y,%arg_z,%arg_z))
2090        __(subl $node_size,%imm0)
20912:      __(jg 1b)
2092        __(push %arg_z)
2093        __(movl %temp1,%temp0)
2094        __(movd %mm0,%nargs)
2095        __(jmp *%ra0)
2096_endsubp(req_heap_rest_arg)
2097
2098/* %imm0 bytes of stuff has already been pushed   */
2099/* make an &rest arg out of any others   */
2100_spentry(heap_cons_rest_arg)
2101        __(movd %nargs,%mm0)
2102        __(subl %imm0,%nargs)
2103        __(movl %nargs,%imm0)
2104        __(movl $nil_value,%arg_z)
2105        __(movl %ra0,%arg_y)    /* temp0 can't be live while consing */
2106        __(jmp 2f)              /* (did I mention that already?) */
2107        .p2align 4
21081:      __(pop %temp1)
2109        __(Cons(%temp1,%arg_z,%arg_z))
2110        __(subl $node_size,%imm0)
21112:      __(jg 1b)
2112        __(push %arg_z)
2113        __(movd %mm0,%nargs)
2114        __(jmp *%arg_y)
2115_endsubp(heap_cons_rest_arg)
2116
2117_spentry(simple_keywords)
2118        __(xor %imm0,%imm0)
2119        __(push_argregs())
2120        __(jmp _SPkeyword_bind)
2121_endsubp(simple_keywords)
2122
2123_spentry(keyword_args)
2124        __(push_argregs())
2125        __(jmp _SPkeyword_bind)
2126_endsubp(keyword_args)
2127
2128/* There are %nargs words of arguments on the stack; %imm0 contains the */
2129/* number of non-keyword args pushed.  It's possible that we never actually */
2130/* got any keyword args, which would make things much simpler. */
2131
2132/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
2133/* indicating whether &allow-other-keys and/or &rest was present in the */
2134/* lambda list. */
2135
2136/* Once we get here, we can use the arg registers. */
2137
2138/* N.B.: %ra0 is %temp0, and must not be clobbered. */
2139
2140define([keyword_flags_aok_bit],[16])
2141define([keyword_flags_unknown_keys_bit],[17])
2142define([keyword_flags_rest_bit],[18])
2143define([keyword_flags_seen_aok_bit],[19])
2144
2145_spentry(keyword_bind)
2146        __(movl %temp1,rcontext(tcr.unboxed0))  /* save keyword flags */
2147        __(movzwl %nargs_w,%nargs)
2148        __(movl %nargs,%arg_z)
2149        __(subl %imm0,%arg_z)
2150        __(jbe local_label(no_keyword_values))
2151        __(btl $word_shift,%arg_z)
2152        __(jnc local_label(even))
2153        __(movl $nil_value,%arg_y)
2154        __(movl %arg_z,%nargs)
2155        __(test %nargs,%nargs)
2156        __(movl %ra0,rcontext(tcr.save0))       /* save temp0 while consing */
2157        __(jmp 1f)
21580:      __(pop %arg_z)
2159        __(Cons(%arg_z,%arg_y,%arg_y))
2160        __(subl $node_size,%nargs)
21611:      __(jnz 0b)
2162        __(movl rcontext(tcr.save0),%ra0)
2163        __(movapd %fpzero,rcontext(tcr.save0))
2164        __(movl %arg_y,%arg_z)
2165        __(movl $XBADKEYS,%arg_y)
2166        __(set_nargs(2))
2167        __(jmp _SPksignalerr)
2168
2169        /* Now that we're sure that we have an even number of */
2170        /* keywords and values (in %arg_z), move the pairs over */
2171        /* to the temp stack. */
2172local_label(even):
2173        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
2174        __(TSP_Alloc_Var(%arg_y,%imm0))
21752:      __(subl $node_size,%arg_y)
2176        __(pop (%arg_y))
2177        __(cmpl %arg_y,%imm0)
2178        __(jne 2b)
2179
2180        /* Get the keyword vector into %arg_y, and its length into %imm0. */
2181        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
2182        /* for each declared keyword. */
2183        __(movzwl misc_data_offset(%fn),%imm0)
2184        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2185        __(vector_length(%arg_y,%imm0))
2186        __(jmp 4f)
21873:      __(push $nil_value)
2188        __(push $nil_value)
21894:      __(subl $fixnumone,%imm0)
2190        __(jge 3b)
2191
2192        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
2193        /* in order to get a couple more registers to work with. */
2194        __(push %ra0)
2195        __(push %nargs)
2196
2197        /* At this point we have: */
2198        /* number of supplied keywords and values in %arg_z */
2199        /* keyword vector in %arg_y */
2200        __(vector_length(%arg_y,%imm0))
2201        __(push %imm0)          /* count of declared keywords */
2202        __(push %arg_z)         /* count of supplied keys and values */
2203
2204        /* For each declared keyword, iterate over the supplied k/v pairs */
2205        /* to see if it's supplied and what the value is. */
2206        /* checking to see if any */
2207        /* key-value pairs were unexpectedly supplied. */
2208
2209        __(movl rcontext(tcr.save_tsp),%temp0)
2210        __(addl $2*node_size,%temp0) /* skip frame overhead */
2211        /* %temp0: top of tstack (skipping frame overhead) */
2212        __(lea 4*node_size(%esp,%imm0,2),%temp1)
2213        /* %temp1: word above 0th value/supplied-p pair on vstack */
2214        /* %arg_y: keyword vector */
2215        __(xorl %imm0,%imm0)
2216        /* %imm0: index */
2217        /* %arg_z: temporary */
2218
2219        /* Iterate over supplied k/v pairs on tstack.  See if key is */
2220        /* in the keyword vector.  Copy value and set supplied-p on */
2221        /* vstack if found. */
2222
2223local_label(tstack_loop):
2224        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
2225        __(push %imm0)
2226        __(xorl %imm0,%imm0)
2227        __(cmpl $nrs.kallowotherkeys,%arg_z)
2228        __(jne local_label(next_keyvect_entry))
2229        __(btsl $keyword_flags_seen_aok_bit,rcontext(tcr.unboxed0))
2230        __(jc local_label(next_keyvect_entry))
2231        __(push %imm0)
2232        __(movl 4(%esp),%imm0)
2233        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
2234        __(pop %imm0)
2235        __(je local_label(next_keyvect_entry))
2236        __(btsl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2237        __(jmp local_label(next_keyvect_entry))
2238        /* loop through keyword vector */
22396:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
2240        __(jne 7f)
2241        /* Got a match; have we already seen this keyword? */
2242        __(negl %imm0)
2243        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
2244        __(jne 9f)      /* seen it, ignore this value */
2245        __(movl (%esp),%arg_z)
2246        __(lea (%temp0,%arg_z,2),%arg_z)
2247        __(movl node_size(%arg_z),%arg_z) /* value for this key */
2248        __(movl %arg_z,-node_size(%temp1,%imm0,2))
2249        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
2250        __(jmp 9f)
22517:      __(addl $node_size,%imm0)
2252local_label(next_keyvect_entry):
2253        __(cmpl %imm0,8(%esp))
2254        __(jne 6b)
2255        /* Didn't match anything in the keyword vector.  Is the keyword */
2256        /* :allow-other-keys? */
2257        __(cmpl $nrs.kallowotherkeys,%arg_z)
2258        __(je 9f)       /* :allow-other-keys is never "unknown" */
22598:      __(btsl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
22609:      __(pop %imm0)
2261        __(addl $fixnumone,%imm0)
2262        __(movl %imm0,%arg_z)
2263        __(shll $1,%arg_z)      /* pairs of tstack words */
2264        __(cmpl %arg_z,0(%esp))
2265        __(jne local_label(tstack_loop))
2266
2267        __(pop %imm0)   /* count of supplied keys and values */
2268        __(addl $node_size,%esp)
2269        __(pop %nargs)
2270        __(pop %ra0)
2271
2272        /* If the function takes an &rest arg, or if we got an unrecognized */
2273        /* keyword and don't allow that, copy the incoming k/v pairs from */
2274        /* the temp stack back to the value stack. */
2275        __(btl $keyword_flags_rest_bit,rcontext(tcr.unboxed0))
2276        __(jc 1f)
2277        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
2278        __(jnc 0f)
2279        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2280        __(jnc 1f)
2281        /* pop the tstack frame */
22820:      __(discard_temp_frame(%imm0))
2283        __(jmp *%ra0)
2284
2285        /* Copy the k/v pairs from the tstack back to the value stack, */
2286        /* either because the function takes an &rest arg or because */
2287        /* we need to signal an "unknown keywords" error. */
22881:      __(movl rcontext(tcr.save_tsp),%arg_z)
2289        __(mov (%arg_z),%arg_y)
2290        __(jmp 3f)
22912:      __(push (%arg_z))
2292        __(push node_size(%arg_z))
22933:      __(addl $dnode_size,%arg_z)
2294        __(cmpl %arg_z,%arg_y)
2295        __(jne 2b)
2296        __(discard_temp_frame(%arg_z))
2297        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
2298        __(jnc 9f)
2299        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
2300        __(jc 9f)
2301        /* Signal an "unknown keywords" error */
2302        __(movl %imm0,%nargs)
2303        __(movl $nil_value,%arg_z)
2304        __(test %nargs,%nargs)
2305        __(movl %ra0,rcontext(tcr.save0))
2306        __(jmp 5f)
23074:      __(pop %arg_y)
2308        __(Cons(%arg_y,%arg_z,%arg_z))
2309        __(subl $node_size,%nargs)
23105:      __(jnz 4b)
2311        __(movl $XBADKEYS,%arg_y)
2312        __(set_nargs(2))
2313        __(movl rcontext(tcr.save0),%ra0)
2314        __(movl $0,rcontext(tcr.save0))
2315        __(jmp _SPksignalerr)
23169:      __(jmp *%ra0)
2317
2318/* No keyword value were provided.  Access the keyword vector (which is the */
2319/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
2320/* N could be 0... */
2321
2322local_label(no_keyword_values):
2323        __(movzwl misc_data_offset(%fn),%imm0)
2324        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2325        __(vector_length(%arg_y,%arg_z))
2326        __(movl $nil_value,%imm0)
2327        __(jmp 1f)
23280:      __(push %imm0)
2329        __(push %imm0)
23301:      __(subl $fixnumone,%arg_z)
2331        __(jge 0b)
2332        __(jmp *%ra0)
2333_endsubp(keyword_bind)
2334
2335/* Normally, we'd just set %fname (aka %temp0) and do */
2336/* jump_fname().  Sometimes, though, %temp0 is being used */
2337/* as %ra0, and I'm not sure that it's going to be safe to */
2338/* clobber that.  (Note that nil-relative symbols aren't going */
2339/* get moved around by the GC, so we can get away with putting */
2340/* '%err-disp in %imm0.) */
2341_spentry(ksignalerr)
2342        __(mov $nrs.errdisp,%imm0)
2343        __(mov symbol.fcell(%imm0),%fn)
2344        __(jump_fn)
2345_endsubp(ksignalerr)
2346
2347_spentry(stack_rest_arg)
2348        __(xorl %imm0,%imm0)
2349        __(push_argregs())
2350        __(jmp _SPstack_cons_rest_arg)
2351_endsubp(stack_rest_arg)
2352
2353_spentry(req_stack_rest_arg)
2354        __(push_argregs())
2355        __(jmp _SPstack_cons_rest_arg)
2356_endsubp(req_stack_rest_arg)
2357
2358_spentry(stack_cons_rest_arg)
2359        __(movd %nargs,%mm2)
2360        __(movl %temp0,rcontext(tcr.save0))
2361        __(subl %imm0,%temp1)
2362        __(movl $nil_value,%arg_z)
2363        __(jle 2f)      /* empty list; make an empty TSP frame */
2364        __(addl %temp1,%temp1)
2365        __(cmpl $(tstack_alloc_limit-dnode_size),%temp1)
2366        __(ja 3f)       /* make empty frame, then heap-cons */
2367        __(dnode_align(%temp1,tsp_frame.fixed_overhead,%imm0))
2368        __(TSP_Alloc_Var(%imm0,%temp0))
2369        __(addl $fulltag_cons,%temp0)
23701:      __(pop %arg_y)
2371        __(_rplacd(%temp0,%arg_z))
2372        __(_rplaca(%temp0,%arg_y))
2373        __(movl %temp0,%arg_z)
2374        __(addl $cons.size,%temp0)
2375        __(subl $dnode_size,%temp1)
2376        __(jne 1b)
2377        __(push %arg_z)
2378        __(movd %mm2,%nargs)
2379        __(movl rcontext(tcr.save0),%temp0)
2380        __(movss %fpzero,rcontext(tcr.save0))
2381        __(jmp *%temp0)
2382/* Length 0, make empty frame */
23832:
2384        __(TSP_Alloc_Fixed(0,%temp0))
2385        __(push %arg_z)
2386        __(movd %mm2,%nargs)
2387        __(movl rcontext(tcr.save0),%temp0)
2388        __(movss %fpzero,rcontext(tcr.save0))
2389        __(jmp *%temp0)
2390/* Too big to stack-cons, but make an empty frame before heap-consing */
2391        __(TSP_Alloc_Fixed(0,%temp0))
2392        __(movd %mm2,%nargs)
2393        __(movl rcontext(tcr.save0),%temp0)
2394        __(movss %fpzero,rcontext(tcr.save0))
2395        __(jmp _SPheap_cons_rest_arg)
2396_endsubp(stack_cons_rest_arg)
2397
2398_spentry(getxlong)
2399        __(int $3)
2400_endsubp(getxlong)
2401
2402/* Have to be a little careful here: the caller may or may not have pushed  */
2403/* an empty frame, and we may or may not have needed one.  We can't easily  */
2404/* tell whether or not a frame will be needed (if the caller didn't reserve  */
2405/* a frame, whether or not we need one depends on the length of the list  */
2406/* in arg_z.  So, if the caller didn't push a frame, we do so; once */
2407/* everything's been spread, we discard the reserved frame (regardless of
2408/* who pushed it) if all args fit in registers.   */
2409
2410/* xxx preserve temp1 somehow? cf. comment in x862-invoke-fn */
2411_spentry(spreadargz)
2412        __(test %nargs,%nargs)
2413        __(jne 0f)
2414        __(push $reserved_frame_marker)
2415        __(push $reserved_frame_marker)
24160:      __(movl %arg_z,rcontext(tcr.save0))     /* save in case of error */
2417        __(movd %nargs,%mm0)    /* now we can use %temp1 */
2418        __(xorl %nargs,%nargs)
2419        __(cmpl $nil_value,%arg_z)
2420        __(je 2f)
24211:      __(extract_fulltag(%arg_z,%imm0))
2422        __(cmpb $fulltag_cons,%imm0_b)
2423        __(jne 9f)
2424        __(_car(%arg_z,%arg_y))
2425        __(_cdr(%arg_z,%arg_z))
2426        __(add $node_size,%nargs)
2427        __(cmpl $call_arguments_limit<<fixnumshift,%nargs)
2428        __(jge 8f)
2429        __(push %arg_y)
2430        __(cmpl $nil_value,%arg_z)
2431        __(jne 1b)
24322:      __(movd %mm0,%imm0)
2433        __(addl %imm0,%nargs)
2434        __(jne 4f)
24353:      __(addl $2*node_size,%esp)
2436        __(movl $0,rcontext(tcr.save0))
2437        __(jmp *%ra0)
24384:      __(pop %arg_z)
2439        __(cmp $1*node_size,%nargs)
2440        __(je 3b)
2441        __(pop %arg_y)
2442        __(cmp $2*node_size,%nargs)
2443        __(je 3b)
2444        __(movl $0,rcontext(tcr.save0))
2445        __(jmp *%ra0)
2446/* Discard everything that's been pushed already, complain */
24478:      __(lea (%esp,%nargs),%esp)
2448        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2449        __(movl $0,rcontext(tcr.save0))
2450        __(movl $XTMINPS,%arg_y)
2451        __(set_nargs(2))
2452        __(push %ra0)
2453        __(jmp _SPksignalerr)
24549:      __(lea (%esp,%nargs),%esp)
2455        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2456        __(movl $0,rcontext(tcr.save0))
2457        __(movl $XNOSPREAD,%arg_y)
2458        __(set_nargs(2))
2459        __(push %ra0)
2460        __(jmp _SPksignalerr)
2461_endsubp(spreadargz)
2462
2463
2464/* Caller built its own frame when it was entered.  If all outgoing args  */
2465/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2466/* relative to it and restore %rbp/%ra0   */
2467_spentry(tfuncallgen)
2468        __(cmpl $nargregs*node_size,%nargs)
2469        __(jbe 9f)
2470        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2471        __(movl %temp0,rcontext(tcr.save0))
2472        __(movd %nargs,%mm0)
2473        __(xorl %temp1,%temp1)
2474        /* We can use %ra0 as a temporary here, since the real return address */
2475        /* is on the stack   */
24760:      __(movl -node_size(%imm0),%ra0)
2477        __(movl %ra0,-node_size(%ebp,%temp1))
2478        __(subl $node_size,%imm0)
2479        __(subl $node_size,%temp1)
2480        __(cmpl %imm0,%esp)
2481        __(jne 0b)
2482        __(lea (%ebp,%temp1),%esp)
2483        __(movl 4(%ebp),%ra0)
2484        __(movl (%ebp),%ebp)
2485        __(pushl %ra0)
2486        __(movd %mm0,%nargs)
2487        __(movl rcontext(tcr.save0),%temp0)
2488        __(movss %fpzero,rcontext(tcr.save0))
2489        __(do_funcall())
2490        /* All args in regs; exactly the same as the tfuncallvsp case   */
24919:             
2492        __(leave)
2493        __(do_funcall())
2494
2495_endsubp(tfuncallgen)
2496
2497/* Some args were pushed; move them down in the frame   */
2498_spentry(tfuncallslide)
2499        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2500        __(movd %nargs,%mm0)
2501        __(xorl %temp1,%temp1)
2502        __(movl %temp0,rcontext(tcr.save0))
25030:      __(movl -node_size(%imm0),%temp0)
2504        __(movl %temp0,-node_size(%ebp,%temp1))
2505        __(subl $node_size,%imm0)
2506        __(subl $node_size,%temp1)
2507        __(cmpl %imm0,%esp)
2508        __(jne 0b)
2509        __(lea (%ebp,%temp1),%esp)
2510        __(push 4(%ebp))        /* return address */
2511        __(movl (%ebp),%ebp)
2512        __(movd %mm0,%nargs)
2513        __(movl rcontext(tcr.save0),%temp0)
2514        __(movss %fpzero,rcontext(tcr.save0))
2515        __(do_funcall())
2516_endsubp(tfuncallslide)
2517
2518/* No args were pushed; recover saved context & do funcall        */
2519_spentry(tfuncallvsp)
2520        __(leave)
2521        __(do_funcall())
2522_endsubp(tfuncallvsp)
2523
2524_spentry(tcallsymgen)
2525        __(cmpl $nargregs*node_size,%nargs)
2526        __(jbe 9f)
2527        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2528        __(movd %nargs,%mm0)
2529        __(movl %temp0,rcontext(tcr.save0))
2530        __(xorl %temp1,%temp1)  /* aka nargs */
25310:      __(movl -node_size(%imm0),%temp0)
2532        __(movl %temp0,-node_size(%ebp,%temp1))
2533        __(subl $node_size,%imm0)
2534        __(subl $node_size,%temp1)
2535        __(cmpl %imm0,%esp)
2536        __(jne 0b)
2537        __(lea (%ebp,%temp1),%esp)
2538        __(movl 4(%ebp),%temp0)
2539        __(movl (%ebp),%ebp)
2540        __(push %temp0)
2541        __(movl rcontext(tcr.save0),%temp0)
2542        __(movss %fpzero,rcontext(tcr.save0))
2543        __(movd %mm0,%nargs)
2544        __(jump_fname())
2545/* All args in regs; exactly the same as the tcallsymvsp case. */
25469:
2547        __(leave)
2548        __(jump_fname())
2549_endsubp(tcallsymgen)
2550
2551_spentry(tcallsymslide)
2552        __(movl %ebp,%imm0)
2553        __(subl %nargs,%imm0)
2554        __(addl $nargregs*node_size,%imm0)      /* new tos */
2555        __(push %imm0)
2556        __(push %arg_y)
2557        __(push %arg_z)
2558        __(push %nargs)
2559        __(lea (4-nargregs)*node_size(%esp,%nargs),%arg_y) /* src ptr */
2560        __(movl %ebp,%imm0) /* dst ptr */
2561        __(subl $fixnumone*nargregs,%nargs)
2562        __(jmp 1f)
25630:      __(subl $node_size,%arg_y)
2564        __(movl (%arg_y),%arg_z)
2565        __(subl $node_size,%imm0)
2566        __(movl %arg_z,(%imm0))
25671:      __(subl $fixnumone,%nargs)
2568        __(jge 0b)
2569        __(pop %nargs)
2570        __(pop %arg_z)
2571        __(pop %arg_y)
2572        __(pop %esp)
2573        __(push node_size(%ebp))
2574        __(movl 0(%ebp),%ebp)
2575        __(jump_fname)
2576_endsubp(tcallsymslide)
2577
2578_spentry(tcallsymvsp)
2579        __(leave)
2580        __(jump_fname())
2581_endsubp(tcallsymvsp)
2582
2583_spentry(tcallnfngen)
2584        __(cmpl $nargregs*node_size,%nargs)
2585        __(jbe 9f)
2586        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2587        __(movd %nargs,%mm0)    /* stash nargs aka temp1 */
2588        __(xorl %temp1,%temp1)
2589        __(movl %temp0,rcontext(tcr.save0))
2590        /* It's OK to use %ra0 (%temp0) as an temp here, since the */
2591        /* real return address is on the stack. */
25920:      __(movl -node_size(%imm0),%ra0)
2593        __(movl %ra0,-node_size(%ebp,%temp1))
2594        __(subl $node_size,%imm0)
2595        __(subl $node_size,%temp1)
2596        __(cmpl %imm0,%esp)
2597        __(jne 0b)
2598        __(movl rcontext(tcr.save0),%fn)
2599        __(movss %fpzero,rcontext(tcr.save0))
2600        __(lea (%ebp,%temp1),%esp)
2601        __(movl lisp_frame.savera0(%ebp),%ra0)
2602        __(movl lisp_frame.backlink(%ebp),%ebp)
2603        __(push %ra0)
2604        __(movd %mm0,%nargs)
2605        __(jmp *%fn)
26069:      /* All args in regs; exactly the same as the tcallnfnvsp case */
2607        __(movl %temp0,%fn)
2608        __(leave)
2609        __(jmp *%fn)
2610_endsubp(tcallnfngen)
2611
2612_spentry(tcallnfnslide)
2613        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2614        __(movd %nargs,%mm0)    /* save nargs aka temp1 */
2615        __(xorl %temp1,%temp1)
2616        __(movl %temp0,rcontext(tcr.save0))
2617        /* We can use %ra0 as a temporary here, since the real return address */
2618        /* is on the stack   */
26190:      __(movl -node_size(%imm0),%ra0)
2620        __(movl %ra0,-node_size(%ebp,%temp1))
2621        __(subl $node_size,%imm0)
2622        __(subl $node_size,%temp1)
2623        __(cmpl %imm0,%esp)
2624        __(jne 0b)
2625        __(movl rcontext(tcr.save0),%fn)
2626        __(lea (%ebp,%temp1),%esp)
2627        __(movl lisp_frame.savera0(%ebp),%ra0)
2628        __(movl lisp_frame.backlink(%ebp),%ebp)
2629        __(push %ra0)
2630        __(movapd %fpzero,rcontext(tcr.save0))
2631        __(movd %mm0,%nargs)
2632        __(jmp *%fn)
2633_endsubp(tcallnfnslide)
2634
2635_spentry(tcallnfnvsp)
2636        __(mov %temp0,%fn)
2637        __(leave)
2638        __(jmp *%fn)
2639_endsubp(tcallnfnvsp)
2640
2641/* Make a "raw" area on the foreign stack, stack-cons a macptr to point */
2642/* to it, and return the macptr.  Size (in bytes, boxed) is in arg_z */
2643/* on entry; macptr in arg_z on exit. */
2644_spentry(makestackblock)
2645        __(check_cstack_alignment())
2646        __(unbox_fixnum(%arg_z,%imm0))
2647        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2648        __(cmpl $tstack_alloc_limit,%imm0)
2649        __(jae 1f)
2650        __(movd rcontext(tcr.foreign_sp),%mm0)
2651        __(subl %imm0,rcontext(tcr.foreign_sp))
2652        __(movl rcontext(tcr.foreign_sp),%arg_z)
2653        __(movd %mm0,(%arg_z))
2654        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2655        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2656        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2657        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2658        __(movl %imm0,macptr.address(%arg_z))
2659        __(movss %fpzero,macptr.domain(%arg_z))
2660        __(movss %fpzero,macptr.type(%arg_z))
2661        __(ret)
26621:      __(movd rcontext(tcr.foreign_sp),%mm0)
2663        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2664        __(movl rcontext(tcr.foreign_sp),%imm0)
2665        __(movd %mm0,(%imm0))
2666        __(movl %ebp,csp_frame.save_ebp(%imm0))
2667        __(set_nargs(1))
2668        __(movl $nrs.new_gcable_ptr,%fname)
2669        __(jump_fname())
2670_endsubp(makestackblock)
2671
2672_spentry(makestackblock0)
2673        __(unbox_fixnum(%arg_z,%imm0))
2674        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2675        __(cmpl $tstack_alloc_limit,%imm0)
2676        __(jae 9f)
2677        __(movl rcontext(tcr.foreign_sp),%temp0)
2678        __(subl %imm0,rcontext(tcr.foreign_sp))
2679        __(movl rcontext(tcr.foreign_sp),%arg_z)
2680        __(movl %temp0,(%arg_z))
2681        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2682        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2683        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2684        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2685        __(movl %imm0,macptr.address(%arg_z))
2686        __(movss %fpzero,macptr.domain(%arg_z))
2687        __(movss %fpzero,macptr.type(%arg_z))
2688        __(jmp 2f)
26891:      __(movsd %fpzero,(%imm0))
2690        __(addl $dnode_size,%imm0)
26912:      __(cmpl %imm0,%temp0)
2692        __(jne 1b)
2693        __(repret)
26949:      __(movd rcontext(tcr.foreign_sp),%mm0)
2695        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2696        __(movl rcontext(tcr.foreign_sp),%imm0)
2697        __(movd %mm0,(%imm0))
2698        __(movl %ebp,csp_frame.save_ebp(%imm0))
2699        __(set_nargs(1))
2700        __(movl $nrs.new_gcable_ptr,%fname)
2701        __(jump_fname())
2702_endsubp(makestackblock0)
2703
2704_spentry(makestacklist)
2705        __(test %arg_y,%arg_y)
2706        __(js 9f)
2707        __(movl %arg_y,%imm0)
2708        __(testb $fixnummask,%imm0_b)
2709        __(jne 9f)
2710        __(addl %imm0,%imm0)
2711        __(rcmpl(%imm0,$tstack_alloc_limit))
2712        __(movl $nil_value,%temp1) 
2713        __(jae 2f)
2714        __(addl $tsp_frame.fixed_overhead,%imm0)
2715        __(TSP_Alloc_Var(%imm0,%temp0))
2716        __(addl $fulltag_cons,%temp0)
2717        __(jmp 1f)
27180:      __(_rplaca(%temp0,%arg_z))
2719        __(_rplacd(%temp0,%temp1))
2720        __(movl %temp0,%temp1)
2721        __(addl $cons.size,%temp0)
27221:      __(subl $fixnumone,%arg_y)
2723        __(jge 0b)
2724        __(movl %temp1,%arg_z)
2725        __(ret)
27262:      __(TSP_Alloc_Fixed(0,%imm0))
2727        __(jmp 4f)
27283:      __(Cons(%arg_z,%temp1,%temp1))
27294:      __(subl $fixnumone,%arg_y)                             
2730        __(jge 3b)
2731        __(movl %temp1,%arg_z)
2732        __(ret)
27339:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
2734_endsubp(makestacklist)
2735
2736/* subtype (boxed) vpushed before initial values. (Had better be a */
2737/* node header subtag.)  Nargs set to count of things vpushed. */
2738_spentry(stkgvector)
2739        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2740        __(shrl $fixnumshift,%imm0)
2741        __(leal -fixnumone(%nargs),%arg_z)
2742        __(movl %arg_z,%arg_y)
2743        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2744        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2745        __(movd %imm0,%mm0)
2746        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2747        __(TSP_Alloc_Var(%imm0,%arg_z))
2748        __(movd %mm0,(%arg_z))
2749        __(addl $fulltag_misc,%arg_z)
2750        __(lea -node_size(%nargs),%imm0)
2751        __(jmp 2f)
27521:      __(pop misc_data_offset(%arg_z,%imm0))
27532:      __(subl $node_size,%imm0)
2754        __(jge 1b)
2755        __(addl $node_size,%esp)
2756        __(jmp *%ra0)
2757_endsubp(stkgvector)
2758
2759/* Allocate a fulltag-misc object. */
2760/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
2761_spentry(misc_alloc)
2762        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2763        __(jne local_label(misc_alloc_not_u24))
2764        __(unbox_fixnum(%arg_z,%imm0))
2765        __(mov %arg_y,%temp0)
2766        __(shl $num_subtag_bits-fixnumshift,%temp0)
2767        __(or %temp0,%imm0)     /* %imm0 now = header */
2768        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2769        __(andb $fulltagmask,%imm0_b)
2770        __(cmpb $fulltag_nodeheader,%imm0_b)
2771        __(je local_label(misc_alloc_32))
2772        __(movd %mm0,%imm0)
2773        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2774        __(jbe local_label(misc_alloc_32))
2775        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2776        __(jbe local_label(misc_alloc_8))
2777        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2778        __(jbe local_label(misc_alloc_16))
2779        __(cmpb $subtag_double_float_vector,%imm0_b)
2780        __(jne local_label(misc_alloc_1))
2781        /* double-float vector case */
2782        __(imul $2,%arg_y,%imm0)
2783        __(jmp local_label(misc_alloc_alloc_vector))
2784local_label(misc_alloc_1):
2785        __(unbox_fixnum(%arg_y,%imm0))
2786        __(addl $7,%imm0)
2787        __(shrl $3,%imm0)
2788        __(jmp local_label(misc_alloc_alloc_vector))
2789local_label(misc_alloc_8):
2790        __(unbox_fixnum(%arg_y,%imm0))
2791        __(jmp local_label(misc_alloc_alloc_vector))
2792local_label(misc_alloc_16):
2793        __(unbox_fixnum(%arg_y,%imm0))
2794        __(shl $1,%imm0)
2795        __(jmp local_label(misc_alloc_alloc_vector))
2796local_label(misc_alloc_32):
2797        __(movl %arg_y,%imm0)
2798local_label(misc_alloc_alloc_vector):
2799        __(dnode_align(%imm0,node_size,%imm0))
2800        __(Misc_Alloc(%arg_z))
2801        __(ret)
2802local_label(misc_alloc_not_u24):
2803        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2804_endsubp(misc_alloc)
2805
2806/* N.B. arg count word in %imm0, not %nargs */
2807/* no %whole_reg;  it's in rcontext(tcr.save0) */
2808/* %arg_reg is %temp1, key vector in %arg_y */
2809_startfn(C(destbind1))
2810        __(movl %ra0,rcontext(tcr.save1))
2811        /* Save entry %esp in case of error   */
2812        __(movd %esp,%mm0)
2813        /* Save arg count word */
2814        __(movd %imm0,%mm1)
2815        /* Extract required arg count.   */
2816        __(testb %imm0_b,%imm0_b)
2817        __(je local_label(opt))         /* skip if no required args   */
2818        __(movzbl %imm0_b,%imm0)
2819local_label(req_loop): 
2820        __(compare_reg_to_nil(%arg_reg))
2821        __(je local_label(toofew))
2822        __(movb $fulltagmask,%imm0_bh)
2823        __(andb %arg_reg_b,%imm0_bh)
2824        __(cmpb $fulltag_cons,%imm0_bh)
2825        __(jne local_label(badlist))
2826        __(subb $1,%imm0_b)
2827        __(pushl cons.car(%arg_reg))
2828        __(_cdr(%arg_reg,%arg_reg))
2829        __(jne local_label(req_loop))
2830        __(movd %mm1,%imm0)
2831local_label(opt):
2832        __(testb %imm0_bh,%imm0_bh)
2833        __(je local_label(rest_keys))
2834        __(btl $initopt_bit,%imm0)
2835        __(jc local_label(opt_supp))
2836        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2837local_label(simple_opt_loop):
2838        __(compare_reg_to_nil(%arg_reg))
2839        __(je local_label(default_simple_opt))
2840        __(movb $fulltagmask,%imm0_bh)
2841        __(andb %arg_reg_b,%imm0_bh)
2842        __(cmpb $fulltag_cons,%imm0_bh)
2843        __(jne local_label(badlist))
2844        __(subb $1,%imm0_b)
2845        __(pushl cons.car(%arg_reg))
2846        __(_cdr(%arg_reg,%arg_reg))
2847        __(jne local_label(simple_opt_loop))
2848        __(jmp local_label(rest_keys))
2849local_label(default_simple_opt):
2850        __(subb $1,%imm0_b)
2851        __(pushl $nil_value)
2852        __(jne local_label(default_simple_opt))
2853        __(jmp local_label(rest_keys))
2854local_label(opt_supp):
2855        __(movb $fulltagmask,%imm0_bh)
2856        __(andb %arg_reg_b,%imm0_bh)
2857        __(compare_reg_to_nil(%arg_z))
2858        __(je local_label(default_hard_opt))
2859        __(cmpb $fulltag_cons,%imm0_bh)
2860        __(jne local_label(badlist))
2861        __(subb $1,%imm0_b)
2862        __(pushl cons.car(%arg_reg))
2863        __(_cdr(%arg_reg,%arg_reg))
2864        __(push $t_value)
2865        __(jne local_label(opt_supp))
2866        __(jmp local_label(rest_keys))
2867local_label(default_hard_opt):
2868        __(subb $1,%imm0_b)
2869        __(push $nil_value)
2870        __(push $nil_value)
2871        __(jne local_label(default_hard_opt))
2872local_label(rest_keys):
2873        __(btl $restp_bit,%imm0)
2874        __(jc local_label(have_rest))
2875        __(btl $keyp_bit,%imm0)
2876        __(jc local_label(have_keys))
2877        __(compare_reg_to_nil(%arg_reg))
2878        __(jne local_label(toomany))
2879        __(movss %fpzero,rcontext(tcr.save0))
2880        __(jmp *%ra0)
2881local_label(have_rest):
2882        __(pushl %arg_reg)
2883        __(btl $keyp_bit,%imm0)
2884        __(jc local_label(have_keys))
2885        __(movss %fpzero,rcontext(tcr.save0))
2886        __(jmp *%ra0)
2887        /* Ensure that arg_reg contains a proper,even-length list.  */
2888        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2889local_label(have_keys):
2890        __(movb $255,%imm0_b)
2891        __(push %arg_reg)
2892        __(push %arg_z)
2893        __(xorl %arg_z,%arg_z)
2894local_label(count_keys_loop):
2895        __(compare_reg_to_nil(%arg_reg))
2896        __(je local_label(counted_keys))
2897        __(subb $1,%imm0_b)
2898        __(jb local_label(toomany))
2899        __(movb $fulltagmask,%arg_z_bh)
2900        __(andb %arg_reg_b,%arg_z_bh)
2901        __(cmpb $fulltag_cons,%arg_z_bh)
2902        __(jne local_label(badlist))
2903        __(_cdr(%arg_reg,%arg_reg))
2904        __(movb $fulltagmask,%arg_z_bh)
2905        __(andb %arg_reg_b,%arg_z_bh)
2906        __(cmpb $fulltag_cons,%arg_z_bh)
2907        __(jne local_label(badlist))
2908        __(_cdr(%arg_reg,%arg_reg))
2909        __(jmp local_label(count_keys_loop))
2910local_label(counted_keys):             
2911        /* We've got a proper, even-length list of key/value pairs in  */
2912        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2913        /* of NILs on the vstack.   */
2914        __(pop %arg_z)
2915        __(pop %arg_reg)
2916        __(movd %mm1,%imm0)
2917        __(shrl $16,%imm0)
2918        __(movzbl %imm0_b,%imm0)
2919        __(movl %esp,rcontext(tcr.unboxed0))    /* 0th value/supplied-p pair */
2920        __(jmp local_label(push_pair_test))
2921local_label(push_pair_loop):
2922        __(push $nil_value)
2923        __(push $nil_value)
2924local_label(push_pair_test):   
2925        __(subb $1,%imm0_b)
2926        __(jge local_label(push_pair_loop))
2927        __(push %temp0) /* keyword */
2928        __(push %arg_z) /* value */
2929        __(vector_length(%arg_y,%imm0))
2930        __(push %arg_reg)
2931        __(push %imm0)  /* keyword vector length */
2932        __(movd %mm1,%imm0)
2933        __(movl $0,rcontext(tcr.unboxed1)) /* count of unknown keywords seen */
2934local_label(match_keys_loop):
2935        __(movl 4(%esp),%arg_reg)
2936        __(compare_reg_to_nil(%arg_reg))
2937        __(je local_label(matched_keys))
2938        __(_car(%arg_reg,%temp0))
2939        __(_cdr(%arg_reg,%arg_reg))
2940        __(_car(%arg_reg,%arg_z))
2941        __(_cdr(%arg_reg,%arg_reg))
2942        __(movl %arg_reg,4(%esp))
2943        __(xorl %temp1,%temp1)
2944        __(jmp local_label(match_test))
2945local_label(match_loop):
2946        __(cmpl misc_data_offset(%arg_y,%temp1),%arg_z)
2947        __(je local_label(matched))
2948        __(addl $node_size,%temp1)
2949local_label(match_test):
2950        __(cmpl %temp1,(%esp))  /* compare index, keyword vector length */
2951        __(jne local_label(match_loop))
2952        /* No match.  Note unknown keyword, check for :allow-other-keys   */
2953        __(addl $1,rcontext(tcr.unboxed1))
2954        __(cmpl $nrs.kallowotherkeys,%temp0)
2955        __(jne local_label(match_keys_loop))
2956        __(subl $1,rcontext(tcr.unboxed1))
2957        __(btsl $seen_aok_bit,%imm0)
2958        __(jc local_label(match_keys_loop))
2959        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
2960        __(compare_reg_to_nil(%arg_z))
2961        __(je local_label(match_keys_loop))
2962        __(btsl $aok_bit,%imm0)
2963        __(jmp local_label(match_keys_loop))
2964        /* Got a match.  Worry about :allow-other-keys here, too.   */
2965local_label(matched):
2966        __(negl %temp1)
2967        __(shll $1,%temp1)
2968        __(addl rcontext(tcr.unboxed0),%temp1)
2969        __(cmpl $nil_value,-node_size*2(%temp1))
2970        __(jne local_label(match_keys_loop))
2971        __(movl %arg_z,-node_size(%temp1))
2972        __(movl $t_value,-node_size*2(%temp1))
2973        __(cmpl $nrs.kallowotherkeys,%temp0)
2974        __(jne local_label(match_keys_loop))
2975        __(btsl $seen_aok_bit,%imm0)
2976        __(jnc local_label(match_keys_loop))
2977        __(compare_reg_to_nil(%arg_z))
2978        __(je local_label(match_keys_loop))
2979        __(btsl $aok_bit,%imm0)
2980        __(jmp local_label(match_keys_loop))
2981local_label(matched_keys):     
2982        __(cmpl $0,rcontext(tcr.unboxed1))      /* any unknown keys seen? */
2983        __(je local_label(keys_ok))
2984        __(btl $aok_bit,%imm0)
2985        __(jnc local_label(badkeys))
2986local_label(keys_ok):
2987        __(addl $(3*node_size),%esp)
2988        __(pop %ra0)
2989        __(movss %fpzero,rcontext(tcr.save0))
2990        __(jmp *%ra0)
2991        /* Some unrecognized keywords.  Complain generically about   */
2992        /* invalid keywords.   */
2993local_label(badkeys):
2994        __(movl $XBADKEYS,%arg_y)
2995        __(jmp local_label(destructure_error))
2996local_label(toomany):
2997        __(movl $XCALLTOOMANY,%arg_y)
2998        __(jmp local_label(destructure_error))
2999local_label(toofew):
3000        __(movl $XCALLTOOFEW,%arg_y)
3001        __(jmp local_label(destructure_error))
3002local_label(badlist):
3003        __(movl $XCALLNOMATCH,%arg_y)
3004local_label(destructure_error):
3005        __(movd %mm0,%esp)              /* undo everything done to the stack */
3006        __(movl rcontext(tcr.save0),%arg_z)     /* %whole_reg */
3007        __(movss %fpzero,rcontext(tcr.save0))
3008        __(set_nargs(2))
3009        __(push %ra0)
3010        __(jmp _SPksignalerr)
3011_endfn(C(destbind1))
3012
3013_spentry(macro_bind)
3014        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3015        __(extract_fulltag(%arg_reg,%imm0))
3016        __(cmpb $fulltag_cons,%imm0_b)
3017        __(jne 1f)
3018        __(_cdr(%arg_reg,%arg_reg))
3019        __(jmp C(destbind1))
30201:      __(movl $XCALLNOMATCH,%arg_y)
3021        __(movl rcontext(tcr.save0),%arg_z)
3022        __(movss %fpzero,rcontext(tcr.save0))
3023        __(set_nargs(2))
3024        __(push %ra0)       
3025        __(jmp _SPksignalerr)
3026
3027_endsubp(macro_bind)
3028
3029_spentry(destructuring_bind)
3030        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3031        __(jmp C(destbind1))
3032_endsubp(destructuring_bind)
3033
3034_spentry(destructuring_bind_inner)
3035        __(movl %arg_z,rcontext(tcr.save0))     /* %whole_reg */
3036        __(jmp C(destbind1))
3037_endsubp(destructuring_bind_inner)
3038
3039_spentry(vpopargregs)
3040        __(int $3)
3041_endsubp(vpopargregs)
3042
3043/* If arg_z is an integer, return in imm0 something whose sign  */
3044/* is the same as arg_z's.  If not an integer, error.   */
3045_spentry(integer_sign)
3046        __(mov %arg_z,%imm0)
3047        __(testb $tagmask,%arg_z_b)
3048        __(je 8f)
3049        __(extract_typecode(%arg_z,%imm0))
3050        __(cmpb $subtag_bignum,%imm0_b)
3051        __(jne 9f)
3052        __(getvheader(%arg_z,%imm0))
3053        __(shr $num_subtag_bits,%imm0)
3054        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
30558:      __(repret)
30569:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3057_endsubp(integer_sign)
3058
3059/* "slide" nargs worth of values up the stack.  imm0 contains */
3060/* the difference between the current stack pointer and the target. */
3061_spentry(mvslide)
3062        __(movd %nargs,%mm0)
3063        __(lea (%esp,%nargs),%arg_y)
3064        __(lea (%arg_y,%imm0),%imm0)
3065        __(test %nargs,%nargs)
3066        __(je 2f)
30671:
3068        __(subl $node_size,%arg_y)
3069        __(movl (%arg_y),%arg_z)
3070        __(subl $node_size,%imm0)
3071        __(movl %arg_z,(%imm0))
3072        __(subl $node_size,%nargs)
3073        __(jne 1b)
30742:      __(movl %imm0,%esp)
3075        __(movd %mm0,%nargs)
3076        __(jmp *%ra0)
3077_endsubp(mvslide)
3078
3079_spentry(save_values)
3080        __(movd rcontext(tcr.save_tsp),%mm1)
3081/* common exit: nargs = values in this set, mm1 = ptr to tsp before call to save_values   */
3082local_label(save_values_to_tsp):
3083        __(movl %ra0,rcontext(tcr.save0))
3084        __(movl rcontext(tcr.save_tsp),%temp0)
3085        __(dnode_align(%nargs,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3086        __(TSP_Alloc_Var(%imm0,%arg_z))
3087        __(movl rcontext(tcr.save_tsp),%imm0)
3088        __(movd %mm1,(%imm0))
3089        __(movl %nargs,(%arg_z))
3090        __(movl %temp0,node_size(%arg_z))
3091        __(leal 2*node_size(%arg_z,%nargs),%arg_y)
3092        __(leal (%esp,%nargs),%imm0)
3093        __(cmpl %imm0,%esp)
3094        __(jmp 2f)
30951:      __(subl $node_size,%imm0)
3096        __(movl (%imm0),%arg_z)
3097        __(subl $node_size,%arg_y)
3098        __(cmpl %imm0,%esp)
3099        __(movl %arg_z,(%arg_y))
31002:      __(jne 1b)
3101        __(addl %nargs,%esp)
3102        __(movl rcontext(tcr.save0),%ra0)
3103        __(movl $0,rcontext(tcr.save0))
3104        __(jmp *%ra0)
3105_endsubp(save_values)
3106
3107/* Add the multiple values that are on top of the vstack to the set  */
3108/* saved in the top tsp frame, popping them off of the vstack in the  */
3109/* process.  It is an error (a bad one) if the TSP contains something  */
3110/* other than a previously saved set of multiple-values.  */
3111/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3112/* each add_values call adds another linked element to the list of  */
3113/* values. This makes recover_values harder.   */
3114_spentry(add_values)
3115        /* do we need to preserve imm0? */
3116        __(test %nargs,%nargs)
3117        __(movl rcontext(tcr.save_tsp),%imm0)
3118        __(movl (%imm0),%imm0)
3119        __(movd %imm0,%mm1)     /* for the benefit of save_values_to_tsp */
3120        __(jne local_label(save_values_to_tsp))
3121        __(jmp *%ra0)
3122_endsubp(add_values)
3123
3124/* push the values in the value set atop the sp, incrementing nargs.  */
3125/* Discard the tsp frame; leave values atop the sp.   */
3126_spentry(recover_values)
3127        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3128        __(movd %nargs,%mm0)              /* temp1 */
3129        /* First, walk the segments reversing the pointer to previous  */
3130        /* segment pointers Can tell the end because that previous  */
3131        /* segment pointer is the prev tsp pointer   */
3132        __(movl rcontext(tcr.save_tsp),%temp1)
3133        __(movl %temp1,%temp0)  /* current segment   */
3134        __(movl %temp1,%arg_y)  /* last segment   */
3135        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3136local_label(walkloop):
3137        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3138        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3139        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3140        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3141        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3142        __(jne local_label(walkloop))
3143
3144        __(movl %temp1,%arg_z)
3145        __(movd %mm0,%nargs)
3146        /* the final segment pointer is now in %arg_y  */
3147        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3148local_label(pushloop):
3149        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3150        __(test %imm0,%imm0)
3151        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3152        __(leal (%nargs,%imm0),%nargs)
3153        __(jmp 2f)
31541:      __(push -node_size(%temp0))
3155        __(subl $node_size,%temp0)
3156        __(subl $fixnum_one,%imm0)
31572:      __(jne 1b)
3158        __(cmpl %arg_y,%arg_z)
3159        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3160        __(jne local_label(pushloop))
3161        __(movl (%arg_z),%arg_z)
3162        __(movl %arg_z,rcontext(tcr.save_tsp))
3163        __(movl %arg_z,rcontext(tcr.next_tsp))
3164        __(movl rcontext(tcr.save0),%ra0)
3165        __(movl $0,rcontext(tcr.save0))
3166        __(jmp *%ra0)           
3167_endsubp(recover_values)
3168
3169/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3170/* frame if any values (which will be used as outgoing arguments) will  */
3171/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3172/* that no other arguments have been pushed) on entry.   */
3173
3174_spentry(recover_values_for_mvcall)
3175        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3176        /* First, walk the segments reversing the pointer to previous  */
3177        /* segment pointers Can tell the end because that previous  */
3178        /* segment pointer is the prev tsp pointer   */
3179        __(xorl %nargs,%nargs)
3180        __(push %nargs)
3181        __(movl rcontext(tcr.save_tsp),%temp1)
3182        __(movl %temp1,%temp0)  /* current segment   */
3183        __(movl %temp1,%arg_y)  /* last segment   */
3184        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3185local_label(walkloop_mvcall):
3186        __(movl tsp_frame.data_offset(%temp0),%imm0)
3187        __(addl %imm0,(%esp))
3188        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3189        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3190        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3191        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3192        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3193        __(jne local_label(walkloop_mvcall))
3194
3195        __(movl %temp1,%arg_z)
3196        __(pop %nargs)
3197
3198        __(cmpl $nargregs*node_size,%nargs)
3199        __(jbe local_label(pushloop_mvcall))
3200        __(push $reserved_frame_marker)
3201        __(push $reserved_frame_marker)
3202
3203        /* the final segment pointer is now in %arg_y  */
3204        /* walk backwards, pushing values on the stack and incrementing %nargs*/
3205local_label(pushloop_mvcall):
3206        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment */
3207        __(test %imm0,%imm0)
3208        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3209        __(jmp 2f)
32101:      __(push -node_size(%temp0))
3211        __(subl $node_size,%temp0)
3212        __(subl $fixnum_one,%imm0)
32132:      __(jne 1b)
3214        __(cmpl %arg_y,%arg_z)
3215        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3216        __(jne local_label(pushloop_mvcall))
3217        __(movl (%arg_z),%arg_z)
3218        __(movl %arg_z,rcontext(tcr.save_tsp))
3219        __(movl %arg_z,rcontext(tcr.next_tsp))
3220        __(movl rcontext(tcr.save0),%ra0)
3221        __(movl $0,rcontext(tcr.save0))
3222        __(jmp *%ra0)           
3223_endsubp(recover_values_for_mvcall)
3224
3225_spentry(reset)
3226        __(int $3)
3227_endsubp(reset)
3228
3229/* temp0 = element-count, arg_y = subtag, arg_z = initval */
3230_spentry(misc_alloc_init)
3231        __(push %ebp)
3232        __(movl %esp,%ebp)
3233        __(push %arg_z)
3234        __(movl %arg_y,%arg_z)
3235        __(movl %temp0,%arg_y)
3236        __(push $local_label(misc_alloc_init_back))
3237        __(jmp _SPmisc_alloc)
3238__(tra(local_label(misc_alloc_init_back)))
3239        __(pop %arg_y)
3240        __(leave)
3241        __(movl $nrs.init_misc,%fname)
3242        __(set_nargs(2))
3243        __(jump_fname())
3244_endsubp(misc_alloc_init)
3245
3246_spentry(stack_misc_alloc_init)
3247        __(int $3)
3248_endsubp(stack_misc_alloc_init)
3249
3250        .globl C(popj)
3251_spentry(popj)
3252C(popj):
3253        __(leave)
3254        __(ret)
3255_endsubp(popj)
3256
3257/* arg_z should be of type (signed-byte 64) */
3258/* return unboxed value in mm0 */
3259_spentry(gets64)
3260        __(testb $fixnummask,%arg_z_b)
3261        __(jne 1f)
3262        __(unbox_fixnum(%arg_z,%imm0))
3263        __(movd %imm0,%mm0)
3264        __(jns 8f)
3265        /* get sign into upper half of %mm0 */
3266        __(pcmpeqd %mm1,%mm1)   /* all ones */
3267        __(psllq $32,%mm1)
3268        __(por %mm1,%mm0)
3269        __(ret)
32701:      __(movb %arg_z_b,%imm0_b)
3271        __(andb $tagmask,%imm0_b)
3272        __(cmpb $tag_misc,%imm0_b)
3273        __(jne 9f)
3274        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3275        __(cmpb $subtag_bignum,%imm0_b)
3276        __(jne 9f)
3277        __(movl misc_header_offset(%arg_z),%imm0)
3278        __(cmpl $two_digit_bignum_header,%imm0)
3279        __(jne 9f)
3280        __(movq misc_data_offset(%arg_z),%mm0)
32818:      __(repret)
32829:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3283_endsubp(gets64)
3284
3285/* arg_z should be of type (unsigned-byte 64) */
3286/* return unboxed value in mm0 */
3287_spentry(getu64)
3288        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3289        __(testl %arg_z,%imm0)
3290        __(movl %arg_z,%imm0)
3291        __(jne 1f)
3292        __(sarl $fixnumshift,%imm0)
3293        __(movd %imm0,%mm0)
3294        __(ret)
32951:      __(andb $tagmask,%imm0_b)
3296        __(cmpb $tag_misc,%imm0_b)
3297        __(jne 9f)
3298        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3299        __(cmpb $subtag_bignum,%imm0_b)
3300        __(jne 9f)
3301        __(movl misc_header_offset(%arg_z),%imm0)
3302        __(cmpl $three_digit_bignum_header,%imm0)
3303        __(je 3f)
3304        __(cmpl $two_digit_bignum_header,%imm0)
3305        __(jne 9f)
3306        __(movl misc_data_offset+4(%arg_z),%imm0)
3307        __(testl %imm0,%imm0)
3308        __(js 9f)
3309        __(movq misc_data_offset(%arg_z),%mm0)
3310        __(ret)
33113:      __(movl misc_data_offset(%arg_z),%imm0)
3312        __(cmpl $0,misc_data_offset+8(%arg_z))
3313        __(jne 9f)
3314        __(movq misc_data_offset(%arg_z),%mm0)
3315        __(repret)
33169:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3317_endsubp(getu64)
3318
3319/* Make unsigned integer from value in mm0 */
3320_spentry(makeu64)
3321        __(movq %mm0,%mm1)
3322        __(psrlq $32,%mm0)
3323        __(movd %mm0,%imm0)
3324        __(test %imm0,%imm0)
3325        __(js 3f)
3326        __(jnz 2f)
3327        __(movd %mm1,%imm0)
3328        __(cmpl $target_most_positive_fixnum,%imm0)
3329        __(ja 1f)
3330        __(box_fixnum(%imm0,%arg_z))
3331        __(ret)
33321:      /* maybe make a 1 digit bignum */
3333        __(test %imm0,%imm0)
3334        __(js 2f)
3335        __(movl $one_digit_bignum_header,%imm0)
3336        __(movd %imm0,%mm0)
3337        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3338        __(movd %mm1,misc_data_offset(%arg_z))
3339        __(ret)
3340        /* make a 2 digit bignum */
33412:      __(movl $two_digit_bignum_header,%imm0)
3342        __(movd %imm0,%mm0)
3343        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3344        __(movq %mm1,misc_data_offset(%arg_z))
3345        __(ret)
3346        /* make a 3 digit bignum */
33473:      __(movl $three_digit_bignum_header,%imm0)
3348        __(movd %imm0,%mm0)
3349        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
3350        __(movq %mm1,misc_data_offset(%arg_z))
3351        __(ret)
3352_endsubp(makeu64)
3353
3354/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
3355/* unbound_marker), arg_y = symbol */
3356_spentry(specref)
3357        __(movl symbol.binding_index(%arg_z),%imm0)
3358        __(cmp rcontext(tcr.tlb_limit),%imm0)
3359        __(movl rcontext(tcr.tlb_pointer),%temp1)
3360        __(movl %arg_z,%arg_y)
3361        __(jae 7f)
3362        __(movl (%temp1,%imm0),%arg_z)
3363        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3364        __(jne 8f)
33657:      __(movl symbol.vcell(%arg_y),%arg_z)
33668:      __(repret)             
3367_endsubp(specref)
3368
3369/* arg_y = special symbol, arg_z = new value. */
3370_spentry(specset)
3371        __(movl symbol.binding_index(%arg_y),%imm0)
3372        __(cmp rcontext(tcr.tlb_limit),%imm0)
3373        __(movl rcontext(tcr.tlb_pointer),%temp1)
3374        __(jae 1f)
3375        __(movl (%temp1,%imm0),%temp0)
3376        __(cmpb $no_thread_local_binding_marker,%temp0_b)
3377        __(je 1f)
3378        __(movl %arg_z,(%temp1,%imm0))
3379        __(ret)
33801:      __(movl %arg_y,%temp0)
3381        __(movl $1<<fixnumshift,%arg_y)
3382        __(jmp _SPgvset)
3383_endsubp(specset)
3384
3385_spentry(specrefcheck)
3386        __(mov %arg_z,%arg_y)
3387        __(movl symbol.binding_index(%arg_z),%imm0)
3388        __(cmp rcontext(tcr.tlb_limit),%imm0)
3389        __(jae 7f)
3390        __(movl rcontext(tcr.tlb_pointer),%temp1)
3391        __(movl (%temp1,%imm0),%arg_z)
3392        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3393        __(jne 8f)
33947:      __(movl symbol.vcell(%arg_y),%arg_z)
33958:      __(cmpb $unbound_marker,%arg_z_b)
3396        __(jne 9f)
3397        __(uuo_error_reg_unbound(Rarg_y))
33989:      __(repret)
3399_endsubp(specrefcheck)
3400
3401_spentry(restoreintlevel)
3402        __(int $3)
3403_endsubp(restoreintlevel)
3404
3405/* Make a lisp integer from the unsigned value in imm0 */
3406_spentry(makeu32)
3407        __(cmpl $target_most_positive_fixnum,%imm0)
3408        __(ja 0f)       /* need to make a bignum */
3409        __(box_fixnum(%imm0,%arg_z))
3410        __(ret)
34110:      __(movd %imm0,%mm1)
3412        __(test %imm0,%imm0)
3413        __(js 1f)
3414        __(movl $one_digit_bignum_header,%imm0)
3415        __(movd %imm0,%mm0)
3416        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3417        __(movd %mm1,misc_data_offset(%arg_z))
3418        __(ret)
34191:      __(movl $two_digit_bignum_header,%imm0)
3420        __(movd %imm0,%mm0)
3421        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3422        __(movd %mm1,misc_data_offset(%arg_z))
3423        __(ret)
3424_endsubp(makeu32)
3425
3426/* arg_z is of type (signed-byte 32) */
3427/* return unboxed value in %imm0 */
3428_spentry(gets32)
3429        __(testb $fixnummask,%arg_z_b)
3430        __(jne 1f)
3431        __(unbox_fixnum(%arg_z,%imm0))
3432        __(ret)
34331:      __(movb %arg_z_b,%imm0_b)
3434        __(andb $tagmask,%imm0_b)
3435        __(cmpb $tag_misc,%imm0_b)
3436        __(jne 9f)
3437        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3438        __(cmpb $subtag_bignum,%imm0_b)
3439        __(jne 9f)
3440        __(movl misc_header_offset(%arg_z),%imm0)
3441        __(cmpl $one_digit_bignum_header,%imm0)
3442        __(jne 9f)
3443        __(movl misc_data_offset(%arg_z),%imm0)
3444        __(ret)
34459:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_signed_byte_32))
3446_endsubp(gets32)
3447
3448/* arg_z is of type (unsigned-byte 32) */
3449/* return unboxed value in %imm0 */
3450_spentry(getu32)
3451        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3452        __(testl %arg_z,%imm0)
3453        __(movl %arg_z,%imm0)
3454        __(jne 1f)
3455        __(sarl $fixnumshift,%imm0)
3456        __(ret)
34571:      __(andb $tagmask,%imm0_b)
3458        __(cmpb $tag_misc,%imm0_b)
3459        __(jne 9f)
3460        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3461        __(cmpb $subtag_bignum,%imm0_b)
3462        __(jne 9f)
3463        __(movl misc_header_offset(%arg_z),%imm0)
3464        __(cmpl $two_digit_bignum_header,%imm0)
3465        __(je 2f)
3466        __(cmpl $one_digit_bignum_header,%imm0)
3467        __(jne 9f)
3468        __(movl misc_data_offset(%arg_z),%imm0)
3469        __(ret)
34702:      __(movl misc_data_offset(%arg_z),%imm0)
3471        __(cmpl $0,misc_data_offset+4(%arg_z))
3472        __(jne 9f)
3473        __(ret)
34749:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_unsigned_byte_32))
3475_endsubp(getu32)
3476
3477_spentry(mvpasssym)
3478        __(int $3)
3479_endsubp(mvpasssym)
3480
3481/* don't smash arg_z */
3482_spentry(unbind)
3483        __(push %arg_z)
3484        __(movl rcontext(tcr.db_link),%imm0)
3485        __(movl rcontext(tcr.tlb_pointer),%arg_z)
3486        __(movl binding.sym(%imm0),%temp0)
3487        __(movl binding.val(%imm0),%arg_y)
3488        __(movl binding.link(%imm0),%imm0)
3489        __(movl %arg_y,(%arg_z,%temp0))
3490        __(movl %imm0,rcontext(tcr.db_link))
3491        __(pop %arg_z)
3492        __(ret)
3493_endsubp(unbind)
3494
3495_spentry(unbind_n)
3496        __(push %temp1)         /* preserve temp1/nargs */
3497        __(push %arg_z)
3498        __(xorl %arg_z,%arg_z)
3499        __(movl rcontext(tcr.db_link),%temp1)
3500        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35011:             
3502        __(movl binding.sym(%temp1),%temp0)
3503        __(movl binding.val(%temp1),%arg_y)
3504        __(movl binding.link(%temp1),%temp1)
3505        __(movl %arg_y,(%arg_z,%temp0))
3506        __(decl %imm0)
3507        __(jne 1b)
3508        __(movl %temp1,rcontext(tcr.db_link))
3509        __(pop %arg_z)
3510        __(pop %temp1)
3511        __(ret) 
3512_endsubp(unbind_n)
3513
3514_spentry(unbind_to)
3515        __(push %arg_y)
3516        __(push %arg_z)
3517        __(push %temp0)
3518        __(push %temp1)
3519       
3520        __(movl rcontext(tcr.db_link),%temp0)
3521        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35221:
3523        __(movl binding.sym(%temp0),%temp1)
3524        __(movl binding.val(%temp0),%arg_y)
3525        __(movl binding.link(%temp0),%temp0)
3526        __(movl %arg_y,(%arg_z,%temp1))
3527        __(cmpl %temp0,%imm0)
3528        __(jne 1b)
3529        __(movl %temp0,rcontext(tcr.db_link))
3530
3531        __(pop %temp1)
3532        __(pop %temp0)
3533        __(pop %arg_z)
3534        __(pop %arg_y)
3535        __(ret)
3536_endsubp(unbind_to)
3537
3538_spentry(bind_interrupt_level_0)
3539        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3540        __(cmpl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3541        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3542        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3543        __(push rcontext(tcr.db_link))
3544        __(movl %esp,rcontext(tcr.db_link))
3545        __(movl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3546        __(js 1f)
35470:      __(jmp *%ra0)
3548        /* Interrupt level was negative; interrupt may be pending */
35491:      __(check_pending_enabled_interrupt(2f))
35502:      __(jmp *%ra0)
3551_endsubp(bind_interrupt_level_0)
3552
3553/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3554/* of disabling interrupts.)   */
3555_spentry(bind_interrupt_level_m1)
3556        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3557        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3558        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3559        __(push rcontext(tcr.db_link))
3560        __(movl %esp,rcontext(tcr.db_link))
3561        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3562        __(jmp *%ra0)
3563_endsubp(bind_interrupt_level_m1)
3564
3565/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
3566/* do what _SPbind_interrupt_level_0 does. */
3567_spentry(bind_interrupt_level)
3568        __(test %arg_z,%arg_z)
3569        __(jz _SPbind_interrupt_level_0)
3570        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3571        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3572        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3573        __(push rcontext(tcr.db_link))
3574        __(movl %esp,rcontext(tcr.db_link))
3575        __(movl %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3576        __(jmp *%ra0)
3577_endsubp(bind_interrupt_level)
3578
3579/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
3580/* non-negative, check for pending interrupts. */
3581_spentry(unbind_interrupt_level)
3582        __(btl $TCR_FLAG_BIT_PENDING_SUSPEND,rcontext(tcr.flags))
3583        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3584        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
3585        __(jc 5f)
35860:      __(test %imm0,%imm0)
3587        __(movl rcontext(tcr.db_link),%imm0)
3588        __(movl binding.val(%imm0),%temp0)
3589        __(movl binding.link(%imm0),%imm0)
3590        __(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3591        __(movl %imm0,rcontext(tcr.db_link))
3592        __(js 3f)
35932:      __(repret)
35943:      __(test %temp0,%temp0)
3595        __(js 2b)
3596        __(check_pending_enabled_interrupt(4f))
35974:      __(repret)
35985:       /* Missed a suspend request; force suspend now if we're restoring
3599          interrupt level to -1 or greater */
3600        __(cmpl $-2<<fixnumshift,%imm0)
3601        __(jne 0b)
3602        __(movl rcontext(tcr.db_link),%temp0)
3603        __(movl binding.val(%temp0),%temp0)
3604        __(cmpl %imm0,%temp0)
3605        __(je 0b)
3606        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3607        __(suspend_now())
3608        __(jmp 0b)
3609_endsubp(unbind_interrupt_level)
3610
3611_spentry(progvrestore)
3612        __(movl rcontext(tcr.save_tsp),%imm0)
3613        __(movl tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3614        __(movl tsp_frame.data_offset(%imm0),%imm0)
3615        __(shrl $fixnumshift,%imm0)
3616        __(jne _SPunbind_n)
3617        __(repret)
3618_endsubp(progvrestore)
3619
3620/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3621/* inline.  Call out otherwise.   */
3622_spentry(builtin_plus)
3623        __(movl %arg_y,%imm0)
3624        __(orl %arg_z,%imm0)
3625        __(testb $fixnummask,%imm0_b)
3626        __(jne 1f)
3627        __(addl %arg_y,%arg_z)
3628        __(jo C(fix_one_bit_overflow))
3629        __(repret)
36301:      __(jump_builtin(_builtin_plus,2))
3631_endsubp(builtin_plus)
3632
3633/* %arg_z <- %arg_y - %arg_z.  Do the fixnum case - including overflow -  */
3634/*  inline.  Call out otherwise.   */
3635_spentry(builtin_minus)
3636        __(movl %arg_y,%imm0)
3637        __(orl %arg_z,%imm0)
3638        __(testb $fixnummask,%imm0_b)
3639        __(jne 1f)
3640        __(xchgl %arg_y,%arg_z)
3641        __(subl %arg_y,%arg_z)
3642        __(jo C(fix_one_bit_overflow))
3643        __(repret)
36441:      __(jump_builtin(_builtin_minus,2))
3645_endsubp(builtin_minus)
3646
3647/* %arg_z -< arg_y * arg_z. */
3648/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
3649_spentry(builtin_times)
3650        __(movl %arg_y,%imm0)
3651        __(orb %arg_z_b,%imm0_b)
3652        __(testb $fixnummask,%imm0_b)
3653        __(jne 2f)
3654        __(unbox_fixnum(%arg_z,%imm0))
3655        /* 32-bit fixnum result in %imm0.  Overflow set if it doesn't fit. */
3656        __(imul %arg_y,%imm0)
3657        __(jo 1f)
3658        __(movl %imm0,%arg_z)
3659        __(ret)
36601:      __(unbox_fixnum(%arg_z,%eax))
3661        __(mark_as_imm(%edx))
3662        __(unbox_fixnum(%arg_y,%edx))
3663        __(imul %edx)
3664        __(movd %eax,%mm0)
3665        __(movd %edx,%mm1)
3666        __(mark_as_node(%edx))
3667        __(psllq $32,%mm1)
3668        __(por %mm1,%mm0)
3669        __(jmp _SPmakes64)
36702:      __(jump_builtin(_builtin_times,2))
3671_endsubp(builtin_times)
3672
3673_spentry(builtin_div)
3674        __(jump_builtin(_builtin_div,2))
3675
3676/* %arg_z <- (= %arg_y %arg_z).   */
3677_spentry(builtin_eq)
3678        __(movl %arg_y,%imm0)
3679        __(orb %arg_z_b,%imm0_b)
3680        __(testb $fixnummask,%imm0_b)
3681        __(jne 1f)
3682        __(rcmpl(%arg_z,%arg_y))
3683        __(condition_to_boolean(e,%imm0,%arg_z))
3684        __(ret)
36851:      __(jump_builtin(_builtin_eq,2))
3686_endsubp(builtin_eq)
3687
3688/* %arg_z <- (/= %arg_y %arg_z).          */
3689_spentry(builtin_ne)
3690        __(movl %arg_y,%imm0)
3691        __(orb %arg_z_b,%imm0_b)
3692        __(testb $fixnummask,%imm0_b)
3693        __(jne 1f)
3694        __(rcmpl(%arg_z,%arg_y))
3695        __(condition_to_boolean(ne,%imm0,%arg_z))
3696        __(ret)
36971:      __(jump_builtin(_builtin_ne,2))
3698_endsubp(builtin_ne)
3699
3700/* %arg_z <- (> %arg_y %arg_z).   */
3701_spentry(builtin_gt)
3702        __(movl %arg_y,%imm0)
3703        __(orb %arg_z_b,%imm0_b)
3704        __(testb $fixnummask,%imm0_b)
3705        __(jne 1f)
3706        __(rcmpl(%arg_y,%arg_z))
3707        __(condition_to_boolean(g,%imm0,%arg_z))
3708        __(ret)
37091:      __(jump_builtin(_builtin_gt,2))
3710_endsubp(builtin_gt)
3711
3712/* %arg_z <- (>= %arg_y %arg_z).          */
3713_spentry(builtin_ge)
3714        __(movl %arg_y,%imm0)
3715        __(orb %arg_z_b,%imm0_b)
3716        __(testb $fixnummask,%imm0_b)
3717        __(jne 1f)
3718        __(rcmpl(%arg_y,%arg_z))
3719        __(condition_to_boolean(ge,%imm0,%arg_z))
3720        __(ret)
37211:      __(jump_builtin(_builtin_ge,2))
3722_endsubp(builtin_ge)
3723
3724/* %arg_z <- (< %arg_y %arg_z).   */
3725_spentry(builtin_lt)
3726        __(movl %arg_y,%imm0)
3727        __(orb %arg_z_b,%imm0_b)
3728        __(testb $fixnummask,%imm0_b)
3729        __(jne 1f)
3730        __(rcmpl(%arg_y,%arg_z))
3731        __(condition_to_boolean(l,%imm0,%arg_z))
3732        __(ret)
37331:      __(jump_builtin(_builtin_lt,2))
3734_endsubp(builtin_lt)
3735
3736/* %arg_z <- (<= %arg_y %arg_z).   */
3737_spentry(builtin_le)
3738        __(movl %arg_y,%imm0)
3739        __(orb %arg_z_b,%imm0_b)
3740        __(testb $fixnummask,%imm0_b)
3741        __(jne 1f)
3742        __(rcmpl(%arg_y,%arg_z))
3743        __(condition_to_boolean(le,%imm0,%arg_z))
3744        __(ret)
37451:      __(jump_builtin(_builtin_le,2))
3746_endsubp(builtin_le)
3747
3748_spentry(builtin_eql)
3749        __(cmpl %arg_y,%arg_z)
3750        __(je 1f)
3751        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3752        /* and both have the same subtag. */
3753        __(movl %arg_y,%imm0)
3754        __(andb $tagmask,%imm0_b)
3755        __(cmpb $tag_misc,%imm0_b)
3756        __(jne 2f)
3757        __(movb %arg_z_b,%imm0_bh)
3758        __(andb $tagmask,%imm0_bh)
3759        __(cmpb %imm0_bh,%imm0_b)
3760        __(jne 2f)
3761        __(extract_subtag(%arg_y,%imm0_b))
3762        __(extract_subtag(%arg_z,%imm0_bh))
3763        __(cmpb %imm0_b,%imm0_bh)
3764        __(jne 2f)
3765        __(jump_builtin(_builtin_eql,2))
37661:      __(movl $t_value,%arg_z)
3767        __(ret)
37682:      __(movl $nil_value,%arg_z)
3769        __(ret)
3770_endsubp(builtin_eql)
3771
3772_spentry(builtin_length)
3773        __(extract_fulltag(%arg_z,%imm0))
3774        __(cmpl $tag_list,%imm0)
3775        __(jz 2f)
3776        __(andl $tagmask,%imm0)
3777        __(cmpl $tag_misc,%imm0)
3778        __(jnz 8f)
3779        __(extract_subtag(%arg_z,%imm0_b))
3780        __(rcmpb(%imm0_b,$min_vector_subtag))
3781        __(jb 8f)
3782        __(je 1f)
3783        /* (simple-array * (*)) */
3784        __(movl %arg_z,%arg_y)
3785        __(vector_length(%arg_y,%arg_z))
3786        __(ret)
37871:      /* vector header */
3788        __(movl vectorH.logsize(%arg_z),%arg_z)
3789        __(ret)
37902:      /* list.  Maybe null, maybe dotted or circular. */
3791        __(movl $-fixnumone,%arg_y)
3792        __(movl %arg_z,%temp0)  /* fast pointer */
3793        __(movl %arg_z,%temp1)  /* slow pointer */
37943:      __(movb %temp0_b,%al)
3795        __(andb $fulltagmask,%al)
3796        __(addl $fixnumone,%arg_y)
3797        __(compare_reg_to_nil(%temp0))
3798        __(je 9f)
3799        __(cmpb $fulltag_cons,%al)
3800        __(jne 8f)
3801        __(movb %temp1_b,%ah)
3802        __(andb $fulltagmask,%ah)
3803        __(_cdr(%temp0,%temp0))
3804        __(testl $fixnumone,%arg_y)
3805        __(je 3b)
3806        __(cmpb $fulltag_cons,%ah)
3807        __(jne 8f)
3808        __(_cdr(%temp1,%temp1))
3809        __(cmpl %temp0,%temp1)
3810        __(jne 3b)
38118:
3812        __(jump_builtin(_builtin_length,1))
38139:
3814        __(movl %arg_y,%arg_z)
3815        __(ret)
3816_endsubp(builtin_length)
3817
3818_spentry(builtin_seqtype)
3819        __(extract_fulltag(%arg_z,%imm0))
3820        __(cmpb $fulltag_cons,%imm0_b)
3821        __(jz 1f)
3822        __(cmpb $tag_misc,%imm0_b)
3823        __(jne 2f)
3824        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3825        __(rcmpb(%imm0_b,$min_vector_subtag))
3826        __(jb 2f)
3827        __(movl $nil_value,%arg_z)
3828        __(ret)
38291:      __(movl $t_value,%arg_z)
3830        __(ret)
38312:
3832        __(jump_builtin(_builtin_seqtype,1))
3833_endsubp(builtin_seqtype)
3834
3835_spentry(builtin_assq)
3836        __(cmpl $nil_value,%arg_z)
3837        __(je 5f)
38381:      __(movl %arg_z,%imm0)
3839        __(andb $fulltagmask,%imm0_b)
3840        __(cmpb $fulltag_cons,%imm0_b)
3841        __(je 2f)
3842        __(uuo_error_reg_not_list(Rarg_z))
38432:      __(_car(%arg_z,%temp0))
3844        __(_cdr(%arg_z,%arg_z))
3845        __(cmpl $nil_value,%temp0)
3846        __(je 4f)
3847        __(movl %temp0,%imm0)
3848        __(andb $fulltagmask,%imm0_b)
3849        __(cmpb $fulltag_cons,%imm0_b)
3850        __(je 3f)
3851        __(uuo_error_reg_not_list(Rtemp0))
38523:      __(_car(%temp0,%temp1))
3853        __(cmpl %temp1,%arg_y)
3854        __(jne 4f)
3855        __(movl %temp0,%arg_z)
3856        __(ret)
38574:      __(cmpl $nil_value,%arg_z)
38585:      __(jnz 1b)
3859        __(repret)
3860_endsubp(builtin_assq)
3861
3862_spentry(builtin_memq)
3863        __(cmpl $nil_value,%arg_z)
3864        __(jmp 3f)
38651:      __(movb $fulltagmask,%imm0_b)
3866        __(andb %arg_z_b,%imm0_b)
3867        __(cmpb $fulltag_cons,%imm0_b)
3868        __(jz 2f)
3869        __(uuo_error_reg_not_list(Rarg_z))
38702:      __(_car(%arg_z,%temp1))
3871        __(_cdr(%arg_z,%temp0))
3872        __(cmpl %temp1,%arg_y)
3873        __(jz 4f)
3874        __(cmpl $nil_value,%temp0)
3875        __(movl %temp0,%arg_z)
38763:      __(jnz 1b)
38774:      __(repret)
3878_endsubp(builtin_memq)
3879
3880logbitp_max_bit = 30
3881
3882_spentry(builtin_logbitp)
3883        /* Call out unless: both args fixnums, arg_y in [0, logbitp_max_bit) */
3884        __(movl %arg_z,%imm0)
3885        __(orl %arg_y,%imm0)
3886        __(testb $fixnummask,%imm0_b)
3887        __(jnz 1f)
3888        __(unbox_fixnum(%arg_y,%imm0))
3889        __(js 1f)       /* bit number negative */
3890        __(addb $fixnumshift,%imm0_b)
3891        __(cmpl $logbitp_max_bit<<fixnumshift,%arg_y)
3892        __(jb 2f)
3893        __(movl $logbitp_max_bit-1+fixnumshift,%imm0)
38942:      __(bt %imm0,%arg_z)
3895        __(condition_to_boolean(b,%imm0,%arg_z))
3896        __(ret)
38971:      __(jump_builtin(_builtin_logbitp,2))
3898_endsubp(builtin_logbitp)
3899
3900_spentry(builtin_logior)
3901        __(movl %arg_y,%imm0)
3902        __(orb %arg_z_b,%imm0_b)
3903        __(testb $fixnummask,%imm0_b)
3904        __(jne 1f)
3905        __(orl %arg_y,%arg_z)
3906        __(ret)
39071:
3908        __(jump_builtin(_builtin_logior,2))
3909_endsubp(builtin_logior)
3910
3911_spentry(builtin_logand)
3912        __(movl %arg_y,%imm0)
3913        __(orb %arg_z_b,%imm0_b)
3914        __(testb $fixnummask,%imm0_b)
3915        __(jne 1f)
3916        __(andl %arg_y,%arg_z)
3917        __(ret)
39181:
3919        __(jump_builtin(_builtin_logand,2))
3920_endsubp(builtin_logand)
3921
3922_spentry(builtin_negate)
3923        __(testb $fixnummask,%arg_z_b)
3924        __(jne 1f)
3925        __(negl %arg_z)
3926        __(jo C(fix_one_bit_overflow))
3927        __(repret)
39281:
3929        __(jump_builtin(_builtin_negate,1))
3930_endsubp(builtin_negate)
3931
3932_spentry(builtin_logxor)
3933        __(movl %arg_y,%imm0)
3934        __(orb %arg_z_b,%imm0_b)
3935        __(testb $fixnummask,%imm0_b)
3936        __(jne 1f)
3937        __(xorl %arg_y,%arg_z)
3938        __(ret)
39391:
3940        __(jump_builtin(_builtin_logxor,2))
3941_endsubp(builtin_logxor)
3942
3943/* temp0 = vector, arg_y = index, arg_z = newval */
3944_spentry(aset1)
3945        __(extract_typecode(%temp0,%imm0))
3946        __(box_fixnum(%imm0,%temp1))
3947        __(cmpb $min_vector_subtag,%imm0_b)
3948        __(ja _SPsubtag_misc_set)
3949        /* push frame... */
3950        __(pop %temp1)
3951        __(push $reserved_frame_marker)
3952        __(push $reserved_frame_marker)
3953        __(push %temp0)
3954        __(push %temp1)
3955        /* and fall through... */
3956_endsubp(aset1)
3957
3958_spentry(builtin_aset1)
3959        __(jump_builtin(_builtin_aset1,3))
3960_endsubp(builtin_aset1)
3961
3962_spentry(builtin_ash)
3963        __(movl %arg_y,%imm0)
3964        __(orb %arg_z_b,%imm0_b)
3965        __(testb $fixnummask,%imm0_b)
3966        __(jne 9f)
3967        __(unbox_fixnum(%arg_z,%imm0))
3968        /* Z flag set if zero ASH shift count */
3969        __(jnz 1f)
3970        __(movl %arg_y,%arg_z) /* shift by 0 */
3971        __(ret)
39721:      __(jns 3f)
3973        __(rcmpl(%imm0,$-31))
3974        __(jg 2f)
3975        __(unbox_fixnum(%arg_y,%imm0))
3976        __(sar $31,%imm0)
3977        __(box_fixnum(%imm0,%arg_z))
3978        __(ret)
39792:      /* Right-shift by small fixnum */
3980        __(negb %imm0_b)
3981        __(movzbl %imm0_b,%ecx)
3982        __(unbox_fixnum(%arg_y,%imm0))
3983        __(sar %cl,%imm0)
3984        __(box_fixnum(%imm0,%arg_z))
3985        __(ret)
39863:      /* Left shift by fixnum.  We can't shift by more than 31 bits, */
3987        /* though shifting by 32 is actually easy. */
3988        __(rcmpl(%imm0,$32))
3989        __(jg 9f)
3990        __(jne 4f)
3991        /* left-shift by 32 bits exactly */
3992        __(unbox_fixnum(%arg_y,%imm0))
3993        __(movd %imm0,%mm0)
3994        __(psllq $32,%mm0)
3995        __(jmp _SPmakes64)
39964:      /* left-shift by 1..31 bits. Safe to move shift count to %cl */
3997        __(movd %imm0,%mm1)     /* shift count */
3998        __(unbox_fixnum(%arg_y,%imm0))
3999        __(movd %imm0,%mm0)
4000        __(sarl $31,%imm0)      /* propagate sign */
4001        __(movd %imm0,%mm2)
4002        __(pshufw $0x4e,%mm2,%mm2) /* swap hi/lo halves */
4003        __(por %mm2,%mm0)
4004        __(psllq %mm1,%mm0)
4005        __(jmp _SPmakes64)
40069:
4007        __(jump_builtin(_builtin_ash,2))
4008_endsubp(builtin_ash)
4009
4010_spentry(builtin_aref1)
4011        __(extract_typecode(%arg_y,%imm0))
4012        __(box_fixnum_no_flags(%imm0,%temp0))
4013        __(cmpb $min_vector_subtag,%imm0_b)
4014        __(ja _SPsubtag_misc_ref)
4015        __(jump_builtin(_builtin_aref1,2))
4016_endsubp(builtin_aref1)
4017
4018/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
4019/* if so.  This might allow us to avoid having to have a priori */
4020/* knowledge of whether a foreign function returns a floating-point result. */
4021/* backlink to saved %esp, below */
4022/* arg n-1 */
4023/* arg n-2 */
4024/* ... */
4025/* arg 0 */
4026/* space for alignment */
4027/* previous %esp */
4028
4029_spentry(ffcall)
4030LocalLabelPrefix[]ffcall:
4031        __(unbox_fixnum(%arg_z,%imm0))
4032        __(testb $fixnummask,%arg_z_b)
4033        __(je 0f)
4034        __(movl macptr.address(%arg_z),%imm0)
40350:
4036        /* Save lisp registers. */
4037        __(push %ebp)
4038        __(mov %esp,%ebp)
4039        __(push %temp0)
4040        __(push %temp1)
4041        __(push %arg_y)
4042        __(push %arg_z)
4043        __(push %fn)
4044        __(movl %esp,rcontext(tcr.save_vsp))
4045        __(movl %ebp,rcontext(tcr.save_ebp))
4046        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4047        __(movl rcontext(tcr.foreign_sp),%esp)
4048        /* preserve state of direction flag */
4049        __(pushfl)
4050        __(popl rcontext(tcr.save_eflags))
4051        __(cld)
4052        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4053        __(emms)
4054        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4055        __(movl (%esp),%ebp)
4056LocalLabelPrefix[]ffcall_setup:
4057        __(addl $node_size,%esp)
4058LocalLabelPrefix[]ffcall_call:
4059        __(call *%eax)
4060LocalLabelPrefix[]ffcall_call_end:
4061        __(movl %ebp,%esp)
4062        __(movl %esp,rcontext(tcr.foreign_sp))
4063        __(clr %arg_z)
4064        __(clr %arg_y)
4065        __(clr %temp1)
4066        __(clr %temp0)
4067        __(clr %fn)
4068        __(pxor %fpzero,%fpzero)
4069        __ifdef([DARWIN])
4070        /* Darwin's math library seems to cause spurious FP exceptions. */
4071        __(movl %arg_z,rcontext(tcr.ffi_exception))
4072        __else
4073        __(stmxcsr rcontext(tcr.ffi_exception))
4074        __endif
4075        __(pushl rcontext(tcr.save_eflags))
4076        __(popfl)
4077        __(movl rcontext(tcr.save_vsp),%esp)
4078        __(movl rcontext(tcr.save_ebp),%ebp)
4079        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4080        __(pop %fn)
4081        __(pop %arg_z)
4082        __(pop %arg_y)
4083        __(pop %temp1)
4084        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4085        __(check_pending_interrupt(%temp0))
4086        __(pop %temp0)
4087        __(leave)
4088        __(ret)
4089        /* need to deal with NSExceptions and Objc-2.0 execptions */
4090_endsubp(ffcall)
4091
4092_spentry(ffcall_return_registers)
4093        __(int $3)
4094_endsubp(ffcall_return_registers)
4095
4096/* We need to reserve a frame here if (a) nothing else was already pushed
4097/* and (b) we push something (e.g., more than 2 args in the lexpr) */
4098_spentry(spread_lexprz)
4099        new_local_labels()
4100        __(movl (%arg_z),%imm0) /* lexpr count */
4101        __(leal node_size(%arg_z,%imm0),%arg_y)
4102        __(movd %arg_y,%mm1)
4103        __(test %nargs,%nargs) /* anything pushed by caller ? */
4104        __(jne 0f)              /* yes, caller has already created frame. */
4105        __(cmpl $(nargregs*node_size),%imm0) /* will we push anything ? */
4106        __(jbe 0f)
4107        __(push $reserved_frame_marker)
4108        __(push $reserved_frame_marker)
41090:      __(addl %imm0,%nargs)
4110        __(cmpl $(1*node_size),%imm0)
4111        __(ja 2f)
4112        __(je 1f)
4113        /* lexpr count was 0; vpop the args that */
4114        /* were pushed by the caller */
4115        __(test %nargs,%nargs)
4116        __(je local_label(all_args_popped))
4117        __(pop %arg_z)
4118local_label(maybe_pop_y):
4119        __(cmpl $(1*node_size),%nargs)
4120        __(je local_label(all_args_popped))
4121        __(pop %arg_y)
4122local_label(all_args_popped):   
4123        /* If all args fit in registers but some were pushed */
4124        /* by the caller, discard the reserved frame that the caller */
4125        /* pushed.         */
4126        __(cmpl %imm0,%nargs)
4127        __(je local_label(go))
4128        __(cmpl $(nargregs*node_size),%nargs)
4129        __(ja local_label(go))
4130        __(addl $(2*node_size),%esp)
4131local_label(go):
4132        __(jmp *%ra0)
4133
4134        /* lexpr count is two or more: vpush args from the lexpr until */
4135        /* we have only two left, then assign them to arg_y and arg_z */
41362:      __(cmpl $(2*node_size),%imm0)
4137        __(je local_label(push_loop_end))
4138local_label(push_loop):
4139        __(lea -1*node_size(%imm0),%imm0)
4140        __(push -node_size(%arg_y))
4141        __(lea -1*node_size(%arg_y),%arg_y)
4142        __(cmpl $(2*node_size),%imm0)
4143        __(jne 2b)
4144local_label(push_loop_end):
4145        __(movl -node_size*2(%arg_y),%arg_z)
4146        __(movl -node_size*1(%arg_y),%arg_y)
4147        __(jmp *%ra0)
4148        /* lexpr count is one: set arg_z from the lexpr, */
4149        /* maybe vpop arg_y  */
41501:      __(movl -node_size*1(%arg_y),%arg_z)
4151        __(jmp local_label(maybe_pop_y))
4152_endsubp(spread_lexprz)
4153
4154_spentry(callback)
4155        __(push %ebp)
4156        __(movl %esp,%ebp)
4157        /* C scalar args are already on the stack. */
4158        /* arg word 0 at 8(%ebp), word 1 at 12(%ebp), etc. */
4159
4160        /* C NVRs */
4161        __(push %edi)
4162        __(push %esi)
4163        __(push %ebx)
4164        __(push %ebp)
4165       
4166        __(box_fixnum(%eax,%esi))       /* put callback index in arg_y */
4167        __(ref_global(get_tcr,%eax))
4168        __(push $1)
4169        __(call *%eax)
4170        __(addl $node_size,%esp)
4171        /* linear TCR addr now in %eax */
4172        __(movw tcr.ldt_selector(%eax), %rcontext_reg)
4173
4174        /* ebp is 16-byte aligned, and we've pushed 4 words.  Make
4175          sure that when we push old foreign_sp, %esp will be 16-byte
4176          aligned again */
4177        __(subl $12,%esp)       
4178        __(push rcontext(tcr.foreign_sp))
4179        __(movl %esp,rcontext(tcr.foreign_sp))
4180        __(clr %arg_z)
4181        /* arg_y contains callback index */
4182        __(clr %temp1)
4183        __(clr %temp0)
4184        __(clr %fn)
4185        __(pxor %fpzero,%fpzero)
4186        __(movl rcontext(tcr.save_vsp),%esp)
4187        __(movl %ebp,%arg_z)
4188        __(movl rcontext(tcr.save_ebp),%ebp)
4189        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4190        __(stmxcsr rcontext(tcr.foreign_mxcsr))
4191        __(andb $~mxcsr_all_exceptions,rcontext(tcr.foreign_mxcsr))
4192        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4193        __(movl $nrs.callbacks,%fname)
4194        __(push $local_label(back_from_callback))
4195        __(set_nargs(2))
4196        __(check_cstack_alignment())
4197        __(jump_fname())
4198__(tra(local_label(back_from_callback)))
4199        __(movl %esp,rcontext(tcr.save_vsp))
4200        __(movl %ebp,rcontext(tcr.save_ebp))
4201        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4202        __(movl rcontext(tcr.foreign_sp),%esp)
4203        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4204        __(emms)
4205        __(pop rcontext(tcr.foreign_sp))
4206        __(addl $12,%esp)       /* discard alignment padding */
4207        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4208        __(pop %ebp)
4209        __(pop %ebx)
4210        __(pop %esi)
4211        __(pop %edi)
4212        __(movl 8(%ebp),%eax)
4213        /* doubleword result? */
4214        /* fp result? */
4215        __(leave)
4216        __(ret)
4217_endsubp(callback)
4218
4219/* temp0 = array, arg_y = i, arg_z = j. Typecheck everything.
4220   We don't know whether the array is alleged to be simple or
4221   not, and don't know anythng about the element type.  */
4222
4223_spentry(aref2)
4224        __(testl $fixnummask,%arg_y)
4225        __(je 0f)
4226        __(uuo_error_reg_not_fixnum(Rarg_y))
42270:      __(testb $fixnummask,%arg_z_b)
4228        __(je 1f)
4229        __(uuo_error_reg_not_fixnum(Rarg_z))
42301:      __(extract_typecode(%temp0,%imm0))
4231        __(cmpb $subtag_arrayH,%imm0_b)
4232        __(jne 2f)
4233        __(cmpl $2<<fixnumshift,arrayH.rank(%temp0))
4234        __(je 3f)
42352:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
42363:      __(cmpl arrayH.dim0(%temp0),%arg_y)
4237        __(jb 4f)
4238        __(uuo_error_array_bounds(Rarg_y,Rtemp0))
42394:      __(movl arrayH.dim0+node_size(%temp0),%imm0)
4240        __(cmpl %imm0,%arg_z)
4241        __(jb 5f)
4242        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
42435:      __(sarl $fixnumshift,%imm0)
4244        __(imull %arg_y,%imm0)
4245        __(addl %imm0,%arg_z)
4246        __(movl %temp0,%arg_y)
4247        __(xorl %temp1,%temp1)
42486:      __(addl arrayH.displacement(%arg_y),%arg_z)
4249        __(movl arrayH.data_vector(%arg_y),%arg_y)
4250        __(extract_subtag(%arg_y,%imm0_b))
4251        __(cmpb $subtag_vectorH,%imm0_b)
4252        __(ja C(misc_ref_common))
4253        __(jmp 6b)
4254_endsubp(aref2)
4255
4256_spentry(aref3)
4257        __(int $3)
4258_endsubp(aref3)
4259
4260/* As with aref2, but temp1 = array, temp0 = i, arg_y = j, arg_z = new_value */
4261_spentry(aset2)
4262        __(testb $fixnummask,%temp0_b)
4263        __(je 0f)
4264        __(uuo_error_reg_not_fixnum(Rtemp0))
42650:      __(testl $fixnummask,%arg_y)
4266        __(je 1f)
4267        __(uuo_error_reg_not_fixnum(Rarg_y))
42681:      __(extract_typecode(%temp1,%imm0))
4269        __(cmpb $subtag_arrayH,%imm0_b)
4270        __(jne 2f)
4271        __(cmpl $2<<fixnumshift,arrayH.rank(%temp1))
4272        __(je 3f)
42732:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_2d))
42743:      __(cmpl arrayH.dim0(%temp1),%temp0)
4275        __(jb 4f)
4276        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
42774:      __(movl arrayH.dim0+node_size(%temp1),%imm0)
4278        __(cmpl %imm0,%arg_y)
4279        __(jb 5f)
4280        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
42815:      __(sarl $fixnumshift,%imm0)
4282        __(imull %temp0,%imm0)
4283        __(addl %imm0,%arg_y)
4284        __(movl %temp1,%temp0)
4285        __(xorl %temp1,%temp1)
42866:      __(addl arrayH.displacement(%temp0),%arg_y)
4287        __(movl arrayH.data_vector(%temp0),%temp0)
4288        __(extract_subtag(%temp0,%imm0_b))
4289        __(cmpb $subtag_vectorH,%imm0_b)
4290        __(ja C(misc_set_common))
4291        __(jmp 6b)
4292_endsubp(aset2)
4293
4294_spentry(aset3)
4295        __(int $3)
4296_endsubp(aset3)
4297
4298/* Prepend all but the first seven (6 words of code & other immediate data,
4299/* plus inner fn) and last (lfbits) elements of %fn to the "arglist". */
4300_spentry(call_closure)
4301        new_local_labels()
4302        __(vector_length(%fn,%imm0))
4303        __(subl $8<<fixnumshift,%imm0)  /* imm0 = inherited arg count */
4304        __(lea (%nargs,%imm0),%temp0)
4305        __(cmpl $nargregs<<fixnumshift,%temp0)
4306        __(jna local_label(regs_only))  /* either: 1 arg, 1 inherited, or */
4307                                        /* no args, 2 inherited */
4308        __(pop rcontext(tcr.save0))             /* save return address */
4309        __(cmpl $nargregs<<fixnumshift,%nargs)
4310        __(jna local_label(no_insert))
4311
4312/* Some arguments have already been pushed.  Push %imm0's worth */
4313/* of NILs, copy those arguments that have already been vpushed from */
4314/* the old TOS to the new, then insert all of the inherited args */
4315/* and go to the function. */
4316
4317        __(mov %imm0,%temp0)
4318local_label(push_nil_loop):
4319        __(push $nil_value)
4320        __(sub $fixnumone,%temp0)
4321        __(jne local_label(push_nil_loop))
4322
4323/* Need to use arg regs as temporaries.  Stash them in the spill area. */
4324        __(movl %arg_y,rcontext(tcr.save1))
4325        __(movl %arg_z,rcontext(tcr.save2))
4326
4327        __(leal (%esp,%imm0),%temp0)    /* start of already-pushed args */
4328        __(leal -nargregs<<fixnumshift(%nargs),%arg_y) /* args pushed */
4329        __(movd %imm0,%mm0)     /* save inherited arg count */
4330        __(xorl %imm0,%imm0)
4331local_label(copy_already_loop):
4332        __(movl (%temp0,%imm0),%arg_z)
4333        __(movl %arg_z,(%esp,%imm0))
4334        __(addl $fixnumone,%imm0)
4335        __(cmpl %imm0,%arg_y)
4336        __(jne local_label(copy_already_loop))
4337
4338        __(lea -node_size(%temp0,%imm0),%arg_y) /* start of args on stack */
4339        __(movl $7<<fixnumshift,%temp0) /* skip code, new fn */
4340        __(movd %mm0,%imm0)
4341local_label(insert_loop):
4342        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4343        __(addl $node_size,%temp0)
4344        __(addl $fixnumone,%nargs)
4345        __(movl %arg_z,(%arg_y))
4346        __(subl $node_size,%arg_y)
4347        __(subl $fixnumone,%imm0)
4348        __(jne local_label(insert_loop))
4349
4350        /* Recover arg regs, saved earlier */
4351        __(movl rcontext(tcr.save1),%arg_y)
4352        __(movl rcontext(tcr.save2),%arg_z)
4353        __(jmp local_label(go))
4354       
4355/* Here if no args were pushed by the caller. */
4356/* cases: */
4357/* no args, more than two inherited args */
4358/* a single arg in arg_z, more than one inherited arg */
4359/* two args in arg_y and arg_z, some number of inherited args */
4360
4361/* Therefore, we're always going to have to push something (the sum of */
4362/* %nargs and %imm0 will always be greater than $nargregs), and */
4363/* we will have to reserve space for a stack frame. */
4364/* The 0 args, 2 inherited case and the 1 arg, 1 inherited case get */
4365/* handled at local_label(regs_ony). */
4366       
4367local_label(no_insert):
4368        /* Reserve space for a stack frame */
4369        __(push $reserved_frame_marker)
4370        __(push $reserved_frame_marker)
4371        __(lea 7<<fixnumshift(%imm0),%temp0)    /* last inherited arg */
4372        __(rcmpl(%nargs,$fixnumone))
4373        __(je local_label(set_arg_y))
4374        __(jb local_label(set_y_z))
4375        /* %nargs = $nargregs (i.e., 2), vpush remaining inherited vars. */
4376
4377local_label(vpush_remaining):
4378        __(movl $7<<fixnumshift,%temp0)
4379local_label(vpush_remaining_loop):
4380        __(push misc_data_offset(%fn,%temp0))
4381        __(add $node_size,%temp0)
4382        __(add $fixnumone,%nargs)
4383        __(sub $node_size,%imm0)
4384        __(jnz local_label(vpush_remaining_loop))
4385        __(jmp local_label(go))
4386       
4387local_label(set_arg_y):
4388        /* one arg in arg_z.  set arg_y and vpush remaining inherited args */
4389        __(subl $node_size,%temp0)
4390        __(movl misc_data_offset(%fn,%temp0),%arg_y)
4391        __(addl $fixnumone,%nargs)
4392        __(subl $fixnumone,%imm0)
4393        __(jmp local_label(vpush_remaining))
4394local_label(set_y_z):
4395        __(subl $node_size,%temp0)
4396        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4397        __(addl $fixnumone,%nargs)
4398        __(subl $fixnumone,%imm0)
4399        __(jmp local_label(set_arg_y))
4400
4401local_label(go):
4402        __(movl misc_data_offset+(6*node_size)(%fn),%fn)
4403        __(push rcontext(tcr.save0))    /* restore return addr */
4404        __(movapd %fpzero,rcontext(tcr.save0))  /* clear out spill area */
4405        __(jmp *%fn)
4406local_label(regs_only):
4407        __(lea 7<<fixnumshift(%imm0),%temp0)
4408        __(test %nargs,%nargs)
4409        __(jne local_label(one_arg))
4410        /* no args passed, two inherited args */
4411        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_z)
4412        __(cmpl $node_size,%imm0)
4413        __(je local_label(rgo))
4414        __(movl misc_data_offset-(node_size*2)(%fn,%temp0),%arg_y)
4415local_label(rgo):
4416        __(addl %imm0,%nargs)
4417        __(jmp *misc_data_offset+(6*node_size)(%fn))
4418local_label(one_arg):
4419        /* one arg was passed, so there's one inherited arg */
4420        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_y)
4421        __(jmp local_label(rgo))
4422_endsubp(call_closure)
4423
4424_spentry(poweropen_callbackX)
4425        __(int $3)
4426_endsubp(poweropen_callbackX)
4427
4428_spentry(poweropen_ffcallX)
4429        __(int $3)
4430_endsubp(poweropen_ffcallX)
4431
4432_spentry(eabi_ff_call)
4433        __(int $3)
4434_endsubp(eabi_ff_call)
4435
4436_spentry(eabi_callback)
4437        __(int $3)
4438_endsubp(eabi_callback)
4439
4440
4441/* Unused, and often not used on PPC either  */
4442_spentry(callbuiltin)
4443        __(int $3)
4444_endsubp(callbuiltin)
4445
4446_spentry(callbuiltin0)
4447        __(int $3)
4448_endsubp(callbuiltin0)
4449
4450_spentry(callbuiltin1)
4451        __(int $3)
4452_endsubp(callbuiltin1)
4453
4454_spentry(callbuiltin2)
4455        __(int $3)
4456_endsubp(callbuiltin2)
4457
4458_spentry(callbuiltin3)
4459        __(int $3)
4460_endsubp(callbuiltin3)
4461
4462_spentry(restorefullcontext)
4463        __(int $3)
4464_endsubp(restorefullcontext)
4465
4466_spentry(savecontextvsp)
4467        __(int $3)
4468_endsubp(savecontextvsp)
4469
4470_spentry(savecontext0)
4471        __(int $3)
4472_endsubp(savecontext0)
4473
4474_spentry(restorecontext)
4475        __(int $3)
4476_endsubp(restorecontext)
4477
4478_spentry(stkconsyz)
4479        __(int $3)
4480_endsubp(stkconsyz)
4481
4482_spentry(stkvcell0)
4483        __(int $3)
4484_endsubp(stkvcell0)
4485
4486_spentry(stkvcellvsp)
4487        __(int $3)
4488_endsubp(stkvcellvsp)
4489
4490_spentry(breakpoint)
4491        __(int $3)
4492_endsubp(breakpoint)
4493
4494_spentry(unused_6)
4495        __(int $3)
4496_endsubp(unused_6)
4497
4498/* %temp1 = array, %temp0 = i,%arg_y = j, %arg_z = k */
4499/*
4500_spentry(aref3)
4501        __(testb $fixnummask,%temp0_b)
4502        __(je 0f)
4503        __(uuo_error_reg_not_fixnum(Rtemp0))
45040:      __(testl $fixnummask,%arg_y)
4505        __(je 1f)
4506        __(uuo_error_reg_not_fixnum(Rarg_y))
45071:      __(testb $fixnummask,%arg_z_b)
4508        __(je 2f)
4509        __(uuo_error_reg_not_fixnum(Rarg_z))
45102:      __(extract_typecode(%temp1,%imm0))
4511        __(cmpb $subtag_arrayH,%imm0_b)
4512        __(jne 3f)
4513        __(cmpl $3<<fixnumshift,arrayH.rank(%temp1))
4514        __(je 4f)
45153:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
45164:      __(cmpl arrayH.dim0(%temp1),%temp0)
4517        __(jb 5f)
4518        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
45195:      __(movl arrayH.dim0+node_size(%temp1),%imm0)
4520        __(cmpl %imm0,%arg_y)
4521        __(jb 6f)
4522        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
45236:      __(unbox_fixnum(%imm0,%imm0))
4524        __(movl arrayH.dim0+(node_size*2)(%temp1),%imm1)
4525        __(cmpq %imm1,%arg_z)
4526        __(jb 7f)
4527        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
45287:      __(unbox_fixnum(%imm1,%imm1))
4529        __(imulq %imm1,%arg_y)
4530        __(mulq %imm1)
4531        __(imulq %imm0,%arg_x)
4532        __(addq %arg_x,%arg_z)
4533        __(addq %arg_y,%arg_z)
4534        __(movq %temp0,%arg_y)
45358:      __(addq arrayH.displacement(%arg_y),%arg_z)
4536        __(movq arrayH.data_vector(%arg_y),%arg_y)
4537        __(extract_subtag(%arg_y,%imm1_b))
4538        __(cmpb $subtag_vectorH,%imm1_b)
4539        __(ja C(misc_ref_common))
4540        __(jmp 8b)
4541_endsubp(aref3)
4542*/       
4543
4544/* %temp1 = array, %imm0 = i, %temp0 = j, %arg_y = k, %arg_z = newval. */
4545/*
4546_spentry(aset3)
4547        __(testb $fixnummask,%temp0_b)
4548        __(je 0f)
4549        __(uuo_error_reg_not_fixnum(Rtemp0))
45500:      __(testb $fixnummask,%arg_x_b)
4551        __(je 1f)
4552        __(uuo_error_reg_not_fixnum(Rarg_x))
45531:      __(testb $fixnummask,%arg_y_b)
4554        __(je 2f)
4555        __(uuo_error_reg_not_fixnum(Rarg_y))
45562:      __(extract_typecode(%temp1,%imm0))
4557        __(cmpb $subtag_arrayH,%imm0_b)
4558        __(jne 3f)
4559        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4560        __(je 4f)
45613:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
45624:      __(cmpq arrayH.dim0(%temp1),%temp0)
4563        __(jb 5f)
4564        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
45655:      __(movq arrayH.dim0+node_size(%temp1),%imm0)
4566        __(cmpq %imm0,%arg_x)
4567        __(jb 6f)
4568        __(uuo_error_array_bounds(Rarg_x,Rtemp1))
45696:      __(unbox_fixnum(%imm0,%imm0))
4570        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4571        __(cmpq %imm1,%arg_y)
4572        __(jb 7f)
4573        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
45747:      __(unbox_fixnum(%imm1,%imm1))
4575        __(imulq %imm1,%arg_x)
4576        __(mulq %imm1)
4577        __(imulq %imm0,%temp0)
4578        __(addq %temp0,%arg_y)
4579        __(addq %arg_x,%arg_y)
4580        __(movq %temp1,%arg_x)
45818:      __(addq arrayH.displacement(%arg_x),%arg_y)
4582        __(movq arrayH.data_vector(%arg_x),%arg_x)
4583        __(extract_subtag(%arg_x,%imm1_b))
4584        __(cmpb $subtag_vectorH,%imm1_b)
4585        __(ja C(misc_set_common))
4586        __(jmp 8b)
4587_endsubp(aset3)
4588*/
Note: See TracBrowser for help on using the repository browser.