do_func.sa revision 1.2 1 1.2 cgd * $NetBSD: do_func.sa,v 1.2 1994/10/26 07:49:02 cgd 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.1 mycroft bge.b 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.1 mycroft st.b STORE_FLG(a6)
122 1.1 mycroft rts
123 1.1 mycroft *
124 1.1 mycroft * These routines load forced values into fp0. They are called
125 1.1 mycroft * by index into tbldo.
126 1.1 mycroft *
127 1.1 mycroft * Load a signed zero to fp0 and set inex2/ainex
128 1.1 mycroft *
129 1.1 mycroft xdef snzrinx
130 1.1 mycroft snzrinx:
131 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;get sign of source operand
132 1.1 mycroft bne.b ld_mzinx ;if negative, branch
133 1.1 mycroft bsr ld_pzero ;bsr so we can return and set inx
134 1.1 mycroft bra t_inx2 ;now, set the inx for the next inst
135 1.1 mycroft ld_mzinx:
136 1.1 mycroft bsr ld_mzero ;if neg, load neg zero, return here
137 1.1 mycroft bra t_inx2 ;now, set the inx for the next inst
138 1.1 mycroft *
139 1.1 mycroft * Load a signed zero to fp0; do not set inex2/ainex
140 1.1 mycroft *
141 1.1 mycroft xdef szero
142 1.1 mycroft szero:
143 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;get sign of source operand
144 1.1 mycroft bne ld_mzero ;if neg, load neg zero
145 1.1 mycroft bra ld_pzero ;load positive zero
146 1.1 mycroft *
147 1.1 mycroft * Load a signed infinity to fp0; do not set inex2/ainex
148 1.1 mycroft *
149 1.1 mycroft xdef sinf
150 1.1 mycroft sinf:
151 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;get sign of source operand
152 1.1 mycroft bne ld_minf ;if negative branch
153 1.1 mycroft bra ld_pinf
154 1.1 mycroft *
155 1.1 mycroft * Load a signed one to fp0; do not set inex2/ainex
156 1.1 mycroft *
157 1.1 mycroft xdef sone
158 1.1 mycroft sone:
159 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
160 1.1 mycroft bne ld_mone
161 1.1 mycroft bra ld_pone
162 1.1 mycroft *
163 1.1 mycroft * Load a signed pi/2 to fp0; do not set inex2/ainex
164 1.1 mycroft *
165 1.1 mycroft xdef spi_2
166 1.1 mycroft spi_2:
167 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
168 1.1 mycroft bne ld_mpi2
169 1.1 mycroft bra ld_ppi2
170 1.1 mycroft *
171 1.1 mycroft * Load either a +0 or +inf for plus/minus operand
172 1.1 mycroft *
173 1.1 mycroft xdef szr_inf
174 1.1 mycroft szr_inf:
175 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
176 1.1 mycroft bne ld_pzero
177 1.1 mycroft bra ld_pinf
178 1.1 mycroft *
179 1.1 mycroft * Result is either an operr or +inf for plus/minus operand
180 1.1 mycroft * [Used by slogn, slognp1, slog10, and slog2]
181 1.1 mycroft *
182 1.1 mycroft xdef sopr_inf
183 1.1 mycroft sopr_inf:
184 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
185 1.1 mycroft bne t_operr
186 1.1 mycroft bra ld_pinf
187 1.1 mycroft *
188 1.1 mycroft * FLOGNP1
189 1.1 mycroft *
190 1.1 mycroft xdef sslognp1
191 1.1 mycroft sslognp1:
192 1.1 mycroft fmovem.x (a0),fp0
193 1.1 mycroft fcmp.b #-1,fp0
194 1.1 mycroft fbgt slognp1
195 1.1 mycroft fbeq t_dz2 ;if = -1, divide by zero exception
196 1.1 mycroft fmove.l #0,FPSR ;clr N flag
197 1.1 mycroft bra t_operr ;take care of operands < -1
198 1.1 mycroft *
199 1.1 mycroft * FETOXM1
200 1.1 mycroft *
201 1.1 mycroft xdef setoxm1i
202 1.1 mycroft setoxm1i:
203 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0) ;check sign of source
204 1.1 mycroft bne ld_mone
205 1.1 mycroft bra ld_pinf
206 1.1 mycroft *
207 1.1 mycroft * FLOGN
208 1.1 mycroft *
209 1.1 mycroft * Test for 1.0 as an input argument, returning +zero. Also check
210 1.1 mycroft * the sign and return operr if negative.
211 1.1 mycroft *
212 1.1 mycroft xdef sslogn
213 1.1 mycroft sslogn:
214 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
215 1.1 mycroft bne t_operr ;take care of operands < 0
216 1.1 mycroft cmpi.w #$3fff,LOCAL_EX(a0) ;test for 1.0 input
217 1.1 mycroft bne slogn
218 1.1 mycroft cmpi.l #$80000000,LOCAL_HI(a0)
219 1.1 mycroft bne slogn
220 1.1 mycroft tst.l LOCAL_LO(a0)
221 1.1 mycroft bne slogn
222 1.1 mycroft fmove.x PZERO,fp0
223 1.1 mycroft rts
224 1.1 mycroft
225 1.1 mycroft xdef sslognd
226 1.1 mycroft sslognd:
227 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
228 1.1 mycroft beq slognd
229 1.1 mycroft bra t_operr ;take care of operands < 0
230 1.1 mycroft
231 1.1 mycroft *
232 1.1 mycroft * FLOG10
233 1.1 mycroft *
234 1.1 mycroft xdef sslog10
235 1.1 mycroft sslog10:
236 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
237 1.1 mycroft bne t_operr ;take care of operands < 0
238 1.1 mycroft cmpi.w #$3fff,LOCAL_EX(a0) ;test for 1.0 input
239 1.1 mycroft bne slog10
240 1.1 mycroft cmpi.l #$80000000,LOCAL_HI(a0)
241 1.1 mycroft bne slog10
242 1.1 mycroft tst.l LOCAL_LO(a0)
243 1.1 mycroft bne slog10
244 1.1 mycroft fmove.x PZERO,fp0
245 1.1 mycroft rts
246 1.1 mycroft
247 1.1 mycroft xdef sslog10d
248 1.1 mycroft sslog10d:
249 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
250 1.1 mycroft beq slog10d
251 1.1 mycroft bra t_operr ;take care of operands < 0
252 1.1 mycroft
253 1.1 mycroft *
254 1.1 mycroft * FLOG2
255 1.1 mycroft *
256 1.1 mycroft xdef sslog2
257 1.1 mycroft sslog2:
258 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
259 1.1 mycroft bne t_operr ;take care of operands < 0
260 1.1 mycroft cmpi.w #$3fff,LOCAL_EX(a0) ;test for 1.0 input
261 1.1 mycroft bne slog2
262 1.1 mycroft cmpi.l #$80000000,LOCAL_HI(a0)
263 1.1 mycroft bne slog2
264 1.1 mycroft tst.l LOCAL_LO(a0)
265 1.1 mycroft bne slog2
266 1.1 mycroft fmove.x PZERO,fp0
267 1.1 mycroft rts
268 1.1 mycroft
269 1.1 mycroft xdef sslog2d
270 1.1 mycroft sslog2d:
271 1.1 mycroft btst.b #sign_bit,LOCAL_EX(a0)
272 1.1 mycroft beq slog2d
273 1.1 mycroft bra t_operr ;take care of operands < 0
274 1.1 mycroft
275 1.1 mycroft *
276 1.1 mycroft * FMOD
277 1.1 mycroft *
278 1.1 mycroft pmodt:
279 1.1 mycroft * ;$21 fmod
280 1.1 mycroft * ;dtag,stag
281 1.1 mycroft dc.l smod ; 00,00 norm,norm = normal
282 1.1 mycroft dc.l smod_oper ; 00,01 norm,zero = nan with operr
283 1.1 mycroft dc.l smod_fpn ; 00,10 norm,inf = fpn
284 1.1 mycroft dc.l smod_snan ; 00,11 norm,nan = nan
285 1.1 mycroft dc.l smod_zro ; 01,00 zero,norm = +-zero
286 1.1 mycroft dc.l smod_oper ; 01,01 zero,zero = nan with operr
287 1.1 mycroft dc.l smod_zro ; 01,10 zero,inf = +-zero
288 1.1 mycroft dc.l smod_snan ; 01,11 zero,nan = nan
289 1.1 mycroft dc.l smod_oper ; 10,00 inf,norm = nan with operr
290 1.1 mycroft dc.l smod_oper ; 10,01 inf,zero = nan with operr
291 1.1 mycroft dc.l smod_oper ; 10,10 inf,inf = nan with operr
292 1.1 mycroft dc.l smod_snan ; 10,11 inf,nan = nan
293 1.1 mycroft dc.l smod_dnan ; 11,00 nan,norm = nan
294 1.1 mycroft dc.l smod_dnan ; 11,01 nan,zero = nan
295 1.1 mycroft dc.l smod_dnan ; 11,10 nan,inf = nan
296 1.1 mycroft dc.l smod_dnan ; 11,11 nan,nan = nan
297 1.1 mycroft
298 1.1 mycroft xdef pmod
299 1.1 mycroft pmod:
300 1.1 mycroft clr.b FPSR_QBYTE(a6) ; clear quotient field
301 1.1 mycroft bfextu STAG(a6){0:3},d0 ;stag = d0
302 1.1 mycroft bfextu DTAG(a6){0:3},d1 ;dtag = d1
303 1.1 mycroft
304 1.1 mycroft *
305 1.1 mycroft * Alias extended denorms to norms for the jump table.
306 1.1 mycroft *
307 1.1 mycroft bclr.l #2,d0
308 1.1 mycroft bclr.l #2,d1
309 1.1 mycroft
310 1.1 mycroft lsl.b #2,d1
311 1.1 mycroft or.b d0,d1 ;d1{3:2} = dtag, d1{1:0} = stag
312 1.1 mycroft * ;Tag values:
313 1.1 mycroft * ;00 = norm or denorm
314 1.1 mycroft * ;01 = zero
315 1.1 mycroft * ;10 = inf
316 1.1 mycroft * ;11 = nan
317 1.1 mycroft lea pmodt,a1
318 1.1 mycroft move.l (a1,d1.w*4),a1
319 1.1 mycroft jmp (a1)
320 1.1 mycroft
321 1.1 mycroft smod_snan:
322 1.1 mycroft bra src_nan
323 1.1 mycroft smod_dnan:
324 1.1 mycroft bra dst_nan
325 1.1 mycroft smod_oper:
326 1.1 mycroft bra t_operr
327 1.1 mycroft smod_zro:
328 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
329 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
330 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
331 1.1 mycroft btst.l #7,d1 ;test for sign
332 1.1 mycroft beq.b smod_zsn ;if clr, do not set sign big
333 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
334 1.1 mycroft smod_zsn:
335 1.1 mycroft btst.l #7,d0 ;test if + or -
336 1.1 mycroft beq ld_pzero ;if pos then load +0
337 1.1 mycroft bra ld_mzero ;else neg load -0
338 1.1 mycroft
339 1.1 mycroft smod_fpn:
340 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
341 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
342 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
343 1.1 mycroft btst.l #7,d1 ;test for sign
344 1.1 mycroft beq.b smod_fsn ;if clr, do not set sign big
345 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
346 1.1 mycroft smod_fsn:
347 1.1 mycroft tst.b DTAG(a6) ;filter out denormal destination case
348 1.1 mycroft bpl.b smod_nrm ;
349 1.1 mycroft lea.l FPTEMP(a6),a0 ;a0<- addr(FPTEMP)
350 1.1 mycroft bra t_resdnrm ;force UNFL(but exact) result
351 1.1 mycroft smod_nrm:
352 1.1 mycroft fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
353 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;return dest to fp0
354 1.1 mycroft rts
355 1.1 mycroft
356 1.1 mycroft *
357 1.1 mycroft * FREM
358 1.1 mycroft *
359 1.1 mycroft premt:
360 1.1 mycroft * ;$25 frem
361 1.1 mycroft * ;dtag,stag
362 1.1 mycroft dc.l srem ; 00,00 norm,norm = normal
363 1.1 mycroft dc.l srem_oper ; 00,01 norm,zero = nan with operr
364 1.1 mycroft dc.l srem_fpn ; 00,10 norm,inf = fpn
365 1.1 mycroft dc.l srem_snan ; 00,11 norm,nan = nan
366 1.1 mycroft dc.l srem_zro ; 01,00 zero,norm = +-zero
367 1.1 mycroft dc.l srem_oper ; 01,01 zero,zero = nan with operr
368 1.1 mycroft dc.l srem_zro ; 01,10 zero,inf = +-zero
369 1.1 mycroft dc.l srem_snan ; 01,11 zero,nan = nan
370 1.1 mycroft dc.l srem_oper ; 10,00 inf,norm = nan with operr
371 1.1 mycroft dc.l srem_oper ; 10,01 inf,zero = nan with operr
372 1.1 mycroft dc.l srem_oper ; 10,10 inf,inf = nan with operr
373 1.1 mycroft dc.l srem_snan ; 10,11 inf,nan = nan
374 1.1 mycroft dc.l srem_dnan ; 11,00 nan,norm = nan
375 1.1 mycroft dc.l srem_dnan ; 11,01 nan,zero = nan
376 1.1 mycroft dc.l srem_dnan ; 11,10 nan,inf = nan
377 1.1 mycroft dc.l srem_dnan ; 11,11 nan,nan = nan
378 1.1 mycroft
379 1.1 mycroft xdef prem
380 1.1 mycroft prem:
381 1.1 mycroft clr.b FPSR_QBYTE(a6) ;clear quotient field
382 1.1 mycroft bfextu STAG(a6){0:3},d0 ;stag = d0
383 1.1 mycroft bfextu DTAG(a6){0:3},d1 ;dtag = d1
384 1.1 mycroft *
385 1.1 mycroft * Alias extended denorms to norms for the jump table.
386 1.1 mycroft *
387 1.1 mycroft bclr #2,d0
388 1.1 mycroft bclr #2,d1
389 1.1 mycroft
390 1.1 mycroft lsl.b #2,d1
391 1.1 mycroft or.b d0,d1 ;d1{3:2} = dtag, d1{1:0} = stag
392 1.1 mycroft * ;Tag values:
393 1.1 mycroft * ;00 = norm or denorm
394 1.1 mycroft * ;01 = zero
395 1.1 mycroft * ;10 = inf
396 1.1 mycroft * ;11 = nan
397 1.1 mycroft lea premt,a1
398 1.1 mycroft move.l (a1,d1.w*4),a1
399 1.1 mycroft jmp (a1)
400 1.1 mycroft
401 1.1 mycroft srem_snan:
402 1.1 mycroft bra src_nan
403 1.1 mycroft srem_dnan:
404 1.1 mycroft bra dst_nan
405 1.1 mycroft srem_oper:
406 1.1 mycroft bra t_operr
407 1.1 mycroft srem_zro:
408 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
409 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
410 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
411 1.1 mycroft btst.l #7,d1 ;test for sign
412 1.1 mycroft beq.b srem_zsn ;if clr, do not set sign big
413 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
414 1.1 mycroft srem_zsn:
415 1.1 mycroft btst.l #7,d0 ;test if + or -
416 1.1 mycroft beq ld_pzero ;if pos then load +0
417 1.1 mycroft bra ld_mzero ;else neg load -0
418 1.1 mycroft
419 1.1 mycroft srem_fpn:
420 1.1 mycroft move.b ETEMP(a6),d1 ;get sign of src op
421 1.1 mycroft move.b FPTEMP(a6),d0 ;get sign of dst op
422 1.1 mycroft eor.b d0,d1 ;get exor of sign bits
423 1.1 mycroft btst.l #7,d1 ;test for sign
424 1.1 mycroft beq.b srem_fsn ;if clr, do not set sign big
425 1.1 mycroft bset.b #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
426 1.1 mycroft srem_fsn:
427 1.1 mycroft tst.b DTAG(a6) ;filter out denormal destination case
428 1.1 mycroft bpl.b srem_nrm ;
429 1.1 mycroft lea.l FPTEMP(a6),a0 ;a0<- addr(FPTEMP)
430 1.1 mycroft bra t_resdnrm ;force UNFL(but exact) result
431 1.1 mycroft srem_nrm:
432 1.1 mycroft fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
433 1.1 mycroft fmove.x FPTEMP(a6),fp0 ;return dest to fp0
434 1.1 mycroft rts
435 1.1 mycroft *
436 1.1 mycroft * FSCALE
437 1.1 mycroft *
438 1.1 mycroft pscalet:
439 1.1 mycroft * ;$26 fscale
440 1.1 mycroft * ;dtag,stag
441 1.1 mycroft dc.l sscale ; 00,00 norm,norm = result
442 1.1 mycroft dc.l sscale ; 00,01 norm,zero = fpn
443 1.1 mycroft dc.l scl_opr ; 00,10 norm,inf = nan with operr
444 1.1 mycroft dc.l scl_snan ; 00,11 norm,nan = nan
445 1.1 mycroft dc.l scl_zro ; 01,00 zero,norm = +-zero
446 1.1 mycroft dc.l scl_zro ; 01,01 zero,zero = +-zero
447 1.1 mycroft dc.l scl_opr ; 01,10 zero,inf = nan with operr
448 1.1 mycroft dc.l scl_snan ; 01,11 zero,nan = nan
449 1.1 mycroft dc.l scl_inf ; 10,00 inf,norm = +-inf
450 1.1 mycroft dc.l scl_inf ; 10,01 inf,zero = +-inf
451 1.1 mycroft dc.l scl_opr ; 10,10 inf,inf = nan with operr
452 1.1 mycroft dc.l scl_snan ; 10,11 inf,nan = nan
453 1.1 mycroft dc.l scl_dnan ; 11,00 nan,norm = nan
454 1.1 mycroft dc.l scl_dnan ; 11,01 nan,zero = nan
455 1.1 mycroft dc.l scl_dnan ; 11,10 nan,inf = nan
456 1.1 mycroft dc.l scl_dnan ; 11,11 nan,nan = nan
457 1.1 mycroft
458 1.1 mycroft xdef pscale
459 1.1 mycroft pscale:
460 1.1 mycroft bfextu STAG(a6){0:3},d0 ;stag in d0
461 1.1 mycroft bfextu DTAG(a6){0:3},d1 ;dtag in d1
462 1.1 mycroft bclr.l #2,d0 ;alias denorm into norm
463 1.1 mycroft bclr.l #2,d1 ;alias denorm into norm
464 1.1 mycroft lsl.b #2,d1
465 1.1 mycroft or.b d0,d1 ;d1{4:2} = dtag, d1{1:0} = stag
466 1.1 mycroft * ;dtag values stag values:
467 1.1 mycroft * ;000 = norm 00 = norm
468 1.1 mycroft * ;001 = zero 01 = zero
469 1.1 mycroft * ;010 = inf 10 = inf
470 1.1 mycroft * ;011 = nan 11 = nan
471 1.1 mycroft * ;100 = dnrm
472 1.1 mycroft *
473 1.1 mycroft *
474 1.1 mycroft lea.l pscalet,a1 ;load start of jump table
475 1.1 mycroft move.l (a1,d1.w*4),a1 ;load a1 with label depending on tag
476 1.1 mycroft jmp (a1) ;go to the routine
477 1.1 mycroft
478 1.1 mycroft scl_opr:
479 1.1 mycroft bra t_operr
480 1.1 mycroft
481 1.1 mycroft scl_dnan:
482 1.1 mycroft bra dst_nan
483 1.1 mycroft
484 1.1 mycroft scl_zro:
485 1.1 mycroft btst.b #sign_bit,FPTEMP_EX(a6) ;test if + or -
486 1.1 mycroft beq ld_pzero ;if pos then load +0
487 1.1 mycroft bra ld_mzero ;if neg then load -0
488 1.1 mycroft scl_inf:
489 1.1 mycroft btst.b #sign_bit,FPTEMP_EX(a6) ;test if + or -
490 1.1 mycroft beq ld_pinf ;if pos then load +inf
491 1.1 mycroft bra ld_minf ;else neg load -inf
492 1.1 mycroft scl_snan:
493 1.1 mycroft bra src_nan
494 1.1 mycroft *
495 1.1 mycroft * FSINCOS
496 1.1 mycroft *
497 1.1 mycroft xdef ssincosz
498 1.1 mycroft ssincosz:
499 1.1 mycroft btst.b #sign_bit,ETEMP(a6) ;get sign
500 1.1 mycroft beq.b sincosp
501 1.1 mycroft fmove.x MZERO,fp0
502 1.1 mycroft bra.b sincoscom
503 1.1 mycroft sincosp:
504 1.1 mycroft fmove.x PZERO,fp0
505 1.1 mycroft sincoscom:
506 1.1 mycroft fmovem.x PONE,fp1 ;do not allow FPSR to be affected
507 1.1 mycroft bra sto_cos ;store cosine result
508 1.1 mycroft
509 1.1 mycroft xdef ssincosi
510 1.1 mycroft ssincosi:
511 1.1 mycroft fmove.x QNAN,fp1 ;load NAN
512 1.1 mycroft bsr sto_cos ;store cosine result
513 1.1 mycroft fmove.x QNAN,fp0 ;load NAN
514 1.1 mycroft bra t_operr
515 1.1 mycroft
516 1.1 mycroft xdef ssincosnan
517 1.1 mycroft ssincosnan:
518 1.1 mycroft move.l ETEMP_EX(a6),FP_SCR1(a6)
519 1.1 mycroft move.l ETEMP_HI(a6),FP_SCR1+4(a6)
520 1.1 mycroft move.l ETEMP_LO(a6),FP_SCR1+8(a6)
521 1.1 mycroft bset.b #signan_bit,FP_SCR1+4(a6)
522 1.1 mycroft fmovem.x FP_SCR1(a6),fp1
523 1.1 mycroft bsr sto_cos
524 1.1 mycroft bra src_nan
525 1.1 mycroft *
526 1.1 mycroft * This code forces default values for the zero, inf, and nan cases
527 1.1 mycroft * in the transcendentals code. The CC bits must be set in the
528 1.1 mycroft * stacked FPSR to be correctly reported.
529 1.1 mycroft *
530 1.1 mycroft ***Returns +PI/2
531 1.1 mycroft xdef ld_ppi2
532 1.1 mycroft ld_ppi2:
533 1.1 mycroft fmove.x PPIBY2,fp0 ;load +pi/2
534 1.1 mycroft bra t_inx2 ;set inex2 exc
535 1.1 mycroft
536 1.1 mycroft ***Returns -PI/2
537 1.1 mycroft xdef ld_mpi2
538 1.1 mycroft ld_mpi2:
539 1.1 mycroft fmove.x MPIBY2,fp0 ;load -pi/2
540 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit
541 1.1 mycroft bra t_inx2 ;set inex2 exc
542 1.1 mycroft
543 1.1 mycroft ***Returns +inf
544 1.1 mycroft xdef ld_pinf
545 1.1 mycroft ld_pinf:
546 1.1 mycroft fmove.x PINF,fp0 ;load +inf
547 1.1 mycroft or.l #inf_mask,USER_FPSR(a6) ;set I bit
548 1.1 mycroft rts
549 1.1 mycroft
550 1.1 mycroft ***Returns -inf
551 1.1 mycroft xdef ld_minf
552 1.1 mycroft ld_minf:
553 1.1 mycroft fmove.x MINF,fp0 ;load -inf
554 1.1 mycroft or.l #neg_mask+inf_mask,USER_FPSR(a6) ;set N and I bits
555 1.1 mycroft rts
556 1.1 mycroft
557 1.1 mycroft ***Returns +1
558 1.1 mycroft xdef ld_pone
559 1.1 mycroft ld_pone:
560 1.1 mycroft fmove.x PONE,fp0 ;load +1
561 1.1 mycroft rts
562 1.1 mycroft
563 1.1 mycroft ***Returns -1
564 1.1 mycroft xdef ld_mone
565 1.1 mycroft ld_mone:
566 1.1 mycroft fmove.x MONE,fp0 ;load -1
567 1.1 mycroft or.l #neg_mask,USER_FPSR(a6) ;set N bit
568 1.1 mycroft rts
569 1.1 mycroft
570 1.1 mycroft ***Returns +0
571 1.1 mycroft xdef ld_pzero
572 1.1 mycroft ld_pzero:
573 1.1 mycroft fmove.x PZERO,fp0 ;load +0
574 1.1 mycroft or.l #z_mask,USER_FPSR(a6) ;set Z bit
575 1.1 mycroft rts
576 1.1 mycroft
577 1.1 mycroft ***Returns -0
578 1.1 mycroft xdef ld_mzero
579 1.1 mycroft ld_mzero:
580 1.1 mycroft fmove.x MZERO,fp0 ;load -0
581 1.1 mycroft or.l #neg_mask+z_mask,USER_FPSR(a6) ;set N and Z bits
582 1.1 mycroft rts
583 1.1 mycroft
584 1.1 mycroft end
585