11da177e4SLinus Torvalds| 21da177e4SLinus Torvalds| sint.sa 3.1 12/10/90 31da177e4SLinus Torvalds| 41da177e4SLinus Torvalds| The entry point sINT computes the rounded integer 51da177e4SLinus Torvalds| equivalent of the input argument, sINTRZ computes 61da177e4SLinus Torvalds| the integer rounded to zero of the input argument. 71da177e4SLinus Torvalds| 81da177e4SLinus Torvalds| Entry points sint and sintrz are called from do_func 91da177e4SLinus Torvalds| to emulate the fint and fintrz unimplemented instructions, 101da177e4SLinus Torvalds| respectively. Entry point sintdo is used by bindec. 111da177e4SLinus Torvalds| 121da177e4SLinus Torvalds| Input: (Entry points sint and sintrz) Double-extended 131da177e4SLinus Torvalds| number X in the ETEMP space in the floating-point 141da177e4SLinus Torvalds| save stack. 151da177e4SLinus Torvalds| (Entry point sintdo) Double-extended number X in 161da177e4SLinus Torvalds| location pointed to by the address register a0. 171da177e4SLinus Torvalds| (Entry point sintd) Double-extended denormalized 181da177e4SLinus Torvalds| number X in the ETEMP space in the floating-point 191da177e4SLinus Torvalds| save stack. 201da177e4SLinus Torvalds| 211da177e4SLinus Torvalds| Output: The function returns int(X) or intrz(X) in fp0. 221da177e4SLinus Torvalds| 231da177e4SLinus Torvalds| Modifies: fp0. 241da177e4SLinus Torvalds| 251da177e4SLinus Torvalds| Algorithm: (sint and sintrz) 261da177e4SLinus Torvalds| 271da177e4SLinus Torvalds| 1. If exp(X) >= 63, return X. 281da177e4SLinus Torvalds| If exp(X) < 0, return +/- 0 or +/- 1, according to 291da177e4SLinus Torvalds| the rounding mode. 301da177e4SLinus Torvalds| 311da177e4SLinus Torvalds| 2. (X is in range) set rsc = 63 - exp(X). Unnormalize the 321da177e4SLinus Torvalds| result to the exponent $403e. 331da177e4SLinus Torvalds| 341da177e4SLinus Torvalds| 3. Round the result in the mode given in USER_FPCR. For 351da177e4SLinus Torvalds| sintrz, force round-to-zero mode. 361da177e4SLinus Torvalds| 371da177e4SLinus Torvalds| 4. Normalize the rounded result; store in fp0. 381da177e4SLinus Torvalds| 391da177e4SLinus Torvalds| For the denormalized cases, force the correct result 401da177e4SLinus Torvalds| for the given sign and rounding mode. 411da177e4SLinus Torvalds| 421da177e4SLinus Torvalds| Sign(X) 431da177e4SLinus Torvalds| RMODE + - 441da177e4SLinus Torvalds| ----- -------- 451da177e4SLinus Torvalds| RN +0 -0 461da177e4SLinus Torvalds| RZ +0 -0 471da177e4SLinus Torvalds| RM +0 -1 481da177e4SLinus Torvalds| RP +1 -0 491da177e4SLinus Torvalds| 501da177e4SLinus Torvalds| 511da177e4SLinus Torvalds| Copyright (C) Motorola, Inc. 1990 521da177e4SLinus Torvalds| All Rights Reserved 531da177e4SLinus Torvalds| 54*e00d82d0SMatt Waddel| For details on the license for this file, please see the 55*e00d82d0SMatt Waddel| file, README, in this same directory. 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds|SINT idnt 2,1 | Motorola 040 Floating Point Software Package 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds |section 8 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds#include "fpsp.h" 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds |xref dnrm_lp 641da177e4SLinus Torvalds |xref nrm_set 651da177e4SLinus Torvalds |xref round 661da177e4SLinus Torvalds |xref t_inx2 671da177e4SLinus Torvalds |xref ld_pone 681da177e4SLinus Torvalds |xref ld_mone 691da177e4SLinus Torvalds |xref ld_pzero 701da177e4SLinus Torvalds |xref ld_mzero 711da177e4SLinus Torvalds |xref snzrinx 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds| 741da177e4SLinus Torvalds| FINT 751da177e4SLinus Torvalds| 761da177e4SLinus Torvalds .global sint 771da177e4SLinus Torvaldssint: 781da177e4SLinus Torvalds bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 791da177e4SLinus Torvalds| ;implicitly has extend precision 801da177e4SLinus Torvalds| ;in upper word. 811da177e4SLinus Torvalds movel %d1,L_SCR1(%a6) |save mode bits 821da177e4SLinus Torvalds bras sintexc 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds| 851da177e4SLinus Torvalds| FINT with extended denorm inputs. 861da177e4SLinus Torvalds| 871da177e4SLinus Torvalds .global sintd 881da177e4SLinus Torvaldssintd: 891da177e4SLinus Torvalds btstb #5,FPCR_MODE(%a6) 901da177e4SLinus Torvalds beq snzrinx |if round nearest or round zero, +/- 0 911da177e4SLinus Torvalds btstb #4,FPCR_MODE(%a6) 921da177e4SLinus Torvalds beqs rnd_mns 931da177e4SLinus Torvaldsrnd_pls: 941da177e4SLinus Torvalds btstb #sign_bit,LOCAL_EX(%a0) 951da177e4SLinus Torvalds bnes sintmz 961da177e4SLinus Torvalds bsr ld_pone |if round plus inf and pos, answer is +1 971da177e4SLinus Torvalds bra t_inx2 981da177e4SLinus Torvaldsrnd_mns: 991da177e4SLinus Torvalds btstb #sign_bit,LOCAL_EX(%a0) 1001da177e4SLinus Torvalds beqs sintpz 1011da177e4SLinus Torvalds bsr ld_mone |if round mns inf and neg, answer is -1 1021da177e4SLinus Torvalds bra t_inx2 1031da177e4SLinus Torvaldssintpz: 1041da177e4SLinus Torvalds bsr ld_pzero 1051da177e4SLinus Torvalds bra t_inx2 1061da177e4SLinus Torvaldssintmz: 1071da177e4SLinus Torvalds bsr ld_mzero 1081da177e4SLinus Torvalds bra t_inx2 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds| 1111da177e4SLinus Torvalds| FINTRZ 1121da177e4SLinus Torvalds| 1131da177e4SLinus Torvalds .global sintrz 1141da177e4SLinus Torvaldssintrz: 1151da177e4SLinus Torvalds movel #1,L_SCR1(%a6) |use rz mode for rounding 1161da177e4SLinus Torvalds| ;implicitly has extend precision 1171da177e4SLinus Torvalds| ;in upper word. 1181da177e4SLinus Torvalds bras sintexc 1191da177e4SLinus Torvalds| 1201da177e4SLinus Torvalds| SINTDO 1211da177e4SLinus Torvalds| 1221da177e4SLinus Torvalds| Input: a0 points to an IEEE extended format operand 1231da177e4SLinus Torvalds| Output: fp0 has the result 1241da177e4SLinus Torvalds| 1251da177e4SLinus Torvalds| Exceptions: 1261da177e4SLinus Torvalds| 1271da177e4SLinus Torvalds| If the subroutine results in an inexact operation, the inx2 and 1281da177e4SLinus Torvalds| ainx bits in the USER_FPSR are set. 1291da177e4SLinus Torvalds| 1301da177e4SLinus Torvalds| 1311da177e4SLinus Torvalds .global sintdo 1321da177e4SLinus Torvaldssintdo: 1331da177e4SLinus Torvalds bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 1341da177e4SLinus Torvalds| ;implicitly has ext precision 1351da177e4SLinus Torvalds| ;in upper word. 1361da177e4SLinus Torvalds movel %d1,L_SCR1(%a6) |save mode bits 1371da177e4SLinus Torvalds| 1381da177e4SLinus Torvalds| Real work of sint is in sintexc 1391da177e4SLinus Torvalds| 1401da177e4SLinus Torvaldssintexc: 1411da177e4SLinus Torvalds bclrb #sign_bit,LOCAL_EX(%a0) |convert to internal extended 1421da177e4SLinus Torvalds| ;format 1431da177e4SLinus Torvalds sne LOCAL_SGN(%a0) 1441da177e4SLinus Torvalds cmpw #0x403e,LOCAL_EX(%a0) |check if (unbiased) exp > 63 1451da177e4SLinus Torvalds bgts out_rnge |branch if exp < 63 1461da177e4SLinus Torvalds cmpw #0x3ffd,LOCAL_EX(%a0) |check if (unbiased) exp < 0 1471da177e4SLinus Torvalds bgt in_rnge |if 63 >= exp > 0, do calc 1481da177e4SLinus Torvalds| 1491da177e4SLinus Torvalds| Input is less than zero. Restore sign, and check for directed 1501da177e4SLinus Torvalds| rounding modes. L_SCR1 contains the rmode in the lower byte. 1511da177e4SLinus Torvalds| 1521da177e4SLinus Torvaldsun_rnge: 1531da177e4SLinus Torvalds btstb #1,L_SCR1+3(%a6) |check for rn and rz 1541da177e4SLinus Torvalds beqs un_rnrz 1551da177e4SLinus Torvalds tstb LOCAL_SGN(%a0) |check for sign 1561da177e4SLinus Torvalds bnes un_rmrp_neg 1571da177e4SLinus Torvalds| 1581da177e4SLinus Torvalds| Sign is +. If rp, load +1.0, if rm, load +0.0 1591da177e4SLinus Torvalds| 1601da177e4SLinus Torvalds cmpib #3,L_SCR1+3(%a6) |check for rp 1611da177e4SLinus Torvalds beqs un_ldpone |if rp, load +1.0 1621da177e4SLinus Torvalds bsr ld_pzero |if rm, load +0.0 1631da177e4SLinus Torvalds bra t_inx2 1641da177e4SLinus Torvaldsun_ldpone: 1651da177e4SLinus Torvalds bsr ld_pone 1661da177e4SLinus Torvalds bra t_inx2 1671da177e4SLinus Torvalds| 1681da177e4SLinus Torvalds| Sign is -. If rm, load -1.0, if rp, load -0.0 1691da177e4SLinus Torvalds| 1701da177e4SLinus Torvaldsun_rmrp_neg: 1711da177e4SLinus Torvalds cmpib #2,L_SCR1+3(%a6) |check for rm 1721da177e4SLinus Torvalds beqs un_ldmone |if rm, load -1.0 1731da177e4SLinus Torvalds bsr ld_mzero |if rp, load -0.0 1741da177e4SLinus Torvalds bra t_inx2 1751da177e4SLinus Torvaldsun_ldmone: 1761da177e4SLinus Torvalds bsr ld_mone 1771da177e4SLinus Torvalds bra t_inx2 1781da177e4SLinus Torvalds| 1791da177e4SLinus Torvalds| Rmode is rn or rz; return signed zero 1801da177e4SLinus Torvalds| 1811da177e4SLinus Torvaldsun_rnrz: 1821da177e4SLinus Torvalds tstb LOCAL_SGN(%a0) |check for sign 1831da177e4SLinus Torvalds bnes un_rnrz_neg 1841da177e4SLinus Torvalds bsr ld_pzero 1851da177e4SLinus Torvalds bra t_inx2 1861da177e4SLinus Torvaldsun_rnrz_neg: 1871da177e4SLinus Torvalds bsr ld_mzero 1881da177e4SLinus Torvalds bra t_inx2 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds| 1911da177e4SLinus Torvalds| Input is greater than 2^63. All bits are significant. Return 1921da177e4SLinus Torvalds| the input. 1931da177e4SLinus Torvalds| 1941da177e4SLinus Torvaldsout_rnge: 1951da177e4SLinus Torvalds bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format 1961da177e4SLinus Torvalds beqs intps 1971da177e4SLinus Torvalds bsetb #sign_bit,LOCAL_EX(%a0) 1981da177e4SLinus Torvaldsintps: 1991da177e4SLinus Torvalds fmovel %fpcr,-(%sp) 2001da177e4SLinus Torvalds fmovel #0,%fpcr 2011da177e4SLinus Torvalds fmovex LOCAL_EX(%a0),%fp0 |if exp > 63 2021da177e4SLinus Torvalds| ;then return X to the user 2031da177e4SLinus Torvalds| ;there are no fraction bits 2041da177e4SLinus Torvalds fmovel (%sp)+,%fpcr 2051da177e4SLinus Torvalds rts 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvaldsin_rnge: 2081da177e4SLinus Torvalds| ;shift off fraction bits 2091da177e4SLinus Torvalds clrl %d0 |clear d0 - initial g,r,s for 2101da177e4SLinus Torvalds| ;dnrm_lp 2111da177e4SLinus Torvalds movel #0x403e,%d1 |set threshold for dnrm_lp 2121da177e4SLinus Torvalds| ;assumes a0 points to operand 2131da177e4SLinus Torvalds bsr dnrm_lp 2141da177e4SLinus Torvalds| ;returns unnormalized number 2151da177e4SLinus Torvalds| ;pointed by a0 2161da177e4SLinus Torvalds| ;output d0 supplies g,r,s 2171da177e4SLinus Torvalds| ;used by round 2181da177e4SLinus Torvalds movel L_SCR1(%a6),%d1 |use selected rounding mode 2191da177e4SLinus Torvalds| 2201da177e4SLinus Torvalds| 2211da177e4SLinus Torvalds bsr round |round the unnorm based on users 2221da177e4SLinus Torvalds| ;input a0 ptr to ext X 2231da177e4SLinus Torvalds| ; d0 g,r,s bits 2241da177e4SLinus Torvalds| ; d1 PREC/MODE info 2251da177e4SLinus Torvalds| ;output a0 ptr to rounded result 2261da177e4SLinus Torvalds| ;inexact flag set in USER_FPSR 2271da177e4SLinus Torvalds| ;if initial grs set 2281da177e4SLinus Torvalds| 2291da177e4SLinus Torvalds| normalize the rounded result and store value in fp0 2301da177e4SLinus Torvalds| 2311da177e4SLinus Torvalds bsr nrm_set |normalize the unnorm 2321da177e4SLinus Torvalds| ;Input: a0 points to operand to 2331da177e4SLinus Torvalds| ;be normalized 2341da177e4SLinus Torvalds| ;Output: a0 points to normalized 2351da177e4SLinus Torvalds| ;result 2361da177e4SLinus Torvalds bfclr LOCAL_SGN(%a0){#0:#8} 2371da177e4SLinus Torvalds beqs nrmrndp 2381da177e4SLinus Torvalds bsetb #sign_bit,LOCAL_EX(%a0) |return to IEEE extended format 2391da177e4SLinus Torvaldsnrmrndp: 2401da177e4SLinus Torvalds fmovel %fpcr,-(%sp) 2411da177e4SLinus Torvalds fmovel #0,%fpcr 2421da177e4SLinus Torvalds fmovex LOCAL_EX(%a0),%fp0 |move result to fp0 2431da177e4SLinus Torvalds fmovel (%sp)+,%fpcr 2441da177e4SLinus Torvalds rts 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds |end 247