mem.isa revision 5222
12124SN/A// -*- mode:c++ -*-
22124SN/A
35222Sksewell@umich.edu// Copyright .AN) 2007 MIPS Technologies, Inc.  All Rights Reserved
45222Sksewell@umich.edu
55222Sksewell@umich.edu//  This software is part of the M5 simulator.
65222Sksewell@umich.edu
75222Sksewell@umich.edu//  THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING
85222Sksewell@umich.edu//  DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
95222Sksewell@umich.edu//  TO THESE TERMS AND CONDITIONS.
105222Sksewell@umich.edu
115222Sksewell@umich.edu//  Permission is granted to use, copy, create derivative works and
125222Sksewell@umich.edu//  distribute this software and such derivative works for any purpose,
135222Sksewell@umich.edu//  so long as (1) the copyright notice above, this grant of permission,
145222Sksewell@umich.edu//  and the disclaimer below appear in all copies and derivative works
155222Sksewell@umich.edu//  made, (2) the copyright notice above is augmented as appropriate to
165222Sksewell@umich.edu//  reflect the addition of any new copyrightable work in a derivative
175222Sksewell@umich.edu//  work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3)
185222Sksewell@umich.edu//  the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any
195222Sksewell@umich.edu//  advertising or publicity pertaining to the use or distribution of
205222Sksewell@umich.edu//  this software without specific, written prior authorization.
215222Sksewell@umich.edu
225222Sksewell@umich.edu//  THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B  MIPS MAKES NO WARRANTIES AND
235222Sksewell@umich.edu//  DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
245222Sksewell@umich.edu//  OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
255222Sksewell@umich.edu//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
265222Sksewell@umich.edu//  NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
275222Sksewell@umich.edu//  IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
285222Sksewell@umich.edu//  INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
295222Sksewell@umich.edu//  ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
305222Sksewell@umich.edu//  THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
315222Sksewell@umich.edu//  IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
325222Sksewell@umich.edu//  STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
335222Sksewell@umich.edu//  POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
345222Sksewell@umich.edu
355222Sksewell@umich.edu//Authors: Steve Reinhardt
365222Sksewell@umich.edu//         Korey L. Sewell
372022SN/A
382649Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
392649Ssaidi@eecs.umich.edu//
402706Sksewell@umich.edu// Memory-format instructions
412649Ssaidi@eecs.umich.edu//
422649Ssaidi@eecs.umich.edu
432022SN/Aoutput header {{
442124SN/A    /**
452124SN/A     * Base class for general Mips memory-format instructions.
462124SN/A     */
472124SN/A    class Memory : public MipsStaticInst
482124SN/A    {
492124SN/A      protected:
502124SN/A
512124SN/A        /// Memory request flags.  See mem_req_base.hh.
522124SN/A        unsigned memAccessFlags;
532124SN/A        /// Pointer to EAComp object.
542124SN/A        const StaticInstPtr eaCompPtr;
552124SN/A        /// Pointer to MemAcc object.
562124SN/A        const StaticInstPtr memAccPtr;
572239SN/A
582124SN/A        /// Displacement for EA calculation (signed).
592124SN/A        int32_t disp;
602124SN/A
612124SN/A        /// Constructor
622124SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
632124SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
642124SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
652124SN/A            : MipsStaticInst(mnem, _machInst, __opClass),
662124SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
672742Sksewell@umich.edu              disp(sext<16>(OFFSET))
682022SN/A        {
692124SN/A        }
702022SN/A
712124SN/A        std::string
722124SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
732022SN/A
742124SN/A      public:
752124SN/A
762124SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
772124SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
784661Sksewell@umich.edu
794661Sksewell@umich.edu        unsigned memAccFlags() { return memAccessFlags; }
802124SN/A    };
812124SN/A
822742Sksewell@umich.edu     /**
832742Sksewell@umich.edu     * Base class for a few miscellaneous memory-format insts
842742Sksewell@umich.edu     * that don't interpret the disp field
852742Sksewell@umich.edu     */
862742Sksewell@umich.edu    class MemoryNoDisp : public Memory
872742Sksewell@umich.edu    {
882742Sksewell@umich.edu      protected:
892742Sksewell@umich.edu        /// Constructor
902742Sksewell@umich.edu        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
912742Sksewell@umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
922742Sksewell@umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
932742Sksewell@umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
942742Sksewell@umich.edu        {
952742Sksewell@umich.edu        }
962742Sksewell@umich.edu
972742Sksewell@umich.edu        std::string
982742Sksewell@umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
992742Sksewell@umich.edu    };
1002022SN/A}};
1012022SN/A
1022124SN/A
1032022SN/Aoutput decoder {{
1042124SN/A    std::string
1052124SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1062124SN/A    {
1072742Sksewell@umich.edu        return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
1082239SN/A                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
1092124SN/A    }
1102124SN/A
1112742Sksewell@umich.edu    std::string
1122742Sksewell@umich.edu    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1132742Sksewell@umich.edu    {
1142742Sksewell@umich.edu        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
1152742Sksewell@umich.edu                        flags[IsFloating] ? 'f' : 'r',
1162742Sksewell@umich.edu                        flags[IsFloating] ? FD : RD,
1172742Sksewell@umich.edu                        RS, RT);
1182742Sksewell@umich.edu    }
1194661Sksewell@umich.edu
1204661Sksewell@umich.edu}};
1214661Sksewell@umich.edu
1224661Sksewell@umich.eduoutput exec {{
1234661Sksewell@umich.edu    /** return data in cases where there the size of data is only
1244661Sksewell@umich.edu        known in the packet
1254661Sksewell@umich.edu    */
1265222Sksewell@umich.edu    uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) {
1274661Sksewell@umich.edu        switch (packet->getSize())
1284661Sksewell@umich.edu        {
1295222Sksewell@umich.edu          case 1:
1304661Sksewell@umich.edu            return packet->get<uint8_t>();
1314661Sksewell@umich.edu
1325222Sksewell@umich.edu          case 2:
1334661Sksewell@umich.edu            return packet->get<uint16_t>();
1344661Sksewell@umich.edu
1355222Sksewell@umich.edu          case 4:
1364661Sksewell@umich.edu            return packet->get<uint32_t>();
1374661Sksewell@umich.edu
1385222Sksewell@umich.edu          case 8:
1394661Sksewell@umich.edu            return packet->get<uint64_t>();
1404661Sksewell@umich.edu
1414661Sksewell@umich.edu          default:
1424661Sksewell@umich.edu            std::cerr << "bad store data size = " << packet->getSize() << std::endl;
1434661Sksewell@umich.edu
1444661Sksewell@umich.edu            assert(0);
1454661Sksewell@umich.edu            return 0;
1464661Sksewell@umich.edu        }
1474661Sksewell@umich.edu    }
1484661Sksewell@umich.edu
1494661Sksewell@umich.edu
1502022SN/A}};
1512022SN/A
1522124SN/Adef template LoadStoreDeclare {{
1532124SN/A    /**
1542124SN/A     * Static instruction class for "%(mnemonic)s".
1552124SN/A     */
1562124SN/A    class %(class_name)s : public %(base_class)s
1572124SN/A    {
1582124SN/A      protected:
1592124SN/A
1602124SN/A        /**
1612124SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1622124SN/A         */
1632124SN/A        class EAComp : public %(base_class)s
1642124SN/A        {
1652124SN/A          public:
1662124SN/A            /// Constructor
1674661Sksewell@umich.edu            EAComp(ExtMachInst machInst);
1682124SN/A
1692124SN/A            %(BasicExecDeclare)s
1702124SN/A        };
1712124SN/A
1722124SN/A        /**
1732124SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1742124SN/A         */
1752124SN/A        class MemAcc : public %(base_class)s
1762124SN/A        {
1772124SN/A          public:
1782124SN/A            /// Constructor
1794661Sksewell@umich.edu            MemAcc(ExtMachInst machInst);
1802124SN/A
1812124SN/A            %(BasicExecDeclare)s
1822124SN/A        };
1832124SN/A
1842124SN/A      public:
1852124SN/A
1862124SN/A        /// Constructor.
1874661Sksewell@umich.edu        %(class_name)s(ExtMachInst machInst);
1882124SN/A
1892124SN/A        %(BasicExecDeclare)s
1902124SN/A
1912124SN/A        %(InitiateAccDeclare)s
1922124SN/A
1932124SN/A        %(CompleteAccDeclare)s
1944661Sksewell@umich.edu
1954661Sksewell@umich.edu        %(MemAccSizeDeclare)s
1962124SN/A    };
1972022SN/A}};
1982022SN/A
1992124SN/A
2002124SN/Adef template InitiateAccDeclare {{
2012132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
2022022SN/A}};
2032124SN/A
2042124SN/A
2052124SN/Adef template CompleteAccDeclare {{
2064661Sksewell@umich.edu    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
2072124SN/A}};
2082124SN/A
2094661Sksewell@umich.edudef template MemAccSizeDeclare {{
2104661Sksewell@umich.edu    int memAccSize(%(CPU_exec_context)s *xc);
2114661Sksewell@umich.edu}};
2122124SN/A
2135222Sksewell@umich.edu
2145222Sksewell@umich.edudef template MiscMemAccSize {{
2155222Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
2165222Sksewell@umich.edu    {
2175222Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
2185222Sksewell@umich.edu        return 0;
2195222Sksewell@umich.edu    }
2205222Sksewell@umich.edu}};
2215222Sksewell@umich.edu
2223953Sstever@eecs.umich.edudef template EACompConstructor {{
2232124SN/A    /** TODO: change op_class to AddrGenOp or something (requires
2242124SN/A     * creating new member of OpClass enum in op_class.hh, updating
2252124SN/A     * config files, etc.). */
2264661Sksewell@umich.edu    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
2272124SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2282124SN/A    {
2293953Sstever@eecs.umich.edu        %(constructor)s;
2302124SN/A    }
2313953Sstever@eecs.umich.edu}};
2322124SN/A
2333953Sstever@eecs.umich.edu
2343953Sstever@eecs.umich.edudef template MemAccConstructor {{
2354661Sksewell@umich.edu    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2362124SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2372124SN/A    {
2383953Sstever@eecs.umich.edu        %(constructor)s;
2392124SN/A    }
2403953Sstever@eecs.umich.edu}};
2412124SN/A
2423953Sstever@eecs.umich.edu
2433953Sstever@eecs.umich.edudef template LoadStoreConstructor {{
2444661Sksewell@umich.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2452124SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2462124SN/A                          new EAComp(machInst), new MemAcc(machInst))
2472124SN/A    {
2482124SN/A        %(constructor)s;
2492124SN/A    }
2502124SN/A}};
2512124SN/A
2522124SN/A
2532124SN/Adef template EACompExecute {{
2542132SN/A    Fault
2552124SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2562124SN/A                                   Trace::InstRecord *traceData) const
2572124SN/A    {
2582124SN/A        Addr EA;
2592132SN/A        Fault fault = NoFault;
2602124SN/A
2615222Sksewell@umich.edu        if (this->isFloating()) {
2625222Sksewell@umich.edu            %(fp_enable_check)s;
2635222Sksewell@umich.edu
2645222Sksewell@umich.edu            if(fault != NoFault)
2655222Sksewell@umich.edu                return fault;
2665222Sksewell@umich.edu        }
2675222Sksewell@umich.edu
2682124SN/A        %(op_decl)s;
2692124SN/A        %(op_rd)s;
2703953Sstever@eecs.umich.edu        %(ea_code)s;
2712124SN/A
2724661Sksewell@umich.edu        // NOTE: Trace Data is written using execute or completeAcc templates
2732124SN/A        if (fault == NoFault) {
2742124SN/A            xc->setEA(EA);
2752124SN/A        }
2762124SN/A
2772124SN/A        return fault;
2782124SN/A    }
2792124SN/A}};
2802124SN/A
2815222Sksewell@umich.edudef template LoadStoreFPEACompExecute {{
2825222Sksewell@umich.edu    Fault
2835222Sksewell@umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2845222Sksewell@umich.edu                                   Trace::InstRecord *traceData) const
2855222Sksewell@umich.edu    {
2865222Sksewell@umich.edu        Addr EA;
2875222Sksewell@umich.edu        Fault fault = NoFault;
2885222Sksewell@umich.edu
2895222Sksewell@umich.edu        %(fp_enable_check)s;
2905222Sksewell@umich.edu        if(fault != NoFault)
2915222Sksewell@umich.edu          return fault;
2925222Sksewell@umich.edu        %(op_decl)s;
2935222Sksewell@umich.edu        %(op_rd)s;
2945222Sksewell@umich.edu        %(ea_code)s;
2955222Sksewell@umich.edu
2965222Sksewell@umich.edu        // NOTE: Trace Data is written using execute or completeAcc templates
2975222Sksewell@umich.edu        if (fault == NoFault) {
2985222Sksewell@umich.edu            xc->setEA(EA);
2995222Sksewell@umich.edu        }
3005222Sksewell@umich.edu
3015222Sksewell@umich.edu        return fault;
3025222Sksewell@umich.edu    }
3035222Sksewell@umich.edu}};
3045222Sksewell@umich.edu
3055222Sksewell@umich.edu
3062124SN/Adef template LoadMemAccExecute {{
3072132SN/A    Fault
3082124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3092124SN/A                                   Trace::InstRecord *traceData) const
3102124SN/A    {
3112239SN/A        Addr EA;
3125222Sksewell@umich.edu
3132132SN/A        Fault fault = NoFault;
3142239SN/A
3155222Sksewell@umich.edu        if (this->isFloating()) {
3165222Sksewell@umich.edu            %(fp_enable_check)s;
3175222Sksewell@umich.edu
3185222Sksewell@umich.edu            if(fault != NoFault)
3195222Sksewell@umich.edu                return fault;
3205222Sksewell@umich.edu        }
3215222Sksewell@umich.edu
3222239SN/A        %(op_decl)s;
3232239SN/A        %(op_rd)s;
3244661Sksewell@umich.edu
3252239SN/A        EA = xc->getEA();
3262239SN/A
3274661Sksewell@umich.edu        fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
3282239SN/A
3294661Sksewell@umich.edu        %(memacc_code)s;
3304661Sksewell@umich.edu
3314661Sksewell@umich.edu        // NOTE: Write back data using execute or completeAcc templates
3322239SN/A
3332124SN/A        return fault;
3342124SN/A    }
3352124SN/A}};
3362124SN/A
3372124SN/A
3382124SN/Adef template LoadExecute {{
3392132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3402124SN/A                                  Trace::InstRecord *traceData) const
3412124SN/A    {
3422124SN/A        Addr EA;
3432132SN/A        Fault fault = NoFault;
3442124SN/A
3455222Sksewell@umich.edu        if (this->isFloating()) {
3465222Sksewell@umich.edu            %(fp_enable_check)s;
3475222Sksewell@umich.edu
3485222Sksewell@umich.edu            if(fault != NoFault)
3495222Sksewell@umich.edu                return fault;
3505222Sksewell@umich.edu        }
3515222Sksewell@umich.edu
3522124SN/A        %(op_decl)s;
3532124SN/A        %(op_rd)s;
3542124SN/A        %(ea_code)s;
3552124SN/A
3562124SN/A        if (fault == NoFault) {
3572124SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
3582124SN/A            %(memacc_code)s;
3592124SN/A        }
3602124SN/A
3612124SN/A        if (fault == NoFault) {
3622124SN/A            %(op_wb)s;
3632124SN/A        }
3642124SN/A
3652124SN/A        return fault;
3662124SN/A    }
3672124SN/A}};
3682124SN/A
3692124SN/A
3702124SN/Adef template LoadInitiateAcc {{
3712132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3722124SN/A                                      Trace::InstRecord *traceData) const
3732124SN/A    {
3742239SN/A        Addr EA;
3752132SN/A        Fault fault = NoFault;
3762239SN/A
3775222Sksewell@umich.edu        if (this->isFloating()) {
3785222Sksewell@umich.edu            %(fp_enable_check)s;
3795222Sksewell@umich.edu
3805222Sksewell@umich.edu            if(fault != NoFault)
3815222Sksewell@umich.edu                return fault;
3825222Sksewell@umich.edu        }
3835222Sksewell@umich.edu
3842239SN/A        %(op_src_decl)s;
3852239SN/A        %(op_rd)s;
3862239SN/A        %(ea_code)s;
3872239SN/A
3882239SN/A        if (fault == NoFault) {
3892239SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3902239SN/A        }
3912239SN/A
3922124SN/A        return fault;
3932124SN/A    }
3942124SN/A}};
3952124SN/A
3962124SN/Adef template LoadCompleteAcc {{
3974661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
3982124SN/A                                      %(CPU_exec_context)s *xc,
3992124SN/A                                      Trace::InstRecord *traceData) const
4002124SN/A    {
4012132SN/A        Fault fault = NoFault;
4022239SN/A
4035222Sksewell@umich.edu        if (this->isFloating()) {
4045222Sksewell@umich.edu            %(fp_enable_check)s;
4055222Sksewell@umich.edu
4065222Sksewell@umich.edu            if(fault != NoFault)
4075222Sksewell@umich.edu                return fault;
4085222Sksewell@umich.edu        }
4095222Sksewell@umich.edu
4102506SN/A        %(op_decl)s;
4114661Sksewell@umich.edu        %(op_rd)s;
4122239SN/A
4132935Sksewell@umich.edu        Mem = pkt->get<typeof(Mem)>();
4142239SN/A
4152239SN/A        if (fault == NoFault) {
4162239SN/A            %(memacc_code)s;
4172239SN/A        }
4182239SN/A
4192239SN/A        if (fault == NoFault) {
4202239SN/A            %(op_wb)s;
4212239SN/A        }
4222239SN/A
4232124SN/A        return fault;
4242124SN/A    }
4252124SN/A}};
4262124SN/A
4272124SN/A
4284661Sksewell@umich.edudef template LoadStoreMemAccSize {{
4294661Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
4304661Sksewell@umich.edu    {
4314661Sksewell@umich.edu        // Return the memory access size in bytes
4324661Sksewell@umich.edu        return (%(mem_acc_size)d / 8);
4334661Sksewell@umich.edu    }
4344661Sksewell@umich.edu}};
4354661Sksewell@umich.edu
4362124SN/Adef template StoreMemAccExecute {{
4372132SN/A    Fault
4382124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4392124SN/A                                   Trace::InstRecord *traceData) const
4402124SN/A    {
4412239SN/A        Addr EA;
4422132SN/A        Fault fault = NoFault;
4434056Sstever@eecs.umich.edu
4444056Sstever@eecs.umich.edu        %(fp_enable_check)s;
4454056Sstever@eecs.umich.edu        %(op_decl)s;
4464056Sstever@eecs.umich.edu        %(op_rd)s;
4474661Sksewell@umich.edu
4484056Sstever@eecs.umich.edu        EA = xc->getEA();
4494056Sstever@eecs.umich.edu
4504056Sstever@eecs.umich.edu        if (fault == NoFault) {
4514056Sstever@eecs.umich.edu            %(memacc_code)s;
4524056Sstever@eecs.umich.edu        }
4534056Sstever@eecs.umich.edu
4544056Sstever@eecs.umich.edu        if (fault == NoFault) {
4554056Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4564675Sksewell@umich.edu                              memAccessFlags, NULL);
4574661Sksewell@umich.edu            // @NOTE: Need to Call Complete Access to Set Trace Data
4584661Sksewell@umich.edu            //if (traceData) { traceData->setData(Mem); }
4594056Sstever@eecs.umich.edu        }
4604056Sstever@eecs.umich.edu
4614056Sstever@eecs.umich.edu        return fault;
4624056Sstever@eecs.umich.edu    }
4634056Sstever@eecs.umich.edu}};
4644056Sstever@eecs.umich.edu
4654056Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{
4664056Sstever@eecs.umich.edu    Fault
4674056Sstever@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4684056Sstever@eecs.umich.edu                                   Trace::InstRecord *traceData) const
4694056Sstever@eecs.umich.edu    {
4704056Sstever@eecs.umich.edu        Addr EA;
4714056Sstever@eecs.umich.edu        Fault fault = NoFault;
4722239SN/A        uint64_t write_result = 0;
4732239SN/A
4742239SN/A        %(fp_enable_check)s;
4752239SN/A        %(op_decl)s;
4762239SN/A        %(op_rd)s;
4772239SN/A        EA = xc->getEA();
4782239SN/A
4792239SN/A        if (fault == NoFault) {
4803953Sstever@eecs.umich.edu            %(memacc_code)s;
4812239SN/A        }
4822239SN/A
4832239SN/A        if (fault == NoFault) {
4842239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4852239SN/A                              memAccessFlags, &write_result);
4862239SN/A            if (traceData) { traceData->setData(Mem); }
4872239SN/A        }
4882239SN/A
4892239SN/A        if (fault == NoFault) {
4902239SN/A            %(postacc_code)s;
4912239SN/A        }
4922239SN/A
4932239SN/A        if (fault == NoFault) {
4942239SN/A            %(op_wb)s;
4952239SN/A        }
4962239SN/A
4972124SN/A        return fault;
4982124SN/A    }
4992124SN/A}};
5002124SN/A
5012124SN/Adef template StoreExecute {{
5022132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5032124SN/A                                  Trace::InstRecord *traceData) const
5042124SN/A    {
5052124SN/A        Addr EA;
5062132SN/A        Fault fault = NoFault;
5074056Sstever@eecs.umich.edu
5084056Sstever@eecs.umich.edu        %(fp_enable_check)s;
5094056Sstever@eecs.umich.edu        %(op_decl)s;
5104056Sstever@eecs.umich.edu        %(op_rd)s;
5114056Sstever@eecs.umich.edu        %(ea_code)s;
5124056Sstever@eecs.umich.edu
5134056Sstever@eecs.umich.edu        if (fault == NoFault) {
5144056Sstever@eecs.umich.edu            %(memacc_code)s;
5154056Sstever@eecs.umich.edu        }
5164056Sstever@eecs.umich.edu
5174056Sstever@eecs.umich.edu        if (fault == NoFault) {
5184056Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5194675Sksewell@umich.edu                              memAccessFlags, NULL);
5204056Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
5214056Sstever@eecs.umich.edu        }
5224056Sstever@eecs.umich.edu
5234056Sstever@eecs.umich.edu        if (fault == NoFault) {
5244056Sstever@eecs.umich.edu            %(postacc_code)s;
5254056Sstever@eecs.umich.edu        }
5264056Sstever@eecs.umich.edu
5274056Sstever@eecs.umich.edu        if (fault == NoFault) {
5284056Sstever@eecs.umich.edu            %(op_wb)s;
5294056Sstever@eecs.umich.edu        }
5304056Sstever@eecs.umich.edu
5314056Sstever@eecs.umich.edu        return fault;
5324056Sstever@eecs.umich.edu    }
5334056Sstever@eecs.umich.edu}};
5344056Sstever@eecs.umich.edu
5355222Sksewell@umich.edu
5365222Sksewell@umich.edudef template StoreFPExecute {{
5375222Sksewell@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5385222Sksewell@umich.edu                                  Trace::InstRecord *traceData) const
5395222Sksewell@umich.edu    {
5405222Sksewell@umich.edu        Addr EA;
5415222Sksewell@umich.edu        Fault fault = NoFault;
5425222Sksewell@umich.edu
5435222Sksewell@umich.edu        %(fp_enable_check)s;
5445222Sksewell@umich.edu        if(fault != NoFault)
5455222Sksewell@umich.edu          return fault;
5465222Sksewell@umich.edu        %(op_decl)s;
5475222Sksewell@umich.edu        %(op_rd)s;
5485222Sksewell@umich.edu        %(ea_code)s;
5495222Sksewell@umich.edu
5505222Sksewell@umich.edu        if (fault == NoFault) {
5515222Sksewell@umich.edu            %(memacc_code)s;
5525222Sksewell@umich.edu        }
5535222Sksewell@umich.edu
5545222Sksewell@umich.edu        if (fault == NoFault) {
5555222Sksewell@umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5565222Sksewell@umich.edu                              memAccessFlags, NULL);
5575222Sksewell@umich.edu            if (traceData) { traceData->setData(Mem); }
5585222Sksewell@umich.edu        }
5595222Sksewell@umich.edu
5605222Sksewell@umich.edu        if (fault == NoFault) {
5615222Sksewell@umich.edu            %(postacc_code)s;
5625222Sksewell@umich.edu        }
5635222Sksewell@umich.edu
5645222Sksewell@umich.edu        if (fault == NoFault) {
5655222Sksewell@umich.edu            %(op_wb)s;
5665222Sksewell@umich.edu        }
5675222Sksewell@umich.edu
5685222Sksewell@umich.edu        return fault;
5695222Sksewell@umich.edu    }
5705222Sksewell@umich.edu}};
5715222Sksewell@umich.edu
5724056Sstever@eecs.umich.edudef template StoreCondExecute {{
5734056Sstever@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5744056Sstever@eecs.umich.edu                                  Trace::InstRecord *traceData) const
5754056Sstever@eecs.umich.edu    {
5764056Sstever@eecs.umich.edu        Addr EA;
5774056Sstever@eecs.umich.edu        Fault fault = NoFault;
5782124SN/A        uint64_t write_result = 0;
5792124SN/A
5802124SN/A        %(fp_enable_check)s;
5812124SN/A        %(op_decl)s;
5822124SN/A        %(op_rd)s;
5832124SN/A        %(ea_code)s;
5842124SN/A
5852124SN/A        if (fault == NoFault) {
5862124SN/A            %(memacc_code)s;
5872124SN/A        }
5882124SN/A
5892124SN/A        if (fault == NoFault) {
5902124SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5912124SN/A                              memAccessFlags, &write_result);
5922124SN/A            if (traceData) { traceData->setData(Mem); }
5932124SN/A        }
5942124SN/A
5952124SN/A        if (fault == NoFault) {
5962124SN/A            %(postacc_code)s;
5972124SN/A        }
5982124SN/A
5992124SN/A        if (fault == NoFault) {
6002124SN/A            %(op_wb)s;
6012124SN/A        }
6022124SN/A
6032124SN/A        return fault;
6042124SN/A    }
6052124SN/A}};
6062124SN/A
6072124SN/Adef template StoreInitiateAcc {{
6082132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
6092124SN/A                                      Trace::InstRecord *traceData) const
6102124SN/A    {
6112239SN/A        Addr EA;
6122132SN/A        Fault fault = NoFault;
6132239SN/A
6142239SN/A        %(fp_enable_check)s;
6152506SN/A        %(op_decl)s;
6162239SN/A        %(op_rd)s;
6172239SN/A        %(ea_code)s;
6182239SN/A
6192239SN/A        if (fault == NoFault) {
6202239SN/A            %(memacc_code)s;
6212239SN/A        }
6222239SN/A
6232239SN/A        if (fault == NoFault) {
6242239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
6252935Sksewell@umich.edu                              memAccessFlags, NULL);
6262239SN/A            if (traceData) { traceData->setData(Mem); }
6272239SN/A        }
6282239SN/A
6292124SN/A        return fault;
6302124SN/A    }
6312124SN/A}};
6322124SN/A
6332124SN/A
6342124SN/Adef template StoreCompleteAcc {{
6354661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
6362124SN/A                                      %(CPU_exec_context)s *xc,
6372124SN/A                                      Trace::InstRecord *traceData) const
6382124SN/A    {
6392132SN/A        Fault fault = NoFault;
6402239SN/A
6412239SN/A        %(fp_enable_check)s;
6422239SN/A        %(op_dest_decl)s;
6432239SN/A
6442935Sksewell@umich.edu        if (fault == NoFault) {
6452935Sksewell@umich.edu            %(postacc_code)s;
6462935Sksewell@umich.edu        }
6472935Sksewell@umich.edu
6482935Sksewell@umich.edu        if (fault == NoFault) {
6492935Sksewell@umich.edu            %(op_wb)s;
6504661Sksewell@umich.edu
6515222Sksewell@umich.edu            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
6525222Sksewell@umich.edu        }
6535222Sksewell@umich.edu
6545222Sksewell@umich.edu        return fault;
6555222Sksewell@umich.edu    }
6565222Sksewell@umich.edu}};
6575222Sksewell@umich.edu
6585222Sksewell@umich.edu
6595222Sksewell@umich.edudef template StoreCompleteAcc {{
6605222Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
6615222Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
6625222Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
6635222Sksewell@umich.edu    {
6645222Sksewell@umich.edu        Fault fault = NoFault;
6655222Sksewell@umich.edu
6665222Sksewell@umich.edu        %(op_dest_decl)s;
6675222Sksewell@umich.edu
6685222Sksewell@umich.edu        if (fault == NoFault) {
6695222Sksewell@umich.edu            %(postacc_code)s;
6705222Sksewell@umich.edu        }
6715222Sksewell@umich.edu
6725222Sksewell@umich.edu        if (fault == NoFault) {
6735222Sksewell@umich.edu            %(op_wb)s;
6745222Sksewell@umich.edu
6755222Sksewell@umich.edu            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
6762935Sksewell@umich.edu        }
6772935Sksewell@umich.edu
6782935Sksewell@umich.edu        return fault;
6792935Sksewell@umich.edu    }
6802935Sksewell@umich.edu}};
6812935Sksewell@umich.edu
6822935Sksewell@umich.edudef template StoreCondCompleteAcc {{
6834661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
6842935Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
6852935Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
6862935Sksewell@umich.edu    {
6872935Sksewell@umich.edu        Fault fault = NoFault;
6882935Sksewell@umich.edu
6892935Sksewell@umich.edu        %(fp_enable_check)s;
6902935Sksewell@umich.edu        %(op_dest_decl)s;
6912935Sksewell@umich.edu
6924055Ssaidi@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
6932239SN/A
6942239SN/A        if (fault == NoFault) {
6952239SN/A            %(postacc_code)s;
6962239SN/A        }
6972239SN/A
6982239SN/A        if (fault == NoFault) {
6992239SN/A            %(op_wb)s;
7002239SN/A        }
7012239SN/A
7022124SN/A        return fault;
7032124SN/A    }
7042124SN/A}};
7052124SN/A
7062686Sksewell@umich.edu
7072686Sksewell@umich.edudef template MiscMemAccExecute {{
7082686Sksewell@umich.edu    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
7092686Sksewell@umich.edu                                          Trace::InstRecord *traceData) const
7102686Sksewell@umich.edu    {
7112686Sksewell@umich.edu        Addr EA;
7122686Sksewell@umich.edu        Fault fault = NoFault;
7132686Sksewell@umich.edu
7142686Sksewell@umich.edu        %(fp_enable_check)s;
7152686Sksewell@umich.edu        %(op_decl)s;
7162686Sksewell@umich.edu        %(op_rd)s;
7172686Sksewell@umich.edu        EA = xc->getEA();
7182686Sksewell@umich.edu
7192686Sksewell@umich.edu        if (fault == NoFault) {
7203953Sstever@eecs.umich.edu            %(memacc_code)s;
7212686Sksewell@umich.edu        }
7222686Sksewell@umich.edu
7232686Sksewell@umich.edu        return NoFault;
7242686Sksewell@umich.edu    }
7252686Sksewell@umich.edu}};
7262686Sksewell@umich.edu
7272686Sksewell@umich.edudef template MiscExecute {{
7282686Sksewell@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
7292686Sksewell@umich.edu                                  Trace::InstRecord *traceData) const
7302686Sksewell@umich.edu    {
7312686Sksewell@umich.edu        Addr EA;
7322686Sksewell@umich.edu        Fault fault = NoFault;
7332686Sksewell@umich.edu
7342686Sksewell@umich.edu        %(fp_enable_check)s;
7352686Sksewell@umich.edu        %(op_decl)s;
7362686Sksewell@umich.edu        %(op_rd)s;
7372686Sksewell@umich.edu        %(ea_code)s;
7382686Sksewell@umich.edu
7392686Sksewell@umich.edu        if (fault == NoFault) {
7402686Sksewell@umich.edu            %(memacc_code)s;
7412686Sksewell@umich.edu        }
7422686Sksewell@umich.edu
7432686Sksewell@umich.edu        return NoFault;
7442686Sksewell@umich.edu    }
7452686Sksewell@umich.edu}};
7462686Sksewell@umich.edu
7472686Sksewell@umich.edudef template MiscInitiateAcc {{
7482686Sksewell@umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
7492686Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
7502686Sksewell@umich.edu    {
7512686Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
7522686Sksewell@umich.edu        return NoFault;
7532686Sksewell@umich.edu    }
7542686Sksewell@umich.edu}};
7552686Sksewell@umich.edu
7562686Sksewell@umich.edu
7572686Sksewell@umich.edudef template MiscCompleteAcc {{
7584661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
7592686Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
7602686Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
7612686Sksewell@umich.edu    {
7622686Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
7632686Sksewell@umich.edu
7642686Sksewell@umich.edu        return NoFault;
7652686Sksewell@umich.edu    }
7662686Sksewell@umich.edu}};
7672686Sksewell@umich.edu
7684661Sksewell@umich.edu
7694661Sksewell@umich.edudef template MiscMemAccSize {{
7704661Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
7714661Sksewell@umich.edu    {
7724661Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
7734661Sksewell@umich.edu        return 0;
7744661Sksewell@umich.edu    }
7754661Sksewell@umich.edu}};
7764661Sksewell@umich.edu
7772124SN/Adef format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
7782124SN/A                     mem_flags = [], inst_flags = []) {{
7792124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7802124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7812750Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
7822124SN/A                      exec_template_base = 'Load')
7832124SN/A}};
7842124SN/A
7855222Sksewell@umich.edu
7862124SN/Adef format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
7872124SN/A                     mem_flags = [], inst_flags = []) {{
7882124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7892124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7902124SN/A                      exec_template_base = 'Store')
7912124SN/A}};
7922124SN/A
7932686Sksewell@umich.edudef format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
7942573SN/A                     mem_flags = [], inst_flags = []) {{
7955222Sksewell@umich.edu    inst_flags += ['IsIndexed']
7962573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7972573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7982750Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
7992573SN/A                      exec_template_base = 'Load')
8002573SN/A}};
8012573SN/A
8022686Sksewell@umich.edudef format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
8032573SN/A                     mem_flags = [], inst_flags = []) {{
8045222Sksewell@umich.edu    inst_flags += ['IsIndexed']
8052573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
8062573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8072573SN/A                      exec_template_base = 'Store')
8082573SN/A}};
8092573SN/A
8105222Sksewell@umich.edudef format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
8115222Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8125222Sksewell@umich.edu    inst_flags += ['IsIndexed', 'IsFloating']
8135222Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8145222Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8155222Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
8165222Sksewell@umich.edu                      exec_template_base = 'Load')
8175222Sksewell@umich.edu}};
8185222Sksewell@umich.edu
8195222Sksewell@umich.edudef format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
8205222Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8215222Sksewell@umich.edu    inst_flags += ['IsIndexed', 'IsFloating']
8225222Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8235222Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8245222Sksewell@umich.edu                      exec_template_base = 'Store')
8255222Sksewell@umich.edu}};
8265222Sksewell@umich.edu
8275222Sksewell@umich.edu
8282686Sksewell@umich.edudef format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
8292686Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8302686Sksewell@umich.edu    decl_code = 'uint32_t mem_word = Mem.uw;\n'
8312686Sksewell@umich.edu    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
8322686Sksewell@umich.edu    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
8332686Sksewell@umich.edu    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
8342686Sksewell@umich.edu    decl_code += '\tbyte_offset ^= 3;\n'
8352686Sksewell@umich.edu    decl_code += '#endif\n'
8362573SN/A
8372686Sksewell@umich.edu    memacc_code = decl_code + memacc_code
8382686Sksewell@umich.edu
8392686Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8402686Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8412750Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
8422686Sksewell@umich.edu                      exec_template_base = 'Load')
8432686Sksewell@umich.edu}};
8442686Sksewell@umich.edu
8452686Sksewell@umich.edudef format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
8462686Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8472686Sksewell@umich.edu    decl_code = 'uint32_t mem_word = 0;\n'
8482686Sksewell@umich.edu    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
8492686Sksewell@umich.edu    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
8502686Sksewell@umich.edu    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
8512686Sksewell@umich.edu    decl_code += '\tbyte_offset ^= 3;\n'
8522686Sksewell@umich.edu    decl_code += '#endif\n'
8532686Sksewell@umich.edu    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
8544661Sksewell@umich.edu    #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
8552686Sksewell@umich.edu    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
8562686Sksewell@umich.edu
8572686Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8582686Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8592686Sksewell@umich.edu                      exec_template_base = 'Store')
8602686Sksewell@umich.edu}};
8612686Sksewell@umich.edu
8622686Sksewell@umich.edudef format Prefetch(ea_code = {{ EA = Rs + disp; }},
8632686Sksewell@umich.edu                          mem_flags = [], pf_flags = [], inst_flags = []) {{
8642686Sksewell@umich.edu    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
8652686Sksewell@umich.edu    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
8662686Sksewell@umich.edu                                  'IsDataPrefetch', 'MemReadOp']
8672686Sksewell@umich.edu
8682686Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8692686Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code,
8702686Sksewell@umich.edu                      'xc->prefetch(EA, memAccessFlags);',
8712686Sksewell@umich.edu                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
8722686Sksewell@umich.edu
8732686Sksewell@umich.edu}};
8742686Sksewell@umich.edu
8752686Sksewell@umich.edudef format StoreCond(memacc_code, postacc_code,
8762686Sksewell@umich.edu                     ea_code = {{ EA = Rs + disp; }},
8772495SN/A                     mem_flags = [], inst_flags = []) {{
8782495SN/A    (header_output, decoder_output, decode_block, exec_output) = \
8792495SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8802935Sksewell@umich.edu                      postacc_code, exec_template_base = 'StoreCond')
8812495SN/A}};
882