summaryrefslogtreecommitdiff
path: root/src/arch/x86/insts
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/insts')
-rw-r--r--src/arch/x86/insts/microregop.cc99
-rw-r--r--src/arch/x86/insts/microregop.hh97
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)
{
}