~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/math-emu/wm_shrx.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2         .file   "wm_shrx.S"
  3 /*---------------------------------------------------------------------------+
  4  |  wm_shrx.S                                                                |
  5  |                                                                           |
  6  | 64 bit right shift functions                                              |
  7  |                                                                           |
  8  | Copyright (C) 1992,1995                                                   |
  9  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
 10  |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
 11  |                                                                           |
 12  | Call from C as:                                                           |
 13  |   unsigned FPU_shrx(void *arg1, unsigned arg2)                            |
 14  | and                                                                       |
 15  |   unsigned FPU_shrxs(void *arg1, unsigned arg2)                           |
 16  |                                                                           |
 17  +---------------------------------------------------------------------------*/
 18 
 19 #include "fpu_emu.h"
 20 
 21 .text
 22 /*---------------------------------------------------------------------------+
 23  |   unsigned FPU_shrx(void *arg1, unsigned arg2)                            |
 24  |                                                                           |
 25  |   Extended shift right function.                                          |
 26  |   Fastest for small shifts.                                               |
 27  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
 28  |   right by the number of bits specified by the second arg (arg2).         |
 29  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
 30  |                [  64 bit arg ][ eax ]                                     |
 31  |            shift right  --------->                                        |
 32  |   The eax register is initialized to 0 before the shifting.               |
 33  |   Results returned in the 64 bit arg and eax.                             |
 34  +---------------------------------------------------------------------------*/
 35 
 36 SYM_FUNC_START(FPU_shrx)
 37         push    %ebp
 38         movl    %esp,%ebp
 39         pushl   %esi
 40         movl    PARAM2,%ecx
 41         movl    PARAM1,%esi
 42         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
 43         jnc     L_more_than_31
 44 
 45 /* less than 32 bits */
 46         pushl   %ebx
 47         movl    (%esi),%ebx     /* lsl */
 48         movl    4(%esi),%edx    /* msl */
 49         xorl    %eax,%eax       /* extension */
 50         shrd    %cl,%ebx,%eax
 51         shrd    %cl,%edx,%ebx
 52         shr     %cl,%edx
 53         movl    %ebx,(%esi)
 54         movl    %edx,4(%esi)
 55         popl    %ebx
 56         popl    %esi
 57         leave
 58         RET
 59 
 60 L_more_than_31:
 61         cmpl    $64,%ecx
 62         jnc     L_more_than_63
 63 
 64         subb    $32,%cl
 65         movl    (%esi),%eax     /* lsl */
 66         movl    4(%esi),%edx    /* msl */
 67         shrd    %cl,%edx,%eax
 68         shr     %cl,%edx
 69         movl    %edx,(%esi)
 70         movl    $0,4(%esi)
 71         popl    %esi
 72         leave
 73         RET
 74 
 75 L_more_than_63:
 76         cmpl    $96,%ecx
 77         jnc     L_more_than_95
 78 
 79         subb    $64,%cl
 80         movl    4(%esi),%eax    /* msl */
 81         shr     %cl,%eax
 82         xorl    %edx,%edx
 83         movl    %edx,(%esi)
 84         movl    %edx,4(%esi)
 85         popl    %esi
 86         leave
 87         RET
 88 
 89 L_more_than_95:
 90         xorl    %eax,%eax
 91         movl    %eax,(%esi)
 92         movl    %eax,4(%esi)
 93         popl    %esi
 94         leave
 95         RET
 96 SYM_FUNC_END(FPU_shrx)
 97 
 98 
 99 /*---------------------------------------------------------------------------+
100  |   unsigned FPU_shrxs(void *arg1, unsigned arg2)                           |
101  |                                                                           |
102  |   Extended shift right function (optimized for small floating point       |
103  |   integers).                                                              |
104  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
105  |   right by the number of bits specified by the second arg (arg2).         |
106  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
107  |                [  64 bit arg ][ eax ]                                     |
108  |            shift right  --------->                                        |
109  |   The eax register is initialized to 0 before the shifting.               |
110  |   The lower 8 bits of eax are lost and replaced by a flag which is        |
111  |   set (to 0x01) if any bit, apart from the first one, is set in the       |
112  |   part which has been shifted out of the arg.                             |
113  |   Results returned in the 64 bit arg and eax.                             |
114  +---------------------------------------------------------------------------*/
115 SYM_FUNC_START(FPU_shrxs)
116         push    %ebp
117         movl    %esp,%ebp
118         pushl   %esi
119         pushl   %ebx
120         movl    PARAM2,%ecx
121         movl    PARAM1,%esi
122         cmpl    $64,%ecx        /* shrd only works for 0..31 bits */
123         jnc     Ls_more_than_63
124 
125         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
126         jc      Ls_less_than_32
127 
128 /* We got here without jumps by assuming that the most common requirement
129    is for small integers */
130 /* Shift by [32..63] bits */
131         subb    $32,%cl
132         movl    (%esi),%eax     /* lsl */
133         movl    4(%esi),%edx    /* msl */
134         xorl    %ebx,%ebx
135         shrd    %cl,%eax,%ebx
136         shrd    %cl,%edx,%eax
137         shr     %cl,%edx
138         orl     %ebx,%ebx               /* test these 32 bits */
139         setne   %bl
140         test    $0x7fffffff,%eax        /* and 31 bits here */
141         setne   %bh
142         orw     %bx,%bx                 /* Any of the 63 bit set ? */
143         setne   %al
144         movl    %edx,(%esi)
145         movl    $0,4(%esi)
146         popl    %ebx
147         popl    %esi
148         leave
149         RET
150 
151 /* Shift by [0..31] bits */
152 Ls_less_than_32:
153         movl    (%esi),%ebx     /* lsl */
154         movl    4(%esi),%edx    /* msl */
155         xorl    %eax,%eax       /* extension */
156         shrd    %cl,%ebx,%eax
157         shrd    %cl,%edx,%ebx
158         shr     %cl,%edx
159         test    $0x7fffffff,%eax        /* only need to look at eax here */
160         setne   %al
161         movl    %ebx,(%esi)
162         movl    %edx,4(%esi)
163         popl    %ebx
164         popl    %esi
165         leave
166         RET
167 
168 /* Shift by [64..95] bits */
169 Ls_more_than_63:
170         cmpl    $96,%ecx
171         jnc     Ls_more_than_95
172 
173         subb    $64,%cl
174         movl    (%esi),%ebx     /* lsl */
175         movl    4(%esi),%eax    /* msl */
176         xorl    %edx,%edx       /* extension */
177         shrd    %cl,%ebx,%edx
178         shrd    %cl,%eax,%ebx
179         shr     %cl,%eax
180         orl     %ebx,%edx
181         setne   %bl
182         test    $0x7fffffff,%eax        /* only need to look at eax here */
183         setne   %bh
184         orw     %bx,%bx
185         setne   %al
186         xorl    %edx,%edx
187         movl    %edx,(%esi)     /* set to zero */
188         movl    %edx,4(%esi)    /* set to zero */
189         popl    %ebx
190         popl    %esi
191         leave
192         RET
193 
194 Ls_more_than_95:
195 /* Shift by [96..inf) bits */
196         xorl    %eax,%eax
197         movl    (%esi),%ebx
198         orl     4(%esi),%ebx
199         setne   %al
200         xorl    %ebx,%ebx
201         movl    %ebx,(%esi)
202         movl    %ebx,4(%esi)
203         popl    %ebx
204         popl    %esi
205         leave
206         RET
207 SYM_FUNC_END(FPU_shrxs)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php