1
2 .file "reg_u_div.S"
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include "exception.h"
27 #include "fpu_emu.h"
28 #include "control_w.h"
29
30
31
32
33
34
35 #ifndef NON_REENTRANT_FPU
36
37
38
39
40
41 #define FPU_accum_3 -4(%ebp)
42 #define FPU_accum_2 -8(%ebp)
43 #define FPU_accum_1 -12(%ebp)
44 #define FPU_accum_0 -16(%ebp)
45 #define FPU_result_1 -20(%ebp)
46 #define FPU_result_2 -24(%ebp)
47 #define FPU_ovfl_flag -28(%ebp)
48
49 #else
50 .data
51
52
53
54
55
56 .align 4,0
57 FPU_accum_3:
58 .long 0
59 FPU_accum_2:
60 .long 0
61 FPU_accum_1:
62 .long 0
63 FPU_accum_0:
64 .long 0
65 FPU_result_1:
66 .long 0
67 FPU_result_2:
68 .long 0
69 FPU_ovfl_flag:
70 .byte 0
71 #endif
72
73 #define REGA PARAM1
74 #define REGB PARAM2
75 #define DEST PARAM3
76
77 .text
78 ENTRY(FPU_u_div)
79 pushl %ebp
80 movl %esp,%ebp
81 #ifndef NON_REENTRANT_FPU
82 subl $28,%esp
83 #endif
84
85 pushl %esi
86 pushl %edi
87 pushl %ebx
88
89 movl REGA,%esi
90 movl REGB,%ebx
91 movl DEST,%edi
92
93 movswl EXP(%esi),%edx
94 movswl EXP(%ebx),%eax
95 subl %eax,%edx
96 addl EXP_BIAS,%edx
97
98
99 cmpl EXP_WAY_UNDER,%edx
100 jg xExp_not_underflow
101
102
103 movl EXP_WAY_UNDER,%edx
104
105 xExp_not_underflow:
106
107 movw %dx,EXP(%edi)
108
109 #ifdef PARANOID
110
111
112 testl $0x80000000, SIGH(%ebx)
113 je L_bugged
114 #endif
115
116
117 cmpl $0,SIGL(%ebx)
118 jnz L_Full_Division
119
120
121 movl SIGH(%ebx),%ecx
122 movl SIGH(%esi),%edx
123 movl SIGL(%esi),%eax
124
125 cmpl %ecx,%edx
126 setaeb FPU_ovfl_flag
127 jb L_no_adjust
128
129 subl %ecx,%edx
130
131 L_no_adjust:
132
133 divl %ecx
134 movl %eax,FPU_result_2
135
136
137 xorl %eax,%eax
138 divl %ecx
139 movl %eax,FPU_result_1
140
141
142 xorl %eax,%eax
143 divl %ecx
144
145 testb $255,FPU_ovfl_flag
146 je L_no_overflow
147
148
149
150 incw EXP(%edi)
151
152
153 stc
154 rcrl FPU_result_2
155 rcrl FPU_result_1
156 rcrl %eax
157
158 L_no_overflow:
159 jmp LRound_precision
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 L_Full_Division:
181
182 movl SIGL(%esi),%eax
183 movl %eax,FPU_accum_2
184 movl SIGH(%esi),%eax
185 movl %eax,FPU_accum_3
186 xorl %eax,%eax
187 movl %eax,FPU_accum_1
188 movl %eax,FPU_accum_0
189
190 movl SIGL(%esi),%eax
191 movl SIGH(%esi),%edx
192
193
194
195
196
197 movb $0,FPU_ovfl_flag
198 cmpl SIGH(%ebx),%edx
199 jb LLess_than_1
200 ja LGreater_than_1
201
202 cmpl SIGL(%ebx),%eax
203 jb LLess_than_1
204
205 LGreater_than_1:
206
207 setaeb FPU_ovfl_flag
208
209 subl SIGL(%ebx),%eax
210 sbbl SIGH(%ebx),%edx
211 movl %eax,FPU_accum_2
212 movl %edx,FPU_accum_3
213
214 LLess_than_1:
215
216
217
218
219 movl SIGH(%ebx),%ecx
220 addl $1,%ecx
221 jnc LFirst_div_not_1
222
223
224
225 mov %edx,%eax
226 jmp LFirst_div_done
227
228 LFirst_div_not_1:
229 divl %ecx
230
231
232 LFirst_div_done:
233 movl %eax,FPU_result_2
234
235 mull SIGH(%ebx)
236
237 subl %eax,FPU_accum_2
238 sbbl %edx,FPU_accum_3
239
240 movl FPU_result_2,%eax
241 mull SIGL(%ebx)
242
243 subl %eax,FPU_accum_1
244 sbbl %edx,FPU_accum_2
245 sbbl $0,FPU_accum_3
246 je LDo_2nd_32_bits
247
248 #ifdef PARANOID
249 jb L_bugged_1
250 #endif
251
252
253 incl FPU_result_2
254
255 movl SIGL(%ebx),%eax
256 movl SIGH(%ebx),%edx
257 subl %eax,FPU_accum_1
258 sbbl %edx,FPU_accum_2
259
260 #ifdef PARANOID
261 sbbl $0,FPU_accum_3
262 jne L_bugged_1
263 #endif
264
265
266
267
268
269 LDo_2nd_32_bits:
270 movl FPU_accum_2,%edx
271 movl FPU_accum_1,%eax
272
273
274 cmpl SIGH(%ebx),%edx
275 jb LDo_2nd_div
276 ja LPrevent_2nd_overflow
277
278 cmpl SIGL(%ebx),%eax
279 jb LDo_2nd_div
280
281 LPrevent_2nd_overflow:
282
283
284 subl SIGL(%ebx),%eax
285 sbbl SIGH(%ebx),%edx
286 movl %edx,FPU_accum_2
287 movl %eax,FPU_accum_1
288
289 incl FPU_result_2
290
291 #ifdef PARANOID
292 je L_bugged_2
293 #endif
294
295 LDo_2nd_div:
296 cmpl $0,%ecx
297 jnz LSecond_div_not_1
298
299
300 mov %edx,%eax
301 jmp LSecond_div_done
302
303 LSecond_div_not_1:
304 divl %ecx
305
306 LSecond_div_done:
307 movl %eax,FPU_result_1
308
309 mull SIGH(%ebx)
310
311 subl %eax,FPU_accum_1
312 sbbl %edx,FPU_accum_2
313
314 #ifdef PARANOID
315 jc L_bugged_2
316 #endif
317
318 movl FPU_result_1,%eax
319 mull SIGL(%ebx)
320
321 subl %eax,FPU_accum_0
322 sbbl %edx,FPU_accum_1
323 sbbl $0,FPU_accum_2
324
325 #ifdef PARANOID
326 jc L_bugged_2
327 #endif
328
329 jz LDo_3rd_32_bits
330
331 #ifdef PARANOID
332 cmpl $1,FPU_accum_2
333 jne L_bugged_2
334 #endif
335
336
337 movl SIGL(%ebx),%eax
338 movl SIGH(%ebx),%edx
339 subl %eax,FPU_accum_0
340 sbbl %edx,FPU_accum_1
341 sbbl $0,FPU_accum_2
342
343 #ifdef PARANOID
344 jc L_bugged_2
345 jne L_bugged_2
346 #endif
347
348 addl $1,FPU_result_1
349 adcl $0,FPU_result_2
350
351 #ifdef PARANOID
352 jc L_bugged_2
353 #endif
354
355
356
357
358
359 LDo_3rd_32_bits:
360 movl FPU_accum_1,%edx
361 movl FPU_accum_0,%eax
362
363
364 cmpl SIGH(%ebx),%edx
365 jb LRound_prep
366 ja LPrevent_3rd_overflow
367
368 cmpl SIGL(%ebx),%eax
369 jb LRound_prep
370
371 LPrevent_3rd_overflow:
372
373 subl SIGL(%ebx),%eax
374 sbbl SIGH(%ebx),%edx
375 movl %edx,FPU_accum_1
376 movl %eax,FPU_accum_0
377
378 addl $1,FPU_result_1
379 adcl $0,FPU_result_2
380 jne LRound_prep
381 jnc LRound_prep
382
383
384 movb $255,FPU_ovfl_flag
385
386 LRound_prep:
387
388
389
390
391
392 movl FPU_accum_0,%ecx
393 movl FPU_accum_1,%edx
394 movl %ecx,%eax
395 orl %edx,%eax
396 jz LRound_ovfl
397
398
399 clc
400 rcll $1,%ecx
401 rcll $1,%edx
402 jc LRound_large
403
404 subl SIGL(%ebx),%ecx
405 sbbl SIGH(%ebx),%edx
406 jnc LRound_not_small
407
408 movl $0x70000000,%eax
409 jmp LRound_ovfl
410
411 LRound_not_small:
412 jnz LRound_large
413
414 movl $0x80000000,%eax
415 jmp LRound_ovfl
416
417 LRound_large:
418 movl $0xff000000,%eax
419
420 LRound_ovfl:
421
422
423 testb $255,FPU_ovfl_flag
424 je LRound_precision
425
426 incw EXP(%edi)
427
428
429 stc
430 rcrl FPU_result_2
431 rcrl FPU_result_1
432 rcrl %eax
433
434
435 LRound_precision:
436 decw EXP(%edi)
437
438 movl %eax,%edx
439 movl FPU_result_1,%ebx
440 movl FPU_result_2,%eax
441 jmp fpu_reg_round
442
443
444 #ifdef PARANOID
445
446 L_bugged:
447 pushl EX_INTERNAL|0x202
448 call EXCEPTION
449 pop %ebx
450 jmp L_exit
451
452 L_bugged_1:
453 pushl EX_INTERNAL|0x203
454 call EXCEPTION
455 pop %ebx
456 jmp L_exit
457
458 L_bugged_2:
459 pushl EX_INTERNAL|0x204
460 call EXCEPTION
461 pop %ebx
462 jmp L_exit
463
464 L_exit:
465 movl $-1,%eax
466 popl %ebx
467 popl %edi
468 popl %esi
469
470 leave
471 ret
472 #endif
473
474 ENDPROC(FPU_u_div)