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