1 1.1 is # 2 1.3 msaitoh # $NetBSD: fplsp.s,v 1.3 2021/12/05 03:10:53 msaitoh Exp $ 3 1.1 is # 4 1.1 is 5 1.1 is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 1.1 is # MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 7 1.1 is # M68000 Hi-Performance Microprocessor Division 8 1.1 is # M68060 Software Package Production Release 9 1.1 is # 10 1.1 is # M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc. 11 1.1 is # All rights reserved. 12 1.1 is # 13 1.1 is # THE SOFTWARE is provided on an "AS IS" basis and without warranty. 14 1.1 is # To the maximum extent permitted by applicable law, 15 1.1 is # MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 16 1.1 is # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS 17 1.1 is # FOR A PARTICULAR PURPOSE and any warranty against infringement with 18 1.1 is # regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 19 1.1 is # and any accompanying written materials. 20 1.1 is # 21 1.1 is # To the maximum extent permitted by applicable law, 22 1.1 is # IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 23 1.1 is # (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 24 1.1 is # BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) 25 1.1 is # ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. 26 1.1 is # 27 1.1 is # Motorola assumes no responsibility for the maintenance and support 28 1.1 is # of the SOFTWARE. 29 1.1 is # 30 1.1 is # You are hereby granted a copyright license to use, modify, and distribute the 31 1.1 is # SOFTWARE so long as this entire notice is retained without alteration 32 1.1 is # in any modified and/or redistributed versions, and that such modified 33 1.1 is # versions are clearly identified as such. 34 1.1 is # No licenses are granted by implication, estoppel or otherwise under any 35 1.1 is # patents or trademarks of Motorola, Inc. 36 1.1 is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 1.1 is 38 1.1 is # 39 1.1 is # lfptop.s: 40 1.1 is # This file is appended to the top of the 060ILSP package 41 1.1 is # and contains the entry points into the package. The user, in 42 1.1 is # effect, branches to one of the branch table entries located here. 43 1.1 is # 44 1.1 is 45 1.1 is bra.l _facoss_ 46 1.1 is short 0x0000 47 1.1 is bra.l _facosd_ 48 1.1 is short 0x0000 49 1.1 is bra.l _facosx_ 50 1.1 is short 0x0000 51 1.1 is 52 1.1 is bra.l _fasins_ 53 1.1 is short 0x0000 54 1.1 is bra.l _fasind_ 55 1.1 is short 0x0000 56 1.1 is bra.l _fasinx_ 57 1.1 is short 0x0000 58 1.1 is 59 1.1 is bra.l _fatans_ 60 1.1 is short 0x0000 61 1.1 is bra.l _fatand_ 62 1.1 is short 0x0000 63 1.1 is bra.l _fatanx_ 64 1.1 is short 0x0000 65 1.1 is 66 1.1 is bra.l _fatanhs_ 67 1.1 is short 0x0000 68 1.1 is bra.l _fatanhd_ 69 1.1 is short 0x0000 70 1.1 is bra.l _fatanhx_ 71 1.1 is short 0x0000 72 1.1 is 73 1.1 is bra.l _fcoss_ 74 1.1 is short 0x0000 75 1.1 is bra.l _fcosd_ 76 1.1 is short 0x0000 77 1.1 is bra.l _fcosx_ 78 1.1 is short 0x0000 79 1.1 is 80 1.1 is bra.l _fcoshs_ 81 1.1 is short 0x0000 82 1.1 is bra.l _fcoshd_ 83 1.1 is short 0x0000 84 1.1 is bra.l _fcoshx_ 85 1.1 is short 0x0000 86 1.1 is 87 1.1 is bra.l _fetoxs_ 88 1.1 is short 0x0000 89 1.1 is bra.l _fetoxd_ 90 1.1 is short 0x0000 91 1.1 is bra.l _fetoxx_ 92 1.1 is short 0x0000 93 1.1 is 94 1.1 is bra.l _fetoxm1s_ 95 1.1 is short 0x0000 96 1.1 is bra.l _fetoxm1d_ 97 1.1 is short 0x0000 98 1.1 is bra.l _fetoxm1x_ 99 1.1 is short 0x0000 100 1.1 is 101 1.1 is bra.l _fgetexps_ 102 1.1 is short 0x0000 103 1.1 is bra.l _fgetexpd_ 104 1.1 is short 0x0000 105 1.1 is bra.l _fgetexpx_ 106 1.1 is short 0x0000 107 1.1 is 108 1.1 is bra.l _fgetmans_ 109 1.1 is short 0x0000 110 1.1 is bra.l _fgetmand_ 111 1.1 is short 0x0000 112 1.1 is bra.l _fgetmanx_ 113 1.1 is short 0x0000 114 1.1 is 115 1.1 is bra.l _flog10s_ 116 1.1 is short 0x0000 117 1.1 is bra.l _flog10d_ 118 1.1 is short 0x0000 119 1.1 is bra.l _flog10x_ 120 1.1 is short 0x0000 121 1.1 is 122 1.1 is bra.l _flog2s_ 123 1.1 is short 0x0000 124 1.1 is bra.l _flog2d_ 125 1.1 is short 0x0000 126 1.1 is bra.l _flog2x_ 127 1.1 is short 0x0000 128 1.1 is 129 1.1 is bra.l _flogns_ 130 1.1 is short 0x0000 131 1.1 is bra.l _flognd_ 132 1.1 is short 0x0000 133 1.1 is bra.l _flognx_ 134 1.1 is short 0x0000 135 1.1 is 136 1.1 is bra.l _flognp1s_ 137 1.1 is short 0x0000 138 1.1 is bra.l _flognp1d_ 139 1.1 is short 0x0000 140 1.1 is bra.l _flognp1x_ 141 1.1 is short 0x0000 142 1.1 is 143 1.1 is bra.l _fmods_ 144 1.1 is short 0x0000 145 1.1 is bra.l _fmodd_ 146 1.1 is short 0x0000 147 1.1 is bra.l _fmodx_ 148 1.1 is short 0x0000 149 1.1 is 150 1.1 is bra.l _frems_ 151 1.1 is short 0x0000 152 1.1 is bra.l _fremd_ 153 1.1 is short 0x0000 154 1.1 is bra.l _fremx_ 155 1.1 is short 0x0000 156 1.1 is 157 1.1 is bra.l _fscales_ 158 1.1 is short 0x0000 159 1.1 is bra.l _fscaled_ 160 1.1 is short 0x0000 161 1.1 is bra.l _fscalex_ 162 1.1 is short 0x0000 163 1.1 is 164 1.1 is bra.l _fsins_ 165 1.1 is short 0x0000 166 1.1 is bra.l _fsind_ 167 1.1 is short 0x0000 168 1.1 is bra.l _fsinx_ 169 1.1 is short 0x0000 170 1.1 is 171 1.1 is bra.l _fsincoss_ 172 1.1 is short 0x0000 173 1.1 is bra.l _fsincosd_ 174 1.1 is short 0x0000 175 1.1 is bra.l _fsincosx_ 176 1.1 is short 0x0000 177 1.1 is 178 1.1 is bra.l _fsinhs_ 179 1.1 is short 0x0000 180 1.1 is bra.l _fsinhd_ 181 1.1 is short 0x0000 182 1.1 is bra.l _fsinhx_ 183 1.1 is short 0x0000 184 1.1 is 185 1.1 is bra.l _ftans_ 186 1.1 is short 0x0000 187 1.1 is bra.l _ftand_ 188 1.1 is short 0x0000 189 1.1 is bra.l _ftanx_ 190 1.1 is short 0x0000 191 1.1 is 192 1.1 is bra.l _ftanhs_ 193 1.1 is short 0x0000 194 1.1 is bra.l _ftanhd_ 195 1.1 is short 0x0000 196 1.1 is bra.l _ftanhx_ 197 1.1 is short 0x0000 198 1.1 is 199 1.1 is bra.l _ftentoxs_ 200 1.1 is short 0x0000 201 1.1 is bra.l _ftentoxd_ 202 1.1 is short 0x0000 203 1.1 is bra.l _ftentoxx_ 204 1.1 is short 0x0000 205 1.1 is 206 1.1 is bra.l _ftwotoxs_ 207 1.1 is short 0x0000 208 1.1 is bra.l _ftwotoxd_ 209 1.1 is short 0x0000 210 1.1 is bra.l _ftwotoxx_ 211 1.1 is short 0x0000 212 1.1 is 213 1.1 is bra.l _fabss_ 214 1.1 is short 0x0000 215 1.1 is bra.l _fabsd_ 216 1.1 is short 0x0000 217 1.1 is bra.l _fabsx_ 218 1.1 is short 0x0000 219 1.1 is 220 1.1 is bra.l _fadds_ 221 1.1 is short 0x0000 222 1.1 is bra.l _faddd_ 223 1.1 is short 0x0000 224 1.1 is bra.l _faddx_ 225 1.1 is short 0x0000 226 1.1 is 227 1.1 is bra.l _fdivs_ 228 1.1 is short 0x0000 229 1.1 is bra.l _fdivd_ 230 1.1 is short 0x0000 231 1.1 is bra.l _fdivx_ 232 1.1 is short 0x0000 233 1.1 is 234 1.1 is bra.l _fints_ 235 1.1 is short 0x0000 236 1.1 is bra.l _fintd_ 237 1.1 is short 0x0000 238 1.1 is bra.l _fintx_ 239 1.1 is short 0x0000 240 1.1 is 241 1.1 is bra.l _fintrzs_ 242 1.1 is short 0x0000 243 1.1 is bra.l _fintrzd_ 244 1.1 is short 0x0000 245 1.1 is bra.l _fintrzx_ 246 1.1 is short 0x0000 247 1.1 is 248 1.1 is bra.l _fmuls_ 249 1.1 is short 0x0000 250 1.1 is bra.l _fmuld_ 251 1.1 is short 0x0000 252 1.1 is bra.l _fmulx_ 253 1.1 is short 0x0000 254 1.1 is 255 1.1 is bra.l _fnegs_ 256 1.1 is short 0x0000 257 1.1 is bra.l _fnegd_ 258 1.1 is short 0x0000 259 1.1 is bra.l _fnegx_ 260 1.1 is short 0x0000 261 1.1 is 262 1.1 is bra.l _fsqrts_ 263 1.1 is short 0x0000 264 1.1 is bra.l _fsqrtd_ 265 1.1 is short 0x0000 266 1.1 is bra.l _fsqrtx_ 267 1.1 is short 0x0000 268 1.1 is 269 1.1 is bra.l _fsubs_ 270 1.1 is short 0x0000 271 1.1 is bra.l _fsubd_ 272 1.1 is short 0x0000 273 1.1 is bra.l _fsubx_ 274 1.1 is short 0x0000 275 1.1 is 276 1.1 is # leave room for future possible additions 277 1.1 is align 0x400 278 1.1 is 279 1.1 is # 280 1.1 is # This file contains a set of define statements for constants 281 1.1 is # in order to promote readability within the corecode itself. 282 1.1 is # 283 1.1 is 284 1.1 is set LOCAL_SIZE, 192 # stack frame size(bytes) 285 1.1 is set LV, -LOCAL_SIZE # stack offset 286 1.1 is 287 1.1 is set EXC_SR, 0x4 # stack status register 288 1.1 is set EXC_PC, 0x6 # stack pc 289 1.1 is set EXC_VOFF, 0xa # stacked vector offset 290 1.1 is set EXC_EA, 0xc # stacked <ea> 291 1.1 is 292 1.1 is set EXC_FP, 0x0 # frame pointer 293 1.1 is 294 1.1 is set EXC_AREGS, -68 # offset of all address regs 295 1.1 is set EXC_DREGS, -100 # offset of all data regs 296 1.1 is set EXC_FPREGS, -36 # offset of all fp regs 297 1.1 is 298 1.1 is set EXC_A7, EXC_AREGS+(7*4) # offset of saved a7 299 1.1 is set OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7 300 1.1 is set EXC_A6, EXC_AREGS+(6*4) # offset of saved a6 301 1.1 is set EXC_A5, EXC_AREGS+(5*4) 302 1.1 is set EXC_A4, EXC_AREGS+(4*4) 303 1.1 is set EXC_A3, EXC_AREGS+(3*4) 304 1.1 is set EXC_A2, EXC_AREGS+(2*4) 305 1.1 is set EXC_A1, EXC_AREGS+(1*4) 306 1.1 is set EXC_A0, EXC_AREGS+(0*4) 307 1.1 is set EXC_D7, EXC_DREGS+(7*4) 308 1.1 is set EXC_D6, EXC_DREGS+(6*4) 309 1.1 is set EXC_D5, EXC_DREGS+(5*4) 310 1.1 is set EXC_D4, EXC_DREGS+(4*4) 311 1.1 is set EXC_D3, EXC_DREGS+(3*4) 312 1.1 is set EXC_D2, EXC_DREGS+(2*4) 313 1.1 is set EXC_D1, EXC_DREGS+(1*4) 314 1.1 is set EXC_D0, EXC_DREGS+(0*4) 315 1.1 is 316 1.1 is set EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0 317 1.1 is set EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1 318 1.1 is set EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used) 319 1.1 is 320 1.1 is set FP_SCR1, LV+80 # fp scratch 1 321 1.1 is set FP_SCR1_EX, FP_SCR1+0 322 1.1 is set FP_SCR1_SGN, FP_SCR1+2 323 1.1 is set FP_SCR1_HI, FP_SCR1+4 324 1.1 is set FP_SCR1_LO, FP_SCR1+8 325 1.1 is 326 1.1 is set FP_SCR0, LV+68 # fp scratch 0 327 1.1 is set FP_SCR0_EX, FP_SCR0+0 328 1.1 is set FP_SCR0_SGN, FP_SCR0+2 329 1.1 is set FP_SCR0_HI, FP_SCR0+4 330 1.1 is set FP_SCR0_LO, FP_SCR0+8 331 1.1 is 332 1.1 is set FP_DST, LV+56 # fp destination operand 333 1.1 is set FP_DST_EX, FP_DST+0 334 1.1 is set FP_DST_SGN, FP_DST+2 335 1.1 is set FP_DST_HI, FP_DST+4 336 1.1 is set FP_DST_LO, FP_DST+8 337 1.1 is 338 1.1 is set FP_SRC, LV+44 # fp source operand 339 1.1 is set FP_SRC_EX, FP_SRC+0 340 1.1 is set FP_SRC_SGN, FP_SRC+2 341 1.1 is set FP_SRC_HI, FP_SRC+4 342 1.1 is set FP_SRC_LO, FP_SRC+8 343 1.1 is 344 1.1 is set USER_FPIAR, LV+40 # FP instr address register 345 1.1 is 346 1.1 is set USER_FPSR, LV+36 # FP status register 347 1.1 is set FPSR_CC, USER_FPSR+0 # FPSR condition codes 348 1.1 is set FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte 349 1.1 is set FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte 350 1.1 is set FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte 351 1.1 is 352 1.1 is set USER_FPCR, LV+32 # FP control register 353 1.1 is set FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable 354 1.1 is set FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control 355 1.1 is 356 1.1 is set L_SCR3, LV+28 # integer scratch 3 357 1.1 is set L_SCR2, LV+24 # integer scratch 2 358 1.1 is set L_SCR1, LV+20 # integer scratch 1 359 1.1 is 360 1.1 is set STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst) 361 1.1 is 362 1.1 is set EXC_TEMP2, LV+24 # temporary space 363 1.1 is set EXC_TEMP, LV+16 # temporary space 364 1.1 is 365 1.1 is set DTAG, LV+15 # destination operand type 366 1.1 is set STAG, LV+14 # source operand type 367 1.1 is 368 1.1 is set SPCOND_FLG, LV+10 # flag: special case (see below) 369 1.1 is 370 1.1 is set EXC_CC, LV+8 # saved condition codes 371 1.1 is set EXC_EXTWPTR, LV+4 # saved current PC (active) 372 1.1 is set EXC_EXTWORD, LV+2 # saved extension word 373 1.1 is set EXC_CMDREG, LV+2 # saved extension word 374 1.1 is set EXC_OPWORD, LV+0 # saved operation word 375 1.1 is 376 1.1 is ################################ 377 1.1 is 378 1.1 is # Helpful macros 379 1.1 is 380 1.1 is set FTEMP, 0 # offsets within an 381 1.1 is set FTEMP_EX, 0 # extended precision 382 1.1 is set FTEMP_SGN, 2 # value saved in memory. 383 1.1 is set FTEMP_HI, 4 384 1.1 is set FTEMP_LO, 8 385 1.1 is set FTEMP_GRS, 12 386 1.1 is 387 1.1 is set LOCAL, 0 # offsets within an 388 1.1 is set LOCAL_EX, 0 # extended precision 389 1.1 is set LOCAL_SGN, 2 # value saved in memory. 390 1.1 is set LOCAL_HI, 4 391 1.1 is set LOCAL_LO, 8 392 1.1 is set LOCAL_GRS, 12 393 1.1 is 394 1.1 is set DST, 0 # offsets within an 395 1.1 is set DST_EX, 0 # extended precision 396 1.1 is set DST_HI, 4 # value saved in memory. 397 1.1 is set DST_LO, 8 398 1.1 is 399 1.1 is set SRC, 0 # offsets within an 400 1.1 is set SRC_EX, 0 # extended precision 401 1.1 is set SRC_HI, 4 # value saved in memory. 402 1.1 is set SRC_LO, 8 403 1.1 is 404 1.1 is set SGL_LO, 0x3f81 # min sgl prec exponent 405 1.1 is set SGL_HI, 0x407e # max sgl prec exponent 406 1.1 is set DBL_LO, 0x3c01 # min dbl prec exponent 407 1.1 is set DBL_HI, 0x43fe # max dbl prec exponent 408 1.1 is set EXT_LO, 0x0 # min ext prec exponent 409 1.1 is set EXT_HI, 0x7ffe # max ext prec exponent 410 1.1 is 411 1.1 is set EXT_BIAS, 0x3fff # extended precision bias 412 1.1 is set SGL_BIAS, 0x007f # single precision bias 413 1.1 is set DBL_BIAS, 0x03ff # double precision bias 414 1.1 is 415 1.1 is set NORM, 0x00 # operand type for STAG/DTAG 416 1.1 is set ZERO, 0x01 # operand type for STAG/DTAG 417 1.1 is set INF, 0x02 # operand type for STAG/DTAG 418 1.1 is set QNAN, 0x03 # operand type for STAG/DTAG 419 1.1 is set DENORM, 0x04 # operand type for STAG/DTAG 420 1.1 is set SNAN, 0x05 # operand type for STAG/DTAG 421 1.1 is set UNNORM, 0x06 # operand type for STAG/DTAG 422 1.1 is 423 1.1 is ################## 424 1.1 is # FPSR/FPCR bits # 425 1.1 is ################## 426 1.1 is set neg_bit, 0x3 # negative result 427 1.1 is set z_bit, 0x2 # zero result 428 1.1 is set inf_bit, 0x1 # infinite result 429 1.1 is set nan_bit, 0x0 # NAN result 430 1.1 is 431 1.1 is set q_sn_bit, 0x7 # sign bit of quotient byte 432 1.1 is 433 1.1 is set bsun_bit, 7 # branch on unordered 434 1.1 is set snan_bit, 6 # signalling NAN 435 1.1 is set operr_bit, 5 # operand error 436 1.1 is set ovfl_bit, 4 # overflow 437 1.1 is set unfl_bit, 3 # underflow 438 1.1 is set dz_bit, 2 # divide by zero 439 1.1 is set inex2_bit, 1 # inexact result 2 440 1.1 is set inex1_bit, 0 # inexact result 1 441 1.1 is 442 1.1 is set aiop_bit, 7 # accrued inexact operation bit 443 1.1 is set aovfl_bit, 6 # accrued overflow bit 444 1.1 is set aunfl_bit, 5 # accrued underflow bit 445 1.1 is set adz_bit, 4 # accrued dz bit 446 1.1 is set ainex_bit, 3 # accrued inexact bit 447 1.1 is 448 1.1 is ############################# 449 1.1 is # FPSR individual bit masks # 450 1.1 is ############################# 451 1.1 is set neg_mask, 0x08000000 # negative bit mask (lw) 452 1.1 is set inf_mask, 0x02000000 # infinity bit mask (lw) 453 1.1 is set z_mask, 0x04000000 # zero bit mask (lw) 454 1.1 is set nan_mask, 0x01000000 # nan bit mask (lw) 455 1.1 is 456 1.1 is set neg_bmask, 0x08 # negative bit mask (byte) 457 1.1 is set inf_bmask, 0x02 # infinity bit mask (byte) 458 1.1 is set z_bmask, 0x04 # zero bit mask (byte) 459 1.1 is set nan_bmask, 0x01 # nan bit mask (byte) 460 1.1 is 461 1.1 is set bsun_mask, 0x00008000 # bsun exception mask 462 1.1 is set snan_mask, 0x00004000 # snan exception mask 463 1.1 is set operr_mask, 0x00002000 # operr exception mask 464 1.1 is set ovfl_mask, 0x00001000 # overflow exception mask 465 1.1 is set unfl_mask, 0x00000800 # underflow exception mask 466 1.1 is set dz_mask, 0x00000400 # dz exception mask 467 1.1 is set inex2_mask, 0x00000200 # inex2 exception mask 468 1.1 is set inex1_mask, 0x00000100 # inex1 exception mask 469 1.1 is 470 1.1 is set aiop_mask, 0x00000080 # accrued illegal operation 471 1.1 is set aovfl_mask, 0x00000040 # accrued overflow 472 1.1 is set aunfl_mask, 0x00000020 # accrued underflow 473 1.1 is set adz_mask, 0x00000010 # accrued divide by zero 474 1.1 is set ainex_mask, 0x00000008 # accrued inexact 475 1.1 is 476 1.1 is ###################################### 477 1.1 is # FPSR combinations used in the FPSP # 478 1.1 is ###################################### 479 1.1 is set dzinf_mask, inf_mask+dz_mask+adz_mask 480 1.1 is set opnan_mask, nan_mask+operr_mask+aiop_mask 481 1.1 is set nzi_mask, 0x01ffffff #clears N, Z, and I 482 1.1 is set unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask 483 1.1 is set unf2inx_mask, unfl_mask+inex2_mask+ainex_mask 484 1.1 is set ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask 485 1.1 is set inx1a_mask, inex1_mask+ainex_mask 486 1.1 is set inx2a_mask, inex2_mask+ainex_mask 487 1.1 is set snaniop_mask, nan_mask+snan_mask+aiop_mask 488 1.1 is set snaniop2_mask, snan_mask+aiop_mask 489 1.1 is set naniop_mask, nan_mask+aiop_mask 490 1.1 is set neginf_mask, neg_mask+inf_mask 491 1.1 is set infaiop_mask, inf_mask+aiop_mask 492 1.1 is set negz_mask, neg_mask+z_mask 493 1.1 is set opaop_mask, operr_mask+aiop_mask 494 1.1 is set unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask 495 1.1 is set ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask 496 1.1 is 497 1.1 is ######### 498 1.1 is # misc. # 499 1.1 is ######### 500 1.1 is set rnd_stky_bit, 29 # stky bit pos in longword 501 1.1 is 502 1.1 is set sign_bit, 0x7 # sign bit 503 1.1 is set signan_bit, 0x6 # signalling nan bit 504 1.1 is 505 1.1 is set sgl_thresh, 0x3f81 # minimum sgl exponent 506 1.1 is set dbl_thresh, 0x3c01 # minimum dbl exponent 507 1.1 is 508 1.1 is set x_mode, 0x0 # extended precision 509 1.1 is set s_mode, 0x4 # single precision 510 1.1 is set d_mode, 0x8 # double precision 511 1.1 is 512 1.1 is set rn_mode, 0x0 # round-to-nearest 513 1.1 is set rz_mode, 0x1 # round-to-zero 514 1.1 is set rm_mode, 0x2 # round-tp-minus-infinity 515 1.1 is set rp_mode, 0x3 # round-to-plus-infinity 516 1.1 is 517 1.1 is set mantissalen, 64 # length of mantissa in bits 518 1.1 is 519 1.1 is set BYTE, 1 # len(byte) == 1 byte 520 1.1 is set WORD, 2 # len(word) == 2 bytes 521 1.1 is set LONG, 4 # len(longword) == 2 bytes 522 1.1 is 523 1.1 is set BSUN_VEC, 0xc0 # bsun vector offset 524 1.1 is set INEX_VEC, 0xc4 # inexact vector offset 525 1.1 is set DZ_VEC, 0xc8 # dz vector offset 526 1.1 is set UNFL_VEC, 0xcc # unfl vector offset 527 1.1 is set OPERR_VEC, 0xd0 # operr vector offset 528 1.1 is set OVFL_VEC, 0xd4 # ovfl vector offset 529 1.1 is set SNAN_VEC, 0xd8 # snan vector offset 530 1.1 is 531 1.1 is ########################### 532 1.1 is # SPecial CONDition FLaGs # 533 1.1 is ########################### 534 1.1 is set ftrapcc_flg, 0x01 # flag bit: ftrapcc exception 535 1.1 is set fbsun_flg, 0x02 # flag bit: bsun exception 536 1.1 is set mia7_flg, 0x04 # flag bit: (a7)+ <ea> 537 1.1 is set mda7_flg, 0x08 # flag bit: -(a7) <ea> 538 1.1 is set fmovm_flg, 0x40 # flag bit: fmovm instruction 539 1.1 is set immed_flg, 0x80 # flag bit: &<data> <ea> 540 1.1 is 541 1.1 is set ftrapcc_bit, 0x0 542 1.1 is set fbsun_bit, 0x1 543 1.1 is set mia7_bit, 0x2 544 1.1 is set mda7_bit, 0x3 545 1.1 is set immed_bit, 0x7 546 1.1 is 547 1.1 is ################################## 548 1.1 is # TRANSCENDENTAL "LAST-OP" FLAGS # 549 1.1 is ################################## 550 1.1 is set FMUL_OP, 0x0 # fmul instr performed last 551 1.1 is set FDIV_OP, 0x1 # fdiv performed last 552 1.1 is set FADD_OP, 0x2 # fadd performed last 553 1.1 is set FMOV_OP, 0x3 # fmov performed last 554 1.1 is 555 1.1 is ############# 556 1.1 is # CONSTANTS # 557 1.1 is ############# 558 1.1 is T1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD 559 1.1 is T2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL 560 1.1 is 561 1.1 is PI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000 562 1.1 is PIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 563 1.1 is 564 1.1 is TWOBYPI: 565 1.1 is long 0x3FE45F30,0x6DC9C883 566 1.1 is 567 1.1 is ######################################################################### 568 1.1 is # MONADIC TEMPLATE # 569 1.1 is ######################################################################### 570 1.1 is global _fsins_ 571 1.1 is _fsins_: 572 1.1 is link %a6,&-LOCAL_SIZE 573 1.1 is 574 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 575 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 576 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 577 1.1 is 578 1.1 is fmov.l &0x0,%fpcr # zero FPCR 579 1.1 is 580 1.1 is # 581 1.1 is # copy, convert, and tag input argument 582 1.1 is # 583 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 584 1.1 is fmov.x %fp0,FP_SRC(%a6) 585 1.1 is lea FP_SRC(%a6),%a0 586 1.1 is bsr.l tag # fetch operand type 587 1.1 is mov.b %d0,STAG(%a6) 588 1.1 is mov.b %d0,%d1 589 1.1 is 590 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 591 1.1 is 592 1.1 is clr.l %d0 593 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 594 1.1 is 595 1.1 is tst.b %d1 596 1.1 is bne.b _L0_2s 597 1.1 is bsr.l ssin # operand is a NORM 598 1.1 is bra.b _L0_6s 599 1.1 is _L0_2s: 600 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 601 1.1 is bne.b _L0_3s # no 602 1.1 is bsr.l src_zero # yes 603 1.1 is bra.b _L0_6s 604 1.1 is _L0_3s: 605 1.1 is cmpi.b %d1,&INF # is operand an INF? 606 1.1 is bne.b _L0_4s # no 607 1.1 is bsr.l t_operr # yes 608 1.1 is bra.b _L0_6s 609 1.1 is _L0_4s: 610 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 611 1.1 is bne.b _L0_5s # no 612 1.1 is bsr.l src_qnan # yes 613 1.1 is bra.b _L0_6s 614 1.1 is _L0_5s: 615 1.1 is bsr.l ssind # operand is a DENORM 616 1.1 is _L0_6s: 617 1.1 is 618 1.1 is # 619 1.1 is # Result is now in FP0 620 1.1 is # 621 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 622 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 623 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 624 1.1 is unlk %a6 625 1.1 is rts 626 1.1 is 627 1.1 is global _fsind_ 628 1.1 is _fsind_: 629 1.1 is link %a6,&-LOCAL_SIZE 630 1.1 is 631 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 632 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 633 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 634 1.1 is 635 1.1 is fmov.l &0x0,%fpcr # zero FPCR 636 1.1 is 637 1.1 is # 638 1.1 is # copy, convert, and tag input argument 639 1.1 is # 640 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 641 1.1 is fmov.x %fp0,FP_SRC(%a6) 642 1.1 is lea FP_SRC(%a6),%a0 643 1.1 is bsr.l tag # fetch operand type 644 1.1 is mov.b %d0,STAG(%a6) 645 1.1 is mov.b %d0,%d1 646 1.1 is 647 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 648 1.1 is 649 1.1 is clr.l %d0 650 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 651 1.1 is 652 1.1 is mov.b %d1,STAG(%a6) 653 1.1 is tst.b %d1 654 1.1 is bne.b _L0_2d 655 1.1 is bsr.l ssin # operand is a NORM 656 1.1 is bra.b _L0_6d 657 1.1 is _L0_2d: 658 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 659 1.1 is bne.b _L0_3d # no 660 1.1 is bsr.l src_zero # yes 661 1.1 is bra.b _L0_6d 662 1.1 is _L0_3d: 663 1.1 is cmpi.b %d1,&INF # is operand an INF? 664 1.1 is bne.b _L0_4d # no 665 1.1 is bsr.l t_operr # yes 666 1.1 is bra.b _L0_6d 667 1.1 is _L0_4d: 668 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 669 1.1 is bne.b _L0_5d # no 670 1.1 is bsr.l src_qnan # yes 671 1.1 is bra.b _L0_6d 672 1.1 is _L0_5d: 673 1.1 is bsr.l ssind # operand is a DENORM 674 1.1 is _L0_6d: 675 1.1 is 676 1.1 is # 677 1.1 is # Result is now in FP0 678 1.1 is # 679 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 680 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 681 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 682 1.1 is unlk %a6 683 1.1 is rts 684 1.1 is 685 1.1 is global _fsinx_ 686 1.1 is _fsinx_: 687 1.1 is link %a6,&-LOCAL_SIZE 688 1.1 is 689 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 690 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 691 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 692 1.1 is 693 1.1 is fmov.l &0x0,%fpcr # zero FPCR 694 1.1 is 695 1.1 is # 696 1.1 is # copy, convert, and tag input argument 697 1.1 is # 698 1.1 is lea FP_SRC(%a6),%a0 699 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 700 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 701 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 702 1.1 is bsr.l tag # fetch operand type 703 1.1 is mov.b %d0,STAG(%a6) 704 1.1 is mov.b %d0,%d1 705 1.1 is 706 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 707 1.1 is 708 1.1 is clr.l %d0 709 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 710 1.1 is 711 1.1 is tst.b %d1 712 1.1 is bne.b _L0_2x 713 1.1 is bsr.l ssin # operand is a NORM 714 1.1 is bra.b _L0_6x 715 1.1 is _L0_2x: 716 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 717 1.1 is bne.b _L0_3x # no 718 1.1 is bsr.l src_zero # yes 719 1.1 is bra.b _L0_6x 720 1.1 is _L0_3x: 721 1.1 is cmpi.b %d1,&INF # is operand an INF? 722 1.1 is bne.b _L0_4x # no 723 1.1 is bsr.l t_operr # yes 724 1.1 is bra.b _L0_6x 725 1.1 is _L0_4x: 726 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 727 1.1 is bne.b _L0_5x # no 728 1.1 is bsr.l src_qnan # yes 729 1.1 is bra.b _L0_6x 730 1.1 is _L0_5x: 731 1.1 is bsr.l ssind # operand is a DENORM 732 1.1 is _L0_6x: 733 1.1 is 734 1.1 is # 735 1.1 is # Result is now in FP0 736 1.1 is # 737 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 738 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 739 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 740 1.1 is unlk %a6 741 1.1 is rts 742 1.1 is 743 1.1 is 744 1.1 is ######################################################################### 745 1.1 is # MONADIC TEMPLATE # 746 1.1 is ######################################################################### 747 1.1 is global _fcoss_ 748 1.1 is _fcoss_: 749 1.1 is link %a6,&-LOCAL_SIZE 750 1.1 is 751 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 752 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 753 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 754 1.1 is 755 1.1 is fmov.l &0x0,%fpcr # zero FPCR 756 1.1 is 757 1.1 is # 758 1.1 is # copy, convert, and tag input argument 759 1.1 is # 760 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 761 1.1 is fmov.x %fp0,FP_SRC(%a6) 762 1.1 is lea FP_SRC(%a6),%a0 763 1.1 is bsr.l tag # fetch operand type 764 1.1 is mov.b %d0,STAG(%a6) 765 1.1 is mov.b %d0,%d1 766 1.1 is 767 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 768 1.1 is 769 1.1 is clr.l %d0 770 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 771 1.1 is 772 1.1 is tst.b %d1 773 1.1 is bne.b _L1_2s 774 1.1 is bsr.l scos # operand is a NORM 775 1.1 is bra.b _L1_6s 776 1.1 is _L1_2s: 777 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 778 1.1 is bne.b _L1_3s # no 779 1.1 is bsr.l ld_pone # yes 780 1.1 is bra.b _L1_6s 781 1.1 is _L1_3s: 782 1.1 is cmpi.b %d1,&INF # is operand an INF? 783 1.1 is bne.b _L1_4s # no 784 1.1 is bsr.l t_operr # yes 785 1.1 is bra.b _L1_6s 786 1.1 is _L1_4s: 787 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 788 1.1 is bne.b _L1_5s # no 789 1.1 is bsr.l src_qnan # yes 790 1.1 is bra.b _L1_6s 791 1.1 is _L1_5s: 792 1.1 is bsr.l scosd # operand is a DENORM 793 1.1 is _L1_6s: 794 1.1 is 795 1.1 is # 796 1.1 is # Result is now in FP0 797 1.1 is # 798 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 799 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 800 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 801 1.1 is unlk %a6 802 1.1 is rts 803 1.1 is 804 1.1 is global _fcosd_ 805 1.1 is _fcosd_: 806 1.1 is link %a6,&-LOCAL_SIZE 807 1.1 is 808 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 809 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 810 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 811 1.1 is 812 1.1 is fmov.l &0x0,%fpcr # zero FPCR 813 1.1 is 814 1.1 is # 815 1.1 is # copy, convert, and tag input argument 816 1.1 is # 817 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 818 1.1 is fmov.x %fp0,FP_SRC(%a6) 819 1.1 is lea FP_SRC(%a6),%a0 820 1.1 is bsr.l tag # fetch operand type 821 1.1 is mov.b %d0,STAG(%a6) 822 1.1 is mov.b %d0,%d1 823 1.1 is 824 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 825 1.1 is 826 1.1 is clr.l %d0 827 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 828 1.1 is 829 1.1 is mov.b %d1,STAG(%a6) 830 1.1 is tst.b %d1 831 1.1 is bne.b _L1_2d 832 1.1 is bsr.l scos # operand is a NORM 833 1.1 is bra.b _L1_6d 834 1.1 is _L1_2d: 835 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 836 1.1 is bne.b _L1_3d # no 837 1.1 is bsr.l ld_pone # yes 838 1.1 is bra.b _L1_6d 839 1.1 is _L1_3d: 840 1.1 is cmpi.b %d1,&INF # is operand an INF? 841 1.1 is bne.b _L1_4d # no 842 1.1 is bsr.l t_operr # yes 843 1.1 is bra.b _L1_6d 844 1.1 is _L1_4d: 845 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 846 1.1 is bne.b _L1_5d # no 847 1.1 is bsr.l src_qnan # yes 848 1.1 is bra.b _L1_6d 849 1.1 is _L1_5d: 850 1.1 is bsr.l scosd # operand is a DENORM 851 1.1 is _L1_6d: 852 1.1 is 853 1.1 is # 854 1.1 is # Result is now in FP0 855 1.1 is # 856 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 857 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 858 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 859 1.1 is unlk %a6 860 1.1 is rts 861 1.1 is 862 1.1 is global _fcosx_ 863 1.1 is _fcosx_: 864 1.1 is link %a6,&-LOCAL_SIZE 865 1.1 is 866 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 867 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 868 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 869 1.1 is 870 1.1 is fmov.l &0x0,%fpcr # zero FPCR 871 1.1 is 872 1.1 is # 873 1.1 is # copy, convert, and tag input argument 874 1.1 is # 875 1.1 is lea FP_SRC(%a6),%a0 876 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 877 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 878 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 879 1.1 is bsr.l tag # fetch operand type 880 1.1 is mov.b %d0,STAG(%a6) 881 1.1 is mov.b %d0,%d1 882 1.1 is 883 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 884 1.1 is 885 1.1 is clr.l %d0 886 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 887 1.1 is 888 1.1 is tst.b %d1 889 1.1 is bne.b _L1_2x 890 1.1 is bsr.l scos # operand is a NORM 891 1.1 is bra.b _L1_6x 892 1.1 is _L1_2x: 893 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 894 1.1 is bne.b _L1_3x # no 895 1.1 is bsr.l ld_pone # yes 896 1.1 is bra.b _L1_6x 897 1.1 is _L1_3x: 898 1.1 is cmpi.b %d1,&INF # is operand an INF? 899 1.1 is bne.b _L1_4x # no 900 1.1 is bsr.l t_operr # yes 901 1.1 is bra.b _L1_6x 902 1.1 is _L1_4x: 903 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 904 1.1 is bne.b _L1_5x # no 905 1.1 is bsr.l src_qnan # yes 906 1.1 is bra.b _L1_6x 907 1.1 is _L1_5x: 908 1.1 is bsr.l scosd # operand is a DENORM 909 1.1 is _L1_6x: 910 1.1 is 911 1.1 is # 912 1.1 is # Result is now in FP0 913 1.1 is # 914 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 915 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 916 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 917 1.1 is unlk %a6 918 1.1 is rts 919 1.1 is 920 1.1 is 921 1.1 is ######################################################################### 922 1.1 is # MONADIC TEMPLATE # 923 1.1 is ######################################################################### 924 1.1 is global _fsinhs_ 925 1.1 is _fsinhs_: 926 1.1 is link %a6,&-LOCAL_SIZE 927 1.1 is 928 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 929 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 930 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 931 1.1 is 932 1.1 is fmov.l &0x0,%fpcr # zero FPCR 933 1.1 is 934 1.1 is # 935 1.1 is # copy, convert, and tag input argument 936 1.1 is # 937 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 938 1.1 is fmov.x %fp0,FP_SRC(%a6) 939 1.1 is lea FP_SRC(%a6),%a0 940 1.1 is bsr.l tag # fetch operand type 941 1.1 is mov.b %d0,STAG(%a6) 942 1.1 is mov.b %d0,%d1 943 1.1 is 944 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 945 1.1 is 946 1.1 is clr.l %d0 947 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 948 1.1 is 949 1.1 is tst.b %d1 950 1.1 is bne.b _L2_2s 951 1.1 is bsr.l ssinh # operand is a NORM 952 1.1 is bra.b _L2_6s 953 1.1 is _L2_2s: 954 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 955 1.1 is bne.b _L2_3s # no 956 1.1 is bsr.l src_zero # yes 957 1.1 is bra.b _L2_6s 958 1.1 is _L2_3s: 959 1.1 is cmpi.b %d1,&INF # is operand an INF? 960 1.1 is bne.b _L2_4s # no 961 1.1 is bsr.l src_inf # yes 962 1.1 is bra.b _L2_6s 963 1.1 is _L2_4s: 964 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 965 1.1 is bne.b _L2_5s # no 966 1.1 is bsr.l src_qnan # yes 967 1.1 is bra.b _L2_6s 968 1.1 is _L2_5s: 969 1.1 is bsr.l ssinhd # operand is a DENORM 970 1.1 is _L2_6s: 971 1.1 is 972 1.1 is # 973 1.1 is # Result is now in FP0 974 1.1 is # 975 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 976 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 977 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 978 1.1 is unlk %a6 979 1.1 is rts 980 1.1 is 981 1.1 is global _fsinhd_ 982 1.1 is _fsinhd_: 983 1.1 is link %a6,&-LOCAL_SIZE 984 1.1 is 985 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 986 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 987 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 988 1.1 is 989 1.1 is fmov.l &0x0,%fpcr # zero FPCR 990 1.1 is 991 1.1 is # 992 1.1 is # copy, convert, and tag input argument 993 1.1 is # 994 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 995 1.1 is fmov.x %fp0,FP_SRC(%a6) 996 1.1 is lea FP_SRC(%a6),%a0 997 1.1 is bsr.l tag # fetch operand type 998 1.1 is mov.b %d0,STAG(%a6) 999 1.1 is mov.b %d0,%d1 1000 1.1 is 1001 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1002 1.1 is 1003 1.1 is clr.l %d0 1004 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1005 1.1 is 1006 1.1 is mov.b %d1,STAG(%a6) 1007 1.1 is tst.b %d1 1008 1.1 is bne.b _L2_2d 1009 1.1 is bsr.l ssinh # operand is a NORM 1010 1.1 is bra.b _L2_6d 1011 1.1 is _L2_2d: 1012 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1013 1.1 is bne.b _L2_3d # no 1014 1.1 is bsr.l src_zero # yes 1015 1.1 is bra.b _L2_6d 1016 1.1 is _L2_3d: 1017 1.1 is cmpi.b %d1,&INF # is operand an INF? 1018 1.1 is bne.b _L2_4d # no 1019 1.1 is bsr.l src_inf # yes 1020 1.1 is bra.b _L2_6d 1021 1.1 is _L2_4d: 1022 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1023 1.1 is bne.b _L2_5d # no 1024 1.1 is bsr.l src_qnan # yes 1025 1.1 is bra.b _L2_6d 1026 1.1 is _L2_5d: 1027 1.1 is bsr.l ssinhd # operand is a DENORM 1028 1.1 is _L2_6d: 1029 1.1 is 1030 1.1 is # 1031 1.1 is # Result is now in FP0 1032 1.1 is # 1033 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1034 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1035 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1036 1.1 is unlk %a6 1037 1.1 is rts 1038 1.1 is 1039 1.1 is global _fsinhx_ 1040 1.1 is _fsinhx_: 1041 1.1 is link %a6,&-LOCAL_SIZE 1042 1.1 is 1043 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1044 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1045 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1046 1.1 is 1047 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1048 1.1 is 1049 1.1 is # 1050 1.1 is # copy, convert, and tag input argument 1051 1.1 is # 1052 1.1 is lea FP_SRC(%a6),%a0 1053 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 1054 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 1055 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 1056 1.1 is bsr.l tag # fetch operand type 1057 1.1 is mov.b %d0,STAG(%a6) 1058 1.1 is mov.b %d0,%d1 1059 1.1 is 1060 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1061 1.1 is 1062 1.1 is clr.l %d0 1063 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1064 1.1 is 1065 1.1 is tst.b %d1 1066 1.1 is bne.b _L2_2x 1067 1.1 is bsr.l ssinh # operand is a NORM 1068 1.1 is bra.b _L2_6x 1069 1.1 is _L2_2x: 1070 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1071 1.1 is bne.b _L2_3x # no 1072 1.1 is bsr.l src_zero # yes 1073 1.1 is bra.b _L2_6x 1074 1.1 is _L2_3x: 1075 1.1 is cmpi.b %d1,&INF # is operand an INF? 1076 1.1 is bne.b _L2_4x # no 1077 1.1 is bsr.l src_inf # yes 1078 1.1 is bra.b _L2_6x 1079 1.1 is _L2_4x: 1080 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1081 1.1 is bne.b _L2_5x # no 1082 1.1 is bsr.l src_qnan # yes 1083 1.1 is bra.b _L2_6x 1084 1.1 is _L2_5x: 1085 1.1 is bsr.l ssinhd # operand is a DENORM 1086 1.1 is _L2_6x: 1087 1.1 is 1088 1.1 is # 1089 1.1 is # Result is now in FP0 1090 1.1 is # 1091 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1092 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1093 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1094 1.1 is unlk %a6 1095 1.1 is rts 1096 1.1 is 1097 1.1 is 1098 1.1 is ######################################################################### 1099 1.1 is # MONADIC TEMPLATE # 1100 1.1 is ######################################################################### 1101 1.1 is global _flognp1s_ 1102 1.1 is _flognp1s_: 1103 1.1 is link %a6,&-LOCAL_SIZE 1104 1.1 is 1105 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1106 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1107 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1108 1.1 is 1109 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1110 1.1 is 1111 1.1 is # 1112 1.1 is # copy, convert, and tag input argument 1113 1.1 is # 1114 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 1115 1.1 is fmov.x %fp0,FP_SRC(%a6) 1116 1.1 is lea FP_SRC(%a6),%a0 1117 1.1 is bsr.l tag # fetch operand type 1118 1.1 is mov.b %d0,STAG(%a6) 1119 1.1 is mov.b %d0,%d1 1120 1.1 is 1121 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1122 1.1 is 1123 1.1 is clr.l %d0 1124 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1125 1.1 is 1126 1.1 is tst.b %d1 1127 1.1 is bne.b _L3_2s 1128 1.1 is bsr.l slognp1 # operand is a NORM 1129 1.1 is bra.b _L3_6s 1130 1.1 is _L3_2s: 1131 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1132 1.1 is bne.b _L3_3s # no 1133 1.1 is bsr.l src_zero # yes 1134 1.1 is bra.b _L3_6s 1135 1.1 is _L3_3s: 1136 1.1 is cmpi.b %d1,&INF # is operand an INF? 1137 1.1 is bne.b _L3_4s # no 1138 1.1 is bsr.l sopr_inf # yes 1139 1.1 is bra.b _L3_6s 1140 1.1 is _L3_4s: 1141 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1142 1.1 is bne.b _L3_5s # no 1143 1.1 is bsr.l src_qnan # yes 1144 1.1 is bra.b _L3_6s 1145 1.1 is _L3_5s: 1146 1.1 is bsr.l slognp1d # operand is a DENORM 1147 1.1 is _L3_6s: 1148 1.1 is 1149 1.1 is # 1150 1.1 is # Result is now in FP0 1151 1.1 is # 1152 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1153 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1154 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1155 1.1 is unlk %a6 1156 1.1 is rts 1157 1.1 is 1158 1.1 is global _flognp1d_ 1159 1.1 is _flognp1d_: 1160 1.1 is link %a6,&-LOCAL_SIZE 1161 1.1 is 1162 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1163 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1164 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1165 1.1 is 1166 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1167 1.1 is 1168 1.1 is # 1169 1.1 is # copy, convert, and tag input argument 1170 1.1 is # 1171 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 1172 1.1 is fmov.x %fp0,FP_SRC(%a6) 1173 1.1 is lea FP_SRC(%a6),%a0 1174 1.1 is bsr.l tag # fetch operand type 1175 1.1 is mov.b %d0,STAG(%a6) 1176 1.1 is mov.b %d0,%d1 1177 1.1 is 1178 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1179 1.1 is 1180 1.1 is clr.l %d0 1181 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1182 1.1 is 1183 1.1 is mov.b %d1,STAG(%a6) 1184 1.1 is tst.b %d1 1185 1.1 is bne.b _L3_2d 1186 1.1 is bsr.l slognp1 # operand is a NORM 1187 1.1 is bra.b _L3_6d 1188 1.1 is _L3_2d: 1189 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1190 1.1 is bne.b _L3_3d # no 1191 1.1 is bsr.l src_zero # yes 1192 1.1 is bra.b _L3_6d 1193 1.1 is _L3_3d: 1194 1.1 is cmpi.b %d1,&INF # is operand an INF? 1195 1.1 is bne.b _L3_4d # no 1196 1.1 is bsr.l sopr_inf # yes 1197 1.1 is bra.b _L3_6d 1198 1.1 is _L3_4d: 1199 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1200 1.1 is bne.b _L3_5d # no 1201 1.1 is bsr.l src_qnan # yes 1202 1.1 is bra.b _L3_6d 1203 1.1 is _L3_5d: 1204 1.1 is bsr.l slognp1d # operand is a DENORM 1205 1.1 is _L3_6d: 1206 1.1 is 1207 1.1 is # 1208 1.1 is # Result is now in FP0 1209 1.1 is # 1210 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1211 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1212 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1213 1.1 is unlk %a6 1214 1.1 is rts 1215 1.1 is 1216 1.1 is global _flognp1x_ 1217 1.1 is _flognp1x_: 1218 1.1 is link %a6,&-LOCAL_SIZE 1219 1.1 is 1220 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1221 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1222 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1223 1.1 is 1224 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1225 1.1 is 1226 1.1 is # 1227 1.1 is # copy, convert, and tag input argument 1228 1.1 is # 1229 1.1 is lea FP_SRC(%a6),%a0 1230 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 1231 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 1232 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 1233 1.1 is bsr.l tag # fetch operand type 1234 1.1 is mov.b %d0,STAG(%a6) 1235 1.1 is mov.b %d0,%d1 1236 1.1 is 1237 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1238 1.1 is 1239 1.1 is clr.l %d0 1240 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1241 1.1 is 1242 1.1 is tst.b %d1 1243 1.1 is bne.b _L3_2x 1244 1.1 is bsr.l slognp1 # operand is a NORM 1245 1.1 is bra.b _L3_6x 1246 1.1 is _L3_2x: 1247 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1248 1.1 is bne.b _L3_3x # no 1249 1.1 is bsr.l src_zero # yes 1250 1.1 is bra.b _L3_6x 1251 1.1 is _L3_3x: 1252 1.1 is cmpi.b %d1,&INF # is operand an INF? 1253 1.1 is bne.b _L3_4x # no 1254 1.1 is bsr.l sopr_inf # yes 1255 1.1 is bra.b _L3_6x 1256 1.1 is _L3_4x: 1257 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1258 1.1 is bne.b _L3_5x # no 1259 1.1 is bsr.l src_qnan # yes 1260 1.1 is bra.b _L3_6x 1261 1.1 is _L3_5x: 1262 1.1 is bsr.l slognp1d # operand is a DENORM 1263 1.1 is _L3_6x: 1264 1.1 is 1265 1.1 is # 1266 1.1 is # Result is now in FP0 1267 1.1 is # 1268 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1269 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1270 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1271 1.1 is unlk %a6 1272 1.1 is rts 1273 1.1 is 1274 1.1 is 1275 1.1 is ######################################################################### 1276 1.1 is # MONADIC TEMPLATE # 1277 1.1 is ######################################################################### 1278 1.1 is global _fetoxm1s_ 1279 1.1 is _fetoxm1s_: 1280 1.1 is link %a6,&-LOCAL_SIZE 1281 1.1 is 1282 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1283 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1284 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1285 1.1 is 1286 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1287 1.1 is 1288 1.1 is # 1289 1.1 is # copy, convert, and tag input argument 1290 1.1 is # 1291 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 1292 1.1 is fmov.x %fp0,FP_SRC(%a6) 1293 1.1 is lea FP_SRC(%a6),%a0 1294 1.1 is bsr.l tag # fetch operand type 1295 1.1 is mov.b %d0,STAG(%a6) 1296 1.1 is mov.b %d0,%d1 1297 1.1 is 1298 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1299 1.1 is 1300 1.1 is clr.l %d0 1301 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1302 1.1 is 1303 1.1 is tst.b %d1 1304 1.1 is bne.b _L4_2s 1305 1.1 is bsr.l setoxm1 # operand is a NORM 1306 1.1 is bra.b _L4_6s 1307 1.1 is _L4_2s: 1308 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1309 1.1 is bne.b _L4_3s # no 1310 1.1 is bsr.l src_zero # yes 1311 1.1 is bra.b _L4_6s 1312 1.1 is _L4_3s: 1313 1.1 is cmpi.b %d1,&INF # is operand an INF? 1314 1.1 is bne.b _L4_4s # no 1315 1.1 is bsr.l setoxm1i # yes 1316 1.1 is bra.b _L4_6s 1317 1.1 is _L4_4s: 1318 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1319 1.1 is bne.b _L4_5s # no 1320 1.1 is bsr.l src_qnan # yes 1321 1.1 is bra.b _L4_6s 1322 1.1 is _L4_5s: 1323 1.1 is bsr.l setoxm1d # operand is a DENORM 1324 1.1 is _L4_6s: 1325 1.1 is 1326 1.1 is # 1327 1.1 is # Result is now in FP0 1328 1.1 is # 1329 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1330 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1331 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1332 1.1 is unlk %a6 1333 1.1 is rts 1334 1.1 is 1335 1.1 is global _fetoxm1d_ 1336 1.1 is _fetoxm1d_: 1337 1.1 is link %a6,&-LOCAL_SIZE 1338 1.1 is 1339 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1340 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1341 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1342 1.1 is 1343 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1344 1.1 is 1345 1.1 is # 1346 1.1 is # copy, convert, and tag input argument 1347 1.1 is # 1348 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 1349 1.1 is fmov.x %fp0,FP_SRC(%a6) 1350 1.1 is lea FP_SRC(%a6),%a0 1351 1.1 is bsr.l tag # fetch operand type 1352 1.1 is mov.b %d0,STAG(%a6) 1353 1.1 is mov.b %d0,%d1 1354 1.1 is 1355 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1356 1.1 is 1357 1.1 is clr.l %d0 1358 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1359 1.1 is 1360 1.1 is mov.b %d1,STAG(%a6) 1361 1.1 is tst.b %d1 1362 1.1 is bne.b _L4_2d 1363 1.1 is bsr.l setoxm1 # operand is a NORM 1364 1.1 is bra.b _L4_6d 1365 1.1 is _L4_2d: 1366 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1367 1.1 is bne.b _L4_3d # no 1368 1.1 is bsr.l src_zero # yes 1369 1.1 is bra.b _L4_6d 1370 1.1 is _L4_3d: 1371 1.1 is cmpi.b %d1,&INF # is operand an INF? 1372 1.1 is bne.b _L4_4d # no 1373 1.1 is bsr.l setoxm1i # yes 1374 1.1 is bra.b _L4_6d 1375 1.1 is _L4_4d: 1376 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1377 1.1 is bne.b _L4_5d # no 1378 1.1 is bsr.l src_qnan # yes 1379 1.1 is bra.b _L4_6d 1380 1.1 is _L4_5d: 1381 1.1 is bsr.l setoxm1d # operand is a DENORM 1382 1.1 is _L4_6d: 1383 1.1 is 1384 1.1 is # 1385 1.1 is # Result is now in FP0 1386 1.1 is # 1387 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1388 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1389 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1390 1.1 is unlk %a6 1391 1.1 is rts 1392 1.1 is 1393 1.1 is global _fetoxm1x_ 1394 1.1 is _fetoxm1x_: 1395 1.1 is link %a6,&-LOCAL_SIZE 1396 1.1 is 1397 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1398 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1399 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1400 1.1 is 1401 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1402 1.1 is 1403 1.1 is # 1404 1.1 is # copy, convert, and tag input argument 1405 1.1 is # 1406 1.1 is lea FP_SRC(%a6),%a0 1407 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 1408 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 1409 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 1410 1.1 is bsr.l tag # fetch operand type 1411 1.1 is mov.b %d0,STAG(%a6) 1412 1.1 is mov.b %d0,%d1 1413 1.1 is 1414 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1415 1.1 is 1416 1.1 is clr.l %d0 1417 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1418 1.1 is 1419 1.1 is tst.b %d1 1420 1.1 is bne.b _L4_2x 1421 1.1 is bsr.l setoxm1 # operand is a NORM 1422 1.1 is bra.b _L4_6x 1423 1.1 is _L4_2x: 1424 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1425 1.1 is bne.b _L4_3x # no 1426 1.1 is bsr.l src_zero # yes 1427 1.1 is bra.b _L4_6x 1428 1.1 is _L4_3x: 1429 1.1 is cmpi.b %d1,&INF # is operand an INF? 1430 1.1 is bne.b _L4_4x # no 1431 1.1 is bsr.l setoxm1i # yes 1432 1.1 is bra.b _L4_6x 1433 1.1 is _L4_4x: 1434 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1435 1.1 is bne.b _L4_5x # no 1436 1.1 is bsr.l src_qnan # yes 1437 1.1 is bra.b _L4_6x 1438 1.1 is _L4_5x: 1439 1.1 is bsr.l setoxm1d # operand is a DENORM 1440 1.1 is _L4_6x: 1441 1.1 is 1442 1.1 is # 1443 1.1 is # Result is now in FP0 1444 1.1 is # 1445 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1446 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1447 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1448 1.1 is unlk %a6 1449 1.1 is rts 1450 1.1 is 1451 1.1 is 1452 1.1 is ######################################################################### 1453 1.1 is # MONADIC TEMPLATE # 1454 1.1 is ######################################################################### 1455 1.1 is global _ftanhs_ 1456 1.1 is _ftanhs_: 1457 1.1 is link %a6,&-LOCAL_SIZE 1458 1.1 is 1459 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1460 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1461 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1462 1.1 is 1463 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1464 1.1 is 1465 1.1 is # 1466 1.1 is # copy, convert, and tag input argument 1467 1.1 is # 1468 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 1469 1.1 is fmov.x %fp0,FP_SRC(%a6) 1470 1.1 is lea FP_SRC(%a6),%a0 1471 1.1 is bsr.l tag # fetch operand type 1472 1.1 is mov.b %d0,STAG(%a6) 1473 1.1 is mov.b %d0,%d1 1474 1.1 is 1475 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1476 1.1 is 1477 1.1 is clr.l %d0 1478 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1479 1.1 is 1480 1.1 is tst.b %d1 1481 1.1 is bne.b _L5_2s 1482 1.1 is bsr.l stanh # operand is a NORM 1483 1.1 is bra.b _L5_6s 1484 1.1 is _L5_2s: 1485 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1486 1.1 is bne.b _L5_3s # no 1487 1.1 is bsr.l src_zero # yes 1488 1.1 is bra.b _L5_6s 1489 1.1 is _L5_3s: 1490 1.1 is cmpi.b %d1,&INF # is operand an INF? 1491 1.1 is bne.b _L5_4s # no 1492 1.1 is bsr.l src_one # yes 1493 1.1 is bra.b _L5_6s 1494 1.1 is _L5_4s: 1495 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1496 1.1 is bne.b _L5_5s # no 1497 1.1 is bsr.l src_qnan # yes 1498 1.1 is bra.b _L5_6s 1499 1.1 is _L5_5s: 1500 1.1 is bsr.l stanhd # operand is a DENORM 1501 1.1 is _L5_6s: 1502 1.1 is 1503 1.1 is # 1504 1.1 is # Result is now in FP0 1505 1.1 is # 1506 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1507 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1508 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1509 1.1 is unlk %a6 1510 1.1 is rts 1511 1.1 is 1512 1.1 is global _ftanhd_ 1513 1.1 is _ftanhd_: 1514 1.1 is link %a6,&-LOCAL_SIZE 1515 1.1 is 1516 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1517 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1518 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1519 1.1 is 1520 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1521 1.1 is 1522 1.1 is # 1523 1.1 is # copy, convert, and tag input argument 1524 1.1 is # 1525 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 1526 1.1 is fmov.x %fp0,FP_SRC(%a6) 1527 1.1 is lea FP_SRC(%a6),%a0 1528 1.1 is bsr.l tag # fetch operand type 1529 1.1 is mov.b %d0,STAG(%a6) 1530 1.1 is mov.b %d0,%d1 1531 1.1 is 1532 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1533 1.1 is 1534 1.1 is clr.l %d0 1535 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1536 1.1 is 1537 1.1 is mov.b %d1,STAG(%a6) 1538 1.1 is tst.b %d1 1539 1.1 is bne.b _L5_2d 1540 1.1 is bsr.l stanh # operand is a NORM 1541 1.1 is bra.b _L5_6d 1542 1.1 is _L5_2d: 1543 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1544 1.1 is bne.b _L5_3d # no 1545 1.1 is bsr.l src_zero # yes 1546 1.1 is bra.b _L5_6d 1547 1.1 is _L5_3d: 1548 1.1 is cmpi.b %d1,&INF # is operand an INF? 1549 1.1 is bne.b _L5_4d # no 1550 1.1 is bsr.l src_one # yes 1551 1.1 is bra.b _L5_6d 1552 1.1 is _L5_4d: 1553 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1554 1.1 is bne.b _L5_5d # no 1555 1.1 is bsr.l src_qnan # yes 1556 1.1 is bra.b _L5_6d 1557 1.1 is _L5_5d: 1558 1.1 is bsr.l stanhd # operand is a DENORM 1559 1.1 is _L5_6d: 1560 1.1 is 1561 1.1 is # 1562 1.1 is # Result is now in FP0 1563 1.1 is # 1564 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1565 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1566 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1567 1.1 is unlk %a6 1568 1.1 is rts 1569 1.1 is 1570 1.1 is global _ftanhx_ 1571 1.1 is _ftanhx_: 1572 1.1 is link %a6,&-LOCAL_SIZE 1573 1.1 is 1574 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1575 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1576 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1577 1.1 is 1578 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1579 1.1 is 1580 1.1 is # 1581 1.1 is # copy, convert, and tag input argument 1582 1.1 is # 1583 1.1 is lea FP_SRC(%a6),%a0 1584 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 1585 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 1586 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 1587 1.1 is bsr.l tag # fetch operand type 1588 1.1 is mov.b %d0,STAG(%a6) 1589 1.1 is mov.b %d0,%d1 1590 1.1 is 1591 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1592 1.1 is 1593 1.1 is clr.l %d0 1594 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1595 1.1 is 1596 1.1 is tst.b %d1 1597 1.1 is bne.b _L5_2x 1598 1.1 is bsr.l stanh # operand is a NORM 1599 1.1 is bra.b _L5_6x 1600 1.1 is _L5_2x: 1601 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1602 1.1 is bne.b _L5_3x # no 1603 1.1 is bsr.l src_zero # yes 1604 1.1 is bra.b _L5_6x 1605 1.1 is _L5_3x: 1606 1.1 is cmpi.b %d1,&INF # is operand an INF? 1607 1.1 is bne.b _L5_4x # no 1608 1.1 is bsr.l src_one # yes 1609 1.1 is bra.b _L5_6x 1610 1.1 is _L5_4x: 1611 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1612 1.1 is bne.b _L5_5x # no 1613 1.1 is bsr.l src_qnan # yes 1614 1.1 is bra.b _L5_6x 1615 1.1 is _L5_5x: 1616 1.1 is bsr.l stanhd # operand is a DENORM 1617 1.1 is _L5_6x: 1618 1.1 is 1619 1.1 is # 1620 1.1 is # Result is now in FP0 1621 1.1 is # 1622 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1623 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1624 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1625 1.1 is unlk %a6 1626 1.1 is rts 1627 1.1 is 1628 1.1 is 1629 1.1 is ######################################################################### 1630 1.1 is # MONADIC TEMPLATE # 1631 1.1 is ######################################################################### 1632 1.1 is global _fatans_ 1633 1.1 is _fatans_: 1634 1.1 is link %a6,&-LOCAL_SIZE 1635 1.1 is 1636 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1637 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1638 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1639 1.1 is 1640 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1641 1.1 is 1642 1.1 is # 1643 1.1 is # copy, convert, and tag input argument 1644 1.1 is # 1645 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 1646 1.1 is fmov.x %fp0,FP_SRC(%a6) 1647 1.1 is lea FP_SRC(%a6),%a0 1648 1.1 is bsr.l tag # fetch operand type 1649 1.1 is mov.b %d0,STAG(%a6) 1650 1.1 is mov.b %d0,%d1 1651 1.1 is 1652 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1653 1.1 is 1654 1.1 is clr.l %d0 1655 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1656 1.1 is 1657 1.1 is tst.b %d1 1658 1.1 is bne.b _L6_2s 1659 1.1 is bsr.l satan # operand is a NORM 1660 1.1 is bra.b _L6_6s 1661 1.1 is _L6_2s: 1662 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1663 1.1 is bne.b _L6_3s # no 1664 1.1 is bsr.l src_zero # yes 1665 1.1 is bra.b _L6_6s 1666 1.1 is _L6_3s: 1667 1.1 is cmpi.b %d1,&INF # is operand an INF? 1668 1.1 is bne.b _L6_4s # no 1669 1.1 is bsr.l spi_2 # yes 1670 1.1 is bra.b _L6_6s 1671 1.1 is _L6_4s: 1672 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1673 1.1 is bne.b _L6_5s # no 1674 1.1 is bsr.l src_qnan # yes 1675 1.1 is bra.b _L6_6s 1676 1.1 is _L6_5s: 1677 1.1 is bsr.l satand # operand is a DENORM 1678 1.1 is _L6_6s: 1679 1.1 is 1680 1.1 is # 1681 1.1 is # Result is now in FP0 1682 1.1 is # 1683 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1684 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1685 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1686 1.1 is unlk %a6 1687 1.1 is rts 1688 1.1 is 1689 1.1 is global _fatand_ 1690 1.1 is _fatand_: 1691 1.1 is link %a6,&-LOCAL_SIZE 1692 1.1 is 1693 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1694 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1695 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1696 1.1 is 1697 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1698 1.1 is 1699 1.1 is # 1700 1.1 is # copy, convert, and tag input argument 1701 1.1 is # 1702 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 1703 1.1 is fmov.x %fp0,FP_SRC(%a6) 1704 1.1 is lea FP_SRC(%a6),%a0 1705 1.1 is bsr.l tag # fetch operand type 1706 1.1 is mov.b %d0,STAG(%a6) 1707 1.1 is mov.b %d0,%d1 1708 1.1 is 1709 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1710 1.1 is 1711 1.1 is clr.l %d0 1712 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1713 1.1 is 1714 1.1 is mov.b %d1,STAG(%a6) 1715 1.1 is tst.b %d1 1716 1.1 is bne.b _L6_2d 1717 1.1 is bsr.l satan # operand is a NORM 1718 1.1 is bra.b _L6_6d 1719 1.1 is _L6_2d: 1720 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1721 1.1 is bne.b _L6_3d # no 1722 1.1 is bsr.l src_zero # yes 1723 1.1 is bra.b _L6_6d 1724 1.1 is _L6_3d: 1725 1.1 is cmpi.b %d1,&INF # is operand an INF? 1726 1.1 is bne.b _L6_4d # no 1727 1.1 is bsr.l spi_2 # yes 1728 1.1 is bra.b _L6_6d 1729 1.1 is _L6_4d: 1730 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1731 1.1 is bne.b _L6_5d # no 1732 1.1 is bsr.l src_qnan # yes 1733 1.1 is bra.b _L6_6d 1734 1.1 is _L6_5d: 1735 1.1 is bsr.l satand # operand is a DENORM 1736 1.1 is _L6_6d: 1737 1.1 is 1738 1.1 is # 1739 1.1 is # Result is now in FP0 1740 1.1 is # 1741 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1742 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1743 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1744 1.1 is unlk %a6 1745 1.1 is rts 1746 1.1 is 1747 1.1 is global _fatanx_ 1748 1.1 is _fatanx_: 1749 1.1 is link %a6,&-LOCAL_SIZE 1750 1.1 is 1751 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1752 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1753 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1754 1.1 is 1755 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1756 1.1 is 1757 1.1 is # 1758 1.1 is # copy, convert, and tag input argument 1759 1.1 is # 1760 1.1 is lea FP_SRC(%a6),%a0 1761 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 1762 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 1763 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 1764 1.1 is bsr.l tag # fetch operand type 1765 1.1 is mov.b %d0,STAG(%a6) 1766 1.1 is mov.b %d0,%d1 1767 1.1 is 1768 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1769 1.1 is 1770 1.1 is clr.l %d0 1771 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1772 1.1 is 1773 1.1 is tst.b %d1 1774 1.1 is bne.b _L6_2x 1775 1.1 is bsr.l satan # operand is a NORM 1776 1.1 is bra.b _L6_6x 1777 1.1 is _L6_2x: 1778 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1779 1.1 is bne.b _L6_3x # no 1780 1.1 is bsr.l src_zero # yes 1781 1.1 is bra.b _L6_6x 1782 1.1 is _L6_3x: 1783 1.1 is cmpi.b %d1,&INF # is operand an INF? 1784 1.1 is bne.b _L6_4x # no 1785 1.1 is bsr.l spi_2 # yes 1786 1.1 is bra.b _L6_6x 1787 1.1 is _L6_4x: 1788 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1789 1.1 is bne.b _L6_5x # no 1790 1.1 is bsr.l src_qnan # yes 1791 1.1 is bra.b _L6_6x 1792 1.1 is _L6_5x: 1793 1.1 is bsr.l satand # operand is a DENORM 1794 1.1 is _L6_6x: 1795 1.1 is 1796 1.1 is # 1797 1.1 is # Result is now in FP0 1798 1.1 is # 1799 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1800 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1801 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1802 1.1 is unlk %a6 1803 1.1 is rts 1804 1.1 is 1805 1.1 is 1806 1.1 is ######################################################################### 1807 1.1 is # MONADIC TEMPLATE # 1808 1.1 is ######################################################################### 1809 1.1 is global _fasins_ 1810 1.1 is _fasins_: 1811 1.1 is link %a6,&-LOCAL_SIZE 1812 1.1 is 1813 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1814 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1815 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1816 1.1 is 1817 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1818 1.1 is 1819 1.1 is # 1820 1.1 is # copy, convert, and tag input argument 1821 1.1 is # 1822 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 1823 1.1 is fmov.x %fp0,FP_SRC(%a6) 1824 1.1 is lea FP_SRC(%a6),%a0 1825 1.1 is bsr.l tag # fetch operand type 1826 1.1 is mov.b %d0,STAG(%a6) 1827 1.1 is mov.b %d0,%d1 1828 1.1 is 1829 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1830 1.1 is 1831 1.1 is clr.l %d0 1832 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1833 1.1 is 1834 1.1 is tst.b %d1 1835 1.1 is bne.b _L7_2s 1836 1.1 is bsr.l sasin # operand is a NORM 1837 1.1 is bra.b _L7_6s 1838 1.1 is _L7_2s: 1839 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1840 1.1 is bne.b _L7_3s # no 1841 1.1 is bsr.l src_zero # yes 1842 1.1 is bra.b _L7_6s 1843 1.1 is _L7_3s: 1844 1.1 is cmpi.b %d1,&INF # is operand an INF? 1845 1.1 is bne.b _L7_4s # no 1846 1.1 is bsr.l t_operr # yes 1847 1.1 is bra.b _L7_6s 1848 1.1 is _L7_4s: 1849 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1850 1.1 is bne.b _L7_5s # no 1851 1.1 is bsr.l src_qnan # yes 1852 1.1 is bra.b _L7_6s 1853 1.1 is _L7_5s: 1854 1.1 is bsr.l sasind # operand is a DENORM 1855 1.1 is _L7_6s: 1856 1.1 is 1857 1.1 is # 1858 1.1 is # Result is now in FP0 1859 1.1 is # 1860 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1861 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1862 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1863 1.1 is unlk %a6 1864 1.1 is rts 1865 1.1 is 1866 1.1 is global _fasind_ 1867 1.1 is _fasind_: 1868 1.1 is link %a6,&-LOCAL_SIZE 1869 1.1 is 1870 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1871 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1872 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1873 1.1 is 1874 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1875 1.1 is 1876 1.1 is # 1877 1.1 is # copy, convert, and tag input argument 1878 1.1 is # 1879 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 1880 1.1 is fmov.x %fp0,FP_SRC(%a6) 1881 1.1 is lea FP_SRC(%a6),%a0 1882 1.1 is bsr.l tag # fetch operand type 1883 1.1 is mov.b %d0,STAG(%a6) 1884 1.1 is mov.b %d0,%d1 1885 1.1 is 1886 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1887 1.1 is 1888 1.1 is clr.l %d0 1889 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1890 1.1 is 1891 1.1 is mov.b %d1,STAG(%a6) 1892 1.1 is tst.b %d1 1893 1.1 is bne.b _L7_2d 1894 1.1 is bsr.l sasin # operand is a NORM 1895 1.1 is bra.b _L7_6d 1896 1.1 is _L7_2d: 1897 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1898 1.1 is bne.b _L7_3d # no 1899 1.1 is bsr.l src_zero # yes 1900 1.1 is bra.b _L7_6d 1901 1.1 is _L7_3d: 1902 1.1 is cmpi.b %d1,&INF # is operand an INF? 1903 1.1 is bne.b _L7_4d # no 1904 1.1 is bsr.l t_operr # yes 1905 1.1 is bra.b _L7_6d 1906 1.1 is _L7_4d: 1907 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1908 1.1 is bne.b _L7_5d # no 1909 1.1 is bsr.l src_qnan # yes 1910 1.1 is bra.b _L7_6d 1911 1.1 is _L7_5d: 1912 1.1 is bsr.l sasind # operand is a DENORM 1913 1.1 is _L7_6d: 1914 1.1 is 1915 1.1 is # 1916 1.1 is # Result is now in FP0 1917 1.1 is # 1918 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1919 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1920 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1921 1.1 is unlk %a6 1922 1.1 is rts 1923 1.1 is 1924 1.1 is global _fasinx_ 1925 1.1 is _fasinx_: 1926 1.1 is link %a6,&-LOCAL_SIZE 1927 1.1 is 1928 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1929 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1930 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1931 1.1 is 1932 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1933 1.1 is 1934 1.1 is # 1935 1.1 is # copy, convert, and tag input argument 1936 1.1 is # 1937 1.1 is lea FP_SRC(%a6),%a0 1938 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 1939 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 1940 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 1941 1.1 is bsr.l tag # fetch operand type 1942 1.1 is mov.b %d0,STAG(%a6) 1943 1.1 is mov.b %d0,%d1 1944 1.1 is 1945 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 1946 1.1 is 1947 1.1 is clr.l %d0 1948 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 1949 1.1 is 1950 1.1 is tst.b %d1 1951 1.1 is bne.b _L7_2x 1952 1.1 is bsr.l sasin # operand is a NORM 1953 1.1 is bra.b _L7_6x 1954 1.1 is _L7_2x: 1955 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 1956 1.1 is bne.b _L7_3x # no 1957 1.1 is bsr.l src_zero # yes 1958 1.1 is bra.b _L7_6x 1959 1.1 is _L7_3x: 1960 1.1 is cmpi.b %d1,&INF # is operand an INF? 1961 1.1 is bne.b _L7_4x # no 1962 1.1 is bsr.l t_operr # yes 1963 1.1 is bra.b _L7_6x 1964 1.1 is _L7_4x: 1965 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 1966 1.1 is bne.b _L7_5x # no 1967 1.1 is bsr.l src_qnan # yes 1968 1.1 is bra.b _L7_6x 1969 1.1 is _L7_5x: 1970 1.1 is bsr.l sasind # operand is a DENORM 1971 1.1 is _L7_6x: 1972 1.1 is 1973 1.1 is # 1974 1.1 is # Result is now in FP0 1975 1.1 is # 1976 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1977 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 1978 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 1979 1.1 is unlk %a6 1980 1.1 is rts 1981 1.1 is 1982 1.1 is 1983 1.1 is ######################################################################### 1984 1.1 is # MONADIC TEMPLATE # 1985 1.1 is ######################################################################### 1986 1.1 is global _fatanhs_ 1987 1.1 is _fatanhs_: 1988 1.1 is link %a6,&-LOCAL_SIZE 1989 1.1 is 1990 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1991 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 1992 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 1993 1.1 is 1994 1.1 is fmov.l &0x0,%fpcr # zero FPCR 1995 1.1 is 1996 1.1 is # 1997 1.1 is # copy, convert, and tag input argument 1998 1.1 is # 1999 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 2000 1.1 is fmov.x %fp0,FP_SRC(%a6) 2001 1.1 is lea FP_SRC(%a6),%a0 2002 1.1 is bsr.l tag # fetch operand type 2003 1.1 is mov.b %d0,STAG(%a6) 2004 1.1 is mov.b %d0,%d1 2005 1.1 is 2006 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2007 1.1 is 2008 1.1 is clr.l %d0 2009 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2010 1.1 is 2011 1.1 is tst.b %d1 2012 1.1 is bne.b _L8_2s 2013 1.1 is bsr.l satanh # operand is a NORM 2014 1.1 is bra.b _L8_6s 2015 1.1 is _L8_2s: 2016 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2017 1.1 is bne.b _L8_3s # no 2018 1.1 is bsr.l src_zero # yes 2019 1.1 is bra.b _L8_6s 2020 1.1 is _L8_3s: 2021 1.1 is cmpi.b %d1,&INF # is operand an INF? 2022 1.1 is bne.b _L8_4s # no 2023 1.1 is bsr.l t_operr # yes 2024 1.1 is bra.b _L8_6s 2025 1.1 is _L8_4s: 2026 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2027 1.1 is bne.b _L8_5s # no 2028 1.1 is bsr.l src_qnan # yes 2029 1.1 is bra.b _L8_6s 2030 1.1 is _L8_5s: 2031 1.1 is bsr.l satanhd # operand is a DENORM 2032 1.1 is _L8_6s: 2033 1.1 is 2034 1.1 is # 2035 1.1 is # Result is now in FP0 2036 1.1 is # 2037 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2038 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2039 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2040 1.1 is unlk %a6 2041 1.1 is rts 2042 1.1 is 2043 1.1 is global _fatanhd_ 2044 1.1 is _fatanhd_: 2045 1.1 is link %a6,&-LOCAL_SIZE 2046 1.1 is 2047 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2048 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2049 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2050 1.1 is 2051 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2052 1.1 is 2053 1.1 is # 2054 1.1 is # copy, convert, and tag input argument 2055 1.1 is # 2056 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 2057 1.1 is fmov.x %fp0,FP_SRC(%a6) 2058 1.1 is lea FP_SRC(%a6),%a0 2059 1.1 is bsr.l tag # fetch operand type 2060 1.1 is mov.b %d0,STAG(%a6) 2061 1.1 is mov.b %d0,%d1 2062 1.1 is 2063 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2064 1.1 is 2065 1.1 is clr.l %d0 2066 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2067 1.1 is 2068 1.1 is mov.b %d1,STAG(%a6) 2069 1.1 is tst.b %d1 2070 1.1 is bne.b _L8_2d 2071 1.1 is bsr.l satanh # operand is a NORM 2072 1.1 is bra.b _L8_6d 2073 1.1 is _L8_2d: 2074 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2075 1.1 is bne.b _L8_3d # no 2076 1.1 is bsr.l src_zero # yes 2077 1.1 is bra.b _L8_6d 2078 1.1 is _L8_3d: 2079 1.1 is cmpi.b %d1,&INF # is operand an INF? 2080 1.1 is bne.b _L8_4d # no 2081 1.1 is bsr.l t_operr # yes 2082 1.1 is bra.b _L8_6d 2083 1.1 is _L8_4d: 2084 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2085 1.1 is bne.b _L8_5d # no 2086 1.1 is bsr.l src_qnan # yes 2087 1.1 is bra.b _L8_6d 2088 1.1 is _L8_5d: 2089 1.1 is bsr.l satanhd # operand is a DENORM 2090 1.1 is _L8_6d: 2091 1.1 is 2092 1.1 is # 2093 1.1 is # Result is now in FP0 2094 1.1 is # 2095 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2096 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2097 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2098 1.1 is unlk %a6 2099 1.1 is rts 2100 1.1 is 2101 1.1 is global _fatanhx_ 2102 1.1 is _fatanhx_: 2103 1.1 is link %a6,&-LOCAL_SIZE 2104 1.1 is 2105 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2106 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2107 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2108 1.1 is 2109 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2110 1.1 is 2111 1.1 is # 2112 1.1 is # copy, convert, and tag input argument 2113 1.1 is # 2114 1.1 is lea FP_SRC(%a6),%a0 2115 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 2116 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 2117 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 2118 1.1 is bsr.l tag # fetch operand type 2119 1.1 is mov.b %d0,STAG(%a6) 2120 1.1 is mov.b %d0,%d1 2121 1.1 is 2122 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2123 1.1 is 2124 1.1 is clr.l %d0 2125 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2126 1.1 is 2127 1.1 is tst.b %d1 2128 1.1 is bne.b _L8_2x 2129 1.1 is bsr.l satanh # operand is a NORM 2130 1.1 is bra.b _L8_6x 2131 1.1 is _L8_2x: 2132 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2133 1.1 is bne.b _L8_3x # no 2134 1.1 is bsr.l src_zero # yes 2135 1.1 is bra.b _L8_6x 2136 1.1 is _L8_3x: 2137 1.1 is cmpi.b %d1,&INF # is operand an INF? 2138 1.1 is bne.b _L8_4x # no 2139 1.1 is bsr.l t_operr # yes 2140 1.1 is bra.b _L8_6x 2141 1.1 is _L8_4x: 2142 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2143 1.1 is bne.b _L8_5x # no 2144 1.1 is bsr.l src_qnan # yes 2145 1.1 is bra.b _L8_6x 2146 1.1 is _L8_5x: 2147 1.1 is bsr.l satanhd # operand is a DENORM 2148 1.1 is _L8_6x: 2149 1.1 is 2150 1.1 is # 2151 1.1 is # Result is now in FP0 2152 1.1 is # 2153 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2154 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2155 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2156 1.1 is unlk %a6 2157 1.1 is rts 2158 1.1 is 2159 1.1 is 2160 1.1 is ######################################################################### 2161 1.1 is # MONADIC TEMPLATE # 2162 1.1 is ######################################################################### 2163 1.1 is global _ftans_ 2164 1.1 is _ftans_: 2165 1.1 is link %a6,&-LOCAL_SIZE 2166 1.1 is 2167 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2168 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2169 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2170 1.1 is 2171 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2172 1.1 is 2173 1.1 is # 2174 1.1 is # copy, convert, and tag input argument 2175 1.1 is # 2176 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 2177 1.1 is fmov.x %fp0,FP_SRC(%a6) 2178 1.1 is lea FP_SRC(%a6),%a0 2179 1.1 is bsr.l tag # fetch operand type 2180 1.1 is mov.b %d0,STAG(%a6) 2181 1.1 is mov.b %d0,%d1 2182 1.1 is 2183 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2184 1.1 is 2185 1.1 is clr.l %d0 2186 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2187 1.1 is 2188 1.1 is tst.b %d1 2189 1.1 is bne.b _L9_2s 2190 1.1 is bsr.l stan # operand is a NORM 2191 1.1 is bra.b _L9_6s 2192 1.1 is _L9_2s: 2193 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2194 1.1 is bne.b _L9_3s # no 2195 1.1 is bsr.l src_zero # yes 2196 1.1 is bra.b _L9_6s 2197 1.1 is _L9_3s: 2198 1.1 is cmpi.b %d1,&INF # is operand an INF? 2199 1.1 is bne.b _L9_4s # no 2200 1.1 is bsr.l t_operr # yes 2201 1.1 is bra.b _L9_6s 2202 1.1 is _L9_4s: 2203 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2204 1.1 is bne.b _L9_5s # no 2205 1.1 is bsr.l src_qnan # yes 2206 1.1 is bra.b _L9_6s 2207 1.1 is _L9_5s: 2208 1.1 is bsr.l stand # operand is a DENORM 2209 1.1 is _L9_6s: 2210 1.1 is 2211 1.1 is # 2212 1.1 is # Result is now in FP0 2213 1.1 is # 2214 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2215 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2216 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2217 1.1 is unlk %a6 2218 1.1 is rts 2219 1.1 is 2220 1.1 is global _ftand_ 2221 1.1 is _ftand_: 2222 1.1 is link %a6,&-LOCAL_SIZE 2223 1.1 is 2224 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2225 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2226 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2227 1.1 is 2228 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2229 1.1 is 2230 1.1 is # 2231 1.1 is # copy, convert, and tag input argument 2232 1.1 is # 2233 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 2234 1.1 is fmov.x %fp0,FP_SRC(%a6) 2235 1.1 is lea FP_SRC(%a6),%a0 2236 1.1 is bsr.l tag # fetch operand type 2237 1.1 is mov.b %d0,STAG(%a6) 2238 1.1 is mov.b %d0,%d1 2239 1.1 is 2240 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2241 1.1 is 2242 1.1 is clr.l %d0 2243 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2244 1.1 is 2245 1.1 is mov.b %d1,STAG(%a6) 2246 1.1 is tst.b %d1 2247 1.1 is bne.b _L9_2d 2248 1.1 is bsr.l stan # operand is a NORM 2249 1.1 is bra.b _L9_6d 2250 1.1 is _L9_2d: 2251 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2252 1.1 is bne.b _L9_3d # no 2253 1.1 is bsr.l src_zero # yes 2254 1.1 is bra.b _L9_6d 2255 1.1 is _L9_3d: 2256 1.1 is cmpi.b %d1,&INF # is operand an INF? 2257 1.1 is bne.b _L9_4d # no 2258 1.1 is bsr.l t_operr # yes 2259 1.1 is bra.b _L9_6d 2260 1.1 is _L9_4d: 2261 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2262 1.1 is bne.b _L9_5d # no 2263 1.1 is bsr.l src_qnan # yes 2264 1.1 is bra.b _L9_6d 2265 1.1 is _L9_5d: 2266 1.1 is bsr.l stand # operand is a DENORM 2267 1.1 is _L9_6d: 2268 1.1 is 2269 1.1 is # 2270 1.1 is # Result is now in FP0 2271 1.1 is # 2272 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2273 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2274 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2275 1.1 is unlk %a6 2276 1.1 is rts 2277 1.1 is 2278 1.1 is global _ftanx_ 2279 1.1 is _ftanx_: 2280 1.1 is link %a6,&-LOCAL_SIZE 2281 1.1 is 2282 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2283 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2284 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2285 1.1 is 2286 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2287 1.1 is 2288 1.1 is # 2289 1.1 is # copy, convert, and tag input argument 2290 1.1 is # 2291 1.1 is lea FP_SRC(%a6),%a0 2292 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 2293 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 2294 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 2295 1.1 is bsr.l tag # fetch operand type 2296 1.1 is mov.b %d0,STAG(%a6) 2297 1.1 is mov.b %d0,%d1 2298 1.1 is 2299 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2300 1.1 is 2301 1.1 is clr.l %d0 2302 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2303 1.1 is 2304 1.1 is tst.b %d1 2305 1.1 is bne.b _L9_2x 2306 1.1 is bsr.l stan # operand is a NORM 2307 1.1 is bra.b _L9_6x 2308 1.1 is _L9_2x: 2309 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2310 1.1 is bne.b _L9_3x # no 2311 1.1 is bsr.l src_zero # yes 2312 1.1 is bra.b _L9_6x 2313 1.1 is _L9_3x: 2314 1.1 is cmpi.b %d1,&INF # is operand an INF? 2315 1.1 is bne.b _L9_4x # no 2316 1.1 is bsr.l t_operr # yes 2317 1.1 is bra.b _L9_6x 2318 1.1 is _L9_4x: 2319 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2320 1.1 is bne.b _L9_5x # no 2321 1.1 is bsr.l src_qnan # yes 2322 1.1 is bra.b _L9_6x 2323 1.1 is _L9_5x: 2324 1.1 is bsr.l stand # operand is a DENORM 2325 1.1 is _L9_6x: 2326 1.1 is 2327 1.1 is # 2328 1.1 is # Result is now in FP0 2329 1.1 is # 2330 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2331 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2332 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2333 1.1 is unlk %a6 2334 1.1 is rts 2335 1.1 is 2336 1.1 is 2337 1.1 is ######################################################################### 2338 1.1 is # MONADIC TEMPLATE # 2339 1.1 is ######################################################################### 2340 1.1 is global _fetoxs_ 2341 1.1 is _fetoxs_: 2342 1.1 is link %a6,&-LOCAL_SIZE 2343 1.1 is 2344 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2345 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2346 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2347 1.1 is 2348 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2349 1.1 is 2350 1.1 is # 2351 1.1 is # copy, convert, and tag input argument 2352 1.1 is # 2353 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 2354 1.1 is fmov.x %fp0,FP_SRC(%a6) 2355 1.1 is lea FP_SRC(%a6),%a0 2356 1.1 is bsr.l tag # fetch operand type 2357 1.1 is mov.b %d0,STAG(%a6) 2358 1.1 is mov.b %d0,%d1 2359 1.1 is 2360 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2361 1.1 is 2362 1.1 is clr.l %d0 2363 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2364 1.1 is 2365 1.1 is tst.b %d1 2366 1.1 is bne.b _L10_2s 2367 1.1 is bsr.l setox # operand is a NORM 2368 1.1 is bra.b _L10_6s 2369 1.1 is _L10_2s: 2370 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2371 1.1 is bne.b _L10_3s # no 2372 1.1 is bsr.l ld_pone # yes 2373 1.1 is bra.b _L10_6s 2374 1.1 is _L10_3s: 2375 1.1 is cmpi.b %d1,&INF # is operand an INF? 2376 1.1 is bne.b _L10_4s # no 2377 1.1 is bsr.l szr_inf # yes 2378 1.1 is bra.b _L10_6s 2379 1.1 is _L10_4s: 2380 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2381 1.1 is bne.b _L10_5s # no 2382 1.1 is bsr.l src_qnan # yes 2383 1.1 is bra.b _L10_6s 2384 1.1 is _L10_5s: 2385 1.1 is bsr.l setoxd # operand is a DENORM 2386 1.1 is _L10_6s: 2387 1.1 is 2388 1.1 is # 2389 1.1 is # Result is now in FP0 2390 1.1 is # 2391 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2392 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2393 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2394 1.1 is unlk %a6 2395 1.1 is rts 2396 1.1 is 2397 1.1 is global _fetoxd_ 2398 1.1 is _fetoxd_: 2399 1.1 is link %a6,&-LOCAL_SIZE 2400 1.1 is 2401 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2402 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2403 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2404 1.1 is 2405 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2406 1.1 is 2407 1.1 is # 2408 1.1 is # copy, convert, and tag input argument 2409 1.1 is # 2410 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 2411 1.1 is fmov.x %fp0,FP_SRC(%a6) 2412 1.1 is lea FP_SRC(%a6),%a0 2413 1.1 is bsr.l tag # fetch operand type 2414 1.1 is mov.b %d0,STAG(%a6) 2415 1.1 is mov.b %d0,%d1 2416 1.1 is 2417 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2418 1.1 is 2419 1.1 is clr.l %d0 2420 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2421 1.1 is 2422 1.1 is mov.b %d1,STAG(%a6) 2423 1.1 is tst.b %d1 2424 1.1 is bne.b _L10_2d 2425 1.1 is bsr.l setox # operand is a NORM 2426 1.1 is bra.b _L10_6d 2427 1.1 is _L10_2d: 2428 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2429 1.1 is bne.b _L10_3d # no 2430 1.1 is bsr.l ld_pone # yes 2431 1.1 is bra.b _L10_6d 2432 1.1 is _L10_3d: 2433 1.1 is cmpi.b %d1,&INF # is operand an INF? 2434 1.1 is bne.b _L10_4d # no 2435 1.1 is bsr.l szr_inf # yes 2436 1.1 is bra.b _L10_6d 2437 1.1 is _L10_4d: 2438 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2439 1.1 is bne.b _L10_5d # no 2440 1.1 is bsr.l src_qnan # yes 2441 1.1 is bra.b _L10_6d 2442 1.1 is _L10_5d: 2443 1.1 is bsr.l setoxd # operand is a DENORM 2444 1.1 is _L10_6d: 2445 1.1 is 2446 1.1 is # 2447 1.1 is # Result is now in FP0 2448 1.1 is # 2449 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2450 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2451 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2452 1.1 is unlk %a6 2453 1.1 is rts 2454 1.1 is 2455 1.1 is global _fetoxx_ 2456 1.1 is _fetoxx_: 2457 1.1 is link %a6,&-LOCAL_SIZE 2458 1.1 is 2459 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2460 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2461 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2462 1.1 is 2463 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2464 1.1 is 2465 1.1 is # 2466 1.1 is # copy, convert, and tag input argument 2467 1.1 is # 2468 1.1 is lea FP_SRC(%a6),%a0 2469 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 2470 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 2471 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 2472 1.1 is bsr.l tag # fetch operand type 2473 1.1 is mov.b %d0,STAG(%a6) 2474 1.1 is mov.b %d0,%d1 2475 1.1 is 2476 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2477 1.1 is 2478 1.1 is clr.l %d0 2479 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2480 1.1 is 2481 1.1 is tst.b %d1 2482 1.1 is bne.b _L10_2x 2483 1.1 is bsr.l setox # operand is a NORM 2484 1.1 is bra.b _L10_6x 2485 1.1 is _L10_2x: 2486 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2487 1.1 is bne.b _L10_3x # no 2488 1.1 is bsr.l ld_pone # yes 2489 1.1 is bra.b _L10_6x 2490 1.1 is _L10_3x: 2491 1.1 is cmpi.b %d1,&INF # is operand an INF? 2492 1.1 is bne.b _L10_4x # no 2493 1.1 is bsr.l szr_inf # yes 2494 1.1 is bra.b _L10_6x 2495 1.1 is _L10_4x: 2496 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2497 1.1 is bne.b _L10_5x # no 2498 1.1 is bsr.l src_qnan # yes 2499 1.1 is bra.b _L10_6x 2500 1.1 is _L10_5x: 2501 1.1 is bsr.l setoxd # operand is a DENORM 2502 1.1 is _L10_6x: 2503 1.1 is 2504 1.1 is # 2505 1.1 is # Result is now in FP0 2506 1.1 is # 2507 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2508 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2509 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2510 1.1 is unlk %a6 2511 1.1 is rts 2512 1.1 is 2513 1.1 is 2514 1.1 is ######################################################################### 2515 1.1 is # MONADIC TEMPLATE # 2516 1.1 is ######################################################################### 2517 1.1 is global _ftwotoxs_ 2518 1.1 is _ftwotoxs_: 2519 1.1 is link %a6,&-LOCAL_SIZE 2520 1.1 is 2521 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2522 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2523 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2524 1.1 is 2525 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2526 1.1 is 2527 1.1 is # 2528 1.1 is # copy, convert, and tag input argument 2529 1.1 is # 2530 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 2531 1.1 is fmov.x %fp0,FP_SRC(%a6) 2532 1.1 is lea FP_SRC(%a6),%a0 2533 1.1 is bsr.l tag # fetch operand type 2534 1.1 is mov.b %d0,STAG(%a6) 2535 1.1 is mov.b %d0,%d1 2536 1.1 is 2537 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2538 1.1 is 2539 1.1 is clr.l %d0 2540 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2541 1.1 is 2542 1.1 is tst.b %d1 2543 1.1 is bne.b _L11_2s 2544 1.1 is bsr.l stwotox # operand is a NORM 2545 1.1 is bra.b _L11_6s 2546 1.1 is _L11_2s: 2547 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2548 1.1 is bne.b _L11_3s # no 2549 1.1 is bsr.l ld_pone # yes 2550 1.1 is bra.b _L11_6s 2551 1.1 is _L11_3s: 2552 1.1 is cmpi.b %d1,&INF # is operand an INF? 2553 1.1 is bne.b _L11_4s # no 2554 1.1 is bsr.l szr_inf # yes 2555 1.1 is bra.b _L11_6s 2556 1.1 is _L11_4s: 2557 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2558 1.1 is bne.b _L11_5s # no 2559 1.1 is bsr.l src_qnan # yes 2560 1.1 is bra.b _L11_6s 2561 1.1 is _L11_5s: 2562 1.1 is bsr.l stwotoxd # operand is a DENORM 2563 1.1 is _L11_6s: 2564 1.1 is 2565 1.1 is # 2566 1.1 is # Result is now in FP0 2567 1.1 is # 2568 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2569 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2570 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2571 1.1 is unlk %a6 2572 1.1 is rts 2573 1.1 is 2574 1.1 is global _ftwotoxd_ 2575 1.1 is _ftwotoxd_: 2576 1.1 is link %a6,&-LOCAL_SIZE 2577 1.1 is 2578 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2579 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2580 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2581 1.1 is 2582 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2583 1.1 is 2584 1.1 is # 2585 1.1 is # copy, convert, and tag input argument 2586 1.1 is # 2587 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 2588 1.1 is fmov.x %fp0,FP_SRC(%a6) 2589 1.1 is lea FP_SRC(%a6),%a0 2590 1.1 is bsr.l tag # fetch operand type 2591 1.1 is mov.b %d0,STAG(%a6) 2592 1.1 is mov.b %d0,%d1 2593 1.1 is 2594 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2595 1.1 is 2596 1.1 is clr.l %d0 2597 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2598 1.1 is 2599 1.1 is mov.b %d1,STAG(%a6) 2600 1.1 is tst.b %d1 2601 1.1 is bne.b _L11_2d 2602 1.1 is bsr.l stwotox # operand is a NORM 2603 1.1 is bra.b _L11_6d 2604 1.1 is _L11_2d: 2605 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2606 1.1 is bne.b _L11_3d # no 2607 1.1 is bsr.l ld_pone # yes 2608 1.1 is bra.b _L11_6d 2609 1.1 is _L11_3d: 2610 1.1 is cmpi.b %d1,&INF # is operand an INF? 2611 1.1 is bne.b _L11_4d # no 2612 1.1 is bsr.l szr_inf # yes 2613 1.1 is bra.b _L11_6d 2614 1.1 is _L11_4d: 2615 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2616 1.1 is bne.b _L11_5d # no 2617 1.1 is bsr.l src_qnan # yes 2618 1.1 is bra.b _L11_6d 2619 1.1 is _L11_5d: 2620 1.1 is bsr.l stwotoxd # operand is a DENORM 2621 1.1 is _L11_6d: 2622 1.1 is 2623 1.1 is # 2624 1.1 is # Result is now in FP0 2625 1.1 is # 2626 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2627 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2628 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2629 1.1 is unlk %a6 2630 1.1 is rts 2631 1.1 is 2632 1.1 is global _ftwotoxx_ 2633 1.1 is _ftwotoxx_: 2634 1.1 is link %a6,&-LOCAL_SIZE 2635 1.1 is 2636 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2637 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2638 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2639 1.1 is 2640 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2641 1.1 is 2642 1.1 is # 2643 1.1 is # copy, convert, and tag input argument 2644 1.1 is # 2645 1.1 is lea FP_SRC(%a6),%a0 2646 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 2647 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 2648 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 2649 1.1 is bsr.l tag # fetch operand type 2650 1.1 is mov.b %d0,STAG(%a6) 2651 1.1 is mov.b %d0,%d1 2652 1.1 is 2653 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2654 1.1 is 2655 1.1 is clr.l %d0 2656 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2657 1.1 is 2658 1.1 is tst.b %d1 2659 1.1 is bne.b _L11_2x 2660 1.1 is bsr.l stwotox # operand is a NORM 2661 1.1 is bra.b _L11_6x 2662 1.1 is _L11_2x: 2663 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2664 1.1 is bne.b _L11_3x # no 2665 1.1 is bsr.l ld_pone # yes 2666 1.1 is bra.b _L11_6x 2667 1.1 is _L11_3x: 2668 1.1 is cmpi.b %d1,&INF # is operand an INF? 2669 1.1 is bne.b _L11_4x # no 2670 1.1 is bsr.l szr_inf # yes 2671 1.1 is bra.b _L11_6x 2672 1.1 is _L11_4x: 2673 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2674 1.1 is bne.b _L11_5x # no 2675 1.1 is bsr.l src_qnan # yes 2676 1.1 is bra.b _L11_6x 2677 1.1 is _L11_5x: 2678 1.1 is bsr.l stwotoxd # operand is a DENORM 2679 1.1 is _L11_6x: 2680 1.1 is 2681 1.1 is # 2682 1.1 is # Result is now in FP0 2683 1.1 is # 2684 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2685 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2686 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2687 1.1 is unlk %a6 2688 1.1 is rts 2689 1.1 is 2690 1.1 is 2691 1.1 is ######################################################################### 2692 1.1 is # MONADIC TEMPLATE # 2693 1.1 is ######################################################################### 2694 1.1 is global _ftentoxs_ 2695 1.1 is _ftentoxs_: 2696 1.1 is link %a6,&-LOCAL_SIZE 2697 1.1 is 2698 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2699 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2700 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2701 1.1 is 2702 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2703 1.1 is 2704 1.1 is # 2705 1.1 is # copy, convert, and tag input argument 2706 1.1 is # 2707 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 2708 1.1 is fmov.x %fp0,FP_SRC(%a6) 2709 1.1 is lea FP_SRC(%a6),%a0 2710 1.1 is bsr.l tag # fetch operand type 2711 1.1 is mov.b %d0,STAG(%a6) 2712 1.1 is mov.b %d0,%d1 2713 1.1 is 2714 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2715 1.1 is 2716 1.1 is clr.l %d0 2717 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2718 1.1 is 2719 1.1 is tst.b %d1 2720 1.1 is bne.b _L12_2s 2721 1.1 is bsr.l stentox # operand is a NORM 2722 1.1 is bra.b _L12_6s 2723 1.1 is _L12_2s: 2724 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2725 1.1 is bne.b _L12_3s # no 2726 1.1 is bsr.l ld_pone # yes 2727 1.1 is bra.b _L12_6s 2728 1.1 is _L12_3s: 2729 1.1 is cmpi.b %d1,&INF # is operand an INF? 2730 1.1 is bne.b _L12_4s # no 2731 1.1 is bsr.l szr_inf # yes 2732 1.1 is bra.b _L12_6s 2733 1.1 is _L12_4s: 2734 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2735 1.1 is bne.b _L12_5s # no 2736 1.1 is bsr.l src_qnan # yes 2737 1.1 is bra.b _L12_6s 2738 1.1 is _L12_5s: 2739 1.1 is bsr.l stentoxd # operand is a DENORM 2740 1.1 is _L12_6s: 2741 1.1 is 2742 1.1 is # 2743 1.1 is # Result is now in FP0 2744 1.1 is # 2745 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2746 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2747 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2748 1.1 is unlk %a6 2749 1.1 is rts 2750 1.1 is 2751 1.1 is global _ftentoxd_ 2752 1.1 is _ftentoxd_: 2753 1.1 is link %a6,&-LOCAL_SIZE 2754 1.1 is 2755 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2756 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2757 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2758 1.1 is 2759 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2760 1.1 is 2761 1.1 is # 2762 1.1 is # copy, convert, and tag input argument 2763 1.1 is # 2764 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 2765 1.1 is fmov.x %fp0,FP_SRC(%a6) 2766 1.1 is lea FP_SRC(%a6),%a0 2767 1.1 is bsr.l tag # fetch operand type 2768 1.1 is mov.b %d0,STAG(%a6) 2769 1.1 is mov.b %d0,%d1 2770 1.1 is 2771 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2772 1.1 is 2773 1.1 is clr.l %d0 2774 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2775 1.1 is 2776 1.1 is mov.b %d1,STAG(%a6) 2777 1.1 is tst.b %d1 2778 1.1 is bne.b _L12_2d 2779 1.1 is bsr.l stentox # operand is a NORM 2780 1.1 is bra.b _L12_6d 2781 1.1 is _L12_2d: 2782 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2783 1.1 is bne.b _L12_3d # no 2784 1.1 is bsr.l ld_pone # yes 2785 1.1 is bra.b _L12_6d 2786 1.1 is _L12_3d: 2787 1.1 is cmpi.b %d1,&INF # is operand an INF? 2788 1.1 is bne.b _L12_4d # no 2789 1.1 is bsr.l szr_inf # yes 2790 1.1 is bra.b _L12_6d 2791 1.1 is _L12_4d: 2792 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2793 1.1 is bne.b _L12_5d # no 2794 1.1 is bsr.l src_qnan # yes 2795 1.1 is bra.b _L12_6d 2796 1.1 is _L12_5d: 2797 1.1 is bsr.l stentoxd # operand is a DENORM 2798 1.1 is _L12_6d: 2799 1.1 is 2800 1.1 is # 2801 1.1 is # Result is now in FP0 2802 1.1 is # 2803 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2804 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2805 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2806 1.1 is unlk %a6 2807 1.1 is rts 2808 1.1 is 2809 1.1 is global _ftentoxx_ 2810 1.1 is _ftentoxx_: 2811 1.1 is link %a6,&-LOCAL_SIZE 2812 1.1 is 2813 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2814 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2815 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2816 1.1 is 2817 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2818 1.1 is 2819 1.1 is # 2820 1.1 is # copy, convert, and tag input argument 2821 1.1 is # 2822 1.1 is lea FP_SRC(%a6),%a0 2823 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 2824 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 2825 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 2826 1.1 is bsr.l tag # fetch operand type 2827 1.1 is mov.b %d0,STAG(%a6) 2828 1.1 is mov.b %d0,%d1 2829 1.1 is 2830 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2831 1.1 is 2832 1.1 is clr.l %d0 2833 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2834 1.1 is 2835 1.1 is tst.b %d1 2836 1.1 is bne.b _L12_2x 2837 1.1 is bsr.l stentox # operand is a NORM 2838 1.1 is bra.b _L12_6x 2839 1.1 is _L12_2x: 2840 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2841 1.1 is bne.b _L12_3x # no 2842 1.1 is bsr.l ld_pone # yes 2843 1.1 is bra.b _L12_6x 2844 1.1 is _L12_3x: 2845 1.1 is cmpi.b %d1,&INF # is operand an INF? 2846 1.1 is bne.b _L12_4x # no 2847 1.1 is bsr.l szr_inf # yes 2848 1.1 is bra.b _L12_6x 2849 1.1 is _L12_4x: 2850 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2851 1.1 is bne.b _L12_5x # no 2852 1.1 is bsr.l src_qnan # yes 2853 1.1 is bra.b _L12_6x 2854 1.1 is _L12_5x: 2855 1.1 is bsr.l stentoxd # operand is a DENORM 2856 1.1 is _L12_6x: 2857 1.1 is 2858 1.1 is # 2859 1.1 is # Result is now in FP0 2860 1.1 is # 2861 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2862 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2863 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2864 1.1 is unlk %a6 2865 1.1 is rts 2866 1.1 is 2867 1.1 is 2868 1.1 is ######################################################################### 2869 1.1 is # MONADIC TEMPLATE # 2870 1.1 is ######################################################################### 2871 1.1 is global _flogns_ 2872 1.1 is _flogns_: 2873 1.1 is link %a6,&-LOCAL_SIZE 2874 1.1 is 2875 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2876 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2877 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2878 1.1 is 2879 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2880 1.1 is 2881 1.1 is # 2882 1.1 is # copy, convert, and tag input argument 2883 1.1 is # 2884 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 2885 1.1 is fmov.x %fp0,FP_SRC(%a6) 2886 1.1 is lea FP_SRC(%a6),%a0 2887 1.1 is bsr.l tag # fetch operand type 2888 1.1 is mov.b %d0,STAG(%a6) 2889 1.1 is mov.b %d0,%d1 2890 1.1 is 2891 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2892 1.1 is 2893 1.1 is clr.l %d0 2894 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2895 1.1 is 2896 1.1 is tst.b %d1 2897 1.1 is bne.b _L13_2s 2898 1.1 is bsr.l slogn # operand is a NORM 2899 1.1 is bra.b _L13_6s 2900 1.1 is _L13_2s: 2901 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2902 1.1 is bne.b _L13_3s # no 2903 1.1 is bsr.l t_dz2 # yes 2904 1.1 is bra.b _L13_6s 2905 1.1 is _L13_3s: 2906 1.1 is cmpi.b %d1,&INF # is operand an INF? 2907 1.1 is bne.b _L13_4s # no 2908 1.1 is bsr.l sopr_inf # yes 2909 1.1 is bra.b _L13_6s 2910 1.1 is _L13_4s: 2911 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2912 1.1 is bne.b _L13_5s # no 2913 1.1 is bsr.l src_qnan # yes 2914 1.1 is bra.b _L13_6s 2915 1.1 is _L13_5s: 2916 1.1 is bsr.l slognd # operand is a DENORM 2917 1.1 is _L13_6s: 2918 1.1 is 2919 1.1 is # 2920 1.1 is # Result is now in FP0 2921 1.1 is # 2922 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2923 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2924 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2925 1.1 is unlk %a6 2926 1.1 is rts 2927 1.1 is 2928 1.1 is global _flognd_ 2929 1.1 is _flognd_: 2930 1.1 is link %a6,&-LOCAL_SIZE 2931 1.1 is 2932 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2933 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2934 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2935 1.1 is 2936 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2937 1.1 is 2938 1.1 is # 2939 1.1 is # copy, convert, and tag input argument 2940 1.1 is # 2941 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 2942 1.1 is fmov.x %fp0,FP_SRC(%a6) 2943 1.1 is lea FP_SRC(%a6),%a0 2944 1.1 is bsr.l tag # fetch operand type 2945 1.1 is mov.b %d0,STAG(%a6) 2946 1.1 is mov.b %d0,%d1 2947 1.1 is 2948 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 2949 1.1 is 2950 1.1 is clr.l %d0 2951 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 2952 1.1 is 2953 1.1 is mov.b %d1,STAG(%a6) 2954 1.1 is tst.b %d1 2955 1.1 is bne.b _L13_2d 2956 1.1 is bsr.l slogn # operand is a NORM 2957 1.1 is bra.b _L13_6d 2958 1.1 is _L13_2d: 2959 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 2960 1.1 is bne.b _L13_3d # no 2961 1.1 is bsr.l t_dz2 # yes 2962 1.1 is bra.b _L13_6d 2963 1.1 is _L13_3d: 2964 1.1 is cmpi.b %d1,&INF # is operand an INF? 2965 1.1 is bne.b _L13_4d # no 2966 1.1 is bsr.l sopr_inf # yes 2967 1.1 is bra.b _L13_6d 2968 1.1 is _L13_4d: 2969 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 2970 1.1 is bne.b _L13_5d # no 2971 1.1 is bsr.l src_qnan # yes 2972 1.1 is bra.b _L13_6d 2973 1.1 is _L13_5d: 2974 1.1 is bsr.l slognd # operand is a DENORM 2975 1.1 is _L13_6d: 2976 1.1 is 2977 1.1 is # 2978 1.1 is # Result is now in FP0 2979 1.1 is # 2980 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2981 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 2982 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 2983 1.1 is unlk %a6 2984 1.1 is rts 2985 1.1 is 2986 1.1 is global _flognx_ 2987 1.1 is _flognx_: 2988 1.1 is link %a6,&-LOCAL_SIZE 2989 1.1 is 2990 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2991 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 2992 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 2993 1.1 is 2994 1.1 is fmov.l &0x0,%fpcr # zero FPCR 2995 1.1 is 2996 1.1 is # 2997 1.1 is # copy, convert, and tag input argument 2998 1.1 is # 2999 1.1 is lea FP_SRC(%a6),%a0 3000 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 3001 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 3002 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 3003 1.1 is bsr.l tag # fetch operand type 3004 1.1 is mov.b %d0,STAG(%a6) 3005 1.1 is mov.b %d0,%d1 3006 1.1 is 3007 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3008 1.1 is 3009 1.1 is clr.l %d0 3010 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3011 1.1 is 3012 1.1 is tst.b %d1 3013 1.1 is bne.b _L13_2x 3014 1.1 is bsr.l slogn # operand is a NORM 3015 1.1 is bra.b _L13_6x 3016 1.1 is _L13_2x: 3017 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3018 1.1 is bne.b _L13_3x # no 3019 1.1 is bsr.l t_dz2 # yes 3020 1.1 is bra.b _L13_6x 3021 1.1 is _L13_3x: 3022 1.1 is cmpi.b %d1,&INF # is operand an INF? 3023 1.1 is bne.b _L13_4x # no 3024 1.1 is bsr.l sopr_inf # yes 3025 1.1 is bra.b _L13_6x 3026 1.1 is _L13_4x: 3027 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3028 1.1 is bne.b _L13_5x # no 3029 1.1 is bsr.l src_qnan # yes 3030 1.1 is bra.b _L13_6x 3031 1.1 is _L13_5x: 3032 1.1 is bsr.l slognd # operand is a DENORM 3033 1.1 is _L13_6x: 3034 1.1 is 3035 1.1 is # 3036 1.1 is # Result is now in FP0 3037 1.1 is # 3038 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3039 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3040 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3041 1.1 is unlk %a6 3042 1.1 is rts 3043 1.1 is 3044 1.1 is 3045 1.1 is ######################################################################### 3046 1.1 is # MONADIC TEMPLATE # 3047 1.1 is ######################################################################### 3048 1.1 is global _flog10s_ 3049 1.1 is _flog10s_: 3050 1.1 is link %a6,&-LOCAL_SIZE 3051 1.1 is 3052 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3053 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3054 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3055 1.1 is 3056 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3057 1.1 is 3058 1.1 is # 3059 1.1 is # copy, convert, and tag input argument 3060 1.1 is # 3061 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 3062 1.1 is fmov.x %fp0,FP_SRC(%a6) 3063 1.1 is lea FP_SRC(%a6),%a0 3064 1.1 is bsr.l tag # fetch operand type 3065 1.1 is mov.b %d0,STAG(%a6) 3066 1.1 is mov.b %d0,%d1 3067 1.1 is 3068 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3069 1.1 is 3070 1.1 is clr.l %d0 3071 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3072 1.1 is 3073 1.1 is tst.b %d1 3074 1.1 is bne.b _L14_2s 3075 1.1 is bsr.l slog10 # operand is a NORM 3076 1.1 is bra.b _L14_6s 3077 1.1 is _L14_2s: 3078 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3079 1.1 is bne.b _L14_3s # no 3080 1.1 is bsr.l t_dz2 # yes 3081 1.1 is bra.b _L14_6s 3082 1.1 is _L14_3s: 3083 1.1 is cmpi.b %d1,&INF # is operand an INF? 3084 1.1 is bne.b _L14_4s # no 3085 1.1 is bsr.l sopr_inf # yes 3086 1.1 is bra.b _L14_6s 3087 1.1 is _L14_4s: 3088 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3089 1.1 is bne.b _L14_5s # no 3090 1.1 is bsr.l src_qnan # yes 3091 1.1 is bra.b _L14_6s 3092 1.1 is _L14_5s: 3093 1.1 is bsr.l slog10d # operand is a DENORM 3094 1.1 is _L14_6s: 3095 1.1 is 3096 1.1 is # 3097 1.1 is # Result is now in FP0 3098 1.1 is # 3099 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3100 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3101 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3102 1.1 is unlk %a6 3103 1.1 is rts 3104 1.1 is 3105 1.1 is global _flog10d_ 3106 1.1 is _flog10d_: 3107 1.1 is link %a6,&-LOCAL_SIZE 3108 1.1 is 3109 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3110 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3111 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3112 1.1 is 3113 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3114 1.1 is 3115 1.1 is # 3116 1.1 is # copy, convert, and tag input argument 3117 1.1 is # 3118 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 3119 1.1 is fmov.x %fp0,FP_SRC(%a6) 3120 1.1 is lea FP_SRC(%a6),%a0 3121 1.1 is bsr.l tag # fetch operand type 3122 1.1 is mov.b %d0,STAG(%a6) 3123 1.1 is mov.b %d0,%d1 3124 1.1 is 3125 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3126 1.1 is 3127 1.1 is clr.l %d0 3128 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3129 1.1 is 3130 1.1 is mov.b %d1,STAG(%a6) 3131 1.1 is tst.b %d1 3132 1.1 is bne.b _L14_2d 3133 1.1 is bsr.l slog10 # operand is a NORM 3134 1.1 is bra.b _L14_6d 3135 1.1 is _L14_2d: 3136 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3137 1.1 is bne.b _L14_3d # no 3138 1.1 is bsr.l t_dz2 # yes 3139 1.1 is bra.b _L14_6d 3140 1.1 is _L14_3d: 3141 1.1 is cmpi.b %d1,&INF # is operand an INF? 3142 1.1 is bne.b _L14_4d # no 3143 1.1 is bsr.l sopr_inf # yes 3144 1.1 is bra.b _L14_6d 3145 1.1 is _L14_4d: 3146 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3147 1.1 is bne.b _L14_5d # no 3148 1.1 is bsr.l src_qnan # yes 3149 1.1 is bra.b _L14_6d 3150 1.1 is _L14_5d: 3151 1.1 is bsr.l slog10d # operand is a DENORM 3152 1.1 is _L14_6d: 3153 1.1 is 3154 1.1 is # 3155 1.1 is # Result is now in FP0 3156 1.1 is # 3157 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3158 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3159 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3160 1.1 is unlk %a6 3161 1.1 is rts 3162 1.1 is 3163 1.1 is global _flog10x_ 3164 1.1 is _flog10x_: 3165 1.1 is link %a6,&-LOCAL_SIZE 3166 1.1 is 3167 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3168 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3169 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3170 1.1 is 3171 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3172 1.1 is 3173 1.1 is # 3174 1.1 is # copy, convert, and tag input argument 3175 1.1 is # 3176 1.1 is lea FP_SRC(%a6),%a0 3177 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 3178 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 3179 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 3180 1.1 is bsr.l tag # fetch operand type 3181 1.1 is mov.b %d0,STAG(%a6) 3182 1.1 is mov.b %d0,%d1 3183 1.1 is 3184 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3185 1.1 is 3186 1.1 is clr.l %d0 3187 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3188 1.1 is 3189 1.1 is tst.b %d1 3190 1.1 is bne.b _L14_2x 3191 1.1 is bsr.l slog10 # operand is a NORM 3192 1.1 is bra.b _L14_6x 3193 1.1 is _L14_2x: 3194 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3195 1.1 is bne.b _L14_3x # no 3196 1.1 is bsr.l t_dz2 # yes 3197 1.1 is bra.b _L14_6x 3198 1.1 is _L14_3x: 3199 1.1 is cmpi.b %d1,&INF # is operand an INF? 3200 1.1 is bne.b _L14_4x # no 3201 1.1 is bsr.l sopr_inf # yes 3202 1.1 is bra.b _L14_6x 3203 1.1 is _L14_4x: 3204 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3205 1.1 is bne.b _L14_5x # no 3206 1.1 is bsr.l src_qnan # yes 3207 1.1 is bra.b _L14_6x 3208 1.1 is _L14_5x: 3209 1.1 is bsr.l slog10d # operand is a DENORM 3210 1.1 is _L14_6x: 3211 1.1 is 3212 1.1 is # 3213 1.1 is # Result is now in FP0 3214 1.1 is # 3215 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3216 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3217 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3218 1.1 is unlk %a6 3219 1.1 is rts 3220 1.1 is 3221 1.1 is 3222 1.1 is ######################################################################### 3223 1.1 is # MONADIC TEMPLATE # 3224 1.1 is ######################################################################### 3225 1.1 is global _flog2s_ 3226 1.1 is _flog2s_: 3227 1.1 is link %a6,&-LOCAL_SIZE 3228 1.1 is 3229 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3230 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3231 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3232 1.1 is 3233 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3234 1.1 is 3235 1.1 is # 3236 1.1 is # copy, convert, and tag input argument 3237 1.1 is # 3238 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 3239 1.1 is fmov.x %fp0,FP_SRC(%a6) 3240 1.1 is lea FP_SRC(%a6),%a0 3241 1.1 is bsr.l tag # fetch operand type 3242 1.1 is mov.b %d0,STAG(%a6) 3243 1.1 is mov.b %d0,%d1 3244 1.1 is 3245 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3246 1.1 is 3247 1.1 is clr.l %d0 3248 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3249 1.1 is 3250 1.1 is tst.b %d1 3251 1.1 is bne.b _L15_2s 3252 1.1 is bsr.l slog2 # operand is a NORM 3253 1.1 is bra.b _L15_6s 3254 1.1 is _L15_2s: 3255 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3256 1.1 is bne.b _L15_3s # no 3257 1.1 is bsr.l t_dz2 # yes 3258 1.1 is bra.b _L15_6s 3259 1.1 is _L15_3s: 3260 1.1 is cmpi.b %d1,&INF # is operand an INF? 3261 1.1 is bne.b _L15_4s # no 3262 1.1 is bsr.l sopr_inf # yes 3263 1.1 is bra.b _L15_6s 3264 1.1 is _L15_4s: 3265 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3266 1.1 is bne.b _L15_5s # no 3267 1.1 is bsr.l src_qnan # yes 3268 1.1 is bra.b _L15_6s 3269 1.1 is _L15_5s: 3270 1.1 is bsr.l slog2d # operand is a DENORM 3271 1.1 is _L15_6s: 3272 1.1 is 3273 1.1 is # 3274 1.1 is # Result is now in FP0 3275 1.1 is # 3276 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3277 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3278 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3279 1.1 is unlk %a6 3280 1.1 is rts 3281 1.1 is 3282 1.1 is global _flog2d_ 3283 1.1 is _flog2d_: 3284 1.1 is link %a6,&-LOCAL_SIZE 3285 1.1 is 3286 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3287 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3288 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3289 1.1 is 3290 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3291 1.1 is 3292 1.1 is # 3293 1.1 is # copy, convert, and tag input argument 3294 1.1 is # 3295 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 3296 1.1 is fmov.x %fp0,FP_SRC(%a6) 3297 1.1 is lea FP_SRC(%a6),%a0 3298 1.1 is bsr.l tag # fetch operand type 3299 1.1 is mov.b %d0,STAG(%a6) 3300 1.1 is mov.b %d0,%d1 3301 1.1 is 3302 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3303 1.1 is 3304 1.1 is clr.l %d0 3305 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3306 1.1 is 3307 1.1 is mov.b %d1,STAG(%a6) 3308 1.1 is tst.b %d1 3309 1.1 is bne.b _L15_2d 3310 1.1 is bsr.l slog2 # operand is a NORM 3311 1.1 is bra.b _L15_6d 3312 1.1 is _L15_2d: 3313 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3314 1.1 is bne.b _L15_3d # no 3315 1.1 is bsr.l t_dz2 # yes 3316 1.1 is bra.b _L15_6d 3317 1.1 is _L15_3d: 3318 1.1 is cmpi.b %d1,&INF # is operand an INF? 3319 1.1 is bne.b _L15_4d # no 3320 1.1 is bsr.l sopr_inf # yes 3321 1.1 is bra.b _L15_6d 3322 1.1 is _L15_4d: 3323 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3324 1.1 is bne.b _L15_5d # no 3325 1.1 is bsr.l src_qnan # yes 3326 1.1 is bra.b _L15_6d 3327 1.1 is _L15_5d: 3328 1.1 is bsr.l slog2d # operand is a DENORM 3329 1.1 is _L15_6d: 3330 1.1 is 3331 1.1 is # 3332 1.1 is # Result is now in FP0 3333 1.1 is # 3334 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3335 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3336 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3337 1.1 is unlk %a6 3338 1.1 is rts 3339 1.1 is 3340 1.1 is global _flog2x_ 3341 1.1 is _flog2x_: 3342 1.1 is link %a6,&-LOCAL_SIZE 3343 1.1 is 3344 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3345 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3346 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3347 1.1 is 3348 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3349 1.1 is 3350 1.1 is # 3351 1.1 is # copy, convert, and tag input argument 3352 1.1 is # 3353 1.1 is lea FP_SRC(%a6),%a0 3354 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 3355 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 3356 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 3357 1.1 is bsr.l tag # fetch operand type 3358 1.1 is mov.b %d0,STAG(%a6) 3359 1.1 is mov.b %d0,%d1 3360 1.1 is 3361 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3362 1.1 is 3363 1.1 is clr.l %d0 3364 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3365 1.1 is 3366 1.1 is tst.b %d1 3367 1.1 is bne.b _L15_2x 3368 1.1 is bsr.l slog2 # operand is a NORM 3369 1.1 is bra.b _L15_6x 3370 1.1 is _L15_2x: 3371 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3372 1.1 is bne.b _L15_3x # no 3373 1.1 is bsr.l t_dz2 # yes 3374 1.1 is bra.b _L15_6x 3375 1.1 is _L15_3x: 3376 1.1 is cmpi.b %d1,&INF # is operand an INF? 3377 1.1 is bne.b _L15_4x # no 3378 1.1 is bsr.l sopr_inf # yes 3379 1.1 is bra.b _L15_6x 3380 1.1 is _L15_4x: 3381 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3382 1.1 is bne.b _L15_5x # no 3383 1.1 is bsr.l src_qnan # yes 3384 1.1 is bra.b _L15_6x 3385 1.1 is _L15_5x: 3386 1.1 is bsr.l slog2d # operand is a DENORM 3387 1.1 is _L15_6x: 3388 1.1 is 3389 1.1 is # 3390 1.1 is # Result is now in FP0 3391 1.1 is # 3392 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3393 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3394 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3395 1.1 is unlk %a6 3396 1.1 is rts 3397 1.1 is 3398 1.1 is 3399 1.1 is ######################################################################### 3400 1.1 is # MONADIC TEMPLATE # 3401 1.1 is ######################################################################### 3402 1.1 is global _fcoshs_ 3403 1.1 is _fcoshs_: 3404 1.1 is link %a6,&-LOCAL_SIZE 3405 1.1 is 3406 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3407 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3408 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3409 1.1 is 3410 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3411 1.1 is 3412 1.1 is # 3413 1.1 is # copy, convert, and tag input argument 3414 1.1 is # 3415 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 3416 1.1 is fmov.x %fp0,FP_SRC(%a6) 3417 1.1 is lea FP_SRC(%a6),%a0 3418 1.1 is bsr.l tag # fetch operand type 3419 1.1 is mov.b %d0,STAG(%a6) 3420 1.1 is mov.b %d0,%d1 3421 1.1 is 3422 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3423 1.1 is 3424 1.1 is clr.l %d0 3425 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3426 1.1 is 3427 1.1 is tst.b %d1 3428 1.1 is bne.b _L16_2s 3429 1.1 is bsr.l scosh # operand is a NORM 3430 1.1 is bra.b _L16_6s 3431 1.1 is _L16_2s: 3432 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3433 1.1 is bne.b _L16_3s # no 3434 1.1 is bsr.l ld_pone # yes 3435 1.1 is bra.b _L16_6s 3436 1.1 is _L16_3s: 3437 1.1 is cmpi.b %d1,&INF # is operand an INF? 3438 1.1 is bne.b _L16_4s # no 3439 1.1 is bsr.l ld_pinf # yes 3440 1.1 is bra.b _L16_6s 3441 1.1 is _L16_4s: 3442 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3443 1.1 is bne.b _L16_5s # no 3444 1.1 is bsr.l src_qnan # yes 3445 1.1 is bra.b _L16_6s 3446 1.1 is _L16_5s: 3447 1.1 is bsr.l scoshd # operand is a DENORM 3448 1.1 is _L16_6s: 3449 1.1 is 3450 1.1 is # 3451 1.1 is # Result is now in FP0 3452 1.1 is # 3453 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3454 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3455 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3456 1.1 is unlk %a6 3457 1.1 is rts 3458 1.1 is 3459 1.1 is global _fcoshd_ 3460 1.1 is _fcoshd_: 3461 1.1 is link %a6,&-LOCAL_SIZE 3462 1.1 is 3463 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3464 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3465 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3466 1.1 is 3467 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3468 1.1 is 3469 1.1 is # 3470 1.1 is # copy, convert, and tag input argument 3471 1.1 is # 3472 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 3473 1.1 is fmov.x %fp0,FP_SRC(%a6) 3474 1.1 is lea FP_SRC(%a6),%a0 3475 1.1 is bsr.l tag # fetch operand type 3476 1.1 is mov.b %d0,STAG(%a6) 3477 1.1 is mov.b %d0,%d1 3478 1.1 is 3479 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3480 1.1 is 3481 1.1 is clr.l %d0 3482 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3483 1.1 is 3484 1.1 is mov.b %d1,STAG(%a6) 3485 1.1 is tst.b %d1 3486 1.1 is bne.b _L16_2d 3487 1.1 is bsr.l scosh # operand is a NORM 3488 1.1 is bra.b _L16_6d 3489 1.1 is _L16_2d: 3490 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3491 1.1 is bne.b _L16_3d # no 3492 1.1 is bsr.l ld_pone # yes 3493 1.1 is bra.b _L16_6d 3494 1.1 is _L16_3d: 3495 1.1 is cmpi.b %d1,&INF # is operand an INF? 3496 1.1 is bne.b _L16_4d # no 3497 1.1 is bsr.l ld_pinf # yes 3498 1.1 is bra.b _L16_6d 3499 1.1 is _L16_4d: 3500 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3501 1.1 is bne.b _L16_5d # no 3502 1.1 is bsr.l src_qnan # yes 3503 1.1 is bra.b _L16_6d 3504 1.1 is _L16_5d: 3505 1.1 is bsr.l scoshd # operand is a DENORM 3506 1.1 is _L16_6d: 3507 1.1 is 3508 1.1 is # 3509 1.1 is # Result is now in FP0 3510 1.1 is # 3511 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3512 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3513 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3514 1.1 is unlk %a6 3515 1.1 is rts 3516 1.1 is 3517 1.1 is global _fcoshx_ 3518 1.1 is _fcoshx_: 3519 1.1 is link %a6,&-LOCAL_SIZE 3520 1.1 is 3521 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3522 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3523 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3524 1.1 is 3525 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3526 1.1 is 3527 1.1 is # 3528 1.1 is # copy, convert, and tag input argument 3529 1.1 is # 3530 1.1 is lea FP_SRC(%a6),%a0 3531 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 3532 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 3533 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 3534 1.1 is bsr.l tag # fetch operand type 3535 1.1 is mov.b %d0,STAG(%a6) 3536 1.1 is mov.b %d0,%d1 3537 1.1 is 3538 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3539 1.1 is 3540 1.1 is clr.l %d0 3541 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3542 1.1 is 3543 1.1 is tst.b %d1 3544 1.1 is bne.b _L16_2x 3545 1.1 is bsr.l scosh # operand is a NORM 3546 1.1 is bra.b _L16_6x 3547 1.1 is _L16_2x: 3548 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3549 1.1 is bne.b _L16_3x # no 3550 1.1 is bsr.l ld_pone # yes 3551 1.1 is bra.b _L16_6x 3552 1.1 is _L16_3x: 3553 1.1 is cmpi.b %d1,&INF # is operand an INF? 3554 1.1 is bne.b _L16_4x # no 3555 1.1 is bsr.l ld_pinf # yes 3556 1.1 is bra.b _L16_6x 3557 1.1 is _L16_4x: 3558 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3559 1.1 is bne.b _L16_5x # no 3560 1.1 is bsr.l src_qnan # yes 3561 1.1 is bra.b _L16_6x 3562 1.1 is _L16_5x: 3563 1.1 is bsr.l scoshd # operand is a DENORM 3564 1.1 is _L16_6x: 3565 1.1 is 3566 1.1 is # 3567 1.1 is # Result is now in FP0 3568 1.1 is # 3569 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3570 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3571 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3572 1.1 is unlk %a6 3573 1.1 is rts 3574 1.1 is 3575 1.1 is 3576 1.1 is ######################################################################### 3577 1.1 is # MONADIC TEMPLATE # 3578 1.1 is ######################################################################### 3579 1.1 is global _facoss_ 3580 1.1 is _facoss_: 3581 1.1 is link %a6,&-LOCAL_SIZE 3582 1.1 is 3583 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3584 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3585 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3586 1.1 is 3587 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3588 1.1 is 3589 1.1 is # 3590 1.1 is # copy, convert, and tag input argument 3591 1.1 is # 3592 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 3593 1.1 is fmov.x %fp0,FP_SRC(%a6) 3594 1.1 is lea FP_SRC(%a6),%a0 3595 1.1 is bsr.l tag # fetch operand type 3596 1.1 is mov.b %d0,STAG(%a6) 3597 1.1 is mov.b %d0,%d1 3598 1.1 is 3599 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3600 1.1 is 3601 1.1 is clr.l %d0 3602 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3603 1.1 is 3604 1.1 is tst.b %d1 3605 1.1 is bne.b _L17_2s 3606 1.1 is bsr.l sacos # operand is a NORM 3607 1.1 is bra.b _L17_6s 3608 1.1 is _L17_2s: 3609 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3610 1.1 is bne.b _L17_3s # no 3611 1.1 is bsr.l ld_ppi2 # yes 3612 1.1 is bra.b _L17_6s 3613 1.1 is _L17_3s: 3614 1.1 is cmpi.b %d1,&INF # is operand an INF? 3615 1.1 is bne.b _L17_4s # no 3616 1.1 is bsr.l t_operr # yes 3617 1.1 is bra.b _L17_6s 3618 1.1 is _L17_4s: 3619 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3620 1.1 is bne.b _L17_5s # no 3621 1.1 is bsr.l src_qnan # yes 3622 1.1 is bra.b _L17_6s 3623 1.1 is _L17_5s: 3624 1.1 is bsr.l sacosd # operand is a DENORM 3625 1.1 is _L17_6s: 3626 1.1 is 3627 1.1 is # 3628 1.1 is # Result is now in FP0 3629 1.1 is # 3630 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3631 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3632 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3633 1.1 is unlk %a6 3634 1.1 is rts 3635 1.1 is 3636 1.1 is global _facosd_ 3637 1.1 is _facosd_: 3638 1.1 is link %a6,&-LOCAL_SIZE 3639 1.1 is 3640 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3641 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3642 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3643 1.1 is 3644 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3645 1.1 is 3646 1.1 is # 3647 1.1 is # copy, convert, and tag input argument 3648 1.1 is # 3649 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 3650 1.1 is fmov.x %fp0,FP_SRC(%a6) 3651 1.1 is lea FP_SRC(%a6),%a0 3652 1.1 is bsr.l tag # fetch operand type 3653 1.1 is mov.b %d0,STAG(%a6) 3654 1.1 is mov.b %d0,%d1 3655 1.1 is 3656 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3657 1.1 is 3658 1.1 is clr.l %d0 3659 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3660 1.1 is 3661 1.1 is mov.b %d1,STAG(%a6) 3662 1.1 is tst.b %d1 3663 1.1 is bne.b _L17_2d 3664 1.1 is bsr.l sacos # operand is a NORM 3665 1.1 is bra.b _L17_6d 3666 1.1 is _L17_2d: 3667 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3668 1.1 is bne.b _L17_3d # no 3669 1.1 is bsr.l ld_ppi2 # yes 3670 1.1 is bra.b _L17_6d 3671 1.1 is _L17_3d: 3672 1.1 is cmpi.b %d1,&INF # is operand an INF? 3673 1.1 is bne.b _L17_4d # no 3674 1.1 is bsr.l t_operr # yes 3675 1.1 is bra.b _L17_6d 3676 1.1 is _L17_4d: 3677 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3678 1.1 is bne.b _L17_5d # no 3679 1.1 is bsr.l src_qnan # yes 3680 1.1 is bra.b _L17_6d 3681 1.1 is _L17_5d: 3682 1.1 is bsr.l sacosd # operand is a DENORM 3683 1.1 is _L17_6d: 3684 1.1 is 3685 1.1 is # 3686 1.1 is # Result is now in FP0 3687 1.1 is # 3688 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3689 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3690 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3691 1.1 is unlk %a6 3692 1.1 is rts 3693 1.1 is 3694 1.1 is global _facosx_ 3695 1.1 is _facosx_: 3696 1.1 is link %a6,&-LOCAL_SIZE 3697 1.1 is 3698 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3699 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3700 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3701 1.1 is 3702 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3703 1.1 is 3704 1.1 is # 3705 1.1 is # copy, convert, and tag input argument 3706 1.1 is # 3707 1.1 is lea FP_SRC(%a6),%a0 3708 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 3709 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 3710 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 3711 1.1 is bsr.l tag # fetch operand type 3712 1.1 is mov.b %d0,STAG(%a6) 3713 1.1 is mov.b %d0,%d1 3714 1.1 is 3715 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3716 1.1 is 3717 1.1 is clr.l %d0 3718 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3719 1.1 is 3720 1.1 is tst.b %d1 3721 1.1 is bne.b _L17_2x 3722 1.1 is bsr.l sacos # operand is a NORM 3723 1.1 is bra.b _L17_6x 3724 1.1 is _L17_2x: 3725 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3726 1.1 is bne.b _L17_3x # no 3727 1.1 is bsr.l ld_ppi2 # yes 3728 1.1 is bra.b _L17_6x 3729 1.1 is _L17_3x: 3730 1.1 is cmpi.b %d1,&INF # is operand an INF? 3731 1.1 is bne.b _L17_4x # no 3732 1.1 is bsr.l t_operr # yes 3733 1.1 is bra.b _L17_6x 3734 1.1 is _L17_4x: 3735 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3736 1.1 is bne.b _L17_5x # no 3737 1.1 is bsr.l src_qnan # yes 3738 1.1 is bra.b _L17_6x 3739 1.1 is _L17_5x: 3740 1.1 is bsr.l sacosd # operand is a DENORM 3741 1.1 is _L17_6x: 3742 1.1 is 3743 1.1 is # 3744 1.1 is # Result is now in FP0 3745 1.1 is # 3746 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3747 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3748 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3749 1.1 is unlk %a6 3750 1.1 is rts 3751 1.1 is 3752 1.1 is 3753 1.1 is ######################################################################### 3754 1.1 is # MONADIC TEMPLATE # 3755 1.1 is ######################################################################### 3756 1.1 is global _fgetexps_ 3757 1.1 is _fgetexps_: 3758 1.1 is link %a6,&-LOCAL_SIZE 3759 1.1 is 3760 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3761 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3762 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3763 1.1 is 3764 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3765 1.1 is 3766 1.1 is # 3767 1.1 is # copy, convert, and tag input argument 3768 1.1 is # 3769 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 3770 1.1 is fmov.x %fp0,FP_SRC(%a6) 3771 1.1 is lea FP_SRC(%a6),%a0 3772 1.1 is bsr.l tag # fetch operand type 3773 1.1 is mov.b %d0,STAG(%a6) 3774 1.1 is mov.b %d0,%d1 3775 1.1 is 3776 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3777 1.1 is 3778 1.1 is clr.l %d0 3779 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3780 1.1 is 3781 1.1 is tst.b %d1 3782 1.1 is bne.b _L18_2s 3783 1.1 is bsr.l sgetexp # operand is a NORM 3784 1.1 is bra.b _L18_6s 3785 1.1 is _L18_2s: 3786 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3787 1.1 is bne.b _L18_3s # no 3788 1.1 is bsr.l src_zero # yes 3789 1.1 is bra.b _L18_6s 3790 1.1 is _L18_3s: 3791 1.1 is cmpi.b %d1,&INF # is operand an INF? 3792 1.1 is bne.b _L18_4s # no 3793 1.1 is bsr.l t_operr # yes 3794 1.1 is bra.b _L18_6s 3795 1.1 is _L18_4s: 3796 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3797 1.1 is bne.b _L18_5s # no 3798 1.1 is bsr.l src_qnan # yes 3799 1.1 is bra.b _L18_6s 3800 1.1 is _L18_5s: 3801 1.1 is bsr.l sgetexpd # operand is a DENORM 3802 1.1 is _L18_6s: 3803 1.1 is 3804 1.1 is # 3805 1.1 is # Result is now in FP0 3806 1.1 is # 3807 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3808 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3809 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3810 1.1 is unlk %a6 3811 1.1 is rts 3812 1.1 is 3813 1.1 is global _fgetexpd_ 3814 1.1 is _fgetexpd_: 3815 1.1 is link %a6,&-LOCAL_SIZE 3816 1.1 is 3817 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3818 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3819 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3820 1.1 is 3821 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3822 1.1 is 3823 1.1 is # 3824 1.1 is # copy, convert, and tag input argument 3825 1.1 is # 3826 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 3827 1.1 is fmov.x %fp0,FP_SRC(%a6) 3828 1.1 is lea FP_SRC(%a6),%a0 3829 1.1 is bsr.l tag # fetch operand type 3830 1.1 is mov.b %d0,STAG(%a6) 3831 1.1 is mov.b %d0,%d1 3832 1.1 is 3833 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3834 1.1 is 3835 1.1 is clr.l %d0 3836 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3837 1.1 is 3838 1.1 is mov.b %d1,STAG(%a6) 3839 1.1 is tst.b %d1 3840 1.1 is bne.b _L18_2d 3841 1.1 is bsr.l sgetexp # operand is a NORM 3842 1.1 is bra.b _L18_6d 3843 1.1 is _L18_2d: 3844 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3845 1.1 is bne.b _L18_3d # no 3846 1.1 is bsr.l src_zero # yes 3847 1.1 is bra.b _L18_6d 3848 1.1 is _L18_3d: 3849 1.1 is cmpi.b %d1,&INF # is operand an INF? 3850 1.1 is bne.b _L18_4d # no 3851 1.1 is bsr.l t_operr # yes 3852 1.1 is bra.b _L18_6d 3853 1.1 is _L18_4d: 3854 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3855 1.1 is bne.b _L18_5d # no 3856 1.1 is bsr.l src_qnan # yes 3857 1.1 is bra.b _L18_6d 3858 1.1 is _L18_5d: 3859 1.1 is bsr.l sgetexpd # operand is a DENORM 3860 1.1 is _L18_6d: 3861 1.1 is 3862 1.1 is # 3863 1.1 is # Result is now in FP0 3864 1.1 is # 3865 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3866 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3867 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3868 1.1 is unlk %a6 3869 1.1 is rts 3870 1.1 is 3871 1.1 is global _fgetexpx_ 3872 1.1 is _fgetexpx_: 3873 1.1 is link %a6,&-LOCAL_SIZE 3874 1.1 is 3875 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3876 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3877 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3878 1.1 is 3879 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3880 1.1 is 3881 1.1 is # 3882 1.1 is # copy, convert, and tag input argument 3883 1.1 is # 3884 1.1 is lea FP_SRC(%a6),%a0 3885 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 3886 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 3887 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 3888 1.1 is bsr.l tag # fetch operand type 3889 1.1 is mov.b %d0,STAG(%a6) 3890 1.1 is mov.b %d0,%d1 3891 1.1 is 3892 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3893 1.1 is 3894 1.1 is clr.l %d0 3895 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3896 1.1 is 3897 1.1 is tst.b %d1 3898 1.1 is bne.b _L18_2x 3899 1.1 is bsr.l sgetexp # operand is a NORM 3900 1.1 is bra.b _L18_6x 3901 1.1 is _L18_2x: 3902 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3903 1.1 is bne.b _L18_3x # no 3904 1.1 is bsr.l src_zero # yes 3905 1.1 is bra.b _L18_6x 3906 1.1 is _L18_3x: 3907 1.1 is cmpi.b %d1,&INF # is operand an INF? 3908 1.1 is bne.b _L18_4x # no 3909 1.1 is bsr.l t_operr # yes 3910 1.1 is bra.b _L18_6x 3911 1.1 is _L18_4x: 3912 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3913 1.1 is bne.b _L18_5x # no 3914 1.1 is bsr.l src_qnan # yes 3915 1.1 is bra.b _L18_6x 3916 1.1 is _L18_5x: 3917 1.1 is bsr.l sgetexpd # operand is a DENORM 3918 1.1 is _L18_6x: 3919 1.1 is 3920 1.1 is # 3921 1.1 is # Result is now in FP0 3922 1.1 is # 3923 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3924 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3925 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3926 1.1 is unlk %a6 3927 1.1 is rts 3928 1.1 is 3929 1.1 is 3930 1.1 is ######################################################################### 3931 1.1 is # MONADIC TEMPLATE # 3932 1.1 is ######################################################################### 3933 1.1 is global _fgetmans_ 3934 1.1 is _fgetmans_: 3935 1.1 is link %a6,&-LOCAL_SIZE 3936 1.1 is 3937 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3938 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3939 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3940 1.1 is 3941 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3942 1.1 is 3943 1.1 is # 3944 1.1 is # copy, convert, and tag input argument 3945 1.1 is # 3946 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 3947 1.1 is fmov.x %fp0,FP_SRC(%a6) 3948 1.1 is lea FP_SRC(%a6),%a0 3949 1.1 is bsr.l tag # fetch operand type 3950 1.1 is mov.b %d0,STAG(%a6) 3951 1.1 is mov.b %d0,%d1 3952 1.1 is 3953 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 3954 1.1 is 3955 1.1 is clr.l %d0 3956 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 3957 1.1 is 3958 1.1 is tst.b %d1 3959 1.1 is bne.b _L19_2s 3960 1.1 is bsr.l sgetman # operand is a NORM 3961 1.1 is bra.b _L19_6s 3962 1.1 is _L19_2s: 3963 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 3964 1.1 is bne.b _L19_3s # no 3965 1.1 is bsr.l src_zero # yes 3966 1.1 is bra.b _L19_6s 3967 1.1 is _L19_3s: 3968 1.1 is cmpi.b %d1,&INF # is operand an INF? 3969 1.1 is bne.b _L19_4s # no 3970 1.1 is bsr.l t_operr # yes 3971 1.1 is bra.b _L19_6s 3972 1.1 is _L19_4s: 3973 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 3974 1.1 is bne.b _L19_5s # no 3975 1.1 is bsr.l src_qnan # yes 3976 1.1 is bra.b _L19_6s 3977 1.1 is _L19_5s: 3978 1.1 is bsr.l sgetmand # operand is a DENORM 3979 1.1 is _L19_6s: 3980 1.1 is 3981 1.1 is # 3982 1.1 is # Result is now in FP0 3983 1.1 is # 3984 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3985 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 3986 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 3987 1.1 is unlk %a6 3988 1.1 is rts 3989 1.1 is 3990 1.1 is global _fgetmand_ 3991 1.1 is _fgetmand_: 3992 1.1 is link %a6,&-LOCAL_SIZE 3993 1.1 is 3994 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3995 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 3996 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 3997 1.1 is 3998 1.1 is fmov.l &0x0,%fpcr # zero FPCR 3999 1.1 is 4000 1.1 is # 4001 1.1 is # copy, convert, and tag input argument 4002 1.1 is # 4003 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 4004 1.1 is fmov.x %fp0,FP_SRC(%a6) 4005 1.1 is lea FP_SRC(%a6),%a0 4006 1.1 is bsr.l tag # fetch operand type 4007 1.1 is mov.b %d0,STAG(%a6) 4008 1.1 is mov.b %d0,%d1 4009 1.1 is 4010 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4011 1.1 is 4012 1.1 is clr.l %d0 4013 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4014 1.1 is 4015 1.1 is mov.b %d1,STAG(%a6) 4016 1.1 is tst.b %d1 4017 1.1 is bne.b _L19_2d 4018 1.1 is bsr.l sgetman # operand is a NORM 4019 1.1 is bra.b _L19_6d 4020 1.1 is _L19_2d: 4021 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4022 1.1 is bne.b _L19_3d # no 4023 1.1 is bsr.l src_zero # yes 4024 1.1 is bra.b _L19_6d 4025 1.1 is _L19_3d: 4026 1.1 is cmpi.b %d1,&INF # is operand an INF? 4027 1.1 is bne.b _L19_4d # no 4028 1.1 is bsr.l t_operr # yes 4029 1.1 is bra.b _L19_6d 4030 1.1 is _L19_4d: 4031 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4032 1.1 is bne.b _L19_5d # no 4033 1.1 is bsr.l src_qnan # yes 4034 1.1 is bra.b _L19_6d 4035 1.1 is _L19_5d: 4036 1.1 is bsr.l sgetmand # operand is a DENORM 4037 1.1 is _L19_6d: 4038 1.1 is 4039 1.1 is # 4040 1.1 is # Result is now in FP0 4041 1.1 is # 4042 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4043 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4044 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4045 1.1 is unlk %a6 4046 1.1 is rts 4047 1.1 is 4048 1.1 is global _fgetmanx_ 4049 1.1 is _fgetmanx_: 4050 1.1 is link %a6,&-LOCAL_SIZE 4051 1.1 is 4052 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4053 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4054 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4055 1.1 is 4056 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4057 1.1 is 4058 1.1 is # 4059 1.1 is # copy, convert, and tag input argument 4060 1.1 is # 4061 1.1 is lea FP_SRC(%a6),%a0 4062 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 4063 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 4064 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 4065 1.1 is bsr.l tag # fetch operand type 4066 1.1 is mov.b %d0,STAG(%a6) 4067 1.1 is mov.b %d0,%d1 4068 1.1 is 4069 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4070 1.1 is 4071 1.1 is clr.l %d0 4072 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4073 1.1 is 4074 1.1 is tst.b %d1 4075 1.1 is bne.b _L19_2x 4076 1.1 is bsr.l sgetman # operand is a NORM 4077 1.1 is bra.b _L19_6x 4078 1.1 is _L19_2x: 4079 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4080 1.1 is bne.b _L19_3x # no 4081 1.1 is bsr.l src_zero # yes 4082 1.1 is bra.b _L19_6x 4083 1.1 is _L19_3x: 4084 1.1 is cmpi.b %d1,&INF # is operand an INF? 4085 1.1 is bne.b _L19_4x # no 4086 1.1 is bsr.l t_operr # yes 4087 1.1 is bra.b _L19_6x 4088 1.1 is _L19_4x: 4089 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4090 1.1 is bne.b _L19_5x # no 4091 1.1 is bsr.l src_qnan # yes 4092 1.1 is bra.b _L19_6x 4093 1.1 is _L19_5x: 4094 1.1 is bsr.l sgetmand # operand is a DENORM 4095 1.1 is _L19_6x: 4096 1.1 is 4097 1.1 is # 4098 1.1 is # Result is now in FP0 4099 1.1 is # 4100 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4101 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4102 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4103 1.1 is unlk %a6 4104 1.1 is rts 4105 1.1 is 4106 1.1 is 4107 1.1 is ######################################################################### 4108 1.1 is # MONADIC TEMPLATE # 4109 1.1 is ######################################################################### 4110 1.1 is global _fsincoss_ 4111 1.1 is _fsincoss_: 4112 1.1 is link %a6,&-LOCAL_SIZE 4113 1.1 is 4114 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4115 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4116 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4117 1.1 is 4118 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4119 1.1 is 4120 1.1 is # 4121 1.1 is # copy, convert, and tag input argument 4122 1.1 is # 4123 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl input 4124 1.1 is fmov.x %fp0,FP_SRC(%a6) 4125 1.1 is lea FP_SRC(%a6),%a0 4126 1.1 is bsr.l tag # fetch operand type 4127 1.1 is mov.b %d0,STAG(%a6) 4128 1.1 is mov.b %d0,%d1 4129 1.1 is 4130 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4131 1.1 is 4132 1.1 is clr.l %d0 4133 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4134 1.1 is 4135 1.1 is tst.b %d1 4136 1.1 is bne.b _L20_2s 4137 1.1 is bsr.l ssincos # operand is a NORM 4138 1.1 is bra.b _L20_6s 4139 1.1 is _L20_2s: 4140 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4141 1.1 is bne.b _L20_3s # no 4142 1.1 is bsr.l ssincosz # yes 4143 1.1 is bra.b _L20_6s 4144 1.1 is _L20_3s: 4145 1.1 is cmpi.b %d1,&INF # is operand an INF? 4146 1.1 is bne.b _L20_4s # no 4147 1.1 is bsr.l ssincosi # yes 4148 1.1 is bra.b _L20_6s 4149 1.1 is _L20_4s: 4150 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4151 1.1 is bne.b _L20_5s # no 4152 1.1 is bsr.l ssincosqnan # yes 4153 1.1 is bra.b _L20_6s 4154 1.1 is _L20_5s: 4155 1.1 is bsr.l ssincosd # operand is a DENORM 4156 1.1 is _L20_6s: 4157 1.1 is 4158 1.1 is # 4159 1.1 is # Result is now in FP0 4160 1.1 is # 4161 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4162 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4163 1.1 is fmovm.x &0x03,-(%sp) # store off fp0/fp1 4164 1.1 is fmovm.x (%sp)+,&0x40 # fp0 now in fp1 4165 1.1 is fmovm.x (%sp)+,&0x80 # fp1 now in fp0 4166 1.1 is unlk %a6 4167 1.1 is rts 4168 1.1 is 4169 1.1 is global _fsincosd_ 4170 1.1 is _fsincosd_: 4171 1.1 is link %a6,&-LOCAL_SIZE 4172 1.1 is 4173 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4174 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4175 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4176 1.1 is 4177 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4178 1.1 is 4179 1.1 is # 4180 1.1 is # copy, convert, and tag input argument 4181 1.1 is # 4182 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl input 4183 1.1 is fmov.x %fp0,FP_SRC(%a6) 4184 1.1 is lea FP_SRC(%a6),%a0 4185 1.1 is bsr.l tag # fetch operand type 4186 1.1 is mov.b %d0,STAG(%a6) 4187 1.1 is mov.b %d0,%d1 4188 1.1 is 4189 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4190 1.1 is 4191 1.1 is clr.l %d0 4192 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4193 1.1 is 4194 1.1 is mov.b %d1,STAG(%a6) 4195 1.1 is tst.b %d1 4196 1.1 is bne.b _L20_2d 4197 1.1 is bsr.l ssincos # operand is a NORM 4198 1.1 is bra.b _L20_6d 4199 1.1 is _L20_2d: 4200 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4201 1.1 is bne.b _L20_3d # no 4202 1.1 is bsr.l ssincosz # yes 4203 1.1 is bra.b _L20_6d 4204 1.1 is _L20_3d: 4205 1.1 is cmpi.b %d1,&INF # is operand an INF? 4206 1.1 is bne.b _L20_4d # no 4207 1.1 is bsr.l ssincosi # yes 4208 1.1 is bra.b _L20_6d 4209 1.1 is _L20_4d: 4210 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4211 1.1 is bne.b _L20_5d # no 4212 1.1 is bsr.l ssincosqnan # yes 4213 1.1 is bra.b _L20_6d 4214 1.1 is _L20_5d: 4215 1.1 is bsr.l ssincosd # operand is a DENORM 4216 1.1 is _L20_6d: 4217 1.1 is 4218 1.1 is # 4219 1.1 is # Result is now in FP0 4220 1.1 is # 4221 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4222 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4223 1.1 is fmovm.x &0x03,-(%sp) # store off fp0/fp1 4224 1.1 is fmovm.x (%sp)+,&0x40 # fp0 now in fp1 4225 1.1 is fmovm.x (%sp)+,&0x80 # fp1 now in fp0 4226 1.1 is unlk %a6 4227 1.1 is rts 4228 1.1 is 4229 1.1 is global _fsincosx_ 4230 1.1 is _fsincosx_: 4231 1.1 is link %a6,&-LOCAL_SIZE 4232 1.1 is 4233 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4234 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4235 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4236 1.1 is 4237 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4238 1.1 is 4239 1.1 is # 4240 1.1 is # copy, convert, and tag input argument 4241 1.1 is # 4242 1.1 is lea FP_SRC(%a6),%a0 4243 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 4244 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 4245 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 4246 1.1 is bsr.l tag # fetch operand type 4247 1.1 is mov.b %d0,STAG(%a6) 4248 1.1 is mov.b %d0,%d1 4249 1.1 is 4250 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4251 1.1 is 4252 1.1 is clr.l %d0 4253 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4254 1.1 is 4255 1.1 is tst.b %d1 4256 1.1 is bne.b _L20_2x 4257 1.1 is bsr.l ssincos # operand is a NORM 4258 1.1 is bra.b _L20_6x 4259 1.1 is _L20_2x: 4260 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4261 1.1 is bne.b _L20_3x # no 4262 1.1 is bsr.l ssincosz # yes 4263 1.1 is bra.b _L20_6x 4264 1.1 is _L20_3x: 4265 1.1 is cmpi.b %d1,&INF # is operand an INF? 4266 1.1 is bne.b _L20_4x # no 4267 1.1 is bsr.l ssincosi # yes 4268 1.1 is bra.b _L20_6x 4269 1.1 is _L20_4x: 4270 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4271 1.1 is bne.b _L20_5x # no 4272 1.1 is bsr.l ssincosqnan # yes 4273 1.1 is bra.b _L20_6x 4274 1.1 is _L20_5x: 4275 1.1 is bsr.l ssincosd # operand is a DENORM 4276 1.1 is _L20_6x: 4277 1.1 is 4278 1.1 is # 4279 1.1 is # Result is now in FP0 4280 1.1 is # 4281 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4282 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4283 1.1 is fmovm.x &0x03,-(%sp) # store off fp0/fp1 4284 1.1 is fmovm.x (%sp)+,&0x40 # fp0 now in fp1 4285 1.1 is fmovm.x (%sp)+,&0x80 # fp1 now in fp0 4286 1.1 is unlk %a6 4287 1.1 is rts 4288 1.1 is 4289 1.1 is 4290 1.1 is ######################################################################### 4291 1.1 is # DYADIC TEMPLATE # 4292 1.1 is ######################################################################### 4293 1.1 is global _frems_ 4294 1.1 is _frems_: 4295 1.1 is link %a6,&-LOCAL_SIZE 4296 1.1 is 4297 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4298 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4299 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4300 1.1 is 4301 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4302 1.1 is 4303 1.1 is # 4304 1.1 is # copy, convert, and tag input argument 4305 1.1 is # 4306 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl dst 4307 1.1 is fmov.x %fp0,FP_DST(%a6) 4308 1.1 is lea FP_DST(%a6),%a0 4309 1.1 is bsr.l tag # fetch operand type 4310 1.1 is mov.b %d0,DTAG(%a6) 4311 1.1 is 4312 1.1 is fmov.s 0xc(%a6),%fp0 # load sgl src 4313 1.1 is fmov.x %fp0,FP_SRC(%a6) 4314 1.1 is lea FP_SRC(%a6),%a0 4315 1.1 is bsr.l tag # fetch operand type 4316 1.1 is mov.b %d0,STAG(%a6) 4317 1.1 is mov.l %d0,%d1 4318 1.1 is 4319 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4320 1.1 is 4321 1.1 is clr.l %d0 4322 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4323 1.1 is 4324 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4325 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4326 1.1 is 4327 1.1 is tst.b %d1 4328 1.1 is bne.b _L21_2s 4329 1.1 is bsr.l srem_snorm # operand is a NORM 4330 1.1 is bra.b _L21_6s 4331 1.1 is _L21_2s: 4332 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4333 1.1 is bne.b _L21_3s # no 4334 1.1 is bsr.l srem_szero # yes 4335 1.1 is bra.b _L21_6s 4336 1.1 is _L21_3s: 4337 1.1 is cmpi.b %d1,&INF # is operand an INF? 4338 1.1 is bne.b _L21_4s # no 4339 1.1 is bsr.l srem_sinf # yes 4340 1.1 is bra.b _L21_6s 4341 1.1 is _L21_4s: 4342 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4343 1.1 is bne.b _L21_5s # no 4344 1.1 is bsr.l sop_sqnan # yes 4345 1.1 is bra.b _L21_6s 4346 1.1 is _L21_5s: 4347 1.1 is bsr.l srem_sdnrm # operand is a DENORM 4348 1.1 is _L21_6s: 4349 1.1 is 4350 1.1 is # 4351 1.1 is # Result is now in FP0 4352 1.1 is # 4353 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4354 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4355 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4356 1.1 is unlk %a6 4357 1.1 is rts 4358 1.1 is 4359 1.1 is global _fremd_ 4360 1.1 is _fremd_: 4361 1.1 is link %a6,&-LOCAL_SIZE 4362 1.1 is 4363 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4364 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4365 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4366 1.1 is 4367 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4368 1.1 is 4369 1.1 is # 4370 1.1 is # copy, convert, and tag input argument 4371 1.1 is # 4372 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl dst 4373 1.1 is fmov.x %fp0,FP_DST(%a6) 4374 1.1 is lea FP_DST(%a6),%a0 4375 1.1 is bsr.l tag # fetch operand type 4376 1.1 is mov.b %d0,DTAG(%a6) 4377 1.1 is 4378 1.1 is fmov.d 0x10(%a6),%fp0 # load dbl src 4379 1.1 is fmov.x %fp0,FP_SRC(%a6) 4380 1.1 is lea FP_SRC(%a6),%a0 4381 1.1 is bsr.l tag # fetch operand type 4382 1.1 is mov.b %d0,STAG(%a6) 4383 1.1 is mov.l %d0,%d1 4384 1.1 is 4385 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4386 1.1 is 4387 1.1 is clr.l %d0 4388 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4389 1.1 is 4390 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4391 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4392 1.1 is 4393 1.1 is tst.b %d1 4394 1.1 is bne.b _L21_2d 4395 1.1 is bsr.l srem_snorm # operand is a NORM 4396 1.1 is bra.b _L21_6d 4397 1.1 is _L21_2d: 4398 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4399 1.1 is bne.b _L21_3d # no 4400 1.1 is bsr.l srem_szero # yes 4401 1.1 is bra.b _L21_6d 4402 1.1 is _L21_3d: 4403 1.1 is cmpi.b %d1,&INF # is operand an INF? 4404 1.1 is bne.b _L21_4d # no 4405 1.1 is bsr.l srem_sinf # yes 4406 1.1 is bra.b _L21_6d 4407 1.1 is _L21_4d: 4408 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4409 1.1 is bne.b _L21_5d # no 4410 1.1 is bsr.l sop_sqnan # yes 4411 1.1 is bra.b _L21_6d 4412 1.1 is _L21_5d: 4413 1.1 is bsr.l srem_sdnrm # operand is a DENORM 4414 1.1 is _L21_6d: 4415 1.1 is 4416 1.1 is # 4417 1.1 is # Result is now in FP0 4418 1.1 is # 4419 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4420 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4421 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4422 1.1 is unlk %a6 4423 1.1 is rts 4424 1.1 is 4425 1.1 is global _fremx_ 4426 1.1 is _fremx_: 4427 1.1 is link %a6,&-LOCAL_SIZE 4428 1.1 is 4429 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4430 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4431 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4432 1.1 is 4433 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4434 1.1 is 4435 1.1 is # 4436 1.1 is # copy, convert, and tag input argument 4437 1.1 is # 4438 1.1 is lea FP_DST(%a6),%a0 4439 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 4440 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 4441 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 4442 1.1 is bsr.l tag # fetch operand type 4443 1.1 is mov.b %d0,DTAG(%a6) 4444 1.1 is 4445 1.1 is lea FP_SRC(%a6),%a0 4446 1.1 is mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 4447 1.1 is mov.l 0x14+0x4(%a6),0x4(%a0) 4448 1.1 is mov.l 0x14+0x8(%a6),0x8(%a0) 4449 1.1 is bsr.l tag # fetch operand type 4450 1.1 is mov.b %d0,STAG(%a6) 4451 1.1 is mov.l %d0,%d1 4452 1.1 is 4453 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4454 1.1 is 4455 1.1 is clr.l %d0 4456 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4457 1.1 is 4458 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4459 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4460 1.1 is 4461 1.1 is tst.b %d1 4462 1.1 is bne.b _L21_2x 4463 1.1 is bsr.l srem_snorm # operand is a NORM 4464 1.1 is bra.b _L21_6x 4465 1.1 is _L21_2x: 4466 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4467 1.1 is bne.b _L21_3x # no 4468 1.1 is bsr.l srem_szero # yes 4469 1.1 is bra.b _L21_6x 4470 1.1 is _L21_3x: 4471 1.1 is cmpi.b %d1,&INF # is operand an INF? 4472 1.1 is bne.b _L21_4x # no 4473 1.1 is bsr.l srem_sinf # yes 4474 1.1 is bra.b _L21_6x 4475 1.1 is _L21_4x: 4476 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4477 1.1 is bne.b _L21_5x # no 4478 1.1 is bsr.l sop_sqnan # yes 4479 1.1 is bra.b _L21_6x 4480 1.1 is _L21_5x: 4481 1.1 is bsr.l srem_sdnrm # operand is a DENORM 4482 1.1 is _L21_6x: 4483 1.1 is 4484 1.1 is # 4485 1.1 is # Result is now in FP0 4486 1.1 is # 4487 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4488 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4489 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4490 1.1 is unlk %a6 4491 1.1 is rts 4492 1.1 is 4493 1.1 is 4494 1.1 is ######################################################################### 4495 1.1 is # DYADIC TEMPLATE # 4496 1.1 is ######################################################################### 4497 1.1 is global _fmods_ 4498 1.1 is _fmods_: 4499 1.1 is link %a6,&-LOCAL_SIZE 4500 1.1 is 4501 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4502 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4503 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4504 1.1 is 4505 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4506 1.1 is 4507 1.1 is # 4508 1.1 is # copy, convert, and tag input argument 4509 1.1 is # 4510 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl dst 4511 1.1 is fmov.x %fp0,FP_DST(%a6) 4512 1.1 is lea FP_DST(%a6),%a0 4513 1.1 is bsr.l tag # fetch operand type 4514 1.1 is mov.b %d0,DTAG(%a6) 4515 1.1 is 4516 1.1 is fmov.s 0xc(%a6),%fp0 # load sgl src 4517 1.1 is fmov.x %fp0,FP_SRC(%a6) 4518 1.1 is lea FP_SRC(%a6),%a0 4519 1.1 is bsr.l tag # fetch operand type 4520 1.1 is mov.b %d0,STAG(%a6) 4521 1.1 is mov.l %d0,%d1 4522 1.1 is 4523 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4524 1.1 is 4525 1.1 is clr.l %d0 4526 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4527 1.1 is 4528 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4529 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4530 1.1 is 4531 1.1 is tst.b %d1 4532 1.1 is bne.b _L22_2s 4533 1.1 is bsr.l smod_snorm # operand is a NORM 4534 1.1 is bra.b _L22_6s 4535 1.1 is _L22_2s: 4536 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4537 1.1 is bne.b _L22_3s # no 4538 1.1 is bsr.l smod_szero # yes 4539 1.1 is bra.b _L22_6s 4540 1.1 is _L22_3s: 4541 1.1 is cmpi.b %d1,&INF # is operand an INF? 4542 1.1 is bne.b _L22_4s # no 4543 1.1 is bsr.l smod_sinf # yes 4544 1.1 is bra.b _L22_6s 4545 1.1 is _L22_4s: 4546 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4547 1.1 is bne.b _L22_5s # no 4548 1.1 is bsr.l sop_sqnan # yes 4549 1.1 is bra.b _L22_6s 4550 1.1 is _L22_5s: 4551 1.1 is bsr.l smod_sdnrm # operand is a DENORM 4552 1.1 is _L22_6s: 4553 1.1 is 4554 1.1 is # 4555 1.1 is # Result is now in FP0 4556 1.1 is # 4557 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4558 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4559 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4560 1.1 is unlk %a6 4561 1.1 is rts 4562 1.1 is 4563 1.1 is global _fmodd_ 4564 1.1 is _fmodd_: 4565 1.1 is link %a6,&-LOCAL_SIZE 4566 1.1 is 4567 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4568 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4569 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4570 1.1 is 4571 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4572 1.1 is 4573 1.1 is # 4574 1.1 is # copy, convert, and tag input argument 4575 1.1 is # 4576 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl dst 4577 1.1 is fmov.x %fp0,FP_DST(%a6) 4578 1.1 is lea FP_DST(%a6),%a0 4579 1.1 is bsr.l tag # fetch operand type 4580 1.1 is mov.b %d0,DTAG(%a6) 4581 1.1 is 4582 1.1 is fmov.d 0x10(%a6),%fp0 # load dbl src 4583 1.1 is fmov.x %fp0,FP_SRC(%a6) 4584 1.1 is lea FP_SRC(%a6),%a0 4585 1.1 is bsr.l tag # fetch operand type 4586 1.1 is mov.b %d0,STAG(%a6) 4587 1.1 is mov.l %d0,%d1 4588 1.1 is 4589 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4590 1.1 is 4591 1.1 is clr.l %d0 4592 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4593 1.1 is 4594 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4595 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4596 1.1 is 4597 1.1 is tst.b %d1 4598 1.1 is bne.b _L22_2d 4599 1.1 is bsr.l smod_snorm # operand is a NORM 4600 1.1 is bra.b _L22_6d 4601 1.1 is _L22_2d: 4602 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4603 1.1 is bne.b _L22_3d # no 4604 1.1 is bsr.l smod_szero # yes 4605 1.1 is bra.b _L22_6d 4606 1.1 is _L22_3d: 4607 1.1 is cmpi.b %d1,&INF # is operand an INF? 4608 1.1 is bne.b _L22_4d # no 4609 1.1 is bsr.l smod_sinf # yes 4610 1.1 is bra.b _L22_6d 4611 1.1 is _L22_4d: 4612 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4613 1.1 is bne.b _L22_5d # no 4614 1.1 is bsr.l sop_sqnan # yes 4615 1.1 is bra.b _L22_6d 4616 1.1 is _L22_5d: 4617 1.1 is bsr.l smod_sdnrm # operand is a DENORM 4618 1.1 is _L22_6d: 4619 1.1 is 4620 1.1 is # 4621 1.1 is # Result is now in FP0 4622 1.1 is # 4623 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4624 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4625 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4626 1.1 is unlk %a6 4627 1.1 is rts 4628 1.1 is 4629 1.1 is global _fmodx_ 4630 1.1 is _fmodx_: 4631 1.1 is link %a6,&-LOCAL_SIZE 4632 1.1 is 4633 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4634 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4635 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4636 1.1 is 4637 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4638 1.1 is 4639 1.1 is # 4640 1.1 is # copy, convert, and tag input argument 4641 1.1 is # 4642 1.1 is lea FP_DST(%a6),%a0 4643 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 4644 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 4645 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 4646 1.1 is bsr.l tag # fetch operand type 4647 1.1 is mov.b %d0,DTAG(%a6) 4648 1.1 is 4649 1.1 is lea FP_SRC(%a6),%a0 4650 1.1 is mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 4651 1.1 is mov.l 0x14+0x4(%a6),0x4(%a0) 4652 1.1 is mov.l 0x14+0x8(%a6),0x8(%a0) 4653 1.1 is bsr.l tag # fetch operand type 4654 1.1 is mov.b %d0,STAG(%a6) 4655 1.1 is mov.l %d0,%d1 4656 1.1 is 4657 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4658 1.1 is 4659 1.1 is clr.l %d0 4660 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4661 1.1 is 4662 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4663 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4664 1.1 is 4665 1.1 is tst.b %d1 4666 1.1 is bne.b _L22_2x 4667 1.1 is bsr.l smod_snorm # operand is a NORM 4668 1.1 is bra.b _L22_6x 4669 1.1 is _L22_2x: 4670 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4671 1.1 is bne.b _L22_3x # no 4672 1.1 is bsr.l smod_szero # yes 4673 1.1 is bra.b _L22_6x 4674 1.1 is _L22_3x: 4675 1.1 is cmpi.b %d1,&INF # is operand an INF? 4676 1.1 is bne.b _L22_4x # no 4677 1.1 is bsr.l smod_sinf # yes 4678 1.1 is bra.b _L22_6x 4679 1.1 is _L22_4x: 4680 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4681 1.1 is bne.b _L22_5x # no 4682 1.1 is bsr.l sop_sqnan # yes 4683 1.1 is bra.b _L22_6x 4684 1.1 is _L22_5x: 4685 1.1 is bsr.l smod_sdnrm # operand is a DENORM 4686 1.1 is _L22_6x: 4687 1.1 is 4688 1.1 is # 4689 1.1 is # Result is now in FP0 4690 1.1 is # 4691 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4692 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4693 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4694 1.1 is unlk %a6 4695 1.1 is rts 4696 1.1 is 4697 1.1 is 4698 1.1 is ######################################################################### 4699 1.1 is # DYADIC TEMPLATE # 4700 1.1 is ######################################################################### 4701 1.1 is global _fscales_ 4702 1.1 is _fscales_: 4703 1.1 is link %a6,&-LOCAL_SIZE 4704 1.1 is 4705 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4706 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4707 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4708 1.1 is 4709 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4710 1.1 is 4711 1.1 is # 4712 1.1 is # copy, convert, and tag input argument 4713 1.1 is # 4714 1.1 is fmov.s 0x8(%a6),%fp0 # load sgl dst 4715 1.1 is fmov.x %fp0,FP_DST(%a6) 4716 1.1 is lea FP_DST(%a6),%a0 4717 1.1 is bsr.l tag # fetch operand type 4718 1.1 is mov.b %d0,DTAG(%a6) 4719 1.1 is 4720 1.1 is fmov.s 0xc(%a6),%fp0 # load sgl src 4721 1.1 is fmov.x %fp0,FP_SRC(%a6) 4722 1.1 is lea FP_SRC(%a6),%a0 4723 1.1 is bsr.l tag # fetch operand type 4724 1.1 is mov.b %d0,STAG(%a6) 4725 1.1 is mov.l %d0,%d1 4726 1.1 is 4727 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4728 1.1 is 4729 1.1 is clr.l %d0 4730 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4731 1.1 is 4732 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4733 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4734 1.1 is 4735 1.1 is tst.b %d1 4736 1.1 is bne.b _L23_2s 4737 1.1 is bsr.l sscale_snorm # operand is a NORM 4738 1.1 is bra.b _L23_6s 4739 1.1 is _L23_2s: 4740 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4741 1.1 is bne.b _L23_3s # no 4742 1.1 is bsr.l sscale_szero # yes 4743 1.1 is bra.b _L23_6s 4744 1.1 is _L23_3s: 4745 1.1 is cmpi.b %d1,&INF # is operand an INF? 4746 1.1 is bne.b _L23_4s # no 4747 1.1 is bsr.l sscale_sinf # yes 4748 1.1 is bra.b _L23_6s 4749 1.1 is _L23_4s: 4750 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4751 1.1 is bne.b _L23_5s # no 4752 1.1 is bsr.l sop_sqnan # yes 4753 1.1 is bra.b _L23_6s 4754 1.1 is _L23_5s: 4755 1.1 is bsr.l sscale_sdnrm # operand is a DENORM 4756 1.1 is _L23_6s: 4757 1.1 is 4758 1.1 is # 4759 1.1 is # Result is now in FP0 4760 1.1 is # 4761 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4762 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4763 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4764 1.1 is unlk %a6 4765 1.1 is rts 4766 1.1 is 4767 1.1 is global _fscaled_ 4768 1.1 is _fscaled_: 4769 1.1 is link %a6,&-LOCAL_SIZE 4770 1.1 is 4771 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4772 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4773 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4774 1.1 is 4775 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4776 1.1 is 4777 1.1 is # 4778 1.1 is # copy, convert, and tag input argument 4779 1.1 is # 4780 1.1 is fmov.d 0x8(%a6),%fp0 # load dbl dst 4781 1.1 is fmov.x %fp0,FP_DST(%a6) 4782 1.1 is lea FP_DST(%a6),%a0 4783 1.1 is bsr.l tag # fetch operand type 4784 1.1 is mov.b %d0,DTAG(%a6) 4785 1.1 is 4786 1.1 is fmov.d 0x10(%a6),%fp0 # load dbl src 4787 1.1 is fmov.x %fp0,FP_SRC(%a6) 4788 1.1 is lea FP_SRC(%a6),%a0 4789 1.1 is bsr.l tag # fetch operand type 4790 1.1 is mov.b %d0,STAG(%a6) 4791 1.1 is mov.l %d0,%d1 4792 1.1 is 4793 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4794 1.1 is 4795 1.1 is clr.l %d0 4796 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4797 1.1 is 4798 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4799 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4800 1.1 is 4801 1.1 is tst.b %d1 4802 1.1 is bne.b _L23_2d 4803 1.1 is bsr.l sscale_snorm # operand is a NORM 4804 1.1 is bra.b _L23_6d 4805 1.1 is _L23_2d: 4806 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4807 1.1 is bne.b _L23_3d # no 4808 1.1 is bsr.l sscale_szero # yes 4809 1.1 is bra.b _L23_6d 4810 1.1 is _L23_3d: 4811 1.1 is cmpi.b %d1,&INF # is operand an INF? 4812 1.1 is bne.b _L23_4d # no 4813 1.1 is bsr.l sscale_sinf # yes 4814 1.1 is bra.b _L23_6d 4815 1.1 is _L23_4d: 4816 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4817 1.1 is bne.b _L23_5d # no 4818 1.1 is bsr.l sop_sqnan # yes 4819 1.1 is bra.b _L23_6d 4820 1.1 is _L23_5d: 4821 1.1 is bsr.l sscale_sdnrm # operand is a DENORM 4822 1.1 is _L23_6d: 4823 1.1 is 4824 1.1 is # 4825 1.1 is # Result is now in FP0 4826 1.1 is # 4827 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4828 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4829 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4830 1.1 is unlk %a6 4831 1.1 is rts 4832 1.1 is 4833 1.1 is global _fscalex_ 4834 1.1 is _fscalex_: 4835 1.1 is link %a6,&-LOCAL_SIZE 4836 1.1 is 4837 1.1 is movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4838 1.1 is fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 4839 1.1 is fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 4840 1.1 is 4841 1.1 is fmov.l &0x0,%fpcr # zero FPCR 4842 1.1 is 4843 1.1 is # 4844 1.1 is # copy, convert, and tag input argument 4845 1.1 is # 4846 1.1 is lea FP_DST(%a6),%a0 4847 1.1 is mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 4848 1.1 is mov.l 0x8+0x4(%a6),0x4(%a0) 4849 1.1 is mov.l 0x8+0x8(%a6),0x8(%a0) 4850 1.1 is bsr.l tag # fetch operand type 4851 1.1 is mov.b %d0,DTAG(%a6) 4852 1.1 is 4853 1.1 is lea FP_SRC(%a6),%a0 4854 1.1 is mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 4855 1.1 is mov.l 0x14+0x4(%a6),0x4(%a0) 4856 1.1 is mov.l 0x14+0x8(%a6),0x8(%a0) 4857 1.1 is bsr.l tag # fetch operand type 4858 1.1 is mov.b %d0,STAG(%a6) 4859 1.1 is mov.l %d0,%d1 4860 1.1 is 4861 1.1 is andi.l &0x00ff00ff,USER_FPSR(%a6) 4862 1.1 is 4863 1.1 is clr.l %d0 4864 1.1 is mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 4865 1.1 is 4866 1.1 is lea FP_SRC(%a6),%a0 # pass ptr to src 4867 1.1 is lea FP_DST(%a6),%a1 # pass ptr to dst 4868 1.1 is 4869 1.1 is tst.b %d1 4870 1.1 is bne.b _L23_2x 4871 1.1 is bsr.l sscale_snorm # operand is a NORM 4872 1.1 is bra.b _L23_6x 4873 1.1 is _L23_2x: 4874 1.1 is cmpi.b %d1,&ZERO # is operand a ZERO? 4875 1.1 is bne.b _L23_3x # no 4876 1.1 is bsr.l sscale_szero # yes 4877 1.1 is bra.b _L23_6x 4878 1.1 is _L23_3x: 4879 1.1 is cmpi.b %d1,&INF # is operand an INF? 4880 1.1 is bne.b _L23_4x # no 4881 1.1 is bsr.l sscale_sinf # yes 4882 1.1 is bra.b _L23_6x 4883 1.1 is _L23_4x: 4884 1.1 is cmpi.b %d1,&QNAN # is operand a QNAN? 4885 1.1 is bne.b _L23_5x # no 4886 1.1 is bsr.l sop_sqnan # yes 4887 1.1 is bra.b _L23_6x 4888 1.1 is _L23_5x: 4889 1.1 is bsr.l sscale_sdnrm # operand is a DENORM 4890 1.1 is _L23_6x: 4891 1.1 is 4892 1.1 is # 4893 1.1 is # Result is now in FP0 4894 1.1 is # 4895 1.1 is movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4896 1.1 is fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 4897 1.1 is fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 4898 1.1 is unlk %a6 4899 1.1 is rts 4900 1.1 is 4901 1.1 is 4902 1.1 is ######################################################################### 4903 1.1 is # ssin(): computes the sine of a normalized input # 4904 1.1 is # ssind(): computes the sine of a denormalized input # 4905 1.1 is # scos(): computes the cosine of a normalized input # 4906 1.1 is # scosd(): computes the cosine of a denormalized input # 4907 1.1 is # ssincos(): computes the sine and cosine of a normalized input # 4908 1.1 is # ssincosd(): computes the sine and cosine of a denormalized input # 4909 1.1 is # # 4910 1.1 is # INPUT *************************************************************** # 4911 1.1 is # a0 = pointer to extended precision input # 4912 1.1 is # d0 = round precision,mode # 4913 1.1 is # # 4914 1.1 is # OUTPUT ************************************************************** # 4915 1.1 is # fp0 = sin(X) or cos(X) # 4916 1.1 is # # 4917 1.1 is # For ssincos(X): # 4918 1.1 is # fp0 = sin(X) # 4919 1.1 is # fp1 = cos(X) # 4920 1.1 is # # 4921 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 4922 1.1 is # The returned result is within 1 ulp in 64 significant bit, i.e. # 4923 1.1 is # within 0.5001 ulp to 53 bits if the result is subsequently # 4924 1.1 is # rounded to double precision. The result is provably monotonic # 4925 1.1 is # in double precision. # 4926 1.1 is # # 4927 1.1 is # ALGORITHM *********************************************************** # 4928 1.1 is # # 4929 1.1 is # SIN and COS: # 4930 1.1 is # 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. # 4931 1.1 is # # 4932 1.1 is # 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. # 4933 1.1 is # # 4934 1.1 is # 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 4935 1.1 is # k = N mod 4, so in particular, k = 0,1,2,or 3. # 4936 1.1 is # Overwrite k by k := k + AdjN. # 4937 1.1 is # # 4938 1.1 is # 4. If k is even, go to 6. # 4939 1.1 is # # 4940 1.1 is # 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. # 4941 1.1 is # Return sgn*cos(r) where cos(r) is approximated by an # 4942 1.1 is # even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), # 4943 1.1 is # s = r*r. # 4944 1.1 is # Exit. # 4945 1.1 is # # 4946 1.1 is # 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) # 4947 1.1 is # where sin(r) is approximated by an odd polynomial in r # 4948 1.1 is # r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. # 4949 1.1 is # Exit. # 4950 1.1 is # # 4951 1.1 is # 7. If |X| > 1, go to 9. # 4952 1.1 is # # 4953 1.1 is # 8. (|X|<2**(-40)) If SIN is invoked, return X; # 4954 1.1 is # otherwise return 1. # 4955 1.1 is # # 4956 1.1 is # 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 4957 1.1 is # go back to 3. # 4958 1.1 is # # 4959 1.1 is # SINCOS: # 4960 1.1 is # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 4961 1.1 is # # 4962 1.1 is # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 4963 1.1 is # k = N mod 4, so in particular, k = 0,1,2,or 3. # 4964 1.1 is # # 4965 1.1 is # 3. If k is even, go to 5. # 4966 1.1 is # # 4967 1.1 is # 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie. # 4968 1.1 is # j1 exclusive or with the l.s.b. of k. # 4969 1.1 is # sgn1 := (-1)**j1, sgn2 := (-1)**j2. # 4970 1.1 is # SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where # 4971 1.1 is # sin(r) and cos(r) are computed as odd and even # 4972 1.1 is # polynomials in r, respectively. Exit # 4973 1.1 is # # 4974 1.1 is # 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. # 4975 1.1 is # SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where # 4976 1.1 is # sin(r) and cos(r) are computed as odd and even # 4977 1.1 is # polynomials in r, respectively. Exit # 4978 1.1 is # # 4979 1.1 is # 6. If |X| > 1, go to 8. # 4980 1.1 is # # 4981 1.1 is # 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. # 4982 1.1 is # # 4983 1.1 is # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 4984 1.1 is # go back to 2. # 4985 1.1 is # # 4986 1.1 is ######################################################################### 4987 1.1 is 4988 1.1 is SINA7: long 0xBD6AAA77,0xCCC994F5 4989 1.1 is SINA6: long 0x3DE61209,0x7AAE8DA1 4990 1.1 is SINA5: long 0xBE5AE645,0x2A118AE4 4991 1.1 is SINA4: long 0x3EC71DE3,0xA5341531 4992 1.1 is SINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000 4993 1.1 is SINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000 4994 1.1 is SINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000 4995 1.1 is 4996 1.1 is COSB8: long 0x3D2AC4D0,0xD6011EE3 4997 1.1 is COSB7: long 0xBDA9396F,0x9F45AC19 4998 1.1 is COSB6: long 0x3E21EED9,0x0612C972 4999 1.1 is COSB5: long 0xBE927E4F,0xB79D9FCF 5000 1.1 is COSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000 5001 1.1 is COSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000 5002 1.1 is COSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E 5003 1.1 is COSB1: long 0xBF000000 5004 1.1 is 5005 1.1 is set INARG,FP_SCR0 5006 1.1 is 5007 1.1 is set X,FP_SCR0 5008 1.1 is # set XDCARE,X+2 5009 1.1 is set XFRAC,X+4 5010 1.1 is 5011 1.1 is set RPRIME,FP_SCR0 5012 1.1 is set SPRIME,FP_SCR1 5013 1.1 is 5014 1.1 is set POSNEG1,L_SCR1 5015 1.1 is set TWOTO63,L_SCR1 5016 1.1 is 5017 1.1 is set ENDFLAG,L_SCR2 5018 1.1 is set INT,L_SCR2 5019 1.1 is 5020 1.1 is set ADJN,L_SCR3 5021 1.1 is 5022 1.1 is ############################################ 5023 1.1 is global ssin 5024 1.1 is ssin: 5025 1.1 is mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0 5026 1.1 is bra.b SINBGN 5027 1.1 is 5028 1.1 is ############################################ 5029 1.1 is global scos 5030 1.1 is scos: 5031 1.1 is mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1 5032 1.1 is 5033 1.1 is ############################################ 5034 1.1 is SINBGN: 5035 1.1 is #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE 5036 1.1 is 5037 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 5038 1.1 is fmov.x %fp0,X(%a6) # save input at X 5039 1.1 is 5040 1.1 is # "COMPACTIFY" X 5041 1.1 is mov.l (%a0),%d1 # put exp in hi word 5042 1.1 is mov.w 4(%a0),%d1 # fetch hi(man) 5043 1.1 is and.l &0x7FFFFFFF,%d1 # strip sign 5044 1.1 is 5045 1.1 is cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)? 5046 1.1 is bge.b SOK1 # no 5047 1.1 is bra.w SINSM # yes; input is very small 5048 1.1 is 5049 1.1 is SOK1: 5050 1.1 is cmp.l %d1,&0x4004BC7E # is |X| < 15 PI? 5051 1.1 is blt.b SINMAIN # no 5052 1.1 is bra.w SREDUCEX # yes; input is very large 5053 1.1 is 5054 1.1 is #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5055 1.1 is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 5056 1.1 is SINMAIN: 5057 1.1 is fmov.x %fp0,%fp1 5058 1.1 is fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 5059 1.1 is 5060 1.1 is lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 5061 1.1 is 5062 1.1 is fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 5063 1.1 is 5064 1.1 is mov.l INT(%a6),%d1 # make a copy of N 5065 1.1 is asl.l &4,%d1 # N *= 16 5066 1.1 is add.l %d1,%a1 # tbl_addr = a1 + (N*16) 5067 1.1 is 5068 1.1 is # A1 IS THE ADDRESS OF N*PIBY2 5069 1.1 is # ...WHICH IS IN TWO PIECES Y1 & Y2 5070 1.1 is fsub.x (%a1)+,%fp0 # X-Y1 5071 1.1 is fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2 5072 1.1 is 5073 1.1 is SINCONT: 5074 1.1 is #--continuation from REDUCEX 5075 1.1 is 5076 1.1 is #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED 5077 1.1 is mov.l INT(%a6),%d1 5078 1.1 is add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN 5079 1.1 is ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE 5080 1.1 is cmp.l %d1,&0 5081 1.1 is blt.w COSPOLY 5082 1.1 is 5083 1.1 is #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 5084 1.1 is #--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY 5085 1.1 is #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE 5086 1.1 is #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS 5087 1.1 is #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))]) 5088 1.1 is #--WHERE T=S*S. 5089 1.1 is #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION 5090 1.1 is #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT. 5091 1.1 is SINPOLY: 5092 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3 5093 1.1 is 5094 1.1 is fmov.x %fp0,X(%a6) # X IS R 5095 1.1 is fmul.x %fp0,%fp0 # FP0 IS S 5096 1.1 is 5097 1.1 is fmov.d SINA7(%pc),%fp3 5098 1.1 is fmov.d SINA6(%pc),%fp2 5099 1.1 is 5100 1.1 is fmov.x %fp0,%fp1 5101 1.1 is fmul.x %fp1,%fp1 # FP1 IS T 5102 1.1 is 5103 1.1 is ror.l &1,%d1 5104 1.1 is and.l &0x80000000,%d1 5105 1.1 is # ...LEAST SIG. BIT OF D0 IN SIGN POSITION 5106 1.1 is eor.l %d1,X(%a6) # X IS NOW R'= SGN*R 5107 1.1 is 5108 1.1 is fmul.x %fp1,%fp3 # TA7 5109 1.1 is fmul.x %fp1,%fp2 # TA6 5110 1.1 is 5111 1.1 is fadd.d SINA5(%pc),%fp3 # A5+TA7 5112 1.1 is fadd.d SINA4(%pc),%fp2 # A4+TA6 5113 1.1 is 5114 1.1 is fmul.x %fp1,%fp3 # T(A5+TA7) 5115 1.1 is fmul.x %fp1,%fp2 # T(A4+TA6) 5116 1.1 is 5117 1.1 is fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7) 5118 1.1 is fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6) 5119 1.1 is 5120 1.1 is fmul.x %fp3,%fp1 # T(A3+T(A5+TA7)) 5121 1.1 is 5122 1.1 is fmul.x %fp0,%fp2 # S(A2+T(A4+TA6)) 5123 1.1 is fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7)) 5124 1.1 is fmul.x X(%a6),%fp0 # R'*S 5125 1.1 is 5126 1.1 is fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))] 5127 1.1 is 5128 1.1 is fmul.x %fp1,%fp0 # SIN(R')-R' 5129 1.1 is 5130 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3 5131 1.1 is 5132 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5133 1.1 is fadd.x X(%a6),%fp0 # last inst - possible exception set 5134 1.1 is bra t_inx2 5135 1.1 is 5136 1.1 is #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 5137 1.1 is #--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY 5138 1.1 is #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE 5139 1.1 is #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS 5140 1.1 is #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))]) 5141 1.1 is #--WHERE T=S*S. 5142 1.1 is #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION 5143 1.1 is #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2 5144 1.1 is #--AND IS THEREFORE STORED AS SINGLE PRECISION. 5145 1.1 is COSPOLY: 5146 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3 5147 1.1 is 5148 1.1 is fmul.x %fp0,%fp0 # FP0 IS S 5149 1.1 is 5150 1.1 is fmov.d COSB8(%pc),%fp2 5151 1.1 is fmov.d COSB7(%pc),%fp3 5152 1.1 is 5153 1.1 is fmov.x %fp0,%fp1 5154 1.1 is fmul.x %fp1,%fp1 # FP1 IS T 5155 1.1 is 5156 1.1 is fmov.x %fp0,X(%a6) # X IS S 5157 1.1 is ror.l &1,%d1 5158 1.1 is and.l &0x80000000,%d1 5159 1.1 is # ...LEAST SIG. BIT OF D0 IN SIGN POSITION 5160 1.1 is 5161 1.1 is fmul.x %fp1,%fp2 # TB8 5162 1.1 is 5163 1.1 is eor.l %d1,X(%a6) # X IS NOW S'= SGN*S 5164 1.1 is and.l &0x80000000,%d1 5165 1.1 is 5166 1.1 is fmul.x %fp1,%fp3 # TB7 5167 1.1 is 5168 1.1 is or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE 5169 1.1 is mov.l %d1,POSNEG1(%a6) 5170 1.1 is 5171 1.1 is fadd.d COSB6(%pc),%fp2 # B6+TB8 5172 1.1 is fadd.d COSB5(%pc),%fp3 # B5+TB7 5173 1.1 is 5174 1.1 is fmul.x %fp1,%fp2 # T(B6+TB8) 5175 1.1 is fmul.x %fp1,%fp3 # T(B5+TB7) 5176 1.1 is 5177 1.1 is fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8) 5178 1.1 is fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7) 5179 1.1 is 5180 1.1 is fmul.x %fp1,%fp2 # T(B4+T(B6+TB8)) 5181 1.1 is fmul.x %fp3,%fp1 # T(B3+T(B5+TB7)) 5182 1.1 is 5183 1.1 is fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8)) 5184 1.1 is fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7)) 5185 1.1 is 5186 1.1 is fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8))) 5187 1.1 is 5188 1.1 is fadd.x %fp1,%fp0 5189 1.1 is 5190 1.1 is fmul.x X(%a6),%fp0 5191 1.1 is 5192 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3 5193 1.1 is 5194 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5195 1.1 is fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set 5196 1.1 is bra t_inx2 5197 1.1 is 5198 1.1 is ############################################## 5199 1.1 is 5200 1.1 is # SINe: Big OR Small? 5201 1.1 is #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 5202 1.1 is #--IF |X| < 2**(-40), RETURN X OR 1. 5203 1.1 is SINBORS: 5204 1.1 is cmp.l %d1,&0x3FFF8000 5205 1.1 is bgt.l SREDUCEX 5206 1.1 is 5207 1.1 is SINSM: 5208 1.1 is mov.l ADJN(%a6),%d1 5209 1.1 is cmp.l %d1,&0 5210 1.1 is bgt.b COSTINY 5211 1.1 is 5212 1.1 is # here, the operation may underflow iff the precision is sgl or dbl. 5213 1.1 is # extended denorms are handled through another entry point. 5214 1.1 is SINTINY: 5215 1.1 is # mov.w &0x0000,XDCARE(%a6) # JUST IN CASE 5216 1.1 is 5217 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5218 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 5219 1.1 is fmov.x X(%a6),%fp0 # last inst - possible exception set 5220 1.1 is bra t_catch 5221 1.1 is 5222 1.1 is COSTINY: 5223 1.1 is fmov.s &0x3F800000,%fp0 # fp0 = 1.0 5224 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5225 1.1 is fadd.s &0x80800000,%fp0 # last inst - possible exception set 5226 1.1 is bra t_pinx2 5227 1.1 is 5228 1.1 is ################################################ 5229 1.1 is global ssind 5230 1.1 is #--SIN(X) = X FOR DENORMALIZED X 5231 1.1 is ssind: 5232 1.1 is bra t_extdnrm 5233 1.1 is 5234 1.1 is ############################################ 5235 1.1 is global scosd 5236 1.1 is #--COS(X) = 1 FOR DENORMALIZED X 5237 1.1 is scosd: 5238 1.1 is fmov.s &0x3F800000,%fp0 # fp0 = 1.0 5239 1.1 is bra t_pinx2 5240 1.1 is 5241 1.1 is ################################################## 5242 1.1 is 5243 1.1 is global ssincos 5244 1.1 is ssincos: 5245 1.1 is #--SET ADJN TO 4 5246 1.1 is mov.l &4,ADJN(%a6) 5247 1.1 is 5248 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 5249 1.1 is fmov.x %fp0,X(%a6) 5250 1.1 is 5251 1.1 is mov.l (%a0),%d1 5252 1.1 is mov.w 4(%a0),%d1 5253 1.1 is and.l &0x7FFFFFFF,%d1 # COMPACTIFY X 5254 1.1 is 5255 1.1 is cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 5256 1.1 is bge.b SCOK1 5257 1.1 is bra.w SCSM 5258 1.1 is 5259 1.1 is SCOK1: 5260 1.1 is cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 5261 1.1 is blt.b SCMAIN 5262 1.1 is bra.w SREDUCEX 5263 1.1 is 5264 1.1 is 5265 1.1 is #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5266 1.1 is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 5267 1.1 is SCMAIN: 5268 1.1 is fmov.x %fp0,%fp1 5269 1.1 is 5270 1.1 is fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 5271 1.1 is 5272 1.1 is lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 5273 1.1 is 5274 1.1 is fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 5275 1.1 is 5276 1.1 is mov.l INT(%a6),%d1 5277 1.1 is asl.l &4,%d1 5278 1.1 is add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2 5279 1.1 is 5280 1.1 is fsub.x (%a1)+,%fp0 # X-Y1 5281 1.1 is fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 5282 1.1 is 5283 1.1 is SCCONT: 5284 1.1 is #--continuation point from REDUCEX 5285 1.1 is 5286 1.1 is mov.l INT(%a6),%d1 5287 1.1 is ror.l &1,%d1 5288 1.1 is cmp.l %d1,&0 # D0 < 0 IFF N IS ODD 5289 1.1 is bge.w NEVEN 5290 1.1 is 5291 1.1 is SNODD: 5292 1.1 is #--REGISTERS SAVED SO FAR: D0, A0, FP2. 5293 1.1 is fmovm.x &0x04,-(%sp) # save fp2 5294 1.1 is 5295 1.1 is fmov.x %fp0,RPRIME(%a6) 5296 1.1 is fmul.x %fp0,%fp0 # FP0 IS S = R*R 5297 1.1 is fmov.d SINA7(%pc),%fp1 # A7 5298 1.1 is fmov.d COSB8(%pc),%fp2 # B8 5299 1.1 is fmul.x %fp0,%fp1 # SA7 5300 1.1 is fmul.x %fp0,%fp2 # SB8 5301 1.1 is 5302 1.1 is mov.l %d2,-(%sp) 5303 1.1 is mov.l %d1,%d2 5304 1.1 is ror.l &1,%d2 5305 1.1 is and.l &0x80000000,%d2 5306 1.1 is eor.l %d1,%d2 5307 1.1 is and.l &0x80000000,%d2 5308 1.1 is 5309 1.1 is fadd.d SINA6(%pc),%fp1 # A6+SA7 5310 1.1 is fadd.d COSB7(%pc),%fp2 # B7+SB8 5311 1.1 is 5312 1.1 is fmul.x %fp0,%fp1 # S(A6+SA7) 5313 1.1 is eor.l %d2,RPRIME(%a6) 5314 1.1 is mov.l (%sp)+,%d2 5315 1.1 is fmul.x %fp0,%fp2 # S(B7+SB8) 5316 1.1 is ror.l &1,%d1 5317 1.1 is and.l &0x80000000,%d1 5318 1.1 is mov.l &0x3F800000,POSNEG1(%a6) 5319 1.1 is eor.l %d1,POSNEG1(%a6) 5320 1.1 is 5321 1.1 is fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7) 5322 1.1 is fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8) 5323 1.1 is 5324 1.1 is fmul.x %fp0,%fp1 # S(A5+S(A6+SA7)) 5325 1.1 is fmul.x %fp0,%fp2 # S(B6+S(B7+SB8)) 5326 1.1 is fmov.x %fp0,SPRIME(%a6) 5327 1.1 is 5328 1.1 is fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7)) 5329 1.1 is eor.l %d1,SPRIME(%a6) 5330 1.1 is fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8)) 5331 1.1 is 5332 1.1 is fmul.x %fp0,%fp1 # S(A4+...) 5333 1.1 is fmul.x %fp0,%fp2 # S(B5+...) 5334 1.1 is 5335 1.1 is fadd.d SINA3(%pc),%fp1 # A3+S(A4+...) 5336 1.1 is fadd.d COSB4(%pc),%fp2 # B4+S(B5+...) 5337 1.1 is 5338 1.1 is fmul.x %fp0,%fp1 # S(A3+...) 5339 1.1 is fmul.x %fp0,%fp2 # S(B4+...) 5340 1.1 is 5341 1.1 is fadd.x SINA2(%pc),%fp1 # A2+S(A3+...) 5342 1.1 is fadd.x COSB3(%pc),%fp2 # B3+S(B4+...) 5343 1.1 is 5344 1.1 is fmul.x %fp0,%fp1 # S(A2+...) 5345 1.1 is fmul.x %fp0,%fp2 # S(B3+...) 5346 1.1 is 5347 1.1 is fadd.x SINA1(%pc),%fp1 # A1+S(A2+...) 5348 1.1 is fadd.x COSB2(%pc),%fp2 # B2+S(B3+...) 5349 1.1 is 5350 1.1 is fmul.x %fp0,%fp1 # S(A1+...) 5351 1.1 is fmul.x %fp2,%fp0 # S(B2+...) 5352 1.1 is 5353 1.1 is fmul.x RPRIME(%a6),%fp1 # R'S(A1+...) 5354 1.1 is fadd.s COSB1(%pc),%fp0 # B1+S(B2...) 5355 1.1 is fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...)) 5356 1.1 is 5357 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2 5358 1.1 is 5359 1.1 is fmov.l %d0,%fpcr 5360 1.1 is fadd.x RPRIME(%a6),%fp1 # COS(X) 5361 1.1 is bsr sto_cos # store cosine result 5362 1.1 is fadd.s POSNEG1(%a6),%fp0 # SIN(X) 5363 1.1 is bra t_inx2 5364 1.1 is 5365 1.1 is NEVEN: 5366 1.1 is #--REGISTERS SAVED SO FAR: FP2. 5367 1.1 is fmovm.x &0x04,-(%sp) # save fp2 5368 1.1 is 5369 1.1 is fmov.x %fp0,RPRIME(%a6) 5370 1.1 is fmul.x %fp0,%fp0 # FP0 IS S = R*R 5371 1.1 is 5372 1.1 is fmov.d COSB8(%pc),%fp1 # B8 5373 1.1 is fmov.d SINA7(%pc),%fp2 # A7 5374 1.1 is 5375 1.1 is fmul.x %fp0,%fp1 # SB8 5376 1.1 is fmov.x %fp0,SPRIME(%a6) 5377 1.1 is fmul.x %fp0,%fp2 # SA7 5378 1.1 is 5379 1.1 is ror.l &1,%d1 5380 1.1 is and.l &0x80000000,%d1 5381 1.1 is 5382 1.1 is fadd.d COSB7(%pc),%fp1 # B7+SB8 5383 1.1 is fadd.d SINA6(%pc),%fp2 # A6+SA7 5384 1.1 is 5385 1.1 is eor.l %d1,RPRIME(%a6) 5386 1.1 is eor.l %d1,SPRIME(%a6) 5387 1.1 is 5388 1.1 is fmul.x %fp0,%fp1 # S(B7+SB8) 5389 1.1 is 5390 1.1 is or.l &0x3F800000,%d1 5391 1.1 is mov.l %d1,POSNEG1(%a6) 5392 1.1 is 5393 1.1 is fmul.x %fp0,%fp2 # S(A6+SA7) 5394 1.1 is 5395 1.1 is fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8) 5396 1.1 is fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7) 5397 1.1 is 5398 1.1 is fmul.x %fp0,%fp1 # S(B6+S(B7+SB8)) 5399 1.1 is fmul.x %fp0,%fp2 # S(A5+S(A6+SA7)) 5400 1.1 is 5401 1.1 is fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8)) 5402 1.1 is fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7)) 5403 1.1 is 5404 1.1 is fmul.x %fp0,%fp1 # S(B5+...) 5405 1.1 is fmul.x %fp0,%fp2 # S(A4+...) 5406 1.1 is 5407 1.1 is fadd.d COSB4(%pc),%fp1 # B4+S(B5+...) 5408 1.1 is fadd.d SINA3(%pc),%fp2 # A3+S(A4+...) 5409 1.1 is 5410 1.1 is fmul.x %fp0,%fp1 # S(B4+...) 5411 1.1 is fmul.x %fp0,%fp2 # S(A3+...) 5412 1.1 is 5413 1.1 is fadd.x COSB3(%pc),%fp1 # B3+S(B4+...) 5414 1.1 is fadd.x SINA2(%pc),%fp2 # A2+S(A3+...) 5415 1.1 is 5416 1.1 is fmul.x %fp0,%fp1 # S(B3+...) 5417 1.1 is fmul.x %fp0,%fp2 # S(A2+...) 5418 1.1 is 5419 1.1 is fadd.x COSB2(%pc),%fp1 # B2+S(B3+...) 5420 1.1 is fadd.x SINA1(%pc),%fp2 # A1+S(A2+...) 5421 1.1 is 5422 1.1 is fmul.x %fp0,%fp1 # S(B2+...) 5423 1.1 is fmul.x %fp2,%fp0 # s(a1+...) 5424 1.1 is 5425 1.1 is 5426 1.1 is fadd.s COSB1(%pc),%fp1 # B1+S(B2...) 5427 1.1 is fmul.x RPRIME(%a6),%fp0 # R'S(A1+...) 5428 1.1 is fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...)) 5429 1.1 is 5430 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2 5431 1.1 is 5432 1.1 is fmov.l %d0,%fpcr 5433 1.1 is fadd.s POSNEG1(%a6),%fp1 # COS(X) 5434 1.1 is bsr sto_cos # store cosine result 5435 1.1 is fadd.x RPRIME(%a6),%fp0 # SIN(X) 5436 1.1 is bra t_inx2 5437 1.1 is 5438 1.1 is ################################################ 5439 1.1 is 5440 1.1 is SCBORS: 5441 1.1 is cmp.l %d1,&0x3FFF8000 5442 1.1 is bgt.w SREDUCEX 5443 1.1 is 5444 1.1 is ################################################ 5445 1.1 is 5446 1.1 is SCSM: 5447 1.1 is # mov.w &0x0000,XDCARE(%a6) 5448 1.1 is fmov.s &0x3F800000,%fp1 5449 1.1 is 5450 1.1 is fmov.l %d0,%fpcr 5451 1.1 is fsub.s &0x00800000,%fp1 5452 1.1 is bsr sto_cos # store cosine result 5453 1.1 is fmov.l %fpcr,%d0 # d0 must have fpcr,too 5454 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 5455 1.1 is fmov.x X(%a6),%fp0 5456 1.1 is bra t_catch 5457 1.1 is 5458 1.1 is ############################################## 5459 1.1 is 5460 1.1 is global ssincosd 5461 1.1 is #--SIN AND COS OF X FOR DENORMALIZED X 5462 1.1 is ssincosd: 5463 1.1 is mov.l %d0,-(%sp) # save d0 5464 1.1 is fmov.s &0x3F800000,%fp1 5465 1.1 is bsr sto_cos # store cosine result 5466 1.1 is mov.l (%sp)+,%d0 # restore d0 5467 1.1 is bra t_extdnrm 5468 1.1 is 5469 1.1 is ############################################ 5470 1.1 is 5471 1.1 is #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 5472 1.1 is #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 5473 1.1 is #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 5474 1.1 is SREDUCEX: 5475 1.1 is fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 5476 1.1 is mov.l %d2,-(%sp) # save d2 5477 1.1 is fmov.s &0x00000000,%fp1 # fp1 = 0 5478 1.1 is 5479 1.1 is #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 5480 1.1 is #--there is a danger of unwanted overflow in first LOOP iteration. In this 5481 1.1 is #--case, reduce argument by one remainder step to make subsequent reduction 5482 1.1 is #--safe. 5483 1.1 is cmp.l %d1,&0x7ffeffff # is arg dangerously large? 5484 1.1 is bne.b SLOOP # no 5485 1.1 is 5486 1.1 is # yes; create 2**16383*PI/2 5487 1.1 is mov.w &0x7ffe,FP_SCR0_EX(%a6) 5488 1.1 is mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 5489 1.1 is clr.l FP_SCR0_LO(%a6) 5490 1.1 is 5491 1.1 is # create low half of 2**16383*PI/2 at FP_SCR1 5492 1.1 is mov.w &0x7fdc,FP_SCR1_EX(%a6) 5493 1.1 is mov.l &0x85a308d3,FP_SCR1_HI(%a6) 5494 1.1 is clr.l FP_SCR1_LO(%a6) 5495 1.1 is 5496 1.1 is ftest.x %fp0 # test sign of argument 5497 1.1 is fblt.w sred_neg 5498 1.1 is 5499 1.1 is or.b &0x80,FP_SCR0_EX(%a6) # positive arg 5500 1.1 is or.b &0x80,FP_SCR1_EX(%a6) 5501 1.1 is sred_neg: 5502 1.1 is fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 5503 1.1 is fmov.x %fp0,%fp1 # save high result in fp1 5504 1.1 is fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 5505 1.1 is fsub.x %fp0,%fp1 # determine low component of result 5506 1.1 is fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 5507 1.1 is 5508 1.1 is #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 5509 1.1 is #--integer quotient will be stored in N 5510 1.1 is #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 5511 1.1 is SLOOP: 5512 1.1 is fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 5513 1.1 is mov.w INARG(%a6),%d1 5514 1.1 is mov.l %d1,%a1 # save a copy of D0 5515 1.1 is and.l &0x00007FFF,%d1 5516 1.1 is sub.l &0x00003FFF,%d1 # d0 = K 5517 1.1 is cmp.l %d1,&28 5518 1.1 is ble.b SLASTLOOP 5519 1.1 is SCONTLOOP: 5520 1.1 is sub.l &27,%d1 # d0 = L := K-27 5521 1.1 is mov.b &0,ENDFLAG(%a6) 5522 1.1 is bra.b SWORK 5523 1.1 is SLASTLOOP: 5524 1.1 is clr.l %d1 # d0 = L := 0 5525 1.1 is mov.b &1,ENDFLAG(%a6) 5526 1.1 is 5527 1.1 is SWORK: 5528 1.1 is #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 5529 1.1 is #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 5530 1.1 is 5531 1.1 is #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 5532 1.1 is #--2**L * (PIby2_1), 2**L * (PIby2_2) 5533 1.1 is 5534 1.1 is mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 5535 1.1 is sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 5536 1.1 is 5537 1.1 is mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 5538 1.1 is mov.l &0x4E44152A,FP_SCR0_LO(%a6) 5539 1.1 is mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 5540 1.1 is 5541 1.1 is fmov.x %fp0,%fp2 5542 1.1 is fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 5543 1.1 is 5544 1.1 is #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 5545 1.1 is #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 5546 1.1 is #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 5547 1.1 is #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 5548 1.1 is #--US THE DESIRED VALUE IN FLOATING POINT. 5549 1.1 is mov.l %a1,%d2 5550 1.1 is swap %d2 5551 1.1 is and.l &0x80000000,%d2 5552 1.1 is or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 5553 1.1 is mov.l %d2,TWOTO63(%a6) 5554 1.1 is fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 5555 1.1 is fsub.s TWOTO63(%a6),%fp2 # fp2 = N 5556 1.1 is # fint.x %fp2 5557 1.1 is 5558 1.1 is #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 5559 1.1 is mov.l %d1,%d2 # d2 = L 5560 1.1 is 5561 1.1 is add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 5562 1.1 is mov.w %d2,FP_SCR0_EX(%a6) 5563 1.1 is mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 5564 1.1 is clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 5565 1.1 is 5566 1.1 is add.l &0x00003FDD,%d1 5567 1.1 is mov.w %d1,FP_SCR1_EX(%a6) 5568 1.1 is mov.l &0x85A308D3,FP_SCR1_HI(%a6) 5569 1.1 is clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 5570 1.1 is 5571 1.1 is mov.b ENDFLAG(%a6),%d1 5572 1.1 is 5573 1.1 is #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 5574 1.1 is #--P2 = 2**(L) * Piby2_2 5575 1.1 is fmov.x %fp2,%fp4 # fp4 = N 5576 1.1 is fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 5577 1.1 is fmov.x %fp2,%fp5 # fp5 = N 5578 1.1 is fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 5579 1.1 is fmov.x %fp4,%fp3 # fp3 = W = N*P1 5580 1.1 is 5581 1.1 is #--we want P+p = W+w but |p| <= half ulp of P 5582 1.1 is #--Then, we need to compute A := R-P and a := r-p 5583 1.1 is fadd.x %fp5,%fp3 # fp3 = P 5584 1.1 is fsub.x %fp3,%fp4 # fp4 = W-P 5585 1.1 is 5586 1.1 is fsub.x %fp3,%fp0 # fp0 = A := R - P 5587 1.1 is fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 5588 1.1 is 5589 1.1 is fmov.x %fp0,%fp3 # fp3 = A 5590 1.1 is fsub.x %fp4,%fp1 # fp1 = a := r - p 5591 1.1 is 5592 1.1 is #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 5593 1.1 is #--|r| <= half ulp of R. 5594 1.1 is fadd.x %fp1,%fp0 # fp0 = R := A+a 5595 1.1 is #--No need to calculate r if this is the last loop 5596 1.1 is cmp.b %d1,&0 5597 1.1 is bgt.w SRESTORE 5598 1.1 is 5599 1.1 is #--Need to calculate r 5600 1.1 is fsub.x %fp0,%fp3 # fp3 = A-R 5601 1.1 is fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 5602 1.1 is bra.w SLOOP 5603 1.1 is 5604 1.1 is SRESTORE: 5605 1.1 is fmov.l %fp2,INT(%a6) 5606 1.1 is mov.l (%sp)+,%d2 # restore d2 5607 1.1 is fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 5608 1.1 is 5609 1.1 is mov.l ADJN(%a6),%d1 5610 1.1 is cmp.l %d1,&4 5611 1.1 is 5612 1.1 is blt.w SINCONT 5613 1.1 is bra.w SCCONT 5614 1.1 is 5615 1.1 is ######################################################################### 5616 1.1 is # stan(): computes the tangent of a normalized input # 5617 1.1 is # stand(): computes the tangent of a denormalized input # 5618 1.1 is # # 5619 1.1 is # INPUT *************************************************************** # 5620 1.1 is # a0 = pointer to extended precision input # 5621 1.1 is # d0 = round precision,mode # 5622 1.1 is # # 5623 1.1 is # OUTPUT ************************************************************** # 5624 1.1 is # fp0 = tan(X) # 5625 1.1 is # # 5626 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 5627 1.1 is # The returned result is within 3 ulp in 64 significant bit, i.e. # 5628 1.1 is # within 0.5001 ulp to 53 bits if the result is subsequently # 5629 1.1 is # rounded to double precision. The result is provably monotonic # 5630 1.1 is # in double precision. # 5631 1.1 is # # 5632 1.1 is # ALGORITHM *********************************************************** # 5633 1.1 is # # 5634 1.1 is # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 5635 1.1 is # # 5636 1.1 is # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 5637 1.1 is # k = N mod 2, so in particular, k = 0 or 1. # 5638 1.1 is # # 5639 1.1 is # 3. If k is odd, go to 5. # 5640 1.1 is # # 5641 1.1 is # 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a # 5642 1.1 is # rational function U/V where # 5643 1.1 is # U = r + r*s*(P1 + s*(P2 + s*P3)), and # 5644 1.1 is # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. # 5645 1.1 is # Exit. # 5646 1.1 is # # 5647 1.1 is # 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by # 5648 1.1 is # a rational function U/V where # 5649 1.1 is # U = r + r*s*(P1 + s*(P2 + s*P3)), and # 5650 1.1 is # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, # 5651 1.1 is # -Cot(r) = -V/U. Exit. # 5652 1.1 is # # 5653 1.1 is # 6. If |X| > 1, go to 8. # 5654 1.1 is # # 5655 1.1 is # 7. (|X|<2**(-40)) Tan(X) = X. Exit. # 5656 1.1 is # # 5657 1.1 is # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back # 5658 1.1 is # to 2. # 5659 1.1 is # # 5660 1.1 is ######################################################################### 5661 1.1 is 5662 1.1 is TANQ4: 5663 1.1 is long 0x3EA0B759,0xF50F8688 5664 1.1 is TANP3: 5665 1.1 is long 0xBEF2BAA5,0xA8924F04 5666 1.1 is 5667 1.1 is TANQ3: 5668 1.1 is long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000 5669 1.1 is 5670 1.1 is TANP2: 5671 1.1 is long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000 5672 1.1 is 5673 1.1 is TANQ2: 5674 1.1 is long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000 5675 1.1 is 5676 1.1 is TANP1: 5677 1.1 is long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000 5678 1.1 is 5679 1.1 is TANQ1: 5680 1.1 is long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000 5681 1.1 is 5682 1.1 is INVTWOPI: 5683 1.1 is long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000 5684 1.1 is 5685 1.1 is TWOPI1: 5686 1.1 is long 0x40010000,0xC90FDAA2,0x00000000,0x00000000 5687 1.1 is TWOPI2: 5688 1.1 is long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000 5689 1.1 is 5690 1.1 is #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING 5691 1.1 is #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT 5692 1.1 is #--MOST 69 BITS LONG. 5693 1.1 is # global PITBL 5694 1.1 is PITBL: 5695 1.1 is long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000 5696 1.1 is long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000 5697 1.1 is long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000 5698 1.1 is long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000 5699 1.1 is long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000 5700 1.1 is long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000 5701 1.1 is long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000 5702 1.1 is long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000 5703 1.1 is long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000 5704 1.1 is long 0xC0040000,0x90836524,0x88034B96,0x20B00000 5705 1.1 is long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000 5706 1.1 is long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000 5707 1.1 is long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000 5708 1.1 is long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000 5709 1.1 is long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000 5710 1.1 is long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000 5711 1.1 is long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000 5712 1.1 is long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000 5713 1.1 is long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000 5714 1.1 is long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000 5715 1.1 is long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000 5716 1.1 is long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000 5717 1.1 is long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000 5718 1.1 is long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000 5719 1.1 is long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000 5720 1.1 is long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000 5721 1.1 is long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000 5722 1.1 is long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000 5723 1.1 is long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000 5724 1.1 is long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000 5725 1.1 is long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000 5726 1.1 is long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000 5727 1.1 is long 0x00000000,0x00000000,0x00000000,0x00000000 5728 1.1 is long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000 5729 1.1 is long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000 5730 1.1 is long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000 5731 1.1 is long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000 5732 1.1 is long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000 5733 1.1 is long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000 5734 1.1 is long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000 5735 1.1 is long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000 5736 1.1 is long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000 5737 1.1 is long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000 5738 1.1 is long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000 5739 1.1 is long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000 5740 1.1 is long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000 5741 1.1 is long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000 5742 1.1 is long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000 5743 1.1 is long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000 5744 1.1 is long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000 5745 1.1 is long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000 5746 1.1 is long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000 5747 1.1 is long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000 5748 1.1 is long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000 5749 1.1 is long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000 5750 1.1 is long 0x40040000,0x90836524,0x88034B96,0xA0B00000 5751 1.1 is long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000 5752 1.1 is long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000 5753 1.1 is long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000 5754 1.1 is long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000 5755 1.1 is long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000 5756 1.1 is long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000 5757 1.1 is long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000 5758 1.1 is long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000 5759 1.1 is long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000 5760 1.1 is 5761 1.1 is set INARG,FP_SCR0 5762 1.1 is 5763 1.1 is set TWOTO63,L_SCR1 5764 1.1 is set INT,L_SCR1 5765 1.1 is set ENDFLAG,L_SCR2 5766 1.1 is 5767 1.1 is global stan 5768 1.1 is stan: 5769 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 5770 1.1 is 5771 1.1 is mov.l (%a0),%d1 5772 1.1 is mov.w 4(%a0),%d1 5773 1.1 is and.l &0x7FFFFFFF,%d1 5774 1.1 is 5775 1.1 is cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 5776 1.1 is bge.b TANOK1 5777 1.1 is bra.w TANSM 5778 1.1 is TANOK1: 5779 1.1 is cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 5780 1.1 is blt.b TANMAIN 5781 1.1 is bra.w REDUCEX 5782 1.1 is 5783 1.1 is TANMAIN: 5784 1.1 is #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5785 1.1 is #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 5786 1.1 is fmov.x %fp0,%fp1 5787 1.1 is fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 5788 1.1 is 5789 1.1 is lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 5790 1.1 is 5791 1.1 is fmov.l %fp1,%d1 # CONVERT TO INTEGER 5792 1.1 is 5793 1.1 is asl.l &4,%d1 5794 1.1 is add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2 5795 1.1 is 5796 1.1 is fsub.x (%a1)+,%fp0 # X-Y1 5797 1.1 is 5798 1.1 is fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 5799 1.1 is 5800 1.1 is ror.l &5,%d1 5801 1.1 is and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0 5802 1.1 is 5803 1.1 is TANCONT: 5804 1.1 is fmovm.x &0x0c,-(%sp) # save fp2,fp3 5805 1.1 is 5806 1.1 is cmp.l %d1,&0 5807 1.1 is blt.w NODD 5808 1.1 is 5809 1.1 is fmov.x %fp0,%fp1 5810 1.1 is fmul.x %fp1,%fp1 # S = R*R 5811 1.1 is 5812 1.1 is fmov.d TANQ4(%pc),%fp3 5813 1.1 is fmov.d TANP3(%pc),%fp2 5814 1.1 is 5815 1.1 is fmul.x %fp1,%fp3 # SQ4 5816 1.1 is fmul.x %fp1,%fp2 # SP3 5817 1.1 is 5818 1.1 is fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 5819 1.1 is fadd.x TANP2(%pc),%fp2 # P2+SP3 5820 1.1 is 5821 1.1 is fmul.x %fp1,%fp3 # S(Q3+SQ4) 5822 1.1 is fmul.x %fp1,%fp2 # S(P2+SP3) 5823 1.1 is 5824 1.1 is fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 5825 1.1 is fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 5826 1.1 is 5827 1.1 is fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4)) 5828 1.1 is fmul.x %fp1,%fp2 # S(P1+S(P2+SP3)) 5829 1.1 is 5830 1.1 is fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 5831 1.1 is fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3)) 5832 1.1 is 5833 1.1 is fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4))) 5834 1.1 is 5835 1.1 is fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3)) 5836 1.1 is 5837 1.1 is fadd.s &0x3F800000,%fp1 # 1+S(Q1+...) 5838 1.1 is 5839 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2,fp3 5840 1.1 is 5841 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5842 1.1 is fdiv.x %fp1,%fp0 # last inst - possible exception set 5843 1.1 is bra t_inx2 5844 1.1 is 5845 1.1 is NODD: 5846 1.1 is fmov.x %fp0,%fp1 5847 1.1 is fmul.x %fp0,%fp0 # S = R*R 5848 1.1 is 5849 1.1 is fmov.d TANQ4(%pc),%fp3 5850 1.1 is fmov.d TANP3(%pc),%fp2 5851 1.1 is 5852 1.1 is fmul.x %fp0,%fp3 # SQ4 5853 1.1 is fmul.x %fp0,%fp2 # SP3 5854 1.1 is 5855 1.1 is fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 5856 1.1 is fadd.x TANP2(%pc),%fp2 # P2+SP3 5857 1.1 is 5858 1.1 is fmul.x %fp0,%fp3 # S(Q3+SQ4) 5859 1.1 is fmul.x %fp0,%fp2 # S(P2+SP3) 5860 1.1 is 5861 1.1 is fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 5862 1.1 is fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 5863 1.1 is 5864 1.1 is fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4)) 5865 1.1 is fmul.x %fp0,%fp2 # S(P1+S(P2+SP3)) 5866 1.1 is 5867 1.1 is fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 5868 1.1 is fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3)) 5869 1.1 is 5870 1.1 is fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4))) 5871 1.1 is 5872 1.1 is fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3)) 5873 1.1 is fadd.s &0x3F800000,%fp0 # 1+S(Q1+...) 5874 1.1 is 5875 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2,fp3 5876 1.1 is 5877 1.1 is fmov.x %fp1,-(%sp) 5878 1.1 is eor.l &0x80000000,(%sp) 5879 1.1 is 5880 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5881 1.1 is fdiv.x (%sp)+,%fp0 # last inst - possible exception set 5882 1.1 is bra t_inx2 5883 1.1 is 5884 1.1 is TANBORS: 5885 1.1 is #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 5886 1.1 is #--IF |X| < 2**(-40), RETURN X OR 1. 5887 1.1 is cmp.l %d1,&0x3FFF8000 5888 1.1 is bgt.b REDUCEX 5889 1.1 is 5890 1.1 is TANSM: 5891 1.1 is fmov.x %fp0,-(%sp) 5892 1.1 is fmov.l %d0,%fpcr # restore users round mode,prec 5893 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 5894 1.1 is fmov.x (%sp)+,%fp0 # last inst - posibble exception set 5895 1.1 is bra t_catch 5896 1.1 is 5897 1.1 is global stand 5898 1.1 is #--TAN(X) = X FOR DENORMALIZED X 5899 1.1 is stand: 5900 1.1 is bra t_extdnrm 5901 1.1 is 5902 1.1 is #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 5903 1.1 is #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 5904 1.1 is #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 5905 1.1 is REDUCEX: 5906 1.1 is fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 5907 1.1 is mov.l %d2,-(%sp) # save d2 5908 1.1 is fmov.s &0x00000000,%fp1 # fp1 = 0 5909 1.1 is 5910 1.1 is #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 5911 1.1 is #--there is a danger of unwanted overflow in first LOOP iteration. In this 5912 1.1 is #--case, reduce argument by one remainder step to make subsequent reduction 5913 1.1 is #--safe. 5914 1.1 is cmp.l %d1,&0x7ffeffff # is arg dangerously large? 5915 1.1 is bne.b LOOP # no 5916 1.1 is 5917 1.1 is # yes; create 2**16383*PI/2 5918 1.1 is mov.w &0x7ffe,FP_SCR0_EX(%a6) 5919 1.1 is mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 5920 1.1 is clr.l FP_SCR0_LO(%a6) 5921 1.1 is 5922 1.1 is # create low half of 2**16383*PI/2 at FP_SCR1 5923 1.1 is mov.w &0x7fdc,FP_SCR1_EX(%a6) 5924 1.1 is mov.l &0x85a308d3,FP_SCR1_HI(%a6) 5925 1.1 is clr.l FP_SCR1_LO(%a6) 5926 1.1 is 5927 1.1 is ftest.x %fp0 # test sign of argument 5928 1.1 is fblt.w red_neg 5929 1.1 is 5930 1.1 is or.b &0x80,FP_SCR0_EX(%a6) # positive arg 5931 1.1 is or.b &0x80,FP_SCR1_EX(%a6) 5932 1.1 is red_neg: 5933 1.1 is fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 5934 1.1 is fmov.x %fp0,%fp1 # save high result in fp1 5935 1.1 is fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 5936 1.1 is fsub.x %fp0,%fp1 # determine low component of result 5937 1.1 is fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 5938 1.1 is 5939 1.1 is #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 5940 1.1 is #--integer quotient will be stored in N 5941 1.1 is #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 5942 1.1 is LOOP: 5943 1.1 is fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 5944 1.1 is mov.w INARG(%a6),%d1 5945 1.1 is mov.l %d1,%a1 # save a copy of D0 5946 1.1 is and.l &0x00007FFF,%d1 5947 1.1 is sub.l &0x00003FFF,%d1 # d0 = K 5948 1.1 is cmp.l %d1,&28 5949 1.1 is ble.b LASTLOOP 5950 1.1 is CONTLOOP: 5951 1.1 is sub.l &27,%d1 # d0 = L := K-27 5952 1.1 is mov.b &0,ENDFLAG(%a6) 5953 1.1 is bra.b WORK 5954 1.1 is LASTLOOP: 5955 1.1 is clr.l %d1 # d0 = L := 0 5956 1.1 is mov.b &1,ENDFLAG(%a6) 5957 1.1 is 5958 1.1 is WORK: 5959 1.1 is #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 5960 1.1 is #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 5961 1.1 is 5962 1.1 is #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 5963 1.1 is #--2**L * (PIby2_1), 2**L * (PIby2_2) 5964 1.1 is 5965 1.1 is mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 5966 1.1 is sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 5967 1.1 is 5968 1.1 is mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 5969 1.1 is mov.l &0x4E44152A,FP_SCR0_LO(%a6) 5970 1.1 is mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 5971 1.1 is 5972 1.1 is fmov.x %fp0,%fp2 5973 1.1 is fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 5974 1.1 is 5975 1.1 is #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 5976 1.1 is #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 5977 1.1 is #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 5978 1.1 is #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 5979 1.1 is #--US THE DESIRED VALUE IN FLOATING POINT. 5980 1.1 is mov.l %a1,%d2 5981 1.1 is swap %d2 5982 1.1 is and.l &0x80000000,%d2 5983 1.1 is or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 5984 1.1 is mov.l %d2,TWOTO63(%a6) 5985 1.1 is fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 5986 1.1 is fsub.s TWOTO63(%a6),%fp2 # fp2 = N 5987 1.1 is # fintrz.x %fp2,%fp2 5988 1.1 is 5989 1.1 is #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 5990 1.1 is mov.l %d1,%d2 # d2 = L 5991 1.1 is 5992 1.1 is add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 5993 1.1 is mov.w %d2,FP_SCR0_EX(%a6) 5994 1.1 is mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 5995 1.1 is clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 5996 1.1 is 5997 1.1 is add.l &0x00003FDD,%d1 5998 1.1 is mov.w %d1,FP_SCR1_EX(%a6) 5999 1.1 is mov.l &0x85A308D3,FP_SCR1_HI(%a6) 6000 1.1 is clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 6001 1.1 is 6002 1.1 is mov.b ENDFLAG(%a6),%d1 6003 1.1 is 6004 1.1 is #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 6005 1.1 is #--P2 = 2**(L) * Piby2_2 6006 1.1 is fmov.x %fp2,%fp4 # fp4 = N 6007 1.1 is fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 6008 1.1 is fmov.x %fp2,%fp5 # fp5 = N 6009 1.1 is fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 6010 1.1 is fmov.x %fp4,%fp3 # fp3 = W = N*P1 6011 1.1 is 6012 1.1 is #--we want P+p = W+w but |p| <= half ulp of P 6013 1.1 is #--Then, we need to compute A := R-P and a := r-p 6014 1.1 is fadd.x %fp5,%fp3 # fp3 = P 6015 1.1 is fsub.x %fp3,%fp4 # fp4 = W-P 6016 1.1 is 6017 1.1 is fsub.x %fp3,%fp0 # fp0 = A := R - P 6018 1.1 is fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 6019 1.1 is 6020 1.1 is fmov.x %fp0,%fp3 # fp3 = A 6021 1.1 is fsub.x %fp4,%fp1 # fp1 = a := r - p 6022 1.1 is 6023 1.1 is #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 6024 1.1 is #--|r| <= half ulp of R. 6025 1.1 is fadd.x %fp1,%fp0 # fp0 = R := A+a 6026 1.1 is #--No need to calculate r if this is the last loop 6027 1.1 is cmp.b %d1,&0 6028 1.1 is bgt.w RESTORE 6029 1.1 is 6030 1.1 is #--Need to calculate r 6031 1.1 is fsub.x %fp0,%fp3 # fp3 = A-R 6032 1.1 is fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 6033 1.1 is bra.w LOOP 6034 1.1 is 6035 1.1 is RESTORE: 6036 1.1 is fmov.l %fp2,INT(%a6) 6037 1.1 is mov.l (%sp)+,%d2 # restore d2 6038 1.1 is fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 6039 1.1 is 6040 1.1 is mov.l INT(%a6),%d1 6041 1.1 is ror.l &1,%d1 6042 1.1 is 6043 1.1 is bra.w TANCONT 6044 1.1 is 6045 1.1 is ######################################################################### 6046 1.1 is # satan(): computes the arctangent of a normalized number # 6047 1.1 is # satand(): computes the arctangent of a denormalized number # 6048 1.1 is # # 6049 1.1 is # INPUT *************************************************************** # 6050 1.1 is # a0 = pointer to extended precision input # 6051 1.1 is # d0 = round precision,mode # 6052 1.1 is # # 6053 1.1 is # OUTPUT ************************************************************** # 6054 1.1 is # fp0 = arctan(X) # 6055 1.1 is # # 6056 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 6057 1.1 is # The returned result is within 2 ulps in 64 significant bit, # 6058 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6059 1.1 is # rounded to double precision. The result is provably monotonic # 6060 1.1 is # in double precision. # 6061 1.1 is # # 6062 1.1 is # ALGORITHM *********************************************************** # 6063 1.1 is # Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. # 6064 1.1 is # # 6065 1.1 is # Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. # 6066 1.1 is # Note that k = -4, -3,..., or 3. # 6067 1.1 is # Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 # 6068 1.1 is # significant bits of X with a bit-1 attached at the 6-th # 6069 1.1 is # bit position. Define u to be u = (X-F) / (1 + X*F). # 6070 1.1 is # # 6071 1.1 is # Step 3. Approximate arctan(u) by a polynomial poly. # 6072 1.1 is # # 6073 1.1 is # Step 4. Return arctan(F) + poly, arctan(F) is fetched from a # 6074 1.1 is # table of values calculated beforehand. Exit. # 6075 1.1 is # # 6076 1.1 is # Step 5. If |X| >= 16, go to Step 7. # 6077 1.1 is # # 6078 1.1 is # Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. # 6079 1.1 is # # 6080 1.1 is # Step 7. Define X' = -1/X. Approximate arctan(X') by an odd # 6081 1.1 is # polynomial in X'. # 6082 1.1 is # Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. # 6083 1.1 is # # 6084 1.1 is ######################################################################### 6085 1.1 is 6086 1.1 is ATANA3: long 0xBFF6687E,0x314987D8 6087 1.1 is ATANA2: long 0x4002AC69,0x34A26DB3 6088 1.1 is ATANA1: long 0xBFC2476F,0x4E1DA28E 6089 1.1 is 6090 1.1 is ATANB6: long 0x3FB34444,0x7F876989 6091 1.1 is ATANB5: long 0xBFB744EE,0x7FAF45DB 6092 1.1 is ATANB4: long 0x3FBC71C6,0x46940220 6093 1.1 is ATANB3: long 0xBFC24924,0x921872F9 6094 1.1 is ATANB2: long 0x3FC99999,0x99998FA9 6095 1.1 is ATANB1: long 0xBFD55555,0x55555555 6096 1.1 is 6097 1.1 is ATANC5: long 0xBFB70BF3,0x98539E6A 6098 1.1 is ATANC4: long 0x3FBC7187,0x962D1D7D 6099 1.1 is ATANC3: long 0xBFC24924,0x827107B8 6100 1.1 is ATANC2: long 0x3FC99999,0x9996263E 6101 1.1 is ATANC1: long 0xBFD55555,0x55555536 6102 1.1 is 6103 1.1 is PPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 6104 1.1 is NPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000 6105 1.1 is 6106 1.1 is PTINY: long 0x00010000,0x80000000,0x00000000,0x00000000 6107 1.1 is NTINY: long 0x80010000,0x80000000,0x00000000,0x00000000 6108 1.1 is 6109 1.1 is ATANTBL: 6110 1.1 is long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000 6111 1.1 is long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000 6112 1.1 is long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000 6113 1.1 is long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000 6114 1.1 is long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000 6115 1.1 is long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000 6116 1.1 is long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000 6117 1.1 is long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000 6118 1.1 is long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000 6119 1.1 is long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000 6120 1.1 is long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000 6121 1.1 is long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000 6122 1.1 is long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000 6123 1.1 is long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000 6124 1.1 is long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000 6125 1.1 is long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000 6126 1.1 is long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000 6127 1.1 is long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000 6128 1.1 is long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000 6129 1.1 is long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000 6130 1.1 is long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000 6131 1.1 is long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000 6132 1.1 is long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000 6133 1.1 is long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000 6134 1.1 is long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000 6135 1.1 is long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000 6136 1.1 is long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000 6137 1.1 is long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000 6138 1.1 is long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000 6139 1.1 is long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000 6140 1.1 is long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000 6141 1.1 is long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000 6142 1.1 is long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000 6143 1.1 is long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000 6144 1.1 is long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000 6145 1.1 is long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000 6146 1.1 is long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000 6147 1.1 is long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000 6148 1.1 is long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000 6149 1.1 is long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000 6150 1.1 is long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000 6151 1.1 is long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000 6152 1.1 is long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000 6153 1.1 is long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000 6154 1.1 is long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000 6155 1.1 is long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000 6156 1.1 is long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000 6157 1.1 is long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000 6158 1.1 is long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000 6159 1.1 is long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000 6160 1.1 is long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000 6161 1.1 is long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000 6162 1.1 is long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000 6163 1.1 is long 0x3FFE0000,0x97731420,0x365E538C,0x00000000 6164 1.1 is long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000 6165 1.1 is long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000 6166 1.1 is long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000 6167 1.1 is long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000 6168 1.1 is long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000 6169 1.1 is long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000 6170 1.1 is long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000 6171 1.1 is long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000 6172 1.1 is long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000 6173 1.1 is long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000 6174 1.1 is long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000 6175 1.1 is long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000 6176 1.1 is long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000 6177 1.1 is long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000 6178 1.1 is long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000 6179 1.1 is long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000 6180 1.1 is long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000 6181 1.1 is long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000 6182 1.1 is long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000 6183 1.1 is long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000 6184 1.1 is long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000 6185 1.1 is long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000 6186 1.1 is long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000 6187 1.1 is long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000 6188 1.1 is long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000 6189 1.1 is long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000 6190 1.1 is long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000 6191 1.1 is long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000 6192 1.1 is long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000 6193 1.1 is long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000 6194 1.1 is long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000 6195 1.1 is long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000 6196 1.1 is long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000 6197 1.1 is long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000 6198 1.1 is long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000 6199 1.1 is long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000 6200 1.1 is long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000 6201 1.1 is long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000 6202 1.1 is long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000 6203 1.1 is long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000 6204 1.1 is long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000 6205 1.1 is long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000 6206 1.1 is long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000 6207 1.1 is long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000 6208 1.1 is long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000 6209 1.1 is long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000 6210 1.1 is long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000 6211 1.1 is long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000 6212 1.1 is long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000 6213 1.1 is long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000 6214 1.1 is long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000 6215 1.1 is long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000 6216 1.1 is long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000 6217 1.1 is long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000 6218 1.1 is long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000 6219 1.1 is long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000 6220 1.1 is long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000 6221 1.1 is long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000 6222 1.1 is long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000 6223 1.1 is long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000 6224 1.1 is long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000 6225 1.1 is long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000 6226 1.1 is long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000 6227 1.1 is long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000 6228 1.1 is long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000 6229 1.1 is long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000 6230 1.1 is long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000 6231 1.1 is long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000 6232 1.1 is long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000 6233 1.1 is long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000 6234 1.1 is long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000 6235 1.1 is long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000 6236 1.1 is long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000 6237 1.1 is long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000 6238 1.1 is 6239 1.1 is set X,FP_SCR0 6240 1.1 is set XDCARE,X+2 6241 1.1 is set XFRAC,X+4 6242 1.1 is set XFRACLO,X+8 6243 1.1 is 6244 1.1 is set ATANF,FP_SCR1 6245 1.1 is set ATANFHI,ATANF+4 6246 1.1 is set ATANFLO,ATANF+8 6247 1.1 is 6248 1.1 is global satan 6249 1.1 is #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 6250 1.1 is satan: 6251 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 6252 1.1 is 6253 1.1 is mov.l (%a0),%d1 6254 1.1 is mov.w 4(%a0),%d1 6255 1.1 is fmov.x %fp0,X(%a6) 6256 1.1 is and.l &0x7FFFFFFF,%d1 6257 1.1 is 6258 1.1 is cmp.l %d1,&0x3FFB8000 # |X| >= 1/16? 6259 1.1 is bge.b ATANOK1 6260 1.1 is bra.w ATANSM 6261 1.1 is 6262 1.1 is ATANOK1: 6263 1.1 is cmp.l %d1,&0x4002FFFF # |X| < 16 ? 6264 1.1 is ble.b ATANMAIN 6265 1.1 is bra.w ATANBIG 6266 1.1 is 6267 1.1 is #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE 6268 1.1 is #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ). 6269 1.1 is #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN 6270 1.1 is #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE 6271 1.1 is #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS 6272 1.1 is #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR 6273 1.1 is #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO 6274 1.1 is #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE 6275 1.1 is #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL 6276 1.1 is #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE 6277 1.1 is #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION 6278 1.1 is #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION 6279 1.1 is #--WILL INVOLVE A VERY LONG POLYNOMIAL. 6280 1.1 is 6281 1.1 is #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS 6282 1.1 is #--WE CHOSE F TO BE +-2^K * 1.BBBB1 6283 1.1 is #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE 6284 1.1 is #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE 6285 1.1 is #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS 6286 1.1 is #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|). 6287 1.1 is 6288 1.1 is ATANMAIN: 6289 1.1 is 6290 1.1 is and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS 6291 1.1 is or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1 6292 1.1 is mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F 6293 1.1 is 6294 1.1 is fmov.x %fp0,%fp1 # FP1 IS X 6295 1.1 is fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0 6296 1.1 is fsub.x X(%a6),%fp0 # FP0 IS X-F 6297 1.1 is fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F 6298 1.1 is fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F) 6299 1.1 is 6300 1.1 is #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|) 6301 1.1 is #--CREATE ATAN(F) AND STORE IT IN ATANF, AND 6302 1.1 is #--SAVE REGISTERS FP2. 6303 1.1 is 6304 1.1 is mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY 6305 1.1 is mov.l %d1,%d2 # THE EXP AND 16 BITS OF X 6306 1.1 is and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION 6307 1.1 is and.l &0x7FFF0000,%d2 # EXPONENT OF F 6308 1.1 is sub.l &0x3FFB0000,%d2 # K+4 6309 1.1 is asr.l &1,%d2 6310 1.1 is add.l %d2,%d1 # THE 7 BITS IDENTIFYING F 6311 1.1 is asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|) 6312 1.1 is lea ATANTBL(%pc),%a1 6313 1.1 is add.l %d1,%a1 # ADDRESS OF ATAN(|F|) 6314 1.1 is mov.l (%a1)+,ATANF(%a6) 6315 1.1 is mov.l (%a1)+,ATANFHI(%a6) 6316 1.1 is mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|) 6317 1.1 is mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN 6318 1.1 is and.l &0x80000000,%d1 # SIGN(F) 6319 1.1 is or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|) 6320 1.1 is mov.l (%sp)+,%d2 # RESTORE d2 6321 1.1 is 6322 1.1 is #--THAT'S ALL I HAVE TO DO FOR NOW, 6323 1.1 is #--BUT ALAS, THE DIVIDE IS STILL CRANKING! 6324 1.1 is 6325 1.1 is #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS 6326 1.1 is #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U 6327 1.1 is #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT. 6328 1.1 is #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3)) 6329 1.1 is #--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3. 6330 1.1 is #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT 6331 1.1 is #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED 6332 1.1 is 6333 1.1 is fmovm.x &0x04,-(%sp) # save fp2 6334 1.1 is 6335 1.1 is fmov.x %fp0,%fp1 6336 1.1 is fmul.x %fp1,%fp1 6337 1.1 is fmov.d ATANA3(%pc),%fp2 6338 1.1 is fadd.x %fp1,%fp2 # A3+V 6339 1.1 is fmul.x %fp1,%fp2 # V*(A3+V) 6340 1.1 is fmul.x %fp0,%fp1 # U*V 6341 1.1 is fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V) 6342 1.1 is fmul.d ATANA1(%pc),%fp1 # A1*U*V 6343 1.1 is fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V)) 6344 1.1 is fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED 6345 1.1 is 6346 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2 6347 1.1 is 6348 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec 6349 1.1 is fadd.x ATANF(%a6),%fp0 # ATAN(X) 6350 1.1 is bra t_inx2 6351 1.1 is 6352 1.1 is ATANBORS: 6353 1.1 is #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED. 6354 1.1 is #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16. 6355 1.1 is cmp.l %d1,&0x3FFF8000 6356 1.1 is bgt.w ATANBIG # I.E. |X| >= 16 6357 1.1 is 6358 1.1 is ATANSM: 6359 1.1 is #--|X| <= 1/16 6360 1.1 is #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE 6361 1.1 is #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6))))) 6362 1.1 is #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] ) 6363 1.1 is #--WHERE Y = X*X, AND Z = Y*Y. 6364 1.1 is 6365 1.1 is cmp.l %d1,&0x3FD78000 6366 1.1 is blt.w ATANTINY 6367 1.1 is 6368 1.1 is #--COMPUTE POLYNOMIAL 6369 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3 6370 1.1 is 6371 1.1 is fmul.x %fp0,%fp0 # FPO IS Y = X*X 6372 1.1 is 6373 1.1 is fmov.x %fp0,%fp1 6374 1.1 is fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 6375 1.1 is 6376 1.1 is fmov.d ATANB6(%pc),%fp2 6377 1.1 is fmov.d ATANB5(%pc),%fp3 6378 1.1 is 6379 1.1 is fmul.x %fp1,%fp2 # Z*B6 6380 1.1 is fmul.x %fp1,%fp3 # Z*B5 6381 1.1 is 6382 1.1 is fadd.d ATANB4(%pc),%fp2 # B4+Z*B6 6383 1.1 is fadd.d ATANB3(%pc),%fp3 # B3+Z*B5 6384 1.1 is 6385 1.1 is fmul.x %fp1,%fp2 # Z*(B4+Z*B6) 6386 1.1 is fmul.x %fp3,%fp1 # Z*(B3+Z*B5) 6387 1.1 is 6388 1.1 is fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6) 6389 1.1 is fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5) 6390 1.1 is 6391 1.1 is fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6)) 6392 1.1 is fmul.x X(%a6),%fp0 # X*Y 6393 1.1 is 6394 1.1 is fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))] 6395 1.1 is 6396 1.1 is fmul.x %fp1,%fp0 # X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]) 6397 1.1 is 6398 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3 6399 1.1 is 6400 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec 6401 1.1 is fadd.x X(%a6),%fp0 6402 1.1 is bra t_inx2 6403 1.1 is 6404 1.1 is ATANTINY: 6405 1.1 is #--|X| < 2^(-40), ATAN(X) = X 6406 1.1 is 6407 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec 6408 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 6409 1.1 is fmov.x X(%a6),%fp0 # last inst - possible exception set 6410 1.1 is 6411 1.1 is bra t_catch 6412 1.1 is 6413 1.1 is ATANBIG: 6414 1.1 is #--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE, 6415 1.1 is #--RETURN SIGN(X)*PI/2 + ATAN(-1/X). 6416 1.1 is cmp.l %d1,&0x40638000 6417 1.1 is bgt.w ATANHUGE 6418 1.1 is 6419 1.1 is #--APPROXIMATE ATAN(-1/X) BY 6420 1.1 is #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X' 6421 1.1 is #--THIS CAN BE RE-WRITTEN AS 6422 1.1 is #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y. 6423 1.1 is 6424 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3 6425 1.1 is 6426 1.1 is fmov.s &0xBF800000,%fp1 # LOAD -1 6427 1.1 is fdiv.x %fp0,%fp1 # FP1 IS -1/X 6428 1.1 is 6429 1.1 is #--DIVIDE IS STILL CRANKING 6430 1.1 is 6431 1.1 is fmov.x %fp1,%fp0 # FP0 IS X' 6432 1.1 is fmul.x %fp0,%fp0 # FP0 IS Y = X'*X' 6433 1.1 is fmov.x %fp1,X(%a6) # X IS REALLY X' 6434 1.1 is 6435 1.1 is fmov.x %fp0,%fp1 6436 1.1 is fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 6437 1.1 is 6438 1.1 is fmov.d ATANC5(%pc),%fp3 6439 1.1 is fmov.d ATANC4(%pc),%fp2 6440 1.1 is 6441 1.1 is fmul.x %fp1,%fp3 # Z*C5 6442 1.1 is fmul.x %fp1,%fp2 # Z*B4 6443 1.1 is 6444 1.1 is fadd.d ATANC3(%pc),%fp3 # C3+Z*C5 6445 1.1 is fadd.d ATANC2(%pc),%fp2 # C2+Z*C4 6446 1.1 is 6447 1.1 is fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED 6448 1.1 is fmul.x %fp0,%fp2 # Y*(C2+Z*C4) 6449 1.1 is 6450 1.1 is fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5) 6451 1.1 is fmul.x X(%a6),%fp0 # X'*Y 6452 1.1 is 6453 1.1 is fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)] 6454 1.1 is 6455 1.1 is fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)] 6456 1.1 is # ... +[Y*(B2+Z*(B4+Z*B6))]) 6457 1.1 is fadd.x X(%a6),%fp0 6458 1.1 is 6459 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3 6460 1.1 is 6461 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec 6462 1.1 is tst.b (%a0) 6463 1.1 is bpl.b pos_big 6464 1.1 is 6465 1.1 is neg_big: 6466 1.1 is fadd.x NPIBY2(%pc),%fp0 6467 1.1 is bra t_minx2 6468 1.1 is 6469 1.1 is pos_big: 6470 1.1 is fadd.x PPIBY2(%pc),%fp0 6471 1.1 is bra t_pinx2 6472 1.1 is 6473 1.1 is ATANHUGE: 6474 1.1 is #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY 6475 1.1 is tst.b (%a0) 6476 1.1 is bpl.b pos_huge 6477 1.1 is 6478 1.1 is neg_huge: 6479 1.1 is fmov.x NPIBY2(%pc),%fp0 6480 1.1 is fmov.l %d0,%fpcr 6481 1.1 is fadd.x PTINY(%pc),%fp0 6482 1.1 is bra t_minx2 6483 1.1 is 6484 1.1 is pos_huge: 6485 1.1 is fmov.x PPIBY2(%pc),%fp0 6486 1.1 is fmov.l %d0,%fpcr 6487 1.1 is fadd.x NTINY(%pc),%fp0 6488 1.1 is bra t_pinx2 6489 1.1 is 6490 1.1 is global satand 6491 1.1 is #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT 6492 1.1 is satand: 6493 1.1 is bra t_extdnrm 6494 1.1 is 6495 1.1 is ######################################################################### 6496 1.1 is # sasin(): computes the inverse sine of a normalized input # 6497 1.1 is # sasind(): computes the inverse sine of a denormalized input # 6498 1.1 is # # 6499 1.1 is # INPUT *************************************************************** # 6500 1.1 is # a0 = pointer to extended precision input # 6501 1.1 is # d0 = round precision,mode # 6502 1.1 is # # 6503 1.1 is # OUTPUT ************************************************************** # 6504 1.1 is # fp0 = arcsin(X) # 6505 1.1 is # # 6506 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 6507 1.1 is # The returned result is within 3 ulps in 64 significant bit, # 6508 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6509 1.1 is # rounded to double precision. The result is provably monotonic # 6510 1.1 is # in double precision. # 6511 1.1 is # # 6512 1.1 is # ALGORITHM *********************************************************** # 6513 1.1 is # # 6514 1.1 is # ASIN # 6515 1.1 is # 1. If |X| >= 1, go to 3. # 6516 1.1 is # # 6517 1.1 is # 2. (|X| < 1) Calculate asin(X) by # 6518 1.1 is # z := sqrt( [1-X][1+X] ) # 6519 1.1 is # asin(X) = atan( x / z ). # 6520 1.1 is # Exit. # 6521 1.1 is # # 6522 1.1 is # 3. If |X| > 1, go to 5. # 6523 1.1 is # # 6524 1.1 is # 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.# 6525 1.1 is # # 6526 1.1 is # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 6527 1.1 is # Exit. # 6528 1.1 is # # 6529 1.1 is ######################################################################### 6530 1.1 is 6531 1.1 is global sasin 6532 1.1 is sasin: 6533 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 6534 1.1 is 6535 1.1 is mov.l (%a0),%d1 6536 1.1 is mov.w 4(%a0),%d1 6537 1.1 is and.l &0x7FFFFFFF,%d1 6538 1.1 is cmp.l %d1,&0x3FFF8000 6539 1.1 is bge.b ASINBIG 6540 1.1 is 6541 1.1 is # This catch is added here for the '060 QSP. Originally, the call to 6542 1.1 is # satan() would handle this case by causing the exception which would 6543 1.1 is # not be caught until gen_except(). Now, with the exceptions being 6544 1.1 is # detected inside of satan(), the exception would have been handled there 6545 1.1 is # instead of inside sasin() as expected. 6546 1.1 is cmp.l %d1,&0x3FD78000 6547 1.1 is blt.w ASINTINY 6548 1.1 is 6549 1.1 is #--THIS IS THE USUAL CASE, |X| < 1 6550 1.1 is #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) ) 6551 1.1 is 6552 1.1 is ASINMAIN: 6553 1.1 is fmov.s &0x3F800000,%fp1 6554 1.1 is fsub.x %fp0,%fp1 # 1-X 6555 1.1 is fmovm.x &0x4,-(%sp) # {fp2} 6556 1.1 is fmov.s &0x3F800000,%fp2 6557 1.1 is fadd.x %fp0,%fp2 # 1+X 6558 1.1 is fmul.x %fp2,%fp1 # (1+X)(1-X) 6559 1.1 is fmovm.x (%sp)+,&0x20 # {fp2} 6560 1.1 is fsqrt.x %fp1 # SQRT([1-X][1+X]) 6561 1.1 is fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X]) 6562 1.1 is fmovm.x &0x01,-(%sp) # save X/SQRT(...) 6563 1.1 is lea (%sp),%a0 # pass ptr to X/SQRT(...) 6564 1.1 is bsr satan 6565 1.1 is add.l &0xc,%sp # clear X/SQRT(...) from stack 6566 1.1 is bra t_inx2 6567 1.1 is 6568 1.1 is ASINBIG: 6569 1.1 is fabs.x %fp0 # |X| 6570 1.1 is fcmp.s %fp0,&0x3F800000 6571 1.1 is fbgt t_operr # cause an operr exception 6572 1.1 is 6573 1.1 is #--|X| = 1, ASIN(X) = +- PI/2. 6574 1.1 is ASINONE: 6575 1.1 is fmov.x PIBY2(%pc),%fp0 6576 1.1 is mov.l (%a0),%d1 6577 1.1 is and.l &0x80000000,%d1 # SIGN BIT OF X 6578 1.1 is or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT 6579 1.1 is mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT 6580 1.1 is fmov.l %d0,%fpcr 6581 1.1 is fmul.s (%sp)+,%fp0 6582 1.1 is bra t_inx2 6583 1.1 is 6584 1.1 is #--|X| < 2^(-40), ATAN(X) = X 6585 1.1 is ASINTINY: 6586 1.1 is fmov.l %d0,%fpcr # restore users rnd mode,prec 6587 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 6588 1.1 is fmov.x (%a0),%fp0 # last inst - possible exception 6589 1.1 is bra t_catch 6590 1.1 is 6591 1.1 is global sasind 6592 1.1 is #--ASIN(X) = X FOR DENORMALIZED X 6593 1.1 is sasind: 6594 1.1 is bra t_extdnrm 6595 1.1 is 6596 1.1 is ######################################################################### 6597 1.1 is # sacos(): computes the inverse cosine of a normalized input # 6598 1.1 is # sacosd(): computes the inverse cosine of a denormalized input # 6599 1.1 is # # 6600 1.1 is # INPUT *************************************************************** # 6601 1.1 is # a0 = pointer to extended precision input # 6602 1.1 is # d0 = round precision,mode # 6603 1.1 is # # 6604 1.1 is # OUTPUT ************************************************************** # 6605 1.1 is # fp0 = arccos(X) # 6606 1.1 is # # 6607 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 6608 1.1 is # The returned result is within 3 ulps in 64 significant bit, # 6609 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6610 1.1 is # rounded to double precision. The result is provably monotonic # 6611 1.1 is # in double precision. # 6612 1.1 is # # 6613 1.1 is # ALGORITHM *********************************************************** # 6614 1.1 is # # 6615 1.1 is # ACOS # 6616 1.1 is # 1. If |X| >= 1, go to 3. # 6617 1.1 is # # 6618 1.1 is # 2. (|X| < 1) Calculate acos(X) by # 6619 1.1 is # z := (1-X) / (1+X) # 6620 1.1 is # acos(X) = 2 * atan( sqrt(z) ). # 6621 1.1 is # Exit. # 6622 1.1 is # # 6623 1.1 is # 3. If |X| > 1, go to 5. # 6624 1.1 is # # 6625 1.1 is # 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. # 6626 1.1 is # # 6627 1.1 is # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 6628 1.1 is # Exit. # 6629 1.1 is # # 6630 1.1 is ######################################################################### 6631 1.1 is 6632 1.1 is global sacos 6633 1.1 is sacos: 6634 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 6635 1.1 is 6636 1.1 is mov.l (%a0),%d1 # pack exp w/ upper 16 fraction 6637 1.1 is mov.w 4(%a0),%d1 6638 1.1 is and.l &0x7FFFFFFF,%d1 6639 1.1 is cmp.l %d1,&0x3FFF8000 6640 1.1 is bge.b ACOSBIG 6641 1.1 is 6642 1.1 is #--THIS IS THE USUAL CASE, |X| < 1 6643 1.1 is #--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) ) 6644 1.1 is 6645 1.1 is ACOSMAIN: 6646 1.1 is fmov.s &0x3F800000,%fp1 6647 1.1 is fadd.x %fp0,%fp1 # 1+X 6648 1.1 is fneg.x %fp0 # -X 6649 1.1 is fadd.s &0x3F800000,%fp0 # 1-X 6650 1.1 is fdiv.x %fp1,%fp0 # (1-X)/(1+X) 6651 1.1 is fsqrt.x %fp0 # SQRT((1-X)/(1+X)) 6652 1.1 is mov.l %d0,-(%sp) # save original users fpcr 6653 1.1 is clr.l %d0 6654 1.1 is fmovm.x &0x01,-(%sp) # save SQRT(...) to stack 6655 1.1 is lea (%sp),%a0 # pass ptr to sqrt 6656 1.1 is bsr satan # ATAN(SQRT([1-X]/[1+X])) 6657 1.1 is add.l &0xc,%sp # clear SQRT(...) from stack 6658 1.1 is 6659 1.1 is fmov.l (%sp)+,%fpcr # restore users round prec,mode 6660 1.1 is fadd.x %fp0,%fp0 # 2 * ATAN( STUFF ) 6661 1.1 is bra t_pinx2 6662 1.1 is 6663 1.1 is ACOSBIG: 6664 1.1 is fabs.x %fp0 6665 1.1 is fcmp.s %fp0,&0x3F800000 6666 1.1 is fbgt t_operr # cause an operr exception 6667 1.1 is 6668 1.1 is #--|X| = 1, ACOS(X) = 0 OR PI 6669 1.1 is tst.b (%a0) # is X positive or negative? 6670 1.1 is bpl.b ACOSP1 6671 1.1 is 6672 1.1 is #--X = -1 6673 1.1 is #Returns PI and inexact exception 6674 1.1 is ACOSM1: 6675 1.1 is fmov.x PI(%pc),%fp0 # load PI 6676 1.1 is fmov.l %d0,%fpcr # load round mode,prec 6677 1.1 is fadd.s &0x00800000,%fp0 # add a small value 6678 1.1 is bra t_pinx2 6679 1.1 is 6680 1.1 is ACOSP1: 6681 1.1 is bra ld_pzero # answer is positive zero 6682 1.1 is 6683 1.1 is global sacosd 6684 1.1 is #--ACOS(X) = PI/2 FOR DENORMALIZED X 6685 1.1 is sacosd: 6686 1.1 is fmov.l %d0,%fpcr # load user's rnd mode/prec 6687 1.1 is fmov.x PIBY2(%pc),%fp0 6688 1.1 is bra t_pinx2 6689 1.1 is 6690 1.1 is ######################################################################### 6691 1.1 is # setox(): computes the exponential for a normalized input # 6692 1.1 is # setoxd(): computes the exponential for a denormalized input # 6693 1.1 is # setoxm1(): computes the exponential minus 1 for a normalized input # 6694 1.1 is # setoxm1d(): computes the exponential minus 1 for a denormalized input # 6695 1.1 is # # 6696 1.1 is # INPUT *************************************************************** # 6697 1.1 is # a0 = pointer to extended precision input # 6698 1.1 is # d0 = round precision,mode # 6699 1.1 is # # 6700 1.1 is # OUTPUT ************************************************************** # 6701 1.1 is # fp0 = exp(X) or exp(X)-1 # 6702 1.1 is # # 6703 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 6704 1.1 is # The returned result is within 0.85 ulps in 64 significant bit, # 6705 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6706 1.1 is # rounded to double precision. The result is provably monotonic # 6707 1.1 is # in double precision. # 6708 1.1 is # # 6709 1.1 is # ALGORITHM and IMPLEMENTATION **************************************** # 6710 1.1 is # # 6711 1.1 is # setoxd # 6712 1.1 is # ------ # 6713 1.1 is # Step 1. Set ans := 1.0 # 6714 1.1 is # # 6715 1.1 is # Step 2. Return ans := ans + sign(X)*2^(-126). Exit. # 6716 1.1 is # Notes: This will always generate one exception -- inexact. # 6717 1.1 is # # 6718 1.1 is # # 6719 1.1 is # setox # 6720 1.1 is # ----- # 6721 1.1 is # # 6722 1.1 is # Step 1. Filter out extreme cases of input argument. # 6723 1.1 is # 1.1 If |X| >= 2^(-65), go to Step 1.3. # 6724 1.1 is # 1.2 Go to Step 7. # 6725 1.1 is # 1.3 If |X| < 16380 log(2), go to Step 2. # 6726 1.1 is # 1.4 Go to Step 8. # 6727 1.1 is # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 6728 1.1 is # To avoid the use of floating-point comparisons, a # 6729 1.1 is # compact representation of |X| is used. This format is a # 6730 1.1 is # 32-bit integer, the upper (more significant) 16 bits # 6731 1.1 is # are the sign and biased exponent field of |X|; the # 6732 1.1 is # lower 16 bits are the 16 most significant fraction # 6733 1.1 is # (including the explicit bit) bits of |X|. Consequently, # 6734 1.1 is # the comparisons in Steps 1.1 and 1.3 can be performed # 6735 1.1 is # by integer comparison. Note also that the constant # 6736 1.1 is # 16380 log(2) used in Step 1.3 is also in the compact # 6737 1.1 is # form. Thus taking the branch to Step 2 guarantees # 6738 1.1 is # |X| < 16380 log(2). There is no harm to have a small # 6739 1.1 is # number of cases where |X| is less than, but close to, # 6740 1.1 is # 16380 log(2) and the branch to Step 9 is taken. # 6741 1.1 is # # 6742 1.1 is # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 6743 1.1 is # 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 # 6744 1.1 is # was taken) # 6745 1.1 is # 2.2 N := round-to-nearest-integer( X * 64/log2 ). # 6746 1.1 is # 2.3 Calculate J = N mod 64; so J = 0,1,2,..., # 6747 1.1 is # or 63. # 6748 1.1 is # 2.4 Calculate M = (N - J)/64; so N = 64M + J. # 6749 1.1 is # 2.5 Calculate the address of the stored value of # 6750 1.1 is # 2^(J/64). # 6751 1.1 is # 2.6 Create the value Scale = 2^M. # 6752 1.1 is # Notes: The calculation in 2.2 is really performed by # 6753 1.1 is # Z := X * constant # 6754 1.1 is # N := round-to-nearest-integer(Z) # 6755 1.1 is # where # 6756 1.1 is # constant := single-precision( 64/log 2 ). # 6757 1.1 is # # 6758 1.1 is # Using a single-precision constant avoids memory # 6759 1.1 is # access. Another effect of using a single-precision # 6760 1.1 is # "constant" is that the calculated value Z is # 6761 1.1 is # # 6762 1.1 is # Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). # 6763 1.1 is # # 6764 1.1 is # This error has to be considered later in Steps 3 and 4. # 6765 1.1 is # # 6766 1.1 is # Step 3. Calculate X - N*log2/64. # 6767 1.1 is # 3.1 R := X + N*L1, # 6768 1.1 is # where L1 := single-precision(-log2/64). # 6769 1.1 is # 3.2 R := R + N*L2, # 6770 1.1 is # L2 := extended-precision(-log2/64 - L1).# 6771 1.1 is # Notes: a) The way L1 and L2 are chosen ensures L1+L2 # 6772 1.1 is # approximate the value -log2/64 to 88 bits of accuracy. # 6773 1.1 is # b) N*L1 is exact because N is no longer than 22 bits # 6774 1.1 is # and L1 is no longer than 24 bits. # 6775 1.1 is # c) The calculation X+N*L1 is also exact due to # 6776 1.1 is # cancellation. Thus, R is practically X+N(L1+L2) to full # 6777 1.1 is # 64 bits. # 6778 1.1 is # d) It is important to estimate how large can |R| be # 6779 1.1 is # after Step 3.2. # 6780 1.1 is # # 6781 1.1 is # N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) # 6782 1.1 is # X*64/log2 (1+eps) = N + f, |f| <= 0.5 # 6783 1.1 is # X*64/log2 - N = f - eps*X 64/log2 # 6784 1.1 is # X - N*log2/64 = f*log2/64 - eps*X # 6785 1.1 is # # 6786 1.1 is # # 6787 1.1 is # Now |X| <= 16446 log2, thus # 6788 1.1 is # # 6789 1.1 is # |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 # 6790 1.1 is # <= 0.57 log2/64. # 6791 1.1 is # This bound will be used in Step 4. # 6792 1.1 is # # 6793 1.1 is # Step 4. Approximate exp(R)-1 by a polynomial # 6794 1.1 is # p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) # 6795 1.1 is # Notes: a) In order to reduce memory access, the coefficients # 6796 1.1 is # are made as "short" as possible: A1 (which is 1/2), A4 # 6797 1.1 is # and A5 are single precision; A2 and A3 are double # 6798 1.1 is # precision. # 6799 1.1 is # b) Even with the restrictions above, # 6800 1.1 is # |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. # 6801 1.1 is # Note that 0.0062 is slightly bigger than 0.57 log2/64. # 6802 1.2 perry # c) To fully use the pipeline, p is separated into # 6803 1.1 is # two independent pieces of roughly equal complexities # 6804 1.1 is # p = [ R + R*S*(A2 + S*A4) ] + # 6805 1.1 is # [ S*(A1 + S*(A3 + S*A5)) ] # 6806 1.1 is # where S = R*R. # 6807 1.1 is # # 6808 1.1 is # Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by # 6809 1.1 is # ans := T + ( T*p + t) # 6810 1.1 is # where T and t are the stored values for 2^(J/64). # 6811 1.1 is # Notes: 2^(J/64) is stored as T and t where T+t approximates # 6812 1.1 is # 2^(J/64) to roughly 85 bits; T is in extended precision # 6813 1.1 is # and t is in single precision. Note also that T is # 6814 1.1 is # rounded to 62 bits so that the last two bits of T are # 6815 1.1 is # zero. The reason for such a special form is that T-1, # 6816 1.1 is # T-2, and T-8 will all be exact --- a property that will # 6817 1.1 is # give much more accurate computation of the function # 6818 1.1 is # EXPM1. # 6819 1.1 is # # 6820 1.1 is # Step 6. Reconstruction of exp(X) # 6821 1.1 is # exp(X) = 2^M * 2^(J/64) * exp(R). # 6822 1.1 is # 6.1 If AdjFlag = 0, go to 6.3 # 6823 1.1 is # 6.2 ans := ans * AdjScale # 6824 1.1 is # 6.3 Restore the user FPCR # 6825 1.1 is # 6.4 Return ans := ans * Scale. Exit. # 6826 1.1 is # Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, # 6827 1.1 is # |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will # 6828 1.1 is # neither overflow nor underflow. If AdjFlag = 1, that # 6829 1.1 is # means that # 6830 1.1 is # X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. # 6831 1.1 is # Hence, exp(X) may overflow or underflow or neither. # 6832 1.1 is # When that is the case, AdjScale = 2^(M1) where M1 is # 6833 1.1 is # approximately M. Thus 6.2 will never cause # 6834 1.1 is # over/underflow. Possible exception in 6.4 is overflow # 6835 1.1 is # or underflow. The inexact exception is not generated in # 6836 1.1 is # 6.4. Although one can argue that the inexact flag # 6837 1.1 is # should always be raised, to simulate that exception # 6838 1.1 is # cost to much than the flag is worth in practical uses. # 6839 1.1 is # # 6840 1.1 is # Step 7. Return 1 + X. # 6841 1.1 is # 7.1 ans := X # 6842 1.1 is # 7.2 Restore user FPCR. # 6843 1.1 is # 7.3 Return ans := 1 + ans. Exit # 6844 1.1 is # Notes: For non-zero X, the inexact exception will always be # 6845 1.1 is # raised by 7.3. That is the only exception raised by 7.3.# 6846 1.1 is # Note also that we use the FMOVEM instruction to move X # 6847 1.1 is # in Step 7.1 to avoid unnecessary trapping. (Although # 6848 1.1 is # the FMOVEM may not seem relevant since X is normalized, # 6849 1.1 is # the precaution will be useful in the library version of # 6850 1.1 is # this code where the separate entry for denormalized # 6851 1.1 is # inputs will be done away with.) # 6852 1.1 is # # 6853 1.1 is # Step 8. Handle exp(X) where |X| >= 16380log2. # 6854 1.1 is # 8.1 If |X| > 16480 log2, go to Step 9. # 6855 1.1 is # (mimic 2.2 - 2.6) # 6856 1.1 is # 8.2 N := round-to-integer( X * 64/log2 ) # 6857 1.1 is # 8.3 Calculate J = N mod 64, J = 0,1,...,63 # 6858 1.1 is # 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, # 6859 1.1 is # AdjFlag := 1. # 6860 1.1 is # 8.5 Calculate the address of the stored value # 6861 1.1 is # 2^(J/64). # 6862 1.1 is # 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. # 6863 1.1 is # 8.7 Go to Step 3. # 6864 1.1 is # Notes: Refer to notes for 2.2 - 2.6. # 6865 1.1 is # # 6866 1.1 is # Step 9. Handle exp(X), |X| > 16480 log2. # 6867 1.1 is # 9.1 If X < 0, go to 9.3 # 6868 1.1 is # 9.2 ans := Huge, go to 9.4 # 6869 1.1 is # 9.3 ans := Tiny. # 6870 1.1 is # 9.4 Restore user FPCR. # 6871 1.1 is # 9.5 Return ans := ans * ans. Exit. # 6872 1.1 is # Notes: Exp(X) will surely overflow or underflow, depending on # 6873 1.1 is # X's sign. "Huge" and "Tiny" are respectively large/tiny # 6874 1.1 is # extended-precision numbers whose square over/underflow # 6875 1.1 is # with an inexact result. Thus, 9.5 always raises the # 6876 1.1 is # inexact together with either overflow or underflow. # 6877 1.1 is # # 6878 1.1 is # setoxm1d # 6879 1.1 is # -------- # 6880 1.1 is # # 6881 1.1 is # Step 1. Set ans := 0 # 6882 1.1 is # # 6883 1.1 is # Step 2. Return ans := X + ans. Exit. # 6884 1.1 is # Notes: This will return X with the appropriate rounding # 6885 1.1 is # precision prescribed by the user FPCR. # 6886 1.1 is # # 6887 1.1 is # setoxm1 # 6888 1.1 is # ------- # 6889 1.1 is # # 6890 1.1 is # Step 1. Check |X| # 6891 1.1 is # 1.1 If |X| >= 1/4, go to Step 1.3. # 6892 1.1 is # 1.2 Go to Step 7. # 6893 1.1 is # 1.3 If |X| < 70 log(2), go to Step 2. # 6894 1.1 is # 1.4 Go to Step 10. # 6895 1.1 is # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 6896 1.1 is # However, it is conceivable |X| can be small very often # 6897 1.1 is # because EXPM1 is intended to evaluate exp(X)-1 # 6898 1.1 is # accurately when |X| is small. For further details on # 6899 1.1 is # the comparisons, see the notes on Step 1 of setox. # 6900 1.1 is # # 6901 1.1 is # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 6902 1.1 is # 2.1 N := round-to-nearest-integer( X * 64/log2 ). # 6903 1.1 is # 2.2 Calculate J = N mod 64; so J = 0,1,2,..., # 6904 1.1 is # or 63. # 6905 1.1 is # 2.3 Calculate M = (N - J)/64; so N = 64M + J. # 6906 1.1 is # 2.4 Calculate the address of the stored value of # 6907 1.1 is # 2^(J/64). # 6908 1.1 is # 2.5 Create the values Sc = 2^M and # 6909 1.1 is # OnebySc := -2^(-M). # 6910 1.1 is # Notes: See the notes on Step 2 of setox. # 6911 1.1 is # # 6912 1.1 is # Step 3. Calculate X - N*log2/64. # 6913 1.1 is # 3.1 R := X + N*L1, # 6914 1.1 is # where L1 := single-precision(-log2/64). # 6915 1.1 is # 3.2 R := R + N*L2, # 6916 1.1 is # L2 := extended-precision(-log2/64 - L1).# 6917 1.1 is # Notes: Applying the analysis of Step 3 of setox in this case # 6918 1.1 is # shows that |R| <= 0.0055 (note that |X| <= 70 log2 in # 6919 1.1 is # this case). # 6920 1.1 is # # 6921 1.1 is # Step 4. Approximate exp(R)-1 by a polynomial # 6922 1.1 is # p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) # 6923 1.1 is # Notes: a) In order to reduce memory access, the coefficients # 6924 1.1 is # are made as "short" as possible: A1 (which is 1/2), A5 # 6925 1.1 is # and A6 are single precision; A2, A3 and A4 are double # 6926 1.1 is # precision. # 6927 1.1 is # b) Even with the restriction above, # 6928 1.1 is # |p - (exp(R)-1)| < |R| * 2^(-72.7) # 6929 1.1 is # for all |R| <= 0.0055. # 6930 1.2 perry # c) To fully use the pipeline, p is separated into # 6931 1.1 is # two independent pieces of roughly equal complexity # 6932 1.1 is # p = [ R*S*(A2 + S*(A4 + S*A6)) ] + # 6933 1.1 is # [ R + S*(A1 + S*(A3 + S*A5)) ] # 6934 1.1 is # where S = R*R. # 6935 1.1 is # # 6936 1.1 is # Step 5. Compute 2^(J/64)*p by # 6937 1.1 is # p := T*p # 6938 1.1 is # where T and t are the stored values for 2^(J/64). # 6939 1.1 is # Notes: 2^(J/64) is stored as T and t where T+t approximates # 6940 1.1 is # 2^(J/64) to roughly 85 bits; T is in extended precision # 6941 1.1 is # and t is in single precision. Note also that T is # 6942 1.1 is # rounded to 62 bits so that the last two bits of T are # 6943 1.1 is # zero. The reason for such a special form is that T-1, # 6944 1.1 is # T-2, and T-8 will all be exact --- a property that will # 6945 1.1 is # be exploited in Step 6 below. The total relative error # 6946 1.1 is # in p is no bigger than 2^(-67.7) compared to the final # 6947 1.1 is # result. # 6948 1.1 is # # 6949 1.1 is # Step 6. Reconstruction of exp(X)-1 # 6950 1.1 is # exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). # 6951 1.1 is # 6.1 If M <= 63, go to Step 6.3. # 6952 1.1 is # 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 # 6953 1.1 is # 6.3 If M >= -3, go to 6.5. # 6954 1.1 is # 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 # 6955 1.1 is # 6.5 ans := (T + OnebySc) + (p + t). # 6956 1.1 is # 6.6 Restore user FPCR. # 6957 1.1 is # 6.7 Return ans := Sc * ans. Exit. # 6958 1.1 is # Notes: The various arrangements of the expressions give # 6959 1.1 is # accurate evaluations. # 6960 1.1 is # # 6961 1.1 is # Step 7. exp(X)-1 for |X| < 1/4. # 6962 1.1 is # 7.1 If |X| >= 2^(-65), go to Step 9. # 6963 1.1 is # 7.2 Go to Step 8. # 6964 1.1 is # # 6965 1.1 is # Step 8. Calculate exp(X)-1, |X| < 2^(-65). # 6966 1.1 is # 8.1 If |X| < 2^(-16312), goto 8.3 # 6967 1.1 is # 8.2 Restore FPCR; return ans := X - 2^(-16382). # 6968 1.1 is # Exit. # 6969 1.1 is # 8.3 X := X * 2^(140). # 6970 1.1 is # 8.4 Restore FPCR; ans := ans - 2^(-16382). # 6971 1.1 is # Return ans := ans*2^(140). Exit # 6972 1.1 is # Notes: The idea is to return "X - tiny" under the user # 6973 1.1 is # precision and rounding modes. To avoid unnecessary # 6974 1.1 is # inefficiency, we stay away from denormalized numbers # 6975 1.1 is # the best we can. For |X| >= 2^(-16312), the # 6976 1.1 is # straightforward 8.2 generates the inexact exception as # 6977 1.1 is # the case warrants. # 6978 1.1 is # # 6979 1.1 is # Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial # 6980 1.1 is # p = X + X*X*(B1 + X*(B2 + ... + X*B12)) # 6981 1.1 is # Notes: a) In order to reduce memory access, the coefficients # 6982 1.1 is # are made as "short" as possible: B1 (which is 1/2), B9 # 6983 1.1 is # to B12 are single precision; B3 to B8 are double # 6984 1.1 is # precision; and B2 is double extended. # 6985 1.1 is # b) Even with the restriction above, # 6986 1.1 is # |p - (exp(X)-1)| < |X| 2^(-70.6) # 6987 1.1 is # for all |X| <= 0.251. # 6988 1.1 is # Note that 0.251 is slightly bigger than 1/4. # 6989 1.1 is # c) To fully preserve accuracy, the polynomial is # 6990 1.1 is # computed as # 6991 1.1 is # X + ( S*B1 + Q ) where S = X*X and # 6992 1.1 is # Q = X*S*(B2 + X*(B3 + ... + X*B12)) # 6993 1.2 perry # d) To fully use the pipeline, Q is separated into # 6994 1.1 is # two independent pieces of roughly equal complexity # 6995 1.1 is # Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + # 6996 1.1 is # [ S*S*(B3 + S*(B5 + ... + S*B11)) ] # 6997 1.1 is # # 6998 1.1 is # Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. # 6999 1.1 is # 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all # 7000 1.1 is # practical purposes. Therefore, go to Step 1 of setox. # 7001 1.1 is # 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical # 7002 1.1 is # purposes. # 7003 1.1 is # ans := -1 # 7004 1.1 is # Restore user FPCR # 7005 1.1 is # Return ans := ans + 2^(-126). Exit. # 7006 1.1 is # Notes: 10.2 will always create an inexact and return -1 + tiny # 7007 1.1 is # in the user rounding precision and mode. # 7008 1.1 is # # 7009 1.1 is ######################################################################### 7010 1.1 is 7011 1.1 is L2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000 7012 1.1 is 7013 1.1 is EEXPA3: long 0x3FA55555,0x55554CC1 7014 1.1 is EEXPA2: long 0x3FC55555,0x55554A54 7015 1.1 is 7016 1.1 is EM1A4: long 0x3F811111,0x11174385 7017 1.1 is EM1A3: long 0x3FA55555,0x55554F5A 7018 1.1 is 7019 1.1 is EM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000 7020 1.1 is 7021 1.1 is EM1B8: long 0x3EC71DE3,0xA5774682 7022 1.1 is EM1B7: long 0x3EFA01A0,0x19D7CB68 7023 1.1 is 7024 1.1 is EM1B6: long 0x3F2A01A0,0x1A019DF3 7025 1.1 is EM1B5: long 0x3F56C16C,0x16C170E2 7026 1.1 is 7027 1.1 is EM1B4: long 0x3F811111,0x11111111 7028 1.1 is EM1B3: long 0x3FA55555,0x55555555 7029 1.1 is 7030 1.1 is EM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB 7031 1.1 is long 0x00000000 7032 1.1 is 7033 1.1 is TWO140: long 0x48B00000,0x00000000 7034 1.1 is TWON140: 7035 1.1 is long 0x37300000,0x00000000 7036 1.1 is 7037 1.1 is EEXPTBL: 7038 1.1 is long 0x3FFF0000,0x80000000,0x00000000,0x00000000 7039 1.1 is long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B 7040 1.1 is long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9 7041 1.1 is long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369 7042 1.1 is long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C 7043 1.1 is long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F 7044 1.1 is long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729 7045 1.1 is long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF 7046 1.1 is long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF 7047 1.1 is long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA 7048 1.1 is long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051 7049 1.1 is long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029 7050 1.1 is long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494 7051 1.1 is long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0 7052 1.1 is long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D 7053 1.1 is long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537 7054 1.1 is long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD 7055 1.1 is long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087 7056 1.1 is long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818 7057 1.1 is long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D 7058 1.1 is long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890 7059 1.1 is long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C 7060 1.1 is long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05 7061 1.1 is long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126 7062 1.1 is long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140 7063 1.1 is long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA 7064 1.1 is long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A 7065 1.1 is long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC 7066 1.1 is long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC 7067 1.1 is long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610 7068 1.1 is long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90 7069 1.1 is long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A 7070 1.1 is long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13 7071 1.1 is long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30 7072 1.1 is long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC 7073 1.1 is long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6 7074 1.1 is long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70 7075 1.1 is long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518 7076 1.1 is long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41 7077 1.1 is long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B 7078 1.1 is long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568 7079 1.1 is long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E 7080 1.1 is long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03 7081 1.1 is long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D 7082 1.1 is long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4 7083 1.1 is long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C 7084 1.1 is long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9 7085 1.1 is long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21 7086 1.1 is long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F 7087 1.1 is long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F 7088 1.1 is long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207 7089 1.1 is long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175 7090 1.1 is long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B 7091 1.1 is long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5 7092 1.1 is long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A 7093 1.1 is long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22 7094 1.1 is long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945 7095 1.1 is long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B 7096 1.1 is long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3 7097 1.1 is long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05 7098 1.1 is long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19 7099 1.1 is long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5 7100 1.1 is long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22 7101 1.1 is long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A 7102 1.1 is 7103 1.1 is set ADJFLAG,L_SCR2 7104 1.1 is set SCALE,FP_SCR0 7105 1.1 is set ADJSCALE,FP_SCR1 7106 1.1 is set SC,FP_SCR0 7107 1.1 is set ONEBYSC,FP_SCR1 7108 1.1 is 7109 1.1 is global setox 7110 1.1 is setox: 7111 1.1 is #--entry point for EXP(X), here X is finite, non-zero, and not NaN's 7112 1.1 is 7113 1.1 is #--Step 1. 7114 1.1 is mov.l (%a0),%d1 # load part of input X 7115 1.1 is and.l &0x7FFF0000,%d1 # biased expo. of X 7116 1.1 is cmp.l %d1,&0x3FBE0000 # 2^(-65) 7117 1.1 is bge.b EXPC1 # normal case 7118 1.1 is bra EXPSM 7119 1.1 is 7120 1.1 is EXPC1: 7121 1.1 is #--The case |X| >= 2^(-65) 7122 1.1 is mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 7123 1.1 is cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits 7124 1.1 is blt.b EXPMAIN # normal case 7125 1.1 is bra EEXPBIG 7126 1.1 is 7127 1.1 is EXPMAIN: 7128 1.1 is #--Step 2. 7129 1.1 is #--This is the normal branch: 2^(-65) <= |X| < 16380 log2. 7130 1.1 is fmov.x (%a0),%fp0 # load input from (a0) 7131 1.1 is 7132 1.1 is fmov.x %fp0,%fp1 7133 1.1 is fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 7134 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7135 1.1 is mov.l &0,ADJFLAG(%a6) 7136 1.1 is fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 7137 1.1 is lea EEXPTBL(%pc),%a1 7138 1.1 is fmov.l %d1,%fp0 # convert to floating-format 7139 1.1 is 7140 1.1 is mov.l %d1,L_SCR1(%a6) # save N temporarily 7141 1.1 is and.l &0x3F,%d1 # D0 is J = N mod 64 7142 1.1 is lsl.l &4,%d1 7143 1.1 is add.l %d1,%a1 # address of 2^(J/64) 7144 1.1 is mov.l L_SCR1(%a6),%d1 7145 1.1 is asr.l &6,%d1 # D0 is M 7146 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(M) 7147 1.1 is mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB 7148 1.1 is 7149 1.1 is EXPCONT1: 7150 1.1 is #--Step 3. 7151 1.1 is #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 7152 1.1 is #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M) 7153 1.1 is fmov.x %fp0,%fp2 7154 1.1 is fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 7155 1.1 is fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 7156 1.1 is fadd.x %fp1,%fp0 # X + N*L1 7157 1.1 is fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 7158 1.1 is 7159 1.1 is #--Step 4. 7160 1.1 is #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 7161 1.1 is #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) 7162 1.2 perry #--TO FULLY USE THE PIPELINE, WE COMPUTE S = R*R 7163 1.1 is #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))] 7164 1.1 is 7165 1.1 is fmov.x %fp0,%fp1 7166 1.1 is fmul.x %fp1,%fp1 # fp1 IS S = R*R 7167 1.1 is 7168 1.1 is fmov.s &0x3AB60B70,%fp2 # fp2 IS A5 7169 1.1 is 7170 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*A5 7171 1.1 is fmov.x %fp1,%fp3 7172 1.1 is fmul.s &0x3C088895,%fp3 # fp3 IS S*A4 7173 1.1 is 7174 1.1 is fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5 7175 1.1 is fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4 7176 1.1 is 7177 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5) 7178 1.1 is mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended 7179 1.1 is mov.l &0x80000000,SCALE+4(%a6) 7180 1.1 is clr.l SCALE+8(%a6) 7181 1.1 is 7182 1.1 is fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4) 7183 1.1 is 7184 1.1 is fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5) 7185 1.1 is fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4) 7186 1.1 is 7187 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5)) 7188 1.1 is fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4), 7189 1.1 is 7190 1.1 is fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64) 7191 1.1 is fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1 7192 1.1 is 7193 1.1 is #--Step 5 7194 1.1 is #--final reconstruction process 7195 1.1 is #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) ) 7196 1.1 is 7197 1.1 is fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1) 7198 1.1 is fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 7199 1.1 is fadd.s (%a1),%fp0 # accurate 2^(J/64) 7200 1.1 is 7201 1.1 is fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*... 7202 1.1 is mov.l ADJFLAG(%a6),%d1 7203 1.1 is 7204 1.1 is #--Step 6 7205 1.1 is tst.l %d1 7206 1.1 is beq.b NORMAL 7207 1.1 is ADJUST: 7208 1.1 is fmul.x ADJSCALE(%a6),%fp0 7209 1.1 is NORMAL: 7210 1.1 is fmov.l %d0,%fpcr # restore user FPCR 7211 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 7212 1.1 is fmul.x SCALE(%a6),%fp0 # multiply 2^(M) 7213 1.1 is bra t_catch 7214 1.1 is 7215 1.1 is EXPSM: 7216 1.1 is #--Step 7 7217 1.1 is fmovm.x (%a0),&0x80 # load X 7218 1.1 is fmov.l %d0,%fpcr 7219 1.1 is fadd.s &0x3F800000,%fp0 # 1+X in user mode 7220 1.1 is bra t_pinx2 7221 1.1 is 7222 1.1 is EEXPBIG: 7223 1.1 is #--Step 8 7224 1.1 is cmp.l %d1,&0x400CB27C # 16480 log2 7225 1.1 is bgt.b EXP2BIG 7226 1.1 is #--Steps 8.2 -- 8.6 7227 1.1 is fmov.x (%a0),%fp0 # load input from (a0) 7228 1.1 is 7229 1.1 is fmov.x %fp0,%fp1 7230 1.1 is fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 7231 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7232 1.1 is mov.l &1,ADJFLAG(%a6) 7233 1.1 is fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 7234 1.1 is lea EEXPTBL(%pc),%a1 7235 1.1 is fmov.l %d1,%fp0 # convert to floating-format 7236 1.1 is mov.l %d1,L_SCR1(%a6) # save N temporarily 7237 1.1 is and.l &0x3F,%d1 # D0 is J = N mod 64 7238 1.1 is lsl.l &4,%d1 7239 1.1 is add.l %d1,%a1 # address of 2^(J/64) 7240 1.1 is mov.l L_SCR1(%a6),%d1 7241 1.1 is asr.l &6,%d1 # D0 is K 7242 1.1 is mov.l %d1,L_SCR1(%a6) # save K temporarily 7243 1.1 is asr.l &1,%d1 # D0 is M1 7244 1.1 is sub.l %d1,L_SCR1(%a6) # a1 is M 7245 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(M1) 7246 1.1 is mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1) 7247 1.1 is mov.l &0x80000000,ADJSCALE+4(%a6) 7248 1.1 is clr.l ADJSCALE+8(%a6) 7249 1.1 is mov.l L_SCR1(%a6),%d1 # D0 is M 7250 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(M) 7251 1.1 is bra.w EXPCONT1 # go back to Step 3 7252 1.1 is 7253 1.1 is EXP2BIG: 7254 1.1 is #--Step 9 7255 1.1 is tst.b (%a0) # is X positive or negative? 7256 1.1 is bmi t_unfl2 7257 1.1 is bra t_ovfl2 7258 1.1 is 7259 1.1 is global setoxd 7260 1.1 is setoxd: 7261 1.1 is #--entry point for EXP(X), X is denormalized 7262 1.1 is mov.l (%a0),-(%sp) 7263 1.1 is andi.l &0x80000000,(%sp) 7264 1.1 is ori.l &0x00800000,(%sp) # sign(X)*2^(-126) 7265 1.1 is 7266 1.1 is fmov.s &0x3F800000,%fp0 7267 1.1 is 7268 1.1 is fmov.l %d0,%fpcr 7269 1.1 is fadd.s (%sp)+,%fp0 7270 1.1 is bra t_pinx2 7271 1.1 is 7272 1.1 is global setoxm1 7273 1.1 is setoxm1: 7274 1.1 is #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN 7275 1.1 is 7276 1.1 is #--Step 1. 7277 1.1 is #--Step 1.1 7278 1.1 is mov.l (%a0),%d1 # load part of input X 7279 1.1 is and.l &0x7FFF0000,%d1 # biased expo. of X 7280 1.1 is cmp.l %d1,&0x3FFD0000 # 1/4 7281 1.1 is bge.b EM1CON1 # |X| >= 1/4 7282 1.1 is bra EM1SM 7283 1.1 is 7284 1.1 is EM1CON1: 7285 1.1 is #--Step 1.3 7286 1.1 is #--The case |X| >= 1/4 7287 1.1 is mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 7288 1.1 is cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits 7289 1.1 is ble.b EM1MAIN # 1/4 <= |X| <= 70log2 7290 1.1 is bra EM1BIG 7291 1.1 is 7292 1.1 is EM1MAIN: 7293 1.1 is #--Step 2. 7294 1.1 is #--This is the case: 1/4 <= |X| <= 70 log2. 7295 1.1 is fmov.x (%a0),%fp0 # load input from (a0) 7296 1.1 is 7297 1.1 is fmov.x %fp0,%fp1 7298 1.1 is fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 7299 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7300 1.1 is fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 7301 1.1 is lea EEXPTBL(%pc),%a1 7302 1.1 is fmov.l %d1,%fp0 # convert to floating-format 7303 1.1 is 7304 1.1 is mov.l %d1,L_SCR1(%a6) # save N temporarily 7305 1.1 is and.l &0x3F,%d1 # D0 is J = N mod 64 7306 1.1 is lsl.l &4,%d1 7307 1.1 is add.l %d1,%a1 # address of 2^(J/64) 7308 1.1 is mov.l L_SCR1(%a6),%d1 7309 1.1 is asr.l &6,%d1 # D0 is M 7310 1.1 is mov.l %d1,L_SCR1(%a6) # save a copy of M 7311 1.1 is 7312 1.1 is #--Step 3. 7313 1.1 is #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 7314 1.1 is #--a0 points to 2^(J/64), D0 and a1 both contain M 7315 1.1 is fmov.x %fp0,%fp2 7316 1.1 is fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 7317 1.1 is fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 7318 1.1 is fadd.x %fp1,%fp0 # X + N*L1 7319 1.1 is fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 7320 1.1 is add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M 7321 1.1 is 7322 1.1 is #--Step 4. 7323 1.1 is #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 7324 1.1 is #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6))))) 7325 1.2 perry #--TO FULLY USE THE PIPELINE, WE COMPUTE S = R*R 7326 1.1 is #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))] 7327 1.1 is 7328 1.1 is fmov.x %fp0,%fp1 7329 1.1 is fmul.x %fp1,%fp1 # fp1 IS S = R*R 7330 1.1 is 7331 1.1 is fmov.s &0x3950097B,%fp2 # fp2 IS a6 7332 1.1 is 7333 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*A6 7334 1.1 is fmov.x %fp1,%fp3 7335 1.1 is fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5 7336 1.1 is 7337 1.1 is fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6 7338 1.1 is fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5 7339 1.1 is mov.w %d1,SC(%a6) # SC is 2^(M) in extended 7340 1.1 is mov.l &0x80000000,SC+4(%a6) 7341 1.1 is clr.l SC+8(%a6) 7342 1.1 is 7343 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6) 7344 1.1 is mov.l L_SCR1(%a6),%d1 # D0 is M 7345 1.1 is neg.w %d1 # D0 is -M 7346 1.1 is fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5) 7347 1.1 is add.w &0x3FFF,%d1 # biased expo. of 2^(-M) 7348 1.1 is fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6) 7349 1.1 is fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5) 7350 1.1 is 7351 1.1 is fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6)) 7352 1.1 is or.w &0x8000,%d1 # signed/expo. of -2^(-M) 7353 1.1 is mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M) 7354 1.1 is mov.l &0x80000000,ONEBYSC+4(%a6) 7355 1.1 is clr.l ONEBYSC+8(%a6) 7356 1.1 is fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5)) 7357 1.1 is 7358 1.1 is fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6)) 7359 1.1 is fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5)) 7360 1.1 is 7361 1.1 is fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1 7362 1.1 is 7363 1.1 is fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 7364 1.1 is 7365 1.1 is #--Step 5 7366 1.1 is #--Compute 2^(J/64)*p 7367 1.1 is 7368 1.1 is fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1) 7369 1.1 is 7370 1.1 is #--Step 6 7371 1.1 is #--Step 6.1 7372 1.1 is mov.l L_SCR1(%a6),%d1 # retrieve M 7373 1.1 is cmp.l %d1,&63 7374 1.1 is ble.b MLE63 7375 1.1 is #--Step 6.2 M >= 64 7376 1.1 is fmov.s 12(%a1),%fp1 # fp1 is t 7377 1.1 is fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc 7378 1.1 is fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released 7379 1.1 is fadd.x (%a1),%fp0 # T+(p+(t+OnebySc)) 7380 1.1 is bra EM1SCALE 7381 1.1 is MLE63: 7382 1.1 is #--Step 6.3 M <= 63 7383 1.1 is cmp.l %d1,&-3 7384 1.1 is bge.b MGEN3 7385 1.1 is MLTN3: 7386 1.1 is #--Step 6.4 M <= -4 7387 1.1 is fadd.s 12(%a1),%fp0 # p+t 7388 1.1 is fadd.x (%a1),%fp0 # T+(p+t) 7389 1.1 is fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t)) 7390 1.1 is bra EM1SCALE 7391 1.1 is MGEN3: 7392 1.1 is #--Step 6.5 -3 <= M <= 63 7393 1.1 is fmov.x (%a1)+,%fp1 # fp1 is T 7394 1.1 is fadd.s (%a1),%fp0 # fp0 is p+t 7395 1.1 is fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc 7396 1.1 is fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t) 7397 1.1 is 7398 1.1 is EM1SCALE: 7399 1.1 is #--Step 6.6 7400 1.1 is fmov.l %d0,%fpcr 7401 1.1 is fmul.x SC(%a6),%fp0 7402 1.1 is bra t_inx2 7403 1.1 is 7404 1.1 is EM1SM: 7405 1.1 is #--Step 7 |X| < 1/4. 7406 1.1 is cmp.l %d1,&0x3FBE0000 # 2^(-65) 7407 1.1 is bge.b EM1POLY 7408 1.1 is 7409 1.1 is EM1TINY: 7410 1.1 is #--Step 8 |X| < 2^(-65) 7411 1.1 is cmp.l %d1,&0x00330000 # 2^(-16312) 7412 1.1 is blt.b EM12TINY 7413 1.1 is #--Step 8.2 7414 1.1 is mov.l &0x80010000,SC(%a6) # SC is -2^(-16382) 7415 1.1 is mov.l &0x80000000,SC+4(%a6) 7416 1.1 is clr.l SC+8(%a6) 7417 1.1 is fmov.x (%a0),%fp0 7418 1.1 is fmov.l %d0,%fpcr 7419 1.1 is mov.b &FADD_OP,%d1 # last inst is ADD 7420 1.1 is fadd.x SC(%a6),%fp0 7421 1.1 is bra t_catch 7422 1.1 is 7423 1.1 is EM12TINY: 7424 1.1 is #--Step 8.3 7425 1.1 is fmov.x (%a0),%fp0 7426 1.1 is fmul.d TWO140(%pc),%fp0 7427 1.1 is mov.l &0x80010000,SC(%a6) 7428 1.1 is mov.l &0x80000000,SC+4(%a6) 7429 1.1 is clr.l SC+8(%a6) 7430 1.1 is fadd.x SC(%a6),%fp0 7431 1.1 is fmov.l %d0,%fpcr 7432 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 7433 1.1 is fmul.d TWON140(%pc),%fp0 7434 1.1 is bra t_catch 7435 1.1 is 7436 1.1 is EM1POLY: 7437 1.1 is #--Step 9 exp(X)-1 by a simple polynomial 7438 1.1 is fmov.x (%a0),%fp0 # fp0 is X 7439 1.1 is fmul.x %fp0,%fp0 # fp0 is S := X*X 7440 1.1 is fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7441 1.1 is fmov.s &0x2F30CAA8,%fp1 # fp1 is B12 7442 1.1 is fmul.x %fp0,%fp1 # fp1 is S*B12 7443 1.1 is fmov.s &0x310F8290,%fp2 # fp2 is B11 7444 1.1 is fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12 7445 1.1 is 7446 1.1 is fmul.x %fp0,%fp2 # fp2 is S*B11 7447 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B10 + ... 7448 1.1 is 7449 1.1 is fadd.s &0x3493F281,%fp2 # fp2 is B9+S*... 7450 1.1 is fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*... 7451 1.1 is 7452 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B9+... 7453 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B8+... 7454 1.1 is 7455 1.1 is fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*... 7456 1.1 is fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*... 7457 1.1 is 7458 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B7+... 7459 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B6+... 7460 1.1 is 7461 1.1 is fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*... 7462 1.1 is fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*... 7463 1.1 is 7464 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B5+... 7465 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B4+... 7466 1.1 is 7467 1.1 is fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*... 7468 1.1 is fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*... 7469 1.1 is 7470 1.1 is fmul.x %fp0,%fp2 # fp2 is S*(B3+... 7471 1.1 is fmul.x %fp0,%fp1 # fp1 is S*(B2+... 7472 1.1 is 7473 1.1 is fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...) 7474 1.1 is fmul.x (%a0),%fp1 # fp1 is X*S*(B2... 7475 1.1 is 7476 1.1 is fmul.s &0x3F000000,%fp0 # fp0 is S*B1 7477 1.1 is fadd.x %fp2,%fp1 # fp1 is Q 7478 1.1 is 7479 1.1 is fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 7480 1.1 is 7481 1.1 is fadd.x %fp1,%fp0 # fp0 is S*B1+Q 7482 1.1 is 7483 1.1 is fmov.l %d0,%fpcr 7484 1.1 is fadd.x (%a0),%fp0 7485 1.1 is bra t_inx2 7486 1.1 is 7487 1.1 is EM1BIG: 7488 1.1 is #--Step 10 |X| > 70 log2 7489 1.1 is mov.l (%a0),%d1 7490 1.1 is cmp.l %d1,&0 7491 1.1 is bgt.w EXPC1 7492 1.1 is #--Step 10.2 7493 1.1 is fmov.s &0xBF800000,%fp0 # fp0 is -1 7494 1.1 is fmov.l %d0,%fpcr 7495 1.1 is fadd.s &0x00800000,%fp0 # -1 + 2^(-126) 7496 1.1 is bra t_minx2 7497 1.1 is 7498 1.1 is global setoxm1d 7499 1.1 is setoxm1d: 7500 1.1 is #--entry point for EXPM1(X), here X is denormalized 7501 1.1 is #--Step 0. 7502 1.1 is bra t_extdnrm 7503 1.1 is 7504 1.1 is ######################################################################### 7505 1.1 is # sgetexp(): returns the exponent portion of the input argument. # 7506 1.1 is # The exponent bias is removed and the exponent value is # 7507 1.1 is # returned as an extended precision number in fp0. # 7508 1.1 is # sgetexpd(): handles denormalized numbers. # 7509 1.1 is # # 7510 1.1 is # sgetman(): extracts the mantissa of the input argument. The # 7511 1.1 is # mantissa is converted to an extended precision number w/ # 7512 1.1 is # an exponent of $3fff and is returned in fp0. The range of # 7513 1.1 is # the result is [1.0 - 2.0). # 7514 1.1 is # sgetmand(): handles denormalized numbers. # 7515 1.1 is # # 7516 1.1 is # INPUT *************************************************************** # 7517 1.1 is # a0 = pointer to extended precision input # 7518 1.1 is # # 7519 1.1 is # OUTPUT ************************************************************** # 7520 1.1 is # fp0 = exponent(X) or mantissa(X) # 7521 1.1 is # # 7522 1.1 is ######################################################################### 7523 1.1 is 7524 1.1 is global sgetexp 7525 1.1 is sgetexp: 7526 1.1 is mov.w SRC_EX(%a0),%d0 # get the exponent 7527 1.1 is bclr &0xf,%d0 # clear the sign bit 7528 1.1 is subi.w &0x3fff,%d0 # subtract off the bias 7529 1.1 is fmov.w %d0,%fp0 # return exp in fp0 7530 1.1 is blt.b sgetexpn # it's negative 7531 1.1 is rts 7532 1.1 is 7533 1.1 is sgetexpn: 7534 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 7535 1.1 is rts 7536 1.1 is 7537 1.1 is global sgetexpd 7538 1.1 is sgetexpd: 7539 1.1 is bsr.l norm # normalize 7540 1.1 is neg.w %d0 # new exp = -(shft amt) 7541 1.1 is subi.w &0x3fff,%d0 # subtract off the bias 7542 1.1 is fmov.w %d0,%fp0 # return exp in fp0 7543 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 7544 1.1 is rts 7545 1.1 is 7546 1.1 is global sgetman 7547 1.1 is sgetman: 7548 1.1 is mov.w SRC_EX(%a0),%d0 # get the exp 7549 1.1 is ori.w &0x7fff,%d0 # clear old exp 7550 1.1 is bclr &0xe,%d0 # make it the new exp +-3fff 7551 1.1 is 7552 1.1 is # here, we build the result in a tmp location so as not to disturb the input 7553 1.1 is mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc 7554 1.1 is mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc 7555 1.1 is mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 7556 1.1 is fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0 7557 1.1 is bmi.b sgetmann # it's negative 7558 1.1 is rts 7559 1.1 is 7560 1.1 is sgetmann: 7561 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 7562 1.1 is rts 7563 1.1 is 7564 1.1 is # 7565 1.1 is # For denormalized numbers, shift the mantissa until the j-bit = 1, 7566 1.1 is # then load the exponent with +/1 $3fff. 7567 1.1 is # 7568 1.1 is global sgetmand 7569 1.1 is sgetmand: 7570 1.1 is bsr.l norm # normalize exponent 7571 1.1 is bra.b sgetman 7572 1.1 is 7573 1.1 is ######################################################################### 7574 1.1 is # scosh(): computes the hyperbolic cosine of a normalized input # 7575 1.1 is # scoshd(): computes the hyperbolic cosine of a denormalized input # 7576 1.1 is # # 7577 1.1 is # INPUT *************************************************************** # 7578 1.1 is # a0 = pointer to extended precision input # 7579 1.1 is # d0 = round precision,mode # 7580 1.1 is # # 7581 1.1 is # OUTPUT ************************************************************** # 7582 1.1 is # fp0 = cosh(X) # 7583 1.1 is # # 7584 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 7585 1.1 is # The returned result is within 3 ulps in 64 significant bit, # 7586 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7587 1.1 is # rounded to double precision. The result is provably monotonic # 7588 1.1 is # in double precision. # 7589 1.1 is # # 7590 1.1 is # ALGORITHM *********************************************************** # 7591 1.1 is # # 7592 1.1 is # COSH # 7593 1.1 is # 1. If |X| > 16380 log2, go to 3. # 7594 1.1 is # # 7595 1.1 is # 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae # 7596 1.1 is # y = |X|, z = exp(Y), and # 7597 1.1 is # cosh(X) = (1/2)*( z + 1/z ). # 7598 1.1 is # Exit. # 7599 1.1 is # # 7600 1.1 is # 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. # 7601 1.1 is # # 7602 1.1 is # 4. (16380 log2 < |X| <= 16480 log2) # 7603 1.1 is # cosh(X) = sign(X) * exp(|X|)/2. # 7604 1.1 is # However, invoking exp(|X|) may cause premature # 7605 1.1 is # overflow. Thus, we calculate sinh(X) as follows: # 7606 1.1 is # Y := |X| # 7607 1.1 is # Fact := 2**(16380) # 7608 1.1 is # Y' := Y - 16381 log2 # 7609 1.1 is # cosh(X) := Fact * exp(Y'). # 7610 1.1 is # Exit. # 7611 1.1 is # # 7612 1.1 is # 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 7613 1.1 is # Huge*Huge to generate overflow and an infinity with # 7614 1.1 is # the appropriate sign. Huge is the largest finite number # 7615 1.1 is # in extended format. Exit. # 7616 1.1 is # # 7617 1.1 is ######################################################################### 7618 1.1 is 7619 1.1 is TWO16380: 7620 1.1 is long 0x7FFB0000,0x80000000,0x00000000,0x00000000 7621 1.1 is 7622 1.1 is global scosh 7623 1.1 is scosh: 7624 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 7625 1.1 is 7626 1.1 is mov.l (%a0),%d1 7627 1.1 is mov.w 4(%a0),%d1 7628 1.1 is and.l &0x7FFFFFFF,%d1 7629 1.1 is cmp.l %d1,&0x400CB167 7630 1.1 is bgt.b COSHBIG 7631 1.1 is 7632 1.1 is #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 7633 1.1 is #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) ) 7634 1.1 is 7635 1.1 is fabs.x %fp0 # |X| 7636 1.1 is 7637 1.1 is mov.l %d0,-(%sp) 7638 1.1 is clr.l %d0 7639 1.1 is fmovm.x &0x01,-(%sp) # save |X| to stack 7640 1.1 is lea (%sp),%a0 # pass ptr to |X| 7641 1.1 is bsr setox # FP0 IS EXP(|X|) 7642 1.1 is add.l &0xc,%sp # erase |X| from stack 7643 1.1 is fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|) 7644 1.1 is mov.l (%sp)+,%d0 7645 1.1 is 7646 1.1 is fmov.s &0x3E800000,%fp1 # (1/4) 7647 1.1 is fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|)) 7648 1.1 is 7649 1.1 is fmov.l %d0,%fpcr 7650 1.1 is mov.b &FADD_OP,%d1 # last inst is ADD 7651 1.1 is fadd.x %fp1,%fp0 7652 1.1 is bra t_catch 7653 1.1 is 7654 1.1 is COSHBIG: 7655 1.1 is cmp.l %d1,&0x400CB2B3 7656 1.1 is bgt.b COSHHUGE 7657 1.1 is 7658 1.1 is fabs.x %fp0 7659 1.1 is fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 7660 1.1 is fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 7661 1.1 is 7662 1.1 is mov.l %d0,-(%sp) 7663 1.1 is clr.l %d0 7664 1.1 is fmovm.x &0x01,-(%sp) # save fp0 to stack 7665 1.1 is lea (%sp),%a0 # pass ptr to fp0 7666 1.1 is bsr setox 7667 1.1 is add.l &0xc,%sp # clear fp0 from stack 7668 1.1 is mov.l (%sp)+,%d0 7669 1.1 is 7670 1.1 is fmov.l %d0,%fpcr 7671 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 7672 1.1 is fmul.x TWO16380(%pc),%fp0 7673 1.1 is bra t_catch 7674 1.1 is 7675 1.1 is COSHHUGE: 7676 1.1 is bra t_ovfl2 7677 1.1 is 7678 1.1 is global scoshd 7679 1.1 is #--COSH(X) = 1 FOR DENORMALIZED X 7680 1.1 is scoshd: 7681 1.1 is fmov.s &0x3F800000,%fp0 7682 1.1 is 7683 1.1 is fmov.l %d0,%fpcr 7684 1.1 is fadd.s &0x00800000,%fp0 7685 1.1 is bra t_pinx2 7686 1.1 is 7687 1.1 is ######################################################################### 7688 1.1 is # ssinh(): computes the hyperbolic sine of a normalized input # 7689 1.1 is # ssinhd(): computes the hyperbolic sine of a denormalized input # 7690 1.1 is # # 7691 1.1 is # INPUT *************************************************************** # 7692 1.1 is # a0 = pointer to extended precision input # 7693 1.1 is # d0 = round precision,mode # 7694 1.1 is # # 7695 1.1 is # OUTPUT ************************************************************** # 7696 1.1 is # fp0 = sinh(X) # 7697 1.1 is # # 7698 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 7699 1.1 is # The returned result is within 3 ulps in 64 significant bit, # 7700 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7701 1.1 is # rounded to double precision. The result is provably monotonic # 7702 1.1 is # in double precision. # 7703 1.1 is # # 7704 1.1 is # ALGORITHM *********************************************************** # 7705 1.1 is # # 7706 1.1 is # SINH # 7707 1.1 is # 1. If |X| > 16380 log2, go to 3. # 7708 1.1 is # # 7709 1.1 is # 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula # 7710 1.1 is # y = |X|, sgn = sign(X), and z = expm1(Y), # 7711 1.1 is # sinh(X) = sgn*(1/2)*( z + z/(1+z) ). # 7712 1.1 is # Exit. # 7713 1.1 is # # 7714 1.1 is # 3. If |X| > 16480 log2, go to 5. # 7715 1.1 is # # 7716 1.1 is # 4. (16380 log2 < |X| <= 16480 log2) # 7717 1.1 is # sinh(X) = sign(X) * exp(|X|)/2. # 7718 1.1 is # However, invoking exp(|X|) may cause premature overflow. # 7719 1.1 is # Thus, we calculate sinh(X) as follows: # 7720 1.1 is # Y := |X| # 7721 1.1 is # sgn := sign(X) # 7722 1.1 is # sgnFact := sgn * 2**(16380) # 7723 1.1 is # Y' := Y - 16381 log2 # 7724 1.1 is # sinh(X) := sgnFact * exp(Y'). # 7725 1.1 is # Exit. # 7726 1.1 is # # 7727 1.1 is # 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 7728 1.1 is # sign(X)*Huge*Huge to generate overflow and an infinity with # 7729 1.1 is # the appropriate sign. Huge is the largest finite number in # 7730 1.1 is # extended format. Exit. # 7731 1.1 is # # 7732 1.1 is ######################################################################### 7733 1.1 is 7734 1.1 is global ssinh 7735 1.1 is ssinh: 7736 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 7737 1.1 is 7738 1.1 is mov.l (%a0),%d1 7739 1.1 is mov.w 4(%a0),%d1 7740 1.1 is mov.l %d1,%a1 # save (compacted) operand 7741 1.1 is and.l &0x7FFFFFFF,%d1 7742 1.1 is cmp.l %d1,&0x400CB167 7743 1.1 is bgt.b SINHBIG 7744 1.1 is 7745 1.1 is #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 7746 1.1 is #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) ) 7747 1.1 is 7748 1.1 is fabs.x %fp0 # Y = |X| 7749 1.1 is 7750 1.1 is movm.l &0x8040,-(%sp) # {a1/d0} 7751 1.1 is fmovm.x &0x01,-(%sp) # save Y on stack 7752 1.1 is lea (%sp),%a0 # pass ptr to Y 7753 1.1 is clr.l %d0 7754 1.1 is bsr setoxm1 # FP0 IS Z = EXPM1(Y) 7755 1.1 is add.l &0xc,%sp # clear Y from stack 7756 1.1 is fmov.l &0,%fpcr 7757 1.1 is movm.l (%sp)+,&0x0201 # {a1/d0} 7758 1.1 is 7759 1.1 is fmov.x %fp0,%fp1 7760 1.1 is fadd.s &0x3F800000,%fp1 # 1+Z 7761 1.1 is fmov.x %fp0,-(%sp) 7762 1.1 is fdiv.x %fp1,%fp0 # Z/(1+Z) 7763 1.1 is mov.l %a1,%d1 7764 1.1 is and.l &0x80000000,%d1 7765 1.1 is or.l &0x3F000000,%d1 7766 1.1 is fadd.x (%sp)+,%fp0 7767 1.1 is mov.l %d1,-(%sp) 7768 1.1 is 7769 1.1 is fmov.l %d0,%fpcr 7770 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 7771 1.1 is fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set 7772 1.1 is bra t_catch 7773 1.1 is 7774 1.1 is SINHBIG: 7775 1.1 is cmp.l %d1,&0x400CB2B3 7776 1.1 is bgt t_ovfl 7777 1.1 is fabs.x %fp0 7778 1.1 is fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 7779 1.1 is mov.l &0,-(%sp) 7780 1.1 is mov.l &0x80000000,-(%sp) 7781 1.1 is mov.l %a1,%d1 7782 1.1 is and.l &0x80000000,%d1 7783 1.1 is or.l &0x7FFB0000,%d1 7784 1.1 is mov.l %d1,-(%sp) # EXTENDED FMT 7785 1.1 is fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 7786 1.1 is 7787 1.1 is mov.l %d0,-(%sp) 7788 1.1 is clr.l %d0 7789 1.1 is fmovm.x &0x01,-(%sp) # save fp0 on stack 7790 1.1 is lea (%sp),%a0 # pass ptr to fp0 7791 1.1 is bsr setox 7792 1.1 is add.l &0xc,%sp # clear fp0 from stack 7793 1.1 is 7794 1.1 is mov.l (%sp)+,%d0 7795 1.1 is fmov.l %d0,%fpcr 7796 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 7797 1.1 is fmul.x (%sp)+,%fp0 # possible exception 7798 1.1 is bra t_catch 7799 1.1 is 7800 1.1 is global ssinhd 7801 1.1 is #--SINH(X) = X FOR DENORMALIZED X 7802 1.1 is ssinhd: 7803 1.1 is bra t_extdnrm 7804 1.1 is 7805 1.1 is ######################################################################### 7806 1.1 is # stanh(): computes the hyperbolic tangent of a normalized input # 7807 1.1 is # stanhd(): computes the hyperbolic tangent of a denormalized input # 7808 1.1 is # # 7809 1.1 is # INPUT *************************************************************** # 7810 1.1 is # a0 = pointer to extended precision input # 7811 1.1 is # d0 = round precision,mode # 7812 1.1 is # # 7813 1.1 is # OUTPUT ************************************************************** # 7814 1.1 is # fp0 = tanh(X) # 7815 1.1 is # # 7816 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 7817 1.1 is # The returned result is within 3 ulps in 64 significant bit, # 7818 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7819 1.1 is # rounded to double precision. The result is provably monotonic # 7820 1.1 is # in double precision. # 7821 1.1 is # # 7822 1.1 is # ALGORITHM *********************************************************** # 7823 1.1 is # # 7824 1.1 is # TANH # 7825 1.1 is # 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. # 7826 1.1 is # # 7827 1.1 is # 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by # 7828 1.1 is # sgn := sign(X), y := 2|X|, z := expm1(Y), and # 7829 1.1 is # tanh(X) = sgn*( z/(2+z) ). # 7830 1.1 is # Exit. # 7831 1.1 is # # 7832 1.1 is # 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, # 7833 1.1 is # go to 7. # 7834 1.1 is # # 7835 1.1 is # 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. # 7836 1.1 is # # 7837 1.1 is # 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by # 7838 1.1 is # sgn := sign(X), y := 2|X|, z := exp(Y), # 7839 1.1 is # tanh(X) = sgn - [ sgn*2/(1+z) ]. # 7840 1.1 is # Exit. # 7841 1.1 is # # 7842 1.1 is # 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we # 7843 1.1 is # calculate Tanh(X) by # 7844 1.1 is # sgn := sign(X), Tiny := 2**(-126), # 7845 1.1 is # tanh(X) := sgn - sgn*Tiny. # 7846 1.1 is # Exit. # 7847 1.1 is # # 7848 1.1 is # 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. # 7849 1.1 is # # 7850 1.1 is ######################################################################### 7851 1.1 is 7852 1.1 is set X,FP_SCR0 7853 1.1 is set XFRAC,X+4 7854 1.1 is 7855 1.1 is set SGN,L_SCR3 7856 1.1 is 7857 1.1 is set V,FP_SCR0 7858 1.1 is 7859 1.1 is global stanh 7860 1.1 is stanh: 7861 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 7862 1.1 is 7863 1.1 is fmov.x %fp0,X(%a6) 7864 1.1 is mov.l (%a0),%d1 7865 1.1 is mov.w 4(%a0),%d1 7866 1.1 is mov.l %d1,X(%a6) 7867 1.1 is and.l &0x7FFFFFFF,%d1 7868 1.1 is cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)? 7869 1.1 is blt.w TANHBORS # yes 7870 1.1 is cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2? 7871 1.1 is bgt.w TANHBORS # yes 7872 1.1 is 7873 1.1 is #--THIS IS THE USUAL CASE 7874 1.1 is #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2). 7875 1.1 is 7876 1.1 is mov.l X(%a6),%d1 7877 1.1 is mov.l %d1,SGN(%a6) 7878 1.1 is and.l &0x7FFF0000,%d1 7879 1.1 is add.l &0x00010000,%d1 # EXPONENT OF 2|X| 7880 1.1 is mov.l %d1,X(%a6) 7881 1.1 is and.l &0x80000000,SGN(%a6) 7882 1.1 is fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X| 7883 1.1 is 7884 1.1 is mov.l %d0,-(%sp) 7885 1.1 is clr.l %d0 7886 1.1 is fmovm.x &0x1,-(%sp) # save Y on stack 7887 1.1 is lea (%sp),%a0 # pass ptr to Y 7888 1.1 is bsr setoxm1 # FP0 IS Z = EXPM1(Y) 7889 1.1 is add.l &0xc,%sp # clear Y from stack 7890 1.1 is mov.l (%sp)+,%d0 7891 1.1 is 7892 1.1 is fmov.x %fp0,%fp1 7893 1.1 is fadd.s &0x40000000,%fp1 # Z+2 7894 1.1 is mov.l SGN(%a6),%d1 7895 1.1 is fmov.x %fp1,V(%a6) 7896 1.1 is eor.l %d1,V(%a6) 7897 1.1 is 7898 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode 7899 1.1 is fdiv.x V(%a6),%fp0 7900 1.1 is bra t_inx2 7901 1.1 is 7902 1.1 is TANHBORS: 7903 1.1 is cmp.l %d1,&0x3FFF8000 7904 1.1 is blt.w TANHSM 7905 1.1 is 7906 1.1 is cmp.l %d1,&0x40048AA1 7907 1.1 is bgt.w TANHHUGE 7908 1.1 is 7909 1.1 is #-- (5/2) LOG2 < |X| < 50 LOG2, 7910 1.1 is #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X), 7911 1.1 is #--TANH(X) = SGN - SGN*2/[EXP(Y)+1]. 7912 1.1 is 7913 1.1 is mov.l X(%a6),%d1 7914 1.1 is mov.l %d1,SGN(%a6) 7915 1.1 is and.l &0x7FFF0000,%d1 7916 1.1 is add.l &0x00010000,%d1 # EXPO OF 2|X| 7917 1.1 is mov.l %d1,X(%a6) # Y = 2|X| 7918 1.1 is and.l &0x80000000,SGN(%a6) 7919 1.1 is mov.l SGN(%a6),%d1 7920 1.1 is fmov.x X(%a6),%fp0 # Y = 2|X| 7921 1.1 is 7922 1.1 is mov.l %d0,-(%sp) 7923 1.1 is clr.l %d0 7924 1.1 is fmovm.x &0x01,-(%sp) # save Y on stack 7925 1.1 is lea (%sp),%a0 # pass ptr to Y 7926 1.1 is bsr setox # FP0 IS EXP(Y) 7927 1.1 is add.l &0xc,%sp # clear Y from stack 7928 1.1 is mov.l (%sp)+,%d0 7929 1.1 is mov.l SGN(%a6),%d1 7930 1.1 is fadd.s &0x3F800000,%fp0 # EXP(Y)+1 7931 1.1 is 7932 1.1 is eor.l &0xC0000000,%d1 # -SIGN(X)*2 7933 1.1 is fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT 7934 1.1 is fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ] 7935 1.1 is 7936 1.1 is mov.l SGN(%a6),%d1 7937 1.1 is or.l &0x3F800000,%d1 # SGN 7938 1.1 is fmov.s %d1,%fp0 # SGN IN SGL FMT 7939 1.1 is 7940 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode 7941 1.1 is mov.b &FADD_OP,%d1 # last inst is ADD 7942 1.1 is fadd.x %fp1,%fp0 7943 1.1 is bra t_inx2 7944 1.1 is 7945 1.1 is TANHSM: 7946 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode 7947 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 7948 1.1 is fmov.x X(%a6),%fp0 # last inst - possible exception set 7949 1.1 is bra t_catch 7950 1.1 is 7951 1.1 is #---RETURN SGN(X) - SGN(X)EPS 7952 1.1 is TANHHUGE: 7953 1.1 is mov.l X(%a6),%d1 7954 1.1 is and.l &0x80000000,%d1 7955 1.1 is or.l &0x3F800000,%d1 7956 1.1 is fmov.s %d1,%fp0 7957 1.1 is and.l &0x80000000,%d1 7958 1.1 is eor.l &0x80800000,%d1 # -SIGN(X)*EPS 7959 1.1 is 7960 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode 7961 1.1 is fadd.s %d1,%fp0 7962 1.1 is bra t_inx2 7963 1.1 is 7964 1.1 is global stanhd 7965 1.1 is #--TANH(X) = X FOR DENORMALIZED X 7966 1.1 is stanhd: 7967 1.1 is bra t_extdnrm 7968 1.1 is 7969 1.1 is ######################################################################### 7970 1.1 is # slogn(): computes the natural logarithm of a normalized input # 7971 1.1 is # slognd(): computes the natural logarithm of a denormalized input # 7972 1.1 is # slognp1(): computes the log(1+X) of a normalized input # 7973 1.1 is # slognp1d(): computes the log(1+X) of a denormalized input # 7974 1.1 is # # 7975 1.1 is # INPUT *************************************************************** # 7976 1.1 is # a0 = pointer to extended precision input # 7977 1.1 is # d0 = round precision,mode # 7978 1.1 is # # 7979 1.1 is # OUTPUT ************************************************************** # 7980 1.1 is # fp0 = log(X) or log(1+X) # 7981 1.1 is # # 7982 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 7983 1.1 is # The returned result is within 2 ulps in 64 significant bit, # 7984 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7985 1.1 is # rounded to double precision. The result is provably monotonic # 7986 1.1 is # in double precision. # 7987 1.1 is # # 7988 1.1 is # ALGORITHM *********************************************************** # 7989 1.1 is # LOGN: # 7990 1.1 is # Step 1. If |X-1| < 1/16, approximate log(X) by an odd # 7991 1.1 is # polynomial in u, where u = 2(X-1)/(X+1). Otherwise, # 7992 1.1 is # move on to Step 2. # 7993 1.1 is # # 7994 1.1 is # Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first # 7995 1.1 is # seven significant bits of Y plus 2**(-7), i.e. # 7996 1.1 is # F = 1.xxxxxx1 in base 2 where the six "x" match those # 7997 1.1 is # of Y. Note that |Y-F| <= 2**(-7). # 7998 1.1 is # # 7999 1.1 is # Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a # 8000 1.1 is # polynomial in u, log(1+u) = poly. # 8001 1.1 is # # 8002 1.1 is # Step 4. Reconstruct # 8003 1.1 is # log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) # 8004 1.1 is # by k*log(2) + (log(F) + poly). The values of log(F) are # 8005 1.1 is # calculated beforehand and stored in the program. # 8006 1.1 is # # 8007 1.1 is # lognp1: # 8008 1.1 is # Step 1: If |X| < 1/16, approximate log(1+X) by an odd # 8009 1.1 is # polynomial in u where u = 2X/(2+X). Otherwise, move on # 8010 1.1 is # to Step 2. # 8011 1.1 is # # 8012 1.1 is # Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done # 8013 1.1 is # in Step 2 of the algorithm for LOGN and compute # 8014 1.1 is # log(1+X) as k*log(2) + log(F) + poly where poly # 8015 1.1 is # approximates log(1+u), u = (Y-F)/F. # 8016 1.1 is # # 8017 1.1 is # Implementation Notes: # 8018 1.1 is # Note 1. There are 64 different possible values for F, thus 64 # 8019 1.1 is # log(F)'s need to be tabulated. Moreover, the values of # 8020 1.1 is # 1/F are also tabulated so that the division in (Y-F)/F # 8021 1.1 is # can be performed by a multiplication. # 8022 1.1 is # # 8023 1.1 is # Note 2. In Step 2 of lognp1, in order to preserved accuracy, # 8024 1.1 is # the value Y-F has to be calculated carefully when # 8025 1.1 is # 1/2 <= X < 3/2. # 8026 1.1 is # # 8027 1.1 is # Note 3. To fully exploit the pipeline, polynomials are usually # 8028 1.1 is # separated into two parts evaluated independently before # 8029 1.1 is # being added up. # 8030 1.1 is # # 8031 1.1 is ######################################################################### 8032 1.1 is LOGOF2: 8033 1.1 is long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 8034 1.1 is 8035 1.1 is one: 8036 1.1 is long 0x3F800000 8037 1.1 is zero: 8038 1.1 is long 0x00000000 8039 1.1 is infty: 8040 1.1 is long 0x7F800000 8041 1.1 is negone: 8042 1.1 is long 0xBF800000 8043 1.1 is 8044 1.1 is LOGA6: 8045 1.1 is long 0x3FC2499A,0xB5E4040B 8046 1.1 is LOGA5: 8047 1.1 is long 0xBFC555B5,0x848CB7DB 8048 1.1 is 8049 1.1 is LOGA4: 8050 1.1 is long 0x3FC99999,0x987D8730 8051 1.1 is LOGA3: 8052 1.1 is long 0xBFCFFFFF,0xFF6F7E97 8053 1.1 is 8054 1.1 is LOGA2: 8055 1.1 is long 0x3FD55555,0x555555A4 8056 1.1 is LOGA1: 8057 1.1 is long 0xBFE00000,0x00000008 8058 1.1 is 8059 1.1 is LOGB5: 8060 1.1 is long 0x3F175496,0xADD7DAD6 8061 1.1 is LOGB4: 8062 1.1 is long 0x3F3C71C2,0xFE80C7E0 8063 1.1 is 8064 1.1 is LOGB3: 8065 1.1 is long 0x3F624924,0x928BCCFF 8066 1.1 is LOGB2: 8067 1.1 is long 0x3F899999,0x999995EC 8068 1.1 is 8069 1.1 is LOGB1: 8070 1.1 is long 0x3FB55555,0x55555555 8071 1.1 is TWO: 8072 1.1 is long 0x40000000,0x00000000 8073 1.1 is 8074 1.1 is LTHOLD: 8075 1.1 is long 0x3f990000,0x80000000,0x00000000,0x00000000 8076 1.1 is 8077 1.1 is LOGTBL: 8078 1.1 is long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000 8079 1.1 is long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000 8080 1.1 is long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000 8081 1.1 is long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000 8082 1.1 is long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000 8083 1.1 is long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000 8084 1.1 is long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000 8085 1.1 is long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000 8086 1.1 is long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000 8087 1.1 is long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000 8088 1.1 is long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000 8089 1.1 is long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000 8090 1.1 is long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000 8091 1.1 is long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000 8092 1.1 is long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000 8093 1.1 is long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000 8094 1.1 is long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000 8095 1.1 is long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000 8096 1.1 is long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000 8097 1.1 is long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000 8098 1.1 is long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000 8099 1.1 is long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000 8100 1.1 is long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000 8101 1.1 is long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000 8102 1.1 is long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000 8103 1.1 is long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000 8104 1.1 is long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000 8105 1.1 is long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000 8106 1.1 is long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000 8107 1.1 is long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000 8108 1.1 is long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000 8109 1.1 is long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000 8110 1.1 is long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000 8111 1.1 is long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000 8112 1.1 is long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000 8113 1.1 is long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000 8114 1.1 is long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000 8115 1.1 is long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000 8116 1.1 is long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000 8117 1.1 is long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000 8118 1.1 is long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000 8119 1.1 is long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000 8120 1.1 is long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000 8121 1.1 is long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000 8122 1.1 is long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000 8123 1.1 is long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000 8124 1.1 is long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000 8125 1.1 is long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000 8126 1.1 is long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000 8127 1.1 is long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000 8128 1.1 is long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000 8129 1.1 is long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000 8130 1.1 is long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000 8131 1.1 is long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000 8132 1.1 is long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000 8133 1.1 is long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000 8134 1.1 is long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000 8135 1.1 is long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000 8136 1.1 is long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000 8137 1.1 is long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000 8138 1.1 is long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000 8139 1.1 is long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000 8140 1.1 is long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000 8141 1.1 is long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000 8142 1.1 is long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000 8143 1.1 is long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000 8144 1.1 is long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000 8145 1.1 is long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000 8146 1.1 is long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000 8147 1.1 is long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000 8148 1.1 is long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000 8149 1.1 is long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000 8150 1.1 is long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000 8151 1.1 is long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000 8152 1.1 is long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000 8153 1.1 is long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000 8154 1.1 is long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000 8155 1.1 is long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000 8156 1.1 is long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000 8157 1.1 is long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000 8158 1.1 is long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000 8159 1.1 is long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000 8160 1.1 is long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000 8161 1.1 is long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000 8162 1.1 is long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000 8163 1.1 is long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000 8164 1.1 is long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000 8165 1.1 is long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000 8166 1.1 is long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000 8167 1.1 is long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000 8168 1.1 is long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000 8169 1.1 is long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000 8170 1.1 is long 0x3FFE0000,0x94458094,0x45809446,0x00000000 8171 1.1 is long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000 8172 1.1 is long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000 8173 1.1 is long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000 8174 1.1 is long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000 8175 1.1 is long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000 8176 1.1 is long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000 8177 1.1 is long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000 8178 1.1 is long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000 8179 1.1 is long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000 8180 1.1 is long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000 8181 1.1 is long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000 8182 1.1 is long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000 8183 1.1 is long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000 8184 1.1 is long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000 8185 1.1 is long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000 8186 1.1 is long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000 8187 1.1 is long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000 8188 1.1 is long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000 8189 1.1 is long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000 8190 1.1 is long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000 8191 1.1 is long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000 8192 1.1 is long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000 8193 1.1 is long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000 8194 1.1 is long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000 8195 1.1 is long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000 8196 1.1 is long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000 8197 1.1 is long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000 8198 1.1 is long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000 8199 1.1 is long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000 8200 1.1 is long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000 8201 1.1 is long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000 8202 1.1 is long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000 8203 1.1 is long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000 8204 1.1 is long 0x3FFE0000,0x80808080,0x80808081,0x00000000 8205 1.1 is long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000 8206 1.1 is 8207 1.1 is set ADJK,L_SCR1 8208 1.1 is 8209 1.1 is set X,FP_SCR0 8210 1.1 is set XDCARE,X+2 8211 1.1 is set XFRAC,X+4 8212 1.1 is 8213 1.1 is set F,FP_SCR1 8214 1.1 is set FFRAC,F+4 8215 1.1 is 8216 1.1 is set KLOG2,FP_SCR0 8217 1.1 is 8218 1.1 is set SAVEU,FP_SCR0 8219 1.1 is 8220 1.1 is global slogn 8221 1.1 is #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S 8222 1.1 is slogn: 8223 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 8224 1.1 is mov.l &0x00000000,ADJK(%a6) 8225 1.1 is 8226 1.1 is LOGBGN: 8227 1.1 is #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS 8228 1.1 is #--A FINITE, NON-ZERO, NORMALIZED NUMBER. 8229 1.1 is 8230 1.1 is mov.l (%a0),%d1 8231 1.1 is mov.w 4(%a0),%d1 8232 1.1 is 8233 1.1 is mov.l (%a0),X(%a6) 8234 1.1 is mov.l 4(%a0),X+4(%a6) 8235 1.1 is mov.l 8(%a0),X+8(%a6) 8236 1.1 is 8237 1.1 is cmp.l %d1,&0 # CHECK IF X IS NEGATIVE 8238 1.1 is blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID 8239 1.1 is # X IS POSITIVE, CHECK IF X IS NEAR 1 8240 1.1 is cmp.l %d1,&0x3ffef07d # IS X < 15/16? 8241 1.1 is blt.b LOGMAIN # YES 8242 1.1 is cmp.l %d1,&0x3fff8841 # IS X > 17/16? 8243 1.1 is ble.w LOGNEAR1 # NO 8244 1.1 is 8245 1.1 is LOGMAIN: 8246 1.1 is #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1 8247 1.1 is 8248 1.1 is #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY. 8249 1.1 is #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1. 8250 1.1 is #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y) 8251 1.1 is #-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F). 8252 1.1 is #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING 8253 1.1 is #--LOG(1+U) CAN BE VERY EFFICIENT. 8254 1.1 is #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO 8255 1.1 is #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F. 8256 1.1 is 8257 1.1 is #--GET K, Y, F, AND ADDRESS OF 1/F. 8258 1.1 is asr.l &8,%d1 8259 1.1 is asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X 8260 1.1 is sub.l &0x3FFF,%d1 # THIS IS K 8261 1.1 is add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM. 8262 1.1 is lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F) 8263 1.1 is fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT 8264 1.1 is 8265 1.1 is #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F 8266 1.1 is mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X 8267 1.1 is mov.l XFRAC(%a6),FFRAC(%a6) 8268 1.1 is and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y 8269 1.1 is or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT 8270 1.1 is mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F 8271 1.1 is and.l &0x7E000000,%d1 8272 1.1 is asr.l &8,%d1 8273 1.1 is asr.l &8,%d1 8274 1.1 is asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT 8275 1.1 is add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F 8276 1.1 is 8277 1.1 is fmov.x X(%a6),%fp0 8278 1.1 is mov.l &0x3fff0000,F(%a6) 8279 1.1 is clr.l F+8(%a6) 8280 1.1 is fsub.x F(%a6),%fp0 # Y-F 8281 1.1 is fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY 8282 1.1 is #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K 8283 1.1 is #--REGISTERS SAVED: FPCR, FP1, FP2 8284 1.1 is 8285 1.1 is LP1CONT1: 8286 1.1 is #--AN RE-ENTRY POINT FOR LOGNP1 8287 1.1 is fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F 8288 1.1 is fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY 8289 1.1 is fmov.x %fp0,%fp2 8290 1.1 is fmul.x %fp2,%fp2 # FP2 IS V=U*U 8291 1.3 msaitoh fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMORY, FREE FP1 8292 1.1 is 8293 1.1 is #--LOG(1+U) IS APPROXIMATED BY 8294 1.1 is #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS 8295 1.1 is #--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))] 8296 1.1 is 8297 1.1 is fmov.x %fp2,%fp3 8298 1.1 is fmov.x %fp2,%fp1 8299 1.1 is 8300 1.1 is fmul.d LOGA6(%pc),%fp1 # V*A6 8301 1.1 is fmul.d LOGA5(%pc),%fp2 # V*A5 8302 1.1 is 8303 1.1 is fadd.d LOGA4(%pc),%fp1 # A4+V*A6 8304 1.1 is fadd.d LOGA3(%pc),%fp2 # A3+V*A5 8305 1.1 is 8306 1.1 is fmul.x %fp3,%fp1 # V*(A4+V*A6) 8307 1.1 is fmul.x %fp3,%fp2 # V*(A3+V*A5) 8308 1.1 is 8309 1.1 is fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6) 8310 1.1 is fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5) 8311 1.1 is 8312 1.1 is fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6)) 8313 1.1 is add.l &16,%a0 # ADDRESS OF LOG(F) 8314 1.1 is fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5)) 8315 1.1 is 8316 1.1 is fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6)) 8317 1.1 is fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5)) 8318 1.1 is 8319 1.1 is fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6)) 8320 1.1 is fmovm.x (%sp)+,&0x30 # RESTORE FP2-3 8321 1.1 is fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U) 8322 1.1 is 8323 1.1 is fmov.l %d0,%fpcr 8324 1.1 is fadd.x KLOG2(%a6),%fp0 # FINAL ADD 8325 1.1 is bra t_inx2 8326 1.1 is 8327 1.1 is 8328 1.1 is LOGNEAR1: 8329 1.1 is 8330 1.1 is # if the input is exactly equal to one, then exit through ld_pzero. 8331 1.1 is # if these 2 lines weren't here, the correct answer would be returned 8332 1.1 is # but the INEX2 bit would be set. 8333 1.1 is fcmp.b %fp0,&0x1 # is it equal to one? 8334 1.1 is fbeq.l ld_pzero # yes 8335 1.1 is 8336 1.1 is #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT. 8337 1.1 is fmov.x %fp0,%fp1 8338 1.1 is fsub.s one(%pc),%fp1 # FP1 IS X-1 8339 1.1 is fadd.s one(%pc),%fp0 # FP0 IS X+1 8340 1.1 is fadd.x %fp1,%fp1 # FP1 IS 2(X-1) 8341 1.1 is #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL 8342 1.1 is #--IN U, U = 2(X-1)/(X+1) = FP1/FP0 8343 1.1 is 8344 1.1 is LP1CONT2: 8345 1.1 is #--THIS IS AN RE-ENTRY POINT FOR LOGNP1 8346 1.1 is fdiv.x %fp0,%fp1 # FP1 IS U 8347 1.1 is fmovm.x &0xc,-(%sp) # SAVE FP2-3 8348 1.1 is #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3 8349 1.1 is #--LET V=U*U, W=V*V, CALCULATE 8350 1.1 is #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY 8351 1.1 is #--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] ) 8352 1.1 is fmov.x %fp1,%fp0 8353 1.1 is fmul.x %fp0,%fp0 # FP0 IS V 8354 1.1 is fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1 8355 1.1 is fmov.x %fp0,%fp1 8356 1.1 is fmul.x %fp1,%fp1 # FP1 IS W 8357 1.1 is 8358 1.1 is fmov.d LOGB5(%pc),%fp3 8359 1.1 is fmov.d LOGB4(%pc),%fp2 8360 1.1 is 8361 1.1 is fmul.x %fp1,%fp3 # W*B5 8362 1.1 is fmul.x %fp1,%fp2 # W*B4 8363 1.1 is 8364 1.1 is fadd.d LOGB3(%pc),%fp3 # B3+W*B5 8365 1.1 is fadd.d LOGB2(%pc),%fp2 # B2+W*B4 8366 1.1 is 8367 1.1 is fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED 8368 1.1 is 8369 1.1 is fmul.x %fp0,%fp2 # V*(B2+W*B4) 8370 1.1 is 8371 1.1 is fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5) 8372 1.1 is fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V 8373 1.1 is 8374 1.1 is fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED 8375 1.1 is fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED 8376 1.1 is 8377 1.1 is fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] ) 8378 1.1 is 8379 1.1 is fmov.l %d0,%fpcr 8380 1.1 is fadd.x SAVEU(%a6),%fp0 8381 1.1 is bra t_inx2 8382 1.1 is 8383 1.1 is #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID 8384 1.1 is LOGNEG: 8385 1.1 is bra t_operr 8386 1.1 is 8387 1.1 is global slognd 8388 1.1 is slognd: 8389 1.1 is #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT 8390 1.1 is 8391 1.1 is mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0 8392 1.1 is 8393 1.1 is #----normalize the input value by left shifting k bits (k to be determined 8394 1.1 is #----below), adjusting exponent and storing -k to ADJK 8395 1.1 is #----the value TWOTO100 is no longer needed. 8396 1.1 is #----Note that this code assumes the denormalized input is NON-ZERO. 8397 1.1 is 8398 1.1 is movm.l &0x3f00,-(%sp) # save some registers {d2-d7} 8399 1.1 is mov.l (%a0),%d3 # D3 is exponent of smallest norm. # 8400 1.1 is mov.l 4(%a0),%d4 8401 1.1 is mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X) 8402 1.1 is clr.l %d2 # D2 used for holding K 8403 1.1 is 8404 1.1 is tst.l %d4 8405 1.1 is bne.b Hi_not0 8406 1.1 is 8407 1.1 is Hi_0: 8408 1.1 is mov.l %d5,%d4 8409 1.1 is clr.l %d5 8410 1.1 is mov.l &32,%d2 8411 1.1 is clr.l %d6 8412 1.1 is bfffo %d4{&0:&32},%d6 8413 1.1 is lsl.l %d6,%d4 8414 1.1 is add.l %d6,%d2 # (D3,D4,D5) is normalized 8415 1.1 is 8416 1.1 is mov.l %d3,X(%a6) 8417 1.1 is mov.l %d4,XFRAC(%a6) 8418 1.1 is mov.l %d5,XFRAC+4(%a6) 8419 1.1 is neg.l %d2 8420 1.1 is mov.l %d2,ADJK(%a6) 8421 1.1 is fmov.x X(%a6),%fp0 8422 1.1 is movm.l (%sp)+,&0xfc # restore registers {d2-d7} 8423 1.1 is lea X(%a6),%a0 8424 1.1 is bra.w LOGBGN # begin regular log(X) 8425 1.1 is 8426 1.1 is Hi_not0: 8427 1.1 is clr.l %d6 8428 1.1 is bfffo %d4{&0:&32},%d6 # find first 1 8429 1.1 is mov.l %d6,%d2 # get k 8430 1.1 is lsl.l %d6,%d4 8431 1.1 is mov.l %d5,%d7 # a copy of D5 8432 1.1 is lsl.l %d6,%d5 8433 1.1 is neg.l %d6 8434 1.1 is add.l &32,%d6 8435 1.1 is lsr.l %d6,%d7 8436 1.1 is or.l %d7,%d4 # (D3,D4,D5) normalized 8437 1.1 is 8438 1.1 is mov.l %d3,X(%a6) 8439 1.1 is mov.l %d4,XFRAC(%a6) 8440 1.1 is mov.l %d5,XFRAC+4(%a6) 8441 1.1 is neg.l %d2 8442 1.1 is mov.l %d2,ADJK(%a6) 8443 1.1 is fmov.x X(%a6),%fp0 8444 1.1 is movm.l (%sp)+,&0xfc # restore registers {d2-d7} 8445 1.1 is lea X(%a6),%a0 8446 1.1 is bra.w LOGBGN # begin regular log(X) 8447 1.1 is 8448 1.1 is global slognp1 8449 1.1 is #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S 8450 1.1 is slognp1: 8451 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 8452 1.1 is fabs.x %fp0 # test magnitude 8453 1.1 is fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold 8454 1.1 is fbgt.w LP1REAL # if greater, continue 8455 1.1 is fmov.l %d0,%fpcr 8456 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 8457 1.1 is fmov.x (%a0),%fp0 # return signed argument 8458 1.1 is bra t_catch 8459 1.1 is 8460 1.1 is LP1REAL: 8461 1.1 is fmov.x (%a0),%fp0 # LOAD INPUT 8462 1.1 is mov.l &0x00000000,ADJK(%a6) 8463 1.1 is fmov.x %fp0,%fp1 # FP1 IS INPUT Z 8464 1.1 is fadd.s one(%pc),%fp0 # X := ROUND(1+Z) 8465 1.1 is fmov.x %fp0,X(%a6) 8466 1.1 is mov.w XFRAC(%a6),XDCARE(%a6) 8467 1.1 is mov.l X(%a6),%d1 8468 1.1 is cmp.l %d1,&0 8469 1.1 is ble.w LP1NEG0 # LOG OF ZERO OR -VE 8470 1.1 is cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]? 8471 1.1 is blt.w LOGMAIN 8472 1.1 is cmp.l %d1,&0x3fffc000 8473 1.1 is bgt.w LOGMAIN 8474 1.1 is #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z, 8475 1.1 is #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE, 8476 1.1 is #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z). 8477 1.1 is 8478 1.1 is LP1NEAR1: 8479 1.1 is #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16) 8480 1.1 is cmp.l %d1,&0x3ffef07d 8481 1.1 is blt.w LP1CARE 8482 1.1 is cmp.l %d1,&0x3fff8841 8483 1.1 is bgt.w LP1CARE 8484 1.1 is 8485 1.1 is LP1ONE16: 8486 1.1 is #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2) 8487 1.1 is #--WHERE U = 2Z/(2+Z) = 2Z/(1+X). 8488 1.1 is fadd.x %fp1,%fp1 # FP1 IS 2Z 8489 1.1 is fadd.s one(%pc),%fp0 # FP0 IS 1+X 8490 1.1 is #--U = FP1/FP0 8491 1.1 is bra.w LP1CONT2 8492 1.1 is 8493 1.1 is LP1CARE: 8494 1.1 is #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE 8495 1.1 is #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST 8496 1.1 is #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2], 8497 1.1 is #--THERE ARE ONLY TWO CASES. 8498 1.1 is #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z 8499 1.1 is #--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z 8500 1.1 is #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF 8501 1.1 is #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED. 8502 1.1 is 8503 1.1 is mov.l XFRAC(%a6),FFRAC(%a6) 8504 1.1 is and.l &0xFE000000,FFRAC(%a6) 8505 1.1 is or.l &0x01000000,FFRAC(%a6) # F OBTAINED 8506 1.1 is cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1 8507 1.1 is bge.b KISZERO 8508 1.1 is 8509 1.1 is KISNEG1: 8510 1.1 is fmov.s TWO(%pc),%fp0 8511 1.1 is mov.l &0x3fff0000,F(%a6) 8512 1.1 is clr.l F+8(%a6) 8513 1.1 is fsub.x F(%a6),%fp0 # 2-F 8514 1.1 is mov.l FFRAC(%a6),%d1 8515 1.1 is and.l &0x7E000000,%d1 8516 1.1 is asr.l &8,%d1 8517 1.1 is asr.l &8,%d1 8518 1.1 is asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F 8519 1.1 is fadd.x %fp1,%fp1 # GET 2Z 8520 1.1 is fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3} 8521 1.1 is fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z 8522 1.1 is lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F 8523 1.1 is add.l %d1,%a0 8524 1.1 is fmov.s negone(%pc),%fp1 # FP1 IS K = -1 8525 1.1 is bra.w LP1CONT1 8526 1.1 is 8527 1.1 is KISZERO: 8528 1.1 is fmov.s one(%pc),%fp0 8529 1.1 is mov.l &0x3fff0000,F(%a6) 8530 1.1 is clr.l F+8(%a6) 8531 1.1 is fsub.x F(%a6),%fp0 # 1-F 8532 1.1 is mov.l FFRAC(%a6),%d1 8533 1.1 is and.l &0x7E000000,%d1 8534 1.1 is asr.l &8,%d1 8535 1.1 is asr.l &8,%d1 8536 1.1 is asr.l &4,%d1 8537 1.1 is fadd.x %fp1,%fp0 # FP0 IS Y-F 8538 1.1 is fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3} 8539 1.1 is lea LOGTBL(%pc),%a0 8540 1.1 is add.l %d1,%a0 # A0 IS ADDRESS OF 1/F 8541 1.1 is fmov.s zero(%pc),%fp1 # FP1 IS K = 0 8542 1.1 is bra.w LP1CONT1 8543 1.1 is 8544 1.1 is LP1NEG0: 8545 1.1 is #--FPCR SAVED. D0 IS X IN COMPACT FORM. 8546 1.1 is cmp.l %d1,&0 8547 1.1 is blt.b LP1NEG 8548 1.1 is LP1ZERO: 8549 1.1 is fmov.s negone(%pc),%fp0 8550 1.1 is 8551 1.1 is fmov.l %d0,%fpcr 8552 1.1 is bra t_dz 8553 1.1 is 8554 1.1 is LP1NEG: 8555 1.1 is fmov.s zero(%pc),%fp0 8556 1.1 is 8557 1.1 is fmov.l %d0,%fpcr 8558 1.1 is bra t_operr 8559 1.1 is 8560 1.1 is global slognp1d 8561 1.1 is #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT 8562 1.1 is # Simply return the denorm 8563 1.1 is slognp1d: 8564 1.1 is bra t_extdnrm 8565 1.1 is 8566 1.1 is ######################################################################### 8567 1.1 is # satanh(): computes the inverse hyperbolic tangent of a norm input # 8568 1.1 is # satanhd(): computes the inverse hyperbolic tangent of a denorm input # 8569 1.1 is # # 8570 1.1 is # INPUT *************************************************************** # 8571 1.1 is # a0 = pointer to extended precision input # 8572 1.1 is # d0 = round precision,mode # 8573 1.1 is # # 8574 1.1 is # OUTPUT ************************************************************** # 8575 1.1 is # fp0 = arctanh(X) # 8576 1.1 is # # 8577 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 8578 1.1 is # The returned result is within 3 ulps in 64 significant bit, # 8579 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 8580 1.1 is # rounded to double precision. The result is provably monotonic # 8581 1.1 is # in double precision. # 8582 1.1 is # # 8583 1.1 is # ALGORITHM *********************************************************** # 8584 1.1 is # # 8585 1.1 is # ATANH # 8586 1.1 is # 1. If |X| >= 1, go to 3. # 8587 1.1 is # # 8588 1.1 is # 2. (|X| < 1) Calculate atanh(X) by # 8589 1.1 is # sgn := sign(X) # 8590 1.1 is # y := |X| # 8591 1.1 is # z := 2y/(1-y) # 8592 1.1 is # atanh(X) := sgn * (1/2) * logp1(z) # 8593 1.1 is # Exit. # 8594 1.1 is # # 8595 1.1 is # 3. If |X| > 1, go to 5. # 8596 1.1 is # # 8597 1.1 is # 4. (|X| = 1) Generate infinity with an appropriate sign and # 8598 1.1 is # divide-by-zero by # 8599 1.1 is # sgn := sign(X) # 8600 1.1 is # atan(X) := sgn / (+0). # 8601 1.1 is # Exit. # 8602 1.1 is # # 8603 1.1 is # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 8604 1.1 is # Exit. # 8605 1.1 is # # 8606 1.1 is ######################################################################### 8607 1.1 is 8608 1.1 is global satanh 8609 1.1 is satanh: 8610 1.1 is mov.l (%a0),%d1 8611 1.1 is mov.w 4(%a0),%d1 8612 1.1 is and.l &0x7FFFFFFF,%d1 8613 1.1 is cmp.l %d1,&0x3FFF8000 8614 1.1 is bge.b ATANHBIG 8615 1.1 is 8616 1.1 is #--THIS IS THE USUAL CASE, |X| < 1 8617 1.1 is #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z). 8618 1.1 is 8619 1.1 is fabs.x (%a0),%fp0 # Y = |X| 8620 1.1 is fmov.x %fp0,%fp1 8621 1.1 is fneg.x %fp1 # -Y 8622 1.1 is fadd.x %fp0,%fp0 # 2Y 8623 1.1 is fadd.s &0x3F800000,%fp1 # 1-Y 8624 1.1 is fdiv.x %fp1,%fp0 # 2Y/(1-Y) 8625 1.1 is mov.l (%a0),%d1 8626 1.1 is and.l &0x80000000,%d1 8627 1.1 is or.l &0x3F000000,%d1 # SIGN(X)*HALF 8628 1.1 is mov.l %d1,-(%sp) 8629 1.1 is 8630 1.1 is mov.l %d0,-(%sp) # save rnd prec,mode 8631 1.1 is clr.l %d0 # pass ext prec,RN 8632 1.1 is fmovm.x &0x01,-(%sp) # save Z on stack 8633 1.1 is lea (%sp),%a0 # pass ptr to Z 8634 1.1 is bsr slognp1 # LOG1P(Z) 8635 1.1 is add.l &0xc,%sp # clear Z from stack 8636 1.1 is 8637 1.1 is mov.l (%sp)+,%d0 # fetch old prec,mode 8638 1.1 is fmov.l %d0,%fpcr # load it 8639 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 8640 1.1 is fmul.s (%sp)+,%fp0 8641 1.1 is bra t_catch 8642 1.1 is 8643 1.1 is ATANHBIG: 8644 1.1 is fabs.x (%a0),%fp0 # |X| 8645 1.1 is fcmp.s %fp0,&0x3F800000 8646 1.1 is fbgt t_operr 8647 1.1 is bra t_dz 8648 1.1 is 8649 1.1 is global satanhd 8650 1.1 is #--ATANH(X) = X FOR DENORMALIZED X 8651 1.1 is satanhd: 8652 1.1 is bra t_extdnrm 8653 1.1 is 8654 1.1 is ######################################################################### 8655 1.1 is # slog10(): computes the base-10 logarithm of a normalized input # 8656 1.1 is # slog10d(): computes the base-10 logarithm of a denormalized input # 8657 1.1 is # slog2(): computes the base-2 logarithm of a normalized input # 8658 1.1 is # slog2d(): computes the base-2 logarithm of a denormalized input # 8659 1.1 is # # 8660 1.1 is # INPUT *************************************************************** # 8661 1.1 is # a0 = pointer to extended precision input # 8662 1.1 is # d0 = round precision,mode # 8663 1.1 is # # 8664 1.1 is # OUTPUT ************************************************************** # 8665 1.1 is # fp0 = log_10(X) or log_2(X) # 8666 1.1 is # # 8667 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 8668 1.1 is # The returned result is within 1.7 ulps in 64 significant bit, # 8669 1.1 is # i.e. within 0.5003 ulp to 53 bits if the result is subsequently # 8670 1.1 is # rounded to double precision. The result is provably monotonic # 8671 1.1 is # in double precision. # 8672 1.1 is # # 8673 1.1 is # ALGORITHM *********************************************************** # 8674 1.1 is # # 8675 1.1 is # slog10d: # 8676 1.1 is # # 8677 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation # 8678 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8679 1.1 is # Notes: Default means round-to-nearest mode, no floating-point # 8680 1.1 is # traps, and precision control = double extended. # 8681 1.1 is # # 8682 1.1 is # Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 8683 1.1 is # Notes: Even if X is denormalized, log(X) is always normalized. # 8684 1.1 is # # 8685 1.1 is # Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 8686 1.1 is # 2.1 Restore the user FPCR # 8687 1.1 is # 2.2 Return ans := Y * INV_L10. # 8688 1.1 is # # 8689 1.1 is # slog10: # 8690 1.1 is # # 8691 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation # 8692 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8693 1.1 is # Notes: Default means round-to-nearest mode, no floating-point # 8694 1.1 is # traps, and precision control = double extended. # 8695 1.1 is # # 8696 1.1 is # Step 1. Call sLogN to obtain Y = log(X), the natural log of X. # 8697 1.1 is # # 8698 1.1 is # Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 8699 1.1 is # 2.1 Restore the user FPCR # 8700 1.1 is # 2.2 Return ans := Y * INV_L10. # 8701 1.1 is # # 8702 1.1 is # sLog2d: # 8703 1.1 is # # 8704 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation # 8705 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8706 1.1 is # Notes: Default means round-to-nearest mode, no floating-point # 8707 1.1 is # traps, and precision control = double extended. # 8708 1.1 is # # 8709 1.1 is # Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 8710 1.1 is # Notes: Even if X is denormalized, log(X) is always normalized. # 8711 1.1 is # # 8712 1.1 is # Step 2. Compute log_10(X) = log(X) * (1/log(2)). # 8713 1.1 is # 2.1 Restore the user FPCR # 8714 1.1 is # 2.2 Return ans := Y * INV_L2. # 8715 1.1 is # # 8716 1.1 is # sLog2: # 8717 1.1 is # # 8718 1.1 is # Step 0. If X < 0, create a NaN and raise the invalid operation # 8719 1.1 is # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8720 1.1 is # Notes: Default means round-to-nearest mode, no floating-point # 8721 1.1 is # traps, and precision control = double extended. # 8722 1.1 is # # 8723 1.1 is # Step 1. If X is not an integer power of two, i.e., X != 2^k, # 8724 1.1 is # go to Step 3. # 8725 1.1 is # # 8726 1.1 is # Step 2. Return k. # 8727 1.1 is # 2.1 Get integer k, X = 2^k. # 8728 1.1 is # 2.2 Restore the user FPCR. # 8729 1.1 is # 2.3 Return ans := convert-to-double-extended(k). # 8730 1.1 is # # 8731 1.1 is # Step 3. Call sLogN to obtain Y = log(X), the natural log of X. # 8732 1.1 is # # 8733 1.1 is # Step 4. Compute log_2(X) = log(X) * (1/log(2)). # 8734 1.1 is # 4.1 Restore the user FPCR # 8735 1.1 is # 4.2 Return ans := Y * INV_L2. # 8736 1.1 is # # 8737 1.1 is ######################################################################### 8738 1.1 is 8739 1.1 is INV_L10: 8740 1.1 is long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 8741 1.1 is 8742 1.1 is INV_L2: 8743 1.1 is long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 8744 1.1 is 8745 1.1 is global slog10 8746 1.1 is #--entry point for Log10(X), X is normalized 8747 1.1 is slog10: 8748 1.1 is fmov.b &0x1,%fp0 8749 1.1 is fcmp.x %fp0,(%a0) # if operand == 1, 8750 1.1 is fbeq.l ld_pzero # return an EXACT zero 8751 1.1 is 8752 1.1 is mov.l (%a0),%d1 8753 1.1 is blt.w invalid 8754 1.1 is mov.l %d0,-(%sp) 8755 1.1 is clr.l %d0 8756 1.1 is bsr slogn # log(X), X normal. 8757 1.1 is fmov.l (%sp)+,%fpcr 8758 1.1 is fmul.x INV_L10(%pc),%fp0 8759 1.1 is bra t_inx2 8760 1.1 is 8761 1.1 is global slog10d 8762 1.1 is #--entry point for Log10(X), X is denormalized 8763 1.1 is slog10d: 8764 1.1 is mov.l (%a0),%d1 8765 1.1 is blt.w invalid 8766 1.1 is mov.l %d0,-(%sp) 8767 1.1 is clr.l %d0 8768 1.1 is bsr slognd # log(X), X denorm. 8769 1.1 is fmov.l (%sp)+,%fpcr 8770 1.1 is fmul.x INV_L10(%pc),%fp0 8771 1.1 is bra t_minx2 8772 1.1 is 8773 1.1 is global slog2 8774 1.1 is #--entry point for Log2(X), X is normalized 8775 1.1 is slog2: 8776 1.1 is mov.l (%a0),%d1 8777 1.1 is blt.w invalid 8778 1.1 is 8779 1.1 is mov.l 8(%a0),%d1 8780 1.1 is bne.b continue # X is not 2^k 8781 1.1 is 8782 1.1 is mov.l 4(%a0),%d1 8783 1.1 is and.l &0x7FFFFFFF,%d1 8784 1.1 is bne.b continue 8785 1.1 is 8786 1.1 is #--X = 2^k. 8787 1.1 is mov.w (%a0),%d1 8788 1.1 is and.l &0x00007FFF,%d1 8789 1.1 is sub.l &0x3FFF,%d1 8790 1.1 is beq.l ld_pzero 8791 1.1 is fmov.l %d0,%fpcr 8792 1.1 is fmov.l %d1,%fp0 8793 1.1 is bra t_inx2 8794 1.1 is 8795 1.1 is continue: 8796 1.1 is mov.l %d0,-(%sp) 8797 1.1 is clr.l %d0 8798 1.1 is bsr slogn # log(X), X normal. 8799 1.1 is fmov.l (%sp)+,%fpcr 8800 1.1 is fmul.x INV_L2(%pc),%fp0 8801 1.1 is bra t_inx2 8802 1.1 is 8803 1.1 is invalid: 8804 1.1 is bra t_operr 8805 1.1 is 8806 1.1 is global slog2d 8807 1.1 is #--entry point for Log2(X), X is denormalized 8808 1.1 is slog2d: 8809 1.1 is mov.l (%a0),%d1 8810 1.1 is blt.w invalid 8811 1.1 is mov.l %d0,-(%sp) 8812 1.1 is clr.l %d0 8813 1.1 is bsr slognd # log(X), X denorm. 8814 1.1 is fmov.l (%sp)+,%fpcr 8815 1.1 is fmul.x INV_L2(%pc),%fp0 8816 1.1 is bra t_minx2 8817 1.1 is 8818 1.1 is ######################################################################### 8819 1.1 is # stwotox(): computes 2**X for a normalized input # 8820 1.1 is # stwotoxd(): computes 2**X for a denormalized input # 8821 1.1 is # stentox(): computes 10**X for a normalized input # 8822 1.1 is # stentoxd(): computes 10**X for a denormalized input # 8823 1.1 is # # 8824 1.1 is # INPUT *************************************************************** # 8825 1.1 is # a0 = pointer to extended precision input # 8826 1.1 is # d0 = round precision,mode # 8827 1.1 is # # 8828 1.1 is # OUTPUT ************************************************************** # 8829 1.1 is # fp0 = 2**X or 10**X # 8830 1.1 is # # 8831 1.1 is # ACCURACY and MONOTONICITY ******************************************* # 8832 1.1 is # The returned result is within 2 ulps in 64 significant bit, # 8833 1.1 is # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 8834 1.1 is # rounded to double precision. The result is provably monotonic # 8835 1.1 is # in double precision. # 8836 1.1 is # # 8837 1.1 is # ALGORITHM *********************************************************** # 8838 1.1 is # # 8839 1.1 is # twotox # 8840 1.1 is # 1. If |X| > 16480, go to ExpBig. # 8841 1.1 is # # 8842 1.1 is # 2. If |X| < 2**(-70), go to ExpSm. # 8843 1.1 is # # 8844 1.1 is # 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore # 8845 1.1 is # decompose N as # 8846 1.1 is # N = 64(M + M') + j, j = 0,1,2,...,63. # 8847 1.1 is # # 8848 1.1 is # 4. Overwrite r := r * log2. Then # 8849 1.1 is # 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 8850 1.1 is # Go to expr to compute that expression. # 8851 1.1 is # # 8852 1.1 is # tentox # 8853 1.1 is # 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. # 8854 1.1 is # # 8855 1.1 is # 2. If |X| < 2**(-70), go to ExpSm. # 8856 1.1 is # # 8857 1.1 is # 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set # 8858 1.1 is # N := round-to-int(y). Decompose N as # 8859 1.1 is # N = 64(M + M') + j, j = 0,1,2,...,63. # 8860 1.1 is # # 8861 1.1 is # 4. Define r as # 8862 1.1 is # r := ((X - N*L1)-N*L2) * L10 # 8863 1.1 is # where L1, L2 are the leading and trailing parts of # 8864 1.1 is # log_10(2)/64 and L10 is the natural log of 10. Then # 8865 1.1 is # 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 8866 1.1 is # Go to expr to compute that expression. # 8867 1.1 is # # 8868 1.1 is # expr # 8869 1.1 is # 1. Fetch 2**(j/64) from table as Fact1 and Fact2. # 8870 1.1 is # # 8871 1.1 is # 2. Overwrite Fact1 and Fact2 by # 8872 1.1 is # Fact1 := 2**(M) * Fact1 # 8873 1.1 is # Fact2 := 2**(M) * Fact2 # 8874 1.1 is # Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). # 8875 1.1 is # # 8876 1.1 is # 3. Calculate P where 1 + P approximates exp(r): # 8877 1.1 is # P = r + r*r*(A1+r*(A2+...+r*A5)). # 8878 1.1 is # # 8879 1.1 is # 4. Let AdjFact := 2**(M'). Return # 8880 1.1 is # AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). # 8881 1.1 is # Exit. # 8882 1.1 is # # 8883 1.1 is # ExpBig # 8884 1.1 is # 1. Generate overflow by Huge * Huge if X > 0; otherwise, # 8885 1.1 is # generate underflow by Tiny * Tiny. # 8886 1.1 is # # 8887 1.1 is # ExpSm # 8888 1.1 is # 1. Return 1 + X. # 8889 1.1 is # # 8890 1.1 is ######################################################################### 8891 1.1 is 8892 1.1 is L2TEN64: 8893 1.1 is long 0x406A934F,0x0979A371 # 64LOG10/LOG2 8894 1.1 is L10TWO1: 8895 1.1 is long 0x3F734413,0x509F8000 # LOG2/64LOG10 8896 1.1 is 8897 1.1 is L10TWO2: 8898 1.1 is long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000 8899 1.1 is 8900 1.1 is LOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000 8901 1.1 is 8902 1.1 is LOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 8903 1.1 is 8904 1.1 is EXPA5: long 0x3F56C16D,0x6F7BD0B2 8905 1.1 is EXPA4: long 0x3F811112,0x302C712C 8906 1.1 is EXPA3: long 0x3FA55555,0x55554CC1 8907 1.1 is EXPA2: long 0x3FC55555,0x55554A54 8908 1.1 is EXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000 8909 1.1 is 8910 1.1 is TEXPTBL: 8911 1.1 is long 0x3FFF0000,0x80000000,0x00000000,0x3F738000 8912 1.1 is long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA 8913 1.1 is long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9 8914 1.1 is long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9 8915 1.1 is long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA 8916 1.1 is long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C 8917 1.1 is long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1 8918 1.1 is long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA 8919 1.1 is long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373 8920 1.1 is long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670 8921 1.1 is long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700 8922 1.1 is long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0 8923 1.1 is long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D 8924 1.1 is long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319 8925 1.1 is long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B 8926 1.1 is long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5 8927 1.1 is long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A 8928 1.1 is long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B 8929 1.1 is long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF 8930 1.1 is long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA 8931 1.1 is long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD 8932 1.1 is long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E 8933 1.1 is long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B 8934 1.1 is long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB 8935 1.1 is long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB 8936 1.1 is long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274 8937 1.1 is long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C 8938 1.1 is long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00 8939 1.1 is long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301 8940 1.1 is long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367 8941 1.1 is long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F 8942 1.1 is long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C 8943 1.1 is long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB 8944 1.1 is long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB 8945 1.1 is long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C 8946 1.1 is long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA 8947 1.1 is long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD 8948 1.1 is long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51 8949 1.1 is long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A 8950 1.1 is long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2 8951 1.1 is long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB 8952 1.1 is long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17 8953 1.1 is long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C 8954 1.1 is long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8 8955 1.1 is long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53 8956 1.1 is long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE 8957 1.1 is long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124 8958 1.1 is long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243 8959 1.1 is long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A 8960 1.1 is long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61 8961 1.1 is long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610 8962 1.1 is long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1 8963 1.1 is long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12 8964 1.1 is long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE 8965 1.1 is long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4 8966 1.1 is long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F 8967 1.1 is long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A 8968 1.1 is long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A 8969 1.1 is long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC 8970 1.1 is long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F 8971 1.1 is long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A 8972 1.1 is long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795 8973 1.1 is long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B 8974 1.1 is long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581 8975 1.1 is 8976 1.1 is set INT,L_SCR1 8977 1.1 is 8978 1.1 is set X,FP_SCR0 8979 1.1 is set XDCARE,X+2 8980 1.1 is set XFRAC,X+4 8981 1.1 is 8982 1.1 is set ADJFACT,FP_SCR0 8983 1.1 is 8984 1.1 is set FACT1,FP_SCR0 8985 1.1 is set FACT1HI,FACT1+4 8986 1.1 is set FACT1LOW,FACT1+8 8987 1.1 is 8988 1.1 is set FACT2,FP_SCR1 8989 1.1 is set FACT2HI,FACT2+4 8990 1.1 is set FACT2LOW,FACT2+8 8991 1.1 is 8992 1.1 is global stwotox 8993 1.1 is #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 8994 1.1 is stwotox: 8995 1.1 is fmovm.x (%a0),&0x80 # LOAD INPUT 8996 1.1 is 8997 1.1 is mov.l (%a0),%d1 8998 1.1 is mov.w 4(%a0),%d1 8999 1.1 is fmov.x %fp0,X(%a6) 9000 1.1 is and.l &0x7FFFFFFF,%d1 9001 1.1 is 9002 1.1 is cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 9003 1.1 is bge.b TWOOK1 9004 1.1 is bra.w EXPBORS 9005 1.1 is 9006 1.1 is TWOOK1: 9007 1.1 is cmp.l %d1,&0x400D80C0 # |X| > 16480? 9008 1.1 is ble.b TWOMAIN 9009 1.1 is bra.w EXPBORS 9010 1.1 is 9011 1.1 is TWOMAIN: 9012 1.1 is #--USUAL CASE, 2^(-70) <= |X| <= 16480 9013 1.1 is 9014 1.1 is fmov.x %fp0,%fp1 9015 1.1 is fmul.s &0x42800000,%fp1 # 64 * X 9016 1.1 is fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X) 9017 1.1 is mov.l %d2,-(%sp) 9018 1.1 is lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 9019 1.1 is fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 9020 1.1 is mov.l INT(%a6),%d1 9021 1.1 is mov.l %d1,%d2 9022 1.1 is and.l &0x3F,%d1 # D0 IS J 9023 1.1 is asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 9024 1.1 is add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 9025 1.1 is asr.l &6,%d2 # d2 IS L, N = 64L + J 9026 1.1 is mov.l %d2,%d1 9027 1.1 is asr.l &1,%d1 # D0 IS M 9028 1.1 is sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 9029 1.1 is add.l &0x3FFF,%d2 9030 1.1 is 9031 1.1 is #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 9032 1.1 is #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 9033 1.1 is #--ADJFACT = 2^(M'). 9034 1.1 is #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 9035 1.1 is 9036 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3 9037 1.1 is 9038 1.1 is fmul.s &0x3C800000,%fp1 # (1/64)*N 9039 1.1 is mov.l (%a1)+,FACT1(%a6) 9040 1.1 is mov.l (%a1)+,FACT1HI(%a6) 9041 1.1 is mov.l (%a1)+,FACT1LOW(%a6) 9042 1.1 is mov.w (%a1)+,FACT2(%a6) 9043 1.1 is 9044 1.1 is fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X) 9045 1.1 is 9046 1.1 is mov.w (%a1)+,FACT2HI(%a6) 9047 1.1 is clr.w FACT2HI+2(%a6) 9048 1.1 is clr.l FACT2LOW(%a6) 9049 1.1 is add.w %d1,FACT1(%a6) 9050 1.1 is fmul.x LOG2(%pc),%fp0 # FP0 IS R 9051 1.1 is add.w %d1,FACT2(%a6) 9052 1.1 is 9053 1.1 is bra.w expr 9054 1.1 is 9055 1.1 is EXPBORS: 9056 1.1 is #--FPCR, D0 SAVED 9057 1.1 is cmp.l %d1,&0x3FFF8000 9058 1.1 is bgt.b TEXPBIG 9059 1.1 is 9060 1.1 is #--|X| IS SMALL, RETURN 1 + X 9061 1.1 is 9062 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode 9063 1.1 is fadd.s &0x3F800000,%fp0 # RETURN 1 + X 9064 1.1 is bra t_pinx2 9065 1.1 is 9066 1.1 is TEXPBIG: 9067 1.1 is #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW 9068 1.1 is #--REGISTERS SAVE SO FAR ARE FPCR AND D0 9069 1.1 is mov.l X(%a6),%d1 9070 1.1 is cmp.l %d1,&0 9071 1.1 is blt.b EXPNEG 9072 1.1 is 9073 1.1 is bra t_ovfl2 # t_ovfl expects positive value 9074 1.1 is 9075 1.1 is EXPNEG: 9076 1.1 is bra t_unfl2 # t_unfl expects positive value 9077 1.1 is 9078 1.1 is global stwotoxd 9079 1.1 is stwotoxd: 9080 1.1 is #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT 9081 1.1 is 9082 1.1 is fmov.l %d0,%fpcr # set user's rounding mode/precision 9083 1.1 is fmov.s &0x3F800000,%fp0 # RETURN 1 + X 9084 1.1 is mov.l (%a0),%d1 9085 1.1 is or.l &0x00800001,%d1 9086 1.1 is fadd.s %d1,%fp0 9087 1.1 is bra t_pinx2 9088 1.1 is 9089 1.1 is global stentox 9090 1.1 is #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 9091 1.1 is stentox: 9092 1.1 is fmovm.x (%a0),&0x80 # LOAD INPUT 9093 1.1 is 9094 1.1 is mov.l (%a0),%d1 9095 1.1 is mov.w 4(%a0),%d1 9096 1.1 is fmov.x %fp0,X(%a6) 9097 1.1 is and.l &0x7FFFFFFF,%d1 9098 1.1 is 9099 1.1 is cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 9100 1.1 is bge.b TENOK1 9101 1.1 is bra.w EXPBORS 9102 1.1 is 9103 1.1 is TENOK1: 9104 1.1 is cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ? 9105 1.1 is ble.b TENMAIN 9106 1.1 is bra.w EXPBORS 9107 1.1 is 9108 1.1 is TENMAIN: 9109 1.1 is #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10 9110 1.1 is 9111 1.1 is fmov.x %fp0,%fp1 9112 1.1 is fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2 9113 1.1 is fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2) 9114 1.1 is mov.l %d2,-(%sp) 9115 1.1 is lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 9116 1.1 is fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 9117 1.1 is mov.l INT(%a6),%d1 9118 1.1 is mov.l %d1,%d2 9119 1.1 is and.l &0x3F,%d1 # D0 IS J 9120 1.1 is asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 9121 1.1 is add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 9122 1.1 is asr.l &6,%d2 # d2 IS L, N = 64L + J 9123 1.1 is mov.l %d2,%d1 9124 1.1 is asr.l &1,%d1 # D0 IS M 9125 1.1 is sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 9126 1.1 is add.l &0x3FFF,%d2 9127 1.1 is 9128 1.1 is #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 9129 1.1 is #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 9130 1.1 is #--ADJFACT = 2^(M'). 9131 1.1 is #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 9132 1.1 is fmovm.x &0x0c,-(%sp) # save fp2/fp3 9133 1.1 is 9134 1.1 is fmov.x %fp1,%fp2 9135 1.1 is 9136 1.1 is fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD 9137 1.1 is mov.l (%a1)+,FACT1(%a6) 9138 1.1 is 9139 1.1 is fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL 9140 1.1 is 9141 1.1 is mov.l (%a1)+,FACT1HI(%a6) 9142 1.1 is mov.l (%a1)+,FACT1LOW(%a6) 9143 1.1 is fsub.x %fp1,%fp0 # X - N L_LEAD 9144 1.1 is mov.w (%a1)+,FACT2(%a6) 9145 1.1 is 9146 1.1 is fsub.x %fp2,%fp0 # X - N L_TRAIL 9147 1.1 is 9148 1.1 is mov.w (%a1)+,FACT2HI(%a6) 9149 1.1 is clr.w FACT2HI+2(%a6) 9150 1.1 is clr.l FACT2LOW(%a6) 9151 1.1 is 9152 1.1 is fmul.x LOG10(%pc),%fp0 # FP0 IS R 9153 1.1 is add.w %d1,FACT1(%a6) 9154 1.1 is add.w %d1,FACT2(%a6) 9155 1.1 is 9156 1.1 is expr: 9157 1.1 is #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN. 9158 1.1 is #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64). 9159 1.1 is #--FP0 IS R. THE FOLLOWING CODE COMPUTES 9160 1.1 is #-- 2**(M'+M) * 2**(J/64) * EXP(R) 9161 1.1 is 9162 1.1 is fmov.x %fp0,%fp1 9163 1.1 is fmul.x %fp1,%fp1 # FP1 IS S = R*R 9164 1.1 is 9165 1.1 is fmov.d EXPA5(%pc),%fp2 # FP2 IS A5 9166 1.1 is fmov.d EXPA4(%pc),%fp3 # FP3 IS A4 9167 1.1 is 9168 1.1 is fmul.x %fp1,%fp2 # FP2 IS S*A5 9169 1.1 is fmul.x %fp1,%fp3 # FP3 IS S*A4 9170 1.1 is 9171 1.1 is fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5 9172 1.1 is fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4 9173 1.1 is 9174 1.1 is fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5) 9175 1.1 is fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4) 9176 1.1 is 9177 1.1 is fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5) 9178 1.1 is fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4) 9179 1.1 is 9180 1.1 is fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5)) 9181 1.1 is fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4) 9182 1.1 is fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1 9183 1.1 is 9184 1.1 is fmovm.x (%sp)+,&0x30 # restore fp2/fp3 9185 1.1 is 9186 1.1 is #--FINAL RECONSTRUCTION PROCESS 9187 1.1 is #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1) - (1 OR 0) 9188 1.1 is 9189 1.1 is fmul.x FACT1(%a6),%fp0 9190 1.1 is fadd.x FACT2(%a6),%fp0 9191 1.1 is fadd.x FACT1(%a6),%fp0 9192 1.1 is 9193 1.1 is fmov.l %d0,%fpcr # restore users round prec,mode 9194 1.1 is mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT 9195 1.1 is mov.l (%sp)+,%d2 9196 1.1 is mov.l &0x80000000,ADJFACT+4(%a6) 9197 1.1 is clr.l ADJFACT+8(%a6) 9198 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 9199 1.1 is fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT 9200 1.1 is bra t_catch 9201 1.1 is 9202 1.1 is global stentoxd 9203 1.1 is stentoxd: 9204 1.1 is #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT 9205 1.1 is 9206 1.1 is fmov.l %d0,%fpcr # set user's rounding mode/precision 9207 1.1 is fmov.s &0x3F800000,%fp0 # RETURN 1 + X 9208 1.1 is mov.l (%a0),%d1 9209 1.1 is or.l &0x00800001,%d1 9210 1.1 is fadd.s %d1,%fp0 9211 1.1 is bra t_pinx2 9212 1.1 is 9213 1.1 is ######################################################################### 9214 1.1 is # sscale(): computes the destination operand scaled by the source # 9215 1.1 is # operand. If the absoulute value of the source operand is # 9216 1.1 is # >= 2^14, an overflow or underflow is returned. # 9217 1.1 is # # 9218 1.1 is # INPUT *************************************************************** # 9219 1.1 is # a0 = pointer to double-extended source operand X # 9220 1.1 is # a1 = pointer to double-extended destination operand Y # 9221 1.1 is # # 9222 1.1 is # OUTPUT ************************************************************** # 9223 1.1 is # fp0 = scale(X,Y) # 9224 1.1 is # # 9225 1.1 is ######################################################################### 9226 1.1 is 9227 1.1 is set SIGN, L_SCR1 9228 1.1 is 9229 1.1 is global sscale 9230 1.1 is sscale: 9231 1.1 is mov.l %d0,-(%sp) # store off ctrl bits for now 9232 1.1 is 9233 1.1 is mov.w DST_EX(%a1),%d1 # get dst exponent 9234 1.1 is smi.b SIGN(%a6) # use SIGN to hold dst sign 9235 1.1 is andi.l &0x00007fff,%d1 # strip sign from dst exp 9236 1.1 is 9237 1.1 is mov.w SRC_EX(%a0),%d0 # check src bounds 9238 1.1 is andi.w &0x7fff,%d0 # clr src sign bit 9239 1.1 is cmpi.w %d0,&0x3fff # is src ~ ZERO? 9240 1.1 is blt.w src_small # yes 9241 1.1 is cmpi.w %d0,&0x400c # no; is src too big? 9242 1.1 is bgt.w src_out # yes 9243 1.1 is 9244 1.1 is # 9245 1.1 is # Source is within 2^14 range. 9246 1.1 is # 9247 1.1 is src_ok: 9248 1.1 is fintrz.x SRC(%a0),%fp0 # calc int of src 9249 1.1 is fmov.l %fp0,%d0 # int src to d0 9250 1.1 is # don't want any accrued bits from the fintrz showing up later since 9251 1.1 is # we may need to read the fpsr for the last fp op in t_catch2(). 9252 1.1 is fmov.l &0x0,%fpsr 9253 1.1 is 9254 1.1 is tst.b DST_HI(%a1) # is dst denormalized? 9255 1.1 is bmi.b sok_norm 9256 1.1 is 9257 1.1 is # the dst is a DENORM. normalize the DENORM and add the adjustment to 9258 1.1 is # the src value. then, jump to the norm part of the routine. 9259 1.1 is sok_dnrm: 9260 1.1 is mov.l %d0,-(%sp) # save src for now 9261 1.1 is 9262 1.1 is mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy 9263 1.1 is mov.l DST_HI(%a1),FP_SCR0_HI(%a6) 9264 1.1 is mov.l DST_LO(%a1),FP_SCR0_LO(%a6) 9265 1.1 is 9266 1.1 is lea FP_SCR0(%a6),%a0 # pass ptr to DENORM 9267 1.1 is bsr.l norm # normalize the DENORM 9268 1.1 is neg.l %d0 9269 1.1 is add.l (%sp)+,%d0 # add adjustment to src 9270 1.1 is 9271 1.1 is fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM 9272 1.1 is 9273 1.1 is cmpi.w %d0,&-0x3fff # is the shft amt really low? 9274 1.1 is bge.b sok_norm2 # thank goodness no 9275 1.1 is 9276 1.1 is # the multiply factor that we're trying to create should be a denorm 9277 1.1 is # for the multiply to work. therefore, we're going to actually do a 9278 1.1 is # multiply with a denorm which will cause an unimplemented data type 9279 1.1 is # exception to be put into the machine which will be caught and corrected 9280 1.1 is # later. we don't do this with the DENORMs above because this method 9281 1.1 is # is slower. but, don't fret, I don't see it being used much either. 9282 1.1 is fmov.l (%sp)+,%fpcr # restore user fpcr 9283 1.1 is mov.l &0x80000000,%d1 # load normalized mantissa 9284 1.1 is subi.l &-0x3fff,%d0 # how many should we shift? 9285 1.1 is neg.l %d0 # make it positive 9286 1.1 is cmpi.b %d0,&0x20 # is it > 32? 9287 1.1 is bge.b sok_dnrm_32 # yes 9288 1.1 is lsr.l %d0,%d1 # no; bit stays in upper lw 9289 1.1 is clr.l -(%sp) # insert zero low mantissa 9290 1.1 is mov.l %d1,-(%sp) # insert new high mantissa 9291 1.1 is clr.l -(%sp) # make zero exponent 9292 1.1 is bra.b sok_norm_cont 9293 1.1 is sok_dnrm_32: 9294 1.1 is subi.b &0x20,%d0 # get shift count 9295 1.1 is lsr.l %d0,%d1 # make low mantissa longword 9296 1.1 is mov.l %d1,-(%sp) # insert new low mantissa 9297 1.1 is clr.l -(%sp) # insert zero high mantissa 9298 1.1 is clr.l -(%sp) # make zero exponent 9299 1.1 is bra.b sok_norm_cont 9300 1.1 is 9301 1.1 is # the src will force the dst to a DENORM value or worse. so, let's 9302 1.1 is # create an fp multiply that will create the result. 9303 1.1 is sok_norm: 9304 1.1 is fmovm.x DST(%a1),&0x80 # load fp0 with normalized src 9305 1.1 is sok_norm2: 9306 1.1 is fmov.l (%sp)+,%fpcr # restore user fpcr 9307 1.1 is 9308 1.1 is addi.w &0x3fff,%d0 # turn src amt into exp value 9309 1.1 is swap %d0 # put exponent in high word 9310 1.1 is clr.l -(%sp) # insert new exponent 9311 1.1 is mov.l &0x80000000,-(%sp) # insert new high mantissa 9312 1.1 is mov.l %d0,-(%sp) # insert new lo mantissa 9313 1.1 is 9314 1.1 is sok_norm_cont: 9315 1.1 is fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2 9316 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 9317 1.1 is fmul.x (%sp)+,%fp0 # do the multiply 9318 1.1 is bra t_catch2 # catch any exceptions 9319 1.1 is 9320 1.1 is # 9321 1.1 is # Source is outside of 2^14 range. Test the sign and branch 9322 1.1 is # to the appropriate exception handler. 9323 1.1 is # 9324 1.1 is src_out: 9325 1.1 is mov.l (%sp)+,%d0 # restore ctrl bits 9326 1.1 is exg %a0,%a1 # swap src,dst ptrs 9327 1.1 is tst.b SRC_EX(%a1) # is src negative? 9328 1.1 is bmi t_unfl # yes; underflow 9329 1.1 is bra t_ovfl_sc # no; overflow 9330 1.1 is 9331 1.1 is # 9332 1.1 is # The source input is below 1, so we check for denormalized numbers 9333 1.1 is # and set unfl. 9334 1.1 is # 9335 1.1 is src_small: 9336 1.1 is tst.b DST_HI(%a1) # is dst denormalized? 9337 1.1 is bpl.b ssmall_done # yes 9338 1.1 is 9339 1.1 is mov.l (%sp)+,%d0 9340 1.1 is fmov.l %d0,%fpcr # no; load control bits 9341 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 9342 1.1 is fmov.x DST(%a1),%fp0 # simply return dest 9343 1.1 is bra t_catch2 9344 1.1 is ssmall_done: 9345 1.1 is mov.l (%sp)+,%d0 # load control bits into d1 9346 1.1 is mov.l %a1,%a0 # pass ptr to dst 9347 1.1 is bra t_resdnrm 9348 1.1 is 9349 1.1 is ######################################################################### 9350 1.1 is # smod(): computes the fp MOD of the input values X,Y. # 9351 1.1 is # srem(): computes the fp (IEEE) REM of the input values X,Y. # 9352 1.1 is # # 9353 1.1 is # INPUT *************************************************************** # 9354 1.1 is # a0 = pointer to extended precision input X # 9355 1.1 is # a1 = pointer to extended precision input Y # 9356 1.1 is # d0 = round precision,mode # 9357 1.1 is # # 9358 1.1 is # The input operands X and Y can be either normalized or # 9359 1.1 is # denormalized. # 9360 1.1 is # # 9361 1.1 is # OUTPUT ************************************************************** # 9362 1.1 is # fp0 = FREM(X,Y) or FMOD(X,Y) # 9363 1.1 is # # 9364 1.1 is # ALGORITHM *********************************************************** # 9365 1.1 is # # 9366 1.1 is # Step 1. Save and strip signs of X and Y: signX := sign(X), # 9367 1.1 is # signY := sign(Y), X := |X|, Y := |Y|, # 9368 1.1 is # signQ := signX EOR signY. Record whether MOD or REM # 9369 1.1 is # is requested. # 9370 1.1 is # # 9371 1.1 is # Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. # 9372 1.1 is # If (L < 0) then # 9373 1.1 is # R := X, go to Step 4. # 9374 1.1 is # else # 9375 1.1 is # R := 2^(-L)X, j := L. # 9376 1.1 is # endif # 9377 1.1 is # # 9378 1.1 is # Step 3. Perform MOD(X,Y) # 9379 1.1 is # 3.1 If R = Y, go to Step 9. # 9380 1.1 is # 3.2 If R > Y, then { R := R - Y, Q := Q + 1} # 9381 1.1 is # 3.3 If j = 0, go to Step 4. # 9382 1.1 is # 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to # 9383 1.1 is # Step 3.1. # 9384 1.1 is # # 9385 1.1 is # Step 4. At this point, R = X - QY = MOD(X,Y). Set # 9386 1.1 is # Last_Subtract := false (used in Step 7 below). If # 9387 1.1 is # MOD is requested, go to Step 6. # 9388 1.1 is # # 9389 1.1 is # Step 5. R = MOD(X,Y), but REM(X,Y) is requested. # 9390 1.1 is # 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to # 9391 1.1 is # Step 6. # 9392 1.1 is # 5.2 If R > Y/2, then { set Last_Subtract := true, # 9393 1.1 is # Q := Q + 1, Y := signY*Y }. Go to Step 6. # 9394 1.1 is # 5.3 This is the tricky case of R = Y/2. If Q is odd, # 9395 1.1 is # then { Q := Q + 1, signX := -signX }. # 9396 1.1 is # # 9397 1.1 is # Step 6. R := signX*R. # 9398 1.1 is # # 9399 1.1 is # Step 7. If Last_Subtract = true, R := R - Y. # 9400 1.1 is # # 9401 1.1 is # Step 8. Return signQ, last 7 bits of Q, and R as required. # 9402 1.1 is # # 9403 1.1 is # Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, # 9404 1.1 is # X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), # 9405 1.1 is # R := 0. Return signQ, last 7 bits of Q, and R. # 9406 1.1 is # # 9407 1.1 is ######################################################################### 9408 1.1 is 9409 1.1 is set Mod_Flag,L_SCR3 9410 1.1 is set Sc_Flag,L_SCR3+1 9411 1.1 is 9412 1.1 is set SignY,L_SCR2 9413 1.1 is set SignX,L_SCR2+2 9414 1.1 is set SignQ,L_SCR3+2 9415 1.1 is 9416 1.1 is set Y,FP_SCR0 9417 1.1 is set Y_Hi,Y+4 9418 1.1 is set Y_Lo,Y+8 9419 1.1 is 9420 1.1 is set R,FP_SCR1 9421 1.1 is set R_Hi,R+4 9422 1.1 is set R_Lo,R+8 9423 1.1 is 9424 1.1 is Scale: 9425 1.1 is long 0x00010000,0x80000000,0x00000000,0x00000000 9426 1.1 is 9427 1.1 is global smod 9428 1.1 is smod: 9429 1.1 is clr.b FPSR_QBYTE(%a6) 9430 1.1 is mov.l %d0,-(%sp) # save ctrl bits 9431 1.1 is clr.b Mod_Flag(%a6) 9432 1.1 is bra.b Mod_Rem 9433 1.1 is 9434 1.1 is global srem 9435 1.1 is srem: 9436 1.1 is clr.b FPSR_QBYTE(%a6) 9437 1.1 is mov.l %d0,-(%sp) # save ctrl bits 9438 1.1 is mov.b &0x1,Mod_Flag(%a6) 9439 1.1 is 9440 1.1 is Mod_Rem: 9441 1.1 is #..Save sign of X and Y 9442 1.1 is movm.l &0x3f00,-(%sp) # save data registers 9443 1.1 is mov.w SRC_EX(%a0),%d3 9444 1.1 is mov.w %d3,SignY(%a6) 9445 1.1 is and.l &0x00007FFF,%d3 # Y := |Y| 9446 1.1 is 9447 1.1 is # 9448 1.1 is mov.l SRC_HI(%a0),%d4 9449 1.1 is mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y| 9450 1.1 is 9451 1.1 is tst.l %d3 9452 1.1 is bne.b Y_Normal 9453 1.1 is 9454 1.1 is mov.l &0x00003FFE,%d3 # $3FFD + 1 9455 1.1 is tst.l %d4 9456 1.1 is bne.b HiY_not0 9457 1.1 is 9458 1.1 is HiY_0: 9459 1.1 is mov.l %d5,%d4 9460 1.1 is clr.l %d5 9461 1.1 is sub.l &32,%d3 9462 1.1 is clr.l %d6 9463 1.1 is bfffo %d4{&0:&32},%d6 9464 1.1 is lsl.l %d6,%d4 9465 1.1 is sub.l %d6,%d3 # (D3,D4,D5) is normalized 9466 1.1 is # ...with bias $7FFD 9467 1.1 is bra.b Chk_X 9468 1.1 is 9469 1.1 is HiY_not0: 9470 1.1 is clr.l %d6 9471 1.1 is bfffo %d4{&0:&32},%d6 9472 1.1 is sub.l %d6,%d3 9473 1.1 is lsl.l %d6,%d4 9474 1.1 is mov.l %d5,%d7 # a copy of D5 9475 1.1 is lsl.l %d6,%d5 9476 1.1 is neg.l %d6 9477 1.1 is add.l &32,%d6 9478 1.1 is lsr.l %d6,%d7 9479 1.1 is or.l %d7,%d4 # (D3,D4,D5) normalized 9480 1.1 is # ...with bias $7FFD 9481 1.1 is bra.b Chk_X 9482 1.1 is 9483 1.1 is Y_Normal: 9484 1.1 is add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized 9485 1.1 is # ...with bias $7FFD 9486 1.1 is 9487 1.1 is Chk_X: 9488 1.1 is mov.w DST_EX(%a1),%d0 9489 1.1 is mov.w %d0,SignX(%a6) 9490 1.1 is mov.w SignY(%a6),%d1 9491 1.1 is eor.l %d0,%d1 9492 1.1 is and.l &0x00008000,%d1 9493 1.1 is mov.w %d1,SignQ(%a6) # sign(Q) obtained 9494 1.1 is and.l &0x00007FFF,%d0 9495 1.1 is mov.l DST_HI(%a1),%d1 9496 1.1 is mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X| 9497 1.1 is tst.l %d0 9498 1.1 is bne.b X_Normal 9499 1.1 is mov.l &0x00003FFE,%d0 9500 1.1 is tst.l %d1 9501 1.1 is bne.b HiX_not0 9502 1.1 is 9503 1.1 is HiX_0: 9504 1.1 is mov.l %d2,%d1 9505 1.1 is clr.l %d2 9506 1.1 is sub.l &32,%d0 9507 1.1 is clr.l %d6 9508 1.1 is bfffo %d1{&0:&32},%d6 9509 1.1 is lsl.l %d6,%d1 9510 1.1 is sub.l %d6,%d0 # (D0,D1,D2) is normalized 9511 1.1 is # ...with bias $7FFD 9512 1.1 is bra.b Init 9513 1.1 is 9514 1.1 is HiX_not0: 9515 1.1 is clr.l %d6 9516 1.1 is bfffo %d1{&0:&32},%d6 9517 1.1 is sub.l %d6,%d0 9518 1.1 is lsl.l %d6,%d1 9519 1.1 is mov.l %d2,%d7 # a copy of D2 9520 1.1 is lsl.l %d6,%d2 9521 1.1 is neg.l %d6 9522 1.1 is add.l &32,%d6 9523 1.1 is lsr.l %d6,%d7 9524 1.1 is or.l %d7,%d1 # (D0,D1,D2) normalized 9525 1.1 is # ...with bias $7FFD 9526 1.1 is bra.b Init 9527 1.1 is 9528 1.1 is X_Normal: 9529 1.1 is add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized 9530 1.1 is # ...with bias $7FFD 9531 1.1 is 9532 1.1 is Init: 9533 1.1 is # 9534 1.1 is mov.l %d3,L_SCR1(%a6) # save biased exp(Y) 9535 1.1 is mov.l %d0,-(%sp) # save biased exp(X) 9536 1.1 is sub.l %d3,%d0 # L := expo(X)-expo(Y) 9537 1.1 is 9538 1.1 is clr.l %d6 # D6 := carry <- 0 9539 1.1 is clr.l %d3 # D3 is Q 9540 1.1 is mov.l &0,%a1 # A1 is k; j+k=L, Q=0 9541 1.1 is 9542 1.1 is #..(Carry,D1,D2) is R 9543 1.1 is tst.l %d0 9544 1.1 is bge.b Mod_Loop_pre 9545 1.1 is 9546 1.1 is #..expo(X) < expo(Y). Thus X = mod(X,Y) 9547 1.1 is # 9548 1.1 is mov.l (%sp)+,%d0 # restore d0 9549 1.1 is bra.w Get_Mod 9550 1.1 is 9551 1.1 is Mod_Loop_pre: 9552 1.1 is addq.l &0x4,%sp # erase exp(X) 9553 1.1 is #..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L 9554 1.1 is Mod_Loop: 9555 1.1 is tst.l %d6 # test carry bit 9556 1.1 is bgt.b R_GT_Y 9557 1.1 is 9558 1.1 is #..At this point carry = 0, R = (D1,D2), Y = (D4,D5) 9559 1.1 is cmp.l %d1,%d4 # compare hi(R) and hi(Y) 9560 1.1 is bne.b R_NE_Y 9561 1.1 is cmp.l %d2,%d5 # compare lo(R) and lo(Y) 9562 1.1 is bne.b R_NE_Y 9563 1.1 is 9564 1.1 is #..At this point, R = Y 9565 1.1 is bra.w Rem_is_0 9566 1.1 is 9567 1.1 is R_NE_Y: 9568 1.1 is #..use the borrow of the previous compare 9569 1.1 is bcs.b R_LT_Y # borrow is set iff R < Y 9570 1.1 is 9571 1.1 is R_GT_Y: 9572 1.1 is #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0 9573 1.1 is #..and Y < (D1,D2) < 2Y. Either way, perform R - Y 9574 1.1 is sub.l %d5,%d2 # lo(R) - lo(Y) 9575 1.1 is subx.l %d4,%d1 # hi(R) - hi(Y) 9576 1.1 is clr.l %d6 # clear carry 9577 1.1 is addq.l &1,%d3 # Q := Q + 1 9578 1.1 is 9579 1.1 is R_LT_Y: 9580 1.1 is #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0. 9581 1.1 is tst.l %d0 # see if j = 0. 9582 1.1 is beq.b PostLoop 9583 1.1 is 9584 1.1 is add.l %d3,%d3 # Q := 2Q 9585 1.1 is add.l %d2,%d2 # lo(R) = 2lo(R) 9586 1.1 is roxl.l &1,%d1 # hi(R) = 2hi(R) + carry 9587 1.1 is scs %d6 # set Carry if 2(R) overflows 9588 1.1 is addq.l &1,%a1 # k := k+1 9589 1.1 is subq.l &1,%d0 # j := j - 1 9590 1.1 is #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y. 9591 1.1 is 9592 1.1 is bra.b Mod_Loop 9593 1.1 is 9594 1.1 is PostLoop: 9595 1.1 is #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y. 9596 1.1 is 9597 1.1 is #..normalize R. 9598 1.1 is mov.l L_SCR1(%a6),%d0 # new biased expo of R 9599 1.1 is tst.l %d1 9600 1.1 is bne.b HiR_not0 9601 1.1 is 9602 1.1 is HiR_0: 9603 1.1 is mov.l %d2,%d1 9604 1.1 is clr.l %d2 9605 1.1 is sub.l &32,%d0 9606 1.1 is clr.l %d6 9607 1.1 is bfffo %d1{&0:&32},%d6 9608 1.1 is lsl.l %d6,%d1 9609 1.1 is sub.l %d6,%d0 # (D0,D1,D2) is normalized 9610 1.1 is # ...with bias $7FFD 9611 1.1 is bra.b Get_Mod 9612 1.1 is 9613 1.1 is HiR_not0: 9614 1.1 is clr.l %d6 9615 1.1 is bfffo %d1{&0:&32},%d6 9616 1.1 is bmi.b Get_Mod # already normalized 9617 1.1 is sub.l %d6,%d0 9618 1.1 is lsl.l %d6,%d1 9619 1.1 is mov.l %d2,%d7 # a copy of D2 9620 1.1 is lsl.l %d6,%d2 9621 1.1 is neg.l %d6 9622 1.1 is add.l &32,%d6 9623 1.1 is lsr.l %d6,%d7 9624 1.1 is or.l %d7,%d1 # (D0,D1,D2) normalized 9625 1.1 is 9626 1.1 is # 9627 1.1 is Get_Mod: 9628 1.1 is cmp.l %d0,&0x000041FE 9629 1.1 is bge.b No_Scale 9630 1.1 is Do_Scale: 9631 1.1 is mov.w %d0,R(%a6) 9632 1.1 is mov.l %d1,R_Hi(%a6) 9633 1.1 is mov.l %d2,R_Lo(%a6) 9634 1.1 is mov.l L_SCR1(%a6),%d6 9635 1.1 is mov.w %d6,Y(%a6) 9636 1.1 is mov.l %d4,Y_Hi(%a6) 9637 1.1 is mov.l %d5,Y_Lo(%a6) 9638 1.1 is fmov.x R(%a6),%fp0 # no exception 9639 1.1 is mov.b &1,Sc_Flag(%a6) 9640 1.1 is bra.b ModOrRem 9641 1.1 is No_Scale: 9642 1.1 is mov.l %d1,R_Hi(%a6) 9643 1.1 is mov.l %d2,R_Lo(%a6) 9644 1.1 is sub.l &0x3FFE,%d0 9645 1.1 is mov.w %d0,R(%a6) 9646 1.1 is mov.l L_SCR1(%a6),%d6 9647 1.1 is sub.l &0x3FFE,%d6 9648 1.1 is mov.l %d6,L_SCR1(%a6) 9649 1.1 is fmov.x R(%a6),%fp0 9650 1.1 is mov.w %d6,Y(%a6) 9651 1.1 is mov.l %d4,Y_Hi(%a6) 9652 1.1 is mov.l %d5,Y_Lo(%a6) 9653 1.1 is clr.b Sc_Flag(%a6) 9654 1.1 is 9655 1.1 is # 9656 1.1 is ModOrRem: 9657 1.1 is tst.b Mod_Flag(%a6) 9658 1.1 is beq.b Fix_Sign 9659 1.1 is 9660 1.1 is mov.l L_SCR1(%a6),%d6 # new biased expo(Y) 9661 1.1 is subq.l &1,%d6 # biased expo(Y/2) 9662 1.1 is cmp.l %d0,%d6 9663 1.1 is blt.b Fix_Sign 9664 1.1 is bgt.b Last_Sub 9665 1.1 is 9666 1.1 is cmp.l %d1,%d4 9667 1.1 is bne.b Not_EQ 9668 1.1 is cmp.l %d2,%d5 9669 1.1 is bne.b Not_EQ 9670 1.1 is bra.w Tie_Case 9671 1.1 is 9672 1.1 is Not_EQ: 9673 1.1 is bcs.b Fix_Sign 9674 1.1 is 9675 1.1 is Last_Sub: 9676 1.1 is # 9677 1.1 is fsub.x Y(%a6),%fp0 # no exceptions 9678 1.1 is addq.l &1,%d3 # Q := Q + 1 9679 1.1 is 9680 1.1 is # 9681 1.1 is Fix_Sign: 9682 1.1 is #..Get sign of X 9683 1.1 is mov.w SignX(%a6),%d6 9684 1.1 is bge.b Get_Q 9685 1.1 is fneg.x %fp0 9686 1.1 is 9687 1.1 is #..Get Q 9688 1.1 is # 9689 1.1 is Get_Q: 9690 1.1 is clr.l %d6 9691 1.1 is mov.w SignQ(%a6),%d6 # D6 is sign(Q) 9692 1.1 is mov.l &8,%d7 9693 1.1 is lsr.l %d7,%d6 9694 1.1 is and.l &0x0000007F,%d3 # 7 bits of Q 9695 1.1 is or.l %d6,%d3 # sign and bits of Q 9696 1.1 is # swap %d3 9697 1.1 is # fmov.l %fpsr,%d6 9698 1.1 is # and.l &0xFF00FFFF,%d6 9699 1.1 is # or.l %d3,%d6 9700 1.1 is # fmov.l %d6,%fpsr # put Q in fpsr 9701 1.1 is mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr 9702 1.1 is 9703 1.1 is # 9704 1.1 is Restore: 9705 1.1 is movm.l (%sp)+,&0xfc # {%d2-%d7} 9706 1.1 is mov.l (%sp)+,%d0 9707 1.1 is fmov.l %d0,%fpcr 9708 1.1 is tst.b Sc_Flag(%a6) 9709 1.1 is beq.b Finish 9710 1.1 is mov.b &FMUL_OP,%d1 # last inst is MUL 9711 1.1 is fmul.x Scale(%pc),%fp0 # may cause underflow 9712 1.1 is bra t_catch2 9713 1.1 is # the '040 package did this apparently to see if the dst operand for the 9714 1.1 is # preceding fmul was a denorm. but, it better not have been since the 9715 1.1 is # algorithm just got done playing with fp0 and expected no exceptions 9716 1.1 is # as a result. trust me... 9717 1.1 is # bra t_avoid_unsupp # check for denorm as a 9718 1.1 is # ;result of the scaling 9719 1.1 is 9720 1.1 is Finish: 9721 1.1 is mov.b &FMOV_OP,%d1 # last inst is MOVE 9722 1.1 is fmov.x %fp0,%fp0 # capture exceptions & round 9723 1.1 is bra t_catch2 9724 1.1 is 9725 1.1 is Rem_is_0: 9726 1.1 is #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1) 9727 1.1 is addq.l &1,%d3 9728 1.1 is cmp.l %d0,&8 # D0 is j 9729 1.1 is bge.b Q_Big 9730 1.1 is 9731 1.1 is lsl.l %d0,%d3 9732 1.1 is bra.b Set_R_0 9733 1.1 is 9734 1.1 is Q_Big: 9735 1.1 is clr.l %d3 9736 1.1 is 9737 1.1 is Set_R_0: 9738 1.1 is fmov.s &0x00000000,%fp0 9739 1.1 is clr.b Sc_Flag(%a6) 9740 1.1 is bra.w Fix_Sign 9741 1.1 is 9742 1.1 is Tie_Case: 9743 1.1 is #..Check parity of Q 9744 1.1 is mov.l %d3,%d6 9745 1.1 is and.l &0x00000001,%d6 9746 1.1 is tst.l %d6 9747 1.1 is beq.w Fix_Sign # Q is even 9748 1.1 is 9749 1.1 is #..Q is odd, Q := Q + 1, signX := -signX 9750 1.1 is addq.l &1,%d3 9751 1.1 is mov.w SignX(%a6),%d6 9752 1.1 is eor.l &0x00008000,%d6 9753 1.1 is mov.w %d6,SignX(%a6) 9754 1.1 is bra.w Fix_Sign 9755 1.1 is 9756 1.1 is ######################################################################### 9757 1.1 is # XDEF **************************************************************** # 9758 1.1 is # tag(): return the optype of the input ext fp number # 9759 1.1 is # # 9760 1.1 is # This routine is used by the 060FPLSP. # 9761 1.1 is # # 9762 1.1 is # XREF **************************************************************** # 9763 1.1 is # None # 9764 1.1 is # # 9765 1.1 is # INPUT *************************************************************** # 9766 1.1 is # a0 = pointer to extended precision operand # 9767 1.1 is # # 9768 1.1 is # OUTPUT ************************************************************** # 9769 1.1 is # d0 = value of type tag # 9770 1.1 is # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO # 9771 1.1 is # # 9772 1.1 is # ALGORITHM *********************************************************** # 9773 1.1 is # Simply test the exponent, j-bit, and mantissa values to # 9774 1.1 is # determine the type of operand. # 9775 1.1 is # If it's an unnormalized zero, alter the operand and force it # 9776 1.1 is # to be a normal zero. # 9777 1.1 is # # 9778 1.1 is ######################################################################### 9779 1.1 is 9780 1.1 is global tag 9781 1.1 is tag: 9782 1.1 is mov.w FTEMP_EX(%a0), %d0 # extract exponent 9783 1.1 is andi.w &0x7fff, %d0 # strip off sign 9784 1.1 is cmpi.w %d0, &0x7fff # is (EXP == MAX)? 9785 1.1 is beq.b inf_or_nan_x 9786 1.1 is not_inf_or_nan_x: 9787 1.1 is btst &0x7,FTEMP_HI(%a0) 9788 1.1 is beq.b not_norm_x 9789 1.1 is is_norm_x: 9790 1.1 is mov.b &NORM, %d0 9791 1.1 is rts 9792 1.1 is not_norm_x: 9793 1.1 is tst.w %d0 # is exponent = 0? 9794 1.1 is bne.b is_unnorm_x 9795 1.1 is not_unnorm_x: 9796 1.1 is tst.l FTEMP_HI(%a0) 9797 1.1 is bne.b is_denorm_x 9798 1.1 is tst.l FTEMP_LO(%a0) 9799 1.1 is bne.b is_denorm_x 9800 1.1 is is_zero_x: 9801 1.1 is mov.b &ZERO, %d0 9802 1.1 is rts 9803 1.1 is is_denorm_x: 9804 1.1 is mov.b &DENORM, %d0 9805 1.1 is rts 9806 1.1 is is_unnorm_x: 9807 1.1 is bsr.l unnorm_fix # convert to norm,denorm,or zero 9808 1.1 is rts 9809 1.1 is is_unnorm_reg_x: 9810 1.1 is mov.b &UNNORM, %d0 9811 1.1 is rts 9812 1.1 is inf_or_nan_x: 9813 1.1 is tst.l FTEMP_LO(%a0) 9814 1.1 is bne.b is_nan_x 9815 1.1 is mov.l FTEMP_HI(%a0), %d0 9816 1.1 is and.l &0x7fffffff, %d0 # msb is a don't care! 9817 1.1 is bne.b is_nan_x 9818 1.1 is is_inf_x: 9819 1.1 is mov.b &INF, %d0 9820 1.1 is rts 9821 1.1 is is_nan_x: 9822 1.1 is mov.b &QNAN, %d0 9823 1.1 is rts 9824 1.1 is 9825 1.1 is ############################################################# 9826 1.1 is 9827 1.1 is qnan: long 0x7fff0000, 0xffffffff, 0xffffffff 9828 1.1 is 9829 1.1 is ######################################################################### 9830 1.1 is # XDEF **************************************************************** # 9831 1.1 is # t_dz(): Handle 060FPLSP dz exception for "flogn" emulation. # 9832 1.1 is # t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation. # 9833 1.1 is # # 9834 1.1 is # These rouitnes are used by the 060FPLSP package. # 9835 1.1 is # # 9836 1.1 is # XREF **************************************************************** # 9837 1.1 is # None # 9838 1.1 is # # 9839 1.1 is # INPUT *************************************************************** # 9840 1.1 is # a0 = pointer to extended precision source operand. # 9841 1.1 is # # 9842 1.1 is # OUTPUT ************************************************************** # 9843 1.1 is # fp0 = default DZ result. # 9844 1.1 is # # 9845 1.1 is # ALGORITHM *********************************************************** # 9846 1.1 is # Transcendental emulation for the 060FPLSP has detected that # 9847 1.1 is # a DZ exception should occur for the instruction. If DZ is disabled, # 9848 1.1 is # return the default result. # 9849 1.1 is # If DZ is enabled, the dst operand should be returned unscathed # 9850 1.1 is # in fp0 while fp1 is used to create a DZ exception so that the # 9851 1.1 is # operating system can log that such an event occurred. # 9852 1.1 is # # 9853 1.1 is ######################################################################### 9854 1.1 is 9855 1.1 is global t_dz 9856 1.1 is t_dz: 9857 1.1 is tst.b SRC_EX(%a0) # check sign for neg or pos 9858 1.1 is bpl.b dz_pinf # branch if pos sign 9859 1.1 is 9860 1.1 is global t_dz2 9861 1.1 is t_dz2: 9862 1.1 is ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ 9863 1.1 is 9864 1.1 is btst &dz_bit,FPCR_ENABLE(%a6) 9865 1.1 is bne.b dz_minf_ena 9866 1.1 is 9867 1.1 is # dz is disabled. return a -INF. 9868 1.1 is fmov.s &0xff800000,%fp0 # return -INF 9869 1.1 is rts 9870 1.1 is 9871 1.1 is # dz is enabled. create a dz exception so the user can record it 9872 1.1 is # but use fp1 instead. return the dst operand unscathed in fp0. 9873 1.1 is dz_minf_ena: 9874 1.1 is fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 9875 1.1 is fmov.l USER_FPCR(%a6),%fpcr 9876 1.1 is fmov.s &0xbf800000,%fp1 # load -1 9877 1.1 is fdiv.s &0x00000000,%fp1 # -1 / 0 9878 1.1 is rts 9879 1.1 is 9880 1.1 is dz_pinf: 9881 1.1 is ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ 9882 1.1 is 9883 1.1 is btst &dz_bit,FPCR_ENABLE(%a6) 9884 1.1 is bne.b dz_pinf_ena 9885 1.1 is 9886 1.1 is # dz is disabled. return a +INF. 9887 1.1 is fmov.s &0x7f800000,%fp0 # return +INF 9888 1.1 is rts 9889 1.1 is 9890 1.1 is # dz is enabled. create a dz exception so the user can record it 9891 1.1 is # but use fp1 instead. return the dst operand unscathed in fp0. 9892 1.1 is dz_pinf_ena: 9893 1.1 is fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 9894 1.1 is fmov.l USER_FPCR(%a6),%fpcr 9895 1.1 is fmov.s &0x3f800000,%fp1 # load +1 9896 1.1 is fdiv.s &0x00000000,%fp1 # +1 / 0 9897 1.1 is rts 9898 1.1 is 9899 1.1 is ######################################################################### 9900 1.1 is # XDEF **************************************************************** # 9901 1.1 is # t_operr(): Handle 060FPLSP OPERR exception during emulation. # 9902 1.1 is # # 9903 1.1 is # This routine is used by the 060FPLSP package. # 9904 1.1 is # # 9905 1.1 is # XREF **************************************************************** # 9906 1.1 is # None. # 9907 1.1 is # # 9908 1.1 is # INPUT *************************************************************** # 9909 1.1 is # fp1 = source operand # 9910 1.1 is # # 9911 1.1 is # OUTPUT ************************************************************** # 9912 1.1 is # fp0 = default result # 9913 1.1 is # fp1 = unchanged # 9914 1.1 is # # 9915 1.1 is # ALGORITHM *********************************************************** # 9916 1.1 is # An operand error should occur as the result of transcendental # 9917 1.1 is # emulation in the 060FPLSP. If OPERR is disabled, just return a NAN # 9918 1.1 is # in fp0. If OPERR is enabled, return the dst operand unscathed in fp0 # 9919 1.1 is # and the source operand in fp1. Use fp2 to create an OPERR exception # 9920 1.1 is # so that the operating system can log the event. # 9921 1.1 is # # 9922 1.1 is ######################################################################### 9923 1.1 is 9924 1.1 is global t_operr 9925 1.1 is t_operr: 9926 1.1 is ori.l &opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP 9927 1.1 is 9928 1.1 is btst &operr_bit,FPCR_ENABLE(%a6) 9929 1.1 is bne.b operr_ena 9930 1.1 is 9931 1.1 is # operr is disabled. return a QNAN in fp0 9932 1.1 is fmovm.x qnan(%pc),&0x80 # return QNAN 9933 1.1 is rts 9934 1.1 is 9935 1.1 is # operr is enabled. create an operr exception so the user can record it 9936 1.1 is # but use fp2 instead. return the dst operand unscathed in fp0. 9937 1.1 is operr_ena: 9938 1.1 is fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 9939 1.1 is fmov.l USER_FPCR(%a6),%fpcr 9940 1.1 is fmovm.x &0x04,-(%sp) # save fp2 9941 1.1 is fmov.s &0x7f800000,%fp2 # load +INF 9942 1.1 is fmul.s &0x00000000,%fp2 # +INF x 0 9943 1.1 is fmovm.x (%sp)+,&0x20 # restore fp2 9944 1.1 is rts 9945 1.1 is 9946 1.1 is pls_huge: 9947 1.1 is long 0x7ffe0000,0xffffffff,0xffffffff 9948 1.1 is mns_huge: 9949 1.1 is long 0xfffe0000,0xffffffff,0xffffffff 9950 1.1 is pls_tiny: 9951 1.1 is long 0x00000000,0x80000000,0x00000000 9952 1.1 is mns_tiny: 9953 1.1 is long 0x80000000,0x80000000,0x00000000 9954 1.1 is 9955 1.1 is ######################################################################### 9956 1.1 is # XDEF **************************************************************** # 9957 1.1 is # t_unfl(): Handle 060FPLSP underflow exception during emulation. # 9958 1.1 is # t_unfl2(): Handle 060FPLSP underflow exception during # 9959 1.1 is # emulation. result always positive. # 9960 1.1 is # # 9961 1.1 is # This routine is used by the 060FPLSP package. # 9962 1.1 is # # 9963 1.1 is # XREF **************************************************************** # 9964 1.1 is # None. # 9965 1.1 is # # 9966 1.1 is # INPUT *************************************************************** # 9967 1.1 is # a0 = pointer to extended precision source operand # 9968 1.1 is # # 9969 1.1 is # OUTPUT ************************************************************** # 9970 1.1 is # fp0 = default underflow result # 9971 1.1 is # # 9972 1.1 is # ALGORITHM *********************************************************** # 9973 1.1 is # An underflow should occur as the result of transcendental # 9974 1.1 is # emulation in the 060FPLSP. Create an underflow by using "fmul" # 9975 1.1 is # and two very small numbers of appropriate sign so that the operating # 9976 1.1 is # system can log the event. # 9977 1.1 is # # 9978 1.1 is ######################################################################### 9979 1.1 is 9980 1.1 is global t_unfl 9981 1.1 is t_unfl: 9982 1.1 is tst.b SRC_EX(%a0) 9983 1.1 is bpl.b unf_pos 9984 1.1 is 9985 1.1 is global t_unfl2 9986 1.1 is t_unfl2: 9987 1.1 is ori.l &unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX 9988 1.1 is 9989 1.1 is fmov.l USER_FPCR(%a6),%fpcr 9990 1.1 is fmovm.x mns_tiny(%pc),&0x80 9991 1.1 is fmul.x pls_tiny(%pc),%fp0 9992 1.1 is 9993 1.1 is fmov.l %fpsr,%d0 9994 1.1 is rol.l &0x8,%d0 9995 1.1 is mov.b %d0,FPSR_CC(%a6) 9996 1.1 is rts 9997 1.1 is unf_pos: 9998 1.1 is ori.w &unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX 9999 1.1 is 10000 1.1 is fmov.l USER_FPCR(%a6),%fpcr 10001 1.1 is fmovm.x pls_tiny(%pc),&0x80 10002 1.1 is fmul.x %fp0,%fp0 10003 1.1 is 10004 1.1 is fmov.l %fpsr,%d0 10005 1.1 is rol.l &0x8,%d0 10006 1.1 is mov.b %d0,FPSR_CC(%a6) 10007 1.1 is rts 10008 1.1 is 10009 1.1 is ######################################################################### 10010 1.1 is # XDEF **************************************************************** # 10011 1.1 is # t_ovfl(): Handle 060FPLSP overflow exception during emulation. # 10012 1.1 is # (monadic) # 10013 1.1 is # t_ovfl2(): Handle 060FPLSP overflow exception during # 10014 1.1 is # emulation. result always positive. (dyadic) # 10015 1.1 is # t_ovfl_sc(): Handle 060FPLSP overflow exception during # 10016 1.1 is # emulation for "fscale". # 10017 1.1 is # # 10018 1.1 is # This routine is used by the 060FPLSP package. # 10019 1.1 is # # 10020 1.1 is # XREF **************************************************************** # 10021 1.1 is # None. # 10022 1.1 is # # 10023 1.1 is # INPUT *************************************************************** # 10024 1.1 is # a0 = pointer to extended precision source operand # 10025 1.1 is # # 10026 1.1 is # OUTPUT ************************************************************** # 10027 1.1 is # fp0 = default underflow result # 10028 1.1 is # # 10029 1.1 is # ALGORITHM *********************************************************** # 10030 1.1 is # An overflow should occur as the result of transcendental # 10031 1.1 is # emulation in the 060FPLSP. Create an overflow by using "fmul" # 10032 1.1 is # and two very lareg numbers of appropriate sign so that the operating # 10033 1.1 is # system can log the event. # 10034 1.1 is # For t_ovfl_sc() we take special care not to lose the INEX2 bit. # 10035 1.1 is # # 10036 1.1 is ######################################################################### 10037 1.1 is 10038 1.1 is global t_ovfl_sc 10039 1.1 is t_ovfl_sc: 10040 1.1 is ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX 10041 1.1 is 10042 1.1 is mov.b %d0,%d1 # fetch rnd prec,mode 10043 1.1 is andi.b &0xc0,%d1 # extract prec 10044 1.1 is beq.w ovfl_work 10045 1.1 is 10046 1.1 is # dst op is a DENORM. we have to normalize the mantissa to see if the 10047 1.1 is # result would be inexact for the given precision. make a copy of the 10048 1.1 is # dst so we don't screw up the version passed to us. 10049 1.1 is mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6) 10050 1.1 is mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6) 10051 1.1 is mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6) 10052 1.1 is lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0 10053 1.1 is movm.l &0xc080,-(%sp) # save d0-d1/a0 10054 1.1 is bsr.l norm # normalize mantissa 10055 1.1 is movm.l (%sp)+,&0x0103 # restore d0-d1/a0 10056 1.1 is 10057 1.1 is cmpi.b %d1,&0x40 # is precision sgl? 10058 1.1 is bne.b ovfl_sc_dbl # no; dbl 10059 1.1 is ovfl_sc_sgl: 10060 1.1 is tst.l LOCAL_LO(%a0) # is lo lw of sgl set? 10061 1.1 is bne.b ovfl_sc_inx # yes 10062 1.1 is tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set? 10063 1.1 is bne.b ovfl_sc_inx # yes 10064 1.1 is bra.w ovfl_work # don't set INEX2 10065 1.1 is ovfl_sc_dbl: 10066 1.1 is mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of 10067 1.1 is andi.l &0x7ff,%d1 # dbl mantissa set? 10068 1.1 is beq.w ovfl_work # no; don't set INEX2 10069 1.1 is ovfl_sc_inx: 10070 1.1 is ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2 10071 1.1 is bra.b ovfl_work # continue 10072 1.1 is 10073 1.1 is global t_ovfl 10074 1.1 is t_ovfl: 10075 1.1 is ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX 10076 1.1 is ovfl_work: 10077 1.1 is tst.b SRC_EX(%a0) 10078 1.1 is bpl.b ovfl_p 10079 1.1 is ovfl_m: 10080 1.1 is fmov.l USER_FPCR(%a6),%fpcr 10081 1.1 is fmovm.x mns_huge(%pc),&0x80 10082 1.1 is fmul.x pls_huge(%pc),%fp0 10083 1.1 is 10084 1.1 is fmov.l %fpsr,%d0 10085 1.1 is rol.l &0x8,%d0 10086 1.1 is ori.b &neg_mask,%d0 10087 1.1 is mov.b %d0,FPSR_CC(%a6) 10088 1.1 is rts 10089 1.1 is ovfl_p: 10090 1.1 is fmov.l USER_FPCR(%a6),%fpcr 10091 1.1 is fmovm.x pls_huge(%pc),&0x80 10092 1.1 is fmul.x pls_huge(%pc),%fp0 10093 1.1 is 10094 1.1 is fmov.l %fpsr,%d0 10095 1.1 is rol.l &0x8,%d0 10096 1.1 is mov.b %d0,FPSR_CC(%a6) 10097 1.1 is rts 10098 1.1 is 10099 1.1 is global t_ovfl2 10100 1.1 is t_ovfl2: 10101 1.1 is ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX 10102 1.1 is fmov.l USER_FPCR(%a6),%fpcr 10103 1.1 is fmovm.x pls_huge(%pc),&0x80 10104 1.1 is fmul.x pls_huge(%pc),%fp0 10105 1.1 is 10106 1.1 is fmov.l %fpsr,%d0 10107 1.1 is rol.l &0x8,%d0 10108 1.1 is mov.b %d0,FPSR_CC(%a6) 10109 1.1 is rts 10110 1.1 is 10111 1.1 is ######################################################################### 10112 1.1 is # XDEF **************************************************************** # 10113 1.1 is # t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during # 10114 1.1 is # emulation. # 10115 1.1 is # t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during # 10116 1.1 is # emulation. # 10117 1.1 is # # 10118 1.1 is # These routines are used by the 060FPLSP package. # 10119 1.1 is # # 10120 1.1 is # XREF **************************************************************** # 10121 1.1 is # None. # 10122 1.1 is # # 10123 1.1 is # INPUT *************************************************************** # 10124 1.1 is # fp0 = default underflow or overflow result # 10125 1.1 is # # 10126 1.1 is # OUTPUT ************************************************************** # 10127 1.1 is # fp0 = default result # 10128 1.1 is # # 10129 1.1 is # ALGORITHM *********************************************************** # 10130 1.1 is # If an overflow or underflow occurred during the last # 10131 1.1 is # instruction of transcendental 060FPLSP emulation, then it has already # 10132 1.1 is # occurred and has been logged. Now we need to see if an inexact # 10133 1.1 is # exception should occur. # 10134 1.1 is # # 10135 1.1 is ######################################################################### 10136 1.1 is 10137 1.1 is global t_catch2 10138 1.1 is t_catch2: 10139 1.1 is fmov.l %fpsr,%d0 10140 1.1 is or.l %d0,USER_FPSR(%a6) 10141 1.1 is bra.b inx2_work 10142 1.1 is 10143 1.1 is global t_catch 10144 1.1 is t_catch: 10145 1.1 is fmov.l %fpsr,%d0 10146 1.1 is or.l %d0,USER_FPSR(%a6) 10147 1.1 is 10148 1.1 is ######################################################################### 10149 1.1 is # XDEF **************************************************************** # 10150 1.1 is # t_inx2(): Handle inexact 060FPLSP exception during emulation. # 10151 1.1 is # t_pinx2(): Handle inexact 060FPLSP exception for "+" results. # 10152 1.1 is # t_minx2(): Handle inexact 060FPLSP exception for "-" results. # 10153 1.1 is # # 10154 1.1 is # XREF **************************************************************** # 10155 1.1 is # None. # 10156 1.1 is # # 10157 1.1 is # INPUT *************************************************************** # 10158 1.1 is # fp0 = default result # 10159 1.1 is # # 10160 1.1 is # OUTPUT ************************************************************** # 10161 1.1 is # fp0 = default result # 10162 1.1 is # # 10163 1.1 is # ALGORITHM *********************************************************** # 10164 1.1 is # The last instruction of transcendental emulation for the # 10165 1.1 is # 060FPLSP should be inexact. So, if inexact is enabled, then we create # 10166 1.1 is # the event here by adding a large and very small number together # 10167 1.1 is # so that the operating system can log the event. # 10168 1.1 is # Must check, too, if the result was zero, in which case we just # 10169 1.1 is # set the FPSR bits and return. # 10170 1.1 is # # 10171 1.1 is ######################################################################### 10172 1.1 is 10173 1.1 is global t_inx2 10174 1.1 is t_inx2: 10175 1.1 is fblt.w t_minx2 10176 1.1 is fbeq.w inx2_zero 10177 1.1 is 10178 1.1 is global t_pinx2 10179 1.1 is t_pinx2: 10180 1.1 is ori.w &inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX 10181 1.1 is bra.b inx2_work 10182 1.1 is 10183 1.1 is global t_minx2 10184 1.1 is t_minx2: 10185 1.1 is ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6) 10186 1.1 is 10187 1.1 is inx2_work: 10188 1.1 is btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled? 10189 1.1 is bne.b inx2_work_ena # yes 10190 1.1 is rts 10191 1.1 is inx2_work_ena: 10192 1.1 is fmov.l USER_FPCR(%a6),%fpcr # insert user's exceptions 10193 1.1 is fmov.s &0x3f800000,%fp1 # load +1 10194 1.1 is fadd.x pls_tiny(%pc),%fp1 # cause exception 10195 1.1 is rts 10196 1.1 is 10197 1.1 is inx2_zero: 10198 1.1 is mov.b &z_bmask,FPSR_CC(%a6) 10199 1.1 is ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX 10200 1.1 is rts 10201 1.1 is 10202 1.1 is ######################################################################### 10203 1.1 is # XDEF **************************************************************** # 10204 1.1 is # t_extdnrm(): Handle DENORM inputs in 060FPLSP. # 10205 1.1 is # t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale". # 10206 1.1 is # # 10207 1.1 is # This routine is used by the 060FPLSP package. # 10208 1.1 is # # 10209 1.1 is # XREF **************************************************************** # 10210 1.1 is # None. # 10211 1.1 is # # 10212 1.1 is # INPUT *************************************************************** # 10213 1.1 is # a0 = pointer to extended precision input operand # 10214 1.1 is # # 10215 1.1 is # OUTPUT ************************************************************** # 10216 1.1 is # fp0 = default result # 10217 1.1 is # # 10218 1.1 is # ALGORITHM *********************************************************** # 10219 1.1 is # For all functions that have a denormalized input and that # 10220 1.1 is # f(x)=x, this is the entry point. # 10221 1.1 is # DENORM value is moved using "fmove" which triggers an exception # 10222 1.1 is # if enabled so the operating system can log the event. # 10223 1.1 is # # 10224 1.1 is ######################################################################### 10225 1.1 is 10226 1.1 is global t_extdnrm 10227 1.1 is t_extdnrm: 10228 1.1 is fmov.l USER_FPCR(%a6),%fpcr 10229 1.1 is fmov.x SRC_EX(%a0),%fp0 10230 1.1 is fmov.l %fpsr,%d0 10231 1.1 is ori.l &unfinx_mask,%d0 10232 1.1 is or.l %d0,USER_FPSR(%a6) 10233 1.1 is rts 10234 1.1 is 10235 1.1 is global t_resdnrm 10236 1.1 is t_resdnrm: 10237 1.1 is fmov.l USER_FPCR(%a6),%fpcr 10238 1.1 is fmov.x SRC_EX(%a0),%fp0 10239 1.1 is fmov.l %fpsr,%d0 10240 1.1 is or.l %d0,USER_FPSR(%a6) 10241 1.1 is rts 10242 1.1 is 10243 1.1 is ########################################## 10244 1.1 is 10245 1.1 is # 10246 1.1 is # sto_cos: 10247 1.1 is # This is used by fsincos library emulation. The correct 10248 1.1 is # values are already in fp0 and fp1 so we do nothing here. 10249 1.1 is # 10250 1.1 is global sto_cos 10251 1.1 is sto_cos: 10252 1.1 is rts 10253 1.1 is 10254 1.1 is ########################################## 10255 1.1 is 10256 1.1 is # 10257 1.1 is # dst_qnan --- force result when destination is a NaN 10258 1.1 is # 10259 1.1 is global dst_qnan 10260 1.1 is dst_qnan: 10261 1.1 is fmov.x DST(%a1),%fp0 10262 1.1 is tst.b DST_EX(%a1) 10263 1.1 is bmi.b dst_qnan_m 10264 1.1 is dst_qnan_p: 10265 1.1 is mov.b &nan_bmask,FPSR_CC(%a6) 10266 1.1 is rts 10267 1.1 is dst_qnan_m: 10268 1.1 is mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6) 10269 1.1 is rts 10270 1.1 is 10271 1.1 is # 10272 1.1 is # src_qnan --- force result when source is a NaN 10273 1.1 is # 10274 1.1 is global src_qnan 10275 1.1 is src_qnan: 10276 1.1 is fmov.x SRC(%a0),%fp0 10277 1.1 is tst.b SRC_EX(%a0) 10278 1.1 is bmi.b src_qnan_m 10279 1.1 is src_qnan_p: 10280 1.1 is mov.b &nan_bmask,FPSR_CC(%a6) 10281 1.1 is rts 10282 1.1 is src_qnan_m: 10283 1.1 is mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6) 10284 1.1 is rts 10285 1.1 is 10286 1.1 is ########################################## 10287 1.1 is 10288 1.1 is # 10289 1.1 is # Native instruction support 10290 1.1 is # 10291 1.1 is # Some systems may need entry points even for 68060 native 10292 1.1 is # instructions. These routines are provided for 10293 1.1 is # convenience. 10294 1.1 is # 10295 1.1 is global _fadds_ 10296 1.1 is _fadds_: 10297 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10298 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10299 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst 10300 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10301 1.1 is fadd.s 0x8(%sp),%fp0 # fadd w/ sgl src 10302 1.1 is rts 10303 1.1 is 10304 1.1 is global _faddd_ 10305 1.1 is _faddd_: 10306 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10307 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10308 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst 10309 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10310 1.1 is fadd.d 0xc(%sp),%fp0 # fadd w/ dbl src 10311 1.1 is rts 10312 1.1 is 10313 1.1 is global _faddx_ 10314 1.1 is _faddx_: 10315 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst 10316 1.1 is fadd.x 0x10(%sp),%fp0 # fadd w/ ext src 10317 1.1 is rts 10318 1.1 is 10319 1.1 is global _fsubs_ 10320 1.1 is _fsubs_: 10321 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10322 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10323 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst 10324 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10325 1.1 is fsub.s 0x8(%sp),%fp0 # fsub w/ sgl src 10326 1.1 is rts 10327 1.1 is 10328 1.1 is global _fsubd_ 10329 1.1 is _fsubd_: 10330 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10331 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10332 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst 10333 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10334 1.1 is fsub.d 0xc(%sp),%fp0 # fsub w/ dbl src 10335 1.1 is rts 10336 1.1 is 10337 1.1 is global _fsubx_ 10338 1.1 is _fsubx_: 10339 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst 10340 1.1 is fsub.x 0x10(%sp),%fp0 # fsub w/ ext src 10341 1.1 is rts 10342 1.1 is 10343 1.1 is global _fmuls_ 10344 1.1 is _fmuls_: 10345 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10346 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10347 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst 10348 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10349 1.1 is fmul.s 0x8(%sp),%fp0 # fmul w/ sgl src 10350 1.1 is rts 10351 1.1 is 10352 1.1 is global _fmuld_ 10353 1.1 is _fmuld_: 10354 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10355 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10356 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst 10357 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10358 1.1 is fmul.d 0xc(%sp),%fp0 # fmul w/ dbl src 10359 1.1 is rts 10360 1.1 is 10361 1.1 is global _fmulx_ 10362 1.1 is _fmulx_: 10363 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst 10364 1.1 is fmul.x 0x10(%sp),%fp0 # fmul w/ ext src 10365 1.1 is rts 10366 1.1 is 10367 1.1 is global _fdivs_ 10368 1.1 is _fdivs_: 10369 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10370 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10371 1.1 is fmov.s 0x8(%sp),%fp0 # load sgl dst 10372 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10373 1.1 is fdiv.s 0x8(%sp),%fp0 # fdiv w/ sgl src 10374 1.1 is rts 10375 1.1 is 10376 1.1 is global _fdivd_ 10377 1.1 is _fdivd_: 10378 1.1 is fmov.l %fpcr,-(%sp) # save fpcr 10379 1.1 is fmov.l &0x00000000,%fpcr # clear fpcr for load 10380 1.1 is fmov.d 0x8(%sp),%fp0 # load dbl dst 10381 1.1 is fmov.l (%sp)+,%fpcr # restore fpcr 10382 1.1 is fdiv.d 0xc(%sp),%fp0 # fdiv w/ dbl src 10383 1.1 is rts 10384 1.1 is 10385 1.1 is global _fdivx_ 10386 1.1 is _fdivx_: 10387 1.1 is fmovm.x 0x4(%sp),&0x80 # load ext dst 10388 1.1 is fdiv.x 0x10(%sp),%fp0 # fdiv w/ ext src 10389 1.1 is rts 10390 1.1 is 10391 1.1 is global _fabss_ 10392 1.1 is _fabss_: 10393 1.1 is fabs.s 0x4(%sp),%fp0 # fabs w/ sgl src 10394 1.1 is rts 10395 1.1 is 10396 1.1 is global _fabsd_ 10397 1.1 is _fabsd_: 10398 1.1 is fabs.d 0x4(%sp),%fp0 # fabs w/ dbl src 10399 1.1 is rts 10400 1.1 is 10401 1.1 is global _fabsx_ 10402 1.1 is _fabsx_: 10403 1.1 is fabs.x 0x4(%sp),%fp0 # fabs w/ ext src 10404 1.1 is rts 10405 1.1 is 10406 1.1 is global _fnegs_ 10407 1.1 is _fnegs_: 10408 1.1 is fneg.s 0x4(%sp),%fp0 # fneg w/ sgl src 10409 1.1 is rts 10410 1.1 is 10411 1.1 is global _fnegd_ 10412 1.1 is _fnegd_: 10413 1.1 is fneg.d 0x4(%sp),%fp0 # fneg w/ dbl src 10414 1.1 is rts 10415 1.1 is 10416 1.1 is global _fnegx_ 10417 1.1 is _fnegx_: 10418 1.1 is fneg.x 0x4(%sp),%fp0 # fneg w/ ext src 10419 1.1 is rts 10420 1.1 is 10421 1.1 is global _fsqrts_ 10422 1.1 is _fsqrts_: 10423 1.1 is fsqrt.s 0x4(%sp),%fp0 # fsqrt w/ sgl src 10424 1.1 is rts 10425 1.1 is 10426 1.1 is global _fsqrtd_ 10427 1.1 is _fsqrtd_: 10428 1.1 is fsqrt.d 0x4(%sp),%fp0 # fsqrt w/ dbl src 10429 1.1 is rts 10430 1.1 is 10431 1.1 is global _fsqrtx_ 10432 1.1 is _fsqrtx_: 10433 1.1 is fsqrt.x 0x4(%sp),%fp0 # fsqrt w/ ext src 10434 1.1 is rts 10435 1.1 is 10436 1.1 is global _fints_ 10437 1.1 is _fints_: 10438 1.1 is fint.s 0x4(%sp),%fp0 # fint w/ sgl src 10439 1.1 is rts 10440 1.1 is 10441 1.1 is global _fintd_ 10442 1.1 is _fintd_: 10443 1.1 is fint.d 0x4(%sp),%fp0 # fint w/ dbl src 10444 1.1 is rts 10445 1.1 is 10446 1.1 is global _fintx_ 10447 1.1 is _fintx_: 10448 1.1 is fint.x 0x4(%sp),%fp0 # fint w/ ext src 10449 1.1 is rts 10450 1.1 is 10451 1.1 is global _fintrzs_ 10452 1.1 is _fintrzs_: 10453 1.1 is fintrz.s 0x4(%sp),%fp0 # fintrz w/ sgl src 10454 1.1 is rts 10455 1.1 is 10456 1.1 is global _fintrzd_ 10457 1.1 is _fintrzd_: 10458 1.1 is fintrz.d 0x4(%sp),%fp0 # fintrx w/ dbl src 10459 1.1 is rts 10460 1.1 is 10461 1.1 is global _fintrzx_ 10462 1.1 is _fintrzx_: 10463 1.1 is fintrz.x 0x4(%sp),%fp0 # fintrz w/ ext src 10464 1.1 is rts 10465 1.1 is 10466 1.1 is ######################################################################## 10467 1.1 is 10468 1.1 is ######################################################################### 10469 1.1 is # src_zero(): Return signed zero according to sign of src operand. # 10470 1.1 is ######################################################################### 10471 1.1 is global src_zero 10472 1.1 is src_zero: 10473 1.1 is tst.b SRC_EX(%a0) # get sign of src operand 10474 1.1 is bmi.b ld_mzero # if neg, load neg zero 10475 1.1 is 10476 1.1 is # 10477 1.1 is # ld_pzero(): return a positive zero. 10478 1.1 is # 10479 1.1 is global ld_pzero 10480 1.1 is ld_pzero: 10481 1.1 is fmov.s &0x00000000,%fp0 # load +0 10482 1.1 is mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 10483 1.1 is rts 10484 1.1 is 10485 1.1 is # ld_mzero(): return a negative zero. 10486 1.1 is global ld_mzero 10487 1.1 is ld_mzero: 10488 1.1 is fmov.s &0x80000000,%fp0 # load -0 10489 1.1 is mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits 10490 1.1 is rts 10491 1.1 is 10492 1.1 is ######################################################################### 10493 1.1 is # dst_zero(): Return signed zero according to sign of dst operand. # 10494 1.1 is ######################################################################### 10495 1.1 is global dst_zero 10496 1.1 is dst_zero: 10497 1.1 is tst.b DST_EX(%a1) # get sign of dst operand 10498 1.1 is bmi.b ld_mzero # if neg, load neg zero 10499 1.1 is bra.b ld_pzero # load positive zero 10500 1.1 is 10501 1.1 is ######################################################################### 10502 1.1 is # src_inf(): Return signed inf according to sign of src operand. # 10503 1.1 is ######################################################################### 10504 1.1 is global src_inf 10505 1.1 is src_inf: 10506 1.1 is tst.b SRC_EX(%a0) # get sign of src operand 10507 1.1 is bmi.b ld_minf # if negative branch 10508 1.1 is 10509 1.1 is # 10510 1.1 is # ld_pinf(): return a positive infinity. 10511 1.1 is # 10512 1.1 is global ld_pinf 10513 1.1 is ld_pinf: 10514 1.1 is fmov.s &0x7f800000,%fp0 # load +INF 10515 1.1 is mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit 10516 1.1 is rts 10517 1.1 is 10518 1.1 is # 10519 1.1 is # ld_minf():return a negative infinity. 10520 1.1 is # 10521 1.1 is global ld_minf 10522 1.1 is ld_minf: 10523 1.1 is fmov.s &0xff800000,%fp0 # load -INF 10524 1.1 is mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits 10525 1.1 is rts 10526 1.1 is 10527 1.1 is ######################################################################### 10528 1.1 is # dst_inf(): Return signed inf according to sign of dst operand. # 10529 1.1 is ######################################################################### 10530 1.1 is global dst_inf 10531 1.1 is dst_inf: 10532 1.1 is tst.b DST_EX(%a1) # get sign of dst operand 10533 1.1 is bmi.b ld_minf # if negative branch 10534 1.1 is bra.b ld_pinf 10535 1.1 is 10536 1.1 is global szr_inf 10537 1.1 is ################################################################# 10538 1.1 is # szr_inf(): Return +ZERO for a negative src operand or # 10539 1.1 is # +INF for a positive src operand. # 10540 1.1 is # Routine used for fetox, ftwotox, and ftentox. # 10541 1.1 is ################################################################# 10542 1.1 is szr_inf: 10543 1.1 is tst.b SRC_EX(%a0) # check sign of source 10544 1.1 is bmi.b ld_pzero 10545 1.1 is bra.b ld_pinf 10546 1.1 is 10547 1.1 is ######################################################################### 10548 1.1 is # sopr_inf(): Return +INF for a positive src operand or # 10549 1.1 is # jump to operand error routine for a negative src operand. # 10550 1.1 is # Routine used for flogn, flognp1, flog10, and flog2. # 10551 1.1 is ######################################################################### 10552 1.1 is global sopr_inf 10553 1.1 is sopr_inf: 10554 1.1 is tst.b SRC_EX(%a0) # check sign of source 10555 1.1 is bmi.w t_operr 10556 1.1 is bra.b ld_pinf 10557 1.1 is 10558 1.1 is ################################################################# 10559 1.1 is # setoxm1i(): Return minus one for a negative src operand or # 10560 1.1 is # positive infinity for a positive src operand. # 10561 1.1 is # Routine used for fetoxm1. # 10562 1.1 is ################################################################# 10563 1.1 is global setoxm1i 10564 1.1 is setoxm1i: 10565 1.1 is tst.b SRC_EX(%a0) # check sign of source 10566 1.1 is bmi.b ld_mone 10567 1.1 is bra.b ld_pinf 10568 1.1 is 10569 1.1 is ######################################################################### 10570 1.1 is # src_one(): Return signed one according to sign of src operand. # 10571 1.1 is ######################################################################### 10572 1.1 is global src_one 10573 1.1 is src_one: 10574 1.1 is tst.b SRC_EX(%a0) # check sign of source 10575 1.1 is bmi.b ld_mone 10576 1.1 is 10577 1.1 is # 10578 1.1 is # ld_pone(): return positive one. 10579 1.1 is # 10580 1.1 is global ld_pone 10581 1.1 is ld_pone: 10582 1.1 is fmov.s &0x3f800000,%fp0 # load +1 10583 1.1 is clr.b FPSR_CC(%a6) 10584 1.1 is rts 10585 1.1 is 10586 1.1 is # 10587 1.1 is # ld_mone(): return negative one. 10588 1.1 is # 10589 1.1 is global ld_mone 10590 1.1 is ld_mone: 10591 1.1 is fmov.s &0xbf800000,%fp0 # load -1 10592 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 10593 1.1 is rts 10594 1.1 is 10595 1.1 is ppiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235 10596 1.1 is mpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235 10597 1.1 is 10598 1.1 is ################################################################# 10599 1.1 is # spi_2(): Return signed PI/2 according to sign of src operand. # 10600 1.1 is ################################################################# 10601 1.1 is global spi_2 10602 1.1 is spi_2: 10603 1.1 is tst.b SRC_EX(%a0) # check sign of source 10604 1.1 is bmi.b ld_mpi2 10605 1.1 is 10606 1.1 is # 10607 1.1 is # ld_ppi2(): return positive PI/2. 10608 1.1 is # 10609 1.1 is global ld_ppi2 10610 1.1 is ld_ppi2: 10611 1.1 is fmov.l %d0,%fpcr 10612 1.1 is fmov.x ppiby2(%pc),%fp0 # load +pi/2 10613 1.1 is bra.w t_pinx2 # set INEX2 10614 1.1 is 10615 1.1 is # 10616 1.1 is # ld_mpi2(): return negative PI/2. 10617 1.1 is # 10618 1.1 is global ld_mpi2 10619 1.1 is ld_mpi2: 10620 1.1 is fmov.l %d0,%fpcr 10621 1.1 is fmov.x mpiby2(%pc),%fp0 # load -pi/2 10622 1.1 is bra.w t_minx2 # set INEX2 10623 1.1 is 10624 1.1 is #################################################### 10625 1.1 is # The following routines give support for fsincos. # 10626 1.1 is #################################################### 10627 1.1 is 10628 1.1 is # 10629 1.1 is # ssincosz(): When the src operand is ZERO, store a one in the 10630 1.1 is # cosine register and return a ZERO in fp0 w/ the same sign 10631 1.1 is # as the src operand. 10632 1.1 is # 10633 1.1 is global ssincosz 10634 1.1 is ssincosz: 10635 1.1 is fmov.s &0x3f800000,%fp1 10636 1.1 is tst.b SRC_EX(%a0) # test sign 10637 1.1 is bpl.b sincoszp 10638 1.1 is fmov.s &0x80000000,%fp0 # return sin result in fp0 10639 1.1 is mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) 10640 1.1 is rts 10641 1.1 is sincoszp: 10642 1.1 is fmov.s &0x00000000,%fp0 # return sin result in fp0 10643 1.1 is mov.b &z_bmask,FPSR_CC(%a6) 10644 1.1 is rts 10645 1.1 is 10646 1.1 is # 10647 1.1 is # ssincosi(): When the src operand is INF, store a QNAN in the cosine 10648 1.1 is # register and jump to the operand error routine for negative 10649 1.1 is # src operands. 10650 1.1 is # 10651 1.1 is global ssincosi 10652 1.1 is ssincosi: 10653 1.1 is fmov.x qnan(%pc),%fp1 # load NAN 10654 1.1 is bra.w t_operr 10655 1.1 is 10656 1.1 is # 10657 1.1 is # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine 10658 1.1 is # register and branch to the src QNAN routine. 10659 1.1 is # 10660 1.1 is global ssincosqnan 10661 1.1 is ssincosqnan: 10662 1.1 is fmov.x LOCAL_EX(%a0),%fp1 10663 1.1 is bra.w src_qnan 10664 1.1 is 10665 1.1 is ######################################################################## 10666 1.1 is 10667 1.1 is global smod_sdnrm 10668 1.1 is global smod_snorm 10669 1.1 is smod_sdnrm: 10670 1.1 is smod_snorm: 10671 1.1 is mov.b DTAG(%a6),%d1 10672 1.1 is beq.l smod 10673 1.1 is cmpi.b %d1,&ZERO 10674 1.1 is beq.w smod_zro 10675 1.1 is cmpi.b %d1,&INF 10676 1.1 is beq.l t_operr 10677 1.1 is cmpi.b %d1,&DENORM 10678 1.1 is beq.l smod 10679 1.1 is bra.l dst_qnan 10680 1.1 is 10681 1.1 is global smod_szero 10682 1.1 is smod_szero: 10683 1.1 is mov.b DTAG(%a6),%d1 10684 1.1 is beq.l t_operr 10685 1.1 is cmpi.b %d1,&ZERO 10686 1.1 is beq.l t_operr 10687 1.1 is cmpi.b %d1,&INF 10688 1.1 is beq.l t_operr 10689 1.1 is cmpi.b %d1,&DENORM 10690 1.1 is beq.l t_operr 10691 1.1 is bra.l dst_qnan 10692 1.1 is 10693 1.1 is global smod_sinf 10694 1.1 is smod_sinf: 10695 1.1 is mov.b DTAG(%a6),%d1 10696 1.1 is beq.l smod_fpn 10697 1.1 is cmpi.b %d1,&ZERO 10698 1.1 is beq.l smod_zro 10699 1.1 is cmpi.b %d1,&INF 10700 1.1 is beq.l t_operr 10701 1.1 is cmpi.b %d1,&DENORM 10702 1.1 is beq.l smod_fpn 10703 1.1 is bra.l dst_qnan 10704 1.1 is 10705 1.1 is smod_zro: 10706 1.1 is srem_zro: 10707 1.1 is mov.b SRC_EX(%a0),%d1 # get src sign 10708 1.1 is mov.b DST_EX(%a1),%d0 # get dst sign 10709 1.1 is eor.b %d0,%d1 # get qbyte sign 10710 1.1 is andi.b &0x80,%d1 10711 1.1 is mov.b %d1,FPSR_QBYTE(%a6) 10712 1.1 is tst.b %d0 10713 1.1 is bpl.w ld_pzero 10714 1.1 is bra.w ld_mzero 10715 1.1 is 10716 1.1 is smod_fpn: 10717 1.1 is srem_fpn: 10718 1.1 is clr.b FPSR_QBYTE(%a6) 10719 1.1 is mov.l %d0,-(%sp) 10720 1.1 is mov.b SRC_EX(%a0),%d1 # get src sign 10721 1.1 is mov.b DST_EX(%a1),%d0 # get dst sign 10722 1.1 is eor.b %d0,%d1 # get qbyte sign 10723 1.1 is andi.b &0x80,%d1 10724 1.1 is mov.b %d1,FPSR_QBYTE(%a6) 10725 1.1 is cmpi.b DTAG(%a6),&DENORM 10726 1.1 is bne.b smod_nrm 10727 1.1 is lea DST(%a1),%a0 10728 1.1 is mov.l (%sp)+,%d0 10729 1.1 is bra t_resdnrm 10730 1.1 is smod_nrm: 10731 1.1 is fmov.l (%sp)+,%fpcr 10732 1.1 is fmov.x DST(%a1),%fp0 10733 1.1 is tst.b DST_EX(%a1) 10734 1.1 is bmi.b smod_nrm_neg 10735 1.1 is rts 10736 1.1 is 10737 1.1 is smod_nrm_neg: 10738 1.1 is mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' code 10739 1.1 is rts 10740 1.1 is 10741 1.1 is ######################################################################### 10742 1.1 is global srem_snorm 10743 1.1 is global srem_sdnrm 10744 1.1 is srem_sdnrm: 10745 1.1 is srem_snorm: 10746 1.1 is mov.b DTAG(%a6),%d1 10747 1.1 is beq.l srem 10748 1.1 is cmpi.b %d1,&ZERO 10749 1.1 is beq.w srem_zro 10750 1.1 is cmpi.b %d1,&INF 10751 1.1 is beq.l t_operr 10752 1.1 is cmpi.b %d1,&DENORM 10753 1.1 is beq.l srem 10754 1.1 is bra.l dst_qnan 10755 1.1 is 10756 1.1 is global srem_szero 10757 1.1 is srem_szero: 10758 1.1 is mov.b DTAG(%a6),%d1 10759 1.1 is beq.l t_operr 10760 1.1 is cmpi.b %d1,&ZERO 10761 1.1 is beq.l t_operr 10762 1.1 is cmpi.b %d1,&INF 10763 1.1 is beq.l t_operr 10764 1.1 is cmpi.b %d1,&DENORM 10765 1.1 is beq.l t_operr 10766 1.1 is bra.l dst_qnan 10767 1.1 is 10768 1.1 is global srem_sinf 10769 1.1 is srem_sinf: 10770 1.1 is mov.b DTAG(%a6),%d1 10771 1.1 is beq.w srem_fpn 10772 1.1 is cmpi.b %d1,&ZERO 10773 1.1 is beq.w srem_zro 10774 1.1 is cmpi.b %d1,&INF 10775 1.1 is beq.l t_operr 10776 1.1 is cmpi.b %d1,&DENORM 10777 1.1 is beq.l srem_fpn 10778 1.1 is bra.l dst_qnan 10779 1.1 is 10780 1.1 is ######################################################################### 10781 1.1 is 10782 1.1 is global sscale_snorm 10783 1.1 is global sscale_sdnrm 10784 1.1 is sscale_snorm: 10785 1.1 is sscale_sdnrm: 10786 1.1 is mov.b DTAG(%a6),%d1 10787 1.1 is beq.l sscale 10788 1.1 is cmpi.b %d1,&ZERO 10789 1.1 is beq.l dst_zero 10790 1.1 is cmpi.b %d1,&INF 10791 1.1 is beq.l dst_inf 10792 1.1 is cmpi.b %d1,&DENORM 10793 1.1 is beq.l sscale 10794 1.1 is bra.l dst_qnan 10795 1.1 is 10796 1.1 is global sscale_szero 10797 1.1 is sscale_szero: 10798 1.1 is mov.b DTAG(%a6),%d1 10799 1.1 is beq.l sscale 10800 1.1 is cmpi.b %d1,&ZERO 10801 1.1 is beq.l dst_zero 10802 1.1 is cmpi.b %d1,&INF 10803 1.1 is beq.l dst_inf 10804 1.1 is cmpi.b %d1,&DENORM 10805 1.1 is beq.l sscale 10806 1.1 is bra.l dst_qnan 10807 1.1 is 10808 1.1 is global sscale_sinf 10809 1.1 is sscale_sinf: 10810 1.1 is mov.b DTAG(%a6),%d1 10811 1.1 is beq.l t_operr 10812 1.1 is cmpi.b %d1,&QNAN 10813 1.1 is beq.l dst_qnan 10814 1.1 is bra.l t_operr 10815 1.1 is 10816 1.1 is ######################################################################## 10817 1.1 is 10818 1.1 is global sop_sqnan 10819 1.1 is sop_sqnan: 10820 1.1 is mov.b DTAG(%a6),%d1 10821 1.1 is cmpi.b %d1,&QNAN 10822 1.1 is beq.l dst_qnan 10823 1.1 is bra.l src_qnan 10824 1.1 is 10825 1.1 is ######################################################################### 10826 1.1 is # norm(): normalize the mantissa of an extended precision input. the # 10827 1.1 is # input operand should not be normalized already. # 10828 1.1 is # # 10829 1.1 is # XDEF **************************************************************** # 10830 1.1 is # norm() # 10831 1.1 is # # 10832 1.1 is # XREF **************************************************************** # 10833 1.1 is # none # 10834 1.1 is # # 10835 1.1 is # INPUT *************************************************************** # 10836 1.1 is # a0 = pointer fp extended precision operand to normalize # 10837 1.1 is # # 10838 1.1 is # OUTPUT ************************************************************** # 10839 1.1 is # d0 = number of bit positions the mantissa was shifted # 10840 1.1 is # a0 = the input operand's mantissa is normalized; the exponent # 10841 1.1 is # is unchanged. # 10842 1.1 is # # 10843 1.1 is ######################################################################### 10844 1.1 is global norm 10845 1.1 is norm: 10846 1.1 is mov.l %d2, -(%sp) # create some temp regs 10847 1.1 is mov.l %d3, -(%sp) 10848 1.1 is 10849 1.1 is mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa) 10850 1.1 is mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa) 10851 1.1 is 10852 1.1 is bfffo %d0{&0:&32}, %d2 # how many places to shift? 10853 1.1 is beq.b norm_lo # hi(man) is all zeroes! 10854 1.1 is 10855 1.1 is norm_hi: 10856 1.1 is lsl.l %d2, %d0 # left shift hi(man) 10857 1.1 is bfextu %d1{&0:%d2}, %d3 # extract lo bits 10858 1.1 is 10859 1.1 is or.l %d3, %d0 # create hi(man) 10860 1.1 is lsl.l %d2, %d1 # create lo(man) 10861 1.1 is 10862 1.1 is mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 10863 1.1 is mov.l %d1, FTEMP_LO(%a0) # store new lo(man) 10864 1.1 is 10865 1.1 is mov.l %d2, %d0 # return shift amount 10866 1.1 is 10867 1.1 is mov.l (%sp)+, %d3 # restore temp regs 10868 1.1 is mov.l (%sp)+, %d2 10869 1.1 is 10870 1.1 is rts 10871 1.1 is 10872 1.1 is norm_lo: 10873 1.1 is bfffo %d1{&0:&32}, %d2 # how many places to shift? 10874 1.1 is lsl.l %d2, %d1 # shift lo(man) 10875 1.1 is add.l &32, %d2 # add 32 to shft amount 10876 1.1 is 10877 1.1 is mov.l %d1, FTEMP_HI(%a0) # store hi(man) 10878 1.1 is clr.l FTEMP_LO(%a0) # lo(man) is now zero 10879 1.1 is 10880 1.1 is mov.l %d2, %d0 # return shift amount 10881 1.1 is 10882 1.1 is mov.l (%sp)+, %d3 # restore temp regs 10883 1.1 is mov.l (%sp)+, %d2 10884 1.1 is 10885 1.1 is rts 10886 1.1 is 10887 1.1 is ######################################################################### 10888 1.1 is # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO # 10889 1.1 is # - returns corresponding optype tag # 10890 1.1 is # # 10891 1.1 is # XDEF **************************************************************** # 10892 1.1 is # unnorm_fix() # 10893 1.1 is # # 10894 1.1 is # XREF **************************************************************** # 10895 1.1 is # norm() - normalize the mantissa # 10896 1.1 is # # 10897 1.1 is # INPUT *************************************************************** # 10898 1.1 is # a0 = pointer to unnormalized extended precision number # 10899 1.1 is # # 10900 1.1 is # OUTPUT ************************************************************** # 10901 1.1 is # d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO # 10902 1.1 is # a0 = input operand has been converted to a norm, denorm, or # 10903 1.1 is # zero; both the exponent and mantissa are changed. # 10904 1.1 is # # 10905 1.1 is ######################################################################### 10906 1.1 is 10907 1.1 is global unnorm_fix 10908 1.1 is unnorm_fix: 10909 1.1 is bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed? 10910 1.1 is bne.b unnorm_shift # hi(man) is not all zeroes 10911 1.1 is 10912 1.1 is # 10913 1.1 is # hi(man) is all zeroes so see if any bits in lo(man) are set 10914 1.1 is # 10915 1.1 is unnorm_chk_lo: 10916 1.1 is bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero? 10917 1.1 is beq.w unnorm_zero # yes 10918 1.1 is 10919 1.1 is add.w &32, %d0 # no; fix shift distance 10920 1.1 is 10921 1.1 is # 10922 1.1 is # d0 = # shifts needed for complete normalization 10923 1.1 is # 10924 1.1 is unnorm_shift: 10925 1.1 is clr.l %d1 # clear top word 10926 1.1 is mov.w FTEMP_EX(%a0), %d1 # extract exponent 10927 1.1 is and.w &0x7fff, %d1 # strip off sgn 10928 1.1 is 10929 1.1 is cmp.w %d0, %d1 # will denorm push exp < 0? 10930 1.1 is bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0 10931 1.1 is 10932 1.1 is # 10933 1.1 is # exponent would not go < 0. therefore, number stays normalized 10934 1.1 is # 10935 1.1 is sub.w %d0, %d1 # shift exponent value 10936 1.1 is mov.w FTEMP_EX(%a0), %d0 # load old exponent 10937 1.1 is and.w &0x8000, %d0 # save old sign 10938 1.1 is or.w %d0, %d1 # {sgn,new exp} 10939 1.1 is mov.w %d1, FTEMP_EX(%a0) # insert new exponent 10940 1.1 is 10941 1.1 is bsr.l norm # normalize UNNORM 10942 1.1 is 10943 1.1 is mov.b &NORM, %d0 # return new optype tag 10944 1.1 is rts 10945 1.1 is 10946 1.1 is # 10947 1.1 is # exponent would go < 0, so only denormalize until exp = 0 10948 1.1 is # 10949 1.1 is unnorm_nrm_zero: 10950 1.1 is cmp.b %d1, &32 # is exp <= 32? 10951 1.1 is bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent 10952 1.1 is 10953 1.1 is bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man) 10954 1.1 is mov.l %d0, FTEMP_HI(%a0) # save new hi(man) 10955 1.1 is 10956 1.1 is mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 10957 1.1 is lsl.l %d1, %d0 # extract new lo(man) 10958 1.1 is mov.l %d0, FTEMP_LO(%a0) # save new lo(man) 10959 1.1 is 10960 1.1 is and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 10961 1.1 is 10962 1.1 is mov.b &DENORM, %d0 # return new optype tag 10963 1.1 is rts 10964 1.1 is 10965 1.1 is # 10966 1.1 is # only mantissa bits set are in lo(man) 10967 1.1 is # 10968 1.1 is unnorm_nrm_zero_lrg: 10969 1.1 is sub.w &32, %d1 # adjust shft amt by 32 10970 1.1 is 10971 1.1 is mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 10972 1.1 is lsl.l %d1, %d0 # left shift lo(man) 10973 1.1 is 10974 1.1 is mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 10975 1.1 is clr.l FTEMP_LO(%a0) # lo(man) = 0 10976 1.1 is 10977 1.1 is and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 10978 1.1 is 10979 1.1 is mov.b &DENORM, %d0 # return new optype tag 10980 1.1 is rts 10981 1.1 is 10982 1.1 is # 10983 1.1 is # whole mantissa is zero so this UNNORM is actually a zero 10984 1.1 is # 10985 1.1 is unnorm_zero: 10986 1.1 is and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero 10987 1.1 is 10988 1.1 is mov.b &ZERO, %d0 # fix optype tag 10989 1.1 is rts 10990