diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 101 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/x86_traits.hh | 3 |
3 files changed, 104 insertions, 1 deletions
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index dc6819886..017ac49e4 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -884,6 +884,107 @@ let {{ } ''' + class Sld(RegOp): + code = ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); + uint8_t dataBits = dataSize * 8; + uint8_t realShiftAmt = shiftAmt % (2 * dataBits); + uint64_t result; + if (realShiftAmt == 0) { + result = psrc1; + } else if (realShiftAmt < dataBits) { + result = (psrc1 << realShiftAmt) | + (DoubleBits >> (dataBits - realShiftAmt)); + } else { + result = (DoubleBits << (realShiftAmt - dataBits)) | + (psrc1 >> (2 * dataBits - realShiftAmt)); + } + DestReg = merge(DestReg, result, dataSize); + ''' + flag_code = ''' + // If the shift amount is zero, no flags should be modified. + if (shiftAmt) { + //Zero out any flags we might modify. This way we only have to + //worry about setting them. + ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); + int CFBits = 0; + //Figure out if we -would- set the CF bits if requested. + if ((realShiftAmt == 0 && + bits(DoubleBits, 0)) || + (realShiftAmt <= dataBits && + bits(SrcReg1, dataBits - realShiftAmt)) || + (realShiftAmt > dataBits && + bits(DoubleBits, 2 * dataBits - realShiftAmt))) { + CFBits = 1; + } + //If some combination of the CF bits need to be set, set them. + if ((ext & (CFBit | ECFBit)) && CFBits) + ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + //Figure out what the OF bit should be. + if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ + bits(result, dataBits - 1))) + ccFlagBits = ccFlagBits | OFBit; + //Use the regular mechanisms to calculate the other flags. + ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), + DestReg, psrc1, op2); + } + ''' + + class Srd(RegOp): + code = ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); + uint8_t dataBits = dataSize * 8; + uint8_t realShiftAmt = shiftAmt % (2 * dataBits); + uint64_t result; + if (realShiftAmt == 0) { + result = psrc1; + } else if (realShiftAmt < dataBits) { + // Because what happens to the bits shift -in- on a right + // shift is not defined in the C/C++ standard, we have to + // mask them out to be sure they're zero. + uint64_t logicalMask = mask(dataBits - realShiftAmt); + result = ((psrc1 >> realShiftAmt) & logicalMask) | + (DoubleBits << (dataBits - realShiftAmt)); + } else { + uint64_t logicalMask = mask(2 * dataBits - realShiftAmt); + result = ((DoubleBits >> (realShiftAmt - dataBits)) & + logicalMask) | + (psrc1 << (2 * dataBits - realShiftAmt)); + } + DestReg = merge(DestReg, result, dataSize); + ''' + flag_code = ''' + // If the shift amount is zero, no flags should be modified. + if (shiftAmt) { + //Zero out any flags we might modify. This way we only have to + //worry about setting them. + ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit)); + int CFBits = 0; + //If some combination of the CF bits need to be set, set them. + if ((realShiftAmt == 0 && + bits(DoubleBits, dataBits - 1)) || + (realShiftAmt <= dataBits && + bits(SrcReg1, realShiftAmt - 1)) || + (realShiftAmt > dataBits && + bits(DoubleBits, realShiftAmt - dataBits - 1))) { + CFBits = 1; + } + //If some combination of the CF bits need to be set, set them. + if ((ext & (CFBit | ECFBit)) && CFBits) + ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit)); + //Figure out what the OF bit should be. + if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ + bits(result, dataBits - 1))) + ccFlagBits = ccFlagBits | OFBit; + //Use the regular mechanisms to calculate the other flags. + ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit), + DestReg, psrc1, op2); + } + ''' + + class Mdb(WrRegOp): + code = 'DoubleBits = psrc1 ^ op2;' + class Wrip(WrRegOp, CondRegOp): code = 'RIP = psrc1 + sop2 + CSBase' else_code="RIP = RIP;" diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 5ea803bfc..135fc10df 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -127,6 +127,7 @@ def operands {{ 'Quotient': impIntReg(2, 9), 'Remainder': impIntReg(3, 10), 'Divisor': impIntReg(4, 11), + 'DoubleBits': impIntReg(5, 11), 'Rax': intReg('(INTREG_RAX)', 12), 'Rbx': intReg('(INTREG_RBX)', 13), 'Rcx': intReg('(INTREG_RCX)', 14), diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index 8b50bdf9b..a73aaef19 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -68,12 +68,13 @@ namespace X86ISA const int NumPseudoIntRegs = 1; //1. The condition code bits of the rflags register. - const int NumImplicitIntRegs = 5; + const int NumImplicitIntRegs = 6; //1. The lower part of the result of multiplication. //2. The upper part of the result of multiplication. //3. The quotient from division //4. The remainder from division //5. The divisor for division + //6. The register to use for shift doubles const int NumMMXRegs = 8; const int NumXMMRegs = 16; |