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