namespace X86ISA
{
- /*
- uint64_t FpOp::genFlags(uint64_t oldFlags, uint64_t flagMask,
- uint64_t _dest, uint64_t _src1, uint64_t _src2,
- bool subtract) const
- {
- }
- */
- std::string
- FpOp::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
+std::string
+FpOp::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printDestReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 1, dataSize);
+ return response.str();
+}
- printMnemonic(response, instMnem, mnemonic);
- printDestReg(response, 0, dataSize);
- response << ", ";
- printSrcReg(response, 0, dataSize);
- response << ", ";
- printSrcReg(response, 1, dataSize);
- return response.str();
- }
}
namespace X86ISA
{
- /**
- * Base classes for FpOps which provides a generateDisassembly method.
- */
- class FpOp : public X86MicroopBase
- {
- protected:
- const RegIndex src1;
- const RegIndex src2;
- const RegIndex dest;
- const uint8_t dataSize;
- const int8_t spm;
+/**
+ * Base classes for FpOps which provides a generateDisassembly method.
+ */
+class FpOp : public X86MicroopBase
+{
+ protected:
+ const RegIndex src1;
+ const RegIndex src2;
+ const RegIndex dest;
+ const uint8_t dataSize;
+ const int8_t spm;
- // Constructor
- FpOp(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem,
- uint64_t setFlags,
- InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
- uint8_t _dataSize, int8_t _spm,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
- __opClass),
- src1(_src1.index()), src2(_src2.index()), dest(_dest.index()),
- dataSize(_dataSize), spm(_spm)
- {}
-/*
- //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,
- bool subtract = false) const;
- bool checkCondition(uint64_t flags) const;*/
+ // Constructor
+ FpOp(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem,
+ uint64_t setFlags,
+ InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
+ uint8_t _dataSize, int8_t _spm,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
+ __opClass),
+ src1(_src1.index()), src2(_src2.index()), dest(_dest.index()),
+ dataSize(_dataSize), spm(_spm)
+ {}
+
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
- };
}
#endif //__ARCH_X86_INSTS_MICROFPOP_HH__
namespace X86ISA
{
- std::string
- LdStOp::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
- printMnemonic(response, instMnem, mnemonic);
- if (flags[IsLoad])
- printDestReg(response, 0, dataSize);
- else
- printSrcReg(response, 2, dataSize);
- response << ", ";
- printMem(response, segment, scale, index, base, disp,
- addressSize, false);
- return response.str();
- }
+std::string
+LdStOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ if (flags[IsLoad])
+ printDestReg(response, 0, dataSize);
+ else
+ printSrcReg(response, 2, dataSize);
+ response << ", ";
+ printMem(response, segment, scale, index, base, disp, addressSize, false);
+ return response.str();
+}
- std::string
- LdStSplitOp::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
+std::string
+LdStSplitOp::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ int baseRegIdx = flags[IsLoad] ? 0 : 2;
+ response << "[";
+ printDestReg(response, baseRegIdx, dataSize);
+ response << ", ";
+ printDestReg(response, baseRegIdx+1, dataSize);
+ response << "], ";
+ printMem(response, segment, scale, index, base, disp, addressSize, false);
+ return response.str();
+}
- printMnemonic(response, instMnem, mnemonic);
- int baseRegIdx = flags[IsLoad] ? 0 : 2;
- response << "[";
- printDestReg(response, baseRegIdx, dataSize);
- response << ", ";
- printDestReg(response, baseRegIdx+1, dataSize);
- response << "], ";
- printMem(response, segment, scale, index, base, disp,
- addressSize, false);
- return response.str();
- }
}
namespace X86ISA
{
- /**
- * Base class for memory ops
- */
- class MemOp : public X86MicroopBase
+
+/**
+ * Base class for memory ops
+ */
+class MemOp : public X86MicroopBase
+{
+ protected:
+ const uint8_t scale;
+ const RegIndex index;
+ const RegIndex base;
+ const uint64_t disp;
+ const uint8_t segment;
+ const uint8_t dataSize;
+ const uint8_t addressSize;
+ const Request::FlagsType memFlags;
+ RegIndex foldOBit, foldABit;
+
+ //Constructor
+ MemOp(ExtMachInst _machInst,
+ const char * mnem, const char * _instMnem,
+ uint64_t setFlags,
+ uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
+ uint64_t _disp, InstRegIndex _segment,
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass),
+ scale(_scale), index(_index.index()), base(_base.index()),
+ disp(_disp), segment(_segment.index()),
+ dataSize(_dataSize), addressSize(_addressSize),
+ memFlags(_memFlags | _segment.index())
{
- protected:
- const uint8_t scale;
- const RegIndex index;
- const RegIndex base;
- const uint64_t disp;
- const uint8_t segment;
- const uint8_t dataSize;
- const uint8_t addressSize;
- const Request::FlagsType memFlags;
- RegIndex foldOBit, foldABit;
+ assert(_segment.index() < NUM_SEGMENTREGS);
+ foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
+ foldABit = (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
+ }
+};
- //Constructor
- MemOp(ExtMachInst _machInst,
- const char * mnem, const char * _instMnem,
- uint64_t setFlags,
- uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
- uint64_t _disp, InstRegIndex _segment,
- uint8_t _dataSize, uint8_t _addressSize,
- Request::FlagsType _memFlags,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass),
- scale(_scale), index(_index.index()), base(_base.index()),
- disp(_disp), segment(_segment.index()),
- dataSize(_dataSize), addressSize(_addressSize),
- memFlags(_memFlags | _segment.index())
- {
- assert(_segment.index() < NUM_SEGMENTREGS);
- foldOBit =
- (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
- foldABit =
- (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
- }
- };
+/**
+ * Base class for load and store ops using one register
+ */
+class LdStOp : public MemOp
+{
+ protected:
+ const RegIndex data;
- /**
- * Base class for load and store ops using one register
- */
- class LdStOp : public MemOp
+ //Constructor
+ LdStOp(ExtMachInst _machInst,
+ const char * mnem, const char * _instMnem,
+ uint64_t setFlags,
+ uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
+ uint64_t _disp, InstRegIndex _segment,
+ InstRegIndex _data,
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags,
+ OpClass __opClass) :
+ MemOp(_machInst, mnem, _instMnem, setFlags,
+ _scale, _index, _base, _disp, _segment,
+ _dataSize, _addressSize, _memFlags,
+ __opClass),
+ data(_data.index())
{
- protected:
- const RegIndex data;
+ }
- //Constructor
- LdStOp(ExtMachInst _machInst,
- const char * mnem, const char * _instMnem,
- uint64_t setFlags,
- uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
- uint64_t _disp, InstRegIndex _segment,
- InstRegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize,
- Request::FlagsType _memFlags,
- OpClass __opClass) :
- MemOp(_machInst, mnem, _instMnem, setFlags,
- _scale, _index, _base, _disp, _segment,
- _dataSize, _addressSize, _memFlags,
- __opClass),
- data(_data.index())
- {
- }
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
- };
+/**
+ * Base class for load and store ops using two registers, we will
+ * call them split ops for this reason. These are mainly used to
+ * implement cmpxchg8b and cmpxchg16b.
+ */
+class LdStSplitOp : public MemOp
+{
+ protected:
+ const RegIndex dataLow;
+ const RegIndex dataHi;
- /**
- * Base class for load and store ops using two registers, we will
- * call them split ops for this reason. These are mainly used to
- * implement cmpxchg8b and cmpxchg16b.
- */
- class LdStSplitOp : public MemOp
+ //Constructor
+ LdStSplitOp(ExtMachInst _machInst,
+ const char * mnem, const char * _instMnem,
+ uint64_t setFlags,
+ uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
+ uint64_t _disp, InstRegIndex _segment,
+ InstRegIndex _dataLow, InstRegIndex _dataHi,
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags,
+ OpClass __opClass) :
+ MemOp(_machInst, mnem, _instMnem, setFlags,
+ _scale, _index, _base, _disp, _segment,
+ _dataSize, _addressSize, _memFlags,
+ __opClass),
+ dataLow(_dataLow.index()),
+ dataHi(_dataHi.index())
{
- protected:
- const RegIndex dataLow;
- const RegIndex dataHi;
+ }
- //Constructor
- LdStSplitOp(ExtMachInst _machInst,
- const char * mnem, const char * _instMnem,
- uint64_t setFlags,
- uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
- uint64_t _disp, InstRegIndex _segment,
- InstRegIndex _dataLow, InstRegIndex _dataHi,
- uint8_t _dataSize, uint8_t _addressSize,
- Request::FlagsType _memFlags,
- OpClass __opClass) :
- MemOp(_machInst, mnem, _instMnem, setFlags,
- _scale, _index, _base, _disp, _segment,
- _dataSize, _addressSize, _memFlags,
- __opClass),
- dataLow(_dataLow.index()),
- dataHi(_dataHi.index())
- {
- }
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
- };
}
#endif //__ARCH_X86_INSTS_MICROLDSTOP_HH__
namespace X86ISA
{
- std::string
- MediaOpReg::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
- printMnemonic(response, instMnem, mnemonic);
- printDestReg(response, 0, destSize);
- response << ", ";
- printSrcReg(response, 0, srcSize);
- response << ", ";
- printSrcReg(response, 1, srcSize);
- return response.str();
- }
+std::string
+MediaOpReg::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printDestReg(response, 0, destSize);
+ response << ", ";
+ printSrcReg(response, 0, srcSize);
+ response << ", ";
+ printSrcReg(response, 1, srcSize);
+ return response.str();
+}
- std::string
- MediaOpImm::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
+std::string
+MediaOpImm::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printDestReg(response, 0, destSize);
+ response << ", ";
+ printSrcReg(response, 0, srcSize);
+ ccprintf(response, ", %#x", imm8);
+ return response.str();
+}
- printMnemonic(response, instMnem, mnemonic);
- printDestReg(response, 0, destSize);
- response << ", ";
- printSrcReg(response, 0, srcSize);
- ccprintf(response, ", %#x", imm8);
- return response.str();
- }
}
namespace X86ISA
{
- enum MediaFlag {
- MediaMultHiOp = 1,
- MediaSignedOp = 64,
- MediaScalarOp = 128
- };
- class MediaOpBase : public X86MicroopBase
+enum MediaFlag
+{
+ MediaMultHiOp = 1,
+ MediaSignedOp = 64,
+ MediaScalarOp = 128
+};
+
+class MediaOpBase : public X86MicroopBase
+{
+ protected:
+ const RegIndex src1;
+ const RegIndex dest;
+ const uint8_t srcSize;
+ const uint8_t destSize;
+ const uint8_t ext;
+ static const RegIndex foldOBit = 0;
+
+ // Constructor
+ MediaOpBase(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem, uint64_t setFlags,
+ InstRegIndex _src1, InstRegIndex _dest,
+ uint8_t _srcSize, uint8_t _destSize, uint8_t _ext,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
+ __opClass),
+ src1(_src1.index()), dest(_dest.index()),
+ srcSize(_srcSize), destSize(_destSize), ext(_ext)
+ {}
+
+ bool
+ scalarOp() const
{
- protected:
- const RegIndex src1;
- const RegIndex dest;
- const uint8_t srcSize;
- const uint8_t destSize;
- const uint8_t ext;
- static const RegIndex foldOBit = 0;
-
- // Constructor
- MediaOpBase(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem, uint64_t setFlags,
- InstRegIndex _src1, InstRegIndex _dest,
- uint8_t _srcSize, uint8_t _destSize, uint8_t _ext,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
- __opClass),
- src1(_src1.index()), dest(_dest.index()),
- srcSize(_srcSize), destSize(_destSize), ext(_ext)
- {}
-
- bool
- scalarOp() const
- {
- return ext & MediaScalarOp;
- }
-
- int
- numItems(int size) const
- {
- return scalarOp() ? 1 : (sizeof(uint64_t) / size);
- }
-
- bool
- multHi() const
- {
- return ext & MediaMultHiOp;
- }
-
- bool
- signedOp() const
- {
- return ext & MediaSignedOp;
- }
- };
-
- class MediaOpReg : public MediaOpBase
+ return ext & MediaScalarOp;
+ }
+
+ int
+ numItems(int size) const
{
- protected:
- const RegIndex src2;
-
- // Constructor
- MediaOpReg(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem, uint64_t setFlags,
- InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
- uint8_t _srcSize, uint8_t _destSize, uint8_t _ext,
- OpClass __opClass) :
- MediaOpBase(_machInst, mnem, _instMnem, setFlags,
- _src1, _dest, _srcSize, _destSize, _ext,
- __opClass),
- src2(_src2.index())
- {}
-
- std::string generateDisassembly(Addr pc,
- const Loader::SymbolTable *symtab) const override;
- };
-
- class MediaOpImm : public MediaOpBase
+ return scalarOp() ? 1 : (sizeof(uint64_t) / size);
+ }
+
+ bool
+ multHi() const
{
- protected:
- uint8_t imm8;
-
- // Constructor
- MediaOpImm(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem, uint64_t setFlags,
- InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
- uint8_t _srcSize, uint8_t _destSize, uint8_t _ext,
- OpClass __opClass) :
- MediaOpBase(_machInst, mnem, _instMnem, setFlags,
- _src1, _dest, _srcSize, _destSize, _ext,
- __opClass),
- imm8(_imm8)
- {}
-
- std::string generateDisassembly(Addr pc,
- const Loader::SymbolTable *symtab) const override;
- };
+ return ext & MediaMultHiOp;
+ }
+
+ bool
+ signedOp() const
+ {
+ return ext & MediaSignedOp;
+ }
+};
+
+class MediaOpReg : public MediaOpBase
+{
+ protected:
+ const RegIndex src2;
+
+ // Constructor
+ MediaOpReg(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem, uint64_t setFlags,
+ InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
+ uint8_t _srcSize, uint8_t _destSize, uint8_t _ext,
+ OpClass __opClass) :
+ MediaOpBase(_machInst, mnem, _instMnem, setFlags,
+ _src1, _dest, _srcSize, _destSize, _ext,
+ __opClass),
+ src2(_src2.index())
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const Loader::SymbolTable *symtab) const override;
+};
+
+class MediaOpImm : public MediaOpBase
+{
+ protected:
+ uint8_t imm8;
+
+ // Constructor
+ MediaOpImm(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem, uint64_t setFlags,
+ InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
+ uint8_t _srcSize, uint8_t _destSize, uint8_t _ext,
+ OpClass __opClass) :
+ MediaOpBase(_machInst, mnem, _instMnem, setFlags,
+ _src1, _dest, _srcSize, _destSize, _ext,
+ __opClass),
+ imm8(_imm8)
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const Loader::SymbolTable *symtab) const override;
+};
+
}
#endif //__ARCH_X86_INSTS_MICROMEDIAOP_HH__
namespace X86ISA
{
- bool X86MicroopBase::checkCondition(uint64_t flags, int condition) const
+bool
+X86MicroopBase::checkCondition(uint64_t flags, int condition) const
+{
+ CCFlagBits ccflags = flags;
+ switch(condition)
{
- CCFlagBits ccflags = flags;
- switch(condition)
- {
- 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::STRZnEZF:
- return !ccflags.ezf && ccflags.zf;
- //And no interrupts or debug traps are waiting
- 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::STRnZnEZF:
- return !ccflags.ezf && !ccflags.zf;
- //And no interrupts or debug traps are waiting
- 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", condition);
+ 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::STRZnEZF:
+ return !ccflags.ezf && ccflags.zf;
+ //And no interrupts or debug traps are waiting
+ 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::STRnZnEZF:
+ return !ccflags.ezf && !ccflags.zf;
+ //And no interrupts or debug traps are waiting
+ 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", condition);
+ return true;
+}
+
}
namespace X86ISA
{
- namespace ConditionTests
+
+namespace ConditionTests
+{
+
+enum CondTest
+{
+ True,
+ NotFalse = True,
+ ECF,
+ EZF,
+ SZnZF,
+ MSTRZ,
+ STRZ,
+ MSTRC,
+ STRZnEZF,
+ OF,
+ CF,
+ ZF,
+ CvZF,
+ SF,
+ PF,
+ SxOF,
+ SxOvZF,
+
+ False,
+ NotTrue = False,
+ NotECF,
+ NotEZF,
+ NotSZnZF,
+ NotMSTRZ,
+ NotSTRZ,
+ NotMSTRC,
+ STRnZnEZF,
+ NotOF,
+ NotCF,
+ NotZF,
+ NotCvZF,
+ NotSF,
+ NotPF,
+ NotSxOF,
+ NotSxOvZF
+};
+
+}
+
+//A class which is the base of all x86 micro ops. It provides a function to
+//set necessary flags appropriately.
+class X86MicroopBase : public X86StaticInst
+{
+ protected:
+ const char * instMnem;
+ uint8_t opSize;
+ uint8_t addrSize;
+
+ X86MicroopBase(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem,
+ uint64_t setFlags, OpClass __opClass) :
+ X86ISA::X86StaticInst(mnem, _machInst, __opClass),
+ instMnem(_instMnem)
{
- enum CondTest {
- True,
- NotFalse = True,
- ECF,
- EZF,
- SZnZF,
- MSTRZ,
- STRZ,
- MSTRC,
- STRZnEZF,
- OF,
- CF,
- ZF,
- CvZF,
- SF,
- PF,
- SxOF,
- SxOvZF,
-
- False,
- NotTrue = False,
- NotECF,
- NotEZF,
- NotSZnZF,
- NotMSTRZ,
- NotSTRZ,
- NotMSTRC,
- STRnZnEZF,
- NotOF,
- NotCF,
- NotZF,
- NotCvZF,
- NotSF,
- NotPF,
- NotSxOF,
- NotSxOvZF
- };
+ const int ChunkSize = sizeof(unsigned long);
+ const int Chunks = sizeof(setFlags) / ChunkSize;
+
+ // Since the bitset constructor can only handle unsigned long
+ // sized chunks, feed it those one at a time while oring them in.
+ for (int i = 0; i < Chunks; i++) {
+ unsigned shift = i * ChunkSize * 8;
+ flags |= (std::bitset<Num_Flags>(setFlags >> shift) << shift);
+ }
}
- //A class which is the base of all x86 micro ops. It provides a function to
- //set necessary flags appropriately.
- class X86MicroopBase : public X86StaticInst
+ std::string
+ generateDisassembly(Addr pc,
+ const Loader::SymbolTable *symtab) const override
{
- protected:
- const char * instMnem;
- uint8_t opSize;
- uint8_t addrSize;
-
- X86MicroopBase(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem,
- uint64_t setFlags, OpClass __opClass) :
- X86ISA::X86StaticInst(mnem, _machInst, __opClass),
- instMnem(_instMnem)
- {
- const int ChunkSize = sizeof(unsigned long);
- const int Chunks = sizeof(setFlags) / ChunkSize;
-
- // Since the bitset constructor can only handle unsigned long
- // sized chunks, feed it those one at a time while oring them in.
- for (int i = 0; i < Chunks; i++) {
- unsigned shift = i * ChunkSize * 8;
- flags |= (std::bitset<Num_Flags>(setFlags >> shift) << shift);
- }
- }
+ std::stringstream ss;
- std::string
- generateDisassembly(Addr pc,
- const Loader::SymbolTable *symtab) const override
- {
- std::stringstream ss;
+ ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
- ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
+ return ss.str();
+ }
- return ss.str();
- }
+ bool checkCondition(uint64_t flags, int condition) const;
- bool checkCondition(uint64_t flags, int condition) const;
+ void
+ advancePC(PCState &pcState) const override
+ {
+ if (flags[IsLastMicroop])
+ pcState.uEnd();
+ else
+ pcState.uAdvance();
+ }
+};
- void
- advancePC(PCState &pcState) const override
- {
- if (flags[IsLastMicroop])
- pcState.uEnd();
- else
- pcState.uAdvance();
- }
- };
}
#endif //__ARCH_X86_INSTS_MICROOP_HH__
namespace X86ISA
{
- uint64_t RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask,
- uint64_t _dest, uint64_t _src1, uint64_t _src2,
- bool subtract) const
- {
- DPRINTF(X86, "flagMask = %#x\n", flagMask);
- uint64_t flags = oldFlags & ~flagMask;
- if (flagMask & (ECFBit | CFBit))
- {
- if (findCarry(dataSize*8, _dest, _src1, _src2))
- flags |= (flagMask & (ECFBit | CFBit));
- if (subtract)
- flags ^= (flagMask & (ECFBit | CFBit));
- }
- if (flagMask & PFBit && !findParity(8, _dest))
- flags |= PFBit;
- if (flagMask & AFBit)
- {
- if (findCarry(4, _dest, _src1, _src2))
- flags |= AFBit;
- if (subtract)
- flags ^= AFBit;
- }
- if (flagMask & (EZFBit | ZFBit) && findZero(dataSize*8, _dest))
- flags |= (flagMask & (EZFBit | ZFBit));
- if (flagMask & SFBit && findNegative(dataSize*8, _dest))
- flags |= SFBit;
- if (flagMask & OFBit && findOverflow(dataSize*8, _dest, _src1, _src2))
- flags |= OFBit;
- return flags;
+
+uint64_t
+RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask,
+ uint64_t _dest, uint64_t _src1, uint64_t _src2, bool subtract) const
+{
+ DPRINTF(X86, "flagMask = %#x\n", flagMask);
+ uint64_t flags = oldFlags & ~flagMask;
+ if (flagMask & (ECFBit | CFBit)) {
+ if (findCarry(dataSize*8, _dest, _src1, _src2))
+ flags |= (flagMask & (ECFBit | CFBit));
+ if (subtract)
+ flags ^= (flagMask & (ECFBit | CFBit));
+ }
+ if (flagMask & PFBit && !findParity(8, _dest))
+ flags |= PFBit;
+ if (flagMask & AFBit) {
+ if (findCarry(4, _dest, _src1, _src2))
+ flags |= AFBit;
+ if (subtract)
+ flags ^= AFBit;
}
+ if (flagMask & (EZFBit | ZFBit) && findZero(dataSize*8, _dest))
+ flags |= (flagMask & (EZFBit | ZFBit));
+ if (flagMask & SFBit && findNegative(dataSize*8, _dest))
+ flags |= SFBit;
+ if (flagMask & OFBit && findOverflow(dataSize*8, _dest, _src1, _src2))
+ flags |= OFBit;
+ return flags;
+}
- std::string
- RegOp::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
+std::string
+RegOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
- printMnemonic(response, instMnem, mnemonic);
- printDestReg(response, 0, dataSize);
- response << ", ";
- printSrcReg(response, 0, dataSize);
- response << ", ";
- printSrcReg(response, 1, dataSize);
- return response.str();
- }
+ printMnemonic(response, instMnem, mnemonic);
+ printDestReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 1, dataSize);
+ return response.str();
+}
- std::string
- RegOpImm::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream response;
+std::string
+RegOpImm::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printDestReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 0, dataSize);
+ ccprintf(response, ", %#x", imm8);
+ return response.str();
+}
- printMnemonic(response, instMnem, mnemonic);
- printDestReg(response, 0, dataSize);
- response << ", ";
- printSrcReg(response, 0, dataSize);
- ccprintf(response, ", %#x", imm8);
- return response.str();
- }
}
namespace X86ISA
{
- /**
- * Base classes for RegOps which provides a generateDisassembly method.
- */
- class RegOpBase : public X86MicroopBase
+
+/**
+ * Base classes for RegOps which provides a generateDisassembly method.
+ */
+class RegOpBase : public X86MicroopBase
+{
+ protected:
+ const RegIndex src1;
+ const RegIndex dest;
+ const uint8_t dataSize;
+ const uint16_t ext;
+ RegIndex foldOBit;
+
+ // Constructor
+ RegOpBase(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem, uint64_t setFlags,
+ InstRegIndex _src1, InstRegIndex _dest,
+ uint8_t _dataSize, uint16_t _ext,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
+ __opClass),
+ src1(_src1.index()), dest(_dest.index()),
+ dataSize(_dataSize), ext(_ext)
{
- protected:
- const RegIndex src1;
- const RegIndex dest;
- const uint8_t dataSize;
- const uint16_t ext;
- RegIndex foldOBit;
+ foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
+ }
- // Constructor
- RegOpBase(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem, uint64_t setFlags,
- InstRegIndex _src1, InstRegIndex _dest,
- uint8_t _dataSize, uint16_t _ext,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
- __opClass),
- src1(_src1.index()), dest(_dest.index()),
- dataSize(_dataSize), ext(_ext)
- {
- foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
- }
+ //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,
+ bool subtract = false) const;
+};
- //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,
- bool subtract = false) const;
- };
+class RegOp : public RegOpBase
+{
+ protected:
+ const RegIndex src2;
- class RegOp : public RegOpBase
+ // Constructor
+ RegOp(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem, uint64_t setFlags,
+ InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
+ uint8_t _dataSize, uint16_t _ext,
+ OpClass __opClass) :
+ RegOpBase(_machInst, mnem, _instMnem, setFlags,
+ _src1, _dest, _dataSize, _ext,
+ __opClass),
+ src2(_src2.index())
{
- protected:
- const RegIndex src2;
+ }
- // Constructor
- RegOp(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem, uint64_t setFlags,
- InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
- uint8_t _dataSize, uint16_t _ext,
- OpClass __opClass) :
- RegOpBase(_machInst, mnem, _instMnem, setFlags,
- _src1, _dest, _dataSize, _ext,
- __opClass),
- src2(_src2.index())
- {
- }
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
- };
+class RegOpImm : public RegOpBase
+{
+ protected:
+ const uint8_t imm8;
- class RegOpImm : public RegOpBase
+ // Constructor
+ RegOpImm(ExtMachInst _machInst,
+ const char * mnem, const char *_instMnem, uint64_t setFlags,
+ InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
+ uint8_t _dataSize, uint16_t _ext,
+ OpClass __opClass) :
+ RegOpBase(_machInst, mnem, _instMnem, setFlags,
+ _src1, _dest, _dataSize, _ext,
+ __opClass),
+ imm8(_imm8)
{
- protected:
- const uint8_t imm8;
+ }
- // Constructor
- RegOpImm(ExtMachInst _machInst,
- const char * mnem, const char *_instMnem, uint64_t setFlags,
- InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
- uint8_t _dataSize, uint16_t _ext,
- OpClass __opClass) :
- RegOpBase(_machInst, mnem, _instMnem, setFlags,
- _src1, _dest, _dataSize, _ext,
- __opClass),
- imm8(_imm8)
- {
- }
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
- };
}
#endif //__ARCH_X86_INSTS_MICROREGOP_HH__
namespace X86ISA
{
- void X86StaticInst::printMnemonic(std::ostream &os,
- const char * mnemonic) const
- {
- ccprintf(os, " %s ", mnemonic);
- }
- void X86StaticInst::printMnemonic(std::ostream &os,
- const char * instMnemonic, const char * mnemonic) const
+void
+X86StaticInst::printMnemonic(std::ostream &os, const char *mnemonic) const
+{
+ ccprintf(os, " %s ", mnemonic);
+}
+
+void
+X86StaticInst::printMnemonic(std::ostream &os, const char *instMnemonic,
+ const char *mnemonic) const
+{
+ ccprintf(os, " %s : %s ", instMnemonic, mnemonic);
+}
+
+void X86StaticInst::printSegment(std::ostream &os, int segment) const
+{
+ switch (segment)
{
- ccprintf(os, " %s : %s ", instMnemonic, mnemonic);
+ case SEGMENT_REG_ES:
+ ccprintf(os, "ES");
+ break;
+ case SEGMENT_REG_CS:
+ ccprintf(os, "CS");
+ break;
+ case SEGMENT_REG_SS:
+ ccprintf(os, "SS");
+ break;
+ case SEGMENT_REG_DS:
+ ccprintf(os, "DS");
+ break;
+ case SEGMENT_REG_FS:
+ ccprintf(os, "FS");
+ break;
+ case SEGMENT_REG_GS:
+ ccprintf(os, "GS");
+ break;
+ case SEGMENT_REG_HS:
+ ccprintf(os, "HS");
+ break;
+ case SEGMENT_REG_TSL:
+ ccprintf(os, "TSL");
+ break;
+ case SEGMENT_REG_TSG:
+ ccprintf(os, "TSG");
+ break;
+ case SEGMENT_REG_LS:
+ ccprintf(os, "LS");
+ break;
+ case SEGMENT_REG_MS:
+ ccprintf(os, "MS");
+ break;
+ case SYS_SEGMENT_REG_TR:
+ ccprintf(os, "TR");
+ break;
+ case SYS_SEGMENT_REG_IDTR:
+ ccprintf(os, "IDTR");
+ break;
+ default:
+ panic("Unrecognized segment %d\n", segment);
}
+}
- void X86StaticInst::printSegment(std::ostream &os, int segment) const
- {
- switch (segment)
- {
- case SEGMENT_REG_ES:
- ccprintf(os, "ES");
+void
+X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
+{
+ if (_numSrcRegs > reg)
+ printReg(os, srcRegIdx(reg), size);
+}
+
+void
+X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
+{
+ if (_numDestRegs > reg)
+ printReg(os, destRegIdx(reg), size);
+}
+
+void
+X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const
+{
+ assert(size == 1 || size == 2 || size == 4 || size == 8);
+ static const char * abcdFormats[9] =
+ {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"};
+ static const char * piFormats[9] =
+ {"", "%s", "%s", "", "e%s", "", "", "", "r%s"};
+ static const char * longFormats[9] =
+ {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
+ static const char * microFormats[9] =
+ {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
+
+ RegIndex reg_idx = reg.index();
+
+ if (reg.isIntReg()) {
+ const char * suffix = "";
+ bool fold = reg_idx & IntFoldBit;
+ reg_idx &= ~IntFoldBit;
+
+ if (fold)
+ suffix = "h";
+ else if (reg_idx < 8 && size == 1)
+ suffix = "l";
+
+ switch (reg_idx) {
+ case INTREG_RAX:
+ ccprintf(os, abcdFormats[size], "a");
+ break;
+ case INTREG_RBX:
+ ccprintf(os, abcdFormats[size], "b");
break;
- case SEGMENT_REG_CS:
- ccprintf(os, "CS");
+ case INTREG_RCX:
+ ccprintf(os, abcdFormats[size], "c");
break;
- case SEGMENT_REG_SS:
- ccprintf(os, "SS");
+ case INTREG_RDX:
+ ccprintf(os, abcdFormats[size], "d");
break;
- case SEGMENT_REG_DS:
- ccprintf(os, "DS");
+ case INTREG_RSP:
+ ccprintf(os, piFormats[size], "sp");
break;
- case SEGMENT_REG_FS:
- ccprintf(os, "FS");
+ case INTREG_RBP:
+ ccprintf(os, piFormats[size], "bp");
break;
- case SEGMENT_REG_GS:
- ccprintf(os, "GS");
+ case INTREG_RSI:
+ ccprintf(os, piFormats[size], "si");
break;
- case SEGMENT_REG_HS:
- ccprintf(os, "HS");
+ case INTREG_RDI:
+ ccprintf(os, piFormats[size], "di");
break;
- case SEGMENT_REG_TSL:
- ccprintf(os, "TSL");
+ case INTREG_R8W:
+ ccprintf(os, longFormats[size], "8");
break;
- case SEGMENT_REG_TSG:
- ccprintf(os, "TSG");
+ case INTREG_R9W:
+ ccprintf(os, longFormats[size], "9");
break;
- case SEGMENT_REG_LS:
- ccprintf(os, "LS");
+ case INTREG_R10W:
+ ccprintf(os, longFormats[size], "10");
break;
- case SEGMENT_REG_MS:
- ccprintf(os, "MS");
+ case INTREG_R11W:
+ ccprintf(os, longFormats[size], "11");
break;
- case SYS_SEGMENT_REG_TR:
- ccprintf(os, "TR");
+ case INTREG_R12W:
+ ccprintf(os, longFormats[size], "12");
break;
- case SYS_SEGMENT_REG_IDTR:
- ccprintf(os, "IDTR");
+ case INTREG_R13W:
+ ccprintf(os, longFormats[size], "13");
+ break;
+ case INTREG_R14W:
+ ccprintf(os, longFormats[size], "14");
+ break;
+ case INTREG_R15W:
+ ccprintf(os, longFormats[size], "15");
break;
default:
- panic("Unrecognized segment %d\n", segment);
+ ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
}
- }
+ ccprintf(os, suffix);
- void
- X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
- {
- if (_numSrcRegs > reg)
- printReg(os, srcRegIdx(reg), size);
- }
-
- void
- X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
- {
- if (_numDestRegs > reg)
- printReg(os, destRegIdx(reg), size);
- }
-
- void
- X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const
- {
- assert(size == 1 || size == 2 || size == 4 || size == 8);
- static const char * abcdFormats[9] =
- {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"};
- static const char * piFormats[9] =
- {"", "%s", "%s", "", "e%s", "", "", "", "r%s"};
- static const char * longFormats[9] =
- {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
- static const char * microFormats[9] =
- {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
-
- RegIndex reg_idx = reg.index();
-
- if (reg.isIntReg()) {
- const char * suffix = "";
- bool fold = reg_idx & IntFoldBit;
- reg_idx &= ~IntFoldBit;
-
- if (fold)
- suffix = "h";
- else if (reg_idx < 8 && size == 1)
- suffix = "l";
-
- switch (reg_idx) {
- case INTREG_RAX:
- ccprintf(os, abcdFormats[size], "a");
- break;
- case INTREG_RBX:
- ccprintf(os, abcdFormats[size], "b");
- break;
- case INTREG_RCX:
- ccprintf(os, abcdFormats[size], "c");
- break;
- case INTREG_RDX:
- ccprintf(os, abcdFormats[size], "d");
- break;
- case INTREG_RSP:
- ccprintf(os, piFormats[size], "sp");
- break;
- case INTREG_RBP:
- ccprintf(os, piFormats[size], "bp");
- break;
- case INTREG_RSI:
- ccprintf(os, piFormats[size], "si");
- break;
- case INTREG_RDI:
- ccprintf(os, piFormats[size], "di");
- break;
- case INTREG_R8W:
- ccprintf(os, longFormats[size], "8");
- break;
- case INTREG_R9W:
- ccprintf(os, longFormats[size], "9");
- break;
- case INTREG_R10W:
- ccprintf(os, longFormats[size], "10");
- break;
- case INTREG_R11W:
- ccprintf(os, longFormats[size], "11");
- break;
- case INTREG_R12W:
- ccprintf(os, longFormats[size], "12");
- break;
- case INTREG_R13W:
- ccprintf(os, longFormats[size], "13");
- break;
- case INTREG_R14W:
- ccprintf(os, longFormats[size], "14");
- break;
- case INTREG_R15W:
- ccprintf(os, longFormats[size], "15");
- break;
- default:
- ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
- }
- ccprintf(os, suffix);
-
- } else if (reg.isFloatReg()) {
- if (reg_idx < NumMMXRegs) {
- ccprintf(os, "%%mmx%d", reg_idx);
- return;
- }
- reg_idx -= NumMMXRegs;
- if (reg_idx < NumXMMRegs * 2) {
- ccprintf(os, "%%xmm%d_%s", reg_idx / 2,
- (reg_idx % 2) ? "high": "low");
- return;
- }
- reg_idx -= NumXMMRegs * 2;
- if (reg_idx < NumMicroFpRegs) {
- ccprintf(os, "%%ufp%d", reg_idx);
- return;
- }
- reg_idx -= NumMicroFpRegs;
- ccprintf(os, "%%st(%d)", reg_idx);
+ } else if (reg.isFloatReg()) {
+ if (reg_idx < NumMMXRegs) {
+ ccprintf(os, "%%mmx%d", reg_idx);
+ return;
+ }
+ reg_idx -= NumMMXRegs;
+ if (reg_idx < NumXMMRegs * 2) {
+ ccprintf(os, "%%xmm%d_%s", reg_idx / 2,
+ (reg_idx % 2) ? "high": "low");
+ return;
+ }
+ reg_idx -= NumXMMRegs * 2;
+ if (reg_idx < NumMicroFpRegs) {
+ ccprintf(os, "%%ufp%d", reg_idx);
+ return;
+ }
+ reg_idx -= NumMicroFpRegs;
+ ccprintf(os, "%%st(%d)", reg_idx);
- } else if (reg.isCCReg()) {
- ccprintf(os, "%%cc%d", reg_idx);
+ } else if (reg.isCCReg()) {
+ ccprintf(os, "%%cc%d", reg_idx);
- } else if (reg.isMiscReg()) {
- switch (reg_idx) {
- default:
- ccprintf(os, "%%ctrl%d", reg_idx);
- }
+ } else if (reg.isMiscReg()) {
+ switch (reg_idx) {
+ default:
+ ccprintf(os, "%%ctrl%d", reg_idx);
}
}
+}
- void X86StaticInst::printMem(std::ostream &os, uint8_t segment,
- uint8_t scale, RegIndex index, RegIndex base,
- uint64_t disp, uint8_t addressSize, bool rip) const
- {
- bool someAddr = false;
- printSegment(os, segment);
- os << ":[";
- if (rip) {
- os << "rip";
+void
+X86StaticInst::printMem(std::ostream &os, uint8_t segment,
+ uint8_t scale, RegIndex index, RegIndex base,
+ uint64_t disp, uint8_t addressSize, bool rip) const
+{
+ bool someAddr = false;
+ printSegment(os, segment);
+ os << ":[";
+ if (rip) {
+ os << "rip";
+ someAddr = true;
+ } else {
+ if (scale != 0 && index != ZeroReg) {
+ if (scale != 1)
+ ccprintf(os, "%d*", scale);
+ printReg(os, InstRegIndex(index), addressSize);
someAddr = true;
- } else {
- if (scale != 0 && index != ZeroReg)
- {
- if (scale != 1)
- ccprintf(os, "%d*", scale);
- printReg(os, InstRegIndex(index), addressSize);
- someAddr = true;
- }
- if (base != ZeroReg)
- {
- if (someAddr)
- os << " + ";
- printReg(os, InstRegIndex(base), addressSize);
- someAddr = true;
- }
}
- if (disp != 0)
- {
+ if (base != ZeroReg) {
if (someAddr)
os << " + ";
- ccprintf(os, "%#x", disp);
+ printReg(os, InstRegIndex(base), addressSize);
someAddr = true;
}
- if (!someAddr)
- os << "0";
- os << "]";
}
+ if (disp != 0) {
+ if (someAddr)
+ os << " + ";
+ ccprintf(os, "%#x", disp);
+ someAddr = true;
+ }
+ if (!someAddr)
+ os << "0";
+ os << "]";
+}
- std::string
- X86StaticInst::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
- {
- std::stringstream ss;
+std::string
+X86StaticInst::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream ss;
- printMnemonic(ss, mnemonic);
+ printMnemonic(ss, mnemonic);
+
+ return ss.str();
+}
- return ss.str();
- }
}
namespace X86ISA
{
- /**
- * Class for register indices passed to instruction constructors. Using a
- * wrapper struct for these lets take advantage of the compiler's type
- * checking.
- */
- struct InstRegIndex : public RegId
+
+/**
+ * Class for register indices passed to instruction constructors. Using a
+ * wrapper struct for these lets take advantage of the compiler's type
+ * checking.
+ */
+struct InstRegIndex : public RegId
+{
+ explicit InstRegIndex(RegIndex _idx) :
+ RegId(computeRegClass(_idx), _idx) {}
+
+ private:
+ // TODO: As X86 register index definition is highly built on the
+ // unified space concept, it is easier for the moment to rely on
+ // an helper function to compute the RegClass. It would be nice
+ // to fix those definition and get rid of this.
+ RegClass
+ computeRegClass(RegIndex _idx)
{
- explicit InstRegIndex(RegIndex _idx) :
- RegId(computeRegClass(_idx), _idx) {}
-
- private:
- // TODO: As X86 register index definition is highly built on the
- // unified space concept, it is easier for the moment to rely on
- // an helper function to compute the RegClass. It would be nice
- // to fix those definition and get rid of this.
- RegClass computeRegClass(RegIndex _idx) {
- if (_idx < FP_Reg_Base) {
- return IntRegClass;
- } else if (_idx < CC_Reg_Base) {
- return FloatRegClass;
- } else if (_idx < Misc_Reg_Base) {
- return CCRegClass;
- } else {
- return MiscRegClass;
- }
+ if (_idx < FP_Reg_Base) {
+ return IntRegClass;
+ } else if (_idx < CC_Reg_Base) {
+ return FloatRegClass;
+ } else if (_idx < Misc_Reg_Base) {
+ return CCRegClass;
+ } else {
+ return MiscRegClass;
}
- };
+ }
+};
- /**
- * Base class for all X86 static instructions.
- */
+/**
+ * Base class for all X86 static instructions.
+ */
- class X86StaticInst : public StaticInst
- {
- protected:
- using ExtMachInst = X86ISA::ExtMachInst;
+class X86StaticInst : public StaticInst
+{
+ protected:
+ using ExtMachInst = X86ISA::ExtMachInst;
- // Constructor.
- X86StaticInst(const char *mnem,
- ExtMachInst _machInst, OpClass __opClass)
- : StaticInst(mnem, _machInst, __opClass)
- {
- }
+ // Constructor.
+ X86StaticInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : StaticInst(mnem, _machInst, __opClass)
+ {
+ }
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
- void printMnemonic(std::ostream &os, const char * mnemonic) const;
- void printMnemonic(std::ostream &os, const char * instMnemonic,
- const char * mnemonic) const;
+ void printMnemonic(std::ostream &os, const char * mnemonic) const;
+ void printMnemonic(std::ostream &os, const char * instMnemonic,
+ const char * mnemonic) const;
- void printSegment(std::ostream &os, int segment) const;
+ void printSegment(std::ostream &os, int segment) const;
- void printReg(std::ostream &os, RegId reg, int size) const;
- void printSrcReg(std::ostream &os, int reg, int size) const;
- void printDestReg(std::ostream &os, int reg, int size) const;
- void printMem(std::ostream &os, uint8_t segment,
- uint8_t scale, RegIndex index, RegIndex base,
- uint64_t disp, uint8_t addressSize, bool rip) const;
+ void printReg(std::ostream &os, RegId reg, int size) const;
+ void printSrcReg(std::ostream &os, int reg, int size) const;
+ void printDestReg(std::ostream &os, int reg, int size) const;
+ void printMem(std::ostream &os, uint8_t segment,
+ uint8_t scale, RegIndex index, RegIndex base,
+ uint64_t disp, uint8_t addressSize, bool rip) const;
- inline uint64_t merge(uint64_t into, uint64_t val, int size) const
- {
- X86IntReg reg = into;
- if (destRegIdx(0).index() & IntFoldBit)
- {
- reg.H = val;
- return reg;
- }
- switch(size)
- {
- case 1:
- reg.L = val;
- break;
- case 2:
- reg.X = val;
- break;
- case 4:
- //XXX Check if this should be zeroed or sign extended
- reg = 0;
- reg.E = val;
- break;
- case 8:
- reg.R = val;
- break;
- default:
- panic("Tried to merge with unrecognized size %d.\n", size);
- }
+ inline uint64_t
+ merge(uint64_t into, uint64_t val, int size) const
+ {
+ X86IntReg reg = into;
+ if (destRegIdx(0).index() & IntFoldBit) {
+ reg.H = val;
return reg;
}
-
- inline uint64_t pick(uint64_t from, int idx, int size) const
- {
- X86IntReg reg = from;
- DPRINTF(X86, "Picking with size %d\n", size);
- if (srcRegIdx(idx).index() & IntFoldBit)
- return reg.H;
- switch(size)
- {
- case 1:
- return reg.L;
- case 2:
- return reg.X;
- case 4:
- return reg.E;
- case 8:
- return reg.R;
- default:
- panic("Tried to pick with unrecognized size %d.\n", size);
- }
+ switch(size) {
+ case 1:
+ reg.L = val;
+ break;
+ case 2:
+ reg.X = val;
+ break;
+ case 4:
+ //XXX Check if this should be zeroed or sign extended
+ reg = 0;
+ reg.E = val;
+ break;
+ case 8:
+ reg.R = val;
+ break;
+ default:
+ panic("Tried to merge with unrecognized size %d.\n", size);
}
+ return reg;
+ }
- inline int64_t signedPick(uint64_t from, int idx, int size) const
- {
- X86IntReg reg = from;
- DPRINTF(X86, "Picking with size %d\n", size);
- if (srcRegIdx(idx).index() & IntFoldBit)
- return reg.SH;
- switch(size)
- {
- case 1:
- return reg.SL;
- case 2:
- return reg.SX;
- case 4:
- return reg.SE;
- case 8:
- return reg.SR;
- default:
- panic("Tried to pick with unrecognized size %d.\n", size);
- }
+ inline uint64_t
+ pick(uint64_t from, int idx, int size) const
+ {
+ X86IntReg reg = from;
+ DPRINTF(X86, "Picking with size %d\n", size);
+ if (srcRegIdx(idx).index() & IntFoldBit)
+ return reg.H;
+ switch(size) {
+ case 1:
+ return reg.L;
+ case 2:
+ return reg.X;
+ case 4:
+ return reg.E;
+ case 8:
+ return reg.R;
+ default:
+ panic("Tried to pick with unrecognized size %d.\n", size);
}
+ }
- void
- advancePC(PCState &pcState) const override
- {
- pcState.advance();
+ inline int64_t
+ signedPick(uint64_t from, int idx, int size) const
+ {
+ X86IntReg reg = from;
+ DPRINTF(X86, "Picking with size %d\n", size);
+ if (srcRegIdx(idx).index() & IntFoldBit)
+ return reg.SH;
+ switch(size) {
+ case 1:
+ return reg.SL;
+ case 2:
+ return reg.SX;
+ case 4:
+ return reg.SE;
+ case 8:
+ return reg.SR;
+ default:
+ panic("Tried to pick with unrecognized size %d.\n", size);
}
- };
+ }
+
+ void
+ advancePC(PCState &pcState) const override
+ {
+ pcState.advance();
+ }
+};
}
#endif //__ARCH_X86_INSTS_STATICINST_HH__