mem.isa revision 6179
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        /// 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),
575736Snate@binkert.org              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; }
686179Sksewell@umich.edu
696179Sksewell@umich.edu        Request::Flags memAccFlags() { return memAccessFlags; }
702068SN/A    };
712068SN/A
722068SN/A    /**
732068SN/A     * Base class for memory-format instructions using a 32-bit
742068SN/A     * displacement (i.e. most of them).
752068SN/A     */
762068SN/A    class MemoryDisp32 : public Memory
772068SN/A    {
782068SN/A      protected:
792068SN/A        /// Displacement for EA calculation (signed).
802068SN/A        int32_t disp;
812068SN/A
822068SN/A        /// Constructor.
832227SN/A        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
842107SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
852107SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
862068SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
872068SN/A              disp(MEMDISP)
882068SN/A        {
892068SN/A        }
902068SN/A    };
912068SN/A
922068SN/A
932068SN/A    /**
942068SN/A     * Base class for a few miscellaneous memory-format insts
952068SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
962068SN/A     * None of these instructions has a destination register either.
972068SN/A     */
982068SN/A    class MemoryNoDisp : public Memory
992068SN/A    {
1002068SN/A      protected:
1012068SN/A        /// Constructor
1022227SN/A        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1032107SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
1042107SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
1052068SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
1062068SN/A        {
1072068SN/A        }
1082068SN/A
1092068SN/A        std::string
1102068SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1112068SN/A    };
1122068SN/A}};
1132068SN/A
1142068SN/A
1152068SN/Aoutput decoder {{
1162068SN/A    std::string
1172068SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1182068SN/A    {
1192068SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1202068SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1212068SN/A    }
1222068SN/A
1232068SN/A    std::string
1242068SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1252068SN/A    {
1262068SN/A        return csprintf("%-10s (r%d)", mnemonic, RB);
1272068SN/A    }
1282068SN/A}};
1292068SN/A
1302068SN/Adef format LoadAddress(code) {{
1313953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1322068SN/A    header_output = BasicDeclare.subst(iop)
1332068SN/A    decoder_output = BasicConstructor.subst(iop)
1342068SN/A    decode_block = BasicDecode.subst(iop)
1352068SN/A    exec_output = BasicExecute.subst(iop)
1362068SN/A}};
1372068SN/A
1382068SN/A
1392068SN/Adef template LoadStoreDeclare {{
1402068SN/A    /**
1412068SN/A     * Static instruction class for "%(mnemonic)s".
1422068SN/A     */
1432068SN/A    class %(class_name)s : public %(base_class)s
1442068SN/A    {
1452068SN/A      protected:
1462068SN/A
1472068SN/A        /**
1482068SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1492068SN/A         */
1502068SN/A        class EAComp : public %(base_class)s
1512068SN/A        {
1522068SN/A          public:
1532068SN/A            /// Constructor
1542227SN/A            EAComp(ExtMachInst machInst);
1552068SN/A
1562068SN/A            %(BasicExecDeclare)s
1572068SN/A        };
1582068SN/A
1592068SN/A        /**
1602068SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1612068SN/A         */
1622068SN/A        class MemAcc : public %(base_class)s
1632068SN/A        {
1642068SN/A          public:
1652068SN/A            /// Constructor
1662227SN/A            MemAcc(ExtMachInst machInst);
1672068SN/A
1682068SN/A            %(BasicExecDeclare)s
1692068SN/A        };
1702068SN/A
1712068SN/A      public:
1722068SN/A
1732068SN/A        /// Constructor.
1742227SN/A        %(class_name)s(ExtMachInst machInst);
1752068SN/A
1762068SN/A        %(BasicExecDeclare)s
1772095SN/A
1782095SN/A        %(InitiateAccDeclare)s
1792095SN/A
1802095SN/A        %(CompleteAccDeclare)s
1816179Sksewell@umich.edu
1826179Sksewell@umich.edu        %(MemAccSizeDeclare)s
1832068SN/A    };
1842068SN/A}};
1852068SN/A
1862095SN/A
1872095SN/Adef template InitiateAccDeclare {{
1882132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1892095SN/A}};
1902095SN/A
1912095SN/A
1922095SN/Adef template CompleteAccDeclare {{
1933349Sbinkertn@umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1942623SN/A                      Trace::InstRecord *) const;
1952095SN/A}};
1962095SN/A
1976179Sksewell@umich.edudef template MemAccSizeDeclare {{
1986179Sksewell@umich.edu    int memAccSize(%(CPU_exec_context)s *xc);
1996179Sksewell@umich.edu}};
2006179Sksewell@umich.edu
2016179Sksewell@umich.edudef template MiscMemAccSize {{
2026179Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
2036179Sksewell@umich.edu    {
2046179Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
2056179Sksewell@umich.edu        return 0;
2066179Sksewell@umich.edu    }
2076179Sksewell@umich.edu}};
2086179Sksewell@umich.edu
2096179Sksewell@umich.edudef template LoadStoreMemAccSize {{
2106179Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
2116179Sksewell@umich.edu    {
2126179Sksewell@umich.edu        // Return the memory access size in bytes
2136179Sksewell@umich.edu        return (%(mem_acc_size)d / 8);
2146179Sksewell@umich.edu    }
2156179Sksewell@umich.edu}};
2162095SN/A
2173953Sstever@eecs.umich.edudef template EACompConstructor {{
2182068SN/A    /** TODO: change op_class to AddrGenOp or something (requires
2192068SN/A     * creating new member of OpClass enum in op_class.hh, updating
2202068SN/A     * config files, etc.). */
2212227SN/A    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
2222068SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2232068SN/A    {
2243953Sstever@eecs.umich.edu        %(constructor)s;
2252068SN/A    }
2263953Sstever@eecs.umich.edu}};
2272068SN/A
2283953Sstever@eecs.umich.edu
2293953Sstever@eecs.umich.edudef template MemAccConstructor {{
2302227SN/A    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2312068SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2322068SN/A    {
2333953Sstever@eecs.umich.edu        %(constructor)s;
2342068SN/A    }
2353953Sstever@eecs.umich.edu}};
2362068SN/A
2373953Sstever@eecs.umich.edu
2383953Sstever@eecs.umich.edudef template LoadStoreConstructor {{
2392227SN/A    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2402068SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2412068SN/A                          new EAComp(machInst), new MemAcc(machInst))
2422068SN/A    {
2432068SN/A        %(constructor)s;
2442068SN/A    }
2452068SN/A}};
2462068SN/A
2472068SN/A
2482068SN/Adef template EACompExecute {{
2492132SN/A    Fault
2502068SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2512068SN/A                                   Trace::InstRecord *traceData) const
2522068SN/A    {
2532068SN/A        Addr EA;
2542132SN/A        Fault fault = NoFault;
2552068SN/A
2562068SN/A        %(fp_enable_check)s;
2572068SN/A        %(op_decl)s;
2582068SN/A        %(op_rd)s;
2593953Sstever@eecs.umich.edu        %(ea_code)s;
2602068SN/A
2612090SN/A        if (fault == NoFault) {
2622068SN/A            %(op_wb)s;
2632068SN/A            xc->setEA(EA);
2642068SN/A        }
2652068SN/A
2662068SN/A        return fault;
2672068SN/A    }
2682068SN/A}};
2692068SN/A
2702069SN/Adef template LoadMemAccExecute {{
2712132SN/A    Fault
2722068SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2732068SN/A                                   Trace::InstRecord *traceData) const
2742068SN/A    {
2752068SN/A        Addr EA;
2762132SN/A        Fault fault = NoFault;
2772068SN/A
2782068SN/A        %(fp_enable_check)s;
2792068SN/A        %(op_decl)s;
2802069SN/A        %(op_rd)s;
2812068SN/A        EA = xc->getEA();
2822068SN/A
2832090SN/A        if (fault == NoFault) {
2842069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2853953Sstever@eecs.umich.edu            %(memacc_code)s;
2862068SN/A        }
2872068SN/A
2882090SN/A        if (fault == NoFault) {
2892069SN/A            %(op_wb)s;
2902068SN/A        }
2912068SN/A
2922068SN/A        return fault;
2932068SN/A    }
2942068SN/A}};
2952068SN/A
2962068SN/A
2972069SN/Adef template LoadExecute {{
2982132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2992068SN/A                                  Trace::InstRecord *traceData) const
3002068SN/A    {
3012068SN/A        Addr EA;
3022132SN/A        Fault fault = NoFault;
3032068SN/A
3042068SN/A        %(fp_enable_check)s;
3052068SN/A        %(op_decl)s;
3062069SN/A        %(op_rd)s;
3072068SN/A        %(ea_code)s;
3082068SN/A
3092090SN/A        if (fault == NoFault) {
3102069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
3112068SN/A            %(memacc_code)s;
3122068SN/A        }
3132068SN/A
3142090SN/A        if (fault == NoFault) {
3152069SN/A            %(op_wb)s;
3162069SN/A        }
3172069SN/A
3182069SN/A        return fault;
3192069SN/A    }
3202069SN/A}};
3212069SN/A
3222069SN/A
3232095SN/Adef template LoadInitiateAcc {{
3242132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3252095SN/A                                      Trace::InstRecord *traceData) const
3262095SN/A    {
3272095SN/A        Addr EA;
3282132SN/A        Fault fault = NoFault;
3292095SN/A
3302095SN/A        %(fp_enable_check)s;
3312095SN/A        %(op_src_decl)s;
3322095SN/A        %(op_rd)s;
3332095SN/A        %(ea_code)s;
3342095SN/A
3352098SN/A        if (fault == NoFault) {
3362095SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3372095SN/A        }
3382095SN/A
3392095SN/A        return fault;
3402095SN/A    }
3412095SN/A}};
3422095SN/A
3432095SN/A
3442095SN/Adef template LoadCompleteAcc {{
3453349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3462095SN/A                                      %(CPU_exec_context)s *xc,
3472095SN/A                                      Trace::InstRecord *traceData) const
3482095SN/A    {
3492132SN/A        Fault fault = NoFault;
3502095SN/A
3512095SN/A        %(fp_enable_check)s;
3522506SN/A        %(op_decl)s;
3532095SN/A
3542623SN/A        Mem = pkt->get<typeof(Mem)>();
3552095SN/A
3562098SN/A        if (fault == NoFault) {
3572095SN/A            %(memacc_code)s;
3582095SN/A        }
3592095SN/A
3602098SN/A        if (fault == NoFault) {
3612095SN/A            %(op_wb)s;
3622095SN/A        }
3632095SN/A
3642095SN/A        return fault;
3652095SN/A    }
3662095SN/A}};
3672095SN/A
3682095SN/A
3692069SN/Adef template StoreMemAccExecute {{
3702132SN/A    Fault
3712069SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3722069SN/A                                   Trace::InstRecord *traceData) const
3732069SN/A    {
3742069SN/A        Addr EA;
3752132SN/A        Fault fault = NoFault;
3764027Sstever@eecs.umich.edu
3774027Sstever@eecs.umich.edu        %(fp_enable_check)s;
3784027Sstever@eecs.umich.edu        %(op_decl)s;
3794027Sstever@eecs.umich.edu        %(op_rd)s;
3804027Sstever@eecs.umich.edu        EA = xc->getEA();
3814027Sstever@eecs.umich.edu
3824027Sstever@eecs.umich.edu        if (fault == NoFault) {
3834027Sstever@eecs.umich.edu            %(memacc_code)s;
3844027Sstever@eecs.umich.edu        }
3854027Sstever@eecs.umich.edu
3864027Sstever@eecs.umich.edu        if (fault == NoFault) {
3874027Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3884027Sstever@eecs.umich.edu                              memAccessFlags, NULL);
3894027Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
3904027Sstever@eecs.umich.edu        }
3914027Sstever@eecs.umich.edu
3924027Sstever@eecs.umich.edu        if (fault == NoFault) {
3934027Sstever@eecs.umich.edu            %(postacc_code)s;
3944027Sstever@eecs.umich.edu        }
3954027Sstever@eecs.umich.edu
3964027Sstever@eecs.umich.edu        if (fault == NoFault) {
3974027Sstever@eecs.umich.edu            %(op_wb)s;
3984027Sstever@eecs.umich.edu        }
3994027Sstever@eecs.umich.edu
4004027Sstever@eecs.umich.edu        return fault;
4014027Sstever@eecs.umich.edu    }
4024027Sstever@eecs.umich.edu}};
4034027Sstever@eecs.umich.edu
4044027Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{
4054027Sstever@eecs.umich.edu    Fault
4064027Sstever@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4074027Sstever@eecs.umich.edu                                   Trace::InstRecord *traceData) const
4084027Sstever@eecs.umich.edu    {
4094027Sstever@eecs.umich.edu        Addr EA;
4104027Sstever@eecs.umich.edu        Fault fault = NoFault;
4112069SN/A        uint64_t write_result = 0;
4122069SN/A
4132069SN/A        %(fp_enable_check)s;
4142069SN/A        %(op_decl)s;
4152069SN/A        %(op_rd)s;
4162069SN/A        EA = xc->getEA();
4172069SN/A
4182090SN/A        if (fault == NoFault) {
4193953Sstever@eecs.umich.edu            %(memacc_code)s;
4202069SN/A        }
4212069SN/A
4222090SN/A        if (fault == NoFault) {
4232069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4242069SN/A                              memAccessFlags, &write_result);
4252069SN/A            if (traceData) { traceData->setData(Mem); }
4262068SN/A        }
4272068SN/A
4282090SN/A        if (fault == NoFault) {
4292068SN/A            %(postacc_code)s;
4302068SN/A        }
4312068SN/A
4322090SN/A        if (fault == NoFault) {
4332069SN/A            %(op_wb)s;
4342068SN/A        }
4352068SN/A
4362068SN/A        return fault;
4372068SN/A    }
4382068SN/A}};
4392068SN/A
4402068SN/A
4412069SN/Adef template StoreExecute {{
4422132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4432069SN/A                                  Trace::InstRecord *traceData) const
4442069SN/A    {
4452069SN/A        Addr EA;
4462132SN/A        Fault fault = NoFault;
4474027Sstever@eecs.umich.edu
4484027Sstever@eecs.umich.edu        %(fp_enable_check)s;
4494027Sstever@eecs.umich.edu        %(op_decl)s;
4504027Sstever@eecs.umich.edu        %(op_rd)s;
4514027Sstever@eecs.umich.edu        %(ea_code)s;
4524027Sstever@eecs.umich.edu
4534027Sstever@eecs.umich.edu        if (fault == NoFault) {
4544027Sstever@eecs.umich.edu            %(memacc_code)s;
4554027Sstever@eecs.umich.edu        }
4564027Sstever@eecs.umich.edu
4574027Sstever@eecs.umich.edu        if (fault == NoFault) {
4584027Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4594027Sstever@eecs.umich.edu                              memAccessFlags, NULL);
4604027Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
4614027Sstever@eecs.umich.edu        }
4624027Sstever@eecs.umich.edu
4634027Sstever@eecs.umich.edu        if (fault == NoFault) {
4644027Sstever@eecs.umich.edu            %(postacc_code)s;
4654027Sstever@eecs.umich.edu        }
4664027Sstever@eecs.umich.edu
4674027Sstever@eecs.umich.edu        if (fault == NoFault) {
4684027Sstever@eecs.umich.edu            %(op_wb)s;
4694027Sstever@eecs.umich.edu        }
4704027Sstever@eecs.umich.edu
4714027Sstever@eecs.umich.edu        return fault;
4724027Sstever@eecs.umich.edu    }
4734027Sstever@eecs.umich.edu}};
4744027Sstever@eecs.umich.edu
4754027Sstever@eecs.umich.edudef template StoreCondExecute {{
4764027Sstever@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4774027Sstever@eecs.umich.edu                                  Trace::InstRecord *traceData) const
4784027Sstever@eecs.umich.edu    {
4794027Sstever@eecs.umich.edu        Addr EA;
4804027Sstever@eecs.umich.edu        Fault fault = NoFault;
4812069SN/A        uint64_t write_result = 0;
4822069SN/A
4832069SN/A        %(fp_enable_check)s;
4842069SN/A        %(op_decl)s;
4852069SN/A        %(op_rd)s;
4862069SN/A        %(ea_code)s;
4872069SN/A
4882090SN/A        if (fault == NoFault) {
4892069SN/A            %(memacc_code)s;
4902069SN/A        }
4912069SN/A
4922090SN/A        if (fault == NoFault) {
4932069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4942069SN/A                              memAccessFlags, &write_result);
4952069SN/A            if (traceData) { traceData->setData(Mem); }
4962069SN/A        }
4972069SN/A
4982090SN/A        if (fault == NoFault) {
4992069SN/A            %(postacc_code)s;
5002069SN/A        }
5012069SN/A
5022090SN/A        if (fault == NoFault) {
5032069SN/A            %(op_wb)s;
5042069SN/A        }
5052069SN/A
5062069SN/A        return fault;
5072069SN/A    }
5082069SN/A}};
5092069SN/A
5102095SN/Adef template StoreInitiateAcc {{
5112132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5122095SN/A                                      Trace::InstRecord *traceData) const
5132095SN/A    {
5142095SN/A        Addr EA;
5152132SN/A        Fault fault = NoFault;
5162095SN/A
5172095SN/A        %(fp_enable_check)s;
5182506SN/A        %(op_decl)s;
5192095SN/A        %(op_rd)s;
5202095SN/A        %(ea_code)s;
5212095SN/A
5222098SN/A        if (fault == NoFault) {
5232095SN/A            %(memacc_code)s;
5242095SN/A        }
5252095SN/A
5262098SN/A        if (fault == NoFault) {
5272095SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5282623SN/A                              memAccessFlags, NULL);
5292095SN/A            if (traceData) { traceData->setData(Mem); }
5302095SN/A        }
5312095SN/A
5322095SN/A        return fault;
5332095SN/A    }
5342095SN/A}};
5352095SN/A
5362095SN/A
5372095SN/Adef template StoreCompleteAcc {{
5383349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5392095SN/A                                      %(CPU_exec_context)s *xc,
5402095SN/A                                      Trace::InstRecord *traceData) const
5412095SN/A    {
5422132SN/A        Fault fault = NoFault;
5432095SN/A
5442095SN/A        %(fp_enable_check)s;
5452095SN/A        %(op_dest_decl)s;
5462095SN/A
5472623SN/A        if (fault == NoFault) {
5482623SN/A            %(postacc_code)s;
5492623SN/A        }
5502623SN/A
5512623SN/A        if (fault == NoFault) {
5522623SN/A            %(op_wb)s;
5532623SN/A        }
5542623SN/A
5552623SN/A        return fault;
5562623SN/A    }
5572623SN/A}};
5582623SN/A
5592623SN/A
5602623SN/Adef template StoreCondCompleteAcc {{
5613349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5622623SN/A                                      %(CPU_exec_context)s *xc,
5632623SN/A                                      Trace::InstRecord *traceData) const
5642623SN/A    {
5652623SN/A        Fault fault = NoFault;
5662623SN/A
5672623SN/A        %(fp_enable_check)s;
5682623SN/A        %(op_dest_decl)s;
5692623SN/A
5704040Ssaidi@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
5712095SN/A
5722098SN/A        if (fault == NoFault) {
5732095SN/A            %(postacc_code)s;
5742095SN/A        }
5752095SN/A
5762098SN/A        if (fault == NoFault) {
5772095SN/A            %(op_wb)s;
5782095SN/A        }
5792095SN/A
5802095SN/A        return fault;
5812095SN/A    }
5822095SN/A}};
5832095SN/A
5842069SN/A
5852069SN/Adef template MiscMemAccExecute {{
5862132SN/A    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
5872069SN/A                                          Trace::InstRecord *traceData) const
5882069SN/A    {
5892069SN/A        Addr EA;
5902132SN/A        Fault fault = NoFault;
5912069SN/A
5922069SN/A        %(fp_enable_check)s;
5932069SN/A        %(op_decl)s;
5942069SN/A        %(op_rd)s;
5952069SN/A        EA = xc->getEA();
5962069SN/A
5972090SN/A        if (fault == NoFault) {
5983953Sstever@eecs.umich.edu            %(memacc_code)s;
5992069SN/A        }
6002069SN/A
6012090SN/A        return NoFault;
6022069SN/A    }
6032069SN/A}};
6042069SN/A
6052069SN/Adef template MiscExecute {{
6062132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
6072068SN/A                                  Trace::InstRecord *traceData) const
6082068SN/A    {
6092068SN/A        Addr EA;
6102132SN/A        Fault fault = NoFault;
6112068SN/A
6122068SN/A        %(fp_enable_check)s;
6132068SN/A        %(op_decl)s;
6142069SN/A        %(op_rd)s;
6152068SN/A        %(ea_code)s;
6162068SN/A
6172090SN/A        if (fault == NoFault) {
6182069SN/A            %(memacc_code)s;
6192068SN/A        }
6202068SN/A
6212090SN/A        return NoFault;
6222068SN/A    }
6232068SN/A}};
6242068SN/A
6252095SN/Adef template MiscInitiateAcc {{
6262132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
6272095SN/A                                      Trace::InstRecord *traceData) const
6282095SN/A    {
6292355SN/A        warn("Misc instruction does not support split access method!");
6302098SN/A        return NoFault;
6312095SN/A    }
6322095SN/A}};
6332095SN/A
6342095SN/A
6352095SN/Adef template MiscCompleteAcc {{
6363349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
6372095SN/A                                      %(CPU_exec_context)s *xc,
6382095SN/A                                      Trace::InstRecord *traceData) const
6392095SN/A    {
6402355SN/A        warn("Misc instruction does not support split access method!");
6412110SN/A
6422098SN/A        return NoFault;
6432095SN/A    }
6442095SN/A}};
6452095SN/A
6466179Sksewell@umich.edudef template MiscMemAccSize {{
6476179Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
6486179Sksewell@umich.edu    {
6496179Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
6506179Sksewell@umich.edu        return 0;
6516179Sksewell@umich.edu    }
6526179Sksewell@umich.edu}};
6536179Sksewell@umich.edu
6542068SN/A// load instructions use Ra as dest, so check for
6552068SN/A// Ra == 31 to detect nops
6562068SN/Adef template LoadNopCheckDecode {{
6572068SN/A {
6582068SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
6592068SN/A     if (RA == 31) {
6602068SN/A         i = makeNop(i);
6612068SN/A     }
6622068SN/A     return i;
6632068SN/A }
6642068SN/A}};
6652068SN/A
6662068SN/A
6672068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
6682068SN/Adef template LoadPrefetchCheckDecode {{
6692068SN/A {
6702068SN/A     if (RA != 31) {
6712068SN/A         return new %(class_name)s(machInst);
6722068SN/A     }
6732068SN/A     else {
6742068SN/A         return new %(class_name)sPrefetch(machInst);
6752068SN/A     }
6762068SN/A }
6772068SN/A}};
6782068SN/A
6792068SN/A
6802068SN/Alet {{
6812075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6822075SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
6832069SN/A                  decode_template = BasicDecode, exec_template_base = ''):
6842075SN/A    # Make sure flags are in lists (convert to lists if not).
6852075SN/A    mem_flags = makeList(mem_flags)
6862075SN/A    inst_flags = makeList(inst_flags)
6872068SN/A
6882068SN/A    # add hook to get effective addresses into execution trace output.
6892068SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
6902068SN/A
6912068SN/A    # Some CPU models execute the memory operation as an atomic unit,
6922068SN/A    # while others want to separate them into an effective address
6932068SN/A    # computation and a memory access operation.  As a result, we need
6942068SN/A    # to generate three StaticInst objects.  Note that the latter two
6952068SN/A    # are nested inside the larger "atomic" one.
6962068SN/A
6973953Sstever@eecs.umich.edu    # Generate InstObjParams for each of the three objects.  Note that
6983953Sstever@eecs.umich.edu    # they differ only in the set of code objects contained (which in
6993953Sstever@eecs.umich.edu    # turn affects the object's overall operand list).
7003953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, base_class,
7013953Sstever@eecs.umich.edu                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
7023953Sstever@eecs.umich.edu                        inst_flags)
7033953Sstever@eecs.umich.edu    ea_iop = InstObjParams(name, Name, base_class,
7043953Sstever@eecs.umich.edu                        { 'ea_code':ea_code },
7053953Sstever@eecs.umich.edu                        inst_flags)
7063953Sstever@eecs.umich.edu    memacc_iop = InstObjParams(name, Name, base_class,
7073953Sstever@eecs.umich.edu                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
7083953Sstever@eecs.umich.edu                        inst_flags)
7092068SN/A
7102068SN/A    if mem_flags:
7115736Snate@binkert.org        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
7125745Snate@binkert.org        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
7132068SN/A        iop.constructor += s
7142068SN/A        memacc_iop.constructor += s
7152068SN/A
7162069SN/A    # select templates
7172623SN/A
7184027Sstever@eecs.umich.edu    # The InitiateAcc template is the same for StoreCond templates as the
7194027Sstever@eecs.umich.edu    # corresponding Store template..
7202623SN/A    StoreCondInitiateAcc = StoreInitiateAcc
7212623SN/A
7222069SN/A    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
7232069SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
7242095SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
7252095SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
7262069SN/A
7276179Sksewell@umich.edu    if (exec_template_base == 'Load' or exec_template_base == 'Store'):
7286179Sksewell@umich.edu      memAccSizeTemplate = eval('LoadStoreMemAccSize')
7296179Sksewell@umich.edu    else:
7306179Sksewell@umich.edu      memAccSizeTemplate = eval('MiscMemAccSize')
7316179Sksewell@umich.edu
7322068SN/A    # (header_output, decoder_output, decode_block, exec_output)
7333953Sstever@eecs.umich.edu    return (LoadStoreDeclare.subst(iop),
7343953Sstever@eecs.umich.edu            EACompConstructor.subst(ea_iop)
7353953Sstever@eecs.umich.edu            + MemAccConstructor.subst(memacc_iop)
7363953Sstever@eecs.umich.edu            + LoadStoreConstructor.subst(iop),
7372068SN/A            decode_template.subst(iop),
7382068SN/A            EACompExecute.subst(ea_iop)
7392069SN/A            + memAccExecTemplate.subst(memacc_iop)
7402095SN/A            + fullExecTemplate.subst(iop)
7413953Sstever@eecs.umich.edu            + initiateAccTemplate.subst(iop)
7426179Sksewell@umich.edu            + completeAccTemplate.subst(iop)
7436179Sksewell@umich.edu            + memAccSizeTemplate.subst(memacc_iop))
7442068SN/A}};
7452068SN/A
7462075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
7472075SN/A                     mem_flags = [], inst_flags = []) {{
7482068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7492075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7502069SN/A                      decode_template = LoadNopCheckDecode,
7512069SN/A                      exec_template_base = 'Load')
7522068SN/A}};
7532068SN/A
7542068SN/A
7552068SN/A// Note that the flags passed in apply only to the prefetch version
7562075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
7572075SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
7582068SN/A    # declare the load instruction object and generate the decode block
7592068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7602075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7612069SN/A                      decode_template = LoadPrefetchCheckDecode,
7622069SN/A                      exec_template_base = 'Load')
7632068SN/A
7642068SN/A    # Declare the prefetch instruction object.
7652068SN/A
7662075SN/A    # Make sure flag args are lists so we can mess with them.
7672075SN/A    mem_flags = makeList(mem_flags)
7682075SN/A    pf_flags = makeList(pf_flags)
7692075SN/A    inst_flags = makeList(inst_flags)
7702075SN/A
7712075SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
7722075SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
7732075SN/A                                  'IsDataPrefetch', 'MemReadOp']
7742068SN/A
7752068SN/A    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
7762069SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
7772069SN/A                      'xc->prefetch(EA, memAccessFlags);',
7782075SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
7792068SN/A
7802068SN/A    header_output += pf_header_output
7812068SN/A    decoder_output += pf_decoder_output
7822068SN/A    exec_output += pf_exec_output
7832068SN/A}};
7842068SN/A
7852068SN/A
7862075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
7872075SN/A                 mem_flags = [], inst_flags = []) {{
7882068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7892075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7902069SN/A                      exec_template_base = 'Store')
7912068SN/A}};
7922068SN/A
7932068SN/A
7942075SN/Adef format StoreCond(memacc_code, postacc_code,
7952075SN/A                     ea_code = {{ EA = Rb + disp; }},
7962075SN/A                     mem_flags = [], inst_flags = []) {{
7972068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7982075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7992623SN/A                      postacc_code, exec_template_base = 'StoreCond')
8002068SN/A}};
8012068SN/A
8022068SN/A
8032068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
8042075SN/Adef format MiscPrefetch(ea_code, memacc_code,
8052075SN/A                        mem_flags = [], inst_flags = []) {{
8062068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
8072075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8082069SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
8092068SN/A}};
8102068SN/A
8112068SN/A
812