mem.isa revision 4661
17118Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27118Sgblack@eecs.umich.edu
37118Sgblack@eecs.umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
47118Sgblack@eecs.umich.edu// All rights reserved.
57118Sgblack@eecs.umich.edu//
67118Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
77118Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
87118Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
97118Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
107118Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
117118Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
127118Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
137118Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
147118Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
156253Sgblack@eecs.umich.edu// this software without specific prior written permission.
166253Sgblack@eecs.umich.edu//
176253Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186253Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196253Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206253Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216253Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226253Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236253Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246253Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256253Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266253Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276253Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286253Sgblack@eecs.umich.edu//
296253Sgblack@eecs.umich.edu// Authors: Steve Reinhardt
306253Sgblack@eecs.umich.edu//          Kevin Lim
316253Sgblack@eecs.umich.edu
326253Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
336253Sgblack@eecs.umich.edu//
346253Sgblack@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store
356253Sgblack@eecs.umich.edu//
366253Sgblack@eecs.umich.edu
376253Sgblack@eecs.umich.eduoutput header {{
386253Sgblack@eecs.umich.edu    /**
396253Sgblack@eecs.umich.edu     * Base class for general Alpha memory-format instructions.
406253Sgblack@eecs.umich.edu     */
416253Sgblack@eecs.umich.edu    class Memory : public AlphaStaticInst
426253Sgblack@eecs.umich.edu    {
436253Sgblack@eecs.umich.edu      protected:
446253Sgblack@eecs.umich.edu
456253Sgblack@eecs.umich.edu        /// Memory request flags.  See mem_req_base.hh.
466253Sgblack@eecs.umich.edu        unsigned memAccessFlags;
476253Sgblack@eecs.umich.edu        /// Pointer to EAComp object.
486253Sgblack@eecs.umich.edu        const StaticInstPtr eaCompPtr;
497118Sgblack@eecs.umich.edu        /// Pointer to MemAcc object.
507205Sgblack@eecs.umich.edu        const StaticInstPtr memAccPtr;
517205Sgblack@eecs.umich.edu
527205Sgblack@eecs.umich.edu        /// Constructor
537205Sgblack@eecs.umich.edu        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
547205Sgblack@eecs.umich.edu               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
557205Sgblack@eecs.umich.edu               StaticInstPtr _memAccPtr = nullStaticInstPtr)
567205Sgblack@eecs.umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass),
577205Sgblack@eecs.umich.edu              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
587205Sgblack@eecs.umich.edu        {
597205Sgblack@eecs.umich.edu        }
607205Sgblack@eecs.umich.edu
617205Sgblack@eecs.umich.edu        std::string
627205Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
6312616Sgabeblack@google.com
6412616Sgabeblack@google.com      public:
657205Sgblack@eecs.umich.edu
667205Sgblack@eecs.umich.edu        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
677720Sgblack@eecs.umich.edu        const StaticInstPtr &memAccInst() const { return memAccPtr; }
687720Sgblack@eecs.umich.edu    };
697720Sgblack@eecs.umich.edu
707720Sgblack@eecs.umich.edu    /**
717720Sgblack@eecs.umich.edu     * Base class for memory-format instructions using a 32-bit
727720Sgblack@eecs.umich.edu     * displacement (i.e. most of them).
737720Sgblack@eecs.umich.edu     */
747720Sgblack@eecs.umich.edu    class MemoryDisp32 : public Memory
757720Sgblack@eecs.umich.edu    {
767720Sgblack@eecs.umich.edu      protected:
777720Sgblack@eecs.umich.edu        /// Displacement for EA calculation (signed).
787720Sgblack@eecs.umich.edu        int32_t disp;
797720Sgblack@eecs.umich.edu
807720Sgblack@eecs.umich.edu        /// Constructor.
817720Sgblack@eecs.umich.edu        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
827720Sgblack@eecs.umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
837720Sgblack@eecs.umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
847720Sgblack@eecs.umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
857720Sgblack@eecs.umich.edu              disp(MEMDISP)
867720Sgblack@eecs.umich.edu        {
877291Sgblack@eecs.umich.edu        }
887720Sgblack@eecs.umich.edu    };
897291Sgblack@eecs.umich.edu
907291Sgblack@eecs.umich.edu
917291Sgblack@eecs.umich.edu    /**
927291Sgblack@eecs.umich.edu     * Base class for a few miscellaneous memory-format insts
937291Sgblack@eecs.umich.edu     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
947291Sgblack@eecs.umich.edu     * None of these instructions has a destination register either.
957291Sgblack@eecs.umich.edu     */
967291Sgblack@eecs.umich.edu    class MemoryNoDisp : public Memory
977291Sgblack@eecs.umich.edu    {
987291Sgblack@eecs.umich.edu      protected:
997291Sgblack@eecs.umich.edu        /// Constructor
1007291Sgblack@eecs.umich.edu        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1018140SMatt.Horsnell@arm.com                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
1028140SMatt.Horsnell@arm.com                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
1037646Sgene.wu@arm.com            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
1047646Sgene.wu@arm.com        {
1057291Sgblack@eecs.umich.edu        }
1067291Sgblack@eecs.umich.edu
1077291Sgblack@eecs.umich.edu        std::string
1087720Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1098140SMatt.Horsnell@arm.com    };
1108140SMatt.Horsnell@arm.com}};
1118140SMatt.Horsnell@arm.com
1128140SMatt.Horsnell@arm.com
1137291Sgblack@eecs.umich.eduoutput decoder {{
1147291Sgblack@eecs.umich.edu    std::string
1157646Sgene.wu@arm.com    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1167646Sgene.wu@arm.com    {
1177646Sgene.wu@arm.com        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1187747SAli.Saidi@ARM.com                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1197646Sgene.wu@arm.com    }
1207646Sgene.wu@arm.com
1217646Sgene.wu@arm.com    std::string
12212616Sgabeblack@google.com    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1237646Sgene.wu@arm.com    {
1247646Sgene.wu@arm.com        return csprintf("%-10s (r%d)", mnemonic, RB);
1257646Sgene.wu@arm.com    }
1267646Sgene.wu@arm.com}};
1277646Sgene.wu@arm.com
12812616Sgabeblack@google.comdef format LoadAddress(code) {{
12912616Sgabeblack@google.com    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
1307291Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
1317291Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
1327312Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
1337720Sgblack@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
1347312Sgblack@eecs.umich.edu}};
1357312Sgblack@eecs.umich.edu
1367312Sgblack@eecs.umich.edu
1377312Sgblack@eecs.umich.edudef template LoadStoreDeclare {{
1387312Sgblack@eecs.umich.edu    /**
1397312Sgblack@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
1407312Sgblack@eecs.umich.edu     */
1417312Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
1427312Sgblack@eecs.umich.edu    {
1437312Sgblack@eecs.umich.edu      protected:
1447312Sgblack@eecs.umich.edu
1457312Sgblack@eecs.umich.edu        /**
1467646Sgene.wu@arm.com         * "Fake" effective address computation class for "%(mnemonic)s".
1477646Sgene.wu@arm.com         */
1487646Sgene.wu@arm.com        class EAComp : public %(base_class)s
1497312Sgblack@eecs.umich.edu        {
1507312Sgblack@eecs.umich.edu          public:
1517312Sgblack@eecs.umich.edu            /// Constructor
1527720Sgblack@eecs.umich.edu            EAComp(ExtMachInst machInst);
1537646Sgene.wu@arm.com
1547312Sgblack@eecs.umich.edu            %(BasicExecDeclare)s
1557312Sgblack@eecs.umich.edu        };
1567646Sgene.wu@arm.com
1577646Sgene.wu@arm.com        /**
1587646Sgene.wu@arm.com         * "Fake" memory access instruction class for "%(mnemonic)s".
1597845SAli.Saidi@ARM.com         */
1607646Sgene.wu@arm.com        class MemAcc : public %(base_class)s
1617646Sgene.wu@arm.com        {
1627646Sgene.wu@arm.com          public:
16312616Sgabeblack@google.com            /// Constructor
1647646Sgene.wu@arm.com            MemAcc(ExtMachInst machInst);
1657646Sgene.wu@arm.com
1667646Sgene.wu@arm.com            %(BasicExecDeclare)s
1677646Sgene.wu@arm.com        };
1687646Sgene.wu@arm.com
16912616Sgabeblack@google.com      public:
17012616Sgabeblack@google.com
1717312Sgblack@eecs.umich.edu        /// Constructor.
1727312Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst);
1737720Sgblack@eecs.umich.edu
1747118Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
1757118Sgblack@eecs.umich.edu
1767118Sgblack@eecs.umich.edu        %(InitiateAccDeclare)s
1777118Sgblack@eecs.umich.edu
1787118Sgblack@eecs.umich.edu        %(CompleteAccDeclare)s
1797118Sgblack@eecs.umich.edu    };
1807118Sgblack@eecs.umich.edu}};
1817118Sgblack@eecs.umich.edu
1827118Sgblack@eecs.umich.edu
1837118Sgblack@eecs.umich.edudef template InitiateAccDeclare {{
1847118Sgblack@eecs.umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1857118Sgblack@eecs.umich.edu}};
1867118Sgblack@eecs.umich.edu
1877646Sgene.wu@arm.com
1887646Sgene.wu@arm.comdef template CompleteAccDeclare {{
1897646Sgene.wu@arm.com    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
1907118Sgblack@eecs.umich.edu                      Trace::InstRecord *) const;
1917132Sgblack@eecs.umich.edu}};
1927132Sgblack@eecs.umich.edu
1937720Sgblack@eecs.umich.edu
1947646Sgene.wu@arm.comdef template EACompConstructor {{
1957118Sgblack@eecs.umich.edu    /** TODO: change op_class to AddrGenOp or something (requires
1967118Sgblack@eecs.umich.edu     * creating new member of OpClass enum in op_class.hh, updating
1977646Sgene.wu@arm.com     * config files, etc.). */
1987646Sgene.wu@arm.com    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
1997646Sgene.wu@arm.com        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2007646Sgene.wu@arm.com    {
2017646Sgene.wu@arm.com        %(constructor)s;
2027646Sgene.wu@arm.com    }
2037646Sgene.wu@arm.com}};
20412616Sgabeblack@google.com
2057646Sgene.wu@arm.com
2067646Sgene.wu@arm.comdef template MemAccConstructor {{
2077646Sgene.wu@arm.com    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2087646Sgene.wu@arm.com        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2097646Sgene.wu@arm.com    {
2107118Sgblack@eecs.umich.edu        %(constructor)s;
2117118Sgblack@eecs.umich.edu    }
2127118Sgblack@eecs.umich.edu}};
2137118Sgblack@eecs.umich.edu
2147279Sgblack@eecs.umich.edu
2157279Sgblack@eecs.umich.edudef template LoadStoreConstructor {{
2167279Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
21712104Snathanael.premillieu@arm.com         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2187279Sgblack@eecs.umich.edu                          new EAComp(machInst), new MemAcc(machInst))
2197279Sgblack@eecs.umich.edu    {
2207118Sgblack@eecs.umich.edu        %(constructor)s;
2217118Sgblack@eecs.umich.edu    }
2227118Sgblack@eecs.umich.edu}};
2237118Sgblack@eecs.umich.edu
2247132Sgblack@eecs.umich.edu
2257118Sgblack@eecs.umich.edudef template EACompExecute {{
2267118Sgblack@eecs.umich.edu    Fault
2277118Sgblack@eecs.umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2287118Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
2297132Sgblack@eecs.umich.edu    {
2307132Sgblack@eecs.umich.edu        Addr EA;
2317132Sgblack@eecs.umich.edu        Fault fault = NoFault;
2327118Sgblack@eecs.umich.edu
2337118Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2347118Sgblack@eecs.umich.edu        %(op_decl)s;
2357118Sgblack@eecs.umich.edu        %(op_rd)s;
2367118Sgblack@eecs.umich.edu        %(ea_code)s;
2377118Sgblack@eecs.umich.edu
2387118Sgblack@eecs.umich.edu        if (fault == NoFault) {
2397118Sgblack@eecs.umich.edu            %(op_wb)s;
2407118Sgblack@eecs.umich.edu            xc->setEA(EA);
2417118Sgblack@eecs.umich.edu        }
2427118Sgblack@eecs.umich.edu
2437118Sgblack@eecs.umich.edu        return fault;
2447303Sgblack@eecs.umich.edu    }
2457303Sgblack@eecs.umich.edu}};
2467303Sgblack@eecs.umich.edu
2477303Sgblack@eecs.umich.edudef template LoadMemAccExecute {{
2487303Sgblack@eecs.umich.edu    Fault
2497303Sgblack@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2507303Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
2517303Sgblack@eecs.umich.edu    {
2527303Sgblack@eecs.umich.edu        Addr EA;
2537303Sgblack@eecs.umich.edu        Fault fault = NoFault;
2547303Sgblack@eecs.umich.edu
2557303Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2567303Sgblack@eecs.umich.edu        %(op_decl)s;
2577303Sgblack@eecs.umich.edu        %(op_rd)s;
2587303Sgblack@eecs.umich.edu        EA = xc->getEA();
25912104Snathanael.premillieu@arm.com
2607303Sgblack@eecs.umich.edu        if (fault == NoFault) {
2617303Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2627303Sgblack@eecs.umich.edu            %(memacc_code)s;
2637303Sgblack@eecs.umich.edu        }
2647303Sgblack@eecs.umich.edu
2657279Sgblack@eecs.umich.edu        if (fault == NoFault) {
2667279Sgblack@eecs.umich.edu            %(op_wb)s;
2677279Sgblack@eecs.umich.edu        }
2687279Sgblack@eecs.umich.edu
2697279Sgblack@eecs.umich.edu        return fault;
2707279Sgblack@eecs.umich.edu    }
2717279Sgblack@eecs.umich.edu}};
2727279Sgblack@eecs.umich.edu
2737279Sgblack@eecs.umich.edu
2747279Sgblack@eecs.umich.edudef template LoadExecute {{
2757279Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2767279Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
2777279Sgblack@eecs.umich.edu    {
2787279Sgblack@eecs.umich.edu        Addr EA;
2797279Sgblack@eecs.umich.edu        Fault fault = NoFault;
2807279Sgblack@eecs.umich.edu
2817279Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2827279Sgblack@eecs.umich.edu        %(op_decl)s;
28312104Snathanael.premillieu@arm.com        %(op_rd)s;
2847279Sgblack@eecs.umich.edu        %(ea_code)s;
2857279Sgblack@eecs.umich.edu
2867279Sgblack@eecs.umich.edu        if (fault == NoFault) {
2877303Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2887303Sgblack@eecs.umich.edu            %(memacc_code)s;
2897303Sgblack@eecs.umich.edu        }
2907303Sgblack@eecs.umich.edu
2917303Sgblack@eecs.umich.edu        if (fault == NoFault) {
2927303Sgblack@eecs.umich.edu            %(op_wb)s;
2937303Sgblack@eecs.umich.edu        }
2947303Sgblack@eecs.umich.edu
2957303Sgblack@eecs.umich.edu        return fault;
2967303Sgblack@eecs.umich.edu    }
2977303Sgblack@eecs.umich.edu}};
2987303Sgblack@eecs.umich.edu
2997303Sgblack@eecs.umich.edu
3007303Sgblack@eecs.umich.edudef template LoadInitiateAcc {{
3017303Sgblack@eecs.umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
30212104Snathanael.premillieu@arm.com                                      Trace::InstRecord *traceData) const
3037303Sgblack@eecs.umich.edu    {
3047303Sgblack@eecs.umich.edu        Addr EA;
3057303Sgblack@eecs.umich.edu        Fault fault = NoFault;
3067303Sgblack@eecs.umich.edu
3077303Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3087118Sgblack@eecs.umich.edu        %(op_src_decl)s;
3097132Sgblack@eecs.umich.edu        %(op_rd)s;
3107118Sgblack@eecs.umich.edu        %(ea_code)s;
3117118Sgblack@eecs.umich.edu
3127118Sgblack@eecs.umich.edu        if (fault == NoFault) {
3137118Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3147118Sgblack@eecs.umich.edu        }
3157118Sgblack@eecs.umich.edu
3167132Sgblack@eecs.umich.edu        return fault;
3177132Sgblack@eecs.umich.edu    }
3187132Sgblack@eecs.umich.edu}};
3197132Sgblack@eecs.umich.edu
3207132Sgblack@eecs.umich.edu
3217118Sgblack@eecs.umich.edudef template LoadCompleteAcc {{
3227118Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
3237118Sgblack@eecs.umich.edu                                      %(CPU_exec_context)s *xc,
3247428Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3257118Sgblack@eecs.umich.edu    {
3267118Sgblack@eecs.umich.edu        Fault fault = NoFault;
3277279Sgblack@eecs.umich.edu
3287279Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3297279Sgblack@eecs.umich.edu        %(op_decl)s;
3307279Sgblack@eecs.umich.edu
3317279Sgblack@eecs.umich.edu        Mem = pkt->get<typeof(Mem)>();
3327279Sgblack@eecs.umich.edu
3337279Sgblack@eecs.umich.edu        if (fault == NoFault) {
3347279Sgblack@eecs.umich.edu            %(memacc_code)s;
3357279Sgblack@eecs.umich.edu        }
3367279Sgblack@eecs.umich.edu
3377279Sgblack@eecs.umich.edu        if (fault == NoFault) {
3387279Sgblack@eecs.umich.edu            %(op_wb)s;
3397279Sgblack@eecs.umich.edu        }
3407279Sgblack@eecs.umich.edu
3417279Sgblack@eecs.umich.edu        return fault;
3427279Sgblack@eecs.umich.edu    }
3437279Sgblack@eecs.umich.edu}};
3447279Sgblack@eecs.umich.edu
3457279Sgblack@eecs.umich.edu
3467279Sgblack@eecs.umich.edudef template StoreMemAccExecute {{
34712104Snathanael.premillieu@arm.com    Fault
3487279Sgblack@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3497279Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
3507279Sgblack@eecs.umich.edu    {
3517118Sgblack@eecs.umich.edu        Addr EA;
3527132Sgblack@eecs.umich.edu        Fault fault = NoFault;
3537118Sgblack@eecs.umich.edu
3547118Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3557132Sgblack@eecs.umich.edu        %(op_decl)s;
3567132Sgblack@eecs.umich.edu        %(op_rd)s;
3577132Sgblack@eecs.umich.edu        EA = xc->getEA();
3587132Sgblack@eecs.umich.edu
3597132Sgblack@eecs.umich.edu        if (fault == NoFault) {
3607132Sgblack@eecs.umich.edu            %(memacc_code)s;
3617132Sgblack@eecs.umich.edu        }
3627132Sgblack@eecs.umich.edu
3637132Sgblack@eecs.umich.edu        if (fault == NoFault) {
3647132Sgblack@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3657132Sgblack@eecs.umich.edu                              memAccessFlags, NULL);
3667132Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
3677132Sgblack@eecs.umich.edu        }
3687132Sgblack@eecs.umich.edu
3697279Sgblack@eecs.umich.edu        if (fault == NoFault) {
3707279Sgblack@eecs.umich.edu            %(postacc_code)s;
3717279Sgblack@eecs.umich.edu        }
3727279Sgblack@eecs.umich.edu
3737279Sgblack@eecs.umich.edu        if (fault == NoFault) {
3747279Sgblack@eecs.umich.edu            %(op_wb)s;
3757279Sgblack@eecs.umich.edu        }
3767303Sgblack@eecs.umich.edu
3777303Sgblack@eecs.umich.edu        return fault;
3787303Sgblack@eecs.umich.edu    }
3797303Sgblack@eecs.umich.edu}};
3807303Sgblack@eecs.umich.edu
3817303Sgblack@eecs.umich.edudef template StoreCondMemAccExecute {{
3827303Sgblack@eecs.umich.edu    Fault
3837303Sgblack@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3847279Sgblack@eecs.umich.edu                                   Trace::InstRecord *traceData) const
3857279Sgblack@eecs.umich.edu    {
3867279Sgblack@eecs.umich.edu        Addr EA;
3877279Sgblack@eecs.umich.edu        Fault fault = NoFault;
3887279Sgblack@eecs.umich.edu        uint64_t write_result = 0;
3897279Sgblack@eecs.umich.edu
3907279Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3917279Sgblack@eecs.umich.edu        %(op_decl)s;
3927132Sgblack@eecs.umich.edu        %(op_rd)s;
3937132Sgblack@eecs.umich.edu        EA = xc->getEA();
3947132Sgblack@eecs.umich.edu
3957132Sgblack@eecs.umich.edu        if (fault == NoFault) {
3967132Sgblack@eecs.umich.edu            %(memacc_code)s;
3977132Sgblack@eecs.umich.edu        }
3987132Sgblack@eecs.umich.edu
3997132Sgblack@eecs.umich.edu        if (fault == NoFault) {
4007132Sgblack@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4017132Sgblack@eecs.umich.edu                              memAccessFlags, &write_result);
4027132Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
4037132Sgblack@eecs.umich.edu        }
4047132Sgblack@eecs.umich.edu
4057132Sgblack@eecs.umich.edu        if (fault == NoFault) {
4067132Sgblack@eecs.umich.edu            %(postacc_code)s;
4077132Sgblack@eecs.umich.edu        }
4087132Sgblack@eecs.umich.edu
4097132Sgblack@eecs.umich.edu        if (fault == NoFault) {
4107132Sgblack@eecs.umich.edu            %(op_wb)s;
4117132Sgblack@eecs.umich.edu        }
4127132Sgblack@eecs.umich.edu
4137132Sgblack@eecs.umich.edu        return fault;
4147132Sgblack@eecs.umich.edu    }
4157132Sgblack@eecs.umich.edu}};
4167132Sgblack@eecs.umich.edu
4177132Sgblack@eecs.umich.edu
4187132Sgblack@eecs.umich.edudef template StoreExecute {{
4197279Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4207279Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
4217279Sgblack@eecs.umich.edu    {
4227279Sgblack@eecs.umich.edu        Addr EA;
4237279Sgblack@eecs.umich.edu        Fault fault = NoFault;
4247279Sgblack@eecs.umich.edu
4257279Sgblack@eecs.umich.edu        %(fp_enable_check)s;
4267303Sgblack@eecs.umich.edu        %(op_decl)s;
4277303Sgblack@eecs.umich.edu        %(op_rd)s;
4287303Sgblack@eecs.umich.edu        %(ea_code)s;
4297303Sgblack@eecs.umich.edu
4307303Sgblack@eecs.umich.edu        if (fault == NoFault) {
4317303Sgblack@eecs.umich.edu            %(memacc_code)s;
4327303Sgblack@eecs.umich.edu        }
4337303Sgblack@eecs.umich.edu
4347279Sgblack@eecs.umich.edu        if (fault == NoFault) {
4357279Sgblack@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4367279Sgblack@eecs.umich.edu                              memAccessFlags, NULL);
4377279Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
4387279Sgblack@eecs.umich.edu        }
4397279Sgblack@eecs.umich.edu
4407279Sgblack@eecs.umich.edu        if (fault == NoFault) {
4417279Sgblack@eecs.umich.edu            %(postacc_code)s;
4427132Sgblack@eecs.umich.edu        }
4437132Sgblack@eecs.umich.edu
4447132Sgblack@eecs.umich.edu        if (fault == NoFault) {
4457132Sgblack@eecs.umich.edu            %(op_wb)s;
4467132Sgblack@eecs.umich.edu        }
4477132Sgblack@eecs.umich.edu
4487132Sgblack@eecs.umich.edu        return fault;
4497132Sgblack@eecs.umich.edu    }
4507132Sgblack@eecs.umich.edu}};
4517132Sgblack@eecs.umich.edu
4527132Sgblack@eecs.umich.edudef template StoreCondExecute {{
4537132Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4547132Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
4557132Sgblack@eecs.umich.edu    {
4567118Sgblack@eecs.umich.edu        Addr EA;
4577118Sgblack@eecs.umich.edu        Fault fault = NoFault;
4587118Sgblack@eecs.umich.edu        uint64_t write_result = 0;
4597118Sgblack@eecs.umich.edu
4607118Sgblack@eecs.umich.edu        %(fp_enable_check)s;
4617132Sgblack@eecs.umich.edu        %(op_decl)s;
4627118Sgblack@eecs.umich.edu        %(op_rd)s;
4637118Sgblack@eecs.umich.edu        %(ea_code)s;
4647118Sgblack@eecs.umich.edu
4657118Sgblack@eecs.umich.edu        if (fault == NoFault) {
4667118Sgblack@eecs.umich.edu            %(memacc_code)s;
4677118Sgblack@eecs.umich.edu        }
4687118Sgblack@eecs.umich.edu
4697279Sgblack@eecs.umich.edu        if (fault == NoFault) {
4707279Sgblack@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4717279Sgblack@eecs.umich.edu                              memAccessFlags, &write_result);
4727279Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
4737279Sgblack@eecs.umich.edu        }
4747279Sgblack@eecs.umich.edu
4757279Sgblack@eecs.umich.edu        if (fault == NoFault) {
4767303Sgblack@eecs.umich.edu            %(postacc_code)s;
4777303Sgblack@eecs.umich.edu        }
4787303Sgblack@eecs.umich.edu
4797303Sgblack@eecs.umich.edu        if (fault == NoFault) {
4807303Sgblack@eecs.umich.edu            %(op_wb)s;
4817303Sgblack@eecs.umich.edu        }
4827303Sgblack@eecs.umich.edu
4837303Sgblack@eecs.umich.edu        return fault;
4847279Sgblack@eecs.umich.edu    }
4857279Sgblack@eecs.umich.edu}};
4867279Sgblack@eecs.umich.edu
4877279Sgblack@eecs.umich.edudef template StoreInitiateAcc {{
4887279Sgblack@eecs.umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4897279Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
4907279Sgblack@eecs.umich.edu    {
4917279Sgblack@eecs.umich.edu        Addr EA;
4927118Sgblack@eecs.umich.edu        Fault fault = NoFault;
4937118Sgblack@eecs.umich.edu
4947118Sgblack@eecs.umich.edu        %(fp_enable_check)s;
4957118Sgblack@eecs.umich.edu        %(op_decl)s;
4967132Sgblack@eecs.umich.edu        %(op_rd)s;
4977118Sgblack@eecs.umich.edu        %(ea_code)s;
4987118Sgblack@eecs.umich.edu
4997118Sgblack@eecs.umich.edu        if (fault == NoFault) {
5006253Sgblack@eecs.umich.edu            %(memacc_code)s;
5016253Sgblack@eecs.umich.edu        }
5026253Sgblack@eecs.umich.edu
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->getExtraData();
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