diff options
Diffstat (limited to 'arch/m68k/fpsp040/sint.S')
-rw-r--r-- | arch/m68k/fpsp040/sint.S | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/arch/m68k/fpsp040/sint.S b/arch/m68k/fpsp040/sint.S new file mode 100644 index 000000000000..0f9bd28e55a0 --- /dev/null +++ b/arch/m68k/fpsp040/sint.S | |||
@@ -0,0 +1,247 @@ | |||
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 | | | ||
54 | | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA | ||
55 | | The copyright notice above does not evidence any | ||
56 | | actual or intended publication of such source code. | ||
57 | |||
58 | |SINT idnt 2,1 | Motorola 040 Floating Point Software Package | ||
59 | |||
60 | |section 8 | ||
61 | |||
62 | #include "fpsp.h" | ||
63 | |||
64 | |xref dnrm_lp | ||
65 | |xref nrm_set | ||
66 | |xref round | ||
67 | |xref t_inx2 | ||
68 | |xref ld_pone | ||
69 | |xref ld_mone | ||
70 | |xref ld_pzero | ||
71 | |xref ld_mzero | ||
72 | |xref snzrinx | ||
73 | |||
74 | | | ||
75 | | FINT | ||
76 | | | ||
77 | .global sint | ||
78 | sint: | ||
79 | bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding | ||
80 | | ;implicitly has extend precision | ||
81 | | ;in upper word. | ||
82 | movel %d1,L_SCR1(%a6) |save mode bits | ||
83 | bras sintexc | ||
84 | |||
85 | | | ||
86 | | FINT with extended denorm inputs. | ||
87 | | | ||
88 | .global sintd | ||
89 | sintd: | ||
90 | btstb #5,FPCR_MODE(%a6) | ||
91 | beq snzrinx |if round nearest or round zero, +/- 0 | ||
92 | btstb #4,FPCR_MODE(%a6) | ||
93 | beqs rnd_mns | ||
94 | rnd_pls: | ||
95 | btstb #sign_bit,LOCAL_EX(%a0) | ||
96 | bnes sintmz | ||
97 | bsr ld_pone |if round plus inf and pos, answer is +1 | ||
98 | bra t_inx2 | ||
99 | rnd_mns: | ||
100 | btstb #sign_bit,LOCAL_EX(%a0) | ||
101 | beqs sintpz | ||
102 | bsr ld_mone |if round mns inf and neg, answer is -1 | ||
103 | bra t_inx2 | ||
104 | sintpz: | ||
105 | bsr ld_pzero | ||
106 | bra t_inx2 | ||
107 | sintmz: | ||
108 | bsr ld_mzero | ||
109 | bra t_inx2 | ||
110 | |||
111 | | | ||
112 | | FINTRZ | ||
113 | | | ||
114 | .global sintrz | ||
115 | sintrz: | ||
116 | movel #1,L_SCR1(%a6) |use rz mode for rounding | ||
117 | | ;implicitly has extend precision | ||
118 | | ;in upper word. | ||
119 | bras sintexc | ||
120 | | | ||
121 | | SINTDO | ||
122 | | | ||
123 | | Input: a0 points to an IEEE extended format operand | ||
124 | | Output: fp0 has the result | ||
125 | | | ||
126 | | Exceptions: | ||
127 | | | ||
128 | | If the subroutine results in an inexact operation, the inx2 and | ||
129 | | ainx bits in the USER_FPSR are set. | ||
130 | | | ||
131 | | | ||
132 | .global sintdo | ||
133 | sintdo: | ||
134 | bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding | ||
135 | | ;implicitly has ext precision | ||
136 | | ;in upper word. | ||
137 | movel %d1,L_SCR1(%a6) |save mode bits | ||
138 | | | ||
139 | | Real work of sint is in sintexc | ||
140 | | | ||
141 | sintexc: | ||
142 | bclrb #sign_bit,LOCAL_EX(%a0) |convert to internal extended | ||
143 | | ;format | ||
144 | sne LOCAL_SGN(%a0) | ||
145 | cmpw #0x403e,LOCAL_EX(%a0) |check if (unbiased) exp > 63 | ||
146 | bgts out_rnge |branch if exp < 63 | ||
147 | cmpw #0x3ffd,LOCAL_EX(%a0) |check if (unbiased) exp < 0 | ||
148 | bgt in_rnge |if 63 >= exp > 0, do calc | ||
149 | | | ||
150 | | Input is less than zero. Restore sign, and check for directed | ||
151 | | rounding modes. L_SCR1 contains the rmode in the lower byte. | ||
152 | | | ||
153 | un_rnge: | ||
154 | btstb #1,L_SCR1+3(%a6) |check for rn and rz | ||
155 | beqs un_rnrz | ||
156 | tstb LOCAL_SGN(%a0) |check for sign | ||
157 | bnes un_rmrp_neg | ||
158 | | | ||
159 | | Sign is +. If rp, load +1.0, if rm, load +0.0 | ||
160 | | | ||
161 | cmpib #3,L_SCR1+3(%a6) |check for rp | ||
162 | beqs un_ldpone |if rp, load +1.0 | ||
163 | bsr ld_pzero |if rm, load +0.0 | ||
164 | bra t_inx2 | ||
165 | un_ldpone: | ||
166 | bsr ld_pone | ||
167 | bra t_inx2 | ||
168 | | | ||
169 | | Sign is -. If rm, load -1.0, if rp, load -0.0 | ||
170 | | | ||
171 | un_rmrp_neg: | ||
172 | cmpib #2,L_SCR1+3(%a6) |check for rm | ||
173 | beqs un_ldmone |if rm, load -1.0 | ||
174 | bsr ld_mzero |if rp, load -0.0 | ||
175 | bra t_inx2 | ||
176 | un_ldmone: | ||
177 | bsr ld_mone | ||
178 | bra t_inx2 | ||
179 | | | ||
180 | | Rmode is rn or rz; return signed zero | ||
181 | | | ||
182 | un_rnrz: | ||
183 | tstb LOCAL_SGN(%a0) |check for sign | ||
184 | bnes un_rnrz_neg | ||
185 | bsr ld_pzero | ||
186 | bra t_inx2 | ||
187 | un_rnrz_neg: | ||
188 | bsr ld_mzero | ||
189 | bra t_inx2 | ||
190 | |||
191 | | | ||
192 | | Input is greater than 2^63. All bits are significant. Return | ||
193 | | the input. | ||
194 | | | ||
195 | out_rnge: | ||
196 | bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format | ||
197 | beqs intps | ||
198 | bsetb #sign_bit,LOCAL_EX(%a0) | ||
199 | intps: | ||
200 | fmovel %fpcr,-(%sp) | ||
201 | fmovel #0,%fpcr | ||
202 | fmovex LOCAL_EX(%a0),%fp0 |if exp > 63 | ||
203 | | ;then return X to the user | ||
204 | | ;there are no fraction bits | ||
205 | fmovel (%sp)+,%fpcr | ||
206 | rts | ||
207 | |||
208 | in_rnge: | ||
209 | | ;shift off fraction bits | ||
210 | clrl %d0 |clear d0 - initial g,r,s for | ||
211 | | ;dnrm_lp | ||
212 | movel #0x403e,%d1 |set threshold for dnrm_lp | ||
213 | | ;assumes a0 points to operand | ||
214 | bsr dnrm_lp | ||
215 | | ;returns unnormalized number | ||
216 | | ;pointed by a0 | ||
217 | | ;output d0 supplies g,r,s | ||
218 | | ;used by round | ||
219 | movel L_SCR1(%a6),%d1 |use selected rounding mode | ||
220 | | | ||
221 | | | ||
222 | bsr round |round the unnorm based on users | ||
223 | | ;input a0 ptr to ext X | ||
224 | | ; d0 g,r,s bits | ||
225 | | ; d1 PREC/MODE info | ||
226 | | ;output a0 ptr to rounded result | ||
227 | | ;inexact flag set in USER_FPSR | ||
228 | | ;if initial grs set | ||
229 | | | ||
230 | | normalize the rounded result and store value in fp0 | ||
231 | | | ||
232 | bsr nrm_set |normalize the unnorm | ||
233 | | ;Input: a0 points to operand to | ||
234 | | ;be normalized | ||
235 | | ;Output: a0 points to normalized | ||
236 | | ;result | ||
237 | bfclr LOCAL_SGN(%a0){#0:#8} | ||
238 | beqs nrmrndp | ||
239 | bsetb #sign_bit,LOCAL_EX(%a0) |return to IEEE extended format | ||
240 | nrmrndp: | ||
241 | fmovel %fpcr,-(%sp) | ||
242 | fmovel #0,%fpcr | ||
243 | fmovex LOCAL_EX(%a0),%fp0 |move result to fp0 | ||
244 | fmovel (%sp)+,%fpcr | ||
245 | rts | ||
246 | |||
247 | |end | ||