^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) | kernel_ex.sa 3.3 12/19/90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | This file contains routines to force exception status in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | fpu for exceptional cases detected or reported within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | transcendental functions. Typically, the t_xx routine will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | set the appropriate bits in the USER_FPSR word on the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | The bits are tested in gen_except.sa to determine if an exceptional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) | situation needs to be created on return from the FPSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) | All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) | For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) | file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) KERNEL_EX: |idnt 2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) |section 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) mns_inf: .long 0xffff0000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) pls_inf: .long 0x7fff0000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) nan: .long 0x7fff0000,0xffffffff,0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) huge: .long 0x7ffe0000,0xffffffff,0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) |xref ovf_r_k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) |xref unf_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) |xref nrm_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .global t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .global t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .global t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .global t_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .global t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .global t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .global t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .global t_frcinx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .global t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .global t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .global dst_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .global src_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) | DZ exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) | if dz trap disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) | store properly signed inf (use sign of etemp) into fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) | set FPSR exception status dz bit, condition code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) | inf bit, and accrued dz bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) | return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) | frestore the frame into the machine (done by unimp_hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) | else dz trap enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) | set exception status bit & accrued bits in FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) | set flag to disable sto_res from corrupting fp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) | return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) | frestore the frame into the machine (done by unimp_hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) | t_dz2 is used by monadic functions such as flogn (from do_func).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) | t_dz is used by monadic functions such as satanh (from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) | transcendental function).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) t_dz2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) bsetb #neg_bit,FPSR_CC(%a6) |set neg bit in FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) fmovel #0,%FPSR |clr status bits (Z set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) btstb #dz_bit,FPCR_ENABLE(%a6) |test FPCR for dz exc enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bnes dz_ena_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bras m_inf |flogx always returns -inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) t_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) fmovel #0,%FPSR |clr status bits (Z set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) btstb #dz_bit,FPCR_ENABLE(%a6) |test FPCR for dz exc enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) bnes dz_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) | dz disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) btstb #sign_bit,ETEMP_EX(%a6) |check sign for neg or pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) beqs p_inf |branch if pos sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) m_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) fmovemx mns_inf,%fp0-%fp0 |load -inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) bsetb #neg_bit,FPSR_CC(%a6) |set neg bit in FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) bras set_fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) p_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) fmovemx pls_inf,%fp0-%fp0 |load +inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) set_fpsr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) orl #dzinf_mask,USER_FPSR(%a6) |set I,DZ,ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) | dz enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dz_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) btstb #sign_bit,ETEMP_EX(%a6) |check sign for neg or pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) beqs dz_ena_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) bsetb #neg_bit,FPSR_CC(%a6) |set neg bit in FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dz_ena_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) orl #dzinf_mask,USER_FPSR(%a6) |set I,DZ,ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) st STORE_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) | OPERR exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) | if (operr trap disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) | set FPSR exception status operr bit, condition code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) | nan bit; Store default NAN into fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) | frestore the frame into the machine (done by unimp_hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) | else (operr trap enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) | set FPSR exception status operr bit, accrued operr bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) | set flag to disable sto_res from corrupting fp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) | frestore the frame into the machine (done by unimp_hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) t_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) orl #opnan_mask,USER_FPSR(%a6) |set NaN, OPERR, AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) btstb #operr_bit,FPCR_ENABLE(%a6) |test FPCR for operr enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bnes op_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) fmovemx nan,%fp0-%fp0 |load default nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) op_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) st STORE_FLG(%a6) |do not corrupt destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) | t_unfl --- UNFL exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) | This entry point is used by all routines requiring unfl, inex2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) | aunfl, and ainex to be set on exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) | On entry, a0 points to the exceptional operand. The final exceptional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) | operand is built in FP_SCR1 and only the sign from the original operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) | is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) t_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) clrl FP_SCR1(%a6) |set exceptional operand to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) clrl FP_SCR1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) clrl FP_SCR1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) tstb (%a0) |extract sign from caller's exop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) bpls unfl_signok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) bset #sign_bit,FP_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unfl_signok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) leal FP_SCR1(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) orl #unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) | ;set UNFL, INEX2, AUNFL, AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unfl_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) btstb #unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) beqs unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) bfclr STAG(%a6){#5:#3} |clear wbtm66,wbtm1,wbtm0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bsetb #wbtemp15_bit,WB_BYTE(%a6) |set wbtemp15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bsetb #sticky_bit,STICKY(%a6) |set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) bclrb #E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) bfextu FPCR_MODE(%a6){#0:#2},%d0 |get round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) bclrb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) sne LOCAL_SGN(%a0) |convert to internal ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) bsr unf_sub |returns IEEE result at a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) | ;and sets FPSR_CC accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) bfclr LOCAL_SGN(%a0){#0:#8} |convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) beqs unfl_fin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) bsetb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) bsetb #sign_bit,FP_SCR1(%a6) |set sign bit of exc operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unfl_fin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fmovemx (%a0),%fp0-%fp0 |store result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) | t_ovfl2 --- OVFL exception (without inex2 returned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) | This entry is used by scale to force catastrophic overflow. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) | ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) t_ovfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) orl #ovfl_inx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) movel ETEMP(%a6),FP_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) movel ETEMP_HI(%a6),FP_SCR1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) movel ETEMP_LO(%a6),FP_SCR1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) | Check for single or double round precision. If single, check if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) | the lower 40 bits of ETEMP are zero; if not, set inex2. If double,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) | check if the lower 21 bits are zero; if not, set inex2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) moveb FPCR_MODE(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) andib #0xc0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) beq t_work |if extended, finish ovfl processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cmpib #0x40,%d0 |test for single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) bnes t_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) t_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) tstb ETEMP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) bnes t_setinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) movel ETEMP_HI(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) andil #0xff,%d0 |look at only lower 8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bnes t_setinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) bra t_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) t_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) movel ETEMP_LO(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) andil #0x7ff,%d0 |look at only lower 11 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) beq t_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) t_setinx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) orl #inex2_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) bras t_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) | t_ovfl --- OVFL exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) |** Note: the exc operand is returned in ETEMP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) t_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) orl #ovfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) t_work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) btstb #ovfl_bit,FPCR_ENABLE(%a6) |test FPCR for ovfl enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) beqs ovf_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ovf_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) clrl FP_SCR1(%a6) |set exceptional operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) clrl FP_SCR1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) clrl FP_SCR1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) bfclr STAG(%a6){#5:#3} |clear wbtm66,wbtm1,wbtm0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) bclrb #wbtemp15_bit,WB_BYTE(%a6) |clear wbtemp15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) bsetb #sticky_bit,STICKY(%a6) |set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) bclrb #E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) | ;fall through to disabled case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) | For disabled overflow call 'ovf_r_k'. This routine loads the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) | correct result based on the rounding precision, destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) | format, rounding mode and sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ovf_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) bsr ovf_r_k |returns unsigned ETEMP_EX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) | ;and sets FPSR_CC accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) bfclr ETEMP_SGN(%a6){#0:#8} |fix sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) beqs ovf_pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bsetb #sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) bsetb #sign_bit,FP_SCR1(%a6) |set exceptional operand sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ovf_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) fmovemx ETEMP(%a6),%fp0-%fp0 |move the result to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) | INEX2 exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) | The inex2 and ainex bits are set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) t_inx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) orl #inx2a_mask,USER_FPSR(%a6) |set INEX2, AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) | Force Inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) | This routine is called by the transcendental routines to force
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) | the inex2 exception bits set in the FPSR. If the underflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) | is set, but the underflow trap was not taken, the aunfl bit in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) | the FPSR must be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) t_frcinx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) orl #inx2a_mask,USER_FPSR(%a6) |set INEX2, AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) btstb #unfl_bit,FPSR_EXCEPT(%a6) |test for unfl bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) beqs no_uacc1 |if clear, do not set aunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) bsetb #aunfl_bit,FPSR_AEXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) no_uacc1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) | DST_NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) | Determine if the destination nan is signalling or non-signalling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) | and set the FPSR bits accordingly. See the MC68040 User's Manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) | section 3.2.2.5 NOT-A-NUMBERS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) dst_nan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) btstb #sign_bit,FPTEMP_EX(%a6) |test sign of nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) beqs dst_pos |if clr, it was positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) bsetb #neg_bit,FPSR_CC(%a6) |set N bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dst_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) btstb #signan_bit,FPTEMP_HI(%a6) |check if signalling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) beqs dst_snan |branch if signalling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) fmovel %d1,%fpcr |restore user's rmode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) fmovex FPTEMP(%a6),%fp0 |return the non-signalling nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) | Check the source nan. If it is signalling, snan will be reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) moveb STAG(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) andib #0xe0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) cmpib #0x60,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) bnes no_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) btstb #signan_bit,ETEMP_HI(%a6) |check if signalling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) bnes no_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) orl #snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) no_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dst_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) btstb #snan_bit,FPCR_ENABLE(%a6) |check if trap enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) beqs dst_dis |branch if disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) orb #nan_tag,DTAG(%a6) |set up dtag for nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) st STORE_FLG(%a6) |do not store a result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) orl #snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dst_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) bsetb #signan_bit,FPTEMP_HI(%a6) |set SNAN bit in sop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) fmovel %d1,%fpcr |restore user's rmode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fmovex FPTEMP(%a6),%fp0 |load non-sign. nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) orl #snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) rts
^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) | SRC_NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) | Determine if the source nan is signalling or non-signalling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) | and set the FPSR bits accordingly. See the MC68040 User's Manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) | section 3.2.2.5 NOT-A-NUMBERS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) src_nan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) btstb #sign_bit,ETEMP_EX(%a6) |test sign of nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) beqs src_pos |if clr, it was positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) bsetb #neg_bit,FPSR_CC(%a6) |set N bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) src_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) btstb #signan_bit,ETEMP_HI(%a6) |check if signalling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) beqs src_snan |branch if signalling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) fmovel %d1,%fpcr |restore user's rmode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) fmovex ETEMP(%a6),%fp0 |return the non-signalling nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) src_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) btstb #snan_bit,FPCR_ENABLE(%a6) |check if trap enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) beqs src_dis |branch if disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) bsetb #signan_bit,ETEMP_HI(%a6) |set SNAN bit in sop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) orb #norm_tag,DTAG(%a6) |set up dtag for norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) orb #nan_tag,STAG(%a6) |set up stag for nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) st STORE_FLG(%a6) |do not store a result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) orl #snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) src_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) bsetb #signan_bit,ETEMP_HI(%a6) |set SNAN bit in sop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) fmovel %d1,%fpcr |restore user's rmode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) fmovex ETEMP(%a6),%fp0 |load non-sign. nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) orl #snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) | For all functions that have a denormalized input and that f(x)=x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) | this is the entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) t_extdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) orl #unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) | ;set UNFL, INEX2, AUNFL, AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) bras xdnrm_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) | Entry point for scale with extended denorm. The function does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) | not set inex2, aunfl, or ainex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) t_resdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) orl #unfl_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) xdnrm_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) btstb #unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) beqs xdnrm_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) | If exceptions are enabled, the additional task of setting up WBTEMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) | is needed so that when the underflow exception handler is entered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) | the user perceives no difference between what the 040 provides vs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) | what the FPSP provides.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) xdnrm_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) movel %a0,-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) movel LOCAL_EX(%a0),FP_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) movel LOCAL_HI(%a0),FP_SCR1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) movel LOCAL_LO(%a0),FP_SCR1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) lea FP_SCR1(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) bclrb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) sne LOCAL_SGN(%a0) |convert to internal ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) tstw LOCAL_EX(%a0) |check if input is denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) beqs xdnrm_dn |if so, skip nrm_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) bsr nrm_set |normalize the result (exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) | ;will be negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) xdnrm_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) bclrb #sign_bit,LOCAL_EX(%a0) |take off false sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) beqs xdep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) bsetb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) xdep:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) bfclr STAG(%a6){#5:#3} |clear wbtm66,wbtm1,wbtm0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bsetb #wbtemp15_bit,WB_BYTE(%a6) |set wbtemp15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) bclrb #sticky_bit,STICKY(%a6) |clear sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) bclrb #E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) movel (%a7)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) xdnrm_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) bfextu FPCR_MODE(%a6){#0:#2},%d0 |get round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) bnes not_ext |if not round extended, store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) | ;IEEE defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) is_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) beqs xdnrm_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) bsetb #neg_bit,FPSR_CC(%a6) |set N bit in FPSR_CC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) bras xdnrm_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) bclrb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) sne LOCAL_SGN(%a0) |convert to internal ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) bsr unf_sub |returns IEEE result pointed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) | ;a0; sets FPSR_CC accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) bfclr LOCAL_SGN(%a0){#0:#8} |convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) beqs xdnrm_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) bsetb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) xdnrm_store:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) fmovemx (%a0),%fp0-%fp0 |store result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) | This subroutine is used for dyadic operations that use an extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) | denorm within the kernel. The approach used is to capture the frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) | fix/restore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .global t_avoid_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) t_avoid_unsupp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) link %a2,#-LOCAL_SIZE |so that a2 fpsp.h negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) | ;offsets may be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) fsave -(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) tstb 1(%a7) |check if idle, exit if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) beq idle_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) btstb #E1,E_BYTE(%a2) |check for an E1 exception if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) | ;enabled, there is an unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) beq end_avun |else, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) btstb #7,DTAG(%a2) |check for denorm destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) beqs src_den |else, must be a source denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) | handle destination denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) lea FPTEMP(%a2),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) sne LOCAL_SGN(%a0) |convert to internal ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) bclrb #7,DTAG(%a2) |set DTAG to norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) bsr nrm_set |normalize result, exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) | ;will become negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) bclrb #sign_bit,LOCAL_EX(%a0) |get rid of fake sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) bfclr LOCAL_SGN(%a0){#0:#8} |convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) beqs ck_src_den |check if source is also denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) bsetb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ck_src_den:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) btstb #7,STAG(%a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) beqs end_avun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) src_den:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) lea ETEMP(%a2),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) sne LOCAL_SGN(%a0) |convert to internal ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) bclrb #7,STAG(%a2) |set STAG to norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) bsr nrm_set |normalize result, exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) | ;will become negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) bclrb #sign_bit,LOCAL_EX(%a0) |get rid of fake sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) bfclr LOCAL_SGN(%a0){#0:#8} |convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) beqs den_com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) bsetb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) den_com:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) moveb #0xfe,CU_SAVEPC(%a2) |set continue frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) clrw NMNEXC(%a2) |clear NMNEXC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) bclrb #E1,E_BYTE(%a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) | fmove.l %FPSR,FPSR_SHADOW(%a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) | bset.b #SFLAG,E_BYTE(%a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) | bset.b #XFLAG,T_BYTE(%a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) end_avun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) frestore (%a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) unlk %a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) idle_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) addl #4,%a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) unlk %a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) |end