Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002     .file "reg_round.S"
0003 /*---------------------------------------------------------------------------+
0004  |  reg_round.S                                                              |
0005  |                                                                           |
0006  | Rounding/truncation/etc for FPU basic arithmetic functions.               |
0007  |                                                                           |
0008  | Copyright (C) 1993,1995,1997                                              |
0009  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
0010  |                       Australia.  E-mail billm@suburbia.net               |
0011  |                                                                           |
0012  | This code has four possible entry points.                                 |
0013  | The following must be entered by a jmp instruction:                       |
0014  |   fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit.                  |
0015  |                                                                           |
0016  | The FPU_round entry point is intended to be used by C code.               |
0017  | From C, call as:                                                          |
0018  |  int FPU_round(FPU_REG *arg, unsigned int extent, unsigned int control_w) |
0019  |                                                                           |
0020  |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
0021  |    one was raised, or -1 on internal error.                               |
0022  |                                                                           |
0023  | For correct "up" and "down" rounding, the argument must have the correct  |
0024  | sign.                                                                     |
0025  |                                                                           |
0026  +---------------------------------------------------------------------------*/
0027 
0028 /*---------------------------------------------------------------------------+
0029  | Four entry points.                                                        |
0030  |                                                                           |
0031  | Needed by both the fpu_reg_round and fpu_reg_round_sqrt entry points:     |
0032  |  %eax:%ebx  64 bit significand                                            |
0033  |  %edx       32 bit extension of the significand                           |
0034  |  %edi       pointer to an FPU_REG for the result to be stored             |
0035  |  stack      calling function must have set up a C stack frame and         |
0036  |             pushed %esi, %edi, and %ebx                                   |
0037  |                                                                           |
0038  | Needed just for the fpu_reg_round_sqrt entry point:                       |
0039  |  %cx  A control word in the same format as the FPU control word.          |
0040  | Otherwise, PARAM4 must give such a value.                                 |
0041  |                                                                           |
0042  |                                                                           |
0043  | The significand and its extension are assumed to be exact in the          |
0044  | following sense:                                                          |
0045  |   If the significand by itself is the exact result then the significand   |
0046  |   extension (%edx) must contain 0, otherwise the significand extension    |
0047  |   must be non-zero.                                                       |
0048  |   If the significand extension is non-zero then the significand is        |
0049  |   smaller than the magnitude of the correct exact result by an amount     |
0050  |   greater than zero and less than one ls bit of the significand.          |
0051  |   The significand extension is only required to have three possible       |
0052  |   non-zero values:                                                        |
0053  |       less than 0x80000000  <=> the significand is less than 1/2 an ls    |
0054  |                                 bit smaller than the magnitude of the     |
0055  |                                 true exact result.                        |
0056  |         exactly 0x80000000  <=> the significand is exactly 1/2 an ls bit  |
0057  |                                 smaller than the magnitude of the true    |
0058  |                                 exact result.                             |
0059  |    greater than 0x80000000  <=> the significand is more than 1/2 an ls    |
0060  |                                 bit smaller than the magnitude of the     |
0061  |                                 true exact result.                        |
0062  |                                                                           |
0063  +---------------------------------------------------------------------------*/
0064 
0065 /*---------------------------------------------------------------------------+
0066  |  The code in this module has become quite complex, but it should handle   |
0067  |  all of the FPU flags which are set at this stage of the basic arithmetic |
0068  |  computations.                                                            |
0069  |  There are a few rare cases where the results are not set identically to  |
0070  |  a real FPU. These require a bit more thought because at this stage the   |
0071  |  results of the code here appear to be more consistent...                 |
0072  |  This may be changed in a future version.                                 |
0073  +---------------------------------------------------------------------------*/
0074 
0075 
0076 #include "fpu_emu.h"
0077 #include "exception.h"
0078 #include "control_w.h"
0079 
0080 /* Flags for FPU_bits_lost */
0081 #define LOST_DOWN   $1
0082 #define LOST_UP     $2
0083 
0084 /* Flags for FPU_denormal */
0085 #define DENORMAL    $1
0086 #define UNMASKED_UNDERFLOW $2
0087 
0088 
0089 #ifndef NON_REENTRANT_FPU
0090 /*  Make the code re-entrant by putting
0091     local storage on the stack: */
0092 #define FPU_bits_lost   (%esp)
0093 #define FPU_denormal    1(%esp)
0094 
0095 #else
0096 /*  Not re-entrant, so we can gain speed by putting
0097     local storage in a static area: */
0098 .data
0099     .align 4,0
0100 FPU_bits_lost:
0101     .byte   0
0102 FPU_denormal:
0103     .byte   0
0104 #endif /* NON_REENTRANT_FPU */
0105 
0106 
0107 .text
0108 .globl fpu_reg_round
0109 .globl fpu_Arith_exit
0110 
0111 /* Entry point when called from C */
0112 SYM_FUNC_START(FPU_round)
0113     pushl   %ebp
0114     movl    %esp,%ebp
0115     pushl   %esi
0116     pushl   %edi
0117     pushl   %ebx
0118 
0119     movl    PARAM1,%edi
0120     movl    SIGH(%edi),%eax
0121     movl    SIGL(%edi),%ebx
0122     movl    PARAM2,%edx
0123 
0124 fpu_reg_round:          /* Normal entry point */
0125     movl    PARAM4,%ecx
0126 
0127 #ifndef NON_REENTRANT_FPU
0128     pushl   %ebx        /* adjust the stack pointer */
0129 #endif /* NON_REENTRANT_FPU */ 
0130 
0131 #ifdef PARANOID
0132 /* Cannot use this here yet */
0133 /*  orl %eax,%eax */
0134 /*  jns L_entry_bugged */
0135 #endif /* PARANOID */
0136 
0137     cmpw    EXP_UNDER,EXP(%edi)
0138     jle L_Make_denorm           /* The number is a de-normal */
0139 
0140     movb    $0,FPU_denormal         /* 0 -> not a de-normal */
0141 
0142 Denorm_done:
0143     movb    $0,FPU_bits_lost        /* No bits yet lost in rounding */
0144 
0145     movl    %ecx,%esi
0146     andl    CW_PC,%ecx
0147     cmpl    PR_64_BITS,%ecx
0148     je  LRound_To_64
0149 
0150     cmpl    PR_53_BITS,%ecx
0151     je  LRound_To_53
0152 
0153     cmpl    PR_24_BITS,%ecx
0154     je  LRound_To_24
0155 
0156 #ifdef PECULIAR_486
0157 /* With the precision control bits set to 01 "(reserved)", a real 80486
0158    behaves as if the precision control bits were set to 11 "64 bits" */
0159     cmpl    PR_RESERVED_BITS,%ecx
0160     je  LRound_To_64
0161 #ifdef PARANOID
0162     jmp L_bugged_denorm_486
0163 #endif /* PARANOID */ 
0164 #else
0165 #ifdef PARANOID
0166     jmp L_bugged_denorm /* There is no bug, just a bad control word */
0167 #endif /* PARANOID */ 
0168 #endif /* PECULIAR_486 */
0169 
0170 
0171 /* Round etc to 24 bit precision */
0172 LRound_To_24:
0173     movl    %esi,%ecx
0174     andl    CW_RC,%ecx
0175     cmpl    RC_RND,%ecx
0176     je  LRound_nearest_24
0177 
0178     cmpl    RC_CHOP,%ecx
0179     je  LCheck_truncate_24
0180 
0181     cmpl    RC_UP,%ecx      /* Towards +infinity */
0182     je  LUp_24
0183 
0184     cmpl    RC_DOWN,%ecx        /* Towards -infinity */
0185     je  LDown_24
0186 
0187 #ifdef PARANOID
0188     jmp L_bugged_round24
0189 #endif /* PARANOID */ 
0190 
0191 LUp_24:
0192     cmpb    SIGN_POS,PARAM5
0193     jne LCheck_truncate_24  /* If negative then  up==truncate */
0194 
0195     jmp LCheck_24_round_up
0196 
0197 LDown_24:
0198     cmpb    SIGN_POS,PARAM5
0199     je  LCheck_truncate_24  /* If positive then  down==truncate */
0200 
0201 LCheck_24_round_up:
0202     movl    %eax,%ecx
0203     andl    $0x000000ff,%ecx
0204     orl %ebx,%ecx
0205     orl %edx,%ecx
0206     jnz LDo_24_round_up
0207     jmp L_Re_normalise
0208 
0209 LRound_nearest_24:
0210     /* Do rounding of the 24th bit if needed (nearest or even) */
0211     movl    %eax,%ecx
0212     andl    $0x000000ff,%ecx
0213     cmpl    $0x00000080,%ecx
0214     jc  LCheck_truncate_24  /* less than half, no increment needed */
0215 
0216     jne LGreater_Half_24    /* greater than half, increment needed */
0217 
0218     /* Possibly half, we need to check the ls bits */
0219     orl %ebx,%ebx
0220     jnz LGreater_Half_24    /* greater than half, increment needed */
0221 
0222     orl %edx,%edx
0223     jnz LGreater_Half_24    /* greater than half, increment needed */
0224 
0225     /* Exactly half, increment only if 24th bit is 1 (round to even) */
0226     testl   $0x00000100,%eax
0227     jz  LDo_truncate_24
0228 
0229 LGreater_Half_24:           /* Rounding: increment at the 24th bit */
0230 LDo_24_round_up:
0231     andl    $0xffffff00,%eax    /* Truncate to 24 bits */
0232     xorl    %ebx,%ebx
0233     movb    LOST_UP,FPU_bits_lost
0234     addl    $0x00000100,%eax
0235     jmp LCheck_Round_Overflow
0236 
0237 LCheck_truncate_24:
0238     movl    %eax,%ecx
0239     andl    $0x000000ff,%ecx
0240     orl %ebx,%ecx
0241     orl %edx,%ecx
0242     jz  L_Re_normalise      /* No truncation needed */
0243 
0244 LDo_truncate_24:
0245     andl    $0xffffff00,%eax    /* Truncate to 24 bits */
0246     xorl    %ebx,%ebx
0247     movb    LOST_DOWN,FPU_bits_lost
0248     jmp L_Re_normalise
0249 
0250 
0251 /* Round etc to 53 bit precision */
0252 LRound_To_53:
0253     movl    %esi,%ecx
0254     andl    CW_RC,%ecx
0255     cmpl    RC_RND,%ecx
0256     je  LRound_nearest_53
0257 
0258     cmpl    RC_CHOP,%ecx
0259     je  LCheck_truncate_53
0260 
0261     cmpl    RC_UP,%ecx      /* Towards +infinity */
0262     je  LUp_53
0263 
0264     cmpl    RC_DOWN,%ecx        /* Towards -infinity */
0265     je  LDown_53
0266 
0267 #ifdef PARANOID
0268     jmp L_bugged_round53
0269 #endif /* PARANOID */ 
0270 
0271 LUp_53:
0272     cmpb    SIGN_POS,PARAM5
0273     jne LCheck_truncate_53  /* If negative then  up==truncate */
0274 
0275     jmp LCheck_53_round_up
0276 
0277 LDown_53:
0278     cmpb    SIGN_POS,PARAM5
0279     je  LCheck_truncate_53  /* If positive then  down==truncate */
0280 
0281 LCheck_53_round_up:
0282     movl    %ebx,%ecx
0283     andl    $0x000007ff,%ecx
0284     orl %edx,%ecx
0285     jnz LDo_53_round_up
0286     jmp L_Re_normalise
0287 
0288 LRound_nearest_53:
0289     /* Do rounding of the 53rd bit if needed (nearest or even) */
0290     movl    %ebx,%ecx
0291     andl    $0x000007ff,%ecx
0292     cmpl    $0x00000400,%ecx
0293     jc  LCheck_truncate_53  /* less than half, no increment needed */
0294 
0295     jnz LGreater_Half_53    /* greater than half, increment needed */
0296 
0297     /* Possibly half, we need to check the ls bits */
0298     orl %edx,%edx
0299     jnz LGreater_Half_53    /* greater than half, increment needed */
0300 
0301     /* Exactly half, increment only if 53rd bit is 1 (round to even) */
0302     testl   $0x00000800,%ebx
0303     jz  LTruncate_53
0304 
0305 LGreater_Half_53:           /* Rounding: increment at the 53rd bit */
0306 LDo_53_round_up:
0307     movb    LOST_UP,FPU_bits_lost
0308     andl    $0xfffff800,%ebx    /* Truncate to 53 bits */
0309     addl    $0x00000800,%ebx
0310     adcl    $0,%eax
0311     jmp LCheck_Round_Overflow
0312 
0313 LCheck_truncate_53:
0314     movl    %ebx,%ecx
0315     andl    $0x000007ff,%ecx
0316     orl %edx,%ecx
0317     jz  L_Re_normalise
0318 
0319 LTruncate_53:
0320     movb    LOST_DOWN,FPU_bits_lost
0321     andl    $0xfffff800,%ebx    /* Truncate to 53 bits */
0322     jmp L_Re_normalise
0323 
0324 
0325 /* Round etc to 64 bit precision */
0326 LRound_To_64:
0327     movl    %esi,%ecx
0328     andl    CW_RC,%ecx
0329     cmpl    RC_RND,%ecx
0330     je  LRound_nearest_64
0331 
0332     cmpl    RC_CHOP,%ecx
0333     je  LCheck_truncate_64
0334 
0335     cmpl    RC_UP,%ecx      /* Towards +infinity */
0336     je  LUp_64
0337 
0338     cmpl    RC_DOWN,%ecx        /* Towards -infinity */
0339     je  LDown_64
0340 
0341 #ifdef PARANOID
0342     jmp L_bugged_round64
0343 #endif /* PARANOID */ 
0344 
0345 LUp_64:
0346     cmpb    SIGN_POS,PARAM5
0347     jne LCheck_truncate_64  /* If negative then  up==truncate */
0348 
0349     orl %edx,%edx
0350     jnz LDo_64_round_up
0351     jmp L_Re_normalise
0352 
0353 LDown_64:
0354     cmpb    SIGN_POS,PARAM5
0355     je  LCheck_truncate_64  /* If positive then  down==truncate */
0356 
0357     orl %edx,%edx
0358     jnz LDo_64_round_up
0359     jmp L_Re_normalise
0360 
0361 LRound_nearest_64:
0362     cmpl    $0x80000000,%edx
0363     jc  LCheck_truncate_64
0364 
0365     jne LDo_64_round_up
0366 
0367     /* Now test for round-to-even */
0368     testb   $1,%bl
0369     jz  LCheck_truncate_64
0370 
0371 LDo_64_round_up:
0372     movb    LOST_UP,FPU_bits_lost
0373     addl    $1,%ebx
0374     adcl    $0,%eax
0375 
0376 LCheck_Round_Overflow:
0377     jnc L_Re_normalise
0378 
0379     /* Overflow, adjust the result (significand to 1.0) */
0380     rcrl    $1,%eax
0381     rcrl    $1,%ebx
0382     incw    EXP(%edi)
0383     jmp L_Re_normalise
0384 
0385 LCheck_truncate_64:
0386     orl %edx,%edx
0387     jz  L_Re_normalise
0388 
0389 LTruncate_64:
0390     movb    LOST_DOWN,FPU_bits_lost
0391 
0392 L_Re_normalise:
0393     testb   $0xff,FPU_denormal
0394     jnz Normalise_result
0395 
0396 L_Normalised:
0397     movl    TAG_Valid,%edx
0398 
0399 L_deNormalised:
0400     cmpb    LOST_UP,FPU_bits_lost
0401     je  L_precision_lost_up
0402 
0403     cmpb    LOST_DOWN,FPU_bits_lost
0404     je  L_precision_lost_down
0405 
0406 L_no_precision_loss:
0407     /* store the result */
0408 
0409 L_Store_significand:
0410     movl    %eax,SIGH(%edi)
0411     movl    %ebx,SIGL(%edi)
0412 
0413     cmpw    EXP_OVER,EXP(%edi)
0414     jge L_overflow
0415 
0416     movl    %edx,%eax
0417 
0418     /* Convert the exponent to 80x87 form. */
0419     addw    EXTENDED_Ebias,EXP(%edi)
0420     andw    $0x7fff,EXP(%edi)
0421 
0422 fpu_reg_round_signed_special_exit:
0423 
0424     cmpb    SIGN_POS,PARAM5
0425     je  fpu_reg_round_special_exit
0426 
0427     orw $0x8000,EXP(%edi)   /* Negative sign for the result. */
0428 
0429 fpu_reg_round_special_exit:
0430 
0431 #ifndef NON_REENTRANT_FPU
0432     popl    %ebx        /* adjust the stack pointer */
0433 #endif /* NON_REENTRANT_FPU */ 
0434 
0435 fpu_Arith_exit:
0436     popl    %ebx
0437     popl    %edi
0438     popl    %esi
0439     leave
0440     RET
0441 
0442 
0443 /*
0444  * Set the FPU status flags to represent precision loss due to
0445  * round-up.
0446  */
0447 L_precision_lost_up:
0448     push    %edx
0449     push    %eax
0450     call    set_precision_flag_up
0451     popl    %eax
0452     popl    %edx
0453     jmp L_no_precision_loss
0454 
0455 /*
0456  * Set the FPU status flags to represent precision loss due to
0457  * truncation.
0458  */
0459 L_precision_lost_down:
0460     push    %edx
0461     push    %eax
0462     call    set_precision_flag_down
0463     popl    %eax
0464     popl    %edx
0465     jmp L_no_precision_loss
0466 
0467 
0468 /*
0469  * The number is a denormal (which might get rounded up to a normal)
0470  * Shift the number right the required number of bits, which will
0471  * have to be undone later...
0472  */
0473 L_Make_denorm:
0474     /* The action to be taken depends upon whether the underflow
0475        exception is masked */
0476     testb   CW_Underflow,%cl        /* Underflow mask. */
0477     jz  Unmasked_underflow      /* Do not make a denormal. */
0478 
0479     movb    DENORMAL,FPU_denormal
0480 
0481     pushl   %ecx        /* Save */
0482     movw    EXP_UNDER+1,%cx
0483     subw    EXP(%edi),%cx
0484 
0485     cmpw    $64,%cx /* shrd only works for 0..31 bits */
0486     jnc Denorm_shift_more_than_63
0487 
0488     cmpw    $32,%cx /* shrd only works for 0..31 bits */
0489     jnc Denorm_shift_more_than_32
0490 
0491 /*
0492  * We got here without jumps by assuming that the most common requirement
0493  *   is for a small de-normalising shift.
0494  * Shift by [1..31] bits
0495  */
0496     addw    %cx,EXP(%edi)
0497     orl %edx,%edx   /* extension */
0498     setne   %ch     /* Save whether %edx is non-zero */
0499     xorl    %edx,%edx
0500     shrd    %cl,%ebx,%edx
0501     shrd    %cl,%eax,%ebx
0502     shr %cl,%eax
0503     orb %ch,%dl
0504     popl    %ecx
0505     jmp Denorm_done
0506 
0507 /* Shift by [32..63] bits */
0508 Denorm_shift_more_than_32:
0509     addw    %cx,EXP(%edi)
0510     subb    $32,%cl
0511     orl %edx,%edx
0512     setne   %ch
0513     orb %ch,%bl
0514     xorl    %edx,%edx
0515     shrd    %cl,%ebx,%edx
0516     shrd    %cl,%eax,%ebx
0517     shr %cl,%eax
0518     orl %edx,%edx       /* test these 32 bits */
0519     setne   %cl
0520     orb %ch,%bl
0521     orb %cl,%bl
0522     movl    %ebx,%edx
0523     movl    %eax,%ebx
0524     xorl    %eax,%eax
0525     popl    %ecx
0526     jmp Denorm_done
0527 
0528 /* Shift by [64..) bits */
0529 Denorm_shift_more_than_63:
0530     cmpw    $64,%cx
0531     jne Denorm_shift_more_than_64
0532 
0533 /* Exactly 64 bit shift */
0534     addw    %cx,EXP(%edi)
0535     xorl    %ecx,%ecx
0536     orl %edx,%edx
0537     setne   %cl
0538     orl %ebx,%ebx
0539     setne   %ch
0540     orb %ch,%cl
0541     orb %cl,%al
0542     movl    %eax,%edx
0543     xorl    %eax,%eax
0544     xorl    %ebx,%ebx
0545     popl    %ecx
0546     jmp Denorm_done
0547 
0548 Denorm_shift_more_than_64:
0549     movw    EXP_UNDER+1,EXP(%edi)
0550 /* This is easy, %eax must be non-zero, so.. */
0551     movl    $1,%edx
0552     xorl    %eax,%eax
0553     xorl    %ebx,%ebx
0554     popl    %ecx
0555     jmp Denorm_done
0556 
0557 
0558 Unmasked_underflow:
0559     movb    UNMASKED_UNDERFLOW,FPU_denormal
0560     jmp Denorm_done
0561 
0562 
0563 /* Undo the de-normalisation. */
0564 Normalise_result:
0565     cmpb    UNMASKED_UNDERFLOW,FPU_denormal
0566     je  Signal_underflow
0567 
0568 /* The number must be a denormal if we got here. */
0569 #ifdef PARANOID
0570     /* But check it... just in case. */
0571     cmpw    EXP_UNDER+1,EXP(%edi)
0572     jne L_norm_bugged
0573 #endif /* PARANOID */
0574 
0575 #ifdef PECULIAR_486
0576     /*
0577      * This implements a special feature of 80486 behaviour.
0578      * Underflow will be signaled even if the number is
0579      * not a denormal after rounding.
0580      * This difference occurs only for masked underflow, and not
0581      * in the unmasked case.
0582      * Actual 80486 behaviour differs from this in some circumstances.
0583      */
0584     orl %eax,%eax       /* ms bits */
0585     js  LPseudoDenormal     /* Will be masked underflow */
0586 #else
0587     orl %eax,%eax       /* ms bits */
0588     js  L_Normalised        /* No longer a denormal */
0589 #endif /* PECULIAR_486 */ 
0590 
0591     jnz LDenormal_adj_exponent
0592 
0593     orl %ebx,%ebx
0594     jz  L_underflow_to_zero /* The contents are zero */
0595 
0596 LDenormal_adj_exponent:
0597     decw    EXP(%edi)
0598 
0599 LPseudoDenormal:
0600     testb   $0xff,FPU_bits_lost /* bits lost == underflow */
0601     movl    TAG_Special,%edx
0602     jz  L_deNormalised
0603 
0604     /* There must be a masked underflow */
0605     push    %eax
0606     pushl   EX_Underflow
0607     call    EXCEPTION
0608     popl    %eax
0609     popl    %eax
0610     movl    TAG_Special,%edx
0611     jmp L_deNormalised
0612 
0613 
0614 /*
0615  * The operations resulted in a number too small to represent.
0616  * Masked response.
0617  */
0618 L_underflow_to_zero:
0619     push    %eax
0620     call    set_precision_flag_down
0621     popl    %eax
0622 
0623     push    %eax
0624     pushl   EX_Underflow
0625     call    EXCEPTION
0626     popl    %eax
0627     popl    %eax
0628 
0629 /* Reduce the exponent to EXP_UNDER */
0630     movw    EXP_UNDER,EXP(%edi)
0631     movl    TAG_Zero,%edx
0632     jmp L_Store_significand
0633 
0634 
0635 /* The operations resulted in a number too large to represent. */
0636 L_overflow:
0637     addw    EXTENDED_Ebias,EXP(%edi)    /* Set for unmasked response. */
0638     push    %edi
0639     call    arith_overflow
0640     pop %edi
0641     jmp fpu_reg_round_signed_special_exit
0642 
0643 
0644 Signal_underflow:
0645     /* The number may have been changed to a non-denormal */
0646     /* by the rounding operations. */
0647     cmpw    EXP_UNDER,EXP(%edi)
0648     jle Do_unmasked_underflow
0649 
0650     jmp L_Normalised
0651 
0652 Do_unmasked_underflow:
0653     /* Increase the exponent by the magic number */
0654     addw    $(3*(1<<13)),EXP(%edi)
0655     push    %eax
0656     pushl   EX_Underflow
0657     call    EXCEPTION
0658     popl    %eax
0659     popl    %eax
0660     jmp L_Normalised
0661 
0662 
0663 #ifdef PARANOID
0664 #ifdef PECULIAR_486
0665 L_bugged_denorm_486:
0666     pushl   EX_INTERNAL|0x236
0667     call    EXCEPTION
0668     popl    %ebx
0669     jmp L_exception_exit
0670 #else
0671 L_bugged_denorm:
0672     pushl   EX_INTERNAL|0x230
0673     call    EXCEPTION
0674     popl    %ebx
0675     jmp L_exception_exit
0676 #endif /* PECULIAR_486 */ 
0677 
0678 L_bugged_round24:
0679     pushl   EX_INTERNAL|0x231
0680     call    EXCEPTION
0681     popl    %ebx
0682     jmp L_exception_exit
0683 
0684 L_bugged_round53:
0685     pushl   EX_INTERNAL|0x232
0686     call    EXCEPTION
0687     popl    %ebx
0688     jmp L_exception_exit
0689 
0690 L_bugged_round64:
0691     pushl   EX_INTERNAL|0x233
0692     call    EXCEPTION
0693     popl    %ebx
0694     jmp L_exception_exit
0695 
0696 L_norm_bugged:
0697     pushl   EX_INTERNAL|0x234
0698     call    EXCEPTION
0699     popl    %ebx
0700     jmp L_exception_exit
0701 
0702 L_entry_bugged:
0703     pushl   EX_INTERNAL|0x235
0704     call    EXCEPTION
0705     popl    %ebx
0706 L_exception_exit:
0707     mov $-1,%eax
0708     jmp fpu_reg_round_special_exit
0709 #endif /* PARANOID */ 
0710 
0711 SYM_FUNC_END(FPU_round)