linux/arch/m68k/fpsp040/x_snan.S
<<
>>
Prefs
   1|
   2|       x_snan.sa 3.3 7/1/91
   3|
   4| fpsp_snan --- FPSP handler for signalling NAN exception
   5|
   6| SNAN for float -> integer conversions (integer conversion of
   7| an SNAN) is a non-maskable run-time exception.
   8|
   9| For trap disabled the 040 does the following:
  10| If the dest data format is s, d, or x, then the SNAN bit in the NAN
  11| is set to one and the resulting non-signaling NAN (truncated if
  12| necessary) is transferred to the dest.  If the dest format is b, w,
  13| or l, then garbage is written to the dest (actually the upper 32 bits
  14| of the mantissa are sent to the integer unit).
  15|
  16| For trap enabled the 040 does the following:
  17| If the inst is move_out, then the results are the same as for trap
  18| disabled with the exception posted.  If the instruction is not move_
  19| out, the dest. is not modified, and the exception is posted.
  20|
  21
  22|               Copyright (C) Motorola, Inc. 1990
  23|                       All Rights Reserved
  24|
  25|       For details on the license for this file, please see the
  26|       file, README, in this same directory.
  27
  28X_SNAN: |idnt    2,1 | Motorola 040 Floating Point Software Package
  29
  30        |section        8
  31
  32#include "fpsp.h"
  33
  34        |xref   get_fline
  35        |xref   mem_write
  36        |xref   real_snan
  37        |xref   real_inex
  38        |xref   fpsp_done
  39        |xref   reg_dest
  40
  41        .global fpsp_snan
  42fpsp_snan:
  43        link            %a6,#-LOCAL_SIZE
  44        fsave           -(%a7)
  45        moveml          %d0-%d1/%a0-%a1,USER_DA(%a6)
  46        fmovemx %fp0-%fp3,USER_FP0(%a6)
  47        fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
  48
  49|
  50| Check if trap enabled
  51|
  52        btstb           #snan_bit,FPCR_ENABLE(%a6)
  53        bnes            ena             |If enabled, then branch
  54
  55        bsrl            move_out        |else SNAN disabled
  56|
  57| It is possible to have an inex1 exception with the
  58| snan.  If the inex enable bit is set in the FPCR, and either
  59| inex2 or inex1 occurred, we must clean up and branch to the
  60| real inex handler.
  61|
  62ck_inex:
  63        moveb   FPCR_ENABLE(%a6),%d0
  64        andb    FPSR_EXCEPT(%a6),%d0
  65        andib   #0x3,%d0
  66        beq     end_snan
  67|
  68| Inexact enabled and reported, and we must take an inexact exception.
  69|
  70take_inex:
  71        moveb           #INEX_VEC,EXC_VEC+1(%a6)
  72        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
  73        fmovemx USER_FP0(%a6),%fp0-%fp3
  74        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
  75        frestore        (%a7)+
  76        unlk            %a6
  77        bral            real_inex
  78|
  79| SNAN is enabled.  Check if inst is move_out.
  80| Make any corrections to the 040 output as necessary.
  81|
  82ena:
  83        btstb           #5,CMDREG1B(%a6) |if set, inst is move out
  84        beq             not_out
  85
  86        bsrl            move_out
  87
  88report_snan:
  89        moveb           (%a7),VER_TMP(%a6)
  90        cmpib           #VER_40,(%a7)   |test for orig unimp frame
  91        bnes            ck_rev
  92        moveql          #13,%d0         |need to zero 14 lwords
  93        bras            rep_con
  94ck_rev:
  95        moveql          #11,%d0         |need to zero 12 lwords
  96rep_con:
  97        clrl            (%a7)
  98loop1:
  99        clrl            -(%a7)          |clear and dec a7
 100        dbra            %d0,loop1
 101        moveb           VER_TMP(%a6),(%a7) |format a busy frame
 102        moveb           #BUSY_SIZE-4,1(%a7)
 103        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
 104        orl             #sx_mask,E_BYTE(%a6)
 105        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
 106        fmovemx USER_FP0(%a6),%fp0-%fp3
 107        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
 108        frestore        (%a7)+
 109        unlk            %a6
 110        bral            real_snan
 111|
 112| Exit snan handler by expanding the unimp frame into a busy frame
 113|
 114end_snan:
 115        bclrb           #E1,E_BYTE(%a6)
 116
 117        moveb           (%a7),VER_TMP(%a6)
 118        cmpib           #VER_40,(%a7)   |test for orig unimp frame
 119        bnes            ck_rev2
 120        moveql          #13,%d0         |need to zero 14 lwords
 121        bras            rep_con2
 122ck_rev2:
 123        moveql          #11,%d0         |need to zero 12 lwords
 124rep_con2:
 125        clrl            (%a7)
 126loop2:
 127        clrl            -(%a7)          |clear and dec a7
 128        dbra            %d0,loop2
 129        moveb           VER_TMP(%a6),(%a7) |format a busy frame
 130        moveb           #BUSY_SIZE-4,1(%a7) |write busy size
 131        movel           USER_FPSR(%a6),FPSR_SHADOW(%a6)
 132        orl             #sx_mask,E_BYTE(%a6)
 133        moveml          USER_DA(%a6),%d0-%d1/%a0-%a1
 134        fmovemx USER_FP0(%a6),%fp0-%fp3
 135        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
 136        frestore        (%a7)+
 137        unlk            %a6
 138        bral            fpsp_done
 139
 140|
 141| Move_out
 142|
 143move_out:
 144        movel           EXC_EA(%a6),%a0 |get <ea> from exc frame
 145
 146        bfextu          CMDREG1B(%a6){#3:#3},%d0 |move rx field to d0{2:0}
 147        cmpil           #0,%d0          |check for long
 148        beqs            sto_long        |branch if move_out long
 149
 150        cmpil           #4,%d0          |check for word
 151        beqs            sto_word        |branch if move_out word
 152
 153        cmpil           #6,%d0          |check for byte
 154        beqs            sto_byte        |branch if move_out byte
 155
 156|
 157| Not byte, word or long
 158|
 159        rts
 160|
 161| Get the 32 most significant bits of etemp mantissa
 162|
 163sto_long:
 164        movel           ETEMP_HI(%a6),%d1
 165        movel           #4,%d0          |load byte count
 166|
 167| Set signalling nan bit
 168|
 169        bsetl           #30,%d1
 170|
 171| Store to the users destination address
 172|
 173        tstl            %a0             |check if <ea> is 0
 174        beqs            wrt_dn          |destination is a data register
 175
 176        movel           %d1,-(%a7)      |move the snan onto the stack
 177        movel           %a0,%a1         |load dest addr into a1
 178        movel           %a7,%a0         |load src addr of snan into a0
 179        bsrl            mem_write       |write snan to user memory
 180        movel           (%a7)+,%d1      |clear off stack
 181        rts
 182|
 183| Get the 16 most significant bits of etemp mantissa
 184|
 185sto_word:
 186        movel           ETEMP_HI(%a6),%d1
 187        movel           #2,%d0          |load byte count
 188|
 189| Set signalling nan bit
 190|
 191        bsetl           #30,%d1
 192|
 193| Store to the users destination address
 194|
 195        tstl            %a0             |check if <ea> is 0
 196        beqs            wrt_dn          |destination is a data register
 197
 198        movel           %d1,-(%a7)      |move the snan onto the stack
 199        movel           %a0,%a1         |load dest addr into a1
 200        movel           %a7,%a0         |point to low word
 201        bsrl            mem_write       |write snan to user memory
 202        movel           (%a7)+,%d1      |clear off stack
 203        rts
 204|
 205| Get the 8 most significant bits of etemp mantissa
 206|
 207sto_byte:
 208        movel           ETEMP_HI(%a6),%d1
 209        movel           #1,%d0          |load byte count
 210|
 211| Set signalling nan bit
 212|
 213        bsetl           #30,%d1
 214|
 215| Store to the users destination address
 216|
 217        tstl            %a0             |check if <ea> is 0
 218        beqs            wrt_dn          |destination is a data register
 219        movel           %d1,-(%a7)      |move the snan onto the stack
 220        movel           %a0,%a1         |load dest addr into a1
 221        movel           %a7,%a0         |point to source byte
 222        bsrl            mem_write       |write snan to user memory
 223        movel           (%a7)+,%d1      |clear off stack
 224        rts
 225
 226|
 227|       wrt_dn --- write to a data register
 228|
 229|       We get here with D1 containing the data to write and D0 the
 230|       number of bytes to write: 1=byte,2=word,4=long.
 231|
 232wrt_dn:
 233        movel           %d1,L_SCR1(%a6) |data
 234        movel           %d0,-(%a7)      |size
 235        bsrl            get_fline       |returns fline word in d0
 236        movel           %d0,%d1
 237        andil           #0x7,%d1                |d1 now holds register number
 238        movel           (%sp)+,%d0      |get original size
 239        cmpil           #4,%d0
 240        beqs            wrt_long
 241        cmpil           #2,%d0
 242        bnes            wrt_byte
 243wrt_word:
 244        orl             #0x8,%d1
 245        bral            reg_dest
 246wrt_long:
 247        orl             #0x10,%d1
 248        bral            reg_dest
 249wrt_byte:
 250        bral            reg_dest
 251|
 252| Check if it is a src nan or dst nan
 253|
 254not_out:
 255        movel           DTAG(%a6),%d0
 256        bfextu          %d0{#0:#3},%d0  |isolate dtag in lsbs
 257
 258        cmpib           #3,%d0          |check for nan in destination
 259        bnes            issrc           |destination nan has priority
 260dst_nan:
 261        btstb           #6,FPTEMP_HI(%a6) |check if dest nan is an snan
 262        bnes            issrc           |no, so check source for snan
 263        movew           FPTEMP_EX(%a6),%d0
 264        bras            cont
 265issrc:
 266        movew           ETEMP_EX(%a6),%d0
 267cont:
 268        btstl           #15,%d0         |test for sign of snan
 269        beqs            clr_neg
 270        bsetb           #neg_bit,FPSR_CC(%a6)
 271        bra             report_snan
 272clr_neg:
 273        bclrb           #neg_bit,FPSR_CC(%a6)
 274        bra             report_snan
 275
 276        |end
 277