1*57fb77a1Scgd* $NetBSD: kernel_ex.sa,v 1.2 1994/10/26 07:49:12 cgd Exp $ 2*57fb77a1Scgd 322ef5fa9Smycroft* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 422ef5fa9Smycroft* M68000 Hi-Performance Microprocessor Division 522ef5fa9Smycroft* M68040 Software Package 622ef5fa9Smycroft* 722ef5fa9Smycroft* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 822ef5fa9Smycroft* All rights reserved. 922ef5fa9Smycroft* 1022ef5fa9Smycroft* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 1122ef5fa9Smycroft* To the maximum extent permitted by applicable law, 1222ef5fa9Smycroft* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 1322ef5fa9Smycroft* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 1422ef5fa9Smycroft* PARTICULAR PURPOSE and any warranty against infringement with 1522ef5fa9Smycroft* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 1622ef5fa9Smycroft* and any accompanying written materials. 1722ef5fa9Smycroft* 1822ef5fa9Smycroft* To the maximum extent permitted by applicable law, 1922ef5fa9Smycroft* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 2022ef5fa9Smycroft* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 2122ef5fa9Smycroft* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 2222ef5fa9Smycroft* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 2322ef5fa9Smycroft* SOFTWARE. Motorola assumes no responsibility for the maintenance 2422ef5fa9Smycroft* and support of the SOFTWARE. 2522ef5fa9Smycroft* 2622ef5fa9Smycroft* You are hereby granted a copyright license to use, modify, and 2722ef5fa9Smycroft* distribute the SOFTWARE so long as this entire notice is retained 2822ef5fa9Smycroft* without alteration in any modified and/or redistributed versions, 2922ef5fa9Smycroft* and that such modified versions are clearly identified as such. 3022ef5fa9Smycroft* No licenses are granted by implication, estoppel or otherwise 3122ef5fa9Smycroft* under any patents or trademarks of Motorola, Inc. 3222ef5fa9Smycroft 3322ef5fa9Smycroft* 3422ef5fa9Smycroft* kernel_ex.sa 3.3 12/19/90 3522ef5fa9Smycroft* 3622ef5fa9Smycroft* This file contains routines to force exception status in the 3722ef5fa9Smycroft* fpu for exceptional cases detected or reported within the 3822ef5fa9Smycroft* transcendental functions. Typically, the t_xx routine will 3922ef5fa9Smycroft* set the appropriate bits in the USER_FPSR word on the stack. 4022ef5fa9Smycroft* The bits are tested in gen_except.sa to determine if an exceptional 4122ef5fa9Smycroft* situation needs to be created on return from the FPSP. 4222ef5fa9Smycroft* 4322ef5fa9Smycroft 4422ef5fa9SmycroftKERNEL_EX IDNT 2,1 Motorola 040 Floating Point Software Package 4522ef5fa9Smycroft 4622ef5fa9Smycroft section 8 4722ef5fa9Smycroft 4822ef5fa9Smycroft include fpsp.h 4922ef5fa9Smycroft 5022ef5fa9Smycroftmns_inf dc.l $ffff0000,$00000000,$00000000 5122ef5fa9Smycroftpls_inf dc.l $7fff0000,$00000000,$00000000 5222ef5fa9Smycroftnan dc.l $7fff0000,$ffffffff,$ffffffff 5322ef5fa9Smycrofthuge dc.l $7ffe0000,$ffffffff,$ffffffff 5422ef5fa9Smycroft 5522ef5fa9Smycroft xref ovf_r_k 5622ef5fa9Smycroft xref unf_sub 5722ef5fa9Smycroft xref nrm_set 5822ef5fa9Smycroft 5922ef5fa9Smycroft xdef t_dz 6022ef5fa9Smycroft xdef t_dz2 6122ef5fa9Smycroft xdef t_operr 6222ef5fa9Smycroft xdef t_unfl 6322ef5fa9Smycroft xdef t_ovfl 6422ef5fa9Smycroft xdef t_ovfl2 6522ef5fa9Smycroft xdef t_inx2 6622ef5fa9Smycroft xdef t_frcinx 6722ef5fa9Smycroft xdef t_extdnrm 6822ef5fa9Smycroft xdef t_resdnrm 6922ef5fa9Smycroft xdef dst_nan 7022ef5fa9Smycroft xdef src_nan 7122ef5fa9Smycroft* 7222ef5fa9Smycroft* DZ exception 7322ef5fa9Smycroft* 7422ef5fa9Smycroft* 7522ef5fa9Smycroft* if dz trap disabled 7622ef5fa9Smycroft* store properly signed inf (use sign of etemp) into fp0 7722ef5fa9Smycroft* set FPSR exception status dz bit, condition code 7822ef5fa9Smycroft* inf bit, and accrued dz bit 7922ef5fa9Smycroft* return 8022ef5fa9Smycroft* frestore the frame into the machine (done by unimp_hd) 8122ef5fa9Smycroft* 8222ef5fa9Smycroft* else dz trap enabled 8322ef5fa9Smycroft* set exception status bit & accrued bits in FPSR 8422ef5fa9Smycroft* set flag to disable sto_res from corrupting fp register 8522ef5fa9Smycroft* return 8622ef5fa9Smycroft* frestore the frame into the machine (done by unimp_hd) 8722ef5fa9Smycroft* 8822ef5fa9Smycroft* t_dz2 is used by monadic functions such as flogn (from do_func). 8922ef5fa9Smycroft* t_dz is used by monadic functions such as satanh (from the 9022ef5fa9Smycroft* transcendental function). 9122ef5fa9Smycroft* 9222ef5fa9Smycroftt_dz2: 9322ef5fa9Smycroft bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR 9422ef5fa9Smycroft fmove.l #0,FPSR ;clr status bits (Z set) 9522ef5fa9Smycroft btst.b #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled 9622ef5fa9Smycroft bne.b dz_ena_end 9722ef5fa9Smycroft bra.b m_inf ;flogx always returns -inf 9822ef5fa9Smycroftt_dz: 9922ef5fa9Smycroft fmove.l #0,FPSR ;clr status bits (Z set) 10022ef5fa9Smycroft btst.b #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled 10122ef5fa9Smycroft bne.b dz_ena 10222ef5fa9Smycroft* 10322ef5fa9Smycroft* dz disabled 10422ef5fa9Smycroft* 10522ef5fa9Smycroft btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos 10622ef5fa9Smycroft beq.b p_inf ;branch if pos sign 10722ef5fa9Smycroft 10822ef5fa9Smycroftm_inf: 10922ef5fa9Smycroft fmovem.x mns_inf,fp0 ;load -inf 11022ef5fa9Smycroft bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR 11122ef5fa9Smycroft bra.b set_fpsr 11222ef5fa9Smycroftp_inf: 11322ef5fa9Smycroft fmovem.x pls_inf,fp0 ;load +inf 11422ef5fa9Smycroftset_fpsr: 11522ef5fa9Smycroft or.l #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ 11622ef5fa9Smycroft rts 11722ef5fa9Smycroft* 11822ef5fa9Smycroft* dz enabled 11922ef5fa9Smycroft* 12022ef5fa9Smycroftdz_ena: 12122ef5fa9Smycroft btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos 12222ef5fa9Smycroft beq.b dz_ena_end 12322ef5fa9Smycroft bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR 12422ef5fa9Smycroftdz_ena_end: 12522ef5fa9Smycroft or.l #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ 12622ef5fa9Smycroft st.b STORE_FLG(a6) 12722ef5fa9Smycroft rts 12822ef5fa9Smycroft* 12922ef5fa9Smycroft* OPERR exception 13022ef5fa9Smycroft* 13122ef5fa9Smycroft* if (operr trap disabled) 13222ef5fa9Smycroft* set FPSR exception status operr bit, condition code 13322ef5fa9Smycroft* nan bit; Store default NAN into fp0 13422ef5fa9Smycroft* frestore the frame into the machine (done by unimp_hd) 13522ef5fa9Smycroft* 13622ef5fa9Smycroft* else (operr trap enabled) 13722ef5fa9Smycroft* set FPSR exception status operr bit, accrued operr bit 13822ef5fa9Smycroft* set flag to disable sto_res from corrupting fp register 13922ef5fa9Smycroft* frestore the frame into the machine (done by unimp_hd) 14022ef5fa9Smycroft* 14122ef5fa9Smycroftt_operr: 14222ef5fa9Smycroft or.l #opnan_mask,USER_FPSR(a6) ;set NaN, OPERR, AIOP 14322ef5fa9Smycroft 14422ef5fa9Smycroft btst.b #operr_bit,FPCR_ENABLE(a6) ;test FPCR for operr enabled 14522ef5fa9Smycroft bne.b op_ena 14622ef5fa9Smycroft 14722ef5fa9Smycroft fmovem.x nan,fp0 ;load default nan 14822ef5fa9Smycroft rts 14922ef5fa9Smycroftop_ena: 15022ef5fa9Smycroft st.b STORE_FLG(a6) ;do not corrupt destination 15122ef5fa9Smycroft rts 15222ef5fa9Smycroft 15322ef5fa9Smycroft* 15422ef5fa9Smycroft* t_unfl --- UNFL exception 15522ef5fa9Smycroft* 15622ef5fa9Smycroft* This entry point is used by all routines requiring unfl, inex2, 15722ef5fa9Smycroft* aunfl, and ainex to be set on exit. 15822ef5fa9Smycroft* 15922ef5fa9Smycroft* On entry, a0 points to the exceptional operand. The final exceptional 16022ef5fa9Smycroft* operand is built in FP_SCR1 and only the sign from the original operand 16122ef5fa9Smycroft* is used. 16222ef5fa9Smycroft* 16322ef5fa9Smycroftt_unfl: 16422ef5fa9Smycroft clr.l FP_SCR1(a6) ;set exceptional operand to zero 16522ef5fa9Smycroft clr.l FP_SCR1+4(a6) 16622ef5fa9Smycroft clr.l FP_SCR1+8(a6) 16722ef5fa9Smycroft tst.b (a0) ;extract sign from caller's exop 16822ef5fa9Smycroft bpl.b unfl_signok 16922ef5fa9Smycroft bset #sign_bit,FP_SCR1(a6) 17022ef5fa9Smycroftunfl_signok: 17122ef5fa9Smycroft lea.l FP_SCR1(a6),a0 17222ef5fa9Smycroft or.l #unfinx_mask,USER_FPSR(a6) 17322ef5fa9Smycroft* ;set UNFL, INEX2, AUNFL, AINEX 17422ef5fa9Smycroftunfl_con: 17522ef5fa9Smycroft btst.b #unfl_bit,FPCR_ENABLE(a6) 17622ef5fa9Smycroft beq.b unfl_dis 17722ef5fa9Smycroft 17822ef5fa9Smycroftunfl_ena: 17922ef5fa9Smycroft bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0 18022ef5fa9Smycroft bset.b #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15 18122ef5fa9Smycroft bset.b #sticky_bit,STICKY(a6) ;set sticky bit 18222ef5fa9Smycroft 18322ef5fa9Smycroft bclr.b #E1,E_BYTE(a6) 18422ef5fa9Smycroft 18522ef5fa9Smycroftunfl_dis: 18622ef5fa9Smycroft bfextu FPCR_MODE(a6){0:2},d0 ;get round precision 18722ef5fa9Smycroft 18822ef5fa9Smycroft bclr.b #sign_bit,LOCAL_EX(a0) 18922ef5fa9Smycroft sne LOCAL_SGN(a0) ;convert to internal ext format 19022ef5fa9Smycroft 19122ef5fa9Smycroft bsr unf_sub ;returns IEEE result at a0 19222ef5fa9Smycroft* ;and sets FPSR_CC accordingly 19322ef5fa9Smycroft 19422ef5fa9Smycroft bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format 19522ef5fa9Smycroft beq.b unfl_fin 19622ef5fa9Smycroft 19722ef5fa9Smycroft bset.b #sign_bit,LOCAL_EX(a0) 19822ef5fa9Smycroft bset.b #sign_bit,FP_SCR1(a6) ;set sign bit of exc operand 19922ef5fa9Smycroft 20022ef5fa9Smycroftunfl_fin: 20122ef5fa9Smycroft fmovem.x (a0),fp0 ;store result in fp0 20222ef5fa9Smycroft rts 20322ef5fa9Smycroft 20422ef5fa9Smycroft 20522ef5fa9Smycroft* 20622ef5fa9Smycroft* t_ovfl2 --- OVFL exception (without inex2 returned) 20722ef5fa9Smycroft* 20822ef5fa9Smycroft* This entry is used by scale to force catastrophic overflow. The 20922ef5fa9Smycroft* ovfl, aovfl, and ainex bits are set, but not the inex2 bit. 21022ef5fa9Smycroft* 21122ef5fa9Smycroftt_ovfl2: 21222ef5fa9Smycroft or.l #ovfl_inx_mask,USER_FPSR(a6) 21322ef5fa9Smycroft move.l ETEMP(a6),FP_SCR1(a6) 21422ef5fa9Smycroft move.l ETEMP_HI(a6),FP_SCR1+4(a6) 21522ef5fa9Smycroft move.l ETEMP_LO(a6),FP_SCR1+8(a6) 21622ef5fa9Smycroft* 21722ef5fa9Smycroft* Check for single or double round precision. If single, check if 21822ef5fa9Smycroft* the lower 40 bits of ETEMP are zero; if not, set inex2. If double, 21922ef5fa9Smycroft* check if the lower 21 bits are zero; if not, set inex2. 22022ef5fa9Smycroft* 22122ef5fa9Smycroft move.b FPCR_MODE(a6),d0 22222ef5fa9Smycroft andi.b #$c0,d0 22322ef5fa9Smycroft beq.w t_work ;if extended, finish ovfl processing 22422ef5fa9Smycroft cmpi.b #$40,d0 ;test for single 22522ef5fa9Smycroft bne.b t_dbl 22622ef5fa9Smycroftt_sgl: 22722ef5fa9Smycroft tst.b ETEMP_LO(a6) 22822ef5fa9Smycroft bne.b t_setinx2 22922ef5fa9Smycroft move.l ETEMP_HI(a6),d0 23022ef5fa9Smycroft andi.l #$ff,d0 ;look at only lower 8 bits 23122ef5fa9Smycroft bne.b t_setinx2 23222ef5fa9Smycroft bra.w t_work 23322ef5fa9Smycroftt_dbl: 23422ef5fa9Smycroft move.l ETEMP_LO(a6),d0 23522ef5fa9Smycroft andi.l #$7ff,d0 ;look at only lower 11 bits 23622ef5fa9Smycroft beq.w t_work 23722ef5fa9Smycroftt_setinx2: 23822ef5fa9Smycroft or.l #inex2_mask,USER_FPSR(a6) 23922ef5fa9Smycroft bra.b t_work 24022ef5fa9Smycroft* 24122ef5fa9Smycroft* t_ovfl --- OVFL exception 24222ef5fa9Smycroft* 24322ef5fa9Smycroft*** Note: the exc operand is returned in ETEMP. 24422ef5fa9Smycroft* 24522ef5fa9Smycroftt_ovfl: 24622ef5fa9Smycroft or.l #ovfinx_mask,USER_FPSR(a6) 24722ef5fa9Smycroftt_work: 24822ef5fa9Smycroft btst.b #ovfl_bit,FPCR_ENABLE(a6) ;test FPCR for ovfl enabled 24922ef5fa9Smycroft beq.b ovf_dis 25022ef5fa9Smycroft 25122ef5fa9Smycroftovf_ena: 25222ef5fa9Smycroft clr.l FP_SCR1(a6) ;set exceptional operand 25322ef5fa9Smycroft clr.l FP_SCR1+4(a6) 25422ef5fa9Smycroft clr.l FP_SCR1+8(a6) 25522ef5fa9Smycroft 25622ef5fa9Smycroft bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0 25722ef5fa9Smycroft bclr.b #wbtemp15_bit,WB_BYTE(a6) ;clear wbtemp15 25822ef5fa9Smycroft bset.b #sticky_bit,STICKY(a6) ;set sticky bit 25922ef5fa9Smycroft 26022ef5fa9Smycroft bclr.b #E1,E_BYTE(a6) 26122ef5fa9Smycroft* ;fall through to disabled case 26222ef5fa9Smycroft 26322ef5fa9Smycroft* For disabled overflow call 'ovf_r_k'. This routine loads the 26422ef5fa9Smycroft* correct result based on the rounding precision, destination 26522ef5fa9Smycroft* format, rounding mode and sign. 26622ef5fa9Smycroft* 26722ef5fa9Smycroftovf_dis: 26822ef5fa9Smycroft bsr ovf_r_k ;returns unsigned ETEMP_EX 26922ef5fa9Smycroft* ;and sets FPSR_CC accordingly. 27022ef5fa9Smycroft bfclr ETEMP_SGN(a6){0:8} ;fix sign 27122ef5fa9Smycroft beq.b ovf_pos 27222ef5fa9Smycroft bset.b #sign_bit,ETEMP_EX(a6) 27322ef5fa9Smycroft bset.b #sign_bit,FP_SCR1(a6) ;set exceptional operand sign 27422ef5fa9Smycroftovf_pos: 27522ef5fa9Smycroft fmovem.x ETEMP(a6),fp0 ;move the result to fp0 27622ef5fa9Smycroft rts 27722ef5fa9Smycroft 27822ef5fa9Smycroft 27922ef5fa9Smycroft* 28022ef5fa9Smycroft* INEX2 exception 28122ef5fa9Smycroft* 28222ef5fa9Smycroft* The inex2 and ainex bits are set. 28322ef5fa9Smycroft* 28422ef5fa9Smycroftt_inx2: 28522ef5fa9Smycroft or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX 28622ef5fa9Smycroft rts 28722ef5fa9Smycroft 28822ef5fa9Smycroft* 28922ef5fa9Smycroft* Force Inex2 29022ef5fa9Smycroft* 29122ef5fa9Smycroft* This routine is called by the transcendental routines to force 29222ef5fa9Smycroft* the inex2 exception bits set in the FPSR. If the underflow bit 29322ef5fa9Smycroft* is set, but the underflow trap was not taken, the aunfl bit in 29422ef5fa9Smycroft* the FPSR must be set. 29522ef5fa9Smycroft* 29622ef5fa9Smycroftt_frcinx: 29722ef5fa9Smycroft or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX 29822ef5fa9Smycroft btst.b #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set 29922ef5fa9Smycroft beq.b no_uacc1 ;if clear, do not set aunfl 30022ef5fa9Smycroft bset.b #aunfl_bit,FPSR_AEXCEPT(a6) 30122ef5fa9Smycroftno_uacc1: 30222ef5fa9Smycroft rts 30322ef5fa9Smycroft 30422ef5fa9Smycroft* 30522ef5fa9Smycroft* DST_NAN 30622ef5fa9Smycroft* 30722ef5fa9Smycroft* Determine if the destination nan is signalling or non-signalling, 30822ef5fa9Smycroft* and set the FPSR bits accordingly. See the MC68040 User's Manual 30922ef5fa9Smycroft* section 3.2.2.5 NOT-A-NUMBERS. 31022ef5fa9Smycroft* 31122ef5fa9Smycroftdst_nan: 31222ef5fa9Smycroft btst.b #sign_bit,FPTEMP_EX(a6) ;test sign of nan 31322ef5fa9Smycroft beq.b dst_pos ;if clr, it was positive 31422ef5fa9Smycroft bset.b #neg_bit,FPSR_CC(a6) ;set N bit 31522ef5fa9Smycroftdst_pos: 31622ef5fa9Smycroft btst.b #signan_bit,FPTEMP_HI(a6) ;check if signalling 31722ef5fa9Smycroft beq.b dst_snan ;branch if signalling 31822ef5fa9Smycroft 31922ef5fa9Smycroft fmove.l d1,fpcr ;restore user's rmode/prec 32022ef5fa9Smycroft fmove.x FPTEMP(a6),fp0 ;return the non-signalling nan 32122ef5fa9Smycroft* 32222ef5fa9Smycroft* Check the source nan. If it is signalling, snan will be reported. 32322ef5fa9Smycroft* 32422ef5fa9Smycroft move.b STAG(a6),d0 32522ef5fa9Smycroft andi.b #$e0,d0 32622ef5fa9Smycroft cmpi.b #$60,d0 32722ef5fa9Smycroft bne.b no_snan 32822ef5fa9Smycroft btst.b #signan_bit,ETEMP_HI(a6) ;check if signalling 32922ef5fa9Smycroft bne.b no_snan 33022ef5fa9Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP 33122ef5fa9Smycroftno_snan: 33222ef5fa9Smycroft rts 33322ef5fa9Smycroft 33422ef5fa9Smycroftdst_snan: 33522ef5fa9Smycroft btst.b #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled 33622ef5fa9Smycroft beq.b dst_dis ;branch if disabled 33722ef5fa9Smycroft 33822ef5fa9Smycroft or.b #nan_tag,DTAG(a6) ;set up dtag for nan 33922ef5fa9Smycroft st.b STORE_FLG(a6) ;do not store a result 34022ef5fa9Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP 34122ef5fa9Smycroft rts 34222ef5fa9Smycroft 34322ef5fa9Smycroftdst_dis: 34422ef5fa9Smycroft bset.b #signan_bit,FPTEMP_HI(a6) ;set SNAN bit in sop 34522ef5fa9Smycroft fmove.l d1,fpcr ;restore user's rmode/prec 34622ef5fa9Smycroft fmove.x FPTEMP(a6),fp0 ;load non-sign. nan 34722ef5fa9Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP 34822ef5fa9Smycroft rts 34922ef5fa9Smycroft 35022ef5fa9Smycroft* 35122ef5fa9Smycroft* SRC_NAN 35222ef5fa9Smycroft* 35322ef5fa9Smycroft* Determine if the source nan is signalling or non-signalling, 35422ef5fa9Smycroft* and set the FPSR bits accordingly. See the MC68040 User's Manual 35522ef5fa9Smycroft* section 3.2.2.5 NOT-A-NUMBERS. 35622ef5fa9Smycroft* 35722ef5fa9Smycroftsrc_nan: 35822ef5fa9Smycroft btst.b #sign_bit,ETEMP_EX(a6) ;test sign of nan 35922ef5fa9Smycroft beq.b src_pos ;if clr, it was positive 36022ef5fa9Smycroft bset.b #neg_bit,FPSR_CC(a6) ;set N bit 36122ef5fa9Smycroftsrc_pos: 36222ef5fa9Smycroft btst.b #signan_bit,ETEMP_HI(a6) ;check if signalling 36322ef5fa9Smycroft beq.b src_snan ;branch if signalling 36422ef5fa9Smycroft fmove.l d1,fpcr ;restore user's rmode/prec 36522ef5fa9Smycroft fmove.x ETEMP(a6),fp0 ;return the non-signalling nan 36622ef5fa9Smycroft rts 36722ef5fa9Smycroft 36822ef5fa9Smycroftsrc_snan: 36922ef5fa9Smycroft btst.b #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled 37022ef5fa9Smycroft beq.b src_dis ;branch if disabled 37122ef5fa9Smycroft bset.b #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop 37222ef5fa9Smycroft or.b #norm_tag,DTAG(a6) ;set up dtag for norm 37322ef5fa9Smycroft or.b #nan_tag,STAG(a6) ;set up stag for nan 37422ef5fa9Smycroft st.b STORE_FLG(a6) ;do not store a result 37522ef5fa9Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP 37622ef5fa9Smycroft rts 37722ef5fa9Smycroft 37822ef5fa9Smycroftsrc_dis: 37922ef5fa9Smycroft bset.b #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop 38022ef5fa9Smycroft fmove.l d1,fpcr ;restore user's rmode/prec 38122ef5fa9Smycroft fmove.x ETEMP(a6),fp0 ;load non-sign. nan 38222ef5fa9Smycroft or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP 38322ef5fa9Smycroft rts 38422ef5fa9Smycroft 38522ef5fa9Smycroft* 38622ef5fa9Smycroft* For all functions that have a denormalized input and that f(x)=x, 38722ef5fa9Smycroft* this is the entry point 38822ef5fa9Smycroft* 38922ef5fa9Smycroftt_extdnrm: 39022ef5fa9Smycroft or.l #unfinx_mask,USER_FPSR(a6) 39122ef5fa9Smycroft* ;set UNFL, INEX2, AUNFL, AINEX 39222ef5fa9Smycroft bra.b xdnrm_con 39322ef5fa9Smycroft* 39422ef5fa9Smycroft* Entry point for scale with extended denorm. The function does 39522ef5fa9Smycroft* not set inex2, aunfl, or ainex. 39622ef5fa9Smycroft* 39722ef5fa9Smycroftt_resdnrm: 39822ef5fa9Smycroft or.l #unfl_mask,USER_FPSR(a6) 39922ef5fa9Smycroft 40022ef5fa9Smycroftxdnrm_con: 40122ef5fa9Smycroft btst.b #unfl_bit,FPCR_ENABLE(a6) 40222ef5fa9Smycroft beq.b xdnrm_dis 40322ef5fa9Smycroft 40422ef5fa9Smycroft* 40522ef5fa9Smycroft* If exceptions are enabled, the additional task of setting up WBTEMP 40622ef5fa9Smycroft* is needed so that when the underflow exception handler is entered, 40722ef5fa9Smycroft* the user perceives no difference between what the 040 provides vs. 40822ef5fa9Smycroft* what the FPSP provides. 40922ef5fa9Smycroft* 41022ef5fa9Smycroftxdnrm_ena: 41122ef5fa9Smycroft move.l a0,-(a7) 41222ef5fa9Smycroft 41322ef5fa9Smycroft move.l LOCAL_EX(a0),FP_SCR1(a6) 41422ef5fa9Smycroft move.l LOCAL_HI(a0),FP_SCR1+4(a6) 41522ef5fa9Smycroft move.l LOCAL_LO(a0),FP_SCR1+8(a6) 41622ef5fa9Smycroft 41722ef5fa9Smycroft lea FP_SCR1(a6),a0 41822ef5fa9Smycroft 41922ef5fa9Smycroft bclr.b #sign_bit,LOCAL_EX(a0) 42022ef5fa9Smycroft sne LOCAL_SGN(a0) ;convert to internal ext format 42122ef5fa9Smycroft tst.w LOCAL_EX(a0) ;check if input is denorm 42222ef5fa9Smycroft beq.b xdnrm_dn ;if so, skip nrm_set 42322ef5fa9Smycroft bsr nrm_set ;normalize the result (exponent 42422ef5fa9Smycroft* ;will be negative 42522ef5fa9Smycroftxdnrm_dn: 42622ef5fa9Smycroft bclr.b #sign_bit,LOCAL_EX(a0) ;take off false sign 42722ef5fa9Smycroft bfclr LOCAL_SGN(a0){0:8} ;change back to IEEE ext format 42822ef5fa9Smycroft beq.b xdep 42922ef5fa9Smycroft bset.b #sign_bit,LOCAL_EX(a0) 43022ef5fa9Smycroftxdep: 43122ef5fa9Smycroft bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0 43222ef5fa9Smycroft bset.b #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15 43322ef5fa9Smycroft bclr.b #sticky_bit,STICKY(a6) ;clear sticky bit 43422ef5fa9Smycroft bclr.b #E1,E_BYTE(a6) 43522ef5fa9Smycroft move.l (a7)+,a0 43622ef5fa9Smycroftxdnrm_dis: 43722ef5fa9Smycroft bfextu FPCR_MODE(a6){0:2},d0 ;get round precision 43822ef5fa9Smycroft bne.b not_ext ;if not round extended, store 43922ef5fa9Smycroft* ;IEEE defaults 44022ef5fa9Smycroftis_ext: 44122ef5fa9Smycroft btst.b #sign_bit,LOCAL_EX(a0) 44222ef5fa9Smycroft beq.b xdnrm_store 44322ef5fa9Smycroft 44422ef5fa9Smycroft bset.b #neg_bit,FPSR_CC(a6) ;set N bit in FPSR_CC 44522ef5fa9Smycroft 44622ef5fa9Smycroft bra.b xdnrm_store 44722ef5fa9Smycroft 44822ef5fa9Smycroftnot_ext: 44922ef5fa9Smycroft bclr.b #sign_bit,LOCAL_EX(a0) 45022ef5fa9Smycroft sne LOCAL_SGN(a0) ;convert to internal ext format 45122ef5fa9Smycroft bsr unf_sub ;returns IEEE result pointed by 45222ef5fa9Smycroft* ;a0; sets FPSR_CC accordingly 45322ef5fa9Smycroft bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format 45422ef5fa9Smycroft beq.b xdnrm_store 45522ef5fa9Smycroft bset.b #sign_bit,LOCAL_EX(a0) 45622ef5fa9Smycroftxdnrm_store: 45722ef5fa9Smycroft fmovem.x (a0),fp0 ;store result in fp0 45822ef5fa9Smycroft rts 45922ef5fa9Smycroft 46022ef5fa9Smycroft* 46122ef5fa9Smycroft* This subroutine is used for dyadic operations that use an extended 46222ef5fa9Smycroft* denorm within the kernel. The approach used is to capture the frame, 46322ef5fa9Smycroft* fix/restore. 46422ef5fa9Smycroft* 46522ef5fa9Smycroft xdef t_avoid_unsupp 46622ef5fa9Smycroftt_avoid_unsupp: 46722ef5fa9Smycroft link a2,#-LOCAL_SIZE ;so that a2 fpsp.h negative 46822ef5fa9Smycroft* ;offsets may be used 46922ef5fa9Smycroft fsave -(a7) 47022ef5fa9Smycroft tst.b 1(a7) ;check if idle, exit if so 47122ef5fa9Smycroft beq.w idle_end 47222ef5fa9Smycroft btst.b #E1,E_BYTE(a2) ;check for an E1 exception if 47322ef5fa9Smycroft* ;enabled, there is an unsupp 47422ef5fa9Smycroft beq.w end_avun ;else, exit 47522ef5fa9Smycroft btst.b #7,DTAG(a2) ;check for denorm destination 47622ef5fa9Smycroft beq.b src_den ;else, must be a source denorm 47722ef5fa9Smycroft* 47822ef5fa9Smycroft* handle destination denorm 47922ef5fa9Smycroft* 48022ef5fa9Smycroft lea FPTEMP(a2),a0 48122ef5fa9Smycroft btst.b #sign_bit,LOCAL_EX(a0) 48222ef5fa9Smycroft sne LOCAL_SGN(a0) ;convert to internal ext format 48322ef5fa9Smycroft bclr.b #7,DTAG(a2) ;set DTAG to norm 48422ef5fa9Smycroft bsr nrm_set ;normalize result, exponent 48522ef5fa9Smycroft* ;will become negative 48622ef5fa9Smycroft bclr.b #sign_bit,LOCAL_EX(a0) ;get rid of fake sign 48722ef5fa9Smycroft bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format 48822ef5fa9Smycroft beq.b ck_src_den ;check if source is also denorm 48922ef5fa9Smycroft bset.b #sign_bit,LOCAL_EX(a0) 49022ef5fa9Smycroftck_src_den: 49122ef5fa9Smycroft btst.b #7,STAG(a2) 49222ef5fa9Smycroft beq.b end_avun 49322ef5fa9Smycroftsrc_den: 49422ef5fa9Smycroft lea ETEMP(a2),a0 49522ef5fa9Smycroft btst.b #sign_bit,LOCAL_EX(a0) 49622ef5fa9Smycroft sne LOCAL_SGN(a0) ;convert to internal ext format 49722ef5fa9Smycroft bclr.b #7,STAG(a2) ;set STAG to norm 49822ef5fa9Smycroft bsr nrm_set ;normalize result, exponent 49922ef5fa9Smycroft* ;will become negative 50022ef5fa9Smycroft bclr.b #sign_bit,LOCAL_EX(a0) ;get rid of fake sign 50122ef5fa9Smycroft bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format 50222ef5fa9Smycroft beq.b den_com 50322ef5fa9Smycroft bset.b #sign_bit,LOCAL_EX(a0) 50422ef5fa9Smycroftden_com: 50522ef5fa9Smycroft move.b #$fe,CU_SAVEPC(a2) ;set continue frame 50622ef5fa9Smycroft clr.w NMNEXC(a2) ;clear NMNEXC 50722ef5fa9Smycroft bclr.b #E1,E_BYTE(a2) 50822ef5fa9Smycroft* fmove.l FPSR,FPSR_SHADOW(a2) 50922ef5fa9Smycroft* bset.b #SFLAG,E_BYTE(a2) 51022ef5fa9Smycroft* bset.b #XFLAG,T_BYTE(a2) 51122ef5fa9Smycroftend_avun: 51222ef5fa9Smycroft frestore (a7)+ 51322ef5fa9Smycroft unlk a2 51422ef5fa9Smycroft rts 51522ef5fa9Smycroftidle_end: 51622ef5fa9Smycroft add.l #4,a7 51722ef5fa9Smycroft unlk a2 51822ef5fa9Smycroft rts 51922ef5fa9Smycroft end 520