^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) .file "reg_round.S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | reg_round.S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | Rounding/truncation/etc for FPU basic arithmetic functions. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | Copyright (C) 1993,1995,1997 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) | Australia. E-mail billm@suburbia.net |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | This code has four possible entry points. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) | The following must be entered by a jmp instruction: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) | fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) | The FPU_round entry point is intended to be used by C code. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) | From C, call as: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) | int FPU_round(FPU_REG *arg, unsigned int extent, unsigned int control_w) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) | Return value is the tag of the answer, or-ed with FPU_Exception if |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) | one was raised, or -1 on internal error. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) | For correct "up" and "down" rounding, the argument must have the correct |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) | sign. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) | Four entry points. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) | Needed by both the fpu_reg_round and fpu_reg_round_sqrt entry points: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) | %eax:%ebx 64 bit significand |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) | %edx 32 bit extension of the significand |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) | %edi pointer to an FPU_REG for the result to be stored |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) | stack calling function must have set up a C stack frame and |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) | pushed %esi, %edi, and %ebx |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) | Needed just for the fpu_reg_round_sqrt entry point: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) | %cx A control word in the same format as the FPU control word. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) | Otherwise, PARAM4 must give such a value. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) | The significand and its extension are assumed to be exact in the |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) | following sense: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) | If the significand by itself is the exact result then the significand |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) | extension (%edx) must contain 0, otherwise the significand extension |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) | must be non-zero. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) | If the significand extension is non-zero then the significand is |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) | smaller than the magnitude of the correct exact result by an amount |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) | greater than zero and less than one ls bit of the significand. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) | The significand extension is only required to have three possible |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) | non-zero values: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) | less than 0x80000000 <=> the significand is less than 1/2 an ls |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) | bit smaller than the magnitude of the |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) | true exact result. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) | exactly 0x80000000 <=> the significand is exactly 1/2 an ls bit |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) | smaller than the magnitude of the true |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) | exact result. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) | greater than 0x80000000 <=> the significand is more than 1/2 an ls |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) | bit smaller than the magnitude of the |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) | true exact result. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) | The code in this module has become quite complex, but it should handle |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) | all of the FPU flags which are set at this stage of the basic arithmetic |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) | computations. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) | There are a few rare cases where the results are not set identically to |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) | a real FPU. These require a bit more thought because at this stage the |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) | results of the code here appear to be more consistent... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) | This may be changed in a future version. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include "fpu_emu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include "exception.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include "control_w.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Flags for FPU_bits_lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LOST_DOWN $1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define LOST_UP $2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Flags for FPU_denormal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define DENORMAL $1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define UNMASKED_UNDERFLOW $2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #ifndef NON_REENTRANT_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Make the code re-entrant by putting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) local storage on the stack: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FPU_bits_lost (%esp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define FPU_denormal 1(%esp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Not re-entrant, so we can gain speed by putting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) local storage in a static area: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .align 4,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) FPU_bits_lost:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .byte 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) FPU_denormal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .byte 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #endif /* NON_REENTRANT_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .globl fpu_reg_round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .globl fpu_Arith_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Entry point when called from C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) SYM_FUNC_START(FPU_round)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pushl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) movl %esp,%ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pushl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pushl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) pushl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) movl PARAM1,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) movl SIGH(%edi),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) movl SIGL(%edi),%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) movl PARAM2,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) fpu_reg_round: /* Normal entry point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) movl PARAM4,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #ifndef NON_REENTRANT_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pushl %ebx /* adjust the stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #endif /* NON_REENTRANT_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Cannot use this here yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* orl %eax,%eax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* jns L_entry_bugged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) cmpw EXP_UNDER,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) jle L_Make_denorm /* The number is a de-normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) movb $0,FPU_denormal /* 0 -> not a de-normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) Denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) movb $0,FPU_bits_lost /* No bits yet lost in rounding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) movl %ecx,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) andl CW_PC,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) cmpl PR_64_BITS,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) je LRound_To_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) cmpl PR_53_BITS,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) je LRound_To_53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) cmpl PR_24_BITS,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) je LRound_To_24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #ifdef PECULIAR_486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* With the precision control bits set to 01 "(reserved)", a real 80486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) behaves as if the precision control bits were set to 11 "64 bits" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) cmpl PR_RESERVED_BITS,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) je LRound_To_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) jmp L_bugged_denorm_486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) jmp L_bugged_denorm /* There is no bug, just a bad control word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #endif /* PECULIAR_486 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Round etc to 24 bit precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) LRound_To_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) movl %esi,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) andl CW_RC,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) cmpl RC_RND,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) je LRound_nearest_24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) cmpl RC_CHOP,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) je LCheck_truncate_24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) cmpl RC_UP,%ecx /* Towards +infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) je LUp_24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) cmpl RC_DOWN,%ecx /* Towards -infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) je LDown_24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) jmp L_bugged_round24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) LUp_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) jne LCheck_truncate_24 /* If negative then up==truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) jmp LCheck_24_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) LDown_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) je LCheck_truncate_24 /* If positive then down==truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) LCheck_24_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) andl $0x000000ff,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) orl %ebx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) orl %edx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) jnz LDo_24_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) LRound_nearest_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* Do rounding of the 24th bit if needed (nearest or even) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) andl $0x000000ff,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) cmpl $0x00000080,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) jc LCheck_truncate_24 /* less than half, no increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) jne LGreater_Half_24 /* greater than half, increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Possibly half, we need to check the ls bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) orl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) jnz LGreater_Half_24 /* greater than half, increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) jnz LGreater_Half_24 /* greater than half, increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Exactly half, increment only if 24th bit is 1 (round to even) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) testl $0x00000100,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) jz LDo_truncate_24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) LGreater_Half_24: /* Rounding: increment at the 24th bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) LDo_24_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) andl $0xffffff00,%eax /* Truncate to 24 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) xorl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) movb LOST_UP,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) addl $0x00000100,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) jmp LCheck_Round_Overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) LCheck_truncate_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) andl $0x000000ff,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) orl %ebx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) orl %edx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) jz L_Re_normalise /* No truncation needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) LDo_truncate_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) andl $0xffffff00,%eax /* Truncate to 24 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) xorl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) movb LOST_DOWN,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* Round etc to 53 bit precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) LRound_To_53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) movl %esi,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) andl CW_RC,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) cmpl RC_RND,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) je LRound_nearest_53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) cmpl RC_CHOP,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) je LCheck_truncate_53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) cmpl RC_UP,%ecx /* Towards +infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) je LUp_53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) cmpl RC_DOWN,%ecx /* Towards -infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) je LDown_53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) jmp L_bugged_round53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) LUp_53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) jne LCheck_truncate_53 /* If negative then up==truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) jmp LCheck_53_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) LDown_53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) je LCheck_truncate_53 /* If positive then down==truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) LCheck_53_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) movl %ebx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) andl $0x000007ff,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) orl %edx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) jnz LDo_53_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) LRound_nearest_53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Do rounding of the 53rd bit if needed (nearest or even) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) movl %ebx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) andl $0x000007ff,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) cmpl $0x00000400,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) jc LCheck_truncate_53 /* less than half, no increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) jnz LGreater_Half_53 /* greater than half, increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* Possibly half, we need to check the ls bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) jnz LGreater_Half_53 /* greater than half, increment needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Exactly half, increment only if 53rd bit is 1 (round to even) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) testl $0x00000800,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) jz LTruncate_53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) LGreater_Half_53: /* Rounding: increment at the 53rd bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) LDo_53_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) movb LOST_UP,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) andl $0xfffff800,%ebx /* Truncate to 53 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) addl $0x00000800,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) adcl $0,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) jmp LCheck_Round_Overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) LCheck_truncate_53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) movl %ebx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) andl $0x000007ff,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) orl %edx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) jz L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) LTruncate_53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) movb LOST_DOWN,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) andl $0xfffff800,%ebx /* Truncate to 53 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* Round etc to 64 bit precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) LRound_To_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) movl %esi,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) andl CW_RC,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cmpl RC_RND,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) je LRound_nearest_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) cmpl RC_CHOP,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) je LCheck_truncate_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) cmpl RC_UP,%ecx /* Towards +infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) je LUp_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) cmpl RC_DOWN,%ecx /* Towards -infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) je LDown_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) jmp L_bugged_round64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) LUp_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) jne LCheck_truncate_64 /* If negative then up==truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) jnz LDo_64_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) LDown_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) je LCheck_truncate_64 /* If positive then down==truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) jnz LDo_64_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) LRound_nearest_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) cmpl $0x80000000,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) jc LCheck_truncate_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) jne LDo_64_round_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Now test for round-to-even */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) testb $1,%bl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) jz LCheck_truncate_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) LDo_64_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) movb LOST_UP,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) addl $1,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) adcl $0,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) LCheck_Round_Overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) jnc L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* Overflow, adjust the result (significand to 1.0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) rcrl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) rcrl $1,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) incw EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) jmp L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) LCheck_truncate_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) jz L_Re_normalise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) LTruncate_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) movb LOST_DOWN,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) L_Re_normalise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) testb $0xff,FPU_denormal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) jnz Normalise_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) L_Normalised:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) movl TAG_Valid,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) L_deNormalised:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) cmpb LOST_UP,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) je L_precision_lost_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) cmpb LOST_DOWN,FPU_bits_lost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) je L_precision_lost_down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) L_no_precision_loss:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* store the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) L_Store_significand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) movl %eax,SIGH(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) movl %ebx,SIGL(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) cmpw EXP_OVER,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) jge L_overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) movl %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* Convert the exponent to 80x87 form. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) addw EXTENDED_Ebias,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) andw $0x7fff,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) fpu_reg_round_signed_special_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) cmpb SIGN_POS,PARAM5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) je fpu_reg_round_special_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) orw $0x8000,EXP(%edi) /* Negative sign for the result. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) fpu_reg_round_special_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #ifndef NON_REENTRANT_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) popl %ebx /* adjust the stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #endif /* NON_REENTRANT_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) fpu_Arith_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) popl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) popl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * Set the FPU status flags to represent precision loss due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * round-up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) L_precision_lost_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) push %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) push %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) call set_precision_flag_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) popl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) jmp L_no_precision_loss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * Set the FPU status flags to represent precision loss due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * truncation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) L_precision_lost_down:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) push %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) push %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) call set_precision_flag_down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) popl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) jmp L_no_precision_loss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * The number is a denormal (which might get rounded up to a normal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * Shift the number right the required number of bits, which will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * have to be undone later...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) L_Make_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* The action to be taken depends upon whether the underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) exception is masked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) testb CW_Underflow,%cl /* Underflow mask. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) jz Unmasked_underflow /* Do not make a denormal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) movb DENORMAL,FPU_denormal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pushl %ecx /* Save */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) movw EXP_UNDER+1,%cx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) subw EXP(%edi),%cx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) cmpw $64,%cx /* shrd only works for 0..31 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) jnc Denorm_shift_more_than_63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) cmpw $32,%cx /* shrd only works for 0..31 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) jnc Denorm_shift_more_than_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * We got here without jumps by assuming that the most common requirement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * is for a small de-normalising shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * Shift by [1..31] bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) addw %cx,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) orl %edx,%edx /* extension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) setne %ch /* Save whether %edx is non-zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) xorl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) shrd %cl,%ebx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) shrd %cl,%eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) shr %cl,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) orb %ch,%dl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) jmp Denorm_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Shift by [32..63] bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) Denorm_shift_more_than_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) addw %cx,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) subb $32,%cl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) setne %ch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) orb %ch,%bl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) xorl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) shrd %cl,%ebx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) shrd %cl,%eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) shr %cl,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) orl %edx,%edx /* test these 32 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) setne %cl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) orb %ch,%bl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) orb %cl,%bl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) movl %ebx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) movl %eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) xorl %eax,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) jmp Denorm_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* Shift by [64..) bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) Denorm_shift_more_than_63:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) cmpw $64,%cx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) jne Denorm_shift_more_than_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* Exactly 64 bit shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) addw %cx,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) xorl %ecx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) orl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) setne %cl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) orl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) setne %ch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) orb %ch,%cl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) orb %cl,%al
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) movl %eax,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) xorl %eax,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) xorl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) jmp Denorm_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) Denorm_shift_more_than_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) movw EXP_UNDER+1,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* This is easy, %eax must be non-zero, so.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) movl $1,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) xorl %eax,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) xorl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) popl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) jmp Denorm_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) Unmasked_underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) movb UNMASKED_UNDERFLOW,FPU_denormal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) jmp Denorm_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* Undo the de-normalisation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) Normalise_result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) cmpb UNMASKED_UNDERFLOW,FPU_denormal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) je Signal_underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* The number must be a denormal if we got here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* But check it... just in case. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) cmpw EXP_UNDER+1,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) jne L_norm_bugged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef PECULIAR_486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * This implements a special feature of 80486 behaviour.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * Underflow will be signalled even if the number is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * not a denormal after rounding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * This difference occurs only for masked underflow, and not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * in the unmasked case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * Actual 80486 behaviour differs from this in some circumstances.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) orl %eax,%eax /* ms bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) js LPseudoDenormal /* Will be masked underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) orl %eax,%eax /* ms bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) js L_Normalised /* No longer a denormal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #endif /* PECULIAR_486 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) jnz LDenormal_adj_exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) orl %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) jz L_underflow_to_zero /* The contents are zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) LDenormal_adj_exponent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) decw EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) LPseudoDenormal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) testb $0xff,FPU_bits_lost /* bits lost == underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) movl TAG_Special,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) jz L_deNormalised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* There must be a masked underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) push %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) pushl EX_Underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) movl TAG_Special,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) jmp L_deNormalised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * The operations resulted in a number too small to represent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * Masked response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) L_underflow_to_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) push %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) call set_precision_flag_down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) push %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) pushl EX_Underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Reduce the exponent to EXP_UNDER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) movw EXP_UNDER,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) movl TAG_Zero,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) jmp L_Store_significand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* The operations resulted in a number too large to represent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) L_overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) addw EXTENDED_Ebias,EXP(%edi) /* Set for unmasked response. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) push %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) call arith_overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) pop %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) jmp fpu_reg_round_signed_special_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) Signal_underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* The number may have been changed to a non-denormal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* by the rounding operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) cmpw EXP_UNDER,EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) jle Do_unmasked_underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) jmp L_Normalised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) Do_unmasked_underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* Increase the exponent by the magic number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) addw $(3*(1<<13)),EXP(%edi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) push %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) pushl EX_Underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) popl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) jmp L_Normalised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) #ifdef PECULIAR_486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) L_bugged_denorm_486:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) pushl EX_INTERNAL|0x236
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) jmp L_exception_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) L_bugged_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) pushl EX_INTERNAL|0x230
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) jmp L_exception_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #endif /* PECULIAR_486 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) L_bugged_round24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pushl EX_INTERNAL|0x231
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) jmp L_exception_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) L_bugged_round53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) pushl EX_INTERNAL|0x232
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) jmp L_exception_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) L_bugged_round64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) pushl EX_INTERNAL|0x233
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) jmp L_exception_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) L_norm_bugged:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) pushl EX_INTERNAL|0x234
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) jmp L_exception_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) L_entry_bugged:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) pushl EX_INTERNAL|0x235
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) L_exception_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mov $-1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) jmp fpu_reg_round_special_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) SYM_FUNC_END(FPU_round)