mirror of
https://github.com/deadw00d/AROS.git
synced 2025-12-09 07:34:27 +00:00
215 lines
5.2 KiB
C
215 lines
5.2 KiB
C
/*
|
|
Copyright (C) 1995-2001, The AROS Development Team. All rights reserved.
|
|
*/
|
|
|
|
#include <aros/libcall.h>
|
|
#include <exec/types.h>
|
|
#include <proto/mathieeedoubbas.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include "mathieeedoubbas_intern.h"
|
|
|
|
#undef double
|
|
|
|
/*
|
|
Problem (ONLY on Linux/M68K with binary compatibility turned on):
|
|
In order to get binary compatibility with the original Amiga OS
|
|
we have to return the value in D0/D1. This is NOT automatically
|
|
done by the compiler. The result would be returned in one of the
|
|
FPU registers instead. So we're using the trick with the QUADs.
|
|
See below.
|
|
*/
|
|
|
|
/*
|
|
!!! Fixme !!!
|
|
Problem on i386 etc:
|
|
The functions in the *.arch file (integer-emulation of double
|
|
operations) return QUADs. The protos however say that these functions
|
|
are returning doubles. Unfortunately doubles are not returned like
|
|
QUADs!
|
|
*/
|
|
//#define UseRegisterArgs 1
|
|
#if UseRegisterArgs
|
|
#define RETURN_TYPE QUAD /* For Linux/M68k & AmigaOS w/ bin. compat. */
|
|
#else
|
|
#define RETURN_TYPE double /* for the rest */
|
|
#endif
|
|
|
|
AROS_LHDOUBLE1(LONG, FPU_IEEEDPFix,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 5, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
return (LONG)y;
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPFix */
|
|
|
|
AROS_LHDOUBLE1(RETURN_TYPE, FPU_IEEEDPFlt,
|
|
AROS_LHA2(LONG, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 6, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
#if UseRegisterArgs
|
|
double d;
|
|
QUAD * Res = (QUAD *)&d; /* this forces the returned value to be in D0/D1 */
|
|
d = (double)y;
|
|
return * Res;
|
|
#else
|
|
return (double)y;
|
|
#endif
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPFlt */
|
|
|
|
AROS_LHDOUBLE2(LONG, FPU_IEEEDPCmp,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
AROS_LHA2(double, z, D2, D3),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 7, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
|
|
if (y == z) return 0;
|
|
if (y > z) return 1;
|
|
return -1;
|
|
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPCmp */
|
|
|
|
AROS_LHDOUBLE1(LONG, FPU_IEEEDPTst,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 8, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
|
|
if (0.0 == y) return 0;
|
|
if (y > 0) return 1;
|
|
return -1;
|
|
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPTst */
|
|
|
|
AROS_LHDOUBLE1(RETURN_TYPE, FPU_IEEEDPAbs,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 9, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
|
|
#if UseRegisterArgs
|
|
QUAD * Res = (QUAD *)&y; /* this forces the returned value to be in D0/D1 */
|
|
y=abs(y);
|
|
return * Res;
|
|
#else
|
|
return abs(y);
|
|
#endif
|
|
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPAbs */
|
|
|
|
AROS_LHDOUBLE1(RETURN_TYPE, FPU_IEEEDPNeg,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 10, MathIeeeDoubBas)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
#if UseRegisterArgs
|
|
QUAD * Res = (QUAD *)&y; /* this forces the returned value to be in D0/D1 */
|
|
y = -y;
|
|
return * Res;
|
|
#else
|
|
return -y;
|
|
#endif
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPNeg */
|
|
|
|
AROS_LHDOUBLE2(RETURN_TYPE, FPU_IEEEDPAdd,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
AROS_LHA2(double, z, D2, D3),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 11, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
#if UseRegisterArgs
|
|
QUAD * Res = (QUAD *)&y; /* this forces the returned value to be in D0/D1 */
|
|
y=y+z;
|
|
return * Res;
|
|
#else
|
|
return (y+z);
|
|
#endif
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPAdd */
|
|
|
|
AROS_LHDOUBLE2(RETURN_TYPE, FPU_IEEEDPSub,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
AROS_LHA2(double, z, D2, D3),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 12, MathIeeeDoubBas)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
#if UseRegisterArgs
|
|
QUAD * Res = (QUAD *)&y; /* this forces the returned value to be in D0/D1 */
|
|
y=y-z;
|
|
return * Res;
|
|
#else
|
|
return (y-z);
|
|
#endif
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPSub */
|
|
|
|
AROS_LHDOUBLE2(RETURN_TYPE, FPU_IEEEDPMul,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
AROS_LHA2(double, z, D2, D3),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 13, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
#if UseRegisterArgs
|
|
QUAD * Res = (QUAD *)&y; /* this forces the returned value to be in D0/D1 */
|
|
y=y*z;
|
|
return * Res;
|
|
#else
|
|
return y*z;
|
|
#endif
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPMul */
|
|
|
|
AROS_LHDOUBLE2(RETURN_TYPE, FPU_IEEEDPDiv,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
AROS_LHA2(double, z, D2, D3),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 14, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
#if UseRegisterArgs
|
|
QUAD * Res = (QUAD *)&y; /* this forces the returned value to be in D0/D1 */
|
|
y = y/z;
|
|
return * Res;
|
|
#else
|
|
return (y/z);
|
|
#endif
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPDiv */
|
|
|
|
AROS_LHDOUBLE1(RETURN_TYPE, FPU_IEEEDPFloor,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 15, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
/* return floor(y); */
|
|
return 0xbadc0deULL;
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPFloor */
|
|
|
|
AROS_LHDOUBLE1(RETURN_TYPE, FPU_IEEEDPCeil,
|
|
AROS_LHA2(double, y, D0, D1),
|
|
struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 16, MathIeeeDoubBas
|
|
)
|
|
{
|
|
AROS_LIBFUNC_INIT
|
|
/* return ceil(y); */
|
|
return 0xbadc0deULL;
|
|
AROS_LIBFUNC_EXIT
|
|
} /* FPU_IEEEDPCeil */
|