1*4882a593Smuzhiyun| 2*4882a593Smuzhiyun| sint.sa 3.1 12/10/90 3*4882a593Smuzhiyun| 4*4882a593Smuzhiyun| The entry point sINT computes the rounded integer 5*4882a593Smuzhiyun| equivalent of the input argument, sINTRZ computes 6*4882a593Smuzhiyun| the integer rounded to zero of the input argument. 7*4882a593Smuzhiyun| 8*4882a593Smuzhiyun| Entry points sint and sintrz are called from do_func 9*4882a593Smuzhiyun| to emulate the fint and fintrz unimplemented instructions, 10*4882a593Smuzhiyun| respectively. Entry point sintdo is used by bindec. 11*4882a593Smuzhiyun| 12*4882a593Smuzhiyun| Input: (Entry points sint and sintrz) Double-extended 13*4882a593Smuzhiyun| number X in the ETEMP space in the floating-point 14*4882a593Smuzhiyun| save stack. 15*4882a593Smuzhiyun| (Entry point sintdo) Double-extended number X in 16*4882a593Smuzhiyun| location pointed to by the address register a0. 17*4882a593Smuzhiyun| (Entry point sintd) Double-extended denormalized 18*4882a593Smuzhiyun| number X in the ETEMP space in the floating-point 19*4882a593Smuzhiyun| save stack. 20*4882a593Smuzhiyun| 21*4882a593Smuzhiyun| Output: The function returns int(X) or intrz(X) in fp0. 22*4882a593Smuzhiyun| 23*4882a593Smuzhiyun| Modifies: fp0. 24*4882a593Smuzhiyun| 25*4882a593Smuzhiyun| Algorithm: (sint and sintrz) 26*4882a593Smuzhiyun| 27*4882a593Smuzhiyun| 1. If exp(X) >= 63, return X. 28*4882a593Smuzhiyun| If exp(X) < 0, return +/- 0 or +/- 1, according to 29*4882a593Smuzhiyun| the rounding mode. 30*4882a593Smuzhiyun| 31*4882a593Smuzhiyun| 2. (X is in range) set rsc = 63 - exp(X). Unnormalize the 32*4882a593Smuzhiyun| result to the exponent $403e. 33*4882a593Smuzhiyun| 34*4882a593Smuzhiyun| 3. Round the result in the mode given in USER_FPCR. For 35*4882a593Smuzhiyun| sintrz, force round-to-zero mode. 36*4882a593Smuzhiyun| 37*4882a593Smuzhiyun| 4. Normalize the rounded result; store in fp0. 38*4882a593Smuzhiyun| 39*4882a593Smuzhiyun| For the denormalized cases, force the correct result 40*4882a593Smuzhiyun| for the given sign and rounding mode. 41*4882a593Smuzhiyun| 42*4882a593Smuzhiyun| Sign(X) 43*4882a593Smuzhiyun| RMODE + - 44*4882a593Smuzhiyun| ----- -------- 45*4882a593Smuzhiyun| RN +0 -0 46*4882a593Smuzhiyun| RZ +0 -0 47*4882a593Smuzhiyun| RM +0 -1 48*4882a593Smuzhiyun| RP +1 -0 49*4882a593Smuzhiyun| 50*4882a593Smuzhiyun| 51*4882a593Smuzhiyun| Copyright (C) Motorola, Inc. 1990 52*4882a593Smuzhiyun| All Rights Reserved 53*4882a593Smuzhiyun| 54*4882a593Smuzhiyun| For details on the license for this file, please see the 55*4882a593Smuzhiyun| file, README, in this same directory. 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun|SINT idnt 2,1 | Motorola 040 Floating Point Software Package 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun |section 8 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun#include "fpsp.h" 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun |xref dnrm_lp 64*4882a593Smuzhiyun |xref nrm_set 65*4882a593Smuzhiyun |xref round 66*4882a593Smuzhiyun |xref t_inx2 67*4882a593Smuzhiyun |xref ld_pone 68*4882a593Smuzhiyun |xref ld_mone 69*4882a593Smuzhiyun |xref ld_pzero 70*4882a593Smuzhiyun |xref ld_mzero 71*4882a593Smuzhiyun |xref snzrinx 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun| 74*4882a593Smuzhiyun| FINT 75*4882a593Smuzhiyun| 76*4882a593Smuzhiyun .global sint 77*4882a593Smuzhiyunsint: 78*4882a593Smuzhiyun bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 79*4882a593Smuzhiyun| ;implicitly has extend precision 80*4882a593Smuzhiyun| ;in upper word. 81*4882a593Smuzhiyun movel %d1,L_SCR1(%a6) |save mode bits 82*4882a593Smuzhiyun bras sintexc 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun| 85*4882a593Smuzhiyun| FINT with extended denorm inputs. 86*4882a593Smuzhiyun| 87*4882a593Smuzhiyun .global sintd 88*4882a593Smuzhiyunsintd: 89*4882a593Smuzhiyun btstb #5,FPCR_MODE(%a6) 90*4882a593Smuzhiyun beq snzrinx |if round nearest or round zero, +/- 0 91*4882a593Smuzhiyun btstb #4,FPCR_MODE(%a6) 92*4882a593Smuzhiyun beqs rnd_mns 93*4882a593Smuzhiyunrnd_pls: 94*4882a593Smuzhiyun btstb #sign_bit,LOCAL_EX(%a0) 95*4882a593Smuzhiyun bnes sintmz 96*4882a593Smuzhiyun bsr ld_pone |if round plus inf and pos, answer is +1 97*4882a593Smuzhiyun bra t_inx2 98*4882a593Smuzhiyunrnd_mns: 99*4882a593Smuzhiyun btstb #sign_bit,LOCAL_EX(%a0) 100*4882a593Smuzhiyun beqs sintpz 101*4882a593Smuzhiyun bsr ld_mone |if round mns inf and neg, answer is -1 102*4882a593Smuzhiyun bra t_inx2 103*4882a593Smuzhiyunsintpz: 104*4882a593Smuzhiyun bsr ld_pzero 105*4882a593Smuzhiyun bra t_inx2 106*4882a593Smuzhiyunsintmz: 107*4882a593Smuzhiyun bsr ld_mzero 108*4882a593Smuzhiyun bra t_inx2 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun| 111*4882a593Smuzhiyun| FINTRZ 112*4882a593Smuzhiyun| 113*4882a593Smuzhiyun .global sintrz 114*4882a593Smuzhiyunsintrz: 115*4882a593Smuzhiyun movel #1,L_SCR1(%a6) |use rz mode for rounding 116*4882a593Smuzhiyun| ;implicitly has extend precision 117*4882a593Smuzhiyun| ;in upper word. 118*4882a593Smuzhiyun bras sintexc 119*4882a593Smuzhiyun| 120*4882a593Smuzhiyun| SINTDO 121*4882a593Smuzhiyun| 122*4882a593Smuzhiyun| Input: a0 points to an IEEE extended format operand 123*4882a593Smuzhiyun| Output: fp0 has the result 124*4882a593Smuzhiyun| 125*4882a593Smuzhiyun| Exceptions: 126*4882a593Smuzhiyun| 127*4882a593Smuzhiyun| If the subroutine results in an inexact operation, the inx2 and 128*4882a593Smuzhiyun| ainx bits in the USER_FPSR are set. 129*4882a593Smuzhiyun| 130*4882a593Smuzhiyun| 131*4882a593Smuzhiyun .global sintdo 132*4882a593Smuzhiyunsintdo: 133*4882a593Smuzhiyun bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 134*4882a593Smuzhiyun| ;implicitly has ext precision 135*4882a593Smuzhiyun| ;in upper word. 136*4882a593Smuzhiyun movel %d1,L_SCR1(%a6) |save mode bits 137*4882a593Smuzhiyun| 138*4882a593Smuzhiyun| Real work of sint is in sintexc 139*4882a593Smuzhiyun| 140*4882a593Smuzhiyunsintexc: 141*4882a593Smuzhiyun bclrb #sign_bit,LOCAL_EX(%a0) |convert to internal extended 142*4882a593Smuzhiyun| ;format 143*4882a593Smuzhiyun sne LOCAL_SGN(%a0) 144*4882a593Smuzhiyun cmpw #0x403e,LOCAL_EX(%a0) |check if (unbiased) exp > 63 145*4882a593Smuzhiyun bgts out_rnge |branch if exp < 63 146*4882a593Smuzhiyun cmpw #0x3ffd,LOCAL_EX(%a0) |check if (unbiased) exp < 0 147*4882a593Smuzhiyun bgt in_rnge |if 63 >= exp > 0, do calc 148*4882a593Smuzhiyun| 149*4882a593Smuzhiyun| Input is less than zero. Restore sign, and check for directed 150*4882a593Smuzhiyun| rounding modes. L_SCR1 contains the rmode in the lower byte. 151*4882a593Smuzhiyun| 152*4882a593Smuzhiyunun_rnge: 153*4882a593Smuzhiyun btstb #1,L_SCR1+3(%a6) |check for rn and rz 154*4882a593Smuzhiyun beqs un_rnrz 155*4882a593Smuzhiyun tstb LOCAL_SGN(%a0) |check for sign 156*4882a593Smuzhiyun bnes un_rmrp_neg 157*4882a593Smuzhiyun| 158*4882a593Smuzhiyun| Sign is +. If rp, load +1.0, if rm, load +0.0 159*4882a593Smuzhiyun| 160*4882a593Smuzhiyun cmpib #3,L_SCR1+3(%a6) |check for rp 161*4882a593Smuzhiyun beqs un_ldpone |if rp, load +1.0 162*4882a593Smuzhiyun bsr ld_pzero |if rm, load +0.0 163*4882a593Smuzhiyun bra t_inx2 164*4882a593Smuzhiyunun_ldpone: 165*4882a593Smuzhiyun bsr ld_pone 166*4882a593Smuzhiyun bra t_inx2 167*4882a593Smuzhiyun| 168*4882a593Smuzhiyun| Sign is -. If rm, load -1.0, if rp, load -0.0 169*4882a593Smuzhiyun| 170*4882a593Smuzhiyunun_rmrp_neg: 171*4882a593Smuzhiyun cmpib #2,L_SCR1+3(%a6) |check for rm 172*4882a593Smuzhiyun beqs un_ldmone |if rm, load -1.0 173*4882a593Smuzhiyun bsr ld_mzero |if rp, load -0.0 174*4882a593Smuzhiyun bra t_inx2 175*4882a593Smuzhiyunun_ldmone: 176*4882a593Smuzhiyun bsr ld_mone 177*4882a593Smuzhiyun bra t_inx2 178*4882a593Smuzhiyun| 179*4882a593Smuzhiyun| Rmode is rn or rz; return signed zero 180*4882a593Smuzhiyun| 181*4882a593Smuzhiyunun_rnrz: 182*4882a593Smuzhiyun tstb LOCAL_SGN(%a0) |check for sign 183*4882a593Smuzhiyun bnes un_rnrz_neg 184*4882a593Smuzhiyun bsr ld_pzero 185*4882a593Smuzhiyun bra t_inx2 186*4882a593Smuzhiyunun_rnrz_neg: 187*4882a593Smuzhiyun bsr ld_mzero 188*4882a593Smuzhiyun bra t_inx2 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun| 191*4882a593Smuzhiyun| Input is greater than 2^63. All bits are significant. Return 192*4882a593Smuzhiyun| the input. 193*4882a593Smuzhiyun| 194*4882a593Smuzhiyunout_rnge: 195*4882a593Smuzhiyun bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format 196*4882a593Smuzhiyun beqs intps 197*4882a593Smuzhiyun bsetb #sign_bit,LOCAL_EX(%a0) 198*4882a593Smuzhiyunintps: 199*4882a593Smuzhiyun fmovel %fpcr,-(%sp) 200*4882a593Smuzhiyun fmovel #0,%fpcr 201*4882a593Smuzhiyun fmovex LOCAL_EX(%a0),%fp0 |if exp > 63 202*4882a593Smuzhiyun| ;then return X to the user 203*4882a593Smuzhiyun| ;there are no fraction bits 204*4882a593Smuzhiyun fmovel (%sp)+,%fpcr 205*4882a593Smuzhiyun rts 206*4882a593Smuzhiyun 207*4882a593Smuzhiyunin_rnge: 208*4882a593Smuzhiyun| ;shift off fraction bits 209*4882a593Smuzhiyun clrl %d0 |clear d0 - initial g,r,s for 210*4882a593Smuzhiyun| ;dnrm_lp 211*4882a593Smuzhiyun movel #0x403e,%d1 |set threshold for dnrm_lp 212*4882a593Smuzhiyun| ;assumes a0 points to operand 213*4882a593Smuzhiyun bsr dnrm_lp 214*4882a593Smuzhiyun| ;returns unnormalized number 215*4882a593Smuzhiyun| ;pointed by a0 216*4882a593Smuzhiyun| ;output d0 supplies g,r,s 217*4882a593Smuzhiyun| ;used by round 218*4882a593Smuzhiyun movel L_SCR1(%a6),%d1 |use selected rounding mode 219*4882a593Smuzhiyun| 220*4882a593Smuzhiyun| 221*4882a593Smuzhiyun bsr round |round the unnorm based on users 222*4882a593Smuzhiyun| ;input a0 ptr to ext X 223*4882a593Smuzhiyun| ; d0 g,r,s bits 224*4882a593Smuzhiyun| ; d1 PREC/MODE info 225*4882a593Smuzhiyun| ;output a0 ptr to rounded result 226*4882a593Smuzhiyun| ;inexact flag set in USER_FPSR 227*4882a593Smuzhiyun| ;if initial grs set 228*4882a593Smuzhiyun| 229*4882a593Smuzhiyun| normalize the rounded result and store value in fp0 230*4882a593Smuzhiyun| 231*4882a593Smuzhiyun bsr nrm_set |normalize the unnorm 232*4882a593Smuzhiyun| ;Input: a0 points to operand to 233*4882a593Smuzhiyun| ;be normalized 234*4882a593Smuzhiyun| ;Output: a0 points to normalized 235*4882a593Smuzhiyun| ;result 236*4882a593Smuzhiyun bfclr LOCAL_SGN(%a0){#0:#8} 237*4882a593Smuzhiyun beqs nrmrndp 238*4882a593Smuzhiyun bsetb #sign_bit,LOCAL_EX(%a0) |return to IEEE extended format 239*4882a593Smuzhiyunnrmrndp: 240*4882a593Smuzhiyun fmovel %fpcr,-(%sp) 241*4882a593Smuzhiyun fmovel #0,%fpcr 242*4882a593Smuzhiyun fmovex LOCAL_EX(%a0),%fp0 |move result to fp0 243*4882a593Smuzhiyun fmovel (%sp)+,%fpcr 244*4882a593Smuzhiyun rts 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun |end 247