11da177e4SLinus Torvalds~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 21da177e4SLinus TorvaldsMOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 31da177e4SLinus TorvaldsM68000 Hi-Performance Microprocessor Division 41da177e4SLinus TorvaldsM68060 Software Package 51da177e4SLinus TorvaldsProduction Release P1.00 -- October 10, 1994 61da177e4SLinus Torvalds 7*96de0e25SJan EngelhardtM68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved. 81da177e4SLinus Torvalds 91da177e4SLinus TorvaldsTHE SOFTWARE is provided on an "AS IS" basis and without warranty. 101da177e4SLinus TorvaldsTo the maximum extent permitted by applicable law, 111da177e4SLinus TorvaldsMOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 121da177e4SLinus TorvaldsINCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 131da177e4SLinus Torvaldsand any warranty against infringement with regard to the SOFTWARE 141da177e4SLinus Torvalds(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials. 151da177e4SLinus Torvalds 161da177e4SLinus TorvaldsTo the maximum extent permitted by applicable law, 171da177e4SLinus TorvaldsIN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 181da177e4SLinus Torvalds(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 191da177e4SLinus TorvaldsBUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) 201da177e4SLinus TorvaldsARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. 211da177e4SLinus TorvaldsMotorola assumes no responsibility for the maintenance and support of the SOFTWARE. 221da177e4SLinus Torvalds 231da177e4SLinus TorvaldsYou are hereby granted a copyright license to use, modify, and distribute the SOFTWARE 241da177e4SLinus Torvaldsso long as this entire notice is retained without alteration in any modified and/or 251da177e4SLinus Torvaldsredistributed versions, and that such modified versions are clearly identified as such. 261da177e4SLinus TorvaldsNo licenses are granted by implication, estoppel or otherwise under any patents 271da177e4SLinus Torvaldsor trademarks of Motorola, Inc. 281da177e4SLinus Torvalds~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291da177e4SLinus Torvalds# 301da177e4SLinus Torvalds# lfptop.s: 311da177e4SLinus Torvalds# This file is appended to the top of the 060ILSP package 321da177e4SLinus Torvalds# and contains the entry points into the package. The user, in 331da177e4SLinus Torvalds# effect, branches to one of the branch table entries located here. 341da177e4SLinus Torvalds# 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds bra.l _facoss_ 371da177e4SLinus Torvalds short 0x0000 381da177e4SLinus Torvalds bra.l _facosd_ 391da177e4SLinus Torvalds short 0x0000 401da177e4SLinus Torvalds bra.l _facosx_ 411da177e4SLinus Torvalds short 0x0000 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds bra.l _fasins_ 441da177e4SLinus Torvalds short 0x0000 451da177e4SLinus Torvalds bra.l _fasind_ 461da177e4SLinus Torvalds short 0x0000 471da177e4SLinus Torvalds bra.l _fasinx_ 481da177e4SLinus Torvalds short 0x0000 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds bra.l _fatans_ 511da177e4SLinus Torvalds short 0x0000 521da177e4SLinus Torvalds bra.l _fatand_ 531da177e4SLinus Torvalds short 0x0000 541da177e4SLinus Torvalds bra.l _fatanx_ 551da177e4SLinus Torvalds short 0x0000 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds bra.l _fatanhs_ 581da177e4SLinus Torvalds short 0x0000 591da177e4SLinus Torvalds bra.l _fatanhd_ 601da177e4SLinus Torvalds short 0x0000 611da177e4SLinus Torvalds bra.l _fatanhx_ 621da177e4SLinus Torvalds short 0x0000 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds bra.l _fcoss_ 651da177e4SLinus Torvalds short 0x0000 661da177e4SLinus Torvalds bra.l _fcosd_ 671da177e4SLinus Torvalds short 0x0000 681da177e4SLinus Torvalds bra.l _fcosx_ 691da177e4SLinus Torvalds short 0x0000 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds bra.l _fcoshs_ 721da177e4SLinus Torvalds short 0x0000 731da177e4SLinus Torvalds bra.l _fcoshd_ 741da177e4SLinus Torvalds short 0x0000 751da177e4SLinus Torvalds bra.l _fcoshx_ 761da177e4SLinus Torvalds short 0x0000 771da177e4SLinus Torvalds 781da177e4SLinus Torvalds bra.l _fetoxs_ 791da177e4SLinus Torvalds short 0x0000 801da177e4SLinus Torvalds bra.l _fetoxd_ 811da177e4SLinus Torvalds short 0x0000 821da177e4SLinus Torvalds bra.l _fetoxx_ 831da177e4SLinus Torvalds short 0x0000 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds bra.l _fetoxm1s_ 861da177e4SLinus Torvalds short 0x0000 871da177e4SLinus Torvalds bra.l _fetoxm1d_ 881da177e4SLinus Torvalds short 0x0000 891da177e4SLinus Torvalds bra.l _fetoxm1x_ 901da177e4SLinus Torvalds short 0x0000 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds bra.l _fgetexps_ 931da177e4SLinus Torvalds short 0x0000 941da177e4SLinus Torvalds bra.l _fgetexpd_ 951da177e4SLinus Torvalds short 0x0000 961da177e4SLinus Torvalds bra.l _fgetexpx_ 971da177e4SLinus Torvalds short 0x0000 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds bra.l _fgetmans_ 1001da177e4SLinus Torvalds short 0x0000 1011da177e4SLinus Torvalds bra.l _fgetmand_ 1021da177e4SLinus Torvalds short 0x0000 1031da177e4SLinus Torvalds bra.l _fgetmanx_ 1041da177e4SLinus Torvalds short 0x0000 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds bra.l _flog10s_ 1071da177e4SLinus Torvalds short 0x0000 1081da177e4SLinus Torvalds bra.l _flog10d_ 1091da177e4SLinus Torvalds short 0x0000 1101da177e4SLinus Torvalds bra.l _flog10x_ 1111da177e4SLinus Torvalds short 0x0000 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds bra.l _flog2s_ 1141da177e4SLinus Torvalds short 0x0000 1151da177e4SLinus Torvalds bra.l _flog2d_ 1161da177e4SLinus Torvalds short 0x0000 1171da177e4SLinus Torvalds bra.l _flog2x_ 1181da177e4SLinus Torvalds short 0x0000 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds bra.l _flogns_ 1211da177e4SLinus Torvalds short 0x0000 1221da177e4SLinus Torvalds bra.l _flognd_ 1231da177e4SLinus Torvalds short 0x0000 1241da177e4SLinus Torvalds bra.l _flognx_ 1251da177e4SLinus Torvalds short 0x0000 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds bra.l _flognp1s_ 1281da177e4SLinus Torvalds short 0x0000 1291da177e4SLinus Torvalds bra.l _flognp1d_ 1301da177e4SLinus Torvalds short 0x0000 1311da177e4SLinus Torvalds bra.l _flognp1x_ 1321da177e4SLinus Torvalds short 0x0000 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds bra.l _fmods_ 1351da177e4SLinus Torvalds short 0x0000 1361da177e4SLinus Torvalds bra.l _fmodd_ 1371da177e4SLinus Torvalds short 0x0000 1381da177e4SLinus Torvalds bra.l _fmodx_ 1391da177e4SLinus Torvalds short 0x0000 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds bra.l _frems_ 1421da177e4SLinus Torvalds short 0x0000 1431da177e4SLinus Torvalds bra.l _fremd_ 1441da177e4SLinus Torvalds short 0x0000 1451da177e4SLinus Torvalds bra.l _fremx_ 1461da177e4SLinus Torvalds short 0x0000 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds bra.l _fscales_ 1491da177e4SLinus Torvalds short 0x0000 1501da177e4SLinus Torvalds bra.l _fscaled_ 1511da177e4SLinus Torvalds short 0x0000 1521da177e4SLinus Torvalds bra.l _fscalex_ 1531da177e4SLinus Torvalds short 0x0000 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds bra.l _fsins_ 1561da177e4SLinus Torvalds short 0x0000 1571da177e4SLinus Torvalds bra.l _fsind_ 1581da177e4SLinus Torvalds short 0x0000 1591da177e4SLinus Torvalds bra.l _fsinx_ 1601da177e4SLinus Torvalds short 0x0000 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds bra.l _fsincoss_ 1631da177e4SLinus Torvalds short 0x0000 1641da177e4SLinus Torvalds bra.l _fsincosd_ 1651da177e4SLinus Torvalds short 0x0000 1661da177e4SLinus Torvalds bra.l _fsincosx_ 1671da177e4SLinus Torvalds short 0x0000 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds bra.l _fsinhs_ 1701da177e4SLinus Torvalds short 0x0000 1711da177e4SLinus Torvalds bra.l _fsinhd_ 1721da177e4SLinus Torvalds short 0x0000 1731da177e4SLinus Torvalds bra.l _fsinhx_ 1741da177e4SLinus Torvalds short 0x0000 1751da177e4SLinus Torvalds 1761da177e4SLinus Torvalds bra.l _ftans_ 1771da177e4SLinus Torvalds short 0x0000 1781da177e4SLinus Torvalds bra.l _ftand_ 1791da177e4SLinus Torvalds short 0x0000 1801da177e4SLinus Torvalds bra.l _ftanx_ 1811da177e4SLinus Torvalds short 0x0000 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds bra.l _ftanhs_ 1841da177e4SLinus Torvalds short 0x0000 1851da177e4SLinus Torvalds bra.l _ftanhd_ 1861da177e4SLinus Torvalds short 0x0000 1871da177e4SLinus Torvalds bra.l _ftanhx_ 1881da177e4SLinus Torvalds short 0x0000 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds bra.l _ftentoxs_ 1911da177e4SLinus Torvalds short 0x0000 1921da177e4SLinus Torvalds bra.l _ftentoxd_ 1931da177e4SLinus Torvalds short 0x0000 1941da177e4SLinus Torvalds bra.l _ftentoxx_ 1951da177e4SLinus Torvalds short 0x0000 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds bra.l _ftwotoxs_ 1981da177e4SLinus Torvalds short 0x0000 1991da177e4SLinus Torvalds bra.l _ftwotoxd_ 2001da177e4SLinus Torvalds short 0x0000 2011da177e4SLinus Torvalds bra.l _ftwotoxx_ 2021da177e4SLinus Torvalds short 0x0000 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds bra.l _fabss_ 2051da177e4SLinus Torvalds short 0x0000 2061da177e4SLinus Torvalds bra.l _fabsd_ 2071da177e4SLinus Torvalds short 0x0000 2081da177e4SLinus Torvalds bra.l _fabsx_ 2091da177e4SLinus Torvalds short 0x0000 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds bra.l _fadds_ 2121da177e4SLinus Torvalds short 0x0000 2131da177e4SLinus Torvalds bra.l _faddd_ 2141da177e4SLinus Torvalds short 0x0000 2151da177e4SLinus Torvalds bra.l _faddx_ 2161da177e4SLinus Torvalds short 0x0000 2171da177e4SLinus Torvalds 2181da177e4SLinus Torvalds bra.l _fdivs_ 2191da177e4SLinus Torvalds short 0x0000 2201da177e4SLinus Torvalds bra.l _fdivd_ 2211da177e4SLinus Torvalds short 0x0000 2221da177e4SLinus Torvalds bra.l _fdivx_ 2231da177e4SLinus Torvalds short 0x0000 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds bra.l _fints_ 2261da177e4SLinus Torvalds short 0x0000 2271da177e4SLinus Torvalds bra.l _fintd_ 2281da177e4SLinus Torvalds short 0x0000 2291da177e4SLinus Torvalds bra.l _fintx_ 2301da177e4SLinus Torvalds short 0x0000 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds bra.l _fintrzs_ 2331da177e4SLinus Torvalds short 0x0000 2341da177e4SLinus Torvalds bra.l _fintrzd_ 2351da177e4SLinus Torvalds short 0x0000 2361da177e4SLinus Torvalds bra.l _fintrzx_ 2371da177e4SLinus Torvalds short 0x0000 2381da177e4SLinus Torvalds 2391da177e4SLinus Torvalds bra.l _fmuls_ 2401da177e4SLinus Torvalds short 0x0000 2411da177e4SLinus Torvalds bra.l _fmuld_ 2421da177e4SLinus Torvalds short 0x0000 2431da177e4SLinus Torvalds bra.l _fmulx_ 2441da177e4SLinus Torvalds short 0x0000 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds bra.l _fnegs_ 2471da177e4SLinus Torvalds short 0x0000 2481da177e4SLinus Torvalds bra.l _fnegd_ 2491da177e4SLinus Torvalds short 0x0000 2501da177e4SLinus Torvalds bra.l _fnegx_ 2511da177e4SLinus Torvalds short 0x0000 2521da177e4SLinus Torvalds 2531da177e4SLinus Torvalds bra.l _fsqrts_ 2541da177e4SLinus Torvalds short 0x0000 2551da177e4SLinus Torvalds bra.l _fsqrtd_ 2561da177e4SLinus Torvalds short 0x0000 2571da177e4SLinus Torvalds bra.l _fsqrtx_ 2581da177e4SLinus Torvalds short 0x0000 2591da177e4SLinus Torvalds 2601da177e4SLinus Torvalds bra.l _fsubs_ 2611da177e4SLinus Torvalds short 0x0000 2621da177e4SLinus Torvalds bra.l _fsubd_ 2631da177e4SLinus Torvalds short 0x0000 2641da177e4SLinus Torvalds bra.l _fsubx_ 2651da177e4SLinus Torvalds short 0x0000 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds# leave room for future possible additions 2681da177e4SLinus Torvalds align 0x400 2691da177e4SLinus Torvalds 2701da177e4SLinus Torvalds# 2711da177e4SLinus Torvalds# This file contains a set of define statements for constants 2721da177e4SLinus Torvalds# in order to promote readability within the corecode itself. 2731da177e4SLinus Torvalds# 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvaldsset LOCAL_SIZE, 192 # stack frame size(bytes) 2761da177e4SLinus Torvaldsset LV, -LOCAL_SIZE # stack offset 2771da177e4SLinus Torvalds 2781da177e4SLinus Torvaldsset EXC_SR, 0x4 # stack status register 2791da177e4SLinus Torvaldsset EXC_PC, 0x6 # stack pc 2801da177e4SLinus Torvaldsset EXC_VOFF, 0xa # stacked vector offset 2811da177e4SLinus Torvaldsset EXC_EA, 0xc # stacked <ea> 2821da177e4SLinus Torvalds 2831da177e4SLinus Torvaldsset EXC_FP, 0x0 # frame pointer 2841da177e4SLinus Torvalds 2851da177e4SLinus Torvaldsset EXC_AREGS, -68 # offset of all address regs 2861da177e4SLinus Torvaldsset EXC_DREGS, -100 # offset of all data regs 2871da177e4SLinus Torvaldsset EXC_FPREGS, -36 # offset of all fp regs 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvaldsset EXC_A7, EXC_AREGS+(7*4) # offset of saved a7 2901da177e4SLinus Torvaldsset OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7 2911da177e4SLinus Torvaldsset EXC_A6, EXC_AREGS+(6*4) # offset of saved a6 2921da177e4SLinus Torvaldsset EXC_A5, EXC_AREGS+(5*4) 2931da177e4SLinus Torvaldsset EXC_A4, EXC_AREGS+(4*4) 2941da177e4SLinus Torvaldsset EXC_A3, EXC_AREGS+(3*4) 2951da177e4SLinus Torvaldsset EXC_A2, EXC_AREGS+(2*4) 2961da177e4SLinus Torvaldsset EXC_A1, EXC_AREGS+(1*4) 2971da177e4SLinus Torvaldsset EXC_A0, EXC_AREGS+(0*4) 2981da177e4SLinus Torvaldsset EXC_D7, EXC_DREGS+(7*4) 2991da177e4SLinus Torvaldsset EXC_D6, EXC_DREGS+(6*4) 3001da177e4SLinus Torvaldsset EXC_D5, EXC_DREGS+(5*4) 3011da177e4SLinus Torvaldsset EXC_D4, EXC_DREGS+(4*4) 3021da177e4SLinus Torvaldsset EXC_D3, EXC_DREGS+(3*4) 3031da177e4SLinus Torvaldsset EXC_D2, EXC_DREGS+(2*4) 3041da177e4SLinus Torvaldsset EXC_D1, EXC_DREGS+(1*4) 3051da177e4SLinus Torvaldsset EXC_D0, EXC_DREGS+(0*4) 3061da177e4SLinus Torvalds 3071da177e4SLinus Torvaldsset EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0 3081da177e4SLinus Torvaldsset EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1 3091da177e4SLinus Torvaldsset EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used) 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvaldsset FP_SCR1, LV+80 # fp scratch 1 3121da177e4SLinus Torvaldsset FP_SCR1_EX, FP_SCR1+0 3131da177e4SLinus Torvaldsset FP_SCR1_SGN, FP_SCR1+2 3141da177e4SLinus Torvaldsset FP_SCR1_HI, FP_SCR1+4 3151da177e4SLinus Torvaldsset FP_SCR1_LO, FP_SCR1+8 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvaldsset FP_SCR0, LV+68 # fp scratch 0 3181da177e4SLinus Torvaldsset FP_SCR0_EX, FP_SCR0+0 3191da177e4SLinus Torvaldsset FP_SCR0_SGN, FP_SCR0+2 3201da177e4SLinus Torvaldsset FP_SCR0_HI, FP_SCR0+4 3211da177e4SLinus Torvaldsset FP_SCR0_LO, FP_SCR0+8 3221da177e4SLinus Torvalds 3231da177e4SLinus Torvaldsset FP_DST, LV+56 # fp destination operand 3241da177e4SLinus Torvaldsset FP_DST_EX, FP_DST+0 3251da177e4SLinus Torvaldsset FP_DST_SGN, FP_DST+2 3261da177e4SLinus Torvaldsset FP_DST_HI, FP_DST+4 3271da177e4SLinus Torvaldsset FP_DST_LO, FP_DST+8 3281da177e4SLinus Torvalds 3291da177e4SLinus Torvaldsset FP_SRC, LV+44 # fp source operand 3301da177e4SLinus Torvaldsset FP_SRC_EX, FP_SRC+0 3311da177e4SLinus Torvaldsset FP_SRC_SGN, FP_SRC+2 3321da177e4SLinus Torvaldsset FP_SRC_HI, FP_SRC+4 3331da177e4SLinus Torvaldsset FP_SRC_LO, FP_SRC+8 3341da177e4SLinus Torvalds 3351da177e4SLinus Torvaldsset USER_FPIAR, LV+40 # FP instr address register 3361da177e4SLinus Torvalds 3371da177e4SLinus Torvaldsset USER_FPSR, LV+36 # FP status register 3381da177e4SLinus Torvaldsset FPSR_CC, USER_FPSR+0 # FPSR condition codes 3391da177e4SLinus Torvaldsset FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte 3401da177e4SLinus Torvaldsset FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte 3411da177e4SLinus Torvaldsset FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte 3421da177e4SLinus Torvalds 3431da177e4SLinus Torvaldsset USER_FPCR, LV+32 # FP control register 3441da177e4SLinus Torvaldsset FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable 3451da177e4SLinus Torvaldsset FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvaldsset L_SCR3, LV+28 # integer scratch 3 3481da177e4SLinus Torvaldsset L_SCR2, LV+24 # integer scratch 2 3491da177e4SLinus Torvaldsset L_SCR1, LV+20 # integer scratch 1 3501da177e4SLinus Torvalds 3511da177e4SLinus Torvaldsset STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst) 3521da177e4SLinus Torvalds 3531da177e4SLinus Torvaldsset EXC_TEMP2, LV+24 # temporary space 3541da177e4SLinus Torvaldsset EXC_TEMP, LV+16 # temporary space 3551da177e4SLinus Torvalds 3561da177e4SLinus Torvaldsset DTAG, LV+15 # destination operand type 3571da177e4SLinus Torvaldsset STAG, LV+14 # source operand type 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvaldsset SPCOND_FLG, LV+10 # flag: special case (see below) 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvaldsset EXC_CC, LV+8 # saved condition codes 3621da177e4SLinus Torvaldsset EXC_EXTWPTR, LV+4 # saved current PC (active) 3631da177e4SLinus Torvaldsset EXC_EXTWORD, LV+2 # saved extension word 3641da177e4SLinus Torvaldsset EXC_CMDREG, LV+2 # saved extension word 3651da177e4SLinus Torvaldsset EXC_OPWORD, LV+0 # saved operation word 3661da177e4SLinus Torvalds 3671da177e4SLinus Torvalds################################ 3681da177e4SLinus Torvalds 3691da177e4SLinus Torvalds# Helpful macros 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvaldsset FTEMP, 0 # offsets within an 3721da177e4SLinus Torvaldsset FTEMP_EX, 0 # extended precision 3731da177e4SLinus Torvaldsset FTEMP_SGN, 2 # value saved in memory. 3741da177e4SLinus Torvaldsset FTEMP_HI, 4 3751da177e4SLinus Torvaldsset FTEMP_LO, 8 3761da177e4SLinus Torvaldsset FTEMP_GRS, 12 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvaldsset LOCAL, 0 # offsets within an 3791da177e4SLinus Torvaldsset LOCAL_EX, 0 # extended precision 3801da177e4SLinus Torvaldsset LOCAL_SGN, 2 # value saved in memory. 3811da177e4SLinus Torvaldsset LOCAL_HI, 4 3821da177e4SLinus Torvaldsset LOCAL_LO, 8 3831da177e4SLinus Torvaldsset LOCAL_GRS, 12 3841da177e4SLinus Torvalds 3851da177e4SLinus Torvaldsset DST, 0 # offsets within an 3861da177e4SLinus Torvaldsset DST_EX, 0 # extended precision 3871da177e4SLinus Torvaldsset DST_HI, 4 # value saved in memory. 3881da177e4SLinus Torvaldsset DST_LO, 8 3891da177e4SLinus Torvalds 3901da177e4SLinus Torvaldsset SRC, 0 # offsets within an 3911da177e4SLinus Torvaldsset SRC_EX, 0 # extended precision 3921da177e4SLinus Torvaldsset SRC_HI, 4 # value saved in memory. 3931da177e4SLinus Torvaldsset SRC_LO, 8 3941da177e4SLinus Torvalds 3951da177e4SLinus Torvaldsset SGL_LO, 0x3f81 # min sgl prec exponent 3961da177e4SLinus Torvaldsset SGL_HI, 0x407e # max sgl prec exponent 3971da177e4SLinus Torvaldsset DBL_LO, 0x3c01 # min dbl prec exponent 3981da177e4SLinus Torvaldsset DBL_HI, 0x43fe # max dbl prec exponent 3991da177e4SLinus Torvaldsset EXT_LO, 0x0 # min ext prec exponent 4001da177e4SLinus Torvaldsset EXT_HI, 0x7ffe # max ext prec exponent 4011da177e4SLinus Torvalds 4021da177e4SLinus Torvaldsset EXT_BIAS, 0x3fff # extended precision bias 4031da177e4SLinus Torvaldsset SGL_BIAS, 0x007f # single precision bias 4041da177e4SLinus Torvaldsset DBL_BIAS, 0x03ff # double precision bias 4051da177e4SLinus Torvalds 4061da177e4SLinus Torvaldsset NORM, 0x00 # operand type for STAG/DTAG 4071da177e4SLinus Torvaldsset ZERO, 0x01 # operand type for STAG/DTAG 4081da177e4SLinus Torvaldsset INF, 0x02 # operand type for STAG/DTAG 4091da177e4SLinus Torvaldsset QNAN, 0x03 # operand type for STAG/DTAG 4101da177e4SLinus Torvaldsset DENORM, 0x04 # operand type for STAG/DTAG 4111da177e4SLinus Torvaldsset SNAN, 0x05 # operand type for STAG/DTAG 4121da177e4SLinus Torvaldsset UNNORM, 0x06 # operand type for STAG/DTAG 4131da177e4SLinus Torvalds 4141da177e4SLinus Torvalds################## 4151da177e4SLinus Torvalds# FPSR/FPCR bits # 4161da177e4SLinus Torvalds################## 4171da177e4SLinus Torvaldsset neg_bit, 0x3 # negative result 4181da177e4SLinus Torvaldsset z_bit, 0x2 # zero result 4191da177e4SLinus Torvaldsset inf_bit, 0x1 # infinite result 4201da177e4SLinus Torvaldsset nan_bit, 0x0 # NAN result 4211da177e4SLinus Torvalds 4221da177e4SLinus Torvaldsset q_sn_bit, 0x7 # sign bit of quotient byte 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvaldsset bsun_bit, 7 # branch on unordered 4251da177e4SLinus Torvaldsset snan_bit, 6 # signalling NAN 4261da177e4SLinus Torvaldsset operr_bit, 5 # operand error 4271da177e4SLinus Torvaldsset ovfl_bit, 4 # overflow 4281da177e4SLinus Torvaldsset unfl_bit, 3 # underflow 4291da177e4SLinus Torvaldsset dz_bit, 2 # divide by zero 4301da177e4SLinus Torvaldsset inex2_bit, 1 # inexact result 2 4311da177e4SLinus Torvaldsset inex1_bit, 0 # inexact result 1 4321da177e4SLinus Torvalds 4331da177e4SLinus Torvaldsset aiop_bit, 7 # accrued inexact operation bit 4341da177e4SLinus Torvaldsset aovfl_bit, 6 # accrued overflow bit 4351da177e4SLinus Torvaldsset aunfl_bit, 5 # accrued underflow bit 4361da177e4SLinus Torvaldsset adz_bit, 4 # accrued dz bit 4371da177e4SLinus Torvaldsset ainex_bit, 3 # accrued inexact bit 4381da177e4SLinus Torvalds 4391da177e4SLinus Torvalds############################# 4401da177e4SLinus Torvalds# FPSR individual bit masks # 4411da177e4SLinus Torvalds############################# 4421da177e4SLinus Torvaldsset neg_mask, 0x08000000 # negative bit mask (lw) 4431da177e4SLinus Torvaldsset inf_mask, 0x02000000 # infinity bit mask (lw) 4441da177e4SLinus Torvaldsset z_mask, 0x04000000 # zero bit mask (lw) 4451da177e4SLinus Torvaldsset nan_mask, 0x01000000 # nan bit mask (lw) 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvaldsset neg_bmask, 0x08 # negative bit mask (byte) 4481da177e4SLinus Torvaldsset inf_bmask, 0x02 # infinity bit mask (byte) 4491da177e4SLinus Torvaldsset z_bmask, 0x04 # zero bit mask (byte) 4501da177e4SLinus Torvaldsset nan_bmask, 0x01 # nan bit mask (byte) 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvaldsset bsun_mask, 0x00008000 # bsun exception mask 4531da177e4SLinus Torvaldsset snan_mask, 0x00004000 # snan exception mask 4541da177e4SLinus Torvaldsset operr_mask, 0x00002000 # operr exception mask 4551da177e4SLinus Torvaldsset ovfl_mask, 0x00001000 # overflow exception mask 4561da177e4SLinus Torvaldsset unfl_mask, 0x00000800 # underflow exception mask 4571da177e4SLinus Torvaldsset dz_mask, 0x00000400 # dz exception mask 4581da177e4SLinus Torvaldsset inex2_mask, 0x00000200 # inex2 exception mask 4591da177e4SLinus Torvaldsset inex1_mask, 0x00000100 # inex1 exception mask 4601da177e4SLinus Torvalds 4611da177e4SLinus Torvaldsset aiop_mask, 0x00000080 # accrued illegal operation 4621da177e4SLinus Torvaldsset aovfl_mask, 0x00000040 # accrued overflow 4631da177e4SLinus Torvaldsset aunfl_mask, 0x00000020 # accrued underflow 4641da177e4SLinus Torvaldsset adz_mask, 0x00000010 # accrued divide by zero 4651da177e4SLinus Torvaldsset ainex_mask, 0x00000008 # accrued inexact 4661da177e4SLinus Torvalds 4671da177e4SLinus Torvalds###################################### 4681da177e4SLinus Torvalds# FPSR combinations used in the FPSP # 4691da177e4SLinus Torvalds###################################### 4701da177e4SLinus Torvaldsset dzinf_mask, inf_mask+dz_mask+adz_mask 4711da177e4SLinus Torvaldsset opnan_mask, nan_mask+operr_mask+aiop_mask 4721da177e4SLinus Torvaldsset nzi_mask, 0x01ffffff #clears N, Z, and I 4731da177e4SLinus Torvaldsset unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask 4741da177e4SLinus Torvaldsset unf2inx_mask, unfl_mask+inex2_mask+ainex_mask 4751da177e4SLinus Torvaldsset ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask 4761da177e4SLinus Torvaldsset inx1a_mask, inex1_mask+ainex_mask 4771da177e4SLinus Torvaldsset inx2a_mask, inex2_mask+ainex_mask 4781da177e4SLinus Torvaldsset snaniop_mask, nan_mask+snan_mask+aiop_mask 4791da177e4SLinus Torvaldsset snaniop2_mask, snan_mask+aiop_mask 4801da177e4SLinus Torvaldsset naniop_mask, nan_mask+aiop_mask 4811da177e4SLinus Torvaldsset neginf_mask, neg_mask+inf_mask 4821da177e4SLinus Torvaldsset infaiop_mask, inf_mask+aiop_mask 4831da177e4SLinus Torvaldsset negz_mask, neg_mask+z_mask 4841da177e4SLinus Torvaldsset opaop_mask, operr_mask+aiop_mask 4851da177e4SLinus Torvaldsset unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask 4861da177e4SLinus Torvaldsset ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds######### 4891da177e4SLinus Torvalds# misc. # 4901da177e4SLinus Torvalds######### 4911da177e4SLinus Torvaldsset rnd_stky_bit, 29 # stky bit pos in longword 4921da177e4SLinus Torvalds 4931da177e4SLinus Torvaldsset sign_bit, 0x7 # sign bit 4941da177e4SLinus Torvaldsset signan_bit, 0x6 # signalling nan bit 4951da177e4SLinus Torvalds 4961da177e4SLinus Torvaldsset sgl_thresh, 0x3f81 # minimum sgl exponent 4971da177e4SLinus Torvaldsset dbl_thresh, 0x3c01 # minimum dbl exponent 4981da177e4SLinus Torvalds 4991da177e4SLinus Torvaldsset x_mode, 0x0 # extended precision 5001da177e4SLinus Torvaldsset s_mode, 0x4 # single precision 5011da177e4SLinus Torvaldsset d_mode, 0x8 # double precision 5021da177e4SLinus Torvalds 5031da177e4SLinus Torvaldsset rn_mode, 0x0 # round-to-nearest 5041da177e4SLinus Torvaldsset rz_mode, 0x1 # round-to-zero 5051da177e4SLinus Torvaldsset rm_mode, 0x2 # round-tp-minus-infinity 5061da177e4SLinus Torvaldsset rp_mode, 0x3 # round-to-plus-infinity 5071da177e4SLinus Torvalds 5081da177e4SLinus Torvaldsset mantissalen, 64 # length of mantissa in bits 5091da177e4SLinus Torvalds 5101da177e4SLinus Torvaldsset BYTE, 1 # len(byte) == 1 byte 5111da177e4SLinus Torvaldsset WORD, 2 # len(word) == 2 bytes 5121da177e4SLinus Torvaldsset LONG, 4 # len(longword) == 2 bytes 5131da177e4SLinus Torvalds 5141da177e4SLinus Torvaldsset BSUN_VEC, 0xc0 # bsun vector offset 5151da177e4SLinus Torvaldsset INEX_VEC, 0xc4 # inexact vector offset 5161da177e4SLinus Torvaldsset DZ_VEC, 0xc8 # dz vector offset 5171da177e4SLinus Torvaldsset UNFL_VEC, 0xcc # unfl vector offset 5181da177e4SLinus Torvaldsset OPERR_VEC, 0xd0 # operr vector offset 5191da177e4SLinus Torvaldsset OVFL_VEC, 0xd4 # ovfl vector offset 5201da177e4SLinus Torvaldsset SNAN_VEC, 0xd8 # snan vector offset 5211da177e4SLinus Torvalds 5221da177e4SLinus Torvalds########################### 5231da177e4SLinus Torvalds# SPecial CONDition FLaGs # 5241da177e4SLinus Torvalds########################### 5251da177e4SLinus Torvaldsset ftrapcc_flg, 0x01 # flag bit: ftrapcc exception 5261da177e4SLinus Torvaldsset fbsun_flg, 0x02 # flag bit: bsun exception 5271da177e4SLinus Torvaldsset mia7_flg, 0x04 # flag bit: (a7)+ <ea> 5281da177e4SLinus Torvaldsset mda7_flg, 0x08 # flag bit: -(a7) <ea> 5291da177e4SLinus Torvaldsset fmovm_flg, 0x40 # flag bit: fmovm instruction 5301da177e4SLinus Torvaldsset immed_flg, 0x80 # flag bit: &<data> <ea> 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvaldsset ftrapcc_bit, 0x0 5331da177e4SLinus Torvaldsset fbsun_bit, 0x1 5341da177e4SLinus Torvaldsset mia7_bit, 0x2 5351da177e4SLinus Torvaldsset mda7_bit, 0x3 5361da177e4SLinus Torvaldsset immed_bit, 0x7 5371da177e4SLinus Torvalds 5381da177e4SLinus Torvalds################################## 5391da177e4SLinus Torvalds# TRANSCENDENTAL "LAST-OP" FLAGS # 5401da177e4SLinus Torvalds################################## 5411da177e4SLinus Torvaldsset FMUL_OP, 0x0 # fmul instr performed last 5421da177e4SLinus Torvaldsset FDIV_OP, 0x1 # fdiv performed last 5431da177e4SLinus Torvaldsset FADD_OP, 0x2 # fadd performed last 5441da177e4SLinus Torvaldsset FMOV_OP, 0x3 # fmov performed last 5451da177e4SLinus Torvalds 5461da177e4SLinus Torvalds############# 5471da177e4SLinus Torvalds# CONSTANTS # 5481da177e4SLinus Torvalds############# 5491da177e4SLinus TorvaldsT1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD 5501da177e4SLinus TorvaldsT2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL 5511da177e4SLinus Torvalds 5521da177e4SLinus TorvaldsPI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000 5531da177e4SLinus TorvaldsPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 5541da177e4SLinus Torvalds 5551da177e4SLinus TorvaldsTWOBYPI: 5561da177e4SLinus Torvalds long 0x3FE45F30,0x6DC9C883 5571da177e4SLinus Torvalds 5581da177e4SLinus Torvalds######################################################################### 5591da177e4SLinus Torvalds# MONADIC TEMPLATE # 5601da177e4SLinus Torvalds######################################################################### 5611da177e4SLinus Torvalds global _fsins_ 5621da177e4SLinus Torvalds_fsins_: 5631da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 5641da177e4SLinus Torvalds 5651da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 5661da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 5671da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 5681da177e4SLinus Torvalds 5691da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds# 5721da177e4SLinus Torvalds# copy, convert, and tag input argument 5731da177e4SLinus Torvalds# 5741da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 5751da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 5761da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 5771da177e4SLinus Torvalds bsr.l tag # fetch operand type 5781da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 5791da177e4SLinus Torvalds mov.b %d0,%d1 5801da177e4SLinus Torvalds 5811da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 5821da177e4SLinus Torvalds 5831da177e4SLinus Torvalds clr.l %d0 5841da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 5851da177e4SLinus Torvalds 5861da177e4SLinus Torvalds tst.b %d1 5871da177e4SLinus Torvalds bne.b _L0_2s 5881da177e4SLinus Torvalds bsr.l ssin # operand is a NORM 5891da177e4SLinus Torvalds bra.b _L0_6s 5901da177e4SLinus Torvalds_L0_2s: 5911da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 5921da177e4SLinus Torvalds bne.b _L0_3s # no 5931da177e4SLinus Torvalds bsr.l src_zero # yes 5941da177e4SLinus Torvalds bra.b _L0_6s 5951da177e4SLinus Torvalds_L0_3s: 5961da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 5971da177e4SLinus Torvalds bne.b _L0_4s # no 5981da177e4SLinus Torvalds bsr.l t_operr # yes 5991da177e4SLinus Torvalds bra.b _L0_6s 6001da177e4SLinus Torvalds_L0_4s: 6011da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 6021da177e4SLinus Torvalds bne.b _L0_5s # no 6031da177e4SLinus Torvalds bsr.l src_qnan # yes 6041da177e4SLinus Torvalds bra.b _L0_6s 6051da177e4SLinus Torvalds_L0_5s: 6061da177e4SLinus Torvalds bsr.l ssind # operand is a DENORM 6071da177e4SLinus Torvalds_L0_6s: 6081da177e4SLinus Torvalds 6091da177e4SLinus Torvalds# 6101da177e4SLinus Torvalds# Result is now in FP0 6111da177e4SLinus Torvalds# 6121da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 6131da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 6141da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 6151da177e4SLinus Torvalds unlk %a6 6161da177e4SLinus Torvalds rts 6171da177e4SLinus Torvalds 6181da177e4SLinus Torvalds global _fsind_ 6191da177e4SLinus Torvalds_fsind_: 6201da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 6211da177e4SLinus Torvalds 6221da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 6231da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 6241da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 6251da177e4SLinus Torvalds 6261da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 6271da177e4SLinus Torvalds 6281da177e4SLinus Torvalds# 6291da177e4SLinus Torvalds# copy, convert, and tag input argument 6301da177e4SLinus Torvalds# 6311da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 6321da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 6331da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 6341da177e4SLinus Torvalds bsr.l tag # fetch operand type 6351da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 6361da177e4SLinus Torvalds mov.b %d0,%d1 6371da177e4SLinus Torvalds 6381da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds clr.l %d0 6411da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 6421da177e4SLinus Torvalds 6431da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 6441da177e4SLinus Torvalds tst.b %d1 6451da177e4SLinus Torvalds bne.b _L0_2d 6461da177e4SLinus Torvalds bsr.l ssin # operand is a NORM 6471da177e4SLinus Torvalds bra.b _L0_6d 6481da177e4SLinus Torvalds_L0_2d: 6491da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 6501da177e4SLinus Torvalds bne.b _L0_3d # no 6511da177e4SLinus Torvalds bsr.l src_zero # yes 6521da177e4SLinus Torvalds bra.b _L0_6d 6531da177e4SLinus Torvalds_L0_3d: 6541da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 6551da177e4SLinus Torvalds bne.b _L0_4d # no 6561da177e4SLinus Torvalds bsr.l t_operr # yes 6571da177e4SLinus Torvalds bra.b _L0_6d 6581da177e4SLinus Torvalds_L0_4d: 6591da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 6601da177e4SLinus Torvalds bne.b _L0_5d # no 6611da177e4SLinus Torvalds bsr.l src_qnan # yes 6621da177e4SLinus Torvalds bra.b _L0_6d 6631da177e4SLinus Torvalds_L0_5d: 6641da177e4SLinus Torvalds bsr.l ssind # operand is a DENORM 6651da177e4SLinus Torvalds_L0_6d: 6661da177e4SLinus Torvalds 6671da177e4SLinus Torvalds# 6681da177e4SLinus Torvalds# Result is now in FP0 6691da177e4SLinus Torvalds# 6701da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 6711da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 6721da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 6731da177e4SLinus Torvalds unlk %a6 6741da177e4SLinus Torvalds rts 6751da177e4SLinus Torvalds 6761da177e4SLinus Torvalds global _fsinx_ 6771da177e4SLinus Torvalds_fsinx_: 6781da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 6791da177e4SLinus Torvalds 6801da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 6811da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 6821da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 6831da177e4SLinus Torvalds 6841da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 6851da177e4SLinus Torvalds 6861da177e4SLinus Torvalds# 6871da177e4SLinus Torvalds# copy, convert, and tag input argument 6881da177e4SLinus Torvalds# 6891da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 6901da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 6911da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 6921da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 6931da177e4SLinus Torvalds bsr.l tag # fetch operand type 6941da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 6951da177e4SLinus Torvalds mov.b %d0,%d1 6961da177e4SLinus Torvalds 6971da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 6981da177e4SLinus Torvalds 6991da177e4SLinus Torvalds clr.l %d0 7001da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 7011da177e4SLinus Torvalds 7021da177e4SLinus Torvalds tst.b %d1 7031da177e4SLinus Torvalds bne.b _L0_2x 7041da177e4SLinus Torvalds bsr.l ssin # operand is a NORM 7051da177e4SLinus Torvalds bra.b _L0_6x 7061da177e4SLinus Torvalds_L0_2x: 7071da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 7081da177e4SLinus Torvalds bne.b _L0_3x # no 7091da177e4SLinus Torvalds bsr.l src_zero # yes 7101da177e4SLinus Torvalds bra.b _L0_6x 7111da177e4SLinus Torvalds_L0_3x: 7121da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 7131da177e4SLinus Torvalds bne.b _L0_4x # no 7141da177e4SLinus Torvalds bsr.l t_operr # yes 7151da177e4SLinus Torvalds bra.b _L0_6x 7161da177e4SLinus Torvalds_L0_4x: 7171da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 7181da177e4SLinus Torvalds bne.b _L0_5x # no 7191da177e4SLinus Torvalds bsr.l src_qnan # yes 7201da177e4SLinus Torvalds bra.b _L0_6x 7211da177e4SLinus Torvalds_L0_5x: 7221da177e4SLinus Torvalds bsr.l ssind # operand is a DENORM 7231da177e4SLinus Torvalds_L0_6x: 7241da177e4SLinus Torvalds 7251da177e4SLinus Torvalds# 7261da177e4SLinus Torvalds# Result is now in FP0 7271da177e4SLinus Torvalds# 7281da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 7291da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 7301da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 7311da177e4SLinus Torvalds unlk %a6 7321da177e4SLinus Torvalds rts 7331da177e4SLinus Torvalds 7341da177e4SLinus Torvalds 7351da177e4SLinus Torvalds######################################################################### 7361da177e4SLinus Torvalds# MONADIC TEMPLATE # 7371da177e4SLinus Torvalds######################################################################### 7381da177e4SLinus Torvalds global _fcoss_ 7391da177e4SLinus Torvalds_fcoss_: 7401da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 7431da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 7441da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 7451da177e4SLinus Torvalds 7461da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds# 7491da177e4SLinus Torvalds# copy, convert, and tag input argument 7501da177e4SLinus Torvalds# 7511da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 7521da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 7531da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 7541da177e4SLinus Torvalds bsr.l tag # fetch operand type 7551da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 7561da177e4SLinus Torvalds mov.b %d0,%d1 7571da177e4SLinus Torvalds 7581da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 7591da177e4SLinus Torvalds 7601da177e4SLinus Torvalds clr.l %d0 7611da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 7621da177e4SLinus Torvalds 7631da177e4SLinus Torvalds tst.b %d1 7641da177e4SLinus Torvalds bne.b _L1_2s 7651da177e4SLinus Torvalds bsr.l scos # operand is a NORM 7661da177e4SLinus Torvalds bra.b _L1_6s 7671da177e4SLinus Torvalds_L1_2s: 7681da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 7691da177e4SLinus Torvalds bne.b _L1_3s # no 7701da177e4SLinus Torvalds bsr.l ld_pone # yes 7711da177e4SLinus Torvalds bra.b _L1_6s 7721da177e4SLinus Torvalds_L1_3s: 7731da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 7741da177e4SLinus Torvalds bne.b _L1_4s # no 7751da177e4SLinus Torvalds bsr.l t_operr # yes 7761da177e4SLinus Torvalds bra.b _L1_6s 7771da177e4SLinus Torvalds_L1_4s: 7781da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 7791da177e4SLinus Torvalds bne.b _L1_5s # no 7801da177e4SLinus Torvalds bsr.l src_qnan # yes 7811da177e4SLinus Torvalds bra.b _L1_6s 7821da177e4SLinus Torvalds_L1_5s: 7831da177e4SLinus Torvalds bsr.l scosd # operand is a DENORM 7841da177e4SLinus Torvalds_L1_6s: 7851da177e4SLinus Torvalds 7861da177e4SLinus Torvalds# 7871da177e4SLinus Torvalds# Result is now in FP0 7881da177e4SLinus Torvalds# 7891da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 7901da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 7911da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 7921da177e4SLinus Torvalds unlk %a6 7931da177e4SLinus Torvalds rts 7941da177e4SLinus Torvalds 7951da177e4SLinus Torvalds global _fcosd_ 7961da177e4SLinus Torvalds_fcosd_: 7971da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 7981da177e4SLinus Torvalds 7991da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 8001da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 8011da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 8021da177e4SLinus Torvalds 8031da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds# 8061da177e4SLinus Torvalds# copy, convert, and tag input argument 8071da177e4SLinus Torvalds# 8081da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 8091da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 8101da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 8111da177e4SLinus Torvalds bsr.l tag # fetch operand type 8121da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 8131da177e4SLinus Torvalds mov.b %d0,%d1 8141da177e4SLinus Torvalds 8151da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 8161da177e4SLinus Torvalds 8171da177e4SLinus Torvalds clr.l %d0 8181da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 8191da177e4SLinus Torvalds 8201da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 8211da177e4SLinus Torvalds tst.b %d1 8221da177e4SLinus Torvalds bne.b _L1_2d 8231da177e4SLinus Torvalds bsr.l scos # operand is a NORM 8241da177e4SLinus Torvalds bra.b _L1_6d 8251da177e4SLinus Torvalds_L1_2d: 8261da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 8271da177e4SLinus Torvalds bne.b _L1_3d # no 8281da177e4SLinus Torvalds bsr.l ld_pone # yes 8291da177e4SLinus Torvalds bra.b _L1_6d 8301da177e4SLinus Torvalds_L1_3d: 8311da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 8321da177e4SLinus Torvalds bne.b _L1_4d # no 8331da177e4SLinus Torvalds bsr.l t_operr # yes 8341da177e4SLinus Torvalds bra.b _L1_6d 8351da177e4SLinus Torvalds_L1_4d: 8361da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 8371da177e4SLinus Torvalds bne.b _L1_5d # no 8381da177e4SLinus Torvalds bsr.l src_qnan # yes 8391da177e4SLinus Torvalds bra.b _L1_6d 8401da177e4SLinus Torvalds_L1_5d: 8411da177e4SLinus Torvalds bsr.l scosd # operand is a DENORM 8421da177e4SLinus Torvalds_L1_6d: 8431da177e4SLinus Torvalds 8441da177e4SLinus Torvalds# 8451da177e4SLinus Torvalds# Result is now in FP0 8461da177e4SLinus Torvalds# 8471da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 8481da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 8491da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 8501da177e4SLinus Torvalds unlk %a6 8511da177e4SLinus Torvalds rts 8521da177e4SLinus Torvalds 8531da177e4SLinus Torvalds global _fcosx_ 8541da177e4SLinus Torvalds_fcosx_: 8551da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 8561da177e4SLinus Torvalds 8571da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 8581da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 8591da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 8601da177e4SLinus Torvalds 8611da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds# 8641da177e4SLinus Torvalds# copy, convert, and tag input argument 8651da177e4SLinus Torvalds# 8661da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 8671da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 8681da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 8691da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 8701da177e4SLinus Torvalds bsr.l tag # fetch operand type 8711da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 8721da177e4SLinus Torvalds mov.b %d0,%d1 8731da177e4SLinus Torvalds 8741da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 8751da177e4SLinus Torvalds 8761da177e4SLinus Torvalds clr.l %d0 8771da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 8781da177e4SLinus Torvalds 8791da177e4SLinus Torvalds tst.b %d1 8801da177e4SLinus Torvalds bne.b _L1_2x 8811da177e4SLinus Torvalds bsr.l scos # operand is a NORM 8821da177e4SLinus Torvalds bra.b _L1_6x 8831da177e4SLinus Torvalds_L1_2x: 8841da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 8851da177e4SLinus Torvalds bne.b _L1_3x # no 8861da177e4SLinus Torvalds bsr.l ld_pone # yes 8871da177e4SLinus Torvalds bra.b _L1_6x 8881da177e4SLinus Torvalds_L1_3x: 8891da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 8901da177e4SLinus Torvalds bne.b _L1_4x # no 8911da177e4SLinus Torvalds bsr.l t_operr # yes 8921da177e4SLinus Torvalds bra.b _L1_6x 8931da177e4SLinus Torvalds_L1_4x: 8941da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 8951da177e4SLinus Torvalds bne.b _L1_5x # no 8961da177e4SLinus Torvalds bsr.l src_qnan # yes 8971da177e4SLinus Torvalds bra.b _L1_6x 8981da177e4SLinus Torvalds_L1_5x: 8991da177e4SLinus Torvalds bsr.l scosd # operand is a DENORM 9001da177e4SLinus Torvalds_L1_6x: 9011da177e4SLinus Torvalds 9021da177e4SLinus Torvalds# 9031da177e4SLinus Torvalds# Result is now in FP0 9041da177e4SLinus Torvalds# 9051da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 9061da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 9071da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 9081da177e4SLinus Torvalds unlk %a6 9091da177e4SLinus Torvalds rts 9101da177e4SLinus Torvalds 9111da177e4SLinus Torvalds 9121da177e4SLinus Torvalds######################################################################### 9131da177e4SLinus Torvalds# MONADIC TEMPLATE # 9141da177e4SLinus Torvalds######################################################################### 9151da177e4SLinus Torvalds global _fsinhs_ 9161da177e4SLinus Torvalds_fsinhs_: 9171da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 9201da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 9211da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 9221da177e4SLinus Torvalds 9231da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 9241da177e4SLinus Torvalds 9251da177e4SLinus Torvalds# 9261da177e4SLinus Torvalds# copy, convert, and tag input argument 9271da177e4SLinus Torvalds# 9281da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 9291da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 9301da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 9311da177e4SLinus Torvalds bsr.l tag # fetch operand type 9321da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 9331da177e4SLinus Torvalds mov.b %d0,%d1 9341da177e4SLinus Torvalds 9351da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 9361da177e4SLinus Torvalds 9371da177e4SLinus Torvalds clr.l %d0 9381da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 9391da177e4SLinus Torvalds 9401da177e4SLinus Torvalds tst.b %d1 9411da177e4SLinus Torvalds bne.b _L2_2s 9421da177e4SLinus Torvalds bsr.l ssinh # operand is a NORM 9431da177e4SLinus Torvalds bra.b _L2_6s 9441da177e4SLinus Torvalds_L2_2s: 9451da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 9461da177e4SLinus Torvalds bne.b _L2_3s # no 9471da177e4SLinus Torvalds bsr.l src_zero # yes 9481da177e4SLinus Torvalds bra.b _L2_6s 9491da177e4SLinus Torvalds_L2_3s: 9501da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 9511da177e4SLinus Torvalds bne.b _L2_4s # no 9521da177e4SLinus Torvalds bsr.l src_inf # yes 9531da177e4SLinus Torvalds bra.b _L2_6s 9541da177e4SLinus Torvalds_L2_4s: 9551da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 9561da177e4SLinus Torvalds bne.b _L2_5s # no 9571da177e4SLinus Torvalds bsr.l src_qnan # yes 9581da177e4SLinus Torvalds bra.b _L2_6s 9591da177e4SLinus Torvalds_L2_5s: 9601da177e4SLinus Torvalds bsr.l ssinhd # operand is a DENORM 9611da177e4SLinus Torvalds_L2_6s: 9621da177e4SLinus Torvalds 9631da177e4SLinus Torvalds# 9641da177e4SLinus Torvalds# Result is now in FP0 9651da177e4SLinus Torvalds# 9661da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 9671da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 9681da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 9691da177e4SLinus Torvalds unlk %a6 9701da177e4SLinus Torvalds rts 9711da177e4SLinus Torvalds 9721da177e4SLinus Torvalds global _fsinhd_ 9731da177e4SLinus Torvalds_fsinhd_: 9741da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 9751da177e4SLinus Torvalds 9761da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 9771da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 9781da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 9791da177e4SLinus Torvalds 9801da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 9811da177e4SLinus Torvalds 9821da177e4SLinus Torvalds# 9831da177e4SLinus Torvalds# copy, convert, and tag input argument 9841da177e4SLinus Torvalds# 9851da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 9861da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 9871da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 9881da177e4SLinus Torvalds bsr.l tag # fetch operand type 9891da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 9901da177e4SLinus Torvalds mov.b %d0,%d1 9911da177e4SLinus Torvalds 9921da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 9931da177e4SLinus Torvalds 9941da177e4SLinus Torvalds clr.l %d0 9951da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 9961da177e4SLinus Torvalds 9971da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 9981da177e4SLinus Torvalds tst.b %d1 9991da177e4SLinus Torvalds bne.b _L2_2d 10001da177e4SLinus Torvalds bsr.l ssinh # operand is a NORM 10011da177e4SLinus Torvalds bra.b _L2_6d 10021da177e4SLinus Torvalds_L2_2d: 10031da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 10041da177e4SLinus Torvalds bne.b _L2_3d # no 10051da177e4SLinus Torvalds bsr.l src_zero # yes 10061da177e4SLinus Torvalds bra.b _L2_6d 10071da177e4SLinus Torvalds_L2_3d: 10081da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 10091da177e4SLinus Torvalds bne.b _L2_4d # no 10101da177e4SLinus Torvalds bsr.l src_inf # yes 10111da177e4SLinus Torvalds bra.b _L2_6d 10121da177e4SLinus Torvalds_L2_4d: 10131da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 10141da177e4SLinus Torvalds bne.b _L2_5d # no 10151da177e4SLinus Torvalds bsr.l src_qnan # yes 10161da177e4SLinus Torvalds bra.b _L2_6d 10171da177e4SLinus Torvalds_L2_5d: 10181da177e4SLinus Torvalds bsr.l ssinhd # operand is a DENORM 10191da177e4SLinus Torvalds_L2_6d: 10201da177e4SLinus Torvalds 10211da177e4SLinus Torvalds# 10221da177e4SLinus Torvalds# Result is now in FP0 10231da177e4SLinus Torvalds# 10241da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 10251da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 10261da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 10271da177e4SLinus Torvalds unlk %a6 10281da177e4SLinus Torvalds rts 10291da177e4SLinus Torvalds 10301da177e4SLinus Torvalds global _fsinhx_ 10311da177e4SLinus Torvalds_fsinhx_: 10321da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 10331da177e4SLinus Torvalds 10341da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 10351da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 10361da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 10371da177e4SLinus Torvalds 10381da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 10391da177e4SLinus Torvalds 10401da177e4SLinus Torvalds# 10411da177e4SLinus Torvalds# copy, convert, and tag input argument 10421da177e4SLinus Torvalds# 10431da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 10441da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 10451da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 10461da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 10471da177e4SLinus Torvalds bsr.l tag # fetch operand type 10481da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 10491da177e4SLinus Torvalds mov.b %d0,%d1 10501da177e4SLinus Torvalds 10511da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 10521da177e4SLinus Torvalds 10531da177e4SLinus Torvalds clr.l %d0 10541da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 10551da177e4SLinus Torvalds 10561da177e4SLinus Torvalds tst.b %d1 10571da177e4SLinus Torvalds bne.b _L2_2x 10581da177e4SLinus Torvalds bsr.l ssinh # operand is a NORM 10591da177e4SLinus Torvalds bra.b _L2_6x 10601da177e4SLinus Torvalds_L2_2x: 10611da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 10621da177e4SLinus Torvalds bne.b _L2_3x # no 10631da177e4SLinus Torvalds bsr.l src_zero # yes 10641da177e4SLinus Torvalds bra.b _L2_6x 10651da177e4SLinus Torvalds_L2_3x: 10661da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 10671da177e4SLinus Torvalds bne.b _L2_4x # no 10681da177e4SLinus Torvalds bsr.l src_inf # yes 10691da177e4SLinus Torvalds bra.b _L2_6x 10701da177e4SLinus Torvalds_L2_4x: 10711da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 10721da177e4SLinus Torvalds bne.b _L2_5x # no 10731da177e4SLinus Torvalds bsr.l src_qnan # yes 10741da177e4SLinus Torvalds bra.b _L2_6x 10751da177e4SLinus Torvalds_L2_5x: 10761da177e4SLinus Torvalds bsr.l ssinhd # operand is a DENORM 10771da177e4SLinus Torvalds_L2_6x: 10781da177e4SLinus Torvalds 10791da177e4SLinus Torvalds# 10801da177e4SLinus Torvalds# Result is now in FP0 10811da177e4SLinus Torvalds# 10821da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 10831da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 10841da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 10851da177e4SLinus Torvalds unlk %a6 10861da177e4SLinus Torvalds rts 10871da177e4SLinus Torvalds 10881da177e4SLinus Torvalds 10891da177e4SLinus Torvalds######################################################################### 10901da177e4SLinus Torvalds# MONADIC TEMPLATE # 10911da177e4SLinus Torvalds######################################################################### 10921da177e4SLinus Torvalds global _flognp1s_ 10931da177e4SLinus Torvalds_flognp1s_: 10941da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 10951da177e4SLinus Torvalds 10961da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 10971da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 10981da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 10991da177e4SLinus Torvalds 11001da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 11011da177e4SLinus Torvalds 11021da177e4SLinus Torvalds# 11031da177e4SLinus Torvalds# copy, convert, and tag input argument 11041da177e4SLinus Torvalds# 11051da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 11061da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 11071da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 11081da177e4SLinus Torvalds bsr.l tag # fetch operand type 11091da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 11101da177e4SLinus Torvalds mov.b %d0,%d1 11111da177e4SLinus Torvalds 11121da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 11131da177e4SLinus Torvalds 11141da177e4SLinus Torvalds clr.l %d0 11151da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 11161da177e4SLinus Torvalds 11171da177e4SLinus Torvalds tst.b %d1 11181da177e4SLinus Torvalds bne.b _L3_2s 11191da177e4SLinus Torvalds bsr.l slognp1 # operand is a NORM 11201da177e4SLinus Torvalds bra.b _L3_6s 11211da177e4SLinus Torvalds_L3_2s: 11221da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 11231da177e4SLinus Torvalds bne.b _L3_3s # no 11241da177e4SLinus Torvalds bsr.l src_zero # yes 11251da177e4SLinus Torvalds bra.b _L3_6s 11261da177e4SLinus Torvalds_L3_3s: 11271da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 11281da177e4SLinus Torvalds bne.b _L3_4s # no 11291da177e4SLinus Torvalds bsr.l sopr_inf # yes 11301da177e4SLinus Torvalds bra.b _L3_6s 11311da177e4SLinus Torvalds_L3_4s: 11321da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 11331da177e4SLinus Torvalds bne.b _L3_5s # no 11341da177e4SLinus Torvalds bsr.l src_qnan # yes 11351da177e4SLinus Torvalds bra.b _L3_6s 11361da177e4SLinus Torvalds_L3_5s: 11371da177e4SLinus Torvalds bsr.l slognp1d # operand is a DENORM 11381da177e4SLinus Torvalds_L3_6s: 11391da177e4SLinus Torvalds 11401da177e4SLinus Torvalds# 11411da177e4SLinus Torvalds# Result is now in FP0 11421da177e4SLinus Torvalds# 11431da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 11441da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 11451da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 11461da177e4SLinus Torvalds unlk %a6 11471da177e4SLinus Torvalds rts 11481da177e4SLinus Torvalds 11491da177e4SLinus Torvalds global _flognp1d_ 11501da177e4SLinus Torvalds_flognp1d_: 11511da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 11521da177e4SLinus Torvalds 11531da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 11541da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 11551da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 11561da177e4SLinus Torvalds 11571da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 11581da177e4SLinus Torvalds 11591da177e4SLinus Torvalds# 11601da177e4SLinus Torvalds# copy, convert, and tag input argument 11611da177e4SLinus Torvalds# 11621da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 11631da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 11641da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 11651da177e4SLinus Torvalds bsr.l tag # fetch operand type 11661da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 11671da177e4SLinus Torvalds mov.b %d0,%d1 11681da177e4SLinus Torvalds 11691da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 11701da177e4SLinus Torvalds 11711da177e4SLinus Torvalds clr.l %d0 11721da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 11731da177e4SLinus Torvalds 11741da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 11751da177e4SLinus Torvalds tst.b %d1 11761da177e4SLinus Torvalds bne.b _L3_2d 11771da177e4SLinus Torvalds bsr.l slognp1 # operand is a NORM 11781da177e4SLinus Torvalds bra.b _L3_6d 11791da177e4SLinus Torvalds_L3_2d: 11801da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 11811da177e4SLinus Torvalds bne.b _L3_3d # no 11821da177e4SLinus Torvalds bsr.l src_zero # yes 11831da177e4SLinus Torvalds bra.b _L3_6d 11841da177e4SLinus Torvalds_L3_3d: 11851da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 11861da177e4SLinus Torvalds bne.b _L3_4d # no 11871da177e4SLinus Torvalds bsr.l sopr_inf # yes 11881da177e4SLinus Torvalds bra.b _L3_6d 11891da177e4SLinus Torvalds_L3_4d: 11901da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 11911da177e4SLinus Torvalds bne.b _L3_5d # no 11921da177e4SLinus Torvalds bsr.l src_qnan # yes 11931da177e4SLinus Torvalds bra.b _L3_6d 11941da177e4SLinus Torvalds_L3_5d: 11951da177e4SLinus Torvalds bsr.l slognp1d # operand is a DENORM 11961da177e4SLinus Torvalds_L3_6d: 11971da177e4SLinus Torvalds 11981da177e4SLinus Torvalds# 11991da177e4SLinus Torvalds# Result is now in FP0 12001da177e4SLinus Torvalds# 12011da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 12021da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 12031da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 12041da177e4SLinus Torvalds unlk %a6 12051da177e4SLinus Torvalds rts 12061da177e4SLinus Torvalds 12071da177e4SLinus Torvalds global _flognp1x_ 12081da177e4SLinus Torvalds_flognp1x_: 12091da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 12101da177e4SLinus Torvalds 12111da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 12121da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 12131da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 12141da177e4SLinus Torvalds 12151da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 12161da177e4SLinus Torvalds 12171da177e4SLinus Torvalds# 12181da177e4SLinus Torvalds# copy, convert, and tag input argument 12191da177e4SLinus Torvalds# 12201da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 12211da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 12221da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 12231da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 12241da177e4SLinus Torvalds bsr.l tag # fetch operand type 12251da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 12261da177e4SLinus Torvalds mov.b %d0,%d1 12271da177e4SLinus Torvalds 12281da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 12291da177e4SLinus Torvalds 12301da177e4SLinus Torvalds clr.l %d0 12311da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 12321da177e4SLinus Torvalds 12331da177e4SLinus Torvalds tst.b %d1 12341da177e4SLinus Torvalds bne.b _L3_2x 12351da177e4SLinus Torvalds bsr.l slognp1 # operand is a NORM 12361da177e4SLinus Torvalds bra.b _L3_6x 12371da177e4SLinus Torvalds_L3_2x: 12381da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 12391da177e4SLinus Torvalds bne.b _L3_3x # no 12401da177e4SLinus Torvalds bsr.l src_zero # yes 12411da177e4SLinus Torvalds bra.b _L3_6x 12421da177e4SLinus Torvalds_L3_3x: 12431da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 12441da177e4SLinus Torvalds bne.b _L3_4x # no 12451da177e4SLinus Torvalds bsr.l sopr_inf # yes 12461da177e4SLinus Torvalds bra.b _L3_6x 12471da177e4SLinus Torvalds_L3_4x: 12481da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 12491da177e4SLinus Torvalds bne.b _L3_5x # no 12501da177e4SLinus Torvalds bsr.l src_qnan # yes 12511da177e4SLinus Torvalds bra.b _L3_6x 12521da177e4SLinus Torvalds_L3_5x: 12531da177e4SLinus Torvalds bsr.l slognp1d # operand is a DENORM 12541da177e4SLinus Torvalds_L3_6x: 12551da177e4SLinus Torvalds 12561da177e4SLinus Torvalds# 12571da177e4SLinus Torvalds# Result is now in FP0 12581da177e4SLinus Torvalds# 12591da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 12601da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 12611da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 12621da177e4SLinus Torvalds unlk %a6 12631da177e4SLinus Torvalds rts 12641da177e4SLinus Torvalds 12651da177e4SLinus Torvalds 12661da177e4SLinus Torvalds######################################################################### 12671da177e4SLinus Torvalds# MONADIC TEMPLATE # 12681da177e4SLinus Torvalds######################################################################### 12691da177e4SLinus Torvalds global _fetoxm1s_ 12701da177e4SLinus Torvalds_fetoxm1s_: 12711da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 12721da177e4SLinus Torvalds 12731da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 12741da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 12751da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 12761da177e4SLinus Torvalds 12771da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 12781da177e4SLinus Torvalds 12791da177e4SLinus Torvalds# 12801da177e4SLinus Torvalds# copy, convert, and tag input argument 12811da177e4SLinus Torvalds# 12821da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 12831da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 12841da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 12851da177e4SLinus Torvalds bsr.l tag # fetch operand type 12861da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 12871da177e4SLinus Torvalds mov.b %d0,%d1 12881da177e4SLinus Torvalds 12891da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 12901da177e4SLinus Torvalds 12911da177e4SLinus Torvalds clr.l %d0 12921da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 12931da177e4SLinus Torvalds 12941da177e4SLinus Torvalds tst.b %d1 12951da177e4SLinus Torvalds bne.b _L4_2s 12961da177e4SLinus Torvalds bsr.l setoxm1 # operand is a NORM 12971da177e4SLinus Torvalds bra.b _L4_6s 12981da177e4SLinus Torvalds_L4_2s: 12991da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 13001da177e4SLinus Torvalds bne.b _L4_3s # no 13011da177e4SLinus Torvalds bsr.l src_zero # yes 13021da177e4SLinus Torvalds bra.b _L4_6s 13031da177e4SLinus Torvalds_L4_3s: 13041da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 13051da177e4SLinus Torvalds bne.b _L4_4s # no 13061da177e4SLinus Torvalds bsr.l setoxm1i # yes 13071da177e4SLinus Torvalds bra.b _L4_6s 13081da177e4SLinus Torvalds_L4_4s: 13091da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 13101da177e4SLinus Torvalds bne.b _L4_5s # no 13111da177e4SLinus Torvalds bsr.l src_qnan # yes 13121da177e4SLinus Torvalds bra.b _L4_6s 13131da177e4SLinus Torvalds_L4_5s: 13141da177e4SLinus Torvalds bsr.l setoxm1d # operand is a DENORM 13151da177e4SLinus Torvalds_L4_6s: 13161da177e4SLinus Torvalds 13171da177e4SLinus Torvalds# 13181da177e4SLinus Torvalds# Result is now in FP0 13191da177e4SLinus Torvalds# 13201da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 13211da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 13221da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 13231da177e4SLinus Torvalds unlk %a6 13241da177e4SLinus Torvalds rts 13251da177e4SLinus Torvalds 13261da177e4SLinus Torvalds global _fetoxm1d_ 13271da177e4SLinus Torvalds_fetoxm1d_: 13281da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 13291da177e4SLinus Torvalds 13301da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 13311da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 13321da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 13331da177e4SLinus Torvalds 13341da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 13351da177e4SLinus Torvalds 13361da177e4SLinus Torvalds# 13371da177e4SLinus Torvalds# copy, convert, and tag input argument 13381da177e4SLinus Torvalds# 13391da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 13401da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 13411da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 13421da177e4SLinus Torvalds bsr.l tag # fetch operand type 13431da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 13441da177e4SLinus Torvalds mov.b %d0,%d1 13451da177e4SLinus Torvalds 13461da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 13471da177e4SLinus Torvalds 13481da177e4SLinus Torvalds clr.l %d0 13491da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 13501da177e4SLinus Torvalds 13511da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 13521da177e4SLinus Torvalds tst.b %d1 13531da177e4SLinus Torvalds bne.b _L4_2d 13541da177e4SLinus Torvalds bsr.l setoxm1 # operand is a NORM 13551da177e4SLinus Torvalds bra.b _L4_6d 13561da177e4SLinus Torvalds_L4_2d: 13571da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 13581da177e4SLinus Torvalds bne.b _L4_3d # no 13591da177e4SLinus Torvalds bsr.l src_zero # yes 13601da177e4SLinus Torvalds bra.b _L4_6d 13611da177e4SLinus Torvalds_L4_3d: 13621da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 13631da177e4SLinus Torvalds bne.b _L4_4d # no 13641da177e4SLinus Torvalds bsr.l setoxm1i # yes 13651da177e4SLinus Torvalds bra.b _L4_6d 13661da177e4SLinus Torvalds_L4_4d: 13671da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 13681da177e4SLinus Torvalds bne.b _L4_5d # no 13691da177e4SLinus Torvalds bsr.l src_qnan # yes 13701da177e4SLinus Torvalds bra.b _L4_6d 13711da177e4SLinus Torvalds_L4_5d: 13721da177e4SLinus Torvalds bsr.l setoxm1d # operand is a DENORM 13731da177e4SLinus Torvalds_L4_6d: 13741da177e4SLinus Torvalds 13751da177e4SLinus Torvalds# 13761da177e4SLinus Torvalds# Result is now in FP0 13771da177e4SLinus Torvalds# 13781da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 13791da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 13801da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 13811da177e4SLinus Torvalds unlk %a6 13821da177e4SLinus Torvalds rts 13831da177e4SLinus Torvalds 13841da177e4SLinus Torvalds global _fetoxm1x_ 13851da177e4SLinus Torvalds_fetoxm1x_: 13861da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 13871da177e4SLinus Torvalds 13881da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 13891da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 13901da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 13911da177e4SLinus Torvalds 13921da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 13931da177e4SLinus Torvalds 13941da177e4SLinus Torvalds# 13951da177e4SLinus Torvalds# copy, convert, and tag input argument 13961da177e4SLinus Torvalds# 13971da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 13981da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 13991da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 14001da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 14011da177e4SLinus Torvalds bsr.l tag # fetch operand type 14021da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 14031da177e4SLinus Torvalds mov.b %d0,%d1 14041da177e4SLinus Torvalds 14051da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 14061da177e4SLinus Torvalds 14071da177e4SLinus Torvalds clr.l %d0 14081da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 14091da177e4SLinus Torvalds 14101da177e4SLinus Torvalds tst.b %d1 14111da177e4SLinus Torvalds bne.b _L4_2x 14121da177e4SLinus Torvalds bsr.l setoxm1 # operand is a NORM 14131da177e4SLinus Torvalds bra.b _L4_6x 14141da177e4SLinus Torvalds_L4_2x: 14151da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 14161da177e4SLinus Torvalds bne.b _L4_3x # no 14171da177e4SLinus Torvalds bsr.l src_zero # yes 14181da177e4SLinus Torvalds bra.b _L4_6x 14191da177e4SLinus Torvalds_L4_3x: 14201da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 14211da177e4SLinus Torvalds bne.b _L4_4x # no 14221da177e4SLinus Torvalds bsr.l setoxm1i # yes 14231da177e4SLinus Torvalds bra.b _L4_6x 14241da177e4SLinus Torvalds_L4_4x: 14251da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 14261da177e4SLinus Torvalds bne.b _L4_5x # no 14271da177e4SLinus Torvalds bsr.l src_qnan # yes 14281da177e4SLinus Torvalds bra.b _L4_6x 14291da177e4SLinus Torvalds_L4_5x: 14301da177e4SLinus Torvalds bsr.l setoxm1d # operand is a DENORM 14311da177e4SLinus Torvalds_L4_6x: 14321da177e4SLinus Torvalds 14331da177e4SLinus Torvalds# 14341da177e4SLinus Torvalds# Result is now in FP0 14351da177e4SLinus Torvalds# 14361da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 14371da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 14381da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 14391da177e4SLinus Torvalds unlk %a6 14401da177e4SLinus Torvalds rts 14411da177e4SLinus Torvalds 14421da177e4SLinus Torvalds 14431da177e4SLinus Torvalds######################################################################### 14441da177e4SLinus Torvalds# MONADIC TEMPLATE # 14451da177e4SLinus Torvalds######################################################################### 14461da177e4SLinus Torvalds global _ftanhs_ 14471da177e4SLinus Torvalds_ftanhs_: 14481da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 14491da177e4SLinus Torvalds 14501da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 14511da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 14521da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 14531da177e4SLinus Torvalds 14541da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 14551da177e4SLinus Torvalds 14561da177e4SLinus Torvalds# 14571da177e4SLinus Torvalds# copy, convert, and tag input argument 14581da177e4SLinus Torvalds# 14591da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 14601da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 14611da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 14621da177e4SLinus Torvalds bsr.l tag # fetch operand type 14631da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 14641da177e4SLinus Torvalds mov.b %d0,%d1 14651da177e4SLinus Torvalds 14661da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 14671da177e4SLinus Torvalds 14681da177e4SLinus Torvalds clr.l %d0 14691da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 14701da177e4SLinus Torvalds 14711da177e4SLinus Torvalds tst.b %d1 14721da177e4SLinus Torvalds bne.b _L5_2s 14731da177e4SLinus Torvalds bsr.l stanh # operand is a NORM 14741da177e4SLinus Torvalds bra.b _L5_6s 14751da177e4SLinus Torvalds_L5_2s: 14761da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 14771da177e4SLinus Torvalds bne.b _L5_3s # no 14781da177e4SLinus Torvalds bsr.l src_zero # yes 14791da177e4SLinus Torvalds bra.b _L5_6s 14801da177e4SLinus Torvalds_L5_3s: 14811da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 14821da177e4SLinus Torvalds bne.b _L5_4s # no 14831da177e4SLinus Torvalds bsr.l src_one # yes 14841da177e4SLinus Torvalds bra.b _L5_6s 14851da177e4SLinus Torvalds_L5_4s: 14861da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 14871da177e4SLinus Torvalds bne.b _L5_5s # no 14881da177e4SLinus Torvalds bsr.l src_qnan # yes 14891da177e4SLinus Torvalds bra.b _L5_6s 14901da177e4SLinus Torvalds_L5_5s: 14911da177e4SLinus Torvalds bsr.l stanhd # operand is a DENORM 14921da177e4SLinus Torvalds_L5_6s: 14931da177e4SLinus Torvalds 14941da177e4SLinus Torvalds# 14951da177e4SLinus Torvalds# Result is now in FP0 14961da177e4SLinus Torvalds# 14971da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 14981da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 14991da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 15001da177e4SLinus Torvalds unlk %a6 15011da177e4SLinus Torvalds rts 15021da177e4SLinus Torvalds 15031da177e4SLinus Torvalds global _ftanhd_ 15041da177e4SLinus Torvalds_ftanhd_: 15051da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 15061da177e4SLinus Torvalds 15071da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 15081da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 15091da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 15101da177e4SLinus Torvalds 15111da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 15121da177e4SLinus Torvalds 15131da177e4SLinus Torvalds# 15141da177e4SLinus Torvalds# copy, convert, and tag input argument 15151da177e4SLinus Torvalds# 15161da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 15171da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 15181da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 15191da177e4SLinus Torvalds bsr.l tag # fetch operand type 15201da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 15211da177e4SLinus Torvalds mov.b %d0,%d1 15221da177e4SLinus Torvalds 15231da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 15241da177e4SLinus Torvalds 15251da177e4SLinus Torvalds clr.l %d0 15261da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 15271da177e4SLinus Torvalds 15281da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 15291da177e4SLinus Torvalds tst.b %d1 15301da177e4SLinus Torvalds bne.b _L5_2d 15311da177e4SLinus Torvalds bsr.l stanh # operand is a NORM 15321da177e4SLinus Torvalds bra.b _L5_6d 15331da177e4SLinus Torvalds_L5_2d: 15341da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 15351da177e4SLinus Torvalds bne.b _L5_3d # no 15361da177e4SLinus Torvalds bsr.l src_zero # yes 15371da177e4SLinus Torvalds bra.b _L5_6d 15381da177e4SLinus Torvalds_L5_3d: 15391da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 15401da177e4SLinus Torvalds bne.b _L5_4d # no 15411da177e4SLinus Torvalds bsr.l src_one # yes 15421da177e4SLinus Torvalds bra.b _L5_6d 15431da177e4SLinus Torvalds_L5_4d: 15441da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 15451da177e4SLinus Torvalds bne.b _L5_5d # no 15461da177e4SLinus Torvalds bsr.l src_qnan # yes 15471da177e4SLinus Torvalds bra.b _L5_6d 15481da177e4SLinus Torvalds_L5_5d: 15491da177e4SLinus Torvalds bsr.l stanhd # operand is a DENORM 15501da177e4SLinus Torvalds_L5_6d: 15511da177e4SLinus Torvalds 15521da177e4SLinus Torvalds# 15531da177e4SLinus Torvalds# Result is now in FP0 15541da177e4SLinus Torvalds# 15551da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 15561da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 15571da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 15581da177e4SLinus Torvalds unlk %a6 15591da177e4SLinus Torvalds rts 15601da177e4SLinus Torvalds 15611da177e4SLinus Torvalds global _ftanhx_ 15621da177e4SLinus Torvalds_ftanhx_: 15631da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 15641da177e4SLinus Torvalds 15651da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 15661da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 15671da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 15681da177e4SLinus Torvalds 15691da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 15701da177e4SLinus Torvalds 15711da177e4SLinus Torvalds# 15721da177e4SLinus Torvalds# copy, convert, and tag input argument 15731da177e4SLinus Torvalds# 15741da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 15751da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 15761da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 15771da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 15781da177e4SLinus Torvalds bsr.l tag # fetch operand type 15791da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 15801da177e4SLinus Torvalds mov.b %d0,%d1 15811da177e4SLinus Torvalds 15821da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 15831da177e4SLinus Torvalds 15841da177e4SLinus Torvalds clr.l %d0 15851da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 15861da177e4SLinus Torvalds 15871da177e4SLinus Torvalds tst.b %d1 15881da177e4SLinus Torvalds bne.b _L5_2x 15891da177e4SLinus Torvalds bsr.l stanh # operand is a NORM 15901da177e4SLinus Torvalds bra.b _L5_6x 15911da177e4SLinus Torvalds_L5_2x: 15921da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 15931da177e4SLinus Torvalds bne.b _L5_3x # no 15941da177e4SLinus Torvalds bsr.l src_zero # yes 15951da177e4SLinus Torvalds bra.b _L5_6x 15961da177e4SLinus Torvalds_L5_3x: 15971da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 15981da177e4SLinus Torvalds bne.b _L5_4x # no 15991da177e4SLinus Torvalds bsr.l src_one # yes 16001da177e4SLinus Torvalds bra.b _L5_6x 16011da177e4SLinus Torvalds_L5_4x: 16021da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 16031da177e4SLinus Torvalds bne.b _L5_5x # no 16041da177e4SLinus Torvalds bsr.l src_qnan # yes 16051da177e4SLinus Torvalds bra.b _L5_6x 16061da177e4SLinus Torvalds_L5_5x: 16071da177e4SLinus Torvalds bsr.l stanhd # operand is a DENORM 16081da177e4SLinus Torvalds_L5_6x: 16091da177e4SLinus Torvalds 16101da177e4SLinus Torvalds# 16111da177e4SLinus Torvalds# Result is now in FP0 16121da177e4SLinus Torvalds# 16131da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 16141da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 16151da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 16161da177e4SLinus Torvalds unlk %a6 16171da177e4SLinus Torvalds rts 16181da177e4SLinus Torvalds 16191da177e4SLinus Torvalds 16201da177e4SLinus Torvalds######################################################################### 16211da177e4SLinus Torvalds# MONADIC TEMPLATE # 16221da177e4SLinus Torvalds######################################################################### 16231da177e4SLinus Torvalds global _fatans_ 16241da177e4SLinus Torvalds_fatans_: 16251da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 16261da177e4SLinus Torvalds 16271da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 16281da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 16291da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 16301da177e4SLinus Torvalds 16311da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 16321da177e4SLinus Torvalds 16331da177e4SLinus Torvalds# 16341da177e4SLinus Torvalds# copy, convert, and tag input argument 16351da177e4SLinus Torvalds# 16361da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 16371da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 16381da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 16391da177e4SLinus Torvalds bsr.l tag # fetch operand type 16401da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 16411da177e4SLinus Torvalds mov.b %d0,%d1 16421da177e4SLinus Torvalds 16431da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 16441da177e4SLinus Torvalds 16451da177e4SLinus Torvalds clr.l %d0 16461da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 16471da177e4SLinus Torvalds 16481da177e4SLinus Torvalds tst.b %d1 16491da177e4SLinus Torvalds bne.b _L6_2s 16501da177e4SLinus Torvalds bsr.l satan # operand is a NORM 16511da177e4SLinus Torvalds bra.b _L6_6s 16521da177e4SLinus Torvalds_L6_2s: 16531da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 16541da177e4SLinus Torvalds bne.b _L6_3s # no 16551da177e4SLinus Torvalds bsr.l src_zero # yes 16561da177e4SLinus Torvalds bra.b _L6_6s 16571da177e4SLinus Torvalds_L6_3s: 16581da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 16591da177e4SLinus Torvalds bne.b _L6_4s # no 16601da177e4SLinus Torvalds bsr.l spi_2 # yes 16611da177e4SLinus Torvalds bra.b _L6_6s 16621da177e4SLinus Torvalds_L6_4s: 16631da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 16641da177e4SLinus Torvalds bne.b _L6_5s # no 16651da177e4SLinus Torvalds bsr.l src_qnan # yes 16661da177e4SLinus Torvalds bra.b _L6_6s 16671da177e4SLinus Torvalds_L6_5s: 16681da177e4SLinus Torvalds bsr.l satand # operand is a DENORM 16691da177e4SLinus Torvalds_L6_6s: 16701da177e4SLinus Torvalds 16711da177e4SLinus Torvalds# 16721da177e4SLinus Torvalds# Result is now in FP0 16731da177e4SLinus Torvalds# 16741da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 16751da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 16761da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 16771da177e4SLinus Torvalds unlk %a6 16781da177e4SLinus Torvalds rts 16791da177e4SLinus Torvalds 16801da177e4SLinus Torvalds global _fatand_ 16811da177e4SLinus Torvalds_fatand_: 16821da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 16831da177e4SLinus Torvalds 16841da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 16851da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 16861da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 16871da177e4SLinus Torvalds 16881da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 16891da177e4SLinus Torvalds 16901da177e4SLinus Torvalds# 16911da177e4SLinus Torvalds# copy, convert, and tag input argument 16921da177e4SLinus Torvalds# 16931da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 16941da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 16951da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 16961da177e4SLinus Torvalds bsr.l tag # fetch operand type 16971da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 16981da177e4SLinus Torvalds mov.b %d0,%d1 16991da177e4SLinus Torvalds 17001da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 17011da177e4SLinus Torvalds 17021da177e4SLinus Torvalds clr.l %d0 17031da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 17041da177e4SLinus Torvalds 17051da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 17061da177e4SLinus Torvalds tst.b %d1 17071da177e4SLinus Torvalds bne.b _L6_2d 17081da177e4SLinus Torvalds bsr.l satan # operand is a NORM 17091da177e4SLinus Torvalds bra.b _L6_6d 17101da177e4SLinus Torvalds_L6_2d: 17111da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 17121da177e4SLinus Torvalds bne.b _L6_3d # no 17131da177e4SLinus Torvalds bsr.l src_zero # yes 17141da177e4SLinus Torvalds bra.b _L6_6d 17151da177e4SLinus Torvalds_L6_3d: 17161da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 17171da177e4SLinus Torvalds bne.b _L6_4d # no 17181da177e4SLinus Torvalds bsr.l spi_2 # yes 17191da177e4SLinus Torvalds bra.b _L6_6d 17201da177e4SLinus Torvalds_L6_4d: 17211da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 17221da177e4SLinus Torvalds bne.b _L6_5d # no 17231da177e4SLinus Torvalds bsr.l src_qnan # yes 17241da177e4SLinus Torvalds bra.b _L6_6d 17251da177e4SLinus Torvalds_L6_5d: 17261da177e4SLinus Torvalds bsr.l satand # operand is a DENORM 17271da177e4SLinus Torvalds_L6_6d: 17281da177e4SLinus Torvalds 17291da177e4SLinus Torvalds# 17301da177e4SLinus Torvalds# Result is now in FP0 17311da177e4SLinus Torvalds# 17321da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 17331da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 17341da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 17351da177e4SLinus Torvalds unlk %a6 17361da177e4SLinus Torvalds rts 17371da177e4SLinus Torvalds 17381da177e4SLinus Torvalds global _fatanx_ 17391da177e4SLinus Torvalds_fatanx_: 17401da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 17411da177e4SLinus Torvalds 17421da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 17431da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 17441da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 17451da177e4SLinus Torvalds 17461da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 17471da177e4SLinus Torvalds 17481da177e4SLinus Torvalds# 17491da177e4SLinus Torvalds# copy, convert, and tag input argument 17501da177e4SLinus Torvalds# 17511da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 17521da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 17531da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 17541da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 17551da177e4SLinus Torvalds bsr.l tag # fetch operand type 17561da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 17571da177e4SLinus Torvalds mov.b %d0,%d1 17581da177e4SLinus Torvalds 17591da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 17601da177e4SLinus Torvalds 17611da177e4SLinus Torvalds clr.l %d0 17621da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 17631da177e4SLinus Torvalds 17641da177e4SLinus Torvalds tst.b %d1 17651da177e4SLinus Torvalds bne.b _L6_2x 17661da177e4SLinus Torvalds bsr.l satan # operand is a NORM 17671da177e4SLinus Torvalds bra.b _L6_6x 17681da177e4SLinus Torvalds_L6_2x: 17691da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 17701da177e4SLinus Torvalds bne.b _L6_3x # no 17711da177e4SLinus Torvalds bsr.l src_zero # yes 17721da177e4SLinus Torvalds bra.b _L6_6x 17731da177e4SLinus Torvalds_L6_3x: 17741da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 17751da177e4SLinus Torvalds bne.b _L6_4x # no 17761da177e4SLinus Torvalds bsr.l spi_2 # yes 17771da177e4SLinus Torvalds bra.b _L6_6x 17781da177e4SLinus Torvalds_L6_4x: 17791da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 17801da177e4SLinus Torvalds bne.b _L6_5x # no 17811da177e4SLinus Torvalds bsr.l src_qnan # yes 17821da177e4SLinus Torvalds bra.b _L6_6x 17831da177e4SLinus Torvalds_L6_5x: 17841da177e4SLinus Torvalds bsr.l satand # operand is a DENORM 17851da177e4SLinus Torvalds_L6_6x: 17861da177e4SLinus Torvalds 17871da177e4SLinus Torvalds# 17881da177e4SLinus Torvalds# Result is now in FP0 17891da177e4SLinus Torvalds# 17901da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 17911da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 17921da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 17931da177e4SLinus Torvalds unlk %a6 17941da177e4SLinus Torvalds rts 17951da177e4SLinus Torvalds 17961da177e4SLinus Torvalds 17971da177e4SLinus Torvalds######################################################################### 17981da177e4SLinus Torvalds# MONADIC TEMPLATE # 17991da177e4SLinus Torvalds######################################################################### 18001da177e4SLinus Torvalds global _fasins_ 18011da177e4SLinus Torvalds_fasins_: 18021da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 18031da177e4SLinus Torvalds 18041da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 18051da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 18061da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 18071da177e4SLinus Torvalds 18081da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 18091da177e4SLinus Torvalds 18101da177e4SLinus Torvalds# 18111da177e4SLinus Torvalds# copy, convert, and tag input argument 18121da177e4SLinus Torvalds# 18131da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 18141da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 18151da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 18161da177e4SLinus Torvalds bsr.l tag # fetch operand type 18171da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 18181da177e4SLinus Torvalds mov.b %d0,%d1 18191da177e4SLinus Torvalds 18201da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 18211da177e4SLinus Torvalds 18221da177e4SLinus Torvalds clr.l %d0 18231da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 18241da177e4SLinus Torvalds 18251da177e4SLinus Torvalds tst.b %d1 18261da177e4SLinus Torvalds bne.b _L7_2s 18271da177e4SLinus Torvalds bsr.l sasin # operand is a NORM 18281da177e4SLinus Torvalds bra.b _L7_6s 18291da177e4SLinus Torvalds_L7_2s: 18301da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 18311da177e4SLinus Torvalds bne.b _L7_3s # no 18321da177e4SLinus Torvalds bsr.l src_zero # yes 18331da177e4SLinus Torvalds bra.b _L7_6s 18341da177e4SLinus Torvalds_L7_3s: 18351da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 18361da177e4SLinus Torvalds bne.b _L7_4s # no 18371da177e4SLinus Torvalds bsr.l t_operr # yes 18381da177e4SLinus Torvalds bra.b _L7_6s 18391da177e4SLinus Torvalds_L7_4s: 18401da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 18411da177e4SLinus Torvalds bne.b _L7_5s # no 18421da177e4SLinus Torvalds bsr.l src_qnan # yes 18431da177e4SLinus Torvalds bra.b _L7_6s 18441da177e4SLinus Torvalds_L7_5s: 18451da177e4SLinus Torvalds bsr.l sasind # operand is a DENORM 18461da177e4SLinus Torvalds_L7_6s: 18471da177e4SLinus Torvalds 18481da177e4SLinus Torvalds# 18491da177e4SLinus Torvalds# Result is now in FP0 18501da177e4SLinus Torvalds# 18511da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 18521da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 18531da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 18541da177e4SLinus Torvalds unlk %a6 18551da177e4SLinus Torvalds rts 18561da177e4SLinus Torvalds 18571da177e4SLinus Torvalds global _fasind_ 18581da177e4SLinus Torvalds_fasind_: 18591da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 18601da177e4SLinus Torvalds 18611da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 18621da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 18631da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 18641da177e4SLinus Torvalds 18651da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 18661da177e4SLinus Torvalds 18671da177e4SLinus Torvalds# 18681da177e4SLinus Torvalds# copy, convert, and tag input argument 18691da177e4SLinus Torvalds# 18701da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 18711da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 18721da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 18731da177e4SLinus Torvalds bsr.l tag # fetch operand type 18741da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 18751da177e4SLinus Torvalds mov.b %d0,%d1 18761da177e4SLinus Torvalds 18771da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 18781da177e4SLinus Torvalds 18791da177e4SLinus Torvalds clr.l %d0 18801da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 18811da177e4SLinus Torvalds 18821da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 18831da177e4SLinus Torvalds tst.b %d1 18841da177e4SLinus Torvalds bne.b _L7_2d 18851da177e4SLinus Torvalds bsr.l sasin # operand is a NORM 18861da177e4SLinus Torvalds bra.b _L7_6d 18871da177e4SLinus Torvalds_L7_2d: 18881da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 18891da177e4SLinus Torvalds bne.b _L7_3d # no 18901da177e4SLinus Torvalds bsr.l src_zero # yes 18911da177e4SLinus Torvalds bra.b _L7_6d 18921da177e4SLinus Torvalds_L7_3d: 18931da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 18941da177e4SLinus Torvalds bne.b _L7_4d # no 18951da177e4SLinus Torvalds bsr.l t_operr # yes 18961da177e4SLinus Torvalds bra.b _L7_6d 18971da177e4SLinus Torvalds_L7_4d: 18981da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 18991da177e4SLinus Torvalds bne.b _L7_5d # no 19001da177e4SLinus Torvalds bsr.l src_qnan # yes 19011da177e4SLinus Torvalds bra.b _L7_6d 19021da177e4SLinus Torvalds_L7_5d: 19031da177e4SLinus Torvalds bsr.l sasind # operand is a DENORM 19041da177e4SLinus Torvalds_L7_6d: 19051da177e4SLinus Torvalds 19061da177e4SLinus Torvalds# 19071da177e4SLinus Torvalds# Result is now in FP0 19081da177e4SLinus Torvalds# 19091da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 19101da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 19111da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 19121da177e4SLinus Torvalds unlk %a6 19131da177e4SLinus Torvalds rts 19141da177e4SLinus Torvalds 19151da177e4SLinus Torvalds global _fasinx_ 19161da177e4SLinus Torvalds_fasinx_: 19171da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 19181da177e4SLinus Torvalds 19191da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 19201da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 19211da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 19221da177e4SLinus Torvalds 19231da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 19241da177e4SLinus Torvalds 19251da177e4SLinus Torvalds# 19261da177e4SLinus Torvalds# copy, convert, and tag input argument 19271da177e4SLinus Torvalds# 19281da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 19291da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 19301da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 19311da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 19321da177e4SLinus Torvalds bsr.l tag # fetch operand type 19331da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 19341da177e4SLinus Torvalds mov.b %d0,%d1 19351da177e4SLinus Torvalds 19361da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 19371da177e4SLinus Torvalds 19381da177e4SLinus Torvalds clr.l %d0 19391da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 19401da177e4SLinus Torvalds 19411da177e4SLinus Torvalds tst.b %d1 19421da177e4SLinus Torvalds bne.b _L7_2x 19431da177e4SLinus Torvalds bsr.l sasin # operand is a NORM 19441da177e4SLinus Torvalds bra.b _L7_6x 19451da177e4SLinus Torvalds_L7_2x: 19461da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 19471da177e4SLinus Torvalds bne.b _L7_3x # no 19481da177e4SLinus Torvalds bsr.l src_zero # yes 19491da177e4SLinus Torvalds bra.b _L7_6x 19501da177e4SLinus Torvalds_L7_3x: 19511da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 19521da177e4SLinus Torvalds bne.b _L7_4x # no 19531da177e4SLinus Torvalds bsr.l t_operr # yes 19541da177e4SLinus Torvalds bra.b _L7_6x 19551da177e4SLinus Torvalds_L7_4x: 19561da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 19571da177e4SLinus Torvalds bne.b _L7_5x # no 19581da177e4SLinus Torvalds bsr.l src_qnan # yes 19591da177e4SLinus Torvalds bra.b _L7_6x 19601da177e4SLinus Torvalds_L7_5x: 19611da177e4SLinus Torvalds bsr.l sasind # operand is a DENORM 19621da177e4SLinus Torvalds_L7_6x: 19631da177e4SLinus Torvalds 19641da177e4SLinus Torvalds# 19651da177e4SLinus Torvalds# Result is now in FP0 19661da177e4SLinus Torvalds# 19671da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 19681da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 19691da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 19701da177e4SLinus Torvalds unlk %a6 19711da177e4SLinus Torvalds rts 19721da177e4SLinus Torvalds 19731da177e4SLinus Torvalds 19741da177e4SLinus Torvalds######################################################################### 19751da177e4SLinus Torvalds# MONADIC TEMPLATE # 19761da177e4SLinus Torvalds######################################################################### 19771da177e4SLinus Torvalds global _fatanhs_ 19781da177e4SLinus Torvalds_fatanhs_: 19791da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 19801da177e4SLinus Torvalds 19811da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 19821da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 19831da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 19841da177e4SLinus Torvalds 19851da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 19861da177e4SLinus Torvalds 19871da177e4SLinus Torvalds# 19881da177e4SLinus Torvalds# copy, convert, and tag input argument 19891da177e4SLinus Torvalds# 19901da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 19911da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 19921da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 19931da177e4SLinus Torvalds bsr.l tag # fetch operand type 19941da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 19951da177e4SLinus Torvalds mov.b %d0,%d1 19961da177e4SLinus Torvalds 19971da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 19981da177e4SLinus Torvalds 19991da177e4SLinus Torvalds clr.l %d0 20001da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 20011da177e4SLinus Torvalds 20021da177e4SLinus Torvalds tst.b %d1 20031da177e4SLinus Torvalds bne.b _L8_2s 20041da177e4SLinus Torvalds bsr.l satanh # operand is a NORM 20051da177e4SLinus Torvalds bra.b _L8_6s 20061da177e4SLinus Torvalds_L8_2s: 20071da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 20081da177e4SLinus Torvalds bne.b _L8_3s # no 20091da177e4SLinus Torvalds bsr.l src_zero # yes 20101da177e4SLinus Torvalds bra.b _L8_6s 20111da177e4SLinus Torvalds_L8_3s: 20121da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 20131da177e4SLinus Torvalds bne.b _L8_4s # no 20141da177e4SLinus Torvalds bsr.l t_operr # yes 20151da177e4SLinus Torvalds bra.b _L8_6s 20161da177e4SLinus Torvalds_L8_4s: 20171da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 20181da177e4SLinus Torvalds bne.b _L8_5s # no 20191da177e4SLinus Torvalds bsr.l src_qnan # yes 20201da177e4SLinus Torvalds bra.b _L8_6s 20211da177e4SLinus Torvalds_L8_5s: 20221da177e4SLinus Torvalds bsr.l satanhd # operand is a DENORM 20231da177e4SLinus Torvalds_L8_6s: 20241da177e4SLinus Torvalds 20251da177e4SLinus Torvalds# 20261da177e4SLinus Torvalds# Result is now in FP0 20271da177e4SLinus Torvalds# 20281da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 20291da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 20301da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 20311da177e4SLinus Torvalds unlk %a6 20321da177e4SLinus Torvalds rts 20331da177e4SLinus Torvalds 20341da177e4SLinus Torvalds global _fatanhd_ 20351da177e4SLinus Torvalds_fatanhd_: 20361da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 20371da177e4SLinus Torvalds 20381da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 20391da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 20401da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 20411da177e4SLinus Torvalds 20421da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 20431da177e4SLinus Torvalds 20441da177e4SLinus Torvalds# 20451da177e4SLinus Torvalds# copy, convert, and tag input argument 20461da177e4SLinus Torvalds# 20471da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 20481da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 20491da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 20501da177e4SLinus Torvalds bsr.l tag # fetch operand type 20511da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 20521da177e4SLinus Torvalds mov.b %d0,%d1 20531da177e4SLinus Torvalds 20541da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 20551da177e4SLinus Torvalds 20561da177e4SLinus Torvalds clr.l %d0 20571da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 20581da177e4SLinus Torvalds 20591da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 20601da177e4SLinus Torvalds tst.b %d1 20611da177e4SLinus Torvalds bne.b _L8_2d 20621da177e4SLinus Torvalds bsr.l satanh # operand is a NORM 20631da177e4SLinus Torvalds bra.b _L8_6d 20641da177e4SLinus Torvalds_L8_2d: 20651da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 20661da177e4SLinus Torvalds bne.b _L8_3d # no 20671da177e4SLinus Torvalds bsr.l src_zero # yes 20681da177e4SLinus Torvalds bra.b _L8_6d 20691da177e4SLinus Torvalds_L8_3d: 20701da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 20711da177e4SLinus Torvalds bne.b _L8_4d # no 20721da177e4SLinus Torvalds bsr.l t_operr # yes 20731da177e4SLinus Torvalds bra.b _L8_6d 20741da177e4SLinus Torvalds_L8_4d: 20751da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 20761da177e4SLinus Torvalds bne.b _L8_5d # no 20771da177e4SLinus Torvalds bsr.l src_qnan # yes 20781da177e4SLinus Torvalds bra.b _L8_6d 20791da177e4SLinus Torvalds_L8_5d: 20801da177e4SLinus Torvalds bsr.l satanhd # operand is a DENORM 20811da177e4SLinus Torvalds_L8_6d: 20821da177e4SLinus Torvalds 20831da177e4SLinus Torvalds# 20841da177e4SLinus Torvalds# Result is now in FP0 20851da177e4SLinus Torvalds# 20861da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 20871da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 20881da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 20891da177e4SLinus Torvalds unlk %a6 20901da177e4SLinus Torvalds rts 20911da177e4SLinus Torvalds 20921da177e4SLinus Torvalds global _fatanhx_ 20931da177e4SLinus Torvalds_fatanhx_: 20941da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 20951da177e4SLinus Torvalds 20961da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 20971da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 20981da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 20991da177e4SLinus Torvalds 21001da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 21011da177e4SLinus Torvalds 21021da177e4SLinus Torvalds# 21031da177e4SLinus Torvalds# copy, convert, and tag input argument 21041da177e4SLinus Torvalds# 21051da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 21061da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 21071da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 21081da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 21091da177e4SLinus Torvalds bsr.l tag # fetch operand type 21101da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 21111da177e4SLinus Torvalds mov.b %d0,%d1 21121da177e4SLinus Torvalds 21131da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 21141da177e4SLinus Torvalds 21151da177e4SLinus Torvalds clr.l %d0 21161da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 21171da177e4SLinus Torvalds 21181da177e4SLinus Torvalds tst.b %d1 21191da177e4SLinus Torvalds bne.b _L8_2x 21201da177e4SLinus Torvalds bsr.l satanh # operand is a NORM 21211da177e4SLinus Torvalds bra.b _L8_6x 21221da177e4SLinus Torvalds_L8_2x: 21231da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 21241da177e4SLinus Torvalds bne.b _L8_3x # no 21251da177e4SLinus Torvalds bsr.l src_zero # yes 21261da177e4SLinus Torvalds bra.b _L8_6x 21271da177e4SLinus Torvalds_L8_3x: 21281da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 21291da177e4SLinus Torvalds bne.b _L8_4x # no 21301da177e4SLinus Torvalds bsr.l t_operr # yes 21311da177e4SLinus Torvalds bra.b _L8_6x 21321da177e4SLinus Torvalds_L8_4x: 21331da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 21341da177e4SLinus Torvalds bne.b _L8_5x # no 21351da177e4SLinus Torvalds bsr.l src_qnan # yes 21361da177e4SLinus Torvalds bra.b _L8_6x 21371da177e4SLinus Torvalds_L8_5x: 21381da177e4SLinus Torvalds bsr.l satanhd # operand is a DENORM 21391da177e4SLinus Torvalds_L8_6x: 21401da177e4SLinus Torvalds 21411da177e4SLinus Torvalds# 21421da177e4SLinus Torvalds# Result is now in FP0 21431da177e4SLinus Torvalds# 21441da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 21451da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 21461da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 21471da177e4SLinus Torvalds unlk %a6 21481da177e4SLinus Torvalds rts 21491da177e4SLinus Torvalds 21501da177e4SLinus Torvalds 21511da177e4SLinus Torvalds######################################################################### 21521da177e4SLinus Torvalds# MONADIC TEMPLATE # 21531da177e4SLinus Torvalds######################################################################### 21541da177e4SLinus Torvalds global _ftans_ 21551da177e4SLinus Torvalds_ftans_: 21561da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 21571da177e4SLinus Torvalds 21581da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 21591da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 21601da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 21611da177e4SLinus Torvalds 21621da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 21631da177e4SLinus Torvalds 21641da177e4SLinus Torvalds# 21651da177e4SLinus Torvalds# copy, convert, and tag input argument 21661da177e4SLinus Torvalds# 21671da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 21681da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 21691da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 21701da177e4SLinus Torvalds bsr.l tag # fetch operand type 21711da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 21721da177e4SLinus Torvalds mov.b %d0,%d1 21731da177e4SLinus Torvalds 21741da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 21751da177e4SLinus Torvalds 21761da177e4SLinus Torvalds clr.l %d0 21771da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 21781da177e4SLinus Torvalds 21791da177e4SLinus Torvalds tst.b %d1 21801da177e4SLinus Torvalds bne.b _L9_2s 21811da177e4SLinus Torvalds bsr.l stan # operand is a NORM 21821da177e4SLinus Torvalds bra.b _L9_6s 21831da177e4SLinus Torvalds_L9_2s: 21841da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 21851da177e4SLinus Torvalds bne.b _L9_3s # no 21861da177e4SLinus Torvalds bsr.l src_zero # yes 21871da177e4SLinus Torvalds bra.b _L9_6s 21881da177e4SLinus Torvalds_L9_3s: 21891da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 21901da177e4SLinus Torvalds bne.b _L9_4s # no 21911da177e4SLinus Torvalds bsr.l t_operr # yes 21921da177e4SLinus Torvalds bra.b _L9_6s 21931da177e4SLinus Torvalds_L9_4s: 21941da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 21951da177e4SLinus Torvalds bne.b _L9_5s # no 21961da177e4SLinus Torvalds bsr.l src_qnan # yes 21971da177e4SLinus Torvalds bra.b _L9_6s 21981da177e4SLinus Torvalds_L9_5s: 21991da177e4SLinus Torvalds bsr.l stand # operand is a DENORM 22001da177e4SLinus Torvalds_L9_6s: 22011da177e4SLinus Torvalds 22021da177e4SLinus Torvalds# 22031da177e4SLinus Torvalds# Result is now in FP0 22041da177e4SLinus Torvalds# 22051da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 22061da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 22071da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 22081da177e4SLinus Torvalds unlk %a6 22091da177e4SLinus Torvalds rts 22101da177e4SLinus Torvalds 22111da177e4SLinus Torvalds global _ftand_ 22121da177e4SLinus Torvalds_ftand_: 22131da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 22141da177e4SLinus Torvalds 22151da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 22161da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 22171da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 22181da177e4SLinus Torvalds 22191da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 22201da177e4SLinus Torvalds 22211da177e4SLinus Torvalds# 22221da177e4SLinus Torvalds# copy, convert, and tag input argument 22231da177e4SLinus Torvalds# 22241da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 22251da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 22261da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 22271da177e4SLinus Torvalds bsr.l tag # fetch operand type 22281da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 22291da177e4SLinus Torvalds mov.b %d0,%d1 22301da177e4SLinus Torvalds 22311da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 22321da177e4SLinus Torvalds 22331da177e4SLinus Torvalds clr.l %d0 22341da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 22351da177e4SLinus Torvalds 22361da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 22371da177e4SLinus Torvalds tst.b %d1 22381da177e4SLinus Torvalds bne.b _L9_2d 22391da177e4SLinus Torvalds bsr.l stan # operand is a NORM 22401da177e4SLinus Torvalds bra.b _L9_6d 22411da177e4SLinus Torvalds_L9_2d: 22421da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 22431da177e4SLinus Torvalds bne.b _L9_3d # no 22441da177e4SLinus Torvalds bsr.l src_zero # yes 22451da177e4SLinus Torvalds bra.b _L9_6d 22461da177e4SLinus Torvalds_L9_3d: 22471da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 22481da177e4SLinus Torvalds bne.b _L9_4d # no 22491da177e4SLinus Torvalds bsr.l t_operr # yes 22501da177e4SLinus Torvalds bra.b _L9_6d 22511da177e4SLinus Torvalds_L9_4d: 22521da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 22531da177e4SLinus Torvalds bne.b _L9_5d # no 22541da177e4SLinus Torvalds bsr.l src_qnan # yes 22551da177e4SLinus Torvalds bra.b _L9_6d 22561da177e4SLinus Torvalds_L9_5d: 22571da177e4SLinus Torvalds bsr.l stand # operand is a DENORM 22581da177e4SLinus Torvalds_L9_6d: 22591da177e4SLinus Torvalds 22601da177e4SLinus Torvalds# 22611da177e4SLinus Torvalds# Result is now in FP0 22621da177e4SLinus Torvalds# 22631da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 22641da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 22651da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 22661da177e4SLinus Torvalds unlk %a6 22671da177e4SLinus Torvalds rts 22681da177e4SLinus Torvalds 22691da177e4SLinus Torvalds global _ftanx_ 22701da177e4SLinus Torvalds_ftanx_: 22711da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 22721da177e4SLinus Torvalds 22731da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 22741da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 22751da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 22761da177e4SLinus Torvalds 22771da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 22781da177e4SLinus Torvalds 22791da177e4SLinus Torvalds# 22801da177e4SLinus Torvalds# copy, convert, and tag input argument 22811da177e4SLinus Torvalds# 22821da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 22831da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 22841da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 22851da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 22861da177e4SLinus Torvalds bsr.l tag # fetch operand type 22871da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 22881da177e4SLinus Torvalds mov.b %d0,%d1 22891da177e4SLinus Torvalds 22901da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 22911da177e4SLinus Torvalds 22921da177e4SLinus Torvalds clr.l %d0 22931da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 22941da177e4SLinus Torvalds 22951da177e4SLinus Torvalds tst.b %d1 22961da177e4SLinus Torvalds bne.b _L9_2x 22971da177e4SLinus Torvalds bsr.l stan # operand is a NORM 22981da177e4SLinus Torvalds bra.b _L9_6x 22991da177e4SLinus Torvalds_L9_2x: 23001da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 23011da177e4SLinus Torvalds bne.b _L9_3x # no 23021da177e4SLinus Torvalds bsr.l src_zero # yes 23031da177e4SLinus Torvalds bra.b _L9_6x 23041da177e4SLinus Torvalds_L9_3x: 23051da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 23061da177e4SLinus Torvalds bne.b _L9_4x # no 23071da177e4SLinus Torvalds bsr.l t_operr # yes 23081da177e4SLinus Torvalds bra.b _L9_6x 23091da177e4SLinus Torvalds_L9_4x: 23101da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 23111da177e4SLinus Torvalds bne.b _L9_5x # no 23121da177e4SLinus Torvalds bsr.l src_qnan # yes 23131da177e4SLinus Torvalds bra.b _L9_6x 23141da177e4SLinus Torvalds_L9_5x: 23151da177e4SLinus Torvalds bsr.l stand # operand is a DENORM 23161da177e4SLinus Torvalds_L9_6x: 23171da177e4SLinus Torvalds 23181da177e4SLinus Torvalds# 23191da177e4SLinus Torvalds# Result is now in FP0 23201da177e4SLinus Torvalds# 23211da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 23221da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 23231da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 23241da177e4SLinus Torvalds unlk %a6 23251da177e4SLinus Torvalds rts 23261da177e4SLinus Torvalds 23271da177e4SLinus Torvalds 23281da177e4SLinus Torvalds######################################################################### 23291da177e4SLinus Torvalds# MONADIC TEMPLATE # 23301da177e4SLinus Torvalds######################################################################### 23311da177e4SLinus Torvalds global _fetoxs_ 23321da177e4SLinus Torvalds_fetoxs_: 23331da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 23341da177e4SLinus Torvalds 23351da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 23361da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 23371da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 23381da177e4SLinus Torvalds 23391da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 23401da177e4SLinus Torvalds 23411da177e4SLinus Torvalds# 23421da177e4SLinus Torvalds# copy, convert, and tag input argument 23431da177e4SLinus Torvalds# 23441da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 23451da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 23461da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 23471da177e4SLinus Torvalds bsr.l tag # fetch operand type 23481da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 23491da177e4SLinus Torvalds mov.b %d0,%d1 23501da177e4SLinus Torvalds 23511da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 23521da177e4SLinus Torvalds 23531da177e4SLinus Torvalds clr.l %d0 23541da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 23551da177e4SLinus Torvalds 23561da177e4SLinus Torvalds tst.b %d1 23571da177e4SLinus Torvalds bne.b _L10_2s 23581da177e4SLinus Torvalds bsr.l setox # operand is a NORM 23591da177e4SLinus Torvalds bra.b _L10_6s 23601da177e4SLinus Torvalds_L10_2s: 23611da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 23621da177e4SLinus Torvalds bne.b _L10_3s # no 23631da177e4SLinus Torvalds bsr.l ld_pone # yes 23641da177e4SLinus Torvalds bra.b _L10_6s 23651da177e4SLinus Torvalds_L10_3s: 23661da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 23671da177e4SLinus Torvalds bne.b _L10_4s # no 23681da177e4SLinus Torvalds bsr.l szr_inf # yes 23691da177e4SLinus Torvalds bra.b _L10_6s 23701da177e4SLinus Torvalds_L10_4s: 23711da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 23721da177e4SLinus Torvalds bne.b _L10_5s # no 23731da177e4SLinus Torvalds bsr.l src_qnan # yes 23741da177e4SLinus Torvalds bra.b _L10_6s 23751da177e4SLinus Torvalds_L10_5s: 23761da177e4SLinus Torvalds bsr.l setoxd # operand is a DENORM 23771da177e4SLinus Torvalds_L10_6s: 23781da177e4SLinus Torvalds 23791da177e4SLinus Torvalds# 23801da177e4SLinus Torvalds# Result is now in FP0 23811da177e4SLinus Torvalds# 23821da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 23831da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 23841da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 23851da177e4SLinus Torvalds unlk %a6 23861da177e4SLinus Torvalds rts 23871da177e4SLinus Torvalds 23881da177e4SLinus Torvalds global _fetoxd_ 23891da177e4SLinus Torvalds_fetoxd_: 23901da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 23911da177e4SLinus Torvalds 23921da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 23931da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 23941da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 23951da177e4SLinus Torvalds 23961da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 23971da177e4SLinus Torvalds 23981da177e4SLinus Torvalds# 23991da177e4SLinus Torvalds# copy, convert, and tag input argument 24001da177e4SLinus Torvalds# 24011da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 24021da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 24031da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 24041da177e4SLinus Torvalds bsr.l tag # fetch operand type 24051da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 24061da177e4SLinus Torvalds mov.b %d0,%d1 24071da177e4SLinus Torvalds 24081da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 24091da177e4SLinus Torvalds 24101da177e4SLinus Torvalds clr.l %d0 24111da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 24121da177e4SLinus Torvalds 24131da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 24141da177e4SLinus Torvalds tst.b %d1 24151da177e4SLinus Torvalds bne.b _L10_2d 24161da177e4SLinus Torvalds bsr.l setox # operand is a NORM 24171da177e4SLinus Torvalds bra.b _L10_6d 24181da177e4SLinus Torvalds_L10_2d: 24191da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 24201da177e4SLinus Torvalds bne.b _L10_3d # no 24211da177e4SLinus Torvalds bsr.l ld_pone # yes 24221da177e4SLinus Torvalds bra.b _L10_6d 24231da177e4SLinus Torvalds_L10_3d: 24241da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 24251da177e4SLinus Torvalds bne.b _L10_4d # no 24261da177e4SLinus Torvalds bsr.l szr_inf # yes 24271da177e4SLinus Torvalds bra.b _L10_6d 24281da177e4SLinus Torvalds_L10_4d: 24291da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 24301da177e4SLinus Torvalds bne.b _L10_5d # no 24311da177e4SLinus Torvalds bsr.l src_qnan # yes 24321da177e4SLinus Torvalds bra.b _L10_6d 24331da177e4SLinus Torvalds_L10_5d: 24341da177e4SLinus Torvalds bsr.l setoxd # operand is a DENORM 24351da177e4SLinus Torvalds_L10_6d: 24361da177e4SLinus Torvalds 24371da177e4SLinus Torvalds# 24381da177e4SLinus Torvalds# Result is now in FP0 24391da177e4SLinus Torvalds# 24401da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 24411da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 24421da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 24431da177e4SLinus Torvalds unlk %a6 24441da177e4SLinus Torvalds rts 24451da177e4SLinus Torvalds 24461da177e4SLinus Torvalds global _fetoxx_ 24471da177e4SLinus Torvalds_fetoxx_: 24481da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 24491da177e4SLinus Torvalds 24501da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 24511da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 24521da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 24531da177e4SLinus Torvalds 24541da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 24551da177e4SLinus Torvalds 24561da177e4SLinus Torvalds# 24571da177e4SLinus Torvalds# copy, convert, and tag input argument 24581da177e4SLinus Torvalds# 24591da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 24601da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 24611da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 24621da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 24631da177e4SLinus Torvalds bsr.l tag # fetch operand type 24641da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 24651da177e4SLinus Torvalds mov.b %d0,%d1 24661da177e4SLinus Torvalds 24671da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 24681da177e4SLinus Torvalds 24691da177e4SLinus Torvalds clr.l %d0 24701da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 24711da177e4SLinus Torvalds 24721da177e4SLinus Torvalds tst.b %d1 24731da177e4SLinus Torvalds bne.b _L10_2x 24741da177e4SLinus Torvalds bsr.l setox # operand is a NORM 24751da177e4SLinus Torvalds bra.b _L10_6x 24761da177e4SLinus Torvalds_L10_2x: 24771da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 24781da177e4SLinus Torvalds bne.b _L10_3x # no 24791da177e4SLinus Torvalds bsr.l ld_pone # yes 24801da177e4SLinus Torvalds bra.b _L10_6x 24811da177e4SLinus Torvalds_L10_3x: 24821da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 24831da177e4SLinus Torvalds bne.b _L10_4x # no 24841da177e4SLinus Torvalds bsr.l szr_inf # yes 24851da177e4SLinus Torvalds bra.b _L10_6x 24861da177e4SLinus Torvalds_L10_4x: 24871da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 24881da177e4SLinus Torvalds bne.b _L10_5x # no 24891da177e4SLinus Torvalds bsr.l src_qnan # yes 24901da177e4SLinus Torvalds bra.b _L10_6x 24911da177e4SLinus Torvalds_L10_5x: 24921da177e4SLinus Torvalds bsr.l setoxd # operand is a DENORM 24931da177e4SLinus Torvalds_L10_6x: 24941da177e4SLinus Torvalds 24951da177e4SLinus Torvalds# 24961da177e4SLinus Torvalds# Result is now in FP0 24971da177e4SLinus Torvalds# 24981da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 24991da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 25001da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 25011da177e4SLinus Torvalds unlk %a6 25021da177e4SLinus Torvalds rts 25031da177e4SLinus Torvalds 25041da177e4SLinus Torvalds 25051da177e4SLinus Torvalds######################################################################### 25061da177e4SLinus Torvalds# MONADIC TEMPLATE # 25071da177e4SLinus Torvalds######################################################################### 25081da177e4SLinus Torvalds global _ftwotoxs_ 25091da177e4SLinus Torvalds_ftwotoxs_: 25101da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 25111da177e4SLinus Torvalds 25121da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 25131da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 25141da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 25151da177e4SLinus Torvalds 25161da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 25171da177e4SLinus Torvalds 25181da177e4SLinus Torvalds# 25191da177e4SLinus Torvalds# copy, convert, and tag input argument 25201da177e4SLinus Torvalds# 25211da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 25221da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 25231da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 25241da177e4SLinus Torvalds bsr.l tag # fetch operand type 25251da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 25261da177e4SLinus Torvalds mov.b %d0,%d1 25271da177e4SLinus Torvalds 25281da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 25291da177e4SLinus Torvalds 25301da177e4SLinus Torvalds clr.l %d0 25311da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 25321da177e4SLinus Torvalds 25331da177e4SLinus Torvalds tst.b %d1 25341da177e4SLinus Torvalds bne.b _L11_2s 25351da177e4SLinus Torvalds bsr.l stwotox # operand is a NORM 25361da177e4SLinus Torvalds bra.b _L11_6s 25371da177e4SLinus Torvalds_L11_2s: 25381da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 25391da177e4SLinus Torvalds bne.b _L11_3s # no 25401da177e4SLinus Torvalds bsr.l ld_pone # yes 25411da177e4SLinus Torvalds bra.b _L11_6s 25421da177e4SLinus Torvalds_L11_3s: 25431da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 25441da177e4SLinus Torvalds bne.b _L11_4s # no 25451da177e4SLinus Torvalds bsr.l szr_inf # yes 25461da177e4SLinus Torvalds bra.b _L11_6s 25471da177e4SLinus Torvalds_L11_4s: 25481da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 25491da177e4SLinus Torvalds bne.b _L11_5s # no 25501da177e4SLinus Torvalds bsr.l src_qnan # yes 25511da177e4SLinus Torvalds bra.b _L11_6s 25521da177e4SLinus Torvalds_L11_5s: 25531da177e4SLinus Torvalds bsr.l stwotoxd # operand is a DENORM 25541da177e4SLinus Torvalds_L11_6s: 25551da177e4SLinus Torvalds 25561da177e4SLinus Torvalds# 25571da177e4SLinus Torvalds# Result is now in FP0 25581da177e4SLinus Torvalds# 25591da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 25601da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 25611da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 25621da177e4SLinus Torvalds unlk %a6 25631da177e4SLinus Torvalds rts 25641da177e4SLinus Torvalds 25651da177e4SLinus Torvalds global _ftwotoxd_ 25661da177e4SLinus Torvalds_ftwotoxd_: 25671da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 25681da177e4SLinus Torvalds 25691da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 25701da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 25711da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 25721da177e4SLinus Torvalds 25731da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 25741da177e4SLinus Torvalds 25751da177e4SLinus Torvalds# 25761da177e4SLinus Torvalds# copy, convert, and tag input argument 25771da177e4SLinus Torvalds# 25781da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 25791da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 25801da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 25811da177e4SLinus Torvalds bsr.l tag # fetch operand type 25821da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 25831da177e4SLinus Torvalds mov.b %d0,%d1 25841da177e4SLinus Torvalds 25851da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 25861da177e4SLinus Torvalds 25871da177e4SLinus Torvalds clr.l %d0 25881da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 25891da177e4SLinus Torvalds 25901da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 25911da177e4SLinus Torvalds tst.b %d1 25921da177e4SLinus Torvalds bne.b _L11_2d 25931da177e4SLinus Torvalds bsr.l stwotox # operand is a NORM 25941da177e4SLinus Torvalds bra.b _L11_6d 25951da177e4SLinus Torvalds_L11_2d: 25961da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 25971da177e4SLinus Torvalds bne.b _L11_3d # no 25981da177e4SLinus Torvalds bsr.l ld_pone # yes 25991da177e4SLinus Torvalds bra.b _L11_6d 26001da177e4SLinus Torvalds_L11_3d: 26011da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 26021da177e4SLinus Torvalds bne.b _L11_4d # no 26031da177e4SLinus Torvalds bsr.l szr_inf # yes 26041da177e4SLinus Torvalds bra.b _L11_6d 26051da177e4SLinus Torvalds_L11_4d: 26061da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 26071da177e4SLinus Torvalds bne.b _L11_5d # no 26081da177e4SLinus Torvalds bsr.l src_qnan # yes 26091da177e4SLinus Torvalds bra.b _L11_6d 26101da177e4SLinus Torvalds_L11_5d: 26111da177e4SLinus Torvalds bsr.l stwotoxd # operand is a DENORM 26121da177e4SLinus Torvalds_L11_6d: 26131da177e4SLinus Torvalds 26141da177e4SLinus Torvalds# 26151da177e4SLinus Torvalds# Result is now in FP0 26161da177e4SLinus Torvalds# 26171da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 26181da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 26191da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 26201da177e4SLinus Torvalds unlk %a6 26211da177e4SLinus Torvalds rts 26221da177e4SLinus Torvalds 26231da177e4SLinus Torvalds global _ftwotoxx_ 26241da177e4SLinus Torvalds_ftwotoxx_: 26251da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 26261da177e4SLinus Torvalds 26271da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 26281da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 26291da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 26301da177e4SLinus Torvalds 26311da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 26321da177e4SLinus Torvalds 26331da177e4SLinus Torvalds# 26341da177e4SLinus Torvalds# copy, convert, and tag input argument 26351da177e4SLinus Torvalds# 26361da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 26371da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 26381da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 26391da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 26401da177e4SLinus Torvalds bsr.l tag # fetch operand type 26411da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 26421da177e4SLinus Torvalds mov.b %d0,%d1 26431da177e4SLinus Torvalds 26441da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 26451da177e4SLinus Torvalds 26461da177e4SLinus Torvalds clr.l %d0 26471da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 26481da177e4SLinus Torvalds 26491da177e4SLinus Torvalds tst.b %d1 26501da177e4SLinus Torvalds bne.b _L11_2x 26511da177e4SLinus Torvalds bsr.l stwotox # operand is a NORM 26521da177e4SLinus Torvalds bra.b _L11_6x 26531da177e4SLinus Torvalds_L11_2x: 26541da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 26551da177e4SLinus Torvalds bne.b _L11_3x # no 26561da177e4SLinus Torvalds bsr.l ld_pone # yes 26571da177e4SLinus Torvalds bra.b _L11_6x 26581da177e4SLinus Torvalds_L11_3x: 26591da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 26601da177e4SLinus Torvalds bne.b _L11_4x # no 26611da177e4SLinus Torvalds bsr.l szr_inf # yes 26621da177e4SLinus Torvalds bra.b _L11_6x 26631da177e4SLinus Torvalds_L11_4x: 26641da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 26651da177e4SLinus Torvalds bne.b _L11_5x # no 26661da177e4SLinus Torvalds bsr.l src_qnan # yes 26671da177e4SLinus Torvalds bra.b _L11_6x 26681da177e4SLinus Torvalds_L11_5x: 26691da177e4SLinus Torvalds bsr.l stwotoxd # operand is a DENORM 26701da177e4SLinus Torvalds_L11_6x: 26711da177e4SLinus Torvalds 26721da177e4SLinus Torvalds# 26731da177e4SLinus Torvalds# Result is now in FP0 26741da177e4SLinus Torvalds# 26751da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 26761da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 26771da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 26781da177e4SLinus Torvalds unlk %a6 26791da177e4SLinus Torvalds rts 26801da177e4SLinus Torvalds 26811da177e4SLinus Torvalds 26821da177e4SLinus Torvalds######################################################################### 26831da177e4SLinus Torvalds# MONADIC TEMPLATE # 26841da177e4SLinus Torvalds######################################################################### 26851da177e4SLinus Torvalds global _ftentoxs_ 26861da177e4SLinus Torvalds_ftentoxs_: 26871da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 26881da177e4SLinus Torvalds 26891da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 26901da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 26911da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 26921da177e4SLinus Torvalds 26931da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 26941da177e4SLinus Torvalds 26951da177e4SLinus Torvalds# 26961da177e4SLinus Torvalds# copy, convert, and tag input argument 26971da177e4SLinus Torvalds# 26981da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 26991da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 27001da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 27011da177e4SLinus Torvalds bsr.l tag # fetch operand type 27021da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 27031da177e4SLinus Torvalds mov.b %d0,%d1 27041da177e4SLinus Torvalds 27051da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 27061da177e4SLinus Torvalds 27071da177e4SLinus Torvalds clr.l %d0 27081da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 27091da177e4SLinus Torvalds 27101da177e4SLinus Torvalds tst.b %d1 27111da177e4SLinus Torvalds bne.b _L12_2s 27121da177e4SLinus Torvalds bsr.l stentox # operand is a NORM 27131da177e4SLinus Torvalds bra.b _L12_6s 27141da177e4SLinus Torvalds_L12_2s: 27151da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 27161da177e4SLinus Torvalds bne.b _L12_3s # no 27171da177e4SLinus Torvalds bsr.l ld_pone # yes 27181da177e4SLinus Torvalds bra.b _L12_6s 27191da177e4SLinus Torvalds_L12_3s: 27201da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 27211da177e4SLinus Torvalds bne.b _L12_4s # no 27221da177e4SLinus Torvalds bsr.l szr_inf # yes 27231da177e4SLinus Torvalds bra.b _L12_6s 27241da177e4SLinus Torvalds_L12_4s: 27251da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 27261da177e4SLinus Torvalds bne.b _L12_5s # no 27271da177e4SLinus Torvalds bsr.l src_qnan # yes 27281da177e4SLinus Torvalds bra.b _L12_6s 27291da177e4SLinus Torvalds_L12_5s: 27301da177e4SLinus Torvalds bsr.l stentoxd # operand is a DENORM 27311da177e4SLinus Torvalds_L12_6s: 27321da177e4SLinus Torvalds 27331da177e4SLinus Torvalds# 27341da177e4SLinus Torvalds# Result is now in FP0 27351da177e4SLinus Torvalds# 27361da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 27371da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 27381da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 27391da177e4SLinus Torvalds unlk %a6 27401da177e4SLinus Torvalds rts 27411da177e4SLinus Torvalds 27421da177e4SLinus Torvalds global _ftentoxd_ 27431da177e4SLinus Torvalds_ftentoxd_: 27441da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 27451da177e4SLinus Torvalds 27461da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 27471da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 27481da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 27491da177e4SLinus Torvalds 27501da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 27511da177e4SLinus Torvalds 27521da177e4SLinus Torvalds# 27531da177e4SLinus Torvalds# copy, convert, and tag input argument 27541da177e4SLinus Torvalds# 27551da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 27561da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 27571da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 27581da177e4SLinus Torvalds bsr.l tag # fetch operand type 27591da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 27601da177e4SLinus Torvalds mov.b %d0,%d1 27611da177e4SLinus Torvalds 27621da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 27631da177e4SLinus Torvalds 27641da177e4SLinus Torvalds clr.l %d0 27651da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 27661da177e4SLinus Torvalds 27671da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 27681da177e4SLinus Torvalds tst.b %d1 27691da177e4SLinus Torvalds bne.b _L12_2d 27701da177e4SLinus Torvalds bsr.l stentox # operand is a NORM 27711da177e4SLinus Torvalds bra.b _L12_6d 27721da177e4SLinus Torvalds_L12_2d: 27731da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 27741da177e4SLinus Torvalds bne.b _L12_3d # no 27751da177e4SLinus Torvalds bsr.l ld_pone # yes 27761da177e4SLinus Torvalds bra.b _L12_6d 27771da177e4SLinus Torvalds_L12_3d: 27781da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 27791da177e4SLinus Torvalds bne.b _L12_4d # no 27801da177e4SLinus Torvalds bsr.l szr_inf # yes 27811da177e4SLinus Torvalds bra.b _L12_6d 27821da177e4SLinus Torvalds_L12_4d: 27831da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 27841da177e4SLinus Torvalds bne.b _L12_5d # no 27851da177e4SLinus Torvalds bsr.l src_qnan # yes 27861da177e4SLinus Torvalds bra.b _L12_6d 27871da177e4SLinus Torvalds_L12_5d: 27881da177e4SLinus Torvalds bsr.l stentoxd # operand is a DENORM 27891da177e4SLinus Torvalds_L12_6d: 27901da177e4SLinus Torvalds 27911da177e4SLinus Torvalds# 27921da177e4SLinus Torvalds# Result is now in FP0 27931da177e4SLinus Torvalds# 27941da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 27951da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 27961da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 27971da177e4SLinus Torvalds unlk %a6 27981da177e4SLinus Torvalds rts 27991da177e4SLinus Torvalds 28001da177e4SLinus Torvalds global _ftentoxx_ 28011da177e4SLinus Torvalds_ftentoxx_: 28021da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 28031da177e4SLinus Torvalds 28041da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 28051da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 28061da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 28071da177e4SLinus Torvalds 28081da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 28091da177e4SLinus Torvalds 28101da177e4SLinus Torvalds# 28111da177e4SLinus Torvalds# copy, convert, and tag input argument 28121da177e4SLinus Torvalds# 28131da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 28141da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 28151da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 28161da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 28171da177e4SLinus Torvalds bsr.l tag # fetch operand type 28181da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 28191da177e4SLinus Torvalds mov.b %d0,%d1 28201da177e4SLinus Torvalds 28211da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 28221da177e4SLinus Torvalds 28231da177e4SLinus Torvalds clr.l %d0 28241da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 28251da177e4SLinus Torvalds 28261da177e4SLinus Torvalds tst.b %d1 28271da177e4SLinus Torvalds bne.b _L12_2x 28281da177e4SLinus Torvalds bsr.l stentox # operand is a NORM 28291da177e4SLinus Torvalds bra.b _L12_6x 28301da177e4SLinus Torvalds_L12_2x: 28311da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 28321da177e4SLinus Torvalds bne.b _L12_3x # no 28331da177e4SLinus Torvalds bsr.l ld_pone # yes 28341da177e4SLinus Torvalds bra.b _L12_6x 28351da177e4SLinus Torvalds_L12_3x: 28361da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 28371da177e4SLinus Torvalds bne.b _L12_4x # no 28381da177e4SLinus Torvalds bsr.l szr_inf # yes 28391da177e4SLinus Torvalds bra.b _L12_6x 28401da177e4SLinus Torvalds_L12_4x: 28411da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 28421da177e4SLinus Torvalds bne.b _L12_5x # no 28431da177e4SLinus Torvalds bsr.l src_qnan # yes 28441da177e4SLinus Torvalds bra.b _L12_6x 28451da177e4SLinus Torvalds_L12_5x: 28461da177e4SLinus Torvalds bsr.l stentoxd # operand is a DENORM 28471da177e4SLinus Torvalds_L12_6x: 28481da177e4SLinus Torvalds 28491da177e4SLinus Torvalds# 28501da177e4SLinus Torvalds# Result is now in FP0 28511da177e4SLinus Torvalds# 28521da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 28531da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 28541da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 28551da177e4SLinus Torvalds unlk %a6 28561da177e4SLinus Torvalds rts 28571da177e4SLinus Torvalds 28581da177e4SLinus Torvalds 28591da177e4SLinus Torvalds######################################################################### 28601da177e4SLinus Torvalds# MONADIC TEMPLATE # 28611da177e4SLinus Torvalds######################################################################### 28621da177e4SLinus Torvalds global _flogns_ 28631da177e4SLinus Torvalds_flogns_: 28641da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 28651da177e4SLinus Torvalds 28661da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 28671da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 28681da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 28691da177e4SLinus Torvalds 28701da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 28711da177e4SLinus Torvalds 28721da177e4SLinus Torvalds# 28731da177e4SLinus Torvalds# copy, convert, and tag input argument 28741da177e4SLinus Torvalds# 28751da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 28761da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 28771da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 28781da177e4SLinus Torvalds bsr.l tag # fetch operand type 28791da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 28801da177e4SLinus Torvalds mov.b %d0,%d1 28811da177e4SLinus Torvalds 28821da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 28831da177e4SLinus Torvalds 28841da177e4SLinus Torvalds clr.l %d0 28851da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 28861da177e4SLinus Torvalds 28871da177e4SLinus Torvalds tst.b %d1 28881da177e4SLinus Torvalds bne.b _L13_2s 28891da177e4SLinus Torvalds bsr.l slogn # operand is a NORM 28901da177e4SLinus Torvalds bra.b _L13_6s 28911da177e4SLinus Torvalds_L13_2s: 28921da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 28931da177e4SLinus Torvalds bne.b _L13_3s # no 28941da177e4SLinus Torvalds bsr.l t_dz2 # yes 28951da177e4SLinus Torvalds bra.b _L13_6s 28961da177e4SLinus Torvalds_L13_3s: 28971da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 28981da177e4SLinus Torvalds bne.b _L13_4s # no 28991da177e4SLinus Torvalds bsr.l sopr_inf # yes 29001da177e4SLinus Torvalds bra.b _L13_6s 29011da177e4SLinus Torvalds_L13_4s: 29021da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 29031da177e4SLinus Torvalds bne.b _L13_5s # no 29041da177e4SLinus Torvalds bsr.l src_qnan # yes 29051da177e4SLinus Torvalds bra.b _L13_6s 29061da177e4SLinus Torvalds_L13_5s: 29071da177e4SLinus Torvalds bsr.l slognd # operand is a DENORM 29081da177e4SLinus Torvalds_L13_6s: 29091da177e4SLinus Torvalds 29101da177e4SLinus Torvalds# 29111da177e4SLinus Torvalds# Result is now in FP0 29121da177e4SLinus Torvalds# 29131da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 29141da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 29151da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 29161da177e4SLinus Torvalds unlk %a6 29171da177e4SLinus Torvalds rts 29181da177e4SLinus Torvalds 29191da177e4SLinus Torvalds global _flognd_ 29201da177e4SLinus Torvalds_flognd_: 29211da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 29221da177e4SLinus Torvalds 29231da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 29241da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 29251da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 29261da177e4SLinus Torvalds 29271da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 29281da177e4SLinus Torvalds 29291da177e4SLinus Torvalds# 29301da177e4SLinus Torvalds# copy, convert, and tag input argument 29311da177e4SLinus Torvalds# 29321da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 29331da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 29341da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 29351da177e4SLinus Torvalds bsr.l tag # fetch operand type 29361da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 29371da177e4SLinus Torvalds mov.b %d0,%d1 29381da177e4SLinus Torvalds 29391da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 29401da177e4SLinus Torvalds 29411da177e4SLinus Torvalds clr.l %d0 29421da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 29431da177e4SLinus Torvalds 29441da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 29451da177e4SLinus Torvalds tst.b %d1 29461da177e4SLinus Torvalds bne.b _L13_2d 29471da177e4SLinus Torvalds bsr.l slogn # operand is a NORM 29481da177e4SLinus Torvalds bra.b _L13_6d 29491da177e4SLinus Torvalds_L13_2d: 29501da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 29511da177e4SLinus Torvalds bne.b _L13_3d # no 29521da177e4SLinus Torvalds bsr.l t_dz2 # yes 29531da177e4SLinus Torvalds bra.b _L13_6d 29541da177e4SLinus Torvalds_L13_3d: 29551da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 29561da177e4SLinus Torvalds bne.b _L13_4d # no 29571da177e4SLinus Torvalds bsr.l sopr_inf # yes 29581da177e4SLinus Torvalds bra.b _L13_6d 29591da177e4SLinus Torvalds_L13_4d: 29601da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 29611da177e4SLinus Torvalds bne.b _L13_5d # no 29621da177e4SLinus Torvalds bsr.l src_qnan # yes 29631da177e4SLinus Torvalds bra.b _L13_6d 29641da177e4SLinus Torvalds_L13_5d: 29651da177e4SLinus Torvalds bsr.l slognd # operand is a DENORM 29661da177e4SLinus Torvalds_L13_6d: 29671da177e4SLinus Torvalds 29681da177e4SLinus Torvalds# 29691da177e4SLinus Torvalds# Result is now in FP0 29701da177e4SLinus Torvalds# 29711da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 29721da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 29731da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 29741da177e4SLinus Torvalds unlk %a6 29751da177e4SLinus Torvalds rts 29761da177e4SLinus Torvalds 29771da177e4SLinus Torvalds global _flognx_ 29781da177e4SLinus Torvalds_flognx_: 29791da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 29801da177e4SLinus Torvalds 29811da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 29821da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 29831da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 29841da177e4SLinus Torvalds 29851da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 29861da177e4SLinus Torvalds 29871da177e4SLinus Torvalds# 29881da177e4SLinus Torvalds# copy, convert, and tag input argument 29891da177e4SLinus Torvalds# 29901da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 29911da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 29921da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 29931da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 29941da177e4SLinus Torvalds bsr.l tag # fetch operand type 29951da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 29961da177e4SLinus Torvalds mov.b %d0,%d1 29971da177e4SLinus Torvalds 29981da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 29991da177e4SLinus Torvalds 30001da177e4SLinus Torvalds clr.l %d0 30011da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 30021da177e4SLinus Torvalds 30031da177e4SLinus Torvalds tst.b %d1 30041da177e4SLinus Torvalds bne.b _L13_2x 30051da177e4SLinus Torvalds bsr.l slogn # operand is a NORM 30061da177e4SLinus Torvalds bra.b _L13_6x 30071da177e4SLinus Torvalds_L13_2x: 30081da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 30091da177e4SLinus Torvalds bne.b _L13_3x # no 30101da177e4SLinus Torvalds bsr.l t_dz2 # yes 30111da177e4SLinus Torvalds bra.b _L13_6x 30121da177e4SLinus Torvalds_L13_3x: 30131da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 30141da177e4SLinus Torvalds bne.b _L13_4x # no 30151da177e4SLinus Torvalds bsr.l sopr_inf # yes 30161da177e4SLinus Torvalds bra.b _L13_6x 30171da177e4SLinus Torvalds_L13_4x: 30181da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 30191da177e4SLinus Torvalds bne.b _L13_5x # no 30201da177e4SLinus Torvalds bsr.l src_qnan # yes 30211da177e4SLinus Torvalds bra.b _L13_6x 30221da177e4SLinus Torvalds_L13_5x: 30231da177e4SLinus Torvalds bsr.l slognd # operand is a DENORM 30241da177e4SLinus Torvalds_L13_6x: 30251da177e4SLinus Torvalds 30261da177e4SLinus Torvalds# 30271da177e4SLinus Torvalds# Result is now in FP0 30281da177e4SLinus Torvalds# 30291da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 30301da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 30311da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 30321da177e4SLinus Torvalds unlk %a6 30331da177e4SLinus Torvalds rts 30341da177e4SLinus Torvalds 30351da177e4SLinus Torvalds 30361da177e4SLinus Torvalds######################################################################### 30371da177e4SLinus Torvalds# MONADIC TEMPLATE # 30381da177e4SLinus Torvalds######################################################################### 30391da177e4SLinus Torvalds global _flog10s_ 30401da177e4SLinus Torvalds_flog10s_: 30411da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 30421da177e4SLinus Torvalds 30431da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 30441da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 30451da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 30461da177e4SLinus Torvalds 30471da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 30481da177e4SLinus Torvalds 30491da177e4SLinus Torvalds# 30501da177e4SLinus Torvalds# copy, convert, and tag input argument 30511da177e4SLinus Torvalds# 30521da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 30531da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 30541da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 30551da177e4SLinus Torvalds bsr.l tag # fetch operand type 30561da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 30571da177e4SLinus Torvalds mov.b %d0,%d1 30581da177e4SLinus Torvalds 30591da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 30601da177e4SLinus Torvalds 30611da177e4SLinus Torvalds clr.l %d0 30621da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 30631da177e4SLinus Torvalds 30641da177e4SLinus Torvalds tst.b %d1 30651da177e4SLinus Torvalds bne.b _L14_2s 30661da177e4SLinus Torvalds bsr.l slog10 # operand is a NORM 30671da177e4SLinus Torvalds bra.b _L14_6s 30681da177e4SLinus Torvalds_L14_2s: 30691da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 30701da177e4SLinus Torvalds bne.b _L14_3s # no 30711da177e4SLinus Torvalds bsr.l t_dz2 # yes 30721da177e4SLinus Torvalds bra.b _L14_6s 30731da177e4SLinus Torvalds_L14_3s: 30741da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 30751da177e4SLinus Torvalds bne.b _L14_4s # no 30761da177e4SLinus Torvalds bsr.l sopr_inf # yes 30771da177e4SLinus Torvalds bra.b _L14_6s 30781da177e4SLinus Torvalds_L14_4s: 30791da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 30801da177e4SLinus Torvalds bne.b _L14_5s # no 30811da177e4SLinus Torvalds bsr.l src_qnan # yes 30821da177e4SLinus Torvalds bra.b _L14_6s 30831da177e4SLinus Torvalds_L14_5s: 30841da177e4SLinus Torvalds bsr.l slog10d # operand is a DENORM 30851da177e4SLinus Torvalds_L14_6s: 30861da177e4SLinus Torvalds 30871da177e4SLinus Torvalds# 30881da177e4SLinus Torvalds# Result is now in FP0 30891da177e4SLinus Torvalds# 30901da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 30911da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 30921da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 30931da177e4SLinus Torvalds unlk %a6 30941da177e4SLinus Torvalds rts 30951da177e4SLinus Torvalds 30961da177e4SLinus Torvalds global _flog10d_ 30971da177e4SLinus Torvalds_flog10d_: 30981da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 30991da177e4SLinus Torvalds 31001da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 31011da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 31021da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 31031da177e4SLinus Torvalds 31041da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 31051da177e4SLinus Torvalds 31061da177e4SLinus Torvalds# 31071da177e4SLinus Torvalds# copy, convert, and tag input argument 31081da177e4SLinus Torvalds# 31091da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 31101da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 31111da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 31121da177e4SLinus Torvalds bsr.l tag # fetch operand type 31131da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 31141da177e4SLinus Torvalds mov.b %d0,%d1 31151da177e4SLinus Torvalds 31161da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 31171da177e4SLinus Torvalds 31181da177e4SLinus Torvalds clr.l %d0 31191da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 31201da177e4SLinus Torvalds 31211da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 31221da177e4SLinus Torvalds tst.b %d1 31231da177e4SLinus Torvalds bne.b _L14_2d 31241da177e4SLinus Torvalds bsr.l slog10 # operand is a NORM 31251da177e4SLinus Torvalds bra.b _L14_6d 31261da177e4SLinus Torvalds_L14_2d: 31271da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 31281da177e4SLinus Torvalds bne.b _L14_3d # no 31291da177e4SLinus Torvalds bsr.l t_dz2 # yes 31301da177e4SLinus Torvalds bra.b _L14_6d 31311da177e4SLinus Torvalds_L14_3d: 31321da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 31331da177e4SLinus Torvalds bne.b _L14_4d # no 31341da177e4SLinus Torvalds bsr.l sopr_inf # yes 31351da177e4SLinus Torvalds bra.b _L14_6d 31361da177e4SLinus Torvalds_L14_4d: 31371da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 31381da177e4SLinus Torvalds bne.b _L14_5d # no 31391da177e4SLinus Torvalds bsr.l src_qnan # yes 31401da177e4SLinus Torvalds bra.b _L14_6d 31411da177e4SLinus Torvalds_L14_5d: 31421da177e4SLinus Torvalds bsr.l slog10d # operand is a DENORM 31431da177e4SLinus Torvalds_L14_6d: 31441da177e4SLinus Torvalds 31451da177e4SLinus Torvalds# 31461da177e4SLinus Torvalds# Result is now in FP0 31471da177e4SLinus Torvalds# 31481da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 31491da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 31501da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 31511da177e4SLinus Torvalds unlk %a6 31521da177e4SLinus Torvalds rts 31531da177e4SLinus Torvalds 31541da177e4SLinus Torvalds global _flog10x_ 31551da177e4SLinus Torvalds_flog10x_: 31561da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 31571da177e4SLinus Torvalds 31581da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 31591da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 31601da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 31611da177e4SLinus Torvalds 31621da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 31631da177e4SLinus Torvalds 31641da177e4SLinus Torvalds# 31651da177e4SLinus Torvalds# copy, convert, and tag input argument 31661da177e4SLinus Torvalds# 31671da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 31681da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 31691da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 31701da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 31711da177e4SLinus Torvalds bsr.l tag # fetch operand type 31721da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 31731da177e4SLinus Torvalds mov.b %d0,%d1 31741da177e4SLinus Torvalds 31751da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 31761da177e4SLinus Torvalds 31771da177e4SLinus Torvalds clr.l %d0 31781da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 31791da177e4SLinus Torvalds 31801da177e4SLinus Torvalds tst.b %d1 31811da177e4SLinus Torvalds bne.b _L14_2x 31821da177e4SLinus Torvalds bsr.l slog10 # operand is a NORM 31831da177e4SLinus Torvalds bra.b _L14_6x 31841da177e4SLinus Torvalds_L14_2x: 31851da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 31861da177e4SLinus Torvalds bne.b _L14_3x # no 31871da177e4SLinus Torvalds bsr.l t_dz2 # yes 31881da177e4SLinus Torvalds bra.b _L14_6x 31891da177e4SLinus Torvalds_L14_3x: 31901da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 31911da177e4SLinus Torvalds bne.b _L14_4x # no 31921da177e4SLinus Torvalds bsr.l sopr_inf # yes 31931da177e4SLinus Torvalds bra.b _L14_6x 31941da177e4SLinus Torvalds_L14_4x: 31951da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 31961da177e4SLinus Torvalds bne.b _L14_5x # no 31971da177e4SLinus Torvalds bsr.l src_qnan # yes 31981da177e4SLinus Torvalds bra.b _L14_6x 31991da177e4SLinus Torvalds_L14_5x: 32001da177e4SLinus Torvalds bsr.l slog10d # operand is a DENORM 32011da177e4SLinus Torvalds_L14_6x: 32021da177e4SLinus Torvalds 32031da177e4SLinus Torvalds# 32041da177e4SLinus Torvalds# Result is now in FP0 32051da177e4SLinus Torvalds# 32061da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 32071da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 32081da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 32091da177e4SLinus Torvalds unlk %a6 32101da177e4SLinus Torvalds rts 32111da177e4SLinus Torvalds 32121da177e4SLinus Torvalds 32131da177e4SLinus Torvalds######################################################################### 32141da177e4SLinus Torvalds# MONADIC TEMPLATE # 32151da177e4SLinus Torvalds######################################################################### 32161da177e4SLinus Torvalds global _flog2s_ 32171da177e4SLinus Torvalds_flog2s_: 32181da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 32191da177e4SLinus Torvalds 32201da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 32211da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 32221da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 32231da177e4SLinus Torvalds 32241da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 32251da177e4SLinus Torvalds 32261da177e4SLinus Torvalds# 32271da177e4SLinus Torvalds# copy, convert, and tag input argument 32281da177e4SLinus Torvalds# 32291da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 32301da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 32311da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 32321da177e4SLinus Torvalds bsr.l tag # fetch operand type 32331da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 32341da177e4SLinus Torvalds mov.b %d0,%d1 32351da177e4SLinus Torvalds 32361da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 32371da177e4SLinus Torvalds 32381da177e4SLinus Torvalds clr.l %d0 32391da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 32401da177e4SLinus Torvalds 32411da177e4SLinus Torvalds tst.b %d1 32421da177e4SLinus Torvalds bne.b _L15_2s 32431da177e4SLinus Torvalds bsr.l slog2 # operand is a NORM 32441da177e4SLinus Torvalds bra.b _L15_6s 32451da177e4SLinus Torvalds_L15_2s: 32461da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 32471da177e4SLinus Torvalds bne.b _L15_3s # no 32481da177e4SLinus Torvalds bsr.l t_dz2 # yes 32491da177e4SLinus Torvalds bra.b _L15_6s 32501da177e4SLinus Torvalds_L15_3s: 32511da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 32521da177e4SLinus Torvalds bne.b _L15_4s # no 32531da177e4SLinus Torvalds bsr.l sopr_inf # yes 32541da177e4SLinus Torvalds bra.b _L15_6s 32551da177e4SLinus Torvalds_L15_4s: 32561da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 32571da177e4SLinus Torvalds bne.b _L15_5s # no 32581da177e4SLinus Torvalds bsr.l src_qnan # yes 32591da177e4SLinus Torvalds bra.b _L15_6s 32601da177e4SLinus Torvalds_L15_5s: 32611da177e4SLinus Torvalds bsr.l slog2d # operand is a DENORM 32621da177e4SLinus Torvalds_L15_6s: 32631da177e4SLinus Torvalds 32641da177e4SLinus Torvalds# 32651da177e4SLinus Torvalds# Result is now in FP0 32661da177e4SLinus Torvalds# 32671da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 32681da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 32691da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 32701da177e4SLinus Torvalds unlk %a6 32711da177e4SLinus Torvalds rts 32721da177e4SLinus Torvalds 32731da177e4SLinus Torvalds global _flog2d_ 32741da177e4SLinus Torvalds_flog2d_: 32751da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 32761da177e4SLinus Torvalds 32771da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 32781da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 32791da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 32801da177e4SLinus Torvalds 32811da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 32821da177e4SLinus Torvalds 32831da177e4SLinus Torvalds# 32841da177e4SLinus Torvalds# copy, convert, and tag input argument 32851da177e4SLinus Torvalds# 32861da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 32871da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 32881da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 32891da177e4SLinus Torvalds bsr.l tag # fetch operand type 32901da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 32911da177e4SLinus Torvalds mov.b %d0,%d1 32921da177e4SLinus Torvalds 32931da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 32941da177e4SLinus Torvalds 32951da177e4SLinus Torvalds clr.l %d0 32961da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 32971da177e4SLinus Torvalds 32981da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 32991da177e4SLinus Torvalds tst.b %d1 33001da177e4SLinus Torvalds bne.b _L15_2d 33011da177e4SLinus Torvalds bsr.l slog2 # operand is a NORM 33021da177e4SLinus Torvalds bra.b _L15_6d 33031da177e4SLinus Torvalds_L15_2d: 33041da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 33051da177e4SLinus Torvalds bne.b _L15_3d # no 33061da177e4SLinus Torvalds bsr.l t_dz2 # yes 33071da177e4SLinus Torvalds bra.b _L15_6d 33081da177e4SLinus Torvalds_L15_3d: 33091da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 33101da177e4SLinus Torvalds bne.b _L15_4d # no 33111da177e4SLinus Torvalds bsr.l sopr_inf # yes 33121da177e4SLinus Torvalds bra.b _L15_6d 33131da177e4SLinus Torvalds_L15_4d: 33141da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 33151da177e4SLinus Torvalds bne.b _L15_5d # no 33161da177e4SLinus Torvalds bsr.l src_qnan # yes 33171da177e4SLinus Torvalds bra.b _L15_6d 33181da177e4SLinus Torvalds_L15_5d: 33191da177e4SLinus Torvalds bsr.l slog2d # operand is a DENORM 33201da177e4SLinus Torvalds_L15_6d: 33211da177e4SLinus Torvalds 33221da177e4SLinus Torvalds# 33231da177e4SLinus Torvalds# Result is now in FP0 33241da177e4SLinus Torvalds# 33251da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 33261da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 33271da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 33281da177e4SLinus Torvalds unlk %a6 33291da177e4SLinus Torvalds rts 33301da177e4SLinus Torvalds 33311da177e4SLinus Torvalds global _flog2x_ 33321da177e4SLinus Torvalds_flog2x_: 33331da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 33341da177e4SLinus Torvalds 33351da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 33361da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 33371da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 33381da177e4SLinus Torvalds 33391da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 33401da177e4SLinus Torvalds 33411da177e4SLinus Torvalds# 33421da177e4SLinus Torvalds# copy, convert, and tag input argument 33431da177e4SLinus Torvalds# 33441da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 33451da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 33461da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 33471da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 33481da177e4SLinus Torvalds bsr.l tag # fetch operand type 33491da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 33501da177e4SLinus Torvalds mov.b %d0,%d1 33511da177e4SLinus Torvalds 33521da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 33531da177e4SLinus Torvalds 33541da177e4SLinus Torvalds clr.l %d0 33551da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 33561da177e4SLinus Torvalds 33571da177e4SLinus Torvalds tst.b %d1 33581da177e4SLinus Torvalds bne.b _L15_2x 33591da177e4SLinus Torvalds bsr.l slog2 # operand is a NORM 33601da177e4SLinus Torvalds bra.b _L15_6x 33611da177e4SLinus Torvalds_L15_2x: 33621da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 33631da177e4SLinus Torvalds bne.b _L15_3x # no 33641da177e4SLinus Torvalds bsr.l t_dz2 # yes 33651da177e4SLinus Torvalds bra.b _L15_6x 33661da177e4SLinus Torvalds_L15_3x: 33671da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 33681da177e4SLinus Torvalds bne.b _L15_4x # no 33691da177e4SLinus Torvalds bsr.l sopr_inf # yes 33701da177e4SLinus Torvalds bra.b _L15_6x 33711da177e4SLinus Torvalds_L15_4x: 33721da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 33731da177e4SLinus Torvalds bne.b _L15_5x # no 33741da177e4SLinus Torvalds bsr.l src_qnan # yes 33751da177e4SLinus Torvalds bra.b _L15_6x 33761da177e4SLinus Torvalds_L15_5x: 33771da177e4SLinus Torvalds bsr.l slog2d # operand is a DENORM 33781da177e4SLinus Torvalds_L15_6x: 33791da177e4SLinus Torvalds 33801da177e4SLinus Torvalds# 33811da177e4SLinus Torvalds# Result is now in FP0 33821da177e4SLinus Torvalds# 33831da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 33841da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 33851da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 33861da177e4SLinus Torvalds unlk %a6 33871da177e4SLinus Torvalds rts 33881da177e4SLinus Torvalds 33891da177e4SLinus Torvalds 33901da177e4SLinus Torvalds######################################################################### 33911da177e4SLinus Torvalds# MONADIC TEMPLATE # 33921da177e4SLinus Torvalds######################################################################### 33931da177e4SLinus Torvalds global _fcoshs_ 33941da177e4SLinus Torvalds_fcoshs_: 33951da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 33961da177e4SLinus Torvalds 33971da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 33981da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 33991da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 34001da177e4SLinus Torvalds 34011da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 34021da177e4SLinus Torvalds 34031da177e4SLinus Torvalds# 34041da177e4SLinus Torvalds# copy, convert, and tag input argument 34051da177e4SLinus Torvalds# 34061da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 34071da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 34081da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 34091da177e4SLinus Torvalds bsr.l tag # fetch operand type 34101da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 34111da177e4SLinus Torvalds mov.b %d0,%d1 34121da177e4SLinus Torvalds 34131da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 34141da177e4SLinus Torvalds 34151da177e4SLinus Torvalds clr.l %d0 34161da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 34171da177e4SLinus Torvalds 34181da177e4SLinus Torvalds tst.b %d1 34191da177e4SLinus Torvalds bne.b _L16_2s 34201da177e4SLinus Torvalds bsr.l scosh # operand is a NORM 34211da177e4SLinus Torvalds bra.b _L16_6s 34221da177e4SLinus Torvalds_L16_2s: 34231da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 34241da177e4SLinus Torvalds bne.b _L16_3s # no 34251da177e4SLinus Torvalds bsr.l ld_pone # yes 34261da177e4SLinus Torvalds bra.b _L16_6s 34271da177e4SLinus Torvalds_L16_3s: 34281da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 34291da177e4SLinus Torvalds bne.b _L16_4s # no 34301da177e4SLinus Torvalds bsr.l ld_pinf # yes 34311da177e4SLinus Torvalds bra.b _L16_6s 34321da177e4SLinus Torvalds_L16_4s: 34331da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 34341da177e4SLinus Torvalds bne.b _L16_5s # no 34351da177e4SLinus Torvalds bsr.l src_qnan # yes 34361da177e4SLinus Torvalds bra.b _L16_6s 34371da177e4SLinus Torvalds_L16_5s: 34381da177e4SLinus Torvalds bsr.l scoshd # operand is a DENORM 34391da177e4SLinus Torvalds_L16_6s: 34401da177e4SLinus Torvalds 34411da177e4SLinus Torvalds# 34421da177e4SLinus Torvalds# Result is now in FP0 34431da177e4SLinus Torvalds# 34441da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 34451da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 34461da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 34471da177e4SLinus Torvalds unlk %a6 34481da177e4SLinus Torvalds rts 34491da177e4SLinus Torvalds 34501da177e4SLinus Torvalds global _fcoshd_ 34511da177e4SLinus Torvalds_fcoshd_: 34521da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 34531da177e4SLinus Torvalds 34541da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 34551da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 34561da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 34571da177e4SLinus Torvalds 34581da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 34591da177e4SLinus Torvalds 34601da177e4SLinus Torvalds# 34611da177e4SLinus Torvalds# copy, convert, and tag input argument 34621da177e4SLinus Torvalds# 34631da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 34641da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 34651da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 34661da177e4SLinus Torvalds bsr.l tag # fetch operand type 34671da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 34681da177e4SLinus Torvalds mov.b %d0,%d1 34691da177e4SLinus Torvalds 34701da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 34711da177e4SLinus Torvalds 34721da177e4SLinus Torvalds clr.l %d0 34731da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 34741da177e4SLinus Torvalds 34751da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 34761da177e4SLinus Torvalds tst.b %d1 34771da177e4SLinus Torvalds bne.b _L16_2d 34781da177e4SLinus Torvalds bsr.l scosh # operand is a NORM 34791da177e4SLinus Torvalds bra.b _L16_6d 34801da177e4SLinus Torvalds_L16_2d: 34811da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 34821da177e4SLinus Torvalds bne.b _L16_3d # no 34831da177e4SLinus Torvalds bsr.l ld_pone # yes 34841da177e4SLinus Torvalds bra.b _L16_6d 34851da177e4SLinus Torvalds_L16_3d: 34861da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 34871da177e4SLinus Torvalds bne.b _L16_4d # no 34881da177e4SLinus Torvalds bsr.l ld_pinf # yes 34891da177e4SLinus Torvalds bra.b _L16_6d 34901da177e4SLinus Torvalds_L16_4d: 34911da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 34921da177e4SLinus Torvalds bne.b _L16_5d # no 34931da177e4SLinus Torvalds bsr.l src_qnan # yes 34941da177e4SLinus Torvalds bra.b _L16_6d 34951da177e4SLinus Torvalds_L16_5d: 34961da177e4SLinus Torvalds bsr.l scoshd # operand is a DENORM 34971da177e4SLinus Torvalds_L16_6d: 34981da177e4SLinus Torvalds 34991da177e4SLinus Torvalds# 35001da177e4SLinus Torvalds# Result is now in FP0 35011da177e4SLinus Torvalds# 35021da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 35031da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 35041da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 35051da177e4SLinus Torvalds unlk %a6 35061da177e4SLinus Torvalds rts 35071da177e4SLinus Torvalds 35081da177e4SLinus Torvalds global _fcoshx_ 35091da177e4SLinus Torvalds_fcoshx_: 35101da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 35111da177e4SLinus Torvalds 35121da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 35131da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 35141da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 35151da177e4SLinus Torvalds 35161da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 35171da177e4SLinus Torvalds 35181da177e4SLinus Torvalds# 35191da177e4SLinus Torvalds# copy, convert, and tag input argument 35201da177e4SLinus Torvalds# 35211da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 35221da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 35231da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 35241da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 35251da177e4SLinus Torvalds bsr.l tag # fetch operand type 35261da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 35271da177e4SLinus Torvalds mov.b %d0,%d1 35281da177e4SLinus Torvalds 35291da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 35301da177e4SLinus Torvalds 35311da177e4SLinus Torvalds clr.l %d0 35321da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 35331da177e4SLinus Torvalds 35341da177e4SLinus Torvalds tst.b %d1 35351da177e4SLinus Torvalds bne.b _L16_2x 35361da177e4SLinus Torvalds bsr.l scosh # operand is a NORM 35371da177e4SLinus Torvalds bra.b _L16_6x 35381da177e4SLinus Torvalds_L16_2x: 35391da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 35401da177e4SLinus Torvalds bne.b _L16_3x # no 35411da177e4SLinus Torvalds bsr.l ld_pone # yes 35421da177e4SLinus Torvalds bra.b _L16_6x 35431da177e4SLinus Torvalds_L16_3x: 35441da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 35451da177e4SLinus Torvalds bne.b _L16_4x # no 35461da177e4SLinus Torvalds bsr.l ld_pinf # yes 35471da177e4SLinus Torvalds bra.b _L16_6x 35481da177e4SLinus Torvalds_L16_4x: 35491da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 35501da177e4SLinus Torvalds bne.b _L16_5x # no 35511da177e4SLinus Torvalds bsr.l src_qnan # yes 35521da177e4SLinus Torvalds bra.b _L16_6x 35531da177e4SLinus Torvalds_L16_5x: 35541da177e4SLinus Torvalds bsr.l scoshd # operand is a DENORM 35551da177e4SLinus Torvalds_L16_6x: 35561da177e4SLinus Torvalds 35571da177e4SLinus Torvalds# 35581da177e4SLinus Torvalds# Result is now in FP0 35591da177e4SLinus Torvalds# 35601da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 35611da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 35621da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 35631da177e4SLinus Torvalds unlk %a6 35641da177e4SLinus Torvalds rts 35651da177e4SLinus Torvalds 35661da177e4SLinus Torvalds 35671da177e4SLinus Torvalds######################################################################### 35681da177e4SLinus Torvalds# MONADIC TEMPLATE # 35691da177e4SLinus Torvalds######################################################################### 35701da177e4SLinus Torvalds global _facoss_ 35711da177e4SLinus Torvalds_facoss_: 35721da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 35731da177e4SLinus Torvalds 35741da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 35751da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 35761da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 35771da177e4SLinus Torvalds 35781da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 35791da177e4SLinus Torvalds 35801da177e4SLinus Torvalds# 35811da177e4SLinus Torvalds# copy, convert, and tag input argument 35821da177e4SLinus Torvalds# 35831da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 35841da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 35851da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 35861da177e4SLinus Torvalds bsr.l tag # fetch operand type 35871da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 35881da177e4SLinus Torvalds mov.b %d0,%d1 35891da177e4SLinus Torvalds 35901da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 35911da177e4SLinus Torvalds 35921da177e4SLinus Torvalds clr.l %d0 35931da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 35941da177e4SLinus Torvalds 35951da177e4SLinus Torvalds tst.b %d1 35961da177e4SLinus Torvalds bne.b _L17_2s 35971da177e4SLinus Torvalds bsr.l sacos # operand is a NORM 35981da177e4SLinus Torvalds bra.b _L17_6s 35991da177e4SLinus Torvalds_L17_2s: 36001da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 36011da177e4SLinus Torvalds bne.b _L17_3s # no 36021da177e4SLinus Torvalds bsr.l ld_ppi2 # yes 36031da177e4SLinus Torvalds bra.b _L17_6s 36041da177e4SLinus Torvalds_L17_3s: 36051da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 36061da177e4SLinus Torvalds bne.b _L17_4s # no 36071da177e4SLinus Torvalds bsr.l t_operr # yes 36081da177e4SLinus Torvalds bra.b _L17_6s 36091da177e4SLinus Torvalds_L17_4s: 36101da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 36111da177e4SLinus Torvalds bne.b _L17_5s # no 36121da177e4SLinus Torvalds bsr.l src_qnan # yes 36131da177e4SLinus Torvalds bra.b _L17_6s 36141da177e4SLinus Torvalds_L17_5s: 36151da177e4SLinus Torvalds bsr.l sacosd # operand is a DENORM 36161da177e4SLinus Torvalds_L17_6s: 36171da177e4SLinus Torvalds 36181da177e4SLinus Torvalds# 36191da177e4SLinus Torvalds# Result is now in FP0 36201da177e4SLinus Torvalds# 36211da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 36221da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 36231da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 36241da177e4SLinus Torvalds unlk %a6 36251da177e4SLinus Torvalds rts 36261da177e4SLinus Torvalds 36271da177e4SLinus Torvalds global _facosd_ 36281da177e4SLinus Torvalds_facosd_: 36291da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 36301da177e4SLinus Torvalds 36311da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 36321da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 36331da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 36341da177e4SLinus Torvalds 36351da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 36361da177e4SLinus Torvalds 36371da177e4SLinus Torvalds# 36381da177e4SLinus Torvalds# copy, convert, and tag input argument 36391da177e4SLinus Torvalds# 36401da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 36411da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 36421da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 36431da177e4SLinus Torvalds bsr.l tag # fetch operand type 36441da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 36451da177e4SLinus Torvalds mov.b %d0,%d1 36461da177e4SLinus Torvalds 36471da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 36481da177e4SLinus Torvalds 36491da177e4SLinus Torvalds clr.l %d0 36501da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 36511da177e4SLinus Torvalds 36521da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 36531da177e4SLinus Torvalds tst.b %d1 36541da177e4SLinus Torvalds bne.b _L17_2d 36551da177e4SLinus Torvalds bsr.l sacos # operand is a NORM 36561da177e4SLinus Torvalds bra.b _L17_6d 36571da177e4SLinus Torvalds_L17_2d: 36581da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 36591da177e4SLinus Torvalds bne.b _L17_3d # no 36601da177e4SLinus Torvalds bsr.l ld_ppi2 # yes 36611da177e4SLinus Torvalds bra.b _L17_6d 36621da177e4SLinus Torvalds_L17_3d: 36631da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 36641da177e4SLinus Torvalds bne.b _L17_4d # no 36651da177e4SLinus Torvalds bsr.l t_operr # yes 36661da177e4SLinus Torvalds bra.b _L17_6d 36671da177e4SLinus Torvalds_L17_4d: 36681da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 36691da177e4SLinus Torvalds bne.b _L17_5d # no 36701da177e4SLinus Torvalds bsr.l src_qnan # yes 36711da177e4SLinus Torvalds bra.b _L17_6d 36721da177e4SLinus Torvalds_L17_5d: 36731da177e4SLinus Torvalds bsr.l sacosd # operand is a DENORM 36741da177e4SLinus Torvalds_L17_6d: 36751da177e4SLinus Torvalds 36761da177e4SLinus Torvalds# 36771da177e4SLinus Torvalds# Result is now in FP0 36781da177e4SLinus Torvalds# 36791da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 36801da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 36811da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 36821da177e4SLinus Torvalds unlk %a6 36831da177e4SLinus Torvalds rts 36841da177e4SLinus Torvalds 36851da177e4SLinus Torvalds global _facosx_ 36861da177e4SLinus Torvalds_facosx_: 36871da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 36881da177e4SLinus Torvalds 36891da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 36901da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 36911da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 36921da177e4SLinus Torvalds 36931da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 36941da177e4SLinus Torvalds 36951da177e4SLinus Torvalds# 36961da177e4SLinus Torvalds# copy, convert, and tag input argument 36971da177e4SLinus Torvalds# 36981da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 36991da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 37001da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 37011da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 37021da177e4SLinus Torvalds bsr.l tag # fetch operand type 37031da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 37041da177e4SLinus Torvalds mov.b %d0,%d1 37051da177e4SLinus Torvalds 37061da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 37071da177e4SLinus Torvalds 37081da177e4SLinus Torvalds clr.l %d0 37091da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 37101da177e4SLinus Torvalds 37111da177e4SLinus Torvalds tst.b %d1 37121da177e4SLinus Torvalds bne.b _L17_2x 37131da177e4SLinus Torvalds bsr.l sacos # operand is a NORM 37141da177e4SLinus Torvalds bra.b _L17_6x 37151da177e4SLinus Torvalds_L17_2x: 37161da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 37171da177e4SLinus Torvalds bne.b _L17_3x # no 37181da177e4SLinus Torvalds bsr.l ld_ppi2 # yes 37191da177e4SLinus Torvalds bra.b _L17_6x 37201da177e4SLinus Torvalds_L17_3x: 37211da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 37221da177e4SLinus Torvalds bne.b _L17_4x # no 37231da177e4SLinus Torvalds bsr.l t_operr # yes 37241da177e4SLinus Torvalds bra.b _L17_6x 37251da177e4SLinus Torvalds_L17_4x: 37261da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 37271da177e4SLinus Torvalds bne.b _L17_5x # no 37281da177e4SLinus Torvalds bsr.l src_qnan # yes 37291da177e4SLinus Torvalds bra.b _L17_6x 37301da177e4SLinus Torvalds_L17_5x: 37311da177e4SLinus Torvalds bsr.l sacosd # operand is a DENORM 37321da177e4SLinus Torvalds_L17_6x: 37331da177e4SLinus Torvalds 37341da177e4SLinus Torvalds# 37351da177e4SLinus Torvalds# Result is now in FP0 37361da177e4SLinus Torvalds# 37371da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 37381da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 37391da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 37401da177e4SLinus Torvalds unlk %a6 37411da177e4SLinus Torvalds rts 37421da177e4SLinus Torvalds 37431da177e4SLinus Torvalds 37441da177e4SLinus Torvalds######################################################################### 37451da177e4SLinus Torvalds# MONADIC TEMPLATE # 37461da177e4SLinus Torvalds######################################################################### 37471da177e4SLinus Torvalds global _fgetexps_ 37481da177e4SLinus Torvalds_fgetexps_: 37491da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 37501da177e4SLinus Torvalds 37511da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 37521da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 37531da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 37541da177e4SLinus Torvalds 37551da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 37561da177e4SLinus Torvalds 37571da177e4SLinus Torvalds# 37581da177e4SLinus Torvalds# copy, convert, and tag input argument 37591da177e4SLinus Torvalds# 37601da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 37611da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 37621da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 37631da177e4SLinus Torvalds bsr.l tag # fetch operand type 37641da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 37651da177e4SLinus Torvalds mov.b %d0,%d1 37661da177e4SLinus Torvalds 37671da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 37681da177e4SLinus Torvalds 37691da177e4SLinus Torvalds clr.l %d0 37701da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 37711da177e4SLinus Torvalds 37721da177e4SLinus Torvalds tst.b %d1 37731da177e4SLinus Torvalds bne.b _L18_2s 37741da177e4SLinus Torvalds bsr.l sgetexp # operand is a NORM 37751da177e4SLinus Torvalds bra.b _L18_6s 37761da177e4SLinus Torvalds_L18_2s: 37771da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 37781da177e4SLinus Torvalds bne.b _L18_3s # no 37791da177e4SLinus Torvalds bsr.l src_zero # yes 37801da177e4SLinus Torvalds bra.b _L18_6s 37811da177e4SLinus Torvalds_L18_3s: 37821da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 37831da177e4SLinus Torvalds bne.b _L18_4s # no 37841da177e4SLinus Torvalds bsr.l t_operr # yes 37851da177e4SLinus Torvalds bra.b _L18_6s 37861da177e4SLinus Torvalds_L18_4s: 37871da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 37881da177e4SLinus Torvalds bne.b _L18_5s # no 37891da177e4SLinus Torvalds bsr.l src_qnan # yes 37901da177e4SLinus Torvalds bra.b _L18_6s 37911da177e4SLinus Torvalds_L18_5s: 37921da177e4SLinus Torvalds bsr.l sgetexpd # operand is a DENORM 37931da177e4SLinus Torvalds_L18_6s: 37941da177e4SLinus Torvalds 37951da177e4SLinus Torvalds# 37961da177e4SLinus Torvalds# Result is now in FP0 37971da177e4SLinus Torvalds# 37981da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 37991da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 38001da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 38011da177e4SLinus Torvalds unlk %a6 38021da177e4SLinus Torvalds rts 38031da177e4SLinus Torvalds 38041da177e4SLinus Torvalds global _fgetexpd_ 38051da177e4SLinus Torvalds_fgetexpd_: 38061da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 38071da177e4SLinus Torvalds 38081da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 38091da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 38101da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 38111da177e4SLinus Torvalds 38121da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 38131da177e4SLinus Torvalds 38141da177e4SLinus Torvalds# 38151da177e4SLinus Torvalds# copy, convert, and tag input argument 38161da177e4SLinus Torvalds# 38171da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 38181da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 38191da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 38201da177e4SLinus Torvalds bsr.l tag # fetch operand type 38211da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 38221da177e4SLinus Torvalds mov.b %d0,%d1 38231da177e4SLinus Torvalds 38241da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 38251da177e4SLinus Torvalds 38261da177e4SLinus Torvalds clr.l %d0 38271da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 38281da177e4SLinus Torvalds 38291da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 38301da177e4SLinus Torvalds tst.b %d1 38311da177e4SLinus Torvalds bne.b _L18_2d 38321da177e4SLinus Torvalds bsr.l sgetexp # operand is a NORM 38331da177e4SLinus Torvalds bra.b _L18_6d 38341da177e4SLinus Torvalds_L18_2d: 38351da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 38361da177e4SLinus Torvalds bne.b _L18_3d # no 38371da177e4SLinus Torvalds bsr.l src_zero # yes 38381da177e4SLinus Torvalds bra.b _L18_6d 38391da177e4SLinus Torvalds_L18_3d: 38401da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 38411da177e4SLinus Torvalds bne.b _L18_4d # no 38421da177e4SLinus Torvalds bsr.l t_operr # yes 38431da177e4SLinus Torvalds bra.b _L18_6d 38441da177e4SLinus Torvalds_L18_4d: 38451da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 38461da177e4SLinus Torvalds bne.b _L18_5d # no 38471da177e4SLinus Torvalds bsr.l src_qnan # yes 38481da177e4SLinus Torvalds bra.b _L18_6d 38491da177e4SLinus Torvalds_L18_5d: 38501da177e4SLinus Torvalds bsr.l sgetexpd # operand is a DENORM 38511da177e4SLinus Torvalds_L18_6d: 38521da177e4SLinus Torvalds 38531da177e4SLinus Torvalds# 38541da177e4SLinus Torvalds# Result is now in FP0 38551da177e4SLinus Torvalds# 38561da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 38571da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 38581da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 38591da177e4SLinus Torvalds unlk %a6 38601da177e4SLinus Torvalds rts 38611da177e4SLinus Torvalds 38621da177e4SLinus Torvalds global _fgetexpx_ 38631da177e4SLinus Torvalds_fgetexpx_: 38641da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 38651da177e4SLinus Torvalds 38661da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 38671da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 38681da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 38691da177e4SLinus Torvalds 38701da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 38711da177e4SLinus Torvalds 38721da177e4SLinus Torvalds# 38731da177e4SLinus Torvalds# copy, convert, and tag input argument 38741da177e4SLinus Torvalds# 38751da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 38761da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 38771da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 38781da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 38791da177e4SLinus Torvalds bsr.l tag # fetch operand type 38801da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 38811da177e4SLinus Torvalds mov.b %d0,%d1 38821da177e4SLinus Torvalds 38831da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 38841da177e4SLinus Torvalds 38851da177e4SLinus Torvalds clr.l %d0 38861da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 38871da177e4SLinus Torvalds 38881da177e4SLinus Torvalds tst.b %d1 38891da177e4SLinus Torvalds bne.b _L18_2x 38901da177e4SLinus Torvalds bsr.l sgetexp # operand is a NORM 38911da177e4SLinus Torvalds bra.b _L18_6x 38921da177e4SLinus Torvalds_L18_2x: 38931da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 38941da177e4SLinus Torvalds bne.b _L18_3x # no 38951da177e4SLinus Torvalds bsr.l src_zero # yes 38961da177e4SLinus Torvalds bra.b _L18_6x 38971da177e4SLinus Torvalds_L18_3x: 38981da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 38991da177e4SLinus Torvalds bne.b _L18_4x # no 39001da177e4SLinus Torvalds bsr.l t_operr # yes 39011da177e4SLinus Torvalds bra.b _L18_6x 39021da177e4SLinus Torvalds_L18_4x: 39031da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 39041da177e4SLinus Torvalds bne.b _L18_5x # no 39051da177e4SLinus Torvalds bsr.l src_qnan # yes 39061da177e4SLinus Torvalds bra.b _L18_6x 39071da177e4SLinus Torvalds_L18_5x: 39081da177e4SLinus Torvalds bsr.l sgetexpd # operand is a DENORM 39091da177e4SLinus Torvalds_L18_6x: 39101da177e4SLinus Torvalds 39111da177e4SLinus Torvalds# 39121da177e4SLinus Torvalds# Result is now in FP0 39131da177e4SLinus Torvalds# 39141da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 39151da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 39161da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 39171da177e4SLinus Torvalds unlk %a6 39181da177e4SLinus Torvalds rts 39191da177e4SLinus Torvalds 39201da177e4SLinus Torvalds 39211da177e4SLinus Torvalds######################################################################### 39221da177e4SLinus Torvalds# MONADIC TEMPLATE # 39231da177e4SLinus Torvalds######################################################################### 39241da177e4SLinus Torvalds global _fgetmans_ 39251da177e4SLinus Torvalds_fgetmans_: 39261da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 39271da177e4SLinus Torvalds 39281da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 39291da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 39301da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 39311da177e4SLinus Torvalds 39321da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 39331da177e4SLinus Torvalds 39341da177e4SLinus Torvalds# 39351da177e4SLinus Torvalds# copy, convert, and tag input argument 39361da177e4SLinus Torvalds# 39371da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 39381da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 39391da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 39401da177e4SLinus Torvalds bsr.l tag # fetch operand type 39411da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 39421da177e4SLinus Torvalds mov.b %d0,%d1 39431da177e4SLinus Torvalds 39441da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 39451da177e4SLinus Torvalds 39461da177e4SLinus Torvalds clr.l %d0 39471da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 39481da177e4SLinus Torvalds 39491da177e4SLinus Torvalds tst.b %d1 39501da177e4SLinus Torvalds bne.b _L19_2s 39511da177e4SLinus Torvalds bsr.l sgetman # operand is a NORM 39521da177e4SLinus Torvalds bra.b _L19_6s 39531da177e4SLinus Torvalds_L19_2s: 39541da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 39551da177e4SLinus Torvalds bne.b _L19_3s # no 39561da177e4SLinus Torvalds bsr.l src_zero # yes 39571da177e4SLinus Torvalds bra.b _L19_6s 39581da177e4SLinus Torvalds_L19_3s: 39591da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 39601da177e4SLinus Torvalds bne.b _L19_4s # no 39611da177e4SLinus Torvalds bsr.l t_operr # yes 39621da177e4SLinus Torvalds bra.b _L19_6s 39631da177e4SLinus Torvalds_L19_4s: 39641da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 39651da177e4SLinus Torvalds bne.b _L19_5s # no 39661da177e4SLinus Torvalds bsr.l src_qnan # yes 39671da177e4SLinus Torvalds bra.b _L19_6s 39681da177e4SLinus Torvalds_L19_5s: 39691da177e4SLinus Torvalds bsr.l sgetmand # operand is a DENORM 39701da177e4SLinus Torvalds_L19_6s: 39711da177e4SLinus Torvalds 39721da177e4SLinus Torvalds# 39731da177e4SLinus Torvalds# Result is now in FP0 39741da177e4SLinus Torvalds# 39751da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 39761da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 39771da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 39781da177e4SLinus Torvalds unlk %a6 39791da177e4SLinus Torvalds rts 39801da177e4SLinus Torvalds 39811da177e4SLinus Torvalds global _fgetmand_ 39821da177e4SLinus Torvalds_fgetmand_: 39831da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 39841da177e4SLinus Torvalds 39851da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 39861da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 39871da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 39881da177e4SLinus Torvalds 39891da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 39901da177e4SLinus Torvalds 39911da177e4SLinus Torvalds# 39921da177e4SLinus Torvalds# copy, convert, and tag input argument 39931da177e4SLinus Torvalds# 39941da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 39951da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 39961da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 39971da177e4SLinus Torvalds bsr.l tag # fetch operand type 39981da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 39991da177e4SLinus Torvalds mov.b %d0,%d1 40001da177e4SLinus Torvalds 40011da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 40021da177e4SLinus Torvalds 40031da177e4SLinus Torvalds clr.l %d0 40041da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 40051da177e4SLinus Torvalds 40061da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 40071da177e4SLinus Torvalds tst.b %d1 40081da177e4SLinus Torvalds bne.b _L19_2d 40091da177e4SLinus Torvalds bsr.l sgetman # operand is a NORM 40101da177e4SLinus Torvalds bra.b _L19_6d 40111da177e4SLinus Torvalds_L19_2d: 40121da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 40131da177e4SLinus Torvalds bne.b _L19_3d # no 40141da177e4SLinus Torvalds bsr.l src_zero # yes 40151da177e4SLinus Torvalds bra.b _L19_6d 40161da177e4SLinus Torvalds_L19_3d: 40171da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 40181da177e4SLinus Torvalds bne.b _L19_4d # no 40191da177e4SLinus Torvalds bsr.l t_operr # yes 40201da177e4SLinus Torvalds bra.b _L19_6d 40211da177e4SLinus Torvalds_L19_4d: 40221da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 40231da177e4SLinus Torvalds bne.b _L19_5d # no 40241da177e4SLinus Torvalds bsr.l src_qnan # yes 40251da177e4SLinus Torvalds bra.b _L19_6d 40261da177e4SLinus Torvalds_L19_5d: 40271da177e4SLinus Torvalds bsr.l sgetmand # operand is a DENORM 40281da177e4SLinus Torvalds_L19_6d: 40291da177e4SLinus Torvalds 40301da177e4SLinus Torvalds# 40311da177e4SLinus Torvalds# Result is now in FP0 40321da177e4SLinus Torvalds# 40331da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 40341da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 40351da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 40361da177e4SLinus Torvalds unlk %a6 40371da177e4SLinus Torvalds rts 40381da177e4SLinus Torvalds 40391da177e4SLinus Torvalds global _fgetmanx_ 40401da177e4SLinus Torvalds_fgetmanx_: 40411da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 40421da177e4SLinus Torvalds 40431da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 40441da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 40451da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 40461da177e4SLinus Torvalds 40471da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 40481da177e4SLinus Torvalds 40491da177e4SLinus Torvalds# 40501da177e4SLinus Torvalds# copy, convert, and tag input argument 40511da177e4SLinus Torvalds# 40521da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 40531da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 40541da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 40551da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 40561da177e4SLinus Torvalds bsr.l tag # fetch operand type 40571da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 40581da177e4SLinus Torvalds mov.b %d0,%d1 40591da177e4SLinus Torvalds 40601da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 40611da177e4SLinus Torvalds 40621da177e4SLinus Torvalds clr.l %d0 40631da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 40641da177e4SLinus Torvalds 40651da177e4SLinus Torvalds tst.b %d1 40661da177e4SLinus Torvalds bne.b _L19_2x 40671da177e4SLinus Torvalds bsr.l sgetman # operand is a NORM 40681da177e4SLinus Torvalds bra.b _L19_6x 40691da177e4SLinus Torvalds_L19_2x: 40701da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 40711da177e4SLinus Torvalds bne.b _L19_3x # no 40721da177e4SLinus Torvalds bsr.l src_zero # yes 40731da177e4SLinus Torvalds bra.b _L19_6x 40741da177e4SLinus Torvalds_L19_3x: 40751da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 40761da177e4SLinus Torvalds bne.b _L19_4x # no 40771da177e4SLinus Torvalds bsr.l t_operr # yes 40781da177e4SLinus Torvalds bra.b _L19_6x 40791da177e4SLinus Torvalds_L19_4x: 40801da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 40811da177e4SLinus Torvalds bne.b _L19_5x # no 40821da177e4SLinus Torvalds bsr.l src_qnan # yes 40831da177e4SLinus Torvalds bra.b _L19_6x 40841da177e4SLinus Torvalds_L19_5x: 40851da177e4SLinus Torvalds bsr.l sgetmand # operand is a DENORM 40861da177e4SLinus Torvalds_L19_6x: 40871da177e4SLinus Torvalds 40881da177e4SLinus Torvalds# 40891da177e4SLinus Torvalds# Result is now in FP0 40901da177e4SLinus Torvalds# 40911da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 40921da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 40931da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 40941da177e4SLinus Torvalds unlk %a6 40951da177e4SLinus Torvalds rts 40961da177e4SLinus Torvalds 40971da177e4SLinus Torvalds 40981da177e4SLinus Torvalds######################################################################### 40991da177e4SLinus Torvalds# MONADIC TEMPLATE # 41001da177e4SLinus Torvalds######################################################################### 41011da177e4SLinus Torvalds global _fsincoss_ 41021da177e4SLinus Torvalds_fsincoss_: 41031da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 41041da177e4SLinus Torvalds 41051da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 41061da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 41071da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 41081da177e4SLinus Torvalds 41091da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 41101da177e4SLinus Torvalds 41111da177e4SLinus Torvalds# 41121da177e4SLinus Torvalds# copy, convert, and tag input argument 41131da177e4SLinus Torvalds# 41141da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl input 41151da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 41161da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 41171da177e4SLinus Torvalds bsr.l tag # fetch operand type 41181da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 41191da177e4SLinus Torvalds mov.b %d0,%d1 41201da177e4SLinus Torvalds 41211da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 41221da177e4SLinus Torvalds 41231da177e4SLinus Torvalds clr.l %d0 41241da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 41251da177e4SLinus Torvalds 41261da177e4SLinus Torvalds tst.b %d1 41271da177e4SLinus Torvalds bne.b _L20_2s 41281da177e4SLinus Torvalds bsr.l ssincos # operand is a NORM 41291da177e4SLinus Torvalds bra.b _L20_6s 41301da177e4SLinus Torvalds_L20_2s: 41311da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 41321da177e4SLinus Torvalds bne.b _L20_3s # no 41331da177e4SLinus Torvalds bsr.l ssincosz # yes 41341da177e4SLinus Torvalds bra.b _L20_6s 41351da177e4SLinus Torvalds_L20_3s: 41361da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 41371da177e4SLinus Torvalds bne.b _L20_4s # no 41381da177e4SLinus Torvalds bsr.l ssincosi # yes 41391da177e4SLinus Torvalds bra.b _L20_6s 41401da177e4SLinus Torvalds_L20_4s: 41411da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 41421da177e4SLinus Torvalds bne.b _L20_5s # no 41431da177e4SLinus Torvalds bsr.l ssincosqnan # yes 41441da177e4SLinus Torvalds bra.b _L20_6s 41451da177e4SLinus Torvalds_L20_5s: 41461da177e4SLinus Torvalds bsr.l ssincosd # operand is a DENORM 41471da177e4SLinus Torvalds_L20_6s: 41481da177e4SLinus Torvalds 41491da177e4SLinus Torvalds# 41501da177e4SLinus Torvalds# Result is now in FP0 41511da177e4SLinus Torvalds# 41521da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 41531da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 41541da177e4SLinus Torvalds fmovm.x &0x03,-(%sp) # store off fp0/fp1 41551da177e4SLinus Torvalds fmovm.x (%sp)+,&0x40 # fp0 now in fp1 41561da177e4SLinus Torvalds fmovm.x (%sp)+,&0x80 # fp1 now in fp0 41571da177e4SLinus Torvalds unlk %a6 41581da177e4SLinus Torvalds rts 41591da177e4SLinus Torvalds 41601da177e4SLinus Torvalds global _fsincosd_ 41611da177e4SLinus Torvalds_fsincosd_: 41621da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 41631da177e4SLinus Torvalds 41641da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 41651da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 41661da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 41671da177e4SLinus Torvalds 41681da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 41691da177e4SLinus Torvalds 41701da177e4SLinus Torvalds# 41711da177e4SLinus Torvalds# copy, convert, and tag input argument 41721da177e4SLinus Torvalds# 41731da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl input 41741da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 41751da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 41761da177e4SLinus Torvalds bsr.l tag # fetch operand type 41771da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 41781da177e4SLinus Torvalds mov.b %d0,%d1 41791da177e4SLinus Torvalds 41801da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 41811da177e4SLinus Torvalds 41821da177e4SLinus Torvalds clr.l %d0 41831da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 41841da177e4SLinus Torvalds 41851da177e4SLinus Torvalds mov.b %d1,STAG(%a6) 41861da177e4SLinus Torvalds tst.b %d1 41871da177e4SLinus Torvalds bne.b _L20_2d 41881da177e4SLinus Torvalds bsr.l ssincos # operand is a NORM 41891da177e4SLinus Torvalds bra.b _L20_6d 41901da177e4SLinus Torvalds_L20_2d: 41911da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 41921da177e4SLinus Torvalds bne.b _L20_3d # no 41931da177e4SLinus Torvalds bsr.l ssincosz # yes 41941da177e4SLinus Torvalds bra.b _L20_6d 41951da177e4SLinus Torvalds_L20_3d: 41961da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 41971da177e4SLinus Torvalds bne.b _L20_4d # no 41981da177e4SLinus Torvalds bsr.l ssincosi # yes 41991da177e4SLinus Torvalds bra.b _L20_6d 42001da177e4SLinus Torvalds_L20_4d: 42011da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 42021da177e4SLinus Torvalds bne.b _L20_5d # no 42031da177e4SLinus Torvalds bsr.l ssincosqnan # yes 42041da177e4SLinus Torvalds bra.b _L20_6d 42051da177e4SLinus Torvalds_L20_5d: 42061da177e4SLinus Torvalds bsr.l ssincosd # operand is a DENORM 42071da177e4SLinus Torvalds_L20_6d: 42081da177e4SLinus Torvalds 42091da177e4SLinus Torvalds# 42101da177e4SLinus Torvalds# Result is now in FP0 42111da177e4SLinus Torvalds# 42121da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 42131da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 42141da177e4SLinus Torvalds fmovm.x &0x03,-(%sp) # store off fp0/fp1 42151da177e4SLinus Torvalds fmovm.x (%sp)+,&0x40 # fp0 now in fp1 42161da177e4SLinus Torvalds fmovm.x (%sp)+,&0x80 # fp1 now in fp0 42171da177e4SLinus Torvalds unlk %a6 42181da177e4SLinus Torvalds rts 42191da177e4SLinus Torvalds 42201da177e4SLinus Torvalds global _fsincosx_ 42211da177e4SLinus Torvalds_fsincosx_: 42221da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 42231da177e4SLinus Torvalds 42241da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 42251da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 42261da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 42271da177e4SLinus Torvalds 42281da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 42291da177e4SLinus Torvalds 42301da177e4SLinus Torvalds# 42311da177e4SLinus Torvalds# copy, convert, and tag input argument 42321da177e4SLinus Torvalds# 42331da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 42341da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 42351da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 42361da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 42371da177e4SLinus Torvalds bsr.l tag # fetch operand type 42381da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 42391da177e4SLinus Torvalds mov.b %d0,%d1 42401da177e4SLinus Torvalds 42411da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 42421da177e4SLinus Torvalds 42431da177e4SLinus Torvalds clr.l %d0 42441da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 42451da177e4SLinus Torvalds 42461da177e4SLinus Torvalds tst.b %d1 42471da177e4SLinus Torvalds bne.b _L20_2x 42481da177e4SLinus Torvalds bsr.l ssincos # operand is a NORM 42491da177e4SLinus Torvalds bra.b _L20_6x 42501da177e4SLinus Torvalds_L20_2x: 42511da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 42521da177e4SLinus Torvalds bne.b _L20_3x # no 42531da177e4SLinus Torvalds bsr.l ssincosz # yes 42541da177e4SLinus Torvalds bra.b _L20_6x 42551da177e4SLinus Torvalds_L20_3x: 42561da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 42571da177e4SLinus Torvalds bne.b _L20_4x # no 42581da177e4SLinus Torvalds bsr.l ssincosi # yes 42591da177e4SLinus Torvalds bra.b _L20_6x 42601da177e4SLinus Torvalds_L20_4x: 42611da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 42621da177e4SLinus Torvalds bne.b _L20_5x # no 42631da177e4SLinus Torvalds bsr.l ssincosqnan # yes 42641da177e4SLinus Torvalds bra.b _L20_6x 42651da177e4SLinus Torvalds_L20_5x: 42661da177e4SLinus Torvalds bsr.l ssincosd # operand is a DENORM 42671da177e4SLinus Torvalds_L20_6x: 42681da177e4SLinus Torvalds 42691da177e4SLinus Torvalds# 42701da177e4SLinus Torvalds# Result is now in FP0 42711da177e4SLinus Torvalds# 42721da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 42731da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 42741da177e4SLinus Torvalds fmovm.x &0x03,-(%sp) # store off fp0/fp1 42751da177e4SLinus Torvalds fmovm.x (%sp)+,&0x40 # fp0 now in fp1 42761da177e4SLinus Torvalds fmovm.x (%sp)+,&0x80 # fp1 now in fp0 42771da177e4SLinus Torvalds unlk %a6 42781da177e4SLinus Torvalds rts 42791da177e4SLinus Torvalds 42801da177e4SLinus Torvalds 42811da177e4SLinus Torvalds######################################################################### 42821da177e4SLinus Torvalds# DYADIC TEMPLATE # 42831da177e4SLinus Torvalds######################################################################### 42841da177e4SLinus Torvalds global _frems_ 42851da177e4SLinus Torvalds_frems_: 42861da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 42871da177e4SLinus Torvalds 42881da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 42891da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 42901da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 42911da177e4SLinus Torvalds 42921da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 42931da177e4SLinus Torvalds 42941da177e4SLinus Torvalds# 42951da177e4SLinus Torvalds# copy, convert, and tag input argument 42961da177e4SLinus Torvalds# 42971da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl dst 42981da177e4SLinus Torvalds fmov.x %fp0,FP_DST(%a6) 42991da177e4SLinus Torvalds lea FP_DST(%a6),%a0 43001da177e4SLinus Torvalds bsr.l tag # fetch operand type 43011da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 43021da177e4SLinus Torvalds 43031da177e4SLinus Torvalds fmov.s 0xc(%a6),%fp0 # load sgl src 43041da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 43051da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 43061da177e4SLinus Torvalds bsr.l tag # fetch operand type 43071da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 43081da177e4SLinus Torvalds mov.l %d0,%d1 43091da177e4SLinus Torvalds 43101da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 43111da177e4SLinus Torvalds 43121da177e4SLinus Torvalds clr.l %d0 43131da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 43141da177e4SLinus Torvalds 43151da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 43161da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 43171da177e4SLinus Torvalds 43181da177e4SLinus Torvalds tst.b %d1 43191da177e4SLinus Torvalds bne.b _L21_2s 43201da177e4SLinus Torvalds bsr.l srem_snorm # operand is a NORM 43211da177e4SLinus Torvalds bra.b _L21_6s 43221da177e4SLinus Torvalds_L21_2s: 43231da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 43241da177e4SLinus Torvalds bne.b _L21_3s # no 43251da177e4SLinus Torvalds bsr.l srem_szero # yes 43261da177e4SLinus Torvalds bra.b _L21_6s 43271da177e4SLinus Torvalds_L21_3s: 43281da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 43291da177e4SLinus Torvalds bne.b _L21_4s # no 43301da177e4SLinus Torvalds bsr.l srem_sinf # yes 43311da177e4SLinus Torvalds bra.b _L21_6s 43321da177e4SLinus Torvalds_L21_4s: 43331da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 43341da177e4SLinus Torvalds bne.b _L21_5s # no 43351da177e4SLinus Torvalds bsr.l sop_sqnan # yes 43361da177e4SLinus Torvalds bra.b _L21_6s 43371da177e4SLinus Torvalds_L21_5s: 43381da177e4SLinus Torvalds bsr.l srem_sdnrm # operand is a DENORM 43391da177e4SLinus Torvalds_L21_6s: 43401da177e4SLinus Torvalds 43411da177e4SLinus Torvalds# 43421da177e4SLinus Torvalds# Result is now in FP0 43431da177e4SLinus Torvalds# 43441da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 43451da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 43461da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 43471da177e4SLinus Torvalds unlk %a6 43481da177e4SLinus Torvalds rts 43491da177e4SLinus Torvalds 43501da177e4SLinus Torvalds global _fremd_ 43511da177e4SLinus Torvalds_fremd_: 43521da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 43531da177e4SLinus Torvalds 43541da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 43551da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 43561da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 43571da177e4SLinus Torvalds 43581da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 43591da177e4SLinus Torvalds 43601da177e4SLinus Torvalds# 43611da177e4SLinus Torvalds# copy, convert, and tag input argument 43621da177e4SLinus Torvalds# 43631da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl dst 43641da177e4SLinus Torvalds fmov.x %fp0,FP_DST(%a6) 43651da177e4SLinus Torvalds lea FP_DST(%a6),%a0 43661da177e4SLinus Torvalds bsr.l tag # fetch operand type 43671da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 43681da177e4SLinus Torvalds 43691da177e4SLinus Torvalds fmov.d 0x10(%a6),%fp0 # load dbl src 43701da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 43711da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 43721da177e4SLinus Torvalds bsr.l tag # fetch operand type 43731da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 43741da177e4SLinus Torvalds mov.l %d0,%d1 43751da177e4SLinus Torvalds 43761da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 43771da177e4SLinus Torvalds 43781da177e4SLinus Torvalds clr.l %d0 43791da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 43801da177e4SLinus Torvalds 43811da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 43821da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 43831da177e4SLinus Torvalds 43841da177e4SLinus Torvalds tst.b %d1 43851da177e4SLinus Torvalds bne.b _L21_2d 43861da177e4SLinus Torvalds bsr.l srem_snorm # operand is a NORM 43871da177e4SLinus Torvalds bra.b _L21_6d 43881da177e4SLinus Torvalds_L21_2d: 43891da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 43901da177e4SLinus Torvalds bne.b _L21_3d # no 43911da177e4SLinus Torvalds bsr.l srem_szero # yes 43921da177e4SLinus Torvalds bra.b _L21_6d 43931da177e4SLinus Torvalds_L21_3d: 43941da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 43951da177e4SLinus Torvalds bne.b _L21_4d # no 43961da177e4SLinus Torvalds bsr.l srem_sinf # yes 43971da177e4SLinus Torvalds bra.b _L21_6d 43981da177e4SLinus Torvalds_L21_4d: 43991da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 44001da177e4SLinus Torvalds bne.b _L21_5d # no 44011da177e4SLinus Torvalds bsr.l sop_sqnan # yes 44021da177e4SLinus Torvalds bra.b _L21_6d 44031da177e4SLinus Torvalds_L21_5d: 44041da177e4SLinus Torvalds bsr.l srem_sdnrm # operand is a DENORM 44051da177e4SLinus Torvalds_L21_6d: 44061da177e4SLinus Torvalds 44071da177e4SLinus Torvalds# 44081da177e4SLinus Torvalds# Result is now in FP0 44091da177e4SLinus Torvalds# 44101da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 44111da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 44121da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 44131da177e4SLinus Torvalds unlk %a6 44141da177e4SLinus Torvalds rts 44151da177e4SLinus Torvalds 44161da177e4SLinus Torvalds global _fremx_ 44171da177e4SLinus Torvalds_fremx_: 44181da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 44191da177e4SLinus Torvalds 44201da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 44211da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 44221da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 44231da177e4SLinus Torvalds 44241da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 44251da177e4SLinus Torvalds 44261da177e4SLinus Torvalds# 44271da177e4SLinus Torvalds# copy, convert, and tag input argument 44281da177e4SLinus Torvalds# 44291da177e4SLinus Torvalds lea FP_DST(%a6),%a0 44301da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 44311da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 44321da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 44331da177e4SLinus Torvalds bsr.l tag # fetch operand type 44341da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 44351da177e4SLinus Torvalds 44361da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 44371da177e4SLinus Torvalds mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 44381da177e4SLinus Torvalds mov.l 0x14+0x4(%a6),0x4(%a0) 44391da177e4SLinus Torvalds mov.l 0x14+0x8(%a6),0x8(%a0) 44401da177e4SLinus Torvalds bsr.l tag # fetch operand type 44411da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 44421da177e4SLinus Torvalds mov.l %d0,%d1 44431da177e4SLinus Torvalds 44441da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 44451da177e4SLinus Torvalds 44461da177e4SLinus Torvalds clr.l %d0 44471da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 44481da177e4SLinus Torvalds 44491da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 44501da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 44511da177e4SLinus Torvalds 44521da177e4SLinus Torvalds tst.b %d1 44531da177e4SLinus Torvalds bne.b _L21_2x 44541da177e4SLinus Torvalds bsr.l srem_snorm # operand is a NORM 44551da177e4SLinus Torvalds bra.b _L21_6x 44561da177e4SLinus Torvalds_L21_2x: 44571da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 44581da177e4SLinus Torvalds bne.b _L21_3x # no 44591da177e4SLinus Torvalds bsr.l srem_szero # yes 44601da177e4SLinus Torvalds bra.b _L21_6x 44611da177e4SLinus Torvalds_L21_3x: 44621da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 44631da177e4SLinus Torvalds bne.b _L21_4x # no 44641da177e4SLinus Torvalds bsr.l srem_sinf # yes 44651da177e4SLinus Torvalds bra.b _L21_6x 44661da177e4SLinus Torvalds_L21_4x: 44671da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 44681da177e4SLinus Torvalds bne.b _L21_5x # no 44691da177e4SLinus Torvalds bsr.l sop_sqnan # yes 44701da177e4SLinus Torvalds bra.b _L21_6x 44711da177e4SLinus Torvalds_L21_5x: 44721da177e4SLinus Torvalds bsr.l srem_sdnrm # operand is a DENORM 44731da177e4SLinus Torvalds_L21_6x: 44741da177e4SLinus Torvalds 44751da177e4SLinus Torvalds# 44761da177e4SLinus Torvalds# Result is now in FP0 44771da177e4SLinus Torvalds# 44781da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 44791da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 44801da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 44811da177e4SLinus Torvalds unlk %a6 44821da177e4SLinus Torvalds rts 44831da177e4SLinus Torvalds 44841da177e4SLinus Torvalds 44851da177e4SLinus Torvalds######################################################################### 44861da177e4SLinus Torvalds# DYADIC TEMPLATE # 44871da177e4SLinus Torvalds######################################################################### 44881da177e4SLinus Torvalds global _fmods_ 44891da177e4SLinus Torvalds_fmods_: 44901da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 44911da177e4SLinus Torvalds 44921da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 44931da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 44941da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 44951da177e4SLinus Torvalds 44961da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 44971da177e4SLinus Torvalds 44981da177e4SLinus Torvalds# 44991da177e4SLinus Torvalds# copy, convert, and tag input argument 45001da177e4SLinus Torvalds# 45011da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl dst 45021da177e4SLinus Torvalds fmov.x %fp0,FP_DST(%a6) 45031da177e4SLinus Torvalds lea FP_DST(%a6),%a0 45041da177e4SLinus Torvalds bsr.l tag # fetch operand type 45051da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 45061da177e4SLinus Torvalds 45071da177e4SLinus Torvalds fmov.s 0xc(%a6),%fp0 # load sgl src 45081da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 45091da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 45101da177e4SLinus Torvalds bsr.l tag # fetch operand type 45111da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 45121da177e4SLinus Torvalds mov.l %d0,%d1 45131da177e4SLinus Torvalds 45141da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 45151da177e4SLinus Torvalds 45161da177e4SLinus Torvalds clr.l %d0 45171da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 45181da177e4SLinus Torvalds 45191da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 45201da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 45211da177e4SLinus Torvalds 45221da177e4SLinus Torvalds tst.b %d1 45231da177e4SLinus Torvalds bne.b _L22_2s 45241da177e4SLinus Torvalds bsr.l smod_snorm # operand is a NORM 45251da177e4SLinus Torvalds bra.b _L22_6s 45261da177e4SLinus Torvalds_L22_2s: 45271da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 45281da177e4SLinus Torvalds bne.b _L22_3s # no 45291da177e4SLinus Torvalds bsr.l smod_szero # yes 45301da177e4SLinus Torvalds bra.b _L22_6s 45311da177e4SLinus Torvalds_L22_3s: 45321da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 45331da177e4SLinus Torvalds bne.b _L22_4s # no 45341da177e4SLinus Torvalds bsr.l smod_sinf # yes 45351da177e4SLinus Torvalds bra.b _L22_6s 45361da177e4SLinus Torvalds_L22_4s: 45371da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 45381da177e4SLinus Torvalds bne.b _L22_5s # no 45391da177e4SLinus Torvalds bsr.l sop_sqnan # yes 45401da177e4SLinus Torvalds bra.b _L22_6s 45411da177e4SLinus Torvalds_L22_5s: 45421da177e4SLinus Torvalds bsr.l smod_sdnrm # operand is a DENORM 45431da177e4SLinus Torvalds_L22_6s: 45441da177e4SLinus Torvalds 45451da177e4SLinus Torvalds# 45461da177e4SLinus Torvalds# Result is now in FP0 45471da177e4SLinus Torvalds# 45481da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 45491da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 45501da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 45511da177e4SLinus Torvalds unlk %a6 45521da177e4SLinus Torvalds rts 45531da177e4SLinus Torvalds 45541da177e4SLinus Torvalds global _fmodd_ 45551da177e4SLinus Torvalds_fmodd_: 45561da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 45571da177e4SLinus Torvalds 45581da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 45591da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 45601da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 45611da177e4SLinus Torvalds 45621da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 45631da177e4SLinus Torvalds 45641da177e4SLinus Torvalds# 45651da177e4SLinus Torvalds# copy, convert, and tag input argument 45661da177e4SLinus Torvalds# 45671da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl dst 45681da177e4SLinus Torvalds fmov.x %fp0,FP_DST(%a6) 45691da177e4SLinus Torvalds lea FP_DST(%a6),%a0 45701da177e4SLinus Torvalds bsr.l tag # fetch operand type 45711da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 45721da177e4SLinus Torvalds 45731da177e4SLinus Torvalds fmov.d 0x10(%a6),%fp0 # load dbl src 45741da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 45751da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 45761da177e4SLinus Torvalds bsr.l tag # fetch operand type 45771da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 45781da177e4SLinus Torvalds mov.l %d0,%d1 45791da177e4SLinus Torvalds 45801da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 45811da177e4SLinus Torvalds 45821da177e4SLinus Torvalds clr.l %d0 45831da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 45841da177e4SLinus Torvalds 45851da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 45861da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 45871da177e4SLinus Torvalds 45881da177e4SLinus Torvalds tst.b %d1 45891da177e4SLinus Torvalds bne.b _L22_2d 45901da177e4SLinus Torvalds bsr.l smod_snorm # operand is a NORM 45911da177e4SLinus Torvalds bra.b _L22_6d 45921da177e4SLinus Torvalds_L22_2d: 45931da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 45941da177e4SLinus Torvalds bne.b _L22_3d # no 45951da177e4SLinus Torvalds bsr.l smod_szero # yes 45961da177e4SLinus Torvalds bra.b _L22_6d 45971da177e4SLinus Torvalds_L22_3d: 45981da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 45991da177e4SLinus Torvalds bne.b _L22_4d # no 46001da177e4SLinus Torvalds bsr.l smod_sinf # yes 46011da177e4SLinus Torvalds bra.b _L22_6d 46021da177e4SLinus Torvalds_L22_4d: 46031da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 46041da177e4SLinus Torvalds bne.b _L22_5d # no 46051da177e4SLinus Torvalds bsr.l sop_sqnan # yes 46061da177e4SLinus Torvalds bra.b _L22_6d 46071da177e4SLinus Torvalds_L22_5d: 46081da177e4SLinus Torvalds bsr.l smod_sdnrm # operand is a DENORM 46091da177e4SLinus Torvalds_L22_6d: 46101da177e4SLinus Torvalds 46111da177e4SLinus Torvalds# 46121da177e4SLinus Torvalds# Result is now in FP0 46131da177e4SLinus Torvalds# 46141da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 46151da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 46161da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 46171da177e4SLinus Torvalds unlk %a6 46181da177e4SLinus Torvalds rts 46191da177e4SLinus Torvalds 46201da177e4SLinus Torvalds global _fmodx_ 46211da177e4SLinus Torvalds_fmodx_: 46221da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 46231da177e4SLinus Torvalds 46241da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 46251da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 46261da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 46271da177e4SLinus Torvalds 46281da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 46291da177e4SLinus Torvalds 46301da177e4SLinus Torvalds# 46311da177e4SLinus Torvalds# copy, convert, and tag input argument 46321da177e4SLinus Torvalds# 46331da177e4SLinus Torvalds lea FP_DST(%a6),%a0 46341da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 46351da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 46361da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 46371da177e4SLinus Torvalds bsr.l tag # fetch operand type 46381da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 46391da177e4SLinus Torvalds 46401da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 46411da177e4SLinus Torvalds mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 46421da177e4SLinus Torvalds mov.l 0x14+0x4(%a6),0x4(%a0) 46431da177e4SLinus Torvalds mov.l 0x14+0x8(%a6),0x8(%a0) 46441da177e4SLinus Torvalds bsr.l tag # fetch operand type 46451da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 46461da177e4SLinus Torvalds mov.l %d0,%d1 46471da177e4SLinus Torvalds 46481da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 46491da177e4SLinus Torvalds 46501da177e4SLinus Torvalds clr.l %d0 46511da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 46521da177e4SLinus Torvalds 46531da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 46541da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 46551da177e4SLinus Torvalds 46561da177e4SLinus Torvalds tst.b %d1 46571da177e4SLinus Torvalds bne.b _L22_2x 46581da177e4SLinus Torvalds bsr.l smod_snorm # operand is a NORM 46591da177e4SLinus Torvalds bra.b _L22_6x 46601da177e4SLinus Torvalds_L22_2x: 46611da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 46621da177e4SLinus Torvalds bne.b _L22_3x # no 46631da177e4SLinus Torvalds bsr.l smod_szero # yes 46641da177e4SLinus Torvalds bra.b _L22_6x 46651da177e4SLinus Torvalds_L22_3x: 46661da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 46671da177e4SLinus Torvalds bne.b _L22_4x # no 46681da177e4SLinus Torvalds bsr.l smod_sinf # yes 46691da177e4SLinus Torvalds bra.b _L22_6x 46701da177e4SLinus Torvalds_L22_4x: 46711da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 46721da177e4SLinus Torvalds bne.b _L22_5x # no 46731da177e4SLinus Torvalds bsr.l sop_sqnan # yes 46741da177e4SLinus Torvalds bra.b _L22_6x 46751da177e4SLinus Torvalds_L22_5x: 46761da177e4SLinus Torvalds bsr.l smod_sdnrm # operand is a DENORM 46771da177e4SLinus Torvalds_L22_6x: 46781da177e4SLinus Torvalds 46791da177e4SLinus Torvalds# 46801da177e4SLinus Torvalds# Result is now in FP0 46811da177e4SLinus Torvalds# 46821da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 46831da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 46841da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 46851da177e4SLinus Torvalds unlk %a6 46861da177e4SLinus Torvalds rts 46871da177e4SLinus Torvalds 46881da177e4SLinus Torvalds 46891da177e4SLinus Torvalds######################################################################### 46901da177e4SLinus Torvalds# DYADIC TEMPLATE # 46911da177e4SLinus Torvalds######################################################################### 46921da177e4SLinus Torvalds global _fscales_ 46931da177e4SLinus Torvalds_fscales_: 46941da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 46951da177e4SLinus Torvalds 46961da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 46971da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 46981da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 46991da177e4SLinus Torvalds 47001da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 47011da177e4SLinus Torvalds 47021da177e4SLinus Torvalds# 47031da177e4SLinus Torvalds# copy, convert, and tag input argument 47041da177e4SLinus Torvalds# 47051da177e4SLinus Torvalds fmov.s 0x8(%a6),%fp0 # load sgl dst 47061da177e4SLinus Torvalds fmov.x %fp0,FP_DST(%a6) 47071da177e4SLinus Torvalds lea FP_DST(%a6),%a0 47081da177e4SLinus Torvalds bsr.l tag # fetch operand type 47091da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 47101da177e4SLinus Torvalds 47111da177e4SLinus Torvalds fmov.s 0xc(%a6),%fp0 # load sgl src 47121da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 47131da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 47141da177e4SLinus Torvalds bsr.l tag # fetch operand type 47151da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 47161da177e4SLinus Torvalds mov.l %d0,%d1 47171da177e4SLinus Torvalds 47181da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 47191da177e4SLinus Torvalds 47201da177e4SLinus Torvalds clr.l %d0 47211da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 47221da177e4SLinus Torvalds 47231da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 47241da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 47251da177e4SLinus Torvalds 47261da177e4SLinus Torvalds tst.b %d1 47271da177e4SLinus Torvalds bne.b _L23_2s 47281da177e4SLinus Torvalds bsr.l sscale_snorm # operand is a NORM 47291da177e4SLinus Torvalds bra.b _L23_6s 47301da177e4SLinus Torvalds_L23_2s: 47311da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 47321da177e4SLinus Torvalds bne.b _L23_3s # no 47331da177e4SLinus Torvalds bsr.l sscale_szero # yes 47341da177e4SLinus Torvalds bra.b _L23_6s 47351da177e4SLinus Torvalds_L23_3s: 47361da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 47371da177e4SLinus Torvalds bne.b _L23_4s # no 47381da177e4SLinus Torvalds bsr.l sscale_sinf # yes 47391da177e4SLinus Torvalds bra.b _L23_6s 47401da177e4SLinus Torvalds_L23_4s: 47411da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 47421da177e4SLinus Torvalds bne.b _L23_5s # no 47431da177e4SLinus Torvalds bsr.l sop_sqnan # yes 47441da177e4SLinus Torvalds bra.b _L23_6s 47451da177e4SLinus Torvalds_L23_5s: 47461da177e4SLinus Torvalds bsr.l sscale_sdnrm # operand is a DENORM 47471da177e4SLinus Torvalds_L23_6s: 47481da177e4SLinus Torvalds 47491da177e4SLinus Torvalds# 47501da177e4SLinus Torvalds# Result is now in FP0 47511da177e4SLinus Torvalds# 47521da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 47531da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 47541da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 47551da177e4SLinus Torvalds unlk %a6 47561da177e4SLinus Torvalds rts 47571da177e4SLinus Torvalds 47581da177e4SLinus Torvalds global _fscaled_ 47591da177e4SLinus Torvalds_fscaled_: 47601da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 47611da177e4SLinus Torvalds 47621da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 47631da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 47641da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 47651da177e4SLinus Torvalds 47661da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 47671da177e4SLinus Torvalds 47681da177e4SLinus Torvalds# 47691da177e4SLinus Torvalds# copy, convert, and tag input argument 47701da177e4SLinus Torvalds# 47711da177e4SLinus Torvalds fmov.d 0x8(%a6),%fp0 # load dbl dst 47721da177e4SLinus Torvalds fmov.x %fp0,FP_DST(%a6) 47731da177e4SLinus Torvalds lea FP_DST(%a6),%a0 47741da177e4SLinus Torvalds bsr.l tag # fetch operand type 47751da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 47761da177e4SLinus Torvalds 47771da177e4SLinus Torvalds fmov.d 0x10(%a6),%fp0 # load dbl src 47781da177e4SLinus Torvalds fmov.x %fp0,FP_SRC(%a6) 47791da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 47801da177e4SLinus Torvalds bsr.l tag # fetch operand type 47811da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 47821da177e4SLinus Torvalds mov.l %d0,%d1 47831da177e4SLinus Torvalds 47841da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 47851da177e4SLinus Torvalds 47861da177e4SLinus Torvalds clr.l %d0 47871da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 47881da177e4SLinus Torvalds 47891da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 47901da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 47911da177e4SLinus Torvalds 47921da177e4SLinus Torvalds tst.b %d1 47931da177e4SLinus Torvalds bne.b _L23_2d 47941da177e4SLinus Torvalds bsr.l sscale_snorm # operand is a NORM 47951da177e4SLinus Torvalds bra.b _L23_6d 47961da177e4SLinus Torvalds_L23_2d: 47971da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 47981da177e4SLinus Torvalds bne.b _L23_3d # no 47991da177e4SLinus Torvalds bsr.l sscale_szero # yes 48001da177e4SLinus Torvalds bra.b _L23_6d 48011da177e4SLinus Torvalds_L23_3d: 48021da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 48031da177e4SLinus Torvalds bne.b _L23_4d # no 48041da177e4SLinus Torvalds bsr.l sscale_sinf # yes 48051da177e4SLinus Torvalds bra.b _L23_6d 48061da177e4SLinus Torvalds_L23_4d: 48071da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 48081da177e4SLinus Torvalds bne.b _L23_5d # no 48091da177e4SLinus Torvalds bsr.l sop_sqnan # yes 48101da177e4SLinus Torvalds bra.b _L23_6d 48111da177e4SLinus Torvalds_L23_5d: 48121da177e4SLinus Torvalds bsr.l sscale_sdnrm # operand is a DENORM 48131da177e4SLinus Torvalds_L23_6d: 48141da177e4SLinus Torvalds 48151da177e4SLinus Torvalds# 48161da177e4SLinus Torvalds# Result is now in FP0 48171da177e4SLinus Torvalds# 48181da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 48191da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 48201da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 48211da177e4SLinus Torvalds unlk %a6 48221da177e4SLinus Torvalds rts 48231da177e4SLinus Torvalds 48241da177e4SLinus Torvalds global _fscalex_ 48251da177e4SLinus Torvalds_fscalex_: 48261da177e4SLinus Torvalds link %a6,&-LOCAL_SIZE 48271da177e4SLinus Torvalds 48281da177e4SLinus Torvalds movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 48291da177e4SLinus Torvalds fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 48301da177e4SLinus Torvalds fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 48311da177e4SLinus Torvalds 48321da177e4SLinus Torvalds fmov.l &0x0,%fpcr # zero FPCR 48331da177e4SLinus Torvalds 48341da177e4SLinus Torvalds# 48351da177e4SLinus Torvalds# copy, convert, and tag input argument 48361da177e4SLinus Torvalds# 48371da177e4SLinus Torvalds lea FP_DST(%a6),%a0 48381da177e4SLinus Torvalds mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 48391da177e4SLinus Torvalds mov.l 0x8+0x4(%a6),0x4(%a0) 48401da177e4SLinus Torvalds mov.l 0x8+0x8(%a6),0x8(%a0) 48411da177e4SLinus Torvalds bsr.l tag # fetch operand type 48421da177e4SLinus Torvalds mov.b %d0,DTAG(%a6) 48431da177e4SLinus Torvalds 48441da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 48451da177e4SLinus Torvalds mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 48461da177e4SLinus Torvalds mov.l 0x14+0x4(%a6),0x4(%a0) 48471da177e4SLinus Torvalds mov.l 0x14+0x8(%a6),0x8(%a0) 48481da177e4SLinus Torvalds bsr.l tag # fetch operand type 48491da177e4SLinus Torvalds mov.b %d0,STAG(%a6) 48501da177e4SLinus Torvalds mov.l %d0,%d1 48511da177e4SLinus Torvalds 48521da177e4SLinus Torvalds andi.l &0x00ff00ff,USER_FPSR(%a6) 48531da177e4SLinus Torvalds 48541da177e4SLinus Torvalds clr.l %d0 48551da177e4SLinus Torvalds mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 48561da177e4SLinus Torvalds 48571da177e4SLinus Torvalds lea FP_SRC(%a6),%a0 # pass ptr to src 48581da177e4SLinus Torvalds lea FP_DST(%a6),%a1 # pass ptr to dst 48591da177e4SLinus Torvalds 48601da177e4SLinus Torvalds tst.b %d1 48611da177e4SLinus Torvalds bne.b _L23_2x 48621da177e4SLinus Torvalds bsr.l sscale_snorm # operand is a NORM 48631da177e4SLinus Torvalds bra.b _L23_6x 48641da177e4SLinus Torvalds_L23_2x: 48651da177e4SLinus Torvalds cmpi.b %d1,&ZERO # is operand a ZERO? 48661da177e4SLinus Torvalds bne.b _L23_3x # no 48671da177e4SLinus Torvalds bsr.l sscale_szero # yes 48681da177e4SLinus Torvalds bra.b _L23_6x 48691da177e4SLinus Torvalds_L23_3x: 48701da177e4SLinus Torvalds cmpi.b %d1,&INF # is operand an INF? 48711da177e4SLinus Torvalds bne.b _L23_4x # no 48721da177e4SLinus Torvalds bsr.l sscale_sinf # yes 48731da177e4SLinus Torvalds bra.b _L23_6x 48741da177e4SLinus Torvalds_L23_4x: 48751da177e4SLinus Torvalds cmpi.b %d1,&QNAN # is operand a QNAN? 48761da177e4SLinus Torvalds bne.b _L23_5x # no 48771da177e4SLinus Torvalds bsr.l sop_sqnan # yes 48781da177e4SLinus Torvalds bra.b _L23_6x 48791da177e4SLinus Torvalds_L23_5x: 48801da177e4SLinus Torvalds bsr.l sscale_sdnrm # operand is a DENORM 48811da177e4SLinus Torvalds_L23_6x: 48821da177e4SLinus Torvalds 48831da177e4SLinus Torvalds# 48841da177e4SLinus Torvalds# Result is now in FP0 48851da177e4SLinus Torvalds# 48861da177e4SLinus Torvalds movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 48871da177e4SLinus Torvalds fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 48881da177e4SLinus Torvalds fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 48891da177e4SLinus Torvalds unlk %a6 48901da177e4SLinus Torvalds rts 48911da177e4SLinus Torvalds 48921da177e4SLinus Torvalds 48931da177e4SLinus Torvalds######################################################################### 48941da177e4SLinus Torvalds# ssin(): computes the sine of a normalized input # 48951da177e4SLinus Torvalds# ssind(): computes the sine of a denormalized input # 48961da177e4SLinus Torvalds# scos(): computes the cosine of a normalized input # 48971da177e4SLinus Torvalds# scosd(): computes the cosine of a denormalized input # 48981da177e4SLinus Torvalds# ssincos(): computes the sine and cosine of a normalized input # 48991da177e4SLinus Torvalds# ssincosd(): computes the sine and cosine of a denormalized input # 49001da177e4SLinus Torvalds# # 49011da177e4SLinus Torvalds# INPUT *************************************************************** # 49021da177e4SLinus Torvalds# a0 = pointer to extended precision input # 49031da177e4SLinus Torvalds# d0 = round precision,mode # 49041da177e4SLinus Torvalds# # 49051da177e4SLinus Torvalds# OUTPUT ************************************************************** # 49061da177e4SLinus Torvalds# fp0 = sin(X) or cos(X) # 49071da177e4SLinus Torvalds# # 49081da177e4SLinus Torvalds# For ssincos(X): # 49091da177e4SLinus Torvalds# fp0 = sin(X) # 49101da177e4SLinus Torvalds# fp1 = cos(X) # 49111da177e4SLinus Torvalds# # 49121da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 49131da177e4SLinus Torvalds# The returned result is within 1 ulp in 64 significant bit, i.e. # 49141da177e4SLinus Torvalds# within 0.5001 ulp to 53 bits if the result is subsequently # 49151da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 49161da177e4SLinus Torvalds# in double precision. # 49171da177e4SLinus Torvalds# # 49181da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 49191da177e4SLinus Torvalds# # 49201da177e4SLinus Torvalds# SIN and COS: # 49211da177e4SLinus Torvalds# 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. # 49221da177e4SLinus Torvalds# # 49231da177e4SLinus Torvalds# 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. # 49241da177e4SLinus Torvalds# # 49251da177e4SLinus Torvalds# 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 49261da177e4SLinus Torvalds# k = N mod 4, so in particular, k = 0,1,2,or 3. # 49271da177e4SLinus Torvalds# Overwrite k by k := k + AdjN. # 49281da177e4SLinus Torvalds# # 49291da177e4SLinus Torvalds# 4. If k is even, go to 6. # 49301da177e4SLinus Torvalds# # 49311da177e4SLinus Torvalds# 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. # 49321da177e4SLinus Torvalds# Return sgn*cos(r) where cos(r) is approximated by an # 49331da177e4SLinus Torvalds# even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), # 49341da177e4SLinus Torvalds# s = r*r. # 49351da177e4SLinus Torvalds# Exit. # 49361da177e4SLinus Torvalds# # 49371da177e4SLinus Torvalds# 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) # 49381da177e4SLinus Torvalds# where sin(r) is approximated by an odd polynomial in r # 49391da177e4SLinus Torvalds# r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. # 49401da177e4SLinus Torvalds# Exit. # 49411da177e4SLinus Torvalds# # 49421da177e4SLinus Torvalds# 7. If |X| > 1, go to 9. # 49431da177e4SLinus Torvalds# # 49441da177e4SLinus Torvalds# 8. (|X|<2**(-40)) If SIN is invoked, return X; # 49451da177e4SLinus Torvalds# otherwise return 1. # 49461da177e4SLinus Torvalds# # 49471da177e4SLinus Torvalds# 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 49481da177e4SLinus Torvalds# go back to 3. # 49491da177e4SLinus Torvalds# # 49501da177e4SLinus Torvalds# SINCOS: # 49511da177e4SLinus Torvalds# 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 49521da177e4SLinus Torvalds# # 49531da177e4SLinus Torvalds# 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 49541da177e4SLinus Torvalds# k = N mod 4, so in particular, k = 0,1,2,or 3. # 49551da177e4SLinus Torvalds# # 49561da177e4SLinus Torvalds# 3. If k is even, go to 5. # 49571da177e4SLinus Torvalds# # 49581da177e4SLinus Torvalds# 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie. # 49591da177e4SLinus Torvalds# j1 exclusive or with the l.s.b. of k. # 49601da177e4SLinus Torvalds# sgn1 := (-1)**j1, sgn2 := (-1)**j2. # 49611da177e4SLinus Torvalds# SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where # 49621da177e4SLinus Torvalds# sin(r) and cos(r) are computed as odd and even # 49631da177e4SLinus Torvalds# polynomials in r, respectively. Exit # 49641da177e4SLinus Torvalds# # 49651da177e4SLinus Torvalds# 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. # 49661da177e4SLinus Torvalds# SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where # 49671da177e4SLinus Torvalds# sin(r) and cos(r) are computed as odd and even # 49681da177e4SLinus Torvalds# polynomials in r, respectively. Exit # 49691da177e4SLinus Torvalds# # 49701da177e4SLinus Torvalds# 6. If |X| > 1, go to 8. # 49711da177e4SLinus Torvalds# # 49721da177e4SLinus Torvalds# 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. # 49731da177e4SLinus Torvalds# # 49741da177e4SLinus Torvalds# 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 49751da177e4SLinus Torvalds# go back to 2. # 49761da177e4SLinus Torvalds# # 49771da177e4SLinus Torvalds######################################################################### 49781da177e4SLinus Torvalds 49791da177e4SLinus TorvaldsSINA7: long 0xBD6AAA77,0xCCC994F5 49801da177e4SLinus TorvaldsSINA6: long 0x3DE61209,0x7AAE8DA1 49811da177e4SLinus TorvaldsSINA5: long 0xBE5AE645,0x2A118AE4 49821da177e4SLinus TorvaldsSINA4: long 0x3EC71DE3,0xA5341531 49831da177e4SLinus TorvaldsSINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000 49841da177e4SLinus TorvaldsSINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000 49851da177e4SLinus TorvaldsSINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000 49861da177e4SLinus Torvalds 49871da177e4SLinus TorvaldsCOSB8: long 0x3D2AC4D0,0xD6011EE3 49881da177e4SLinus TorvaldsCOSB7: long 0xBDA9396F,0x9F45AC19 49891da177e4SLinus TorvaldsCOSB6: long 0x3E21EED9,0x0612C972 49901da177e4SLinus TorvaldsCOSB5: long 0xBE927E4F,0xB79D9FCF 49911da177e4SLinus TorvaldsCOSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000 49921da177e4SLinus TorvaldsCOSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000 49931da177e4SLinus TorvaldsCOSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E 49941da177e4SLinus TorvaldsCOSB1: long 0xBF000000 49951da177e4SLinus Torvalds 49961da177e4SLinus Torvalds set INARG,FP_SCR0 49971da177e4SLinus Torvalds 49981da177e4SLinus Torvalds set X,FP_SCR0 49991da177e4SLinus Torvalds# set XDCARE,X+2 50001da177e4SLinus Torvalds set XFRAC,X+4 50011da177e4SLinus Torvalds 50021da177e4SLinus Torvalds set RPRIME,FP_SCR0 50031da177e4SLinus Torvalds set SPRIME,FP_SCR1 50041da177e4SLinus Torvalds 50051da177e4SLinus Torvalds set POSNEG1,L_SCR1 50061da177e4SLinus Torvalds set TWOTO63,L_SCR1 50071da177e4SLinus Torvalds 50081da177e4SLinus Torvalds set ENDFLAG,L_SCR2 50091da177e4SLinus Torvalds set INT,L_SCR2 50101da177e4SLinus Torvalds 50111da177e4SLinus Torvalds set ADJN,L_SCR3 50121da177e4SLinus Torvalds 50131da177e4SLinus Torvalds############################################ 50141da177e4SLinus Torvalds global ssin 50151da177e4SLinus Torvaldsssin: 50161da177e4SLinus Torvalds mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0 50171da177e4SLinus Torvalds bra.b SINBGN 50181da177e4SLinus Torvalds 50191da177e4SLinus Torvalds############################################ 50201da177e4SLinus Torvalds global scos 50211da177e4SLinus Torvaldsscos: 50221da177e4SLinus Torvalds mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1 50231da177e4SLinus Torvalds 50241da177e4SLinus Torvalds############################################ 50251da177e4SLinus TorvaldsSINBGN: 50261da177e4SLinus Torvalds#--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE 50271da177e4SLinus Torvalds 50281da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 50291da177e4SLinus Torvalds fmov.x %fp0,X(%a6) # save input at X 50301da177e4SLinus Torvalds 50311da177e4SLinus Torvalds# "COMPACTIFY" X 50321da177e4SLinus Torvalds mov.l (%a0),%d1 # put exp in hi word 50331da177e4SLinus Torvalds mov.w 4(%a0),%d1 # fetch hi(man) 50341da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 # strip sign 50351da177e4SLinus Torvalds 50361da177e4SLinus Torvalds cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)? 50371da177e4SLinus Torvalds bge.b SOK1 # no 50381da177e4SLinus Torvalds bra.w SINSM # yes; input is very small 50391da177e4SLinus Torvalds 50401da177e4SLinus TorvaldsSOK1: 50411da177e4SLinus Torvalds cmp.l %d1,&0x4004BC7E # is |X| < 15 PI? 50421da177e4SLinus Torvalds blt.b SINMAIN # no 50431da177e4SLinus Torvalds bra.w SREDUCEX # yes; input is very large 50441da177e4SLinus Torvalds 50451da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| <= 15 PI. 50461da177e4SLinus Torvalds#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 50471da177e4SLinus TorvaldsSINMAIN: 50481da177e4SLinus Torvalds fmov.x %fp0,%fp1 50491da177e4SLinus Torvalds fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 50501da177e4SLinus Torvalds 50511da177e4SLinus Torvalds lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 50521da177e4SLinus Torvalds 50531da177e4SLinus Torvalds fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 50541da177e4SLinus Torvalds 50551da177e4SLinus Torvalds mov.l INT(%a6),%d1 # make a copy of N 50561da177e4SLinus Torvalds asl.l &4,%d1 # N *= 16 50571da177e4SLinus Torvalds add.l %d1,%a1 # tbl_addr = a1 + (N*16) 50581da177e4SLinus Torvalds 50591da177e4SLinus Torvalds# A1 IS THE ADDRESS OF N*PIBY2 50601da177e4SLinus Torvalds# ...WHICH IS IN TWO PIECES Y1 & Y2 50611da177e4SLinus Torvalds fsub.x (%a1)+,%fp0 # X-Y1 50621da177e4SLinus Torvalds fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2 50631da177e4SLinus Torvalds 50641da177e4SLinus TorvaldsSINCONT: 50651da177e4SLinus Torvalds#--continuation from REDUCEX 50661da177e4SLinus Torvalds 50671da177e4SLinus Torvalds#--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED 50681da177e4SLinus Torvalds mov.l INT(%a6),%d1 50691da177e4SLinus Torvalds add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN 50701da177e4SLinus Torvalds ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE 50711da177e4SLinus Torvalds cmp.l %d1,&0 50721da177e4SLinus Torvalds blt.w COSPOLY 50731da177e4SLinus Torvalds 50741da177e4SLinus Torvalds#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 50751da177e4SLinus Torvalds#--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY 50761da177e4SLinus Torvalds#--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE 50771da177e4SLinus Torvalds#--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS 50781da177e4SLinus Torvalds#--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))]) 50791da177e4SLinus Torvalds#--WHERE T=S*S. 50801da177e4SLinus Torvalds#--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION 50811da177e4SLinus Torvalds#--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT. 50821da177e4SLinus TorvaldsSINPOLY: 50831da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2/fp3 50841da177e4SLinus Torvalds 50851da177e4SLinus Torvalds fmov.x %fp0,X(%a6) # X IS R 50861da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FP0 IS S 50871da177e4SLinus Torvalds 50881da177e4SLinus Torvalds fmov.d SINA7(%pc),%fp3 50891da177e4SLinus Torvalds fmov.d SINA6(%pc),%fp2 50901da177e4SLinus Torvalds 50911da177e4SLinus Torvalds fmov.x %fp0,%fp1 50921da177e4SLinus Torvalds fmul.x %fp1,%fp1 # FP1 IS T 50931da177e4SLinus Torvalds 50941da177e4SLinus Torvalds ror.l &1,%d1 50951da177e4SLinus Torvalds and.l &0x80000000,%d1 50961da177e4SLinus Torvalds# ...LEAST SIG. BIT OF D0 IN SIGN POSITION 50971da177e4SLinus Torvalds eor.l %d1,X(%a6) # X IS NOW R'= SGN*R 50981da177e4SLinus Torvalds 50991da177e4SLinus Torvalds fmul.x %fp1,%fp3 # TA7 51001da177e4SLinus Torvalds fmul.x %fp1,%fp2 # TA6 51011da177e4SLinus Torvalds 51021da177e4SLinus Torvalds fadd.d SINA5(%pc),%fp3 # A5+TA7 51031da177e4SLinus Torvalds fadd.d SINA4(%pc),%fp2 # A4+TA6 51041da177e4SLinus Torvalds 51051da177e4SLinus Torvalds fmul.x %fp1,%fp3 # T(A5+TA7) 51061da177e4SLinus Torvalds fmul.x %fp1,%fp2 # T(A4+TA6) 51071da177e4SLinus Torvalds 51081da177e4SLinus Torvalds fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7) 51091da177e4SLinus Torvalds fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6) 51101da177e4SLinus Torvalds 51111da177e4SLinus Torvalds fmul.x %fp3,%fp1 # T(A3+T(A5+TA7)) 51121da177e4SLinus Torvalds 51131da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(A2+T(A4+TA6)) 51141da177e4SLinus Torvalds fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7)) 51151da177e4SLinus Torvalds fmul.x X(%a6),%fp0 # R'*S 51161da177e4SLinus Torvalds 51171da177e4SLinus Torvalds fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))] 51181da177e4SLinus Torvalds 51191da177e4SLinus Torvalds fmul.x %fp1,%fp0 # SIN(R')-R' 51201da177e4SLinus Torvalds 51211da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2/fp3 51221da177e4SLinus Torvalds 51231da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 51241da177e4SLinus Torvalds fadd.x X(%a6),%fp0 # last inst - possible exception set 51251da177e4SLinus Torvalds bra t_inx2 51261da177e4SLinus Torvalds 51271da177e4SLinus Torvalds#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 51281da177e4SLinus Torvalds#--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY 51291da177e4SLinus Torvalds#--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE 51301da177e4SLinus Torvalds#--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS 51311da177e4SLinus Torvalds#--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))]) 51321da177e4SLinus Torvalds#--WHERE T=S*S. 51331da177e4SLinus Torvalds#--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION 51341da177e4SLinus Torvalds#--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2 51351da177e4SLinus Torvalds#--AND IS THEREFORE STORED AS SINGLE PRECISION. 51361da177e4SLinus TorvaldsCOSPOLY: 51371da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2/fp3 51381da177e4SLinus Torvalds 51391da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FP0 IS S 51401da177e4SLinus Torvalds 51411da177e4SLinus Torvalds fmov.d COSB8(%pc),%fp2 51421da177e4SLinus Torvalds fmov.d COSB7(%pc),%fp3 51431da177e4SLinus Torvalds 51441da177e4SLinus Torvalds fmov.x %fp0,%fp1 51451da177e4SLinus Torvalds fmul.x %fp1,%fp1 # FP1 IS T 51461da177e4SLinus Torvalds 51471da177e4SLinus Torvalds fmov.x %fp0,X(%a6) # X IS S 51481da177e4SLinus Torvalds ror.l &1,%d1 51491da177e4SLinus Torvalds and.l &0x80000000,%d1 51501da177e4SLinus Torvalds# ...LEAST SIG. BIT OF D0 IN SIGN POSITION 51511da177e4SLinus Torvalds 51521da177e4SLinus Torvalds fmul.x %fp1,%fp2 # TB8 51531da177e4SLinus Torvalds 51541da177e4SLinus Torvalds eor.l %d1,X(%a6) # X IS NOW S'= SGN*S 51551da177e4SLinus Torvalds and.l &0x80000000,%d1 51561da177e4SLinus Torvalds 51571da177e4SLinus Torvalds fmul.x %fp1,%fp3 # TB7 51581da177e4SLinus Torvalds 51591da177e4SLinus Torvalds or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE 51601da177e4SLinus Torvalds mov.l %d1,POSNEG1(%a6) 51611da177e4SLinus Torvalds 51621da177e4SLinus Torvalds fadd.d COSB6(%pc),%fp2 # B6+TB8 51631da177e4SLinus Torvalds fadd.d COSB5(%pc),%fp3 # B5+TB7 51641da177e4SLinus Torvalds 51651da177e4SLinus Torvalds fmul.x %fp1,%fp2 # T(B6+TB8) 51661da177e4SLinus Torvalds fmul.x %fp1,%fp3 # T(B5+TB7) 51671da177e4SLinus Torvalds 51681da177e4SLinus Torvalds fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8) 51691da177e4SLinus Torvalds fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7) 51701da177e4SLinus Torvalds 51711da177e4SLinus Torvalds fmul.x %fp1,%fp2 # T(B4+T(B6+TB8)) 51721da177e4SLinus Torvalds fmul.x %fp3,%fp1 # T(B3+T(B5+TB7)) 51731da177e4SLinus Torvalds 51741da177e4SLinus Torvalds fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8)) 51751da177e4SLinus Torvalds fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7)) 51761da177e4SLinus Torvalds 51771da177e4SLinus Torvalds fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8))) 51781da177e4SLinus Torvalds 51791da177e4SLinus Torvalds fadd.x %fp1,%fp0 51801da177e4SLinus Torvalds 51811da177e4SLinus Torvalds fmul.x X(%a6),%fp0 51821da177e4SLinus Torvalds 51831da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2/fp3 51841da177e4SLinus Torvalds 51851da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 51861da177e4SLinus Torvalds fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set 51871da177e4SLinus Torvalds bra t_inx2 51881da177e4SLinus Torvalds 51891da177e4SLinus Torvalds############################################## 51901da177e4SLinus Torvalds 51911da177e4SLinus Torvalds# SINe: Big OR Small? 51921da177e4SLinus Torvalds#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 51931da177e4SLinus Torvalds#--IF |X| < 2**(-40), RETURN X OR 1. 51941da177e4SLinus TorvaldsSINBORS: 51951da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 51961da177e4SLinus Torvalds bgt.l SREDUCEX 51971da177e4SLinus Torvalds 51981da177e4SLinus TorvaldsSINSM: 51991da177e4SLinus Torvalds mov.l ADJN(%a6),%d1 52001da177e4SLinus Torvalds cmp.l %d1,&0 52011da177e4SLinus Torvalds bgt.b COSTINY 52021da177e4SLinus Torvalds 52031da177e4SLinus Torvalds# here, the operation may underflow iff the precision is sgl or dbl. 52041da177e4SLinus Torvalds# extended denorms are handled through another entry point. 52051da177e4SLinus TorvaldsSINTINY: 52061da177e4SLinus Torvalds# mov.w &0x0000,XDCARE(%a6) # JUST IN CASE 52071da177e4SLinus Torvalds 52081da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 52091da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 52101da177e4SLinus Torvalds fmov.x X(%a6),%fp0 # last inst - possible exception set 52111da177e4SLinus Torvalds bra t_catch 52121da177e4SLinus Torvalds 52131da177e4SLinus TorvaldsCOSTINY: 52141da177e4SLinus Torvalds fmov.s &0x3F800000,%fp0 # fp0 = 1.0 52151da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 52161da177e4SLinus Torvalds fadd.s &0x80800000,%fp0 # last inst - possible exception set 52171da177e4SLinus Torvalds bra t_pinx2 52181da177e4SLinus Torvalds 52191da177e4SLinus Torvalds################################################ 52201da177e4SLinus Torvalds global ssind 52211da177e4SLinus Torvalds#--SIN(X) = X FOR DENORMALIZED X 52221da177e4SLinus Torvaldsssind: 52231da177e4SLinus Torvalds bra t_extdnrm 52241da177e4SLinus Torvalds 52251da177e4SLinus Torvalds############################################ 52261da177e4SLinus Torvalds global scosd 52271da177e4SLinus Torvalds#--COS(X) = 1 FOR DENORMALIZED X 52281da177e4SLinus Torvaldsscosd: 52291da177e4SLinus Torvalds fmov.s &0x3F800000,%fp0 # fp0 = 1.0 52301da177e4SLinus Torvalds bra t_pinx2 52311da177e4SLinus Torvalds 52321da177e4SLinus Torvalds################################################## 52331da177e4SLinus Torvalds 52341da177e4SLinus Torvalds global ssincos 52351da177e4SLinus Torvaldsssincos: 52361da177e4SLinus Torvalds#--SET ADJN TO 4 52371da177e4SLinus Torvalds mov.l &4,ADJN(%a6) 52381da177e4SLinus Torvalds 52391da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 52401da177e4SLinus Torvalds fmov.x %fp0,X(%a6) 52411da177e4SLinus Torvalds 52421da177e4SLinus Torvalds mov.l (%a0),%d1 52431da177e4SLinus Torvalds mov.w 4(%a0),%d1 52441da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 # COMPACTIFY X 52451da177e4SLinus Torvalds 52461da177e4SLinus Torvalds cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 52471da177e4SLinus Torvalds bge.b SCOK1 52481da177e4SLinus Torvalds bra.w SCSM 52491da177e4SLinus Torvalds 52501da177e4SLinus TorvaldsSCOK1: 52511da177e4SLinus Torvalds cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 52521da177e4SLinus Torvalds blt.b SCMAIN 52531da177e4SLinus Torvalds bra.w SREDUCEX 52541da177e4SLinus Torvalds 52551da177e4SLinus Torvalds 52561da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| <= 15 PI. 52571da177e4SLinus Torvalds#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 52581da177e4SLinus TorvaldsSCMAIN: 52591da177e4SLinus Torvalds fmov.x %fp0,%fp1 52601da177e4SLinus Torvalds 52611da177e4SLinus Torvalds fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 52621da177e4SLinus Torvalds 52631da177e4SLinus Torvalds lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 52641da177e4SLinus Torvalds 52651da177e4SLinus Torvalds fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 52661da177e4SLinus Torvalds 52671da177e4SLinus Torvalds mov.l INT(%a6),%d1 52681da177e4SLinus Torvalds asl.l &4,%d1 52691da177e4SLinus Torvalds add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2 52701da177e4SLinus Torvalds 52711da177e4SLinus Torvalds fsub.x (%a1)+,%fp0 # X-Y1 52721da177e4SLinus Torvalds fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 52731da177e4SLinus Torvalds 52741da177e4SLinus TorvaldsSCCONT: 52751da177e4SLinus Torvalds#--continuation point from REDUCEX 52761da177e4SLinus Torvalds 52771da177e4SLinus Torvalds mov.l INT(%a6),%d1 52781da177e4SLinus Torvalds ror.l &1,%d1 52791da177e4SLinus Torvalds cmp.l %d1,&0 # D0 < 0 IFF N IS ODD 52801da177e4SLinus Torvalds bge.w NEVEN 52811da177e4SLinus Torvalds 52821da177e4SLinus TorvaldsSNODD: 52831da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR: D0, A0, FP2. 52841da177e4SLinus Torvalds fmovm.x &0x04,-(%sp) # save fp2 52851da177e4SLinus Torvalds 52861da177e4SLinus Torvalds fmov.x %fp0,RPRIME(%a6) 52871da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FP0 IS S = R*R 52881da177e4SLinus Torvalds fmov.d SINA7(%pc),%fp1 # A7 52891da177e4SLinus Torvalds fmov.d COSB8(%pc),%fp2 # B8 52901da177e4SLinus Torvalds fmul.x %fp0,%fp1 # SA7 52911da177e4SLinus Torvalds fmul.x %fp0,%fp2 # SB8 52921da177e4SLinus Torvalds 52931da177e4SLinus Torvalds mov.l %d2,-(%sp) 52941da177e4SLinus Torvalds mov.l %d1,%d2 52951da177e4SLinus Torvalds ror.l &1,%d2 52961da177e4SLinus Torvalds and.l &0x80000000,%d2 52971da177e4SLinus Torvalds eor.l %d1,%d2 52981da177e4SLinus Torvalds and.l &0x80000000,%d2 52991da177e4SLinus Torvalds 53001da177e4SLinus Torvalds fadd.d SINA6(%pc),%fp1 # A6+SA7 53011da177e4SLinus Torvalds fadd.d COSB7(%pc),%fp2 # B7+SB8 53021da177e4SLinus Torvalds 53031da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(A6+SA7) 53041da177e4SLinus Torvalds eor.l %d2,RPRIME(%a6) 53051da177e4SLinus Torvalds mov.l (%sp)+,%d2 53061da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(B7+SB8) 53071da177e4SLinus Torvalds ror.l &1,%d1 53081da177e4SLinus Torvalds and.l &0x80000000,%d1 53091da177e4SLinus Torvalds mov.l &0x3F800000,POSNEG1(%a6) 53101da177e4SLinus Torvalds eor.l %d1,POSNEG1(%a6) 53111da177e4SLinus Torvalds 53121da177e4SLinus Torvalds fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7) 53131da177e4SLinus Torvalds fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8) 53141da177e4SLinus Torvalds 53151da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(A5+S(A6+SA7)) 53161da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(B6+S(B7+SB8)) 53171da177e4SLinus Torvalds fmov.x %fp0,SPRIME(%a6) 53181da177e4SLinus Torvalds 53191da177e4SLinus Torvalds fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7)) 53201da177e4SLinus Torvalds eor.l %d1,SPRIME(%a6) 53211da177e4SLinus Torvalds fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8)) 53221da177e4SLinus Torvalds 53231da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(A4+...) 53241da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(B5+...) 53251da177e4SLinus Torvalds 53261da177e4SLinus Torvalds fadd.d SINA3(%pc),%fp1 # A3+S(A4+...) 53271da177e4SLinus Torvalds fadd.d COSB4(%pc),%fp2 # B4+S(B5+...) 53281da177e4SLinus Torvalds 53291da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(A3+...) 53301da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(B4+...) 53311da177e4SLinus Torvalds 53321da177e4SLinus Torvalds fadd.x SINA2(%pc),%fp1 # A2+S(A3+...) 53331da177e4SLinus Torvalds fadd.x COSB3(%pc),%fp2 # B3+S(B4+...) 53341da177e4SLinus Torvalds 53351da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(A2+...) 53361da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(B3+...) 53371da177e4SLinus Torvalds 53381da177e4SLinus Torvalds fadd.x SINA1(%pc),%fp1 # A1+S(A2+...) 53391da177e4SLinus Torvalds fadd.x COSB2(%pc),%fp2 # B2+S(B3+...) 53401da177e4SLinus Torvalds 53411da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(A1+...) 53421da177e4SLinus Torvalds fmul.x %fp2,%fp0 # S(B2+...) 53431da177e4SLinus Torvalds 53441da177e4SLinus Torvalds fmul.x RPRIME(%a6),%fp1 # R'S(A1+...) 53451da177e4SLinus Torvalds fadd.s COSB1(%pc),%fp0 # B1+S(B2...) 53461da177e4SLinus Torvalds fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...)) 53471da177e4SLinus Torvalds 53481da177e4SLinus Torvalds fmovm.x (%sp)+,&0x20 # restore fp2 53491da177e4SLinus Torvalds 53501da177e4SLinus Torvalds fmov.l %d0,%fpcr 53511da177e4SLinus Torvalds fadd.x RPRIME(%a6),%fp1 # COS(X) 53521da177e4SLinus Torvalds bsr sto_cos # store cosine result 53531da177e4SLinus Torvalds fadd.s POSNEG1(%a6),%fp0 # SIN(X) 53541da177e4SLinus Torvalds bra t_inx2 53551da177e4SLinus Torvalds 53561da177e4SLinus TorvaldsNEVEN: 53571da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR: FP2. 53581da177e4SLinus Torvalds fmovm.x &0x04,-(%sp) # save fp2 53591da177e4SLinus Torvalds 53601da177e4SLinus Torvalds fmov.x %fp0,RPRIME(%a6) 53611da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FP0 IS S = R*R 53621da177e4SLinus Torvalds 53631da177e4SLinus Torvalds fmov.d COSB8(%pc),%fp1 # B8 53641da177e4SLinus Torvalds fmov.d SINA7(%pc),%fp2 # A7 53651da177e4SLinus Torvalds 53661da177e4SLinus Torvalds fmul.x %fp0,%fp1 # SB8 53671da177e4SLinus Torvalds fmov.x %fp0,SPRIME(%a6) 53681da177e4SLinus Torvalds fmul.x %fp0,%fp2 # SA7 53691da177e4SLinus Torvalds 53701da177e4SLinus Torvalds ror.l &1,%d1 53711da177e4SLinus Torvalds and.l &0x80000000,%d1 53721da177e4SLinus Torvalds 53731da177e4SLinus Torvalds fadd.d COSB7(%pc),%fp1 # B7+SB8 53741da177e4SLinus Torvalds fadd.d SINA6(%pc),%fp2 # A6+SA7 53751da177e4SLinus Torvalds 53761da177e4SLinus Torvalds eor.l %d1,RPRIME(%a6) 53771da177e4SLinus Torvalds eor.l %d1,SPRIME(%a6) 53781da177e4SLinus Torvalds 53791da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(B7+SB8) 53801da177e4SLinus Torvalds 53811da177e4SLinus Torvalds or.l &0x3F800000,%d1 53821da177e4SLinus Torvalds mov.l %d1,POSNEG1(%a6) 53831da177e4SLinus Torvalds 53841da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(A6+SA7) 53851da177e4SLinus Torvalds 53861da177e4SLinus Torvalds fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8) 53871da177e4SLinus Torvalds fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7) 53881da177e4SLinus Torvalds 53891da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(B6+S(B7+SB8)) 53901da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(A5+S(A6+SA7)) 53911da177e4SLinus Torvalds 53921da177e4SLinus Torvalds fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8)) 53931da177e4SLinus Torvalds fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7)) 53941da177e4SLinus Torvalds 53951da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(B5+...) 53961da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(A4+...) 53971da177e4SLinus Torvalds 53981da177e4SLinus Torvalds fadd.d COSB4(%pc),%fp1 # B4+S(B5+...) 53991da177e4SLinus Torvalds fadd.d SINA3(%pc),%fp2 # A3+S(A4+...) 54001da177e4SLinus Torvalds 54011da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(B4+...) 54021da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(A3+...) 54031da177e4SLinus Torvalds 54041da177e4SLinus Torvalds fadd.x COSB3(%pc),%fp1 # B3+S(B4+...) 54051da177e4SLinus Torvalds fadd.x SINA2(%pc),%fp2 # A2+S(A3+...) 54061da177e4SLinus Torvalds 54071da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(B3+...) 54081da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(A2+...) 54091da177e4SLinus Torvalds 54101da177e4SLinus Torvalds fadd.x COSB2(%pc),%fp1 # B2+S(B3+...) 54111da177e4SLinus Torvalds fadd.x SINA1(%pc),%fp2 # A1+S(A2+...) 54121da177e4SLinus Torvalds 54131da177e4SLinus Torvalds fmul.x %fp0,%fp1 # S(B2+...) 54141da177e4SLinus Torvalds fmul.x %fp2,%fp0 # s(a1+...) 54151da177e4SLinus Torvalds 54161da177e4SLinus Torvalds 54171da177e4SLinus Torvalds fadd.s COSB1(%pc),%fp1 # B1+S(B2...) 54181da177e4SLinus Torvalds fmul.x RPRIME(%a6),%fp0 # R'S(A1+...) 54191da177e4SLinus Torvalds fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...)) 54201da177e4SLinus Torvalds 54211da177e4SLinus Torvalds fmovm.x (%sp)+,&0x20 # restore fp2 54221da177e4SLinus Torvalds 54231da177e4SLinus Torvalds fmov.l %d0,%fpcr 54241da177e4SLinus Torvalds fadd.s POSNEG1(%a6),%fp1 # COS(X) 54251da177e4SLinus Torvalds bsr sto_cos # store cosine result 54261da177e4SLinus Torvalds fadd.x RPRIME(%a6),%fp0 # SIN(X) 54271da177e4SLinus Torvalds bra t_inx2 54281da177e4SLinus Torvalds 54291da177e4SLinus Torvalds################################################ 54301da177e4SLinus Torvalds 54311da177e4SLinus TorvaldsSCBORS: 54321da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 54331da177e4SLinus Torvalds bgt.w SREDUCEX 54341da177e4SLinus Torvalds 54351da177e4SLinus Torvalds################################################ 54361da177e4SLinus Torvalds 54371da177e4SLinus TorvaldsSCSM: 54381da177e4SLinus Torvalds# mov.w &0x0000,XDCARE(%a6) 54391da177e4SLinus Torvalds fmov.s &0x3F800000,%fp1 54401da177e4SLinus Torvalds 54411da177e4SLinus Torvalds fmov.l %d0,%fpcr 54421da177e4SLinus Torvalds fsub.s &0x00800000,%fp1 54431da177e4SLinus Torvalds bsr sto_cos # store cosine result 54441da177e4SLinus Torvalds fmov.l %fpcr,%d0 # d0 must have fpcr,too 54451da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 54461da177e4SLinus Torvalds fmov.x X(%a6),%fp0 54471da177e4SLinus Torvalds bra t_catch 54481da177e4SLinus Torvalds 54491da177e4SLinus Torvalds############################################## 54501da177e4SLinus Torvalds 54511da177e4SLinus Torvalds global ssincosd 54521da177e4SLinus Torvalds#--SIN AND COS OF X FOR DENORMALIZED X 54531da177e4SLinus Torvaldsssincosd: 54541da177e4SLinus Torvalds mov.l %d0,-(%sp) # save d0 54551da177e4SLinus Torvalds fmov.s &0x3F800000,%fp1 54561da177e4SLinus Torvalds bsr sto_cos # store cosine result 54571da177e4SLinus Torvalds mov.l (%sp)+,%d0 # restore d0 54581da177e4SLinus Torvalds bra t_extdnrm 54591da177e4SLinus Torvalds 54601da177e4SLinus Torvalds############################################ 54611da177e4SLinus Torvalds 54621da177e4SLinus Torvalds#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 54631da177e4SLinus Torvalds#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 54641da177e4SLinus Torvalds#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 54651da177e4SLinus TorvaldsSREDUCEX: 54661da177e4SLinus Torvalds fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 54671da177e4SLinus Torvalds mov.l %d2,-(%sp) # save d2 54681da177e4SLinus Torvalds fmov.s &0x00000000,%fp1 # fp1 = 0 54691da177e4SLinus Torvalds 54701da177e4SLinus Torvalds#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 54711da177e4SLinus Torvalds#--there is a danger of unwanted overflow in first LOOP iteration. In this 54721da177e4SLinus Torvalds#--case, reduce argument by one remainder step to make subsequent reduction 54731da177e4SLinus Torvalds#--safe. 54741da177e4SLinus Torvalds cmp.l %d1,&0x7ffeffff # is arg dangerously large? 54751da177e4SLinus Torvalds bne.b SLOOP # no 54761da177e4SLinus Torvalds 54771da177e4SLinus Torvalds# yes; create 2**16383*PI/2 54781da177e4SLinus Torvalds mov.w &0x7ffe,FP_SCR0_EX(%a6) 54791da177e4SLinus Torvalds mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 54801da177e4SLinus Torvalds clr.l FP_SCR0_LO(%a6) 54811da177e4SLinus Torvalds 54821da177e4SLinus Torvalds# create low half of 2**16383*PI/2 at FP_SCR1 54831da177e4SLinus Torvalds mov.w &0x7fdc,FP_SCR1_EX(%a6) 54841da177e4SLinus Torvalds mov.l &0x85a308d3,FP_SCR1_HI(%a6) 54851da177e4SLinus Torvalds clr.l FP_SCR1_LO(%a6) 54861da177e4SLinus Torvalds 54871da177e4SLinus Torvalds ftest.x %fp0 # test sign of argument 54881da177e4SLinus Torvalds fblt.w sred_neg 54891da177e4SLinus Torvalds 54901da177e4SLinus Torvalds or.b &0x80,FP_SCR0_EX(%a6) # positive arg 54911da177e4SLinus Torvalds or.b &0x80,FP_SCR1_EX(%a6) 54921da177e4SLinus Torvaldssred_neg: 54931da177e4SLinus Torvalds fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 54941da177e4SLinus Torvalds fmov.x %fp0,%fp1 # save high result in fp1 54951da177e4SLinus Torvalds fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 54961da177e4SLinus Torvalds fsub.x %fp0,%fp1 # determine low component of result 54971da177e4SLinus Torvalds fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 54981da177e4SLinus Torvalds 54991da177e4SLinus Torvalds#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 55001da177e4SLinus Torvalds#--integer quotient will be stored in N 55011da177e4SLinus Torvalds#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 55021da177e4SLinus TorvaldsSLOOP: 55031da177e4SLinus Torvalds fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 55041da177e4SLinus Torvalds mov.w INARG(%a6),%d1 55051da177e4SLinus Torvalds mov.l %d1,%a1 # save a copy of D0 55061da177e4SLinus Torvalds and.l &0x00007FFF,%d1 55071da177e4SLinus Torvalds sub.l &0x00003FFF,%d1 # d0 = K 55081da177e4SLinus Torvalds cmp.l %d1,&28 55091da177e4SLinus Torvalds ble.b SLASTLOOP 55101da177e4SLinus TorvaldsSCONTLOOP: 55111da177e4SLinus Torvalds sub.l &27,%d1 # d0 = L := K-27 55121da177e4SLinus Torvalds mov.b &0,ENDFLAG(%a6) 55131da177e4SLinus Torvalds bra.b SWORK 55141da177e4SLinus TorvaldsSLASTLOOP: 55151da177e4SLinus Torvalds clr.l %d1 # d0 = L := 0 55161da177e4SLinus Torvalds mov.b &1,ENDFLAG(%a6) 55171da177e4SLinus Torvalds 55181da177e4SLinus TorvaldsSWORK: 55191da177e4SLinus Torvalds#--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 55201da177e4SLinus Torvalds#--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 55211da177e4SLinus Torvalds 55221da177e4SLinus Torvalds#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 55231da177e4SLinus Torvalds#--2**L * (PIby2_1), 2**L * (PIby2_2) 55241da177e4SLinus Torvalds 55251da177e4SLinus Torvalds mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 55261da177e4SLinus Torvalds sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 55271da177e4SLinus Torvalds 55281da177e4SLinus Torvalds mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 55291da177e4SLinus Torvalds mov.l &0x4E44152A,FP_SCR0_LO(%a6) 55301da177e4SLinus Torvalds mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 55311da177e4SLinus Torvalds 55321da177e4SLinus Torvalds fmov.x %fp0,%fp2 55331da177e4SLinus Torvalds fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 55341da177e4SLinus Torvalds 55351da177e4SLinus Torvalds#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 55361da177e4SLinus Torvalds#--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 55371da177e4SLinus Torvalds#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 55381da177e4SLinus Torvalds#--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 55391da177e4SLinus Torvalds#--US THE DESIRED VALUE IN FLOATING POINT. 55401da177e4SLinus Torvalds mov.l %a1,%d2 55411da177e4SLinus Torvalds swap %d2 55421da177e4SLinus Torvalds and.l &0x80000000,%d2 55431da177e4SLinus Torvalds or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 55441da177e4SLinus Torvalds mov.l %d2,TWOTO63(%a6) 55451da177e4SLinus Torvalds fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 55461da177e4SLinus Torvalds fsub.s TWOTO63(%a6),%fp2 # fp2 = N 55471da177e4SLinus Torvalds# fint.x %fp2 55481da177e4SLinus Torvalds 55491da177e4SLinus Torvalds#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 55501da177e4SLinus Torvalds mov.l %d1,%d2 # d2 = L 55511da177e4SLinus Torvalds 55521da177e4SLinus Torvalds add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 55531da177e4SLinus Torvalds mov.w %d2,FP_SCR0_EX(%a6) 55541da177e4SLinus Torvalds mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 55551da177e4SLinus Torvalds clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 55561da177e4SLinus Torvalds 55571da177e4SLinus Torvalds add.l &0x00003FDD,%d1 55581da177e4SLinus Torvalds mov.w %d1,FP_SCR1_EX(%a6) 55591da177e4SLinus Torvalds mov.l &0x85A308D3,FP_SCR1_HI(%a6) 55601da177e4SLinus Torvalds clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 55611da177e4SLinus Torvalds 55621da177e4SLinus Torvalds mov.b ENDFLAG(%a6),%d1 55631da177e4SLinus Torvalds 55641da177e4SLinus Torvalds#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 55651da177e4SLinus Torvalds#--P2 = 2**(L) * Piby2_2 55661da177e4SLinus Torvalds fmov.x %fp2,%fp4 # fp4 = N 55671da177e4SLinus Torvalds fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 55681da177e4SLinus Torvalds fmov.x %fp2,%fp5 # fp5 = N 55691da177e4SLinus Torvalds fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 55701da177e4SLinus Torvalds fmov.x %fp4,%fp3 # fp3 = W = N*P1 55711da177e4SLinus Torvalds 55721da177e4SLinus Torvalds#--we want P+p = W+w but |p| <= half ulp of P 55731da177e4SLinus Torvalds#--Then, we need to compute A := R-P and a := r-p 55741da177e4SLinus Torvalds fadd.x %fp5,%fp3 # fp3 = P 55751da177e4SLinus Torvalds fsub.x %fp3,%fp4 # fp4 = W-P 55761da177e4SLinus Torvalds 55771da177e4SLinus Torvalds fsub.x %fp3,%fp0 # fp0 = A := R - P 55781da177e4SLinus Torvalds fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 55791da177e4SLinus Torvalds 55801da177e4SLinus Torvalds fmov.x %fp0,%fp3 # fp3 = A 55811da177e4SLinus Torvalds fsub.x %fp4,%fp1 # fp1 = a := r - p 55821da177e4SLinus Torvalds 55831da177e4SLinus Torvalds#--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 55841da177e4SLinus Torvalds#--|r| <= half ulp of R. 55851da177e4SLinus Torvalds fadd.x %fp1,%fp0 # fp0 = R := A+a 55861da177e4SLinus Torvalds#--No need to calculate r if this is the last loop 55871da177e4SLinus Torvalds cmp.b %d1,&0 55881da177e4SLinus Torvalds bgt.w SRESTORE 55891da177e4SLinus Torvalds 55901da177e4SLinus Torvalds#--Need to calculate r 55911da177e4SLinus Torvalds fsub.x %fp0,%fp3 # fp3 = A-R 55921da177e4SLinus Torvalds fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 55931da177e4SLinus Torvalds bra.w SLOOP 55941da177e4SLinus Torvalds 55951da177e4SLinus TorvaldsSRESTORE: 55961da177e4SLinus Torvalds fmov.l %fp2,INT(%a6) 55971da177e4SLinus Torvalds mov.l (%sp)+,%d2 # restore d2 55981da177e4SLinus Torvalds fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 55991da177e4SLinus Torvalds 56001da177e4SLinus Torvalds mov.l ADJN(%a6),%d1 56011da177e4SLinus Torvalds cmp.l %d1,&4 56021da177e4SLinus Torvalds 56031da177e4SLinus Torvalds blt.w SINCONT 56041da177e4SLinus Torvalds bra.w SCCONT 56051da177e4SLinus Torvalds 56061da177e4SLinus Torvalds######################################################################### 56071da177e4SLinus Torvalds# stan(): computes the tangent of a normalized input # 56081da177e4SLinus Torvalds# stand(): computes the tangent of a denormalized input # 56091da177e4SLinus Torvalds# # 56101da177e4SLinus Torvalds# INPUT *************************************************************** # 56111da177e4SLinus Torvalds# a0 = pointer to extended precision input # 56121da177e4SLinus Torvalds# d0 = round precision,mode # 56131da177e4SLinus Torvalds# # 56141da177e4SLinus Torvalds# OUTPUT ************************************************************** # 56151da177e4SLinus Torvalds# fp0 = tan(X) # 56161da177e4SLinus Torvalds# # 56171da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 56181da177e4SLinus Torvalds# The returned result is within 3 ulp in 64 significant bit, i.e. # 56191da177e4SLinus Torvalds# within 0.5001 ulp to 53 bits if the result is subsequently # 56201da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 56211da177e4SLinus Torvalds# in double precision. # 56221da177e4SLinus Torvalds# # 56231da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 56241da177e4SLinus Torvalds# # 56251da177e4SLinus Torvalds# 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 56261da177e4SLinus Torvalds# # 56271da177e4SLinus Torvalds# 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 56281da177e4SLinus Torvalds# k = N mod 2, so in particular, k = 0 or 1. # 56291da177e4SLinus Torvalds# # 56301da177e4SLinus Torvalds# 3. If k is odd, go to 5. # 56311da177e4SLinus Torvalds# # 56321da177e4SLinus Torvalds# 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a # 56331da177e4SLinus Torvalds# rational function U/V where # 56341da177e4SLinus Torvalds# U = r + r*s*(P1 + s*(P2 + s*P3)), and # 56351da177e4SLinus Torvalds# V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. # 56361da177e4SLinus Torvalds# Exit. # 56371da177e4SLinus Torvalds# # 56381da177e4SLinus Torvalds# 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by # 56391da177e4SLinus Torvalds# a rational function U/V where # 56401da177e4SLinus Torvalds# U = r + r*s*(P1 + s*(P2 + s*P3)), and # 56411da177e4SLinus Torvalds# V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, # 56421da177e4SLinus Torvalds# -Cot(r) = -V/U. Exit. # 56431da177e4SLinus Torvalds# # 56441da177e4SLinus Torvalds# 6. If |X| > 1, go to 8. # 56451da177e4SLinus Torvalds# # 56461da177e4SLinus Torvalds# 7. (|X|<2**(-40)) Tan(X) = X. Exit. # 56471da177e4SLinus Torvalds# # 56481da177e4SLinus Torvalds# 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back # 56491da177e4SLinus Torvalds# to 2. # 56501da177e4SLinus Torvalds# # 56511da177e4SLinus Torvalds######################################################################### 56521da177e4SLinus Torvalds 56531da177e4SLinus TorvaldsTANQ4: 56541da177e4SLinus Torvalds long 0x3EA0B759,0xF50F8688 56551da177e4SLinus TorvaldsTANP3: 56561da177e4SLinus Torvalds long 0xBEF2BAA5,0xA8924F04 56571da177e4SLinus Torvalds 56581da177e4SLinus TorvaldsTANQ3: 56591da177e4SLinus Torvalds long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000 56601da177e4SLinus Torvalds 56611da177e4SLinus TorvaldsTANP2: 56621da177e4SLinus Torvalds long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000 56631da177e4SLinus Torvalds 56641da177e4SLinus TorvaldsTANQ2: 56651da177e4SLinus Torvalds long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000 56661da177e4SLinus Torvalds 56671da177e4SLinus TorvaldsTANP1: 56681da177e4SLinus Torvalds long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000 56691da177e4SLinus Torvalds 56701da177e4SLinus TorvaldsTANQ1: 56711da177e4SLinus Torvalds long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000 56721da177e4SLinus Torvalds 56731da177e4SLinus TorvaldsINVTWOPI: 56741da177e4SLinus Torvalds long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000 56751da177e4SLinus Torvalds 56761da177e4SLinus TorvaldsTWOPI1: 56771da177e4SLinus Torvalds long 0x40010000,0xC90FDAA2,0x00000000,0x00000000 56781da177e4SLinus TorvaldsTWOPI2: 56791da177e4SLinus Torvalds long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000 56801da177e4SLinus Torvalds 56811da177e4SLinus Torvalds#--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING 56821da177e4SLinus Torvalds#--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT 56831da177e4SLinus Torvalds#--MOST 69 BITS LONG. 56841da177e4SLinus Torvalds# global PITBL 56851da177e4SLinus TorvaldsPITBL: 56861da177e4SLinus Torvalds long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000 56871da177e4SLinus Torvalds long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000 56881da177e4SLinus Torvalds long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000 56891da177e4SLinus Torvalds long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000 56901da177e4SLinus Torvalds long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000 56911da177e4SLinus Torvalds long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000 56921da177e4SLinus Torvalds long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000 56931da177e4SLinus Torvalds long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000 56941da177e4SLinus Torvalds long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000 56951da177e4SLinus Torvalds long 0xC0040000,0x90836524,0x88034B96,0x20B00000 56961da177e4SLinus Torvalds long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000 56971da177e4SLinus Torvalds long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000 56981da177e4SLinus Torvalds long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000 56991da177e4SLinus Torvalds long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000 57001da177e4SLinus Torvalds long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000 57011da177e4SLinus Torvalds long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000 57021da177e4SLinus Torvalds long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000 57031da177e4SLinus Torvalds long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000 57041da177e4SLinus Torvalds long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000 57051da177e4SLinus Torvalds long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000 57061da177e4SLinus Torvalds long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000 57071da177e4SLinus Torvalds long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000 57081da177e4SLinus Torvalds long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000 57091da177e4SLinus Torvalds long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000 57101da177e4SLinus Torvalds long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000 57111da177e4SLinus Torvalds long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000 57121da177e4SLinus Torvalds long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000 57131da177e4SLinus Torvalds long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000 57141da177e4SLinus Torvalds long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000 57151da177e4SLinus Torvalds long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000 57161da177e4SLinus Torvalds long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000 57171da177e4SLinus Torvalds long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000 57181da177e4SLinus Torvalds long 0x00000000,0x00000000,0x00000000,0x00000000 57191da177e4SLinus Torvalds long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000 57201da177e4SLinus Torvalds long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000 57211da177e4SLinus Torvalds long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000 57221da177e4SLinus Torvalds long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000 57231da177e4SLinus Torvalds long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000 57241da177e4SLinus Torvalds long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000 57251da177e4SLinus Torvalds long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000 57261da177e4SLinus Torvalds long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000 57271da177e4SLinus Torvalds long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000 57281da177e4SLinus Torvalds long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000 57291da177e4SLinus Torvalds long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000 57301da177e4SLinus Torvalds long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000 57311da177e4SLinus Torvalds long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000 57321da177e4SLinus Torvalds long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000 57331da177e4SLinus Torvalds long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000 57341da177e4SLinus Torvalds long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000 57351da177e4SLinus Torvalds long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000 57361da177e4SLinus Torvalds long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000 57371da177e4SLinus Torvalds long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000 57381da177e4SLinus Torvalds long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000 57391da177e4SLinus Torvalds long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000 57401da177e4SLinus Torvalds long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000 57411da177e4SLinus Torvalds long 0x40040000,0x90836524,0x88034B96,0xA0B00000 57421da177e4SLinus Torvalds long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000 57431da177e4SLinus Torvalds long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000 57441da177e4SLinus Torvalds long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000 57451da177e4SLinus Torvalds long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000 57461da177e4SLinus Torvalds long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000 57471da177e4SLinus Torvalds long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000 57481da177e4SLinus Torvalds long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000 57491da177e4SLinus Torvalds long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000 57501da177e4SLinus Torvalds long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000 57511da177e4SLinus Torvalds 57521da177e4SLinus Torvalds set INARG,FP_SCR0 57531da177e4SLinus Torvalds 57541da177e4SLinus Torvalds set TWOTO63,L_SCR1 57551da177e4SLinus Torvalds set INT,L_SCR1 57561da177e4SLinus Torvalds set ENDFLAG,L_SCR2 57571da177e4SLinus Torvalds 57581da177e4SLinus Torvalds global stan 57591da177e4SLinus Torvaldsstan: 57601da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 57611da177e4SLinus Torvalds 57621da177e4SLinus Torvalds mov.l (%a0),%d1 57631da177e4SLinus Torvalds mov.w 4(%a0),%d1 57641da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 57651da177e4SLinus Torvalds 57661da177e4SLinus Torvalds cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 57671da177e4SLinus Torvalds bge.b TANOK1 57681da177e4SLinus Torvalds bra.w TANSM 57691da177e4SLinus TorvaldsTANOK1: 57701da177e4SLinus Torvalds cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 57711da177e4SLinus Torvalds blt.b TANMAIN 57721da177e4SLinus Torvalds bra.w REDUCEX 57731da177e4SLinus Torvalds 57741da177e4SLinus TorvaldsTANMAIN: 57751da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| <= 15 PI. 57761da177e4SLinus Torvalds#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 57771da177e4SLinus Torvalds fmov.x %fp0,%fp1 57781da177e4SLinus Torvalds fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 57791da177e4SLinus Torvalds 57801da177e4SLinus Torvalds lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 57811da177e4SLinus Torvalds 57821da177e4SLinus Torvalds fmov.l %fp1,%d1 # CONVERT TO INTEGER 57831da177e4SLinus Torvalds 57841da177e4SLinus Torvalds asl.l &4,%d1 57851da177e4SLinus Torvalds add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2 57861da177e4SLinus Torvalds 57871da177e4SLinus Torvalds fsub.x (%a1)+,%fp0 # X-Y1 57881da177e4SLinus Torvalds 57891da177e4SLinus Torvalds fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 57901da177e4SLinus Torvalds 57911da177e4SLinus Torvalds ror.l &5,%d1 57921da177e4SLinus Torvalds and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0 57931da177e4SLinus Torvalds 57941da177e4SLinus TorvaldsTANCONT: 57951da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2,fp3 57961da177e4SLinus Torvalds 57971da177e4SLinus Torvalds cmp.l %d1,&0 57981da177e4SLinus Torvalds blt.w NODD 57991da177e4SLinus Torvalds 58001da177e4SLinus Torvalds fmov.x %fp0,%fp1 58011da177e4SLinus Torvalds fmul.x %fp1,%fp1 # S = R*R 58021da177e4SLinus Torvalds 58031da177e4SLinus Torvalds fmov.d TANQ4(%pc),%fp3 58041da177e4SLinus Torvalds fmov.d TANP3(%pc),%fp2 58051da177e4SLinus Torvalds 58061da177e4SLinus Torvalds fmul.x %fp1,%fp3 # SQ4 58071da177e4SLinus Torvalds fmul.x %fp1,%fp2 # SP3 58081da177e4SLinus Torvalds 58091da177e4SLinus Torvalds fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 58101da177e4SLinus Torvalds fadd.x TANP2(%pc),%fp2 # P2+SP3 58111da177e4SLinus Torvalds 58121da177e4SLinus Torvalds fmul.x %fp1,%fp3 # S(Q3+SQ4) 58131da177e4SLinus Torvalds fmul.x %fp1,%fp2 # S(P2+SP3) 58141da177e4SLinus Torvalds 58151da177e4SLinus Torvalds fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 58161da177e4SLinus Torvalds fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 58171da177e4SLinus Torvalds 58181da177e4SLinus Torvalds fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4)) 58191da177e4SLinus Torvalds fmul.x %fp1,%fp2 # S(P1+S(P2+SP3)) 58201da177e4SLinus Torvalds 58211da177e4SLinus Torvalds fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 58221da177e4SLinus Torvalds fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3)) 58231da177e4SLinus Torvalds 58241da177e4SLinus Torvalds fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4))) 58251da177e4SLinus Torvalds 58261da177e4SLinus Torvalds fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3)) 58271da177e4SLinus Torvalds 58281da177e4SLinus Torvalds fadd.s &0x3F800000,%fp1 # 1+S(Q1+...) 58291da177e4SLinus Torvalds 58301da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2,fp3 58311da177e4SLinus Torvalds 58321da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 58331da177e4SLinus Torvalds fdiv.x %fp1,%fp0 # last inst - possible exception set 58341da177e4SLinus Torvalds bra t_inx2 58351da177e4SLinus Torvalds 58361da177e4SLinus TorvaldsNODD: 58371da177e4SLinus Torvalds fmov.x %fp0,%fp1 58381da177e4SLinus Torvalds fmul.x %fp0,%fp0 # S = R*R 58391da177e4SLinus Torvalds 58401da177e4SLinus Torvalds fmov.d TANQ4(%pc),%fp3 58411da177e4SLinus Torvalds fmov.d TANP3(%pc),%fp2 58421da177e4SLinus Torvalds 58431da177e4SLinus Torvalds fmul.x %fp0,%fp3 # SQ4 58441da177e4SLinus Torvalds fmul.x %fp0,%fp2 # SP3 58451da177e4SLinus Torvalds 58461da177e4SLinus Torvalds fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 58471da177e4SLinus Torvalds fadd.x TANP2(%pc),%fp2 # P2+SP3 58481da177e4SLinus Torvalds 58491da177e4SLinus Torvalds fmul.x %fp0,%fp3 # S(Q3+SQ4) 58501da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(P2+SP3) 58511da177e4SLinus Torvalds 58521da177e4SLinus Torvalds fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 58531da177e4SLinus Torvalds fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 58541da177e4SLinus Torvalds 58551da177e4SLinus Torvalds fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4)) 58561da177e4SLinus Torvalds fmul.x %fp0,%fp2 # S(P1+S(P2+SP3)) 58571da177e4SLinus Torvalds 58581da177e4SLinus Torvalds fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 58591da177e4SLinus Torvalds fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3)) 58601da177e4SLinus Torvalds 58611da177e4SLinus Torvalds fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4))) 58621da177e4SLinus Torvalds 58631da177e4SLinus Torvalds fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3)) 58641da177e4SLinus Torvalds fadd.s &0x3F800000,%fp0 # 1+S(Q1+...) 58651da177e4SLinus Torvalds 58661da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2,fp3 58671da177e4SLinus Torvalds 58681da177e4SLinus Torvalds fmov.x %fp1,-(%sp) 58691da177e4SLinus Torvalds eor.l &0x80000000,(%sp) 58701da177e4SLinus Torvalds 58711da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 58721da177e4SLinus Torvalds fdiv.x (%sp)+,%fp0 # last inst - possible exception set 58731da177e4SLinus Torvalds bra t_inx2 58741da177e4SLinus Torvalds 58751da177e4SLinus TorvaldsTANBORS: 58761da177e4SLinus Torvalds#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 58771da177e4SLinus Torvalds#--IF |X| < 2**(-40), RETURN X OR 1. 58781da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 58791da177e4SLinus Torvalds bgt.b REDUCEX 58801da177e4SLinus Torvalds 58811da177e4SLinus TorvaldsTANSM: 58821da177e4SLinus Torvalds fmov.x %fp0,-(%sp) 58831da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round mode,prec 58841da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 58851da177e4SLinus Torvalds fmov.x (%sp)+,%fp0 # last inst - posibble exception set 58861da177e4SLinus Torvalds bra t_catch 58871da177e4SLinus Torvalds 58881da177e4SLinus Torvalds global stand 58891da177e4SLinus Torvalds#--TAN(X) = X FOR DENORMALIZED X 58901da177e4SLinus Torvaldsstand: 58911da177e4SLinus Torvalds bra t_extdnrm 58921da177e4SLinus Torvalds 58931da177e4SLinus Torvalds#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 58941da177e4SLinus Torvalds#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 58951da177e4SLinus Torvalds#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 58961da177e4SLinus TorvaldsREDUCEX: 58971da177e4SLinus Torvalds fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 58981da177e4SLinus Torvalds mov.l %d2,-(%sp) # save d2 58991da177e4SLinus Torvalds fmov.s &0x00000000,%fp1 # fp1 = 0 59001da177e4SLinus Torvalds 59011da177e4SLinus Torvalds#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 59021da177e4SLinus Torvalds#--there is a danger of unwanted overflow in first LOOP iteration. In this 59031da177e4SLinus Torvalds#--case, reduce argument by one remainder step to make subsequent reduction 59041da177e4SLinus Torvalds#--safe. 59051da177e4SLinus Torvalds cmp.l %d1,&0x7ffeffff # is arg dangerously large? 59061da177e4SLinus Torvalds bne.b LOOP # no 59071da177e4SLinus Torvalds 59081da177e4SLinus Torvalds# yes; create 2**16383*PI/2 59091da177e4SLinus Torvalds mov.w &0x7ffe,FP_SCR0_EX(%a6) 59101da177e4SLinus Torvalds mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 59111da177e4SLinus Torvalds clr.l FP_SCR0_LO(%a6) 59121da177e4SLinus Torvalds 59131da177e4SLinus Torvalds# create low half of 2**16383*PI/2 at FP_SCR1 59141da177e4SLinus Torvalds mov.w &0x7fdc,FP_SCR1_EX(%a6) 59151da177e4SLinus Torvalds mov.l &0x85a308d3,FP_SCR1_HI(%a6) 59161da177e4SLinus Torvalds clr.l FP_SCR1_LO(%a6) 59171da177e4SLinus Torvalds 59181da177e4SLinus Torvalds ftest.x %fp0 # test sign of argument 59191da177e4SLinus Torvalds fblt.w red_neg 59201da177e4SLinus Torvalds 59211da177e4SLinus Torvalds or.b &0x80,FP_SCR0_EX(%a6) # positive arg 59221da177e4SLinus Torvalds or.b &0x80,FP_SCR1_EX(%a6) 59231da177e4SLinus Torvaldsred_neg: 59241da177e4SLinus Torvalds fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 59251da177e4SLinus Torvalds fmov.x %fp0,%fp1 # save high result in fp1 59261da177e4SLinus Torvalds fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 59271da177e4SLinus Torvalds fsub.x %fp0,%fp1 # determine low component of result 59281da177e4SLinus Torvalds fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 59291da177e4SLinus Torvalds 59301da177e4SLinus Torvalds#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 59311da177e4SLinus Torvalds#--integer quotient will be stored in N 59321da177e4SLinus Torvalds#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 59331da177e4SLinus TorvaldsLOOP: 59341da177e4SLinus Torvalds fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 59351da177e4SLinus Torvalds mov.w INARG(%a6),%d1 59361da177e4SLinus Torvalds mov.l %d1,%a1 # save a copy of D0 59371da177e4SLinus Torvalds and.l &0x00007FFF,%d1 59381da177e4SLinus Torvalds sub.l &0x00003FFF,%d1 # d0 = K 59391da177e4SLinus Torvalds cmp.l %d1,&28 59401da177e4SLinus Torvalds ble.b LASTLOOP 59411da177e4SLinus TorvaldsCONTLOOP: 59421da177e4SLinus Torvalds sub.l &27,%d1 # d0 = L := K-27 59431da177e4SLinus Torvalds mov.b &0,ENDFLAG(%a6) 59441da177e4SLinus Torvalds bra.b WORK 59451da177e4SLinus TorvaldsLASTLOOP: 59461da177e4SLinus Torvalds clr.l %d1 # d0 = L := 0 59471da177e4SLinus Torvalds mov.b &1,ENDFLAG(%a6) 59481da177e4SLinus Torvalds 59491da177e4SLinus TorvaldsWORK: 59501da177e4SLinus Torvalds#--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 59511da177e4SLinus Torvalds#--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 59521da177e4SLinus Torvalds 59531da177e4SLinus Torvalds#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 59541da177e4SLinus Torvalds#--2**L * (PIby2_1), 2**L * (PIby2_2) 59551da177e4SLinus Torvalds 59561da177e4SLinus Torvalds mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 59571da177e4SLinus Torvalds sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 59581da177e4SLinus Torvalds 59591da177e4SLinus Torvalds mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 59601da177e4SLinus Torvalds mov.l &0x4E44152A,FP_SCR0_LO(%a6) 59611da177e4SLinus Torvalds mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 59621da177e4SLinus Torvalds 59631da177e4SLinus Torvalds fmov.x %fp0,%fp2 59641da177e4SLinus Torvalds fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 59651da177e4SLinus Torvalds 59661da177e4SLinus Torvalds#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 59671da177e4SLinus Torvalds#--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 59681da177e4SLinus Torvalds#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 59691da177e4SLinus Torvalds#--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 59701da177e4SLinus Torvalds#--US THE DESIRED VALUE IN FLOATING POINT. 59711da177e4SLinus Torvalds mov.l %a1,%d2 59721da177e4SLinus Torvalds swap %d2 59731da177e4SLinus Torvalds and.l &0x80000000,%d2 59741da177e4SLinus Torvalds or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 59751da177e4SLinus Torvalds mov.l %d2,TWOTO63(%a6) 59761da177e4SLinus Torvalds fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 59771da177e4SLinus Torvalds fsub.s TWOTO63(%a6),%fp2 # fp2 = N 59781da177e4SLinus Torvalds# fintrz.x %fp2,%fp2 59791da177e4SLinus Torvalds 59801da177e4SLinus Torvalds#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 59811da177e4SLinus Torvalds mov.l %d1,%d2 # d2 = L 59821da177e4SLinus Torvalds 59831da177e4SLinus Torvalds add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 59841da177e4SLinus Torvalds mov.w %d2,FP_SCR0_EX(%a6) 59851da177e4SLinus Torvalds mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 59861da177e4SLinus Torvalds clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 59871da177e4SLinus Torvalds 59881da177e4SLinus Torvalds add.l &0x00003FDD,%d1 59891da177e4SLinus Torvalds mov.w %d1,FP_SCR1_EX(%a6) 59901da177e4SLinus Torvalds mov.l &0x85A308D3,FP_SCR1_HI(%a6) 59911da177e4SLinus Torvalds clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 59921da177e4SLinus Torvalds 59931da177e4SLinus Torvalds mov.b ENDFLAG(%a6),%d1 59941da177e4SLinus Torvalds 59951da177e4SLinus Torvalds#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 59961da177e4SLinus Torvalds#--P2 = 2**(L) * Piby2_2 59971da177e4SLinus Torvalds fmov.x %fp2,%fp4 # fp4 = N 59981da177e4SLinus Torvalds fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 59991da177e4SLinus Torvalds fmov.x %fp2,%fp5 # fp5 = N 60001da177e4SLinus Torvalds fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 60011da177e4SLinus Torvalds fmov.x %fp4,%fp3 # fp3 = W = N*P1 60021da177e4SLinus Torvalds 60031da177e4SLinus Torvalds#--we want P+p = W+w but |p| <= half ulp of P 60041da177e4SLinus Torvalds#--Then, we need to compute A := R-P and a := r-p 60051da177e4SLinus Torvalds fadd.x %fp5,%fp3 # fp3 = P 60061da177e4SLinus Torvalds fsub.x %fp3,%fp4 # fp4 = W-P 60071da177e4SLinus Torvalds 60081da177e4SLinus Torvalds fsub.x %fp3,%fp0 # fp0 = A := R - P 60091da177e4SLinus Torvalds fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 60101da177e4SLinus Torvalds 60111da177e4SLinus Torvalds fmov.x %fp0,%fp3 # fp3 = A 60121da177e4SLinus Torvalds fsub.x %fp4,%fp1 # fp1 = a := r - p 60131da177e4SLinus Torvalds 60141da177e4SLinus Torvalds#--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 60151da177e4SLinus Torvalds#--|r| <= half ulp of R. 60161da177e4SLinus Torvalds fadd.x %fp1,%fp0 # fp0 = R := A+a 60171da177e4SLinus Torvalds#--No need to calculate r if this is the last loop 60181da177e4SLinus Torvalds cmp.b %d1,&0 60191da177e4SLinus Torvalds bgt.w RESTORE 60201da177e4SLinus Torvalds 60211da177e4SLinus Torvalds#--Need to calculate r 60221da177e4SLinus Torvalds fsub.x %fp0,%fp3 # fp3 = A-R 60231da177e4SLinus Torvalds fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 60241da177e4SLinus Torvalds bra.w LOOP 60251da177e4SLinus Torvalds 60261da177e4SLinus TorvaldsRESTORE: 60271da177e4SLinus Torvalds fmov.l %fp2,INT(%a6) 60281da177e4SLinus Torvalds mov.l (%sp)+,%d2 # restore d2 60291da177e4SLinus Torvalds fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 60301da177e4SLinus Torvalds 60311da177e4SLinus Torvalds mov.l INT(%a6),%d1 60321da177e4SLinus Torvalds ror.l &1,%d1 60331da177e4SLinus Torvalds 60341da177e4SLinus Torvalds bra.w TANCONT 60351da177e4SLinus Torvalds 60361da177e4SLinus Torvalds######################################################################### 60371da177e4SLinus Torvalds# satan(): computes the arctangent of a normalized number # 60381da177e4SLinus Torvalds# satand(): computes the arctangent of a denormalized number # 60391da177e4SLinus Torvalds# # 60401da177e4SLinus Torvalds# INPUT *************************************************************** # 60411da177e4SLinus Torvalds# a0 = pointer to extended precision input # 60421da177e4SLinus Torvalds# d0 = round precision,mode # 60431da177e4SLinus Torvalds# # 60441da177e4SLinus Torvalds# OUTPUT ************************************************************** # 60451da177e4SLinus Torvalds# fp0 = arctan(X) # 60461da177e4SLinus Torvalds# # 60471da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 60481da177e4SLinus Torvalds# The returned result is within 2 ulps in 64 significant bit, # 60491da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 60501da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 60511da177e4SLinus Torvalds# in double precision. # 60521da177e4SLinus Torvalds# # 60531da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 60541da177e4SLinus Torvalds# Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. # 60551da177e4SLinus Torvalds# # 60561da177e4SLinus Torvalds# Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. # 60571da177e4SLinus Torvalds# Note that k = -4, -3,..., or 3. # 60581da177e4SLinus Torvalds# Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 # 60591da177e4SLinus Torvalds# significant bits of X with a bit-1 attached at the 6-th # 60601da177e4SLinus Torvalds# bit position. Define u to be u = (X-F) / (1 + X*F). # 60611da177e4SLinus Torvalds# # 60621da177e4SLinus Torvalds# Step 3. Approximate arctan(u) by a polynomial poly. # 60631da177e4SLinus Torvalds# # 60641da177e4SLinus Torvalds# Step 4. Return arctan(F) + poly, arctan(F) is fetched from a # 60651da177e4SLinus Torvalds# table of values calculated beforehand. Exit. # 60661da177e4SLinus Torvalds# # 60671da177e4SLinus Torvalds# Step 5. If |X| >= 16, go to Step 7. # 60681da177e4SLinus Torvalds# # 60691da177e4SLinus Torvalds# Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. # 60701da177e4SLinus Torvalds# # 60711da177e4SLinus Torvalds# Step 7. Define X' = -1/X. Approximate arctan(X') by an odd # 60721da177e4SLinus Torvalds# polynomial in X'. # 60731da177e4SLinus Torvalds# Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. # 60741da177e4SLinus Torvalds# # 60751da177e4SLinus Torvalds######################################################################### 60761da177e4SLinus Torvalds 60771da177e4SLinus TorvaldsATANA3: long 0xBFF6687E,0x314987D8 60781da177e4SLinus TorvaldsATANA2: long 0x4002AC69,0x34A26DB3 60791da177e4SLinus TorvaldsATANA1: long 0xBFC2476F,0x4E1DA28E 60801da177e4SLinus Torvalds 60811da177e4SLinus TorvaldsATANB6: long 0x3FB34444,0x7F876989 60821da177e4SLinus TorvaldsATANB5: long 0xBFB744EE,0x7FAF45DB 60831da177e4SLinus TorvaldsATANB4: long 0x3FBC71C6,0x46940220 60841da177e4SLinus TorvaldsATANB3: long 0xBFC24924,0x921872F9 60851da177e4SLinus TorvaldsATANB2: long 0x3FC99999,0x99998FA9 60861da177e4SLinus TorvaldsATANB1: long 0xBFD55555,0x55555555 60871da177e4SLinus Torvalds 60881da177e4SLinus TorvaldsATANC5: long 0xBFB70BF3,0x98539E6A 60891da177e4SLinus TorvaldsATANC4: long 0x3FBC7187,0x962D1D7D 60901da177e4SLinus TorvaldsATANC3: long 0xBFC24924,0x827107B8 60911da177e4SLinus TorvaldsATANC2: long 0x3FC99999,0x9996263E 60921da177e4SLinus TorvaldsATANC1: long 0xBFD55555,0x55555536 60931da177e4SLinus Torvalds 60941da177e4SLinus TorvaldsPPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 60951da177e4SLinus TorvaldsNPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000 60961da177e4SLinus Torvalds 60971da177e4SLinus TorvaldsPTINY: long 0x00010000,0x80000000,0x00000000,0x00000000 60981da177e4SLinus TorvaldsNTINY: long 0x80010000,0x80000000,0x00000000,0x00000000 60991da177e4SLinus Torvalds 61001da177e4SLinus TorvaldsATANTBL: 61011da177e4SLinus Torvalds long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000 61021da177e4SLinus Torvalds long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000 61031da177e4SLinus Torvalds long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000 61041da177e4SLinus Torvalds long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000 61051da177e4SLinus Torvalds long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000 61061da177e4SLinus Torvalds long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000 61071da177e4SLinus Torvalds long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000 61081da177e4SLinus Torvalds long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000 61091da177e4SLinus Torvalds long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000 61101da177e4SLinus Torvalds long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000 61111da177e4SLinus Torvalds long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000 61121da177e4SLinus Torvalds long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000 61131da177e4SLinus Torvalds long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000 61141da177e4SLinus Torvalds long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000 61151da177e4SLinus Torvalds long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000 61161da177e4SLinus Torvalds long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000 61171da177e4SLinus Torvalds long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000 61181da177e4SLinus Torvalds long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000 61191da177e4SLinus Torvalds long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000 61201da177e4SLinus Torvalds long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000 61211da177e4SLinus Torvalds long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000 61221da177e4SLinus Torvalds long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000 61231da177e4SLinus Torvalds long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000 61241da177e4SLinus Torvalds long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000 61251da177e4SLinus Torvalds long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000 61261da177e4SLinus Torvalds long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000 61271da177e4SLinus Torvalds long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000 61281da177e4SLinus Torvalds long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000 61291da177e4SLinus Torvalds long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000 61301da177e4SLinus Torvalds long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000 61311da177e4SLinus Torvalds long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000 61321da177e4SLinus Torvalds long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000 61331da177e4SLinus Torvalds long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000 61341da177e4SLinus Torvalds long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000 61351da177e4SLinus Torvalds long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000 61361da177e4SLinus Torvalds long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000 61371da177e4SLinus Torvalds long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000 61381da177e4SLinus Torvalds long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000 61391da177e4SLinus Torvalds long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000 61401da177e4SLinus Torvalds long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000 61411da177e4SLinus Torvalds long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000 61421da177e4SLinus Torvalds long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000 61431da177e4SLinus Torvalds long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000 61441da177e4SLinus Torvalds long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000 61451da177e4SLinus Torvalds long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000 61461da177e4SLinus Torvalds long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000 61471da177e4SLinus Torvalds long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000 61481da177e4SLinus Torvalds long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000 61491da177e4SLinus Torvalds long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000 61501da177e4SLinus Torvalds long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000 61511da177e4SLinus Torvalds long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000 61521da177e4SLinus Torvalds long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000 61531da177e4SLinus Torvalds long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000 61541da177e4SLinus Torvalds long 0x3FFE0000,0x97731420,0x365E538C,0x00000000 61551da177e4SLinus Torvalds long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000 61561da177e4SLinus Torvalds long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000 61571da177e4SLinus Torvalds long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000 61581da177e4SLinus Torvalds long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000 61591da177e4SLinus Torvalds long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000 61601da177e4SLinus Torvalds long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000 61611da177e4SLinus Torvalds long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000 61621da177e4SLinus Torvalds long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000 61631da177e4SLinus Torvalds long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000 61641da177e4SLinus Torvalds long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000 61651da177e4SLinus Torvalds long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000 61661da177e4SLinus Torvalds long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000 61671da177e4SLinus Torvalds long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000 61681da177e4SLinus Torvalds long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000 61691da177e4SLinus Torvalds long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000 61701da177e4SLinus Torvalds long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000 61711da177e4SLinus Torvalds long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000 61721da177e4SLinus Torvalds long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000 61731da177e4SLinus Torvalds long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000 61741da177e4SLinus Torvalds long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000 61751da177e4SLinus Torvalds long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000 61761da177e4SLinus Torvalds long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000 61771da177e4SLinus Torvalds long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000 61781da177e4SLinus Torvalds long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000 61791da177e4SLinus Torvalds long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000 61801da177e4SLinus Torvalds long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000 61811da177e4SLinus Torvalds long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000 61821da177e4SLinus Torvalds long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000 61831da177e4SLinus Torvalds long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000 61841da177e4SLinus Torvalds long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000 61851da177e4SLinus Torvalds long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000 61861da177e4SLinus Torvalds long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000 61871da177e4SLinus Torvalds long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000 61881da177e4SLinus Torvalds long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000 61891da177e4SLinus Torvalds long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000 61901da177e4SLinus Torvalds long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000 61911da177e4SLinus Torvalds long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000 61921da177e4SLinus Torvalds long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000 61931da177e4SLinus Torvalds long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000 61941da177e4SLinus Torvalds long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000 61951da177e4SLinus Torvalds long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000 61961da177e4SLinus Torvalds long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000 61971da177e4SLinus Torvalds long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000 61981da177e4SLinus Torvalds long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000 61991da177e4SLinus Torvalds long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000 62001da177e4SLinus Torvalds long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000 62011da177e4SLinus Torvalds long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000 62021da177e4SLinus Torvalds long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000 62031da177e4SLinus Torvalds long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000 62041da177e4SLinus Torvalds long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000 62051da177e4SLinus Torvalds long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000 62061da177e4SLinus Torvalds long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000 62071da177e4SLinus Torvalds long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000 62081da177e4SLinus Torvalds long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000 62091da177e4SLinus Torvalds long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000 62101da177e4SLinus Torvalds long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000 62111da177e4SLinus Torvalds long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000 62121da177e4SLinus Torvalds long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000 62131da177e4SLinus Torvalds long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000 62141da177e4SLinus Torvalds long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000 62151da177e4SLinus Torvalds long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000 62161da177e4SLinus Torvalds long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000 62171da177e4SLinus Torvalds long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000 62181da177e4SLinus Torvalds long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000 62191da177e4SLinus Torvalds long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000 62201da177e4SLinus Torvalds long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000 62211da177e4SLinus Torvalds long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000 62221da177e4SLinus Torvalds long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000 62231da177e4SLinus Torvalds long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000 62241da177e4SLinus Torvalds long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000 62251da177e4SLinus Torvalds long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000 62261da177e4SLinus Torvalds long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000 62271da177e4SLinus Torvalds long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000 62281da177e4SLinus Torvalds long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000 62291da177e4SLinus Torvalds 62301da177e4SLinus Torvalds set X,FP_SCR0 62311da177e4SLinus Torvalds set XDCARE,X+2 62321da177e4SLinus Torvalds set XFRAC,X+4 62331da177e4SLinus Torvalds set XFRACLO,X+8 62341da177e4SLinus Torvalds 62351da177e4SLinus Torvalds set ATANF,FP_SCR1 62361da177e4SLinus Torvalds set ATANFHI,ATANF+4 62371da177e4SLinus Torvalds set ATANFLO,ATANF+8 62381da177e4SLinus Torvalds 62391da177e4SLinus Torvalds global satan 62401da177e4SLinus Torvalds#--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 62411da177e4SLinus Torvaldssatan: 62421da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 62431da177e4SLinus Torvalds 62441da177e4SLinus Torvalds mov.l (%a0),%d1 62451da177e4SLinus Torvalds mov.w 4(%a0),%d1 62461da177e4SLinus Torvalds fmov.x %fp0,X(%a6) 62471da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 62481da177e4SLinus Torvalds 62491da177e4SLinus Torvalds cmp.l %d1,&0x3FFB8000 # |X| >= 1/16? 62501da177e4SLinus Torvalds bge.b ATANOK1 62511da177e4SLinus Torvalds bra.w ATANSM 62521da177e4SLinus Torvalds 62531da177e4SLinus TorvaldsATANOK1: 62541da177e4SLinus Torvalds cmp.l %d1,&0x4002FFFF # |X| < 16 ? 62551da177e4SLinus Torvalds ble.b ATANMAIN 62561da177e4SLinus Torvalds bra.w ATANBIG 62571da177e4SLinus Torvalds 62581da177e4SLinus Torvalds#--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE 62591da177e4SLinus Torvalds#--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ). 62601da177e4SLinus Torvalds#--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN 62611da177e4SLinus Torvalds#--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE 62621da177e4SLinus Torvalds#--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS 62631da177e4SLinus Torvalds#--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR 62641da177e4SLinus Torvalds#--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO 62651da177e4SLinus Torvalds#--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE 62661da177e4SLinus Torvalds#--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL 62671da177e4SLinus Torvalds#--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE 62681da177e4SLinus Torvalds#--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION 62691da177e4SLinus Torvalds#--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION 62701da177e4SLinus Torvalds#--WILL INVOLVE A VERY LONG POLYNOMIAL. 62711da177e4SLinus Torvalds 62721da177e4SLinus Torvalds#--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS 62731da177e4SLinus Torvalds#--WE CHOSE F TO BE +-2^K * 1.BBBB1 62741da177e4SLinus Torvalds#--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE 62751da177e4SLinus Torvalds#--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE 62761da177e4SLinus Torvalds#--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS 62771da177e4SLinus Torvalds#-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|). 62781da177e4SLinus Torvalds 62791da177e4SLinus TorvaldsATANMAIN: 62801da177e4SLinus Torvalds 62811da177e4SLinus Torvalds and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS 62821da177e4SLinus Torvalds or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1 62831da177e4SLinus Torvalds mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F 62841da177e4SLinus Torvalds 62851da177e4SLinus Torvalds fmov.x %fp0,%fp1 # FP1 IS X 62861da177e4SLinus Torvalds fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0 62871da177e4SLinus Torvalds fsub.x X(%a6),%fp0 # FP0 IS X-F 62881da177e4SLinus Torvalds fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F 62891da177e4SLinus Torvalds fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F) 62901da177e4SLinus Torvalds 62911da177e4SLinus Torvalds#--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|) 62921da177e4SLinus Torvalds#--CREATE ATAN(F) AND STORE IT IN ATANF, AND 62931da177e4SLinus Torvalds#--SAVE REGISTERS FP2. 62941da177e4SLinus Torvalds 62951da177e4SLinus Torvalds mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY 62961da177e4SLinus Torvalds mov.l %d1,%d2 # THE EXP AND 16 BITS OF X 62971da177e4SLinus Torvalds and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION 62981da177e4SLinus Torvalds and.l &0x7FFF0000,%d2 # EXPONENT OF F 62991da177e4SLinus Torvalds sub.l &0x3FFB0000,%d2 # K+4 63001da177e4SLinus Torvalds asr.l &1,%d2 63011da177e4SLinus Torvalds add.l %d2,%d1 # THE 7 BITS IDENTIFYING F 63021da177e4SLinus Torvalds asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|) 63031da177e4SLinus Torvalds lea ATANTBL(%pc),%a1 63041da177e4SLinus Torvalds add.l %d1,%a1 # ADDRESS OF ATAN(|F|) 63051da177e4SLinus Torvalds mov.l (%a1)+,ATANF(%a6) 63061da177e4SLinus Torvalds mov.l (%a1)+,ATANFHI(%a6) 63071da177e4SLinus Torvalds mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|) 63081da177e4SLinus Torvalds mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN 63091da177e4SLinus Torvalds and.l &0x80000000,%d1 # SIGN(F) 63101da177e4SLinus Torvalds or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|) 63111da177e4SLinus Torvalds mov.l (%sp)+,%d2 # RESTORE d2 63121da177e4SLinus Torvalds 63131da177e4SLinus Torvalds#--THAT'S ALL I HAVE TO DO FOR NOW, 63141da177e4SLinus Torvalds#--BUT ALAS, THE DIVIDE IS STILL CRANKING! 63151da177e4SLinus Torvalds 63161da177e4SLinus Torvalds#--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS 63171da177e4SLinus Torvalds#--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U 63181da177e4SLinus Torvalds#--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT. 63191da177e4SLinus Torvalds#--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3)) 63201da177e4SLinus Torvalds#--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3. 63211da177e4SLinus Torvalds#--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT 63221da177e4SLinus Torvalds#--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED 63231da177e4SLinus Torvalds 63241da177e4SLinus Torvalds fmovm.x &0x04,-(%sp) # save fp2 63251da177e4SLinus Torvalds 63261da177e4SLinus Torvalds fmov.x %fp0,%fp1 63271da177e4SLinus Torvalds fmul.x %fp1,%fp1 63281da177e4SLinus Torvalds fmov.d ATANA3(%pc),%fp2 63291da177e4SLinus Torvalds fadd.x %fp1,%fp2 # A3+V 63301da177e4SLinus Torvalds fmul.x %fp1,%fp2 # V*(A3+V) 63311da177e4SLinus Torvalds fmul.x %fp0,%fp1 # U*V 63321da177e4SLinus Torvalds fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V) 63331da177e4SLinus Torvalds fmul.d ATANA1(%pc),%fp1 # A1*U*V 63341da177e4SLinus Torvalds fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V)) 63351da177e4SLinus Torvalds fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED 63361da177e4SLinus Torvalds 63371da177e4SLinus Torvalds fmovm.x (%sp)+,&0x20 # restore fp2 63381da177e4SLinus Torvalds 63391da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users rnd mode,prec 63401da177e4SLinus Torvalds fadd.x ATANF(%a6),%fp0 # ATAN(X) 63411da177e4SLinus Torvalds bra t_inx2 63421da177e4SLinus Torvalds 63431da177e4SLinus TorvaldsATANBORS: 63441da177e4SLinus Torvalds#--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED. 63451da177e4SLinus Torvalds#--FP0 IS X AND |X| <= 1/16 OR |X| >= 16. 63461da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 63471da177e4SLinus Torvalds bgt.w ATANBIG # I.E. |X| >= 16 63481da177e4SLinus Torvalds 63491da177e4SLinus TorvaldsATANSM: 63501da177e4SLinus Torvalds#--|X| <= 1/16 63511da177e4SLinus Torvalds#--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE 63521da177e4SLinus Torvalds#--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6))))) 63531da177e4SLinus Torvalds#--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] ) 63541da177e4SLinus Torvalds#--WHERE Y = X*X, AND Z = Y*Y. 63551da177e4SLinus Torvalds 63561da177e4SLinus Torvalds cmp.l %d1,&0x3FD78000 63571da177e4SLinus Torvalds blt.w ATANTINY 63581da177e4SLinus Torvalds 63591da177e4SLinus Torvalds#--COMPUTE POLYNOMIAL 63601da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2/fp3 63611da177e4SLinus Torvalds 63621da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FPO IS Y = X*X 63631da177e4SLinus Torvalds 63641da177e4SLinus Torvalds fmov.x %fp0,%fp1 63651da177e4SLinus Torvalds fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 63661da177e4SLinus Torvalds 63671da177e4SLinus Torvalds fmov.d ATANB6(%pc),%fp2 63681da177e4SLinus Torvalds fmov.d ATANB5(%pc),%fp3 63691da177e4SLinus Torvalds 63701da177e4SLinus Torvalds fmul.x %fp1,%fp2 # Z*B6 63711da177e4SLinus Torvalds fmul.x %fp1,%fp3 # Z*B5 63721da177e4SLinus Torvalds 63731da177e4SLinus Torvalds fadd.d ATANB4(%pc),%fp2 # B4+Z*B6 63741da177e4SLinus Torvalds fadd.d ATANB3(%pc),%fp3 # B3+Z*B5 63751da177e4SLinus Torvalds 63761da177e4SLinus Torvalds fmul.x %fp1,%fp2 # Z*(B4+Z*B6) 63771da177e4SLinus Torvalds fmul.x %fp3,%fp1 # Z*(B3+Z*B5) 63781da177e4SLinus Torvalds 63791da177e4SLinus Torvalds fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6) 63801da177e4SLinus Torvalds fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5) 63811da177e4SLinus Torvalds 63821da177e4SLinus Torvalds fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6)) 63831da177e4SLinus Torvalds fmul.x X(%a6),%fp0 # X*Y 63841da177e4SLinus Torvalds 63851da177e4SLinus Torvalds fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))] 63861da177e4SLinus Torvalds 63871da177e4SLinus Torvalds fmul.x %fp1,%fp0 # X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]) 63881da177e4SLinus Torvalds 63891da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2/fp3 63901da177e4SLinus Torvalds 63911da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users rnd mode,prec 63921da177e4SLinus Torvalds fadd.x X(%a6),%fp0 63931da177e4SLinus Torvalds bra t_inx2 63941da177e4SLinus Torvalds 63951da177e4SLinus TorvaldsATANTINY: 63961da177e4SLinus Torvalds#--|X| < 2^(-40), ATAN(X) = X 63971da177e4SLinus Torvalds 63981da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users rnd mode,prec 63991da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 64001da177e4SLinus Torvalds fmov.x X(%a6),%fp0 # last inst - possible exception set 64011da177e4SLinus Torvalds 64021da177e4SLinus Torvalds bra t_catch 64031da177e4SLinus Torvalds 64041da177e4SLinus TorvaldsATANBIG: 64051da177e4SLinus Torvalds#--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE, 64061da177e4SLinus Torvalds#--RETURN SIGN(X)*PI/2 + ATAN(-1/X). 64071da177e4SLinus Torvalds cmp.l %d1,&0x40638000 64081da177e4SLinus Torvalds bgt.w ATANHUGE 64091da177e4SLinus Torvalds 64101da177e4SLinus Torvalds#--APPROXIMATE ATAN(-1/X) BY 64111da177e4SLinus Torvalds#--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X' 64121da177e4SLinus Torvalds#--THIS CAN BE RE-WRITTEN AS 64131da177e4SLinus Torvalds#--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y. 64141da177e4SLinus Torvalds 64151da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2/fp3 64161da177e4SLinus Torvalds 64171da177e4SLinus Torvalds fmov.s &0xBF800000,%fp1 # LOAD -1 64181da177e4SLinus Torvalds fdiv.x %fp0,%fp1 # FP1 IS -1/X 64191da177e4SLinus Torvalds 64201da177e4SLinus Torvalds#--DIVIDE IS STILL CRANKING 64211da177e4SLinus Torvalds 64221da177e4SLinus Torvalds fmov.x %fp1,%fp0 # FP0 IS X' 64231da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FP0 IS Y = X'*X' 64241da177e4SLinus Torvalds fmov.x %fp1,X(%a6) # X IS REALLY X' 64251da177e4SLinus Torvalds 64261da177e4SLinus Torvalds fmov.x %fp0,%fp1 64271da177e4SLinus Torvalds fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 64281da177e4SLinus Torvalds 64291da177e4SLinus Torvalds fmov.d ATANC5(%pc),%fp3 64301da177e4SLinus Torvalds fmov.d ATANC4(%pc),%fp2 64311da177e4SLinus Torvalds 64321da177e4SLinus Torvalds fmul.x %fp1,%fp3 # Z*C5 64331da177e4SLinus Torvalds fmul.x %fp1,%fp2 # Z*B4 64341da177e4SLinus Torvalds 64351da177e4SLinus Torvalds fadd.d ATANC3(%pc),%fp3 # C3+Z*C5 64361da177e4SLinus Torvalds fadd.d ATANC2(%pc),%fp2 # C2+Z*C4 64371da177e4SLinus Torvalds 64381da177e4SLinus Torvalds fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED 64391da177e4SLinus Torvalds fmul.x %fp0,%fp2 # Y*(C2+Z*C4) 64401da177e4SLinus Torvalds 64411da177e4SLinus Torvalds fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5) 64421da177e4SLinus Torvalds fmul.x X(%a6),%fp0 # X'*Y 64431da177e4SLinus Torvalds 64441da177e4SLinus Torvalds fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)] 64451da177e4SLinus Torvalds 64461da177e4SLinus Torvalds fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)] 64471da177e4SLinus Torvalds# ... +[Y*(B2+Z*(B4+Z*B6))]) 64481da177e4SLinus Torvalds fadd.x X(%a6),%fp0 64491da177e4SLinus Torvalds 64501da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2/fp3 64511da177e4SLinus Torvalds 64521da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users rnd mode,prec 64531da177e4SLinus Torvalds tst.b (%a0) 64541da177e4SLinus Torvalds bpl.b pos_big 64551da177e4SLinus Torvalds 64561da177e4SLinus Torvaldsneg_big: 64571da177e4SLinus Torvalds fadd.x NPIBY2(%pc),%fp0 64581da177e4SLinus Torvalds bra t_minx2 64591da177e4SLinus Torvalds 64601da177e4SLinus Torvaldspos_big: 64611da177e4SLinus Torvalds fadd.x PPIBY2(%pc),%fp0 64621da177e4SLinus Torvalds bra t_pinx2 64631da177e4SLinus Torvalds 64641da177e4SLinus TorvaldsATANHUGE: 64651da177e4SLinus Torvalds#--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY 64661da177e4SLinus Torvalds tst.b (%a0) 64671da177e4SLinus Torvalds bpl.b pos_huge 64681da177e4SLinus Torvalds 64691da177e4SLinus Torvaldsneg_huge: 64701da177e4SLinus Torvalds fmov.x NPIBY2(%pc),%fp0 64711da177e4SLinus Torvalds fmov.l %d0,%fpcr 64721da177e4SLinus Torvalds fadd.x PTINY(%pc),%fp0 64731da177e4SLinus Torvalds bra t_minx2 64741da177e4SLinus Torvalds 64751da177e4SLinus Torvaldspos_huge: 64761da177e4SLinus Torvalds fmov.x PPIBY2(%pc),%fp0 64771da177e4SLinus Torvalds fmov.l %d0,%fpcr 64781da177e4SLinus Torvalds fadd.x NTINY(%pc),%fp0 64791da177e4SLinus Torvalds bra t_pinx2 64801da177e4SLinus Torvalds 64811da177e4SLinus Torvalds global satand 64821da177e4SLinus Torvalds#--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT 64831da177e4SLinus Torvaldssatand: 64841da177e4SLinus Torvalds bra t_extdnrm 64851da177e4SLinus Torvalds 64861da177e4SLinus Torvalds######################################################################### 64871da177e4SLinus Torvalds# sasin(): computes the inverse sine of a normalized input # 64881da177e4SLinus Torvalds# sasind(): computes the inverse sine of a denormalized input # 64891da177e4SLinus Torvalds# # 64901da177e4SLinus Torvalds# INPUT *************************************************************** # 64911da177e4SLinus Torvalds# a0 = pointer to extended precision input # 64921da177e4SLinus Torvalds# d0 = round precision,mode # 64931da177e4SLinus Torvalds# # 64941da177e4SLinus Torvalds# OUTPUT ************************************************************** # 64951da177e4SLinus Torvalds# fp0 = arcsin(X) # 64961da177e4SLinus Torvalds# # 64971da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 64981da177e4SLinus Torvalds# The returned result is within 3 ulps in 64 significant bit, # 64991da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 65001da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 65011da177e4SLinus Torvalds# in double precision. # 65021da177e4SLinus Torvalds# # 65031da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 65041da177e4SLinus Torvalds# # 65051da177e4SLinus Torvalds# ASIN # 65061da177e4SLinus Torvalds# 1. If |X| >= 1, go to 3. # 65071da177e4SLinus Torvalds# # 65081da177e4SLinus Torvalds# 2. (|X| < 1) Calculate asin(X) by # 65091da177e4SLinus Torvalds# z := sqrt( [1-X][1+X] ) # 65101da177e4SLinus Torvalds# asin(X) = atan( x / z ). # 65111da177e4SLinus Torvalds# Exit. # 65121da177e4SLinus Torvalds# # 65131da177e4SLinus Torvalds# 3. If |X| > 1, go to 5. # 65141da177e4SLinus Torvalds# # 65151da177e4SLinus Torvalds# 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.# 65161da177e4SLinus Torvalds# # 65171da177e4SLinus Torvalds# 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 65181da177e4SLinus Torvalds# Exit. # 65191da177e4SLinus Torvalds# # 65201da177e4SLinus Torvalds######################################################################### 65211da177e4SLinus Torvalds 65221da177e4SLinus Torvalds global sasin 65231da177e4SLinus Torvaldssasin: 65241da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 65251da177e4SLinus Torvalds 65261da177e4SLinus Torvalds mov.l (%a0),%d1 65271da177e4SLinus Torvalds mov.w 4(%a0),%d1 65281da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 65291da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 65301da177e4SLinus Torvalds bge.b ASINBIG 65311da177e4SLinus Torvalds 65321da177e4SLinus Torvalds# This catch is added here for the '060 QSP. Originally, the call to 65331da177e4SLinus Torvalds# satan() would handle this case by causing the exception which would 65341da177e4SLinus Torvalds# not be caught until gen_except(). Now, with the exceptions being 65351da177e4SLinus Torvalds# detected inside of satan(), the exception would have been handled there 65361da177e4SLinus Torvalds# instead of inside sasin() as expected. 65371da177e4SLinus Torvalds cmp.l %d1,&0x3FD78000 65381da177e4SLinus Torvalds blt.w ASINTINY 65391da177e4SLinus Torvalds 65401da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 1 65411da177e4SLinus Torvalds#--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) ) 65421da177e4SLinus Torvalds 65431da177e4SLinus TorvaldsASINMAIN: 65441da177e4SLinus Torvalds fmov.s &0x3F800000,%fp1 65451da177e4SLinus Torvalds fsub.x %fp0,%fp1 # 1-X 65461da177e4SLinus Torvalds fmovm.x &0x4,-(%sp) # {fp2} 65471da177e4SLinus Torvalds fmov.s &0x3F800000,%fp2 65481da177e4SLinus Torvalds fadd.x %fp0,%fp2 # 1+X 65491da177e4SLinus Torvalds fmul.x %fp2,%fp1 # (1+X)(1-X) 65501da177e4SLinus Torvalds fmovm.x (%sp)+,&0x20 # {fp2} 65511da177e4SLinus Torvalds fsqrt.x %fp1 # SQRT([1-X][1+X]) 65521da177e4SLinus Torvalds fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X]) 65531da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save X/SQRT(...) 65541da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to X/SQRT(...) 65551da177e4SLinus Torvalds bsr satan 65561da177e4SLinus Torvalds add.l &0xc,%sp # clear X/SQRT(...) from stack 65571da177e4SLinus Torvalds bra t_inx2 65581da177e4SLinus Torvalds 65591da177e4SLinus TorvaldsASINBIG: 65601da177e4SLinus Torvalds fabs.x %fp0 # |X| 65611da177e4SLinus Torvalds fcmp.s %fp0,&0x3F800000 65621da177e4SLinus Torvalds fbgt t_operr # cause an operr exception 65631da177e4SLinus Torvalds 65641da177e4SLinus Torvalds#--|X| = 1, ASIN(X) = +- PI/2. 65651da177e4SLinus TorvaldsASINONE: 65661da177e4SLinus Torvalds fmov.x PIBY2(%pc),%fp0 65671da177e4SLinus Torvalds mov.l (%a0),%d1 65681da177e4SLinus Torvalds and.l &0x80000000,%d1 # SIGN BIT OF X 65691da177e4SLinus Torvalds or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT 65701da177e4SLinus Torvalds mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT 65711da177e4SLinus Torvalds fmov.l %d0,%fpcr 65721da177e4SLinus Torvalds fmul.s (%sp)+,%fp0 65731da177e4SLinus Torvalds bra t_inx2 65741da177e4SLinus Torvalds 65751da177e4SLinus Torvalds#--|X| < 2^(-40), ATAN(X) = X 65761da177e4SLinus TorvaldsASINTINY: 65771da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users rnd mode,prec 65781da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 65791da177e4SLinus Torvalds fmov.x (%a0),%fp0 # last inst - possible exception 65801da177e4SLinus Torvalds bra t_catch 65811da177e4SLinus Torvalds 65821da177e4SLinus Torvalds global sasind 65831da177e4SLinus Torvalds#--ASIN(X) = X FOR DENORMALIZED X 65841da177e4SLinus Torvaldssasind: 65851da177e4SLinus Torvalds bra t_extdnrm 65861da177e4SLinus Torvalds 65871da177e4SLinus Torvalds######################################################################### 65881da177e4SLinus Torvalds# sacos(): computes the inverse cosine of a normalized input # 65891da177e4SLinus Torvalds# sacosd(): computes the inverse cosine of a denormalized input # 65901da177e4SLinus Torvalds# # 65911da177e4SLinus Torvalds# INPUT *************************************************************** # 65921da177e4SLinus Torvalds# a0 = pointer to extended precision input # 65931da177e4SLinus Torvalds# d0 = round precision,mode # 65941da177e4SLinus Torvalds# # 65951da177e4SLinus Torvalds# OUTPUT ************************************************************** # 65961da177e4SLinus Torvalds# fp0 = arccos(X) # 65971da177e4SLinus Torvalds# # 65981da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 65991da177e4SLinus Torvalds# The returned result is within 3 ulps in 64 significant bit, # 66001da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 66011da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 66021da177e4SLinus Torvalds# in double precision. # 66031da177e4SLinus Torvalds# # 66041da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 66051da177e4SLinus Torvalds# # 66061da177e4SLinus Torvalds# ACOS # 66071da177e4SLinus Torvalds# 1. If |X| >= 1, go to 3. # 66081da177e4SLinus Torvalds# # 66091da177e4SLinus Torvalds# 2. (|X| < 1) Calculate acos(X) by # 66101da177e4SLinus Torvalds# z := (1-X) / (1+X) # 66111da177e4SLinus Torvalds# acos(X) = 2 * atan( sqrt(z) ). # 66121da177e4SLinus Torvalds# Exit. # 66131da177e4SLinus Torvalds# # 66141da177e4SLinus Torvalds# 3. If |X| > 1, go to 5. # 66151da177e4SLinus Torvalds# # 66161da177e4SLinus Torvalds# 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. # 66171da177e4SLinus Torvalds# # 66181da177e4SLinus Torvalds# 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 66191da177e4SLinus Torvalds# Exit. # 66201da177e4SLinus Torvalds# # 66211da177e4SLinus Torvalds######################################################################### 66221da177e4SLinus Torvalds 66231da177e4SLinus Torvalds global sacos 66241da177e4SLinus Torvaldssacos: 66251da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 66261da177e4SLinus Torvalds 66271da177e4SLinus Torvalds mov.l (%a0),%d1 # pack exp w/ upper 16 fraction 66281da177e4SLinus Torvalds mov.w 4(%a0),%d1 66291da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 66301da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 66311da177e4SLinus Torvalds bge.b ACOSBIG 66321da177e4SLinus Torvalds 66331da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 1 66341da177e4SLinus Torvalds#--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) ) 66351da177e4SLinus Torvalds 66361da177e4SLinus TorvaldsACOSMAIN: 66371da177e4SLinus Torvalds fmov.s &0x3F800000,%fp1 66381da177e4SLinus Torvalds fadd.x %fp0,%fp1 # 1+X 66391da177e4SLinus Torvalds fneg.x %fp0 # -X 66401da177e4SLinus Torvalds fadd.s &0x3F800000,%fp0 # 1-X 66411da177e4SLinus Torvalds fdiv.x %fp1,%fp0 # (1-X)/(1+X) 66421da177e4SLinus Torvalds fsqrt.x %fp0 # SQRT((1-X)/(1+X)) 66431da177e4SLinus Torvalds mov.l %d0,-(%sp) # save original users fpcr 66441da177e4SLinus Torvalds clr.l %d0 66451da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save SQRT(...) to stack 66461da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to sqrt 66471da177e4SLinus Torvalds bsr satan # ATAN(SQRT([1-X]/[1+X])) 66481da177e4SLinus Torvalds add.l &0xc,%sp # clear SQRT(...) from stack 66491da177e4SLinus Torvalds 66501da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore users round prec,mode 66511da177e4SLinus Torvalds fadd.x %fp0,%fp0 # 2 * ATAN( STUFF ) 66521da177e4SLinus Torvalds bra t_pinx2 66531da177e4SLinus Torvalds 66541da177e4SLinus TorvaldsACOSBIG: 66551da177e4SLinus Torvalds fabs.x %fp0 66561da177e4SLinus Torvalds fcmp.s %fp0,&0x3F800000 66571da177e4SLinus Torvalds fbgt t_operr # cause an operr exception 66581da177e4SLinus Torvalds 66591da177e4SLinus Torvalds#--|X| = 1, ACOS(X) = 0 OR PI 66601da177e4SLinus Torvalds tst.b (%a0) # is X positive or negative? 66611da177e4SLinus Torvalds bpl.b ACOSP1 66621da177e4SLinus Torvalds 66631da177e4SLinus Torvalds#--X = -1 66641da177e4SLinus Torvalds#Returns PI and inexact exception 66651da177e4SLinus TorvaldsACOSM1: 66661da177e4SLinus Torvalds fmov.x PI(%pc),%fp0 # load PI 66671da177e4SLinus Torvalds fmov.l %d0,%fpcr # load round mode,prec 66681da177e4SLinus Torvalds fadd.s &0x00800000,%fp0 # add a small value 66691da177e4SLinus Torvalds bra t_pinx2 66701da177e4SLinus Torvalds 66711da177e4SLinus TorvaldsACOSP1: 66721da177e4SLinus Torvalds bra ld_pzero # answer is positive zero 66731da177e4SLinus Torvalds 66741da177e4SLinus Torvalds global sacosd 66751da177e4SLinus Torvalds#--ACOS(X) = PI/2 FOR DENORMALIZED X 66761da177e4SLinus Torvaldssacosd: 66771da177e4SLinus Torvalds fmov.l %d0,%fpcr # load user's rnd mode/prec 66781da177e4SLinus Torvalds fmov.x PIBY2(%pc),%fp0 66791da177e4SLinus Torvalds bra t_pinx2 66801da177e4SLinus Torvalds 66811da177e4SLinus Torvalds######################################################################### 66821da177e4SLinus Torvalds# setox(): computes the exponential for a normalized input # 66831da177e4SLinus Torvalds# setoxd(): computes the exponential for a denormalized input # 66841da177e4SLinus Torvalds# setoxm1(): computes the exponential minus 1 for a normalized input # 66851da177e4SLinus Torvalds# setoxm1d(): computes the exponential minus 1 for a denormalized input # 66861da177e4SLinus Torvalds# # 66871da177e4SLinus Torvalds# INPUT *************************************************************** # 66881da177e4SLinus Torvalds# a0 = pointer to extended precision input # 66891da177e4SLinus Torvalds# d0 = round precision,mode # 66901da177e4SLinus Torvalds# # 66911da177e4SLinus Torvalds# OUTPUT ************************************************************** # 66921da177e4SLinus Torvalds# fp0 = exp(X) or exp(X)-1 # 66931da177e4SLinus Torvalds# # 66941da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 66951da177e4SLinus Torvalds# The returned result is within 0.85 ulps in 64 significant bit, # 66961da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 66971da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 66981da177e4SLinus Torvalds# in double precision. # 66991da177e4SLinus Torvalds# # 67001da177e4SLinus Torvalds# ALGORITHM and IMPLEMENTATION **************************************** # 67011da177e4SLinus Torvalds# # 67021da177e4SLinus Torvalds# setoxd # 67031da177e4SLinus Torvalds# ------ # 67041da177e4SLinus Torvalds# Step 1. Set ans := 1.0 # 67051da177e4SLinus Torvalds# # 67061da177e4SLinus Torvalds# Step 2. Return ans := ans + sign(X)*2^(-126). Exit. # 67071da177e4SLinus Torvalds# Notes: This will always generate one exception -- inexact. # 67081da177e4SLinus Torvalds# # 67091da177e4SLinus Torvalds# # 67101da177e4SLinus Torvalds# setox # 67111da177e4SLinus Torvalds# ----- # 67121da177e4SLinus Torvalds# # 67131da177e4SLinus Torvalds# Step 1. Filter out extreme cases of input argument. # 67141da177e4SLinus Torvalds# 1.1 If |X| >= 2^(-65), go to Step 1.3. # 67151da177e4SLinus Torvalds# 1.2 Go to Step 7. # 67161da177e4SLinus Torvalds# 1.3 If |X| < 16380 log(2), go to Step 2. # 67171da177e4SLinus Torvalds# 1.4 Go to Step 8. # 67181da177e4SLinus Torvalds# Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 67191da177e4SLinus Torvalds# To avoid the use of floating-point comparisons, a # 67201da177e4SLinus Torvalds# compact representation of |X| is used. This format is a # 67211da177e4SLinus Torvalds# 32-bit integer, the upper (more significant) 16 bits # 67221da177e4SLinus Torvalds# are the sign and biased exponent field of |X|; the # 67231da177e4SLinus Torvalds# lower 16 bits are the 16 most significant fraction # 67241da177e4SLinus Torvalds# (including the explicit bit) bits of |X|. Consequently, # 67251da177e4SLinus Torvalds# the comparisons in Steps 1.1 and 1.3 can be performed # 67261da177e4SLinus Torvalds# by integer comparison. Note also that the constant # 67271da177e4SLinus Torvalds# 16380 log(2) used in Step 1.3 is also in the compact # 67281da177e4SLinus Torvalds# form. Thus taking the branch to Step 2 guarantees # 67291da177e4SLinus Torvalds# |X| < 16380 log(2). There is no harm to have a small # 67301da177e4SLinus Torvalds# number of cases where |X| is less than, but close to, # 67311da177e4SLinus Torvalds# 16380 log(2) and the branch to Step 9 is taken. # 67321da177e4SLinus Torvalds# # 67331da177e4SLinus Torvalds# Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 67341da177e4SLinus Torvalds# 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 # 67351da177e4SLinus Torvalds# was taken) # 67361da177e4SLinus Torvalds# 2.2 N := round-to-nearest-integer( X * 64/log2 ). # 67371da177e4SLinus Torvalds# 2.3 Calculate J = N mod 64; so J = 0,1,2,..., # 67381da177e4SLinus Torvalds# or 63. # 67391da177e4SLinus Torvalds# 2.4 Calculate M = (N - J)/64; so N = 64M + J. # 67401da177e4SLinus Torvalds# 2.5 Calculate the address of the stored value of # 67411da177e4SLinus Torvalds# 2^(J/64). # 67421da177e4SLinus Torvalds# 2.6 Create the value Scale = 2^M. # 67431da177e4SLinus Torvalds# Notes: The calculation in 2.2 is really performed by # 67441da177e4SLinus Torvalds# Z := X * constant # 67451da177e4SLinus Torvalds# N := round-to-nearest-integer(Z) # 67461da177e4SLinus Torvalds# where # 67471da177e4SLinus Torvalds# constant := single-precision( 64/log 2 ). # 67481da177e4SLinus Torvalds# # 67491da177e4SLinus Torvalds# Using a single-precision constant avoids memory # 67501da177e4SLinus Torvalds# access. Another effect of using a single-precision # 67511da177e4SLinus Torvalds# "constant" is that the calculated value Z is # 67521da177e4SLinus Torvalds# # 67531da177e4SLinus Torvalds# Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). # 67541da177e4SLinus Torvalds# # 67551da177e4SLinus Torvalds# This error has to be considered later in Steps 3 and 4. # 67561da177e4SLinus Torvalds# # 67571da177e4SLinus Torvalds# Step 3. Calculate X - N*log2/64. # 67581da177e4SLinus Torvalds# 3.1 R := X + N*L1, # 67591da177e4SLinus Torvalds# where L1 := single-precision(-log2/64). # 67601da177e4SLinus Torvalds# 3.2 R := R + N*L2, # 67611da177e4SLinus Torvalds# L2 := extended-precision(-log2/64 - L1).# 67621da177e4SLinus Torvalds# Notes: a) The way L1 and L2 are chosen ensures L1+L2 # 67631da177e4SLinus Torvalds# approximate the value -log2/64 to 88 bits of accuracy. # 67641da177e4SLinus Torvalds# b) N*L1 is exact because N is no longer than 22 bits # 67651da177e4SLinus Torvalds# and L1 is no longer than 24 bits. # 67661da177e4SLinus Torvalds# c) The calculation X+N*L1 is also exact due to # 67671da177e4SLinus Torvalds# cancellation. Thus, R is practically X+N(L1+L2) to full # 67681da177e4SLinus Torvalds# 64 bits. # 67691da177e4SLinus Torvalds# d) It is important to estimate how large can |R| be # 67701da177e4SLinus Torvalds# after Step 3.2. # 67711da177e4SLinus Torvalds# # 67721da177e4SLinus Torvalds# N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) # 67731da177e4SLinus Torvalds# X*64/log2 (1+eps) = N + f, |f| <= 0.5 # 67741da177e4SLinus Torvalds# X*64/log2 - N = f - eps*X 64/log2 # 67751da177e4SLinus Torvalds# X - N*log2/64 = f*log2/64 - eps*X # 67761da177e4SLinus Torvalds# # 67771da177e4SLinus Torvalds# # 67781da177e4SLinus Torvalds# Now |X| <= 16446 log2, thus # 67791da177e4SLinus Torvalds# # 67801da177e4SLinus Torvalds# |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 # 67811da177e4SLinus Torvalds# <= 0.57 log2/64. # 67821da177e4SLinus Torvalds# This bound will be used in Step 4. # 67831da177e4SLinus Torvalds# # 67841da177e4SLinus Torvalds# Step 4. Approximate exp(R)-1 by a polynomial # 67851da177e4SLinus Torvalds# p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) # 67861da177e4SLinus Torvalds# Notes: a) In order to reduce memory access, the coefficients # 67871da177e4SLinus Torvalds# are made as "short" as possible: A1 (which is 1/2), A4 # 67881da177e4SLinus Torvalds# and A5 are single precision; A2 and A3 are double # 67891da177e4SLinus Torvalds# precision. # 67901da177e4SLinus Torvalds# b) Even with the restrictions above, # 67911da177e4SLinus Torvalds# |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. # 67921da177e4SLinus Torvalds# Note that 0.0062 is slightly bigger than 0.57 log2/64. # 67931da177e4SLinus Torvalds# c) To fully utilize the pipeline, p is separated into # 67941da177e4SLinus Torvalds# two independent pieces of roughly equal complexities # 67951da177e4SLinus Torvalds# p = [ R + R*S*(A2 + S*A4) ] + # 67961da177e4SLinus Torvalds# [ S*(A1 + S*(A3 + S*A5)) ] # 67971da177e4SLinus Torvalds# where S = R*R. # 67981da177e4SLinus Torvalds# # 67991da177e4SLinus Torvalds# Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by # 68001da177e4SLinus Torvalds# ans := T + ( T*p + t) # 68011da177e4SLinus Torvalds# where T and t are the stored values for 2^(J/64). # 68021da177e4SLinus Torvalds# Notes: 2^(J/64) is stored as T and t where T+t approximates # 68031da177e4SLinus Torvalds# 2^(J/64) to roughly 85 bits; T is in extended precision # 68041da177e4SLinus Torvalds# and t is in single precision. Note also that T is # 68051da177e4SLinus Torvalds# rounded to 62 bits so that the last two bits of T are # 68061da177e4SLinus Torvalds# zero. The reason for such a special form is that T-1, # 68071da177e4SLinus Torvalds# T-2, and T-8 will all be exact --- a property that will # 68081da177e4SLinus Torvalds# give much more accurate computation of the function # 68091da177e4SLinus Torvalds# EXPM1. # 68101da177e4SLinus Torvalds# # 68111da177e4SLinus Torvalds# Step 6. Reconstruction of exp(X) # 68121da177e4SLinus Torvalds# exp(X) = 2^M * 2^(J/64) * exp(R). # 68131da177e4SLinus Torvalds# 6.1 If AdjFlag = 0, go to 6.3 # 68141da177e4SLinus Torvalds# 6.2 ans := ans * AdjScale # 68151da177e4SLinus Torvalds# 6.3 Restore the user FPCR # 68161da177e4SLinus Torvalds# 6.4 Return ans := ans * Scale. Exit. # 68171da177e4SLinus Torvalds# Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, # 68181da177e4SLinus Torvalds# |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will # 68191da177e4SLinus Torvalds# neither overflow nor underflow. If AdjFlag = 1, that # 68201da177e4SLinus Torvalds# means that # 68211da177e4SLinus Torvalds# X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. # 68221da177e4SLinus Torvalds# Hence, exp(X) may overflow or underflow or neither. # 68231da177e4SLinus Torvalds# When that is the case, AdjScale = 2^(M1) where M1 is # 68241da177e4SLinus Torvalds# approximately M. Thus 6.2 will never cause # 68251da177e4SLinus Torvalds# over/underflow. Possible exception in 6.4 is overflow # 68261da177e4SLinus Torvalds# or underflow. The inexact exception is not generated in # 68271da177e4SLinus Torvalds# 6.4. Although one can argue that the inexact flag # 68281da177e4SLinus Torvalds# should always be raised, to simulate that exception # 68291da177e4SLinus Torvalds# cost to much than the flag is worth in practical uses. # 68301da177e4SLinus Torvalds# # 68311da177e4SLinus Torvalds# Step 7. Return 1 + X. # 68321da177e4SLinus Torvalds# 7.1 ans := X # 68331da177e4SLinus Torvalds# 7.2 Restore user FPCR. # 68341da177e4SLinus Torvalds# 7.3 Return ans := 1 + ans. Exit # 68351da177e4SLinus Torvalds# Notes: For non-zero X, the inexact exception will always be # 68361da177e4SLinus Torvalds# raised by 7.3. That is the only exception raised by 7.3.# 68371da177e4SLinus Torvalds# Note also that we use the FMOVEM instruction to move X # 68381da177e4SLinus Torvalds# in Step 7.1 to avoid unnecessary trapping. (Although # 68391da177e4SLinus Torvalds# the FMOVEM may not seem relevant since X is normalized, # 68401da177e4SLinus Torvalds# the precaution will be useful in the library version of # 68411da177e4SLinus Torvalds# this code where the separate entry for denormalized # 68421da177e4SLinus Torvalds# inputs will be done away with.) # 68431da177e4SLinus Torvalds# # 68441da177e4SLinus Torvalds# Step 8. Handle exp(X) where |X| >= 16380log2. # 68451da177e4SLinus Torvalds# 8.1 If |X| > 16480 log2, go to Step 9. # 68461da177e4SLinus Torvalds# (mimic 2.2 - 2.6) # 68471da177e4SLinus Torvalds# 8.2 N := round-to-integer( X * 64/log2 ) # 68481da177e4SLinus Torvalds# 8.3 Calculate J = N mod 64, J = 0,1,...,63 # 68491da177e4SLinus Torvalds# 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, # 68501da177e4SLinus Torvalds# AdjFlag := 1. # 68511da177e4SLinus Torvalds# 8.5 Calculate the address of the stored value # 68521da177e4SLinus Torvalds# 2^(J/64). # 68531da177e4SLinus Torvalds# 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. # 68541da177e4SLinus Torvalds# 8.7 Go to Step 3. # 68551da177e4SLinus Torvalds# Notes: Refer to notes for 2.2 - 2.6. # 68561da177e4SLinus Torvalds# # 68571da177e4SLinus Torvalds# Step 9. Handle exp(X), |X| > 16480 log2. # 68581da177e4SLinus Torvalds# 9.1 If X < 0, go to 9.3 # 68591da177e4SLinus Torvalds# 9.2 ans := Huge, go to 9.4 # 68601da177e4SLinus Torvalds# 9.3 ans := Tiny. # 68611da177e4SLinus Torvalds# 9.4 Restore user FPCR. # 68621da177e4SLinus Torvalds# 9.5 Return ans := ans * ans. Exit. # 68631da177e4SLinus Torvalds# Notes: Exp(X) will surely overflow or underflow, depending on # 68641da177e4SLinus Torvalds# X's sign. "Huge" and "Tiny" are respectively large/tiny # 68651da177e4SLinus Torvalds# extended-precision numbers whose square over/underflow # 68661da177e4SLinus Torvalds# with an inexact result. Thus, 9.5 always raises the # 68671da177e4SLinus Torvalds# inexact together with either overflow or underflow. # 68681da177e4SLinus Torvalds# # 68691da177e4SLinus Torvalds# setoxm1d # 68701da177e4SLinus Torvalds# -------- # 68711da177e4SLinus Torvalds# # 68721da177e4SLinus Torvalds# Step 1. Set ans := 0 # 68731da177e4SLinus Torvalds# # 68741da177e4SLinus Torvalds# Step 2. Return ans := X + ans. Exit. # 68751da177e4SLinus Torvalds# Notes: This will return X with the appropriate rounding # 68761da177e4SLinus Torvalds# precision prescribed by the user FPCR. # 68771da177e4SLinus Torvalds# # 68781da177e4SLinus Torvalds# setoxm1 # 68791da177e4SLinus Torvalds# ------- # 68801da177e4SLinus Torvalds# # 68811da177e4SLinus Torvalds# Step 1. Check |X| # 68821da177e4SLinus Torvalds# 1.1 If |X| >= 1/4, go to Step 1.3. # 68831da177e4SLinus Torvalds# 1.2 Go to Step 7. # 68841da177e4SLinus Torvalds# 1.3 If |X| < 70 log(2), go to Step 2. # 68851da177e4SLinus Torvalds# 1.4 Go to Step 10. # 68861da177e4SLinus Torvalds# Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 68871da177e4SLinus Torvalds# However, it is conceivable |X| can be small very often # 68881da177e4SLinus Torvalds# because EXPM1 is intended to evaluate exp(X)-1 # 68891da177e4SLinus Torvalds# accurately when |X| is small. For further details on # 68901da177e4SLinus Torvalds# the comparisons, see the notes on Step 1 of setox. # 68911da177e4SLinus Torvalds# # 68921da177e4SLinus Torvalds# Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 68931da177e4SLinus Torvalds# 2.1 N := round-to-nearest-integer( X * 64/log2 ). # 68941da177e4SLinus Torvalds# 2.2 Calculate J = N mod 64; so J = 0,1,2,..., # 68951da177e4SLinus Torvalds# or 63. # 68961da177e4SLinus Torvalds# 2.3 Calculate M = (N - J)/64; so N = 64M + J. # 68971da177e4SLinus Torvalds# 2.4 Calculate the address of the stored value of # 68981da177e4SLinus Torvalds# 2^(J/64). # 68991da177e4SLinus Torvalds# 2.5 Create the values Sc = 2^M and # 69001da177e4SLinus Torvalds# OnebySc := -2^(-M). # 69011da177e4SLinus Torvalds# Notes: See the notes on Step 2 of setox. # 69021da177e4SLinus Torvalds# # 69031da177e4SLinus Torvalds# Step 3. Calculate X - N*log2/64. # 69041da177e4SLinus Torvalds# 3.1 R := X + N*L1, # 69051da177e4SLinus Torvalds# where L1 := single-precision(-log2/64). # 69061da177e4SLinus Torvalds# 3.2 R := R + N*L2, # 69071da177e4SLinus Torvalds# L2 := extended-precision(-log2/64 - L1).# 69081da177e4SLinus Torvalds# Notes: Applying the analysis of Step 3 of setox in this case # 69091da177e4SLinus Torvalds# shows that |R| <= 0.0055 (note that |X| <= 70 log2 in # 69101da177e4SLinus Torvalds# this case). # 69111da177e4SLinus Torvalds# # 69121da177e4SLinus Torvalds# Step 4. Approximate exp(R)-1 by a polynomial # 69131da177e4SLinus Torvalds# p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) # 69141da177e4SLinus Torvalds# Notes: a) In order to reduce memory access, the coefficients # 69151da177e4SLinus Torvalds# are made as "short" as possible: A1 (which is 1/2), A5 # 69161da177e4SLinus Torvalds# and A6 are single precision; A2, A3 and A4 are double # 69171da177e4SLinus Torvalds# precision. # 69181da177e4SLinus Torvalds# b) Even with the restriction above, # 69191da177e4SLinus Torvalds# |p - (exp(R)-1)| < |R| * 2^(-72.7) # 69201da177e4SLinus Torvalds# for all |R| <= 0.0055. # 69211da177e4SLinus Torvalds# c) To fully utilize the pipeline, p is separated into # 69221da177e4SLinus Torvalds# two independent pieces of roughly equal complexity # 69231da177e4SLinus Torvalds# p = [ R*S*(A2 + S*(A4 + S*A6)) ] + # 69241da177e4SLinus Torvalds# [ R + S*(A1 + S*(A3 + S*A5)) ] # 69251da177e4SLinus Torvalds# where S = R*R. # 69261da177e4SLinus Torvalds# # 69271da177e4SLinus Torvalds# Step 5. Compute 2^(J/64)*p by # 69281da177e4SLinus Torvalds# p := T*p # 69291da177e4SLinus Torvalds# where T and t are the stored values for 2^(J/64). # 69301da177e4SLinus Torvalds# Notes: 2^(J/64) is stored as T and t where T+t approximates # 69311da177e4SLinus Torvalds# 2^(J/64) to roughly 85 bits; T is in extended precision # 69321da177e4SLinus Torvalds# and t is in single precision. Note also that T is # 69331da177e4SLinus Torvalds# rounded to 62 bits so that the last two bits of T are # 69341da177e4SLinus Torvalds# zero. The reason for such a special form is that T-1, # 69351da177e4SLinus Torvalds# T-2, and T-8 will all be exact --- a property that will # 69361da177e4SLinus Torvalds# be exploited in Step 6 below. The total relative error # 69371da177e4SLinus Torvalds# in p is no bigger than 2^(-67.7) compared to the final # 69381da177e4SLinus Torvalds# result. # 69391da177e4SLinus Torvalds# # 69401da177e4SLinus Torvalds# Step 6. Reconstruction of exp(X)-1 # 69411da177e4SLinus Torvalds# exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). # 69421da177e4SLinus Torvalds# 6.1 If M <= 63, go to Step 6.3. # 69431da177e4SLinus Torvalds# 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 # 69441da177e4SLinus Torvalds# 6.3 If M >= -3, go to 6.5. # 69451da177e4SLinus Torvalds# 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 # 69461da177e4SLinus Torvalds# 6.5 ans := (T + OnebySc) + (p + t). # 69471da177e4SLinus Torvalds# 6.6 Restore user FPCR. # 69481da177e4SLinus Torvalds# 6.7 Return ans := Sc * ans. Exit. # 69491da177e4SLinus Torvalds# Notes: The various arrangements of the expressions give # 69501da177e4SLinus Torvalds# accurate evaluations. # 69511da177e4SLinus Torvalds# # 69521da177e4SLinus Torvalds# Step 7. exp(X)-1 for |X| < 1/4. # 69531da177e4SLinus Torvalds# 7.1 If |X| >= 2^(-65), go to Step 9. # 69541da177e4SLinus Torvalds# 7.2 Go to Step 8. # 69551da177e4SLinus Torvalds# # 69561da177e4SLinus Torvalds# Step 8. Calculate exp(X)-1, |X| < 2^(-65). # 69571da177e4SLinus Torvalds# 8.1 If |X| < 2^(-16312), goto 8.3 # 69581da177e4SLinus Torvalds# 8.2 Restore FPCR; return ans := X - 2^(-16382). # 69591da177e4SLinus Torvalds# Exit. # 69601da177e4SLinus Torvalds# 8.3 X := X * 2^(140). # 69611da177e4SLinus Torvalds# 8.4 Restore FPCR; ans := ans - 2^(-16382). # 69621da177e4SLinus Torvalds# Return ans := ans*2^(140). Exit # 69631da177e4SLinus Torvalds# Notes: The idea is to return "X - tiny" under the user # 69641da177e4SLinus Torvalds# precision and rounding modes. To avoid unnecessary # 69651da177e4SLinus Torvalds# inefficiency, we stay away from denormalized numbers # 69661da177e4SLinus Torvalds# the best we can. For |X| >= 2^(-16312), the # 69671da177e4SLinus Torvalds# straightforward 8.2 generates the inexact exception as # 69681da177e4SLinus Torvalds# the case warrants. # 69691da177e4SLinus Torvalds# # 69701da177e4SLinus Torvalds# Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial # 69711da177e4SLinus Torvalds# p = X + X*X*(B1 + X*(B2 + ... + X*B12)) # 69721da177e4SLinus Torvalds# Notes: a) In order to reduce memory access, the coefficients # 69731da177e4SLinus Torvalds# are made as "short" as possible: B1 (which is 1/2), B9 # 69741da177e4SLinus Torvalds# to B12 are single precision; B3 to B8 are double # 69751da177e4SLinus Torvalds# precision; and B2 is double extended. # 69761da177e4SLinus Torvalds# b) Even with the restriction above, # 69771da177e4SLinus Torvalds# |p - (exp(X)-1)| < |X| 2^(-70.6) # 69781da177e4SLinus Torvalds# for all |X| <= 0.251. # 69791da177e4SLinus Torvalds# Note that 0.251 is slightly bigger than 1/4. # 69801da177e4SLinus Torvalds# c) To fully preserve accuracy, the polynomial is # 69811da177e4SLinus Torvalds# computed as # 69821da177e4SLinus Torvalds# X + ( S*B1 + Q ) where S = X*X and # 69831da177e4SLinus Torvalds# Q = X*S*(B2 + X*(B3 + ... + X*B12)) # 69841da177e4SLinus Torvalds# d) To fully utilize the pipeline, Q is separated into # 69851da177e4SLinus Torvalds# two independent pieces of roughly equal complexity # 69861da177e4SLinus Torvalds# Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + # 69871da177e4SLinus Torvalds# [ S*S*(B3 + S*(B5 + ... + S*B11)) ] # 69881da177e4SLinus Torvalds# # 69891da177e4SLinus Torvalds# Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. # 69901da177e4SLinus Torvalds# 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all # 69911da177e4SLinus Torvalds# practical purposes. Therefore, go to Step 1 of setox. # 69921da177e4SLinus Torvalds# 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical # 69931da177e4SLinus Torvalds# purposes. # 69941da177e4SLinus Torvalds# ans := -1 # 69951da177e4SLinus Torvalds# Restore user FPCR # 69961da177e4SLinus Torvalds# Return ans := ans + 2^(-126). Exit. # 69971da177e4SLinus Torvalds# Notes: 10.2 will always create an inexact and return -1 + tiny # 69981da177e4SLinus Torvalds# in the user rounding precision and mode. # 69991da177e4SLinus Torvalds# # 70001da177e4SLinus Torvalds######################################################################### 70011da177e4SLinus Torvalds 70021da177e4SLinus TorvaldsL2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000 70031da177e4SLinus Torvalds 70041da177e4SLinus TorvaldsEEXPA3: long 0x3FA55555,0x55554CC1 70051da177e4SLinus TorvaldsEEXPA2: long 0x3FC55555,0x55554A54 70061da177e4SLinus Torvalds 70071da177e4SLinus TorvaldsEM1A4: long 0x3F811111,0x11174385 70081da177e4SLinus TorvaldsEM1A3: long 0x3FA55555,0x55554F5A 70091da177e4SLinus Torvalds 70101da177e4SLinus TorvaldsEM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000 70111da177e4SLinus Torvalds 70121da177e4SLinus TorvaldsEM1B8: long 0x3EC71DE3,0xA5774682 70131da177e4SLinus TorvaldsEM1B7: long 0x3EFA01A0,0x19D7CB68 70141da177e4SLinus Torvalds 70151da177e4SLinus TorvaldsEM1B6: long 0x3F2A01A0,0x1A019DF3 70161da177e4SLinus TorvaldsEM1B5: long 0x3F56C16C,0x16C170E2 70171da177e4SLinus Torvalds 70181da177e4SLinus TorvaldsEM1B4: long 0x3F811111,0x11111111 70191da177e4SLinus TorvaldsEM1B3: long 0x3FA55555,0x55555555 70201da177e4SLinus Torvalds 70211da177e4SLinus TorvaldsEM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB 70221da177e4SLinus Torvalds long 0x00000000 70231da177e4SLinus Torvalds 70241da177e4SLinus TorvaldsTWO140: long 0x48B00000,0x00000000 70251da177e4SLinus TorvaldsTWON140: 70261da177e4SLinus Torvalds long 0x37300000,0x00000000 70271da177e4SLinus Torvalds 70281da177e4SLinus TorvaldsEEXPTBL: 70291da177e4SLinus Torvalds long 0x3FFF0000,0x80000000,0x00000000,0x00000000 70301da177e4SLinus Torvalds long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B 70311da177e4SLinus Torvalds long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9 70321da177e4SLinus Torvalds long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369 70331da177e4SLinus Torvalds long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C 70341da177e4SLinus Torvalds long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F 70351da177e4SLinus Torvalds long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729 70361da177e4SLinus Torvalds long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF 70371da177e4SLinus Torvalds long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF 70381da177e4SLinus Torvalds long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA 70391da177e4SLinus Torvalds long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051 70401da177e4SLinus Torvalds long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029 70411da177e4SLinus Torvalds long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494 70421da177e4SLinus Torvalds long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0 70431da177e4SLinus Torvalds long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D 70441da177e4SLinus Torvalds long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537 70451da177e4SLinus Torvalds long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD 70461da177e4SLinus Torvalds long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087 70471da177e4SLinus Torvalds long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818 70481da177e4SLinus Torvalds long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D 70491da177e4SLinus Torvalds long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890 70501da177e4SLinus Torvalds long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C 70511da177e4SLinus Torvalds long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05 70521da177e4SLinus Torvalds long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126 70531da177e4SLinus Torvalds long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140 70541da177e4SLinus Torvalds long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA 70551da177e4SLinus Torvalds long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A 70561da177e4SLinus Torvalds long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC 70571da177e4SLinus Torvalds long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC 70581da177e4SLinus Torvalds long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610 70591da177e4SLinus Torvalds long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90 70601da177e4SLinus Torvalds long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A 70611da177e4SLinus Torvalds long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13 70621da177e4SLinus Torvalds long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30 70631da177e4SLinus Torvalds long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC 70641da177e4SLinus Torvalds long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6 70651da177e4SLinus Torvalds long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70 70661da177e4SLinus Torvalds long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518 70671da177e4SLinus Torvalds long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41 70681da177e4SLinus Torvalds long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B 70691da177e4SLinus Torvalds long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568 70701da177e4SLinus Torvalds long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E 70711da177e4SLinus Torvalds long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03 70721da177e4SLinus Torvalds long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D 70731da177e4SLinus Torvalds long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4 70741da177e4SLinus Torvalds long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C 70751da177e4SLinus Torvalds long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9 70761da177e4SLinus Torvalds long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21 70771da177e4SLinus Torvalds long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F 70781da177e4SLinus Torvalds long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F 70791da177e4SLinus Torvalds long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207 70801da177e4SLinus Torvalds long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175 70811da177e4SLinus Torvalds long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B 70821da177e4SLinus Torvalds long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5 70831da177e4SLinus Torvalds long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A 70841da177e4SLinus Torvalds long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22 70851da177e4SLinus Torvalds long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945 70861da177e4SLinus Torvalds long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B 70871da177e4SLinus Torvalds long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3 70881da177e4SLinus Torvalds long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05 70891da177e4SLinus Torvalds long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19 70901da177e4SLinus Torvalds long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5 70911da177e4SLinus Torvalds long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22 70921da177e4SLinus Torvalds long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A 70931da177e4SLinus Torvalds 70941da177e4SLinus Torvalds set ADJFLAG,L_SCR2 70951da177e4SLinus Torvalds set SCALE,FP_SCR0 70961da177e4SLinus Torvalds set ADJSCALE,FP_SCR1 70971da177e4SLinus Torvalds set SC,FP_SCR0 70981da177e4SLinus Torvalds set ONEBYSC,FP_SCR1 70991da177e4SLinus Torvalds 71001da177e4SLinus Torvalds global setox 71011da177e4SLinus Torvaldssetox: 71021da177e4SLinus Torvalds#--entry point for EXP(X), here X is finite, non-zero, and not NaN's 71031da177e4SLinus Torvalds 71041da177e4SLinus Torvalds#--Step 1. 71051da177e4SLinus Torvalds mov.l (%a0),%d1 # load part of input X 71061da177e4SLinus Torvalds and.l &0x7FFF0000,%d1 # biased expo. of X 71071da177e4SLinus Torvalds cmp.l %d1,&0x3FBE0000 # 2^(-65) 71081da177e4SLinus Torvalds bge.b EXPC1 # normal case 71091da177e4SLinus Torvalds bra EXPSM 71101da177e4SLinus Torvalds 71111da177e4SLinus TorvaldsEXPC1: 71121da177e4SLinus Torvalds#--The case |X| >= 2^(-65) 71131da177e4SLinus Torvalds mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 71141da177e4SLinus Torvalds cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits 71151da177e4SLinus Torvalds blt.b EXPMAIN # normal case 71161da177e4SLinus Torvalds bra EEXPBIG 71171da177e4SLinus Torvalds 71181da177e4SLinus TorvaldsEXPMAIN: 71191da177e4SLinus Torvalds#--Step 2. 71201da177e4SLinus Torvalds#--This is the normal branch: 2^(-65) <= |X| < 16380 log2. 71211da177e4SLinus Torvalds fmov.x (%a0),%fp0 # load input from (a0) 71221da177e4SLinus Torvalds 71231da177e4SLinus Torvalds fmov.x %fp0,%fp1 71241da177e4SLinus Torvalds fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 71251da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 71261da177e4SLinus Torvalds mov.l &0,ADJFLAG(%a6) 71271da177e4SLinus Torvalds fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 71281da177e4SLinus Torvalds lea EEXPTBL(%pc),%a1 71291da177e4SLinus Torvalds fmov.l %d1,%fp0 # convert to floating-format 71301da177e4SLinus Torvalds 71311da177e4SLinus Torvalds mov.l %d1,L_SCR1(%a6) # save N temporarily 71321da177e4SLinus Torvalds and.l &0x3F,%d1 # D0 is J = N mod 64 71331da177e4SLinus Torvalds lsl.l &4,%d1 71341da177e4SLinus Torvalds add.l %d1,%a1 # address of 2^(J/64) 71351da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d1 71361da177e4SLinus Torvalds asr.l &6,%d1 # D0 is M 71371da177e4SLinus Torvalds add.w &0x3FFF,%d1 # biased expo. of 2^(M) 71381da177e4SLinus Torvalds mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB 71391da177e4SLinus Torvalds 71401da177e4SLinus TorvaldsEXPCONT1: 71411da177e4SLinus Torvalds#--Step 3. 71421da177e4SLinus Torvalds#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 71431da177e4SLinus Torvalds#--a0 points to 2^(J/64), D0 is biased expo. of 2^(M) 71441da177e4SLinus Torvalds fmov.x %fp0,%fp2 71451da177e4SLinus Torvalds fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 71461da177e4SLinus Torvalds fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 71471da177e4SLinus Torvalds fadd.x %fp1,%fp0 # X + N*L1 71481da177e4SLinus Torvalds fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 71491da177e4SLinus Torvalds 71501da177e4SLinus Torvalds#--Step 4. 71511da177e4SLinus Torvalds#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 71521da177e4SLinus Torvalds#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) 71531da177e4SLinus Torvalds#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R 71541da177e4SLinus Torvalds#--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))] 71551da177e4SLinus Torvalds 71561da177e4SLinus Torvalds fmov.x %fp0,%fp1 71571da177e4SLinus Torvalds fmul.x %fp1,%fp1 # fp1 IS S = R*R 71581da177e4SLinus Torvalds 71591da177e4SLinus Torvalds fmov.s &0x3AB60B70,%fp2 # fp2 IS A5 71601da177e4SLinus Torvalds 71611da177e4SLinus Torvalds fmul.x %fp1,%fp2 # fp2 IS S*A5 71621da177e4SLinus Torvalds fmov.x %fp1,%fp3 71631da177e4SLinus Torvalds fmul.s &0x3C088895,%fp3 # fp3 IS S*A4 71641da177e4SLinus Torvalds 71651da177e4SLinus Torvalds fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5 71661da177e4SLinus Torvalds fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4 71671da177e4SLinus Torvalds 71681da177e4SLinus Torvalds fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5) 71691da177e4SLinus Torvalds mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended 71701da177e4SLinus Torvalds mov.l &0x80000000,SCALE+4(%a6) 71711da177e4SLinus Torvalds clr.l SCALE+8(%a6) 71721da177e4SLinus Torvalds 71731da177e4SLinus Torvalds fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4) 71741da177e4SLinus Torvalds 71751da177e4SLinus Torvalds fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5) 71761da177e4SLinus Torvalds fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4) 71771da177e4SLinus Torvalds 71781da177e4SLinus Torvalds fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5)) 71791da177e4SLinus Torvalds fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4), 71801da177e4SLinus Torvalds 71811da177e4SLinus Torvalds fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64) 71821da177e4SLinus Torvalds fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1 71831da177e4SLinus Torvalds 71841da177e4SLinus Torvalds#--Step 5 71851da177e4SLinus Torvalds#--final reconstruction process 71861da177e4SLinus Torvalds#--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) ) 71871da177e4SLinus Torvalds 71881da177e4SLinus Torvalds fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1) 71891da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 71901da177e4SLinus Torvalds fadd.s (%a1),%fp0 # accurate 2^(J/64) 71911da177e4SLinus Torvalds 71921da177e4SLinus Torvalds fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*... 71931da177e4SLinus Torvalds mov.l ADJFLAG(%a6),%d1 71941da177e4SLinus Torvalds 71951da177e4SLinus Torvalds#--Step 6 71961da177e4SLinus Torvalds tst.l %d1 71971da177e4SLinus Torvalds beq.b NORMAL 71981da177e4SLinus TorvaldsADJUST: 71991da177e4SLinus Torvalds fmul.x ADJSCALE(%a6),%fp0 72001da177e4SLinus TorvaldsNORMAL: 72011da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore user FPCR 72021da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 72031da177e4SLinus Torvalds fmul.x SCALE(%a6),%fp0 # multiply 2^(M) 72041da177e4SLinus Torvalds bra t_catch 72051da177e4SLinus Torvalds 72061da177e4SLinus TorvaldsEXPSM: 72071da177e4SLinus Torvalds#--Step 7 72081da177e4SLinus Torvalds fmovm.x (%a0),&0x80 # load X 72091da177e4SLinus Torvalds fmov.l %d0,%fpcr 72101da177e4SLinus Torvalds fadd.s &0x3F800000,%fp0 # 1+X in user mode 72111da177e4SLinus Torvalds bra t_pinx2 72121da177e4SLinus Torvalds 72131da177e4SLinus TorvaldsEEXPBIG: 72141da177e4SLinus Torvalds#--Step 8 72151da177e4SLinus Torvalds cmp.l %d1,&0x400CB27C # 16480 log2 72161da177e4SLinus Torvalds bgt.b EXP2BIG 72171da177e4SLinus Torvalds#--Steps 8.2 -- 8.6 72181da177e4SLinus Torvalds fmov.x (%a0),%fp0 # load input from (a0) 72191da177e4SLinus Torvalds 72201da177e4SLinus Torvalds fmov.x %fp0,%fp1 72211da177e4SLinus Torvalds fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 72221da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 72231da177e4SLinus Torvalds mov.l &1,ADJFLAG(%a6) 72241da177e4SLinus Torvalds fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 72251da177e4SLinus Torvalds lea EEXPTBL(%pc),%a1 72261da177e4SLinus Torvalds fmov.l %d1,%fp0 # convert to floating-format 72271da177e4SLinus Torvalds mov.l %d1,L_SCR1(%a6) # save N temporarily 72281da177e4SLinus Torvalds and.l &0x3F,%d1 # D0 is J = N mod 64 72291da177e4SLinus Torvalds lsl.l &4,%d1 72301da177e4SLinus Torvalds add.l %d1,%a1 # address of 2^(J/64) 72311da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d1 72321da177e4SLinus Torvalds asr.l &6,%d1 # D0 is K 72331da177e4SLinus Torvalds mov.l %d1,L_SCR1(%a6) # save K temporarily 72341da177e4SLinus Torvalds asr.l &1,%d1 # D0 is M1 72351da177e4SLinus Torvalds sub.l %d1,L_SCR1(%a6) # a1 is M 72361da177e4SLinus Torvalds add.w &0x3FFF,%d1 # biased expo. of 2^(M1) 72371da177e4SLinus Torvalds mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1) 72381da177e4SLinus Torvalds mov.l &0x80000000,ADJSCALE+4(%a6) 72391da177e4SLinus Torvalds clr.l ADJSCALE+8(%a6) 72401da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d1 # D0 is M 72411da177e4SLinus Torvalds add.w &0x3FFF,%d1 # biased expo. of 2^(M) 72421da177e4SLinus Torvalds bra.w EXPCONT1 # go back to Step 3 72431da177e4SLinus Torvalds 72441da177e4SLinus TorvaldsEXP2BIG: 72451da177e4SLinus Torvalds#--Step 9 72461da177e4SLinus Torvalds tst.b (%a0) # is X positive or negative? 72471da177e4SLinus Torvalds bmi t_unfl2 72481da177e4SLinus Torvalds bra t_ovfl2 72491da177e4SLinus Torvalds 72501da177e4SLinus Torvalds global setoxd 72511da177e4SLinus Torvaldssetoxd: 72521da177e4SLinus Torvalds#--entry point for EXP(X), X is denormalized 72531da177e4SLinus Torvalds mov.l (%a0),-(%sp) 72541da177e4SLinus Torvalds andi.l &0x80000000,(%sp) 72551da177e4SLinus Torvalds ori.l &0x00800000,(%sp) # sign(X)*2^(-126) 72561da177e4SLinus Torvalds 72571da177e4SLinus Torvalds fmov.s &0x3F800000,%fp0 72581da177e4SLinus Torvalds 72591da177e4SLinus Torvalds fmov.l %d0,%fpcr 72601da177e4SLinus Torvalds fadd.s (%sp)+,%fp0 72611da177e4SLinus Torvalds bra t_pinx2 72621da177e4SLinus Torvalds 72631da177e4SLinus Torvalds global setoxm1 72641da177e4SLinus Torvaldssetoxm1: 72651da177e4SLinus Torvalds#--entry point for EXPM1(X), here X is finite, non-zero, non-NaN 72661da177e4SLinus Torvalds 72671da177e4SLinus Torvalds#--Step 1. 72681da177e4SLinus Torvalds#--Step 1.1 72691da177e4SLinus Torvalds mov.l (%a0),%d1 # load part of input X 72701da177e4SLinus Torvalds and.l &0x7FFF0000,%d1 # biased expo. of X 72711da177e4SLinus Torvalds cmp.l %d1,&0x3FFD0000 # 1/4 72721da177e4SLinus Torvalds bge.b EM1CON1 # |X| >= 1/4 72731da177e4SLinus Torvalds bra EM1SM 72741da177e4SLinus Torvalds 72751da177e4SLinus TorvaldsEM1CON1: 72761da177e4SLinus Torvalds#--Step 1.3 72771da177e4SLinus Torvalds#--The case |X| >= 1/4 72781da177e4SLinus Torvalds mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 72791da177e4SLinus Torvalds cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits 72801da177e4SLinus Torvalds ble.b EM1MAIN # 1/4 <= |X| <= 70log2 72811da177e4SLinus Torvalds bra EM1BIG 72821da177e4SLinus Torvalds 72831da177e4SLinus TorvaldsEM1MAIN: 72841da177e4SLinus Torvalds#--Step 2. 72851da177e4SLinus Torvalds#--This is the case: 1/4 <= |X| <= 70 log2. 72861da177e4SLinus Torvalds fmov.x (%a0),%fp0 # load input from (a0) 72871da177e4SLinus Torvalds 72881da177e4SLinus Torvalds fmov.x %fp0,%fp1 72891da177e4SLinus Torvalds fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 72901da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 72911da177e4SLinus Torvalds fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 72921da177e4SLinus Torvalds lea EEXPTBL(%pc),%a1 72931da177e4SLinus Torvalds fmov.l %d1,%fp0 # convert to floating-format 72941da177e4SLinus Torvalds 72951da177e4SLinus Torvalds mov.l %d1,L_SCR1(%a6) # save N temporarily 72961da177e4SLinus Torvalds and.l &0x3F,%d1 # D0 is J = N mod 64 72971da177e4SLinus Torvalds lsl.l &4,%d1 72981da177e4SLinus Torvalds add.l %d1,%a1 # address of 2^(J/64) 72991da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d1 73001da177e4SLinus Torvalds asr.l &6,%d1 # D0 is M 73011da177e4SLinus Torvalds mov.l %d1,L_SCR1(%a6) # save a copy of M 73021da177e4SLinus Torvalds 73031da177e4SLinus Torvalds#--Step 3. 73041da177e4SLinus Torvalds#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 73051da177e4SLinus Torvalds#--a0 points to 2^(J/64), D0 and a1 both contain M 73061da177e4SLinus Torvalds fmov.x %fp0,%fp2 73071da177e4SLinus Torvalds fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 73081da177e4SLinus Torvalds fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 73091da177e4SLinus Torvalds fadd.x %fp1,%fp0 # X + N*L1 73101da177e4SLinus Torvalds fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 73111da177e4SLinus Torvalds add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M 73121da177e4SLinus Torvalds 73131da177e4SLinus Torvalds#--Step 4. 73141da177e4SLinus Torvalds#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 73151da177e4SLinus Torvalds#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6))))) 73161da177e4SLinus Torvalds#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R 73171da177e4SLinus Torvalds#--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))] 73181da177e4SLinus Torvalds 73191da177e4SLinus Torvalds fmov.x %fp0,%fp1 73201da177e4SLinus Torvalds fmul.x %fp1,%fp1 # fp1 IS S = R*R 73211da177e4SLinus Torvalds 73221da177e4SLinus Torvalds fmov.s &0x3950097B,%fp2 # fp2 IS a6 73231da177e4SLinus Torvalds 73241da177e4SLinus Torvalds fmul.x %fp1,%fp2 # fp2 IS S*A6 73251da177e4SLinus Torvalds fmov.x %fp1,%fp3 73261da177e4SLinus Torvalds fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5 73271da177e4SLinus Torvalds 73281da177e4SLinus Torvalds fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6 73291da177e4SLinus Torvalds fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5 73301da177e4SLinus Torvalds mov.w %d1,SC(%a6) # SC is 2^(M) in extended 73311da177e4SLinus Torvalds mov.l &0x80000000,SC+4(%a6) 73321da177e4SLinus Torvalds clr.l SC+8(%a6) 73331da177e4SLinus Torvalds 73341da177e4SLinus Torvalds fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6) 73351da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d1 # D0 is M 73361da177e4SLinus Torvalds neg.w %d1 # D0 is -M 73371da177e4SLinus Torvalds fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5) 73381da177e4SLinus Torvalds add.w &0x3FFF,%d1 # biased expo. of 2^(-M) 73391da177e4SLinus Torvalds fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6) 73401da177e4SLinus Torvalds fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5) 73411da177e4SLinus Torvalds 73421da177e4SLinus Torvalds fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6)) 73431da177e4SLinus Torvalds or.w &0x8000,%d1 # signed/expo. of -2^(-M) 73441da177e4SLinus Torvalds mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M) 73451da177e4SLinus Torvalds mov.l &0x80000000,ONEBYSC+4(%a6) 73461da177e4SLinus Torvalds clr.l ONEBYSC+8(%a6) 73471da177e4SLinus Torvalds fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5)) 73481da177e4SLinus Torvalds 73491da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6)) 73501da177e4SLinus Torvalds fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5)) 73511da177e4SLinus Torvalds 73521da177e4SLinus Torvalds fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1 73531da177e4SLinus Torvalds 73541da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 73551da177e4SLinus Torvalds 73561da177e4SLinus Torvalds#--Step 5 73571da177e4SLinus Torvalds#--Compute 2^(J/64)*p 73581da177e4SLinus Torvalds 73591da177e4SLinus Torvalds fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1) 73601da177e4SLinus Torvalds 73611da177e4SLinus Torvalds#--Step 6 73621da177e4SLinus Torvalds#--Step 6.1 73631da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d1 # retrieve M 73641da177e4SLinus Torvalds cmp.l %d1,&63 73651da177e4SLinus Torvalds ble.b MLE63 73661da177e4SLinus Torvalds#--Step 6.2 M >= 64 73671da177e4SLinus Torvalds fmov.s 12(%a1),%fp1 # fp1 is t 73681da177e4SLinus Torvalds fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc 73691da177e4SLinus Torvalds fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released 73701da177e4SLinus Torvalds fadd.x (%a1),%fp0 # T+(p+(t+OnebySc)) 73711da177e4SLinus Torvalds bra EM1SCALE 73721da177e4SLinus TorvaldsMLE63: 73731da177e4SLinus Torvalds#--Step 6.3 M <= 63 73741da177e4SLinus Torvalds cmp.l %d1,&-3 73751da177e4SLinus Torvalds bge.b MGEN3 73761da177e4SLinus TorvaldsMLTN3: 73771da177e4SLinus Torvalds#--Step 6.4 M <= -4 73781da177e4SLinus Torvalds fadd.s 12(%a1),%fp0 # p+t 73791da177e4SLinus Torvalds fadd.x (%a1),%fp0 # T+(p+t) 73801da177e4SLinus Torvalds fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t)) 73811da177e4SLinus Torvalds bra EM1SCALE 73821da177e4SLinus TorvaldsMGEN3: 73831da177e4SLinus Torvalds#--Step 6.5 -3 <= M <= 63 73841da177e4SLinus Torvalds fmov.x (%a1)+,%fp1 # fp1 is T 73851da177e4SLinus Torvalds fadd.s (%a1),%fp0 # fp0 is p+t 73861da177e4SLinus Torvalds fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc 73871da177e4SLinus Torvalds fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t) 73881da177e4SLinus Torvalds 73891da177e4SLinus TorvaldsEM1SCALE: 73901da177e4SLinus Torvalds#--Step 6.6 73911da177e4SLinus Torvalds fmov.l %d0,%fpcr 73921da177e4SLinus Torvalds fmul.x SC(%a6),%fp0 73931da177e4SLinus Torvalds bra t_inx2 73941da177e4SLinus Torvalds 73951da177e4SLinus TorvaldsEM1SM: 73961da177e4SLinus Torvalds#--Step 7 |X| < 1/4. 73971da177e4SLinus Torvalds cmp.l %d1,&0x3FBE0000 # 2^(-65) 73981da177e4SLinus Torvalds bge.b EM1POLY 73991da177e4SLinus Torvalds 74001da177e4SLinus TorvaldsEM1TINY: 74011da177e4SLinus Torvalds#--Step 8 |X| < 2^(-65) 74021da177e4SLinus Torvalds cmp.l %d1,&0x00330000 # 2^(-16312) 74031da177e4SLinus Torvalds blt.b EM12TINY 74041da177e4SLinus Torvalds#--Step 8.2 74051da177e4SLinus Torvalds mov.l &0x80010000,SC(%a6) # SC is -2^(-16382) 74061da177e4SLinus Torvalds mov.l &0x80000000,SC+4(%a6) 74071da177e4SLinus Torvalds clr.l SC+8(%a6) 74081da177e4SLinus Torvalds fmov.x (%a0),%fp0 74091da177e4SLinus Torvalds fmov.l %d0,%fpcr 74101da177e4SLinus Torvalds mov.b &FADD_OP,%d1 # last inst is ADD 74111da177e4SLinus Torvalds fadd.x SC(%a6),%fp0 74121da177e4SLinus Torvalds bra t_catch 74131da177e4SLinus Torvalds 74141da177e4SLinus TorvaldsEM12TINY: 74151da177e4SLinus Torvalds#--Step 8.3 74161da177e4SLinus Torvalds fmov.x (%a0),%fp0 74171da177e4SLinus Torvalds fmul.d TWO140(%pc),%fp0 74181da177e4SLinus Torvalds mov.l &0x80010000,SC(%a6) 74191da177e4SLinus Torvalds mov.l &0x80000000,SC+4(%a6) 74201da177e4SLinus Torvalds clr.l SC+8(%a6) 74211da177e4SLinus Torvalds fadd.x SC(%a6),%fp0 74221da177e4SLinus Torvalds fmov.l %d0,%fpcr 74231da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 74241da177e4SLinus Torvalds fmul.d TWON140(%pc),%fp0 74251da177e4SLinus Torvalds bra t_catch 74261da177e4SLinus Torvalds 74271da177e4SLinus TorvaldsEM1POLY: 74281da177e4SLinus Torvalds#--Step 9 exp(X)-1 by a simple polynomial 74291da177e4SLinus Torvalds fmov.x (%a0),%fp0 # fp0 is X 74301da177e4SLinus Torvalds fmul.x %fp0,%fp0 # fp0 is S := X*X 74311da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 74321da177e4SLinus Torvalds fmov.s &0x2F30CAA8,%fp1 # fp1 is B12 74331da177e4SLinus Torvalds fmul.x %fp0,%fp1 # fp1 is S*B12 74341da177e4SLinus Torvalds fmov.s &0x310F8290,%fp2 # fp2 is B11 74351da177e4SLinus Torvalds fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12 74361da177e4SLinus Torvalds 74371da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 is S*B11 74381da177e4SLinus Torvalds fmul.x %fp0,%fp1 # fp1 is S*(B10 + ... 74391da177e4SLinus Torvalds 74401da177e4SLinus Torvalds fadd.s &0x3493F281,%fp2 # fp2 is B9+S*... 74411da177e4SLinus Torvalds fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*... 74421da177e4SLinus Torvalds 74431da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 is S*(B9+... 74441da177e4SLinus Torvalds fmul.x %fp0,%fp1 # fp1 is S*(B8+... 74451da177e4SLinus Torvalds 74461da177e4SLinus Torvalds fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*... 74471da177e4SLinus Torvalds fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*... 74481da177e4SLinus Torvalds 74491da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 is S*(B7+... 74501da177e4SLinus Torvalds fmul.x %fp0,%fp1 # fp1 is S*(B6+... 74511da177e4SLinus Torvalds 74521da177e4SLinus Torvalds fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*... 74531da177e4SLinus Torvalds fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*... 74541da177e4SLinus Torvalds 74551da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 is S*(B5+... 74561da177e4SLinus Torvalds fmul.x %fp0,%fp1 # fp1 is S*(B4+... 74571da177e4SLinus Torvalds 74581da177e4SLinus Torvalds fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*... 74591da177e4SLinus Torvalds fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*... 74601da177e4SLinus Torvalds 74611da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 is S*(B3+... 74621da177e4SLinus Torvalds fmul.x %fp0,%fp1 # fp1 is S*(B2+... 74631da177e4SLinus Torvalds 74641da177e4SLinus Torvalds fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...) 74651da177e4SLinus Torvalds fmul.x (%a0),%fp1 # fp1 is X*S*(B2... 74661da177e4SLinus Torvalds 74671da177e4SLinus Torvalds fmul.s &0x3F000000,%fp0 # fp0 is S*B1 74681da177e4SLinus Torvalds fadd.x %fp2,%fp1 # fp1 is Q 74691da177e4SLinus Torvalds 74701da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 74711da177e4SLinus Torvalds 74721da177e4SLinus Torvalds fadd.x %fp1,%fp0 # fp0 is S*B1+Q 74731da177e4SLinus Torvalds 74741da177e4SLinus Torvalds fmov.l %d0,%fpcr 74751da177e4SLinus Torvalds fadd.x (%a0),%fp0 74761da177e4SLinus Torvalds bra t_inx2 74771da177e4SLinus Torvalds 74781da177e4SLinus TorvaldsEM1BIG: 74791da177e4SLinus Torvalds#--Step 10 |X| > 70 log2 74801da177e4SLinus Torvalds mov.l (%a0),%d1 74811da177e4SLinus Torvalds cmp.l %d1,&0 74821da177e4SLinus Torvalds bgt.w EXPC1 74831da177e4SLinus Torvalds#--Step 10.2 74841da177e4SLinus Torvalds fmov.s &0xBF800000,%fp0 # fp0 is -1 74851da177e4SLinus Torvalds fmov.l %d0,%fpcr 74861da177e4SLinus Torvalds fadd.s &0x00800000,%fp0 # -1 + 2^(-126) 74871da177e4SLinus Torvalds bra t_minx2 74881da177e4SLinus Torvalds 74891da177e4SLinus Torvalds global setoxm1d 74901da177e4SLinus Torvaldssetoxm1d: 74911da177e4SLinus Torvalds#--entry point for EXPM1(X), here X is denormalized 74921da177e4SLinus Torvalds#--Step 0. 74931da177e4SLinus Torvalds bra t_extdnrm 74941da177e4SLinus Torvalds 74951da177e4SLinus Torvalds######################################################################### 74961da177e4SLinus Torvalds# sgetexp(): returns the exponent portion of the input argument. # 74971da177e4SLinus Torvalds# The exponent bias is removed and the exponent value is # 74981da177e4SLinus Torvalds# returned as an extended precision number in fp0. # 74991da177e4SLinus Torvalds# sgetexpd(): handles denormalized numbers. # 75001da177e4SLinus Torvalds# # 75011da177e4SLinus Torvalds# sgetman(): extracts the mantissa of the input argument. The # 75021da177e4SLinus Torvalds# mantissa is converted to an extended precision number w/ # 75031da177e4SLinus Torvalds# an exponent of $3fff and is returned in fp0. The range of # 75041da177e4SLinus Torvalds# the result is [1.0 - 2.0). # 75051da177e4SLinus Torvalds# sgetmand(): handles denormalized numbers. # 75061da177e4SLinus Torvalds# # 75071da177e4SLinus Torvalds# INPUT *************************************************************** # 75081da177e4SLinus Torvalds# a0 = pointer to extended precision input # 75091da177e4SLinus Torvalds# # 75101da177e4SLinus Torvalds# OUTPUT ************************************************************** # 75111da177e4SLinus Torvalds# fp0 = exponent(X) or mantissa(X) # 75121da177e4SLinus Torvalds# # 75131da177e4SLinus Torvalds######################################################################### 75141da177e4SLinus Torvalds 75151da177e4SLinus Torvalds global sgetexp 75161da177e4SLinus Torvaldssgetexp: 75171da177e4SLinus Torvalds mov.w SRC_EX(%a0),%d0 # get the exponent 75181da177e4SLinus Torvalds bclr &0xf,%d0 # clear the sign bit 75191da177e4SLinus Torvalds subi.w &0x3fff,%d0 # subtract off the bias 75201da177e4SLinus Torvalds fmov.w %d0,%fp0 # return exp in fp0 75211da177e4SLinus Torvalds blt.b sgetexpn # it's negative 75221da177e4SLinus Torvalds rts 75231da177e4SLinus Torvalds 75241da177e4SLinus Torvaldssgetexpn: 75251da177e4SLinus Torvalds mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 75261da177e4SLinus Torvalds rts 75271da177e4SLinus Torvalds 75281da177e4SLinus Torvalds global sgetexpd 75291da177e4SLinus Torvaldssgetexpd: 75301da177e4SLinus Torvalds bsr.l norm # normalize 75311da177e4SLinus Torvalds neg.w %d0 # new exp = -(shft amt) 75321da177e4SLinus Torvalds subi.w &0x3fff,%d0 # subtract off the bias 75331da177e4SLinus Torvalds fmov.w %d0,%fp0 # return exp in fp0 75341da177e4SLinus Torvalds mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 75351da177e4SLinus Torvalds rts 75361da177e4SLinus Torvalds 75371da177e4SLinus Torvalds global sgetman 75381da177e4SLinus Torvaldssgetman: 75391da177e4SLinus Torvalds mov.w SRC_EX(%a0),%d0 # get the exp 75401da177e4SLinus Torvalds ori.w &0x7fff,%d0 # clear old exp 75411da177e4SLinus Torvalds bclr &0xe,%d0 # make it the new exp +-3fff 75421da177e4SLinus Torvalds 75431da177e4SLinus Torvalds# here, we build the result in a tmp location so as not to disturb the input 75441da177e4SLinus Torvalds mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc 75451da177e4SLinus Torvalds mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc 75461da177e4SLinus Torvalds mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 75471da177e4SLinus Torvalds fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0 75481da177e4SLinus Torvalds bmi.b sgetmann # it's negative 75491da177e4SLinus Torvalds rts 75501da177e4SLinus Torvalds 75511da177e4SLinus Torvaldssgetmann: 75521da177e4SLinus Torvalds mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 75531da177e4SLinus Torvalds rts 75541da177e4SLinus Torvalds 75551da177e4SLinus Torvalds# 75561da177e4SLinus Torvalds# For denormalized numbers, shift the mantissa until the j-bit = 1, 75571da177e4SLinus Torvalds# then load the exponent with +/1 $3fff. 75581da177e4SLinus Torvalds# 75591da177e4SLinus Torvalds global sgetmand 75601da177e4SLinus Torvaldssgetmand: 75611da177e4SLinus Torvalds bsr.l norm # normalize exponent 75621da177e4SLinus Torvalds bra.b sgetman 75631da177e4SLinus Torvalds 75641da177e4SLinus Torvalds######################################################################### 75651da177e4SLinus Torvalds# scosh(): computes the hyperbolic cosine of a normalized input # 75661da177e4SLinus Torvalds# scoshd(): computes the hyperbolic cosine of a denormalized input # 75671da177e4SLinus Torvalds# # 75681da177e4SLinus Torvalds# INPUT *************************************************************** # 75691da177e4SLinus Torvalds# a0 = pointer to extended precision input # 75701da177e4SLinus Torvalds# d0 = round precision,mode # 75711da177e4SLinus Torvalds# # 75721da177e4SLinus Torvalds# OUTPUT ************************************************************** # 75731da177e4SLinus Torvalds# fp0 = cosh(X) # 75741da177e4SLinus Torvalds# # 75751da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 75761da177e4SLinus Torvalds# The returned result is within 3 ulps in 64 significant bit, # 75771da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 75781da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 75791da177e4SLinus Torvalds# in double precision. # 75801da177e4SLinus Torvalds# # 75811da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 75821da177e4SLinus Torvalds# # 75831da177e4SLinus Torvalds# COSH # 75841da177e4SLinus Torvalds# 1. If |X| > 16380 log2, go to 3. # 75851da177e4SLinus Torvalds# # 75861da177e4SLinus Torvalds# 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae # 75871da177e4SLinus Torvalds# y = |X|, z = exp(Y), and # 75881da177e4SLinus Torvalds# cosh(X) = (1/2)*( z + 1/z ). # 75891da177e4SLinus Torvalds# Exit. # 75901da177e4SLinus Torvalds# # 75911da177e4SLinus Torvalds# 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. # 75921da177e4SLinus Torvalds# # 75931da177e4SLinus Torvalds# 4. (16380 log2 < |X| <= 16480 log2) # 75941da177e4SLinus Torvalds# cosh(X) = sign(X) * exp(|X|)/2. # 75951da177e4SLinus Torvalds# However, invoking exp(|X|) may cause premature # 75961da177e4SLinus Torvalds# overflow. Thus, we calculate sinh(X) as follows: # 75971da177e4SLinus Torvalds# Y := |X| # 75981da177e4SLinus Torvalds# Fact := 2**(16380) # 75991da177e4SLinus Torvalds# Y' := Y - 16381 log2 # 76001da177e4SLinus Torvalds# cosh(X) := Fact * exp(Y'). # 76011da177e4SLinus Torvalds# Exit. # 76021da177e4SLinus Torvalds# # 76031da177e4SLinus Torvalds# 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 76041da177e4SLinus Torvalds# Huge*Huge to generate overflow and an infinity with # 76051da177e4SLinus Torvalds# the appropriate sign. Huge is the largest finite number # 76061da177e4SLinus Torvalds# in extended format. Exit. # 76071da177e4SLinus Torvalds# # 76081da177e4SLinus Torvalds######################################################################### 76091da177e4SLinus Torvalds 76101da177e4SLinus TorvaldsTWO16380: 76111da177e4SLinus Torvalds long 0x7FFB0000,0x80000000,0x00000000,0x00000000 76121da177e4SLinus Torvalds 76131da177e4SLinus Torvalds global scosh 76141da177e4SLinus Torvaldsscosh: 76151da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 76161da177e4SLinus Torvalds 76171da177e4SLinus Torvalds mov.l (%a0),%d1 76181da177e4SLinus Torvalds mov.w 4(%a0),%d1 76191da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 76201da177e4SLinus Torvalds cmp.l %d1,&0x400CB167 76211da177e4SLinus Torvalds bgt.b COSHBIG 76221da177e4SLinus Torvalds 76231da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 16380 LOG2 76241da177e4SLinus Torvalds#--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) ) 76251da177e4SLinus Torvalds 76261da177e4SLinus Torvalds fabs.x %fp0 # |X| 76271da177e4SLinus Torvalds 76281da177e4SLinus Torvalds mov.l %d0,-(%sp) 76291da177e4SLinus Torvalds clr.l %d0 76301da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save |X| to stack 76311da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to |X| 76321da177e4SLinus Torvalds bsr setox # FP0 IS EXP(|X|) 76331da177e4SLinus Torvalds add.l &0xc,%sp # erase |X| from stack 76341da177e4SLinus Torvalds fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|) 76351da177e4SLinus Torvalds mov.l (%sp)+,%d0 76361da177e4SLinus Torvalds 76371da177e4SLinus Torvalds fmov.s &0x3E800000,%fp1 # (1/4) 76381da177e4SLinus Torvalds fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|)) 76391da177e4SLinus Torvalds 76401da177e4SLinus Torvalds fmov.l %d0,%fpcr 76411da177e4SLinus Torvalds mov.b &FADD_OP,%d1 # last inst is ADD 76421da177e4SLinus Torvalds fadd.x %fp1,%fp0 76431da177e4SLinus Torvalds bra t_catch 76441da177e4SLinus Torvalds 76451da177e4SLinus TorvaldsCOSHBIG: 76461da177e4SLinus Torvalds cmp.l %d1,&0x400CB2B3 76471da177e4SLinus Torvalds bgt.b COSHHUGE 76481da177e4SLinus Torvalds 76491da177e4SLinus Torvalds fabs.x %fp0 76501da177e4SLinus Torvalds fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 76511da177e4SLinus Torvalds fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 76521da177e4SLinus Torvalds 76531da177e4SLinus Torvalds mov.l %d0,-(%sp) 76541da177e4SLinus Torvalds clr.l %d0 76551da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save fp0 to stack 76561da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to fp0 76571da177e4SLinus Torvalds bsr setox 76581da177e4SLinus Torvalds add.l &0xc,%sp # clear fp0 from stack 76591da177e4SLinus Torvalds mov.l (%sp)+,%d0 76601da177e4SLinus Torvalds 76611da177e4SLinus Torvalds fmov.l %d0,%fpcr 76621da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 76631da177e4SLinus Torvalds fmul.x TWO16380(%pc),%fp0 76641da177e4SLinus Torvalds bra t_catch 76651da177e4SLinus Torvalds 76661da177e4SLinus TorvaldsCOSHHUGE: 76671da177e4SLinus Torvalds bra t_ovfl2 76681da177e4SLinus Torvalds 76691da177e4SLinus Torvalds global scoshd 76701da177e4SLinus Torvalds#--COSH(X) = 1 FOR DENORMALIZED X 76711da177e4SLinus Torvaldsscoshd: 76721da177e4SLinus Torvalds fmov.s &0x3F800000,%fp0 76731da177e4SLinus Torvalds 76741da177e4SLinus Torvalds fmov.l %d0,%fpcr 76751da177e4SLinus Torvalds fadd.s &0x00800000,%fp0 76761da177e4SLinus Torvalds bra t_pinx2 76771da177e4SLinus Torvalds 76781da177e4SLinus Torvalds######################################################################### 76791da177e4SLinus Torvalds# ssinh(): computes the hyperbolic sine of a normalized input # 76801da177e4SLinus Torvalds# ssinhd(): computes the hyperbolic sine of a denormalized input # 76811da177e4SLinus Torvalds# # 76821da177e4SLinus Torvalds# INPUT *************************************************************** # 76831da177e4SLinus Torvalds# a0 = pointer to extended precision input # 76841da177e4SLinus Torvalds# d0 = round precision,mode # 76851da177e4SLinus Torvalds# # 76861da177e4SLinus Torvalds# OUTPUT ************************************************************** # 76871da177e4SLinus Torvalds# fp0 = sinh(X) # 76881da177e4SLinus Torvalds# # 76891da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 76901da177e4SLinus Torvalds# The returned result is within 3 ulps in 64 significant bit, # 76911da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 76921da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 76931da177e4SLinus Torvalds# in double precision. # 76941da177e4SLinus Torvalds# # 76951da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 76961da177e4SLinus Torvalds# # 76971da177e4SLinus Torvalds# SINH # 76981da177e4SLinus Torvalds# 1. If |X| > 16380 log2, go to 3. # 76991da177e4SLinus Torvalds# # 77001da177e4SLinus Torvalds# 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula # 77011da177e4SLinus Torvalds# y = |X|, sgn = sign(X), and z = expm1(Y), # 77021da177e4SLinus Torvalds# sinh(X) = sgn*(1/2)*( z + z/(1+z) ). # 77031da177e4SLinus Torvalds# Exit. # 77041da177e4SLinus Torvalds# # 77051da177e4SLinus Torvalds# 3. If |X| > 16480 log2, go to 5. # 77061da177e4SLinus Torvalds# # 77071da177e4SLinus Torvalds# 4. (16380 log2 < |X| <= 16480 log2) # 77081da177e4SLinus Torvalds# sinh(X) = sign(X) * exp(|X|)/2. # 77091da177e4SLinus Torvalds# However, invoking exp(|X|) may cause premature overflow. # 77101da177e4SLinus Torvalds# Thus, we calculate sinh(X) as follows: # 77111da177e4SLinus Torvalds# Y := |X| # 77121da177e4SLinus Torvalds# sgn := sign(X) # 77131da177e4SLinus Torvalds# sgnFact := sgn * 2**(16380) # 77141da177e4SLinus Torvalds# Y' := Y - 16381 log2 # 77151da177e4SLinus Torvalds# sinh(X) := sgnFact * exp(Y'). # 77161da177e4SLinus Torvalds# Exit. # 77171da177e4SLinus Torvalds# # 77181da177e4SLinus Torvalds# 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 77191da177e4SLinus Torvalds# sign(X)*Huge*Huge to generate overflow and an infinity with # 77201da177e4SLinus Torvalds# the appropriate sign. Huge is the largest finite number in # 77211da177e4SLinus Torvalds# extended format. Exit. # 77221da177e4SLinus Torvalds# # 77231da177e4SLinus Torvalds######################################################################### 77241da177e4SLinus Torvalds 77251da177e4SLinus Torvalds global ssinh 77261da177e4SLinus Torvaldsssinh: 77271da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 77281da177e4SLinus Torvalds 77291da177e4SLinus Torvalds mov.l (%a0),%d1 77301da177e4SLinus Torvalds mov.w 4(%a0),%d1 77311da177e4SLinus Torvalds mov.l %d1,%a1 # save (compacted) operand 77321da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 77331da177e4SLinus Torvalds cmp.l %d1,&0x400CB167 77341da177e4SLinus Torvalds bgt.b SINHBIG 77351da177e4SLinus Torvalds 77361da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 16380 LOG2 77371da177e4SLinus Torvalds#--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) ) 77381da177e4SLinus Torvalds 77391da177e4SLinus Torvalds fabs.x %fp0 # Y = |X| 77401da177e4SLinus Torvalds 77411da177e4SLinus Torvalds movm.l &0x8040,-(%sp) # {a1/d0} 77421da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save Y on stack 77431da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to Y 77441da177e4SLinus Torvalds clr.l %d0 77451da177e4SLinus Torvalds bsr setoxm1 # FP0 IS Z = EXPM1(Y) 77461da177e4SLinus Torvalds add.l &0xc,%sp # clear Y from stack 77471da177e4SLinus Torvalds fmov.l &0,%fpcr 77481da177e4SLinus Torvalds movm.l (%sp)+,&0x0201 # {a1/d0} 77491da177e4SLinus Torvalds 77501da177e4SLinus Torvalds fmov.x %fp0,%fp1 77511da177e4SLinus Torvalds fadd.s &0x3F800000,%fp1 # 1+Z 77521da177e4SLinus Torvalds fmov.x %fp0,-(%sp) 77531da177e4SLinus Torvalds fdiv.x %fp1,%fp0 # Z/(1+Z) 77541da177e4SLinus Torvalds mov.l %a1,%d1 77551da177e4SLinus Torvalds and.l &0x80000000,%d1 77561da177e4SLinus Torvalds or.l &0x3F000000,%d1 77571da177e4SLinus Torvalds fadd.x (%sp)+,%fp0 77581da177e4SLinus Torvalds mov.l %d1,-(%sp) 77591da177e4SLinus Torvalds 77601da177e4SLinus Torvalds fmov.l %d0,%fpcr 77611da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 77621da177e4SLinus Torvalds fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set 77631da177e4SLinus Torvalds bra t_catch 77641da177e4SLinus Torvalds 77651da177e4SLinus TorvaldsSINHBIG: 77661da177e4SLinus Torvalds cmp.l %d1,&0x400CB2B3 77671da177e4SLinus Torvalds bgt t_ovfl 77681da177e4SLinus Torvalds fabs.x %fp0 77691da177e4SLinus Torvalds fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 77701da177e4SLinus Torvalds mov.l &0,-(%sp) 77711da177e4SLinus Torvalds mov.l &0x80000000,-(%sp) 77721da177e4SLinus Torvalds mov.l %a1,%d1 77731da177e4SLinus Torvalds and.l &0x80000000,%d1 77741da177e4SLinus Torvalds or.l &0x7FFB0000,%d1 77751da177e4SLinus Torvalds mov.l %d1,-(%sp) # EXTENDED FMT 77761da177e4SLinus Torvalds fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 77771da177e4SLinus Torvalds 77781da177e4SLinus Torvalds mov.l %d0,-(%sp) 77791da177e4SLinus Torvalds clr.l %d0 77801da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save fp0 on stack 77811da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to fp0 77821da177e4SLinus Torvalds bsr setox 77831da177e4SLinus Torvalds add.l &0xc,%sp # clear fp0 from stack 77841da177e4SLinus Torvalds 77851da177e4SLinus Torvalds mov.l (%sp)+,%d0 77861da177e4SLinus Torvalds fmov.l %d0,%fpcr 77871da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 77881da177e4SLinus Torvalds fmul.x (%sp)+,%fp0 # possible exception 77891da177e4SLinus Torvalds bra t_catch 77901da177e4SLinus Torvalds 77911da177e4SLinus Torvalds global ssinhd 77921da177e4SLinus Torvalds#--SINH(X) = X FOR DENORMALIZED X 77931da177e4SLinus Torvaldsssinhd: 77941da177e4SLinus Torvalds bra t_extdnrm 77951da177e4SLinus Torvalds 77961da177e4SLinus Torvalds######################################################################### 77971da177e4SLinus Torvalds# stanh(): computes the hyperbolic tangent of a normalized input # 77981da177e4SLinus Torvalds# stanhd(): computes the hyperbolic tangent of a denormalized input # 77991da177e4SLinus Torvalds# # 78001da177e4SLinus Torvalds# INPUT *************************************************************** # 78011da177e4SLinus Torvalds# a0 = pointer to extended precision input # 78021da177e4SLinus Torvalds# d0 = round precision,mode # 78031da177e4SLinus Torvalds# # 78041da177e4SLinus Torvalds# OUTPUT ************************************************************** # 78051da177e4SLinus Torvalds# fp0 = tanh(X) # 78061da177e4SLinus Torvalds# # 78071da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 78081da177e4SLinus Torvalds# The returned result is within 3 ulps in 64 significant bit, # 78091da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 78101da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 78111da177e4SLinus Torvalds# in double precision. # 78121da177e4SLinus Torvalds# # 78131da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 78141da177e4SLinus Torvalds# # 78151da177e4SLinus Torvalds# TANH # 78161da177e4SLinus Torvalds# 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. # 78171da177e4SLinus Torvalds# # 78181da177e4SLinus Torvalds# 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by # 78191da177e4SLinus Torvalds# sgn := sign(X), y := 2|X|, z := expm1(Y), and # 78201da177e4SLinus Torvalds# tanh(X) = sgn*( z/(2+z) ). # 78211da177e4SLinus Torvalds# Exit. # 78221da177e4SLinus Torvalds# # 78231da177e4SLinus Torvalds# 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, # 78241da177e4SLinus Torvalds# go to 7. # 78251da177e4SLinus Torvalds# # 78261da177e4SLinus Torvalds# 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. # 78271da177e4SLinus Torvalds# # 78281da177e4SLinus Torvalds# 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by # 78291da177e4SLinus Torvalds# sgn := sign(X), y := 2|X|, z := exp(Y), # 78301da177e4SLinus Torvalds# tanh(X) = sgn - [ sgn*2/(1+z) ]. # 78311da177e4SLinus Torvalds# Exit. # 78321da177e4SLinus Torvalds# # 78331da177e4SLinus Torvalds# 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we # 78341da177e4SLinus Torvalds# calculate Tanh(X) by # 78351da177e4SLinus Torvalds# sgn := sign(X), Tiny := 2**(-126), # 78361da177e4SLinus Torvalds# tanh(X) := sgn - sgn*Tiny. # 78371da177e4SLinus Torvalds# Exit. # 78381da177e4SLinus Torvalds# # 78391da177e4SLinus Torvalds# 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. # 78401da177e4SLinus Torvalds# # 78411da177e4SLinus Torvalds######################################################################### 78421da177e4SLinus Torvalds 78431da177e4SLinus Torvalds set X,FP_SCR0 78441da177e4SLinus Torvalds set XFRAC,X+4 78451da177e4SLinus Torvalds 78461da177e4SLinus Torvalds set SGN,L_SCR3 78471da177e4SLinus Torvalds 78481da177e4SLinus Torvalds set V,FP_SCR0 78491da177e4SLinus Torvalds 78501da177e4SLinus Torvalds global stanh 78511da177e4SLinus Torvaldsstanh: 78521da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 78531da177e4SLinus Torvalds 78541da177e4SLinus Torvalds fmov.x %fp0,X(%a6) 78551da177e4SLinus Torvalds mov.l (%a0),%d1 78561da177e4SLinus Torvalds mov.w 4(%a0),%d1 78571da177e4SLinus Torvalds mov.l %d1,X(%a6) 78581da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 78591da177e4SLinus Torvalds cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)? 78601da177e4SLinus Torvalds blt.w TANHBORS # yes 78611da177e4SLinus Torvalds cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2? 78621da177e4SLinus Torvalds bgt.w TANHBORS # yes 78631da177e4SLinus Torvalds 78641da177e4SLinus Torvalds#--THIS IS THE USUAL CASE 78651da177e4SLinus Torvalds#--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2). 78661da177e4SLinus Torvalds 78671da177e4SLinus Torvalds mov.l X(%a6),%d1 78681da177e4SLinus Torvalds mov.l %d1,SGN(%a6) 78691da177e4SLinus Torvalds and.l &0x7FFF0000,%d1 78701da177e4SLinus Torvalds add.l &0x00010000,%d1 # EXPONENT OF 2|X| 78711da177e4SLinus Torvalds mov.l %d1,X(%a6) 78721da177e4SLinus Torvalds and.l &0x80000000,SGN(%a6) 78731da177e4SLinus Torvalds fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X| 78741da177e4SLinus Torvalds 78751da177e4SLinus Torvalds mov.l %d0,-(%sp) 78761da177e4SLinus Torvalds clr.l %d0 78771da177e4SLinus Torvalds fmovm.x &0x1,-(%sp) # save Y on stack 78781da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to Y 78791da177e4SLinus Torvalds bsr setoxm1 # FP0 IS Z = EXPM1(Y) 78801da177e4SLinus Torvalds add.l &0xc,%sp # clear Y from stack 78811da177e4SLinus Torvalds mov.l (%sp)+,%d0 78821da177e4SLinus Torvalds 78831da177e4SLinus Torvalds fmov.x %fp0,%fp1 78841da177e4SLinus Torvalds fadd.s &0x40000000,%fp1 # Z+2 78851da177e4SLinus Torvalds mov.l SGN(%a6),%d1 78861da177e4SLinus Torvalds fmov.x %fp1,V(%a6) 78871da177e4SLinus Torvalds eor.l %d1,V(%a6) 78881da177e4SLinus Torvalds 78891da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round prec,mode 78901da177e4SLinus Torvalds fdiv.x V(%a6),%fp0 78911da177e4SLinus Torvalds bra t_inx2 78921da177e4SLinus Torvalds 78931da177e4SLinus TorvaldsTANHBORS: 78941da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 78951da177e4SLinus Torvalds blt.w TANHSM 78961da177e4SLinus Torvalds 78971da177e4SLinus Torvalds cmp.l %d1,&0x40048AA1 78981da177e4SLinus Torvalds bgt.w TANHHUGE 78991da177e4SLinus Torvalds 79001da177e4SLinus Torvalds#-- (5/2) LOG2 < |X| < 50 LOG2, 79011da177e4SLinus Torvalds#--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X), 79021da177e4SLinus Torvalds#--TANH(X) = SGN - SGN*2/[EXP(Y)+1]. 79031da177e4SLinus Torvalds 79041da177e4SLinus Torvalds mov.l X(%a6),%d1 79051da177e4SLinus Torvalds mov.l %d1,SGN(%a6) 79061da177e4SLinus Torvalds and.l &0x7FFF0000,%d1 79071da177e4SLinus Torvalds add.l &0x00010000,%d1 # EXPO OF 2|X| 79081da177e4SLinus Torvalds mov.l %d1,X(%a6) # Y = 2|X| 79091da177e4SLinus Torvalds and.l &0x80000000,SGN(%a6) 79101da177e4SLinus Torvalds mov.l SGN(%a6),%d1 79111da177e4SLinus Torvalds fmov.x X(%a6),%fp0 # Y = 2|X| 79121da177e4SLinus Torvalds 79131da177e4SLinus Torvalds mov.l %d0,-(%sp) 79141da177e4SLinus Torvalds clr.l %d0 79151da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save Y on stack 79161da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to Y 79171da177e4SLinus Torvalds bsr setox # FP0 IS EXP(Y) 79181da177e4SLinus Torvalds add.l &0xc,%sp # clear Y from stack 79191da177e4SLinus Torvalds mov.l (%sp)+,%d0 79201da177e4SLinus Torvalds mov.l SGN(%a6),%d1 79211da177e4SLinus Torvalds fadd.s &0x3F800000,%fp0 # EXP(Y)+1 79221da177e4SLinus Torvalds 79231da177e4SLinus Torvalds eor.l &0xC0000000,%d1 # -SIGN(X)*2 79241da177e4SLinus Torvalds fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT 79251da177e4SLinus Torvalds fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ] 79261da177e4SLinus Torvalds 79271da177e4SLinus Torvalds mov.l SGN(%a6),%d1 79281da177e4SLinus Torvalds or.l &0x3F800000,%d1 # SGN 79291da177e4SLinus Torvalds fmov.s %d1,%fp0 # SGN IN SGL FMT 79301da177e4SLinus Torvalds 79311da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round prec,mode 79321da177e4SLinus Torvalds mov.b &FADD_OP,%d1 # last inst is ADD 79331da177e4SLinus Torvalds fadd.x %fp1,%fp0 79341da177e4SLinus Torvalds bra t_inx2 79351da177e4SLinus Torvalds 79361da177e4SLinus TorvaldsTANHSM: 79371da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round prec,mode 79381da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 79391da177e4SLinus Torvalds fmov.x X(%a6),%fp0 # last inst - possible exception set 79401da177e4SLinus Torvalds bra t_catch 79411da177e4SLinus Torvalds 79421da177e4SLinus Torvalds#---RETURN SGN(X) - SGN(X)EPS 79431da177e4SLinus TorvaldsTANHHUGE: 79441da177e4SLinus Torvalds mov.l X(%a6),%d1 79451da177e4SLinus Torvalds and.l &0x80000000,%d1 79461da177e4SLinus Torvalds or.l &0x3F800000,%d1 79471da177e4SLinus Torvalds fmov.s %d1,%fp0 79481da177e4SLinus Torvalds and.l &0x80000000,%d1 79491da177e4SLinus Torvalds eor.l &0x80800000,%d1 # -SIGN(X)*EPS 79501da177e4SLinus Torvalds 79511da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round prec,mode 79521da177e4SLinus Torvalds fadd.s %d1,%fp0 79531da177e4SLinus Torvalds bra t_inx2 79541da177e4SLinus Torvalds 79551da177e4SLinus Torvalds global stanhd 79561da177e4SLinus Torvalds#--TANH(X) = X FOR DENORMALIZED X 79571da177e4SLinus Torvaldsstanhd: 79581da177e4SLinus Torvalds bra t_extdnrm 79591da177e4SLinus Torvalds 79601da177e4SLinus Torvalds######################################################################### 79611da177e4SLinus Torvalds# slogn(): computes the natural logarithm of a normalized input # 79621da177e4SLinus Torvalds# slognd(): computes the natural logarithm of a denormalized input # 79631da177e4SLinus Torvalds# slognp1(): computes the log(1+X) of a normalized input # 79641da177e4SLinus Torvalds# slognp1d(): computes the log(1+X) of a denormalized input # 79651da177e4SLinus Torvalds# # 79661da177e4SLinus Torvalds# INPUT *************************************************************** # 79671da177e4SLinus Torvalds# a0 = pointer to extended precision input # 79681da177e4SLinus Torvalds# d0 = round precision,mode # 79691da177e4SLinus Torvalds# # 79701da177e4SLinus Torvalds# OUTPUT ************************************************************** # 79711da177e4SLinus Torvalds# fp0 = log(X) or log(1+X) # 79721da177e4SLinus Torvalds# # 79731da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 79741da177e4SLinus Torvalds# The returned result is within 2 ulps in 64 significant bit, # 79751da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 79761da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 79771da177e4SLinus Torvalds# in double precision. # 79781da177e4SLinus Torvalds# # 79791da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 79801da177e4SLinus Torvalds# LOGN: # 79811da177e4SLinus Torvalds# Step 1. If |X-1| < 1/16, approximate log(X) by an odd # 79821da177e4SLinus Torvalds# polynomial in u, where u = 2(X-1)/(X+1). Otherwise, # 79831da177e4SLinus Torvalds# move on to Step 2. # 79841da177e4SLinus Torvalds# # 79851da177e4SLinus Torvalds# Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first # 79861da177e4SLinus Torvalds# seven significant bits of Y plus 2**(-7), i.e. # 79871da177e4SLinus Torvalds# F = 1.xxxxxx1 in base 2 where the six "x" match those # 79881da177e4SLinus Torvalds# of Y. Note that |Y-F| <= 2**(-7). # 79891da177e4SLinus Torvalds# # 79901da177e4SLinus Torvalds# Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a # 79911da177e4SLinus Torvalds# polynomial in u, log(1+u) = poly. # 79921da177e4SLinus Torvalds# # 79931da177e4SLinus Torvalds# Step 4. Reconstruct # 79941da177e4SLinus Torvalds# log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) # 79951da177e4SLinus Torvalds# by k*log(2) + (log(F) + poly). The values of log(F) are # 79961da177e4SLinus Torvalds# calculated beforehand and stored in the program. # 79971da177e4SLinus Torvalds# # 79981da177e4SLinus Torvalds# lognp1: # 79991da177e4SLinus Torvalds# Step 1: If |X| < 1/16, approximate log(1+X) by an odd # 80001da177e4SLinus Torvalds# polynomial in u where u = 2X/(2+X). Otherwise, move on # 80011da177e4SLinus Torvalds# to Step 2. # 80021da177e4SLinus Torvalds# # 80031da177e4SLinus Torvalds# Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done # 80041da177e4SLinus Torvalds# in Step 2 of the algorithm for LOGN and compute # 80051da177e4SLinus Torvalds# log(1+X) as k*log(2) + log(F) + poly where poly # 80061da177e4SLinus Torvalds# approximates log(1+u), u = (Y-F)/F. # 80071da177e4SLinus Torvalds# # 80081da177e4SLinus Torvalds# Implementation Notes: # 80091da177e4SLinus Torvalds# Note 1. There are 64 different possible values for F, thus 64 # 80101da177e4SLinus Torvalds# log(F)'s need to be tabulated. Moreover, the values of # 80111da177e4SLinus Torvalds# 1/F are also tabulated so that the division in (Y-F)/F # 80121da177e4SLinus Torvalds# can be performed by a multiplication. # 80131da177e4SLinus Torvalds# # 80141da177e4SLinus Torvalds# Note 2. In Step 2 of lognp1, in order to preserved accuracy, # 80151da177e4SLinus Torvalds# the value Y-F has to be calculated carefully when # 80161da177e4SLinus Torvalds# 1/2 <= X < 3/2. # 80171da177e4SLinus Torvalds# # 80181da177e4SLinus Torvalds# Note 3. To fully exploit the pipeline, polynomials are usually # 80191da177e4SLinus Torvalds# separated into two parts evaluated independently before # 80201da177e4SLinus Torvalds# being added up. # 80211da177e4SLinus Torvalds# # 80221da177e4SLinus Torvalds######################################################################### 80231da177e4SLinus TorvaldsLOGOF2: 80241da177e4SLinus Torvalds long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 80251da177e4SLinus Torvalds 80261da177e4SLinus Torvaldsone: 80271da177e4SLinus Torvalds long 0x3F800000 80281da177e4SLinus Torvaldszero: 80291da177e4SLinus Torvalds long 0x00000000 80301da177e4SLinus Torvaldsinfty: 80311da177e4SLinus Torvalds long 0x7F800000 80321da177e4SLinus Torvaldsnegone: 80331da177e4SLinus Torvalds long 0xBF800000 80341da177e4SLinus Torvalds 80351da177e4SLinus TorvaldsLOGA6: 80361da177e4SLinus Torvalds long 0x3FC2499A,0xB5E4040B 80371da177e4SLinus TorvaldsLOGA5: 80381da177e4SLinus Torvalds long 0xBFC555B5,0x848CB7DB 80391da177e4SLinus Torvalds 80401da177e4SLinus TorvaldsLOGA4: 80411da177e4SLinus Torvalds long 0x3FC99999,0x987D8730 80421da177e4SLinus TorvaldsLOGA3: 80431da177e4SLinus Torvalds long 0xBFCFFFFF,0xFF6F7E97 80441da177e4SLinus Torvalds 80451da177e4SLinus TorvaldsLOGA2: 80461da177e4SLinus Torvalds long 0x3FD55555,0x555555A4 80471da177e4SLinus TorvaldsLOGA1: 80481da177e4SLinus Torvalds long 0xBFE00000,0x00000008 80491da177e4SLinus Torvalds 80501da177e4SLinus TorvaldsLOGB5: 80511da177e4SLinus Torvalds long 0x3F175496,0xADD7DAD6 80521da177e4SLinus TorvaldsLOGB4: 80531da177e4SLinus Torvalds long 0x3F3C71C2,0xFE80C7E0 80541da177e4SLinus Torvalds 80551da177e4SLinus TorvaldsLOGB3: 80561da177e4SLinus Torvalds long 0x3F624924,0x928BCCFF 80571da177e4SLinus TorvaldsLOGB2: 80581da177e4SLinus Torvalds long 0x3F899999,0x999995EC 80591da177e4SLinus Torvalds 80601da177e4SLinus TorvaldsLOGB1: 80611da177e4SLinus Torvalds long 0x3FB55555,0x55555555 80621da177e4SLinus TorvaldsTWO: 80631da177e4SLinus Torvalds long 0x40000000,0x00000000 80641da177e4SLinus Torvalds 80651da177e4SLinus TorvaldsLTHOLD: 80661da177e4SLinus Torvalds long 0x3f990000,0x80000000,0x00000000,0x00000000 80671da177e4SLinus Torvalds 80681da177e4SLinus TorvaldsLOGTBL: 80691da177e4SLinus Torvalds long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000 80701da177e4SLinus Torvalds long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000 80711da177e4SLinus Torvalds long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000 80721da177e4SLinus Torvalds long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000 80731da177e4SLinus Torvalds long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000 80741da177e4SLinus Torvalds long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000 80751da177e4SLinus Torvalds long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000 80761da177e4SLinus Torvalds long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000 80771da177e4SLinus Torvalds long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000 80781da177e4SLinus Torvalds long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000 80791da177e4SLinus Torvalds long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000 80801da177e4SLinus Torvalds long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000 80811da177e4SLinus Torvalds long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000 80821da177e4SLinus Torvalds long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000 80831da177e4SLinus Torvalds long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000 80841da177e4SLinus Torvalds long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000 80851da177e4SLinus Torvalds long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000 80861da177e4SLinus Torvalds long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000 80871da177e4SLinus Torvalds long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000 80881da177e4SLinus Torvalds long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000 80891da177e4SLinus Torvalds long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000 80901da177e4SLinus Torvalds long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000 80911da177e4SLinus Torvalds long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000 80921da177e4SLinus Torvalds long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000 80931da177e4SLinus Torvalds long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000 80941da177e4SLinus Torvalds long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000 80951da177e4SLinus Torvalds long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000 80961da177e4SLinus Torvalds long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000 80971da177e4SLinus Torvalds long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000 80981da177e4SLinus Torvalds long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000 80991da177e4SLinus Torvalds long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000 81001da177e4SLinus Torvalds long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000 81011da177e4SLinus Torvalds long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000 81021da177e4SLinus Torvalds long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000 81031da177e4SLinus Torvalds long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000 81041da177e4SLinus Torvalds long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000 81051da177e4SLinus Torvalds long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000 81061da177e4SLinus Torvalds long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000 81071da177e4SLinus Torvalds long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000 81081da177e4SLinus Torvalds long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000 81091da177e4SLinus Torvalds long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000 81101da177e4SLinus Torvalds long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000 81111da177e4SLinus Torvalds long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000 81121da177e4SLinus Torvalds long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000 81131da177e4SLinus Torvalds long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000 81141da177e4SLinus Torvalds long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000 81151da177e4SLinus Torvalds long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000 81161da177e4SLinus Torvalds long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000 81171da177e4SLinus Torvalds long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000 81181da177e4SLinus Torvalds long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000 81191da177e4SLinus Torvalds long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000 81201da177e4SLinus Torvalds long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000 81211da177e4SLinus Torvalds long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000 81221da177e4SLinus Torvalds long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000 81231da177e4SLinus Torvalds long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000 81241da177e4SLinus Torvalds long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000 81251da177e4SLinus Torvalds long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000 81261da177e4SLinus Torvalds long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000 81271da177e4SLinus Torvalds long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000 81281da177e4SLinus Torvalds long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000 81291da177e4SLinus Torvalds long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000 81301da177e4SLinus Torvalds long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000 81311da177e4SLinus Torvalds long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000 81321da177e4SLinus Torvalds long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000 81331da177e4SLinus Torvalds long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000 81341da177e4SLinus Torvalds long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000 81351da177e4SLinus Torvalds long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000 81361da177e4SLinus Torvalds long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000 81371da177e4SLinus Torvalds long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000 81381da177e4SLinus Torvalds long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000 81391da177e4SLinus Torvalds long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000 81401da177e4SLinus Torvalds long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000 81411da177e4SLinus Torvalds long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000 81421da177e4SLinus Torvalds long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000 81431da177e4SLinus Torvalds long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000 81441da177e4SLinus Torvalds long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000 81451da177e4SLinus Torvalds long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000 81461da177e4SLinus Torvalds long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000 81471da177e4SLinus Torvalds long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000 81481da177e4SLinus Torvalds long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000 81491da177e4SLinus Torvalds long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000 81501da177e4SLinus Torvalds long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000 81511da177e4SLinus Torvalds long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000 81521da177e4SLinus Torvalds long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000 81531da177e4SLinus Torvalds long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000 81541da177e4SLinus Torvalds long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000 81551da177e4SLinus Torvalds long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000 81561da177e4SLinus Torvalds long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000 81571da177e4SLinus Torvalds long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000 81581da177e4SLinus Torvalds long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000 81591da177e4SLinus Torvalds long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000 81601da177e4SLinus Torvalds long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000 81611da177e4SLinus Torvalds long 0x3FFE0000,0x94458094,0x45809446,0x00000000 81621da177e4SLinus Torvalds long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000 81631da177e4SLinus Torvalds long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000 81641da177e4SLinus Torvalds long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000 81651da177e4SLinus Torvalds long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000 81661da177e4SLinus Torvalds long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000 81671da177e4SLinus Torvalds long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000 81681da177e4SLinus Torvalds long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000 81691da177e4SLinus Torvalds long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000 81701da177e4SLinus Torvalds long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000 81711da177e4SLinus Torvalds long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000 81721da177e4SLinus Torvalds long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000 81731da177e4SLinus Torvalds long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000 81741da177e4SLinus Torvalds long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000 81751da177e4SLinus Torvalds long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000 81761da177e4SLinus Torvalds long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000 81771da177e4SLinus Torvalds long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000 81781da177e4SLinus Torvalds long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000 81791da177e4SLinus Torvalds long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000 81801da177e4SLinus Torvalds long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000 81811da177e4SLinus Torvalds long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000 81821da177e4SLinus Torvalds long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000 81831da177e4SLinus Torvalds long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000 81841da177e4SLinus Torvalds long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000 81851da177e4SLinus Torvalds long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000 81861da177e4SLinus Torvalds long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000 81871da177e4SLinus Torvalds long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000 81881da177e4SLinus Torvalds long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000 81891da177e4SLinus Torvalds long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000 81901da177e4SLinus Torvalds long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000 81911da177e4SLinus Torvalds long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000 81921da177e4SLinus Torvalds long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000 81931da177e4SLinus Torvalds long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000 81941da177e4SLinus Torvalds long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000 81951da177e4SLinus Torvalds long 0x3FFE0000,0x80808080,0x80808081,0x00000000 81961da177e4SLinus Torvalds long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000 81971da177e4SLinus Torvalds 81981da177e4SLinus Torvalds set ADJK,L_SCR1 81991da177e4SLinus Torvalds 82001da177e4SLinus Torvalds set X,FP_SCR0 82011da177e4SLinus Torvalds set XDCARE,X+2 82021da177e4SLinus Torvalds set XFRAC,X+4 82031da177e4SLinus Torvalds 82041da177e4SLinus Torvalds set F,FP_SCR1 82051da177e4SLinus Torvalds set FFRAC,F+4 82061da177e4SLinus Torvalds 82071da177e4SLinus Torvalds set KLOG2,FP_SCR0 82081da177e4SLinus Torvalds 82091da177e4SLinus Torvalds set SAVEU,FP_SCR0 82101da177e4SLinus Torvalds 82111da177e4SLinus Torvalds global slogn 82121da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S 82131da177e4SLinus Torvaldsslogn: 82141da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 82151da177e4SLinus Torvalds mov.l &0x00000000,ADJK(%a6) 82161da177e4SLinus Torvalds 82171da177e4SLinus TorvaldsLOGBGN: 82181da177e4SLinus Torvalds#--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS 82191da177e4SLinus Torvalds#--A FINITE, NON-ZERO, NORMALIZED NUMBER. 82201da177e4SLinus Torvalds 82211da177e4SLinus Torvalds mov.l (%a0),%d1 82221da177e4SLinus Torvalds mov.w 4(%a0),%d1 82231da177e4SLinus Torvalds 82241da177e4SLinus Torvalds mov.l (%a0),X(%a6) 82251da177e4SLinus Torvalds mov.l 4(%a0),X+4(%a6) 82261da177e4SLinus Torvalds mov.l 8(%a0),X+8(%a6) 82271da177e4SLinus Torvalds 82281da177e4SLinus Torvalds cmp.l %d1,&0 # CHECK IF X IS NEGATIVE 82291da177e4SLinus Torvalds blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID 82301da177e4SLinus Torvalds# X IS POSITIVE, CHECK IF X IS NEAR 1 82311da177e4SLinus Torvalds cmp.l %d1,&0x3ffef07d # IS X < 15/16? 82321da177e4SLinus Torvalds blt.b LOGMAIN # YES 82331da177e4SLinus Torvalds cmp.l %d1,&0x3fff8841 # IS X > 17/16? 82341da177e4SLinus Torvalds ble.w LOGNEAR1 # NO 82351da177e4SLinus Torvalds 82361da177e4SLinus TorvaldsLOGMAIN: 82371da177e4SLinus Torvalds#--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1 82381da177e4SLinus Torvalds 82391da177e4SLinus Torvalds#--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY. 82401da177e4SLinus Torvalds#--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1. 82411da177e4SLinus Torvalds#--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y) 82421da177e4SLinus Torvalds#-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F). 82431da177e4SLinus Torvalds#--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING 82441da177e4SLinus Torvalds#--LOG(1+U) CAN BE VERY EFFICIENT. 82451da177e4SLinus Torvalds#--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO 82461da177e4SLinus Torvalds#--DIVISION IS NEEDED TO CALCULATE (Y-F)/F. 82471da177e4SLinus Torvalds 82481da177e4SLinus Torvalds#--GET K, Y, F, AND ADDRESS OF 1/F. 82491da177e4SLinus Torvalds asr.l &8,%d1 82501da177e4SLinus Torvalds asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X 82511da177e4SLinus Torvalds sub.l &0x3FFF,%d1 # THIS IS K 82521da177e4SLinus Torvalds add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM. 82531da177e4SLinus Torvalds lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F) 82541da177e4SLinus Torvalds fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT 82551da177e4SLinus Torvalds 82561da177e4SLinus Torvalds#--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F 82571da177e4SLinus Torvalds mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X 82581da177e4SLinus Torvalds mov.l XFRAC(%a6),FFRAC(%a6) 82591da177e4SLinus Torvalds and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y 82601da177e4SLinus Torvalds or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT 82611da177e4SLinus Torvalds mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F 82621da177e4SLinus Torvalds and.l &0x7E000000,%d1 82631da177e4SLinus Torvalds asr.l &8,%d1 82641da177e4SLinus Torvalds asr.l &8,%d1 82651da177e4SLinus Torvalds asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT 82661da177e4SLinus Torvalds add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F 82671da177e4SLinus Torvalds 82681da177e4SLinus Torvalds fmov.x X(%a6),%fp0 82691da177e4SLinus Torvalds mov.l &0x3fff0000,F(%a6) 82701da177e4SLinus Torvalds clr.l F+8(%a6) 82711da177e4SLinus Torvalds fsub.x F(%a6),%fp0 # Y-F 82721da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY 82731da177e4SLinus Torvalds#--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K 82741da177e4SLinus Torvalds#--REGISTERS SAVED: FPCR, FP1, FP2 82751da177e4SLinus Torvalds 82761da177e4SLinus TorvaldsLP1CONT1: 82771da177e4SLinus Torvalds#--AN RE-ENTRY POINT FOR LOGNP1 82781da177e4SLinus Torvalds fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F 82791da177e4SLinus Torvalds fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY 82801da177e4SLinus Torvalds fmov.x %fp0,%fp2 82811da177e4SLinus Torvalds fmul.x %fp2,%fp2 # FP2 IS V=U*U 82821da177e4SLinus Torvalds fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMEORY, FREE FP1 82831da177e4SLinus Torvalds 82841da177e4SLinus Torvalds#--LOG(1+U) IS APPROXIMATED BY 82851da177e4SLinus Torvalds#--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS 82861da177e4SLinus Torvalds#--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))] 82871da177e4SLinus Torvalds 82881da177e4SLinus Torvalds fmov.x %fp2,%fp3 82891da177e4SLinus Torvalds fmov.x %fp2,%fp1 82901da177e4SLinus Torvalds 82911da177e4SLinus Torvalds fmul.d LOGA6(%pc),%fp1 # V*A6 82921da177e4SLinus Torvalds fmul.d LOGA5(%pc),%fp2 # V*A5 82931da177e4SLinus Torvalds 82941da177e4SLinus Torvalds fadd.d LOGA4(%pc),%fp1 # A4+V*A6 82951da177e4SLinus Torvalds fadd.d LOGA3(%pc),%fp2 # A3+V*A5 82961da177e4SLinus Torvalds 82971da177e4SLinus Torvalds fmul.x %fp3,%fp1 # V*(A4+V*A6) 82981da177e4SLinus Torvalds fmul.x %fp3,%fp2 # V*(A3+V*A5) 82991da177e4SLinus Torvalds 83001da177e4SLinus Torvalds fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6) 83011da177e4SLinus Torvalds fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5) 83021da177e4SLinus Torvalds 83031da177e4SLinus Torvalds fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6)) 83041da177e4SLinus Torvalds add.l &16,%a0 # ADDRESS OF LOG(F) 83051da177e4SLinus Torvalds fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5)) 83061da177e4SLinus Torvalds 83071da177e4SLinus Torvalds fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6)) 83081da177e4SLinus Torvalds fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5)) 83091da177e4SLinus Torvalds 83101da177e4SLinus Torvalds fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6)) 83111da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # RESTORE FP2-3 83121da177e4SLinus Torvalds fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U) 83131da177e4SLinus Torvalds 83141da177e4SLinus Torvalds fmov.l %d0,%fpcr 83151da177e4SLinus Torvalds fadd.x KLOG2(%a6),%fp0 # FINAL ADD 83161da177e4SLinus Torvalds bra t_inx2 83171da177e4SLinus Torvalds 83181da177e4SLinus Torvalds 83191da177e4SLinus TorvaldsLOGNEAR1: 83201da177e4SLinus Torvalds 83211da177e4SLinus Torvalds# if the input is exactly equal to one, then exit through ld_pzero. 83221da177e4SLinus Torvalds# if these 2 lines weren't here, the correct answer would be returned 83231da177e4SLinus Torvalds# but the INEX2 bit would be set. 83241da177e4SLinus Torvalds fcmp.b %fp0,&0x1 # is it equal to one? 83251da177e4SLinus Torvalds fbeq.l ld_pzero # yes 83261da177e4SLinus Torvalds 83271da177e4SLinus Torvalds#--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT. 83281da177e4SLinus Torvalds fmov.x %fp0,%fp1 83291da177e4SLinus Torvalds fsub.s one(%pc),%fp1 # FP1 IS X-1 83301da177e4SLinus Torvalds fadd.s one(%pc),%fp0 # FP0 IS X+1 83311da177e4SLinus Torvalds fadd.x %fp1,%fp1 # FP1 IS 2(X-1) 83321da177e4SLinus Torvalds#--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL 83331da177e4SLinus Torvalds#--IN U, U = 2(X-1)/(X+1) = FP1/FP0 83341da177e4SLinus Torvalds 83351da177e4SLinus TorvaldsLP1CONT2: 83361da177e4SLinus Torvalds#--THIS IS AN RE-ENTRY POINT FOR LOGNP1 83371da177e4SLinus Torvalds fdiv.x %fp0,%fp1 # FP1 IS U 83381da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # SAVE FP2-3 83391da177e4SLinus Torvalds#--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3 83401da177e4SLinus Torvalds#--LET V=U*U, W=V*V, CALCULATE 83411da177e4SLinus Torvalds#--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY 83421da177e4SLinus Torvalds#--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] ) 83431da177e4SLinus Torvalds fmov.x %fp1,%fp0 83441da177e4SLinus Torvalds fmul.x %fp0,%fp0 # FP0 IS V 83451da177e4SLinus Torvalds fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1 83461da177e4SLinus Torvalds fmov.x %fp0,%fp1 83471da177e4SLinus Torvalds fmul.x %fp1,%fp1 # FP1 IS W 83481da177e4SLinus Torvalds 83491da177e4SLinus Torvalds fmov.d LOGB5(%pc),%fp3 83501da177e4SLinus Torvalds fmov.d LOGB4(%pc),%fp2 83511da177e4SLinus Torvalds 83521da177e4SLinus Torvalds fmul.x %fp1,%fp3 # W*B5 83531da177e4SLinus Torvalds fmul.x %fp1,%fp2 # W*B4 83541da177e4SLinus Torvalds 83551da177e4SLinus Torvalds fadd.d LOGB3(%pc),%fp3 # B3+W*B5 83561da177e4SLinus Torvalds fadd.d LOGB2(%pc),%fp2 # B2+W*B4 83571da177e4SLinus Torvalds 83581da177e4SLinus Torvalds fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED 83591da177e4SLinus Torvalds 83601da177e4SLinus Torvalds fmul.x %fp0,%fp2 # V*(B2+W*B4) 83611da177e4SLinus Torvalds 83621da177e4SLinus Torvalds fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5) 83631da177e4SLinus Torvalds fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V 83641da177e4SLinus Torvalds 83651da177e4SLinus Torvalds fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED 83661da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED 83671da177e4SLinus Torvalds 83681da177e4SLinus Torvalds fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] ) 83691da177e4SLinus Torvalds 83701da177e4SLinus Torvalds fmov.l %d0,%fpcr 83711da177e4SLinus Torvalds fadd.x SAVEU(%a6),%fp0 83721da177e4SLinus Torvalds bra t_inx2 83731da177e4SLinus Torvalds 83741da177e4SLinus Torvalds#--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID 83751da177e4SLinus TorvaldsLOGNEG: 83761da177e4SLinus Torvalds bra t_operr 83771da177e4SLinus Torvalds 83781da177e4SLinus Torvalds global slognd 83791da177e4SLinus Torvaldsslognd: 83801da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT 83811da177e4SLinus Torvalds 83821da177e4SLinus Torvalds mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0 83831da177e4SLinus Torvalds 83841da177e4SLinus Torvalds#----normalize the input value by left shifting k bits (k to be determined 83851da177e4SLinus Torvalds#----below), adjusting exponent and storing -k to ADJK 83861da177e4SLinus Torvalds#----the value TWOTO100 is no longer needed. 83871da177e4SLinus Torvalds#----Note that this code assumes the denormalized input is NON-ZERO. 83881da177e4SLinus Torvalds 83891da177e4SLinus Torvalds movm.l &0x3f00,-(%sp) # save some registers {d2-d7} 83901da177e4SLinus Torvalds mov.l (%a0),%d3 # D3 is exponent of smallest norm. # 83911da177e4SLinus Torvalds mov.l 4(%a0),%d4 83921da177e4SLinus Torvalds mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X) 83931da177e4SLinus Torvalds clr.l %d2 # D2 used for holding K 83941da177e4SLinus Torvalds 83951da177e4SLinus Torvalds tst.l %d4 83961da177e4SLinus Torvalds bne.b Hi_not0 83971da177e4SLinus Torvalds 83981da177e4SLinus TorvaldsHi_0: 83991da177e4SLinus Torvalds mov.l %d5,%d4 84001da177e4SLinus Torvalds clr.l %d5 84011da177e4SLinus Torvalds mov.l &32,%d2 84021da177e4SLinus Torvalds clr.l %d6 84031da177e4SLinus Torvalds bfffo %d4{&0:&32},%d6 84041da177e4SLinus Torvalds lsl.l %d6,%d4 84051da177e4SLinus Torvalds add.l %d6,%d2 # (D3,D4,D5) is normalized 84061da177e4SLinus Torvalds 84071da177e4SLinus Torvalds mov.l %d3,X(%a6) 84081da177e4SLinus Torvalds mov.l %d4,XFRAC(%a6) 84091da177e4SLinus Torvalds mov.l %d5,XFRAC+4(%a6) 84101da177e4SLinus Torvalds neg.l %d2 84111da177e4SLinus Torvalds mov.l %d2,ADJK(%a6) 84121da177e4SLinus Torvalds fmov.x X(%a6),%fp0 84131da177e4SLinus Torvalds movm.l (%sp)+,&0xfc # restore registers {d2-d7} 84141da177e4SLinus Torvalds lea X(%a6),%a0 84151da177e4SLinus Torvalds bra.w LOGBGN # begin regular log(X) 84161da177e4SLinus Torvalds 84171da177e4SLinus TorvaldsHi_not0: 84181da177e4SLinus Torvalds clr.l %d6 84191da177e4SLinus Torvalds bfffo %d4{&0:&32},%d6 # find first 1 84201da177e4SLinus Torvalds mov.l %d6,%d2 # get k 84211da177e4SLinus Torvalds lsl.l %d6,%d4 84221da177e4SLinus Torvalds mov.l %d5,%d7 # a copy of D5 84231da177e4SLinus Torvalds lsl.l %d6,%d5 84241da177e4SLinus Torvalds neg.l %d6 84251da177e4SLinus Torvalds add.l &32,%d6 84261da177e4SLinus Torvalds lsr.l %d6,%d7 84271da177e4SLinus Torvalds or.l %d7,%d4 # (D3,D4,D5) normalized 84281da177e4SLinus Torvalds 84291da177e4SLinus Torvalds mov.l %d3,X(%a6) 84301da177e4SLinus Torvalds mov.l %d4,XFRAC(%a6) 84311da177e4SLinus Torvalds mov.l %d5,XFRAC+4(%a6) 84321da177e4SLinus Torvalds neg.l %d2 84331da177e4SLinus Torvalds mov.l %d2,ADJK(%a6) 84341da177e4SLinus Torvalds fmov.x X(%a6),%fp0 84351da177e4SLinus Torvalds movm.l (%sp)+,&0xfc # restore registers {d2-d7} 84361da177e4SLinus Torvalds lea X(%a6),%a0 84371da177e4SLinus Torvalds bra.w LOGBGN # begin regular log(X) 84381da177e4SLinus Torvalds 84391da177e4SLinus Torvalds global slognp1 84401da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S 84411da177e4SLinus Torvaldsslognp1: 84421da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 84431da177e4SLinus Torvalds fabs.x %fp0 # test magnitude 84441da177e4SLinus Torvalds fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold 84451da177e4SLinus Torvalds fbgt.w LP1REAL # if greater, continue 84461da177e4SLinus Torvalds fmov.l %d0,%fpcr 84471da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 84481da177e4SLinus Torvalds fmov.x (%a0),%fp0 # return signed argument 84491da177e4SLinus Torvalds bra t_catch 84501da177e4SLinus Torvalds 84511da177e4SLinus TorvaldsLP1REAL: 84521da177e4SLinus Torvalds fmov.x (%a0),%fp0 # LOAD INPUT 84531da177e4SLinus Torvalds mov.l &0x00000000,ADJK(%a6) 84541da177e4SLinus Torvalds fmov.x %fp0,%fp1 # FP1 IS INPUT Z 84551da177e4SLinus Torvalds fadd.s one(%pc),%fp0 # X := ROUND(1+Z) 84561da177e4SLinus Torvalds fmov.x %fp0,X(%a6) 84571da177e4SLinus Torvalds mov.w XFRAC(%a6),XDCARE(%a6) 84581da177e4SLinus Torvalds mov.l X(%a6),%d1 84591da177e4SLinus Torvalds cmp.l %d1,&0 84601da177e4SLinus Torvalds ble.w LP1NEG0 # LOG OF ZERO OR -VE 84611da177e4SLinus Torvalds cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]? 84621da177e4SLinus Torvalds blt.w LOGMAIN 84631da177e4SLinus Torvalds cmp.l %d1,&0x3fffc000 84641da177e4SLinus Torvalds bgt.w LOGMAIN 84651da177e4SLinus Torvalds#--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z, 84661da177e4SLinus Torvalds#--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE, 84671da177e4SLinus Torvalds#--SIMPLY INVOKE LOG(X) FOR LOG(1+Z). 84681da177e4SLinus Torvalds 84691da177e4SLinus TorvaldsLP1NEAR1: 84701da177e4SLinus Torvalds#--NEXT SEE IF EXP(-1/16) < X < EXP(1/16) 84711da177e4SLinus Torvalds cmp.l %d1,&0x3ffef07d 84721da177e4SLinus Torvalds blt.w LP1CARE 84731da177e4SLinus Torvalds cmp.l %d1,&0x3fff8841 84741da177e4SLinus Torvalds bgt.w LP1CARE 84751da177e4SLinus Torvalds 84761da177e4SLinus TorvaldsLP1ONE16: 84771da177e4SLinus Torvalds#--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2) 84781da177e4SLinus Torvalds#--WHERE U = 2Z/(2+Z) = 2Z/(1+X). 84791da177e4SLinus Torvalds fadd.x %fp1,%fp1 # FP1 IS 2Z 84801da177e4SLinus Torvalds fadd.s one(%pc),%fp0 # FP0 IS 1+X 84811da177e4SLinus Torvalds#--U = FP1/FP0 84821da177e4SLinus Torvalds bra.w LP1CONT2 84831da177e4SLinus Torvalds 84841da177e4SLinus TorvaldsLP1CARE: 84851da177e4SLinus Torvalds#--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE 84861da177e4SLinus Torvalds#--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST 84871da177e4SLinus Torvalds#--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2], 84881da177e4SLinus Torvalds#--THERE ARE ONLY TWO CASES. 84891da177e4SLinus Torvalds#--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z 84901da177e4SLinus Torvalds#--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z 84911da177e4SLinus Torvalds#--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF 84921da177e4SLinus Torvalds#--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED. 84931da177e4SLinus Torvalds 84941da177e4SLinus Torvalds mov.l XFRAC(%a6),FFRAC(%a6) 84951da177e4SLinus Torvalds and.l &0xFE000000,FFRAC(%a6) 84961da177e4SLinus Torvalds or.l &0x01000000,FFRAC(%a6) # F OBTAINED 84971da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1 84981da177e4SLinus Torvalds bge.b KISZERO 84991da177e4SLinus Torvalds 85001da177e4SLinus TorvaldsKISNEG1: 85011da177e4SLinus Torvalds fmov.s TWO(%pc),%fp0 85021da177e4SLinus Torvalds mov.l &0x3fff0000,F(%a6) 85031da177e4SLinus Torvalds clr.l F+8(%a6) 85041da177e4SLinus Torvalds fsub.x F(%a6),%fp0 # 2-F 85051da177e4SLinus Torvalds mov.l FFRAC(%a6),%d1 85061da177e4SLinus Torvalds and.l &0x7E000000,%d1 85071da177e4SLinus Torvalds asr.l &8,%d1 85081da177e4SLinus Torvalds asr.l &8,%d1 85091da177e4SLinus Torvalds asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F 85101da177e4SLinus Torvalds fadd.x %fp1,%fp1 # GET 2Z 85111da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3} 85121da177e4SLinus Torvalds fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z 85131da177e4SLinus Torvalds lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F 85141da177e4SLinus Torvalds add.l %d1,%a0 85151da177e4SLinus Torvalds fmov.s negone(%pc),%fp1 # FP1 IS K = -1 85161da177e4SLinus Torvalds bra.w LP1CONT1 85171da177e4SLinus Torvalds 85181da177e4SLinus TorvaldsKISZERO: 85191da177e4SLinus Torvalds fmov.s one(%pc),%fp0 85201da177e4SLinus Torvalds mov.l &0x3fff0000,F(%a6) 85211da177e4SLinus Torvalds clr.l F+8(%a6) 85221da177e4SLinus Torvalds fsub.x F(%a6),%fp0 # 1-F 85231da177e4SLinus Torvalds mov.l FFRAC(%a6),%d1 85241da177e4SLinus Torvalds and.l &0x7E000000,%d1 85251da177e4SLinus Torvalds asr.l &8,%d1 85261da177e4SLinus Torvalds asr.l &8,%d1 85271da177e4SLinus Torvalds asr.l &4,%d1 85281da177e4SLinus Torvalds fadd.x %fp1,%fp0 # FP0 IS Y-F 85291da177e4SLinus Torvalds fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3} 85301da177e4SLinus Torvalds lea LOGTBL(%pc),%a0 85311da177e4SLinus Torvalds add.l %d1,%a0 # A0 IS ADDRESS OF 1/F 85321da177e4SLinus Torvalds fmov.s zero(%pc),%fp1 # FP1 IS K = 0 85331da177e4SLinus Torvalds bra.w LP1CONT1 85341da177e4SLinus Torvalds 85351da177e4SLinus TorvaldsLP1NEG0: 85361da177e4SLinus Torvalds#--FPCR SAVED. D0 IS X IN COMPACT FORM. 85371da177e4SLinus Torvalds cmp.l %d1,&0 85381da177e4SLinus Torvalds blt.b LP1NEG 85391da177e4SLinus TorvaldsLP1ZERO: 85401da177e4SLinus Torvalds fmov.s negone(%pc),%fp0 85411da177e4SLinus Torvalds 85421da177e4SLinus Torvalds fmov.l %d0,%fpcr 85431da177e4SLinus Torvalds bra t_dz 85441da177e4SLinus Torvalds 85451da177e4SLinus TorvaldsLP1NEG: 85461da177e4SLinus Torvalds fmov.s zero(%pc),%fp0 85471da177e4SLinus Torvalds 85481da177e4SLinus Torvalds fmov.l %d0,%fpcr 85491da177e4SLinus Torvalds bra t_operr 85501da177e4SLinus Torvalds 85511da177e4SLinus Torvalds global slognp1d 85521da177e4SLinus Torvalds#--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT 85531da177e4SLinus Torvalds# Simply return the denorm 85541da177e4SLinus Torvaldsslognp1d: 85551da177e4SLinus Torvalds bra t_extdnrm 85561da177e4SLinus Torvalds 85571da177e4SLinus Torvalds######################################################################### 85581da177e4SLinus Torvalds# satanh(): computes the inverse hyperbolic tangent of a norm input # 85591da177e4SLinus Torvalds# satanhd(): computes the inverse hyperbolic tangent of a denorm input # 85601da177e4SLinus Torvalds# # 85611da177e4SLinus Torvalds# INPUT *************************************************************** # 85621da177e4SLinus Torvalds# a0 = pointer to extended precision input # 85631da177e4SLinus Torvalds# d0 = round precision,mode # 85641da177e4SLinus Torvalds# # 85651da177e4SLinus Torvalds# OUTPUT ************************************************************** # 85661da177e4SLinus Torvalds# fp0 = arctanh(X) # 85671da177e4SLinus Torvalds# # 85681da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 85691da177e4SLinus Torvalds# The returned result is within 3 ulps in 64 significant bit, # 85701da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 85711da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 85721da177e4SLinus Torvalds# in double precision. # 85731da177e4SLinus Torvalds# # 85741da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 85751da177e4SLinus Torvalds# # 85761da177e4SLinus Torvalds# ATANH # 85771da177e4SLinus Torvalds# 1. If |X| >= 1, go to 3. # 85781da177e4SLinus Torvalds# # 85791da177e4SLinus Torvalds# 2. (|X| < 1) Calculate atanh(X) by # 85801da177e4SLinus Torvalds# sgn := sign(X) # 85811da177e4SLinus Torvalds# y := |X| # 85821da177e4SLinus Torvalds# z := 2y/(1-y) # 85831da177e4SLinus Torvalds# atanh(X) := sgn * (1/2) * logp1(z) # 85841da177e4SLinus Torvalds# Exit. # 85851da177e4SLinus Torvalds# # 85861da177e4SLinus Torvalds# 3. If |X| > 1, go to 5. # 85871da177e4SLinus Torvalds# # 85881da177e4SLinus Torvalds# 4. (|X| = 1) Generate infinity with an appropriate sign and # 85891da177e4SLinus Torvalds# divide-by-zero by # 85901da177e4SLinus Torvalds# sgn := sign(X) # 85911da177e4SLinus Torvalds# atan(X) := sgn / (+0). # 85921da177e4SLinus Torvalds# Exit. # 85931da177e4SLinus Torvalds# # 85941da177e4SLinus Torvalds# 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 85951da177e4SLinus Torvalds# Exit. # 85961da177e4SLinus Torvalds# # 85971da177e4SLinus Torvalds######################################################################### 85981da177e4SLinus Torvalds 85991da177e4SLinus Torvalds global satanh 86001da177e4SLinus Torvaldssatanh: 86011da177e4SLinus Torvalds mov.l (%a0),%d1 86021da177e4SLinus Torvalds mov.w 4(%a0),%d1 86031da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 86041da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 86051da177e4SLinus Torvalds bge.b ATANHBIG 86061da177e4SLinus Torvalds 86071da177e4SLinus Torvalds#--THIS IS THE USUAL CASE, |X| < 1 86081da177e4SLinus Torvalds#--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z). 86091da177e4SLinus Torvalds 86101da177e4SLinus Torvalds fabs.x (%a0),%fp0 # Y = |X| 86111da177e4SLinus Torvalds fmov.x %fp0,%fp1 86121da177e4SLinus Torvalds fneg.x %fp1 # -Y 86131da177e4SLinus Torvalds fadd.x %fp0,%fp0 # 2Y 86141da177e4SLinus Torvalds fadd.s &0x3F800000,%fp1 # 1-Y 86151da177e4SLinus Torvalds fdiv.x %fp1,%fp0 # 2Y/(1-Y) 86161da177e4SLinus Torvalds mov.l (%a0),%d1 86171da177e4SLinus Torvalds and.l &0x80000000,%d1 86181da177e4SLinus Torvalds or.l &0x3F000000,%d1 # SIGN(X)*HALF 86191da177e4SLinus Torvalds mov.l %d1,-(%sp) 86201da177e4SLinus Torvalds 86211da177e4SLinus Torvalds mov.l %d0,-(%sp) # save rnd prec,mode 86221da177e4SLinus Torvalds clr.l %d0 # pass ext prec,RN 86231da177e4SLinus Torvalds fmovm.x &0x01,-(%sp) # save Z on stack 86241da177e4SLinus Torvalds lea (%sp),%a0 # pass ptr to Z 86251da177e4SLinus Torvalds bsr slognp1 # LOG1P(Z) 86261da177e4SLinus Torvalds add.l &0xc,%sp # clear Z from stack 86271da177e4SLinus Torvalds 86281da177e4SLinus Torvalds mov.l (%sp)+,%d0 # fetch old prec,mode 86291da177e4SLinus Torvalds fmov.l %d0,%fpcr # load it 86301da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 86311da177e4SLinus Torvalds fmul.s (%sp)+,%fp0 86321da177e4SLinus Torvalds bra t_catch 86331da177e4SLinus Torvalds 86341da177e4SLinus TorvaldsATANHBIG: 86351da177e4SLinus Torvalds fabs.x (%a0),%fp0 # |X| 86361da177e4SLinus Torvalds fcmp.s %fp0,&0x3F800000 86371da177e4SLinus Torvalds fbgt t_operr 86381da177e4SLinus Torvalds bra t_dz 86391da177e4SLinus Torvalds 86401da177e4SLinus Torvalds global satanhd 86411da177e4SLinus Torvalds#--ATANH(X) = X FOR DENORMALIZED X 86421da177e4SLinus Torvaldssatanhd: 86431da177e4SLinus Torvalds bra t_extdnrm 86441da177e4SLinus Torvalds 86451da177e4SLinus Torvalds######################################################################### 86461da177e4SLinus Torvalds# slog10(): computes the base-10 logarithm of a normalized input # 86471da177e4SLinus Torvalds# slog10d(): computes the base-10 logarithm of a denormalized input # 86481da177e4SLinus Torvalds# slog2(): computes the base-2 logarithm of a normalized input # 86491da177e4SLinus Torvalds# slog2d(): computes the base-2 logarithm of a denormalized input # 86501da177e4SLinus Torvalds# # 86511da177e4SLinus Torvalds# INPUT *************************************************************** # 86521da177e4SLinus Torvalds# a0 = pointer to extended precision input # 86531da177e4SLinus Torvalds# d0 = round precision,mode # 86541da177e4SLinus Torvalds# # 86551da177e4SLinus Torvalds# OUTPUT ************************************************************** # 86561da177e4SLinus Torvalds# fp0 = log_10(X) or log_2(X) # 86571da177e4SLinus Torvalds# # 86581da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 86591da177e4SLinus Torvalds# The returned result is within 1.7 ulps in 64 significant bit, # 86601da177e4SLinus Torvalds# i.e. within 0.5003 ulp to 53 bits if the result is subsequently # 86611da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 86621da177e4SLinus Torvalds# in double precision. # 86631da177e4SLinus Torvalds# # 86641da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 86651da177e4SLinus Torvalds# # 86661da177e4SLinus Torvalds# slog10d: # 86671da177e4SLinus Torvalds# # 86681da177e4SLinus Torvalds# Step 0. If X < 0, create a NaN and raise the invalid operation # 86691da177e4SLinus Torvalds# flag. Otherwise, save FPCR in D1; set FpCR to default. # 86701da177e4SLinus Torvalds# Notes: Default means round-to-nearest mode, no floating-point # 86711da177e4SLinus Torvalds# traps, and precision control = double extended. # 86721da177e4SLinus Torvalds# # 86731da177e4SLinus Torvalds# Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 86741da177e4SLinus Torvalds# Notes: Even if X is denormalized, log(X) is always normalized. # 86751da177e4SLinus Torvalds# # 86761da177e4SLinus Torvalds# Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 86771da177e4SLinus Torvalds# 2.1 Restore the user FPCR # 86781da177e4SLinus Torvalds# 2.2 Return ans := Y * INV_L10. # 86791da177e4SLinus Torvalds# # 86801da177e4SLinus Torvalds# slog10: # 86811da177e4SLinus Torvalds# # 86821da177e4SLinus Torvalds# Step 0. If X < 0, create a NaN and raise the invalid operation # 86831da177e4SLinus Torvalds# flag. Otherwise, save FPCR in D1; set FpCR to default. # 86841da177e4SLinus Torvalds# Notes: Default means round-to-nearest mode, no floating-point # 86851da177e4SLinus Torvalds# traps, and precision control = double extended. # 86861da177e4SLinus Torvalds# # 86871da177e4SLinus Torvalds# Step 1. Call sLogN to obtain Y = log(X), the natural log of X. # 86881da177e4SLinus Torvalds# # 86891da177e4SLinus Torvalds# Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 86901da177e4SLinus Torvalds# 2.1 Restore the user FPCR # 86911da177e4SLinus Torvalds# 2.2 Return ans := Y * INV_L10. # 86921da177e4SLinus Torvalds# # 86931da177e4SLinus Torvalds# sLog2d: # 86941da177e4SLinus Torvalds# # 86951da177e4SLinus Torvalds# Step 0. If X < 0, create a NaN and raise the invalid operation # 86961da177e4SLinus Torvalds# flag. Otherwise, save FPCR in D1; set FpCR to default. # 86971da177e4SLinus Torvalds# Notes: Default means round-to-nearest mode, no floating-point # 86981da177e4SLinus Torvalds# traps, and precision control = double extended. # 86991da177e4SLinus Torvalds# # 87001da177e4SLinus Torvalds# Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 87011da177e4SLinus Torvalds# Notes: Even if X is denormalized, log(X) is always normalized. # 87021da177e4SLinus Torvalds# # 87031da177e4SLinus Torvalds# Step 2. Compute log_10(X) = log(X) * (1/log(2)). # 87041da177e4SLinus Torvalds# 2.1 Restore the user FPCR # 87051da177e4SLinus Torvalds# 2.2 Return ans := Y * INV_L2. # 87061da177e4SLinus Torvalds# # 87071da177e4SLinus Torvalds# sLog2: # 87081da177e4SLinus Torvalds# # 87091da177e4SLinus Torvalds# Step 0. If X < 0, create a NaN and raise the invalid operation # 87101da177e4SLinus Torvalds# flag. Otherwise, save FPCR in D1; set FpCR to default. # 87111da177e4SLinus Torvalds# Notes: Default means round-to-nearest mode, no floating-point # 87121da177e4SLinus Torvalds# traps, and precision control = double extended. # 87131da177e4SLinus Torvalds# # 87141da177e4SLinus Torvalds# Step 1. If X is not an integer power of two, i.e., X != 2^k, # 87151da177e4SLinus Torvalds# go to Step 3. # 87161da177e4SLinus Torvalds# # 87171da177e4SLinus Torvalds# Step 2. Return k. # 87181da177e4SLinus Torvalds# 2.1 Get integer k, X = 2^k. # 87191da177e4SLinus Torvalds# 2.2 Restore the user FPCR. # 87201da177e4SLinus Torvalds# 2.3 Return ans := convert-to-double-extended(k). # 87211da177e4SLinus Torvalds# # 87221da177e4SLinus Torvalds# Step 3. Call sLogN to obtain Y = log(X), the natural log of X. # 87231da177e4SLinus Torvalds# # 87241da177e4SLinus Torvalds# Step 4. Compute log_2(X) = log(X) * (1/log(2)). # 87251da177e4SLinus Torvalds# 4.1 Restore the user FPCR # 87261da177e4SLinus Torvalds# 4.2 Return ans := Y * INV_L2. # 87271da177e4SLinus Torvalds# # 87281da177e4SLinus Torvalds######################################################################### 87291da177e4SLinus Torvalds 87301da177e4SLinus TorvaldsINV_L10: 87311da177e4SLinus Torvalds long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 87321da177e4SLinus Torvalds 87331da177e4SLinus TorvaldsINV_L2: 87341da177e4SLinus Torvalds long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 87351da177e4SLinus Torvalds 87361da177e4SLinus Torvalds global slog10 87371da177e4SLinus Torvalds#--entry point for Log10(X), X is normalized 87381da177e4SLinus Torvaldsslog10: 87391da177e4SLinus Torvalds fmov.b &0x1,%fp0 87401da177e4SLinus Torvalds fcmp.x %fp0,(%a0) # if operand == 1, 87411da177e4SLinus Torvalds fbeq.l ld_pzero # return an EXACT zero 87421da177e4SLinus Torvalds 87431da177e4SLinus Torvalds mov.l (%a0),%d1 87441da177e4SLinus Torvalds blt.w invalid 87451da177e4SLinus Torvalds mov.l %d0,-(%sp) 87461da177e4SLinus Torvalds clr.l %d0 87471da177e4SLinus Torvalds bsr slogn # log(X), X normal. 87481da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr 87491da177e4SLinus Torvalds fmul.x INV_L10(%pc),%fp0 87501da177e4SLinus Torvalds bra t_inx2 87511da177e4SLinus Torvalds 87521da177e4SLinus Torvalds global slog10d 87531da177e4SLinus Torvalds#--entry point for Log10(X), X is denormalized 87541da177e4SLinus Torvaldsslog10d: 87551da177e4SLinus Torvalds mov.l (%a0),%d1 87561da177e4SLinus Torvalds blt.w invalid 87571da177e4SLinus Torvalds mov.l %d0,-(%sp) 87581da177e4SLinus Torvalds clr.l %d0 87591da177e4SLinus Torvalds bsr slognd # log(X), X denorm. 87601da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr 87611da177e4SLinus Torvalds fmul.x INV_L10(%pc),%fp0 87621da177e4SLinus Torvalds bra t_minx2 87631da177e4SLinus Torvalds 87641da177e4SLinus Torvalds global slog2 87651da177e4SLinus Torvalds#--entry point for Log2(X), X is normalized 87661da177e4SLinus Torvaldsslog2: 87671da177e4SLinus Torvalds mov.l (%a0),%d1 87681da177e4SLinus Torvalds blt.w invalid 87691da177e4SLinus Torvalds 87701da177e4SLinus Torvalds mov.l 8(%a0),%d1 87711da177e4SLinus Torvalds bne.b continue # X is not 2^k 87721da177e4SLinus Torvalds 87731da177e4SLinus Torvalds mov.l 4(%a0),%d1 87741da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 87751da177e4SLinus Torvalds bne.b continue 87761da177e4SLinus Torvalds 87771da177e4SLinus Torvalds#--X = 2^k. 87781da177e4SLinus Torvalds mov.w (%a0),%d1 87791da177e4SLinus Torvalds and.l &0x00007FFF,%d1 87801da177e4SLinus Torvalds sub.l &0x3FFF,%d1 87811da177e4SLinus Torvalds beq.l ld_pzero 87821da177e4SLinus Torvalds fmov.l %d0,%fpcr 87831da177e4SLinus Torvalds fmov.l %d1,%fp0 87841da177e4SLinus Torvalds bra t_inx2 87851da177e4SLinus Torvalds 87861da177e4SLinus Torvaldscontinue: 87871da177e4SLinus Torvalds mov.l %d0,-(%sp) 87881da177e4SLinus Torvalds clr.l %d0 87891da177e4SLinus Torvalds bsr slogn # log(X), X normal. 87901da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr 87911da177e4SLinus Torvalds fmul.x INV_L2(%pc),%fp0 87921da177e4SLinus Torvalds bra t_inx2 87931da177e4SLinus Torvalds 87941da177e4SLinus Torvaldsinvalid: 87951da177e4SLinus Torvalds bra t_operr 87961da177e4SLinus Torvalds 87971da177e4SLinus Torvalds global slog2d 87981da177e4SLinus Torvalds#--entry point for Log2(X), X is denormalized 87991da177e4SLinus Torvaldsslog2d: 88001da177e4SLinus Torvalds mov.l (%a0),%d1 88011da177e4SLinus Torvalds blt.w invalid 88021da177e4SLinus Torvalds mov.l %d0,-(%sp) 88031da177e4SLinus Torvalds clr.l %d0 88041da177e4SLinus Torvalds bsr slognd # log(X), X denorm. 88051da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr 88061da177e4SLinus Torvalds fmul.x INV_L2(%pc),%fp0 88071da177e4SLinus Torvalds bra t_minx2 88081da177e4SLinus Torvalds 88091da177e4SLinus Torvalds######################################################################### 88101da177e4SLinus Torvalds# stwotox(): computes 2**X for a normalized input # 88111da177e4SLinus Torvalds# stwotoxd(): computes 2**X for a denormalized input # 88121da177e4SLinus Torvalds# stentox(): computes 10**X for a normalized input # 88131da177e4SLinus Torvalds# stentoxd(): computes 10**X for a denormalized input # 88141da177e4SLinus Torvalds# # 88151da177e4SLinus Torvalds# INPUT *************************************************************** # 88161da177e4SLinus Torvalds# a0 = pointer to extended precision input # 88171da177e4SLinus Torvalds# d0 = round precision,mode # 88181da177e4SLinus Torvalds# # 88191da177e4SLinus Torvalds# OUTPUT ************************************************************** # 88201da177e4SLinus Torvalds# fp0 = 2**X or 10**X # 88211da177e4SLinus Torvalds# # 88221da177e4SLinus Torvalds# ACCURACY and MONOTONICITY ******************************************* # 88231da177e4SLinus Torvalds# The returned result is within 2 ulps in 64 significant bit, # 88241da177e4SLinus Torvalds# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 88251da177e4SLinus Torvalds# rounded to double precision. The result is provably monotonic # 88261da177e4SLinus Torvalds# in double precision. # 88271da177e4SLinus Torvalds# # 88281da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 88291da177e4SLinus Torvalds# # 88301da177e4SLinus Torvalds# twotox # 88311da177e4SLinus Torvalds# 1. If |X| > 16480, go to ExpBig. # 88321da177e4SLinus Torvalds# # 88331da177e4SLinus Torvalds# 2. If |X| < 2**(-70), go to ExpSm. # 88341da177e4SLinus Torvalds# # 88351da177e4SLinus Torvalds# 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore # 88361da177e4SLinus Torvalds# decompose N as # 88371da177e4SLinus Torvalds# N = 64(M + M') + j, j = 0,1,2,...,63. # 88381da177e4SLinus Torvalds# # 88391da177e4SLinus Torvalds# 4. Overwrite r := r * log2. Then # 88401da177e4SLinus Torvalds# 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 88411da177e4SLinus Torvalds# Go to expr to compute that expression. # 88421da177e4SLinus Torvalds# # 88431da177e4SLinus Torvalds# tentox # 88441da177e4SLinus Torvalds# 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. # 88451da177e4SLinus Torvalds# # 88461da177e4SLinus Torvalds# 2. If |X| < 2**(-70), go to ExpSm. # 88471da177e4SLinus Torvalds# # 88481da177e4SLinus Torvalds# 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set # 88491da177e4SLinus Torvalds# N := round-to-int(y). Decompose N as # 88501da177e4SLinus Torvalds# N = 64(M + M') + j, j = 0,1,2,...,63. # 88511da177e4SLinus Torvalds# # 88521da177e4SLinus Torvalds# 4. Define r as # 88531da177e4SLinus Torvalds# r := ((X - N*L1)-N*L2) * L10 # 88541da177e4SLinus Torvalds# where L1, L2 are the leading and trailing parts of # 88551da177e4SLinus Torvalds# log_10(2)/64 and L10 is the natural log of 10. Then # 88561da177e4SLinus Torvalds# 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 88571da177e4SLinus Torvalds# Go to expr to compute that expression. # 88581da177e4SLinus Torvalds# # 88591da177e4SLinus Torvalds# expr # 88601da177e4SLinus Torvalds# 1. Fetch 2**(j/64) from table as Fact1 and Fact2. # 88611da177e4SLinus Torvalds# # 88621da177e4SLinus Torvalds# 2. Overwrite Fact1 and Fact2 by # 88631da177e4SLinus Torvalds# Fact1 := 2**(M) * Fact1 # 88641da177e4SLinus Torvalds# Fact2 := 2**(M) * Fact2 # 88651da177e4SLinus Torvalds# Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). # 88661da177e4SLinus Torvalds# # 88671da177e4SLinus Torvalds# 3. Calculate P where 1 + P approximates exp(r): # 88681da177e4SLinus Torvalds# P = r + r*r*(A1+r*(A2+...+r*A5)). # 88691da177e4SLinus Torvalds# # 88701da177e4SLinus Torvalds# 4. Let AdjFact := 2**(M'). Return # 88711da177e4SLinus Torvalds# AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). # 88721da177e4SLinus Torvalds# Exit. # 88731da177e4SLinus Torvalds# # 88741da177e4SLinus Torvalds# ExpBig # 88751da177e4SLinus Torvalds# 1. Generate overflow by Huge * Huge if X > 0; otherwise, # 88761da177e4SLinus Torvalds# generate underflow by Tiny * Tiny. # 88771da177e4SLinus Torvalds# # 88781da177e4SLinus Torvalds# ExpSm # 88791da177e4SLinus Torvalds# 1. Return 1 + X. # 88801da177e4SLinus Torvalds# # 88811da177e4SLinus Torvalds######################################################################### 88821da177e4SLinus Torvalds 88831da177e4SLinus TorvaldsL2TEN64: 88841da177e4SLinus Torvalds long 0x406A934F,0x0979A371 # 64LOG10/LOG2 88851da177e4SLinus TorvaldsL10TWO1: 88861da177e4SLinus Torvalds long 0x3F734413,0x509F8000 # LOG2/64LOG10 88871da177e4SLinus Torvalds 88881da177e4SLinus TorvaldsL10TWO2: 88891da177e4SLinus Torvalds long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000 88901da177e4SLinus Torvalds 88911da177e4SLinus TorvaldsLOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000 88921da177e4SLinus Torvalds 88931da177e4SLinus TorvaldsLOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 88941da177e4SLinus Torvalds 88951da177e4SLinus TorvaldsEXPA5: long 0x3F56C16D,0x6F7BD0B2 88961da177e4SLinus TorvaldsEXPA4: long 0x3F811112,0x302C712C 88971da177e4SLinus TorvaldsEXPA3: long 0x3FA55555,0x55554CC1 88981da177e4SLinus TorvaldsEXPA2: long 0x3FC55555,0x55554A54 88991da177e4SLinus TorvaldsEXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000 89001da177e4SLinus Torvalds 89011da177e4SLinus TorvaldsTEXPTBL: 89021da177e4SLinus Torvalds long 0x3FFF0000,0x80000000,0x00000000,0x3F738000 89031da177e4SLinus Torvalds long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA 89041da177e4SLinus Torvalds long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9 89051da177e4SLinus Torvalds long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9 89061da177e4SLinus Torvalds long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA 89071da177e4SLinus Torvalds long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C 89081da177e4SLinus Torvalds long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1 89091da177e4SLinus Torvalds long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA 89101da177e4SLinus Torvalds long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373 89111da177e4SLinus Torvalds long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670 89121da177e4SLinus Torvalds long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700 89131da177e4SLinus Torvalds long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0 89141da177e4SLinus Torvalds long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D 89151da177e4SLinus Torvalds long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319 89161da177e4SLinus Torvalds long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B 89171da177e4SLinus Torvalds long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5 89181da177e4SLinus Torvalds long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A 89191da177e4SLinus Torvalds long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B 89201da177e4SLinus Torvalds long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF 89211da177e4SLinus Torvalds long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA 89221da177e4SLinus Torvalds long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD 89231da177e4SLinus Torvalds long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E 89241da177e4SLinus Torvalds long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B 89251da177e4SLinus Torvalds long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB 89261da177e4SLinus Torvalds long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB 89271da177e4SLinus Torvalds long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274 89281da177e4SLinus Torvalds long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C 89291da177e4SLinus Torvalds long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00 89301da177e4SLinus Torvalds long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301 89311da177e4SLinus Torvalds long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367 89321da177e4SLinus Torvalds long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F 89331da177e4SLinus Torvalds long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C 89341da177e4SLinus Torvalds long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB 89351da177e4SLinus Torvalds long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB 89361da177e4SLinus Torvalds long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C 89371da177e4SLinus Torvalds long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA 89381da177e4SLinus Torvalds long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD 89391da177e4SLinus Torvalds long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51 89401da177e4SLinus Torvalds long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A 89411da177e4SLinus Torvalds long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2 89421da177e4SLinus Torvalds long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB 89431da177e4SLinus Torvalds long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17 89441da177e4SLinus Torvalds long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C 89451da177e4SLinus Torvalds long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8 89461da177e4SLinus Torvalds long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53 89471da177e4SLinus Torvalds long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE 89481da177e4SLinus Torvalds long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124 89491da177e4SLinus Torvalds long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243 89501da177e4SLinus Torvalds long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A 89511da177e4SLinus Torvalds long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61 89521da177e4SLinus Torvalds long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610 89531da177e4SLinus Torvalds long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1 89541da177e4SLinus Torvalds long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12 89551da177e4SLinus Torvalds long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE 89561da177e4SLinus Torvalds long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4 89571da177e4SLinus Torvalds long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F 89581da177e4SLinus Torvalds long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A 89591da177e4SLinus Torvalds long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A 89601da177e4SLinus Torvalds long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC 89611da177e4SLinus Torvalds long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F 89621da177e4SLinus Torvalds long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A 89631da177e4SLinus Torvalds long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795 89641da177e4SLinus Torvalds long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B 89651da177e4SLinus Torvalds long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581 89661da177e4SLinus Torvalds 89671da177e4SLinus Torvalds set INT,L_SCR1 89681da177e4SLinus Torvalds 89691da177e4SLinus Torvalds set X,FP_SCR0 89701da177e4SLinus Torvalds set XDCARE,X+2 89711da177e4SLinus Torvalds set XFRAC,X+4 89721da177e4SLinus Torvalds 89731da177e4SLinus Torvalds set ADJFACT,FP_SCR0 89741da177e4SLinus Torvalds 89751da177e4SLinus Torvalds set FACT1,FP_SCR0 89761da177e4SLinus Torvalds set FACT1HI,FACT1+4 89771da177e4SLinus Torvalds set FACT1LOW,FACT1+8 89781da177e4SLinus Torvalds 89791da177e4SLinus Torvalds set FACT2,FP_SCR1 89801da177e4SLinus Torvalds set FACT2HI,FACT2+4 89811da177e4SLinus Torvalds set FACT2LOW,FACT2+8 89821da177e4SLinus Torvalds 89831da177e4SLinus Torvalds global stwotox 89841da177e4SLinus Torvalds#--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 89851da177e4SLinus Torvaldsstwotox: 89861da177e4SLinus Torvalds fmovm.x (%a0),&0x80 # LOAD INPUT 89871da177e4SLinus Torvalds 89881da177e4SLinus Torvalds mov.l (%a0),%d1 89891da177e4SLinus Torvalds mov.w 4(%a0),%d1 89901da177e4SLinus Torvalds fmov.x %fp0,X(%a6) 89911da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 89921da177e4SLinus Torvalds 89931da177e4SLinus Torvalds cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 89941da177e4SLinus Torvalds bge.b TWOOK1 89951da177e4SLinus Torvalds bra.w EXPBORS 89961da177e4SLinus Torvalds 89971da177e4SLinus TorvaldsTWOOK1: 89981da177e4SLinus Torvalds cmp.l %d1,&0x400D80C0 # |X| > 16480? 89991da177e4SLinus Torvalds ble.b TWOMAIN 90001da177e4SLinus Torvalds bra.w EXPBORS 90011da177e4SLinus Torvalds 90021da177e4SLinus TorvaldsTWOMAIN: 90031da177e4SLinus Torvalds#--USUAL CASE, 2^(-70) <= |X| <= 16480 90041da177e4SLinus Torvalds 90051da177e4SLinus Torvalds fmov.x %fp0,%fp1 90061da177e4SLinus Torvalds fmul.s &0x42800000,%fp1 # 64 * X 90071da177e4SLinus Torvalds fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X) 90081da177e4SLinus Torvalds mov.l %d2,-(%sp) 90091da177e4SLinus Torvalds lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 90101da177e4SLinus Torvalds fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 90111da177e4SLinus Torvalds mov.l INT(%a6),%d1 90121da177e4SLinus Torvalds mov.l %d1,%d2 90131da177e4SLinus Torvalds and.l &0x3F,%d1 # D0 IS J 90141da177e4SLinus Torvalds asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 90151da177e4SLinus Torvalds add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 90161da177e4SLinus Torvalds asr.l &6,%d2 # d2 IS L, N = 64L + J 90171da177e4SLinus Torvalds mov.l %d2,%d1 90181da177e4SLinus Torvalds asr.l &1,%d1 # D0 IS M 90191da177e4SLinus Torvalds sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 90201da177e4SLinus Torvalds add.l &0x3FFF,%d2 90211da177e4SLinus Torvalds 90221da177e4SLinus Torvalds#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 90231da177e4SLinus Torvalds#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 90241da177e4SLinus Torvalds#--ADJFACT = 2^(M'). 90251da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 90261da177e4SLinus Torvalds 90271da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2/fp3 90281da177e4SLinus Torvalds 90291da177e4SLinus Torvalds fmul.s &0x3C800000,%fp1 # (1/64)*N 90301da177e4SLinus Torvalds mov.l (%a1)+,FACT1(%a6) 90311da177e4SLinus Torvalds mov.l (%a1)+,FACT1HI(%a6) 90321da177e4SLinus Torvalds mov.l (%a1)+,FACT1LOW(%a6) 90331da177e4SLinus Torvalds mov.w (%a1)+,FACT2(%a6) 90341da177e4SLinus Torvalds 90351da177e4SLinus Torvalds fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X) 90361da177e4SLinus Torvalds 90371da177e4SLinus Torvalds mov.w (%a1)+,FACT2HI(%a6) 90381da177e4SLinus Torvalds clr.w FACT2HI+2(%a6) 90391da177e4SLinus Torvalds clr.l FACT2LOW(%a6) 90401da177e4SLinus Torvalds add.w %d1,FACT1(%a6) 90411da177e4SLinus Torvalds fmul.x LOG2(%pc),%fp0 # FP0 IS R 90421da177e4SLinus Torvalds add.w %d1,FACT2(%a6) 90431da177e4SLinus Torvalds 90441da177e4SLinus Torvalds bra.w expr 90451da177e4SLinus Torvalds 90461da177e4SLinus TorvaldsEXPBORS: 90471da177e4SLinus Torvalds#--FPCR, D0 SAVED 90481da177e4SLinus Torvalds cmp.l %d1,&0x3FFF8000 90491da177e4SLinus Torvalds bgt.b TEXPBIG 90501da177e4SLinus Torvalds 90511da177e4SLinus Torvalds#--|X| IS SMALL, RETURN 1 + X 90521da177e4SLinus Torvalds 90531da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round prec,mode 90541da177e4SLinus Torvalds fadd.s &0x3F800000,%fp0 # RETURN 1 + X 90551da177e4SLinus Torvalds bra t_pinx2 90561da177e4SLinus Torvalds 90571da177e4SLinus TorvaldsTEXPBIG: 90581da177e4SLinus Torvalds#--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW 90591da177e4SLinus Torvalds#--REGISTERS SAVE SO FAR ARE FPCR AND D0 90601da177e4SLinus Torvalds mov.l X(%a6),%d1 90611da177e4SLinus Torvalds cmp.l %d1,&0 90621da177e4SLinus Torvalds blt.b EXPNEG 90631da177e4SLinus Torvalds 90641da177e4SLinus Torvalds bra t_ovfl2 # t_ovfl expects positive value 90651da177e4SLinus Torvalds 90661da177e4SLinus TorvaldsEXPNEG: 90671da177e4SLinus Torvalds bra t_unfl2 # t_unfl expects positive value 90681da177e4SLinus Torvalds 90691da177e4SLinus Torvalds global stwotoxd 90701da177e4SLinus Torvaldsstwotoxd: 90711da177e4SLinus Torvalds#--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT 90721da177e4SLinus Torvalds 90731da177e4SLinus Torvalds fmov.l %d0,%fpcr # set user's rounding mode/precision 90741da177e4SLinus Torvalds fmov.s &0x3F800000,%fp0 # RETURN 1 + X 90751da177e4SLinus Torvalds mov.l (%a0),%d1 90761da177e4SLinus Torvalds or.l &0x00800001,%d1 90771da177e4SLinus Torvalds fadd.s %d1,%fp0 90781da177e4SLinus Torvalds bra t_pinx2 90791da177e4SLinus Torvalds 90801da177e4SLinus Torvalds global stentox 90811da177e4SLinus Torvalds#--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 90821da177e4SLinus Torvaldsstentox: 90831da177e4SLinus Torvalds fmovm.x (%a0),&0x80 # LOAD INPUT 90841da177e4SLinus Torvalds 90851da177e4SLinus Torvalds mov.l (%a0),%d1 90861da177e4SLinus Torvalds mov.w 4(%a0),%d1 90871da177e4SLinus Torvalds fmov.x %fp0,X(%a6) 90881da177e4SLinus Torvalds and.l &0x7FFFFFFF,%d1 90891da177e4SLinus Torvalds 90901da177e4SLinus Torvalds cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 90911da177e4SLinus Torvalds bge.b TENOK1 90921da177e4SLinus Torvalds bra.w EXPBORS 90931da177e4SLinus Torvalds 90941da177e4SLinus TorvaldsTENOK1: 90951da177e4SLinus Torvalds cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ? 90961da177e4SLinus Torvalds ble.b TENMAIN 90971da177e4SLinus Torvalds bra.w EXPBORS 90981da177e4SLinus Torvalds 90991da177e4SLinus TorvaldsTENMAIN: 91001da177e4SLinus Torvalds#--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10 91011da177e4SLinus Torvalds 91021da177e4SLinus Torvalds fmov.x %fp0,%fp1 91031da177e4SLinus Torvalds fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2 91041da177e4SLinus Torvalds fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2) 91051da177e4SLinus Torvalds mov.l %d2,-(%sp) 91061da177e4SLinus Torvalds lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 91071da177e4SLinus Torvalds fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 91081da177e4SLinus Torvalds mov.l INT(%a6),%d1 91091da177e4SLinus Torvalds mov.l %d1,%d2 91101da177e4SLinus Torvalds and.l &0x3F,%d1 # D0 IS J 91111da177e4SLinus Torvalds asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 91121da177e4SLinus Torvalds add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 91131da177e4SLinus Torvalds asr.l &6,%d2 # d2 IS L, N = 64L + J 91141da177e4SLinus Torvalds mov.l %d2,%d1 91151da177e4SLinus Torvalds asr.l &1,%d1 # D0 IS M 91161da177e4SLinus Torvalds sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 91171da177e4SLinus Torvalds add.l &0x3FFF,%d2 91181da177e4SLinus Torvalds 91191da177e4SLinus Torvalds#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 91201da177e4SLinus Torvalds#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 91211da177e4SLinus Torvalds#--ADJFACT = 2^(M'). 91221da177e4SLinus Torvalds#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 91231da177e4SLinus Torvalds fmovm.x &0x0c,-(%sp) # save fp2/fp3 91241da177e4SLinus Torvalds 91251da177e4SLinus Torvalds fmov.x %fp1,%fp2 91261da177e4SLinus Torvalds 91271da177e4SLinus Torvalds fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD 91281da177e4SLinus Torvalds mov.l (%a1)+,FACT1(%a6) 91291da177e4SLinus Torvalds 91301da177e4SLinus Torvalds fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL 91311da177e4SLinus Torvalds 91321da177e4SLinus Torvalds mov.l (%a1)+,FACT1HI(%a6) 91331da177e4SLinus Torvalds mov.l (%a1)+,FACT1LOW(%a6) 91341da177e4SLinus Torvalds fsub.x %fp1,%fp0 # X - N L_LEAD 91351da177e4SLinus Torvalds mov.w (%a1)+,FACT2(%a6) 91361da177e4SLinus Torvalds 91371da177e4SLinus Torvalds fsub.x %fp2,%fp0 # X - N L_TRAIL 91381da177e4SLinus Torvalds 91391da177e4SLinus Torvalds mov.w (%a1)+,FACT2HI(%a6) 91401da177e4SLinus Torvalds clr.w FACT2HI+2(%a6) 91411da177e4SLinus Torvalds clr.l FACT2LOW(%a6) 91421da177e4SLinus Torvalds 91431da177e4SLinus Torvalds fmul.x LOG10(%pc),%fp0 # FP0 IS R 91441da177e4SLinus Torvalds add.w %d1,FACT1(%a6) 91451da177e4SLinus Torvalds add.w %d1,FACT2(%a6) 91461da177e4SLinus Torvalds 91471da177e4SLinus Torvaldsexpr: 91481da177e4SLinus Torvalds#--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN. 91491da177e4SLinus Torvalds#--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64). 91501da177e4SLinus Torvalds#--FP0 IS R. THE FOLLOWING CODE COMPUTES 91511da177e4SLinus Torvalds#-- 2**(M'+M) * 2**(J/64) * EXP(R) 91521da177e4SLinus Torvalds 91531da177e4SLinus Torvalds fmov.x %fp0,%fp1 91541da177e4SLinus Torvalds fmul.x %fp1,%fp1 # FP1 IS S = R*R 91551da177e4SLinus Torvalds 91561da177e4SLinus Torvalds fmov.d EXPA5(%pc),%fp2 # FP2 IS A5 91571da177e4SLinus Torvalds fmov.d EXPA4(%pc),%fp3 # FP3 IS A4 91581da177e4SLinus Torvalds 91591da177e4SLinus Torvalds fmul.x %fp1,%fp2 # FP2 IS S*A5 91601da177e4SLinus Torvalds fmul.x %fp1,%fp3 # FP3 IS S*A4 91611da177e4SLinus Torvalds 91621da177e4SLinus Torvalds fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5 91631da177e4SLinus Torvalds fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4 91641da177e4SLinus Torvalds 91651da177e4SLinus Torvalds fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5) 91661da177e4SLinus Torvalds fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4) 91671da177e4SLinus Torvalds 91681da177e4SLinus Torvalds fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5) 91691da177e4SLinus Torvalds fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4) 91701da177e4SLinus Torvalds 91711da177e4SLinus Torvalds fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5)) 91721da177e4SLinus Torvalds fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4) 91731da177e4SLinus Torvalds fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1 91741da177e4SLinus Torvalds 91751da177e4SLinus Torvalds fmovm.x (%sp)+,&0x30 # restore fp2/fp3 91761da177e4SLinus Torvalds 91771da177e4SLinus Torvalds#--FINAL RECONSTRUCTION PROCESS 91781da177e4SLinus Torvalds#--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1) - (1 OR 0) 91791da177e4SLinus Torvalds 91801da177e4SLinus Torvalds fmul.x FACT1(%a6),%fp0 91811da177e4SLinus Torvalds fadd.x FACT2(%a6),%fp0 91821da177e4SLinus Torvalds fadd.x FACT1(%a6),%fp0 91831da177e4SLinus Torvalds 91841da177e4SLinus Torvalds fmov.l %d0,%fpcr # restore users round prec,mode 91851da177e4SLinus Torvalds mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT 91861da177e4SLinus Torvalds mov.l (%sp)+,%d2 91871da177e4SLinus Torvalds mov.l &0x80000000,ADJFACT+4(%a6) 91881da177e4SLinus Torvalds clr.l ADJFACT+8(%a6) 91891da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 91901da177e4SLinus Torvalds fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT 91911da177e4SLinus Torvalds bra t_catch 91921da177e4SLinus Torvalds 91931da177e4SLinus Torvalds global stentoxd 91941da177e4SLinus Torvaldsstentoxd: 91951da177e4SLinus Torvalds#--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT 91961da177e4SLinus Torvalds 91971da177e4SLinus Torvalds fmov.l %d0,%fpcr # set user's rounding mode/precision 91981da177e4SLinus Torvalds fmov.s &0x3F800000,%fp0 # RETURN 1 + X 91991da177e4SLinus Torvalds mov.l (%a0),%d1 92001da177e4SLinus Torvalds or.l &0x00800001,%d1 92011da177e4SLinus Torvalds fadd.s %d1,%fp0 92021da177e4SLinus Torvalds bra t_pinx2 92031da177e4SLinus Torvalds 92041da177e4SLinus Torvalds######################################################################### 92051da177e4SLinus Torvalds# sscale(): computes the destination operand scaled by the source # 92061da177e4SLinus Torvalds# operand. If the absoulute value of the source operand is # 92071da177e4SLinus Torvalds# >= 2^14, an overflow or underflow is returned. # 92081da177e4SLinus Torvalds# # 92091da177e4SLinus Torvalds# INPUT *************************************************************** # 92101da177e4SLinus Torvalds# a0 = pointer to double-extended source operand X # 92111da177e4SLinus Torvalds# a1 = pointer to double-extended destination operand Y # 92121da177e4SLinus Torvalds# # 92131da177e4SLinus Torvalds# OUTPUT ************************************************************** # 92141da177e4SLinus Torvalds# fp0 = scale(X,Y) # 92151da177e4SLinus Torvalds# # 92161da177e4SLinus Torvalds######################################################################### 92171da177e4SLinus Torvalds 92181da177e4SLinus Torvaldsset SIGN, L_SCR1 92191da177e4SLinus Torvalds 92201da177e4SLinus Torvalds global sscale 92211da177e4SLinus Torvaldssscale: 92221da177e4SLinus Torvalds mov.l %d0,-(%sp) # store off ctrl bits for now 92231da177e4SLinus Torvalds 92241da177e4SLinus Torvalds mov.w DST_EX(%a1),%d1 # get dst exponent 92251da177e4SLinus Torvalds smi.b SIGN(%a6) # use SIGN to hold dst sign 92261da177e4SLinus Torvalds andi.l &0x00007fff,%d1 # strip sign from dst exp 92271da177e4SLinus Torvalds 92281da177e4SLinus Torvalds mov.w SRC_EX(%a0),%d0 # check src bounds 92291da177e4SLinus Torvalds andi.w &0x7fff,%d0 # clr src sign bit 92301da177e4SLinus Torvalds cmpi.w %d0,&0x3fff # is src ~ ZERO? 92311da177e4SLinus Torvalds blt.w src_small # yes 92321da177e4SLinus Torvalds cmpi.w %d0,&0x400c # no; is src too big? 92331da177e4SLinus Torvalds bgt.w src_out # yes 92341da177e4SLinus Torvalds 92351da177e4SLinus Torvalds# 92361da177e4SLinus Torvalds# Source is within 2^14 range. 92371da177e4SLinus Torvalds# 92381da177e4SLinus Torvaldssrc_ok: 92391da177e4SLinus Torvalds fintrz.x SRC(%a0),%fp0 # calc int of src 92401da177e4SLinus Torvalds fmov.l %fp0,%d0 # int src to d0 92411da177e4SLinus Torvalds# don't want any accrued bits from the fintrz showing up later since 92421da177e4SLinus Torvalds# we may need to read the fpsr for the last fp op in t_catch2(). 92431da177e4SLinus Torvalds fmov.l &0x0,%fpsr 92441da177e4SLinus Torvalds 92451da177e4SLinus Torvalds tst.b DST_HI(%a1) # is dst denormalized? 92461da177e4SLinus Torvalds bmi.b sok_norm 92471da177e4SLinus Torvalds 92481da177e4SLinus Torvalds# the dst is a DENORM. normalize the DENORM and add the adjustment to 92491da177e4SLinus Torvalds# the src value. then, jump to the norm part of the routine. 92501da177e4SLinus Torvaldssok_dnrm: 92511da177e4SLinus Torvalds mov.l %d0,-(%sp) # save src for now 92521da177e4SLinus Torvalds 92531da177e4SLinus Torvalds mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy 92541da177e4SLinus Torvalds mov.l DST_HI(%a1),FP_SCR0_HI(%a6) 92551da177e4SLinus Torvalds mov.l DST_LO(%a1),FP_SCR0_LO(%a6) 92561da177e4SLinus Torvalds 92571da177e4SLinus Torvalds lea FP_SCR0(%a6),%a0 # pass ptr to DENORM 92581da177e4SLinus Torvalds bsr.l norm # normalize the DENORM 92591da177e4SLinus Torvalds neg.l %d0 92601da177e4SLinus Torvalds add.l (%sp)+,%d0 # add adjustment to src 92611da177e4SLinus Torvalds 92621da177e4SLinus Torvalds fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM 92631da177e4SLinus Torvalds 92641da177e4SLinus Torvalds cmpi.w %d0,&-0x3fff # is the shft amt really low? 92651da177e4SLinus Torvalds bge.b sok_norm2 # thank goodness no 92661da177e4SLinus Torvalds 92671da177e4SLinus Torvalds# the multiply factor that we're trying to create should be a denorm 92681da177e4SLinus Torvalds# for the multiply to work. therefore, we're going to actually do a 92691da177e4SLinus Torvalds# multiply with a denorm which will cause an unimplemented data type 92701da177e4SLinus Torvalds# exception to be put into the machine which will be caught and corrected 92711da177e4SLinus Torvalds# later. we don't do this with the DENORMs above because this method 92721da177e4SLinus Torvalds# is slower. but, don't fret, I don't see it being used much either. 92731da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore user fpcr 92741da177e4SLinus Torvalds mov.l &0x80000000,%d1 # load normalized mantissa 92751da177e4SLinus Torvalds subi.l &-0x3fff,%d0 # how many should we shift? 92761da177e4SLinus Torvalds neg.l %d0 # make it positive 92771da177e4SLinus Torvalds cmpi.b %d0,&0x20 # is it > 32? 92781da177e4SLinus Torvalds bge.b sok_dnrm_32 # yes 92791da177e4SLinus Torvalds lsr.l %d0,%d1 # no; bit stays in upper lw 92801da177e4SLinus Torvalds clr.l -(%sp) # insert zero low mantissa 92811da177e4SLinus Torvalds mov.l %d1,-(%sp) # insert new high mantissa 92821da177e4SLinus Torvalds clr.l -(%sp) # make zero exponent 92831da177e4SLinus Torvalds bra.b sok_norm_cont 92841da177e4SLinus Torvaldssok_dnrm_32: 92851da177e4SLinus Torvalds subi.b &0x20,%d0 # get shift count 92861da177e4SLinus Torvalds lsr.l %d0,%d1 # make low mantissa longword 92871da177e4SLinus Torvalds mov.l %d1,-(%sp) # insert new low mantissa 92881da177e4SLinus Torvalds clr.l -(%sp) # insert zero high mantissa 92891da177e4SLinus Torvalds clr.l -(%sp) # make zero exponent 92901da177e4SLinus Torvalds bra.b sok_norm_cont 92911da177e4SLinus Torvalds 92921da177e4SLinus Torvalds# the src will force the dst to a DENORM value or worse. so, let's 92931da177e4SLinus Torvalds# create an fp multiply that will create the result. 92941da177e4SLinus Torvaldssok_norm: 92951da177e4SLinus Torvalds fmovm.x DST(%a1),&0x80 # load fp0 with normalized src 92961da177e4SLinus Torvaldssok_norm2: 92971da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore user fpcr 92981da177e4SLinus Torvalds 92991da177e4SLinus Torvalds addi.w &0x3fff,%d0 # turn src amt into exp value 93001da177e4SLinus Torvalds swap %d0 # put exponent in high word 93011da177e4SLinus Torvalds clr.l -(%sp) # insert new exponent 93021da177e4SLinus Torvalds mov.l &0x80000000,-(%sp) # insert new high mantissa 93031da177e4SLinus Torvalds mov.l %d0,-(%sp) # insert new lo mantissa 93041da177e4SLinus Torvalds 93051da177e4SLinus Torvaldssok_norm_cont: 93061da177e4SLinus Torvalds fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2 93071da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 93081da177e4SLinus Torvalds fmul.x (%sp)+,%fp0 # do the multiply 93091da177e4SLinus Torvalds bra t_catch2 # catch any exceptions 93101da177e4SLinus Torvalds 93111da177e4SLinus Torvalds# 93121da177e4SLinus Torvalds# Source is outside of 2^14 range. Test the sign and branch 93131da177e4SLinus Torvalds# to the appropriate exception handler. 93141da177e4SLinus Torvalds# 93151da177e4SLinus Torvaldssrc_out: 93161da177e4SLinus Torvalds mov.l (%sp)+,%d0 # restore ctrl bits 93171da177e4SLinus Torvalds exg %a0,%a1 # swap src,dst ptrs 93181da177e4SLinus Torvalds tst.b SRC_EX(%a1) # is src negative? 93191da177e4SLinus Torvalds bmi t_unfl # yes; underflow 93201da177e4SLinus Torvalds bra t_ovfl_sc # no; overflow 93211da177e4SLinus Torvalds 93221da177e4SLinus Torvalds# 93231da177e4SLinus Torvalds# The source input is below 1, so we check for denormalized numbers 93241da177e4SLinus Torvalds# and set unfl. 93251da177e4SLinus Torvalds# 93261da177e4SLinus Torvaldssrc_small: 93271da177e4SLinus Torvalds tst.b DST_HI(%a1) # is dst denormalized? 93281da177e4SLinus Torvalds bpl.b ssmall_done # yes 93291da177e4SLinus Torvalds 93301da177e4SLinus Torvalds mov.l (%sp)+,%d0 93311da177e4SLinus Torvalds fmov.l %d0,%fpcr # no; load control bits 93321da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 93331da177e4SLinus Torvalds fmov.x DST(%a1),%fp0 # simply return dest 93341da177e4SLinus Torvalds bra t_catch2 93351da177e4SLinus Torvaldsssmall_done: 93361da177e4SLinus Torvalds mov.l (%sp)+,%d0 # load control bits into d1 93371da177e4SLinus Torvalds mov.l %a1,%a0 # pass ptr to dst 93381da177e4SLinus Torvalds bra t_resdnrm 93391da177e4SLinus Torvalds 93401da177e4SLinus Torvalds######################################################################### 93411da177e4SLinus Torvalds# smod(): computes the fp MOD of the input values X,Y. # 93421da177e4SLinus Torvalds# srem(): computes the fp (IEEE) REM of the input values X,Y. # 93431da177e4SLinus Torvalds# # 93441da177e4SLinus Torvalds# INPUT *************************************************************** # 93451da177e4SLinus Torvalds# a0 = pointer to extended precision input X # 93461da177e4SLinus Torvalds# a1 = pointer to extended precision input Y # 93471da177e4SLinus Torvalds# d0 = round precision,mode # 93481da177e4SLinus Torvalds# # 93491da177e4SLinus Torvalds# The input operands X and Y can be either normalized or # 93501da177e4SLinus Torvalds# denormalized. # 93511da177e4SLinus Torvalds# # 93521da177e4SLinus Torvalds# OUTPUT ************************************************************** # 93531da177e4SLinus Torvalds# fp0 = FREM(X,Y) or FMOD(X,Y) # 93541da177e4SLinus Torvalds# # 93551da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 93561da177e4SLinus Torvalds# # 93571da177e4SLinus Torvalds# Step 1. Save and strip signs of X and Y: signX := sign(X), # 93581da177e4SLinus Torvalds# signY := sign(Y), X := |X|, Y := |Y|, # 93591da177e4SLinus Torvalds# signQ := signX EOR signY. Record whether MOD or REM # 93601da177e4SLinus Torvalds# is requested. # 93611da177e4SLinus Torvalds# # 93621da177e4SLinus Torvalds# Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. # 93631da177e4SLinus Torvalds# If (L < 0) then # 93641da177e4SLinus Torvalds# R := X, go to Step 4. # 93651da177e4SLinus Torvalds# else # 93661da177e4SLinus Torvalds# R := 2^(-L)X, j := L. # 93671da177e4SLinus Torvalds# endif # 93681da177e4SLinus Torvalds# # 93691da177e4SLinus Torvalds# Step 3. Perform MOD(X,Y) # 93701da177e4SLinus Torvalds# 3.1 If R = Y, go to Step 9. # 93711da177e4SLinus Torvalds# 3.2 If R > Y, then { R := R - Y, Q := Q + 1} # 93721da177e4SLinus Torvalds# 3.3 If j = 0, go to Step 4. # 93731da177e4SLinus Torvalds# 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to # 93741da177e4SLinus Torvalds# Step 3.1. # 93751da177e4SLinus Torvalds# # 93761da177e4SLinus Torvalds# Step 4. At this point, R = X - QY = MOD(X,Y). Set # 93771da177e4SLinus Torvalds# Last_Subtract := false (used in Step 7 below). If # 93781da177e4SLinus Torvalds# MOD is requested, go to Step 6. # 93791da177e4SLinus Torvalds# # 93801da177e4SLinus Torvalds# Step 5. R = MOD(X,Y), but REM(X,Y) is requested. # 93811da177e4SLinus Torvalds# 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to # 93821da177e4SLinus Torvalds# Step 6. # 93831da177e4SLinus Torvalds# 5.2 If R > Y/2, then { set Last_Subtract := true, # 93841da177e4SLinus Torvalds# Q := Q + 1, Y := signY*Y }. Go to Step 6. # 93851da177e4SLinus Torvalds# 5.3 This is the tricky case of R = Y/2. If Q is odd, # 93861da177e4SLinus Torvalds# then { Q := Q + 1, signX := -signX }. # 93871da177e4SLinus Torvalds# # 93881da177e4SLinus Torvalds# Step 6. R := signX*R. # 93891da177e4SLinus Torvalds# # 93901da177e4SLinus Torvalds# Step 7. If Last_Subtract = true, R := R - Y. # 93911da177e4SLinus Torvalds# # 93921da177e4SLinus Torvalds# Step 8. Return signQ, last 7 bits of Q, and R as required. # 93931da177e4SLinus Torvalds# # 93941da177e4SLinus Torvalds# Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, # 93951da177e4SLinus Torvalds# X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), # 93961da177e4SLinus Torvalds# R := 0. Return signQ, last 7 bits of Q, and R. # 93971da177e4SLinus Torvalds# # 93981da177e4SLinus Torvalds######################################################################### 93991da177e4SLinus Torvalds 94001da177e4SLinus Torvalds set Mod_Flag,L_SCR3 94011da177e4SLinus Torvalds set Sc_Flag,L_SCR3+1 94021da177e4SLinus Torvalds 94031da177e4SLinus Torvalds set SignY,L_SCR2 94041da177e4SLinus Torvalds set SignX,L_SCR2+2 94051da177e4SLinus Torvalds set SignQ,L_SCR3+2 94061da177e4SLinus Torvalds 94071da177e4SLinus Torvalds set Y,FP_SCR0 94081da177e4SLinus Torvalds set Y_Hi,Y+4 94091da177e4SLinus Torvalds set Y_Lo,Y+8 94101da177e4SLinus Torvalds 94111da177e4SLinus Torvalds set R,FP_SCR1 94121da177e4SLinus Torvalds set R_Hi,R+4 94131da177e4SLinus Torvalds set R_Lo,R+8 94141da177e4SLinus Torvalds 94151da177e4SLinus TorvaldsScale: 94161da177e4SLinus Torvalds long 0x00010000,0x80000000,0x00000000,0x00000000 94171da177e4SLinus Torvalds 94181da177e4SLinus Torvalds global smod 94191da177e4SLinus Torvaldssmod: 94201da177e4SLinus Torvalds clr.b FPSR_QBYTE(%a6) 94211da177e4SLinus Torvalds mov.l %d0,-(%sp) # save ctrl bits 94221da177e4SLinus Torvalds clr.b Mod_Flag(%a6) 94231da177e4SLinus Torvalds bra.b Mod_Rem 94241da177e4SLinus Torvalds 94251da177e4SLinus Torvalds global srem 94261da177e4SLinus Torvaldssrem: 94271da177e4SLinus Torvalds clr.b FPSR_QBYTE(%a6) 94281da177e4SLinus Torvalds mov.l %d0,-(%sp) # save ctrl bits 94291da177e4SLinus Torvalds mov.b &0x1,Mod_Flag(%a6) 94301da177e4SLinus Torvalds 94311da177e4SLinus TorvaldsMod_Rem: 94321da177e4SLinus Torvalds#..Save sign of X and Y 94331da177e4SLinus Torvalds movm.l &0x3f00,-(%sp) # save data registers 94341da177e4SLinus Torvalds mov.w SRC_EX(%a0),%d3 94351da177e4SLinus Torvalds mov.w %d3,SignY(%a6) 94361da177e4SLinus Torvalds and.l &0x00007FFF,%d3 # Y := |Y| 94371da177e4SLinus Torvalds 94381da177e4SLinus Torvalds# 94391da177e4SLinus Torvalds mov.l SRC_HI(%a0),%d4 94401da177e4SLinus Torvalds mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y| 94411da177e4SLinus Torvalds 94421da177e4SLinus Torvalds tst.l %d3 94431da177e4SLinus Torvalds bne.b Y_Normal 94441da177e4SLinus Torvalds 94451da177e4SLinus Torvalds mov.l &0x00003FFE,%d3 # $3FFD + 1 94461da177e4SLinus Torvalds tst.l %d4 94471da177e4SLinus Torvalds bne.b HiY_not0 94481da177e4SLinus Torvalds 94491da177e4SLinus TorvaldsHiY_0: 94501da177e4SLinus Torvalds mov.l %d5,%d4 94511da177e4SLinus Torvalds clr.l %d5 94521da177e4SLinus Torvalds sub.l &32,%d3 94531da177e4SLinus Torvalds clr.l %d6 94541da177e4SLinus Torvalds bfffo %d4{&0:&32},%d6 94551da177e4SLinus Torvalds lsl.l %d6,%d4 94561da177e4SLinus Torvalds sub.l %d6,%d3 # (D3,D4,D5) is normalized 94571da177e4SLinus Torvalds# ...with bias $7FFD 94581da177e4SLinus Torvalds bra.b Chk_X 94591da177e4SLinus Torvalds 94601da177e4SLinus TorvaldsHiY_not0: 94611da177e4SLinus Torvalds clr.l %d6 94621da177e4SLinus Torvalds bfffo %d4{&0:&32},%d6 94631da177e4SLinus Torvalds sub.l %d6,%d3 94641da177e4SLinus Torvalds lsl.l %d6,%d4 94651da177e4SLinus Torvalds mov.l %d5,%d7 # a copy of D5 94661da177e4SLinus Torvalds lsl.l %d6,%d5 94671da177e4SLinus Torvalds neg.l %d6 94681da177e4SLinus Torvalds add.l &32,%d6 94691da177e4SLinus Torvalds lsr.l %d6,%d7 94701da177e4SLinus Torvalds or.l %d7,%d4 # (D3,D4,D5) normalized 94711da177e4SLinus Torvalds# ...with bias $7FFD 94721da177e4SLinus Torvalds bra.b Chk_X 94731da177e4SLinus Torvalds 94741da177e4SLinus TorvaldsY_Normal: 94751da177e4SLinus Torvalds add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized 94761da177e4SLinus Torvalds# ...with bias $7FFD 94771da177e4SLinus Torvalds 94781da177e4SLinus TorvaldsChk_X: 94791da177e4SLinus Torvalds mov.w DST_EX(%a1),%d0 94801da177e4SLinus Torvalds mov.w %d0,SignX(%a6) 94811da177e4SLinus Torvalds mov.w SignY(%a6),%d1 94821da177e4SLinus Torvalds eor.l %d0,%d1 94831da177e4SLinus Torvalds and.l &0x00008000,%d1 94841da177e4SLinus Torvalds mov.w %d1,SignQ(%a6) # sign(Q) obtained 94851da177e4SLinus Torvalds and.l &0x00007FFF,%d0 94861da177e4SLinus Torvalds mov.l DST_HI(%a1),%d1 94871da177e4SLinus Torvalds mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X| 94881da177e4SLinus Torvalds tst.l %d0 94891da177e4SLinus Torvalds bne.b X_Normal 94901da177e4SLinus Torvalds mov.l &0x00003FFE,%d0 94911da177e4SLinus Torvalds tst.l %d1 94921da177e4SLinus Torvalds bne.b HiX_not0 94931da177e4SLinus Torvalds 94941da177e4SLinus TorvaldsHiX_0: 94951da177e4SLinus Torvalds mov.l %d2,%d1 94961da177e4SLinus Torvalds clr.l %d2 94971da177e4SLinus Torvalds sub.l &32,%d0 94981da177e4SLinus Torvalds clr.l %d6 94991da177e4SLinus Torvalds bfffo %d1{&0:&32},%d6 95001da177e4SLinus Torvalds lsl.l %d6,%d1 95011da177e4SLinus Torvalds sub.l %d6,%d0 # (D0,D1,D2) is normalized 95021da177e4SLinus Torvalds# ...with bias $7FFD 95031da177e4SLinus Torvalds bra.b Init 95041da177e4SLinus Torvalds 95051da177e4SLinus TorvaldsHiX_not0: 95061da177e4SLinus Torvalds clr.l %d6 95071da177e4SLinus Torvalds bfffo %d1{&0:&32},%d6 95081da177e4SLinus Torvalds sub.l %d6,%d0 95091da177e4SLinus Torvalds lsl.l %d6,%d1 95101da177e4SLinus Torvalds mov.l %d2,%d7 # a copy of D2 95111da177e4SLinus Torvalds lsl.l %d6,%d2 95121da177e4SLinus Torvalds neg.l %d6 95131da177e4SLinus Torvalds add.l &32,%d6 95141da177e4SLinus Torvalds lsr.l %d6,%d7 95151da177e4SLinus Torvalds or.l %d7,%d1 # (D0,D1,D2) normalized 95161da177e4SLinus Torvalds# ...with bias $7FFD 95171da177e4SLinus Torvalds bra.b Init 95181da177e4SLinus Torvalds 95191da177e4SLinus TorvaldsX_Normal: 95201da177e4SLinus Torvalds add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized 95211da177e4SLinus Torvalds# ...with bias $7FFD 95221da177e4SLinus Torvalds 95231da177e4SLinus TorvaldsInit: 95241da177e4SLinus Torvalds# 95251da177e4SLinus Torvalds mov.l %d3,L_SCR1(%a6) # save biased exp(Y) 95261da177e4SLinus Torvalds mov.l %d0,-(%sp) # save biased exp(X) 95271da177e4SLinus Torvalds sub.l %d3,%d0 # L := expo(X)-expo(Y) 95281da177e4SLinus Torvalds 95291da177e4SLinus Torvalds clr.l %d6 # D6 := carry <- 0 95301da177e4SLinus Torvalds clr.l %d3 # D3 is Q 95311da177e4SLinus Torvalds mov.l &0,%a1 # A1 is k; j+k=L, Q=0 95321da177e4SLinus Torvalds 95331da177e4SLinus Torvalds#..(Carry,D1,D2) is R 95341da177e4SLinus Torvalds tst.l %d0 95351da177e4SLinus Torvalds bge.b Mod_Loop_pre 95361da177e4SLinus Torvalds 95371da177e4SLinus Torvalds#..expo(X) < expo(Y). Thus X = mod(X,Y) 95381da177e4SLinus Torvalds# 95391da177e4SLinus Torvalds mov.l (%sp)+,%d0 # restore d0 95401da177e4SLinus Torvalds bra.w Get_Mod 95411da177e4SLinus Torvalds 95421da177e4SLinus TorvaldsMod_Loop_pre: 95431da177e4SLinus Torvalds addq.l &0x4,%sp # erase exp(X) 95441da177e4SLinus Torvalds#..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L 95451da177e4SLinus TorvaldsMod_Loop: 95461da177e4SLinus Torvalds tst.l %d6 # test carry bit 95471da177e4SLinus Torvalds bgt.b R_GT_Y 95481da177e4SLinus Torvalds 95491da177e4SLinus Torvalds#..At this point carry = 0, R = (D1,D2), Y = (D4,D5) 95501da177e4SLinus Torvalds cmp.l %d1,%d4 # compare hi(R) and hi(Y) 95511da177e4SLinus Torvalds bne.b R_NE_Y 95521da177e4SLinus Torvalds cmp.l %d2,%d5 # compare lo(R) and lo(Y) 95531da177e4SLinus Torvalds bne.b R_NE_Y 95541da177e4SLinus Torvalds 95551da177e4SLinus Torvalds#..At this point, R = Y 95561da177e4SLinus Torvalds bra.w Rem_is_0 95571da177e4SLinus Torvalds 95581da177e4SLinus TorvaldsR_NE_Y: 95591da177e4SLinus Torvalds#..use the borrow of the previous compare 95601da177e4SLinus Torvalds bcs.b R_LT_Y # borrow is set iff R < Y 95611da177e4SLinus Torvalds 95621da177e4SLinus TorvaldsR_GT_Y: 95631da177e4SLinus Torvalds#..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0 95641da177e4SLinus Torvalds#..and Y < (D1,D2) < 2Y. Either way, perform R - Y 95651da177e4SLinus Torvalds sub.l %d5,%d2 # lo(R) - lo(Y) 95661da177e4SLinus Torvalds subx.l %d4,%d1 # hi(R) - hi(Y) 95671da177e4SLinus Torvalds clr.l %d6 # clear carry 95681da177e4SLinus Torvalds addq.l &1,%d3 # Q := Q + 1 95691da177e4SLinus Torvalds 95701da177e4SLinus TorvaldsR_LT_Y: 95711da177e4SLinus Torvalds#..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0. 95721da177e4SLinus Torvalds tst.l %d0 # see if j = 0. 95731da177e4SLinus Torvalds beq.b PostLoop 95741da177e4SLinus Torvalds 95751da177e4SLinus Torvalds add.l %d3,%d3 # Q := 2Q 95761da177e4SLinus Torvalds add.l %d2,%d2 # lo(R) = 2lo(R) 95771da177e4SLinus Torvalds roxl.l &1,%d1 # hi(R) = 2hi(R) + carry 95781da177e4SLinus Torvalds scs %d6 # set Carry if 2(R) overflows 95791da177e4SLinus Torvalds addq.l &1,%a1 # k := k+1 95801da177e4SLinus Torvalds subq.l &1,%d0 # j := j - 1 95811da177e4SLinus Torvalds#..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y. 95821da177e4SLinus Torvalds 95831da177e4SLinus Torvalds bra.b Mod_Loop 95841da177e4SLinus Torvalds 95851da177e4SLinus TorvaldsPostLoop: 95861da177e4SLinus Torvalds#..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y. 95871da177e4SLinus Torvalds 95881da177e4SLinus Torvalds#..normalize R. 95891da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d0 # new biased expo of R 95901da177e4SLinus Torvalds tst.l %d1 95911da177e4SLinus Torvalds bne.b HiR_not0 95921da177e4SLinus Torvalds 95931da177e4SLinus TorvaldsHiR_0: 95941da177e4SLinus Torvalds mov.l %d2,%d1 95951da177e4SLinus Torvalds clr.l %d2 95961da177e4SLinus Torvalds sub.l &32,%d0 95971da177e4SLinus Torvalds clr.l %d6 95981da177e4SLinus Torvalds bfffo %d1{&0:&32},%d6 95991da177e4SLinus Torvalds lsl.l %d6,%d1 96001da177e4SLinus Torvalds sub.l %d6,%d0 # (D0,D1,D2) is normalized 96011da177e4SLinus Torvalds# ...with bias $7FFD 96021da177e4SLinus Torvalds bra.b Get_Mod 96031da177e4SLinus Torvalds 96041da177e4SLinus TorvaldsHiR_not0: 96051da177e4SLinus Torvalds clr.l %d6 96061da177e4SLinus Torvalds bfffo %d1{&0:&32},%d6 96071da177e4SLinus Torvalds bmi.b Get_Mod # already normalized 96081da177e4SLinus Torvalds sub.l %d6,%d0 96091da177e4SLinus Torvalds lsl.l %d6,%d1 96101da177e4SLinus Torvalds mov.l %d2,%d7 # a copy of D2 96111da177e4SLinus Torvalds lsl.l %d6,%d2 96121da177e4SLinus Torvalds neg.l %d6 96131da177e4SLinus Torvalds add.l &32,%d6 96141da177e4SLinus Torvalds lsr.l %d6,%d7 96151da177e4SLinus Torvalds or.l %d7,%d1 # (D0,D1,D2) normalized 96161da177e4SLinus Torvalds 96171da177e4SLinus Torvalds# 96181da177e4SLinus TorvaldsGet_Mod: 96191da177e4SLinus Torvalds cmp.l %d0,&0x000041FE 96201da177e4SLinus Torvalds bge.b No_Scale 96211da177e4SLinus TorvaldsDo_Scale: 96221da177e4SLinus Torvalds mov.w %d0,R(%a6) 96231da177e4SLinus Torvalds mov.l %d1,R_Hi(%a6) 96241da177e4SLinus Torvalds mov.l %d2,R_Lo(%a6) 96251da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d6 96261da177e4SLinus Torvalds mov.w %d6,Y(%a6) 96271da177e4SLinus Torvalds mov.l %d4,Y_Hi(%a6) 96281da177e4SLinus Torvalds mov.l %d5,Y_Lo(%a6) 96291da177e4SLinus Torvalds fmov.x R(%a6),%fp0 # no exception 96301da177e4SLinus Torvalds mov.b &1,Sc_Flag(%a6) 96311da177e4SLinus Torvalds bra.b ModOrRem 96321da177e4SLinus TorvaldsNo_Scale: 96331da177e4SLinus Torvalds mov.l %d1,R_Hi(%a6) 96341da177e4SLinus Torvalds mov.l %d2,R_Lo(%a6) 96351da177e4SLinus Torvalds sub.l &0x3FFE,%d0 96361da177e4SLinus Torvalds mov.w %d0,R(%a6) 96371da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d6 96381da177e4SLinus Torvalds sub.l &0x3FFE,%d6 96391da177e4SLinus Torvalds mov.l %d6,L_SCR1(%a6) 96401da177e4SLinus Torvalds fmov.x R(%a6),%fp0 96411da177e4SLinus Torvalds mov.w %d6,Y(%a6) 96421da177e4SLinus Torvalds mov.l %d4,Y_Hi(%a6) 96431da177e4SLinus Torvalds mov.l %d5,Y_Lo(%a6) 96441da177e4SLinus Torvalds clr.b Sc_Flag(%a6) 96451da177e4SLinus Torvalds 96461da177e4SLinus Torvalds# 96471da177e4SLinus TorvaldsModOrRem: 96481da177e4SLinus Torvalds tst.b Mod_Flag(%a6) 96491da177e4SLinus Torvalds beq.b Fix_Sign 96501da177e4SLinus Torvalds 96511da177e4SLinus Torvalds mov.l L_SCR1(%a6),%d6 # new biased expo(Y) 96521da177e4SLinus Torvalds subq.l &1,%d6 # biased expo(Y/2) 96531da177e4SLinus Torvalds cmp.l %d0,%d6 96541da177e4SLinus Torvalds blt.b Fix_Sign 96551da177e4SLinus Torvalds bgt.b Last_Sub 96561da177e4SLinus Torvalds 96571da177e4SLinus Torvalds cmp.l %d1,%d4 96581da177e4SLinus Torvalds bne.b Not_EQ 96591da177e4SLinus Torvalds cmp.l %d2,%d5 96601da177e4SLinus Torvalds bne.b Not_EQ 96611da177e4SLinus Torvalds bra.w Tie_Case 96621da177e4SLinus Torvalds 96631da177e4SLinus TorvaldsNot_EQ: 96641da177e4SLinus Torvalds bcs.b Fix_Sign 96651da177e4SLinus Torvalds 96661da177e4SLinus TorvaldsLast_Sub: 96671da177e4SLinus Torvalds# 96681da177e4SLinus Torvalds fsub.x Y(%a6),%fp0 # no exceptions 96691da177e4SLinus Torvalds addq.l &1,%d3 # Q := Q + 1 96701da177e4SLinus Torvalds 96711da177e4SLinus Torvalds# 96721da177e4SLinus TorvaldsFix_Sign: 96731da177e4SLinus Torvalds#..Get sign of X 96741da177e4SLinus Torvalds mov.w SignX(%a6),%d6 96751da177e4SLinus Torvalds bge.b Get_Q 96761da177e4SLinus Torvalds fneg.x %fp0 96771da177e4SLinus Torvalds 96781da177e4SLinus Torvalds#..Get Q 96791da177e4SLinus Torvalds# 96801da177e4SLinus TorvaldsGet_Q: 96811da177e4SLinus Torvalds clr.l %d6 96821da177e4SLinus Torvalds mov.w SignQ(%a6),%d6 # D6 is sign(Q) 96831da177e4SLinus Torvalds mov.l &8,%d7 96841da177e4SLinus Torvalds lsr.l %d7,%d6 96851da177e4SLinus Torvalds and.l &0x0000007F,%d3 # 7 bits of Q 96861da177e4SLinus Torvalds or.l %d6,%d3 # sign and bits of Q 96871da177e4SLinus Torvalds# swap %d3 96881da177e4SLinus Torvalds# fmov.l %fpsr,%d6 96891da177e4SLinus Torvalds# and.l &0xFF00FFFF,%d6 96901da177e4SLinus Torvalds# or.l %d3,%d6 96911da177e4SLinus Torvalds# fmov.l %d6,%fpsr # put Q in fpsr 96921da177e4SLinus Torvalds mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr 96931da177e4SLinus Torvalds 96941da177e4SLinus Torvalds# 96951da177e4SLinus TorvaldsRestore: 96961da177e4SLinus Torvalds movm.l (%sp)+,&0xfc # {%d2-%d7} 96971da177e4SLinus Torvalds mov.l (%sp)+,%d0 96981da177e4SLinus Torvalds fmov.l %d0,%fpcr 96991da177e4SLinus Torvalds tst.b Sc_Flag(%a6) 97001da177e4SLinus Torvalds beq.b Finish 97011da177e4SLinus Torvalds mov.b &FMUL_OP,%d1 # last inst is MUL 97021da177e4SLinus Torvalds fmul.x Scale(%pc),%fp0 # may cause underflow 97031da177e4SLinus Torvalds bra t_catch2 97041da177e4SLinus Torvalds# the '040 package did this apparently to see if the dst operand for the 97051da177e4SLinus Torvalds# preceding fmul was a denorm. but, it better not have been since the 97061da177e4SLinus Torvalds# algorithm just got done playing with fp0 and expected no exceptions 97071da177e4SLinus Torvalds# as a result. trust me... 97081da177e4SLinus Torvalds# bra t_avoid_unsupp # check for denorm as a 97091da177e4SLinus Torvalds# ;result of the scaling 97101da177e4SLinus Torvalds 97111da177e4SLinus TorvaldsFinish: 97121da177e4SLinus Torvalds mov.b &FMOV_OP,%d1 # last inst is MOVE 97131da177e4SLinus Torvalds fmov.x %fp0,%fp0 # capture exceptions & round 97141da177e4SLinus Torvalds bra t_catch2 97151da177e4SLinus Torvalds 97161da177e4SLinus TorvaldsRem_is_0: 97171da177e4SLinus Torvalds#..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1) 97181da177e4SLinus Torvalds addq.l &1,%d3 97191da177e4SLinus Torvalds cmp.l %d0,&8 # D0 is j 97201da177e4SLinus Torvalds bge.b Q_Big 97211da177e4SLinus Torvalds 97221da177e4SLinus Torvalds lsl.l %d0,%d3 97231da177e4SLinus Torvalds bra.b Set_R_0 97241da177e4SLinus Torvalds 97251da177e4SLinus TorvaldsQ_Big: 97261da177e4SLinus Torvalds clr.l %d3 97271da177e4SLinus Torvalds 97281da177e4SLinus TorvaldsSet_R_0: 97291da177e4SLinus Torvalds fmov.s &0x00000000,%fp0 97301da177e4SLinus Torvalds clr.b Sc_Flag(%a6) 97311da177e4SLinus Torvalds bra.w Fix_Sign 97321da177e4SLinus Torvalds 97331da177e4SLinus TorvaldsTie_Case: 97341da177e4SLinus Torvalds#..Check parity of Q 97351da177e4SLinus Torvalds mov.l %d3,%d6 97361da177e4SLinus Torvalds and.l &0x00000001,%d6 97371da177e4SLinus Torvalds tst.l %d6 97381da177e4SLinus Torvalds beq.w Fix_Sign # Q is even 97391da177e4SLinus Torvalds 97401da177e4SLinus Torvalds#..Q is odd, Q := Q + 1, signX := -signX 97411da177e4SLinus Torvalds addq.l &1,%d3 97421da177e4SLinus Torvalds mov.w SignX(%a6),%d6 97431da177e4SLinus Torvalds eor.l &0x00008000,%d6 97441da177e4SLinus Torvalds mov.w %d6,SignX(%a6) 97451da177e4SLinus Torvalds bra.w Fix_Sign 97461da177e4SLinus Torvalds 97471da177e4SLinus Torvalds######################################################################### 97481da177e4SLinus Torvalds# XDEF **************************************************************** # 97491da177e4SLinus Torvalds# tag(): return the optype of the input ext fp number # 97501da177e4SLinus Torvalds# # 97511da177e4SLinus Torvalds# This routine is used by the 060FPLSP. # 97521da177e4SLinus Torvalds# # 97531da177e4SLinus Torvalds# XREF **************************************************************** # 97541da177e4SLinus Torvalds# None # 97551da177e4SLinus Torvalds# # 97561da177e4SLinus Torvalds# INPUT *************************************************************** # 97571da177e4SLinus Torvalds# a0 = pointer to extended precision operand # 97581da177e4SLinus Torvalds# # 97591da177e4SLinus Torvalds# OUTPUT ************************************************************** # 97601da177e4SLinus Torvalds# d0 = value of type tag # 97611da177e4SLinus Torvalds# one of: NORM, INF, QNAN, SNAN, DENORM, ZERO # 97621da177e4SLinus Torvalds# # 97631da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 97641da177e4SLinus Torvalds# Simply test the exponent, j-bit, and mantissa values to # 97651da177e4SLinus Torvalds# determine the type of operand. # 97661da177e4SLinus Torvalds# If it's an unnormalized zero, alter the operand and force it # 97671da177e4SLinus Torvalds# to be a normal zero. # 97681da177e4SLinus Torvalds# # 97691da177e4SLinus Torvalds######################################################################### 97701da177e4SLinus Torvalds 97711da177e4SLinus Torvalds global tag 97721da177e4SLinus Torvaldstag: 97731da177e4SLinus Torvalds mov.w FTEMP_EX(%a0), %d0 # extract exponent 97741da177e4SLinus Torvalds andi.w &0x7fff, %d0 # strip off sign 97751da177e4SLinus Torvalds cmpi.w %d0, &0x7fff # is (EXP == MAX)? 97761da177e4SLinus Torvalds beq.b inf_or_nan_x 97771da177e4SLinus Torvaldsnot_inf_or_nan_x: 97781da177e4SLinus Torvalds btst &0x7,FTEMP_HI(%a0) 97791da177e4SLinus Torvalds beq.b not_norm_x 97801da177e4SLinus Torvaldsis_norm_x: 97811da177e4SLinus Torvalds mov.b &NORM, %d0 97821da177e4SLinus Torvalds rts 97831da177e4SLinus Torvaldsnot_norm_x: 97841da177e4SLinus Torvalds tst.w %d0 # is exponent = 0? 97851da177e4SLinus Torvalds bne.b is_unnorm_x 97861da177e4SLinus Torvaldsnot_unnorm_x: 97871da177e4SLinus Torvalds tst.l FTEMP_HI(%a0) 97881da177e4SLinus Torvalds bne.b is_denorm_x 97891da177e4SLinus Torvalds tst.l FTEMP_LO(%a0) 97901da177e4SLinus Torvalds bne.b is_denorm_x 97911da177e4SLinus Torvaldsis_zero_x: 97921da177e4SLinus Torvalds mov.b &ZERO, %d0 97931da177e4SLinus Torvalds rts 97941da177e4SLinus Torvaldsis_denorm_x: 97951da177e4SLinus Torvalds mov.b &DENORM, %d0 97961da177e4SLinus Torvalds rts 97971da177e4SLinus Torvaldsis_unnorm_x: 97981da177e4SLinus Torvalds bsr.l unnorm_fix # convert to norm,denorm,or zero 97991da177e4SLinus Torvalds rts 98001da177e4SLinus Torvaldsis_unnorm_reg_x: 98011da177e4SLinus Torvalds mov.b &UNNORM, %d0 98021da177e4SLinus Torvalds rts 98031da177e4SLinus Torvaldsinf_or_nan_x: 98041da177e4SLinus Torvalds tst.l FTEMP_LO(%a0) 98051da177e4SLinus Torvalds bne.b is_nan_x 98061da177e4SLinus Torvalds mov.l FTEMP_HI(%a0), %d0 98071da177e4SLinus Torvalds and.l &0x7fffffff, %d0 # msb is a don't care! 98081da177e4SLinus Torvalds bne.b is_nan_x 98091da177e4SLinus Torvaldsis_inf_x: 98101da177e4SLinus Torvalds mov.b &INF, %d0 98111da177e4SLinus Torvalds rts 98121da177e4SLinus Torvaldsis_nan_x: 98131da177e4SLinus Torvalds mov.b &QNAN, %d0 98141da177e4SLinus Torvalds rts 98151da177e4SLinus Torvalds 98161da177e4SLinus Torvalds############################################################# 98171da177e4SLinus Torvalds 98181da177e4SLinus Torvaldsqnan: long 0x7fff0000, 0xffffffff, 0xffffffff 98191da177e4SLinus Torvalds 98201da177e4SLinus Torvalds######################################################################### 98211da177e4SLinus Torvalds# XDEF **************************************************************** # 98221da177e4SLinus Torvalds# t_dz(): Handle 060FPLSP dz exception for "flogn" emulation. # 98231da177e4SLinus Torvalds# t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation. # 98241da177e4SLinus Torvalds# # 98251da177e4SLinus Torvalds# These rouitnes are used by the 060FPLSP package. # 98261da177e4SLinus Torvalds# # 98271da177e4SLinus Torvalds# XREF **************************************************************** # 98281da177e4SLinus Torvalds# None # 98291da177e4SLinus Torvalds# # 98301da177e4SLinus Torvalds# INPUT *************************************************************** # 98311da177e4SLinus Torvalds# a0 = pointer to extended precision source operand. # 98321da177e4SLinus Torvalds# # 98331da177e4SLinus Torvalds# OUTPUT ************************************************************** # 98341da177e4SLinus Torvalds# fp0 = default DZ result. # 98351da177e4SLinus Torvalds# # 98361da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 98371da177e4SLinus Torvalds# Transcendental emulation for the 060FPLSP has detected that # 98381da177e4SLinus Torvalds# a DZ exception should occur for the instruction. If DZ is disabled, # 98391da177e4SLinus Torvalds# return the default result. # 98401da177e4SLinus Torvalds# If DZ is enabled, the dst operand should be returned unscathed # 98411da177e4SLinus Torvalds# in fp0 while fp1 is used to create a DZ exception so that the # 98421da177e4SLinus Torvalds# operating system can log that such an event occurred. # 98431da177e4SLinus Torvalds# # 98441da177e4SLinus Torvalds######################################################################### 98451da177e4SLinus Torvalds 98461da177e4SLinus Torvalds global t_dz 98471da177e4SLinus Torvaldst_dz: 98481da177e4SLinus Torvalds tst.b SRC_EX(%a0) # check sign for neg or pos 98491da177e4SLinus Torvalds bpl.b dz_pinf # branch if pos sign 98501da177e4SLinus Torvalds 98511da177e4SLinus Torvalds global t_dz2 98521da177e4SLinus Torvaldst_dz2: 98531da177e4SLinus Torvalds ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ 98541da177e4SLinus Torvalds 98551da177e4SLinus Torvalds btst &dz_bit,FPCR_ENABLE(%a6) 98561da177e4SLinus Torvalds bne.b dz_minf_ena 98571da177e4SLinus Torvalds 98581da177e4SLinus Torvalds# dz is disabled. return a -INF. 98591da177e4SLinus Torvalds fmov.s &0xff800000,%fp0 # return -INF 98601da177e4SLinus Torvalds rts 98611da177e4SLinus Torvalds 98621da177e4SLinus Torvalds# dz is enabled. create a dz exception so the user can record it 98631da177e4SLinus Torvalds# but use fp1 instead. return the dst operand unscathed in fp0. 98641da177e4SLinus Torvaldsdz_minf_ena: 98651da177e4SLinus Torvalds fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 98661da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 98671da177e4SLinus Torvalds fmov.s &0xbf800000,%fp1 # load -1 98681da177e4SLinus Torvalds fdiv.s &0x00000000,%fp1 # -1 / 0 98691da177e4SLinus Torvalds rts 98701da177e4SLinus Torvalds 98711da177e4SLinus Torvaldsdz_pinf: 98721da177e4SLinus Torvalds ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ 98731da177e4SLinus Torvalds 98741da177e4SLinus Torvalds btst &dz_bit,FPCR_ENABLE(%a6) 98751da177e4SLinus Torvalds bne.b dz_pinf_ena 98761da177e4SLinus Torvalds 98771da177e4SLinus Torvalds# dz is disabled. return a +INF. 98781da177e4SLinus Torvalds fmov.s &0x7f800000,%fp0 # return +INF 98791da177e4SLinus Torvalds rts 98801da177e4SLinus Torvalds 98811da177e4SLinus Torvalds# dz is enabled. create a dz exception so the user can record it 98821da177e4SLinus Torvalds# but use fp1 instead. return the dst operand unscathed in fp0. 98831da177e4SLinus Torvaldsdz_pinf_ena: 98841da177e4SLinus Torvalds fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 98851da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 98861da177e4SLinus Torvalds fmov.s &0x3f800000,%fp1 # load +1 98871da177e4SLinus Torvalds fdiv.s &0x00000000,%fp1 # +1 / 0 98881da177e4SLinus Torvalds rts 98891da177e4SLinus Torvalds 98901da177e4SLinus Torvalds######################################################################### 98911da177e4SLinus Torvalds# XDEF **************************************************************** # 98921da177e4SLinus Torvalds# t_operr(): Handle 060FPLSP OPERR exception during emulation. # 98931da177e4SLinus Torvalds# # 98941da177e4SLinus Torvalds# This routine is used by the 060FPLSP package. # 98951da177e4SLinus Torvalds# # 98961da177e4SLinus Torvalds# XREF **************************************************************** # 98971da177e4SLinus Torvalds# None. # 98981da177e4SLinus Torvalds# # 98991da177e4SLinus Torvalds# INPUT *************************************************************** # 99001da177e4SLinus Torvalds# fp1 = source operand # 99011da177e4SLinus Torvalds# # 99021da177e4SLinus Torvalds# OUTPUT ************************************************************** # 99031da177e4SLinus Torvalds# fp0 = default result # 99041da177e4SLinus Torvalds# fp1 = unchanged # 99051da177e4SLinus Torvalds# # 99061da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 99071da177e4SLinus Torvalds# An operand error should occur as the result of transcendental # 99081da177e4SLinus Torvalds# emulation in the 060FPLSP. If OPERR is disabled, just return a NAN # 99091da177e4SLinus Torvalds# in fp0. If OPERR is enabled, return the dst operand unscathed in fp0 # 99101da177e4SLinus Torvalds# and the source operand in fp1. Use fp2 to create an OPERR exception # 99111da177e4SLinus Torvalds# so that the operating system can log the event. # 99121da177e4SLinus Torvalds# # 99131da177e4SLinus Torvalds######################################################################### 99141da177e4SLinus Torvalds 99151da177e4SLinus Torvalds global t_operr 99161da177e4SLinus Torvaldst_operr: 99171da177e4SLinus Torvalds ori.l &opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP 99181da177e4SLinus Torvalds 99191da177e4SLinus Torvalds btst &operr_bit,FPCR_ENABLE(%a6) 99201da177e4SLinus Torvalds bne.b operr_ena 99211da177e4SLinus Torvalds 99221da177e4SLinus Torvalds# operr is disabled. return a QNAN in fp0 99231da177e4SLinus Torvalds fmovm.x qnan(%pc),&0x80 # return QNAN 99241da177e4SLinus Torvalds rts 99251da177e4SLinus Torvalds 99261da177e4SLinus Torvalds# operr is enabled. create an operr exception so the user can record it 99271da177e4SLinus Torvalds# but use fp2 instead. return the dst operand unscathed in fp0. 99281da177e4SLinus Torvaldsoperr_ena: 99291da177e4SLinus Torvalds fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 99301da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 99311da177e4SLinus Torvalds fmovm.x &0x04,-(%sp) # save fp2 99321da177e4SLinus Torvalds fmov.s &0x7f800000,%fp2 # load +INF 99331da177e4SLinus Torvalds fmul.s &0x00000000,%fp2 # +INF x 0 99341da177e4SLinus Torvalds fmovm.x (%sp)+,&0x20 # restore fp2 99351da177e4SLinus Torvalds rts 99361da177e4SLinus Torvalds 99371da177e4SLinus Torvaldspls_huge: 99381da177e4SLinus Torvalds long 0x7ffe0000,0xffffffff,0xffffffff 99391da177e4SLinus Torvaldsmns_huge: 99401da177e4SLinus Torvalds long 0xfffe0000,0xffffffff,0xffffffff 99411da177e4SLinus Torvaldspls_tiny: 99421da177e4SLinus Torvalds long 0x00000000,0x80000000,0x00000000 99431da177e4SLinus Torvaldsmns_tiny: 99441da177e4SLinus Torvalds long 0x80000000,0x80000000,0x00000000 99451da177e4SLinus Torvalds 99461da177e4SLinus Torvalds######################################################################### 99471da177e4SLinus Torvalds# XDEF **************************************************************** # 99481da177e4SLinus Torvalds# t_unfl(): Handle 060FPLSP underflow exception during emulation. # 99491da177e4SLinus Torvalds# t_unfl2(): Handle 060FPLSP underflow exception during # 99501da177e4SLinus Torvalds# emulation. result always positive. # 99511da177e4SLinus Torvalds# # 99521da177e4SLinus Torvalds# This routine is used by the 060FPLSP package. # 99531da177e4SLinus Torvalds# # 99541da177e4SLinus Torvalds# XREF **************************************************************** # 99551da177e4SLinus Torvalds# None. # 99561da177e4SLinus Torvalds# # 99571da177e4SLinus Torvalds# INPUT *************************************************************** # 99581da177e4SLinus Torvalds# a0 = pointer to extended precision source operand # 99591da177e4SLinus Torvalds# # 99601da177e4SLinus Torvalds# OUTPUT ************************************************************** # 99611da177e4SLinus Torvalds# fp0 = default underflow result # 99621da177e4SLinus Torvalds# # 99631da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 99641da177e4SLinus Torvalds# An underflow should occur as the result of transcendental # 99651da177e4SLinus Torvalds# emulation in the 060FPLSP. Create an underflow by using "fmul" # 99661da177e4SLinus Torvalds# and two very small numbers of appropriate sign so the operating # 99671da177e4SLinus Torvalds# system can log the event. # 99681da177e4SLinus Torvalds# # 99691da177e4SLinus Torvalds######################################################################### 99701da177e4SLinus Torvalds 99711da177e4SLinus Torvalds global t_unfl 99721da177e4SLinus Torvaldst_unfl: 99731da177e4SLinus Torvalds tst.b SRC_EX(%a0) 99741da177e4SLinus Torvalds bpl.b unf_pos 99751da177e4SLinus Torvalds 99761da177e4SLinus Torvalds global t_unfl2 99771da177e4SLinus Torvaldst_unfl2: 99781da177e4SLinus Torvalds ori.l &unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX 99791da177e4SLinus Torvalds 99801da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 99811da177e4SLinus Torvalds fmovm.x mns_tiny(%pc),&0x80 99821da177e4SLinus Torvalds fmul.x pls_tiny(%pc),%fp0 99831da177e4SLinus Torvalds 99841da177e4SLinus Torvalds fmov.l %fpsr,%d0 99851da177e4SLinus Torvalds rol.l &0x8,%d0 99861da177e4SLinus Torvalds mov.b %d0,FPSR_CC(%a6) 99871da177e4SLinus Torvalds rts 99881da177e4SLinus Torvaldsunf_pos: 99891da177e4SLinus Torvalds ori.w &unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX 99901da177e4SLinus Torvalds 99911da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 99921da177e4SLinus Torvalds fmovm.x pls_tiny(%pc),&0x80 99931da177e4SLinus Torvalds fmul.x %fp0,%fp0 99941da177e4SLinus Torvalds 99951da177e4SLinus Torvalds fmov.l %fpsr,%d0 99961da177e4SLinus Torvalds rol.l &0x8,%d0 99971da177e4SLinus Torvalds mov.b %d0,FPSR_CC(%a6) 99981da177e4SLinus Torvalds rts 99991da177e4SLinus Torvalds 100001da177e4SLinus Torvalds######################################################################### 100011da177e4SLinus Torvalds# XDEF **************************************************************** # 100021da177e4SLinus Torvalds# t_ovfl(): Handle 060FPLSP overflow exception during emulation. # 100031da177e4SLinus Torvalds# (monadic) # 100041da177e4SLinus Torvalds# t_ovfl2(): Handle 060FPLSP overflow exception during # 100051da177e4SLinus Torvalds# emulation. result always positive. (dyadic) # 100061da177e4SLinus Torvalds# t_ovfl_sc(): Handle 060FPLSP overflow exception during # 100071da177e4SLinus Torvalds# emulation for "fscale". # 100081da177e4SLinus Torvalds# # 100091da177e4SLinus Torvalds# This routine is used by the 060FPLSP package. # 100101da177e4SLinus Torvalds# # 100111da177e4SLinus Torvalds# XREF **************************************************************** # 100121da177e4SLinus Torvalds# None. # 100131da177e4SLinus Torvalds# # 100141da177e4SLinus Torvalds# INPUT *************************************************************** # 100151da177e4SLinus Torvalds# a0 = pointer to extended precision source operand # 100161da177e4SLinus Torvalds# # 100171da177e4SLinus Torvalds# OUTPUT ************************************************************** # 100181da177e4SLinus Torvalds# fp0 = default underflow result # 100191da177e4SLinus Torvalds# # 100201da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 100211da177e4SLinus Torvalds# An overflow should occur as the result of transcendental # 100221da177e4SLinus Torvalds# emulation in the 060FPLSP. Create an overflow by using "fmul" # 100231da177e4SLinus Torvalds# and two very lareg numbers of appropriate sign so the operating # 100241da177e4SLinus Torvalds# system can log the event. # 100251da177e4SLinus Torvalds# For t_ovfl_sc() we take special care not to lose the INEX2 bit. # 100261da177e4SLinus Torvalds# # 100271da177e4SLinus Torvalds######################################################################### 100281da177e4SLinus Torvalds 100291da177e4SLinus Torvalds global t_ovfl_sc 100301da177e4SLinus Torvaldst_ovfl_sc: 100311da177e4SLinus Torvalds ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX 100321da177e4SLinus Torvalds 100331da177e4SLinus Torvalds mov.b %d0,%d1 # fetch rnd prec,mode 100341da177e4SLinus Torvalds andi.b &0xc0,%d1 # extract prec 100351da177e4SLinus Torvalds beq.w ovfl_work 100361da177e4SLinus Torvalds 100371da177e4SLinus Torvalds# dst op is a DENORM. we have to normalize the mantissa to see if the 100381da177e4SLinus Torvalds# result would be inexact for the given precision. make a copy of the 100391da177e4SLinus Torvalds# dst so we don't screw up the version passed to us. 100401da177e4SLinus Torvalds mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6) 100411da177e4SLinus Torvalds mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6) 100421da177e4SLinus Torvalds mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6) 100431da177e4SLinus Torvalds lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0 100441da177e4SLinus Torvalds movm.l &0xc080,-(%sp) # save d0-d1/a0 100451da177e4SLinus Torvalds bsr.l norm # normalize mantissa 100461da177e4SLinus Torvalds movm.l (%sp)+,&0x0103 # restore d0-d1/a0 100471da177e4SLinus Torvalds 100481da177e4SLinus Torvalds cmpi.b %d1,&0x40 # is precision sgl? 100491da177e4SLinus Torvalds bne.b ovfl_sc_dbl # no; dbl 100501da177e4SLinus Torvaldsovfl_sc_sgl: 100511da177e4SLinus Torvalds tst.l LOCAL_LO(%a0) # is lo lw of sgl set? 100521da177e4SLinus Torvalds bne.b ovfl_sc_inx # yes 100531da177e4SLinus Torvalds tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set? 100541da177e4SLinus Torvalds bne.b ovfl_sc_inx # yes 100551da177e4SLinus Torvalds bra.w ovfl_work # don't set INEX2 100561da177e4SLinus Torvaldsovfl_sc_dbl: 100571da177e4SLinus Torvalds mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of 100581da177e4SLinus Torvalds andi.l &0x7ff,%d1 # dbl mantissa set? 100591da177e4SLinus Torvalds beq.w ovfl_work # no; don't set INEX2 100601da177e4SLinus Torvaldsovfl_sc_inx: 100611da177e4SLinus Torvalds ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2 100621da177e4SLinus Torvalds bra.b ovfl_work # continue 100631da177e4SLinus Torvalds 100641da177e4SLinus Torvalds global t_ovfl 100651da177e4SLinus Torvaldst_ovfl: 100661da177e4SLinus Torvalds ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX 100671da177e4SLinus Torvaldsovfl_work: 100681da177e4SLinus Torvalds tst.b SRC_EX(%a0) 100691da177e4SLinus Torvalds bpl.b ovfl_p 100701da177e4SLinus Torvaldsovfl_m: 100711da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 100721da177e4SLinus Torvalds fmovm.x mns_huge(%pc),&0x80 100731da177e4SLinus Torvalds fmul.x pls_huge(%pc),%fp0 100741da177e4SLinus Torvalds 100751da177e4SLinus Torvalds fmov.l %fpsr,%d0 100761da177e4SLinus Torvalds rol.l &0x8,%d0 100771da177e4SLinus Torvalds ori.b &neg_mask,%d0 100781da177e4SLinus Torvalds mov.b %d0,FPSR_CC(%a6) 100791da177e4SLinus Torvalds rts 100801da177e4SLinus Torvaldsovfl_p: 100811da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 100821da177e4SLinus Torvalds fmovm.x pls_huge(%pc),&0x80 100831da177e4SLinus Torvalds fmul.x pls_huge(%pc),%fp0 100841da177e4SLinus Torvalds 100851da177e4SLinus Torvalds fmov.l %fpsr,%d0 100861da177e4SLinus Torvalds rol.l &0x8,%d0 100871da177e4SLinus Torvalds mov.b %d0,FPSR_CC(%a6) 100881da177e4SLinus Torvalds rts 100891da177e4SLinus Torvalds 100901da177e4SLinus Torvalds global t_ovfl2 100911da177e4SLinus Torvaldst_ovfl2: 100921da177e4SLinus Torvalds ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX 100931da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 100941da177e4SLinus Torvalds fmovm.x pls_huge(%pc),&0x80 100951da177e4SLinus Torvalds fmul.x pls_huge(%pc),%fp0 100961da177e4SLinus Torvalds 100971da177e4SLinus Torvalds fmov.l %fpsr,%d0 100981da177e4SLinus Torvalds rol.l &0x8,%d0 100991da177e4SLinus Torvalds mov.b %d0,FPSR_CC(%a6) 101001da177e4SLinus Torvalds rts 101011da177e4SLinus Torvalds 101021da177e4SLinus Torvalds######################################################################### 101031da177e4SLinus Torvalds# XDEF **************************************************************** # 101041da177e4SLinus Torvalds# t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during # 101051da177e4SLinus Torvalds# emulation. # 101061da177e4SLinus Torvalds# t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during # 101071da177e4SLinus Torvalds# emulation. # 101081da177e4SLinus Torvalds# # 101091da177e4SLinus Torvalds# These routines are used by the 060FPLSP package. # 101101da177e4SLinus Torvalds# # 101111da177e4SLinus Torvalds# XREF **************************************************************** # 101121da177e4SLinus Torvalds# None. # 101131da177e4SLinus Torvalds# # 101141da177e4SLinus Torvalds# INPUT *************************************************************** # 101151da177e4SLinus Torvalds# fp0 = default underflow or overflow result # 101161da177e4SLinus Torvalds# # 101171da177e4SLinus Torvalds# OUTPUT ************************************************************** # 101181da177e4SLinus Torvalds# fp0 = default result # 101191da177e4SLinus Torvalds# # 101201da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 101211da177e4SLinus Torvalds# If an overflow or underflow occurred during the last # 101221da177e4SLinus Torvalds# instruction of transcendental 060FPLSP emulation, then it has already # 101231da177e4SLinus Torvalds# occurred and has been logged. Now we need to see if an inexact # 101241da177e4SLinus Torvalds# exception should occur. # 101251da177e4SLinus Torvalds# # 101261da177e4SLinus Torvalds######################################################################### 101271da177e4SLinus Torvalds 101281da177e4SLinus Torvalds global t_catch2 101291da177e4SLinus Torvaldst_catch2: 101301da177e4SLinus Torvalds fmov.l %fpsr,%d0 101311da177e4SLinus Torvalds or.l %d0,USER_FPSR(%a6) 101321da177e4SLinus Torvalds bra.b inx2_work 101331da177e4SLinus Torvalds 101341da177e4SLinus Torvalds global t_catch 101351da177e4SLinus Torvaldst_catch: 101361da177e4SLinus Torvalds fmov.l %fpsr,%d0 101371da177e4SLinus Torvalds or.l %d0,USER_FPSR(%a6) 101381da177e4SLinus Torvalds 101391da177e4SLinus Torvalds######################################################################### 101401da177e4SLinus Torvalds# XDEF **************************************************************** # 101411da177e4SLinus Torvalds# t_inx2(): Handle inexact 060FPLSP exception during emulation. # 101421da177e4SLinus Torvalds# t_pinx2(): Handle inexact 060FPLSP exception for "+" results. # 101431da177e4SLinus Torvalds# t_minx2(): Handle inexact 060FPLSP exception for "-" results. # 101441da177e4SLinus Torvalds# # 101451da177e4SLinus Torvalds# XREF **************************************************************** # 101461da177e4SLinus Torvalds# None. # 101471da177e4SLinus Torvalds# # 101481da177e4SLinus Torvalds# INPUT *************************************************************** # 101491da177e4SLinus Torvalds# fp0 = default result # 101501da177e4SLinus Torvalds# # 101511da177e4SLinus Torvalds# OUTPUT ************************************************************** # 101521da177e4SLinus Torvalds# fp0 = default result # 101531da177e4SLinus Torvalds# # 101541da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 101551da177e4SLinus Torvalds# The last instruction of transcendental emulation for the # 101561da177e4SLinus Torvalds# 060FPLSP should be inexact. So, if inexact is enabled, then we create # 101571da177e4SLinus Torvalds# the event here by adding a large and very small number together # 101581da177e4SLinus Torvalds# so that the operating system can log the event. # 101591da177e4SLinus Torvalds# Must check, too, if the result was zero, in which case we just # 101601da177e4SLinus Torvalds# set the FPSR bits and return. # 101611da177e4SLinus Torvalds# # 101621da177e4SLinus Torvalds######################################################################### 101631da177e4SLinus Torvalds 101641da177e4SLinus Torvalds global t_inx2 101651da177e4SLinus Torvaldst_inx2: 101661da177e4SLinus Torvalds fblt.w t_minx2 101671da177e4SLinus Torvalds fbeq.w inx2_zero 101681da177e4SLinus Torvalds 101691da177e4SLinus Torvalds global t_pinx2 101701da177e4SLinus Torvaldst_pinx2: 101711da177e4SLinus Torvalds ori.w &inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX 101721da177e4SLinus Torvalds bra.b inx2_work 101731da177e4SLinus Torvalds 101741da177e4SLinus Torvalds global t_minx2 101751da177e4SLinus Torvaldst_minx2: 101761da177e4SLinus Torvalds ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6) 101771da177e4SLinus Torvalds 101781da177e4SLinus Torvaldsinx2_work: 101791da177e4SLinus Torvalds btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled? 101801da177e4SLinus Torvalds bne.b inx2_work_ena # yes 101811da177e4SLinus Torvalds rts 101821da177e4SLinus Torvaldsinx2_work_ena: 101831da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr # insert user's exceptions 101841da177e4SLinus Torvalds fmov.s &0x3f800000,%fp1 # load +1 101851da177e4SLinus Torvalds fadd.x pls_tiny(%pc),%fp1 # cause exception 101861da177e4SLinus Torvalds rts 101871da177e4SLinus Torvalds 101881da177e4SLinus Torvaldsinx2_zero: 101891da177e4SLinus Torvalds mov.b &z_bmask,FPSR_CC(%a6) 101901da177e4SLinus Torvalds ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX 101911da177e4SLinus Torvalds rts 101921da177e4SLinus Torvalds 101931da177e4SLinus Torvalds######################################################################### 101941da177e4SLinus Torvalds# XDEF **************************************************************** # 101951da177e4SLinus Torvalds# t_extdnrm(): Handle DENORM inputs in 060FPLSP. # 101961da177e4SLinus Torvalds# t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale". # 101971da177e4SLinus Torvalds# # 101981da177e4SLinus Torvalds# This routine is used by the 060FPLSP package. # 101991da177e4SLinus Torvalds# # 102001da177e4SLinus Torvalds# XREF **************************************************************** # 102011da177e4SLinus Torvalds# None. # 102021da177e4SLinus Torvalds# # 102031da177e4SLinus Torvalds# INPUT *************************************************************** # 102041da177e4SLinus Torvalds# a0 = pointer to extended precision input operand # 102051da177e4SLinus Torvalds# # 102061da177e4SLinus Torvalds# OUTPUT ************************************************************** # 102071da177e4SLinus Torvalds# fp0 = default result # 102081da177e4SLinus Torvalds# # 102091da177e4SLinus Torvalds# ALGORITHM *********************************************************** # 102101da177e4SLinus Torvalds# For all functions that have a denormalized input and that # 102111da177e4SLinus Torvalds# f(x)=x, this is the entry point. # 102121da177e4SLinus Torvalds# DENORM value is moved using "fmove" which triggers an exception # 102131da177e4SLinus Torvalds# if enabled so the operating system can log the event. # 102141da177e4SLinus Torvalds# # 102151da177e4SLinus Torvalds######################################################################### 102161da177e4SLinus Torvalds 102171da177e4SLinus Torvalds global t_extdnrm 102181da177e4SLinus Torvaldst_extdnrm: 102191da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 102201da177e4SLinus Torvalds fmov.x SRC_EX(%a0),%fp0 102211da177e4SLinus Torvalds fmov.l %fpsr,%d0 102221da177e4SLinus Torvalds ori.l &unfinx_mask,%d0 102231da177e4SLinus Torvalds or.l %d0,USER_FPSR(%a6) 102241da177e4SLinus Torvalds rts 102251da177e4SLinus Torvalds 102261da177e4SLinus Torvalds global t_resdnrm 102271da177e4SLinus Torvaldst_resdnrm: 102281da177e4SLinus Torvalds fmov.l USER_FPCR(%a6),%fpcr 102291da177e4SLinus Torvalds fmov.x SRC_EX(%a0),%fp0 102301da177e4SLinus Torvalds fmov.l %fpsr,%d0 102311da177e4SLinus Torvalds or.l %d0,USER_FPSR(%a6) 102321da177e4SLinus Torvalds rts 102331da177e4SLinus Torvalds 102341da177e4SLinus Torvalds########################################## 102351da177e4SLinus Torvalds 102361da177e4SLinus Torvalds# 102371da177e4SLinus Torvalds# sto_cos: 102381da177e4SLinus Torvalds# This is used by fsincos library emulation. The correct 102391da177e4SLinus Torvalds# values are already in fp0 and fp1 so we do nothing here. 102401da177e4SLinus Torvalds# 102411da177e4SLinus Torvalds global sto_cos 102421da177e4SLinus Torvaldssto_cos: 102431da177e4SLinus Torvalds rts 102441da177e4SLinus Torvalds 102451da177e4SLinus Torvalds########################################## 102461da177e4SLinus Torvalds 102471da177e4SLinus Torvalds# 102481da177e4SLinus Torvalds# dst_qnan --- force result when destination is a NaN 102491da177e4SLinus Torvalds# 102501da177e4SLinus Torvalds global dst_qnan 102511da177e4SLinus Torvaldsdst_qnan: 102521da177e4SLinus Torvalds fmov.x DST(%a1),%fp0 102531da177e4SLinus Torvalds tst.b DST_EX(%a1) 102541da177e4SLinus Torvalds bmi.b dst_qnan_m 102551da177e4SLinus Torvaldsdst_qnan_p: 102561da177e4SLinus Torvalds mov.b &nan_bmask,FPSR_CC(%a6) 102571da177e4SLinus Torvalds rts 102581da177e4SLinus Torvaldsdst_qnan_m: 102591da177e4SLinus Torvalds mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6) 102601da177e4SLinus Torvalds rts 102611da177e4SLinus Torvalds 102621da177e4SLinus Torvalds# 102631da177e4SLinus Torvalds# src_qnan --- force result when source is a NaN 102641da177e4SLinus Torvalds# 102651da177e4SLinus Torvalds global src_qnan 102661da177e4SLinus Torvaldssrc_qnan: 102671da177e4SLinus Torvalds fmov.x SRC(%a0),%fp0 102681da177e4SLinus Torvalds tst.b SRC_EX(%a0) 102691da177e4SLinus Torvalds bmi.b src_qnan_m 102701da177e4SLinus Torvaldssrc_qnan_p: 102711da177e4SLinus Torvalds mov.b &nan_bmask,FPSR_CC(%a6) 102721da177e4SLinus Torvalds rts 102731da177e4SLinus Torvaldssrc_qnan_m: 102741da177e4SLinus Torvalds mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6) 102751da177e4SLinus Torvalds rts 102761da177e4SLinus Torvalds 102771da177e4SLinus Torvalds########################################## 102781da177e4SLinus Torvalds 102791da177e4SLinus Torvalds# 102801da177e4SLinus Torvalds# Native instruction support 102811da177e4SLinus Torvalds# 102821da177e4SLinus Torvalds# Some systems may need entry points even for 68060 native 102831da177e4SLinus Torvalds# instructions. These routines are provided for 102841da177e4SLinus Torvalds# convenience. 102851da177e4SLinus Torvalds# 102861da177e4SLinus Torvalds global _fadds_ 102871da177e4SLinus Torvalds_fadds_: 102881da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 102891da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 102901da177e4SLinus Torvalds fmov.s 0x8(%sp),%fp0 # load sgl dst 102911da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 102921da177e4SLinus Torvalds fadd.s 0x8(%sp),%fp0 # fadd w/ sgl src 102931da177e4SLinus Torvalds rts 102941da177e4SLinus Torvalds 102951da177e4SLinus Torvalds global _faddd_ 102961da177e4SLinus Torvalds_faddd_: 102971da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 102981da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 102991da177e4SLinus Torvalds fmov.d 0x8(%sp),%fp0 # load dbl dst 103001da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103011da177e4SLinus Torvalds fadd.d 0xc(%sp),%fp0 # fadd w/ dbl src 103021da177e4SLinus Torvalds rts 103031da177e4SLinus Torvalds 103041da177e4SLinus Torvalds global _faddx_ 103051da177e4SLinus Torvalds_faddx_: 103061da177e4SLinus Torvalds fmovm.x 0x4(%sp),&0x80 # load ext dst 103071da177e4SLinus Torvalds fadd.x 0x10(%sp),%fp0 # fadd w/ ext src 103081da177e4SLinus Torvalds rts 103091da177e4SLinus Torvalds 103101da177e4SLinus Torvalds global _fsubs_ 103111da177e4SLinus Torvalds_fsubs_: 103121da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 103131da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 103141da177e4SLinus Torvalds fmov.s 0x8(%sp),%fp0 # load sgl dst 103151da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103161da177e4SLinus Torvalds fsub.s 0x8(%sp),%fp0 # fsub w/ sgl src 103171da177e4SLinus Torvalds rts 103181da177e4SLinus Torvalds 103191da177e4SLinus Torvalds global _fsubd_ 103201da177e4SLinus Torvalds_fsubd_: 103211da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 103221da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 103231da177e4SLinus Torvalds fmov.d 0x8(%sp),%fp0 # load dbl dst 103241da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103251da177e4SLinus Torvalds fsub.d 0xc(%sp),%fp0 # fsub w/ dbl src 103261da177e4SLinus Torvalds rts 103271da177e4SLinus Torvalds 103281da177e4SLinus Torvalds global _fsubx_ 103291da177e4SLinus Torvalds_fsubx_: 103301da177e4SLinus Torvalds fmovm.x 0x4(%sp),&0x80 # load ext dst 103311da177e4SLinus Torvalds fsub.x 0x10(%sp),%fp0 # fsub w/ ext src 103321da177e4SLinus Torvalds rts 103331da177e4SLinus Torvalds 103341da177e4SLinus Torvalds global _fmuls_ 103351da177e4SLinus Torvalds_fmuls_: 103361da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 103371da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 103381da177e4SLinus Torvalds fmov.s 0x8(%sp),%fp0 # load sgl dst 103391da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103401da177e4SLinus Torvalds fmul.s 0x8(%sp),%fp0 # fmul w/ sgl src 103411da177e4SLinus Torvalds rts 103421da177e4SLinus Torvalds 103431da177e4SLinus Torvalds global _fmuld_ 103441da177e4SLinus Torvalds_fmuld_: 103451da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 103461da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 103471da177e4SLinus Torvalds fmov.d 0x8(%sp),%fp0 # load dbl dst 103481da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103491da177e4SLinus Torvalds fmul.d 0xc(%sp),%fp0 # fmul w/ dbl src 103501da177e4SLinus Torvalds rts 103511da177e4SLinus Torvalds 103521da177e4SLinus Torvalds global _fmulx_ 103531da177e4SLinus Torvalds_fmulx_: 103541da177e4SLinus Torvalds fmovm.x 0x4(%sp),&0x80 # load ext dst 103551da177e4SLinus Torvalds fmul.x 0x10(%sp),%fp0 # fmul w/ ext src 103561da177e4SLinus Torvalds rts 103571da177e4SLinus Torvalds 103581da177e4SLinus Torvalds global _fdivs_ 103591da177e4SLinus Torvalds_fdivs_: 103601da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 103611da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 103621da177e4SLinus Torvalds fmov.s 0x8(%sp),%fp0 # load sgl dst 103631da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103641da177e4SLinus Torvalds fdiv.s 0x8(%sp),%fp0 # fdiv w/ sgl src 103651da177e4SLinus Torvalds rts 103661da177e4SLinus Torvalds 103671da177e4SLinus Torvalds global _fdivd_ 103681da177e4SLinus Torvalds_fdivd_: 103691da177e4SLinus Torvalds fmov.l %fpcr,-(%sp) # save fpcr 103701da177e4SLinus Torvalds fmov.l &0x00000000,%fpcr # clear fpcr for load 103711da177e4SLinus Torvalds fmov.d 0x8(%sp),%fp0 # load dbl dst 103721da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr # restore fpcr 103731da177e4SLinus Torvalds fdiv.d 0xc(%sp),%fp0 # fdiv w/ dbl src 103741da177e4SLinus Torvalds rts 103751da177e4SLinus Torvalds 103761da177e4SLinus Torvalds global _fdivx_ 103771da177e4SLinus Torvalds_fdivx_: 103781da177e4SLinus Torvalds fmovm.x 0x4(%sp),&0x80 # load ext dst 103791da177e4SLinus Torvalds fdiv.x 0x10(%sp),%fp0 # fdiv w/ ext src 103801da177e4SLinus Torvalds rts 103811da177e4SLinus Torvalds 103821da177e4SLinus Torvalds global _fabss_ 103831da177e4SLinus Torvalds_fabss_: 103841da177e4SLinus Torvalds fabs.s 0x4(%sp),%fp0 # fabs w/ sgl src 103851da177e4SLinus Torvalds rts 103861da177e4SLinus Torvalds 103871da177e4SLinus Torvalds global _fabsd_ 103881da177e4SLinus Torvalds_fabsd_: 103891da177e4SLinus Torvalds fabs.d 0x4(%sp),%fp0 # fabs w/ dbl src 103901da177e4SLinus Torvalds rts 103911da177e4SLinus Torvalds 103921da177e4SLinus Torvalds global _fabsx_ 103931da177e4SLinus Torvalds_fabsx_: 103941da177e4SLinus Torvalds fabs.x 0x4(%sp),%fp0 # fabs w/ ext src 103951da177e4SLinus Torvalds rts 103961da177e4SLinus Torvalds 103971da177e4SLinus Torvalds global _fnegs_ 103981da177e4SLinus Torvalds_fnegs_: 103991da177e4SLinus Torvalds fneg.s 0x4(%sp),%fp0 # fneg w/ sgl src 104001da177e4SLinus Torvalds rts 104011da177e4SLinus Torvalds 104021da177e4SLinus Torvalds global _fnegd_ 104031da177e4SLinus Torvalds_fnegd_: 104041da177e4SLinus Torvalds fneg.d 0x4(%sp),%fp0 # fneg w/ dbl src 104051da177e4SLinus Torvalds rts 104061da177e4SLinus Torvalds 104071da177e4SLinus Torvalds global _fnegx_ 104081da177e4SLinus Torvalds_fnegx_: 104091da177e4SLinus Torvalds fneg.x 0x4(%sp),%fp0 # fneg w/ ext src 104101da177e4SLinus Torvalds rts 104111da177e4SLinus Torvalds 104121da177e4SLinus Torvalds global _fsqrts_ 104131da177e4SLinus Torvalds_fsqrts_: 104141da177e4SLinus Torvalds fsqrt.s 0x4(%sp),%fp0 # fsqrt w/ sgl src 104151da177e4SLinus Torvalds rts 104161da177e4SLinus Torvalds 104171da177e4SLinus Torvalds global _fsqrtd_ 104181da177e4SLinus Torvalds_fsqrtd_: 104191da177e4SLinus Torvalds fsqrt.d 0x4(%sp),%fp0 # fsqrt w/ dbl src 104201da177e4SLinus Torvalds rts 104211da177e4SLinus Torvalds 104221da177e4SLinus Torvalds global _fsqrtx_ 104231da177e4SLinus Torvalds_fsqrtx_: 104241da177e4SLinus Torvalds fsqrt.x 0x4(%sp),%fp0 # fsqrt w/ ext src 104251da177e4SLinus Torvalds rts 104261da177e4SLinus Torvalds 104271da177e4SLinus Torvalds global _fints_ 104281da177e4SLinus Torvalds_fints_: 104291da177e4SLinus Torvalds fint.s 0x4(%sp),%fp0 # fint w/ sgl src 104301da177e4SLinus Torvalds rts 104311da177e4SLinus Torvalds 104321da177e4SLinus Torvalds global _fintd_ 104331da177e4SLinus Torvalds_fintd_: 104341da177e4SLinus Torvalds fint.d 0x4(%sp),%fp0 # fint w/ dbl src 104351da177e4SLinus Torvalds rts 104361da177e4SLinus Torvalds 104371da177e4SLinus Torvalds global _fintx_ 104381da177e4SLinus Torvalds_fintx_: 104391da177e4SLinus Torvalds fint.x 0x4(%sp),%fp0 # fint w/ ext src 104401da177e4SLinus Torvalds rts 104411da177e4SLinus Torvalds 104421da177e4SLinus Torvalds global _fintrzs_ 104431da177e4SLinus Torvalds_fintrzs_: 104441da177e4SLinus Torvalds fintrz.s 0x4(%sp),%fp0 # fintrz w/ sgl src 104451da177e4SLinus Torvalds rts 104461da177e4SLinus Torvalds 104471da177e4SLinus Torvalds global _fintrzd_ 104481da177e4SLinus Torvalds_fintrzd_: 104491da177e4SLinus Torvalds fintrz.d 0x4(%sp),%fp0 # fintrx w/ dbl src 104501da177e4SLinus Torvalds rts 104511da177e4SLinus Torvalds 104521da177e4SLinus Torvalds global _fintrzx_ 104531da177e4SLinus Torvalds_fintrzx_: 104541da177e4SLinus Torvalds fintrz.x 0x4(%sp),%fp0 # fintrz w/ ext src 104551da177e4SLinus Torvalds rts 104561da177e4SLinus Torvalds 104571da177e4SLinus Torvalds######################################################################## 104581da177e4SLinus Torvalds 104591da177e4SLinus Torvalds######################################################################### 104601da177e4SLinus Torvalds# src_zero(): Return signed zero according to sign of src operand. # 104611da177e4SLinus Torvalds######################################################################### 104621da177e4SLinus Torvalds global src_zero 104631da177e4SLinus Torvaldssrc_zero: 104641da177e4SLinus Torvalds tst.b SRC_EX(%a0) # get sign of src operand 104651da177e4SLinus Torvalds bmi.b ld_mzero # if neg, load neg zero 104661da177e4SLinus Torvalds 104671da177e4SLinus Torvalds# 104681da177e4SLinus Torvalds# ld_pzero(): return a positive zero. 104691da177e4SLinus Torvalds# 104701da177e4SLinus Torvalds global ld_pzero 104711da177e4SLinus Torvaldsld_pzero: 104721da177e4SLinus Torvalds fmov.s &0x00000000,%fp0 # load +0 104731da177e4SLinus Torvalds mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 104741da177e4SLinus Torvalds rts 104751da177e4SLinus Torvalds 104761da177e4SLinus Torvalds# ld_mzero(): return a negative zero. 104771da177e4SLinus Torvalds global ld_mzero 104781da177e4SLinus Torvaldsld_mzero: 104791da177e4SLinus Torvalds fmov.s &0x80000000,%fp0 # load -0 104801da177e4SLinus Torvalds mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits 104811da177e4SLinus Torvalds rts 104821da177e4SLinus Torvalds 104831da177e4SLinus Torvalds######################################################################### 104841da177e4SLinus Torvalds# dst_zero(): Return signed zero according to sign of dst operand. # 104851da177e4SLinus Torvalds######################################################################### 104861da177e4SLinus Torvalds global dst_zero 104871da177e4SLinus Torvaldsdst_zero: 104881da177e4SLinus Torvalds tst.b DST_EX(%a1) # get sign of dst operand 104891da177e4SLinus Torvalds bmi.b ld_mzero # if neg, load neg zero 104901da177e4SLinus Torvalds bra.b ld_pzero # load positive zero 104911da177e4SLinus Torvalds 104921da177e4SLinus Torvalds######################################################################### 104931da177e4SLinus Torvalds# src_inf(): Return signed inf according to sign of src operand. # 104941da177e4SLinus Torvalds######################################################################### 104951da177e4SLinus Torvalds global src_inf 104961da177e4SLinus Torvaldssrc_inf: 104971da177e4SLinus Torvalds tst.b SRC_EX(%a0) # get sign of src operand 104981da177e4SLinus Torvalds bmi.b ld_minf # if negative branch 104991da177e4SLinus Torvalds 105001da177e4SLinus Torvalds# 105011da177e4SLinus Torvalds# ld_pinf(): return a positive infinity. 105021da177e4SLinus Torvalds# 105031da177e4SLinus Torvalds global ld_pinf 105041da177e4SLinus Torvaldsld_pinf: 105051da177e4SLinus Torvalds fmov.s &0x7f800000,%fp0 # load +INF 105061da177e4SLinus Torvalds mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit 105071da177e4SLinus Torvalds rts 105081da177e4SLinus Torvalds 105091da177e4SLinus Torvalds# 105101da177e4SLinus Torvalds# ld_minf():return a negative infinity. 105111da177e4SLinus Torvalds# 105121da177e4SLinus Torvalds global ld_minf 105131da177e4SLinus Torvaldsld_minf: 105141da177e4SLinus Torvalds fmov.s &0xff800000,%fp0 # load -INF 105151da177e4SLinus Torvalds mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits 105161da177e4SLinus Torvalds rts 105171da177e4SLinus Torvalds 105181da177e4SLinus Torvalds######################################################################### 105191da177e4SLinus Torvalds# dst_inf(): Return signed inf according to sign of dst operand. # 105201da177e4SLinus Torvalds######################################################################### 105211da177e4SLinus Torvalds global dst_inf 105221da177e4SLinus Torvaldsdst_inf: 105231da177e4SLinus Torvalds tst.b DST_EX(%a1) # get sign of dst operand 105241da177e4SLinus Torvalds bmi.b ld_minf # if negative branch 105251da177e4SLinus Torvalds bra.b ld_pinf 105261da177e4SLinus Torvalds 105271da177e4SLinus Torvalds global szr_inf 105281da177e4SLinus Torvalds################################################################# 105291da177e4SLinus Torvalds# szr_inf(): Return +ZERO for a negative src operand or # 105301da177e4SLinus Torvalds# +INF for a positive src operand. # 105311da177e4SLinus Torvalds# Routine used for fetox, ftwotox, and ftentox. # 105321da177e4SLinus Torvalds################################################################# 105331da177e4SLinus Torvaldsszr_inf: 105341da177e4SLinus Torvalds tst.b SRC_EX(%a0) # check sign of source 105351da177e4SLinus Torvalds bmi.b ld_pzero 105361da177e4SLinus Torvalds bra.b ld_pinf 105371da177e4SLinus Torvalds 105381da177e4SLinus Torvalds######################################################################### 105391da177e4SLinus Torvalds# sopr_inf(): Return +INF for a positive src operand or # 105401da177e4SLinus Torvalds# jump to operand error routine for a negative src operand. # 105411da177e4SLinus Torvalds# Routine used for flogn, flognp1, flog10, and flog2. # 105421da177e4SLinus Torvalds######################################################################### 105431da177e4SLinus Torvalds global sopr_inf 105441da177e4SLinus Torvaldssopr_inf: 105451da177e4SLinus Torvalds tst.b SRC_EX(%a0) # check sign of source 105461da177e4SLinus Torvalds bmi.w t_operr 105471da177e4SLinus Torvalds bra.b ld_pinf 105481da177e4SLinus Torvalds 105491da177e4SLinus Torvalds################################################################# 105501da177e4SLinus Torvalds# setoxm1i(): Return minus one for a negative src operand or # 105511da177e4SLinus Torvalds# positive infinity for a positive src operand. # 105521da177e4SLinus Torvalds# Routine used for fetoxm1. # 105531da177e4SLinus Torvalds################################################################# 105541da177e4SLinus Torvalds global setoxm1i 105551da177e4SLinus Torvaldssetoxm1i: 105561da177e4SLinus Torvalds tst.b SRC_EX(%a0) # check sign of source 105571da177e4SLinus Torvalds bmi.b ld_mone 105581da177e4SLinus Torvalds bra.b ld_pinf 105591da177e4SLinus Torvalds 105601da177e4SLinus Torvalds######################################################################### 105611da177e4SLinus Torvalds# src_one(): Return signed one according to sign of src operand. # 105621da177e4SLinus Torvalds######################################################################### 105631da177e4SLinus Torvalds global src_one 105641da177e4SLinus Torvaldssrc_one: 105651da177e4SLinus Torvalds tst.b SRC_EX(%a0) # check sign of source 105661da177e4SLinus Torvalds bmi.b ld_mone 105671da177e4SLinus Torvalds 105681da177e4SLinus Torvalds# 105691da177e4SLinus Torvalds# ld_pone(): return positive one. 105701da177e4SLinus Torvalds# 105711da177e4SLinus Torvalds global ld_pone 105721da177e4SLinus Torvaldsld_pone: 105731da177e4SLinus Torvalds fmov.s &0x3f800000,%fp0 # load +1 105741da177e4SLinus Torvalds clr.b FPSR_CC(%a6) 105751da177e4SLinus Torvalds rts 105761da177e4SLinus Torvalds 105771da177e4SLinus Torvalds# 105781da177e4SLinus Torvalds# ld_mone(): return negative one. 105791da177e4SLinus Torvalds# 105801da177e4SLinus Torvalds global ld_mone 105811da177e4SLinus Torvaldsld_mone: 105821da177e4SLinus Torvalds fmov.s &0xbf800000,%fp0 # load -1 105831da177e4SLinus Torvalds mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 105841da177e4SLinus Torvalds rts 105851da177e4SLinus Torvalds 105861da177e4SLinus Torvaldsppiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235 105871da177e4SLinus Torvaldsmpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235 105881da177e4SLinus Torvalds 105891da177e4SLinus Torvalds################################################################# 105901da177e4SLinus Torvalds# spi_2(): Return signed PI/2 according to sign of src operand. # 105911da177e4SLinus Torvalds################################################################# 105921da177e4SLinus Torvalds global spi_2 105931da177e4SLinus Torvaldsspi_2: 105941da177e4SLinus Torvalds tst.b SRC_EX(%a0) # check sign of source 105951da177e4SLinus Torvalds bmi.b ld_mpi2 105961da177e4SLinus Torvalds 105971da177e4SLinus Torvalds# 105981da177e4SLinus Torvalds# ld_ppi2(): return positive PI/2. 105991da177e4SLinus Torvalds# 106001da177e4SLinus Torvalds global ld_ppi2 106011da177e4SLinus Torvaldsld_ppi2: 106021da177e4SLinus Torvalds fmov.l %d0,%fpcr 106031da177e4SLinus Torvalds fmov.x ppiby2(%pc),%fp0 # load +pi/2 106041da177e4SLinus Torvalds bra.w t_pinx2 # set INEX2 106051da177e4SLinus Torvalds 106061da177e4SLinus Torvalds# 106071da177e4SLinus Torvalds# ld_mpi2(): return negative PI/2. 106081da177e4SLinus Torvalds# 106091da177e4SLinus Torvalds global ld_mpi2 106101da177e4SLinus Torvaldsld_mpi2: 106111da177e4SLinus Torvalds fmov.l %d0,%fpcr 106121da177e4SLinus Torvalds fmov.x mpiby2(%pc),%fp0 # load -pi/2 106131da177e4SLinus Torvalds bra.w t_minx2 # set INEX2 106141da177e4SLinus Torvalds 106151da177e4SLinus Torvalds#################################################### 106161da177e4SLinus Torvalds# The following routines give support for fsincos. # 106171da177e4SLinus Torvalds#################################################### 106181da177e4SLinus Torvalds 106191da177e4SLinus Torvalds# 106201da177e4SLinus Torvalds# ssincosz(): When the src operand is ZERO, store a one in the 106211da177e4SLinus Torvalds# cosine register and return a ZERO in fp0 w/ the same sign 106221da177e4SLinus Torvalds# as the src operand. 106231da177e4SLinus Torvalds# 106241da177e4SLinus Torvalds global ssincosz 106251da177e4SLinus Torvaldsssincosz: 106261da177e4SLinus Torvalds fmov.s &0x3f800000,%fp1 106271da177e4SLinus Torvalds tst.b SRC_EX(%a0) # test sign 106281da177e4SLinus Torvalds bpl.b sincoszp 106291da177e4SLinus Torvalds fmov.s &0x80000000,%fp0 # return sin result in fp0 106301da177e4SLinus Torvalds mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) 106311da177e4SLinus Torvalds rts 106321da177e4SLinus Torvaldssincoszp: 106331da177e4SLinus Torvalds fmov.s &0x00000000,%fp0 # return sin result in fp0 106341da177e4SLinus Torvalds mov.b &z_bmask,FPSR_CC(%a6) 106351da177e4SLinus Torvalds rts 106361da177e4SLinus Torvalds 106371da177e4SLinus Torvalds# 106381da177e4SLinus Torvalds# ssincosi(): When the src operand is INF, store a QNAN in the cosine 106391da177e4SLinus Torvalds# register and jump to the operand error routine for negative 106401da177e4SLinus Torvalds# src operands. 106411da177e4SLinus Torvalds# 106421da177e4SLinus Torvalds global ssincosi 106431da177e4SLinus Torvaldsssincosi: 106441da177e4SLinus Torvalds fmov.x qnan(%pc),%fp1 # load NAN 106451da177e4SLinus Torvalds bra.w t_operr 106461da177e4SLinus Torvalds 106471da177e4SLinus Torvalds# 106481da177e4SLinus Torvalds# ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine 106491da177e4SLinus Torvalds# register and branch to the src QNAN routine. 106501da177e4SLinus Torvalds# 106511da177e4SLinus Torvalds global ssincosqnan 106521da177e4SLinus Torvaldsssincosqnan: 106531da177e4SLinus Torvalds fmov.x LOCAL_EX(%a0),%fp1 106541da177e4SLinus Torvalds bra.w src_qnan 106551da177e4SLinus Torvalds 106561da177e4SLinus Torvalds######################################################################## 106571da177e4SLinus Torvalds 106581da177e4SLinus Torvalds global smod_sdnrm 106591da177e4SLinus Torvalds global smod_snorm 106601da177e4SLinus Torvaldssmod_sdnrm: 106611da177e4SLinus Torvaldssmod_snorm: 106621da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 106631da177e4SLinus Torvalds beq.l smod 106641da177e4SLinus Torvalds cmpi.b %d1,&ZERO 106651da177e4SLinus Torvalds beq.w smod_zro 106661da177e4SLinus Torvalds cmpi.b %d1,&INF 106671da177e4SLinus Torvalds beq.l t_operr 106681da177e4SLinus Torvalds cmpi.b %d1,&DENORM 106691da177e4SLinus Torvalds beq.l smod 106701da177e4SLinus Torvalds bra.l dst_qnan 106711da177e4SLinus Torvalds 106721da177e4SLinus Torvalds global smod_szero 106731da177e4SLinus Torvaldssmod_szero: 106741da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 106751da177e4SLinus Torvalds beq.l t_operr 106761da177e4SLinus Torvalds cmpi.b %d1,&ZERO 106771da177e4SLinus Torvalds beq.l t_operr 106781da177e4SLinus Torvalds cmpi.b %d1,&INF 106791da177e4SLinus Torvalds beq.l t_operr 106801da177e4SLinus Torvalds cmpi.b %d1,&DENORM 106811da177e4SLinus Torvalds beq.l t_operr 106821da177e4SLinus Torvalds bra.l dst_qnan 106831da177e4SLinus Torvalds 106841da177e4SLinus Torvalds global smod_sinf 106851da177e4SLinus Torvaldssmod_sinf: 106861da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 106871da177e4SLinus Torvalds beq.l smod_fpn 106881da177e4SLinus Torvalds cmpi.b %d1,&ZERO 106891da177e4SLinus Torvalds beq.l smod_zro 106901da177e4SLinus Torvalds cmpi.b %d1,&INF 106911da177e4SLinus Torvalds beq.l t_operr 106921da177e4SLinus Torvalds cmpi.b %d1,&DENORM 106931da177e4SLinus Torvalds beq.l smod_fpn 106941da177e4SLinus Torvalds bra.l dst_qnan 106951da177e4SLinus Torvalds 106961da177e4SLinus Torvaldssmod_zro: 106971da177e4SLinus Torvaldssrem_zro: 106981da177e4SLinus Torvalds mov.b SRC_EX(%a0),%d1 # get src sign 106991da177e4SLinus Torvalds mov.b DST_EX(%a1),%d0 # get dst sign 107001da177e4SLinus Torvalds eor.b %d0,%d1 # get qbyte sign 107011da177e4SLinus Torvalds andi.b &0x80,%d1 107021da177e4SLinus Torvalds mov.b %d1,FPSR_QBYTE(%a6) 107031da177e4SLinus Torvalds tst.b %d0 107041da177e4SLinus Torvalds bpl.w ld_pzero 107051da177e4SLinus Torvalds bra.w ld_mzero 107061da177e4SLinus Torvalds 107071da177e4SLinus Torvaldssmod_fpn: 107081da177e4SLinus Torvaldssrem_fpn: 107091da177e4SLinus Torvalds clr.b FPSR_QBYTE(%a6) 107101da177e4SLinus Torvalds mov.l %d0,-(%sp) 107111da177e4SLinus Torvalds mov.b SRC_EX(%a0),%d1 # get src sign 107121da177e4SLinus Torvalds mov.b DST_EX(%a1),%d0 # get dst sign 107131da177e4SLinus Torvalds eor.b %d0,%d1 # get qbyte sign 107141da177e4SLinus Torvalds andi.b &0x80,%d1 107151da177e4SLinus Torvalds mov.b %d1,FPSR_QBYTE(%a6) 107161da177e4SLinus Torvalds cmpi.b DTAG(%a6),&DENORM 107171da177e4SLinus Torvalds bne.b smod_nrm 107181da177e4SLinus Torvalds lea DST(%a1),%a0 107191da177e4SLinus Torvalds mov.l (%sp)+,%d0 107201da177e4SLinus Torvalds bra t_resdnrm 107211da177e4SLinus Torvaldssmod_nrm: 107221da177e4SLinus Torvalds fmov.l (%sp)+,%fpcr 107231da177e4SLinus Torvalds fmov.x DST(%a1),%fp0 107241da177e4SLinus Torvalds tst.b DST_EX(%a1) 107251da177e4SLinus Torvalds bmi.b smod_nrm_neg 107261da177e4SLinus Torvalds rts 107271da177e4SLinus Torvalds 107281da177e4SLinus Torvaldssmod_nrm_neg: 107291da177e4SLinus Torvalds mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' code 107301da177e4SLinus Torvalds rts 107311da177e4SLinus Torvalds 107321da177e4SLinus Torvalds######################################################################### 107331da177e4SLinus Torvalds global srem_snorm 107341da177e4SLinus Torvalds global srem_sdnrm 107351da177e4SLinus Torvaldssrem_sdnrm: 107361da177e4SLinus Torvaldssrem_snorm: 107371da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 107381da177e4SLinus Torvalds beq.l srem 107391da177e4SLinus Torvalds cmpi.b %d1,&ZERO 107401da177e4SLinus Torvalds beq.w srem_zro 107411da177e4SLinus Torvalds cmpi.b %d1,&INF 107421da177e4SLinus Torvalds beq.l t_operr 107431da177e4SLinus Torvalds cmpi.b %d1,&DENORM 107441da177e4SLinus Torvalds beq.l srem 107451da177e4SLinus Torvalds bra.l dst_qnan 107461da177e4SLinus Torvalds 107471da177e4SLinus Torvalds global srem_szero 107481da177e4SLinus Torvaldssrem_szero: 107491da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 107501da177e4SLinus Torvalds beq.l t_operr 107511da177e4SLinus Torvalds cmpi.b %d1,&ZERO 107521da177e4SLinus Torvalds beq.l t_operr 107531da177e4SLinus Torvalds cmpi.b %d1,&INF 107541da177e4SLinus Torvalds beq.l t_operr 107551da177e4SLinus Torvalds cmpi.b %d1,&DENORM 107561da177e4SLinus Torvalds beq.l t_operr 107571da177e4SLinus Torvalds bra.l dst_qnan 107581da177e4SLinus Torvalds 107591da177e4SLinus Torvalds global srem_sinf 107601da177e4SLinus Torvaldssrem_sinf: 107611da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 107621da177e4SLinus Torvalds beq.w srem_fpn 107631da177e4SLinus Torvalds cmpi.b %d1,&ZERO 107641da177e4SLinus Torvalds beq.w srem_zro 107651da177e4SLinus Torvalds cmpi.b %d1,&INF 107661da177e4SLinus Torvalds beq.l t_operr 107671da177e4SLinus Torvalds cmpi.b %d1,&DENORM 107681da177e4SLinus Torvalds beq.l srem_fpn 107691da177e4SLinus Torvalds bra.l dst_qnan 107701da177e4SLinus Torvalds 107711da177e4SLinus Torvalds######################################################################### 107721da177e4SLinus Torvalds 107731da177e4SLinus Torvalds global sscale_snorm 107741da177e4SLinus Torvalds global sscale_sdnrm 107751da177e4SLinus Torvaldssscale_snorm: 107761da177e4SLinus Torvaldssscale_sdnrm: 107771da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 107781da177e4SLinus Torvalds beq.l sscale 107791da177e4SLinus Torvalds cmpi.b %d1,&ZERO 107801da177e4SLinus Torvalds beq.l dst_zero 107811da177e4SLinus Torvalds cmpi.b %d1,&INF 107821da177e4SLinus Torvalds beq.l dst_inf 107831da177e4SLinus Torvalds cmpi.b %d1,&DENORM 107841da177e4SLinus Torvalds beq.l sscale 107851da177e4SLinus Torvalds bra.l dst_qnan 107861da177e4SLinus Torvalds 107871da177e4SLinus Torvalds global sscale_szero 107881da177e4SLinus Torvaldssscale_szero: 107891da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 107901da177e4SLinus Torvalds beq.l sscale 107911da177e4SLinus Torvalds cmpi.b %d1,&ZERO 107921da177e4SLinus Torvalds beq.l dst_zero 107931da177e4SLinus Torvalds cmpi.b %d1,&INF 107941da177e4SLinus Torvalds beq.l dst_inf 107951da177e4SLinus Torvalds cmpi.b %d1,&DENORM 107961da177e4SLinus Torvalds beq.l sscale 107971da177e4SLinus Torvalds bra.l dst_qnan 107981da177e4SLinus Torvalds 107991da177e4SLinus Torvalds global sscale_sinf 108001da177e4SLinus Torvaldssscale_sinf: 108011da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 108021da177e4SLinus Torvalds beq.l t_operr 108031da177e4SLinus Torvalds cmpi.b %d1,&QNAN 108041da177e4SLinus Torvalds beq.l dst_qnan 108051da177e4SLinus Torvalds bra.l t_operr 108061da177e4SLinus Torvalds 108071da177e4SLinus Torvalds######################################################################## 108081da177e4SLinus Torvalds 108091da177e4SLinus Torvalds global sop_sqnan 108101da177e4SLinus Torvaldssop_sqnan: 108111da177e4SLinus Torvalds mov.b DTAG(%a6),%d1 108121da177e4SLinus Torvalds cmpi.b %d1,&QNAN 108131da177e4SLinus Torvalds beq.l dst_qnan 108141da177e4SLinus Torvalds bra.l src_qnan 108151da177e4SLinus Torvalds 108161da177e4SLinus Torvalds######################################################################### 108171da177e4SLinus Torvalds# norm(): normalize the mantissa of an extended precision input. the # 108181da177e4SLinus Torvalds# input operand should not be normalized already. # 108191da177e4SLinus Torvalds# # 108201da177e4SLinus Torvalds# XDEF **************************************************************** # 108211da177e4SLinus Torvalds# norm() # 108221da177e4SLinus Torvalds# # 108231da177e4SLinus Torvalds# XREF **************************************************************** # 108241da177e4SLinus Torvalds# none # 108251da177e4SLinus Torvalds# # 108261da177e4SLinus Torvalds# INPUT *************************************************************** # 108271da177e4SLinus Torvalds# a0 = pointer fp extended precision operand to normalize # 108281da177e4SLinus Torvalds# # 108291da177e4SLinus Torvalds# OUTPUT ************************************************************** # 108301da177e4SLinus Torvalds# d0 = number of bit positions the mantissa was shifted # 108311da177e4SLinus Torvalds# a0 = the input operand's mantissa is normalized; the exponent # 108321da177e4SLinus Torvalds# is unchanged. # 108331da177e4SLinus Torvalds# # 108341da177e4SLinus Torvalds######################################################################### 108351da177e4SLinus Torvalds global norm 108361da177e4SLinus Torvaldsnorm: 108371da177e4SLinus Torvalds mov.l %d2, -(%sp) # create some temp regs 108381da177e4SLinus Torvalds mov.l %d3, -(%sp) 108391da177e4SLinus Torvalds 108401da177e4SLinus Torvalds mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa) 108411da177e4SLinus Torvalds mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa) 108421da177e4SLinus Torvalds 108431da177e4SLinus Torvalds bfffo %d0{&0:&32}, %d2 # how many places to shift? 108441da177e4SLinus Torvalds beq.b norm_lo # hi(man) is all zeroes! 108451da177e4SLinus Torvalds 108461da177e4SLinus Torvaldsnorm_hi: 108471da177e4SLinus Torvalds lsl.l %d2, %d0 # left shift hi(man) 108481da177e4SLinus Torvalds bfextu %d1{&0:%d2}, %d3 # extract lo bits 108491da177e4SLinus Torvalds 108501da177e4SLinus Torvalds or.l %d3, %d0 # create hi(man) 108511da177e4SLinus Torvalds lsl.l %d2, %d1 # create lo(man) 108521da177e4SLinus Torvalds 108531da177e4SLinus Torvalds mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 108541da177e4SLinus Torvalds mov.l %d1, FTEMP_LO(%a0) # store new lo(man) 108551da177e4SLinus Torvalds 108561da177e4SLinus Torvalds mov.l %d2, %d0 # return shift amount 108571da177e4SLinus Torvalds 108581da177e4SLinus Torvalds mov.l (%sp)+, %d3 # restore temp regs 108591da177e4SLinus Torvalds mov.l (%sp)+, %d2 108601da177e4SLinus Torvalds 108611da177e4SLinus Torvalds rts 108621da177e4SLinus Torvalds 108631da177e4SLinus Torvaldsnorm_lo: 108641da177e4SLinus Torvalds bfffo %d1{&0:&32}, %d2 # how many places to shift? 108651da177e4SLinus Torvalds lsl.l %d2, %d1 # shift lo(man) 108661da177e4SLinus Torvalds add.l &32, %d2 # add 32 to shft amount 108671da177e4SLinus Torvalds 108681da177e4SLinus Torvalds mov.l %d1, FTEMP_HI(%a0) # store hi(man) 108691da177e4SLinus Torvalds clr.l FTEMP_LO(%a0) # lo(man) is now zero 108701da177e4SLinus Torvalds 108711da177e4SLinus Torvalds mov.l %d2, %d0 # return shift amount 108721da177e4SLinus Torvalds 108731da177e4SLinus Torvalds mov.l (%sp)+, %d3 # restore temp regs 108741da177e4SLinus Torvalds mov.l (%sp)+, %d2 108751da177e4SLinus Torvalds 108761da177e4SLinus Torvalds rts 108771da177e4SLinus Torvalds 108781da177e4SLinus Torvalds######################################################################### 108791da177e4SLinus Torvalds# unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO # 108801da177e4SLinus Torvalds# - returns corresponding optype tag # 108811da177e4SLinus Torvalds# # 108821da177e4SLinus Torvalds# XDEF **************************************************************** # 108831da177e4SLinus Torvalds# unnorm_fix() # 108841da177e4SLinus Torvalds# # 108851da177e4SLinus Torvalds# XREF **************************************************************** # 108861da177e4SLinus Torvalds# norm() - normalize the mantissa # 108871da177e4SLinus Torvalds# # 108881da177e4SLinus Torvalds# INPUT *************************************************************** # 108891da177e4SLinus Torvalds# a0 = pointer to unnormalized extended precision number # 108901da177e4SLinus Torvalds# # 108911da177e4SLinus Torvalds# OUTPUT ************************************************************** # 108921da177e4SLinus Torvalds# d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO # 108931da177e4SLinus Torvalds# a0 = input operand has been converted to a norm, denorm, or # 108941da177e4SLinus Torvalds# zero; both the exponent and mantissa are changed. # 108951da177e4SLinus Torvalds# # 108961da177e4SLinus Torvalds######################################################################### 108971da177e4SLinus Torvalds 108981da177e4SLinus Torvalds global unnorm_fix 108991da177e4SLinus Torvaldsunnorm_fix: 109001da177e4SLinus Torvalds bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed? 109011da177e4SLinus Torvalds bne.b unnorm_shift # hi(man) is not all zeroes 109021da177e4SLinus Torvalds 109031da177e4SLinus Torvalds# 109041da177e4SLinus Torvalds# hi(man) is all zeroes so see if any bits in lo(man) are set 109051da177e4SLinus Torvalds# 109061da177e4SLinus Torvaldsunnorm_chk_lo: 109071da177e4SLinus Torvalds bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero? 109081da177e4SLinus Torvalds beq.w unnorm_zero # yes 109091da177e4SLinus Torvalds 109101da177e4SLinus Torvalds add.w &32, %d0 # no; fix shift distance 109111da177e4SLinus Torvalds 109121da177e4SLinus Torvalds# 109131da177e4SLinus Torvalds# d0 = # shifts needed for complete normalization 109141da177e4SLinus Torvalds# 109151da177e4SLinus Torvaldsunnorm_shift: 109161da177e4SLinus Torvalds clr.l %d1 # clear top word 109171da177e4SLinus Torvalds mov.w FTEMP_EX(%a0), %d1 # extract exponent 109181da177e4SLinus Torvalds and.w &0x7fff, %d1 # strip off sgn 109191da177e4SLinus Torvalds 109201da177e4SLinus Torvalds cmp.w %d0, %d1 # will denorm push exp < 0? 109211da177e4SLinus Torvalds bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0 109221da177e4SLinus Torvalds 109231da177e4SLinus Torvalds# 109241da177e4SLinus Torvalds# exponent would not go < 0. therefore, number stays normalized 109251da177e4SLinus Torvalds# 109261da177e4SLinus Torvalds sub.w %d0, %d1 # shift exponent value 109271da177e4SLinus Torvalds mov.w FTEMP_EX(%a0), %d0 # load old exponent 109281da177e4SLinus Torvalds and.w &0x8000, %d0 # save old sign 109291da177e4SLinus Torvalds or.w %d0, %d1 # {sgn,new exp} 109301da177e4SLinus Torvalds mov.w %d1, FTEMP_EX(%a0) # insert new exponent 109311da177e4SLinus Torvalds 109321da177e4SLinus Torvalds bsr.l norm # normalize UNNORM 109331da177e4SLinus Torvalds 109341da177e4SLinus Torvalds mov.b &NORM, %d0 # return new optype tag 109351da177e4SLinus Torvalds rts 109361da177e4SLinus Torvalds 109371da177e4SLinus Torvalds# 109381da177e4SLinus Torvalds# exponent would go < 0, so only denormalize until exp = 0 109391da177e4SLinus Torvalds# 109401da177e4SLinus Torvaldsunnorm_nrm_zero: 109411da177e4SLinus Torvalds cmp.b %d1, &32 # is exp <= 32? 109421da177e4SLinus Torvalds bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent 109431da177e4SLinus Torvalds 109441da177e4SLinus Torvalds bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man) 109451da177e4SLinus Torvalds mov.l %d0, FTEMP_HI(%a0) # save new hi(man) 109461da177e4SLinus Torvalds 109471da177e4SLinus Torvalds mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 109481da177e4SLinus Torvalds lsl.l %d1, %d0 # extract new lo(man) 109491da177e4SLinus Torvalds mov.l %d0, FTEMP_LO(%a0) # save new lo(man) 109501da177e4SLinus Torvalds 109511da177e4SLinus Torvalds and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 109521da177e4SLinus Torvalds 109531da177e4SLinus Torvalds mov.b &DENORM, %d0 # return new optype tag 109541da177e4SLinus Torvalds rts 109551da177e4SLinus Torvalds 109561da177e4SLinus Torvalds# 109571da177e4SLinus Torvalds# only mantissa bits set are in lo(man) 109581da177e4SLinus Torvalds# 109591da177e4SLinus Torvaldsunnorm_nrm_zero_lrg: 109601da177e4SLinus Torvalds sub.w &32, %d1 # adjust shft amt by 32 109611da177e4SLinus Torvalds 109621da177e4SLinus Torvalds mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 109631da177e4SLinus Torvalds lsl.l %d1, %d0 # left shift lo(man) 109641da177e4SLinus Torvalds 109651da177e4SLinus Torvalds mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 109661da177e4SLinus Torvalds clr.l FTEMP_LO(%a0) # lo(man) = 0 109671da177e4SLinus Torvalds 109681da177e4SLinus Torvalds and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 109691da177e4SLinus Torvalds 109701da177e4SLinus Torvalds mov.b &DENORM, %d0 # return new optype tag 109711da177e4SLinus Torvalds rts 109721da177e4SLinus Torvalds 109731da177e4SLinus Torvalds# 109741da177e4SLinus Torvalds# whole mantissa is zero so this UNNORM is actually a zero 109751da177e4SLinus Torvalds# 109761da177e4SLinus Torvaldsunnorm_zero: 109771da177e4SLinus Torvalds and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero 109781da177e4SLinus Torvalds 109791da177e4SLinus Torvalds mov.b &ZERO, %d0 # fix optype tag 109801da177e4SLinus Torvalds rts 10981