amo.isa revision 11965
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; 9911965Sar4jc@virginia.edu ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", (" 10011965Sar4jc@virginia.edu << regName(_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; 10811965Sar4jc@virginia.edu ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " 10911965Sar4jc@virginia.edu << regName(_srcRegIdx[1]) << ", (" 11011965Sar4jc@virginia.edu << regName(_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; 11811726Sar4jc@virginia.edu ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " 11911726Sar4jc@virginia.edu << regName(_srcRegIdx[1]) << ", (" 12011726Sar4jc@virginia.edu << regName(_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 13311965Sar4jc@virginia.edudef template LRSCDeclare {{ 13411965Sar4jc@virginia.edu class %(class_name)s : public %(base_class)s 13511965Sar4jc@virginia.edu { 13611965Sar4jc@virginia.edu public: 13711965Sar4jc@virginia.edu %(class_name)s(ExtMachInst machInst); 13811965Sar4jc@virginia.edu 13911965Sar4jc@virginia.edu %(BasicExecDeclare)s 14011965Sar4jc@virginia.edu 14111965Sar4jc@virginia.edu %(EACompDeclare)s 14211965Sar4jc@virginia.edu 14311965Sar4jc@virginia.edu %(InitiateAccDeclare)s 14411965Sar4jc@virginia.edu 14511965Sar4jc@virginia.edu %(CompleteAccDeclare)s 14611965Sar4jc@virginia.edu }; 14711965Sar4jc@virginia.edu}}; 14811965Sar4jc@virginia.edu 14911726Sar4jc@virginia.edudef template AtomicMemOpDeclare {{ 15011726Sar4jc@virginia.edu /** 15111726Sar4jc@virginia.edu * Static instruction class for an AtomicMemOp operation 15211726Sar4jc@virginia.edu */ 15311726Sar4jc@virginia.edu class %(class_name)s : public %(base_class)s 15411726Sar4jc@virginia.edu { 15511726Sar4jc@virginia.edu public: 15611726Sar4jc@virginia.edu // Constructor 15711726Sar4jc@virginia.edu %(class_name)s(ExtMachInst machInst); 15811726Sar4jc@virginia.edu 15911726Sar4jc@virginia.edu protected: 16011726Sar4jc@virginia.edu 16111726Sar4jc@virginia.edu class %(class_name)sLoad : public %(base_class)sMicro 16211726Sar4jc@virginia.edu { 16311726Sar4jc@virginia.edu public: 16411726Sar4jc@virginia.edu // Constructor 16511726Sar4jc@virginia.edu %(class_name)sLoad(ExtMachInst machInst, %(class_name)s *_p); 16611726Sar4jc@virginia.edu 16711726Sar4jc@virginia.edu %(BasicExecDeclare)s 16811726Sar4jc@virginia.edu 16911726Sar4jc@virginia.edu %(EACompDeclare)s 17011726Sar4jc@virginia.edu 17111726Sar4jc@virginia.edu %(InitiateAccDeclare)s 17211726Sar4jc@virginia.edu 17311726Sar4jc@virginia.edu %(CompleteAccDeclare)s 17411726Sar4jc@virginia.edu }; 17511726Sar4jc@virginia.edu 17611726Sar4jc@virginia.edu class %(class_name)sStore : public %(base_class)sMicro 17711726Sar4jc@virginia.edu { 17811726Sar4jc@virginia.edu public: 17911726Sar4jc@virginia.edu // Constructor 18011726Sar4jc@virginia.edu %(class_name)sStore(ExtMachInst machInst, %(class_name)s *_p); 18111726Sar4jc@virginia.edu 18211726Sar4jc@virginia.edu %(BasicExecDeclare)s 18311726Sar4jc@virginia.edu 18411726Sar4jc@virginia.edu %(EACompDeclare)s 18511726Sar4jc@virginia.edu 18611726Sar4jc@virginia.edu %(InitiateAccDeclare)s 18711726Sar4jc@virginia.edu 18811726Sar4jc@virginia.edu %(CompleteAccDeclare)s 18911726Sar4jc@virginia.edu }; 19011726Sar4jc@virginia.edu }; 19111726Sar4jc@virginia.edu}}; 19211726Sar4jc@virginia.edu 19311965Sar4jc@virginia.edudef template LRSCConstructor {{ 19411965Sar4jc@virginia.edu %(class_name)s::%(class_name)s(ExtMachInst machInst): 19511965Sar4jc@virginia.edu %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 19611965Sar4jc@virginia.edu { 19711965Sar4jc@virginia.edu %(constructor)s; 19811965Sar4jc@virginia.edu if (AQ) 19911965Sar4jc@virginia.edu memAccessFlags = memAccessFlags | Request::ACQUIRE; 20011965Sar4jc@virginia.edu if (RL) 20111965Sar4jc@virginia.edu memAccessFlags = memAccessFlags | Request::RELEASE; 20211965Sar4jc@virginia.edu } 20311965Sar4jc@virginia.edu}}; 20411965Sar4jc@virginia.edu 20511726Sar4jc@virginia.edudef template AtomicMemOpMacroConstructor {{ 20611726Sar4jc@virginia.edu %(class_name)s::%(class_name)s(ExtMachInst machInst) 20711726Sar4jc@virginia.edu : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 20811726Sar4jc@virginia.edu { 20911726Sar4jc@virginia.edu %(constructor)s; 21011726Sar4jc@virginia.edu microops = {new %(class_name)sLoad(machInst, this), 21111726Sar4jc@virginia.edu new %(class_name)sStore(machInst, this)}; 21211726Sar4jc@virginia.edu } 21311726Sar4jc@virginia.edu}}; 21411726Sar4jc@virginia.edu 21511726Sar4jc@virginia.edudef template AtomicMemOpLoadConstructor {{ 21611726Sar4jc@virginia.edu %(class_name)s::%(class_name)sLoad::%(class_name)sLoad( 21711726Sar4jc@virginia.edu ExtMachInst machInst, %(class_name)s *_p) 21811726Sar4jc@virginia.edu : %(base_class)s("%(mnemonic)s[l]", machInst, %(op_class)s) 21911726Sar4jc@virginia.edu { 22011726Sar4jc@virginia.edu %(constructor)s; 22111726Sar4jc@virginia.edu flags[IsFirstMicroop] = true; 22211726Sar4jc@virginia.edu flags[IsDelayedCommit] = true; 22311726Sar4jc@virginia.edu if (AQ) 22411726Sar4jc@virginia.edu memAccessFlags = Request::ACQUIRE; 22511726Sar4jc@virginia.edu } 22611726Sar4jc@virginia.edu}}; 22711726Sar4jc@virginia.edu 22811726Sar4jc@virginia.edudef template AtomicMemOpStoreConstructor {{ 22911726Sar4jc@virginia.edu %(class_name)s::%(class_name)sStore::%(class_name)sStore( 23011726Sar4jc@virginia.edu ExtMachInst machInst, %(class_name)s *_p) 23111726Sar4jc@virginia.edu : %(base_class)s("%(mnemonic)s[s]", machInst, %(op_class)s) 23211726Sar4jc@virginia.edu { 23311726Sar4jc@virginia.edu %(constructor)s; 23411726Sar4jc@virginia.edu flags[IsLastMicroop] = true; 23511726Sar4jc@virginia.edu flags[IsNonSpeculative] = true; 23611726Sar4jc@virginia.edu if (RL) 23711726Sar4jc@virginia.edu memAccessFlags = Request::RELEASE; 23811726Sar4jc@virginia.edu } 23911726Sar4jc@virginia.edu}}; 24011726Sar4jc@virginia.edu 24111726Sar4jc@virginia.edudef template AtomicMemOpMacroDecode {{ 24211726Sar4jc@virginia.edu return new %(class_name)s(machInst); 24311726Sar4jc@virginia.edu}}; 24411726Sar4jc@virginia.edu 24511965Sar4jc@virginia.edudef template LoadReservedExecute {{ 24611965Sar4jc@virginia.edu Fault 24711965Sar4jc@virginia.edu %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 24811965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 24911965Sar4jc@virginia.edu { 25011965Sar4jc@virginia.edu Addr EA; 25111965Sar4jc@virginia.edu Fault fault = NoFault; 25211965Sar4jc@virginia.edu 25311965Sar4jc@virginia.edu %(op_decl)s; 25411965Sar4jc@virginia.edu %(op_rd)s; 25511965Sar4jc@virginia.edu %(ea_code)s; 25611965Sar4jc@virginia.edu 25711965Sar4jc@virginia.edu if (fault == NoFault) { 25811965Sar4jc@virginia.edu fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 25911965Sar4jc@virginia.edu %(memacc_code)s; 26011965Sar4jc@virginia.edu } 26111965Sar4jc@virginia.edu 26211965Sar4jc@virginia.edu if (fault == NoFault) { 26311965Sar4jc@virginia.edu %(op_wb)s; 26411965Sar4jc@virginia.edu } 26511965Sar4jc@virginia.edu 26611965Sar4jc@virginia.edu return fault; 26711965Sar4jc@virginia.edu } 26811965Sar4jc@virginia.edu}}; 26911965Sar4jc@virginia.edu 27011965Sar4jc@virginia.edudef template StoreCondExecute {{ 27111965Sar4jc@virginia.edu Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 27211965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 27311965Sar4jc@virginia.edu { 27411965Sar4jc@virginia.edu Addr EA; 27511965Sar4jc@virginia.edu Fault fault = NoFault; 27611965Sar4jc@virginia.edu uint64_t result; 27711965Sar4jc@virginia.edu 27811965Sar4jc@virginia.edu %(op_decl)s; 27911965Sar4jc@virginia.edu %(op_rd)s; 28011965Sar4jc@virginia.edu %(ea_code)s; 28111965Sar4jc@virginia.edu 28211965Sar4jc@virginia.edu if (fault == NoFault) { 28311965Sar4jc@virginia.edu %(memacc_code)s; 28411965Sar4jc@virginia.edu } 28511965Sar4jc@virginia.edu 28611965Sar4jc@virginia.edu if (fault == NoFault) { 28711965Sar4jc@virginia.edu fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 28811965Sar4jc@virginia.edu &result); 28911965Sar4jc@virginia.edu // RISC-V has the opposite convention gem5 has for success flags, 29011965Sar4jc@virginia.edu // so we invert the result here. 29111965Sar4jc@virginia.edu result = !result; 29211965Sar4jc@virginia.edu } 29311965Sar4jc@virginia.edu 29411965Sar4jc@virginia.edu if (fault == NoFault) { 29511965Sar4jc@virginia.edu %(postacc_code)s; 29611965Sar4jc@virginia.edu } 29711965Sar4jc@virginia.edu 29811965Sar4jc@virginia.edu if (fault == NoFault) { 29911965Sar4jc@virginia.edu %(op_wb)s; 30011965Sar4jc@virginia.edu } 30111965Sar4jc@virginia.edu 30211965Sar4jc@virginia.edu return fault; 30311965Sar4jc@virginia.edu } 30411965Sar4jc@virginia.edu}}; 30511965Sar4jc@virginia.edu 30611726Sar4jc@virginia.edudef template AtomicMemOpLoadExecute {{ 30711726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sLoad::execute(CPU_EXEC_CONTEXT *xc, 30811726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 30911726Sar4jc@virginia.edu { 31011726Sar4jc@virginia.edu Addr EA; 31111726Sar4jc@virginia.edu Fault fault = NoFault; 31211726Sar4jc@virginia.edu 31311726Sar4jc@virginia.edu %(op_decl)s; 31411726Sar4jc@virginia.edu %(op_rd)s; 31511726Sar4jc@virginia.edu %(ea_code)s; 31611726Sar4jc@virginia.edu 31711726Sar4jc@virginia.edu if (fault == NoFault) { 31811726Sar4jc@virginia.edu fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 31911726Sar4jc@virginia.edu } 32011726Sar4jc@virginia.edu 32111726Sar4jc@virginia.edu if (fault == NoFault) { 32211726Sar4jc@virginia.edu %(code)s; 32311726Sar4jc@virginia.edu } 32411726Sar4jc@virginia.edu 32511726Sar4jc@virginia.edu if (fault == NoFault) { 32611726Sar4jc@virginia.edu %(op_wb)s; 32711726Sar4jc@virginia.edu } 32811726Sar4jc@virginia.edu 32911726Sar4jc@virginia.edu return fault; 33011726Sar4jc@virginia.edu } 33111726Sar4jc@virginia.edu}}; 33211726Sar4jc@virginia.edu 33311726Sar4jc@virginia.edudef template AtomicMemOpStoreExecute {{ 33411726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sStore::execute(CPU_EXEC_CONTEXT *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_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 %(code)s; 34611726Sar4jc@virginia.edu } 34711726Sar4jc@virginia.edu 34811726Sar4jc@virginia.edu if (fault == NoFault) { 34911726Sar4jc@virginia.edu fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 35011726Sar4jc@virginia.edu nullptr); 35111726Sar4jc@virginia.edu } 35211726Sar4jc@virginia.edu 35311726Sar4jc@virginia.edu if (fault == NoFault) { 35411726Sar4jc@virginia.edu %(op_wb)s; 35511726Sar4jc@virginia.edu } 35611726Sar4jc@virginia.edu 35711726Sar4jc@virginia.edu return fault; 35811726Sar4jc@virginia.edu } 35911726Sar4jc@virginia.edu}}; 36011726Sar4jc@virginia.edu 36111965Sar4jc@virginia.edudef template LRSCEACompExecute {{ 36211965Sar4jc@virginia.edu Fault 36311965Sar4jc@virginia.edu %(class_name)s::eaComp(CPU_EXEC_CONTEXT *xc, 36411965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 36511965Sar4jc@virginia.edu { 36611965Sar4jc@virginia.edu Addr EA; 36711965Sar4jc@virginia.edu Fault fault = NoFault; 36811965Sar4jc@virginia.edu 36911965Sar4jc@virginia.edu %(op_decl)s; 37011965Sar4jc@virginia.edu %(op_rd)s; 37111965Sar4jc@virginia.edu %(ea_code)s; 37211965Sar4jc@virginia.edu 37311965Sar4jc@virginia.edu if (fault == NoFault) { 37411965Sar4jc@virginia.edu %(op_wb)s; 37511965Sar4jc@virginia.edu xc->setEA(EA); 37611965Sar4jc@virginia.edu } 37711965Sar4jc@virginia.edu 37811965Sar4jc@virginia.edu return fault; 37911965Sar4jc@virginia.edu } 38011965Sar4jc@virginia.edu}}; 38111965Sar4jc@virginia.edu 38211726Sar4jc@virginia.edudef template AtomicMemOpLoadEACompExecute {{ 38311726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sLoad::eaComp(CPU_EXEC_CONTEXT *xc, 38411726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 38511726Sar4jc@virginia.edu { 38611726Sar4jc@virginia.edu Addr EA; 38711726Sar4jc@virginia.edu Fault fault = NoFault; 38811726Sar4jc@virginia.edu 38911726Sar4jc@virginia.edu %(op_decl)s; 39011726Sar4jc@virginia.edu %(op_rd)s; 39111726Sar4jc@virginia.edu %(ea_code)s; 39211726Sar4jc@virginia.edu 39311726Sar4jc@virginia.edu if (fault == NoFault) { 39411726Sar4jc@virginia.edu %(op_wb)s; 39511726Sar4jc@virginia.edu xc->setEA(EA); 39611726Sar4jc@virginia.edu } 39711726Sar4jc@virginia.edu 39811726Sar4jc@virginia.edu return fault; 39911726Sar4jc@virginia.edu } 40011726Sar4jc@virginia.edu}}; 40111726Sar4jc@virginia.edu 40211726Sar4jc@virginia.edudef template AtomicMemOpStoreEACompExecute {{ 40311726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sStore::eaComp(CPU_EXEC_CONTEXT *xc, 40411726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 40511726Sar4jc@virginia.edu { 40611726Sar4jc@virginia.edu Addr EA; 40711726Sar4jc@virginia.edu Fault fault = NoFault; 40811726Sar4jc@virginia.edu 40911726Sar4jc@virginia.edu %(op_decl)s; 41011726Sar4jc@virginia.edu %(op_rd)s; 41111726Sar4jc@virginia.edu %(ea_code)s; 41211726Sar4jc@virginia.edu 41311726Sar4jc@virginia.edu if (fault == NoFault) { 41411726Sar4jc@virginia.edu %(op_wb)s; 41511726Sar4jc@virginia.edu xc->setEA(EA); 41611726Sar4jc@virginia.edu } 41711726Sar4jc@virginia.edu 41811726Sar4jc@virginia.edu return fault; 41911726Sar4jc@virginia.edu } 42011726Sar4jc@virginia.edu}}; 42111726Sar4jc@virginia.edu 42211965Sar4jc@virginia.edudef template LoadReservedInitiateAcc {{ 42311965Sar4jc@virginia.edu Fault 42411965Sar4jc@virginia.edu %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 42511965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 42611965Sar4jc@virginia.edu { 42711965Sar4jc@virginia.edu Addr EA; 42811965Sar4jc@virginia.edu Fault fault = NoFault; 42911965Sar4jc@virginia.edu 43011965Sar4jc@virginia.edu %(op_src_decl)s; 43111965Sar4jc@virginia.edu %(op_rd)s; 43211965Sar4jc@virginia.edu %(ea_code)s; 43311965Sar4jc@virginia.edu 43411965Sar4jc@virginia.edu if (fault == NoFault) { 43511965Sar4jc@virginia.edu fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 43611965Sar4jc@virginia.edu } 43711965Sar4jc@virginia.edu 43811965Sar4jc@virginia.edu return fault; 43911965Sar4jc@virginia.edu } 44011965Sar4jc@virginia.edu}}; 44111965Sar4jc@virginia.edu 44211965Sar4jc@virginia.edudef template StoreCondInitiateAcc {{ 44311965Sar4jc@virginia.edu Fault 44411965Sar4jc@virginia.edu %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 44511965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 44611965Sar4jc@virginia.edu { 44711965Sar4jc@virginia.edu Addr EA; 44811965Sar4jc@virginia.edu Fault fault = NoFault; 44911965Sar4jc@virginia.edu 45011965Sar4jc@virginia.edu %(op_decl)s; 45111965Sar4jc@virginia.edu %(op_rd)s; 45211965Sar4jc@virginia.edu %(ea_code)s; 45311965Sar4jc@virginia.edu 45411965Sar4jc@virginia.edu if (fault == NoFault) { 45511965Sar4jc@virginia.edu %(memacc_code)s; 45611965Sar4jc@virginia.edu } 45711965Sar4jc@virginia.edu 45811965Sar4jc@virginia.edu if (fault == NoFault) { 45911965Sar4jc@virginia.edu fault = writeMemTiming(xc, traceData, Mem, EA, 46011965Sar4jc@virginia.edu memAccessFlags, nullptr); 46111965Sar4jc@virginia.edu } 46211965Sar4jc@virginia.edu 46311965Sar4jc@virginia.edu if (fault == NoFault) { 46411965Sar4jc@virginia.edu %(op_wb)s; 46511965Sar4jc@virginia.edu } 46611965Sar4jc@virginia.edu 46711965Sar4jc@virginia.edu return fault; 46811965Sar4jc@virginia.edu } 46911965Sar4jc@virginia.edu}}; 47011965Sar4jc@virginia.edu 47111726Sar4jc@virginia.edudef template AtomicMemOpLoadInitiateAcc {{ 47211726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sLoad::initiateAcc(CPU_EXEC_CONTEXT *xc, 47311726Sar4jc@virginia.edu Trace::InstRecord *traceData) const 47411726Sar4jc@virginia.edu { 47511726Sar4jc@virginia.edu Addr EA; 47611726Sar4jc@virginia.edu Fault fault = NoFault; 47711726Sar4jc@virginia.edu 47811726Sar4jc@virginia.edu %(op_src_decl)s; 47911726Sar4jc@virginia.edu %(op_rd)s; 48011726Sar4jc@virginia.edu %(ea_code)s; 48111726Sar4jc@virginia.edu 48211726Sar4jc@virginia.edu if (fault == NoFault) { 48311726Sar4jc@virginia.edu fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 48411726Sar4jc@virginia.edu } 48511726Sar4jc@virginia.edu 48611726Sar4jc@virginia.edu return fault; 48711726Sar4jc@virginia.edu } 48811726Sar4jc@virginia.edu}}; 48911726Sar4jc@virginia.edu 49011726Sar4jc@virginia.edudef template AtomicMemOpStoreInitiateAcc {{ 49111726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sStore::initiateAcc( 49211726Sar4jc@virginia.edu CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 49311726Sar4jc@virginia.edu { 49411726Sar4jc@virginia.edu Addr EA; 49511726Sar4jc@virginia.edu Fault fault = NoFault; 49611726Sar4jc@virginia.edu 49711726Sar4jc@virginia.edu %(op_decl)s; 49811726Sar4jc@virginia.edu %(op_rd)s; 49911726Sar4jc@virginia.edu %(ea_code)s; 50011726Sar4jc@virginia.edu 50111726Sar4jc@virginia.edu if (fault == NoFault) { 50211726Sar4jc@virginia.edu %(code)s; 50311726Sar4jc@virginia.edu } 50411726Sar4jc@virginia.edu 50511726Sar4jc@virginia.edu if (fault == NoFault) { 50611726Sar4jc@virginia.edu fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 50711726Sar4jc@virginia.edu nullptr); 50811726Sar4jc@virginia.edu } 50911726Sar4jc@virginia.edu 51011726Sar4jc@virginia.edu if (fault == NoFault) { 51111726Sar4jc@virginia.edu %(op_wb)s; 51211726Sar4jc@virginia.edu } 51311726Sar4jc@virginia.edu 51411726Sar4jc@virginia.edu return fault; 51511726Sar4jc@virginia.edu } 51611726Sar4jc@virginia.edu}}; 51711726Sar4jc@virginia.edu 51811965Sar4jc@virginia.edudef template LoadReservedCompleteAcc {{ 51911965Sar4jc@virginia.edu Fault 52011965Sar4jc@virginia.edu %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc, 52111965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 52211965Sar4jc@virginia.edu { 52311965Sar4jc@virginia.edu Fault fault = NoFault; 52411965Sar4jc@virginia.edu 52511965Sar4jc@virginia.edu %(op_decl)s; 52611965Sar4jc@virginia.edu %(op_rd)s; 52711965Sar4jc@virginia.edu 52811965Sar4jc@virginia.edu getMem(pkt, Mem, traceData); 52911965Sar4jc@virginia.edu 53011965Sar4jc@virginia.edu if (fault == NoFault) { 53111965Sar4jc@virginia.edu %(memacc_code)s; 53211965Sar4jc@virginia.edu } 53311965Sar4jc@virginia.edu 53411965Sar4jc@virginia.edu if (fault == NoFault) { 53511965Sar4jc@virginia.edu %(op_wb)s; 53611965Sar4jc@virginia.edu } 53711965Sar4jc@virginia.edu 53811965Sar4jc@virginia.edu return fault; 53911965Sar4jc@virginia.edu } 54011965Sar4jc@virginia.edu}}; 54111965Sar4jc@virginia.edu 54211965Sar4jc@virginia.edudef template StoreCondCompleteAcc {{ 54311965Sar4jc@virginia.edu Fault %(class_name)s::completeAcc(Packet *pkt, CPU_EXEC_CONTEXT *xc, 54411965Sar4jc@virginia.edu Trace::InstRecord *traceData) const 54511965Sar4jc@virginia.edu { 54611965Sar4jc@virginia.edu Fault fault = NoFault; 54711965Sar4jc@virginia.edu 54811965Sar4jc@virginia.edu %(op_dest_decl)s; 54911965Sar4jc@virginia.edu 55011965Sar4jc@virginia.edu // RISC-V has the opposite convention gem5 has for success flags, 55111965Sar4jc@virginia.edu // so we invert the result here. 55211965Sar4jc@virginia.edu uint64_t result = !pkt->req->getExtraData(); 55311965Sar4jc@virginia.edu 55411965Sar4jc@virginia.edu if (fault == NoFault) { 55511965Sar4jc@virginia.edu %(postacc_code)s; 55611965Sar4jc@virginia.edu } 55711965Sar4jc@virginia.edu 55811965Sar4jc@virginia.edu if (fault == NoFault) { 55911965Sar4jc@virginia.edu %(op_wb)s; 56011965Sar4jc@virginia.edu } 56111965Sar4jc@virginia.edu 56211965Sar4jc@virginia.edu return fault; 56311965Sar4jc@virginia.edu } 56411965Sar4jc@virginia.edu}}; 56511965Sar4jc@virginia.edu 56611726Sar4jc@virginia.edudef template AtomicMemOpLoadCompleteAcc {{ 56711726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sLoad::completeAcc(PacketPtr pkt, 56811726Sar4jc@virginia.edu CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 56911726Sar4jc@virginia.edu { 57011726Sar4jc@virginia.edu Fault fault = NoFault; 57111726Sar4jc@virginia.edu 57211726Sar4jc@virginia.edu %(op_decl)s; 57311726Sar4jc@virginia.edu %(op_rd)s; 57411726Sar4jc@virginia.edu 57511726Sar4jc@virginia.edu getMem(pkt, Mem, traceData); 57611726Sar4jc@virginia.edu 57711726Sar4jc@virginia.edu if (fault == NoFault) { 57811726Sar4jc@virginia.edu %(code)s; 57911726Sar4jc@virginia.edu } 58011726Sar4jc@virginia.edu 58111726Sar4jc@virginia.edu if (fault == NoFault) { 58211726Sar4jc@virginia.edu %(op_wb)s; 58311726Sar4jc@virginia.edu } 58411726Sar4jc@virginia.edu 58511726Sar4jc@virginia.edu return fault; 58611726Sar4jc@virginia.edu } 58711726Sar4jc@virginia.edu}}; 58811726Sar4jc@virginia.edu 58911726Sar4jc@virginia.edudef template AtomicMemOpStoreCompleteAcc {{ 59011726Sar4jc@virginia.edu Fault %(class_name)s::%(class_name)sStore::completeAcc(PacketPtr pkt, 59111726Sar4jc@virginia.edu CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 59211726Sar4jc@virginia.edu { 59311726Sar4jc@virginia.edu return NoFault; 59411726Sar4jc@virginia.edu } 59511726Sar4jc@virginia.edu}}; 59611726Sar4jc@virginia.edu 59711965Sar4jc@virginia.edudef format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 59811965Sar4jc@virginia.edu mem_flags=[], inst_flags=[]) {{ 59911965Sar4jc@virginia.edu mem_flags = makeList(mem_flags) 60011965Sar4jc@virginia.edu inst_flags = makeList(inst_flags) 60111965Sar4jc@virginia.edu iop = InstObjParams(name, Name, 'LoadReserved', 60211965Sar4jc@virginia.edu {'ea_code': ea_code, 'memacc_code': memacc_code, 60311965Sar4jc@virginia.edu 'postacc_code': postacc_code}, inst_flags) 60411965Sar4jc@virginia.edu iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 60511965Sar4jc@virginia.edu '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 60611965Sar4jc@virginia.edu 60711965Sar4jc@virginia.edu header_output = LRSCDeclare.subst(iop) 60811965Sar4jc@virginia.edu decoder_output = LRSCConstructor.subst(iop) 60911965Sar4jc@virginia.edu decode_block = BasicDecode.subst(iop) 61011965Sar4jc@virginia.edu exec_output = LoadReservedExecute.subst(iop) \ 61111965Sar4jc@virginia.edu + LRSCEACompExecute.subst(iop) \ 61211965Sar4jc@virginia.edu + LoadReservedInitiateAcc.subst(iop) \ 61311965Sar4jc@virginia.edu + LoadReservedCompleteAcc.subst(iop) 61411965Sar4jc@virginia.edu}}; 61511965Sar4jc@virginia.edu 61611965Sar4jc@virginia.edudef format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}}, 61711965Sar4jc@virginia.edu mem_flags=[], inst_flags=[]) {{ 61811965Sar4jc@virginia.edu mem_flags = makeList(mem_flags) 61911965Sar4jc@virginia.edu inst_flags = makeList(inst_flags) 62011965Sar4jc@virginia.edu iop = InstObjParams(name, Name, 'StoreCond', 62111965Sar4jc@virginia.edu {'ea_code': ea_code, 'memacc_code': memacc_code, 62211965Sar4jc@virginia.edu 'postacc_code': postacc_code}, inst_flags) 62311965Sar4jc@virginia.edu iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \ 62411965Sar4jc@virginia.edu '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';' 62511965Sar4jc@virginia.edu 62611965Sar4jc@virginia.edu header_output = LRSCDeclare.subst(iop) 62711965Sar4jc@virginia.edu decoder_output = LRSCConstructor.subst(iop) 62811965Sar4jc@virginia.edu decode_block = BasicDecode.subst(iop) 62911965Sar4jc@virginia.edu exec_output = StoreCondExecute.subst(iop) \ 63011965Sar4jc@virginia.edu + LRSCEACompExecute.subst(iop) \ 63111965Sar4jc@virginia.edu + StoreCondInitiateAcc.subst(iop) \ 63211965Sar4jc@virginia.edu + StoreCondCompleteAcc.subst(iop) 63311965Sar4jc@virginia.edu}}; 63411965Sar4jc@virginia.edu 63511726Sar4jc@virginia.edudef format AtomicMemOp(load_code, store_code, ea_code, load_flags=[], 63611726Sar4jc@virginia.edu store_flags=[], inst_flags=[]) {{ 63711726Sar4jc@virginia.edu macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags) 63811726Sar4jc@virginia.edu header_output = AtomicMemOpDeclare.subst(macro_iop) 63911726Sar4jc@virginia.edu decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop) 64011726Sar4jc@virginia.edu decode_block = AtomicMemOpMacroDecode.subst(macro_iop) 64111726Sar4jc@virginia.edu exec_output = '' 64211726Sar4jc@virginia.edu 64311726Sar4jc@virginia.edu load_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsLoad"] 64411726Sar4jc@virginia.edu load_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 64511726Sar4jc@virginia.edu {'ea_code': ea_code, 'code': load_code}, load_inst_flags) 64611726Sar4jc@virginia.edu decoder_output += AtomicMemOpLoadConstructor.subst(load_iop) 64711726Sar4jc@virginia.edu exec_output += AtomicMemOpLoadExecute.subst(load_iop) \ 64811726Sar4jc@virginia.edu + AtomicMemOpLoadEACompExecute.subst(load_iop) \ 64911726Sar4jc@virginia.edu + AtomicMemOpLoadInitiateAcc.subst(load_iop) \ 65011726Sar4jc@virginia.edu + AtomicMemOpLoadCompleteAcc.subst(load_iop) 65111726Sar4jc@virginia.edu 65211726Sar4jc@virginia.edu store_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsStore"] 65311726Sar4jc@virginia.edu store_iop = InstObjParams(name, Name, 'AtomicMemOpMicro', 65411726Sar4jc@virginia.edu {'ea_code': ea_code, 'code': store_code}, store_inst_flags) 65511726Sar4jc@virginia.edu decoder_output += AtomicMemOpStoreConstructor.subst(store_iop) 65611726Sar4jc@virginia.edu exec_output += AtomicMemOpStoreExecute.subst(store_iop) \ 65711726Sar4jc@virginia.edu + AtomicMemOpStoreEACompExecute.subst(store_iop) \ 65811726Sar4jc@virginia.edu + AtomicMemOpStoreInitiateAcc.subst(store_iop) \ 65911726Sar4jc@virginia.edu + AtomicMemOpStoreCompleteAcc.subst(store_iop) 66011726Sar4jc@virginia.edu}}; 661