mem.isa revision 12616
12686Sksewell@umich.edu// -*- mode:c++ -*-
22100SN/A
35254Sksewell@umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
45254Sksewell@umich.edu// All rights reserved.
55254Sksewell@umich.edu//
65254Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
75254Sksewell@umich.edu// modification, are permitted provided that the following conditions are
85254Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
95254Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
105254Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
115254Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
125254Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
135254Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
145254Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
155254Sksewell@umich.edu// this software without specific prior written permission.
165254Sksewell@umich.edu//
175254Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185254Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195254Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205254Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215254Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225254Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235254Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245254Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255254Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265254Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275254Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285254Sksewell@umich.edu//
295254Sksewell@umich.edu// Authors: Steve Reinhardt
305254Sksewell@umich.edu//          Kevin Lim
315254Sksewell@umich.edu
322706Sksewell@umich.edu////////////////////////////////////////////////////////////////////
332022SN/A//
342022SN/A// Memory-format instructions: LoadAddress, Load, Store
352043SN/A//
362024SN/A
372024SN/Aoutput header {{
382043SN/A    /**
392686Sksewell@umich.edu     * Base class for general Alpha memory-format instructions.
404661Sksewell@umich.edu     */
412022SN/A    class Memory : public AlphaStaticInst
422083SN/A    {
432686Sksewell@umich.edu      protected:
442101SN/A
452043SN/A        /// Memory request flags.  See mem_req_base.hh.
462043SN/A        Request::Flags memAccessFlags;
472101SN/A
482101SN/A        /// Constructor
496384Sgblack@eecs.umich.edu        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
506384Sgblack@eecs.umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass)
516384Sgblack@eecs.umich.edu        {
526384Sgblack@eecs.umich.edu        }
536384Sgblack@eecs.umich.edu
546384Sgblack@eecs.umich.edu        std::string generateDisassembly(
552101SN/A                Addr pc, const SymbolTable *symtab) const override;
562101SN/A    };
572101SN/A
582046SN/A    /**
592686Sksewell@umich.edu     * Base class for memory-format instructions using a 32-bit
602686Sksewell@umich.edu     * displacement (i.e. most of them).
612686Sksewell@umich.edu     */
622470SN/A    class MemoryDisp32 : public Memory
632686Sksewell@umich.edu    {
644661Sksewell@umich.edu      protected:
655222Sksewell@umich.edu        /// Displacement for EA calculation (signed).
665222Sksewell@umich.edu        int32_t disp;
672686Sksewell@umich.edu
6813389Sgabeblack@google.com        /// Constructor.
692470SN/A        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
702241SN/A            : Memory(mnem, _machInst, __opClass),
712101SN/A              disp(MEMDISP)
722495SN/A        {
732495SN/A        }
7413389Sgabeblack@google.com    };
752101SN/A
766384Sgblack@eecs.umich.edu
776384Sgblack@eecs.umich.edu    /**
786384Sgblack@eecs.umich.edu     * Base class for a few miscellaneous memory-format insts
7913389Sgabeblack@google.com     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
806384Sgblack@eecs.umich.edu     * None of these instructions has a destination register either.
812495SN/A     */
822101SN/A    class MemoryNoDisp : public Memory
832101SN/A    {
842495SN/A      protected:
852495SN/A        /// Constructor
862495SN/A        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
872495SN/A            : Memory(mnem, _machInst, __opClass)
882495SN/A        {
892495SN/A        }
902495SN/A
912495SN/A        std::string generateDisassembly(
922495SN/A                Addr pc, const SymbolTable *symtab) const override;
932495SN/A    };
942495SN/A}};
952495SN/A
962495SN/A
972101SN/Aoutput decoder {{
9813389Sgabeblack@google.com    std::string
992101SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1002101SN/A    {
10113389Sgabeblack@google.com        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1022101SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1036384Sgblack@eecs.umich.edu    }
1046384Sgblack@eecs.umich.edu
1056384Sgblack@eecs.umich.edu    std::string
10613389Sgabeblack@google.com    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1076384Sgblack@eecs.umich.edu    {
1082101SN/A        return csprintf("%-10s (r%d)", mnemonic, RB);
1092101SN/A    }
1102495SN/A}};
1112495SN/A
1122495SN/Adef format LoadAddress(code) {{
1132495SN/A    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1142495SN/A    header_output = BasicDeclare.subst(iop)
1156384Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
1166384Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
1176384Sgblack@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
1186384Sgblack@eecs.umich.edu}};
1196384Sgblack@eecs.umich.edu
1202495SN/A
1216384Sgblack@eecs.umich.edudef template LoadStoreDeclare {{
1222495SN/A    /**
1232495SN/A     * Static instruction class for "%(mnemonic)s".
1242043SN/A     */
1252043SN/A    class %(class_name)s : public %(base_class)s
1262025SN/A    {
1272043SN/A      public:
1282686Sksewell@umich.edu
1292686Sksewell@umich.edu        /// Constructor.
1302123SN/A        %(class_name)s(ExtMachInst machInst);
1312101SN/A
1326376Sgblack@eecs.umich.edu        Fault execute(ExecContext *, Trace::InstRecord *) const override;
1336376Sgblack@eecs.umich.edu        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
1346376Sgblack@eecs.umich.edu        Fault completeAcc(PacketPtr, ExecContext *,
1357792Sgblack@eecs.umich.edu                          Trace::InstRecord *) const override;
1366376Sgblack@eecs.umich.edu    };
1376376Sgblack@eecs.umich.edu}};
1386376Sgblack@eecs.umich.edu
1396376Sgblack@eecs.umich.edudef template LoadStoreConstructor {{
1406376Sgblack@eecs.umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst)
1416376Sgblack@eecs.umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1426376Sgblack@eecs.umich.edu    {
1437792Sgblack@eecs.umich.edu        %(constructor)s;
1446376Sgblack@eecs.umich.edu    }
1456376Sgblack@eecs.umich.edu}};
1466376Sgblack@eecs.umich.edu
1476376Sgblack@eecs.umich.edu
1482101SN/Adef template LoadExecute {{
1492042SN/A    Fault %(class_name)s::execute(ExecContext *xc,
1502101SN/A                                  Trace::InstRecord *traceData) const
1517720Sgblack@eecs.umich.edu    {
1527792Sgblack@eecs.umich.edu        Addr EA;
1537792Sgblack@eecs.umich.edu        Fault fault = NoFault;
1547720Sgblack@eecs.umich.edu
1557720Sgblack@eecs.umich.edu        %(fp_enable_check)s;
1567792Sgblack@eecs.umich.edu        %(op_decl)s;
1577792Sgblack@eecs.umich.edu        %(op_rd)s;
1587720Sgblack@eecs.umich.edu        %(ea_code)s;
1592101SN/A
1602101SN/A        if (fault == NoFault) {
1612042SN/A            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
1622101SN/A            %(memacc_code)s;
1632686Sksewell@umich.edu        }
1642686Sksewell@umich.edu
1658901Sandreas.hansson@arm.com        if (fault == NoFault) {
16611877Sbrandon.potter@amd.com            %(op_wb)s;
1678564Sgblack@eecs.umich.edu        }
16810474Sandreas.hansson@arm.com
1698564Sgblack@eecs.umich.edu        return fault;
1702686Sksewell@umich.edu    }
17110474Sandreas.hansson@arm.com}};
1722101SN/A
1732083SN/A
1742043SN/Adef template LoadInitiateAcc {{
1752025SN/A    Fault %(class_name)s::initiateAcc(ExecContext *xc,
1762043SN/A                                      Trace::InstRecord *traceData) const
1776384Sgblack@eecs.umich.edu    {
1786384Sgblack@eecs.umich.edu        Addr EA;
1794661Sksewell@umich.edu        Fault fault = NoFault;
1806384Sgblack@eecs.umich.edu
1816384Sgblack@eecs.umich.edu        %(fp_enable_check)s;
1824661Sksewell@umich.edu        %(op_src_decl)s;
1832083SN/A        %(op_rd)s;
1842025SN/A        %(ea_code)s;
1852043SN/A
1864661Sksewell@umich.edu        if (fault == NoFault) {
1878588Sgblack@eecs.umich.edu            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
1888588Sgblack@eecs.umich.edu        }
1894661Sksewell@umich.edu
1904661Sksewell@umich.edu        return fault;
1912686Sksewell@umich.edu    }
1926384Sgblack@eecs.umich.edu}};
1938588Sgblack@eecs.umich.edu
1948588Sgblack@eecs.umich.edu
1958588Sgblack@eecs.umich.edudef template LoadCompleteAcc {{
1966384Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
1975222Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
1985222Sksewell@umich.edu    {
1996384Sgblack@eecs.umich.edu        Fault fault = NoFault;
2008588Sgblack@eecs.umich.edu
2018588Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2028588Sgblack@eecs.umich.edu        %(op_decl)s;
2036384Sgblack@eecs.umich.edu
2045222Sksewell@umich.edu        getMem(pkt, Mem, traceData);
2052101SN/A
2062084SN/A        if (fault == NoFault) {
2072025SN/A            %(memacc_code)s;
2082495SN/A        }
2092495SN/A
2102495SN/A        if (fault == NoFault) {
2116384Sgblack@eecs.umich.edu            %(op_wb)s;
21213389Sgabeblack@google.com        }
2138564Sgblack@eecs.umich.edu
2148738Sgblack@eecs.umich.edu        return fault;
2158564Sgblack@eecs.umich.edu    }
21610474Sandreas.hansson@arm.com}};
2176384Sgblack@eecs.umich.edu
2186384Sgblack@eecs.umich.edu
21913389Sgabeblack@google.comdef template StoreExecute {{
2205222Sksewell@umich.edu    Fault %(class_name)s::execute(ExecContext *xc,
22113389Sgabeblack@google.com                                  Trace::InstRecord *traceData) const
2228564Sgblack@eecs.umich.edu    {
2238738Sgblack@eecs.umich.edu        Addr EA;
2248564Sgblack@eecs.umich.edu        Fault fault = NoFault;
22510474Sandreas.hansson@arm.com
2266384Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2276384Sgblack@eecs.umich.edu        %(op_decl)s;
22813389Sgabeblack@google.com        %(op_rd)s;
2296384Sgblack@eecs.umich.edu        %(ea_code)s;
2306384Sgblack@eecs.umich.edu
2316384Sgblack@eecs.umich.edu        if (fault == NoFault) {
2326384Sgblack@eecs.umich.edu            %(memacc_code)s;
2332495SN/A        }
2342101SN/A
2352043SN/A        if (fault == NoFault) {
2362025SN/A            fault = writeMemAtomic(xc, traceData, Mem, EA,
2372495SN/A                    memAccessFlags, NULL);
2382495SN/A        }
2392495SN/A
24013389Sgabeblack@google.com        if (fault == NoFault) {
24113389Sgabeblack@google.com            %(postacc_code)s;
2422495SN/A        }
2432101SN/A
2442084SN/A        if (fault == NoFault) {
2452024SN/A            %(op_wb)s;
2462043SN/A        }
2472239SN/A
24813389Sgabeblack@google.com        return fault;
24913389Sgabeblack@google.com    }
2508588Sgblack@eecs.umich.edu}};
25113389Sgabeblack@google.com
2528588Sgblack@eecs.umich.edudef template StoreCondExecute {{
2538588Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(ExecContext *xc,
2542101SN/A                                  Trace::InstRecord *traceData) const
2552043SN/A    {
2562043SN/A        Addr EA;
2572025SN/A        Fault fault = NoFault;
2582043SN/A        uint64_t write_result = 0;
2592043SN/A
2602101SN/A        %(fp_enable_check)s;
2618588Sgblack@eecs.umich.edu        %(op_decl)s;
2628588Sgblack@eecs.umich.edu        %(op_rd)s;
2638588Sgblack@eecs.umich.edu        %(ea_code)s;
2648588Sgblack@eecs.umich.edu
2652101SN/A        if (fault == NoFault) {
2662043SN/A            %(memacc_code)s;
2672025SN/A        }
2682043SN/A
2695222Sksewell@umich.edu        if (fault == NoFault) {
2708588Sgblack@eecs.umich.edu            fault = writeMemAtomic(xc, traceData, Mem, EA,
2716384Sgblack@eecs.umich.edu                    memAccessFlags, &write_result);
27213389Sgabeblack@google.com        }
2736384Sgblack@eecs.umich.edu
2748588Sgblack@eecs.umich.edu        if (fault == NoFault) {
2756384Sgblack@eecs.umich.edu            %(postacc_code)s;
27613389Sgabeblack@google.com        }
2776384Sgblack@eecs.umich.edu
2788588Sgblack@eecs.umich.edu        if (fault == NoFault) {
2798588Sgblack@eecs.umich.edu            %(op_wb)s;
2802101SN/A        }
2812043SN/A
2822043SN/A        return fault;
2832043SN/A    }
2842101SN/A}};
2858588Sgblack@eecs.umich.edu
2862686Sksewell@umich.edudef template StoreInitiateAcc {{
2872686Sksewell@umich.edu    Fault %(class_name)s::initiateAcc(ExecContext *xc,
2888588Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
2892686Sksewell@umich.edu    {
2908588Sgblack@eecs.umich.edu        Addr EA;
2918588Sgblack@eecs.umich.edu        Fault fault = NoFault;
2922101SN/A
2932043SN/A        %(fp_enable_check)s;
2942043SN/A        %(op_decl)s;
2952043SN/A        %(op_rd)s;
2966384Sgblack@eecs.umich.edu        %(ea_code)s;
2976384Sgblack@eecs.umich.edu
2984661Sksewell@umich.edu        if (fault == NoFault) {
2992101SN/A            %(memacc_code)s;
3002101SN/A        }
3012101SN/A
3022043SN/A        if (fault == NoFault) {
3032043SN/A            fault = writeMemTiming(xc, traceData, Mem, EA,
3042043SN/A                    memAccessFlags, NULL);
3052123SN/A        }
3067792Sgblack@eecs.umich.edu
3077792Sgblack@eecs.umich.edu        return fault;
3087792Sgblack@eecs.umich.edu    }
3092043SN/A}};
3102043SN/A
3112100SN/A
3122686Sksewell@umich.edudef template StoreCompleteAcc {{
3132686Sksewell@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
3148588Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3152686Sksewell@umich.edu    {
3168588Sgblack@eecs.umich.edu        return NoFault;
3178588Sgblack@eecs.umich.edu    }
3188588Sgblack@eecs.umich.edu}};
3192043SN/A
3202084SN/A
3212024SN/Adef template StoreCondCompleteAcc {{
3222101SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
3232686Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
3245222Sksewell@umich.edu    {
32513389Sgabeblack@google.com        Fault fault = NoFault;
3268564Sgblack@eecs.umich.edu
3278738Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3288564Sgblack@eecs.umich.edu        %(op_dest_decl)s;
32910474Sandreas.hansson@arm.com
3306384Sgblack@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
3316384Sgblack@eecs.umich.edu
33213389Sgabeblack@google.com        if (fault == NoFault) {
33313389Sgabeblack@google.com            %(postacc_code)s;
33413389Sgabeblack@google.com        }
33513389Sgabeblack@google.com
33613389Sgabeblack@google.com        if (fault == NoFault) {
33713389Sgabeblack@google.com            %(op_wb)s;
3382495SN/A        }
3392495SN/A
3406384Sgblack@eecs.umich.edu        return fault;
3412495SN/A    }
3422084SN/A}};
3432084SN/A
3442024SN/A
3452101SN/Adef template MiscExecute {{
3462101SN/A    Fault %(class_name)s::execute(ExecContext *xc,
3472101SN/A                                  Trace::InstRecord *traceData) const
3482101SN/A    {
3496384Sgblack@eecs.umich.edu        Addr EA M5_VAR_USED;
3506384Sgblack@eecs.umich.edu        Fault fault = NoFault;
3516384Sgblack@eecs.umich.edu
3526384Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3536384Sgblack@eecs.umich.edu        %(op_decl)s;
3546384Sgblack@eecs.umich.edu        %(op_rd)s;
3556384Sgblack@eecs.umich.edu        %(ea_code)s;
3566384Sgblack@eecs.umich.edu
3576384Sgblack@eecs.umich.edu        warn_once("Prefetch instructions in Alpha do not do anything\n");
3586384Sgblack@eecs.umich.edu        if (fault == NoFault) {
3596384Sgblack@eecs.umich.edu            %(memacc_code)s;
3606384Sgblack@eecs.umich.edu        }
36111320Ssteve.reinhardt@amd.com
3626384Sgblack@eecs.umich.edu        return NoFault;
3636384Sgblack@eecs.umich.edu    }
3646384Sgblack@eecs.umich.edu}};
3656384Sgblack@eecs.umich.edu
3666384Sgblack@eecs.umich.edu// Prefetches in Alpha don't actually do anything
3676384Sgblack@eecs.umich.edu// They just build an effective address and complete
3686384Sgblack@eecs.umich.edudef template MiscInitiateAcc {{
3696384Sgblack@eecs.umich.edu    Fault %(class_name)s::initiateAcc(ExecContext *xc,
3706384Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3716384Sgblack@eecs.umich.edu    {
3726384Sgblack@eecs.umich.edu        warn("initiateAcc undefined: Misc instruction does not support split "
3736384Sgblack@eecs.umich.edu             "access method!");
3746384Sgblack@eecs.umich.edu        return NoFault;
3756384Sgblack@eecs.umich.edu    }
3766384Sgblack@eecs.umich.edu}};
3776384Sgblack@eecs.umich.edu
3786384Sgblack@eecs.umich.edu
3796384Sgblack@eecs.umich.edudef template MiscCompleteAcc {{
3806384Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
3816384Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3826384Sgblack@eecs.umich.edu    {
3836384Sgblack@eecs.umich.edu        warn("completeAcc undefined: Misc instruction does not support split "
3844661Sksewell@umich.edu             "access method!");
3856376Sgblack@eecs.umich.edu
38612104Snathanael.premillieu@arm.com        return NoFault;
38712104Snathanael.premillieu@arm.com    }
3886376Sgblack@eecs.umich.edu}};
3894661Sksewell@umich.edu
3906384Sgblack@eecs.umich.edu
39112104Snathanael.premillieu@arm.com// load instructions use Ra as dest, so check for
39212104Snathanael.premillieu@arm.com// Ra == 31 to detect nops
3936384Sgblack@eecs.umich.edudef template LoadNopCheckDecode {{
3944661Sksewell@umich.edu {
39512104Snathanael.premillieu@arm.com     AlphaStaticInst *i = new %(class_name)s(machInst);
39612104Snathanael.premillieu@arm.com     if (RA == 31) {
39712104Snathanael.premillieu@arm.com         i = makeNop(i);
39812104Snathanael.premillieu@arm.com     }
39912104Snathanael.premillieu@arm.com     return i;
40012104Snathanael.premillieu@arm.com }
40112104Snathanael.premillieu@arm.com}};
40212104Snathanael.premillieu@arm.com
40312104Snathanael.premillieu@arm.com
40412104Snathanael.premillieu@arm.com// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
40512104Snathanael.premillieu@arm.comdef template LoadPrefetchCheckDecode {{
40612104Snathanael.premillieu@arm.com {
40712104Snathanael.premillieu@arm.com     if (RA != 31) {
40812104Snathanael.premillieu@arm.com         return new %(class_name)s(machInst);
40912104Snathanael.premillieu@arm.com     }
41012104Snathanael.premillieu@arm.com     else {
41112104Snathanael.premillieu@arm.com         return new %(class_name)sPrefetch(machInst);
41212104Snathanael.premillieu@arm.com     }
41312104Snathanael.premillieu@arm.com }
41412104Snathanael.premillieu@arm.com}};
41512104Snathanael.premillieu@arm.com
41612104Snathanael.premillieu@arm.com
41712104Snathanael.premillieu@arm.comlet {{
41812104Snathanael.premillieu@arm.comdef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
41912104Snathanael.premillieu@arm.com                  postacc_code = '', base_class = 'MemoryDisp32',
42012104Snathanael.premillieu@arm.com                  decode_template = BasicDecode, exec_template_base = ''):
42112104Snathanael.premillieu@arm.com    # Make sure flags are in lists (convert to lists if not).
42212104Snathanael.premillieu@arm.com    mem_flags = makeList(mem_flags)
42312104Snathanael.premillieu@arm.com    inst_flags = makeList(inst_flags)
42412104Snathanael.premillieu@arm.com
42512104Snathanael.premillieu@arm.com    iop = InstObjParams(name, Name, base_class,
42612104Snathanael.premillieu@arm.com                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
42712104Snathanael.premillieu@arm.com                        inst_flags)
42812104Snathanael.premillieu@arm.com
42912104Snathanael.premillieu@arm.com    if mem_flags:
43012104Snathanael.premillieu@arm.com        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
43112104Snathanael.premillieu@arm.com        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
43212104Snathanael.premillieu@arm.com        iop.constructor += s
43312104Snathanael.premillieu@arm.com
43412104Snathanael.premillieu@arm.com    # select templates
43512104Snathanael.premillieu@arm.com
43612104Snathanael.premillieu@arm.com    # The InitiateAcc template is the same for StoreCond templates as the
43712104Snathanael.premillieu@arm.com    # corresponding Store template..
43812104Snathanael.premillieu@arm.com    StoreCondInitiateAcc = StoreInitiateAcc
43912104Snathanael.premillieu@arm.com
44012104Snathanael.premillieu@arm.com    fullExecTemplate = eval(exec_template_base + 'Execute')
44112104Snathanael.premillieu@arm.com    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
44212104Snathanael.premillieu@arm.com    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
44312104Snathanael.premillieu@arm.com
44412104Snathanael.premillieu@arm.com    # (header_output, decoder_output, decode_block, exec_output)
44512104Snathanael.premillieu@arm.com    return (LoadStoreDeclare.subst(iop),
44612104Snathanael.premillieu@arm.com            LoadStoreConstructor.subst(iop),
4476384Sgblack@eecs.umich.edu            decode_template.subst(iop),
4482686Sksewell@umich.edu            fullExecTemplate.subst(iop)
4494661Sksewell@umich.edu            + initiateAccTemplate.subst(iop)
45012104Snathanael.premillieu@arm.com            + completeAccTemplate.subst(iop))
45112104Snathanael.premillieu@arm.com}};
45212104Snathanael.premillieu@arm.com
4536384Sgblack@eecs.umich.edudef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
45412104Snathanael.premillieu@arm.com                     mem_flags = [], inst_flags = []) {{
45512104Snathanael.premillieu@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
45612104Snathanael.premillieu@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4576384Sgblack@eecs.umich.edu                      decode_template = LoadNopCheckDecode,
4586384Sgblack@eecs.umich.edu                      exec_template_base = 'Load')
4596384Sgblack@eecs.umich.edu}};
46012104Snathanael.premillieu@arm.com
46112104Snathanael.premillieu@arm.com
4626384Sgblack@eecs.umich.edu// Note that the flags passed in apply only to the prefetch version
4636384Sgblack@eecs.umich.edudef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
46412104Snathanael.premillieu@arm.com                          mem_flags = [], pf_flags = [], inst_flags = []) {{
46512104Snathanael.premillieu@arm.com    # declare the load instruction object and generate the decode block
4666384Sgblack@eecs.umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
4676384Sgblack@eecs.umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
4686384Sgblack@eecs.umich.edu                      decode_template = LoadPrefetchCheckDecode,
4696384Sgblack@eecs.umich.edu                      exec_template_base = 'Load')
4706384Sgblack@eecs.umich.edu
4716384Sgblack@eecs.umich.edu    # Declare the prefetch instruction object.
4726384Sgblack@eecs.umich.edu
4736384Sgblack@eecs.umich.edu    # Make sure flag args are lists so we can mess with them.
4746384Sgblack@eecs.umich.edu    mem_flags = makeList(mem_flags)
4756384Sgblack@eecs.umich.edu    pf_flags = makeList(pf_flags)
4766384Sgblack@eecs.umich.edu    inst_flags = makeList(inst_flags)
4776384Sgblack@eecs.umich.edu
4786384Sgblack@eecs.umich.edu    pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
4796384Sgblack@eecs.umich.edu    pf_inst_flags = inst_flags
4806384Sgblack@eecs.umich.edu
4816384Sgblack@eecs.umich.edu    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
4826384Sgblack@eecs.umich.edu        LoadStoreBase(name, Name + 'Prefetch', ea_code, ';',
4836384Sgblack@eecs.umich.edu                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
4846384Sgblack@eecs.umich.edu
4856384Sgblack@eecs.umich.edu    header_output += pf_header_output
4866384Sgblack@eecs.umich.edu    decoder_output += pf_decoder_output
4872101SN/A    exec_output += pf_exec_output
4886384Sgblack@eecs.umich.edu}};
4892686Sksewell@umich.edu
4902027SN/A
4916384Sgblack@eecs.umich.edudef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
4926384Sgblack@eecs.umich.edu                 mem_flags = [], inst_flags = []) {{
4934661Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
49412104Snathanael.premillieu@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
49512104Snathanael.premillieu@arm.com                      exec_template_base = 'Store')
4964661Sksewell@umich.edu}};
4974661Sksewell@umich.edu
49812104Snathanael.premillieu@arm.com
49912104Snathanael.premillieu@arm.comdef format StoreCond(memacc_code, postacc_code,
50012104Snathanael.premillieu@arm.com                     ea_code = {{ EA = Rb + disp; }},
5014661Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
50212104Snathanael.premillieu@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
50312104Snathanael.premillieu@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
50412104Snathanael.premillieu@arm.com                      postacc_code, exec_template_base = 'StoreCond')
50512104Snathanael.premillieu@arm.com}};
50612104Snathanael.premillieu@arm.com
50712104Snathanael.premillieu@arm.com
50812104Snathanael.premillieu@arm.com// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
50912104Snathanael.premillieu@arm.comdef format MiscPrefetch(ea_code, memacc_code,
51012104Snathanael.premillieu@arm.com                        mem_flags = [], inst_flags = []) {{
51112104Snathanael.premillieu@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
51212104Snathanael.premillieu@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
51312104Snathanael.premillieu@arm.com                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
51412104Snathanael.premillieu@arm.com}};
51512104Snathanael.premillieu@arm.com
51612104Snathanael.premillieu@arm.com
51712104Snathanael.premillieu@arm.com