mem.isa revision 4027:53292b42ee1c
15081Sgblack@eecs.umich.edu// -*- mode:c++ -*-
25081Sgblack@eecs.umich.edu
35081Sgblack@eecs.umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
47087Snate@binkert.org// All rights reserved.
57087Snate@binkert.org//
67087Snate@binkert.org// Redistribution and use in source and binary forms, with or without
77087Snate@binkert.org// modification, are permitted provided that the following conditions are
87087Snate@binkert.org// met: redistributions of source code must retain the above copyright
97087Snate@binkert.org// notice, this list of conditions and the following disclaimer;
107087Snate@binkert.org// redistributions in binary form must reproduce the above copyright
117087Snate@binkert.org// notice, this list of conditions and the following disclaimer in the
125081Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
137087Snate@binkert.org// neither the name of the copyright holders nor the names of its
147087Snate@binkert.org// contributors may be used to endorse or promote products derived from
157087Snate@binkert.org// this software without specific prior written permission.
167087Snate@binkert.org//
177087Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187087Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
197087Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
207087Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215081Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
227087Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235081Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245081Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255081Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265081Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275081Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285081Sgblack@eecs.umich.edu//
295081Sgblack@eecs.umich.edu// Authors: Steve Reinhardt
305081Sgblack@eecs.umich.edu//          Kevin Lim
315081Sgblack@eecs.umich.edu
325081Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
335081Sgblack@eecs.umich.edu//
345081Sgblack@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store
355081Sgblack@eecs.umich.edu//
365081Sgblack@eecs.umich.edu
375081Sgblack@eecs.umich.eduoutput header {{
385081Sgblack@eecs.umich.edu    /**
395081Sgblack@eecs.umich.edu     * Base class for general Alpha memory-format instructions.
405081Sgblack@eecs.umich.edu     */
415081Sgblack@eecs.umich.edu    class Memory : public AlphaStaticInst
425081Sgblack@eecs.umich.edu    {
435081Sgblack@eecs.umich.edu      protected:
445081Sgblack@eecs.umich.edu
455081Sgblack@eecs.umich.edu        /// Memory request flags.  See mem_req_base.hh.
465081Sgblack@eecs.umich.edu        unsigned memAccessFlags;
475119Sgblack@eecs.umich.edu        /// Pointer to EAComp object.
485081Sgblack@eecs.umich.edu        const StaticInstPtr eaCompPtr;
495081Sgblack@eecs.umich.edu        /// Pointer to MemAcc object.
505081Sgblack@eecs.umich.edu        const StaticInstPtr memAccPtr;
515081Sgblack@eecs.umich.edu
525081Sgblack@eecs.umich.edu        /// Constructor
535081Sgblack@eecs.umich.edu        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
545081Sgblack@eecs.umich.edu               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
555081Sgblack@eecs.umich.edu               StaticInstPtr _memAccPtr = nullStaticInstPtr)
565119Sgblack@eecs.umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass),
575081Sgblack@eecs.umich.edu              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
585081Sgblack@eecs.umich.edu        {
595081Sgblack@eecs.umich.edu        }
605081Sgblack@eecs.umich.edu
616082Sgblack@eecs.umich.edu        std::string
626082Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
636082Sgblack@eecs.umich.edu
648610Snilay@cs.wisc.edu      public:
656082Sgblack@eecs.umich.edu
666082Sgblack@eecs.umich.edu        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
676082Sgblack@eecs.umich.edu        const StaticInstPtr &memAccInst() const { return memAccPtr; }
688610Snilay@cs.wisc.edu    };
696082Sgblack@eecs.umich.edu
706082Sgblack@eecs.umich.edu    /**
716082Sgblack@eecs.umich.edu     * Base class for memory-format instructions using a 32-bit
726082Sgblack@eecs.umich.edu     * displacement (i.e. most of them).
736082Sgblack@eecs.umich.edu     */
746082Sgblack@eecs.umich.edu    class MemoryDisp32 : public Memory
758610Snilay@cs.wisc.edu    {
766082Sgblack@eecs.umich.edu      protected:
776082Sgblack@eecs.umich.edu        /// Displacement for EA calculation (signed).
786082Sgblack@eecs.umich.edu        int32_t disp;
798610Snilay@cs.wisc.edu
806082Sgblack@eecs.umich.edu        /// Constructor.
816082Sgblack@eecs.umich.edu        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
825081Sgblack@eecs.umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
835081Sgblack@eecs.umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
845119Sgblack@eecs.umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
855081Sgblack@eecs.umich.edu              disp(MEMDISP)
865081Sgblack@eecs.umich.edu        {
875081Sgblack@eecs.umich.edu        }
885081Sgblack@eecs.umich.edu    };
895081Sgblack@eecs.umich.edu
905081Sgblack@eecs.umich.edu
915081Sgblack@eecs.umich.edu    /**
925119Sgblack@eecs.umich.edu     * Base class for a few miscellaneous memory-format insts
935081Sgblack@eecs.umich.edu     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
945081Sgblack@eecs.umich.edu     * None of these instructions has a destination register either.
955081Sgblack@eecs.umich.edu     */
965081Sgblack@eecs.umich.edu    class MemoryNoDisp : public Memory
976082Sgblack@eecs.umich.edu    {
986082Sgblack@eecs.umich.edu      protected:
998610Snilay@cs.wisc.edu        /// Constructor
1006082Sgblack@eecs.umich.edu        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1016082Sgblack@eecs.umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
1026082Sgblack@eecs.umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
1038610Snilay@cs.wisc.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
1046082Sgblack@eecs.umich.edu        {
1056082Sgblack@eecs.umich.edu        }
1066082Sgblack@eecs.umich.edu
1076082Sgblack@eecs.umich.edu        std::string
1086082Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1098610Snilay@cs.wisc.edu    };
1106082Sgblack@eecs.umich.edu}};
1116082Sgblack@eecs.umich.edu
1126082Sgblack@eecs.umich.edu
1138610Snilay@cs.wisc.eduoutput decoder {{
1146082Sgblack@eecs.umich.edu    std::string
1156082Sgblack@eecs.umich.edu    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1165081Sgblack@eecs.umich.edu    {
1175081Sgblack@eecs.umich.edu        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1185081Sgblack@eecs.umich.edu                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1195081Sgblack@eecs.umich.edu    }
1205081Sgblack@eecs.umich.edu
1215081Sgblack@eecs.umich.edu    std::string
1225081Sgblack@eecs.umich.edu    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1235081Sgblack@eecs.umich.edu    {
1245081Sgblack@eecs.umich.edu        return csprintf("%-10s (r%d)", mnemonic, RB);
1255081Sgblack@eecs.umich.edu    }
1265081Sgblack@eecs.umich.edu}};
1275081Sgblack@eecs.umich.edu
1285081Sgblack@eecs.umich.edudef format LoadAddress(code) {{
1295081Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1305081Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
1315081Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
1325081Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
1335081Sgblack@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
1345081Sgblack@eecs.umich.edu}};
1355081Sgblack@eecs.umich.edu
1365081Sgblack@eecs.umich.edu
1375081Sgblack@eecs.umich.edudef template LoadStoreDeclare {{
1385081Sgblack@eecs.umich.edu    /**
1395081Sgblack@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
1405081Sgblack@eecs.umich.edu     */
1415081Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
1425081Sgblack@eecs.umich.edu    {
1435081Sgblack@eecs.umich.edu      protected:
1445081Sgblack@eecs.umich.edu
1455081Sgblack@eecs.umich.edu        /**
1465081Sgblack@eecs.umich.edu         * "Fake" effective address computation class for "%(mnemonic)s".
1475081Sgblack@eecs.umich.edu         */
1485081Sgblack@eecs.umich.edu        class EAComp : public %(base_class)s
1495119Sgblack@eecs.umich.edu        {
1505081Sgblack@eecs.umich.edu          public:
1515081Sgblack@eecs.umich.edu            /// Constructor
1525081Sgblack@eecs.umich.edu            EAComp(ExtMachInst machInst);
1535081Sgblack@eecs.umich.edu
1545081Sgblack@eecs.umich.edu            %(BasicExecDeclare)s
1555081Sgblack@eecs.umich.edu        };
1565081Sgblack@eecs.umich.edu
1575081Sgblack@eecs.umich.edu        /**
1585119Sgblack@eecs.umich.edu         * "Fake" memory access instruction class for "%(mnemonic)s".
1595081Sgblack@eecs.umich.edu         */
1605081Sgblack@eecs.umich.edu        class MemAcc : public %(base_class)s
1615081Sgblack@eecs.umich.edu        {
1625081Sgblack@eecs.umich.edu          public:
1636087Sgblack@eecs.umich.edu            /// Constructor
1646087Sgblack@eecs.umich.edu            MemAcc(ExtMachInst machInst);
1656087Sgblack@eecs.umich.edu
1668610Snilay@cs.wisc.edu            %(BasicExecDeclare)s
1676087Sgblack@eecs.umich.edu        };
1686087Sgblack@eecs.umich.edu
1696087Sgblack@eecs.umich.edu      public:
1708610Snilay@cs.wisc.edu
1716087Sgblack@eecs.umich.edu        /// Constructor.
1726087Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst);
1736087Sgblack@eecs.umich.edu
1746087Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
1756087Sgblack@eecs.umich.edu
1766087Sgblack@eecs.umich.edu        %(InitiateAccDeclare)s
1778610Snilay@cs.wisc.edu
1786087Sgblack@eecs.umich.edu        %(CompleteAccDeclare)s
1796087Sgblack@eecs.umich.edu    };
1806087Sgblack@eecs.umich.edu}};
1818610Snilay@cs.wisc.edu
1826087Sgblack@eecs.umich.edu
1836087Sgblack@eecs.umich.edudef template InitiateAccDeclare {{
1845081Sgblack@eecs.umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1855081Sgblack@eecs.umich.edu}};
1865119Sgblack@eecs.umich.edu
1875081Sgblack@eecs.umich.edu
1885081Sgblack@eecs.umich.edudef template CompleteAccDeclare {{
1895081Sgblack@eecs.umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1905081Sgblack@eecs.umich.edu                      Trace::InstRecord *) const;
1915081Sgblack@eecs.umich.edu}};
1925081Sgblack@eecs.umich.edu
1935081Sgblack@eecs.umich.edu
1945119Sgblack@eecs.umich.edudef template EACompConstructor {{
1955081Sgblack@eecs.umich.edu    /** TODO: change op_class to AddrGenOp or something (requires
1965081Sgblack@eecs.umich.edu     * creating new member of OpClass enum in op_class.hh, updating
1975081Sgblack@eecs.umich.edu     * config files, etc.). */
1985081Sgblack@eecs.umich.edu    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
1996087Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2006087Sgblack@eecs.umich.edu    {
2018610Snilay@cs.wisc.edu        %(constructor)s;
2026087Sgblack@eecs.umich.edu    }
2036087Sgblack@eecs.umich.edu}};
2046087Sgblack@eecs.umich.edu
2058610Snilay@cs.wisc.edu
2066087Sgblack@eecs.umich.edudef template MemAccConstructor {{
2076087Sgblack@eecs.umich.edu    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2086087Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2096087Sgblack@eecs.umich.edu    {
2106087Sgblack@eecs.umich.edu        %(constructor)s;
2118610Snilay@cs.wisc.edu    }
2126087Sgblack@eecs.umich.edu}};
2136087Sgblack@eecs.umich.edu
2146087Sgblack@eecs.umich.edu
2158610Snilay@cs.wisc.edudef template LoadStoreConstructor {{
2166087Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2176087Sgblack@eecs.umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2185081Sgblack@eecs.umich.edu                          new EAComp(machInst), new MemAcc(machInst))
2195081Sgblack@eecs.umich.edu    {
2205081Sgblack@eecs.umich.edu        %(constructor)s;
2215081Sgblack@eecs.umich.edu    }
2225081Sgblack@eecs.umich.edu}};
2235081Sgblack@eecs.umich.edu
2245081Sgblack@eecs.umich.edu
2255081Sgblack@eecs.umich.edudef template EACompExecute {{
2265081Sgblack@eecs.umich.edu    Fault
2275081Sgblack@eecs.umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2285081Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
2295081Sgblack@eecs.umich.edu    {
2305081Sgblack@eecs.umich.edu        Addr EA;
2315081Sgblack@eecs.umich.edu        Fault fault = NoFault;
2325081Sgblack@eecs.umich.edu
2335081Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2345081Sgblack@eecs.umich.edu        %(op_decl)s;
2355081Sgblack@eecs.umich.edu        %(op_rd)s;
2365081Sgblack@eecs.umich.edu        %(ea_code)s;
2375081Sgblack@eecs.umich.edu
2385081Sgblack@eecs.umich.edu        if (fault == NoFault) {
2395081Sgblack@eecs.umich.edu            %(op_wb)s;
2405081Sgblack@eecs.umich.edu            xc->setEA(EA);
2415081Sgblack@eecs.umich.edu        }
2425081Sgblack@eecs.umich.edu
2435081Sgblack@eecs.umich.edu        return fault;
2445081Sgblack@eecs.umich.edu    }
2455081Sgblack@eecs.umich.edu}};
2465081Sgblack@eecs.umich.edu
2475081Sgblack@eecs.umich.edudef template LoadMemAccExecute {{
2485081Sgblack@eecs.umich.edu    Fault
2495081Sgblack@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2505081Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
2515081Sgblack@eecs.umich.edu    {
2525081Sgblack@eecs.umich.edu        Addr EA;
2535081Sgblack@eecs.umich.edu        Fault fault = NoFault;
2545081Sgblack@eecs.umich.edu
2555081Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2565081Sgblack@eecs.umich.edu        %(op_decl)s;
2575119Sgblack@eecs.umich.edu        %(op_rd)s;
2585081Sgblack@eecs.umich.edu        EA = xc->getEA();
2595081Sgblack@eecs.umich.edu
2605081Sgblack@eecs.umich.edu        if (fault == NoFault) {
2615081Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2625081Sgblack@eecs.umich.edu            %(memacc_code)s;
2635081Sgblack@eecs.umich.edu        }
2645081Sgblack@eecs.umich.edu
2655081Sgblack@eecs.umich.edu        if (fault == NoFault) {
2665119Sgblack@eecs.umich.edu            %(op_wb)s;
2675081Sgblack@eecs.umich.edu        }
2685081Sgblack@eecs.umich.edu
2695081Sgblack@eecs.umich.edu        return fault;
2705081Sgblack@eecs.umich.edu    }
2715081Sgblack@eecs.umich.edu}};
2726085Sgblack@eecs.umich.edu
2736085Sgblack@eecs.umich.edu
2748610Snilay@cs.wisc.edudef template LoadExecute {{
2756085Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2766085Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
2776085Sgblack@eecs.umich.edu    {
2786085Sgblack@eecs.umich.edu        Addr EA;
2798610Snilay@cs.wisc.edu        Fault fault = NoFault;
2806085Sgblack@eecs.umich.edu
2816085Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2826085Sgblack@eecs.umich.edu        %(op_decl)s;
2836085Sgblack@eecs.umich.edu        %(op_rd)s;
2846085Sgblack@eecs.umich.edu        %(ea_code)s;
2858610Snilay@cs.wisc.edu
2866085Sgblack@eecs.umich.edu        if (fault == NoFault) {
2876085Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2886085Sgblack@eecs.umich.edu            %(memacc_code)s;
2896085Sgblack@eecs.umich.edu        }
2908610Snilay@cs.wisc.edu
2916085Sgblack@eecs.umich.edu        if (fault == NoFault) {
2926085Sgblack@eecs.umich.edu            %(op_wb)s;
2935081Sgblack@eecs.umich.edu        }
2945081Sgblack@eecs.umich.edu
2955119Sgblack@eecs.umich.edu        return fault;
2965081Sgblack@eecs.umich.edu    }
2975081Sgblack@eecs.umich.edu}};
2985081Sgblack@eecs.umich.edu
2995081Sgblack@eecs.umich.edu
3005081Sgblack@eecs.umich.edudef template LoadInitiateAcc {{
3015081Sgblack@eecs.umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3025081Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3035119Sgblack@eecs.umich.edu    {
3045081Sgblack@eecs.umich.edu        Addr EA;
3055081Sgblack@eecs.umich.edu        Fault fault = NoFault;
3065081Sgblack@eecs.umich.edu
3075081Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3086085Sgblack@eecs.umich.edu        %(op_src_decl)s;
3096085Sgblack@eecs.umich.edu        %(op_rd)s;
3108610Snilay@cs.wisc.edu        %(ea_code)s;
3116085Sgblack@eecs.umich.edu
3126085Sgblack@eecs.umich.edu        if (fault == NoFault) {
3136085Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3148610Snilay@cs.wisc.edu        }
3156085Sgblack@eecs.umich.edu
3166085Sgblack@eecs.umich.edu        return fault;
3176085Sgblack@eecs.umich.edu    }
3186085Sgblack@eecs.umich.edu}};
3196085Sgblack@eecs.umich.edu
3208610Snilay@cs.wisc.edu
3216085Sgblack@eecs.umich.edudef template LoadCompleteAcc {{
3226085Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3236085Sgblack@eecs.umich.edu                                      %(CPU_exec_context)s *xc,
3248610Snilay@cs.wisc.edu                                      Trace::InstRecord *traceData) const
3256085Sgblack@eecs.umich.edu    {
3266085Sgblack@eecs.umich.edu        Fault fault = NoFault;
3275081Sgblack@eecs.umich.edu
3285081Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3295081Sgblack@eecs.umich.edu        %(op_decl)s;
3305081Sgblack@eecs.umich.edu
3315081Sgblack@eecs.umich.edu        Mem = pkt->get<typeof(Mem)>();
3325081Sgblack@eecs.umich.edu
3335081Sgblack@eecs.umich.edu        if (fault == NoFault) {
3345081Sgblack@eecs.umich.edu            %(memacc_code)s;
3355081Sgblack@eecs.umich.edu        }
3365119Sgblack@eecs.umich.edu
3375081Sgblack@eecs.umich.edu        if (fault == NoFault) {
3385081Sgblack@eecs.umich.edu            %(op_wb)s;
3395081Sgblack@eecs.umich.edu        }
3405081Sgblack@eecs.umich.edu
3415081Sgblack@eecs.umich.edu        return fault;
3425081Sgblack@eecs.umich.edu    }
3435081Sgblack@eecs.umich.edu}};
3445081Sgblack@eecs.umich.edu
3455119Sgblack@eecs.umich.edu
3465081Sgblack@eecs.umich.edudef template StoreMemAccExecute {{
3475081Sgblack@eecs.umich.edu    Fault
3485081Sgblack@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3496089Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
3506089Sgblack@eecs.umich.edu    {
3516089Sgblack@eecs.umich.edu        Addr EA;
3526089Sgblack@eecs.umich.edu        Fault fault = NoFault;
3538610Snilay@cs.wisc.edu
3546089Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3556089Sgblack@eecs.umich.edu        %(op_decl)s;
3566089Sgblack@eecs.umich.edu        %(op_rd)s;
3578610Snilay@cs.wisc.edu        EA = xc->getEA();
3586089Sgblack@eecs.umich.edu
3596089Sgblack@eecs.umich.edu        if (fault == NoFault) {
3606089Sgblack@eecs.umich.edu            %(memacc_code)s;
3616089Sgblack@eecs.umich.edu        }
3626089Sgblack@eecs.umich.edu
3636089Sgblack@eecs.umich.edu        if (fault == NoFault) {
3648610Snilay@cs.wisc.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3656089Sgblack@eecs.umich.edu                              memAccessFlags, NULL);
3666089Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
3676089Sgblack@eecs.umich.edu        }
3688610Snilay@cs.wisc.edu
3696089Sgblack@eecs.umich.edu        if (fault == NoFault) {
3705081Sgblack@eecs.umich.edu            %(postacc_code)s;
371        }
372
373        if (fault == NoFault) {
374            %(op_wb)s;
375        }
376
377        return fault;
378    }
379}};
380
381def template StoreCondMemAccExecute {{
382    Fault
383    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
384                                   Trace::InstRecord *traceData) const
385    {
386        Addr EA;
387        Fault fault = NoFault;
388        uint64_t write_result = 0;
389
390        %(fp_enable_check)s;
391        %(op_decl)s;
392        %(op_rd)s;
393        EA = xc->getEA();
394
395        if (fault == NoFault) {
396            %(memacc_code)s;
397        }
398
399        if (fault == NoFault) {
400            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
401                              memAccessFlags, &write_result);
402            if (traceData) { traceData->setData(Mem); }
403        }
404
405        if (fault == NoFault) {
406            %(postacc_code)s;
407        }
408
409        if (fault == NoFault) {
410            %(op_wb)s;
411        }
412
413        return fault;
414    }
415}};
416
417
418def template StoreExecute {{
419    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
420                                  Trace::InstRecord *traceData) const
421    {
422        Addr EA;
423        Fault fault = NoFault;
424
425        %(fp_enable_check)s;
426        %(op_decl)s;
427        %(op_rd)s;
428        %(ea_code)s;
429
430        if (fault == NoFault) {
431            %(memacc_code)s;
432        }
433
434        if (fault == NoFault) {
435            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
436                              memAccessFlags, NULL);
437            if (traceData) { traceData->setData(Mem); }
438        }
439
440        if (fault == NoFault) {
441            %(postacc_code)s;
442        }
443
444        if (fault == NoFault) {
445            %(op_wb)s;
446        }
447
448        return fault;
449    }
450}};
451
452def template StoreCondExecute {{
453    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
454                                  Trace::InstRecord *traceData) const
455    {
456        Addr EA;
457        Fault fault = NoFault;
458        uint64_t write_result = 0;
459
460        %(fp_enable_check)s;
461        %(op_decl)s;
462        %(op_rd)s;
463        %(ea_code)s;
464
465        if (fault == NoFault) {
466            %(memacc_code)s;
467        }
468
469        if (fault == NoFault) {
470            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
471                              memAccessFlags, &write_result);
472            if (traceData) { traceData->setData(Mem); }
473        }
474
475        if (fault == NoFault) {
476            %(postacc_code)s;
477        }
478
479        if (fault == NoFault) {
480            %(op_wb)s;
481        }
482
483        return fault;
484    }
485}};
486
487def template StoreInitiateAcc {{
488    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
489                                      Trace::InstRecord *traceData) const
490    {
491        Addr EA;
492        Fault fault = NoFault;
493
494        %(fp_enable_check)s;
495        %(op_decl)s;
496        %(op_rd)s;
497        %(ea_code)s;
498
499        if (fault == NoFault) {
500            %(memacc_code)s;
501        }
502
503        if (fault == NoFault) {
504            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
505                              memAccessFlags, NULL);
506            if (traceData) { traceData->setData(Mem); }
507        }
508
509        return fault;
510    }
511}};
512
513
514def template StoreCompleteAcc {{
515    Fault %(class_name)s::completeAcc(PacketPtr pkt,
516                                      %(CPU_exec_context)s *xc,
517                                      Trace::InstRecord *traceData) const
518    {
519        Fault fault = NoFault;
520
521        %(fp_enable_check)s;
522        %(op_dest_decl)s;
523
524        if (fault == NoFault) {
525            %(postacc_code)s;
526        }
527
528        if (fault == NoFault) {
529            %(op_wb)s;
530        }
531
532        return fault;
533    }
534}};
535
536
537def template StoreCondCompleteAcc {{
538    Fault %(class_name)s::completeAcc(PacketPtr pkt,
539                                      %(CPU_exec_context)s *xc,
540                                      Trace::InstRecord *traceData) const
541    {
542        Fault fault = NoFault;
543
544        %(fp_enable_check)s;
545        %(op_dest_decl)s;
546
547        uint64_t write_result = pkt->req->getScResult();
548
549        if (fault == NoFault) {
550            %(postacc_code)s;
551        }
552
553        if (fault == NoFault) {
554            %(op_wb)s;
555        }
556
557        return fault;
558    }
559}};
560
561
562def template MiscMemAccExecute {{
563    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
564                                          Trace::InstRecord *traceData) const
565    {
566        Addr EA;
567        Fault fault = NoFault;
568
569        %(fp_enable_check)s;
570        %(op_decl)s;
571        %(op_rd)s;
572        EA = xc->getEA();
573
574        if (fault == NoFault) {
575            %(memacc_code)s;
576        }
577
578        return NoFault;
579    }
580}};
581
582def template MiscExecute {{
583    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
584                                  Trace::InstRecord *traceData) const
585    {
586        Addr EA;
587        Fault fault = NoFault;
588
589        %(fp_enable_check)s;
590        %(op_decl)s;
591        %(op_rd)s;
592        %(ea_code)s;
593
594        if (fault == NoFault) {
595            %(memacc_code)s;
596        }
597
598        return NoFault;
599    }
600}};
601
602def template MiscInitiateAcc {{
603    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
604                                      Trace::InstRecord *traceData) const
605    {
606        warn("Misc instruction does not support split access method!");
607        return NoFault;
608    }
609}};
610
611
612def template MiscCompleteAcc {{
613    Fault %(class_name)s::completeAcc(PacketPtr pkt,
614                                      %(CPU_exec_context)s *xc,
615                                      Trace::InstRecord *traceData) const
616    {
617        warn("Misc instruction does not support split access method!");
618
619        return NoFault;
620    }
621}};
622
623// load instructions use Ra as dest, so check for
624// Ra == 31 to detect nops
625def template LoadNopCheckDecode {{
626 {
627     AlphaStaticInst *i = new %(class_name)s(machInst);
628     if (RA == 31) {
629         i = makeNop(i);
630     }
631     return i;
632 }
633}};
634
635
636// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
637def template LoadPrefetchCheckDecode {{
638 {
639     if (RA != 31) {
640         return new %(class_name)s(machInst);
641     }
642     else {
643         return new %(class_name)sPrefetch(machInst);
644     }
645 }
646}};
647
648
649let {{
650def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
651                  postacc_code = '', base_class = 'MemoryDisp32',
652                  decode_template = BasicDecode, exec_template_base = ''):
653    # Make sure flags are in lists (convert to lists if not).
654    mem_flags = makeList(mem_flags)
655    inst_flags = makeList(inst_flags)
656
657    # add hook to get effective addresses into execution trace output.
658    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
659
660    # Some CPU models execute the memory operation as an atomic unit,
661    # while others want to separate them into an effective address
662    # computation and a memory access operation.  As a result, we need
663    # to generate three StaticInst objects.  Note that the latter two
664    # are nested inside the larger "atomic" one.
665
666    # Generate InstObjParams for each of the three objects.  Note that
667    # they differ only in the set of code objects contained (which in
668    # turn affects the object's overall operand list).
669    iop = InstObjParams(name, Name, base_class,
670                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
671                        inst_flags)
672    ea_iop = InstObjParams(name, Name, base_class,
673                        { 'ea_code':ea_code },
674                        inst_flags)
675    memacc_iop = InstObjParams(name, Name, base_class,
676                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
677                        inst_flags)
678
679    if mem_flags:
680        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
681        iop.constructor += s
682        memacc_iop.constructor += s
683
684    # select templates
685
686    # The InitiateAcc template is the same for StoreCond templates as the
687    # corresponding Store template..
688    StoreCondInitiateAcc = StoreInitiateAcc
689
690    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
691    fullExecTemplate = eval(exec_template_base + 'Execute')
692    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
693    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
694
695    # (header_output, decoder_output, decode_block, exec_output)
696    return (LoadStoreDeclare.subst(iop),
697            EACompConstructor.subst(ea_iop)
698            + MemAccConstructor.subst(memacc_iop)
699            + LoadStoreConstructor.subst(iop),
700            decode_template.subst(iop),
701            EACompExecute.subst(ea_iop)
702            + memAccExecTemplate.subst(memacc_iop)
703            + fullExecTemplate.subst(iop)
704            + initiateAccTemplate.subst(iop)
705            + completeAccTemplate.subst(iop))
706}};
707
708def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
709                     mem_flags = [], inst_flags = []) {{
710    (header_output, decoder_output, decode_block, exec_output) = \
711        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
712                      decode_template = LoadNopCheckDecode,
713                      exec_template_base = 'Load')
714}};
715
716
717// Note that the flags passed in apply only to the prefetch version
718def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
719                          mem_flags = [], pf_flags = [], inst_flags = []) {{
720    # declare the load instruction object and generate the decode block
721    (header_output, decoder_output, decode_block, exec_output) = \
722        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
723                      decode_template = LoadPrefetchCheckDecode,
724                      exec_template_base = 'Load')
725
726    # Declare the prefetch instruction object.
727
728    # Make sure flag args are lists so we can mess with them.
729    mem_flags = makeList(mem_flags)
730    pf_flags = makeList(pf_flags)
731    inst_flags = makeList(inst_flags)
732
733    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
734    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
735                                  'IsDataPrefetch', 'MemReadOp']
736
737    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
738        LoadStoreBase(name, Name + 'Prefetch', ea_code,
739                      'xc->prefetch(EA, memAccessFlags);',
740                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
741
742    header_output += pf_header_output
743    decoder_output += pf_decoder_output
744    exec_output += pf_exec_output
745}};
746
747
748def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
749                 mem_flags = [], inst_flags = []) {{
750    (header_output, decoder_output, decode_block, exec_output) = \
751        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
752                      exec_template_base = 'Store')
753}};
754
755
756def format StoreCond(memacc_code, postacc_code,
757                     ea_code = {{ EA = Rb + disp; }},
758                     mem_flags = [], inst_flags = []) {{
759    (header_output, decoder_output, decode_block, exec_output) = \
760        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
761                      postacc_code, exec_template_base = 'StoreCond')
762}};
763
764
765// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
766def format MiscPrefetch(ea_code, memacc_code,
767                        mem_flags = [], inst_flags = []) {{
768    (header_output, decoder_output, decode_block, exec_output) = \
769        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
770                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
771}};
772
773
774