Skip to content

Commit

Permalink
Removed from math constructors the function was clearing all exceptio…
Browse files Browse the repository at this point in the history
…ns from FPU. Some crtbegin.c fixes
  • Loading branch information
afxgroup committed Aug 23, 2023
1 parent 47740cc commit 4cde3e4
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 125 deletions.
12 changes: 5 additions & 7 deletions library/crtbegin.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ static void CloseLibraryInterface(struct ExecIFace *iexec, struct Interface *int
struct Library *library = interface->Data.LibBase;

iexec->DropInterface(interface);
if (library != NULL)
interface = NULL;
if (library != NULL) {
iexec->CloseLibrary(library);
library = NULL;
}
}
}

Expand Down Expand Up @@ -152,10 +155,5 @@ clib2_start(char *args, int32 arglen, struct Library *sysbase) {

int
_start(STRPTR argstring, int32 arglen, struct Library *sysbase) {
SysBase = *(struct Library **) 4;
IExec = (struct ExecIFace *) ((struct ExecBase *) SysBase)->MainInterface;

int rc = clib2_start(argstring, arglen, sysbase);

return rc;
return clib2_start(argstring, arglen, sysbase);
}
177 changes: 141 additions & 36 deletions library/include/fenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,149 @@
#define __fenv_static static
#endif


#if defined __NO_FPRS__ && !defined _SOFT_FLOAT /* E500 */

/* Define bits representing the exception. We use the bit positions of
the appropriate bits in the SPEFSCR... */
enum
{
FE_INEXACT = 1 << (63 - 42),
#define FE_INEXACT FE_INEXACT
FE_INVALID = 1 << (63 - 43),
#define FE_INVALID FE_INVALID
FE_DIVBYZERO = 1 << (63 - 44),
#define FE_DIVBYZERO FE_DIVBYZERO
FE_UNDERFLOW = 1 << (63 - 45),
#define FE_UNDERFLOW FE_UNDERFLOW
FE_OVERFLOW = 1 << (63 - 46)
#define FE_OVERFLOW FE_OVERFLOW
};

#define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)

/* The E500 support all of the four defined rounding modes. We use
the bit pattern in the SPEFSCR as the values for the appropriate
macros. */
enum
{
FE_TONEAREST = 0,
#define FE_TONEAREST FE_TONEAREST
FE_TOWARDZERO = 1,
#define FE_TOWARDZERO FE_TOWARDZERO
FE_UPWARD = 2,
#define FE_UPWARD FE_UPWARD
FE_DOWNWARD = 3
#define FE_DOWNWARD FE_DOWNWARD
};

/* Type representing exception flags. */
typedef unsigned int fexcept_t;
typedef uint32_t fenv_t;
typedef uint32_t fexcept_t;
#else
/* Define bits representing the exception. We use the bit positions of
the appropriate bits in the FPSCR... */
enum
{
FE_INEXACT = 1 << (31 - 6),
#define FE_INEXACT FE_INEXACT
FE_DIVBYZERO = 1 << (31 - 5),
#define FE_DIVBYZERO FE_DIVBYZERO
FE_UNDERFLOW = 1 << (31 - 4),
#define FE_UNDERFLOW FE_UNDERFLOW
FE_OVERFLOW = 1 << (31 - 3),
#define FE_OVERFLOW FE_OVERFLOW

/* ... except for FE_INVALID, for which we use bit 31. FE_INVALID
actually corresponds to bits 7 through 12 and 21 through 23
in the FPSCR, but we can't use that because the current draft
says that it must be a power of 2. Instead we use bit 2 which
is the summary bit for all the FE_INVALID exceptions, which
kind of makes sense. */
FE_INVALID = 1 << (31 - 2),
#define FE_INVALID FE_INVALID

#ifdef __USE_GNU
/* Breakdown of the FE_INVALID bits. Setting FE_INVALID on an
input to a routine is equivalent to setting all of these bits;
FE_INVALID will be set on output from a routine iff one of
these bits is set. Note, though, that you can't disable or
enable these exceptions individually. */

/* Operation with SNaN. */
FE_INVALID_SNAN = 1 << (31 - 7),
# define FE_INVALID_SNAN FE_INVALID_SNAN

/* Inf - Inf */
FE_INVALID_ISI = 1 << (31 - 8),
# define FE_INVALID_ISI FE_INVALID_ISI

/* Inf / Inf */
FE_INVALID_IDI = 1 << (31 - 9),
# define FE_INVALID_IDI FE_INVALID_IDI

/* 0 / 0 */
FE_INVALID_ZDZ = 1 << (31 - 10),
# define FE_INVALID_ZDZ FE_INVALID_ZDZ

/* Inf * 0 */
FE_INVALID_IMZ = 1 << (31 - 11),
# define FE_INVALID_IMZ FE_INVALID_IMZ

/* Comparison with NaN or SNaN. */
FE_INVALID_COMPARE = 1 << (31 - 12),
# define FE_INVALID_COMPARE FE_INVALID_COMPARE

/* Invalid operation flag for software (not set by hardware). */
/* Note that some chips don't have this implemented, presumably
because no-one expected anyone to write software for them %-). */
FE_INVALID_SOFTWARE = 1 << (31 - 21),
# define FE_INVALID_SOFTWARE FE_INVALID_SOFTWARE

/* Square root of negative number (including -Inf). */
/* Note that some chips don't have this implemented. */
FE_INVALID_SQRT = 1 << (31 - 22),
# define FE_INVALID_SQRT FE_INVALID_SQRT

/* Conversion-to-integer of a NaN or a number too large or too small. */
FE_INVALID_INTEGER_CONVERSION = 1 << (31 - 23)
# define FE_INVALID_INTEGER_CONVERSION FE_INVALID_INTEGER_CONVERSION

# define FE_ALL_INVALID \
(FE_INVALID_SNAN | FE_INVALID_ISI | FE_INVALID_IDI | FE_INVALID_ZDZ \
| FE_INVALID_IMZ | FE_INVALID_COMPARE | FE_INVALID_SOFTWARE \
| FE_INVALID_SQRT | FE_INVALID_INTEGER_CONVERSION)
#endif
};

/* Exception flags */
#define FE_INEXACT 0x02000000
#define FE_DIVBYZERO 0x04000000
#define FE_UNDERFLOW 0x08000000
#define FE_OVERFLOW 0x10000000
#define FE_INVALID 0x20000000 /* all types of invalid FP ops */
#define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)

/*
* The PowerPC architecture has extra invalid flags that indicate the
* specific type of invalid operation occurred. These flags may be
* tested, set, and cleared---but not masked---separately. All of
* these bits are cleared when FE_INVALID is cleared, but only
* FE_VXSOFT is set when FE_INVALID is explicitly set in software.
*/
#define FE_VXCVI 0x00000100 /* invalid integer convert */
#define FE_VXSQRT 0x00000200 /* square root of a negative */
#define FE_VXSOFT 0x00000400 /* software-requested exception */
#define FE_VXVC 0x00080000 /* ordered comparison involving NaN */
#define FE_VXIMZ 0x00100000 /* inf * 0 */
#define FE_VXZDZ 0x00200000 /* 0 / 0 */
#define FE_VXIDI 0x00400000 /* inf / inf */
#define FE_VXISI 0x00800000 /* inf - inf */
#define FE_VXSNAN 0x01000000 /* operation on a signalling NaN */
#define FE_ALL_INVALID (FE_VXCVI | FE_VXSQRT | FE_VXSOFT | FE_VXVC | \
FE_VXIMZ | FE_VXZDZ | FE_VXIDI | FE_VXISI | \
FE_VXSNAN | FE_INVALID)
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
FE_ALL_INVALID | FE_OVERFLOW | FE_UNDERFLOW)

/* Rounding modes */
#define FE_TONEAREST 0x0000
#define FE_TOWARDZERO 0x0001
#define FE_UPWARD 0x0002
#define FE_DOWNWARD 0x0003
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
/* PowerPC chips support all of the four defined rounding modes. We
use the bit pattern in the FPSCR as the values for the
appropriate macros. */
enum
{
FE_TONEAREST = 0,
#define FE_TONEAREST FE_TONEAREST
FE_TOWARDZERO = 1,
#define FE_TOWARDZERO FE_TOWARDZERO
FE_UPWARD = 2,
#define FE_UPWARD FE_UPWARD
FE_DOWNWARD = 3
#define FE_DOWNWARD FE_DOWNWARD
};

/* Type representing exception flags. */
typedef unsigned int fexcept_t;

/* Type representing floating-point environment. We leave it as 'double'
for efficiency reasons (rather than writing it to a 32-bit integer). */
typedef uint32_t fenv_t;
#endif

#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)

__BEGIN_DECLS

Expand Down Expand Up @@ -140,7 +245,7 @@ feraiseexcept(int __excepts)
union __fpscr __r;

if (__excepts & FE_INVALID)
__excepts |= FE_VXSOFT;
__excepts |= FE_INVALID_SOFTWARE;
__mffs(&__r);
__r.__bits.__reg |= __excepts;
__mtfsf(__r);
Expand Down
4 changes: 0 additions & 4 deletions library/math/e_sqrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ __ieee754_sqrt(double x) {
double z;

#ifndef __SPE__
asm ("fsqrt %0,%1\n" :"=f" (z):"f" (x));
#else
int32_t sign = (int) 0x80000000;
int32_t ix0, s0, q, m, t, i;
uint32_t r, t1, s1, ix1, q1;

EXTRACT_WORDS(ix0, ix1, x);
printf("ix0 = %ld\n");
printf("ix1 = %ld\n");

/* take care of Inf and NaN */
if ((ix0 & 0x7ff00000) == 0x7ff00000) {
Expand Down
4 changes: 0 additions & 4 deletions library/math/e_sqrtf.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ __ieee754_sqrtf(float x) {
float z;

#ifndef __SPE__
asm ("fsqrts %0,%1\n" :"=f" (z):"f" (x));
#else
#if 0
int32_t sign = (int) 0x80000000;
int32_t ix, s, q, m, t, i;
uint32_t r;
Expand Down Expand Up @@ -165,7 +162,6 @@ __ieee754_sqrtf(float x) {
return (x - x) / (x - x); /* sqrt(-ve)=sNaN */
return 0x1p-256 * __ieee754_sqrt(x * 0x1p512);
}
#endif
#endif
return z;
}
16 changes: 2 additions & 14 deletions library/math/init_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,20 @@ __setfpucw(fpu_control_t set) {
}

MATH_CONSTRUCTOR(math_init) {
BOOL success = FALSE;
union ieee_single *single_x;
struct _clib2 *__clib2 = __CLIB2;

ENTER();

/* Clear fenv flags */
feclearexcept(FE_ALL_EXCEPT);
#ifdef __SPE__
__setfpucw(_FPU_RC_NEAREST);
#endif

/* Finally, fill in the constants behind INFINITY and NAN. */
single_x = (union ieee_single *) &__clib2->__infinity;
single_x->raw[0] = 0x7f800000;

single_x = (union ieee_single *) &__clib2->__nan;
single_x->raw[0] = 0x7fc00000;

success = TRUE;
single_x->raw[0] = 0x7fc00001;

SHOWVALUE(success);
LEAVE();

if (success)
CONSTRUCTOR_SUCCEED();
else
CONSTRUCTOR_FAIL();
CONSTRUCTOR_SUCCEED();
}
59 changes: 0 additions & 59 deletions library/math/root.tbl

This file was deleted.

2 changes: 1 addition & 1 deletion misc/control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: amigaos4-clib2
Version: 1.0.11
Version: 1.0.12
Maintainer: Andrea Palmatè <os4test@amigasoft.net>
Architecture: amd64
Section: libdevel
Expand Down

0 comments on commit 4cde3e4

Please sign in to comment.