summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/utility.cc46
-rw-r--r--src/arch/x86/utility.hh31
2 files changed, 77 insertions, 0 deletions
diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc
index 3df948986..7f5ae980a 100644
--- a/src/arch/x86/utility.cc
+++ b/src/arch/x86/utility.cc
@@ -268,6 +268,52 @@ setRFlags(ThreadContext *tc, uint64_t val)
tc->setMiscReg(MISCREG_RFLAGS, val & ~(ccFlagMask | cfofMask | DFBit));
}
+uint8_t
+convX87TagsToXTags(uint16_t ftw)
+{
+ uint8_t ftwx(0);
+ for (int i = 0; i < 8; ++i) {
+ // Extract the tag for the current element on the FP stack
+ const unsigned tag((ftw >> (2 * i)) & 0x3);
+
+ /*
+ * Check the type of the current FP element. Valid values are:
+ * 0 == Valid
+ * 1 == Zero
+ * 2 == Special (Nan, unsupported, infinity, denormal)
+ * 3 == Empty
+ */
+ // The xsave version of the tag word only keeps track of
+ // whether the element is empty or not. Set the corresponding
+ // bit in the ftwx if it's not empty,
+ if (tag != 0x3)
+ ftwx |= 1 << i;
+ }
+
+ return ftwx;
+}
+
+uint16_t
+convX87XTagsToTags(uint8_t ftwx)
+{
+ uint16_t ftw(0);
+ for (int i = 0; i < 8; ++i) {
+ const unsigned xtag(((ftwx >> i) & 0x1));
+
+ // The xtag for an x87 stack position is 0 for empty stack positions.
+ if (!xtag) {
+ // Set the tag word to 3 (empty) for the current element.
+ ftw |= 0x3 << (2 * i);
+ } else {
+ // TODO: We currently assume that non-empty elements are
+ // valid (0x0), but we should ideally reconstruct the full
+ // state (valid/zero/special).
+ }
+ }
+
+ return ftw;
+}
+
uint16_t
genX87Tags(uint16_t ftw, uint8_t top, int8_t spm)
{
diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh
index 24aca3e0a..dcf61bddb 100644
--- a/src/arch/x86/utility.hh
+++ b/src/arch/x86/utility.hh
@@ -143,6 +143,37 @@ namespace X86ISA
}
/**
+ * Convert an x87 tag word to abridged tag format.
+ *
+ * Convert from the x87 tag representation to the tag abridged
+ * representation used in the FXSAVE area. The classic format uses
+ * 2 bits per stack position to indicate if a position is valid,
+ * zero, special, or empty. The abridged format only stores
+ * whether a position is empty or not.
+ *
+ * @param ftw Tag word in classic x87 format.
+ * @return Tag word in the abridged format.
+ */
+ uint8_t convX87TagsToXTags(uint16_t ftw);
+
+ /**
+ * Convert an x87 xtag word to normal tags format.
+ *
+ * Convert from the abridged x87 tag representation used in the
+ * FXSAVE area to a full x87 tag. The classic format uses 2 bits
+ * per stack position to indicate if a position is valid, zero,
+ * special, or empty. The abridged format only stores whether a
+ * position is empty or not.
+ *
+ * @todo Reconstruct the correct state of stack positions instead
+ * of just valid/invalid.
+ *
+ * @param ftwx Tag word in the abridged format.
+ * @return Tag word in classic x87 format.
+ */
+ uint16_t convX87XTagsToTags(uint8_t ftwx);
+
+ /**
* Generate and updated x87 tag register after a push/pop
* operation.
*