1* $NetBSD: x_unfl.sa,v 1.4 2001/09/16 16:34:32 wiz Exp $ 2 3* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 4* M68000 Hi-Performance Microprocessor Division 5* M68040 Software Package 6* 7* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 8* All rights reserved. 9* 10* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 11* To the maximum extent permitted by applicable law, 12* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 13* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 14* PARTICULAR PURPOSE and any warranty against infringement with 15* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 16* and any accompanying written materials. 17* 18* To the maximum extent permitted by applicable law, 19* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 20* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 21* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 22* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 23* SOFTWARE. Motorola assumes no responsibility for the maintenance 24* and support of the SOFTWARE. 25* 26* You are hereby granted a copyright license to use, modify, and 27* distribute the SOFTWARE so long as this entire notice is retained 28* without alteration in any modified and/or redistributed versions, 29* and that such modified versions are clearly identified as such. 30* No licenses are granted by implication, estoppel or otherwise 31* under any patents or trademarks of Motorola, Inc. 32 33* 34* x_unfl.sa 3.4 7/1/91 35* 36* fpsp_unfl --- FPSP handler for underflow exception 37* 38* Trap disabled results 39* For 881/2 compatibility, sw must denormalize the intermediate 40* result, then store the result. Denormalization is accomplished 41* by taking the intermediate result (which is always normalized) and 42* shifting the mantissa right while incrementing the exponent until 43* it is equal to the denormalized exponent for the destination 44* format. After denormalizatoin, the result is rounded to the 45* destination format. 46* 47* Trap enabled results 48* All trap disabled code applies. In addition the exceptional 49* operand needs to made available to the user with a bias of $6000 50* added to the exponent. 51* 52 53X_UNFL IDNT 2,1 Motorola 040 Floating Point Software Package 54 55 section 8 56 57 include fpsp.h 58 59 xref denorm 60 xref round 61 xref store 62 xref g_rndpr 63 xref g_opcls 64 xref g_dfmtou 65 xref real_unfl 66 xref real_inex 67 xref fpsp_done 68 xref b1238_fix 69 70 xdef fpsp_unfl 71fpsp_unfl: 72 link a6,#-LOCAL_SIZE 73 fsave -(a7) 74 movem.l d0-d1/a0-a1,USER_DA(a6) 75 fmovem.x fp0-fp3,USER_FP0(a6) 76 fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6) 77 78* 79 bsr.l unf_res ;denormalize, round & store interm op 80* 81* If underflow exceptions are not enabled, check for inexact 82* exception 83* 84 btst.b #unfl_bit,FPCR_ENABLE(a6) 85 beq.b ck_inex 86 87 btst.b #E3,E_BYTE(a6) 88 beq.b no_e3_1 89* 90* Clear dirty bit on dest resister in the frame before branching 91* to b1238_fix. 92* 93 bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no 94 bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit 95 bsr.l b1238_fix ;test for bug1238 case 96 move.l USER_FPSR(a6),FPSR_SHADOW(a6) 97 or.l #sx_mask,E_BYTE(a6) 98no_e3_1: 99 movem.l USER_DA(a6),d0-d1/a0-a1 100 fmovem.x USER_FP0(a6),fp0-fp3 101 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 102 frestore (a7)+ 103 unlk a6 104 bra.l real_unfl 105* 106* It is possible to have either inex2 or inex1 exceptions with the 107* unfl. If the inex enable bit is set in the FPCR, and either 108* inex2 or inex1 occurred, we must clean up and branch to the 109* real inex handler. 110* 111ck_inex: 112 move.b FPCR_ENABLE(a6),d0 113 and.b FPSR_EXCEPT(a6),d0 114 andi.b #$3,d0 115 beq.b unfl_done 116 117* 118* Inexact enabled and reported, and we must take an inexact exception 119* 120take_inex: 121 btst.b #E3,E_BYTE(a6) 122 beq.b no_e3_2 123* 124* Clear dirty bit on dest resister in the frame before branching 125* to b1238_fix. 126* 127 bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no 128 bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit 129 bsr.l b1238_fix ;test for bug1238 case 130 move.l USER_FPSR(a6),FPSR_SHADOW(a6) 131 or.l #sx_mask,E_BYTE(a6) 132no_e3_2: 133 move.b #INEX_VEC,EXC_VEC+1(a6) 134 movem.l USER_DA(a6),d0-d1/a0-a1 135 fmovem.x USER_FP0(a6),fp0-fp3 136 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 137 frestore (a7)+ 138 unlk a6 139 bra.l real_inex 140 141unfl_done: 142 bclr.b #E3,E_BYTE(a6) 143 beq.b e1_set ;if set then branch 144* 145* Clear dirty bit on dest resister in the frame before branching 146* to b1238_fix. 147* 148 bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no 149 bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit 150 bsr.l b1238_fix ;test for bug1238 case 151 move.l USER_FPSR(a6),FPSR_SHADOW(a6) 152 or.l #sx_mask,E_BYTE(a6) 153 movem.l USER_DA(a6),d0-d1/a0-a1 154 fmovem.x USER_FP0(a6),fp0-fp3 155 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 156 frestore (a7)+ 157 unlk a6 158 bra.l fpsp_done 159e1_set: 160 movem.l USER_DA(a6),d0-d1/a0-a1 161 fmovem.x USER_FP0(a6),fp0-fp3 162 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar 163 unlk a6 164 bra.l fpsp_done 165* 166* unf_res --- underflow result calculation 167* 168unf_res: 169 bsr.l g_rndpr ;returns RND_PREC in d0 0=ext, 170* ;1=sgl, 2=dbl 171* ;we need the RND_PREC in the 172* ;upper word for round 173 clr.w -(a7) 174 move.w d0,-(a7) ;copy RND_PREC to stack 175* 176* 177* If the exception bit set is E3, the exceptional operand from the 178* fpu is in WBTEMP; else it is in FPTEMP. 179* 180 btst.b #E3,E_BYTE(a6) 181 beq.b unf_E1 182unf_E3: 183 lea WBTEMP(a6),a0 ;a0 now points to operand 184* 185* Test for fsgldiv and fsglmul. If the inst was one of these, then 186* force the precision to extended for the denorm routine. Use 187* the user's precision for the round routine. 188* 189 move.w CMDREG3B(a6),d1 ;check for fsgldiv or fsglmul 190 andi.w #$7f,d1 191 cmpi.w #$30,d1 ;check for sgldiv 192 beq.b unf_sgl 193 cmpi.w #$33,d1 ;check for sglmul 194 bne.b unf_cont ;if not, use fpcr prec in round 195unf_sgl: 196 clr.l d0 197 move.w #$1,(a7) ;override g_rndpr precision 198* ;force single 199 bra.b unf_cont 200unf_E1: 201 lea FPTEMP(a6),a0 ;a0 now points to operand 202unf_cont: 203 bclr.b #sign_bit,LOCAL_EX(a0) ;clear sign bit 204 sne LOCAL_SGN(a0) ;store sign 205 206 bsr.l denorm ;returns denorm, a0 points to it 207* 208* WARNING: 209* ;d0 has guard,round sticky bit 210* ;make sure that it is not corrupted 211* ;before it reaches the round subroutine 212* ;also ensure that a0 isn't corrupted 213 214* 215* Set up d1 for round subroutine d1 contains the PREC/MODE 216* information respectively on upper/lower register halves. 217* 218 bfextu FPCR_MODE(a6){2:2},d1 ;get mode from FPCR 219* ;mode in lower d1 220 add.l (a7)+,d1 ;merge PREC/MODE 221* 222* WARNING: a0 and d0 are assumed to be intact between the denorm and 223* round subroutines. All code between these two subroutines 224* must not corrupt a0 and d0. 225* 226* 227* Perform Round 228* Input: a0 points to input operand 229* d0{31:29} has guard, round, sticky 230* d1{01:00} has rounding mode 231* d1{17:16} has rounding precision 232* Output: a0 points to rounded operand 233* 234 235 bsr.l round ;returns rounded denorm at (a0) 236* 237* Differentiate between store to memory vs. store to register 238* 239unf_store: 240 bsr.l g_opcls ;returns opclass in d0{2:0} 241 cmpi.b #$3,d0 242 bne.b not_opc011 243* 244* At this point, a store to memory is pending 245* 246opc011: 247 bsr.l g_dfmtou 248 tst.b d0 249 beq.b ext_opc011 ;If extended, do not subtract 250* ;If destination format is sgl/dbl, 251 tst.b LOCAL_HI(a0) ;If rounded result is normal,don't 252* ;subtract 253 bmi.b ext_opc011 254 subq.w #1,LOCAL_EX(a0) ;account for denorm bias vs. 255* ;normalized bias 256* ; normalized denormalized 257* ;single $7f $7e 258* ;double $3ff $3fe 259* 260ext_opc011: 261 bsr.l store ;stores to memory 262 bra.b unf_done ;finish up 263 264* 265* At this point, a store to a float register is pending 266* 267not_opc011: 268 bsr.l store ;stores to float register 269* ;a0 is not corrupted on a store to a 270* ;float register. 271* 272* Set the condition codes according to result 273* 274 tst.l LOCAL_HI(a0) ;check upper mantissa 275 bne.b ck_sgn 276 tst.l LOCAL_LO(a0) ;check lower mantissa 277 bne.b ck_sgn 278 bset.b #z_bit,FPSR_CC(a6) ;set condition codes if zero 279ck_sgn: 280 btst.b #sign_bit,LOCAL_EX(a0) ;check the sign bit 281 beq.b unf_done 282 bset.b #neg_bit,FPSR_CC(a6) 283 284* 285* Finish. 286* 287unf_done: 288 btst.b #inex2_bit,FPSR_EXCEPT(a6) 289 beq.b no_aunfl 290 bset.b #aunfl_bit,FPSR_AEXCEPT(a6) 291no_aunfl: 292 rts 293 294 end 295