summaryrefslogtreecommitdiff
path: root/src/arch/arm/insts
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:14 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:14 -0500
commit86a1093992e686cac81db2555c477e2b4cad0c63 (patch)
tree41db50073d396c706c8e423f5be85706c348bea2 /src/arch/arm/insts
parente478df35f529eaa1390aec0f46b39e81ef3cdb90 (diff)
downloadgem5-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.hh75
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: