From 6142401b554ca7aef8748099587f20af44e5698a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 4 Mar 2021 02:34:52 -0800 Subject: [PATCH] arch-x86: Use the new op bases for memory microops. Change-Id: I73538b547093e6f872e085686ea164ef89527321 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42346 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- src/arch/x86/SConscript | 1 - src/arch/x86/insts/microldstop.cc | 78 ----- src/arch/x86/insts/microldstop.hh | 144 ++++----- src/arch/x86/insts/microop_args.hh | 104 ++++++- .../cache_and_memory_management.py | 12 +- src/arch/x86/isa/microops/ldstop.isa | 276 +++++++++--------- src/arch/x86/isa/operands.isa | 10 +- 7 files changed, 327 insertions(+), 298 deletions(-) delete mode 100644 src/arch/x86/insts/microldstop.cc diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 9b16fad957..b0f908bfb1 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -51,7 +51,6 @@ Source('faults.cc') Source('fs_workload.cc') Source('insts/badmicroop.cc') Source('insts/microfpop.cc') -Source('insts/microldstop.cc') Source('insts/micromediaop.cc') Source('insts/microop.cc') Source('insts/microregop.cc') diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc deleted file mode 100644 index 1debacc0ee..0000000000 --- a/src/arch/x86/insts/microldstop.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2007 The Hewlett-Packard Development Company - * Copyright (c) 2015 Advanced Micro Devices, Inc. - * All rights reserved. - * - * The license below extends only to copyright in the software and shall - * not be construed as granting a license to any other intellectual - * property including but not limited to intellectual property relating - * to a hardware implementation of the functionality of the software - * licensed hereunder. You may use the software subject to the license - * terms below provided that you ensure that this notice is replicated - * unmodified and in its entirety in all distributions of the software, - * modified or unmodified, in source code or in binary form. - * - * 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. - */ - -#include "arch/x86/insts/microldstop.hh" - -#include - -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 -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(); -} - -} diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index 26110959c7..1272cb00b5 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -40,6 +40,7 @@ #define __ARCH_X86_INSTS_MICROLDSTOP_HH__ #include "arch/x86/insts/microop.hh" +#include "arch/x86/insts/microop_args.hh" #include "arch/x86/ldstflags.hh" #include "mem/packet.hh" #include "mem/request.hh" @@ -54,65 +55,80 @@ namespace X86ISA 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()) - { - assert(_segment.index() < NUM_SEGMENTREGS); - foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; - foldABit = (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; - } + MemOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, OpClass op_class, + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags) : + X86MicroopBase(mach_inst, mnem, inst_mnem, set_flags, op_class), + memFlags(mem_flags), + dataSize(data_size), addressSize(address_size), + foldOBit((dataSize == 1 && !mach_inst.rex.present) ? 1 << 6 : 0), + foldABit((addressSize == 1 && !mach_inst.rex.present) ? 1 << 6 : 0) + {} + + public: + const uint8_t dataSize; + const uint8_t addressSize; + const RegIndex foldOBit, foldABit; }; /** - * Base class for load and store ops using one register + * Base class for load ops using one integer register. */ -class LdStOp : public MemOp +class LdStOp : public InstOperands { protected: - const RegIndex data; - - //Constructor - LdStOp(ExtMachInst _machInst, - const char * mnem, const char * _instMnem, - uint64_t setFlags, + LdStOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, InstRegIndex _data, 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()) - { - } + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags, OpClass op_class) : + InstOperands( + mach_inst, mnem, inst_mnem, set_flags, op_class, + _data, { _scale, _index, _base, _disp, _segment }, + data_size, address_size, mem_flags | _segment.index()) + {} +}; - std::string generateDisassembly( - Addr pc, const Loader::SymbolTable *symtab) const override; +/** + * Base class for load ops using one FP register. + */ +class LdStFpOp : public InstOperands +{ + protected: + LdStFpOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, InstRegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags, OpClass op_class) : + InstOperands( + mach_inst, mnem, inst_mnem, set_flags, op_class, + _data, { _scale, _index, _base, _disp, _segment }, + data_size, address_size, mem_flags | _segment.index()) + {} +}; + +/** + * Base class for the tia microop which has no destination register. + */ +class MemNoDataOp : public InstOperands +{ + protected: + MemNoDataOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, uint8_t _scale, InstRegIndex _index, + InstRegIndex _base, uint64_t _disp, InstRegIndex _segment, + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags, OpClass op_class) : + InstOperands( + mach_inst, mnem, inst_mnem, set_flags, op_class, + { _scale, _index, _base, _disp, _segment }, + data_size, address_size, mem_flags | _segment.index()) + {} }; /** @@ -120,33 +136,21 @@ class LdStOp : public MemOp * call them split ops for this reason. These are mainly used to * implement cmpxchg8b and cmpxchg16b. */ -class LdStSplitOp : public MemOp +class LdStSplitOp : + public InstOperands { protected: - const RegIndex dataLow; - const RegIndex dataHi; - - //Constructor - LdStSplitOp(ExtMachInst _machInst, - const char * mnem, const char * _instMnem, - uint64_t setFlags, + LdStSplitOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem, + uint64_t set_flags, InstRegIndex data_low, InstRegIndex data_hi, 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; + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags, OpClass op_class) : + InstOperands( + mach_inst, mnem, inst_mnem, set_flags, op_class, + data_low, data_hi, { _scale, _index, _base, _disp, _segment }, + data_size, address_size, mem_flags | _segment.index()) + {} }; } diff --git a/src/arch/x86/insts/microop_args.hh b/src/arch/x86/insts/microop_args.hh index 27af296be8..2956d88071 100644 --- a/src/arch/x86/insts/microop_args.hh +++ b/src/arch/x86/insts/microop_args.hh @@ -46,7 +46,7 @@ struct DestOp using ArgType = InstRegIndex; const RegIndex dest; const size_t size; - RegIndex index() const { return dest; } + RegIndex opIndex() const { return dest; } DestOp(RegIndex _dest, size_t _size) : dest(_dest), size(_size) {} }; @@ -56,7 +56,7 @@ struct Src1Op using ArgType = InstRegIndex; const RegIndex src1; const size_t size; - RegIndex index() const { return src1; } + RegIndex opIndex() const { return src1; } Src1Op(RegIndex _src1, size_t _size) : src1(_src1), size(_size) {} }; @@ -66,11 +66,42 @@ struct Src2Op using ArgType = InstRegIndex; const RegIndex src2; const size_t size; - RegIndex index() const { return src2; } + RegIndex opIndex() const { return src2; } Src2Op(RegIndex _src2, size_t _size) : src2(_src2), size(_size) {} }; +struct DataOp +{ + using ArgType = InstRegIndex; + const RegIndex data; + const size_t size; + RegIndex opIndex() const { return data; } + + DataOp(RegIndex _data, size_t _size) : data(_data), size(_size) {} +}; + +struct DataHiOp +{ + using ArgType = InstRegIndex; + const RegIndex dataHi; + const size_t size; + RegIndex opIndex() const { return dataHi; } + + DataHiOp(RegIndex data_hi, size_t _size) : dataHi(data_hi), size(_size) {} +}; + +struct DataLowOp +{ + using ArgType = InstRegIndex; + const RegIndex dataLow; + const size_t size; + RegIndex opIndex() const { return dataLow; } + + DataLowOp(RegIndex data_low, size_t _size) : dataLow(data_low), size(_size) + {} +}; + template struct FoldedOp : public Base { @@ -82,7 +113,7 @@ struct FoldedOp : public Base void print(std::ostream &os) const { - X86StaticInst::printReg(os, RegId(IntRegClass, this->index()), + X86StaticInst::printReg(os, RegId(IntRegClass, this->opIndex()), this->size); } }; @@ -96,7 +127,7 @@ struct CrOp : public Base void print(std::ostream &os) const { - ccprintf(os, "cr%d", this->index()); + ccprintf(os, "cr%d", this->opIndex()); } }; @@ -109,7 +140,7 @@ struct DbgOp : public Base void print(std::ostream &os) const { - ccprintf(os, "dr%d", this->index()); + ccprintf(os, "dr%d", this->opIndex()); } }; @@ -123,7 +154,7 @@ struct SegOp : public Base void print(std::ostream &os) const { - X86StaticInst::printSegment(os, this->index()); + X86StaticInst::printSegment(os, this->opIndex()); } }; @@ -138,7 +169,23 @@ struct MiscOp : public Base void print(std::ostream &os) const { - X86StaticInst::printReg(os, RegId(MiscRegClass, this->index()), + X86StaticInst::printReg(os, RegId(MiscRegClass, this->opIndex()), + this->size); + } +}; + +template +struct FloatOp : public Base +{ + template + FloatOp(InstType *inst, typename Base::ArgType idx) : + Base(idx.index(), inst->dataSize) + {} + + void + print(std::ostream &os) const + { + X86StaticInst::printReg(os, RegId(FloatRegClass, this->opIndex()), this->size); } }; @@ -157,6 +204,11 @@ using MiscSrc1Op = MiscOp; using FoldedSrc2Op = FoldedOp; +using FoldedDataOp = FoldedOp; +using FloatDataOp = FloatOp; +using FoldedDataHiOp = FoldedOp; +using FoldedDataLowOp = FoldedOp; + struct Imm8Op { using ArgType = uint8_t; @@ -173,6 +225,42 @@ struct Imm8Op } }; +struct AddrOp +{ + struct ArgType + { + uint8_t scale; + InstRegIndex index; + InstRegIndex base; + uint64_t disp; + InstRegIndex segment; + }; + + const uint8_t scale; + const RegIndex index; + const RegIndex base; + const uint64_t disp; + const uint8_t segment; + const size_t size; + + template + AddrOp(InstType *inst, const ArgType &args) : scale(args.scale), + index(INTREG_FOLDED(args.index.index(), inst->foldABit)), + base(INTREG_FOLDED(args.base.index(), inst->foldABit)), + disp(args.disp), segment(args.segment.index()), + size(inst->addressSize) + { + assert(segment < NUM_SEGMENTREGS); + } + + void + print(std::ostream &os) const + { + X86StaticInst::printMem( + os, segment, scale, index, base, disp, size, false); + } +}; + template class InstOperands : public Base, public Operands... { diff --git a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py index d10398c6ee..4dd4943edb 100644 --- a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py +++ b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py @@ -58,37 +58,37 @@ def macroop PREFETCH_T0_P def macroop CLFLUSH_M { - clflushopt t0, seg, sib, disp, dataSize=1 + clflushopt seg, sib, disp, dataSize=1 mfence }; def macroop CLFLUSH_P { rdip t7 - clflushopt t0, seg, riprel, disp, dataSize=1 + clflushopt seg, riprel, disp, dataSize=1 mfence }; def macroop CLFLUSHOPT_M { - clflushopt t0, seg, sib, disp, dataSize=1 + clflushopt seg, sib, disp, dataSize=1 }; def macroop CLFLUSHOPT_P { rdip t7 - clflushopt t0, seg, riprel, disp, dataSize=1 + clflushopt seg, riprel, disp, dataSize=1 }; def macroop CLWB_M { - clwb t1, seg, sib, disp, dataSize=1 + clwb seg, sib, disp, dataSize=1 }; def macroop CLWB_P { rdip t7 - clwb t1, seg, riprel, disp, dataSize=1 + clwb seg, riprel, disp, dataSize=1 }; ''' diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 79aadfa887..c70b8c71b2 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -58,8 +58,7 @@ def template MicroLeaExecute {{ DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); %(code)s; - if(fault == NoFault) - { + if (fault == NoFault) { %(op_wb)s; } @@ -74,13 +73,16 @@ def template MicroLeaDeclare {{ %(reg_idx_arr_decl)s; public: - %(class_name)s(ExtMachInst _machInst, - 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); + template + %(class_name)s(ExtMachInst mach_inst, const char *inst_mnem, + uint64_t set_flags, uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags, Args ...args) : + %(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags, + args..., data_size, address_size, mem_flags, %(op_class)s) + { + %(set_reg_idx_arr)s; + %(constructor)s; + } Fault execute(ExecContext *, Trace::InstRecord *) const override; }; @@ -89,8 +91,9 @@ def template MicroLeaDeclare {{ // Load templates def template MicroLoadExecute {{ - Fault %(class_name)s::execute(ExecContext *xc, - Trace::InstRecord *traceData) const + Fault + %(class_name)s::execute(ExecContext *xc, + Trace::InstRecord *traceData) const { Fault fault = NoFault; Addr EA; @@ -108,8 +111,7 @@ def template MicroLoadExecute {{ // For prefetches, ignore any faults/exceptions. return NoFault; } - if(fault == NoFault) - { + if (fault == NoFault) { %(op_wb)s; } @@ -118,8 +120,9 @@ def template MicroLoadExecute {{ }}; def template MicroLoadInitiateAcc {{ - Fault %(class_name)s::initiateAcc(ExecContext * xc, - Trace::InstRecord * traceData) const + Fault + %(class_name)s::initiateAcc(ExecContext *xc, + Trace::InstRecord *traceData) const { Fault fault = NoFault; Addr EA; @@ -129,16 +132,16 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = initiateMemRead(xc, traceData, EA, - %(memDataSize)s, memFlags); + fault = initiateMemRead(xc, traceData, EA, %(memDataSize)s, memFlags); return fault; } }}; def template MicroLoadCompleteAcc {{ - Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc, - Trace::InstRecord * traceData) const + Fault + %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, + Trace::InstRecord *traceData) const { Fault fault = NoFault; @@ -149,8 +152,7 @@ def template MicroLoadCompleteAcc {{ %(code)s; - if(fault == NoFault) - { + if (fault == NoFault) { %(op_wb)s; } @@ -161,7 +163,8 @@ def template MicroLoadCompleteAcc {{ // Store templates def template MicroStoreExecute {{ - Fault %(class_name)s::execute(ExecContext * xc, + Fault + %(class_name)s::execute(ExecContext *xc, Trace::InstRecord *traceData) const { Fault fault = NoFault; @@ -176,7 +179,7 @@ def template MicroStoreExecute {{ if (fault == NoFault) { fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA, - memFlags, NULL); + memFlags, NULL); if (fault == NoFault) { %(op_wb)s; } @@ -187,8 +190,9 @@ def template MicroStoreExecute {{ }}; def template MicroStoreInitiateAcc {{ - Fault %(class_name)s::initiateAcc(ExecContext * xc, - Trace::InstRecord * traceData) const + Fault + %(class_name)s::initiateAcc(ExecContext *xc, + Trace::InstRecord *traceData) const { Fault fault = NoFault; @@ -202,15 +206,16 @@ def template MicroStoreInitiateAcc {{ if (fault == NoFault) { fault = writeMemTiming(xc, traceData, Mem, dataSize, EA, - memFlags, NULL); + memFlags, NULL); } return fault; } }}; def template MicroStoreCompleteAcc {{ - Fault %(class_name)s::completeAcc(PacketPtr pkt, - ExecContext * xc, Trace::InstRecord * traceData) const + Fault + %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, + Trace::InstRecord *traceData) const { %(op_decl)s; %(op_rd)s; @@ -227,13 +232,17 @@ def template MicroLdStOpDeclare {{ %(reg_idx_arr_decl)s; public: - %(class_name)s(ExtMachInst _machInst, - 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); + template + %(class_name)s(ExtMachInst mach_inst, const char *inst_mnem, + uint64_t set_flags, uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags, Args ...args) : + %(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags, + args..., data_size, address_size, mem_flags, %(op_class)s) + { + %(set_reg_idx_arr)s; + %(constructor)s; + } + Fault execute(ExecContext *, Trace::InstRecord *) const override; Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; @@ -251,13 +260,13 @@ def template MicroLdStSplitOpDeclare {{ %(reg_idx_arr_decl)s; public: - %(class_name)s(ExtMachInst _machInst, - const char * instMnem, uint64_t setFlags, + %(class_name)s(ExtMachInst mach_inst, const char *inst_mnem, + uint64_t set_flags, + InstRegIndex data_low, InstRegIndex data_hi, 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); + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags); Fault execute(ExecContext *, Trace::InstRecord *) const override; Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; @@ -266,36 +275,17 @@ def template MicroLdStSplitOpDeclare {{ }; }}; -def template MicroLdStOpConstructor {{ - %(class_name)s::%(class_name)s( - ExtMachInst machInst, 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) : - %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, - _scale, _index, _base, - _disp, _segment, _data, - _dataSize, _addressSize, _memFlags, %(op_class)s) - { - %(set_reg_idx_arr)s; - %(constructor)s; - } -}}; - def template MicroLdStSplitOpConstructor {{ - %(class_name)s::%(class_name)s( - ExtMachInst machInst, const char * instMnem, uint64_t setFlags, + %(class_name)s::%(class_name)s(ExtMachInst mach_inst, + const char *inst_mnem, uint64_t set_flags, + InstRegIndex data_low, InstRegIndex data_hi, 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) : - %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, - _scale, _index, _base, - _disp, _segment, _dataLow, _dataHi, - _dataSize, _addressSize, _memFlags, %(op_class)s) + uint8_t data_size, uint8_t address_size, + Request::FlagsType mem_flags) : + %(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags, + data_low, data_hi, _scale, _index, _base, _disp, _segment, + data_size, address_size, mem_flags, %(op_class)s) { %(set_reg_idx_arr)s; %(constructor)s; @@ -332,9 +322,9 @@ let {{ def getAllocator(self, microFlags): allocator = '''new %(class_name)s(machInst, macrocodeBlock, - %(flags)s, %(scale)s, %(index)s, %(base)s, - %(disp)s, %(segment)s, %(data)s, - %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { + %(flags)s, %(dataSize)s, %(addressSize)s, %(memFlags)s, + %(data)s, %(scale)s, %(index)s, %(base)s, + %(disp)s, %(segment)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags) + self.instFlags, "scale" : self.scale, "index" : self.index, @@ -376,13 +366,13 @@ let {{ allocString = ''' (%(dataSize)s >= 4) ? (StaticInstPtr)(new %(class_name)sBig(machInst, - macrocodeBlock, %(flags)s, %(scale)s, %(index)s, - %(base)s, %(disp)s, %(segment)s, %(data)s, - %(dataSize)s, %(addressSize)s, %(memFlags)s)) : + macrocodeBlock, %(flags)s, %(dataSize)s, + %(addressSize)s, %(memFlags)s, %(data)s, %(scale)s, + %(index)s, %(base)s, %(disp)s, %(segment)s)) : (StaticInstPtr)(new %(class_name)s(machInst, - macrocodeBlock, %(flags)s, %(scale)s, %(index)s, - %(base)s, %(disp)s, %(segment)s, %(data)s, - %(dataSize)s, %(addressSize)s, %(memFlags)s)) + macrocodeBlock, %(flags)s, %(dataSize)s, + %(addressSize)s, %(memFlags)s, %(data)s, %(scale)s, + %(index)s, %(base)s, %(disp)s, %(segment)s)) ''' allocator = allocString % { "class_name" : self.className, @@ -406,9 +396,8 @@ let {{ def getAllocator(self, microFlags): allocString = '''(StaticInstPtr)(new %(class_name)s(machInst, - macrocodeBlock, %(flags)s, %(scale)s, %(index)s, - %(base)s, %(disp)s, %(segment)s, - %(dataLow)s, %(dataHi)s, + macrocodeBlock, %(flags)s, %(dataLow)s, %(dataHi)s, + %(scale)s, %(index)s, %(base)s, %(disp)s, %(segment)s, %(dataSize)s, %(addressSize)s, %(memFlags)s)) ''' allocator = allocString % { @@ -423,6 +412,34 @@ let {{ "memFlags" : self.memFlags} return allocator + class MemNoDataOp(X86Microop): + def __init__(self, segment, addr, disp=0, + dataSize="env.dataSize", addressSize="env.addressSize", + baseFlags="0"): + [self.scale, self.index, self.base] = addr + self.disp = disp + self.segment = segment + self.dataSize = dataSize + self.addressSize = addressSize + self.instFlags = "" + self.memFlags = baseFlags + "| " \ + "(machInst.legacy.addr ? (AddrSizeFlagBit << FlagShift) : 0)" + + def getAllocator(self, microFlags): + allocator = '''new %(class_name)s(machInst, macrocodeBlock, + %(flags)s, %(dataSize)s, %(addressSize)s, %(memFlags)s, + %(scale)s, %(index)s, %(base)s, %(disp)s, + %(segment)s)''' % { + "class_name" : self.className, + "flags" : self.microFlagsText(microFlags) + self.instFlags, + "scale" : self.scale, "index" : self.index, + "base" : self.base, + "disp" : self.disp, + "segment" : self.segment, + "dataSize" : self.dataSize, "addressSize" : self.addressSize, + "memFlags" : self.memFlags} + return allocator + }}; let {{ @@ -440,7 +457,7 @@ let {{ def defineMicroLoadOp(mnemonic, code, bigCode='', mem_flags="0", big=True, nonSpec=False, - implicitStack=False): + implicitStack=False, is_float=False): global header_output global decoder_output global exec_output @@ -448,19 +465,23 @@ let {{ Name = mnemonic name = mnemonic.lower() + if is_float: + base = 'X86ISA::LdStFpOp' + else: + base = 'X86ISA::LdStOp' + # Build up the all register version of this micro op - iops = [InstObjParams(name, Name, 'X86ISA::LdStOp', + iops = [InstObjParams(name, Name, base, { "code": code, "ea_code": calculateEA, "memDataSize": "dataSize" })] if big: - iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp', + iops += [InstObjParams(name, Name + "Big", base, { "code": bigCode, "ea_code": calculateEA, "memDataSize": "dataSize" })] for iop in iops: header_output += MicroLdStOpDeclare.subst(iop) - decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLoadExecute.subst(iop) exec_output += MicroLoadInitiateAcc.subst(iop) exec_output += MicroLoadCompleteAcc.subst(iop) @@ -503,7 +524,8 @@ let {{ '(StoreCheck << FlagShift) | Request::LOCKED_RMW', nonSpec=True) - defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False) + defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big=False, + is_float=True) defineMicroLoadOp('Ldfp87', code=''' switch (dataSize) @@ -517,7 +539,7 @@ let {{ default: panic("Unhandled data size in LdFp87.\\n"); } - ''', big = False) + ''', big=False, is_float=True) # Load integer from memory into x87 top-of-stack register. # Used to implement fild instruction. @@ -536,7 +558,7 @@ let {{ default: panic("Unhandled data size in LdIFp87.\\n"); } - ''', big = False) + ''', big=False, is_float=True) def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0", nonSpec=False): global header_output @@ -584,7 +606,7 @@ let {{ nonSpec=True) def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0", - implicitStack=False): + implicitStack=False, is_float=False, has_data=True): global header_output global decoder_output global exec_output @@ -592,14 +614,20 @@ let {{ Name = mnemonic name = mnemonic.lower() + if not has_data: + base = 'X86ISA::MemNoDataOp' + elif is_float: + base = 'X86ISA::LdStFpOp' + else: + base = 'X86ISA::LdStOp' + # Build up the all register version of this micro op - iop = InstObjParams(name, Name, 'X86ISA::LdStOp', + iop = InstObjParams(name, Name, base, { "code": code, "complete_code": completeCode, "ea_code": calculateEA, "memDataSize": "dataSize" }) header_output += MicroLdStOpDeclare.subst(iop) - decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroStoreExecute.subst(iop) exec_output += MicroStoreInitiateAcc.subst(iop) exec_output += MicroStoreCompleteAcc.subst(iop) @@ -612,17 +640,25 @@ let {{ else: addressSize = "env.addressSize" - class StoreOp(LdStOp): - def __init__(self, data, segment, addr, disp = 0, - dataSize="env.dataSize", - addressSize=addressSize, - atCPL0=False, nonSpec=False, implicitStack=implicitStack, - uncacheable=False): - super(StoreOp, self).__init__(data, segment, addr, disp, - dataSize, addressSize, mem_flags, atCPL0, False, - nonSpec, implicitStack, uncacheable) - self.className = Name - self.mnemonic = name + if has_data: + class StoreOp(LdStOp): + def __init__(self, data, segment, addr, disp=0, + dataSize="env.dataSize", addressSize=addressSize, + atCPL0=False, nonSpec=False, + implicitStack=implicitStack, uncacheable=False): + super(StoreOp, self).__init__(data, segment, addr, disp, + dataSize, addressSize, mem_flags, atCPL0, False, + nonSpec, implicitStack, uncacheable) + self.className = Name + self.mnemonic = name + else: + class StoreOp(MemNoDataOp): + def __init__(self, segment, addr, disp=0, + dataSize="env.dataSize", addressSize=addressSize): + super(StoreOp, self).__init__(segment, addr, disp, + dataSize, addressSize, mem_flags) + self.className = Name + self.mnemonic = name microopClasses[name] = StoreOp @@ -632,7 +668,7 @@ let {{ defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', mem_flags="Request::LOCKED_RMW") - defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;') + defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;', is_float=True) defineMicroStoreOp('Stfp87', code=''' switch (dataSize) @@ -647,13 +683,14 @@ let {{ default: panic("Unhandled data size in StFp87.\\n"); } - ''') + ''', is_float=True) - defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") + defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS", + has_data=False) defineMicroStoreOp('Clflushopt', 'Mem = 0;', mem_flags="Request::CLEAN | Request::INVALIDATE" + - " | Request::DST_POC") - defineMicroStoreOp('Clwb', 'Mem = 0;', + " | Request::DST_POC", has_data=False) + defineMicroStoreOp('Clwb', 'Mem = 0;', has_data=False, mem_flags="Request::CLEAN | Request::DST_POC") def defineMicroStoreSplitOp(mnemonic, code, @@ -706,7 +743,6 @@ let {{ "ea_code": "EA = " + segmentEAExpr, "memDataSize": "dataSize" }) header_output += MicroLeaDeclare.subst(iop) - decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) class LeaOp(LdStOp): @@ -721,35 +757,15 @@ let {{ microopClasses["lea"] = LeaOp - iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', + iop = InstObjParams("tia", "Tia", 'X86ISA::MemNoDataOp', { "code": "xc->demapPage(EA, 0);", "ea_code": calculateEA, "memDataSize": "dataSize" }) header_output += MicroLeaDeclare.subst(iop) - decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) - class TiaOp(LdStOp): - def __init__(self, segment, addr, disp = 0, - dataSize="env.dataSize", - addressSize="env.addressSize"): - super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, - addr, disp, dataSize, addressSize, "0", False, False, - False, False, False) - self.className = "Tia" - self.mnemonic = "tia" - + class TiaOp(MemNoDataOp): + className = "Tia" + mnemonic = "tia" microopClasses["tia"] = TiaOp - - class CdaOp(LdStOp): - def __init__(self, segment, addr, disp = 0, - dataSize="env.dataSize", - addressSize="env.addressSize", atCPL0=False): - super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, - addr, disp, dataSize, addressSize, "Request::NO_ACCESS", - atCPL0, False, False, False, False) - self.className = "Cda" - self.mnemonic = "cda" - - microopClasses["cda"] = CdaOp }}; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 3b805f784a..ffd9e53847 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -93,13 +93,13 @@ def operands {{ 'SSrcReg1': intReg('src1', 1), 'SrcReg2': foldInt('src2', 'foldOBit', 2), 'SSrcReg2': intReg('src2', 2), - 'Index': foldInt('index', 'foldABit', 3), - 'Base': foldInt('base', 'foldABit', 4), + 'Index': intReg('index', 3), + 'Base': intReg('base', 4), 'DestReg': foldInt('dest', 'foldOBit', 5), 'SDestReg': intReg('dest', 5), - 'Data': foldInt('data', 'foldOBit', 6), - 'DataLow': foldInt('dataLow', 'foldOBit', 6), - 'DataHi': foldInt('dataHi', 'foldOBit', 6), + 'Data': intReg('data', 6), + 'DataLow': intReg('dataLow', 6), + 'DataHi': intReg('dataHi', 6), 'ProdLow': impIntReg(0, 7), 'ProdHi': impIntReg(1, 8), 'Quotient': impIntReg(2, 9),