source: release/1.9/source/lisp-kernel/x86-spentry32.s @ 15706

Last change on this file since 15706 was 15706, checked in by gb, 6 years ago

Propagate recent trunk changes.

File size: 159.8 KB
RevLine 
[15429]1/*
2   Copyright (C) 2006-2012 Clozure Associates
3   This file is part of Clozure CL. 
4
5   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
6   License , known as the LLGPL and distributed with Clozure CL as the
7   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
8   which is distributed with Clozure CL as the file "LGPL".  Where these
9   conflict, the preamble takes precedence. 
10
11   Clozure CL is referenced in the preamble as the "LIBRARY."
12
13   The LLGPL is also available online at
14   http://opensource.franz.com/preamble.html
15*/
[7267]16        include(lisp.s)
[8223]17        _beginfile
[8647]18
[7267]19        .align 2
[13337]20define(`_spentry',`ifdef(`__func_name',`_endfn',`')
[7267]21        .p2align 3
22        _exportfn(_SP$1)
[13337]23')
[7267]24
[13337]25define(`_endsubp',`
[7267]26        _endfn(_SP$1)
[13337]27')
[7267]28
[13337]29define(`jump_builtin',`
[7286]30        ref_nrs_value(builtin_functions,%fname)
31        set_nargs($2)
32        vrefr(%fname,%fname,$1)
33        jump_fname()
[13337]34')
[7286]35
[8647]36_spentry(bad_funcall)
[10583]37Xspentry_start:                 
[8647]38        .globl C(bad_funcall)
[7286]39__(tra(C(bad_funcall)))
40        __(uuo_error_not_callable)
41_endsubp(bad_funcall)
42
[7267]43/* %arg_z has overflowed by one bit.  Make a bignum with 1 (32-bit) digit. */
44_spentry(fix_overflow)
45C(fix_one_bit_overflow):
46        __(movl $one_digit_bignum_header,%imm0)
47        __(movd %imm0,%mm0)
[13337]48        __(Misc_Alloc_Fixed(`',aligned_bignum_size(1)))
[7267]49        __(unbox_fixnum(%arg_z,%imm0))
50        __(xor $0xc0000000,%imm0)
51        __(mov %temp0,%arg_z)
52        __(movl %imm0,misc_data_offset(%arg_z))
53        __(ret)
54_endsubp(fix_overflow)
55
[8647]56/* %arg_y = vector, %arg_z = unscaled-idx */
[8068]57_spentry(misc_ref)
[8647]58        __(mov %arg_y,%imm0)
59        __(andb $tagmask,%imm0_b)
60        __(cmpb $tag_misc,%imm0_b)
[11227]61        __(jne 0f)
62        __(testb $fixnummask,%arg_z_b)
63        __(jne 1f)
64        __(movl misc_header_offset(%arg_y),%imm0)
[8647]65        __(xorb %imm0_b,%imm0_b)
66        __(shrl $num_subtag_bits-fixnumshift,%imm0)
[9173]67        __(cmpl %imm0,%arg_z)
[11227]68        __(jae 2f)
[8647]69        __(movb misc_subtag_offset(%arg_y),%imm0_b)
[11227]70        __(jmp C(misc_ref_common))
71
720:      __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
731:      __(uuo_error_reg_not_fixnum(Rarg_z))
742:      __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
[8068]75_endsubp(misc_ref)
76
[9676]77/* %imm0_b = subtag, %arg_y = vector, %arg_z = index. */
[8253]78/* Bounds/type-checking done in caller. */
[8068]79_startfn(C(misc_ref_common))
[9676]80        __(movzbl %imm0_b,%imm0)
[8647]81        __(leal local_label(misc_ref_jmp)(,%imm0,4),%imm0)
[8260]82        __(jmp *(%imm0))
[8253]83        .p2align 2
84local_label(misc_ref_jmp):
85        /* 00-0f */
86        .long local_label(misc_ref_invalid) /* 00 even_fixnum  */
87        .long local_label(misc_ref_invalid) /* 01 cons  */
88        .long local_label(misc_ref_invalid) /* 02 nodeheader  */
89        .long local_label(misc_ref_invalid) /* 03 imm  */
90        .long local_label(misc_ref_invalid) /* 04 odd_fixnum  */
91        .long local_label(misc_ref_invalid) /* 05 tra  */
92        .long local_label(misc_ref_invalid) /* 06 misc  */
93        .long local_label(misc_ref_u32) /* 07 bignum  */
94        .long local_label(misc_ref_invalid) /* 08 even_fixnum  */
95        .long local_label(misc_ref_invalid) /* 09 cons  */
96        .long local_label(misc_ref_node) /* 0a ratio  */
97        .long local_label(misc_ref_invalid) /* 0b imm  */
98        .long local_label(misc_ref_invalid) /* 0c odd_fixnum  */
99        .long local_label(misc_ref_invalid) /* 0d tra  */
100        .long local_label(misc_ref_invalid) /* 0e misc  */
101        .long local_label(misc_ref_u32) /* 0f single_float  */
102        /* 10-1*/
103        .long local_label(misc_ref_invalid) /* 10 even_fixnum  */
104        .long local_label(misc_ref_invalid) /* 11 cons  */
105        .long local_label(misc_ref_invalid) /* 12 nodeheader  */
106        .long local_label(misc_ref_invalid) /* 13 imm  */
107        .long local_label(misc_ref_invalid) /* 14 odd_fixnum  */
108        .long local_label(misc_ref_invalid) /* 15 tra  */
109        .long local_label(misc_ref_invalid) /* 16 misc  */
110        .long local_label(misc_ref_u32) /* 17 double_float  */
111        .long local_label(misc_ref_invalid) /* 18 even_fixnum  */
112        .long local_label(misc_ref_invalid) /* 19 cons  */
113        .long local_label(misc_ref_node) /* 1a complex  */
114        .long local_label(misc_ref_invalid) /* 1b imm  */
115        .long local_label(misc_ref_invalid) /* 1c odd_fixnum  */
116        .long local_label(misc_ref_invalid) /* 1d tra  */
117        .long local_label(misc_ref_invalid) /* 1e misc  */
118        .long local_label(misc_ref_u32) /* 1f macptr  */
119        /* 20-2*/
120        .long local_label(misc_ref_invalid) /* 20 even_fixnum  */
121        .long local_label(misc_ref_invalid) /* 21 cons  */
[11857]122        .long local_label(misc_ref_node) /* 22 catch_frame  */
[8253]123        .long local_label(misc_ref_invalid) /* 23 imm  */
124        .long local_label(misc_ref_invalid) /* 24 odd_fixnum  */
125        .long local_label(misc_ref_invalid) /* 25 tra  */
126        .long local_label(misc_ref_invalid) /* 26 misc  */
127        .long local_label(misc_ref_u32) /* 27 dead_macptr  */
128        .long local_label(misc_ref_invalid) /* 28 even_fixnum  */
129        .long local_label(misc_ref_invalid) /* 29 cons  */
130        .long local_label(misc_ref_function) /* 2a function  */
131        .long local_label(misc_ref_invalid) /* 2b imm  */
132        .long local_label(misc_ref_invalid) /* 2c odd_fixnum  */
133        .long local_label(misc_ref_invalid) /* 2d tra  */
134        .long local_label(misc_ref_invalid) /* 2e misc  */
135        .long local_label(misc_ref_invalid) /* 2f immheader  */
136        /* 30-3*/
137        .long local_label(misc_ref_invalid) /* 30 even_fixnum  */
138        .long local_label(misc_ref_invalid) /* 31 cons  */
[11857]139        .long local_label(misc_ref_node) /* 32 basic_stream  */
[8253]140        .long local_label(misc_ref_invalid) /* 33 imm  */
141        .long local_label(misc_ref_invalid) /* 34 odd_fixnum  */
142        .long local_label(misc_ref_invalid) /* 35 tra  */
143        .long local_label(misc_ref_invalid) /* 36 misc  */
144        .long local_label(misc_ref_invalid) /* 37 immheader  */
145        .long local_label(misc_ref_invalid) /* 38 even_fixnum  */
146        .long local_label(misc_ref_invalid) /* 39 cons  */
147        .long local_label(misc_ref_node) /* 3a symbol  */
148        .long local_label(misc_ref_invalid) /* 3b imm  */
149        .long local_label(misc_ref_invalid) /* 3c odd_fixnum  */
150        .long local_label(misc_ref_invalid) /* 3d tra  */
151        .long local_label(misc_ref_invalid) /* 3e misc  */
152        .long local_label(misc_ref_u32) /* 3f xcode_vector  */
153        /* 40-4*/
154        .long local_label(misc_ref_invalid) /* 40 even_fixnum  */
155        .long local_label(misc_ref_invalid) /* 41 cons  */
156        .long local_label(misc_ref_node) /* 42 lock  */
157        .long local_label(misc_ref_invalid) /* 43 imm  */
158        .long local_label(misc_ref_invalid) /* 44 odd_fixnum  */
159        .long local_label(misc_ref_invalid) /* 45 tra  */
160        .long local_label(misc_ref_invalid) /* 46 misc  */
161        .long local_label(misc_ref_invalid) /* 47 immheader  */
162        .long local_label(misc_ref_invalid) /* 48 even_fixnum  */
163        .long local_label(misc_ref_invalid) /* 49 cons  */
164        .long local_label(misc_ref_node) /* 4a hash_vector  */
165        .long local_label(misc_ref_invalid) /* 4b imm  */
166        .long local_label(misc_ref_invalid) /* 4c odd_fixnum  */
167        .long local_label(misc_ref_invalid) /* 4d tra  */
168        .long local_label(misc_ref_invalid) /* 4e misc  */
169        .long local_label(misc_ref_invalid) /* 4f immheader  */
170        /* 50-5*/
171        .long local_label(misc_ref_invalid) /* 50 even_fixnum  */
172        .long local_label(misc_ref_invalid) /* 51 cons  */
173        .long local_label(misc_ref_node) /* 52 pool  */
174        .long local_label(misc_ref_invalid) /* 53 imm  */
175        .long local_label(misc_ref_invalid) /* 54 odd_fixnum  */
176        .long local_label(misc_ref_invalid) /* 55 tra  */
177        .long local_label(misc_ref_invalid) /* 56 misc  */
178        .long local_label(misc_ref_invalid) /* 57 immheader  */
179        .long local_label(misc_ref_invalid) /* 58 even_fixnum  */
180        .long local_label(misc_ref_invalid) /* 59 cons  */
181        .long local_label(misc_ref_node) /* 5a weak  */
182        .long local_label(misc_ref_invalid) /* 5b imm  */
183        .long local_label(misc_ref_invalid) /* 5c odd_fixnum  */
184        .long local_label(misc_ref_invalid) /* 5d tra  */
185        .long local_label(misc_ref_invalid) /* 5e misc  */
186        .long local_label(misc_ref_invalid) /* 5f immheader  */
187        /* 60-6*/
188        .long local_label(misc_ref_invalid) /* 60 even_fixnum  */
189        .long local_label(misc_ref_invalid) /* 61 cons  */
190        .long local_label(misc_ref_node) /* 62 package  */
191        .long local_label(misc_ref_invalid) /* 63 imm  */
192        .long local_label(misc_ref_invalid) /* 64 odd_fixnum  */
193        .long local_label(misc_ref_invalid) /* 65 tra  */
194        .long local_label(misc_ref_invalid) /* 66 misc  */
195        .long local_label(misc_ref_invalid) /* 67 immheader  */
196        .long local_label(misc_ref_invalid) /* 68 even_fixnum  */
197        .long local_label(misc_ref_invalid) /* 69 cons  */
198        .long local_label(misc_ref_node) /* 6a slot_vector  */
199        .long local_label(misc_ref_invalid) /* 6b imm  */
200        .long local_label(misc_ref_invalid) /* 6c odd_fixnum  */
201        .long local_label(misc_ref_invalid) /* 6d tra  */
202        .long local_label(misc_ref_invalid) /* 6e misc  */
203        .long local_label(misc_ref_invalid) /* 6f immheader  */
204        /* 70-7*/
205        .long local_label(misc_ref_invalid) /* 70 even_fixnum  */
206        .long local_label(misc_ref_invalid) /* 71 cons  */
207        .long local_label(misc_ref_node) /* 72 instance  */
208        .long local_label(misc_ref_invalid) /* 73 imm  */
209        .long local_label(misc_ref_invalid) /* 74 odd_fixnum  */
210        .long local_label(misc_ref_invalid) /* 75 tra  */
211        .long local_label(misc_ref_invalid) /* 76 misc  */
212        .long local_label(misc_ref_invalid) /* 77 immheader  */
213        .long local_label(misc_ref_invalid) /* 78 even_fixnum  */
214        .long local_label(misc_ref_invalid) /* 79 cons  */
215        .long local_label(misc_ref_node) /* 7a struct  */
216        .long local_label(misc_ref_invalid) /* 7b imm  */
217        .long local_label(misc_ref_invalid) /* 7c odd_fixnum  */
218        .long local_label(misc_ref_invalid) /* 7d tra  */
219        .long local_label(misc_ref_invalid) /* 7e misc  */
220        .long local_label(misc_ref_invalid) /* 7f immheader  */
221        /* 80-8*/
222        .long local_label(misc_ref_invalid) /* 80 even_fixnum  */
223        .long local_label(misc_ref_invalid) /* 81 cons  */
224        .long local_label(misc_ref_node) /* 82 istruct  */
225        .long local_label(misc_ref_invalid) /* 83 imm  */
226        .long local_label(misc_ref_invalid) /* 84 odd_fixnum  */
227        .long local_label(misc_ref_invalid) /* 85 tra  */
228        .long local_label(misc_ref_invalid) /* 86 misc  */
229        .long local_label(misc_ref_invalid) /* 87 immheader  */
230        .long local_label(misc_ref_invalid) /* 88 even_fixnum  */
231        .long local_label(misc_ref_invalid) /* 89 cons  */
232        .long local_label(misc_ref_node) /* 8a value_cell  */
233        .long local_label(misc_ref_invalid) /* 8b imm  */
234        .long local_label(misc_ref_invalid) /* 8c odd_fixnum  */
235        .long local_label(misc_ref_invalid) /* 8d tra  */
236        .long local_label(misc_ref_invalid) /* 8e misc  */
237        .long local_label(misc_ref_invalid) /* 8f immheader  */
238        /* 90-9*/
239        .long local_label(misc_ref_invalid) /* 90 even_fixnum  */
240        .long local_label(misc_ref_invalid) /* 91 cons  */
241        .long local_label(misc_ref_node) /* 92 xfunction  */
242        .long local_label(misc_ref_invalid) /* 93 imm  */
243        .long local_label(misc_ref_invalid) /* 94 odd_fixnum  */
244        .long local_label(misc_ref_invalid) /* 95 tra  */
245        .long local_label(misc_ref_invalid) /* 96 misc  */
246        .long local_label(misc_ref_invalid) /* 97 immheader  */
247        .long local_label(misc_ref_invalid) /* 98 even_fixnum  */
248        .long local_label(misc_ref_invalid) /* 99 cons  */
[8647]249        .long local_label(misc_ref_node) /* 9a arrayH  */
[8253]250        .long local_label(misc_ref_invalid) /* 9b imm  */
251        .long local_label(misc_ref_invalid) /* 9c odd_fixnum  */
252        .long local_label(misc_ref_invalid) /* 9d tra  */
253        .long local_label(misc_ref_invalid) /* 9e misc  */
254        .long local_label(misc_ref_invalid) /* 9f immheader  */
255        /* a0-af  */
256        .long local_label(misc_ref_invalid) /* a0 even_fixnum  */
257        .long local_label(misc_ref_invalid) /* a1 cons  */
258        .long local_label(misc_ref_node) /* a2 vectorH  */
259        .long local_label(misc_ref_invalid) /* a3 imm  */
260        .long local_label(misc_ref_invalid) /* a4 odd_fixnum  */
261        .long local_label(misc_ref_invalid) /* a5 tra  */
262        .long local_label(misc_ref_invalid) /* a6 misc  */
263        .long local_label(misc_ref_single_float_vector) /* a7 sf_vector  */
264        .long local_label(misc_ref_invalid) /* a8 even_fixnum  */
265        .long local_label(misc_ref_invalid) /* a9 cons  */
266        .long local_label(misc_ref_node) /* aa simple_vector  */
267        .long local_label(misc_ref_invalid) /* ab imm  */
268        .long local_label(misc_ref_invalid) /* ac odd_fixnum  */
269        .long local_label(misc_ref_invalid) /* ad tra  */
270        .long local_label(misc_ref_invalid) /* ae misc  */
271        .long local_label(misc_ref_u32) /* af u32  */
272        /* b0-bf  */
273        .long local_label(misc_ref_invalid) /* b0 even_fixnum  */
274        .long local_label(misc_ref_invalid) /* b1 cons  */
275        .long local_label(misc_ref_invalid) /* b2 nodeheader  */
276        .long local_label(misc_ref_invalid) /* b3 imm  */
277        .long local_label(misc_ref_invalid) /* b4 odd_fixnum  */
278        .long local_label(misc_ref_invalid) /* b5 tra  */
279        .long local_label(misc_ref_invalid) /* b6 misc  */
280        .long local_label(misc_ref_s32) /* b7 s32  */
281        .long local_label(misc_ref_invalid) /* b8 even_fixnum  */
282        .long local_label(misc_ref_invalid) /* b9 cons  */
283        .long local_label(misc_ref_invalid) /* ba nodeheader  */
284        .long local_label(misc_ref_invalid) /* bb imm  */
285        .long local_label(misc_ref_invalid) /* bc odd_fixnum  */
286        .long local_label(misc_ref_invalid) /* bd tra  */
287        .long local_label(misc_ref_invalid) /* be misc  */
288        .long local_label(misc_ref_fixnum_vector) /* bf fixnum_vector  */
289        /* c0-cf  */
290        .long local_label(misc_ref_invalid) /* c0 even_fixnum  */
291        .long local_label(misc_ref_invalid) /* c1 cons  */
292        .long local_label(misc_ref_invalid) /* c2 nodeheader  */
293        .long local_label(misc_ref_invalid) /* c3 imm  */
294        .long local_label(misc_ref_invalid) /* c4 odd_fixnum  */
295        .long local_label(misc_ref_invalid) /* c5 tra  */
296        .long local_label(misc_ref_invalid) /* c6 misc  */
297        .long local_label(misc_ref_string) /* c7 simple_base_string  */
298        .long local_label(misc_ref_invalid) /* c8 even_fixnum  */
299        .long local_label(misc_ref_invalid) /* c9 cons  */
300        .long local_label(misc_ref_invalid) /* ca nodeheader  */
301        .long local_label(misc_ref_invalid) /* cb imm  */
302        .long local_label(misc_ref_invalid) /* cc odd_fixnum  */
303        .long local_label(misc_ref_invalid) /* cd tra  */
304        .long local_label(misc_ref_invalid) /* ce misc  */
305        .long local_label(misc_ref_u8) /* cf u8  */
306        /* d0-df  */
307        .long local_label(misc_ref_invalid) /* d0 even_fixnum  */
308        .long local_label(misc_ref_invalid) /* d1 cons  */
309        .long local_label(misc_ref_invalid) /* d2 nodeheader  */
310        .long local_label(misc_ref_invalid) /* d3 imm  */
311        .long local_label(misc_ref_invalid) /* d4 odd_fixnum  */
312        .long local_label(misc_ref_invalid) /* d5 tra  */
313        .long local_label(misc_ref_invalid) /* d6 misc  */
314        .long local_label(misc_ref_s8)      /* d7 s8  */
315        .long local_label(misc_ref_invalid) /* d8 even_fixnum  */
316        .long local_label(misc_ref_invalid) /* d9 cons  */
317        .long local_label(misc_ref_invalid) /* da nodeheader  */
318        .long local_label(misc_ref_invalid) /* db imm  */
319        .long local_label(misc_ref_invalid) /* dc odd_fixnum  */
320        .long local_label(misc_ref_invalid) /* dd tra  */
321        .long local_label(misc_ref_invalid) /* de misc  */
322        .long local_label(misc_ref_invalid) /* df immheader  */
323        /* e0-ef  */
324        .long local_label(misc_ref_invalid) /* e0 even_fixnum  */
325        .long local_label(misc_ref_invalid) /* e1 cons  */
326        .long local_label(misc_ref_invalid) /* e2 nodeheader  */
327        .long local_label(misc_ref_invalid) /* e3 imm  */
328        .long local_label(misc_ref_invalid) /* e4 odd_fixnum  */
329        .long local_label(misc_ref_invalid) /* e5 tra  */
330        .long local_label(misc_ref_invalid) /* e6 misc  */
331        .long local_label(misc_ref_u16) /* e7 u16  */
332        .long local_label(misc_ref_invalid) /* e8 even_fixnum  */
333        .long local_label(misc_ref_invalid) /* e9 cons  */
334        .long local_label(misc_ref_invalid) /* ea nodeheader  */
335        .long local_label(misc_ref_invalid) /* eb imm  */
336        .long local_label(misc_ref_invalid) /* ec odd_fixnum  */
337        .long local_label(misc_ref_invalid) /* ed tra  */
338        .long local_label(misc_ref_invalid) /* ee misc  */
339        .long local_label(misc_ref_s16) /* ef s16  */
340        /* f0-ff  */
341        .long local_label(misc_ref_invalid) /* f0 even_fixnum  */
342        .long local_label(misc_ref_invalid) /* f1 cons  */
343        .long local_label(misc_ref_invalid) /* f2 nodeheader  */
344        .long local_label(misc_ref_invalid) /* f3 imm  */
345        .long local_label(misc_ref_invalid) /* f4 odd_fixnum  */
346        .long local_label(misc_ref_invalid) /* f5 tra  */
347        .long local_label(misc_ref_invalid) /* f6 misc  */
348        .long local_label(misc_ref_double_float_vector) /* f7 df vector  */
349        .long local_label(misc_ref_invalid) /* f8 even_fixnum  */
350        .long local_label(misc_ref_invalid) /* f9 cons  */
351        .long local_label(misc_ref_invalid) /* fa nodeheader  */
352        .long local_label(misc_ref_invalid) /* fb imm  */
353        .long local_label(misc_ref_invalid) /* fc odd_fixnum  */
354        .long local_label(misc_ref_invalid) /* fd tra  */
355        .long local_label(misc_ref_invalid) /* fe misc  */
356        .long local_label(misc_ref_bit_vector) /* ff bit_vector  */
357
358/* Functions are funny.  The first N words are treated as */
359/* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
360
361local_label(misc_ref_function):
362        __(movzwl misc_data_offset(%arg_y), %imm0)
[12374]363        /* XXX bootstrapping */
364        __(btr $15,%imm0)
365        __(jnc 0f)
366        __(movl $0xffffff00,%temp0)
367        __(andl misc_header_offset(%arg_y),%temp0)
368        __(shr $num_subtag_bits-fixnumshift,%temp0)
[8253]369        __(shl $fixnumshift,%imm0)
[12374]370        __(subl %imm0,%temp0)
371        __(movl %temp0,%imm0)
372        __(shr $fixnumshift,%imm0)
3730:     
374        __(shl $fixnumshift,%imm0)
[8253]375        __(rcmpl(%arg_z,%imm0))
376        __(jb local_label(misc_ref_u32))
377local_label(misc_ref_node):
378        __(movl misc_data_offset(%arg_y,%arg_z),%arg_z)
379        __(ret)
380local_label(misc_ref_u32):
381        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
382        __(jmp _SPmakeu32)
383local_label(misc_ref_s32):
384        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
385        __(jmp _SPmakes32)
386local_label(misc_ref_single_float_vector):
387        __(movss misc_data_offset(%arg_y,%arg_z),%fp1)
388        __(movl $single_float_header,%imm0)
389        __(movd %imm0,%mm0)
390        __(Misc_Alloc_Fixed(%arg_z,single_float.size))
391        __(movss %fp1,single_float.value(%arg_z))
392        __(ret)
393local_label(misc_ref_double_float_vector):
[9721]394        __(movsd misc_dfloat_offset(%arg_y,%arg_z,2),%fp1)
[8253]395        __(movl $double_float_header,%imm0)
396        __(movd %imm0,%mm0)
397        __(Misc_Alloc_Fixed(%arg_z,double_float.size))
398        __(movsd %fp1,double_float.value(%arg_z))
399        __(ret)
400local_label(misc_ref_fixnum_vector):
401        __(movl misc_data_offset(%arg_y,%arg_z),%imm0)
402        __(box_fixnum(%imm0,%arg_z))
403        __(ret)
404local_label(misc_ref_u8):
405        __(movl %arg_z,%imm0)
406        __(shr $2,%imm0)
407        __(movzbl misc_data_offset(%arg_y,%imm0),%imm0)
408        __(box_fixnum(%imm0,%arg_z))
409        __(ret)
410local_label(misc_ref_s8):
411        __(movl %arg_z,%imm0)
412        __(shr $2,%imm0)
413        __(movsbl misc_data_offset(%arg_y,%imm0),%imm0)
414        __(box_fixnum(%imm0,%arg_z))
415        __(ret)
416local_label(misc_ref_string):
417        __(movl %arg_z,%imm0)
418        __(movl misc_data_offset(%arg_y,%imm0),%imm0)
419        __(shll $charcode_shift,%imm0)
420        __(leal subtag_character(%imm0),%arg_z)
421        __(ret)
422local_label(misc_ref_u16):
423        __(movl %arg_z,%imm0)
424        __(shrl $1,%imm0)
425        __(movzwl misc_data_offset(%arg_y,%imm0),%imm0)
426        __(box_fixnum(%imm0,%arg_z))
427        __(ret)
428local_label(misc_ref_s16):
429        __(movl %arg_z,%imm0)
430        __(shrl $1,%imm0)
431        __(movswl misc_data_offset(%arg_y,%imm0),%imm0)
432        __(box_fixnum(%imm0,%arg_z))
433        __(ret)
434local_label(misc_ref_bit_vector):
435        __(unbox_fixnum(%arg_z,%imm0))
436        __(btl %imm0,misc_data_offset(%arg_y))
437        __(setc %imm0_b)
438        __(movzbl %imm0_b,%imm0)
439        __(box_fixnum(%imm0,%arg_z))
440        __(ret)
441local_label(misc_ref_invalid):
[11449]442        __(pop %temp1)  /* return addr */
[8647]443        __(push $reserved_frame_marker)
444        __(push $reserved_frame_marker)
[8253]445        __(push $XBADVEC)
[11449]446        __(push %temp1)
[8253]447        __(set_nargs(3))
448        __(jmp _SPksignalerr)
[8068]449_endfn(C(misc_ref_common))
450
[8253]451/* Like misc_ref, only the boxed subtag is in temp0. */
[8068]452_spentry(subtag_misc_ref)
[8253]453        __(mov %arg_y,%imm0)
454        __(and $tagmask,%imm0)
455        __(cmp $tag_misc,%imm0)
[11227]456        __(jne 0f)
457        __(testb $fixnummask,%arg_z_b)
458        __(jne 1f)
459        __(movl misc_header_offset(%arg_y),%imm0)
[8253]460        __(xorb %imm0_b,%imm0_b)
461        __(shrl $num_subtag_bits-fixnumshift,%imm0)
462        __(cmp %imm0,%arg_z)
[11227]463        __(jae 2f)
464        __(unbox_fixnum(%temp0,%imm0))
[8253]465        __(jmp C(misc_ref_common))
[11227]4660:      __(uuo_error_reg_not_tag(Rarg_y,tag_misc))
4671:      __(uuo_error_reg_not_fixnum(Rarg_z))
4682:      __(uuo_error_vector_bounds(Rarg_z,Rarg_y))
[8068]469_endsubp(subtag_misc_ref)
470
[8647]471/* Like misc_set, only the boxed subtag is in temp1. */
[8068]472_spentry(subtag_misc_set)
[8647]473        __(mov %temp0,%imm0)
474        __(andb $tagmask,%imm0_b)
475        __(cmpb $tag_misc,%imm0_b)
[11227]476        __(jne 0f)
477        __(mov %arg_y,%imm0)
[8647]478        __(testb $fixnummask,%imm0_b)
[11227]479        __(jne 1f)
480        __(movl misc_header_offset(%temp0),%imm0)
[8647]481        __(xorb %imm0_b,%imm0_b)
482        __(shrl $num_subtag_bits-fixnumshift,%imm0)
483        __(cmpl %imm0,%arg_y)
[11227]484        __(jae 2f)
485        __(unbox_fixnum(%temp1,%imm0))
[8647]486        __(jmp C(misc_set_common))
[11227]4870:      __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
4881:      __(uuo_error_reg_not_fixnum(Rarg_y))
4892:      __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
[8068]490_endsubp(subtag_misc_set)
491
[8647]492/* %temp0 = vector, %arg_y = unscaled-idx, %arg_z = val */
[8068]493_spentry(misc_set)
[8647]494        __(mov %temp0,%imm0)
495        __(andb $tagmask,%imm0_b)
496        __(cmpb $tag_misc,%imm0_b)
[11227]497        __(jne 0f)
498        __(test $fixnummask,%arg_y)
499        __(jne 1f)
500        __(movl misc_header_offset(%temp0),%imm0)
[8647]501        __(xorb %imm0_b,%imm0_b)
502        __(shrl $num_subtag_bits-fixnumshift,%imm0)
503        __(cmpl %imm0,%arg_y)
[11227]504        __(jae 2f)
505        __(xorl %imm0,%imm0)
[8647]506        __(movb misc_subtag_offset(%temp0),%imm0_b)
[11227]507        __(jmp C(misc_set_common))
5080:      __(uuo_error_reg_not_tag(Rtemp0,tag_misc))
5091:      __(uuo_error_reg_not_fixnum(Rarg_y))
5102:      __(uuo_error_vector_bounds(Rarg_y,Rtemp0))
[8068]511_endsubp(misc_set)
512
[9781]513/* imm0_b = subtag, %temp0 = vector, %arg_y = index, %arg_z = value */
[8068]514_startfn(C(misc_set_common))
[9781]515        __(movzbl %imm0_b,%imm0)
[8647]516        __(leal local_label(misc_set_jmp)(,%imm0,4),%imm0)
517        __(jmp *(%imm0))
518        .p2align 2
519local_label(misc_set_jmp):
520        /* 00-0f */
521        .long local_label(misc_set_invalid) /* 00 even_fixnum  */
522        .long local_label(misc_set_invalid) /* 01 cons  */
523        .long local_label(misc_set_invalid) /* 02 nodeheader  */
524        .long local_label(misc_set_invalid) /* 03 imm  */
525        .long local_label(misc_set_invalid) /* 04 odd_fixnum  */
526        .long local_label(misc_set_invalid) /* 05 tra  */
527        .long local_label(misc_set_invalid) /* 06 misc  */
528        .long local_label(misc_set_u32) /* 07 bignum  */
529        .long local_label(misc_set_invalid) /* 08 even_fixnum  */
530        .long local_label(misc_set_invalid) /* 09 cons  */
531        .long _SPgvset /* 0a ratio  */
532        .long local_label(misc_set_invalid) /* 0b imm  */
533        .long local_label(misc_set_invalid) /* 0c odd_fixnum  */
534        .long local_label(misc_set_invalid) /* 0d tra  */
535        .long local_label(misc_set_invalid) /* 0e misc  */
536        .long local_label(misc_set_u32) /* 0f single_float  */
537        /* 10-1*/
538        .long local_label(misc_set_invalid) /* 10 even_fixnum  */
539        .long local_label(misc_set_invalid) /* 11 cons  */
540        .long local_label(misc_set_invalid) /* 12 nodeheader  */
541        .long local_label(misc_set_invalid) /* 13 imm  */
542        .long local_label(misc_set_invalid) /* 14 odd_fixnum  */
543        .long local_label(misc_set_invalid) /* 15 tra  */
544        .long local_label(misc_set_invalid) /* 16 misc  */
545        .long local_label(misc_set_u32) /* 17 double_float  */
546        .long local_label(misc_set_invalid) /* 18 even_fixnum  */
547        .long local_label(misc_set_invalid) /* 19 cons  */
548        .long _SPgvset /* 1a complex  */
549        .long local_label(misc_set_invalid) /* 1b imm  */
550        .long local_label(misc_set_invalid) /* 1c odd_fixnum  */
551        .long local_label(misc_set_invalid) /* 1d tra  */
552        .long local_label(misc_set_invalid) /* 1e misc  */
553        .long local_label(misc_set_u32) /* 1f macptr  */
554        /* 20-2*/
555        .long local_label(misc_set_invalid) /* 20 even_fixnum  */
556        .long local_label(misc_set_invalid) /* 21 cons  */
[11857]557        .long _SPgvset /* 22 catch_frame  */
[8647]558        .long local_label(misc_set_invalid) /* 23 imm  */
559        .long local_label(misc_set_invalid) /* 24 odd_fixnum  */
560        .long local_label(misc_set_invalid) /* 25 tra  */
561        .long local_label(misc_set_invalid) /* 26 misc  */
562        .long local_label(misc_set_u32) /* 27 dead_macptr  */
563        .long local_label(misc_set_invalid) /* 28 even_fixnum  */
564        .long local_label(misc_set_invalid) /* 29 cons  */
565        .long local_label(misc_set_function) /* 2a function  */
566        .long local_label(misc_set_invalid) /* 2b imm  */
567        .long local_label(misc_set_invalid) /* 2c odd_fixnum  */
568        .long local_label(misc_set_invalid) /* 2d tra  */
569        .long local_label(misc_set_invalid) /* 2e misc  */
570        .long local_label(misc_set_invalid) /* 2f immheader  */
571        /* 30-3*/
572        .long local_label(misc_set_invalid) /* 30 even_fixnum  */
573        .long local_label(misc_set_invalid) /* 31 cons  */
[11857]574        .long _SPgvset /* 32 basic_stream  */
[8647]575        .long local_label(misc_set_invalid) /* 33 imm  */
576        .long local_label(misc_set_invalid) /* 34 odd_fixnum  */
577        .long local_label(misc_set_invalid) /* 35 tra  */
578        .long local_label(misc_set_invalid) /* 36 misc  */
579        .long local_label(misc_set_invalid) /* 37 immheader  */
580        .long local_label(misc_set_invalid) /* 38 even_fixnum  */
581        .long local_label(misc_set_invalid) /* 39 cons  */
582        .long _SPgvset /* 3a symbol  */
583        .long local_label(misc_set_invalid) /* 3b imm  */
584        .long local_label(misc_set_invalid) /* 3c odd_fixnum  */
585        .long local_label(misc_set_invalid) /* 3d tra  */
586        .long local_label(misc_set_invalid) /* 3e misc  */
587        .long local_label(misc_set_u32) /* 3f xcode_vector  */
588        /* 40-4*/
589        .long local_label(misc_set_invalid) /* 40 even_fixnum  */
590        .long local_label(misc_set_invalid) /* 41 cons  */
591        .long _SPgvset /* 42 lock  */
592        .long local_label(misc_set_invalid) /* 43 imm  */
593        .long local_label(misc_set_invalid) /* 44 odd_fixnum  */
594        .long local_label(misc_set_invalid) /* 45 tra  */
595        .long local_label(misc_set_invalid) /* 46 misc  */
596        .long local_label(misc_set_invalid) /* 47 immheader  */
597        .long local_label(misc_set_invalid) /* 48 even_fixnum  */
598        .long local_label(misc_set_invalid) /* 49 cons  */
599        .long _SPgvset /* 4a hash_vector  */
600        .long local_label(misc_set_invalid) /* 4b imm  */
601        .long local_label(misc_set_invalid) /* 4c odd_fixnum  */
602        .long local_label(misc_set_invalid) /* 4d tra  */
603        .long local_label(misc_set_invalid) /* 4e misc  */
604        .long local_label(misc_set_invalid) /* 4f immheader  */
605        /* 50-5*/
606        .long local_label(misc_set_invalid) /* 50 even_fixnum  */
607        .long local_label(misc_set_invalid) /* 51 cons  */
608        .long _SPgvset /* 52 pool  */
609        .long local_label(misc_set_invalid) /* 53 imm  */
610        .long local_label(misc_set_invalid) /* 54 odd_fixnum  */
611        .long local_label(misc_set_invalid) /* 55 tra  */
612        .long local_label(misc_set_invalid) /* 56 misc  */
613        .long local_label(misc_set_invalid) /* 57 immheader  */
614        .long local_label(misc_set_invalid) /* 58 even_fixnum  */
615        .long local_label(misc_set_invalid) /* 59 cons  */
616        .long _SPgvset /* 5a weak  */
617        .long local_label(misc_set_invalid) /* 5b imm  */
618        .long local_label(misc_set_invalid) /* 5c odd_fixnum  */
619        .long local_label(misc_set_invalid) /* 5d tra  */
620        .long local_label(misc_set_invalid) /* 5e misc  */
621        .long local_label(misc_set_invalid) /* 5f immheader  */
622        /* 60-6*/
623        .long local_label(misc_set_invalid) /* 60 even_fixnum  */
624        .long local_label(misc_set_invalid) /* 61 cons  */
625        .long _SPgvset /* 62 package  */
626        .long local_label(misc_set_invalid) /* 63 imm  */
627        .long local_label(misc_set_invalid) /* 64 odd_fixnum  */
628        .long local_label(misc_set_invalid) /* 65 tra  */
629        .long local_label(misc_set_invalid) /* 66 misc  */
630        .long local_label(misc_set_invalid) /* 67 immheader  */
631        .long local_label(misc_set_invalid) /* 68 even_fixnum  */
632        .long local_label(misc_set_invalid) /* 69 cons  */
633        .long _SPgvset /* 6a slot_vector  */
634        .long local_label(misc_set_invalid) /* 6b imm  */
635        .long local_label(misc_set_invalid) /* 6c odd_fixnum  */
636        .long local_label(misc_set_invalid) /* 6d tra  */
637        .long local_label(misc_set_invalid) /* 6e misc  */
638        .long local_label(misc_set_invalid) /* 6f immheader  */
639        /* 70-7*/
640        .long local_label(misc_set_invalid) /* 70 even_fixnum  */
641        .long local_label(misc_set_invalid) /* 71 cons  */
642        .long _SPgvset /* 72 instance  */
643        .long local_label(misc_set_invalid) /* 73 imm  */
644        .long local_label(misc_set_invalid) /* 74 odd_fixnum  */
645        .long local_label(misc_set_invalid) /* 75 tra  */
646        .long local_label(misc_set_invalid) /* 76 misc  */
647        .long local_label(misc_set_invalid) /* 77 immheader  */
648        .long local_label(misc_set_invalid) /* 78 even_fixnum  */
649        .long local_label(misc_set_invalid) /* 79 cons  */
650        .long _SPgvset /* 7a struct  */
651        .long local_label(misc_set_invalid) /* 7b imm  */
652        .long local_label(misc_set_invalid) /* 7c odd_fixnum  */
653        .long local_label(misc_set_invalid) /* 7d tra  */
654        .long local_label(misc_set_invalid) /* 7e misc  */
655        .long local_label(misc_set_invalid) /* 7f immheader  */
656        /* 80-8*/
657        .long local_label(misc_set_invalid) /* 80 even_fixnum  */
658        .long local_label(misc_set_invalid) /* 81 cons  */
659        .long _SPgvset /* 82 istruct  */
660        .long local_label(misc_set_invalid) /* 83 imm  */
661        .long local_label(misc_set_invalid) /* 84 odd_fixnum  */
662        .long local_label(misc_set_invalid) /* 85 tra  */
663        .long local_label(misc_set_invalid) /* 86 misc  */
664        .long local_label(misc_set_invalid) /* 87 immheader  */
665        .long local_label(misc_set_invalid) /* 88 even_fixnum  */
666        .long local_label(misc_set_invalid) /* 89 cons  */
667        .long _SPgvset /* 8a value_cell  */
668        .long local_label(misc_set_invalid) /* 8b imm  */
669        .long local_label(misc_set_invalid) /* 8c odd_fixnum  */
670        .long local_label(misc_set_invalid) /* 8d tra  */
671        .long local_label(misc_set_invalid) /* 8e misc  */
672        .long local_label(misc_set_invalid) /* 8f immheader  */
673        /* 90-9*/
674        .long local_label(misc_set_invalid) /* 90 even_fixnum  */
675        .long local_label(misc_set_invalid) /* 91 cons  */
676        .long _SPgvset /* 92 xfunction  */
677        .long local_label(misc_set_invalid) /* 93 imm  */
678        .long local_label(misc_set_invalid) /* 94 odd_fixnum  */
679        .long local_label(misc_set_invalid) /* 95 tra  */
680        .long local_label(misc_set_invalid) /* 96 misc  */
681        .long local_label(misc_set_invalid) /* 97 immheader  */
682        .long local_label(misc_set_invalid) /* 98 even_fixnum  */
683        .long local_label(misc_set_invalid) /* 99 cons  */
684        .long _SPgvset /* 9a arrayH  */
685        .long local_label(misc_set_invalid) /* 9b imm  */
686        .long local_label(misc_set_invalid) /* 9c odd_fixnum  */
687        .long local_label(misc_set_invalid) /* 9d tra  */
688        .long local_label(misc_set_invalid) /* 9e misc  */
689        .long local_label(misc_set_invalid) /* 9f immheader  */
690        /* a0-af  */
691        .long local_label(misc_set_invalid) /* a0 even_fixnum  */
692        .long local_label(misc_set_invalid) /* a1 cons  */
693        .long _SPgvset /* a2 vectorH  */
694        .long local_label(misc_set_invalid) /* a3 imm  */
695        .long local_label(misc_set_invalid) /* a4 odd_fixnum  */
696        .long local_label(misc_set_invalid) /* a5 tra  */
697        .long local_label(misc_set_invalid) /* a6 misc  */
698        .long local_label(misc_set_single_float_vector) /* a7 sf_vector  */
699        .long local_label(misc_set_invalid) /* a8 even_fixnum  */
700        .long local_label(misc_set_invalid) /* a9 cons  */
701        .long _SPgvset /* aa simple_vector  */
702        .long local_label(misc_set_invalid) /* ab imm  */
703        .long local_label(misc_set_invalid) /* ac odd_fixnum  */
704        .long local_label(misc_set_invalid) /* ad tra  */
705        .long local_label(misc_set_invalid) /* ae misc  */
706        .long local_label(misc_set_u32) /* af u32  */
707        /* b0-bf  */
708        .long local_label(misc_set_invalid) /* b0 even_fixnum  */
709        .long local_label(misc_set_invalid) /* b1 cons  */
710        .long local_label(misc_set_invalid) /* b2 nodeheader  */
711        .long local_label(misc_set_invalid) /* b3 imm  */
712        .long local_label(misc_set_invalid) /* b4 odd_fixnum  */
713        .long local_label(misc_set_invalid) /* b5 tra  */
714        .long local_label(misc_set_invalid) /* b6 misc  */
715        .long local_label(misc_set_s32) /* b7 s32  */
716        .long local_label(misc_set_invalid) /* b8 even_fixnum  */
717        .long local_label(misc_set_invalid) /* b9 cons  */
718        .long local_label(misc_set_invalid) /* ba nodeheader  */
719        .long local_label(misc_set_invalid) /* bb imm  */
720        .long local_label(misc_set_invalid) /* bc odd_fixnum  */
721        .long local_label(misc_set_invalid) /* bd tra  */
722        .long local_label(misc_set_invalid) /* be misc  */
723        .long local_label(misc_set_fixnum_vector) /* bf fixnum_vector  */
724        /* c0-cf  */
725        .long local_label(misc_set_invalid) /* c0 even_fixnum  */
726        .long local_label(misc_set_invalid) /* c1 cons  */
727        .long local_label(misc_set_invalid) /* c2 nodeheader  */
728        .long local_label(misc_set_invalid) /* c3 imm  */
729        .long local_label(misc_set_invalid) /* c4 odd_fixnum  */
730        .long local_label(misc_set_invalid) /* c5 tra  */
731        .long local_label(misc_set_invalid) /* c6 misc  */
732        .long local_label(misc_set_string) /* c7 simple_base_string  */
733        .long local_label(misc_set_invalid) /* c8 even_fixnum  */
734        .long local_label(misc_set_invalid) /* c9 cons  */
735        .long local_label(misc_set_invalid) /* ca nodeheader  */
736        .long local_label(misc_set_invalid) /* cb imm  */
737        .long local_label(misc_set_invalid) /* cc odd_fixnum  */
738        .long local_label(misc_set_invalid) /* cd tra  */
739        .long local_label(misc_set_invalid) /* ce misc  */
740        .long local_label(misc_set_u8) /* cf u8  */
741        /* d0-df  */
742        .long local_label(misc_set_invalid) /* d0 even_fixnum  */
743        .long local_label(misc_set_invalid) /* d1 cons  */
744        .long local_label(misc_set_invalid) /* d2 nodeheader  */
745        .long local_label(misc_set_invalid) /* d3 imm  */
746        .long local_label(misc_set_invalid) /* d4 odd_fixnum  */
747        .long local_label(misc_set_invalid) /* d5 tra  */
748        .long local_label(misc_set_invalid) /* d6 misc  */
749        .long local_label(misc_set_s8)      /* d7 s8  */
750        .long local_label(misc_set_invalid) /* d8 even_fixnum  */
751        .long local_label(misc_set_invalid) /* d9 cons  */
752        .long local_label(misc_set_invalid) /* da nodeheader  */
753        .long local_label(misc_set_invalid) /* db imm  */
754        .long local_label(misc_set_invalid) /* dc odd_fixnum  */
755        .long local_label(misc_set_invalid) /* dd tra  */
756        .long local_label(misc_set_invalid) /* de misc  */
757        .long local_label(misc_set_invalid) /* df immheader  */
758        /* e0-ef  */
759        .long local_label(misc_set_invalid) /* e0 even_fixnum  */
760        .long local_label(misc_set_invalid) /* e1 cons  */
761        .long local_label(misc_set_invalid) /* e2 nodeheader  */
762        .long local_label(misc_set_invalid) /* e3 imm  */
763        .long local_label(misc_set_invalid) /* e4 odd_fixnum  */
764        .long local_label(misc_set_invalid) /* e5 tra  */
765        .long local_label(misc_set_invalid) /* e6 misc  */
766        .long local_label(misc_set_u16) /* e7 u16  */
767        .long local_label(misc_set_invalid) /* e8 even_fixnum  */
768        .long local_label(misc_set_invalid) /* e9 cons  */
769        .long local_label(misc_set_invalid) /* ea nodeheader  */
770        .long local_label(misc_set_invalid) /* eb imm  */
771        .long local_label(misc_set_invalid) /* ec odd_fixnum  */
772        .long local_label(misc_set_invalid) /* ed tra  */
773        .long local_label(misc_set_invalid) /* ee misc  */
774        .long local_label(misc_set_s16) /* ef s16  */
775        /* f0-ff  */
776        .long local_label(misc_set_invalid) /* f0 even_fixnum  */
777        .long local_label(misc_set_invalid) /* f1 cons  */
778        .long local_label(misc_set_invalid) /* f2 nodeheader  */
779        .long local_label(misc_set_invalid) /* f3 imm  */
780        .long local_label(misc_set_invalid) /* f4 odd_fixnum  */
781        .long local_label(misc_set_invalid) /* f5 tra  */
782        .long local_label(misc_set_invalid) /* f6 misc  */
783        .long local_label(misc_set_double_float_vector) /* f7 df vector  */
784        .long local_label(misc_set_invalid) /* f8 even_fixnum  */
785        .long local_label(misc_set_invalid) /* f9 cons  */
786        .long local_label(misc_set_invalid) /* fa nodeheader  */
787        .long local_label(misc_set_invalid) /* fb imm  */
788        .long local_label(misc_set_invalid) /* fc odd_fixnum  */
789        .long local_label(misc_set_invalid) /* fd tra  */
790        .long local_label(misc_set_invalid) /* fe misc  */
791        .long local_label(misc_set_bit_vector) /* ff bit_vector  */
792
793local_label(misc_set_function):
794        /* Functions are funny: the first N words are treated as */
795        /* (UNSIGNED-BYTE 32), where N is the low 16 bits of the first word. */
796        __(movzwl misc_data_offset(%temp0),%imm0)
[12374]797        /* XXX bootstrapping */
798        __(btr $15,%imm0)
799        __(jnc 0f)
800        __(movl $0xffffff00,%temp1)
801        __(andl misc_header_offset(%temp0),%temp1)
802        __(shr $num_subtag_bits-fixnumshift,%temp1)
[8647]803        __(shl $fixnumshift,%imm0)
[12374]804        __(subl %imm0,%temp1)
805        __(movl %temp1,%imm0)
806        __(shr $fixnumshift,%imm0)
8070:
808        __(shl $fixnumshift,%imm0)
[8647]809        __(rcmpl(%arg_y,%imm0))
810        __(jae _SPgvset)
811local_label(misc_set_u32):
812        /* Either a non-negative fixnum, a positive one-digit bignum, or */
813        /* a two-digit bignum whose sign-digit is 0 is OK. */
814        __(movl $~(target_most_positive_fixnum <<fixnumshift),%imm0)
815        __(test %arg_z,%imm0)
816        __(movl %arg_z,%imm0)
817        __(jne 1f)
818        __(sarl $fixnumshift,%imm0)
819        __(jmp 9f)
8201:      __(andb $tagmask,%imm0_b)
821        __(cmpb $tag_misc,%imm0_b)
822        __(jne local_label(misc_set_bad))
823        __(movb misc_subtag_offset(%arg_z),%imm0_b)
824        __(cmpb $subtag_bignum,%imm0_b)
825        __(jne local_label(misc_set_bad))
826        __(movl misc_header_offset(%arg_z),%imm0)
827        __(cmpl $two_digit_bignum_header,%imm0)
828        __(je 3f)
829        __(cmpl $one_digit_bignum_header,%imm0)
830        __(jne local_label(misc_set_bad))
831        __(movl misc_data_offset(%arg_z),%imm0)
832        __(testl %imm0,%imm0)
833        __(js local_label(misc_set_bad))
834        __(jmp 9f)
8353:      __(movl misc_data_offset(%arg_z),%imm0)
836        __(cmpl $0,misc_data_offset+4(%arg_z))
837        __(jne local_label(misc_set_bad))
8389:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
[8068]839        __(ret)
[8647]840local_label(misc_set_s32):
841        __(unbox_fixnum(%arg_z,%imm0))
842        __(testb $fixnummask,%arg_z_b)
843        __(je 9f)
8441:      __(movb %arg_z_b,%imm0_b)
845        __(andb $tagmask,%imm0_b)
846        __(cmpb $tag_misc,%imm0_b)
847        __(jne local_label(misc_set_bad))
848        __(movl misc_header_offset(%arg_z),%imm0)
849        __(cmpl $one_digit_bignum_header,%imm0)
850        __(jne local_label(misc_set_bad))
851        __(movl misc_data_offset(%arg_z),%imm0)
8529:      __(movl %imm0,misc_data_offset(%temp0,%arg_y))
853        __(ret)
854local_label(misc_set_bad):
855        __(movl %arg_z,%arg_y)
856        __(movl %temp0,%arg_z)
[11449]857        __(pop %temp1)  /* return addr */
[8647]858        __(push $reserved_frame_marker)
859        __(push $reserved_frame_marker)
860        __(push $XNOTELT)
[11449]861        __(push %temp1)
[8647]862        __(set_nargs(3))
863        __(jmp _SPksignalerr)
864local_label(misc_set_single_float_vector):
865        __(extract_lisptag(%arg_z,%imm0))
866        __(cmpb $tag_misc,%imm0_b)
867        __(jne local_label(misc_set_bad))
868        __(movb misc_subtag_offset(%arg_z),%imm0_b)
869        __(cmpb $subtag_single_float,%imm0_b)
870        __(jne local_label(misc_set_bad))
871        __(movl single_float.value(%arg_z),%imm0)
872        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
873        __(ret)
874local_label(misc_set_double_float_vector):
875        __(extract_lisptag(%arg_z,%imm0))
876        __(cmpb $tag_misc,%imm0_b)
877        __(jne local_label(misc_set_bad))
878        __(movb misc_subtag_offset(%arg_z),%imm0_b)
879        __(cmpb $subtag_double_float,%imm0_b)
880        __(jne local_label(misc_set_bad))
881        __(movsd double_float.value(%arg_z),%fp0)
[9721]882        __(movsd %fp0,misc_dfloat_offset(%temp0,%arg_y,2))
[8647]883        __(ret)
884local_label(misc_set_fixnum_vector):
885        __(unbox_fixnum(%arg_z,%imm0))
886        __(testb $fixnummask,%arg_z_b)
887        __(jne local_label(misc_set_bad))
888        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
889        __(ret)
890local_label(misc_set_u8):
891        __(testl $~(0xff<<fixnumshift),%arg_z)
892        __(jne local_label(misc_set_bad))
893        __(unbox_fixnum(%arg_y,%imm0))
894        __(movl %arg_z,%arg_y)
895        __(shll $8-fixnumshift,%arg_z)
896        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
897        __(movl %arg_y,%arg_z)
898        __(ret)
899local_label(misc_set_s8):
900        __(movl %arg_z,%imm0)
901        __(shll $32-(8+fixnumshift),%imm0)
902        __(sarl $32-(8+fixnumshift),%imm0)
903        __(cmpl %arg_z,%imm0)
904        __(jne local_label(misc_set_bad))
905        __(testb $fixnummask,%arg_z_b)
906        __(jne local_label(misc_set_bad))
907        __(unbox_fixnum(%arg_y,%imm0))
908        __(movl %arg_z,%arg_z)
909        __(shll $8-fixnumshift,%arg_z)
910        __(movb %arg_z_bh,misc_data_offset(%temp0,%imm0))
911        __(movl %arg_y,%arg_z)
912        __(ret)
913local_label(misc_set_string):
914        __(cmpb $subtag_character,%arg_z_b)
915        __(jne local_label(misc_set_bad))
916        __(movl %arg_z,%imm0)
917        __(shrl $charcode_shift,%imm0)
918        __(movl %imm0,misc_data_offset(%temp0,%arg_y))
919        __(ret)
920local_label(misc_set_u16):
921        __(testl $~(0xffff<<fixnumshift),%arg_z)
922        __(jne local_label(misc_set_bad))
923        __(movl %arg_y,%imm0)
924        __(shrl $1,%imm0)
[9676]925        __(mark_as_imm(%temp1))
926        __(unbox_fixnum(%arg_z,%temp1))
927        __(movw %temp1_w,misc_data_offset(%temp0,%imm0))
928        __(mark_as_node(%temp1))
[8647]929        __(ret)
930local_label(misc_set_s16):
931        __(movl %arg_z,%imm0)
932        __(shll $32-(16+fixnumshift),%imm0)
933        __(sarl $32-(16+fixnumshift),%imm0)
934        __(cmpl %arg_z,%imm0)
935        __(jne local_label(misc_set_bad))
936        __(testb $fixnummask,%arg_z_b)
937        __(jne local_label(misc_set_bad))
938        __(movl %arg_y,%imm0)
939        __(shrl $1,%imm0)
[9676]940        __(mark_as_imm(%temp1))
941        __(unbox_fixnum(%arg_z,%temp1))
942        __(movw %temp1_w,misc_data_offset(%temp0,%imm0))
943        __(mark_as_node(%temp1))
[8647]944        __(ret)
945local_label(misc_set_bit_vector):
946        __(testl $~fixnumone,%arg_z)
947        __(jne local_label(misc_set_bad))
948        __(unbox_fixnum(%arg_y,%imm0))
949        __(testb %arg_z_b,%arg_z_b)
950        __(je local_label(misc_set_clr_bit))
951local_label(misc_set_set_bit):
952        __(btsl %imm0,misc_data_offset(%temp0))
953        __(ret)
954local_label(misc_set_clr_bit):
955        __(btrl %imm0,misc_data_offset(%temp0))
956        __(ret)
957local_label(misc_set_invalid):
[11449]958        __(pop %temp1)  /* return addr */
[8647]959        __(push $reserved_frame_marker)
960        __(push $reserved_frame_marker)
961        __(push $XSETBADVEC)
962        __(push %temp0)
[11449]963        __(push %temp1)
[8647]964        __(set_nargs(4))
965        __(jmp _SPksignalerr)
[8068]966_endfn(C(misc_set_common))
967
968_spentry(Fret1valn)
969        .globl C(ret1valn)
970__(tra(C(ret1valn)))
971        __(mov (%esp),%ra0)
972        __(mov %arg_z,(%esp))
973        __(set_nargs(1))
974        __(jmp *%ra0)
975_endsubp(Fret1valn)
976
977_spentry(nvalret)
[8647]978        .globl C(nvalret)
[8068]979C(nvalret):
[8635]980        __(ref_global(ret1val_addr,%temp0))
981        __(cmpl lisp_frame.savera0(%ebp),%temp0)
982        __(je 1f)
983        __(test %nargs,%nargs)
984        __(movl $nil_value,%arg_z)
985        __(cmovnel -node_size(%esp,%nargs),%arg_z)
[8068]986        __(leave)
987        __(ret)
[8635]988
989/* actually need to return values; always need to copy. */
9901:      __(lea 2*node_size(%ebp),%imm0)
991        __(pushl (%imm0))
992        __(movl 0(%ebp),%ebp)
993        __(addl $node_size,%imm0)
994        __(lea node_size(%esp,%nargs),%temp0)
995        __(xorl %arg_y,%arg_y)
996        __(jmp 3f)
9972:      __(movl -node_size(%temp0),%arg_z)
998        __(subl $node_size,%temp0)
999        __(addl $node_size,%arg_y)
1000        __(movl %arg_z,-node_size(%imm0))
1001        __(subl $node_size,%imm0)
10023:      __(cmpl %arg_y,%nargs)
1003        __(jne 2b)
1004        __(pop %ra0)
1005        __(movl %imm0,%esp)
1006        __(jmp *%ra0)
[8068]1007_endsubp(nvalret)
1008
1009_spentry(jmpsym)
1010        __(jump_fname())
1011_endsubp(jmpsym)
1012
1013_spentry(jmpnfn)
1014        __(mov %temp0,%fn)
1015        __(jmp *%fn)
1016_endsubp(jmpnfn)
1017
1018_spentry(funcall)
1019        __(do_funcall())
1020_endsubp(funcall)
1021
[7267]1022/* Make a lisp integer (fixnum or one-digit bignum) from the value in %imm0 */
1023_spentry(makes32)
[8253]1024        __(imull $fixnumone,%imm0,%arg_z)       /* result is fixnum-tagged */
1025        __(jno 0f)                              /* but may have overflowed */
[7267]1026        __(movd %imm0,%mm1)
1027        __(movl $one_digit_bignum_header,%imm0)
1028        __(movd %imm0,%mm0)
1029        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
1030        __(movd %mm1,misc_data_offset(%arg_z))
[7286]10310:      __(repret)
[7267]1032_endsubp(makes32)
[8068]1033
[8834]1034/* Make a lisp integer out of the unboxed 64-bit word in %mm0. */
1035/* This is a little clumsy, but the alternative requires callers to */
1036/* have already marked %edx as an imm reg (or else store it in memory
1037/* somewhere), and I'm nervous about */
1038/* splitting up the mark-as-imm/mark-as-node between two separate */
1039/* pieces of code. */
[8068]1040_spentry(makes64)
[8834]1041        __(movq %mm0,%mm2)
1042        __(pshufw $0x4e,%mm0,%mm1)      /* swap hi/lo halves */
1043        __(psrad $31,%mm0)      /* propagate sign */
1044        __(pcmpeqd %mm0,%mm1)   /* all ones if equal */
1045        __(movd %mm1,%imm0)
1046        __(cmpb $-1,%imm0_b)    /* upper half just sign extension? */
1047        __(jne 1f)
1048        __(movd %mm2,%imm0)
[8823]1049        __(jmp _SPmakes32)
[8834]10501:      __(movl $two_digit_bignum_header,%imm0)
1051        __(movd %imm0,%mm0)
1052        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
1053        __(movq %mm2,misc_data_offset(%arg_z))
1054        __(ret)
[8647]1055_endsubp(makes64)
[8068]1056
[8834]1057_spentry(syscall)
1058        /* Save lisp registers */
1059        __(push %ebp)
1060        __(movl %esp,%ebp)
1061        __(push %temp0)
1062        __(push %temp1)
1063        __(push %arg_y)
1064        __(push %arg_z)
1065        __(push %fn)
[10092]1066        __(movl %esp,rcontext(tcr.save_vsp))
1067        __(movl %ebp,rcontext(tcr.save_ebp))
1068        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
1069        __(movl rcontext(tcr.foreign_sp),%esp)
[8834]1070        __(emms)
1071        __(pop %ebp)            /* backlink */
[10558]1072        __(lea 15(%esp),%edx)
1073        __(andl $-16,%edx)
1074        __(movl %edx,%esp)
[8834]1075        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1076        __(movl $local_label(back_from_sysenter),%edx)
1077        __(push %edx)
1078        __(movl %esp,%ecx)
1079        __(sysenter)
1080local_label(back_from_sysenter):
1081        __(jnc 0f)
1082        __(neg %eax)
10830:     
1084        __(movl %ebp,%esp)
[10092]1085        __(movl %esp,rcontext(tcr.foreign_sp))
1086        __(clr %arg_z)
1087        __(clr %arg_y)
1088        __(clr %temp1)
1089        __(clr %temp0)
1090        __(clr %fn)
[8834]1091        __(pxor %fpzero,%fpzero)
[10092]1092        __(movl rcontext(tcr.save_vsp),%esp)
1093        __(movl rcontext(tcr.save_ebp),%ebp)
1094        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
[8834]1095        __(pop %fn)
1096        __(pop %arg_z)
1097        __(pop %arg_y)
1098        __(pop %temp1)
1099        __(check_pending_interrupt(%temp0))
[8899]1100        __(pop %temp0)
[8834]1101        __(leave)
[7267]1102        __(ret)
[8834]1103_endsubp(syscall)
[7286]1104
[8834]1105/* Make system call that returns a doubleword result in %edx:%eax and */
1106/* copy the result into %mm0. */
1107_spentry(syscall2)
[8068]1108        /* Save lisp registers */
1109        __(push %ebp)
1110        __(movl %esp,%ebp)
1111        __(push %temp0)
1112        __(push %temp1)
1113        __(push %arg_y)
1114        __(push %arg_z)
1115        __(push %fn)
[10092]1116        __(movl %esp,rcontext(tcr.save_vsp))
1117        __(movl %ebp,rcontext(tcr.save_ebp))
1118        __(movl $TCR_STATE_FOREIGN,rcontext(tcr.valence))
1119        __(movl rcontext(tcr.foreign_sp),%esp)
[8068]1120        __(emms)
[8828]1121        __(pop %ebp)            /* backlink */
[10558]1122        __(lea 15(%esp),%edx)
1123        __(andl $-16,%edx)
1124        __(movl %edx,%esp)
[8823]1125        __(unbox_fixnum(%arg_z,%eax))   /* syscall number */
1126        __(pushl $local_label(back_from_syscall))
1127        __(int $0x80)
1128local_label(back_from_syscall):
1129        __(jnc 0f)
1130        __(neg %eax)
[8834]1131        __(movl $-1,%edx)
11320:
1133        /* just use memory rather than screwing around with */
1134        /* movd %eax,%mm0, movd %edx,%mm1, psllq $32,%mm1, por %mm1,%mm0 */
1135        __(push %edx)
1136        __(push %eax)
1137        __(movq (%esp),%mm0)
[8823]1138        __(movl %ebp,%esp)
[10092]1139        __(movl %esp,rcontext(tcr.foreign_sp))
1140        __(clr %arg_z)
1141        __(clr %arg_y)
1142        __(clr %temp1)
1143        __(clr %temp0)
1144        __(clr %fn)
[8068]1145        __(pxor %fpzero,%fpzero)
[10092]1146        __(movl rcontext(tcr.save_vsp),%esp)
1147        __(movl rcontext(tcr.save_ebp),%ebp)
1148        __(movl $TCR_STATE_LISP,rcontext(tcr.valence))
[8068]1149        __(pop %fn)
1150        __(pop %arg_z)
1151        __(pop %arg_y)
1152        __(pop %temp1)
1153        __(check_pending_interrupt(%temp0))
[8899]1154        __(pop %temp0)
[8068]1155        __(leave)
[7286]1156        __(ret)
[8834]1157_endsubp(syscall2)
[8068]1158
[8834]1159
[8068]1160_spentry(mkcatch1v)
1161        __(nMake_Catch(0))
[7286]1162        __(ret)
[8068]1163_endsubp(mkcatch1v)
[7358]1164
[8068]1165_spentry(mkunwind)
[9301]1166        __(movl $undefined,%arg_z)
1167        __(Make_Catch(fixnumone))
1168        __(jmp *%ra0)
[8068]1169_endsubp(mkunwind)
[8647]1170
[8068]1171/* this takes a return address in %ra0; it's "new" in that it does the */
1172/*   double binding of *interrupt-level* out-of-line */
1173_spentry(nmkunwind)
[10092]1174        __(movl rcontext(tcr.tlb_pointer),%arg_z)
[8253]1175        __(movl INTERRUPT_LEVEL_BINDING_INDEX(%arg_z),%arg_y)
1176        __(push %arg_y)
1177        __(push $INTERRUPT_LEVEL_BINDING_INDEX)
[10092]1178        __(push rcontext(tcr.db_link))
1179        __(movl %esp,rcontext(tcr.db_link))
[8253]1180        __(movl $-1<<fixnumshift,INTERRUPT_LEVEL_BINDING_INDEX(%arg_z))
1181        __(movl $undefined,%arg_z)
1182        /* %arg_z = tag, %xfn (%temp1) = pc */
1183        __(Make_Catch(fixnumone))
1184        __(movl %arg_y,%arg_z)
1185        __(jmp _SPbind_interrupt_level)
[8068]1186_endsubp(nmkunwind)
1187
1188_spentry(mkcatchmv)
[9128]1189        __(nMake_Catch(fixnumone))
1190        __(ret)
[8068]1191_endsubp(mkcatchmv)
1192
1193_spentry(throw)
[10092]1194        __(movl rcontext(tcr.catch_top),%imm0)
[9301]1195        __(movl (%esp,%nargs),%arg_y)   /* arg_y = tag   */
1196        __(movd %nargs,%mm0)
1197        __(xorl %temp1,%temp1)
1198        __(jmp local_label(_throw_test))
1199local_label(_throw_loop):
1200        __(cmpl %arg_y,catch_frame.catch_tag(%imm0))
1201        __(je local_label(_throw_found))
1202        __(movl catch_frame.link(%imm0),%imm0)
1203        __(addl $fixnum_one,%temp1)
1204local_label(_throw_test):
1205        __(test %imm0,%imm0)
1206        __(jne local_label(_throw_loop))
1207        __(push %ra0)
[9676]1208        __(uuo_error_reg_not_tag(Rarg_y,subtag_catch_frame))
[9301]1209        __(pop %ra0)
1210        __(jmp _SPthrow)
1211local_label(_throw_found):
1212        __(testb $fulltagmask,catch_frame.mvflag(%imm0))
1213        __(movl %temp1,%imm0)
1214        __(movd %mm0,%nargs)
1215        __(jne local_label(_throw_multiple))
[9676]1216        __(movl $nil_value,%arg_z)
[9301]1217        __(test %nargs,%nargs)
1218        __(je local_label(_throw_one_value))
1219        __(movl -node_size(%esp,%nargs),%arg_z)
1220        __(add %nargs,%esp)
1221local_label(_throw_one_value):
1222        __(movl $local_label(_threw_one_value),%ra0)
1223        __(jmp _SPnthrow1value)
1224__(tra(local_label(_threw_one_value)))
[10092]1225        __(movl rcontext(tcr.catch_top),%arg_y)
[9301]1226        __(movl catch_frame.db_link(%arg_y),%imm0)
[10092]1227        __(cmpl %imm0,rcontext(tcr.db_link))
[9301]1228        __(jz local_label(_threw_one_value_dont_unbind))
1229        __(push $local_label(_threw_one_value_dont_unbind))
1230        __(jmp _SPunbind_to)    /* preserves registers */
1231__(tra(local_label(_threw_one_value_dont_unbind)))
1232        __(movl catch_frame.ebp(%arg_y),%ebp)
1233        __(movl catch_frame.foreign_sp(%arg_y),%imm0)
[10092]1234        __(movl %imm0,rcontext(tcr.foreign_sp))
[9301]1235        __(movl catch_frame.xframe(%arg_y),%imm0)
[10092]1236        __(movl %imm0,rcontext(tcr.xframe))
[9301]1237        __(movl catch_frame.esp(%arg_y),%esp)
1238        __(movl catch_frame.link(%arg_y),%imm0)
[10092]1239        __(movl %imm0,rcontext(tcr.catch_top))
[9301]1240        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%arg_y),%imm0)
1241        __(movl (%imm0),%imm0)
[10092]1242        __(movl %imm0,rcontext(tcr.save_tsp))
1243        __(movl %imm0,rcontext(tcr.next_tsp))
[9301]1244        __(movl catch_frame.pc(%arg_y),%ra0)
1245        __(jmp *%ra0)
1246local_label(_throw_multiple):
1247        __(movl $local_label(_threw_multiple),%ra0)
1248        __(jmp _SPnthrowvalues)
1249__(tra(local_label(_threw_multiple)))
[10092]1250        __(movl rcontext(tcr.catch_top),%arg_y)
[9301]1251        __(movl catch_frame.db_link(%arg_y),%imm0)
[10092]1252        __(cmpl %imm0,rcontext(tcr.db_link))
[9301]1253        __(je local_label(_threw_multiple_dont_unbind))
1254        __(push $local_label(_threw_multiple_dont_unbind))
1255        __(jmp _SPunbind_to)    /* preserves registers */
1256__(tra(local_label(_threw_multiple_dont_unbind)))
1257        /* Copy multiple values from the current %esp to the target %esp   */
1258        __(lea (%esp,%nargs),%imm0)
1259        __(movd %nargs,%mm0)    /* nargs is aka temp1 */
1260        __(movl catch_frame.esp(%arg_y),%temp1)
1261        __(jmp local_label(_threw_multiple_push_test))
1262local_label(_threw_multiple_push_loop):
1263        __(subl $node_size,%imm0)
1264        __(subl $node_size,%temp1)
1265        __(movl (%imm0),%arg_z)
1266        __(movl %arg_z,(%temp1))
1267local_label(_threw_multiple_push_test):
1268        __(cmpl %imm0,%esp)
1269        __(jne local_label(_threw_multiple_push_loop))
1270        /* target %esp is now in %temp1   */
1271        __(movl catch_frame.ebp(%arg_y),%ebp)
1272        __(movl catch_frame.foreign_sp(%arg_y),%imm0)
[10092]1273        __(movl %imm0,rcontext(tcr.foreign_sp))       
[9301]1274        __(movl catch_frame.xframe(%arg_y),%imm0)
[10092]1275        __(movl %imm0,rcontext(tcr.xframe))
[9301]1276        __(movl %temp1,%esp)
1277        __(movl catch_frame.link(%arg_y),%temp1)
[10092]1278        __(movl %temp1,rcontext(tcr.catch_top))
[9301]1279        __(movd %mm0,%nargs)
1280        __(lea -(tsp_frame.fixed_overhead+fulltag_misc)(%arg_y),%imm0)
1281        __(movl catch_frame.pc(%arg_y),%ra0)
1282        __(movl (%imm0),%imm0)
[10092]1283        __(movl %imm0,rcontext(tcr.save_tsp))
1284        __(movl %imm0,rcontext(tcr.next_tsp))
[9301]1285        __(jmp *%ra0)
[8068]1286_endsubp(throw)
1287
[8686]1288        /* This takes N multiple values atop the vstack.   */
[8068]1289_spentry(nthrowvalues)
[10092]1290        __(movb $1,rcontext(tcr.unwinding))
1291        __(movl %ra0,rcontext(tcr.save0)) /* %ra0 (aka %temp0) to spill area */
[8686]1292local_label(_nthrowv_nextframe):
1293        __(subl $fixnumone,%imm0)
1294        __(js local_label(_nthrowv_done))
1295        __(movd %imm0,%mm1)
[10092]1296        __(movl rcontext(tcr.catch_top),%temp0)
[8686]1297        __(movl catch_frame.link(%temp0),%imm0)
[10092]1298        __(movl %imm0,rcontext(tcr.catch_top))
[8686]1299        __(movl catch_frame.db_link(%temp0),%imm0)
[10092]1300        __(cmpl %imm0,rcontext(tcr.db_link))
[8686]1301        __(jz local_label(_nthrowv_dont_unbind))
1302        __(push %temp1)
1303        __(push %temp0)
1304        __(push $local_label(_nthrowv_back_from_unbind))
1305        __(jmp _SPunbind_to)
1306__(tra(local_label(_nthrowv_back_from_unbind)))
1307        __(pop %temp0)
1308        __(pop %temp1)
1309local_label(_nthrowv_dont_unbind):
1310        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp0))
1311        __(je local_label(_nthrowv_do_unwind))
1312/* A catch frame.  If the last one, restore context from there.   */
1313        __(movd %mm1,%imm0)
1314        __(test %imm0,%imm0)    /* last catch frame ?   */
1315        __(jne local_label(_nthrowv_skip))
1316        __(movl catch_frame.xframe(%temp0),%arg_y)
[10092]1317        __(movl %arg_y,rcontext(tcr.xframe))
[8686]1318        __(lea (%esp,%nargs),%arg_y)
1319        __(movl catch_frame.esp(%temp0),%arg_z)
1320        __(movd %nargs,%mm2)
1321        __(jmp local_label(_nthrowv_push_test))
1322local_label(_nthrowv_push_loop):
1323        __(subl $node_size,%arg_y)
1324        __(subl $node_size,%arg_z)
1325        __(movd (%arg_y),%mm0)
1326        __(movd %mm0,(%arg_z))
1327local_label(_nthrowv_push_test):
1328        __(subl $node_size,%nargs)
1329        __(jns local_label(_nthrowv_push_loop))
1330        __(movd %mm2,%nargs)
1331        __(movl catch_frame.xframe(%temp0),%arg_y)
[10092]1332        __(movl %arg_y,rcontext(tcr.xframe))
[8686]1333        __(movl %arg_z,%esp)
1334        __(movl catch_frame.ebp(%temp0),%ebp)
1335        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
[10092]1336        __(movd %stack_temp,rcontext(tcr.foreign_sp))       
[8686]1337local_label(_nthrowv_skip):     
1338        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
[10092]1339        __(movl %imm0,rcontext(tcr.save_tsp))
1340        __(movl %imm0,rcontext(tcr.next_tsp))
[8686]1341        __(movd %mm1,%imm0)
1342        __(jmp local_label(_nthrowv_nextframe))
1343local_label(_nthrowv_do_unwind):       
1344/* This is harder.  Call the cleanup code with the multiple values and   */
1345/* nargs, the throw count, and the caller's return address in a temp  */
1346/* stack frame.   */
1347        __(leal (%esp,%nargs),%arg_y)
1348        __(push catch_frame.pc(%temp0))
1349        __(movl catch_frame.ebp(%temp0),%ebp)
1350        __(movd catch_frame.xframe(%temp0),%stack_temp)
[10092]1351        __(movd %stack_temp,rcontext(tcr.xframe))
[8686]1352        __(movl catch_frame.esp(%temp0),%arg_z)
1353        __(movd catch_frame.foreign_sp(%temp0),%stack_temp)
[10092]1354        __(movd %stack_temp,rcontext(tcr.foreign_sp))       
[8686]1355        /* Discard the catch frame, so we can build a temp frame   */
1356        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp0),%imm0)
[10092]1357        __(movl %imm0,rcontext(tcr.save_tsp))
1358        __(movl %imm0,rcontext(tcr.next_tsp))
[8835]1359        __(movd %temp1,%mm2) /* save %nargs */
[8686]1360        /* tsp overhead, nargs, throw count, ra0   */
1361        __(dnode_align(%nargs,(tsp_frame.fixed_overhead+(3*node_size)),%imm0))
1362        __(movl %imm0,%temp1)
1363        __(TSP_Alloc_Var(%temp1,%imm0))
1364        __(movd %mm2,%temp1) /* aka %nargs */
1365
1366        __(movl %nargs,(%imm0))
[10092]1367        __(movl rcontext(tcr.save0),%ra0)
[8686]1368        __(movl %ra0,node_size(%imm0))
1369        __(movd %mm1,node_size*2(%imm0))
1370        __(leal node_size*3(%imm0),%imm0)
1371        __(jmp local_label(_nthrowv_tpushtest))
1372local_label(_nthrowv_tpushloop):
1373        __(movl -node_size(%arg_y),%temp0)
1374        __(subl $node_size,%arg_y)
1375        __(movl %temp0,(%imm0))
1376        __(addl $node_size,%imm0)
1377local_label(_nthrowv_tpushtest):
1378        __(subl $node_size,%nargs)
1379        __(jns local_label(_nthrowv_tpushloop))
1380        __(pop %xfn)    /* aka %temp1/%nargs */
1381        __(movl %arg_z,%esp)
1382/* Ready to call cleanup code. set up tra, jmp to %xfn   */
1383        __(push $local_label(_nthrowv_called_cleanup))
[10092]1384        __(movb $0,rcontext(tcr.unwinding))
[8686]1385        __(jmp *%xfn)
1386__(tra(local_label(_nthrowv_called_cleanup)))
1387
[10092]1388        __(movb $1,rcontext(tcr.unwinding))
1389        __(movl rcontext(tcr.save_tsp),%imm0)
[8686]1390        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%nargs)
1391        __(movl tsp_frame.data_offset+(1*node_size)(%imm0),%ra0)
[10092]1392        __(movl %ra0,rcontext(tcr.save0))
[8686]1393        __(movd tsp_frame.data_offset+(2*node_size)(%imm0),%mm1)
1394        __(movd %nargs,%mm2)
1395        __(addl $tsp_frame.fixed_overhead+(node_size*3),%imm0)
1396        __(jmp local_label(_nthrowv_tpoptest))
1397local_label(_nthrowv_tpoploop):
1398        __(push (%imm0))
1399        __(addl $node_size,%imm0)
1400local_label(_nthrowv_tpoptest):
1401        __(subl $node_size,%nargs)
1402        __(jns local_label(_nthrowv_tpoploop))
1403        __(movd %mm2,%nargs)
[10092]1404        __(movl rcontext(tcr.save_tsp),%imm0)
[8686]1405        __(movl (%imm0),%imm0)
[10092]1406        __(movl %imm0,rcontext(tcr.save_tsp))
1407        __(movl %imm0,rcontext(tcr.next_tsp))
[8686]1408        __(movd %mm1,%imm0)
1409        __(jmp local_label(_nthrowv_nextframe))
1410local_label(_nthrowv_done):
[10092]1411        __(movb $0,rcontext(tcr.unwinding))
[8686]1412        __(check_pending_interrupt(%imm0))
1413local_label(_nthrowv_return):
[10092]1414        __(movl rcontext(tcr.save0),%ra0)
1415        __(movss %fpzero,rcontext(tcr.save0))
[8686]1416        __(jmp *%ra0)   
[8068]1417_endsubp(nthrowvalues)
1418
1419/* This is a (slight) optimization.  When running an unwind-protect,  */
1420/* save the single value and the throw count in the tstack frame.  */
1421/* Note that this takes a single value in arg_z.  */
[8647]1422
[8068]1423_spentry(nthrow1value)
[10092]1424        __(movb $1,rcontext(tcr.unwinding))
[8350]1425local_label(_nthrow1v_nextframe):
1426        __(subl $fixnumone,%imm0)
1427        __(js local_label(_nthrow1v_done))
1428        __(movd %imm0,%mm0)
[10092]1429        __(movl rcontext(tcr.catch_top),%temp1)
[8350]1430        __(movl catch_frame.link(%temp1),%imm0)
[10092]1431        __(movl %imm0,rcontext(tcr.catch_top))
[8350]1432        __(movl catch_frame.db_link(%temp1),%imm0)
[10092]1433        __(cmpl %imm0,rcontext(tcr.db_link))
[8350]1434        __(jz local_label(_nthrow1v_dont_unbind))
1435        __(push %temp1)
1436        __(push %temp0)
1437        __(push %arg_z)
[13337]1438        __(push `$'local_label(_nthrow1v_back_from_unbind))
[8350]1439        __(jmp _SPunbind_to)
1440__(tra(local_label(_nthrow1v_back_from_unbind)))
1441        __(pop %arg_z)
1442        __(pop %temp0)
1443        __(pop %temp1)
1444local_label(_nthrow1v_dont_unbind):
1445        __(cmpb $unbound_marker,catch_frame.catch_tag(%temp1))
1446        __(je local_label(_nthrow1v_do_unwind))
1447/* A catch frame.  If the last one, restore context from there. */
1448        __(movd %mm0,%imm0)
1449        __(test %imm0,%imm0)    /* last catch frame? */
1450        __(jne local_label(_nthrow1v_skip))
1451        __(movl catch_frame.xframe(%temp1),%arg_y)
[10092]1452        __(movl %arg_y,rcontext(tcr.xframe))
[8350]1453        __(movl catch_frame.esp(%temp1),%esp)
1454        __(movl catch_frame.ebp(%temp1),%ebp)
1455        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
[10092]1456        __(movd %stack_temp,rcontext(tcr.foreign_sp))
[8350]1457local_label(_nthrow1v_skip):
1458        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
[10092]1459        __(movl %imm0,rcontext(tcr.save_tsp))
1460        __(movl %imm0,rcontext(tcr.next_tsp))
[8350]1461        __(movd %mm0,%imm0)
1462        __(jmp local_label(_nthrow1v_nextframe))
1463local_label(_nthrow1v_do_unwind):
1464/* This is harder, but not as hard (not as much BLTing) as the */
1465/* multiple-value case. */
1466        __(movl catch_frame.xframe(%temp1),%arg_y)
[10092]1467        __(movl %arg_y,rcontext(tcr.xframe))
[8350]1468        __(movl catch_frame.ebp(%temp1),%ebp)
1469        __(movl catch_frame.esp(%temp1),%esp)
1470        __(movd catch_frame.foreign_sp(%temp1),%stack_temp)
[10092]1471        __(movd %stack_temp,rcontext(tcr.foreign_sp))
[8350]1472        /* Discard the catch frame so we can build a temp frame. */
1473        __(movl -(tsp_frame.fixed_overhead+fulltag_misc)(%temp1),%imm0)
[10092]1474        __(movl %imm0,rcontext(tcr.save_tsp))
1475        __(movl %imm0,rcontext(tcr.next_tsp))
[8350]1476        __(movl catch_frame.pc(%temp1),%xfn) /* xfn is temp1 */
1477        __(TSP_Alloc_Fixed((3*node_size),%imm0))
1478        __(addl $tsp_frame.fixed_overhead,%imm0)
1479        __(movl %ra0,(%imm0))
1480        __(movd %mm0,node_size*1(%imm0))
1481        __(movl %arg_z,node_size*2(%imm0))
1482/* Ready to call cleanup code.  Set up tra, jmp to %xfn. */
1483        __(push $local_label(_nthrow1v_called_cleanup))
[10092]1484        __(movb $0,rcontext(tcr.unwinding))
[8350]1485        __(jmp *%xfn)
1486__(tra(local_label(_nthrow1v_called_cleanup)))
[10092]1487        __(movb $1,rcontext(tcr.unwinding))
1488        __(movl rcontext(tcr.save_tsp),%imm0)
[8350]1489        __(movl tsp_frame.data_offset+(0*node_size)(%imm0),%ra0)
1490        __(movd tsp_frame.data_offset+(1*node_size)(%imm0),%mm0)
1491        __(movl tsp_frame.data_offset+(2*node_size)(%imm0),%arg_z)
1492        __(movl (%imm0),%imm0)
[10092]1493        __(movl %imm0,rcontext(tcr.save_tsp))
1494        __(movl %imm0,rcontext(tcr.next_tsp))
[8350]1495        __(movd %mm0,%imm0)
1496        __(jmp local_label(_nthrow1v_nextframe))
1497local_label(_nthrow1v_done):
[10092]1498        __(movb $0,rcontext(tcr.unwinding))
[8350]1499        __(check_pending_interrupt(%imm0))
1500local_label(_nthrow1v_return):
1501        __(jmp *%ra0)
[8068]1502_endsubp(nthrow1value)
1503
1504/* This never affects the symbol's vcell   */
1505/* Non-null symbol in arg_y, new value in arg_z           */
[8647]1506
[8068]1507_spentry(bind)
[9040]1508        __(movl symbol.binding_index(%arg_y),%imm0)
[10092]1509        __(cmpl rcontext(tcr.tlb_limit),%imm0)
[9692]1510        __(jb 0f)
[9040]1511        __(push %imm0)
1512        __(tlb_too_small())
15130:      __(test %imm0,%imm0)
1514        __(jz 9f)
[10092]1515        __(movl rcontext(tcr.tlb_pointer),%temp1)
[9040]1516        __(push (%temp1,%imm0))
1517        __(push %imm0)
[10092]1518        __(push rcontext(tcr.db_link))
1519        __(movl %esp,rcontext(tcr.db_link))
[9040]1520        __(movl %arg_z,(%temp1,%imm0))
1521        __(jmp *%ra0)
15229:     
1523        __(movl %arg_y,%arg_z)
1524        __(movl $XSYMNOBIND,%arg_y)
1525        __(set_nargs(2))
1526        __(push %ra0)
1527        __(jmp _SPksignalerr)
[8068]1528_endsubp(bind)
1529
1530/* arg_z = symbol: bind it to its current value  */
[8647]1531
[8068]1532_spentry(bind_self)
[9267]1533        __(movl symbol.binding_index(%arg_z),%imm0)
[10092]1534        __(cmpl rcontext(tcr.tlb_limit),%imm0)
[9692]1535        __(jb 0f)
[9267]1536        __(push %imm0)
1537        __(tlb_too_small())
15380:      __(test %imm0,%imm0)
1539        __(jz 9f)
[10092]1540        __(movl rcontext(tcr.tlb_pointer),%temp1)
[9267]1541        __(cmpb $no_thread_local_binding_marker,(%temp1,%imm0))
1542        __(jz 2f)
1543        __(push (%temp1,%imm0))
1544        __(push %imm0)
[10092]1545        __(push rcontext(tcr.db_link))
1546        __(movl %esp,rcontext(tcr.db_link))
[9267]1547        __(jmp *%ra0)
15482:      __(movl symbol.vcell(%arg_z),%arg_y)
1549        __(push (%temp1,%imm0))
1550        __(push %imm0)
[10092]1551        __(push rcontext(tcr.db_link))
[9267]1552        __(movl %arg_y,(%temp1,%imm0))
[10092]1553        __(movl %esp,rcontext(tcr.db_link))
[9267]1554        __(jmp *%ra0)
15559:      __(movl $XSYMNOBIND,%arg_y)
1556        __(set_nargs(2))
1557        __(push %ra0)
1558        __(jmp _SPksignalerr)
[8068]1559_endsubp(bind_self)
1560
1561_spentry(bind_nil)
[9128]1562        __(movl symbol.binding_index(%arg_z),%imm0)
[10092]1563        __(cmpl rcontext(tcr.tlb_limit),%imm0)
[9692]1564        __(jb 0f)
[9128]1565        __(push %imm0)
1566        __(tlb_too_small())
15670:      __(test %imm0,%imm0)
1568        __(jz 9f)
[10092]1569        __(movl rcontext(tcr.tlb_pointer),%temp1)
[9128]1570        __(push (%temp1,%imm0))
1571        __(push %imm0)
[10092]1572        __(push rcontext(tcr.db_link))
1573        __(movl %esp,rcontext(tcr.db_link))
[9128]1574        __(movl $nil_value,(%temp1,%imm0))
1575        __(jmp *%ra0)
15769:      __(movl $XSYMNOBIND,%arg_y)
1577        __(set_nargs(2))
1578        __(push %ra0)
1579        __(jmp _SPksignalerr)
[8068]1580_endsubp(bind_nil)
1581
1582_spentry(bind_self_boundp_check)
[9267]1583        __(movl symbol.binding_index(%arg_z),%imm0)
[10092]1584        __(cmpl rcontext(tcr.tlb_limit),%imm0)
[9692]1585        __(jb 0f)
[9267]1586        __(push %imm0)
1587        __(tlb_too_small())
15880:      __(test %imm0,%imm0)
1589        __(jz 9f)
[10092]1590        __(movl rcontext(tcr.tlb_pointer),%temp1)
[9267]1591        __(cmpb $no_thread_local_binding_marker,(%temp1,%imm0))
1592        __(je 2f)
1593        __(cmpb $unbound_marker,(%temp1,%imm0))
1594        __(je 8f)
1595        __(push (%temp1,%imm0))
1596        __(push %imm0)
[10092]1597        __(push rcontext(tcr.db_link))
1598        __(movl %esp,rcontext(tcr.db_link))
[9267]1599        __(jmp *%ra0)
16002:      __(movl symbol.vcell(%arg_z),%arg_y)
1601        __(cmpl $unbound_marker,%arg_y)
1602        __(jz 8f)
1603        __(push (%temp1,%imm0))
1604        __(push %imm0)
[10092]1605        __(push rcontext(tcr.db_link))
1606        __(movl %esp,rcontext(tcr.db_link))
[9267]1607        __(movl %arg_y,(%temp1,%imm0))
1608        __(jmp *%ra0)
16098:      __(push %ra0)
1610        __(uuo_error_reg_unbound(Rarg_z))
1611       
16129:      __(movl $XSYMNOBIND,%arg_y)
1613        __(set_nargs(2))
1614        __(push %ra0)
1615        __(jmp _SPksignalerr)
[8068]1616_endsubp(bind_self_boundp_check)
1617
1618_spentry(conslist)
[8904]1619        __(movl %nargs,%imm0)
1620        __(movl %temp0,%temp1)  /* have to use temp0 for consing */
1621        __(movl $nil_value,%arg_z)
1622        __(test %imm0,%imm0)
1623        __(jmp 2f)
16241:      __(pop %arg_y)
1625        __(Cons(%arg_y,%arg_z,%arg_z))
1626        __(subl $node_size,%imm0)
16272:      __(jnz 1b)
1628        __(jmp *%temp1)
[8068]1629_endsubp(conslist)
1630
1631/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
1632/* Cons, one cons cell at at time.  Maybe optimize this later.  */
[8647]1633
[8068]1634_spentry(conslist_star)
[9135]1635        __(movl %nargs,%imm0)
1636        __(test %imm0,%imm0)
1637        __(movl %ra0,%temp1)
1638        __(jmp 2f)
16391:      __(pop %arg_y)
1640        __(Cons(%arg_y,%arg_z,%arg_z))
1641        __(subl $node_size,%imm0)
16422:      __(jnz 1b)
1643        __(jmp *%temp1)
[8068]1644_endsubp(conslist_star)
1645
[9150]1646/* We always have to create a tsp frame (even if nargs is 0), so the compiler */
1647/* doesn't get confused. */
[8068]1648_spentry(stkconslist)
[11315]1649        __(movl $nil_value,%arg_z)
1650C(stkconslist_common):               
[10092]1651        __(movl %ra0,rcontext(tcr.save0))
[9150]1652        __(movd %nargs,%mm0)
1653        __(movl %nargs,%temp0)
1654        __(addl %temp0,%temp0)
1655        __(dnode_align(%temp0,tsp_frame.fixed_overhead,%temp0))
1656        __(TSP_Alloc_Var(%temp0,%imm0))
1657        __(addl $fulltag_cons,%imm0)
1658        __(test %nargs,%nargs)
1659        __(jmp 2f)
16601:      __(pop %arg_y)
1661        __(_rplaca(%imm0,%arg_y))
1662        __(_rplacd(%imm0,%arg_z))
1663        __(movl %imm0,%arg_z)
1664        __(add $cons.size,%imm0)
1665        __(subl $node_size,%nargs)
16662:      __(jne 1b)
[10092]1667        __(movl rcontext(tcr.save0),%ra0)
1668        __(movl $0,rcontext(tcr.save0))
[9150]1669        __(jmp *%ra0)
[8068]1670_endsubp(stkconslist)
1671
1672/* do list*: last arg in arg_z, all others vpushed,   */
1673/*      nargs set to #args vpushed.  */
[8647]1674
[8068]1675_spentry(stkconslist_star)
[11315]1676        __(jmp C(stkconslist_common))
[8068]1677_endsubp(stkconslist_star)
1678
1679
1680/* Make a stack-consed simple-vector out of the NARGS objects   */
1681/*      on top of the vstack; return it in arg_z.  */
[8647]1682
[8068]1683_spentry(mkstackv)
[9267]1684        __(dnode_align(%nargs,tsp_frame.fixed_overhead+node_size,%imm0))
1685        __(TSP_Alloc_Var(%imm0,%arg_y))
1686        __(movl %nargs,%imm0)
1687        __(shll $(num_subtag_bits-fixnumshift),%imm0)
1688        __(movb $subtag_simple_vector,%imm0_b)
1689        __(movl %imm0,(%arg_y))
1690        __(leal fulltag_misc(%arg_y),%arg_z)
1691        __(test %nargs,%nargs)
1692        __(leal misc_data_offset(%arg_z,%nargs),%imm0)
1693        __(jmp 2f)
16941:      __(pop -node_size(%imm0))
1695        __(subl $node_size,%nargs)
1696        __(leal -node_size(%imm0),%imm0)
16972:      __(jne 1b)
1698        __(jmp *%ra0)   
[8068]1699_endsubp(mkstackv)
1700
1701        .globl C(egc_write_barrier_start)
1702C(egc_write_barrier_start):
1703/*  */
1704/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
1705/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
1706/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
1707/* an intergenerational reference (a young pointer stored in an old object) has  */
1708/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
1709/* This has to happen atomically, and has to happen atomically wrt GC.  */
1710
1711/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
1712/* interlocked loads and stores.  */
1713
1714/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
1715/* in the function, we can do the store (even if it's already been done) and  */
1716/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
1717/* setting the bit needs to be done atomically, unless we're sure that other  */
1718/* threads are suspended.)  */
1719/* We can unconditionally set the suspended thread's RIP to the return address.  */
1720
1721_spentry(rplaca)
1722        .globl C(egc_rplaca)
1723C(egc_rplaca):
[8686]1724        __(rcmpl(%arg_z,%arg_y))
1725        __(_rplaca(%arg_y,%arg_z))
1726        __(ja 1f)
17270:      __(repret)
17281:      __(movl %arg_y,%imm0)
[13279]1729        __(subl lisp_global(ref_base),%imm0)
[8686]1730        __(shrl $dnode_shift,%imm0)
1731        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
[15366]1732        __(jae 2f)
[9616]1733        __(ref_global(refbits,%temp0))
[8686]1734        __(xorb $31,%imm0_b)
1735        __(lock)
1736        __(btsl %imm0,(%temp0))
[15366]1737        __(xorb $31,%imm0_b)
17382:      __(cmpl lisp_global(managed_static_dnodes),%imm0)
1739        __(jae 0b)
1740        __(ref_global(managed_static_refbits,%temp0))
1741        __(xorb $31,%imm0_b)
1742        __(lock)
1743        __(btsl %imm0,(%temp0))       
[8686]1744        __(ret)
[8068]1745_endsubp(rplaca)
1746
1747_spentry(rplacd)
1748        .globl C(egc_rplacd)
1749C(egc_rplacd):
[8647]1750        __(rcmpl(%arg_z,%arg_y))
1751        __(_rplacd(%arg_y,%arg_z))
1752        __(ja 1f)
17530:      __(repret)
17541:      __(movl %arg_y,%imm0)
[13279]1755        __(subl lisp_global(ref_base),%imm0)
[8647]1756        __(shrl $dnode_shift,%imm0)
1757        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
[15366]1758        __(jae 2f)
[9616]1759        __(ref_global(refbits,%temp0))
[8647]1760        __(xorb $31,%imm0_b)
1761        __(lock)
1762        __(btsl %imm0,(%temp0))
[15366]1763        __(xorb $31,%imm0_b)       
17642:      __(cmpl lisp_global(managed_static_dnodes),%imm0)
1765        __(jae 0b)
1766        __(ref_global(managed_static_refbits,%temp0))
1767        __(xorb $31,%imm0_b)
1768        __(lock)
1769        __(btsl %imm0,(%temp0))       
[8647]1770        __(ret)
[8068]1771_endsubp(rplacd)
1772
[11794]1773/* Storing into a gvector can be handled the same way as storing into a CONS. */
[8209]1774/* args (src, unscaled-idx, val) in temp0, arg_y, arg_z */
[8068]1775_spentry(gvset)
1776        .globl C(egc_gvset)
1777C(egc_gvset):
[8253]1778        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1779        __(rcmpl(%arg_z,%temp0))
1780        __(ja 1f)
17810:      __(repret)
17821:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
[13279]1783        __(subl lisp_global(ref_base),%imm0)
[8253]1784        __(shrl $dnode_shift,%imm0)
1785        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
[15366]1786        __(jae 2f)
[11752]1787        __(ref_global(refbits,%temp1))
[8253]1788        __(xorb $31,%imm0_b)
1789        __(lock)
[11752]1790        __(btsl %imm0,(%temp1))
[15366]1791        __(xorb $31,%imm0_b)
17922:      __(cmpl lisp_global(managed_static_dnodes),%imm0)
1793        __(jae 0b)
1794        __(ref_global(managed_static_refbits,%temp1))
1795        __(xorb $31,%imm0_b)
1796        __(lock)
1797        __(btsl %imm0,(%temp1))
[8253]1798        __(ret)
[8068]1799_endsubp(gvset)
1800
[8686]1801/* This is a special case of storing into a gvector: if we need to  */
1802/* memoize the store, record the address of the hash-table vector  */
1803/* in the refmap, as well.  */
1804
[8068]1805_spentry(set_hash_key)
1806        .globl C(egc_set_hash_key)
[8647]1807C(egc_set_hash_key):
[8686]1808        __(movl %arg_z,misc_data_offset(%temp0,%arg_y))
1809        __(rcmpl(%arg_z,%temp0))
1810        __(ja 1f)
18110:      __(repret)
18121:      __(lea misc_data_offset(%temp0,%arg_y),%imm0)
[13279]1813        __(subl lisp_global(ref_base),%imm0)
[8686]1814        __(shrl $dnode_shift,%imm0)
1815        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
[15366]1816        __(jae 2f)
[9616]1817        __(ref_global(refbits,%temp1))
[8686]1818        __(xorb $31,%imm0_b)
1819        __(lock)
[9616]1820        __(btsl %imm0,(%temp1))
[8686]1821        /* Now memoize the address of the hash vector */
[9616]1822        __(movl %temp0,%imm0)
[13279]1823        __(subl lisp_global(ref_base),%imm0)
[8686]1824        __(shrl $dnode_shift,%imm0)
1825        __(xorb $31,%imm0_b)
1826        __(lock)
[9616]1827        __(btsl %imm0,(%temp1))
[15366]1828        __(lea misc_data_offset(%temp0,%arg_y),%imm0)
1829        __(subl lisp_global(ref_base),%imm0)
1830        __(shrl $dnode_shift,%imm0)
18312:      __(cmpl lisp_global(managed_static_dnodes),%imm0)
1832        __(jae 0b)
1833        __(ref_global(managed_static_refbits,%temp1))
1834        __(xorb $31,%imm0_b)
1835        __(lock)
1836        __(btsl %imm0,(%temp1))
1837        /* Now memoize the address of the hash vector */
1838        __(movl %temp0,%imm0)
1839        __(subl lisp_global(ref_base),%imm0)
1840        __(shrl $dnode_shift,%imm0)
1841        __(xorb $31,%imm0_b)
1842        __(lock)
1843        __(btsl %imm0,(%temp1))               
[8686]1844        __(ret)
[8068]1845_endsubp(set_hash_key)
1846
1847/* This is a little trickier: if this is interrupted, we need to know  */
[15500]1848/* whether or not the STORE-CONDITIONAL (cmpxchgl) has won or not.    */
[8647]1849/* If we're interrupted   before the PC has reached the "success_test" label, */
[11794]1850/* repeat (luser the PC back to store_node_conditional_retry.)  If
1851        we're at that */
[8068]1852/* label with the Z flag set, we won and (may) need to memoize.  */
1853
[8647]1854/* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
[8068]1855_spentry(store_node_conditional)
1856        .globl C(egc_store_node_conditional)
1857C(egc_store_node_conditional):
[8660]1858        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1859        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
[11794]1860        .globl C(egc_store_node_conditional_retry)
1861C(egc_store_node_conditional_retry):     
[15500]18620:      __(movl %arg_y,%imm0)
[8647]1863        __(lock)
[8660]1864        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
[8068]1865        .globl C(egc_store_node_conditional_success_test)
1866C(egc_store_node_conditional_success_test):
[15500]1867        __(jne 9f)
[8660]1868        __(leal misc_data_offset(%temp1,%temp0),%imm0)
[13279]1869        __(subl lisp_global(ref_base),%imm0)
[8647]1870        __(shrl $dnode_shift,%imm0)
1871        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1872        __(jae 2f)
[15433]1873        __(ref_global(refbits,%arg_y))
[8647]1874        __(xorb $31,%imm0_b)
1875        __(lock)
[15433]1876        __(btsl %imm0,(%arg_y))
[15366]1877        __(xorb $31,%imm0_b)
18782:      __(cmpl lisp_global(managed_static_dnodes),%imm0)
1879        __(jae 8f)
[15433]1880        __(ref_global(managed_static_refbits,%arg_y))
[15366]1881        __(xorb $31,%imm0_b)
1882        __(lock)
[15433]1883        __(btsl %imm0,(%arg_y))
[10731]1884        .globl C(egc_store_node_conditional_success_end)
1885C(egc_store_node_conditional_success_end):
[15366]18868:      __(movl $t_value,%arg_z)
[10731]1887        __(ret)
[15366]18889:      __(movl $nil_value,%arg_z)
[10731]1889        __(ret)
1890_endsubp(store_node_conditional)
1891
1892        /* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
1893_spentry(set_hash_key_conditional)
1894        .globl C(egc_set_hash_key_conditional)
1895C(egc_set_hash_key_conditional):
1896        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
1897        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
[11792]1898        .globl C(egc_set_hash_key_conditional_retry)
1899C(egc_set_hash_key_conditional_retry):         
[15500]19000:      __(movl %arg_y,%imm0)
[10731]1901        __(lock)
1902        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
1903        .globl C(egc_set_hash_key_conditional_success_test)
1904C(egc_set_hash_key_conditional_success_test):
[15500]1905        __(jne 9f)
[10731]1906        __(leal misc_data_offset(%temp1,%temp0),%imm0)
[13279]1907        __(subl lisp_global(ref_base),%imm0)
[10731]1908        __(shrl $dnode_shift,%imm0)
1909        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
1910        __(jae 2f)
[15366]1911        __(ref_global(refbits,%arg_y))
[10731]1912        __(xorb $31,%imm0_b)
1913        __(lock)
[15366]1914        __(btsl %imm0,(%arg_y))
[10731]1915        /* Now memoize the address of the hash vector */
1916        __(movl %temp1,%imm0)
[13279]1917        __(subl lisp_global(ref_base),%imm0)
[10731]1918        __(shrl $dnode_shift,%imm0)
1919        __(xorb $31,%imm0_b)
1920        __(lock)
[15366]1921        __(btsl %imm0,(%arg_y))
1922        __(leal misc_data_offset(%temp1,%temp0),%imm0)
1923        __(subl lisp_global(ref_base),%imm0)
1924        __(shrl $dnode_shift,%imm0)
19252:      __(cmpl lisp_global(managed_static_dnodes),%imm0)
1926        __(jae 8f)
1927        __(ref_global(managed_static_refbits,%arg_y))
1928        __(xorb $31,%imm0_b)
1929        __(lock)
1930        __(btsl %imm0,(%arg_y))
1931        /* Now memoize the address of the hash vector */
1932        __(movl %temp1,%imm0)
1933        __(subl lisp_global(ref_base),%imm0)
1934        __(shrl $dnode_shift,%imm0)
1935        __(xorb $31,%imm0_b)
1936        __(lock)
1937        __(btsl %imm0,(%arg_y))
[8068]1938        .globl C(egc_write_barrier_end)
1939C(egc_write_barrier_end):
[15366]19408:      __(movl $t_value,%arg_z)
[8647]1941        __(ret)
[15366]19429:      __(movl $nil_value,%arg_z)
[8647]1943        __(ret)
[8068]1944_endsubp(store_node_conditional)
1945
1946_spentry(setqsym)
1947        __(bt $sym_vbit_const,symbol.flags(%arg_y))
1948        __(jae _SPspecset)
1949        __(mov %arg_y,%arg_z)
1950        __(mov $XCONST,%arg_y)
1951        __(set_nargs(2))
1952        __(jmp _SPksignalerr)
1953_endsubp(setqsym)
1954
1955_spentry(progvsave)
[9301]1956        __(push %arg_y)
1957       
1958        /* Error if arg_z isn't a proper list.  That's unlikely,  */
1959        /* but it's better to check now than to crash later.  */
1960       
1961        __(compare_reg_to_nil(%arg_z))
1962        __(movl %arg_z,%temp0)  /* fast   */
1963        __(movl %arg_z,%temp1)  /* slow   */
1964        __(je 9f)               /* Null list is proper   */
19650:
1966        __(extract_lisptag(%temp0,%imm0))
1967        __(cmpb $tag_list,%imm0_b)
1968        __(jne 8f)
1969        __(compare_reg_to_nil(%temp0))
1970        __(je 9f)
1971        __(_cdr(%temp0,%arg_y)) /* (null (cdr fast)) ?   */
1972        __(compare_reg_to_nil(%arg_y))
1973        __(je 9f)
1974        __(extract_lisptag(%arg_y,%imm0))
1975        __(cmpb $tag_list,%imm0_b)
1976        __(jne 8f)
1977        __(_cdr(%arg_y,%temp0))
1978        __(_cdr(%temp1,%temp1))
1979        __(cmpl %temp1,%temp0)
1980        __(jne 0b)
1981
19828:      __(add $node_size,%esp) /* discard pushed arg_y */
1983        __(movl $XIMPROPERLIST,%arg_y)
1984        __(set_nargs(2))
1985        __(jmp _SPksignalerr)
19869:      /* Whew           */
1987
1988        /* Next, determine the length of arg_y.  We   */
1989        /* know that it's a proper list.   */
1990        __(pop %arg_y)
1991       
1992        __(movl $-fixnumone,%imm0)
1993        __(movl %arg_y,%temp0)
19941:      __(compare_reg_to_nil(%temp0))
1995        __(_cdr(%temp0,%temp0))
1996        __(leal fixnumone(%imm0),%imm0)
1997        __(jne 1b)
1998       
1999        /* imm0 is now (boxed) triplet count.  */
2000        /* Determine word count, add 1 (to align), and make room.  */
2001        /*  if count is 0, make an empty tsp frame and exit   */
2002        __(testl %imm0,%imm0)
2003        __(jne 2f)
2004        __(TSP_Alloc_Fixed(2*node_size,%imm0))
2005        __(ret)
20062:      __(movl %imm0,%temp1)
2007        __(add %imm0,%imm0)
2008        __(add %temp1,%imm0)
2009        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
2010        __(TSP_Alloc_Var(%imm0,%temp0))
[9546]2011        __(movl %temp1,(%temp0))
[10092]2012        __(movd rcontext(tcr.db_link),%mm0)
[9301]20133:      __(movl $unbound_marker,%temp0)
2014        __(compare_reg_to_nil(%arg_z))
2015        __(cmovnel cons.car(%arg_z),%temp0)
2016        __(cmovnel cons.cdr(%arg_z),%arg_z)
2017        __(_car(%arg_y,%temp1))
2018        __(_cdr(%arg_y,%arg_y))
2019        __(movl symbol.binding_index(%temp1),%temp1)
[10092]2020        __(cmp rcontext(tcr.tlb_limit),%temp1)
[9692]2021        __(jb 4f)
[9301]2022        __(push %temp1)
2023        __(tlb_too_small())
20244:      __(push %arg_z)
[10092]2025        __(movl rcontext(tcr.tlb_pointer),%arg_z)
[9301]2026        __(subl $binding.size,%imm0)
2027        __(movl %temp1,binding.sym(%imm0))
2028        __(push (%arg_z,%temp1))
2029        __(pop binding.val(%imm0))
2030        __(movl %temp0,(%arg_z,%temp1))
2031        __(pop %arg_z)
2032        __(movd %mm0,binding.link(%imm0))
2033        __(movd %imm0,%mm0)
2034        __(compare_reg_to_nil(%arg_y))
2035        __(jne 3b)
[10092]2036        __(movd %mm0,rcontext(tcr.db_link))
[9301]2037        __(ret)
[8068]2038_endsubp(progvsave)
2039
2040/* Allocate node objects on the temp stack, immediate objects on the foreign  */
2041/* stack. (The caller has to know which stack to discard a frame from.)  */
2042/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
[8647]2043
[8068]2044_spentry(stack_misc_alloc)
[8635]2045        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2046        __(jne local_label(stack_misc_alloc_not_u24))
2047        __(unbox_fixnum(%arg_z,%imm0))
2048        __(mov %arg_y,%temp0)
2049        __(shl $num_subtag_bits-fixnumshift,%temp0)
2050        __(or %temp0,%imm0)     /* %imm0 now = header */
2051        __(movd %imm0,%mm0)     /* cache header in %mm0 */
2052        __(andb $fulltagmask,%imm0_b)
2053        __(cmpb $fulltag_nodeheader,%imm0_b)
2054        __(je local_label(stack_misc_alloc_node))
2055        __(movd %mm0,%imm0)
2056        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2057        __(jbe local_label(stack_misc_alloc_32))
2058        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2059        __(jbe local_label(stack_misc_alloc_8))
2060        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2061        __(jbe local_label(stack_misc_alloc_16))
2062        __(cmpb $subtag_double_float_vector,%imm0_b)
2063        __(jne local_label(stack_misc_alloc_1))
2064        /* double-float vector case */
2065        __(imul $2,%arg_y,%imm0)
2066        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2067local_label(stack_misc_alloc_1):
2068        __(unbox_fixnum(%arg_y,%imm0))
2069        __(addl $7,%imm0)
2070        __(shrl $3,%imm0)
2071        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2072local_label(stack_misc_alloc_8):
2073        __(unbox_fixnum(%arg_y,%imm0))
2074        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2075local_label(stack_misc_alloc_16):
2076        __(unbox_fixnum(%arg_y,%imm0))
2077        __(shl $1,%imm0)
2078        __(jmp local_label(stack_misc_alloc_alloc_ivector))
2079local_label(stack_misc_alloc_32):
2080        __(mov %arg_y,%imm0)
2081local_label(stack_misc_alloc_alloc_ivector):
2082        /* byte count in %imm0 */
2083        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
2084        __(cmpl $tstack_alloc_limit,%imm0)
2085        __(ja local_label(stack_misc_alloc_heap_alloc_ivector))
[13337]2086        __ifdef(`WINDOWS')
[11828]2087         __(windows_cstack_probe(%imm0,%temp1))
2088        __endif
[10092]2089        __(movd rcontext(tcr.foreign_sp),%stack_temp)
[8635]2090        __(movd %stack_temp,%temp1)
[10092]2091        __(subl %imm0,rcontext(tcr.foreign_sp))
2092        __(movl rcontext(tcr.foreign_sp),%temp0)
[8635]20930:      __(movsd %fpzero,-dnode_size(%temp1))
2094        __(subl $dnode_size,%temp1)
2095        __(cmpl %temp1,%temp0)
2096        __(jnz 0b)
2097        __(movd %stack_temp,(%temp0))
[10273]2098        __(movl %ebp,csp_frame.save_ebp(%temp0))
2099        __(movd %mm0,csp_frame.fixed_overhead(%temp0))
2100        __(lea csp_frame.fixed_overhead+fulltag_misc(%temp0),%arg_z)
[8635]2101        __(ret)
2102local_label(stack_misc_alloc_heap_alloc_ivector):
[10092]2103        __(movd rcontext(tcr.foreign_sp),%stack_temp)
2104        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2105        __(movl rcontext(tcr.foreign_sp),%imm0)
[8635]2106        __(movd %stack_temp,(%imm0))
2107        __(jmp _SPmisc_alloc)
2108local_label(stack_misc_alloc_node):
2109        __(movl %arg_y,%imm0)
2110        __(dnode_align(%imm0,tsp_frame.fixed_overhead+node_size,%imm0))
2111        __(cmpl $tstack_alloc_limit,%imm0)
2112        __(ja local_label(stack_misc_alloc_heap_alloc_gvector))
2113        __(TSP_Alloc_Var(%imm0,%temp1))
2114        __(movd %mm0,(%temp1))
2115        __(leal fulltag_misc(%temp1),%arg_z)
2116        __(ret)
2117local_label(stack_misc_alloc_heap_alloc_gvector):
2118        __(TSP_Alloc_Fixed(0,%imm0))
2119        __(jmp _SPmisc_alloc)
[8647]2120
[8635]2121local_label(stack_misc_alloc_not_u24):
[15706]2122        __(popl %temp0)
2123        __(pushl $reserved_frame_marker)
2124        __(pushl $reserved_frame_marker)
2125        __(pushl $XARRLIMIT)
2126        __(pushl %temp0)
2127        __(set_nargs(3))
2128        __(jmp _SPksignalerr)       
[8068]2129_endsubp(stack_misc_alloc)
2130
[8635]2131/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of */
2132/* initial-contents.  Note that this can be used to cons any type of */
2133/* initialized node-header'ed misc object (symbols, closures, ...) */
2134/* as well as vector-like objects. */
[8068]2135_spentry(gvector)
[8635]2136        __(subl $node_size,%nargs)      /* off by one in x862-%gvector */
2137        __(movl (%esp,%nargs),%imm0)    /* boxed subtype */
2138        __(sarl $fixnumshift,%imm0)
2139        __(movl %nargs,%arg_z)
2140        __(shll $num_subtag_bits-word_shift,%arg_z)
2141        __(orl %arg_z,%imm0)
2142        __(movd %imm0,%mm0)
2143        __(dnode_align(%nargs,node_size,%imm0))
2144        __(push %ra0)   /* aka %temp0, can't be live while consing */
2145        __(Misc_Alloc(%arg_z))
2146        __(pop %ra0)
2147        __(movl %nargs,%imm0)
2148        __(jmp 2f)
21491:      __(movl %arg_y,misc_data_offset(%arg_z,%imm0))
21502:      __(subl $node_size,%imm0)
2151        __(pop %arg_y)  /* Note the intentional fencepost: */
2152                        /* discard the subtype as well. */
2153        __(jge 1b)
2154        __(jmp *%ra0)
[8068]2155_endsubp(gvector)
2156
2157_spentry(mvpass)
[11314]2158        __(hlt)
[8068]2159_endsubp(mvpass)
2160
2161_spentry(nthvalue)
[11314]2162        __(hlt)
[8068]2163_endsubp(nthvalue)
2164
2165_spentry(values)
[9001]2166        __(movl (%temp0),%arg_y)        /* return address */
2167        __(ref_global(ret1val_addr,%imm0))
2168        __(movl $nil_value,%arg_z)
2169        __(cmpl %imm0,%arg_y)
2170        __(je 0f)
2171        __(test %nargs,%nargs)
2172        __(cmovne -node_size(%esp,%nargs),%arg_z)
2173        __(movl %temp0,%esp)
2174        __(ret)
21750:      __(movl 4(%temp0),%arg_y)
2176        __(addl $2*node_size,%temp0)
2177        __(lea (%esp,%nargs),%imm0)
2178        __(movd %nargs,%mm0)
2179        __(jmp 2f)
21801:      __(subl $node_size,%imm0)
2181        __(movl (%imm0),%temp1)
2182        __(subl $node_size,%temp0)
2183        __(movl %temp1,(%temp0))
21842:      __(cmp %imm0,%esp)
2185        __(jne 1b)
2186        __(movl %temp0,%esp)
2187        __(movd %mm0,%nargs)
2188        __(jmp *%arg_y)
2189
[8068]2190_endsubp(values)
[8647]2191
[8068]2192_spentry(default_optional_args)
[11314]2193        __(hlt)
[8068]2194_endsubp(default_optional_args)
2195
2196_spentry(opt_supplied_p)
[11314]2197        __(hlt)
[8068]2198_endsubp(opt_supplied_p)
2199
2200_spentry(lexpr_entry)
[11314]2201        __(hlt)
[8068]2202_endsubp(lexpr_entry)
[8647]2203
[8068]2204_spentry(heap_rest_arg)
[9173]2205        __(push_argregs())
2206        __(movl %temp0,%arg_y)
2207        __(movl %nargs,%imm0)
2208        __(testl %imm0,%imm0)
2209        __(movl $nil_value,%arg_z)
2210        __(jmp 2f)
2211        .p2align 4
22121:      __(pop %temp1)
2213        __(Cons(%temp1,%arg_z,%arg_z))
2214        __(subl $node_size,%imm0)
22152:      __(jg 1b)
2216        __(push %arg_z)
2217        __(movl %arg_y,%temp0)
2218        __(jmp *%ra0)
2219
[8068]2220_endsubp(heap_rest_arg)
[8647]2221
[9040]2222/* %imm0 contains the number of fixed args; make an &rest arg out of */
2223/* the others. */
[8068]2224_spentry(req_heap_rest_arg)
[9040]2225        __(push_argregs())
2226        __(movd %nargs,%mm0)
2227        __(subl %imm0,%nargs)
2228        __(movl %nargs,%imm0)
2229        __(movl %temp0,%temp1)
2230        __(movl $nil_value,%arg_z)
2231        __(jmp 2f)
2232        .p2align 4
22331:      __(pop %arg_y)
2234        __(Cons(%arg_y,%arg_z,%arg_z))
2235        __(subl $node_size,%imm0)
22362:      __(jg 1b)
2237        __(push %arg_z)
2238        __(movl %temp1,%temp0)
2239        __(movd %mm0,%nargs)
2240        __(jmp *%ra0)
[8068]2241_endsubp(req_heap_rest_arg)
2242
2243/* %imm0 bytes of stuff has already been pushed   */
2244/* make an &rest arg out of any others   */
2245_spentry(heap_cons_rest_arg)
[9128]2246        __(movd %nargs,%mm0)
2247        __(subl %imm0,%nargs)
2248        __(movl %nargs,%imm0)
2249        __(movl $nil_value,%arg_z)
2250        __(movl %ra0,%arg_y)    /* temp0 can't be live while consing */
2251        __(jmp 2f)              /* (did I mention that already?) */
2252        .p2align 4
22531:      __(pop %temp1)
2254        __(Cons(%temp1,%arg_z,%arg_z))
2255        __(subl $node_size,%imm0)
22562:      __(jg 1b)
2257        __(push %arg_z)
2258        __(movd %mm0,%nargs)
2259        __(jmp *%arg_y)
[8068]2260_endsubp(heap_cons_rest_arg)
2261
2262_spentry(simple_keywords)
2263        __(xor %imm0,%imm0)
2264        __(push_argregs())
2265        __(jmp _SPkeyword_bind)
2266_endsubp(simple_keywords)
2267
2268_spentry(keyword_args)
2269        __(push_argregs())
2270        __(jmp _SPkeyword_bind)
2271_endsubp(keyword_args)
[8647]2272
[8466]2273/* There are %nargs words of arguments on the stack; %imm0 contains the */
2274/* number of non-keyword args pushed.  It's possible that we never actually */
2275/* got any keyword args, which would make things much simpler. */
[8068]2276
[8466]2277/* On entry, the upper half of %temp1 (aka %nargs) contains some bits */
2278/* indicating whether &allow-other-keys and/or &rest was present in the */
[9128]2279/* lambda list. */
[8068]2280
[8466]2281/* Once we get here, we can use the arg registers. */
2282
2283/* N.B.: %ra0 is %temp0, and must not be clobbered. */
2284
[13337]2285define(`keyword_flags_aok_bit',`16')
2286define(`keyword_flags_unknown_keys_bit',`17')
2287define(`keyword_flags_rest_bit',`18')
2288define(`keyword_flags_seen_aok_bit',`19')
[8647]2289
[8068]2290_spentry(keyword_bind)
[10092]2291        __(movl %temp1,rcontext(tcr.unboxed0))  /* save keyword flags */
[9128]2292        __(movzwl %nargs_w,%nargs)
2293        __(movl %nargs,%arg_z)
[8466]2294        __(subl %imm0,%arg_z)
2295        __(jbe local_label(no_keyword_values))
2296        __(btl $word_shift,%arg_z)
2297        __(jnc local_label(even))
2298        __(movl $nil_value,%arg_y)
[9128]2299        __(movl %arg_z,%nargs)
2300        __(test %nargs,%nargs)
[10092]2301        __(movl %ra0,rcontext(tcr.save0))       /* save temp0 while consing */
[8466]2302        __(jmp 1f)
23030:      __(pop %arg_z)
2304        __(Cons(%arg_z,%arg_y,%arg_y))
[9128]2305        __(subl $node_size,%nargs)
[8466]23061:      __(jnz 0b)
[10092]2307        __(movl rcontext(tcr.save0),%ra0)
2308        __(movapd %fpzero,rcontext(tcr.save0))
[8466]2309        __(movl %arg_y,%arg_z)
2310        __(movl $XBADKEYS,%arg_y)
2311        __(set_nargs(2))
2312        __(jmp _SPksignalerr)
2313
2314        /* Now that we're sure that we have an even number of */
2315        /* keywords and values (in %arg_z), move the pairs over */
2316        /* to the temp stack. */
2317local_label(even):
2318        __(lea tsp_frame.fixed_overhead(%arg_z),%arg_y)
2319        __(TSP_Alloc_Var(%arg_y,%imm0))
23202:      __(subl $node_size,%arg_y)
2321        __(pop (%arg_y))
2322        __(cmpl %arg_y,%imm0)
2323        __(jne 2b)
2324
2325        /* Get the keyword vector into %arg_y, and its length into %imm0. */
2326        /* Push %imm0 pairs of NILs (representing value, supplied-p) */
2327        /* for each declared keyword. */
2328        __(movzwl misc_data_offset(%fn),%imm0)
[12374]2329        /* XXX bootstrapping */
2330        __(btr $15,%imm0)
2331        __(jnc 0f)
2332        __(vector_length(%fn,%arg_y))
2333        __(box_fixnum(%imm0,%imm0))
2334        __(subl %imm0,%arg_y)
2335        __(movl %arg_y,%imm0)
2336        __(shrl $fixnumshift,%imm0)
23370:
[8466]2338        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2339        __(vector_length(%arg_y,%imm0))
2340        __(jmp 4f)
23413:      __(push $nil_value)
2342        __(push $nil_value)
23434:      __(subl $fixnumone,%imm0)
2344        __(jge 3b)
2345
2346        /* We can now push %ra0 (aka %temp0) and %nargs (aka %temp1) */
2347        /* in order to get a couple more registers to work with. */
2348        __(push %ra0)
2349        __(push %nargs)
2350
2351        /* At this point we have: */
2352        /* number of supplied keywords and values in %arg_z */
2353        /* keyword vector in %arg_y */
2354        __(vector_length(%arg_y,%imm0))
2355        __(push %imm0)          /* count of declared keywords */
2356        __(push %arg_z)         /* count of supplied keys and values */
[8647]2357
[8466]2358        /* For each declared keyword, iterate over the supplied k/v pairs */
2359        /* to see if it's supplied and what the value is. */
2360        /* checking to see if any */
2361        /* key-value pairs were unexpectedly supplied. */
2362
[10092]2363        __(movl rcontext(tcr.save_tsp),%temp0)
[8466]2364        __(addl $2*node_size,%temp0) /* skip frame overhead */
2365        /* %temp0: top of tstack (skipping frame overhead) */
2366        __(lea 4*node_size(%esp,%imm0,2),%temp1)
2367        /* %temp1: word above 0th value/supplied-p pair on vstack */
2368        /* %arg_y: keyword vector */
2369        __(xorl %imm0,%imm0)
2370        /* %imm0: index */
2371        /* %arg_z: temporary */
2372
2373        /* Iterate over supplied k/v pairs on tstack.  See if key is */
2374        /* in the keyword vector.  Copy value and set supplied-p on */
2375        /* vstack if found. */
2376
2377local_label(tstack_loop):
2378        __(movl (%temp0,%imm0,2),%arg_z)        /* keyword */
2379        __(push %imm0)
2380        __(xorl %imm0,%imm0)
2381        __(cmpl $nrs.kallowotherkeys,%arg_z)
2382        __(jne local_label(next_keyvect_entry))
[10092]2383        __(btsl $keyword_flags_seen_aok_bit,rcontext(tcr.unboxed0))
[8466]2384        __(jc local_label(next_keyvect_entry))
[9722]2385        __(push %imm0)
2386        __(movl 4(%esp),%imm0)
[8466]2387        __(cmpl $nil_value,node_size(%temp0,%imm0,2))
[9722]2388        __(pop %imm0)
[8466]2389        __(je local_label(next_keyvect_entry))
[10092]2390        __(btsl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
[8466]2391        __(jmp local_label(next_keyvect_entry))
2392        /* loop through keyword vector */
23936:      __(cmpl misc_data_offset(%arg_y,%imm0),%arg_z)
2394        __(jne 7f)
2395        /* Got a match; have we already seen this keyword? */
2396        __(negl %imm0)
2397        __(cmpl $nil_value,-node_size*2(%temp1,%imm0,2))
2398        __(jne 9f)      /* seen it, ignore this value */
2399        __(movl (%esp),%arg_z)
2400        __(lea (%temp0,%arg_z,2),%arg_z)
2401        __(movl node_size(%arg_z),%arg_z) /* value for this key */
2402        __(movl %arg_z,-node_size(%temp1,%imm0,2))
2403        __(movl $t_value,-node_size*2(%temp1,%imm0,2))
2404        __(jmp 9f)
24057:      __(addl $node_size,%imm0)
2406local_label(next_keyvect_entry):
2407        __(cmpl %imm0,8(%esp))
2408        __(jne 6b)
2409        /* Didn't match anything in the keyword vector.  Is the keyword */
2410        /* :allow-other-keys? */
2411        __(cmpl $nrs.kallowotherkeys,%arg_z)
2412        __(je 9f)       /* :allow-other-keys is never "unknown" */
[10092]24138:      __(btsl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
[8466]24149:      __(pop %imm0)
2415        __(addl $fixnumone,%imm0)
2416        __(movl %imm0,%arg_z)
2417        __(shll $1,%arg_z)      /* pairs of tstack words */
2418        __(cmpl %arg_z,0(%esp))
2419        __(jne local_label(tstack_loop))
2420
2421        __(pop %imm0)   /* count of supplied keys and values */
2422        __(addl $node_size,%esp)
2423        __(pop %nargs)
2424        __(pop %ra0)
2425
2426        /* If the function takes an &rest arg, or if we got an unrecognized */
2427        /* keyword and don't allow that, copy the incoming k/v pairs from */
2428        /* the temp stack back to the value stack. */
[10092]2429        __(btl $keyword_flags_rest_bit,rcontext(tcr.unboxed0))
[8466]2430        __(jc 1f)
[10092]2431        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
[8466]2432        __(jnc 0f)
[10092]2433        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
[8466]2434        __(jnc 1f)
2435        /* pop the tstack frame */
24360:      __(discard_temp_frame(%imm0))
2437        __(jmp *%ra0)
2438
2439        /* Copy the k/v pairs from the tstack back to the value stack, */
2440        /* either because the function takes an &rest arg or because */
2441        /* we need to signal an "unknown keywords" error. */
[10092]24421:      __(movl rcontext(tcr.save_tsp),%arg_z)
[8466]2443        __(mov (%arg_z),%arg_y)
2444        __(jmp 3f)
24452:      __(push (%arg_z))
2446        __(push node_size(%arg_z))
24473:      __(addl $dnode_size,%arg_z)
2448        __(cmpl %arg_z,%arg_y)
2449        __(jne 2b)
2450        __(discard_temp_frame(%arg_z))
[10092]2451        __(btl $keyword_flags_unknown_keys_bit,rcontext(tcr.unboxed0))
[8466]2452        __(jnc 9f)
[10092]2453        __(btl $keyword_flags_aok_bit,rcontext(tcr.unboxed0))
[8466]2454        __(jc 9f)
2455        /* Signal an "unknown keywords" error */
2456        __(movl %imm0,%nargs)
2457        __(movl $nil_value,%arg_z)
2458        __(test %nargs,%nargs)
[10092]2459        __(movl %ra0,rcontext(tcr.save0))
[8466]2460        __(jmp 5f)
24614:      __(pop %arg_y)
2462        __(Cons(%arg_y,%arg_z,%arg_z))
2463        __(subl $node_size,%nargs)
24645:      __(jnz 4b)
2465        __(movl $XBADKEYS,%arg_y)
2466        __(set_nargs(2))
[10092]2467        __(movl rcontext(tcr.save0),%ra0)
2468        __(movl $0,rcontext(tcr.save0))
[8466]2469        __(jmp _SPksignalerr)
24709:      __(jmp *%ra0)
[8647]2471
[8466]2472/* No keyword value were provided.  Access the keyword vector (which is the */
2473/* 0th constant in %fn), determine its length N, and push N pairs of NILs. */
2474/* N could be 0... */
2475
2476local_label(no_keyword_values):
2477        __(movzwl misc_data_offset(%fn),%imm0)
[12374]2478        /* XXX bootstrapping */
2479        __(btr $15,%imm0)
2480        __(jnc 9f)
2481        __(vector_length(%fn,%arg_y))
2482        __(box_fixnum(%imm0,%imm0))
2483        __(subl %imm0,%arg_y)
2484        __(movl %arg_y,%imm0)
2485        __(shrl $fixnumshift,%imm0)
24869:
[8466]2487        __(movl misc_data_offset(%fn,%imm0,node_size),%arg_y)
2488        __(vector_length(%arg_y,%arg_z))
2489        __(movl $nil_value,%imm0)
2490        __(jmp 1f)
24910:      __(push %imm0)
2492        __(push %imm0)
24931:      __(subl $fixnumone,%arg_z)
2494        __(jge 0b)
2495        __(jmp *%ra0)
[8068]2496_endsubp(keyword_bind)
2497
[8466]2498/* Normally, we'd just set %fname (aka %temp0) and do */
2499/* jump_fname().  Sometimes, though, %temp0 is being used */
2500/* as %ra0, and I'm not sure that it's going to be safe to */
2501/* clobber that.  (Note that nil-relative symbols aren't going */
2502/* get moved around by the GC, so we can get away with putting */
2503/* '%err-disp in %imm0.) */
[8068]2504_spentry(ksignalerr)
[8466]2505        __(mov $nrs.errdisp,%imm0)
2506        __(mov symbol.fcell(%imm0),%fn)
2507        __(jump_fn)
[8068]2508_endsubp(ksignalerr)
2509
2510_spentry(stack_rest_arg)
2511        __(xorl %imm0,%imm0)
2512        __(push_argregs())
2513        __(jmp _SPstack_cons_rest_arg)
2514_endsubp(stack_rest_arg)
2515
2516_spentry(req_stack_rest_arg)
2517        __(push_argregs())
2518        __(jmp _SPstack_cons_rest_arg)
2519_endsubp(req_stack_rest_arg)
2520
2521_spentry(stack_cons_rest_arg)
[8899]2522        __(movd %nargs,%mm2)
[10092]2523        __(movl %temp0,rcontext(tcr.save0))
[8899]2524        __(subl %imm0,%temp1)
2525        __(movl $nil_value,%arg_z)
[9771]2526        __(jle 2f)      /* empty list; make an empty TSP frame */
[8899]2527        __(addl %temp1,%temp1)
2528        __(cmpl $(tstack_alloc_limit-dnode_size),%temp1)
[9738]2529        __(ja 3f)       /* make empty frame, then heap-cons */
[8899]2530        __(dnode_align(%temp1,tsp_frame.fixed_overhead,%imm0))
2531        __(TSP_Alloc_Var(%imm0,%temp0))
2532        __(addl $fulltag_cons,%temp0)
25331:      __(pop %arg_y)
2534        __(_rplacd(%temp0,%arg_z))
2535        __(_rplaca(%temp0,%arg_y))
2536        __(movl %temp0,%arg_z)
2537        __(addl $cons.size,%temp0)
2538        __(subl $dnode_size,%temp1)
2539        __(jne 1b)
2540        __(push %arg_z)
2541        __(movd %mm2,%nargs)
[10092]2542        __(movl rcontext(tcr.save0),%temp0)
2543        __(movss %fpzero,rcontext(tcr.save0))
[8899]2544        __(jmp *%temp0)
2545/* Length 0, make empty frame */
25462:
2547        __(TSP_Alloc_Fixed(0,%temp0))
2548        __(push %arg_z)
2549        __(movd %mm2,%nargs)
[10092]2550        __(movl rcontext(tcr.save0),%temp0)
2551        __(movss %fpzero,rcontext(tcr.save0))
[8899]2552        __(jmp *%temp0)
2553/* Too big to stack-cons, but make an empty frame before heap-consing */
2554        __(TSP_Alloc_Fixed(0,%temp0))
2555        __(movd %mm2,%nargs)
[10092]2556        __(movl rcontext(tcr.save0),%temp0)
2557        __(movss %fpzero,rcontext(tcr.save0))
[8899]2558        __(jmp _SPheap_cons_rest_arg)
[8068]2559_endsubp(stack_cons_rest_arg)
2560
2561_spentry(getxlong)
[11314]2562        __(hlt)
[8068]2563_endsubp(getxlong)
2564
2565/* Have to be a little careful here: the caller may or may not have pushed  */
[8253]2566/* an empty frame, and we may or may not have needed one.  We can't easily  */
2567/* tell whether or not a frame will be needed (if the caller didn't reserve  */
2568/* a frame, whether or not we need one depends on the length of the list  */
2569/* in arg_z.  So, if the caller didn't push a frame, we do so; once */
2570/* everything's been spread, we discard the reserved frame (regardless of
2571/* who pushed it) if all args fit in registers.   */
[8899]2572
2573/* xxx preserve temp1 somehow? cf. comment in x862-invoke-fn */
[8068]2574_spentry(spreadargz)
[8686]2575        __(test %nargs,%nargs)
2576        __(jne 0f)
2577        __(push $reserved_frame_marker)
2578        __(push $reserved_frame_marker)
[10092]25790:      __(movl %arg_z,rcontext(tcr.save0))     /* save in case of error */
[8686]2580        __(movd %nargs,%mm0)    /* now we can use %temp1 */
2581        __(xorl %nargs,%nargs)
2582        __(cmpl $nil_value,%arg_z)
2583        __(je 2f)
25841:      __(extract_fulltag(%arg_z,%imm0))
2585        __(cmpb $fulltag_cons,%imm0_b)
2586        __(jne 9f)
2587        __(_car(%arg_z,%arg_y))
2588        __(_cdr(%arg_z,%arg_z))
2589        __(add $node_size,%nargs)
2590        __(cmpl $call_arguments_limit<<fixnumshift,%nargs)
[13406]2591        __(jae 8f)
[8686]2592        __(push %arg_y)
2593        __(cmpl $nil_value,%arg_z)
2594        __(jne 1b)
25952:      __(movd %mm0,%imm0)
2596        __(addl %imm0,%nargs)
2597        __(jne 4f)
25983:      __(addl $2*node_size,%esp)
[10092]2599        __(movl $0,rcontext(tcr.save0))
[8686]2600        __(jmp *%ra0)
26014:      __(pop %arg_z)
2602        __(cmp $1*node_size,%nargs)
2603        __(je 3b)
2604        __(pop %arg_y)
2605        __(cmp $2*node_size,%nargs)
2606        __(je 3b)
[10092]2607        __(movl $0,rcontext(tcr.save0))
[8686]2608        __(jmp *%ra0)
2609/* Discard everything that's been pushed already, complain */
26108:      __(lea (%esp,%nargs),%esp)
[10092]2611        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2612        __(movl $0,rcontext(tcr.save0))
[8686]2613        __(movl $XTMINPS,%arg_y)
2614        __(set_nargs(2))
2615        __(push %ra0)
2616        __(jmp _SPksignalerr)
26179:      __(lea (%esp,%nargs),%esp)
[10092]2618        __(movl rcontext(tcr.save0),%arg_z) /* recover original */
2619        __(movl $0,rcontext(tcr.save0))
[8686]2620        __(movl $XNOSPREAD,%arg_y)
2621        __(set_nargs(2))
2622        __(push %ra0)
2623        __(jmp _SPksignalerr)
[8068]2624_endsubp(spreadargz)
2625
[8647]2626
[8686]2627/* Caller built its own frame when it was entered.  If all outgoing args  */
[8068]2628/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
2629/* relative to it and restore %rbp/%ra0   */
2630_spentry(tfuncallgen)
[9267]2631        __(cmpl $nargregs*node_size,%nargs)
2632        __(jbe 9f)
2633        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
[10092]2634        __(movl %temp0,rcontext(tcr.save0))
[9267]2635        __(movd %nargs,%mm0)
2636        __(xorl %temp1,%temp1)
2637        /* We can use %ra0 as a temporary here, since the real return address */
2638        /* is on the stack   */
26390:      __(movl -node_size(%imm0),%ra0)
2640        __(movl %ra0,-node_size(%ebp,%temp1))
2641        __(subl $node_size,%imm0)
2642        __(subl $node_size,%temp1)
2643        __(cmpl %imm0,%esp)
2644        __(jne 0b)
2645        __(lea (%ebp,%temp1),%esp)
2646        __(movl 4(%ebp),%ra0)
2647        __(movl (%ebp),%ebp)
2648        __(pushl %ra0)
2649        __(movd %mm0,%nargs)
[10092]2650        __(movl rcontext(tcr.save0),%temp0)
2651        __(movss %fpzero,rcontext(tcr.save0))
[9267]2652        __(do_funcall())
2653        /* All args in regs; exactly the same as the tfuncallvsp case   */
26549:             
2655        __(leave)
2656        __(do_funcall())
2657
[8068]2658_endsubp(tfuncallgen)
2659
2660/* Some args were pushed; move them down in the frame   */
2661_spentry(tfuncallslide)
[8856]2662        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2663        __(movd %nargs,%mm0)
2664        __(xorl %temp1,%temp1)
[10092]2665        __(movl %temp0,rcontext(tcr.save0))
[8856]26660:      __(movl -node_size(%imm0),%temp0)
2667        __(movl %temp0,-node_size(%ebp,%temp1))
2668        __(subl $node_size,%imm0)
2669        __(subl $node_size,%temp1)
2670        __(cmpl %imm0,%esp)
2671        __(jne 0b)
2672        __(lea (%ebp,%temp1),%esp)
2673        __(push 4(%ebp))        /* return address */
2674        __(movl (%ebp),%ebp)
2675        __(movd %mm0,%nargs)
[10092]2676        __(movl rcontext(tcr.save0),%temp0)
2677        __(movss %fpzero,rcontext(tcr.save0))
[8856]2678        __(do_funcall())
[8068]2679_endsubp(tfuncallslide)
2680
2681/* No args were pushed; recover saved context & do funcall        */
2682_spentry(tfuncallvsp)
2683        __(leave)
2684        __(do_funcall())
2685_endsubp(tfuncallvsp)
2686
2687_spentry(tcallsymgen)
[8899]2688        __(cmpl $nargregs*node_size,%nargs)
2689        __(jbe 9f)
2690        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2691        __(movd %nargs,%mm0)
[10092]2692        __(movl %temp0,rcontext(tcr.save0))
[8899]2693        __(xorl %temp1,%temp1)  /* aka nargs */
26940:      __(movl -node_size(%imm0),%temp0)
2695        __(movl %temp0,-node_size(%ebp,%temp1))
2696        __(subl $node_size,%imm0)
2697        __(subl $node_size,%temp1)
2698        __(cmpl %imm0,%esp)
2699        __(jne 0b)
2700        __(lea (%ebp,%temp1),%esp)
2701        __(movl 4(%ebp),%temp0)
2702        __(movl (%ebp),%ebp)
2703        __(push %temp0)
[10092]2704        __(movl rcontext(tcr.save0),%temp0)
2705        __(movss %fpzero,rcontext(tcr.save0))
[8899]2706        __(movd %mm0,%nargs)
2707        __(jump_fname())
2708/* All args in regs; exactly the same as the tcallsymvsp case. */
27099:
2710        __(leave)
2711        __(jump_fname())
[8068]2712_endsubp(tcallsymgen)
2713
2714_spentry(tcallsymslide)
[8391]2715        __(movl %ebp,%imm0)
[8467]2716        __(subl %nargs,%imm0)
2717        __(addl $nargregs*node_size,%imm0)      /* new tos */
[8391]2718        __(push %imm0)
2719        __(push %arg_y)
2720        __(push %arg_z)
2721        __(push %nargs)
2722        __(lea (4-nargregs)*node_size(%esp,%nargs),%arg_y) /* src ptr */
2723        __(movl %ebp,%imm0) /* dst ptr */
2724        __(subl $fixnumone*nargregs,%nargs)
2725        __(jmp 1f)
27260:      __(subl $node_size,%arg_y)
2727        __(movl (%arg_y),%arg_z)
2728        __(subl $node_size,%imm0)
2729        __(movl %arg_z,(%imm0))
27301:      __(subl $fixnumone,%nargs)
2731        __(jge 0b)
2732        __(pop %nargs)
2733        __(pop %arg_z)
2734        __(pop %arg_y)
2735        __(pop %esp)
[8467]2736        __(push node_size(%ebp))
[8391]2737        __(movl 0(%ebp),%ebp)
2738        __(jump_fname)
[8068]2739_endsubp(tcallsymslide)
2740
2741_spentry(tcallsymvsp)
2742        __(leave)
2743        __(jump_fname())
2744_endsubp(tcallsymvsp)
2745
2746_spentry(tcallnfngen)
[9625]2747        __(cmpl $nargregs*node_size,%nargs)
2748        __(jbe 9f)
2749        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2750        __(movd %nargs,%mm0)    /* stash nargs aka temp1 */
2751        __(xorl %temp1,%temp1)
[10092]2752        __(movl %temp0,rcontext(tcr.save0))
[9625]2753        /* It's OK to use %ra0 (%temp0) as an temp here, since the */
2754        /* real return address is on the stack. */
27550:      __(movl -node_size(%imm0),%ra0)
2756        __(movl %ra0,-node_size(%ebp,%temp1))
2757        __(subl $node_size,%imm0)
2758        __(subl $node_size,%temp1)
2759        __(cmpl %imm0,%esp)
2760        __(jne 0b)
[10092]2761        __(movl rcontext(tcr.save0),%fn)
2762        __(movss %fpzero,rcontext(tcr.save0))
[9625]2763        __(lea (%ebp,%temp1),%esp)
2764        __(movl lisp_frame.savera0(%ebp),%ra0)
2765        __(movl lisp_frame.backlink(%ebp),%ebp)
2766        __(push %ra0)
[9739]2767        __(movd %mm0,%nargs)
[9625]2768        __(jmp *%fn)
27699:      /* All args in regs; exactly the same as the tcallnfnvsp case */
2770        __(movl %temp0,%fn)
2771        __(leave)
2772        __(jmp *%fn)
[8068]2773_endsubp(tcallnfngen)
[8647]2774
[8068]2775_spentry(tcallnfnslide)
[9128]2776        __(lea -nargregs*node_size(%esp,%nargs),%imm0)
2777        __(movd %nargs,%mm0)    /* save nargs aka temp1 */
2778        __(xorl %temp1,%temp1)
[10092]2779        __(movl %temp0,rcontext(tcr.save0))
[9128]2780        /* We can use %ra0 as a temporary here, since the real return address */
2781        /* is on the stack   */
27820:      __(movl -node_size(%imm0),%ra0)
2783        __(movl %ra0,-node_size(%ebp,%temp1))
2784        __(subl $node_size,%imm0)
2785        __(subl $node_size,%temp1)
2786        __(cmpl %imm0,%esp)
2787        __(jne 0b)
[10092]2788        __(movl rcontext(tcr.save0),%fn)
[9128]2789        __(lea (%ebp,%temp1),%esp)
2790        __(movl lisp_frame.savera0(%ebp),%ra0)
2791        __(movl lisp_frame.backlink(%ebp),%ebp)
2792        __(push %ra0)
[10092]2793        __(movapd %fpzero,rcontext(tcr.save0))
[9128]2794        __(movd %mm0,%nargs)
2795        __(jmp *%fn)
[8068]2796_endsubp(tcallnfnslide)
2797
2798_spentry(tcallnfnvsp)
2799        __(mov %temp0,%fn)
2800        __(leave)
2801        __(jmp *%fn)
2802_endsubp(tcallnfnvsp)
2803
[8391]2804/* Make a "raw" area on the foreign stack, stack-cons a macptr to point */
2805/* to it, and return the macptr.  Size (in bytes, boxed) is in arg_z */
2806/* on entry; macptr in arg_z on exit. */
[8068]2807_spentry(makestackblock)
[10500]2808        __(check_cstack_alignment())
[8391]2809        __(unbox_fixnum(%arg_z,%imm0))
2810        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2811        __(cmpl $tstack_alloc_limit,%imm0)
2812        __(jae 1f)
[13337]2813        __ifdef(`WINDOWS')
[11828]2814         __(windows_cstack_probe(%imm0,%arg_z))
2815        __endif
[10092]2816        __(movd rcontext(tcr.foreign_sp),%mm0)
2817        __(subl %imm0,rcontext(tcr.foreign_sp))
2818        __(movl rcontext(tcr.foreign_sp),%arg_z)
[8391]2819        __(movd %mm0,(%arg_z))
[10273]2820        __(movl %ebp,csp_frame.save_ebp(%arg_z))
[8391]2821        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2822        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2823        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2824        __(movl %imm0,macptr.address(%arg_z))
2825        __(movss %fpzero,macptr.domain(%arg_z))
2826        __(movss %fpzero,macptr.type(%arg_z))
2827        __(ret)
[10092]28281:      __(movd rcontext(tcr.foreign_sp),%mm0)
2829        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2830        __(movl rcontext(tcr.foreign_sp),%imm0)
[8391]2831        __(movd %mm0,(%imm0))
[10273]2832        __(movl %ebp,csp_frame.save_ebp(%imm0))
[8391]2833        __(set_nargs(1))
2834        __(movl $nrs.new_gcable_ptr,%fname)
2835        __(jump_fname())
[8068]2836_endsubp(makestackblock)
[8647]2837
[8068]2838_spentry(makestackblock0)
[9301]2839        __(unbox_fixnum(%arg_z,%imm0))
2840        __(dnode_align(%imm0,tsp_frame.fixed_overhead+macptr.size,%imm0))
2841        __(cmpl $tstack_alloc_limit,%imm0)
2842        __(jae 9f)
[13337]2843        __ifdef(`WINDOWS')
[11828]2844         __(windows_cstack_probe(%imm0,%temp0))
2845        __endif
[10092]2846        __(movl rcontext(tcr.foreign_sp),%temp0)
2847        __(subl %imm0,rcontext(tcr.foreign_sp))
2848        __(movl rcontext(tcr.foreign_sp),%arg_z)
[9301]2849        __(movl %temp0,(%arg_z))
[10273]2850        __(movl %ebp,csp_frame.save_ebp(%arg_z))
[9301]2851        __(lea macptr.size+tsp_frame.fixed_overhead(%arg_z),%imm0)
2852        __(movl $macptr_header,tsp_frame.fixed_overhead(%arg_z))
2853        __(addl $fulltag_misc+tsp_frame.fixed_overhead,%arg_z)
2854        __(movl %imm0,macptr.address(%arg_z))
2855        __(movss %fpzero,macptr.domain(%arg_z))
2856        __(movss %fpzero,macptr.type(%arg_z))
2857        __(jmp 2f)
28581:      __(movsd %fpzero,(%imm0))
2859        __(addl $dnode_size,%imm0)
28602:      __(cmpl %imm0,%temp0)
2861        __(jne 1b)
2862        __(repret)
[10092]28639:      __(movd rcontext(tcr.foreign_sp),%mm0)
2864        __(subl $dnode_size,rcontext(tcr.foreign_sp))
2865        __(movl rcontext(tcr.foreign_sp),%imm0)
[9301]2866        __(movd %mm0,(%imm0))
[10273]2867        __(movl %ebp,csp_frame.save_ebp(%imm0))
[9301]2868        __(set_nargs(1))
2869        __(movl $nrs.new_gcable_ptr,%fname)
2870        __(jump_fname())
[8068]2871_endsubp(makestackblock0)
[8647]2872
[8068]2873_spentry(makestacklist)
[9128]2874        __(test %arg_y,%arg_y)
2875        __(js 9f)
2876        __(movl %arg_y,%imm0)
2877        __(testb $fixnummask,%imm0_b)
2878        __(jne 9f)
2879        __(addl %imm0,%imm0)
2880        __(rcmpl(%imm0,$tstack_alloc_limit))
2881        __(movl $nil_value,%temp1)
2882        __(jae 2f)
2883        __(addl $tsp_frame.fixed_overhead,%imm0)
2884        __(TSP_Alloc_Var(%imm0,%temp0))
2885        __(addl $fulltag_cons,%temp0)
2886        __(jmp 1f)
28870:      __(_rplaca(%temp0,%arg_z))
2888        __(_rplacd(%temp0,%temp1))
2889        __(movl %temp0,%temp1)
2890        __(addl $cons.size,%temp0)
28911:      __(subl $fixnumone,%arg_y)
2892        __(jge 0b)
2893        __(movl %temp1,%arg_z)
2894        __(ret)
28952:      __(TSP_Alloc_Fixed(0,%imm0))
2896        __(jmp 4f)
28973:      __(Cons(%arg_z,%temp1,%temp1))
28984:      __(subl $fixnumone,%arg_y)                             
2899        __(jge 3b)
2900        __(movl %temp1,%arg_z)
2901        __(ret)
29029:      __(uuo_error_reg_not_type(Rarg_y,error_object_not_unsigned_byte))
[8068]2903_endsubp(makestacklist)
[8647]2904
[8686]2905/* subtype (boxed) vpushed before initial values. (Had better be a */
2906/* node header subtag.)  Nargs set to count of things vpushed. */
[8068]2907_spentry(stkgvector)
[8686]2908        __(movl -fixnumone(%esp,%nargs),%imm0)  /* boxed subtag */
2909        __(shrl $fixnumshift,%imm0)
2910        __(leal -fixnumone(%nargs),%arg_z)
2911        __(movl %arg_z,%arg_y)
2912        __(shll $num_subtag_bits-fixnumshift,%arg_z)
2913        __(orl %arg_z,%imm0)    /* imm0 = header, %arg_y = unaligned size */
2914        __(movd %imm0,%mm0)
2915        __(dnode_align(%arg_y,(tsp_frame.fixed_overhead+node_size),%imm0))
2916        __(TSP_Alloc_Var(%imm0,%arg_z))
2917        __(movd %mm0,(%arg_z))
2918        __(addl $fulltag_misc,%arg_z)
2919        __(lea -node_size(%nargs),%imm0)
2920        __(jmp 2f)
29211:      __(pop misc_data_offset(%arg_z,%imm0))
29222:      __(subl $node_size,%imm0)
2923        __(jge 1b)
2924        __(addl $node_size,%esp)
2925        __(jmp *%ra0)
[8068]2926_endsubp(stkgvector)
2927
[8635]2928/* Allocate a fulltag-misc object. */
2929/* arg_y = boxed element count, arg_z = subtag (boxed, of course) */
[8068]2930_spentry(misc_alloc)
[8635]2931        __(testl $~(((1<<24)-1)<<fixnumshift),%arg_y)
2932        __(jne local_label(misc_alloc_not_u24))
2933        __(unbox_fixnum(%arg_z,%imm0))
2934        __(mov %arg_y,%temp0)
2935        __(shl $num_subtag_bits-fixnumshift,%temp0)
2936        __(or %temp0,%imm0)     /* %imm0 now = header */
2937        __(movd %imm0,%mm0)     /* Misc_Alloc wants header in %mm0 */
2938        __(andb $fulltagmask,%imm0_b)
2939        __(cmpb $fulltag_nodeheader,%imm0_b)
2940        __(je local_label(misc_alloc_32))
2941        __(movd %mm0,%imm0)
2942        __(cmpb $max_32_bit_ivector_subtag,%imm0_b)
2943        __(jbe local_label(misc_alloc_32))
2944        __(cmpb $max_8_bit_ivector_subtag,%imm0_b)
2945        __(jbe local_label(misc_alloc_8))
2946        __(cmpb $max_16_bit_ivector_subtag,%imm0_b)
2947        __(jbe local_label(misc_alloc_16))
2948        __(cmpb $subtag_double_float_vector,%imm0_b)
2949        __(jne local_label(misc_alloc_1))
2950        /* double-float vector case */
2951        __(imul $2,%arg_y,%imm0)
2952        __(jmp local_label(misc_alloc_alloc_vector))
2953local_label(misc_alloc_1):
2954        __(unbox_fixnum(%arg_y,%imm0))
2955        __(addl $7,%imm0)
2956        __(shrl $3,%imm0)
2957        __(jmp local_label(misc_alloc_alloc_vector))
2958local_label(misc_alloc_8):
2959        __(unbox_fixnum(%arg_y,%imm0))
2960        __(jmp local_label(misc_alloc_alloc_vector))
2961local_label(misc_alloc_16):
2962        __(unbox_fixnum(%arg_y,%imm0))
2963        __(shl $1,%imm0)
2964        __(jmp local_label(misc_alloc_alloc_vector))
2965local_label(misc_alloc_32):
2966        __(movl %arg_y,%imm0)
2967local_label(misc_alloc_alloc_vector):
2968        __(dnode_align(%imm0,node_size,%imm0))
2969        __(Misc_Alloc(%arg_z))
2970        __(ret)
2971local_label(misc_alloc_not_u24):
[15706]2972        __(popl %temp0)
2973        __(pushl $reserved_frame_marker)
2974        __(pushl $reserved_frame_marker)
2975        __(pushl $XARRLIMIT)
2976        __(pushl %temp0)
2977        __(set_nargs(3))
2978        __(jmp _SPksignalerr)       
[8068]2979_endsubp(misc_alloc)
2980
[9676]2981/* N.B. arg count word in %imm0, not %nargs */
[10092]2982/* no %whole_reg;  it's in rcontext(tcr.save0) */
[9676]2983/* %arg_reg is %temp1, key vector in %arg_y */
[8068]2984_startfn(C(destbind1))
[10092]2985        __(movl %ra0,rcontext(tcr.save1))
[9690]2986        /* Save entry %esp in case of error   */
2987        __(movd %esp,%mm0)
2988        /* Save arg count word */
2989        __(movd %imm0,%mm1)
2990        /* Extract required arg count.   */
2991        __(testb %imm0_b,%imm0_b)
2992        __(je local_label(opt))         /* skip if no required args   */
2993        __(movzbl %imm0_b,%imm0)
2994local_label(req_loop): 
2995        __(compare_reg_to_nil(%arg_reg))
2996        __(je local_label(toofew))
2997        __(movb $fulltagmask,%imm0_bh)
2998        __(andb %arg_reg_b,%imm0_bh)
2999        __(cmpb $fulltag_cons,%imm0_bh)
3000        __(jne local_label(badlist))
3001        __(subb $1,%imm0_b)
3002        __(pushl cons.car(%arg_reg))
3003        __(_cdr(%arg_reg,%arg_reg))
3004        __(jne local_label(req_loop))
3005        __(movd %mm1,%imm0)
3006local_label(opt):
[13230]3007        __(movb %imm0_bh,%imm0_b)
3008        __(testb %imm0_b,%imm0_b)
[9690]3009        __(je local_label(rest_keys))
3010        __(btl $initopt_bit,%imm0)
3011        __(jc local_label(opt_supp))
3012        /* 'simple' &optionals:  no supplied-p, default to nil.   */
3013local_label(simple_opt_loop):
3014        __(compare_reg_to_nil(%arg_reg))
3015        __(je local_label(default_simple_opt))
3016        __(movb $fulltagmask,%imm0_bh)
3017        __(andb %arg_reg_b,%imm0_bh)
3018        __(cmpb $fulltag_cons,%imm0_bh)
3019        __(jne local_label(badlist))
3020        __(subb $1,%imm0_b)
3021        __(pushl cons.car(%arg_reg))
3022        __(_cdr(%arg_reg,%arg_reg))
3023        __(jne local_label(simple_opt_loop))
3024        __(jmp local_label(rest_keys))
3025local_label(default_simple_opt):
3026        __(subb $1,%imm0_b)
3027        __(pushl $nil_value)
3028        __(jne local_label(default_simple_opt))
3029        __(jmp local_label(rest_keys))
3030local_label(opt_supp):
3031        __(movb $fulltagmask,%imm0_bh)
3032        __(andb %arg_reg_b,%imm0_bh)
[13230]3033        __(compare_reg_to_nil(%arg_reg))
[9690]3034        __(je local_label(default_hard_opt))
3035        __(cmpb $fulltag_cons,%imm0_bh)
3036        __(jne local_label(badlist))
3037        __(subb $1,%imm0_b)
3038        __(pushl cons.car(%arg_reg))
3039        __(_cdr(%arg_reg,%arg_reg))
3040        __(push $t_value)
3041        __(jne local_label(opt_supp))
3042        __(jmp local_label(rest_keys))
3043local_label(default_hard_opt):
3044        __(subb $1,%imm0_b)
3045        __(push $nil_value)
3046        __(push $nil_value)
3047        __(jne local_label(default_hard_opt))
3048local_label(rest_keys):
3049        __(btl $restp_bit,%imm0)
3050        __(jc local_label(have_rest))
3051        __(btl $keyp_bit,%imm0)
3052        __(jc local_label(have_keys))
3053        __(compare_reg_to_nil(%arg_reg))
3054        __(jne local_label(toomany))
[10092]3055        __(movss %fpzero,rcontext(tcr.save0))
[9690]3056        __(jmp *%ra0)
3057local_label(have_rest):
3058        __(pushl %arg_reg)
3059        __(btl $keyp_bit,%imm0)
3060        __(jc local_label(have_keys))
[10092]3061        __(movss %fpzero,rcontext(tcr.save0))
[9690]3062        __(jmp *%ra0)
3063        /* Ensure that arg_reg contains a proper,even-length list.  */
3064        /* Insist that its length is <= 512 (as a cheap circularity check.)   */
3065local_label(have_keys):
3066        __(movb $255,%imm0_b)
3067        __(push %arg_reg)
3068        __(push %arg_z)
3069        __(xorl %arg_z,%arg_z)
3070local_label(count_keys_loop):
3071        __(compare_reg_to_nil(%arg_reg))
3072        __(je local_label(counted_keys))
3073        __(subb $1,%imm0_b)
3074        __(jb local_label(toomany))
3075        __(movb $fulltagmask,%arg_z_bh)
3076        __(andb %arg_reg_b,%arg_z_bh)
3077        __(cmpb $fulltag_cons,%arg_z_bh)
3078        __(jne local_label(badlist))
3079        __(_cdr(%arg_reg,%arg_reg))
[12362]3080        __(compare_reg_to_nil(%arg_reg))
3081        __(je local_label(badlist))
[9690]3082        __(movb $fulltagmask,%arg_z_bh)
3083        __(andb %arg_reg_b,%arg_z_bh)
3084        __(cmpb $fulltag_cons,%arg_z_bh)
3085        __(jne local_label(badlist))
3086        __(_cdr(%arg_reg,%arg_reg))
3087        __(jmp local_label(count_keys_loop))
3088local_label(counted_keys):             
3089        /* We've got a proper, even-length list of key/value pairs in  */
3090        /* arg_reg. For each keyword var in the lambda-list, push a pair  */
3091        /* of NILs on the vstack.   */
3092        __(pop %arg_z)
3093        __(pop %arg_reg)
3094        __(movd %mm1,%imm0)
3095        __(shrl $16,%imm0)
3096        __(movzbl %imm0_b,%imm0)
[10092]3097        __(movl %esp,rcontext(tcr.unboxed0))    /* 0th value/supplied-p pair */
[9690]3098        __(jmp local_label(push_pair_test))
3099local_label(push_pair_loop):
3100        __(push $nil_value)
3101        __(push $nil_value)
3102local_label(push_pair_test):   
3103        __(subb $1,%imm0_b)
3104        __(jge local_label(push_pair_loop))
3105        __(push %temp0) /* keyword */
3106        __(push %arg_z) /* value */
3107        __(vector_length(%arg_y,%imm0))
3108        __(push %arg_reg)
3109        __(push %imm0)  /* keyword vector length */
3110        __(movd %mm1,%imm0)
[10092]3111        __(movl $0,rcontext(tcr.unboxed1)) /* count of unknown keywords seen */
[9690]3112local_label(match_keys_loop):
3113        __(movl 4(%esp),%arg_reg)
3114        __(compare_reg_to_nil(%arg_reg))
3115        __(je local_label(matched_keys))
3116        __(_car(%arg_reg,%temp0))
3117        __(_cdr(%arg_reg,%arg_reg))
3118        __(_car(%arg_reg,%arg_z))
3119        __(_cdr(%arg_reg,%arg_reg))
3120        __(movl %arg_reg,4(%esp))
3121        __(xorl %temp1,%temp1)
3122        __(jmp local_label(match_test))
3123local_label(match_loop):
[11277]3124        __(cmpl misc_data_offset(%arg_y,%temp1),%temp0)
[9690]3125        __(je local_label(matched))
3126        __(addl $node_size,%temp1)
3127local_label(match_test):
3128        __(cmpl %temp1,(%esp))  /* compare index, keyword vector length */
3129        __(jne local_label(match_loop))
3130        /* No match.  Note unknown keyword, check for :allow-other-keys   */
[10092]3131        __(addl $1,rcontext(tcr.unboxed1))
[9690]3132        __(cmpl $nrs.kallowotherkeys,%temp0)
3133        __(jne local_label(match_keys_loop))
[10092]3134        __(subl $1,rcontext(tcr.unboxed1))
[9690]3135        __(btsl $seen_aok_bit,%imm0)
3136        __(jc local_label(match_keys_loop))
3137        /* First time we've seen :allow-other-keys.  Maybe set aok_bit.   */
3138        __(compare_reg_to_nil(%arg_z))
3139        __(je local_label(match_keys_loop))
3140        __(btsl $aok_bit,%imm0)
3141        __(jmp local_label(match_keys_loop))
3142        /* Got a match.  Worry about :allow-other-keys here, too.   */
3143local_label(matched):
3144        __(negl %temp1)
3145        __(shll $1,%temp1)
[10092]3146        __(addl rcontext(tcr.unboxed0),%temp1)
[9690]3147        __(cmpl $nil_value,-node_size*2(%temp1))
3148        __(jne local_label(match_keys_loop))
3149        __(movl %arg_z,-node_size(%temp1))
3150        __(movl $t_value,-node_size*2(%temp1))
3151        __(cmpl $nrs.kallowotherkeys,%temp0)
3152        __(jne local_label(match_keys_loop))
3153        __(btsl $seen_aok_bit,%imm0)
3154        __(jnc local_label(match_keys_loop))
3155        __(compare_reg_to_nil(%arg_z))
3156        __(je local_label(match_keys_loop))
3157        __(btsl $aok_bit,%imm0)
3158        __(jmp local_label(match_keys_loop))
3159local_label(matched_keys):     
[10092]3160        __(cmpl $0,rcontext(tcr.unboxed1))      /* any unknown keys seen? */
[9690]3161        __(je local_label(keys_ok))
3162        __(btl $aok_bit,%imm0)
3163        __(jnc local_label(badkeys))
3164local_label(keys_ok):
3165        __(addl $(3*node_size),%esp)
3166        __(pop %ra0)
[10092]3167        __(movss %fpzero,rcontext(tcr.save0))
[9690]3168        __(jmp *%ra0)
3169        /* Some unrecognized keywords.  Complain generically about   */
3170        /* invalid keywords.   */
3171local_label(badkeys):
3172        __(movl $XBADKEYS,%arg_y)
3173        __(jmp local_label(destructure_error))
3174local_label(toomany):
3175        __(movl $XCALLTOOMANY,%arg_y)
3176        __(jmp local_label(destructure_error))
3177local_label(toofew):
3178        __(movl $XCALLTOOFEW,%arg_y)
3179        __(jmp local_label(destructure_error))
3180local_label(badlist):
3181        __(movl $XCALLNOMATCH,%arg_y)
3182local_label(destructure_error):
3183        __(movd %mm0,%esp)              /* undo everything done to the stack */
[10092]3184        __(movl rcontext(tcr.save0),%arg_z)     /* %whole_reg */
3185        __(movss %fpzero,rcontext(tcr.save0))
[9690]3186        __(set_nargs(2))
3187        __(push %ra0)
3188        __(jmp _SPksignalerr)
[8647]3189_endfn(C(destbind1))
[8068]3190
3191_spentry(macro_bind)
[10092]3192        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
[9690]3193        __(extract_fulltag(%arg_reg,%imm0))
3194        __(cmpb $fulltag_cons,%imm0_b)
3195        __(jne 1f)
3196        __(_cdr(%arg_reg,%arg_reg))
3197        __(jmp C(destbind1))
31981:      __(movl $XCALLNOMATCH,%arg_y)
[10092]3199        __(movl rcontext(tcr.save0),%arg_z)
3200        __(movss %fpzero,rcontext(tcr.save0))
[9690]3201        __(set_nargs(2))
3202        __(push %ra0)       
3203        __(jmp _SPksignalerr)
3204
[8068]3205_endsubp(macro_bind)
3206
3207_spentry(destructuring_bind)
[10092]3208        __(movl %arg_reg,rcontext(tcr.save0))   /* %whole_reg */
[8068]3209        __(jmp C(destbind1))
3210_endsubp(destructuring_bind)
3211
3212_spentry(destructuring_bind_inner)
[10092]3213        __(movl %arg_z,rcontext(tcr.save0))     /* %whole_reg */
[8068]3214        __(jmp C(destbind1))
3215_endsubp(destructuring_bind_inner)
3216
3217_spentry(vpopargregs)
[11314]3218        __(hlt)
[8068]3219_endsubp(vpopargregs)
3220
3221/* If arg_z is an integer, return in imm0 something whose sign  */
3222/* is the same as arg_z's.  If not an integer, error.   */
3223_spentry(integer_sign)
[8253]3224        __(mov %arg_z,%imm0)
[8068]3225        __(testb $tagmask,%arg_z_b)
3226        __(je 8f)
3227        __(extract_typecode(%arg_z,%imm0))
3228        __(cmpb $subtag_bignum,%imm0_b)
3229        __(jne 9f)
3230        __(getvheader(%arg_z,%imm0))
3231        __(shr $num_subtag_bits,%imm0)
3232        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
32338:      __(repret)
32349:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
3235_endsubp(integer_sign)
3236
[8686]3237/* "slide" nargs worth of values up the stack.  imm0 contains */
3238/* the difference between the current stack pointer and the target. */
[8068]3239_spentry(mvslide)
[8899]3240        __(movd %nargs,%mm0)
[8686]3241        __(lea (%esp,%nargs),%arg_y)
3242        __(lea (%arg_y,%imm0),%imm0)
[8899]3243        __(test %nargs,%nargs)
[8686]3244        __(je 2f)
32451:
3246        __(subl $node_size,%arg_y)
3247        __(movl (%arg_y),%arg_z)
3248        __(subl $node_size,%imm0)
3249        __(movl %arg_z,(%imm0))
[8899]3250        __(subl $node_size,%nargs)
[8686]3251        __(jne 1b)
32522:      __(movl %imm0,%esp)
[8899]3253        __(movd %mm0,%nargs)
[8686]3254        __(jmp *%ra0)
[8068]3255_endsubp(mvslide)
3256
3257_spentry(save_values)
[10092]3258        __(movd rcontext(tcr.save_tsp),%mm1)
[9379]3259/* common exit: nargs = values in this set, mm1 = ptr to tsp before call to save_values   */
[9150]3260local_label(save_values_to_tsp):
[10092]3261        __(movl %ra0,rcontext(tcr.save0))
3262        __(movl rcontext(tcr.save_tsp),%temp0)
[9150]3263        __(dnode_align(%nargs,tsp_frame.fixed_overhead+(2*node_size),%imm0)) /* count, link   */
3264        __(TSP_Alloc_Var(%imm0,%arg_z))
[10092]3265        __(movl rcontext(tcr.save_tsp),%imm0)
[9150]3266        __(movd %mm1,(%imm0))
3267        __(movl %nargs,(%arg_z))
3268        __(movl %temp0,node_size(%arg_z))
3269        __(leal 2*node_size(%arg_z,%nargs),%arg_y)
3270        __(leal (%esp,%nargs),%imm0)
3271        __(cmpl %imm0,%esp)
3272        __(jmp 2f)
32731:      __(subl $node_size,%imm0)
3274        __(movl (%imm0),%arg_z)
3275        __(subl $node_size,%arg_y)
3276        __(cmpl %imm0,%esp)
3277        __(movl %arg_z,(%arg_y))
32782:      __(jne 1b)
3279        __(addl %nargs,%esp)
[10092]3280        __(movl rcontext(tcr.save0),%ra0)
3281        __(movl $0,rcontext(tcr.save0))
[9150]3282        __(jmp *%ra0)
[8068]3283_endsubp(save_values)
3284
[9150]3285/* Add the multiple values that are on top of the vstack to the set  */
3286/* saved in the top tsp frame, popping them off of the vstack in the  */
3287/* process.  It is an error (a bad one) if the TSP contains something  */
3288/* other than a previously saved set of multiple-values.  */
3289/* Since adding to the TSP may cause a new TSP segment to be allocated,  */
3290/* each add_values call adds another linked element to the list of  */
3291/* values. This makes recover_values harder.   */
[8068]3292_spentry(add_values)
[9379]3293        /* do we need to preserve imm0? */
3294        __(test %nargs,%nargs)
[10092]3295        __(movl rcontext(tcr.save_tsp),%imm0)
[9379]3296        __(movl (%imm0),%imm0)
3297        __(movd %imm0,%mm1)     /* for the benefit of save_values_to_tsp */
3298        __(jne local_label(save_values_to_tsp))
3299        __(jmp *%ra0)
[8068]3300_endsubp(add_values)
[8647]3301
[9150]3302/* push the values in the value set atop the sp, incrementing nargs.  */
3303/* Discard the tsp frame; leave values atop the sp.   */
[8068]3304_spentry(recover_values)
[10092]3305        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
[9150]3306        __(movd %nargs,%mm0)              /* temp1 */
3307        /* First, walk the segments reversing the pointer to previous  */
3308        /* segment pointers Can tell the end because that previous  */
3309        /* segment pointer is the prev tsp pointer   */
[10092]3310        __(movl rcontext(tcr.save_tsp),%temp1)
[9150]3311        __(movl %temp1,%temp0)  /* current segment   */
3312        __(movl %temp1,%arg_y)  /* last segment   */
3313        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3314local_label(walkloop):
3315        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3316        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3317        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3318        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3319        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3320        __(jne local_label(walkloop))
3321
3322        __(movl %temp1,%arg_z)
3323        __(movd %mm0,%nargs)
3324        /* the final segment pointer is now in %arg_y  */
3325        /* walk backwards, pushing values on the stack and incrementing %nargs   */
3326local_label(pushloop):
3327        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment   */
3328        __(test %imm0,%imm0)
3329        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3330        __(leal (%nargs,%imm0),%nargs)
3331        __(jmp 2f)
33321:      __(push -node_size(%temp0))
3333        __(subl $node_size,%temp0)
3334        __(subl $fixnum_one,%imm0)
33352:      __(jne 1b)
3336        __(cmpl %arg_y,%arg_z)
3337        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3338        __(jne local_label(pushloop))
3339        __(movl (%arg_z),%arg_z)
[10092]3340        __(movl %arg_z,rcontext(tcr.save_tsp))
3341        __(movl %arg_z,rcontext(tcr.next_tsp))
3342        __(movl rcontext(tcr.save0),%ra0)
3343        __(movl $0,rcontext(tcr.save0))
[9150]3344        __(jmp *%ra0)           
[8068]3345_endsubp(recover_values)
[8647]3346
[9379]3347/* Exactly like recover_values, but it's necessary to reserve an outgoing  */
3348/* frame if any values (which will be used as outgoing arguments) will  */
3349/* wind up on the stack.  We can assume that %nargs contains 0 (and  */
3350/* that no other arguments have been pushed) on entry.   */
3351
[8068]3352_spentry(recover_values_for_mvcall)
[10092]3353        __(movl %ra0,rcontext(tcr.save0)) /* temp0 */
[9379]3354        /* First, walk the segments reversing the pointer to previous  */
3355        /* segment pointers Can tell the end because that previous  */
3356        /* segment pointer is the prev tsp pointer   */
3357        __(xorl %nargs,%nargs)
3358        __(push %nargs)
[10092]3359        __(movl rcontext(tcr.save_tsp),%temp1)
[9379]3360        __(movl %temp1,%temp0)  /* current segment   */
3361        __(movl %temp1,%arg_y)  /* last segment   */
3362        __(movl tsp_frame.backlink(%temp1),%arg_z)      /* previous tsp   */
3363local_label(walkloop_mvcall):
3364        __(movl tsp_frame.data_offset(%temp0),%imm0)
3365        __(addl %imm0,(%esp))
3366        __(movl tsp_frame.fixed_overhead+node_size(%temp0),%imm0)
3367        __(cmpl %imm0,%arg_z)   /* last segment ?   */
3368        __(movl %arg_y,tsp_frame.fixed_overhead+node_size(%temp0))
3369        __(movl %temp0,%arg_y)  /* last segment <- current segment   */
3370        __(movl %imm0,%temp0)   /* current segment <- next segment   */
3371        __(jne local_label(walkloop_mvcall))
3372
3373        __(movl %temp1,%arg_z)
3374        __(pop %nargs)
3375
3376        __(cmpl $nargregs*node_size,%nargs)
3377        __(jbe local_label(pushloop_mvcall))
3378        __(push $reserved_frame_marker)
3379        __(push $reserved_frame_marker)
3380
3381        /* the final segment pointer is now in %arg_y  */
3382        /* walk backwards, pushing values on the stack and incrementing %nargs*/
3383local_label(pushloop_mvcall):
3384        __(movl tsp_frame.data_offset(%arg_y),%imm0)    /* nargs in segment */
3385        __(test %imm0,%imm0)
3386        __(leal tsp_frame.data_offset+(2*node_size)(%arg_y,%imm0),%temp0)
3387        __(jmp 2f)
33881:      __(push -node_size(%temp0))
3389        __(subl $node_size,%temp0)
3390        __(subl $fixnum_one,%imm0)
33912:      __(jne 1b)
3392        __(cmpl %arg_y,%arg_z)
3393        __(movl tsp_frame.data_offset+node_size(%arg_y),%arg_y)
3394        __(jne local_label(pushloop_mvcall))
3395        __(movl (%arg_z),%arg_z)
[10092]3396        __(movl %arg_z,rcontext(tcr.save_tsp))
3397        __(movl %arg_z,rcontext(tcr.next_tsp))
3398        __(movl rcontext(tcr.save0),%ra0)
3399        __(movl $0,rcontext(tcr.save0))
[9379]3400        __(jmp *%ra0)           
[8068]3401_endsubp(recover_values_for_mvcall)
[8647]3402
[8068]3403_spentry(reset)
[11314]3404        __(hlt)
[8068]3405_endsubp(reset)
3406
[8647]3407/* temp0 = element-count, arg_y = subtag, arg_z = initval */
[8068]3408_spentry(misc_alloc_init)
[8647]3409        __(push %ebp)
3410        __(movl %esp,%ebp)
3411        __(push %arg_z)
3412        __(movl %arg_y,%arg_z)
3413        __(movl %temp0,%arg_y)
3414        __(push $local_label(misc_alloc_init_back))
3415        __(jmp _SPmisc_alloc)
3416__(tra(local_label(misc_alloc_init_back)))
3417        __(pop %arg_y)
3418        __(leave)
3419        __(movl $nrs.init_misc,%fname)
3420        __(set_nargs(2))
3421        __(jump_fname())
[8068]3422_endsubp(misc_alloc_init)
[8647]3423
[11314]3424/* %temp1 = element-count, %arg_y = subtag, %arg_z = initial-value */       
[8068]3425_spentry(stack_misc_alloc_init)
[11314]3426        __(push %ebp)
3427        __(movl %esp,%ebp)
3428        __(push %arg_z)
3429        __(movl %arg_y,%arg_z)
3430        __(movl %temp1,%arg_y)
3431        __(pushl $local_label(stack_misc_alloc_init_back))
3432        __(jmp _SPstack_misc_alloc)
3433__(tra(local_label(stack_misc_alloc_init_back)))
3434        __(popl %arg_y)
3435        __(leave)
3436        __(movl $nrs.init_misc,%fname)
3437        __(set_nargs(2))
3438        __(jump_fname())
[8068]3439_endsubp(stack_misc_alloc_init)
3440
3441        .globl C(popj)
3442_spentry(popj)
3443C(popj):
3444        __(leave)
3445        __(ret)
3446_endsubp(popj)
3447
[8823]3448/* arg_z should be of type (signed-byte 64) */
3449/* return unboxed value in mm0 */
[8068]3450_spentry(gets64)
[8828]3451        __(testb $fixnummask,%arg_z_b)
3452        __(jne 1f)
3453        __(unbox_fixnum(%arg_z,%imm0))
3454        __(movd %imm0,%mm0)
3455        __(jns 8f)
3456        /* get sign into upper half of %mm0 */
3457        __(pcmpeqd %mm1,%mm1)   /* all ones */
3458        __(psllq $32,%mm1)
3459        __(por %mm1,%mm0)
3460        __(ret)
34611:      __(movb %arg_z_b,%imm0_b)
3462        __(andb $tagmask,%imm0_b)
3463        __(cmpb $tag_misc,%imm0_b)
3464        __(jne 9f)
[11051]3465        __(movl misc_header_offset(%arg_z),%imm0)
[8828]3466        __(cmpb $subtag_bignum,%imm0_b)
3467        __(jne 9f)
3468        __(cmpl $two_digit_bignum_header,%imm0)
[11051]3469        __(ja 9f)
3470        __(movd misc_data_offset(%arg_z),%mm0)
3471        __(jne 8f)
3472        __(movq misc_data_offset(%arg_z),%mm0)
[8828]34738:      __(repret)
[11052]34749:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_s64))
[8068]3475_endsubp(gets64)
[8647]3476
[8068]3477/* arg_z should be of type (unsigned-byte 64) */
3478/* return unboxed value in mm0 */
3479_spentry(getu64)
3480        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
3481        __(testl %arg_z,%imm0)
3482        __(movl %arg_z,%imm0)
3483        __(jne 1f)
3484        __(sarl $fixnumshift,%imm0)
3485        __(movd %imm0,%mm0)
3486        __(ret)
34871:      __(andb $tagmask,%imm0_b)
3488        __(cmpb $tag_misc,%imm0_b)
3489        __(jne 9f)
[11053]3490        __(movl misc_header_offset(%arg_z),%imm0)
[8068]3491        __(cmpb $subtag_bignum,%imm0_b)
3492        __(jne 9f)
3493        __(cmpl $three_digit_bignum_header,%imm0)
[11053]3494        __(ja 9f)
[8068]3495        __(je 3f)
3496        __(cmpl $two_digit_bignum_header,%imm0)
[11053]3497        __(je 2f)
3498        /* must be a one digit bignum */
3499        __(movl misc_data_offset(%arg_z),%imm0)
3500        __(test %imm0,%imm0)
3501        __(js 9f)
3502        __(movd %imm0,%mm0)
3503        __(ret)
35042:      __(movl misc_data_offset+4(%arg_z),%imm0)
[8068]3505        __(testl %imm0,%imm0)
3506        __(js 9f)
[8834]3507        __(movq misc_data_offset(%arg_z),%mm0)
3508        __(ret)
[8068]35093:      __(movl misc_data_offset(%arg_z),%imm0)
3510        __(cmpl $0,misc_data_offset+8(%arg_z))
3511        __(jne 9f)
[8834]3512        __(movq misc_data_offset(%arg_z),%mm0)
[8068]3513        __(repret)
35149:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
3515_endsubp(getu64)
3516
[9616]3517/* Make unsigned integer from value in mm0 */
[8068]3518_spentry(makeu64)
[9616]3519        __(movq %mm0,%mm1)
3520        __(psrlq $32,%mm0)
3521        __(movd %mm0,%imm0)
3522        __(test %imm0,%imm0)
3523        __(js 3f)
3524        __(jnz 2f)
3525        __(movd %mm1,%imm0)
3526        __(cmpl $target_most_positive_fixnum,%imm0)
3527        __(ja 1f)
3528        __(box_fixnum(%imm0,%arg_z))
3529        __(ret)
35301:      /* maybe make a 1 digit bignum */
3531        __(test %imm0,%imm0)
3532        __(js 2f)
3533        __(movl $one_digit_bignum_header,%imm0)
3534        __(movd %imm0,%mm0)
3535        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
3536        __(movd %mm1,misc_data_offset(%arg_z))
3537        __(ret)
3538        /* make a 2 digit bignum */
35392:      __(movl $two_digit_bignum_header,%imm0)
3540        __(movd %imm0,%mm0)
3541        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
3542        __(movq %mm1,misc_data_offset(%arg_z))
3543        __(ret)
3544        /* make a 3 digit bignum */
35453:      __(movl $three_digit_bignum_header,%imm0)
3546        __(movd %imm0,%mm0)
3547        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(3)))
3548        __(movq %mm1,misc_data_offset(%arg_z))
3549        __(ret)
[8068]3550_endsubp(makeu64)
[8350]3551
3552/* on entry: arg_z = symbol.  On exit, arg_z = va