mem.isa revision 5736
11689SN/A// -*- mode:c++ -*-
27598Sminkyu.jeong@arm.com
37598Sminkyu.jeong@arm.com// Copyright (c) 2003-2005 The Regents of The University of Michigan
47598Sminkyu.jeong@arm.com// All rights reserved.
57598Sminkyu.jeong@arm.com//
67598Sminkyu.jeong@arm.com// Redistribution and use in source and binary forms, with or without
77598Sminkyu.jeong@arm.com// modification, are permitted provided that the following conditions are
87598Sminkyu.jeong@arm.com// met: redistributions of source code must retain the above copyright
97598Sminkyu.jeong@arm.com// notice, this list of conditions and the following disclaimer;
107598Sminkyu.jeong@arm.com// redistributions in binary form must reproduce the above copyright
117598Sminkyu.jeong@arm.com// notice, this list of conditions and the following disclaimer in the
127598Sminkyu.jeong@arm.com// documentation and/or other materials provided with the distribution;
137598Sminkyu.jeong@arm.com// neither the name of the copyright holders nor the names of its
142326SN/A// contributors may be used to endorse or promote products derived from
151689SN/A// this software without specific prior written permission.
161689SN/A//
171689SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181689SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191689SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201689SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211689SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221689SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231689SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241689SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251689SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261689SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
271689SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
281689SN/A//
291689SN/A// Authors: Steve Reinhardt
301689SN/A//          Kevin Lim
311689SN/A
321689SN/A////////////////////////////////////////////////////////////////////
331689SN/A//
341689SN/A// Memory-format instructions: LoadAddress, Load, Store
351689SN/A//
361689SN/A
371689SN/Aoutput header {{
381689SN/A    /**
392665Ssaidi@eecs.umich.edu     * Base class for general Alpha memory-format instructions.
402665Ssaidi@eecs.umich.edu     */
411689SN/A    class Memory : public AlphaStaticInst
421689SN/A    {
431060SN/A      protected:
441060SN/A
451689SN/A        /// Memory request flags.  See mem_req_base.hh.
461060SN/A        Request::Flags memAccessFlags;
471060SN/A        /// Pointer to EAComp object.
481060SN/A        const StaticInstPtr eaCompPtr;
497813Ssteve.reinhardt@amd.com        /// Pointer to MemAcc object.
506658Snate@binkert.org        const StaticInstPtr memAccPtr;
512292SN/A
521717SN/A        /// Constructor
535529Snate@binkert.org        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
541060SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
556221Snate@binkert.org               StaticInstPtr _memAccPtr = nullStaticInstPtr)
566221Snate@binkert.org            : AlphaStaticInst(mnem, _machInst, __opClass),
571681SN/A              eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
585529Snate@binkert.org        {
592873Sktlim@umich.edu        }
604329Sktlim@umich.edu
614329Sktlim@umich.edu        std::string
624329Sktlim@umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
632292SN/A
642292SN/A      public:
652292SN/A
662292SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
672820Sktlim@umich.edu        const StaticInstPtr &memAccInst() const { return memAccPtr; }
682292SN/A    };
692820Sktlim@umich.edu
702820Sktlim@umich.edu    /**
715529Snate@binkert.org     * Base class for memory-format instructions using a 32-bit
722307SN/A     * displacement (i.e. most of them).
731060SN/A     */
742292SN/A    class MemoryDisp32 : public Memory
752292SN/A    {
762292SN/A      protected:
771060SN/A        /// Displacement for EA calculation (signed).
781060SN/A        int32_t disp;
791060SN/A
801060SN/A        /// Constructor.
811060SN/A        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
821060SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
831681SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
846221Snate@binkert.org            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
856221Snate@binkert.org              disp(MEMDISP)
866221Snate@binkert.org        {
876221Snate@binkert.org        }
882292SN/A    };
892292SN/A
902820Sktlim@umich.edu
912820Sktlim@umich.edu    /**
922292SN/A     * Base class for a few miscellaneous memory-format insts
932292SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
942820Sktlim@umich.edu     * None of these instructions has a destination register either.
952820Sktlim@umich.edu     */
962292SN/A    class MemoryNoDisp : public Memory
972292SN/A    {
982292SN/A      protected:
992292SN/A        /// Constructor
1002292SN/A        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1012292SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
1022292SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
1032292SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
1041060SN/A        {
1051060SN/A        }
1061681SN/A
1071062SN/A        std::string
1082292SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1091062SN/A    };
1102301SN/A}};
1112301SN/A
1121062SN/A
1132727Sktlim@umich.eduoutput decoder {{
1141062SN/A    std::string
1151062SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1161062SN/A    {
1171062SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1181062SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1191062SN/A    }
1201062SN/A
1211062SN/A    std::string
1221062SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1231062SN/A    {
1241062SN/A        return csprintf("%-10s (r%d)", mnemonic, RB);
1251062SN/A    }
1261062SN/A}};
1271062SN/A
1281062SN/Adef format LoadAddress(code) {{
1291062SN/A    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1301062SN/A    header_output = BasicDeclare.subst(iop)
1311062SN/A    decoder_output = BasicConstructor.subst(iop)
1321062SN/A    decode_block = BasicDecode.subst(iop)
1331062SN/A    exec_output = BasicExecute.subst(iop)
1341062SN/A}};
1351062SN/A
1361062SN/A
1371062SN/Adef template LoadStoreDeclare {{
1381062SN/A    /**
1391062SN/A     * Static instruction class for "%(mnemonic)s".
1401062SN/A     */
1411062SN/A    class %(class_name)s : public %(base_class)s
1421062SN/A    {
1431062SN/A      protected:
1441062SN/A
1451062SN/A        /**
1461062SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1471062SN/A         */
1481062SN/A        class EAComp : public %(base_class)s
1491062SN/A        {
1501062SN/A          public:
1511062SN/A            /// Constructor
1521062SN/A            EAComp(ExtMachInst machInst);
1531062SN/A
1541062SN/A            %(BasicExecDeclare)s
1552292SN/A        };
1562292SN/A
1572292SN/A        /**
1582292SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1591062SN/A         */
1601062SN/A        class MemAcc : public %(base_class)s
1611062SN/A        {
1621062SN/A          public:
1631062SN/A            /// Constructor
1641062SN/A            MemAcc(ExtMachInst machInst);
1651062SN/A
1662292SN/A            %(BasicExecDeclare)s
1672292SN/A        };
1682292SN/A
1692292SN/A      public:
1702292SN/A
1712292SN/A        /// Constructor.
1722292SN/A        %(class_name)s(ExtMachInst machInst);
1732292SN/A
1742292SN/A        %(BasicExecDeclare)s
1752292SN/A
1762301SN/A        %(InitiateAccDeclare)s
1772727Sktlim@umich.edu
1782353SN/A        %(CompleteAccDeclare)s
1792727Sktlim@umich.edu    };
1802727Sktlim@umich.edu}};
1812727Sktlim@umich.edu
1826221Snate@binkert.org
1832353SN/Adef template InitiateAccDeclare {{
1842727Sktlim@umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1852727Sktlim@umich.edu}};
1862727Sktlim@umich.edu
1872727Sktlim@umich.edu
1882353SN/Adef template CompleteAccDeclare {{
1892727Sktlim@umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1902727Sktlim@umich.edu                      Trace::InstRecord *) const;
1912727Sktlim@umich.edu}};
1926221Snate@binkert.org
1932301SN/A
1942301SN/Adef template EACompConstructor {{
1952727Sktlim@umich.edu    /** TODO: change op_class to AddrGenOp or something (requires
1962301SN/A     * creating new member of OpClass enum in op_class.hh, updating
1972727Sktlim@umich.edu     * config files, etc.). */
1986221Snate@binkert.org    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
1992301SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2002301SN/A    {
2012727Sktlim@umich.edu        %(constructor)s;
2022301SN/A    }
2032727Sktlim@umich.edu}};
2046221Snate@binkert.org
2052301SN/A
2062301SN/Adef template MemAccConstructor {{
2072727Sktlim@umich.edu    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2082301SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2092727Sktlim@umich.edu    {
2106221Snate@binkert.org        %(constructor)s;
2112301SN/A    }
2122301SN/A}};
2132727Sktlim@umich.edu
2142301SN/A
2152301SN/Adef template LoadStoreConstructor {{
2162301SN/A    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2172301SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2182727Sktlim@umich.edu                          new EAComp(machInst), new MemAcc(machInst))
2192727Sktlim@umich.edu    {
2202727Sktlim@umich.edu        %(constructor)s;
2212727Sktlim@umich.edu    }
2222727Sktlim@umich.edu}};
2232727Sktlim@umich.edu
2242727Sktlim@umich.edu
2252727Sktlim@umich.edudef template EACompExecute {{
2262727Sktlim@umich.edu    Fault
2272301SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2282301SN/A                                   Trace::InstRecord *traceData) const
2296221Snate@binkert.org    {
2302301SN/A        Addr EA;
2312301SN/A        Fault fault = NoFault;
2322727Sktlim@umich.edu
2332301SN/A        %(fp_enable_check)s;
2342326SN/A        %(op_decl)s;
2356221Snate@binkert.org        %(op_rd)s;
2362301SN/A        %(ea_code)s;
2372301SN/A
2382727Sktlim@umich.edu        if (fault == NoFault) {
2392301SN/A            %(op_wb)s;
2402326SN/A            xc->setEA(EA);
2416221Snate@binkert.org        }
2422301SN/A
2432301SN/A        return fault;
2442727Sktlim@umich.edu    }
2452301SN/A}};
2462326SN/A
2476221Snate@binkert.orgdef template LoadMemAccExecute {{
2482301SN/A    Fault
2492301SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2502727Sktlim@umich.edu                                   Trace::InstRecord *traceData) const
2512301SN/A    {
2522326SN/A        Addr EA;
2536221Snate@binkert.org        Fault fault = NoFault;
2542301SN/A
2552301SN/A        %(fp_enable_check)s;
2562727Sktlim@umich.edu        %(op_decl)s;
2572301SN/A        %(op_rd)s;
2582326SN/A        EA = xc->getEA();
2592301SN/A
2602301SN/A        if (fault == NoFault) {
2612727Sktlim@umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2622301SN/A            %(memacc_code)s;
2632326SN/A        }
2642301SN/A
2652326SN/A        if (fault == NoFault) {
2662301SN/A            %(op_wb)s;
2672301SN/A        }
2682727Sktlim@umich.edu
2692301SN/A        return fault;
2702326SN/A    }
2712301SN/A}};
2722326SN/A
2732301SN/A
2742301SN/Adef template LoadExecute {{
2752727Sktlim@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2762326SN/A                                  Trace::InstRecord *traceData) const
2771062SN/A    {
2781062SN/A        Addr EA;
2791681SN/A        Fault fault = NoFault;
2801060SN/A
2812292SN/A        %(fp_enable_check)s;
2821060SN/A        %(op_decl)s;
2836221Snate@binkert.org        %(op_rd)s;
2842292SN/A        %(ea_code)s;
2852292SN/A
2862292SN/A        if (fault == NoFault) {
2872292SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2882292SN/A            %(memacc_code)s;
2892292SN/A        }
2902292SN/A
2912292SN/A        if (fault == NoFault) {
2922292SN/A            %(op_wb)s;
2932733Sktlim@umich.edu        }
2941060SN/A
2951060SN/A        return fault;
2961681SN/A    }
2971060SN/A}};
2982292SN/A
2991060SN/A
3001060SN/Adef template LoadInitiateAcc {{
3011060SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3021060SN/A                                      Trace::InstRecord *traceData) const
3031060SN/A    {
3041060SN/A        Addr EA;
3051060SN/A        Fault fault = NoFault;
3061060SN/A
3071060SN/A        %(fp_enable_check)s;
3082292SN/A        %(op_src_decl)s;
3092292SN/A        %(op_rd)s;
3101060SN/A        %(ea_code)s;
3111060SN/A
3121060SN/A        if (fault == NoFault) {
3131060SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3141681SN/A        }
3151060SN/A
3162292SN/A        return fault;
3171060SN/A    }
3181060SN/A}};
3191060SN/A
3201060SN/A
3211060SN/Adef template LoadCompleteAcc {{
3221060SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3231060SN/A                                      %(CPU_exec_context)s *xc,
3241681SN/A                                      Trace::InstRecord *traceData) const
3251060SN/A    {
3262292SN/A        Fault fault = NoFault;
3271060SN/A
3281060SN/A        %(fp_enable_check)s;
3291060SN/A        %(op_decl)s;
3301060SN/A
3311060SN/A        Mem = pkt->get<typeof(Mem)>();
3321060SN/A
3331060SN/A        if (fault == NoFault) {
3341681SN/A            %(memacc_code)s;
3351060SN/A        }
3366221Snate@binkert.org
3371060SN/A        if (fault == NoFault) {
3382292SN/A            %(op_wb)s;
3392292SN/A        }
3402292SN/A
3412292SN/A        return fault;
3421060SN/A    }
3431060SN/A}};
3441681SN/A
3451060SN/A
3462292SN/Adef template StoreMemAccExecute {{
3471060SN/A    Fault
3482292SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3491060SN/A                                   Trace::InstRecord *traceData) const
3501060SN/A    {
3512307SN/A        Addr EA;
3522863Sktlim@umich.edu        Fault fault = NoFault;
3532843Sktlim@umich.edu
3542307SN/A        %(fp_enable_check)s;
3552843Sktlim@umich.edu        %(op_decl)s;
3562843Sktlim@umich.edu        %(op_rd)s;
3572863Sktlim@umich.edu        EA = xc->getEA();
3581681SN/A
3591681SN/A        if (fault == NoFault) {
3602316SN/A            %(memacc_code)s;
3611681SN/A        }
3622843Sktlim@umich.edu
3632843Sktlim@umich.edu        if (fault == NoFault) {
3642843Sktlim@umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3652843Sktlim@umich.edu                              memAccessFlags, NULL);
3662843Sktlim@umich.edu            if (traceData) { traceData->setData(Mem); }
3672843Sktlim@umich.edu        }
3682843Sktlim@umich.edu
3691681SN/A        if (fault == NoFault) {
3702348SN/A            %(postacc_code)s;
3712307SN/A        }
3722367SN/A
3732367SN/A        if (fault == NoFault) {
3741681SN/A            %(op_wb)s;
3752307SN/A        }
3762307SN/A
3772307SN/A        return fault;
3782307SN/A    }
3796221Snate@binkert.org}};
3806221Snate@binkert.org
3816221Snate@binkert.orgdef template StoreCondMemAccExecute {{
3826221Snate@binkert.org    Fault
3836221Snate@binkert.org    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3842307SN/A                                   Trace::InstRecord *traceData) const
3851681SN/A    {
3861681SN/A        Addr EA;
3872307SN/A        Fault fault = NoFault;
3881681SN/A        uint64_t write_result = 0;
3892307SN/A
3901060SN/A        %(fp_enable_check)s;
3912348SN/A        %(op_decl)s;
3922307SN/A        %(op_rd)s;
3932307SN/A        EA = xc->getEA();
3942307SN/A
3952307SN/A        if (fault == NoFault) {
3961060SN/A            %(memacc_code)s;
3972307SN/A        }
3982307SN/A
3992307SN/A        if (fault == NoFault) {
4001060SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4012307SN/A                              memAccessFlags, &write_result);
4022307SN/A            if (traceData) { traceData->setData(Mem); }
4031060SN/A        }
4046221Snate@binkert.org
4056221Snate@binkert.org        if (fault == NoFault) {
4066221Snate@binkert.org            %(postacc_code)s;
4076221Snate@binkert.org        }
4082307SN/A
4091060SN/A        if (fault == NoFault) {
4102307SN/A            %(op_wb)s;
4112307SN/A        }
4122873Sktlim@umich.edu
4132307SN/A        return fault;
4141060SN/A    }
4151060SN/A}};
4161060SN/A
4171681SN/A
4181060SN/Adef template StoreExecute {{
4196221Snate@binkert.org    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4202107SN/A                                  Trace::InstRecord *traceData) const
4216221Snate@binkert.org    {
4222107SN/A        Addr EA;
4232292SN/A        Fault fault = NoFault;
4242292SN/A
4252107SN/A        %(fp_enable_check)s;
4262292SN/A        %(op_decl)s;
4272326SN/A        %(op_rd)s;
4282292SN/A        %(ea_code)s;
4292107SN/A
4302292SN/A        if (fault == NoFault) {
4312935Sksewell@umich.edu            %(memacc_code)s;
4324632Sgblack@eecs.umich.edu        }
4332935Sksewell@umich.edu
4342292SN/A        if (fault == NoFault) {
4352292SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4362292SN/A                              memAccessFlags, NULL);
4372292SN/A            if (traceData) { traceData->setData(Mem); }
4382292SN/A        }
4392107SN/A
4402292SN/A        if (fault == NoFault) {
4412107SN/A            %(postacc_code)s;
4422292SN/A        }
4432292SN/A
4442107SN/A        if (fault == NoFault) {
4452702Sktlim@umich.edu            %(op_wb)s;
4462107SN/A        }
4472107SN/A
4482107SN/A        return fault;
4492107SN/A    }
4506221Snate@binkert.org}};
4512292SN/A
4527720Sgblack@eecs.umich.edudef template StoreCondExecute {{
4537720Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4542292SN/A                                  Trace::InstRecord *traceData) const
4557852SMatt.Horsnell@arm.com    {
4567852SMatt.Horsnell@arm.com        Addr EA;
4577852SMatt.Horsnell@arm.com        Fault fault = NoFault;
4587852SMatt.Horsnell@arm.com        uint64_t write_result = 0;
4597852SMatt.Horsnell@arm.com
4607852SMatt.Horsnell@arm.com        %(fp_enable_check)s;
4617852SMatt.Horsnell@arm.com        %(op_decl)s;
4622935Sksewell@umich.edu        %(op_rd)s;
4637852SMatt.Horsnell@arm.com        %(ea_code)s;
4647852SMatt.Horsnell@arm.com
4652292SN/A        if (fault == NoFault) {
4667852SMatt.Horsnell@arm.com            %(memacc_code)s;
4677852SMatt.Horsnell@arm.com        }
4687852SMatt.Horsnell@arm.com
4692292SN/A        if (fault == NoFault) {
4707852SMatt.Horsnell@arm.com            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4717852SMatt.Horsnell@arm.com                              memAccessFlags, &write_result);
4727852SMatt.Horsnell@arm.com            if (traceData) { traceData->setData(Mem); }
4732292SN/A        }
4742292SN/A
4752292SN/A        if (fault == NoFault) {
4762292SN/A            %(postacc_code)s;
4776221Snate@binkert.org        }
4782292SN/A
4792292SN/A        if (fault == NoFault) {
4807720Sgblack@eecs.umich.edu            %(op_wb)s;
4812292SN/A        }
4827852SMatt.Horsnell@arm.com
4837852SMatt.Horsnell@arm.com        return fault;
4847852SMatt.Horsnell@arm.com    }
4857852SMatt.Horsnell@arm.com}};
4867852SMatt.Horsnell@arm.com
4877852SMatt.Horsnell@arm.comdef template StoreInitiateAcc {{
4887852SMatt.Horsnell@arm.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4897852SMatt.Horsnell@arm.com                                      Trace::InstRecord *traceData) const
4902292SN/A    {
4917852SMatt.Horsnell@arm.com        Addr EA;
4922292SN/A        Fault fault = NoFault;
4937852SMatt.Horsnell@arm.com
4947852SMatt.Horsnell@arm.com        %(fp_enable_check)s;
4952292SN/A        %(op_decl)s;
4962292SN/A        %(op_rd)s;
4972292SN/A        %(ea_code)s;
4982292SN/A
4996221Snate@binkert.org        if (fault == NoFault) {
5002292SN/A            %(memacc_code)s;
5012292SN/A        }
5027720Sgblack@eecs.umich.edu
5037852SMatt.Horsnell@arm.com        if (fault == NoFault) {
5047852SMatt.Horsnell@arm.com            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5057852SMatt.Horsnell@arm.com                              memAccessFlags, NULL);
5062292SN/A            if (traceData) { traceData->setData(Mem); }
5077852SMatt.Horsnell@arm.com        }
5087852SMatt.Horsnell@arm.com
5097852SMatt.Horsnell@arm.com        return fault;
5102292SN/A    }
5117852SMatt.Horsnell@arm.com}};
5127852SMatt.Horsnell@arm.com
5132292SN/A
5147852SMatt.Horsnell@arm.comdef template StoreCompleteAcc {{
5152292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5167852SMatt.Horsnell@arm.com                                      %(CPU_exec_context)s *xc,
5177852SMatt.Horsnell@arm.com                                      Trace::InstRecord *traceData) const
5182292SN/A    {
5192292SN/A        Fault fault = NoFault;
5202292SN/A
5212292SN/A        %(fp_enable_check)s;
5226221Snate@binkert.org        %(op_dest_decl)s;
5232292SN/A
5242292SN/A        if (fault == NoFault) {
5252292SN/A            %(postacc_code)s;
5262292SN/A        }
5272292SN/A
5282292SN/A        if (fault == NoFault) {
5292292SN/A            %(op_wb)s;
5302292SN/A        }
5312292SN/A
5322292SN/A        return fault;
5332292SN/A    }
5342292SN/A}};
5352292SN/A
5362292SN/A
5372292SN/Adef template StoreCondCompleteAcc {{
5382292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5392292SN/A                                      %(CPU_exec_context)s *xc,
5402292SN/A                                      Trace::InstRecord *traceData) const
5416221Snate@binkert.org    {
5422292SN/A        Fault fault = NoFault;
5432292SN/A
5442292SN/A        %(fp_enable_check)s;
5452292SN/A        %(op_dest_decl)s;
5462292SN/A
5472292SN/A        uint64_t write_result = pkt->req->getExtraData();
5482292SN/A
5492292SN/A        if (fault == NoFault) {
5502292SN/A            %(postacc_code)s;
5512292SN/A        }
5522292SN/A
5532292SN/A        if (fault == NoFault) {
5542292SN/A            %(op_wb)s;
5552292SN/A        }
5562292SN/A
5572292SN/A        return fault;
5582292SN/A    }
5591060SN/A}};
5601681SN/A
5611060SN/A
5621060SN/Adef template MiscMemAccExecute {{
5632292SN/A    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
5642292SN/A                                          Trace::InstRecord *traceData) const
5652292SN/A    {
5662292SN/A        Addr EA;
5672292SN/A        Fault fault = NoFault;
5682292SN/A
5691681SN/A        %(fp_enable_check)s;
5701681SN/A        %(op_decl)s;
5711060SN/A        %(op_rd)s;
5722292SN/A        EA = xc->getEA();
5731060SN/A
5742292SN/A        if (fault == NoFault) {
5752292SN/A            %(memacc_code)s;
5761060SN/A        }
5772292SN/A
5782292SN/A        return NoFault;
5792292SN/A    }
5802292SN/A}};
5813221Sktlim@umich.edu
5823221Sktlim@umich.edudef template MiscExecute {{
5833221Sktlim@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5843221Sktlim@umich.edu                                  Trace::InstRecord *traceData) const
5853221Sktlim@umich.edu    {
5862292SN/A        Addr EA;
5872292SN/A        Fault fault = NoFault;
5882292SN/A
5892292SN/A        %(fp_enable_check)s;
5902326SN/A        %(op_decl)s;
5912292SN/A        %(op_rd)s;
5922292SN/A        %(ea_code)s;
5932820Sktlim@umich.edu
5942292SN/A        if (fault == NoFault) {
5952292SN/A            %(memacc_code)s;
5962292SN/A        }
5972292SN/A
5982353SN/A        return NoFault;
5992292SN/A    }
6002292SN/A}};
6012353SN/A
6022353SN/Adef template MiscInitiateAcc {{
6032292SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
6042292SN/A                                      Trace::InstRecord *traceData) const
6052292SN/A    {
6062292SN/A        warn("Misc instruction does not support split access method!");
6072292SN/A        return NoFault;
6082292SN/A    }
6092292SN/A}};
6102292SN/A
6112292SN/A
6122292SN/Adef template MiscCompleteAcc {{
6132292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
6142292SN/A                                      %(CPU_exec_context)s *xc,
6152731Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
6162292SN/A    {
6172292SN/A        warn("Misc instruction does not support split access method!");
6182292SN/A
6192292SN/A        return NoFault;
6202292SN/A    }
6212292SN/A}};
6222292SN/A
6232292SN/A// load instructions use Ra as dest, so check for
6246221Snate@binkert.org// Ra == 31 to detect nops
6252292SN/Adef template LoadNopCheckDecode {{
6262292SN/A {
6272292SN/A     AlphaStaticInst *i = new %(class_name)s(machInst);
6282292SN/A     if (RA == 31) {
6292292SN/A         i = makeNop(i);
6302292SN/A     }
6312292SN/A     return i;
6322292SN/A }
6337720Sgblack@eecs.umich.edu}};
6342292SN/A
6357720Sgblack@eecs.umich.edu
6362292SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
6372292SN/Adef template LoadPrefetchCheckDecode {{
6382292SN/A {
6392292SN/A     if (RA != 31) {
6402292SN/A         return new %(class_name)s(machInst);
6412292SN/A     }
6422292SN/A     else {
6432292SN/A         return new %(class_name)sPrefetch(machInst);
6442292SN/A     }
6452292SN/A }
6462292SN/A}};
6472292SN/A
6482292SN/A
6492292SN/Alet {{
6506221Snate@binkert.orgdef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6516221Snate@binkert.org                  postacc_code = '', base_class = 'MemoryDisp32',
6522292SN/A                  decode_template = BasicDecode, exec_template_base = ''):
6533867Sbinkertn@umich.edu    # Make sure flags are in lists (convert to lists if not).
6546221Snate@binkert.org    mem_flags = makeList(mem_flags)
6553867Sbinkertn@umich.edu    inst_flags = makeList(inst_flags)
6562292SN/A
6572292SN/A    # add hook to get effective addresses into execution trace output.
6582292SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
6592292SN/A
6602292SN/A    # Some CPU models execute the memory operation as an atomic unit,
6612292SN/A    # while others want to separate them into an effective address
6622292SN/A    # computation and a memory access operation.  As a result, we need
6632292SN/A    # to generate three StaticInst objects.  Note that the latter two
6642292SN/A    # are nested inside the larger "atomic" one.
6652292SN/A
6662292SN/A    # Generate InstObjParams for each of the three objects.  Note that
6676221Snate@binkert.org    # they differ only in the set of code objects contained (which in
6686221Snate@binkert.org    # turn affects the object's overall operand list).
6692292SN/A    iop = InstObjParams(name, Name, base_class,
6703867Sbinkertn@umich.edu                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
6716221Snate@binkert.org                        inst_flags)
6723867Sbinkertn@umich.edu    ea_iop = InstObjParams(name, Name, base_class,
6733867Sbinkertn@umich.edu                        { 'ea_code':ea_code },
6742292SN/A                        inst_flags)
6752292SN/A    memacc_iop = InstObjParams(name, Name, base_class,
6762292SN/A                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
6772292SN/A                        inst_flags)
6781062SN/A
6791062SN/A    if mem_flags:
6801681SN/A        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
6811062SN/A        s = '\n\tmemAccessFlags.reset(' + string.join(mem_flags, '|') + ');'
6822292SN/A        iop.constructor += s
6831062SN/A        memacc_iop.constructor += s
6842292SN/A
6851062SN/A    # select templates
6866221Snate@binkert.org
6876221Snate@binkert.org    # The InitiateAcc template is the same for StoreCond templates as the
6881062SN/A    # corresponding Store template..
6893867Sbinkertn@umich.edu    StoreCondInitiateAcc = StoreInitiateAcc
6906221Snate@binkert.org
6911062SN/A    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
6922292SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
6932292SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
6942292SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
6952292SN/A
6962292SN/A    # (header_output, decoder_output, decode_block, exec_output)
6971062SN/A    return (LoadStoreDeclare.subst(iop),
6982292SN/A            EACompConstructor.subst(ea_iop)
6992292SN/A            + MemAccConstructor.subst(memacc_iop)
7002292SN/A            + LoadStoreConstructor.subst(iop),
7012292SN/A            decode_template.subst(iop),
7022292SN/A            EACompExecute.subst(ea_iop)
7032292SN/A            + memAccExecTemplate.subst(memacc_iop)
7041062SN/A            + fullExecTemplate.subst(iop)
7052292SN/A            + initiateAccTemplate.subst(iop)
7061062SN/A            + completeAccTemplate.subst(iop))
7072292SN/A}};
7082292SN/A
7092292SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
7102292SN/A                     mem_flags = [], inst_flags = []) {{
7112292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7122292SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7131062SN/A                      decode_template = LoadNopCheckDecode,
7142292SN/A                      exec_template_base = 'Load')
7151062SN/A}};
7162292SN/A
7171062SN/A
7181062SN/A// Note that the flags passed in apply only to the prefetch version
7191062SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
7201681SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
7211062SN/A    # declare the load instruction object and generate the decode block
7222292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7231062SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7242292SN/A                      decode_template = LoadPrefetchCheckDecode,
7252292SN/A                      exec_template_base = 'Load')
7262292SN/A
7271062SN/A    # Declare the prefetch instruction object.
7282292SN/A
7292292SN/A    # Make sure flag args are lists so we can mess with them.
7306221Snate@binkert.org    mem_flags = makeList(mem_flags)
7312292SN/A    pf_flags = makeList(pf_flags)
7322292SN/A    inst_flags = makeList(inst_flags)
7332292SN/A
7342292SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
7351062SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
7362292SN/A                                  'IsDataPrefetch', 'MemReadOp']
7372292SN/A
7382292SN/A    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
7392292SN/A        LoadStoreBase(name, Name + 'Prefetch', ea_code,
7402292SN/A                      'xc->prefetch(EA, memAccessFlags);',
7412292SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
7422292SN/A
7432292SN/A    header_output += pf_header_output
7446221Snate@binkert.org    decoder_output += pf_decoder_output
7452292SN/A    exec_output += pf_exec_output
7462292SN/A}};
7472292SN/A
7482292SN/A
7492292SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
7502292SN/A                 mem_flags = [], inst_flags = []) {{
7512292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7522292SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7532292SN/A                      exec_template_base = 'Store')
7542292SN/A}};
7552292SN/A
7562292SN/A
7572292SN/Adef format StoreCond(memacc_code, postacc_code,
7582292SN/A                     ea_code = {{ EA = Rb + disp; }},
7592292SN/A                     mem_flags = [], inst_flags = []) {{
7602292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7612292SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7622292SN/A                      postacc_code, exec_template_base = 'StoreCond')
7632292SN/A}};
7642292SN/A
7652292SN/A
7662292SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
7672292SN/Adef format MiscPrefetch(ea_code, memacc_code,
7682292SN/A                        mem_flags = [], inst_flags = []) {{
7692292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7702292SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7712292SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
7722292SN/A}};
7732292SN/A
7742292SN/A
7752292SN/A