summaryrefslogtreecommitdiff
path: root/src/arch/x86/insts/microregop.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-07-17 15:33:18 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-07-17 15:33:18 -0700
commita6757095c35cfdc491396cd97a32c19aacaffe2e (patch)
tree9b2dc5f77f47bee8b1107d1b168ca843e2a32540 /src/arch/x86/insts/microregop.cc
parentcf846d5205c021a04ab1a8e830d9cb86be0bda6e (diff)
downloadgem5-a6757095c35cfdc491396cd97a32c19aacaffe2e.tar.xz
Add in support for condition code flags.
Some microops can set the condition codes, and some of them can be predicated on them. Some of the codes aren't implemented because it was unclear from the AMD patent what they actually did. They are used with string instructions, but they use variables IP, DTF, and SSTF which don't appear to be documented. --HG-- extra : convert_revision : 2236cccd07d0091762b50148975f301bb1d2da3f
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
{