Initial import from FreeBSD RELENG_4:
[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  *
67  */
68
69
70 #include <gnu/i386/fpemul/fpu_asm.h>
71
72 .text
73
74 /*---------------------------------------------------------------------------+
75  |   unsigned shrx(void *arg1, unsigned arg2)                                |
76  |                                                                           |
77  |   Extended shift right function.                                          |
78  |   Fastest for small shifts.                                               |
79  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
80  |   right by the number of bits specified by the second arg (arg2).         |
81  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
82  |                [  64 bit arg ][ eax ]                                     |
83  |            shift right  --------->                                        |
84  |   The eax register is initialized to 0 before the shifting.               |
85  |   Results returned in the 64 bit arg and eax.                             |
86  +---------------------------------------------------------------------------*/
87
88 ENTRY(shrx)
89         push    %ebp
90         movl    %esp,%ebp
91         pushl   %esi
92         movl    PARAM2,%ecx
93         movl    PARAM1,%esi
94         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
95         jnc     L_more_than_31
96
97 /* less than 32 bits */
98         pushl   %ebx
99         movl    (%esi),%ebx     /* lsl */
100         movl    4(%esi),%edx    /* msl */
101         xorl    %eax,%eax       /* extension */
102         shrd    %cl,%ebx,%eax
103         shrd    %cl,%edx,%ebx
104         shr     %cl,%edx
105         movl    %ebx,(%esi)
106         movl    %edx,4(%esi)
107         popl    %ebx
108         popl    %esi
109         leave
110         ret
111
112 L_more_than_31:
113         cmpl    $64,%ecx
114         jnc     L_more_than_63
115
116         subb    $32,%cl
117         movl    (%esi),%eax     /* lsl */
118         movl    4(%esi),%edx    /* msl */
119         shrd    %cl,%edx,%eax
120         shr     %cl,%edx
121         movl    %edx,(%esi)
122         movl    $0,4(%esi)
123         popl    %esi
124         leave
125         ret
126
127 L_more_than_63:
128         cmpl    $96,%ecx
129         jnc     L_more_than_95
130
131         subb    $64,%cl
132         movl    4(%esi),%eax    /* msl */
133         shr     %cl,%eax
134         xorl    %edx,%edx
135         movl    %edx,(%esi)
136         movl    %edx,4(%esi)
137         popl    %esi
138         leave
139         ret
140
141 L_more_than_95:
142         xorl    %eax,%eax
143         movl    %eax,(%esi)
144         movl    %eax,4(%esi)
145         popl    %esi
146         leave
147         ret
148
149
150 /*---------------------------------------------------------------------------+
151  |   unsigned shrxs(void *arg1, unsigned arg2)                               |
152  |                                                                           |
153  |   Extended shift right function (optimized for small floating point       |
154  |   integers).                                                              |
155  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
156  |   right by the number of bits specified by the second arg (arg2).         |
157  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
158  |                [  64 bit arg ][ eax ]                                     |
159  |            shift right  --------->                                        |
160  |   The eax register is initialized to 0 before the shifting.               |
161  |   The lower 8 bits of eax are lost and replaced by a flag which is        |
162  |   set (to 0x01) if any bit, apart from the first one, is set in the       |
163  |   part which has been shifted out of the arg.                             |
164  |   Results returned in the 64 bit arg and eax.                             |
165  +---------------------------------------------------------------------------*/
166         .globl  _shrxs
167 _shrxs:
168         push    %ebp
169         movl    %esp,%ebp
170         pushl   %esi
171         pushl   %ebx
172         movl    PARAM2,%ecx
173         movl    PARAM1,%esi
174         cmpl    $64,%ecx        /* shrd only works for 0..31 bits */
175         jnc     Ls_more_than_63
176
177         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
178         jc      Ls_less_than_32
179
180 /* We got here without jumps by assuming that the most common requirement
181    is for small integers */
182 /* Shift by [32..63] bits */
183         subb    $32,%cl
184         movl    (%esi),%eax     /* lsl */
185         movl    4(%esi),%edx    /* msl */
186         xorl    %ebx,%ebx
187         shrd    %cl,%eax,%ebx
188         shrd    %cl,%edx,%eax
189         shr     %cl,%edx
190         orl     %ebx,%ebx               /* test these 32 bits */
191         setne   %bl
192         test    $0x7fffffff,%eax        /* and 31 bits here */
193         setne   %bh
194         orw     %bx,%bx                 /* Any of the 63 bit set ? */
195         setne   %al
196         movl    %edx,(%esi)
197         movl    $0,4(%esi)
198         popl    %ebx
199         popl    %esi
200         leave
201         ret
202
203 /* Shift by [0..31] bits */
204 Ls_less_than_32:
205         movl    (%esi),%ebx     /* lsl */
206         movl    4(%esi),%edx    /* msl */
207         xorl    %eax,%eax       /* extension */
208         shrd    %cl,%ebx,%eax
209         shrd    %cl,%edx,%ebx
210         shr     %cl,%edx
211         test    $0x7fffffff,%eax        /* only need to look at eax here */
212         setne   %al
213         movl    %ebx,(%esi)
214         movl    %edx,4(%esi)
215         popl    %ebx
216         popl    %esi
217         leave
218         ret
219
220 /* Shift by [64..95] bits */
221 Ls_more_than_63:
222         cmpl    $96,%ecx
223         jnc     Ls_more_than_95
224
225         subb    $64,%cl
226         movl    (%esi),%ebx     /* lsl */
227         movl    4(%esi),%eax    /* msl */
228         xorl    %edx,%edx       /* extension */
229         shrd    %cl,%ebx,%edx
230         shrd    %cl,%eax,%ebx
231         shr     %cl,%eax
232         orl     %ebx,%edx
233         setne   %bl
234         test    $0x7fffffff,%eax        /* only need to look at eax here */
235         setne   %bh
236         orw     %bx,%bx
237         setne   %al
238         xorl    %edx,%edx
239         movl    %edx,(%esi)     /* set to zero */
240         movl    %edx,4(%esi)    /* set to zero */
241         popl    %ebx
242         popl    %esi
243         leave
244         ret
245
246 Ls_more_than_95:
247 /* Shift by [96..inf) bits */
248         xorl    %eax,%eax
249         movl    (%esi),%ebx
250         orl     4(%esi),%ebx
251         setne   %al
252         xorl    %ebx,%ebx
253         movl    %ebx,(%esi)
254         movl    %ebx,4(%esi)
255         popl    %ebx
256         popl    %esi
257         leave
258         ret