From 4b1ac05dfa4a679ee13a583e9beca113cca63079 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 28 Feb 2021 21:25:21 -0800 Subject: [PATCH] arch-x86: Let individual reg uops specialize their arguments. Rather than force all x86 microops to have one destination and two sources, the second of which is a register or immediate, make it possible for these microops to pick any combination of those elements by modularizing the operand aspects of the base class. This prevents having a bunch of extra parameters and members of the classes, or having a lot of explicitly laid out classes with various combinations. This also improves the accuracy/usefulness of Exec traces since register types and therefore names will be determined correctly. Also, there was a branchTarget override added to all register uops which would be used when the macroop was an direct control transfer instruction. The assumption was that the immediate value of the whole instruction would be the PC offset, which is not necessarily correct but is probably a fairly safe assumption. This override was only provided for all *register* uops though, and there's nothing saying the last uop in a branch instruction has to be a a register uop. This change moves that override to the uop base class so that *any* uop can be last in the macroop and still support branchTarget correctly (or at least as correctly as a register uop would). Change-Id: I9d42d22609d511fa757a784c04a5a9874beca479 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42343 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- src/arch/x86/insts/microop.cc | 11 + src/arch/x86/insts/microop.hh | 5 + src/arch/x86/insts/microregop.cc | 51 +-- src/arch/x86/insts/microregop.hh | 317 +++++++++++--- src/arch/x86/insts/static_inst.cc | 10 +- src/arch/x86/insts/static_inst.hh | 23 +- src/arch/x86/isa/includes.isa | 1 + src/arch/x86/isa/microasm.isa | 3 +- src/arch/x86/isa/microops/regop.isa | 643 ++++++++++++++-------------- src/arch/x86/isa/operands.isa | 137 +++--- 10 files changed, 699 insertions(+), 502 deletions(-) diff --git a/src/arch/x86/insts/microop.cc b/src/arch/x86/insts/microop.cc index 937ff6b34e..0f81d6aa02 100644 --- a/src/arch/x86/insts/microop.cc +++ b/src/arch/x86/insts/microop.cc @@ -119,4 +119,15 @@ X86MicroopBase::checkCondition(uint64_t flags, int condition) const return true; } +PCState +X86MicroopBase::branchTarget(const PCState &branchPC) const +{ + PCState pcs = branchPC; + DPRINTF(X86, "branchTarget PC info: %s, Immediate: %lx\n", pcs, + (int64_t)machInst.immediate); + pcs.npc(pcs.npc() + (int64_t)machInst.immediate); + pcs.uEnd(); + return pcs; +} + } diff --git a/src/arch/x86/insts/microop.hh b/src/arch/x86/insts/microop.hh index 56c5fe3f2f..ac12cecd34 100644 --- a/src/arch/x86/insts/microop.hh +++ b/src/arch/x86/insts/microop.hh @@ -134,6 +134,11 @@ class X86MicroopBase : public X86StaticInst else pcState.uAdvance(); } + + PCState branchTarget(const PCState &branchPC) const override; + + // Explicitly import the otherwise hidden branchTarget. + using StaticInst::branchTarget; }; } diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 5deb0f0589..63cdf50ab2 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -47,59 +47,32 @@ namespace X86ISA { uint64_t -RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask, +RegOpBase::genFlags(uint64_t old_flags, uint64_t flag_mask, 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)) { + DPRINTF(X86, "flag_mask = %#x\n", flag_mask); + uint64_t flags = old_flags & ~flag_mask; + if (flag_mask & (ECFBit | CFBit)) { if (findCarry(dataSize*8, _dest, _src1, _src2)) - flags |= (flagMask & (ECFBit | CFBit)); + flags |= (flag_mask & (ECFBit | CFBit)); if (subtract) - flags ^= (flagMask & (ECFBit | CFBit)); + flags ^= (flag_mask & (ECFBit | CFBit)); } - if (flagMask & PFBit && !findParity(8, _dest)) + if (flag_mask & PFBit && !findParity(8, _dest)) flags |= PFBit; - if (flagMask & AFBit) { + if (flag_mask & 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)) + if (flag_mask & (EZFBit | ZFBit) && findZero(dataSize * 8, _dest)) + flags |= (flag_mask & (EZFBit | ZFBit)); + if (flag_mask & SFBit && findNegative(dataSize * 8, _dest)) flags |= SFBit; - if (flagMask & OFBit && findOverflow(dataSize*8, _dest, _src1, _src2)) + if (flag_mask & 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; - - 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; - - printMnemonic(response, instMnem, mnemonic); - printDestReg(response, 0, dataSize); - response << ", "; - printSrcReg(response, 0, dataSize); - ccprintf(response, ", %#x", imm8); - return response.str(); -} - } diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index 1c26111851..e7bd0538c9 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -43,80 +43,279 @@ namespace X86ISA { -/** - * Base classes for RegOps which provides a generateDisassembly method. - */ +struct RegOpDest +{ + using ArgType = InstRegIndex; + + RegIndex dest; + size_t size; + + template + RegOpDest(InstType *inst, ArgType idx) : + dest(INTREG_FOLDED(idx.index(), inst->foldOBit)), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(IntRegClass, dest), size); + } +}; + +struct RegOpDbgDest +{ + using ArgType = InstRegIndex; + + RegIndex dest; + size_t size; + + template + RegOpDbgDest(InstType *inst, ArgType idx) : dest(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + ccprintf(os, "dr%d", dest); + } +}; + +struct RegOpCrDest +{ + using ArgType = InstRegIndex; + + RegIndex dest; + size_t size; + + template + RegOpCrDest(InstType *inst, ArgType idx) : dest(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + ccprintf(os, "cr%d", dest); + } +}; + +struct RegOpSegDest +{ + using ArgType = InstRegIndex; + + RegIndex dest; + size_t size; + + template + RegOpSegDest(InstType *inst, ArgType idx) : dest(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printSegment(os, dest); + } +}; + +struct RegOpMiscDest +{ + using ArgType = InstRegIndex; + + RegIndex dest; + size_t size; + + template + RegOpMiscDest(InstType *inst, ArgType idx) : dest(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(MiscRegClass, dest), size); + } +}; + +struct RegOpSrc1 +{ + using ArgType = InstRegIndex; + + RegIndex src1; + size_t size; + + template + RegOpSrc1(InstType *inst, ArgType idx) : + src1(INTREG_FOLDED(idx.index(), inst->foldOBit)), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(IntRegClass, src1), size); + } +}; + +struct RegOpDbgSrc1 +{ + using ArgType = InstRegIndex; + + RegIndex src1; + size_t size; + + template + RegOpDbgSrc1(InstType *inst, ArgType idx) : src1(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + ccprintf(os, "dr%d", src1); + } +}; + +struct RegOpCrSrc1 +{ + using ArgType = InstRegIndex; + + RegIndex src1; + size_t size; + + template + RegOpCrSrc1(InstType *inst, ArgType idx) : src1(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + ccprintf(os, "cr%d", src1); + } +}; + +struct RegOpSegSrc1 +{ + using ArgType = InstRegIndex; + + RegIndex src1; + size_t size; + + template + RegOpSegSrc1(InstType *inst, ArgType idx) : src1(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printSegment(os, src1); + } +}; + +struct RegOpMiscSrc1 +{ + using ArgType = InstRegIndex; + + RegIndex src1; + size_t size; + + template + RegOpMiscSrc1(InstType *inst, ArgType idx) : src1(idx.index()), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(MiscRegClass, src1), size); + } +}; + +struct RegOpSrc2 +{ + using ArgType = InstRegIndex; + + RegIndex src2; + size_t size; + + template + RegOpSrc2(InstType *inst, ArgType idx) : + src2(INTREG_FOLDED(idx.index(), inst->foldOBit)), + size(inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(IntRegClass, src2), size); + } +}; + +struct RegOpImm8 +{ + using ArgType = uint8_t; + + uint8_t imm8; + + template + RegOpImm8(InstType *inst, ArgType _imm8) : imm8(_imm8) {} + + void + print(std::ostream &os) const + { + ccprintf(os, "%#x", imm8); + } +}; + 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) - { - foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; - } + RegOpBase(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, uint8_t data_size, uint16_t _ext, + OpClass op_class) : + X86MicroopBase(mach_inst, mnem, inst_mnem, set_flags, op_class), + ext(_ext), dataSize(data_size), + foldOBit((data_size == 1 && !mach_inst.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 genFlags(uint64_t old_flags, uint64_t flag_mask, uint64_t _dest, uint64_t _src1, uint64_t _src2, - bool subtract = false) const; + bool subtract=false)const ; + + public: + const uint8_t dataSize; + const RegIndex foldOBit; }; -class RegOp : public RegOpBase +template +class RegOpT : public RegOpBase, public Operands... { protected: - const RegIndex src2; + RegOpT(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, uint8_t data_size, uint16_t _ext, + OpClass op_class, typename Operands::ArgType... args) : + RegOpBase(mach_inst, mnem, inst_mnem, set_flags, data_size, _ext, + op_class), Operands(this, args)... + {} - // 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::stringstream response; + printMnemonic(response, instMnem, mnemonic); + int count = 0; + M5_FOR_EACH_IN_PACK(ccprintf(response, count++ ? ", " : ""), + Operands::print(response)); + return response.str(); } - - std::string generateDisassembly( - Addr pc, const Loader::SymbolTable *symtab) const override; -}; - -class RegOpImm : public RegOpBase -{ - 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; }; } diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index 6a9286e545..71aa6e5ee4 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -45,19 +45,19 @@ namespace X86ISA { void -X86StaticInst::printMnemonic(std::ostream &os, const char *mnemonic) const +X86StaticInst::printMnemonic(std::ostream &os, const char *mnemonic) { ccprintf(os, " %s ", mnemonic); } void X86StaticInst::printMnemonic(std::ostream &os, const char *instMnemonic, - const char *mnemonic) const + const char *mnemonic) { ccprintf(os, " %s : %s ", instMnemonic, mnemonic); } -void X86StaticInst::printSegment(std::ostream &os, int segment) const +void X86StaticInst::printSegment(std::ostream &os, int segment) { switch (segment) { @@ -120,7 +120,7 @@ X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const } void -X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const +X86StaticInst::printReg(std::ostream &os, RegId reg, int size) { assert(size == 1 || size == 2 || size == 4 || size == 8); static const char * abcdFormats[9] = @@ -231,7 +231,7 @@ X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const 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 + uint64_t disp, uint8_t addressSize, bool rip) { bool someAddr = false; printSegment(os, segment); diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index 52f8048e23..507de19831 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -81,6 +81,18 @@ struct InstRegIndex : public RegId class X86StaticInst : public StaticInst { + public: + static void printMnemonic(std::ostream &os, const char *mnemonic); + static void printMnemonic(std::ostream &os, const char *instMnemonic, + const char *mnemonic); + static void printMem(std::ostream &os, uint8_t segment, + uint8_t scale, RegIndex index, RegIndex base, + uint64_t disp, uint8_t addressSize, bool rip); + + static void printSegment(std::ostream &os, int segment); + + static void printReg(std::ostream &os, RegId reg, int size); + protected: using ExtMachInst = X86ISA::ExtMachInst; @@ -95,19 +107,8 @@ class X86StaticInst : public StaticInst 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 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; inline uint64_t merge(uint64_t into, uint64_t val, int size) const diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 13f96876a7..1e1d8656ae 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -77,6 +77,7 @@ output decoder {{ #include "arch/x86/faults.hh" #include "arch/x86/microcode_rom.hh" #include "arch/x86/regs/float.hh" +#include "arch/x86/regs/int.hh" #include "arch/x86/regs/misc.hh" #include "arch/x86/regs/segment.hh" #include "arch/x86/tlb.hh" diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 856abac93a..59551a5c7f 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -135,7 +135,8 @@ let {{ for reg in ('ah', 'bh', 'ch', 'dh'): assembler.symbols[reg] = \ - regIdx("INTREG_FOLDED(INTREG_%s, IntFoldBit)" % reg.upper()) + regIdx("X86ISA::INTREG_FOLDED(INTREG_%s, IntFoldBit)" % + reg.upper()) for reg in range(16): assembler.symbols["cr%d" % reg] = regIdx("MISCREG_CR%d" % reg) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 2236dec076..38a4be301b 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -67,33 +67,6 @@ def template MicroRegOpExecute {{ } }}; -def template MicroRegOpImmExecute {{ - Fault - %(class_name)s::execute(ExecContext *xc, - Trace::InstRecord *traceData) const - { - Fault fault = NoFault; - - %(op_decl)s; - %(op_rd)s; - - M5_VAR_USED RegVal result; - - if (%(cond_check)s) { - %(code)s; - %(flag_code)s; - } else { - %(else_code)s; - } - - //Write the resulting state to the execution context - if (fault == NoFault) { - %(op_wb)s; - } - return fault; - } -}}; - def template MicroRegOpDeclare {{ class %(class_name)s : public %(base_class)s { @@ -101,33 +74,40 @@ def template MicroRegOpDeclare {{ %(reg_idx_arr_decl)s; public: - %(class_name)s(ExtMachInst _machInst, - const char * instMnem, uint64_t setFlags, - InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, - uint8_t _dataSize, uint16_t _ext); + template + %(class_name)s(ExtMachInst mach_inst, const char *inst_mnem, + uint64_t set_flags, uint8_t data_size, uint16_t _ext, + Args... args) : + %(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags, + data_size, _ext, %(op_class)s, args...) + { + %(set_reg_idx_arr)s; + %(constructor)s; + %(cond_control_flag_init)s; + } Fault execute(ExecContext *, Trace::InstRecord *) const override; - - X86ISA::PCState branchTarget( - const X86ISA::PCState &branchPC) const override; - - /// Explicitly import the otherwise hidden branchTarget - using StaticInst::branchTarget; }; }}; -def template MicroRegOpImmDeclare {{ - +def template MicroRegOpBranchDeclare {{ class %(class_name)s : public %(base_class)s { private: %(reg_idx_arr_decl)s; public: - %(class_name)s(ExtMachInst _machInst, - const char * instMnem, uint64_t setFlags, - InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, - uint8_t _dataSize, uint16_t _ext); + template + %(class_name)s(ExtMachInst mach_inst, const char *inst_mnem, + uint64_t set_flags, uint8_t data_size, uint16_t _ext, + Args... args) : + %(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags, + data_size, _ext, %(op_class)s, args...) + { + %(set_reg_idx_arr)s; + %(constructor)s; + %(cond_control_flag_init)s; + } Fault execute(ExecContext *, Trace::InstRecord *) const override; @@ -139,45 +119,7 @@ def template MicroRegOpImmDeclare {{ }; }}; -def template MicroRegOpConstructor {{ - %(class_name)s::%(class_name)s( - ExtMachInst machInst, const char *instMnem, uint64_t setFlags, - InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, - uint8_t _dataSize, uint16_t _ext) : - %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, - _src1, _src2, _dest, _dataSize, _ext, - %(op_class)s) - { - %(set_reg_idx_arr)s; - %(constructor)s; - %(cond_control_flag_init)s; - } - - X86ISA::PCState - %(class_name)s::branchTarget(const X86ISA::PCState &branchPC) const - { - X86ISA::PCState pcs = branchPC; - DPRINTF(X86, "branchTarget PC info: %s, Immediate: %lx\n", - pcs, (int64_t)this->machInst.immediate); - pcs.npc(pcs.npc() + (int64_t)this->machInst.immediate); - pcs.uEnd(); - return pcs; - } -}}; - -def template MicroRegOpImmConstructor {{ - %(class_name)s::%(class_name)s( - ExtMachInst machInst, const char *instMnem, uint64_t setFlags, - InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, - uint8_t _dataSize, uint16_t _ext) : - %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, - _src1, _imm8, _dest, _dataSize, _ext, %(op_class)s) - { - %(set_reg_idx_arr)s; - %(constructor)s; - %(cond_control_flag_init)s; - } - +def template MicroRegOpBranchTarget {{ X86ISA::PCState %(class_name)s::branchTarget(const X86ISA::PCState &branchPC) const { @@ -260,20 +202,36 @@ let {{ decoder_output = "" exec_output = "" - immTemplates = ( - MicroRegOpImmDeclare, - MicroRegOpImmConstructor, - MicroRegOpImmExecute) - - regTemplates = ( - MicroRegOpDeclare, - MicroRegOpConstructor, + branchTemplates = ( + MicroRegOpBranchDeclare, + MicroRegOpBranchTarget, MicroRegOpExecute) + normalTemplates = ( + MicroRegOpDeclare, + None, + MicroRegOpExecute) + + + dest_op = 'X86ISA::RegOpDest' + dbg_dest_op = 'X86ISA::RegOpDbgDest' + cr_dest_op = 'X86ISA::RegOpCrDest' + seg_dest_op = 'X86ISA::RegOpSegDest' + misc_dest_op = 'X86ISA::RegOpMiscDest' + + src1_op = 'X86ISA::RegOpSrc1' + dbg_src1_op = 'X86ISA::RegOpDbgSrc1' + cr_src1_op = 'X86ISA::RegOpCrSrc1' + seg_src1_op = 'X86ISA::RegOpSegSrc1' + misc_src1_op = 'X86ISA::RegOpMiscSrc1' + + src2_op = 'X86ISA::RegOpSrc2' + imm_op = 'X86ISA::RegOpImm8' + class RegOpMeta(type): def buildCppClasses(self, name, Name, suffix, code, big_code, \ flag_code, cond_check, else_code, cond_control_flag_init, - op_class): + op_class, operands): # Globals to stick the output in global header_output @@ -288,9 +246,15 @@ let {{ # If op2 is used anywhere, make register and immediate versions # of this code. - matcher = \ - re.compile(r"(?s?)op2(?P_[^\W_]+)?") + matcher = re.compile( + r"(?s?)op2(?P_[^\W_]+)?") match = matcher.search(allCode + allBigCode) + + imm_operands = list([op if op != 'op2' else imm_op for + op in operands]) + operands = list([op if op != 'op2' else src2_op for + op in operands]) + if match: typeQual = "" if match.group("typeQual"): @@ -303,7 +267,7 @@ let {{ matcher.sub(src2_name, cond_check), matcher.sub(src2_name, else_code), matcher.sub(src2_name, cond_control_flag_init), - op_class) + op_class, operands) imm_name = "%simm8" % match.group("prefix") self.buildCppClasses(name + "i", Name, suffix + "Imm", matcher.sub(imm_name, code), @@ -312,7 +276,7 @@ let {{ matcher.sub(imm_name, cond_check), matcher.sub(imm_name, else_code), matcher.sub(imm_name, cond_control_flag_init), - op_class) + op_class, imm_operands) return # If there's something optional to do with flags, generate @@ -320,7 +284,8 @@ let {{ if flag_code != "" or cond_check != "true": self.buildCppClasses(name, Name, suffix, code, big_code, "", "true", else_code, - "flags[IsUncondControl] = flags[IsControl];", op_class) + "flags[IsUncondControl] = flags[IsControl];", op_class, + operands) suffix = "Flags" + suffix # If psrc1 or psrc2 is used, we need to actually insert code to @@ -329,13 +294,15 @@ let {{ prefix = "" for (rex, decl) in ( ("(?' # If imm8 shows up in the code, use the immediate templates, if # not, hopefully the register ones will be correct. - templates = regTemplates + templates = normalTemplates matcher = re.compile("(?_[^\W_]+)?") + if matcher.search(allCode): + microopClasses[name + 'i'] = cls - # If op2 is used anywhere, make register and immediate versions - # of this code. - matcher = re.compile(r"op2(?P_[^\W_]+)?") - if matcher.search(allCode): - microopClasses[name + 'i'] = cls return cls @@ -432,11 +403,8 @@ let {{ cond_control_flag_init = "" op_class = "IntAluOp" - def __init__(self, dest, src1, op2, flags=None, - dataSize="env.dataSize"): - self.dest = dest - self.src1 = src1 - self.op2 = op2 + def __init__(self, *ops, flags=None, dataSize="env.dataSize"): + self.ops = list(map(str, ops)) self.flags = flags self.dataSize = dataSize if flags is None: @@ -448,6 +416,7 @@ let {{ self.className += "Flags" def getAllocator(self, microFlags): + op_args = ', '.join(self.ops) if self.big_code != "": className = self.className if self.mnemonic == self.base_mnemonic + 'i': @@ -455,17 +424,16 @@ let {{ allocString = ''' (%(dataSize)s >= 4) ? (StaticInstPtr)(new %(class_name)sBig(machInst, - macrocodeBlock, %(flags)s, %(src1)s, %(op2)s, - %(dest)s, %(dataSize)s, %(ext)s)) : + macrocodeBlock, %(flags)s, %(dataSize)s, %(ext)s, + %(op_args)s)) : (StaticInstPtr)(new %(class_name)s(machInst, - macrocodeBlock, %(flags)s, %(src1)s, %(op2)s, - %(dest)s, %(dataSize)s, %(ext)s)) + macrocodeBlock, %(flags)s, %(dataSize)s, %(ext)s, + %(op_args)s)) ''' allocator = allocString % { "class_name" : className, "flags" : self.microFlagsText(microFlags), - "src1" : self.src1, "op2" : self.op2, - "dest" : self.dest, + "op_args" : op_args, "dataSize" : self.dataSize, "ext" : self.ext} return allocator @@ -474,17 +442,24 @@ let {{ if self.mnemonic == self.base_mnemonic + 'i': className += "Imm" allocator = '''new %(class_name)s(machInst, macrocodeBlock, - %(flags)s, %(src1)s, %(op2)s, %(dest)s, - %(dataSize)s, %(ext)s)''' % { + %(flags)s, %(dataSize)s, %(ext)s, %(op_args)s)''' % { "class_name" : className, "flags" : self.microFlagsText(microFlags), - "src1" : self.src1, "op2" : self.op2, - "dest" : self.dest, + "op_args" : op_args, "dataSize" : self.dataSize, "ext" : self.ext} return allocator - class LogicRegOp(RegOp): + class BasicRegOp(RegOp): + operands = (dest_op, src1_op, 'op2') + abstract = True + + def __init__(self, dest, src1, src2, flags=None, + dataSize="env.dataSize"): + super(BasicRegOp, self).__init__(dest, src1, src2, flags=flags, + dataSize=dataSize) + + class LogicRegOp(BasicRegOp): abstract = True flag_code = ''' //Don't have genFlags handle the OF or CF bits @@ -500,7 +475,7 @@ let {{ PredecfBit = PredecfBit & ~(ECFBit & ext); ''' - class FlagRegOp(RegOp): + class FlagRegOp(BasicRegOp): abstract = True flag_code = ''' uint64_t newFlags = genFlags(PredccFlagBits | PredcfofBits | @@ -514,7 +489,7 @@ let {{ PredccFlagBits = newFlags & ccFlagMask; ''' - class SubRegOp(RegOp): + class SubRegOp(BasicRegOp): abstract = True flag_code = ''' uint64_t newFlags = genFlags(PredccFlagBits | PredcfofBits | @@ -535,75 +510,77 @@ let {{ cond_control_flag_init = "flags[IsCondControl] = flags[IsControl];" class RdRegOp(RegOp): + operands = (dest_op, src1_op) abstract = True def __init__(self, dest, src1=None, dataSize="env.dataSize"): if not src1: src1 = dest - super(RdRegOp, self).__init__(dest, src1, \ - "InstRegIndex(NUM_INTREGS)", None, dataSize) + super(RdRegOp, self).__init__(dest, src1, dataSize=dataSize) class WrRegOp(RegOp): + operands = (src1_op, 'op2') + abstract = True def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): - super(WrRegOp, self).__init__("InstRegIndex(NUM_INTREGS)", \ - src1, src2, flags, dataSize) + super(WrRegOp, self).__init__( + src1, src2, flags=flags, dataSize=dataSize) class Add(FlagRegOp): code = ''' result = psrc1 + op2; - DestReg = merge(DestReg, result, dataSize); + SDestReg = merge(SDestReg, result, dataSize); ''' - big_code = 'DestReg = result = (psrc1 + op2) & mask(dataSize * 8);' + big_code = 'SDestReg = result = (psrc1 + op2) & mask(dataSize * 8);' class Or(LogicRegOp): code = ''' result = psrc1 | op2; - DestReg = merge(DestReg, result, dataSize); + SDestReg = merge(SDestReg, result, dataSize); ''' - big_code = 'DestReg = result = (psrc1 | op2) & mask(dataSize * 8);' + big_code = 'SDestReg = result = (psrc1 | op2) & mask(dataSize * 8);' class Adc(FlagRegOp): code = ''' CCFlagBits flags = cfofBits; result = psrc1 + op2 + flags.cf; - DestReg = merge(DestReg, result, dataSize); + SDestReg = merge(SDestReg, result, dataSize); ''' big_code = ''' CCFlagBits flags = cfofBits; - DestReg = result = (psrc1 + op2 + flags.cf) & mask(dataSize * 8); + SDestReg = result = (psrc1 + op2 + flags.cf) & mask(dataSize * 8); ''' class Sbb(SubRegOp): code = ''' CCFlagBits flags = cfofBits; result = psrc1 - op2 - flags.cf; - DestReg = merge(DestReg, result, dataSize); + SDestReg = merge(SDestReg, result, dataSize); ''' big_code = ''' CCFlagBits flags = cfofBits; - DestReg = result = (psrc1 - op2 - flags.cf) & mask(dataSize * 8); + SDestReg = result = (psrc1 - op2 - flags.cf) & mask(dataSize * 8); ''' class And(LogicRegOp): code = ''' result = psrc1 & op2; - DestReg = merge(DestReg, result, dataSize) + SDestReg = merge(SDestReg, result, dataSize) ''' - big_code = 'DestReg = result = (psrc1 & op2) & mask(dataSize * 8)' + big_code = 'SDestReg = result = (psrc1 & op2) & mask(dataSize * 8)' class Sub(SubRegOp): code = ''' result = psrc1 - op2; - DestReg = merge(DestReg, result, dataSize) + DestReg = merge(SDestReg, result, dataSize) ''' - big_code = 'DestReg = result = (psrc1 - op2) & mask(dataSize * 8)' + big_code = 'SDestReg = result = (psrc1 - op2) & mask(dataSize * 8)' class Xor(LogicRegOp): code = ''' result = psrc1 ^ op2; - DestReg = merge(DestReg, result, dataSize) + SDestReg = merge(SDestReg, result, dataSize) ''' - big_code = 'DestReg = result = (psrc1 ^ op2) & mask(dataSize * 8)' + big_code = 'SDestReg = result = (psrc1 ^ op2) & mask(dataSize * 8)' class Mul1s(WrRegOp): op_class = 'IntMultOp' @@ -699,17 +676,17 @@ let {{ ''' class Mulel(RdRegOp): - code = 'DestReg = merge(SrcReg1, ProdLow, dataSize);' - big_code = 'DestReg = ProdLow & mask(dataSize * 8);' + code = 'SDestReg = merge(SSrcReg1, ProdLow, dataSize);' + big_code = 'SDestReg = ProdLow & mask(dataSize * 8);' class Muleh(RdRegOp): - def __init__(self, dest, src1=None, flags=None, dataSize="env.dataSize"): + def __init__(self, dest, src1=None, flags=None, + dataSize="env.dataSize"): if not src1: src1 = dest - super(RdRegOp, self).__init__(dest, src1, \ - "InstRegIndex(NUM_INTREGS)", flags, dataSize) - code = 'DestReg = merge(SrcReg1, ProdHi, dataSize);' - big_code = 'DestReg = ProdHi & mask(dataSize * 8);' + super(RdRegOp, self).__init__(dest, src1, dataSize=dataSize) + code = 'SDestReg = merge(SSrcReg1, ProdHi, dataSize);' + big_code = 'SDestReg = ProdHi & mask(dataSize * 8);' # One or two bit divide class Div1(WrRegOp): @@ -738,7 +715,7 @@ let {{ ''' # Step divide - class Div2(RegOp): + class Div2(BasicRegOp): op_class = 'IntDivOp' divCode = ''' @@ -755,7 +732,7 @@ let {{ if (divisor & (1ULL << 63)) { while (remaining && !(dividend & (1ULL << 63))) { dividend = (dividend << 1) | - bits(SrcReg1, remaining - 1); + bits(SSrcReg1, remaining - 1); quotient <<= 1; remaining--; } @@ -764,7 +741,7 @@ let {{ if (dividend < divisor && remaining) { highBit = true; dividend = (dividend << 1) | - bits(SrcReg1, remaining - 1); + bits(SSrcReg1, remaining - 1); quotient <<= 1; remaining--; } @@ -778,7 +755,7 @@ let {{ //Shift in bits from the low order portion of the dividend while (dividend < divisor && remaining) { dividend = (dividend << 1) | - bits(SrcReg1, remaining - 1); + bits(SSrcReg1, remaining - 1); quotient <<= 1; remaining--; } @@ -793,8 +770,8 @@ let {{ Remainder = remainder; Quotient = quotient; ''' - code = divCode % "DestReg = merge(DestReg, remaining, dataSize);" - big_code = divCode % "DestReg = remaining & mask(dataSize * 8);" + code = divCode % "SDestReg = merge(SDestReg, remaining, dataSize);" + big_code = divCode % "SDestReg = remaining & mask(dataSize * 8);" flag_code = ''' if (remaining == 0) PredezfBit = PredezfBit | (ext & EZFBit); @@ -803,27 +780,27 @@ let {{ ''' class Divq(RdRegOp): - code = 'DestReg = merge(SrcReg1, Quotient, dataSize);' - big_code = 'DestReg = Quotient & mask(dataSize * 8);' + code = 'SDestReg = merge(SSrcReg1, Quotient, dataSize);' + big_code = 'SDestReg = Quotient & mask(dataSize * 8);' class Divr(RdRegOp): - code = 'DestReg = merge(SrcReg1, Remainder, dataSize);' - big_code = 'DestReg = Remainder & mask(dataSize * 8);' + code = 'SDestReg = merge(SSrcReg1, Remainder, dataSize);' + big_code = 'SDestReg = Remainder & mask(dataSize * 8);' - class Mov(CondRegOp): - code = 'DestReg = merge(SrcReg1, op2, dataSize)' - else_code = 'DestReg = DestReg;' + class Mov(BasicRegOp, CondRegOp): + code = 'SDestReg = merge(SSrcReg1, op2, dataSize)' + else_code = 'SDestReg = SDestReg;' # Shift instructions - class Sll(RegOp): + class Sll(BasicRegOp): code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); - DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize); + SDestReg = merge(SDestReg, psrc1 << shiftAmt, dataSize); ''' big_code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); - DestReg = (psrc1 << shiftAmt) & mask(dataSize * 8); + SDestReg = (psrc1 << shiftAmt) & mask(dataSize * 8); ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -836,7 +813,7 @@ let {{ int CFBits = 0; //Figure out if we -would- set the CF bits if requested. if (shiftAmt <= dataSize * 8 && - bits(SrcReg1, dataSize * 8 - shiftAmt)) { + bits(SSrcReg1, dataSize * 8 - shiftAmt)) { CFBits = 1; } @@ -848,14 +825,14 @@ let {{ //Figure out what the OF bit should be. if ((ext & OFBit) && - (CFBits ^ bits(DestReg, dataSize * 8 - 1))) { + (CFBits ^ bits(SDestReg, dataSize * 8 - 1))) { PredcfofBits = PredcfofBits | OFBit; } //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -863,20 +840,20 @@ let {{ } ''' - class Srl(RegOp): + class Srl(BasicRegOp): # Because what happens to the bits shift -in- on a right shift # is not defined in the C/C++ standard, we have to mask them out # to be sure they're zero. code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); uint64_t logicalMask = mask(dataSize * 8 - shiftAmt); - DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, + SDestReg = merge(SDestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize); ''' big_code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); uint64_t logicalMask = mask(dataSize * 8 - shiftAmt); - DestReg = (psrc1 >> shiftAmt) & logicalMask; + SDestReg = (psrc1 >> shiftAmt) & logicalMask; ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -889,19 +866,19 @@ let {{ //If some combination of the CF bits need to be set, set them. if ((ext & (CFBit | ECFBit)) && shiftAmt <= dataSize * 8 && - bits(SrcReg1, shiftAmt - 1)) { + bits(SSrcReg1, shiftAmt - 1)) { PredcfofBits = PredcfofBits | (ext & CFBit); PredecfBit = PredecfBit | (ext & ECFBit); } //Figure out what the OF bit should be. - if ((ext & OFBit) && bits(SrcReg1, dataSize * 8 - 1)) + if ((ext & OFBit) && bits(SSrcReg1, dataSize * 8 - 1)) PredcfofBits = PredcfofBits | OFBit; //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -909,7 +886,7 @@ let {{ } ''' - class Sra(RegOp): + class Sra(BasicRegOp): # Because what happens to the bits shift -in- on a right shift # is not defined in the C/C++ standard, we have to sign extend # them manually to be sure. @@ -917,13 +894,14 @@ let {{ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); uint64_t arithMask = (shiftAmt == 0) ? 0 : -bits(psrc1, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt); - DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize); + SDestReg = merge(SDestReg, + (psrc1 >> shiftAmt) | arithMask, dataSize); ''' big_code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); uint64_t arithMask = (shiftAmt == 0) ? 0 : -bits(psrc1, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt); - DestReg = ((psrc1 >> shiftAmt) | arithMask) & mask(dataSize * 8); + SDestReg = ((psrc1 >> shiftAmt) | arithMask) & mask(dataSize * 8); ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -937,7 +915,7 @@ let {{ uint8_t effectiveShift = (shiftAmt <= dataSize * 8) ? shiftAmt : (dataSize * 8); if ((ext & (CFBit | ECFBit)) && - bits(SrcReg1, effectiveShift - 1)) { + bits(SSrcReg1, effectiveShift - 1)) { PredcfofBits = PredcfofBits | (ext & CFBit); PredecfBit = PredecfBit | (ext & ECFBit); } @@ -945,7 +923,7 @@ let {{ //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -953,7 +931,7 @@ let {{ } ''' - class Ror(RegOp): + class Ror(BasicRegOp): code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); @@ -961,9 +939,9 @@ let {{ if (realShiftAmt) { uint64_t top = psrc1 << (dataSize * 8 - realShiftAmt); uint64_t bottom = bits(psrc1, dataSize * 8, realShiftAmt); - DestReg = merge(DestReg, top | bottom, dataSize); + SDestReg = merge(SDestReg, top | bottom, dataSize); } else - DestReg = merge(DestReg, DestReg, dataSize); + SDestReg = merge(SDestReg, SDestReg, dataSize); ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -974,8 +952,8 @@ let {{ PredecfBit = PredecfBit & ~(ext & ECFBit); //Find the most and second most significant bits of the result. - int msb = bits(DestReg, dataSize * 8 - 1); - int smsb = bits(DestReg, dataSize * 8 - 2); + int msb = bits(SDestReg, dataSize * 8 - 1); + int smsb = bits(SDestReg, dataSize * 8 - 2); //If some combination of the CF bits need to be set, set them. if ((ext & (CFBit | ECFBit)) && msb) { PredcfofBits = PredcfofBits | (ext & CFBit); @@ -989,7 +967,7 @@ let {{ //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -997,7 +975,7 @@ let {{ } ''' - class Rcr(RegOp): + class Rcr(BasicRegOp): code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); @@ -1008,9 +986,9 @@ let {{ if (realShiftAmt > 1) top |= psrc1 << (dataSize * 8 - realShiftAmt + 1); uint64_t bottom = bits(psrc1, dataSize * 8 - 1, realShiftAmt); - DestReg = merge(DestReg, top | bottom, dataSize); + SDestReg = merge(SDestReg, top | bottom, dataSize); } else - DestReg = merge(DestReg, DestReg, dataSize); + SDestReg = merge(SDestReg, SDestReg, dataSize); ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -1023,13 +1001,13 @@ let {{ //Figure out what the OF bit should be. if ((ext & OFBit) && (origCFBit ^ - bits(SrcReg1, dataSize * 8 - 1))) { + bits(SSrcReg1, dataSize * 8 - 1))) { PredcfofBits = PredcfofBits | OFBit; } //If some combination of the CF bits need to be set, set them. if ((ext & (CFBit | ECFBit)) && (realShiftAmt == 0) ? origCFBit : - bits(SrcReg1, realShiftAmt - 1)) { + bits(SSrcReg1, realShiftAmt - 1)) { PredcfofBits = PredcfofBits | (ext & CFBit); PredecfBit = PredecfBit | (ext & ECFBit); } @@ -1037,7 +1015,7 @@ let {{ //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -1045,7 +1023,7 @@ let {{ } ''' - class Rol(RegOp): + class Rol(BasicRegOp): code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); @@ -1054,9 +1032,9 @@ let {{ uint64_t top = psrc1 << realShiftAmt; uint64_t bottom = bits(psrc1, dataSize * 8 - 1, dataSize * 8 - realShiftAmt); - DestReg = merge(DestReg, top | bottom, dataSize); + SDestReg = merge(SDestReg, top | bottom, dataSize); } else - DestReg = merge(DestReg, DestReg, dataSize); + SDestReg = merge(SDestReg, SDestReg, dataSize); ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -1067,8 +1045,8 @@ let {{ PredecfBit = PredecfBit & ~(ext & ECFBit); //The CF bits, if set, would be set to the lsb of the result. - int lsb = DestReg & 0x1; - int msb = bits(DestReg, dataSize * 8 - 1); + int lsb = SDestReg & 0x1; + int msb = bits(SDestReg, dataSize * 8 - 1); //If some combination of the CF bits need to be set, set them. if ((ext & (CFBit | ECFBit)) && lsb) { PredcfofBits = PredcfofBits | (ext & CFBit); @@ -1082,7 +1060,7 @@ let {{ //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -1090,7 +1068,7 @@ let {{ } ''' - class Rcl(RegOp): + class Rcl(BasicRegOp): code = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); @@ -1103,9 +1081,9 @@ let {{ bottom |= bits(psrc1, dataSize * 8 - 1, dataSize * 8 - realShiftAmt + 1); - DestReg = merge(DestReg, top | bottom, dataSize); + SDestReg = merge(SDestReg, top | bottom, dataSize); } else - DestReg = merge(DestReg, DestReg, dataSize); + SDestReg = merge(SDestReg, SDestReg, dataSize); ''' flag_code = ''' // If the shift amount is zero, no flags should be modified. @@ -1116,8 +1094,8 @@ let {{ PredcfofBits = PredcfofBits & ~(ext & (CFBit | OFBit)); PredecfBit = PredecfBit & ~(ext & ECFBit); - int msb = bits(DestReg, dataSize * 8 - 1); - int CFBits = bits(SrcReg1, dataSize * 8 - realShiftAmt); + int msb = bits(SDestReg, dataSize * 8 - 1); + int CFBits = bits(SSrcReg1, dataSize * 8 - realShiftAmt); //If some combination of the CF bits need to be set, set them. if ((ext & (CFBit | ECFBit)) && (realShiftAmt == 0) ? origCFBit : CFBits) { @@ -1132,7 +1110,7 @@ let {{ //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -1140,7 +1118,7 @@ let {{ } ''' - class Sld(RegOp): + class Sld(BasicRegOp): sldCode = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); uint8_t dataBits = dataSize * 8; @@ -1157,8 +1135,8 @@ let {{ } %s ''' - code = sldCode % "DestReg = merge(DestReg, result, dataSize);" - big_code = sldCode % "DestReg = result & mask(dataSize * 8);" + code = sldCode % "SDestReg = merge(SDestReg, result, dataSize);" + big_code = sldCode % "SDestReg = result & mask(dataSize * 8);" flag_code = ''' // If the shift amount is zero, no flags should be modified. if (shiftAmt) { @@ -1172,7 +1150,7 @@ let {{ if ((realShiftAmt == 0 && bits(DoubleBits, 0)) || (realShiftAmt <= dataBits && - bits(SrcReg1, dataBits - realShiftAmt)) || + bits(SSrcReg1, dataBits - realShiftAmt)) || (realShiftAmt > dataBits && bits(DoubleBits, 2 * dataBits - realShiftAmt))) { CFBits = 1; @@ -1185,14 +1163,14 @@ let {{ } //Figure out what the OF bit should be. - if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ + if ((ext & OFBit) && (bits(SSrcReg1, dataBits - 1) ^ bits(result, dataBits - 1))) PredcfofBits = PredcfofBits | OFBit; //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -1200,7 +1178,7 @@ let {{ } ''' - class Srd(RegOp): + class Srd(BasicRegOp): srdCode = ''' uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); uint8_t dataBits = dataSize * 8; @@ -1223,8 +1201,8 @@ let {{ } %s ''' - code = srdCode % "DestReg = merge(DestReg, result, dataSize);" - big_code = srdCode % "DestReg = result & mask(dataSize * 8);" + code = srdCode % "SDestReg = merge(SDestReg, result, dataSize);" + big_code = srdCode % "SDestReg = result & mask(dataSize * 8);" flag_code = ''' // If the shift amount is zero, no flags should be modified. if (shiftAmt) { @@ -1238,7 +1216,7 @@ let {{ if ((realShiftAmt == 0 && bits(DoubleBits, dataBits - 1)) || (realShiftAmt <= dataBits && - bits(SrcReg1, realShiftAmt - 1)) || + bits(SSrcReg1, realShiftAmt - 1)) || (realShiftAmt > dataBits && bits(DoubleBits, realShiftAmt - dataBits - 1))) { CFBits = 1; @@ -1251,14 +1229,14 @@ let {{ } //Figure out what the OF bit should be. - if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^ + if ((ext & OFBit) && (bits(SSrcReg1, dataBits - 1) ^ bits(result, dataBits - 1))) PredcfofBits = PredcfofBits | OFBit; //Use the regular mechanisms to calculate the other flags. uint64_t newFlags = genFlags(PredccFlagBits | PreddfBit | PredezfBit, ext & ~(CFBit | ECFBit | OFBit), - DestReg, psrc1, op2); + SDestReg, psrc1, op2); PredezfBit = newFlags & EZFBit; PreddfBit = newFlags & DFBit; @@ -1300,14 +1278,14 @@ let {{ ''' class Rdip(RdRegOp): - code = 'DestReg = NRIP - CSBase;' + code = 'SDestReg = NRIP - CSBase;' class Ruflags(RdRegOp): - code = 'DestReg = ccFlagBits | cfofBits | dfBit | ecfBit | ezfBit;' + code = 'SDestReg = ccFlagBits | cfofBits | dfBit | ecfBit | ezfBit;' class Rflags(RdRegOp): code = ''' - DestReg = ccFlagBits | cfofBits | dfBit | + SDestReg = ccFlagBits | cfofBits | dfBit | ecfBit | ezfBit | nccFlagBits; ''' @@ -1315,21 +1293,22 @@ let {{ code = ''' int flag = bits(ccFlagBits | cfofBits | dfBit | ecfBit | ezfBit, imm8); - DestReg = merge(DestReg, flag, dataSize); + SDestReg = merge(SDestReg, flag, dataSize); ezfBit = (flag == 0) ? EZFBit : 0; ''' big_code = ''' int flag = bits(ccFlagBits | cfofBits | dfBit | ecfBit | ezfBit, imm8); - DestReg = flag & mask(dataSize * 8); + SDestReg = flag & mask(dataSize * 8); ezfBit = (flag == 0) ? EZFBit : 0; ''' - def __init__(self, dest, imm, flags=None, \ - dataSize="env.dataSize"): - super(Ruflag, self).__init__(dest, \ - "InstRegIndex(NUM_INTREGS)", imm, flags, dataSize) + operands = (dest_op, imm_op) + + def __init__(self, dest, imm, flags=None, dataSize="env.dataSize"): + super(Ruflag, self).__init__(dest, imm, flags=flags, + dataSize=dataSize) class Rflag(RegOp): code = ''' @@ -1338,7 +1317,7 @@ let {{ ecfBit | ezfBit) & flagMask; int flag = bits(flags, imm8); - DestReg = merge(DestReg, flag, dataSize); + SDestReg = merge(SDestReg, flag, dataSize); ezfBit = (flag == 0) ? EZFBit : 0; ''' @@ -1348,16 +1327,16 @@ let {{ ecfBit | ezfBit) & flagMask; int flag = bits(flags, imm8); - DestReg = flag & mask(dataSize * 8); + SDestReg = flag & mask(dataSize * 8); ezfBit = (flag == 0) ? EZFBit : 0; ''' - def __init__(self, dest, imm, flags=None, \ - dataSize="env.dataSize"): - super(Rflag, self).__init__(dest, \ - "InstRegIndex(NUM_INTREGS)", imm, flags, dataSize) + operands = (dest_op, imm_op) + def __init__(self, dest, imm, flags=None, dataSize="env.dataSize"): + super(Rflag, self).__init__(dest, imm, flags=flags, + dataSize=dataSize) - class Sext(RegOp): + class Sext(BasicRegOp): code = ''' RegVal val = psrc1; // Mask the bit position so that it wraps. @@ -1365,7 +1344,7 @@ let {{ int sign_bit = bits(val, bitPos, bitPos); uint64_t maskVal = mask(bitPos+1); val = sign_bit ? (val | ~maskVal) : (val & maskVal); - DestReg = merge(DestReg, val, dataSize); + SDestReg = merge(SDestReg, val, dataSize); ''' big_code = ''' @@ -1375,7 +1354,7 @@ let {{ int sign_bit = bits(val, bitPos, bitPos); uint64_t maskVal = mask(bitPos+1); val = sign_bit ? (val | ~maskVal) : (val & maskVal); - DestReg = val & mask(dataSize * 8); + SDestReg = val & mask(dataSize * 8); ''' flag_code = ''' @@ -1392,14 +1371,15 @@ let {{ } ''' - class Zext(RegOp): - code = 'DestReg = merge(DestReg, bits(psrc1, op2, 0), dataSize);' - big_code = 'DestReg = bits(psrc1, op2, 0) & mask(dataSize * 8);' + class Zext(BasicRegOp): + code = 'SDestReg = merge(SDestReg, bits(psrc1, op2, 0), dataSize);' + big_code = 'SDestReg = bits(psrc1, op2, 0) & mask(dataSize * 8);' class Rddr(RegOp): + operands = (dest_op, dbg_src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Rddr, self).__init__(dest, \ - src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(Rddr, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) rdrCode = ''' CR4 cr4 = CR4Op; DR7 dr7 = DR7Op; @@ -1411,13 +1391,14 @@ let {{ %s } ''' - code = rdrCode % "DestReg = merge(DestReg, DebugSrc1, dataSize);" - big_code = rdrCode % "DestReg = DebugSrc1 & mask(dataSize * 8);" + code = rdrCode % "SDestReg = merge(SDestReg, DebugSrc1, dataSize);" + big_code = rdrCode % "SDestReg = DebugSrc1 & mask(dataSize * 8);" class Wrdr(RegOp): + operands = (dbg_dest_op, src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Wrdr, self).__init__(dest, \ - src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(Wrdr, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) code = ''' CR4 cr4 = CR4Op; DR7 dr7 = DR7Op; @@ -1434,9 +1415,10 @@ let {{ ''' class Rdcr(RegOp): + operands = (dest_op, cr_src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Rdcr, self).__init__(dest, \ - src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(Rdcr, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) rdcrCode = ''' if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) { fault = std::make_shared(); @@ -1444,13 +1426,14 @@ let {{ %s } ''' - code = rdcrCode % "DestReg = merge(DestReg, ControlSrc1, dataSize);" - big_code = rdcrCode % "DestReg = ControlSrc1 & mask(dataSize * 8);" + code = rdcrCode % "SDestReg = merge(SDestReg, ControlSrc1, dataSize);" + big_code = rdcrCode % "SDestReg = ControlSrc1 & mask(dataSize * 8);" class Wrcr(RegOp): + operands = (cr_dest_op, src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Wrcr, self).__init__(dest, \ - src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(Wrcr, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) code = ''' if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { fault = std::make_shared(); @@ -1501,71 +1484,83 @@ let {{ # Microops for manipulating segmentation registers class SegOp(CondRegOp): abstract = True + operands = (seg_dest_op, src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(SegOp, self).__init__(dest, \ - src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(SegOp, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) - class Wrbase(SegOp): + class WrSegOp(CondRegOp): + abstract = True + operands = (seg_dest_op, src1_op) + + class Wrbase(WrSegOp): code = ''' SegBaseDest = psrc1; ''' - class Wrlimit(SegOp): + class Wrlimit(WrSegOp): code = ''' SegLimitDest = psrc1; ''' - class Wrsel(SegOp): + class Wrsel(WrSegOp): code = ''' SegSelDest = psrc1; ''' - class WrAttr(SegOp): + class WrAttr(WrSegOp): code = ''' SegAttrDest = psrc1; ''' - class Rdbase(SegOp): - code = 'DestReg = merge(DestReg, SegBaseSrc1, dataSize);' - big_code = 'DestReg = SegBaseSrc1 & mask(dataSize * 8);' + class RdSegOp(CondRegOp): + abstract = True + operands = (dest_op, seg_src1_op) - class Rdlimit(SegOp): - code = 'DestReg = merge(DestReg, SegLimitSrc1, dataSize);' - big_code = 'DestReg = SegLimitSrc1 & mask(dataSize * 8);' + class Rdbase(RdSegOp): + code = 'SDestReg = merge(SDestReg, SegBaseSrc1, dataSize);' + big_code = 'SDestReg = SegBaseSrc1 & mask(dataSize * 8);' - class RdAttr(SegOp): - code = 'DestReg = merge(DestReg, SegAttrSrc1, dataSize);' - big_code = 'DestReg = SegAttrSrc1 & mask(dataSize * 8);' + class Rdlimit(RdSegOp): + code = 'SDestReg = merge(SDestReg, SegLimitSrc1, dataSize);' + big_code = 'SDestReg = SegLimitSrc1 & mask(dataSize * 8);' - class Rdsel(SegOp): - code = 'DestReg = merge(DestReg, SegSelSrc1, dataSize);' - big_code = 'DestReg = SegSelSrc1 & mask(dataSize * 8);' + class RdAttr(RdSegOp): + code = 'SDestReg = merge(SDestReg, SegAttrSrc1, dataSize);' + big_code = 'SDestReg = SegAttrSrc1 & mask(dataSize * 8);' + + class Rdsel(RdSegOp): + code = 'SDestReg = merge(SDestReg, SegSelSrc1, dataSize);' + big_code = 'SDestReg = SegSelSrc1 & mask(dataSize * 8);' class Rdval(RegOp): + operands = (dest_op, misc_src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Rdval, self).__init__(dest, src1, \ - "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(Rdval, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) code = ''' - DestReg = MiscRegSrc1; + SDestReg = MiscRegSrc1; ''' class Wrval(RegOp): + operands = (misc_dest_op, src1_op) def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Wrval, self).__init__(dest, src1, \ - "InstRegIndex(NUM_INTREGS)", flags, dataSize) + super(Wrval, self).__init__(dest, src1, flags=flags, + dataSize=dataSize) code = ''' - MiscRegDest = SrcReg1; + MiscRegDest = SSrcReg1; ''' class Chks(RegOp): - def __init__(self, dest, src1, src2=0, - flags=None, dataSize="env.dataSize"): - super(Chks, self).__init__(dest, - src1, src2, flags, dataSize) + operands = (src1_op, src2_op, imm_op) + def __init__(self, src1, src2, imm=0, flags=None, + dataSize="env.dataSize"): + super(Chks, self).__init__(src1, src2, imm, flags=flags, + dataSize=dataSize) code = ''' // The selector is in source 1 and can be at most 16 bits. - SegSelector selector = DestReg; - SegDescriptor desc = SrcReg1; + SegSelector selector = SSrcReg1; + SegDescriptor desc = SSrcReg2; HandyM5Reg m5reg = M5Reg; switch (imm8) @@ -1680,11 +1675,11 @@ let {{ } ''' - class Wrdh(RegOp): + class Wrdh(BasicRegOp): code = ''' - SegDescriptor desc = SrcReg1; + SegDescriptor desc = SSrcReg1; - uint64_t target = bits(SrcReg2, 31, 0) << 32; + uint64_t target = bits(SSrcReg2, 31, 0) << 32; switch(desc.type) { case LDT64: case AvailableTSS64: @@ -1701,7 +1696,7 @@ let {{ fault = std::make_shared( "Wrdh used with wrong descriptor type!\\n"); } - DestReg = target; + SDestReg = target; ''' class Wrtsc(WrRegOp): @@ -1711,18 +1706,19 @@ let {{ class Rdtsc(RdRegOp): code = ''' - DestReg = TscOp; + SDestReg = TscOp; ''' class Rdm5reg(RdRegOp): code = ''' - DestReg = M5Reg; + SDestReg = M5Reg; ''' - class Wrdl(RegOp): + class Wrdl(BasicRegOp): + operands = (seg_dest_op, src1_op, 'op2') code = ''' - SegDescriptor desc = SrcReg1; - SegSelector selector = SrcReg2; + SegDescriptor desc = SSrcReg1; + SegSelector selector = SSrcReg2; // This while loop is so we can use break statements in the code // below to skip the rest of this section without a bunch of // nesting. @@ -1776,27 +1772,28 @@ let {{ } ''' - class Wrxftw(WrRegOp): - def __init__(self, src1, **kwargs): - super(Wrxftw, self).__init__(src1, "InstRegIndex(NUM_INTREGS)", \ - **kwargs) + class Wrxftw(RegOp): + operands = (src1_op,) + def __init__(self, src1, flags=None, dataSize="env.dataSize"): + super(Wrxftw, self).__init__(src1, flags=None, dataSize=dataSize) code = ''' - FTW = X86ISA::convX87XTagsToTags(SrcReg1); + FTW = X86ISA::convX87XTagsToTags(SSrcReg1); ''' class Rdxftw(RdRegOp): code = ''' - DestReg = X86ISA::convX87TagsToXTags(FTW); + SDestReg = X86ISA::convX87TagsToXTags(FTW); ''' - class Popcnt(RegOp): - code = 'DestReg = merge(DestReg, popCount(psrc1), dataSize);' + class Popcnt(BasicRegOp): + code = 'SDestReg = merge(SDestReg, popCount(psrc1), dataSize);' flag_code = ''' - ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit); - if (findZero(dataSize * 8, SrcReg1)) { - ccFlagBits = ccFlagBits | ZFBit; + ccFlagBits = ccFlagBits & ~(X86ISA::SFBit | X86ISA::AFBit | + X86ISA::ZFBit | X86ISA::PFBit); + if (findZero(dataSize * 8, SSrcReg1)) { + ccFlagBits = ccFlagBits | X86ISA::ZFBit; } - cfofBits = cfofBits & ~(OFBit | CFBit); + cfofBits = cfofBits & ~(X86ISA::OFBit | X86ISA::CFBit); ''' }}; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index a1a83966e8..3b805f784a 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -55,12 +55,14 @@ def operand_types {{ let {{ def foldInt(idx, foldBit, id): - return ('IntReg', 'uqw', 'INTREG_FOLDED(%s, %s)' % (idx, foldBit), - 'IsInteger', id) + return ('IntReg', 'uqw', + 'X86ISA::INTREG_FOLDED(%s, %s)' % (idx, foldBit), 'IsInteger', + id) def intReg(idx, id): return ('IntReg', 'uqw', idx, 'IsInteger', id) def impIntReg(idx, id): - return ('IntReg', 'uqw', 'INTREG_IMPLICIT(%s)' % idx, 'IsInteger', id) + return ('IntReg', 'uqw', 'X86ISA::INTREG_IMPLICIT(%s)' % idx, + 'IsInteger', id) def floatReg(idx, id): return ('FloatReg', 'df', idx, 'IsFloating', id) def ccReg(idx, id): @@ -81,7 +83,7 @@ let {{ def squashCReg(idx, id, ctype = 'uqw'): return squashCheckReg(idx, id, 'true', ctype) def squashCSReg(idx, id, ctype = 'uqw'): - return squashCheckReg(idx, id, 'dest == SEGMENT_REG_CS', ctype) + return squashCheckReg(idx, id, 'dest == X86ISA::SEGMENT_REG_CS', ctype) def squashCR0Reg(idx, id, ctype = 'uqw'): return squashCheckReg(idx, id, 'dest == 0', ctype) }}; @@ -104,16 +106,16 @@ def operands {{ 'Remainder': impIntReg(3, 10), 'Divisor': impIntReg(4, 11), 'DoubleBits': impIntReg(5, 11), - 'Rax': intReg('(INTREG_RAX)', 12), - 'Rbx': intReg('(INTREG_RBX)', 13), - 'Rcx': intReg('(INTREG_RCX)', 14), - 'Rdx': intReg('(INTREG_RDX)', 15), - 'Rsp': intReg('(INTREG_RSP)', 16), - 'Rbp': intReg('(INTREG_RBP)', 17), - 'Rsi': intReg('(INTREG_RSI)', 18), - 'Rdi': intReg('(INTREG_RDI)', 19), - 'R8': intReg('(INTREG_R8)', 20), - 'R9': intReg('(INTREG_R9)', 21), + 'Rax': intReg('X86ISA::INTREG_RAX', 12), + 'Rbx': intReg('X86ISA::INTREG_RBX', 13), + 'Rcx': intReg('X86ISA::INTREG_RCX', 14), + 'Rdx': intReg('X86ISA::INTREG_RDX', 15), + 'Rsp': intReg('X86ISA::INTREG_RSP', 16), + 'Rbp': intReg('X86ISA::INTREG_RBP', 17), + 'Rsi': intReg('X86ISA::INTREG_RSI', 18), + 'Rdi': intReg('X86ISA::INTREG_RDI', 19), + 'R8': intReg('X86ISA::INTREG_R8', 20), + 'R9': intReg('X86ISA::INTREG_R9', 21), 'FpSrcReg1': floatReg('src1', 22), 'FpSrcReg2': floatReg('src2', 23), 'FpDestReg': floatReg('dest', 24), @@ -126,11 +128,11 @@ def operands {{ (None, None, 'IsControl'), 50), # These registers hold the condition code portion of the flag # register. The nccFlagBits version holds the rest. - 'ccFlagBits': ccReg('(CCREG_ZAPS)', 60), - 'cfofBits': ccReg('(CCREG_CFOF)', 61), - 'dfBit': ccReg('(CCREG_DF)', 62), - 'ecfBit': ccReg('(CCREG_ECF)', 63), - 'ezfBit': ccReg('(CCREG_EZF)', 64), + 'ccFlagBits': ccReg('X86ISA::CCREG_ZAPS', 60), + 'cfofBits': ccReg('X86ISA::CCREG_CFOF', 61), + 'dfBit': ccReg('X86ISA::CCREG_DF', 62), + 'ecfBit': ccReg('X86ISA::CCREG_ECF', 63), + 'ezfBit': ccReg('X86ISA::CCREG_EZF', 64), # These Pred registers are to be used where reading the portions of # condition code registers is possibly optional, depending on how the @@ -147,65 +149,72 @@ def operands {{ # would be retained, the write predicate checks if any of the bits # are being written. - 'PredccFlagBits': ('CCReg', 'uqw', '(CCREG_ZAPS)', None, - 60, None, None, '''(((ext & (PFBit | AFBit | ZFBit | SFBit - )) != (PFBit | AFBit | ZFBit | SFBit )) && - ((ext & (PFBit | AFBit | ZFBit | SFBit )) != 0))''', - '((ext & (PFBit | AFBit | ZFBit | SFBit )) != 0)'), - 'PredcfofBits': ('CCReg', 'uqw', '(CCREG_CFOF)', None, - 61, None, None, '''(((ext & CFBit) == 0 || - (ext & OFBit) == 0) && ((ext & (CFBit | OFBit)) != 0))''', - '((ext & (CFBit | OFBit)) != 0)'), - 'PreddfBit': ('CCReg', 'uqw', '(CCREG_DF)', None, - 62, None, None, '(false)', '((ext & DFBit) != 0)'), - 'PredecfBit': ('CCReg', 'uqw', '(CCREG_ECF)', None, - 63, None, None, '(false)', '((ext & ECFBit) != 0)'), - 'PredezfBit': ('CCReg', 'uqw', '(CCREG_EZF)', None, - 64, None, None, '(false)', '((ext & EZFBit) != 0)'), + 'PredccFlagBits': ('CCReg', 'uqw', '(X86ISA::CCREG_ZAPS)', None, + 60, None, None, + '''(((ext & (X86ISA::PFBit | X86ISA::AFBit | + X86ISA::ZFBit | X86ISA::SFBit)) != + (X86ISA::PFBit | X86ISA::AFBit | + X86ISA::ZFBit | X86ISA::SFBit)) && + ((ext & (X86ISA::PFBit | X86ISA::AFBit | + X86ISA::ZFBit | X86ISA::SFBit)) != 0))''', + '''((ext & (X86ISA::PFBit | X86ISA::AFBit | + X86ISA::ZFBit | X86ISA::SFBit)) != 0)'''), + 'PredcfofBits': ('CCReg', 'uqw', '(X86ISA::CCREG_CFOF)', None, + 61, None, None, '''(((ext & X86ISA::CFBit) == 0 || + (ext & X86ISA::OFBit) == 0) && + ((ext & (X86ISA::CFBit | X86ISA::OFBit)) != 0))''', + '((ext & (X86ISA::CFBit | X86ISA::OFBit)) != 0)'), + 'PreddfBit': ('CCReg', 'uqw', '(X86ISA::CCREG_DF)', None, + 62, None, None, '(false)', '((ext & X86ISA::DFBit) != 0)'), + 'PredecfBit': ('CCReg', 'uqw', '(X86ISA::CCREG_ECF)', None, + 63, None, None, '(false)', '((ext & X86ISA::ECFBit) != 0)'), + 'PredezfBit': ('CCReg', 'uqw', '(X86ISA::CCREG_EZF)', None, + 64, None, None, '(false)', '((ext & X86ISA::EZFBit) != 0)'), # These register should needs to be more protected so that later # instructions don't map their indexes with an old value. - 'nccFlagBits': controlReg('MISCREG_RFLAGS', 65), + 'nccFlagBits': controlReg('X86ISA::MISCREG_RFLAGS', 65), # Registers related to the state of x87 floating point unit. - 'TOP': controlReg('MISCREG_X87_TOP', 66, ctype='ub'), - 'FSW': controlReg('MISCREG_FSW', 67, ctype='uw'), - 'FTW': controlReg('MISCREG_FTW', 68, ctype='uw'), - 'FCW': controlReg('MISCREG_FCW', 69, ctype='uw'), + 'TOP': controlReg('X86ISA::MISCREG_X87_TOP', 66, ctype='ub'), + 'FSW': controlReg('X86ISA::MISCREG_FSW', 67, ctype='uw'), + 'FTW': controlReg('X86ISA::MISCREG_FTW', 68, ctype='uw'), + 'FCW': controlReg('X86ISA::MISCREG_FCW', 69, ctype='uw'), # The segment base as used by memory instructions. - 'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70), + 'SegBase': controlReg('X86ISA::MISCREG_SEG_EFF_BASE(segment)', + 70), # Operands to get and set registers indexed by the operands of the # original instruction. - 'ControlDest': squashCR0Reg('MISCREG_CR(dest)', 100), - 'ControlSrc1': controlReg('MISCREG_CR(src1)', 101), - 'DebugDest': controlReg('MISCREG_DR(dest)', 102), - 'DebugSrc1': controlReg('MISCREG_DR(src1)', 103), - 'SegBaseDest': squashCSReg('MISCREG_SEG_BASE(dest)', 104), - 'SegBaseSrc1': controlReg('MISCREG_SEG_BASE(src1)', 105), - 'SegLimitDest': squashCSReg('MISCREG_SEG_LIMIT(dest)', 106), - 'SegLimitSrc1': controlReg('MISCREG_SEG_LIMIT(src1)', 107), - 'SegSelDest': controlReg('MISCREG_SEG_SEL(dest)', 108), - 'SegSelSrc1': controlReg('MISCREG_SEG_SEL(src1)', 109), - 'SegAttrDest': squashCSReg('MISCREG_SEG_ATTR(dest)', 110), - 'SegAttrSrc1': controlReg('MISCREG_SEG_ATTR(src1)', 111), + 'ControlDest': squashCR0Reg('X86ISA::MISCREG_CR(dest)', 100), + 'ControlSrc1': controlReg('X86ISA::MISCREG_CR(src1)', 101), + 'DebugDest': controlReg('X86ISA::MISCREG_DR(dest)', 102), + 'DebugSrc1': controlReg('X86ISA::MISCREG_DR(src1)', 103), + 'SegBaseDest': squashCSReg('X86ISA::MISCREG_SEG_BASE(dest)', 104), + 'SegBaseSrc1': controlReg('X86ISA::MISCREG_SEG_BASE(src1)', 105), + 'SegLimitDest': squashCSReg('X86ISA::MISCREG_SEG_LIMIT(dest)', 106), + 'SegLimitSrc1': controlReg('X86ISA::MISCREG_SEG_LIMIT(src1)', 107), + 'SegSelDest': controlReg('X86ISA::MISCREG_SEG_SEL(dest)', 108), + 'SegSelSrc1': controlReg('X86ISA::MISCREG_SEG_SEL(src1)', 109), + 'SegAttrDest': squashCSReg('X86ISA::MISCREG_SEG_ATTR(dest)', 110), + 'SegAttrSrc1': controlReg('X86ISA::MISCREG_SEG_ATTR(src1)', 111), # Operands to access specific control registers directly. - 'EferOp': squashCReg('MISCREG_EFER', 200), - 'CR4Op': controlReg('MISCREG_CR4', 201), - 'DR7Op': controlReg('MISCREG_DR7', 202), - 'LDTRBase': controlReg('MISCREG_TSL_BASE', 203), - 'LDTRLimit': controlReg('MISCREG_TSL_LIMIT', 204), - 'LDTRSel': controlReg('MISCREG_TSL', 205), - 'GDTRBase': controlReg('MISCREG_TSG_BASE', 206), - 'GDTRLimit': controlReg('MISCREG_TSG_LIMIT', 207), - 'CSBase': squashCReg('MISCREG_CS_EFF_BASE', 208), - 'CSAttr': squashCReg('MISCREG_CS_ATTR', 209), + 'EferOp': squashCReg('X86ISA::MISCREG_EFER', 200), + 'CR4Op': controlReg('X86ISA::MISCREG_CR4', 201), + 'DR7Op': controlReg('X86ISA::MISCREG_DR7', 202), + 'LDTRBase': controlReg('X86ISA::MISCREG_TSL_BASE', 203), + 'LDTRLimit': controlReg('X86ISA::MISCREG_TSL_LIMIT', 204), + 'LDTRSel': controlReg('X86ISA::MISCREG_TSL', 205), + 'GDTRBase': controlReg('X86ISA::MISCREG_TSG_BASE', 206), + 'GDTRLimit': controlReg('X86ISA::MISCREG_TSG_LIMIT', 207), + 'CSBase': squashCReg('X86ISA::MISCREG_CS_EFF_BASE', 208), + 'CSAttr': squashCReg('X86ISA::MISCREG_CS_ATTR', 209), 'MiscRegDest': controlReg('dest', 210), 'MiscRegSrc1': controlReg('src1', 211), - 'TscOp': controlReg('MISCREG_TSC', 212), - 'M5Reg': squashCReg('MISCREG_M5_REG', 213), + 'TscOp': controlReg('X86ISA::MISCREG_TSC', 212), + 'M5Reg': squashCReg('X86ISA::MISCREG_M5_REG', 213), 'Mem': ('Mem', 'uqw', None, \ (None, 'IsLoad', 'IsStore'), 300) }};