summaryrefslogtreecommitdiff
path: root/src/arch/x86/insts/microregop.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/insts/microregop.cc')
-rw-r--r--src/arch/x86/insts/microregop.cc99
1 files changed, 99 insertions, 0 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
{