mem.isa revision 4040
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;
3532069SN/A        uint64_t write_result = 0;
3542069SN/A
3552069SN/A        %(fp_enable_check)s;
3562069SN/A        %(op_decl)s;
3572069SN/A        %(op_rd)s;
3582069SN/A        EA = xc->getEA();
3592069SN/A
3602090SN/A        if (fault == NoFault) {
3613953Sstever@eecs.umich.edu            %(memacc_code)s;
3622069SN/A        }
3632069SN/A
3642090SN/A        if (fault == NoFault) {
3652069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3662069SN/A                              memAccessFlags, &write_result);
3672069SN/A            if (traceData) { traceData->setData(Mem); }
3682068SN/A        }
3692068SN/A
3702090SN/A        if (fault == NoFault) {
3712068SN/A            %(postacc_code)s;
3722068SN/A        }
3732068SN/A
3742090SN/A        if (fault == NoFault) {
3752069SN/A            %(op_wb)s;
3762068SN/A        }
3772068SN/A
3782068SN/A        return fault;
3792068SN/A    }
3802068SN/A}};
3812068SN/A
3822068SN/A
3832069SN/Adef template StoreExecute {{
3842132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3852069SN/A                                  Trace::InstRecord *traceData) const
3862069SN/A    {
3872069SN/A        Addr EA;
3882132SN/A        Fault fault = NoFault;
3892069SN/A        uint64_t write_result = 0;
3902069SN/A
3912069SN/A        %(fp_enable_check)s;
3922069SN/A        %(op_decl)s;
3932069SN/A        %(op_rd)s;
3942069SN/A        %(ea_code)s;
3952069SN/A
3962090SN/A        if (fault == NoFault) {
3972069SN/A            %(memacc_code)s;
3982069SN/A        }
3992069SN/A
4002090SN/A        if (fault == NoFault) {
4012069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4022069SN/A                              memAccessFlags, &write_result);
4032069SN/A            if (traceData) { traceData->setData(Mem); }
4042069SN/A        }
4052069SN/A
4062090SN/A        if (fault == NoFault) {
4072069SN/A            %(postacc_code)s;
4082069SN/A        }
4092069SN/A
4102090SN/A        if (fault == NoFault) {
4112069SN/A            %(op_wb)s;
4122069SN/A        }
4132069SN/A
4142069SN/A        return fault;
4152069SN/A    }
4162069SN/A}};
4172069SN/A
4182095SN/Adef template StoreInitiateAcc {{
4192132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4202095SN/A                                      Trace::InstRecord *traceData) const
4212095SN/A    {
4222095SN/A        Addr EA;
4232132SN/A        Fault fault = NoFault;
4242095SN/A
4252095SN/A        %(fp_enable_check)s;
4262506SN/A        %(op_decl)s;
4272095SN/A        %(op_rd)s;
4282095SN/A        %(ea_code)s;
4292095SN/A
4302098SN/A        if (fault == NoFault) {
4312095SN/A            %(memacc_code)s;
4322095SN/A        }
4332095SN/A
4342098SN/A        if (fault == NoFault) {
4352095SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4362623SN/A                              memAccessFlags, NULL);
4372095SN/A            if (traceData) { traceData->setData(Mem); }
4382095SN/A        }
4392095SN/A
4402095SN/A        return fault;
4412095SN/A    }
4422095SN/A}};
4432095SN/A
4442095SN/A
4452095SN/Adef template StoreCompleteAcc {{
4463349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4472095SN/A                                      %(CPU_exec_context)s *xc,
4482095SN/A                                      Trace::InstRecord *traceData) const
4492095SN/A    {
4502132SN/A        Fault fault = NoFault;
4512095SN/A
4522095SN/A        %(fp_enable_check)s;
4532095SN/A        %(op_dest_decl)s;
4542095SN/A
4552623SN/A        if (fault == NoFault) {
4562623SN/A            %(postacc_code)s;
4572623SN/A        }
4582623SN/A
4592623SN/A        if (fault == NoFault) {
4602623SN/A            %(op_wb)s;
4612623SN/A        }
4622623SN/A
4632623SN/A        return fault;
4642623SN/A    }
4652623SN/A}};
4662623SN/A
4672623SN/A
4682623SN/Adef template StoreCondCompleteAcc {{
4693349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4702623SN/A                                      %(CPU_exec_context)s *xc,
4712623SN/A                                      Trace::InstRecord *traceData) const
4722623SN/A    {
4732623SN/A        Fault fault = NoFault;
4742623SN/A
4752623SN/A        %(fp_enable_check)s;
4762623SN/A        %(op_dest_decl)s;
4772623SN/A
4784040Ssaidi@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
4792095SN/A
4802098SN/A        if (fault == NoFault) {
4812095SN/A            %(postacc_code)s;
4822095SN/A        }
4832095SN/A
4842098SN/A        if (fault == NoFault) {
4852095SN/A            %(op_wb)s;
4862095SN/A        }
4872095SN/A
4882095SN/A        return fault;
4892095SN/A    }
4902095SN/A}};
4912095SN/A
4922069SN/A
4932069SN/Adef template MiscMemAccExecute {{
4942132SN/A    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4952069SN/A                                          Trace::InstRecord *traceData) const
4962069SN/A    {
4972069SN/A        Addr EA;
4982132SN/A        Fault fault = NoFault;
4992069SN/A
5002069SN/A        %(fp_enable_check)s;
5012069SN/A        %(op_decl)s;
5022069SN/A        %(op_rd)s;
5032069SN/A        EA = xc->getEA();
5042069SN/A
5052090SN/A        if (fault == NoFault) {
5063953Sstever@eecs.umich.edu            %(memacc_code)s;
5072069SN/A        }
5082069SN/A
5092090SN/A        return NoFault;
5102069SN/A    }
5112069SN/A}};
5122069SN/A
5132069SN/Adef template MiscExecute {{
5142132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5152068SN/A                                  Trace::InstRecord *traceData) const
5162068SN/A    {
5172068SN/A        Addr EA;
5182132SN/A        Fault fault = NoFault;
5192068SN/A
5202068SN/A        %(fp_enable_check)s;
5212068SN/A        %(op_decl)s;
5222069SN/A        %(op_rd)s;
5232068SN/A        %(ea_code)s;
5242068SN/A
5252090SN/A        if (fault == NoFault) {
5262069SN/A            %(memacc_code)s;
5272068SN/A        }
5282068SN/A
5292090SN/A        return NoFault;
5302068SN/A    }
5312068SN/A}};
5322068SN/A
5332095SN/Adef template MiscInitiateAcc {{
5342132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5352095SN/A                                      Trace::InstRecord *traceData) const
5362095SN/A    {
5372355SN/A        warn("Misc instruction does not support split access method!");
5382098SN/A        return NoFault;
5392095SN/A    }
5402095SN/A}};
5412095SN/A
5422095SN/A
5432095SN/Adef template MiscCompleteAcc {{
5443349Sbinkertn@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5452095SN/A                                      %(CPU_exec_context)s *xc,
5462095SN/A                                      Trace::InstRecord *traceData) const
5472095SN/A    {
5482355SN/A        warn("Misc instruction does not support split access method!");
5492110SN/A
5502098SN/A        return NoFault;
5512095SN/A    }
5522095SN/A}};
5532095SN/A
5542068SN/A// load instructions use Ra as dest, so check for
5552068SN/A// Ra == 31 to detect nops
5562068SN/Adef template LoadNopCheckDecode {{
5572068SN/A {
5582068SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
5592068SN/A     if (RA == 31) {
5602068SN/A         i = makeNop(i);
5612068SN/A     }
5622068SN/A     return i;
5632068SN/A }
5642068SN/A}};
5652068SN/A
5662068SN/A
5672068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
5682068SN/Adef template LoadPrefetchCheckDecode {{
5692068SN/A {
5702068SN/A     if (RA != 31) {
5712068SN/A         return new %(class_name)s(machInst);
5722068SN/A     }
5732068SN/A     else {
5742068SN/A         return new %(class_name)sPrefetch(machInst);
5752068SN/A     }
5762068SN/A }
5772068SN/A}};
5782068SN/A
5792068SN/A
5802068SN/Alet {{
5812075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5822075SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
5832069SN/A                  decode_template = BasicDecode, exec_template_base = ''):
5842075SN/A    # Make sure flags are in lists (convert to lists if not).
5852075SN/A    mem_flags = makeList(mem_flags)
5862075SN/A    inst_flags = makeList(inst_flags)
5872068SN/A
5882068SN/A    # add hook to get effective addresses into execution trace output.
5892068SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5902068SN/A
5912068SN/A    # Some CPU models execute the memory operation as an atomic unit,
5922068SN/A    # while others want to separate them into an effective address
5932068SN/A    # computation and a memory access operation.  As a result, we need
5942068SN/A    # to generate three StaticInst objects.  Note that the latter two
5952068SN/A    # are nested inside the larger "atomic" one.
5962068SN/A
5973953Sstever@eecs.umich.edu    # Generate InstObjParams for each of the three objects.  Note that
5983953Sstever@eecs.umich.edu    # they differ only in the set of code objects contained (which in
5993953Sstever@eecs.umich.edu    # turn affects the object's overall operand list).
6003953Sstever@eecs.umich.edu    iop = InstObjParams(name, Name, base_class,
6013953Sstever@eecs.umich.edu                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
6023953Sstever@eecs.umich.edu                        inst_flags)
6033953Sstever@eecs.umich.edu    ea_iop = InstObjParams(name, Name, base_class,
6043953Sstever@eecs.umich.edu                        { 'ea_code':ea_code },
6053953Sstever@eecs.umich.edu                        inst_flags)
6063953Sstever@eecs.umich.edu    memacc_iop = InstObjParams(name, Name, base_class,
6073953Sstever@eecs.umich.edu                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
6083953Sstever@eecs.umich.edu                        inst_flags)
6092068SN/A
6102068SN/A    if mem_flags:
6112068SN/A        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
6122068SN/A        iop.constructor += s
6132068SN/A        memacc_iop.constructor += s
6142068SN/A
6152069SN/A    # select templates
6162623SN/A
6172623SN/A    # define aliases... most StoreCond templates are the same as the
6182623SN/A    # corresponding Store templates (only CompleteAcc is different).
6192623SN/A    StoreCondMemAccExecute = StoreMemAccExecute
6202623SN/A    StoreCondExecute = StoreExecute
6212623SN/A    StoreCondInitiateAcc = StoreInitiateAcc
6222623SN/A
6232069SN/A    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
6242069SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
6252095SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
6262095SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
6272069SN/A
6282068SN/A    # (header_output, decoder_output, decode_block, exec_output)
6293953Sstever@eecs.umich.edu    return (LoadStoreDeclare.subst(iop),
6303953Sstever@eecs.umich.edu            EACompConstructor.subst(ea_iop)
6313953Sstever@eecs.umich.edu            + MemAccConstructor.subst(memacc_iop)
6323953Sstever@eecs.umich.edu            + LoadStoreConstructor.subst(iop),
6332068SN/A            decode_template.subst(iop),
6342068SN/A            EACompExecute.subst(ea_iop)
6352069SN/A            + memAccExecTemplate.subst(memacc_iop)
6362095SN/A            + fullExecTemplate.subst(iop)
6373953Sstever@eecs.umich.edu            + initiateAccTemplate.subst(iop)
6383953Sstever@eecs.umich.edu            + completeAccTemplate.subst(iop))
6392068SN/A}};
6402068SN/A
6412075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
6422075SN/A                     mem_flags = [], inst_flags = []) {{
6432068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6442075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6452069SN/A                      decode_template = LoadNopCheckDecode,
6462069SN/A                      exec_template_base = 'Load')
6472068SN/A}};
6482068SN/A
6492068SN/A
6502068SN/A// Note that the flags passed in apply only to the prefetch version
6512075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
6522075SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
6532068SN/A    # declare the load instruction object and generate the decode block
6542068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6552075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6562069SN/A                      decode_template = LoadPrefetchCheckDecode,
6572069SN/A                      exec_template_base = 'Load')
6582068SN/A
6592068SN/A    # Declare the prefetch instruction object.
6602068SN/A
6612075SN/A    # Make sure flag args are lists so we can mess with them.
6622075SN/A    mem_flags = makeList(mem_flags)
6632075SN/A    pf_flags = makeList(pf_flags)
6642075SN/A    inst_flags = makeList(inst_flags)
6652075SN/A
6662075SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
6672075SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
6682075SN/A                                  'IsDataPrefetch', 'MemReadOp']
6692068SN/A
6702068SN/A    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
6712069SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
6722069SN/A                      'xc->prefetch(EA, memAccessFlags);',
6732075SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
6742068SN/A
6752068SN/A    header_output += pf_header_output
6762068SN/A    decoder_output += pf_decoder_output
6772068SN/A    exec_output += pf_exec_output
6782068SN/A}};
6792068SN/A
6802068SN/A
6812075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
6822075SN/A                 mem_flags = [], inst_flags = []) {{
6832068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6842075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6852069SN/A                      exec_template_base = 'Store')
6862068SN/A}};
6872068SN/A
6882068SN/A
6892075SN/Adef format StoreCond(memacc_code, postacc_code,
6902075SN/A                     ea_code = {{ EA = Rb + disp; }},
6912075SN/A                     mem_flags = [], inst_flags = []) {{
6922068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6932075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6942623SN/A                      postacc_code, exec_template_base = 'StoreCond')
6952068SN/A}};
6962068SN/A
6972068SN/A
6982068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
6992075SN/Adef format MiscPrefetch(ea_code, memacc_code,
7002075SN/A                        mem_flags = [], inst_flags = []) {{
7012068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7022075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7032069SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
7042068SN/A}};
7052068SN/A
7062068SN/A
707