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

Last change on this file since 8209 was 8209, checked in by rme, 13 years ago

SPspecset, SPspecrefcheck

File size: 21.8 KB
Line 
1        include(lisp.s)
2
3        .align 2
4define([_spentry],[ifdef([__func_name],[_endfn],[])
5        .p2align 3
6        _exportfn(_SP$1)
7])
8
9define([_endsubp],[
10        _endfn(_SP$1)
11])
12
13define([jump_builtin],[
14        ref_nrs_value(builtin_functions,%fname)
15        set_nargs($2)
16        vrefr(%fname,%fname,$1)
17        jump_fname()
18])
19
20_spentry(bad_funcall)   
21        .globl C(bad_funcall)   
22__(tra(C(bad_funcall)))
23        __(uuo_error_not_callable)
24_endsubp(bad_funcall)
25
26/* %arg_z has overflowed by one bit.  Make a bignum with 1 (32-bit) digit. */
27_spentry(fix_overflow)
28C(fix_one_bit_overflow):
29        __(movl $one_digit_bignum_header,%imm0)
30        __(movd %imm0,%mm0)
31        __(Misc_Alloc_Fixed([],aligned_bignum_size(1)))
32        __(unbox_fixnum(%arg_z,%imm0))
33        __(xor $0xc0000000,%imm0)
34        __(mov %temp0,%arg_z)
35        __(movl %imm0,misc_data_offset(%arg_z))
36        __(ret)
37_endsubp(fix_overflow)
38
39_spentry(misc_ref)
40        __(int $3)
41_endsubp(misc_ref)
42
43_startfn(C(misc_ref_common))
44        __(int $3)
45_endfn(C(misc_ref_common))
46
47_spentry(subtag_misc_ref)
48        __(int $3)
49_endsubp(subtag_misc_ref)
50
51_spentry(subtag_misc_set)
52        __(int $3)
53_endsubp(subtag_misc_set)
54
55_spentry(misc_set)
56        __(int $3)
57_endsubp(misc_set)
58
59_startfn(C(misc_set_common))
60        __(ret)
61_endfn(C(misc_set_common))
62
63_spentry(Fret1valn)
64        .globl C(ret1valn)
65__(tra(C(ret1valn)))
66        __(mov (%esp),%ra0)
67        __(mov %arg_z,(%esp))
68        __(set_nargs(1))
69        __(jmp *%ra0)
70_endsubp(Fret1valn)
71
72_spentry(nvalret)
73        .globl C(nvalret)                       
74C(nvalret):
75        __(leave)
76        __(ret)
77_endsubp(nvalret)
78
79_spentry(jmpsym)
80        __(jump_fname())
81_endsubp(jmpsym)
82
83_spentry(jmpnfn)
84        __(mov %temp0,%fn)
85        __(jmp *%fn)
86_endsubp(jmpnfn)
87
88_spentry(funcall)
89        __(do_funcall())
90_endsubp(funcall)
91
92/* Make a lisp integer (fixnum or one-digit bignum) from the value in %imm0 */
93/* This is slightly icky because we have only 1 immediate register */
94_spentry(makes32)
95        __(movd %imm0,%mm1)
96        __(shll $fixnumshift, %imm0)
97        __(movl %imm0,%arg_z)
98        __(movd %mm1,%imm0)
99        __(sarl $24,%imm0)
100        __(movb %al,%ah)
101        __(shlb $fixnumshift,%al)
102        __(sarb $fixnumshift,%al)
103        __(cmpb %al,%ah)                /* high bits just sign? */
104        __(je,pt 0f)                    /* yes, value fits in a fixnum */
105        __(movl $one_digit_bignum_header,%imm0)
106        __(movd %imm0,%mm0)
107        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(1)))
108        __(movd %mm1,misc_data_offset(%arg_z))
1090:      __(repret)
110_endsubp(makes32)
111
112_spentry(makes64)
113        __(int $3)
114_endsubp(makes64)       
115
116/* xxx make lisp integer out of mm0 */
117/* Make a lisp integer (probably a bignum) out of the %edx:%eax pair. */
118/* We assume that the node_regs_mask in the TCR has been set to mark */
119/* %edx an immediate register. */
120_startfn(C(makes64))
121        __(movd %eax,%mm1)
122        __(sarl $31,%eax)
123        __(cmpl %eax,%edx)      /* upper bits just sign extension? */
124        __(movd %mm1,%eax)
125        __(je _SPmakes32)       /* yes, make a 32 bit integer */
126        __(movl $two_digit_bignum_header,%eax)
127        __(movd %eax,%mm0)
128        __(Misc_Alloc_Fixed(%arg_z,aligned_bignum_size(2)))
129        __(movd %mm1,misc_data_offset(%arg_z))
130        __(movl %edx,misc_data_offset+4(%arg_z))
131        __(ret)
132_endfn
133
134
135_spentry(syscall)
136        /* Save lisp registers */
137        __(push %ebp)
138        __(movl %esp,%ebp)
139        __(push %temp0)
140        __(push %temp1)
141        __(push %arg_y)
142        __(push %arg_z)
143        __(push %fn)
144        __(movl %esp,%rcontext:tcr.save_vsp)
145        __(movl %ebp,%rcontext:tcr.save_ebp)
146        __(movl $TCR_STATE_FOREIGN,%rcontext:tcr.valence)
147        __(movl %rcontext:tcr.foreign_sp,%esp)
148        __(emms)
149        __(movl (%esp),%ebp)
150        __(addl $2*node_size,%esp)
151        __(unbox_fixnum(%arg_z,%eax))
152        /* push syscall args on stack */
153        __(int $0x80)
154        __(movl %ebp,%esp)
155        __(movl %esp,%rcontext:tcr.foreign_sp)
156        __(zero_node_regs)
157        __(pxor %fpzero,%fpzero)
158        __(movl %rcontext:tcr.save_vsp,%esp)
159        __(movl %rcontext:tcr.save_ebp,%ebp)
160        __(movl $TCR_STATE_LISP,%rcontext:tcr.valence)
161        __(pop %fn)
162        __(pop %arg_z)
163        __(pop %arg_y)
164        __(pop %temp1)
165        __(check_pending_interrupt(%temp0))
166        __(push %temp0)
167        __(leave)
168        __(ret)
169_endsubp(syscall)
170
171_spentry(mkcatch1v)
172        __(nMake_Catch(0))
173        __(ret)
174_endsubp(mkcatch1v)
175
176_spentry(mkunwind)
177        __(int $3)
178_endsubp(mkunwind)
179       
180/* this takes a return address in %ra0; it's "new" in that it does the */
181/*   double binding of *interrupt-level* out-of-line */
182_spentry(nmkunwind)
183        __(int $3)
184_endsubp(nmkunwind)
185
186_spentry(mkcatchmv)
187        __(int $3)
188_endsubp(mkcatchmv)
189
190_spentry(throw)
191        __(int $3)
192_endsubp(throw)
193
194/* This takes N multiple values atop the vstack.   */
195_spentry(nthrowvalues)
196        __(int $3)
197_endsubp(nthrowvalues)
198
199/* This is a (slight) optimization.  When running an unwind-protect,  */
200/* save the single value and the throw count in the tstack frame.  */
201/* Note that this takes a single value in arg_z.  */
202       
203_spentry(nthrow1value)
204        __(int $3)
205_endsubp(nthrow1value)
206
207/* This never affects the symbol's vcell   */
208/* Non-null symbol in arg_y, new value in arg_z           */
209       
210_spentry(bind)
211        __(int $3)
212_endsubp(bind)
213
214/* arg_z = symbol: bind it to its current value  */
215       
216_spentry(bind_self)
217        __(int $3)
218_endsubp(bind_self)
219
220_spentry(bind_nil)
221        __(int $3)
222_endsubp(bind_nil)
223
224_spentry(bind_self_boundp_check)
225        __(int $3)
226_endsubp(bind_self_boundp_check)
227
228_spentry(conslist)
229        __(int $3)
230_endsubp(conslist)
231
232/* do list*: last arg in arg_z, all others pushed, nargs set to #args pushed.  */
233/* Cons, one cons cell at at time.  Maybe optimize this later.  */
234       
235_spentry(conslist_star)
236        __(int $3)
237_endsubp(conslist_star)
238
239/* We always have to create a tsp frame (even if nargs is 0), so the compiler   */
240/* doesn't get confused.   */
241_spentry(stkconslist)
242        __(int $3)
243_endsubp(stkconslist)
244
245/* do list*: last arg in arg_z, all others vpushed,   */
246/*      nargs set to #args vpushed.  */
247       
248_spentry(stkconslist_star)
249        __(int $3)
250_endsubp(stkconslist_star)
251
252
253/* Make a stack-consed simple-vector out of the NARGS objects   */
254/*      on top of the vstack; return it in arg_z.  */
255       
256_spentry(mkstackv)
257        __(int $3)
258_endsubp(mkstackv)
259
260        .globl C(egc_write_barrier_start)
261C(egc_write_barrier_start):
262/*  */
263/* The function pc_luser_xp() - which is used to ensure that suspended threads  */
264/* are suspended in a GC-safe way - has to treat these subprims (which implement  */
265/* the EGC write-barrier) specially.  Specifically, a store that might introduce  */
266/* an intergenerational reference (a young pointer stored in an old object) has  */
267/* to "memoize" that reference by setting a bit in the global "refbits" bitmap.  */
268/* This has to happen atomically, and has to happen atomically wrt GC.  */
269
270/* Note that updating a word in a bitmap is itself not atomic, unless we use  */
271/* interlocked loads and stores.  */
272
273/* For RPLACA and RPLACD, things are fairly simple: regardless of where we are  */
274/* in the function, we can do the store (even if it's already been done) and  */
275/* calculate whether or not we need to set the bit out-of-line.  (Actually  */
276/* setting the bit needs to be done atomically, unless we're sure that other  */
277/* threads are suspended.)  */
278/* We can unconditionally set the suspended thread's RIP to the return address.  */
279
280_spentry(rplaca)
281        .globl C(egc_rplaca)
282C(egc_rplaca):
283        __(int $3)
284_endsubp(rplaca)
285
286_spentry(rplacd)
287        .globl C(egc_rplacd)
288C(egc_rplacd):
289        __(int $3)
290_endsubp(rplacd)
291
292/* args (src, unscaled-idx, val) in temp0, arg_y, arg_z */
293_spentry(gvset)
294        .globl C(egc_gvset)
295C(egc_gvset):
296        __(int $3)
297_endsubp(gvset)
298
299_spentry(set_hash_key)
300        .globl C(egc_set_hash_key)
301C(egc_set_hash_key): 
302        __(int $3)
303_endsubp(set_hash_key)
304
305/* This is a little trickier: if this is interrupted, we need to know  */
306/* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
307/* If we're interrupted   before the PC has reached the "success_test" label,   */
308/* repeat (luser the PC back to .SPstore_node_conditional.)  If we're at that  */
309/* label with the Z flag set, we won and (may) need to memoize.  */
310
311_spentry(store_node_conditional)
312        .globl C(egc_store_node_conditional)
313C(egc_store_node_conditional):
314        .globl C(egc_store_node_conditional_success_test)
315C(egc_store_node_conditional_success_test):
316        .globl C(egc_write_barrier_end)
317C(egc_write_barrier_end):
318        __(int $3)
319_endsubp(store_node_conditional)
320
321_spentry(setqsym)
322        __(bt $sym_vbit_const,symbol.flags(%arg_y))
323        __(jae _SPspecset)
324        __(mov %arg_y,%arg_z)
325        __(mov $XCONST,%arg_y)
326        __(set_nargs(2))
327        __(jmp _SPksignalerr)
328_endsubp(setqsym)
329
330_spentry(progvsave)
331        __(int $3)
332_endsubp(progvsave)
333
334/* Allocate node objects on the temp stack, immediate objects on the foreign  */
335/* stack. (The caller has to know which stack to discard a frame from.)  */
336/* %arg_y = boxed element-count, %arg_z = boxed subtype  */
337       
338_spentry(stack_misc_alloc)
339        __(int $3)
340_endsubp(stack_misc_alloc)
341
342/* subtype (boxed, of course) is pushed, followed by nargs bytes worth of   */
343/* initial-contents.  Note that this can be used to cons any type of initialized   */
344/* node-header'ed misc object (symbols, closures, ...) as well as vector-like   */
345/* objects.   */
346_spentry(gvector)
347        __(int $3)
348_endsubp(gvector)
349
350_spentry(mvpass)
351        __(int $3)
352_endsubp(mvpass)
353
354_spentry(nthvalue)
355        __(int $3)
356_endsubp(nthvalue)
357
358_spentry(values)
359        __(int $3)
360_endsubp(values)
361       
362_spentry(default_optional_args)
363        __(int $3)
364_endsubp(default_optional_args)
365
366_spentry(opt_supplied_p)
367        __(int $3)
368_endsubp(opt_supplied_p)
369
370_spentry(lexpr_entry)
371        __(int $3)
372_endsubp(lexpr_entry)
373       
374_spentry(heap_rest_arg)
375        __(int $3)
376_endsubp(heap_rest_arg)
377       
378/* %imm0 contains the number of fixed args ; make an &rest arg out of the others   */
379_spentry(req_heap_rest_arg)
380        __(int $3)
381_endsubp(req_heap_rest_arg)
382
383/* %imm0 bytes of stuff has already been pushed   */
384/* make an &rest arg out of any others   */
385_spentry(heap_cons_rest_arg)
386        __(int $3)
387_endsubp(heap_cons_rest_arg)
388
389_spentry(simple_keywords)
390        __(xor %imm0,%imm0)
391        __(push_argregs())
392        __(jmp _SPkeyword_bind)
393_endsubp(simple_keywords)
394
395_spentry(keyword_args)
396        __(push_argregs())
397        __(jmp _SPkeyword_bind)
398_endsubp(keyword_args)
399       
400/* There are %nargs words of arguments on the stack; %imm0 contains the number  */
401/* of non-keyword args pushed.  It's possible that we never actually got  */
402/* any keyword args, which would make things much simpler.   */
403
404/* On entry, temp1 contains a fixnum with bits indicating whether   */
405/* &allow-other-keys and/or &rest was present in the lambda list.  */
406/* Once we get here, we can use the arg registers.  */
407
408define([keyword_flags_aok_bit],[fixnumshift])
409define([keyword_flags_unknown_keys_bit],[fixnumshift+1])
410define([keyword_flags_rest_bit],[fixnumshift+2])
411define([keyword_flags_seen_aok_bit],[fixnumshift+3])       
412       
413_spentry(keyword_bind)
414        __(int $3)
415_endsubp(keyword_bind)
416
417_spentry(ksignalerr)
418        __(mov $nrs.errdisp,%fname)
419        __(jump_fname) 
420_endsubp(ksignalerr)
421
422_spentry(stack_rest_arg)
423        __(xorl %imm0,%imm0)
424        __(push_argregs())
425        __(jmp _SPstack_cons_rest_arg)
426_endsubp(stack_rest_arg)
427
428_spentry(req_stack_rest_arg)
429        __(push_argregs())
430        __(jmp _SPstack_cons_rest_arg)
431_endsubp(req_stack_rest_arg)
432
433_spentry(stack_cons_rest_arg)
434_endsubp(stack_cons_rest_arg)
435
436_spentry(getxlong)
437        __(int $3)
438_endsubp(getxlong)
439
440/* Have to be a little careful here: the caller may or may not have pushed  */
441/*   an empty frame, and we may or may not have needed one.  We can't easily  */
442/*   tell whether or not a frame will be needed (if the caller didn't reserve  */
443/*   a frame, whether or not we need one depends on the length of the list  */
444/*   in arg_z.  So, if the caller didn't push a frame, we do so ; once everything'*/
445/*   been spread, we discard the reserved frame (regardless of who pushed it)  */
446/*   if all args fit in registers.   */
447_spentry(spreadargz)
448        __(int $3)
449_endsubp(spreadargz)
450
451       
452/* Caller built it's own frame when it was entered.  If all outgoing args  */
453/* are in registers, we can discard that frame; otherwise, we copy outgoing  */
454/* relative to it and restore %rbp/%ra0   */
455_spentry(tfuncallgen)
456        __(int $3)
457_endsubp(tfuncallgen)
458
459/* Some args were pushed; move them down in the frame   */
460_spentry(tfuncallslide)
461        __(int $3)
462_endsubp(tfuncallslide)
463
464/* No args were pushed; recover saved context & do funcall        */
465_spentry(tfuncallvsp)
466        __(leave)
467        __(do_funcall())
468_endsubp(tfuncallvsp)
469
470_spentry(tcallsymgen)
471        __(int $3)
472_endsubp(tcallsymgen)
473
474_spentry(tcallsymslide)
475        __(int $3)
476_endsubp(tcallsymslide)
477
478_spentry(tcallsymvsp)
479        __(leave)
480        __(jump_fname())
481_endsubp(tcallsymvsp)
482
483_spentry(tcallnfngen)
484        __(int $3)
485_endsubp(tcallnfngen)
486       
487_spentry(tcallnfnslide)
488        __(int $3)
489_endsubp(tcallnfnslide)
490
491_spentry(tcallnfnvsp)
492        __(mov %temp0,%fn)
493        __(leave)
494        __(jmp *%fn)
495_endsubp(tcallnfnvsp)
496
497_spentry(makestackblock)
498        __(int $3)
499_endsubp(makestackblock)
500       
501_spentry(makestackblock0)
502        __(int $3)
503_endsubp(makestackblock0)
504       
505_spentry(makestacklist)
506        __(int $3)
507_endsubp(makestacklist)
508       
509_spentry(stkgvector)
510        __(int $3)
511_endsubp(stkgvector)
512
513_spentry(misc_alloc)
514        __(int $3)
515_endsubp(misc_alloc)
516
517_startfn(C(destbind1))
518        __(jmp *%ra0)
519_endfn(C(destbind1))   
520
521_spentry(macro_bind)
522        __(int $3)
523_endsubp(macro_bind)
524
525_spentry(destructuring_bind)
526        __(mov %arg_reg,%whole_reg)
527        __(jmp C(destbind1))
528_endsubp(destructuring_bind)
529
530_spentry(destructuring_bind_inner)
531        __(mov %arg_z,%whole_reg)
532        __(jmp C(destbind1))
533_endsubp(destructuring_bind_inner)
534
535_spentry(vpopargregs)
536        __(int $3)
537_endsubp(vpopargregs)
538
539/* If arg_z is an integer, return in imm0 something whose sign  */
540/* is the same as arg_z's.  If not an integer, error.   */
541_spentry(integer_sign)
542        __(testb $tagmask,%arg_z_b)
543        __(mov %arg_z,%imm0)
544        __(je 8f)
545        __(extract_typecode(%arg_z,%imm0))
546        __(cmpb $subtag_bignum,%imm0_b)
547        __(jne 9f)
548        __(getvheader(%arg_z,%imm0))
549        __(shr $num_subtag_bits,%imm0)
550        __(movl misc_data_offset-4(%arg_z,%imm0,4),%imm0)
5518:      __(repret)
5529:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_integer))
553_endsubp(integer_sign)
554
555_spentry(mvslide)
556        __(int $3)
557_endsubp(mvslide)
558
559_spentry(save_values)
560        __(int $3)
561_endsubp(save_values)
562
563_spentry(add_values)
564        __(int $3)
565_endsubp(add_values)
566                                       
567_spentry(recover_values)
568        __(int $3)
569_endsubp(recover_values)
570                                       
571_spentry(recover_values_for_mvcall)
572        __(int $3)
573_endsubp(recover_values_for_mvcall)
574                                       
575_spentry(reset)
576        __(int $3)
577_endsubp(reset)
578
579_spentry(misc_alloc_init)
580        __(int $3)
581_endsubp(misc_alloc_init)
582       
583_spentry(stack_misc_alloc_init)
584        __(int $3)
585_endsubp(stack_misc_alloc_init)
586
587        .globl C(popj)
588_spentry(popj)
589C(popj):
590        __(leave)
591        __(ret)
592_endsubp(popj)
593
594
595_spentry(gets64)
596        __(int $3)
597_endsubp(gets64)
598       
599       
600/* arg_z should be of type (unsigned-byte 64) */
601/* return unboxed value in mm0 */
602_spentry(getu64)
603        __(movl $~(target_most_positive_fixnum << fixnumshift),%imm0)
604        __(testl %arg_z,%imm0)
605        __(movl %arg_z,%imm0)
606        __(jne 1f)
607        __(sarl $fixnumshift,%imm0)
608        __(movd %imm0,%mm0)
609        __(ret)
6101:      __(andb $tagmask,%imm0_b)
611        __(cmpb $tag_misc,%imm0_b)
612        __(jne 9f)
613        __(movb misc_subtag_offset(%arg_z),%imm0_b)
614        __(cmpb $subtag_bignum,%imm0_b)
615        __(jne 9f)
616        __(movl misc_header_offset(%arg_z),%imm0)
617        __(cmpl $three_digit_bignum_header,%imm0)
618        __(je 3f)
619        __(cmpl $two_digit_bignum_header,%imm0)
620        __(jne 9f)
621        __(movl misc_data_offset(%arg_z),%imm0)
622        __(testl %imm0,%imm0)
623        __(js 9f)
624        __(repret)
6253:      __(movl misc_data_offset(%arg_z),%imm0)
626        __(cmpl $0,misc_data_offset+8(%arg_z))
627        __(jne 9f)
628        __(repret)
6299:      __(uuo_error_reg_not_type(Rarg_z,error_object_not_u64))
630_endsubp(getu64)
631
632_spentry(makeu64)
633        __(int $3)
634_endsubp(makeu64)
635       
636_spentry(specref)
637        __(int $3)
638_endsubp(specref)
639
640/* arg_y = special symbol, arg_z = new value. */
641_spentry(specset)
642        __(movl symbol.binding_index(%arg_y),%imm0)
643        __(cmp %rcontext:tcr.tlb_limit,%imm0)
644        __(movl %rcontext:tcr.tlb_pointer,%temp1)
645        __(jae 1f)
646        __(movl (%temp1,%imm0),%temp0)
647        __(cmpb $no_thread_local_binding_marker,%temp0_b)
648        __(je 1f)
649        __(movl %arg_z,(%temp1,%imm0))
650        __(ret)
6511:      __(movl %arg_y,%temp0)
652        __(movl $1<<fixnumshift,%arg_y)
653        __(jmp _SPgvset)
654_endsubp(specset)
655       
656_spentry(specrefcheck)
657        __(movl symbol.binding_index(%arg_z),%imm0)
658        __(cmp %rcontext:tcr.tlb_limit,%imm0)
659        __(movl %rcontext:tcr.tlb_pointer,%temp1)
660        __(mov %arg_z,%arg_y)
661        __(jae 7f)
662        __(movl (%temp1,%imm0),%arg_z)
663        __(cmpb $no_thread_local_binding_marker,%arg_z_b)
664        __(jne 8f)
6657:      __(movl symbol.vcell(%arg_y),%arg_z)
6668:      __(cmpb $unbound_marker,%arg_z_b)
667        __(jne,pt 9f)
668        __(uuo_error_reg_unbound(Rarg_y))
6699:      __(repret)             
670_endsubp(specrefcheck)
671
672_spentry(restoreintlevel)
673        __(int $3)
674_endsubp(restoreintlevel)
675
676_spentry(makeu32)
677        __(int $3)
678_endsubp(makeu32)
679
680_spentry(gets32)
681        __(int $3)
682_endsubp(gets32)
683
684_spentry(getu32)
685        __(int $3)
686_endsubp(getu32)
687
688_spentry(mvpasssym)
689        __(int $3)
690_endsubp(mvpasssym)
691
692_spentry(unbind)
693        __(int $3)
694_endsubp(unbind)
695
696_spentry(unbind_n)
697        __(int $3)
698_endsubp(unbind_n)
699
700_spentry(unbind_to)
701        __(int $3)
702_endsubp(unbind_to)
703
704_spentry(bind_interrupt_level_0)
705        __(int $3)
706_endsubp(bind_interrupt_level_0)
707
708_spentry(bind_interrupt_level_m1)
709        __(int $3)
710_endsubp(bind_interrupt_level_m1)
711
712_spentry(bind_interrupt_level)
713        __(int $3)
714_endsubp(bind_interrupt_level)
715
716_spentry(unbind_interrupt_level)
717        __(int $3)
718_endsubp(unbind_interrupt_level)
719
720_spentry(progvrestore)
721        __(int $3)
722_endsubp(progvrestore)
723
724_spentry(builtin_plus)
725        __(int $3)
726_endsubp(builtin_plus)
727
728_spentry(builtin_minus)
729        __(int $3)
730_endsubp(builtin_minus)
731
732_spentry(builtin_times)
733        __(int $3)
734_endsubp(builtin_times)
735
736_spentry(builtin_div)
737        __(jump_builtin(_builtin_div,2))
738
739/* %arg_z <- (= %arg_y %arg_z).   */
740_spentry(builtin_eq)
741        __(movl %arg_y,%imm0)
742        __(orb %arg_z_b,%imm0_b)
743        __(testb $fixnummask,%imm0_b)
744        __(jne 1f)
745        __(rcmpl(%arg_z,%arg_y))
746        __(condition_to_boolean(e,%imm0,%arg_z))
747        __(ret)
7481:      __(jump_builtin(_builtin_eq,2))
749_endsubp(builtin_eq)
750       
751/* %arg_z <- (/= %arg_y %arg_z).          */
752_spentry(builtin_ne)
753        __(movl %arg_y,%imm0)
754        __(orb %arg_z_b,%imm0_b)
755        __(testb $fixnummask,%imm0_b)
756        __(jne 1f)
757        __(rcmpl(%arg_z,%arg_y))
758        __(condition_to_boolean(ne,%imm0,%arg_z))
759        __(ret)
7601:      __(jump_builtin(_builtin_ne,2))
761_endsubp(builtin_ne)
762       
763/* %arg_z <- (> %arg_y %arg_z).   */
764_spentry(builtin_gt)
765        __(movl %arg_y,%imm0)
766        __(orb %arg_z_b,%imm0_b)
767        __(testb $fixnummask,%imm0_b)
768        __(jne 1f)
769        __(rcmpl(%arg_y,%arg_z))
770        __(condition_to_boolean(g,%imm0,%arg_z))
771        __(ret)
7721:      __(jump_builtin(_builtin_gt,2))
773_endsubp(builtin_gt)
774
775/* %arg_z <- (>= %arg_y %arg_z).          */
776_spentry(builtin_ge)
777        __(movl %arg_y,%imm0)
778        __(orb %arg_z_b,%imm0_b)
779        __(testb $fixnummask,%imm0_b)
780        __(jne 1f)
781        __(rcmpl(%arg_y,%arg_z))
782        __(condition_to_boolean(ge,%imm0,%arg_z))
783        __(ret)
7841:      __(jump_builtin(_builtin_ge,2))
785_endsubp(builtin_ge)
786       
787/* %arg_z <- (< %arg_y %arg_z).   */
788_spentry(builtin_lt)
789        __(movl %arg_y,%imm0)
790        __(orb %arg_z_b,%imm0_b)
791        __(testb $fixnummask,%imm0_b)
792        __(jne 1f)
793        __(rcmpl(%arg_y,%arg_z))
794        __(condition_to_boolean(l,%imm0,%arg_z))
795        __(ret)
7961:      __(jump_builtin(_builtin_lt,2))
797_endsubp(builtin_lt)
798
799/* %arg_z <- (<= %arg_y %arg_z).   */
800_spentry(builtin_le)
801        __(movl %arg_y,%imm0)
802        __(orb %arg_z_b,%imm0_b)
803        __(testb $fixnummask,%imm0_b)
804        __(jne 1f)
805        __(rcmpl(%arg_y,%arg_z))
806        __(condition_to_boolean(le,%imm0,%arg_z))
807        __(ret)
8081:      __(jump_builtin(_builtin_le,2))
809_endsubp(builtin_le)
810
811_spentry(builtin_eql)
812        __(int $3)
813_endsubp(builtin_eql)
814
815_spentry(builtin_length)
816        __(int $3)
817_endsubp(builtin_length)
818
819_spentry(builtin_seqtype)
820        __(int $3)
821_endsubp(builtin_seqtype)
822
823_spentry(builtin_assq)
824        __(int $3)
825_endsubp(builtin_assq)
826
827_spentry(builtin_memq)
828        __(int $3)
829_endsubp(builtin_memq)
830
831logbitp_max_bit = 30
832
833_spentry(builtin_logbitp)
834        __(int $3)
835_endsubp(builtin_logbitp)
836
837_spentry(builtin_logior)
838        __(movl %arg_y,%imm0)
839        __(orb %arg_z_b,%imm0_b)
840        __(testb $fixnummask,%imm0_b)
841        __(jne 1f)
842        __(orl %arg_y,%arg_z)
843        __(ret)
8441:     
845        __(jump_builtin(_builtin_logior,2))
846_endsubp(builtin_logior)
847
848_spentry(builtin_logand)
849        __(movl %arg_y,%imm0)
850        __(orb %arg_z_b,%imm0_b)
851        __(testb $fixnummask,%imm0_b)
852        __(jne 1f)
853        __(andl %arg_y,%arg_z)
854        __(ret)
8551:             
856        __(jump_builtin(_builtin_logand,2))
857_endsubp(builtin_logand)
858
859_spentry(builtin_negate)
860        __(testb $fixnummask,%arg_z_b)
861        __(jne 1f)
862        __(negl %arg_z)
863        __(jo,pn C(fix_one_bit_overflow))
864        __(repret)
8651:             
866        __(jump_builtin(_builtin_negate,1))     
867_endsubp(builtin_negate)
868
869_spentry(builtin_logxor)
870        __(movl %arg_y,%imm0)
871        __(orb %arg_z_b,%imm0_b)
872        __(testb $fixnummask,%imm0_b)
873        __(jne 1f)
874        __(xorl %arg_y,%arg_z)
875        __(ret)
8761:             
877        __(jump_builtin(_builtin_logxor,2))
878_endsubp(builtin_logxor)
879       
880_spentry(builtin_aset1)
881        __(int $3)
882_endsubp(builtin_aset1)
883
884_spentry(builtin_ash)
885        __(int $3)
886_endsubp(builtin_ash)
887
888_spentry(builtin_aref1)
889        __(extract_typecode(%arg_y,%imm0))
890        __(cmpb $min_vector_subtag,%imm0_b)
891        __(box_fixnum_no_flags(%imm0,%arg_y))
892        __(ja _SPsubtag_misc_ref)
893        __(jump_builtin(_builtin_aref1,2))
894_endsubp(builtin_aref1)
895
896_spentry(ffcall)
897        __(int $3)
898_endsubp(ffcall)
899       
900_spentry(ffcall_return_registers)
901        __(int $3)
902_endsubp(ffcall_return_registers)
903
904_spentry(spread_lexprz)
905        __(int $3)
906_endsubp(spread_lexprz)
907
908_spentry(callback)
909        __(int $3)
910_endsubp(callback)
911
912_spentry(aref2)
913        __(int $3)
914_endsubp(aref2)
915
916_spentry(aref3)
917        __(int $3)
918_endsubp(aref3)
919
920_spentry(aset2)
921        __(int $3)
922_endsubp(aset2)
923
924_spentry(aset3)
925        __(int $3)
926_endsubp(aset3)
927
928_spentry(call_closure)
929        __(int $3)
930_endsubp(call_closure)
931
932_spentry(poweropen_callbackX)
933        __(int $3)
934_endsubp(poweropen_callbackX)
935       
936_spentry(poweropen_ffcallX)
937        __(int $3)
938_endsubp(poweropen_ffcallX)
939               
940_spentry(poweropen_syscall)
941        __(int $3)
942_endsubp(poweropen_syscall)
943
944_spentry(eabi_ff_call)
945        __(int $3)
946_endsubp(eabi_ff_call)
947
948_spentry(eabi_callback)
949        __(int $3)
950_endsubp(eabi_callback)
951
952
953/* Unused, and often not used on PPC either  */
954_spentry(callbuiltin)
955        __(int $3)
956_endsubp(callbuiltin)
957
958_spentry(callbuiltin0)
959        __(int $3)
960_endsubp(callbuiltin0)
961
962_spentry(callbuiltin1)
963        __(int $3)
964_endsubp(callbuiltin1)
965
966_spentry(callbuiltin2)
967        __(int $3)
968_endsubp(callbuiltin2)
969
970_spentry(callbuiltin3)
971        __(int $3)
972_endsubp(callbuiltin3)
973       
974_spentry(restorefullcontext)
975        __(int $3)
976_endsubp(restorefullcontext)
977
978_spentry(savecontextvsp)
979        __(int $3)
980_endsubp(savecontextvsp)
981
982_spentry(savecontext0)
983        __(int $3)
984_endsubp(savecontext0)
985
986_spentry(restorecontext)
987        __(int $3)
988_endsubp(restorecontext)
989
990_spentry(stkconsyz)
991        __(int $3)
992_endsubp(stkconsyz)
993
994_spentry(stkvcell0)
995        __(int $3)
996_endsubp(stkvcell0)
997
998_spentry(stkvcellvsp)
999        __(int $3)
1000_endsubp(stkvcellvsp)
1001
1002_spentry(breakpoint)
1003        __(int $3)
1004_endsubp(breakpoint)
1005
1006_spentry(unused_5)
1007        __(int $3)
1008_endsubp(unused_5)
1009
1010_spentry(unused_6)
1011        __(int $3)
1012_endsubp(unused_6)
Note: See TracBrowser for help on using the repository browser.