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.
This commit is contained in:
Andreas Sandberg 2013-09-19 17:30:26 +02:00
parent 4dbf25adc3
commit a6e723e4d6
2 changed files with 77 additions and 0 deletions

View file

@ -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)
{

View file

@ -142,6 +142,37 @@ namespace X86ISA
return *(uint64_t *)(&val);
}
/**
* 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.