diff options
Diffstat (limited to 'arch/m68k/fpsp040/do_func.S')
-rw-r--r-- | arch/m68k/fpsp040/do_func.S | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/arch/m68k/fpsp040/do_func.S b/arch/m68k/fpsp040/do_func.S new file mode 100644 index 000000000000..81f6a9856dce --- /dev/null +++ b/arch/m68k/fpsp040/do_func.S | |||
@@ -0,0 +1,559 @@ | |||
1 | | | ||
2 | | do_func.sa 3.4 2/18/91 | ||
3 | | | ||
4 | | Do_func performs the unimplemented operation. The operation | ||
5 | | to be performed is determined from the lower 7 bits of the | ||
6 | | extension word (except in the case of fmovecr and fsincos). | ||
7 | | The opcode and tag bits form an index into a jump table in | ||
8 | | tbldo.sa. Cases of zero, infinity and NaN are handled in | ||
9 | | do_func by forcing the default result. Normalized and | ||
10 | | denormalized (there are no unnormalized numbers at this | ||
11 | | point) are passed onto the emulation code. | ||
12 | | | ||
13 | | CMDREG1B and STAG are extracted from the fsave frame | ||
14 | | and combined to form the table index. The function called | ||
15 | | will start with a0 pointing to the ETEMP operand. Dyadic | ||
16 | | functions can find FPTEMP at -12(a0). | ||
17 | | | ||
18 | | Called functions return their result in fp0. Sincos returns | ||
19 | | sin(x) in fp0 and cos(x) in fp1. | ||
20 | | | ||
21 | |||
22 | | Copyright (C) Motorola, Inc. 1990 | ||
23 | | All Rights Reserved | ||
24 | | | ||
25 | | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA | ||
26 | | The copyright notice above does not evidence any | ||
27 | | actual or intended publication of such source code. | ||
28 | |||
29 | DO_FUNC: |idnt 2,1 | Motorola 040 Floating Point Software Package | ||
30 | |||
31 | |section 8 | ||
32 | |||
33 | #include "fpsp.h" | ||
34 | |||
35 | |xref t_dz2 | ||
36 | |xref t_operr | ||
37 | |xref t_inx2 | ||
38 | |xref t_resdnrm | ||
39 | |xref dst_nan | ||
40 | |xref src_nan | ||
41 | |xref nrm_set | ||
42 | |xref sto_cos | ||
43 | |||
44 | |xref tblpre | ||
45 | |xref slognp1,slogn,slog10,slog2 | ||
46 | |xref slognd,slog10d,slog2d | ||
47 | |xref smod,srem | ||
48 | |xref sscale | ||
49 | |xref smovcr | ||
50 | |||
51 | PONE: .long 0x3fff0000,0x80000000,0x00000000 |+1 | ||
52 | MONE: .long 0xbfff0000,0x80000000,0x00000000 |-1 | ||
53 | PZERO: .long 0x00000000,0x00000000,0x00000000 |+0 | ||
54 | MZERO: .long 0x80000000,0x00000000,0x00000000 |-0 | ||
55 | PINF: .long 0x7fff0000,0x00000000,0x00000000 |+inf | ||
56 | MINF: .long 0xffff0000,0x00000000,0x00000000 |-inf | ||
57 | QNAN: .long 0x7fff0000,0xffffffff,0xffffffff |non-signaling nan | ||
58 | PPIBY2: .long 0x3FFF0000,0xC90FDAA2,0x2168C235 |+PI/2 | ||
59 | MPIBY2: .long 0xbFFF0000,0xC90FDAA2,0x2168C235 |-PI/2 | ||
60 | |||
61 | .global do_func | ||
62 | do_func: | ||
63 | clrb CU_ONLY(%a6) | ||
64 | | | ||
65 | | Check for fmovecr. It does not follow the format of fp gen | ||
66 | | unimplemented instructions. The test is on the upper 6 bits; | ||
67 | | if they are $17, the inst is fmovecr. Call entry smovcr | ||
68 | | directly. | ||
69 | | | ||
70 | bfextu CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields | ||
71 | cmpil #0x17,%d0 |if op class and size fields are $17, | ||
72 | | ;it is FMOVECR; if not, continue | ||
73 | bnes not_fmovecr | ||
74 | jmp smovcr |fmovecr; jmp directly to emulation | ||
75 | |||
76 | not_fmovecr: | ||
77 | movew CMDREG1B(%a6),%d0 | ||
78 | andl #0x7F,%d0 | ||
79 | cmpil #0x38,%d0 |if the extension is >= $38, | ||
80 | bge serror |it is illegal | ||
81 | bfextu STAG(%a6){#0:#3},%d1 | ||
82 | lsll #3,%d0 |make room for STAG | ||
83 | addl %d1,%d0 |combine for final index into table | ||
84 | leal tblpre,%a1 |start of monster jump table | ||
85 | movel (%a1,%d0.w*4),%a1 |real target address | ||
86 | leal ETEMP(%a6),%a0 |a0 is pointer to src op | ||
87 | movel USER_FPCR(%a6),%d1 | ||
88 | andl #0xFF,%d1 | discard all but rounding mode/prec | ||
89 | fmovel #0,%fpcr | ||
90 | jmp (%a1) | ||
91 | | | ||
92 | | ERROR | ||
93 | | | ||
94 | .global serror | ||
95 | serror: | ||
96 | st STORE_FLG(%a6) | ||
97 | rts | ||
98 | | | ||
99 | | These routines load forced values into fp0. They are called | ||
100 | | by index into tbldo. | ||
101 | | | ||
102 | | Load a signed zero to fp0 and set inex2/ainex | ||
103 | | | ||
104 | .global snzrinx | ||
105 | snzrinx: | ||
106 | btstb #sign_bit,LOCAL_EX(%a0) |get sign of source operand | ||
107 | bnes ld_mzinx |if negative, branch | ||
108 | bsr ld_pzero |bsr so we can return and set inx | ||
109 | bra t_inx2 |now, set the inx for the next inst | ||
110 | ld_mzinx: | ||
111 | bsr ld_mzero |if neg, load neg zero, return here | ||
112 | bra t_inx2 |now, set the inx for the next inst | ||
113 | | | ||
114 | | Load a signed zero to fp0; do not set inex2/ainex | ||
115 | | | ||
116 | .global szero | ||
117 | szero: | ||
118 | btstb #sign_bit,LOCAL_EX(%a0) |get sign of source operand | ||
119 | bne ld_mzero |if neg, load neg zero | ||
120 | bra ld_pzero |load positive zero | ||
121 | | | ||
122 | | Load a signed infinity to fp0; do not set inex2/ainex | ||
123 | | | ||
124 | .global sinf | ||
125 | sinf: | ||
126 | btstb #sign_bit,LOCAL_EX(%a0) |get sign of source operand | ||
127 | bne ld_minf |if negative branch | ||
128 | bra ld_pinf | ||
129 | | | ||
130 | | Load a signed one to fp0; do not set inex2/ainex | ||
131 | | | ||
132 | .global sone | ||
133 | sone: | ||
134 | btstb #sign_bit,LOCAL_EX(%a0) |check sign of source | ||
135 | bne ld_mone | ||
136 | bra ld_pone | ||
137 | | | ||
138 | | Load a signed pi/2 to fp0; do not set inex2/ainex | ||
139 | | | ||
140 | .global spi_2 | ||
141 | spi_2: | ||
142 | btstb #sign_bit,LOCAL_EX(%a0) |check sign of source | ||
143 | bne ld_mpi2 | ||
144 | bra ld_ppi2 | ||
145 | | | ||
146 | | Load either a +0 or +inf for plus/minus operand | ||
147 | | | ||
148 | .global szr_inf | ||
149 | szr_inf: | ||
150 | btstb #sign_bit,LOCAL_EX(%a0) |check sign of source | ||
151 | bne ld_pzero | ||
152 | bra ld_pinf | ||
153 | | | ||
154 | | Result is either an operr or +inf for plus/minus operand | ||
155 | | [Used by slogn, slognp1, slog10, and slog2] | ||
156 | | | ||
157 | .global sopr_inf | ||
158 | sopr_inf: | ||
159 | btstb #sign_bit,LOCAL_EX(%a0) |check sign of source | ||
160 | bne t_operr | ||
161 | bra ld_pinf | ||
162 | | | ||
163 | | FLOGNP1 | ||
164 | | | ||
165 | .global sslognp1 | ||
166 | sslognp1: | ||
167 | fmovemx (%a0),%fp0-%fp0 | ||
168 | fcmpb #-1,%fp0 | ||
169 | fbgt slognp1 | ||
170 | fbeq t_dz2 |if = -1, divide by zero exception | ||
171 | fmovel #0,%FPSR |clr N flag | ||
172 | bra t_operr |take care of operands < -1 | ||
173 | | | ||
174 | | FETOXM1 | ||
175 | | | ||
176 | .global setoxm1i | ||
177 | setoxm1i: | ||
178 | btstb #sign_bit,LOCAL_EX(%a0) |check sign of source | ||
179 | bne ld_mone | ||
180 | bra ld_pinf | ||
181 | | | ||
182 | | FLOGN | ||
183 | | | ||
184 | | Test for 1.0 as an input argument, returning +zero. Also check | ||
185 | | the sign and return operr if negative. | ||
186 | | | ||
187 | .global sslogn | ||
188 | sslogn: | ||
189 | btstb #sign_bit,LOCAL_EX(%a0) | ||
190 | bne t_operr |take care of operands < 0 | ||
191 | cmpiw #0x3fff,LOCAL_EX(%a0) |test for 1.0 input | ||
192 | bne slogn | ||
193 | cmpil #0x80000000,LOCAL_HI(%a0) | ||
194 | bne slogn | ||
195 | tstl LOCAL_LO(%a0) | ||
196 | bne slogn | ||
197 | fmovex PZERO,%fp0 | ||
198 | rts | ||
199 | |||
200 | .global sslognd | ||
201 | sslognd: | ||
202 | btstb #sign_bit,LOCAL_EX(%a0) | ||
203 | beq slognd | ||
204 | bra t_operr |take care of operands < 0 | ||
205 | |||
206 | | | ||
207 | | FLOG10 | ||
208 | | | ||
209 | .global sslog10 | ||
210 | sslog10: | ||
211 | btstb #sign_bit,LOCAL_EX(%a0) | ||
212 | bne t_operr |take care of operands < 0 | ||
213 | cmpiw #0x3fff,LOCAL_EX(%a0) |test for 1.0 input | ||
214 | bne slog10 | ||
215 | cmpil #0x80000000,LOCAL_HI(%a0) | ||
216 | bne slog10 | ||
217 | tstl LOCAL_LO(%a0) | ||
218 | bne slog10 | ||
219 | fmovex PZERO,%fp0 | ||
220 | rts | ||
221 | |||
222 | .global sslog10d | ||
223 | sslog10d: | ||
224 | btstb #sign_bit,LOCAL_EX(%a0) | ||
225 | beq slog10d | ||
226 | bra t_operr |take care of operands < 0 | ||
227 | |||
228 | | | ||
229 | | FLOG2 | ||
230 | | | ||
231 | .global sslog2 | ||
232 | sslog2: | ||
233 | btstb #sign_bit,LOCAL_EX(%a0) | ||
234 | bne t_operr |take care of operands < 0 | ||
235 | cmpiw #0x3fff,LOCAL_EX(%a0) |test for 1.0 input | ||
236 | bne slog2 | ||
237 | cmpil #0x80000000,LOCAL_HI(%a0) | ||
238 | bne slog2 | ||
239 | tstl LOCAL_LO(%a0) | ||
240 | bne slog2 | ||
241 | fmovex PZERO,%fp0 | ||
242 | rts | ||
243 | |||
244 | .global sslog2d | ||
245 | sslog2d: | ||
246 | btstb #sign_bit,LOCAL_EX(%a0) | ||
247 | beq slog2d | ||
248 | bra t_operr |take care of operands < 0 | ||
249 | |||
250 | | | ||
251 | | FMOD | ||
252 | | | ||
253 | pmodt: | ||
254 | | ;$21 fmod | ||
255 | | ;dtag,stag | ||
256 | .long smod | 00,00 norm,norm = normal | ||
257 | .long smod_oper | 00,01 norm,zero = nan with operr | ||
258 | .long smod_fpn | 00,10 norm,inf = fpn | ||
259 | .long smod_snan | 00,11 norm,nan = nan | ||
260 | .long smod_zro | 01,00 zero,norm = +-zero | ||
261 | .long smod_oper | 01,01 zero,zero = nan with operr | ||
262 | .long smod_zro | 01,10 zero,inf = +-zero | ||
263 | .long smod_snan | 01,11 zero,nan = nan | ||
264 | .long smod_oper | 10,00 inf,norm = nan with operr | ||
265 | .long smod_oper | 10,01 inf,zero = nan with operr | ||
266 | .long smod_oper | 10,10 inf,inf = nan with operr | ||
267 | .long smod_snan | 10,11 inf,nan = nan | ||
268 | .long smod_dnan | 11,00 nan,norm = nan | ||
269 | .long smod_dnan | 11,01 nan,zero = nan | ||
270 | .long smod_dnan | 11,10 nan,inf = nan | ||
271 | .long smod_dnan | 11,11 nan,nan = nan | ||
272 | |||
273 | .global pmod | ||
274 | pmod: | ||
275 | clrb FPSR_QBYTE(%a6) | clear quotient field | ||
276 | bfextu STAG(%a6){#0:#3},%d0 |stag = d0 | ||
277 | bfextu DTAG(%a6){#0:#3},%d1 |dtag = d1 | ||
278 | |||
279 | | | ||
280 | | Alias extended denorms to norms for the jump table. | ||
281 | | | ||
282 | bclrl #2,%d0 | ||
283 | bclrl #2,%d1 | ||
284 | |||
285 | lslb #2,%d1 | ||
286 | orb %d0,%d1 |d1{3:2} = dtag, d1{1:0} = stag | ||
287 | | ;Tag values: | ||
288 | | ;00 = norm or denorm | ||
289 | | ;01 = zero | ||
290 | | ;10 = inf | ||
291 | | ;11 = nan | ||
292 | lea pmodt,%a1 | ||
293 | movel (%a1,%d1.w*4),%a1 | ||
294 | jmp (%a1) | ||
295 | |||
296 | smod_snan: | ||
297 | bra src_nan | ||
298 | smod_dnan: | ||
299 | bra dst_nan | ||
300 | smod_oper: | ||
301 | bra t_operr | ||
302 | smod_zro: | ||
303 | moveb ETEMP(%a6),%d1 |get sign of src op | ||
304 | moveb FPTEMP(%a6),%d0 |get sign of dst op | ||
305 | eorb %d0,%d1 |get exor of sign bits | ||
306 | btstl #7,%d1 |test for sign | ||
307 | beqs smod_zsn |if clr, do not set sign big | ||
308 | bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit | ||
309 | smod_zsn: | ||
310 | btstl #7,%d0 |test if + or - | ||
311 | beq ld_pzero |if pos then load +0 | ||
312 | bra ld_mzero |else neg load -0 | ||
313 | |||
314 | smod_fpn: | ||
315 | moveb ETEMP(%a6),%d1 |get sign of src op | ||
316 | moveb FPTEMP(%a6),%d0 |get sign of dst op | ||
317 | eorb %d0,%d1 |get exor of sign bits | ||
318 | btstl #7,%d1 |test for sign | ||
319 | beqs smod_fsn |if clr, do not set sign big | ||
320 | bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit | ||
321 | smod_fsn: | ||
322 | tstb DTAG(%a6) |filter out denormal destination case | ||
323 | bpls smod_nrm | | ||
324 | leal FPTEMP(%a6),%a0 |a0<- addr(FPTEMP) | ||
325 | bra t_resdnrm |force UNFL(but exact) result | ||
326 | smod_nrm: | ||
327 | fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision | ||
328 | fmovex FPTEMP(%a6),%fp0 |return dest to fp0 | ||
329 | rts | ||
330 | |||
331 | | | ||
332 | | FREM | ||
333 | | | ||
334 | premt: | ||
335 | | ;$25 frem | ||
336 | | ;dtag,stag | ||
337 | .long srem | 00,00 norm,norm = normal | ||
338 | .long srem_oper | 00,01 norm,zero = nan with operr | ||
339 | .long srem_fpn | 00,10 norm,inf = fpn | ||
340 | .long srem_snan | 00,11 norm,nan = nan | ||
341 | .long srem_zro | 01,00 zero,norm = +-zero | ||
342 | .long srem_oper | 01,01 zero,zero = nan with operr | ||
343 | .long srem_zro | 01,10 zero,inf = +-zero | ||
344 | .long srem_snan | 01,11 zero,nan = nan | ||
345 | .long srem_oper | 10,00 inf,norm = nan with operr | ||
346 | .long srem_oper | 10,01 inf,zero = nan with operr | ||
347 | .long srem_oper | 10,10 inf,inf = nan with operr | ||
348 | .long srem_snan | 10,11 inf,nan = nan | ||
349 | .long srem_dnan | 11,00 nan,norm = nan | ||
350 | .long srem_dnan | 11,01 nan,zero = nan | ||
351 | .long srem_dnan | 11,10 nan,inf = nan | ||
352 | .long srem_dnan | 11,11 nan,nan = nan | ||
353 | |||
354 | .global prem | ||
355 | prem: | ||
356 | clrb FPSR_QBYTE(%a6) |clear quotient field | ||
357 | bfextu STAG(%a6){#0:#3},%d0 |stag = d0 | ||
358 | bfextu DTAG(%a6){#0:#3},%d1 |dtag = d1 | ||
359 | | | ||
360 | | Alias extended denorms to norms for the jump table. | ||
361 | | | ||
362 | bclr #2,%d0 | ||
363 | bclr #2,%d1 | ||
364 | |||
365 | lslb #2,%d1 | ||
366 | orb %d0,%d1 |d1{3:2} = dtag, d1{1:0} = stag | ||
367 | | ;Tag values: | ||
368 | | ;00 = norm or denorm | ||
369 | | ;01 = zero | ||
370 | | ;10 = inf | ||
371 | | ;11 = nan | ||
372 | lea premt,%a1 | ||
373 | movel (%a1,%d1.w*4),%a1 | ||
374 | jmp (%a1) | ||
375 | |||
376 | srem_snan: | ||
377 | bra src_nan | ||
378 | srem_dnan: | ||
379 | bra dst_nan | ||
380 | srem_oper: | ||
381 | bra t_operr | ||
382 | srem_zro: | ||
383 | moveb ETEMP(%a6),%d1 |get sign of src op | ||
384 | moveb FPTEMP(%a6),%d0 |get sign of dst op | ||
385 | eorb %d0,%d1 |get exor of sign bits | ||
386 | btstl #7,%d1 |test for sign | ||
387 | beqs srem_zsn |if clr, do not set sign big | ||
388 | bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit | ||
389 | srem_zsn: | ||
390 | btstl #7,%d0 |test if + or - | ||
391 | beq ld_pzero |if pos then load +0 | ||
392 | bra ld_mzero |else neg load -0 | ||
393 | |||
394 | srem_fpn: | ||
395 | moveb ETEMP(%a6),%d1 |get sign of src op | ||
396 | moveb FPTEMP(%a6),%d0 |get sign of dst op | ||
397 | eorb %d0,%d1 |get exor of sign bits | ||
398 | btstl #7,%d1 |test for sign | ||
399 | beqs srem_fsn |if clr, do not set sign big | ||
400 | bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit | ||
401 | srem_fsn: | ||
402 | tstb DTAG(%a6) |filter out denormal destination case | ||
403 | bpls srem_nrm | | ||
404 | leal FPTEMP(%a6),%a0 |a0<- addr(FPTEMP) | ||
405 | bra t_resdnrm |force UNFL(but exact) result | ||
406 | srem_nrm: | ||
407 | fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision | ||
408 | fmovex FPTEMP(%a6),%fp0 |return dest to fp0 | ||
409 | rts | ||
410 | | | ||
411 | | FSCALE | ||
412 | | | ||
413 | pscalet: | ||
414 | | ;$26 fscale | ||
415 | | ;dtag,stag | ||
416 | .long sscale | 00,00 norm,norm = result | ||
417 | .long sscale | 00,01 norm,zero = fpn | ||
418 | .long scl_opr | 00,10 norm,inf = nan with operr | ||
419 | .long scl_snan | 00,11 norm,nan = nan | ||
420 | .long scl_zro | 01,00 zero,norm = +-zero | ||
421 | .long scl_zro | 01,01 zero,zero = +-zero | ||
422 | .long scl_opr | 01,10 zero,inf = nan with operr | ||
423 | .long scl_snan | 01,11 zero,nan = nan | ||
424 | .long scl_inf | 10,00 inf,norm = +-inf | ||
425 | .long scl_inf | 10,01 inf,zero = +-inf | ||
426 | .long scl_opr | 10,10 inf,inf = nan with operr | ||
427 | .long scl_snan | 10,11 inf,nan = nan | ||
428 | .long scl_dnan | 11,00 nan,norm = nan | ||
429 | .long scl_dnan | 11,01 nan,zero = nan | ||
430 | .long scl_dnan | 11,10 nan,inf = nan | ||
431 | .long scl_dnan | 11,11 nan,nan = nan | ||
432 | |||
433 | .global pscale | ||
434 | pscale: | ||
435 | bfextu STAG(%a6){#0:#3},%d0 |stag in d0 | ||
436 | bfextu DTAG(%a6){#0:#3},%d1 |dtag in d1 | ||
437 | bclrl #2,%d0 |alias denorm into norm | ||
438 | bclrl #2,%d1 |alias denorm into norm | ||
439 | lslb #2,%d1 | ||
440 | orb %d0,%d1 |d1{4:2} = dtag, d1{1:0} = stag | ||
441 | | ;dtag values stag values: | ||
442 | | ;000 = norm 00 = norm | ||
443 | | ;001 = zero 01 = zero | ||
444 | | ;010 = inf 10 = inf | ||
445 | | ;011 = nan 11 = nan | ||
446 | | ;100 = dnrm | ||
447 | | | ||
448 | | | ||
449 | leal pscalet,%a1 |load start of jump table | ||
450 | movel (%a1,%d1.w*4),%a1 |load a1 with label depending on tag | ||
451 | jmp (%a1) |go to the routine | ||
452 | |||
453 | scl_opr: | ||
454 | bra t_operr | ||
455 | |||
456 | scl_dnan: | ||
457 | bra dst_nan | ||
458 | |||
459 | scl_zro: | ||
460 | btstb #sign_bit,FPTEMP_EX(%a6) |test if + or - | ||
461 | beq ld_pzero |if pos then load +0 | ||
462 | bra ld_mzero |if neg then load -0 | ||
463 | scl_inf: | ||
464 | btstb #sign_bit,FPTEMP_EX(%a6) |test if + or - | ||
465 | beq ld_pinf |if pos then load +inf | ||
466 | bra ld_minf |else neg load -inf | ||
467 | scl_snan: | ||
468 | bra src_nan | ||
469 | | | ||
470 | | FSINCOS | ||
471 | | | ||
472 | .global ssincosz | ||
473 | ssincosz: | ||
474 | btstb #sign_bit,ETEMP(%a6) |get sign | ||
475 | beqs sincosp | ||
476 | fmovex MZERO,%fp0 | ||
477 | bras sincoscom | ||
478 | sincosp: | ||
479 | fmovex PZERO,%fp0 | ||
480 | sincoscom: | ||
481 | fmovemx PONE,%fp1-%fp1 |do not allow FPSR to be affected | ||
482 | bra sto_cos |store cosine result | ||
483 | |||
484 | .global ssincosi | ||
485 | ssincosi: | ||
486 | fmovex QNAN,%fp1 |load NAN | ||
487 | bsr sto_cos |store cosine result | ||
488 | fmovex QNAN,%fp0 |load NAN | ||
489 | bra t_operr | ||
490 | |||
491 | .global ssincosnan | ||
492 | ssincosnan: | ||
493 | movel ETEMP_EX(%a6),FP_SCR1(%a6) | ||
494 | movel ETEMP_HI(%a6),FP_SCR1+4(%a6) | ||
495 | movel ETEMP_LO(%a6),FP_SCR1+8(%a6) | ||
496 | bsetb #signan_bit,FP_SCR1+4(%a6) | ||
497 | fmovemx FP_SCR1(%a6),%fp1-%fp1 | ||
498 | bsr sto_cos | ||
499 | bra src_nan | ||
500 | | | ||
501 | | This code forces default values for the zero, inf, and nan cases | ||
502 | | in the transcendentals code. The CC bits must be set in the | ||
503 | | stacked FPSR to be correctly reported. | ||
504 | | | ||
505 | |**Returns +PI/2 | ||
506 | .global ld_ppi2 | ||
507 | ld_ppi2: | ||
508 | fmovex PPIBY2,%fp0 |load +pi/2 | ||
509 | bra t_inx2 |set inex2 exc | ||
510 | |||
511 | |**Returns -PI/2 | ||
512 | .global ld_mpi2 | ||
513 | ld_mpi2: | ||
514 | fmovex MPIBY2,%fp0 |load -pi/2 | ||
515 | orl #neg_mask,USER_FPSR(%a6) |set N bit | ||
516 | bra t_inx2 |set inex2 exc | ||
517 | |||
518 | |**Returns +inf | ||
519 | .global ld_pinf | ||
520 | ld_pinf: | ||
521 | fmovex PINF,%fp0 |load +inf | ||
522 | orl #inf_mask,USER_FPSR(%a6) |set I bit | ||
523 | rts | ||
524 | |||
525 | |**Returns -inf | ||
526 | .global ld_minf | ||
527 | ld_minf: | ||
528 | fmovex MINF,%fp0 |load -inf | ||
529 | orl #neg_mask+inf_mask,USER_FPSR(%a6) |set N and I bits | ||
530 | rts | ||
531 | |||
532 | |**Returns +1 | ||
533 | .global ld_pone | ||
534 | ld_pone: | ||
535 | fmovex PONE,%fp0 |load +1 | ||
536 | rts | ||
537 | |||
538 | |**Returns -1 | ||
539 | .global ld_mone | ||
540 | ld_mone: | ||
541 | fmovex MONE,%fp0 |load -1 | ||
542 | orl #neg_mask,USER_FPSR(%a6) |set N bit | ||
543 | rts | ||
544 | |||
545 | |**Returns +0 | ||
546 | .global ld_pzero | ||
547 | ld_pzero: | ||
548 | fmovex PZERO,%fp0 |load +0 | ||
549 | orl #z_mask,USER_FPSR(%a6) |set Z bit | ||
550 | rts | ||
551 | |||
552 | |**Returns -0 | ||
553 | .global ld_mzero | ||
554 | ld_mzero: | ||
555 | fmovex MZERO,%fp0 |load -0 | ||
556 | orl #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z bits | ||
557 | rts | ||
558 | |||
559 | |end | ||