Skip to content

Commit

Permalink
Reworking SPE fenv functions
Browse files Browse the repository at this point in the history
  • Loading branch information
afxgroup committed Jul 27, 2023
1 parent 91f2fff commit 8278c1b
Show file tree
Hide file tree
Showing 4 changed files with 573 additions and 214 deletions.
14 changes: 7 additions & 7 deletions GNUmakefile.os4
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ AFLAGS := -Wa,-mregnames -mstrict-align
ifdef SPE
CC := ppc-amigaos-gcc-6.4.0
AS := ppc-amigaos-as-6.4.0
CFLAGS := $(CFLAGS) -D__SPE__ -mspe -mcpu=8540 -mabi=spe -mno-string -ffloat-store -mfloat-gprs=double -fno-inline-functions -fno-partial-inlining \
CFLAGS := $(CFLAGS) -D__SPE__ -mspe -mcpu=8540 -mabi=spe -mfloat-gprs=double -ffloat-store -fno-fast-math -fno-inline-functions -fno-partial-inlining \
-fno-align-functions -fno-align-jumps -fno-align-loops -fno-align-labels -fno-inline-small-functions -fno-indirect-inlining -Wno-overflow -Wno-unused-but-set-variable -Wno-uninitialized #-Wdouble-promotion
AFLAGS := $(AFLAGS) -D__SPE__ -mspe -mcpu=8540 -mfloat-gprs=double -ffloat-store -mno-string -Wno-overflow
AFLAGS := $(AFLAGS) -mvrsave -D__SPE__ -mspe -mcpu=8540 -ffloat-store -mfloat-gprs=double -fno-fast-math -Wno-overflow
endif

VERBOSE ?= @
Expand Down Expand Up @@ -306,24 +306,24 @@ endef
define COMPILE_SPE_REG
$(VERBOSE)@$(MAKEDIR) $(@D)
$(VERBOSE)echo -e "\rAssembling SPE with regnames \033[0;33m[$(@D)]\033[0m \r\t\t\t\t\t\t\t\t\t\t\t \033[0;31m$(@F)\033[0m"
$(VERBOSE)$(CC) $(AFLAGS) -mvrsave -mregnames -DVRSAVE -mspe -mcpu=8540 -mfloat-gprs=double -o $@ -c $< $(LOG_COMMAND)
$(VERBOSE)$(CC) $(AFLAGS) -mregnames -DVRSAVE -o $@ -c $< $(LOG_COMMAND)
endef

define COMPILE_SPE
$(VERBOSE)@$(MAKEDIR) $(@D)
$(VERBOSE)echo -e "\rPreprocessing and compiling SPE \033[0;33m[$(@D)]\033[0m \r\t\t\t\t\t\t\t\t\t\t\t \033[0;31m$(@F)\033[0m"
$(VERBOSE)$(CC) -c -mspe -mcpu=8540 -mfloat-gprs=double -mabi=spe $(CFLAGS) -mno-regnames -S -o $@_in $< $(LOG_COMMAND)
$(VERBOSE)$(CC) -c $(CFLAGS) -mno-regnames -S -o $@_in $< $(LOG_COMMAND)
$(VERBOSE)$(BUILD_DIR)/PatchForSPE $@_in $@.S >/dev/null
$(VERBOSE)$(CC) -mspe -mcpu=8540 -mfloat-gprs=double -mabi=spe $(CFLAGS) -c $@.S -o $@ $(LOG_COMMAND)
$(VERBOSE)$(CC) $(CFLAGS) -c $@.S -o $@ $(LOG_COMMAND)
$(VERBOSE)-$(DELETE) $@_in $@.S
endef

define COMPILE_SHARED_SPE
$(VERBOSE)@$(MAKEDIR) $(@D)
$(VERBOSE)echo -e "\rPreprocessing and compiling SPE \033[0;33m[$(@D)]\033[0m \r\t\t\t\t\t\t\t\t\t\t\t \033[0;31m$(@F)\033[0m"
$(VERBOSE)$(CC) -c -mspe -mcpu=8540 -mfloat-gprs=double $(PIC) -mabi=spe $(CFLAGS) -mno-regnames -S -o $@_in $< $(LOG_COMMAND)
$(VERBOSE)$(CC) -c $(PIC) -mabi=spe $(CFLAGS) -mno-regnames -S -o $@_in $< $(LOG_COMMAND)
$(VERBOSE)$(BUILD_DIR)/PatchForSPE $@_in $@.S >/dev/null
$(VERBOSE)$(CC) -mspe -mcpu=8540 -mfloat-gprs=double $(PIC) -mabi=spe $(CFLAGS) -c $@.S -o $@ $(LOG_COMMAND)
$(VERBOSE)$(CC) $(PIC) -mabi=spe $(CFLAGS) -c $@.S -o $@ $(LOG_COMMAND)
$(VERBOSE)-$(DELETE) $@_in $@.S
endef

Expand Down
209 changes: 28 additions & 181 deletions library/include/fenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
#include <features.h>
#include <endian.h>

#ifndef __fenv_static
#define __fenv_static static
#endif

typedef uint32_t fenv_t;
typedef uint32_t fexcept_t;

Expand Down Expand Up @@ -50,32 +46,29 @@ typedef uint32_t fexcept_t;
#define FE_TOWARDZERO 0x0001
#define FE_UPWARD 0x0002
#define FE_DOWNWARD 0x0003
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
FE_UPWARD | FE_TOWARDZERO)
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)

__BEGIN_DECLS

/* Default floating-point environment */
extern const fenv_t
__fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env)
extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env)

/* We need to be able to map status flag positions to mask flag positions */
#define _FPUSW_SHIFT 22
#define _ENABLE_MASK ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT)
#define _FPUSW_SHIFT 22
#define _ENABLE_MASK ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT)

#ifndef _SOFT_FLOAT
#ifdef __SPE__
#define __mffs(__env) __asm __volatile("mfspr %0, 512" : "=r" (*(__env)))
#define __mtfsf(__env) __asm __volatile("mtspr 512, %0; isync" :: "r" ((__env)))
#else
#define __mffs(__env) __asm __volatile("mffs %0" : "=f" (*(__env)))
#define __mtfsf(__env) __asm __volatile("mtfsf 255, %0" :: "f" ((__env)))
#endif
#ifdef __SPE__
#define __mffs(__env) __asm __volatile("mfspr %0, 512" : "=r" (*(__env)))
#define __mtfsf(__env) __asm __volatile("mtspr 512, %0; isync" :: "r" ((__env)))
#else
#define __mffs(__env)
#define __mtfsf(__env)
/* Equivalent to fegetenv, but returns an unsigned int instead of taking a pointer. */
#define fegetenv_register() \
({ unsigned int fscr; asm volatile ("mfspefscr %0" : "=r" (fscr)); fscr; })

/* Equivalent to fesetenv, but takes an unsigned int instead of a pointer. */
#define fesetenv_register(fscr) \
({ asm volatile ("mtspefscr %0" : : "r" (fscr)); })
#endif

union __fpscr {
Expand All @@ -91,166 +84,20 @@ union __fpscr {
} __bits;
};

__fenv_static inline int
feclearexcept(int __excepts) {
union __fpscr __r;

if (__excepts & FE_INVALID)
__excepts |= FE_ALL_INVALID;
__mffs(&__r.__d);
__r.__bits.__reg &= ~__excepts;
__mtfsf(__r.__d);
return (0);
}

__fenv_static inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts) {
union __fpscr __r;

__mffs(&__r.__d);
*__flagp = __r.__bits.__reg & __excepts;
return (0);
}

__fenv_static inline int
fesetexceptflag(const fexcept_t *__flagp, int __excepts) {
union __fpscr __r;

if (__excepts & FE_INVALID)
__excepts |= FE_ALL_EXCEPT;
__mffs(&__r.__d);
__r.__bits.__reg &= ~__excepts;
__r.__bits.__reg |= *__flagp & __excepts;
__mtfsf(__r.__d);
return (0);
}

#ifndef __SPE__
__fenv_static inline int
feraiseexcept(int __excepts) {
union __fpscr __r;

if (__excepts & FE_INVALID)
__excepts |= FE_VXSOFT;
__mffs(&__r.__d);
__r.__bits.__reg |= __excepts;
__mtfsf(__r.__d);
return (0);
}
#else
extern int feclearexcept(int __excepts);
extern int fegetexceptflag(fexcept_t *__flagp, int __excepts);
extern int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
extern int feraiseexcept(int __excepts);
#endif

__fenv_static inline int
fetestexcept(int __excepts) {
union __fpscr __r;

__mffs(&__r.__d);
return (__r.__bits.__reg & __excepts);
}

__fenv_static inline int
fegetround(void) {
union __fpscr __r;

__mffs(&__r.__d);
return (__r.__bits.__reg & _ROUND_MASK);
}

__fenv_static inline int
fesetround(int __round) {
union __fpscr __r;

if (__round & ~_ROUND_MASK)
return (-1);
__mffs(&__r.__d);
__r.__bits.__reg &= ~_ROUND_MASK;
__r.__bits.__reg |= __round;
__mtfsf(__r.__d);
return (0);
}

__fenv_static inline int
fegetenv(fenv_t * __envp) {
union __fpscr __r;

__mffs(&__r.__d);
*__envp = __r.__bits.__reg;
return (0);
}

__fenv_static inline int
feholdexcept(fenv_t * __envp) {
union __fpscr __r;

__mffs(&__r.__d);
*__envp = __r.__d;
__r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
__mtfsf(__r.__d);
return (0);
}

__fenv_static inline int
fesetenv(const fenv_t *__envp) {
union __fpscr __r;

__r.__bits.__reg = *__envp;
__mtfsf(__r.__d);
return (0);
}

__fenv_static inline int
feupdateenv(const fenv_t *__envp) {
union __fpscr __r;

__mffs(&__r.__d);
__r.__bits.__reg &= FE_ALL_EXCEPT;
__r.__bits.__reg |= *__envp;
__mtfsf(__r.__d);
return (0);
}

#if __BSD_VISIBLE

/* We currently provide no external definitions of the functions below. */

static inline int
feenableexcept(int __mask)
{
union __fpscr __r;
fenv_t __oldmask;

__mffs(&__r.__d);
__oldmask = __r.__bits.__reg;
__r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
__mtfsf(__r.__d);
return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
}

static inline int
fedisableexcept(int __mask)
{
union __fpscr __r;
fenv_t __oldmask;

__mffs(&__r.__d);
__oldmask = __r.__bits.__reg;
__r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
__mtfsf(__r.__d);
return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
}

static inline int
fegetexcept(void)
{
union __fpscr __r;

__mffs(&__r.__d);
return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
}

#endif /* __BSD_VISIBLE */

extern int fetestexcept(int __excepts);
extern int fegetround(void);
extern int fesetround(int __round);
extern int fegetenv(fenv_t *__envp);
extern int feholdexcept(fenv_t *__envp);
extern int fesetenv(const fenv_t *__envp);
extern int feupdateenv(const fenv_t *__envp);
extern int fegetexcept(void);
extern int feenableexcept(int __mask);
extern int fedisableexcept(int __mask);

__END_DECLS

Expand Down
Loading

0 comments on commit 8278c1b

Please sign in to comment.