source: branches/ia32/lisp-kernel/x86-spentry32.s @ 8828

Last change on this file since 8828 was 8828, checked in by rme, 14 years ago

Add SPgets64.

The thought at the moment is to use mm0 (rather than the %edx:%eax
pair) as the place where gets64/getu64/makes64/makeu64 put or get an
unboxed 64-bit quantity.

If this idea holds up, SPsyscall will to have to know when a syscall
returns a doubleword result, and copy the %edx:%eax pair into %mm0.

File size: 102.7 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        __(int $3)
43        __(mov %arg_y,%imm0)
44        __(andb $tagmask,%imm0_b)
45        __(cmpb $tag_misc,%imm0_b)
46        __(je,pt 0f)
47        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
480:      __(testb $fixnummask,%arg_z_b)
49        __(je,pt 1f)
50        __(uuo_error_reg_not_fixnum(Rarg_z))
511:      __(movl misc_header_offset(%arg_y),%imm0)
52        __(xorb %imm0_b,%imm0_b)
53        __(shrl $num_subtag_bits-fixnumshift,%imm0)
54        __(jb,pt 2f)
55        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
56        __(xorl %imm0,%imm0)
57        __(movb misc_subtag_offset(%arg_y),%imm0_b)
58        /* fall through */
59_endsubp(misc_ref)
60
61/* %imm0 = subtag, %arg_y = vector, %arg_z = index. */
62/* Bounds/type-checking done in caller. */
63_startfn(C(misc_ref_common))
64        __(leal local_label(misc_ref_jmp)(,%imm0,4),%imm0)
65        __(jmp *(%imm0))
66        .p2align 2
67local_label(misc_ref_jmp):
68        /* 00-0f */
69        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
70        .long local_label(misc_ref_invalid) /* 01 cons  */
71        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
72        .long local_label(misc_ref_invalid) /* 03 imm  */
73        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
74        .long local_label(misc_ref_invalid) /* 05 tra  */
75        .long local_label(misc_ref_invalid) /* 06 misc  */
76        .long local_label(misc_ref_u32) /* 07 bignum  */
77        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
78        .long local_label(misc_ref_invalid) /* 09 cons  */
79        .long local_label(misc_ref_node) /* 0a ratio  */
80        .long local_label(misc_ref_invalid) /* 0b imm  */
81        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
82        .long local_label(misc_ref_invalid) /* 0d tra  */
83        .long local_label(misc_ref_invalid) /* 0e misc  */
84        .long local_label(misc_ref_u32) /* 0f single_float  */
85        /* 10-1*/
86        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
87        .long local_label(misc_ref_invalid) /* 11 cons  */
88        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
89        .long local_label(misc_ref_invalid) /* 13 imm  */
90        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
91        .long local_label(misc_ref_invalid) /* 15 tra  */
92        .long local_label(misc_ref_invalid) /* 16 misc  */
93        .long local_label(misc_ref_u32) /* 17 double_float  */
94        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
95        .long local_label(misc_ref_invalid) /* 19 cons  */
96        .long local_label(misc_ref_node) /* 1a complex  */
97        .long local_label(misc_ref_invalid) /* 1b imm  */
98        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
99        .long local_label(misc_ref_invalid) /* 1d tra  */
100        .long local_label(misc_ref_invalid) /* 1e misc  */
101        .long local_label(misc_ref_u32) /* 1f macptr  */
102        /* 20-2*/
103        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
104        .long local_label(misc_ref_invalid) /* 21 cons  */
105        .long local_label(misc_ref_invalid) /* 22 catch_frame  */
106        .long local_label(misc_ref_invalid) /* 23 imm  */
107        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
108        .long local_label(misc_ref_invalid) /* 25 tra  */
109        .long local_label(misc_ref_invalid) /* 26 misc  */
110        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
111        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
112        .long local_label(misc_ref_invalid) /* 29 cons  */
113        .long local_label(misc_ref_function) /* 2a function  */
114        .long local_label(misc_ref_invalid) /* 2b imm  */
115        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
116        .long local_label(misc_ref_invalid) /* 2d tra  */
117        .long local_label(misc_ref_invalid) /* 2e misc  */
118        .long local_label(misc_ref_invalid) /* 2f immheader  */
119        /* 30-3*/
120        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
121        .long local_label(misc_ref_invalid) /* 31 cons  */
122        .long local_label(misc_ref_invalid) /* 32 nodeheader  */
123        .long local_label(misc_ref_invalid) /* 33 imm  */
124        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
125        .long local_label(misc_ref_invalid) /* 35 tra  */
126        .long local_label(misc_ref_invalid) /* 36 misc  */
127        .long local_label(misc_ref_invalid) /* 37 immheader  */
128        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
129        .long local_label(misc_ref_invalid) /* 39 cons  */
130        .long local_label(misc_ref_node) /* 3a symbol  */
131        .long local_label(misc_ref_invalid) /* 3b imm  */
132        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
133        .long local_label(misc_ref_invalid) /* 3d tra  */
134        .long local_label(misc_ref_invalid) /* 3e misc  */
135        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
136        /* 40-4*/
137        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
138        .long local_label(misc_ref_invalid) /* 41 cons  */
139        .long local_label(misc_ref_node) /* 42 lock  */
140        .long local_label(misc_ref_invalid) /* 43 imm  */
141        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
142        .long local_label(misc_ref_invalid) /* 45 tra  */
143        .long local_label(misc_ref_invalid) /* 46 misc  */
144        .long local_label(misc_ref_invalid) /* 47 immheader  */
145        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
146        .long local_label(misc_ref_invalid) /* 49 cons  */
147        .long local_label(misc_ref_node) /* 4a hash_vector  */
148        .long local_label(misc_ref_invalid) /* 4b imm  */
149        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
150        .long local_label(misc_ref_invalid) /* 4d tra  */
151        .long local_label(misc_ref_invalid) /* 4e misc  */
152        .long local_label(misc_ref_invalid) /* 4f immheader  */
153        /* 50-5*/
154        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
155        .long local_label(misc_ref_invalid) /* 51 cons  */
156        .long local_label(misc_ref_node) /* 52 pool  */
157        .long local_label(misc_ref_invalid) /* 53 imm  */
158        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
159        .long local_label(misc_ref_invalid) /* 55 tra  */
160        .long local_label(misc_ref_invalid) /* 56 misc  */
161        .long local_label(misc_ref_invalid) /* 57 immheader  */
162        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
163        .long local_label(misc_ref_invalid) /* 59 cons  */
164        .long local_label(misc_ref_node) /* 5a weak  */
165        .long local_label(misc_ref_invalid) /* 5b imm  */
166        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
167        .long local_label(misc_ref_invalid) /* 5d tra  */
168        .long local_label(misc_ref_invalid) /* 5e misc  */
169        .long local_label(misc_ref_invalid) /* 5f immheader  */
170        /* 60-6*/
171        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
172        .long local_label(misc_ref_invalid) /* 61 cons  */
173        .long local_label(misc_ref_node) /* 62 package  */
174        .long local_label(misc_ref_invalid) /* 63 imm  */
175        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
176        .long local_label(misc_ref_invalid) /* 65 tra  */
177        .long local_label(misc_ref_invalid) /* 66 misc  */
178        .long local_label(misc_ref_invalid) /* 67 immheader  */
179        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
180        .long local_label(misc_ref_invalid) /* 69 cons  */
181        .long local_label(misc_ref_node) /* 6a slot_vector  */
182        .long local_label(misc_ref_invalid) /* 6b imm  */
183        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
184        .long local_label(misc_ref_invalid) /* 6d tra  */
185        .long local_label(misc_ref_invalid) /* 6e misc  */
186        .long local_label(misc_ref_invalid) /* 6f immheader  */
187        /* 70-7*/
188        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
189        .long local_label(misc_ref_invalid) /* 71 cons  */
190        .long local_label(misc_ref_node) /* 72 instance  */
191        .long local_label(misc_ref_invalid) /* 73 imm  */
192        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
193        .long local_label(misc_ref_invalid) /* 75 tra  */
194        .long local_label(misc_ref_invalid) /* 76 misc  */
195        .long local_label(misc_ref_invalid) /* 77 immheader  */
196        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
197        .long local_label(misc_ref_invalid) /* 79 cons  */
198        .long local_label(misc_ref_node) /* 7a struct  */
199        .long local_label(misc_ref_invalid) /* 7b imm  */
200        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
201        .long local_label(misc_ref_invalid) /* 7d tra  */
202        .long local_label(misc_ref_invalid) /* 7e misc  */
203        .long local_label(misc_ref_invalid) /* 7f immheader  */
204        /* 80-8*/
205        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
206        .long local_label(misc_ref_invalid) /* 81 cons  */
207        .long local_label(misc_ref_node) /* 82 istruct  */
208        .long local_label(misc_ref_invalid) /* 83 imm  */
209        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
210        .long local_label(misc_ref_invalid) /* 85 tra  */
211        .long local_label(misc_ref_invalid) /* 86 misc  */
212        .long local_label(misc_ref_invalid) /* 87 immheader  */
213        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
214        .long local_label(misc_ref_invalid) /* 89 cons  */
215        .long local_label(misc_ref_node) /* 8a value_cell  */
216        .long local_label(misc_ref_invalid) /* 8b imm  */
217        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
218        .long local_label(misc_ref_invalid) /* 8d tra  */
219        .long local_label(misc_ref_invalid) /* 8e misc  */
220        .long local_label(misc_ref_invalid) /* 8f immheader  */
221        /* 90-9*/
222        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
223        .long local_label(misc_ref_invalid) /* 91 cons  */
224        .long local_label(misc_ref_node) /* 92 xfunction  */
225        .long local_label(misc_ref_invalid) /* 93 imm  */
226        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
227        .long local_label(misc_ref_invalid) /* 95 tra  */
228        .long local_label(misc_ref_invalid) /* 96 misc  */
229        .long local_label(misc_ref_invalid) /* 97 immheader  */
230        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
231        .long local_label(misc_ref_invalid) /* 99 cons  */
232        .long local_label(misc_ref_node) /* 9a arrayH  */
233        .long local_label(misc_ref_invalid) /* 9b imm  */
234        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
235        .long local_label(misc_ref_invalid) /* 9d tra  */
236        .long local_label(misc_ref_invalid) /* 9e misc  */
237        .long local_label(misc_ref_invalid) /* 9f immheader  */
238        /* a0-af  */
239        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
240        .long local_label(misc_ref_invalid) /* a1 cons  */
241        .long local_label(misc_ref_node) /* a2 vectorH  */
242        .long local_label(misc_ref_invalid) /* a3 imm  */
243        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
244        .long local_label(misc_ref_invalid) /* a5 tra  */
245        .long local_label(misc_ref_invalid) /* a6 misc  */
246        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
247        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
248        .long local_label(misc_ref_invalid) /* a9 cons  */
249        .long local_label(misc_ref_node) /* aa simple_vector  */
250        .long local_label(misc_ref_invalid) /* ab imm  */
251        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
252        .long local_label(misc_ref_invalid) /* ad tra  */
253        .long local_label(misc_ref_invalid) /* ae misc  */
254        .long local_label(misc_ref_u32) /* af u32  */
255        /* b0-bf  */
256        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
257        .long local_label(misc_ref_invalid) /* b1 cons  */
258        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
259        .long local_label(misc_ref_invalid) /* b3 imm  */
260        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
261        .long local_label(misc_ref_invalid) /* b5 tra  */
262        .long local_label(misc_ref_invalid) /* b6 misc  */
263        .long local_label(misc_ref_s32) /* b7 s32  */
264        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
265        .long local_label(misc_ref_invalid) /* b9 cons  */
266        .long local_label(misc_ref_invalid) /* ba nodeheader  */
267        .long local_label(misc_ref_invalid) /* bb imm  */
268        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
269        .long local_label(misc_ref_invalid) /* bd tra  */
270        .long local_label(misc_ref_invalid) /* be misc  */
271        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
272        /* c0-cf  */
273        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
274        .long local_label(misc_ref_invalid) /* c1 cons  */
275        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
276        .long local_label(misc_ref_invalid) /* c3 imm  */
277        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
278        .long local_label(misc_ref_invalid) /* c5 tra  */
279        .long local_label(misc_ref_invalid) /* c6 misc  */
280        .long local_label(misc_ref_string) /* c7 simple_base_string  */
281        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
282        .long local_label(misc_ref_invalid) /* c9 cons  */
283        .long local_label(misc_ref_invalid) /* ca nodeheader  */
284        .long local_label(misc_ref_invalid) /* cb imm  */
285        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
286        .long local_label(misc_ref_invalid) /* cd tra  */
287        .long local_label(misc_ref_invalid) /* ce misc  */
288        .long local_label(misc_ref_u8) /* cf u8  */
289        /* d0-df  */
290        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
291        .long local_label(misc_ref_invalid) /* d1 cons  */
292        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
293        .long local_label(misc_ref_invalid) /* d3 imm  */
294        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
295        .long local_label(misc_ref_invalid) /* d5 tra  */
296        .long local_label(misc_ref_invalid) /* d6 misc  */
297        .long local_label(misc_ref_s8)      /* d7 s8  */
298        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
299        .long local_label(misc_ref_invalid) /* d9 cons  */
300        .long local_label(misc_ref_invalid) /* da nodeheader  */
301        .long local_label(misc_ref_invalid) /* db imm  */
302        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
303        .long local_label(misc_ref_invalid) /* dd tra  */
304        .long local_label(misc_ref_invalid) /* de misc  */
305        .long local_label(misc_ref_invalid) /* df immheader  */
306        /* e0-ef  */
307        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
308        .long local_label(misc_ref_invalid) /* e1 cons  */
309        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
310        .long local_label(misc_ref_invalid) /* e3 imm  */
311        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
312        .long local_label(misc_ref_invalid) /* e5 tra  */
313        .long local_label(misc_ref_invalid) /* e6 misc  */
314        .long local_label(misc_ref_u16) /* e7 u16  */
315        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
316        .long local_label(misc_ref_invalid) /* e9 cons  */
317        .long local_label(misc_ref_invalid) /* ea nodeheader  */
318        .long local_label(misc_ref_invalid) /* eb imm  */
319        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
320        .long local_label(misc_ref_invalid) /* ed tra  */
321        .long local_label(misc_ref_invalid) /* ee misc  */
322        .long local_label(misc_ref_s16) /* ef s16  */
323        /* f0-ff  */
324        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
325        .long local_label(misc_ref_invalid) /* f1 cons  */
326        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
327        .long local_label(misc_ref_invalid) /* f3 imm  */
328        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
329        .long local_label(misc_ref_invalid) /* f5 tra  */
330        .long local_label(misc_ref_invalid) /* f6 misc  */
331        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
332        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
333        .long local_label(misc_ref_invalid) /* f9 cons  */
334        .long local_label(misc_ref_invalid) /* fa nodeheader  */
335        .long local_label(misc_ref_invalid) /* fb imm  */
336        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
337        .long local_label(misc_ref_invalid) /* fd tra  */
338        .long local_label(misc_ref_invalid) /* fe misc  */
339        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
340
341/* Functions are funny.  The first N words are treated as */
342/* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
343
344local_label(misc_ref_function):
345        __(movzwl misc_data_offset(%arg_y), %imm0)
346        __(shl $fixnumshift,%imm0)
347        __(rcmpl(%arg_z,%imm0))
348        __(jb local_label(misc_ref_u32))
349local_label(misc_ref_node):
350        __(movl misc_data_offset(%arg_y,%arg_z),%arg_z)
351        __(ret)
352local_label(misc_ref_u32):
353        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
354        __(jmp _SPmakeu32)
355local_label(misc_ref_s32):
356        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
357        __(jmp _SPmakes32)
358local_label(misc_ref_single_float_vector):
359        __(movss misc_data_offset(%arg_y,%arg_z),%fp1)
360        __(movl $single_float_header,%imm0)
361        __(movd %imm0,%mm0)
362        __(Misc_Alloc_Fixed(%arg_z,single_float.size))
363        __(movss %fp1,single_float.value(%arg_z))
364        __(ret)
365local_label(misc_ref_double_float_vector):
366        __(movsd misc_dfloat_offset(%arg_y,%arg_z),%fp1)
367        __(movl $double_float_header,%imm0)
368        __(movd %imm0,%mm0)
369        __(Misc_Alloc_Fixed(%arg_z,double_float.size))
370        __(movsd %fp1,double_float.value(%arg_z))
371        __(ret)
372local_label(misc_ref_fixnum_vector):
373        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
374        __(box_fixnum(%imm0,%arg_z))
375        __(ret)
376local_label(misc_ref_u8):
377        __(movl %arg_z,%imm0)
378        __(shr $2,%imm0)
379        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0)
380        __(box_fixnum(%imm0,%arg_z))
381        __(ret)
382local_label(misc_ref_s8):
383        __(movl %arg_z,%imm0)
384        __(shr $2,%imm0)
385        __(movsbl misc_data_offset(%arg_y,%imm0),%imm0)
386        __(box_fixnum(%imm0,%arg_z))
387        __(ret)
388local_label(misc_ref_string):
389        __(movl %arg_z,%imm0)
390        __(movl misc_data_offset(%arg_y,%imm0),%imm0)
391        __(shll $charcode_shift,%imm0)
392        __(leal subtag_character(%imm0),%arg_z)
393        __(ret)
394local_label(misc_ref_u16):
395        __(movl %arg_z,%imm0)
396        __(shrl $1,%imm0)
397        __(movzwl misc_data_offset(%arg_y,%imm0),%imm0)
398        __(box_fixnum(%imm0,%arg_z))
399        __(ret)
400local_label(misc_ref_s16):
401        __(movl %arg_z,%imm0)
402        __(shrl $1,%imm0)
403        __(movswl misc_data_offset(%arg_y,%imm0),%imm0)
404        __(box_fixnum(%imm0,%arg_z))
405        __(ret)
406local_label(misc_ref_bit_vector):
407        __(unbox_fixnum(%arg_z,%imm0))
408        __(btl %imm0,misc_data_offset(%arg_y))
409        __(setc %imm0_b)
410        __(movzbl %imm0_b,%imm0)
411        __(box_fixnum(%imm0,%arg_z))
412        __(ret)
413local_label(misc_ref_invalid):
414        __(push $reserved_frame_marker)
415        __(push $reserved_frame_marker)
416        __(push $XBADVEC)
417        __(set_nargs(3))
418        __(jmp _SPksignalerr)
419_endfn(C(misc_ref_common))
420
421/* Like misc_ref, only the boxed subtag is in temp0. */
422_spentry(subtag_misc_ref)
423        __(mov %arg_y,%imm0)
424        __(and $tagmask,%imm0)
425        __(cmp $tag_misc,%imm0)
426        __(je,pt 0f)
427        __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
4280:      __(testb $fixnummask,%arg_z_b)
429        __(je,pt 1f)
430        __(uuo_error_reg_not_fixnum(Rarg_z))
4311:      __(movl misc_header_offset(%arg_y),%imm0)
432        __(xorb %imm0_b,%imm0_b)
433        __(shrl $num_subtag_bits-fixnumshift,%imm0)
434        __(cmp %imm0,%arg_z)
435        __(jb 2f)
436        __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
4372:      __(unbox_fixnum(%temp0,%imm0))
438        __(jmp C(misc_ref_common))
439_endsubp(subtag_misc_ref)
440
441/* Like misc_set, only the boxed subtag is in temp1. */
442_spentry(subtag_misc_set)
443        __(int $3)
444        __(mov %temp0,%imm0)
445        __(andb $tagmask,%imm0_b)
446        __(cmpb $tag_misc,%imm0_b)
447        __(je,pt 0f)
448        __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4490:      __(mov %arg_y,%imm0)
450        __(testb $fixnummask,%imm0_b)
451        __(je,pt 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,pt 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,pt 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 = subtag, %temp0 = vector, %arg_y = index, %arg_z = value */
486_startfn(C(misc_set_common))
487        __(leal local_label(misc_set_jmp)(,%imm0,4),%imm0)
488        __(jmp *(%imm0))
489        .p2align 2
490local_label(misc_set_jmp):
491        /* 00-0f */
492        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
493        .long local_label(misc_set_invalid) /* 01 cons  */
494        .long local_label(misc_set_invalid) /* 02 nodeheader  */
495        .long local_label(misc_set_invalid) /* 03 imm  */
496        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
497        .long local_label(misc_set_invalid) /* 05 tra  */
498        .long local_label(misc_set_invalid) /* 06 misc  */
499        .long local_label(misc_set_u32) /* 07 bignum  */
500        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
501        .long local_label(misc_set_invalid) /* 09 cons  */
502        .long _SPgvset /* 0a ratio  */
503        .long local_label(misc_set_invalid) /* 0b imm  */
504        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
505        .long local_label(misc_set_invalid) /* 0d tra  */
506        .long local_label(misc_set_invalid) /* 0e misc  */
507        .long local_label(misc_set_u32) /* 0f single_float  */
508        /* 10-1f  */
509        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
510        .long local_label(misc_set_invalid) /* 11 cons  */
511        .long local_label(misc_set_invalid) /* 12 nodeheader  */
512        .long local_label(misc_set_invalid) /* 13 imm  */
513        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
514        .long local_label(misc_set_invalid) /* 15 tra  */
515        .long local_label(misc_set_invalid) /* 16 misc  */
516        .long local_label(misc_set_u32) /* 17 double_float  */
517        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
518        .long local_label(misc_set_invalid) /* 19 cons  */
519        .long _SPgvset /* 1a complex  */
520        .long local_label(misc_set_invalid) /* 1b imm  */
521        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
522        .long local_label(misc_set_invalid) /* 1d tra  */
523        .long local_label(misc_set_invalid) /* 1e misc  */
524        .long local_label(misc_set_u32) /* 1f macptr  */
525        /* 20-2f  */
526        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
527        .long local_label(misc_set_invalid) /* 21 cons  */
528        .long local_label(misc_set_invalid) /* 22 catch_frame  */
529        .long local_label(misc_set_invalid) /* 23 imm  */
530        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
531        .long local_label(misc_set_invalid) /* 25 tra  */
532        .long local_label(misc_set_invalid) /* 26 misc  */
533        .long local_label(misc_set_u32) /* 27 dead_macptr  */
534        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
535        .long local_label(misc_set_invalid) /* 29 cons  */
536        .long local_label(misc_set_function) /* 2a function  */
537        .long local_label(misc_set_invalid) /* 2b imm  */
538        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
539        .long local_label(misc_set_invalid) /* 2d tra  */
540        .long local_label(misc_set_invalid) /* 2e misc  */
541        .long local_label(misc_set_invalid) /* 2f immheader  */
542        /* 30-3f  */
543        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
544        .long local_label(misc_set_invalid) /* 31 cons  */
545        .long local_label(misc_set_invalid) /* 32 nodeheader  */
546        .long local_label(misc_set_invalid) /* 33 imm  */
547        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
548        .long local_label(misc_set_invalid) /* 35 tra  */
549        .long local_label(misc_set_invalid) /* 36 misc  */
550        .long local_label(misc_set_invalid) /* 37 immheader  */
551        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
552        .long local_label(misc_set_invalid) /* 39 cons  */
553        .long _SPgvset /* 3a symbol  */
554        .long local_label(misc_set_invalid) /* 3b imm  */
555        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
556        .long local_label(misc_set_invalid) /* 3d tra  */
557        .long local_label(misc_set_invalid) /* 3e misc  */
558        .long local_label(misc_set_u32) /* 3f xcode_vector  */
559        /* 40-4f  */
560        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
561        .long local_label(misc_set_invalid) /* 41 cons  */
562        .long _SPgvset /* 42 lock  */
563        .long local_label(misc_set_invalid) /* 43 imm  */
564        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
565        .long local_label(misc_set_invalid) /* 45 tra  */
566        .long local_label(misc_set_invalid) /* 46 misc  */
567        .long local_label(misc_set_invalid) /* 47 immheader  */
568        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
569        .long local_label(misc_set_invalid) /* 49 cons  */
570        .long _SPgvset /* 4a hash_vector  */
571        .long local_label(misc_set_invalid) /* 4b imm  */
572        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
573        .long local_label(misc_set_invalid) /* 4d tra  */
574        .long local_label(misc_set_invalid) /* 4e misc  */
575        .long local_label(misc_set_invalid) /* 4f immheader  */
576        /* 50-5f  */
577        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
578        .long local_label(misc_set_invalid) /* 51 cons  */
579        .long _SPgvset /* 52 pool  */
580        .long local_label(misc_set_invalid) /* 53 imm  */
581        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
582        .long local_label(misc_set_invalid) /* 55 tra  */
583        .long local_label(misc_set_invalid) /* 56 misc  */
584        .long local_label(misc_set_invalid) /* 57 immheader  */
585        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
586        .long local_label(misc_set_invalid) /* 59 cons  */
587        .long _SPgvset /* 5a weak  */
588        .long local_label(misc_set_invalid) /* 5b imm  */
589        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
590        .long local_label(misc_set_invalid) /* 5d tra  */
591        .long local_label(misc_set_invalid) /* 5e misc  */
592        .long local_label(misc_set_invalid) /* 5f immheader  */
593        /* 60-6f  */
594        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
595        .long local_label(misc_set_invalid) /* 61 cons  */
596        .long _SPgvset /* 62 package  */
597        .long local_label(misc_set_invalid) /* 63 imm  */
598        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
599        .long local_label(misc_set_invalid) /* 65 tra  */
600        .long local_label(misc_set_invalid) /* 66 misc  */
601        .long local_label(misc_set_invalid) /* 67 immheader  */
602        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
603        .long local_label(misc_set_invalid) /* 69 cons  */
604        .long _SPgvset /* 6a slot_vector  */
605        .long local_label(misc_set_invalid) /* 6b imm  */
606        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
607        .long local_label(misc_set_invalid) /* 6d tra  */
608        .long local_label(misc_set_invalid) /* 6e misc  */
609        .long local_label(misc_set_invalid) /* 6f immheader  */
610        /* 70-7f  */
611        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
612        .long local_label(misc_set_invalid) /* 71 cons  */
613        .long _SPgvset /* 72 instance  */
614        .long local_label(misc_set_invalid) /* 73 imm  */
615        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
616        .long local_label(misc_set_invalid) /* 75 tra  */
617        .long local_label(misc_set_invalid) /* 76 misc  */
618        .long local_label(misc_set_invalid) /* 77 immheader  */
619        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
620        .long local_label(misc_set_invalid) /* 79 cons  */
621        .long _SPgvset /* 7a struct  */
622        .long local_label(misc_set_invalid) /* 7b imm  */
623        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
624        .long local_label(misc_set_invalid) /* 7d tra  */
625        .long local_label(misc_set_invalid) /* 7e misc  */
626        .long local_label(misc_set_invalid) /* 7f immheader  */
627        /* 80-8f  */
628        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
629        .long local_label(misc_set_invalid) /* 81 cons  */
630        .long _SPgvset /* 82 istruct  */
631        .long local_label(misc_set_invalid) /* 83 imm  */
632        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
633        .long local_label(misc_set_invalid) /* 85 tra  */
634        .long local_label(misc_set_invalid) /* 86 misc  */
635        .long local_label(misc_set_invalid) /* 87 immheader  */
636        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
637        .long local_label(misc_set_invalid) /* 89 cons  */
638        .long _SPgvset /* 8a value_cell  */
639        .long local_label(misc_set_invalid) /* 8b imm  */
640        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
641        .long local_label(misc_set_invalid) /* 8d tra  */
642        .long local_label(misc_set_invalid) /* 8e misc  */
643        .long local_label(misc_set_invalid) /* 8f immheader  */
644        /* 90-9f  */
645        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
646        .long local_label(misc_set_invalid) /* 91 cons  */
647        .long _SPgvset /* 92 xfunction  */
648        .long local_label(misc_set_invalid) /* 93 imm  */
649        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
650        .long local_label(misc_set_invalid) /* 95 tra  */
651        .long local_label(misc_set_invalid) /* 96 misc  */
652        .long local_label(misc_set_invalid) /* 97 immheader  */
653        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
654        .long local_label(misc_set_invalid) /* 99 cons  */
655        .long _SPgvset /* 9a arrayH  */
656        .long local_label(misc_set_invalid) /* 9b imm  */
657        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
658        .long local_label(misc_set_invalid) /* 9d tra  */
659        .long local_label(misc_set_invalid) /* 9e misc  */
660        .long local_label(misc_set_invalid) /* 9f immheader  */
661        /* a0-af  */
662        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
663        .long local_label(misc_set_invalid) /* a1 cons  */
664        .long _SPgvset /* a2 vectorH  */
665        .long local_label(misc_set_invalid) /* a3 imm  */
666        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
667        .long local_label(misc_set_invalid) /* a5 tra  */
668        .long local_label(misc_set_invalid) /* a6 misc  */
669        .long local_label(misc_set_single_float_vector) /* a7 sf_vector  */
670        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
671        .long local_label(misc_set_invalid) /* a9 cons  */
672        .long _SPgvset /* aa simple_vector  */
673        .long local_label(misc_set_invalid) /* ab imm  */
674        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
675        .long local_label(misc_set_invalid) /* ad tra  */
676        .long local_label(misc_set_invalid) /* ae misc  */
677        .long local_label(misc_set_u32) /* af u32  */
678        /* b0-bf  */
679        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
680        .long local_label(misc_set_invalid) /* b1 cons  */
681        .long local_label(misc_set_invalid) /* b2 nodeheader  */
682        .long local_label(misc_set_invalid) /* b3 imm  */
683        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
684        .long local_label(misc_set_invalid) /* b5 tra  */
685        .long local_label(misc_set_invalid) /* b6 misc  */
686        .long local_label(misc_set_s32) /* b7 s32  */
687        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
688        .long local_label(misc_set_invalid) /* b9 cons  */
689        .long local_label(misc_set_invalid) /* ba nodeheader  */
690        .long local_label(misc_set_invalid) /* bb imm  */
691        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
692        .long local_label(misc_set_invalid) /* bd tra  */
693        .long local_label(misc_set_invalid) /* be misc  */
694        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
695        /* c0-cf  */
696        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
697        .long local_label(misc_set_invalid) /* c1 cons  */
698        .long local_label(misc_set_invalid) /* c2 nodeheader  */
699        .long local_label(misc_set_invalid) /* c3 imm  */
700        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
701        .long local_label(misc_set_invalid) /* c5 tra  */
702        .long local_label(misc_set_invalid) /* c6 misc  */
703        .long local_label(misc_set_string) /* c7 simple_base_string  */
704        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
705        .long local_label(misc_set_invalid) /* c9 cons  */
706        .long local_label(misc_set_invalid) /* ca nodeheader  */
707        .long local_label(misc_set_invalid) /* cb imm  */
708        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
709        .long local_label(misc_set_invalid) /* cd tra  */
710        .long local_label(misc_set_invalid) /* ce misc  */
711        .long local_label(misc_set_u8) /* cf u8  */
712        /* d0-df  */
713        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
714        .long local_label(misc_set_invalid) /* d1 cons  */
715        .long local_label(misc_set_invalid) /* d2 nodeheader  */
716        .long local_label(misc_set_invalid) /* d3 imm  */
717        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
718        .long local_label(misc_set_invalid) /* d5 tra  */
719        .long local_label(misc_set_invalid) /* d6 misc  */
720        .long local_label(misc_set_s8)      /* d7 s8  */
721        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
722        .long local_label(misc_set_invalid) /* d9 cons  */
723        .long local_label(misc_set_invalid) /* da nodeheader  */
724        .long local_label(misc_set_invalid) /* db imm  */
725        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
726        .long local_label(misc_set_invalid) /* dd tra  */
727        .long local_label(misc_set_invalid) /* de misc  */
728        .long local_label(misc_set_invalid) /* df immheader  */
729        /* e0-ef  */
730        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
731        .long local_label(misc_set_invalid) /* e1 cons  */
732        .long local_label(misc_set_invalid) /* e2 nodeheader  */
733        .long local_label(misc_set_invalid) /* e3 imm  */
734        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
735        .long local_label(misc_set_invalid) /* e5 tra  */
736        .long local_label(misc_set_invalid) /* e6 misc  */
737        .long local_label(misc_set_u16) /* e7 u16  */
738        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
739        .long local_label(misc_set_invalid) /* e9 cons  */
740        .long local_label(misc_set_invalid) /* ea nodeheader  */
741        .long local_label(misc_set_invalid) /* eb imm  */
742        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
743        .long local_label(misc_set_invalid) /* ed tra  */
744        .long local_label(misc_set_invalid) /* ee misc  */
745        .long local_label(misc_set_s16) /* ef s16  */
746        /* f0-ff  */
747        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
748        .long local_label(misc_set_invalid) /* f1 cons  */
749        .long local_label(misc_set_invalid) /* f2 nodeheader  */
750        .long local_label(misc_set_invalid) /* f3 imm  */
751        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
752        .long local_label(misc_set_invalid) /* f5 tra  */
753        .long local_label(misc_set_invalid) /* f6 misc  */
754        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
755        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
756        .long local_label(misc_set_invalid) /* f9 cons  */
757        .long local_label(misc_set_invalid) /* fa nodeheader  */
758        .long local_label(misc_set_invalid) /* fb imm  */
759        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
760        .long local_label(misc_set_invalid) /* fd tra  */
761        .long local_label(misc_set_invalid) /* fe misc  */
762        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
763
764local_label(misc_set_function):
765        /* Functions are funny: the first N words are treated as */
766        /* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
767        __(movzwl misc_data_offset(%temp0),%imm0)
768        __(shl $fixnumshift,%imm0)
769        __(rcmpl(%arg_y,%imm0))
770        __(jae _SPgvset)
771local_label(misc_set_u32):
772        /* Either a non-negative fixnum, a positive one-digit bignum, or */
773        /* a two-digit bignum whose sign-digit is 0 is OK. */
774        __(movl $~(target_most_positive_fixnum <<fixnumshift),%imm0)
775        __(test %arg_z,%imm0)
776        __(movl %arg_z,%imm0)
777        __(jne 1f)
778        __(sarl $fixnumshift,%imm0)
779        __(jmp 9f)
7801:      __(andb $tagmask,%imm0_b)
781        __(cmpb $tag_misc,%imm0_b)
782        __(jne local_label(misc_set_bad))
783        __(movb misc_subtag_offset(%arg_z),%imm0_b)
784        __(cmpb $subtag_bignum,%imm0_b)
785        __(jne local_label(misc_set_bad))
786        __(movl misc_header_offset(%arg_z),%imm0)
787        __(cmpl $two_digit_bignum_header,%imm0)
788        __(je 3f)
789        __(cmpl $one_digit_bignum_header,%imm0)
790        __(jne local_label(misc_set_bad))
791        __(movl misc_data_offset(%arg_z),%imm0)
792        __(testl %imm0,%imm0)
793        __(js local_label(misc_set_bad))
794        __(jmp 9f)
7953:      __(movl misc_data_offset(%arg_z),%imm0)
796        __(cmpl $0,misc_data_offset+4(%arg_z))
797        __(jne local_label(misc_set_bad))
7989:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
799        __(ret)
800local_label(misc_set_s32):
801        __(unbox_fixnum(%arg_z,%imm0))
802        __(testb $fixnummask,%arg_z_b)
803        __(je 9f)
8041:      __(movb %arg_z_b,%imm0_b)
805        __(andb $tagmask,%imm0_b)
806        __(cmpb $tag_misc,%imm0_b)
807        __(jne local_label(misc_set_bad))
808        __(movl misc_header_offset(%arg_z),%imm0)
809        __(cmpl $one_digit_bignum_header,%imm0)
810        __(jne local_label(misc_set_bad))
811        __(movl misc_data_offset(%arg_z),%imm0)
8129:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
813        __(ret)
814local_label(misc_set_bad):
815        __(movl %arg_z,%arg_y)
816        __(movl %temp0,%arg_z)
817        __(push $reserved_frame_marker)
818        __(push $reserved_frame_marker)
819        __(push $XNOTELT)
820        __(set_nargs(3))
821        __(jmp _SPksignalerr)
822local_label(misc_set_single_float_vector):
823        __(extract_lisptag(%arg_z,%imm0))
824        __(cmpb $tag_misc,%imm0_b)
825        __(jne local_label(misc_set_bad))
826        __(movb misc_subtag_offset(%arg_z),%imm0_b)
827        __(cmpb $subtag_single_float,%imm0_b)
828        __(jne local_label(misc_set_bad))
829        __(movl single_float.value(%arg_z),%imm0)
830        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
831        __(ret)
832local_label(misc_set_double_float_vector):
833        __(extract_lisptag(%arg_z,%imm0))
834        __(cmpb $tag_misc,%imm0_b)
835        __(jne local_label(misc_set_bad))
836        __(movb misc_subtag_offset(%arg_z),%imm0_b)
837        __(cmpb $subtag_double_float,%imm0_b)
838        __(jne local_label(misc_set_bad))
839        __(movsd double_float.value(%arg_z),%fp0)
840        __(movsd %fp0,misc_dfloat_offset(%temp0,%arg_y))
841        __(ret)
842local_label(misc_set_fixnum_vector):
843        __(unbox_fixnum(%arg_z,%imm0))
844        __(testb $fixnummask,%arg_z_b)
845        __(jne local_label(misc_set_bad))
846        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
847        __(ret)
848local_label(misc_set_u8):
849        __(testl $~(0xff<<fixnumshift),%arg_z)
850        __(jne local_label(misc_set_bad))
851        __(unbox_fixnum(%arg_y,%imm0))
852        __(movl %arg_z,%arg_y)
853        __(shll $8-fixnumshift,%arg_z)
854        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
855        __(movl %arg_y,%arg_z)
856        __(ret)
857local_label(misc_set_s8):
858        __(movl %arg_z,%imm0)
859        __(shll $32-(8+fixnumshift),%imm0)
860        __(sarl $32-(8+fixnumshift),%imm0)
861        __(cmpl %arg_z,%imm0)
862        __(jne local_label(misc_set_bad))
863        __(testb $fixnummask,%arg_z_b)
864        __(jne local_label(misc_set_bad))
865        __(unbox_fixnum(%arg_y,%imm0))
866        __(movl %arg_z,%arg_z)
867        __(shll $8-fixnumshift,%arg_z)
868        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
869        __(movl %arg_y,%arg_z)
870        __(ret)
871local_label(misc_set_string):
872        __(cmpb $subtag_character,%arg_z_b)
873        __(jne local_label(misc_set_bad))
874        __(movl %arg_z,%imm0)
875        __(shrl $charcode_shift,%imm0)
876        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
877        __(ret)
878local_label(misc_set_u16):
879        __(testl $~(0xffff<<fixnumshift),%arg_z)
880        __(jne local_label(misc_set_bad))
881        __(movl %arg_y,%imm0)
882        __(shrl $1,%imm0)
883        __(movl %arg_z,%arg_y)
884        /* If there's a better way, I'd be glad to hear of it. */
885        __(shll $8-fixnumshift,%arg_z)
886        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
887        __(xorb %arg_z_bh,%arg_z_bh)
888        __(shrl $8,%arg_z)
889        __(movb %arg_z_bh,misc_data_offset+1(%temp0,%imm0))
890        __(movl %arg_y,%arg_z)
891        __(ret)
892local_label(misc_set_s16):
893        __(movl %arg_z,%imm0)
894        __(shll $32-(16+fixnumshift),%imm0)
895        __(sarl $32-(16+fixnumshift),%imm0)
896        __(cmpl %arg_z,%imm0)
897        __(jne local_label(misc_set_bad))
898        __(testb $fixnummask,%arg_z_b)
899        __(jne local_label(misc_set_bad))
900        __(movl %arg_y,%imm0)
901        __(shrl $1,%imm0)
902        __(movl %arg_z,%arg_y)
903        /* If there's a better way, I'd be glad to hear of it. */
904        __(shll $8-fixnumshift,%arg_z)
905        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
906        __(xorb %arg_z_bh,%arg_z_bh)
907        __(sarl $8,%arg_z)
908        __(movb %arg_z_bh,misc_data_offset+1(%temp0,%imm0))
909        __(movl %arg_y,%arg_z)
910        __(ret)
911local_label(misc_set_bit_vector):
912        __(testl $~fixnumone,%arg_z)
913        __(jne local_label(misc_set_bad))
914        __(unbox_fixnum(%arg_y,%imm0))
915        __(testb %arg_z_b,%arg_z_b)
916        __(je local_label(misc_set_clr_bit))
917local_label(misc_set_set_bit):
918        __(btsl %imm0,misc_data_offset(%temp0))
919        __(ret)
920local_label(misc_set_clr_bit):
921        __(btrl %imm0,misc_data_offset(%temp0))
922        __(ret)
923local_label(misc_set_invalid):
924        __(push $reserved_frame_marker)
925        __(push $reserved_frame_marker)
926        __(push $XSETBADVEC)
927        __(push %temp0)
928        __(set_nargs(4))
929        __(jmp _SPksignalerr)
930_endfn(C(misc_set_common))
931
932_spentry(Fret1valn)
933        .globl C(ret1valn)
934__(tra(C(ret1valn)))
935        __(mov (%esp),%ra0)
936        __(mov %arg_z,(%esp))
937        __(set_nargs(1))
938        __(jmp *%ra0)
939_endsubp(Fret1valn)
940
941_spentry(nvalret)
942        .globl C(nvalret)
943C(nvalret):
944        __(ref_global(ret1val_addr,%temp0))
945        __(cmpl lisp_frame.savera0(%ebp),%temp0)
946        __(je 1f)
947        __(test %nargs,%nargs)
948        __(movl $nil_value,%arg_z)
949        __(cmovnel -node_size(%esp,%nargs),%arg_z)
950        __(leave)
951        __(ret)
952
953/* actually need to return values; always need to copy. */
9541:      __(lea 2*node_size(%ebp),%imm0)
955        __(pushl (%imm0))
956        __(movl 0(%ebp),%ebp)
957        __(addl $node_size,%imm0)
958        __(lea node_size(%esp,%nargs),%temp0)
959        __(xorl %arg_y,%arg_y)
960        __(jmp 3f)
9612:      __(movl -node_size(%temp0),%arg_z)
962        __(subl $node_size,%temp0)
963        __(addl $node_size,%arg_y)
964        __(movl %arg_z,-node_size(%imm0))
965        __(subl $node_size,%imm0)
9663:      __(cmpl %arg_y,%nargs)
967        __(jne 2b)
968        __(pop %ra0)
969        __(movl %imm0,%esp)
970        __(jmp *%ra0)
971_endsubp(nvalret)
972
973_spentry(jmpsym)
974        __(jump_fname())
975_endsubp(jmpsym)
976
977_spentry(jmpnfn)
978        __(mov %temp0,%fn)
979        __(jmp *%fn)
980_endsubp(jmpnfn)
981
982_spentry(funcall)
983        __(do_funcall())
984_endsubp(funcall)
985
986/* Make a lisp integer (fixnum or one-digit bignum) from the value in %imm0 */
987_spentry(makes32)
988        __(imull $fixnumone,%imm0,%arg_z)       /* result is fixnum-tagged */
989        __(jno 0f)                              /* but may have overflowed */
990        __(movd %imm0,%mm1)
991        __(movl $one_digit_bignum_header,%imm0)
992        __(movd %imm0,%mm0)
993        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
994        __(movd %mm1,misc_data_offset(%arg_z))
9950:      __(repret)
996_endsubp(makes32)
997
998_spentry(makes64)
999        __(int $3)
1000        __(jmp _SPmakes32)
1001_endsubp(makes64)
1002
1003/* xxx make lisp integer out of mm0? */
1004/* Make a lisp integer (probably a bignum) out of the %edx:%eax pair. */
1005/* We assume that the node_regs_mask in the TCR has been set to mark */
1006/* %edx an immediate register. */
1007_startfn(C(makes64))
1008        __(movd %eax,%mm1)
1009        __(sarl $31,%eax)
1010        __(cmpl %eax,%edx)      /* upper bits just sign extension? */
1011        __(movd %mm1,%eax)
1012        __(jne 1f)      /* no, make a bignum */
1013        __(mark_as_node(%edx))
1014        __(jmp _SPmakes32)
10151:      __(movl $two_digit_bignum_header,%eax)
1016        __(movd %eax,%mm0)
1017        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
1018        __(movd %mm1,misc_data_offset(%arg_z))
1019        __(movl %edx,misc_data_offset+4(%arg_z))
1020        __(mark_as_node(%edx))
1021        __(ret)
1022_endfn
1023
1024
1025_spentry(syscall)
1026        __(int $3)
1027        /* Save lisp registers */
1028        __(push %ebp)
1029        __(movl %esp,%ebp)
1030        __(push %temp0)
1031        __(push %temp1)
1032        __(push %arg_y)
1033        __(push %arg_z)
1034        __(push %fn)
1035        __(movl %esp,%rcontext:tcr.save_vsp)
1036        __(movl %ebp,%rcontext:tcr.save_ebp)
1037        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
1038        __(movl %rcontext:tcr.foreign_sp,%esp)
1039        __(emms)
1040        __(pop %ebp)            /* backlink */
1041        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1042        __(pushl $local_label(back_from_syscall))
1043        __(int $0x80)
1044local_label(back_from_syscall):
1045        __(jnc 0f)
1046        __(neg %eax)
10470:     
1048        __(movl %ebp,%esp)
1049        __(movl %esp,%rcontext:tcr.foreign_sp)
1050        __(zero_node_regs)
1051        __(pxor %fpzero,%fpzero)
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        __(push %temp0)
1061        __(leave)
1062        __(ret)
1063_endsubp(syscall)
1064
1065_spentry(mkcatch1v)
1066        __(nMake_Catch(0))
1067        __(ret)
1068_endsubp(mkcatch1v)
1069
1070_spentry(mkunwind)
1071        __(int $3)
1072_endsubp(mkunwind)
1073
1074/* this takes a return address in %ra0; it's "new" in that it does the */
1075/*   double binding of *interrupt-level* out-of-line */
1076_spentry(nmkunwind)
1077        __(movl %rcontext:tcr.tlb_pointer,%arg_z)
1078        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_z),%arg_y)
1079        __(push %arg_y)
1080        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
1081        __(push %rcontext:tcr.db_link)
1082        __(movl %esp,%rcontext:tcr.db_link)
1083        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_z))
1084        __(movl $undefined,%arg_z)
1085        /* %arg_z = tag, %xfn (%temp1) = pc */
1086        __(Make_Catch(fixnumone))
1087        __(movl %arg_y,%arg_z)
1088        __(jmp _SPbind_interrupt_level)
1089_endsubp(nmkunwind)
1090
1091_spentry(mkcatchmv)
1092        __(int $3)
1093_endsubp(mkcatchmv)
1094
1095_spentry(throw)
1096        __(int $3)
1097_endsubp(throw)
1098
1099        /* This takes N multiple values atop the vstack.   */
1100_spentry(nthrowvalues)
1101        __(movb $1,%rcontext:tcr.unwinding)
1102        __(movl %ra0,%rcontext:tcr.save0) /* %ra0 (aka %temp0) to spill area */
1103local_label(_nthrowv_nextframe):
1104        __(subl $fixnumone,%imm0)
1105        __(js local_label(_nthrowv_done))
1106        __(movd %imm0,%mm1)
1107        __(movl %rcontext:tcr.catch_top,%temp0)
1108        __(movl catch_frame.link(%temp0),%imm0)
1109        __(movl %imm0,%rcontext:tcr.catch_top)
1110        __(movl catch_frame.db_link(%temp0),%imm0)
1111        __(cmpl %imm0,%rcontext:tcr.db_link)
1112        __(jz local_label(_nthrowv_dont_unbind))
1113        __(push %temp1)
1114        __(push %temp0)
1115        __(push $local_label(_nthrowv_back_from_unbind))
1116        __(jmp _SPunbind_to)
1117__(tra(local_label(_nthrowv_back_from_unbind)))
1118        __(pop %temp0)
1119        __(pop %temp1)
1120local_label(_nthrowv_dont_unbind):
1121        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1122        __(je local_label(_nthrowv_do_unwind))
1123/* A catch frame.  If the last one, restore context from there.   */
1124        __(movd %mm1,%imm0)
1125        __(test %imm0,%imm0)    /* last catch frame ?   */
1126        __(jne local_label(_nthrowv_skip))
1127        __(movl catch_frame.xframe(%temp0),%arg_y)
1128        __(movl %arg_y,%rcontext:tcr.xframe)
1129        __(lea (%esp,%nargs),%arg_y)
1130        __(movl catch_frame.esp(%temp0),%arg_z)
1131        __(movd %nargs,%mm2)
1132        __(jmp local_label(_nthrowv_push_test))
1133local_label(_nthrowv_push_loop):
1134        __(subl $node_size,%arg_y)
1135        __(subl $node_size,%arg_z)
1136        __(movd (%arg_y),%mm0)
1137        __(movd %mm0,(%arg_z))
1138local_label(_nthrowv_push_test):
1139        __(subl $node_size,%nargs)
1140        __(jns local_label(_nthrowv_push_loop))
1141        __(movd %mm2,%nargs)
1142        __(movl catch_frame.xframe(%temp0),%arg_y)
1143        __(movl %arg_y,%rcontext:tcr.xframe)
1144        __(movl %arg_z,%esp)
1145        __(movl catch_frame.ebp(%temp0),%ebp)
1146        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1147        __(movd %stack_temp,%rcontext:tcr.foreign_sp)       
1148local_label(_nthrowv_skip):     
1149        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1150        __(movl %imm0,%rcontext:tcr.save_tsp)
1151        __(movl %imm0,%rcontext:tcr.next_tsp)
1152        __(movd %mm1,%imm0)
1153        __(jmp local_label(_nthrowv_nextframe))
1154local_label(_nthrowv_do_unwind):       
1155/* This is harder.  Call the cleanup code with the multiple values and   */
1156/* nargs, the throw count, and the caller's return address in a temp  */
1157/* stack frame.   */
1158        __(leal (%esp,%nargs),%arg_y)
1159        __(push catch_frame.pc(%temp0))
1160        __(movl catch_frame.ebp(%temp0),%ebp)
1161        __(movd catch_frame.xframe(%temp0),%stack_temp)
1162        __(movd %stack_temp,%rcontext:tcr.xframe)
1163        __(movl catch_frame.esp(%temp0),%arg_z)
1164        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
1165        __(movd %stack_temp,%rcontext:tcr.foreign_sp)       
1166        /* Discard the catch frame, so we can build a temp frame   */
1167        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
1168        __(movl %imm0,%rcontext:tcr.save_tsp)
1169        __(movl %imm0,%rcontext:tcr.next_tsp)
1170        /* tsp overhead, nargs, throw count, ra0   */
1171        __(dnode_align(%nargs,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1172        __(movl %imm0,%temp1)
1173        __(TSP_Alloc_Var(%temp1,%imm0))
1174        __(movd %mm2,%temp1) /* aka %nargs */
1175
1176        __(movl %nargs,(%imm0))
1177        __(movl %rcontext:tcr.save0,%ra0)
1178        __(movl %ra0,node_size(%imm0))
1179        __(movd %mm1,node_size*2(%imm0))
1180        __(leal node_size*3(%imm0),%imm0)
1181        __(jmp local_label(_nthrowv_tpushtest))
1182local_label(_nthrowv_tpushloop):
1183        __(movl -node_size(%arg_y),%temp0)
1184        __(subl $node_size,%arg_y)
1185        __(movl %temp0,(%imm0))
1186        __(addl $node_size,%imm0)
1187local_label(_nthrowv_tpushtest):
1188        __(subl $node_size,%nargs)
1189        __(jns local_label(_nthrowv_tpushloop))
1190        __(pop %xfn)    /* aka %temp1/%nargs */
1191        __(movl %arg_z,%esp)
1192/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1193        __(push $local_label(_nthrowv_called_cleanup))
1194        __(movb $0,%rcontext:tcr.unwinding)
1195        __(jmp *%xfn)
1196__(tra(local_label(_nthrowv_called_cleanup)))
1197
1198        __(movb $1,%rcontext:tcr.unwinding)
1199        __(movl %rcontext:tcr.save_tsp,%imm0)
1200        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%nargs)
1201        __(movl tsp_frame.data_offset+(1*node_size)(%imm0),%ra0)
1202        __(movl %ra0,%rcontext:tcr.save0)
1203        __(movd tsp_frame.data_offset+(2*node_size)(%imm0),%mm1)
1204        __(movd %nargs,%mm2)
1205        __(addl $tsp_frame.fixed_overhead+(node_size*3),%imm0)
1206        __(jmp local_label(_nthrowv_tpoptest))
1207local_label(_nthrowv_tpoploop): 
1208        __(push (%imm0))
1209        __(addl $node_size,%imm0)
1210local_label(_nthrowv_tpoptest): 
1211        __(subl $node_size,%nargs)
1212        __(jns local_label(_nthrowv_tpoploop))
1213        __(movd %mm2,%nargs)
1214        __(movl %rcontext:tcr.save_tsp,%imm0)
1215        __(movl (%imm0),%imm0)
1216        __(movl %imm0,%rcontext:tcr.save_tsp)
1217        __(movl %imm0,%rcontext:tcr.next_tsp)
1218        __(movd %mm1,%imm0)
1219        __(jmp local_label(_nthrowv_nextframe))
1220local_label(_nthrowv_done):
1221        __(movb $0,%rcontext:tcr.unwinding)
1222        __(check_pending_interrupt(%imm0))
1223local_label(_nthrowv_return):
1224        __(movl %rcontext:tcr.save0,%ra0)
1225        __(movss %fpzero,%rcontext:tcr.save0)
1226        __(jmp *%ra0)   
1227_endsubp(nthrowvalues)
1228
1229/* This is a (slight) optimization.  When running an unwind-protect,  */
1230/* save the single value and the throw count in the tstack frame.  */
1231/* Note that this takes a single value in arg_z.  */
1232
1233_spentry(nthrow1value)
1234        __(movb $1,%rcontext:tcr.unwinding)
1235local_label(_nthrow1v_nextframe):
1236        __(subl $fixnumone,%imm0)
1237        __(js local_label(_nthrow1v_done))
1238        __(movd %imm0,%mm0)
1239        __(movl %rcontext:tcr.catch_top,%temp1)
1240        __(movl catch_frame.link(%temp1),%imm0)
1241        __(movl %imm0,%rcontext:tcr.catch_top)
1242        __(movl catch_frame.db_link(%temp1),%imm0)
1243        __(cmpl %imm0,%rcontext:tcr.db_link)
1244        __(jz local_label(_nthrow1v_dont_unbind))
1245        __(push %temp1)
1246        __(push %temp0)
1247        __(push %arg_z)
1248        __(push [$]local_label(_nthrow1v_back_from_unbind))
1249        __(jmp _SPunbind_to)
1250__(tra(local_label(_nthrow1v_back_from_unbind)))
1251        __(pop %arg_z)
1252        __(pop %temp0)
1253        __(pop %temp1)
1254local_label(_nthrow1v_dont_unbind):
1255        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp1))
1256        __(je local_label(_nthrow1v_do_unwind))
1257/* A catch frame.  If the last one, restore context from there. */
1258        __(movd %mm0,%imm0)
1259        __(test %imm0,%imm0)    /* last catch frame? */
1260        __(jne local_label(_nthrow1v_skip))
1261        __(movl catch_frame.xframe(%temp1),%arg_y)
1262        __(movl %arg_y,%rcontext:tcr.xframe)
1263        __(movl catch_frame.esp(%temp1),%esp)
1264        __(movl catch_frame.ebp(%temp1),%ebp)
1265        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1266        __(movd %stack_temp,%rcontext:tcr.foreign_sp)
1267local_label(_nthrow1v_skip):
1268        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1269        __(movl %imm0,%rcontext:tcr.save_tsp)
1270        __(movl %imm0,%rcontext:tcr.next_tsp)
1271        __(movd %mm0,%imm0)
1272        __(jmp local_label(_nthrow1v_nextframe))
1273local_label(_nthrow1v_do_unwind):
1274/* This is harder, but not as hard (not as much BLTing) as the */
1275/* multiple-value case. */
1276        __(movl catch_frame.xframe(%temp1),%arg_y)
1277        __(movl %arg_y,%rcontext:tcr.xframe)
1278        __(movl catch_frame.ebp(%temp1),%ebp)
1279        __(movl catch_frame.esp(%temp1),%esp)
1280        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
1281        __(movd %stack_temp,%rcontext:tcr.foreign_sp)
1282        /* Discard the catch frame so we can build a temp frame. */
1283        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
1284        __(movl %imm0,%rcontext:tcr.save_tsp)
1285        __(movl %imm0,%rcontext:tcr.next_tsp)
1286        __(movl catch_frame.pc(%temp1),%xfn) /* xfn is temp1 */
1287        __(TSP_Alloc_Fixed((3*node_size),%imm0))
1288        __(addl $tsp_frame.fixed_overhead,%imm0)
1289        __(movl %ra0,(%imm0))
1290        __(movd %mm0,node_size*1(%imm0))
1291        __(movl %arg_z,node_size*2(%imm0))
1292/* Ready to call cleanup code.  Set up tra, jmp to %xfn. */
1293        __(push $local_label(_nthrow1v_called_cleanup))
1294        __(movb $0,%rcontext:tcr.unwinding)
1295        __(jmp *%xfn)
1296__(tra(local_label(_nthrow1v_called_cleanup)))
1297        __(movb $1,%rcontext:tcr.unwinding)
1298        __(movl %rcontext:tcr.save_tsp,%imm0)
1299        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%ra0)
1300        __(movd tsp_frame.data_offset+(1*node_size)(%imm0),%mm0)
1301        __(movl tsp_frame.data_offset+(2*node_size)(%imm0),%arg_z)
1302        __(movl (%imm0),%imm0)
1303        __(movl %imm0,%rcontext:tcr.save_tsp)
1304        __(movl %imm0,%rcontext:tcr.next_tsp)
1305        __(movd %mm0,%imm0)
1306        __(jmp local_label(_nthrow1v_nextframe))
1307local_label(_nthrow1v_done):
1308        __(movb $0,%rcontext:tcr.unwinding)
1309        __(check_pending_interrupt(%imm0))
1310local_label(_nthrow1v_return):
1311        __(jmp *%ra0)
1312_endsubp(nthrow1value)
1313
1314/* This never affects the symbol's vcell   */
1315/* Non-null symbol in arg_y, new value in arg_z           */
1316
1317_spentry(bind)
1318        __(int $3)
1319_endsubp(bind)
1320
1321/* arg_z = symbol: bind it to its current value  */
1322
1323_spentry(bind_self)
1324        __(int $3)
1325_endsubp(bind_self)
1326
1327_spentry(bind_nil)
1328        __(int $3)
1329_endsubp(bind_nil)
1330
1331_spentry(bind_self_boundp_check)
1332        __(int $3)
1333_endsubp(bind_self_boundp_check)
1334
1335_spentry(conslist)
1336        __(int $3)
1337_endsubp(conslist)
1338
1339/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1340/* Cons, one cons cell at at time.  Maybe optimize this later.  */
1341
1342_spentry(conslist_star)
1343        __(int $3)
1344_endsubp(conslist_star)
1345
1346/* We always have to create a tsp frame (even if nargs is 0), so the compiler   */
1347/* doesn't get confused.   */
1348_spentry(stkconslist)
1349        __(int $3)
1350_endsubp(stkconslist)
1351
1352/* do list*: last arg in arg_z, all others vpushed,   */
1353/*      nargs set to #args vpushed.  */
1354
1355_spentry(stkconslist_star)
1356        __(int $3)
1357_endsubp(stkconslist_star)
1358
1359
1360/* Make a stack-consed simple-vector out of the NARGS objects   */
1361/*      on top of the vstack; return it in arg_z.  */
1362
1363_spentry(mkstackv)
1364        __(int $3)
1365_endsubp(mkstackv)
1366
1367        .globl C(egc_write_barrier_start)
1368C(egc_write_barrier_start):
1369/*  */
1370/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1371/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1372/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1373/* an intergenerational reference (a young pointer stored in an old object) has  */
1374/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1375/* This has to happen atomically, and has to happen atomically wrt GC.  */
1376
1377/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1378/* interlocked loads and stores.  */
1379
1380/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1381/* in the function, we can do the store (even if it's already been done) and  */
1382/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1383/* setting the bit needs to be done atomically, unless we're sure that other  */
1384/* threads are suspended.)  */
1385/* We can unconditionally set the suspended thread's RIP to the return address.  */
1386
1387_spentry(rplaca)
1388        .globl C(egc_rplaca)
1389C(egc_rplaca):
1390        __(rcmpl(%arg_z,%arg_y))
1391        __(_rplaca(%arg_y,%arg_z))
1392        __(ja 1f)
13930:      __(repret)
13941:      __(movl %arg_y,%imm0)
1395        __(subl lisp_global(heap_start),%imm0)
1396        __(shrl $dnode_shift,%imm0)
1397        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1398        __(jae 0b)
1399        __(andl $~(1<<bitmap_shift-1),%temp0)
1400        __(shrl $bitmap_shift-fixnumshift,%temp0)
1401        __(andl $31,%imm0)
1402        __(addl lisp_global(refbits),%temp0)
1403        __(xorb $31,%imm0_b)
1404        __(lock)
1405        __(btsl %imm0,(%temp0))
1406        __(ret)
1407_endsubp(rplaca)
1408
1409_spentry(rplacd)
1410        .globl C(egc_rplacd)
1411C(egc_rplacd):
1412        __(rcmpl(%arg_z,%arg_y))
1413        __(_rplacd(%arg_y,%arg_z))
1414        __(ja 1f)
14150:      __(repret)
14161:      __(movl %arg_y,%imm0)
1417        __(subl lisp_global(heap_start),%imm0)
1418        __(shrl $dnode_shift,%imm0)
1419        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1420        __(jae 0b)
1421        __(andl $~(1<<bitmap_shift-1),%temp0)
1422        __(shrl $bitmap_shift-fixnumshift,%temp0)
1423        __(andl $31,%imm0)
1424        __(addl lisp_global(refbits),%temp0)
1425        __(xorb $31,%imm0_b)
1426        __(lock)
1427        __(btsl %imm0,(%temp0))
1428        __(ret)
1429_endsubp(rplacd)
1430
1431/* Storing into a gvector can be handles the same way as storing into a CONS. */
1432/* args (src, unscaled-idx, val) in temp0, arg_y, arg_z */
1433_spentry(gvset)
1434        .globl C(egc_gvset)
1435C(egc_gvset):
1436        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1437        __(rcmpl(%arg_z,%temp0))
1438        __(ja 1f)
14390:      __(repret)
14401:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1441        __(subl lisp_global(heap_start),%imm0)
1442        __(shrl $dnode_shift,%imm0)
1443        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1444        __(jae 0b)
1445        __(andl $~(1<<bitmap_shift-1),%temp0)
1446        __(shrl $bitmap_shift-fixnumshift,%temp0)
1447        __(andl $31,%imm0)
1448        __(addl lisp_global(refbits),%temp0)
1449        __(xorb $31,%imm0_b)
1450        __(lock)
1451        __(btsl %imm0,(%temp0))
1452        __(ret)
1453_endsubp(gvset)
1454
1455/* This is a special case of storing into a gvector: if we need to  */
1456/* memoize the store, record the address of the hash-table vector  */
1457/* in the refmap, as well.  */
1458
1459_spentry(set_hash_key)
1460        .globl C(egc_set_hash_key)
1461C(egc_set_hash_key):
1462        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1463        __(rcmpl(%arg_z,%temp0))
1464        __(ja 1f)
14650:      __(repret)
14661:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1467        __(subl lisp_global(heap_start),%imm0)
1468        __(shrl $dnode_shift,%imm0)
1469        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1470        __(jae 0b)
1471        __(push %temp0)
1472        __(andl $~(1<<bitmap_shift-1),%temp0)
1473        __(shrl $bitmap_shift-fixnumshift,%temp0)
1474        __(andl $31,%imm0)
1475        __(addl lisp_global(refbits),%temp0)
1476        __(xorb $31,%imm0_b)
1477        __(lock)
1478        __(btsl %imm0,(%temp0))
1479        /* Now memoize the address of the hash vector */
1480        __(pop %imm0)
1481        __(subl lisp_global(heap_start),%imm0)
1482        __(shrl $dnode_shift,%imm0)
1483        __(andl $~(1<<bitmap_shift-1),%temp0)
1484        __(shrl $bitmap_shift-fixnumshift,%temp0)
1485        __(andl $31,%imm0)
1486        __(addl lisp_global(refbits),%temp0)
1487        __(xorb $31,%imm0_b)
1488        __(lock)
1489        __(btsl %imm0,(%temp0))
1490        __(ret)
1491_endsubp(set_hash_key)
1492
1493/* This is a little trickier: if this is interrupted, we need to know  */
1494/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
1495/* If we're interrupted   before the PC has reached the "success_test" label, */
1496/* repeat (luser the PC back to .SPstore_node_conditional.)  If we're at that */
1497/* label with the Z flag set, we won and (may) need to memoize.  */
1498
1499/* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1500_spentry(store_node_conditional)
1501        .globl C(egc_store_node_conditional)
1502C(egc_store_node_conditional):
1503        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1504        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
15050:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
1506        __(movl misc_data_offset(%temp1,%temp0),%imm0)
1507        __(jne 3f)
1508        __(lock)
1509        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1510        .globl C(egc_store_node_conditional_success_test)
1511C(egc_store_node_conditional_success_test):
1512        __(jne 0b)
1513        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1514        __(subl lisp_global(heap_start),%imm0)
1515        __(shrl $dnode_shift,%imm0)
1516        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1517        __(jae 2f)
1518        __(andl $~(1<<bitmap_shift-1),%temp0)
1519        __(shrl $bitmap_shift-fixnumshift,%temp0)
1520        __(andl $31,%imm0)
1521        __(addl lisp_global(refbits),%temp0)
1522        __(xorb $31,%imm0_b)
1523        __(lock)
1524        __(btsl %imm0,(%temp0))
1525        .globl C(egc_write_barrier_end)
1526C(egc_write_barrier_end):
15272:      __(movl $t_value,%arg_z)
1528        __(ret)
15293:      __(movl $nil_value,%arg_z)
1530        __(ret)
1531_endsubp(store_node_conditional)
1532
1533_spentry(setqsym)
1534        __(bt $sym_vbit_const,symbol.flags(%arg_y))
1535        __(jae _SPspecset)
1536        __(mov %arg_y,%arg_z)
1537        __(mov $XCONST,%arg_y)
1538        __(set_nargs(2))
1539        __(jmp _SPksignalerr)
1540_endsubp(setqsym)
1541
1542_spentry(progvsave)
1543        __(int $3)
1544_endsubp(progvsave)
1545
1546/* Allocate node objects on the temp stack, immediate objects on the foreign  */
1547/* stack. (The caller has to know which stack to discard a frame from.)  */
1548/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
1549
1550_spentry(stack_misc_alloc)
1551        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
1552        __(jne local_label(stack_misc_alloc_not_u24))
1553        __(unbox_fixnum(%arg_z,%imm0))
1554        __(mov %arg_y,%temp0)
1555        __(shl $num_subtag_bits-fixnumshift,%temp0)
1556        __(or %temp0,%imm0)     /* %imm0 now = header */
1557        __(movd %imm0,%mm0)     /* cache header in %mm0 */
1558        __(andb $fulltagmask,%imm0_b)
1559        __(cmpb $fulltag_nodeheader,%imm0_b)
1560        __(je local_label(stack_misc_alloc_node))
1561        __(movd %mm0,%imm0)
1562        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
1563        __(jbe local_label(stack_misc_alloc_32))
1564        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
1565        __(jbe local_label(stack_misc_alloc_8))
1566        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
1567        __(jbe local_label(stack_misc_alloc_16))
1568        __(cmpb $subtag_double_float_vector,%imm0_b)
1569        __(jne local_label(stack_misc_alloc_1))
1570        /* double-float vector case */
1571        __(imul $2,%arg_y,%imm0)
1572        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1573local_label(stack_misc_alloc_1):
1574        __(unbox_fixnum(%arg_y,%imm0))
1575        __(addl $7,%imm0)
1576        __(shrl $3,%imm0)
1577        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1578local_label(stack_misc_alloc_8):
1579        __(unbox_fixnum(%arg_y,%imm0))
1580        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1581local_label(stack_misc_alloc_16):
1582        __(unbox_fixnum(%arg_y,%imm0))
1583        __(shl $1,%imm0)
1584        __(jmp local_label(stack_misc_alloc_alloc_ivector))
1585local_label(stack_misc_alloc_32):
1586        __(mov %arg_y,%imm0)
1587local_label(stack_misc_alloc_alloc_ivector):
1588        /* byte count in %imm0 */
1589        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1590        __(cmpl $tstack_alloc_limit,%imm0)
1591        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
1592        __(movd %rcontext:tcr.foreign_sp,%stack_temp)
1593        __(movd %stack_temp,%temp1)
1594        __(subl %imm0,%rcontext:tcr.foreign_sp)
1595        __(movl %rcontext:tcr.foreign_sp,%temp0)
15960:      __(movsd %fpzero,-dnode_size(%temp1))
1597        __(subl $dnode_size,%temp1)
1598        __(cmpl %temp1,%temp0)
1599        __(jnz 0b)
1600        __(movd %stack_temp,(%temp0))
1601        __(movd %mm0,tsp_frame.fixed_overhead(%temp0))
1602        __(lea tsp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
1603        __(ret)
1604local_label(stack_misc_alloc_heap_alloc_ivector):
1605        __(movd %rcontext:tcr.foreign_sp,%stack_temp)
1606        __(subl $dnode_size,%rcontext:tcr.foreign_sp)
1607        __(movl %rcontext:tcr.foreign_sp,%imm0)
1608        __(movd %stack_temp,(%imm0))
1609        __(jmp _SPmisc_alloc)
1610local_label(stack_misc_alloc_node):
1611        __(movl %arg_y,%imm0)
1612        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
1613        __(cmpl $tstack_alloc_limit,%imm0)
1614        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
1615        __(TSP_Alloc_Var(%imm0,%temp1))
1616        __(movd %mm0,(%temp1))
1617        __(leal fulltag_misc(%temp1),%arg_z)
1618        __(ret)
1619local_label(stack_misc_alloc_heap_alloc_gvector):
1620        __(TSP_Alloc_Fixed(0,%imm0))
1621        __(jmp _SPmisc_alloc)
1622
1623local_label(stack_misc_alloc_not_u24):
1624        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
1625_endsubp(stack_misc_alloc)
1626
1627/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of */
1628/* initial-contents.  Note that this can be used to cons any type of */
1629/* initialized node-header'ed misc object (symbols, closures, ...) */
1630/* as well as vector-like objects. */
1631_spentry(gvector)
1632        __(subl $node_size,%nargs)      /* off by one in x862-%gvector */
1633        __(movl (%esp,%nargs),%imm0)    /* boxed subtype */
1634        __(sarl $fixnumshift,%imm0)
1635        __(movl %nargs,%arg_z)
1636        __(shll $num_subtag_bits-word_shift,%arg_z)
1637        __(orl %arg_z,%imm0)
1638        __(movd %imm0,%mm0)
1639        __(dnode_align(%nargs,node_size,%imm0))
1640        __(push %ra0)   /* aka %temp0, can't be live while consing */
1641        __(Misc_Alloc(%arg_z))
1642        __(pop %ra0)
1643        __(movl %nargs,%imm0)
1644        __(jmp 2f)
16451:      __(movl %arg_y,misc_data_offset(%arg_z,%imm0))
16462:      __(subl $node_size,%imm0)
1647        __(pop %arg_y)  /* Note the intentional fencepost: */
1648                        /* discard the subtype as well. */
1649        __(jge 1b)
1650        __(jmp *%ra0)
1651_endsubp(gvector)
1652
1653_spentry(mvpass)
1654        __(int $3)
1655_endsubp(mvpass)
1656
1657_spentry(nthvalue)
1658        __(int $3)
1659_endsubp(nthvalue)
1660
1661_spentry(values)
1662        __(int $3)
1663_endsubp(values)
1664
1665_spentry(default_optional_args)
1666        __(int $3)
1667_endsubp(default_optional_args)
1668
1669_spentry(opt_supplied_p)
1670        __(int $3)
1671_endsubp(opt_supplied_p)
1672
1673_spentry(lexpr_entry)
1674        __(int $3)
1675_endsubp(lexpr_entry)
1676
1677_spentry(heap_rest_arg)
1678        __(int $3)
1679_endsubp(heap_rest_arg)
1680
1681/* %imm0 contains the number of fixed args ; make an &rest arg out of the others   */
1682_spentry(req_heap_rest_arg)
1683        __(int $3)
1684_endsubp(req_heap_rest_arg)
1685
1686/* %imm0 bytes of stuff has already been pushed   */
1687/* make an &rest arg out of any others   */
1688_spentry(heap_cons_rest_arg)
1689        __(int $3)
1690_endsubp(heap_cons_rest_arg)
1691
1692_spentry(simple_keywords)
1693        __(xor %imm0,%imm0)
1694        __(push_argregs())
1695        __(jmp _SPkeyword_bind)
1696_endsubp(simple_keywords)
1697
1698_spentry(keyword_args)
1699        __(push_argregs())
1700        __(jmp _SPkeyword_bind)
1701_endsubp(keyword_args)
1702
1703/* There are %nargs words of arguments on the stack; %imm0 contains the */
1704/* number of non-keyword args pushed.  It's possible that we never actually */
1705/* got any keyword args, which would make things much simpler. */
1706
1707/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
1708/* indicating whether &allow-other-keys and/or &rest was present in the */
1709/* lambda list.  We therefore need to access %nargs as a 16-bit register. */
1710
1711/* Once we get here, we can use the arg registers. */
1712
1713/* N.B.: %ra0 is %temp0, and must not be clobbered. */
1714
1715define([keyword_flags_aok_bit],[16])
1716define([keyword_flags_unknown_keys_bit],[17])
1717define([keyword_flags_rest_bit],[18])
1718define([keyword_flags_seen_aok_bit],[19])
1719
1720_spentry(keyword_bind)
1721        __(movzwl %nargs_w,%arg_z)
1722        __(subl %imm0,%arg_z)
1723        __(jbe local_label(no_keyword_values))
1724        __(btl $word_shift,%arg_z)
1725        __(jnc local_label(even))
1726        __(movl $nil_value,%arg_y)
1727        __(movw %arg_z_w,%nargs_w)
1728        __(testw %nargs_w,%nargs_w)
1729        __(jmp 1f)
17300:      __(pop %arg_z)
1731        __(push %ra0) /* aka temp0; temp0 can't be live while consing. */
1732        __(Cons(%arg_z,%arg_y,%arg_y))
1733        __(pop %ra0)  /* the push/pop in a loop is disgusting. */
1734        __(subw $node_size,%nargs_w)
17351:      __(jnz 0b)
1736        __(movl %arg_y,%arg_z)
1737        __(movl $XBADKEYS,%arg_y)
1738        __(set_nargs(2))
1739        __(jmp _SPksignalerr)
1740
1741        /* Now that we're sure that we have an even number of */
1742        /* keywords and values (in %arg_z), move the pairs over */
1743        /* to the temp stack. */
1744local_label(even):
1745        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
1746        __(TSP_Alloc_Var(%arg_y,%imm0))
17472:      __(subl $node_size,%arg_y)
1748        __(pop (%arg_y))
1749        __(cmpl %arg_y,%imm0)
1750        __(jne 2b)
1751
1752        /* Get the keyword vector into %arg_y, and its length into %imm0. */
1753        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
1754        /* for each declared keyword. */
1755        __(movzwl misc_data_offset(%fn),%imm0)
1756        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
1757        __(vector_length(%arg_y,%imm0))
1758        __(jmp 4f)
17593:      __(push $nil_value)
1760        __(push $nil_value)
17614:      __(subl $fixnumone,%imm0)
1762        __(jge 3b)
1763
1764        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
1765        /* in order to get a couple more registers to work with. */
1766        __(push %ra0)
1767        __(push %nargs)
1768
1769        /* At this point we have: */
1770        /* number of supplied keywords and values in %arg_z */
1771        /* keyword vector in %arg_y */
1772        __(vector_length(%arg_y,%imm0))
1773        __(push %imm0)          /* count of declared keywords */
1774        __(push %arg_z)         /* count of supplied keys and values */
1775
1776        /* For each declared keyword, iterate over the supplied k/v pairs */
1777        /* to see if it's supplied and what the value is. */
1778        /* checking to see if any */
1779        /* key-value pairs were unexpectedly supplied. */
1780
1781        __(movl %rcontext:tcr.save_tsp,%temp0)
1782        __(addl $2*node_size,%temp0) /* skip frame overhead */
1783        /* %temp0: top of tstack (skipping frame overhead) */
1784        __(lea 4*node_size(%esp,%imm0,2),%temp1)
1785        /* %temp1: word above 0th value/supplied-p pair on vstack */
1786        /* %arg_y: keyword vector */
1787        __(xorl %imm0,%imm0)
1788        /* %imm0: index */
1789        /* %arg_z: temporary */
1790
1791        /* Iterate over supplied k/v pairs on tstack.  See if key is */
1792        /* in the keyword vector.  Copy value and set supplied-p on */
1793        /* vstack if found. */
1794
1795local_label(tstack_loop):
1796        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
1797        __(push %imm0)
1798        __(xorl %imm0,%imm0)
1799        __(cmpl $nrs.kallowotherkeys,%arg_z)
1800        __(jne local_label(next_keyvect_entry))
1801        __(btsl $keyword_flags_seen_aok_bit,12(%esp))
1802        __(jc local_label(next_keyvect_entry))
1803        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
1804        __(je local_label(next_keyvect_entry))
1805        __(btsl $keyword_flags_aok_bit,12(%esp))
1806        __(jmp local_label(next_keyvect_entry))
1807        /* loop through keyword vector */
18086:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
1809        __(jne 7f)
1810        /* Got a match; have we already seen this keyword? */
1811        __(negl %imm0)
1812        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
1813        __(jne 9f)      /* seen it, ignore this value */
1814        __(movl (%esp),%arg_z)
1815        __(lea (%temp0,%arg_z,2),%arg_z)
1816        __(movl node_size(%arg_z),%arg_z) /* value for this key */
1817        __(movl %arg_z,-node_size(%temp1,%imm0,2))
1818        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
1819        __(jmp 9f)
18207:      __(addl $node_size,%imm0)
1821local_label(next_keyvect_entry):
1822        __(cmpl %imm0,8(%esp))
1823        __(jne 6b)
1824        /* Didn't match anything in the keyword vector.  Is the keyword */
1825        /* :allow-other-keys? */
1826        __(cmpl $nrs.kallowotherkeys,%arg_z)
1827        __(je 9f)       /* :allow-other-keys is never "unknown" */
18288:      __(btsl $keyword_flags_unknown_keys_bit,12(%esp))
18299:      __(pop %imm0)
1830        __(addl $fixnumone,%imm0)
1831        __(movl %imm0,%arg_z)
1832        __(shll $1,%arg_z)      /* pairs of tstack words */
1833        __(cmpl %arg_z,0(%esp))
1834        __(jne local_label(tstack_loop))
1835
1836        __(pop %imm0)   /* count of supplied keys and values */
1837        __(addl $node_size,%esp)
1838        __(pop %nargs)
1839        __(pop %ra0)
1840
1841        /* If the function takes an &rest arg, or if we got an unrecognized */
1842        /* keyword and don't allow that, copy the incoming k/v pairs from */
1843        /* the temp stack back to the value stack. */
1844        __(btl $keyword_flags_rest_bit,%temp1)
1845        __(jc 1f)
1846        __(btl $keyword_flags_unknown_keys_bit,%temp1)
1847        __(jnc 0f)
1848        __(btl $keyword_flags_aok_bit,%temp1)
1849        __(jnc 1f)
1850        /* pop the tstack frame */
18510:      __(discard_temp_frame(%imm0))
1852        __(jmp *%ra0)
1853
1854        /* Copy the k/v pairs from the tstack back to the value stack, */
1855        /* either because the function takes an &rest arg or because */
1856        /* we need to signal an "unknown keywords" error. */
18571:      __(movl %rcontext:tcr.save_tsp,%arg_z)
1858        __(mov (%arg_z),%arg_y)
1859        __(jmp 3f)
18602:      __(push (%arg_z))
1861        __(push node_size(%arg_z))
18623:      __(addl $dnode_size,%arg_z)
1863        __(cmpl %arg_z,%arg_y)
1864        __(jne 2b)
1865        __(discard_temp_frame(%arg_z))
1866        __(btl $keyword_flags_unknown_keys_bit,%temp1)
1867        __(jnc 9f)
1868        __(btl $keyword_flags_aok_bit,%temp1)
1869        __(jc 9f)
1870        /* Signal an "unknown keywords" error */
1871        __(movl %imm0,%nargs)
1872        __(movl $nil_value,%arg_z)
1873        __(test %nargs,%nargs)
1874        __(push %ra0)
1875        __(jmp 5f)
18764:      __(pop %arg_y)
1877        __(Cons(%arg_y,%arg_z,%arg_z))
1878        __(subl $node_size,%nargs)
18795:      __(jnz 4b)
1880        __(movl $XBADKEYS,%arg_y)
1881        __(set_nargs(2))
1882        __(movl 0(%esp),%ra0)
1883        __(jmp _SPksignalerr)
18849:      __(jmp *%ra0)
1885
1886/* No keyword value were provided.  Access the keyword vector (which is the */
1887/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
1888/* N could be 0... */
1889
1890local_label(no_keyword_values):
1891        __(movzwl misc_data_offset(%fn),%imm0)
1892        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
1893        __(vector_length(%arg_y,%arg_z))
1894        __(movl $nil_value,%imm0)
1895        __(jmp 1f)
18960:      __(push %imm0)
1897        __(push %imm0)
18981:      __(subl $fixnumone,%arg_z)
1899        __(jge 0b)
1900        __(jmp *%ra0)
1901_endsubp(keyword_bind)
1902
1903/* Normally, we'd just set %fname (aka %temp0) and do */
1904/* jump_fname().  Sometimes, though, %temp0 is being used */
1905/* as %ra0, and I'm not sure that it's going to be safe to */
1906/* clobber that.  (Note that nil-relative symbols aren't going */
1907/* get moved around by the GC, so we can get away with putting */
1908/* '%err-disp in %imm0.) */
1909_spentry(ksignalerr)
1910        __(mov $nrs.errdisp,%imm0)
1911        __(mov symbol.fcell(%imm0),%fn)
1912        __(jump_fn)
1913_endsubp(ksignalerr)
1914
1915_spentry(stack_rest_arg)
1916        __(xorl %imm0,%imm0)
1917        __(push_argregs())
1918        __(jmp _SPstack_cons_rest_arg)
1919_endsubp(stack_rest_arg)
1920
1921_spentry(req_stack_rest_arg)
1922        __(push_argregs())
1923        __(jmp _SPstack_cons_rest_arg)
1924_endsubp(req_stack_rest_arg)
1925
1926_spentry(stack_cons_rest_arg)
1927_endsubp(stack_cons_rest_arg)
1928
1929_spentry(getxlong)
1930        __(int $3)
1931_endsubp(getxlong)
1932
1933/* Have to be a little careful here: the caller may or may not have pushed  */
1934/* an empty frame, and we may or may not have needed one.  We can't easily  */
1935/* tell whether or not a frame will be needed (if the caller didn't reserve  */
1936/* a frame, whether or not we need one depends on the length of the list  */
1937/* in arg_z.  So, if the caller didn't push a frame, we do so; once */
1938/* everything's been spread, we discard the reserved frame (regardless of
1939/* who pushed it) if all args fit in registers.   */
1940_spentry(spreadargz)
1941        __(test %nargs,%nargs)
1942        __(jne 0f)
1943        __(push $reserved_frame_marker)
1944        __(push $reserved_frame_marker)
19450:      __(movl %arg_z,%rcontext:tcr.save0)     /* save in case of error */
1946        __(movd %nargs,%mm0)    /* now we can use %temp1 */
1947        __(xorl %nargs,%nargs)
1948        __(cmpl $nil_value,%arg_z)
1949        __(je 2f)
19501:      __(extract_fulltag(%arg_z,%imm0))
1951        __(cmpb $fulltag_cons,%imm0_b)
1952        __(jne 9f)
1953        __(_car(%arg_z,%arg_y))
1954        __(_cdr(%arg_z,%arg_z))
1955        __(add $node_size,%nargs)
1956        __(cmpl $call_arguments_limit<<fixnumshift,%nargs)
1957        __(jge 8f)
1958        __(push %arg_y)
1959        __(cmpl $nil_value,%arg_z)
1960        __(jne 1b)
19612:      __(movd %mm0,%imm0)
1962        __(addl %imm0,%nargs)
1963        __(jne 4f)
19643:      __(addl $2*node_size,%esp)
1965        __(movl $0,%rcontext:tcr.save0)
1966        __(jmp *%ra0)
19674:      __(pop %arg_z)
1968        __(cmp $1*node_size,%nargs)
1969        __(je 3b)
1970        __(pop %arg_y)
1971        __(cmp $2*node_size,%nargs)
1972        __(je 3b)
1973        __(movl $0,%rcontext:tcr.save0)
1974        __(jmp *%ra0)
1975/* Discard everything that's been pushed already, complain */
19768:      __(lea (%esp,%nargs),%esp)
1977        __(movl %rcontext:tcr.save0,%arg_z) /* recover original */
1978        __(movl $0,%rcontext:tcr.save0)
1979        __(movl $XTMINPS,%arg_y)
1980        __(set_nargs(2))
1981        __(push %ra0)
1982        __(jmp _SPksignalerr)
19839:      __(lea (%esp,%nargs),%esp)
1984        __(movl %rcontext:tcr.save0,%arg_z) /* recover original */
1985        __(movl $0,%rcontext:tcr.save0)
1986        __(movl $XNOSPREAD,%arg_y)
1987        __(set_nargs(2))
1988        __(push %ra0)
1989        __(jmp _SPksignalerr)
1990_endsubp(spreadargz)
1991
1992
1993/* Caller built its own frame when it was entered.  If all outgoing args  */
1994/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
1995/* relative to it and restore %rbp/%ra0   */
1996_spentry(tfuncallgen)
1997        __(int $3)
1998_endsubp(tfuncallgen)
1999
2000/* Some args were pushed; move them down in the frame   */
2001_spentry(tfuncallslide)
2002        __(int $3)
2003_endsubp(tfuncallslide)
2004
2005/* No args were pushed; recover saved context & do funcall        */
2006_spentry(tfuncallvsp)
2007        __(leave)
2008        __(do_funcall())
2009_endsubp(tfuncallvsp)
2010
2011_spentry(tcallsymgen)
2012        __(int $3)
2013_endsubp(tcallsymgen)
2014
2015_spentry(tcallsymslide)
2016        __(movl %ebp,%imm0)
2017        __(subl %nargs,%imm0)
2018        __(addl $nargregs*node_size,%imm0)      /* new tos */
2019        __(push %imm0)
2020        __(push %arg_y)
2021        __(push %arg_z)
2022        __(push %nargs)
2023        __(lea (4-nargregs)*node_size(%esp,%nargs),%arg_y) /* src ptr */
2024        __(movl %ebp,%imm0) /* dst ptr */
2025        __(subl $fixnumone*nargregs,%nargs)
2026        __(jmp 1f)
20270:      __(subl $node_size,%arg_y)
2028        __(movl (%arg_y),%arg_z)
2029        __(subl $node_size,%imm0)
2030        __(movl %arg_z,(%imm0))
20311:      __(subl $fixnumone,%nargs)
2032        __(jge 0b)
2033        __(pop %nargs)
2034        __(pop %arg_z)
2035        __(pop %arg_y)
2036        __(pop %esp)
2037        __(push node_size(%ebp))
2038        __(movl 0(%ebp),%ebp)
2039        __(jump_fname)
2040_endsubp(tcallsymslide)
2041
2042_spentry(tcallsymvsp)
2043        __(leave)
2044        __(jump_fname())
2045_endsubp(tcallsymvsp)
2046
2047_spentry(tcallnfngen)
2048        __(int $3)
2049_endsubp(tcallnfngen)
2050
2051_spentry(tcallnfnslide)
2052        __(int $3)
2053_endsubp(tcallnfnslide)
2054
2055_spentry(tcallnfnvsp)
2056        __(mov %temp0,%fn)
2057        __(leave)
2058        __(jmp *%fn)
2059_endsubp(tcallnfnvsp)
2060
2061/* Make a "raw" area on the foreign stack, stack-cons a macptr to point */
2062/* to it, and return the macptr.  Size (in bytes, boxed) is in arg_z */
2063/* on entry; macptr in arg_z on exit. */
2064_spentry(makestackblock)
2065        __(unbox_fixnum(%arg_z,%imm0))
2066        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2067        __(cmpl $tstack_alloc_limit,%imm0)
2068        __(jae 1f)
2069        __(movd %rcontext:tcr.foreign_sp,%mm0)
2070        __(subl %imm0,%rcontext:tcr.foreign_sp)
2071        __(movl %rcontext:tcr.foreign_sp,%arg_z)
2072        __(movd %mm0,(%arg_z))
2073        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2074        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2075        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2076        __(movl %imm0,macptr.address(%arg_z))
2077        __(movss %fpzero,macptr.domain(%arg_z))
2078        __(movss %fpzero,macptr.type(%arg_z))
2079        __(ret)
20801:      __(movd %rcontext:tcr.foreign_sp,%mm0)
2081        __(subl $dnode_size,%rcontext:tcr.foreign_sp)
2082        __(movl %rcontext:tcr.foreign_sp,%imm0)
2083        __(movd %mm0,(%imm0))
2084        __(set_nargs(1))
2085        __(movl $nrs.new_gcable_ptr,%fname)
2086        __(jump_fname())
2087_endsubp(makestackblock)
2088
2089_spentry(makestackblock0)
2090        __(int $3)
2091_endsubp(makestackblock0)
2092
2093_spentry(makestacklist)
2094        __(int $3)
2095_endsubp(makestacklist)
2096
2097/* subtype (boxed) vpushed before initial values. (Had better be a */
2098/* node header subtag.)  Nargs set to count of things vpushed. */
2099_spentry(stkgvector)
2100        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2101        __(shrl $fixnumshift,%imm0)
2102        __(leal -fixnumone(%nargs),%arg_z)
2103        __(movl %arg_z,%arg_y)
2104        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2105        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2106        __(movd %imm0,%mm0)
2107        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2108        __(TSP_Alloc_Var(%imm0,%arg_z))
2109        __(movd %mm0,(%arg_z))
2110        __(addl $fulltag_misc,%arg_z)
2111        __(lea -node_size(%nargs),%imm0)
2112        __(jmp 2f)
21131:      __(pop misc_data_offset(%arg_z,%imm0))
21142:      __(subl $node_size,%imm0)
2115        __(jge 1b)
2116        __(addl $node_size,%esp)
2117        __(jmp *%ra0)
2118_endsubp(stkgvector)
2119
2120/* Allocate a fulltag-misc object. */
2121/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
2122_spentry(misc_alloc)
2123        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2124        __(jne local_label(misc_alloc_not_u24))
2125        __(unbox_fixnum(%arg_z,%imm0))
2126        __(mov %arg_y,%temp0)
2127        __(shl $num_subtag_bits-fixnumshift,%temp0)
2128        __(or %temp0,%imm0)     /* %imm0 now = header */
2129        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2130        __(andb $fulltagmask,%imm0_b)
2131        __(cmpb $fulltag_nodeheader,%imm0_b)
2132        __(je local_label(misc_alloc_32))
2133        __(movd %mm0,%imm0)
2134        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2135        __(jbe local_label(misc_alloc_32))
2136        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2137        __(jbe local_label(misc_alloc_8))
2138        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2139        __(jbe local_label(misc_alloc_16))
2140        __(cmpb $subtag_double_float_vector,%imm0_b)
2141        __(jne local_label(misc_alloc_1))
2142        /* double-float vector case */
2143        __(imul $2,%arg_y,%imm0)
2144        __(jmp local_label(misc_alloc_alloc_vector))
2145local_label(misc_alloc_1):
2146        __(unbox_fixnum(%arg_y,%imm0))
2147        __(addl $7,%imm0)
2148        __(shrl $3,%imm0)
2149        __(jmp local_label(misc_alloc_alloc_vector))
2150local_label(misc_alloc_8):
2151        __(unbox_fixnum(%arg_y,%imm0))
2152        __(jmp local_label(misc_alloc_alloc_vector))
2153local_label(misc_alloc_16):
2154        __(unbox_fixnum(%arg_y,%imm0))
2155        __(shl $1,%imm0)
2156        __(jmp local_label(misc_alloc_alloc_vector))
2157local_label(misc_alloc_32):
2158        __(movl %arg_y,%imm0)
2159local_label(misc_alloc_alloc_vector):
2160        __(dnode_align(%imm0,node_size,%imm0))
2161        __(Misc_Alloc(%arg_z))
2162        __(ret)
2163local_label(misc_alloc_not_u24):
2164        __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte_24))
2165_endsubp(misc_alloc)
2166
2167_startfn(C(destbind1))
2168        __(jmp *%ra0)
2169_endfn(C(destbind1))
2170
2171_spentry(macro_bind)
2172        __(int $3)
2173_endsubp(macro_bind)
2174
2175_spentry(destructuring_bind)
2176        __(mov %arg_reg,%whole_reg)
2177        __(jmp C(destbind1))
2178_endsubp(destructuring_bind)
2179
2180_spentry(destructuring_bind_inner)
2181        __(mov %arg_z,%whole_reg)
2182        __(jmp C(destbind1))
2183_endsubp(destructuring_bind_inner)
2184
2185_spentry(vpopargregs)
2186        __(int $3)
2187_endsubp(vpopargregs)
2188
2189/* If arg_z is an integer, return in imm0 something whose sign  */
2190/* is the same as arg_z's.  If not an integer, error.   */
2191_spentry(integer_sign)
2192        __(mov %arg_z,%imm0)
2193        __(testb $tagmask,%arg_z_b)
2194        __(je 8f)
2195        __(extract_typecode(%arg_z,%imm0))
2196        __(cmpb $subtag_bignum,%imm0_b)
2197        __(jne 9f)
2198        __(getvheader(%arg_z,%imm0))
2199        __(shr $num_subtag_bits,%imm0)
2200        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
22018:      __(repret)
22029:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
2203_endsubp(integer_sign)
2204
2205/* "slide" nargs worth of values up the stack.  imm0 contains */
2206/* the difference between the current stack pointer and the target. */
2207_spentry(mvslide)
2208        __(movl %nargs,%temp1)
2209        __(lea (%esp,%nargs),%arg_y)
2210        __(lea (%arg_y,%imm0),%imm0)
2211        __(test %temp1,%temp1)
2212        __(je 2f)
22131:
2214        __(subl $node_size,%arg_y)
2215        __(movl (%arg_y),%arg_z)
2216        __(subl $node_size,%imm0)
2217        __(movl %arg_z,(%imm0))
2218        __(subl $node_size,%temp1)
2219        __(jne 1b)
22202:      __(movl %imm0,%esp)
2221        __(jmp *%ra0)
2222_endsubp(mvslide)
2223
2224_spentry(save_values)
2225        __(int $3)
2226_endsubp(save_values)
2227
2228_spentry(add_values)
2229        __(int $3)
2230_endsubp(add_values)
2231
2232_spentry(recover_values)
2233        __(int $3)
2234_endsubp(recover_values)
2235
2236_spentry(recover_values_for_mvcall)
2237        __(int $3)
2238_endsubp(recover_values_for_mvcall)
2239
2240_spentry(reset)
2241        __(int $3)
2242_endsubp(reset)
2243
2244/* temp0 = element-count, arg_y = subtag, arg_z = initval */
2245_spentry(misc_alloc_init)
2246        __(push %ebp)
2247        __(movl %esp,%ebp)
2248        __(push %arg_z)
2249        __(movl %arg_y,%arg_z)
2250        __(movl %temp0,%arg_y)
2251        __(push $local_label(misc_alloc_init_back))
2252        __(jmp _SPmisc_alloc)
2253__(tra(local_label(misc_alloc_init_back)))
2254        __(pop %arg_y)
2255        __(leave)
2256        __(movl $nrs.init_misc,%fname)
2257        __(set_nargs(2))
2258        __(jump_fname())
2259_endsubp(misc_alloc_init)
2260
2261_spentry(stack_misc_alloc_init)
2262        __(int $3)
2263_endsubp(stack_misc_alloc_init)
2264
2265        .globl C(popj)
2266_spentry(popj)
2267C(popj):
2268        __(leave)
2269        __(ret)
2270_endsubp(popj)
2271
2272/* arg_z should be of type (signed-byte 64) */
2273/* return unboxed value in mm0 */
2274_spentry(gets64)
2275        __(testb $fixnummask,%arg_z_b)
2276        __(jne 1f)
2277        __(unbox_fixnum(%arg_z,%imm0))
2278        __(movd %imm0,%mm0)
2279        __(jns 8f)
2280        /* get sign into upper half of %mm0 */
2281        __(pcmpeqd %mm1,%mm1)   /* all ones */
2282        __(psllq $32,%mm1)
2283        __(por %mm1,%mm0)
2284        __(ret)
22851:      __(movb %arg_z_b,%imm0_b)
2286        __(andb $tagmask,%imm0_b)
2287        __(cmpb $tag_misc,%imm0_b)
2288        __(jne 9f)
2289        __(movb misc_subtag_offset(%arg_z),%imm0_b)
2290        __(cmpb $subtag_bignum,%imm0_b)
2291        __(jne 9f)
2292        __(movl misc_header_offset(%arg_z),%imm0)
2293        __(cmpl $two_digit_bignum_header,%imm0)
2294        __(jne 9f)
2295        __(movq misc_data_offset(%arg_z),%mm0)
22968:      __(repret)
22979:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
2298_endsubp(gets64)
2299
2300/* arg_z should be of type (unsigned-byte 64) */
2301/* return unboxed value in mm0 */
2302_spentry(getu64)
2303        __(int $3)
2304        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
2305        __(testl %arg_z,%imm0)
2306        __(movl %arg_z,%imm0)
2307        __(jne 1f)
2308        __(sarl $fixnumshift,%imm0)
2309        __(movd %imm0,%mm0)
2310        __(ret)
23111:      __(andb $tagmask,%imm0_b)
2312        __(cmpb $tag_misc,%imm0_b)
2313        __(jne 9f)
2314        __(movb misc_subtag_offset(%arg_z),%imm0_b)
2315        __(cmpb $subtag_bignum,%imm0_b)
2316        __(jne 9f)
2317        __(movl misc_header_offset(%arg_z),%imm0)
2318        __(cmpl $three_digit_bignum_header,%imm0)
2319        __(je 3f)
2320        __(cmpl $two_digit_bignum_header,%imm0)
2321        __(jne 9f)
2322        __(movl misc_data_offset(%arg_z),%imm0)
2323        __(testl %imm0,%imm0)
2324        __(js 9f)
2325        __(repret)
23263:      __(movl misc_data_offset(%arg_z),%imm0)
2327        __(cmpl $0,misc_data_offset+8(%arg_z))
2328        __(jne 9f)
2329        __(repret)
23309:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
2331_endsubp(getu64)
2332
2333_spentry(makeu64)
2334        __(int $3)
2335_endsubp(makeu64)
2336
2337/* on entry: arg_z = symbol.  On exit, arg_z = value (possibly */
2338/* unbound_marker), arg_y = symbol */
2339_spentry(specref)
2340        __(int $3)
2341_endsubp(specref)
2342
2343/* arg_y = special symbol, arg_z = new value. */
2344_spentry(specset)
2345        __(movl symbol.binding_index(%arg_y),%imm0)
2346        __(cmp %rcontext:tcr.tlb_limit,%imm0)
2347        __(movl %rcontext:tcr.tlb_pointer,%temp1)
2348        __(jae 1f)
2349        __(movl (%temp1,%imm0),%temp0)
2350        __(cmpb $no_thread_local_binding_marker,%temp0_b)
2351        __(je 1f)
2352        __(movl %arg_z,(%temp1,%imm0))
2353        __(ret)
23541:      __(movl %arg_y,%temp0)
2355        __(movl $1<<fixnumshift,%arg_y)
2356        __(jmp _SPgvset)
2357_endsubp(specset)
2358
2359_spentry(specrefcheck)
2360        __(mov %arg_z,%arg_y)
2361        __(movl symbol.binding_index(%arg_z),%imm0)
2362        __(cmp %rcontext:tcr.tlb_limit,%imm0)
2363        __(jae 7f)
2364        __(movl %rcontext:tcr.tlb_pointer,%temp1)
2365        __(movl (%temp1,%imm0),%arg_z)
2366        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
2367        __(jne 8f)
23687:      __(movl symbol.vcell(%arg_y),%arg_z)
23698:      __(cmpb $unbound_marker,%arg_z_b)
2370        __(jne,pt 9f)
2371        __(uuo_error_reg_unbound(Rarg_y))
23729:      __(repret)
2373_endsubp(specrefcheck)
2374
2375_spentry(restoreintlevel)
2376        __(int $3)
2377_endsubp(restoreintlevel)
2378
2379/* Make a lisp integer from the unsigned value in imm0 */
2380_spentry(makeu32)
2381        __(cmpl $(1<<29),%imm0)
2382        __(jae 0f)      /* need to make a bignum */
2383        __(box_fixnum(%imm0,%arg_z))
2384        __(ret)
23850:      __(movd %imm0,%mm1)
2386        __(test %imm0,%imm0)
2387        __(js 1f)
2388        __(movl $one_digit_bignum_header,%imm0)
2389        __(movd %imm0,%mm0)
2390        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
2391        __(movd %mm1,misc_data_offset(%arg_z))
2392        __(ret)
23931:      __(movl $two_digit_bignum_header,%imm0)
2394        __(movd %imm0,%mm0)
2395        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
2396        __(movd %mm1,misc_data_offset(%arg_z))
2397        __(ret)
2398_endsubp(makeu32)
2399
2400_spentry(gets32)
2401        __(int $3)
2402_endsubp(gets32)
2403
2404_spentry(getu32)
2405        __(int $3)
2406_endsubp(getu32)
2407
2408_spentry(mvpasssym)
2409        __(int $3)
2410_endsubp(mvpasssym)
2411
2412/* */
2413_spentry(unbind)
2414        __(int $3)
2415_endsubp(unbind)
2416
2417_spentry(unbind_n)
2418        __(int $3)
2419_endsubp(unbind_n)
2420
2421_spentry(unbind_to)
2422        __(movl %rcontext:tcr.db_link,%temp0)
2423        __(movl %rcontext:tcr.tlb_pointer,%arg_z)
24241:
2425        __(movl binding.sym(%temp0),%temp1)
2426        __(movl binding.val(%temp0),%arg_y)
2427        __(movl binding.link(%temp0),%temp0)
2428        __(movl %arg_y,(%arg_z,%temp1))
2429        __(cmpl %temp0,%imm0)
2430        __(jne 1b)
2431        __(movl %temp0,%rcontext:tcr.db_link)
2432        __(ret)
2433_endsubp(unbind_to)
2434
2435_spentry(bind_interrupt_level_0)
2436        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2437        __(cmpl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2438        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2439        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
2440        __(push %rcontext:tcr.db_link)
2441        __(movl %esp,%rcontext:tcr.db_link)
2442        __(movl $0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2443        __(js,pn 1f)
24440:      __(jmp *%ra0)
2445        /* Interrupt level was negative; interrupt may be pending */
24461:      __(check_pending_enabled_interrupt(2f))
24472:      __(jmp *%ra0)
2448_endsubp(bind_interrupt_level_0)
2449
2450/* Bind CCL::*INTERRUPT-LEVEL* to the fixnum -1.  (This has the effect  */
2451/* of disabling interrupts.)   */
2452_spentry(bind_interrupt_level_m1)
2453        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2454        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2455        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
2456        __(push %rcontext:tcr.db_link)
2457        __(movl %esp,%rcontext:tcr.db_link)
2458        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2459        __(jmp *%ra0)
2460_endsubp(bind_interrupt_level_m1)
2461
2462/* Bind CCL::*INTERRUPT-LEVEL* to the value in arg_z.  If that value's 0, */
2463/* do what _SPbind_interrupt_level_0 does. */
2464_spentry(bind_interrupt_level)
2465        __(test %arg_z,%arg_z)
2466        __(jz _SPbind_interrupt_level_0)
2467        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2468        __(push INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2469        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
2470        __(push %rcontext:tcr.db_link)
2471        __(movl %esp,%rcontext:tcr.db_link)
2472        __(movl %arg_z,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2473        __(jmp *%ra0)
2474_endsubp(bind_interrupt_level)
2475
2476/* Unbind CCL::*INTERRUPT-LEVEL*.  If the value changes from negative to */
2477/* non-negative, check for pending interrupts. */
2478_spentry(unbind_interrupt_level)
2479        __(movl %rcontext:tcr.tlb_pointer,%arg_y)
2480        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_y),%imm0)
2481        __(test %imm0,%imm0)
2482        __(movl %rcontext:tcr.db_link,%imm0)
2483        __(movl binding.val(%imm0),%temp0)
2484        __(movl binding.link(%imm0),%imm0)
2485        __(movl %temp0,INTERRUPT_LEVEL_BINDING_INDEX(%arg_y))
2486        __(movl %imm0,%rcontext:tcr.db_link)
2487        __(js,pn 1f)
24880:      __(repret)
24891:      __(test %temp0,%temp0)
2490        __(js 0b)
2491        __(check_pending_enabled_interrupt(2f))
24922:      __(repret)
2493_endsubp(unbind_interrupt_level)
2494
2495_spentry(progvrestore)
2496        __(int $3)
2497_endsubp(progvrestore)
2498
2499/* %arg_z <- %arg_y + %arg_z.  Do the fixnum case - including overflow -  */
2500/* inline.  Call out otherwise.   */
2501_spentry(builtin_plus)
2502        __(movl %arg_y,%imm0)
2503        __(orl %arg_z,%imm0)
2504        __(testb $fixnummask,%imm0_b)
2505        __(jne 1f)
2506        __(addl %arg_y,%arg_z)
2507        __(jo,pn C(fix_one_bit_overflow))
2508        __(repret)
25091:      __(jump_builtin(_builtin_plus,2))
2510_endsubp(builtin_plus)
2511
2512/* %arg_z <- %arg_y - %arg_z.  Do the fixnum case - including overflow -  */
2513/*  inline.  Call out otherwise.   */
2514_spentry(builtin_minus)
2515        __(movl %arg_y,%imm0)
2516        __(orl %arg_z,%imm0)
2517        __(testb $fixnummask,%imm0_b)
2518        __(jne 1f)
2519        __(xchgl %arg_y,%arg_z)
2520        __(subl %arg_y,%arg_z)
2521        __(jo,pn C(fix_one_bit_overflow))
2522        __(repret)
25231:      __(jump_builtin(_builtin_minus,2))
2524_endsubp(builtin_minus)
2525
2526/* %arg_z -< arg_y * arg_z. */
2527/* Do the fixnum case---including overflow---inline.  Call out otherwise. */
2528_spentry(builtin_times)
2529        __(movl %arg_y,%imm0)
2530        __(orb %arg_z_b,%imm0_b)
2531        __(testb $fixnummask,%imm0_b)
2532        __(jne 2f)
2533        __(unbox_fixnum(%arg_z,%imm0))
2534        /* 32-bit fixnum result in %imm0.  Overflow set if it doesn't fit. */
2535        __(imul %arg_y,%imm0)
2536        __(jo 1f)
2537        __(movl %imm0,%arg_z)
2538        __(ret)
25391:      __(unbox_fixnum(%arg_z,%eax))
2540        __(mark_as_imm(%edx))
2541        __(unbox_fixnum(%arg_y,%edx))
2542        __(imul %edx)
2543        /* SPmakes64 expects that %edx will be marked as an imm reg */
2544        __(jmp C(makes64))
25452:      __(jump_builtin(_builtin_times,2))
2546_endsubp(builtin_times)
2547
2548_spentry(builtin_div)
2549        __(jump_builtin(_builtin_div,2))
2550
2551/* %arg_z <- (= %arg_y %arg_z).   */
2552_spentry(builtin_eq)
2553        __(movl %arg_y,%imm0)
2554        __(orb %arg_z_b,%imm0_b)
2555        __(testb $fixnummask,%imm0_b)
2556        __(jne 1f)
2557        __(rcmpl(%arg_z,%arg_y))
2558        __(condition_to_boolean(e,%imm0,%arg_z))
2559        __(ret)
25601:      __(jump_builtin(_builtin_eq,2))
2561_endsubp(builtin_eq)
2562
2563/* %arg_z <- (/= %arg_y %arg_z).          */
2564_spentry(builtin_ne)
2565        __(movl %arg_y,%imm0)
2566        __(orb %arg_z_b,%imm0_b)
2567        __(testb $fixnummask,%imm0_b)
2568        __(jne 1f)
2569        __(rcmpl(%arg_z,%arg_y))
2570        __(condition_to_boolean(ne,%imm0,%arg_z))
2571        __(ret)
25721:      __(jump_builtin(_builtin_ne,2))
2573_endsubp(builtin_ne)
2574
2575/* %arg_z <- (> %arg_y %arg_z).   */
2576_spentry(builtin_gt)
2577        __(movl %arg_y,%imm0)
2578        __(orb %arg_z_b,%imm0_b)
2579        __(testb $fixnummask,%imm0_b)
2580        __(jne 1f)
2581        __(rcmpl(%arg_y,%arg_z))
2582        __(condition_to_boolean(g,%imm0,%arg_z))
2583        __(ret)
25841:      __(jump_builtin(_builtin_gt,2))
2585_endsubp(builtin_gt)
2586
2587/* %arg_z <- (>= %arg_y %arg_z).          */
2588_spentry(builtin_ge)
2589        __(movl %arg_y,%imm0)
2590        __(orb %arg_z_b,%imm0_b)
2591        __(testb $fixnummask,%imm0_b)
2592        __(jne 1f)
2593        __(rcmpl(%arg_y,%arg_z))
2594        __(condition_to_boolean(ge,%imm0,%arg_z))
2595        __(ret)
25961:      __(jump_builtin(_builtin_ge,2))
2597_endsubp(builtin_ge)
2598
2599/* %arg_z <- (< %arg_y %arg_z).   */
2600_spentry(builtin_lt)
2601        __(movl %arg_y,%imm0)
2602        __(orb %arg_z_b,%imm0_b)
2603        __(testb $fixnummask,%imm0_b)
2604        __(jne 1f)
2605        __(rcmpl(%arg_y,%arg_z))
2606        __(condition_to_boolean(l,%imm0,%arg_z))
2607        __(ret)
26081:      __(jump_builtin(_builtin_lt,2))
2609_endsubp(builtin_lt)
2610
2611/* %arg_z <- (<= %arg_y %arg_z).   */
2612_spentry(builtin_le)
2613        __(movl %arg_y,%imm0)
2614        __(orb %arg_z_b,%imm0_b)
2615        __(testb $fixnummask,%imm0_b)
2616        __(jne 1f)
2617        __(rcmpl(%arg_y,%arg_z))
2618        __(condition_to_boolean(le,%imm0,%arg_z))
2619        __(ret)
26201:      __(jump_builtin(_builtin_le,2))
2621_endsubp(builtin_le)
2622
2623_spentry(builtin_eql)
2624        __(cmpl %arg_y,%arg_z)
2625        __(je 1f)
2626        /* Not EQ.  Could only possibly be EQL if both are tag-misc  */
2627        /* and both have the same subtag. */
2628        __(movl %arg_y,%imm0)
2629        __(andb $tagmask,%imm0_b)
2630        __(cmpb $tag_misc,%imm0_b)
2631        __(jne 2f)
2632        __(movl %arg_z,%imm0)
2633        __(andb $tagmask,%imm0_b)
2634        __(jne 2f)
2635        __(extract_subtag(%arg_y,%imm0_b))
2636        __(extract_subtag(%arg_z,%imm0_bh))
2637        __(cmpb %imm0_b,%imm0_bh)
2638        __(jne 2f)
2639        __(jump_builtin(_builtin_eql,2))
26401:      __(movl $t_value,%arg_z)
2641        __(ret)
26422:      __(movl $nil_value,%arg_z)
2643        __(ret)
2644_endsubp(builtin_eql)
2645
2646_spentry(builtin_length)
2647        __(extract_fulltag(%arg_z,%imm0))
2648        __(cmpl $tag_list,%imm0)
2649        __(jz 2f)
2650        __(andl $tagmask,%imm0)
2651        __(cmpl $tag_misc,%imm0)
2652        __(jnz 8f)
2653        __(extract_subtag(%arg_z,%imm0_b))
2654        __(rcmpb(%imm0_b,$min_vector_subtag))
2655        __(jb 8f)
2656        __(je 1f)
2657        /* (simple-array * (*)) */
2658        __(movl %arg_z,%arg_y)
2659        __(vector_length(%arg_y,%arg_z))
2660        __(ret)
26611:      /* vector header */
2662        __(movl vectorH.logsize(%arg_z),%arg_z)
2663        __(ret)
26642:      /* list.  Maybe null, maybe dotted or circular. */
2665        __(movl $-fixnumone,%arg_y)
2666        __(movl %arg_z,%temp0)  /* fast pointer */
2667        __(movl %arg_z,%temp1)  /* slow pointer */
26683:      __(movb %temp0_b,%al)
2669        __(andb $fulltagmask,%al)
2670        __(addl $fixnumone,%arg_y)
2671        __(compare_reg_to_nil(%temp0))
2672        __(je 9f)
2673        __(cmpb $fulltag_cons,%al)
2674        __(jne 8f)
2675        __(movb %temp1_b,%ah)
2676        __(andb $fulltagmask,%ah)
2677        __(_cdr(%temp0,%temp0))
2678        __(testl $fixnumone,%arg_y)
2679        __(je 3b)
2680        __(cmpb $fulltag_cons,%ah)
2681        __(jne 8f)
2682        __(_cdr(%temp1,%temp1))
2683        __(cmpl %temp0,%temp1)
2684        __(jne 3b)
26858:
2686        __(jump_builtin(_builtin_length,1))
26879:
2688        __(movl %arg_y,%arg_z)
2689        __(ret)
2690_endsubp(builtin_length)
2691
2692_spentry(builtin_seqtype)
2693        __(int $3)
2694_endsubp(builtin_seqtype)
2695
2696_spentry(builtin_assq)
2697        __(cmpl $nil_value,%arg_z)
2698        __(je 5f)
26991:      __(movl %arg_z,%imm0)
2700        __(andb $fulltagmask,%imm0_b)
2701        __(cmpb $fulltag_cons,%imm0_b)
2702        __(je,pt 2f)
2703        __(uuo_error_reg_not_list(Rarg_z))
27042:      __(_car(%arg_z,%temp0))
2705        __(_cdr(%arg_z,%arg_z))
2706        __(cmpl $nil_value,%temp0)
2707        __(je 4f)
2708        __(movl %temp0,%imm0)
2709        __(andb $fulltagmask,%imm0_b)
2710        __(cmpb $fulltag_cons,%imm0_b)
2711        __(je,pt 3f)
2712        __(uuo_error_reg_not_list(Rtemp0))
27133:      __(_car(%temp0,%temp1))
2714        __(cmpl %temp0,%arg_y)
2715        __(jne 4f)
2716        __(movl %temp0,%arg_z)
2717        __(ret)
27184:      __(cmpl $nil_value,%arg_z)
27195:      __(jnz 1b)
2720        __(repret)
2721_endsubp(builtin_assq)
2722
2723_spentry(builtin_memq)
2724        __(int $3)
2725_endsubp(builtin_memq)
2726
2727logbitp_max_bit = 30
2728
2729_spentry(builtin_logbitp)
2730        /* Call out unless: both args fixnums, arg_y in [0, logbitp_max_bit) */
2731        __(movl %arg_z,%imm0)
2732        __(orl %arg_y,%imm0)
2733        __(testb $fixnummask,%imm0_b)
2734        __(jnz 1f)
2735        __(unbox_fixnum(%arg_y,%imm0))
2736        __(cmpb $logbitp_max_bit,%imm0_b)
2737        __(jae 1f)
2738        __(addb $fixnumshift,%imm0_b)
2739        __(bt %imm0,%arg_z)
2740        __(condition_to_boolean(b,%imm0,%arg_z))
2741        __(ret)
27421:      __(jump_builtin(_builtin_logbitp,2))
2743_endsubp(builtin_logbitp)
2744
2745_spentry(builtin_logior)
2746        __(movl %arg_y,%imm0)
2747        __(orb %arg_z_b,%imm0_b)
2748        __(testb $fixnummask,%imm0_b)
2749        __(jne 1f)
2750        __(orl %arg_y,%arg_z)
2751        __(ret)
27521:
2753        __(jump_builtin(_builtin_logior,2))
2754_endsubp(builtin_logior)
2755
2756_spentry(builtin_logand)
2757        __(movl %arg_y,%imm0)
2758        __(orb %arg_z_b,%imm0_b)
2759        __(testb $fixnummask,%imm0_b)
2760        __(jne 1f)
2761        __(andl %arg_y,%arg_z)
2762        __(ret)
27631:
2764        __(jump_builtin(_builtin_logand,2))
2765_endsubp(builtin_logand)
2766
2767_spentry(builtin_negate)
2768        __(testb $fixnummask,%arg_z_b)
2769        __(jne 1f)
2770        __(negl %arg_z)
2771        __(jo,pn C(fix_one_bit_overflow))
2772        __(repret)
27731:
2774        __(jump_builtin(_builtin_negate,1))
2775_endsubp(builtin_negate)
2776
2777_spentry(builtin_logxor)
2778        __(movl %arg_y,%imm0)
2779        __(orb %arg_z_b,%imm0_b)
2780        __(testb $fixnummask,%imm0_b)
2781        __(jne 1f)
2782        __(xorl %arg_y,%arg_z)
2783        __(ret)
27841:
2785        __(jump_builtin(_builtin_logxor,2))
2786_endsubp(builtin_logxor)
2787
2788_spentry(builtin_aset1)
2789        __(int $3)
2790_endsubp(builtin_aset1)
2791
2792_spentry(builtin_ash)
2793        __(movl %arg_y,%imm0)
2794        __(orb %arg_z_b,%imm0_b)
2795        __(testb $fixnummask,%imm0_b)
2796        __(jne 9f)
2797        __(unbox_fixnum(%arg_z,%imm0))
2798        /* Z flag set if zero ASH shift count */
2799        __(jnz 1f)
2800        __(movl %arg_y,%arg_z) /* shift by 0 */
2801        __(ret)
28021:      __(jns 3f)
2803        __(rcmpl(%imm0,$-31))
2804        __(jg 2f)
2805        __(unbox_fixnum(%arg_y,%imm0))
2806        __(sar $31,%imm0)
2807        __(box_fixnum(%imm0,%arg_z))
2808        __(ret)
28092:      /* Right-shift by small fixnum */
2810        __(negb %imm0_b)
2811        __(movzbl %imm0_b,%ecx)
2812        __(unbox_fixnum(%arg_y,%imm0))
2813        __(sar %cl,%imm0)
2814        __(box_fixnum(%imm0,%arg_z))
2815        __(ret)
28163:      /* Left shift by fixnum.  We can't shift by more than 31 bits, */
2817        /* though shifting by 32 is actually easy. */
2818        __(rcmpl(%imm0,$32))
2819        __(jg 9f)
2820        __(jne 4f)
2821        /* left-shift by 32 bits exactly */
2822        __(mark_as_imm(%edx)) /* aka temp1 (makes64 will undo this) */
2823        __(unbox_fixnum(%arg_y,%edx))
2824        __(xorl %imm0,%imm0)
2825        __(jmp C(makes64))
28264:      /* left-shift by 1..31 bits. Safe to move shift count to %cl */
2827        __(movzbl %imm0_b,%ecx)
2828        __(unbox_fixnum(%arg_y,%imm0))
2829        __(mark_as_imm(%edx)) /* aka temp1 (makes64 will undo this) */
2830        __(movl %imm0,%edx)
2831        __(sarl $31,%edx)       /* propagate sign */
2832        __(shld %cl,%imm0,%edx)
2833        __(shl %cl,%imm0)
2834        __(jmp C(makes64))
28359:
2836        __(jump_builtin(_builtin_ash,2))
2837_endsubp(builtin_ash)
2838
2839_spentry(builtin_aref1)
2840        __(extract_typecode(%arg_y,%imm0))
2841        __(box_fixnum_no_flags(%imm0,%temp0))
2842        __(cmpb $min_vector_subtag,%imm0_b)
2843        __(ja _SPsubtag_misc_ref)
2844        __(jump_builtin(_builtin_aref1,2))
2845_endsubp(builtin_aref1)
2846
2847/* Maybe check the x87 tag word to see if st(0) is valid and pop it */
2848/* if so.  This might allow us to avoid having to have a priori */
2849/* knowledge of whether a foreign function returns a floating-point result. */
2850/* backlink to saved %esp, below */
2851/* arg n-1 */
2852/* arg n-2 */
2853/* ... */
2854/* arg 0 */
2855/* space for alignment */
2856/* previous %esp */
2857
2858_spentry(ffcall)
2859LocalLabelPrefix[]ffcall:
2860        __(unbox_fixnum(%arg_z,%imm0))
2861        __(testb $fixnummask,%arg_z_b)
2862        __(je 0f)
2863        __(movl macptr.address(%arg_z),%imm0)
28640:
2865        /* Save lisp registers. */
2866        __(push %ebp)
2867        __(mov %esp,%ebp)
2868        __(push %temp0)
2869        __(push %temp1)
2870        __(push %arg_y)
2871        __(push %arg_z)
2872        __(push %fn)
2873        __(movl %esp,%rcontext:tcr.save_vsp)
2874        __(movl %ebp,%rcontext:tcr.save_ebp)
2875        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
2876        __(movl %rcontext:tcr.foreign_sp,%esp)
2877        __(stmxcsr %rcontext:tcr.lisp_mxcsr)
2878        __(emms)
2879        __(ldmxcsr %rcontext:tcr.foreign_mxcsr)
2880        __(movl (%esp),%ebp)
2881LocalLabelPrefix[]ffcall_setup:
2882        __(addl $node_size,%esp)
2883LocalLabelPrefix[]ffcall_call:
2884        __(call *%eax)
2885LocalLabelPrefix[]ffcall_call_end:
2886        __(movl %ebp,%esp)
2887        __(movl %esp,%rcontext:tcr.foreign_sp)
2888        __(clr %arg_z)
2889        __(clr %arg_y)
2890        __(clr %temp1)
2891        __(clr %temp0)
2892        __(clr %fn)
2893        __(pxor %fpzero,%fpzero)
2894        __ifdef([DARWIN])
2895        /* Darwin's math library seems to cause spurious FP exceptions. */
2896        __(movl %arg_z,%rcontext:tcr.ffi_exception)
2897        __else
2898        __(stmxcsr %rcontext:tcr.ffi_exception)
2899        __endif
2900        __(movl %rcontext:tcr.save_vsp,%esp)
2901        __(movl %rcontext:tcr.save_ebp,%ebp)
2902        __(movl $TCR_STATE_LISP,%rcontext:tcr.valence)
2903        __(pop %fn)
2904        __(pop %arg_z)
2905        __(pop %arg_y)
2906        __(pop %temp1)
2907        __(ldmxcsr %rcontext:tcr.lisp_mxcsr)
2908        __(check_pending_interrupt(%temp0))
2909        __(pop %temp0)
2910        __(leave)
2911        __(ret)
2912        /* need to deal with NSExceptions and Objc-2.0 execptions */
2913_endsubp(ffcall)
2914
2915_spentry(ffcall_return_registers)
2916        __(int $3)
2917_endsubp(ffcall_return_registers)
2918
2919_spentry(spread_lexprz)
2920        __(int $3)
2921_endsubp(spread_lexprz)
2922
2923_spentry(callback)
2924        __(int $3)
2925_endsubp(callback)
2926
2927_spentry(aref2)
2928        __(int $3)
2929_endsubp(aref2)
2930
2931_spentry(aref3)
2932        __(int $3)
2933_endsubp(aref3)
2934
2935_spentry(aset2)
2936        __(int $3)
2937_endsubp(aset2)
2938
2939_spentry(aset3)
2940        __(int $3)
2941_endsubp(aset3)
2942
2943/* Prepend all but the first seven (6 words of code & other immediate data,
2944/* plus inner fn) and last (lfbits) elements of %fn to the "arglist". */
2945_spentry(call_closure)
2946        new_local_labels()
2947        __(vector_length(%fn,%imm0))
2948        __(subl $8<<fixnumshift,%imm0)  /* imm0 = inherited arg count */
2949        __(lea (%nargs,%imm0),%temp0)
2950        __(cmpl $nargregs<<fixnumshift,%temp0)
2951        __(jna local_label(regs_only))  /* either: 1 arg, 1 inherited, or */
2952                                        /* no args, 2 inherited */
2953        __(pop %rcontext:tcr.save0)             /* save return address */
2954        __(cmpl $nargregs<<fixnumshift,%nargs)
2955        __(jna local_label(no_insert))
2956
2957/* Some arguments have already been pushed.  Push %imm0's worth */
2958/* of NILs, copy those arguments that have already been vpushed from */
2959/* the old TOS to the new, then insert all of the inherited args */
2960/* and go to the function. */
2961
2962        __(mov %imm0,%temp0)
2963local_label(push_nil_loop):
2964        __(push $nil_value)
2965        __(sub $fixnumone,%temp0)
2966        __(jne local_label(push_nil_loop))
2967
2968        __(int $3)
2969/* Here if no args were pushed by the caller. */
2970/* cases: */
2971/* no args, more than two inherited args */
2972/* a single arg in arg_z, more than one inherited arg */
2973/* two args in arg_y and arg_z, some number of inherited args */
2974
2975/* Therefore, we're always going to have to push something (the sum of
2976/* %nargs and %imm0 will always be greater than $nargregs), and */
2977/* we will have to reserve space for a stack frame. */
2978/* The 0 args, 2 inherited case and the 1 arg, 1 inherited case get */
2979/* handled at local_label(regs_ony). */
2980       
2981local_label(no_insert):
2982        /* Reserve space for a stack frame */
2983        __(push $reserved_frame_marker)
2984        __(push $reserved_frame_marker)
2985        __(lea 7<<fixnumshift(%imm0),%temp0)    /* last inherited arg */
2986        __(rcmpl(%nargs,$fixnumone))
2987        __(je local_label(set_arg_y))
2988        __(jb local_label(set_y_z))
2989        /* %nargs = $nargregs (i.e., 2), vpush remaining inherited vars. */
2990
2991local_label(vpush_remaining):
2992        __(movl $7<<fixnumshift,%temp0)
2993local_label(vpush_remaining_loop):
2994        __(push misc_data_offset(%fn,%temp0))
2995        __(add $node_size,%temp0)
2996        __(add $fixnumone,%nargs)
2997        __(sub $node_size,%imm0)
2998        __(jnz local_label(vpush_remaining_loop))
2999        __(jmp local_label(go))
3000       
3001local_label(set_arg_y):
3002        /* one arg in arg_z.  set arg_y and vpush remaining inherited args */
3003        __(subl $node_size,%temp0)
3004        __(movl misc_data_offset(%fn,%temp0),%arg_y)
3005        __(addl $fixnumone,%nargs)
3006        __(subl $fixnumone,%imm0)
3007        __(jmp local_label(vpush_remaining))
3008local_label(set_y_z):
3009        __(subl $node_size,%temp0)
3010        __(movl misc_data_offset(%fn,%temp0),%arg_z)
3011        __(addl $fixnumone,%nargs)
3012        __(subl $fixnumone,%imm0)
3013        __(jmp local_label(set_arg_y))
3014
3015local_label(go):
3016        __(movl misc_data_offset+(6*node_size)(%fn),%fn)
3017        __(push %rcontext:tcr.save0)    /* restore return addr */
3018        __(movapd %fpzero,%rcontext:tcr.save0)  /* clear out spill area */
3019        __(jmp *%fn)
3020local_label(regs_only):
3021        __(lea 7<<fixnumshift(%imm0),%temp0)
3022        __(test %nargs,%nargs)
3023        __(jne local_label(one_arg))
3024        /* no args passed, two inherited args */
3025        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_z)
3026        __(cmpl $node_size,%imm0)
3027        __(je local_label(rgo))
3028        __(movl misc_data_offset-(node_size*2)(%fn,%temp0),%arg_y)
3029local_label(rgo):
3030        __(addl %imm0,%nargs)
3031        __(jmp *misc_data_offset+(6*node_size)(%fn))
3032local_label(one_arg):
3033        /* one arg was passed, so there's one inherited arg */
3034        __(movl misc_data_offset-node_size(%fn,%temp0),%arg_y)
3035        __(jmp local_label(rgo))
3036_endsubp(call_closure)
3037
3038_spentry(poweropen_callbackX)
3039        __(int $3)
3040_endsubp(poweropen_callbackX)
3041
3042_spentry(poweropen_ffcallX)
3043        __(int $3)
3044_endsubp(poweropen_ffcallX)
3045
3046_spentry(poweropen_syscall)
3047        __(int $3)
3048_endsubp(poweropen_syscall)
3049
3050_spentry(eabi_ff_call)
3051        __(int $3)
3052_endsubp(eabi_ff_call)
3053
3054_spentry(eabi_callback)
3055        __(int $3)
3056_endsubp(eabi_callback)
3057
3058
3059/* Unused, and often not used on PPC either  */
3060_spentry(callbuiltin)
3061        __(int $3)
3062_endsubp(callbuiltin)
3063
3064_spentry(callbuiltin0)
3065        __(int $3)
3066_endsubp(callbuiltin0)
3067
3068_spentry(callbuiltin1)
3069        __(int $3)
3070_endsubp(callbuiltin1)
3071
3072_spentry(callbuiltin2)
3073        __(int $3)
3074_endsubp(callbuiltin2)
3075
3076_spentry(callbuiltin3)
3077        __(int $3)
3078_endsubp(callbuiltin3)
3079
3080_spentry(restorefullcontext)
3081        __(int $3)
3082_endsubp(restorefullcontext)
3083
3084_spentry(savecontextvsp)
3085        __(int $3)
3086_endsubp(savecontextvsp)
3087
3088_spentry(savecontext0)
3089        __(int $3)
3090_endsubp(savecontext0)
3091
3092_spentry(restorecontext)
3093        __(int $3)
3094_endsubp(restorecontext)
3095
3096_spentry(stkconsyz)
3097        __(int $3)
3098_endsubp(stkconsyz)
3099
3100_spentry(stkvcell0)
3101        __(int $3)
3102_endsubp(stkvcell0)
3103
3104_spentry(stkvcellvsp)
3105        __(int $3)
3106_endsubp(stkvcellvsp)
3107
3108_spentry(breakpoint)
3109        __(int $3)
3110_endsubp(breakpoint)
3111
3112_spentry(unused_5)
3113        __(int $3)
3114_endsubp(unused_5)
3115
3116_spentry(unused_6)
3117        __(int $3)
3118_endsubp(unused_6)
3119
Note: See TracBrowser for help on using the repository browser.