Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:49

0001 #include "fpsp-namespace.h"
0002 //
0003 //
0004 //  x_snan.sa 3.3 7/1/91
0005 //
0006 // fpsp_snan --- FPSP handler for signalling NAN exception
0007 //
0008 // SNAN for float -> integer conversions (integer conversion of
0009 // an SNAN) is a non-maskable run-time exception.
0010 //
0011 // For trap disabled the 040 does the following:
0012 // If the dest data format is s, d, or x, then the SNAN bit in the NAN
0013 // is set to one and the resulting non-signaling NAN (truncated if
0014 // necessary) is transferred to the dest.  If the dest format is b, w,
0015 // or l, then garbage is written to the dest (actually the upper 32 bits
0016 // of the mantissa are sent to the integer unit).
0017 //
0018 // For trap enabled the 040 does the following:
0019 // If the inst is move_out, then the results are the same as for trap
0020 // disabled with the exception posted.  If the instruction is not move_
0021 // out, the dest. is not modified, and the exception is posted.
0022 //
0023 
0024 //      Copyright (C) Motorola, Inc. 1990
0025 //          All Rights Reserved
0026 //
0027 //  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
0028 //  The copyright notice above does not evidence any
0029 //  actual or intended publication of such source code.
0030 
0031 X_SNAN: //idnt    2,1 | Motorola 040 Floating Point Software Package
0032 
0033     |section    8
0034 
0035 #include "fpsp.defs"
0036 
0037     |xref   get_fline
0038     |xref   mem_write
0039     |xref   real_snan
0040     |xref   real_inex
0041     |xref   fpsp_done
0042     |xref   reg_dest
0043 
0044     .global fpsp_snan
0045 fpsp_snan:
0046     link        %a6,#-LOCAL_SIZE
0047     fsave       -(%a7)
0048     moveml      %d0-%d1/%a0-%a1,USER_DA(%a6)
0049     fmovemx %fp0-%fp3,USER_FP0(%a6)
0050     fmoveml %fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
0051 
0052 //
0053 // Check if trap enabled
0054 //
0055     btstb       #snan_bit,FPCR_ENABLE(%a6)
0056     bnes        ena     //If enabled, then branch
0057 
0058     bsrl        move_out    //else SNAN disabled
0059 //
0060 // It is possible to have an inex1 exception with the
0061 // snan.  If the inex enable bit is set in the FPCR, and either
0062 // inex2 or inex1 occurred, we must clean up and branch to the
0063 // real inex handler.
0064 //
0065 ck_inex:
0066     moveb   FPCR_ENABLE(%a6),%d0
0067     andb    FPSR_EXCEPT(%a6),%d0
0068     andib   #0x3,%d0
0069     beq end_snan
0070 //
0071 // Inexact enabled and reported, and we must take an inexact exception.
0072 //
0073 take_inex:
0074     moveb       #INEX_VEC,EXC_VEC+1(%a6)
0075     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0076     fmovemx USER_FP0(%a6),%fp0-%fp3
0077     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0078     frestore    (%a7)+
0079     unlk        %a6
0080     bral        real_inex
0081 //
0082 // SNAN is enabled.  Check if inst is move_out.
0083 // Make any corrections to the 040 output as necessary.
0084 //
0085 ena:
0086     btstb       #5,CMDREG1B(%a6) //if set, inst is move out
0087     beq     not_out
0088 
0089     bsrl        move_out
0090 
0091 report_snan:
0092     moveb       (%a7),VER_TMP(%a6)
0093     cmpib       #VER_40,(%a7)   //test for orig unimp frame
0094     bnes        ck_rev
0095     moveql      #13,%d0     //need to zero 14 lwords
0096     bras        rep_con
0097 ck_rev:
0098     moveql      #11,%d0     //need to zero 12 lwords
0099 rep_con:
0100     clrl        (%a7)
0101 loop1:
0102     clrl        -(%a7)      //clear and dec a7
0103     dbra        %d0,loop1
0104     moveb       VER_TMP(%a6),(%a7) //format a busy frame
0105     moveb       #BUSY_SIZE-4,1(%a7)
0106     movel       USER_FPSR(%a6),FPSR_SHADOW(%a6)
0107     orl     #sx_mask,E_BYTE(%a6)
0108     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0109     fmovemx USER_FP0(%a6),%fp0-%fp3
0110     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0111     frestore    (%a7)+
0112     unlk        %a6
0113     bral        real_snan
0114 //
0115 // Exit snan handler by expanding the unimp frame into a busy frame
0116 //
0117 end_snan:
0118     bclrb       #E1,E_BYTE(%a6)
0119 
0120     moveb       (%a7),VER_TMP(%a6)
0121     cmpib       #VER_40,(%a7)   //test for orig unimp frame
0122     bnes        ck_rev2
0123     moveql      #13,%d0     //need to zero 14 lwords
0124     bras        rep_con2
0125 ck_rev2:
0126     moveql      #11,%d0     //need to zero 12 lwords
0127 rep_con2:
0128     clrl        (%a7)
0129 loop2:
0130     clrl        -(%a7)      //clear and dec a7
0131     dbra        %d0,loop2
0132     moveb       VER_TMP(%a6),(%a7) //format a busy frame
0133     moveb       #BUSY_SIZE-4,1(%a7) //write busy size
0134     movel       USER_FPSR(%a6),FPSR_SHADOW(%a6)
0135     orl     #sx_mask,E_BYTE(%a6)
0136     moveml      USER_DA(%a6),%d0-%d1/%a0-%a1
0137     fmovemx USER_FP0(%a6),%fp0-%fp3
0138     fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
0139     frestore    (%a7)+
0140     unlk        %a6
0141     bral        fpsp_done
0142 
0143 //
0144 // Move_out
0145 //
0146 move_out:
0147     movel       EXC_EA(%a6),%a0 //get <ea> from exc frame
0148 
0149     bfextu      CMDREG1B(%a6){#3:#3},%d0 //move rx field to d0{2:0}
0150     cmpil       #0,%d0      //check for long
0151     beqs        sto_long    //branch if move_out long
0152 
0153     cmpil       #4,%d0      //check for word
0154     beqs        sto_word    //branch if move_out word
0155 
0156     cmpil       #6,%d0      //check for byte
0157     beqs        sto_byte    //branch if move_out byte
0158 
0159 //
0160 // Not byte, word or long
0161 //
0162     rts
0163 //
0164 // Get the 32 most significant bits of etemp mantissa
0165 //
0166 sto_long:
0167     movel       ETEMP_HI(%a6),%d1
0168     movel       #4,%d0      //load byte count
0169 //
0170 // Set signalling nan bit
0171 //
0172     bsetl       #30,%d1
0173 //
0174 // Store to the users destination address
0175 //
0176     tstl        %a0     //check if <ea> is 0
0177     beqs        wrt_dn      //destination is a data register
0178 
0179     movel       %d1,-(%a7)  //move the snan onto the stack
0180     movel       %a0,%a1     //load dest addr into a1
0181     movel       %a7,%a0     //load src addr of snan into a0
0182     bsrl        mem_write   //write snan to user memory
0183     movel       (%a7)+,%d1  //clear off stack
0184     rts
0185 //
0186 // Get the 16 most significant bits of etemp mantissa
0187 //
0188 sto_word:
0189     movel       ETEMP_HI(%a6),%d1
0190     movel       #2,%d0      //load byte count
0191 //
0192 // Set signalling nan bit
0193 //
0194     bsetl       #30,%d1
0195 //
0196 // Store to the users destination address
0197 //
0198     tstl        %a0     //check if <ea> is 0
0199     beqs        wrt_dn      //destination is a data register
0200 
0201     movel       %d1,-(%a7)  //move the snan onto the stack
0202     movel       %a0,%a1     //load dest addr into a1
0203     movel       %a7,%a0     //point to low word
0204     bsrl        mem_write   //write snan to user memory
0205     movel       (%a7)+,%d1  //clear off stack
0206     rts
0207 //
0208 // Get the 8 most significant bits of etemp mantissa
0209 //
0210 sto_byte:
0211     movel       ETEMP_HI(%a6),%d1
0212     movel       #1,%d0      //load byte count
0213 //
0214 // Set signalling nan bit
0215 //
0216     bsetl       #30,%d1
0217 //
0218 // Store to the users destination address
0219 //
0220     tstl        %a0     //check if <ea> is 0
0221     beqs        wrt_dn      //destination is a data register
0222     movel       %d1,-(%a7)  //move the snan onto the stack
0223     movel       %a0,%a1     //load dest addr into a1
0224     movel       %a7,%a0     //point to source byte
0225     bsrl        mem_write   //write snan to user memory
0226     movel       (%a7)+,%d1  //clear off stack
0227     rts
0228 
0229 //
0230 //  wrt_dn --- write to a data register
0231 //
0232 //  We get here with D1 containing the data to write and D0 the
0233 //  number of bytes to write: 1=byte,2=word,4=long.
0234 //
0235 wrt_dn:
0236     movel       %d1,L_SCR1(%a6) //data
0237     movel       %d0,-(%a7)  //size
0238     bsrl        get_fline   //returns fline word in d0
0239     movel       %d0,%d1
0240     andil       #0x7,%d1        //d1 now holds register number
0241     movel       (%sp)+,%d0  //get original size
0242     cmpil       #4,%d0
0243     beqs        wrt_long
0244     cmpil       #2,%d0
0245     bnes        wrt_byte
0246 wrt_word:
0247     orl     #0x8,%d1
0248     bral        reg_dest
0249 wrt_long:
0250     orl     #0x10,%d1
0251     bral        reg_dest
0252 wrt_byte:
0253     bral        reg_dest
0254 //
0255 // Check if it is a src nan or dst nan
0256 //
0257 not_out:
0258     movel       DTAG(%a6),%d0
0259     bfextu      %d0{#0:#3},%d0  //isolate dtag in lsbs
0260 
0261     cmpib       #3,%d0      //check for nan in destination
0262     bnes        issrc       //destination nan has priority
0263 dst_nan:
0264     btstb       #6,FPTEMP_HI(%a6) //check if dest nan is an snan
0265     bnes        issrc       //no, so check source for snan
0266     movew       FPTEMP_EX(%a6),%d0
0267     bras        cont
0268 issrc:
0269     movew       ETEMP_EX(%a6),%d0
0270 cont:
0271     btstl       #15,%d0     //test for sign of snan
0272     beqs        clr_neg
0273     bsetb       #neg_bit,FPSR_CC(%a6)
0274     bra     report_snan
0275 clr_neg:
0276     bclrb       #neg_bit,FPSR_CC(%a6)
0277     bra     report_snan
0278 
0279     |end