mem.isa revision 6181
11689SN/A// -*- mode:c++ -*-
22326SN/A
31689SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
41689SN/A// All rights reserved.
51689SN/A//
61689SN/A// Redistribution and use in source and binary forms, with or without
71689SN/A// modification, are permitted provided that the following conditions are
81689SN/A// met: redistributions of source code must retain the above copyright
91689SN/A// notice, this list of conditions and the following disclaimer;
101689SN/A// redistributions in binary form must reproduce the above copyright
111689SN/A// notice, this list of conditions and the following disclaimer in the
121689SN/A// documentation and/or other materials provided with the distribution;
131689SN/A// neither the name of the copyright holders nor the names of its
141689SN/A// contributors may be used to endorse or promote products derived from
151689SN/A// this software without specific prior written permission.
161689SN/A//
171689SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181689SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191689SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201689SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211689SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221689SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231689SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241689SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251689SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261689SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292831Sksewell@umich.edu// Authors: Steve Reinhardt
301689SN/A//          Kevin Lim
311689SN/A
322064SN/A////////////////////////////////////////////////////////////////////
331060SN/A//
341060SN/A// Memory-format instructions: LoadAddress, Load, Store
352292SN/A//
361717SN/A
374762Snate@binkert.orgoutput header {{
386221Snate@binkert.org    /**
394762Snate@binkert.org     * Base class for general Alpha memory-format instructions.
401060SN/A     */
416221Snate@binkert.org    class Memory : public AlphaStaticInst
425529Snate@binkert.org    {
431061SN/A      protected:
442292SN/A
455606Snate@binkert.org        /// Memory request flags.  See mem_req_base.hh.
465606Snate@binkert.org        Request::Flags memAccessFlags;
475606Snate@binkert.org
481060SN/A        /// Constructor
492292SN/A        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
502292SN/A            : AlphaStaticInst(mnem, _machInst, __opClass)
512292SN/A        {
522292SN/A        }
532292SN/A
542292SN/A        std::string
552292SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
562326SN/A
572292SN/A       public:
582292SN/A
592292SN/A        Request::Flags memAccFlags() { return memAccessFlags; }
602292SN/A    };
612292SN/A
622292SN/A    /**
635336Shines@cs.fsu.edu     * Base class for memory-format instructions using a 32-bit
642292SN/A     * displacement (i.e. most of them).
654873Sstever@eecs.umich.edu     */
662292SN/A    class MemoryDisp32 : public Memory
672292SN/A    {
682292SN/A      protected:
694329Sktlim@umich.edu        /// Displacement for EA calculation (signed).
705529Snate@binkert.org        int32_t disp;
714329Sktlim@umich.edu
724329Sktlim@umich.edu        /// Constructor.
734329Sktlim@umich.edu        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
742292SN/A            : Memory(mnem, _machInst, __opClass),
752292SN/A              disp(MEMDISP)
762292SN/A        {
772292SN/A        }
782292SN/A    };
792292SN/A
802292SN/A
812292SN/A    /**
822307SN/A     * Base class for a few miscellaneous memory-format insts
832307SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
845529Snate@binkert.org     * None of these instructions has a destination register either.
851060SN/A     */
861060SN/A    class MemoryNoDisp : public Memory
871060SN/A    {
881060SN/A      protected:
891060SN/A        /// Constructor
901060SN/A        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
912326SN/A            : Memory(mnem, _machInst, __opClass)
921060SN/A        {
931060SN/A        }
941060SN/A
951060SN/A        std::string
962292SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
976221Snate@binkert.org    };
986221Snate@binkert.org}};
996221Snate@binkert.org
1001060SN/A
1011060SN/Aoutput decoder {{
1022307SN/A    std::string
1032292SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1042980Sgblack@eecs.umich.edu    {
1052292SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1062292SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1072292SN/A    }
1082292SN/A
1092292SN/A    std::string
1102292SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1112292SN/A    {
1122292SN/A        return csprintf("%-10s (r%d)", mnemonic, RB);
1132292SN/A    }
1142292SN/A}};
1156221Snate@binkert.org
1166221Snate@binkert.orgdef format LoadAddress(code) {{
1172292SN/A    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1182292SN/A    header_output = BasicDeclare.subst(iop)
1192292SN/A    decoder_output = BasicConstructor.subst(iop)
1202292SN/A    decode_block = BasicDecode.subst(iop)
1212292SN/A    exec_output = BasicExecute.subst(iop)
1222292SN/A}};
1232292SN/A
1242292SN/A
1252292SN/Adef template LoadStoreDeclare {{
1266221Snate@binkert.org    /**
1276221Snate@binkert.org     * Static instruction class for "%(mnemonic)s".
1282292SN/A     */
1292292SN/A    class %(class_name)s : public %(base_class)s
1302831Sksewell@umich.edu    {
1312292SN/A      public:
1322292SN/A
1332292SN/A        /// Constructor.
1342292SN/A        %(class_name)s(ExtMachInst machInst);
1352292SN/A
1362292SN/A        %(BasicExecDeclare)s
1372292SN/A
1382292SN/A        %(EACompDeclare)s
1392292SN/A
1406221Snate@binkert.org        %(InitiateAccDeclare)s
1416221Snate@binkert.org
1422292SN/A        %(CompleteAccDeclare)s
1432292SN/A
1442831Sksewell@umich.edu        %(MemAccSizeDeclare)s
1452292SN/A    };
1462292SN/A}};
1472292SN/A
1482292SN/A
1492292SN/Adef template EACompDeclare {{
1502292SN/A    Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1512292SN/A}};
1522292SN/A
1532292SN/Adef template InitiateAccDeclare {{
1542292SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1552326SN/A}};
1562348SN/A
1572326SN/A
1582326SN/Adef template CompleteAccDeclare {{
1592348SN/A    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1602292SN/A                      Trace::InstRecord *) const;
1612292SN/A}};
1622292SN/A
1632292SN/Adef template MemAccSizeDeclare {{
1642292SN/A    int memAccSize(%(CPU_exec_context)s *xc);
1652292SN/A}};
1662292SN/A
1671060SN/Adef template MiscMemAccSize {{
1681060SN/A    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
1691061SN/A    {
1701060SN/A        panic("Misc instruction does not support split access method!");
1711062SN/A        return 0;
1721062SN/A    }
1732301SN/A}};
1741062SN/A
1751062SN/Adef template LoadStoreMemAccSize {{
1761062SN/A    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
1771062SN/A    {
1781062SN/A        // Return the memory access size in bytes
1791062SN/A        return (%(mem_acc_size)d / 8);
1801062SN/A    }
1811062SN/A}};
1821062SN/A
1831062SN/A
1842301SN/Adef template LoadStoreConstructor {{
1852301SN/A    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
1862301SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1872301SN/A    {
1881062SN/A        %(constructor)s;
1891062SN/A    }
1901062SN/A}};
1911062SN/A
1921062SN/Adef template EACompExecute {{
1931062SN/A    Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
1941062SN/A                                  Trace::InstRecord *traceData) const
1951062SN/A    {
1961062SN/A        Addr EA;
1971062SN/A        Fault fault = NoFault;
1981062SN/A
1991062SN/A        %(fp_enable_check)s;
2001062SN/A        %(op_decl)s;
2011062SN/A        %(op_rd)s;
2021062SN/A        %(ea_code)s;
2031062SN/A
2041062SN/A        if (fault == NoFault) {
2051062SN/A            %(op_wb)s;
2061062SN/A            xc->setEA(EA);
2071062SN/A        }
2081062SN/A
2091062SN/A        return fault;
2101062SN/A    }
2111062SN/A}};
2121062SN/A
2131062SN/A
2141062SN/Adef template LoadExecute {{
2151062SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2161062SN/A                                  Trace::InstRecord *traceData) const
2171062SN/A    {
2181062SN/A        Addr EA;
2191062SN/A        Fault fault = NoFault;
2201062SN/A
2211062SN/A        %(fp_enable_check)s;
2221062SN/A        %(op_decl)s;
2231062SN/A        %(op_rd)s;
2241062SN/A        %(ea_code)s;
2251062SN/A
2261062SN/A        if (fault == NoFault) {
2271062SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2281062SN/A            %(memacc_code)s;
2291062SN/A        }
2301062SN/A
2311062SN/A        if (fault == NoFault) {
2321062SN/A            %(op_wb)s;
2331062SN/A        }
2341062SN/A
2352361SN/A        return fault;
2362326SN/A    }
2372301SN/A}};
2382301SN/A
2392301SN/A
2402301SN/Adef template LoadInitiateAcc {{
2412301SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2422301SN/A                                      Trace::InstRecord *traceData) const
2432326SN/A    {
2442301SN/A        Addr EA;
2452361SN/A        Fault fault = NoFault;
2462326SN/A
2472307SN/A        %(fp_enable_check)s;
2482301SN/A        %(op_src_decl)s;
2492301SN/A        %(op_rd)s;
2502307SN/A        %(ea_code)s;
2512301SN/A
2522301SN/A        if (fault == NoFault) {
2532301SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2542301SN/A        }
2552301SN/A
2562301SN/A        return fault;
2572301SN/A    }
2582301SN/A}};
2592301SN/A
2602301SN/A
2612301SN/Adef template LoadCompleteAcc {{
2622301SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
2632326SN/A                                      %(CPU_exec_context)s *xc,
2644762Snate@binkert.org                                      Trace::InstRecord *traceData) const
2652301SN/A    {
2662301SN/A        Fault fault = NoFault;
2672301SN/A
2682301SN/A        %(fp_enable_check)s;
2694762Snate@binkert.org        %(op_decl)s;
2702301SN/A
2712301SN/A        Mem = pkt->get<typeof(Mem)>();
2722301SN/A
2732301SN/A        if (fault == NoFault) {
2742361SN/A            %(memacc_code)s;
2752326SN/A        }
2762301SN/A
2772301SN/A        if (fault == NoFault) {
2782301SN/A            %(op_wb)s;
2792301SN/A        }
2802301SN/A
2812301SN/A        return fault;
2822301SN/A    }
2832980Sgblack@eecs.umich.edu}};
2842301SN/A
2852326SN/A
2862301SN/Adef template StoreExecute {{
2872361SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2882326SN/A                                  Trace::InstRecord *traceData) const
2892301SN/A    {
2902301SN/A        Addr EA;
2912301SN/A        Fault fault = NoFault;
2922301SN/A
2932326SN/A        %(fp_enable_check)s;
2942727Sktlim@umich.edu        %(op_decl)s;
2952326SN/A        %(op_rd)s;
2962301SN/A        %(ea_code)s;
2972301SN/A
2982301SN/A        if (fault == NoFault) {
2992301SN/A            %(memacc_code)s;
3002301SN/A        }
3012301SN/A
3024762Snate@binkert.org        if (fault == NoFault) {
3032301SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3042301SN/A                              memAccessFlags, NULL);
3052326SN/A            if (traceData) { traceData->setData(Mem); }
3062301SN/A        }
3072301SN/A
3082301SN/A        if (fault == NoFault) {
3092301SN/A            %(postacc_code)s;
3102301SN/A        }
3112301SN/A
3122326SN/A        if (fault == NoFault) {
3132301SN/A            %(op_wb)s;
3142301SN/A        }
3152301SN/A
3162301SN/A        return fault;
3172326SN/A    }
3182301SN/A}};
3196221Snate@binkert.org
3202292SN/Adef template StoreCondExecute {{
3216221Snate@binkert.org    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3222292SN/A                                  Trace::InstRecord *traceData) const
3237897Shestness@cs.utexas.edu    {
3247897Shestness@cs.utexas.edu        Addr EA;
3257897Shestness@cs.utexas.edu        Fault fault = NoFault;
3267897Shestness@cs.utexas.edu        uint64_t write_result = 0;
3277897Shestness@cs.utexas.edu
3287897Shestness@cs.utexas.edu        %(fp_enable_check)s;
3297897Shestness@cs.utexas.edu        %(op_decl)s;
3307897Shestness@cs.utexas.edu        %(op_rd)s;
3317897Shestness@cs.utexas.edu        %(ea_code)s;
3327897Shestness@cs.utexas.edu
3337897Shestness@cs.utexas.edu        if (fault == NoFault) {
3347897Shestness@cs.utexas.edu            %(memacc_code)s;
3357897Shestness@cs.utexas.edu        }
3367897Shestness@cs.utexas.edu
3377897Shestness@cs.utexas.edu        if (fault == NoFault) {
3387897Shestness@cs.utexas.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3397897Shestness@cs.utexas.edu                              memAccessFlags, &write_result);
3407897Shestness@cs.utexas.edu            if (traceData) { traceData->setData(Mem); }
3417897Shestness@cs.utexas.edu        }
3427897Shestness@cs.utexas.edu
3437897Shestness@cs.utexas.edu        if (fault == NoFault) {
3447897Shestness@cs.utexas.edu            %(postacc_code)s;
3457897Shestness@cs.utexas.edu        }
3467897Shestness@cs.utexas.edu
3477897Shestness@cs.utexas.edu        if (fault == NoFault) {
3487897Shestness@cs.utexas.edu            %(op_wb)s;
3497897Shestness@cs.utexas.edu        }
3507897Shestness@cs.utexas.edu
3517897Shestness@cs.utexas.edu        return fault;
3527897Shestness@cs.utexas.edu    }
3537897Shestness@cs.utexas.edu}};
3547897Shestness@cs.utexas.edu
3557897Shestness@cs.utexas.edudef template StoreInitiateAcc {{
3567897Shestness@cs.utexas.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3577897Shestness@cs.utexas.edu                                      Trace::InstRecord *traceData) const
3587897Shestness@cs.utexas.edu    {
3597897Shestness@cs.utexas.edu        Addr EA;
3607897Shestness@cs.utexas.edu        Fault fault = NoFault;
3617897Shestness@cs.utexas.edu
3627897Shestness@cs.utexas.edu        %(fp_enable_check)s;
3637897Shestness@cs.utexas.edu        %(op_decl)s;
3641062SN/A        %(op_rd)s;
3651062SN/A        %(ea_code)s;
3661062SN/A
3671062SN/A        if (fault == NoFault) {
3682307SN/A            %(memacc_code)s;
3691060SN/A        }
3702307SN/A
3716221Snate@binkert.org        if (fault == NoFault) {
3726221Snate@binkert.org            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3736221Snate@binkert.org                              memAccessFlags, NULL);
3742307SN/A            if (traceData) { traceData->setData(Mem); }
3751060SN/A        }
3762307SN/A
3772307SN/A        return fault;
3782307SN/A    }
3792307SN/A}};
3802307SN/A
3812307SN/A
3822307SN/Adef template StoreCompleteAcc {{
3832307SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3842307SN/A                                      %(CPU_exec_context)s *xc,
3852307SN/A                                      Trace::InstRecord *traceData) const
3862307SN/A    {
3872307SN/A        Fault fault = NoFault;
3886221Snate@binkert.org
3896221Snate@binkert.org        %(fp_enable_check)s;
3902307SN/A        %(op_dest_decl)s;
3912307SN/A
3922307SN/A        if (fault == NoFault) {
3932307SN/A            %(postacc_code)s;
3942307SN/A        }
3952307SN/A
3962307SN/A        if (fault == NoFault) {
3972307SN/A            %(op_wb)s;
3982307SN/A        }
3992307SN/A
4001060SN/A        return fault;
4011060SN/A    }
4021061SN/A}};
4031060SN/A
4046221Snate@binkert.org
4051060SN/Adef template StoreCondCompleteAcc {{
4062292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4072064SN/A                                      %(CPU_exec_context)s *xc,
4082064SN/A                                      Trace::InstRecord *traceData) const
4092064SN/A    {
4102064SN/A        Fault fault = NoFault;
4112292SN/A
4122064SN/A        %(fp_enable_check)s;
4134318Sktlim@umich.edu        %(op_dest_decl)s;
4141060SN/A
4151060SN/A        uint64_t write_result = pkt->req->getExtraData();
4161061SN/A
4171060SN/A        if (fault == NoFault) {
4181060SN/A            %(postacc_code)s;
4191060SN/A        }
4201060SN/A
4211060SN/A        if (fault == NoFault) {
4221060SN/A            %(op_wb)s;
4231060SN/A        }
4241060SN/A
4251684SN/A        return fault;
4262307SN/A    }
4272307SN/A}};
4282307SN/A
4292367SN/A
4302367SN/Adef template MiscExecute {{
4312367SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4322367SN/A                                  Trace::InstRecord *traceData) const
4332367SN/A    {
4342367SN/A        Addr EA;
4352367SN/A        Fault fault = NoFault;
4362307SN/A
4372326SN/A        %(fp_enable_check)s;
4382367SN/A        %(op_decl)s;
4392307SN/A        %(op_rd)s;
4406221Snate@binkert.org        %(ea_code)s;
4416221Snate@binkert.org
4422307SN/A        if (fault == NoFault) {
4432307SN/A            %(memacc_code)s;
4442307SN/A        }
4452307SN/A
4462307SN/A        return NoFault;
4472307SN/A    }
4482307SN/A}};
4492307SN/A
4502307SN/Adef template MiscInitiateAcc {{
4512307SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4522307SN/A                                      Trace::InstRecord *traceData) const
4532292SN/A    {
4546221Snate@binkert.org        warn("Misc instruction does not support split access method!");
4552292SN/A        return NoFault;
4562292SN/A    }
4572292SN/A}};
4582292SN/A
4592292SN/A
4602292SN/Adef template MiscCompleteAcc {{
4612292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4622292SN/A                                      %(CPU_exec_context)s *xc,
4632292SN/A                                      Trace::InstRecord *traceData) const
4642292SN/A    {
4652292SN/A        warn("Misc instruction does not support split access method!");
4662292SN/A
4672292SN/A        return NoFault;
4682292SN/A    }
4693867Sbinkertn@umich.edu}};
4702292SN/A
4716221Snate@binkert.orgdef template MiscMemAccSize {{
4726221Snate@binkert.org    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
4732292SN/A    {
4743867Sbinkertn@umich.edu        panic("Misc instruction does not support split access method!");
4756221Snate@binkert.org        return 0;
4763867Sbinkertn@umich.edu    }
4772292SN/A}};
4783867Sbinkertn@umich.edu
4792292SN/A// load instructions use Ra as dest, so check for
4803867Sbinkertn@umich.edu// Ra == 31 to detect nops
4812292SN/Adef template LoadNopCheckDecode {{
4822292SN/A {
4832292SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
4842292SN/A     if (RA == 31) {
4852292SN/A         i = makeNop(i);
4862292SN/A     }
4871684SN/A     return i;
4881684SN/A }
4891684SN/A}};
4901684SN/A
4911684SN/A
4921684SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
4932292SN/Adef template LoadPrefetchCheckDecode {{
4942292SN/A {
4956221Snate@binkert.org     if (RA != 31) {
4962292SN/A         return new %(class_name)s(machInst);
4972292SN/A     }
4982292SN/A     else {
4992292SN/A         return new %(class_name)sPrefetch(machInst);
5001060SN/A     }
5011060SN/A }
5021061SN/A}};
5031060SN/A
5041060SN/A
5051060SN/Alet {{
5061060SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5071060SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
5081060SN/A                  decode_template = BasicDecode, exec_template_base = ''):
5091060SN/A    # Make sure flags are in lists (convert to lists if not).
5101060SN/A    mem_flags = makeList(mem_flags)
5111060SN/A    inst_flags = makeList(inst_flags)
5121060SN/A
5131061SN/A    # add hook to get effective addresses into execution trace output.
5142292SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5156221Snate@binkert.org
5162292SN/A    # Some CPU models execute the memory operation as an atomic unit,
5172292SN/A    # while others want to separate them into an effective address
5182292SN/A    # computation and a memory access operation.  As a result, we need
5192292SN/A    # to generate three StaticInst objects.  Note that the latter two
5202292SN/A    # are nested inside the larger "atomic" one.
5212292SN/A
5222292SN/A    # Generate InstObjParams for each of the three objects.  Note that
5232292SN/A    # they differ only in the set of code objects contained (which in
5242292SN/A    # turn affects the object's overall operand list).
5252292SN/A    iop = InstObjParams(name, Name, base_class,
5262292SN/A                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
5272292SN/A                        inst_flags)
5282292SN/A    memacc_iop = InstObjParams(name, Name, base_class,
5292292SN/A                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
5302292SN/A                        inst_flags)
5312292SN/A
5322292SN/A    if mem_flags:
5332292SN/A        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
5342292SN/A        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
5352292SN/A        iop.constructor += s
5362292SN/A        memacc_iop.constructor += s
5372292SN/A
5382292SN/A    # select templates
5392292SN/A
5402292SN/A    # The InitiateAcc template is the same for StoreCond templates as the
5412292SN/A    # corresponding Store template..
5421060SN/A    StoreCondInitiateAcc = StoreInitiateAcc
5431061SN/A
5441060SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
5457897Shestness@cs.utexas.edu    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
5461060SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
5471060SN/A
5481060SN/A    if (exec_template_base == 'Load' or exec_template_base == 'Store'):
5497720Sgblack@eecs.umich.edu      memAccSizeTemplate = eval('LoadStoreMemAccSize')
5507720Sgblack@eecs.umich.edu    else:
5511060SN/A      memAccSizeTemplate = eval('MiscMemAccSize')
5521060SN/A
5531060SN/A    # (header_output, decoder_output, decode_block, exec_output)
5542292SN/A    return (LoadStoreDeclare.subst(iop),
5551060SN/A            LoadStoreConstructor.subst(iop),
5562064SN/A            decode_template.subst(iop),
5571060SN/A            fullExecTemplate.subst(iop)
5582292SN/A            + EACompExecute.subst(iop)
5591060SN/A            + initiateAccTemplate.subst(iop)
5601060SN/A            + completeAccTemplate.subst(iop)
5611060SN/A            + memAccSizeTemplate.subst(memacc_iop))
5621060SN/A}};
5631060SN/A
5641060SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
5651060SN/A                     mem_flags = [], inst_flags = []) {{
5662326SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5671060SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5681061SN/A                      decode_template = LoadNopCheckDecode,
5692292SN/A                      exec_template_base = 'Load')
5701062SN/A}};
5711062SN/A
5721061SN/A
5731061SN/A// Note that the flags passed in apply only to the prefetch version
5741062SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
5751060SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
5762292SN/A    # declare the load instruction object and generate the decode block
5772292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5781060SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5791060SN/A                      decode_template = LoadPrefetchCheckDecode,
5801060SN/A                      exec_template_base = 'Load')
5811061SN/A
5821061SN/A    # Declare the prefetch instruction object.
5832292SN/A
5841061SN/A    # Make sure flag args are lists so we can mess with them.
5851061SN/A    mem_flags = makeList(mem_flags)
5861061SN/A    pf_flags = makeList(pf_flags)
5877897Shestness@cs.utexas.edu    inst_flags = makeList(inst_flags)
5881061SN/A
5892292SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
5901061SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
5912292SN/A                                  'IsDataPrefetch', 'MemReadOp']
5921061SN/A
5937720Sgblack@eecs.umich.edu    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
5942326SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
5957720Sgblack@eecs.umich.edu                      'xc->prefetch(EA, memAccessFlags);',
5962064SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
5971061SN/A
5981061SN/A    header_output += pf_header_output
5992292SN/A    decoder_output += pf_decoder_output
6001061SN/A    exec_output += pf_exec_output
6012064SN/A}};
6021061SN/A
6032292SN/A
6041061SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
6051061SN/A                 mem_flags = [], inst_flags = []) {{
6061061SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6072326SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6081061SN/A                      exec_template_base = 'Store')
6091061SN/A}};
6101061SN/A
6112292SN/A
6122292SN/Adef format StoreCond(memacc_code, postacc_code,
6131061SN/A                     ea_code = {{ EA = Rb + disp; }},
6141062SN/A                     mem_flags = [], inst_flags = []) {{
6151062SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6162292SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6172292SN/A                      postacc_code, exec_template_base = 'StoreCond')
6182292SN/A}};
6192292SN/A
6201061SN/A
6211061SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
6221061SN/Adef format MiscPrefetch(ea_code, memacc_code,
6231060SN/A                        mem_flags = [], inst_flags = []) {{
6242292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6251060SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6262292SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
6271060SN/A}};
6282292SN/A
6292292SN/A
6301060SN/A