RISC-V: Support Zfinx/Zdinx extension.

Zfinx/Zdinx are new extensions ratified in 2022, it similar to F/D extensions,
support hard float operation for single/double precision, but the difference
between Zfinx/Zdinx and F/D is Zfinx/Zdinx is operating under general purpose
registers rather than dedicated floating-point registers.

This patch improve the hard float support detection for RISC-V port, so
that Zfinx/Zdinx can have better/right performance.

Co-authored-by: Jesse Huang <jesse.huang@sifive.com>
This commit is contained in:
Kito Cheng via Newlib 2023-07-26 18:03:19 +08:00 committed by Corinna Vinschen
parent fcc87263c4
commit d572c4482b
42 changed files with 97 additions and 60 deletions

View File

@ -218,10 +218,10 @@
#else
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined (__riscv_zfinx)
# define _SUPPORTS_ERREXCEPT
#endif
#if __riscv_flen == 64
#if (__riscv_flen == 64) || defined (__riscv_zdinx)
# define __OBSOLETE_MATH_DEFAULT 0
#else
# define __OBSOLETE_MATH_DEFAULT 1

View File

@ -11,7 +11,7 @@
#include <ieeefp.h>
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined (__riscv_zfinx)
static void
fssr(unsigned value)
{
@ -85,7 +85,7 @@ fpgetmask(void)
fp_rnd
fpgetround(void)
{
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined (__riscv_zfinx)
unsigned rm = (frsr () >> 5) & 0x7;
return frm_fp_rnd (rm);
#else
@ -96,7 +96,7 @@ fpgetround(void)
fp_except
fpgetsticky(void)
{
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined (__riscv_zfinx)
return frm_fp_except(frsr ());
#else
return 0;
@ -112,7 +112,7 @@ fpsetmask(fp_except mask)
fp_rnd
fpsetround(fp_rnd rnd_dir)
{
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined (__riscv_zfinx)
unsigned fsr = frsr ();
unsigned rm = (fsr >> 5) & 0x7;
unsigned new_rm;
@ -134,7 +134,7 @@ fpsetround(fp_rnd rnd_dir)
fp_except
fpsetsticky(fp_except sticky)
{
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined (__riscv_zfinx)
unsigned fsr = frsr ();
fssr (frm_except(sticky) | (fsr & ~0x1f));
return frm_fp_except(fsr);

View File

@ -14,7 +14,7 @@
#include <stddef.h>
#if __riscv_flen
#if defined(__riscv_f) || defined(__riscv_zfinx)
/* Per "The RISC-V Instruction Set Manual: Volume I: User-Level ISA:
* Version 2.1", Section 8.2, "Floating-Point Control and Status

View File

@ -72,7 +72,8 @@
/* Compiler can inline fma as a single instruction. */
#ifndef HAVE_FAST_FMA
# if __aarch64__ || (__ARM_FEATURE_FMA && (__ARM_FP & 8)) || __riscv_flen >= 64
# if __aarch64__ || (__ARM_FEATURE_FMA && (__ARM_FP & 8)) \
|| __riscv_flen >= 64 || defined (__riscv_zdinx)
# define HAVE_FAST_FMA 1
# else
# define HAVE_FAST_FMA 0
@ -80,7 +81,8 @@
#endif
#ifndef HAVE_FAST_FMAF
# if HAVE_FAST_FMA || (__ARM_FEATURE_FMA && (__ARM_FP & 4)) || __riscv_flen >= 32
# if HAVE_FAST_FMA || (__ARM_FEATURE_FMA && (__ARM_FP & 4)) \
|| __riscv_flen >= 32 || defined (__riscv_zfinx)
# define HAVE_FAST_FMAF 1
# else
# define HAVE_FAST_FMAF 0

View File

@ -36,7 +36,7 @@
#include <math.h>
#include "math_config.h"
#if defined(__riscv_fsqrt) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
double
__ieee754_sqrt (double x)

View File

@ -36,7 +36,7 @@
#include <math.h>
#include "math_config.h"
#if defined(__riscv_fsqrt) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
float
__ieee754_sqrtf (float x)

View File

@ -33,6 +33,7 @@
#include <fenv.h>
#include <stddef.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -47,7 +48,7 @@
int feclearexcept(int excepts)
{
#if __riscv_flen
#if __RISCV_HARD_FLOAT
/* Mask excepts to be sure only supported flag bits are set */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -47,7 +48,7 @@
int fegetenv(fenv_t *envp)
{
#if __riscv_flen
#if __RISCV_HARD_FLOAT
/* Get the current environment (FCSR) */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -48,7 +49,7 @@
int fegetexceptflag(fexcept_t *flagp, int excepts)
{
#if __riscv_flen
#if __RISCV_HARD_FLOAT
/* Mask excepts to be sure only supported flag bits are set */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -45,7 +46,7 @@
int fegetround()
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Get current rounding mode */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -49,7 +50,7 @@
int feholdexcept(fenv_t *envp)
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Store the current FP environment in envp*/

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -58,7 +59,7 @@ int feraiseexcept(int excepts)
excepts &= FE_ALL_EXCEPT;
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Set the requested exception flags */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -54,7 +55,7 @@
int fesetenv(const fenv_t *envp)
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Set environment (FCSR) */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -53,7 +54,7 @@
int fesetexceptflag(const fexcept_t *flagp, int excepts)
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Mask excepts to be sure only supported flag bits are set */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -48,7 +49,7 @@
int fesetround(int round)
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Mask round to be sure only valid rounding bits are set */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -47,7 +48,7 @@
int fetestexcept(int excepts)
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Mask excepts to be sure only supported flag bits are set */

View File

@ -32,6 +32,7 @@
*/
#include <fenv.h>
#include "riscv_math.h"
/* This implementation is intended to comply with the following
* specification:
@ -50,7 +51,7 @@
int feupdateenv(const fenv_t *envp)
{
#if __riscv_flen
#ifdef __RISCV_HARD_FLOAT
/* Get current exception flags */

View File

@ -38,7 +38,13 @@
#ifdef __riscv_flen
#if defined(__riscv_flen) || defined(__riscv_zfinx)
#if (__riscv_flen >= 64) || defined(__riscv_zdinx)
#define __RISCV_HARD_FLOAT 64
#else
#define __RISCV_HARD_FLOAT 32
#endif
#define FCLASS_NEG_INF (1 << 0)
#define FCLASS_NEG_NORMAL (1 << 1)
@ -58,7 +64,7 @@
#define FCLASS_SUBNORMAL (FCLASS_NEG_SUBNORMAL | FCLASS_POS_SUBNORMAL)
#define FCLASS_NAN (FCLASS_SNAN | FCLASS_QNAN)
#if __riscv_flen >= 64
#if (__riscv_flen >= 64) || defined(__riscv_zdinx)
static inline long _fclass_d(double x){
long fclass;
__asm __volatile ("fclass.d\t%0, %1" : "=r" (fclass) : "f" (x));
@ -66,7 +72,7 @@ static inline long _fclass_d(double x){
}
#endif
#if __riscv_flen >= 32
#if (__riscv_flen >= 32) || defined(__riscv_zfinx)
static inline long _fclass_f(float x){
long fclass;
__asm __volatile ("fclass.s\t%0, %1" : "=r" (fclass) : "f" (x));

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
double
copysign (double x, double y)

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
double
fabs (double x)

View File

@ -38,8 +38,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
#include "riscv_math.h"
int finite(double x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
double
fmax (double x, double y)

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
double
fmin (double x, double y)

View File

@ -33,11 +33,10 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <math.h>
#if defined(__riscv_flen) && __riscv_flen >= 64
#include "riscv_math.h"
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
int
__fpclassifyd (double x)
{

View File

@ -35,10 +35,10 @@
#include <math.h>
#include <ieeefp.h>
#if defined(__riscv_flen) && __riscv_flen >= 64
#include "riscv_math.h"
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
#undef isinf
int

View File

@ -35,10 +35,10 @@
#include <math.h>
#include <ieeefp.h>
#if defined(__riscv_flen) && __riscv_flen >= 64
#include "riscv_math.h"
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
#undef isnan
int

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64 && __riscv_xlen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64 && __riscv_xlen >= 64
long long int
llrint (double x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64 && __riscv_xlen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64 && __riscv_xlen >= 64
long long int
llround(double x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
long int
lrint (double x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 64
long int
lround (double x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
float
copysignf (float x, float y)

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
float
fabsf (float x)

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
#include "riscv_math.h"
int finitef(float x)

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
float
fmaxf (float x, float y)

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
float
fminf (float x, float y)

View File

@ -33,8 +33,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
#include "riscv_math.h"

View File

@ -35,10 +35,10 @@
#include <math.h>
#include <ieeefp.h>
#if defined(__riscv_flen) && __riscv_flen >= 32
#include "riscv_math.h"
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
#undef isinff
int

View File

@ -35,10 +35,10 @@
#include <math.h>
#include <ieeefp.h>
#if defined(__riscv_flen) && __riscv_flen >= 32
#include "riscv_math.h"
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
#undef isnanf
int

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32 && __riscv_xlen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32 && __riscv_xlen >= 64
long long int
llrintf (float x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32 && __riscv_xlen >= 64
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32 && __riscv_xlen >= 64
long long int
llroundf (float x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
long int
lrintf (float x)
{

View File

@ -34,8 +34,9 @@
*/
#include <math.h>
#include "riscv_math.h"
#if defined(__riscv_flen) && __riscv_flen >= 32
#if defined(__RISCV_HARD_FLOAT) && __RISCV_HARD_FLOAT >= 32
long int
lroundf(float x)
{