18c2ecf20Sopenharmony_ci| 28c2ecf20Sopenharmony_ci| sint.sa 3.1 12/10/90 38c2ecf20Sopenharmony_ci| 48c2ecf20Sopenharmony_ci| The entry point sINT computes the rounded integer 58c2ecf20Sopenharmony_ci| equivalent of the input argument, sINTRZ computes 68c2ecf20Sopenharmony_ci| the integer rounded to zero of the input argument. 78c2ecf20Sopenharmony_ci| 88c2ecf20Sopenharmony_ci| Entry points sint and sintrz are called from do_func 98c2ecf20Sopenharmony_ci| to emulate the fint and fintrz unimplemented instructions, 108c2ecf20Sopenharmony_ci| respectively. Entry point sintdo is used by bindec. 118c2ecf20Sopenharmony_ci| 128c2ecf20Sopenharmony_ci| Input: (Entry points sint and sintrz) Double-extended 138c2ecf20Sopenharmony_ci| number X in the ETEMP space in the floating-point 148c2ecf20Sopenharmony_ci| save stack. 158c2ecf20Sopenharmony_ci| (Entry point sintdo) Double-extended number X in 168c2ecf20Sopenharmony_ci| location pointed to by the address register a0. 178c2ecf20Sopenharmony_ci| (Entry point sintd) Double-extended denormalized 188c2ecf20Sopenharmony_ci| number X in the ETEMP space in the floating-point 198c2ecf20Sopenharmony_ci| save stack. 208c2ecf20Sopenharmony_ci| 218c2ecf20Sopenharmony_ci| Output: The function returns int(X) or intrz(X) in fp0. 228c2ecf20Sopenharmony_ci| 238c2ecf20Sopenharmony_ci| Modifies: fp0. 248c2ecf20Sopenharmony_ci| 258c2ecf20Sopenharmony_ci| Algorithm: (sint and sintrz) 268c2ecf20Sopenharmony_ci| 278c2ecf20Sopenharmony_ci| 1. If exp(X) >= 63, return X. 288c2ecf20Sopenharmony_ci| If exp(X) < 0, return +/- 0 or +/- 1, according to 298c2ecf20Sopenharmony_ci| the rounding mode. 308c2ecf20Sopenharmony_ci| 318c2ecf20Sopenharmony_ci| 2. (X is in range) set rsc = 63 - exp(X). Unnormalize the 328c2ecf20Sopenharmony_ci| result to the exponent $403e. 338c2ecf20Sopenharmony_ci| 348c2ecf20Sopenharmony_ci| 3. Round the result in the mode given in USER_FPCR. For 358c2ecf20Sopenharmony_ci| sintrz, force round-to-zero mode. 368c2ecf20Sopenharmony_ci| 378c2ecf20Sopenharmony_ci| 4. Normalize the rounded result; store in fp0. 388c2ecf20Sopenharmony_ci| 398c2ecf20Sopenharmony_ci| For the denormalized cases, force the correct result 408c2ecf20Sopenharmony_ci| for the given sign and rounding mode. 418c2ecf20Sopenharmony_ci| 428c2ecf20Sopenharmony_ci| Sign(X) 438c2ecf20Sopenharmony_ci| RMODE + - 448c2ecf20Sopenharmony_ci| ----- -------- 458c2ecf20Sopenharmony_ci| RN +0 -0 468c2ecf20Sopenharmony_ci| RZ +0 -0 478c2ecf20Sopenharmony_ci| RM +0 -1 488c2ecf20Sopenharmony_ci| RP +1 -0 498c2ecf20Sopenharmony_ci| 508c2ecf20Sopenharmony_ci| 518c2ecf20Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 528c2ecf20Sopenharmony_ci| All Rights Reserved 538c2ecf20Sopenharmony_ci| 548c2ecf20Sopenharmony_ci| For details on the license for this file, please see the 558c2ecf20Sopenharmony_ci| file, README, in this same directory. 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci|SINT idnt 2,1 | Motorola 040 Floating Point Software Package 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci |section 8 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#include "fpsp.h" 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci |xref dnrm_lp 648c2ecf20Sopenharmony_ci |xref nrm_set 658c2ecf20Sopenharmony_ci |xref round 668c2ecf20Sopenharmony_ci |xref t_inx2 678c2ecf20Sopenharmony_ci |xref ld_pone 688c2ecf20Sopenharmony_ci |xref ld_mone 698c2ecf20Sopenharmony_ci |xref ld_pzero 708c2ecf20Sopenharmony_ci |xref ld_mzero 718c2ecf20Sopenharmony_ci |xref snzrinx 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci| 748c2ecf20Sopenharmony_ci| FINT 758c2ecf20Sopenharmony_ci| 768c2ecf20Sopenharmony_ci .global sint 778c2ecf20Sopenharmony_cisint: 788c2ecf20Sopenharmony_ci bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 798c2ecf20Sopenharmony_ci| ;implicitly has extend precision 808c2ecf20Sopenharmony_ci| ;in upper word. 818c2ecf20Sopenharmony_ci movel %d1,L_SCR1(%a6) |save mode bits 828c2ecf20Sopenharmony_ci bras sintexc 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci| 858c2ecf20Sopenharmony_ci| FINT with extended denorm inputs. 868c2ecf20Sopenharmony_ci| 878c2ecf20Sopenharmony_ci .global sintd 888c2ecf20Sopenharmony_cisintd: 898c2ecf20Sopenharmony_ci btstb #5,FPCR_MODE(%a6) 908c2ecf20Sopenharmony_ci beq snzrinx |if round nearest or round zero, +/- 0 918c2ecf20Sopenharmony_ci btstb #4,FPCR_MODE(%a6) 928c2ecf20Sopenharmony_ci beqs rnd_mns 938c2ecf20Sopenharmony_cirnd_pls: 948c2ecf20Sopenharmony_ci btstb #sign_bit,LOCAL_EX(%a0) 958c2ecf20Sopenharmony_ci bnes sintmz 968c2ecf20Sopenharmony_ci bsr ld_pone |if round plus inf and pos, answer is +1 978c2ecf20Sopenharmony_ci bra t_inx2 988c2ecf20Sopenharmony_cirnd_mns: 998c2ecf20Sopenharmony_ci btstb #sign_bit,LOCAL_EX(%a0) 1008c2ecf20Sopenharmony_ci beqs sintpz 1018c2ecf20Sopenharmony_ci bsr ld_mone |if round mns inf and neg, answer is -1 1028c2ecf20Sopenharmony_ci bra t_inx2 1038c2ecf20Sopenharmony_cisintpz: 1048c2ecf20Sopenharmony_ci bsr ld_pzero 1058c2ecf20Sopenharmony_ci bra t_inx2 1068c2ecf20Sopenharmony_cisintmz: 1078c2ecf20Sopenharmony_ci bsr ld_mzero 1088c2ecf20Sopenharmony_ci bra t_inx2 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci| 1118c2ecf20Sopenharmony_ci| FINTRZ 1128c2ecf20Sopenharmony_ci| 1138c2ecf20Sopenharmony_ci .global sintrz 1148c2ecf20Sopenharmony_cisintrz: 1158c2ecf20Sopenharmony_ci movel #1,L_SCR1(%a6) |use rz mode for rounding 1168c2ecf20Sopenharmony_ci| ;implicitly has extend precision 1178c2ecf20Sopenharmony_ci| ;in upper word. 1188c2ecf20Sopenharmony_ci bras sintexc 1198c2ecf20Sopenharmony_ci| 1208c2ecf20Sopenharmony_ci| SINTDO 1218c2ecf20Sopenharmony_ci| 1228c2ecf20Sopenharmony_ci| Input: a0 points to an IEEE extended format operand 1238c2ecf20Sopenharmony_ci| Output: fp0 has the result 1248c2ecf20Sopenharmony_ci| 1258c2ecf20Sopenharmony_ci| Exceptions: 1268c2ecf20Sopenharmony_ci| 1278c2ecf20Sopenharmony_ci| If the subroutine results in an inexact operation, the inx2 and 1288c2ecf20Sopenharmony_ci| ainx bits in the USER_FPSR are set. 1298c2ecf20Sopenharmony_ci| 1308c2ecf20Sopenharmony_ci| 1318c2ecf20Sopenharmony_ci .global sintdo 1328c2ecf20Sopenharmony_cisintdo: 1338c2ecf20Sopenharmony_ci bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 1348c2ecf20Sopenharmony_ci| ;implicitly has ext precision 1358c2ecf20Sopenharmony_ci| ;in upper word. 1368c2ecf20Sopenharmony_ci movel %d1,L_SCR1(%a6) |save mode bits 1378c2ecf20Sopenharmony_ci| 1388c2ecf20Sopenharmony_ci| Real work of sint is in sintexc 1398c2ecf20Sopenharmony_ci| 1408c2ecf20Sopenharmony_cisintexc: 1418c2ecf20Sopenharmony_ci bclrb #sign_bit,LOCAL_EX(%a0) |convert to internal extended 1428c2ecf20Sopenharmony_ci| ;format 1438c2ecf20Sopenharmony_ci sne LOCAL_SGN(%a0) 1448c2ecf20Sopenharmony_ci cmpw #0x403e,LOCAL_EX(%a0) |check if (unbiased) exp > 63 1458c2ecf20Sopenharmony_ci bgts out_rnge |branch if exp < 63 1468c2ecf20Sopenharmony_ci cmpw #0x3ffd,LOCAL_EX(%a0) |check if (unbiased) exp < 0 1478c2ecf20Sopenharmony_ci bgt in_rnge |if 63 >= exp > 0, do calc 1488c2ecf20Sopenharmony_ci| 1498c2ecf20Sopenharmony_ci| Input is less than zero. Restore sign, and check for directed 1508c2ecf20Sopenharmony_ci| rounding modes. L_SCR1 contains the rmode in the lower byte. 1518c2ecf20Sopenharmony_ci| 1528c2ecf20Sopenharmony_ciun_rnge: 1538c2ecf20Sopenharmony_ci btstb #1,L_SCR1+3(%a6) |check for rn and rz 1548c2ecf20Sopenharmony_ci beqs un_rnrz 1558c2ecf20Sopenharmony_ci tstb LOCAL_SGN(%a0) |check for sign 1568c2ecf20Sopenharmony_ci bnes un_rmrp_neg 1578c2ecf20Sopenharmony_ci| 1588c2ecf20Sopenharmony_ci| Sign is +. If rp, load +1.0, if rm, load +0.0 1598c2ecf20Sopenharmony_ci| 1608c2ecf20Sopenharmony_ci cmpib #3,L_SCR1+3(%a6) |check for rp 1618c2ecf20Sopenharmony_ci beqs un_ldpone |if rp, load +1.0 1628c2ecf20Sopenharmony_ci bsr ld_pzero |if rm, load +0.0 1638c2ecf20Sopenharmony_ci bra t_inx2 1648c2ecf20Sopenharmony_ciun_ldpone: 1658c2ecf20Sopenharmony_ci bsr ld_pone 1668c2ecf20Sopenharmony_ci bra t_inx2 1678c2ecf20Sopenharmony_ci| 1688c2ecf20Sopenharmony_ci| Sign is -. If rm, load -1.0, if rp, load -0.0 1698c2ecf20Sopenharmony_ci| 1708c2ecf20Sopenharmony_ciun_rmrp_neg: 1718c2ecf20Sopenharmony_ci cmpib #2,L_SCR1+3(%a6) |check for rm 1728c2ecf20Sopenharmony_ci beqs un_ldmone |if rm, load -1.0 1738c2ecf20Sopenharmony_ci bsr ld_mzero |if rp, load -0.0 1748c2ecf20Sopenharmony_ci bra t_inx2 1758c2ecf20Sopenharmony_ciun_ldmone: 1768c2ecf20Sopenharmony_ci bsr ld_mone 1778c2ecf20Sopenharmony_ci bra t_inx2 1788c2ecf20Sopenharmony_ci| 1798c2ecf20Sopenharmony_ci| Rmode is rn or rz; return signed zero 1808c2ecf20Sopenharmony_ci| 1818c2ecf20Sopenharmony_ciun_rnrz: 1828c2ecf20Sopenharmony_ci tstb LOCAL_SGN(%a0) |check for sign 1838c2ecf20Sopenharmony_ci bnes un_rnrz_neg 1848c2ecf20Sopenharmony_ci bsr ld_pzero 1858c2ecf20Sopenharmony_ci bra t_inx2 1868c2ecf20Sopenharmony_ciun_rnrz_neg: 1878c2ecf20Sopenharmony_ci bsr ld_mzero 1888c2ecf20Sopenharmony_ci bra t_inx2 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci| 1918c2ecf20Sopenharmony_ci| Input is greater than 2^63. All bits are significant. Return 1928c2ecf20Sopenharmony_ci| the input. 1938c2ecf20Sopenharmony_ci| 1948c2ecf20Sopenharmony_ciout_rnge: 1958c2ecf20Sopenharmony_ci bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format 1968c2ecf20Sopenharmony_ci beqs intps 1978c2ecf20Sopenharmony_ci bsetb #sign_bit,LOCAL_EX(%a0) 1988c2ecf20Sopenharmony_ciintps: 1998c2ecf20Sopenharmony_ci fmovel %fpcr,-(%sp) 2008c2ecf20Sopenharmony_ci fmovel #0,%fpcr 2018c2ecf20Sopenharmony_ci fmovex LOCAL_EX(%a0),%fp0 |if exp > 63 2028c2ecf20Sopenharmony_ci| ;then return X to the user 2038c2ecf20Sopenharmony_ci| ;there are no fraction bits 2048c2ecf20Sopenharmony_ci fmovel (%sp)+,%fpcr 2058c2ecf20Sopenharmony_ci rts 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ciin_rnge: 2088c2ecf20Sopenharmony_ci| ;shift off fraction bits 2098c2ecf20Sopenharmony_ci clrl %d0 |clear d0 - initial g,r,s for 2108c2ecf20Sopenharmony_ci| ;dnrm_lp 2118c2ecf20Sopenharmony_ci movel #0x403e,%d1 |set threshold for dnrm_lp 2128c2ecf20Sopenharmony_ci| ;assumes a0 points to operand 2138c2ecf20Sopenharmony_ci bsr dnrm_lp 2148c2ecf20Sopenharmony_ci| ;returns unnormalized number 2158c2ecf20Sopenharmony_ci| ;pointed by a0 2168c2ecf20Sopenharmony_ci| ;output d0 supplies g,r,s 2178c2ecf20Sopenharmony_ci| ;used by round 2188c2ecf20Sopenharmony_ci movel L_SCR1(%a6),%d1 |use selected rounding mode 2198c2ecf20Sopenharmony_ci| 2208c2ecf20Sopenharmony_ci| 2218c2ecf20Sopenharmony_ci bsr round |round the unnorm based on users 2228c2ecf20Sopenharmony_ci| ;input a0 ptr to ext X 2238c2ecf20Sopenharmony_ci| ; d0 g,r,s bits 2248c2ecf20Sopenharmony_ci| ; d1 PREC/MODE info 2258c2ecf20Sopenharmony_ci| ;output a0 ptr to rounded result 2268c2ecf20Sopenharmony_ci| ;inexact flag set in USER_FPSR 2278c2ecf20Sopenharmony_ci| ;if initial grs set 2288c2ecf20Sopenharmony_ci| 2298c2ecf20Sopenharmony_ci| normalize the rounded result and store value in fp0 2308c2ecf20Sopenharmony_ci| 2318c2ecf20Sopenharmony_ci bsr nrm_set |normalize the unnorm 2328c2ecf20Sopenharmony_ci| ;Input: a0 points to operand to 2338c2ecf20Sopenharmony_ci| ;be normalized 2348c2ecf20Sopenharmony_ci| ;Output: a0 points to normalized 2358c2ecf20Sopenharmony_ci| ;result 2368c2ecf20Sopenharmony_ci bfclr LOCAL_SGN(%a0){#0:#8} 2378c2ecf20Sopenharmony_ci beqs nrmrndp 2388c2ecf20Sopenharmony_ci bsetb #sign_bit,LOCAL_EX(%a0) |return to IEEE extended format 2398c2ecf20Sopenharmony_cinrmrndp: 2408c2ecf20Sopenharmony_ci fmovel %fpcr,-(%sp) 2418c2ecf20Sopenharmony_ci fmovel #0,%fpcr 2428c2ecf20Sopenharmony_ci fmovex LOCAL_EX(%a0),%fp0 |move result to fp0 2438c2ecf20Sopenharmony_ci fmovel (%sp)+,%fpcr 2448c2ecf20Sopenharmony_ci rts 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci |end 247