162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262306a36Sopenharmony_ciMOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 362306a36Sopenharmony_ciM68000 Hi-Performance Microprocessor Division 462306a36Sopenharmony_ciM68060 Software Package 562306a36Sopenharmony_ciProduction Release P1.00 -- October 10, 1994 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciM68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciTHE SOFTWARE is provided on an "AS IS" basis and without warranty. 1062306a36Sopenharmony_ciTo the maximum extent permitted by applicable law, 1162306a36Sopenharmony_ciMOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 1262306a36Sopenharmony_ciINCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 1362306a36Sopenharmony_ciand any warranty against infringement with regard to the SOFTWARE 1462306a36Sopenharmony_ci(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials. 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciTo the maximum extent permitted by applicable law, 1762306a36Sopenharmony_ciIN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 1862306a36Sopenharmony_ci(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 1962306a36Sopenharmony_ciBUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) 2062306a36Sopenharmony_ciARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. 2162306a36Sopenharmony_ciMotorola assumes no responsibility for the maintenance and support of the SOFTWARE. 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciYou are hereby granted a copyright license to use, modify, and distribute the SOFTWARE 2462306a36Sopenharmony_ciso long as this entire notice is retained without alteration in any modified and/or 2562306a36Sopenharmony_ciredistributed versions, and that such modified versions are clearly identified as such. 2662306a36Sopenharmony_ciNo licenses are granted by implication, estoppel or otherwise under any patents 2762306a36Sopenharmony_cior trademarks of Motorola, Inc. 2862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2962306a36Sopenharmony_ci# 3062306a36Sopenharmony_ci# lfptop.s: 3162306a36Sopenharmony_ci# This file is appended to the top of the 060ILSP package 3262306a36Sopenharmony_ci# and contains the entry points into the package. The user, in 3362306a36Sopenharmony_ci# effect, branches to one of the branch table entries located here. 3462306a36Sopenharmony_ci# 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci bra.l _facoss_ 3762306a36Sopenharmony_ci short 0x0000 3862306a36Sopenharmony_ci bra.l _facosd_ 3962306a36Sopenharmony_ci short 0x0000 4062306a36Sopenharmony_ci bra.l _facosx_ 4162306a36Sopenharmony_ci short 0x0000 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci bra.l _fasins_ 4462306a36Sopenharmony_ci short 0x0000 4562306a36Sopenharmony_ci bra.l _fasind_ 4662306a36Sopenharmony_ci short 0x0000 4762306a36Sopenharmony_ci bra.l _fasinx_ 4862306a36Sopenharmony_ci short 0x0000 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci bra.l _fatans_ 5162306a36Sopenharmony_ci short 0x0000 5262306a36Sopenharmony_ci bra.l _fatand_ 5362306a36Sopenharmony_ci short 0x0000 5462306a36Sopenharmony_ci bra.l _fatanx_ 5562306a36Sopenharmony_ci short 0x0000 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci bra.l _fatanhs_ 5862306a36Sopenharmony_ci short 0x0000 5962306a36Sopenharmony_ci bra.l _fatanhd_ 6062306a36Sopenharmony_ci short 0x0000 6162306a36Sopenharmony_ci bra.l _fatanhx_ 6262306a36Sopenharmony_ci short 0x0000 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci bra.l _fcoss_ 6562306a36Sopenharmony_ci short 0x0000 6662306a36Sopenharmony_ci bra.l _fcosd_ 6762306a36Sopenharmony_ci short 0x0000 6862306a36Sopenharmony_ci bra.l _fcosx_ 6962306a36Sopenharmony_ci short 0x0000 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci bra.l _fcoshs_ 7262306a36Sopenharmony_ci short 0x0000 7362306a36Sopenharmony_ci bra.l _fcoshd_ 7462306a36Sopenharmony_ci short 0x0000 7562306a36Sopenharmony_ci bra.l _fcoshx_ 7662306a36Sopenharmony_ci short 0x0000 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci bra.l _fetoxs_ 7962306a36Sopenharmony_ci short 0x0000 8062306a36Sopenharmony_ci bra.l _fetoxd_ 8162306a36Sopenharmony_ci short 0x0000 8262306a36Sopenharmony_ci bra.l _fetoxx_ 8362306a36Sopenharmony_ci short 0x0000 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci bra.l _fetoxm1s_ 8662306a36Sopenharmony_ci short 0x0000 8762306a36Sopenharmony_ci bra.l _fetoxm1d_ 8862306a36Sopenharmony_ci short 0x0000 8962306a36Sopenharmony_ci bra.l _fetoxm1x_ 9062306a36Sopenharmony_ci short 0x0000 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci bra.l _fgetexps_ 9362306a36Sopenharmony_ci short 0x0000 9462306a36Sopenharmony_ci bra.l _fgetexpd_ 9562306a36Sopenharmony_ci short 0x0000 9662306a36Sopenharmony_ci bra.l _fgetexpx_ 9762306a36Sopenharmony_ci short 0x0000 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci bra.l _fgetmans_ 10062306a36Sopenharmony_ci short 0x0000 10162306a36Sopenharmony_ci bra.l _fgetmand_ 10262306a36Sopenharmony_ci short 0x0000 10362306a36Sopenharmony_ci bra.l _fgetmanx_ 10462306a36Sopenharmony_ci short 0x0000 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci bra.l _flog10s_ 10762306a36Sopenharmony_ci short 0x0000 10862306a36Sopenharmony_ci bra.l _flog10d_ 10962306a36Sopenharmony_ci short 0x0000 11062306a36Sopenharmony_ci bra.l _flog10x_ 11162306a36Sopenharmony_ci short 0x0000 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci bra.l _flog2s_ 11462306a36Sopenharmony_ci short 0x0000 11562306a36Sopenharmony_ci bra.l _flog2d_ 11662306a36Sopenharmony_ci short 0x0000 11762306a36Sopenharmony_ci bra.l _flog2x_ 11862306a36Sopenharmony_ci short 0x0000 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci bra.l _flogns_ 12162306a36Sopenharmony_ci short 0x0000 12262306a36Sopenharmony_ci bra.l _flognd_ 12362306a36Sopenharmony_ci short 0x0000 12462306a36Sopenharmony_ci bra.l _flognx_ 12562306a36Sopenharmony_ci short 0x0000 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci bra.l _flognp1s_ 12862306a36Sopenharmony_ci short 0x0000 12962306a36Sopenharmony_ci bra.l _flognp1d_ 13062306a36Sopenharmony_ci short 0x0000 13162306a36Sopenharmony_ci bra.l _flognp1x_ 13262306a36Sopenharmony_ci short 0x0000 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci bra.l _fmods_ 13562306a36Sopenharmony_ci short 0x0000 13662306a36Sopenharmony_ci bra.l _fmodd_ 13762306a36Sopenharmony_ci short 0x0000 13862306a36Sopenharmony_ci bra.l _fmodx_ 13962306a36Sopenharmony_ci short 0x0000 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci bra.l _frems_ 14262306a36Sopenharmony_ci short 0x0000 14362306a36Sopenharmony_ci bra.l _fremd_ 14462306a36Sopenharmony_ci short 0x0000 14562306a36Sopenharmony_ci bra.l _fremx_ 14662306a36Sopenharmony_ci short 0x0000 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci bra.l _fscales_ 14962306a36Sopenharmony_ci short 0x0000 15062306a36Sopenharmony_ci bra.l _fscaled_ 15162306a36Sopenharmony_ci short 0x0000 15262306a36Sopenharmony_ci bra.l _fscalex_ 15362306a36Sopenharmony_ci short 0x0000 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci bra.l _fsins_ 15662306a36Sopenharmony_ci short 0x0000 15762306a36Sopenharmony_ci bra.l _fsind_ 15862306a36Sopenharmony_ci short 0x0000 15962306a36Sopenharmony_ci bra.l _fsinx_ 16062306a36Sopenharmony_ci short 0x0000 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci bra.l _fsincoss_ 16362306a36Sopenharmony_ci short 0x0000 16462306a36Sopenharmony_ci bra.l _fsincosd_ 16562306a36Sopenharmony_ci short 0x0000 16662306a36Sopenharmony_ci bra.l _fsincosx_ 16762306a36Sopenharmony_ci short 0x0000 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci bra.l _fsinhs_ 17062306a36Sopenharmony_ci short 0x0000 17162306a36Sopenharmony_ci bra.l _fsinhd_ 17262306a36Sopenharmony_ci short 0x0000 17362306a36Sopenharmony_ci bra.l _fsinhx_ 17462306a36Sopenharmony_ci short 0x0000 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci bra.l _ftans_ 17762306a36Sopenharmony_ci short 0x0000 17862306a36Sopenharmony_ci bra.l _ftand_ 17962306a36Sopenharmony_ci short 0x0000 18062306a36Sopenharmony_ci bra.l _ftanx_ 18162306a36Sopenharmony_ci short 0x0000 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci bra.l _ftanhs_ 18462306a36Sopenharmony_ci short 0x0000 18562306a36Sopenharmony_ci bra.l _ftanhd_ 18662306a36Sopenharmony_ci short 0x0000 18762306a36Sopenharmony_ci bra.l _ftanhx_ 18862306a36Sopenharmony_ci short 0x0000 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci bra.l _ftentoxs_ 19162306a36Sopenharmony_ci short 0x0000 19262306a36Sopenharmony_ci bra.l _ftentoxd_ 19362306a36Sopenharmony_ci short 0x0000 19462306a36Sopenharmony_ci bra.l _ftentoxx_ 19562306a36Sopenharmony_ci short 0x0000 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci bra.l _ftwotoxs_ 19862306a36Sopenharmony_ci short 0x0000 19962306a36Sopenharmony_ci bra.l _ftwotoxd_ 20062306a36Sopenharmony_ci short 0x0000 20162306a36Sopenharmony_ci bra.l _ftwotoxx_ 20262306a36Sopenharmony_ci short 0x0000 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci bra.l _fabss_ 20562306a36Sopenharmony_ci short 0x0000 20662306a36Sopenharmony_ci bra.l _fabsd_ 20762306a36Sopenharmony_ci short 0x0000 20862306a36Sopenharmony_ci bra.l _fabsx_ 20962306a36Sopenharmony_ci short 0x0000 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci bra.l _fadds_ 21262306a36Sopenharmony_ci short 0x0000 21362306a36Sopenharmony_ci bra.l _faddd_ 21462306a36Sopenharmony_ci short 0x0000 21562306a36Sopenharmony_ci bra.l _faddx_ 21662306a36Sopenharmony_ci short 0x0000 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci bra.l _fdivs_ 21962306a36Sopenharmony_ci short 0x0000 22062306a36Sopenharmony_ci bra.l _fdivd_ 22162306a36Sopenharmony_ci short 0x0000 22262306a36Sopenharmony_ci bra.l _fdivx_ 22362306a36Sopenharmony_ci short 0x0000 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci bra.l _fints_ 22662306a36Sopenharmony_ci short 0x0000 22762306a36Sopenharmony_ci bra.l _fintd_ 22862306a36Sopenharmony_ci short 0x0000 22962306a36Sopenharmony_ci bra.l _fintx_ 23062306a36Sopenharmony_ci short 0x0000 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci bra.l _fintrzs_ 23362306a36Sopenharmony_ci short 0x0000 23462306a36Sopenharmony_ci bra.l _fintrzd_ 23562306a36Sopenharmony_ci short 0x0000 23662306a36Sopenharmony_ci bra.l _fintrzx_ 23762306a36Sopenharmony_ci short 0x0000 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci bra.l _fmuls_ 24062306a36Sopenharmony_ci short 0x0000 24162306a36Sopenharmony_ci bra.l _fmuld_ 24262306a36Sopenharmony_ci short 0x0000 24362306a36Sopenharmony_ci bra.l _fmulx_ 24462306a36Sopenharmony_ci short 0x0000 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci bra.l _fnegs_ 24762306a36Sopenharmony_ci short 0x0000 24862306a36Sopenharmony_ci bra.l _fnegd_ 24962306a36Sopenharmony_ci short 0x0000 25062306a36Sopenharmony_ci bra.l _fnegx_ 25162306a36Sopenharmony_ci short 0x0000 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci bra.l _fsqrts_ 25462306a36Sopenharmony_ci short 0x0000 25562306a36Sopenharmony_ci bra.l _fsqrtd_ 25662306a36Sopenharmony_ci short 0x0000 25762306a36Sopenharmony_ci bra.l _fsqrtx_ 25862306a36Sopenharmony_ci short 0x0000 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci bra.l _fsubs_ 26162306a36Sopenharmony_ci short 0x0000 26262306a36Sopenharmony_ci bra.l _fsubd_ 26362306a36Sopenharmony_ci short 0x0000 26462306a36Sopenharmony_ci bra.l _fsubx_ 26562306a36Sopenharmony_ci short 0x0000 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci# leave room for future possible additions 26862306a36Sopenharmony_ci align 0x400 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci# 27162306a36Sopenharmony_ci# This file contains a set of define statements for constants 27262306a36Sopenharmony_ci# in order to promote readability within the corecode itself. 27362306a36Sopenharmony_ci# 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ciset LOCAL_SIZE, 192 # stack frame size(bytes) 27662306a36Sopenharmony_ciset LV, -LOCAL_SIZE # stack offset 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ciset EXC_SR, 0x4 # stack status register 27962306a36Sopenharmony_ciset EXC_PC, 0x6 # stack pc 28062306a36Sopenharmony_ciset EXC_VOFF, 0xa # stacked vector offset 28162306a36Sopenharmony_ciset EXC_EA, 0xc # stacked <ea> 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciset EXC_FP, 0x0 # frame pointer 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ciset EXC_AREGS, -68 # offset of all address regs 28662306a36Sopenharmony_ciset EXC_DREGS, -100 # offset of all data regs 28762306a36Sopenharmony_ciset EXC_FPREGS, -36 # offset of all fp regs 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ciset EXC_A7, EXC_AREGS+(7*4) # offset of saved a7 29062306a36Sopenharmony_ciset OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7 29162306a36Sopenharmony_ciset EXC_A6, EXC_AREGS+(6*4) # offset of saved a6 29262306a36Sopenharmony_ciset EXC_A5, EXC_AREGS+(5*4) 29362306a36Sopenharmony_ciset EXC_A4, EXC_AREGS+(4*4) 29462306a36Sopenharmony_ciset EXC_A3, EXC_AREGS+(3*4) 29562306a36Sopenharmony_ciset EXC_A2, EXC_AREGS+(2*4) 29662306a36Sopenharmony_ciset EXC_A1, EXC_AREGS+(1*4) 29762306a36Sopenharmony_ciset EXC_A0, EXC_AREGS+(0*4) 29862306a36Sopenharmony_ciset EXC_D7, EXC_DREGS+(7*4) 29962306a36Sopenharmony_ciset EXC_D6, EXC_DREGS+(6*4) 30062306a36Sopenharmony_ciset EXC_D5, EXC_DREGS+(5*4) 30162306a36Sopenharmony_ciset EXC_D4, EXC_DREGS+(4*4) 30262306a36Sopenharmony_ciset EXC_D3, EXC_DREGS+(3*4) 30362306a36Sopenharmony_ciset EXC_D2, EXC_DREGS+(2*4) 30462306a36Sopenharmony_ciset EXC_D1, EXC_DREGS+(1*4) 30562306a36Sopenharmony_ciset EXC_D0, EXC_DREGS+(0*4) 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ciset EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0 30862306a36Sopenharmony_ciset EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1 30962306a36Sopenharmony_ciset EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used) 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ciset FP_SCR1, LV+80 # fp scratch 1 31262306a36Sopenharmony_ciset FP_SCR1_EX, FP_SCR1+0 31362306a36Sopenharmony_ciset FP_SCR1_SGN, FP_SCR1+2 31462306a36Sopenharmony_ciset FP_SCR1_HI, FP_SCR1+4 31562306a36Sopenharmony_ciset FP_SCR1_LO, FP_SCR1+8 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ciset FP_SCR0, LV+68 # fp scratch 0 31862306a36Sopenharmony_ciset FP_SCR0_EX, FP_SCR0+0 31962306a36Sopenharmony_ciset FP_SCR0_SGN, FP_SCR0+2 32062306a36Sopenharmony_ciset FP_SCR0_HI, FP_SCR0+4 32162306a36Sopenharmony_ciset FP_SCR0_LO, FP_SCR0+8 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ciset FP_DST, LV+56 # fp destination operand 32462306a36Sopenharmony_ciset FP_DST_EX, FP_DST+0 32562306a36Sopenharmony_ciset FP_DST_SGN, FP_DST+2 32662306a36Sopenharmony_ciset FP_DST_HI, FP_DST+4 32762306a36Sopenharmony_ciset FP_DST_LO, FP_DST+8 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ciset FP_SRC, LV+44 # fp source operand 33062306a36Sopenharmony_ciset FP_SRC_EX, FP_SRC+0 33162306a36Sopenharmony_ciset FP_SRC_SGN, FP_SRC+2 33262306a36Sopenharmony_ciset FP_SRC_HI, FP_SRC+4 33362306a36Sopenharmony_ciset FP_SRC_LO, FP_SRC+8 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ciset USER_FPIAR, LV+40 # FP instr address register 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ciset USER_FPSR, LV+36 # FP status register 33862306a36Sopenharmony_ciset FPSR_CC, USER_FPSR+0 # FPSR condition codes 33962306a36Sopenharmony_ciset FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte 34062306a36Sopenharmony_ciset FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte 34162306a36Sopenharmony_ciset FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ciset USER_FPCR, LV+32 # FP control register 34462306a36Sopenharmony_ciset FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable 34562306a36Sopenharmony_ciset FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ciset L_SCR3, LV+28 # integer scratch 3 34862306a36Sopenharmony_ciset L_SCR2, LV+24 # integer scratch 2 34962306a36Sopenharmony_ciset L_SCR1, LV+20 # integer scratch 1 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ciset STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst) 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ciset EXC_TEMP2, LV+24 # temporary space 35462306a36Sopenharmony_ciset EXC_TEMP, LV+16 # temporary space 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ciset DTAG, LV+15 # destination operand type 35762306a36Sopenharmony_ciset STAG, LV+14 # source operand type 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ciset SPCOND_FLG, LV+10 # flag: special case (see below) 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ciset EXC_CC, LV+8 # saved condition codes 36262306a36Sopenharmony_ciset EXC_EXTWPTR, LV+4 # saved current PC (active) 36362306a36Sopenharmony_ciset EXC_EXTWORD, LV+2 # saved extension word 36462306a36Sopenharmony_ciset EXC_CMDREG, LV+2 # saved extension word 36562306a36Sopenharmony_ciset EXC_OPWORD, LV+0 # saved operation word 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci################################ 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci# Helpful macros 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ciset FTEMP, 0 # offsets within an 37262306a36Sopenharmony_ciset FTEMP_EX, 0 # extended precision 37362306a36Sopenharmony_ciset FTEMP_SGN, 2 # value saved in memory. 37462306a36Sopenharmony_ciset FTEMP_HI, 4 37562306a36Sopenharmony_ciset FTEMP_LO, 8 37662306a36Sopenharmony_ciset FTEMP_GRS, 12 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ciset LOCAL, 0 # offsets within an 37962306a36Sopenharmony_ciset LOCAL_EX, 0 # extended precision 38062306a36Sopenharmony_ciset LOCAL_SGN, 2 # value saved in memory. 38162306a36Sopenharmony_ciset LOCAL_HI, 4 38262306a36Sopenharmony_ciset LOCAL_LO, 8 38362306a36Sopenharmony_ciset LOCAL_GRS, 12 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ciset DST, 0 # offsets within an 38662306a36Sopenharmony_ciset DST_EX, 0 # extended precision 38762306a36Sopenharmony_ciset DST_HI, 4 # value saved in memory. 38862306a36Sopenharmony_ciset DST_LO, 8 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ciset SRC, 0 # offsets within an 39162306a36Sopenharmony_ciset SRC_EX, 0 # extended precision 39262306a36Sopenharmony_ciset SRC_HI, 4 # value saved in memory. 39362306a36Sopenharmony_ciset SRC_LO, 8 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ciset SGL_LO, 0x3f81 # min sgl prec exponent 39662306a36Sopenharmony_ciset SGL_HI, 0x407e # max sgl prec exponent 39762306a36Sopenharmony_ciset DBL_LO, 0x3c01 # min dbl prec exponent 39862306a36Sopenharmony_ciset DBL_HI, 0x43fe # max dbl prec exponent 39962306a36Sopenharmony_ciset EXT_LO, 0x0 # min ext prec exponent 40062306a36Sopenharmony_ciset EXT_HI, 0x7ffe # max ext prec exponent 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ciset EXT_BIAS, 0x3fff # extended precision bias 40362306a36Sopenharmony_ciset SGL_BIAS, 0x007f # single precision bias 40462306a36Sopenharmony_ciset DBL_BIAS, 0x03ff # double precision bias 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ciset NORM, 0x00 # operand type for STAG/DTAG 40762306a36Sopenharmony_ciset ZERO, 0x01 # operand type for STAG/DTAG 40862306a36Sopenharmony_ciset INF, 0x02 # operand type for STAG/DTAG 40962306a36Sopenharmony_ciset QNAN, 0x03 # operand type for STAG/DTAG 41062306a36Sopenharmony_ciset DENORM, 0x04 # operand type for STAG/DTAG 41162306a36Sopenharmony_ciset SNAN, 0x05 # operand type for STAG/DTAG 41262306a36Sopenharmony_ciset UNNORM, 0x06 # operand type for STAG/DTAG 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci################## 41562306a36Sopenharmony_ci# FPSR/FPCR bits # 41662306a36Sopenharmony_ci################## 41762306a36Sopenharmony_ciset neg_bit, 0x3 # negative result 41862306a36Sopenharmony_ciset z_bit, 0x2 # zero result 41962306a36Sopenharmony_ciset inf_bit, 0x1 # infinite result 42062306a36Sopenharmony_ciset nan_bit, 0x0 # NAN result 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ciset q_sn_bit, 0x7 # sign bit of quotient byte 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ciset bsun_bit, 7 # branch on unordered 42562306a36Sopenharmony_ciset snan_bit, 6 # signalling NAN 42662306a36Sopenharmony_ciset operr_bit, 5 # operand error 42762306a36Sopenharmony_ciset ovfl_bit, 4 # overflow 42862306a36Sopenharmony_ciset unfl_bit, 3 # underflow 42962306a36Sopenharmony_ciset dz_bit, 2 # divide by zero 43062306a36Sopenharmony_ciset inex2_bit, 1 # inexact result 2 43162306a36Sopenharmony_ciset inex1_bit, 0 # inexact result 1 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ciset aiop_bit, 7 # accrued inexact operation bit 43462306a36Sopenharmony_ciset aovfl_bit, 6 # accrued overflow bit 43562306a36Sopenharmony_ciset aunfl_bit, 5 # accrued underflow bit 43662306a36Sopenharmony_ciset adz_bit, 4 # accrued dz bit 43762306a36Sopenharmony_ciset ainex_bit, 3 # accrued inexact bit 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci############################# 44062306a36Sopenharmony_ci# FPSR individual bit masks # 44162306a36Sopenharmony_ci############################# 44262306a36Sopenharmony_ciset neg_mask, 0x08000000 # negative bit mask (lw) 44362306a36Sopenharmony_ciset inf_mask, 0x02000000 # infinity bit mask (lw) 44462306a36Sopenharmony_ciset z_mask, 0x04000000 # zero bit mask (lw) 44562306a36Sopenharmony_ciset nan_mask, 0x01000000 # nan bit mask (lw) 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ciset neg_bmask, 0x08 # negative bit mask (byte) 44862306a36Sopenharmony_ciset inf_bmask, 0x02 # infinity bit mask (byte) 44962306a36Sopenharmony_ciset z_bmask, 0x04 # zero bit mask (byte) 45062306a36Sopenharmony_ciset nan_bmask, 0x01 # nan bit mask (byte) 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ciset bsun_mask, 0x00008000 # bsun exception mask 45362306a36Sopenharmony_ciset snan_mask, 0x00004000 # snan exception mask 45462306a36Sopenharmony_ciset operr_mask, 0x00002000 # operr exception mask 45562306a36Sopenharmony_ciset ovfl_mask, 0x00001000 # overflow exception mask 45662306a36Sopenharmony_ciset unfl_mask, 0x00000800 # underflow exception mask 45762306a36Sopenharmony_ciset dz_mask, 0x00000400 # dz exception mask 45862306a36Sopenharmony_ciset inex2_mask, 0x00000200 # inex2 exception mask 45962306a36Sopenharmony_ciset inex1_mask, 0x00000100 # inex1 exception mask 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ciset aiop_mask, 0x00000080 # accrued illegal operation 46262306a36Sopenharmony_ciset aovfl_mask, 0x00000040 # accrued overflow 46362306a36Sopenharmony_ciset aunfl_mask, 0x00000020 # accrued underflow 46462306a36Sopenharmony_ciset adz_mask, 0x00000010 # accrued divide by zero 46562306a36Sopenharmony_ciset ainex_mask, 0x00000008 # accrued inexact 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci###################################### 46862306a36Sopenharmony_ci# FPSR combinations used in the FPSP # 46962306a36Sopenharmony_ci###################################### 47062306a36Sopenharmony_ciset dzinf_mask, inf_mask+dz_mask+adz_mask 47162306a36Sopenharmony_ciset opnan_mask, nan_mask+operr_mask+aiop_mask 47262306a36Sopenharmony_ciset nzi_mask, 0x01ffffff #clears N, Z, and I 47362306a36Sopenharmony_ciset unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask 47462306a36Sopenharmony_ciset unf2inx_mask, unfl_mask+inex2_mask+ainex_mask 47562306a36Sopenharmony_ciset ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask 47662306a36Sopenharmony_ciset inx1a_mask, inex1_mask+ainex_mask 47762306a36Sopenharmony_ciset inx2a_mask, inex2_mask+ainex_mask 47862306a36Sopenharmony_ciset snaniop_mask, nan_mask+snan_mask+aiop_mask 47962306a36Sopenharmony_ciset snaniop2_mask, snan_mask+aiop_mask 48062306a36Sopenharmony_ciset naniop_mask, nan_mask+aiop_mask 48162306a36Sopenharmony_ciset neginf_mask, neg_mask+inf_mask 48262306a36Sopenharmony_ciset infaiop_mask, inf_mask+aiop_mask 48362306a36Sopenharmony_ciset negz_mask, neg_mask+z_mask 48462306a36Sopenharmony_ciset opaop_mask, operr_mask+aiop_mask 48562306a36Sopenharmony_ciset unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask 48662306a36Sopenharmony_ciset ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci######### 48962306a36Sopenharmony_ci# misc. # 49062306a36Sopenharmony_ci######### 49162306a36Sopenharmony_ciset rnd_stky_bit, 29 # stky bit pos in longword 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ciset sign_bit, 0x7 # sign bit 49462306a36Sopenharmony_ciset signan_bit, 0x6 # signalling nan bit 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ciset sgl_thresh, 0x3f81 # minimum sgl exponent 49762306a36Sopenharmony_ciset dbl_thresh, 0x3c01 # minimum dbl exponent 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ciset x_mode, 0x0 # extended precision 50062306a36Sopenharmony_ciset s_mode, 0x4 # single precision 50162306a36Sopenharmony_ciset d_mode, 0x8 # double precision 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ciset rn_mode, 0x0 # round-to-nearest 50462306a36Sopenharmony_ciset rz_mode, 0x1 # round-to-zero 50562306a36Sopenharmony_ciset rm_mode, 0x2 # round-tp-minus-infinity 50662306a36Sopenharmony_ciset rp_mode, 0x3 # round-to-plus-infinity 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ciset mantissalen, 64 # length of mantissa in bits 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ciset BYTE, 1 # len(byte) == 1 byte 51162306a36Sopenharmony_ciset WORD, 2 # len(word) == 2 bytes 51262306a36Sopenharmony_ciset LONG, 4 # len(longword) == 2 bytes 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ciset BSUN_VEC, 0xc0 # bsun vector offset 51562306a36Sopenharmony_ciset INEX_VEC, 0xc4 # inexact vector offset 51662306a36Sopenharmony_ciset DZ_VEC, 0xc8 # dz vector offset 51762306a36Sopenharmony_ciset UNFL_VEC, 0xcc # unfl vector offset 51862306a36Sopenharmony_ciset OPERR_VEC, 0xd0 # operr vector offset 51962306a36Sopenharmony_ciset OVFL_VEC, 0xd4 # ovfl vector offset 52062306a36Sopenharmony_ciset SNAN_VEC, 0xd8 # snan vector offset 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci########################### 52362306a36Sopenharmony_ci# SPecial CONDition FLaGs # 52462306a36Sopenharmony_ci########################### 52562306a36Sopenharmony_ciset ftrapcc_flg, 0x01 # flag bit: ftrapcc exception 52662306a36Sopenharmony_ciset fbsun_flg, 0x02 # flag bit: bsun exception 52762306a36Sopenharmony_ciset mia7_flg, 0x04 # flag bit: (a7)+ <ea> 52862306a36Sopenharmony_ciset mda7_flg, 0x08 # flag bit: -(a7) <ea> 52962306a36Sopenharmony_ciset fmovm_flg, 0x40 # flag bit: fmovm instruction 53062306a36Sopenharmony_ciset immed_flg, 0x80 # flag bit: &<data> <ea> 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ciset ftrapcc_bit, 0x0 53362306a36Sopenharmony_ciset fbsun_bit, 0x1 53462306a36Sopenharmony_ciset mia7_bit, 0x2 53562306a36Sopenharmony_ciset mda7_bit, 0x3 53662306a36Sopenharmony_ciset immed_bit, 0x7 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci################################## 53962306a36Sopenharmony_ci# TRANSCENDENTAL "LAST-OP" FLAGS # 54062306a36Sopenharmony_ci################################## 54162306a36Sopenharmony_ciset FMUL_OP, 0x0 # fmul instr performed last 54262306a36Sopenharmony_ciset FDIV_OP, 0x1 # fdiv performed last 54362306a36Sopenharmony_ciset FADD_OP, 0x2 # fadd performed last 54462306a36Sopenharmony_ciset FMOV_OP, 0x3 # fmov performed last 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci############# 54762306a36Sopenharmony_ci# CONSTANTS # 54862306a36Sopenharmony_ci############# 54962306a36Sopenharmony_ciT1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD 55062306a36Sopenharmony_ciT2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ciPI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000 55362306a36Sopenharmony_ciPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ciTWOBYPI: 55662306a36Sopenharmony_ci long 0x3FE45F30,0x6DC9C883 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci######################################################################### 55962306a36Sopenharmony_ci# MONADIC TEMPLATE # 56062306a36Sopenharmony_ci######################################################################### 56162306a36Sopenharmony_ci global _fsins_ 56262306a36Sopenharmony_ci_fsins_: 56362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 56662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 56762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci# 57262306a36Sopenharmony_ci# copy, convert, and tag input argument 57362306a36Sopenharmony_ci# 57462306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 57562306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 57662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 57762306a36Sopenharmony_ci bsr.l tag # fetch operand type 57862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 57962306a36Sopenharmony_ci mov.b %d0,%d1 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci clr.l %d0 58462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci tst.b %d1 58762306a36Sopenharmony_ci bne.b _L0_2s 58862306a36Sopenharmony_ci bsr.l ssin # operand is a NORM 58962306a36Sopenharmony_ci bra.b _L0_6s 59062306a36Sopenharmony_ci_L0_2s: 59162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 59262306a36Sopenharmony_ci bne.b _L0_3s # no 59362306a36Sopenharmony_ci bsr.l src_zero # yes 59462306a36Sopenharmony_ci bra.b _L0_6s 59562306a36Sopenharmony_ci_L0_3s: 59662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 59762306a36Sopenharmony_ci bne.b _L0_4s # no 59862306a36Sopenharmony_ci bsr.l t_operr # yes 59962306a36Sopenharmony_ci bra.b _L0_6s 60062306a36Sopenharmony_ci_L0_4s: 60162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 60262306a36Sopenharmony_ci bne.b _L0_5s # no 60362306a36Sopenharmony_ci bsr.l src_qnan # yes 60462306a36Sopenharmony_ci bra.b _L0_6s 60562306a36Sopenharmony_ci_L0_5s: 60662306a36Sopenharmony_ci bsr.l ssind # operand is a DENORM 60762306a36Sopenharmony_ci_L0_6s: 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci# 61062306a36Sopenharmony_ci# Result is now in FP0 61162306a36Sopenharmony_ci# 61262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 61362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 61462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 61562306a36Sopenharmony_ci unlk %a6 61662306a36Sopenharmony_ci rts 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci global _fsind_ 61962306a36Sopenharmony_ci_fsind_: 62062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 62362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 62462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci# 62962306a36Sopenharmony_ci# copy, convert, and tag input argument 63062306a36Sopenharmony_ci# 63162306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 63262306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 63362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 63462306a36Sopenharmony_ci bsr.l tag # fetch operand type 63562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 63662306a36Sopenharmony_ci mov.b %d0,%d1 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci clr.l %d0 64162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 64462306a36Sopenharmony_ci tst.b %d1 64562306a36Sopenharmony_ci bne.b _L0_2d 64662306a36Sopenharmony_ci bsr.l ssin # operand is a NORM 64762306a36Sopenharmony_ci bra.b _L0_6d 64862306a36Sopenharmony_ci_L0_2d: 64962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 65062306a36Sopenharmony_ci bne.b _L0_3d # no 65162306a36Sopenharmony_ci bsr.l src_zero # yes 65262306a36Sopenharmony_ci bra.b _L0_6d 65362306a36Sopenharmony_ci_L0_3d: 65462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 65562306a36Sopenharmony_ci bne.b _L0_4d # no 65662306a36Sopenharmony_ci bsr.l t_operr # yes 65762306a36Sopenharmony_ci bra.b _L0_6d 65862306a36Sopenharmony_ci_L0_4d: 65962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 66062306a36Sopenharmony_ci bne.b _L0_5d # no 66162306a36Sopenharmony_ci bsr.l src_qnan # yes 66262306a36Sopenharmony_ci bra.b _L0_6d 66362306a36Sopenharmony_ci_L0_5d: 66462306a36Sopenharmony_ci bsr.l ssind # operand is a DENORM 66562306a36Sopenharmony_ci_L0_6d: 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci# 66862306a36Sopenharmony_ci# Result is now in FP0 66962306a36Sopenharmony_ci# 67062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 67162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 67262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 67362306a36Sopenharmony_ci unlk %a6 67462306a36Sopenharmony_ci rts 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci global _fsinx_ 67762306a36Sopenharmony_ci_fsinx_: 67862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 68162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 68262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci# 68762306a36Sopenharmony_ci# copy, convert, and tag input argument 68862306a36Sopenharmony_ci# 68962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 69062306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 69162306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 69262306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 69362306a36Sopenharmony_ci bsr.l tag # fetch operand type 69462306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 69562306a36Sopenharmony_ci mov.b %d0,%d1 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci clr.l %d0 70062306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci tst.b %d1 70362306a36Sopenharmony_ci bne.b _L0_2x 70462306a36Sopenharmony_ci bsr.l ssin # operand is a NORM 70562306a36Sopenharmony_ci bra.b _L0_6x 70662306a36Sopenharmony_ci_L0_2x: 70762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 70862306a36Sopenharmony_ci bne.b _L0_3x # no 70962306a36Sopenharmony_ci bsr.l src_zero # yes 71062306a36Sopenharmony_ci bra.b _L0_6x 71162306a36Sopenharmony_ci_L0_3x: 71262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 71362306a36Sopenharmony_ci bne.b _L0_4x # no 71462306a36Sopenharmony_ci bsr.l t_operr # yes 71562306a36Sopenharmony_ci bra.b _L0_6x 71662306a36Sopenharmony_ci_L0_4x: 71762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 71862306a36Sopenharmony_ci bne.b _L0_5x # no 71962306a36Sopenharmony_ci bsr.l src_qnan # yes 72062306a36Sopenharmony_ci bra.b _L0_6x 72162306a36Sopenharmony_ci_L0_5x: 72262306a36Sopenharmony_ci bsr.l ssind # operand is a DENORM 72362306a36Sopenharmony_ci_L0_6x: 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci# 72662306a36Sopenharmony_ci# Result is now in FP0 72762306a36Sopenharmony_ci# 72862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 72962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 73062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 73162306a36Sopenharmony_ci unlk %a6 73262306a36Sopenharmony_ci rts 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci######################################################################### 73662306a36Sopenharmony_ci# MONADIC TEMPLATE # 73762306a36Sopenharmony_ci######################################################################### 73862306a36Sopenharmony_ci global _fcoss_ 73962306a36Sopenharmony_ci_fcoss_: 74062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 74362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 74462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci# 74962306a36Sopenharmony_ci# copy, convert, and tag input argument 75062306a36Sopenharmony_ci# 75162306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 75262306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 75362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 75462306a36Sopenharmony_ci bsr.l tag # fetch operand type 75562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 75662306a36Sopenharmony_ci mov.b %d0,%d1 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci clr.l %d0 76162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci tst.b %d1 76462306a36Sopenharmony_ci bne.b _L1_2s 76562306a36Sopenharmony_ci bsr.l scos # operand is a NORM 76662306a36Sopenharmony_ci bra.b _L1_6s 76762306a36Sopenharmony_ci_L1_2s: 76862306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 76962306a36Sopenharmony_ci bne.b _L1_3s # no 77062306a36Sopenharmony_ci bsr.l ld_pone # yes 77162306a36Sopenharmony_ci bra.b _L1_6s 77262306a36Sopenharmony_ci_L1_3s: 77362306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 77462306a36Sopenharmony_ci bne.b _L1_4s # no 77562306a36Sopenharmony_ci bsr.l t_operr # yes 77662306a36Sopenharmony_ci bra.b _L1_6s 77762306a36Sopenharmony_ci_L1_4s: 77862306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 77962306a36Sopenharmony_ci bne.b _L1_5s # no 78062306a36Sopenharmony_ci bsr.l src_qnan # yes 78162306a36Sopenharmony_ci bra.b _L1_6s 78262306a36Sopenharmony_ci_L1_5s: 78362306a36Sopenharmony_ci bsr.l scosd # operand is a DENORM 78462306a36Sopenharmony_ci_L1_6s: 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci# 78762306a36Sopenharmony_ci# Result is now in FP0 78862306a36Sopenharmony_ci# 78962306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 79062306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 79162306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 79262306a36Sopenharmony_ci unlk %a6 79362306a36Sopenharmony_ci rts 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci global _fcosd_ 79662306a36Sopenharmony_ci_fcosd_: 79762306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 80062306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 80162306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci# 80662306a36Sopenharmony_ci# copy, convert, and tag input argument 80762306a36Sopenharmony_ci# 80862306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 80962306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 81062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 81162306a36Sopenharmony_ci bsr.l tag # fetch operand type 81262306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 81362306a36Sopenharmony_ci mov.b %d0,%d1 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci clr.l %d0 81862306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 82162306a36Sopenharmony_ci tst.b %d1 82262306a36Sopenharmony_ci bne.b _L1_2d 82362306a36Sopenharmony_ci bsr.l scos # operand is a NORM 82462306a36Sopenharmony_ci bra.b _L1_6d 82562306a36Sopenharmony_ci_L1_2d: 82662306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 82762306a36Sopenharmony_ci bne.b _L1_3d # no 82862306a36Sopenharmony_ci bsr.l ld_pone # yes 82962306a36Sopenharmony_ci bra.b _L1_6d 83062306a36Sopenharmony_ci_L1_3d: 83162306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 83262306a36Sopenharmony_ci bne.b _L1_4d # no 83362306a36Sopenharmony_ci bsr.l t_operr # yes 83462306a36Sopenharmony_ci bra.b _L1_6d 83562306a36Sopenharmony_ci_L1_4d: 83662306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 83762306a36Sopenharmony_ci bne.b _L1_5d # no 83862306a36Sopenharmony_ci bsr.l src_qnan # yes 83962306a36Sopenharmony_ci bra.b _L1_6d 84062306a36Sopenharmony_ci_L1_5d: 84162306a36Sopenharmony_ci bsr.l scosd # operand is a DENORM 84262306a36Sopenharmony_ci_L1_6d: 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci# 84562306a36Sopenharmony_ci# Result is now in FP0 84662306a36Sopenharmony_ci# 84762306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 84862306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 84962306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 85062306a36Sopenharmony_ci unlk %a6 85162306a36Sopenharmony_ci rts 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci global _fcosx_ 85462306a36Sopenharmony_ci_fcosx_: 85562306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 85862306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 85962306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci# 86462306a36Sopenharmony_ci# copy, convert, and tag input argument 86562306a36Sopenharmony_ci# 86662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 86762306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 86862306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 86962306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 87062306a36Sopenharmony_ci bsr.l tag # fetch operand type 87162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 87262306a36Sopenharmony_ci mov.b %d0,%d1 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci clr.l %d0 87762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_ci tst.b %d1 88062306a36Sopenharmony_ci bne.b _L1_2x 88162306a36Sopenharmony_ci bsr.l scos # operand is a NORM 88262306a36Sopenharmony_ci bra.b _L1_6x 88362306a36Sopenharmony_ci_L1_2x: 88462306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 88562306a36Sopenharmony_ci bne.b _L1_3x # no 88662306a36Sopenharmony_ci bsr.l ld_pone # yes 88762306a36Sopenharmony_ci bra.b _L1_6x 88862306a36Sopenharmony_ci_L1_3x: 88962306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 89062306a36Sopenharmony_ci bne.b _L1_4x # no 89162306a36Sopenharmony_ci bsr.l t_operr # yes 89262306a36Sopenharmony_ci bra.b _L1_6x 89362306a36Sopenharmony_ci_L1_4x: 89462306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 89562306a36Sopenharmony_ci bne.b _L1_5x # no 89662306a36Sopenharmony_ci bsr.l src_qnan # yes 89762306a36Sopenharmony_ci bra.b _L1_6x 89862306a36Sopenharmony_ci_L1_5x: 89962306a36Sopenharmony_ci bsr.l scosd # operand is a DENORM 90062306a36Sopenharmony_ci_L1_6x: 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci# 90362306a36Sopenharmony_ci# Result is now in FP0 90462306a36Sopenharmony_ci# 90562306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 90662306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 90762306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 90862306a36Sopenharmony_ci unlk %a6 90962306a36Sopenharmony_ci rts 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci######################################################################### 91362306a36Sopenharmony_ci# MONADIC TEMPLATE # 91462306a36Sopenharmony_ci######################################################################### 91562306a36Sopenharmony_ci global _fsinhs_ 91662306a36Sopenharmony_ci_fsinhs_: 91762306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 92062306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 92162306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci# 92662306a36Sopenharmony_ci# copy, convert, and tag input argument 92762306a36Sopenharmony_ci# 92862306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 92962306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 93062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 93162306a36Sopenharmony_ci bsr.l tag # fetch operand type 93262306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 93362306a36Sopenharmony_ci mov.b %d0,%d1 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci clr.l %d0 93862306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci tst.b %d1 94162306a36Sopenharmony_ci bne.b _L2_2s 94262306a36Sopenharmony_ci bsr.l ssinh # operand is a NORM 94362306a36Sopenharmony_ci bra.b _L2_6s 94462306a36Sopenharmony_ci_L2_2s: 94562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 94662306a36Sopenharmony_ci bne.b _L2_3s # no 94762306a36Sopenharmony_ci bsr.l src_zero # yes 94862306a36Sopenharmony_ci bra.b _L2_6s 94962306a36Sopenharmony_ci_L2_3s: 95062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 95162306a36Sopenharmony_ci bne.b _L2_4s # no 95262306a36Sopenharmony_ci bsr.l src_inf # yes 95362306a36Sopenharmony_ci bra.b _L2_6s 95462306a36Sopenharmony_ci_L2_4s: 95562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 95662306a36Sopenharmony_ci bne.b _L2_5s # no 95762306a36Sopenharmony_ci bsr.l src_qnan # yes 95862306a36Sopenharmony_ci bra.b _L2_6s 95962306a36Sopenharmony_ci_L2_5s: 96062306a36Sopenharmony_ci bsr.l ssinhd # operand is a DENORM 96162306a36Sopenharmony_ci_L2_6s: 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci# 96462306a36Sopenharmony_ci# Result is now in FP0 96562306a36Sopenharmony_ci# 96662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 96762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 96862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 96962306a36Sopenharmony_ci unlk %a6 97062306a36Sopenharmony_ci rts 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci global _fsinhd_ 97362306a36Sopenharmony_ci_fsinhd_: 97462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 97762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 97862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_ci# 98362306a36Sopenharmony_ci# copy, convert, and tag input argument 98462306a36Sopenharmony_ci# 98562306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 98662306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 98762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 98862306a36Sopenharmony_ci bsr.l tag # fetch operand type 98962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 99062306a36Sopenharmony_ci mov.b %d0,%d1 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci clr.l %d0 99562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 99862306a36Sopenharmony_ci tst.b %d1 99962306a36Sopenharmony_ci bne.b _L2_2d 100062306a36Sopenharmony_ci bsr.l ssinh # operand is a NORM 100162306a36Sopenharmony_ci bra.b _L2_6d 100262306a36Sopenharmony_ci_L2_2d: 100362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 100462306a36Sopenharmony_ci bne.b _L2_3d # no 100562306a36Sopenharmony_ci bsr.l src_zero # yes 100662306a36Sopenharmony_ci bra.b _L2_6d 100762306a36Sopenharmony_ci_L2_3d: 100862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 100962306a36Sopenharmony_ci bne.b _L2_4d # no 101062306a36Sopenharmony_ci bsr.l src_inf # yes 101162306a36Sopenharmony_ci bra.b _L2_6d 101262306a36Sopenharmony_ci_L2_4d: 101362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 101462306a36Sopenharmony_ci bne.b _L2_5d # no 101562306a36Sopenharmony_ci bsr.l src_qnan # yes 101662306a36Sopenharmony_ci bra.b _L2_6d 101762306a36Sopenharmony_ci_L2_5d: 101862306a36Sopenharmony_ci bsr.l ssinhd # operand is a DENORM 101962306a36Sopenharmony_ci_L2_6d: 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ci# 102262306a36Sopenharmony_ci# Result is now in FP0 102362306a36Sopenharmony_ci# 102462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 102562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 102662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 102762306a36Sopenharmony_ci unlk %a6 102862306a36Sopenharmony_ci rts 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci global _fsinhx_ 103162306a36Sopenharmony_ci_fsinhx_: 103262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 103562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 103662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci# 104162306a36Sopenharmony_ci# copy, convert, and tag input argument 104262306a36Sopenharmony_ci# 104362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 104462306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 104562306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 104662306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 104762306a36Sopenharmony_ci bsr.l tag # fetch operand type 104862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 104962306a36Sopenharmony_ci mov.b %d0,%d1 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci clr.l %d0 105462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci tst.b %d1 105762306a36Sopenharmony_ci bne.b _L2_2x 105862306a36Sopenharmony_ci bsr.l ssinh # operand is a NORM 105962306a36Sopenharmony_ci bra.b _L2_6x 106062306a36Sopenharmony_ci_L2_2x: 106162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 106262306a36Sopenharmony_ci bne.b _L2_3x # no 106362306a36Sopenharmony_ci bsr.l src_zero # yes 106462306a36Sopenharmony_ci bra.b _L2_6x 106562306a36Sopenharmony_ci_L2_3x: 106662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 106762306a36Sopenharmony_ci bne.b _L2_4x # no 106862306a36Sopenharmony_ci bsr.l src_inf # yes 106962306a36Sopenharmony_ci bra.b _L2_6x 107062306a36Sopenharmony_ci_L2_4x: 107162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 107262306a36Sopenharmony_ci bne.b _L2_5x # no 107362306a36Sopenharmony_ci bsr.l src_qnan # yes 107462306a36Sopenharmony_ci bra.b _L2_6x 107562306a36Sopenharmony_ci_L2_5x: 107662306a36Sopenharmony_ci bsr.l ssinhd # operand is a DENORM 107762306a36Sopenharmony_ci_L2_6x: 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci# 108062306a36Sopenharmony_ci# Result is now in FP0 108162306a36Sopenharmony_ci# 108262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 108362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 108462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 108562306a36Sopenharmony_ci unlk %a6 108662306a36Sopenharmony_ci rts 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci######################################################################### 109062306a36Sopenharmony_ci# MONADIC TEMPLATE # 109162306a36Sopenharmony_ci######################################################################### 109262306a36Sopenharmony_ci global _flognp1s_ 109362306a36Sopenharmony_ci_flognp1s_: 109462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 109762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 109862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci# 110362306a36Sopenharmony_ci# copy, convert, and tag input argument 110462306a36Sopenharmony_ci# 110562306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 110662306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 110762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 110862306a36Sopenharmony_ci bsr.l tag # fetch operand type 110962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 111062306a36Sopenharmony_ci mov.b %d0,%d1 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 111362306a36Sopenharmony_ci 111462306a36Sopenharmony_ci clr.l %d0 111562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci tst.b %d1 111862306a36Sopenharmony_ci bne.b _L3_2s 111962306a36Sopenharmony_ci bsr.l slognp1 # operand is a NORM 112062306a36Sopenharmony_ci bra.b _L3_6s 112162306a36Sopenharmony_ci_L3_2s: 112262306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 112362306a36Sopenharmony_ci bne.b _L3_3s # no 112462306a36Sopenharmony_ci bsr.l src_zero # yes 112562306a36Sopenharmony_ci bra.b _L3_6s 112662306a36Sopenharmony_ci_L3_3s: 112762306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 112862306a36Sopenharmony_ci bne.b _L3_4s # no 112962306a36Sopenharmony_ci bsr.l sopr_inf # yes 113062306a36Sopenharmony_ci bra.b _L3_6s 113162306a36Sopenharmony_ci_L3_4s: 113262306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 113362306a36Sopenharmony_ci bne.b _L3_5s # no 113462306a36Sopenharmony_ci bsr.l src_qnan # yes 113562306a36Sopenharmony_ci bra.b _L3_6s 113662306a36Sopenharmony_ci_L3_5s: 113762306a36Sopenharmony_ci bsr.l slognp1d # operand is a DENORM 113862306a36Sopenharmony_ci_L3_6s: 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci# 114162306a36Sopenharmony_ci# Result is now in FP0 114262306a36Sopenharmony_ci# 114362306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 114462306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 114562306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 114662306a36Sopenharmony_ci unlk %a6 114762306a36Sopenharmony_ci rts 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci global _flognp1d_ 115062306a36Sopenharmony_ci_flognp1d_: 115162306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 115462306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 115562306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_ci# 116062306a36Sopenharmony_ci# copy, convert, and tag input argument 116162306a36Sopenharmony_ci# 116262306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 116362306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 116462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 116562306a36Sopenharmony_ci bsr.l tag # fetch operand type 116662306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 116762306a36Sopenharmony_ci mov.b %d0,%d1 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci clr.l %d0 117262306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 117562306a36Sopenharmony_ci tst.b %d1 117662306a36Sopenharmony_ci bne.b _L3_2d 117762306a36Sopenharmony_ci bsr.l slognp1 # operand is a NORM 117862306a36Sopenharmony_ci bra.b _L3_6d 117962306a36Sopenharmony_ci_L3_2d: 118062306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 118162306a36Sopenharmony_ci bne.b _L3_3d # no 118262306a36Sopenharmony_ci bsr.l src_zero # yes 118362306a36Sopenharmony_ci bra.b _L3_6d 118462306a36Sopenharmony_ci_L3_3d: 118562306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 118662306a36Sopenharmony_ci bne.b _L3_4d # no 118762306a36Sopenharmony_ci bsr.l sopr_inf # yes 118862306a36Sopenharmony_ci bra.b _L3_6d 118962306a36Sopenharmony_ci_L3_4d: 119062306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 119162306a36Sopenharmony_ci bne.b _L3_5d # no 119262306a36Sopenharmony_ci bsr.l src_qnan # yes 119362306a36Sopenharmony_ci bra.b _L3_6d 119462306a36Sopenharmony_ci_L3_5d: 119562306a36Sopenharmony_ci bsr.l slognp1d # operand is a DENORM 119662306a36Sopenharmony_ci_L3_6d: 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_ci# 119962306a36Sopenharmony_ci# Result is now in FP0 120062306a36Sopenharmony_ci# 120162306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 120262306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 120362306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 120462306a36Sopenharmony_ci unlk %a6 120562306a36Sopenharmony_ci rts 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci global _flognp1x_ 120862306a36Sopenharmony_ci_flognp1x_: 120962306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 121262306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 121362306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci# 121862306a36Sopenharmony_ci# copy, convert, and tag input argument 121962306a36Sopenharmony_ci# 122062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 122162306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 122262306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 122362306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 122462306a36Sopenharmony_ci bsr.l tag # fetch operand type 122562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 122662306a36Sopenharmony_ci mov.b %d0,%d1 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 122962306a36Sopenharmony_ci 123062306a36Sopenharmony_ci clr.l %d0 123162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci tst.b %d1 123462306a36Sopenharmony_ci bne.b _L3_2x 123562306a36Sopenharmony_ci bsr.l slognp1 # operand is a NORM 123662306a36Sopenharmony_ci bra.b _L3_6x 123762306a36Sopenharmony_ci_L3_2x: 123862306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 123962306a36Sopenharmony_ci bne.b _L3_3x # no 124062306a36Sopenharmony_ci bsr.l src_zero # yes 124162306a36Sopenharmony_ci bra.b _L3_6x 124262306a36Sopenharmony_ci_L3_3x: 124362306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 124462306a36Sopenharmony_ci bne.b _L3_4x # no 124562306a36Sopenharmony_ci bsr.l sopr_inf # yes 124662306a36Sopenharmony_ci bra.b _L3_6x 124762306a36Sopenharmony_ci_L3_4x: 124862306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 124962306a36Sopenharmony_ci bne.b _L3_5x # no 125062306a36Sopenharmony_ci bsr.l src_qnan # yes 125162306a36Sopenharmony_ci bra.b _L3_6x 125262306a36Sopenharmony_ci_L3_5x: 125362306a36Sopenharmony_ci bsr.l slognp1d # operand is a DENORM 125462306a36Sopenharmony_ci_L3_6x: 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci# 125762306a36Sopenharmony_ci# Result is now in FP0 125862306a36Sopenharmony_ci# 125962306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 126062306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 126162306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 126262306a36Sopenharmony_ci unlk %a6 126362306a36Sopenharmony_ci rts 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci######################################################################### 126762306a36Sopenharmony_ci# MONADIC TEMPLATE # 126862306a36Sopenharmony_ci######################################################################### 126962306a36Sopenharmony_ci global _fetoxm1s_ 127062306a36Sopenharmony_ci_fetoxm1s_: 127162306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 127462306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 127562306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_ci# 128062306a36Sopenharmony_ci# copy, convert, and tag input argument 128162306a36Sopenharmony_ci# 128262306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 128362306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 128462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 128562306a36Sopenharmony_ci bsr.l tag # fetch operand type 128662306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 128762306a36Sopenharmony_ci mov.b %d0,%d1 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci clr.l %d0 129262306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 129362306a36Sopenharmony_ci 129462306a36Sopenharmony_ci tst.b %d1 129562306a36Sopenharmony_ci bne.b _L4_2s 129662306a36Sopenharmony_ci bsr.l setoxm1 # operand is a NORM 129762306a36Sopenharmony_ci bra.b _L4_6s 129862306a36Sopenharmony_ci_L4_2s: 129962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 130062306a36Sopenharmony_ci bne.b _L4_3s # no 130162306a36Sopenharmony_ci bsr.l src_zero # yes 130262306a36Sopenharmony_ci bra.b _L4_6s 130362306a36Sopenharmony_ci_L4_3s: 130462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 130562306a36Sopenharmony_ci bne.b _L4_4s # no 130662306a36Sopenharmony_ci bsr.l setoxm1i # yes 130762306a36Sopenharmony_ci bra.b _L4_6s 130862306a36Sopenharmony_ci_L4_4s: 130962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 131062306a36Sopenharmony_ci bne.b _L4_5s # no 131162306a36Sopenharmony_ci bsr.l src_qnan # yes 131262306a36Sopenharmony_ci bra.b _L4_6s 131362306a36Sopenharmony_ci_L4_5s: 131462306a36Sopenharmony_ci bsr.l setoxm1d # operand is a DENORM 131562306a36Sopenharmony_ci_L4_6s: 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci# 131862306a36Sopenharmony_ci# Result is now in FP0 131962306a36Sopenharmony_ci# 132062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 132162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 132262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 132362306a36Sopenharmony_ci unlk %a6 132462306a36Sopenharmony_ci rts 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_ci global _fetoxm1d_ 132762306a36Sopenharmony_ci_fetoxm1d_: 132862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 133162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 133262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci# 133762306a36Sopenharmony_ci# copy, convert, and tag input argument 133862306a36Sopenharmony_ci# 133962306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 134062306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 134162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 134262306a36Sopenharmony_ci bsr.l tag # fetch operand type 134362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 134462306a36Sopenharmony_ci mov.b %d0,%d1 134562306a36Sopenharmony_ci 134662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci clr.l %d0 134962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 135262306a36Sopenharmony_ci tst.b %d1 135362306a36Sopenharmony_ci bne.b _L4_2d 135462306a36Sopenharmony_ci bsr.l setoxm1 # operand is a NORM 135562306a36Sopenharmony_ci bra.b _L4_6d 135662306a36Sopenharmony_ci_L4_2d: 135762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 135862306a36Sopenharmony_ci bne.b _L4_3d # no 135962306a36Sopenharmony_ci bsr.l src_zero # yes 136062306a36Sopenharmony_ci bra.b _L4_6d 136162306a36Sopenharmony_ci_L4_3d: 136262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 136362306a36Sopenharmony_ci bne.b _L4_4d # no 136462306a36Sopenharmony_ci bsr.l setoxm1i # yes 136562306a36Sopenharmony_ci bra.b _L4_6d 136662306a36Sopenharmony_ci_L4_4d: 136762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 136862306a36Sopenharmony_ci bne.b _L4_5d # no 136962306a36Sopenharmony_ci bsr.l src_qnan # yes 137062306a36Sopenharmony_ci bra.b _L4_6d 137162306a36Sopenharmony_ci_L4_5d: 137262306a36Sopenharmony_ci bsr.l setoxm1d # operand is a DENORM 137362306a36Sopenharmony_ci_L4_6d: 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci# 137662306a36Sopenharmony_ci# Result is now in FP0 137762306a36Sopenharmony_ci# 137862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 137962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 138062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 138162306a36Sopenharmony_ci unlk %a6 138262306a36Sopenharmony_ci rts 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci global _fetoxm1x_ 138562306a36Sopenharmony_ci_fetoxm1x_: 138662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 138962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 139062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci# 139562306a36Sopenharmony_ci# copy, convert, and tag input argument 139662306a36Sopenharmony_ci# 139762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 139862306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 139962306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 140062306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 140162306a36Sopenharmony_ci bsr.l tag # fetch operand type 140262306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 140362306a36Sopenharmony_ci mov.b %d0,%d1 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci clr.l %d0 140862306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 140962306a36Sopenharmony_ci 141062306a36Sopenharmony_ci tst.b %d1 141162306a36Sopenharmony_ci bne.b _L4_2x 141262306a36Sopenharmony_ci bsr.l setoxm1 # operand is a NORM 141362306a36Sopenharmony_ci bra.b _L4_6x 141462306a36Sopenharmony_ci_L4_2x: 141562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 141662306a36Sopenharmony_ci bne.b _L4_3x # no 141762306a36Sopenharmony_ci bsr.l src_zero # yes 141862306a36Sopenharmony_ci bra.b _L4_6x 141962306a36Sopenharmony_ci_L4_3x: 142062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 142162306a36Sopenharmony_ci bne.b _L4_4x # no 142262306a36Sopenharmony_ci bsr.l setoxm1i # yes 142362306a36Sopenharmony_ci bra.b _L4_6x 142462306a36Sopenharmony_ci_L4_4x: 142562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 142662306a36Sopenharmony_ci bne.b _L4_5x # no 142762306a36Sopenharmony_ci bsr.l src_qnan # yes 142862306a36Sopenharmony_ci bra.b _L4_6x 142962306a36Sopenharmony_ci_L4_5x: 143062306a36Sopenharmony_ci bsr.l setoxm1d # operand is a DENORM 143162306a36Sopenharmony_ci_L4_6x: 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci# 143462306a36Sopenharmony_ci# Result is now in FP0 143562306a36Sopenharmony_ci# 143662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 143762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 143862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 143962306a36Sopenharmony_ci unlk %a6 144062306a36Sopenharmony_ci rts 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci######################################################################### 144462306a36Sopenharmony_ci# MONADIC TEMPLATE # 144562306a36Sopenharmony_ci######################################################################### 144662306a36Sopenharmony_ci global _ftanhs_ 144762306a36Sopenharmony_ci_ftanhs_: 144862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 145162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 145262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_ci# 145762306a36Sopenharmony_ci# copy, convert, and tag input argument 145862306a36Sopenharmony_ci# 145962306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 146062306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 146162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 146262306a36Sopenharmony_ci bsr.l tag # fetch operand type 146362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 146462306a36Sopenharmony_ci mov.b %d0,%d1 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci clr.l %d0 146962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci tst.b %d1 147262306a36Sopenharmony_ci bne.b _L5_2s 147362306a36Sopenharmony_ci bsr.l stanh # operand is a NORM 147462306a36Sopenharmony_ci bra.b _L5_6s 147562306a36Sopenharmony_ci_L5_2s: 147662306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 147762306a36Sopenharmony_ci bne.b _L5_3s # no 147862306a36Sopenharmony_ci bsr.l src_zero # yes 147962306a36Sopenharmony_ci bra.b _L5_6s 148062306a36Sopenharmony_ci_L5_3s: 148162306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 148262306a36Sopenharmony_ci bne.b _L5_4s # no 148362306a36Sopenharmony_ci bsr.l src_one # yes 148462306a36Sopenharmony_ci bra.b _L5_6s 148562306a36Sopenharmony_ci_L5_4s: 148662306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 148762306a36Sopenharmony_ci bne.b _L5_5s # no 148862306a36Sopenharmony_ci bsr.l src_qnan # yes 148962306a36Sopenharmony_ci bra.b _L5_6s 149062306a36Sopenharmony_ci_L5_5s: 149162306a36Sopenharmony_ci bsr.l stanhd # operand is a DENORM 149262306a36Sopenharmony_ci_L5_6s: 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci# 149562306a36Sopenharmony_ci# Result is now in FP0 149662306a36Sopenharmony_ci# 149762306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 149862306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 149962306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 150062306a36Sopenharmony_ci unlk %a6 150162306a36Sopenharmony_ci rts 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci global _ftanhd_ 150462306a36Sopenharmony_ci_ftanhd_: 150562306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 150862306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 150962306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci# 151462306a36Sopenharmony_ci# copy, convert, and tag input argument 151562306a36Sopenharmony_ci# 151662306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 151762306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 151862306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 151962306a36Sopenharmony_ci bsr.l tag # fetch operand type 152062306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 152162306a36Sopenharmony_ci mov.b %d0,%d1 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci clr.l %d0 152662306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 152962306a36Sopenharmony_ci tst.b %d1 153062306a36Sopenharmony_ci bne.b _L5_2d 153162306a36Sopenharmony_ci bsr.l stanh # operand is a NORM 153262306a36Sopenharmony_ci bra.b _L5_6d 153362306a36Sopenharmony_ci_L5_2d: 153462306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 153562306a36Sopenharmony_ci bne.b _L5_3d # no 153662306a36Sopenharmony_ci bsr.l src_zero # yes 153762306a36Sopenharmony_ci bra.b _L5_6d 153862306a36Sopenharmony_ci_L5_3d: 153962306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 154062306a36Sopenharmony_ci bne.b _L5_4d # no 154162306a36Sopenharmony_ci bsr.l src_one # yes 154262306a36Sopenharmony_ci bra.b _L5_6d 154362306a36Sopenharmony_ci_L5_4d: 154462306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 154562306a36Sopenharmony_ci bne.b _L5_5d # no 154662306a36Sopenharmony_ci bsr.l src_qnan # yes 154762306a36Sopenharmony_ci bra.b _L5_6d 154862306a36Sopenharmony_ci_L5_5d: 154962306a36Sopenharmony_ci bsr.l stanhd # operand is a DENORM 155062306a36Sopenharmony_ci_L5_6d: 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci# 155362306a36Sopenharmony_ci# Result is now in FP0 155462306a36Sopenharmony_ci# 155562306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 155662306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 155762306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 155862306a36Sopenharmony_ci unlk %a6 155962306a36Sopenharmony_ci rts 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci global _ftanhx_ 156262306a36Sopenharmony_ci_ftanhx_: 156362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 156662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 156762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci# 157262306a36Sopenharmony_ci# copy, convert, and tag input argument 157362306a36Sopenharmony_ci# 157462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 157562306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 157662306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 157762306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 157862306a36Sopenharmony_ci bsr.l tag # fetch operand type 157962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 158062306a36Sopenharmony_ci mov.b %d0,%d1 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci clr.l %d0 158562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci tst.b %d1 158862306a36Sopenharmony_ci bne.b _L5_2x 158962306a36Sopenharmony_ci bsr.l stanh # operand is a NORM 159062306a36Sopenharmony_ci bra.b _L5_6x 159162306a36Sopenharmony_ci_L5_2x: 159262306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 159362306a36Sopenharmony_ci bne.b _L5_3x # no 159462306a36Sopenharmony_ci bsr.l src_zero # yes 159562306a36Sopenharmony_ci bra.b _L5_6x 159662306a36Sopenharmony_ci_L5_3x: 159762306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 159862306a36Sopenharmony_ci bne.b _L5_4x # no 159962306a36Sopenharmony_ci bsr.l src_one # yes 160062306a36Sopenharmony_ci bra.b _L5_6x 160162306a36Sopenharmony_ci_L5_4x: 160262306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 160362306a36Sopenharmony_ci bne.b _L5_5x # no 160462306a36Sopenharmony_ci bsr.l src_qnan # yes 160562306a36Sopenharmony_ci bra.b _L5_6x 160662306a36Sopenharmony_ci_L5_5x: 160762306a36Sopenharmony_ci bsr.l stanhd # operand is a DENORM 160862306a36Sopenharmony_ci_L5_6x: 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci# 161162306a36Sopenharmony_ci# Result is now in FP0 161262306a36Sopenharmony_ci# 161362306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 161462306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 161562306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 161662306a36Sopenharmony_ci unlk %a6 161762306a36Sopenharmony_ci rts 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_ci######################################################################### 162162306a36Sopenharmony_ci# MONADIC TEMPLATE # 162262306a36Sopenharmony_ci######################################################################### 162362306a36Sopenharmony_ci global _fatans_ 162462306a36Sopenharmony_ci_fatans_: 162562306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 162862306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 162962306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci# 163462306a36Sopenharmony_ci# copy, convert, and tag input argument 163562306a36Sopenharmony_ci# 163662306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 163762306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 163862306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 163962306a36Sopenharmony_ci bsr.l tag # fetch operand type 164062306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 164162306a36Sopenharmony_ci mov.b %d0,%d1 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci clr.l %d0 164662306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci tst.b %d1 164962306a36Sopenharmony_ci bne.b _L6_2s 165062306a36Sopenharmony_ci bsr.l satan # operand is a NORM 165162306a36Sopenharmony_ci bra.b _L6_6s 165262306a36Sopenharmony_ci_L6_2s: 165362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 165462306a36Sopenharmony_ci bne.b _L6_3s # no 165562306a36Sopenharmony_ci bsr.l src_zero # yes 165662306a36Sopenharmony_ci bra.b _L6_6s 165762306a36Sopenharmony_ci_L6_3s: 165862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 165962306a36Sopenharmony_ci bne.b _L6_4s # no 166062306a36Sopenharmony_ci bsr.l spi_2 # yes 166162306a36Sopenharmony_ci bra.b _L6_6s 166262306a36Sopenharmony_ci_L6_4s: 166362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 166462306a36Sopenharmony_ci bne.b _L6_5s # no 166562306a36Sopenharmony_ci bsr.l src_qnan # yes 166662306a36Sopenharmony_ci bra.b _L6_6s 166762306a36Sopenharmony_ci_L6_5s: 166862306a36Sopenharmony_ci bsr.l satand # operand is a DENORM 166962306a36Sopenharmony_ci_L6_6s: 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci# 167262306a36Sopenharmony_ci# Result is now in FP0 167362306a36Sopenharmony_ci# 167462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 167562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 167662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 167762306a36Sopenharmony_ci unlk %a6 167862306a36Sopenharmony_ci rts 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci global _fatand_ 168162306a36Sopenharmony_ci_fatand_: 168262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 168562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 168662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 168962306a36Sopenharmony_ci 169062306a36Sopenharmony_ci# 169162306a36Sopenharmony_ci# copy, convert, and tag input argument 169262306a36Sopenharmony_ci# 169362306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 169462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 169562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 169662306a36Sopenharmony_ci bsr.l tag # fetch operand type 169762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 169862306a36Sopenharmony_ci mov.b %d0,%d1 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 170162306a36Sopenharmony_ci 170262306a36Sopenharmony_ci clr.l %d0 170362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 170662306a36Sopenharmony_ci tst.b %d1 170762306a36Sopenharmony_ci bne.b _L6_2d 170862306a36Sopenharmony_ci bsr.l satan # operand is a NORM 170962306a36Sopenharmony_ci bra.b _L6_6d 171062306a36Sopenharmony_ci_L6_2d: 171162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 171262306a36Sopenharmony_ci bne.b _L6_3d # no 171362306a36Sopenharmony_ci bsr.l src_zero # yes 171462306a36Sopenharmony_ci bra.b _L6_6d 171562306a36Sopenharmony_ci_L6_3d: 171662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 171762306a36Sopenharmony_ci bne.b _L6_4d # no 171862306a36Sopenharmony_ci bsr.l spi_2 # yes 171962306a36Sopenharmony_ci bra.b _L6_6d 172062306a36Sopenharmony_ci_L6_4d: 172162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 172262306a36Sopenharmony_ci bne.b _L6_5d # no 172362306a36Sopenharmony_ci bsr.l src_qnan # yes 172462306a36Sopenharmony_ci bra.b _L6_6d 172562306a36Sopenharmony_ci_L6_5d: 172662306a36Sopenharmony_ci bsr.l satand # operand is a DENORM 172762306a36Sopenharmony_ci_L6_6d: 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci# 173062306a36Sopenharmony_ci# Result is now in FP0 173162306a36Sopenharmony_ci# 173262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 173362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 173462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 173562306a36Sopenharmony_ci unlk %a6 173662306a36Sopenharmony_ci rts 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci global _fatanx_ 173962306a36Sopenharmony_ci_fatanx_: 174062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 174162306a36Sopenharmony_ci 174262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 174362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 174462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci# 174962306a36Sopenharmony_ci# copy, convert, and tag input argument 175062306a36Sopenharmony_ci# 175162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 175262306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 175362306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 175462306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 175562306a36Sopenharmony_ci bsr.l tag # fetch operand type 175662306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 175762306a36Sopenharmony_ci mov.b %d0,%d1 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_ci clr.l %d0 176262306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci tst.b %d1 176562306a36Sopenharmony_ci bne.b _L6_2x 176662306a36Sopenharmony_ci bsr.l satan # operand is a NORM 176762306a36Sopenharmony_ci bra.b _L6_6x 176862306a36Sopenharmony_ci_L6_2x: 176962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 177062306a36Sopenharmony_ci bne.b _L6_3x # no 177162306a36Sopenharmony_ci bsr.l src_zero # yes 177262306a36Sopenharmony_ci bra.b _L6_6x 177362306a36Sopenharmony_ci_L6_3x: 177462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 177562306a36Sopenharmony_ci bne.b _L6_4x # no 177662306a36Sopenharmony_ci bsr.l spi_2 # yes 177762306a36Sopenharmony_ci bra.b _L6_6x 177862306a36Sopenharmony_ci_L6_4x: 177962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 178062306a36Sopenharmony_ci bne.b _L6_5x # no 178162306a36Sopenharmony_ci bsr.l src_qnan # yes 178262306a36Sopenharmony_ci bra.b _L6_6x 178362306a36Sopenharmony_ci_L6_5x: 178462306a36Sopenharmony_ci bsr.l satand # operand is a DENORM 178562306a36Sopenharmony_ci_L6_6x: 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci# 178862306a36Sopenharmony_ci# Result is now in FP0 178962306a36Sopenharmony_ci# 179062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 179162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 179262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 179362306a36Sopenharmony_ci unlk %a6 179462306a36Sopenharmony_ci rts 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci######################################################################### 179862306a36Sopenharmony_ci# MONADIC TEMPLATE # 179962306a36Sopenharmony_ci######################################################################### 180062306a36Sopenharmony_ci global _fasins_ 180162306a36Sopenharmony_ci_fasins_: 180262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 180562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 180662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 180762306a36Sopenharmony_ci 180862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 180962306a36Sopenharmony_ci 181062306a36Sopenharmony_ci# 181162306a36Sopenharmony_ci# copy, convert, and tag input argument 181262306a36Sopenharmony_ci# 181362306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 181462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 181562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 181662306a36Sopenharmony_ci bsr.l tag # fetch operand type 181762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 181862306a36Sopenharmony_ci mov.b %d0,%d1 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 182162306a36Sopenharmony_ci 182262306a36Sopenharmony_ci clr.l %d0 182362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci tst.b %d1 182662306a36Sopenharmony_ci bne.b _L7_2s 182762306a36Sopenharmony_ci bsr.l sasin # operand is a NORM 182862306a36Sopenharmony_ci bra.b _L7_6s 182962306a36Sopenharmony_ci_L7_2s: 183062306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 183162306a36Sopenharmony_ci bne.b _L7_3s # no 183262306a36Sopenharmony_ci bsr.l src_zero # yes 183362306a36Sopenharmony_ci bra.b _L7_6s 183462306a36Sopenharmony_ci_L7_3s: 183562306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 183662306a36Sopenharmony_ci bne.b _L7_4s # no 183762306a36Sopenharmony_ci bsr.l t_operr # yes 183862306a36Sopenharmony_ci bra.b _L7_6s 183962306a36Sopenharmony_ci_L7_4s: 184062306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 184162306a36Sopenharmony_ci bne.b _L7_5s # no 184262306a36Sopenharmony_ci bsr.l src_qnan # yes 184362306a36Sopenharmony_ci bra.b _L7_6s 184462306a36Sopenharmony_ci_L7_5s: 184562306a36Sopenharmony_ci bsr.l sasind # operand is a DENORM 184662306a36Sopenharmony_ci_L7_6s: 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_ci# 184962306a36Sopenharmony_ci# Result is now in FP0 185062306a36Sopenharmony_ci# 185162306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 185262306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 185362306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 185462306a36Sopenharmony_ci unlk %a6 185562306a36Sopenharmony_ci rts 185662306a36Sopenharmony_ci 185762306a36Sopenharmony_ci global _fasind_ 185862306a36Sopenharmony_ci_fasind_: 185962306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 186262306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 186362306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 186462306a36Sopenharmony_ci 186562306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci# 186862306a36Sopenharmony_ci# copy, convert, and tag input argument 186962306a36Sopenharmony_ci# 187062306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 187162306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 187262306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 187362306a36Sopenharmony_ci bsr.l tag # fetch operand type 187462306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 187562306a36Sopenharmony_ci mov.b %d0,%d1 187662306a36Sopenharmony_ci 187762306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 187862306a36Sopenharmony_ci 187962306a36Sopenharmony_ci clr.l %d0 188062306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 188162306a36Sopenharmony_ci 188262306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 188362306a36Sopenharmony_ci tst.b %d1 188462306a36Sopenharmony_ci bne.b _L7_2d 188562306a36Sopenharmony_ci bsr.l sasin # operand is a NORM 188662306a36Sopenharmony_ci bra.b _L7_6d 188762306a36Sopenharmony_ci_L7_2d: 188862306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 188962306a36Sopenharmony_ci bne.b _L7_3d # no 189062306a36Sopenharmony_ci bsr.l src_zero # yes 189162306a36Sopenharmony_ci bra.b _L7_6d 189262306a36Sopenharmony_ci_L7_3d: 189362306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 189462306a36Sopenharmony_ci bne.b _L7_4d # no 189562306a36Sopenharmony_ci bsr.l t_operr # yes 189662306a36Sopenharmony_ci bra.b _L7_6d 189762306a36Sopenharmony_ci_L7_4d: 189862306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 189962306a36Sopenharmony_ci bne.b _L7_5d # no 190062306a36Sopenharmony_ci bsr.l src_qnan # yes 190162306a36Sopenharmony_ci bra.b _L7_6d 190262306a36Sopenharmony_ci_L7_5d: 190362306a36Sopenharmony_ci bsr.l sasind # operand is a DENORM 190462306a36Sopenharmony_ci_L7_6d: 190562306a36Sopenharmony_ci 190662306a36Sopenharmony_ci# 190762306a36Sopenharmony_ci# Result is now in FP0 190862306a36Sopenharmony_ci# 190962306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 191062306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 191162306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 191262306a36Sopenharmony_ci unlk %a6 191362306a36Sopenharmony_ci rts 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_ci global _fasinx_ 191662306a36Sopenharmony_ci_fasinx_: 191762306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 192062306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 192162306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 192262306a36Sopenharmony_ci 192362306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_ci# 192662306a36Sopenharmony_ci# copy, convert, and tag input argument 192762306a36Sopenharmony_ci# 192862306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 192962306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 193062306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 193162306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 193262306a36Sopenharmony_ci bsr.l tag # fetch operand type 193362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 193462306a36Sopenharmony_ci mov.b %d0,%d1 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 193762306a36Sopenharmony_ci 193862306a36Sopenharmony_ci clr.l %d0 193962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 194062306a36Sopenharmony_ci 194162306a36Sopenharmony_ci tst.b %d1 194262306a36Sopenharmony_ci bne.b _L7_2x 194362306a36Sopenharmony_ci bsr.l sasin # operand is a NORM 194462306a36Sopenharmony_ci bra.b _L7_6x 194562306a36Sopenharmony_ci_L7_2x: 194662306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 194762306a36Sopenharmony_ci bne.b _L7_3x # no 194862306a36Sopenharmony_ci bsr.l src_zero # yes 194962306a36Sopenharmony_ci bra.b _L7_6x 195062306a36Sopenharmony_ci_L7_3x: 195162306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 195262306a36Sopenharmony_ci bne.b _L7_4x # no 195362306a36Sopenharmony_ci bsr.l t_operr # yes 195462306a36Sopenharmony_ci bra.b _L7_6x 195562306a36Sopenharmony_ci_L7_4x: 195662306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 195762306a36Sopenharmony_ci bne.b _L7_5x # no 195862306a36Sopenharmony_ci bsr.l src_qnan # yes 195962306a36Sopenharmony_ci bra.b _L7_6x 196062306a36Sopenharmony_ci_L7_5x: 196162306a36Sopenharmony_ci bsr.l sasind # operand is a DENORM 196262306a36Sopenharmony_ci_L7_6x: 196362306a36Sopenharmony_ci 196462306a36Sopenharmony_ci# 196562306a36Sopenharmony_ci# Result is now in FP0 196662306a36Sopenharmony_ci# 196762306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 196862306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 196962306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 197062306a36Sopenharmony_ci unlk %a6 197162306a36Sopenharmony_ci rts 197262306a36Sopenharmony_ci 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_ci######################################################################### 197562306a36Sopenharmony_ci# MONADIC TEMPLATE # 197662306a36Sopenharmony_ci######################################################################### 197762306a36Sopenharmony_ci global _fatanhs_ 197862306a36Sopenharmony_ci_fatanhs_: 197962306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 198262306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 198362306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ci# 198862306a36Sopenharmony_ci# copy, convert, and tag input argument 198962306a36Sopenharmony_ci# 199062306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 199162306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 199262306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 199362306a36Sopenharmony_ci bsr.l tag # fetch operand type 199462306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 199562306a36Sopenharmony_ci mov.b %d0,%d1 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 199862306a36Sopenharmony_ci 199962306a36Sopenharmony_ci clr.l %d0 200062306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 200162306a36Sopenharmony_ci 200262306a36Sopenharmony_ci tst.b %d1 200362306a36Sopenharmony_ci bne.b _L8_2s 200462306a36Sopenharmony_ci bsr.l satanh # operand is a NORM 200562306a36Sopenharmony_ci bra.b _L8_6s 200662306a36Sopenharmony_ci_L8_2s: 200762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 200862306a36Sopenharmony_ci bne.b _L8_3s # no 200962306a36Sopenharmony_ci bsr.l src_zero # yes 201062306a36Sopenharmony_ci bra.b _L8_6s 201162306a36Sopenharmony_ci_L8_3s: 201262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 201362306a36Sopenharmony_ci bne.b _L8_4s # no 201462306a36Sopenharmony_ci bsr.l t_operr # yes 201562306a36Sopenharmony_ci bra.b _L8_6s 201662306a36Sopenharmony_ci_L8_4s: 201762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 201862306a36Sopenharmony_ci bne.b _L8_5s # no 201962306a36Sopenharmony_ci bsr.l src_qnan # yes 202062306a36Sopenharmony_ci bra.b _L8_6s 202162306a36Sopenharmony_ci_L8_5s: 202262306a36Sopenharmony_ci bsr.l satanhd # operand is a DENORM 202362306a36Sopenharmony_ci_L8_6s: 202462306a36Sopenharmony_ci 202562306a36Sopenharmony_ci# 202662306a36Sopenharmony_ci# Result is now in FP0 202762306a36Sopenharmony_ci# 202862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 202962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 203062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 203162306a36Sopenharmony_ci unlk %a6 203262306a36Sopenharmony_ci rts 203362306a36Sopenharmony_ci 203462306a36Sopenharmony_ci global _fatanhd_ 203562306a36Sopenharmony_ci_fatanhd_: 203662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 203762306a36Sopenharmony_ci 203862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 203962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 204062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 204162306a36Sopenharmony_ci 204262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 204362306a36Sopenharmony_ci 204462306a36Sopenharmony_ci# 204562306a36Sopenharmony_ci# copy, convert, and tag input argument 204662306a36Sopenharmony_ci# 204762306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 204862306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 204962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 205062306a36Sopenharmony_ci bsr.l tag # fetch operand type 205162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 205262306a36Sopenharmony_ci mov.b %d0,%d1 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 205562306a36Sopenharmony_ci 205662306a36Sopenharmony_ci clr.l %d0 205762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 206062306a36Sopenharmony_ci tst.b %d1 206162306a36Sopenharmony_ci bne.b _L8_2d 206262306a36Sopenharmony_ci bsr.l satanh # operand is a NORM 206362306a36Sopenharmony_ci bra.b _L8_6d 206462306a36Sopenharmony_ci_L8_2d: 206562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 206662306a36Sopenharmony_ci bne.b _L8_3d # no 206762306a36Sopenharmony_ci bsr.l src_zero # yes 206862306a36Sopenharmony_ci bra.b _L8_6d 206962306a36Sopenharmony_ci_L8_3d: 207062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 207162306a36Sopenharmony_ci bne.b _L8_4d # no 207262306a36Sopenharmony_ci bsr.l t_operr # yes 207362306a36Sopenharmony_ci bra.b _L8_6d 207462306a36Sopenharmony_ci_L8_4d: 207562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 207662306a36Sopenharmony_ci bne.b _L8_5d # no 207762306a36Sopenharmony_ci bsr.l src_qnan # yes 207862306a36Sopenharmony_ci bra.b _L8_6d 207962306a36Sopenharmony_ci_L8_5d: 208062306a36Sopenharmony_ci bsr.l satanhd # operand is a DENORM 208162306a36Sopenharmony_ci_L8_6d: 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci# 208462306a36Sopenharmony_ci# Result is now in FP0 208562306a36Sopenharmony_ci# 208662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 208762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 208862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 208962306a36Sopenharmony_ci unlk %a6 209062306a36Sopenharmony_ci rts 209162306a36Sopenharmony_ci 209262306a36Sopenharmony_ci global _fatanhx_ 209362306a36Sopenharmony_ci_fatanhx_: 209462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 209762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 209862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 210162306a36Sopenharmony_ci 210262306a36Sopenharmony_ci# 210362306a36Sopenharmony_ci# copy, convert, and tag input argument 210462306a36Sopenharmony_ci# 210562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 210662306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 210762306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 210862306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 210962306a36Sopenharmony_ci bsr.l tag # fetch operand type 211062306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 211162306a36Sopenharmony_ci mov.b %d0,%d1 211262306a36Sopenharmony_ci 211362306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 211462306a36Sopenharmony_ci 211562306a36Sopenharmony_ci clr.l %d0 211662306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 211762306a36Sopenharmony_ci 211862306a36Sopenharmony_ci tst.b %d1 211962306a36Sopenharmony_ci bne.b _L8_2x 212062306a36Sopenharmony_ci bsr.l satanh # operand is a NORM 212162306a36Sopenharmony_ci bra.b _L8_6x 212262306a36Sopenharmony_ci_L8_2x: 212362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 212462306a36Sopenharmony_ci bne.b _L8_3x # no 212562306a36Sopenharmony_ci bsr.l src_zero # yes 212662306a36Sopenharmony_ci bra.b _L8_6x 212762306a36Sopenharmony_ci_L8_3x: 212862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 212962306a36Sopenharmony_ci bne.b _L8_4x # no 213062306a36Sopenharmony_ci bsr.l t_operr # yes 213162306a36Sopenharmony_ci bra.b _L8_6x 213262306a36Sopenharmony_ci_L8_4x: 213362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 213462306a36Sopenharmony_ci bne.b _L8_5x # no 213562306a36Sopenharmony_ci bsr.l src_qnan # yes 213662306a36Sopenharmony_ci bra.b _L8_6x 213762306a36Sopenharmony_ci_L8_5x: 213862306a36Sopenharmony_ci bsr.l satanhd # operand is a DENORM 213962306a36Sopenharmony_ci_L8_6x: 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci# 214262306a36Sopenharmony_ci# Result is now in FP0 214362306a36Sopenharmony_ci# 214462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 214562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 214662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 214762306a36Sopenharmony_ci unlk %a6 214862306a36Sopenharmony_ci rts 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci 215162306a36Sopenharmony_ci######################################################################### 215262306a36Sopenharmony_ci# MONADIC TEMPLATE # 215362306a36Sopenharmony_ci######################################################################### 215462306a36Sopenharmony_ci global _ftans_ 215562306a36Sopenharmony_ci_ftans_: 215662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 215762306a36Sopenharmony_ci 215862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 215962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 216062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 216362306a36Sopenharmony_ci 216462306a36Sopenharmony_ci# 216562306a36Sopenharmony_ci# copy, convert, and tag input argument 216662306a36Sopenharmony_ci# 216762306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 216862306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 216962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 217062306a36Sopenharmony_ci bsr.l tag # fetch operand type 217162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 217262306a36Sopenharmony_ci mov.b %d0,%d1 217362306a36Sopenharmony_ci 217462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 217562306a36Sopenharmony_ci 217662306a36Sopenharmony_ci clr.l %d0 217762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 217862306a36Sopenharmony_ci 217962306a36Sopenharmony_ci tst.b %d1 218062306a36Sopenharmony_ci bne.b _L9_2s 218162306a36Sopenharmony_ci bsr.l stan # operand is a NORM 218262306a36Sopenharmony_ci bra.b _L9_6s 218362306a36Sopenharmony_ci_L9_2s: 218462306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 218562306a36Sopenharmony_ci bne.b _L9_3s # no 218662306a36Sopenharmony_ci bsr.l src_zero # yes 218762306a36Sopenharmony_ci bra.b _L9_6s 218862306a36Sopenharmony_ci_L9_3s: 218962306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 219062306a36Sopenharmony_ci bne.b _L9_4s # no 219162306a36Sopenharmony_ci bsr.l t_operr # yes 219262306a36Sopenharmony_ci bra.b _L9_6s 219362306a36Sopenharmony_ci_L9_4s: 219462306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 219562306a36Sopenharmony_ci bne.b _L9_5s # no 219662306a36Sopenharmony_ci bsr.l src_qnan # yes 219762306a36Sopenharmony_ci bra.b _L9_6s 219862306a36Sopenharmony_ci_L9_5s: 219962306a36Sopenharmony_ci bsr.l stand # operand is a DENORM 220062306a36Sopenharmony_ci_L9_6s: 220162306a36Sopenharmony_ci 220262306a36Sopenharmony_ci# 220362306a36Sopenharmony_ci# Result is now in FP0 220462306a36Sopenharmony_ci# 220562306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 220662306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 220762306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 220862306a36Sopenharmony_ci unlk %a6 220962306a36Sopenharmony_ci rts 221062306a36Sopenharmony_ci 221162306a36Sopenharmony_ci global _ftand_ 221262306a36Sopenharmony_ci_ftand_: 221362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 221462306a36Sopenharmony_ci 221562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 221662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 221762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci# 222262306a36Sopenharmony_ci# copy, convert, and tag input argument 222362306a36Sopenharmony_ci# 222462306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 222562306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 222662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 222762306a36Sopenharmony_ci bsr.l tag # fetch operand type 222862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 222962306a36Sopenharmony_ci mov.b %d0,%d1 223062306a36Sopenharmony_ci 223162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 223262306a36Sopenharmony_ci 223362306a36Sopenharmony_ci clr.l %d0 223462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 223562306a36Sopenharmony_ci 223662306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 223762306a36Sopenharmony_ci tst.b %d1 223862306a36Sopenharmony_ci bne.b _L9_2d 223962306a36Sopenharmony_ci bsr.l stan # operand is a NORM 224062306a36Sopenharmony_ci bra.b _L9_6d 224162306a36Sopenharmony_ci_L9_2d: 224262306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 224362306a36Sopenharmony_ci bne.b _L9_3d # no 224462306a36Sopenharmony_ci bsr.l src_zero # yes 224562306a36Sopenharmony_ci bra.b _L9_6d 224662306a36Sopenharmony_ci_L9_3d: 224762306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 224862306a36Sopenharmony_ci bne.b _L9_4d # no 224962306a36Sopenharmony_ci bsr.l t_operr # yes 225062306a36Sopenharmony_ci bra.b _L9_6d 225162306a36Sopenharmony_ci_L9_4d: 225262306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 225362306a36Sopenharmony_ci bne.b _L9_5d # no 225462306a36Sopenharmony_ci bsr.l src_qnan # yes 225562306a36Sopenharmony_ci bra.b _L9_6d 225662306a36Sopenharmony_ci_L9_5d: 225762306a36Sopenharmony_ci bsr.l stand # operand is a DENORM 225862306a36Sopenharmony_ci_L9_6d: 225962306a36Sopenharmony_ci 226062306a36Sopenharmony_ci# 226162306a36Sopenharmony_ci# Result is now in FP0 226262306a36Sopenharmony_ci# 226362306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 226462306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 226562306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 226662306a36Sopenharmony_ci unlk %a6 226762306a36Sopenharmony_ci rts 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_ci global _ftanx_ 227062306a36Sopenharmony_ci_ftanx_: 227162306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 227262306a36Sopenharmony_ci 227362306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 227462306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 227562306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 227862306a36Sopenharmony_ci 227962306a36Sopenharmony_ci# 228062306a36Sopenharmony_ci# copy, convert, and tag input argument 228162306a36Sopenharmony_ci# 228262306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 228362306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 228462306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 228562306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 228662306a36Sopenharmony_ci bsr.l tag # fetch operand type 228762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 228862306a36Sopenharmony_ci mov.b %d0,%d1 228962306a36Sopenharmony_ci 229062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 229162306a36Sopenharmony_ci 229262306a36Sopenharmony_ci clr.l %d0 229362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 229462306a36Sopenharmony_ci 229562306a36Sopenharmony_ci tst.b %d1 229662306a36Sopenharmony_ci bne.b _L9_2x 229762306a36Sopenharmony_ci bsr.l stan # operand is a NORM 229862306a36Sopenharmony_ci bra.b _L9_6x 229962306a36Sopenharmony_ci_L9_2x: 230062306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 230162306a36Sopenharmony_ci bne.b _L9_3x # no 230262306a36Sopenharmony_ci bsr.l src_zero # yes 230362306a36Sopenharmony_ci bra.b _L9_6x 230462306a36Sopenharmony_ci_L9_3x: 230562306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 230662306a36Sopenharmony_ci bne.b _L9_4x # no 230762306a36Sopenharmony_ci bsr.l t_operr # yes 230862306a36Sopenharmony_ci bra.b _L9_6x 230962306a36Sopenharmony_ci_L9_4x: 231062306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 231162306a36Sopenharmony_ci bne.b _L9_5x # no 231262306a36Sopenharmony_ci bsr.l src_qnan # yes 231362306a36Sopenharmony_ci bra.b _L9_6x 231462306a36Sopenharmony_ci_L9_5x: 231562306a36Sopenharmony_ci bsr.l stand # operand is a DENORM 231662306a36Sopenharmony_ci_L9_6x: 231762306a36Sopenharmony_ci 231862306a36Sopenharmony_ci# 231962306a36Sopenharmony_ci# Result is now in FP0 232062306a36Sopenharmony_ci# 232162306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 232262306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 232362306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 232462306a36Sopenharmony_ci unlk %a6 232562306a36Sopenharmony_ci rts 232662306a36Sopenharmony_ci 232762306a36Sopenharmony_ci 232862306a36Sopenharmony_ci######################################################################### 232962306a36Sopenharmony_ci# MONADIC TEMPLATE # 233062306a36Sopenharmony_ci######################################################################### 233162306a36Sopenharmony_ci global _fetoxs_ 233262306a36Sopenharmony_ci_fetoxs_: 233362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 233662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 233762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 233862306a36Sopenharmony_ci 233962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 234062306a36Sopenharmony_ci 234162306a36Sopenharmony_ci# 234262306a36Sopenharmony_ci# copy, convert, and tag input argument 234362306a36Sopenharmony_ci# 234462306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 234562306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 234662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 234762306a36Sopenharmony_ci bsr.l tag # fetch operand type 234862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 234962306a36Sopenharmony_ci mov.b %d0,%d1 235062306a36Sopenharmony_ci 235162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 235262306a36Sopenharmony_ci 235362306a36Sopenharmony_ci clr.l %d0 235462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 235562306a36Sopenharmony_ci 235662306a36Sopenharmony_ci tst.b %d1 235762306a36Sopenharmony_ci bne.b _L10_2s 235862306a36Sopenharmony_ci bsr.l setox # operand is a NORM 235962306a36Sopenharmony_ci bra.b _L10_6s 236062306a36Sopenharmony_ci_L10_2s: 236162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 236262306a36Sopenharmony_ci bne.b _L10_3s # no 236362306a36Sopenharmony_ci bsr.l ld_pone # yes 236462306a36Sopenharmony_ci bra.b _L10_6s 236562306a36Sopenharmony_ci_L10_3s: 236662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 236762306a36Sopenharmony_ci bne.b _L10_4s # no 236862306a36Sopenharmony_ci bsr.l szr_inf # yes 236962306a36Sopenharmony_ci bra.b _L10_6s 237062306a36Sopenharmony_ci_L10_4s: 237162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 237262306a36Sopenharmony_ci bne.b _L10_5s # no 237362306a36Sopenharmony_ci bsr.l src_qnan # yes 237462306a36Sopenharmony_ci bra.b _L10_6s 237562306a36Sopenharmony_ci_L10_5s: 237662306a36Sopenharmony_ci bsr.l setoxd # operand is a DENORM 237762306a36Sopenharmony_ci_L10_6s: 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci# 238062306a36Sopenharmony_ci# Result is now in FP0 238162306a36Sopenharmony_ci# 238262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 238362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 238462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 238562306a36Sopenharmony_ci unlk %a6 238662306a36Sopenharmony_ci rts 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_ci global _fetoxd_ 238962306a36Sopenharmony_ci_fetoxd_: 239062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 239162306a36Sopenharmony_ci 239262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 239362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 239462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 239562306a36Sopenharmony_ci 239662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 239762306a36Sopenharmony_ci 239862306a36Sopenharmony_ci# 239962306a36Sopenharmony_ci# copy, convert, and tag input argument 240062306a36Sopenharmony_ci# 240162306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 240262306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 240362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 240462306a36Sopenharmony_ci bsr.l tag # fetch operand type 240562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 240662306a36Sopenharmony_ci mov.b %d0,%d1 240762306a36Sopenharmony_ci 240862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 240962306a36Sopenharmony_ci 241062306a36Sopenharmony_ci clr.l %d0 241162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 241262306a36Sopenharmony_ci 241362306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 241462306a36Sopenharmony_ci tst.b %d1 241562306a36Sopenharmony_ci bne.b _L10_2d 241662306a36Sopenharmony_ci bsr.l setox # operand is a NORM 241762306a36Sopenharmony_ci bra.b _L10_6d 241862306a36Sopenharmony_ci_L10_2d: 241962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 242062306a36Sopenharmony_ci bne.b _L10_3d # no 242162306a36Sopenharmony_ci bsr.l ld_pone # yes 242262306a36Sopenharmony_ci bra.b _L10_6d 242362306a36Sopenharmony_ci_L10_3d: 242462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 242562306a36Sopenharmony_ci bne.b _L10_4d # no 242662306a36Sopenharmony_ci bsr.l szr_inf # yes 242762306a36Sopenharmony_ci bra.b _L10_6d 242862306a36Sopenharmony_ci_L10_4d: 242962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 243062306a36Sopenharmony_ci bne.b _L10_5d # no 243162306a36Sopenharmony_ci bsr.l src_qnan # yes 243262306a36Sopenharmony_ci bra.b _L10_6d 243362306a36Sopenharmony_ci_L10_5d: 243462306a36Sopenharmony_ci bsr.l setoxd # operand is a DENORM 243562306a36Sopenharmony_ci_L10_6d: 243662306a36Sopenharmony_ci 243762306a36Sopenharmony_ci# 243862306a36Sopenharmony_ci# Result is now in FP0 243962306a36Sopenharmony_ci# 244062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 244162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 244262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 244362306a36Sopenharmony_ci unlk %a6 244462306a36Sopenharmony_ci rts 244562306a36Sopenharmony_ci 244662306a36Sopenharmony_ci global _fetoxx_ 244762306a36Sopenharmony_ci_fetoxx_: 244862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 245162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 245262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 245362306a36Sopenharmony_ci 245462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci# 245762306a36Sopenharmony_ci# copy, convert, and tag input argument 245862306a36Sopenharmony_ci# 245962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 246062306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 246162306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 246262306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 246362306a36Sopenharmony_ci bsr.l tag # fetch operand type 246462306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 246562306a36Sopenharmony_ci mov.b %d0,%d1 246662306a36Sopenharmony_ci 246762306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 246862306a36Sopenharmony_ci 246962306a36Sopenharmony_ci clr.l %d0 247062306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 247162306a36Sopenharmony_ci 247262306a36Sopenharmony_ci tst.b %d1 247362306a36Sopenharmony_ci bne.b _L10_2x 247462306a36Sopenharmony_ci bsr.l setox # operand is a NORM 247562306a36Sopenharmony_ci bra.b _L10_6x 247662306a36Sopenharmony_ci_L10_2x: 247762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 247862306a36Sopenharmony_ci bne.b _L10_3x # no 247962306a36Sopenharmony_ci bsr.l ld_pone # yes 248062306a36Sopenharmony_ci bra.b _L10_6x 248162306a36Sopenharmony_ci_L10_3x: 248262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 248362306a36Sopenharmony_ci bne.b _L10_4x # no 248462306a36Sopenharmony_ci bsr.l szr_inf # yes 248562306a36Sopenharmony_ci bra.b _L10_6x 248662306a36Sopenharmony_ci_L10_4x: 248762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 248862306a36Sopenharmony_ci bne.b _L10_5x # no 248962306a36Sopenharmony_ci bsr.l src_qnan # yes 249062306a36Sopenharmony_ci bra.b _L10_6x 249162306a36Sopenharmony_ci_L10_5x: 249262306a36Sopenharmony_ci bsr.l setoxd # operand is a DENORM 249362306a36Sopenharmony_ci_L10_6x: 249462306a36Sopenharmony_ci 249562306a36Sopenharmony_ci# 249662306a36Sopenharmony_ci# Result is now in FP0 249762306a36Sopenharmony_ci# 249862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 249962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 250062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 250162306a36Sopenharmony_ci unlk %a6 250262306a36Sopenharmony_ci rts 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci 250562306a36Sopenharmony_ci######################################################################### 250662306a36Sopenharmony_ci# MONADIC TEMPLATE # 250762306a36Sopenharmony_ci######################################################################### 250862306a36Sopenharmony_ci global _ftwotoxs_ 250962306a36Sopenharmony_ci_ftwotoxs_: 251062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 251162306a36Sopenharmony_ci 251262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 251362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 251462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 251562306a36Sopenharmony_ci 251662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_ci# 251962306a36Sopenharmony_ci# copy, convert, and tag input argument 252062306a36Sopenharmony_ci# 252162306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 252262306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 252362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 252462306a36Sopenharmony_ci bsr.l tag # fetch operand type 252562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 252662306a36Sopenharmony_ci mov.b %d0,%d1 252762306a36Sopenharmony_ci 252862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 252962306a36Sopenharmony_ci 253062306a36Sopenharmony_ci clr.l %d0 253162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 253262306a36Sopenharmony_ci 253362306a36Sopenharmony_ci tst.b %d1 253462306a36Sopenharmony_ci bne.b _L11_2s 253562306a36Sopenharmony_ci bsr.l stwotox # operand is a NORM 253662306a36Sopenharmony_ci bra.b _L11_6s 253762306a36Sopenharmony_ci_L11_2s: 253862306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 253962306a36Sopenharmony_ci bne.b _L11_3s # no 254062306a36Sopenharmony_ci bsr.l ld_pone # yes 254162306a36Sopenharmony_ci bra.b _L11_6s 254262306a36Sopenharmony_ci_L11_3s: 254362306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 254462306a36Sopenharmony_ci bne.b _L11_4s # no 254562306a36Sopenharmony_ci bsr.l szr_inf # yes 254662306a36Sopenharmony_ci bra.b _L11_6s 254762306a36Sopenharmony_ci_L11_4s: 254862306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 254962306a36Sopenharmony_ci bne.b _L11_5s # no 255062306a36Sopenharmony_ci bsr.l src_qnan # yes 255162306a36Sopenharmony_ci bra.b _L11_6s 255262306a36Sopenharmony_ci_L11_5s: 255362306a36Sopenharmony_ci bsr.l stwotoxd # operand is a DENORM 255462306a36Sopenharmony_ci_L11_6s: 255562306a36Sopenharmony_ci 255662306a36Sopenharmony_ci# 255762306a36Sopenharmony_ci# Result is now in FP0 255862306a36Sopenharmony_ci# 255962306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 256062306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 256162306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 256262306a36Sopenharmony_ci unlk %a6 256362306a36Sopenharmony_ci rts 256462306a36Sopenharmony_ci 256562306a36Sopenharmony_ci global _ftwotoxd_ 256662306a36Sopenharmony_ci_ftwotoxd_: 256762306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 256862306a36Sopenharmony_ci 256962306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 257062306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 257162306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 257262306a36Sopenharmony_ci 257362306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 257462306a36Sopenharmony_ci 257562306a36Sopenharmony_ci# 257662306a36Sopenharmony_ci# copy, convert, and tag input argument 257762306a36Sopenharmony_ci# 257862306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 257962306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 258062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 258162306a36Sopenharmony_ci bsr.l tag # fetch operand type 258262306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 258362306a36Sopenharmony_ci mov.b %d0,%d1 258462306a36Sopenharmony_ci 258562306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 258662306a36Sopenharmony_ci 258762306a36Sopenharmony_ci clr.l %d0 258862306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 259162306a36Sopenharmony_ci tst.b %d1 259262306a36Sopenharmony_ci bne.b _L11_2d 259362306a36Sopenharmony_ci bsr.l stwotox # operand is a NORM 259462306a36Sopenharmony_ci bra.b _L11_6d 259562306a36Sopenharmony_ci_L11_2d: 259662306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 259762306a36Sopenharmony_ci bne.b _L11_3d # no 259862306a36Sopenharmony_ci bsr.l ld_pone # yes 259962306a36Sopenharmony_ci bra.b _L11_6d 260062306a36Sopenharmony_ci_L11_3d: 260162306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 260262306a36Sopenharmony_ci bne.b _L11_4d # no 260362306a36Sopenharmony_ci bsr.l szr_inf # yes 260462306a36Sopenharmony_ci bra.b _L11_6d 260562306a36Sopenharmony_ci_L11_4d: 260662306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 260762306a36Sopenharmony_ci bne.b _L11_5d # no 260862306a36Sopenharmony_ci bsr.l src_qnan # yes 260962306a36Sopenharmony_ci bra.b _L11_6d 261062306a36Sopenharmony_ci_L11_5d: 261162306a36Sopenharmony_ci bsr.l stwotoxd # operand is a DENORM 261262306a36Sopenharmony_ci_L11_6d: 261362306a36Sopenharmony_ci 261462306a36Sopenharmony_ci# 261562306a36Sopenharmony_ci# Result is now in FP0 261662306a36Sopenharmony_ci# 261762306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 261862306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 261962306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 262062306a36Sopenharmony_ci unlk %a6 262162306a36Sopenharmony_ci rts 262262306a36Sopenharmony_ci 262362306a36Sopenharmony_ci global _ftwotoxx_ 262462306a36Sopenharmony_ci_ftwotoxx_: 262562306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 262662306a36Sopenharmony_ci 262762306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 262862306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 262962306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 263062306a36Sopenharmony_ci 263162306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 263262306a36Sopenharmony_ci 263362306a36Sopenharmony_ci# 263462306a36Sopenharmony_ci# copy, convert, and tag input argument 263562306a36Sopenharmony_ci# 263662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 263762306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 263862306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 263962306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 264062306a36Sopenharmony_ci bsr.l tag # fetch operand type 264162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 264262306a36Sopenharmony_ci mov.b %d0,%d1 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 264562306a36Sopenharmony_ci 264662306a36Sopenharmony_ci clr.l %d0 264762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 264862306a36Sopenharmony_ci 264962306a36Sopenharmony_ci tst.b %d1 265062306a36Sopenharmony_ci bne.b _L11_2x 265162306a36Sopenharmony_ci bsr.l stwotox # operand is a NORM 265262306a36Sopenharmony_ci bra.b _L11_6x 265362306a36Sopenharmony_ci_L11_2x: 265462306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 265562306a36Sopenharmony_ci bne.b _L11_3x # no 265662306a36Sopenharmony_ci bsr.l ld_pone # yes 265762306a36Sopenharmony_ci bra.b _L11_6x 265862306a36Sopenharmony_ci_L11_3x: 265962306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 266062306a36Sopenharmony_ci bne.b _L11_4x # no 266162306a36Sopenharmony_ci bsr.l szr_inf # yes 266262306a36Sopenharmony_ci bra.b _L11_6x 266362306a36Sopenharmony_ci_L11_4x: 266462306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 266562306a36Sopenharmony_ci bne.b _L11_5x # no 266662306a36Sopenharmony_ci bsr.l src_qnan # yes 266762306a36Sopenharmony_ci bra.b _L11_6x 266862306a36Sopenharmony_ci_L11_5x: 266962306a36Sopenharmony_ci bsr.l stwotoxd # operand is a DENORM 267062306a36Sopenharmony_ci_L11_6x: 267162306a36Sopenharmony_ci 267262306a36Sopenharmony_ci# 267362306a36Sopenharmony_ci# Result is now in FP0 267462306a36Sopenharmony_ci# 267562306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 267662306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 267762306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 267862306a36Sopenharmony_ci unlk %a6 267962306a36Sopenharmony_ci rts 268062306a36Sopenharmony_ci 268162306a36Sopenharmony_ci 268262306a36Sopenharmony_ci######################################################################### 268362306a36Sopenharmony_ci# MONADIC TEMPLATE # 268462306a36Sopenharmony_ci######################################################################### 268562306a36Sopenharmony_ci global _ftentoxs_ 268662306a36Sopenharmony_ci_ftentoxs_: 268762306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 268862306a36Sopenharmony_ci 268962306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 269062306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 269162306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 269262306a36Sopenharmony_ci 269362306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 269462306a36Sopenharmony_ci 269562306a36Sopenharmony_ci# 269662306a36Sopenharmony_ci# copy, convert, and tag input argument 269762306a36Sopenharmony_ci# 269862306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 269962306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 270062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 270162306a36Sopenharmony_ci bsr.l tag # fetch operand type 270262306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 270362306a36Sopenharmony_ci mov.b %d0,%d1 270462306a36Sopenharmony_ci 270562306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 270662306a36Sopenharmony_ci 270762306a36Sopenharmony_ci clr.l %d0 270862306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 270962306a36Sopenharmony_ci 271062306a36Sopenharmony_ci tst.b %d1 271162306a36Sopenharmony_ci bne.b _L12_2s 271262306a36Sopenharmony_ci bsr.l stentox # operand is a NORM 271362306a36Sopenharmony_ci bra.b _L12_6s 271462306a36Sopenharmony_ci_L12_2s: 271562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 271662306a36Sopenharmony_ci bne.b _L12_3s # no 271762306a36Sopenharmony_ci bsr.l ld_pone # yes 271862306a36Sopenharmony_ci bra.b _L12_6s 271962306a36Sopenharmony_ci_L12_3s: 272062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 272162306a36Sopenharmony_ci bne.b _L12_4s # no 272262306a36Sopenharmony_ci bsr.l szr_inf # yes 272362306a36Sopenharmony_ci bra.b _L12_6s 272462306a36Sopenharmony_ci_L12_4s: 272562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 272662306a36Sopenharmony_ci bne.b _L12_5s # no 272762306a36Sopenharmony_ci bsr.l src_qnan # yes 272862306a36Sopenharmony_ci bra.b _L12_6s 272962306a36Sopenharmony_ci_L12_5s: 273062306a36Sopenharmony_ci bsr.l stentoxd # operand is a DENORM 273162306a36Sopenharmony_ci_L12_6s: 273262306a36Sopenharmony_ci 273362306a36Sopenharmony_ci# 273462306a36Sopenharmony_ci# Result is now in FP0 273562306a36Sopenharmony_ci# 273662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 273762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 273862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 273962306a36Sopenharmony_ci unlk %a6 274062306a36Sopenharmony_ci rts 274162306a36Sopenharmony_ci 274262306a36Sopenharmony_ci global _ftentoxd_ 274362306a36Sopenharmony_ci_ftentoxd_: 274462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 274562306a36Sopenharmony_ci 274662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 274762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 274862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 274962306a36Sopenharmony_ci 275062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 275162306a36Sopenharmony_ci 275262306a36Sopenharmony_ci# 275362306a36Sopenharmony_ci# copy, convert, and tag input argument 275462306a36Sopenharmony_ci# 275562306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 275662306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 275762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 275862306a36Sopenharmony_ci bsr.l tag # fetch operand type 275962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 276062306a36Sopenharmony_ci mov.b %d0,%d1 276162306a36Sopenharmony_ci 276262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 276362306a36Sopenharmony_ci 276462306a36Sopenharmony_ci clr.l %d0 276562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 276662306a36Sopenharmony_ci 276762306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 276862306a36Sopenharmony_ci tst.b %d1 276962306a36Sopenharmony_ci bne.b _L12_2d 277062306a36Sopenharmony_ci bsr.l stentox # operand is a NORM 277162306a36Sopenharmony_ci bra.b _L12_6d 277262306a36Sopenharmony_ci_L12_2d: 277362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 277462306a36Sopenharmony_ci bne.b _L12_3d # no 277562306a36Sopenharmony_ci bsr.l ld_pone # yes 277662306a36Sopenharmony_ci bra.b _L12_6d 277762306a36Sopenharmony_ci_L12_3d: 277862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 277962306a36Sopenharmony_ci bne.b _L12_4d # no 278062306a36Sopenharmony_ci bsr.l szr_inf # yes 278162306a36Sopenharmony_ci bra.b _L12_6d 278262306a36Sopenharmony_ci_L12_4d: 278362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 278462306a36Sopenharmony_ci bne.b _L12_5d # no 278562306a36Sopenharmony_ci bsr.l src_qnan # yes 278662306a36Sopenharmony_ci bra.b _L12_6d 278762306a36Sopenharmony_ci_L12_5d: 278862306a36Sopenharmony_ci bsr.l stentoxd # operand is a DENORM 278962306a36Sopenharmony_ci_L12_6d: 279062306a36Sopenharmony_ci 279162306a36Sopenharmony_ci# 279262306a36Sopenharmony_ci# Result is now in FP0 279362306a36Sopenharmony_ci# 279462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 279562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 279662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 279762306a36Sopenharmony_ci unlk %a6 279862306a36Sopenharmony_ci rts 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci global _ftentoxx_ 280162306a36Sopenharmony_ci_ftentoxx_: 280262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 280562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 280662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 280762306a36Sopenharmony_ci 280862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 280962306a36Sopenharmony_ci 281062306a36Sopenharmony_ci# 281162306a36Sopenharmony_ci# copy, convert, and tag input argument 281262306a36Sopenharmony_ci# 281362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 281462306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 281562306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 281662306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 281762306a36Sopenharmony_ci bsr.l tag # fetch operand type 281862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 281962306a36Sopenharmony_ci mov.b %d0,%d1 282062306a36Sopenharmony_ci 282162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 282262306a36Sopenharmony_ci 282362306a36Sopenharmony_ci clr.l %d0 282462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 282562306a36Sopenharmony_ci 282662306a36Sopenharmony_ci tst.b %d1 282762306a36Sopenharmony_ci bne.b _L12_2x 282862306a36Sopenharmony_ci bsr.l stentox # operand is a NORM 282962306a36Sopenharmony_ci bra.b _L12_6x 283062306a36Sopenharmony_ci_L12_2x: 283162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 283262306a36Sopenharmony_ci bne.b _L12_3x # no 283362306a36Sopenharmony_ci bsr.l ld_pone # yes 283462306a36Sopenharmony_ci bra.b _L12_6x 283562306a36Sopenharmony_ci_L12_3x: 283662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 283762306a36Sopenharmony_ci bne.b _L12_4x # no 283862306a36Sopenharmony_ci bsr.l szr_inf # yes 283962306a36Sopenharmony_ci bra.b _L12_6x 284062306a36Sopenharmony_ci_L12_4x: 284162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 284262306a36Sopenharmony_ci bne.b _L12_5x # no 284362306a36Sopenharmony_ci bsr.l src_qnan # yes 284462306a36Sopenharmony_ci bra.b _L12_6x 284562306a36Sopenharmony_ci_L12_5x: 284662306a36Sopenharmony_ci bsr.l stentoxd # operand is a DENORM 284762306a36Sopenharmony_ci_L12_6x: 284862306a36Sopenharmony_ci 284962306a36Sopenharmony_ci# 285062306a36Sopenharmony_ci# Result is now in FP0 285162306a36Sopenharmony_ci# 285262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 285362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 285462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 285562306a36Sopenharmony_ci unlk %a6 285662306a36Sopenharmony_ci rts 285762306a36Sopenharmony_ci 285862306a36Sopenharmony_ci 285962306a36Sopenharmony_ci######################################################################### 286062306a36Sopenharmony_ci# MONADIC TEMPLATE # 286162306a36Sopenharmony_ci######################################################################### 286262306a36Sopenharmony_ci global _flogns_ 286362306a36Sopenharmony_ci_flogns_: 286462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 286562306a36Sopenharmony_ci 286662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 286762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 286862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 286962306a36Sopenharmony_ci 287062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 287162306a36Sopenharmony_ci 287262306a36Sopenharmony_ci# 287362306a36Sopenharmony_ci# copy, convert, and tag input argument 287462306a36Sopenharmony_ci# 287562306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 287662306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 287762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 287862306a36Sopenharmony_ci bsr.l tag # fetch operand type 287962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 288062306a36Sopenharmony_ci mov.b %d0,%d1 288162306a36Sopenharmony_ci 288262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 288362306a36Sopenharmony_ci 288462306a36Sopenharmony_ci clr.l %d0 288562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 288662306a36Sopenharmony_ci 288762306a36Sopenharmony_ci tst.b %d1 288862306a36Sopenharmony_ci bne.b _L13_2s 288962306a36Sopenharmony_ci bsr.l slogn # operand is a NORM 289062306a36Sopenharmony_ci bra.b _L13_6s 289162306a36Sopenharmony_ci_L13_2s: 289262306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 289362306a36Sopenharmony_ci bne.b _L13_3s # no 289462306a36Sopenharmony_ci bsr.l t_dz2 # yes 289562306a36Sopenharmony_ci bra.b _L13_6s 289662306a36Sopenharmony_ci_L13_3s: 289762306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 289862306a36Sopenharmony_ci bne.b _L13_4s # no 289962306a36Sopenharmony_ci bsr.l sopr_inf # yes 290062306a36Sopenharmony_ci bra.b _L13_6s 290162306a36Sopenharmony_ci_L13_4s: 290262306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 290362306a36Sopenharmony_ci bne.b _L13_5s # no 290462306a36Sopenharmony_ci bsr.l src_qnan # yes 290562306a36Sopenharmony_ci bra.b _L13_6s 290662306a36Sopenharmony_ci_L13_5s: 290762306a36Sopenharmony_ci bsr.l slognd # operand is a DENORM 290862306a36Sopenharmony_ci_L13_6s: 290962306a36Sopenharmony_ci 291062306a36Sopenharmony_ci# 291162306a36Sopenharmony_ci# Result is now in FP0 291262306a36Sopenharmony_ci# 291362306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 291462306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 291562306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 291662306a36Sopenharmony_ci unlk %a6 291762306a36Sopenharmony_ci rts 291862306a36Sopenharmony_ci 291962306a36Sopenharmony_ci global _flognd_ 292062306a36Sopenharmony_ci_flognd_: 292162306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 292262306a36Sopenharmony_ci 292362306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 292462306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 292562306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 292662306a36Sopenharmony_ci 292762306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 292862306a36Sopenharmony_ci 292962306a36Sopenharmony_ci# 293062306a36Sopenharmony_ci# copy, convert, and tag input argument 293162306a36Sopenharmony_ci# 293262306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 293362306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 293462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 293562306a36Sopenharmony_ci bsr.l tag # fetch operand type 293662306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 293762306a36Sopenharmony_ci mov.b %d0,%d1 293862306a36Sopenharmony_ci 293962306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 294062306a36Sopenharmony_ci 294162306a36Sopenharmony_ci clr.l %d0 294262306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 294362306a36Sopenharmony_ci 294462306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 294562306a36Sopenharmony_ci tst.b %d1 294662306a36Sopenharmony_ci bne.b _L13_2d 294762306a36Sopenharmony_ci bsr.l slogn # operand is a NORM 294862306a36Sopenharmony_ci bra.b _L13_6d 294962306a36Sopenharmony_ci_L13_2d: 295062306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 295162306a36Sopenharmony_ci bne.b _L13_3d # no 295262306a36Sopenharmony_ci bsr.l t_dz2 # yes 295362306a36Sopenharmony_ci bra.b _L13_6d 295462306a36Sopenharmony_ci_L13_3d: 295562306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 295662306a36Sopenharmony_ci bne.b _L13_4d # no 295762306a36Sopenharmony_ci bsr.l sopr_inf # yes 295862306a36Sopenharmony_ci bra.b _L13_6d 295962306a36Sopenharmony_ci_L13_4d: 296062306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 296162306a36Sopenharmony_ci bne.b _L13_5d # no 296262306a36Sopenharmony_ci bsr.l src_qnan # yes 296362306a36Sopenharmony_ci bra.b _L13_6d 296462306a36Sopenharmony_ci_L13_5d: 296562306a36Sopenharmony_ci bsr.l slognd # operand is a DENORM 296662306a36Sopenharmony_ci_L13_6d: 296762306a36Sopenharmony_ci 296862306a36Sopenharmony_ci# 296962306a36Sopenharmony_ci# Result is now in FP0 297062306a36Sopenharmony_ci# 297162306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 297262306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 297362306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 297462306a36Sopenharmony_ci unlk %a6 297562306a36Sopenharmony_ci rts 297662306a36Sopenharmony_ci 297762306a36Sopenharmony_ci global _flognx_ 297862306a36Sopenharmony_ci_flognx_: 297962306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 298062306a36Sopenharmony_ci 298162306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 298262306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 298362306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 298462306a36Sopenharmony_ci 298562306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 298662306a36Sopenharmony_ci 298762306a36Sopenharmony_ci# 298862306a36Sopenharmony_ci# copy, convert, and tag input argument 298962306a36Sopenharmony_ci# 299062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 299162306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 299262306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 299362306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 299462306a36Sopenharmony_ci bsr.l tag # fetch operand type 299562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 299662306a36Sopenharmony_ci mov.b %d0,%d1 299762306a36Sopenharmony_ci 299862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 299962306a36Sopenharmony_ci 300062306a36Sopenharmony_ci clr.l %d0 300162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 300262306a36Sopenharmony_ci 300362306a36Sopenharmony_ci tst.b %d1 300462306a36Sopenharmony_ci bne.b _L13_2x 300562306a36Sopenharmony_ci bsr.l slogn # operand is a NORM 300662306a36Sopenharmony_ci bra.b _L13_6x 300762306a36Sopenharmony_ci_L13_2x: 300862306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 300962306a36Sopenharmony_ci bne.b _L13_3x # no 301062306a36Sopenharmony_ci bsr.l t_dz2 # yes 301162306a36Sopenharmony_ci bra.b _L13_6x 301262306a36Sopenharmony_ci_L13_3x: 301362306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 301462306a36Sopenharmony_ci bne.b _L13_4x # no 301562306a36Sopenharmony_ci bsr.l sopr_inf # yes 301662306a36Sopenharmony_ci bra.b _L13_6x 301762306a36Sopenharmony_ci_L13_4x: 301862306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 301962306a36Sopenharmony_ci bne.b _L13_5x # no 302062306a36Sopenharmony_ci bsr.l src_qnan # yes 302162306a36Sopenharmony_ci bra.b _L13_6x 302262306a36Sopenharmony_ci_L13_5x: 302362306a36Sopenharmony_ci bsr.l slognd # operand is a DENORM 302462306a36Sopenharmony_ci_L13_6x: 302562306a36Sopenharmony_ci 302662306a36Sopenharmony_ci# 302762306a36Sopenharmony_ci# Result is now in FP0 302862306a36Sopenharmony_ci# 302962306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 303062306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 303162306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 303262306a36Sopenharmony_ci unlk %a6 303362306a36Sopenharmony_ci rts 303462306a36Sopenharmony_ci 303562306a36Sopenharmony_ci 303662306a36Sopenharmony_ci######################################################################### 303762306a36Sopenharmony_ci# MONADIC TEMPLATE # 303862306a36Sopenharmony_ci######################################################################### 303962306a36Sopenharmony_ci global _flog10s_ 304062306a36Sopenharmony_ci_flog10s_: 304162306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 304262306a36Sopenharmony_ci 304362306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 304462306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 304562306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 304662306a36Sopenharmony_ci 304762306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 304862306a36Sopenharmony_ci 304962306a36Sopenharmony_ci# 305062306a36Sopenharmony_ci# copy, convert, and tag input argument 305162306a36Sopenharmony_ci# 305262306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 305362306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 305462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 305562306a36Sopenharmony_ci bsr.l tag # fetch operand type 305662306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 305762306a36Sopenharmony_ci mov.b %d0,%d1 305862306a36Sopenharmony_ci 305962306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 306062306a36Sopenharmony_ci 306162306a36Sopenharmony_ci clr.l %d0 306262306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 306362306a36Sopenharmony_ci 306462306a36Sopenharmony_ci tst.b %d1 306562306a36Sopenharmony_ci bne.b _L14_2s 306662306a36Sopenharmony_ci bsr.l slog10 # operand is a NORM 306762306a36Sopenharmony_ci bra.b _L14_6s 306862306a36Sopenharmony_ci_L14_2s: 306962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 307062306a36Sopenharmony_ci bne.b _L14_3s # no 307162306a36Sopenharmony_ci bsr.l t_dz2 # yes 307262306a36Sopenharmony_ci bra.b _L14_6s 307362306a36Sopenharmony_ci_L14_3s: 307462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 307562306a36Sopenharmony_ci bne.b _L14_4s # no 307662306a36Sopenharmony_ci bsr.l sopr_inf # yes 307762306a36Sopenharmony_ci bra.b _L14_6s 307862306a36Sopenharmony_ci_L14_4s: 307962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 308062306a36Sopenharmony_ci bne.b _L14_5s # no 308162306a36Sopenharmony_ci bsr.l src_qnan # yes 308262306a36Sopenharmony_ci bra.b _L14_6s 308362306a36Sopenharmony_ci_L14_5s: 308462306a36Sopenharmony_ci bsr.l slog10d # operand is a DENORM 308562306a36Sopenharmony_ci_L14_6s: 308662306a36Sopenharmony_ci 308762306a36Sopenharmony_ci# 308862306a36Sopenharmony_ci# Result is now in FP0 308962306a36Sopenharmony_ci# 309062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 309162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 309262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 309362306a36Sopenharmony_ci unlk %a6 309462306a36Sopenharmony_ci rts 309562306a36Sopenharmony_ci 309662306a36Sopenharmony_ci global _flog10d_ 309762306a36Sopenharmony_ci_flog10d_: 309862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 309962306a36Sopenharmony_ci 310062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 310162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 310262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 310362306a36Sopenharmony_ci 310462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 310562306a36Sopenharmony_ci 310662306a36Sopenharmony_ci# 310762306a36Sopenharmony_ci# copy, convert, and tag input argument 310862306a36Sopenharmony_ci# 310962306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 311062306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 311162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 311262306a36Sopenharmony_ci bsr.l tag # fetch operand type 311362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 311462306a36Sopenharmony_ci mov.b %d0,%d1 311562306a36Sopenharmony_ci 311662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 311762306a36Sopenharmony_ci 311862306a36Sopenharmony_ci clr.l %d0 311962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 312062306a36Sopenharmony_ci 312162306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 312262306a36Sopenharmony_ci tst.b %d1 312362306a36Sopenharmony_ci bne.b _L14_2d 312462306a36Sopenharmony_ci bsr.l slog10 # operand is a NORM 312562306a36Sopenharmony_ci bra.b _L14_6d 312662306a36Sopenharmony_ci_L14_2d: 312762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 312862306a36Sopenharmony_ci bne.b _L14_3d # no 312962306a36Sopenharmony_ci bsr.l t_dz2 # yes 313062306a36Sopenharmony_ci bra.b _L14_6d 313162306a36Sopenharmony_ci_L14_3d: 313262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 313362306a36Sopenharmony_ci bne.b _L14_4d # no 313462306a36Sopenharmony_ci bsr.l sopr_inf # yes 313562306a36Sopenharmony_ci bra.b _L14_6d 313662306a36Sopenharmony_ci_L14_4d: 313762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 313862306a36Sopenharmony_ci bne.b _L14_5d # no 313962306a36Sopenharmony_ci bsr.l src_qnan # yes 314062306a36Sopenharmony_ci bra.b _L14_6d 314162306a36Sopenharmony_ci_L14_5d: 314262306a36Sopenharmony_ci bsr.l slog10d # operand is a DENORM 314362306a36Sopenharmony_ci_L14_6d: 314462306a36Sopenharmony_ci 314562306a36Sopenharmony_ci# 314662306a36Sopenharmony_ci# Result is now in FP0 314762306a36Sopenharmony_ci# 314862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 314962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 315062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 315162306a36Sopenharmony_ci unlk %a6 315262306a36Sopenharmony_ci rts 315362306a36Sopenharmony_ci 315462306a36Sopenharmony_ci global _flog10x_ 315562306a36Sopenharmony_ci_flog10x_: 315662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 315762306a36Sopenharmony_ci 315862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 315962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 316062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 316362306a36Sopenharmony_ci 316462306a36Sopenharmony_ci# 316562306a36Sopenharmony_ci# copy, convert, and tag input argument 316662306a36Sopenharmony_ci# 316762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 316862306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 316962306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 317062306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 317162306a36Sopenharmony_ci bsr.l tag # fetch operand type 317262306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 317362306a36Sopenharmony_ci mov.b %d0,%d1 317462306a36Sopenharmony_ci 317562306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_ci clr.l %d0 317862306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 317962306a36Sopenharmony_ci 318062306a36Sopenharmony_ci tst.b %d1 318162306a36Sopenharmony_ci bne.b _L14_2x 318262306a36Sopenharmony_ci bsr.l slog10 # operand is a NORM 318362306a36Sopenharmony_ci bra.b _L14_6x 318462306a36Sopenharmony_ci_L14_2x: 318562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 318662306a36Sopenharmony_ci bne.b _L14_3x # no 318762306a36Sopenharmony_ci bsr.l t_dz2 # yes 318862306a36Sopenharmony_ci bra.b _L14_6x 318962306a36Sopenharmony_ci_L14_3x: 319062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 319162306a36Sopenharmony_ci bne.b _L14_4x # no 319262306a36Sopenharmony_ci bsr.l sopr_inf # yes 319362306a36Sopenharmony_ci bra.b _L14_6x 319462306a36Sopenharmony_ci_L14_4x: 319562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 319662306a36Sopenharmony_ci bne.b _L14_5x # no 319762306a36Sopenharmony_ci bsr.l src_qnan # yes 319862306a36Sopenharmony_ci bra.b _L14_6x 319962306a36Sopenharmony_ci_L14_5x: 320062306a36Sopenharmony_ci bsr.l slog10d # operand is a DENORM 320162306a36Sopenharmony_ci_L14_6x: 320262306a36Sopenharmony_ci 320362306a36Sopenharmony_ci# 320462306a36Sopenharmony_ci# Result is now in FP0 320562306a36Sopenharmony_ci# 320662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 320762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 320862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 320962306a36Sopenharmony_ci unlk %a6 321062306a36Sopenharmony_ci rts 321162306a36Sopenharmony_ci 321262306a36Sopenharmony_ci 321362306a36Sopenharmony_ci######################################################################### 321462306a36Sopenharmony_ci# MONADIC TEMPLATE # 321562306a36Sopenharmony_ci######################################################################### 321662306a36Sopenharmony_ci global _flog2s_ 321762306a36Sopenharmony_ci_flog2s_: 321862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 321962306a36Sopenharmony_ci 322062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 322162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 322262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 322362306a36Sopenharmony_ci 322462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 322562306a36Sopenharmony_ci 322662306a36Sopenharmony_ci# 322762306a36Sopenharmony_ci# copy, convert, and tag input argument 322862306a36Sopenharmony_ci# 322962306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 323062306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 323162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 323262306a36Sopenharmony_ci bsr.l tag # fetch operand type 323362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 323462306a36Sopenharmony_ci mov.b %d0,%d1 323562306a36Sopenharmony_ci 323662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 323762306a36Sopenharmony_ci 323862306a36Sopenharmony_ci clr.l %d0 323962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 324062306a36Sopenharmony_ci 324162306a36Sopenharmony_ci tst.b %d1 324262306a36Sopenharmony_ci bne.b _L15_2s 324362306a36Sopenharmony_ci bsr.l slog2 # operand is a NORM 324462306a36Sopenharmony_ci bra.b _L15_6s 324562306a36Sopenharmony_ci_L15_2s: 324662306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 324762306a36Sopenharmony_ci bne.b _L15_3s # no 324862306a36Sopenharmony_ci bsr.l t_dz2 # yes 324962306a36Sopenharmony_ci bra.b _L15_6s 325062306a36Sopenharmony_ci_L15_3s: 325162306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 325262306a36Sopenharmony_ci bne.b _L15_4s # no 325362306a36Sopenharmony_ci bsr.l sopr_inf # yes 325462306a36Sopenharmony_ci bra.b _L15_6s 325562306a36Sopenharmony_ci_L15_4s: 325662306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 325762306a36Sopenharmony_ci bne.b _L15_5s # no 325862306a36Sopenharmony_ci bsr.l src_qnan # yes 325962306a36Sopenharmony_ci bra.b _L15_6s 326062306a36Sopenharmony_ci_L15_5s: 326162306a36Sopenharmony_ci bsr.l slog2d # operand is a DENORM 326262306a36Sopenharmony_ci_L15_6s: 326362306a36Sopenharmony_ci 326462306a36Sopenharmony_ci# 326562306a36Sopenharmony_ci# Result is now in FP0 326662306a36Sopenharmony_ci# 326762306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 326862306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 326962306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 327062306a36Sopenharmony_ci unlk %a6 327162306a36Sopenharmony_ci rts 327262306a36Sopenharmony_ci 327362306a36Sopenharmony_ci global _flog2d_ 327462306a36Sopenharmony_ci_flog2d_: 327562306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 327862306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 327962306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 328062306a36Sopenharmony_ci 328162306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 328262306a36Sopenharmony_ci 328362306a36Sopenharmony_ci# 328462306a36Sopenharmony_ci# copy, convert, and tag input argument 328562306a36Sopenharmony_ci# 328662306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 328762306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 328862306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 328962306a36Sopenharmony_ci bsr.l tag # fetch operand type 329062306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 329162306a36Sopenharmony_ci mov.b %d0,%d1 329262306a36Sopenharmony_ci 329362306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 329462306a36Sopenharmony_ci 329562306a36Sopenharmony_ci clr.l %d0 329662306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 329762306a36Sopenharmony_ci 329862306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 329962306a36Sopenharmony_ci tst.b %d1 330062306a36Sopenharmony_ci bne.b _L15_2d 330162306a36Sopenharmony_ci bsr.l slog2 # operand is a NORM 330262306a36Sopenharmony_ci bra.b _L15_6d 330362306a36Sopenharmony_ci_L15_2d: 330462306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 330562306a36Sopenharmony_ci bne.b _L15_3d # no 330662306a36Sopenharmony_ci bsr.l t_dz2 # yes 330762306a36Sopenharmony_ci bra.b _L15_6d 330862306a36Sopenharmony_ci_L15_3d: 330962306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 331062306a36Sopenharmony_ci bne.b _L15_4d # no 331162306a36Sopenharmony_ci bsr.l sopr_inf # yes 331262306a36Sopenharmony_ci bra.b _L15_6d 331362306a36Sopenharmony_ci_L15_4d: 331462306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 331562306a36Sopenharmony_ci bne.b _L15_5d # no 331662306a36Sopenharmony_ci bsr.l src_qnan # yes 331762306a36Sopenharmony_ci bra.b _L15_6d 331862306a36Sopenharmony_ci_L15_5d: 331962306a36Sopenharmony_ci bsr.l slog2d # operand is a DENORM 332062306a36Sopenharmony_ci_L15_6d: 332162306a36Sopenharmony_ci 332262306a36Sopenharmony_ci# 332362306a36Sopenharmony_ci# Result is now in FP0 332462306a36Sopenharmony_ci# 332562306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 332662306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 332762306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 332862306a36Sopenharmony_ci unlk %a6 332962306a36Sopenharmony_ci rts 333062306a36Sopenharmony_ci 333162306a36Sopenharmony_ci global _flog2x_ 333262306a36Sopenharmony_ci_flog2x_: 333362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 333462306a36Sopenharmony_ci 333562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 333662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 333762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 333862306a36Sopenharmony_ci 333962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 334062306a36Sopenharmony_ci 334162306a36Sopenharmony_ci# 334262306a36Sopenharmony_ci# copy, convert, and tag input argument 334362306a36Sopenharmony_ci# 334462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 334562306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 334662306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 334762306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 334862306a36Sopenharmony_ci bsr.l tag # fetch operand type 334962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 335062306a36Sopenharmony_ci mov.b %d0,%d1 335162306a36Sopenharmony_ci 335262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 335362306a36Sopenharmony_ci 335462306a36Sopenharmony_ci clr.l %d0 335562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 335662306a36Sopenharmony_ci 335762306a36Sopenharmony_ci tst.b %d1 335862306a36Sopenharmony_ci bne.b _L15_2x 335962306a36Sopenharmony_ci bsr.l slog2 # operand is a NORM 336062306a36Sopenharmony_ci bra.b _L15_6x 336162306a36Sopenharmony_ci_L15_2x: 336262306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 336362306a36Sopenharmony_ci bne.b _L15_3x # no 336462306a36Sopenharmony_ci bsr.l t_dz2 # yes 336562306a36Sopenharmony_ci bra.b _L15_6x 336662306a36Sopenharmony_ci_L15_3x: 336762306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 336862306a36Sopenharmony_ci bne.b _L15_4x # no 336962306a36Sopenharmony_ci bsr.l sopr_inf # yes 337062306a36Sopenharmony_ci bra.b _L15_6x 337162306a36Sopenharmony_ci_L15_4x: 337262306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 337362306a36Sopenharmony_ci bne.b _L15_5x # no 337462306a36Sopenharmony_ci bsr.l src_qnan # yes 337562306a36Sopenharmony_ci bra.b _L15_6x 337662306a36Sopenharmony_ci_L15_5x: 337762306a36Sopenharmony_ci bsr.l slog2d # operand is a DENORM 337862306a36Sopenharmony_ci_L15_6x: 337962306a36Sopenharmony_ci 338062306a36Sopenharmony_ci# 338162306a36Sopenharmony_ci# Result is now in FP0 338262306a36Sopenharmony_ci# 338362306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 338462306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 338562306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 338662306a36Sopenharmony_ci unlk %a6 338762306a36Sopenharmony_ci rts 338862306a36Sopenharmony_ci 338962306a36Sopenharmony_ci 339062306a36Sopenharmony_ci######################################################################### 339162306a36Sopenharmony_ci# MONADIC TEMPLATE # 339262306a36Sopenharmony_ci######################################################################### 339362306a36Sopenharmony_ci global _fcoshs_ 339462306a36Sopenharmony_ci_fcoshs_: 339562306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 339662306a36Sopenharmony_ci 339762306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 339862306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 339962306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 340062306a36Sopenharmony_ci 340162306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 340262306a36Sopenharmony_ci 340362306a36Sopenharmony_ci# 340462306a36Sopenharmony_ci# copy, convert, and tag input argument 340562306a36Sopenharmony_ci# 340662306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 340762306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 340862306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 340962306a36Sopenharmony_ci bsr.l tag # fetch operand type 341062306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 341162306a36Sopenharmony_ci mov.b %d0,%d1 341262306a36Sopenharmony_ci 341362306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 341462306a36Sopenharmony_ci 341562306a36Sopenharmony_ci clr.l %d0 341662306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 341762306a36Sopenharmony_ci 341862306a36Sopenharmony_ci tst.b %d1 341962306a36Sopenharmony_ci bne.b _L16_2s 342062306a36Sopenharmony_ci bsr.l scosh # operand is a NORM 342162306a36Sopenharmony_ci bra.b _L16_6s 342262306a36Sopenharmony_ci_L16_2s: 342362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 342462306a36Sopenharmony_ci bne.b _L16_3s # no 342562306a36Sopenharmony_ci bsr.l ld_pone # yes 342662306a36Sopenharmony_ci bra.b _L16_6s 342762306a36Sopenharmony_ci_L16_3s: 342862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 342962306a36Sopenharmony_ci bne.b _L16_4s # no 343062306a36Sopenharmony_ci bsr.l ld_pinf # yes 343162306a36Sopenharmony_ci bra.b _L16_6s 343262306a36Sopenharmony_ci_L16_4s: 343362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 343462306a36Sopenharmony_ci bne.b _L16_5s # no 343562306a36Sopenharmony_ci bsr.l src_qnan # yes 343662306a36Sopenharmony_ci bra.b _L16_6s 343762306a36Sopenharmony_ci_L16_5s: 343862306a36Sopenharmony_ci bsr.l scoshd # operand is a DENORM 343962306a36Sopenharmony_ci_L16_6s: 344062306a36Sopenharmony_ci 344162306a36Sopenharmony_ci# 344262306a36Sopenharmony_ci# Result is now in FP0 344362306a36Sopenharmony_ci# 344462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 344562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 344662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 344762306a36Sopenharmony_ci unlk %a6 344862306a36Sopenharmony_ci rts 344962306a36Sopenharmony_ci 345062306a36Sopenharmony_ci global _fcoshd_ 345162306a36Sopenharmony_ci_fcoshd_: 345262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 345362306a36Sopenharmony_ci 345462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 345562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 345662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 345762306a36Sopenharmony_ci 345862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 345962306a36Sopenharmony_ci 346062306a36Sopenharmony_ci# 346162306a36Sopenharmony_ci# copy, convert, and tag input argument 346262306a36Sopenharmony_ci# 346362306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 346462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 346562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 346662306a36Sopenharmony_ci bsr.l tag # fetch operand type 346762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 346862306a36Sopenharmony_ci mov.b %d0,%d1 346962306a36Sopenharmony_ci 347062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 347162306a36Sopenharmony_ci 347262306a36Sopenharmony_ci clr.l %d0 347362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 347462306a36Sopenharmony_ci 347562306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 347662306a36Sopenharmony_ci tst.b %d1 347762306a36Sopenharmony_ci bne.b _L16_2d 347862306a36Sopenharmony_ci bsr.l scosh # operand is a NORM 347962306a36Sopenharmony_ci bra.b _L16_6d 348062306a36Sopenharmony_ci_L16_2d: 348162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 348262306a36Sopenharmony_ci bne.b _L16_3d # no 348362306a36Sopenharmony_ci bsr.l ld_pone # yes 348462306a36Sopenharmony_ci bra.b _L16_6d 348562306a36Sopenharmony_ci_L16_3d: 348662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 348762306a36Sopenharmony_ci bne.b _L16_4d # no 348862306a36Sopenharmony_ci bsr.l ld_pinf # yes 348962306a36Sopenharmony_ci bra.b _L16_6d 349062306a36Sopenharmony_ci_L16_4d: 349162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 349262306a36Sopenharmony_ci bne.b _L16_5d # no 349362306a36Sopenharmony_ci bsr.l src_qnan # yes 349462306a36Sopenharmony_ci bra.b _L16_6d 349562306a36Sopenharmony_ci_L16_5d: 349662306a36Sopenharmony_ci bsr.l scoshd # operand is a DENORM 349762306a36Sopenharmony_ci_L16_6d: 349862306a36Sopenharmony_ci 349962306a36Sopenharmony_ci# 350062306a36Sopenharmony_ci# Result is now in FP0 350162306a36Sopenharmony_ci# 350262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 350362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 350462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 350562306a36Sopenharmony_ci unlk %a6 350662306a36Sopenharmony_ci rts 350762306a36Sopenharmony_ci 350862306a36Sopenharmony_ci global _fcoshx_ 350962306a36Sopenharmony_ci_fcoshx_: 351062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 351162306a36Sopenharmony_ci 351262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 351362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 351462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 351562306a36Sopenharmony_ci 351662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 351762306a36Sopenharmony_ci 351862306a36Sopenharmony_ci# 351962306a36Sopenharmony_ci# copy, convert, and tag input argument 352062306a36Sopenharmony_ci# 352162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 352262306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 352362306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 352462306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 352562306a36Sopenharmony_ci bsr.l tag # fetch operand type 352662306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 352762306a36Sopenharmony_ci mov.b %d0,%d1 352862306a36Sopenharmony_ci 352962306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 353062306a36Sopenharmony_ci 353162306a36Sopenharmony_ci clr.l %d0 353262306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 353362306a36Sopenharmony_ci 353462306a36Sopenharmony_ci tst.b %d1 353562306a36Sopenharmony_ci bne.b _L16_2x 353662306a36Sopenharmony_ci bsr.l scosh # operand is a NORM 353762306a36Sopenharmony_ci bra.b _L16_6x 353862306a36Sopenharmony_ci_L16_2x: 353962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 354062306a36Sopenharmony_ci bne.b _L16_3x # no 354162306a36Sopenharmony_ci bsr.l ld_pone # yes 354262306a36Sopenharmony_ci bra.b _L16_6x 354362306a36Sopenharmony_ci_L16_3x: 354462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 354562306a36Sopenharmony_ci bne.b _L16_4x # no 354662306a36Sopenharmony_ci bsr.l ld_pinf # yes 354762306a36Sopenharmony_ci bra.b _L16_6x 354862306a36Sopenharmony_ci_L16_4x: 354962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 355062306a36Sopenharmony_ci bne.b _L16_5x # no 355162306a36Sopenharmony_ci bsr.l src_qnan # yes 355262306a36Sopenharmony_ci bra.b _L16_6x 355362306a36Sopenharmony_ci_L16_5x: 355462306a36Sopenharmony_ci bsr.l scoshd # operand is a DENORM 355562306a36Sopenharmony_ci_L16_6x: 355662306a36Sopenharmony_ci 355762306a36Sopenharmony_ci# 355862306a36Sopenharmony_ci# Result is now in FP0 355962306a36Sopenharmony_ci# 356062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 356162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 356262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 356362306a36Sopenharmony_ci unlk %a6 356462306a36Sopenharmony_ci rts 356562306a36Sopenharmony_ci 356662306a36Sopenharmony_ci 356762306a36Sopenharmony_ci######################################################################### 356862306a36Sopenharmony_ci# MONADIC TEMPLATE # 356962306a36Sopenharmony_ci######################################################################### 357062306a36Sopenharmony_ci global _facoss_ 357162306a36Sopenharmony_ci_facoss_: 357262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 357362306a36Sopenharmony_ci 357462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 357562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 357662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 357762306a36Sopenharmony_ci 357862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 357962306a36Sopenharmony_ci 358062306a36Sopenharmony_ci# 358162306a36Sopenharmony_ci# copy, convert, and tag input argument 358262306a36Sopenharmony_ci# 358362306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 358462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 358562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 358662306a36Sopenharmony_ci bsr.l tag # fetch operand type 358762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 358862306a36Sopenharmony_ci mov.b %d0,%d1 358962306a36Sopenharmony_ci 359062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 359162306a36Sopenharmony_ci 359262306a36Sopenharmony_ci clr.l %d0 359362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 359462306a36Sopenharmony_ci 359562306a36Sopenharmony_ci tst.b %d1 359662306a36Sopenharmony_ci bne.b _L17_2s 359762306a36Sopenharmony_ci bsr.l sacos # operand is a NORM 359862306a36Sopenharmony_ci bra.b _L17_6s 359962306a36Sopenharmony_ci_L17_2s: 360062306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 360162306a36Sopenharmony_ci bne.b _L17_3s # no 360262306a36Sopenharmony_ci bsr.l ld_ppi2 # yes 360362306a36Sopenharmony_ci bra.b _L17_6s 360462306a36Sopenharmony_ci_L17_3s: 360562306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 360662306a36Sopenharmony_ci bne.b _L17_4s # no 360762306a36Sopenharmony_ci bsr.l t_operr # yes 360862306a36Sopenharmony_ci bra.b _L17_6s 360962306a36Sopenharmony_ci_L17_4s: 361062306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 361162306a36Sopenharmony_ci bne.b _L17_5s # no 361262306a36Sopenharmony_ci bsr.l src_qnan # yes 361362306a36Sopenharmony_ci bra.b _L17_6s 361462306a36Sopenharmony_ci_L17_5s: 361562306a36Sopenharmony_ci bsr.l sacosd # operand is a DENORM 361662306a36Sopenharmony_ci_L17_6s: 361762306a36Sopenharmony_ci 361862306a36Sopenharmony_ci# 361962306a36Sopenharmony_ci# Result is now in FP0 362062306a36Sopenharmony_ci# 362162306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 362262306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 362362306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 362462306a36Sopenharmony_ci unlk %a6 362562306a36Sopenharmony_ci rts 362662306a36Sopenharmony_ci 362762306a36Sopenharmony_ci global _facosd_ 362862306a36Sopenharmony_ci_facosd_: 362962306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 363062306a36Sopenharmony_ci 363162306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 363262306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 363362306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 363462306a36Sopenharmony_ci 363562306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 363662306a36Sopenharmony_ci 363762306a36Sopenharmony_ci# 363862306a36Sopenharmony_ci# copy, convert, and tag input argument 363962306a36Sopenharmony_ci# 364062306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 364162306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 364262306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 364362306a36Sopenharmony_ci bsr.l tag # fetch operand type 364462306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 364562306a36Sopenharmony_ci mov.b %d0,%d1 364662306a36Sopenharmony_ci 364762306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 364862306a36Sopenharmony_ci 364962306a36Sopenharmony_ci clr.l %d0 365062306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 365162306a36Sopenharmony_ci 365262306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 365362306a36Sopenharmony_ci tst.b %d1 365462306a36Sopenharmony_ci bne.b _L17_2d 365562306a36Sopenharmony_ci bsr.l sacos # operand is a NORM 365662306a36Sopenharmony_ci bra.b _L17_6d 365762306a36Sopenharmony_ci_L17_2d: 365862306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 365962306a36Sopenharmony_ci bne.b _L17_3d # no 366062306a36Sopenharmony_ci bsr.l ld_ppi2 # yes 366162306a36Sopenharmony_ci bra.b _L17_6d 366262306a36Sopenharmony_ci_L17_3d: 366362306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 366462306a36Sopenharmony_ci bne.b _L17_4d # no 366562306a36Sopenharmony_ci bsr.l t_operr # yes 366662306a36Sopenharmony_ci bra.b _L17_6d 366762306a36Sopenharmony_ci_L17_4d: 366862306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 366962306a36Sopenharmony_ci bne.b _L17_5d # no 367062306a36Sopenharmony_ci bsr.l src_qnan # yes 367162306a36Sopenharmony_ci bra.b _L17_6d 367262306a36Sopenharmony_ci_L17_5d: 367362306a36Sopenharmony_ci bsr.l sacosd # operand is a DENORM 367462306a36Sopenharmony_ci_L17_6d: 367562306a36Sopenharmony_ci 367662306a36Sopenharmony_ci# 367762306a36Sopenharmony_ci# Result is now in FP0 367862306a36Sopenharmony_ci# 367962306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 368062306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 368162306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 368262306a36Sopenharmony_ci unlk %a6 368362306a36Sopenharmony_ci rts 368462306a36Sopenharmony_ci 368562306a36Sopenharmony_ci global _facosx_ 368662306a36Sopenharmony_ci_facosx_: 368762306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 368862306a36Sopenharmony_ci 368962306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 369062306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 369162306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 369262306a36Sopenharmony_ci 369362306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 369462306a36Sopenharmony_ci 369562306a36Sopenharmony_ci# 369662306a36Sopenharmony_ci# copy, convert, and tag input argument 369762306a36Sopenharmony_ci# 369862306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 369962306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 370062306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 370162306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 370262306a36Sopenharmony_ci bsr.l tag # fetch operand type 370362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 370462306a36Sopenharmony_ci mov.b %d0,%d1 370562306a36Sopenharmony_ci 370662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 370762306a36Sopenharmony_ci 370862306a36Sopenharmony_ci clr.l %d0 370962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 371062306a36Sopenharmony_ci 371162306a36Sopenharmony_ci tst.b %d1 371262306a36Sopenharmony_ci bne.b _L17_2x 371362306a36Sopenharmony_ci bsr.l sacos # operand is a NORM 371462306a36Sopenharmony_ci bra.b _L17_6x 371562306a36Sopenharmony_ci_L17_2x: 371662306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 371762306a36Sopenharmony_ci bne.b _L17_3x # no 371862306a36Sopenharmony_ci bsr.l ld_ppi2 # yes 371962306a36Sopenharmony_ci bra.b _L17_6x 372062306a36Sopenharmony_ci_L17_3x: 372162306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 372262306a36Sopenharmony_ci bne.b _L17_4x # no 372362306a36Sopenharmony_ci bsr.l t_operr # yes 372462306a36Sopenharmony_ci bra.b _L17_6x 372562306a36Sopenharmony_ci_L17_4x: 372662306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 372762306a36Sopenharmony_ci bne.b _L17_5x # no 372862306a36Sopenharmony_ci bsr.l src_qnan # yes 372962306a36Sopenharmony_ci bra.b _L17_6x 373062306a36Sopenharmony_ci_L17_5x: 373162306a36Sopenharmony_ci bsr.l sacosd # operand is a DENORM 373262306a36Sopenharmony_ci_L17_6x: 373362306a36Sopenharmony_ci 373462306a36Sopenharmony_ci# 373562306a36Sopenharmony_ci# Result is now in FP0 373662306a36Sopenharmony_ci# 373762306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 373862306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 373962306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 374062306a36Sopenharmony_ci unlk %a6 374162306a36Sopenharmony_ci rts 374262306a36Sopenharmony_ci 374362306a36Sopenharmony_ci 374462306a36Sopenharmony_ci######################################################################### 374562306a36Sopenharmony_ci# MONADIC TEMPLATE # 374662306a36Sopenharmony_ci######################################################################### 374762306a36Sopenharmony_ci global _fgetexps_ 374862306a36Sopenharmony_ci_fgetexps_: 374962306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 375062306a36Sopenharmony_ci 375162306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 375262306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 375362306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 375462306a36Sopenharmony_ci 375562306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 375662306a36Sopenharmony_ci 375762306a36Sopenharmony_ci# 375862306a36Sopenharmony_ci# copy, convert, and tag input argument 375962306a36Sopenharmony_ci# 376062306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 376162306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 376262306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 376362306a36Sopenharmony_ci bsr.l tag # fetch operand type 376462306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 376562306a36Sopenharmony_ci mov.b %d0,%d1 376662306a36Sopenharmony_ci 376762306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 376862306a36Sopenharmony_ci 376962306a36Sopenharmony_ci clr.l %d0 377062306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 377162306a36Sopenharmony_ci 377262306a36Sopenharmony_ci tst.b %d1 377362306a36Sopenharmony_ci bne.b _L18_2s 377462306a36Sopenharmony_ci bsr.l sgetexp # operand is a NORM 377562306a36Sopenharmony_ci bra.b _L18_6s 377662306a36Sopenharmony_ci_L18_2s: 377762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 377862306a36Sopenharmony_ci bne.b _L18_3s # no 377962306a36Sopenharmony_ci bsr.l src_zero # yes 378062306a36Sopenharmony_ci bra.b _L18_6s 378162306a36Sopenharmony_ci_L18_3s: 378262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 378362306a36Sopenharmony_ci bne.b _L18_4s # no 378462306a36Sopenharmony_ci bsr.l t_operr # yes 378562306a36Sopenharmony_ci bra.b _L18_6s 378662306a36Sopenharmony_ci_L18_4s: 378762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 378862306a36Sopenharmony_ci bne.b _L18_5s # no 378962306a36Sopenharmony_ci bsr.l src_qnan # yes 379062306a36Sopenharmony_ci bra.b _L18_6s 379162306a36Sopenharmony_ci_L18_5s: 379262306a36Sopenharmony_ci bsr.l sgetexpd # operand is a DENORM 379362306a36Sopenharmony_ci_L18_6s: 379462306a36Sopenharmony_ci 379562306a36Sopenharmony_ci# 379662306a36Sopenharmony_ci# Result is now in FP0 379762306a36Sopenharmony_ci# 379862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 379962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 380062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 380162306a36Sopenharmony_ci unlk %a6 380262306a36Sopenharmony_ci rts 380362306a36Sopenharmony_ci 380462306a36Sopenharmony_ci global _fgetexpd_ 380562306a36Sopenharmony_ci_fgetexpd_: 380662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 380762306a36Sopenharmony_ci 380862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 380962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 381062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 381162306a36Sopenharmony_ci 381262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 381362306a36Sopenharmony_ci 381462306a36Sopenharmony_ci# 381562306a36Sopenharmony_ci# copy, convert, and tag input argument 381662306a36Sopenharmony_ci# 381762306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 381862306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 381962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 382062306a36Sopenharmony_ci bsr.l tag # fetch operand type 382162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 382262306a36Sopenharmony_ci mov.b %d0,%d1 382362306a36Sopenharmony_ci 382462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 382562306a36Sopenharmony_ci 382662306a36Sopenharmony_ci clr.l %d0 382762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 382862306a36Sopenharmony_ci 382962306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 383062306a36Sopenharmony_ci tst.b %d1 383162306a36Sopenharmony_ci bne.b _L18_2d 383262306a36Sopenharmony_ci bsr.l sgetexp # operand is a NORM 383362306a36Sopenharmony_ci bra.b _L18_6d 383462306a36Sopenharmony_ci_L18_2d: 383562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 383662306a36Sopenharmony_ci bne.b _L18_3d # no 383762306a36Sopenharmony_ci bsr.l src_zero # yes 383862306a36Sopenharmony_ci bra.b _L18_6d 383962306a36Sopenharmony_ci_L18_3d: 384062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 384162306a36Sopenharmony_ci bne.b _L18_4d # no 384262306a36Sopenharmony_ci bsr.l t_operr # yes 384362306a36Sopenharmony_ci bra.b _L18_6d 384462306a36Sopenharmony_ci_L18_4d: 384562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 384662306a36Sopenharmony_ci bne.b _L18_5d # no 384762306a36Sopenharmony_ci bsr.l src_qnan # yes 384862306a36Sopenharmony_ci bra.b _L18_6d 384962306a36Sopenharmony_ci_L18_5d: 385062306a36Sopenharmony_ci bsr.l sgetexpd # operand is a DENORM 385162306a36Sopenharmony_ci_L18_6d: 385262306a36Sopenharmony_ci 385362306a36Sopenharmony_ci# 385462306a36Sopenharmony_ci# Result is now in FP0 385562306a36Sopenharmony_ci# 385662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 385762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 385862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 385962306a36Sopenharmony_ci unlk %a6 386062306a36Sopenharmony_ci rts 386162306a36Sopenharmony_ci 386262306a36Sopenharmony_ci global _fgetexpx_ 386362306a36Sopenharmony_ci_fgetexpx_: 386462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 386562306a36Sopenharmony_ci 386662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 386762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 386862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 386962306a36Sopenharmony_ci 387062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 387162306a36Sopenharmony_ci 387262306a36Sopenharmony_ci# 387362306a36Sopenharmony_ci# copy, convert, and tag input argument 387462306a36Sopenharmony_ci# 387562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 387662306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 387762306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 387862306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 387962306a36Sopenharmony_ci bsr.l tag # fetch operand type 388062306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 388162306a36Sopenharmony_ci mov.b %d0,%d1 388262306a36Sopenharmony_ci 388362306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 388462306a36Sopenharmony_ci 388562306a36Sopenharmony_ci clr.l %d0 388662306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci tst.b %d1 388962306a36Sopenharmony_ci bne.b _L18_2x 389062306a36Sopenharmony_ci bsr.l sgetexp # operand is a NORM 389162306a36Sopenharmony_ci bra.b _L18_6x 389262306a36Sopenharmony_ci_L18_2x: 389362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 389462306a36Sopenharmony_ci bne.b _L18_3x # no 389562306a36Sopenharmony_ci bsr.l src_zero # yes 389662306a36Sopenharmony_ci bra.b _L18_6x 389762306a36Sopenharmony_ci_L18_3x: 389862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 389962306a36Sopenharmony_ci bne.b _L18_4x # no 390062306a36Sopenharmony_ci bsr.l t_operr # yes 390162306a36Sopenharmony_ci bra.b _L18_6x 390262306a36Sopenharmony_ci_L18_4x: 390362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 390462306a36Sopenharmony_ci bne.b _L18_5x # no 390562306a36Sopenharmony_ci bsr.l src_qnan # yes 390662306a36Sopenharmony_ci bra.b _L18_6x 390762306a36Sopenharmony_ci_L18_5x: 390862306a36Sopenharmony_ci bsr.l sgetexpd # operand is a DENORM 390962306a36Sopenharmony_ci_L18_6x: 391062306a36Sopenharmony_ci 391162306a36Sopenharmony_ci# 391262306a36Sopenharmony_ci# Result is now in FP0 391362306a36Sopenharmony_ci# 391462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 391562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 391662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 391762306a36Sopenharmony_ci unlk %a6 391862306a36Sopenharmony_ci rts 391962306a36Sopenharmony_ci 392062306a36Sopenharmony_ci 392162306a36Sopenharmony_ci######################################################################### 392262306a36Sopenharmony_ci# MONADIC TEMPLATE # 392362306a36Sopenharmony_ci######################################################################### 392462306a36Sopenharmony_ci global _fgetmans_ 392562306a36Sopenharmony_ci_fgetmans_: 392662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 392762306a36Sopenharmony_ci 392862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 392962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 393062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 393162306a36Sopenharmony_ci 393262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 393362306a36Sopenharmony_ci 393462306a36Sopenharmony_ci# 393562306a36Sopenharmony_ci# copy, convert, and tag input argument 393662306a36Sopenharmony_ci# 393762306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 393862306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 393962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 394062306a36Sopenharmony_ci bsr.l tag # fetch operand type 394162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 394262306a36Sopenharmony_ci mov.b %d0,%d1 394362306a36Sopenharmony_ci 394462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 394562306a36Sopenharmony_ci 394662306a36Sopenharmony_ci clr.l %d0 394762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 394862306a36Sopenharmony_ci 394962306a36Sopenharmony_ci tst.b %d1 395062306a36Sopenharmony_ci bne.b _L19_2s 395162306a36Sopenharmony_ci bsr.l sgetman # operand is a NORM 395262306a36Sopenharmony_ci bra.b _L19_6s 395362306a36Sopenharmony_ci_L19_2s: 395462306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 395562306a36Sopenharmony_ci bne.b _L19_3s # no 395662306a36Sopenharmony_ci bsr.l src_zero # yes 395762306a36Sopenharmony_ci bra.b _L19_6s 395862306a36Sopenharmony_ci_L19_3s: 395962306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 396062306a36Sopenharmony_ci bne.b _L19_4s # no 396162306a36Sopenharmony_ci bsr.l t_operr # yes 396262306a36Sopenharmony_ci bra.b _L19_6s 396362306a36Sopenharmony_ci_L19_4s: 396462306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 396562306a36Sopenharmony_ci bne.b _L19_5s # no 396662306a36Sopenharmony_ci bsr.l src_qnan # yes 396762306a36Sopenharmony_ci bra.b _L19_6s 396862306a36Sopenharmony_ci_L19_5s: 396962306a36Sopenharmony_ci bsr.l sgetmand # operand is a DENORM 397062306a36Sopenharmony_ci_L19_6s: 397162306a36Sopenharmony_ci 397262306a36Sopenharmony_ci# 397362306a36Sopenharmony_ci# Result is now in FP0 397462306a36Sopenharmony_ci# 397562306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 397662306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 397762306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 397862306a36Sopenharmony_ci unlk %a6 397962306a36Sopenharmony_ci rts 398062306a36Sopenharmony_ci 398162306a36Sopenharmony_ci global _fgetmand_ 398262306a36Sopenharmony_ci_fgetmand_: 398362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 398462306a36Sopenharmony_ci 398562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 398662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 398762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 398862306a36Sopenharmony_ci 398962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 399062306a36Sopenharmony_ci 399162306a36Sopenharmony_ci# 399262306a36Sopenharmony_ci# copy, convert, and tag input argument 399362306a36Sopenharmony_ci# 399462306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 399562306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 399662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 399762306a36Sopenharmony_ci bsr.l tag # fetch operand type 399862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 399962306a36Sopenharmony_ci mov.b %d0,%d1 400062306a36Sopenharmony_ci 400162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 400262306a36Sopenharmony_ci 400362306a36Sopenharmony_ci clr.l %d0 400462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 400562306a36Sopenharmony_ci 400662306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 400762306a36Sopenharmony_ci tst.b %d1 400862306a36Sopenharmony_ci bne.b _L19_2d 400962306a36Sopenharmony_ci bsr.l sgetman # operand is a NORM 401062306a36Sopenharmony_ci bra.b _L19_6d 401162306a36Sopenharmony_ci_L19_2d: 401262306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 401362306a36Sopenharmony_ci bne.b _L19_3d # no 401462306a36Sopenharmony_ci bsr.l src_zero # yes 401562306a36Sopenharmony_ci bra.b _L19_6d 401662306a36Sopenharmony_ci_L19_3d: 401762306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 401862306a36Sopenharmony_ci bne.b _L19_4d # no 401962306a36Sopenharmony_ci bsr.l t_operr # yes 402062306a36Sopenharmony_ci bra.b _L19_6d 402162306a36Sopenharmony_ci_L19_4d: 402262306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 402362306a36Sopenharmony_ci bne.b _L19_5d # no 402462306a36Sopenharmony_ci bsr.l src_qnan # yes 402562306a36Sopenharmony_ci bra.b _L19_6d 402662306a36Sopenharmony_ci_L19_5d: 402762306a36Sopenharmony_ci bsr.l sgetmand # operand is a DENORM 402862306a36Sopenharmony_ci_L19_6d: 402962306a36Sopenharmony_ci 403062306a36Sopenharmony_ci# 403162306a36Sopenharmony_ci# Result is now in FP0 403262306a36Sopenharmony_ci# 403362306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 403462306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 403562306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 403662306a36Sopenharmony_ci unlk %a6 403762306a36Sopenharmony_ci rts 403862306a36Sopenharmony_ci 403962306a36Sopenharmony_ci global _fgetmanx_ 404062306a36Sopenharmony_ci_fgetmanx_: 404162306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 404262306a36Sopenharmony_ci 404362306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 404462306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 404562306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 404662306a36Sopenharmony_ci 404762306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 404862306a36Sopenharmony_ci 404962306a36Sopenharmony_ci# 405062306a36Sopenharmony_ci# copy, convert, and tag input argument 405162306a36Sopenharmony_ci# 405262306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 405362306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 405462306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 405562306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 405662306a36Sopenharmony_ci bsr.l tag # fetch operand type 405762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 405862306a36Sopenharmony_ci mov.b %d0,%d1 405962306a36Sopenharmony_ci 406062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 406162306a36Sopenharmony_ci 406262306a36Sopenharmony_ci clr.l %d0 406362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 406462306a36Sopenharmony_ci 406562306a36Sopenharmony_ci tst.b %d1 406662306a36Sopenharmony_ci bne.b _L19_2x 406762306a36Sopenharmony_ci bsr.l sgetman # operand is a NORM 406862306a36Sopenharmony_ci bra.b _L19_6x 406962306a36Sopenharmony_ci_L19_2x: 407062306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 407162306a36Sopenharmony_ci bne.b _L19_3x # no 407262306a36Sopenharmony_ci bsr.l src_zero # yes 407362306a36Sopenharmony_ci bra.b _L19_6x 407462306a36Sopenharmony_ci_L19_3x: 407562306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 407662306a36Sopenharmony_ci bne.b _L19_4x # no 407762306a36Sopenharmony_ci bsr.l t_operr # yes 407862306a36Sopenharmony_ci bra.b _L19_6x 407962306a36Sopenharmony_ci_L19_4x: 408062306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 408162306a36Sopenharmony_ci bne.b _L19_5x # no 408262306a36Sopenharmony_ci bsr.l src_qnan # yes 408362306a36Sopenharmony_ci bra.b _L19_6x 408462306a36Sopenharmony_ci_L19_5x: 408562306a36Sopenharmony_ci bsr.l sgetmand # operand is a DENORM 408662306a36Sopenharmony_ci_L19_6x: 408762306a36Sopenharmony_ci 408862306a36Sopenharmony_ci# 408962306a36Sopenharmony_ci# Result is now in FP0 409062306a36Sopenharmony_ci# 409162306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 409262306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 409362306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 409462306a36Sopenharmony_ci unlk %a6 409562306a36Sopenharmony_ci rts 409662306a36Sopenharmony_ci 409762306a36Sopenharmony_ci 409862306a36Sopenharmony_ci######################################################################### 409962306a36Sopenharmony_ci# MONADIC TEMPLATE # 410062306a36Sopenharmony_ci######################################################################### 410162306a36Sopenharmony_ci global _fsincoss_ 410262306a36Sopenharmony_ci_fsincoss_: 410362306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 410462306a36Sopenharmony_ci 410562306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 410662306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 410762306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 410862306a36Sopenharmony_ci 410962306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 411062306a36Sopenharmony_ci 411162306a36Sopenharmony_ci# 411262306a36Sopenharmony_ci# copy, convert, and tag input argument 411362306a36Sopenharmony_ci# 411462306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl input 411562306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 411662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 411762306a36Sopenharmony_ci bsr.l tag # fetch operand type 411862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 411962306a36Sopenharmony_ci mov.b %d0,%d1 412062306a36Sopenharmony_ci 412162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 412262306a36Sopenharmony_ci 412362306a36Sopenharmony_ci clr.l %d0 412462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 412562306a36Sopenharmony_ci 412662306a36Sopenharmony_ci tst.b %d1 412762306a36Sopenharmony_ci bne.b _L20_2s 412862306a36Sopenharmony_ci bsr.l ssincos # operand is a NORM 412962306a36Sopenharmony_ci bra.b _L20_6s 413062306a36Sopenharmony_ci_L20_2s: 413162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 413262306a36Sopenharmony_ci bne.b _L20_3s # no 413362306a36Sopenharmony_ci bsr.l ssincosz # yes 413462306a36Sopenharmony_ci bra.b _L20_6s 413562306a36Sopenharmony_ci_L20_3s: 413662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 413762306a36Sopenharmony_ci bne.b _L20_4s # no 413862306a36Sopenharmony_ci bsr.l ssincosi # yes 413962306a36Sopenharmony_ci bra.b _L20_6s 414062306a36Sopenharmony_ci_L20_4s: 414162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 414262306a36Sopenharmony_ci bne.b _L20_5s # no 414362306a36Sopenharmony_ci bsr.l ssincosqnan # yes 414462306a36Sopenharmony_ci bra.b _L20_6s 414562306a36Sopenharmony_ci_L20_5s: 414662306a36Sopenharmony_ci bsr.l ssincosd # operand is a DENORM 414762306a36Sopenharmony_ci_L20_6s: 414862306a36Sopenharmony_ci 414962306a36Sopenharmony_ci# 415062306a36Sopenharmony_ci# Result is now in FP0 415162306a36Sopenharmony_ci# 415262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 415362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 415462306a36Sopenharmony_ci fmovm.x &0x03,-(%sp) # store off fp0/fp1 415562306a36Sopenharmony_ci fmovm.x (%sp)+,&0x40 # fp0 now in fp1 415662306a36Sopenharmony_ci fmovm.x (%sp)+,&0x80 # fp1 now in fp0 415762306a36Sopenharmony_ci unlk %a6 415862306a36Sopenharmony_ci rts 415962306a36Sopenharmony_ci 416062306a36Sopenharmony_ci global _fsincosd_ 416162306a36Sopenharmony_ci_fsincosd_: 416262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 416362306a36Sopenharmony_ci 416462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 416562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 416662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 416762306a36Sopenharmony_ci 416862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 416962306a36Sopenharmony_ci 417062306a36Sopenharmony_ci# 417162306a36Sopenharmony_ci# copy, convert, and tag input argument 417262306a36Sopenharmony_ci# 417362306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl input 417462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 417562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 417662306a36Sopenharmony_ci bsr.l tag # fetch operand type 417762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 417862306a36Sopenharmony_ci mov.b %d0,%d1 417962306a36Sopenharmony_ci 418062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 418162306a36Sopenharmony_ci 418262306a36Sopenharmony_ci clr.l %d0 418362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 418462306a36Sopenharmony_ci 418562306a36Sopenharmony_ci mov.b %d1,STAG(%a6) 418662306a36Sopenharmony_ci tst.b %d1 418762306a36Sopenharmony_ci bne.b _L20_2d 418862306a36Sopenharmony_ci bsr.l ssincos # operand is a NORM 418962306a36Sopenharmony_ci bra.b _L20_6d 419062306a36Sopenharmony_ci_L20_2d: 419162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 419262306a36Sopenharmony_ci bne.b _L20_3d # no 419362306a36Sopenharmony_ci bsr.l ssincosz # yes 419462306a36Sopenharmony_ci bra.b _L20_6d 419562306a36Sopenharmony_ci_L20_3d: 419662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 419762306a36Sopenharmony_ci bne.b _L20_4d # no 419862306a36Sopenharmony_ci bsr.l ssincosi # yes 419962306a36Sopenharmony_ci bra.b _L20_6d 420062306a36Sopenharmony_ci_L20_4d: 420162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 420262306a36Sopenharmony_ci bne.b _L20_5d # no 420362306a36Sopenharmony_ci bsr.l ssincosqnan # yes 420462306a36Sopenharmony_ci bra.b _L20_6d 420562306a36Sopenharmony_ci_L20_5d: 420662306a36Sopenharmony_ci bsr.l ssincosd # operand is a DENORM 420762306a36Sopenharmony_ci_L20_6d: 420862306a36Sopenharmony_ci 420962306a36Sopenharmony_ci# 421062306a36Sopenharmony_ci# Result is now in FP0 421162306a36Sopenharmony_ci# 421262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 421362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 421462306a36Sopenharmony_ci fmovm.x &0x03,-(%sp) # store off fp0/fp1 421562306a36Sopenharmony_ci fmovm.x (%sp)+,&0x40 # fp0 now in fp1 421662306a36Sopenharmony_ci fmovm.x (%sp)+,&0x80 # fp1 now in fp0 421762306a36Sopenharmony_ci unlk %a6 421862306a36Sopenharmony_ci rts 421962306a36Sopenharmony_ci 422062306a36Sopenharmony_ci global _fsincosx_ 422162306a36Sopenharmony_ci_fsincosx_: 422262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 422362306a36Sopenharmony_ci 422462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 422562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 422662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 422762306a36Sopenharmony_ci 422862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 422962306a36Sopenharmony_ci 423062306a36Sopenharmony_ci# 423162306a36Sopenharmony_ci# copy, convert, and tag input argument 423262306a36Sopenharmony_ci# 423362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 423462306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input 423562306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 423662306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 423762306a36Sopenharmony_ci bsr.l tag # fetch operand type 423862306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 423962306a36Sopenharmony_ci mov.b %d0,%d1 424062306a36Sopenharmony_ci 424162306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 424262306a36Sopenharmony_ci 424362306a36Sopenharmony_ci clr.l %d0 424462306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 424562306a36Sopenharmony_ci 424662306a36Sopenharmony_ci tst.b %d1 424762306a36Sopenharmony_ci bne.b _L20_2x 424862306a36Sopenharmony_ci bsr.l ssincos # operand is a NORM 424962306a36Sopenharmony_ci bra.b _L20_6x 425062306a36Sopenharmony_ci_L20_2x: 425162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 425262306a36Sopenharmony_ci bne.b _L20_3x # no 425362306a36Sopenharmony_ci bsr.l ssincosz # yes 425462306a36Sopenharmony_ci bra.b _L20_6x 425562306a36Sopenharmony_ci_L20_3x: 425662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 425762306a36Sopenharmony_ci bne.b _L20_4x # no 425862306a36Sopenharmony_ci bsr.l ssincosi # yes 425962306a36Sopenharmony_ci bra.b _L20_6x 426062306a36Sopenharmony_ci_L20_4x: 426162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 426262306a36Sopenharmony_ci bne.b _L20_5x # no 426362306a36Sopenharmony_ci bsr.l ssincosqnan # yes 426462306a36Sopenharmony_ci bra.b _L20_6x 426562306a36Sopenharmony_ci_L20_5x: 426662306a36Sopenharmony_ci bsr.l ssincosd # operand is a DENORM 426762306a36Sopenharmony_ci_L20_6x: 426862306a36Sopenharmony_ci 426962306a36Sopenharmony_ci# 427062306a36Sopenharmony_ci# Result is now in FP0 427162306a36Sopenharmony_ci# 427262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 427362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 427462306a36Sopenharmony_ci fmovm.x &0x03,-(%sp) # store off fp0/fp1 427562306a36Sopenharmony_ci fmovm.x (%sp)+,&0x40 # fp0 now in fp1 427662306a36Sopenharmony_ci fmovm.x (%sp)+,&0x80 # fp1 now in fp0 427762306a36Sopenharmony_ci unlk %a6 427862306a36Sopenharmony_ci rts 427962306a36Sopenharmony_ci 428062306a36Sopenharmony_ci 428162306a36Sopenharmony_ci######################################################################### 428262306a36Sopenharmony_ci# DYADIC TEMPLATE # 428362306a36Sopenharmony_ci######################################################################### 428462306a36Sopenharmony_ci global _frems_ 428562306a36Sopenharmony_ci_frems_: 428662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 428762306a36Sopenharmony_ci 428862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 428962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 429062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 429162306a36Sopenharmony_ci 429262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 429362306a36Sopenharmony_ci 429462306a36Sopenharmony_ci# 429562306a36Sopenharmony_ci# copy, convert, and tag input argument 429662306a36Sopenharmony_ci# 429762306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl dst 429862306a36Sopenharmony_ci fmov.x %fp0,FP_DST(%a6) 429962306a36Sopenharmony_ci lea FP_DST(%a6),%a0 430062306a36Sopenharmony_ci bsr.l tag # fetch operand type 430162306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 430262306a36Sopenharmony_ci 430362306a36Sopenharmony_ci fmov.s 0xc(%a6),%fp0 # load sgl src 430462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 430562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 430662306a36Sopenharmony_ci bsr.l tag # fetch operand type 430762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 430862306a36Sopenharmony_ci mov.l %d0,%d1 430962306a36Sopenharmony_ci 431062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 431162306a36Sopenharmony_ci 431262306a36Sopenharmony_ci clr.l %d0 431362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 431462306a36Sopenharmony_ci 431562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 431662306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 431762306a36Sopenharmony_ci 431862306a36Sopenharmony_ci tst.b %d1 431962306a36Sopenharmony_ci bne.b _L21_2s 432062306a36Sopenharmony_ci bsr.l srem_snorm # operand is a NORM 432162306a36Sopenharmony_ci bra.b _L21_6s 432262306a36Sopenharmony_ci_L21_2s: 432362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 432462306a36Sopenharmony_ci bne.b _L21_3s # no 432562306a36Sopenharmony_ci bsr.l srem_szero # yes 432662306a36Sopenharmony_ci bra.b _L21_6s 432762306a36Sopenharmony_ci_L21_3s: 432862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 432962306a36Sopenharmony_ci bne.b _L21_4s # no 433062306a36Sopenharmony_ci bsr.l srem_sinf # yes 433162306a36Sopenharmony_ci bra.b _L21_6s 433262306a36Sopenharmony_ci_L21_4s: 433362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 433462306a36Sopenharmony_ci bne.b _L21_5s # no 433562306a36Sopenharmony_ci bsr.l sop_sqnan # yes 433662306a36Sopenharmony_ci bra.b _L21_6s 433762306a36Sopenharmony_ci_L21_5s: 433862306a36Sopenharmony_ci bsr.l srem_sdnrm # operand is a DENORM 433962306a36Sopenharmony_ci_L21_6s: 434062306a36Sopenharmony_ci 434162306a36Sopenharmony_ci# 434262306a36Sopenharmony_ci# Result is now in FP0 434362306a36Sopenharmony_ci# 434462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 434562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 434662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 434762306a36Sopenharmony_ci unlk %a6 434862306a36Sopenharmony_ci rts 434962306a36Sopenharmony_ci 435062306a36Sopenharmony_ci global _fremd_ 435162306a36Sopenharmony_ci_fremd_: 435262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 435362306a36Sopenharmony_ci 435462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 435562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 435662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 435762306a36Sopenharmony_ci 435862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 435962306a36Sopenharmony_ci 436062306a36Sopenharmony_ci# 436162306a36Sopenharmony_ci# copy, convert, and tag input argument 436262306a36Sopenharmony_ci# 436362306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl dst 436462306a36Sopenharmony_ci fmov.x %fp0,FP_DST(%a6) 436562306a36Sopenharmony_ci lea FP_DST(%a6),%a0 436662306a36Sopenharmony_ci bsr.l tag # fetch operand type 436762306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 436862306a36Sopenharmony_ci 436962306a36Sopenharmony_ci fmov.d 0x10(%a6),%fp0 # load dbl src 437062306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 437162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 437262306a36Sopenharmony_ci bsr.l tag # fetch operand type 437362306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 437462306a36Sopenharmony_ci mov.l %d0,%d1 437562306a36Sopenharmony_ci 437662306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 437762306a36Sopenharmony_ci 437862306a36Sopenharmony_ci clr.l %d0 437962306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 438062306a36Sopenharmony_ci 438162306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 438262306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 438362306a36Sopenharmony_ci 438462306a36Sopenharmony_ci tst.b %d1 438562306a36Sopenharmony_ci bne.b _L21_2d 438662306a36Sopenharmony_ci bsr.l srem_snorm # operand is a NORM 438762306a36Sopenharmony_ci bra.b _L21_6d 438862306a36Sopenharmony_ci_L21_2d: 438962306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 439062306a36Sopenharmony_ci bne.b _L21_3d # no 439162306a36Sopenharmony_ci bsr.l srem_szero # yes 439262306a36Sopenharmony_ci bra.b _L21_6d 439362306a36Sopenharmony_ci_L21_3d: 439462306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 439562306a36Sopenharmony_ci bne.b _L21_4d # no 439662306a36Sopenharmony_ci bsr.l srem_sinf # yes 439762306a36Sopenharmony_ci bra.b _L21_6d 439862306a36Sopenharmony_ci_L21_4d: 439962306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 440062306a36Sopenharmony_ci bne.b _L21_5d # no 440162306a36Sopenharmony_ci bsr.l sop_sqnan # yes 440262306a36Sopenharmony_ci bra.b _L21_6d 440362306a36Sopenharmony_ci_L21_5d: 440462306a36Sopenharmony_ci bsr.l srem_sdnrm # operand is a DENORM 440562306a36Sopenharmony_ci_L21_6d: 440662306a36Sopenharmony_ci 440762306a36Sopenharmony_ci# 440862306a36Sopenharmony_ci# Result is now in FP0 440962306a36Sopenharmony_ci# 441062306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 441162306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 441262306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 441362306a36Sopenharmony_ci unlk %a6 441462306a36Sopenharmony_ci rts 441562306a36Sopenharmony_ci 441662306a36Sopenharmony_ci global _fremx_ 441762306a36Sopenharmony_ci_fremx_: 441862306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 441962306a36Sopenharmony_ci 442062306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 442162306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 442262306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 442362306a36Sopenharmony_ci 442462306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 442562306a36Sopenharmony_ci 442662306a36Sopenharmony_ci# 442762306a36Sopenharmony_ci# copy, convert, and tag input argument 442862306a36Sopenharmony_ci# 442962306a36Sopenharmony_ci lea FP_DST(%a6),%a0 443062306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 443162306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 443262306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 443362306a36Sopenharmony_ci bsr.l tag # fetch operand type 443462306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 443562306a36Sopenharmony_ci 443662306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 443762306a36Sopenharmony_ci mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 443862306a36Sopenharmony_ci mov.l 0x14+0x4(%a6),0x4(%a0) 443962306a36Sopenharmony_ci mov.l 0x14+0x8(%a6),0x8(%a0) 444062306a36Sopenharmony_ci bsr.l tag # fetch operand type 444162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 444262306a36Sopenharmony_ci mov.l %d0,%d1 444362306a36Sopenharmony_ci 444462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 444562306a36Sopenharmony_ci 444662306a36Sopenharmony_ci clr.l %d0 444762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 444862306a36Sopenharmony_ci 444962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 445062306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 445162306a36Sopenharmony_ci 445262306a36Sopenharmony_ci tst.b %d1 445362306a36Sopenharmony_ci bne.b _L21_2x 445462306a36Sopenharmony_ci bsr.l srem_snorm # operand is a NORM 445562306a36Sopenharmony_ci bra.b _L21_6x 445662306a36Sopenharmony_ci_L21_2x: 445762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 445862306a36Sopenharmony_ci bne.b _L21_3x # no 445962306a36Sopenharmony_ci bsr.l srem_szero # yes 446062306a36Sopenharmony_ci bra.b _L21_6x 446162306a36Sopenharmony_ci_L21_3x: 446262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 446362306a36Sopenharmony_ci bne.b _L21_4x # no 446462306a36Sopenharmony_ci bsr.l srem_sinf # yes 446562306a36Sopenharmony_ci bra.b _L21_6x 446662306a36Sopenharmony_ci_L21_4x: 446762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 446862306a36Sopenharmony_ci bne.b _L21_5x # no 446962306a36Sopenharmony_ci bsr.l sop_sqnan # yes 447062306a36Sopenharmony_ci bra.b _L21_6x 447162306a36Sopenharmony_ci_L21_5x: 447262306a36Sopenharmony_ci bsr.l srem_sdnrm # operand is a DENORM 447362306a36Sopenharmony_ci_L21_6x: 447462306a36Sopenharmony_ci 447562306a36Sopenharmony_ci# 447662306a36Sopenharmony_ci# Result is now in FP0 447762306a36Sopenharmony_ci# 447862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 447962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 448062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 448162306a36Sopenharmony_ci unlk %a6 448262306a36Sopenharmony_ci rts 448362306a36Sopenharmony_ci 448462306a36Sopenharmony_ci 448562306a36Sopenharmony_ci######################################################################### 448662306a36Sopenharmony_ci# DYADIC TEMPLATE # 448762306a36Sopenharmony_ci######################################################################### 448862306a36Sopenharmony_ci global _fmods_ 448962306a36Sopenharmony_ci_fmods_: 449062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 449162306a36Sopenharmony_ci 449262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 449362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 449462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 449562306a36Sopenharmony_ci 449662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 449762306a36Sopenharmony_ci 449862306a36Sopenharmony_ci# 449962306a36Sopenharmony_ci# copy, convert, and tag input argument 450062306a36Sopenharmony_ci# 450162306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl dst 450262306a36Sopenharmony_ci fmov.x %fp0,FP_DST(%a6) 450362306a36Sopenharmony_ci lea FP_DST(%a6),%a0 450462306a36Sopenharmony_ci bsr.l tag # fetch operand type 450562306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 450662306a36Sopenharmony_ci 450762306a36Sopenharmony_ci fmov.s 0xc(%a6),%fp0 # load sgl src 450862306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 450962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 451062306a36Sopenharmony_ci bsr.l tag # fetch operand type 451162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 451262306a36Sopenharmony_ci mov.l %d0,%d1 451362306a36Sopenharmony_ci 451462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 451562306a36Sopenharmony_ci 451662306a36Sopenharmony_ci clr.l %d0 451762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 451862306a36Sopenharmony_ci 451962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 452062306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 452162306a36Sopenharmony_ci 452262306a36Sopenharmony_ci tst.b %d1 452362306a36Sopenharmony_ci bne.b _L22_2s 452462306a36Sopenharmony_ci bsr.l smod_snorm # operand is a NORM 452562306a36Sopenharmony_ci bra.b _L22_6s 452662306a36Sopenharmony_ci_L22_2s: 452762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 452862306a36Sopenharmony_ci bne.b _L22_3s # no 452962306a36Sopenharmony_ci bsr.l smod_szero # yes 453062306a36Sopenharmony_ci bra.b _L22_6s 453162306a36Sopenharmony_ci_L22_3s: 453262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 453362306a36Sopenharmony_ci bne.b _L22_4s # no 453462306a36Sopenharmony_ci bsr.l smod_sinf # yes 453562306a36Sopenharmony_ci bra.b _L22_6s 453662306a36Sopenharmony_ci_L22_4s: 453762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 453862306a36Sopenharmony_ci bne.b _L22_5s # no 453962306a36Sopenharmony_ci bsr.l sop_sqnan # yes 454062306a36Sopenharmony_ci bra.b _L22_6s 454162306a36Sopenharmony_ci_L22_5s: 454262306a36Sopenharmony_ci bsr.l smod_sdnrm # operand is a DENORM 454362306a36Sopenharmony_ci_L22_6s: 454462306a36Sopenharmony_ci 454562306a36Sopenharmony_ci# 454662306a36Sopenharmony_ci# Result is now in FP0 454762306a36Sopenharmony_ci# 454862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 454962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 455062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 455162306a36Sopenharmony_ci unlk %a6 455262306a36Sopenharmony_ci rts 455362306a36Sopenharmony_ci 455462306a36Sopenharmony_ci global _fmodd_ 455562306a36Sopenharmony_ci_fmodd_: 455662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 455762306a36Sopenharmony_ci 455862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 455962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 456062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 456162306a36Sopenharmony_ci 456262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 456362306a36Sopenharmony_ci 456462306a36Sopenharmony_ci# 456562306a36Sopenharmony_ci# copy, convert, and tag input argument 456662306a36Sopenharmony_ci# 456762306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl dst 456862306a36Sopenharmony_ci fmov.x %fp0,FP_DST(%a6) 456962306a36Sopenharmony_ci lea FP_DST(%a6),%a0 457062306a36Sopenharmony_ci bsr.l tag # fetch operand type 457162306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 457262306a36Sopenharmony_ci 457362306a36Sopenharmony_ci fmov.d 0x10(%a6),%fp0 # load dbl src 457462306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 457562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 457662306a36Sopenharmony_ci bsr.l tag # fetch operand type 457762306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 457862306a36Sopenharmony_ci mov.l %d0,%d1 457962306a36Sopenharmony_ci 458062306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 458162306a36Sopenharmony_ci 458262306a36Sopenharmony_ci clr.l %d0 458362306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 458462306a36Sopenharmony_ci 458562306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 458662306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 458762306a36Sopenharmony_ci 458862306a36Sopenharmony_ci tst.b %d1 458962306a36Sopenharmony_ci bne.b _L22_2d 459062306a36Sopenharmony_ci bsr.l smod_snorm # operand is a NORM 459162306a36Sopenharmony_ci bra.b _L22_6d 459262306a36Sopenharmony_ci_L22_2d: 459362306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 459462306a36Sopenharmony_ci bne.b _L22_3d # no 459562306a36Sopenharmony_ci bsr.l smod_szero # yes 459662306a36Sopenharmony_ci bra.b _L22_6d 459762306a36Sopenharmony_ci_L22_3d: 459862306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 459962306a36Sopenharmony_ci bne.b _L22_4d # no 460062306a36Sopenharmony_ci bsr.l smod_sinf # yes 460162306a36Sopenharmony_ci bra.b _L22_6d 460262306a36Sopenharmony_ci_L22_4d: 460362306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 460462306a36Sopenharmony_ci bne.b _L22_5d # no 460562306a36Sopenharmony_ci bsr.l sop_sqnan # yes 460662306a36Sopenharmony_ci bra.b _L22_6d 460762306a36Sopenharmony_ci_L22_5d: 460862306a36Sopenharmony_ci bsr.l smod_sdnrm # operand is a DENORM 460962306a36Sopenharmony_ci_L22_6d: 461062306a36Sopenharmony_ci 461162306a36Sopenharmony_ci# 461262306a36Sopenharmony_ci# Result is now in FP0 461362306a36Sopenharmony_ci# 461462306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 461562306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 461662306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 461762306a36Sopenharmony_ci unlk %a6 461862306a36Sopenharmony_ci rts 461962306a36Sopenharmony_ci 462062306a36Sopenharmony_ci global _fmodx_ 462162306a36Sopenharmony_ci_fmodx_: 462262306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 462362306a36Sopenharmony_ci 462462306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 462562306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 462662306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 462762306a36Sopenharmony_ci 462862306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 462962306a36Sopenharmony_ci 463062306a36Sopenharmony_ci# 463162306a36Sopenharmony_ci# copy, convert, and tag input argument 463262306a36Sopenharmony_ci# 463362306a36Sopenharmony_ci lea FP_DST(%a6),%a0 463462306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 463562306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 463662306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 463762306a36Sopenharmony_ci bsr.l tag # fetch operand type 463862306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 463962306a36Sopenharmony_ci 464062306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 464162306a36Sopenharmony_ci mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 464262306a36Sopenharmony_ci mov.l 0x14+0x4(%a6),0x4(%a0) 464362306a36Sopenharmony_ci mov.l 0x14+0x8(%a6),0x8(%a0) 464462306a36Sopenharmony_ci bsr.l tag # fetch operand type 464562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 464662306a36Sopenharmony_ci mov.l %d0,%d1 464762306a36Sopenharmony_ci 464862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 464962306a36Sopenharmony_ci 465062306a36Sopenharmony_ci clr.l %d0 465162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 465262306a36Sopenharmony_ci 465362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 465462306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 465562306a36Sopenharmony_ci 465662306a36Sopenharmony_ci tst.b %d1 465762306a36Sopenharmony_ci bne.b _L22_2x 465862306a36Sopenharmony_ci bsr.l smod_snorm # operand is a NORM 465962306a36Sopenharmony_ci bra.b _L22_6x 466062306a36Sopenharmony_ci_L22_2x: 466162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 466262306a36Sopenharmony_ci bne.b _L22_3x # no 466362306a36Sopenharmony_ci bsr.l smod_szero # yes 466462306a36Sopenharmony_ci bra.b _L22_6x 466562306a36Sopenharmony_ci_L22_3x: 466662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 466762306a36Sopenharmony_ci bne.b _L22_4x # no 466862306a36Sopenharmony_ci bsr.l smod_sinf # yes 466962306a36Sopenharmony_ci bra.b _L22_6x 467062306a36Sopenharmony_ci_L22_4x: 467162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 467262306a36Sopenharmony_ci bne.b _L22_5x # no 467362306a36Sopenharmony_ci bsr.l sop_sqnan # yes 467462306a36Sopenharmony_ci bra.b _L22_6x 467562306a36Sopenharmony_ci_L22_5x: 467662306a36Sopenharmony_ci bsr.l smod_sdnrm # operand is a DENORM 467762306a36Sopenharmony_ci_L22_6x: 467862306a36Sopenharmony_ci 467962306a36Sopenharmony_ci# 468062306a36Sopenharmony_ci# Result is now in FP0 468162306a36Sopenharmony_ci# 468262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 468362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 468462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 468562306a36Sopenharmony_ci unlk %a6 468662306a36Sopenharmony_ci rts 468762306a36Sopenharmony_ci 468862306a36Sopenharmony_ci 468962306a36Sopenharmony_ci######################################################################### 469062306a36Sopenharmony_ci# DYADIC TEMPLATE # 469162306a36Sopenharmony_ci######################################################################### 469262306a36Sopenharmony_ci global _fscales_ 469362306a36Sopenharmony_ci_fscales_: 469462306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 469562306a36Sopenharmony_ci 469662306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 469762306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 469862306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 469962306a36Sopenharmony_ci 470062306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 470162306a36Sopenharmony_ci 470262306a36Sopenharmony_ci# 470362306a36Sopenharmony_ci# copy, convert, and tag input argument 470462306a36Sopenharmony_ci# 470562306a36Sopenharmony_ci fmov.s 0x8(%a6),%fp0 # load sgl dst 470662306a36Sopenharmony_ci fmov.x %fp0,FP_DST(%a6) 470762306a36Sopenharmony_ci lea FP_DST(%a6),%a0 470862306a36Sopenharmony_ci bsr.l tag # fetch operand type 470962306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 471062306a36Sopenharmony_ci 471162306a36Sopenharmony_ci fmov.s 0xc(%a6),%fp0 # load sgl src 471262306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 471362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 471462306a36Sopenharmony_ci bsr.l tag # fetch operand type 471562306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 471662306a36Sopenharmony_ci mov.l %d0,%d1 471762306a36Sopenharmony_ci 471862306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 471962306a36Sopenharmony_ci 472062306a36Sopenharmony_ci clr.l %d0 472162306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 472262306a36Sopenharmony_ci 472362306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 472462306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 472562306a36Sopenharmony_ci 472662306a36Sopenharmony_ci tst.b %d1 472762306a36Sopenharmony_ci bne.b _L23_2s 472862306a36Sopenharmony_ci bsr.l sscale_snorm # operand is a NORM 472962306a36Sopenharmony_ci bra.b _L23_6s 473062306a36Sopenharmony_ci_L23_2s: 473162306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 473262306a36Sopenharmony_ci bne.b _L23_3s # no 473362306a36Sopenharmony_ci bsr.l sscale_szero # yes 473462306a36Sopenharmony_ci bra.b _L23_6s 473562306a36Sopenharmony_ci_L23_3s: 473662306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 473762306a36Sopenharmony_ci bne.b _L23_4s # no 473862306a36Sopenharmony_ci bsr.l sscale_sinf # yes 473962306a36Sopenharmony_ci bra.b _L23_6s 474062306a36Sopenharmony_ci_L23_4s: 474162306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 474262306a36Sopenharmony_ci bne.b _L23_5s # no 474362306a36Sopenharmony_ci bsr.l sop_sqnan # yes 474462306a36Sopenharmony_ci bra.b _L23_6s 474562306a36Sopenharmony_ci_L23_5s: 474662306a36Sopenharmony_ci bsr.l sscale_sdnrm # operand is a DENORM 474762306a36Sopenharmony_ci_L23_6s: 474862306a36Sopenharmony_ci 474962306a36Sopenharmony_ci# 475062306a36Sopenharmony_ci# Result is now in FP0 475162306a36Sopenharmony_ci# 475262306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 475362306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 475462306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 475562306a36Sopenharmony_ci unlk %a6 475662306a36Sopenharmony_ci rts 475762306a36Sopenharmony_ci 475862306a36Sopenharmony_ci global _fscaled_ 475962306a36Sopenharmony_ci_fscaled_: 476062306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 476162306a36Sopenharmony_ci 476262306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 476362306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 476462306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 476562306a36Sopenharmony_ci 476662306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 476762306a36Sopenharmony_ci 476862306a36Sopenharmony_ci# 476962306a36Sopenharmony_ci# copy, convert, and tag input argument 477062306a36Sopenharmony_ci# 477162306a36Sopenharmony_ci fmov.d 0x8(%a6),%fp0 # load dbl dst 477262306a36Sopenharmony_ci fmov.x %fp0,FP_DST(%a6) 477362306a36Sopenharmony_ci lea FP_DST(%a6),%a0 477462306a36Sopenharmony_ci bsr.l tag # fetch operand type 477562306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 477662306a36Sopenharmony_ci 477762306a36Sopenharmony_ci fmov.d 0x10(%a6),%fp0 # load dbl src 477862306a36Sopenharmony_ci fmov.x %fp0,FP_SRC(%a6) 477962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 478062306a36Sopenharmony_ci bsr.l tag # fetch operand type 478162306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 478262306a36Sopenharmony_ci mov.l %d0,%d1 478362306a36Sopenharmony_ci 478462306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 478562306a36Sopenharmony_ci 478662306a36Sopenharmony_ci clr.l %d0 478762306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 478862306a36Sopenharmony_ci 478962306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 479062306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 479162306a36Sopenharmony_ci 479262306a36Sopenharmony_ci tst.b %d1 479362306a36Sopenharmony_ci bne.b _L23_2d 479462306a36Sopenharmony_ci bsr.l sscale_snorm # operand is a NORM 479562306a36Sopenharmony_ci bra.b _L23_6d 479662306a36Sopenharmony_ci_L23_2d: 479762306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 479862306a36Sopenharmony_ci bne.b _L23_3d # no 479962306a36Sopenharmony_ci bsr.l sscale_szero # yes 480062306a36Sopenharmony_ci bra.b _L23_6d 480162306a36Sopenharmony_ci_L23_3d: 480262306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 480362306a36Sopenharmony_ci bne.b _L23_4d # no 480462306a36Sopenharmony_ci bsr.l sscale_sinf # yes 480562306a36Sopenharmony_ci bra.b _L23_6d 480662306a36Sopenharmony_ci_L23_4d: 480762306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 480862306a36Sopenharmony_ci bne.b _L23_5d # no 480962306a36Sopenharmony_ci bsr.l sop_sqnan # yes 481062306a36Sopenharmony_ci bra.b _L23_6d 481162306a36Sopenharmony_ci_L23_5d: 481262306a36Sopenharmony_ci bsr.l sscale_sdnrm # operand is a DENORM 481362306a36Sopenharmony_ci_L23_6d: 481462306a36Sopenharmony_ci 481562306a36Sopenharmony_ci# 481662306a36Sopenharmony_ci# Result is now in FP0 481762306a36Sopenharmony_ci# 481862306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 481962306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 482062306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 482162306a36Sopenharmony_ci unlk %a6 482262306a36Sopenharmony_ci rts 482362306a36Sopenharmony_ci 482462306a36Sopenharmony_ci global _fscalex_ 482562306a36Sopenharmony_ci_fscalex_: 482662306a36Sopenharmony_ci link %a6,&-LOCAL_SIZE 482762306a36Sopenharmony_ci 482862306a36Sopenharmony_ci movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 482962306a36Sopenharmony_ci fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs 483062306a36Sopenharmony_ci fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1 483162306a36Sopenharmony_ci 483262306a36Sopenharmony_ci fmov.l &0x0,%fpcr # zero FPCR 483362306a36Sopenharmony_ci 483462306a36Sopenharmony_ci# 483562306a36Sopenharmony_ci# copy, convert, and tag input argument 483662306a36Sopenharmony_ci# 483762306a36Sopenharmony_ci lea FP_DST(%a6),%a0 483862306a36Sopenharmony_ci mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst 483962306a36Sopenharmony_ci mov.l 0x8+0x4(%a6),0x4(%a0) 484062306a36Sopenharmony_ci mov.l 0x8+0x8(%a6),0x8(%a0) 484162306a36Sopenharmony_ci bsr.l tag # fetch operand type 484262306a36Sopenharmony_ci mov.b %d0,DTAG(%a6) 484362306a36Sopenharmony_ci 484462306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 484562306a36Sopenharmony_ci mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src 484662306a36Sopenharmony_ci mov.l 0x14+0x4(%a6),0x4(%a0) 484762306a36Sopenharmony_ci mov.l 0x14+0x8(%a6),0x8(%a0) 484862306a36Sopenharmony_ci bsr.l tag # fetch operand type 484962306a36Sopenharmony_ci mov.b %d0,STAG(%a6) 485062306a36Sopenharmony_ci mov.l %d0,%d1 485162306a36Sopenharmony_ci 485262306a36Sopenharmony_ci andi.l &0x00ff00ff,USER_FPSR(%a6) 485362306a36Sopenharmony_ci 485462306a36Sopenharmony_ci clr.l %d0 485562306a36Sopenharmony_ci mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec 485662306a36Sopenharmony_ci 485762306a36Sopenharmony_ci lea FP_SRC(%a6),%a0 # pass ptr to src 485862306a36Sopenharmony_ci lea FP_DST(%a6),%a1 # pass ptr to dst 485962306a36Sopenharmony_ci 486062306a36Sopenharmony_ci tst.b %d1 486162306a36Sopenharmony_ci bne.b _L23_2x 486262306a36Sopenharmony_ci bsr.l sscale_snorm # operand is a NORM 486362306a36Sopenharmony_ci bra.b _L23_6x 486462306a36Sopenharmony_ci_L23_2x: 486562306a36Sopenharmony_ci cmpi.b %d1,&ZERO # is operand a ZERO? 486662306a36Sopenharmony_ci bne.b _L23_3x # no 486762306a36Sopenharmony_ci bsr.l sscale_szero # yes 486862306a36Sopenharmony_ci bra.b _L23_6x 486962306a36Sopenharmony_ci_L23_3x: 487062306a36Sopenharmony_ci cmpi.b %d1,&INF # is operand an INF? 487162306a36Sopenharmony_ci bne.b _L23_4x # no 487262306a36Sopenharmony_ci bsr.l sscale_sinf # yes 487362306a36Sopenharmony_ci bra.b _L23_6x 487462306a36Sopenharmony_ci_L23_4x: 487562306a36Sopenharmony_ci cmpi.b %d1,&QNAN # is operand a QNAN? 487662306a36Sopenharmony_ci bne.b _L23_5x # no 487762306a36Sopenharmony_ci bsr.l sop_sqnan # yes 487862306a36Sopenharmony_ci bra.b _L23_6x 487962306a36Sopenharmony_ci_L23_5x: 488062306a36Sopenharmony_ci bsr.l sscale_sdnrm # operand is a DENORM 488162306a36Sopenharmony_ci_L23_6x: 488262306a36Sopenharmony_ci 488362306a36Sopenharmony_ci# 488462306a36Sopenharmony_ci# Result is now in FP0 488562306a36Sopenharmony_ci# 488662306a36Sopenharmony_ci movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 488762306a36Sopenharmony_ci fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs 488862306a36Sopenharmony_ci fmovm.x EXC_FP1(%a6),&0x40 # restore fp1 488962306a36Sopenharmony_ci unlk %a6 489062306a36Sopenharmony_ci rts 489162306a36Sopenharmony_ci 489262306a36Sopenharmony_ci 489362306a36Sopenharmony_ci######################################################################### 489462306a36Sopenharmony_ci# ssin(): computes the sine of a normalized input # 489562306a36Sopenharmony_ci# ssind(): computes the sine of a denormalized input # 489662306a36Sopenharmony_ci# scos(): computes the cosine of a normalized input # 489762306a36Sopenharmony_ci# scosd(): computes the cosine of a denormalized input # 489862306a36Sopenharmony_ci# ssincos(): computes the sine and cosine of a normalized input # 489962306a36Sopenharmony_ci# ssincosd(): computes the sine and cosine of a denormalized input # 490062306a36Sopenharmony_ci# # 490162306a36Sopenharmony_ci# INPUT *************************************************************** # 490262306a36Sopenharmony_ci# a0 = pointer to extended precision input # 490362306a36Sopenharmony_ci# d0 = round precision,mode # 490462306a36Sopenharmony_ci# # 490562306a36Sopenharmony_ci# OUTPUT ************************************************************** # 490662306a36Sopenharmony_ci# fp0 = sin(X) or cos(X) # 490762306a36Sopenharmony_ci# # 490862306a36Sopenharmony_ci# For ssincos(X): # 490962306a36Sopenharmony_ci# fp0 = sin(X) # 491062306a36Sopenharmony_ci# fp1 = cos(X) # 491162306a36Sopenharmony_ci# # 491262306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 491362306a36Sopenharmony_ci# The returned result is within 1 ulp in 64 significant bit, i.e. # 491462306a36Sopenharmony_ci# within 0.5001 ulp to 53 bits if the result is subsequently # 491562306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 491662306a36Sopenharmony_ci# in double precision. # 491762306a36Sopenharmony_ci# # 491862306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 491962306a36Sopenharmony_ci# # 492062306a36Sopenharmony_ci# SIN and COS: # 492162306a36Sopenharmony_ci# 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. # 492262306a36Sopenharmony_ci# # 492362306a36Sopenharmony_ci# 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. # 492462306a36Sopenharmony_ci# # 492562306a36Sopenharmony_ci# 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 492662306a36Sopenharmony_ci# k = N mod 4, so in particular, k = 0,1,2,or 3. # 492762306a36Sopenharmony_ci# Overwrite k by k := k + AdjN. # 492862306a36Sopenharmony_ci# # 492962306a36Sopenharmony_ci# 4. If k is even, go to 6. # 493062306a36Sopenharmony_ci# # 493162306a36Sopenharmony_ci# 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. # 493262306a36Sopenharmony_ci# Return sgn*cos(r) where cos(r) is approximated by an # 493362306a36Sopenharmony_ci# even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), # 493462306a36Sopenharmony_ci# s = r*r. # 493562306a36Sopenharmony_ci# Exit. # 493662306a36Sopenharmony_ci# # 493762306a36Sopenharmony_ci# 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) # 493862306a36Sopenharmony_ci# where sin(r) is approximated by an odd polynomial in r # 493962306a36Sopenharmony_ci# r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. # 494062306a36Sopenharmony_ci# Exit. # 494162306a36Sopenharmony_ci# # 494262306a36Sopenharmony_ci# 7. If |X| > 1, go to 9. # 494362306a36Sopenharmony_ci# # 494462306a36Sopenharmony_ci# 8. (|X|<2**(-40)) If SIN is invoked, return X; # 494562306a36Sopenharmony_ci# otherwise return 1. # 494662306a36Sopenharmony_ci# # 494762306a36Sopenharmony_ci# 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 494862306a36Sopenharmony_ci# go back to 3. # 494962306a36Sopenharmony_ci# # 495062306a36Sopenharmony_ci# SINCOS: # 495162306a36Sopenharmony_ci# 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 495262306a36Sopenharmony_ci# # 495362306a36Sopenharmony_ci# 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 495462306a36Sopenharmony_ci# k = N mod 4, so in particular, k = 0,1,2,or 3. # 495562306a36Sopenharmony_ci# # 495662306a36Sopenharmony_ci# 3. If k is even, go to 5. # 495762306a36Sopenharmony_ci# # 495862306a36Sopenharmony_ci# 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie. # 495962306a36Sopenharmony_ci# j1 exclusive or with the l.s.b. of k. # 496062306a36Sopenharmony_ci# sgn1 := (-1)**j1, sgn2 := (-1)**j2. # 496162306a36Sopenharmony_ci# SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where # 496262306a36Sopenharmony_ci# sin(r) and cos(r) are computed as odd and even # 496362306a36Sopenharmony_ci# polynomials in r, respectively. Exit # 496462306a36Sopenharmony_ci# # 496562306a36Sopenharmony_ci# 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. # 496662306a36Sopenharmony_ci# SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where # 496762306a36Sopenharmony_ci# sin(r) and cos(r) are computed as odd and even # 496862306a36Sopenharmony_ci# polynomials in r, respectively. Exit # 496962306a36Sopenharmony_ci# # 497062306a36Sopenharmony_ci# 6. If |X| > 1, go to 8. # 497162306a36Sopenharmony_ci# # 497262306a36Sopenharmony_ci# 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. # 497362306a36Sopenharmony_ci# # 497462306a36Sopenharmony_ci# 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 497562306a36Sopenharmony_ci# go back to 2. # 497662306a36Sopenharmony_ci# # 497762306a36Sopenharmony_ci######################################################################### 497862306a36Sopenharmony_ci 497962306a36Sopenharmony_ciSINA7: long 0xBD6AAA77,0xCCC994F5 498062306a36Sopenharmony_ciSINA6: long 0x3DE61209,0x7AAE8DA1 498162306a36Sopenharmony_ciSINA5: long 0xBE5AE645,0x2A118AE4 498262306a36Sopenharmony_ciSINA4: long 0x3EC71DE3,0xA5341531 498362306a36Sopenharmony_ciSINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000 498462306a36Sopenharmony_ciSINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000 498562306a36Sopenharmony_ciSINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000 498662306a36Sopenharmony_ci 498762306a36Sopenharmony_ciCOSB8: long 0x3D2AC4D0,0xD6011EE3 498862306a36Sopenharmony_ciCOSB7: long 0xBDA9396F,0x9F45AC19 498962306a36Sopenharmony_ciCOSB6: long 0x3E21EED9,0x0612C972 499062306a36Sopenharmony_ciCOSB5: long 0xBE927E4F,0xB79D9FCF 499162306a36Sopenharmony_ciCOSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000 499262306a36Sopenharmony_ciCOSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000 499362306a36Sopenharmony_ciCOSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E 499462306a36Sopenharmony_ciCOSB1: long 0xBF000000 499562306a36Sopenharmony_ci 499662306a36Sopenharmony_ci set INARG,FP_SCR0 499762306a36Sopenharmony_ci 499862306a36Sopenharmony_ci set X,FP_SCR0 499962306a36Sopenharmony_ci# set XDCARE,X+2 500062306a36Sopenharmony_ci set XFRAC,X+4 500162306a36Sopenharmony_ci 500262306a36Sopenharmony_ci set RPRIME,FP_SCR0 500362306a36Sopenharmony_ci set SPRIME,FP_SCR1 500462306a36Sopenharmony_ci 500562306a36Sopenharmony_ci set POSNEG1,L_SCR1 500662306a36Sopenharmony_ci set TWOTO63,L_SCR1 500762306a36Sopenharmony_ci 500862306a36Sopenharmony_ci set ENDFLAG,L_SCR2 500962306a36Sopenharmony_ci set INT,L_SCR2 501062306a36Sopenharmony_ci 501162306a36Sopenharmony_ci set ADJN,L_SCR3 501262306a36Sopenharmony_ci 501362306a36Sopenharmony_ci############################################ 501462306a36Sopenharmony_ci global ssin 501562306a36Sopenharmony_cissin: 501662306a36Sopenharmony_ci mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0 501762306a36Sopenharmony_ci bra.b SINBGN 501862306a36Sopenharmony_ci 501962306a36Sopenharmony_ci############################################ 502062306a36Sopenharmony_ci global scos 502162306a36Sopenharmony_ciscos: 502262306a36Sopenharmony_ci mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1 502362306a36Sopenharmony_ci 502462306a36Sopenharmony_ci############################################ 502562306a36Sopenharmony_ciSINBGN: 502662306a36Sopenharmony_ci#--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE 502762306a36Sopenharmony_ci 502862306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 502962306a36Sopenharmony_ci fmov.x %fp0,X(%a6) # save input at X 503062306a36Sopenharmony_ci 503162306a36Sopenharmony_ci# "COMPACTIFY" X 503262306a36Sopenharmony_ci mov.l (%a0),%d1 # put exp in hi word 503362306a36Sopenharmony_ci mov.w 4(%a0),%d1 # fetch hi(man) 503462306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 # strip sign 503562306a36Sopenharmony_ci 503662306a36Sopenharmony_ci cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)? 503762306a36Sopenharmony_ci bge.b SOK1 # no 503862306a36Sopenharmony_ci bra.w SINSM # yes; input is very small 503962306a36Sopenharmony_ci 504062306a36Sopenharmony_ciSOK1: 504162306a36Sopenharmony_ci cmp.l %d1,&0x4004BC7E # is |X| < 15 PI? 504262306a36Sopenharmony_ci blt.b SINMAIN # no 504362306a36Sopenharmony_ci bra.w SREDUCEX # yes; input is very large 504462306a36Sopenharmony_ci 504562306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| <= 15 PI. 504662306a36Sopenharmony_ci#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 504762306a36Sopenharmony_ciSINMAIN: 504862306a36Sopenharmony_ci fmov.x %fp0,%fp1 504962306a36Sopenharmony_ci fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 505062306a36Sopenharmony_ci 505162306a36Sopenharmony_ci lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 505262306a36Sopenharmony_ci 505362306a36Sopenharmony_ci fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 505462306a36Sopenharmony_ci 505562306a36Sopenharmony_ci mov.l INT(%a6),%d1 # make a copy of N 505662306a36Sopenharmony_ci asl.l &4,%d1 # N *= 16 505762306a36Sopenharmony_ci add.l %d1,%a1 # tbl_addr = a1 + (N*16) 505862306a36Sopenharmony_ci 505962306a36Sopenharmony_ci# A1 IS THE ADDRESS OF N*PIBY2 506062306a36Sopenharmony_ci# ...WHICH IS IN TWO PIECES Y1 & Y2 506162306a36Sopenharmony_ci fsub.x (%a1)+,%fp0 # X-Y1 506262306a36Sopenharmony_ci fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2 506362306a36Sopenharmony_ci 506462306a36Sopenharmony_ciSINCONT: 506562306a36Sopenharmony_ci#--continuation from REDUCEX 506662306a36Sopenharmony_ci 506762306a36Sopenharmony_ci#--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED 506862306a36Sopenharmony_ci mov.l INT(%a6),%d1 506962306a36Sopenharmony_ci add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN 507062306a36Sopenharmony_ci ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE 507162306a36Sopenharmony_ci cmp.l %d1,&0 507262306a36Sopenharmony_ci blt.w COSPOLY 507362306a36Sopenharmony_ci 507462306a36Sopenharmony_ci#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 507562306a36Sopenharmony_ci#--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY 507662306a36Sopenharmony_ci#--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE 507762306a36Sopenharmony_ci#--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS 507862306a36Sopenharmony_ci#--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))]) 507962306a36Sopenharmony_ci#--WHERE T=S*S. 508062306a36Sopenharmony_ci#--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION 508162306a36Sopenharmony_ci#--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT. 508262306a36Sopenharmony_ciSINPOLY: 508362306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2/fp3 508462306a36Sopenharmony_ci 508562306a36Sopenharmony_ci fmov.x %fp0,X(%a6) # X IS R 508662306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FP0 IS S 508762306a36Sopenharmony_ci 508862306a36Sopenharmony_ci fmov.d SINA7(%pc),%fp3 508962306a36Sopenharmony_ci fmov.d SINA6(%pc),%fp2 509062306a36Sopenharmony_ci 509162306a36Sopenharmony_ci fmov.x %fp0,%fp1 509262306a36Sopenharmony_ci fmul.x %fp1,%fp1 # FP1 IS T 509362306a36Sopenharmony_ci 509462306a36Sopenharmony_ci ror.l &1,%d1 509562306a36Sopenharmony_ci and.l &0x80000000,%d1 509662306a36Sopenharmony_ci# ...LEAST SIG. BIT OF D0 IN SIGN POSITION 509762306a36Sopenharmony_ci eor.l %d1,X(%a6) # X IS NOW R'= SGN*R 509862306a36Sopenharmony_ci 509962306a36Sopenharmony_ci fmul.x %fp1,%fp3 # TA7 510062306a36Sopenharmony_ci fmul.x %fp1,%fp2 # TA6 510162306a36Sopenharmony_ci 510262306a36Sopenharmony_ci fadd.d SINA5(%pc),%fp3 # A5+TA7 510362306a36Sopenharmony_ci fadd.d SINA4(%pc),%fp2 # A4+TA6 510462306a36Sopenharmony_ci 510562306a36Sopenharmony_ci fmul.x %fp1,%fp3 # T(A5+TA7) 510662306a36Sopenharmony_ci fmul.x %fp1,%fp2 # T(A4+TA6) 510762306a36Sopenharmony_ci 510862306a36Sopenharmony_ci fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7) 510962306a36Sopenharmony_ci fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6) 511062306a36Sopenharmony_ci 511162306a36Sopenharmony_ci fmul.x %fp3,%fp1 # T(A3+T(A5+TA7)) 511262306a36Sopenharmony_ci 511362306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(A2+T(A4+TA6)) 511462306a36Sopenharmony_ci fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7)) 511562306a36Sopenharmony_ci fmul.x X(%a6),%fp0 # R'*S 511662306a36Sopenharmony_ci 511762306a36Sopenharmony_ci fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))] 511862306a36Sopenharmony_ci 511962306a36Sopenharmony_ci fmul.x %fp1,%fp0 # SIN(R')-R' 512062306a36Sopenharmony_ci 512162306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2/fp3 512262306a36Sopenharmony_ci 512362306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 512462306a36Sopenharmony_ci fadd.x X(%a6),%fp0 # last inst - possible exception set 512562306a36Sopenharmony_ci bra t_inx2 512662306a36Sopenharmony_ci 512762306a36Sopenharmony_ci#--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 512862306a36Sopenharmony_ci#--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY 512962306a36Sopenharmony_ci#--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE 513062306a36Sopenharmony_ci#--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS 513162306a36Sopenharmony_ci#--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))]) 513262306a36Sopenharmony_ci#--WHERE T=S*S. 513362306a36Sopenharmony_ci#--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION 513462306a36Sopenharmony_ci#--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2 513562306a36Sopenharmony_ci#--AND IS THEREFORE STORED AS SINGLE PRECISION. 513662306a36Sopenharmony_ciCOSPOLY: 513762306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2/fp3 513862306a36Sopenharmony_ci 513962306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FP0 IS S 514062306a36Sopenharmony_ci 514162306a36Sopenharmony_ci fmov.d COSB8(%pc),%fp2 514262306a36Sopenharmony_ci fmov.d COSB7(%pc),%fp3 514362306a36Sopenharmony_ci 514462306a36Sopenharmony_ci fmov.x %fp0,%fp1 514562306a36Sopenharmony_ci fmul.x %fp1,%fp1 # FP1 IS T 514662306a36Sopenharmony_ci 514762306a36Sopenharmony_ci fmov.x %fp0,X(%a6) # X IS S 514862306a36Sopenharmony_ci ror.l &1,%d1 514962306a36Sopenharmony_ci and.l &0x80000000,%d1 515062306a36Sopenharmony_ci# ...LEAST SIG. BIT OF D0 IN SIGN POSITION 515162306a36Sopenharmony_ci 515262306a36Sopenharmony_ci fmul.x %fp1,%fp2 # TB8 515362306a36Sopenharmony_ci 515462306a36Sopenharmony_ci eor.l %d1,X(%a6) # X IS NOW S'= SGN*S 515562306a36Sopenharmony_ci and.l &0x80000000,%d1 515662306a36Sopenharmony_ci 515762306a36Sopenharmony_ci fmul.x %fp1,%fp3 # TB7 515862306a36Sopenharmony_ci 515962306a36Sopenharmony_ci or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE 516062306a36Sopenharmony_ci mov.l %d1,POSNEG1(%a6) 516162306a36Sopenharmony_ci 516262306a36Sopenharmony_ci fadd.d COSB6(%pc),%fp2 # B6+TB8 516362306a36Sopenharmony_ci fadd.d COSB5(%pc),%fp3 # B5+TB7 516462306a36Sopenharmony_ci 516562306a36Sopenharmony_ci fmul.x %fp1,%fp2 # T(B6+TB8) 516662306a36Sopenharmony_ci fmul.x %fp1,%fp3 # T(B5+TB7) 516762306a36Sopenharmony_ci 516862306a36Sopenharmony_ci fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8) 516962306a36Sopenharmony_ci fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7) 517062306a36Sopenharmony_ci 517162306a36Sopenharmony_ci fmul.x %fp1,%fp2 # T(B4+T(B6+TB8)) 517262306a36Sopenharmony_ci fmul.x %fp3,%fp1 # T(B3+T(B5+TB7)) 517362306a36Sopenharmony_ci 517462306a36Sopenharmony_ci fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8)) 517562306a36Sopenharmony_ci fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7)) 517662306a36Sopenharmony_ci 517762306a36Sopenharmony_ci fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8))) 517862306a36Sopenharmony_ci 517962306a36Sopenharmony_ci fadd.x %fp1,%fp0 518062306a36Sopenharmony_ci 518162306a36Sopenharmony_ci fmul.x X(%a6),%fp0 518262306a36Sopenharmony_ci 518362306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2/fp3 518462306a36Sopenharmony_ci 518562306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 518662306a36Sopenharmony_ci fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set 518762306a36Sopenharmony_ci bra t_inx2 518862306a36Sopenharmony_ci 518962306a36Sopenharmony_ci############################################## 519062306a36Sopenharmony_ci 519162306a36Sopenharmony_ci# SINe: Big OR Small? 519262306a36Sopenharmony_ci#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 519362306a36Sopenharmony_ci#--IF |X| < 2**(-40), RETURN X OR 1. 519462306a36Sopenharmony_ciSINBORS: 519562306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 519662306a36Sopenharmony_ci bgt.l SREDUCEX 519762306a36Sopenharmony_ci 519862306a36Sopenharmony_ciSINSM: 519962306a36Sopenharmony_ci mov.l ADJN(%a6),%d1 520062306a36Sopenharmony_ci cmp.l %d1,&0 520162306a36Sopenharmony_ci bgt.b COSTINY 520262306a36Sopenharmony_ci 520362306a36Sopenharmony_ci# here, the operation may underflow iff the precision is sgl or dbl. 520462306a36Sopenharmony_ci# extended denorms are handled through another entry point. 520562306a36Sopenharmony_ciSINTINY: 520662306a36Sopenharmony_ci# mov.w &0x0000,XDCARE(%a6) # JUST IN CASE 520762306a36Sopenharmony_ci 520862306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 520962306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 521062306a36Sopenharmony_ci fmov.x X(%a6),%fp0 # last inst - possible exception set 521162306a36Sopenharmony_ci bra t_catch 521262306a36Sopenharmony_ci 521362306a36Sopenharmony_ciCOSTINY: 521462306a36Sopenharmony_ci fmov.s &0x3F800000,%fp0 # fp0 = 1.0 521562306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 521662306a36Sopenharmony_ci fadd.s &0x80800000,%fp0 # last inst - possible exception set 521762306a36Sopenharmony_ci bra t_pinx2 521862306a36Sopenharmony_ci 521962306a36Sopenharmony_ci################################################ 522062306a36Sopenharmony_ci global ssind 522162306a36Sopenharmony_ci#--SIN(X) = X FOR DENORMALIZED X 522262306a36Sopenharmony_cissind: 522362306a36Sopenharmony_ci bra t_extdnrm 522462306a36Sopenharmony_ci 522562306a36Sopenharmony_ci############################################ 522662306a36Sopenharmony_ci global scosd 522762306a36Sopenharmony_ci#--COS(X) = 1 FOR DENORMALIZED X 522862306a36Sopenharmony_ciscosd: 522962306a36Sopenharmony_ci fmov.s &0x3F800000,%fp0 # fp0 = 1.0 523062306a36Sopenharmony_ci bra t_pinx2 523162306a36Sopenharmony_ci 523262306a36Sopenharmony_ci################################################## 523362306a36Sopenharmony_ci 523462306a36Sopenharmony_ci global ssincos 523562306a36Sopenharmony_cissincos: 523662306a36Sopenharmony_ci#--SET ADJN TO 4 523762306a36Sopenharmony_ci mov.l &4,ADJN(%a6) 523862306a36Sopenharmony_ci 523962306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 524062306a36Sopenharmony_ci fmov.x %fp0,X(%a6) 524162306a36Sopenharmony_ci 524262306a36Sopenharmony_ci mov.l (%a0),%d1 524362306a36Sopenharmony_ci mov.w 4(%a0),%d1 524462306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 # COMPACTIFY X 524562306a36Sopenharmony_ci 524662306a36Sopenharmony_ci cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 524762306a36Sopenharmony_ci bge.b SCOK1 524862306a36Sopenharmony_ci bra.w SCSM 524962306a36Sopenharmony_ci 525062306a36Sopenharmony_ciSCOK1: 525162306a36Sopenharmony_ci cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 525262306a36Sopenharmony_ci blt.b SCMAIN 525362306a36Sopenharmony_ci bra.w SREDUCEX 525462306a36Sopenharmony_ci 525562306a36Sopenharmony_ci 525662306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| <= 15 PI. 525762306a36Sopenharmony_ci#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 525862306a36Sopenharmony_ciSCMAIN: 525962306a36Sopenharmony_ci fmov.x %fp0,%fp1 526062306a36Sopenharmony_ci 526162306a36Sopenharmony_ci fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 526262306a36Sopenharmony_ci 526362306a36Sopenharmony_ci lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 526462306a36Sopenharmony_ci 526562306a36Sopenharmony_ci fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 526662306a36Sopenharmony_ci 526762306a36Sopenharmony_ci mov.l INT(%a6),%d1 526862306a36Sopenharmony_ci asl.l &4,%d1 526962306a36Sopenharmony_ci add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2 527062306a36Sopenharmony_ci 527162306a36Sopenharmony_ci fsub.x (%a1)+,%fp0 # X-Y1 527262306a36Sopenharmony_ci fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 527362306a36Sopenharmony_ci 527462306a36Sopenharmony_ciSCCONT: 527562306a36Sopenharmony_ci#--continuation point from REDUCEX 527662306a36Sopenharmony_ci 527762306a36Sopenharmony_ci mov.l INT(%a6),%d1 527862306a36Sopenharmony_ci ror.l &1,%d1 527962306a36Sopenharmony_ci cmp.l %d1,&0 # D0 < 0 IFF N IS ODD 528062306a36Sopenharmony_ci bge.w NEVEN 528162306a36Sopenharmony_ci 528262306a36Sopenharmony_ciSNODD: 528362306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR: D0, A0, FP2. 528462306a36Sopenharmony_ci fmovm.x &0x04,-(%sp) # save fp2 528562306a36Sopenharmony_ci 528662306a36Sopenharmony_ci fmov.x %fp0,RPRIME(%a6) 528762306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FP0 IS S = R*R 528862306a36Sopenharmony_ci fmov.d SINA7(%pc),%fp1 # A7 528962306a36Sopenharmony_ci fmov.d COSB8(%pc),%fp2 # B8 529062306a36Sopenharmony_ci fmul.x %fp0,%fp1 # SA7 529162306a36Sopenharmony_ci fmul.x %fp0,%fp2 # SB8 529262306a36Sopenharmony_ci 529362306a36Sopenharmony_ci mov.l %d2,-(%sp) 529462306a36Sopenharmony_ci mov.l %d1,%d2 529562306a36Sopenharmony_ci ror.l &1,%d2 529662306a36Sopenharmony_ci and.l &0x80000000,%d2 529762306a36Sopenharmony_ci eor.l %d1,%d2 529862306a36Sopenharmony_ci and.l &0x80000000,%d2 529962306a36Sopenharmony_ci 530062306a36Sopenharmony_ci fadd.d SINA6(%pc),%fp1 # A6+SA7 530162306a36Sopenharmony_ci fadd.d COSB7(%pc),%fp2 # B7+SB8 530262306a36Sopenharmony_ci 530362306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(A6+SA7) 530462306a36Sopenharmony_ci eor.l %d2,RPRIME(%a6) 530562306a36Sopenharmony_ci mov.l (%sp)+,%d2 530662306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(B7+SB8) 530762306a36Sopenharmony_ci ror.l &1,%d1 530862306a36Sopenharmony_ci and.l &0x80000000,%d1 530962306a36Sopenharmony_ci mov.l &0x3F800000,POSNEG1(%a6) 531062306a36Sopenharmony_ci eor.l %d1,POSNEG1(%a6) 531162306a36Sopenharmony_ci 531262306a36Sopenharmony_ci fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7) 531362306a36Sopenharmony_ci fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8) 531462306a36Sopenharmony_ci 531562306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(A5+S(A6+SA7)) 531662306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(B6+S(B7+SB8)) 531762306a36Sopenharmony_ci fmov.x %fp0,SPRIME(%a6) 531862306a36Sopenharmony_ci 531962306a36Sopenharmony_ci fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7)) 532062306a36Sopenharmony_ci eor.l %d1,SPRIME(%a6) 532162306a36Sopenharmony_ci fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8)) 532262306a36Sopenharmony_ci 532362306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(A4+...) 532462306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(B5+...) 532562306a36Sopenharmony_ci 532662306a36Sopenharmony_ci fadd.d SINA3(%pc),%fp1 # A3+S(A4+...) 532762306a36Sopenharmony_ci fadd.d COSB4(%pc),%fp2 # B4+S(B5+...) 532862306a36Sopenharmony_ci 532962306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(A3+...) 533062306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(B4+...) 533162306a36Sopenharmony_ci 533262306a36Sopenharmony_ci fadd.x SINA2(%pc),%fp1 # A2+S(A3+...) 533362306a36Sopenharmony_ci fadd.x COSB3(%pc),%fp2 # B3+S(B4+...) 533462306a36Sopenharmony_ci 533562306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(A2+...) 533662306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(B3+...) 533762306a36Sopenharmony_ci 533862306a36Sopenharmony_ci fadd.x SINA1(%pc),%fp1 # A1+S(A2+...) 533962306a36Sopenharmony_ci fadd.x COSB2(%pc),%fp2 # B2+S(B3+...) 534062306a36Sopenharmony_ci 534162306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(A1+...) 534262306a36Sopenharmony_ci fmul.x %fp2,%fp0 # S(B2+...) 534362306a36Sopenharmony_ci 534462306a36Sopenharmony_ci fmul.x RPRIME(%a6),%fp1 # R'S(A1+...) 534562306a36Sopenharmony_ci fadd.s COSB1(%pc),%fp0 # B1+S(B2...) 534662306a36Sopenharmony_ci fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...)) 534762306a36Sopenharmony_ci 534862306a36Sopenharmony_ci fmovm.x (%sp)+,&0x20 # restore fp2 534962306a36Sopenharmony_ci 535062306a36Sopenharmony_ci fmov.l %d0,%fpcr 535162306a36Sopenharmony_ci fadd.x RPRIME(%a6),%fp1 # COS(X) 535262306a36Sopenharmony_ci bsr sto_cos # store cosine result 535362306a36Sopenharmony_ci fadd.s POSNEG1(%a6),%fp0 # SIN(X) 535462306a36Sopenharmony_ci bra t_inx2 535562306a36Sopenharmony_ci 535662306a36Sopenharmony_ciNEVEN: 535762306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR: FP2. 535862306a36Sopenharmony_ci fmovm.x &0x04,-(%sp) # save fp2 535962306a36Sopenharmony_ci 536062306a36Sopenharmony_ci fmov.x %fp0,RPRIME(%a6) 536162306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FP0 IS S = R*R 536262306a36Sopenharmony_ci 536362306a36Sopenharmony_ci fmov.d COSB8(%pc),%fp1 # B8 536462306a36Sopenharmony_ci fmov.d SINA7(%pc),%fp2 # A7 536562306a36Sopenharmony_ci 536662306a36Sopenharmony_ci fmul.x %fp0,%fp1 # SB8 536762306a36Sopenharmony_ci fmov.x %fp0,SPRIME(%a6) 536862306a36Sopenharmony_ci fmul.x %fp0,%fp2 # SA7 536962306a36Sopenharmony_ci 537062306a36Sopenharmony_ci ror.l &1,%d1 537162306a36Sopenharmony_ci and.l &0x80000000,%d1 537262306a36Sopenharmony_ci 537362306a36Sopenharmony_ci fadd.d COSB7(%pc),%fp1 # B7+SB8 537462306a36Sopenharmony_ci fadd.d SINA6(%pc),%fp2 # A6+SA7 537562306a36Sopenharmony_ci 537662306a36Sopenharmony_ci eor.l %d1,RPRIME(%a6) 537762306a36Sopenharmony_ci eor.l %d1,SPRIME(%a6) 537862306a36Sopenharmony_ci 537962306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(B7+SB8) 538062306a36Sopenharmony_ci 538162306a36Sopenharmony_ci or.l &0x3F800000,%d1 538262306a36Sopenharmony_ci mov.l %d1,POSNEG1(%a6) 538362306a36Sopenharmony_ci 538462306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(A6+SA7) 538562306a36Sopenharmony_ci 538662306a36Sopenharmony_ci fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8) 538762306a36Sopenharmony_ci fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7) 538862306a36Sopenharmony_ci 538962306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(B6+S(B7+SB8)) 539062306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(A5+S(A6+SA7)) 539162306a36Sopenharmony_ci 539262306a36Sopenharmony_ci fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8)) 539362306a36Sopenharmony_ci fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7)) 539462306a36Sopenharmony_ci 539562306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(B5+...) 539662306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(A4+...) 539762306a36Sopenharmony_ci 539862306a36Sopenharmony_ci fadd.d COSB4(%pc),%fp1 # B4+S(B5+...) 539962306a36Sopenharmony_ci fadd.d SINA3(%pc),%fp2 # A3+S(A4+...) 540062306a36Sopenharmony_ci 540162306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(B4+...) 540262306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(A3+...) 540362306a36Sopenharmony_ci 540462306a36Sopenharmony_ci fadd.x COSB3(%pc),%fp1 # B3+S(B4+...) 540562306a36Sopenharmony_ci fadd.x SINA2(%pc),%fp2 # A2+S(A3+...) 540662306a36Sopenharmony_ci 540762306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(B3+...) 540862306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(A2+...) 540962306a36Sopenharmony_ci 541062306a36Sopenharmony_ci fadd.x COSB2(%pc),%fp1 # B2+S(B3+...) 541162306a36Sopenharmony_ci fadd.x SINA1(%pc),%fp2 # A1+S(A2+...) 541262306a36Sopenharmony_ci 541362306a36Sopenharmony_ci fmul.x %fp0,%fp1 # S(B2+...) 541462306a36Sopenharmony_ci fmul.x %fp2,%fp0 # s(a1+...) 541562306a36Sopenharmony_ci 541662306a36Sopenharmony_ci 541762306a36Sopenharmony_ci fadd.s COSB1(%pc),%fp1 # B1+S(B2...) 541862306a36Sopenharmony_ci fmul.x RPRIME(%a6),%fp0 # R'S(A1+...) 541962306a36Sopenharmony_ci fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...)) 542062306a36Sopenharmony_ci 542162306a36Sopenharmony_ci fmovm.x (%sp)+,&0x20 # restore fp2 542262306a36Sopenharmony_ci 542362306a36Sopenharmony_ci fmov.l %d0,%fpcr 542462306a36Sopenharmony_ci fadd.s POSNEG1(%a6),%fp1 # COS(X) 542562306a36Sopenharmony_ci bsr sto_cos # store cosine result 542662306a36Sopenharmony_ci fadd.x RPRIME(%a6),%fp0 # SIN(X) 542762306a36Sopenharmony_ci bra t_inx2 542862306a36Sopenharmony_ci 542962306a36Sopenharmony_ci################################################ 543062306a36Sopenharmony_ci 543162306a36Sopenharmony_ciSCBORS: 543262306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 543362306a36Sopenharmony_ci bgt.w SREDUCEX 543462306a36Sopenharmony_ci 543562306a36Sopenharmony_ci################################################ 543662306a36Sopenharmony_ci 543762306a36Sopenharmony_ciSCSM: 543862306a36Sopenharmony_ci# mov.w &0x0000,XDCARE(%a6) 543962306a36Sopenharmony_ci fmov.s &0x3F800000,%fp1 544062306a36Sopenharmony_ci 544162306a36Sopenharmony_ci fmov.l %d0,%fpcr 544262306a36Sopenharmony_ci fsub.s &0x00800000,%fp1 544362306a36Sopenharmony_ci bsr sto_cos # store cosine result 544462306a36Sopenharmony_ci fmov.l %fpcr,%d0 # d0 must have fpcr,too 544562306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 544662306a36Sopenharmony_ci fmov.x X(%a6),%fp0 544762306a36Sopenharmony_ci bra t_catch 544862306a36Sopenharmony_ci 544962306a36Sopenharmony_ci############################################## 545062306a36Sopenharmony_ci 545162306a36Sopenharmony_ci global ssincosd 545262306a36Sopenharmony_ci#--SIN AND COS OF X FOR DENORMALIZED X 545362306a36Sopenharmony_cissincosd: 545462306a36Sopenharmony_ci mov.l %d0,-(%sp) # save d0 545562306a36Sopenharmony_ci fmov.s &0x3F800000,%fp1 545662306a36Sopenharmony_ci bsr sto_cos # store cosine result 545762306a36Sopenharmony_ci mov.l (%sp)+,%d0 # restore d0 545862306a36Sopenharmony_ci bra t_extdnrm 545962306a36Sopenharmony_ci 546062306a36Sopenharmony_ci############################################ 546162306a36Sopenharmony_ci 546262306a36Sopenharmony_ci#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 546362306a36Sopenharmony_ci#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 546462306a36Sopenharmony_ci#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 546562306a36Sopenharmony_ciSREDUCEX: 546662306a36Sopenharmony_ci fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 546762306a36Sopenharmony_ci mov.l %d2,-(%sp) # save d2 546862306a36Sopenharmony_ci fmov.s &0x00000000,%fp1 # fp1 = 0 546962306a36Sopenharmony_ci 547062306a36Sopenharmony_ci#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 547162306a36Sopenharmony_ci#--there is a danger of unwanted overflow in first LOOP iteration. In this 547262306a36Sopenharmony_ci#--case, reduce argument by one remainder step to make subsequent reduction 547362306a36Sopenharmony_ci#--safe. 547462306a36Sopenharmony_ci cmp.l %d1,&0x7ffeffff # is arg dangerously large? 547562306a36Sopenharmony_ci bne.b SLOOP # no 547662306a36Sopenharmony_ci 547762306a36Sopenharmony_ci# yes; create 2**16383*PI/2 547862306a36Sopenharmony_ci mov.w &0x7ffe,FP_SCR0_EX(%a6) 547962306a36Sopenharmony_ci mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 548062306a36Sopenharmony_ci clr.l FP_SCR0_LO(%a6) 548162306a36Sopenharmony_ci 548262306a36Sopenharmony_ci# create low half of 2**16383*PI/2 at FP_SCR1 548362306a36Sopenharmony_ci mov.w &0x7fdc,FP_SCR1_EX(%a6) 548462306a36Sopenharmony_ci mov.l &0x85a308d3,FP_SCR1_HI(%a6) 548562306a36Sopenharmony_ci clr.l FP_SCR1_LO(%a6) 548662306a36Sopenharmony_ci 548762306a36Sopenharmony_ci ftest.x %fp0 # test sign of argument 548862306a36Sopenharmony_ci fblt.w sred_neg 548962306a36Sopenharmony_ci 549062306a36Sopenharmony_ci or.b &0x80,FP_SCR0_EX(%a6) # positive arg 549162306a36Sopenharmony_ci or.b &0x80,FP_SCR1_EX(%a6) 549262306a36Sopenharmony_cisred_neg: 549362306a36Sopenharmony_ci fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 549462306a36Sopenharmony_ci fmov.x %fp0,%fp1 # save high result in fp1 549562306a36Sopenharmony_ci fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 549662306a36Sopenharmony_ci fsub.x %fp0,%fp1 # determine low component of result 549762306a36Sopenharmony_ci fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 549862306a36Sopenharmony_ci 549962306a36Sopenharmony_ci#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 550062306a36Sopenharmony_ci#--integer quotient will be stored in N 550162306a36Sopenharmony_ci#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 550262306a36Sopenharmony_ciSLOOP: 550362306a36Sopenharmony_ci fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 550462306a36Sopenharmony_ci mov.w INARG(%a6),%d1 550562306a36Sopenharmony_ci mov.l %d1,%a1 # save a copy of D0 550662306a36Sopenharmony_ci and.l &0x00007FFF,%d1 550762306a36Sopenharmony_ci sub.l &0x00003FFF,%d1 # d0 = K 550862306a36Sopenharmony_ci cmp.l %d1,&28 550962306a36Sopenharmony_ci ble.b SLASTLOOP 551062306a36Sopenharmony_ciSCONTLOOP: 551162306a36Sopenharmony_ci sub.l &27,%d1 # d0 = L := K-27 551262306a36Sopenharmony_ci mov.b &0,ENDFLAG(%a6) 551362306a36Sopenharmony_ci bra.b SWORK 551462306a36Sopenharmony_ciSLASTLOOP: 551562306a36Sopenharmony_ci clr.l %d1 # d0 = L := 0 551662306a36Sopenharmony_ci mov.b &1,ENDFLAG(%a6) 551762306a36Sopenharmony_ci 551862306a36Sopenharmony_ciSWORK: 551962306a36Sopenharmony_ci#--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 552062306a36Sopenharmony_ci#--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 552162306a36Sopenharmony_ci 552262306a36Sopenharmony_ci#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 552362306a36Sopenharmony_ci#--2**L * (PIby2_1), 2**L * (PIby2_2) 552462306a36Sopenharmony_ci 552562306a36Sopenharmony_ci mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 552662306a36Sopenharmony_ci sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 552762306a36Sopenharmony_ci 552862306a36Sopenharmony_ci mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 552962306a36Sopenharmony_ci mov.l &0x4E44152A,FP_SCR0_LO(%a6) 553062306a36Sopenharmony_ci mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 553162306a36Sopenharmony_ci 553262306a36Sopenharmony_ci fmov.x %fp0,%fp2 553362306a36Sopenharmony_ci fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 553462306a36Sopenharmony_ci 553562306a36Sopenharmony_ci#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 553662306a36Sopenharmony_ci#--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 553762306a36Sopenharmony_ci#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 553862306a36Sopenharmony_ci#--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 553962306a36Sopenharmony_ci#--US THE DESIRED VALUE IN FLOATING POINT. 554062306a36Sopenharmony_ci mov.l %a1,%d2 554162306a36Sopenharmony_ci swap %d2 554262306a36Sopenharmony_ci and.l &0x80000000,%d2 554362306a36Sopenharmony_ci or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 554462306a36Sopenharmony_ci mov.l %d2,TWOTO63(%a6) 554562306a36Sopenharmony_ci fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 554662306a36Sopenharmony_ci fsub.s TWOTO63(%a6),%fp2 # fp2 = N 554762306a36Sopenharmony_ci# fint.x %fp2 554862306a36Sopenharmony_ci 554962306a36Sopenharmony_ci#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 555062306a36Sopenharmony_ci mov.l %d1,%d2 # d2 = L 555162306a36Sopenharmony_ci 555262306a36Sopenharmony_ci add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 555362306a36Sopenharmony_ci mov.w %d2,FP_SCR0_EX(%a6) 555462306a36Sopenharmony_ci mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 555562306a36Sopenharmony_ci clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 555662306a36Sopenharmony_ci 555762306a36Sopenharmony_ci add.l &0x00003FDD,%d1 555862306a36Sopenharmony_ci mov.w %d1,FP_SCR1_EX(%a6) 555962306a36Sopenharmony_ci mov.l &0x85A308D3,FP_SCR1_HI(%a6) 556062306a36Sopenharmony_ci clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 556162306a36Sopenharmony_ci 556262306a36Sopenharmony_ci mov.b ENDFLAG(%a6),%d1 556362306a36Sopenharmony_ci 556462306a36Sopenharmony_ci#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 556562306a36Sopenharmony_ci#--P2 = 2**(L) * Piby2_2 556662306a36Sopenharmony_ci fmov.x %fp2,%fp4 # fp4 = N 556762306a36Sopenharmony_ci fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 556862306a36Sopenharmony_ci fmov.x %fp2,%fp5 # fp5 = N 556962306a36Sopenharmony_ci fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 557062306a36Sopenharmony_ci fmov.x %fp4,%fp3 # fp3 = W = N*P1 557162306a36Sopenharmony_ci 557262306a36Sopenharmony_ci#--we want P+p = W+w but |p| <= half ulp of P 557362306a36Sopenharmony_ci#--Then, we need to compute A := R-P and a := r-p 557462306a36Sopenharmony_ci fadd.x %fp5,%fp3 # fp3 = P 557562306a36Sopenharmony_ci fsub.x %fp3,%fp4 # fp4 = W-P 557662306a36Sopenharmony_ci 557762306a36Sopenharmony_ci fsub.x %fp3,%fp0 # fp0 = A := R - P 557862306a36Sopenharmony_ci fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 557962306a36Sopenharmony_ci 558062306a36Sopenharmony_ci fmov.x %fp0,%fp3 # fp3 = A 558162306a36Sopenharmony_ci fsub.x %fp4,%fp1 # fp1 = a := r - p 558262306a36Sopenharmony_ci 558362306a36Sopenharmony_ci#--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 558462306a36Sopenharmony_ci#--|r| <= half ulp of R. 558562306a36Sopenharmony_ci fadd.x %fp1,%fp0 # fp0 = R := A+a 558662306a36Sopenharmony_ci#--No need to calculate r if this is the last loop 558762306a36Sopenharmony_ci cmp.b %d1,&0 558862306a36Sopenharmony_ci bgt.w SRESTORE 558962306a36Sopenharmony_ci 559062306a36Sopenharmony_ci#--Need to calculate r 559162306a36Sopenharmony_ci fsub.x %fp0,%fp3 # fp3 = A-R 559262306a36Sopenharmony_ci fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 559362306a36Sopenharmony_ci bra.w SLOOP 559462306a36Sopenharmony_ci 559562306a36Sopenharmony_ciSRESTORE: 559662306a36Sopenharmony_ci fmov.l %fp2,INT(%a6) 559762306a36Sopenharmony_ci mov.l (%sp)+,%d2 # restore d2 559862306a36Sopenharmony_ci fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 559962306a36Sopenharmony_ci 560062306a36Sopenharmony_ci mov.l ADJN(%a6),%d1 560162306a36Sopenharmony_ci cmp.l %d1,&4 560262306a36Sopenharmony_ci 560362306a36Sopenharmony_ci blt.w SINCONT 560462306a36Sopenharmony_ci bra.w SCCONT 560562306a36Sopenharmony_ci 560662306a36Sopenharmony_ci######################################################################### 560762306a36Sopenharmony_ci# stan(): computes the tangent of a normalized input # 560862306a36Sopenharmony_ci# stand(): computes the tangent of a denormalized input # 560962306a36Sopenharmony_ci# # 561062306a36Sopenharmony_ci# INPUT *************************************************************** # 561162306a36Sopenharmony_ci# a0 = pointer to extended precision input # 561262306a36Sopenharmony_ci# d0 = round precision,mode # 561362306a36Sopenharmony_ci# # 561462306a36Sopenharmony_ci# OUTPUT ************************************************************** # 561562306a36Sopenharmony_ci# fp0 = tan(X) # 561662306a36Sopenharmony_ci# # 561762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 561862306a36Sopenharmony_ci# The returned result is within 3 ulp in 64 significant bit, i.e. # 561962306a36Sopenharmony_ci# within 0.5001 ulp to 53 bits if the result is subsequently # 562062306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 562162306a36Sopenharmony_ci# in double precision. # 562262306a36Sopenharmony_ci# # 562362306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 562462306a36Sopenharmony_ci# # 562562306a36Sopenharmony_ci# 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 562662306a36Sopenharmony_ci# # 562762306a36Sopenharmony_ci# 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 562862306a36Sopenharmony_ci# k = N mod 2, so in particular, k = 0 or 1. # 562962306a36Sopenharmony_ci# # 563062306a36Sopenharmony_ci# 3. If k is odd, go to 5. # 563162306a36Sopenharmony_ci# # 563262306a36Sopenharmony_ci# 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a # 563362306a36Sopenharmony_ci# rational function U/V where # 563462306a36Sopenharmony_ci# U = r + r*s*(P1 + s*(P2 + s*P3)), and # 563562306a36Sopenharmony_ci# V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. # 563662306a36Sopenharmony_ci# Exit. # 563762306a36Sopenharmony_ci# # 563862306a36Sopenharmony_ci# 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by # 563962306a36Sopenharmony_ci# a rational function U/V where # 564062306a36Sopenharmony_ci# U = r + r*s*(P1 + s*(P2 + s*P3)), and # 564162306a36Sopenharmony_ci# V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, # 564262306a36Sopenharmony_ci# -Cot(r) = -V/U. Exit. # 564362306a36Sopenharmony_ci# # 564462306a36Sopenharmony_ci# 6. If |X| > 1, go to 8. # 564562306a36Sopenharmony_ci# # 564662306a36Sopenharmony_ci# 7. (|X|<2**(-40)) Tan(X) = X. Exit. # 564762306a36Sopenharmony_ci# # 564862306a36Sopenharmony_ci# 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back # 564962306a36Sopenharmony_ci# to 2. # 565062306a36Sopenharmony_ci# # 565162306a36Sopenharmony_ci######################################################################### 565262306a36Sopenharmony_ci 565362306a36Sopenharmony_ciTANQ4: 565462306a36Sopenharmony_ci long 0x3EA0B759,0xF50F8688 565562306a36Sopenharmony_ciTANP3: 565662306a36Sopenharmony_ci long 0xBEF2BAA5,0xA8924F04 565762306a36Sopenharmony_ci 565862306a36Sopenharmony_ciTANQ3: 565962306a36Sopenharmony_ci long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000 566062306a36Sopenharmony_ci 566162306a36Sopenharmony_ciTANP2: 566262306a36Sopenharmony_ci long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000 566362306a36Sopenharmony_ci 566462306a36Sopenharmony_ciTANQ2: 566562306a36Sopenharmony_ci long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000 566662306a36Sopenharmony_ci 566762306a36Sopenharmony_ciTANP1: 566862306a36Sopenharmony_ci long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000 566962306a36Sopenharmony_ci 567062306a36Sopenharmony_ciTANQ1: 567162306a36Sopenharmony_ci long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000 567262306a36Sopenharmony_ci 567362306a36Sopenharmony_ciINVTWOPI: 567462306a36Sopenharmony_ci long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000 567562306a36Sopenharmony_ci 567662306a36Sopenharmony_ciTWOPI1: 567762306a36Sopenharmony_ci long 0x40010000,0xC90FDAA2,0x00000000,0x00000000 567862306a36Sopenharmony_ciTWOPI2: 567962306a36Sopenharmony_ci long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000 568062306a36Sopenharmony_ci 568162306a36Sopenharmony_ci#--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING 568262306a36Sopenharmony_ci#--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT 568362306a36Sopenharmony_ci#--MOST 69 BITS LONG. 568462306a36Sopenharmony_ci# global PITBL 568562306a36Sopenharmony_ciPITBL: 568662306a36Sopenharmony_ci long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000 568762306a36Sopenharmony_ci long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000 568862306a36Sopenharmony_ci long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000 568962306a36Sopenharmony_ci long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000 569062306a36Sopenharmony_ci long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000 569162306a36Sopenharmony_ci long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000 569262306a36Sopenharmony_ci long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000 569362306a36Sopenharmony_ci long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000 569462306a36Sopenharmony_ci long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000 569562306a36Sopenharmony_ci long 0xC0040000,0x90836524,0x88034B96,0x20B00000 569662306a36Sopenharmony_ci long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000 569762306a36Sopenharmony_ci long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000 569862306a36Sopenharmony_ci long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000 569962306a36Sopenharmony_ci long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000 570062306a36Sopenharmony_ci long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000 570162306a36Sopenharmony_ci long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000 570262306a36Sopenharmony_ci long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000 570362306a36Sopenharmony_ci long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000 570462306a36Sopenharmony_ci long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000 570562306a36Sopenharmony_ci long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000 570662306a36Sopenharmony_ci long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000 570762306a36Sopenharmony_ci long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000 570862306a36Sopenharmony_ci long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000 570962306a36Sopenharmony_ci long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000 571062306a36Sopenharmony_ci long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000 571162306a36Sopenharmony_ci long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000 571262306a36Sopenharmony_ci long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000 571362306a36Sopenharmony_ci long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000 571462306a36Sopenharmony_ci long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000 571562306a36Sopenharmony_ci long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000 571662306a36Sopenharmony_ci long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000 571762306a36Sopenharmony_ci long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000 571862306a36Sopenharmony_ci long 0x00000000,0x00000000,0x00000000,0x00000000 571962306a36Sopenharmony_ci long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000 572062306a36Sopenharmony_ci long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000 572162306a36Sopenharmony_ci long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000 572262306a36Sopenharmony_ci long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000 572362306a36Sopenharmony_ci long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000 572462306a36Sopenharmony_ci long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000 572562306a36Sopenharmony_ci long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000 572662306a36Sopenharmony_ci long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000 572762306a36Sopenharmony_ci long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000 572862306a36Sopenharmony_ci long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000 572962306a36Sopenharmony_ci long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000 573062306a36Sopenharmony_ci long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000 573162306a36Sopenharmony_ci long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000 573262306a36Sopenharmony_ci long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000 573362306a36Sopenharmony_ci long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000 573462306a36Sopenharmony_ci long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000 573562306a36Sopenharmony_ci long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000 573662306a36Sopenharmony_ci long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000 573762306a36Sopenharmony_ci long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000 573862306a36Sopenharmony_ci long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000 573962306a36Sopenharmony_ci long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000 574062306a36Sopenharmony_ci long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000 574162306a36Sopenharmony_ci long 0x40040000,0x90836524,0x88034B96,0xA0B00000 574262306a36Sopenharmony_ci long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000 574362306a36Sopenharmony_ci long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000 574462306a36Sopenharmony_ci long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000 574562306a36Sopenharmony_ci long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000 574662306a36Sopenharmony_ci long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000 574762306a36Sopenharmony_ci long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000 574862306a36Sopenharmony_ci long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000 574962306a36Sopenharmony_ci long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000 575062306a36Sopenharmony_ci long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000 575162306a36Sopenharmony_ci 575262306a36Sopenharmony_ci set INARG,FP_SCR0 575362306a36Sopenharmony_ci 575462306a36Sopenharmony_ci set TWOTO63,L_SCR1 575562306a36Sopenharmony_ci set INT,L_SCR1 575662306a36Sopenharmony_ci set ENDFLAG,L_SCR2 575762306a36Sopenharmony_ci 575862306a36Sopenharmony_ci global stan 575962306a36Sopenharmony_cistan: 576062306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 576162306a36Sopenharmony_ci 576262306a36Sopenharmony_ci mov.l (%a0),%d1 576362306a36Sopenharmony_ci mov.w 4(%a0),%d1 576462306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 576562306a36Sopenharmony_ci 576662306a36Sopenharmony_ci cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 576762306a36Sopenharmony_ci bge.b TANOK1 576862306a36Sopenharmony_ci bra.w TANSM 576962306a36Sopenharmony_ciTANOK1: 577062306a36Sopenharmony_ci cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 577162306a36Sopenharmony_ci blt.b TANMAIN 577262306a36Sopenharmony_ci bra.w REDUCEX 577362306a36Sopenharmony_ci 577462306a36Sopenharmony_ciTANMAIN: 577562306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| <= 15 PI. 577662306a36Sopenharmony_ci#--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 577762306a36Sopenharmony_ci fmov.x %fp0,%fp1 577862306a36Sopenharmony_ci fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 577962306a36Sopenharmony_ci 578062306a36Sopenharmony_ci lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 578162306a36Sopenharmony_ci 578262306a36Sopenharmony_ci fmov.l %fp1,%d1 # CONVERT TO INTEGER 578362306a36Sopenharmony_ci 578462306a36Sopenharmony_ci asl.l &4,%d1 578562306a36Sopenharmony_ci add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2 578662306a36Sopenharmony_ci 578762306a36Sopenharmony_ci fsub.x (%a1)+,%fp0 # X-Y1 578862306a36Sopenharmony_ci 578962306a36Sopenharmony_ci fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 579062306a36Sopenharmony_ci 579162306a36Sopenharmony_ci ror.l &5,%d1 579262306a36Sopenharmony_ci and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0 579362306a36Sopenharmony_ci 579462306a36Sopenharmony_ciTANCONT: 579562306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2,fp3 579662306a36Sopenharmony_ci 579762306a36Sopenharmony_ci cmp.l %d1,&0 579862306a36Sopenharmony_ci blt.w NODD 579962306a36Sopenharmony_ci 580062306a36Sopenharmony_ci fmov.x %fp0,%fp1 580162306a36Sopenharmony_ci fmul.x %fp1,%fp1 # S = R*R 580262306a36Sopenharmony_ci 580362306a36Sopenharmony_ci fmov.d TANQ4(%pc),%fp3 580462306a36Sopenharmony_ci fmov.d TANP3(%pc),%fp2 580562306a36Sopenharmony_ci 580662306a36Sopenharmony_ci fmul.x %fp1,%fp3 # SQ4 580762306a36Sopenharmony_ci fmul.x %fp1,%fp2 # SP3 580862306a36Sopenharmony_ci 580962306a36Sopenharmony_ci fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 581062306a36Sopenharmony_ci fadd.x TANP2(%pc),%fp2 # P2+SP3 581162306a36Sopenharmony_ci 581262306a36Sopenharmony_ci fmul.x %fp1,%fp3 # S(Q3+SQ4) 581362306a36Sopenharmony_ci fmul.x %fp1,%fp2 # S(P2+SP3) 581462306a36Sopenharmony_ci 581562306a36Sopenharmony_ci fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 581662306a36Sopenharmony_ci fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 581762306a36Sopenharmony_ci 581862306a36Sopenharmony_ci fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4)) 581962306a36Sopenharmony_ci fmul.x %fp1,%fp2 # S(P1+S(P2+SP3)) 582062306a36Sopenharmony_ci 582162306a36Sopenharmony_ci fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 582262306a36Sopenharmony_ci fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3)) 582362306a36Sopenharmony_ci 582462306a36Sopenharmony_ci fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4))) 582562306a36Sopenharmony_ci 582662306a36Sopenharmony_ci fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3)) 582762306a36Sopenharmony_ci 582862306a36Sopenharmony_ci fadd.s &0x3F800000,%fp1 # 1+S(Q1+...) 582962306a36Sopenharmony_ci 583062306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2,fp3 583162306a36Sopenharmony_ci 583262306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 583362306a36Sopenharmony_ci fdiv.x %fp1,%fp0 # last inst - possible exception set 583462306a36Sopenharmony_ci bra t_inx2 583562306a36Sopenharmony_ci 583662306a36Sopenharmony_ciNODD: 583762306a36Sopenharmony_ci fmov.x %fp0,%fp1 583862306a36Sopenharmony_ci fmul.x %fp0,%fp0 # S = R*R 583962306a36Sopenharmony_ci 584062306a36Sopenharmony_ci fmov.d TANQ4(%pc),%fp3 584162306a36Sopenharmony_ci fmov.d TANP3(%pc),%fp2 584262306a36Sopenharmony_ci 584362306a36Sopenharmony_ci fmul.x %fp0,%fp3 # SQ4 584462306a36Sopenharmony_ci fmul.x %fp0,%fp2 # SP3 584562306a36Sopenharmony_ci 584662306a36Sopenharmony_ci fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 584762306a36Sopenharmony_ci fadd.x TANP2(%pc),%fp2 # P2+SP3 584862306a36Sopenharmony_ci 584962306a36Sopenharmony_ci fmul.x %fp0,%fp3 # S(Q3+SQ4) 585062306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(P2+SP3) 585162306a36Sopenharmony_ci 585262306a36Sopenharmony_ci fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 585362306a36Sopenharmony_ci fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 585462306a36Sopenharmony_ci 585562306a36Sopenharmony_ci fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4)) 585662306a36Sopenharmony_ci fmul.x %fp0,%fp2 # S(P1+S(P2+SP3)) 585762306a36Sopenharmony_ci 585862306a36Sopenharmony_ci fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 585962306a36Sopenharmony_ci fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3)) 586062306a36Sopenharmony_ci 586162306a36Sopenharmony_ci fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4))) 586262306a36Sopenharmony_ci 586362306a36Sopenharmony_ci fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3)) 586462306a36Sopenharmony_ci fadd.s &0x3F800000,%fp0 # 1+S(Q1+...) 586562306a36Sopenharmony_ci 586662306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2,fp3 586762306a36Sopenharmony_ci 586862306a36Sopenharmony_ci fmov.x %fp1,-(%sp) 586962306a36Sopenharmony_ci eor.l &0x80000000,(%sp) 587062306a36Sopenharmony_ci 587162306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 587262306a36Sopenharmony_ci fdiv.x (%sp)+,%fp0 # last inst - possible exception set 587362306a36Sopenharmony_ci bra t_inx2 587462306a36Sopenharmony_ci 587562306a36Sopenharmony_ciTANBORS: 587662306a36Sopenharmony_ci#--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 587762306a36Sopenharmony_ci#--IF |X| < 2**(-40), RETURN X OR 1. 587862306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 587962306a36Sopenharmony_ci bgt.b REDUCEX 588062306a36Sopenharmony_ci 588162306a36Sopenharmony_ciTANSM: 588262306a36Sopenharmony_ci fmov.x %fp0,-(%sp) 588362306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round mode,prec 588462306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 588562306a36Sopenharmony_ci fmov.x (%sp)+,%fp0 # last inst - posibble exception set 588662306a36Sopenharmony_ci bra t_catch 588762306a36Sopenharmony_ci 588862306a36Sopenharmony_ci global stand 588962306a36Sopenharmony_ci#--TAN(X) = X FOR DENORMALIZED X 589062306a36Sopenharmony_cistand: 589162306a36Sopenharmony_ci bra t_extdnrm 589262306a36Sopenharmony_ci 589362306a36Sopenharmony_ci#--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 589462306a36Sopenharmony_ci#--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 589562306a36Sopenharmony_ci#--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 589662306a36Sopenharmony_ciREDUCEX: 589762306a36Sopenharmony_ci fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 589862306a36Sopenharmony_ci mov.l %d2,-(%sp) # save d2 589962306a36Sopenharmony_ci fmov.s &0x00000000,%fp1 # fp1 = 0 590062306a36Sopenharmony_ci 590162306a36Sopenharmony_ci#--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 590262306a36Sopenharmony_ci#--there is a danger of unwanted overflow in first LOOP iteration. In this 590362306a36Sopenharmony_ci#--case, reduce argument by one remainder step to make subsequent reduction 590462306a36Sopenharmony_ci#--safe. 590562306a36Sopenharmony_ci cmp.l %d1,&0x7ffeffff # is arg dangerously large? 590662306a36Sopenharmony_ci bne.b LOOP # no 590762306a36Sopenharmony_ci 590862306a36Sopenharmony_ci# yes; create 2**16383*PI/2 590962306a36Sopenharmony_ci mov.w &0x7ffe,FP_SCR0_EX(%a6) 591062306a36Sopenharmony_ci mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 591162306a36Sopenharmony_ci clr.l FP_SCR0_LO(%a6) 591262306a36Sopenharmony_ci 591362306a36Sopenharmony_ci# create low half of 2**16383*PI/2 at FP_SCR1 591462306a36Sopenharmony_ci mov.w &0x7fdc,FP_SCR1_EX(%a6) 591562306a36Sopenharmony_ci mov.l &0x85a308d3,FP_SCR1_HI(%a6) 591662306a36Sopenharmony_ci clr.l FP_SCR1_LO(%a6) 591762306a36Sopenharmony_ci 591862306a36Sopenharmony_ci ftest.x %fp0 # test sign of argument 591962306a36Sopenharmony_ci fblt.w red_neg 592062306a36Sopenharmony_ci 592162306a36Sopenharmony_ci or.b &0x80,FP_SCR0_EX(%a6) # positive arg 592262306a36Sopenharmony_ci or.b &0x80,FP_SCR1_EX(%a6) 592362306a36Sopenharmony_cired_neg: 592462306a36Sopenharmony_ci fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 592562306a36Sopenharmony_ci fmov.x %fp0,%fp1 # save high result in fp1 592662306a36Sopenharmony_ci fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 592762306a36Sopenharmony_ci fsub.x %fp0,%fp1 # determine low component of result 592862306a36Sopenharmony_ci fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 592962306a36Sopenharmony_ci 593062306a36Sopenharmony_ci#--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 593162306a36Sopenharmony_ci#--integer quotient will be stored in N 593262306a36Sopenharmony_ci#--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 593362306a36Sopenharmony_ciLOOP: 593462306a36Sopenharmony_ci fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 593562306a36Sopenharmony_ci mov.w INARG(%a6),%d1 593662306a36Sopenharmony_ci mov.l %d1,%a1 # save a copy of D0 593762306a36Sopenharmony_ci and.l &0x00007FFF,%d1 593862306a36Sopenharmony_ci sub.l &0x00003FFF,%d1 # d0 = K 593962306a36Sopenharmony_ci cmp.l %d1,&28 594062306a36Sopenharmony_ci ble.b LASTLOOP 594162306a36Sopenharmony_ciCONTLOOP: 594262306a36Sopenharmony_ci sub.l &27,%d1 # d0 = L := K-27 594362306a36Sopenharmony_ci mov.b &0,ENDFLAG(%a6) 594462306a36Sopenharmony_ci bra.b WORK 594562306a36Sopenharmony_ciLASTLOOP: 594662306a36Sopenharmony_ci clr.l %d1 # d0 = L := 0 594762306a36Sopenharmony_ci mov.b &1,ENDFLAG(%a6) 594862306a36Sopenharmony_ci 594962306a36Sopenharmony_ciWORK: 595062306a36Sopenharmony_ci#--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 595162306a36Sopenharmony_ci#--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 595262306a36Sopenharmony_ci 595362306a36Sopenharmony_ci#--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 595462306a36Sopenharmony_ci#--2**L * (PIby2_1), 2**L * (PIby2_2) 595562306a36Sopenharmony_ci 595662306a36Sopenharmony_ci mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 595762306a36Sopenharmony_ci sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 595862306a36Sopenharmony_ci 595962306a36Sopenharmony_ci mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 596062306a36Sopenharmony_ci mov.l &0x4E44152A,FP_SCR0_LO(%a6) 596162306a36Sopenharmony_ci mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 596262306a36Sopenharmony_ci 596362306a36Sopenharmony_ci fmov.x %fp0,%fp2 596462306a36Sopenharmony_ci fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 596562306a36Sopenharmony_ci 596662306a36Sopenharmony_ci#--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 596762306a36Sopenharmony_ci#--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 596862306a36Sopenharmony_ci#--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 596962306a36Sopenharmony_ci#--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 597062306a36Sopenharmony_ci#--US THE DESIRED VALUE IN FLOATING POINT. 597162306a36Sopenharmony_ci mov.l %a1,%d2 597262306a36Sopenharmony_ci swap %d2 597362306a36Sopenharmony_ci and.l &0x80000000,%d2 597462306a36Sopenharmony_ci or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 597562306a36Sopenharmony_ci mov.l %d2,TWOTO63(%a6) 597662306a36Sopenharmony_ci fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 597762306a36Sopenharmony_ci fsub.s TWOTO63(%a6),%fp2 # fp2 = N 597862306a36Sopenharmony_ci# fintrz.x %fp2,%fp2 597962306a36Sopenharmony_ci 598062306a36Sopenharmony_ci#--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 598162306a36Sopenharmony_ci mov.l %d1,%d2 # d2 = L 598262306a36Sopenharmony_ci 598362306a36Sopenharmony_ci add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 598462306a36Sopenharmony_ci mov.w %d2,FP_SCR0_EX(%a6) 598562306a36Sopenharmony_ci mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 598662306a36Sopenharmony_ci clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 598762306a36Sopenharmony_ci 598862306a36Sopenharmony_ci add.l &0x00003FDD,%d1 598962306a36Sopenharmony_ci mov.w %d1,FP_SCR1_EX(%a6) 599062306a36Sopenharmony_ci mov.l &0x85A308D3,FP_SCR1_HI(%a6) 599162306a36Sopenharmony_ci clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 599262306a36Sopenharmony_ci 599362306a36Sopenharmony_ci mov.b ENDFLAG(%a6),%d1 599462306a36Sopenharmony_ci 599562306a36Sopenharmony_ci#--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 599662306a36Sopenharmony_ci#--P2 = 2**(L) * Piby2_2 599762306a36Sopenharmony_ci fmov.x %fp2,%fp4 # fp4 = N 599862306a36Sopenharmony_ci fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 599962306a36Sopenharmony_ci fmov.x %fp2,%fp5 # fp5 = N 600062306a36Sopenharmony_ci fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 600162306a36Sopenharmony_ci fmov.x %fp4,%fp3 # fp3 = W = N*P1 600262306a36Sopenharmony_ci 600362306a36Sopenharmony_ci#--we want P+p = W+w but |p| <= half ulp of P 600462306a36Sopenharmony_ci#--Then, we need to compute A := R-P and a := r-p 600562306a36Sopenharmony_ci fadd.x %fp5,%fp3 # fp3 = P 600662306a36Sopenharmony_ci fsub.x %fp3,%fp4 # fp4 = W-P 600762306a36Sopenharmony_ci 600862306a36Sopenharmony_ci fsub.x %fp3,%fp0 # fp0 = A := R - P 600962306a36Sopenharmony_ci fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 601062306a36Sopenharmony_ci 601162306a36Sopenharmony_ci fmov.x %fp0,%fp3 # fp3 = A 601262306a36Sopenharmony_ci fsub.x %fp4,%fp1 # fp1 = a := r - p 601362306a36Sopenharmony_ci 601462306a36Sopenharmony_ci#--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 601562306a36Sopenharmony_ci#--|r| <= half ulp of R. 601662306a36Sopenharmony_ci fadd.x %fp1,%fp0 # fp0 = R := A+a 601762306a36Sopenharmony_ci#--No need to calculate r if this is the last loop 601862306a36Sopenharmony_ci cmp.b %d1,&0 601962306a36Sopenharmony_ci bgt.w RESTORE 602062306a36Sopenharmony_ci 602162306a36Sopenharmony_ci#--Need to calculate r 602262306a36Sopenharmony_ci fsub.x %fp0,%fp3 # fp3 = A-R 602362306a36Sopenharmony_ci fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 602462306a36Sopenharmony_ci bra.w LOOP 602562306a36Sopenharmony_ci 602662306a36Sopenharmony_ciRESTORE: 602762306a36Sopenharmony_ci fmov.l %fp2,INT(%a6) 602862306a36Sopenharmony_ci mov.l (%sp)+,%d2 # restore d2 602962306a36Sopenharmony_ci fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 603062306a36Sopenharmony_ci 603162306a36Sopenharmony_ci mov.l INT(%a6),%d1 603262306a36Sopenharmony_ci ror.l &1,%d1 603362306a36Sopenharmony_ci 603462306a36Sopenharmony_ci bra.w TANCONT 603562306a36Sopenharmony_ci 603662306a36Sopenharmony_ci######################################################################### 603762306a36Sopenharmony_ci# satan(): computes the arctangent of a normalized number # 603862306a36Sopenharmony_ci# satand(): computes the arctangent of a denormalized number # 603962306a36Sopenharmony_ci# # 604062306a36Sopenharmony_ci# INPUT *************************************************************** # 604162306a36Sopenharmony_ci# a0 = pointer to extended precision input # 604262306a36Sopenharmony_ci# d0 = round precision,mode # 604362306a36Sopenharmony_ci# # 604462306a36Sopenharmony_ci# OUTPUT ************************************************************** # 604562306a36Sopenharmony_ci# fp0 = arctan(X) # 604662306a36Sopenharmony_ci# # 604762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 604862306a36Sopenharmony_ci# The returned result is within 2 ulps in 64 significant bit, # 604962306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 605062306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 605162306a36Sopenharmony_ci# in double precision. # 605262306a36Sopenharmony_ci# # 605362306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 605462306a36Sopenharmony_ci# Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. # 605562306a36Sopenharmony_ci# # 605662306a36Sopenharmony_ci# Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. # 605762306a36Sopenharmony_ci# Note that k = -4, -3,..., or 3. # 605862306a36Sopenharmony_ci# Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 # 605962306a36Sopenharmony_ci# significant bits of X with a bit-1 attached at the 6-th # 606062306a36Sopenharmony_ci# bit position. Define u to be u = (X-F) / (1 + X*F). # 606162306a36Sopenharmony_ci# # 606262306a36Sopenharmony_ci# Step 3. Approximate arctan(u) by a polynomial poly. # 606362306a36Sopenharmony_ci# # 606462306a36Sopenharmony_ci# Step 4. Return arctan(F) + poly, arctan(F) is fetched from a # 606562306a36Sopenharmony_ci# table of values calculated beforehand. Exit. # 606662306a36Sopenharmony_ci# # 606762306a36Sopenharmony_ci# Step 5. If |X| >= 16, go to Step 7. # 606862306a36Sopenharmony_ci# # 606962306a36Sopenharmony_ci# Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. # 607062306a36Sopenharmony_ci# # 607162306a36Sopenharmony_ci# Step 7. Define X' = -1/X. Approximate arctan(X') by an odd # 607262306a36Sopenharmony_ci# polynomial in X'. # 607362306a36Sopenharmony_ci# Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. # 607462306a36Sopenharmony_ci# # 607562306a36Sopenharmony_ci######################################################################### 607662306a36Sopenharmony_ci 607762306a36Sopenharmony_ciATANA3: long 0xBFF6687E,0x314987D8 607862306a36Sopenharmony_ciATANA2: long 0x4002AC69,0x34A26DB3 607962306a36Sopenharmony_ciATANA1: long 0xBFC2476F,0x4E1DA28E 608062306a36Sopenharmony_ci 608162306a36Sopenharmony_ciATANB6: long 0x3FB34444,0x7F876989 608262306a36Sopenharmony_ciATANB5: long 0xBFB744EE,0x7FAF45DB 608362306a36Sopenharmony_ciATANB4: long 0x3FBC71C6,0x46940220 608462306a36Sopenharmony_ciATANB3: long 0xBFC24924,0x921872F9 608562306a36Sopenharmony_ciATANB2: long 0x3FC99999,0x99998FA9 608662306a36Sopenharmony_ciATANB1: long 0xBFD55555,0x55555555 608762306a36Sopenharmony_ci 608862306a36Sopenharmony_ciATANC5: long 0xBFB70BF3,0x98539E6A 608962306a36Sopenharmony_ciATANC4: long 0x3FBC7187,0x962D1D7D 609062306a36Sopenharmony_ciATANC3: long 0xBFC24924,0x827107B8 609162306a36Sopenharmony_ciATANC2: long 0x3FC99999,0x9996263E 609262306a36Sopenharmony_ciATANC1: long 0xBFD55555,0x55555536 609362306a36Sopenharmony_ci 609462306a36Sopenharmony_ciPPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 609562306a36Sopenharmony_ciNPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000 609662306a36Sopenharmony_ci 609762306a36Sopenharmony_ciPTINY: long 0x00010000,0x80000000,0x00000000,0x00000000 609862306a36Sopenharmony_ciNTINY: long 0x80010000,0x80000000,0x00000000,0x00000000 609962306a36Sopenharmony_ci 610062306a36Sopenharmony_ciATANTBL: 610162306a36Sopenharmony_ci long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000 610262306a36Sopenharmony_ci long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000 610362306a36Sopenharmony_ci long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000 610462306a36Sopenharmony_ci long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000 610562306a36Sopenharmony_ci long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000 610662306a36Sopenharmony_ci long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000 610762306a36Sopenharmony_ci long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000 610862306a36Sopenharmony_ci long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000 610962306a36Sopenharmony_ci long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000 611062306a36Sopenharmony_ci long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000 611162306a36Sopenharmony_ci long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000 611262306a36Sopenharmony_ci long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000 611362306a36Sopenharmony_ci long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000 611462306a36Sopenharmony_ci long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000 611562306a36Sopenharmony_ci long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000 611662306a36Sopenharmony_ci long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000 611762306a36Sopenharmony_ci long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000 611862306a36Sopenharmony_ci long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000 611962306a36Sopenharmony_ci long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000 612062306a36Sopenharmony_ci long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000 612162306a36Sopenharmony_ci long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000 612262306a36Sopenharmony_ci long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000 612362306a36Sopenharmony_ci long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000 612462306a36Sopenharmony_ci long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000 612562306a36Sopenharmony_ci long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000 612662306a36Sopenharmony_ci long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000 612762306a36Sopenharmony_ci long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000 612862306a36Sopenharmony_ci long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000 612962306a36Sopenharmony_ci long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000 613062306a36Sopenharmony_ci long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000 613162306a36Sopenharmony_ci long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000 613262306a36Sopenharmony_ci long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000 613362306a36Sopenharmony_ci long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000 613462306a36Sopenharmony_ci long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000 613562306a36Sopenharmony_ci long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000 613662306a36Sopenharmony_ci long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000 613762306a36Sopenharmony_ci long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000 613862306a36Sopenharmony_ci long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000 613962306a36Sopenharmony_ci long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000 614062306a36Sopenharmony_ci long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000 614162306a36Sopenharmony_ci long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000 614262306a36Sopenharmony_ci long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000 614362306a36Sopenharmony_ci long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000 614462306a36Sopenharmony_ci long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000 614562306a36Sopenharmony_ci long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000 614662306a36Sopenharmony_ci long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000 614762306a36Sopenharmony_ci long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000 614862306a36Sopenharmony_ci long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000 614962306a36Sopenharmony_ci long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000 615062306a36Sopenharmony_ci long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000 615162306a36Sopenharmony_ci long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000 615262306a36Sopenharmony_ci long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000 615362306a36Sopenharmony_ci long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000 615462306a36Sopenharmony_ci long 0x3FFE0000,0x97731420,0x365E538C,0x00000000 615562306a36Sopenharmony_ci long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000 615662306a36Sopenharmony_ci long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000 615762306a36Sopenharmony_ci long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000 615862306a36Sopenharmony_ci long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000 615962306a36Sopenharmony_ci long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000 616062306a36Sopenharmony_ci long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000 616162306a36Sopenharmony_ci long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000 616262306a36Sopenharmony_ci long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000 616362306a36Sopenharmony_ci long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000 616462306a36Sopenharmony_ci long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000 616562306a36Sopenharmony_ci long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000 616662306a36Sopenharmony_ci long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000 616762306a36Sopenharmony_ci long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000 616862306a36Sopenharmony_ci long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000 616962306a36Sopenharmony_ci long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000 617062306a36Sopenharmony_ci long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000 617162306a36Sopenharmony_ci long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000 617262306a36Sopenharmony_ci long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000 617362306a36Sopenharmony_ci long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000 617462306a36Sopenharmony_ci long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000 617562306a36Sopenharmony_ci long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000 617662306a36Sopenharmony_ci long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000 617762306a36Sopenharmony_ci long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000 617862306a36Sopenharmony_ci long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000 617962306a36Sopenharmony_ci long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000 618062306a36Sopenharmony_ci long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000 618162306a36Sopenharmony_ci long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000 618262306a36Sopenharmony_ci long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000 618362306a36Sopenharmony_ci long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000 618462306a36Sopenharmony_ci long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000 618562306a36Sopenharmony_ci long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000 618662306a36Sopenharmony_ci long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000 618762306a36Sopenharmony_ci long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000 618862306a36Sopenharmony_ci long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000 618962306a36Sopenharmony_ci long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000 619062306a36Sopenharmony_ci long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000 619162306a36Sopenharmony_ci long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000 619262306a36Sopenharmony_ci long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000 619362306a36Sopenharmony_ci long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000 619462306a36Sopenharmony_ci long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000 619562306a36Sopenharmony_ci long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000 619662306a36Sopenharmony_ci long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000 619762306a36Sopenharmony_ci long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000 619862306a36Sopenharmony_ci long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000 619962306a36Sopenharmony_ci long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000 620062306a36Sopenharmony_ci long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000 620162306a36Sopenharmony_ci long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000 620262306a36Sopenharmony_ci long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000 620362306a36Sopenharmony_ci long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000 620462306a36Sopenharmony_ci long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000 620562306a36Sopenharmony_ci long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000 620662306a36Sopenharmony_ci long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000 620762306a36Sopenharmony_ci long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000 620862306a36Sopenharmony_ci long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000 620962306a36Sopenharmony_ci long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000 621062306a36Sopenharmony_ci long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000 621162306a36Sopenharmony_ci long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000 621262306a36Sopenharmony_ci long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000 621362306a36Sopenharmony_ci long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000 621462306a36Sopenharmony_ci long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000 621562306a36Sopenharmony_ci long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000 621662306a36Sopenharmony_ci long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000 621762306a36Sopenharmony_ci long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000 621862306a36Sopenharmony_ci long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000 621962306a36Sopenharmony_ci long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000 622062306a36Sopenharmony_ci long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000 622162306a36Sopenharmony_ci long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000 622262306a36Sopenharmony_ci long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000 622362306a36Sopenharmony_ci long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000 622462306a36Sopenharmony_ci long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000 622562306a36Sopenharmony_ci long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000 622662306a36Sopenharmony_ci long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000 622762306a36Sopenharmony_ci long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000 622862306a36Sopenharmony_ci long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000 622962306a36Sopenharmony_ci 623062306a36Sopenharmony_ci set X,FP_SCR0 623162306a36Sopenharmony_ci set XDCARE,X+2 623262306a36Sopenharmony_ci set XFRAC,X+4 623362306a36Sopenharmony_ci set XFRACLO,X+8 623462306a36Sopenharmony_ci 623562306a36Sopenharmony_ci set ATANF,FP_SCR1 623662306a36Sopenharmony_ci set ATANFHI,ATANF+4 623762306a36Sopenharmony_ci set ATANFLO,ATANF+8 623862306a36Sopenharmony_ci 623962306a36Sopenharmony_ci global satan 624062306a36Sopenharmony_ci#--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 624162306a36Sopenharmony_cisatan: 624262306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 624362306a36Sopenharmony_ci 624462306a36Sopenharmony_ci mov.l (%a0),%d1 624562306a36Sopenharmony_ci mov.w 4(%a0),%d1 624662306a36Sopenharmony_ci fmov.x %fp0,X(%a6) 624762306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 624862306a36Sopenharmony_ci 624962306a36Sopenharmony_ci cmp.l %d1,&0x3FFB8000 # |X| >= 1/16? 625062306a36Sopenharmony_ci bge.b ATANOK1 625162306a36Sopenharmony_ci bra.w ATANSM 625262306a36Sopenharmony_ci 625362306a36Sopenharmony_ciATANOK1: 625462306a36Sopenharmony_ci cmp.l %d1,&0x4002FFFF # |X| < 16 ? 625562306a36Sopenharmony_ci ble.b ATANMAIN 625662306a36Sopenharmony_ci bra.w ATANBIG 625762306a36Sopenharmony_ci 625862306a36Sopenharmony_ci#--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE 625962306a36Sopenharmony_ci#--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ). 626062306a36Sopenharmony_ci#--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN 626162306a36Sopenharmony_ci#--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE 626262306a36Sopenharmony_ci#--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS 626362306a36Sopenharmony_ci#--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR 626462306a36Sopenharmony_ci#--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO 626562306a36Sopenharmony_ci#--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE 626662306a36Sopenharmony_ci#--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL 626762306a36Sopenharmony_ci#--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE 626862306a36Sopenharmony_ci#--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION 626962306a36Sopenharmony_ci#--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION 627062306a36Sopenharmony_ci#--WILL INVOLVE A VERY LONG POLYNOMIAL. 627162306a36Sopenharmony_ci 627262306a36Sopenharmony_ci#--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS 627362306a36Sopenharmony_ci#--WE CHOSE F TO BE +-2^K * 1.BBBB1 627462306a36Sopenharmony_ci#--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE 627562306a36Sopenharmony_ci#--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE 627662306a36Sopenharmony_ci#--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS 627762306a36Sopenharmony_ci#-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|). 627862306a36Sopenharmony_ci 627962306a36Sopenharmony_ciATANMAIN: 628062306a36Sopenharmony_ci 628162306a36Sopenharmony_ci and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS 628262306a36Sopenharmony_ci or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1 628362306a36Sopenharmony_ci mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F 628462306a36Sopenharmony_ci 628562306a36Sopenharmony_ci fmov.x %fp0,%fp1 # FP1 IS X 628662306a36Sopenharmony_ci fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0 628762306a36Sopenharmony_ci fsub.x X(%a6),%fp0 # FP0 IS X-F 628862306a36Sopenharmony_ci fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F 628962306a36Sopenharmony_ci fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F) 629062306a36Sopenharmony_ci 629162306a36Sopenharmony_ci#--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|) 629262306a36Sopenharmony_ci#--CREATE ATAN(F) AND STORE IT IN ATANF, AND 629362306a36Sopenharmony_ci#--SAVE REGISTERS FP2. 629462306a36Sopenharmony_ci 629562306a36Sopenharmony_ci mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY 629662306a36Sopenharmony_ci mov.l %d1,%d2 # THE EXP AND 16 BITS OF X 629762306a36Sopenharmony_ci and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION 629862306a36Sopenharmony_ci and.l &0x7FFF0000,%d2 # EXPONENT OF F 629962306a36Sopenharmony_ci sub.l &0x3FFB0000,%d2 # K+4 630062306a36Sopenharmony_ci asr.l &1,%d2 630162306a36Sopenharmony_ci add.l %d2,%d1 # THE 7 BITS IDENTIFYING F 630262306a36Sopenharmony_ci asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|) 630362306a36Sopenharmony_ci lea ATANTBL(%pc),%a1 630462306a36Sopenharmony_ci add.l %d1,%a1 # ADDRESS OF ATAN(|F|) 630562306a36Sopenharmony_ci mov.l (%a1)+,ATANF(%a6) 630662306a36Sopenharmony_ci mov.l (%a1)+,ATANFHI(%a6) 630762306a36Sopenharmony_ci mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|) 630862306a36Sopenharmony_ci mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN 630962306a36Sopenharmony_ci and.l &0x80000000,%d1 # SIGN(F) 631062306a36Sopenharmony_ci or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|) 631162306a36Sopenharmony_ci mov.l (%sp)+,%d2 # RESTORE d2 631262306a36Sopenharmony_ci 631362306a36Sopenharmony_ci#--THAT'S ALL I HAVE TO DO FOR NOW, 631462306a36Sopenharmony_ci#--BUT ALAS, THE DIVIDE IS STILL CRANKING! 631562306a36Sopenharmony_ci 631662306a36Sopenharmony_ci#--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS 631762306a36Sopenharmony_ci#--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U 631862306a36Sopenharmony_ci#--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT. 631962306a36Sopenharmony_ci#--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3)) 632062306a36Sopenharmony_ci#--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3. 632162306a36Sopenharmony_ci#--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT 632262306a36Sopenharmony_ci#--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED 632362306a36Sopenharmony_ci 632462306a36Sopenharmony_ci fmovm.x &0x04,-(%sp) # save fp2 632562306a36Sopenharmony_ci 632662306a36Sopenharmony_ci fmov.x %fp0,%fp1 632762306a36Sopenharmony_ci fmul.x %fp1,%fp1 632862306a36Sopenharmony_ci fmov.d ATANA3(%pc),%fp2 632962306a36Sopenharmony_ci fadd.x %fp1,%fp2 # A3+V 633062306a36Sopenharmony_ci fmul.x %fp1,%fp2 # V*(A3+V) 633162306a36Sopenharmony_ci fmul.x %fp0,%fp1 # U*V 633262306a36Sopenharmony_ci fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V) 633362306a36Sopenharmony_ci fmul.d ATANA1(%pc),%fp1 # A1*U*V 633462306a36Sopenharmony_ci fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V)) 633562306a36Sopenharmony_ci fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED 633662306a36Sopenharmony_ci 633762306a36Sopenharmony_ci fmovm.x (%sp)+,&0x20 # restore fp2 633862306a36Sopenharmony_ci 633962306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users rnd mode,prec 634062306a36Sopenharmony_ci fadd.x ATANF(%a6),%fp0 # ATAN(X) 634162306a36Sopenharmony_ci bra t_inx2 634262306a36Sopenharmony_ci 634362306a36Sopenharmony_ciATANBORS: 634462306a36Sopenharmony_ci#--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED. 634562306a36Sopenharmony_ci#--FP0 IS X AND |X| <= 1/16 OR |X| >= 16. 634662306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 634762306a36Sopenharmony_ci bgt.w ATANBIG # I.E. |X| >= 16 634862306a36Sopenharmony_ci 634962306a36Sopenharmony_ciATANSM: 635062306a36Sopenharmony_ci#--|X| <= 1/16 635162306a36Sopenharmony_ci#--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE 635262306a36Sopenharmony_ci#--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6))))) 635362306a36Sopenharmony_ci#--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] ) 635462306a36Sopenharmony_ci#--WHERE Y = X*X, AND Z = Y*Y. 635562306a36Sopenharmony_ci 635662306a36Sopenharmony_ci cmp.l %d1,&0x3FD78000 635762306a36Sopenharmony_ci blt.w ATANTINY 635862306a36Sopenharmony_ci 635962306a36Sopenharmony_ci#--COMPUTE POLYNOMIAL 636062306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2/fp3 636162306a36Sopenharmony_ci 636262306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FPO IS Y = X*X 636362306a36Sopenharmony_ci 636462306a36Sopenharmony_ci fmov.x %fp0,%fp1 636562306a36Sopenharmony_ci fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 636662306a36Sopenharmony_ci 636762306a36Sopenharmony_ci fmov.d ATANB6(%pc),%fp2 636862306a36Sopenharmony_ci fmov.d ATANB5(%pc),%fp3 636962306a36Sopenharmony_ci 637062306a36Sopenharmony_ci fmul.x %fp1,%fp2 # Z*B6 637162306a36Sopenharmony_ci fmul.x %fp1,%fp3 # Z*B5 637262306a36Sopenharmony_ci 637362306a36Sopenharmony_ci fadd.d ATANB4(%pc),%fp2 # B4+Z*B6 637462306a36Sopenharmony_ci fadd.d ATANB3(%pc),%fp3 # B3+Z*B5 637562306a36Sopenharmony_ci 637662306a36Sopenharmony_ci fmul.x %fp1,%fp2 # Z*(B4+Z*B6) 637762306a36Sopenharmony_ci fmul.x %fp3,%fp1 # Z*(B3+Z*B5) 637862306a36Sopenharmony_ci 637962306a36Sopenharmony_ci fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6) 638062306a36Sopenharmony_ci fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5) 638162306a36Sopenharmony_ci 638262306a36Sopenharmony_ci fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6)) 638362306a36Sopenharmony_ci fmul.x X(%a6),%fp0 # X*Y 638462306a36Sopenharmony_ci 638562306a36Sopenharmony_ci fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))] 638662306a36Sopenharmony_ci 638762306a36Sopenharmony_ci fmul.x %fp1,%fp0 # X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]) 638862306a36Sopenharmony_ci 638962306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2/fp3 639062306a36Sopenharmony_ci 639162306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users rnd mode,prec 639262306a36Sopenharmony_ci fadd.x X(%a6),%fp0 639362306a36Sopenharmony_ci bra t_inx2 639462306a36Sopenharmony_ci 639562306a36Sopenharmony_ciATANTINY: 639662306a36Sopenharmony_ci#--|X| < 2^(-40), ATAN(X) = X 639762306a36Sopenharmony_ci 639862306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users rnd mode,prec 639962306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 640062306a36Sopenharmony_ci fmov.x X(%a6),%fp0 # last inst - possible exception set 640162306a36Sopenharmony_ci 640262306a36Sopenharmony_ci bra t_catch 640362306a36Sopenharmony_ci 640462306a36Sopenharmony_ciATANBIG: 640562306a36Sopenharmony_ci#--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE, 640662306a36Sopenharmony_ci#--RETURN SIGN(X)*PI/2 + ATAN(-1/X). 640762306a36Sopenharmony_ci cmp.l %d1,&0x40638000 640862306a36Sopenharmony_ci bgt.w ATANHUGE 640962306a36Sopenharmony_ci 641062306a36Sopenharmony_ci#--APPROXIMATE ATAN(-1/X) BY 641162306a36Sopenharmony_ci#--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X' 641262306a36Sopenharmony_ci#--THIS CAN BE RE-WRITTEN AS 641362306a36Sopenharmony_ci#--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y. 641462306a36Sopenharmony_ci 641562306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2/fp3 641662306a36Sopenharmony_ci 641762306a36Sopenharmony_ci fmov.s &0xBF800000,%fp1 # LOAD -1 641862306a36Sopenharmony_ci fdiv.x %fp0,%fp1 # FP1 IS -1/X 641962306a36Sopenharmony_ci 642062306a36Sopenharmony_ci#--DIVIDE IS STILL CRANKING 642162306a36Sopenharmony_ci 642262306a36Sopenharmony_ci fmov.x %fp1,%fp0 # FP0 IS X' 642362306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FP0 IS Y = X'*X' 642462306a36Sopenharmony_ci fmov.x %fp1,X(%a6) # X IS REALLY X' 642562306a36Sopenharmony_ci 642662306a36Sopenharmony_ci fmov.x %fp0,%fp1 642762306a36Sopenharmony_ci fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 642862306a36Sopenharmony_ci 642962306a36Sopenharmony_ci fmov.d ATANC5(%pc),%fp3 643062306a36Sopenharmony_ci fmov.d ATANC4(%pc),%fp2 643162306a36Sopenharmony_ci 643262306a36Sopenharmony_ci fmul.x %fp1,%fp3 # Z*C5 643362306a36Sopenharmony_ci fmul.x %fp1,%fp2 # Z*B4 643462306a36Sopenharmony_ci 643562306a36Sopenharmony_ci fadd.d ATANC3(%pc),%fp3 # C3+Z*C5 643662306a36Sopenharmony_ci fadd.d ATANC2(%pc),%fp2 # C2+Z*C4 643762306a36Sopenharmony_ci 643862306a36Sopenharmony_ci fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED 643962306a36Sopenharmony_ci fmul.x %fp0,%fp2 # Y*(C2+Z*C4) 644062306a36Sopenharmony_ci 644162306a36Sopenharmony_ci fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5) 644262306a36Sopenharmony_ci fmul.x X(%a6),%fp0 # X'*Y 644362306a36Sopenharmony_ci 644462306a36Sopenharmony_ci fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)] 644562306a36Sopenharmony_ci 644662306a36Sopenharmony_ci fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)] 644762306a36Sopenharmony_ci# ... +[Y*(B2+Z*(B4+Z*B6))]) 644862306a36Sopenharmony_ci fadd.x X(%a6),%fp0 644962306a36Sopenharmony_ci 645062306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2/fp3 645162306a36Sopenharmony_ci 645262306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users rnd mode,prec 645362306a36Sopenharmony_ci tst.b (%a0) 645462306a36Sopenharmony_ci bpl.b pos_big 645562306a36Sopenharmony_ci 645662306a36Sopenharmony_cineg_big: 645762306a36Sopenharmony_ci fadd.x NPIBY2(%pc),%fp0 645862306a36Sopenharmony_ci bra t_minx2 645962306a36Sopenharmony_ci 646062306a36Sopenharmony_cipos_big: 646162306a36Sopenharmony_ci fadd.x PPIBY2(%pc),%fp0 646262306a36Sopenharmony_ci bra t_pinx2 646362306a36Sopenharmony_ci 646462306a36Sopenharmony_ciATANHUGE: 646562306a36Sopenharmony_ci#--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY 646662306a36Sopenharmony_ci tst.b (%a0) 646762306a36Sopenharmony_ci bpl.b pos_huge 646862306a36Sopenharmony_ci 646962306a36Sopenharmony_cineg_huge: 647062306a36Sopenharmony_ci fmov.x NPIBY2(%pc),%fp0 647162306a36Sopenharmony_ci fmov.l %d0,%fpcr 647262306a36Sopenharmony_ci fadd.x PTINY(%pc),%fp0 647362306a36Sopenharmony_ci bra t_minx2 647462306a36Sopenharmony_ci 647562306a36Sopenharmony_cipos_huge: 647662306a36Sopenharmony_ci fmov.x PPIBY2(%pc),%fp0 647762306a36Sopenharmony_ci fmov.l %d0,%fpcr 647862306a36Sopenharmony_ci fadd.x NTINY(%pc),%fp0 647962306a36Sopenharmony_ci bra t_pinx2 648062306a36Sopenharmony_ci 648162306a36Sopenharmony_ci global satand 648262306a36Sopenharmony_ci#--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT 648362306a36Sopenharmony_cisatand: 648462306a36Sopenharmony_ci bra t_extdnrm 648562306a36Sopenharmony_ci 648662306a36Sopenharmony_ci######################################################################### 648762306a36Sopenharmony_ci# sasin(): computes the inverse sine of a normalized input # 648862306a36Sopenharmony_ci# sasind(): computes the inverse sine of a denormalized input # 648962306a36Sopenharmony_ci# # 649062306a36Sopenharmony_ci# INPUT *************************************************************** # 649162306a36Sopenharmony_ci# a0 = pointer to extended precision input # 649262306a36Sopenharmony_ci# d0 = round precision,mode # 649362306a36Sopenharmony_ci# # 649462306a36Sopenharmony_ci# OUTPUT ************************************************************** # 649562306a36Sopenharmony_ci# fp0 = arcsin(X) # 649662306a36Sopenharmony_ci# # 649762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 649862306a36Sopenharmony_ci# The returned result is within 3 ulps in 64 significant bit, # 649962306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 650062306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 650162306a36Sopenharmony_ci# in double precision. # 650262306a36Sopenharmony_ci# # 650362306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 650462306a36Sopenharmony_ci# # 650562306a36Sopenharmony_ci# ASIN # 650662306a36Sopenharmony_ci# 1. If |X| >= 1, go to 3. # 650762306a36Sopenharmony_ci# # 650862306a36Sopenharmony_ci# 2. (|X| < 1) Calculate asin(X) by # 650962306a36Sopenharmony_ci# z := sqrt( [1-X][1+X] ) # 651062306a36Sopenharmony_ci# asin(X) = atan( x / z ). # 651162306a36Sopenharmony_ci# Exit. # 651262306a36Sopenharmony_ci# # 651362306a36Sopenharmony_ci# 3. If |X| > 1, go to 5. # 651462306a36Sopenharmony_ci# # 651562306a36Sopenharmony_ci# 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.# 651662306a36Sopenharmony_ci# # 651762306a36Sopenharmony_ci# 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 651862306a36Sopenharmony_ci# Exit. # 651962306a36Sopenharmony_ci# # 652062306a36Sopenharmony_ci######################################################################### 652162306a36Sopenharmony_ci 652262306a36Sopenharmony_ci global sasin 652362306a36Sopenharmony_cisasin: 652462306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 652562306a36Sopenharmony_ci 652662306a36Sopenharmony_ci mov.l (%a0),%d1 652762306a36Sopenharmony_ci mov.w 4(%a0),%d1 652862306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 652962306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 653062306a36Sopenharmony_ci bge.b ASINBIG 653162306a36Sopenharmony_ci 653262306a36Sopenharmony_ci# This catch is added here for the '060 QSP. Originally, the call to 653362306a36Sopenharmony_ci# satan() would handle this case by causing the exception which would 653462306a36Sopenharmony_ci# not be caught until gen_except(). Now, with the exceptions being 653562306a36Sopenharmony_ci# detected inside of satan(), the exception would have been handled there 653662306a36Sopenharmony_ci# instead of inside sasin() as expected. 653762306a36Sopenharmony_ci cmp.l %d1,&0x3FD78000 653862306a36Sopenharmony_ci blt.w ASINTINY 653962306a36Sopenharmony_ci 654062306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 1 654162306a36Sopenharmony_ci#--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) ) 654262306a36Sopenharmony_ci 654362306a36Sopenharmony_ciASINMAIN: 654462306a36Sopenharmony_ci fmov.s &0x3F800000,%fp1 654562306a36Sopenharmony_ci fsub.x %fp0,%fp1 # 1-X 654662306a36Sopenharmony_ci fmovm.x &0x4,-(%sp) # {fp2} 654762306a36Sopenharmony_ci fmov.s &0x3F800000,%fp2 654862306a36Sopenharmony_ci fadd.x %fp0,%fp2 # 1+X 654962306a36Sopenharmony_ci fmul.x %fp2,%fp1 # (1+X)(1-X) 655062306a36Sopenharmony_ci fmovm.x (%sp)+,&0x20 # {fp2} 655162306a36Sopenharmony_ci fsqrt.x %fp1 # SQRT([1-X][1+X]) 655262306a36Sopenharmony_ci fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X]) 655362306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save X/SQRT(...) 655462306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to X/SQRT(...) 655562306a36Sopenharmony_ci bsr satan 655662306a36Sopenharmony_ci add.l &0xc,%sp # clear X/SQRT(...) from stack 655762306a36Sopenharmony_ci bra t_inx2 655862306a36Sopenharmony_ci 655962306a36Sopenharmony_ciASINBIG: 656062306a36Sopenharmony_ci fabs.x %fp0 # |X| 656162306a36Sopenharmony_ci fcmp.s %fp0,&0x3F800000 656262306a36Sopenharmony_ci fbgt t_operr # cause an operr exception 656362306a36Sopenharmony_ci 656462306a36Sopenharmony_ci#--|X| = 1, ASIN(X) = +- PI/2. 656562306a36Sopenharmony_ciASINONE: 656662306a36Sopenharmony_ci fmov.x PIBY2(%pc),%fp0 656762306a36Sopenharmony_ci mov.l (%a0),%d1 656862306a36Sopenharmony_ci and.l &0x80000000,%d1 # SIGN BIT OF X 656962306a36Sopenharmony_ci or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT 657062306a36Sopenharmony_ci mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT 657162306a36Sopenharmony_ci fmov.l %d0,%fpcr 657262306a36Sopenharmony_ci fmul.s (%sp)+,%fp0 657362306a36Sopenharmony_ci bra t_inx2 657462306a36Sopenharmony_ci 657562306a36Sopenharmony_ci#--|X| < 2^(-40), ATAN(X) = X 657662306a36Sopenharmony_ciASINTINY: 657762306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users rnd mode,prec 657862306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 657962306a36Sopenharmony_ci fmov.x (%a0),%fp0 # last inst - possible exception 658062306a36Sopenharmony_ci bra t_catch 658162306a36Sopenharmony_ci 658262306a36Sopenharmony_ci global sasind 658362306a36Sopenharmony_ci#--ASIN(X) = X FOR DENORMALIZED X 658462306a36Sopenharmony_cisasind: 658562306a36Sopenharmony_ci bra t_extdnrm 658662306a36Sopenharmony_ci 658762306a36Sopenharmony_ci######################################################################### 658862306a36Sopenharmony_ci# sacos(): computes the inverse cosine of a normalized input # 658962306a36Sopenharmony_ci# sacosd(): computes the inverse cosine of a denormalized input # 659062306a36Sopenharmony_ci# # 659162306a36Sopenharmony_ci# INPUT *************************************************************** # 659262306a36Sopenharmony_ci# a0 = pointer to extended precision input # 659362306a36Sopenharmony_ci# d0 = round precision,mode # 659462306a36Sopenharmony_ci# # 659562306a36Sopenharmony_ci# OUTPUT ************************************************************** # 659662306a36Sopenharmony_ci# fp0 = arccos(X) # 659762306a36Sopenharmony_ci# # 659862306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 659962306a36Sopenharmony_ci# The returned result is within 3 ulps in 64 significant bit, # 660062306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 660162306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 660262306a36Sopenharmony_ci# in double precision. # 660362306a36Sopenharmony_ci# # 660462306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 660562306a36Sopenharmony_ci# # 660662306a36Sopenharmony_ci# ACOS # 660762306a36Sopenharmony_ci# 1. If |X| >= 1, go to 3. # 660862306a36Sopenharmony_ci# # 660962306a36Sopenharmony_ci# 2. (|X| < 1) Calculate acos(X) by # 661062306a36Sopenharmony_ci# z := (1-X) / (1+X) # 661162306a36Sopenharmony_ci# acos(X) = 2 * atan( sqrt(z) ). # 661262306a36Sopenharmony_ci# Exit. # 661362306a36Sopenharmony_ci# # 661462306a36Sopenharmony_ci# 3. If |X| > 1, go to 5. # 661562306a36Sopenharmony_ci# # 661662306a36Sopenharmony_ci# 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. # 661762306a36Sopenharmony_ci# # 661862306a36Sopenharmony_ci# 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 661962306a36Sopenharmony_ci# Exit. # 662062306a36Sopenharmony_ci# # 662162306a36Sopenharmony_ci######################################################################### 662262306a36Sopenharmony_ci 662362306a36Sopenharmony_ci global sacos 662462306a36Sopenharmony_cisacos: 662562306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 662662306a36Sopenharmony_ci 662762306a36Sopenharmony_ci mov.l (%a0),%d1 # pack exp w/ upper 16 fraction 662862306a36Sopenharmony_ci mov.w 4(%a0),%d1 662962306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 663062306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 663162306a36Sopenharmony_ci bge.b ACOSBIG 663262306a36Sopenharmony_ci 663362306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 1 663462306a36Sopenharmony_ci#--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) ) 663562306a36Sopenharmony_ci 663662306a36Sopenharmony_ciACOSMAIN: 663762306a36Sopenharmony_ci fmov.s &0x3F800000,%fp1 663862306a36Sopenharmony_ci fadd.x %fp0,%fp1 # 1+X 663962306a36Sopenharmony_ci fneg.x %fp0 # -X 664062306a36Sopenharmony_ci fadd.s &0x3F800000,%fp0 # 1-X 664162306a36Sopenharmony_ci fdiv.x %fp1,%fp0 # (1-X)/(1+X) 664262306a36Sopenharmony_ci fsqrt.x %fp0 # SQRT((1-X)/(1+X)) 664362306a36Sopenharmony_ci mov.l %d0,-(%sp) # save original users fpcr 664462306a36Sopenharmony_ci clr.l %d0 664562306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save SQRT(...) to stack 664662306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to sqrt 664762306a36Sopenharmony_ci bsr satan # ATAN(SQRT([1-X]/[1+X])) 664862306a36Sopenharmony_ci add.l &0xc,%sp # clear SQRT(...) from stack 664962306a36Sopenharmony_ci 665062306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore users round prec,mode 665162306a36Sopenharmony_ci fadd.x %fp0,%fp0 # 2 * ATAN( STUFF ) 665262306a36Sopenharmony_ci bra t_pinx2 665362306a36Sopenharmony_ci 665462306a36Sopenharmony_ciACOSBIG: 665562306a36Sopenharmony_ci fabs.x %fp0 665662306a36Sopenharmony_ci fcmp.s %fp0,&0x3F800000 665762306a36Sopenharmony_ci fbgt t_operr # cause an operr exception 665862306a36Sopenharmony_ci 665962306a36Sopenharmony_ci#--|X| = 1, ACOS(X) = 0 OR PI 666062306a36Sopenharmony_ci tst.b (%a0) # is X positive or negative? 666162306a36Sopenharmony_ci bpl.b ACOSP1 666262306a36Sopenharmony_ci 666362306a36Sopenharmony_ci#--X = -1 666462306a36Sopenharmony_ci#Returns PI and inexact exception 666562306a36Sopenharmony_ciACOSM1: 666662306a36Sopenharmony_ci fmov.x PI(%pc),%fp0 # load PI 666762306a36Sopenharmony_ci fmov.l %d0,%fpcr # load round mode,prec 666862306a36Sopenharmony_ci fadd.s &0x00800000,%fp0 # add a small value 666962306a36Sopenharmony_ci bra t_pinx2 667062306a36Sopenharmony_ci 667162306a36Sopenharmony_ciACOSP1: 667262306a36Sopenharmony_ci bra ld_pzero # answer is positive zero 667362306a36Sopenharmony_ci 667462306a36Sopenharmony_ci global sacosd 667562306a36Sopenharmony_ci#--ACOS(X) = PI/2 FOR DENORMALIZED X 667662306a36Sopenharmony_cisacosd: 667762306a36Sopenharmony_ci fmov.l %d0,%fpcr # load user's rnd mode/prec 667862306a36Sopenharmony_ci fmov.x PIBY2(%pc),%fp0 667962306a36Sopenharmony_ci bra t_pinx2 668062306a36Sopenharmony_ci 668162306a36Sopenharmony_ci######################################################################### 668262306a36Sopenharmony_ci# setox(): computes the exponential for a normalized input # 668362306a36Sopenharmony_ci# setoxd(): computes the exponential for a denormalized input # 668462306a36Sopenharmony_ci# setoxm1(): computes the exponential minus 1 for a normalized input # 668562306a36Sopenharmony_ci# setoxm1d(): computes the exponential minus 1 for a denormalized input # 668662306a36Sopenharmony_ci# # 668762306a36Sopenharmony_ci# INPUT *************************************************************** # 668862306a36Sopenharmony_ci# a0 = pointer to extended precision input # 668962306a36Sopenharmony_ci# d0 = round precision,mode # 669062306a36Sopenharmony_ci# # 669162306a36Sopenharmony_ci# OUTPUT ************************************************************** # 669262306a36Sopenharmony_ci# fp0 = exp(X) or exp(X)-1 # 669362306a36Sopenharmony_ci# # 669462306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 669562306a36Sopenharmony_ci# The returned result is within 0.85 ulps in 64 significant bit, # 669662306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 669762306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 669862306a36Sopenharmony_ci# in double precision. # 669962306a36Sopenharmony_ci# # 670062306a36Sopenharmony_ci# ALGORITHM and IMPLEMENTATION **************************************** # 670162306a36Sopenharmony_ci# # 670262306a36Sopenharmony_ci# setoxd # 670362306a36Sopenharmony_ci# ------ # 670462306a36Sopenharmony_ci# Step 1. Set ans := 1.0 # 670562306a36Sopenharmony_ci# # 670662306a36Sopenharmony_ci# Step 2. Return ans := ans + sign(X)*2^(-126). Exit. # 670762306a36Sopenharmony_ci# Notes: This will always generate one exception -- inexact. # 670862306a36Sopenharmony_ci# # 670962306a36Sopenharmony_ci# # 671062306a36Sopenharmony_ci# setox # 671162306a36Sopenharmony_ci# ----- # 671262306a36Sopenharmony_ci# # 671362306a36Sopenharmony_ci# Step 1. Filter out extreme cases of input argument. # 671462306a36Sopenharmony_ci# 1.1 If |X| >= 2^(-65), go to Step 1.3. # 671562306a36Sopenharmony_ci# 1.2 Go to Step 7. # 671662306a36Sopenharmony_ci# 1.3 If |X| < 16380 log(2), go to Step 2. # 671762306a36Sopenharmony_ci# 1.4 Go to Step 8. # 671862306a36Sopenharmony_ci# Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 671962306a36Sopenharmony_ci# To avoid the use of floating-point comparisons, a # 672062306a36Sopenharmony_ci# compact representation of |X| is used. This format is a # 672162306a36Sopenharmony_ci# 32-bit integer, the upper (more significant) 16 bits # 672262306a36Sopenharmony_ci# are the sign and biased exponent field of |X|; the # 672362306a36Sopenharmony_ci# lower 16 bits are the 16 most significant fraction # 672462306a36Sopenharmony_ci# (including the explicit bit) bits of |X|. Consequently, # 672562306a36Sopenharmony_ci# the comparisons in Steps 1.1 and 1.3 can be performed # 672662306a36Sopenharmony_ci# by integer comparison. Note also that the constant # 672762306a36Sopenharmony_ci# 16380 log(2) used in Step 1.3 is also in the compact # 672862306a36Sopenharmony_ci# form. Thus taking the branch to Step 2 guarantees # 672962306a36Sopenharmony_ci# |X| < 16380 log(2). There is no harm to have a small # 673062306a36Sopenharmony_ci# number of cases where |X| is less than, but close to, # 673162306a36Sopenharmony_ci# 16380 log(2) and the branch to Step 9 is taken. # 673262306a36Sopenharmony_ci# # 673362306a36Sopenharmony_ci# Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 673462306a36Sopenharmony_ci# 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 # 673562306a36Sopenharmony_ci# was taken) # 673662306a36Sopenharmony_ci# 2.2 N := round-to-nearest-integer( X * 64/log2 ). # 673762306a36Sopenharmony_ci# 2.3 Calculate J = N mod 64; so J = 0,1,2,..., # 673862306a36Sopenharmony_ci# or 63. # 673962306a36Sopenharmony_ci# 2.4 Calculate M = (N - J)/64; so N = 64M + J. # 674062306a36Sopenharmony_ci# 2.5 Calculate the address of the stored value of # 674162306a36Sopenharmony_ci# 2^(J/64). # 674262306a36Sopenharmony_ci# 2.6 Create the value Scale = 2^M. # 674362306a36Sopenharmony_ci# Notes: The calculation in 2.2 is really performed by # 674462306a36Sopenharmony_ci# Z := X * constant # 674562306a36Sopenharmony_ci# N := round-to-nearest-integer(Z) # 674662306a36Sopenharmony_ci# where # 674762306a36Sopenharmony_ci# constant := single-precision( 64/log 2 ). # 674862306a36Sopenharmony_ci# # 674962306a36Sopenharmony_ci# Using a single-precision constant avoids memory # 675062306a36Sopenharmony_ci# access. Another effect of using a single-precision # 675162306a36Sopenharmony_ci# "constant" is that the calculated value Z is # 675262306a36Sopenharmony_ci# # 675362306a36Sopenharmony_ci# Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). # 675462306a36Sopenharmony_ci# # 675562306a36Sopenharmony_ci# This error has to be considered later in Steps 3 and 4. # 675662306a36Sopenharmony_ci# # 675762306a36Sopenharmony_ci# Step 3. Calculate X - N*log2/64. # 675862306a36Sopenharmony_ci# 3.1 R := X + N*L1, # 675962306a36Sopenharmony_ci# where L1 := single-precision(-log2/64). # 676062306a36Sopenharmony_ci# 3.2 R := R + N*L2, # 676162306a36Sopenharmony_ci# L2 := extended-precision(-log2/64 - L1).# 676262306a36Sopenharmony_ci# Notes: a) The way L1 and L2 are chosen ensures L1+L2 # 676362306a36Sopenharmony_ci# approximate the value -log2/64 to 88 bits of accuracy. # 676462306a36Sopenharmony_ci# b) N*L1 is exact because N is no longer than 22 bits # 676562306a36Sopenharmony_ci# and L1 is no longer than 24 bits. # 676662306a36Sopenharmony_ci# c) The calculation X+N*L1 is also exact due to # 676762306a36Sopenharmony_ci# cancellation. Thus, R is practically X+N(L1+L2) to full # 676862306a36Sopenharmony_ci# 64 bits. # 676962306a36Sopenharmony_ci# d) It is important to estimate how large can |R| be # 677062306a36Sopenharmony_ci# after Step 3.2. # 677162306a36Sopenharmony_ci# # 677262306a36Sopenharmony_ci# N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) # 677362306a36Sopenharmony_ci# X*64/log2 (1+eps) = N + f, |f| <= 0.5 # 677462306a36Sopenharmony_ci# X*64/log2 - N = f - eps*X 64/log2 # 677562306a36Sopenharmony_ci# X - N*log2/64 = f*log2/64 - eps*X # 677662306a36Sopenharmony_ci# # 677762306a36Sopenharmony_ci# # 677862306a36Sopenharmony_ci# Now |X| <= 16446 log2, thus # 677962306a36Sopenharmony_ci# # 678062306a36Sopenharmony_ci# |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 # 678162306a36Sopenharmony_ci# <= 0.57 log2/64. # 678262306a36Sopenharmony_ci# This bound will be used in Step 4. # 678362306a36Sopenharmony_ci# # 678462306a36Sopenharmony_ci# Step 4. Approximate exp(R)-1 by a polynomial # 678562306a36Sopenharmony_ci# p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) # 678662306a36Sopenharmony_ci# Notes: a) In order to reduce memory access, the coefficients # 678762306a36Sopenharmony_ci# are made as "short" as possible: A1 (which is 1/2), A4 # 678862306a36Sopenharmony_ci# and A5 are single precision; A2 and A3 are double # 678962306a36Sopenharmony_ci# precision. # 679062306a36Sopenharmony_ci# b) Even with the restrictions above, # 679162306a36Sopenharmony_ci# |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. # 679262306a36Sopenharmony_ci# Note that 0.0062 is slightly bigger than 0.57 log2/64. # 679362306a36Sopenharmony_ci# c) To fully utilize the pipeline, p is separated into # 679462306a36Sopenharmony_ci# two independent pieces of roughly equal complexities # 679562306a36Sopenharmony_ci# p = [ R + R*S*(A2 + S*A4) ] + # 679662306a36Sopenharmony_ci# [ S*(A1 + S*(A3 + S*A5)) ] # 679762306a36Sopenharmony_ci# where S = R*R. # 679862306a36Sopenharmony_ci# # 679962306a36Sopenharmony_ci# Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by # 680062306a36Sopenharmony_ci# ans := T + ( T*p + t) # 680162306a36Sopenharmony_ci# where T and t are the stored values for 2^(J/64). # 680262306a36Sopenharmony_ci# Notes: 2^(J/64) is stored as T and t where T+t approximates # 680362306a36Sopenharmony_ci# 2^(J/64) to roughly 85 bits; T is in extended precision # 680462306a36Sopenharmony_ci# and t is in single precision. Note also that T is # 680562306a36Sopenharmony_ci# rounded to 62 bits so that the last two bits of T are # 680662306a36Sopenharmony_ci# zero. The reason for such a special form is that T-1, # 680762306a36Sopenharmony_ci# T-2, and T-8 will all be exact --- a property that will # 680862306a36Sopenharmony_ci# give much more accurate computation of the function # 680962306a36Sopenharmony_ci# EXPM1. # 681062306a36Sopenharmony_ci# # 681162306a36Sopenharmony_ci# Step 6. Reconstruction of exp(X) # 681262306a36Sopenharmony_ci# exp(X) = 2^M * 2^(J/64) * exp(R). # 681362306a36Sopenharmony_ci# 6.1 If AdjFlag = 0, go to 6.3 # 681462306a36Sopenharmony_ci# 6.2 ans := ans * AdjScale # 681562306a36Sopenharmony_ci# 6.3 Restore the user FPCR # 681662306a36Sopenharmony_ci# 6.4 Return ans := ans * Scale. Exit. # 681762306a36Sopenharmony_ci# Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, # 681862306a36Sopenharmony_ci# |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will # 681962306a36Sopenharmony_ci# neither overflow nor underflow. If AdjFlag = 1, that # 682062306a36Sopenharmony_ci# means that # 682162306a36Sopenharmony_ci# X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. # 682262306a36Sopenharmony_ci# Hence, exp(X) may overflow or underflow or neither. # 682362306a36Sopenharmony_ci# When that is the case, AdjScale = 2^(M1) where M1 is # 682462306a36Sopenharmony_ci# approximately M. Thus 6.2 will never cause # 682562306a36Sopenharmony_ci# over/underflow. Possible exception in 6.4 is overflow # 682662306a36Sopenharmony_ci# or underflow. The inexact exception is not generated in # 682762306a36Sopenharmony_ci# 6.4. Although one can argue that the inexact flag # 682862306a36Sopenharmony_ci# should always be raised, to simulate that exception # 682962306a36Sopenharmony_ci# cost to much than the flag is worth in practical uses. # 683062306a36Sopenharmony_ci# # 683162306a36Sopenharmony_ci# Step 7. Return 1 + X. # 683262306a36Sopenharmony_ci# 7.1 ans := X # 683362306a36Sopenharmony_ci# 7.2 Restore user FPCR. # 683462306a36Sopenharmony_ci# 7.3 Return ans := 1 + ans. Exit # 683562306a36Sopenharmony_ci# Notes: For non-zero X, the inexact exception will always be # 683662306a36Sopenharmony_ci# raised by 7.3. That is the only exception raised by 7.3.# 683762306a36Sopenharmony_ci# Note also that we use the FMOVEM instruction to move X # 683862306a36Sopenharmony_ci# in Step 7.1 to avoid unnecessary trapping. (Although # 683962306a36Sopenharmony_ci# the FMOVEM may not seem relevant since X is normalized, # 684062306a36Sopenharmony_ci# the precaution will be useful in the library version of # 684162306a36Sopenharmony_ci# this code where the separate entry for denormalized # 684262306a36Sopenharmony_ci# inputs will be done away with.) # 684362306a36Sopenharmony_ci# # 684462306a36Sopenharmony_ci# Step 8. Handle exp(X) where |X| >= 16380log2. # 684562306a36Sopenharmony_ci# 8.1 If |X| > 16480 log2, go to Step 9. # 684662306a36Sopenharmony_ci# (mimic 2.2 - 2.6) # 684762306a36Sopenharmony_ci# 8.2 N := round-to-integer( X * 64/log2 ) # 684862306a36Sopenharmony_ci# 8.3 Calculate J = N mod 64, J = 0,1,...,63 # 684962306a36Sopenharmony_ci# 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, # 685062306a36Sopenharmony_ci# AdjFlag := 1. # 685162306a36Sopenharmony_ci# 8.5 Calculate the address of the stored value # 685262306a36Sopenharmony_ci# 2^(J/64). # 685362306a36Sopenharmony_ci# 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. # 685462306a36Sopenharmony_ci# 8.7 Go to Step 3. # 685562306a36Sopenharmony_ci# Notes: Refer to notes for 2.2 - 2.6. # 685662306a36Sopenharmony_ci# # 685762306a36Sopenharmony_ci# Step 9. Handle exp(X), |X| > 16480 log2. # 685862306a36Sopenharmony_ci# 9.1 If X < 0, go to 9.3 # 685962306a36Sopenharmony_ci# 9.2 ans := Huge, go to 9.4 # 686062306a36Sopenharmony_ci# 9.3 ans := Tiny. # 686162306a36Sopenharmony_ci# 9.4 Restore user FPCR. # 686262306a36Sopenharmony_ci# 9.5 Return ans := ans * ans. Exit. # 686362306a36Sopenharmony_ci# Notes: Exp(X) will surely overflow or underflow, depending on # 686462306a36Sopenharmony_ci# X's sign. "Huge" and "Tiny" are respectively large/tiny # 686562306a36Sopenharmony_ci# extended-precision numbers whose square over/underflow # 686662306a36Sopenharmony_ci# with an inexact result. Thus, 9.5 always raises the # 686762306a36Sopenharmony_ci# inexact together with either overflow or underflow. # 686862306a36Sopenharmony_ci# # 686962306a36Sopenharmony_ci# setoxm1d # 687062306a36Sopenharmony_ci# -------- # 687162306a36Sopenharmony_ci# # 687262306a36Sopenharmony_ci# Step 1. Set ans := 0 # 687362306a36Sopenharmony_ci# # 687462306a36Sopenharmony_ci# Step 2. Return ans := X + ans. Exit. # 687562306a36Sopenharmony_ci# Notes: This will return X with the appropriate rounding # 687662306a36Sopenharmony_ci# precision prescribed by the user FPCR. # 687762306a36Sopenharmony_ci# # 687862306a36Sopenharmony_ci# setoxm1 # 687962306a36Sopenharmony_ci# ------- # 688062306a36Sopenharmony_ci# # 688162306a36Sopenharmony_ci# Step 1. Check |X| # 688262306a36Sopenharmony_ci# 1.1 If |X| >= 1/4, go to Step 1.3. # 688362306a36Sopenharmony_ci# 1.2 Go to Step 7. # 688462306a36Sopenharmony_ci# 1.3 If |X| < 70 log(2), go to Step 2. # 688562306a36Sopenharmony_ci# 1.4 Go to Step 10. # 688662306a36Sopenharmony_ci# Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 688762306a36Sopenharmony_ci# However, it is conceivable |X| can be small very often # 688862306a36Sopenharmony_ci# because EXPM1 is intended to evaluate exp(X)-1 # 688962306a36Sopenharmony_ci# accurately when |X| is small. For further details on # 689062306a36Sopenharmony_ci# the comparisons, see the notes on Step 1 of setox. # 689162306a36Sopenharmony_ci# # 689262306a36Sopenharmony_ci# Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 689362306a36Sopenharmony_ci# 2.1 N := round-to-nearest-integer( X * 64/log2 ). # 689462306a36Sopenharmony_ci# 2.2 Calculate J = N mod 64; so J = 0,1,2,..., # 689562306a36Sopenharmony_ci# or 63. # 689662306a36Sopenharmony_ci# 2.3 Calculate M = (N - J)/64; so N = 64M + J. # 689762306a36Sopenharmony_ci# 2.4 Calculate the address of the stored value of # 689862306a36Sopenharmony_ci# 2^(J/64). # 689962306a36Sopenharmony_ci# 2.5 Create the values Sc = 2^M and # 690062306a36Sopenharmony_ci# OnebySc := -2^(-M). # 690162306a36Sopenharmony_ci# Notes: See the notes on Step 2 of setox. # 690262306a36Sopenharmony_ci# # 690362306a36Sopenharmony_ci# Step 3. Calculate X - N*log2/64. # 690462306a36Sopenharmony_ci# 3.1 R := X + N*L1, # 690562306a36Sopenharmony_ci# where L1 := single-precision(-log2/64). # 690662306a36Sopenharmony_ci# 3.2 R := R + N*L2, # 690762306a36Sopenharmony_ci# L2 := extended-precision(-log2/64 - L1).# 690862306a36Sopenharmony_ci# Notes: Applying the analysis of Step 3 of setox in this case # 690962306a36Sopenharmony_ci# shows that |R| <= 0.0055 (note that |X| <= 70 log2 in # 691062306a36Sopenharmony_ci# this case). # 691162306a36Sopenharmony_ci# # 691262306a36Sopenharmony_ci# Step 4. Approximate exp(R)-1 by a polynomial # 691362306a36Sopenharmony_ci# p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) # 691462306a36Sopenharmony_ci# Notes: a) In order to reduce memory access, the coefficients # 691562306a36Sopenharmony_ci# are made as "short" as possible: A1 (which is 1/2), A5 # 691662306a36Sopenharmony_ci# and A6 are single precision; A2, A3 and A4 are double # 691762306a36Sopenharmony_ci# precision. # 691862306a36Sopenharmony_ci# b) Even with the restriction above, # 691962306a36Sopenharmony_ci# |p - (exp(R)-1)| < |R| * 2^(-72.7) # 692062306a36Sopenharmony_ci# for all |R| <= 0.0055. # 692162306a36Sopenharmony_ci# c) To fully utilize the pipeline, p is separated into # 692262306a36Sopenharmony_ci# two independent pieces of roughly equal complexity # 692362306a36Sopenharmony_ci# p = [ R*S*(A2 + S*(A4 + S*A6)) ] + # 692462306a36Sopenharmony_ci# [ R + S*(A1 + S*(A3 + S*A5)) ] # 692562306a36Sopenharmony_ci# where S = R*R. # 692662306a36Sopenharmony_ci# # 692762306a36Sopenharmony_ci# Step 5. Compute 2^(J/64)*p by # 692862306a36Sopenharmony_ci# p := T*p # 692962306a36Sopenharmony_ci# where T and t are the stored values for 2^(J/64). # 693062306a36Sopenharmony_ci# Notes: 2^(J/64) is stored as T and t where T+t approximates # 693162306a36Sopenharmony_ci# 2^(J/64) to roughly 85 bits; T is in extended precision # 693262306a36Sopenharmony_ci# and t is in single precision. Note also that T is # 693362306a36Sopenharmony_ci# rounded to 62 bits so that the last two bits of T are # 693462306a36Sopenharmony_ci# zero. The reason for such a special form is that T-1, # 693562306a36Sopenharmony_ci# T-2, and T-8 will all be exact --- a property that will # 693662306a36Sopenharmony_ci# be exploited in Step 6 below. The total relative error # 693762306a36Sopenharmony_ci# in p is no bigger than 2^(-67.7) compared to the final # 693862306a36Sopenharmony_ci# result. # 693962306a36Sopenharmony_ci# # 694062306a36Sopenharmony_ci# Step 6. Reconstruction of exp(X)-1 # 694162306a36Sopenharmony_ci# exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). # 694262306a36Sopenharmony_ci# 6.1 If M <= 63, go to Step 6.3. # 694362306a36Sopenharmony_ci# 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 # 694462306a36Sopenharmony_ci# 6.3 If M >= -3, go to 6.5. # 694562306a36Sopenharmony_ci# 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 # 694662306a36Sopenharmony_ci# 6.5 ans := (T + OnebySc) + (p + t). # 694762306a36Sopenharmony_ci# 6.6 Restore user FPCR. # 694862306a36Sopenharmony_ci# 6.7 Return ans := Sc * ans. Exit. # 694962306a36Sopenharmony_ci# Notes: The various arrangements of the expressions give # 695062306a36Sopenharmony_ci# accurate evaluations. # 695162306a36Sopenharmony_ci# # 695262306a36Sopenharmony_ci# Step 7. exp(X)-1 for |X| < 1/4. # 695362306a36Sopenharmony_ci# 7.1 If |X| >= 2^(-65), go to Step 9. # 695462306a36Sopenharmony_ci# 7.2 Go to Step 8. # 695562306a36Sopenharmony_ci# # 695662306a36Sopenharmony_ci# Step 8. Calculate exp(X)-1, |X| < 2^(-65). # 695762306a36Sopenharmony_ci# 8.1 If |X| < 2^(-16312), goto 8.3 # 695862306a36Sopenharmony_ci# 8.2 Restore FPCR; return ans := X - 2^(-16382). # 695962306a36Sopenharmony_ci# Exit. # 696062306a36Sopenharmony_ci# 8.3 X := X * 2^(140). # 696162306a36Sopenharmony_ci# 8.4 Restore FPCR; ans := ans - 2^(-16382). # 696262306a36Sopenharmony_ci# Return ans := ans*2^(140). Exit # 696362306a36Sopenharmony_ci# Notes: The idea is to return "X - tiny" under the user # 696462306a36Sopenharmony_ci# precision and rounding modes. To avoid unnecessary # 696562306a36Sopenharmony_ci# inefficiency, we stay away from denormalized numbers # 696662306a36Sopenharmony_ci# the best we can. For |X| >= 2^(-16312), the # 696762306a36Sopenharmony_ci# straightforward 8.2 generates the inexact exception as # 696862306a36Sopenharmony_ci# the case warrants. # 696962306a36Sopenharmony_ci# # 697062306a36Sopenharmony_ci# Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial # 697162306a36Sopenharmony_ci# p = X + X*X*(B1 + X*(B2 + ... + X*B12)) # 697262306a36Sopenharmony_ci# Notes: a) In order to reduce memory access, the coefficients # 697362306a36Sopenharmony_ci# are made as "short" as possible: B1 (which is 1/2), B9 # 697462306a36Sopenharmony_ci# to B12 are single precision; B3 to B8 are double # 697562306a36Sopenharmony_ci# precision; and B2 is double extended. # 697662306a36Sopenharmony_ci# b) Even with the restriction above, # 697762306a36Sopenharmony_ci# |p - (exp(X)-1)| < |X| 2^(-70.6) # 697862306a36Sopenharmony_ci# for all |X| <= 0.251. # 697962306a36Sopenharmony_ci# Note that 0.251 is slightly bigger than 1/4. # 698062306a36Sopenharmony_ci# c) To fully preserve accuracy, the polynomial is # 698162306a36Sopenharmony_ci# computed as # 698262306a36Sopenharmony_ci# X + ( S*B1 + Q ) where S = X*X and # 698362306a36Sopenharmony_ci# Q = X*S*(B2 + X*(B3 + ... + X*B12)) # 698462306a36Sopenharmony_ci# d) To fully utilize the pipeline, Q is separated into # 698562306a36Sopenharmony_ci# two independent pieces of roughly equal complexity # 698662306a36Sopenharmony_ci# Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + # 698762306a36Sopenharmony_ci# [ S*S*(B3 + S*(B5 + ... + S*B11)) ] # 698862306a36Sopenharmony_ci# # 698962306a36Sopenharmony_ci# Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. # 699062306a36Sopenharmony_ci# 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all # 699162306a36Sopenharmony_ci# practical purposes. Therefore, go to Step 1 of setox. # 699262306a36Sopenharmony_ci# 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical # 699362306a36Sopenharmony_ci# purposes. # 699462306a36Sopenharmony_ci# ans := -1 # 699562306a36Sopenharmony_ci# Restore user FPCR # 699662306a36Sopenharmony_ci# Return ans := ans + 2^(-126). Exit. # 699762306a36Sopenharmony_ci# Notes: 10.2 will always create an inexact and return -1 + tiny # 699862306a36Sopenharmony_ci# in the user rounding precision and mode. # 699962306a36Sopenharmony_ci# # 700062306a36Sopenharmony_ci######################################################################### 700162306a36Sopenharmony_ci 700262306a36Sopenharmony_ciL2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000 700362306a36Sopenharmony_ci 700462306a36Sopenharmony_ciEEXPA3: long 0x3FA55555,0x55554CC1 700562306a36Sopenharmony_ciEEXPA2: long 0x3FC55555,0x55554A54 700662306a36Sopenharmony_ci 700762306a36Sopenharmony_ciEM1A4: long 0x3F811111,0x11174385 700862306a36Sopenharmony_ciEM1A3: long 0x3FA55555,0x55554F5A 700962306a36Sopenharmony_ci 701062306a36Sopenharmony_ciEM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000 701162306a36Sopenharmony_ci 701262306a36Sopenharmony_ciEM1B8: long 0x3EC71DE3,0xA5774682 701362306a36Sopenharmony_ciEM1B7: long 0x3EFA01A0,0x19D7CB68 701462306a36Sopenharmony_ci 701562306a36Sopenharmony_ciEM1B6: long 0x3F2A01A0,0x1A019DF3 701662306a36Sopenharmony_ciEM1B5: long 0x3F56C16C,0x16C170E2 701762306a36Sopenharmony_ci 701862306a36Sopenharmony_ciEM1B4: long 0x3F811111,0x11111111 701962306a36Sopenharmony_ciEM1B3: long 0x3FA55555,0x55555555 702062306a36Sopenharmony_ci 702162306a36Sopenharmony_ciEM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB 702262306a36Sopenharmony_ci long 0x00000000 702362306a36Sopenharmony_ci 702462306a36Sopenharmony_ciTWO140: long 0x48B00000,0x00000000 702562306a36Sopenharmony_ciTWON140: 702662306a36Sopenharmony_ci long 0x37300000,0x00000000 702762306a36Sopenharmony_ci 702862306a36Sopenharmony_ciEEXPTBL: 702962306a36Sopenharmony_ci long 0x3FFF0000,0x80000000,0x00000000,0x00000000 703062306a36Sopenharmony_ci long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B 703162306a36Sopenharmony_ci long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9 703262306a36Sopenharmony_ci long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369 703362306a36Sopenharmony_ci long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C 703462306a36Sopenharmony_ci long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F 703562306a36Sopenharmony_ci long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729 703662306a36Sopenharmony_ci long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF 703762306a36Sopenharmony_ci long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF 703862306a36Sopenharmony_ci long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA 703962306a36Sopenharmony_ci long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051 704062306a36Sopenharmony_ci long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029 704162306a36Sopenharmony_ci long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494 704262306a36Sopenharmony_ci long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0 704362306a36Sopenharmony_ci long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D 704462306a36Sopenharmony_ci long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537 704562306a36Sopenharmony_ci long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD 704662306a36Sopenharmony_ci long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087 704762306a36Sopenharmony_ci long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818 704862306a36Sopenharmony_ci long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D 704962306a36Sopenharmony_ci long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890 705062306a36Sopenharmony_ci long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C 705162306a36Sopenharmony_ci long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05 705262306a36Sopenharmony_ci long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126 705362306a36Sopenharmony_ci long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140 705462306a36Sopenharmony_ci long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA 705562306a36Sopenharmony_ci long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A 705662306a36Sopenharmony_ci long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC 705762306a36Sopenharmony_ci long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC 705862306a36Sopenharmony_ci long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610 705962306a36Sopenharmony_ci long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90 706062306a36Sopenharmony_ci long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A 706162306a36Sopenharmony_ci long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13 706262306a36Sopenharmony_ci long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30 706362306a36Sopenharmony_ci long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC 706462306a36Sopenharmony_ci long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6 706562306a36Sopenharmony_ci long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70 706662306a36Sopenharmony_ci long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518 706762306a36Sopenharmony_ci long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41 706862306a36Sopenharmony_ci long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B 706962306a36Sopenharmony_ci long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568 707062306a36Sopenharmony_ci long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E 707162306a36Sopenharmony_ci long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03 707262306a36Sopenharmony_ci long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D 707362306a36Sopenharmony_ci long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4 707462306a36Sopenharmony_ci long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C 707562306a36Sopenharmony_ci long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9 707662306a36Sopenharmony_ci long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21 707762306a36Sopenharmony_ci long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F 707862306a36Sopenharmony_ci long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F 707962306a36Sopenharmony_ci long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207 708062306a36Sopenharmony_ci long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175 708162306a36Sopenharmony_ci long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B 708262306a36Sopenharmony_ci long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5 708362306a36Sopenharmony_ci long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A 708462306a36Sopenharmony_ci long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22 708562306a36Sopenharmony_ci long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945 708662306a36Sopenharmony_ci long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B 708762306a36Sopenharmony_ci long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3 708862306a36Sopenharmony_ci long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05 708962306a36Sopenharmony_ci long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19 709062306a36Sopenharmony_ci long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5 709162306a36Sopenharmony_ci long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22 709262306a36Sopenharmony_ci long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A 709362306a36Sopenharmony_ci 709462306a36Sopenharmony_ci set ADJFLAG,L_SCR2 709562306a36Sopenharmony_ci set SCALE,FP_SCR0 709662306a36Sopenharmony_ci set ADJSCALE,FP_SCR1 709762306a36Sopenharmony_ci set SC,FP_SCR0 709862306a36Sopenharmony_ci set ONEBYSC,FP_SCR1 709962306a36Sopenharmony_ci 710062306a36Sopenharmony_ci global setox 710162306a36Sopenharmony_cisetox: 710262306a36Sopenharmony_ci#--entry point for EXP(X), here X is finite, non-zero, and not NaN's 710362306a36Sopenharmony_ci 710462306a36Sopenharmony_ci#--Step 1. 710562306a36Sopenharmony_ci mov.l (%a0),%d1 # load part of input X 710662306a36Sopenharmony_ci and.l &0x7FFF0000,%d1 # biased expo. of X 710762306a36Sopenharmony_ci cmp.l %d1,&0x3FBE0000 # 2^(-65) 710862306a36Sopenharmony_ci bge.b EXPC1 # normal case 710962306a36Sopenharmony_ci bra EXPSM 711062306a36Sopenharmony_ci 711162306a36Sopenharmony_ciEXPC1: 711262306a36Sopenharmony_ci#--The case |X| >= 2^(-65) 711362306a36Sopenharmony_ci mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 711462306a36Sopenharmony_ci cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits 711562306a36Sopenharmony_ci blt.b EXPMAIN # normal case 711662306a36Sopenharmony_ci bra EEXPBIG 711762306a36Sopenharmony_ci 711862306a36Sopenharmony_ciEXPMAIN: 711962306a36Sopenharmony_ci#--Step 2. 712062306a36Sopenharmony_ci#--This is the normal branch: 2^(-65) <= |X| < 16380 log2. 712162306a36Sopenharmony_ci fmov.x (%a0),%fp0 # load input from (a0) 712262306a36Sopenharmony_ci 712362306a36Sopenharmony_ci fmov.x %fp0,%fp1 712462306a36Sopenharmony_ci fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 712562306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 712662306a36Sopenharmony_ci mov.l &0,ADJFLAG(%a6) 712762306a36Sopenharmony_ci fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 712862306a36Sopenharmony_ci lea EEXPTBL(%pc),%a1 712962306a36Sopenharmony_ci fmov.l %d1,%fp0 # convert to floating-format 713062306a36Sopenharmony_ci 713162306a36Sopenharmony_ci mov.l %d1,L_SCR1(%a6) # save N temporarily 713262306a36Sopenharmony_ci and.l &0x3F,%d1 # D0 is J = N mod 64 713362306a36Sopenharmony_ci lsl.l &4,%d1 713462306a36Sopenharmony_ci add.l %d1,%a1 # address of 2^(J/64) 713562306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d1 713662306a36Sopenharmony_ci asr.l &6,%d1 # D0 is M 713762306a36Sopenharmony_ci add.w &0x3FFF,%d1 # biased expo. of 2^(M) 713862306a36Sopenharmony_ci mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB 713962306a36Sopenharmony_ci 714062306a36Sopenharmony_ciEXPCONT1: 714162306a36Sopenharmony_ci#--Step 3. 714262306a36Sopenharmony_ci#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 714362306a36Sopenharmony_ci#--a0 points to 2^(J/64), D0 is biased expo. of 2^(M) 714462306a36Sopenharmony_ci fmov.x %fp0,%fp2 714562306a36Sopenharmony_ci fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 714662306a36Sopenharmony_ci fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 714762306a36Sopenharmony_ci fadd.x %fp1,%fp0 # X + N*L1 714862306a36Sopenharmony_ci fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 714962306a36Sopenharmony_ci 715062306a36Sopenharmony_ci#--Step 4. 715162306a36Sopenharmony_ci#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 715262306a36Sopenharmony_ci#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) 715362306a36Sopenharmony_ci#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R 715462306a36Sopenharmony_ci#--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))] 715562306a36Sopenharmony_ci 715662306a36Sopenharmony_ci fmov.x %fp0,%fp1 715762306a36Sopenharmony_ci fmul.x %fp1,%fp1 # fp1 IS S = R*R 715862306a36Sopenharmony_ci 715962306a36Sopenharmony_ci fmov.s &0x3AB60B70,%fp2 # fp2 IS A5 716062306a36Sopenharmony_ci 716162306a36Sopenharmony_ci fmul.x %fp1,%fp2 # fp2 IS S*A5 716262306a36Sopenharmony_ci fmov.x %fp1,%fp3 716362306a36Sopenharmony_ci fmul.s &0x3C088895,%fp3 # fp3 IS S*A4 716462306a36Sopenharmony_ci 716562306a36Sopenharmony_ci fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5 716662306a36Sopenharmony_ci fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4 716762306a36Sopenharmony_ci 716862306a36Sopenharmony_ci fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5) 716962306a36Sopenharmony_ci mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended 717062306a36Sopenharmony_ci mov.l &0x80000000,SCALE+4(%a6) 717162306a36Sopenharmony_ci clr.l SCALE+8(%a6) 717262306a36Sopenharmony_ci 717362306a36Sopenharmony_ci fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4) 717462306a36Sopenharmony_ci 717562306a36Sopenharmony_ci fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5) 717662306a36Sopenharmony_ci fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4) 717762306a36Sopenharmony_ci 717862306a36Sopenharmony_ci fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5)) 717962306a36Sopenharmony_ci fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4), 718062306a36Sopenharmony_ci 718162306a36Sopenharmony_ci fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64) 718262306a36Sopenharmony_ci fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1 718362306a36Sopenharmony_ci 718462306a36Sopenharmony_ci#--Step 5 718562306a36Sopenharmony_ci#--final reconstruction process 718662306a36Sopenharmony_ci#--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) ) 718762306a36Sopenharmony_ci 718862306a36Sopenharmony_ci fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1) 718962306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 719062306a36Sopenharmony_ci fadd.s (%a1),%fp0 # accurate 2^(J/64) 719162306a36Sopenharmony_ci 719262306a36Sopenharmony_ci fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*... 719362306a36Sopenharmony_ci mov.l ADJFLAG(%a6),%d1 719462306a36Sopenharmony_ci 719562306a36Sopenharmony_ci#--Step 6 719662306a36Sopenharmony_ci tst.l %d1 719762306a36Sopenharmony_ci beq.b NORMAL 719862306a36Sopenharmony_ciADJUST: 719962306a36Sopenharmony_ci fmul.x ADJSCALE(%a6),%fp0 720062306a36Sopenharmony_ciNORMAL: 720162306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore user FPCR 720262306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 720362306a36Sopenharmony_ci fmul.x SCALE(%a6),%fp0 # multiply 2^(M) 720462306a36Sopenharmony_ci bra t_catch 720562306a36Sopenharmony_ci 720662306a36Sopenharmony_ciEXPSM: 720762306a36Sopenharmony_ci#--Step 7 720862306a36Sopenharmony_ci fmovm.x (%a0),&0x80 # load X 720962306a36Sopenharmony_ci fmov.l %d0,%fpcr 721062306a36Sopenharmony_ci fadd.s &0x3F800000,%fp0 # 1+X in user mode 721162306a36Sopenharmony_ci bra t_pinx2 721262306a36Sopenharmony_ci 721362306a36Sopenharmony_ciEEXPBIG: 721462306a36Sopenharmony_ci#--Step 8 721562306a36Sopenharmony_ci cmp.l %d1,&0x400CB27C # 16480 log2 721662306a36Sopenharmony_ci bgt.b EXP2BIG 721762306a36Sopenharmony_ci#--Steps 8.2 -- 8.6 721862306a36Sopenharmony_ci fmov.x (%a0),%fp0 # load input from (a0) 721962306a36Sopenharmony_ci 722062306a36Sopenharmony_ci fmov.x %fp0,%fp1 722162306a36Sopenharmony_ci fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 722262306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 722362306a36Sopenharmony_ci mov.l &1,ADJFLAG(%a6) 722462306a36Sopenharmony_ci fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 722562306a36Sopenharmony_ci lea EEXPTBL(%pc),%a1 722662306a36Sopenharmony_ci fmov.l %d1,%fp0 # convert to floating-format 722762306a36Sopenharmony_ci mov.l %d1,L_SCR1(%a6) # save N temporarily 722862306a36Sopenharmony_ci and.l &0x3F,%d1 # D0 is J = N mod 64 722962306a36Sopenharmony_ci lsl.l &4,%d1 723062306a36Sopenharmony_ci add.l %d1,%a1 # address of 2^(J/64) 723162306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d1 723262306a36Sopenharmony_ci asr.l &6,%d1 # D0 is K 723362306a36Sopenharmony_ci mov.l %d1,L_SCR1(%a6) # save K temporarily 723462306a36Sopenharmony_ci asr.l &1,%d1 # D0 is M1 723562306a36Sopenharmony_ci sub.l %d1,L_SCR1(%a6) # a1 is M 723662306a36Sopenharmony_ci add.w &0x3FFF,%d1 # biased expo. of 2^(M1) 723762306a36Sopenharmony_ci mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1) 723862306a36Sopenharmony_ci mov.l &0x80000000,ADJSCALE+4(%a6) 723962306a36Sopenharmony_ci clr.l ADJSCALE+8(%a6) 724062306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d1 # D0 is M 724162306a36Sopenharmony_ci add.w &0x3FFF,%d1 # biased expo. of 2^(M) 724262306a36Sopenharmony_ci bra.w EXPCONT1 # go back to Step 3 724362306a36Sopenharmony_ci 724462306a36Sopenharmony_ciEXP2BIG: 724562306a36Sopenharmony_ci#--Step 9 724662306a36Sopenharmony_ci tst.b (%a0) # is X positive or negative? 724762306a36Sopenharmony_ci bmi t_unfl2 724862306a36Sopenharmony_ci bra t_ovfl2 724962306a36Sopenharmony_ci 725062306a36Sopenharmony_ci global setoxd 725162306a36Sopenharmony_cisetoxd: 725262306a36Sopenharmony_ci#--entry point for EXP(X), X is denormalized 725362306a36Sopenharmony_ci mov.l (%a0),-(%sp) 725462306a36Sopenharmony_ci andi.l &0x80000000,(%sp) 725562306a36Sopenharmony_ci ori.l &0x00800000,(%sp) # sign(X)*2^(-126) 725662306a36Sopenharmony_ci 725762306a36Sopenharmony_ci fmov.s &0x3F800000,%fp0 725862306a36Sopenharmony_ci 725962306a36Sopenharmony_ci fmov.l %d0,%fpcr 726062306a36Sopenharmony_ci fadd.s (%sp)+,%fp0 726162306a36Sopenharmony_ci bra t_pinx2 726262306a36Sopenharmony_ci 726362306a36Sopenharmony_ci global setoxm1 726462306a36Sopenharmony_cisetoxm1: 726562306a36Sopenharmony_ci#--entry point for EXPM1(X), here X is finite, non-zero, non-NaN 726662306a36Sopenharmony_ci 726762306a36Sopenharmony_ci#--Step 1. 726862306a36Sopenharmony_ci#--Step 1.1 726962306a36Sopenharmony_ci mov.l (%a0),%d1 # load part of input X 727062306a36Sopenharmony_ci and.l &0x7FFF0000,%d1 # biased expo. of X 727162306a36Sopenharmony_ci cmp.l %d1,&0x3FFD0000 # 1/4 727262306a36Sopenharmony_ci bge.b EM1CON1 # |X| >= 1/4 727362306a36Sopenharmony_ci bra EM1SM 727462306a36Sopenharmony_ci 727562306a36Sopenharmony_ciEM1CON1: 727662306a36Sopenharmony_ci#--Step 1.3 727762306a36Sopenharmony_ci#--The case |X| >= 1/4 727862306a36Sopenharmony_ci mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 727962306a36Sopenharmony_ci cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits 728062306a36Sopenharmony_ci ble.b EM1MAIN # 1/4 <= |X| <= 70log2 728162306a36Sopenharmony_ci bra EM1BIG 728262306a36Sopenharmony_ci 728362306a36Sopenharmony_ciEM1MAIN: 728462306a36Sopenharmony_ci#--Step 2. 728562306a36Sopenharmony_ci#--This is the case: 1/4 <= |X| <= 70 log2. 728662306a36Sopenharmony_ci fmov.x (%a0),%fp0 # load input from (a0) 728762306a36Sopenharmony_ci 728862306a36Sopenharmony_ci fmov.x %fp0,%fp1 728962306a36Sopenharmony_ci fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 729062306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 729162306a36Sopenharmony_ci fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 729262306a36Sopenharmony_ci lea EEXPTBL(%pc),%a1 729362306a36Sopenharmony_ci fmov.l %d1,%fp0 # convert to floating-format 729462306a36Sopenharmony_ci 729562306a36Sopenharmony_ci mov.l %d1,L_SCR1(%a6) # save N temporarily 729662306a36Sopenharmony_ci and.l &0x3F,%d1 # D0 is J = N mod 64 729762306a36Sopenharmony_ci lsl.l &4,%d1 729862306a36Sopenharmony_ci add.l %d1,%a1 # address of 2^(J/64) 729962306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d1 730062306a36Sopenharmony_ci asr.l &6,%d1 # D0 is M 730162306a36Sopenharmony_ci mov.l %d1,L_SCR1(%a6) # save a copy of M 730262306a36Sopenharmony_ci 730362306a36Sopenharmony_ci#--Step 3. 730462306a36Sopenharmony_ci#--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 730562306a36Sopenharmony_ci#--a0 points to 2^(J/64), D0 and a1 both contain M 730662306a36Sopenharmony_ci fmov.x %fp0,%fp2 730762306a36Sopenharmony_ci fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 730862306a36Sopenharmony_ci fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 730962306a36Sopenharmony_ci fadd.x %fp1,%fp0 # X + N*L1 731062306a36Sopenharmony_ci fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 731162306a36Sopenharmony_ci add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M 731262306a36Sopenharmony_ci 731362306a36Sopenharmony_ci#--Step 4. 731462306a36Sopenharmony_ci#--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 731562306a36Sopenharmony_ci#-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6))))) 731662306a36Sopenharmony_ci#--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R 731762306a36Sopenharmony_ci#--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))] 731862306a36Sopenharmony_ci 731962306a36Sopenharmony_ci fmov.x %fp0,%fp1 732062306a36Sopenharmony_ci fmul.x %fp1,%fp1 # fp1 IS S = R*R 732162306a36Sopenharmony_ci 732262306a36Sopenharmony_ci fmov.s &0x3950097B,%fp2 # fp2 IS a6 732362306a36Sopenharmony_ci 732462306a36Sopenharmony_ci fmul.x %fp1,%fp2 # fp2 IS S*A6 732562306a36Sopenharmony_ci fmov.x %fp1,%fp3 732662306a36Sopenharmony_ci fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5 732762306a36Sopenharmony_ci 732862306a36Sopenharmony_ci fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6 732962306a36Sopenharmony_ci fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5 733062306a36Sopenharmony_ci mov.w %d1,SC(%a6) # SC is 2^(M) in extended 733162306a36Sopenharmony_ci mov.l &0x80000000,SC+4(%a6) 733262306a36Sopenharmony_ci clr.l SC+8(%a6) 733362306a36Sopenharmony_ci 733462306a36Sopenharmony_ci fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6) 733562306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d1 # D0 is M 733662306a36Sopenharmony_ci neg.w %d1 # D0 is -M 733762306a36Sopenharmony_ci fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5) 733862306a36Sopenharmony_ci add.w &0x3FFF,%d1 # biased expo. of 2^(-M) 733962306a36Sopenharmony_ci fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6) 734062306a36Sopenharmony_ci fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5) 734162306a36Sopenharmony_ci 734262306a36Sopenharmony_ci fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6)) 734362306a36Sopenharmony_ci or.w &0x8000,%d1 # signed/expo. of -2^(-M) 734462306a36Sopenharmony_ci mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M) 734562306a36Sopenharmony_ci mov.l &0x80000000,ONEBYSC+4(%a6) 734662306a36Sopenharmony_ci clr.l ONEBYSC+8(%a6) 734762306a36Sopenharmony_ci fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5)) 734862306a36Sopenharmony_ci 734962306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6)) 735062306a36Sopenharmony_ci fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5)) 735162306a36Sopenharmony_ci 735262306a36Sopenharmony_ci fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1 735362306a36Sopenharmony_ci 735462306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 735562306a36Sopenharmony_ci 735662306a36Sopenharmony_ci#--Step 5 735762306a36Sopenharmony_ci#--Compute 2^(J/64)*p 735862306a36Sopenharmony_ci 735962306a36Sopenharmony_ci fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1) 736062306a36Sopenharmony_ci 736162306a36Sopenharmony_ci#--Step 6 736262306a36Sopenharmony_ci#--Step 6.1 736362306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d1 # retrieve M 736462306a36Sopenharmony_ci cmp.l %d1,&63 736562306a36Sopenharmony_ci ble.b MLE63 736662306a36Sopenharmony_ci#--Step 6.2 M >= 64 736762306a36Sopenharmony_ci fmov.s 12(%a1),%fp1 # fp1 is t 736862306a36Sopenharmony_ci fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc 736962306a36Sopenharmony_ci fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released 737062306a36Sopenharmony_ci fadd.x (%a1),%fp0 # T+(p+(t+OnebySc)) 737162306a36Sopenharmony_ci bra EM1SCALE 737262306a36Sopenharmony_ciMLE63: 737362306a36Sopenharmony_ci#--Step 6.3 M <= 63 737462306a36Sopenharmony_ci cmp.l %d1,&-3 737562306a36Sopenharmony_ci bge.b MGEN3 737662306a36Sopenharmony_ciMLTN3: 737762306a36Sopenharmony_ci#--Step 6.4 M <= -4 737862306a36Sopenharmony_ci fadd.s 12(%a1),%fp0 # p+t 737962306a36Sopenharmony_ci fadd.x (%a1),%fp0 # T+(p+t) 738062306a36Sopenharmony_ci fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t)) 738162306a36Sopenharmony_ci bra EM1SCALE 738262306a36Sopenharmony_ciMGEN3: 738362306a36Sopenharmony_ci#--Step 6.5 -3 <= M <= 63 738462306a36Sopenharmony_ci fmov.x (%a1)+,%fp1 # fp1 is T 738562306a36Sopenharmony_ci fadd.s (%a1),%fp0 # fp0 is p+t 738662306a36Sopenharmony_ci fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc 738762306a36Sopenharmony_ci fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t) 738862306a36Sopenharmony_ci 738962306a36Sopenharmony_ciEM1SCALE: 739062306a36Sopenharmony_ci#--Step 6.6 739162306a36Sopenharmony_ci fmov.l %d0,%fpcr 739262306a36Sopenharmony_ci fmul.x SC(%a6),%fp0 739362306a36Sopenharmony_ci bra t_inx2 739462306a36Sopenharmony_ci 739562306a36Sopenharmony_ciEM1SM: 739662306a36Sopenharmony_ci#--Step 7 |X| < 1/4. 739762306a36Sopenharmony_ci cmp.l %d1,&0x3FBE0000 # 2^(-65) 739862306a36Sopenharmony_ci bge.b EM1POLY 739962306a36Sopenharmony_ci 740062306a36Sopenharmony_ciEM1TINY: 740162306a36Sopenharmony_ci#--Step 8 |X| < 2^(-65) 740262306a36Sopenharmony_ci cmp.l %d1,&0x00330000 # 2^(-16312) 740362306a36Sopenharmony_ci blt.b EM12TINY 740462306a36Sopenharmony_ci#--Step 8.2 740562306a36Sopenharmony_ci mov.l &0x80010000,SC(%a6) # SC is -2^(-16382) 740662306a36Sopenharmony_ci mov.l &0x80000000,SC+4(%a6) 740762306a36Sopenharmony_ci clr.l SC+8(%a6) 740862306a36Sopenharmony_ci fmov.x (%a0),%fp0 740962306a36Sopenharmony_ci fmov.l %d0,%fpcr 741062306a36Sopenharmony_ci mov.b &FADD_OP,%d1 # last inst is ADD 741162306a36Sopenharmony_ci fadd.x SC(%a6),%fp0 741262306a36Sopenharmony_ci bra t_catch 741362306a36Sopenharmony_ci 741462306a36Sopenharmony_ciEM12TINY: 741562306a36Sopenharmony_ci#--Step 8.3 741662306a36Sopenharmony_ci fmov.x (%a0),%fp0 741762306a36Sopenharmony_ci fmul.d TWO140(%pc),%fp0 741862306a36Sopenharmony_ci mov.l &0x80010000,SC(%a6) 741962306a36Sopenharmony_ci mov.l &0x80000000,SC+4(%a6) 742062306a36Sopenharmony_ci clr.l SC+8(%a6) 742162306a36Sopenharmony_ci fadd.x SC(%a6),%fp0 742262306a36Sopenharmony_ci fmov.l %d0,%fpcr 742362306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 742462306a36Sopenharmony_ci fmul.d TWON140(%pc),%fp0 742562306a36Sopenharmony_ci bra t_catch 742662306a36Sopenharmony_ci 742762306a36Sopenharmony_ciEM1POLY: 742862306a36Sopenharmony_ci#--Step 9 exp(X)-1 by a simple polynomial 742962306a36Sopenharmony_ci fmov.x (%a0),%fp0 # fp0 is X 743062306a36Sopenharmony_ci fmul.x %fp0,%fp0 # fp0 is S := X*X 743162306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 743262306a36Sopenharmony_ci fmov.s &0x2F30CAA8,%fp1 # fp1 is B12 743362306a36Sopenharmony_ci fmul.x %fp0,%fp1 # fp1 is S*B12 743462306a36Sopenharmony_ci fmov.s &0x310F8290,%fp2 # fp2 is B11 743562306a36Sopenharmony_ci fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12 743662306a36Sopenharmony_ci 743762306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 is S*B11 743862306a36Sopenharmony_ci fmul.x %fp0,%fp1 # fp1 is S*(B10 + ... 743962306a36Sopenharmony_ci 744062306a36Sopenharmony_ci fadd.s &0x3493F281,%fp2 # fp2 is B9+S*... 744162306a36Sopenharmony_ci fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*... 744262306a36Sopenharmony_ci 744362306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 is S*(B9+... 744462306a36Sopenharmony_ci fmul.x %fp0,%fp1 # fp1 is S*(B8+... 744562306a36Sopenharmony_ci 744662306a36Sopenharmony_ci fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*... 744762306a36Sopenharmony_ci fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*... 744862306a36Sopenharmony_ci 744962306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 is S*(B7+... 745062306a36Sopenharmony_ci fmul.x %fp0,%fp1 # fp1 is S*(B6+... 745162306a36Sopenharmony_ci 745262306a36Sopenharmony_ci fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*... 745362306a36Sopenharmony_ci fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*... 745462306a36Sopenharmony_ci 745562306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 is S*(B5+... 745662306a36Sopenharmony_ci fmul.x %fp0,%fp1 # fp1 is S*(B4+... 745762306a36Sopenharmony_ci 745862306a36Sopenharmony_ci fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*... 745962306a36Sopenharmony_ci fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*... 746062306a36Sopenharmony_ci 746162306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 is S*(B3+... 746262306a36Sopenharmony_ci fmul.x %fp0,%fp1 # fp1 is S*(B2+... 746362306a36Sopenharmony_ci 746462306a36Sopenharmony_ci fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...) 746562306a36Sopenharmony_ci fmul.x (%a0),%fp1 # fp1 is X*S*(B2... 746662306a36Sopenharmony_ci 746762306a36Sopenharmony_ci fmul.s &0x3F000000,%fp0 # fp0 is S*B1 746862306a36Sopenharmony_ci fadd.x %fp2,%fp1 # fp1 is Q 746962306a36Sopenharmony_ci 747062306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 747162306a36Sopenharmony_ci 747262306a36Sopenharmony_ci fadd.x %fp1,%fp0 # fp0 is S*B1+Q 747362306a36Sopenharmony_ci 747462306a36Sopenharmony_ci fmov.l %d0,%fpcr 747562306a36Sopenharmony_ci fadd.x (%a0),%fp0 747662306a36Sopenharmony_ci bra t_inx2 747762306a36Sopenharmony_ci 747862306a36Sopenharmony_ciEM1BIG: 747962306a36Sopenharmony_ci#--Step 10 |X| > 70 log2 748062306a36Sopenharmony_ci mov.l (%a0),%d1 748162306a36Sopenharmony_ci cmp.l %d1,&0 748262306a36Sopenharmony_ci bgt.w EXPC1 748362306a36Sopenharmony_ci#--Step 10.2 748462306a36Sopenharmony_ci fmov.s &0xBF800000,%fp0 # fp0 is -1 748562306a36Sopenharmony_ci fmov.l %d0,%fpcr 748662306a36Sopenharmony_ci fadd.s &0x00800000,%fp0 # -1 + 2^(-126) 748762306a36Sopenharmony_ci bra t_minx2 748862306a36Sopenharmony_ci 748962306a36Sopenharmony_ci global setoxm1d 749062306a36Sopenharmony_cisetoxm1d: 749162306a36Sopenharmony_ci#--entry point for EXPM1(X), here X is denormalized 749262306a36Sopenharmony_ci#--Step 0. 749362306a36Sopenharmony_ci bra t_extdnrm 749462306a36Sopenharmony_ci 749562306a36Sopenharmony_ci######################################################################### 749662306a36Sopenharmony_ci# sgetexp(): returns the exponent portion of the input argument. # 749762306a36Sopenharmony_ci# The exponent bias is removed and the exponent value is # 749862306a36Sopenharmony_ci# returned as an extended precision number in fp0. # 749962306a36Sopenharmony_ci# sgetexpd(): handles denormalized numbers. # 750062306a36Sopenharmony_ci# # 750162306a36Sopenharmony_ci# sgetman(): extracts the mantissa of the input argument. The # 750262306a36Sopenharmony_ci# mantissa is converted to an extended precision number w/ # 750362306a36Sopenharmony_ci# an exponent of $3fff and is returned in fp0. The range of # 750462306a36Sopenharmony_ci# the result is [1.0 - 2.0). # 750562306a36Sopenharmony_ci# sgetmand(): handles denormalized numbers. # 750662306a36Sopenharmony_ci# # 750762306a36Sopenharmony_ci# INPUT *************************************************************** # 750862306a36Sopenharmony_ci# a0 = pointer to extended precision input # 750962306a36Sopenharmony_ci# # 751062306a36Sopenharmony_ci# OUTPUT ************************************************************** # 751162306a36Sopenharmony_ci# fp0 = exponent(X) or mantissa(X) # 751262306a36Sopenharmony_ci# # 751362306a36Sopenharmony_ci######################################################################### 751462306a36Sopenharmony_ci 751562306a36Sopenharmony_ci global sgetexp 751662306a36Sopenharmony_cisgetexp: 751762306a36Sopenharmony_ci mov.w SRC_EX(%a0),%d0 # get the exponent 751862306a36Sopenharmony_ci bclr &0xf,%d0 # clear the sign bit 751962306a36Sopenharmony_ci subi.w &0x3fff,%d0 # subtract off the bias 752062306a36Sopenharmony_ci fmov.w %d0,%fp0 # return exp in fp0 752162306a36Sopenharmony_ci blt.b sgetexpn # it's negative 752262306a36Sopenharmony_ci rts 752362306a36Sopenharmony_ci 752462306a36Sopenharmony_cisgetexpn: 752562306a36Sopenharmony_ci mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 752662306a36Sopenharmony_ci rts 752762306a36Sopenharmony_ci 752862306a36Sopenharmony_ci global sgetexpd 752962306a36Sopenharmony_cisgetexpd: 753062306a36Sopenharmony_ci bsr.l norm # normalize 753162306a36Sopenharmony_ci neg.w %d0 # new exp = -(shft amt) 753262306a36Sopenharmony_ci subi.w &0x3fff,%d0 # subtract off the bias 753362306a36Sopenharmony_ci fmov.w %d0,%fp0 # return exp in fp0 753462306a36Sopenharmony_ci mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 753562306a36Sopenharmony_ci rts 753662306a36Sopenharmony_ci 753762306a36Sopenharmony_ci global sgetman 753862306a36Sopenharmony_cisgetman: 753962306a36Sopenharmony_ci mov.w SRC_EX(%a0),%d0 # get the exp 754062306a36Sopenharmony_ci ori.w &0x7fff,%d0 # clear old exp 754162306a36Sopenharmony_ci bclr &0xe,%d0 # make it the new exp +-3fff 754262306a36Sopenharmony_ci 754362306a36Sopenharmony_ci# here, we build the result in a tmp location so as not to disturb the input 754462306a36Sopenharmony_ci mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc 754562306a36Sopenharmony_ci mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc 754662306a36Sopenharmony_ci mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 754762306a36Sopenharmony_ci fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0 754862306a36Sopenharmony_ci bmi.b sgetmann # it's negative 754962306a36Sopenharmony_ci rts 755062306a36Sopenharmony_ci 755162306a36Sopenharmony_cisgetmann: 755262306a36Sopenharmony_ci mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 755362306a36Sopenharmony_ci rts 755462306a36Sopenharmony_ci 755562306a36Sopenharmony_ci# 755662306a36Sopenharmony_ci# For denormalized numbers, shift the mantissa until the j-bit = 1, 755762306a36Sopenharmony_ci# then load the exponent with +/1 $3fff. 755862306a36Sopenharmony_ci# 755962306a36Sopenharmony_ci global sgetmand 756062306a36Sopenharmony_cisgetmand: 756162306a36Sopenharmony_ci bsr.l norm # normalize exponent 756262306a36Sopenharmony_ci bra.b sgetman 756362306a36Sopenharmony_ci 756462306a36Sopenharmony_ci######################################################################### 756562306a36Sopenharmony_ci# scosh(): computes the hyperbolic cosine of a normalized input # 756662306a36Sopenharmony_ci# scoshd(): computes the hyperbolic cosine of a denormalized input # 756762306a36Sopenharmony_ci# # 756862306a36Sopenharmony_ci# INPUT *************************************************************** # 756962306a36Sopenharmony_ci# a0 = pointer to extended precision input # 757062306a36Sopenharmony_ci# d0 = round precision,mode # 757162306a36Sopenharmony_ci# # 757262306a36Sopenharmony_ci# OUTPUT ************************************************************** # 757362306a36Sopenharmony_ci# fp0 = cosh(X) # 757462306a36Sopenharmony_ci# # 757562306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 757662306a36Sopenharmony_ci# The returned result is within 3 ulps in 64 significant bit, # 757762306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 757862306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 757962306a36Sopenharmony_ci# in double precision. # 758062306a36Sopenharmony_ci# # 758162306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 758262306a36Sopenharmony_ci# # 758362306a36Sopenharmony_ci# COSH # 758462306a36Sopenharmony_ci# 1. If |X| > 16380 log2, go to 3. # 758562306a36Sopenharmony_ci# # 758662306a36Sopenharmony_ci# 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae # 758762306a36Sopenharmony_ci# y = |X|, z = exp(Y), and # 758862306a36Sopenharmony_ci# cosh(X) = (1/2)*( z + 1/z ). # 758962306a36Sopenharmony_ci# Exit. # 759062306a36Sopenharmony_ci# # 759162306a36Sopenharmony_ci# 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. # 759262306a36Sopenharmony_ci# # 759362306a36Sopenharmony_ci# 4. (16380 log2 < |X| <= 16480 log2) # 759462306a36Sopenharmony_ci# cosh(X) = sign(X) * exp(|X|)/2. # 759562306a36Sopenharmony_ci# However, invoking exp(|X|) may cause premature # 759662306a36Sopenharmony_ci# overflow. Thus, we calculate sinh(X) as follows: # 759762306a36Sopenharmony_ci# Y := |X| # 759862306a36Sopenharmony_ci# Fact := 2**(16380) # 759962306a36Sopenharmony_ci# Y' := Y - 16381 log2 # 760062306a36Sopenharmony_ci# cosh(X) := Fact * exp(Y'). # 760162306a36Sopenharmony_ci# Exit. # 760262306a36Sopenharmony_ci# # 760362306a36Sopenharmony_ci# 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 760462306a36Sopenharmony_ci# Huge*Huge to generate overflow and an infinity with # 760562306a36Sopenharmony_ci# the appropriate sign. Huge is the largest finite number # 760662306a36Sopenharmony_ci# in extended format. Exit. # 760762306a36Sopenharmony_ci# # 760862306a36Sopenharmony_ci######################################################################### 760962306a36Sopenharmony_ci 761062306a36Sopenharmony_ciTWO16380: 761162306a36Sopenharmony_ci long 0x7FFB0000,0x80000000,0x00000000,0x00000000 761262306a36Sopenharmony_ci 761362306a36Sopenharmony_ci global scosh 761462306a36Sopenharmony_ciscosh: 761562306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 761662306a36Sopenharmony_ci 761762306a36Sopenharmony_ci mov.l (%a0),%d1 761862306a36Sopenharmony_ci mov.w 4(%a0),%d1 761962306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 762062306a36Sopenharmony_ci cmp.l %d1,&0x400CB167 762162306a36Sopenharmony_ci bgt.b COSHBIG 762262306a36Sopenharmony_ci 762362306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 16380 LOG2 762462306a36Sopenharmony_ci#--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) ) 762562306a36Sopenharmony_ci 762662306a36Sopenharmony_ci fabs.x %fp0 # |X| 762762306a36Sopenharmony_ci 762862306a36Sopenharmony_ci mov.l %d0,-(%sp) 762962306a36Sopenharmony_ci clr.l %d0 763062306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save |X| to stack 763162306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to |X| 763262306a36Sopenharmony_ci bsr setox # FP0 IS EXP(|X|) 763362306a36Sopenharmony_ci add.l &0xc,%sp # erase |X| from stack 763462306a36Sopenharmony_ci fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|) 763562306a36Sopenharmony_ci mov.l (%sp)+,%d0 763662306a36Sopenharmony_ci 763762306a36Sopenharmony_ci fmov.s &0x3E800000,%fp1 # (1/4) 763862306a36Sopenharmony_ci fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|)) 763962306a36Sopenharmony_ci 764062306a36Sopenharmony_ci fmov.l %d0,%fpcr 764162306a36Sopenharmony_ci mov.b &FADD_OP,%d1 # last inst is ADD 764262306a36Sopenharmony_ci fadd.x %fp1,%fp0 764362306a36Sopenharmony_ci bra t_catch 764462306a36Sopenharmony_ci 764562306a36Sopenharmony_ciCOSHBIG: 764662306a36Sopenharmony_ci cmp.l %d1,&0x400CB2B3 764762306a36Sopenharmony_ci bgt.b COSHHUGE 764862306a36Sopenharmony_ci 764962306a36Sopenharmony_ci fabs.x %fp0 765062306a36Sopenharmony_ci fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 765162306a36Sopenharmony_ci fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 765262306a36Sopenharmony_ci 765362306a36Sopenharmony_ci mov.l %d0,-(%sp) 765462306a36Sopenharmony_ci clr.l %d0 765562306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save fp0 to stack 765662306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to fp0 765762306a36Sopenharmony_ci bsr setox 765862306a36Sopenharmony_ci add.l &0xc,%sp # clear fp0 from stack 765962306a36Sopenharmony_ci mov.l (%sp)+,%d0 766062306a36Sopenharmony_ci 766162306a36Sopenharmony_ci fmov.l %d0,%fpcr 766262306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 766362306a36Sopenharmony_ci fmul.x TWO16380(%pc),%fp0 766462306a36Sopenharmony_ci bra t_catch 766562306a36Sopenharmony_ci 766662306a36Sopenharmony_ciCOSHHUGE: 766762306a36Sopenharmony_ci bra t_ovfl2 766862306a36Sopenharmony_ci 766962306a36Sopenharmony_ci global scoshd 767062306a36Sopenharmony_ci#--COSH(X) = 1 FOR DENORMALIZED X 767162306a36Sopenharmony_ciscoshd: 767262306a36Sopenharmony_ci fmov.s &0x3F800000,%fp0 767362306a36Sopenharmony_ci 767462306a36Sopenharmony_ci fmov.l %d0,%fpcr 767562306a36Sopenharmony_ci fadd.s &0x00800000,%fp0 767662306a36Sopenharmony_ci bra t_pinx2 767762306a36Sopenharmony_ci 767862306a36Sopenharmony_ci######################################################################### 767962306a36Sopenharmony_ci# ssinh(): computes the hyperbolic sine of a normalized input # 768062306a36Sopenharmony_ci# ssinhd(): computes the hyperbolic sine of a denormalized input # 768162306a36Sopenharmony_ci# # 768262306a36Sopenharmony_ci# INPUT *************************************************************** # 768362306a36Sopenharmony_ci# a0 = pointer to extended precision input # 768462306a36Sopenharmony_ci# d0 = round precision,mode # 768562306a36Sopenharmony_ci# # 768662306a36Sopenharmony_ci# OUTPUT ************************************************************** # 768762306a36Sopenharmony_ci# fp0 = sinh(X) # 768862306a36Sopenharmony_ci# # 768962306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 769062306a36Sopenharmony_ci# The returned result is within 3 ulps in 64 significant bit, # 769162306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 769262306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 769362306a36Sopenharmony_ci# in double precision. # 769462306a36Sopenharmony_ci# # 769562306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 769662306a36Sopenharmony_ci# # 769762306a36Sopenharmony_ci# SINH # 769862306a36Sopenharmony_ci# 1. If |X| > 16380 log2, go to 3. # 769962306a36Sopenharmony_ci# # 770062306a36Sopenharmony_ci# 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula # 770162306a36Sopenharmony_ci# y = |X|, sgn = sign(X), and z = expm1(Y), # 770262306a36Sopenharmony_ci# sinh(X) = sgn*(1/2)*( z + z/(1+z) ). # 770362306a36Sopenharmony_ci# Exit. # 770462306a36Sopenharmony_ci# # 770562306a36Sopenharmony_ci# 3. If |X| > 16480 log2, go to 5. # 770662306a36Sopenharmony_ci# # 770762306a36Sopenharmony_ci# 4. (16380 log2 < |X| <= 16480 log2) # 770862306a36Sopenharmony_ci# sinh(X) = sign(X) * exp(|X|)/2. # 770962306a36Sopenharmony_ci# However, invoking exp(|X|) may cause premature overflow. # 771062306a36Sopenharmony_ci# Thus, we calculate sinh(X) as follows: # 771162306a36Sopenharmony_ci# Y := |X| # 771262306a36Sopenharmony_ci# sgn := sign(X) # 771362306a36Sopenharmony_ci# sgnFact := sgn * 2**(16380) # 771462306a36Sopenharmony_ci# Y' := Y - 16381 log2 # 771562306a36Sopenharmony_ci# sinh(X) := sgnFact * exp(Y'). # 771662306a36Sopenharmony_ci# Exit. # 771762306a36Sopenharmony_ci# # 771862306a36Sopenharmony_ci# 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 771962306a36Sopenharmony_ci# sign(X)*Huge*Huge to generate overflow and an infinity with # 772062306a36Sopenharmony_ci# the appropriate sign. Huge is the largest finite number in # 772162306a36Sopenharmony_ci# extended format. Exit. # 772262306a36Sopenharmony_ci# # 772362306a36Sopenharmony_ci######################################################################### 772462306a36Sopenharmony_ci 772562306a36Sopenharmony_ci global ssinh 772662306a36Sopenharmony_cissinh: 772762306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 772862306a36Sopenharmony_ci 772962306a36Sopenharmony_ci mov.l (%a0),%d1 773062306a36Sopenharmony_ci mov.w 4(%a0),%d1 773162306a36Sopenharmony_ci mov.l %d1,%a1 # save (compacted) operand 773262306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 773362306a36Sopenharmony_ci cmp.l %d1,&0x400CB167 773462306a36Sopenharmony_ci bgt.b SINHBIG 773562306a36Sopenharmony_ci 773662306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 16380 LOG2 773762306a36Sopenharmony_ci#--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) ) 773862306a36Sopenharmony_ci 773962306a36Sopenharmony_ci fabs.x %fp0 # Y = |X| 774062306a36Sopenharmony_ci 774162306a36Sopenharmony_ci movm.l &0x8040,-(%sp) # {a1/d0} 774262306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save Y on stack 774362306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to Y 774462306a36Sopenharmony_ci clr.l %d0 774562306a36Sopenharmony_ci bsr setoxm1 # FP0 IS Z = EXPM1(Y) 774662306a36Sopenharmony_ci add.l &0xc,%sp # clear Y from stack 774762306a36Sopenharmony_ci fmov.l &0,%fpcr 774862306a36Sopenharmony_ci movm.l (%sp)+,&0x0201 # {a1/d0} 774962306a36Sopenharmony_ci 775062306a36Sopenharmony_ci fmov.x %fp0,%fp1 775162306a36Sopenharmony_ci fadd.s &0x3F800000,%fp1 # 1+Z 775262306a36Sopenharmony_ci fmov.x %fp0,-(%sp) 775362306a36Sopenharmony_ci fdiv.x %fp1,%fp0 # Z/(1+Z) 775462306a36Sopenharmony_ci mov.l %a1,%d1 775562306a36Sopenharmony_ci and.l &0x80000000,%d1 775662306a36Sopenharmony_ci or.l &0x3F000000,%d1 775762306a36Sopenharmony_ci fadd.x (%sp)+,%fp0 775862306a36Sopenharmony_ci mov.l %d1,-(%sp) 775962306a36Sopenharmony_ci 776062306a36Sopenharmony_ci fmov.l %d0,%fpcr 776162306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 776262306a36Sopenharmony_ci fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set 776362306a36Sopenharmony_ci bra t_catch 776462306a36Sopenharmony_ci 776562306a36Sopenharmony_ciSINHBIG: 776662306a36Sopenharmony_ci cmp.l %d1,&0x400CB2B3 776762306a36Sopenharmony_ci bgt t_ovfl 776862306a36Sopenharmony_ci fabs.x %fp0 776962306a36Sopenharmony_ci fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 777062306a36Sopenharmony_ci mov.l &0,-(%sp) 777162306a36Sopenharmony_ci mov.l &0x80000000,-(%sp) 777262306a36Sopenharmony_ci mov.l %a1,%d1 777362306a36Sopenharmony_ci and.l &0x80000000,%d1 777462306a36Sopenharmony_ci or.l &0x7FFB0000,%d1 777562306a36Sopenharmony_ci mov.l %d1,-(%sp) # EXTENDED FMT 777662306a36Sopenharmony_ci fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 777762306a36Sopenharmony_ci 777862306a36Sopenharmony_ci mov.l %d0,-(%sp) 777962306a36Sopenharmony_ci clr.l %d0 778062306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save fp0 on stack 778162306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to fp0 778262306a36Sopenharmony_ci bsr setox 778362306a36Sopenharmony_ci add.l &0xc,%sp # clear fp0 from stack 778462306a36Sopenharmony_ci 778562306a36Sopenharmony_ci mov.l (%sp)+,%d0 778662306a36Sopenharmony_ci fmov.l %d0,%fpcr 778762306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 778862306a36Sopenharmony_ci fmul.x (%sp)+,%fp0 # possible exception 778962306a36Sopenharmony_ci bra t_catch 779062306a36Sopenharmony_ci 779162306a36Sopenharmony_ci global ssinhd 779262306a36Sopenharmony_ci#--SINH(X) = X FOR DENORMALIZED X 779362306a36Sopenharmony_cissinhd: 779462306a36Sopenharmony_ci bra t_extdnrm 779562306a36Sopenharmony_ci 779662306a36Sopenharmony_ci######################################################################### 779762306a36Sopenharmony_ci# stanh(): computes the hyperbolic tangent of a normalized input # 779862306a36Sopenharmony_ci# stanhd(): computes the hyperbolic tangent of a denormalized input # 779962306a36Sopenharmony_ci# # 780062306a36Sopenharmony_ci# INPUT *************************************************************** # 780162306a36Sopenharmony_ci# a0 = pointer to extended precision input # 780262306a36Sopenharmony_ci# d0 = round precision,mode # 780362306a36Sopenharmony_ci# # 780462306a36Sopenharmony_ci# OUTPUT ************************************************************** # 780562306a36Sopenharmony_ci# fp0 = tanh(X) # 780662306a36Sopenharmony_ci# # 780762306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 780862306a36Sopenharmony_ci# The returned result is within 3 ulps in 64 significant bit, # 780962306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 781062306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 781162306a36Sopenharmony_ci# in double precision. # 781262306a36Sopenharmony_ci# # 781362306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 781462306a36Sopenharmony_ci# # 781562306a36Sopenharmony_ci# TANH # 781662306a36Sopenharmony_ci# 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. # 781762306a36Sopenharmony_ci# # 781862306a36Sopenharmony_ci# 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by # 781962306a36Sopenharmony_ci# sgn := sign(X), y := 2|X|, z := expm1(Y), and # 782062306a36Sopenharmony_ci# tanh(X) = sgn*( z/(2+z) ). # 782162306a36Sopenharmony_ci# Exit. # 782262306a36Sopenharmony_ci# # 782362306a36Sopenharmony_ci# 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, # 782462306a36Sopenharmony_ci# go to 7. # 782562306a36Sopenharmony_ci# # 782662306a36Sopenharmony_ci# 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. # 782762306a36Sopenharmony_ci# # 782862306a36Sopenharmony_ci# 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by # 782962306a36Sopenharmony_ci# sgn := sign(X), y := 2|X|, z := exp(Y), # 783062306a36Sopenharmony_ci# tanh(X) = sgn - [ sgn*2/(1+z) ]. # 783162306a36Sopenharmony_ci# Exit. # 783262306a36Sopenharmony_ci# # 783362306a36Sopenharmony_ci# 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we # 783462306a36Sopenharmony_ci# calculate Tanh(X) by # 783562306a36Sopenharmony_ci# sgn := sign(X), Tiny := 2**(-126), # 783662306a36Sopenharmony_ci# tanh(X) := sgn - sgn*Tiny. # 783762306a36Sopenharmony_ci# Exit. # 783862306a36Sopenharmony_ci# # 783962306a36Sopenharmony_ci# 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. # 784062306a36Sopenharmony_ci# # 784162306a36Sopenharmony_ci######################################################################### 784262306a36Sopenharmony_ci 784362306a36Sopenharmony_ci set X,FP_SCR0 784462306a36Sopenharmony_ci set XFRAC,X+4 784562306a36Sopenharmony_ci 784662306a36Sopenharmony_ci set SGN,L_SCR3 784762306a36Sopenharmony_ci 784862306a36Sopenharmony_ci set V,FP_SCR0 784962306a36Sopenharmony_ci 785062306a36Sopenharmony_ci global stanh 785162306a36Sopenharmony_cistanh: 785262306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 785362306a36Sopenharmony_ci 785462306a36Sopenharmony_ci fmov.x %fp0,X(%a6) 785562306a36Sopenharmony_ci mov.l (%a0),%d1 785662306a36Sopenharmony_ci mov.w 4(%a0),%d1 785762306a36Sopenharmony_ci mov.l %d1,X(%a6) 785862306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 785962306a36Sopenharmony_ci cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)? 786062306a36Sopenharmony_ci blt.w TANHBORS # yes 786162306a36Sopenharmony_ci cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2? 786262306a36Sopenharmony_ci bgt.w TANHBORS # yes 786362306a36Sopenharmony_ci 786462306a36Sopenharmony_ci#--THIS IS THE USUAL CASE 786562306a36Sopenharmony_ci#--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2). 786662306a36Sopenharmony_ci 786762306a36Sopenharmony_ci mov.l X(%a6),%d1 786862306a36Sopenharmony_ci mov.l %d1,SGN(%a6) 786962306a36Sopenharmony_ci and.l &0x7FFF0000,%d1 787062306a36Sopenharmony_ci add.l &0x00010000,%d1 # EXPONENT OF 2|X| 787162306a36Sopenharmony_ci mov.l %d1,X(%a6) 787262306a36Sopenharmony_ci and.l &0x80000000,SGN(%a6) 787362306a36Sopenharmony_ci fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X| 787462306a36Sopenharmony_ci 787562306a36Sopenharmony_ci mov.l %d0,-(%sp) 787662306a36Sopenharmony_ci clr.l %d0 787762306a36Sopenharmony_ci fmovm.x &0x1,-(%sp) # save Y on stack 787862306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to Y 787962306a36Sopenharmony_ci bsr setoxm1 # FP0 IS Z = EXPM1(Y) 788062306a36Sopenharmony_ci add.l &0xc,%sp # clear Y from stack 788162306a36Sopenharmony_ci mov.l (%sp)+,%d0 788262306a36Sopenharmony_ci 788362306a36Sopenharmony_ci fmov.x %fp0,%fp1 788462306a36Sopenharmony_ci fadd.s &0x40000000,%fp1 # Z+2 788562306a36Sopenharmony_ci mov.l SGN(%a6),%d1 788662306a36Sopenharmony_ci fmov.x %fp1,V(%a6) 788762306a36Sopenharmony_ci eor.l %d1,V(%a6) 788862306a36Sopenharmony_ci 788962306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round prec,mode 789062306a36Sopenharmony_ci fdiv.x V(%a6),%fp0 789162306a36Sopenharmony_ci bra t_inx2 789262306a36Sopenharmony_ci 789362306a36Sopenharmony_ciTANHBORS: 789462306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 789562306a36Sopenharmony_ci blt.w TANHSM 789662306a36Sopenharmony_ci 789762306a36Sopenharmony_ci cmp.l %d1,&0x40048AA1 789862306a36Sopenharmony_ci bgt.w TANHHUGE 789962306a36Sopenharmony_ci 790062306a36Sopenharmony_ci#-- (5/2) LOG2 < |X| < 50 LOG2, 790162306a36Sopenharmony_ci#--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X), 790262306a36Sopenharmony_ci#--TANH(X) = SGN - SGN*2/[EXP(Y)+1]. 790362306a36Sopenharmony_ci 790462306a36Sopenharmony_ci mov.l X(%a6),%d1 790562306a36Sopenharmony_ci mov.l %d1,SGN(%a6) 790662306a36Sopenharmony_ci and.l &0x7FFF0000,%d1 790762306a36Sopenharmony_ci add.l &0x00010000,%d1 # EXPO OF 2|X| 790862306a36Sopenharmony_ci mov.l %d1,X(%a6) # Y = 2|X| 790962306a36Sopenharmony_ci and.l &0x80000000,SGN(%a6) 791062306a36Sopenharmony_ci mov.l SGN(%a6),%d1 791162306a36Sopenharmony_ci fmov.x X(%a6),%fp0 # Y = 2|X| 791262306a36Sopenharmony_ci 791362306a36Sopenharmony_ci mov.l %d0,-(%sp) 791462306a36Sopenharmony_ci clr.l %d0 791562306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save Y on stack 791662306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to Y 791762306a36Sopenharmony_ci bsr setox # FP0 IS EXP(Y) 791862306a36Sopenharmony_ci add.l &0xc,%sp # clear Y from stack 791962306a36Sopenharmony_ci mov.l (%sp)+,%d0 792062306a36Sopenharmony_ci mov.l SGN(%a6),%d1 792162306a36Sopenharmony_ci fadd.s &0x3F800000,%fp0 # EXP(Y)+1 792262306a36Sopenharmony_ci 792362306a36Sopenharmony_ci eor.l &0xC0000000,%d1 # -SIGN(X)*2 792462306a36Sopenharmony_ci fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT 792562306a36Sopenharmony_ci fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ] 792662306a36Sopenharmony_ci 792762306a36Sopenharmony_ci mov.l SGN(%a6),%d1 792862306a36Sopenharmony_ci or.l &0x3F800000,%d1 # SGN 792962306a36Sopenharmony_ci fmov.s %d1,%fp0 # SGN IN SGL FMT 793062306a36Sopenharmony_ci 793162306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round prec,mode 793262306a36Sopenharmony_ci mov.b &FADD_OP,%d1 # last inst is ADD 793362306a36Sopenharmony_ci fadd.x %fp1,%fp0 793462306a36Sopenharmony_ci bra t_inx2 793562306a36Sopenharmony_ci 793662306a36Sopenharmony_ciTANHSM: 793762306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round prec,mode 793862306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 793962306a36Sopenharmony_ci fmov.x X(%a6),%fp0 # last inst - possible exception set 794062306a36Sopenharmony_ci bra t_catch 794162306a36Sopenharmony_ci 794262306a36Sopenharmony_ci#---RETURN SGN(X) - SGN(X)EPS 794362306a36Sopenharmony_ciTANHHUGE: 794462306a36Sopenharmony_ci mov.l X(%a6),%d1 794562306a36Sopenharmony_ci and.l &0x80000000,%d1 794662306a36Sopenharmony_ci or.l &0x3F800000,%d1 794762306a36Sopenharmony_ci fmov.s %d1,%fp0 794862306a36Sopenharmony_ci and.l &0x80000000,%d1 794962306a36Sopenharmony_ci eor.l &0x80800000,%d1 # -SIGN(X)*EPS 795062306a36Sopenharmony_ci 795162306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round prec,mode 795262306a36Sopenharmony_ci fadd.s %d1,%fp0 795362306a36Sopenharmony_ci bra t_inx2 795462306a36Sopenharmony_ci 795562306a36Sopenharmony_ci global stanhd 795662306a36Sopenharmony_ci#--TANH(X) = X FOR DENORMALIZED X 795762306a36Sopenharmony_cistanhd: 795862306a36Sopenharmony_ci bra t_extdnrm 795962306a36Sopenharmony_ci 796062306a36Sopenharmony_ci######################################################################### 796162306a36Sopenharmony_ci# slogn(): computes the natural logarithm of a normalized input # 796262306a36Sopenharmony_ci# slognd(): computes the natural logarithm of a denormalized input # 796362306a36Sopenharmony_ci# slognp1(): computes the log(1+X) of a normalized input # 796462306a36Sopenharmony_ci# slognp1d(): computes the log(1+X) of a denormalized input # 796562306a36Sopenharmony_ci# # 796662306a36Sopenharmony_ci# INPUT *************************************************************** # 796762306a36Sopenharmony_ci# a0 = pointer to extended precision input # 796862306a36Sopenharmony_ci# d0 = round precision,mode # 796962306a36Sopenharmony_ci# # 797062306a36Sopenharmony_ci# OUTPUT ************************************************************** # 797162306a36Sopenharmony_ci# fp0 = log(X) or log(1+X) # 797262306a36Sopenharmony_ci# # 797362306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 797462306a36Sopenharmony_ci# The returned result is within 2 ulps in 64 significant bit, # 797562306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 797662306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 797762306a36Sopenharmony_ci# in double precision. # 797862306a36Sopenharmony_ci# # 797962306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 798062306a36Sopenharmony_ci# LOGN: # 798162306a36Sopenharmony_ci# Step 1. If |X-1| < 1/16, approximate log(X) by an odd # 798262306a36Sopenharmony_ci# polynomial in u, where u = 2(X-1)/(X+1). Otherwise, # 798362306a36Sopenharmony_ci# move on to Step 2. # 798462306a36Sopenharmony_ci# # 798562306a36Sopenharmony_ci# Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first # 798662306a36Sopenharmony_ci# seven significant bits of Y plus 2**(-7), i.e. # 798762306a36Sopenharmony_ci# F = 1.xxxxxx1 in base 2 where the six "x" match those # 798862306a36Sopenharmony_ci# of Y. Note that |Y-F| <= 2**(-7). # 798962306a36Sopenharmony_ci# # 799062306a36Sopenharmony_ci# Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a # 799162306a36Sopenharmony_ci# polynomial in u, log(1+u) = poly. # 799262306a36Sopenharmony_ci# # 799362306a36Sopenharmony_ci# Step 4. Reconstruct # 799462306a36Sopenharmony_ci# log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) # 799562306a36Sopenharmony_ci# by k*log(2) + (log(F) + poly). The values of log(F) are # 799662306a36Sopenharmony_ci# calculated beforehand and stored in the program. # 799762306a36Sopenharmony_ci# # 799862306a36Sopenharmony_ci# lognp1: # 799962306a36Sopenharmony_ci# Step 1: If |X| < 1/16, approximate log(1+X) by an odd # 800062306a36Sopenharmony_ci# polynomial in u where u = 2X/(2+X). Otherwise, move on # 800162306a36Sopenharmony_ci# to Step 2. # 800262306a36Sopenharmony_ci# # 800362306a36Sopenharmony_ci# Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done # 800462306a36Sopenharmony_ci# in Step 2 of the algorithm for LOGN and compute # 800562306a36Sopenharmony_ci# log(1+X) as k*log(2) + log(F) + poly where poly # 800662306a36Sopenharmony_ci# approximates log(1+u), u = (Y-F)/F. # 800762306a36Sopenharmony_ci# # 800862306a36Sopenharmony_ci# Implementation Notes: # 800962306a36Sopenharmony_ci# Note 1. There are 64 different possible values for F, thus 64 # 801062306a36Sopenharmony_ci# log(F)'s need to be tabulated. Moreover, the values of # 801162306a36Sopenharmony_ci# 1/F are also tabulated so that the division in (Y-F)/F # 801262306a36Sopenharmony_ci# can be performed by a multiplication. # 801362306a36Sopenharmony_ci# # 801462306a36Sopenharmony_ci# Note 2. In Step 2 of lognp1, in order to preserved accuracy, # 801562306a36Sopenharmony_ci# the value Y-F has to be calculated carefully when # 801662306a36Sopenharmony_ci# 1/2 <= X < 3/2. # 801762306a36Sopenharmony_ci# # 801862306a36Sopenharmony_ci# Note 3. To fully exploit the pipeline, polynomials are usually # 801962306a36Sopenharmony_ci# separated into two parts evaluated independently before # 802062306a36Sopenharmony_ci# being added up. # 802162306a36Sopenharmony_ci# # 802262306a36Sopenharmony_ci######################################################################### 802362306a36Sopenharmony_ciLOGOF2: 802462306a36Sopenharmony_ci long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 802562306a36Sopenharmony_ci 802662306a36Sopenharmony_cione: 802762306a36Sopenharmony_ci long 0x3F800000 802862306a36Sopenharmony_cizero: 802962306a36Sopenharmony_ci long 0x00000000 803062306a36Sopenharmony_ciinfty: 803162306a36Sopenharmony_ci long 0x7F800000 803262306a36Sopenharmony_cinegone: 803362306a36Sopenharmony_ci long 0xBF800000 803462306a36Sopenharmony_ci 803562306a36Sopenharmony_ciLOGA6: 803662306a36Sopenharmony_ci long 0x3FC2499A,0xB5E4040B 803762306a36Sopenharmony_ciLOGA5: 803862306a36Sopenharmony_ci long 0xBFC555B5,0x848CB7DB 803962306a36Sopenharmony_ci 804062306a36Sopenharmony_ciLOGA4: 804162306a36Sopenharmony_ci long 0x3FC99999,0x987D8730 804262306a36Sopenharmony_ciLOGA3: 804362306a36Sopenharmony_ci long 0xBFCFFFFF,0xFF6F7E97 804462306a36Sopenharmony_ci 804562306a36Sopenharmony_ciLOGA2: 804662306a36Sopenharmony_ci long 0x3FD55555,0x555555A4 804762306a36Sopenharmony_ciLOGA1: 804862306a36Sopenharmony_ci long 0xBFE00000,0x00000008 804962306a36Sopenharmony_ci 805062306a36Sopenharmony_ciLOGB5: 805162306a36Sopenharmony_ci long 0x3F175496,0xADD7DAD6 805262306a36Sopenharmony_ciLOGB4: 805362306a36Sopenharmony_ci long 0x3F3C71C2,0xFE80C7E0 805462306a36Sopenharmony_ci 805562306a36Sopenharmony_ciLOGB3: 805662306a36Sopenharmony_ci long 0x3F624924,0x928BCCFF 805762306a36Sopenharmony_ciLOGB2: 805862306a36Sopenharmony_ci long 0x3F899999,0x999995EC 805962306a36Sopenharmony_ci 806062306a36Sopenharmony_ciLOGB1: 806162306a36Sopenharmony_ci long 0x3FB55555,0x55555555 806262306a36Sopenharmony_ciTWO: 806362306a36Sopenharmony_ci long 0x40000000,0x00000000 806462306a36Sopenharmony_ci 806562306a36Sopenharmony_ciLTHOLD: 806662306a36Sopenharmony_ci long 0x3f990000,0x80000000,0x00000000,0x00000000 806762306a36Sopenharmony_ci 806862306a36Sopenharmony_ciLOGTBL: 806962306a36Sopenharmony_ci long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000 807062306a36Sopenharmony_ci long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000 807162306a36Sopenharmony_ci long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000 807262306a36Sopenharmony_ci long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000 807362306a36Sopenharmony_ci long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000 807462306a36Sopenharmony_ci long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000 807562306a36Sopenharmony_ci long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000 807662306a36Sopenharmony_ci long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000 807762306a36Sopenharmony_ci long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000 807862306a36Sopenharmony_ci long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000 807962306a36Sopenharmony_ci long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000 808062306a36Sopenharmony_ci long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000 808162306a36Sopenharmony_ci long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000 808262306a36Sopenharmony_ci long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000 808362306a36Sopenharmony_ci long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000 808462306a36Sopenharmony_ci long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000 808562306a36Sopenharmony_ci long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000 808662306a36Sopenharmony_ci long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000 808762306a36Sopenharmony_ci long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000 808862306a36Sopenharmony_ci long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000 808962306a36Sopenharmony_ci long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000 809062306a36Sopenharmony_ci long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000 809162306a36Sopenharmony_ci long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000 809262306a36Sopenharmony_ci long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000 809362306a36Sopenharmony_ci long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000 809462306a36Sopenharmony_ci long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000 809562306a36Sopenharmony_ci long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000 809662306a36Sopenharmony_ci long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000 809762306a36Sopenharmony_ci long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000 809862306a36Sopenharmony_ci long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000 809962306a36Sopenharmony_ci long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000 810062306a36Sopenharmony_ci long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000 810162306a36Sopenharmony_ci long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000 810262306a36Sopenharmony_ci long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000 810362306a36Sopenharmony_ci long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000 810462306a36Sopenharmony_ci long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000 810562306a36Sopenharmony_ci long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000 810662306a36Sopenharmony_ci long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000 810762306a36Sopenharmony_ci long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000 810862306a36Sopenharmony_ci long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000 810962306a36Sopenharmony_ci long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000 811062306a36Sopenharmony_ci long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000 811162306a36Sopenharmony_ci long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000 811262306a36Sopenharmony_ci long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000 811362306a36Sopenharmony_ci long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000 811462306a36Sopenharmony_ci long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000 811562306a36Sopenharmony_ci long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000 811662306a36Sopenharmony_ci long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000 811762306a36Sopenharmony_ci long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000 811862306a36Sopenharmony_ci long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000 811962306a36Sopenharmony_ci long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000 812062306a36Sopenharmony_ci long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000 812162306a36Sopenharmony_ci long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000 812262306a36Sopenharmony_ci long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000 812362306a36Sopenharmony_ci long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000 812462306a36Sopenharmony_ci long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000 812562306a36Sopenharmony_ci long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000 812662306a36Sopenharmony_ci long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000 812762306a36Sopenharmony_ci long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000 812862306a36Sopenharmony_ci long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000 812962306a36Sopenharmony_ci long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000 813062306a36Sopenharmony_ci long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000 813162306a36Sopenharmony_ci long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000 813262306a36Sopenharmony_ci long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000 813362306a36Sopenharmony_ci long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000 813462306a36Sopenharmony_ci long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000 813562306a36Sopenharmony_ci long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000 813662306a36Sopenharmony_ci long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000 813762306a36Sopenharmony_ci long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000 813862306a36Sopenharmony_ci long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000 813962306a36Sopenharmony_ci long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000 814062306a36Sopenharmony_ci long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000 814162306a36Sopenharmony_ci long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000 814262306a36Sopenharmony_ci long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000 814362306a36Sopenharmony_ci long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000 814462306a36Sopenharmony_ci long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000 814562306a36Sopenharmony_ci long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000 814662306a36Sopenharmony_ci long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000 814762306a36Sopenharmony_ci long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000 814862306a36Sopenharmony_ci long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000 814962306a36Sopenharmony_ci long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000 815062306a36Sopenharmony_ci long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000 815162306a36Sopenharmony_ci long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000 815262306a36Sopenharmony_ci long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000 815362306a36Sopenharmony_ci long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000 815462306a36Sopenharmony_ci long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000 815562306a36Sopenharmony_ci long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000 815662306a36Sopenharmony_ci long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000 815762306a36Sopenharmony_ci long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000 815862306a36Sopenharmony_ci long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000 815962306a36Sopenharmony_ci long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000 816062306a36Sopenharmony_ci long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000 816162306a36Sopenharmony_ci long 0x3FFE0000,0x94458094,0x45809446,0x00000000 816262306a36Sopenharmony_ci long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000 816362306a36Sopenharmony_ci long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000 816462306a36Sopenharmony_ci long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000 816562306a36Sopenharmony_ci long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000 816662306a36Sopenharmony_ci long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000 816762306a36Sopenharmony_ci long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000 816862306a36Sopenharmony_ci long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000 816962306a36Sopenharmony_ci long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000 817062306a36Sopenharmony_ci long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000 817162306a36Sopenharmony_ci long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000 817262306a36Sopenharmony_ci long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000 817362306a36Sopenharmony_ci long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000 817462306a36Sopenharmony_ci long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000 817562306a36Sopenharmony_ci long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000 817662306a36Sopenharmony_ci long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000 817762306a36Sopenharmony_ci long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000 817862306a36Sopenharmony_ci long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000 817962306a36Sopenharmony_ci long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000 818062306a36Sopenharmony_ci long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000 818162306a36Sopenharmony_ci long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000 818262306a36Sopenharmony_ci long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000 818362306a36Sopenharmony_ci long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000 818462306a36Sopenharmony_ci long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000 818562306a36Sopenharmony_ci long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000 818662306a36Sopenharmony_ci long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000 818762306a36Sopenharmony_ci long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000 818862306a36Sopenharmony_ci long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000 818962306a36Sopenharmony_ci long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000 819062306a36Sopenharmony_ci long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000 819162306a36Sopenharmony_ci long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000 819262306a36Sopenharmony_ci long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000 819362306a36Sopenharmony_ci long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000 819462306a36Sopenharmony_ci long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000 819562306a36Sopenharmony_ci long 0x3FFE0000,0x80808080,0x80808081,0x00000000 819662306a36Sopenharmony_ci long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000 819762306a36Sopenharmony_ci 819862306a36Sopenharmony_ci set ADJK,L_SCR1 819962306a36Sopenharmony_ci 820062306a36Sopenharmony_ci set X,FP_SCR0 820162306a36Sopenharmony_ci set XDCARE,X+2 820262306a36Sopenharmony_ci set XFRAC,X+4 820362306a36Sopenharmony_ci 820462306a36Sopenharmony_ci set F,FP_SCR1 820562306a36Sopenharmony_ci set FFRAC,F+4 820662306a36Sopenharmony_ci 820762306a36Sopenharmony_ci set KLOG2,FP_SCR0 820862306a36Sopenharmony_ci 820962306a36Sopenharmony_ci set SAVEU,FP_SCR0 821062306a36Sopenharmony_ci 821162306a36Sopenharmony_ci global slogn 821262306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S 821362306a36Sopenharmony_cislogn: 821462306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 821562306a36Sopenharmony_ci mov.l &0x00000000,ADJK(%a6) 821662306a36Sopenharmony_ci 821762306a36Sopenharmony_ciLOGBGN: 821862306a36Sopenharmony_ci#--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS 821962306a36Sopenharmony_ci#--A FINITE, NON-ZERO, NORMALIZED NUMBER. 822062306a36Sopenharmony_ci 822162306a36Sopenharmony_ci mov.l (%a0),%d1 822262306a36Sopenharmony_ci mov.w 4(%a0),%d1 822362306a36Sopenharmony_ci 822462306a36Sopenharmony_ci mov.l (%a0),X(%a6) 822562306a36Sopenharmony_ci mov.l 4(%a0),X+4(%a6) 822662306a36Sopenharmony_ci mov.l 8(%a0),X+8(%a6) 822762306a36Sopenharmony_ci 822862306a36Sopenharmony_ci cmp.l %d1,&0 # CHECK IF X IS NEGATIVE 822962306a36Sopenharmony_ci blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID 823062306a36Sopenharmony_ci# X IS POSITIVE, CHECK IF X IS NEAR 1 823162306a36Sopenharmony_ci cmp.l %d1,&0x3ffef07d # IS X < 15/16? 823262306a36Sopenharmony_ci blt.b LOGMAIN # YES 823362306a36Sopenharmony_ci cmp.l %d1,&0x3fff8841 # IS X > 17/16? 823462306a36Sopenharmony_ci ble.w LOGNEAR1 # NO 823562306a36Sopenharmony_ci 823662306a36Sopenharmony_ciLOGMAIN: 823762306a36Sopenharmony_ci#--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1 823862306a36Sopenharmony_ci 823962306a36Sopenharmony_ci#--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY. 824062306a36Sopenharmony_ci#--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1. 824162306a36Sopenharmony_ci#--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y) 824262306a36Sopenharmony_ci#-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F). 824362306a36Sopenharmony_ci#--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING 824462306a36Sopenharmony_ci#--LOG(1+U) CAN BE VERY EFFICIENT. 824562306a36Sopenharmony_ci#--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO 824662306a36Sopenharmony_ci#--DIVISION IS NEEDED TO CALCULATE (Y-F)/F. 824762306a36Sopenharmony_ci 824862306a36Sopenharmony_ci#--GET K, Y, F, AND ADDRESS OF 1/F. 824962306a36Sopenharmony_ci asr.l &8,%d1 825062306a36Sopenharmony_ci asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X 825162306a36Sopenharmony_ci sub.l &0x3FFF,%d1 # THIS IS K 825262306a36Sopenharmony_ci add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM. 825362306a36Sopenharmony_ci lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F) 825462306a36Sopenharmony_ci fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT 825562306a36Sopenharmony_ci 825662306a36Sopenharmony_ci#--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F 825762306a36Sopenharmony_ci mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X 825862306a36Sopenharmony_ci mov.l XFRAC(%a6),FFRAC(%a6) 825962306a36Sopenharmony_ci and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y 826062306a36Sopenharmony_ci or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT 826162306a36Sopenharmony_ci mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F 826262306a36Sopenharmony_ci and.l &0x7E000000,%d1 826362306a36Sopenharmony_ci asr.l &8,%d1 826462306a36Sopenharmony_ci asr.l &8,%d1 826562306a36Sopenharmony_ci asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT 826662306a36Sopenharmony_ci add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F 826762306a36Sopenharmony_ci 826862306a36Sopenharmony_ci fmov.x X(%a6),%fp0 826962306a36Sopenharmony_ci mov.l &0x3fff0000,F(%a6) 827062306a36Sopenharmony_ci clr.l F+8(%a6) 827162306a36Sopenharmony_ci fsub.x F(%a6),%fp0 # Y-F 827262306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY 827362306a36Sopenharmony_ci#--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K 827462306a36Sopenharmony_ci#--REGISTERS SAVED: FPCR, FP1, FP2 827562306a36Sopenharmony_ci 827662306a36Sopenharmony_ciLP1CONT1: 827762306a36Sopenharmony_ci#--AN RE-ENTRY POINT FOR LOGNP1 827862306a36Sopenharmony_ci fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F 827962306a36Sopenharmony_ci fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY 828062306a36Sopenharmony_ci fmov.x %fp0,%fp2 828162306a36Sopenharmony_ci fmul.x %fp2,%fp2 # FP2 IS V=U*U 828262306a36Sopenharmony_ci fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMEORY, FREE FP1 828362306a36Sopenharmony_ci 828462306a36Sopenharmony_ci#--LOG(1+U) IS APPROXIMATED BY 828562306a36Sopenharmony_ci#--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS 828662306a36Sopenharmony_ci#--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))] 828762306a36Sopenharmony_ci 828862306a36Sopenharmony_ci fmov.x %fp2,%fp3 828962306a36Sopenharmony_ci fmov.x %fp2,%fp1 829062306a36Sopenharmony_ci 829162306a36Sopenharmony_ci fmul.d LOGA6(%pc),%fp1 # V*A6 829262306a36Sopenharmony_ci fmul.d LOGA5(%pc),%fp2 # V*A5 829362306a36Sopenharmony_ci 829462306a36Sopenharmony_ci fadd.d LOGA4(%pc),%fp1 # A4+V*A6 829562306a36Sopenharmony_ci fadd.d LOGA3(%pc),%fp2 # A3+V*A5 829662306a36Sopenharmony_ci 829762306a36Sopenharmony_ci fmul.x %fp3,%fp1 # V*(A4+V*A6) 829862306a36Sopenharmony_ci fmul.x %fp3,%fp2 # V*(A3+V*A5) 829962306a36Sopenharmony_ci 830062306a36Sopenharmony_ci fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6) 830162306a36Sopenharmony_ci fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5) 830262306a36Sopenharmony_ci 830362306a36Sopenharmony_ci fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6)) 830462306a36Sopenharmony_ci add.l &16,%a0 # ADDRESS OF LOG(F) 830562306a36Sopenharmony_ci fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5)) 830662306a36Sopenharmony_ci 830762306a36Sopenharmony_ci fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6)) 830862306a36Sopenharmony_ci fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5)) 830962306a36Sopenharmony_ci 831062306a36Sopenharmony_ci fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6)) 831162306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # RESTORE FP2-3 831262306a36Sopenharmony_ci fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U) 831362306a36Sopenharmony_ci 831462306a36Sopenharmony_ci fmov.l %d0,%fpcr 831562306a36Sopenharmony_ci fadd.x KLOG2(%a6),%fp0 # FINAL ADD 831662306a36Sopenharmony_ci bra t_inx2 831762306a36Sopenharmony_ci 831862306a36Sopenharmony_ci 831962306a36Sopenharmony_ciLOGNEAR1: 832062306a36Sopenharmony_ci 832162306a36Sopenharmony_ci# if the input is exactly equal to one, then exit through ld_pzero. 832262306a36Sopenharmony_ci# if these 2 lines weren't here, the correct answer would be returned 832362306a36Sopenharmony_ci# but the INEX2 bit would be set. 832462306a36Sopenharmony_ci fcmp.b %fp0,&0x1 # is it equal to one? 832562306a36Sopenharmony_ci fbeq.l ld_pzero # yes 832662306a36Sopenharmony_ci 832762306a36Sopenharmony_ci#--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT. 832862306a36Sopenharmony_ci fmov.x %fp0,%fp1 832962306a36Sopenharmony_ci fsub.s one(%pc),%fp1 # FP1 IS X-1 833062306a36Sopenharmony_ci fadd.s one(%pc),%fp0 # FP0 IS X+1 833162306a36Sopenharmony_ci fadd.x %fp1,%fp1 # FP1 IS 2(X-1) 833262306a36Sopenharmony_ci#--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL 833362306a36Sopenharmony_ci#--IN U, U = 2(X-1)/(X+1) = FP1/FP0 833462306a36Sopenharmony_ci 833562306a36Sopenharmony_ciLP1CONT2: 833662306a36Sopenharmony_ci#--THIS IS AN RE-ENTRY POINT FOR LOGNP1 833762306a36Sopenharmony_ci fdiv.x %fp0,%fp1 # FP1 IS U 833862306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # SAVE FP2-3 833962306a36Sopenharmony_ci#--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3 834062306a36Sopenharmony_ci#--LET V=U*U, W=V*V, CALCULATE 834162306a36Sopenharmony_ci#--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY 834262306a36Sopenharmony_ci#--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] ) 834362306a36Sopenharmony_ci fmov.x %fp1,%fp0 834462306a36Sopenharmony_ci fmul.x %fp0,%fp0 # FP0 IS V 834562306a36Sopenharmony_ci fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1 834662306a36Sopenharmony_ci fmov.x %fp0,%fp1 834762306a36Sopenharmony_ci fmul.x %fp1,%fp1 # FP1 IS W 834862306a36Sopenharmony_ci 834962306a36Sopenharmony_ci fmov.d LOGB5(%pc),%fp3 835062306a36Sopenharmony_ci fmov.d LOGB4(%pc),%fp2 835162306a36Sopenharmony_ci 835262306a36Sopenharmony_ci fmul.x %fp1,%fp3 # W*B5 835362306a36Sopenharmony_ci fmul.x %fp1,%fp2 # W*B4 835462306a36Sopenharmony_ci 835562306a36Sopenharmony_ci fadd.d LOGB3(%pc),%fp3 # B3+W*B5 835662306a36Sopenharmony_ci fadd.d LOGB2(%pc),%fp2 # B2+W*B4 835762306a36Sopenharmony_ci 835862306a36Sopenharmony_ci fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED 835962306a36Sopenharmony_ci 836062306a36Sopenharmony_ci fmul.x %fp0,%fp2 # V*(B2+W*B4) 836162306a36Sopenharmony_ci 836262306a36Sopenharmony_ci fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5) 836362306a36Sopenharmony_ci fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V 836462306a36Sopenharmony_ci 836562306a36Sopenharmony_ci fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED 836662306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED 836762306a36Sopenharmony_ci 836862306a36Sopenharmony_ci fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] ) 836962306a36Sopenharmony_ci 837062306a36Sopenharmony_ci fmov.l %d0,%fpcr 837162306a36Sopenharmony_ci fadd.x SAVEU(%a6),%fp0 837262306a36Sopenharmony_ci bra t_inx2 837362306a36Sopenharmony_ci 837462306a36Sopenharmony_ci#--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID 837562306a36Sopenharmony_ciLOGNEG: 837662306a36Sopenharmony_ci bra t_operr 837762306a36Sopenharmony_ci 837862306a36Sopenharmony_ci global slognd 837962306a36Sopenharmony_cislognd: 838062306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT 838162306a36Sopenharmony_ci 838262306a36Sopenharmony_ci mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0 838362306a36Sopenharmony_ci 838462306a36Sopenharmony_ci#----normalize the input value by left shifting k bits (k to be determined 838562306a36Sopenharmony_ci#----below), adjusting exponent and storing -k to ADJK 838662306a36Sopenharmony_ci#----the value TWOTO100 is no longer needed. 838762306a36Sopenharmony_ci#----Note that this code assumes the denormalized input is NON-ZERO. 838862306a36Sopenharmony_ci 838962306a36Sopenharmony_ci movm.l &0x3f00,-(%sp) # save some registers {d2-d7} 839062306a36Sopenharmony_ci mov.l (%a0),%d3 # D3 is exponent of smallest norm. # 839162306a36Sopenharmony_ci mov.l 4(%a0),%d4 839262306a36Sopenharmony_ci mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X) 839362306a36Sopenharmony_ci clr.l %d2 # D2 used for holding K 839462306a36Sopenharmony_ci 839562306a36Sopenharmony_ci tst.l %d4 839662306a36Sopenharmony_ci bne.b Hi_not0 839762306a36Sopenharmony_ci 839862306a36Sopenharmony_ciHi_0: 839962306a36Sopenharmony_ci mov.l %d5,%d4 840062306a36Sopenharmony_ci clr.l %d5 840162306a36Sopenharmony_ci mov.l &32,%d2 840262306a36Sopenharmony_ci clr.l %d6 840362306a36Sopenharmony_ci bfffo %d4{&0:&32},%d6 840462306a36Sopenharmony_ci lsl.l %d6,%d4 840562306a36Sopenharmony_ci add.l %d6,%d2 # (D3,D4,D5) is normalized 840662306a36Sopenharmony_ci 840762306a36Sopenharmony_ci mov.l %d3,X(%a6) 840862306a36Sopenharmony_ci mov.l %d4,XFRAC(%a6) 840962306a36Sopenharmony_ci mov.l %d5,XFRAC+4(%a6) 841062306a36Sopenharmony_ci neg.l %d2 841162306a36Sopenharmony_ci mov.l %d2,ADJK(%a6) 841262306a36Sopenharmony_ci fmov.x X(%a6),%fp0 841362306a36Sopenharmony_ci movm.l (%sp)+,&0xfc # restore registers {d2-d7} 841462306a36Sopenharmony_ci lea X(%a6),%a0 841562306a36Sopenharmony_ci bra.w LOGBGN # begin regular log(X) 841662306a36Sopenharmony_ci 841762306a36Sopenharmony_ciHi_not0: 841862306a36Sopenharmony_ci clr.l %d6 841962306a36Sopenharmony_ci bfffo %d4{&0:&32},%d6 # find first 1 842062306a36Sopenharmony_ci mov.l %d6,%d2 # get k 842162306a36Sopenharmony_ci lsl.l %d6,%d4 842262306a36Sopenharmony_ci mov.l %d5,%d7 # a copy of D5 842362306a36Sopenharmony_ci lsl.l %d6,%d5 842462306a36Sopenharmony_ci neg.l %d6 842562306a36Sopenharmony_ci add.l &32,%d6 842662306a36Sopenharmony_ci lsr.l %d6,%d7 842762306a36Sopenharmony_ci or.l %d7,%d4 # (D3,D4,D5) normalized 842862306a36Sopenharmony_ci 842962306a36Sopenharmony_ci mov.l %d3,X(%a6) 843062306a36Sopenharmony_ci mov.l %d4,XFRAC(%a6) 843162306a36Sopenharmony_ci mov.l %d5,XFRAC+4(%a6) 843262306a36Sopenharmony_ci neg.l %d2 843362306a36Sopenharmony_ci mov.l %d2,ADJK(%a6) 843462306a36Sopenharmony_ci fmov.x X(%a6),%fp0 843562306a36Sopenharmony_ci movm.l (%sp)+,&0xfc # restore registers {d2-d7} 843662306a36Sopenharmony_ci lea X(%a6),%a0 843762306a36Sopenharmony_ci bra.w LOGBGN # begin regular log(X) 843862306a36Sopenharmony_ci 843962306a36Sopenharmony_ci global slognp1 844062306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S 844162306a36Sopenharmony_cislognp1: 844262306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 844362306a36Sopenharmony_ci fabs.x %fp0 # test magnitude 844462306a36Sopenharmony_ci fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold 844562306a36Sopenharmony_ci fbgt.w LP1REAL # if greater, continue 844662306a36Sopenharmony_ci fmov.l %d0,%fpcr 844762306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 844862306a36Sopenharmony_ci fmov.x (%a0),%fp0 # return signed argument 844962306a36Sopenharmony_ci bra t_catch 845062306a36Sopenharmony_ci 845162306a36Sopenharmony_ciLP1REAL: 845262306a36Sopenharmony_ci fmov.x (%a0),%fp0 # LOAD INPUT 845362306a36Sopenharmony_ci mov.l &0x00000000,ADJK(%a6) 845462306a36Sopenharmony_ci fmov.x %fp0,%fp1 # FP1 IS INPUT Z 845562306a36Sopenharmony_ci fadd.s one(%pc),%fp0 # X := ROUND(1+Z) 845662306a36Sopenharmony_ci fmov.x %fp0,X(%a6) 845762306a36Sopenharmony_ci mov.w XFRAC(%a6),XDCARE(%a6) 845862306a36Sopenharmony_ci mov.l X(%a6),%d1 845962306a36Sopenharmony_ci cmp.l %d1,&0 846062306a36Sopenharmony_ci ble.w LP1NEG0 # LOG OF ZERO OR -VE 846162306a36Sopenharmony_ci cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]? 846262306a36Sopenharmony_ci blt.w LOGMAIN 846362306a36Sopenharmony_ci cmp.l %d1,&0x3fffc000 846462306a36Sopenharmony_ci bgt.w LOGMAIN 846562306a36Sopenharmony_ci#--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z, 846662306a36Sopenharmony_ci#--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE, 846762306a36Sopenharmony_ci#--SIMPLY INVOKE LOG(X) FOR LOG(1+Z). 846862306a36Sopenharmony_ci 846962306a36Sopenharmony_ciLP1NEAR1: 847062306a36Sopenharmony_ci#--NEXT SEE IF EXP(-1/16) < X < EXP(1/16) 847162306a36Sopenharmony_ci cmp.l %d1,&0x3ffef07d 847262306a36Sopenharmony_ci blt.w LP1CARE 847362306a36Sopenharmony_ci cmp.l %d1,&0x3fff8841 847462306a36Sopenharmony_ci bgt.w LP1CARE 847562306a36Sopenharmony_ci 847662306a36Sopenharmony_ciLP1ONE16: 847762306a36Sopenharmony_ci#--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2) 847862306a36Sopenharmony_ci#--WHERE U = 2Z/(2+Z) = 2Z/(1+X). 847962306a36Sopenharmony_ci fadd.x %fp1,%fp1 # FP1 IS 2Z 848062306a36Sopenharmony_ci fadd.s one(%pc),%fp0 # FP0 IS 1+X 848162306a36Sopenharmony_ci#--U = FP1/FP0 848262306a36Sopenharmony_ci bra.w LP1CONT2 848362306a36Sopenharmony_ci 848462306a36Sopenharmony_ciLP1CARE: 848562306a36Sopenharmony_ci#--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE 848662306a36Sopenharmony_ci#--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST 848762306a36Sopenharmony_ci#--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2], 848862306a36Sopenharmony_ci#--THERE ARE ONLY TWO CASES. 848962306a36Sopenharmony_ci#--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z 849062306a36Sopenharmony_ci#--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z 849162306a36Sopenharmony_ci#--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF 849262306a36Sopenharmony_ci#--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED. 849362306a36Sopenharmony_ci 849462306a36Sopenharmony_ci mov.l XFRAC(%a6),FFRAC(%a6) 849562306a36Sopenharmony_ci and.l &0xFE000000,FFRAC(%a6) 849662306a36Sopenharmony_ci or.l &0x01000000,FFRAC(%a6) # F OBTAINED 849762306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1 849862306a36Sopenharmony_ci bge.b KISZERO 849962306a36Sopenharmony_ci 850062306a36Sopenharmony_ciKISNEG1: 850162306a36Sopenharmony_ci fmov.s TWO(%pc),%fp0 850262306a36Sopenharmony_ci mov.l &0x3fff0000,F(%a6) 850362306a36Sopenharmony_ci clr.l F+8(%a6) 850462306a36Sopenharmony_ci fsub.x F(%a6),%fp0 # 2-F 850562306a36Sopenharmony_ci mov.l FFRAC(%a6),%d1 850662306a36Sopenharmony_ci and.l &0x7E000000,%d1 850762306a36Sopenharmony_ci asr.l &8,%d1 850862306a36Sopenharmony_ci asr.l &8,%d1 850962306a36Sopenharmony_ci asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F 851062306a36Sopenharmony_ci fadd.x %fp1,%fp1 # GET 2Z 851162306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3} 851262306a36Sopenharmony_ci fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z 851362306a36Sopenharmony_ci lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F 851462306a36Sopenharmony_ci add.l %d1,%a0 851562306a36Sopenharmony_ci fmov.s negone(%pc),%fp1 # FP1 IS K = -1 851662306a36Sopenharmony_ci bra.w LP1CONT1 851762306a36Sopenharmony_ci 851862306a36Sopenharmony_ciKISZERO: 851962306a36Sopenharmony_ci fmov.s one(%pc),%fp0 852062306a36Sopenharmony_ci mov.l &0x3fff0000,F(%a6) 852162306a36Sopenharmony_ci clr.l F+8(%a6) 852262306a36Sopenharmony_ci fsub.x F(%a6),%fp0 # 1-F 852362306a36Sopenharmony_ci mov.l FFRAC(%a6),%d1 852462306a36Sopenharmony_ci and.l &0x7E000000,%d1 852562306a36Sopenharmony_ci asr.l &8,%d1 852662306a36Sopenharmony_ci asr.l &8,%d1 852762306a36Sopenharmony_ci asr.l &4,%d1 852862306a36Sopenharmony_ci fadd.x %fp1,%fp0 # FP0 IS Y-F 852962306a36Sopenharmony_ci fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3} 853062306a36Sopenharmony_ci lea LOGTBL(%pc),%a0 853162306a36Sopenharmony_ci add.l %d1,%a0 # A0 IS ADDRESS OF 1/F 853262306a36Sopenharmony_ci fmov.s zero(%pc),%fp1 # FP1 IS K = 0 853362306a36Sopenharmony_ci bra.w LP1CONT1 853462306a36Sopenharmony_ci 853562306a36Sopenharmony_ciLP1NEG0: 853662306a36Sopenharmony_ci#--FPCR SAVED. D0 IS X IN COMPACT FORM. 853762306a36Sopenharmony_ci cmp.l %d1,&0 853862306a36Sopenharmony_ci blt.b LP1NEG 853962306a36Sopenharmony_ciLP1ZERO: 854062306a36Sopenharmony_ci fmov.s negone(%pc),%fp0 854162306a36Sopenharmony_ci 854262306a36Sopenharmony_ci fmov.l %d0,%fpcr 854362306a36Sopenharmony_ci bra t_dz 854462306a36Sopenharmony_ci 854562306a36Sopenharmony_ciLP1NEG: 854662306a36Sopenharmony_ci fmov.s zero(%pc),%fp0 854762306a36Sopenharmony_ci 854862306a36Sopenharmony_ci fmov.l %d0,%fpcr 854962306a36Sopenharmony_ci bra t_operr 855062306a36Sopenharmony_ci 855162306a36Sopenharmony_ci global slognp1d 855262306a36Sopenharmony_ci#--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT 855362306a36Sopenharmony_ci# Simply return the denorm 855462306a36Sopenharmony_cislognp1d: 855562306a36Sopenharmony_ci bra t_extdnrm 855662306a36Sopenharmony_ci 855762306a36Sopenharmony_ci######################################################################### 855862306a36Sopenharmony_ci# satanh(): computes the inverse hyperbolic tangent of a norm input # 855962306a36Sopenharmony_ci# satanhd(): computes the inverse hyperbolic tangent of a denorm input # 856062306a36Sopenharmony_ci# # 856162306a36Sopenharmony_ci# INPUT *************************************************************** # 856262306a36Sopenharmony_ci# a0 = pointer to extended precision input # 856362306a36Sopenharmony_ci# d0 = round precision,mode # 856462306a36Sopenharmony_ci# # 856562306a36Sopenharmony_ci# OUTPUT ************************************************************** # 856662306a36Sopenharmony_ci# fp0 = arctanh(X) # 856762306a36Sopenharmony_ci# # 856862306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 856962306a36Sopenharmony_ci# The returned result is within 3 ulps in 64 significant bit, # 857062306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 857162306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 857262306a36Sopenharmony_ci# in double precision. # 857362306a36Sopenharmony_ci# # 857462306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 857562306a36Sopenharmony_ci# # 857662306a36Sopenharmony_ci# ATANH # 857762306a36Sopenharmony_ci# 1. If |X| >= 1, go to 3. # 857862306a36Sopenharmony_ci# # 857962306a36Sopenharmony_ci# 2. (|X| < 1) Calculate atanh(X) by # 858062306a36Sopenharmony_ci# sgn := sign(X) # 858162306a36Sopenharmony_ci# y := |X| # 858262306a36Sopenharmony_ci# z := 2y/(1-y) # 858362306a36Sopenharmony_ci# atanh(X) := sgn * (1/2) * logp1(z) # 858462306a36Sopenharmony_ci# Exit. # 858562306a36Sopenharmony_ci# # 858662306a36Sopenharmony_ci# 3. If |X| > 1, go to 5. # 858762306a36Sopenharmony_ci# # 858862306a36Sopenharmony_ci# 4. (|X| = 1) Generate infinity with an appropriate sign and # 858962306a36Sopenharmony_ci# divide-by-zero by # 859062306a36Sopenharmony_ci# sgn := sign(X) # 859162306a36Sopenharmony_ci# atan(X) := sgn / (+0). # 859262306a36Sopenharmony_ci# Exit. # 859362306a36Sopenharmony_ci# # 859462306a36Sopenharmony_ci# 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 859562306a36Sopenharmony_ci# Exit. # 859662306a36Sopenharmony_ci# # 859762306a36Sopenharmony_ci######################################################################### 859862306a36Sopenharmony_ci 859962306a36Sopenharmony_ci global satanh 860062306a36Sopenharmony_cisatanh: 860162306a36Sopenharmony_ci mov.l (%a0),%d1 860262306a36Sopenharmony_ci mov.w 4(%a0),%d1 860362306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 860462306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 860562306a36Sopenharmony_ci bge.b ATANHBIG 860662306a36Sopenharmony_ci 860762306a36Sopenharmony_ci#--THIS IS THE USUAL CASE, |X| < 1 860862306a36Sopenharmony_ci#--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z). 860962306a36Sopenharmony_ci 861062306a36Sopenharmony_ci fabs.x (%a0),%fp0 # Y = |X| 861162306a36Sopenharmony_ci fmov.x %fp0,%fp1 861262306a36Sopenharmony_ci fneg.x %fp1 # -Y 861362306a36Sopenharmony_ci fadd.x %fp0,%fp0 # 2Y 861462306a36Sopenharmony_ci fadd.s &0x3F800000,%fp1 # 1-Y 861562306a36Sopenharmony_ci fdiv.x %fp1,%fp0 # 2Y/(1-Y) 861662306a36Sopenharmony_ci mov.l (%a0),%d1 861762306a36Sopenharmony_ci and.l &0x80000000,%d1 861862306a36Sopenharmony_ci or.l &0x3F000000,%d1 # SIGN(X)*HALF 861962306a36Sopenharmony_ci mov.l %d1,-(%sp) 862062306a36Sopenharmony_ci 862162306a36Sopenharmony_ci mov.l %d0,-(%sp) # save rnd prec,mode 862262306a36Sopenharmony_ci clr.l %d0 # pass ext prec,RN 862362306a36Sopenharmony_ci fmovm.x &0x01,-(%sp) # save Z on stack 862462306a36Sopenharmony_ci lea (%sp),%a0 # pass ptr to Z 862562306a36Sopenharmony_ci bsr slognp1 # LOG1P(Z) 862662306a36Sopenharmony_ci add.l &0xc,%sp # clear Z from stack 862762306a36Sopenharmony_ci 862862306a36Sopenharmony_ci mov.l (%sp)+,%d0 # fetch old prec,mode 862962306a36Sopenharmony_ci fmov.l %d0,%fpcr # load it 863062306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 863162306a36Sopenharmony_ci fmul.s (%sp)+,%fp0 863262306a36Sopenharmony_ci bra t_catch 863362306a36Sopenharmony_ci 863462306a36Sopenharmony_ciATANHBIG: 863562306a36Sopenharmony_ci fabs.x (%a0),%fp0 # |X| 863662306a36Sopenharmony_ci fcmp.s %fp0,&0x3F800000 863762306a36Sopenharmony_ci fbgt t_operr 863862306a36Sopenharmony_ci bra t_dz 863962306a36Sopenharmony_ci 864062306a36Sopenharmony_ci global satanhd 864162306a36Sopenharmony_ci#--ATANH(X) = X FOR DENORMALIZED X 864262306a36Sopenharmony_cisatanhd: 864362306a36Sopenharmony_ci bra t_extdnrm 864462306a36Sopenharmony_ci 864562306a36Sopenharmony_ci######################################################################### 864662306a36Sopenharmony_ci# slog10(): computes the base-10 logarithm of a normalized input # 864762306a36Sopenharmony_ci# slog10d(): computes the base-10 logarithm of a denormalized input # 864862306a36Sopenharmony_ci# slog2(): computes the base-2 logarithm of a normalized input # 864962306a36Sopenharmony_ci# slog2d(): computes the base-2 logarithm of a denormalized input # 865062306a36Sopenharmony_ci# # 865162306a36Sopenharmony_ci# INPUT *************************************************************** # 865262306a36Sopenharmony_ci# a0 = pointer to extended precision input # 865362306a36Sopenharmony_ci# d0 = round precision,mode # 865462306a36Sopenharmony_ci# # 865562306a36Sopenharmony_ci# OUTPUT ************************************************************** # 865662306a36Sopenharmony_ci# fp0 = log_10(X) or log_2(X) # 865762306a36Sopenharmony_ci# # 865862306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 865962306a36Sopenharmony_ci# The returned result is within 1.7 ulps in 64 significant bit, # 866062306a36Sopenharmony_ci# i.e. within 0.5003 ulp to 53 bits if the result is subsequently # 866162306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 866262306a36Sopenharmony_ci# in double precision. # 866362306a36Sopenharmony_ci# # 866462306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 866562306a36Sopenharmony_ci# # 866662306a36Sopenharmony_ci# slog10d: # 866762306a36Sopenharmony_ci# # 866862306a36Sopenharmony_ci# Step 0. If X < 0, create a NaN and raise the invalid operation # 866962306a36Sopenharmony_ci# flag. Otherwise, save FPCR in D1; set FpCR to default. # 867062306a36Sopenharmony_ci# Notes: Default means round-to-nearest mode, no floating-point # 867162306a36Sopenharmony_ci# traps, and precision control = double extended. # 867262306a36Sopenharmony_ci# # 867362306a36Sopenharmony_ci# Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 867462306a36Sopenharmony_ci# Notes: Even if X is denormalized, log(X) is always normalized. # 867562306a36Sopenharmony_ci# # 867662306a36Sopenharmony_ci# Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 867762306a36Sopenharmony_ci# 2.1 Restore the user FPCR # 867862306a36Sopenharmony_ci# 2.2 Return ans := Y * INV_L10. # 867962306a36Sopenharmony_ci# # 868062306a36Sopenharmony_ci# slog10: # 868162306a36Sopenharmony_ci# # 868262306a36Sopenharmony_ci# Step 0. If X < 0, create a NaN and raise the invalid operation # 868362306a36Sopenharmony_ci# flag. Otherwise, save FPCR in D1; set FpCR to default. # 868462306a36Sopenharmony_ci# Notes: Default means round-to-nearest mode, no floating-point # 868562306a36Sopenharmony_ci# traps, and precision control = double extended. # 868662306a36Sopenharmony_ci# # 868762306a36Sopenharmony_ci# Step 1. Call sLogN to obtain Y = log(X), the natural log of X. # 868862306a36Sopenharmony_ci# # 868962306a36Sopenharmony_ci# Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 869062306a36Sopenharmony_ci# 2.1 Restore the user FPCR # 869162306a36Sopenharmony_ci# 2.2 Return ans := Y * INV_L10. # 869262306a36Sopenharmony_ci# # 869362306a36Sopenharmony_ci# sLog2d: # 869462306a36Sopenharmony_ci# # 869562306a36Sopenharmony_ci# Step 0. If X < 0, create a NaN and raise the invalid operation # 869662306a36Sopenharmony_ci# flag. Otherwise, save FPCR in D1; set FpCR to default. # 869762306a36Sopenharmony_ci# Notes: Default means round-to-nearest mode, no floating-point # 869862306a36Sopenharmony_ci# traps, and precision control = double extended. # 869962306a36Sopenharmony_ci# # 870062306a36Sopenharmony_ci# Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 870162306a36Sopenharmony_ci# Notes: Even if X is denormalized, log(X) is always normalized. # 870262306a36Sopenharmony_ci# # 870362306a36Sopenharmony_ci# Step 2. Compute log_10(X) = log(X) * (1/log(2)). # 870462306a36Sopenharmony_ci# 2.1 Restore the user FPCR # 870562306a36Sopenharmony_ci# 2.2 Return ans := Y * INV_L2. # 870662306a36Sopenharmony_ci# # 870762306a36Sopenharmony_ci# sLog2: # 870862306a36Sopenharmony_ci# # 870962306a36Sopenharmony_ci# Step 0. If X < 0, create a NaN and raise the invalid operation # 871062306a36Sopenharmony_ci# flag. Otherwise, save FPCR in D1; set FpCR to default. # 871162306a36Sopenharmony_ci# Notes: Default means round-to-nearest mode, no floating-point # 871262306a36Sopenharmony_ci# traps, and precision control = double extended. # 871362306a36Sopenharmony_ci# # 871462306a36Sopenharmony_ci# Step 1. If X is not an integer power of two, i.e., X != 2^k, # 871562306a36Sopenharmony_ci# go to Step 3. # 871662306a36Sopenharmony_ci# # 871762306a36Sopenharmony_ci# Step 2. Return k. # 871862306a36Sopenharmony_ci# 2.1 Get integer k, X = 2^k. # 871962306a36Sopenharmony_ci# 2.2 Restore the user FPCR. # 872062306a36Sopenharmony_ci# 2.3 Return ans := convert-to-double-extended(k). # 872162306a36Sopenharmony_ci# # 872262306a36Sopenharmony_ci# Step 3. Call sLogN to obtain Y = log(X), the natural log of X. # 872362306a36Sopenharmony_ci# # 872462306a36Sopenharmony_ci# Step 4. Compute log_2(X) = log(X) * (1/log(2)). # 872562306a36Sopenharmony_ci# 4.1 Restore the user FPCR # 872662306a36Sopenharmony_ci# 4.2 Return ans := Y * INV_L2. # 872762306a36Sopenharmony_ci# # 872862306a36Sopenharmony_ci######################################################################### 872962306a36Sopenharmony_ci 873062306a36Sopenharmony_ciINV_L10: 873162306a36Sopenharmony_ci long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 873262306a36Sopenharmony_ci 873362306a36Sopenharmony_ciINV_L2: 873462306a36Sopenharmony_ci long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 873562306a36Sopenharmony_ci 873662306a36Sopenharmony_ci global slog10 873762306a36Sopenharmony_ci#--entry point for Log10(X), X is normalized 873862306a36Sopenharmony_cislog10: 873962306a36Sopenharmony_ci fmov.b &0x1,%fp0 874062306a36Sopenharmony_ci fcmp.x %fp0,(%a0) # if operand == 1, 874162306a36Sopenharmony_ci fbeq.l ld_pzero # return an EXACT zero 874262306a36Sopenharmony_ci 874362306a36Sopenharmony_ci mov.l (%a0),%d1 874462306a36Sopenharmony_ci blt.w invalid 874562306a36Sopenharmony_ci mov.l %d0,-(%sp) 874662306a36Sopenharmony_ci clr.l %d0 874762306a36Sopenharmony_ci bsr slogn # log(X), X normal. 874862306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr 874962306a36Sopenharmony_ci fmul.x INV_L10(%pc),%fp0 875062306a36Sopenharmony_ci bra t_inx2 875162306a36Sopenharmony_ci 875262306a36Sopenharmony_ci global slog10d 875362306a36Sopenharmony_ci#--entry point for Log10(X), X is denormalized 875462306a36Sopenharmony_cislog10d: 875562306a36Sopenharmony_ci mov.l (%a0),%d1 875662306a36Sopenharmony_ci blt.w invalid 875762306a36Sopenharmony_ci mov.l %d0,-(%sp) 875862306a36Sopenharmony_ci clr.l %d0 875962306a36Sopenharmony_ci bsr slognd # log(X), X denorm. 876062306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr 876162306a36Sopenharmony_ci fmul.x INV_L10(%pc),%fp0 876262306a36Sopenharmony_ci bra t_minx2 876362306a36Sopenharmony_ci 876462306a36Sopenharmony_ci global slog2 876562306a36Sopenharmony_ci#--entry point for Log2(X), X is normalized 876662306a36Sopenharmony_cislog2: 876762306a36Sopenharmony_ci mov.l (%a0),%d1 876862306a36Sopenharmony_ci blt.w invalid 876962306a36Sopenharmony_ci 877062306a36Sopenharmony_ci mov.l 8(%a0),%d1 877162306a36Sopenharmony_ci bne.b continue # X is not 2^k 877262306a36Sopenharmony_ci 877362306a36Sopenharmony_ci mov.l 4(%a0),%d1 877462306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 877562306a36Sopenharmony_ci bne.b continue 877662306a36Sopenharmony_ci 877762306a36Sopenharmony_ci#--X = 2^k. 877862306a36Sopenharmony_ci mov.w (%a0),%d1 877962306a36Sopenharmony_ci and.l &0x00007FFF,%d1 878062306a36Sopenharmony_ci sub.l &0x3FFF,%d1 878162306a36Sopenharmony_ci beq.l ld_pzero 878262306a36Sopenharmony_ci fmov.l %d0,%fpcr 878362306a36Sopenharmony_ci fmov.l %d1,%fp0 878462306a36Sopenharmony_ci bra t_inx2 878562306a36Sopenharmony_ci 878662306a36Sopenharmony_cicontinue: 878762306a36Sopenharmony_ci mov.l %d0,-(%sp) 878862306a36Sopenharmony_ci clr.l %d0 878962306a36Sopenharmony_ci bsr slogn # log(X), X normal. 879062306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr 879162306a36Sopenharmony_ci fmul.x INV_L2(%pc),%fp0 879262306a36Sopenharmony_ci bra t_inx2 879362306a36Sopenharmony_ci 879462306a36Sopenharmony_ciinvalid: 879562306a36Sopenharmony_ci bra t_operr 879662306a36Sopenharmony_ci 879762306a36Sopenharmony_ci global slog2d 879862306a36Sopenharmony_ci#--entry point for Log2(X), X is denormalized 879962306a36Sopenharmony_cislog2d: 880062306a36Sopenharmony_ci mov.l (%a0),%d1 880162306a36Sopenharmony_ci blt.w invalid 880262306a36Sopenharmony_ci mov.l %d0,-(%sp) 880362306a36Sopenharmony_ci clr.l %d0 880462306a36Sopenharmony_ci bsr slognd # log(X), X denorm. 880562306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr 880662306a36Sopenharmony_ci fmul.x INV_L2(%pc),%fp0 880762306a36Sopenharmony_ci bra t_minx2 880862306a36Sopenharmony_ci 880962306a36Sopenharmony_ci######################################################################### 881062306a36Sopenharmony_ci# stwotox(): computes 2**X for a normalized input # 881162306a36Sopenharmony_ci# stwotoxd(): computes 2**X for a denormalized input # 881262306a36Sopenharmony_ci# stentox(): computes 10**X for a normalized input # 881362306a36Sopenharmony_ci# stentoxd(): computes 10**X for a denormalized input # 881462306a36Sopenharmony_ci# # 881562306a36Sopenharmony_ci# INPUT *************************************************************** # 881662306a36Sopenharmony_ci# a0 = pointer to extended precision input # 881762306a36Sopenharmony_ci# d0 = round precision,mode # 881862306a36Sopenharmony_ci# # 881962306a36Sopenharmony_ci# OUTPUT ************************************************************** # 882062306a36Sopenharmony_ci# fp0 = 2**X or 10**X # 882162306a36Sopenharmony_ci# # 882262306a36Sopenharmony_ci# ACCURACY and MONOTONICITY ******************************************* # 882362306a36Sopenharmony_ci# The returned result is within 2 ulps in 64 significant bit, # 882462306a36Sopenharmony_ci# i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 882562306a36Sopenharmony_ci# rounded to double precision. The result is provably monotonic # 882662306a36Sopenharmony_ci# in double precision. # 882762306a36Sopenharmony_ci# # 882862306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 882962306a36Sopenharmony_ci# # 883062306a36Sopenharmony_ci# twotox # 883162306a36Sopenharmony_ci# 1. If |X| > 16480, go to ExpBig. # 883262306a36Sopenharmony_ci# # 883362306a36Sopenharmony_ci# 2. If |X| < 2**(-70), go to ExpSm. # 883462306a36Sopenharmony_ci# # 883562306a36Sopenharmony_ci# 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore # 883662306a36Sopenharmony_ci# decompose N as # 883762306a36Sopenharmony_ci# N = 64(M + M') + j, j = 0,1,2,...,63. # 883862306a36Sopenharmony_ci# # 883962306a36Sopenharmony_ci# 4. Overwrite r := r * log2. Then # 884062306a36Sopenharmony_ci# 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 884162306a36Sopenharmony_ci# Go to expr to compute that expression. # 884262306a36Sopenharmony_ci# # 884362306a36Sopenharmony_ci# tentox # 884462306a36Sopenharmony_ci# 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. # 884562306a36Sopenharmony_ci# # 884662306a36Sopenharmony_ci# 2. If |X| < 2**(-70), go to ExpSm. # 884762306a36Sopenharmony_ci# # 884862306a36Sopenharmony_ci# 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set # 884962306a36Sopenharmony_ci# N := round-to-int(y). Decompose N as # 885062306a36Sopenharmony_ci# N = 64(M + M') + j, j = 0,1,2,...,63. # 885162306a36Sopenharmony_ci# # 885262306a36Sopenharmony_ci# 4. Define r as # 885362306a36Sopenharmony_ci# r := ((X - N*L1)-N*L2) * L10 # 885462306a36Sopenharmony_ci# where L1, L2 are the leading and trailing parts of # 885562306a36Sopenharmony_ci# log_10(2)/64 and L10 is the natural log of 10. Then # 885662306a36Sopenharmony_ci# 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 885762306a36Sopenharmony_ci# Go to expr to compute that expression. # 885862306a36Sopenharmony_ci# # 885962306a36Sopenharmony_ci# expr # 886062306a36Sopenharmony_ci# 1. Fetch 2**(j/64) from table as Fact1 and Fact2. # 886162306a36Sopenharmony_ci# # 886262306a36Sopenharmony_ci# 2. Overwrite Fact1 and Fact2 by # 886362306a36Sopenharmony_ci# Fact1 := 2**(M) * Fact1 # 886462306a36Sopenharmony_ci# Fact2 := 2**(M) * Fact2 # 886562306a36Sopenharmony_ci# Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). # 886662306a36Sopenharmony_ci# # 886762306a36Sopenharmony_ci# 3. Calculate P where 1 + P approximates exp(r): # 886862306a36Sopenharmony_ci# P = r + r*r*(A1+r*(A2+...+r*A5)). # 886962306a36Sopenharmony_ci# # 887062306a36Sopenharmony_ci# 4. Let AdjFact := 2**(M'). Return # 887162306a36Sopenharmony_ci# AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). # 887262306a36Sopenharmony_ci# Exit. # 887362306a36Sopenharmony_ci# # 887462306a36Sopenharmony_ci# ExpBig # 887562306a36Sopenharmony_ci# 1. Generate overflow by Huge * Huge if X > 0; otherwise, # 887662306a36Sopenharmony_ci# generate underflow by Tiny * Tiny. # 887762306a36Sopenharmony_ci# # 887862306a36Sopenharmony_ci# ExpSm # 887962306a36Sopenharmony_ci# 1. Return 1 + X. # 888062306a36Sopenharmony_ci# # 888162306a36Sopenharmony_ci######################################################################### 888262306a36Sopenharmony_ci 888362306a36Sopenharmony_ciL2TEN64: 888462306a36Sopenharmony_ci long 0x406A934F,0x0979A371 # 64LOG10/LOG2 888562306a36Sopenharmony_ciL10TWO1: 888662306a36Sopenharmony_ci long 0x3F734413,0x509F8000 # LOG2/64LOG10 888762306a36Sopenharmony_ci 888862306a36Sopenharmony_ciL10TWO2: 888962306a36Sopenharmony_ci long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000 889062306a36Sopenharmony_ci 889162306a36Sopenharmony_ciLOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000 889262306a36Sopenharmony_ci 889362306a36Sopenharmony_ciLOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 889462306a36Sopenharmony_ci 889562306a36Sopenharmony_ciEXPA5: long 0x3F56C16D,0x6F7BD0B2 889662306a36Sopenharmony_ciEXPA4: long 0x3F811112,0x302C712C 889762306a36Sopenharmony_ciEXPA3: long 0x3FA55555,0x55554CC1 889862306a36Sopenharmony_ciEXPA2: long 0x3FC55555,0x55554A54 889962306a36Sopenharmony_ciEXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000 890062306a36Sopenharmony_ci 890162306a36Sopenharmony_ciTEXPTBL: 890262306a36Sopenharmony_ci long 0x3FFF0000,0x80000000,0x00000000,0x3F738000 890362306a36Sopenharmony_ci long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA 890462306a36Sopenharmony_ci long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9 890562306a36Sopenharmony_ci long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9 890662306a36Sopenharmony_ci long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA 890762306a36Sopenharmony_ci long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C 890862306a36Sopenharmony_ci long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1 890962306a36Sopenharmony_ci long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA 891062306a36Sopenharmony_ci long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373 891162306a36Sopenharmony_ci long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670 891262306a36Sopenharmony_ci long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700 891362306a36Sopenharmony_ci long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0 891462306a36Sopenharmony_ci long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D 891562306a36Sopenharmony_ci long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319 891662306a36Sopenharmony_ci long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B 891762306a36Sopenharmony_ci long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5 891862306a36Sopenharmony_ci long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A 891962306a36Sopenharmony_ci long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B 892062306a36Sopenharmony_ci long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF 892162306a36Sopenharmony_ci long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA 892262306a36Sopenharmony_ci long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD 892362306a36Sopenharmony_ci long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E 892462306a36Sopenharmony_ci long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B 892562306a36Sopenharmony_ci long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB 892662306a36Sopenharmony_ci long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB 892762306a36Sopenharmony_ci long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274 892862306a36Sopenharmony_ci long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C 892962306a36Sopenharmony_ci long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00 893062306a36Sopenharmony_ci long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301 893162306a36Sopenharmony_ci long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367 893262306a36Sopenharmony_ci long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F 893362306a36Sopenharmony_ci long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C 893462306a36Sopenharmony_ci long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB 893562306a36Sopenharmony_ci long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB 893662306a36Sopenharmony_ci long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C 893762306a36Sopenharmony_ci long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA 893862306a36Sopenharmony_ci long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD 893962306a36Sopenharmony_ci long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51 894062306a36Sopenharmony_ci long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A 894162306a36Sopenharmony_ci long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2 894262306a36Sopenharmony_ci long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB 894362306a36Sopenharmony_ci long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17 894462306a36Sopenharmony_ci long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C 894562306a36Sopenharmony_ci long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8 894662306a36Sopenharmony_ci long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53 894762306a36Sopenharmony_ci long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE 894862306a36Sopenharmony_ci long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124 894962306a36Sopenharmony_ci long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243 895062306a36Sopenharmony_ci long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A 895162306a36Sopenharmony_ci long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61 895262306a36Sopenharmony_ci long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610 895362306a36Sopenharmony_ci long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1 895462306a36Sopenharmony_ci long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12 895562306a36Sopenharmony_ci long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE 895662306a36Sopenharmony_ci long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4 895762306a36Sopenharmony_ci long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F 895862306a36Sopenharmony_ci long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A 895962306a36Sopenharmony_ci long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A 896062306a36Sopenharmony_ci long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC 896162306a36Sopenharmony_ci long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F 896262306a36Sopenharmony_ci long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A 896362306a36Sopenharmony_ci long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795 896462306a36Sopenharmony_ci long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B 896562306a36Sopenharmony_ci long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581 896662306a36Sopenharmony_ci 896762306a36Sopenharmony_ci set INT,L_SCR1 896862306a36Sopenharmony_ci 896962306a36Sopenharmony_ci set X,FP_SCR0 897062306a36Sopenharmony_ci set XDCARE,X+2 897162306a36Sopenharmony_ci set XFRAC,X+4 897262306a36Sopenharmony_ci 897362306a36Sopenharmony_ci set ADJFACT,FP_SCR0 897462306a36Sopenharmony_ci 897562306a36Sopenharmony_ci set FACT1,FP_SCR0 897662306a36Sopenharmony_ci set FACT1HI,FACT1+4 897762306a36Sopenharmony_ci set FACT1LOW,FACT1+8 897862306a36Sopenharmony_ci 897962306a36Sopenharmony_ci set FACT2,FP_SCR1 898062306a36Sopenharmony_ci set FACT2HI,FACT2+4 898162306a36Sopenharmony_ci set FACT2LOW,FACT2+8 898262306a36Sopenharmony_ci 898362306a36Sopenharmony_ci global stwotox 898462306a36Sopenharmony_ci#--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 898562306a36Sopenharmony_cistwotox: 898662306a36Sopenharmony_ci fmovm.x (%a0),&0x80 # LOAD INPUT 898762306a36Sopenharmony_ci 898862306a36Sopenharmony_ci mov.l (%a0),%d1 898962306a36Sopenharmony_ci mov.w 4(%a0),%d1 899062306a36Sopenharmony_ci fmov.x %fp0,X(%a6) 899162306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 899262306a36Sopenharmony_ci 899362306a36Sopenharmony_ci cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 899462306a36Sopenharmony_ci bge.b TWOOK1 899562306a36Sopenharmony_ci bra.w EXPBORS 899662306a36Sopenharmony_ci 899762306a36Sopenharmony_ciTWOOK1: 899862306a36Sopenharmony_ci cmp.l %d1,&0x400D80C0 # |X| > 16480? 899962306a36Sopenharmony_ci ble.b TWOMAIN 900062306a36Sopenharmony_ci bra.w EXPBORS 900162306a36Sopenharmony_ci 900262306a36Sopenharmony_ciTWOMAIN: 900362306a36Sopenharmony_ci#--USUAL CASE, 2^(-70) <= |X| <= 16480 900462306a36Sopenharmony_ci 900562306a36Sopenharmony_ci fmov.x %fp0,%fp1 900662306a36Sopenharmony_ci fmul.s &0x42800000,%fp1 # 64 * X 900762306a36Sopenharmony_ci fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X) 900862306a36Sopenharmony_ci mov.l %d2,-(%sp) 900962306a36Sopenharmony_ci lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 901062306a36Sopenharmony_ci fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 901162306a36Sopenharmony_ci mov.l INT(%a6),%d1 901262306a36Sopenharmony_ci mov.l %d1,%d2 901362306a36Sopenharmony_ci and.l &0x3F,%d1 # D0 IS J 901462306a36Sopenharmony_ci asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 901562306a36Sopenharmony_ci add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 901662306a36Sopenharmony_ci asr.l &6,%d2 # d2 IS L, N = 64L + J 901762306a36Sopenharmony_ci mov.l %d2,%d1 901862306a36Sopenharmony_ci asr.l &1,%d1 # D0 IS M 901962306a36Sopenharmony_ci sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 902062306a36Sopenharmony_ci add.l &0x3FFF,%d2 902162306a36Sopenharmony_ci 902262306a36Sopenharmony_ci#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 902362306a36Sopenharmony_ci#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 902462306a36Sopenharmony_ci#--ADJFACT = 2^(M'). 902562306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 902662306a36Sopenharmony_ci 902762306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2/fp3 902862306a36Sopenharmony_ci 902962306a36Sopenharmony_ci fmul.s &0x3C800000,%fp1 # (1/64)*N 903062306a36Sopenharmony_ci mov.l (%a1)+,FACT1(%a6) 903162306a36Sopenharmony_ci mov.l (%a1)+,FACT1HI(%a6) 903262306a36Sopenharmony_ci mov.l (%a1)+,FACT1LOW(%a6) 903362306a36Sopenharmony_ci mov.w (%a1)+,FACT2(%a6) 903462306a36Sopenharmony_ci 903562306a36Sopenharmony_ci fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X) 903662306a36Sopenharmony_ci 903762306a36Sopenharmony_ci mov.w (%a1)+,FACT2HI(%a6) 903862306a36Sopenharmony_ci clr.w FACT2HI+2(%a6) 903962306a36Sopenharmony_ci clr.l FACT2LOW(%a6) 904062306a36Sopenharmony_ci add.w %d1,FACT1(%a6) 904162306a36Sopenharmony_ci fmul.x LOG2(%pc),%fp0 # FP0 IS R 904262306a36Sopenharmony_ci add.w %d1,FACT2(%a6) 904362306a36Sopenharmony_ci 904462306a36Sopenharmony_ci bra.w expr 904562306a36Sopenharmony_ci 904662306a36Sopenharmony_ciEXPBORS: 904762306a36Sopenharmony_ci#--FPCR, D0 SAVED 904862306a36Sopenharmony_ci cmp.l %d1,&0x3FFF8000 904962306a36Sopenharmony_ci bgt.b TEXPBIG 905062306a36Sopenharmony_ci 905162306a36Sopenharmony_ci#--|X| IS SMALL, RETURN 1 + X 905262306a36Sopenharmony_ci 905362306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round prec,mode 905462306a36Sopenharmony_ci fadd.s &0x3F800000,%fp0 # RETURN 1 + X 905562306a36Sopenharmony_ci bra t_pinx2 905662306a36Sopenharmony_ci 905762306a36Sopenharmony_ciTEXPBIG: 905862306a36Sopenharmony_ci#--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW 905962306a36Sopenharmony_ci#--REGISTERS SAVE SO FAR ARE FPCR AND D0 906062306a36Sopenharmony_ci mov.l X(%a6),%d1 906162306a36Sopenharmony_ci cmp.l %d1,&0 906262306a36Sopenharmony_ci blt.b EXPNEG 906362306a36Sopenharmony_ci 906462306a36Sopenharmony_ci bra t_ovfl2 # t_ovfl expects positive value 906562306a36Sopenharmony_ci 906662306a36Sopenharmony_ciEXPNEG: 906762306a36Sopenharmony_ci bra t_unfl2 # t_unfl expects positive value 906862306a36Sopenharmony_ci 906962306a36Sopenharmony_ci global stwotoxd 907062306a36Sopenharmony_cistwotoxd: 907162306a36Sopenharmony_ci#--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT 907262306a36Sopenharmony_ci 907362306a36Sopenharmony_ci fmov.l %d0,%fpcr # set user's rounding mode/precision 907462306a36Sopenharmony_ci fmov.s &0x3F800000,%fp0 # RETURN 1 + X 907562306a36Sopenharmony_ci mov.l (%a0),%d1 907662306a36Sopenharmony_ci or.l &0x00800001,%d1 907762306a36Sopenharmony_ci fadd.s %d1,%fp0 907862306a36Sopenharmony_ci bra t_pinx2 907962306a36Sopenharmony_ci 908062306a36Sopenharmony_ci global stentox 908162306a36Sopenharmony_ci#--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 908262306a36Sopenharmony_cistentox: 908362306a36Sopenharmony_ci fmovm.x (%a0),&0x80 # LOAD INPUT 908462306a36Sopenharmony_ci 908562306a36Sopenharmony_ci mov.l (%a0),%d1 908662306a36Sopenharmony_ci mov.w 4(%a0),%d1 908762306a36Sopenharmony_ci fmov.x %fp0,X(%a6) 908862306a36Sopenharmony_ci and.l &0x7FFFFFFF,%d1 908962306a36Sopenharmony_ci 909062306a36Sopenharmony_ci cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 909162306a36Sopenharmony_ci bge.b TENOK1 909262306a36Sopenharmony_ci bra.w EXPBORS 909362306a36Sopenharmony_ci 909462306a36Sopenharmony_ciTENOK1: 909562306a36Sopenharmony_ci cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ? 909662306a36Sopenharmony_ci ble.b TENMAIN 909762306a36Sopenharmony_ci bra.w EXPBORS 909862306a36Sopenharmony_ci 909962306a36Sopenharmony_ciTENMAIN: 910062306a36Sopenharmony_ci#--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10 910162306a36Sopenharmony_ci 910262306a36Sopenharmony_ci fmov.x %fp0,%fp1 910362306a36Sopenharmony_ci fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2 910462306a36Sopenharmony_ci fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2) 910562306a36Sopenharmony_ci mov.l %d2,-(%sp) 910662306a36Sopenharmony_ci lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 910762306a36Sopenharmony_ci fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 910862306a36Sopenharmony_ci mov.l INT(%a6),%d1 910962306a36Sopenharmony_ci mov.l %d1,%d2 911062306a36Sopenharmony_ci and.l &0x3F,%d1 # D0 IS J 911162306a36Sopenharmony_ci asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 911262306a36Sopenharmony_ci add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 911362306a36Sopenharmony_ci asr.l &6,%d2 # d2 IS L, N = 64L + J 911462306a36Sopenharmony_ci mov.l %d2,%d1 911562306a36Sopenharmony_ci asr.l &1,%d1 # D0 IS M 911662306a36Sopenharmony_ci sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 911762306a36Sopenharmony_ci add.l &0x3FFF,%d2 911862306a36Sopenharmony_ci 911962306a36Sopenharmony_ci#--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 912062306a36Sopenharmony_ci#--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 912162306a36Sopenharmony_ci#--ADJFACT = 2^(M'). 912262306a36Sopenharmony_ci#--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 912362306a36Sopenharmony_ci fmovm.x &0x0c,-(%sp) # save fp2/fp3 912462306a36Sopenharmony_ci 912562306a36Sopenharmony_ci fmov.x %fp1,%fp2 912662306a36Sopenharmony_ci 912762306a36Sopenharmony_ci fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD 912862306a36Sopenharmony_ci mov.l (%a1)+,FACT1(%a6) 912962306a36Sopenharmony_ci 913062306a36Sopenharmony_ci fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL 913162306a36Sopenharmony_ci 913262306a36Sopenharmony_ci mov.l (%a1)+,FACT1HI(%a6) 913362306a36Sopenharmony_ci mov.l (%a1)+,FACT1LOW(%a6) 913462306a36Sopenharmony_ci fsub.x %fp1,%fp0 # X - N L_LEAD 913562306a36Sopenharmony_ci mov.w (%a1)+,FACT2(%a6) 913662306a36Sopenharmony_ci 913762306a36Sopenharmony_ci fsub.x %fp2,%fp0 # X - N L_TRAIL 913862306a36Sopenharmony_ci 913962306a36Sopenharmony_ci mov.w (%a1)+,FACT2HI(%a6) 914062306a36Sopenharmony_ci clr.w FACT2HI+2(%a6) 914162306a36Sopenharmony_ci clr.l FACT2LOW(%a6) 914262306a36Sopenharmony_ci 914362306a36Sopenharmony_ci fmul.x LOG10(%pc),%fp0 # FP0 IS R 914462306a36Sopenharmony_ci add.w %d1,FACT1(%a6) 914562306a36Sopenharmony_ci add.w %d1,FACT2(%a6) 914662306a36Sopenharmony_ci 914762306a36Sopenharmony_ciexpr: 914862306a36Sopenharmony_ci#--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN. 914962306a36Sopenharmony_ci#--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64). 915062306a36Sopenharmony_ci#--FP0 IS R. THE FOLLOWING CODE COMPUTES 915162306a36Sopenharmony_ci#-- 2**(M'+M) * 2**(J/64) * EXP(R) 915262306a36Sopenharmony_ci 915362306a36Sopenharmony_ci fmov.x %fp0,%fp1 915462306a36Sopenharmony_ci fmul.x %fp1,%fp1 # FP1 IS S = R*R 915562306a36Sopenharmony_ci 915662306a36Sopenharmony_ci fmov.d EXPA5(%pc),%fp2 # FP2 IS A5 915762306a36Sopenharmony_ci fmov.d EXPA4(%pc),%fp3 # FP3 IS A4 915862306a36Sopenharmony_ci 915962306a36Sopenharmony_ci fmul.x %fp1,%fp2 # FP2 IS S*A5 916062306a36Sopenharmony_ci fmul.x %fp1,%fp3 # FP3 IS S*A4 916162306a36Sopenharmony_ci 916262306a36Sopenharmony_ci fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5 916362306a36Sopenharmony_ci fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4 916462306a36Sopenharmony_ci 916562306a36Sopenharmony_ci fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5) 916662306a36Sopenharmony_ci fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4) 916762306a36Sopenharmony_ci 916862306a36Sopenharmony_ci fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5) 916962306a36Sopenharmony_ci fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4) 917062306a36Sopenharmony_ci 917162306a36Sopenharmony_ci fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5)) 917262306a36Sopenharmony_ci fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4) 917362306a36Sopenharmony_ci fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1 917462306a36Sopenharmony_ci 917562306a36Sopenharmony_ci fmovm.x (%sp)+,&0x30 # restore fp2/fp3 917662306a36Sopenharmony_ci 917762306a36Sopenharmony_ci#--FINAL RECONSTRUCTION PROCESS 917862306a36Sopenharmony_ci#--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1) - (1 OR 0) 917962306a36Sopenharmony_ci 918062306a36Sopenharmony_ci fmul.x FACT1(%a6),%fp0 918162306a36Sopenharmony_ci fadd.x FACT2(%a6),%fp0 918262306a36Sopenharmony_ci fadd.x FACT1(%a6),%fp0 918362306a36Sopenharmony_ci 918462306a36Sopenharmony_ci fmov.l %d0,%fpcr # restore users round prec,mode 918562306a36Sopenharmony_ci mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT 918662306a36Sopenharmony_ci mov.l (%sp)+,%d2 918762306a36Sopenharmony_ci mov.l &0x80000000,ADJFACT+4(%a6) 918862306a36Sopenharmony_ci clr.l ADJFACT+8(%a6) 918962306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 919062306a36Sopenharmony_ci fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT 919162306a36Sopenharmony_ci bra t_catch 919262306a36Sopenharmony_ci 919362306a36Sopenharmony_ci global stentoxd 919462306a36Sopenharmony_cistentoxd: 919562306a36Sopenharmony_ci#--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT 919662306a36Sopenharmony_ci 919762306a36Sopenharmony_ci fmov.l %d0,%fpcr # set user's rounding mode/precision 919862306a36Sopenharmony_ci fmov.s &0x3F800000,%fp0 # RETURN 1 + X 919962306a36Sopenharmony_ci mov.l (%a0),%d1 920062306a36Sopenharmony_ci or.l &0x00800001,%d1 920162306a36Sopenharmony_ci fadd.s %d1,%fp0 920262306a36Sopenharmony_ci bra t_pinx2 920362306a36Sopenharmony_ci 920462306a36Sopenharmony_ci######################################################################### 920562306a36Sopenharmony_ci# sscale(): computes the destination operand scaled by the source # 920662306a36Sopenharmony_ci# operand. If the absoulute value of the source operand is # 920762306a36Sopenharmony_ci# >= 2^14, an overflow or underflow is returned. # 920862306a36Sopenharmony_ci# # 920962306a36Sopenharmony_ci# INPUT *************************************************************** # 921062306a36Sopenharmony_ci# a0 = pointer to double-extended source operand X # 921162306a36Sopenharmony_ci# a1 = pointer to double-extended destination operand Y # 921262306a36Sopenharmony_ci# # 921362306a36Sopenharmony_ci# OUTPUT ************************************************************** # 921462306a36Sopenharmony_ci# fp0 = scale(X,Y) # 921562306a36Sopenharmony_ci# # 921662306a36Sopenharmony_ci######################################################################### 921762306a36Sopenharmony_ci 921862306a36Sopenharmony_ciset SIGN, L_SCR1 921962306a36Sopenharmony_ci 922062306a36Sopenharmony_ci global sscale 922162306a36Sopenharmony_cisscale: 922262306a36Sopenharmony_ci mov.l %d0,-(%sp) # store off ctrl bits for now 922362306a36Sopenharmony_ci 922462306a36Sopenharmony_ci mov.w DST_EX(%a1),%d1 # get dst exponent 922562306a36Sopenharmony_ci smi.b SIGN(%a6) # use SIGN to hold dst sign 922662306a36Sopenharmony_ci andi.l &0x00007fff,%d1 # strip sign from dst exp 922762306a36Sopenharmony_ci 922862306a36Sopenharmony_ci mov.w SRC_EX(%a0),%d0 # check src bounds 922962306a36Sopenharmony_ci andi.w &0x7fff,%d0 # clr src sign bit 923062306a36Sopenharmony_ci cmpi.w %d0,&0x3fff # is src ~ ZERO? 923162306a36Sopenharmony_ci blt.w src_small # yes 923262306a36Sopenharmony_ci cmpi.w %d0,&0x400c # no; is src too big? 923362306a36Sopenharmony_ci bgt.w src_out # yes 923462306a36Sopenharmony_ci 923562306a36Sopenharmony_ci# 923662306a36Sopenharmony_ci# Source is within 2^14 range. 923762306a36Sopenharmony_ci# 923862306a36Sopenharmony_cisrc_ok: 923962306a36Sopenharmony_ci fintrz.x SRC(%a0),%fp0 # calc int of src 924062306a36Sopenharmony_ci fmov.l %fp0,%d0 # int src to d0 924162306a36Sopenharmony_ci# don't want any accrued bits from the fintrz showing up later since 924262306a36Sopenharmony_ci# we may need to read the fpsr for the last fp op in t_catch2(). 924362306a36Sopenharmony_ci fmov.l &0x0,%fpsr 924462306a36Sopenharmony_ci 924562306a36Sopenharmony_ci tst.b DST_HI(%a1) # is dst denormalized? 924662306a36Sopenharmony_ci bmi.b sok_norm 924762306a36Sopenharmony_ci 924862306a36Sopenharmony_ci# the dst is a DENORM. normalize the DENORM and add the adjustment to 924962306a36Sopenharmony_ci# the src value. then, jump to the norm part of the routine. 925062306a36Sopenharmony_cisok_dnrm: 925162306a36Sopenharmony_ci mov.l %d0,-(%sp) # save src for now 925262306a36Sopenharmony_ci 925362306a36Sopenharmony_ci mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy 925462306a36Sopenharmony_ci mov.l DST_HI(%a1),FP_SCR0_HI(%a6) 925562306a36Sopenharmony_ci mov.l DST_LO(%a1),FP_SCR0_LO(%a6) 925662306a36Sopenharmony_ci 925762306a36Sopenharmony_ci lea FP_SCR0(%a6),%a0 # pass ptr to DENORM 925862306a36Sopenharmony_ci bsr.l norm # normalize the DENORM 925962306a36Sopenharmony_ci neg.l %d0 926062306a36Sopenharmony_ci add.l (%sp)+,%d0 # add adjustment to src 926162306a36Sopenharmony_ci 926262306a36Sopenharmony_ci fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM 926362306a36Sopenharmony_ci 926462306a36Sopenharmony_ci cmpi.w %d0,&-0x3fff # is the shft amt really low? 926562306a36Sopenharmony_ci bge.b sok_norm2 # thank goodness no 926662306a36Sopenharmony_ci 926762306a36Sopenharmony_ci# the multiply factor that we're trying to create should be a denorm 926862306a36Sopenharmony_ci# for the multiply to work. therefore, we're going to actually do a 926962306a36Sopenharmony_ci# multiply with a denorm which will cause an unimplemented data type 927062306a36Sopenharmony_ci# exception to be put into the machine which will be caught and corrected 927162306a36Sopenharmony_ci# later. we don't do this with the DENORMs above because this method 927262306a36Sopenharmony_ci# is slower. but, don't fret, I don't see it being used much either. 927362306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore user fpcr 927462306a36Sopenharmony_ci mov.l &0x80000000,%d1 # load normalized mantissa 927562306a36Sopenharmony_ci subi.l &-0x3fff,%d0 # how many should we shift? 927662306a36Sopenharmony_ci neg.l %d0 # make it positive 927762306a36Sopenharmony_ci cmpi.b %d0,&0x20 # is it > 32? 927862306a36Sopenharmony_ci bge.b sok_dnrm_32 # yes 927962306a36Sopenharmony_ci lsr.l %d0,%d1 # no; bit stays in upper lw 928062306a36Sopenharmony_ci clr.l -(%sp) # insert zero low mantissa 928162306a36Sopenharmony_ci mov.l %d1,-(%sp) # insert new high mantissa 928262306a36Sopenharmony_ci clr.l -(%sp) # make zero exponent 928362306a36Sopenharmony_ci bra.b sok_norm_cont 928462306a36Sopenharmony_cisok_dnrm_32: 928562306a36Sopenharmony_ci subi.b &0x20,%d0 # get shift count 928662306a36Sopenharmony_ci lsr.l %d0,%d1 # make low mantissa longword 928762306a36Sopenharmony_ci mov.l %d1,-(%sp) # insert new low mantissa 928862306a36Sopenharmony_ci clr.l -(%sp) # insert zero high mantissa 928962306a36Sopenharmony_ci clr.l -(%sp) # make zero exponent 929062306a36Sopenharmony_ci bra.b sok_norm_cont 929162306a36Sopenharmony_ci 929262306a36Sopenharmony_ci# the src will force the dst to a DENORM value or worse. so, let's 929362306a36Sopenharmony_ci# create an fp multiply that will create the result. 929462306a36Sopenharmony_cisok_norm: 929562306a36Sopenharmony_ci fmovm.x DST(%a1),&0x80 # load fp0 with normalized src 929662306a36Sopenharmony_cisok_norm2: 929762306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore user fpcr 929862306a36Sopenharmony_ci 929962306a36Sopenharmony_ci addi.w &0x3fff,%d0 # turn src amt into exp value 930062306a36Sopenharmony_ci swap %d0 # put exponent in high word 930162306a36Sopenharmony_ci clr.l -(%sp) # insert new exponent 930262306a36Sopenharmony_ci mov.l &0x80000000,-(%sp) # insert new high mantissa 930362306a36Sopenharmony_ci mov.l %d0,-(%sp) # insert new lo mantissa 930462306a36Sopenharmony_ci 930562306a36Sopenharmony_cisok_norm_cont: 930662306a36Sopenharmony_ci fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2 930762306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 930862306a36Sopenharmony_ci fmul.x (%sp)+,%fp0 # do the multiply 930962306a36Sopenharmony_ci bra t_catch2 # catch any exceptions 931062306a36Sopenharmony_ci 931162306a36Sopenharmony_ci# 931262306a36Sopenharmony_ci# Source is outside of 2^14 range. Test the sign and branch 931362306a36Sopenharmony_ci# to the appropriate exception handler. 931462306a36Sopenharmony_ci# 931562306a36Sopenharmony_cisrc_out: 931662306a36Sopenharmony_ci mov.l (%sp)+,%d0 # restore ctrl bits 931762306a36Sopenharmony_ci exg %a0,%a1 # swap src,dst ptrs 931862306a36Sopenharmony_ci tst.b SRC_EX(%a1) # is src negative? 931962306a36Sopenharmony_ci bmi t_unfl # yes; underflow 932062306a36Sopenharmony_ci bra t_ovfl_sc # no; overflow 932162306a36Sopenharmony_ci 932262306a36Sopenharmony_ci# 932362306a36Sopenharmony_ci# The source input is below 1, so we check for denormalized numbers 932462306a36Sopenharmony_ci# and set unfl. 932562306a36Sopenharmony_ci# 932662306a36Sopenharmony_cisrc_small: 932762306a36Sopenharmony_ci tst.b DST_HI(%a1) # is dst denormalized? 932862306a36Sopenharmony_ci bpl.b ssmall_done # yes 932962306a36Sopenharmony_ci 933062306a36Sopenharmony_ci mov.l (%sp)+,%d0 933162306a36Sopenharmony_ci fmov.l %d0,%fpcr # no; load control bits 933262306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 933362306a36Sopenharmony_ci fmov.x DST(%a1),%fp0 # simply return dest 933462306a36Sopenharmony_ci bra t_catch2 933562306a36Sopenharmony_cissmall_done: 933662306a36Sopenharmony_ci mov.l (%sp)+,%d0 # load control bits into d1 933762306a36Sopenharmony_ci mov.l %a1,%a0 # pass ptr to dst 933862306a36Sopenharmony_ci bra t_resdnrm 933962306a36Sopenharmony_ci 934062306a36Sopenharmony_ci######################################################################### 934162306a36Sopenharmony_ci# smod(): computes the fp MOD of the input values X,Y. # 934262306a36Sopenharmony_ci# srem(): computes the fp (IEEE) REM of the input values X,Y. # 934362306a36Sopenharmony_ci# # 934462306a36Sopenharmony_ci# INPUT *************************************************************** # 934562306a36Sopenharmony_ci# a0 = pointer to extended precision input X # 934662306a36Sopenharmony_ci# a1 = pointer to extended precision input Y # 934762306a36Sopenharmony_ci# d0 = round precision,mode # 934862306a36Sopenharmony_ci# # 934962306a36Sopenharmony_ci# The input operands X and Y can be either normalized or # 935062306a36Sopenharmony_ci# denormalized. # 935162306a36Sopenharmony_ci# # 935262306a36Sopenharmony_ci# OUTPUT ************************************************************** # 935362306a36Sopenharmony_ci# fp0 = FREM(X,Y) or FMOD(X,Y) # 935462306a36Sopenharmony_ci# # 935562306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 935662306a36Sopenharmony_ci# # 935762306a36Sopenharmony_ci# Step 1. Save and strip signs of X and Y: signX := sign(X), # 935862306a36Sopenharmony_ci# signY := sign(Y), X := |X|, Y := |Y|, # 935962306a36Sopenharmony_ci# signQ := signX EOR signY. Record whether MOD or REM # 936062306a36Sopenharmony_ci# is requested. # 936162306a36Sopenharmony_ci# # 936262306a36Sopenharmony_ci# Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. # 936362306a36Sopenharmony_ci# If (L < 0) then # 936462306a36Sopenharmony_ci# R := X, go to Step 4. # 936562306a36Sopenharmony_ci# else # 936662306a36Sopenharmony_ci# R := 2^(-L)X, j := L. # 936762306a36Sopenharmony_ci# endif # 936862306a36Sopenharmony_ci# # 936962306a36Sopenharmony_ci# Step 3. Perform MOD(X,Y) # 937062306a36Sopenharmony_ci# 3.1 If R = Y, go to Step 9. # 937162306a36Sopenharmony_ci# 3.2 If R > Y, then { R := R - Y, Q := Q + 1} # 937262306a36Sopenharmony_ci# 3.3 If j = 0, go to Step 4. # 937362306a36Sopenharmony_ci# 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to # 937462306a36Sopenharmony_ci# Step 3.1. # 937562306a36Sopenharmony_ci# # 937662306a36Sopenharmony_ci# Step 4. At this point, R = X - QY = MOD(X,Y). Set # 937762306a36Sopenharmony_ci# Last_Subtract := false (used in Step 7 below). If # 937862306a36Sopenharmony_ci# MOD is requested, go to Step 6. # 937962306a36Sopenharmony_ci# # 938062306a36Sopenharmony_ci# Step 5. R = MOD(X,Y), but REM(X,Y) is requested. # 938162306a36Sopenharmony_ci# 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to # 938262306a36Sopenharmony_ci# Step 6. # 938362306a36Sopenharmony_ci# 5.2 If R > Y/2, then { set Last_Subtract := true, # 938462306a36Sopenharmony_ci# Q := Q + 1, Y := signY*Y }. Go to Step 6. # 938562306a36Sopenharmony_ci# 5.3 This is the tricky case of R = Y/2. If Q is odd, # 938662306a36Sopenharmony_ci# then { Q := Q + 1, signX := -signX }. # 938762306a36Sopenharmony_ci# # 938862306a36Sopenharmony_ci# Step 6. R := signX*R. # 938962306a36Sopenharmony_ci# # 939062306a36Sopenharmony_ci# Step 7. If Last_Subtract = true, R := R - Y. # 939162306a36Sopenharmony_ci# # 939262306a36Sopenharmony_ci# Step 8. Return signQ, last 7 bits of Q, and R as required. # 939362306a36Sopenharmony_ci# # 939462306a36Sopenharmony_ci# Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, # 939562306a36Sopenharmony_ci# X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), # 939662306a36Sopenharmony_ci# R := 0. Return signQ, last 7 bits of Q, and R. # 939762306a36Sopenharmony_ci# # 939862306a36Sopenharmony_ci######################################################################### 939962306a36Sopenharmony_ci 940062306a36Sopenharmony_ci set Mod_Flag,L_SCR3 940162306a36Sopenharmony_ci set Sc_Flag,L_SCR3+1 940262306a36Sopenharmony_ci 940362306a36Sopenharmony_ci set SignY,L_SCR2 940462306a36Sopenharmony_ci set SignX,L_SCR2+2 940562306a36Sopenharmony_ci set SignQ,L_SCR3+2 940662306a36Sopenharmony_ci 940762306a36Sopenharmony_ci set Y,FP_SCR0 940862306a36Sopenharmony_ci set Y_Hi,Y+4 940962306a36Sopenharmony_ci set Y_Lo,Y+8 941062306a36Sopenharmony_ci 941162306a36Sopenharmony_ci set R,FP_SCR1 941262306a36Sopenharmony_ci set R_Hi,R+4 941362306a36Sopenharmony_ci set R_Lo,R+8 941462306a36Sopenharmony_ci 941562306a36Sopenharmony_ciScale: 941662306a36Sopenharmony_ci long 0x00010000,0x80000000,0x00000000,0x00000000 941762306a36Sopenharmony_ci 941862306a36Sopenharmony_ci global smod 941962306a36Sopenharmony_cismod: 942062306a36Sopenharmony_ci clr.b FPSR_QBYTE(%a6) 942162306a36Sopenharmony_ci mov.l %d0,-(%sp) # save ctrl bits 942262306a36Sopenharmony_ci clr.b Mod_Flag(%a6) 942362306a36Sopenharmony_ci bra.b Mod_Rem 942462306a36Sopenharmony_ci 942562306a36Sopenharmony_ci global srem 942662306a36Sopenharmony_cisrem: 942762306a36Sopenharmony_ci clr.b FPSR_QBYTE(%a6) 942862306a36Sopenharmony_ci mov.l %d0,-(%sp) # save ctrl bits 942962306a36Sopenharmony_ci mov.b &0x1,Mod_Flag(%a6) 943062306a36Sopenharmony_ci 943162306a36Sopenharmony_ciMod_Rem: 943262306a36Sopenharmony_ci#..Save sign of X and Y 943362306a36Sopenharmony_ci movm.l &0x3f00,-(%sp) # save data registers 943462306a36Sopenharmony_ci mov.w SRC_EX(%a0),%d3 943562306a36Sopenharmony_ci mov.w %d3,SignY(%a6) 943662306a36Sopenharmony_ci and.l &0x00007FFF,%d3 # Y := |Y| 943762306a36Sopenharmony_ci 943862306a36Sopenharmony_ci# 943962306a36Sopenharmony_ci mov.l SRC_HI(%a0),%d4 944062306a36Sopenharmony_ci mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y| 944162306a36Sopenharmony_ci 944262306a36Sopenharmony_ci tst.l %d3 944362306a36Sopenharmony_ci bne.b Y_Normal 944462306a36Sopenharmony_ci 944562306a36Sopenharmony_ci mov.l &0x00003FFE,%d3 # $3FFD + 1 944662306a36Sopenharmony_ci tst.l %d4 944762306a36Sopenharmony_ci bne.b HiY_not0 944862306a36Sopenharmony_ci 944962306a36Sopenharmony_ciHiY_0: 945062306a36Sopenharmony_ci mov.l %d5,%d4 945162306a36Sopenharmony_ci clr.l %d5 945262306a36Sopenharmony_ci sub.l &32,%d3 945362306a36Sopenharmony_ci clr.l %d6 945462306a36Sopenharmony_ci bfffo %d4{&0:&32},%d6 945562306a36Sopenharmony_ci lsl.l %d6,%d4 945662306a36Sopenharmony_ci sub.l %d6,%d3 # (D3,D4,D5) is normalized 945762306a36Sopenharmony_ci# ...with bias $7FFD 945862306a36Sopenharmony_ci bra.b Chk_X 945962306a36Sopenharmony_ci 946062306a36Sopenharmony_ciHiY_not0: 946162306a36Sopenharmony_ci clr.l %d6 946262306a36Sopenharmony_ci bfffo %d4{&0:&32},%d6 946362306a36Sopenharmony_ci sub.l %d6,%d3 946462306a36Sopenharmony_ci lsl.l %d6,%d4 946562306a36Sopenharmony_ci mov.l %d5,%d7 # a copy of D5 946662306a36Sopenharmony_ci lsl.l %d6,%d5 946762306a36Sopenharmony_ci neg.l %d6 946862306a36Sopenharmony_ci add.l &32,%d6 946962306a36Sopenharmony_ci lsr.l %d6,%d7 947062306a36Sopenharmony_ci or.l %d7,%d4 # (D3,D4,D5) normalized 947162306a36Sopenharmony_ci# ...with bias $7FFD 947262306a36Sopenharmony_ci bra.b Chk_X 947362306a36Sopenharmony_ci 947462306a36Sopenharmony_ciY_Normal: 947562306a36Sopenharmony_ci add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized 947662306a36Sopenharmony_ci# ...with bias $7FFD 947762306a36Sopenharmony_ci 947862306a36Sopenharmony_ciChk_X: 947962306a36Sopenharmony_ci mov.w DST_EX(%a1),%d0 948062306a36Sopenharmony_ci mov.w %d0,SignX(%a6) 948162306a36Sopenharmony_ci mov.w SignY(%a6),%d1 948262306a36Sopenharmony_ci eor.l %d0,%d1 948362306a36Sopenharmony_ci and.l &0x00008000,%d1 948462306a36Sopenharmony_ci mov.w %d1,SignQ(%a6) # sign(Q) obtained 948562306a36Sopenharmony_ci and.l &0x00007FFF,%d0 948662306a36Sopenharmony_ci mov.l DST_HI(%a1),%d1 948762306a36Sopenharmony_ci mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X| 948862306a36Sopenharmony_ci tst.l %d0 948962306a36Sopenharmony_ci bne.b X_Normal 949062306a36Sopenharmony_ci mov.l &0x00003FFE,%d0 949162306a36Sopenharmony_ci tst.l %d1 949262306a36Sopenharmony_ci bne.b HiX_not0 949362306a36Sopenharmony_ci 949462306a36Sopenharmony_ciHiX_0: 949562306a36Sopenharmony_ci mov.l %d2,%d1 949662306a36Sopenharmony_ci clr.l %d2 949762306a36Sopenharmony_ci sub.l &32,%d0 949862306a36Sopenharmony_ci clr.l %d6 949962306a36Sopenharmony_ci bfffo %d1{&0:&32},%d6 950062306a36Sopenharmony_ci lsl.l %d6,%d1 950162306a36Sopenharmony_ci sub.l %d6,%d0 # (D0,D1,D2) is normalized 950262306a36Sopenharmony_ci# ...with bias $7FFD 950362306a36Sopenharmony_ci bra.b Init 950462306a36Sopenharmony_ci 950562306a36Sopenharmony_ciHiX_not0: 950662306a36Sopenharmony_ci clr.l %d6 950762306a36Sopenharmony_ci bfffo %d1{&0:&32},%d6 950862306a36Sopenharmony_ci sub.l %d6,%d0 950962306a36Sopenharmony_ci lsl.l %d6,%d1 951062306a36Sopenharmony_ci mov.l %d2,%d7 # a copy of D2 951162306a36Sopenharmony_ci lsl.l %d6,%d2 951262306a36Sopenharmony_ci neg.l %d6 951362306a36Sopenharmony_ci add.l &32,%d6 951462306a36Sopenharmony_ci lsr.l %d6,%d7 951562306a36Sopenharmony_ci or.l %d7,%d1 # (D0,D1,D2) normalized 951662306a36Sopenharmony_ci# ...with bias $7FFD 951762306a36Sopenharmony_ci bra.b Init 951862306a36Sopenharmony_ci 951962306a36Sopenharmony_ciX_Normal: 952062306a36Sopenharmony_ci add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized 952162306a36Sopenharmony_ci# ...with bias $7FFD 952262306a36Sopenharmony_ci 952362306a36Sopenharmony_ciInit: 952462306a36Sopenharmony_ci# 952562306a36Sopenharmony_ci mov.l %d3,L_SCR1(%a6) # save biased exp(Y) 952662306a36Sopenharmony_ci mov.l %d0,-(%sp) # save biased exp(X) 952762306a36Sopenharmony_ci sub.l %d3,%d0 # L := expo(X)-expo(Y) 952862306a36Sopenharmony_ci 952962306a36Sopenharmony_ci clr.l %d6 # D6 := carry <- 0 953062306a36Sopenharmony_ci clr.l %d3 # D3 is Q 953162306a36Sopenharmony_ci mov.l &0,%a1 # A1 is k; j+k=L, Q=0 953262306a36Sopenharmony_ci 953362306a36Sopenharmony_ci#..(Carry,D1,D2) is R 953462306a36Sopenharmony_ci tst.l %d0 953562306a36Sopenharmony_ci bge.b Mod_Loop_pre 953662306a36Sopenharmony_ci 953762306a36Sopenharmony_ci#..expo(X) < expo(Y). Thus X = mod(X,Y) 953862306a36Sopenharmony_ci# 953962306a36Sopenharmony_ci mov.l (%sp)+,%d0 # restore d0 954062306a36Sopenharmony_ci bra.w Get_Mod 954162306a36Sopenharmony_ci 954262306a36Sopenharmony_ciMod_Loop_pre: 954362306a36Sopenharmony_ci addq.l &0x4,%sp # erase exp(X) 954462306a36Sopenharmony_ci#..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L 954562306a36Sopenharmony_ciMod_Loop: 954662306a36Sopenharmony_ci tst.l %d6 # test carry bit 954762306a36Sopenharmony_ci bgt.b R_GT_Y 954862306a36Sopenharmony_ci 954962306a36Sopenharmony_ci#..At this point carry = 0, R = (D1,D2), Y = (D4,D5) 955062306a36Sopenharmony_ci cmp.l %d1,%d4 # compare hi(R) and hi(Y) 955162306a36Sopenharmony_ci bne.b R_NE_Y 955262306a36Sopenharmony_ci cmp.l %d2,%d5 # compare lo(R) and lo(Y) 955362306a36Sopenharmony_ci bne.b R_NE_Y 955462306a36Sopenharmony_ci 955562306a36Sopenharmony_ci#..At this point, R = Y 955662306a36Sopenharmony_ci bra.w Rem_is_0 955762306a36Sopenharmony_ci 955862306a36Sopenharmony_ciR_NE_Y: 955962306a36Sopenharmony_ci#..use the borrow of the previous compare 956062306a36Sopenharmony_ci bcs.b R_LT_Y # borrow is set iff R < Y 956162306a36Sopenharmony_ci 956262306a36Sopenharmony_ciR_GT_Y: 956362306a36Sopenharmony_ci#..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0 956462306a36Sopenharmony_ci#..and Y < (D1,D2) < 2Y. Either way, perform R - Y 956562306a36Sopenharmony_ci sub.l %d5,%d2 # lo(R) - lo(Y) 956662306a36Sopenharmony_ci subx.l %d4,%d1 # hi(R) - hi(Y) 956762306a36Sopenharmony_ci clr.l %d6 # clear carry 956862306a36Sopenharmony_ci addq.l &1,%d3 # Q := Q + 1 956962306a36Sopenharmony_ci 957062306a36Sopenharmony_ciR_LT_Y: 957162306a36Sopenharmony_ci#..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0. 957262306a36Sopenharmony_ci tst.l %d0 # see if j = 0. 957362306a36Sopenharmony_ci beq.b PostLoop 957462306a36Sopenharmony_ci 957562306a36Sopenharmony_ci add.l %d3,%d3 # Q := 2Q 957662306a36Sopenharmony_ci add.l %d2,%d2 # lo(R) = 2lo(R) 957762306a36Sopenharmony_ci roxl.l &1,%d1 # hi(R) = 2hi(R) + carry 957862306a36Sopenharmony_ci scs %d6 # set Carry if 2(R) overflows 957962306a36Sopenharmony_ci addq.l &1,%a1 # k := k+1 958062306a36Sopenharmony_ci subq.l &1,%d0 # j := j - 1 958162306a36Sopenharmony_ci#..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y. 958262306a36Sopenharmony_ci 958362306a36Sopenharmony_ci bra.b Mod_Loop 958462306a36Sopenharmony_ci 958562306a36Sopenharmony_ciPostLoop: 958662306a36Sopenharmony_ci#..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y. 958762306a36Sopenharmony_ci 958862306a36Sopenharmony_ci#..normalize R. 958962306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d0 # new biased expo of R 959062306a36Sopenharmony_ci tst.l %d1 959162306a36Sopenharmony_ci bne.b HiR_not0 959262306a36Sopenharmony_ci 959362306a36Sopenharmony_ciHiR_0: 959462306a36Sopenharmony_ci mov.l %d2,%d1 959562306a36Sopenharmony_ci clr.l %d2 959662306a36Sopenharmony_ci sub.l &32,%d0 959762306a36Sopenharmony_ci clr.l %d6 959862306a36Sopenharmony_ci bfffo %d1{&0:&32},%d6 959962306a36Sopenharmony_ci lsl.l %d6,%d1 960062306a36Sopenharmony_ci sub.l %d6,%d0 # (D0,D1,D2) is normalized 960162306a36Sopenharmony_ci# ...with bias $7FFD 960262306a36Sopenharmony_ci bra.b Get_Mod 960362306a36Sopenharmony_ci 960462306a36Sopenharmony_ciHiR_not0: 960562306a36Sopenharmony_ci clr.l %d6 960662306a36Sopenharmony_ci bfffo %d1{&0:&32},%d6 960762306a36Sopenharmony_ci bmi.b Get_Mod # already normalized 960862306a36Sopenharmony_ci sub.l %d6,%d0 960962306a36Sopenharmony_ci lsl.l %d6,%d1 961062306a36Sopenharmony_ci mov.l %d2,%d7 # a copy of D2 961162306a36Sopenharmony_ci lsl.l %d6,%d2 961262306a36Sopenharmony_ci neg.l %d6 961362306a36Sopenharmony_ci add.l &32,%d6 961462306a36Sopenharmony_ci lsr.l %d6,%d7 961562306a36Sopenharmony_ci or.l %d7,%d1 # (D0,D1,D2) normalized 961662306a36Sopenharmony_ci 961762306a36Sopenharmony_ci# 961862306a36Sopenharmony_ciGet_Mod: 961962306a36Sopenharmony_ci cmp.l %d0,&0x000041FE 962062306a36Sopenharmony_ci bge.b No_Scale 962162306a36Sopenharmony_ciDo_Scale: 962262306a36Sopenharmony_ci mov.w %d0,R(%a6) 962362306a36Sopenharmony_ci mov.l %d1,R_Hi(%a6) 962462306a36Sopenharmony_ci mov.l %d2,R_Lo(%a6) 962562306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d6 962662306a36Sopenharmony_ci mov.w %d6,Y(%a6) 962762306a36Sopenharmony_ci mov.l %d4,Y_Hi(%a6) 962862306a36Sopenharmony_ci mov.l %d5,Y_Lo(%a6) 962962306a36Sopenharmony_ci fmov.x R(%a6),%fp0 # no exception 963062306a36Sopenharmony_ci mov.b &1,Sc_Flag(%a6) 963162306a36Sopenharmony_ci bra.b ModOrRem 963262306a36Sopenharmony_ciNo_Scale: 963362306a36Sopenharmony_ci mov.l %d1,R_Hi(%a6) 963462306a36Sopenharmony_ci mov.l %d2,R_Lo(%a6) 963562306a36Sopenharmony_ci sub.l &0x3FFE,%d0 963662306a36Sopenharmony_ci mov.w %d0,R(%a6) 963762306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d6 963862306a36Sopenharmony_ci sub.l &0x3FFE,%d6 963962306a36Sopenharmony_ci mov.l %d6,L_SCR1(%a6) 964062306a36Sopenharmony_ci fmov.x R(%a6),%fp0 964162306a36Sopenharmony_ci mov.w %d6,Y(%a6) 964262306a36Sopenharmony_ci mov.l %d4,Y_Hi(%a6) 964362306a36Sopenharmony_ci mov.l %d5,Y_Lo(%a6) 964462306a36Sopenharmony_ci clr.b Sc_Flag(%a6) 964562306a36Sopenharmony_ci 964662306a36Sopenharmony_ci# 964762306a36Sopenharmony_ciModOrRem: 964862306a36Sopenharmony_ci tst.b Mod_Flag(%a6) 964962306a36Sopenharmony_ci beq.b Fix_Sign 965062306a36Sopenharmony_ci 965162306a36Sopenharmony_ci mov.l L_SCR1(%a6),%d6 # new biased expo(Y) 965262306a36Sopenharmony_ci subq.l &1,%d6 # biased expo(Y/2) 965362306a36Sopenharmony_ci cmp.l %d0,%d6 965462306a36Sopenharmony_ci blt.b Fix_Sign 965562306a36Sopenharmony_ci bgt.b Last_Sub 965662306a36Sopenharmony_ci 965762306a36Sopenharmony_ci cmp.l %d1,%d4 965862306a36Sopenharmony_ci bne.b Not_EQ 965962306a36Sopenharmony_ci cmp.l %d2,%d5 966062306a36Sopenharmony_ci bne.b Not_EQ 966162306a36Sopenharmony_ci bra.w Tie_Case 966262306a36Sopenharmony_ci 966362306a36Sopenharmony_ciNot_EQ: 966462306a36Sopenharmony_ci bcs.b Fix_Sign 966562306a36Sopenharmony_ci 966662306a36Sopenharmony_ciLast_Sub: 966762306a36Sopenharmony_ci# 966862306a36Sopenharmony_ci fsub.x Y(%a6),%fp0 # no exceptions 966962306a36Sopenharmony_ci addq.l &1,%d3 # Q := Q + 1 967062306a36Sopenharmony_ci 967162306a36Sopenharmony_ci# 967262306a36Sopenharmony_ciFix_Sign: 967362306a36Sopenharmony_ci#..Get sign of X 967462306a36Sopenharmony_ci mov.w SignX(%a6),%d6 967562306a36Sopenharmony_ci bge.b Get_Q 967662306a36Sopenharmony_ci fneg.x %fp0 967762306a36Sopenharmony_ci 967862306a36Sopenharmony_ci#..Get Q 967962306a36Sopenharmony_ci# 968062306a36Sopenharmony_ciGet_Q: 968162306a36Sopenharmony_ci clr.l %d6 968262306a36Sopenharmony_ci mov.w SignQ(%a6),%d6 # D6 is sign(Q) 968362306a36Sopenharmony_ci mov.l &8,%d7 968462306a36Sopenharmony_ci lsr.l %d7,%d6 968562306a36Sopenharmony_ci and.l &0x0000007F,%d3 # 7 bits of Q 968662306a36Sopenharmony_ci or.l %d6,%d3 # sign and bits of Q 968762306a36Sopenharmony_ci# swap %d3 968862306a36Sopenharmony_ci# fmov.l %fpsr,%d6 968962306a36Sopenharmony_ci# and.l &0xFF00FFFF,%d6 969062306a36Sopenharmony_ci# or.l %d3,%d6 969162306a36Sopenharmony_ci# fmov.l %d6,%fpsr # put Q in fpsr 969262306a36Sopenharmony_ci mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr 969362306a36Sopenharmony_ci 969462306a36Sopenharmony_ci# 969562306a36Sopenharmony_ciRestore: 969662306a36Sopenharmony_ci movm.l (%sp)+,&0xfc # {%d2-%d7} 969762306a36Sopenharmony_ci mov.l (%sp)+,%d0 969862306a36Sopenharmony_ci fmov.l %d0,%fpcr 969962306a36Sopenharmony_ci tst.b Sc_Flag(%a6) 970062306a36Sopenharmony_ci beq.b Finish 970162306a36Sopenharmony_ci mov.b &FMUL_OP,%d1 # last inst is MUL 970262306a36Sopenharmony_ci fmul.x Scale(%pc),%fp0 # may cause underflow 970362306a36Sopenharmony_ci bra t_catch2 970462306a36Sopenharmony_ci# the '040 package did this apparently to see if the dst operand for the 970562306a36Sopenharmony_ci# preceding fmul was a denorm. but, it better not have been since the 970662306a36Sopenharmony_ci# algorithm just got done playing with fp0 and expected no exceptions 970762306a36Sopenharmony_ci# as a result. trust me... 970862306a36Sopenharmony_ci# bra t_avoid_unsupp # check for denorm as a 970962306a36Sopenharmony_ci# ;result of the scaling 971062306a36Sopenharmony_ci 971162306a36Sopenharmony_ciFinish: 971262306a36Sopenharmony_ci mov.b &FMOV_OP,%d1 # last inst is MOVE 971362306a36Sopenharmony_ci fmov.x %fp0,%fp0 # capture exceptions & round 971462306a36Sopenharmony_ci bra t_catch2 971562306a36Sopenharmony_ci 971662306a36Sopenharmony_ciRem_is_0: 971762306a36Sopenharmony_ci#..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1) 971862306a36Sopenharmony_ci addq.l &1,%d3 971962306a36Sopenharmony_ci cmp.l %d0,&8 # D0 is j 972062306a36Sopenharmony_ci bge.b Q_Big 972162306a36Sopenharmony_ci 972262306a36Sopenharmony_ci lsl.l %d0,%d3 972362306a36Sopenharmony_ci bra.b Set_R_0 972462306a36Sopenharmony_ci 972562306a36Sopenharmony_ciQ_Big: 972662306a36Sopenharmony_ci clr.l %d3 972762306a36Sopenharmony_ci 972862306a36Sopenharmony_ciSet_R_0: 972962306a36Sopenharmony_ci fmov.s &0x00000000,%fp0 973062306a36Sopenharmony_ci clr.b Sc_Flag(%a6) 973162306a36Sopenharmony_ci bra.w Fix_Sign 973262306a36Sopenharmony_ci 973362306a36Sopenharmony_ciTie_Case: 973462306a36Sopenharmony_ci#..Check parity of Q 973562306a36Sopenharmony_ci mov.l %d3,%d6 973662306a36Sopenharmony_ci and.l &0x00000001,%d6 973762306a36Sopenharmony_ci tst.l %d6 973862306a36Sopenharmony_ci beq.w Fix_Sign # Q is even 973962306a36Sopenharmony_ci 974062306a36Sopenharmony_ci#..Q is odd, Q := Q + 1, signX := -signX 974162306a36Sopenharmony_ci addq.l &1,%d3 974262306a36Sopenharmony_ci mov.w SignX(%a6),%d6 974362306a36Sopenharmony_ci eor.l &0x00008000,%d6 974462306a36Sopenharmony_ci mov.w %d6,SignX(%a6) 974562306a36Sopenharmony_ci bra.w Fix_Sign 974662306a36Sopenharmony_ci 974762306a36Sopenharmony_ci######################################################################### 974862306a36Sopenharmony_ci# XDEF **************************************************************** # 974962306a36Sopenharmony_ci# tag(): return the optype of the input ext fp number # 975062306a36Sopenharmony_ci# # 975162306a36Sopenharmony_ci# This routine is used by the 060FPLSP. # 975262306a36Sopenharmony_ci# # 975362306a36Sopenharmony_ci# XREF **************************************************************** # 975462306a36Sopenharmony_ci# None # 975562306a36Sopenharmony_ci# # 975662306a36Sopenharmony_ci# INPUT *************************************************************** # 975762306a36Sopenharmony_ci# a0 = pointer to extended precision operand # 975862306a36Sopenharmony_ci# # 975962306a36Sopenharmony_ci# OUTPUT ************************************************************** # 976062306a36Sopenharmony_ci# d0 = value of type tag # 976162306a36Sopenharmony_ci# one of: NORM, INF, QNAN, SNAN, DENORM, ZERO # 976262306a36Sopenharmony_ci# # 976362306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 976462306a36Sopenharmony_ci# Simply test the exponent, j-bit, and mantissa values to # 976562306a36Sopenharmony_ci# determine the type of operand. # 976662306a36Sopenharmony_ci# If it's an unnormalized zero, alter the operand and force it # 976762306a36Sopenharmony_ci# to be a normal zero. # 976862306a36Sopenharmony_ci# # 976962306a36Sopenharmony_ci######################################################################### 977062306a36Sopenharmony_ci 977162306a36Sopenharmony_ci global tag 977262306a36Sopenharmony_citag: 977362306a36Sopenharmony_ci mov.w FTEMP_EX(%a0), %d0 # extract exponent 977462306a36Sopenharmony_ci andi.w &0x7fff, %d0 # strip off sign 977562306a36Sopenharmony_ci cmpi.w %d0, &0x7fff # is (EXP == MAX)? 977662306a36Sopenharmony_ci beq.b inf_or_nan_x 977762306a36Sopenharmony_cinot_inf_or_nan_x: 977862306a36Sopenharmony_ci btst &0x7,FTEMP_HI(%a0) 977962306a36Sopenharmony_ci beq.b not_norm_x 978062306a36Sopenharmony_ciis_norm_x: 978162306a36Sopenharmony_ci mov.b &NORM, %d0 978262306a36Sopenharmony_ci rts 978362306a36Sopenharmony_cinot_norm_x: 978462306a36Sopenharmony_ci tst.w %d0 # is exponent = 0? 978562306a36Sopenharmony_ci bne.b is_unnorm_x 978662306a36Sopenharmony_cinot_unnorm_x: 978762306a36Sopenharmony_ci tst.l FTEMP_HI(%a0) 978862306a36Sopenharmony_ci bne.b is_denorm_x 978962306a36Sopenharmony_ci tst.l FTEMP_LO(%a0) 979062306a36Sopenharmony_ci bne.b is_denorm_x 979162306a36Sopenharmony_ciis_zero_x: 979262306a36Sopenharmony_ci mov.b &ZERO, %d0 979362306a36Sopenharmony_ci rts 979462306a36Sopenharmony_ciis_denorm_x: 979562306a36Sopenharmony_ci mov.b &DENORM, %d0 979662306a36Sopenharmony_ci rts 979762306a36Sopenharmony_ciis_unnorm_x: 979862306a36Sopenharmony_ci bsr.l unnorm_fix # convert to norm,denorm,or zero 979962306a36Sopenharmony_ci rts 980062306a36Sopenharmony_ciis_unnorm_reg_x: 980162306a36Sopenharmony_ci mov.b &UNNORM, %d0 980262306a36Sopenharmony_ci rts 980362306a36Sopenharmony_ciinf_or_nan_x: 980462306a36Sopenharmony_ci tst.l FTEMP_LO(%a0) 980562306a36Sopenharmony_ci bne.b is_nan_x 980662306a36Sopenharmony_ci mov.l FTEMP_HI(%a0), %d0 980762306a36Sopenharmony_ci and.l &0x7fffffff, %d0 # msb is a don't care! 980862306a36Sopenharmony_ci bne.b is_nan_x 980962306a36Sopenharmony_ciis_inf_x: 981062306a36Sopenharmony_ci mov.b &INF, %d0 981162306a36Sopenharmony_ci rts 981262306a36Sopenharmony_ciis_nan_x: 981362306a36Sopenharmony_ci mov.b &QNAN, %d0 981462306a36Sopenharmony_ci rts 981562306a36Sopenharmony_ci 981662306a36Sopenharmony_ci############################################################# 981762306a36Sopenharmony_ci 981862306a36Sopenharmony_ciqnan: long 0x7fff0000, 0xffffffff, 0xffffffff 981962306a36Sopenharmony_ci 982062306a36Sopenharmony_ci######################################################################### 982162306a36Sopenharmony_ci# XDEF **************************************************************** # 982262306a36Sopenharmony_ci# t_dz(): Handle 060FPLSP dz exception for "flogn" emulation. # 982362306a36Sopenharmony_ci# t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation. # 982462306a36Sopenharmony_ci# # 982562306a36Sopenharmony_ci# These rouitnes are used by the 060FPLSP package. # 982662306a36Sopenharmony_ci# # 982762306a36Sopenharmony_ci# XREF **************************************************************** # 982862306a36Sopenharmony_ci# None # 982962306a36Sopenharmony_ci# # 983062306a36Sopenharmony_ci# INPUT *************************************************************** # 983162306a36Sopenharmony_ci# a0 = pointer to extended precision source operand. # 983262306a36Sopenharmony_ci# # 983362306a36Sopenharmony_ci# OUTPUT ************************************************************** # 983462306a36Sopenharmony_ci# fp0 = default DZ result. # 983562306a36Sopenharmony_ci# # 983662306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 983762306a36Sopenharmony_ci# Transcendental emulation for the 060FPLSP has detected that # 983862306a36Sopenharmony_ci# a DZ exception should occur for the instruction. If DZ is disabled, # 983962306a36Sopenharmony_ci# return the default result. # 984062306a36Sopenharmony_ci# If DZ is enabled, the dst operand should be returned unscathed # 984162306a36Sopenharmony_ci# in fp0 while fp1 is used to create a DZ exception so that the # 984262306a36Sopenharmony_ci# operating system can log that such an event occurred. # 984362306a36Sopenharmony_ci# # 984462306a36Sopenharmony_ci######################################################################### 984562306a36Sopenharmony_ci 984662306a36Sopenharmony_ci global t_dz 984762306a36Sopenharmony_cit_dz: 984862306a36Sopenharmony_ci tst.b SRC_EX(%a0) # check sign for neg or pos 984962306a36Sopenharmony_ci bpl.b dz_pinf # branch if pos sign 985062306a36Sopenharmony_ci 985162306a36Sopenharmony_ci global t_dz2 985262306a36Sopenharmony_cit_dz2: 985362306a36Sopenharmony_ci ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ 985462306a36Sopenharmony_ci 985562306a36Sopenharmony_ci btst &dz_bit,FPCR_ENABLE(%a6) 985662306a36Sopenharmony_ci bne.b dz_minf_ena 985762306a36Sopenharmony_ci 985862306a36Sopenharmony_ci# dz is disabled. return a -INF. 985962306a36Sopenharmony_ci fmov.s &0xff800000,%fp0 # return -INF 986062306a36Sopenharmony_ci rts 986162306a36Sopenharmony_ci 986262306a36Sopenharmony_ci# dz is enabled. create a dz exception so the user can record it 986362306a36Sopenharmony_ci# but use fp1 instead. return the dst operand unscathed in fp0. 986462306a36Sopenharmony_cidz_minf_ena: 986562306a36Sopenharmony_ci fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 986662306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 986762306a36Sopenharmony_ci fmov.s &0xbf800000,%fp1 # load -1 986862306a36Sopenharmony_ci fdiv.s &0x00000000,%fp1 # -1 / 0 986962306a36Sopenharmony_ci rts 987062306a36Sopenharmony_ci 987162306a36Sopenharmony_cidz_pinf: 987262306a36Sopenharmony_ci ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ 987362306a36Sopenharmony_ci 987462306a36Sopenharmony_ci btst &dz_bit,FPCR_ENABLE(%a6) 987562306a36Sopenharmony_ci bne.b dz_pinf_ena 987662306a36Sopenharmony_ci 987762306a36Sopenharmony_ci# dz is disabled. return a +INF. 987862306a36Sopenharmony_ci fmov.s &0x7f800000,%fp0 # return +INF 987962306a36Sopenharmony_ci rts 988062306a36Sopenharmony_ci 988162306a36Sopenharmony_ci# dz is enabled. create a dz exception so the user can record it 988262306a36Sopenharmony_ci# but use fp1 instead. return the dst operand unscathed in fp0. 988362306a36Sopenharmony_cidz_pinf_ena: 988462306a36Sopenharmony_ci fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 988562306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 988662306a36Sopenharmony_ci fmov.s &0x3f800000,%fp1 # load +1 988762306a36Sopenharmony_ci fdiv.s &0x00000000,%fp1 # +1 / 0 988862306a36Sopenharmony_ci rts 988962306a36Sopenharmony_ci 989062306a36Sopenharmony_ci######################################################################### 989162306a36Sopenharmony_ci# XDEF **************************************************************** # 989262306a36Sopenharmony_ci# t_operr(): Handle 060FPLSP OPERR exception during emulation. # 989362306a36Sopenharmony_ci# # 989462306a36Sopenharmony_ci# This routine is used by the 060FPLSP package. # 989562306a36Sopenharmony_ci# # 989662306a36Sopenharmony_ci# XREF **************************************************************** # 989762306a36Sopenharmony_ci# None. # 989862306a36Sopenharmony_ci# # 989962306a36Sopenharmony_ci# INPUT *************************************************************** # 990062306a36Sopenharmony_ci# fp1 = source operand # 990162306a36Sopenharmony_ci# # 990262306a36Sopenharmony_ci# OUTPUT ************************************************************** # 990362306a36Sopenharmony_ci# fp0 = default result # 990462306a36Sopenharmony_ci# fp1 = unchanged # 990562306a36Sopenharmony_ci# # 990662306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 990762306a36Sopenharmony_ci# An operand error should occur as the result of transcendental # 990862306a36Sopenharmony_ci# emulation in the 060FPLSP. If OPERR is disabled, just return a NAN # 990962306a36Sopenharmony_ci# in fp0. If OPERR is enabled, return the dst operand unscathed in fp0 # 991062306a36Sopenharmony_ci# and the source operand in fp1. Use fp2 to create an OPERR exception # 991162306a36Sopenharmony_ci# so that the operating system can log the event. # 991262306a36Sopenharmony_ci# # 991362306a36Sopenharmony_ci######################################################################### 991462306a36Sopenharmony_ci 991562306a36Sopenharmony_ci global t_operr 991662306a36Sopenharmony_cit_operr: 991762306a36Sopenharmony_ci ori.l &opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP 991862306a36Sopenharmony_ci 991962306a36Sopenharmony_ci btst &operr_bit,FPCR_ENABLE(%a6) 992062306a36Sopenharmony_ci bne.b operr_ena 992162306a36Sopenharmony_ci 992262306a36Sopenharmony_ci# operr is disabled. return a QNAN in fp0 992362306a36Sopenharmony_ci fmovm.x qnan(%pc),&0x80 # return QNAN 992462306a36Sopenharmony_ci rts 992562306a36Sopenharmony_ci 992662306a36Sopenharmony_ci# operr is enabled. create an operr exception so the user can record it 992762306a36Sopenharmony_ci# but use fp2 instead. return the dst operand unscathed in fp0. 992862306a36Sopenharmony_cioperr_ena: 992962306a36Sopenharmony_ci fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed 993062306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 993162306a36Sopenharmony_ci fmovm.x &0x04,-(%sp) # save fp2 993262306a36Sopenharmony_ci fmov.s &0x7f800000,%fp2 # load +INF 993362306a36Sopenharmony_ci fmul.s &0x00000000,%fp2 # +INF x 0 993462306a36Sopenharmony_ci fmovm.x (%sp)+,&0x20 # restore fp2 993562306a36Sopenharmony_ci rts 993662306a36Sopenharmony_ci 993762306a36Sopenharmony_cipls_huge: 993862306a36Sopenharmony_ci long 0x7ffe0000,0xffffffff,0xffffffff 993962306a36Sopenharmony_cimns_huge: 994062306a36Sopenharmony_ci long 0xfffe0000,0xffffffff,0xffffffff 994162306a36Sopenharmony_cipls_tiny: 994262306a36Sopenharmony_ci long 0x00000000,0x80000000,0x00000000 994362306a36Sopenharmony_cimns_tiny: 994462306a36Sopenharmony_ci long 0x80000000,0x80000000,0x00000000 994562306a36Sopenharmony_ci 994662306a36Sopenharmony_ci######################################################################### 994762306a36Sopenharmony_ci# XDEF **************************************************************** # 994862306a36Sopenharmony_ci# t_unfl(): Handle 060FPLSP underflow exception during emulation. # 994962306a36Sopenharmony_ci# t_unfl2(): Handle 060FPLSP underflow exception during # 995062306a36Sopenharmony_ci# emulation. result always positive. # 995162306a36Sopenharmony_ci# # 995262306a36Sopenharmony_ci# This routine is used by the 060FPLSP package. # 995362306a36Sopenharmony_ci# # 995462306a36Sopenharmony_ci# XREF **************************************************************** # 995562306a36Sopenharmony_ci# None. # 995662306a36Sopenharmony_ci# # 995762306a36Sopenharmony_ci# INPUT *************************************************************** # 995862306a36Sopenharmony_ci# a0 = pointer to extended precision source operand # 995962306a36Sopenharmony_ci# # 996062306a36Sopenharmony_ci# OUTPUT ************************************************************** # 996162306a36Sopenharmony_ci# fp0 = default underflow result # 996262306a36Sopenharmony_ci# # 996362306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 996462306a36Sopenharmony_ci# An underflow should occur as the result of transcendental # 996562306a36Sopenharmony_ci# emulation in the 060FPLSP. Create an underflow by using "fmul" # 996662306a36Sopenharmony_ci# and two very small numbers of appropriate sign so the operating # 996762306a36Sopenharmony_ci# system can log the event. # 996862306a36Sopenharmony_ci# # 996962306a36Sopenharmony_ci######################################################################### 997062306a36Sopenharmony_ci 997162306a36Sopenharmony_ci global t_unfl 997262306a36Sopenharmony_cit_unfl: 997362306a36Sopenharmony_ci tst.b SRC_EX(%a0) 997462306a36Sopenharmony_ci bpl.b unf_pos 997562306a36Sopenharmony_ci 997662306a36Sopenharmony_ci global t_unfl2 997762306a36Sopenharmony_cit_unfl2: 997862306a36Sopenharmony_ci ori.l &unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX 997962306a36Sopenharmony_ci 998062306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 998162306a36Sopenharmony_ci fmovm.x mns_tiny(%pc),&0x80 998262306a36Sopenharmony_ci fmul.x pls_tiny(%pc),%fp0 998362306a36Sopenharmony_ci 998462306a36Sopenharmony_ci fmov.l %fpsr,%d0 998562306a36Sopenharmony_ci rol.l &0x8,%d0 998662306a36Sopenharmony_ci mov.b %d0,FPSR_CC(%a6) 998762306a36Sopenharmony_ci rts 998862306a36Sopenharmony_ciunf_pos: 998962306a36Sopenharmony_ci ori.w &unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX 999062306a36Sopenharmony_ci 999162306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 999262306a36Sopenharmony_ci fmovm.x pls_tiny(%pc),&0x80 999362306a36Sopenharmony_ci fmul.x %fp0,%fp0 999462306a36Sopenharmony_ci 999562306a36Sopenharmony_ci fmov.l %fpsr,%d0 999662306a36Sopenharmony_ci rol.l &0x8,%d0 999762306a36Sopenharmony_ci mov.b %d0,FPSR_CC(%a6) 999862306a36Sopenharmony_ci rts 999962306a36Sopenharmony_ci 1000062306a36Sopenharmony_ci######################################################################### 1000162306a36Sopenharmony_ci# XDEF **************************************************************** # 1000262306a36Sopenharmony_ci# t_ovfl(): Handle 060FPLSP overflow exception during emulation. # 1000362306a36Sopenharmony_ci# (monadic) # 1000462306a36Sopenharmony_ci# t_ovfl2(): Handle 060FPLSP overflow exception during # 1000562306a36Sopenharmony_ci# emulation. result always positive. (dyadic) # 1000662306a36Sopenharmony_ci# t_ovfl_sc(): Handle 060FPLSP overflow exception during # 1000762306a36Sopenharmony_ci# emulation for "fscale". # 1000862306a36Sopenharmony_ci# # 1000962306a36Sopenharmony_ci# This routine is used by the 060FPLSP package. # 1001062306a36Sopenharmony_ci# # 1001162306a36Sopenharmony_ci# XREF **************************************************************** # 1001262306a36Sopenharmony_ci# None. # 1001362306a36Sopenharmony_ci# # 1001462306a36Sopenharmony_ci# INPUT *************************************************************** # 1001562306a36Sopenharmony_ci# a0 = pointer to extended precision source operand # 1001662306a36Sopenharmony_ci# # 1001762306a36Sopenharmony_ci# OUTPUT ************************************************************** # 1001862306a36Sopenharmony_ci# fp0 = default underflow result # 1001962306a36Sopenharmony_ci# # 1002062306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 1002162306a36Sopenharmony_ci# An overflow should occur as the result of transcendental # 1002262306a36Sopenharmony_ci# emulation in the 060FPLSP. Create an overflow by using "fmul" # 1002362306a36Sopenharmony_ci# and two very lareg numbers of appropriate sign so the operating # 1002462306a36Sopenharmony_ci# system can log the event. # 1002562306a36Sopenharmony_ci# For t_ovfl_sc() we take special care not to lose the INEX2 bit. # 1002662306a36Sopenharmony_ci# # 1002762306a36Sopenharmony_ci######################################################################### 1002862306a36Sopenharmony_ci 1002962306a36Sopenharmony_ci global t_ovfl_sc 1003062306a36Sopenharmony_cit_ovfl_sc: 1003162306a36Sopenharmony_ci ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX 1003262306a36Sopenharmony_ci 1003362306a36Sopenharmony_ci mov.b %d0,%d1 # fetch rnd prec,mode 1003462306a36Sopenharmony_ci andi.b &0xc0,%d1 # extract prec 1003562306a36Sopenharmony_ci beq.w ovfl_work 1003662306a36Sopenharmony_ci 1003762306a36Sopenharmony_ci# dst op is a DENORM. we have to normalize the mantissa to see if the 1003862306a36Sopenharmony_ci# result would be inexact for the given precision. make a copy of the 1003962306a36Sopenharmony_ci# dst so we don't screw up the version passed to us. 1004062306a36Sopenharmony_ci mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6) 1004162306a36Sopenharmony_ci mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6) 1004262306a36Sopenharmony_ci mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6) 1004362306a36Sopenharmony_ci lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0 1004462306a36Sopenharmony_ci movm.l &0xc080,-(%sp) # save d0-d1/a0 1004562306a36Sopenharmony_ci bsr.l norm # normalize mantissa 1004662306a36Sopenharmony_ci movm.l (%sp)+,&0x0103 # restore d0-d1/a0 1004762306a36Sopenharmony_ci 1004862306a36Sopenharmony_ci cmpi.b %d1,&0x40 # is precision sgl? 1004962306a36Sopenharmony_ci bne.b ovfl_sc_dbl # no; dbl 1005062306a36Sopenharmony_ciovfl_sc_sgl: 1005162306a36Sopenharmony_ci tst.l LOCAL_LO(%a0) # is lo lw of sgl set? 1005262306a36Sopenharmony_ci bne.b ovfl_sc_inx # yes 1005362306a36Sopenharmony_ci tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set? 1005462306a36Sopenharmony_ci bne.b ovfl_sc_inx # yes 1005562306a36Sopenharmony_ci bra.w ovfl_work # don't set INEX2 1005662306a36Sopenharmony_ciovfl_sc_dbl: 1005762306a36Sopenharmony_ci mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of 1005862306a36Sopenharmony_ci andi.l &0x7ff,%d1 # dbl mantissa set? 1005962306a36Sopenharmony_ci beq.w ovfl_work # no; don't set INEX2 1006062306a36Sopenharmony_ciovfl_sc_inx: 1006162306a36Sopenharmony_ci ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2 1006262306a36Sopenharmony_ci bra.b ovfl_work # continue 1006362306a36Sopenharmony_ci 1006462306a36Sopenharmony_ci global t_ovfl 1006562306a36Sopenharmony_cit_ovfl: 1006662306a36Sopenharmony_ci ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX 1006762306a36Sopenharmony_ciovfl_work: 1006862306a36Sopenharmony_ci tst.b SRC_EX(%a0) 1006962306a36Sopenharmony_ci bpl.b ovfl_p 1007062306a36Sopenharmony_ciovfl_m: 1007162306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 1007262306a36Sopenharmony_ci fmovm.x mns_huge(%pc),&0x80 1007362306a36Sopenharmony_ci fmul.x pls_huge(%pc),%fp0 1007462306a36Sopenharmony_ci 1007562306a36Sopenharmony_ci fmov.l %fpsr,%d0 1007662306a36Sopenharmony_ci rol.l &0x8,%d0 1007762306a36Sopenharmony_ci ori.b &neg_mask,%d0 1007862306a36Sopenharmony_ci mov.b %d0,FPSR_CC(%a6) 1007962306a36Sopenharmony_ci rts 1008062306a36Sopenharmony_ciovfl_p: 1008162306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 1008262306a36Sopenharmony_ci fmovm.x pls_huge(%pc),&0x80 1008362306a36Sopenharmony_ci fmul.x pls_huge(%pc),%fp0 1008462306a36Sopenharmony_ci 1008562306a36Sopenharmony_ci fmov.l %fpsr,%d0 1008662306a36Sopenharmony_ci rol.l &0x8,%d0 1008762306a36Sopenharmony_ci mov.b %d0,FPSR_CC(%a6) 1008862306a36Sopenharmony_ci rts 1008962306a36Sopenharmony_ci 1009062306a36Sopenharmony_ci global t_ovfl2 1009162306a36Sopenharmony_cit_ovfl2: 1009262306a36Sopenharmony_ci ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX 1009362306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 1009462306a36Sopenharmony_ci fmovm.x pls_huge(%pc),&0x80 1009562306a36Sopenharmony_ci fmul.x pls_huge(%pc),%fp0 1009662306a36Sopenharmony_ci 1009762306a36Sopenharmony_ci fmov.l %fpsr,%d0 1009862306a36Sopenharmony_ci rol.l &0x8,%d0 1009962306a36Sopenharmony_ci mov.b %d0,FPSR_CC(%a6) 1010062306a36Sopenharmony_ci rts 1010162306a36Sopenharmony_ci 1010262306a36Sopenharmony_ci######################################################################### 1010362306a36Sopenharmony_ci# XDEF **************************************************************** # 1010462306a36Sopenharmony_ci# t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during # 1010562306a36Sopenharmony_ci# emulation. # 1010662306a36Sopenharmony_ci# t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during # 1010762306a36Sopenharmony_ci# emulation. # 1010862306a36Sopenharmony_ci# # 1010962306a36Sopenharmony_ci# These routines are used by the 060FPLSP package. # 1011062306a36Sopenharmony_ci# # 1011162306a36Sopenharmony_ci# XREF **************************************************************** # 1011262306a36Sopenharmony_ci# None. # 1011362306a36Sopenharmony_ci# # 1011462306a36Sopenharmony_ci# INPUT *************************************************************** # 1011562306a36Sopenharmony_ci# fp0 = default underflow or overflow result # 1011662306a36Sopenharmony_ci# # 1011762306a36Sopenharmony_ci# OUTPUT ************************************************************** # 1011862306a36Sopenharmony_ci# fp0 = default result # 1011962306a36Sopenharmony_ci# # 1012062306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 1012162306a36Sopenharmony_ci# If an overflow or underflow occurred during the last # 1012262306a36Sopenharmony_ci# instruction of transcendental 060FPLSP emulation, then it has already # 1012362306a36Sopenharmony_ci# occurred and has been logged. Now we need to see if an inexact # 1012462306a36Sopenharmony_ci# exception should occur. # 1012562306a36Sopenharmony_ci# # 1012662306a36Sopenharmony_ci######################################################################### 1012762306a36Sopenharmony_ci 1012862306a36Sopenharmony_ci global t_catch2 1012962306a36Sopenharmony_cit_catch2: 1013062306a36Sopenharmony_ci fmov.l %fpsr,%d0 1013162306a36Sopenharmony_ci or.l %d0,USER_FPSR(%a6) 1013262306a36Sopenharmony_ci bra.b inx2_work 1013362306a36Sopenharmony_ci 1013462306a36Sopenharmony_ci global t_catch 1013562306a36Sopenharmony_cit_catch: 1013662306a36Sopenharmony_ci fmov.l %fpsr,%d0 1013762306a36Sopenharmony_ci or.l %d0,USER_FPSR(%a6) 1013862306a36Sopenharmony_ci 1013962306a36Sopenharmony_ci######################################################################### 1014062306a36Sopenharmony_ci# XDEF **************************************************************** # 1014162306a36Sopenharmony_ci# t_inx2(): Handle inexact 060FPLSP exception during emulation. # 1014262306a36Sopenharmony_ci# t_pinx2(): Handle inexact 060FPLSP exception for "+" results. # 1014362306a36Sopenharmony_ci# t_minx2(): Handle inexact 060FPLSP exception for "-" results. # 1014462306a36Sopenharmony_ci# # 1014562306a36Sopenharmony_ci# XREF **************************************************************** # 1014662306a36Sopenharmony_ci# None. # 1014762306a36Sopenharmony_ci# # 1014862306a36Sopenharmony_ci# INPUT *************************************************************** # 1014962306a36Sopenharmony_ci# fp0 = default result # 1015062306a36Sopenharmony_ci# # 1015162306a36Sopenharmony_ci# OUTPUT ************************************************************** # 1015262306a36Sopenharmony_ci# fp0 = default result # 1015362306a36Sopenharmony_ci# # 1015462306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 1015562306a36Sopenharmony_ci# The last instruction of transcendental emulation for the # 1015662306a36Sopenharmony_ci# 060FPLSP should be inexact. So, if inexact is enabled, then we create # 1015762306a36Sopenharmony_ci# the event here by adding a large and very small number together # 1015862306a36Sopenharmony_ci# so that the operating system can log the event. # 1015962306a36Sopenharmony_ci# Must check, too, if the result was zero, in which case we just # 1016062306a36Sopenharmony_ci# set the FPSR bits and return. # 1016162306a36Sopenharmony_ci# # 1016262306a36Sopenharmony_ci######################################################################### 1016362306a36Sopenharmony_ci 1016462306a36Sopenharmony_ci global t_inx2 1016562306a36Sopenharmony_cit_inx2: 1016662306a36Sopenharmony_ci fblt.w t_minx2 1016762306a36Sopenharmony_ci fbeq.w inx2_zero 1016862306a36Sopenharmony_ci 1016962306a36Sopenharmony_ci global t_pinx2 1017062306a36Sopenharmony_cit_pinx2: 1017162306a36Sopenharmony_ci ori.w &inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX 1017262306a36Sopenharmony_ci bra.b inx2_work 1017362306a36Sopenharmony_ci 1017462306a36Sopenharmony_ci global t_minx2 1017562306a36Sopenharmony_cit_minx2: 1017662306a36Sopenharmony_ci ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6) 1017762306a36Sopenharmony_ci 1017862306a36Sopenharmony_ciinx2_work: 1017962306a36Sopenharmony_ci btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled? 1018062306a36Sopenharmony_ci bne.b inx2_work_ena # yes 1018162306a36Sopenharmony_ci rts 1018262306a36Sopenharmony_ciinx2_work_ena: 1018362306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr # insert user's exceptions 1018462306a36Sopenharmony_ci fmov.s &0x3f800000,%fp1 # load +1 1018562306a36Sopenharmony_ci fadd.x pls_tiny(%pc),%fp1 # cause exception 1018662306a36Sopenharmony_ci rts 1018762306a36Sopenharmony_ci 1018862306a36Sopenharmony_ciinx2_zero: 1018962306a36Sopenharmony_ci mov.b &z_bmask,FPSR_CC(%a6) 1019062306a36Sopenharmony_ci ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX 1019162306a36Sopenharmony_ci rts 1019262306a36Sopenharmony_ci 1019362306a36Sopenharmony_ci######################################################################### 1019462306a36Sopenharmony_ci# XDEF **************************************************************** # 1019562306a36Sopenharmony_ci# t_extdnrm(): Handle DENORM inputs in 060FPLSP. # 1019662306a36Sopenharmony_ci# t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale". # 1019762306a36Sopenharmony_ci# # 1019862306a36Sopenharmony_ci# This routine is used by the 060FPLSP package. # 1019962306a36Sopenharmony_ci# # 1020062306a36Sopenharmony_ci# XREF **************************************************************** # 1020162306a36Sopenharmony_ci# None. # 1020262306a36Sopenharmony_ci# # 1020362306a36Sopenharmony_ci# INPUT *************************************************************** # 1020462306a36Sopenharmony_ci# a0 = pointer to extended precision input operand # 1020562306a36Sopenharmony_ci# # 1020662306a36Sopenharmony_ci# OUTPUT ************************************************************** # 1020762306a36Sopenharmony_ci# fp0 = default result # 1020862306a36Sopenharmony_ci# # 1020962306a36Sopenharmony_ci# ALGORITHM *********************************************************** # 1021062306a36Sopenharmony_ci# For all functions that have a denormalized input and that # 1021162306a36Sopenharmony_ci# f(x)=x, this is the entry point. # 1021262306a36Sopenharmony_ci# DENORM value is moved using "fmove" which triggers an exception # 1021362306a36Sopenharmony_ci# if enabled so the operating system can log the event. # 1021462306a36Sopenharmony_ci# # 1021562306a36Sopenharmony_ci######################################################################### 1021662306a36Sopenharmony_ci 1021762306a36Sopenharmony_ci global t_extdnrm 1021862306a36Sopenharmony_cit_extdnrm: 1021962306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 1022062306a36Sopenharmony_ci fmov.x SRC_EX(%a0),%fp0 1022162306a36Sopenharmony_ci fmov.l %fpsr,%d0 1022262306a36Sopenharmony_ci ori.l &unfinx_mask,%d0 1022362306a36Sopenharmony_ci or.l %d0,USER_FPSR(%a6) 1022462306a36Sopenharmony_ci rts 1022562306a36Sopenharmony_ci 1022662306a36Sopenharmony_ci global t_resdnrm 1022762306a36Sopenharmony_cit_resdnrm: 1022862306a36Sopenharmony_ci fmov.l USER_FPCR(%a6),%fpcr 1022962306a36Sopenharmony_ci fmov.x SRC_EX(%a0),%fp0 1023062306a36Sopenharmony_ci fmov.l %fpsr,%d0 1023162306a36Sopenharmony_ci or.l %d0,USER_FPSR(%a6) 1023262306a36Sopenharmony_ci rts 1023362306a36Sopenharmony_ci 1023462306a36Sopenharmony_ci########################################## 1023562306a36Sopenharmony_ci 1023662306a36Sopenharmony_ci# 1023762306a36Sopenharmony_ci# sto_cos: 1023862306a36Sopenharmony_ci# This is used by fsincos library emulation. The correct 1023962306a36Sopenharmony_ci# values are already in fp0 and fp1 so we do nothing here. 1024062306a36Sopenharmony_ci# 1024162306a36Sopenharmony_ci global sto_cos 1024262306a36Sopenharmony_cisto_cos: 1024362306a36Sopenharmony_ci rts 1024462306a36Sopenharmony_ci 1024562306a36Sopenharmony_ci########################################## 1024662306a36Sopenharmony_ci 1024762306a36Sopenharmony_ci# 1024862306a36Sopenharmony_ci# dst_qnan --- force result when destination is a NaN 1024962306a36Sopenharmony_ci# 1025062306a36Sopenharmony_ci global dst_qnan 1025162306a36Sopenharmony_cidst_qnan: 1025262306a36Sopenharmony_ci fmov.x DST(%a1),%fp0 1025362306a36Sopenharmony_ci tst.b DST_EX(%a1) 1025462306a36Sopenharmony_ci bmi.b dst_qnan_m 1025562306a36Sopenharmony_cidst_qnan_p: 1025662306a36Sopenharmony_ci mov.b &nan_bmask,FPSR_CC(%a6) 1025762306a36Sopenharmony_ci rts 1025862306a36Sopenharmony_cidst_qnan_m: 1025962306a36Sopenharmony_ci mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6) 1026062306a36Sopenharmony_ci rts 1026162306a36Sopenharmony_ci 1026262306a36Sopenharmony_ci# 1026362306a36Sopenharmony_ci# src_qnan --- force result when source is a NaN 1026462306a36Sopenharmony_ci# 1026562306a36Sopenharmony_ci global src_qnan 1026662306a36Sopenharmony_cisrc_qnan: 1026762306a36Sopenharmony_ci fmov.x SRC(%a0),%fp0 1026862306a36Sopenharmony_ci tst.b SRC_EX(%a0) 1026962306a36Sopenharmony_ci bmi.b src_qnan_m 1027062306a36Sopenharmony_cisrc_qnan_p: 1027162306a36Sopenharmony_ci mov.b &nan_bmask,FPSR_CC(%a6) 1027262306a36Sopenharmony_ci rts 1027362306a36Sopenharmony_cisrc_qnan_m: 1027462306a36Sopenharmony_ci mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6) 1027562306a36Sopenharmony_ci rts 1027662306a36Sopenharmony_ci 1027762306a36Sopenharmony_ci########################################## 1027862306a36Sopenharmony_ci 1027962306a36Sopenharmony_ci# 1028062306a36Sopenharmony_ci# Native instruction support 1028162306a36Sopenharmony_ci# 1028262306a36Sopenharmony_ci# Some systems may need entry points even for 68060 native 1028362306a36Sopenharmony_ci# instructions. These routines are provided for 1028462306a36Sopenharmony_ci# convenience. 1028562306a36Sopenharmony_ci# 1028662306a36Sopenharmony_ci global _fadds_ 1028762306a36Sopenharmony_ci_fadds_: 1028862306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1028962306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1029062306a36Sopenharmony_ci fmov.s 0x8(%sp),%fp0 # load sgl dst 1029162306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1029262306a36Sopenharmony_ci fadd.s 0x8(%sp),%fp0 # fadd w/ sgl src 1029362306a36Sopenharmony_ci rts 1029462306a36Sopenharmony_ci 1029562306a36Sopenharmony_ci global _faddd_ 1029662306a36Sopenharmony_ci_faddd_: 1029762306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1029862306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1029962306a36Sopenharmony_ci fmov.d 0x8(%sp),%fp0 # load dbl dst 1030062306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1030162306a36Sopenharmony_ci fadd.d 0xc(%sp),%fp0 # fadd w/ dbl src 1030262306a36Sopenharmony_ci rts 1030362306a36Sopenharmony_ci 1030462306a36Sopenharmony_ci global _faddx_ 1030562306a36Sopenharmony_ci_faddx_: 1030662306a36Sopenharmony_ci fmovm.x 0x4(%sp),&0x80 # load ext dst 1030762306a36Sopenharmony_ci fadd.x 0x10(%sp),%fp0 # fadd w/ ext src 1030862306a36Sopenharmony_ci rts 1030962306a36Sopenharmony_ci 1031062306a36Sopenharmony_ci global _fsubs_ 1031162306a36Sopenharmony_ci_fsubs_: 1031262306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1031362306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1031462306a36Sopenharmony_ci fmov.s 0x8(%sp),%fp0 # load sgl dst 1031562306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1031662306a36Sopenharmony_ci fsub.s 0x8(%sp),%fp0 # fsub w/ sgl src 1031762306a36Sopenharmony_ci rts 1031862306a36Sopenharmony_ci 1031962306a36Sopenharmony_ci global _fsubd_ 1032062306a36Sopenharmony_ci_fsubd_: 1032162306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1032262306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1032362306a36Sopenharmony_ci fmov.d 0x8(%sp),%fp0 # load dbl dst 1032462306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1032562306a36Sopenharmony_ci fsub.d 0xc(%sp),%fp0 # fsub w/ dbl src 1032662306a36Sopenharmony_ci rts 1032762306a36Sopenharmony_ci 1032862306a36Sopenharmony_ci global _fsubx_ 1032962306a36Sopenharmony_ci_fsubx_: 1033062306a36Sopenharmony_ci fmovm.x 0x4(%sp),&0x80 # load ext dst 1033162306a36Sopenharmony_ci fsub.x 0x10(%sp),%fp0 # fsub w/ ext src 1033262306a36Sopenharmony_ci rts 1033362306a36Sopenharmony_ci 1033462306a36Sopenharmony_ci global _fmuls_ 1033562306a36Sopenharmony_ci_fmuls_: 1033662306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1033762306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1033862306a36Sopenharmony_ci fmov.s 0x8(%sp),%fp0 # load sgl dst 1033962306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1034062306a36Sopenharmony_ci fmul.s 0x8(%sp),%fp0 # fmul w/ sgl src 1034162306a36Sopenharmony_ci rts 1034262306a36Sopenharmony_ci 1034362306a36Sopenharmony_ci global _fmuld_ 1034462306a36Sopenharmony_ci_fmuld_: 1034562306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1034662306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1034762306a36Sopenharmony_ci fmov.d 0x8(%sp),%fp0 # load dbl dst 1034862306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1034962306a36Sopenharmony_ci fmul.d 0xc(%sp),%fp0 # fmul w/ dbl src 1035062306a36Sopenharmony_ci rts 1035162306a36Sopenharmony_ci 1035262306a36Sopenharmony_ci global _fmulx_ 1035362306a36Sopenharmony_ci_fmulx_: 1035462306a36Sopenharmony_ci fmovm.x 0x4(%sp),&0x80 # load ext dst 1035562306a36Sopenharmony_ci fmul.x 0x10(%sp),%fp0 # fmul w/ ext src 1035662306a36Sopenharmony_ci rts 1035762306a36Sopenharmony_ci 1035862306a36Sopenharmony_ci global _fdivs_ 1035962306a36Sopenharmony_ci_fdivs_: 1036062306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1036162306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1036262306a36Sopenharmony_ci fmov.s 0x8(%sp),%fp0 # load sgl dst 1036362306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1036462306a36Sopenharmony_ci fdiv.s 0x8(%sp),%fp0 # fdiv w/ sgl src 1036562306a36Sopenharmony_ci rts 1036662306a36Sopenharmony_ci 1036762306a36Sopenharmony_ci global _fdivd_ 1036862306a36Sopenharmony_ci_fdivd_: 1036962306a36Sopenharmony_ci fmov.l %fpcr,-(%sp) # save fpcr 1037062306a36Sopenharmony_ci fmov.l &0x00000000,%fpcr # clear fpcr for load 1037162306a36Sopenharmony_ci fmov.d 0x8(%sp),%fp0 # load dbl dst 1037262306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr # restore fpcr 1037362306a36Sopenharmony_ci fdiv.d 0xc(%sp),%fp0 # fdiv w/ dbl src 1037462306a36Sopenharmony_ci rts 1037562306a36Sopenharmony_ci 1037662306a36Sopenharmony_ci global _fdivx_ 1037762306a36Sopenharmony_ci_fdivx_: 1037862306a36Sopenharmony_ci fmovm.x 0x4(%sp),&0x80 # load ext dst 1037962306a36Sopenharmony_ci fdiv.x 0x10(%sp),%fp0 # fdiv w/ ext src 1038062306a36Sopenharmony_ci rts 1038162306a36Sopenharmony_ci 1038262306a36Sopenharmony_ci global _fabss_ 1038362306a36Sopenharmony_ci_fabss_: 1038462306a36Sopenharmony_ci fabs.s 0x4(%sp),%fp0 # fabs w/ sgl src 1038562306a36Sopenharmony_ci rts 1038662306a36Sopenharmony_ci 1038762306a36Sopenharmony_ci global _fabsd_ 1038862306a36Sopenharmony_ci_fabsd_: 1038962306a36Sopenharmony_ci fabs.d 0x4(%sp),%fp0 # fabs w/ dbl src 1039062306a36Sopenharmony_ci rts 1039162306a36Sopenharmony_ci 1039262306a36Sopenharmony_ci global _fabsx_ 1039362306a36Sopenharmony_ci_fabsx_: 1039462306a36Sopenharmony_ci fabs.x 0x4(%sp),%fp0 # fabs w/ ext src 1039562306a36Sopenharmony_ci rts 1039662306a36Sopenharmony_ci 1039762306a36Sopenharmony_ci global _fnegs_ 1039862306a36Sopenharmony_ci_fnegs_: 1039962306a36Sopenharmony_ci fneg.s 0x4(%sp),%fp0 # fneg w/ sgl src 1040062306a36Sopenharmony_ci rts 1040162306a36Sopenharmony_ci 1040262306a36Sopenharmony_ci global _fnegd_ 1040362306a36Sopenharmony_ci_fnegd_: 1040462306a36Sopenharmony_ci fneg.d 0x4(%sp),%fp0 # fneg w/ dbl src 1040562306a36Sopenharmony_ci rts 1040662306a36Sopenharmony_ci 1040762306a36Sopenharmony_ci global _fnegx_ 1040862306a36Sopenharmony_ci_fnegx_: 1040962306a36Sopenharmony_ci fneg.x 0x4(%sp),%fp0 # fneg w/ ext src 1041062306a36Sopenharmony_ci rts 1041162306a36Sopenharmony_ci 1041262306a36Sopenharmony_ci global _fsqrts_ 1041362306a36Sopenharmony_ci_fsqrts_: 1041462306a36Sopenharmony_ci fsqrt.s 0x4(%sp),%fp0 # fsqrt w/ sgl src 1041562306a36Sopenharmony_ci rts 1041662306a36Sopenharmony_ci 1041762306a36Sopenharmony_ci global _fsqrtd_ 1041862306a36Sopenharmony_ci_fsqrtd_: 1041962306a36Sopenharmony_ci fsqrt.d 0x4(%sp),%fp0 # fsqrt w/ dbl src 1042062306a36Sopenharmony_ci rts 1042162306a36Sopenharmony_ci 1042262306a36Sopenharmony_ci global _fsqrtx_ 1042362306a36Sopenharmony_ci_fsqrtx_: 1042462306a36Sopenharmony_ci fsqrt.x 0x4(%sp),%fp0 # fsqrt w/ ext src 1042562306a36Sopenharmony_ci rts 1042662306a36Sopenharmony_ci 1042762306a36Sopenharmony_ci global _fints_ 1042862306a36Sopenharmony_ci_fints_: 1042962306a36Sopenharmony_ci fint.s 0x4(%sp),%fp0 # fint w/ sgl src 1043062306a36Sopenharmony_ci rts 1043162306a36Sopenharmony_ci 1043262306a36Sopenharmony_ci global _fintd_ 1043362306a36Sopenharmony_ci_fintd_: 1043462306a36Sopenharmony_ci fint.d 0x4(%sp),%fp0 # fint w/ dbl src 1043562306a36Sopenharmony_ci rts 1043662306a36Sopenharmony_ci 1043762306a36Sopenharmony_ci global _fintx_ 1043862306a36Sopenharmony_ci_fintx_: 1043962306a36Sopenharmony_ci fint.x 0x4(%sp),%fp0 # fint w/ ext src 1044062306a36Sopenharmony_ci rts 1044162306a36Sopenharmony_ci 1044262306a36Sopenharmony_ci global _fintrzs_ 1044362306a36Sopenharmony_ci_fintrzs_: 1044462306a36Sopenharmony_ci fintrz.s 0x4(%sp),%fp0 # fintrz w/ sgl src 1044562306a36Sopenharmony_ci rts 1044662306a36Sopenharmony_ci 1044762306a36Sopenharmony_ci global _fintrzd_ 1044862306a36Sopenharmony_ci_fintrzd_: 1044962306a36Sopenharmony_ci fintrz.d 0x4(%sp),%fp0 # fintrx w/ dbl src 1045062306a36Sopenharmony_ci rts 1045162306a36Sopenharmony_ci 1045262306a36Sopenharmony_ci global _fintrzx_ 1045362306a36Sopenharmony_ci_fintrzx_: 1045462306a36Sopenharmony_ci fintrz.x 0x4(%sp),%fp0 # fintrz w/ ext src 1045562306a36Sopenharmony_ci rts 1045662306a36Sopenharmony_ci 1045762306a36Sopenharmony_ci######################################################################## 1045862306a36Sopenharmony_ci 1045962306a36Sopenharmony_ci######################################################################### 1046062306a36Sopenharmony_ci# src_zero(): Return signed zero according to sign of src operand. # 1046162306a36Sopenharmony_ci######################################################################### 1046262306a36Sopenharmony_ci global src_zero 1046362306a36Sopenharmony_cisrc_zero: 1046462306a36Sopenharmony_ci tst.b SRC_EX(%a0) # get sign of src operand 1046562306a36Sopenharmony_ci bmi.b ld_mzero # if neg, load neg zero 1046662306a36Sopenharmony_ci 1046762306a36Sopenharmony_ci# 1046862306a36Sopenharmony_ci# ld_pzero(): return a positive zero. 1046962306a36Sopenharmony_ci# 1047062306a36Sopenharmony_ci global ld_pzero 1047162306a36Sopenharmony_cild_pzero: 1047262306a36Sopenharmony_ci fmov.s &0x00000000,%fp0 # load +0 1047362306a36Sopenharmony_ci mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 1047462306a36Sopenharmony_ci rts 1047562306a36Sopenharmony_ci 1047662306a36Sopenharmony_ci# ld_mzero(): return a negative zero. 1047762306a36Sopenharmony_ci global ld_mzero 1047862306a36Sopenharmony_cild_mzero: 1047962306a36Sopenharmony_ci fmov.s &0x80000000,%fp0 # load -0 1048062306a36Sopenharmony_ci mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits 1048162306a36Sopenharmony_ci rts 1048262306a36Sopenharmony_ci 1048362306a36Sopenharmony_ci######################################################################### 1048462306a36Sopenharmony_ci# dst_zero(): Return signed zero according to sign of dst operand. # 1048562306a36Sopenharmony_ci######################################################################### 1048662306a36Sopenharmony_ci global dst_zero 1048762306a36Sopenharmony_cidst_zero: 1048862306a36Sopenharmony_ci tst.b DST_EX(%a1) # get sign of dst operand 1048962306a36Sopenharmony_ci bmi.b ld_mzero # if neg, load neg zero 1049062306a36Sopenharmony_ci bra.b ld_pzero # load positive zero 1049162306a36Sopenharmony_ci 1049262306a36Sopenharmony_ci######################################################################### 1049362306a36Sopenharmony_ci# src_inf(): Return signed inf according to sign of src operand. # 1049462306a36Sopenharmony_ci######################################################################### 1049562306a36Sopenharmony_ci global src_inf 1049662306a36Sopenharmony_cisrc_inf: 1049762306a36Sopenharmony_ci tst.b SRC_EX(%a0) # get sign of src operand 1049862306a36Sopenharmony_ci bmi.b ld_minf # if negative branch 1049962306a36Sopenharmony_ci 1050062306a36Sopenharmony_ci# 1050162306a36Sopenharmony_ci# ld_pinf(): return a positive infinity. 1050262306a36Sopenharmony_ci# 1050362306a36Sopenharmony_ci global ld_pinf 1050462306a36Sopenharmony_cild_pinf: 1050562306a36Sopenharmony_ci fmov.s &0x7f800000,%fp0 # load +INF 1050662306a36Sopenharmony_ci mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit 1050762306a36Sopenharmony_ci rts 1050862306a36Sopenharmony_ci 1050962306a36Sopenharmony_ci# 1051062306a36Sopenharmony_ci# ld_minf():return a negative infinity. 1051162306a36Sopenharmony_ci# 1051262306a36Sopenharmony_ci global ld_minf 1051362306a36Sopenharmony_cild_minf: 1051462306a36Sopenharmony_ci fmov.s &0xff800000,%fp0 # load -INF 1051562306a36Sopenharmony_ci mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits 1051662306a36Sopenharmony_ci rts 1051762306a36Sopenharmony_ci 1051862306a36Sopenharmony_ci######################################################################### 1051962306a36Sopenharmony_ci# dst_inf(): Return signed inf according to sign of dst operand. # 1052062306a36Sopenharmony_ci######################################################################### 1052162306a36Sopenharmony_ci global dst_inf 1052262306a36Sopenharmony_cidst_inf: 1052362306a36Sopenharmony_ci tst.b DST_EX(%a1) # get sign of dst operand 1052462306a36Sopenharmony_ci bmi.b ld_minf # if negative branch 1052562306a36Sopenharmony_ci bra.b ld_pinf 1052662306a36Sopenharmony_ci 1052762306a36Sopenharmony_ci global szr_inf 1052862306a36Sopenharmony_ci################################################################# 1052962306a36Sopenharmony_ci# szr_inf(): Return +ZERO for a negative src operand or # 1053062306a36Sopenharmony_ci# +INF for a positive src operand. # 1053162306a36Sopenharmony_ci# Routine used for fetox, ftwotox, and ftentox. # 1053262306a36Sopenharmony_ci################################################################# 1053362306a36Sopenharmony_ciszr_inf: 1053462306a36Sopenharmony_ci tst.b SRC_EX(%a0) # check sign of source 1053562306a36Sopenharmony_ci bmi.b ld_pzero 1053662306a36Sopenharmony_ci bra.b ld_pinf 1053762306a36Sopenharmony_ci 1053862306a36Sopenharmony_ci######################################################################### 1053962306a36Sopenharmony_ci# sopr_inf(): Return +INF for a positive src operand or # 1054062306a36Sopenharmony_ci# jump to operand error routine for a negative src operand. # 1054162306a36Sopenharmony_ci# Routine used for flogn, flognp1, flog10, and flog2. # 1054262306a36Sopenharmony_ci######################################################################### 1054362306a36Sopenharmony_ci global sopr_inf 1054462306a36Sopenharmony_cisopr_inf: 1054562306a36Sopenharmony_ci tst.b SRC_EX(%a0) # check sign of source 1054662306a36Sopenharmony_ci bmi.w t_operr 1054762306a36Sopenharmony_ci bra.b ld_pinf 1054862306a36Sopenharmony_ci 1054962306a36Sopenharmony_ci################################################################# 1055062306a36Sopenharmony_ci# setoxm1i(): Return minus one for a negative src operand or # 1055162306a36Sopenharmony_ci# positive infinity for a positive src operand. # 1055262306a36Sopenharmony_ci# Routine used for fetoxm1. # 1055362306a36Sopenharmony_ci################################################################# 1055462306a36Sopenharmony_ci global setoxm1i 1055562306a36Sopenharmony_cisetoxm1i: 1055662306a36Sopenharmony_ci tst.b SRC_EX(%a0) # check sign of source 1055762306a36Sopenharmony_ci bmi.b ld_mone 1055862306a36Sopenharmony_ci bra.b ld_pinf 1055962306a36Sopenharmony_ci 1056062306a36Sopenharmony_ci######################################################################### 1056162306a36Sopenharmony_ci# src_one(): Return signed one according to sign of src operand. # 1056262306a36Sopenharmony_ci######################################################################### 1056362306a36Sopenharmony_ci global src_one 1056462306a36Sopenharmony_cisrc_one: 1056562306a36Sopenharmony_ci tst.b SRC_EX(%a0) # check sign of source 1056662306a36Sopenharmony_ci bmi.b ld_mone 1056762306a36Sopenharmony_ci 1056862306a36Sopenharmony_ci# 1056962306a36Sopenharmony_ci# ld_pone(): return positive one. 1057062306a36Sopenharmony_ci# 1057162306a36Sopenharmony_ci global ld_pone 1057262306a36Sopenharmony_cild_pone: 1057362306a36Sopenharmony_ci fmov.s &0x3f800000,%fp0 # load +1 1057462306a36Sopenharmony_ci clr.b FPSR_CC(%a6) 1057562306a36Sopenharmony_ci rts 1057662306a36Sopenharmony_ci 1057762306a36Sopenharmony_ci# 1057862306a36Sopenharmony_ci# ld_mone(): return negative one. 1057962306a36Sopenharmony_ci# 1058062306a36Sopenharmony_ci global ld_mone 1058162306a36Sopenharmony_cild_mone: 1058262306a36Sopenharmony_ci fmov.s &0xbf800000,%fp0 # load -1 1058362306a36Sopenharmony_ci mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 1058462306a36Sopenharmony_ci rts 1058562306a36Sopenharmony_ci 1058662306a36Sopenharmony_cippiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235 1058762306a36Sopenharmony_cimpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235 1058862306a36Sopenharmony_ci 1058962306a36Sopenharmony_ci################################################################# 1059062306a36Sopenharmony_ci# spi_2(): Return signed PI/2 according to sign of src operand. # 1059162306a36Sopenharmony_ci################################################################# 1059262306a36Sopenharmony_ci global spi_2 1059362306a36Sopenharmony_cispi_2: 1059462306a36Sopenharmony_ci tst.b SRC_EX(%a0) # check sign of source 1059562306a36Sopenharmony_ci bmi.b ld_mpi2 1059662306a36Sopenharmony_ci 1059762306a36Sopenharmony_ci# 1059862306a36Sopenharmony_ci# ld_ppi2(): return positive PI/2. 1059962306a36Sopenharmony_ci# 1060062306a36Sopenharmony_ci global ld_ppi2 1060162306a36Sopenharmony_cild_ppi2: 1060262306a36Sopenharmony_ci fmov.l %d0,%fpcr 1060362306a36Sopenharmony_ci fmov.x ppiby2(%pc),%fp0 # load +pi/2 1060462306a36Sopenharmony_ci bra.w t_pinx2 # set INEX2 1060562306a36Sopenharmony_ci 1060662306a36Sopenharmony_ci# 1060762306a36Sopenharmony_ci# ld_mpi2(): return negative PI/2. 1060862306a36Sopenharmony_ci# 1060962306a36Sopenharmony_ci global ld_mpi2 1061062306a36Sopenharmony_cild_mpi2: 1061162306a36Sopenharmony_ci fmov.l %d0,%fpcr 1061262306a36Sopenharmony_ci fmov.x mpiby2(%pc),%fp0 # load -pi/2 1061362306a36Sopenharmony_ci bra.w t_minx2 # set INEX2 1061462306a36Sopenharmony_ci 1061562306a36Sopenharmony_ci#################################################### 1061662306a36Sopenharmony_ci# The following routines give support for fsincos. # 1061762306a36Sopenharmony_ci#################################################### 1061862306a36Sopenharmony_ci 1061962306a36Sopenharmony_ci# 1062062306a36Sopenharmony_ci# ssincosz(): When the src operand is ZERO, store a one in the 1062162306a36Sopenharmony_ci# cosine register and return a ZERO in fp0 w/ the same sign 1062262306a36Sopenharmony_ci# as the src operand. 1062362306a36Sopenharmony_ci# 1062462306a36Sopenharmony_ci global ssincosz 1062562306a36Sopenharmony_cissincosz: 1062662306a36Sopenharmony_ci fmov.s &0x3f800000,%fp1 1062762306a36Sopenharmony_ci tst.b SRC_EX(%a0) # test sign 1062862306a36Sopenharmony_ci bpl.b sincoszp 1062962306a36Sopenharmony_ci fmov.s &0x80000000,%fp0 # return sin result in fp0 1063062306a36Sopenharmony_ci mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) 1063162306a36Sopenharmony_ci rts 1063262306a36Sopenharmony_cisincoszp: 1063362306a36Sopenharmony_ci fmov.s &0x00000000,%fp0 # return sin result in fp0 1063462306a36Sopenharmony_ci mov.b &z_bmask,FPSR_CC(%a6) 1063562306a36Sopenharmony_ci rts 1063662306a36Sopenharmony_ci 1063762306a36Sopenharmony_ci# 1063862306a36Sopenharmony_ci# ssincosi(): When the src operand is INF, store a QNAN in the cosine 1063962306a36Sopenharmony_ci# register and jump to the operand error routine for negative 1064062306a36Sopenharmony_ci# src operands. 1064162306a36Sopenharmony_ci# 1064262306a36Sopenharmony_ci global ssincosi 1064362306a36Sopenharmony_cissincosi: 1064462306a36Sopenharmony_ci fmov.x qnan(%pc),%fp1 # load NAN 1064562306a36Sopenharmony_ci bra.w t_operr 1064662306a36Sopenharmony_ci 1064762306a36Sopenharmony_ci# 1064862306a36Sopenharmony_ci# ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine 1064962306a36Sopenharmony_ci# register and branch to the src QNAN routine. 1065062306a36Sopenharmony_ci# 1065162306a36Sopenharmony_ci global ssincosqnan 1065262306a36Sopenharmony_cissincosqnan: 1065362306a36Sopenharmony_ci fmov.x LOCAL_EX(%a0),%fp1 1065462306a36Sopenharmony_ci bra.w src_qnan 1065562306a36Sopenharmony_ci 1065662306a36Sopenharmony_ci######################################################################## 1065762306a36Sopenharmony_ci 1065862306a36Sopenharmony_ci global smod_sdnrm 1065962306a36Sopenharmony_ci global smod_snorm 1066062306a36Sopenharmony_cismod_sdnrm: 1066162306a36Sopenharmony_cismod_snorm: 1066262306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1066362306a36Sopenharmony_ci beq.l smod 1066462306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1066562306a36Sopenharmony_ci beq.w smod_zro 1066662306a36Sopenharmony_ci cmpi.b %d1,&INF 1066762306a36Sopenharmony_ci beq.l t_operr 1066862306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1066962306a36Sopenharmony_ci beq.l smod 1067062306a36Sopenharmony_ci bra.l dst_qnan 1067162306a36Sopenharmony_ci 1067262306a36Sopenharmony_ci global smod_szero 1067362306a36Sopenharmony_cismod_szero: 1067462306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1067562306a36Sopenharmony_ci beq.l t_operr 1067662306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1067762306a36Sopenharmony_ci beq.l t_operr 1067862306a36Sopenharmony_ci cmpi.b %d1,&INF 1067962306a36Sopenharmony_ci beq.l t_operr 1068062306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1068162306a36Sopenharmony_ci beq.l t_operr 1068262306a36Sopenharmony_ci bra.l dst_qnan 1068362306a36Sopenharmony_ci 1068462306a36Sopenharmony_ci global smod_sinf 1068562306a36Sopenharmony_cismod_sinf: 1068662306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1068762306a36Sopenharmony_ci beq.l smod_fpn 1068862306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1068962306a36Sopenharmony_ci beq.l smod_zro 1069062306a36Sopenharmony_ci cmpi.b %d1,&INF 1069162306a36Sopenharmony_ci beq.l t_operr 1069262306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1069362306a36Sopenharmony_ci beq.l smod_fpn 1069462306a36Sopenharmony_ci bra.l dst_qnan 1069562306a36Sopenharmony_ci 1069662306a36Sopenharmony_cismod_zro: 1069762306a36Sopenharmony_cisrem_zro: 1069862306a36Sopenharmony_ci mov.b SRC_EX(%a0),%d1 # get src sign 1069962306a36Sopenharmony_ci mov.b DST_EX(%a1),%d0 # get dst sign 1070062306a36Sopenharmony_ci eor.b %d0,%d1 # get qbyte sign 1070162306a36Sopenharmony_ci andi.b &0x80,%d1 1070262306a36Sopenharmony_ci mov.b %d1,FPSR_QBYTE(%a6) 1070362306a36Sopenharmony_ci tst.b %d0 1070462306a36Sopenharmony_ci bpl.w ld_pzero 1070562306a36Sopenharmony_ci bra.w ld_mzero 1070662306a36Sopenharmony_ci 1070762306a36Sopenharmony_cismod_fpn: 1070862306a36Sopenharmony_cisrem_fpn: 1070962306a36Sopenharmony_ci clr.b FPSR_QBYTE(%a6) 1071062306a36Sopenharmony_ci mov.l %d0,-(%sp) 1071162306a36Sopenharmony_ci mov.b SRC_EX(%a0),%d1 # get src sign 1071262306a36Sopenharmony_ci mov.b DST_EX(%a1),%d0 # get dst sign 1071362306a36Sopenharmony_ci eor.b %d0,%d1 # get qbyte sign 1071462306a36Sopenharmony_ci andi.b &0x80,%d1 1071562306a36Sopenharmony_ci mov.b %d1,FPSR_QBYTE(%a6) 1071662306a36Sopenharmony_ci cmpi.b DTAG(%a6),&DENORM 1071762306a36Sopenharmony_ci bne.b smod_nrm 1071862306a36Sopenharmony_ci lea DST(%a1),%a0 1071962306a36Sopenharmony_ci mov.l (%sp)+,%d0 1072062306a36Sopenharmony_ci bra t_resdnrm 1072162306a36Sopenharmony_cismod_nrm: 1072262306a36Sopenharmony_ci fmov.l (%sp)+,%fpcr 1072362306a36Sopenharmony_ci fmov.x DST(%a1),%fp0 1072462306a36Sopenharmony_ci tst.b DST_EX(%a1) 1072562306a36Sopenharmony_ci bmi.b smod_nrm_neg 1072662306a36Sopenharmony_ci rts 1072762306a36Sopenharmony_ci 1072862306a36Sopenharmony_cismod_nrm_neg: 1072962306a36Sopenharmony_ci mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' code 1073062306a36Sopenharmony_ci rts 1073162306a36Sopenharmony_ci 1073262306a36Sopenharmony_ci######################################################################### 1073362306a36Sopenharmony_ci global srem_snorm 1073462306a36Sopenharmony_ci global srem_sdnrm 1073562306a36Sopenharmony_cisrem_sdnrm: 1073662306a36Sopenharmony_cisrem_snorm: 1073762306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1073862306a36Sopenharmony_ci beq.l srem 1073962306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1074062306a36Sopenharmony_ci beq.w srem_zro 1074162306a36Sopenharmony_ci cmpi.b %d1,&INF 1074262306a36Sopenharmony_ci beq.l t_operr 1074362306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1074462306a36Sopenharmony_ci beq.l srem 1074562306a36Sopenharmony_ci bra.l dst_qnan 1074662306a36Sopenharmony_ci 1074762306a36Sopenharmony_ci global srem_szero 1074862306a36Sopenharmony_cisrem_szero: 1074962306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1075062306a36Sopenharmony_ci beq.l t_operr 1075162306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1075262306a36Sopenharmony_ci beq.l t_operr 1075362306a36Sopenharmony_ci cmpi.b %d1,&INF 1075462306a36Sopenharmony_ci beq.l t_operr 1075562306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1075662306a36Sopenharmony_ci beq.l t_operr 1075762306a36Sopenharmony_ci bra.l dst_qnan 1075862306a36Sopenharmony_ci 1075962306a36Sopenharmony_ci global srem_sinf 1076062306a36Sopenharmony_cisrem_sinf: 1076162306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1076262306a36Sopenharmony_ci beq.w srem_fpn 1076362306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1076462306a36Sopenharmony_ci beq.w srem_zro 1076562306a36Sopenharmony_ci cmpi.b %d1,&INF 1076662306a36Sopenharmony_ci beq.l t_operr 1076762306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1076862306a36Sopenharmony_ci beq.l srem_fpn 1076962306a36Sopenharmony_ci bra.l dst_qnan 1077062306a36Sopenharmony_ci 1077162306a36Sopenharmony_ci######################################################################### 1077262306a36Sopenharmony_ci 1077362306a36Sopenharmony_ci global sscale_snorm 1077462306a36Sopenharmony_ci global sscale_sdnrm 1077562306a36Sopenharmony_cisscale_snorm: 1077662306a36Sopenharmony_cisscale_sdnrm: 1077762306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1077862306a36Sopenharmony_ci beq.l sscale 1077962306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1078062306a36Sopenharmony_ci beq.l dst_zero 1078162306a36Sopenharmony_ci cmpi.b %d1,&INF 1078262306a36Sopenharmony_ci beq.l dst_inf 1078362306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1078462306a36Sopenharmony_ci beq.l sscale 1078562306a36Sopenharmony_ci bra.l dst_qnan 1078662306a36Sopenharmony_ci 1078762306a36Sopenharmony_ci global sscale_szero 1078862306a36Sopenharmony_cisscale_szero: 1078962306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1079062306a36Sopenharmony_ci beq.l sscale 1079162306a36Sopenharmony_ci cmpi.b %d1,&ZERO 1079262306a36Sopenharmony_ci beq.l dst_zero 1079362306a36Sopenharmony_ci cmpi.b %d1,&INF 1079462306a36Sopenharmony_ci beq.l dst_inf 1079562306a36Sopenharmony_ci cmpi.b %d1,&DENORM 1079662306a36Sopenharmony_ci beq.l sscale 1079762306a36Sopenharmony_ci bra.l dst_qnan 1079862306a36Sopenharmony_ci 1079962306a36Sopenharmony_ci global sscale_sinf 1080062306a36Sopenharmony_cisscale_sinf: 1080162306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1080262306a36Sopenharmony_ci beq.l t_operr 1080362306a36Sopenharmony_ci cmpi.b %d1,&QNAN 1080462306a36Sopenharmony_ci beq.l dst_qnan 1080562306a36Sopenharmony_ci bra.l t_operr 1080662306a36Sopenharmony_ci 1080762306a36Sopenharmony_ci######################################################################## 1080862306a36Sopenharmony_ci 1080962306a36Sopenharmony_ci global sop_sqnan 1081062306a36Sopenharmony_cisop_sqnan: 1081162306a36Sopenharmony_ci mov.b DTAG(%a6),%d1 1081262306a36Sopenharmony_ci cmpi.b %d1,&QNAN 1081362306a36Sopenharmony_ci beq.l dst_qnan 1081462306a36Sopenharmony_ci bra.l src_qnan 1081562306a36Sopenharmony_ci 1081662306a36Sopenharmony_ci######################################################################### 1081762306a36Sopenharmony_ci# norm(): normalize the mantissa of an extended precision input. the # 1081862306a36Sopenharmony_ci# input operand should not be normalized already. # 1081962306a36Sopenharmony_ci# # 1082062306a36Sopenharmony_ci# XDEF **************************************************************** # 1082162306a36Sopenharmony_ci# norm() # 1082262306a36Sopenharmony_ci# # 1082362306a36Sopenharmony_ci# XREF **************************************************************** # 1082462306a36Sopenharmony_ci# none # 1082562306a36Sopenharmony_ci# # 1082662306a36Sopenharmony_ci# INPUT *************************************************************** # 1082762306a36Sopenharmony_ci# a0 = pointer fp extended precision operand to normalize # 1082862306a36Sopenharmony_ci# # 1082962306a36Sopenharmony_ci# OUTPUT ************************************************************** # 1083062306a36Sopenharmony_ci# d0 = number of bit positions the mantissa was shifted # 1083162306a36Sopenharmony_ci# a0 = the input operand's mantissa is normalized; the exponent # 1083262306a36Sopenharmony_ci# is unchanged. # 1083362306a36Sopenharmony_ci# # 1083462306a36Sopenharmony_ci######################################################################### 1083562306a36Sopenharmony_ci global norm 1083662306a36Sopenharmony_cinorm: 1083762306a36Sopenharmony_ci mov.l %d2, -(%sp) # create some temp regs 1083862306a36Sopenharmony_ci mov.l %d3, -(%sp) 1083962306a36Sopenharmony_ci 1084062306a36Sopenharmony_ci mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa) 1084162306a36Sopenharmony_ci mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa) 1084262306a36Sopenharmony_ci 1084362306a36Sopenharmony_ci bfffo %d0{&0:&32}, %d2 # how many places to shift? 1084462306a36Sopenharmony_ci beq.b norm_lo # hi(man) is all zeroes! 1084562306a36Sopenharmony_ci 1084662306a36Sopenharmony_cinorm_hi: 1084762306a36Sopenharmony_ci lsl.l %d2, %d0 # left shift hi(man) 1084862306a36Sopenharmony_ci bfextu %d1{&0:%d2}, %d3 # extract lo bits 1084962306a36Sopenharmony_ci 1085062306a36Sopenharmony_ci or.l %d3, %d0 # create hi(man) 1085162306a36Sopenharmony_ci lsl.l %d2, %d1 # create lo(man) 1085262306a36Sopenharmony_ci 1085362306a36Sopenharmony_ci mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 1085462306a36Sopenharmony_ci mov.l %d1, FTEMP_LO(%a0) # store new lo(man) 1085562306a36Sopenharmony_ci 1085662306a36Sopenharmony_ci mov.l %d2, %d0 # return shift amount 1085762306a36Sopenharmony_ci 1085862306a36Sopenharmony_ci mov.l (%sp)+, %d3 # restore temp regs 1085962306a36Sopenharmony_ci mov.l (%sp)+, %d2 1086062306a36Sopenharmony_ci 1086162306a36Sopenharmony_ci rts 1086262306a36Sopenharmony_ci 1086362306a36Sopenharmony_cinorm_lo: 1086462306a36Sopenharmony_ci bfffo %d1{&0:&32}, %d2 # how many places to shift? 1086562306a36Sopenharmony_ci lsl.l %d2, %d1 # shift lo(man) 1086662306a36Sopenharmony_ci add.l &32, %d2 # add 32 to shft amount 1086762306a36Sopenharmony_ci 1086862306a36Sopenharmony_ci mov.l %d1, FTEMP_HI(%a0) # store hi(man) 1086962306a36Sopenharmony_ci clr.l FTEMP_LO(%a0) # lo(man) is now zero 1087062306a36Sopenharmony_ci 1087162306a36Sopenharmony_ci mov.l %d2, %d0 # return shift amount 1087262306a36Sopenharmony_ci 1087362306a36Sopenharmony_ci mov.l (%sp)+, %d3 # restore temp regs 1087462306a36Sopenharmony_ci mov.l (%sp)+, %d2 1087562306a36Sopenharmony_ci 1087662306a36Sopenharmony_ci rts 1087762306a36Sopenharmony_ci 1087862306a36Sopenharmony_ci######################################################################### 1087962306a36Sopenharmony_ci# unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO # 1088062306a36Sopenharmony_ci# - returns corresponding optype tag # 1088162306a36Sopenharmony_ci# # 1088262306a36Sopenharmony_ci# XDEF **************************************************************** # 1088362306a36Sopenharmony_ci# unnorm_fix() # 1088462306a36Sopenharmony_ci# # 1088562306a36Sopenharmony_ci# XREF **************************************************************** # 1088662306a36Sopenharmony_ci# norm() - normalize the mantissa # 1088762306a36Sopenharmony_ci# # 1088862306a36Sopenharmony_ci# INPUT *************************************************************** # 1088962306a36Sopenharmony_ci# a0 = pointer to unnormalized extended precision number # 1089062306a36Sopenharmony_ci# # 1089162306a36Sopenharmony_ci# OUTPUT ************************************************************** # 1089262306a36Sopenharmony_ci# d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO # 1089362306a36Sopenharmony_ci# a0 = input operand has been converted to a norm, denorm, or # 1089462306a36Sopenharmony_ci# zero; both the exponent and mantissa are changed. # 1089562306a36Sopenharmony_ci# # 1089662306a36Sopenharmony_ci######################################################################### 1089762306a36Sopenharmony_ci 1089862306a36Sopenharmony_ci global unnorm_fix 1089962306a36Sopenharmony_ciunnorm_fix: 1090062306a36Sopenharmony_ci bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed? 1090162306a36Sopenharmony_ci bne.b unnorm_shift # hi(man) is not all zeroes 1090262306a36Sopenharmony_ci 1090362306a36Sopenharmony_ci# 1090462306a36Sopenharmony_ci# hi(man) is all zeroes so see if any bits in lo(man) are set 1090562306a36Sopenharmony_ci# 1090662306a36Sopenharmony_ciunnorm_chk_lo: 1090762306a36Sopenharmony_ci bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero? 1090862306a36Sopenharmony_ci beq.w unnorm_zero # yes 1090962306a36Sopenharmony_ci 1091062306a36Sopenharmony_ci add.w &32, %d0 # no; fix shift distance 1091162306a36Sopenharmony_ci 1091262306a36Sopenharmony_ci# 1091362306a36Sopenharmony_ci# d0 = # shifts needed for complete normalization 1091462306a36Sopenharmony_ci# 1091562306a36Sopenharmony_ciunnorm_shift: 1091662306a36Sopenharmony_ci clr.l %d1 # clear top word 1091762306a36Sopenharmony_ci mov.w FTEMP_EX(%a0), %d1 # extract exponent 1091862306a36Sopenharmony_ci and.w &0x7fff, %d1 # strip off sgn 1091962306a36Sopenharmony_ci 1092062306a36Sopenharmony_ci cmp.w %d0, %d1 # will denorm push exp < 0? 1092162306a36Sopenharmony_ci bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0 1092262306a36Sopenharmony_ci 1092362306a36Sopenharmony_ci# 1092462306a36Sopenharmony_ci# exponent would not go < 0. therefore, number stays normalized 1092562306a36Sopenharmony_ci# 1092662306a36Sopenharmony_ci sub.w %d0, %d1 # shift exponent value 1092762306a36Sopenharmony_ci mov.w FTEMP_EX(%a0), %d0 # load old exponent 1092862306a36Sopenharmony_ci and.w &0x8000, %d0 # save old sign 1092962306a36Sopenharmony_ci or.w %d0, %d1 # {sgn,new exp} 1093062306a36Sopenharmony_ci mov.w %d1, FTEMP_EX(%a0) # insert new exponent 1093162306a36Sopenharmony_ci 1093262306a36Sopenharmony_ci bsr.l norm # normalize UNNORM 1093362306a36Sopenharmony_ci 1093462306a36Sopenharmony_ci mov.b &NORM, %d0 # return new optype tag 1093562306a36Sopenharmony_ci rts 1093662306a36Sopenharmony_ci 1093762306a36Sopenharmony_ci# 1093862306a36Sopenharmony_ci# exponent would go < 0, so only denormalize until exp = 0 1093962306a36Sopenharmony_ci# 1094062306a36Sopenharmony_ciunnorm_nrm_zero: 1094162306a36Sopenharmony_ci cmp.b %d1, &32 # is exp <= 32? 1094262306a36Sopenharmony_ci bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent 1094362306a36Sopenharmony_ci 1094462306a36Sopenharmony_ci bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man) 1094562306a36Sopenharmony_ci mov.l %d0, FTEMP_HI(%a0) # save new hi(man) 1094662306a36Sopenharmony_ci 1094762306a36Sopenharmony_ci mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 1094862306a36Sopenharmony_ci lsl.l %d1, %d0 # extract new lo(man) 1094962306a36Sopenharmony_ci mov.l %d0, FTEMP_LO(%a0) # save new lo(man) 1095062306a36Sopenharmony_ci 1095162306a36Sopenharmony_ci and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 1095262306a36Sopenharmony_ci 1095362306a36Sopenharmony_ci mov.b &DENORM, %d0 # return new optype tag 1095462306a36Sopenharmony_ci rts 1095562306a36Sopenharmony_ci 1095662306a36Sopenharmony_ci# 1095762306a36Sopenharmony_ci# only mantissa bits set are in lo(man) 1095862306a36Sopenharmony_ci# 1095962306a36Sopenharmony_ciunnorm_nrm_zero_lrg: 1096062306a36Sopenharmony_ci sub.w &32, %d1 # adjust shft amt by 32 1096162306a36Sopenharmony_ci 1096262306a36Sopenharmony_ci mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 1096362306a36Sopenharmony_ci lsl.l %d1, %d0 # left shift lo(man) 1096462306a36Sopenharmony_ci 1096562306a36Sopenharmony_ci mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 1096662306a36Sopenharmony_ci clr.l FTEMP_LO(%a0) # lo(man) = 0 1096762306a36Sopenharmony_ci 1096862306a36Sopenharmony_ci and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 1096962306a36Sopenharmony_ci 1097062306a36Sopenharmony_ci mov.b &DENORM, %d0 # return new optype tag 1097162306a36Sopenharmony_ci rts 1097262306a36Sopenharmony_ci 1097362306a36Sopenharmony_ci# 1097462306a36Sopenharmony_ci# whole mantissa is zero so this UNNORM is actually a zero 1097562306a36Sopenharmony_ci# 1097662306a36Sopenharmony_ciunnorm_zero: 1097762306a36Sopenharmony_ci and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero 1097862306a36Sopenharmony_ci 1097962306a36Sopenharmony_ci mov.b &ZERO, %d0 # fix optype tag 1098062306a36Sopenharmony_ci rts 10981