OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems/] [c/] [src/] [lib/] [libcpu/] [m68k/] [m68040/] [fpsp/] [sint.S] - Rev 1765

Compare with Previous | Blame | View Log

//
//      $Id: sint.S,v 1.2 2001-09-27 12:01:22 chris Exp $
//
//      sint.sa 3.1 12/10/90
//
//      The entry point sINT computes the rounded integer 
//      equivalent of the input argument, sINTRZ computes 
//      the integer rounded to zero of the input argument.
//
//      Entry points sint and sintrz are called from do_func
//      to emulate the fint and fintrz unimplemented instructions,
//      respectively.  Entry point sintdo is used by bindec.
//
//      Input: (Entry points sint and sintrz) Double-extended
//              number X in the ETEMP space in the floating-point
//              save stack.
//             (Entry point sintdo) Double-extended number X in
//              location pointed to by the address register a0.
//             (Entry point sintd) Double-extended denormalized
//              number X in the ETEMP space in the floating-point
//              save stack.
//
//      Output: The function returns int(X) or intrz(X) in fp0.
//
//      Modifies: fp0.
//
//      Algorithm: (sint and sintrz)
//
//      1. If exp(X) >= 63, return X. 
//         If exp(X) < 0, return +/- 0 or +/- 1, according to
//         the rounding mode.
//      
//      2. (X is in range) set rsc = 63 - exp(X). Unnormalize the
//         result to the exponent $403e.
//
//      3. Round the result in the mode given in USER_FPCR. For
//         sintrz, force round-to-zero mode.
//
//      4. Normalize the rounded result; store in fp0.
//
//      For the denormalized cases, force the correct result
//      for the given sign and rounding mode.
//
//                      Sign(X)
//              RMODE   +    -
//              -----  --------
//               RN    +0   -0
//               RZ    +0   -0
//               RM    +0   -1
//               RP    +1   -0
//
//
//              Copyright (C) Motorola, Inc. 1990
//                      All Rights Reserved
//
//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 
//      The copyright notice above does not evidence any  
//      actual or intended publication of such source code.

//SINT    idnt    2,1 | Motorola 040 Floating Point Software Package

        |section        8

#include "fpsp.defs"

        |xref   dnrm_lp
        |xref   nrm_set
        |xref   round
        |xref   t_inx2
        |xref   ld_pone
        |xref   ld_mone
        |xref   ld_pzero
        |xref   ld_mzero
        |xref   snzrinx

//
//      FINT
//
        .global sint
sint:
        bfextu  FPCR_MODE(%a6){#2:#2},%d1       //use user's mode for rounding
//                                      ;implicitly has extend precision
//                                      ;in upper word. 
        movel   %d1,L_SCR1(%a6)         //save mode bits
        bras    sintexc                 

//
//      FINT with extended denorm inputs.
//
        .global sintd
sintd:
        btstb   #5,FPCR_MODE(%a6)
        beq     snzrinx         //if round nearest or round zero, +/- 0
        btstb   #4,FPCR_MODE(%a6)
        beqs    rnd_mns
rnd_pls:
        btstb   #sign_bit,LOCAL_EX(%a0)
        bnes    sintmz
        bsr     ld_pone         //if round plus inf and pos, answer is +1
        bra     t_inx2
rnd_mns:
        btstb   #sign_bit,LOCAL_EX(%a0)
        beqs    sintpz
        bsr     ld_mone         //if round mns inf and neg, answer is -1
        bra     t_inx2
sintpz:
        bsr     ld_pzero
        bra     t_inx2
sintmz:
        bsr     ld_mzero
        bra     t_inx2

//
//      FINTRZ
//
        .global sintrz
sintrz:
        movel   #1,L_SCR1(%a6)          //use rz mode for rounding
//                                      ;implicitly has extend precision
//                                      ;in upper word. 
        bras    sintexc                 
//
//      SINTDO
//
//      Input:  a0 points to an IEEE extended format operand
//      Output: fp0 has the result 
//
// Exceptions:
//
// If the subroutine results in an inexact operation, the inx2 and
// ainx bits in the USER_FPSR are set.
//
//
        .global sintdo
sintdo:
        bfextu  FPCR_MODE(%a6){#2:#2},%d1       //use user's mode for rounding
//                                      ;implicitly has ext precision
//                                      ;in upper word. 
        movel   %d1,L_SCR1(%a6)         //save mode bits
//
// Real work of sint is in sintexc
//
sintexc:
        bclrb   #sign_bit,LOCAL_EX(%a0) //convert to internal extended
//                                      ;format
        sne     LOCAL_SGN(%a0)          
        cmpw    #0x403e,LOCAL_EX(%a0)   //check if (unbiased) exp > 63
        bgts    out_rnge                        //branch if exp < 63
        cmpw    #0x3ffd,LOCAL_EX(%a0)   //check if (unbiased) exp < 0
        bgt     in_rnge                 //if 63 >= exp > 0, do calc
//
// Input is less than zero.  Restore sign, and check for directed
// rounding modes.  L_SCR1 contains the rmode in the lower byte.
//
un_rnge:
        btstb   #1,L_SCR1+3(%a6)                //check for rn and rz
        beqs    un_rnrz
        tstb    LOCAL_SGN(%a0)          //check for sign
        bnes    un_rmrp_neg
//
// Sign is +.  If rp, load +1.0, if rm, load +0.0
//
        cmpib   #3,L_SCR1+3(%a6)                //check for rp
        beqs    un_ldpone               //if rp, load +1.0
        bsr     ld_pzero                //if rm, load +0.0
        bra     t_inx2
un_ldpone:
        bsr     ld_pone
        bra     t_inx2
//
// Sign is -.  If rm, load -1.0, if rp, load -0.0
//
un_rmrp_neg:
        cmpib   #2,L_SCR1+3(%a6)                //check for rm
        beqs    un_ldmone               //if rm, load -1.0
        bsr     ld_mzero                //if rp, load -0.0
        bra     t_inx2
un_ldmone:
        bsr     ld_mone
        bra     t_inx2
//
// Rmode is rn or rz; return signed zero
//
un_rnrz:
        tstb    LOCAL_SGN(%a0)          //check for sign
        bnes    un_rnrz_neg
        bsr     ld_pzero
        bra     t_inx2
un_rnrz_neg:
        bsr     ld_mzero
        bra     t_inx2
        
//
// Input is greater than 2^63.  All bits are significant.  Return
// the input.
//
out_rnge:
        bfclr   LOCAL_SGN(%a0){#0:#8}   //change back to IEEE ext format
        beqs    intps
        bsetb   #sign_bit,LOCAL_EX(%a0)
intps:
        fmovel  %fpcr,-(%sp)
        fmovel  #0,%fpcr
        fmovex LOCAL_EX(%a0),%fp0       //if exp > 63
//                                      ;then return X to the user
//                                      ;there are no fraction bits
        fmovel  (%sp)+,%fpcr
        rts

in_rnge:
//                                      ;shift off fraction bits
        clrl    %d0                     //clear d0 - initial g,r,s for
//                                      ;dnrm_lp
        movel   #0x403e,%d1             //set threshold for dnrm_lp
//                                      ;assumes a0 points to operand
        bsr     dnrm_lp
//                                      ;returns unnormalized number
//                                      ;pointed by a0
//                                      ;output d0 supplies g,r,s
//                                      ;used by round
        movel   L_SCR1(%a6),%d1         //use selected rounding mode
//
//
        bsr     round                   //round the unnorm based on users
//                                      ;input  a0 ptr to ext X
//                                      ;       d0 g,r,s bits
//                                      ;       d1 PREC/MODE info
//                                      ;output a0 ptr to rounded result
//                                      ;inexact flag set in USER_FPSR
//                                      ;if initial grs set
//
// normalize the rounded result and store value in fp0
//
        bsr     nrm_set                 //normalize the unnorm
//                                      ;Input: a0 points to operand to
//                                      ;be normalized
//                                      ;Output: a0 points to normalized
//                                      ;result
        bfclr   LOCAL_SGN(%a0){#0:#8}
        beqs    nrmrndp
        bsetb   #sign_bit,LOCAL_EX(%a0) //return to IEEE extended format
nrmrndp:
        fmovel  %fpcr,-(%sp)
        fmovel  #0,%fpcr
        fmovex LOCAL_EX(%a0),%fp0       //move result to fp0
        fmovel  (%sp)+,%fpcr
        rts

        |end

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.