mem.isa revision 2132
12124SN/A// -*- mode:c++ -*-
22124SN/A
35268Sksewell@umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
45268Sksewell@umich.edu// All rights reserved.
55268Sksewell@umich.edu//
65268Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
75268Sksewell@umich.edu// modification, are permitted provided that the following conditions are
85268Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
95268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
105268Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
115268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
125268Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
135268Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
145268Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
155268Sksewell@umich.edu// this software without specific prior written permission.
165268Sksewell@umich.edu//
175268Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185268Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195268Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205268Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215268Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225268Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235268Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245268Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255268Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265268Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275268Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285268Sksewell@umich.edu
295268Sksewell@umich.eduoutput header {{
305268Sksewell@umich.edu    /**
312022SN/A     * Base class for general Alpha memory-format instructions.
322649Ssaidi@eecs.umich.edu     */
332649Ssaidi@eecs.umich.edu    class Memory : public AlphaStaticInst
342706Sksewell@umich.edu    {
352649Ssaidi@eecs.umich.edu      protected:
362649Ssaidi@eecs.umich.edu
372022SN/A        /// Memory request flags.  See mem_req_base.hh.
382124SN/A        unsigned memAccessFlags;
392124SN/A        /// Pointer to EAComp object.
402124SN/A        const StaticInstPtr eaCompPtr;
412124SN/A        /// Pointer to MemAcc object.
422124SN/A        const StaticInstPtr memAccPtr;
432124SN/A
442124SN/A        /// Constructor
455736Snate@binkert.org        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
462239SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
472124SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
482124SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
492124SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
502124SN/A        {
516207Sksewell@umich.edu        }
522124SN/A
532742Sksewell@umich.edu        std::string
542022SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
552124SN/A
562022SN/A      public:
572124SN/A
582124SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
592124SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
602124SN/A    };
612742Sksewell@umich.edu
622742Sksewell@umich.edu    /**
632742Sksewell@umich.edu     * Base class for memory-format instructions using a 32-bit
642742Sksewell@umich.edu     * displacement (i.e. most of them).
652742Sksewell@umich.edu     */
662742Sksewell@umich.edu    class MemoryDisp32 : public Memory
672742Sksewell@umich.edu    {
682742Sksewell@umich.edu      protected:
696207Sksewell@umich.edu        /// Displacement for EA calculation (signed).
706207Sksewell@umich.edu        int32_t disp;
712742Sksewell@umich.edu
722742Sksewell@umich.edu        /// Constructor.
732742Sksewell@umich.edu        MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass,
742742Sksewell@umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
752742Sksewell@umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
762742Sksewell@umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
772022SN/A              disp(MEMDISP)
782022SN/A        {
792124SN/A        }
802022SN/A    };
812124SN/A
822124SN/A
832124SN/A    /**
842742Sksewell@umich.edu     * Base class for a few miscellaneous memory-format insts
852239SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
862124SN/A     * None of these instructions has a destination register either.
872124SN/A     */
882742Sksewell@umich.edu    class MemoryNoDisp : public Memory
892742Sksewell@umich.edu    {
902742Sksewell@umich.edu      protected:
912742Sksewell@umich.edu        /// Constructor
922742Sksewell@umich.edu        MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass,
932742Sksewell@umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
942742Sksewell@umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
952742Sksewell@umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
964661Sksewell@umich.edu        {
974661Sksewell@umich.edu        }
984661Sksewell@umich.edu
999554Sandreas.hansson@arm.com        std::string
1009554Sandreas.hansson@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1019554Sandreas.hansson@arm.com    };
1029554Sandreas.hansson@arm.com}};
1039554Sandreas.hansson@arm.com
1044661Sksewell@umich.edu
1054661Sksewell@umich.eduoutput decoder {{
1064661Sksewell@umich.edu    std::string
1074661Sksewell@umich.edu    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1085222Sksewell@umich.edu    {
1094661Sksewell@umich.edu        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1104661Sksewell@umich.edu                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1115222Sksewell@umich.edu    }
1124661Sksewell@umich.edu
1134661Sksewell@umich.edu    std::string
1145222Sksewell@umich.edu    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1154661Sksewell@umich.edu    {
1164661Sksewell@umich.edu        return csprintf("%-10s (r%d)", mnemonic, RB);
1175222Sksewell@umich.edu    }
1184661Sksewell@umich.edu}};
1194661Sksewell@umich.edu
1205222Sksewell@umich.edudef format LoadAddress(code) {{
1214661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
1224661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
1234661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
1244661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
1254661Sksewell@umich.edu    exec_output = BasicExecute.subst(iop)
1264661Sksewell@umich.edu}};
1274661Sksewell@umich.edu
1284661Sksewell@umich.edu
1294661Sksewell@umich.edudef template LoadStoreDeclare {{
1304661Sksewell@umich.edu    /**
1314661Sksewell@umich.edu     * Static instruction class for "%(mnemonic)s".
1322022SN/A     */
1332022SN/A    class %(class_name)s : public %(base_class)s
1342124SN/A    {
1352124SN/A      protected:
1362124SN/A
1372124SN/A        /**
1382124SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1392124SN/A         */
1402124SN/A        class EAComp : public %(base_class)s
1412124SN/A        {
1422124SN/A          public:
1434661Sksewell@umich.edu            /// Constructor
1442124SN/A            EAComp(MachInst machInst);
1452124SN/A
1462124SN/A            %(BasicExecDeclare)s
1476207Sksewell@umich.edu        };
1486207Sksewell@umich.edu
1492124SN/A        /**
1502124SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1512124SN/A         */
1522124SN/A        class MemAcc : public %(base_class)s
1532022SN/A        {
1542022SN/A          public:
1556207Sksewell@umich.edu            /// Constructor
1566207Sksewell@umich.edu            MemAcc(MachInst machInst);
1576207Sksewell@umich.edu
1582124SN/A            %(BasicExecDeclare)s
1592124SN/A        };
1602132SN/A
1612022SN/A      public:
1622124SN/A
1632124SN/A        /// Constructor.
1642124SN/A        %(class_name)s(MachInst machInst);
1654661Sksewell@umich.edu
1662124SN/A        %(BasicExecDeclare)s
1672124SN/A
1686207Sksewell@umich.edu        %(InitiateAccDeclare)s
1696207Sksewell@umich.edu
1706207Sksewell@umich.edu        %(CompleteAccDeclare)s
1712124SN/A    };
1723953Sstever@eecs.umich.edu}};
1732124SN/A
1743953Sstever@eecs.umich.edu
1752124SN/Adef template InitiateAccDeclare {{
1763953Sstever@eecs.umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1772124SN/A}};
1782132SN/A
1796207Sksewell@umich.edu
1802124SN/Adef template CompleteAccDeclare {{
1812124SN/A    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
1822124SN/A}};
1832132SN/A
1842124SN/A
1855222Sksewell@umich.edudef template LoadStoreConstructor {{
1865222Sksewell@umich.edu    /** TODO: change op_class to AddrGenOp or something (requires
1875222Sksewell@umich.edu     * creating new member of OpClass enum in op_class.hh, updating
1885222Sksewell@umich.edu     * config files, etc.). */
1895222Sksewell@umich.edu    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1905222Sksewell@umich.edu        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
1915222Sksewell@umich.edu    {
1922124SN/A        %(ea_constructor)s;
1932124SN/A    }
1943953Sstever@eecs.umich.edu
1952124SN/A    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
1964661Sksewell@umich.edu        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
1972124SN/A    {
1982124SN/A        %(memacc_constructor)s;
1992124SN/A    }
2002124SN/A
2012124SN/A    inline %(class_name)s::%(class_name)s(MachInst machInst)
2022124SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2032124SN/A                          new EAComp(machInst), new MemAcc(machInst))
2042124SN/A    {
2052124SN/A        %(constructor)s;
2062132SN/A    }
2072124SN/A}};
2082124SN/A
2092124SN/A
2102132SN/Adef template EACompExecute {{
2112124SN/A    Fault
2125222Sksewell@umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2135222Sksewell@umich.edu                                   Trace::InstRecord *traceData) const
2145222Sksewell@umich.edu    {
2155222Sksewell@umich.edu        Addr EA;
2165222Sksewell@umich.edu        Fault fault = NoFault;
2175222Sksewell@umich.edu
2185222Sksewell@umich.edu        %(fp_enable_check)s;
2192124SN/A        %(op_decl)s;
2202124SN/A        %(op_rd)s;
2212124SN/A        %(code)s;
2222124SN/A
2232124SN/A        if (fault == NoFault) {
2248442Sgblack@eecs.umich.edu            %(op_wb)s;
2252124SN/A            xc->setEA(EA);
2262124SN/A        }
2272124SN/A
2282124SN/A        return fault;
2292124SN/A    }
2302124SN/A}};
2312124SN/A
2322124SN/Adef template LoadMemAccExecute {{
2332124SN/A    Fault
2342124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2352124SN/A                                   Trace::InstRecord *traceData) const
2362124SN/A    {
2372124SN/A        Addr EA;
2382132SN/A        Fault fault = NoFault;
2392124SN/A
2402124SN/A        %(fp_enable_check)s;
2412239SN/A        %(op_decl)s;
2422132SN/A        %(op_rd)s;
2432239SN/A        EA = xc->getEA();
2445222Sksewell@umich.edu
2455222Sksewell@umich.edu        if (fault == NoFault) {
2465222Sksewell@umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2475222Sksewell@umich.edu            %(code)s;
2485222Sksewell@umich.edu        }
2495222Sksewell@umich.edu
2505222Sksewell@umich.edu        if (fault == NoFault) {
2512239SN/A            %(op_wb)s;
2522239SN/A        }
2532239SN/A
2542239SN/A        return fault;
2552239SN/A    }
2568442Sgblack@eecs.umich.edu}};
2572239SN/A
2582239SN/A
2592124SN/Adef template LoadExecute {{
2602124SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2612124SN/A                                  Trace::InstRecord *traceData) const
2622124SN/A    {
2632124SN/A        Addr EA;
2644661Sksewell@umich.edu        Fault fault = NoFault;
2652124SN/A
2662124SN/A        %(fp_enable_check)s;
2672124SN/A        %(op_decl)s;
2682132SN/A        %(op_rd)s;
2692239SN/A        %(ea_code)s;
2705222Sksewell@umich.edu
2715222Sksewell@umich.edu        if (fault == NoFault) {
2725222Sksewell@umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2735222Sksewell@umich.edu            %(memacc_code)s;
2745222Sksewell@umich.edu        }
2755222Sksewell@umich.edu
2765222Sksewell@umich.edu        if (fault == NoFault) {
2772506SN/A            %(op_wb)s;
2784661Sksewell@umich.edu        }
2792239SN/A
2808442Sgblack@eecs.umich.edu        return fault;
2812239SN/A    }
2822239SN/A}};
2832239SN/A
2842239SN/A
2852239SN/Adef template LoadInitiateAcc {{
2862239SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2872239SN/A                                      Trace::InstRecord *traceData) const
2882239SN/A    {
2892239SN/A        Addr EA;
2902124SN/A        Fault fault = NoFault;
2912124SN/A
2922124SN/A        %(fp_enable_check)s;
2932124SN/A        %(op_src_decl)s;
2942124SN/A        %(op_rd)s;
2952132SN/A        %(ea_code)s;
2962124SN/A
2972124SN/A        if (fault == NoFault) {
2982124SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2992132SN/A        }
3004056Sstever@eecs.umich.edu
3014056Sstever@eecs.umich.edu        return fault;
3024056Sstever@eecs.umich.edu    }
3034056Sstever@eecs.umich.edu}};
3044056Sstever@eecs.umich.edu
3054056Sstever@eecs.umich.edu
3064056Sstever@eecs.umich.edudef template LoadCompleteAcc {{
3074056Sstever@eecs.umich.edu    Fault %(class_name)s::completeAcc(uint8_t *data,
3084056Sstever@eecs.umich.edu                                      %(CPU_exec_context)s *xc,
3094056Sstever@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3104056Sstever@eecs.umich.edu    {
3118442Sgblack@eecs.umich.edu        Fault fault = NoFault;
3128442Sgblack@eecs.umich.edu
3134056Sstever@eecs.umich.edu        %(fp_enable_check)s;
3144056Sstever@eecs.umich.edu        %(op_src_decl)s;
3154056Sstever@eecs.umich.edu        %(op_dest_decl)s;
3164056Sstever@eecs.umich.edu
3174056Sstever@eecs.umich.edu        memcpy(&Mem, data, sizeof(Mem));
3184056Sstever@eecs.umich.edu
3194056Sstever@eecs.umich.edu        if (fault == NoFault) {
3204056Sstever@eecs.umich.edu            %(memacc_code)s;
3214056Sstever@eecs.umich.edu        }
3224056Sstever@eecs.umich.edu
3234056Sstever@eecs.umich.edu        if (fault == NoFault) {
3244056Sstever@eecs.umich.edu            %(op_wb)s;
3254056Sstever@eecs.umich.edu        }
3264056Sstever@eecs.umich.edu
3275222Sksewell@umich.edu        return fault;
3285222Sksewell@umich.edu    }
3295222Sksewell@umich.edu}};
3305222Sksewell@umich.edu
3315222Sksewell@umich.edu
3325222Sksewell@umich.edudef template StoreMemAccExecute {{
3335222Sksewell@umich.edu    Fault
3345222Sksewell@umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3355222Sksewell@umich.edu                                   Trace::InstRecord *traceData) const
3365222Sksewell@umich.edu    {
3375222Sksewell@umich.edu        Addr EA;
3385222Sksewell@umich.edu        Fault fault = NoFault;
3395222Sksewell@umich.edu        uint64_t write_result = 0;
3405222Sksewell@umich.edu
3415222Sksewell@umich.edu        %(fp_enable_check)s;
3425222Sksewell@umich.edu        %(op_decl)s;
3435222Sksewell@umich.edu        %(op_rd)s;
3445222Sksewell@umich.edu        EA = xc->getEA();
3455222Sksewell@umich.edu
3465222Sksewell@umich.edu        if (fault == NoFault) {
3478442Sgblack@eecs.umich.edu            %(code)s;
3488442Sgblack@eecs.umich.edu        }
3495222Sksewell@umich.edu
3505222Sksewell@umich.edu        if (fault == NoFault) {
3515222Sksewell@umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3525222Sksewell@umich.edu                              memAccessFlags, &write_result);
3535222Sksewell@umich.edu            if (traceData) { traceData->setData(Mem); }
3545222Sksewell@umich.edu        }
3555222Sksewell@umich.edu
3565222Sksewell@umich.edu        if (fault == NoFault) {
3575222Sksewell@umich.edu            %(postacc_code)s;
3585222Sksewell@umich.edu        }
3595222Sksewell@umich.edu
3605222Sksewell@umich.edu        if (fault == NoFault) {
3615222Sksewell@umich.edu            %(op_wb)s;
3625222Sksewell@umich.edu        }
3634056Sstever@eecs.umich.edu
3644056Sstever@eecs.umich.edu        return fault;
3654056Sstever@eecs.umich.edu    }
3664056Sstever@eecs.umich.edu}};
3674056Sstever@eecs.umich.edu
3684056Sstever@eecs.umich.edu
3692124SN/Adef template StoreExecute {{
3702124SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3712124SN/A                                  Trace::InstRecord *traceData) const
3722124SN/A    {
3732124SN/A        Addr EA;
3742124SN/A        Fault fault = NoFault;
3752124SN/A        uint64_t write_result = 0;
3762124SN/A
3772124SN/A        %(fp_enable_check)s;
3782124SN/A        %(op_decl)s;
3792124SN/A        %(op_rd)s;
3802124SN/A        %(ea_code)s;
3818442Sgblack@eecs.umich.edu
3828442Sgblack@eecs.umich.edu        if (fault == NoFault) {
3832124SN/A            %(memacc_code)s;
3842124SN/A        }
3852124SN/A
3862124SN/A        if (fault == NoFault) {
3872124SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3882124SN/A                              memAccessFlags, &write_result);
3892124SN/A            if (traceData) { traceData->setData(Mem); }
3902124SN/A        }
3912124SN/A
3922124SN/A        if (fault == NoFault) {
3932124SN/A            %(postacc_code)s;
3942124SN/A        }
3952124SN/A
3962124SN/A        if (fault == NoFault) {
3972124SN/A            %(op_wb)s;
3982132SN/A        }
3992124SN/A
4002124SN/A        return fault;
4012239SN/A    }
4022132SN/A}};
4032239SN/A
4042239SN/Adef template StoreInitiateAcc {{
4052506SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4062239SN/A                                      Trace::InstRecord *traceData) const
4072239SN/A    {
4082239SN/A        Addr EA;
4092239SN/A        Fault fault = NoFault;
4102239SN/A        uint64_t write_result = 0;
4112239SN/A
4122239SN/A        %(fp_enable_check)s;
4132239SN/A        %(op_src_decl)s;
4148442Sgblack@eecs.umich.edu        %(op_dest_decl)s;
4158442Sgblack@eecs.umich.edu        %(op_rd)s;
4162239SN/A        %(ea_code)s;
4172239SN/A
4182124SN/A        if (fault == NoFault) {
4192124SN/A            %(memacc_code)s;
4202124SN/A        }
4212124SN/A
4222124SN/A        if (fault == NoFault) {
4232124SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4244661Sksewell@umich.edu                              memAccessFlags, &write_result);
4252124SN/A            if (traceData) { traceData->setData(Mem); }
4262124SN/A        }
4272124SN/A
4287712Sgblack@eecs.umich.edu        return fault;
4292935Sksewell@umich.edu    }
4302935Sksewell@umich.edu}};
4312935Sksewell@umich.edu
4322935Sksewell@umich.edu
4334661Sksewell@umich.edudef template StoreCompleteAcc {{
4342935Sksewell@umich.edu    Fault %(class_name)s::completeAcc(uint8_t *data,
4352935Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
4362935Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
4372935Sksewell@umich.edu    {
4382935Sksewell@umich.edu        Fault fault = NoFault;
4392935Sksewell@umich.edu        uint64_t write_result = 0;
4402935Sksewell@umich.edu
4412935Sksewell@umich.edu        %(fp_enable_check)s;
4424055Ssaidi@eecs.umich.edu        %(op_dest_decl)s;
4432239SN/A
4442239SN/A        memcpy(&write_result, data, sizeof(write_result));
4452239SN/A
4462239SN/A        if (fault == NoFault) {
4472239SN/A            %(postacc_code)s;
4482239SN/A        }
4492239SN/A
4502239SN/A        if (fault == NoFault) {
4512239SN/A            %(op_wb)s;
4522124SN/A        }
4532124SN/A
4542124SN/A        return fault;
4552124SN/A    }
4562686Sksewell@umich.edu}};
4572686Sksewell@umich.edu
4582686Sksewell@umich.edu
4592686Sksewell@umich.edudef template MiscMemAccExecute {{
4607725SAli.Saidi@ARM.com    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4612686Sksewell@umich.edu                                          Trace::InstRecord *traceData) const
4622686Sksewell@umich.edu    {
4632686Sksewell@umich.edu        Addr EA;
4642686Sksewell@umich.edu        Fault fault = NoFault;
4652686Sksewell@umich.edu
4662686Sksewell@umich.edu        %(fp_enable_check)s;
4672686Sksewell@umich.edu        %(op_decl)s;
4682686Sksewell@umich.edu        %(op_rd)s;
4692686Sksewell@umich.edu        EA = xc->getEA();
4702686Sksewell@umich.edu
4712686Sksewell@umich.edu        if (fault == NoFault) {
4722686Sksewell@umich.edu            %(code)s;
4732686Sksewell@umich.edu        }
4742686Sksewell@umich.edu
4752686Sksewell@umich.edu        return NoFault;
4762686Sksewell@umich.edu    }
4772686Sksewell@umich.edu}};
4782686Sksewell@umich.edu
4792686Sksewell@umich.edudef template MiscExecute {{
4802686Sksewell@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4812686Sksewell@umich.edu                                  Trace::InstRecord *traceData) const
4822686Sksewell@umich.edu    {
4832686Sksewell@umich.edu        Addr EA;
4842686Sksewell@umich.edu        Fault fault = NoFault;
4852686Sksewell@umich.edu
4862686Sksewell@umich.edu        %(fp_enable_check)s;
4874661Sksewell@umich.edu        %(op_decl)s;
4882686Sksewell@umich.edu        %(op_rd)s;
4892686Sksewell@umich.edu        %(ea_code)s;
4902686Sksewell@umich.edu
4912686Sksewell@umich.edu        if (fault == NoFault) {
4922686Sksewell@umich.edu            %(memacc_code)s;
4932686Sksewell@umich.edu        }
4942686Sksewell@umich.edu
4952686Sksewell@umich.edu        return NoFault;
4962686Sksewell@umich.edu    }
4972124SN/A}};
4982124SN/A
4992124SN/Adef template MiscInitiateAcc {{
5002124SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5012750Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
5022124SN/A    {
5032124SN/A        panic("Misc instruction does not support split access method!");
5042124SN/A        return NoFault;
5055222Sksewell@umich.edu    }
5062124SN/A}};
5072124SN/A
5082124SN/A
5092124SN/Adef template MiscCompleteAcc {{
5102124SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
5112124SN/A                                      %(CPU_exec_context)s *xc,
5122124SN/A                                      Trace::InstRecord *traceData) const
5132686Sksewell@umich.edu    {
5142573SN/A        panic("Misc instruction does not support split access method!");
5155222Sksewell@umich.edu
5162573SN/A        return NoFault;
5172573SN/A    }
5182750Sksewell@umich.edu}};
5192573SN/A
5202573SN/A// load instructions use Ra as dest, so check for
5212573SN/A// Ra == 31 to detect nops
5222686Sksewell@umich.edudef template LoadNopCheckDecode {{
5232573SN/A {
5245222Sksewell@umich.edu     AlphaStaticInst *i = new %(class_name)s(machInst);
5252573SN/A     if (RA == 31) {
5262573SN/A         i = makeNop(i);
5272573SN/A     }
5282573SN/A     return i;
5292573SN/A }
5305222Sksewell@umich.edu}};
5315222Sksewell@umich.edu
5325222Sksewell@umich.edu
5335222Sksewell@umich.edu// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
5345222Sksewell@umich.edudef template LoadPrefetchCheckDecode {{
5355222Sksewell@umich.edu {
5365222Sksewell@umich.edu     if (RA != 31) {
5375222Sksewell@umich.edu         return new %(class_name)s(machInst);
5385222Sksewell@umich.edu     }
5395222Sksewell@umich.edu     else {
5405222Sksewell@umich.edu         return new %(class_name)sPrefetch(machInst);
5415222Sksewell@umich.edu     }
5425222Sksewell@umich.edu }
5435222Sksewell@umich.edu}};
5445222Sksewell@umich.edu
5455222Sksewell@umich.edu
5465222Sksewell@umich.edulet {{
5475222Sksewell@umich.edudef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5482686Sksewell@umich.edu                  postacc_code = '', base_class = 'MemoryDisp32',
5492686Sksewell@umich.edu                  decode_template = BasicDecode, exec_template_base = ''):
5508564Sgblack@eecs.umich.edu    # Make sure flags are in lists (convert to lists if not).
5518588Sgblack@eecs.umich.edu    mem_flags = makeList(mem_flags)
5528564Sgblack@eecs.umich.edu    inst_flags = makeList(inst_flags)
5538564Sgblack@eecs.umich.edu
5548564Sgblack@eecs.umich.edu    # add hook to get effective addresses into execution trace output.
5558564Sgblack@eecs.umich.edu    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5568564Sgblack@eecs.umich.edu
5572573SN/A    # generate code block objects
5582686Sksewell@umich.edu    ea_cblk = CodeBlock(ea_code)
5592686Sksewell@umich.edu    memacc_cblk = CodeBlock(memacc_code)
5602686Sksewell@umich.edu    postacc_cblk = CodeBlock(postacc_code)
5612686Sksewell@umich.edu
5622750Sksewell@umich.edu    # Some CPU models execute the memory operation as an atomic unit,
5632686Sksewell@umich.edu    # while others want to separate them into an effective address
5642686Sksewell@umich.edu    # computation and a memory access operation.  As a result, we need
5652686Sksewell@umich.edu    # to generate three StaticInst objects.  Note that the latter two
5662686Sksewell@umich.edu    # are nested inside the larger "atomic" one.
5672686Sksewell@umich.edu
5688442Sgblack@eecs.umich.edu    # generate InstObjParams for EAComp object
5698442Sgblack@eecs.umich.edu    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
5708442Sgblack@eecs.umich.edu
5718442Sgblack@eecs.umich.edu    # generate InstObjParams for MemAcc object
5728564Sgblack@eecs.umich.edu    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
5738442Sgblack@eecs.umich.edu    # in the split execution model, the MemAcc portion is responsible
5748442Sgblack@eecs.umich.edu    # for the post-access code.
5758442Sgblack@eecs.umich.edu    memacc_iop.postacc_code = postacc_cblk.code
5762686Sksewell@umich.edu
5772686Sksewell@umich.edu    # generate InstObjParams for InitiateAcc, CompleteAcc object
5782686Sksewell@umich.edu    # The code used depends on the template being used
5792686Sksewell@umich.edu    if (exec_template_base == 'Load'):
5802686Sksewell@umich.edu        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
5812686Sksewell@umich.edu        completeacc_cblk = CodeBlock(memacc_code + postacc_code)
5822686Sksewell@umich.edu    elif (exec_template_base == 'Store'):
5832686Sksewell@umich.edu        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
5842686Sksewell@umich.edu        completeacc_cblk = CodeBlock(postacc_code)
5856739Sgblack@eecs.umich.edu    else:
5867725SAli.Saidi@ARM.com        initiateacc_cblk = ''
5872686Sksewell@umich.edu        completeacc_cblk = ''
5882686Sksewell@umich.edu
5892686Sksewell@umich.edu    initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
5907725SAli.Saidi@ARM.com                                    inst_flags)
5912686Sksewell@umich.edu
5922686Sksewell@umich.edu    completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
5932686Sksewell@umich.edu                                    inst_flags)
5942686Sksewell@umich.edu
5952686Sksewell@umich.edu    if (exec_template_base == 'Load'):
5962686Sksewell@umich.edu        initiateacc_iop.ea_code = ea_cblk.code
5972495SN/A        initiateacc_iop.memacc_code = memacc_cblk.code
5982495SN/A        completeacc_iop.memacc_code = memacc_cblk.code
5992495SN/A        completeacc_iop.postacc_code = postacc_cblk.code
6002935Sksewell@umich.edu    elif (exec_template_base == 'Store'):
6012495SN/A        initiateacc_iop.ea_code = ea_cblk.code
602        initiateacc_iop.memacc_code = memacc_cblk.code
603        completeacc_iop.postacc_code = postacc_cblk.code
604
605    # generate InstObjParams for unified execution
606    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
607    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
608
609    iop.ea_constructor = ea_cblk.constructor
610    iop.ea_code = ea_cblk.code
611    iop.memacc_constructor = memacc_cblk.constructor
612    iop.memacc_code = memacc_cblk.code
613    iop.postacc_code = postacc_cblk.code
614
615    if mem_flags:
616        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
617        iop.constructor += s
618        memacc_iop.constructor += s
619
620    # select templates
621    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
622    fullExecTemplate = eval(exec_template_base + 'Execute')
623    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
624    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
625
626    # (header_output, decoder_output, decode_block, exec_output)
627    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
628            decode_template.subst(iop),
629            EACompExecute.subst(ea_iop)
630            + memAccExecTemplate.subst(memacc_iop)
631            + fullExecTemplate.subst(iop)
632            + initiateAccTemplate.subst(initiateacc_iop)
633            + completeAccTemplate.subst(completeacc_iop))
634}};
635
636
637def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
638                     mem_flags = [], inst_flags = []) {{
639    (header_output, decoder_output, decode_block, exec_output) = \
640        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
641                      decode_template = LoadNopCheckDecode,
642                      exec_template_base = 'Load')
643}};
644
645
646// Note that the flags passed in apply only to the prefetch version
647def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
648                          mem_flags = [], pf_flags = [], inst_flags = []) {{
649    # declare the load instruction object and generate the decode block
650    (header_output, decoder_output, decode_block, exec_output) = \
651        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
652                      decode_template = LoadPrefetchCheckDecode,
653                      exec_template_base = 'Load')
654
655    # Declare the prefetch instruction object.
656
657    # Make sure flag args are lists so we can mess with them.
658    mem_flags = makeList(mem_flags)
659    pf_flags = makeList(pf_flags)
660    inst_flags = makeList(inst_flags)
661
662    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
663    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
664                                  'IsDataPrefetch', 'MemReadOp']
665
666    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
667        LoadStoreBase(name, Name + 'Prefetch', ea_code,
668                      'xc->prefetch(EA, memAccessFlags);',
669                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
670
671    header_output += pf_header_output
672    decoder_output += pf_decoder_output
673    exec_output += pf_exec_output
674}};
675
676
677def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
678                 mem_flags = [], inst_flags = []) {{
679    (header_output, decoder_output, decode_block, exec_output) = \
680        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
681                      exec_template_base = 'Store')
682}};
683
684
685def format StoreCond(memacc_code, postacc_code,
686                     ea_code = {{ EA = Rb + disp; }},
687                     mem_flags = [], inst_flags = []) {{
688    (header_output, decoder_output, decode_block, exec_output) = \
689        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
690                      postacc_code, exec_template_base = 'Store')
691}};
692
693
694// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
695def format MiscPrefetch(ea_code, memacc_code,
696                        mem_flags = [], inst_flags = []) {{
697    (header_output, decoder_output, decode_block, exec_output) = \
698        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
699                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
700}};
701
702
703