amo.isa revision 12482
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.edudef template AtomicMemOpDeclare {{
3711726Sar4jc@virginia.edu    /**
3811726Sar4jc@virginia.edu     * Static instruction class for an AtomicMemOp operation
3911726Sar4jc@virginia.edu     */
4011726Sar4jc@virginia.edu    class %(class_name)s : public %(base_class)s
4111726Sar4jc@virginia.edu    {
4211726Sar4jc@virginia.edu      public:
4311726Sar4jc@virginia.edu        // Constructor
4411726Sar4jc@virginia.edu        %(class_name)s(ExtMachInst machInst);
4511726Sar4jc@virginia.edu
4611726Sar4jc@virginia.edu    protected:
4711726Sar4jc@virginia.edu
4811726Sar4jc@virginia.edu        class %(class_name)sLoad : public %(base_class)sMicro
4911726Sar4jc@virginia.edu        {
5011726Sar4jc@virginia.edu          public:
5111726Sar4jc@virginia.edu            // Constructor
5211726Sar4jc@virginia.edu            %(class_name)sLoad(ExtMachInst machInst, %(class_name)s *_p);
5311726Sar4jc@virginia.edu
5412482Sgabeblack@google.com            Fault execute(ExecContext *, Trace::InstRecord *) const override;
5512482Sgabeblack@google.com            Fault initiateAcc(ExecContext *,
5612482Sgabeblack@google.com                              Trace::InstRecord *) const override;
5712236Sgabeblack@google.com            Fault completeAcc(PacketPtr, ExecContext *,
5812482Sgabeblack@google.com                              Trace::InstRecord *) const override;
5911726Sar4jc@virginia.edu        };
6011726Sar4jc@virginia.edu
6111726Sar4jc@virginia.edu        class %(class_name)sStore : public %(base_class)sMicro
6211726Sar4jc@virginia.edu        {
6311726Sar4jc@virginia.edu          public:
6411726Sar4jc@virginia.edu            // Constructor
6511726Sar4jc@virginia.edu            %(class_name)sStore(ExtMachInst machInst, %(class_name)s *_p);
6611726Sar4jc@virginia.edu
6712482Sgabeblack@google.com            Fault execute(ExecContext *, Trace::InstRecord *) const override;
6812482Sgabeblack@google.com            Fault initiateAcc(ExecContext *,
6912482Sgabeblack@google.com                              Trace::InstRecord *) const override;
7012236Sgabeblack@google.com            Fault completeAcc(PacketPtr, ExecContext *,
7112482Sgabeblack@google.com                              Trace::InstRecord *) const override;
7211726Sar4jc@virginia.edu        };
7311726Sar4jc@virginia.edu    };
7411726Sar4jc@virginia.edu}};
7511726Sar4jc@virginia.edu
7611965Sar4jc@virginia.edudef template LRSCConstructor {{
7711965Sar4jc@virginia.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst):
7811965Sar4jc@virginia.edu        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
7911965Sar4jc@virginia.edu    {
8011965Sar4jc@virginia.edu        %(constructor)s;
8111965Sar4jc@virginia.edu        if (AQ)
8211965Sar4jc@virginia.edu            memAccessFlags = memAccessFlags | Request::ACQUIRE;
8311965Sar4jc@virginia.edu        if (RL)
8411965Sar4jc@virginia.edu            memAccessFlags = memAccessFlags | Request::RELEASE;
8511965Sar4jc@virginia.edu    }
8611965Sar4jc@virginia.edu}};
8711965Sar4jc@virginia.edu
8811726Sar4jc@virginia.edudef template AtomicMemOpMacroConstructor {{
8911726Sar4jc@virginia.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst)
9011726Sar4jc@virginia.edu            : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
9111726Sar4jc@virginia.edu    {
9211726Sar4jc@virginia.edu        %(constructor)s;
9311726Sar4jc@virginia.edu        microops = {new %(class_name)sLoad(machInst, this),
9411726Sar4jc@virginia.edu            new %(class_name)sStore(machInst, this)};
9511726Sar4jc@virginia.edu    }
9611726Sar4jc@virginia.edu}};
9711726Sar4jc@virginia.edu
9811726Sar4jc@virginia.edudef template AtomicMemOpLoadConstructor {{
9911726Sar4jc@virginia.edu    %(class_name)s::%(class_name)sLoad::%(class_name)sLoad(
10011726Sar4jc@virginia.edu        ExtMachInst machInst, %(class_name)s *_p)
10111726Sar4jc@virginia.edu            : %(base_class)s("%(mnemonic)s[l]", machInst, %(op_class)s)
10211726Sar4jc@virginia.edu    {
10311726Sar4jc@virginia.edu        %(constructor)s;
10411726Sar4jc@virginia.edu        flags[IsFirstMicroop] = true;
10511726Sar4jc@virginia.edu        flags[IsDelayedCommit] = true;
10611726Sar4jc@virginia.edu        if (AQ)
10711726Sar4jc@virginia.edu            memAccessFlags = Request::ACQUIRE;
10811726Sar4jc@virginia.edu    }
10911726Sar4jc@virginia.edu}};
11011726Sar4jc@virginia.edu
11111726Sar4jc@virginia.edudef template AtomicMemOpStoreConstructor {{
11211726Sar4jc@virginia.edu    %(class_name)s::%(class_name)sStore::%(class_name)sStore(
11311726Sar4jc@virginia.edu        ExtMachInst machInst, %(class_name)s *_p)
11411726Sar4jc@virginia.edu            : %(base_class)s("%(mnemonic)s[s]", machInst, %(op_class)s)
11511726Sar4jc@virginia.edu    {
11611726Sar4jc@virginia.edu        %(constructor)s;
11711726Sar4jc@virginia.edu        flags[IsLastMicroop] = true;
11811726Sar4jc@virginia.edu        flags[IsNonSpeculative] = true;
11911726Sar4jc@virginia.edu        if (RL)
12011726Sar4jc@virginia.edu            memAccessFlags = Request::RELEASE;
12111726Sar4jc@virginia.edu    }
12211726Sar4jc@virginia.edu}};
12311726Sar4jc@virginia.edu
12411965Sar4jc@virginia.edudef template StoreCondExecute {{
12512234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext *xc,
12611965Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
12711965Sar4jc@virginia.edu    {
12811965Sar4jc@virginia.edu        Addr EA;
12911965Sar4jc@virginia.edu        Fault fault = NoFault;
13011965Sar4jc@virginia.edu        uint64_t result;
13111965Sar4jc@virginia.edu
13211965Sar4jc@virginia.edu        %(op_decl)s;
13311965Sar4jc@virginia.edu        %(op_rd)s;
13411965Sar4jc@virginia.edu        %(ea_code)s;
13511965Sar4jc@virginia.edu
13611965Sar4jc@virginia.edu        if (fault == NoFault) {
13711965Sar4jc@virginia.edu            %(memacc_code)s;
13811965Sar4jc@virginia.edu        }
13911965Sar4jc@virginia.edu
14011965Sar4jc@virginia.edu        if (fault == NoFault) {
14111965Sar4jc@virginia.edu            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
14211965Sar4jc@virginia.edu                &result);
14311965Sar4jc@virginia.edu            // RISC-V has the opposite convention gem5 has for success flags,
14411965Sar4jc@virginia.edu            // so we invert the result here.
14511965Sar4jc@virginia.edu            result = !result;
14611965Sar4jc@virginia.edu        }
14711965Sar4jc@virginia.edu
14811965Sar4jc@virginia.edu        if (fault == NoFault) {
14911965Sar4jc@virginia.edu            %(postacc_code)s;
15011965Sar4jc@virginia.edu        }
15111965Sar4jc@virginia.edu
15211965Sar4jc@virginia.edu        if (fault == NoFault) {
15311965Sar4jc@virginia.edu            %(op_wb)s;
15411965Sar4jc@virginia.edu        }
15511965Sar4jc@virginia.edu
15611965Sar4jc@virginia.edu        return fault;
15711965Sar4jc@virginia.edu    }
15811965Sar4jc@virginia.edu}};
15911965Sar4jc@virginia.edu
16011726Sar4jc@virginia.edudef template AtomicMemOpLoadExecute {{
16112234Sgabeblack@google.com    Fault %(class_name)s::%(class_name)sLoad::execute(ExecContext *xc,
16211726Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
16311726Sar4jc@virginia.edu    {
16411726Sar4jc@virginia.edu        Addr EA;
16511726Sar4jc@virginia.edu        Fault fault = NoFault;
16611726Sar4jc@virginia.edu
16711726Sar4jc@virginia.edu        %(op_decl)s;
16811726Sar4jc@virginia.edu        %(op_rd)s;
16911726Sar4jc@virginia.edu        %(ea_code)s;
17011726Sar4jc@virginia.edu
17111726Sar4jc@virginia.edu        if (fault == NoFault) {
17211726Sar4jc@virginia.edu            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
17311726Sar4jc@virginia.edu        }
17411726Sar4jc@virginia.edu
17511726Sar4jc@virginia.edu        if (fault == NoFault) {
17611726Sar4jc@virginia.edu            %(code)s;
17711726Sar4jc@virginia.edu        }
17811726Sar4jc@virginia.edu
17911726Sar4jc@virginia.edu        if (fault == NoFault) {
18011726Sar4jc@virginia.edu            %(op_wb)s;
18111726Sar4jc@virginia.edu        }
18211726Sar4jc@virginia.edu
18311726Sar4jc@virginia.edu        return fault;
18411726Sar4jc@virginia.edu    }
18511726Sar4jc@virginia.edu}};
18611726Sar4jc@virginia.edu
18711726Sar4jc@virginia.edudef template AtomicMemOpStoreExecute {{
18812234Sgabeblack@google.com    Fault %(class_name)s::%(class_name)sStore::execute(ExecContext *xc,
18911726Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
19011726Sar4jc@virginia.edu    {
19111726Sar4jc@virginia.edu        Addr EA;
19211726Sar4jc@virginia.edu        Fault fault = NoFault;
19311726Sar4jc@virginia.edu
19411726Sar4jc@virginia.edu        %(op_decl)s;
19511726Sar4jc@virginia.edu        %(op_rd)s;
19611726Sar4jc@virginia.edu        %(ea_code)s;
19711726Sar4jc@virginia.edu
19811726Sar4jc@virginia.edu        if (fault == NoFault) {
19911726Sar4jc@virginia.edu            %(code)s;
20011726Sar4jc@virginia.edu        }
20111726Sar4jc@virginia.edu
20211726Sar4jc@virginia.edu        if (fault == NoFault) {
20311726Sar4jc@virginia.edu            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
20411726Sar4jc@virginia.edu                nullptr);
20511726Sar4jc@virginia.edu        }
20611726Sar4jc@virginia.edu
20711726Sar4jc@virginia.edu        if (fault == NoFault) {
20811726Sar4jc@virginia.edu            %(op_wb)s;
20911726Sar4jc@virginia.edu        }
21011726Sar4jc@virginia.edu
21111726Sar4jc@virginia.edu        return fault;
21211726Sar4jc@virginia.edu    }
21311726Sar4jc@virginia.edu}};
21411726Sar4jc@virginia.edu
21511726Sar4jc@virginia.edudef template AtomicMemOpLoadInitiateAcc {{
21612234Sgabeblack@google.com    Fault %(class_name)s::%(class_name)sLoad::initiateAcc(ExecContext *xc,
21711726Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
21811726Sar4jc@virginia.edu    {
21911726Sar4jc@virginia.edu        Addr EA;
22011726Sar4jc@virginia.edu        Fault fault = NoFault;
22111726Sar4jc@virginia.edu
22211726Sar4jc@virginia.edu        %(op_src_decl)s;
22311726Sar4jc@virginia.edu        %(op_rd)s;
22411726Sar4jc@virginia.edu        %(ea_code)s;
22511726Sar4jc@virginia.edu
22611726Sar4jc@virginia.edu        if (fault == NoFault) {
22711726Sar4jc@virginia.edu            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
22811726Sar4jc@virginia.edu        }
22911726Sar4jc@virginia.edu
23011726Sar4jc@virginia.edu        return fault;
23111726Sar4jc@virginia.edu    }
23211726Sar4jc@virginia.edu}};
23311726Sar4jc@virginia.edu
23411726Sar4jc@virginia.edudef template AtomicMemOpStoreInitiateAcc {{
23511726Sar4jc@virginia.edu    Fault %(class_name)s::%(class_name)sStore::initiateAcc(
23612234Sgabeblack@google.com        ExecContext *xc, Trace::InstRecord *traceData) const
23711726Sar4jc@virginia.edu    {
23811726Sar4jc@virginia.edu        Addr EA;
23911726Sar4jc@virginia.edu        Fault fault = NoFault;
24011726Sar4jc@virginia.edu
24111726Sar4jc@virginia.edu        %(op_decl)s;
24211726Sar4jc@virginia.edu        %(op_rd)s;
24311726Sar4jc@virginia.edu        %(ea_code)s;
24411726Sar4jc@virginia.edu
24511726Sar4jc@virginia.edu        if (fault == NoFault) {
24611726Sar4jc@virginia.edu            %(code)s;
24711726Sar4jc@virginia.edu        }
24811726Sar4jc@virginia.edu
24911726Sar4jc@virginia.edu        if (fault == NoFault) {
25011726Sar4jc@virginia.edu            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
25111726Sar4jc@virginia.edu                nullptr);
25211726Sar4jc@virginia.edu        }
25311726Sar4jc@virginia.edu
25411726Sar4jc@virginia.edu        if (fault == NoFault) {
25511726Sar4jc@virginia.edu            %(op_wb)s;
25611726Sar4jc@virginia.edu        }
25711726Sar4jc@virginia.edu
25811726Sar4jc@virginia.edu        return fault;
25911726Sar4jc@virginia.edu    }
26011726Sar4jc@virginia.edu}};
26111726Sar4jc@virginia.edu
26211965Sar4jc@virginia.edudef template StoreCondCompleteAcc {{
26312234Sgabeblack@google.com    Fault %(class_name)s::completeAcc(Packet *pkt, ExecContext *xc,
26411965Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
26511965Sar4jc@virginia.edu    {
26611965Sar4jc@virginia.edu        Fault fault = NoFault;
26711965Sar4jc@virginia.edu
26811965Sar4jc@virginia.edu        %(op_dest_decl)s;
26911965Sar4jc@virginia.edu
27011965Sar4jc@virginia.edu        // RISC-V has the opposite convention gem5 has for success flags,
27111965Sar4jc@virginia.edu        // so we invert the result here.
27211965Sar4jc@virginia.edu        uint64_t result = !pkt->req->getExtraData();
27311965Sar4jc@virginia.edu
27411965Sar4jc@virginia.edu        if (fault == NoFault) {
27511965Sar4jc@virginia.edu            %(postacc_code)s;
27611965Sar4jc@virginia.edu        }
27711965Sar4jc@virginia.edu
27811965Sar4jc@virginia.edu        if (fault == NoFault) {
27911965Sar4jc@virginia.edu            %(op_wb)s;
28011965Sar4jc@virginia.edu        }
28111965Sar4jc@virginia.edu
28211965Sar4jc@virginia.edu        return fault;
28311965Sar4jc@virginia.edu    }
28411965Sar4jc@virginia.edu}};
28511965Sar4jc@virginia.edu
28611726Sar4jc@virginia.edudef template AtomicMemOpLoadCompleteAcc {{
28711726Sar4jc@virginia.edu    Fault %(class_name)s::%(class_name)sLoad::completeAcc(PacketPtr pkt,
28812234Sgabeblack@google.com        ExecContext *xc, Trace::InstRecord *traceData) const
28911726Sar4jc@virginia.edu    {
29011726Sar4jc@virginia.edu        Fault fault = NoFault;
29111726Sar4jc@virginia.edu
29211726Sar4jc@virginia.edu        %(op_decl)s;
29311726Sar4jc@virginia.edu        %(op_rd)s;
29411726Sar4jc@virginia.edu
29511726Sar4jc@virginia.edu        getMem(pkt, Mem, traceData);
29611726Sar4jc@virginia.edu
29711726Sar4jc@virginia.edu        if (fault == NoFault) {
29811726Sar4jc@virginia.edu            %(code)s;
29911726Sar4jc@virginia.edu        }
30011726Sar4jc@virginia.edu
30111726Sar4jc@virginia.edu        if (fault == NoFault) {
30211726Sar4jc@virginia.edu            %(op_wb)s;
30311726Sar4jc@virginia.edu        }
30411726Sar4jc@virginia.edu
30511726Sar4jc@virginia.edu        return fault;
30611726Sar4jc@virginia.edu    }
30711726Sar4jc@virginia.edu}};
30811726Sar4jc@virginia.edu
30911726Sar4jc@virginia.edudef template AtomicMemOpStoreCompleteAcc {{
31011726Sar4jc@virginia.edu    Fault %(class_name)s::%(class_name)sStore::completeAcc(PacketPtr pkt,
31112234Sgabeblack@google.com        ExecContext *xc, Trace::InstRecord *traceData) const
31211726Sar4jc@virginia.edu    {
31311726Sar4jc@virginia.edu        return NoFault;
31411726Sar4jc@virginia.edu    }
31511726Sar4jc@virginia.edu}};
31611726Sar4jc@virginia.edu
31711965Sar4jc@virginia.edudef format LoadReserved(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}},
31811965Sar4jc@virginia.edu        mem_flags=[], inst_flags=[]) {{
31911965Sar4jc@virginia.edu    mem_flags = makeList(mem_flags)
32011965Sar4jc@virginia.edu    inst_flags = makeList(inst_flags)
32111965Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'LoadReserved',
32211965Sar4jc@virginia.edu        {'ea_code': ea_code, 'memacc_code': memacc_code,
32311965Sar4jc@virginia.edu        'postacc_code': postacc_code}, inst_flags)
32411965Sar4jc@virginia.edu    iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \
32511965Sar4jc@virginia.edu        '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';'
32611965Sar4jc@virginia.edu
32712119Sar4jc@virginia.edu    header_output = LoadStoreDeclare.subst(iop)
32811965Sar4jc@virginia.edu    decoder_output = LRSCConstructor.subst(iop)
32911965Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
33012119Sar4jc@virginia.edu    exec_output = LoadExecute.subst(iop) \
33112119Sar4jc@virginia.edu        + LoadInitiateAcc.subst(iop) \
33212119Sar4jc@virginia.edu        + LoadCompleteAcc.subst(iop)
33311965Sar4jc@virginia.edu}};
33411965Sar4jc@virginia.edu
33511965Sar4jc@virginia.edudef format StoreCond(memacc_code, postacc_code={{ }}, ea_code={{EA = Rs1;}},
33611965Sar4jc@virginia.edu        mem_flags=[], inst_flags=[]) {{
33711965Sar4jc@virginia.edu    mem_flags = makeList(mem_flags)
33811965Sar4jc@virginia.edu    inst_flags = makeList(inst_flags)
33911965Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'StoreCond',
34011965Sar4jc@virginia.edu        {'ea_code': ea_code, 'memacc_code': memacc_code,
34111965Sar4jc@virginia.edu        'postacc_code': postacc_code}, inst_flags)
34211965Sar4jc@virginia.edu    iop.constructor += '\n\tmemAccessFlags = memAccessFlags | ' + \
34311965Sar4jc@virginia.edu        '|'.join(['Request::%s' % flag for flag in mem_flags]) + ';'
34411965Sar4jc@virginia.edu
34512119Sar4jc@virginia.edu    header_output = LoadStoreDeclare.subst(iop)
34611965Sar4jc@virginia.edu    decoder_output = LRSCConstructor.subst(iop)
34711965Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
34811965Sar4jc@virginia.edu    exec_output = StoreCondExecute.subst(iop) \
34912119Sar4jc@virginia.edu        + StoreInitiateAcc.subst(iop) \
35011965Sar4jc@virginia.edu        + StoreCondCompleteAcc.subst(iop)
35111965Sar4jc@virginia.edu}};
35211965Sar4jc@virginia.edu
35311726Sar4jc@virginia.edudef format AtomicMemOp(load_code, store_code, ea_code, load_flags=[],
35411726Sar4jc@virginia.edu        store_flags=[], inst_flags=[]) {{
35511726Sar4jc@virginia.edu    macro_iop = InstObjParams(name, Name, 'AtomicMemOp', ea_code, inst_flags)
35611726Sar4jc@virginia.edu    header_output = AtomicMemOpDeclare.subst(macro_iop)
35711726Sar4jc@virginia.edu    decoder_output = AtomicMemOpMacroConstructor.subst(macro_iop)
35812119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(macro_iop)
35911726Sar4jc@virginia.edu    exec_output = ''
36011726Sar4jc@virginia.edu
36111726Sar4jc@virginia.edu    load_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsLoad"]
36211726Sar4jc@virginia.edu    load_iop = InstObjParams(name, Name, 'AtomicMemOpMicro',
36312119Sar4jc@virginia.edu        {'ea_code': ea_code, 'code': load_code, 'op_name': 'Load'},
36412119Sar4jc@virginia.edu        load_inst_flags)
36511726Sar4jc@virginia.edu    decoder_output += AtomicMemOpLoadConstructor.subst(load_iop)
36611726Sar4jc@virginia.edu    exec_output += AtomicMemOpLoadExecute.subst(load_iop) \
36711726Sar4jc@virginia.edu        + AtomicMemOpLoadInitiateAcc.subst(load_iop) \
36811726Sar4jc@virginia.edu        + AtomicMemOpLoadCompleteAcc.subst(load_iop)
36911726Sar4jc@virginia.edu
37011726Sar4jc@virginia.edu    store_inst_flags = makeList(inst_flags) + ["IsMemRef", "IsStore"]
37111726Sar4jc@virginia.edu    store_iop = InstObjParams(name, Name, 'AtomicMemOpMicro',
37212119Sar4jc@virginia.edu        {'ea_code': ea_code, 'code': store_code, 'op_name': 'Store'},
37312119Sar4jc@virginia.edu        store_inst_flags)
37411726Sar4jc@virginia.edu    decoder_output += AtomicMemOpStoreConstructor.subst(store_iop)
37511726Sar4jc@virginia.edu    exec_output += AtomicMemOpStoreExecute.subst(store_iop) \
37611726Sar4jc@virginia.edu        + AtomicMemOpStoreInitiateAcc.subst(store_iop) \
37711726Sar4jc@virginia.edu        + AtomicMemOpStoreCompleteAcc.subst(store_iop)
37811726Sar4jc@virginia.edu}};
379