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