base,arch-sparc: Overhaul the small fenv wrapper in base.

This was written in C, broke the style guide, used macros, used an
obsolete m5_ prefix, and used extern "C" in an odd way.

Change-Id: If38f9a1bca6fd4a4f7f533ddb1e81d6207bc9c44
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40878
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-02-07 09:00:58 -08:00
parent 41d934cf18
commit ab65690895
4 changed files with 54 additions and 35 deletions

View File

@@ -156,19 +156,27 @@ def format FpBasic(code, *flags) {{
exec_code = """
Fsr |= bits(Fsr, 4, 0) << 5;
Fsr = insertBits(Fsr, 4, 0, 0);
int newrnd = M5_FE_TONEAREST;
gem5::RoundingMode newrnd = gem5::RoundingMode::ToNearest;
switch (Fsr<31:30>) {
case 0: newrnd = M5_FE_TONEAREST; break;
case 1: newrnd = M5_FE_TOWARDZERO; break;
case 2: newrnd = M5_FE_UPWARD; break;
case 3: newrnd = M5_FE_DOWNWARD; break;
case 0:
newrnd = gem5::RoundingMode::ToNearest;
break;
case 1:
newrnd = gem5::RoundingMode::TowardZero;
break;
case 2:
newrnd = gem5::RoundingMode::Upward;
break;
case 3:
newrnd = gem5::RoundingMode::Downward;
break;
}
int oldrnd = m5_fegetround();
m5_fesetround(newrnd);
gem5::RoundingMode oldrnd = gem5::getFpRound();
gem5::setFpRound(newrnd);
__asm__ __volatile__("" ::: "memory");
fault = doFpOp(xc, traceData);
__asm__ __volatile__("" ::: "memory");
m5_fesetround(oldrnd);
gem5::setFpRound(oldrnd);
return fault;
"""
fp_code = filterDoubles(code)

View File

@@ -43,7 +43,7 @@ Executable('cprintftime', 'cprintftime.cc', 'cprintf.cc')
Source('debug.cc')
GTest('debug.test', 'debug.test.cc', 'debug.cc')
if env['USE_FENV']:
Source('fenv.c')
Source('fenv.cc')
else:
warning("No IEEE FP rounding mode control.\n"
"FP results may deviate slightly from other platforms.")

View File

@@ -1,4 +1,5 @@
/*
* Copyright 2021 Google Inc.
* Copyright (c) 2007 The Regents of The University of Michigan
* All rights reserved.
*
@@ -26,29 +27,28 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include "base/fenv.hh"
#include <fenv.h>
#include <stdlib.h>
void m5_fesetround(int rm);
int m5_fegetround();
#include <cstdlib>
static const int m5_round_ops[] = {FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD};
void m5_fesetround(int rm)
namespace gem5
{
assert(rm >= 0 && rm < 4);
fesetround(m5_round_ops[rm]);
}
int m5_fegetround()
static const int roundOps[] =
{ FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD };
void setFpRound(RoundingMode rm) { fesetround(roundOps[(int)rm]); }
RoundingMode
getFpRound()
{
int x;
int rm = fegetround();
for (x = 0; x < 4; x++)
if (m5_round_ops[x] == rm)
return x;
for (int x = 0; x < 4; x++)
if (roundOps[x] == rm)
return (RoundingMode)x;
abort();
return 0;
}
} // namespace gem5

View File

@@ -31,23 +31,34 @@
#include "config/use_fenv.hh"
#define M5_FE_DOWNWARD 0
#define M5_FE_TONEAREST 1
#define M5_FE_TOWARDZERO 2
#define M5_FE_UPWARD 3
namespace gem5
{
enum class RoundingMode
{
Downward = 0,
ToNearest = 1,
TowardZero = 2,
Upward = 3
};
#if USE_FENV
extern "C" {
void m5_fesetround(int rm);
int m5_fegetround();
}
void setFpRound(RoundingMode rm);
RoundingMode getFpRound();
#else
// Dummy definitions to allow code to compile w/o a real <fenv.h>.
inline void m5_fesetround(int rm) { ; }
inline int m5_fegetround() {return 0; }
static inline void setFpRound(RoundingMode rm) {}
static inline
RoundingMode getFpRound()
{
return RoundingMode::Downward;
}
#endif // USE_FENV
} // namespace gem5
#endif // __BASE_FENV_HH__