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 cmpl $0x80000000,%edx
210 jnz L_must_be_zero
211
212
213 subl $64,EXP(%edi)
214 xchg %edx,%eax
215 jmp FPU_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_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