mem.isa revision 2750
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) {{
1292068SN/A    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(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 {{
1892623SN/A    Fault completeAcc(Packet *, %(CPU_exec_context)s *,
1902623SN/A                      Trace::InstRecord *) const;
1912095SN/A}};
1922095SN/A
1932095SN/A
1942068SN/Adef template LoadStoreConstructor {{
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    {
2012068SN/A        %(ea_constructor)s;
2022068SN/A    }
2032068SN/A
2042227SN/A    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2052068SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2062068SN/A    {
2072068SN/A        %(memacc_constructor)s;
2082068SN/A    }
2092068SN/A
2102227SN/A    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2112068SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2122068SN/A                          new EAComp(machInst), new MemAcc(machInst))
2132068SN/A    {
2142068SN/A        %(constructor)s;
2152068SN/A    }
2162068SN/A}};
2172068SN/A
2182068SN/A
2192068SN/Adef template EACompExecute {{
2202132SN/A    Fault
2212068SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2222068SN/A                                   Trace::InstRecord *traceData) const
2232068SN/A    {
2242068SN/A        Addr EA;
2252132SN/A        Fault fault = NoFault;
2262068SN/A
2272068SN/A        %(fp_enable_check)s;
2282068SN/A        %(op_decl)s;
2292068SN/A        %(op_rd)s;
2302068SN/A        %(code)s;
2312068SN/A
2322090SN/A        if (fault == NoFault) {
2332068SN/A            %(op_wb)s;
2342068SN/A            xc->setEA(EA);
2352068SN/A        }
2362068SN/A
2372068SN/A        return fault;
2382068SN/A    }
2392068SN/A}};
2402068SN/A
2412069SN/Adef template LoadMemAccExecute {{
2422132SN/A    Fault
2432068SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2442068SN/A                                   Trace::InstRecord *traceData) const
2452068SN/A    {
2462068SN/A        Addr EA;
2472132SN/A        Fault fault = NoFault;
2482068SN/A
2492068SN/A        %(fp_enable_check)s;
2502068SN/A        %(op_decl)s;
2512069SN/A        %(op_rd)s;
2522068SN/A        EA = xc->getEA();
2532068SN/A
2542090SN/A        if (fault == NoFault) {
2552069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2562068SN/A            %(code)s;
2572068SN/A        }
2582068SN/A
2592090SN/A        if (fault == NoFault) {
2602069SN/A            %(op_wb)s;
2612068SN/A        }
2622068SN/A
2632068SN/A        return fault;
2642068SN/A    }
2652068SN/A}};
2662068SN/A
2672068SN/A
2682069SN/Adef template LoadExecute {{
2692132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2702068SN/A                                  Trace::InstRecord *traceData) const
2712068SN/A    {
2722068SN/A        Addr EA;
2732132SN/A        Fault fault = NoFault;
2742068SN/A
2752068SN/A        %(fp_enable_check)s;
2762068SN/A        %(op_decl)s;
2772069SN/A        %(op_rd)s;
2782068SN/A        %(ea_code)s;
2792068SN/A
2802090SN/A        if (fault == NoFault) {
2812069SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2822068SN/A            %(memacc_code)s;
2832068SN/A        }
2842068SN/A
2852090SN/A        if (fault == NoFault) {
2862069SN/A            %(op_wb)s;
2872069SN/A        }
2882069SN/A
2892069SN/A        return fault;
2902069SN/A    }
2912069SN/A}};
2922069SN/A
2932069SN/A
2942095SN/Adef template LoadInitiateAcc {{
2952132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2962095SN/A                                      Trace::InstRecord *traceData) const
2972095SN/A    {
2982095SN/A        Addr EA;
2992132SN/A        Fault fault = NoFault;
3002095SN/A
3012095SN/A        %(fp_enable_check)s;
3022095SN/A        %(op_src_decl)s;
3032095SN/A        %(op_rd)s;
3042095SN/A        %(ea_code)s;
3052095SN/A
3062098SN/A        if (fault == NoFault) {
3072095SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3082095SN/A        }
3092095SN/A
3102095SN/A        return fault;
3112095SN/A    }
3122095SN/A}};
3132095SN/A
3142095SN/A
3152095SN/Adef template LoadCompleteAcc {{
3162623SN/A    Fault %(class_name)s::completeAcc(Packet *pkt,
3172095SN/A                                      %(CPU_exec_context)s *xc,
3182095SN/A                                      Trace::InstRecord *traceData) const
3192095SN/A    {
3202132SN/A        Fault fault = NoFault;
3212095SN/A
3222095SN/A        %(fp_enable_check)s;
3232506SN/A        %(op_decl)s;
3242095SN/A
3252623SN/A        Mem = pkt->get<typeof(Mem)>();
3262095SN/A
3272098SN/A        if (fault == NoFault) {
3282095SN/A            %(memacc_code)s;
3292095SN/A        }
3302095SN/A
3312098SN/A        if (fault == NoFault) {
3322095SN/A            %(op_wb)s;
3332095SN/A        }
3342095SN/A
3352095SN/A        return fault;
3362095SN/A    }
3372095SN/A}};
3382095SN/A
3392095SN/A
3402069SN/Adef template StoreMemAccExecute {{
3412132SN/A    Fault
3422069SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3432069SN/A                                   Trace::InstRecord *traceData) const
3442069SN/A    {
3452069SN/A        Addr EA;
3462132SN/A        Fault fault = NoFault;
3472069SN/A        uint64_t write_result = 0;
3482069SN/A
3492069SN/A        %(fp_enable_check)s;
3502069SN/A        %(op_decl)s;
3512069SN/A        %(op_rd)s;
3522069SN/A        EA = xc->getEA();
3532069SN/A
3542090SN/A        if (fault == NoFault) {
3552069SN/A            %(code)s;
3562069SN/A        }
3572069SN/A
3582090SN/A        if (fault == NoFault) {
3592069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3602069SN/A                              memAccessFlags, &write_result);
3612069SN/A            if (traceData) { traceData->setData(Mem); }
3622068SN/A        }
3632068SN/A
3642090SN/A        if (fault == NoFault) {
3652068SN/A            %(postacc_code)s;
3662068SN/A        }
3672068SN/A
3682090SN/A        if (fault == NoFault) {
3692069SN/A            %(op_wb)s;
3702068SN/A        }
3712068SN/A
3722068SN/A        return fault;
3732068SN/A    }
3742068SN/A}};
3752068SN/A
3762068SN/A
3772069SN/Adef template StoreExecute {{
3782132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3792069SN/A                                  Trace::InstRecord *traceData) const
3802069SN/A    {
3812069SN/A        Addr EA;
3822132SN/A        Fault fault = NoFault;
3832069SN/A        uint64_t write_result = 0;
3842069SN/A
3852069SN/A        %(fp_enable_check)s;
3862069SN/A        %(op_decl)s;
3872069SN/A        %(op_rd)s;
3882069SN/A        %(ea_code)s;
3892069SN/A
3902090SN/A        if (fault == NoFault) {
3912069SN/A            %(memacc_code)s;
3922069SN/A        }
3932069SN/A
3942090SN/A        if (fault == NoFault) {
3952069SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3962069SN/A                              memAccessFlags, &write_result);
3972069SN/A            if (traceData) { traceData->setData(Mem); }
3982069SN/A        }
3992069SN/A
4002090SN/A        if (fault == NoFault) {
4012069SN/A            %(postacc_code)s;
4022069SN/A        }
4032069SN/A
4042090SN/A        if (fault == NoFault) {
4052069SN/A            %(op_wb)s;
4062069SN/A        }
4072069SN/A
4082069SN/A        return fault;
4092069SN/A    }
4102069SN/A}};
4112069SN/A
4122095SN/Adef template StoreInitiateAcc {{
4132132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4142095SN/A                                      Trace::InstRecord *traceData) const
4152095SN/A    {
4162095SN/A        Addr EA;
4172132SN/A        Fault fault = NoFault;
4182095SN/A
4192095SN/A        %(fp_enable_check)s;
4202506SN/A        %(op_decl)s;
4212095SN/A        %(op_rd)s;
4222095SN/A        %(ea_code)s;
4232095SN/A
4242098SN/A        if (fault == NoFault) {
4252095SN/A            %(memacc_code)s;
4262095SN/A        }
4272095SN/A
4282098SN/A        if (fault == NoFault) {
4292095SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4302623SN/A                              memAccessFlags, NULL);
4312095SN/A            if (traceData) { traceData->setData(Mem); }
4322095SN/A        }
4332095SN/A
4342095SN/A        return fault;
4352095SN/A    }
4362095SN/A}};
4372095SN/A
4382095SN/A
4392095SN/Adef template StoreCompleteAcc {{
4402623SN/A    Fault %(class_name)s::completeAcc(Packet *pkt,
4412095SN/A                                      %(CPU_exec_context)s *xc,
4422095SN/A                                      Trace::InstRecord *traceData) const
4432095SN/A    {
4442132SN/A        Fault fault = NoFault;
4452095SN/A
4462095SN/A        %(fp_enable_check)s;
4472095SN/A        %(op_dest_decl)s;
4482095SN/A
4492623SN/A        if (fault == NoFault) {
4502623SN/A            %(postacc_code)s;
4512623SN/A        }
4522623SN/A
4532623SN/A        if (fault == NoFault) {
4542623SN/A            %(op_wb)s;
4552623SN/A        }
4562623SN/A
4572623SN/A        return fault;
4582623SN/A    }
4592623SN/A}};
4602623SN/A
4612623SN/A
4622623SN/Adef template StoreCondCompleteAcc {{
4632623SN/A    Fault %(class_name)s::completeAcc(Packet *pkt,
4642623SN/A                                      %(CPU_exec_context)s *xc,
4652623SN/A                                      Trace::InstRecord *traceData) const
4662623SN/A    {
4672623SN/A        Fault fault = NoFault;
4682623SN/A
4692623SN/A        %(fp_enable_check)s;
4702623SN/A        %(op_dest_decl)s;
4712623SN/A
4722623SN/A        uint64_t write_result = pkt->req->getScResult();
4732095SN/A
4742098SN/A        if (fault == NoFault) {
4752095SN/A            %(postacc_code)s;
4762095SN/A        }
4772095SN/A
4782098SN/A        if (fault == NoFault) {
4792095SN/A            %(op_wb)s;
4802095SN/A        }
4812095SN/A
4822095SN/A        return fault;
4832095SN/A    }
4842095SN/A}};
4852095SN/A
4862069SN/A
4872069SN/Adef template MiscMemAccExecute {{
4882132SN/A    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4892069SN/A                                          Trace::InstRecord *traceData) const
4902069SN/A    {
4912069SN/A        Addr EA;
4922132SN/A        Fault fault = NoFault;
4932069SN/A
4942069SN/A        %(fp_enable_check)s;
4952069SN/A        %(op_decl)s;
4962069SN/A        %(op_rd)s;
4972069SN/A        EA = xc->getEA();
4982069SN/A
4992090SN/A        if (fault == NoFault) {
5002069SN/A            %(code)s;
5012069SN/A        }
5022069SN/A
5032090SN/A        return NoFault;
5042069SN/A    }
5052069SN/A}};
5062069SN/A
5072069SN/Adef template MiscExecute {{
5082132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5092068SN/A                                  Trace::InstRecord *traceData) const
5102068SN/A    {
5112068SN/A        Addr EA;
5122132SN/A        Fault fault = NoFault;
5132068SN/A
5142068SN/A        %(fp_enable_check)s;
5152068SN/A        %(op_decl)s;
5162069SN/A        %(op_rd)s;
5172068SN/A        %(ea_code)s;
5182068SN/A
5192090SN/A        if (fault == NoFault) {
5202069SN/A            %(memacc_code)s;
5212068SN/A        }
5222068SN/A
5232090SN/A        return NoFault;
5242068SN/A    }
5252068SN/A}};
5262068SN/A
5272095SN/Adef template MiscInitiateAcc {{
5282132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5292095SN/A                                      Trace::InstRecord *traceData) const
5302095SN/A    {
5312110SN/A        panic("Misc instruction does not support split access method!");
5322098SN/A        return NoFault;
5332095SN/A    }
5342095SN/A}};
5352095SN/A
5362095SN/A
5372095SN/Adef template MiscCompleteAcc {{
5382623SN/A    Fault %(class_name)s::completeAcc(Packet *pkt,
5392095SN/A                                      %(CPU_exec_context)s *xc,
5402095SN/A                                      Trace::InstRecord *traceData) const
5412095SN/A    {
5422110SN/A        panic("Misc instruction does not support split access method!");
5432110SN/A
5442098SN/A        return NoFault;
5452095SN/A    }
5462095SN/A}};
5472095SN/A
5482068SN/A// load instructions use Ra as dest, so check for
5492068SN/A// Ra == 31 to detect nops
5502068SN/Adef template LoadNopCheckDecode {{
5512068SN/A {
5522068SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
5532068SN/A     if (RA == 31) {
5542068SN/A         i = makeNop(i);
5552068SN/A     }
5562068SN/A     return i;
5572068SN/A }
5582068SN/A}};
5592068SN/A
5602068SN/A
5612068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
5622068SN/Adef template LoadPrefetchCheckDecode {{
5632068SN/A {
5642068SN/A     if (RA != 31) {
5652068SN/A         return new %(class_name)s(machInst);
5662068SN/A     }
5672068SN/A     else {
5682068SN/A         return new %(class_name)sPrefetch(machInst);
5692068SN/A     }
5702068SN/A }
5712068SN/A}};
5722068SN/A
5732068SN/A
5742068SN/Alet {{
5752075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5762075SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
5772069SN/A                  decode_template = BasicDecode, exec_template_base = ''):
5782075SN/A    # Make sure flags are in lists (convert to lists if not).
5792075SN/A    mem_flags = makeList(mem_flags)
5802075SN/A    inst_flags = makeList(inst_flags)
5812068SN/A
5822068SN/A    # add hook to get effective addresses into execution trace output.
5832068SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5842068SN/A
5852068SN/A    # generate code block objects
5862068SN/A    ea_cblk = CodeBlock(ea_code)
5872068SN/A    memacc_cblk = CodeBlock(memacc_code)
5882068SN/A    postacc_cblk = CodeBlock(postacc_code)
5892068SN/A
5902068SN/A    # Some CPU models execute the memory operation as an atomic unit,
5912068SN/A    # while others want to separate them into an effective address
5922068SN/A    # computation and a memory access operation.  As a result, we need
5932068SN/A    # to generate three StaticInst objects.  Note that the latter two
5942068SN/A    # are nested inside the larger "atomic" one.
5952068SN/A
5962068SN/A    # generate InstObjParams for EAComp object
5972068SN/A    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
5982068SN/A
5992068SN/A    # generate InstObjParams for MemAcc object
6002068SN/A    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
6012068SN/A    # in the split execution model, the MemAcc portion is responsible
6022068SN/A    # for the post-access code.
6032068SN/A    memacc_iop.postacc_code = postacc_cblk.code
6042068SN/A
6052110SN/A    # generate InstObjParams for InitiateAcc, CompleteAcc object
6062110SN/A    # The code used depends on the template being used
6072110SN/A    if (exec_template_base == 'Load'):
6082110SN/A        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
6092110SN/A        completeacc_cblk = CodeBlock(memacc_code + postacc_code)
6102623SN/A    elif (exec_template_base.startswith('Store')):
6112110SN/A        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
6122110SN/A        completeacc_cblk = CodeBlock(postacc_code)
6132110SN/A    else:
6142110SN/A        initiateacc_cblk = ''
6152110SN/A        completeacc_cblk = ''
6162110SN/A
6172110SN/A    initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
6182110SN/A                                    inst_flags)
6192110SN/A
6202110SN/A    completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
6212110SN/A                                    inst_flags)
6222110SN/A
6232110SN/A    if (exec_template_base == 'Load'):
6242110SN/A        initiateacc_iop.ea_code = ea_cblk.code
6252110SN/A        initiateacc_iop.memacc_code = memacc_cblk.code
6262110SN/A        completeacc_iop.memacc_code = memacc_cblk.code
6272110SN/A        completeacc_iop.postacc_code = postacc_cblk.code
6282623SN/A    elif (exec_template_base.startswith('Store')):
6292110SN/A        initiateacc_iop.ea_code = ea_cblk.code
6302110SN/A        initiateacc_iop.memacc_code = memacc_cblk.code
6312110SN/A        completeacc_iop.postacc_code = postacc_cblk.code
6322110SN/A
6332068SN/A    # generate InstObjParams for unified execution
6342068SN/A    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
6352068SN/A    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
6362068SN/A
6372068SN/A    iop.ea_constructor = ea_cblk.constructor
6382068SN/A    iop.ea_code = ea_cblk.code
6392068SN/A    iop.memacc_constructor = memacc_cblk.constructor
6402068SN/A    iop.memacc_code = memacc_cblk.code
6412068SN/A    iop.postacc_code = postacc_cblk.code
6422068SN/A
6432068SN/A    if mem_flags:
6442068SN/A        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
6452068SN/A        iop.constructor += s
6462068SN/A        memacc_iop.constructor += s
6472068SN/A
6482069SN/A    # select templates
6492623SN/A
6502623SN/A    # define aliases... most StoreCond templates are the same as the
6512623SN/A    # corresponding Store templates (only CompleteAcc is different).
6522623SN/A    StoreCondMemAccExecute = StoreMemAccExecute
6532623SN/A    StoreCondExecute = StoreExecute
6542623SN/A    StoreCondInitiateAcc = StoreInitiateAcc
6552623SN/A
6562069SN/A    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
6572069SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
6582095SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
6592095SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
6602069SN/A
6612068SN/A    # (header_output, decoder_output, decode_block, exec_output)
6622068SN/A    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
6632068SN/A            decode_template.subst(iop),
6642068SN/A            EACompExecute.subst(ea_iop)
6652069SN/A            + memAccExecTemplate.subst(memacc_iop)
6662095SN/A            + fullExecTemplate.subst(iop)
6672110SN/A            + initiateAccTemplate.subst(initiateacc_iop)
6682110SN/A            + completeAccTemplate.subst(completeacc_iop))
6692068SN/A}};
6702068SN/A
6712068SN/A
6722075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
6732075SN/A                     mem_flags = [], inst_flags = []) {{
6742068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6752075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6762069SN/A                      decode_template = LoadNopCheckDecode,
6772069SN/A                      exec_template_base = 'Load')
6782068SN/A}};
6792068SN/A
6802068SN/A
6812068SN/A// Note that the flags passed in apply only to the prefetch version
6822075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
6832075SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
6842068SN/A    # declare the load instruction object and generate the decode block
6852068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6862075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6872069SN/A                      decode_template = LoadPrefetchCheckDecode,
6882069SN/A                      exec_template_base = 'Load')
6892068SN/A
6902068SN/A    # Declare the prefetch instruction object.
6912068SN/A
6922075SN/A    # Make sure flag args are lists so we can mess with them.
6932075SN/A    mem_flags = makeList(mem_flags)
6942075SN/A    pf_flags = makeList(pf_flags)
6952075SN/A    inst_flags = makeList(inst_flags)
6962075SN/A
6972075SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
6982075SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
6992075SN/A                                  'IsDataPrefetch', 'MemReadOp']
7002068SN/A
7012068SN/A    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
7022069SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
7032069SN/A                      'xc->prefetch(EA, memAccessFlags);',
7042075SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
7052068SN/A
7062068SN/A    header_output += pf_header_output
7072068SN/A    decoder_output += pf_decoder_output
7082068SN/A    exec_output += pf_exec_output
7092068SN/A}};
7102068SN/A
7112068SN/A
7122075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
7132075SN/A                 mem_flags = [], inst_flags = []) {{
7142068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7152075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7162069SN/A                      exec_template_base = 'Store')
7172068SN/A}};
7182068SN/A
7192068SN/A
7202075SN/Adef format StoreCond(memacc_code, postacc_code,
7212075SN/A                     ea_code = {{ EA = Rb + disp; }},
7222075SN/A                     mem_flags = [], inst_flags = []) {{
7232068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7242075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7252623SN/A                      postacc_code, exec_template_base = 'StoreCond')
7262068SN/A}};
7272068SN/A
7282068SN/A
7292068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
7302075SN/Adef format MiscPrefetch(ea_code, memacc_code,
7312075SN/A                        mem_flags = [], inst_flags = []) {{
7322068SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7332075SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7342069SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
7352068SN/A}};
7362068SN/A
7372068SN/A
738