Back to home page

LXR

 
 

    


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

0001 #include "fpsp-namespace.h"
0002 //
0003 //
0004 //  sint.sa 3.1 12/10/90
0005 //
0006 //  The entry point sINT computes the rounded integer
0007 //  equivalent of the input argument, sINTRZ computes
0008 //  the integer rounded to zero of the input argument.
0009 //
0010 //  Entry points sint and sintrz are called from do_func
0011 //  to emulate the fint and fintrz unimplemented instructions,
0012 //  respectively.  Entry point sintdo is used by bindec.
0013 //
0014 //  Input: (Entry points sint and sintrz) Double-extended
0015 //      number X in the ETEMP space in the floating-point
0016 //      save stack.
0017 //         (Entry point sintdo) Double-extended number X in
0018 //      location pointed to by the address register a0.
0019 //         (Entry point sintd) Double-extended denormalized
0020 //      number X in the ETEMP space in the floating-point
0021 //      save stack.
0022 //
0023 //  Output: The function returns int(X) or intrz(X) in fp0.
0024 //
0025 //  Modifies: fp0.
0026 //
0027 //  Algorithm: (sint and sintrz)
0028 //
0029 //  1. If exp(X) >= 63, return X.
0030 //     If exp(X) < 0, return +/- 0 or +/- 1, according to
0031 //     the rounding mode.
0032 //
0033 //  2. (X is in range) set rsc = 63 - exp(X). Unnormalize the
0034 //     result to the exponent $403e.
0035 //
0036 //  3. Round the result in the mode given in USER_FPCR. For
0037 //     sintrz, force round-to-zero mode.
0038 //
0039 //  4. Normalize the rounded result; store in fp0.
0040 //
0041 //  For the denormalized cases, force the correct result
0042 //  for the given sign and rounding mode.
0043 //
0044 //              Sign(X)
0045 //      RMODE   +    -
0046 //      -----  --------
0047 //       RN    +0   -0
0048 //       RZ    +0   -0
0049 //       RM    +0   -1
0050 //       RP    +1   -0
0051 //
0052 //
0053 //      Copyright (C) Motorola, Inc. 1990
0054 //          All Rights Reserved
0055 //
0056 //  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
0057 //  The copyright notice above does not evidence any
0058 //  actual or intended publication of such source code.
0059 
0060 //SINT    idnt    2,1 | Motorola 040 Floating Point Software Package
0061 
0062     |section    8
0063 
0064 #include "fpsp.defs"
0065 
0066     |xref   dnrm_lp
0067     |xref   nrm_set
0068     |xref   round
0069     |xref   t_inx2
0070     |xref   ld_pone
0071     |xref   ld_mone
0072     |xref   ld_pzero
0073     |xref   ld_mzero
0074     |xref   snzrinx
0075 
0076 //
0077 //  FINT
0078 //
0079     .global sint
0080 sint:
0081     bfextu  FPCR_MODE(%a6){#2:#2},%d1   //use user's mode for rounding
0082 //                  ;implicitly has extend precision
0083 //                  ;in upper word.
0084     movel   %d1,L_SCR1(%a6)     //save mode bits
0085     bras    sintexc
0086 
0087 //
0088 //  FINT with extended denorm inputs.
0089 //
0090     .global sintd
0091 sintd:
0092     btstb   #5,FPCR_MODE(%a6)
0093     beq snzrinx     //if round nearest or round zero, +/- 0
0094     btstb   #4,FPCR_MODE(%a6)
0095     beqs    rnd_mns
0096 rnd_pls:
0097     btstb   #sign_bit,LOCAL_EX(%a0)
0098     bnes    sintmz
0099     bsr ld_pone     //if round plus inf and pos, answer is +1
0100     bra t_inx2
0101 rnd_mns:
0102     btstb   #sign_bit,LOCAL_EX(%a0)
0103     beqs    sintpz
0104     bsr ld_mone     //if round mns inf and neg, answer is -1
0105     bra t_inx2
0106 sintpz:
0107     bsr ld_pzero
0108     bra t_inx2
0109 sintmz:
0110     bsr ld_mzero
0111     bra t_inx2
0112 
0113 //
0114 //  FINTRZ
0115 //
0116     .global sintrz
0117 sintrz:
0118     movel   #1,L_SCR1(%a6)      //use rz mode for rounding
0119 //                  ;implicitly has extend precision
0120 //                  ;in upper word.
0121     bras    sintexc
0122 //
0123 //  SINTDO
0124 //
0125 //  Input:  a0 points to an IEEE extended format operand
0126 //  Output: fp0 has the result
0127 //
0128 // Exceptions:
0129 //
0130 // If the subroutine results in an inexact operation, the inx2 and
0131 // ainx bits in the USER_FPSR are set.
0132 //
0133 //
0134     .global sintdo
0135 sintdo:
0136     bfextu  FPCR_MODE(%a6){#2:#2},%d1   //use user's mode for rounding
0137 //                  ;implicitly has ext precision
0138 //                  ;in upper word.
0139     movel   %d1,L_SCR1(%a6)     //save mode bits
0140 //
0141 // Real work of sint is in sintexc
0142 //
0143 sintexc:
0144     bclrb   #sign_bit,LOCAL_EX(%a0) //convert to internal extended
0145 //                  ;format
0146     sne LOCAL_SGN(%a0)
0147     cmpw    #0x403e,LOCAL_EX(%a0)   //check if (unbiased) exp > 63
0148     bgts    out_rnge            //branch if exp < 63
0149     cmpw    #0x3ffd,LOCAL_EX(%a0)   //check if (unbiased) exp < 0
0150     bgt in_rnge         //if 63 >= exp > 0, do calc
0151 //
0152 // Input is less than zero.  Restore sign, and check for directed
0153 // rounding modes.  L_SCR1 contains the rmode in the lower byte.
0154 //
0155 un_rnge:
0156     btstb   #1,L_SCR1+3(%a6)        //check for rn and rz
0157     beqs    un_rnrz
0158     tstb    LOCAL_SGN(%a0)      //check for sign
0159     bnes    un_rmrp_neg
0160 //
0161 // Sign is +.  If rp, load +1.0, if rm, load +0.0
0162 //
0163     cmpib   #3,L_SCR1+3(%a6)        //check for rp
0164     beqs    un_ldpone       //if rp, load +1.0
0165     bsr ld_pzero        //if rm, load +0.0
0166     bra t_inx2
0167 un_ldpone:
0168     bsr ld_pone
0169     bra t_inx2
0170 //
0171 // Sign is -.  If rm, load -1.0, if rp, load -0.0
0172 //
0173 un_rmrp_neg:
0174     cmpib   #2,L_SCR1+3(%a6)        //check for rm
0175     beqs    un_ldmone       //if rm, load -1.0
0176     bsr ld_mzero        //if rp, load -0.0
0177     bra t_inx2
0178 un_ldmone:
0179     bsr ld_mone
0180     bra t_inx2
0181 //
0182 // Rmode is rn or rz; return signed zero
0183 //
0184 un_rnrz:
0185     tstb    LOCAL_SGN(%a0)      //check for sign
0186     bnes    un_rnrz_neg
0187     bsr ld_pzero
0188     bra t_inx2
0189 un_rnrz_neg:
0190     bsr ld_mzero
0191     bra t_inx2
0192 
0193 //
0194 // Input is greater than 2^63.  All bits are significant.  Return
0195 // the input.
0196 //
0197 out_rnge:
0198     bfclr   LOCAL_SGN(%a0){#0:#8}   //change back to IEEE ext format
0199     beqs    intps
0200     bsetb   #sign_bit,LOCAL_EX(%a0)
0201 intps:
0202     fmovel  %fpcr,-(%sp)
0203     fmovel  #0,%fpcr
0204     fmovex LOCAL_EX(%a0),%fp0   //if exp > 63
0205 //                  ;then return X to the user
0206 //                  ;there are no fraction bits
0207     fmovel  (%sp)+,%fpcr
0208     rts
0209 
0210 in_rnge:
0211 //                  ;shift off fraction bits
0212     clrl    %d0         //clear d0 - initial g,r,s for
0213 //                  ;dnrm_lp
0214     movel   #0x403e,%d1     //set threshold for dnrm_lp
0215 //                  ;assumes a0 points to operand
0216     bsr dnrm_lp
0217 //                  ;returns unnormalized number
0218 //                  ;pointed by a0
0219 //                  ;output d0 supplies g,r,s
0220 //                  ;used by round
0221     movel   L_SCR1(%a6),%d1     //use selected rounding mode
0222 //
0223 //
0224     bsr round           //round the unnorm based on users
0225 //                  ;input  a0 ptr to ext X
0226 //                  ;   d0 g,r,s bits
0227 //                  ;   d1 PREC/MODE info
0228 //                  ;output a0 ptr to rounded result
0229 //                  ;inexact flag set in USER_FPSR
0230 //                  ;if initial grs set
0231 //
0232 // normalize the rounded result and store value in fp0
0233 //
0234     bsr nrm_set         //normalize the unnorm
0235 //                  ;Input: a0 points to operand to
0236 //                  ;be normalized
0237 //                  ;Output: a0 points to normalized
0238 //                  ;result
0239     bfclr   LOCAL_SGN(%a0){#0:#8}
0240     beqs    nrmrndp
0241     bsetb   #sign_bit,LOCAL_EX(%a0) //return to IEEE extended format
0242 nrmrndp:
0243     fmovel  %fpcr,-(%sp)
0244     fmovel  #0,%fpcr
0245     fmovex LOCAL_EX(%a0),%fp0   //move result to fp0
0246     fmovel  (%sp)+,%fpcr
0247     rts
0248 
0249     |end