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