1 .file "reg_u_sub.S"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include "exception.h"
29 #include "fpu_asm.h"
30 #include "control_w.h"
31
32 .text
33 .align 2,144
34 .globl _reg_u_sub
35 _reg_u_sub:
36 pushl %ebp
37 movl %esp,%ebp
38 pushl %esi
39 pushl %edi
40 pushl %ebx
41
42 movl PARAM1,%esi
43 movl PARAM2,%edi
44
45 #ifdef DENORM_OPERAND
46 cmpl EXP_UNDER,EXP(%esi)
47 jg xOp1_not_denorm
48
49 call _denormal_operand
50 orl %eax,%eax
51 jnz FPU_Arith_exit
52
53 xOp1_not_denorm:
54 cmpl EXP_UNDER,EXP(%edi)
55 jg xOp2_not_denorm
56
57 call _denormal_operand
58 orl %eax,%eax
59 jnz FPU_Arith_exit
60
61 xOp2_not_denorm:
62 #endif DENORM_OPERAND
63
64
65 movl EXP(%esi),%ecx
66 subl EXP(%edi),%ecx
67
68 #ifdef PARANOID
69
70
71 js L_bugged_1
72
73 testl $0x80000000,SIGH(%edi)
74 je L_bugged_2
75
76 testl $0x80000000,SIGH(%esi)
77 je L_bugged_2
78 #endif PARANOID
79
80
81
82
83
84 movl SIGH(%edi),%eax
85 movl SIGL(%edi),%ebx
86
87 movl PARAM3,%edi
88 movl EXP(%esi),%edx
89 movl %edx,EXP(%edi)
90 movb SIGN(%esi),%dl
91 movb %dl,SIGN(%edi)
92
93 xorl %edx,%edx
94
95
96
97
98
99
100 L_shift_r:
101 cmpl $32,%ecx
102 jnc L_more_than_31
103
104
105 shrd %cl,%ebx,%edx
106 shrd %cl,%eax,%ebx
107 shr %cl,%eax
108 jmp L_shift_done
109
110 L_more_than_31:
111 cmpl $64,%ecx
112 jnc L_more_than_63
113
114 subb $32,%cl
115 jz L_exactly_32
116
117 shrd %cl,%eax,%edx
118 shr %cl,%eax
119 orl %ebx,%ebx
120 jz L_more_31_no_low
121
122 orl $1,%edx
123
124 L_more_31_no_low:
125 movl %eax,%ebx
126 xorl %eax,%eax
127 jmp L_shift_done
128
129 L_exactly_32:
130 movl %ebx,%edx
131 movl %eax,%ebx
132 xorl %eax,%eax
133 jmp L_shift_done
134
135 L_more_than_63:
136 cmpw $65,%cx
137 jnc L_more_than_64
138
139
140 movl %eax,%edx
141 orl %ebx,%ebx
142 jz L_more_63_no_low
143
144 orl $1,%edx
145 jmp L_more_63_no_low
146
147 L_more_than_64:
148 jne L_more_than_65
149
150
151
152 movl %eax,%edx
153 rcrl %edx
154 jnc L_shift_65_nc
155
156 orl $1,%edx
157 jmp L_more_63_no_low
158
159 L_shift_65_nc:
160 orl %ebx,%ebx
161 jz L_more_63_no_low
162
163 orl $1,%edx
164 jmp L_more_63_no_low
165
166 L_more_than_65:
167 movl $1,%edx
168
169 L_more_63_no_low:
170 xorl %ebx,%ebx
171 xorl %eax,%eax
172
173 L_shift_done:
174 L_subtr:
175
176
177
178 xorl %ecx,%ecx
179 subl %edx,%ecx
180 movl %ecx,%edx
181 movl SIGL(%esi),%ecx
182 sbbl %ebx,%ecx
183 movl %ecx,%ebx
184 movl SIGH(%esi),%ecx
185 sbbl %eax,%ecx
186 movl %ecx,%eax
187
188 #ifdef PARANOID
189
190 jc L_bugged
191 #endif PARANOID
192
193
194
195
196 testl $0x80000000,%eax
197 jnz L_round
198
199 orl %eax,%eax
200 jnz L_shift_1
201
202 orl %ebx,%ebx
203 jnz L_shift_32
204
205
206
207
208
209
210
211 cmpl $0x80000000,%edx
212 jnz L_must_be_zero
213
214
215 subl $64,EXP(%edi)
216 movl %edx,%eax
217 jmp L_store
218
219 L_must_be_zero:
220 #ifdef PARANOID
221 orl %edx,%edx
222 jnz L_bugged_3
223 #endif PARANOID
224
225
226 movb TW_Zero,TAG(%edi)
227 movl $0,EXP(%edi)
228 movl $0,SIGL(%edi)
229 movl $0,SIGH(%edi)
230 jmp L_exit
231
232 L_shift_32:
233 movl %ebx,%eax
234 movl %edx,%ebx
235 movl $0,%edx
236 subl $32,EXP(%edi)
237
238
239 L_shift_1:
240 bsrl %eax,%ecx
241 subl $31,%ecx
242 negl %ecx
243 shld %cl,%ebx,%eax
244 shld %cl,%edx,%ebx
245 shl %cl,%edx
246 subl %ecx,EXP(%edi)
247
248 L_round:
249 jmp FPU_round
250
251
252 #ifdef PARANOID
253 L_bugged_1:
254 pushl EX_INTERNAL|0x206
255 call EXCEPTION
256 pop %ebx
257 jmp L_exit
258
259 L_bugged_2:
260 pushl EX_INTERNAL|0x209
261 call EXCEPTION
262 pop %ebx
263 jmp L_exit
264
265 L_bugged_3:
266 pushl EX_INTERNAL|0x210
267 call EXCEPTION
268 pop %ebx
269 jmp L_exit
270
271 L_bugged_4:
272 pushl EX_INTERNAL|0x211
273 call EXCEPTION
274 pop %ebx
275 jmp L_exit
276
277 L_bugged:
278 pushl EX_INTERNAL|0x212
279 call EXCEPTION
280 pop %ebx
281 jmp L_exit
282 #endif PARANOID
283
284
285 L_store:
286
287
288
289 movl %eax,SIGH(%edi)
290 movl %ebx,SIGL(%edi)
291
292 movb TW_Valid,TAG(%edi)
293
294 cmpl EXP_UNDER,EXP(%edi)
295 jle L_underflow
296
297 L_exit:
298 popl %ebx
299 popl %edi
300 popl %esi
301 leave
302 ret
303
304
305 L_underflow:
306 push %edi
307 call _arith_underflow
308 pop %ebx
309 jmp L_exit
310