diff options
Diffstat (limited to 'src/arch/x86/insts')
-rw-r--r-- | src/arch/x86/insts/microregop.cc | 99 | ||||
-rw-r--r-- | src/arch/x86/insts/microregop.hh | 97 |
2 files changed, 178 insertions, 18 deletions
diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 481d9f0ad..3c60d7212 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -56,10 +56,109 @@ */ #include "arch/x86/insts/microregop.hh" +#include "arch/x86/miscregs.hh" +#include "base/condcodes.hh" #include <string> namespace X86ISA { + uint64_t RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask, + uint64_t _dest, uint64_t _src1, uint64_t _src2) const + { + uint64_t flags = oldFlags & ~flagMask; + if(flagMask & CFBit && findCarry(dataSize, _dest, _src1, _src2)) + flags |= CFBit; + if(flagMask & PFBit && findParity(dataSize, _dest)) + flags |= PFBit; + if(flagMask & ECFBit && findCarry(dataSize, _dest, _src1, _src2)) + flags |= ECFBit; + if(flagMask & AFBit && findCarry(4, _dest, _src1, _src2)) + flags |= AFBit; + if(flagMask & EZFBit && findZero(dataSize, _dest)) + flags |= EZFBit; + if(flagMask & ZFBit && findZero(dataSize, _dest)) + flags |= ZFBit; + if(flagMask & SFBit && findNegative(dataSize, _dest)) + flags |= SFBit; + if(flagMask & OFBit && findOverflow(dataSize, _dest, _src1, _src2)) + flags |= OFBit; + return flags; + } + + bool RegOpBase::checkCondition(uint64_t flags) const + { + CCFlagBits ccflags = flags; + switch(ext) + { + case ConditionTests::True: + return true; + case ConditionTests::ECF: + return ccflags.ECF; + case ConditionTests::EZF: + return ccflags.EZF; + case ConditionTests::SZnZF: + return !(!ccflags.EZF & ccflags.ZF); + case ConditionTests::MSTRZ: + panic("This condition is not implemented!"); + case ConditionTests::STRZ: + panic("This condition is not implemented!"); + case ConditionTests::MSTRC: + panic("This condition is not implemented!"); + case ConditionTests::STRZnZF: + panic("This condition is not implemented!"); + case ConditionTests::OF: + return ccflags.OF; + case ConditionTests::CF: + return ccflags.CF; + case ConditionTests::ZF: + return ccflags.ZF; + case ConditionTests::CvZF: + return ccflags.CF | ccflags.ZF; + case ConditionTests::SF: + return ccflags.SF; + case ConditionTests::PF: + return ccflags.PF; + case ConditionTests::SxOF: + return ccflags.SF ^ ccflags.OF; + case ConditionTests::SxOvZF: + return ccflags.SF ^ ccflags.OF | ccflags.ZF; + case ConditionTests::False: + return false; + case ConditionTests::NotECF: + return !ccflags.ECF; + case ConditionTests::NotEZF: + return !ccflags.EZF; + case ConditionTests::NotSZnZF: + return !ccflags.EZF & ccflags.ZF; + case ConditionTests::NotMSTRZ: + panic("This condition is not implemented!"); + case ConditionTests::NotSTRZ: + panic("This condition is not implemented!"); + case ConditionTests::NotMSTRC: + panic("This condition is not implemented!"); + case ConditionTests::NotSTRZnZF: + panic("This condition is not implemented!"); + case ConditionTests::NotOF: + return !ccflags.OF; + case ConditionTests::NotCF: + return !ccflags.CF; + case ConditionTests::NotZF: + return !ccflags.ZF; + case ConditionTests::NotCvZF: + return !(ccflags.CF | ccflags.ZF); + case ConditionTests::NotSF: + return !ccflags.SF; + case ConditionTests::NotPF: + return !ccflags.PF; + case ConditionTests::NotSxOF: + return !(ccflags.SF ^ ccflags.OF); + case ConditionTests::NotSxOvZF: + return !(ccflags.SF ^ ccflags.OF | ccflags.ZF); + } + panic("Unknown condition: %d\n", ext); + return true; + } + std::string RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index b20f13d55..a8049ba19 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -62,18 +62,84 @@ namespace X86ISA { + namespace ConditionTests + { + enum CondTest { + True, + NotFalse = True, + ECF, + EZF, + SZnZF, + MSTRZ, + STRZ, + MSTRC, + STRZnZF, + OF, + CF, + ZF, + CvZF, + SF, + PF, + SxOF, + SxOvZF, + + False, + NotTrue = False, + NotECF, + NotEZF, + NotSZnZF, + NotMSTRZ, + NotSTRZ, + NotMSTRC, + NotSTRZnZF, + NotOF, + NotCF, + NotZF, + NotCvZF, + NotSF, + NotPF, + NotSxOF, + NotSxOvZF + }; + } + /** * Base classes for RegOps which provides a generateDisassembly method. */ - class RegOp : public X86MicroopBase + class RegOpBase : public X86MicroopBase { protected: const RegIndex src1; - const RegIndex src2; const RegIndex dest; - const bool setStatus; const uint8_t dataSize; - const uint8_t ext; + const uint16_t ext; + + // Constructor + RegOpBase(ExtMachInst _machInst, + const char *mnem, const char *_instMnem, + bool isMicro, bool isDelayed, + bool isFirst, bool isLast, + RegIndex _src1, RegIndex _dest, + uint8_t _dataSize, uint16_t _ext, + OpClass __opClass) : + X86MicroopBase(_machInst, mnem, _instMnem, + isMicro, isDelayed, isFirst, isLast, + __opClass), + src1(_src1), dest(_dest), + dataSize(_dataSize), ext(_ext) + { + } + + //Figure out what the condition code flags should be. + uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask, + uint64_t _dest, uint64_t _src1, uint64_t _src2) const; + bool checkCondition(uint64_t flags) const; + }; + + class RegOp : public RegOpBase + { + protected: + const RegIndex src2; // Constructor RegOp(ExtMachInst _machInst, @@ -81,13 +147,13 @@ namespace X86ISA bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext, + uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : - X86MicroopBase(_machInst, mnem, _instMnem, + RegOpBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, + _src1, _dest, _dataSize, _ext, __opClass), - src1(_src1), src2(_src2), dest(_dest), - setStatus(_setStatus), dataSize(_dataSize), ext(_ext) + src2(_src2) { } @@ -95,15 +161,10 @@ namespace X86ISA const SymbolTable *symtab) const; }; - class RegOpImm : public X86MicroopBase + class RegOpImm : public RegOpBase { protected: - const RegIndex src1; const uint8_t imm8; - const RegIndex dest; - const bool setStatus; - const uint8_t dataSize; - const uint8_t ext; // Constructor RegOpImm(ExtMachInst _machInst, @@ -111,13 +172,13 @@ namespace X86ISA bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext, + uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : - X86MicroopBase(_machInst, mnem, _instMnem, + RegOpBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, + _src1, _dest, _dataSize, _ext, __opClass), - src1(_src1), imm8(_imm8), dest(_dest), - setStatus(_setStatus), dataSize(_dataSize), ext(_ext) + imm8(_imm8) { } |