kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / platform / pc32 / gnu / fpemul / wm_shrx.s
1         .file   "wm_shrx.S"
2 /*
3  *  wm_shrx.S
4  *
5  * 64 bit right shift functions
6  *
7  * Call from C as:
8  *   unsigned shrx(void *arg1, unsigned arg2)
9  * and
10  *   unsigned shrxs(void *arg1, unsigned arg2)
11  *
12  *
13  * Copyright (C) 1992,1993,1994
14  *                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,
15  *                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au
16  * All rights reserved.
17  *
18  * This copyright notice covers the redistribution and use of the
19  * FPU emulator developed by W. Metzenthen. It covers only its use
20  * in the 386BSD, FreeBSD and NetBSD operating systems. Any other
21  * use is not permitted under this copyright.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must include information specifying
29  *    that source code for the emulator is freely available and include
30  *    either:
31  *      a) an offer to provide the source code for a nominal distribution
32  *         fee, or
33  *      b) list at least two alternative methods whereby the source
34  *         can be obtained, e.g. a publically accessible bulletin board
35  *         and an anonymous ftp site from which the software can be
36  *         downloaded.
37  * 3. All advertising materials specifically mentioning features or use of
38  *    this emulator must acknowledge that it was developed by W. Metzenthen.
39  * 4. The name of W. Metzenthen may not be used to endorse or promote
40  *    products derived from this software without specific prior written
41  *    permission.
42  *
43  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
44  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
45  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
46  * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
47  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
48  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
49  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
50  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
51  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  *
54  *
55  * The purpose of this copyright, based upon the Berkeley copyright, is to
56  * ensure that the covered software remains freely available to everyone.
57  *
58  * The software (with necessary differences) is also available, but under
59  * the terms of the GNU copyleft, for the Linux operating system and for
60  * the djgpp ms-dos extender.
61  *
62  * W. Metzenthen   June 1994.
63  *
64  *
65  * $FreeBSD: src/sys/gnu/i386/fpemul/wm_shrx.s,v 1.8 1999/08/28 00:42:59 peter Exp $
66  * $DragonFly: src/sys/platform/pc32/gnu/fpemul/Attic/wm_shrx.s,v 1.4 2003/08/07 21:17:21 dillon Exp $
67  *
68  */
69
70
71 #include "fpu_asm.h"
72
73 .text
74
75 /*---------------------------------------------------------------------------+
76  |   unsigned shrx(void *arg1, unsigned arg2)                                |
77  |                                                                           |
78  |   Extended shift right function.                                          |
79  |   Fastest for small shifts.                                               |
80  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
81  |   right by the number of bits specified by the second arg (arg2).         |
82  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
83  |                [  64 bit arg ][ eax ]                                     |
84  |            shift right  --------->                                        |
85  |   The eax register is initialized to 0 before the shifting.               |
86  |   Results returned in the 64 bit arg and eax.                             |
87  +---------------------------------------------------------------------------*/
88
89 ENTRY(shrx)
90         push    %ebp
91         movl    %esp,%ebp
92         pushl   %esi
93         movl    PARAM2,%ecx
94         movl    PARAM1,%esi
95         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
96         jnc     L_more_than_31
97
98 /* less than 32 bits */
99         pushl   %ebx
100         movl    (%esi),%ebx     /* lsl */
101         movl    4(%esi),%edx    /* msl */
102         xorl    %eax,%eax       /* extension */
103         shrd    %cl,%ebx,%eax
104         shrd    %cl,%edx,%ebx
105         shr     %cl,%edx
106         movl    %ebx,(%esi)
107         movl    %edx,4(%esi)
108         popl    %ebx
109         popl    %esi
110         leave
111         ret
112
113 L_more_than_31:
114         cmpl    $64,%ecx
115         jnc     L_more_than_63
116
117         subb    $32,%cl
118         movl    (%esi),%eax     /* lsl */
119         movl    4(%esi),%edx    /* msl */
120         shrd    %cl,%edx,%eax
121         shr     %cl,%edx
122         movl    %edx,(%esi)
123         movl    $0,4(%esi)
124         popl    %esi
125         leave
126         ret
127
128 L_more_than_63:
129         cmpl    $96,%ecx
130         jnc     L_more_than_95
131
132         subb    $64,%cl
133         movl    4(%esi),%eax    /* msl */
134         shr     %cl,%eax
135         xorl    %edx,%edx
136         movl    %edx,(%esi)
137         movl    %edx,4(%esi)
138         popl    %esi
139         leave
140         ret
141
142 L_more_than_95:
143         xorl    %eax,%eax
144         movl    %eax,(%esi)
145         movl    %eax,4(%esi)
146         popl    %esi
147         leave
148         ret
149
150
151 /*---------------------------------------------------------------------------+
152  |   unsigned shrxs(void *arg1, unsigned arg2)                               |
153  |                                                                           |
154  |   Extended shift right function (optimized for small floating point       |
155  |   integers).                                                              |
156  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
157  |   right by the number of bits specified by the second arg (arg2).         |
158  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
159  |                [  64 bit arg ][ eax ]                                     |
160  |            shift right  --------->                                        |
161  |   The eax register is initialized to 0 before the shifting.               |
162  |   The lower 8 bits of eax are lost and replaced by a flag which is        |
163  |   set (to 0x01) if any bit, apart from the first one, is set in the       |
164  |   part which has been shifted out of the arg.                             |
165  |   Results returned in the 64 bit arg and eax.                             |
166  +---------------------------------------------------------------------------*/
167         .globl  shrxs
168 shrxs:
169         push    %ebp
170         movl    %esp,%ebp
171         pushl   %esi
172         pushl   %ebx
173         movl    PARAM2,%ecx
174         movl    PARAM1,%esi
175         cmpl    $64,%ecx        /* shrd only works for 0..31 bits */
176         jnc     Ls_more_than_63
177
178         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
179         jc      Ls_less_than_32
180
181 /* We got here without jumps by assuming that the most common requirement
182    is for small integers */
183 /* Shift by [32..63] bits */
184         subb    $32,%cl
185         movl    (%esi),%eax     /* lsl */
186         movl    4(%esi),%edx    /* msl */
187         xorl    %ebx,%ebx
188         shrd    %cl,%eax,%ebx
189         shrd    %cl,%edx,%eax
190         shr     %cl,%edx
191         orl     %ebx,%ebx               /* test these 32 bits */
192         setne   %bl
193         test    $0x7fffffff,%eax        /* and 31 bits here */
194         setne   %bh
195         orw     %bx,%bx                 /* Any of the 63 bit set ? */
196         setne   %al
197         movl    %edx,(%esi)
198         movl    $0,4(%esi)
199         popl    %ebx
200         popl    %esi
201         leave
202         ret
203
204 /* Shift by [0..31] bits */
205 Ls_less_than_32:
206         movl    (%esi),%ebx     /* lsl */
207         movl    4(%esi),%edx    /* msl */
208         xorl    %eax,%eax       /* extension */
209         shrd    %cl,%ebx,%eax
210         shrd    %cl,%edx,%ebx
211         shr     %cl,%edx
212         test    $0x7fffffff,%eax        /* only need to look at eax here */
213         setne   %al
214         movl    %ebx,(%esi)
215         movl    %edx,4(%esi)
216         popl    %ebx
217         popl    %esi
218         leave
219         ret
220
221 /* Shift by [64..95] bits */
222 Ls_more_than_63:
223         cmpl    $96,%ecx
224         jnc     Ls_more_than_95
225
226         subb    $64,%cl
227         movl    (%esi),%ebx     /* lsl */
228         movl    4(%esi),%eax    /* msl */
229         xorl    %edx,%edx       /* extension */
230         shrd    %cl,%ebx,%edx
231         shrd    %cl,%eax,%ebx
232         shr     %cl,%eax
233         orl     %ebx,%edx
234         setne   %bl
235         test    $0x7fffffff,%eax        /* only need to look at eax here */
236         setne   %bh
237         orw     %bx,%bx
238         setne   %al
239         xorl    %edx,%edx
240         movl    %edx,(%esi)     /* set to zero */
241         movl    %edx,4(%esi)    /* set to zero */
242         popl    %ebx
243         popl    %esi
244         leave
245         ret
246
247 Ls_more_than_95:
248 /* Shift by [96..inf) bits */
249         xorl    %eax,%eax
250         movl    (%esi),%ebx
251         orl     4(%esi),%ebx
252         setne   %al
253         xorl    %ebx,%ebx
254         movl    %ebx,(%esi)
255         movl    %ebx,4(%esi)
256         popl    %ebx
257         popl    %esi
258         leave
259         ret