mem.isa revision 5736
12124SN/A// -*- mode:c++ -*-
22124SN/A
35268Sksewell@umich.edu// Copyright (c) 2007 MIPS Technologies, Inc.
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.edu// Authors: Steve Reinhardt
305268Sksewell@umich.edu//          Korey Sewell
312022SN/A
322649Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
332649Ssaidi@eecs.umich.edu//
342706Sksewell@umich.edu// Memory-format instructions
352649Ssaidi@eecs.umich.edu//
362649Ssaidi@eecs.umich.edu
372022SN/Aoutput header {{
382124SN/A    /**
392124SN/A     * Base class for general Mips memory-format instructions.
402124SN/A     */
412124SN/A    class Memory : public MipsStaticInst
422124SN/A    {
432124SN/A      protected:
442124SN/A
452124SN/A        /// Memory request flags.  See mem_req_base.hh.
465736Snate@binkert.org        Request::Flags memAccessFlags;
472124SN/A        /// Pointer to EAComp object.
482124SN/A        const StaticInstPtr eaCompPtr;
492124SN/A        /// Pointer to MemAcc object.
502124SN/A        const StaticInstPtr memAccPtr;
512239SN/A
522124SN/A        /// Displacement for EA calculation (signed).
532124SN/A        int32_t disp;
542124SN/A
552124SN/A        /// Constructor
562124SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
572124SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
582124SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
592124SN/A            : MipsStaticInst(mnem, _machInst, __opClass),
605736Snate@binkert.org              eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
612742Sksewell@umich.edu              disp(sext<16>(OFFSET))
622022SN/A        {
632124SN/A        }
642022SN/A
652124SN/A        std::string
662124SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
672022SN/A
682124SN/A      public:
692124SN/A
702124SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
712124SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
724661Sksewell@umich.edu
735736Snate@binkert.org        Request::Flags memAccFlags() { return memAccessFlags; }
742124SN/A    };
752124SN/A
762742Sksewell@umich.edu     /**
772742Sksewell@umich.edu     * Base class for a few miscellaneous memory-format insts
782742Sksewell@umich.edu     * that don't interpret the disp field
792742Sksewell@umich.edu     */
802742Sksewell@umich.edu    class MemoryNoDisp : public Memory
812742Sksewell@umich.edu    {
822742Sksewell@umich.edu      protected:
832742Sksewell@umich.edu        /// Constructor
842742Sksewell@umich.edu        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
852742Sksewell@umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
862742Sksewell@umich.edu                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
872742Sksewell@umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
882742Sksewell@umich.edu        {
892742Sksewell@umich.edu        }
902742Sksewell@umich.edu
912742Sksewell@umich.edu        std::string
922742Sksewell@umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
932742Sksewell@umich.edu    };
942022SN/A}};
952022SN/A
962124SN/A
972022SN/Aoutput decoder {{
982124SN/A    std::string
992124SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1002124SN/A    {
1012742Sksewell@umich.edu        return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
1022239SN/A                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
1032124SN/A    }
1042124SN/A
1052742Sksewell@umich.edu    std::string
1062742Sksewell@umich.edu    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1072742Sksewell@umich.edu    {
1082742Sksewell@umich.edu        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
1092742Sksewell@umich.edu                        flags[IsFloating] ? 'f' : 'r',
1102742Sksewell@umich.edu                        flags[IsFloating] ? FD : RD,
1112742Sksewell@umich.edu                        RS, RT);
1122742Sksewell@umich.edu    }
1134661Sksewell@umich.edu
1144661Sksewell@umich.edu}};
1154661Sksewell@umich.edu
1164661Sksewell@umich.eduoutput exec {{
1174661Sksewell@umich.edu    /** return data in cases where there the size of data is only
1184661Sksewell@umich.edu        known in the packet
1194661Sksewell@umich.edu    */
1205222Sksewell@umich.edu    uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) {
1214661Sksewell@umich.edu        switch (packet->getSize())
1224661Sksewell@umich.edu        {
1235222Sksewell@umich.edu          case 1:
1244661Sksewell@umich.edu            return packet->get<uint8_t>();
1254661Sksewell@umich.edu
1265222Sksewell@umich.edu          case 2:
1274661Sksewell@umich.edu            return packet->get<uint16_t>();
1284661Sksewell@umich.edu
1295222Sksewell@umich.edu          case 4:
1304661Sksewell@umich.edu            return packet->get<uint32_t>();
1314661Sksewell@umich.edu
1325222Sksewell@umich.edu          case 8:
1334661Sksewell@umich.edu            return packet->get<uint64_t>();
1344661Sksewell@umich.edu
1354661Sksewell@umich.edu          default:
1364661Sksewell@umich.edu            std::cerr << "bad store data size = " << packet->getSize() << std::endl;
1374661Sksewell@umich.edu
1384661Sksewell@umich.edu            assert(0);
1394661Sksewell@umich.edu            return 0;
1404661Sksewell@umich.edu        }
1414661Sksewell@umich.edu    }
1424661Sksewell@umich.edu
1434661Sksewell@umich.edu
1442022SN/A}};
1452022SN/A
1462124SN/Adef template LoadStoreDeclare {{
1472124SN/A    /**
1482124SN/A     * Static instruction class for "%(mnemonic)s".
1492124SN/A     */
1502124SN/A    class %(class_name)s : public %(base_class)s
1512124SN/A    {
1522124SN/A      protected:
1532124SN/A
1542124SN/A        /**
1552124SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1562124SN/A         */
1572124SN/A        class EAComp : public %(base_class)s
1582124SN/A        {
1592124SN/A          public:
1602124SN/A            /// Constructor
1614661Sksewell@umich.edu            EAComp(ExtMachInst machInst);
1622124SN/A
1632124SN/A            %(BasicExecDeclare)s
1642124SN/A        };
1652124SN/A
1662124SN/A        /**
1672124SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1682124SN/A         */
1692124SN/A        class MemAcc : public %(base_class)s
1702124SN/A        {
1712124SN/A          public:
1722124SN/A            /// Constructor
1734661Sksewell@umich.edu            MemAcc(ExtMachInst machInst);
1742124SN/A
1752124SN/A            %(BasicExecDeclare)s
1762124SN/A        };
1772124SN/A
1782124SN/A      public:
1792124SN/A
1802124SN/A        /// Constructor.
1814661Sksewell@umich.edu        %(class_name)s(ExtMachInst machInst);
1822124SN/A
1832124SN/A        %(BasicExecDeclare)s
1842124SN/A
1852124SN/A        %(InitiateAccDeclare)s
1862124SN/A
1872124SN/A        %(CompleteAccDeclare)s
1884661Sksewell@umich.edu
1894661Sksewell@umich.edu        %(MemAccSizeDeclare)s
1902124SN/A    };
1912022SN/A}};
1922022SN/A
1932124SN/A
1942124SN/Adef template InitiateAccDeclare {{
1952132SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1962022SN/A}};
1972124SN/A
1982124SN/A
1992124SN/Adef template CompleteAccDeclare {{
2004661Sksewell@umich.edu    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
2012124SN/A}};
2022124SN/A
2034661Sksewell@umich.edudef template MemAccSizeDeclare {{
2044661Sksewell@umich.edu    int memAccSize(%(CPU_exec_context)s *xc);
2054661Sksewell@umich.edu}};
2062124SN/A
2075222Sksewell@umich.edu
2085222Sksewell@umich.edudef template MiscMemAccSize {{
2095222Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
2105222Sksewell@umich.edu    {
2115222Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
2125222Sksewell@umich.edu        return 0;
2135222Sksewell@umich.edu    }
2145222Sksewell@umich.edu}};
2155222Sksewell@umich.edu
2163953Sstever@eecs.umich.edudef template EACompConstructor {{
2172124SN/A    /** TODO: change op_class to AddrGenOp or something (requires
2182124SN/A     * creating new member of OpClass enum in op_class.hh, updating
2192124SN/A     * config files, etc.). */
2204661Sksewell@umich.edu    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
2212124SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
2222124SN/A    {
2233953Sstever@eecs.umich.edu        %(constructor)s;
2242124SN/A    }
2253953Sstever@eecs.umich.edu}};
2262124SN/A
2273953Sstever@eecs.umich.edu
2283953Sstever@eecs.umich.edudef template MemAccConstructor {{
2294661Sksewell@umich.edu    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
2302124SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
2312124SN/A    {
2323953Sstever@eecs.umich.edu        %(constructor)s;
2332124SN/A    }
2343953Sstever@eecs.umich.edu}};
2352124SN/A
2363953Sstever@eecs.umich.edu
2373953Sstever@eecs.umich.edudef template LoadStoreConstructor {{
2384661Sksewell@umich.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
2392124SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2402124SN/A                          new EAComp(machInst), new MemAcc(machInst))
2412124SN/A    {
2422124SN/A        %(constructor)s;
2432124SN/A    }
2442124SN/A}};
2452124SN/A
2462124SN/A
2472124SN/Adef template EACompExecute {{
2482132SN/A    Fault
2492124SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2502124SN/A                                   Trace::InstRecord *traceData) const
2512124SN/A    {
2522124SN/A        Addr EA;
2532132SN/A        Fault fault = NoFault;
2542124SN/A
2555222Sksewell@umich.edu        if (this->isFloating()) {
2565222Sksewell@umich.edu            %(fp_enable_check)s;
2575222Sksewell@umich.edu
2585222Sksewell@umich.edu            if(fault != NoFault)
2595222Sksewell@umich.edu                return fault;
2605222Sksewell@umich.edu        }
2615222Sksewell@umich.edu
2622124SN/A        %(op_decl)s;
2632124SN/A        %(op_rd)s;
2643953Sstever@eecs.umich.edu        %(ea_code)s;
2652124SN/A
2664661Sksewell@umich.edu        // NOTE: Trace Data is written using execute or completeAcc templates
2672124SN/A        if (fault == NoFault) {
2682124SN/A            xc->setEA(EA);
2692124SN/A        }
2702124SN/A
2712124SN/A        return fault;
2722124SN/A    }
2732124SN/A}};
2742124SN/A
2755222Sksewell@umich.edudef template LoadStoreFPEACompExecute {{
2765222Sksewell@umich.edu    Fault
2775222Sksewell@umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2785222Sksewell@umich.edu                                   Trace::InstRecord *traceData) const
2795222Sksewell@umich.edu    {
2805222Sksewell@umich.edu        Addr EA;
2815222Sksewell@umich.edu        Fault fault = NoFault;
2825222Sksewell@umich.edu
2835222Sksewell@umich.edu        %(fp_enable_check)s;
2845222Sksewell@umich.edu        if(fault != NoFault)
2855222Sksewell@umich.edu          return fault;
2865222Sksewell@umich.edu        %(op_decl)s;
2875222Sksewell@umich.edu        %(op_rd)s;
2885222Sksewell@umich.edu        %(ea_code)s;
2895222Sksewell@umich.edu
2905222Sksewell@umich.edu        // NOTE: Trace Data is written using execute or completeAcc templates
2915222Sksewell@umich.edu        if (fault == NoFault) {
2925222Sksewell@umich.edu            xc->setEA(EA);
2935222Sksewell@umich.edu        }
2945222Sksewell@umich.edu
2955222Sksewell@umich.edu        return fault;
2965222Sksewell@umich.edu    }
2975222Sksewell@umich.edu}};
2985222Sksewell@umich.edu
2995222Sksewell@umich.edu
3002124SN/Adef template LoadMemAccExecute {{
3012132SN/A    Fault
3022124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3032124SN/A                                   Trace::InstRecord *traceData) const
3042124SN/A    {
3052239SN/A        Addr EA;
3065222Sksewell@umich.edu
3072132SN/A        Fault fault = NoFault;
3082239SN/A
3095222Sksewell@umich.edu        if (this->isFloating()) {
3105222Sksewell@umich.edu            %(fp_enable_check)s;
3115222Sksewell@umich.edu
3125222Sksewell@umich.edu            if(fault != NoFault)
3135222Sksewell@umich.edu                return fault;
3145222Sksewell@umich.edu        }
3155222Sksewell@umich.edu
3162239SN/A        %(op_decl)s;
3172239SN/A        %(op_rd)s;
3184661Sksewell@umich.edu
3192239SN/A        EA = xc->getEA();
3202239SN/A
3214661Sksewell@umich.edu        fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
3222239SN/A
3234661Sksewell@umich.edu        %(memacc_code)s;
3244661Sksewell@umich.edu
3254661Sksewell@umich.edu        // NOTE: Write back data using execute or completeAcc templates
3262239SN/A
3272124SN/A        return fault;
3282124SN/A    }
3292124SN/A}};
3302124SN/A
3312124SN/A
3322124SN/Adef template LoadExecute {{
3332132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3342124SN/A                                  Trace::InstRecord *traceData) const
3352124SN/A    {
3362124SN/A        Addr EA;
3372132SN/A        Fault fault = NoFault;
3382124SN/A
3395222Sksewell@umich.edu        if (this->isFloating()) {
3405222Sksewell@umich.edu            %(fp_enable_check)s;
3415222Sksewell@umich.edu
3425222Sksewell@umich.edu            if(fault != NoFault)
3435222Sksewell@umich.edu                return fault;
3445222Sksewell@umich.edu        }
3455222Sksewell@umich.edu
3462124SN/A        %(op_decl)s;
3472124SN/A        %(op_rd)s;
3482124SN/A        %(ea_code)s;
3492124SN/A
3502124SN/A        if (fault == NoFault) {
3512124SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
3522124SN/A            %(memacc_code)s;
3532124SN/A        }
3542124SN/A
3552124SN/A        if (fault == NoFault) {
3562124SN/A            %(op_wb)s;
3572124SN/A        }
3582124SN/A
3592124SN/A        return fault;
3602124SN/A    }
3612124SN/A}};
3622124SN/A
3632124SN/A
3642124SN/Adef template LoadInitiateAcc {{
3652132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3662124SN/A                                      Trace::InstRecord *traceData) const
3672124SN/A    {
3682239SN/A        Addr EA;
3692132SN/A        Fault fault = NoFault;
3702239SN/A
3715222Sksewell@umich.edu        if (this->isFloating()) {
3725222Sksewell@umich.edu            %(fp_enable_check)s;
3735222Sksewell@umich.edu
3745222Sksewell@umich.edu            if(fault != NoFault)
3755222Sksewell@umich.edu                return fault;
3765222Sksewell@umich.edu        }
3775222Sksewell@umich.edu
3782239SN/A        %(op_src_decl)s;
3792239SN/A        %(op_rd)s;
3802239SN/A        %(ea_code)s;
3812239SN/A
3822239SN/A        if (fault == NoFault) {
3832239SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
3842239SN/A        }
3852239SN/A
3862124SN/A        return fault;
3872124SN/A    }
3882124SN/A}};
3892124SN/A
3902124SN/Adef template LoadCompleteAcc {{
3914661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
3922124SN/A                                      %(CPU_exec_context)s *xc,
3932124SN/A                                      Trace::InstRecord *traceData) const
3942124SN/A    {
3952132SN/A        Fault fault = NoFault;
3962239SN/A
3975222Sksewell@umich.edu        if (this->isFloating()) {
3985222Sksewell@umich.edu            %(fp_enable_check)s;
3995222Sksewell@umich.edu
4005222Sksewell@umich.edu            if(fault != NoFault)
4015222Sksewell@umich.edu                return fault;
4025222Sksewell@umich.edu        }
4035222Sksewell@umich.edu
4042506SN/A        %(op_decl)s;
4054661Sksewell@umich.edu        %(op_rd)s;
4062239SN/A
4072935Sksewell@umich.edu        Mem = pkt->get<typeof(Mem)>();
4082239SN/A
4092239SN/A        if (fault == NoFault) {
4102239SN/A            %(memacc_code)s;
4112239SN/A        }
4122239SN/A
4132239SN/A        if (fault == NoFault) {
4142239SN/A            %(op_wb)s;
4152239SN/A        }
4162239SN/A
4172124SN/A        return fault;
4182124SN/A    }
4192124SN/A}};
4202124SN/A
4212124SN/A
4224661Sksewell@umich.edudef template LoadStoreMemAccSize {{
4234661Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
4244661Sksewell@umich.edu    {
4254661Sksewell@umich.edu        // Return the memory access size in bytes
4264661Sksewell@umich.edu        return (%(mem_acc_size)d / 8);
4274661Sksewell@umich.edu    }
4284661Sksewell@umich.edu}};
4294661Sksewell@umich.edu
4302124SN/Adef template StoreMemAccExecute {{
4312132SN/A    Fault
4322124SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4332124SN/A                                   Trace::InstRecord *traceData) const
4342124SN/A    {
4352239SN/A        Addr EA;
4362132SN/A        Fault fault = NoFault;
4374056Sstever@eecs.umich.edu
4384056Sstever@eecs.umich.edu        %(fp_enable_check)s;
4394056Sstever@eecs.umich.edu        %(op_decl)s;
4404056Sstever@eecs.umich.edu        %(op_rd)s;
4414661Sksewell@umich.edu
4424056Sstever@eecs.umich.edu        EA = xc->getEA();
4434056Sstever@eecs.umich.edu
4444056Sstever@eecs.umich.edu        if (fault == NoFault) {
4454056Sstever@eecs.umich.edu            %(memacc_code)s;
4464056Sstever@eecs.umich.edu        }
4474056Sstever@eecs.umich.edu
4484056Sstever@eecs.umich.edu        if (fault == NoFault) {
4494056Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4504675Sksewell@umich.edu                              memAccessFlags, NULL);
4514661Sksewell@umich.edu            // @NOTE: Need to Call Complete Access to Set Trace Data
4524661Sksewell@umich.edu            //if (traceData) { traceData->setData(Mem); }
4534056Sstever@eecs.umich.edu        }
4544056Sstever@eecs.umich.edu
4554056Sstever@eecs.umich.edu        return fault;
4564056Sstever@eecs.umich.edu    }
4574056Sstever@eecs.umich.edu}};
4584056Sstever@eecs.umich.edu
4594056Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{
4604056Sstever@eecs.umich.edu    Fault
4614056Sstever@eecs.umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4624056Sstever@eecs.umich.edu                                   Trace::InstRecord *traceData) const
4634056Sstever@eecs.umich.edu    {
4644056Sstever@eecs.umich.edu        Addr EA;
4654056Sstever@eecs.umich.edu        Fault fault = NoFault;
4662239SN/A        uint64_t write_result = 0;
4672239SN/A
4682239SN/A        %(fp_enable_check)s;
4692239SN/A        %(op_decl)s;
4702239SN/A        %(op_rd)s;
4712239SN/A        EA = xc->getEA();
4722239SN/A
4732239SN/A        if (fault == NoFault) {
4743953Sstever@eecs.umich.edu            %(memacc_code)s;
4752239SN/A        }
4762239SN/A
4772239SN/A        if (fault == NoFault) {
4782239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4792239SN/A                              memAccessFlags, &write_result);
4802239SN/A            if (traceData) { traceData->setData(Mem); }
4812239SN/A        }
4822239SN/A
4832239SN/A        if (fault == NoFault) {
4842239SN/A            %(postacc_code)s;
4852239SN/A        }
4862239SN/A
4872239SN/A        if (fault == NoFault) {
4882239SN/A            %(op_wb)s;
4892239SN/A        }
4902239SN/A
4912124SN/A        return fault;
4922124SN/A    }
4932124SN/A}};
4942124SN/A
4952124SN/Adef template StoreExecute {{
4962132SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4972124SN/A                                  Trace::InstRecord *traceData) const
4982124SN/A    {
4992124SN/A        Addr EA;
5002132SN/A        Fault fault = NoFault;
5014056Sstever@eecs.umich.edu
5024056Sstever@eecs.umich.edu        %(fp_enable_check)s;
5034056Sstever@eecs.umich.edu        %(op_decl)s;
5044056Sstever@eecs.umich.edu        %(op_rd)s;
5054056Sstever@eecs.umich.edu        %(ea_code)s;
5064056Sstever@eecs.umich.edu
5074056Sstever@eecs.umich.edu        if (fault == NoFault) {
5084056Sstever@eecs.umich.edu            %(memacc_code)s;
5094056Sstever@eecs.umich.edu        }
5104056Sstever@eecs.umich.edu
5114056Sstever@eecs.umich.edu        if (fault == NoFault) {
5124056Sstever@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5134675Sksewell@umich.edu                              memAccessFlags, NULL);
5144056Sstever@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
5154056Sstever@eecs.umich.edu        }
5164056Sstever@eecs.umich.edu
5174056Sstever@eecs.umich.edu        if (fault == NoFault) {
5184056Sstever@eecs.umich.edu            %(postacc_code)s;
5194056Sstever@eecs.umich.edu        }
5204056Sstever@eecs.umich.edu
5214056Sstever@eecs.umich.edu        if (fault == NoFault) {
5224056Sstever@eecs.umich.edu            %(op_wb)s;
5234056Sstever@eecs.umich.edu        }
5244056Sstever@eecs.umich.edu
5254056Sstever@eecs.umich.edu        return fault;
5264056Sstever@eecs.umich.edu    }
5274056Sstever@eecs.umich.edu}};
5284056Sstever@eecs.umich.edu
5295222Sksewell@umich.edu
5305222Sksewell@umich.edudef template StoreFPExecute {{
5315222Sksewell@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5325222Sksewell@umich.edu                                  Trace::InstRecord *traceData) const
5335222Sksewell@umich.edu    {
5345222Sksewell@umich.edu        Addr EA;
5355222Sksewell@umich.edu        Fault fault = NoFault;
5365222Sksewell@umich.edu
5375222Sksewell@umich.edu        %(fp_enable_check)s;
5385222Sksewell@umich.edu        if(fault != NoFault)
5395222Sksewell@umich.edu          return fault;
5405222Sksewell@umich.edu        %(op_decl)s;
5415222Sksewell@umich.edu        %(op_rd)s;
5425222Sksewell@umich.edu        %(ea_code)s;
5435222Sksewell@umich.edu
5445222Sksewell@umich.edu        if (fault == NoFault) {
5455222Sksewell@umich.edu            %(memacc_code)s;
5465222Sksewell@umich.edu        }
5475222Sksewell@umich.edu
5485222Sksewell@umich.edu        if (fault == NoFault) {
5495222Sksewell@umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5505222Sksewell@umich.edu                              memAccessFlags, NULL);
5515222Sksewell@umich.edu            if (traceData) { traceData->setData(Mem); }
5525222Sksewell@umich.edu        }
5535222Sksewell@umich.edu
5545222Sksewell@umich.edu        if (fault == NoFault) {
5555222Sksewell@umich.edu            %(postacc_code)s;
5565222Sksewell@umich.edu        }
5575222Sksewell@umich.edu
5585222Sksewell@umich.edu        if (fault == NoFault) {
5595222Sksewell@umich.edu            %(op_wb)s;
5605222Sksewell@umich.edu        }
5615222Sksewell@umich.edu
5625222Sksewell@umich.edu        return fault;
5635222Sksewell@umich.edu    }
5645222Sksewell@umich.edu}};
5655222Sksewell@umich.edu
5664056Sstever@eecs.umich.edudef template StoreCondExecute {{
5674056Sstever@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
5684056Sstever@eecs.umich.edu                                  Trace::InstRecord *traceData) const
5694056Sstever@eecs.umich.edu    {
5704056Sstever@eecs.umich.edu        Addr EA;
5714056Sstever@eecs.umich.edu        Fault fault = NoFault;
5722124SN/A        uint64_t write_result = 0;
5732124SN/A
5742124SN/A        %(fp_enable_check)s;
5752124SN/A        %(op_decl)s;
5762124SN/A        %(op_rd)s;
5772124SN/A        %(ea_code)s;
5782124SN/A
5792124SN/A        if (fault == NoFault) {
5802124SN/A            %(memacc_code)s;
5812124SN/A        }
5822124SN/A
5832124SN/A        if (fault == NoFault) {
5842124SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
5852124SN/A                              memAccessFlags, &write_result);
5862124SN/A            if (traceData) { traceData->setData(Mem); }
5872124SN/A        }
5882124SN/A
5892124SN/A        if (fault == NoFault) {
5902124SN/A            %(postacc_code)s;
5912124SN/A        }
5922124SN/A
5932124SN/A        if (fault == NoFault) {
5942124SN/A            %(op_wb)s;
5952124SN/A        }
5962124SN/A
5972124SN/A        return fault;
5982124SN/A    }
5992124SN/A}};
6002124SN/A
6012124SN/Adef template StoreInitiateAcc {{
6022132SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
6032124SN/A                                      Trace::InstRecord *traceData) const
6042124SN/A    {
6052239SN/A        Addr EA;
6062132SN/A        Fault fault = NoFault;
6072239SN/A
6082239SN/A        %(fp_enable_check)s;
6092506SN/A        %(op_decl)s;
6102239SN/A        %(op_rd)s;
6112239SN/A        %(ea_code)s;
6122239SN/A
6132239SN/A        if (fault == NoFault) {
6142239SN/A            %(memacc_code)s;
6152239SN/A        }
6162239SN/A
6172239SN/A        if (fault == NoFault) {
6182239SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
6192935Sksewell@umich.edu                              memAccessFlags, NULL);
6202239SN/A            if (traceData) { traceData->setData(Mem); }
6212239SN/A        }
6222239SN/A
6232124SN/A        return fault;
6242124SN/A    }
6252124SN/A}};
6262124SN/A
6272124SN/A
6282124SN/Adef template StoreCompleteAcc {{
6294661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
6302124SN/A                                      %(CPU_exec_context)s *xc,
6312124SN/A                                      Trace::InstRecord *traceData) const
6322124SN/A    {
6332132SN/A        Fault fault = NoFault;
6342239SN/A
6352239SN/A        %(fp_enable_check)s;
6362239SN/A        %(op_dest_decl)s;
6372239SN/A
6382935Sksewell@umich.edu        if (fault == NoFault) {
6392935Sksewell@umich.edu            %(postacc_code)s;
6402935Sksewell@umich.edu        }
6412935Sksewell@umich.edu
6422935Sksewell@umich.edu        if (fault == NoFault) {
6432935Sksewell@umich.edu            %(op_wb)s;
6444661Sksewell@umich.edu
6455222Sksewell@umich.edu            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
6465222Sksewell@umich.edu        }
6475222Sksewell@umich.edu
6485222Sksewell@umich.edu        return fault;
6495222Sksewell@umich.edu    }
6505222Sksewell@umich.edu}};
6515222Sksewell@umich.edu
6525222Sksewell@umich.edu
6535222Sksewell@umich.edudef template StoreCompleteAcc {{
6545222Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
6555222Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
6565222Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
6575222Sksewell@umich.edu    {
6585222Sksewell@umich.edu        Fault fault = NoFault;
6595222Sksewell@umich.edu
6605222Sksewell@umich.edu        %(op_dest_decl)s;
6615222Sksewell@umich.edu
6625222Sksewell@umich.edu        if (fault == NoFault) {
6635222Sksewell@umich.edu            %(postacc_code)s;
6645222Sksewell@umich.edu        }
6655222Sksewell@umich.edu
6665222Sksewell@umich.edu        if (fault == NoFault) {
6675222Sksewell@umich.edu            %(op_wb)s;
6685222Sksewell@umich.edu
6695222Sksewell@umich.edu            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
6702935Sksewell@umich.edu        }
6712935Sksewell@umich.edu
6722935Sksewell@umich.edu        return fault;
6732935Sksewell@umich.edu    }
6742935Sksewell@umich.edu}};
6752935Sksewell@umich.edu
6762935Sksewell@umich.edudef template StoreCondCompleteAcc {{
6774661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
6782935Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
6792935Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
6802935Sksewell@umich.edu    {
6812935Sksewell@umich.edu        Fault fault = NoFault;
6822935Sksewell@umich.edu
6832935Sksewell@umich.edu        %(fp_enable_check)s;
6842935Sksewell@umich.edu        %(op_dest_decl)s;
6852935Sksewell@umich.edu
6864055Ssaidi@eecs.umich.edu        uint64_t write_result = pkt->req->getExtraData();
6872239SN/A
6882239SN/A        if (fault == NoFault) {
6892239SN/A            %(postacc_code)s;
6902239SN/A        }
6912239SN/A
6922239SN/A        if (fault == NoFault) {
6932239SN/A            %(op_wb)s;
6942239SN/A        }
6952239SN/A
6962124SN/A        return fault;
6972124SN/A    }
6982124SN/A}};
6992124SN/A
7002686Sksewell@umich.edu
7012686Sksewell@umich.edudef template MiscMemAccExecute {{
7022686Sksewell@umich.edu    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
7032686Sksewell@umich.edu                                          Trace::InstRecord *traceData) const
7042686Sksewell@umich.edu    {
7052686Sksewell@umich.edu        Addr EA;
7062686Sksewell@umich.edu        Fault fault = NoFault;
7072686Sksewell@umich.edu
7082686Sksewell@umich.edu        %(fp_enable_check)s;
7092686Sksewell@umich.edu        %(op_decl)s;
7102686Sksewell@umich.edu        %(op_rd)s;
7112686Sksewell@umich.edu        EA = xc->getEA();
7122686Sksewell@umich.edu
7132686Sksewell@umich.edu        if (fault == NoFault) {
7143953Sstever@eecs.umich.edu            %(memacc_code)s;
7152686Sksewell@umich.edu        }
7162686Sksewell@umich.edu
7172686Sksewell@umich.edu        return NoFault;
7182686Sksewell@umich.edu    }
7192686Sksewell@umich.edu}};
7202686Sksewell@umich.edu
7212686Sksewell@umich.edudef template MiscExecute {{
7222686Sksewell@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
7232686Sksewell@umich.edu                                  Trace::InstRecord *traceData) const
7242686Sksewell@umich.edu    {
7252686Sksewell@umich.edu        Addr EA;
7262686Sksewell@umich.edu        Fault fault = NoFault;
7272686Sksewell@umich.edu
7282686Sksewell@umich.edu        %(fp_enable_check)s;
7292686Sksewell@umich.edu        %(op_decl)s;
7302686Sksewell@umich.edu        %(op_rd)s;
7312686Sksewell@umich.edu        %(ea_code)s;
7322686Sksewell@umich.edu
7332686Sksewell@umich.edu        if (fault == NoFault) {
7342686Sksewell@umich.edu            %(memacc_code)s;
7352686Sksewell@umich.edu        }
7362686Sksewell@umich.edu
7372686Sksewell@umich.edu        return NoFault;
7382686Sksewell@umich.edu    }
7392686Sksewell@umich.edu}};
7402686Sksewell@umich.edu
7412686Sksewell@umich.edudef template MiscInitiateAcc {{
7422686Sksewell@umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
7432686Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
7442686Sksewell@umich.edu    {
7452686Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
7462686Sksewell@umich.edu        return NoFault;
7472686Sksewell@umich.edu    }
7482686Sksewell@umich.edu}};
7492686Sksewell@umich.edu
7502686Sksewell@umich.edu
7512686Sksewell@umich.edudef template MiscCompleteAcc {{
7524661Sksewell@umich.edu    Fault %(class_name)s::completeAcc(Packet *pkt,
7532686Sksewell@umich.edu                                      %(CPU_exec_context)s *xc,
7542686Sksewell@umich.edu                                      Trace::InstRecord *traceData) const
7552686Sksewell@umich.edu    {
7562686Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
7572686Sksewell@umich.edu
7582686Sksewell@umich.edu        return NoFault;
7592686Sksewell@umich.edu    }
7602686Sksewell@umich.edu}};
7612686Sksewell@umich.edu
7624661Sksewell@umich.edu
7634661Sksewell@umich.edudef template MiscMemAccSize {{
7644661Sksewell@umich.edu    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
7654661Sksewell@umich.edu    {
7664661Sksewell@umich.edu        panic("Misc instruction does not support split access method!");
7674661Sksewell@umich.edu        return 0;
7684661Sksewell@umich.edu    }
7694661Sksewell@umich.edu}};
7704661Sksewell@umich.edu
7712124SN/Adef format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
7722124SN/A                     mem_flags = [], inst_flags = []) {{
7732124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7742124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7752750Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
7762124SN/A                      exec_template_base = 'Load')
7772124SN/A}};
7782124SN/A
7795222Sksewell@umich.edu
7802124SN/Adef format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
7812124SN/A                     mem_flags = [], inst_flags = []) {{
7822124SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7832124SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7842124SN/A                      exec_template_base = 'Store')
7852124SN/A}};
7862124SN/A
7872686Sksewell@umich.edudef format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
7882573SN/A                     mem_flags = [], inst_flags = []) {{
7895222Sksewell@umich.edu    inst_flags += ['IsIndexed']
7902573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
7912573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
7922750Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
7932573SN/A                      exec_template_base = 'Load')
7942573SN/A}};
7952573SN/A
7962686Sksewell@umich.edudef format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
7972573SN/A                     mem_flags = [], inst_flags = []) {{
7985222Sksewell@umich.edu    inst_flags += ['IsIndexed']
7992573SN/A    (header_output, decoder_output, decode_block, exec_output) = \
8002573SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8012573SN/A                      exec_template_base = 'Store')
8022573SN/A}};
8032573SN/A
8045222Sksewell@umich.edudef format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
8055222Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8065222Sksewell@umich.edu    inst_flags += ['IsIndexed', 'IsFloating']
8075222Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8085222Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8095222Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
8105222Sksewell@umich.edu                      exec_template_base = 'Load')
8115222Sksewell@umich.edu}};
8125222Sksewell@umich.edu
8135222Sksewell@umich.edudef format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
8145222Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8155222Sksewell@umich.edu    inst_flags += ['IsIndexed', 'IsFloating']
8165222Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8175222Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8185222Sksewell@umich.edu                      exec_template_base = 'Store')
8195222Sksewell@umich.edu}};
8205222Sksewell@umich.edu
8215222Sksewell@umich.edu
8222686Sksewell@umich.edudef format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
8232686Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8242686Sksewell@umich.edu    decl_code = 'uint32_t mem_word = Mem.uw;\n'
8252686Sksewell@umich.edu    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
8262686Sksewell@umich.edu    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
8272686Sksewell@umich.edu    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
8282686Sksewell@umich.edu    decl_code += '\tbyte_offset ^= 3;\n'
8292686Sksewell@umich.edu    decl_code += '#endif\n'
8302573SN/A
8312686Sksewell@umich.edu    memacc_code = decl_code + memacc_code
8322686Sksewell@umich.edu
8332686Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8342686Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8352750Sksewell@umich.edu                      decode_template = ImmNopCheckDecode,
8362686Sksewell@umich.edu                      exec_template_base = 'Load')
8372686Sksewell@umich.edu}};
8382686Sksewell@umich.edu
8392686Sksewell@umich.edudef format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
8402686Sksewell@umich.edu                     mem_flags = [], inst_flags = []) {{
8412686Sksewell@umich.edu    decl_code = 'uint32_t mem_word = 0;\n'
8422686Sksewell@umich.edu    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
8432686Sksewell@umich.edu    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
8442686Sksewell@umich.edu    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
8452686Sksewell@umich.edu    decl_code += '\tbyte_offset ^= 3;\n'
8462686Sksewell@umich.edu    decl_code += '#endif\n'
8472686Sksewell@umich.edu    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
8484661Sksewell@umich.edu    #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
8492686Sksewell@umich.edu    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
8502686Sksewell@umich.edu
8512686Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8522686Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8532686Sksewell@umich.edu                      exec_template_base = 'Store')
8542686Sksewell@umich.edu}};
8552686Sksewell@umich.edu
8562686Sksewell@umich.edudef format Prefetch(ea_code = {{ EA = Rs + disp; }},
8572686Sksewell@umich.edu                          mem_flags = [], pf_flags = [], inst_flags = []) {{
8582686Sksewell@umich.edu    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
8592686Sksewell@umich.edu    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
8602686Sksewell@umich.edu                                  'IsDataPrefetch', 'MemReadOp']
8612686Sksewell@umich.edu
8622686Sksewell@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
8632686Sksewell@umich.edu        LoadStoreBase(name, Name, ea_code,
8642686Sksewell@umich.edu                      'xc->prefetch(EA, memAccessFlags);',
8652686Sksewell@umich.edu                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
8662686Sksewell@umich.edu
8672686Sksewell@umich.edu}};
8682686Sksewell@umich.edu
8692686Sksewell@umich.edudef format StoreCond(memacc_code, postacc_code,
8702686Sksewell@umich.edu                     ea_code = {{ EA = Rs + disp; }},
8712495SN/A                     mem_flags = [], inst_flags = []) {{
8722495SN/A    (header_output, decoder_output, decode_block, exec_output) = \
8732495SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
8742935Sksewell@umich.edu                      postacc_code, exec_template_base = 'StoreCond')
8752495SN/A}};
876