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