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