Commit db299c0d authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] PA-RISC math emu

Add support for unimplemented FP ops on PA processors.
parent af4d0bf6
#
# Makefile for the linux/parisc floating point code
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
obj-y := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \
dfmpy.o sfmpy.o sfsqrt.o dfsqrt.o dfadd.o fmpyfadd.o \
sfadd.o dfsub.o sfsub.o fcnvfxt.o fcnvff.o fcnvxf.o \
fcnvfx.o fcnvuf.o fcnvfu.o fcnvfut.o dfdiv.o sfdiv.o \
dfrem.o sfrem.o dfcmp.o sfcmp.o
# Math emulation code beyond the FRND is required for 712/80i and
# other very old or stripped-down PA-RISC CPUs -- not currently supported
obj-$CONFIG_MATH_EMULATION += unimplemented-math-emulation.o
include $(TOPDIR)/Rules.make
All files except driver.c are snapshots from the HP-UX kernel. They've
been modified as little as possible. Even though they don't fit the
Linux coding style, please leave them in their funny format just in case
someone in the future, with access to HP-UX source code, is generous
enough to update our copies with later changes from HP-UX -- it'll
make their 'diff' job easier if our code is relatively unmodified.
Required Disclaimer: Hewlett-Packard makes no implied or expressed
warranties about this code nor any promises to maintain or test it
in any way. This copy of this snapshot is no longer the property
of Hewlett-Packard.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/fp/denormal.c $ Revision: $
*
* Purpose:
* <<please update with a synopsis of the functionality provided by this file>>
*
* External Interfaces:
* <<the following list was autogenerated, please review>>
* dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
* sgl_denormalize(sgl_opnd,inexactflag,rmode)
*
* Internal Interfaces:
* <<please update>>
*
* Theory:
* <<please update with a overview of the operation of this file>>
*
* END_DESC
*/
#include "float.h"
#include "sgl_float.h"
#include "dbl_float.h"
#include "hppa.h"
#include "types.h"
/* #include <machine/sys/mdep_private.h> */
#undef Fpustatus_register
#define Fpustatus_register Fpu_register[0]
void
sgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
{
unsigned int opnd;
int sign, exponent;
boolean guardbit = FALSE, stickybit, inexact;
opnd = *sgl_opnd;
stickybit = *inexactflag;
exponent = Sgl_exponent(opnd) - SGL_WRAP;
sign = Sgl_sign(opnd);
Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
if (inexact) {
switch (rmode) {
case ROUNDPLUS:
if (sign == 0) {
Sgl_increment(opnd);
}
break;
case ROUNDMINUS:
if (sign != 0) {
Sgl_increment(opnd);
}
break;
case ROUNDNEAREST:
if (guardbit && (stickybit ||
Sgl_isone_lowmantissa(opnd))) {
Sgl_increment(opnd);
}
break;
}
}
Sgl_set_sign(opnd,sign);
*sgl_opnd = opnd;
*inexactflag = inexact;
return;
}
void
dbl_denormalize(unsigned int *dbl_opndp1,
unsigned int * dbl_opndp2,
boolean *inexactflag,
int rmode)
{
unsigned int opndp1, opndp2;
int sign, exponent;
boolean guardbit = FALSE, stickybit, inexact;
opndp1 = *dbl_opndp1;
opndp2 = *dbl_opndp2;
stickybit = *inexactflag;
exponent = Dbl_exponent(opndp1) - DBL_WRAP;
sign = Dbl_sign(opndp1);
Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
if (inexact) {
switch (rmode) {
case ROUNDPLUS:
if (sign == 0) {
Dbl_increment(opndp1,opndp2);
}
break;
case ROUNDMINUS:
if (sign != 0) {
Dbl_increment(opndp1,opndp2);
}
break;
case ROUNDNEAREST:
if (guardbit && (stickybit ||
Dbl_isone_lowmantissap2(opndp2))) {
Dbl_increment(opndp1,opndp2);
}
break;
}
}
Dbl_set_sign(opndp1,sign);
*dbl_opndp1 = opndp1;
*dbl_opndp2 = opndp2;
*inexactflag = inexact;
return;
}
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/spmath/dfcmp.c $Revision: 1.1 $
*
* Purpose:
* dbl_cmp: compare two values
*
* External Interfaces:
* dbl_fcmp(leftptr, rightptr, cond, status)
*
* Internal Interfaces:
*
* Theory:
* <<please update with a overview of the operation of this file>>
*
* END_DESC
*/
#include "float.h"
#include "dbl_float.h"
/*
* dbl_cmp: compare two values
*/
int
dbl_fcmp (dbl_floating_point * leftptr, dbl_floating_point * rightptr,
unsigned int cond, unsigned int *status)
/* The predicate to be tested */
{
register unsigned int leftp1, leftp2, rightp1, rightp2;
register int xorresult;
/* Create local copies of the numbers */
Dbl_copyfromptr(leftptr,leftp1,leftp2);
Dbl_copyfromptr(rightptr,rightp1,rightp2);
/*
* Test for NaN
*/
if( (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
|| (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) )
{
/* Check if a NaN is involved. Signal an invalid exception when
* comparing a signaling NaN or when comparing quiet NaNs and the
* low bit of the condition is set */
if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(leftp1,leftp2)
&& (Exception(cond) || Dbl_isone_signaling(leftp1)))
||
((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(rightp1,rightp2)
&& (Exception(cond) || Dbl_isone_signaling(rightp1))) )
{
if( Is_invalidtrap_enabled() ) {
Set_status_cbit(Unordered(cond));
return(INVALIDEXCEPTION);
}
else Set_invalidflag();
Set_status_cbit(Unordered(cond));
return(NOEXCEPTION);
}
/* All the exceptional conditions are handled, now special case
NaN compares */
else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(leftp1,leftp2))
||
((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(rightp1,rightp2)) )
{
/* NaNs always compare unordered. */
Set_status_cbit(Unordered(cond));
return(NOEXCEPTION);
}
/* infinities will drop down to the normal compare mechanisms */
}
/* First compare for unequal signs => less or greater or
* special equal case */
Dbl_xortointp1(leftp1,rightp1,xorresult);
if( xorresult < 0 )
{
/* left negative => less, left positive => greater.
* equal is possible if both operands are zeros. */
if( Dbl_iszero_exponentmantissa(leftp1,leftp2)
&& Dbl_iszero_exponentmantissa(rightp1,rightp2) )
{
Set_status_cbit(Equal(cond));
}
else if( Dbl_isone_sign(leftp1) )
{
Set_status_cbit(Lessthan(cond));
}
else
{
Set_status_cbit(Greaterthan(cond));
}
}
/* Signs are the same. Treat negative numbers separately
* from the positives because of the reversed sense. */
else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2))
{
Set_status_cbit(Equal(cond));
}
else if( Dbl_iszero_sign(leftp1) )
{
/* Positive compare */
if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
{
Set_status_cbit(Lessthan(cond));
}
else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
{
Set_status_cbit(Greaterthan(cond));
}
else
{
/* Equal first parts. Now we must use unsigned compares to
* resolve the two possibilities. */
if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) )
{
Set_status_cbit(Lessthan(cond));
}
else
{
Set_status_cbit(Greaterthan(cond));
}
}
}
else
{
/* Negative compare. Signed or unsigned compares
* both work the same. That distinction is only
* important when the sign bits differ. */
if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
{
Set_status_cbit(Lessthan(cond));
}
else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
{
Set_status_cbit(Greaterthan(cond));
}
else
{
/* Equal first parts. Now we must use unsigned compares to
* resolve the two possibilities. */
if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) )
{
Set_status_cbit(Lessthan(cond));
}
else
{
Set_status_cbit(Greaterthan(cond));
}
}
}
return(NOEXCEPTION);
}
This diff is collapsed.
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/spmath/dfrem.c $Revision: 1.1 $
*
* Purpose:
* Double Precision Floating-point Remainder
*
* External Interfaces:
* dbl_frem(srcptr1,srcptr2,dstptr,status)
*
* Internal Interfaces:
*
* Theory:
* <<please update with a overview of the operation of this file>>
*
* END_DESC
*/
#include "float.h"
#include "dbl_float.h"
/*
* Double Precision Floating-point Remainder
*/
int
dbl_frem (dbl_floating_point * srcptr1, dbl_floating_point * srcptr2,
dbl_floating_point * dstptr, unsigned int *status)
{
register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
register unsigned int resultp1, resultp2;
register int opnd1_exponent, opnd2_exponent, dest_exponent, stepcount;
register boolean roundup = FALSE;
Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
/*
* check first operand for NaN's or infinity
*/
if ((opnd1_exponent = Dbl_exponent(opnd1p1)) == DBL_INFINITY_EXPONENT) {
if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
/* invalid since first operand is infinity */
if (Is_invalidtrap_enabled())
return(INVALIDEXCEPTION);
Set_invalidflag();
Dbl_makequietnan(resultp1,resultp2);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
}
else {
/*
* is NaN; signaling or quiet?
*/
if (Dbl_isone_signaling(opnd1p1)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled())
return(INVALIDEXCEPTION);
/* make NaN quiet */
Set_invalidflag();
Dbl_set_quiet(opnd1p1);
}
/*
* is second operand a signaling NaN?
*/
else if (Dbl_is_signalingnan(opnd2p1)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled())
return(INVALIDEXCEPTION);
/* make NaN quiet */
Set_invalidflag();
Dbl_set_quiet(opnd2p1);
Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
return(NOEXCEPTION);
}
/*
* return quiet NaN
*/
Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
return(NOEXCEPTION);
}
}
/*
* check second operand for NaN's or infinity
*/
if ((opnd2_exponent = Dbl_exponent(opnd2p1)) == DBL_INFINITY_EXPONENT) {
if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
/*
* return first operand
*/
Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
return(NOEXCEPTION);
}
/*
* is NaN; signaling or quiet?
*/
if (Dbl_isone_signaling(opnd2p1)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
/* make NaN quiet */
Set_invalidflag();
Dbl_set_quiet(opnd2p1);
}
/*
* return quiet NaN
*/
Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
return(NOEXCEPTION);
}
/*
* check second operand for zero
*/
if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
/* invalid since second operand is zero */
if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
Set_invalidflag();
Dbl_makequietnan(resultp1,resultp2);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
/*
* get sign of result
*/
resultp1 = opnd1p1;
/*
* check for denormalized operands
*/
if (opnd1_exponent == 0) {
/* check for zero */
if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
return(NOEXCEPTION);
}
/* normalize, then continue */
opnd1_exponent = 1;
Dbl_normalize(opnd1p1,opnd1p2,opnd1_exponent);
}
else {
Dbl_clear_signexponent_set_hidden(opnd1p1);
}
if (opnd2_exponent == 0) {
/* normalize, then continue */
opnd2_exponent = 1;
Dbl_normalize(opnd2p1,opnd2p2,opnd2_exponent);
}
else {
Dbl_clear_signexponent_set_hidden(opnd2p1);
}
/* find result exponent and divide step loop count */
dest_exponent = opnd2_exponent - 1;
stepcount = opnd1_exponent - opnd2_exponent;
/*
* check for opnd1/opnd2 < 1
*/
if (stepcount < 0) {
/*
* check for opnd1/opnd2 > 1/2
*
* In this case n will round to 1, so
* r = opnd1 - opnd2
*/
if (stepcount == -1 &&
Dbl_isgreaterthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
/* set sign */
Dbl_allp1(resultp1) = ~Dbl_allp1(resultp1);
/* align opnd2 with opnd1 */
Dbl_leftshiftby1(opnd2p1,opnd2p2);
Dbl_subtract(opnd2p1,opnd2p2,opnd1p1,opnd1p2,
opnd2p1,opnd2p2);
/* now normalize */
while (Dbl_iszero_hidden(opnd2p1)) {
Dbl_leftshiftby1(opnd2p1,opnd2p2);
dest_exponent--;
}
Dbl_set_exponentmantissa(resultp1,resultp2,opnd2p1,opnd2p2);
goto testforunderflow;
}
/*
* opnd1/opnd2 <= 1/2
*
* In this case n will round to zero, so
* r = opnd1
*/
Dbl_set_exponentmantissa(resultp1,resultp2,opnd1p1,opnd1p2);
dest_exponent = opnd1_exponent;
goto testforunderflow;
}
/*
* Generate result
*
* Do iterative subtract until remainder is less than operand 2.
*/
while (stepcount-- > 0 && (Dbl_allp1(opnd1p1) || Dbl_allp2(opnd1p2))) {
if (Dbl_isnotlessthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
Dbl_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2,opnd1p1,opnd1p2);
}
Dbl_leftshiftby1(opnd1p1,opnd1p2);
}
/*
* Do last subtract, then determine which way to round if remainder
* is exactly 1/2 of opnd2
*/
if (Dbl_isnotlessthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
Dbl_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2,opnd1p1,opnd1p2);
roundup = TRUE;
}
if (stepcount > 0 || Dbl_iszero(opnd1p1,opnd1p2)) {
/* division is exact, remainder is zero */
Dbl_setzero_exponentmantissa(resultp1,resultp2);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
/*
* Check for cases where opnd1/opnd2 < n
*
* In this case the result's sign will be opposite that of
* opnd1. The mantissa also needs some correction.
*/
Dbl_leftshiftby1(opnd1p1,opnd1p2);
if (Dbl_isgreaterthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
Dbl_invert_sign(resultp1);
Dbl_leftshiftby1(opnd2p1,opnd2p2);
Dbl_subtract(opnd2p1,opnd2p2,opnd1p1,opnd1p2,opnd1p1,opnd1p2);
}
/* check for remainder being exactly 1/2 of opnd2 */
else if (Dbl_isequal(opnd1p1,opnd1p2,opnd2p1,opnd2p2) && roundup) {
Dbl_invert_sign(resultp1);
}
/* normalize result's mantissa */
while (Dbl_iszero_hidden(opnd1p1)) {
dest_exponent--;
Dbl_leftshiftby1(opnd1p1,opnd1p2);
}
Dbl_set_exponentmantissa(resultp1,resultp2,opnd1p1,opnd1p2);
/*
* Test for underflow
*/
testforunderflow:
if (dest_exponent <= 0) {
/* trap if UNDERFLOWTRAP enabled */
if (Is_underflowtrap_enabled()) {
/*
* Adjust bias of result
*/
Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
/* frem is always exact */
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(UNDERFLOWEXCEPTION);
}
/*
* denormalize result or set to signed zero
*/
if (dest_exponent >= (1 - DBL_P)) {
Dbl_rightshift_exponentmantissa(resultp1,resultp2,
1-dest_exponent);
}
else {
Dbl_setzero_exponentmantissa(resultp1,resultp2);
}
}
else Dbl_set_exponent(resultp1,dest_exponent);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/spmath/dfsqrt.c $Revision: 1.1 $
*
* Purpose:
* Double Floating-point Square Root
*
* External Interfaces:
* dbl_fsqrt(srcptr,nullptr,dstptr,status)
*
* Internal Interfaces:
*
* Theory:
* <<please update with a overview of the operation of this file>>
*
* END_DESC
*/
#include "float.h"
#include "dbl_float.h"
/*
* Double Floating-point Square Root
*/
/*ARGSUSED*/
unsigned int
dbl_fsqrt(
dbl_floating_point *srcptr,
unsigned int *nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
register unsigned int srcp1, srcp2, resultp1, resultp2;
register unsigned int newbitp1, newbitp2, sump1, sump2;
register int src_exponent;
register boolean guardbit = FALSE, even_exponent;
Dbl_copyfromptr(srcptr,srcp1,srcp2);
/*
* check source operand for NaN or infinity
*/
if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
/*
* is signaling NaN?
*/
if (Dbl_isone_signaling(srcp1)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
/* make NaN quiet */
Set_invalidflag();
Dbl_set_quiet(srcp1);
}
/*
* Return quiet NaN or positive infinity.
* Fall thru to negative test if negative infinity.
*/
if (Dbl_iszero_sign(srcp1) ||
Dbl_isnotzero_mantissa(srcp1,srcp2)) {
Dbl_copytoptr(srcp1,srcp2,dstptr);
return(NOEXCEPTION);
}
}
/*
* check for zero source operand
*/
if (Dbl_iszero_exponentmantissa(srcp1,srcp2)) {
Dbl_copytoptr(srcp1,srcp2,dstptr);
return(NOEXCEPTION);
}
/*
* check for negative source operand
*/
if (Dbl_isone_sign(srcp1)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
/* make NaN quiet */
Set_invalidflag();
Dbl_makequietnan(srcp1,srcp2);
Dbl_copytoptr(srcp1,srcp2,dstptr);
return(NOEXCEPTION);
}
/*
* Generate result
*/
if (src_exponent > 0) {
even_exponent = Dbl_hidden(srcp1);
Dbl_clear_signexponent_set_hidden(srcp1);
}
else {
/* normalize operand */
Dbl_clear_signexponent(srcp1);
src_exponent++;
Dbl_normalize(srcp1,srcp2,src_exponent);
even_exponent = src_exponent & 1;
}
if (even_exponent) {
/* exponent is even */
/* Add comment here. Explain why odd exponent needs correction */
Dbl_leftshiftby1(srcp1,srcp2);
}
/*
* Add comment here. Explain following algorithm.
*
* Trust me, it works.
*
*/
Dbl_setzero(resultp1,resultp2);
Dbl_allp1(newbitp1) = 1 << (DBL_P - 32);
Dbl_setzero_mantissap2(newbitp2);
while (Dbl_isnotzero(newbitp1,newbitp2) && Dbl_isnotzero(srcp1,srcp2)) {
Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,sump1,sump2);
if(Dbl_isnotgreaterthan(sump1,sump2,srcp1,srcp2)) {
Dbl_leftshiftby1(newbitp1,newbitp2);
/* update result */
Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,
resultp1,resultp2);
Dbl_subtract(srcp1,srcp2,sump1,sump2,srcp1,srcp2);
Dbl_rightshiftby2(newbitp1,newbitp2);
}
else {
Dbl_rightshiftby1(newbitp1,newbitp2);
}
Dbl_leftshiftby1(srcp1,srcp2);
}
/* correct exponent for pre-shift */
if (even_exponent) {
Dbl_rightshiftby1(resultp1,resultp2);
}
/* check for inexact */
if (Dbl_isnotzero(srcp1,srcp2)) {
if (!even_exponent && Dbl_islessthan(resultp1,resultp2,srcp1,srcp2)) {
Dbl_increment(resultp1,resultp2);
}
guardbit = Dbl_lowmantissap2(resultp2);
Dbl_rightshiftby1(resultp1,resultp2);
/* now round result */
switch (Rounding_mode()) {
case ROUNDPLUS:
Dbl_increment(resultp1,resultp2);
break;
case ROUNDNEAREST:
/* stickybit is always true, so guardbit
* is enough to determine rounding */
if (guardbit) {
Dbl_increment(resultp1,resultp2);
}
break;
}
/* increment result exponent by 1 if mantissa overflowed */
if (Dbl_isone_hiddenoverflow(resultp1)) src_exponent+=2;
if (Is_inexacttrap_enabled()) {
Dbl_set_exponent(resultp1,
((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(INEXACTEXCEPTION);
}
else Set_inexactflag();
}
else {
Dbl_rightshiftby1(resultp1,resultp2);
}
Dbl_set_exponent(resultp1,((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* linux/arch/math-emu/driver.c.c
*
* decodes and dispatches unimplemented FPU instructions
*
* Copyright (C) 1999, 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2001 Hewlett-Packard <bame@debian.org>
*/
#include <linux/config.h>
#include <linux/sched.h>
#include "float.h"
#include "math-emu.h"
#define fptpos 31
#define fpr1pos 10
#define extru(r,pos,len) (((r) >> (31-(pos))) & (( 1 << (len)) - 1))
#define FPUDEBUG 0
/* Format of the floating-point exception registers. */
struct exc_reg {
unsigned int exception : 6;
unsigned int ei : 26;
};
/* Macros for grabbing bits of the instruction format from the 'ei'
field above. */
/* Major opcode 0c and 0e */
#define FP0CE_UID(i) (((i) >> 6) & 3)
#define FP0CE_CLASS(i) (((i) >> 9) & 3)
#define FP0CE_SUBOP(i) (((i) >> 13) & 7)
#define FP0CE_SUBOP1(i) (((i) >> 15) & 7) /* Class 1 subopcode */
#define FP0C_FORMAT(i) (((i) >> 11) & 3)
#define FP0E_FORMAT(i) (((i) >> 11) & 1)
/* Major opcode 0c, uid 2 (performance monitoring) */
#define FPPM_SUBOP(i) (((i) >> 9) & 0x1f)
/* Major opcode 2e (fused operations). */
#define FP2E_SUBOP(i) (((i) >> 5) & 1)
#define FP2E_FORMAT(i) (((i) >> 11) & 1)
/* Major opcode 26 (FMPYSUB) */
/* Major opcode 06 (FMPYADD) */
#define FPx6_FORMAT(i) ((i) & 0x1f)
/* Flags and enable bits of the status word. */
#define FPSW_FLAGS(w) ((w) >> 27)
#define FPSW_ENABLE(w) ((w) & 0x1f)
#define FPSW_V (1<<4)
#define FPSW_Z (1<<3)
#define FPSW_O (1<<2)
#define FPSW_U (1<<1)
#define FPSW_I (1<<0)
/* Handle a floating point exception. Return zero if the faulting
instruction can be completed successfully. */
int
handle_fpe(struct pt_regs *regs)
{
extern void printbinary(unsigned long x, int nbits);
struct siginfo si;
unsigned int orig_sw, sw;
int signalcode;
/* need an intermediate copy of float regs because FPU emulation
* code expects an artificial last entry which contains zero
*/
__u64 frcopy[33];
memcpy(frcopy, regs->fr, sizeof regs->fr);
frcopy[32] = 0;
memcpy(&orig_sw, frcopy, sizeof(orig_sw));
if (FPUDEBUG) {
printk(KERN_DEBUG "FP VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI ->\n ");
printbinary(orig_sw, 32);
printk(KERN_DEBUG "\n");
}
signalcode = decode_fpu(frcopy, 0x666);
/* Status word = FR0L. */
memcpy(&sw, frcopy, sizeof(sw));
if (FPUDEBUG) {
printk(KERN_DEBUG "VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI decode_fpu returns %d|0x%x\n",
signalcode >> 24, signalcode & 0xffffff);
printbinary(sw, 32);
printk(KERN_DEBUG "\n");
}
memcpy(regs->fr, frcopy, sizeof regs->fr);
if (signalcode != 0) {
si.si_signo = signalcode >> 24;
si.si_errno = 0;
si.si_code = signalcode & 0xffffff;
si.si_addr = (void *) regs->iaoq[0];
force_sig_info(si.si_signo, &si, current);
return -1;
}
return signalcode ? -1 : 0;
}
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/spmath/fcnvff.c $Revision: 1.1 $
*
* Purpose:
* Single Floating-point to Double Floating-point
* Double Floating-point to Single Floating-point
*
* External Interfaces:
* dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
* sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
*
* Internal Interfaces:
*
* Theory:
* <<please update with a overview of the operation of this file>>
*
* END_DESC
*/
#include "float.h"
#include "sgl_float.h"
#include "dbl_float.h"
#include "cnv_float.h"
/*
* Single Floating-point to Double Floating-point
*/
/*ARGSUSED*/
int
sgl_to_dbl_fcnvff(
sgl_floating_point *srcptr,
unsigned int *nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
register unsigned int src, resultp1, resultp2;
register int src_exponent;
src = *srcptr;
src_exponent = Sgl_exponent(src);
Dbl_allp1(resultp1) = Sgl_all(src); /* set sign of result */
/*
* Test for NaN or infinity
*/
if (src_exponent == SGL_INFINITY_EXPONENT) {
/*
* determine if NaN or infinity
*/
if (Sgl_iszero_mantissa(src)) {
/*
* is infinity; want to return double infinity
*/
Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
else {
/*
* is NaN; signaling or quiet?
*/
if (Sgl_isone_signaling(src)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled())
return(INVALIDEXCEPTION);
/* make NaN quiet */
else {
Set_invalidflag();
Sgl_set_quiet(src);
}
}
/*
* NaN is quiet, return as double NaN
*/
Dbl_setinfinity_exponent(resultp1);
Sgl_to_dbl_mantissa(src,resultp1,resultp2);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
}
/*
* Test for zero or denormalized
*/
if (src_exponent == 0) {
/*
* determine if zero or denormalized
*/
if (Sgl_isnotzero_mantissa(src)) {
/*
* is denormalized; want to normalize
*/
Sgl_clear_signexponent(src);
Sgl_leftshiftby1(src);
Sgl_normalize(src,src_exponent);
Sgl_to_dbl_exponent(src_exponent,resultp1);
Sgl_to_dbl_mantissa(src,resultp1,resultp2);
}
else {
Dbl_setzero_exponentmantissa(resultp1,resultp2);
}
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
/*
* No special cases, just complete the conversion
*/
Sgl_to_dbl_exponent(src_exponent, resultp1);
Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
Dbl_copytoptr(resultp1,resultp2,dstptr);
return(NOEXCEPTION);
}
/*
* Double Floating-point to Single Floating-point
*/
/*ARGSUSED*/
int
dbl_to_sgl_fcnvff(
dbl_floating_point *srcptr,
unsigned int *nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
register unsigned int srcp1, srcp2, result;
register int src_exponent, dest_exponent, dest_mantissa;
register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
register boolean lsb_odd = FALSE;
boolean is_tiny;
Dbl_copyfromptr(srcptr,srcp1,srcp2);
src_exponent = Dbl_exponent(srcp1);
Sgl_all(result) = Dbl_allp1(srcp1); /* set sign of result */
/*
* Test for NaN or infinity
*/
if (src_exponent == DBL_INFINITY_EXPONENT) {
/*
* determine if NaN or infinity
*/
if (Dbl_iszero_mantissa(srcp1,srcp2)) {
/*
* is infinity; want to return single infinity
*/
Sgl_setinfinity_exponentmantissa(result);
*dstptr = result;
return(NOEXCEPTION);
}
/*
* is NaN; signaling or quiet?
*/
if (Dbl_isone_signaling(srcp1)) {
/* trap if INVALIDTRAP enabled */
if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
else {
Set_invalidflag();
/* make NaN quiet */
Dbl_set_quiet(srcp1);
}
}
/*
* NaN is quiet, return as single NaN
*/
Sgl_setinfinity_exponent(result);
Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
*dstptr = result;
return(NOEXCEPTION);
}
/*
* Generate result
*/
Dbl_to_sgl_exponent(src_exponent,dest_exponent);
if (dest_exponent > 0) {
Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit,
stickybit,lsb_odd);
}
else {
if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
Sgl_setzero_exponentmantissa(result);
*dstptr = result;
return(NOEXCEPTION);
}
if (Is_underflowtrap_enabled()) {
Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
guardbit,stickybit,lsb_odd);
}
else {
/* compute result, determine inexact info,
* and set Underflowflag if appropriate
*/
Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
is_tiny);
}
}
/*
* Now round result if not exact
*/
if (inexact) {
switch (Rounding_mode()) {
case ROUNDPLUS:
if (Sgl_iszero_sign(result)) dest_mantissa++;
break;
case ROUNDMINUS:
if (Sgl_isone_sign(result)) dest_mantissa++;
break;
case ROUNDNEAREST:
if (guardbit) {
if (stickybit || lsb_odd) dest_mantissa++;
}
}
}
Sgl_set_exponentmantissa(result,dest_mantissa);
/*
* check for mantissa overflow after rounding
*/
if ((dest_exponent>0 || Is_underflowtrap_enabled()) &&
Sgl_isone_hidden(result)) dest_exponent++;
/*
* Test for overflow
*/
if (dest_exponent >= SGL_INFINITY_EXPONENT) {
/* trap if OVERFLOWTRAP enabled */
if (Is_overflowtrap_enabled()) {
/*
* Check for gross overflow
*/
if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP)
return(UNIMPLEMENTEDEXCEPTION);
/*
* Adjust bias of result
*/
Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
*dstptr = result;
if (inexact)
if (Is_inexacttrap_enabled())
return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
else Set_inexactflag();
return(OVERFLOWEXCEPTION);
}
Set_overflowflag();
inexact = TRUE;
/* set result to infinity or largest number */
Sgl_setoverflow(result);
}
/*
* Test for underflow
*/
else if (dest_exponent <= 0) {
/* trap if UNDERFLOWTRAP enabled */
if (Is_underflowtrap_enabled()) {
/*
* Check for gross underflow
*/
if (dest_exponent <= -(SGL_WRAP))
return(UNIMPLEMENTEDEXCEPTION);
/*
* Adjust bias of result
*/
Sgl_setwrapped_exponent(result,dest_exponent,unfl);
*dstptr = result;
if (inexact)
if (Is_inexacttrap_enabled())
return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
else Set_inexactflag();
return(UNDERFLOWEXCEPTION);
}
/*
* result is denormalized or signed zero
*/
if (inexact && is_tiny) Set_underflowflag();
}
else Sgl_set_exponent(result,dest_exponent);
*dstptr = result;
/*
* Trap if inexact trap is enabled
*/
if (inexact)
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
else Set_inexactflag();
return(NOEXCEPTION);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __NO_PA_HDRS
PA header file -- do not include this header file for non-PA builds.
#endif
/*
* These macros are designed to be portable to all machines that have
* a wordsize greater than or equal to 32 bits that support the portable
* C compiler and the standard C preprocessor. Wordsize (default 32)
* and bitfield assignment (default left-to-right, unlike VAX, PDP-11)
* should be predefined using the constants HOSTWDSZ and BITFRL and
* the C compiler "-D" flag (e.g., -DHOSTWDSZ=36 -DBITFLR for the DEC-20).
* Note that the macro arguments assume that the integer being referenced
* is a 32-bit integer (right-justified on the 20) and that bit 0 is the
* most significant bit.
*/
#ifndef HOSTWDSZ
#define HOSTWDSZ 32
#endif
/*########################### Macros ######################################*/
/*-------------------------------------------------------------------------
* NewDeclareBitField_Reference - Declare a structure similar to the simulator
* function "DeclBitfR" except its use is restricted to occur within a larger
* enclosing structure or union definition. This declaration is an unnamed
* structure with the argument, name, as the member name and the argument,
* uname, as the element name.
*----------------------------------------------------------------------- */
#define Bitfield_extract(start, length, object) \
((object) >> (HOSTWDSZ - (start) - (length)) & \
((unsigned)-1 >> (HOSTWDSZ - (length))))
#define Bitfield_signed_extract(start, length, object) \
((int)((object) << start) >> (HOSTWDSZ - (length)))
#define Bitfield_mask(start, len, object) \
((object) & (((unsigned)-1 >> (HOSTWDSZ-len)) << (HOSTWDSZ-start-len)))
#define Bitfield_deposit(value,start,len,object) object = \
((object) & ~(((unsigned)-1 >> (HOSTWDSZ-len)) << (HOSTWDSZ-start-len))) | \
(((value) & ((unsigned)-1 >> (HOSTWDSZ-len))) << (HOSTWDSZ-start-len))
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/fp/fpu.h $Revision: 1.1 $
*
* Purpose:
* <<please update with a synopis of the functionality provided by this file>>
*
*
* END_DESC
*/
#ifdef __NO_PA_HDRS
PA header file -- do not include this header file for non-PA builds.
#endif
#ifndef _MACHINE_FPU_INCLUDED /* allows multiple inclusion */
#define _MACHINE_FPU_INCLUDED
#if 0
#ifndef _SYS_STDSYMS_INCLUDED
# include <sys/stdsyms.h>
#endif /* _SYS_STDSYMS_INCLUDED */
#include <machine/pdc/pdc_rqsts.h>
#endif
#define PA83_FPU_FLAG 0x00000001
#define PA89_FPU_FLAG 0x00000002
#define PA2_0_FPU_FLAG 0x00000010
#define TIMEX_EXTEN_FLAG 0x00000004
#define ROLEX_EXTEN_FLAG 0x00000008
#define COPR_FP 0x00000080 /* Floating point -- Coprocessor 0 */
#define SFU_MPY_DIVIDE 0x00008000 /* Multiply/Divide __ SFU 0 */
#define EM_FPU_TYPE_OFFSET 272
/* version of EMULATION software for COPR,0,0 instruction */
#define EMULATION_VERSION 4
/*
* The only was to differeniate between TIMEX and ROLEX (or PCX-S and PCX-T)
* is thorough the potential type field from the PDC_MODEL call. The
* following flags are used at assist this differeniation.
*/
#define ROLEX_POTENTIAL_KEY_FLAGS PDC_MODEL_CPU_KEY_WORD_TO_IO
#define TIMEX_POTENTIAL_KEY_FLAGS (PDC_MODEL_CPU_KEY_QUAD_STORE | \
PDC_MODEL_CPU_KEY_RECIP_SQRT)
#endif /* ! _MACHINE_FPU_INCLUDED */
This diff is collapsed.
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __NO_PA_HDRS
PA header file -- do not include this header file for non-PA builds.
#endif
/* amount is assumed to be a constant between 0 and 32 (non-inclusive) */
#define Shiftdouble(left,right,amount,dest) \
/* int left, right, amount, dest; */ \
dest = ((left) << (32-(amount))) | ((unsigned int)(right) >> (amount))
/* amount must be less than 32 */
#define Variableshiftdouble(left,right,amount,dest) \
/* unsigned int left, right; int amount, dest; */ \
if (amount == 0) dest = right; \
else dest = ((((unsigned) left)&0x7fffffff) << (32-(amount))) | \
((unsigned) right >> (amount))
/* amount must be between 0 and 32 (non-inclusive) */
#define Variable_shift_double(left,right,amount,dest) \
/* unsigned int left, right; int amount, dest; */ \
dest = (left << (32-(amount))) | ((unsigned) right >> (amount))
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _PARISC_MATH_EMU_H
#define _PARISC_MATH_EMU_H
#include <asm/ptrace.h>
extern int handle_fpe(struct pt_regs *regs);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#define BUG() do { \
printk(KERN_ERR "floating-pt emulation BUG at %s:%d!\n", __FILE__, __LINE__); \
} while (0)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment