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