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

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

Define csp_frame struct. Use it in a few places, also saving the
frame pointer therein.

File size: 148.6 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        __(unbox_fixnum(%arg_z,%imm0))
2646        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2647        __(cmpl $tstack_alloc_limit,%imm0)
2648        __(jae 1f)
2649        __(movd rcontext(tcr.foreign_sp),%mm0)
2650        __(subl %imm0,rcontext(tcr.foreign_sp))
2651        __(movl rcontext(tcr.foreign_sp),%arg_z)
2652        __(movd %mm0,(%arg_z))
2653        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2654        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2655        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2656        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2657        __(movl %imm0,macptr.address(%arg_z))
2658        __(movss %fpzero,macptr.domain(%arg_z))
2659        __(movss %fpzero,macptr.type(%arg_z))
2660        __(ret)
26611:      __(movd rcontext(tcr.foreign_sp),%mm0)
2662        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2663        __(movl rcontext(tcr.foreign_sp),%imm0)
2664        __(movd %mm0,(%imm0))
2665        __(movl %ebp,csp_frame.save_ebp(%imm0))
2666        __(set_nargs(1))
2667        __(movl $nrs.new_gcable_ptr,%fname)
2668        __(jump_fname())
2669_endsubp(makestackblock)
2670
2671_spentry(makestackblock0)
2672        __(unbox_fixnum(%arg_z,%imm0))
2673        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2674        __(cmpl $tstack_alloc_limit,%imm0)
2675        __(jae 9f)
2676        __(movl rcontext(tcr.foreign_sp),%temp0)
2677        __(subl %imm0,rcontext(tcr.foreign_sp))
2678        __(movl rcontext(tcr.foreign_sp),%arg_z)
2679        __(movl %temp0,(%arg_z))
2680        __(movl %ebp,csp_frame.save_ebp(%arg_z))
2681        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2682        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2683        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2684        __(movl %imm0,macptr.address(%arg_z))
2685        __(movss %fpzero,macptr.domain(%arg_z))
2686        __(movss %fpzero,macptr.type(%arg_z))
2687        __(jmp 2f)
26881:      __(movsd %fpzero,(%imm0))
2689        __(addl $dnode_size,%imm0)
26902:      __(cmpl %imm0,%temp0)
2691        __(jne 1b)
2692        __(repret)
26939:      __(movd rcontext(tcr.foreign_sp),%mm0)
2694        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2695        __(movl rcontext(tcr.foreign_sp),%imm0)
2696        __(movd %mm0,(%imm0))
2697        __(movl %ebp,csp_frame.save_ebp(%imm0))
2698        __(set_nargs(1))
2699        __(movl $nrs.new_gcable_ptr,%fname)
2700        __(jump_fname())
2701_endsubp(makestackblock0)
2702
2703_spentry(makestacklist)
2704        __(test %arg_y,%arg_y)
2705        __(js 9f)
2706        __(movl %arg_y,%imm0)
2707        __(testb $fixnummask,%imm0_b)
2708        __(jne 9f)
2709        __(addl %imm0,%imm0)
2710        __(rcmpl(%imm0,$tstack_alloc_limit))
2711        __(movl $nil_value,%temp1) 
2712        __(jae 2f)
2713        __(addl $tsp_frame.fixed_overhead,%imm0)
2714        __(TSP_Alloc_Var(%imm0,%temp0))
2715        __(addl $fulltag_cons,%temp0)
2716        __(jmp 1f)
27170:      __(_rplaca(%temp0,%arg_z))
2718        __(_rplacd(%temp0,%temp1))
2719        __(movl %temp0,%temp1)
2720        __(addl $cons.size,%temp0)
27211:      __(subl $fixnumone,%arg_y)
2722        __(jge 0b)
2723        __(movl %temp1,%arg_z)
2724        __(ret)
27252:      __(TSP_Alloc_Fixed(0,%imm0))
2726        __(jmp 4f)
27273:      __(Cons(%arg_z,%temp1,%temp1))
27284:      __(subl $fixnumone,%arg_y)                             
2729        __(jge 3b)
2730        __(movl %temp1,%arg_z)
2731        __(ret)
27329:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
2733_endsubp(makestacklist)
2734
2735/* subtype (boxed) vpushed before initial values. (Had better be a */
2736/* node header subtag.)  Nargs set to count of things vpushed. */
2737_spentry(stkgvector)
2738        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2739        __(shrl $fixnumshift,%imm0)
2740        __(leal -fixnumone(%nargs),%arg_z)
2741        __(movl %arg_z,%arg_y)
2742        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2743        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2744        __(movd %imm0,%mm0)
2745        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2746        __(TSP_Alloc_Var(%imm0,%arg_z))
2747        __(movd %mm0,(%arg_z))
2748        __(addl $fulltag_misc,%arg_z)
2749        __(lea -node_size(%nargs),%imm0)
2750        __(jmp 2f)
27511:      __(pop misc_data_offset(%arg_z,%imm0))
27522:      __(subl $node_size,%imm0)
2753        __(jge 1b)
2754        __(addl $node_size,%esp)
2755        __(jmp *%ra0)
2756_endsubp(stkgvector)
2757
2758/* Allocate a fulltag-misc object. */
2759/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
2760_spentry(misc_alloc)
2761        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2762        __(jne local_label(misc_alloc_not_u24))
2763        __(unbox_fixnum(%arg_z,%imm0))
2764        __(mov %arg_y,%temp0)
2765        __(shl $num_subtag_bits-fixnumshift,%temp0)
2766        __(or %temp0,%imm0)     /* %imm0 now = header */
2767        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2768        __(andb $fulltagmask,%imm0_b)
2769        __(cmpb $fulltag_nodeheader,%imm0_b)
2770        __(je local_label(misc_alloc_32))
2771        __(movd %mm0,%imm0)
2772        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2773        __(jbe local_label(misc_alloc_32))
2774        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2775        __(jbe local_label(misc_alloc_8))
2776        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2777        __(jbe local_label(misc_alloc_16))
2778        __(cmpb $subtag_double_float_vector,%imm0_b)
2779        __(jne local_label(misc_alloc_1))
2780        /* double-float vector case */
2781        __(imul $2,%arg_y,%imm0)
2782        __(jmp local_label(misc_alloc_alloc_vector))
2783local_label(misc_alloc_1):
2784        __(unbox_fixnum(%arg_y,%imm0))
2785        __(addl $7,%imm0)
2786        __(shrl $3,%imm0)
2787        __(jmp local_label(misc_alloc_alloc_vector))
2788local_label(misc_alloc_8):
2789        __(unbox_fixnum(%arg_y,%imm0))
2790        __(jmp local_label(misc_alloc_alloc_vector))
2791local_label(misc_alloc_16):
2792        __(unbox_fixnum(%arg_y,%imm0))
2793        __(shl $1,%imm0)
2794        __(jmp local_label(misc_alloc_alloc_vector))
2795local_label(misc_alloc_32):
2796        __(movl %arg_y,%imm0)
2797local_label(misc_alloc_alloc_vector):
2798        __(dnode_align(%imm0,node_size,%imm0))
2799        __(Misc_Alloc(%arg_z))
2800        __(ret)
2801local_label(misc_alloc_not_u24):
2802        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2803_endsubp(misc_alloc)
2804
2805/* N.B. arg count word in %imm0, not %nargs */
2806/* no %whole_reg;  it's in rcontext(tcr.save0) */
2807/* %arg_reg is %temp1, key vector in %arg_y */
2808_startfn(C(destbind1))
2809        __(movl %ra0,rcontext(tcr.save1))
2810        /* Save entry %esp in case of error   */
2811        __(movd %esp,%mm0)
2812        /* Save arg count word */
2813        __(movd %imm0,%mm1)
2814        /* Extract required arg count.   */
2815        __(testb %imm0_b,%imm0_b)
2816        __(je local_label(opt))         /* skip if no required args   */
2817        __(movzbl %imm0_b,%imm0)
2818local_label(req_loop): 
2819        __(compare_reg_to_nil(%arg_reg))
2820        __(je local_label(toofew))
2821        __(movb $fulltagmask,%imm0_bh)
2822        __(andb %arg_reg_b,%imm0_bh)
2823        __(cmpb $fulltag_cons,%imm0_bh)
2824        __(jne local_label(badlist))
2825        __(subb $1,%imm0_b)
2826        __(pushl cons.car(%arg_reg))
2827        __(_cdr(%arg_reg,%arg_reg))
2828        __(jne local_label(req_loop))
2829        __(movd %mm1,%imm0)
2830local_label(opt):
2831        __(testb %imm0_bh,%imm0_bh)
2832        __(je local_label(rest_keys))
2833        __(btl $initopt_bit,%imm0)
2834        __(jc local_label(opt_supp))
2835        /* 'simple' &optionals:  no supplied-p, default to nil.   */
2836local_label(simple_opt_loop):
2837        __(compare_reg_to_nil(%arg_reg))
2838        __(je local_label(default_simple_opt))
2839        __(movb $fulltagmask,%imm0_bh)
2840        __(andb %arg_reg_b,%imm0_bh)
2841        __(cmpb $fulltag_cons,%imm0_bh)
2842        __(jne local_label(badlist))
2843        __(subb $1,%imm0_b)
2844        __(pushl cons.car(%arg_reg))
2845        __(_cdr(%arg_reg,%arg_reg))
2846        __(jne local_label(simple_opt_loop))
2847        __(jmp local_label(rest_keys))
2848local_label(default_simple_opt):
2849        __(subb $1,%imm0_b)
2850        __(pushl $nil_value)
2851        __(jne local_label(default_simple_opt))
2852        __(jmp local_label(rest_keys))
2853local_label(opt_supp):
2854        __(movb $fulltagmask,%imm0_bh)
2855        __(andb %arg_reg_b,%imm0_bh)
2856        __(compare_reg_to_nil(%arg_z))
2857        __(je local_label(default_hard_opt))
2858        __(cmpb $fulltag_cons,%imm0_bh)
2859        __(jne local_label(badlist))
2860        __(subb $1,%imm0_b)
2861        __(pushl cons.car(%arg_reg))
2862        __(_cdr(%arg_reg,%arg_reg))
2863        __(push $t_value)
2864        __(jne local_label(opt_supp))
2865        __(jmp local_label(rest_keys))
2866local_label(default_hard_opt):
2867        __(subb $1,%imm0_b)
2868        __(push $nil_value)
2869        __(push $nil_value)
2870        __(jne local_label(default_hard_opt))
2871local_label(rest_keys):
2872        __(btl $restp_bit,%imm0)
2873        __(jc local_label(have_rest))
2874        __(btl $keyp_bit,%imm0)
2875        __(jc local_label(have_keys))
2876        __(compare_reg_to_nil(%arg_reg))
2877        __(jne local_label(toomany))
2878        __(movss %fpzero,rcontext(tcr.save0))
2879        __(jmp *%ra0)
2880local_label(have_rest):
2881        __(pushl %arg_reg)
2882        __(btl $keyp_bit,%imm0)
2883        __(jc local_label(have_keys))
2884        __(movss %fpzero,rcontext(tcr.save0))
2885        __(jmp *%ra0)
2886        /* Ensure that arg_reg contains a proper,even-length list.  */
2887        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
2888local_label(have_keys):
2889        __(movb $255,%imm0_b)
2890        __(push %arg_reg)
2891        __(push %arg_z)
2892        __(xorl %arg_z,%arg_z)
2893local_label(count_keys_loop):
2894        __(compare_reg_to_nil(%arg_reg))
2895        __(je local_label(counted_keys))
2896        __(subb $1,%imm0_b)
2897        __(jb local_label(toomany))
2898        __(movb $fulltagmask,%arg_z_bh)
2899        __(andb %arg_reg_b,%arg_z_bh)
2900        __(cmpb $fulltag_cons,%arg_z_bh)
2901        __(jne local_label(badlist))
2902        __(_cdr(%arg_reg,%arg_reg))
2903        __(movb $fulltagmask,%arg_z_bh)
2904        __(andb %arg_reg_b,%arg_z_bh)
2905        __(cmpb $fulltag_cons,%arg_z_bh)
2906        __(jne local_label(badlist))
2907        __(_cdr(%arg_reg,%arg_reg))
2908        __(jmp local_label(count_keys_loop))
2909local_label(counted_keys):             
2910        /* We've got a proper, even-length list of key/value pairs in  */
2911        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
2912        /* of NILs on the vstack.   */
2913        __(pop %arg_z)
2914        __(pop %arg_reg)
2915        __(movd %mm1,%imm0)
2916        __(shrl $16,%imm0)
2917        __(movzbl %imm0_b,%imm0)
2918        __(movl %esp,rcontext(tcr.unboxed0))    /* 0th value/supplied-p pair */
2919        __(jmp local_label(push_pair_test))
2920local_label(push_pair_loop):
2921        __(push $nil_value)
2922        __(push $nil_value)
2923local_label(push_pair_test):   
2924        __(subb $1,%imm0_b)
2925        __(jge local_label(push_pair_loop))
2926        __(push %temp0) /* keyword */
2927        __(push %arg_z) /* value */
2928        __(vector_length(%arg_y,%imm0))
2929        __(push %arg_reg)
2930        __(push %imm0)  /* keyword vector length */
2931        __(movd %mm1,%imm0)
2932        __(movl $0,rcontext(tcr.unboxed1)) /* count of unknown keywords seen */
2933local_label(match_keys_loop):
2934        __(movl 4(%esp),%arg_reg)
2935        __(compare_reg_to_nil(%arg_reg))
2936        __(je local_label(matched_keys))
2937        __(_car(%arg_reg,%temp0))
2938        __(_cdr(%arg_reg,%arg_reg))
2939        __(_car(%arg_reg,%arg_z))
2940        __(_cdr(%arg_reg,%arg_reg))
2941        __(movl %arg_reg,4(%esp))
2942        __(xorl %temp1,%temp1)
2943        __(jmp local_label(match_test))
2944local_label(match_loop):
2945        __(cmpl misc_data_offset(%arg_y,%temp1),%arg_z)
2946        __(je local_label(matched))
2947        __(addl $node_size,%temp1)
2948local_label(match_test):
2949        __(cmpl %temp1,(%esp))  /* compare index, keyword vector length */
2950        __(jne local_label(match_loop))
2951        /* No match.  Note unknown keyword, check for :allow-other-keys   */
2952        __(addl $1,rcontext(tcr.unboxed1))
2953        __(cmpl $nrs.kallowotherkeys,%temp0)
2954        __(jne local_label(match_keys_loop))
2955        __(subl $1,rcontext(tcr.unboxed1))
2956        __(btsl $seen_aok_bit,%imm0)
2957        __(jc local_label(match_keys_loop))
2958        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
2959        __(compare_reg_to_nil(%arg_z))
2960        __(je local_label(match_keys_loop))
2961        __(btsl $aok_bit,%imm0)
2962        __(jmp local_label(match_keys_loop))
2963        /* Got a match.  Worry about :allow-other-keys here, too.   */
2964local_label(matched):
2965        __(negl %temp1)
2966        __(shll $1,%temp1)
2967        __(addl rcontext(tcr.unboxed0),%temp1)
2968        __(cmpl $nil_value,-node_size*2(%temp1))
2969        __(jne local_label(match_keys_loop))
2970        __(movl %arg_z,-node_size(%temp1))
2971        __(movl $t_value,-node_size*2(%temp1))
2972        __(cmpl $nrs.kallowotherkeys,%temp0)
2973        __(jne local_label(match_keys_loop))
2974        __(btsl $seen_aok_bit,%imm0)
2975        __(jnc local_label(match_keys_loop))
2976        __(compare_reg_to_nil(%arg_z))
2977        __(je local_label(match_keys_loop))
2978        __(btsl $aok_bit,%imm0)
2979        __(jmp local_label(match_keys_loop))
2980local_label(matched_keys):     
2981        __(cmpl $0,rcontext(tcr.unboxed1))      /* any unknown keys seen? */
2982        __(je local_label(keys_ok))
2983        __(btl $aok_bit,%imm0)
2984        __(jnc local_label(badkeys))
2985local_label(keys_ok):
2986        __(addl $(3*node_size),%esp)
2987        __(pop %ra0)
2988        __(movss %fpzero,rcontext(tcr.save0))
2989        __(jmp *%ra0)
2990        /* Some unrecognized keywords.  Complain generically about   */
2991        /* invalid keywords.   */
2992local_label(badkeys):
2993        __(movl $XBADKEYS,%arg_y)
2994        __(jmp local_label(destructure_error))
2995local_label(toomany):
2996        __(movl $XCALLTOOMANY,%arg_y)
2997        __(jmp local_label(destructure_error))
2998local_label(toofew):
2999        __(movl $XCALLTOOFEW,%arg_y)
3000        __(jmp local_label(destructure_error))
3001local_label(badlist):
3002        __(movl $XCALLNOMATCH,%arg_y)
3003local_label(destructure_error):
3004        __(movd %mm0,%esp)              /* undo everything done to the stack */
3005        __(movl rcontext(tcr.save0),%arg_z)     /* %whole_reg */
3006        __(movss %fpzero,rcontext(tcr.save0))
3007        __(set_nargs(2))
3008        __(push %ra0)
3009        __(jmp _SPksignalerr)
3010_endfn(C(destbind1))
3011
3012_spentry(macro_bind)
3013        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3014        __(extract_fulltag(%arg_reg,%imm0))
3015        __(cmpb $fulltag_cons,%imm0_b)
3016        __(jne 1f)
3017        __(_cdr(%arg_reg,%arg_reg))
3018        __(jmp C(destbind1))
30191:      __(movl $XCALLNOMATCH,%arg_y)
3020        __(movl rcontext(tcr.save0),%arg_z)
3021        __(movss %fpzero,rcontext(tcr.save0))
3022        __(set_nargs(2))
3023        __(push %ra0)       
3024        __(jmp _SPksignalerr)
3025
3026_endsubp(macro_bind)
3027
3028_spentry(destructuring_bind)
3029        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
3030        __(jmp C(destbind1))
3031_endsubp(destructuring_bind)
3032
3033_spentry(destructuring_bind_inner)
3034        __(movl %arg_z,rcontext(tcr.save0))     /* %whole_reg */
3035        __(jmp C(destbind1))
3036_endsubp(destructuring_bind_inner)
3037
3038_spentry(vpopargregs)
3039        __(int $3)
3040_endsubp(vpopargregs)
3041
3042/* If arg_z is an integer, return in imm0 something whose sign  */
3043/* is the same as arg_z's.  If not an integer, error.   */
3044_spentry(integer_sign)
3045        __(mov %arg_z,%imm0)
3046        __(testb $tagmask,%arg_z_b)
3047        __(je 8f)
3048        __(extract_typecode(%arg_z,%imm0))
3049        __(cmpb $subtag_bignum,%imm0_b)
3050        __(jne 9f)
3051        __(getvheader(%arg_z,%imm0))
3052        __(shr $num_subtag_bits,%imm0)
3053        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
30548:      __(repret)
30559:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3056_endsubp(integer_sign)
3057
3058/* "slide" nargs worth of values up the stack.  imm0 contains */
3059/* the difference between the current stack pointer and the target. */
3060_spentry(mvslide)
3061        __(movd %nargs,%mm0)
3062        __(lea (%esp,%nargs),%arg_y)
3063        __(lea (%arg_y,%imm0),%imm0)
3064        __(test %nargs,%nargs)
3065        __(je 2f)
30661:
3067        __(subl $node_size,%arg_y)
3068        __(movl (%arg_y),%arg_z)
3069        __(subl $node_size,%imm0)
3070        __(movl %arg_z,(%imm0))
3071        __(subl $node_size,%nargs)
3072        __(jne 1b)
30732:      __(movl %imm0,%esp)
3074        __(movd %mm0,%nargs)
3075        __(jmp *%ra0)
3076_endsubp(mvslide)
3077
3078_spentry(save_values)
3079        __(movd rcontext(tcr.save_tsp),%mm1)
3080/* common exit: nargs = values in this set, mm1 = ptr to tsp before call to save_values   */
3081local_label(save_values_to_tsp):
3082        __(movl %ra0,rcontext(tcr.save0))
3083        __(movl rcontext(tcr.save_tsp),%temp0)
3084        __(dnode_align(%nargs,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3085        __(TSP_Alloc_Var(%imm0,%arg_z))
3086        __(movl rcontext(tcr.save_tsp),%imm0)
3087        __(movd %mm1,(%imm0))
3088        __(movl %nargs,(%arg_z))
3089        __(movl %temp0,node_size(%arg_z))
3090        __(leal 2*node_size(%arg_z,%nargs),%arg_y)
3091        __(leal (%esp,%nargs),%imm0)
3092        __(cmpl %imm0,%esp)
3093        __(jmp 2f)
30941:      __(subl $node_size,%imm0)
3095        __(movl (%imm0),%arg_z)
3096        __(subl $node_size,%arg_y)
3097        __(cmpl %imm0,%esp)
3098        __(movl %arg_z,(%arg_y))
30992:      __(jne 1b)
3100        __(addl %nargs,%esp)
3101        __(movl rcontext(tcr.save0),%ra0)
3102        __(movl $0,rcontext(tcr.save0))
3103        __(jmp *%ra0)
3104_endsubp(save_values)
3105
3106/* Add the multiple values that are on top of the vstack to the set  */
3107/* saved in the top tsp frame, popping them off of the vstack in the  */
3108/* process.  It is an error (a bad one) if the TSP contains something  */
3109/* other than a previously saved set of multiple-values.  */
3110/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3111/* each add_values call adds another linked element to the list of  */
3112/* values. This makes recover_values harder.   */
3113_spentry(add_values)
3114        /* do we need to preserve imm0? */
3115        __(test %nargs,%nargs)
3116        __(movl rcontext(tcr.save_tsp),%imm0)
3117        __(movl (%imm0),%imm0)
3118        __(movd %imm0,%mm1)     /* for the benefit of save_values_to_tsp */
3119        __(jne local_label(save_values_to_tsp))
3120        __(jmp *%ra0)
3121_endsubp(add_values)
3122
3123/* push the values in the value set atop the sp, incrementing nargs.  */
3124/* Discard the tsp frame; leave values atop the sp.   */
3125_spentry(recover_values)
3126        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3127        __(movd %nargs,%mm0)              /* temp1 */
3128        /* First, walk the segments reversing the pointer to previous  */
3129        /* segment pointers Can tell the end because that previous  */
3130        /* segment pointer is the prev tsp pointer   */
3131        __(movl rcontext(tcr.save_tsp),%temp1)
3132        __(movl %temp1,%temp0)  /* current segment   */
3133        __(movl %temp1,%arg_y)  /* last segment   */
3134        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3135local_label(walkloop):
3136        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3137        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3138        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3139        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3140        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3141        __(jne local_label(walkloop))
3142
3143        __(movl %temp1,%arg_z)
3144        __(movd %mm0,%nargs)
3145        /* the final segment pointer is now in %arg_y  */
3146        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3147local_label(pushloop):
3148        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3149        __(test %imm0,%imm0)
3150        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3151        __(leal (%nargs,%imm0),%nargs)
3152        __(jmp 2f)
31531:      __(push -node_size(%temp0))
3154        __(subl $node_size,%temp0)
3155        __(subl $fixnum_one,%imm0)
31562:      __(jne 1b)
3157        __(cmpl %arg_y,%arg_z)
3158        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3159        __(jne local_label(pushloop))
3160        __(movl (%arg_z),%arg_z)
3161        __(movl %arg_z,rcontext(tcr.save_tsp))
3162        __(movl %arg_z,rcontext(tcr.next_tsp))
3163        __(movl rcontext(tcr.save0),%ra0)
3164        __(movl $0,rcontext(tcr.save0))
3165        __(jmp *%ra0)           
3166_endsubp(recover_values)
3167
3168/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3169/* frame if any values (which will be used as outgoing arguments) will  */
3170/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3171/* that no other arguments have been pushed) on entry.   */
3172
3173_spentry(recover_values_for_mvcall)
3174        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
3175        /* First, walk the segments reversing the pointer to previous  */
3176        /* segment pointers Can tell the end because that previous  */
3177        /* segment pointer is the prev tsp pointer   */
3178        __(xorl %nargs,%nargs)
3179        __(push %nargs)
3180        __(movl rcontext(tcr.save_tsp),%temp1)
3181        __(movl %temp1,%temp0)  /* current segment   */
3182        __(movl %temp1,%arg_y)  /* last segment   */
3183        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3184local_label(walkloop_mvcall):
3185        __(movl tsp_frame.data_offset(%temp0),%imm0)
3186        __(addl %imm0,(%esp))
3187        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3188        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3189        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3190        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3191        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3192        __(jne local_label(walkloop_mvcall))
3193
3194        __(movl %temp1,%arg_z)
3195        __(pop %nargs)
3196
3197        __(cmpl $nargregs*node_size,%nargs)
3198        __(jbe local_label(pushloop_mvcall))
3199        __(push $reserved_frame_marker)
3200        __(push $reserved_frame_marker)
3201
3202        /* the final segment pointer is now in %arg_y  */
3203        /* walk backwards, pushing values on the stack and incrementing %nargs*/
3204local_label(pushloop_mvcall):
3205        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment */
3206        __(test %imm0,%imm0)
3207        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3208        __(jmp 2f)
32091:      __(push -node_size(%temp0))
3210        __(subl $node_size,%temp0)
3211        __(subl $fixnum_one,%imm0)
32122:      __(jne 1b)
3213        __(cmpl %arg_y,%arg_z)
3214        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3215        __(jne local_label(pushloop_mvcall))
3216        __(movl (%arg_z),%arg_z)
3217        __(movl %arg_z,rcontext(tcr.save_tsp))
3218        __(movl %arg_z,rcontext(tcr.next_tsp))
3219        __(movl rcontext(tcr.save0),%ra0)
3220        __(movl $0,rcontext(tcr.save0))
3221        __(jmp *%ra0)           
3222_endsubp(recover_values_for_mvcall)
3223
3224_spentry(reset)
3225        __(int $3)
3226_endsubp(reset)
3227
3228/* temp0 = element-count, arg_y = subtag, arg_z = initval */
3229_spentry(misc_alloc_init)
3230        __(push %ebp)
3231        __(movl %esp,%ebp)
3232        __(push %arg_z)
3233        __(movl %arg_y,%arg_z)
3234        __(movl %temp0,%arg_y)
3235        __(push $local_label(misc_alloc_init_back))
3236        __(jmp _SPmisc_alloc)
3237__(tra(local_label(misc_alloc_init_back)))
3238        __(pop %arg_y)
3239        __(leave)
3240        __(movl $nrs.init_misc,%fname)
3241        __(set_nargs(2))
3242        __(jump_fname())
3243_endsubp(misc_alloc_init)
3244
3245_spentry(stack_misc_alloc_init)
3246        __(int $3)
3247_endsubp(stack_misc_alloc_init)
3248
3249        .globl C(popj)
3250_spentry(popj)
3251C(popj):
3252        __(leave)
3253        __(ret)
3254_endsubp(popj)
3255
3256/* arg_z should be of type (signed-byte 64) */
3257/* return unboxed value in mm0 */
3258_spentry(gets64)
3259        __(testb $fixnummask,%arg_z_b)
3260        __(jne 1f)
3261        __(unbox_fixnum(%arg_z,%imm0))
3262        __(movd %imm0,%mm0)
3263        __(jns 8f)
3264        /* get sign into upper half of %mm0 */
3265        __(pcmpeqd %mm1,%mm1)   /* all ones */
3266        __(psllq $32,%mm1)
3267        __(por %mm1,%mm0)
3268        __(ret)
32691:      __(movb %arg_z_b,%imm0_b)
3270        __(andb $tagmask,%imm0_b)
3271        __(cmpb $tag_misc,%imm0_b)
3272        __(jne 9f)
3273        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3274        __(cmpb $subtag_bignum,%imm0_b)
3275        __(jne 9f)
3276        __(movl misc_header_offset(%arg_z),%imm0)
3277        __(cmpl $two_digit_bignum_header,%imm0)
3278        __(jne 9f)
3279        __(movq misc_data_offset(%arg_z),%mm0)
32808:      __(repret)
32819:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3282_endsubp(gets64)
3283
3284/* arg_z should be of type (unsigned-byte 64) */
3285/* return unboxed value in mm0 */
3286_spentry(getu64)
3287        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3288        __(testl %arg_z,%imm0)
3289        __(movl %arg_z,%imm0)
3290        __(jne 1f)
3291        __(sarl $fixnumshift,%imm0)
3292        __(movd %imm0,%mm0)
3293        __(ret)
32941:      __(andb $tagmask,%imm0_b)
3295        __(cmpb $tag_misc,%imm0_b)
3296        __(jne 9f)
3297        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3298        __(cmpb $subtag_bignum,%imm0_b)
3299        __(jne 9f)
3300        __(movl misc_header_offset(%arg_z),%imm0)
3301        __(cmpl $three_digit_bignum_header,%imm0)
3302        __(je 3f)
3303        __(cmpl $two_digit_bignum_header,%imm0)
3304        __(jne 9f)
3305        __(movl misc_data_offset+4(%arg_z),%imm0)
3306        __(testl %imm0,%imm0)
3307        __(js 9f)
3308        __(movq misc_data_offset(%arg_z),%mm0)
3309        __(ret)
33103:      __(movl misc_data_offset(%arg_z),%imm0)
3311        __(cmpl $0,misc_data_offset+8(%arg_z))
3312        __(jne 9f)
3313        __(movq misc_data_offset(%arg_z),%mm0)
3314        __(repret)
33159:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3316_endsubp(getu64)
3317
3318/* Make unsigned integer from value in mm0 */
3319_spentry(makeu64)
3320        __(movq %mm0,%mm1)
3321        __(psrlq $32,%mm0)
3322        __(movd %mm0,%imm0)
3323        __(test %imm0,%imm0)
3324        __(js 3f)
3325        __(jnz 2f)
3326        __(movd %mm1,%imm0)
3327        __(cmpl $target_most_positive_fixnum,%imm0)
3328        __(ja 1f)
3329        __(box_fixnum(%imm0,%arg_z))
3330        __(ret)
33311:      /* maybe make a 1 digit bignum */
3332        __(test %imm0,%imm0)
3333        __(js 2f)
3334        __(movl $one_digit_bignum_header,%imm0)
3335        __(movd %imm0,%mm0)
3336        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3337        __(movd %mm1,misc_data_offset(%arg_z))
3338        __(ret)
3339        /* make a 2 digit bignum */
33402:      __(movl $two_digit_bignum_header,%imm0)
3341        __(movd %imm0,%mm0)
3342        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3343        __(movq %mm1,misc_data_offset(%arg_z))
3344        __(ret)
3345        /* make a 3 digit bignum */
33463:      __(movl $three_digit_bignum_header,%imm0)
3347        __(movd %imm0,%mm0)
3348        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
3349        __(movq %mm1,misc_data_offset(%arg_z))
3350        __(ret)
3351_endsubp(makeu64)
3352
3353/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
3354/* unbound_marker), arg_y = symbol */
3355_spentry(specref)
3356        __(movl symbol.binding_index(%arg_z),%imm0)
3357        __(cmp rcontext(tcr.tlb_limit),%imm0)
3358        __(movl rcontext(tcr.tlb_pointer),%temp1)
3359        __(movl %arg_z,%arg_y)
3360        __(jae 7f)
3361        __(movl (%temp1,%imm0),%arg_z)
3362        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3363        __(jne 8f)
33647:      __(movl symbol.vcell(%arg_y),%arg_z)
33658:      __(repret)             
3366_endsubp(specref)
3367
3368/* arg_y = special symbol, arg_z = new value. */
3369_spentry(specset)
3370        __(movl symbol.binding_index(%arg_y),%imm0)
3371        __(cmp rcontext(tcr.tlb_limit),%imm0)
3372        __(movl rcontext(tcr.tlb_pointer),%temp1)
3373        __(jae 1f)
3374        __(movl (%temp1,%imm0),%temp0)
3375        __(cmpb $no_thread_local_binding_marker,%temp0_b)
3376        __(je 1f)
3377        __(movl %arg_z,(%temp1,%imm0))
3378        __(ret)
33791:      __(movl %arg_y,%temp0)
3380        __(movl $1<<fixnumshift,%arg_y)
3381        __(jmp _SPgvset)
3382_endsubp(specset)
3383
3384_spentry(specrefcheck)
3385        __(mov %arg_z,%arg_y)
3386        __(movl symbol.binding_index(%arg_z),%imm0)
3387        __(cmp rcontext(tcr.tlb_limit),%imm0)
3388        __(jae 7f)
3389        __(movl rcontext(tcr.tlb_pointer),%temp1)
3390        __(movl (%temp1,%imm0),%arg_z)
3391        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
3392        __(jne 8f)
33937:      __(movl symbol.vcell(%arg_y),%arg_z)
33948:      __(cmpb $unbound_marker,%arg_z_b)
3395        __(jne 9f)
3396        __(uuo_error_reg_unbound(Rarg_y))
33979:      __(repret)
3398_endsubp(specrefcheck)
3399
3400_spentry(restoreintlevel)
3401        __(int $3)
3402_endsubp(restoreintlevel)
3403
3404/* Make a lisp integer from the unsigned value in imm0 */
3405_spentry(makeu32)
3406        __(cmpl $target_most_positive_fixnum,%imm0)
3407        __(ja 0f)       /* need to make a bignum */
3408        __(box_fixnum(%imm0,%arg_z))
3409        __(ret)
34100:      __(movd %imm0,%mm1)
3411        __(test %imm0,%imm0)
3412        __(js 1f)
3413        __(movl $one_digit_bignum_header,%imm0)
3414        __(movd %imm0,%mm0)
3415        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3416        __(movd %mm1,misc_data_offset(%arg_z))
3417        __(ret)
34181:      __(movl $two_digit_bignum_header,%imm0)
3419        __(movd %imm0,%mm0)
3420        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3421        __(movd %mm1,misc_data_offset(%arg_z))
3422        __(ret)
3423_endsubp(makeu32)
3424
3425/* arg_z is of type (signed-byte 32) */
3426/* return unboxed value in %imm0 */
3427_spentry(gets32)
3428        __(testb $fixnummask,%arg_z_b)
3429        __(jne 1f)
3430        __(unbox_fixnum(%arg_z,%imm0))
3431        __(ret)
34321:      __(movb %arg_z_b,%imm0_b)
3433        __(andb $tagmask,%imm0_b)
3434        __(cmpb $tag_misc,%imm0_b)
3435        __(jne 9f)
3436        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3437        __(cmpb $subtag_bignum,%imm0_b)
3438        __(jne 9f)
3439        __(movl misc_header_offset(%arg_z),%imm0)
3440        __(cmpl $one_digit_bignum_header,%imm0)
3441        __(jne 9f)
3442        __(movl misc_data_offset(%arg_z),%imm0)
3443        __(ret)
34449:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_signed_byte_32))
3445_endsubp(gets32)
3446
3447/* arg_z is of type (unsigned-byte 32) */
3448/* return unboxed value in %imm0 */
3449_spentry(getu32)
3450        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3451        __(testl %arg_z,%imm0)
3452        __(movl %arg_z,%imm0)
3453        __(jne 1f)
3454        __(sarl $fixnumshift,%imm0)
3455        __(ret)
34561:      __(andb $tagmask,%imm0_b)
3457        __(cmpb $tag_misc,%imm0_b)
3458        __(jne 9f)
3459        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3460        __(cmpb $subtag_bignum,%imm0_b)
3461        __(jne 9f)
3462        __(movl misc_header_offset(%arg_z),%imm0)
3463        __(cmpl $two_digit_bignum_header,%imm0)
3464        __(je 2f)
3465        __(cmpl $one_digit_bignum_header,%imm0)
3466        __(jne 9f)
3467        __(movl misc_data_offset(%arg_z),%imm0)
3468        __(ret)
34692:      __(movl misc_data_offset(%arg_z),%imm0)
3470        __(cmpl $0,misc_data_offset+4(%arg_z))
3471        __(jne 9f)
3472        __(ret)
34739:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_unsigned_byte_32))
3474_endsubp(getu32)
3475
3476_spentry(mvpasssym)
3477        __(int $3)
3478_endsubp(mvpasssym)
3479
3480/* don't smash arg_z */
3481_spentry(unbind)
3482        __(push %arg_z)
3483        __(movl rcontext(tcr.db_link),%imm0)
3484        __(movl rcontext(tcr.tlb_pointer),%arg_z)
3485        __(movl binding.sym(%imm0),%temp0)
3486        __(movl binding.val(%imm0),%arg_y)
3487        __(movl binding.link(%imm0),%imm0)
3488        __(movl %arg_y,(%arg_z,%temp0))
3489        __(movl %imm0,rcontext(tcr.db_link))
3490        __(pop %arg_z)
3491        __(ret)
3492_endsubp(unbind)
3493
3494_spentry(unbind_n)
3495        __(push %temp1)         /* preserve temp1/nargs */
3496        __(push %arg_z)
3497        __(xorl %arg_z,%arg_z)
3498        __(movl rcontext(tcr.db_link),%temp1)
3499        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35001:             
3501        __(movl binding.sym(%temp1),%temp0)
3502        __(movl binding.val(%temp1),%arg_y)
3503        __(movl binding.link(%temp1),%temp1)
3504        __(movl %arg_y,(%arg_z,%temp0))
3505        __(decl %imm0)
3506        __(jne 1b)
3507        __(movl %temp1,rcontext(tcr.db_link))
3508        __(pop %arg_z)
3509        __(pop %temp1)
3510        __(ret) 
3511_endsubp(unbind_n)
3512
3513_spentry(unbind_to)
3514        __(push %arg_y)
3515        __(push %arg_z)
3516        __(push %temp0)
3517        __(push %temp1)
3518       
3519        __(movl rcontext(tcr.db_link),%temp0)
3520        __(movl rcontext(tcr.tlb_pointer),%arg_z)
35211:
3522        __(movl binding.sym(%temp0),%temp1)
3523        __(movl binding.val(%temp0),%arg_y)
3524        __(movl binding.link(%temp0),%temp0)
3525        __(movl %arg_y,(%arg_z,%temp1))
3526        __(cmpl %temp0,%imm0)
3527        __(jne 1b)
3528        __(movl %temp0,rcontext(tcr.db_link))
3529
3530        __(pop %temp1)
3531        __(pop %temp0)
3532        __(pop %arg_z)
3533        __(pop %arg_y)
3534        __(ret)
3535_endsubp(unbind_to)
3536
3537_spentry(bind_interrupt_level_0)
3538        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3539        __(cmpl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3540        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3541        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3542        __(push rcontext(tcr.db_link))
3543        __(movl %esp,rcontext(tcr.db_link))
3544        __(movl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3545        __(js 1f)
35460:      __(jmp *%ra0)
3547        /* Interrupt level was negative; interrupt may be pending */
35481:      __(check_pending_enabled_interrupt(2f))
35492:      __(jmp *%ra0)
3550_endsubp(bind_interrupt_level_0)
3551
3552/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
3553/* of disabling interrupts.)   */
3554_spentry(bind_interrupt_level_m1)
3555        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3556        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3557        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3558        __(push rcontext(tcr.db_link))
3559        __(movl %esp,rcontext(tcr.db_link))
3560        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3561        __(jmp *%ra0)
3562_endsubp(bind_interrupt_level_m1)
3563
3564/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
3565/* do what _SPbind_interrupt_level_0 does. */
3566_spentry(bind_interrupt_level)
3567        __(test %arg_z,%arg_z)
3568        __(jz _SPbind_interrupt_level_0)
3569        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3570        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3571        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
3572        __(push rcontext(tcr.db_link))
3573        __(movl %esp,rcontext(tcr.db_link))
3574        __(movl %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3575        __(jmp *%ra0)
3576_endsubp(bind_interrupt_level)
3577
3578/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
3579/* non-negative, check for pending interrupts. */
3580_spentry(unbind_interrupt_level)
3581        __(btl $TCR_FLAG_BIT_PENDING_SUSPEND,rcontext(tcr.flags))
3582        __(movl rcontext(tcr.tlb_pointer),%arg_y)
3583        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
3584        __(jc 5f)
35850:      __(test %imm0,%imm0)
3586        __(movl rcontext(tcr.db_link),%imm0)
3587        __(movl binding.val(%imm0),%temp0)
3588        __(movl binding.link(%imm0),%imm0)
3589        __(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3590        __(movl %imm0,rcontext(tcr.db_link))
3591        __(js 3f)
35922:      __(repret)
35933:      __(test %temp0,%temp0)
3594        __(js 2b)
3595        __(check_pending_enabled_interrupt(4f))
35964:      __(repret)
35975:       /* Missed a suspend request; force suspend now if we're restoring
3598          interrupt level to -1 or greater */
3599        __(cmpl $-2<<fixnumshift,%imm0)
3600        __(jne 0b)
3601        __(movl rcontext(tcr.db_link),%temp0)
3602        __(movl binding.val(%temp0),%temp0)
3603        __(cmpl %imm0,%temp0)
3604        __(je 0b)
3605        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
3606        __(suspend_now())
3607        __(jmp 0b)
3608_endsubp(unbind_interrupt_level)
3609
3610_spentry(progvrestore)
3611        __(movl rcontext(tcr.save_tsp),%imm0)
3612        __(movl tsp_frame.backlink(%imm0),%imm0) /* ignore .SPnthrowXXX values frame   */
3613        __(movl tsp_frame.data_offset(%imm0),%imm0)
3614        __(shrl $fixnumshift,%imm0)
3615        __(jne _SPunbind_n)
3616        __(repret)
3617_endsubp(progvrestore)
3618
3619/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
3620/* inline.  Call out otherwise.   */
3621_spentry(builtin_plus)
3622        __(movl %arg_y,%imm0)
3623        __(orl %arg_z,%imm0)
3624        __(testb $fixnummask,%imm0_b)
3625        __(jne 1f)
3626        __(addl %arg_y,%arg_z)
3627        __(jo C(fix_one_bit_overflow))
3628        __(repret)
36291:      __(jump_builtin(_builtin_plus,2))
3630_endsubp(builtin_plus)
3631
3632/* %arg_z <- %arg_y - %arg_z.  Do the fixnum case - including overflow -  */
3633/*  inline.  Call out otherwise.   */
3634_spentry(builtin_minus)
3635        __(movl %arg_y,%imm0)
3636        __(orl %arg_z,%imm0)
3637        __(testb $fixnummask,%imm0_b)
3638        __(jne 1f)
3639        __(xchgl %arg_y,%arg_z)
3640        __(subl %arg_y,%arg_z)
3641        __(jo C(fix_one_bit_overflow))
3642        __(repret)
36431:      __(jump_builtin(_builtin_minus,2))
3644_endsubp(builtin_minus)
3645
3646/* %arg_z -< arg_y * arg_z. */
3647/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
3648_spentry(builtin_times)
3649        __(movl %arg_y,%imm0)
3650        __(orb %arg_z_b,%imm0_b)
3651        __(testb $fixnummask,%imm0_b)
3652        __(jne 2f)
3653        __(unbox_fixnum(%arg_z,%imm0))
3654        /* 32-bit fixnum result in %imm0.  Overflow set if it doesn't fit. */
3655        __(imul %arg_y,%imm0)
3656        __(jo 1f)
3657        __(movl %imm0,%arg_z)
3658        __(ret)
36591:      __(unbox_fixnum(%arg_z,%eax))
3660        __(mark_as_imm(%edx))
3661        __(unbox_fixnum(%arg_y,%edx))
3662        __(imul %edx)
3663        __(movd %eax,%mm0)
3664        __(movd %edx,%mm1)
3665        __(mark_as_node(%edx))
3666        __(psllq $32,%mm1)
3667        __(por %mm1,%mm0)
3668        __(jmp _SPmakes64)
36692:      __(jump_builtin(_builtin_times,2))
3670_endsubp(builtin_times)
3671
3672_spentry(builtin_div)
3673        __(jump_builtin(_builtin_div,2))
3674
3675/* %arg_z <- (= %arg_y %arg_z).   */
3676_spentry(builtin_eq)
3677        __(movl %arg_y,%imm0)
3678        __(orb %arg_z_b,%imm0_b)
3679        __(testb $fixnummask,%imm0_b)
3680        __(jne 1f)
3681        __(rcmpl(%arg_z,%arg_y))
3682        __(condition_to_boolean(e,%imm0,%arg_z))
3683        __(ret)
36841:      __(jump_builtin(_builtin_eq,2))
3685_endsubp(builtin_eq)
3686
3687/* %arg_z <- (/= %arg_y %arg_z).          */
3688_spentry(builtin_ne)
3689        __(movl %arg_y,%imm0)
3690        __(orb %arg_z_b,%imm0_b)
3691        __(testb $fixnummask,%imm0_b)
3692        __(jne 1f)
3693        __(rcmpl(%arg_z,%arg_y))
3694        __(condition_to_boolean(ne,%imm0,%arg_z))
3695        __(ret)
36961:      __(jump_builtin(_builtin_ne,2))
3697_endsubp(builtin_ne)
3698
3699/* %arg_z <- (> %arg_y %arg_z).   */
3700_spentry(builtin_gt)
3701        __(movl %arg_y,%imm0)
3702        __(orb %arg_z_b,%imm0_b)
3703        __(testb $fixnummask,%imm0_b)
3704        __(jne 1f)
3705        __(rcmpl(%arg_y,%arg_z))
3706        __(condition_to_boolean(g,%imm0,%arg_z))
3707        __(ret)
37081:      __(jump_builtin(_builtin_gt,2))
3709_endsubp(builtin_gt)
3710
3711/* %arg_z <- (>= %arg_y %arg_z).          */
3712_spentry(builtin_ge)
3713        __(movl %arg_y,%imm0)
3714        __(orb %arg_z_b,%imm0_b)
3715        __(testb $fixnummask,%imm0_b)
3716        __(jne 1f)
3717        __(rcmpl(%arg_y,%arg_z))
3718        __(condition_to_boolean(ge,%imm0,%arg_z))
3719        __(ret)
37201:      __(jump_builtin(_builtin_ge,2))
3721_endsubp(builtin_ge)
3722
3723/* %arg_z <- (< %arg_y %arg_z).   */
3724_spentry(builtin_lt)
3725        __(movl %arg_y,%imm0)
3726        __(orb %arg_z_b,%imm0_b)
3727        __(testb $fixnummask,%imm0_b)
3728        __(jne 1f)
3729        __(rcmpl(%arg_y,%arg_z))
3730        __(condition_to_boolean(l,%imm0,%arg_z))
3731        __(ret)
37321:      __(jump_builtin(_builtin_lt,2))
3733_endsubp(builtin_lt)
3734
3735/* %arg_z <- (<= %arg_y %arg_z).   */
3736_spentry(builtin_le)
3737        __(movl %arg_y,%imm0)
3738        __(orb %arg_z_b,%imm0_b)
3739        __(testb $fixnummask,%imm0_b)
3740        __(jne 1f)
3741        __(rcmpl(%arg_y,%arg_z))
3742        __(condition_to_boolean(le,%imm0,%arg_z))
3743        __(ret)
37441:      __(jump_builtin(_builtin_le,2))
3745_endsubp(builtin_le)
3746
3747_spentry(builtin_eql)
3748        __(cmpl %arg_y,%arg_z)
3749        __(je 1f)
3750        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
3751        /* and both have the same subtag. */
3752        __(movl %arg_y,%imm0)
3753        __(andb $tagmask,%imm0_b)
3754        __(cmpb $tag_misc,%imm0_b)
3755        __(jne 2f)
3756        __(movb %arg_z_b,%imm0_bh)
3757        __(andb $tagmask,%imm0_bh)
3758        __(cmpb %imm0_bh,%imm0_b)
3759        __(jne 2f)
3760        __(extract_subtag(%arg_y,%imm0_b))
3761        __(extract_subtag(%arg_z,%imm0_bh))
3762        __(cmpb %imm0_b,%imm0_bh)
3763        __(jne 2f)
3764        __(jump_builtin(_builtin_eql,2))
37651:      __(movl $t_value,%arg_z)
3766        __(ret)
37672:      __(movl $nil_value,%arg_z)
3768        __(ret)
3769_endsubp(builtin_eql)
3770
3771_spentry(builtin_length)
3772        __(extract_fulltag(%arg_z,%imm0))
3773        __(cmpl $tag_list,%imm0)
3774        __(jz 2f)
3775        __(andl $tagmask,%imm0)
3776        __(cmpl $tag_misc,%imm0)
3777        __(jnz 8f)
3778        __(extract_subtag(%arg_z,%imm0_b))
3779        __(rcmpb(%imm0_b,$min_vector_subtag))
3780        __(jb 8f)
3781        __(je 1f)
3782        /* (simple-array * (*)) */
3783        __(movl %arg_z,%arg_y)
3784        __(vector_length(%arg_y,%arg_z))
3785        __(ret)
37861:      /* vector header */
3787        __(movl vectorH.logsize(%arg_z),%arg_z)
3788        __(ret)
37892:      /* list.  Maybe null, maybe dotted or circular. */
3790        __(movl $-fixnumone,%arg_y)
3791        __(movl %arg_z,%temp0)  /* fast pointer */
3792        __(movl %arg_z,%temp1)  /* slow pointer */
37933:      __(movb %temp0_b,%al)
3794        __(andb $fulltagmask,%al)
3795        __(addl $fixnumone,%arg_y)
3796        __(compare_reg_to_nil(%temp0))
3797        __(je 9f)
3798        __(cmpb $fulltag_cons,%al)
3799        __(jne 8f)
3800        __(movb %temp1_b,%ah)
3801        __(andb $fulltagmask,%ah)
3802        __(_cdr(%temp0,%temp0))
3803        __(testl $fixnumone,%arg_y)
3804        __(je 3b)
3805        __(cmpb $fulltag_cons,%ah)
3806        __(jne 8f)
3807        __(_cdr(%temp1,%temp1))
3808        __(cmpl %temp0,%temp1)
3809        __(jne 3b)
38108:
3811        __(jump_builtin(_builtin_length,1))
38129:
3813        __(movl %arg_y,%arg_z)
3814        __(ret)
3815_endsubp(builtin_length)
3816
3817_spentry(builtin_seqtype)
3818        __(extract_fulltag(%arg_z,%imm0))
3819        __(cmpb $fulltag_cons,%imm0_b)
3820        __(jz 1f)
3821        __(cmpb $tag_misc,%imm0_b)
3822        __(jne 2f)
3823        __(movb misc_subtag_offset(%arg_z),%imm0_b)
3824        __(rcmpb(%imm0_b,$min_vector_subtag))
3825        __(jb 2f)
3826        __(movl $nil_value,%arg_z)
3827        __(ret)
38281:      __(movl $t_value,%arg_z)
3829        __(ret)
38302:
3831        __(jump_builtin(_builtin_seqtype,1))
3832_endsubp(builtin_seqtype)
3833
3834_spentry(builtin_assq)
3835        __(cmpl $nil_value,%arg_z)
3836        __(je 5f)
38371:      __(movl %arg_z,%imm0)
3838        __(andb $fulltagmask,%imm0_b)
3839        __(cmpb $fulltag_cons,%imm0_b)
3840        __(je 2f)
3841        __(uuo_error_reg_not_list(Rarg_z))
38422:      __(_car(%arg_z,%temp0))
3843        __(_cdr(%arg_z,%arg_z))
3844        __(cmpl $nil_value,%temp0)
3845        __(je 4f)
3846        __(movl %temp0,%imm0)
3847        __(andb $fulltagmask,%imm0_b)
3848        __(cmpb $fulltag_cons,%imm0_b)
3849        __(je 3f)
3850        __(uuo_error_reg_not_list(Rtemp0))
38513:      __(_car(%temp0,%temp1))
3852        __(cmpl %temp1,%arg_y)
3853        __(jne 4f)
3854        __(movl %temp0,%arg_z)
3855        __(ret)
38564:      __(cmpl $nil_value,%arg_z)
38575:      __(jnz 1b)
3858        __(repret)
3859_endsubp(builtin_assq)
3860
3861_spentry(builtin_memq)
3862        __(cmpl $nil_value,%arg_z)
3863        __(jmp 3f)
38641:      __(movb $fulltagmask,%imm0_b)
3865        __(andb %arg_z_b,%imm0_b)
3866        __(cmpb $fulltag_cons,%imm0_b)
3867        __(jz 2f)
3868        __(uuo_error_reg_not_list(Rarg_z))
38692:      __(_car(%arg_z,%temp1))
3870        __(_cdr(%arg_z,%temp0))
3871        __(cmpl %temp1,%arg_y)
3872        __(jz 4f)
3873        __(cmpl $nil_value,%temp0)
3874        __(movl %temp0,%arg_z)
38753:      __(jnz 1b)
38764:      __(repret)
3877_endsubp(builtin_memq)
3878
3879logbitp_max_bit = 30
3880
3881_spentry(builtin_logbitp)
3882        /* Call out unless: both args fixnums, arg_y in [0, logbitp_max_bit) */
3883        __(movl %arg_z,%imm0)
3884        __(orl %arg_y,%imm0)
3885        __(testb $fixnummask,%imm0_b)
3886        __(jnz 1f)
3887        __(unbox_fixnum(%arg_y,%imm0))
3888        __(js 1f)       /* bit number negative */
3889        __(addb $fixnumshift,%imm0_b)
3890        __(cmpl $logbitp_max_bit<<fixnumshift,%arg_y)
3891        __(jb 2f)
3892        __(movl $logbitp_max_bit-1+fixnumshift,%imm0)
38932:      __(bt %imm0,%arg_z)
3894        __(condition_to_boolean(b,%imm0,%arg_z))
3895        __(ret)
38961:      __(jump_builtin(_builtin_logbitp,2))
3897_endsubp(builtin_logbitp)
3898
3899_spentry(builtin_logior)
3900        __(movl %arg_y,%imm0)
3901        __(orb %arg_z_b,%imm0_b)
3902        __(testb $fixnummask,%imm0_b)
3903        __(jne 1f)
3904        __(orl %arg_y,%arg_z)
3905        __(ret)
39061:
3907        __(jump_builtin(_builtin_logior,2))
3908_endsubp(builtin_logior)
3909
3910_spentry(builtin_logand)
3911        __(movl %arg_y,%imm0)
3912        __(orb %arg_z_b,%imm0_b)
3913        __(testb $fixnummask,%imm0_b)
3914        __(jne 1f)
3915        __(andl %arg_y,%arg_z)
3916        __(ret)
39171:
3918        __(jump_builtin(_builtin_logand,2))
3919_endsubp(builtin_logand)
3920
3921_spentry(builtin_negate)
3922        __(testb $fixnummask,%arg_z_b)
3923        __(jne 1f)
3924        __(negl %arg_z)
3925        __(jo C(fix_one_bit_overflow))
3926        __(repret)
39271:
3928        __(jump_builtin(_builtin_negate,1))
3929_endsubp(builtin_negate)
3930
3931_spentry(builtin_logxor)
3932        __(movl %arg_y,%imm0)
3933        __(orb %arg_z_b,%imm0_b)
3934        __(testb $fixnummask,%imm0_b)
3935        __(jne 1f)
3936        __(xorl %arg_y,%arg_z)
3937        __(ret)
39381:
3939        __(jump_builtin(_builtin_logxor,2))
3940_endsubp(builtin_logxor)
3941
3942/* temp0 = vector, arg_y = index, arg_z = newval */
3943_spentry(aset1)
3944        __(extract_typecode(%temp0,%imm0))
3945        __(box_fixnum(%imm0,%temp1))
3946        __(cmpb $min_vector_subtag,%imm0_b)
3947        __(ja _SPsubtag_misc_set)
3948        /* push frame... */
3949        __(pop %temp1)
3950        __(push $reserved_frame_marker)
3951        __(push $reserved_frame_marker)
3952        __(push %temp0)
3953        __(push %temp1)
3954        /* and fall through... */
3955_endsubp(aset1)
3956
3957_spentry(builtin_aset1)
3958        __(jump_builtin(_builtin_aset1,3))
3959_endsubp(builtin_aset1)
3960
3961_spentry(builtin_ash)
3962        __(movl %arg_y,%imm0)
3963        __(orb %arg_z_b,%imm0_b)
3964        __(testb $fixnummask,%imm0_b)
3965        __(jne 9f)
3966        __(unbox_fixnum(%arg_z,%imm0))
3967        /* Z flag set if zero ASH shift count */
3968        __(jnz 1f)
3969        __(movl %arg_y,%arg_z) /* shift by 0 */
3970        __(ret)
39711:      __(jns 3f)
3972        __(rcmpl(%imm0,$-31))
3973        __(jg 2f)
3974        __(unbox_fixnum(%arg_y,%imm0))
3975        __(sar $31,%imm0)
3976        __(box_fixnum(%imm0,%arg_z))
3977        __(ret)
39782:      /* Right-shift by small fixnum */
3979        __(negb %imm0_b)
3980        __(movzbl %imm0_b,%ecx)
3981        __(unbox_fixnum(%arg_y,%imm0))
3982        __(sar %cl,%imm0)
3983        __(box_fixnum(%imm0,%arg_z))
3984        __(ret)
39853:      /* Left shift by fixnum.  We can't shift by more than 31 bits, */
3986        /* though shifting by 32 is actually easy. */
3987        __(rcmpl(%imm0,$32))
3988        __(jg 9f)
3989        __(jne 4f)
3990        /* left-shift by 32 bits exactly */
3991        __(unbox_fixnum(%arg_y,%imm0))
3992        __(movd %imm0,%mm0)
3993        __(psllq $32,%mm0)
3994        __(jmp _SPmakes64)
39954:      /* left-shift by 1..31 bits. Safe to move shift count to %cl */
3996        __(movd %imm0,%mm1)     /* shift count */
3997        __(unbox_fixnum(%arg_y,%imm0))
3998        __(movd %imm0,%mm0)
3999        __(sarl $31,%imm0)      /* propagate sign */
4000        __(movd %imm0,%mm2)
4001        __(pshufw $0x4e,%mm2,%mm2) /* swap hi/lo halves */
4002        __(por %mm2,%mm0)
4003        __(psllq %mm1,%mm0)
4004        __(jmp _SPmakes64)
40059:
4006        __(jump_builtin(_builtin_ash,2))
4007_endsubp(builtin_ash)
4008
4009_spentry(builtin_aref1)
4010        __(extract_typecode(%arg_y,%imm0))
4011        __(box_fixnum_no_flags(%imm0,%temp0))
4012        __(cmpb $min_vector_subtag,%imm0_b)
4013        __(ja _SPsubtag_misc_ref)
4014        __(jump_builtin(_builtin_aref1,2))
4015_endsubp(builtin_aref1)
4016
4017/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
4018/* if so.  This might allow us to avoid having to have a priori */
4019/* knowledge of whether a foreign function returns a floating-point result. */
4020/* backlink to saved %esp, below */
4021/* arg n-1 */
4022/* arg n-2 */
4023/* ... */
4024/* arg 0 */
4025/* space for alignment */
4026/* previous %esp */
4027
4028_spentry(ffcall)
4029LocalLabelPrefix[]ffcall:
4030        __(unbox_fixnum(%arg_z,%imm0))
4031        __(testb $fixnummask,%arg_z_b)
4032        __(je 0f)
4033        __(movl macptr.address(%arg_z),%imm0)
40340:
4035        /* Save lisp registers. */
4036        __(push %ebp)
4037        __(mov %esp,%ebp)
4038        __(push %temp0)
4039        __(push %temp1)
4040        __(push %arg_y)
4041        __(push %arg_z)
4042        __(push %fn)
4043        __(movl %esp,rcontext(tcr.save_vsp))
4044        __(movl %ebp,rcontext(tcr.save_ebp))
4045        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4046        __(movl rcontext(tcr.foreign_sp),%esp)
4047        /* preserve state of direction flag */
4048        __(pushfl)
4049        __(popl rcontext(tcr.save_eflags))
4050        __(cld)
4051        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4052        __(emms)
4053        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4054        __(movl (%esp),%ebp)
4055LocalLabelPrefix[]ffcall_setup:
4056        __(addl $node_size,%esp)
4057LocalLabelPrefix[]ffcall_call:
4058        __(call *%eax)
4059LocalLabelPrefix[]ffcall_call_end:
4060        __(movl %ebp,%esp)
4061        __(movl %esp,rcontext(tcr.foreign_sp))
4062        __(clr %arg_z)
4063        __(clr %arg_y)
4064        __(clr %temp1)
4065        __(clr %temp0)
4066        __(clr %fn)
4067        __(pxor %fpzero,%fpzero)
4068        __ifdef([DARWIN])
4069        /* Darwin's math library seems to cause spurious FP exceptions. */
4070        __(movl %arg_z,rcontext(tcr.ffi_exception))
4071        __else
4072        __(stmxcsr rcontext(tcr.ffi_exception))
4073        __endif
4074        __(pushl rcontext(tcr.save_eflags))
4075        __(popfl)
4076        __(movl rcontext(tcr.save_vsp),%esp)
4077        __(movl rcontext(tcr.save_ebp),%ebp)
4078        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4079        __(pop %fn)
4080        __(pop %arg_z)
4081        __(pop %arg_y)
4082        __(pop %temp1)
4083        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4084        __(check_pending_interrupt(%temp0))
4085        __(pop %temp0)
4086        __(leave)
4087        __(ret)
4088        /* need to deal with NSExceptions and Objc-2.0 execptions */
4089_endsubp(ffcall)
4090
4091_spentry(ffcall_return_registers)
4092        __(int $3)
4093_endsubp(ffcall_return_registers)
4094
4095/* We need to reserve a frame here if (a) nothing else was already pushed
4096/* and (b) we push something (e.g., more than 2 args in the lexpr) */
4097_spentry(spread_lexprz)
4098        new_local_labels()
4099        __(movl (%arg_z),%imm0) /* lexpr count */
4100        __(leal node_size(%arg_z,%imm0),%arg_y)
4101        __(movd %arg_y,%mm1)
4102        __(test %nargs,%nargs) /* anything pushed by caller ? */
4103        __(jne 0f)              /* yes, caller has already created frame. */
4104        __(cmpl $(nargregs*node_size),%imm0) /* will we push anything ? */
4105        __(jbe 0f)
4106        __(push $reserved_frame_marker)
4107        __(push $reserved_frame_marker)
41080:      __(addl %imm0,%nargs)
4109        __(cmpl $(1*node_size),%imm0)
4110        __(ja 2f)
4111        __(je 1f)
4112        /* lexpr count was 0; vpop the args that */
4113        /* were pushed by the caller */
4114        __(test %nargs,%nargs)
4115        __(je local_label(all_args_popped))
4116        __(pop %arg_z)
4117local_label(maybe_pop_y):
4118        __(cmpl $(1*node_size),%nargs)
4119        __(je local_label(all_args_popped))
4120        __(pop %arg_y)
4121local_label(all_args_popped):   
4122        /* If all args fit in registers but some were pushed */
4123        /* by the caller, discard the reserved frame that the caller */
4124        /* pushed.         */
4125        __(cmpl %imm0,%nargs)
4126        __(je local_label(go))
4127        __(cmpl $(nargregs*node_size),%nargs)
4128        __(ja local_label(go))
4129        __(addl $(2*node_size),%esp)
4130local_label(go):
4131        __(jmp *%ra0)
4132
4133        /* lexpr count is two or more: vpush args from the lexpr until */
4134        /* we have only two left, then assign them to arg_y and arg_z */
41352:      __(cmpl $(2*node_size),%imm0)
4136        __(je local_label(push_loop_end))
4137local_label(push_loop):
4138        __(lea -1*node_size(%imm0),%imm0)
4139        __(push -node_size(%arg_y))
4140        __(lea -1*node_size(%arg_y),%arg_y)
4141        __(cmpl $(2*node_size),%imm0)
4142        __(jne 2b)
4143local_label(push_loop_end):
4144        __(movl -node_size*2(%arg_y),%arg_z)
4145        __(movl -node_size*1(%arg_y),%arg_y)
4146        __(jmp *%ra0)
4147        /* lexpr count is one: set arg_z from the lexpr, */
4148        /* maybe vpop arg_y  */
41491:      __(movl -node_size*1(%arg_y),%arg_z)
4150        __(jmp local_label(maybe_pop_y))
4151_endsubp(spread_lexprz)
4152
4153_spentry(callback)
4154        __(push %ebp)
4155        __(movl %esp,%ebp)
4156        /* C scalar args are already on the stack. */
4157        /* arg word 0 at 8(%ebp), word 1 at 12(%ebp), etc. */
4158
4159        /* C NVRs */
4160        __(push %edi)
4161        __(push %esi)
4162        __(push %ebx)
4163        __(push %ebp)
4164       
4165        __(box_fixnum(%eax,%esi))       /* put callback index in arg_y */
4166        __(ref_global(get_tcr,%eax))
4167        __(push $1)
4168        __(call *%eax)
4169        __(addl $node_size,%esp)
4170        /* linear TCR addr now in %eax */
4171        __(movw tcr.ldt_selector(%eax), %rcontext_reg)
4172        __(push rcontext(tcr.foreign_sp))
4173        __(movl %esp,rcontext(tcr.foreign_sp))
4174        __(clr %arg_z)
4175        /* arg_y contains callback index */
4176        __(clr %temp1)
4177        __(clr %temp0)
4178        __(clr %fn)
4179        __(pxor %fpzero,%fpzero)
4180        __(movl rcontext(tcr.save_vsp),%esp)
4181        __(movl %ebp,%arg_z)
4182        __(movl rcontext(tcr.save_ebp),%ebp)
4183        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
4184        __(stmxcsr rcontext(tcr.foreign_mxcsr))
4185        __(andb $~mxcsr_all_exceptions,rcontext(tcr.foreign_mxcsr))
4186        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
4187        __(movl $nrs.callbacks,%fname)
4188        __(push $local_label(back_from_callback))
4189        __(set_nargs(2))
4190        __(jump_fname())
4191__(tra(local_label(back_from_callback)))
4192        __(movl %esp,rcontext(tcr.save_vsp))
4193        __(movl %ebp,rcontext(tcr.save_ebp))
4194        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
4195        __(movl rcontext(tcr.foreign_sp),%esp)
4196        __(stmxcsr rcontext(tcr.lisp_mxcsr))
4197        __(emms)
4198        __(pop rcontext(tcr.foreign_sp))
4199        __(ldmxcsr rcontext(tcr.foreign_mxcsr))
4200        __(pop %ebp)
4201        __(pop %ebx)
4202        __(pop %esi)
4203        __(pop %edi)
4204        __(movl 8(%ebp),%eax)
4205        /* doubleword result? */
4206        /* fp result? */
4207        __(leave)
4208        __(ret)
4209_endsubp(callback)
4210
4211/* temp0 = array, arg_y = i, arg_z = j. Typecheck everything.
4212   We don't know whether the array is alleged to be simple or
4213   not, and don't know anythng about the element type.  */
4214
4215_spentry(aref2)
4216        __(testl $fixnummask,%arg_y)
4217        __(je 0f)
4218        __(uuo_error_reg_not_fixnum(Rarg_y))
42190:      __(testb $fixnummask,%arg_z_b)
4220        __(je 1f)
4221        __(uuo_error_reg_not_fixnum(Rarg_z))
42221:      __(extract_typecode(%temp0,%imm0))
4223        __(cmpb $subtag_arrayH,%imm0_b)
4224        __(jne 2f)
4225        __(cmpl $2<<fixnumshift,arrayH.rank(%temp0))
4226        __(je 3f)
42272:      __(uuo_error_reg_not_type(Rtemp0,error_object_not_array_2d))
42283:      __(cmpl arrayH.dim0(%temp0),%arg_y)
4229        __(jb 4f)
4230        __(uuo_error_array_bounds(Rarg_y,Rtemp0))
42314:      __(movl arrayH.dim0+node_size(%temp0),%imm0)
4232        __(cmpl %imm0,%arg_z)
4233        __(jb 5f)
4234        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
42355:      __(sarl $fixnumshift,%imm0)
4236        __(imull %arg_y,%imm0)
4237        __(addl %imm0,%arg_z)
4238        __(movl %temp0,%arg_y)
4239        __(xorl %temp1,%temp1)
42406:      __(addl arrayH.displacement(%arg_y),%arg_z)
4241        __(movl arrayH.data_vector(%arg_y),%arg_y)
4242        __(extract_subtag(%arg_y,%imm0_b))
4243        __(cmpb $subtag_vectorH,%imm0_b)
4244        __(ja C(misc_ref_common))
4245        __(jmp 6b)
4246_endsubp(aref2)
4247
4248_spentry(aref3)
4249        __(int $3)
4250_endsubp(aref3)
4251
4252/* As with aref2, but temp1 = array, temp0 = i, arg_y = j, arg_z = new_value */
4253_spentry(aset2)
4254        __(testb $fixnummask,%temp0_b)
4255        __(je 0f)
4256        __(uuo_error_reg_not_fixnum(Rtemp0))
42570:      __(testl $fixnummask,%arg_y)
4258        __(je 1f)
4259        __(uuo_error_reg_not_fixnum(Rarg_y))
42601:      __(extract_typecode(%temp1,%imm0))
4261        __(cmpb $subtag_arrayH,%imm0_b)
4262        __(jne 2f)
4263        __(cmpl $2<<fixnumshift,arrayH.rank(%temp1))
4264        __(je 3f)
42652:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_2d))
42663:      __(cmpl arrayH.dim0(%temp1),%temp0)
4267        __(jb 4f)
4268        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
42694:      __(movl arrayH.dim0+node_size(%temp1),%imm0)
4270        __(cmpl %imm0,%arg_y)
4271        __(jb 5f)
4272        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
42735:      __(sarl $fixnumshift,%imm0)
4274        __(imull %temp0,%imm0)
4275        __(addl %imm0,%arg_y)
4276        __(movl %temp1,%temp0)
4277        __(xorl %temp1,%temp1)
42786:      __(addl arrayH.displacement(%temp0),%arg_y)
4279        __(movl arrayH.data_vector(%temp0),%temp0)
4280        __(extract_subtag(%temp0,%imm0_b))
4281        __(cmpb $subtag_vectorH,%imm0_b)
4282        __(ja C(misc_set_common))
4283        __(jmp 6b)
4284_endsubp(aset2)
4285
4286_spentry(aset3)
4287        __(int $3)
4288_endsubp(aset3)
4289
4290/* Prepend all but the first seven (6 words of code & other immediate data,
4291/* plus inner fn) and last (lfbits) elements of %fn to the "arglist". */
4292_spentry(call_closure)
4293        new_local_labels()
4294        __(vector_length(%fn,%imm0))
4295        __(subl $8<<fixnumshift,%imm0)  /* imm0 = inherited arg count */
4296        __(lea (%nargs,%imm0),%temp0)
4297        __(cmpl $nargregs<<fixnumshift,%temp0)
4298        __(jna local_label(regs_only))  /* either: 1 arg, 1 inherited, or */
4299                                        /* no args, 2 inherited */
4300        __(pop rcontext(tcr.save0))             /* save return address */
4301        __(cmpl $nargregs<<fixnumshift,%nargs)
4302        __(jna local_label(no_insert))
4303
4304/* Some arguments have already been pushed.  Push %imm0's worth */
4305/* of NILs, copy those arguments that have already been vpushed from */
4306/* the old TOS to the new, then insert all of the inherited args */
4307/* and go to the function. */
4308
4309        __(mov %imm0,%temp0)
4310local_label(push_nil_loop):
4311        __(push $nil_value)
4312        __(sub $fixnumone,%temp0)
4313        __(jne local_label(push_nil_loop))
4314
4315/* Need to use arg regs as temporaries.  Stash them in the spill area. */
4316        __(movl %arg_y,rcontext(tcr.save1))
4317        __(movl %arg_z,rcontext(tcr.save2))
4318
4319        __(leal (%esp,%imm0),%temp0)    /* start of already-pushed args */
4320        __(leal -nargregs<<fixnumshift(%nargs),%arg_y) /* args pushed */
4321        __(movd %imm0,%mm0)     /* save inherited arg count */
4322        __(xorl %imm0,%imm0)
4323local_label(copy_already_loop):
4324        __(movl (%temp0,%imm0),%arg_z)
4325        __(movl %arg_z,(%esp,%imm0))
4326        __(addl $fixnumone,%imm0)
4327        __(cmpl %imm0,%arg_y)
4328        __(jne local_label(copy_already_loop))
4329
4330        __(lea -node_size(%temp0,%imm0),%arg_y) /* start of args on stack */
4331        __(movl $7<<fixnumshift,%temp0) /* skip code, new fn */
4332        __(movd %mm0,%imm0)
4333local_label(insert_loop):
4334        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4335        __(addl $node_size,%temp0)
4336        __(addl $fixnumone,%nargs)
4337        __(movl %arg_z,(%arg_y))
4338        __(subl $node_size,%arg_y)
4339        __(subl $fixnumone,%imm0)
4340        __(jne local_label(insert_loop))
4341
4342        /* Recover arg regs, saved earlier */
4343        __(movl rcontext(tcr.save1),%arg_y)
4344        __(movl rcontext(tcr.save2),%arg_z)
4345        __(jmp local_label(go))
4346       
4347/* Here if no args were pushed by the caller. */
4348/* cases: */
4349/* no args, more than two inherited args */
4350/* a single arg in arg_z, more than one inherited arg */
4351/* two args in arg_y and arg_z, some number of inherited args */
4352
4353/* Therefore, we're always going to have to push something (the sum of */
4354/* %nargs and %imm0 will always be greater than $nargregs), and */
4355/* we will have to reserve space for a stack frame. */
4356/* The 0 args, 2 inherited case and the 1 arg, 1 inherited case get */
4357/* handled at local_label(regs_ony). */
4358       
4359local_label(no_insert):
4360        /* Reserve space for a stack frame */
4361        __(push $reserved_frame_marker)
4362        __(push $reserved_frame_marker)
4363        __(lea 7<<fixnumshift(%imm0),%temp0)    /* last inherited arg */
4364        __(rcmpl(%nargs,$fixnumone))
4365        __(je local_label(set_arg_y))
4366        __(jb local_label(set_y_z))
4367        /* %nargs = $nargregs (i.e., 2), vpush remaining inherited vars. */
4368
4369local_label(vpush_remaining):
4370        __(movl $7<<fixnumshift,%temp0)
4371local_label(vpush_remaining_loop):
4372        __(push misc_data_offset(%fn,%temp0))
4373        __(add $node_size,%temp0)
4374        __(add $fixnumone,%nargs)
4375        __(sub $node_size,%imm0)
4376        __(jnz local_label(vpush_remaining_loop))
4377        __(jmp local_label(go))
4378       
4379local_label(set_arg_y):
4380        /* one arg in arg_z.  set arg_y and vpush remaining inherited args */
4381        __(subl $node_size,%temp0)
4382        __(movl misc_data_offset(%fn,%temp0),%arg_y)
4383        __(addl $fixnumone,%nargs)
4384        __(subl $fixnumone,%imm0)
4385        __(jmp local_label(vpush_remaining))
4386local_label(set_y_z):
4387        __(subl $node_size,%temp0)
4388        __(movl misc_data_offset(%fn,%temp0),%arg_z)
4389        __(addl $fixnumone,%nargs)
4390        __(subl $fixnumone,%imm0)
4391        __(jmp local_label(set_arg_y))
4392
4393local_label(go):
4394        __(movl misc_data_offset+(6*node_size)(%fn),%fn)
4395        __(push rcontext(tcr.save0))    /* restore return addr */
4396        __(movapd %fpzero,rcontext(tcr.save0))  /* clear out spill area */
4397        __(jmp *%fn)
4398local_label(regs_only):
4399        __(lea 7<<fixnumshift(%imm0),%temp0)
4400        __(test %nargs,%nargs)
4401        __(jne local_label(one_arg))
4402        /* no args passed, two inherited args */
4403        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_z)
4404        __(cmpl $node_size,%imm0)
4405        __(je local_label(rgo))
4406        __(movl misc_data_offset-(node_size*2)(%fn,%temp0),%arg_y)
4407local_label(rgo):
4408        __(addl %imm0,%nargs)
4409        __(jmp *misc_data_offset+(6*node_size)(%fn))
4410local_label(one_arg):
4411        /* one arg was passed, so there's one inherited arg */
4412        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_y)
4413        __(jmp local_label(rgo))
4414_endsubp(call_closure)
4415
4416_spentry(poweropen_callbackX)
4417        __(int $3)
4418_endsubp(poweropen_callbackX)
4419
4420_spentry(poweropen_ffcallX)
4421        __(int $3)
4422_endsubp(poweropen_ffcallX)
4423
4424_spentry(eabi_ff_call)
4425        __(int $3)
4426_endsubp(eabi_ff_call)
4427
4428_spentry(eabi_callback)
4429        __(int $3)
4430_endsubp(eabi_callback)
4431
4432
4433/* Unused, and often not used on PPC either  */
4434_spentry(callbuiltin)
4435        __(int $3)
4436_endsubp(callbuiltin)
4437
4438_spentry(callbuiltin0)
4439        __(int $3)
4440_endsubp(callbuiltin0)
4441
4442_spentry(callbuiltin1)
4443        __(int $3)
4444_endsubp(callbuiltin1)
4445
4446_spentry(callbuiltin2)
4447        __(int $3)
4448_endsubp(callbuiltin2)
4449
4450_spentry(callbuiltin3)
4451        __(int $3)
4452_endsubp(callbuiltin3)
4453
4454_spentry(restorefullcontext)
4455        __(int $3)
4456_endsubp(restorefullcontext)
4457
4458_spentry(savecontextvsp)
4459        __(int $3)
4460_endsubp(savecontextvsp)
4461
4462_spentry(savecontext0)
4463        __(int $3)
4464_endsubp(savecontext0)
4465
4466_spentry(restorecontext)
4467        __(int $3)
4468_endsubp(restorecontext)
4469
4470_spentry(stkconsyz)
4471        __(int $3)
4472_endsubp(stkconsyz)
4473
4474_spentry(stkvcell0)
4475        __(int $3)
4476_endsubp(stkvcell0)
4477
4478_spentry(stkvcellvsp)
4479        __(int $3)
4480_endsubp(stkvcellvsp)
4481
4482_spentry(breakpoint)
4483        __(int $3)
4484_endsubp(breakpoint)
4485
4486_spentry(unused_6)
4487        __(int $3)
4488_endsubp(unused_6)
4489
4490/* %temp1 = array, %temp0 = i,%arg_y = j, %arg_z = k */
4491/*
4492_spentry(aref3)
4493        __(testb $fixnummask,%temp0_b)
4494        __(je 0f)
4495        __(uuo_error_reg_not_fixnum(Rtemp0))
44960:      __(testl $fixnummask,%arg_y)
4497        __(je 1f)
4498        __(uuo_error_reg_not_fixnum(Rarg_y))
44991:      __(testb $fixnummask,%arg_z_b)
4500        __(je 2f)
4501        __(uuo_error_reg_not_fixnum(Rarg_z))
45022:      __(extract_typecode(%temp1,%imm0))
4503        __(cmpb $subtag_arrayH,%imm0_b)
4504        __(jne 3f)
4505        __(cmpl $3<<fixnumshift,arrayH.rank(%temp1))
4506        __(je 4f)
45073:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
45084:      __(cmpl arrayH.dim0(%temp1),%temp0)
4509        __(jb 5f)
4510        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
45115:      __(movl arrayH.dim0+node_size(%temp1),%imm0)
4512        __(cmpl %imm0,%arg_y)
4513        __(jb 6f)
4514        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
45156:      __(unbox_fixnum(%imm0,%imm0))
4516        __(movl arrayH.dim0+(node_size*2)(%temp1),%imm1)
4517        __(cmpq %imm1,%arg_z)
4518        __(jb 7f)
4519        __(uuo_error_array_bounds(Rarg_z,Rtemp0))
45207:      __(unbox_fixnum(%imm1,%imm1))
4521        __(imulq %imm1,%arg_y)
4522        __(mulq %imm1)
4523        __(imulq %imm0,%arg_x)
4524        __(addq %arg_x,%arg_z)
4525        __(addq %arg_y,%arg_z)
4526        __(movq %temp0,%arg_y)
45278:      __(addq arrayH.displacement(%arg_y),%arg_z)
4528        __(movq arrayH.data_vector(%arg_y),%arg_y)
4529        __(extract_subtag(%arg_y,%imm1_b))
4530        __(cmpb $subtag_vectorH,%imm1_b)
4531        __(ja C(misc_ref_common))
4532        __(jmp 8b)
4533_endsubp(aref3)
4534*/       
4535
4536/* %temp1 = array, %imm0 = i, %temp0 = j, %arg_y = k, %arg_z = newval. */
4537/*
4538_spentry(aset3)
4539        __(testb $fixnummask,%temp0_b)
4540        __(je 0f)
4541        __(uuo_error_reg_not_fixnum(Rtemp0))
45420:      __(testb $fixnummask,%arg_x_b)
4543        __(je 1f)
4544        __(uuo_error_reg_not_fixnum(Rarg_x))
45451:      __(testb $fixnummask,%arg_y_b)
4546        __(je 2f)
4547        __(uuo_error_reg_not_fixnum(Rarg_y))
45482:      __(extract_typecode(%temp1,%imm0))
4549        __(cmpb $subtag_arrayH,%imm0_b)
4550        __(jne 3f)
4551        __(cmpq $3<<fixnumshift,arrayH.rank(%temp1))
4552        __(je 4f)
45533:      __(uuo_error_reg_not_type(Rtemp1,error_object_not_array_3d))
45544:      __(cmpq arrayH.dim0(%temp1),%temp0)
4555        __(jb 5f)
4556        __(uuo_error_array_bounds(Rtemp0,Rtemp1))
45575:      __(movq arrayH.dim0+node_size(%temp1),%imm0)
4558        __(cmpq %imm0,%arg_x)
4559        __(jb 6f)
4560        __(uuo_error_array_bounds(Rarg_x,Rtemp1))
45616:      __(unbox_fixnum(%imm0,%imm0))
4562        __(movq arrayH.dim0+(node_size*2)(%temp1),%imm1)
4563        __(cmpq %imm1,%arg_y)
4564        __(jb 7f)
4565        __(uuo_error_array_bounds(Rarg_y,Rtemp1))
45667:      __(unbox_fixnum(%imm1,%imm1))
4567        __(imulq %imm1,%arg_x)
4568        __(mulq %imm1)
4569        __(imulq %imm0,%temp0)
4570        __(addq %temp0,%arg_y)
4571        __(addq %arg_x,%arg_y)
4572        __(movq %temp1,%arg_x)
45738:      __(addq arrayH.displacement(%arg_x),%arg_y)
4574        __(movq arrayH.data_vector(%arg_x),%arg_x)
4575        __(extract_subtag(%arg_x,%imm1_b))
4576        __(cmpb $subtag_vectorH,%imm1_b)
4577        __(ja C(misc_set_common))
4578        __(jmp 8b)
4579_endsubp(aset3)
4580*/
Note: See TracBrowser for help on using the repository browser.