mem.isa revision 6181
12068SN/A// -*- mode:c++ -*-
22068SN/A
32068SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
42068SN/A// All rights reserved.
52068SN/A//
62068SN/A// Redistribution and use in source and binary forms, with or without
72068SN/A// modification, are permitted provided that the following conditions are
82068SN/A// met: redistributions of source code must retain the above copyright
92068SN/A// notice, this list of conditions and the following disclaimer;
102068SN/A// redistributions in binary form must reproduce the above copyright
112068SN/A// notice, this list of conditions and the following disclaimer in the
122068SN/A// documentation and/or other materials provided with the distribution;
132068SN/A// neither the name of the copyright holders nor the names of its
142068SN/A// contributors may be used to endorse or promote products derived from
152068SN/A// this software without specific prior written permission.
162068SN/A//
172068SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182068SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192068SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202068SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212068SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222068SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232068SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242068SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252068SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262068SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272068SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292665Ssaidi@eecs.umich.edu// Authors: Steve Reinhardt
302665Ssaidi@eecs.umich.edu//          Kevin Lim
312068SN/A
322649Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
332649Ssaidi@eecs.umich.edu//
342649Ssaidi@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store
352649Ssaidi@eecs.umich.edu//
362649Ssaidi@eecs.umich.edu
372068SN/Aoutput header {{
382068SN/A    /**
392068SN/A     * Base class for general Alpha memory-format instructions.
402068SN/A     */
412068SN/A    class Memory : public AlphaStaticInst
422068SN/A    {
432068SN/A      protected:
442068SN/A
452068SN/A        /// Memory request flags.  See mem_req_base.hh.
465736Snate@binkert.org        Request::Flags memAccessFlags;
472068SN/A
482068SN/A        /// Constructor
496181Sksewell@umich.edu        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
506181Sksewell@umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass)
512068SN/A        {
522068SN/A        }
532068SN/A
542068SN/A        std::string
552068SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
562068SN/A
576181Sksewell@umich.edu       public:
586179Sksewell@umich.edu
596179Sksewell@umich.edu        Request::Flags memAccFlags() { return memAccessFlags; }
602068SN/A    };
612068SN/A
622068SN/A    /**
632068SN/A     * Base class for memory-format instructions using a 32-bit
642068SN/A     * displacement (i.e. most of them).
652068SN/A     */
662068SN/A    class MemoryDisp32 : public Memory
672068SN/A    {
682068SN/A      protected:
692068SN/A        /// Displacement for EA calculation (signed).
702068SN/A        int32_t disp;
712068SN/A
722068SN/A        /// Constructor.
736181Sksewell@umich.edu        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
746181Sksewell@umich.edu            : Memory(mnem, _machInst, __opClass),
752068SN/A              disp(MEMDISP)
762068SN/A        {
772068SN/A        }
782068SN/A    };
792068SN/A
802068SN/A
812068SN/A    /**
822068SN/A     * Base class for a few miscellaneous memory-format insts
832068SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
842068SN/A     * None of these instructions has a destination register either.
852068SN/A     */
862068SN/A    class MemoryNoDisp : public Memory
872068SN/A    {
882068SN/A      protected:
892068SN/A        /// Constructor
906181Sksewell@umich.edu        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
916181Sksewell@umich.edu            : Memory(mnem, _machInst, __opClass)
922068SN/A        {
932068SN/A        }
942068SN/A
952068SN/A        std::string
962068SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
972068SN/A    };
982068SN/A}};
992068SN/A
1002068SN/A
1012068SN/Aoutput decoder {{
1022068SN/A    std::string
1032068SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1042068SN/A    {
1052068SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1062068SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1072068SN/A    }
1082068SN/A
1092068SN/A    std::string
1102068SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1112068SN/A    {
1122068SN/A        return csprintf("%-10s (r%d)", mnemonic, RB);
1132068SN/A    }
1142068SN/A}};
1152068SN/A
1162068SN/Adef format LoadAddress(code) {{
1173953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1182068SN/A    header_output = BasicDeclare.subst(iop)
1192068SN/A    decoder_output = BasicConstructor.subst(iop)
1202068SN/A    decode_block = BasicDecode.subst(iop)
1212068SN/A    exec_output = BasicExecute.subst(iop)
1222068SN/A}};
1232068SN/A
1242068SN/A
1252068SN/Adef template LoadStoreDeclare {{
1262068SN/A    /**
1272068SN/A     * Static instruction class for "%(mnemonic)s".
1282068SN/A     */
1292068SN/A    class %(class_name)s : public %(base_class)s
1302068SN/A    {
1312068SN/A      public:
1322068SN/A
1332068SN/A        /// Constructor.
1342227SN/A        %(class_name)s(ExtMachInst machInst);
1352068SN/A
1362068SN/A        %(BasicExecDeclare)s
1372095SN/A
1386181Sksewell@umich.edu        %(EACompDeclare)s
1396181Sksewell@umich.edu
1402095SN/A        %(InitiateAccDeclare)s
1412095SN/A
1422095SN/A        %(CompleteAccDeclare)s
1436179Sksewell@umich.edu
1446179Sksewell@umich.edu        %(MemAccSizeDeclare)s
1452068SN/A    };
1462068SN/A}};
1472068SN/A
1482095SN/A
1496181Sksewell@umich.edudef template EACompDeclare {{
1506181Sksewell@umich.edu    Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1516181Sksewell@umich.edu}};
1526181Sksewell@umich.edu
1532095SN/Adef template InitiateAccDeclare {{
1542132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1552095SN/A}};
1562095SN/A
1572095SN/A
1582095SN/Adef template CompleteAccDeclare {{
1593349Sbinkertn@umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1602623SN/A                      Trace::InstRecord *) const;
1612095SN/A}};
1622095SN/A
1636179Sksewell@umich.edudef template MemAccSizeDeclare {{
1646179Sksewell@umich.edu    int memAccSize(%(CPU_exec_context)s *xc);
1656179Sksewell@umich.edu}};
1666179Sksewell@umich.edu
1676179Sksewell@umich.edudef template MiscMemAccSize {{
1686179Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
1696179Sksewell@umich.edu    {
1706179Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
1716179Sksewell@umich.edu        return 0;
1726179Sksewell@umich.edu    }
1736179Sksewell@umich.edu}};
1746179Sksewell@umich.edu
1756179Sksewell@umich.edudef template LoadStoreMemAccSize {{
1766179Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
1776179Sksewell@umich.edu    {
1786179Sksewell@umich.edu        // Return the memory access size in bytes
1796179Sksewell@umich.edu        return (%(mem_acc_size)d / 8);
1806179Sksewell@umich.edu    }
1816179Sksewell@umich.edu}};
1822095SN/A
1836181Sksewell@umich.edu
1846181Sksewell@umich.edudef template LoadStoreConstructor {{
1856181Sksewell@umich.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
1866181Sksewell@umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1872068SN/A    {
1883953Sstever@eecs.umich.edu        %(constructor)s;
1892068SN/A    }
1903953Sstever@eecs.umich.edu}};
1912068SN/A
1922068SN/Adef template EACompExecute {{
1936181Sksewell@umich.edu    Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
1946181Sksewell@umich.edu                                  Trace::InstRecord *traceData) const
1952068SN/A    {
1962068SN/A        Addr EA;
1972132SN/A        Fault fault = NoFault;
1982068SN/A
1992068SN/A        %(fp_enable_check)s;
2002068SN/A        %(op_decl)s;
2012068SN/A        %(op_rd)s;
2023953Sstever@eecs.umich.edu        %(ea_code)s;
2032068SN/A
2042090SN/A        if (fault == NoFault) {
2052068SN/A            %(op_wb)s;
2062068SN/A            xc->setEA(EA);
2072068SN/A        }
2082068SN/A
2092068SN/A        return fault;
2102068SN/A    }
2112068SN/A}};
2122068SN/A
2132068SN/A
2142069SN/Adef template LoadExecute {{
2152132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2162068SN/A                                  Trace::InstRecord *traceData) const
2172068SN/A    {
2182068SN/A        Addr EA;
2192132SN/A        Fault fault = NoFault;
2202068SN/A
2212068SN/A        %(fp_enable_check)s;
2222068SN/A        %(op_decl)s;
2232069SN/A        %(op_rd)s;
2242068SN/A        %(ea_code)s;
2252068SN/A
2262090SN/A        if (fault == NoFault) {
2272069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2282068SN/A            %(memacc_code)s;
2292068SN/A        }
2302068SN/A
2312090SN/A        if (fault == NoFault) {
2322069SN/A            %(op_wb)s;
2332069SN/A        }
2342069SN/A
2352069SN/A        return fault;
2362069SN/A    }
2372069SN/A}};
2382069SN/A
2392069SN/A
2402095SN/Adef template LoadInitiateAcc {{
2412132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2422095SN/A                                      Trace::InstRecord *traceData) const
2432095SN/A    {
2442095SN/A        Addr EA;
2452132SN/A        Fault fault = NoFault;
2462095SN/A
2472095SN/A        %(fp_enable_check)s;
2482095SN/A        %(op_src_decl)s;
2492095SN/A        %(op_rd)s;
2502095SN/A        %(ea_code)s;
2512095SN/A
2522098SN/A        if (fault == NoFault) {
2532095SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2542095SN/A        }
2552095SN/A
2562095SN/A        return fault;
2572095SN/A    }
2582095SN/A}};
2592095SN/A
2602095SN/A
2612095SN/Adef template LoadCompleteAcc {{
2623349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
2632095SN/A                                      %(CPU_exec_context)s *xc,
2642095SN/A                                      Trace::InstRecord *traceData) const
2652095SN/A    {
2662132SN/A        Fault fault = NoFault;
2672095SN/A
2682095SN/A        %(fp_enable_check)s;
2692506SN/A        %(op_decl)s;
2702095SN/A
2712623SN/A        Mem = pkt->get<typeof(Mem)>();
2722095SN/A
2732098SN/A        if (fault == NoFault) {
2742095SN/A            %(memacc_code)s;
2752095SN/A        }
2762095SN/A
2772098SN/A        if (fault == NoFault) {
2782095SN/A            %(op_wb)s;
2792095SN/A        }
2802095SN/A
2812095SN/A        return fault;
2822095SN/A    }
2832095SN/A}};
2842095SN/A
2852095SN/A
2862069SN/Adef template StoreExecute {{
2872132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2882069SN/A                                  Trace::InstRecord *traceData) const
2892069SN/A    {
2902069SN/A        Addr EA;
2912132SN/A        Fault fault = NoFault;
2924027Sstever@eecs.umich.edu
2934027Sstever@eecs.umich.edu        %(fp_enable_check)s;
2944027Sstever@eecs.umich.edu        %(op_decl)s;
2954027Sstever@eecs.umich.edu        %(op_rd)s;
2964027Sstever@eecs.umich.edu        %(ea_code)s;
2974027Sstever@eecs.umich.edu
2984027Sstever@eecs.umich.edu        if (fault == NoFault) {
2994027Sstever@eecs.umich.edu            %(memacc_code)s;
3004027Sstever@eecs.umich.edu        }
3014027Sstever@eecs.umich.edu
3024027Sstever@eecs.umich.edu        if (fault == NoFault) {
3034027Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3044027Sstever@eecs.umich.edu                              memAccessFlags, NULL);
3054027Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
3064027Sstever@eecs.umich.edu        }
3074027Sstever@eecs.umich.edu
3084027Sstever@eecs.umich.edu        if (fault == NoFault) {
3094027Sstever@eecs.umich.edu            %(postacc_code)s;
3104027Sstever@eecs.umich.edu        }
3114027Sstever@eecs.umich.edu
3124027Sstever@eecs.umich.edu        if (fault == NoFault) {
3134027Sstever@eecs.umich.edu            %(op_wb)s;
3144027Sstever@eecs.umich.edu        }
3154027Sstever@eecs.umich.edu
3164027Sstever@eecs.umich.edu        return fault;
3174027Sstever@eecs.umich.edu    }
3184027Sstever@eecs.umich.edu}};
3194027Sstever@eecs.umich.edu
3204027Sstever@eecs.umich.edudef template StoreCondExecute {{
3214027Sstever@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3224027Sstever@eecs.umich.edu                                  Trace::InstRecord *traceData) const
3234027Sstever@eecs.umich.edu    {
3244027Sstever@eecs.umich.edu        Addr EA;
3254027Sstever@eecs.umich.edu        Fault fault = NoFault;
3262069SN/A        uint64_t write_result = 0;
3272069SN/A
3282069SN/A        %(fp_enable_check)s;
3292069SN/A        %(op_decl)s;
3302069SN/A        %(op_rd)s;
3312069SN/A        %(ea_code)s;
3322069SN/A
3332090SN/A        if (fault == NoFault) {
3342069SN/A            %(memacc_code)s;
3352069SN/A        }
3362069SN/A
3372090SN/A        if (fault == NoFault) {
3382069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3392069SN/A                              memAccessFlags, &write_result);
3402069SN/A            if (traceData) { traceData->setData(Mem); }
3412069SN/A        }
3422069SN/A
3432090SN/A        if (fault == NoFault) {
3442069SN/A            %(postacc_code)s;
3452069SN/A        }
3462069SN/A
3472090SN/A        if (fault == NoFault) {
3482069SN/A            %(op_wb)s;
3492069SN/A        }
3502069SN/A
3512069SN/A        return fault;
3522069SN/A    }
3532069SN/A}};
3542069SN/A
3552095SN/Adef template StoreInitiateAcc {{
3562132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3572095SN/A                                      Trace::InstRecord *traceData) const
3582095SN/A    {
3592095SN/A        Addr EA;
3602132SN/A        Fault fault = NoFault;
3612095SN/A
3622095SN/A        %(fp_enable_check)s;
3632506SN/A        %(op_decl)s;
3642095SN/A        %(op_rd)s;
3652095SN/A        %(ea_code)s;
3662095SN/A
3672098SN/A        if (fault == NoFault) {
3682095SN/A            %(memacc_code)s;
3692095SN/A        }
3702095SN/A
3712098SN/A        if (fault == NoFault) {
3722095SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3732623SN/A                              memAccessFlags, NULL);
3742095SN/A            if (traceData) { traceData->setData(Mem); }
3752095SN/A        }
3762095SN/A
3772095SN/A        return fault;
3782095SN/A    }
3792095SN/A}};
3802095SN/A
3812095SN/A
3822095SN/Adef template StoreCompleteAcc {{
3833349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3842095SN/A                                      %(CPU_exec_context)s *xc,
3852095SN/A                                      Trace::InstRecord *traceData) const
3862095SN/A    {
3872132SN/A        Fault fault = NoFault;
3882095SN/A
3892095SN/A        %(fp_enable_check)s;
3902095SN/A        %(op_dest_decl)s;
3912095SN/A
3922623SN/A        if (fault == NoFault) {
3932623SN/A            %(postacc_code)s;
3942623SN/A        }
3952623SN/A
3962623SN/A        if (fault == NoFault) {
3972623SN/A            %(op_wb)s;
3982623SN/A        }
3992623SN/A
4002623SN/A        return fault;
4012623SN/A    }
4022623SN/A}};
4032623SN/A
4042623SN/A
4052623SN/Adef template StoreCondCompleteAcc {{
4063349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4072623SN/A                                      %(CPU_exec_context)s *xc,
4082623SN/A                                      Trace::InstRecord *traceData) const
4092623SN/A    {
4102623SN/A        Fault fault = NoFault;
4112623SN/A
4122623SN/A        %(fp_enable_check)s;
4132623SN/A        %(op_dest_decl)s;
4142623SN/A
4154040Ssaidi@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
4162095SN/A
4172098SN/A        if (fault == NoFault) {
4182095SN/A            %(postacc_code)s;
4192095SN/A        }
4202095SN/A
4212098SN/A        if (fault == NoFault) {
4222095SN/A            %(op_wb)s;
4232095SN/A        }
4242095SN/A
4252095SN/A        return fault;
4262095SN/A    }
4272095SN/A}};
4282095SN/A
4292069SN/A
4302069SN/Adef template MiscExecute {{
4312132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4322068SN/A                                  Trace::InstRecord *traceData) const
4332068SN/A    {
4342068SN/A        Addr EA;
4352132SN/A        Fault fault = NoFault;
4362068SN/A
4372068SN/A        %(fp_enable_check)s;
4382068SN/A        %(op_decl)s;
4392069SN/A        %(op_rd)s;
4402068SN/A        %(ea_code)s;
4412068SN/A
4422090SN/A        if (fault == NoFault) {
4432069SN/A            %(memacc_code)s;
4442068SN/A        }
4452068SN/A
4462090SN/A        return NoFault;
4472068SN/A    }
4482068SN/A}};
4492068SN/A
4502095SN/Adef template MiscInitiateAcc {{
4512132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4522095SN/A                                      Trace::InstRecord *traceData) const
4532095SN/A    {
4542355SN/A        warn("Misc instruction does not support split access method!");
4552098SN/A        return NoFault;
4562095SN/A    }
4572095SN/A}};
4582095SN/A
4592095SN/A
4602095SN/Adef template MiscCompleteAcc {{
4613349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4622095SN/A                                      %(CPU_exec_context)s *xc,
4632095SN/A                                      Trace::InstRecord *traceData) const
4642095SN/A    {
4652355SN/A        warn("Misc instruction does not support split access method!");
4662110SN/A
4672098SN/A        return NoFault;
4682095SN/A    }
4692095SN/A}};
4702095SN/A
4716179Sksewell@umich.edudef template MiscMemAccSize {{
4726179Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
4736179Sksewell@umich.edu    {
4746179Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
4756179Sksewell@umich.edu        return 0;
4766179Sksewell@umich.edu    }
4776179Sksewell@umich.edu}};
4786179Sksewell@umich.edu
4792068SN/A// load instructions use Ra as dest, so check for
4802068SN/A// Ra == 31 to detect nops
4812068SN/Adef template LoadNopCheckDecode {{
4822068SN/A {
4832068SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
4842068SN/A     if (RA == 31) {
4852068SN/A         i = makeNop(i);
4862068SN/A     }
4872068SN/A     return i;
4882068SN/A }
4892068SN/A}};
4902068SN/A
4912068SN/A
4922068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
4932068SN/Adef template LoadPrefetchCheckDecode {{
4942068SN/A {
4952068SN/A     if (RA != 31) {
4962068SN/A         return new %(class_name)s(machInst);
4972068SN/A     }
4982068SN/A     else {
4992068SN/A         return new %(class_name)sPrefetch(machInst);
5002068SN/A     }
5012068SN/A }
5022068SN/A}};
5032068SN/A
5042068SN/A
5052068SN/Alet {{
5062075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5072075SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
5082069SN/A                  decode_template = BasicDecode, exec_template_base = ''):
5092075SN/A    # Make sure flags are in lists (convert to lists if not).
5102075SN/A    mem_flags = makeList(mem_flags)
5112075SN/A    inst_flags = makeList(inst_flags)
5122068SN/A
5132068SN/A    # add hook to get effective addresses into execution trace output.
5142068SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5152068SN/A
5162068SN/A    # Some CPU models execute the memory operation as an atomic unit,
5172068SN/A    # while others want to separate them into an effective address
5182068SN/A    # computation and a memory access operation.  As a result, we need
5192068SN/A    # to generate three StaticInst objects.  Note that the latter two
5202068SN/A    # are nested inside the larger "atomic" one.
5212068SN/A
5223953Sstever@eecs.umich.edu    # Generate InstObjParams for each of the three objects.  Note that
5233953Sstever@eecs.umich.edu    # they differ only in the set of code objects contained (which in
5243953Sstever@eecs.umich.edu    # turn affects the object's overall operand list).
5253953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, base_class,
5263953Sstever@eecs.umich.edu                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
5273953Sstever@eecs.umich.edu                        inst_flags)
5283953Sstever@eecs.umich.edu    memacc_iop = InstObjParams(name, Name, base_class,
5293953Sstever@eecs.umich.edu                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
5303953Sstever@eecs.umich.edu                        inst_flags)
5312068SN/A
5322068SN/A    if mem_flags:
5335736Snate@binkert.org        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
5345745Snate@binkert.org        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
5352068SN/A        iop.constructor += s
5362068SN/A        memacc_iop.constructor += s
5372068SN/A
5382069SN/A    # select templates
5392623SN/A
5404027Sstever@eecs.umich.edu    # The InitiateAcc template is the same for StoreCond templates as the
5414027Sstever@eecs.umich.edu    # corresponding Store template..
5422623SN/A    StoreCondInitiateAcc = StoreInitiateAcc
5432623SN/A
5442069SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
5452095SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
5462095SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
5472069SN/A
5486179Sksewell@umich.edu    if (exec_template_base == 'Load' or exec_template_base == 'Store'):
5496179Sksewell@umich.edu      memAccSizeTemplate = eval('LoadStoreMemAccSize')
5506179Sksewell@umich.edu    else:
5516179Sksewell@umich.edu      memAccSizeTemplate = eval('MiscMemAccSize')
5526179Sksewell@umich.edu
5532068SN/A    # (header_output, decoder_output, decode_block, exec_output)
5543953Sstever@eecs.umich.edu    return (LoadStoreDeclare.subst(iop),
5556181Sksewell@umich.edu            LoadStoreConstructor.subst(iop),
5562068SN/A            decode_template.subst(iop),
5576181Sksewell@umich.edu            fullExecTemplate.subst(iop)
5586181Sksewell@umich.edu            + EACompExecute.subst(iop)
5593953Sstever@eecs.umich.edu            + initiateAccTemplate.subst(iop)
5606179Sksewell@umich.edu            + completeAccTemplate.subst(iop)
5616179Sksewell@umich.edu            + memAccSizeTemplate.subst(memacc_iop))
5622068SN/A}};
5632068SN/A
5642075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
5652075SN/A                     mem_flags = [], inst_flags = []) {{
5662068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5672075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5682069SN/A                      decode_template = LoadNopCheckDecode,
5692069SN/A                      exec_template_base = 'Load')
5702068SN/A}};
5712068SN/A
5722068SN/A
5732068SN/A// Note that the flags passed in apply only to the prefetch version
5742075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
5752075SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
5762068SN/A    # declare the load instruction object and generate the decode block
5772068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5782075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5792069SN/A                      decode_template = LoadPrefetchCheckDecode,
5802069SN/A                      exec_template_base = 'Load')
5812068SN/A
5822068SN/A    # Declare the prefetch instruction object.
5832068SN/A
5842075SN/A    # Make sure flag args are lists so we can mess with them.
5852075SN/A    mem_flags = makeList(mem_flags)
5862075SN/A    pf_flags = makeList(pf_flags)
5872075SN/A    inst_flags = makeList(inst_flags)
5882075SN/A
5892075SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
5902075SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
5912075SN/A                                  'IsDataPrefetch', 'MemReadOp']
5922068SN/A
5932068SN/A    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
5942069SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
5952069SN/A                      'xc->prefetch(EA, memAccessFlags);',
5962075SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
5972068SN/A
5982068SN/A    header_output += pf_header_output
5992068SN/A    decoder_output += pf_decoder_output
6002068SN/A    exec_output += pf_exec_output
6012068SN/A}};
6022068SN/A
6032068SN/A
6042075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
6052075SN/A                 mem_flags = [], inst_flags = []) {{
6062068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6072075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6082069SN/A                      exec_template_base = 'Store')
6092068SN/A}};
6102068SN/A
6112068SN/A
6122075SN/Adef format StoreCond(memacc_code, postacc_code,
6132075SN/A                     ea_code = {{ EA = Rb + disp; }},
6142075SN/A                     mem_flags = [], inst_flags = []) {{
6152068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6162075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6172623SN/A                      postacc_code, exec_template_base = 'StoreCond')
6182068SN/A}};
6192068SN/A
6202068SN/A
6212068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
6222075SN/Adef format MiscPrefetch(ea_code, memacc_code,
6232075SN/A                        mem_flags = [], inst_flags = []) {{
6242068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6252075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6262069SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
6272068SN/A}};
6282068SN/A
6292068SN/A
630