arch-arm: Use src/base/fenv.hh instead of raw fenv.h.

This provides a layer of indirection where the rounding mode
setting/getting code will do nothing if fenv.h isn't available. At build
time, if fenv.h can't be found, a warning is printed.

Also, the include for fenv.h was guarded in the includes in the ISA
header, but the functions from it weren't guarded in the actual code.

Finally, the code was setting the rounding mode, but not setting it
back. That would mean running these instructions would set the rounding
mode in gem5 as a whole, affecting its other behaviors and any other
instructions that might expect the default rounding mode.

Change-Id: Ic5cc32773652f423e66d78f31b80c6604f2c4a49
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41214
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Gabe Black
2021-02-11 19:19:55 -08:00
parent 1791b8732c
commit 8ff1dd9c9b
2 changed files with 14 additions and 11 deletions

View File

@@ -108,17 +108,12 @@ output exec {{
#include "arch/generic/memhelpers.hh"
#include "base/condcodes.hh"
#include "base/crc.hh"
#include "base/fenv.hh"
#include "cpu/base.hh"
#include "sim/pseudo_inst.hh"
#if defined(linux)
#include <fenv.h>
#endif
#include "debug/Arm.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/pseudo_inst.hh"
#include "sim/sim_exit.hh"
using namespace ArmISA;

View File

@@ -1106,11 +1106,13 @@ let {{
FPSCR fpscr = (FPSCR) FpscrExc;
vfpFlushToZero(fpscr, FpOp1);
VfpSavedState state = prepFpState(fpscr.rMode);
fesetround(FeRoundZero);
Gem5::RoundingMode old_rm = Gem5::getFpRound();
Gem5::setFpRound(Gem5::RoundingMode::TowardZero);
__asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
FpDest_uw = vfpFpToFixed<float>(
FpOp1, false, 32, 0, true, {round_mode});
__asm__ __volatile__("" :: "m" (FpDest_uw));
Gem5::setFpRound(old_rm);
finishVfp(fpscr, state, fpscr.fz);
FpscrExc = fpscr;
'''
@@ -1122,11 +1124,13 @@ let {{
double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
vfpFlushToZero(fpscr, cOp1);
VfpSavedState state = prepFpState(fpscr.rMode);
fesetround(FeRoundZero);
Gem5::RoundingMode old_rm = Gem5::getFpRound();
Gem5::setFpRound(Gem5::RoundingMode::TowardZero);
__asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
uint64_t result = vfpFpToFixed<double>(
cOp1, false, 32, 0, true, {round_mode});
__asm__ __volatile__("" :: "m" (result));
Gem5::setFpRound(old_rm);
finishVfp(fpscr, state, fpscr.fz);
FpDestP0_uw = result;
FpscrExc = fpscr;
@@ -1138,11 +1142,13 @@ let {{
FPSCR fpscr = (FPSCR) FpscrExc;
vfpFlushToZero(fpscr, FpOp1);
VfpSavedState state = prepFpState(fpscr.rMode);
fesetround(FeRoundZero);
Gem5::RoundingMode old_rm = Gem5::getFpRound();
Gem5::setFpRound(Gem5::RoundingMode::TowardZero);
__asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
FpDest_sw = vfpFpToFixed<float>(
FpOp1, true, 32, 0, true, {round_mode});
__asm__ __volatile__("" :: "m" (FpDest_sw));
Gem5::setFpRound(old_rm);
finishVfp(fpscr, state, fpscr.fz);
FpscrExc = fpscr;
'''
@@ -1154,11 +1160,13 @@ let {{
double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
vfpFlushToZero(fpscr, cOp1);
VfpSavedState state = prepFpState(fpscr.rMode);
fesetround(FeRoundZero);
Gem5::RoundingMode old_rm = Gem5::getFpRound();
Gem5::setFpRound(Gem5::RoundingMode::TowardZero);
__asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
int64_t result = vfpFpToFixed<double>(
cOp1, true, 32, 0, true, {round_mode});
__asm__ __volatile__("" :: "m" (result));
Gem5::setFpRound(old_rm);
finishVfp(fpscr, state, fpscr.fz);
FpDestP0_uw = result;
FpscrExc = fpscr;