amo.isa revision 12236
111726Sar4jc@virginia.edu// -*- mode:c++ -*- 211726Sar4jc@virginia.edu 311726Sar4jc@virginia.edu// Copyright (c) 2015 Riscv Developers 411726Sar4jc@virginia.edu// Copyright (c) 2016 The University of Virginia 511726Sar4jc@virginia.edu// All rights reserved. 611726Sar4jc@virginia.edu// 711726Sar4jc@virginia.edu// Redistribution and use in source and binary forms, with or without 811726Sar4jc@virginia.edu// modification, are permitted provided that the following conditions are 911726Sar4jc@virginia.edu// met: redistributions of source code must retain the above copyright 1011726Sar4jc@virginia.edu// notice, this list of conditions and the following disclaimer; 1111726Sar4jc@virginia.edu// redistributions in binary form must reproduce the above copyright 1211726Sar4jc@virginia.edu// notice, this list of conditions and the following disclaimer in the 1311726Sar4jc@virginia.edu// documentation and/or other materials provided with the distribution; 1411726Sar4jc@virginia.edu// neither the name of the copyright holders nor the names of its 1511726Sar4jc@virginia.edu// contributors may be used to endorse or promote products derived from 1611726Sar4jc@virginia.edu// this software without specific prior written permission. 1711726Sar4jc@virginia.edu// 1811726Sar4jc@virginia.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1911726Sar4jc@virginia.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2011726Sar4jc@virginia.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2111726Sar4jc@virginia.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2211726Sar4jc@virginia.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2311726Sar4jc@virginia.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2411726Sar4jc@virginia.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2511726Sar4jc@virginia.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2611726Sar4jc@virginia.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2711726Sar4jc@virginia.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2811726Sar4jc@virginia.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2911726Sar4jc@virginia.edu// 3011726Sar4jc@virginia.edu// Authors: Alec Roelke 3111726Sar4jc@virginia.edu 3211726Sar4jc@virginia.edu//////////////////////////////////////////////////////////////////// 3311726Sar4jc@virginia.edu// 3411726Sar4jc@virginia.edu// Atomic memory operation instructions 3511726Sar4jc@virginia.edu// 3611726Sar4jc@virginia.eduoutput header {{ 3711965Sar4jc@virginia.edu class LoadReserved : public RiscvStaticInst 3811965Sar4jc@virginia.edu { 3911965Sar4jc@virginia.edu protected: 4011965Sar4jc@virginia.edu Request::Flags memAccessFlags; 4111965Sar4jc@virginia.edu 4211965Sar4jc@virginia.edu LoadReserved(const char *mnem, ExtMachInst _machInst, 4311965Sar4jc@virginia.edu OpClass __opClass) 4411965Sar4jc@virginia.edu : RiscvStaticInst(mnem, _machInst, __opClass) 4511965Sar4jc@virginia.edu {} 4611965Sar4jc@virginia.edu 4711965Sar4jc@virginia.edu std::string 4811965Sar4jc@virginia.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 4911965Sar4jc@virginia.edu }; 5011965Sar4jc@virginia.edu 5111965Sar4jc@virginia.edu class StoreCond : public RiscvStaticInst 5211965Sar4jc@virginia.edu { 5311965Sar4jc@virginia.edu protected: 5411965Sar4jc@virginia.edu Request::Flags memAccessFlags; 5511965Sar4jc@virginia.edu 5611965Sar4jc@virginia.edu StoreCond(const char* mnem, ExtMachInst _machInst, OpClass __opClass) 5711965Sar4jc@virginia.edu : RiscvStaticInst(mnem, _machInst, __opClass) 5811965Sar4jc@virginia.edu {} 5911965Sar4jc@virginia.edu 6011965Sar4jc@virginia.edu std::string 6111965Sar4jc@virginia.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 6211965Sar4jc@virginia.edu }; 6311965Sar4jc@virginia.edu 6411726Sar4jc@virginia.edu class AtomicMemOp : public RiscvMacroInst 6511726Sar4jc@virginia.edu { 6611726Sar4jc@virginia.edu protected: 6711726Sar4jc@virginia.edu /// Constructor 6811726Sar4jc@virginia.edu // Each AtomicMemOp has a load and a store phase 6911726Sar4jc@virginia.edu AtomicMemOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 7011726Sar4jc@virginia.edu : RiscvMacroInst(mnem, _machInst, __opClass) 7111726Sar4jc@virginia.edu {} 7211726Sar4jc@virginia.edu 7311726Sar4jc@virginia.edu std::string generateDisassembly(Addr pc, 7411726Sar4jc@virginia.edu const SymbolTable *symtab) const; 7511726Sar4jc@virginia.edu }; 7611726Sar4jc@virginia.edu 7711726Sar4jc@virginia.edu class AtomicMemOpMicro : public RiscvMicroInst 7811726Sar4jc@virginia.edu { 7911726Sar4jc@virginia.edu protected: 8011726Sar4jc@virginia.edu /// Memory request flags. See mem/request.hh. 8111726Sar4jc@virginia.edu Request::Flags memAccessFlags; 8211726Sar4jc@virginia.edu 8311726Sar4jc@virginia.edu /// Constructor 8411726Sar4jc@virginia.edu AtomicMemOpMicro(const char *mnem, ExtMachInst _machInst, 8511726Sar4jc@virginia.edu OpClass __opClass) 8611726Sar4jc@virginia.edu : RiscvMicroInst(mnem, _machInst, __opClass) 8711726Sar4jc@virginia.edu {} 8811726Sar4jc@virginia.edu 8911726Sar4jc@virginia.edu std::string generateDisassembly(Addr pc, 9011726Sar4jc@virginia.edu const SymbolTable *symtab) const; 9111726Sar4jc@virginia.edu }; 9211726Sar4jc@virginia.edu}}; 9311726Sar4jc@virginia.edu 9411726Sar4jc@virginia.eduoutput decoder {{ 9511965Sar4jc@virginia.edu std::string LoadReserved::generateDisassembly(Addr pc, 9611965Sar4jc@virginia.edu const SymbolTable *symtab) const 9711965Sar4jc@virginia.edu { 9811965Sar4jc@virginia.edu std::stringstream ss; 9912119Sar4jc@virginia.edu ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", (" 10012119Sar4jc@virginia.edu << registerName(_srcRegIdx[0]) << ')'; 10111965Sar4jc@virginia.edu return ss.str(); 10211965Sar4jc@virginia.edu } 10311965Sar4jc@virginia.edu 10411965Sar4jc@virginia.edu std::string StoreCond::generateDisassembly(Addr pc, 10511965Sar4jc@virginia.edu const SymbolTable *symtab) const 10611965Sar4jc@virginia.edu { 10711965Sar4jc@virginia.edu std::stringstream ss; 10812119Sar4jc@virginia.edu ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " 10912119Sar4jc@virginia.edu << registerName(_srcRegIdx[1]) << ", (" 11012119Sar4jc@virginia.edu << registerName(_srcRegIdx[0]) << ')'; 11111965Sar4jc@virginia.edu return ss.str(); 11211965Sar4jc@virginia.edu } 11311965Sar4jc@virginia.edu 11411726Sar4jc@virginia.edu std::string AtomicMemOp::generateDisassembly(Addr pc, 11511726Sar4jc@virginia.edu const SymbolTable *symtab) const 11611726Sar4jc@virginia.edu { 11711726Sar4jc@virginia.edu std::stringstream ss; 11812119Sar4jc@virginia.edu ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " 11912119Sar4jc@virginia.edu << registerName(_srcRegIdx[1]) << ", (" 12012119Sar4jc@virginia.edu << registerName(_srcRegIdx[0]) << ')'; 12111726Sar4jc@virginia.edu return ss.str(); 12211726Sar4jc@virginia.edu } 12311726Sar4jc@virginia.edu 12411726Sar4jc@virginia.edu std::string AtomicMemOpMicro::generateDisassembly(Addr pc, 12511726Sar4jc@virginia.edu const SymbolTable *symtab) const 12611726Sar4jc@virginia.edu { 12711726Sar4jc@virginia.edu std::stringstream ss; 12811726Sar4jc@virginia.edu ss << csprintf("0x%08x", machInst) << ' ' << mnemonic; 12911726Sar4jc@virginia.edu return ss.str(); 13011726Sar4jc@virginia.edu } 13111726Sar4jc@virginia.edu}}; 13211726Sar4jc@virginia.edu 13311726Sar4jc@virginia.edudef template AtomicMemOpDeclare {{ 13411726Sar4jc@virginia.edu /** 13511726Sar4jc@virginia.edu * Static instruction class for an AtomicMemOp operation 13611726Sar4jc@virginia.edu */ 13711726Sar4jc@virginia.edu class %(class_name)s : public %(base_class)s 13811726Sar4jc@virginia.edu { 13911726Sar4jc@virginia.edu public: 14011726Sar4jc@virginia.edu // Constructor 14111726Sar4jc@virginia.edu %(class_name)s(ExtMachInst machInst); 14211726Sar4jc@virginia.edu 14311726Sar4jc@virginia.edu protected: 14411726Sar4jc@virginia.edu 14511726Sar4jc@virginia.edu class %(class_name)sLoad : public %(base_class)sMicro 14611726Sar4jc@virginia.edu { 14711726Sar4jc@virginia.edu public: 14811726Sar4jc@virginia.edu // Constructor 14911726Sar4jc@virginia.edu %(class_name)sLoad(ExtMachInst machInst, %(class_name)s *_p); 15011726Sar4jc@virginia.edu 15112236Sgabeblack@google.com Fault execute(ExecContext *, Trace::InstRecord *) const; 15212236Sgabeblack@google.com Fault eaComp(ExecContext *, Trace::InstRecord *) const; 15312236Sgabeblack@google.com Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 15412236Sgabeblack@google.com Fault completeAcc(PacketPtr, ExecContext *, 15512236Sgabeblack@google.com Trace::InstRecord *) const; 15611726Sar4jc@virginia.edu }; 15711726Sar4jc@virginia.edu 15811726Sar4jc@virginia.edu class %(class_name)sStore : public %(base_class)sMicro 15911726Sar4jc@virginia.edu { 16011726Sar4jc@virginia.edu public: 16111726Sar4jc@virginia.edu // Constructor 16211726Sar4jc@virginia.edu %(class_name)sStore(ExtMachInst machInst, %(class_name)s *_p); 16311726Sar4jc@virginia.edu 16412236Sgabeblack@google.com Fault execute(ExecContext *, Trace::InstRecord *) const; 16512236Sgabeblack@google.com Fault eaComp(ExecContext *, Trace::InstRecord *) const; 16612236Sgabeblack@google.com Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 16712236Sgabeblack@google.com Fault completeAcc(PacketPtr, ExecContext *, 16812236Sgabeblack@google.com Trace::InstRecord *) const; 16911726Sar4jc@virginia.edu }; 17011726Sar4jc@virginia.edu }; 17111726Sar4jc@virginia.edu}}; 17211726Sar4jc@virginia.edu 17311965Sar4jc@virginia.edudef template LRSCConstructor {{ 17411965Sar4jc@virginia.edu %(class_name)s::%(class_name)s(ExtMachInst machInst): 17511965Sar4jc@virginia.edu %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 17611965Sar4jc@virginia.edu { 17711965Sar4jc@virginia.edu %(constructor)s; 17811965Sar4jc@virginia.edu if (AQ) 17911965Sar4jc@virginia.edu memAccessFlags = memAccessFlags | Request::ACQUIRE; 18011965Sar4jc@virginia.edu if (RL) 18111965Sar4jc@virginia.edu memAccessFlags = memAccessFlags | Request::RELEASE; 18211965Sar4jc@virginia.edu } 18311965Sar4jc@virginia.edu}}; 18411965Sar4jc@virginia.edu 18511726Sar4jc@virginia.edudef template AtomicMemOpMacroConstructor {{ 18611726Sar4jc@virginia.edu %(class_name)s::%(class_name)s(ExtMachInst machInst) 18711726Sar4jc@virginia.edu : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 18811726Sar4jc@virginia.edu { 18911726Sar4jc@virginia.edu %(constructor)s; 19011726Sar4jc@virginia.edu microops = {new %(class_name)sLoad(machInst, this), 19111726Sar4jc@virginia.edu new %(class_name)sStore(machInst, this)}; 19211726Sar4jc@virginia.edu } 19311726Sar4jc@virginia.edu}}; 19411726Sar4jc@virginia.edu 19511726Sar4jc@virginia.edudef template AtomicMemOpLoadConstructor {{ 19611726Sar4jc@virginia.edu %(class_name)s::%(class_name)sLoad::%(class_name)sLoad( 19711726Sar4jc@virginia.edu ExtMachInst machInst, %(class_name)s *_p) 19811726Sar4jc@virginia.edu : %(base_class)s("%(mnemonic)s[l]", machInst, %(op_class)s) 19911726Sar4jc@virginia.edu { 20011726Sar4jc@virginia.edu %(constructor)s; 20111726Sar4jc@virginia.edu flags[IsFirstMicroop] = true; 20211726Sar4jc@virginia.edu flags[IsDelayedCommit] = true; 20311726Sar4jc@virginia.edu if (AQ) 20411726Sar4jc@virginia.edu memAccessFlags = Request::ACQUIRE; 20511726Sar4jc@virginia.edu } 20611726Sar4jc@virginia.edu}}; 20711726Sar4jc@virginia.edu 20811726Sar4jc@virginia.edudef template AtomicMemOpStoreConstructor {{ 20911726Sar4jc@virginia.edu %(class_name)s::%(class_name)sStore::%(class_name)sStore( 21011726Sar4jc@virginia.edu ExtMachInst machInst, %(class_name)s *_p) 21111726Sar4jc@virginia.edu : %(base_class)s("%(mnemonic)s[s]", machInst, %(op_class)s) 21211726Sar4jc@virginia.edu { 21311726Sar4jc@virginia.edu %(constructor)s; 21411726Sar4jc@virginia.edu flags[IsLastMicroop] = true; 21511726Sar4jc@virginia.edu flags[IsNonSpeculative] = true; 21611726Sar4jc@virginia.edu if (RL) 21711726Sar4jc@virginia.edu memAccessFlags = Request::RELEASE; 21811726Sar4jc@virginia.edu } 21911726Sar4jc@virginia.edu}}; 22011726Sar4jc@virginia.edu 22111965Sar4jc@virginia.edudef template StoreCondExecute {{ 22212234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 22311965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 22411965Sar4jc@virginia.edu { 22511965Sar4jc@virginia.edu Addr EA; 22611965Sar4jc@virginia.edu Fault fault = NoFault; 22711965Sar4jc@virginia.edu uint64_t result; 22811965Sar4jc@virginia.edu 22911965Sar4jc@virginia.edu %(op_decl)s; 23011965Sar4jc@virginia.edu %(op_rd)s; 23111965Sar4jc@virginia.edu %(ea_code)s; 23211965Sar4jc@virginia.edu 23311965Sar4jc@virginia.edu if (fault == NoFault) { 23411965Sar4jc@virginia.edu %(memacc_code)s; 23511965Sar4jc@virginia.edu } 23611965Sar4jc@virginia.edu 23711965Sar4jc@virginia.edu if (fault == NoFault) { 23811965Sar4jc@virginia.edu fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 23911965Sar4jc@virginia.edu &result); 24011965Sar4jc@virginia.edu // RISC-V has the opposite convention gem5 has for success flags, 24111965Sar4jc@virginia.edu // so we invert the result here. 24211965Sar4jc@virginia.edu result = !result; 24311965Sar4jc@virginia.edu } 24411965Sar4jc@virginia.edu 24511965Sar4jc@virginia.edu if (fault == NoFault) { 24611965Sar4jc@virginia.edu %(postacc_code)s; 24711965Sar4jc@virginia.edu } 24811965Sar4jc@virginia.edu 24911965Sar4jc@virginia.edu if (fault == NoFault) { 25011965Sar4jc@virginia.edu %(op_wb)s; 25111965Sar4jc@virginia.edu } 25211965Sar4jc@virginia.edu 25311965Sar4jc@virginia.edu return fault; 25411965Sar4jc@virginia.edu } 25511965Sar4jc@virginia.edu}}; 25611965Sar4jc@virginia.edu 25711726Sar4jc@virginia.edudef template AtomicMemOpLoadExecute {{ 25812234Sgabeblack@google.com Fault %(class_name)s::%(class_name)sLoad::execute(ExecContext *xc, 25911726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 26011726Sar4jc@virginia.edu { 26111726Sar4jc@virginia.edu Addr EA; 26211726Sar4jc@virginia.edu Fault fault = NoFault; 26311726Sar4jc@virginia.edu 26411726Sar4jc@virginia.edu %(op_decl)s; 26511726Sar4jc@virginia.edu %(op_rd)s; 26611726Sar4jc@virginia.edu %(ea_code)s; 26711726Sar4jc@virginia.edu 26811726Sar4jc@virginia.edu if (fault == NoFault) { 26911726Sar4jc@virginia.edu fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 27011726Sar4jc@virginia.edu } 27111726Sar4jc@virginia.edu 27211726Sar4jc@virginia.edu if (fault == NoFault) { 27311726Sar4jc@virginia.edu %(code)s; 27411726Sar4jc@virginia.edu } 27511726Sar4jc@virginia.edu 27611726Sar4jc@virginia.edu if (fault == NoFault) { 27711726Sar4jc@virginia.edu %(op_wb)s; 27811726Sar4jc@virginia.edu } 27911726Sar4jc@virginia.edu 28011726Sar4jc@virginia.edu return fault; 28111726Sar4jc@virginia.edu } 28211726Sar4jc@virginia.edu}}; 28311726Sar4jc@virginia.edu 28411726Sar4jc@virginia.edudef template AtomicMemOpStoreExecute {{ 28512234Sgabeblack@google.com Fault %(class_name)s::%(class_name)sStore::execute(ExecContext *xc, 28611726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 28711726Sar4jc@virginia.edu { 28811726Sar4jc@virginia.edu Addr EA; 28911726Sar4jc@virginia.edu Fault fault = NoFault; 29011726Sar4jc@virginia.edu 29111726Sar4jc@virginia.edu %(op_decl)s; 29211726Sar4jc@virginia.edu %(op_rd)s; 29311726Sar4jc@virginia.edu %(ea_code)s; 29411726Sar4jc@virginia.edu 29511726Sar4jc@virginia.edu if (fault == NoFault) { 29611726Sar4jc@virginia.edu %(code)s; 29711726Sar4jc@virginia.edu } 29811726Sar4jc@virginia.edu 29911726Sar4jc@virginia.edu if (fault == NoFault) { 30011726Sar4jc@virginia.edu fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 30111726Sar4jc@virginia.edu nullptr); 30211726Sar4jc@virginia.edu } 30311726Sar4jc@virginia.edu 30411726Sar4jc@virginia.edu if (fault == NoFault) { 30511726Sar4jc@virginia.edu %(op_wb)s; 30611726Sar4jc@virginia.edu } 30711726Sar4jc@virginia.edu 30811726Sar4jc@virginia.edu return fault; 30911726Sar4jc@virginia.edu } 31011726Sar4jc@virginia.edu}}; 31111726Sar4jc@virginia.edu 31212119Sar4jc@virginia.edudef template AtomicMemOpEACompExecute {{ 31311965Sar4jc@virginia.edu Fault 31412234Sgabeblack@google.com %(class_name)s::%(class_name)s%(op_name)s::eaComp(ExecContext *xc, 31511965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 31611965Sar4jc@virginia.edu { 31711965Sar4jc@virginia.edu Addr EA; 31811965Sar4jc@virginia.edu Fault fault = NoFault; 31911965Sar4jc@virginia.edu 32011965Sar4jc@virginia.edu %(op_decl)s; 32111965Sar4jc@virginia.edu %(op_rd)s; 32211965Sar4jc@virginia.edu %(ea_code)s; 32311965Sar4jc@virginia.edu 32411965Sar4jc@virginia.edu if (fault == NoFault) { 32511965Sar4jc@virginia.edu %(op_wb)s; 32611965Sar4jc@virginia.edu xc->setEA(EA); 32711965Sar4jc@virginia.edu } 32811965Sar4jc@virginia.edu 32911965Sar4jc@virginia.edu return fault; 33011965Sar4jc@virginia.edu } 33111965Sar4jc@virginia.edu}}; 33211965Sar4jc@virginia.edu 33311726Sar4jc@virginia.edudef template AtomicMemOpLoadInitiateAcc {{ 33412234Sgabeblack@google.com Fault %(class_name)s::%(class_name)sLoad::initiateAcc(ExecContext *xc, 33511726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 33611726Sar4jc@virginia.edu { 33711726Sar4jc@virginia.edu Addr EA; 33811726Sar4jc@virginia.edu Fault fault = NoFault; 33911726Sar4jc@virginia.edu 34011726Sar4jc@virginia.edu %(op_src_decl)s; 34111726Sar4jc@virginia.edu %(op_rd)s; 34211726Sar4jc@virginia.edu %(ea_code)s; 34311726Sar4jc@virginia.edu 34411726Sar4jc@virginia.edu if (fault == NoFault) { 34511726Sar4jc@virginia.edu fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 34611726Sar4jc@virginia.edu } 34711726Sar4jc@virginia.edu 34811726Sar4jc@virginia.edu return fault; 34911726Sar4jc@virginia.edu } 35011726Sar4jc@virginia.edu}}; 35111726Sar4jc@virginia.edu 35211726Sar4jc@virginia.edudef template AtomicMemOpStoreInitiateAcc {{ 35311726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sStore::initiateAcc( 35412234Sgabeblack@google.com ExecContext *xc, Trace::InstRecord *traceData) const 35511726Sar4jc@virginia.edu { 35611726Sar4jc@virginia.edu Addr EA; 35711726Sar4jc@virginia.edu Fault fault = NoFault; 35811726Sar4jc@virginia.edu 35911726Sar4jc@virginia.edu %(op_decl)s; 36011726Sar4jc@virginia.edu %(op_rd)s; 36111726Sar4jc@virginia.edu %(ea_code)s; 36211726Sar4jc@virginia.edu 36311726Sar4jc@virginia.edu if (fault == NoFault) { 36411726Sar4jc@virginia.edu %(code)s; 36511726Sar4jc@virginia.edu } 36611726Sar4jc@virginia.edu 36711726Sar4jc@virginia.edu if (fault == NoFault) { 36811726Sar4jc@virginia.edu fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 36911726Sar4jc@virginia.edu nullptr); 37011726Sar4jc@virginia.edu } 37111726Sar4jc@virginia.edu 37211726Sar4jc@virginia.edu if (fault == NoFault) { 37311726Sar4jc@virginia.edu %(op_wb)s; 37411726Sar4jc@virginia.edu } 37511726Sar4jc@virginia.edu 37611726Sar4jc@virginia.edu return fault; 37711726Sar4jc@virginia.edu } 37811726Sar4jc@virginia.edu}}; 37911726Sar4jc@virginia.edu 38011965Sar4jc@virginia.edudef template StoreCondCompleteAcc {{ 38112234Sgabeblack@google.com Fault %(class_name)s::completeAcc(Packet *pkt, ExecContext *xc, 38211965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 38311965Sar4jc@virginia.edu { 38411965Sar4jc@virginia.edu Fault fault = NoFault; 38511965Sar4jc@virginia.edu 38611965Sar4jc@virginia.edu %(op_dest_decl)s; 38711965Sar4jc@virginia.edu 38811965Sar4jc@virginia.edu // RISC-V has the opposite convention gem5 has for success flags, 38911965Sar4jc@virginia.edu // so we invert the result here. 39011965Sar4jc@virginia.edu uint64_t result = !pkt->req->getExtraData(); 39111965Sar4jc@virginia.edu 39211965Sar4jc@virginia.edu if (fault == NoFault) { 39311965Sar4jc@virginia.edu %(postacc_code)s; 39411965Sar4jc@virginia.edu } 39511965Sar4jc@virginia.edu 39611965Sar4jc@virginia.edu if (fault == NoFault) { 39711965Sar4jc@virginia.edu %(op_wb)s; 39811965Sar4jc@virginia.edu } 39911965Sar4jc@virginia.edu 40011965Sar4jc@virginia.edu return fault; 40111965Sar4jc@virginia.edu } 40211965Sar4jc@virginia.edu}}; 40311965Sar4jc@virginia.edu 40411726Sar4jc@virginia.edudef template AtomicMemOpLoadCompleteAcc {{ 40511726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sLoad::completeAcc(PacketPtr pkt, 40612234Sgabeblack@google.com ExecContext *xc, Trace::InstRecord *traceData) const 40711726Sar4jc@virginia.edu { 40811726Sar4jc@virginia.edu Fault fault = NoFault; 40911726Sar4jc@virginia.edu 41011726Sar4jc@virginia.edu %(op_decl)s; 41111726Sar4jc@virginia.edu %(op_rd)s; 41211726Sar4jc@virginia.edu 41311726Sar4jc@virginia.edu getMem(pkt, Mem, traceData); 41411726Sar4jc@virginia.edu 41511726Sar4jc@virginia.edu if (fault == NoFault) { 41611726Sar4jc@virginia.edu %(code)s; 41711726Sar4jc@virginia.edu } 41811726Sar4jc@virginia.edu 41911726Sar4jc@virginia.edu if (fault == NoFault) { 42011726Sar4jc@virginia.edu %(op_wb)s; 42111726Sar4jc@virginia.edu } 42211726Sar4jc@virginia.edu 42311726Sar4jc@virginia.edu return fault; 42411726Sar4jc@virginia.edu } 42511726Sar4jc@virginia.edu}}; 42611726Sar4jc@virginia.edu 42711726Sar4jc@virginia.edudef template AtomicMemOpStoreCompleteAcc {{ 42811726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sStore::completeAcc(PacketPtr pkt, 42912234Sgabeblack@google.com ExecContext *xc, Trace::InstRecord *traceData) const 43011726Sar4jc@virginia.edu { 43111726Sar4jc@virginia.edu return NoFault; 43211726Sar4jc@virginia.edu } 43311726Sar4jc@virginia.edu}}; 43411726Sar4jc@virginia.edu 43511965Sar4jc@virginia.edudef format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 43611965Sar4jc@virginia.edu mem_flags=[], inst_flags=[]) {{ 43711965Sar4jc@virginia.edu mem_flags = makeList(mem_flags) 43811965Sar4jc@virginia.edu inst_flags = makeList(inst_flags) 43911965Sar4jc@virginia.edu iop = InstObjParams(name, Name, 'LoadReserved', 44011965Sar4jc@virginia.edu {'ea_code': ea_code, 'memacc_code': memacc_code, 44111965Sar4jc@virginia.edu 'postacc_code': postacc_code}, inst_flags) 44211965Sar4jc@virginia.edu iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 44311965Sar4jc@virginia.edu '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 44411965Sar4jc@virginia.edu 44512119Sar4jc@virginia.edu header_output = LoadStoreDeclare.subst(iop) 44611965Sar4jc@virginia.edu decoder_output = LRSCConstructor.subst(iop) 44711965Sar4jc@virginia.edu decode_block = BasicDecode.subst(iop) 44812119Sar4jc@virginia.edu exec_output = LoadExecute.subst(iop) \ 44912119Sar4jc@virginia.edu + EACompExecute.subst(iop) \ 45012119Sar4jc@virginia.edu + LoadInitiateAcc.subst(iop) \ 45112119Sar4jc@virginia.edu + LoadCompleteAcc.subst(iop) 45211965Sar4jc@virginia.edu}}; 45311965Sar4jc@virginia.edu 45411965Sar4jc@virginia.edudef format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 45511965Sar4jc@virginia.edu mem_flags=[], inst_flags=[]) {{ 45611965Sar4jc@virginia.edu mem_flags = makeList(mem_flags) 45711965Sar4jc@virginia.edu inst_flags = makeList(inst_flags) 45811965Sar4jc@virginia.edu iop = InstObjParams(name, Name, 'StoreCond', 45911965Sar4jc@virginia.edu {'ea_code': ea_code, 'memacc_code': memacc_code, 46011965Sar4jc@virginia.edu 'postacc_code': postacc_code}, inst_flags) 46111965Sar4jc@virginia.edu iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 46211965Sar4jc@virginia.edu '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 46311965Sar4jc@virginia.edu 46412119Sar4jc@virginia.edu header_output = LoadStoreDeclare.subst(iop) 46511965Sar4jc@virginia.edu decoder_output = LRSCConstructor.subst(iop) 46611965Sar4jc@virginia.edu decode_block = BasicDecode.subst(iop) 46711965Sar4jc@virginia.edu exec_output = StoreCondExecute.subst(iop) \ 46812119Sar4jc@virginia.edu + EACompExecute.subst(iop) \ 46912119Sar4jc@virginia.edu + StoreInitiateAcc.subst(iop) \ 47011965Sar4jc@virginia.edu + StoreCondCompleteAcc.subst(iop) 47111965Sar4jc@virginia.edu}}; 47211965Sar4jc@virginia.edu 47311726Sar4jc@virginia.edudef format AtomicMemOp(load_code, store_code, ea_code, load_flags=[], 47411726Sar4jc@virginia.edu store_flags=[], inst_flags=[]) {{ 47511726Sar4jc@virginia.edu macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags) 47611726Sar4jc@virginia.edu header_output = AtomicMemOpDeclare.subst(macro_iop) 47711726Sar4jc@virginia.edu decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop) 47812119Sar4jc@virginia.edu decode_block = BasicDecode.subst(macro_iop) 47911726Sar4jc@virginia.edu exec_output = '' 48011726Sar4jc@virginia.edu 48111726Sar4jc@virginia.edu load_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsLoad"] 48211726Sar4jc@virginia.edu load_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 48312119Sar4jc@virginia.edu {'ea_code': ea_code, 'code': load_code, 'op_name': 'Load'}, 48412119Sar4jc@virginia.edu load_inst_flags) 48511726Sar4jc@virginia.edu decoder_output += AtomicMemOpLoadConstructor.subst(load_iop) 48611726Sar4jc@virginia.edu exec_output += AtomicMemOpLoadExecute.subst(load_iop) \ 48712119Sar4jc@virginia.edu + AtomicMemOpEACompExecute.subst(load_iop) \ 48811726Sar4jc@virginia.edu + AtomicMemOpLoadInitiateAcc.subst(load_iop) \ 48911726Sar4jc@virginia.edu + AtomicMemOpLoadCompleteAcc.subst(load_iop) 49011726Sar4jc@virginia.edu 49111726Sar4jc@virginia.edu store_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsStore"] 49211726Sar4jc@virginia.edu store_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 49312119Sar4jc@virginia.edu {'ea_code': ea_code, 'code': store_code, 'op_name': 'Store'}, 49412119Sar4jc@virginia.edu store_inst_flags) 49511726Sar4jc@virginia.edu decoder_output += AtomicMemOpStoreConstructor.subst(store_iop) 49611726Sar4jc@virginia.edu exec_output += AtomicMemOpStoreExecute.subst(store_iop) \ 49712119Sar4jc@virginia.edu + AtomicMemOpEACompExecute.subst(store_iop) \ 49811726Sar4jc@virginia.edu + AtomicMemOpStoreInitiateAcc.subst(store_iop) \ 49911726Sar4jc@virginia.edu + AtomicMemOpStoreCompleteAcc.subst(store_iop) 50011726Sar4jc@virginia.edu}}; 501