summaryrefslogtreecommitdiff
path: root/src/arch/x86/utility.cc
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas@sandberg.pp.se>2013-09-19 17:30:26 +0200
committerAndreas Sandberg <andreas@sandberg.pp.se>2013-09-19 17:30:26 +0200
commita6e723e4d6240be496c284d3c4d7837850605e33 (patch)
treef6dcee294b2188241e1b34befd765c8f2f2e0e00 /src/arch/x86/utility.cc
parent4dbf25adc379d589c2aad9e62527d47a2ba62553 (diff)
downloadgem5-a6e723e4d6240be496c284d3c4d7837850605e33.tar.xz
x86: Add support routines to convert between x87 tag formats
This changeset adds the convX87XTagsToTags() and convX87TagsToXTags() which convert between the tag formats in the FTW register and the format used in the xsave area. The conversion from to the x87 FTW representation is currently loses some information since it does not reconstruct the valid/zero/special flags which are not included in the xsave representation.
Diffstat (limited to 'src/arch/x86/utility.cc')
-rw-r--r--src/arch/x86/utility.cc46
1 files changed, 46 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)
{