source: trunk/source/lisp-kernel/x86-asmutils32.s @ 15132

Last change on this file since 15132 was 15132, checked in by gb, 10 years ago

Refer to the external symbol 'exp', so that libm isn't discarded
by the linker.

File size: 8.5 KB
Line 
1/*   Copyright (C) 2005-2009 Clozure Associates */
2/*   This file is part of Clozure CL.   */
3 
4/*   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public */
5/*   License , known as the LLGPL and distributed with Clozure CL as the */
6/*   file "LICENSE".  The LLGPL consists of a preamble and the LGPL, */
7/*   which is distributed with Clozure CL as the file "LGPL".  Where these */
8/*   conflict, the preamble takes precedence.   */
9 
10/*   Clozure CL is referenced in the preamble as the "LIBRARY." */
11 
12/*   The LLGPL is also available online at */
13/*   http://opensource.franz.com/preamble.html */
14
15
16       
17
18        include(lisp.s)
19
20        _beginfile
21
22_exportfn(C(current_stack_pointer))
23        __(movl %esp,%eax)
24        __(ret)
25_endfn
26                       
27_exportfn(C(count_leading_zeros))
28        __(bsr 4(%esp),%eax)
29        __(xor $31,%eax)
30        __(ret)
31_endfn
32
33_exportfn(C(noop))
34        __(ret)
35_endfn
36
37_exportfn(C(set_mxcsr))
38        __(ldmxcsr 4(%esp))
39        __(ret)
40_endfn
41       
42_exportfn(C(get_mxcsr))
43        __(push $0)
44        __(stmxcsr (%esp))
45        __(pop %eax)
46        __(ret)
47_endfn
48
49_exportfn(C(save_fp_context))
50_endfn
51       
52_exportfn(C(restore_fp_context))
53_endfn                       
54
55/*  Atomically store new in *p, if *p == old. */
56/*  Return actual old value. */
57/* natural store_conditional(natural *p, natural old, natural new) */
58_exportfn(C(store_conditional))
59        __(movl 12(%esp),%edx)  /* new */
60        __(movl 8(%esp),%eax)   /* old */
61        __(movl 4(%esp),%ecx)   /* ptr */
62        __(lock)
63        __(cmpxchgl %edx,(%ecx))
64        __(cmovne %edx,%eax)
65        __(ret)
66_endfn
67
68/*      Atomically store val in *p; return previous *p */
69/*      of *%rdi. */
70/* signed_natural atomic_swap(signed_natural *p, signed_natural val) */
71_exportfn(C(atomic_swap))
72        __(movl 8(%esp),%eax)
73        __(movl 4(%esp),%edx)
74        __(lock)
75        __(xchg %eax,(%edx))
76        __(ret)
77_endfn
78
79/*      Logior the value in *p with mask (presumably a */
80/*      bitmask with exactly 1 bit set.)  Return non-zero if any of */
81/*      the bits in that bitmask were already set. */
82/* natural atomic_ior(natural *p, natural mask) */
83_exportfn(C(atomic_ior))
84        __(movl 4(%esp),%edx)   /* ptr */
850:      __(movl (%edx),%eax)
86        __(movl %eax,%ecx)
87        __(orl 8(%esp),%ecx)
88        __(lock)
89        __(cmpxchg %ecx,(%edx))
90        __(jnz 0b)
91        __(andl 8(%esp),%eax)
92        __(ret)
93_endfn
94       
95       
96/* Logand the value in *p with mask (presumably a bitmask with exactly 1 */
97/* bit set.)  Return the value now in *p (for some value of "now"). */
98/* natural atomic_and(natural *p, natural mask) */
99_exportfn(C(atomic_and))
100        __(movl 4(%esp),%edx)
1010:      __(movl (%edx),%eax)
102        __(movl %eax,%ecx)
103        __(and 8(%esp),%ecx)
104        __(lock)
105        __(cmpxchg %ecx,(%edx))
106        __(jnz 0b)
107        __(movl %ecx,%eax)
108        __(ret)
109_endfn
110
111
112        __ifdef(`DARWIN')
113_exportfn(C(pseudo_sigreturn))
114        __(hlt)
115        __(jmp C(pseudo_sigreturn))
116_endfn
117        __endif   
118
119/* int cpuid (int code, int *pebx, int *pecx, int *pedx)  */
120_exportfn(C(cpuid))
121        __(push %ebx)           /* %ebx is non-volatile */
122        __(push %esi)           /* ditto here */
123        __(movl 12(%esp),%eax)
124        __(xorl %ecx,%ecx)
125        __(cpuid)
126        __(movl 16(%esp),%esi)
127        __(movl %ebx,(%esi))
128        __(movl 20(%esp),%esi)
129        __(movl %ecx,(%esi))
130        __(movl 24(%esp),%esi)
131        __(movl %edx,(%esi))
132        __(pop %esi)
133        __(pop %ebx)
134        __(ret)
135        .globl C(exp)
136        .long C(exp)
137_endfn
138
139/* switch_to_foreign_stack(new_sp, func, arg_0, arg_1, arg_2)  */
140/*   Not fully general, but should get us off of the signal stack */
141/* Beware: on Darwin, GDB can get very confused by this code, and
142   doesn't really get unconfused until the target function - the
143   handler - has built its stack frame
144   The lone caller of this function passes 3 arguments (besides
145   the new stack pointer and the handler address.)
146   On platforms where the C stack must be 16-byte aligned, pushing
147   a 4th word helps make the stack aligned before the return
148   address is (re-)pushed.
149   On Linux, there are severe constraints on what the top of stack
150   can look like when rt_sigreturn (the code at the return address)
151   runs, and there aren't any constraints on stack alignment, so
152   we don't push the extra word on the new stack.*/
153_exportfn(C(switch_to_foreign_stack))
154        __(addl $4,%esp)        /* discard return address, on wrong stack */
155        __(pop %edi)            /* new esp */
156        __(pop %esi)            /* handler */
157        __(pop %eax)            /* arg_0 */
158        __(pop %ebx)            /* arg_1 */
159        __(pop %ecx)            /* arg_2 */
160        __(mov %edi,%esp)
161        __(pop %edi)            /* Return address pushed by caller */
162        __ifndef(`LINUX')
163        __(push $0)             /* For alignment. See comment above */
164        __endif
165        __(push %ecx)           /* arg_2 */
166        __(push %ebx)           /* arg_1 */
167        __(push %eax)           /* arg_0 */
168        __(push %edi)           /* return address */
169        __(jmp *%esi)           /* On some platforms, we don't really return */
170_endfn
171
172        __ifdef(`FREEBSD')
173        .globl C(sigreturn)
174_exportfn(C(freebsd_sigreturn))
175        __(jmp C(sigreturn))
176_endfn
177        __endif
178
179        __ifdef(`DARWIN')
180_exportfn(C(darwin_sigreturn))
181/* Need to set the sigreturn 'infostyle' argument, which is mostly
182   undocumented.  On x8632 Darwin, sigtramp() sets it to 0x1e, and
183   since we're trying to do what sigtramp() would do if we'd returned
184   to it ... */
185        __(movl $0x1e,8(%esp))
186        __(movl $0xb8,%eax)     /* SYS_sigreturn */
187        __(int $0x80)
188        __(ret)                 /* shouldn't return */
189
190_endfn
191        __endif       
192               
193_exportfn(C(get_vector_registers))
194        __(ret)
195_endfn
196
197_exportfn(C(put_vector_registers))
198        __(ret)
199_endfn                         
200
201        __ifdef(`WIN_32')
202_exportfn(C(restore_windows_context))
203Xrestore_windows_context_start:
204        __(movl 4(%esp),%ecx)   /* context */
205        __(movl 12(%esp),%edx)  /* old valence */
206        __(movl 8(%esp),%eax)   /* tcr */
207        __(movl %edx,rcontext(tcr.valence))
208        __(movl $0,rcontext(tcr.pending_exception_context))
209        __(frstor win32_context.FloatSave(%ecx))
210        /* Windows doesn't bother to align the context, so use
211          'movupd' here */
212        __(movupd win32_context.Xmm0(%ecx),%xmm0)
213        __(movupd win32_context.Xmm1(%ecx),%xmm1)
214        __(movupd win32_context.Xmm2(%ecx),%xmm2)
215        __(movupd win32_context.Xmm3(%ecx),%xmm3)
216        __(movupd win32_context.Xmm4(%ecx),%xmm4)
217        __(movupd win32_context.Xmm5(%ecx),%xmm5)
218        __(movupd win32_context.Xmm6(%ecx),%xmm6)
219        __(movupd win32_context.Xmm7(%ecx),%xmm7)
220        __(ldmxcsr win32_context.MXCSR(%ecx))
221        __(movl win32_context.Ebp(%ecx),%ebp)
222        __(movl win32_context.Edi(%ecx),%edi)
223        __(movl win32_context.Esi(%ecx),%esi)
224        __(movl win32_context.Edx(%ecx),%edx)
225        __(movl win32_context.Ebx(%ecx),%ebx)
226        __(movl win32_context.Eax(%ecx),%eax)
227        __(movl win32_context.Esp(%ecx),%esp)
228        __(pushl win32_context.EFlags(%ecx))
229        __(pushl %cs)
230        __(pushl win32_context.Eip(%ecx))       
231        /* This must be the last thing before the iret, e.g., if we're
232        interrupted before the iret, the context we're returning to here
233        is still in %ecx.  If we're interrupted -at- the iret, then
234        everything but that which the iret will restore has been restored. */
235        __(movl win32_context.Ecx(%ecx),%ecx)
236Xrestore_windows_context_iret:           
237        __(iret)
238Xrestore_windows_context_end:             
239        __(nop)
240_endfn
241       
242_exportfn(C(windows_switch_to_foreign_stack))
243        __(pop %eax)
244        __(pop %ebx)            /* new %esp */
245        __(pop %ecx)            /* handler */
246        __(pop %edx)            /* arg */
247        __(movl %ebx,%esp)
248        __(subl $0x10,%esp)
249        __(movl %edx,(%esp))
250        __(push %eax)
251        __(jmp *%ecx)
252_endfn       
253
254        .data
255        .globl C(restore_windows_context_start)
256        .globl C(restore_windows_context_end)
257        .globl C(restore_windows_context_iret)
258C(restore_windows_context_start):  .long Xrestore_windows_context_start
259C(restore_windows_context_end): .long Xrestore_windows_context_end
260C(restore_windows_context_iret): .long Xrestore_windows_context_iret
261        .text
262       
263/* Something that we shouldn't return to */
264_exportfn(C(windows_halt))
265        __(hlt)
266_endfn         
267
268_exportfn(C(ensure_safe_for_string_operations))
269        __ifdef(`WIN32_ES_HACK')
270        __(movw %es,%ax)
271        __(movw %ds,%dx)
272        __(cmpw %ax,%dx)
273        __(jne 9f)
2740:      __(movw %dx,%es)
275        __endif
276        __(cld)       
277        __(ret)
278        __ifdef(`WIN32_ES_HACK')
2799:      __(hlt)
280        __(jmp 0b)
281        __endif
282_endfn                                       
283        __endif
284        _endfile
285
Note: See TracBrowser for help on using the repository browser.