1 .file "reg_round.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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 #include "fpu_asm.h"
73 #include "exception.h"
74 #include "control_w.h"
75
76
77 #define LOST_DOWN $1
78 #define LOST_UP $2
79
80
81 #define DENORMAL $1
82 #define UNMASKED_UNDERFLOW $2
83
84
85 #ifndef NON_REENTRANT_FPU
86
87
88 #define FPU_bits_lost (%esp)
89 #define FPU_denormal 1(%esp)
90
91 #else
92
93
94 .data
95 .align 2,0
96 FPU_bits_lost:
97 .byte 0
98 FPU_denormal:
99 .byte 0
100 #endif NON_REENTRANT_FPU
101
102
103 .text
104 .align 2,144
105 .globl fpu_reg_round
106 .globl fpu_reg_round_sqrt
107 .globl fpu_Arith_exit
108 .globl _round_reg
109
110
111 _round_reg:
112 pushl %ebp
113 movl %esp,%ebp
114 pushl %esi
115 pushl %edi
116 pushl %ebx
117
118 movl PARAM1,%edi
119 movl SIGH(%edi),%eax
120 movl SIGL(%edi),%ebx
121 movl PARAM2,%edx
122 movl PARAM3,%ecx
123 jmp fpu_reg_round_sqrt
124
125 fpu_reg_round:
126 movl PARAM4,%ecx
127
128 fpu_reg_round_sqrt:
129
130 #ifndef NON_REENTRANT_FPU
131 pushl %ebx
132 #endif NON_REENTRANT_FPU
133
134 #ifdef PARANOID
135
136
137
138 #endif PARANOID
139
140 cmpl EXP_UNDER,EXP(%edi)
141 jle xMake_denorm
142
143 movb $0,FPU_denormal
144
145 xDenorm_done:
146 movb $0,FPU_bits_lost
147
148 movl %ecx,%esi
149 andl CW_PC,%ecx
150 cmpl PR_64_BITS,%ecx
151 je LRound_To_64
152
153 cmpl PR_53_BITS,%ecx
154 je LRound_To_53
155
156 cmpl PR_24_BITS,%ecx
157 je LRound_To_24
158
159 #ifdef PECULIAR_486
160
161
162 cmpl PR_RESERVED_BITS,%ecx
163 je LRound_To_64
164 #ifdef PARANOID
165 jmp L_bugged_denorm_486
166 #endif PARANOID
167 #else
168 #ifdef PARANOID
169 jmp L_bugged_denorm
170 #endif PARANOID
171 #endif PECULIAR_486
172
173
174
175 LRound_To_24:
176 movl %esi,%ecx
177 andl CW_RC,%ecx
178 cmpl RC_RND,%ecx
179 je LRound_nearest_24
180
181 cmpl RC_CHOP,%ecx
182 je LCheck_truncate_24
183
184 cmpl RC_UP,%ecx
185 je LUp_24
186
187 cmpl RC_DOWN,%ecx
188 je LDown_24
189
190 #ifdef PARANOID
191 jmp L_bugged_round24
192 #endif PARANOID
193
194 LUp_24:
195 cmpb SIGN_POS,SIGN(%edi)
196 jne LCheck_truncate_24
197
198 jmp LCheck_24_round_up
199
200 LDown_24:
201 cmpb SIGN_POS,SIGN(%edi)
202 je LCheck_truncate_24
203
204 LCheck_24_round_up:
205 movl %eax,%ecx
206 andl $0x000000ff,%ecx
207 orl %ebx,%ecx
208 orl %edx,%ecx
209 jnz LDo_24_round_up
210 jmp LRe_normalise
211
212 LRound_nearest_24:
213
214 movl %eax,%ecx
215 andl $0x000000ff,%ecx
216 cmpl $0x00000080,%ecx
217 jc LCheck_truncate_24
218
219 jne LGreater_Half_24
220
221
222 orl %ebx,%ebx
223 jnz LGreater_Half_24
224
225 orl %edx,%edx
226 jnz LGreater_Half_24
227
228
229 testl $0x00000100,%eax
230 jz LDo_truncate_24
231
232 LGreater_Half_24:
233 LDo_24_round_up:
234 andl $0xffffff00,%eax
235 xorl %ebx,%ebx
236 movb LOST_UP,FPU_bits_lost
237 addl $0x00000100,%eax
238 jmp LCheck_Round_Overflow
239
240 LCheck_truncate_24:
241 movl %eax,%ecx
242 andl $0x000000ff,%ecx
243 orl %ebx,%ecx
244 orl %edx,%ecx
245 jz LRe_normalise
246
247 LDo_truncate_24:
248 andl $0xffffff00,%eax
249 xorl %ebx,%ebx
250 movb LOST_DOWN,FPU_bits_lost
251 jmp LRe_normalise
252
253
254
255 LRound_To_53:
256 movl %esi,%ecx
257 andl CW_RC,%ecx
258 cmpl RC_RND,%ecx
259 je LRound_nearest_53
260
261 cmpl RC_CHOP,%ecx
262 je LCheck_truncate_53
263
264 cmpl RC_UP,%ecx
265 je LUp_53
266
267 cmpl RC_DOWN,%ecx
268 je LDown_53
269
270 #ifdef PARANOID
271 jmp L_bugged_round53
272 #endif PARANOID
273
274 LUp_53:
275 cmpb SIGN_POS,SIGN(%edi)
276 jne LCheck_truncate_53
277
278 jmp LCheck_53_round_up
279
280 LDown_53:
281 cmpb SIGN_POS,SIGN(%edi)
282 je LCheck_truncate_53
283
284 LCheck_53_round_up:
285 movl %ebx,%ecx
286 andl $0x000007ff,%ecx
287 orl %edx,%ecx
288 jnz LDo_53_round_up
289 jmp LRe_normalise
290
291 LRound_nearest_53:
292
293 movl %ebx,%ecx
294 andl $0x000007ff,%ecx
295 cmpl $0x00000400,%ecx
296 jc LCheck_truncate_53
297
298 jnz LGreater_Half_53
299
300
301 orl %edx,%edx
302 jnz LGreater_Half_53
303
304
305 testl $0x00000800,%ebx
306 jz LTruncate_53
307
308 LGreater_Half_53:
309 LDo_53_round_up:
310 movb LOST_UP,FPU_bits_lost
311 andl $0xfffff800,%ebx
312 addl $0x00000800,%ebx
313 adcl $0,%eax
314 jmp LCheck_Round_Overflow
315
316 LCheck_truncate_53:
317 movl %ebx,%ecx
318 andl $0x000007ff,%ecx
319 orl %edx,%ecx
320 jz LRe_normalise
321
322 LTruncate_53:
323 movb LOST_DOWN,FPU_bits_lost
324 andl $0xfffff800,%ebx
325 jmp LRe_normalise
326
327
328
329 LRound_To_64:
330 movl %esi,%ecx
331 andl CW_RC,%ecx
332 cmpl RC_RND,%ecx
333 je LRound_nearest_64
334
335 cmpl RC_CHOP,%ecx
336 je LCheck_truncate_64
337
338 cmpl RC_UP,%ecx
339 je LUp_64
340
341 cmpl RC_DOWN,%ecx
342 je LDown_64
343
344 #ifdef PARANOID
345 jmp L_bugged_round64
346 #endif PARANOID
347
348 LUp_64:
349 cmpb SIGN_POS,SIGN(%edi)
350 jne LCheck_truncate_64
351
352 orl %edx,%edx
353 jnz LDo_64_round_up
354 jmp LRe_normalise
355
356 LDown_64:
357 cmpb SIGN_POS,SIGN(%edi)
358 je LCheck_truncate_64
359
360 orl %edx,%edx
361 jnz LDo_64_round_up
362 jmp LRe_normalise
363
364 LRound_nearest_64:
365 cmpl $0x80000000,%edx
366 jc LCheck_truncate_64
367
368 jne LDo_64_round_up
369
370
371 testb $1,%ebx
372 jz LCheck_truncate_64
373
374 LDo_64_round_up:
375 movb LOST_UP,FPU_bits_lost
376 addl $1,%ebx
377 adcl $0,%eax
378
379 LCheck_Round_Overflow:
380 jnc LRe_normalise
381
382
383 rcrl $1,%eax
384 rcrl $1,%ebx
385 incl EXP(%edi)
386 jmp LRe_normalise
387
388 LCheck_truncate_64:
389 orl %edx,%edx
390 jz LRe_normalise
391
392 LTruncate_64:
393 movb LOST_DOWN,FPU_bits_lost
394
395 LRe_normalise:
396 testb $0xff,FPU_denormal
397 jnz xNormalise_result
398
399 xL_Normalised:
400 cmpb LOST_UP,FPU_bits_lost
401 je xL_precision_lost_up
402
403 cmpb LOST_DOWN,FPU_bits_lost
404 je xL_precision_lost_down
405
406 xL_no_precision_loss:
407
408 movb TW_Valid,TAG(%edi)
409
410 xL_Store_significand:
411 movl %eax,SIGH(%edi)
412 movl %ebx,SIGL(%edi)
413
414 xorl %eax,%eax
415
416 cmpl EXP_OVER,EXP(%edi)
417 jge L_overflow
418
419 fpu_reg_round_exit:
420 #ifndef NON_REENTRANT_FPU
421 popl %ebx
422 #endif NON_REENTRANT_FPU
423
424 fpu_Arith_exit:
425 popl %ebx
426 popl %edi
427 popl %esi
428 leave
429 ret
430
431
432
433
434
435
436 xL_precision_lost_up:
437 push %eax
438 call _set_precision_flag_up
439 popl %eax
440 jmp xL_no_precision_loss
441
442
443
444
445
446 xL_precision_lost_down:
447 push %eax
448 call _set_precision_flag_down
449 popl %eax
450 jmp xL_no_precision_loss
451
452
453
454
455
456
457
458 xMake_denorm:
459
460
461 testb CW_Underflow,%cl
462 jz xUnmasked_underflow
463
464 movb DENORMAL,FPU_denormal
465
466 pushl %ecx
467 movl EXP_UNDER+1,%ecx
468 subl EXP(%edi),%ecx
469
470 cmpl $64,%ecx
471 jnc xDenorm_shift_more_than_63
472
473 cmpl $32,%ecx
474 jnc xDenorm_shift_more_than_32
475
476
477
478
479
480
481 addl %ecx,EXP(%edi)
482 orl %edx,%edx
483 setne %ch
484 xorl %edx,%edx
485 shrd %cl,%ebx,%edx
486 shrd %cl,%eax,%ebx
487 shr %cl,%eax
488 orb %ch,%dl
489 popl %ecx
490 jmp xDenorm_done
491
492
493 xDenorm_shift_more_than_32:
494 addl %ecx,EXP(%edi)
495 subb $32,%cl
496 orl %edx,%edx
497 setne %ch
498 orb %ch,%bl
499 xorl %edx,%edx
500 shrd %cl,%ebx,%edx
501 shrd %cl,%eax,%ebx
502 shr %cl,%eax
503 orl %edx,%edx
504 setne %cl
505 orb %ch,%bl
506 orb %cl,%bl
507 movl %ebx,%edx
508 movl %eax,%ebx
509 xorl %eax,%eax
510 popl %ecx
511 jmp xDenorm_done
512
513
514 xDenorm_shift_more_than_63:
515 cmpl $64,%ecx
516 jne xDenorm_shift_more_than_64
517
518
519 addl %ecx,EXP(%edi)
520 xorl %ecx,%ecx
521 orl %edx,%edx
522 setne %cl
523 orl %ebx,%ebx
524 setne %ch
525 orb %ch,%cl
526 orb %cl,%al
527 movl %eax,%edx
528 xorl %eax,%eax
529 xorl %ebx,%ebx
530 popl %ecx
531 jmp xDenorm_done
532
533 xDenorm_shift_more_than_64:
534 movl EXP_UNDER+1,EXP(%edi)
535
536 movl $1,%edx
537 xorl %eax,%eax
538 xorl %ebx,%ebx
539 popl %ecx
540 jmp xDenorm_done
541
542
543 xUnmasked_underflow:
544 movb UNMASKED_UNDERFLOW,FPU_denormal
545 jmp xDenorm_done
546
547
548
549 xNormalise_result:
550 cmpb UNMASKED_UNDERFLOW,FPU_denormal
551 je xSignal_underflow
552
553
554 #ifdef PARANOID
555
556 cmpl EXP_UNDER+1,EXP(%edi)
557 jne L_norm_bugged
558 #endif PARANOID
559
560 #ifdef PECULIAR_486
561
562
563
564
565
566
567
568
569 orl %eax,%eax
570 js LNormalise_shift_done
571 #endif PECULIAR_486
572
573 orl %eax,%eax
574 js xL_Normalised
575
576 jnz LNormalise_shift_up_to_31
577
578 orl %ebx,%ebx
579 jz L_underflow_to_zero
580
581
582 movl %ebx,%eax
583 xorl %ebx,%ebx
584 subl $32,EXP(%edi)
585
586 LNormalise_shift_up_to_31:
587 bsrl %eax,%ecx
588 subl $31,%ecx
589 negl %ecx
590 shld %cl,%ebx,%eax
591 shl %cl,%ebx
592 subl %ecx,EXP(%edi)
593
594 LNormalise_shift_done:
595 testb $0xff,FPU_bits_lost
596 jz xL_Normalised
597
598
599 push %eax
600 pushl EX_Underflow
601 call _exception
602 popl %eax
603 popl %eax
604 jmp xL_Normalised
605
606
607
608
609
610
611 L_underflow_to_zero:
612 push %eax
613 call _set_precision_flag_down
614 popl %eax
615
616 push %eax
617 pushl EX_Underflow
618 call _exception
619 popl %eax
620 popl %eax
621
622
623 movl EXP_UNDER,EXP(%edi)
624 movb TW_Zero,TAG(%edi)
625 jmp xL_Store_significand
626
627
628
629 L_overflow:
630 push %edi
631 call _arith_overflow
632 pop %edi
633 jmp fpu_reg_round_exit
634
635
636 xSignal_underflow:
637
638
639 cmpl EXP_UNDER,EXP(%edi)
640 jle xDo_unmasked_underflow
641
642 jmp xL_Normalised
643
644 xDo_unmasked_underflow:
645
646 addl $(3*(1<<13)),EXP(%edi)
647 push %eax
648 pushl EX_Underflow
649 call EXCEPTION
650 popl %eax
651 popl %eax
652 jmp xL_Normalised
653
654
655 #ifdef PARANOID
656 #ifdef PECULIAR_486
657 L_bugged_denorm_486:
658 pushl EX_INTERNAL|0x236
659 call EXCEPTION
660 popl %ebx
661 jmp L_exception_exit
662 #else
663 L_bugged_denorm:
664 pushl EX_INTERNAL|0x230
665 call EXCEPTION
666 popl %ebx
667 jmp L_exception_exit
668 #endif PECULIAR_486
669
670 L_bugged_round24:
671 pushl EX_INTERNAL|0x231
672 call EXCEPTION
673 popl %ebx
674 jmp L_exception_exit
675
676 L_bugged_round53:
677 pushl EX_INTERNAL|0x232
678 call EXCEPTION
679 popl %ebx
680 jmp L_exception_exit
681
682 L_bugged_round64:
683 pushl EX_INTERNAL|0x233
684 call EXCEPTION
685 popl %ebx
686 jmp L_exception_exit
687
688 L_norm_bugged:
689 pushl EX_INTERNAL|0x234
690 call EXCEPTION
691 popl %ebx
692 jmp L_exception_exit
693
694 L_entry_bugged:
695 pushl EX_INTERNAL|0x235
696 call EXCEPTION
697 popl %ebx
698 L_exception_exit:
699 mov $1,%eax
700 jmp fpu_reg_round_exit
701 #endif PARANOID