Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | | | |
e00d82d0 MW |
54 | | For details on the license for this file, please see the |
55 | | file, README, in this same directory. | |
1da177e4 LT |
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 |