do_func.sa revision 1.3 1 1.3 briggs * $NetBSD: do_func.sa,v 1.3 2001/12/09 01:43:13 briggs Exp $
2 1.2 cgd
3 1.1 mycroft * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 1.1 mycroft * M68000 Hi-Performance Microprocessor Division
5 1.1 mycroft * M68040 Software Package
6 1.1 mycroft *
7 1.1 mycroft * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8 1.1 mycroft * All rights reserved.
9 1.1 mycroft *
10 1.1 mycroft * THE SOFTWARE is provided on an "AS IS" basis and without warranty.
11 1.1 mycroft * To the maximum extent permitted by applicable law,
12 1.1 mycroft * MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
13 1.1 mycroft * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
14 1.1 mycroft * PARTICULAR PURPOSE and any warranty against infringement with
15 1.1 mycroft * regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
16 1.1 mycroft * and any accompanying written materials.
17 1.1 mycroft *
18 1.1 mycroft * To the maximum extent permitted by applicable law,
19 1.1 mycroft * IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
20 1.1 mycroft * (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
21 1.1 mycroft * PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
22 1.1 mycroft * OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
23 1.1 mycroft * SOFTWARE. Motorola assumes no responsibility for the maintenance
24 1.1 mycroft * and support of the SOFTWARE.
25 1.1 mycroft *
26 1.1 mycroft * You are hereby granted a copyright license to use, modify, and
27 1.1 mycroft * distribute the SOFTWARE so long as this entire notice is retained
28 1.1 mycroft * without alteration in any modified and/or redistributed versions,
29 1.1 mycroft * and that such modified versions are clearly identified as such.
30 1.1 mycroft * No licenses are granted by implication, estoppel or otherwise
31 1.1 mycroft * under any patents or trademarks of Motorola, Inc.
32 1.1 mycroft
33 1.1 mycroft *
34 1.1 mycroft * do_func.sa 3.4 2/18/91
35 1.1 mycroft *
36 1.1 mycroft * Do_func performs the unimplemented operation. The operation
37 1.1 mycroft * to be performed is determined from the lower 7 bits of the
38 1.1 mycroft * extension word (except in the case of fmovecr and fsincos).
39 1.1 mycroft * The opcode and tag bits form an index into a jump table in
40 1.1 mycroft * tbldo.sa. Cases of zero, infinity and NaN are handled in
41 1.1 mycroft * do_func by forcing the default result. Normalized and
42 1.1 mycroft * denormalized (there are no unnormalized numbers at this
43 1.1 mycroft * point) are passed onto the emulation code.
44 1.1 mycroft *
45 1.1 mycroft * CMDREG1B and STAG are extracted from the fsave frame
46 1.1 mycroft * and combined to form the table index. The function called
47 1.1 mycroft * will start with a0 pointing to the ETEMP operand. Dyadic
48 1.1 mycroft * functions can find FPTEMP at -12(a0).
49 1.1 mycroft *
50 1.1 mycroft * Called functions return their result in fp0. Sincos returns
51 1.1 mycroft * sin(x) in fp0 and cos(x) in fp1.
52 1.1 mycroft *
53 1.1 mycroft
54 1.1 mycroft DO_FUNC IDNT 2,1 Motorola 040 Floating Point Software Package
55 1.1 mycroft
56 1.1 mycroft section 8
57 1.1 mycroft
58 1.1 mycroft include fpsp.h
59 1.1 mycroft
60 1.1 mycroft xref t_dz2
61 1.1 mycroft xref t_operr
62 1.1 mycroft xref t_inx2
63 1.1 mycroft xref t_resdnrm
64 1.1 mycroft xref dst_nan
65 1.1 mycroft xref src_nan
66 1.1 mycroft xref nrm_set
67 1.1 mycroft xref sto_cos
68 1.1 mycroft
69 1.1 mycroft xref tblpre
70 1.1 mycroft xref slognp1,slogn,slog10,slog2
71 1.1 mycroft xref slognd,slog10d,slog2d
72 1.1 mycroft xref smod,srem
73 1.1 mycroft xref sscale
74 1.1 mycroft xref smovcr
75 1.1 mycroft
76 1.1 mycroft PONE dc.l $3fff0000,$80000000,$00000000 ;+1
77 1.1 mycroft MONE dc.l $bfff0000,$80000000,$00000000 ;-1
78 1.1 mycroft PZERO dc.l $00000000,$00000000,$00000000 ;+0
79 1.1 mycroft MZERO dc.l $80000000,$00000000,$00000000 ;-0
80 1.1 mycroft PINF dc.l $7fff0000,$00000000,$00000000 ;+inf
81 1.1 mycroft MINF dc.l $ffff0000,$00000000,$00000000 ;-inf
82 1.1 mycroft QNAN dc.l $7fff0000,$ffffffff,$ffffffff ;non-signaling nan
83 1.1 mycroft PPIBY2 dc.l $3FFF0000,$C90FDAA2,$2168C235 ;+PI/2
84 1.1 mycroft MPIBY2 dc.l $bFFF0000,$C90FDAA2,$2168C235 ;-PI/2
85 1.1 mycroft
86 1.1 mycroft xdef do_func
87 1.1 mycroft do_func:
88 1.1 mycroft clr.b CU_ONLY(a6)
89 1.1 mycroft *
90 1.1 mycroft * Check for fmovecr. It does not follow the format of fp gen
91 1.1 mycroft * unimplemented instructions. The test is on the upper 6 bits;
92 1.1 mycroft * if they are $17, the inst is fmovecr. Call entry smovcr
93 1.1 mycroft * directly.
94 1.1 mycroft *
95 1.1 mycroft bfextu CMDREG1B(a6){0:6},d0 ;get opclass and src fields
96 1.1 mycroft cmpi.l #$17,d0 ;if op class and size fields are $17,
97 1.1 mycroft * ;it is FMOVECR; if not, continue
98 1.1 mycroft bne.b not_fmovecr
99 1.1 mycroft jmp smovcr ;fmovecr; jmp directly to emulation
100 1.1 mycroft
101 1.1 mycroft not_fmovecr:
102 1.1 mycroft move.w CMDREG1B(a6),d0
103 1.1 mycroft and.l #$7F,d0
104 1.1 mycroft cmpi.l #$38,d0 ;if the extension is >= $38,
105 1.3 briggs bge.b short_serror ;it is illegal
106 1.1 mycroft bfextu STAG(a6){0:3},d1
107 1.1 mycroft lsl.l #3,d0 ;make room for STAG
108 1.1 mycroft add.l d1,d0 ;combine for final index into table
109 1.1 mycroft lea.l tblpre,a1 ;start of monster jump table
110 1.1 mycroft move.l (a1,d0.w*4),a1 ;real target address
111 1.1 mycroft lea.l ETEMP(a6),a0 ;a0 is pointer to src op
112 1.1 mycroft move.l USER_FPCR(a6),d1
113 1.1 mycroft and.l #$FF,d1 ; discard all but rounding mode/prec
114 1.1 mycroft fmove.l #0,fpcr
115 1.1 mycroft jmp (a1)
116 1.1 mycroft *
117 1.1 mycroft * ERROR
118 1.1 mycroft *
119 1.1 mycroft xdef serror
120 1.1 mycroft serror:
121 1.3 briggs short_serror:
122 1.1 mycroft st.b STORE_FLG(a6)
123 1.1 mycroft rts
124 1.1 mycroft *
125 1.1 mycroft * These routines load forced values into fp0. They are called
126 1.1 mycroft * by index into tbldo.
127 1.1 mycroft *
128 1.1 mycroft * Load a signed zero to fp0 and set inex2/ainex
129 1.1 mycroft *
130 1.1 mycroft xdef snzrinx
131 1.1 mycroft snzrinx:
132 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;get sign of source operand
133 1.1 mycroft bne.b ld_mzinx ;if negative, branch
134 1.1 mycroft bsr ld_pzero ;bsr so we can return and set inx
135 1.1 mycroft bra t_inx2 ;now, set the inx for the next inst
136 1.1 mycroft ld_mzinx:
137 1.1 mycroft bsr ld_mzero ;if neg, load neg zero, return here
138 1.1 mycroft bra t_inx2 ;now, set the inx for the next inst
139 1.1 mycroft *
140 1.1 mycroft * Load a signed zero to fp0; do not set inex2/ainex
141 1.1 mycroft *
142 1.1 mycroft xdef szero
143 1.1 mycroft szero:
144 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;get sign of source operand
145 1.1 mycroft bne ld_mzero ;if neg, load neg zero
146 1.1 mycroft bra ld_pzero ;load positive zero
147 1.1 mycroft *
148 1.1 mycroft * Load a signed infinity to fp0; do not set inex2/ainex
149 1.1 mycroft *
150 1.1 mycroft xdef sinf
151 1.1 mycroft sinf:
152 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;get sign of source operand
153 1.1 mycroft bne ld_minf ;if negative branch
154 1.1 mycroft bra ld_pinf
155 1.1 mycroft *
156 1.1 mycroft * Load a signed one to fp0; do not set inex2/ainex
157 1.1 mycroft *
158 1.1 mycroft xdef sone
159 1.1 mycroft sone:
160 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
161 1.1 mycroft bne ld_mone
162 1.1 mycroft bra ld_pone
163 1.1 mycroft *
164 1.1 mycroft * Load a signed pi/2 to fp0; do not set inex2/ainex
165 1.1 mycroft *
166 1.1 mycroft xdef spi_2
167 1.1 mycroft spi_2:
168 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
169 1.1 mycroft bne ld_mpi2
170 1.1 mycroft bra ld_ppi2
171 1.1 mycroft *
172 1.1 mycroft * Load either a +0 or +inf for plus/minus operand
173 1.1 mycroft *
174 1.1 mycroft xdef szr_inf
175 1.1 mycroft szr_inf:
176 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
177 1.1 mycroft bne ld_pzero
178 1.1 mycroft bra ld_pinf
179 1.1 mycroft *
180 1.1 mycroft * Result is either an operr or +inf for plus/minus operand
181 1.1 mycroft * [Used by slogn, slognp1, slog10, and slog2]
182 1.1 mycroft *
183 1.1 mycroft xdef sopr_inf
184 1.1 mycroft sopr_inf:
185 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
186 1.1 mycroft bne t_operr
187 1.1 mycroft bra ld_pinf
188 1.1 mycroft *
189 1.1 mycroft * FLOGNP1
190 1.1 mycroft *
191 1.1 mycroft xdef sslognp1
192 1.1 mycroft sslognp1:
193 1.1 mycroft fmovem.x (a0),fp0
194 1.1 mycroft fcmp.b #-1,fp0
195 1.1 mycroft fbgt slognp1
196 1.1 mycroft fbeq t_dz2 ;if = -1, divide by zero exception
197 1.1 mycroft fmove.l #0,FPSR ;clr N flag
198 1.1 mycroft bra t_operr ;take care of operands < -1
199 1.1 mycroft *
200 1.1 mycroft * FETOXM1
201 1.1 mycroft *
202 1.1 mycroft xdef setoxm1i
203 1.1 mycroft setoxm1i:
204 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
205 1.1 mycroft bne ld_mone
206 1.1 mycroft bra ld_pinf
207 1.1 mycroft *
208 1.1 mycroft * FLOGN
209 1.1 mycroft *
210 1.1 mycroft * Test for 1.0 as an input argument, returning +zero. Also check
211 1.1 mycroft * the sign and return operr if negative.
212 1.1 mycroft *
213 1.1 mycroft xdef sslogn
214 1.1 mycroft sslogn:
215 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
216 1.1 mycroft bne t_operr ;take care of operands < 0
217 1.1 mycroft cmpi.w #$3fff,LOCAL_EX(a0) ;test for 1.0 input
218 1.1 mycroft bne slogn
219 1.1 mycroft cmpi.l #$80000000,LOCAL_HI(a0)
220 1.1 mycroft bne slogn
221 1.1 mycroft tst.l LOCAL_LO(a0)
222 1.1 mycroft bne slogn
223 1.1 mycroft fmove.x PZERO,fp0
224 1.1 mycroft rts
225 1.1 mycroft
226 1.1 mycroft xdef sslognd
227 1.1 mycroft sslognd:
228 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
229 1.1 mycroft beq slognd
230 1.1 mycroft bra t_operr ;take care of operands < 0
231 1.1 mycroft
232 1.1 mycroft *
233 1.1 mycroft * FLOG10
234 1.1 mycroft *
235 1.1 mycroft xdef sslog10
236 1.1 mycroft sslog10:
237 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
238 1.1 mycroft bne t_operr ;take care of operands < 0
239 1.1 mycroft cmpi.w #$3fff,LOCAL_EX(a0) ;test for 1.0 input
240 1.1 mycroft bne slog10
241 1.1 mycroft cmpi.l #$80000000,LOCAL_HI(a0)
242 1.1 mycroft bne slog10
243 1.1 mycroft tst.l LOCAL_LO(a0)
244 1.1 mycroft bne slog10
245 1.1 mycroft fmove.x PZERO,fp0
246 1.1 mycroft rts
247 1.1 mycroft
248 1.1 mycroft xdef sslog10d
249 1.1 mycroft sslog10d:
250 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
251 1.1 mycroft beq slog10d
252 1.1 mycroft bra t_operr ;take care of operands < 0
253 1.1 mycroft
254 1.1 mycroft *
255 1.1 mycroft * FLOG2
256 1.1 mycroft *
257 1.1 mycroft xdef sslog2
258 1.1 mycroft sslog2:
259 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
260 1.1 mycroft bne t_operr ;take care of operands < 0
261 1.1 mycroft cmpi.w #$3fff,LOCAL_EX(a0) ;test for 1.0 input
262 1.1 mycroft bne slog2
263 1.1 mycroft cmpi.l #$80000000,LOCAL_HI(a0)
264 1.1 mycroft bne slog2
265 1.1 mycroft tst.l LOCAL_LO(a0)
266 1.1 mycroft bne slog2
267 1.1 mycroft fmove.x PZERO,fp0
268 1.1 mycroft rts
269 1.1 mycroft
270 1.1 mycroft xdef sslog2d
271 1.1 mycroft sslog2d:
272 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
273 1.1 mycroft beq slog2d
274 1.1 mycroft bra t_operr ;take care of operands < 0
275 1.1 mycroft
276 1.1 mycroft *
277 1.1 mycroft * FMOD
278 1.1 mycroft *
279 1.1 mycroft pmodt:
280 1.1 mycroft * ;$21 fmod
281 1.1 mycroft * ;dtag,stag
282 1.1 mycroft dc.l smod ; 00,00 norm,norm = normal
283 1.1 mycroft dc.l smod_oper ; 00,01 norm,zero = nan with operr
284 1.1 mycroft dc.l smod_fpn ; 00,10 norm,inf = fpn
285 1.1 mycroft dc.l smod_snan ; 00,11 norm,nan = nan
286 1.1 mycroft dc.l smod_zro ; 01,00 zero,norm = +-zero
287 1.1 mycroft dc.l smod_oper ; 01,01 zero,zero = nan with operr
288 1.1 mycroft dc.l smod_zro ; 01,10 zero,inf = +-zero
289 1.1 mycroft dc.l smod_snan ; 01,11 zero,nan = nan
290 1.1 mycroft dc.l smod_oper ; 10,00 inf,norm = nan with operr
291 1.1 mycroft dc.l smod_oper ; 10,01 inf,zero = nan with operr
292 1.1 mycroft dc.l smod_oper ; 10,10 inf,inf = nan with operr
293 1.1 mycroft dc.l smod_snan ; 10,11 inf,nan = nan
294 1.1 mycroft dc.l smod_dnan ; 11,00 nan,norm = nan
295 1.1 mycroft dc.l smod_dnan ; 11,01 nan,zero = nan
296 1.1 mycroft dc.l smod_dnan ; 11,10 nan,inf = nan
297 1.1 mycroft dc.l smod_dnan ; 11,11 nan,nan = nan
298 1.1 mycroft
299 1.1 mycroft xdef pmod
300 1.1 mycroft pmod:
301 1.1 mycroft clr.b FPSR_QBYTE(a6) ; clear quotient field
302 1.1 mycroft bfextu STAG(a6){0:3},d0 ;stag = d0
303 1.1 mycroft bfextu DTAG(a6){0:3},d1 ;dtag = d1
304 1.1 mycroft
305 1.1 mycroft *
306 1.1 mycroft * Alias extended denorms to norms for the jump table.
307 1.1 mycroft *
308 1.1 mycroft bclr.l #2,d0
309 1.1 mycroft bclr.l #2,d1
310 1.1 mycroft
311 1.1 mycroft lsl.b #2,d1
312 1.1 mycroft or.b d0,d1 ;d1{3:2} = dtag, d1{1:0} = stag
313 1.1 mycroft * ;Tag values:
314 1.1 mycroft * ;00 = norm or denorm
315 1.1 mycroft * ;01 = zero
316 1.1 mycroft * ;10 = inf
317 1.1 mycroft * ;11 = nan
318 1.1 mycroft lea pmodt,a1
319 1.1 mycroft move.l (a1,d1.w*4),a1
320 1.1 mycroft jmp (a1)
321 1.1 mycroft
322 1.1 mycroft smod_snan:
323 1.1 mycroft bra src_nan
324 1.1 mycroft smod_dnan:
325 1.1 mycroft bra dst_nan
326 1.1 mycroft smod_oper:
327 1.1 mycroft bra t_operr
328 1.1 mycroft smod_zro:
329 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
330 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
331 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
332 1.1 mycroft btst.l #7,d1 ;test for sign
333 1.1 mycroft beq.b smod_zsn ;if clr, do not set sign big
334 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
335 1.1 mycroft smod_zsn:
336 1.1 mycroft btst.l #7,d0 ;test if + or -
337 1.1 mycroft beq ld_pzero ;if pos then load +0
338 1.1 mycroft bra ld_mzero ;else neg load -0
339 1.1 mycroft
340 1.1 mycroft smod_fpn:
341 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
342 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
343 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
344 1.1 mycroft btst.l #7,d1 ;test for sign
345 1.1 mycroft beq.b smod_fsn ;if clr, do not set sign big
346 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
347 1.1 mycroft smod_fsn:
348 1.1 mycroft tst.b DTAG(a6) ;filter out denormal destination case
349 1.1 mycroft bpl.b smod_nrm ;
350 1.1 mycroft lea.l FPTEMP(a6),a0 ;a0<- addr(FPTEMP)
351 1.1 mycroft bra t_resdnrm ;force UNFL(but exact) result
352 1.1 mycroft smod_nrm:
353 1.1 mycroft fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
354 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;return dest to fp0
355 1.1 mycroft rts
356 1.1 mycroft
357 1.1 mycroft *
358 1.1 mycroft * FREM
359 1.1 mycroft *
360 1.1 mycroft premt:
361 1.1 mycroft * ;$25 frem
362 1.1 mycroft * ;dtag,stag
363 1.1 mycroft dc.l srem ; 00,00 norm,norm = normal
364 1.1 mycroft dc.l srem_oper ; 00,01 norm,zero = nan with operr
365 1.1 mycroft dc.l srem_fpn ; 00,10 norm,inf = fpn
366 1.1 mycroft dc.l srem_snan ; 00,11 norm,nan = nan
367 1.1 mycroft dc.l srem_zro ; 01,00 zero,norm = +-zero
368 1.1 mycroft dc.l srem_oper ; 01,01 zero,zero = nan with operr
369 1.1 mycroft dc.l srem_zro ; 01,10 zero,inf = +-zero
370 1.1 mycroft dc.l srem_snan ; 01,11 zero,nan = nan
371 1.1 mycroft dc.l srem_oper ; 10,00 inf,norm = nan with operr
372 1.1 mycroft dc.l srem_oper ; 10,01 inf,zero = nan with operr
373 1.1 mycroft dc.l srem_oper ; 10,10 inf,inf = nan with operr
374 1.1 mycroft dc.l srem_snan ; 10,11 inf,nan = nan
375 1.1 mycroft dc.l srem_dnan ; 11,00 nan,norm = nan
376 1.1 mycroft dc.l srem_dnan ; 11,01 nan,zero = nan
377 1.1 mycroft dc.l srem_dnan ; 11,10 nan,inf = nan
378 1.1 mycroft dc.l srem_dnan ; 11,11 nan,nan = nan
379 1.1 mycroft
380 1.1 mycroft xdef prem
381 1.1 mycroft prem:
382 1.1 mycroft clr.b FPSR_QBYTE(a6) ;clear quotient field
383 1.1 mycroft bfextu STAG(a6){0:3},d0 ;stag = d0
384 1.1 mycroft bfextu DTAG(a6){0:3},d1 ;dtag = d1
385 1.1 mycroft *
386 1.1 mycroft * Alias extended denorms to norms for the jump table.
387 1.1 mycroft *
388 1.1 mycroft bclr #2,d0
389 1.1 mycroft bclr #2,d1
390 1.1 mycroft
391 1.1 mycroft lsl.b #2,d1
392 1.1 mycroft or.b d0,d1 ;d1{3:2} = dtag, d1{1:0} = stag
393 1.1 mycroft * ;Tag values:
394 1.1 mycroft * ;00 = norm or denorm
395 1.1 mycroft * ;01 = zero
396 1.1 mycroft * ;10 = inf
397 1.1 mycroft * ;11 = nan
398 1.1 mycroft lea premt,a1
399 1.1 mycroft move.l (a1,d1.w*4),a1
400 1.1 mycroft jmp (a1)
401 1.1 mycroft
402 1.1 mycroft srem_snan:
403 1.1 mycroft bra src_nan
404 1.1 mycroft srem_dnan:
405 1.1 mycroft bra dst_nan
406 1.1 mycroft srem_oper:
407 1.1 mycroft bra t_operr
408 1.1 mycroft srem_zro:
409 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
410 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
411 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
412 1.1 mycroft btst.l #7,d1 ;test for sign
413 1.1 mycroft beq.b srem_zsn ;if clr, do not set sign big
414 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
415 1.1 mycroft srem_zsn:
416 1.1 mycroft btst.l #7,d0 ;test if + or -
417 1.1 mycroft beq ld_pzero ;if pos then load +0
418 1.1 mycroft bra ld_mzero ;else neg load -0
419 1.1 mycroft
420 1.1 mycroft srem_fpn:
421 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
422 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
423 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
424 1.1 mycroft btst.l #7,d1 ;test for sign
425 1.1 mycroft beq.b srem_fsn ;if clr, do not set sign big
426 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
427 1.1 mycroft srem_fsn:
428 1.1 mycroft tst.b DTAG(a6) ;filter out denormal destination case
429 1.1 mycroft bpl.b srem_nrm ;
430 1.1 mycroft lea.l FPTEMP(a6),a0 ;a0<- addr(FPTEMP)
431 1.1 mycroft bra t_resdnrm ;force UNFL(but exact) result
432 1.1 mycroft srem_nrm:
433 1.1 mycroft fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
434 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;return dest to fp0
435 1.1 mycroft rts
436 1.1 mycroft *
437 1.1 mycroft * FSCALE
438 1.1 mycroft *
439 1.1 mycroft pscalet:
440 1.1 mycroft * ;$26 fscale
441 1.1 mycroft * ;dtag,stag
442 1.1 mycroft dc.l sscale ; 00,00 norm,norm = result
443 1.1 mycroft dc.l sscale ; 00,01 norm,zero = fpn
444 1.1 mycroft dc.l scl_opr ; 00,10 norm,inf = nan with operr
445 1.1 mycroft dc.l scl_snan ; 00,11 norm,nan = nan
446 1.1 mycroft dc.l scl_zro ; 01,00 zero,norm = +-zero
447 1.1 mycroft dc.l scl_zro ; 01,01 zero,zero = +-zero
448 1.1 mycroft dc.l scl_opr ; 01,10 zero,inf = nan with operr
449 1.1 mycroft dc.l scl_snan ; 01,11 zero,nan = nan
450 1.1 mycroft dc.l scl_inf ; 10,00 inf,norm = +-inf
451 1.1 mycroft dc.l scl_inf ; 10,01 inf,zero = +-inf
452 1.1 mycroft dc.l scl_opr ; 10,10 inf,inf = nan with operr
453 1.1 mycroft dc.l scl_snan ; 10,11 inf,nan = nan
454 1.1 mycroft dc.l scl_dnan ; 11,00 nan,norm = nan
455 1.1 mycroft dc.l scl_dnan ; 11,01 nan,zero = nan
456 1.1 mycroft dc.l scl_dnan ; 11,10 nan,inf = nan
457 1.1 mycroft dc.l scl_dnan ; 11,11 nan,nan = nan
458 1.1 mycroft
459 1.1 mycroft xdef pscale
460 1.1 mycroft pscale:
461 1.1 mycroft bfextu STAG(a6){0:3},d0 ;stag in d0
462 1.1 mycroft bfextu DTAG(a6){0:3},d1 ;dtag in d1
463 1.1 mycroft bclr.l #2,d0 ;alias denorm into norm
464 1.1 mycroft bclr.l #2,d1 ;alias denorm into norm
465 1.1 mycroft lsl.b #2,d1
466 1.1 mycroft or.b d0,d1 ;d1{4:2} = dtag, d1{1:0} = stag
467 1.1 mycroft * ;dtag values stag values:
468 1.1 mycroft * ;000 = norm 00 = norm
469 1.1 mycroft * ;001 = zero 01 = zero
470 1.1 mycroft * ;010 = inf 10 = inf
471 1.1 mycroft * ;011 = nan 11 = nan
472 1.1 mycroft * ;100 = dnrm
473 1.1 mycroft *
474 1.1 mycroft *
475 1.1 mycroft lea.l pscalet,a1 ;load start of jump table
476 1.1 mycroft move.l (a1,d1.w*4),a1 ;load a1 with label depending on tag
477 1.1 mycroft jmp (a1) ;go to the routine
478 1.1 mycroft
479 1.1 mycroft scl_opr:
480 1.1 mycroft bra t_operr
481 1.1 mycroft
482 1.1 mycroft scl_dnan:
483 1.1 mycroft bra dst_nan
484 1.1 mycroft
485 1.1 mycroft scl_zro:
486 1.1 mycroft btst.b #sign_bit,FPTEMP_EX(a6) ;test if + or -
487 1.1 mycroft beq ld_pzero ;if pos then load +0
488 1.1 mycroft bra ld_mzero ;if neg then load -0
489 1.1 mycroft scl_inf:
490 1.1 mycroft btst.b #sign_bit,FPTEMP_EX(a6) ;test if + or -
491 1.1 mycroft beq ld_pinf ;if pos then load +inf
492 1.1 mycroft bra ld_minf ;else neg load -inf
493 1.1 mycroft scl_snan:
494 1.1 mycroft bra src_nan
495 1.1 mycroft *
496 1.1 mycroft * FSINCOS
497 1.1 mycroft *
498 1.1 mycroft xdef ssincosz
499 1.1 mycroft ssincosz:
500 1.1 mycroft btst.b #sign_bit,ETEMP(a6) ;get sign
501 1.1 mycroft beq.b sincosp
502 1.1 mycroft fmove.x MZERO,fp0
503 1.1 mycroft bra.b sincoscom
504 1.1 mycroft sincosp:
505 1.1 mycroft fmove.x PZERO,fp0
506 1.1 mycroft sincoscom:
507 1.1 mycroft fmovem.x PONE,fp1 ;do not allow FPSR to be affected
508 1.1 mycroft bra sto_cos ;store cosine result
509 1.1 mycroft
510 1.1 mycroft xdef ssincosi
511 1.1 mycroft ssincosi:
512 1.1 mycroft fmove.x QNAN,fp1 ;load NAN
513 1.1 mycroft bsr sto_cos ;store cosine result
514 1.1 mycroft fmove.x QNAN,fp0 ;load NAN
515 1.1 mycroft bra t_operr
516 1.1 mycroft
517 1.1 mycroft xdef ssincosnan
518 1.1 mycroft ssincosnan:
519 1.1 mycroft move.l ETEMP_EX(a6),FP_SCR1(a6)
520 1.1 mycroft move.l ETEMP_HI(a6),FP_SCR1+4(a6)
521 1.1 mycroft move.l ETEMP_LO(a6),FP_SCR1+8(a6)
522 1.1 mycroft bset.b #signan_bit,FP_SCR1+4(a6)
523 1.1 mycroft fmovem.x FP_SCR1(a6),fp1
524 1.1 mycroft bsr sto_cos
525 1.1 mycroft bra src_nan
526 1.1 mycroft *
527 1.1 mycroft * This code forces default values for the zero, inf, and nan cases
528 1.1 mycroft * in the transcendentals code. The CC bits must be set in the
529 1.1 mycroft * stacked FPSR to be correctly reported.
530 1.1 mycroft *
531 1.1 mycroft ***Returns +PI/2
532 1.1 mycroft xdef ld_ppi2
533 1.1 mycroft ld_ppi2:
534 1.1 mycroft fmove.x PPIBY2,fp0 ;load +pi/2
535 1.1 mycroft bra t_inx2 ;set inex2 exc
536 1.1 mycroft
537 1.1 mycroft ***Returns -PI/2
538 1.1 mycroft xdef ld_mpi2
539 1.1 mycroft ld_mpi2:
540 1.1 mycroft fmove.x MPIBY2,fp0 ;load -pi/2
541 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit
542 1.1 mycroft bra t_inx2 ;set inex2 exc
543 1.1 mycroft
544 1.1 mycroft ***Returns +inf
545 1.1 mycroft xdef ld_pinf
546 1.1 mycroft ld_pinf:
547 1.1 mycroft fmove.x PINF,fp0 ;load +inf
548 1.1 mycroft or.l #inf_mask,USER_FPSR(a6) ;set I bit
549 1.1 mycroft rts
550 1.1 mycroft
551 1.1 mycroft ***Returns -inf
552 1.1 mycroft xdef ld_minf
553 1.1 mycroft ld_minf:
554 1.1 mycroft fmove.x MINF,fp0 ;load -inf
555 1.1 mycroft or.l #neg_mask+inf_mask,USER_FPSR(a6) ;set N and I bits
556 1.1 mycroft rts
557 1.1 mycroft
558 1.1 mycroft ***Returns +1
559 1.1 mycroft xdef ld_pone
560 1.1 mycroft ld_pone:
561 1.1 mycroft fmove.x PONE,fp0 ;load +1
562 1.1 mycroft rts
563 1.1 mycroft
564 1.1 mycroft ***Returns -1
565 1.1 mycroft xdef ld_mone
566 1.1 mycroft ld_mone:
567 1.1 mycroft fmove.x MONE,fp0 ;load -1
568 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit
569 1.1 mycroft rts
570 1.1 mycroft
571 1.1 mycroft ***Returns +0
572 1.1 mycroft xdef ld_pzero
573 1.1 mycroft ld_pzero:
574 1.1 mycroft fmove.x PZERO,fp0 ;load +0
575 1.1 mycroft or.l #z_mask,USER_FPSR(a6) ;set Z bit
576 1.1 mycroft rts
577 1.1 mycroft
578 1.1 mycroft ***Returns -0
579 1.1 mycroft xdef ld_mzero
580 1.1 mycroft ld_mzero:
581 1.1 mycroft fmove.x MZERO,fp0 ;load -0
582 1.1 mycroft or.l #neg_mask+z_mask,USER_FPSR(a6) ;set N and Z bits
583 1.1 mycroft rts
584 1.1 mycroft
585 1.1 mycroft end
586