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 movl EXP(%esi),%ecx
65 subl EXP(%edi),%ecx
66
67 #ifdef PARANOID
68
69 js L_bugged_1
70
71 testl $0x80000000,SIGH(%edi)
72 je L_bugged_2
73
74 testl $0x80000000,SIGH(%esi)
75 je L_bugged_2
76 #endif PARANOID
77
78
79
80
81
82 movl SIGH(%edi),%eax
83 movl SIGL(%edi),%ebx
84
85 movl PARAM3,%edi
86 movl EXP(%esi),%edx
87 movl %edx,EXP(%edi)
88
89
90
91 xorl %edx,%edx
92
93
94
95
96
97
98 L_shift_r:
99 cmpl $32,%ecx
100 jnc L_more_than_31
101
102
103 shrd %cl,%ebx,%edx
104 shrd %cl,%eax,%ebx
105 shr %cl,%eax
106 jmp L_shift_done
107
108 L_more_than_31:
109 cmpl $64,%ecx
110 jnc L_more_than_63
111
112 subb $32,%cl
113 jz L_exactly_32
114
115 shrd %cl,%eax,%edx
116 shr %cl,%eax
117 orl %ebx,%ebx
118 jz L_more_31_no_low
119
120 orl $1,%edx
121
122 L_more_31_no_low:
123 movl %eax,%ebx
124 xorl %eax,%eax
125 jmp L_shift_done
126
127 L_exactly_32:
128 movl %ebx,%edx
129 movl %eax,%ebx
130 xorl %eax,%eax
131 jmp L_shift_done
132
133 L_more_than_63:
134 cmpw $65,%cx
135 jnc L_more_than_64
136
137
138 movl %eax,%edx
139 orl %ebx,%ebx
140 jz L_more_63_no_low
141
142 orl $1,%edx
143 jmp L_more_63_no_low
144
145 L_more_than_64:
146 jne L_more_than_65
147
148
149
150 movl %eax,%edx
151 rcrl %edx
152 jnc L_shift_65_nc
153
154 orl $1,%edx
155 jmp L_more_63_no_low
156
157 L_shift_65_nc:
158 orl %ebx,%ebx
159 jz L_more_63_no_low
160
161 orl $1,%edx
162 jmp L_more_63_no_low
163
164 L_more_than_65:
165 movl $1,%edx
166
167 L_more_63_no_low:
168 xorl %ebx,%ebx
169 xorl %eax,%eax
170
171 L_shift_done:
172 L_subtr:
173
174
175
176 xorl %ecx,%ecx
177 subl %edx,%ecx
178 movl %ecx,%edx
179 movl SIGL(%esi),%ecx
180 sbbl %ebx,%ecx
181 movl %ecx,%ebx
182 movl SIGH(%esi),%ecx
183 sbbl %eax,%ecx
184 movl %ecx,%eax
185
186 #ifdef PARANOID
187
188 jc L_bugged
189 #endif PARANOID
190
191
192
193
194 testl $0x80000000,%eax
195 jnz L_round
196
197 orl %eax,%eax
198 jnz L_shift_1
199
200 orl %ebx,%ebx
201 jnz L_shift_32
202
203
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 xchg %edx,%eax
217 jmp fpu_reg_round
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_reg_round
250
251
252 #ifdef PARANOID
253 L_bugged_1:
254 pushl EX_INTERNAL|0x206
255 call EXCEPTION
256 pop %ebx
257 jmp L_error_exit
258
259 L_bugged_2:
260 pushl EX_INTERNAL|0x209
261 call EXCEPTION
262 pop %ebx
263 jmp L_error_exit
264
265 L_bugged_3:
266 pushl EX_INTERNAL|0x210
267 call EXCEPTION
268 pop %ebx
269 jmp L_error_exit
270
271 L_bugged_4:
272 pushl EX_INTERNAL|0x211
273 call EXCEPTION
274 pop %ebx
275 jmp L_error_exit
276
277 L_bugged:
278 pushl EX_INTERNAL|0x212
279 call EXCEPTION
280 pop %ebx
281 jmp L_error_exit
282 #endif PARANOID
283
284
285 L_error_exit:
286 movl $1,%eax
287 L_exit:
288 popl %ebx
289 popl %edi
290 popl %esi
291 leave
292 ret