diff --git a/src/arch/x86/insts/microop_args.hh b/src/arch/x86/insts/microop_args.hh new file mode 100644 index 0000000000..27af296be8 --- /dev/null +++ b/src/arch/x86/insts/microop_args.hh @@ -0,0 +1,203 @@ +/* + * Copyright 2021 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_X86_INSTS_MICROOP_ARGS_HH__ +#define __ARCH_X86_INSTS_MICROOP_ARGS_HH__ + +#include +#include +#include + +#include "arch/x86/insts/static_inst.hh" +#include "arch/x86/regs/int.hh" +#include "arch/x86/types.hh" +#include "base/cprintf.hh" +#include "cpu/reg_class.hh" + +namespace X86ISA +{ + +struct DestOp +{ + using ArgType = InstRegIndex; + const RegIndex dest; + const size_t size; + RegIndex index() const { return dest; } + + DestOp(RegIndex _dest, size_t _size) : dest(_dest), size(_size) {} +}; + +struct Src1Op +{ + using ArgType = InstRegIndex; + const RegIndex src1; + const size_t size; + RegIndex index() const { return src1; } + + Src1Op(RegIndex _src1, size_t _size) : src1(_src1), size(_size) {} +}; + +struct Src2Op +{ + using ArgType = InstRegIndex; + const RegIndex src2; + const size_t size; + RegIndex index() const { return src2; } + + Src2Op(RegIndex _src2, size_t _size) : src2(_src2), size(_size) {} +}; + +template +struct FoldedOp : public Base +{ + template + FoldedOp(InstType *inst, typename Base::ArgType idx) : + Base(INTREG_FOLDED(idx.index(), inst->foldOBit), inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(IntRegClass, this->index()), + this->size); + } +}; + +template +struct CrOp : public Base +{ + template + CrOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {} + + void + print(std::ostream &os) const + { + ccprintf(os, "cr%d", this->index()); + } +}; + +template +struct DbgOp : public Base +{ + template + DbgOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {} + + void + print(std::ostream &os) const + { + ccprintf(os, "dr%d", this->index()); + } + +}; + +template +struct SegOp : public Base +{ + template + SegOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {} + + void + print(std::ostream &os) const + { + X86StaticInst::printSegment(os, this->index()); + } +}; + +template +struct MiscOp : public Base +{ + template + MiscOp(InstType *inst, typename Base::ArgType idx) : + Base(idx.index(), inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(MiscRegClass, this->index()), + this->size); + } +}; + +using FoldedDestOp = FoldedOp; +using DbgDestOp = DbgOp; +using CrDestOp = CrOp; +using SegDestOp = SegOp; +using MiscDestOp = MiscOp; + +using FoldedSrc1Op = FoldedOp; +using DbgSrc1Op = DbgOp; +using CrSrc1Op = CrOp; +using SegSrc1Op = SegOp; +using MiscSrc1Op = MiscOp; + +using FoldedSrc2Op = FoldedOp; + +struct Imm8Op +{ + using ArgType = uint8_t; + + uint8_t imm8; + + template + Imm8Op(InstType *inst, ArgType _imm8) : imm8(_imm8) {} + + void + print(std::ostream &os) const + { + ccprintf(os, "%#x", imm8); + } +}; + +template +class InstOperands : public Base, public Operands... +{ + protected: + template + InstOperands(ExtMachInst mach_inst, const char *mnem, + const char *inst_mnem, uint64_t set_flags, OpClass op_class, + typename Operands::ArgType... args, CTorArgs... ctor_args) : + Base(mach_inst, mnem, inst_mnem, set_flags, op_class, ctor_args...), + Operands(this, args)... + {} + + std::string + generateDisassembly(Addr pc, + const Loader::SymbolTable *symtab) const override + { + std::stringstream response; + Base::printMnemonic(response, this->instMnem, this->mnemonic); + int count = 0; + M5_FOR_EACH_IN_PACK(ccprintf(response, count++ ? ", " : ""), + Operands::print(response)); + return response.str(); + } +}; + +} + +#endif //__ARCH_X86_INSTS_MICROOP_ARGS_HH__ diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index 37e9d6f7b3..70676df5a4 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -39,150 +39,19 @@ #define __ARCH_X86_INSTS_MICROREGOP_HH__ #include "arch/x86/insts/microop.hh" +#include "arch/x86/insts/microop_args.hh" namespace X86ISA { -struct DestOp -{ - using ArgType = InstRegIndex; - const RegIndex dest; - const size_t size; - RegIndex index() const { return dest; } - - DestOp(RegIndex _dest, size_t _size) : dest(_dest), size(_size) {} -}; - -struct Src1Op -{ - using ArgType = InstRegIndex; - const RegIndex src1; - const size_t size; - RegIndex index() const { return src1; } - - Src1Op(RegIndex _src1, size_t _size) : src1(_src1), size(_size) {} -}; - -struct Src2Op -{ - using ArgType = InstRegIndex; - const RegIndex src2; - const size_t size; - RegIndex index() const { return src2; } - - Src2Op(RegIndex _src2, size_t _size) : src2(_src2), size(_size) {} -}; - -template -struct FoldedOp : public Base -{ - template - FoldedOp(InstType *inst, typename Base::ArgType idx) : - Base(INTREG_FOLDED(idx.index(), inst->foldOBit), inst->dataSize) - {} - - void - print(std::ostream &os) const - { - X86StaticInst::printReg(os, RegId(IntRegClass, this->index()), - this->size); - } -}; - -template -struct CrOp : public Base -{ - template - CrOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {} - - void - print(std::ostream &os) const - { - ccprintf(os, "cr%d", this->index()); - } -}; - -template -struct DbgOp : public Base -{ - template - DbgOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {} - - void - print(std::ostream &os) const - { - ccprintf(os, "dr%d", this->index()); - } - -}; - -template -struct SegOp : public Base -{ - template - SegOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {} - - void - print(std::ostream &os) const - { - X86StaticInst::printSegment(os, this->index()); - } -}; - -template -struct MiscOp : public Base -{ - template - MiscOp(InstType *inst, typename Base::ArgType idx) : - Base(idx.index(), inst->dataSize) - {} - - void - print(std::ostream &os) const - { - X86StaticInst::printReg(os, RegId(MiscRegClass, this->index()), - this->size); - } -}; - -using RegOpDest = FoldedOp; -using RegOpDbgDest = DbgOp; -using RegOpCrDest = CrOp; -using RegOpSegDest = SegOp; -using RegOpMiscDest = MiscOp; - -using RegOpSrc1 = FoldedOp; -using RegOpDbgSrc1 = DbgOp; -using RegOpCrSrc1 = CrOp; -using RegOpSegSrc1 = SegOp; -using RegOpMiscSrc1 = MiscOp; - -using RegOpSrc2 = FoldedOp; - -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 uint16_t ext; 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) : + uint64_t set_flags, OpClass op_class, uint8_t data_size, + uint16_t _ext) : 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) @@ -199,28 +68,7 @@ class RegOpBase : public X86MicroopBase }; template -class RegOpT : public RegOpBase, public Operands... -{ - protected: - 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)... - {} - - 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(); - } -}; +using RegOpT = InstOperands; } diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 38a4be301b..7e024dd63f 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -79,7 +79,7 @@ def template MicroRegOpDeclare {{ 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...) + %(op_class)s, args..., data_size, _ext) { %(set_reg_idx_arr)s; %(constructor)s; @@ -102,7 +102,7 @@ def template MicroRegOpBranchDeclare {{ 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...) + %(op_class)s, args..., data_size, _ext) { %(set_reg_idx_arr)s; %(constructor)s; @@ -213,20 +213,20 @@ let {{ 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' + dest_op = 'X86ISA::FoldedDestOp' + dbg_dest_op = 'X86ISA::DbgDestOp' + cr_dest_op = 'X86ISA::CrDestOp' + seg_dest_op = 'X86ISA::SegDestOp' + misc_dest_op = 'X86ISA::MiscDestOp' - src1_op = 'X86ISA::RegOpSrc1' - dbg_src1_op = 'X86ISA::RegOpDbgSrc1' - cr_src1_op = 'X86ISA::RegOpCrSrc1' - seg_src1_op = 'X86ISA::RegOpSegSrc1' - misc_src1_op = 'X86ISA::RegOpMiscSrc1' + src1_op = 'X86ISA::FoldedSrc1Op' + dbg_src1_op = 'X86ISA::DbgSrc1Op' + cr_src1_op = 'X86ISA::CrSrc1Op' + seg_src1_op = 'X86ISA::SegSrc1Op' + misc_src1_op = 'X86ISA::MiscSrc1Op' - src2_op = 'X86ISA::RegOpSrc2' - imm_op = 'X86ISA::RegOpImm8' + src2_op = 'X86ISA::FoldedSrc2Op' + imm_op = 'X86ISA::Imm8Op' class RegOpMeta(type): def buildCppClasses(self, name, Name, suffix, code, big_code, \ @@ -1489,7 +1489,7 @@ let {{ super(SegOp, self).__init__(dest, src1, flags=flags, dataSize=dataSize) - class WrSegOp(CondRegOp): + class WrSegOp(SegOp): abstract = True operands = (seg_dest_op, src1_op) @@ -1513,7 +1513,7 @@ let {{ SegAttrDest = psrc1; ''' - class RdSegOp(CondRegOp): + class RdSegOp(SegOp): abstract = True operands = (dest_op, seg_src1_op)