diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:14 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:14 -0500 |
commit | 86a1093992e686cac81db2555c477e2b4cad0c63 (patch) | |
tree | 41db50073d396c706c8e423f5be85706c348bea2 /src/arch/arm/insts | |
parent | e478df35f529eaa1390aec0f46b39e81ef3cdb90 (diff) | |
download | gem5-86a1093992e686cac81db2555c477e2b4cad0c63.tar.xz |
ARM: Add code to extract and record VFP exceptions.
Diffstat (limited to 'src/arch/arm/insts')
-rw-r--r-- | src/arch/arm/insts/vfp.hh | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/arch/arm/insts/vfp.hh b/src/arch/arm/insts/vfp.hh index 77e104a13..465384304 100644 --- a/src/arch/arm/insts/vfp.hh +++ b/src/arch/arm/insts/vfp.hh @@ -41,6 +41,8 @@ #define __ARCH_ARM_INSTS_VFP_HH__ #include "arch/arm/insts/misc.hh" +#include "arch/arm/miscregs.hh" +#include <fenv.h> enum VfpMicroMode { VfpNotAMicroop, @@ -73,6 +75,79 @@ setVfpMicroFlags(VfpMicroMode mode, T &flags) } } +enum FeExceptionBit +{ + FeDivByZero = FE_DIVBYZERO, + FeInexact = FE_INEXACT, + FeInvalid = FE_INVALID, + FeOverflow = FE_OVERFLOW, + FeUnderflow = FE_UNDERFLOW, + FeAllExceptions = FE_ALL_EXCEPT +}; + +enum FeRoundingMode +{ + FeRoundDown = FE_DOWNWARD, + FeRoundNearest = FE_TONEAREST, + FeRoundZero = FE_TOWARDZERO, + FeRoundUpward = FE_UPWARD +}; + +enum VfpRoundingMode +{ + VfpRoundNearest = 0, + VfpRoundUpward = 1, + VfpRoundDown = 2, + VfpRoundZero = 3 +}; + +typedef int VfpSavedState; + +static inline VfpSavedState +prepVfpFpscr(FPSCR fpscr) +{ + int roundingMode = fegetround(); + feclearexcept(FeAllExceptions); + switch (fpscr.rMode) { + case VfpRoundNearest: + fesetround(FeRoundNearest); + break; + case VfpRoundUpward: + fesetround(FeRoundUpward); + break; + case VfpRoundDown: + fesetround(FeRoundDown); + break; + case VfpRoundZero: + fesetround(FeRoundZero); + break; + } + return roundingMode; +} + +static inline FPSCR +setVfpFpscr(FPSCR fpscr, VfpSavedState state) +{ + int exceptions = fetestexcept(FeAllExceptions); + if (exceptions & FeInvalid) { + fpscr.ioc = 1; + } + if (exceptions & FeDivByZero) { + fpscr.dzc = 1; + } + if (exceptions & FeOverflow) { + fpscr.ofc = 1; + } + if (exceptions & FeUnderflow) { + fpscr.ufc = 1; + } + if (exceptions & FeInexact) { + fpscr.ixc = 1; + } + fesetround(state); + return fpscr; +} + class VfpMacroOp : public PredMacroOp { public: |