Skip to content

Commit 4beac14

Browse files
committed
Fix the setting of the rounding mode
It would previously read the rounding mode, but wouldn't set it when it was not TONEAREST. That would work in most cases because TONEAREST is the default rounding mode in a process, and none of our tests would set it differently anyway.
1 parent 80c46ed commit 4beac14

18 files changed

+33
-58
lines changed

include/rvvlm.h

+33-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5+
#pragma once
6+
57
#include <stdbool.h>
68
#include <stdint.h>
79

@@ -35,18 +37,41 @@ union sui64_fp64 {
3537
#define UNIT_STRIDE 1
3638
#define GENERAL_STRIDE 2
3739

40+
#ifndef CSR_FRM
41+
#define CSR_FRM 0x002
42+
#endif
43+
44+
#ifndef FE_TONEAREST
45+
#define FE_TONEAREST 0x000
46+
#endif
47+
48+
49+
#define read_frm() \
50+
({ \
51+
unsigned long __value; \
52+
__asm__ __volatile__ ( \
53+
"frrm %0" : "=r" (__value) :: "memory"); \
54+
__value; \
55+
})
56+
57+
#define write_frm(value) \
58+
({ \
59+
unsigned long __value; \
60+
__asm__ __volatile__ ( \
61+
"fsrm %0, %1" : "=r" (__value) : "r" (CSR_FRM) : "memory"); \
62+
__value; \
63+
})
64+
3865
#define SET_ROUNDTONEAREST \
39-
int original_frm; \
40-
bool need_to_restore; \
41-
do { \
42-
(original_frm) = fegetround(); \
43-
need_to_restore = (original_frm != FE_TONEAREST); \
44-
} while (0)
66+
int __original_frm = read_frm(); \
67+
if (__original_frm != FE_TONEAREST) { \
68+
write_frm(FE_TONEAREST); \
69+
}
4570

4671
#define RESTORE_FRM \
4772
do { \
48-
if (need_to_restore) { \
49-
fesetround((original_frm)); \
73+
if (__original_frm != FE_TONEAREST) { \
74+
write_frm(__original_frm); \
5075
} \
5176
} while (0)
5277

include/rvvlm_acoshD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#define F_VER1 RVVLM_ACOSHDI_STD
1111
#endif
1212

13-
#include <fenv.h>
14-
1513
// Acosh(x) is defined for x >= 1 by the formula log(x + sqrt(x*x - 1))
1614
// and for the log function log(2^n z), we uses the expansion in terms of atanh
1715
// n log(2) + 2 atanh((z-1)/(z+1))

include/rvvlm_asincosD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5-
#include <fenv.h>
6-
75
#if defined(COMPILE_FOR_ASIN)
86
#if (STRIDE == UNIT_STRIDE)
97
#define F_VER1 RVVLM_ASIND_FIXEDPT
@@ -116,8 +114,6 @@ static_assert(false, "Must specify asin, acos, asinpi or acospi" __FILE__);
116114
} \
117115
} while (0)
118116

119-
#include <fenv.h>
120-
121117
// For asin/acos, the computation is of the form Const +/- (r + r*s*poly(s))
122118
// This version computes this entire expression in fixed point by converting
123119
// r and s into fixed point.

include/rvvlm_asinhcoshD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
#endif
1919
#endif
2020

21-
#include <fenv.h>
22-
2321
// Acosh(x) is defined for x >= 1 by the formula log(x + sqrt(x*x - 1))
2422
// Asinh(x) is defined for all finite x by the formula log(x + sqrt(x*x + 1))
2523
// Acosh is always positive, and Asinh(-x) = -Asinh(x). Thus we in general

include/rvvlm_atan2D.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5-
#include <fenv.h>
6-
75
#if defined(COMPILE_FOR_ATAN2)
86
#if (STRIDE == UNIT_STRIDE)
97
#define F_VER1 RVVLM_ATAN2D_FIXEDPT

include/rvvlm_atanD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5-
#include <fenv.h>
6-
75
#if defined(COMPILE_FOR_ATAN)
86
#if (STRIDE == UNIT_STRIDE)
97
#define F_VER1 RVVLM_ATAND_FIXEDPT
@@ -71,8 +69,6 @@ static_assert(false, "Must specify atan or atanpi" __FILE__);
7169
} \
7270
} while (0)
7371

74-
#include <fenv.h>
75-
7672
// For atan, atan(x) ~=~ r + r*s*poly(s), r = x and s = r*r for |x| < 1
7773
// and atan(x) = pi/2 - atan(1/x) for |x| >= 1
7874
// Thus atan(x) = (pi/2 or 0) +/- (r + r*s*poly(s)), where r is x or 1/x, s is

include/rvvlm_atanhD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#define F_VER1 RVVLM_ATANHDI_MIXED
1111
#endif
1212

13-
#include <fenv.h>
14-
1513
// Atanh(x) is defined only for |x| <= 1. As atanh(-x) = -atanh(x), the
1614
// main computation works with |x|.
1715
// For |x| > 1 and x being a sNaN, the invalid signal has to be generated

include/rvvlm_cbrtD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5-
#include <fenv.h>
6-
75
#if (STRIDE == UNIT_STRIDE)
86
#define F_VER1 RVVLM_CBRTD_ITER
97
#else
108
#define F_VER1 RVVLM_CBRTDI_ITER
119
#endif
1210

13-
#include <fenv.h>
14-
1511
#define EXCEPTION_HANDLING_CBRT(vx, special_args, vy_special, n_adjust, vlen) \
1612
do { \
1713
VUINT vclass = __riscv_vfclass((vx), (vlen)); \

include/rvvlm_expD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@
8686
static_assert(false, "Must specify base of exponential" __FILE__);
8787
#endif
8888

89-
#include <fenv.h>
90-
9189
// Version 1 is reduction to standard primary interval.
9290
// Reduced argument is represented as one FP64 variable.
9391
void F_VER1(API) {

include/rvvlm_expm1D.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
#define X_MAX 0x1.65p+9
3333
#define X_MIN -0x1.5p+5
3434

35-
#include <fenv.h>
36-
3735
// We use the EPsim version of expD to compute expm1
3836
void F_VER1(API) {
3937
size_t vlen;

include/rvvlm_log1pD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
#define LOG2_HI 0x1.62e42fefa39efp-1
3737
#define LOG2_LO 0x1.abc9e3b39803fp-56
3838

39-
#include <fenv.h>
40-
4139
// Version 1 uses a 128-entry LUT
4240
void F_VER1(API) {
4341
size_t vlen;

include/rvvlm_logD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@
7272
static_assert(false, "Must specify base of logarithm" __FILE__);
7373
#endif
7474

75-
#include <fenv.h>
76-
7775
// Version 1 uses a 128-entry LUT
7876
void F_VER1(API) {
7977
size_t vlen;

include/rvvlm_powD.inc.h

-2
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ static const double negtwo_to_65 = -0x1.0p65;
181181
#define F_VER1 RVVLM_POWDI_TBL
182182
#endif
183183

184-
#include <fenv.h>
185-
186184
// Version 1 is reduction to standard primary interval.
187185
// Reduced argument is represented as one FP64 variable.
188186
void F_VER1(API) {

include/rvvlm_sinandcosD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include "rvvlm_trigD.h"
66

7-
#include <fenv.h>
8-
97
#if defined(COMPILE_FOR_SINCOS)
108
#if (STRIDE == UNIT_STRIDE)
119
#define F_VER1 RVVLM_SINCOSD_STD
@@ -22,8 +20,6 @@
2220
static_assert(false, "Must specify sincos or sincospi" __FILE__);
2321
#endif
2422

25-
#include <fenv.h>
26-
2723
// This versions reduces argument to [-pi/4, pi/4] and computes sin(r) and
2824
// cos(r)
2925
void F_VER1(API) {

include/rvvlm_sincosD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include "rvvlm_trigD.h"
66

7-
#include <fenv.h>
8-
97
#if defined(COMPILE_FOR_SIN)
108
#if (STRIDE == UNIT_STRIDE)
119
#define F_VER1 RVVLM_SIND_MERGED
@@ -34,8 +32,6 @@
3432
static_assert(false, "Must specify sin, sinpi, cos or cospi" __FILE__);
3533
#endif
3634

37-
#include <fenv.h>
38-
3935
// This versions reduces argument to [-pi/4, pi/4] and computes sin(r) or cos(r)
4036
// by merging the appropriate coefficients into a vector register
4137
void F_VER1(API) {

include/rvvlm_sinhcoshD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include "rvvlm_hyperbolicsD.h"
66

7-
#include <fenv.h>
8-
97
#if defined(COMPILE_FOR_SINH)
108
#if (STRIDE == UNIT_STRIDE)
119
#define F_VER1 RVVLM_SINHD_STD
@@ -26,8 +24,6 @@
2624
static_assert(false, "Must specify sinh or cosh" __FILE__);
2725
#endif
2826

29-
#include <fenv.h>
30-
3127
// This versions reduces argument to [-log2/2, log2/2]
3228
// Exploit common expressions exp(R) and exp(-R), and uses purely
3329
// floating point method to preserve precision

include/rvvlm_tanD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include "rvvlm_trigD.h"
66

7-
#include <fenv.h>
8-
97
#if defined(COMPILE_FOR_TAN)
108
#if (STRIDE == UNIT_STRIDE)
119
#define F_VER1 RVVLM_TAND_MERGED
@@ -22,8 +20,6 @@
2220
static_assert(false, "Must specify tan or tanpi" __FILE__);
2321
#endif
2422

25-
#include <fenv.h>
26-
2723
// This versions reduces argument to [-pi/4, pi/4] and computes sin(r) or cos(r)
2824
// tan(x) is either sin(r)/cos(r) or -cos(r)/sin(r)
2925
void F_VER1(API) {

include/rvvlm_tanhD.inc.h

-4
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44

55
#include "rvvlm_hyperbolicsD.h"
66

7-
#include <fenv.h>
8-
97
#if (STRIDE == UNIT_STRIDE)
108
#define F_VER1 RVVLM_TANHD_STD
119
#else
1210
#define F_VER1 RVVLM_TANHDI_STD
1311
#endif
1412

15-
#include <fenv.h>
16-
1713
// This versions reduces argument to [-log2/2, log2/2]
1814
// Exploit common expressions exp(R) and exp(-R),
1915
// and uses purely floating-point computation

0 commit comments

Comments
 (0)