1*57fb77a1Scgd* $NetBSD: l_support.sa,v 1.3 1994/10/26 07:49:16 cgd Exp $ 2*57fb77a1Scgd 322ef5fa9Smycroft* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 422ef5fa9Smycroft* M68000 Hi-Performance Microprocessor Division 522ef5fa9Smycroft* M68040 Software Package 622ef5fa9Smycroft* 722ef5fa9Smycroft* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 822ef5fa9Smycroft* All rights reserved. 922ef5fa9Smycroft* 1022ef5fa9Smycroft* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 1122ef5fa9Smycroft* To the maximum extent permitted by applicable law, 1222ef5fa9Smycroft* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 1322ef5fa9Smycroft* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 1422ef5fa9Smycroft* PARTICULAR PURPOSE and any warranty against infringement with 1522ef5fa9Smycroft* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 1622ef5fa9Smycroft* and any accompanying written materials. 1722ef5fa9Smycroft* 1822ef5fa9Smycroft* To the maximum extent permitted by applicable law, 1922ef5fa9Smycroft* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 2022ef5fa9Smycroft* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 2122ef5fa9Smycroft* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 2222ef5fa9Smycroft* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 2322ef5fa9Smycroft* SOFTWARE. Motorola assumes no responsibility for the maintenance 2422ef5fa9Smycroft* and support of the SOFTWARE. 2522ef5fa9Smycroft* 2622ef5fa9Smycroft* You are hereby granted a copyright license to use, modify, and 2722ef5fa9Smycroft* distribute the SOFTWARE so long as this entire notice is retained 2822ef5fa9Smycroft* without alteration in any modified and/or redistributed versions, 2922ef5fa9Smycroft* and that such modified versions are clearly identified as such. 3022ef5fa9Smycroft* No licenses are granted by implication, estoppel or otherwise 3122ef5fa9Smycroft* under any patents or trademarks of Motorola, Inc. 3222ef5fa9Smycroft 3322ef5fa9Smycroft* 3422ef5fa9Smycroft* l_support.sa 1.2 5/1/91 3522ef5fa9Smycroft* 3622ef5fa9Smycroft 3722ef5fa9SmycroftL_SUPPORT IDNT 2,1 Motorola 040 Floating Point Software Package 3822ef5fa9Smycroft 3922ef5fa9Smycroft section 8 4022ef5fa9Smycroft 4122ef5fa9Smycroftmns_one dc.l $bfff0000,$80000000,$00000000 4222ef5fa9Smycroftpls_one dc.l $3fff0000,$80000000,$00000000 4322ef5fa9Smycroftpls_inf dc.l $7fff0000,$00000000,$00000000 4422ef5fa9Smycroftpls_huge dc.l $7ffe0000,$ffffffff,$ffffffff 4522ef5fa9Smycroftmns_huge dc.l $fffe0000,$ffffffff,$ffffffff 4622ef5fa9Smycroftpls_tiny dc.l $00000000,$80000000,$00000000 4722ef5fa9Smycroftmns_tiny dc.l $80000000,$80000000,$00000000 4822ef5fa9Smycroftsmall dc.l $20000000,$80000000,$00000000 4922ef5fa9Smycroftpls_zero dc.l $00000000,$00000000,$00000000 5022ef5fa9Smycroft 5122ef5fa9Smycroft include l_fpsp.h 5222ef5fa9Smycroft 5322ef5fa9Smycroft* 5422ef5fa9Smycroft* tag --- determine the type of an extended precision operand 5522ef5fa9Smycroft* 5622ef5fa9Smycroft* The tag values returned match the way the 68040 would have 5722ef5fa9Smycroft* tagged them. 5822ef5fa9Smycroft* 5922ef5fa9Smycroft* Input: a0 points to operand 6022ef5fa9Smycroft* 6122ef5fa9Smycroft* Output d0.b = $00 norm 6222ef5fa9Smycroft* $20 zero 6322ef5fa9Smycroft* $40 inf 6422ef5fa9Smycroft* $60 nan 6522ef5fa9Smycroft* $80 denorm 6622ef5fa9Smycroft* All other registers are unchanged 6722ef5fa9Smycroft* 6822ef5fa9Smycroft xdef tag 6922ef5fa9Smycrofttag: 7022ef5fa9Smycroft move.w LOCAL_EX(a0),d0 7122ef5fa9Smycroft andi.w #$7fff,d0 7222ef5fa9Smycroft beq.b chk_zro 7322ef5fa9Smycroft cmpi.w #$7fff,d0 7422ef5fa9Smycroft beq.b chk_inf 7522ef5fa9Smycrofttag_nrm: 7622ef5fa9Smycroft clr.b d0 7722ef5fa9Smycroft rts 7822ef5fa9Smycrofttag_nan: 7922ef5fa9Smycroft move.b #$60,d0 8022ef5fa9Smycroft rts 8122ef5fa9Smycrofttag_dnrm: 8222ef5fa9Smycroft move.b #$80,d0 8322ef5fa9Smycroft rts 8422ef5fa9Smycroftchk_zro: 8522ef5fa9Smycroft btst.b #7,LOCAL_HI(a0) # check if J-bit is set 8622ef5fa9Smycroft bne.b tag_nrm 8722ef5fa9Smycroft tst.l LOCAL_HI(a0) 8822ef5fa9Smycroft bne.b tag_dnrm 8922ef5fa9Smycroft tst.l LOCAL_LO(a0) 9022ef5fa9Smycroft bne.b tag_dnrm 9122ef5fa9Smycrofttag_zero: 9222ef5fa9Smycroft move.b #$20,d0 9322ef5fa9Smycroft rts 9422ef5fa9Smycroftchk_inf: 9522ef5fa9Smycroft tst.l LOCAL_HI(a0) 9622ef5fa9Smycroft bne.b tag_nan 9722ef5fa9Smycroft tst.l LOCAL_LO(a0) 9822ef5fa9Smycroft bne.b tag_nan 9922ef5fa9Smycrofttag_inf: 10022ef5fa9Smycroft move.b #$40,d0 10122ef5fa9Smycroft rts 10222ef5fa9Smycroft 10322ef5fa9Smycroft* 10422ef5fa9Smycroft* t_dz, t_dz2 --- divide by zero exception 10522ef5fa9Smycroft* 10622ef5fa9Smycroft* t_dz2 is used by monadic functions such as flogn (from do_func). 10722ef5fa9Smycroft* t_dz is used by monadic functions such as satanh (from the 10822ef5fa9Smycroft* transcendental function). 10922ef5fa9Smycroft* 11022ef5fa9Smycroft xdef t_dz2 11122ef5fa9Smycroftt_dz2: 11222ef5fa9Smycroft fmovem.x mns_one,fp0 11322ef5fa9Smycroft fmove.l d1,fpcr 11422ef5fa9Smycroft fdiv.x pls_zero,fp0 11522ef5fa9Smycroft rts 11622ef5fa9Smycroft 11722ef5fa9Smycroft xdef t_dz 11822ef5fa9Smycroftt_dz: 11922ef5fa9Smycroft btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos 12022ef5fa9Smycroft beq.b p_inf ;branch if pos sign 12122ef5fa9Smycroftm_inf: 12222ef5fa9Smycroft fmovem.x mns_one,fp0 12322ef5fa9Smycroft fmove.l d1,fpcr 12422ef5fa9Smycroft fdiv.x pls_zero,fp0 12522ef5fa9Smycroft rts 12622ef5fa9Smycroftp_inf: 12722ef5fa9Smycroft fmovem.x pls_one,fp0 12822ef5fa9Smycroft fmove.l d1,fpcr 12922ef5fa9Smycroft fdiv.x pls_zero,fp0 13022ef5fa9Smycroft rts 13122ef5fa9Smycroft* 13222ef5fa9Smycroft* t_operr --- Operand Error exception 13322ef5fa9Smycroft* 13422ef5fa9Smycroft xdef t_operr 13522ef5fa9Smycroftt_operr: 13622ef5fa9Smycroft fmovem.x pls_inf,fp0 13722ef5fa9Smycroft fmove.l d1,fpcr 13822ef5fa9Smycroft fmul.x pls_zero,fp0 13922ef5fa9Smycroft rts 14022ef5fa9Smycroft 14122ef5fa9Smycroft* 14222ef5fa9Smycroft* t_unfl --- UNFL exception 14322ef5fa9Smycroft* 14422ef5fa9Smycroft xdef t_unfl 14522ef5fa9Smycroftt_unfl: 14622ef5fa9Smycroft btst.b #sign_bit,ETEMP(a6) 14722ef5fa9Smycroft beq.b unf_pos 14822ef5fa9Smycroftunf_neg: 14922ef5fa9Smycroft fmovem.x mns_tiny,fp0 15022ef5fa9Smycroft fmove.l d1,fpcr 15122ef5fa9Smycroft fmul.x pls_tiny,fp0 15222ef5fa9Smycroft rts 15322ef5fa9Smycroft 15422ef5fa9Smycroftunf_pos: 15522ef5fa9Smycroft fmovem.x pls_tiny,fp0 15622ef5fa9Smycroft fmove.l d1,fpcr 15722ef5fa9Smycroft fmul.x fp0,fp0 15822ef5fa9Smycroft rts 15922ef5fa9Smycroft* 16022ef5fa9Smycroft* t_ovfl --- OVFL exception 16122ef5fa9Smycroft* 16222ef5fa9Smycroft* t_ovfl is called as an exit for monadic functions. t_ovfl2 16322ef5fa9Smycroft* is for dyadic exits. 16422ef5fa9Smycroft* 16522ef5fa9Smycroft xdef t_ovfl 16622ef5fa9Smycroftt_ovfl: 16722ef5fa9Smycroft xdef t_ovfl2 16822ef5fa9Smycroft move.l d1,USER_FPCR(a6) user's control register 16922ef5fa9Smycroft move.l #ovfinx_mask,d0 17022ef5fa9Smycroft bra.b t_work 17122ef5fa9Smycroftt_ovfl2: 17222ef5fa9Smycroft move.l #ovfl_inx_mask,d0 17322ef5fa9Smycroftt_work: 17422ef5fa9Smycroft btst.b #sign_bit,ETEMP(a6) 17522ef5fa9Smycroft beq.b ovf_pos 17622ef5fa9Smycroftovf_neg: 17722ef5fa9Smycroft fmovem.x mns_huge,fp0 17822ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 17922ef5fa9Smycroft fmul.x pls_huge,fp0 18022ef5fa9Smycroft fmove.l fpsr,d1 18122ef5fa9Smycroft or.l d1,d0 18222ef5fa9Smycroft fmove.l d0,fpsr 18322ef5fa9Smycroft rts 18422ef5fa9Smycroftovf_pos: 18522ef5fa9Smycroft fmovem.x pls_huge,fp0 18622ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 18722ef5fa9Smycroft fmul.x pls_huge,fp0 18822ef5fa9Smycroft fmove.l fpsr,d1 18922ef5fa9Smycroft or.l d1,d0 19022ef5fa9Smycroft fmove.l d0,fpsr 19122ef5fa9Smycroft rts 19222ef5fa9Smycroft* 19322ef5fa9Smycroft* t_inx2 --- INEX2 exception (correct fpcr is in USER_FPCR(a6)) 19422ef5fa9Smycroft* 19522ef5fa9Smycroft xdef t_inx2 19622ef5fa9Smycroftt_inx2: 19722ef5fa9Smycroft fmove.l fpsr,USER_FPSR(a6) capture incoming fpsr 19822ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 19922ef5fa9Smycroft* 20022ef5fa9Smycroft* create an inex2 exception by adding two numbers with very different exponents 20122ef5fa9Smycroft* do the add in fp1 so as to not disturb the result sitting in fp0 20222ef5fa9Smycroft* 20322ef5fa9Smycroft fmove.x pls_one,fp1 20422ef5fa9Smycroft fadd.x small,fp1 20522ef5fa9Smycroft* 20622ef5fa9Smycroft or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX 20722ef5fa9Smycroft fmove.l USER_FPSR(a6),fpsr 20822ef5fa9Smycroft rts 20922ef5fa9Smycroft* 21022ef5fa9Smycroft* t_frcinx --- Force Inex2 (for monadic functions) 21122ef5fa9Smycroft* 21222ef5fa9Smycroft xdef t_frcinx 21322ef5fa9Smycroftt_frcinx: 21422ef5fa9Smycroft fmove.l fpsr,USER_FPSR(a6) capture incoming fpsr 21522ef5fa9Smycroft fmove.l d1,fpcr 21622ef5fa9Smycroft* 21722ef5fa9Smycroft* create an inex2 exception by adding two numbers with very different exponents 21822ef5fa9Smycroft* do the add in fp1 so as to not disturb the result sitting in fp0 21922ef5fa9Smycroft* 22022ef5fa9Smycroft fmove.x pls_one,fp1 22122ef5fa9Smycroft fadd.x small,fp1 22222ef5fa9Smycroft* 22322ef5fa9Smycroft or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX 22422ef5fa9Smycroft btst.b #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set 22522ef5fa9Smycroft beq.b no_uacc1 ;if clear, do not set aunfl 22622ef5fa9Smycroft bset.b #aunfl_bit,FPSR_AEXCEPT(a6) 22722ef5fa9Smycroftno_uacc1: 22822ef5fa9Smycroft fmove.l USER_FPSR(a6),fpsr 22922ef5fa9Smycroft rts 23022ef5fa9Smycroft* 23122ef5fa9Smycroft* dst_nan --- force result when destination is a NaN 23222ef5fa9Smycroft* 23322ef5fa9Smycroft xdef dst_nan 23422ef5fa9Smycroftdst_nan: 23522ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 23622ef5fa9Smycroft fmove.x FPTEMP(a6),fp0 23722ef5fa9Smycroft rts 23822ef5fa9Smycroft 23922ef5fa9Smycroft* 24022ef5fa9Smycroft* src_nan --- force result when source is a NaN 24122ef5fa9Smycroft* 24222ef5fa9Smycroft xdef src_nan 24322ef5fa9Smycroftsrc_nan: 24422ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 24522ef5fa9Smycroft fmove.x ETEMP(a6),fp0 24622ef5fa9Smycroft rts 24722ef5fa9Smycroft* 24822ef5fa9Smycroft* mon_nan --- force result when source is a NaN (monadic version) 24922ef5fa9Smycroft* 25022ef5fa9Smycroft* This is the same as src_nan except that the user's fpcr comes 25122ef5fa9Smycroft* in via d1, not USER_FPCR(a6). 25222ef5fa9Smycroft* 25322ef5fa9Smycroft xdef mon_nan 25422ef5fa9Smycroftmon_nan: 25522ef5fa9Smycroft fmove.l d1,fpcr 25622ef5fa9Smycroft fmove.x ETEMP(a6),fp0 25722ef5fa9Smycroft rts 25822ef5fa9Smycroft* 25922ef5fa9Smycroft* t_extdnrm, t_resdnrm --- generate results for denorm inputs 26022ef5fa9Smycroft* 26122ef5fa9Smycroft* For all functions that have a denormalized input and that f(x)=x, 26222ef5fa9Smycroft* this is the entry point. 26322ef5fa9Smycroft* 26422ef5fa9Smycroft xdef t_extdnrm 26522ef5fa9Smycroftt_extdnrm: 26622ef5fa9Smycroft fmove.l d1,fpcr 26722ef5fa9Smycroft fmove.x LOCAL_EX(a0),fp0 26822ef5fa9Smycroft fmove.l fpsr,d0 26922ef5fa9Smycroft or.l #unfinx_mask,d0 27022ef5fa9Smycroft fmove.l d0,fpsr 27122ef5fa9Smycroft rts 27222ef5fa9Smycroft 27322ef5fa9Smycroft xdef t_resdnrm 27422ef5fa9Smycroftt_resdnrm: 27522ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 27622ef5fa9Smycroft fmove.x LOCAL_EX(a0),fp0 27722ef5fa9Smycroft fmove.l fpsr,d0 27822ef5fa9Smycroft or.l #unfl_mask,d0 27922ef5fa9Smycroft fmove.l d0,fpsr 28022ef5fa9Smycroft rts 28122ef5fa9Smycroft* 28222ef5fa9Smycroft* 28322ef5fa9Smycroft* 28422ef5fa9Smycroft xdef t_avoid_unsupp 28522ef5fa9Smycroftt_avoid_unsupp: 28622ef5fa9Smycroft fmove.x fp0,fp0 28722ef5fa9Smycroft rts 28822ef5fa9Smycroft 28922ef5fa9Smycroft xdef sto_cos 29022ef5fa9Smycroftsto_cos: 29122ef5fa9Smycroft fmovem.x LOCAL_EX(a0),fp1 29222ef5fa9Smycroft rts 29322ef5fa9Smycroft* 29422ef5fa9Smycroft* Native instruction support 29522ef5fa9Smycroft* 29622ef5fa9Smycroft* Some systems may need entry points even for 68040 native 29722ef5fa9Smycroft* instructions. These routines are provided for 29822ef5fa9Smycroft* convenience. 29922ef5fa9Smycroft* 30022ef5fa9Smycroft xdef sadd 30122ef5fa9Smycroftsadd: 30222ef5fa9Smycroft fmovem.x FPTEMP(a6),fp0 30322ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 30422ef5fa9Smycroft fadd.x ETEMP(a6),fp0 30522ef5fa9Smycroft rts 30622ef5fa9Smycroft 30722ef5fa9Smycroft xdef ssub 30822ef5fa9Smycroftssub: 30922ef5fa9Smycroft fmovem.x FPTEMP(a6),fp0 31022ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 31122ef5fa9Smycroft fsub.x ETEMP(a6),fp0 31222ef5fa9Smycroft rts 31322ef5fa9Smycroft 31422ef5fa9Smycroft xdef smul 31522ef5fa9Smycroftsmul: 31622ef5fa9Smycroft fmovem.x FPTEMP(a6),fp0 31722ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 31822ef5fa9Smycroft fmul.x ETEMP(a6),fp0 31922ef5fa9Smycroft rts 32022ef5fa9Smycroft 32122ef5fa9Smycroft xdef sdiv 32222ef5fa9Smycroftsdiv: 32322ef5fa9Smycroft fmovem.x FPTEMP(a6),fp0 32422ef5fa9Smycroft fmove.l USER_FPCR(a6),fpcr 32522ef5fa9Smycroft fdiv.x ETEMP(a6),fp0 32622ef5fa9Smycroft rts 32722ef5fa9Smycroft 32822ef5fa9Smycroft xdef sabs 32922ef5fa9Smycroftsabs: 33022ef5fa9Smycroft fmovem.x ETEMP(a6),fp0 33122ef5fa9Smycroft fmove.l d1,fpcr 332eddb30abSmycroft fabs.x fp0 33322ef5fa9Smycroft rts 33422ef5fa9Smycroft 33522ef5fa9Smycroft xdef sneg 33622ef5fa9Smycroftsneg: 33722ef5fa9Smycroft fmovem.x ETEMP(a6),fp0 33822ef5fa9Smycroft fmove.l d1,fpcr 339eddb30abSmycroft fneg.x fp0 34022ef5fa9Smycroft rts 34122ef5fa9Smycroft 34222ef5fa9Smycroft xdef ssqrt 34322ef5fa9Smycroftssqrt: 34422ef5fa9Smycroft fmovem.x ETEMP(a6),fp0 34522ef5fa9Smycroft fmove.l d1,fpcr 346eddb30abSmycroft fsqrt.x fp0 34722ef5fa9Smycroft rts 34822ef5fa9Smycroft 34922ef5fa9Smycroft* 35022ef5fa9Smycroft* l_sint,l_sintrz,l_sintd --- special wrapper for fint and fintrz 35122ef5fa9Smycroft* 35222ef5fa9Smycroft* On entry, move the user's FPCR to USER_FPCR. 35322ef5fa9Smycroft* 35422ef5fa9Smycroft* On return from, we need to pickup the INEX2/AINEX bits 35522ef5fa9Smycroft* that are in USER_FPSR. 35622ef5fa9Smycroft* 35722ef5fa9Smycroft xref sint 35822ef5fa9Smycroft xref sintrz 35922ef5fa9Smycroft xref sintd 36022ef5fa9Smycroft 36122ef5fa9Smycroft xdef l_sint 36222ef5fa9Smycroftl_sint: 36322ef5fa9Smycroft move.l d1,USER_FPCR(a6) 36422ef5fa9Smycroft jsr sint 36522ef5fa9Smycroft fmove.l fpsr,d0 36622ef5fa9Smycroft or.l USER_FPSR(a6),d0 36722ef5fa9Smycroft fmove.l d0,fpsr 36822ef5fa9Smycroft rts 36922ef5fa9Smycroft 37022ef5fa9Smycroft xdef l_sintrz 37122ef5fa9Smycroftl_sintrz: 37222ef5fa9Smycroft move.l d1,USER_FPCR(a6) 37322ef5fa9Smycroft jsr sintrz 37422ef5fa9Smycroft fmove.l fpsr,d0 37522ef5fa9Smycroft or.l USER_FPSR(a6),d0 37622ef5fa9Smycroft fmove.l d0,fpsr 37722ef5fa9Smycroft rts 37822ef5fa9Smycroft 37922ef5fa9Smycroft xdef l_sintd 38022ef5fa9Smycroftl_sintd: 38122ef5fa9Smycroft move.l d1,USER_FPCR(a6) 38222ef5fa9Smycroft jsr sintd 38322ef5fa9Smycroft fmove.l fpsr,d0 38422ef5fa9Smycroft or.l USER_FPSR(a6),d0 38522ef5fa9Smycroft fmove.l d0,fpsr 38622ef5fa9Smycroft rts 38722ef5fa9Smycroft 38822ef5fa9Smycroft end 389