162306a36Sopenharmony_ci| 262306a36Sopenharmony_ci| sint.sa 3.1 12/10/90 362306a36Sopenharmony_ci| 462306a36Sopenharmony_ci| The entry point sINT computes the rounded integer 562306a36Sopenharmony_ci| equivalent of the input argument, sINTRZ computes 662306a36Sopenharmony_ci| the integer rounded to zero of the input argument. 762306a36Sopenharmony_ci| 862306a36Sopenharmony_ci| Entry points sint and sintrz are called from do_func 962306a36Sopenharmony_ci| to emulate the fint and fintrz unimplemented instructions, 1062306a36Sopenharmony_ci| respectively. Entry point sintdo is used by bindec. 1162306a36Sopenharmony_ci| 1262306a36Sopenharmony_ci| Input: (Entry points sint and sintrz) Double-extended 1362306a36Sopenharmony_ci| number X in the ETEMP space in the floating-point 1462306a36Sopenharmony_ci| save stack. 1562306a36Sopenharmony_ci| (Entry point sintdo) Double-extended number X in 1662306a36Sopenharmony_ci| location pointed to by the address register a0. 1762306a36Sopenharmony_ci| (Entry point sintd) Double-extended denormalized 1862306a36Sopenharmony_ci| number X in the ETEMP space in the floating-point 1962306a36Sopenharmony_ci| save stack. 2062306a36Sopenharmony_ci| 2162306a36Sopenharmony_ci| Output: The function returns int(X) or intrz(X) in fp0. 2262306a36Sopenharmony_ci| 2362306a36Sopenharmony_ci| Modifies: fp0. 2462306a36Sopenharmony_ci| 2562306a36Sopenharmony_ci| Algorithm: (sint and sintrz) 2662306a36Sopenharmony_ci| 2762306a36Sopenharmony_ci| 1. If exp(X) >= 63, return X. 2862306a36Sopenharmony_ci| If exp(X) < 0, return +/- 0 or +/- 1, according to 2962306a36Sopenharmony_ci| the rounding mode. 3062306a36Sopenharmony_ci| 3162306a36Sopenharmony_ci| 2. (X is in range) set rsc = 63 - exp(X). Unnormalize the 3262306a36Sopenharmony_ci| result to the exponent $403e. 3362306a36Sopenharmony_ci| 3462306a36Sopenharmony_ci| 3. Round the result in the mode given in USER_FPCR. For 3562306a36Sopenharmony_ci| sintrz, force round-to-zero mode. 3662306a36Sopenharmony_ci| 3762306a36Sopenharmony_ci| 4. Normalize the rounded result; store in fp0. 3862306a36Sopenharmony_ci| 3962306a36Sopenharmony_ci| For the denormalized cases, force the correct result 4062306a36Sopenharmony_ci| for the given sign and rounding mode. 4162306a36Sopenharmony_ci| 4262306a36Sopenharmony_ci| Sign(X) 4362306a36Sopenharmony_ci| RMODE + - 4462306a36Sopenharmony_ci| ----- -------- 4562306a36Sopenharmony_ci| RN +0 -0 4662306a36Sopenharmony_ci| RZ +0 -0 4762306a36Sopenharmony_ci| RM +0 -1 4862306a36Sopenharmony_ci| RP +1 -0 4962306a36Sopenharmony_ci| 5062306a36Sopenharmony_ci| 5162306a36Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 5262306a36Sopenharmony_ci| All Rights Reserved 5362306a36Sopenharmony_ci| 5462306a36Sopenharmony_ci| For details on the license for this file, please see the 5562306a36Sopenharmony_ci| file, README, in this same directory. 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci|SINT idnt 2,1 | Motorola 040 Floating Point Software Package 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci |section 8 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#include "fpsp.h" 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci |xref dnrm_lp 6462306a36Sopenharmony_ci |xref nrm_set 6562306a36Sopenharmony_ci |xref round 6662306a36Sopenharmony_ci |xref t_inx2 6762306a36Sopenharmony_ci |xref ld_pone 6862306a36Sopenharmony_ci |xref ld_mone 6962306a36Sopenharmony_ci |xref ld_pzero 7062306a36Sopenharmony_ci |xref ld_mzero 7162306a36Sopenharmony_ci |xref snzrinx 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci| 7462306a36Sopenharmony_ci| FINT 7562306a36Sopenharmony_ci| 7662306a36Sopenharmony_ci .global sint 7762306a36Sopenharmony_cisint: 7862306a36Sopenharmony_ci bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 7962306a36Sopenharmony_ci| ;implicitly has extend precision 8062306a36Sopenharmony_ci| ;in upper word. 8162306a36Sopenharmony_ci movel %d1,L_SCR1(%a6) |save mode bits 8262306a36Sopenharmony_ci bras sintexc 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci| 8562306a36Sopenharmony_ci| FINT with extended denorm inputs. 8662306a36Sopenharmony_ci| 8762306a36Sopenharmony_ci .global sintd 8862306a36Sopenharmony_cisintd: 8962306a36Sopenharmony_ci btstb #5,FPCR_MODE(%a6) 9062306a36Sopenharmony_ci beq snzrinx |if round nearest or round zero, +/- 0 9162306a36Sopenharmony_ci btstb #4,FPCR_MODE(%a6) 9262306a36Sopenharmony_ci beqs rnd_mns 9362306a36Sopenharmony_cirnd_pls: 9462306a36Sopenharmony_ci btstb #sign_bit,LOCAL_EX(%a0) 9562306a36Sopenharmony_ci bnes sintmz 9662306a36Sopenharmony_ci bsr ld_pone |if round plus inf and pos, answer is +1 9762306a36Sopenharmony_ci bra t_inx2 9862306a36Sopenharmony_cirnd_mns: 9962306a36Sopenharmony_ci btstb #sign_bit,LOCAL_EX(%a0) 10062306a36Sopenharmony_ci beqs sintpz 10162306a36Sopenharmony_ci bsr ld_mone |if round mns inf and neg, answer is -1 10262306a36Sopenharmony_ci bra t_inx2 10362306a36Sopenharmony_cisintpz: 10462306a36Sopenharmony_ci bsr ld_pzero 10562306a36Sopenharmony_ci bra t_inx2 10662306a36Sopenharmony_cisintmz: 10762306a36Sopenharmony_ci bsr ld_mzero 10862306a36Sopenharmony_ci bra t_inx2 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci| 11162306a36Sopenharmony_ci| FINTRZ 11262306a36Sopenharmony_ci| 11362306a36Sopenharmony_ci .global sintrz 11462306a36Sopenharmony_cisintrz: 11562306a36Sopenharmony_ci movel #1,L_SCR1(%a6) |use rz mode for rounding 11662306a36Sopenharmony_ci| ;implicitly has extend precision 11762306a36Sopenharmony_ci| ;in upper word. 11862306a36Sopenharmony_ci bras sintexc 11962306a36Sopenharmony_ci| 12062306a36Sopenharmony_ci| SINTDO 12162306a36Sopenharmony_ci| 12262306a36Sopenharmony_ci| Input: a0 points to an IEEE extended format operand 12362306a36Sopenharmony_ci| Output: fp0 has the result 12462306a36Sopenharmony_ci| 12562306a36Sopenharmony_ci| Exceptions: 12662306a36Sopenharmony_ci| 12762306a36Sopenharmony_ci| If the subroutine results in an inexact operation, the inx2 and 12862306a36Sopenharmony_ci| ainx bits in the USER_FPSR are set. 12962306a36Sopenharmony_ci| 13062306a36Sopenharmony_ci| 13162306a36Sopenharmony_ci .global sintdo 13262306a36Sopenharmony_cisintdo: 13362306a36Sopenharmony_ci bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding 13462306a36Sopenharmony_ci| ;implicitly has ext precision 13562306a36Sopenharmony_ci| ;in upper word. 13662306a36Sopenharmony_ci movel %d1,L_SCR1(%a6) |save mode bits 13762306a36Sopenharmony_ci| 13862306a36Sopenharmony_ci| Real work of sint is in sintexc 13962306a36Sopenharmony_ci| 14062306a36Sopenharmony_cisintexc: 14162306a36Sopenharmony_ci bclrb #sign_bit,LOCAL_EX(%a0) |convert to internal extended 14262306a36Sopenharmony_ci| ;format 14362306a36Sopenharmony_ci sne LOCAL_SGN(%a0) 14462306a36Sopenharmony_ci cmpw #0x403e,LOCAL_EX(%a0) |check if (unbiased) exp > 63 14562306a36Sopenharmony_ci bgts out_rnge |branch if exp < 63 14662306a36Sopenharmony_ci cmpw #0x3ffd,LOCAL_EX(%a0) |check if (unbiased) exp < 0 14762306a36Sopenharmony_ci bgt in_rnge |if 63 >= exp > 0, do calc 14862306a36Sopenharmony_ci| 14962306a36Sopenharmony_ci| Input is less than zero. Restore sign, and check for directed 15062306a36Sopenharmony_ci| rounding modes. L_SCR1 contains the rmode in the lower byte. 15162306a36Sopenharmony_ci| 15262306a36Sopenharmony_ciun_rnge: 15362306a36Sopenharmony_ci btstb #1,L_SCR1+3(%a6) |check for rn and rz 15462306a36Sopenharmony_ci beqs un_rnrz 15562306a36Sopenharmony_ci tstb LOCAL_SGN(%a0) |check for sign 15662306a36Sopenharmony_ci bnes un_rmrp_neg 15762306a36Sopenharmony_ci| 15862306a36Sopenharmony_ci| Sign is +. If rp, load +1.0, if rm, load +0.0 15962306a36Sopenharmony_ci| 16062306a36Sopenharmony_ci cmpib #3,L_SCR1+3(%a6) |check for rp 16162306a36Sopenharmony_ci beqs un_ldpone |if rp, load +1.0 16262306a36Sopenharmony_ci bsr ld_pzero |if rm, load +0.0 16362306a36Sopenharmony_ci bra t_inx2 16462306a36Sopenharmony_ciun_ldpone: 16562306a36Sopenharmony_ci bsr ld_pone 16662306a36Sopenharmony_ci bra t_inx2 16762306a36Sopenharmony_ci| 16862306a36Sopenharmony_ci| Sign is -. If rm, load -1.0, if rp, load -0.0 16962306a36Sopenharmony_ci| 17062306a36Sopenharmony_ciun_rmrp_neg: 17162306a36Sopenharmony_ci cmpib #2,L_SCR1+3(%a6) |check for rm 17262306a36Sopenharmony_ci beqs un_ldmone |if rm, load -1.0 17362306a36Sopenharmony_ci bsr ld_mzero |if rp, load -0.0 17462306a36Sopenharmony_ci bra t_inx2 17562306a36Sopenharmony_ciun_ldmone: 17662306a36Sopenharmony_ci bsr ld_mone 17762306a36Sopenharmony_ci bra t_inx2 17862306a36Sopenharmony_ci| 17962306a36Sopenharmony_ci| Rmode is rn or rz; return signed zero 18062306a36Sopenharmony_ci| 18162306a36Sopenharmony_ciun_rnrz: 18262306a36Sopenharmony_ci tstb LOCAL_SGN(%a0) |check for sign 18362306a36Sopenharmony_ci bnes un_rnrz_neg 18462306a36Sopenharmony_ci bsr ld_pzero 18562306a36Sopenharmony_ci bra t_inx2 18662306a36Sopenharmony_ciun_rnrz_neg: 18762306a36Sopenharmony_ci bsr ld_mzero 18862306a36Sopenharmony_ci bra t_inx2 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci| 19162306a36Sopenharmony_ci| Input is greater than 2^63. All bits are significant. Return 19262306a36Sopenharmony_ci| the input. 19362306a36Sopenharmony_ci| 19462306a36Sopenharmony_ciout_rnge: 19562306a36Sopenharmony_ci bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format 19662306a36Sopenharmony_ci beqs intps 19762306a36Sopenharmony_ci bsetb #sign_bit,LOCAL_EX(%a0) 19862306a36Sopenharmony_ciintps: 19962306a36Sopenharmony_ci fmovel %fpcr,-(%sp) 20062306a36Sopenharmony_ci fmovel #0,%fpcr 20162306a36Sopenharmony_ci fmovex LOCAL_EX(%a0),%fp0 |if exp > 63 20262306a36Sopenharmony_ci| ;then return X to the user 20362306a36Sopenharmony_ci| ;there are no fraction bits 20462306a36Sopenharmony_ci fmovel (%sp)+,%fpcr 20562306a36Sopenharmony_ci rts 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ciin_rnge: 20862306a36Sopenharmony_ci| ;shift off fraction bits 20962306a36Sopenharmony_ci clrl %d0 |clear d0 - initial g,r,s for 21062306a36Sopenharmony_ci| ;dnrm_lp 21162306a36Sopenharmony_ci movel #0x403e,%d1 |set threshold for dnrm_lp 21262306a36Sopenharmony_ci| ;assumes a0 points to operand 21362306a36Sopenharmony_ci bsr dnrm_lp 21462306a36Sopenharmony_ci| ;returns unnormalized number 21562306a36Sopenharmony_ci| ;pointed by a0 21662306a36Sopenharmony_ci| ;output d0 supplies g,r,s 21762306a36Sopenharmony_ci| ;used by round 21862306a36Sopenharmony_ci movel L_SCR1(%a6),%d1 |use selected rounding mode 21962306a36Sopenharmony_ci| 22062306a36Sopenharmony_ci| 22162306a36Sopenharmony_ci bsr round |round the unnorm based on users 22262306a36Sopenharmony_ci| ;input a0 ptr to ext X 22362306a36Sopenharmony_ci| ; d0 g,r,s bits 22462306a36Sopenharmony_ci| ; d1 PREC/MODE info 22562306a36Sopenharmony_ci| ;output a0 ptr to rounded result 22662306a36Sopenharmony_ci| ;inexact flag set in USER_FPSR 22762306a36Sopenharmony_ci| ;if initial grs set 22862306a36Sopenharmony_ci| 22962306a36Sopenharmony_ci| normalize the rounded result and store value in fp0 23062306a36Sopenharmony_ci| 23162306a36Sopenharmony_ci bsr nrm_set |normalize the unnorm 23262306a36Sopenharmony_ci| ;Input: a0 points to operand to 23362306a36Sopenharmony_ci| ;be normalized 23462306a36Sopenharmony_ci| ;Output: a0 points to normalized 23562306a36Sopenharmony_ci| ;result 23662306a36Sopenharmony_ci bfclr LOCAL_SGN(%a0){#0:#8} 23762306a36Sopenharmony_ci beqs nrmrndp 23862306a36Sopenharmony_ci bsetb #sign_bit,LOCAL_EX(%a0) |return to IEEE extended format 23962306a36Sopenharmony_cinrmrndp: 24062306a36Sopenharmony_ci fmovel %fpcr,-(%sp) 24162306a36Sopenharmony_ci fmovel #0,%fpcr 24262306a36Sopenharmony_ci fmovex LOCAL_EX(%a0),%fp0 |move result to fp0 24362306a36Sopenharmony_ci fmovel (%sp)+,%fpcr 24462306a36Sopenharmony_ci rts 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci |end 247