diff options
author | Andreas Sandberg <andreas@sandberg.pp.se> | 2013-09-19 17:30:26 +0200 |
---|---|---|
committer | Andreas Sandberg <andreas@sandberg.pp.se> | 2013-09-19 17:30:26 +0200 |
commit | a6e723e4d6240be496c284d3c4d7837850605e33 (patch) | |
tree | f6dcee294b2188241e1b34befd765c8f2f2e0e00 | |
parent | 4dbf25adc379d589c2aad9e62527d47a2ba62553 (diff) | |
download | gem5-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.
-rw-r--r-- | src/arch/x86/utility.cc | 46 | ||||
-rw-r--r-- | src/arch/x86/utility.hh | 31 |
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. * |