root/arch/m68k/fpsp040/kernel_ex.S

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

/* [previous][next][first][last][top][bottom][index][help] */