* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: fpsim_support.s
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
/*==========================================================================*
* fpsim_support.s : assembly language routines used by FPSIM libraries.
* Author: Robert Rethemeyer
* (c) Copyright 2006 Sun Microsystems, Inc.
* This is a collection of functions that explicitly invoke the various
* SPARC floating-point instructions, using a supplied rounding mode,
* and returning the exception bits extracted from %fsr.cexc.
* Each routine is essentially a wrapper around the FP instruction.
* Why do this in assembly and not C? One or more of the following reasons:
* 1. No way to do it except using library calls (e.g. fiddling with %fsr)
* 2. C does not provide an easy way to do it (e.g. add & get carry)
* 3. The compiler may substitute its own code to satisfy the C standard
* 4. The compiler does not generate the intended code (e.g. for "D=S*S",
* it will generate FMULS followed by FSTOD, instead of FSMULD.
* These are all leaf subroutines that may use/trash registers:
* Exception bits are returned in %o0
* FP result is returned by Store using result pointer parameter.
* $Id: fpsim_support.s,v 1.5 2006/12/07 20:52:05 bobsmail Exp $
*==========================================================================*/
/*********************************************************************
* ATTENTION: This code is part of a library shared by multiple
* projects. DO NOT MAKE CHANGES TO THIS CODE WITHIN YOUR PROJECT.
* Instead, contact the owner/maintainer of the library, currently:
* Robert.Rethemeyer@Sun.COM +1-408-616-5717 (x45717)
* Systems Group: TVT: FrontEnd Technologies
* The CVS source code repository for the library is at:
* /import/ftap-blimp1/cvs/fpsim
* DO NOT COMMIT CHANGES TO THAT REPOSITORY: contact the maintainer.
********************************************************************/
#define FUNCTION(FNAME) .global FNAME; .type FNAME,#function; FNAME:
#define ENDFUNC(FNAME) .size FNAME,.-FNAME
1. save current FSR in caller-provided temp area (2 words)
2. mask off TEM, NS, CEXC bits
3. insert caller's rounding mode bits
5. save current GSR in g1
#define SET_ROUNDING(ROUND,TEMPFSR) \
3. load updated FSR in %o0
#define RESTORE_FSR(TEMPFSR) \
/*==========================================================================*/
! int asm_faddd( double* op1, double* op2, double* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fsubd( double* op1, double* op2, double* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fmuld( double* op1, double* op2, double* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fdivd( double* op1, double* op2, double* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fsqrtd( double* op2, double* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fadds( float* op1, float* op2, float* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fsubs( float* op1, float* op2, float* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fmuls( float* op1, float* op2, float* rslt, int rnd, int* tmp );
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fdivs( float* op1, float* op2, float* rslt, int rnd, int* tmp )
! %o0 %o0 %o1 %o2 %o3 %o4
/*==========================================================================*/
! int asm_fsqrts( float* op2, float* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fsmuld( float* op1, float* op2, double* rslt, int* tmp );
/*==========================================================================*/
! int asm_fstod( float* op2, double* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fdtos( double* op2, float* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fstox( float* op2, uint64* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fdtox( double* op2, uint64* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fstoi( float* op2, uint* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fdtoi( double* op2, uint* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fxtos( uint64* op2, float* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fxtod( uint64* op2, double* rslt, int rnd, int* tmp );
/*==========================================================================*/
! int asm_fitos( uint* op2, float* rslt, int rnd, int* tmp );
/*==========================================================================*/
! void asm_fitod( uint* op2, double* rslt );
/*==========================================================================*/
! Add 2 integers and return carry-out:
! int asm_addc( uint64 op1, uint64 op2, uint64* res );
addcc %o0, %o1, %o3 ! add
movcs %xcc, 1, %o0 ! get carry-out
/*==========================================================================*/
! Subtract 2 integers and return borrow-out:
! int asm_subc( uint64 op1, uint64 op2, uint64* res );
subcc %o0, %o1, %o3 ! sub
movcs %xcc, 1, %o0 ! get borrow-out