mem.isa revision 4056
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.
462068SN/A        unsigned memAccessFlags;
472068SN/A        /// Pointer to EAComp object.
482107SN/A        const StaticInstPtr eaCompPtr;
492068SN/A        /// Pointer to MemAcc object.
502107SN/A        const StaticInstPtr memAccPtr;
512068SN/A
522068SN/A        /// Constructor
532227SN/A        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
542107SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
552107SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
562068SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
572068SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
582068SN/A        {
592068SN/A        }
602068SN/A
612068SN/A        std::string
622068SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
632068SN/A
642068SN/A      public:
652068SN/A
662107SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
672107SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
682068SN/A    };
692068SN/A
702068SN/A    /**
712068SN/A     * Base class for memory-format instructions using a 32-bit
722068SN/A     * displacement (i.e. most of them).
732068SN/A     */
742068SN/A    class MemoryDisp32 : public Memory
752068SN/A    {
762068SN/A      protected:
772068SN/A        /// Displacement for EA calculation (signed).
782068SN/A        int32_t disp;
792068SN/A
802068SN/A        /// Constructor.
812227SN/A        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
822107SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
832107SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
842068SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
852068SN/A              disp(MEMDISP)
862068SN/A        {
872068SN/A        }
882068SN/A    };
892068SN/A
902068SN/A
912068SN/A    /**
922068SN/A     * Base class for a few miscellaneous memory-format insts
932068SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
942068SN/A     * None of these instructions has a destination register either.
952068SN/A     */
962068SN/A    class MemoryNoDisp : public Memory
972068SN/A    {
982068SN/A      protected:
992068SN/A        /// Constructor
1002227SN/A        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1012107SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
1022107SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
1032068SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
1042068SN/A        {
1052068SN/A        }
1062068SN/A
1072068SN/A        std::string
1082068SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1092068SN/A    };
1102068SN/A}};
1112068SN/A
1122068SN/A
1132068SN/Aoutput decoder {{
1142068SN/A    std::string
1152068SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1162068SN/A    {
1172068SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1182068SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1192068SN/A    }
1202068SN/A
1212068SN/A    std::string
1222068SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1232068SN/A    {
1242068SN/A        return csprintf("%-10s (r%d)", mnemonic, RB);
1252068SN/A    }
1262068SN/A}};
1272068SN/A
1282068SN/Adef format LoadAddress(code) {{
1293953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1302068SN/A    header_output = BasicDeclare.subst(iop)
1312068SN/A    decoder_output = BasicConstructor.subst(iop)
1322068SN/A    decode_block = BasicDecode.subst(iop)
1332068SN/A    exec_output = BasicExecute.subst(iop)
1342068SN/A}};
1352068SN/A
1362068SN/A
1372068SN/Adef template LoadStoreDeclare {{
1382068SN/A    /**
1392068SN/A     * Static instruction class for "%(mnemonic)s".
1402068SN/A     */
1412068SN/A    class %(class_name)s : public %(base_class)s
1422068SN/A    {
1432068SN/A      protected:
1442068SN/A
1452068SN/A        /**
1462068SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1472068SN/A         */
1482068SN/A        class EAComp : public %(base_class)s
1492068SN/A        {
1502068SN/A          public:
1512068SN/A            /// Constructor
1522227SN/A            EAComp(ExtMachInst machInst);
1532068SN/A
1542068SN/A            %(BasicExecDeclare)s
1552068SN/A        };
1562068SN/A
1572068SN/A        /**
1582068SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1592068SN/A         */
1602068SN/A        class MemAcc : public %(base_class)s
1612068SN/A        {
1622068SN/A          public:
1632068SN/A            /// Constructor
1642227SN/A            MemAcc(ExtMachInst machInst);
1652068SN/A
1662068SN/A            %(BasicExecDeclare)s
1672068SN/A        };
1682068SN/A
1692068SN/A      public:
1702068SN/A
1712068SN/A        /// Constructor.
1722227SN/A        %(class_name)s(ExtMachInst machInst);
1732068SN/A
1742068SN/A        %(BasicExecDeclare)s
1752095SN/A
1762095SN/A        %(InitiateAccDeclare)s
1772095SN/A
1782095SN/A        %(CompleteAccDeclare)s
1792068SN/A    };
1802068SN/A}};
1812068SN/A
1822095SN/A
1832095SN/Adef template InitiateAccDeclare {{
1842132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1852095SN/A}};
1862095SN/A
1872095SN/A
1882095SN/Adef template CompleteAccDeclare {{
1893349Sbinkertn@umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1902623SN/A                      Trace::InstRecord *) const;
1912095SN/A}};
1922095SN/A
1932095SN/A
1943953Sstever@eecs.umich.edudef template EACompConstructor {{
1952068SN/A    /** TODO: change op_class to AddrGenOp or something (requires
1962068SN/A     * creating new member of OpClass enum in op_class.hh, updating
1972068SN/A     * config files, etc.). */
1982227SN/A    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
1992068SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2002068SN/A    {
2013953Sstever@eecs.umich.edu        %(constructor)s;
2022068SN/A    }
2033953Sstever@eecs.umich.edu}};
2042068SN/A
2053953Sstever@eecs.umich.edu
2063953Sstever@eecs.umich.edudef template MemAccConstructor {{
2072227SN/A    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2082068SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2092068SN/A    {
2103953Sstever@eecs.umich.edu        %(constructor)s;
2112068SN/A    }
2123953Sstever@eecs.umich.edu}};
2132068SN/A
2143953Sstever@eecs.umich.edu
2153953Sstever@eecs.umich.edudef template LoadStoreConstructor {{
2162227SN/A    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2172068SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2182068SN/A                          new EAComp(machInst), new MemAcc(machInst))
2192068SN/A    {
2202068SN/A        %(constructor)s;
2212068SN/A    }
2222068SN/A}};
2232068SN/A
2242068SN/A
2252068SN/Adef template EACompExecute {{
2262132SN/A    Fault
2272068SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2282068SN/A                                   Trace::InstRecord *traceData) const
2292068SN/A    {
2302068SN/A        Addr EA;
2312132SN/A        Fault fault = NoFault;
2322068SN/A
2332068SN/A        %(fp_enable_check)s;
2342068SN/A        %(op_decl)s;
2352068SN/A        %(op_rd)s;
2363953Sstever@eecs.umich.edu        %(ea_code)s;
2372068SN/A
2382090SN/A        if (fault == NoFault) {
2392068SN/A            %(op_wb)s;
2402068SN/A            xc->setEA(EA);
2412068SN/A        }
2422068SN/A
2432068SN/A        return fault;
2442068SN/A    }
2452068SN/A}};
2462068SN/A
2472069SN/Adef template LoadMemAccExecute {{
2482132SN/A    Fault
2492068SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2502068SN/A                                   Trace::InstRecord *traceData) const
2512068SN/A    {
2522068SN/A        Addr EA;
2532132SN/A        Fault fault = NoFault;
2542068SN/A
2552068SN/A        %(fp_enable_check)s;
2562068SN/A        %(op_decl)s;
2572069SN/A        %(op_rd)s;
2582068SN/A        EA = xc->getEA();
2592068SN/A
2602090SN/A        if (fault == NoFault) {
2612069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2623953Sstever@eecs.umich.edu            %(memacc_code)s;
2632068SN/A        }
2642068SN/A
2652090SN/A        if (fault == NoFault) {
2662069SN/A            %(op_wb)s;
2672068SN/A        }
2682068SN/A
2692068SN/A        return fault;
2702068SN/A    }
2712068SN/A}};
2722068SN/A
2732068SN/A
2742069SN/Adef template LoadExecute {{
2752132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2762068SN/A                                  Trace::InstRecord *traceData) const
2772068SN/A    {
2782068SN/A        Addr EA;
2792132SN/A        Fault fault = NoFault;
2802068SN/A
2812068SN/A        %(fp_enable_check)s;
2822068SN/A        %(op_decl)s;
2832069SN/A        %(op_rd)s;
2842068SN/A        %(ea_code)s;
2852068SN/A
2862090SN/A        if (fault == NoFault) {
2872069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2882068SN/A            %(memacc_code)s;
2892068SN/A        }
2902068SN/A
2912090SN/A        if (fault == NoFault) {
2922069SN/A            %(op_wb)s;
2932069SN/A        }
2942069SN/A
2952069SN/A        return fault;
2962069SN/A    }
2972069SN/A}};
2982069SN/A
2992069SN/A
3002095SN/Adef template LoadInitiateAcc {{
3012132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3022095SN/A                                      Trace::InstRecord *traceData) const
3032095SN/A    {
3042095SN/A        Addr EA;
3052132SN/A        Fault fault = NoFault;
3062095SN/A
3072095SN/A        %(fp_enable_check)s;
3082095SN/A        %(op_src_decl)s;
3092095SN/A        %(op_rd)s;
3102095SN/A        %(ea_code)s;
3112095SN/A
3122098SN/A        if (fault == NoFault) {
3132095SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3142095SN/A        }
3152095SN/A
3162095SN/A        return fault;
3172095SN/A    }
3182095SN/A}};
3192095SN/A
3202095SN/A
3212095SN/Adef template LoadCompleteAcc {{
3223349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3232095SN/A                                      %(CPU_exec_context)s *xc,
3242095SN/A                                      Trace::InstRecord *traceData) const
3252095SN/A    {
3262132SN/A        Fault fault = NoFault;
3272095SN/A
3282095SN/A        %(fp_enable_check)s;
3292506SN/A        %(op_decl)s;
3302095SN/A
3312623SN/A        Mem = pkt->get<typeof(Mem)>();
3322095SN/A
3332098SN/A        if (fault == NoFault) {
3342095SN/A            %(memacc_code)s;
3352095SN/A        }
3362095SN/A
3372098SN/A        if (fault == NoFault) {
3382095SN/A            %(op_wb)s;
3392095SN/A        }
3402095SN/A
3412095SN/A        return fault;
3422095SN/A    }
3432095SN/A}};
3442095SN/A
3452095SN/A
3462069SN/Adef template StoreMemAccExecute {{
3472132SN/A    Fault
3482069SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3492069SN/A                                   Trace::InstRecord *traceData) const
3502069SN/A    {
3512069SN/A        Addr EA;
3522132SN/A        Fault fault = NoFault;
3534027Sstever@eecs.umich.edu
3544027Sstever@eecs.umich.edu        %(fp_enable_check)s;
3554027Sstever@eecs.umich.edu        %(op_decl)s;
3564027Sstever@eecs.umich.edu        %(op_rd)s;
3574027Sstever@eecs.umich.edu        EA = xc->getEA();
3584027Sstever@eecs.umich.edu
3594027Sstever@eecs.umich.edu        if (fault == NoFault) {
3604027Sstever@eecs.umich.edu            %(memacc_code)s;
3614027Sstever@eecs.umich.edu        }
3624027Sstever@eecs.umich.edu
3634027Sstever@eecs.umich.edu        if (fault == NoFault) {
3644027Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3654027Sstever@eecs.umich.edu                              memAccessFlags, NULL);
3664027Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
3674027Sstever@eecs.umich.edu        }
3684027Sstever@eecs.umich.edu
3694027Sstever@eecs.umich.edu        if (fault == NoFault) {
3704027Sstever@eecs.umich.edu            %(postacc_code)s;
3714027Sstever@eecs.umich.edu        }
3724027Sstever@eecs.umich.edu
3734027Sstever@eecs.umich.edu        if (fault == NoFault) {
3744027Sstever@eecs.umich.edu            %(op_wb)s;
3754027Sstever@eecs.umich.edu        }
3764027Sstever@eecs.umich.edu
3774027Sstever@eecs.umich.edu        return fault;
3784027Sstever@eecs.umich.edu    }
3794027Sstever@eecs.umich.edu}};
3804027Sstever@eecs.umich.edu
3814027Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{
3824027Sstever@eecs.umich.edu    Fault
3834027Sstever@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3844027Sstever@eecs.umich.edu                                   Trace::InstRecord *traceData) const
3854027Sstever@eecs.umich.edu    {
3864027Sstever@eecs.umich.edu        Addr EA;
3874027Sstever@eecs.umich.edu        Fault fault = NoFault;
3882069SN/A        uint64_t write_result = 0;
3892069SN/A
3902069SN/A        %(fp_enable_check)s;
3912069SN/A        %(op_decl)s;
3922069SN/A        %(op_rd)s;
3932069SN/A        EA = xc->getEA();
3942069SN/A
3952090SN/A        if (fault == NoFault) {
3963953Sstever@eecs.umich.edu            %(memacc_code)s;
3972069SN/A        }
3982069SN/A
3992090SN/A        if (fault == NoFault) {
4002069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4012069SN/A                              memAccessFlags, &write_result);
4022069SN/A            if (traceData) { traceData->setData(Mem); }
4032068SN/A        }
4042068SN/A
4052090SN/A        if (fault == NoFault) {
4062068SN/A            %(postacc_code)s;
4072068SN/A        }
4082068SN/A
4092090SN/A        if (fault == NoFault) {
4102069SN/A            %(op_wb)s;
4112068SN/A        }
4122068SN/A
4132068SN/A        return fault;
4142068SN/A    }
4152068SN/A}};
4162068SN/A
4172068SN/A
4182069SN/Adef template StoreExecute {{
4192132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4202069SN/A                                  Trace::InstRecord *traceData) const
4212069SN/A    {
4222069SN/A        Addr EA;
4232132SN/A        Fault fault = NoFault;
4244027Sstever@eecs.umich.edu
4254027Sstever@eecs.umich.edu        %(fp_enable_check)s;
4264027Sstever@eecs.umich.edu        %(op_decl)s;
4274027Sstever@eecs.umich.edu        %(op_rd)s;
4284027Sstever@eecs.umich.edu        %(ea_code)s;
4294027Sstever@eecs.umich.edu
4304027Sstever@eecs.umich.edu        if (fault == NoFault) {
4314027Sstever@eecs.umich.edu            %(memacc_code)s;
4324027Sstever@eecs.umich.edu        }
4334027Sstever@eecs.umich.edu
4344027Sstever@eecs.umich.edu        if (fault == NoFault) {
4354027Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4364027Sstever@eecs.umich.edu                              memAccessFlags, NULL);
4374027Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
4384027Sstever@eecs.umich.edu        }
4394027Sstever@eecs.umich.edu
4404027Sstever@eecs.umich.edu        if (fault == NoFault) {
4414027Sstever@eecs.umich.edu            %(postacc_code)s;
4424027Sstever@eecs.umich.edu        }
4434027Sstever@eecs.umich.edu
4444027Sstever@eecs.umich.edu        if (fault == NoFault) {
4454027Sstever@eecs.umich.edu            %(op_wb)s;
4464027Sstever@eecs.umich.edu        }
4474027Sstever@eecs.umich.edu
4484027Sstever@eecs.umich.edu        return fault;
4494027Sstever@eecs.umich.edu    }
4504027Sstever@eecs.umich.edu}};
4514027Sstever@eecs.umich.edu
4524027Sstever@eecs.umich.edudef template StoreCondExecute {{
4534027Sstever@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4544027Sstever@eecs.umich.edu                                  Trace::InstRecord *traceData) const
4554027Sstever@eecs.umich.edu    {
4564027Sstever@eecs.umich.edu        Addr EA;
4574027Sstever@eecs.umich.edu        Fault fault = NoFault;
4582069SN/A        uint64_t write_result = 0;
4592069SN/A
4602069SN/A        %(fp_enable_check)s;
4612069SN/A        %(op_decl)s;
4622069SN/A        %(op_rd)s;
4632069SN/A        %(ea_code)s;
4642069SN/A
4652090SN/A        if (fault == NoFault) {
4662069SN/A            %(memacc_code)s;
4672069SN/A        }
4682069SN/A
4692090SN/A        if (fault == NoFault) {
4702069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4712069SN/A                              memAccessFlags, &write_result);
4722069SN/A            if (traceData) { traceData->setData(Mem); }
4732069SN/A        }
4742069SN/A
4752090SN/A        if (fault == NoFault) {
4762069SN/A            %(postacc_code)s;
4772069SN/A        }
4782069SN/A
4792090SN/A        if (fault == NoFault) {
4802069SN/A            %(op_wb)s;
4812069SN/A        }
4822069SN/A
4832069SN/A        return fault;
4842069SN/A    }
4852069SN/A}};
4862069SN/A
4872095SN/Adef template StoreInitiateAcc {{
4882132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4892095SN/A                                      Trace::InstRecord *traceData) const
4902095SN/A    {
4912095SN/A        Addr EA;
4922132SN/A        Fault fault = NoFault;
4932095SN/A
4942095SN/A        %(fp_enable_check)s;
4952506SN/A        %(op_decl)s;
4962095SN/A        %(op_rd)s;
4972095SN/A        %(ea_code)s;
4982095SN/A
4992098SN/A        if (fault == NoFault) {
5002095SN/A            %(memacc_code)s;
5012095SN/A        }
5022095SN/A
5032098SN/A        if (fault == NoFault) {
5042095SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5052623SN/A                              memAccessFlags, NULL);
5062095SN/A            if (traceData) { traceData->setData(Mem); }
5072095SN/A        }
5082095SN/A
5092095SN/A        return fault;
5102095SN/A    }
5112095SN/A}};
5122095SN/A
5132095SN/A
5142095SN/Adef template StoreCompleteAcc {{
5153349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5162095SN/A                                      %(CPU_exec_context)s *xc,
5172095SN/A                                      Trace::InstRecord *traceData) const
5182095SN/A    {
5192132SN/A        Fault fault = NoFault;
5202095SN/A
5212095SN/A        %(fp_enable_check)s;
5222095SN/A        %(op_dest_decl)s;
5232095SN/A
5242623SN/A        if (fault == NoFault) {
5252623SN/A            %(postacc_code)s;
5262623SN/A        }
5272623SN/A
5282623SN/A        if (fault == NoFault) {
5292623SN/A            %(op_wb)s;
5302623SN/A        }
5312623SN/A
5322623SN/A        return fault;
5332623SN/A    }
5342623SN/A}};
5352623SN/A
5362623SN/A
5372623SN/Adef template StoreCondCompleteAcc {{
5383349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5392623SN/A                                      %(CPU_exec_context)s *xc,
5402623SN/A                                      Trace::InstRecord *traceData) const
5412623SN/A    {
5422623SN/A        Fault fault = NoFault;
5432623SN/A
5442623SN/A        %(fp_enable_check)s;
5452623SN/A        %(op_dest_decl)s;
5462623SN/A
5474040Ssaidi@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
5482095SN/A
5492098SN/A        if (fault == NoFault) {
5502095SN/A            %(postacc_code)s;
5512095SN/A        }
5522095SN/A
5532098SN/A        if (fault == NoFault) {
5542095SN/A            %(op_wb)s;
5552095SN/A        }
5562095SN/A
5572095SN/A        return fault;
5582095SN/A    }
5592095SN/A}};
5602095SN/A
5612069SN/A
5622069SN/Adef template MiscMemAccExecute {{
5632132SN/A    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
5642069SN/A                                          Trace::InstRecord *traceData) const
5652069SN/A    {
5662069SN/A        Addr EA;
5672132SN/A        Fault fault = NoFault;
5682069SN/A
5692069SN/A        %(fp_enable_check)s;
5702069SN/A        %(op_decl)s;
5712069SN/A        %(op_rd)s;
5722069SN/A        EA = xc->getEA();
5732069SN/A
5742090SN/A        if (fault == NoFault) {
5753953Sstever@eecs.umich.edu            %(memacc_code)s;
5762069SN/A        }
5772069SN/A
5782090SN/A        return NoFault;
5792069SN/A    }
5802069SN/A}};
5812069SN/A
5822069SN/Adef template MiscExecute {{
5832132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5842068SN/A                                  Trace::InstRecord *traceData) const
5852068SN/A    {
5862068SN/A        Addr EA;
5872132SN/A        Fault fault = NoFault;
5882068SN/A
5892068SN/A        %(fp_enable_check)s;
5902068SN/A        %(op_decl)s;
5912069SN/A        %(op_rd)s;
5922068SN/A        %(ea_code)s;
5932068SN/A
5942090SN/A        if (fault == NoFault) {
5952069SN/A            %(memacc_code)s;
5962068SN/A        }
5972068SN/A
5982090SN/A        return NoFault;
5992068SN/A    }
6002068SN/A}};
6012068SN/A
6022095SN/Adef template MiscInitiateAcc {{
6032132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
6042095SN/A                                      Trace::InstRecord *traceData) const
6052095SN/A    {
6062355SN/A        warn("Misc instruction does not support split access method!");
6072098SN/A        return NoFault;
6082095SN/A    }
6092095SN/A}};
6102095SN/A
6112095SN/A
6122095SN/Adef template MiscCompleteAcc {{
6133349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
6142095SN/A                                      %(CPU_exec_context)s *xc,
6152095SN/A                                      Trace::InstRecord *traceData) const
6162095SN/A    {
6172355SN/A        warn("Misc instruction does not support split access method!");
6182110SN/A
6192098SN/A        return NoFault;
6202095SN/A    }
6212095SN/A}};
6222095SN/A
6232068SN/A// load instructions use Ra as dest, so check for
6242068SN/A// Ra == 31 to detect nops
6252068SN/Adef template LoadNopCheckDecode {{
6262068SN/A {
6272068SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
6282068SN/A     if (RA == 31) {
6292068SN/A         i = makeNop(i);
6302068SN/A     }
6312068SN/A     return i;
6322068SN/A }
6332068SN/A}};
6342068SN/A
6352068SN/A
6362068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
6372068SN/Adef template LoadPrefetchCheckDecode {{
6382068SN/A {
6392068SN/A     if (RA != 31) {
6402068SN/A         return new %(class_name)s(machInst);
6412068SN/A     }
6422068SN/A     else {
6432068SN/A         return new %(class_name)sPrefetch(machInst);
6442068SN/A     }
6452068SN/A }
6462068SN/A}};
6472068SN/A
6482068SN/A
6492068SN/Alet {{
6502075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6512075SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
6522069SN/A                  decode_template = BasicDecode, exec_template_base = ''):
6532075SN/A    # Make sure flags are in lists (convert to lists if not).
6542075SN/A    mem_flags = makeList(mem_flags)
6552075SN/A    inst_flags = makeList(inst_flags)
6562068SN/A
6572068SN/A    # add hook to get effective addresses into execution trace output.
6582068SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
6592068SN/A
6602068SN/A    # Some CPU models execute the memory operation as an atomic unit,
6612068SN/A    # while others want to separate them into an effective address
6622068SN/A    # computation and a memory access operation.  As a result, we need
6632068SN/A    # to generate three StaticInst objects.  Note that the latter two
6642068SN/A    # are nested inside the larger "atomic" one.
6652068SN/A
6663953Sstever@eecs.umich.edu    # Generate InstObjParams for each of the three objects.  Note that
6673953Sstever@eecs.umich.edu    # they differ only in the set of code objects contained (which in
6683953Sstever@eecs.umich.edu    # turn affects the object's overall operand list).
6693953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, base_class,
6703953Sstever@eecs.umich.edu                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
6713953Sstever@eecs.umich.edu                        inst_flags)
6723953Sstever@eecs.umich.edu    ea_iop = InstObjParams(name, Name, base_class,
6733953Sstever@eecs.umich.edu                        { 'ea_code':ea_code },
6743953Sstever@eecs.umich.edu                        inst_flags)
6753953Sstever@eecs.umich.edu    memacc_iop = InstObjParams(name, Name, base_class,
6763953Sstever@eecs.umich.edu                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
6773953Sstever@eecs.umich.edu                        inst_flags)
6782068SN/A
6792068SN/A    if mem_flags:
6802068SN/A        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
6812068SN/A        iop.constructor += s
6822068SN/A        memacc_iop.constructor += s
6832068SN/A
6842069SN/A    # select templates
6852623SN/A
6864027Sstever@eecs.umich.edu    # The InitiateAcc template is the same for StoreCond templates as the
6874027Sstever@eecs.umich.edu    # corresponding Store template..
6882623SN/A    StoreCondInitiateAcc = StoreInitiateAcc
6892623SN/A
6902069SN/A    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
6912069SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
6922095SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
6932095SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
6942069SN/A
6952068SN/A    # (header_output, decoder_output, decode_block, exec_output)
6963953Sstever@eecs.umich.edu    return (LoadStoreDeclare.subst(iop),
6973953Sstever@eecs.umich.edu            EACompConstructor.subst(ea_iop)
6983953Sstever@eecs.umich.edu            + MemAccConstructor.subst(memacc_iop)
6993953Sstever@eecs.umich.edu            + LoadStoreConstructor.subst(iop),
7002068SN/A            decode_template.subst(iop),
7012068SN/A            EACompExecute.subst(ea_iop)
7022069SN/A            + memAccExecTemplate.subst(memacc_iop)
7032095SN/A            + fullExecTemplate.subst(iop)
7043953Sstever@eecs.umich.edu            + initiateAccTemplate.subst(iop)
7053953Sstever@eecs.umich.edu            + completeAccTemplate.subst(iop))
7062068SN/A}};
7072068SN/A
7082075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
7092075SN/A                     mem_flags = [], inst_flags = []) {{
7102068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7112075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7122069SN/A                      decode_template = LoadNopCheckDecode,
7132069SN/A                      exec_template_base = 'Load')
7142068SN/A}};
7152068SN/A
7162068SN/A
7172068SN/A// Note that the flags passed in apply only to the prefetch version
7182075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
7192075SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
7202068SN/A    # declare the load instruction object and generate the decode block
7212068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7222075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7232069SN/A                      decode_template = LoadPrefetchCheckDecode,
7242069SN/A                      exec_template_base = 'Load')
7252068SN/A
7262068SN/A    # Declare the prefetch instruction object.
7272068SN/A
7282075SN/A    # Make sure flag args are lists so we can mess with them.
7292075SN/A    mem_flags = makeList(mem_flags)
7302075SN/A    pf_flags = makeList(pf_flags)
7312075SN/A    inst_flags = makeList(inst_flags)
7322075SN/A
7332075SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
7342075SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
7352075SN/A                                  'IsDataPrefetch', 'MemReadOp']
7362068SN/A
7372068SN/A    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
7382069SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
7392069SN/A                      'xc->prefetch(EA, memAccessFlags);',
7402075SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
7412068SN/A
7422068SN/A    header_output += pf_header_output
7432068SN/A    decoder_output += pf_decoder_output
7442068SN/A    exec_output += pf_exec_output
7452068SN/A}};
7462068SN/A
7472068SN/A
7482075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
7492075SN/A                 mem_flags = [], inst_flags = []) {{
7502068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7512075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7522069SN/A                      exec_template_base = 'Store')
7532068SN/A}};
7542068SN/A
7552068SN/A
7562075SN/Adef format StoreCond(memacc_code, postacc_code,
7572075SN/A                     ea_code = {{ EA = Rb + disp; }},
7582075SN/A                     mem_flags = [], inst_flags = []) {{
7592068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7602075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7612623SN/A                      postacc_code, exec_template_base = 'StoreCond')
7622068SN/A}};
7632068SN/A
7642068SN/A
7652068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
7662075SN/Adef format MiscPrefetch(ea_code, memacc_code,
7672075SN/A                        mem_flags = [], inst_flags = []) {{
7682068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7692075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7702069SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
7712068SN/A}};
7722068SN/A
7732068SN/A
774