mem.isa revision 2124
12810SN/A// -*- mode:c++ -*-
28856Sandreas.hansson@arm.com
38856Sandreas.hansson@arm.com// Copyright (c) 2003-2005 The Regents of The University of Michigan
48856Sandreas.hansson@arm.com// All rights reserved.
58856Sandreas.hansson@arm.com//
68856Sandreas.hansson@arm.com// Redistribution and use in source and binary forms, with or without
78856Sandreas.hansson@arm.com// modification, are permitted provided that the following conditions are
88856Sandreas.hansson@arm.com// met: redistributions of source code must retain the above copyright
98856Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer;
108856Sandreas.hansson@arm.com// redistributions in binary form must reproduce the above copyright
118856Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer in the
128856Sandreas.hansson@arm.com// documentation and/or other materials provided with the distribution;
138856Sandreas.hansson@arm.com// neither the name of the copyright holders nor the names of its
142810SN/A// contributors may be used to endorse or promote products derived from
152810SN/A// this software without specific prior written permission.
162810SN/A//
172810SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182810SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192810SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202810SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212810SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222810SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232810SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242810SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252810SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262810SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272810SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282810SN/A
292810SN/Aoutput header {{
302810SN/A    /**
312810SN/A     * Base class for general Alpha memory-format instructions.
322810SN/A     */
332810SN/A    class Memory : public AlphaStaticInst
342810SN/A    {
352810SN/A      protected:
362810SN/A
372810SN/A        /// Memory request flags.  See mem_req_base.hh.
382810SN/A        unsigned memAccessFlags;
392810SN/A        /// Pointer to EAComp object.
402810SN/A        const StaticInstPtr eaCompPtr;
412810SN/A        /// Pointer to MemAcc object.
422810SN/A        const StaticInstPtr memAccPtr;
432810SN/A
442810SN/A        /// Constructor
452810SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
462810SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
472810SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
483348SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
493348SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
508232Snate@binkert.org        {
519152Satgutier@umich.edu        }
525338Sstever@gmail.com
535338Sstever@gmail.com        std::string
548786Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
552810SN/A
562810SN/A      public:
572810SN/A
588856Sandreas.hansson@arm.com        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
598856Sandreas.hansson@arm.com        const StaticInstPtr &memAccInst() const { return memAccPtr; }
608856Sandreas.hansson@arm.com    };
618922Swilliam.wang@arm.com
628914Sandreas.hansson@arm.com    /**
638856Sandreas.hansson@arm.com     * Base class for memory-format instructions using a 32-bit
648856Sandreas.hansson@arm.com     * displacement (i.e. most of them).
654475SN/A     */
665034SN/A    class MemoryDisp32 : public Memory
675034SN/A    {
685314SN/A      protected:
695314SN/A        /// Displacement for EA calculation (signed).
704628SN/A        int32_t disp;
715034SN/A
725034SN/A        /// Constructor.
735034SN/A        MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass,
746122SSteve.Reinhardt@amd.com                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
758134SAli.Saidi@ARM.com                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
764626SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
774626SN/A              disp(MEMDISP)
785034SN/A        {
796122SSteve.Reinhardt@amd.com        }
808883SAli.Saidi@ARM.com    };
818833Sdam.sunwoo@arm.com
824458SN/A
832810SN/A    /**
842810SN/A     * Base class for a few miscellaneous memory-format insts
853013SN/A     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
868856Sandreas.hansson@arm.com     * None of these instructions has a destination register either.
872810SN/A     */
883013SN/A    class MemoryNoDisp : public Memory
898856Sandreas.hansson@arm.com    {
902810SN/A      protected:
912810SN/A        /// Constructor
922810SN/A        MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass,
932810SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
948856Sandreas.hansson@arm.com                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
952810SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
963013SN/A        {
978856Sandreas.hansson@arm.com        }
983013SN/A
998856Sandreas.hansson@arm.com        std::string
1008856Sandreas.hansson@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1012897SN/A    };
1024666SN/A}};
1038922Swilliam.wang@arm.com
1042897SN/A
1052810SN/Aoutput decoder {{
1062810SN/A    std::string
1072844SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1082810SN/A    {
1092858SN/A        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1102858SN/A                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1118856Sandreas.hansson@arm.com    }
1128922Swilliam.wang@arm.com
1138711Sandreas.hansson@arm.com    std::string
1142858SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1152858SN/A    {
1168922Swilliam.wang@arm.com        return csprintf("%-10s (r%d)", mnemonic, RB);
1178922Swilliam.wang@arm.com    }
1188922Swilliam.wang@arm.com}};
1198922Swilliam.wang@arm.com
1208922Swilliam.wang@arm.comdef format LoadAddress(code) {{
1218922Swilliam.wang@arm.com    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
1228922Swilliam.wang@arm.com    header_output = BasicDeclare.subst(iop)
1238922Swilliam.wang@arm.com    decoder_output = BasicConstructor.subst(iop)
1248922Swilliam.wang@arm.com    decode_block = BasicDecode.subst(iop)
1258922Swilliam.wang@arm.com    exec_output = BasicExecute.subst(iop)
1268922Swilliam.wang@arm.com}};
1278922Swilliam.wang@arm.com
1288922Swilliam.wang@arm.com
1298922Swilliam.wang@arm.comdef template LoadStoreDeclare {{
1308922Swilliam.wang@arm.com    /**
1318922Swilliam.wang@arm.com     * Static instruction class for "%(mnemonic)s".
1328922Swilliam.wang@arm.com     */
1338922Swilliam.wang@arm.com    class %(class_name)s : public %(base_class)s
1348922Swilliam.wang@arm.com    {
1354628SN/A      protected:
1362858SN/A
1372810SN/A        /**
1382810SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
1392810SN/A         */
1402810SN/A        class EAComp : public %(base_class)s
1412810SN/A        {
1424022SN/A          public:
1434022SN/A            /// Constructor
1444022SN/A            EAComp(MachInst machInst);
1452810SN/A
1462810SN/A            %(BasicExecDeclare)s
1478833Sdam.sunwoo@arm.com        };
1482810SN/A
1492810SN/A        /**
1502810SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
1512810SN/A         */
1528833Sdam.sunwoo@arm.com        class MemAcc : public %(base_class)s
1538833Sdam.sunwoo@arm.com        {
1548833Sdam.sunwoo@arm.com          public:
1552810SN/A            /// Constructor
1562810SN/A            MemAcc(MachInst machInst);
1574871SN/A
1584871SN/A            %(BasicExecDeclare)s
1594871SN/A        };
1604871SN/A
1614871SN/A      public:
1624871SN/A
1634871SN/A        /// Constructor.
1644871SN/A        %(class_name)s(MachInst machInst);
1654871SN/A
1664871SN/A        %(BasicExecDeclare)s
1672810SN/A
1682810SN/A        %(InitiateAccDeclare)s
1692810SN/A
1708833Sdam.sunwoo@arm.com        %(CompleteAccDeclare)s
1712810SN/A    };
1724871SN/A}};
1738833Sdam.sunwoo@arm.com
1748833Sdam.sunwoo@arm.com
1758833Sdam.sunwoo@arm.comdef template InitiateAccDeclare {{
1762810SN/A    Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1772810SN/A}};
1782810SN/A
1792810SN/A
1808833Sdam.sunwoo@arm.comdef template CompleteAccDeclare {{
1812810SN/A    Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
1824871SN/A}};
1838833Sdam.sunwoo@arm.com
1848833Sdam.sunwoo@arm.com
1858833Sdam.sunwoo@arm.comdef template LoadStoreConstructor {{
1862810SN/A    /** TODO: change op_class to AddrGenOp or something (requires
1872810SN/A     * creating new member of OpClass enum in op_class.hh, updating
1884022SN/A     * config files, etc.). */
1894022SN/A    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1904022SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
1912810SN/A    {
1922810SN/A        %(ea_constructor)s;
1938833Sdam.sunwoo@arm.com    }
1942810SN/A
1952810SN/A    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
1962810SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
1972810SN/A    {
1988833Sdam.sunwoo@arm.com        %(memacc_constructor)s;
1998833Sdam.sunwoo@arm.com    }
2008833Sdam.sunwoo@arm.com
2012810SN/A    inline %(class_name)s::%(class_name)s(MachInst machInst)
2022810SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
2032810SN/A                          new EAComp(machInst), new MemAcc(machInst))
2042810SN/A    {
2052810SN/A        %(constructor)s;
2068833Sdam.sunwoo@arm.com    }
2072810SN/A}};
2084871SN/A
2098833Sdam.sunwoo@arm.com
2108833Sdam.sunwoo@arm.comdef template EACompExecute {{
2118833Sdam.sunwoo@arm.com    Fault *
2122810SN/A    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
2132810SN/A                                   Trace::InstRecord *traceData) const
2142810SN/A    {
2152810SN/A        Addr EA;
2168833Sdam.sunwoo@arm.com        Fault * fault = NoFault;
2172810SN/A
2184871SN/A        %(fp_enable_check)s;
2198833Sdam.sunwoo@arm.com        %(op_decl)s;
2208833Sdam.sunwoo@arm.com        %(op_rd)s;
2218833Sdam.sunwoo@arm.com        %(code)s;
2222810SN/A
2232810SN/A        if (fault == NoFault) {
2244022SN/A            %(op_wb)s;
2254022SN/A            xc->setEA(EA);
2264022SN/A        }
2272810SN/A
2282810SN/A        return fault;
2298833Sdam.sunwoo@arm.com    }
2302810SN/A}};
2312810SN/A
2322810SN/Adef template LoadMemAccExecute {{
2332810SN/A    Fault *
2348833Sdam.sunwoo@arm.com    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2358833Sdam.sunwoo@arm.com                                   Trace::InstRecord *traceData) const
2368833Sdam.sunwoo@arm.com    {
2372810SN/A        Addr EA;
2382810SN/A        Fault * fault = NoFault;
2392810SN/A
2402810SN/A        %(fp_enable_check)s;
2412810SN/A        %(op_decl)s;
2428833Sdam.sunwoo@arm.com        %(op_rd)s;
2432810SN/A        EA = xc->getEA();
2444871SN/A
2458833Sdam.sunwoo@arm.com        if (fault == NoFault) {
2468833Sdam.sunwoo@arm.com            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2478833Sdam.sunwoo@arm.com            %(code)s;
2482810SN/A        }
2492810SN/A
2502810SN/A        if (fault == NoFault) {
2512810SN/A            %(op_wb)s;
2528833Sdam.sunwoo@arm.com        }
2532810SN/A
2544871SN/A        return fault;
2558833Sdam.sunwoo@arm.com    }
2568833Sdam.sunwoo@arm.com}};
2578833Sdam.sunwoo@arm.com
2582810SN/A
2592810SN/Adef template LoadExecute {{
2604022SN/A    Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
2614022SN/A                                  Trace::InstRecord *traceData) const
2624022SN/A    {
2632810SN/A        Addr EA;
2642810SN/A        Fault * fault = NoFault;
2652810SN/A
2662810SN/A        %(fp_enable_check)s;
2672810SN/A        %(op_decl)s;
2682810SN/A        %(op_rd)s;
2698833Sdam.sunwoo@arm.com        %(ea_code)s;
2702810SN/A
2718833Sdam.sunwoo@arm.com        if (fault == NoFault) {
2728833Sdam.sunwoo@arm.com            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2738833Sdam.sunwoo@arm.com            %(memacc_code)s;
2742810SN/A        }
2752810SN/A
2762810SN/A        if (fault == NoFault) {
2772810SN/A            %(op_wb)s;
2782810SN/A        }
2798833Sdam.sunwoo@arm.com
2802810SN/A        return fault;
2812810SN/A    }
2828833Sdam.sunwoo@arm.com}};
2838833Sdam.sunwoo@arm.com
2848833Sdam.sunwoo@arm.com
2852810SN/Adef template LoadInitiateAcc {{
2862810SN/A    Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2872810SN/A                                      Trace::InstRecord *traceData) const
2882810SN/A    {
2898833Sdam.sunwoo@arm.com        Addr EA;
2902810SN/A        Fault * fault = NoFault;
2912810SN/A
2928833Sdam.sunwoo@arm.com        %(fp_enable_check)s;
2938833Sdam.sunwoo@arm.com        %(op_src_decl)s;
2948833Sdam.sunwoo@arm.com        %(op_rd)s;
2952810SN/A        %(ea_code)s;
2962810SN/A
2974022SN/A        if (fault == NoFault) {
2984022SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2994022SN/A        }
3002810SN/A
3012810SN/A        return fault;
3022810SN/A    }
3032810SN/A}};
3042810SN/A
3052810SN/A
3068833Sdam.sunwoo@arm.comdef template LoadCompleteAcc {{
3072810SN/A    Fault * %(class_name)s::completeAcc(uint8_t *data,
3088833Sdam.sunwoo@arm.com                                      %(CPU_exec_context)s *xc,
3098833Sdam.sunwoo@arm.com                                      Trace::InstRecord *traceData) const
3108833Sdam.sunwoo@arm.com    {
3112810SN/A        Fault * fault = NoFault;
3122810SN/A
3132810SN/A        %(fp_enable_check)s;
3142810SN/A        %(op_src_decl)s;
3152810SN/A        %(op_dest_decl)s;
3168833Sdam.sunwoo@arm.com
3172810SN/A        memcpy(&Mem, data, sizeof(Mem));
3182810SN/A
3198833Sdam.sunwoo@arm.com        if (fault == NoFault) {
3208833Sdam.sunwoo@arm.com            %(memacc_code)s;
3218833Sdam.sunwoo@arm.com        }
3222810SN/A
3232810SN/A        if (fault == NoFault) {
3242810SN/A            %(op_wb)s;
3252810SN/A        }
3268833Sdam.sunwoo@arm.com
3272810SN/A        return fault;
3282810SN/A    }
3298833Sdam.sunwoo@arm.com}};
3308833Sdam.sunwoo@arm.com
3318833Sdam.sunwoo@arm.com
3322810SN/Adef template StoreMemAccExecute {{
3332810SN/A    Fault *
3344022SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3354022SN/A                                   Trace::InstRecord *traceData) const
3364022SN/A    {
3372810SN/A        Addr EA;
3382810SN/A        Fault * fault = NoFault;
3392810SN/A        uint64_t write_result = 0;
3402810SN/A
3412810SN/A        %(fp_enable_check)s;
3422810SN/A        %(op_decl)s;
3432810SN/A        %(op_rd)s;
3442810SN/A        EA = xc->getEA();
3458833Sdam.sunwoo@arm.com
3468833Sdam.sunwoo@arm.com        if (fault == NoFault) {
3478833Sdam.sunwoo@arm.com            %(code)s;
3488833Sdam.sunwoo@arm.com        }
3492810SN/A
3502810SN/A        if (fault == NoFault) {
3512810SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3522810SN/A                              memAccessFlags, &write_result);
3532810SN/A            if (traceData) { traceData->setData(Mem); }
3548833Sdam.sunwoo@arm.com        }
3552810SN/A
3562810SN/A        if (fault == NoFault) {
3578833Sdam.sunwoo@arm.com            %(postacc_code)s;
3588833Sdam.sunwoo@arm.com        }
3598833Sdam.sunwoo@arm.com
3602810SN/A        if (fault == NoFault) {
3612810SN/A            %(op_wb)s;
3622810SN/A        }
3632810SN/A
3648833Sdam.sunwoo@arm.com        return fault;
3652810SN/A    }
3662810SN/A}};
3678833Sdam.sunwoo@arm.com
3688833Sdam.sunwoo@arm.com
3698833Sdam.sunwoo@arm.comdef template StoreExecute {{
3702810SN/A    Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
3712810SN/A                                  Trace::InstRecord *traceData) const
3722810SN/A    {
3732810SN/A        Addr EA;
3742810SN/A        Fault * fault = NoFault;
3752810SN/A        uint64_t write_result = 0;
3762810SN/A
3772810SN/A        %(fp_enable_check)s;
3782810SN/A        %(op_decl)s;
3792810SN/A        %(op_rd)s;
3802810SN/A        %(ea_code)s;
3812810SN/A
3822810SN/A        if (fault == NoFault) {
3832810SN/A            %(memacc_code)s;
3842810SN/A        }
3852810SN/A
3862810SN/A        if (fault == NoFault) {
3872810SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3882810SN/A                              memAccessFlags, &write_result);
3892810SN/A            if (traceData) { traceData->setData(Mem); }
3902810SN/A        }
3912810SN/A
3922810SN/A        if (fault == NoFault) {
3932810SN/A            %(postacc_code)s;
3942810SN/A        }
3952810SN/A
3962810SN/A        if (fault == NoFault) {
3972810SN/A            %(op_wb)s;
3982810SN/A        }
3992810SN/A
4002810SN/A        return fault;
4012810SN/A    }
4022810SN/A}};
4032810SN/A
4042810SN/Adef template StoreInitiateAcc {{
4052810SN/A    Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4062826SN/A                                      Trace::InstRecord *traceData) const
4074626SN/A    {
4088833Sdam.sunwoo@arm.com        Addr EA;
4094626SN/A        Fault * fault = NoFault;
4104626SN/A        uint64_t write_result = 0;
4118833Sdam.sunwoo@arm.com
4124626SN/A        %(fp_enable_check)s;
4138833Sdam.sunwoo@arm.com        %(op_src_decl)s;
4148833Sdam.sunwoo@arm.com        %(op_dest_decl)s;
4158833Sdam.sunwoo@arm.com        %(op_rd)s;
4164626SN/A        %(ea_code)s;
4174626SN/A
4184626SN/A        if (fault == NoFault) {
4194626SN/A            %(memacc_code)s;
4204626SN/A        }
4214626SN/A
4224626SN/A        if (fault == NoFault) {
4234626SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4248833Sdam.sunwoo@arm.com                              memAccessFlags, &write_result);
4254626SN/A            if (traceData) { traceData->setData(Mem); }
4264626SN/A        }
4274626SN/A
4284626SN/A        return fault;
4298833Sdam.sunwoo@arm.com    }
4308833Sdam.sunwoo@arm.com}};
4318833Sdam.sunwoo@arm.com
4324626SN/A
4334626SN/Adef template StoreCompleteAcc {{
4344626SN/A    Fault * %(class_name)s::completeAcc(uint8_t *data,
4354626SN/A                                      %(CPU_exec_context)s *xc,
4364626SN/A                                      Trace::InstRecord *traceData) const
4378833Sdam.sunwoo@arm.com    {
4384626SN/A        Fault * fault = NoFault;
4394871SN/A        uint64_t write_result = 0;
4408833Sdam.sunwoo@arm.com
4418833Sdam.sunwoo@arm.com        %(fp_enable_check)s;
4428833Sdam.sunwoo@arm.com        %(op_dest_decl)s;
4434626SN/A
4444626SN/A        memcpy(&write_result, data, sizeof(write_result));
4454626SN/A
4464626SN/A        if (fault == NoFault) {
4478833Sdam.sunwoo@arm.com            %(postacc_code)s;
4484626SN/A        }
4494871SN/A
4508833Sdam.sunwoo@arm.com        if (fault == NoFault) {
4518833Sdam.sunwoo@arm.com            %(op_wb)s;
4528833Sdam.sunwoo@arm.com        }
4534626SN/A
4544626SN/A        return fault;
4554626SN/A    }
4564626SN/A}};
4574626SN/A
4584626SN/A
4594626SN/Adef template MiscMemAccExecute {{
4608833Sdam.sunwoo@arm.com    Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4614626SN/A                                          Trace::InstRecord *traceData) const
4624626SN/A    {
4634626SN/A        Addr EA;
4644626SN/A        Fault * fault = NoFault;
4658833Sdam.sunwoo@arm.com
4668833Sdam.sunwoo@arm.com        %(fp_enable_check)s;
4678833Sdam.sunwoo@arm.com        %(op_decl)s;
4684626SN/A        %(op_rd)s;
4694626SN/A        EA = xc->getEA();
4704626SN/A
4714626SN/A        if (fault == NoFault) {
4724626SN/A            %(code)s;
4738833Sdam.sunwoo@arm.com        }
4744626SN/A
4754871SN/A        return NoFault;
4768833Sdam.sunwoo@arm.com    }
4778833Sdam.sunwoo@arm.com}};
4788833Sdam.sunwoo@arm.com
4794626SN/Adef template MiscExecute {{
4804626SN/A    Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
4814626SN/A                                  Trace::InstRecord *traceData) const
4824626SN/A    {
4838833Sdam.sunwoo@arm.com        Addr EA;
4844626SN/A        Fault * fault = NoFault;
4854871SN/A
4868833Sdam.sunwoo@arm.com        %(fp_enable_check)s;
4878833Sdam.sunwoo@arm.com        %(op_decl)s;
4888833Sdam.sunwoo@arm.com        %(op_rd)s;
4894626SN/A        %(ea_code)s;
4904626SN/A
4914626SN/A        if (fault == NoFault) {
4924626SN/A            %(memacc_code)s;
4934626SN/A        }
4944626SN/A
4954626SN/A        return NoFault;
4968833Sdam.sunwoo@arm.com    }
4974626SN/A}};
4984626SN/A
4994626SN/Adef template MiscInitiateAcc {{
5004626SN/A    Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5018833Sdam.sunwoo@arm.com                                      Trace::InstRecord *traceData) const
5028833Sdam.sunwoo@arm.com    {
5038833Sdam.sunwoo@arm.com        panic("Misc instruction does not support split access method!");
5044626SN/A        return NoFault;
5054626SN/A    }
5064626SN/A}};
5074626SN/A
5084626SN/A
5098833Sdam.sunwoo@arm.comdef template MiscCompleteAcc {{
5104626SN/A    Fault * %(class_name)s::completeAcc(uint8_t *data,
5114871SN/A                                      %(CPU_exec_context)s *xc,
5128833Sdam.sunwoo@arm.com                                      Trace::InstRecord *traceData) const
5138833Sdam.sunwoo@arm.com    {
5148833Sdam.sunwoo@arm.com        panic("Misc instruction does not support split access method!");
5154626SN/A
5164626SN/A        return NoFault;
5174626SN/A    }
5184626SN/A}};
5198833Sdam.sunwoo@arm.com
5204626SN/A// load instructions use Ra as dest, so check for
5214871SN/A// Ra == 31 to detect nops
5224871SN/Adef template LoadNopCheckDecode {{
5238833Sdam.sunwoo@arm.com {
5248833Sdam.sunwoo@arm.com     AlphaStaticInst *i = new %(class_name)s(machInst);
5258833Sdam.sunwoo@arm.com     if (RA == 31) {
5264626SN/A         i = makeNop(i);
5274626SN/A     }
5284626SN/A     return i;
5294626SN/A }
5304626SN/A}};
5314626SN/A
5324626SN/A
5338833Sdam.sunwoo@arm.com// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
5344626SN/Adef template LoadPrefetchCheckDecode {{
5354626SN/A {
5364626SN/A     if (RA != 31) {
5374626SN/A         return new %(class_name)s(machInst);
5388833Sdam.sunwoo@arm.com     }
5398833Sdam.sunwoo@arm.com     else {
5408833Sdam.sunwoo@arm.com         return new %(class_name)sPrefetch(machInst);
5414626SN/A     }
5424626SN/A }
5434626SN/A}};
5444626SN/A
5454626SN/A
5468833Sdam.sunwoo@arm.comlet {{
5474626SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5484871SN/A                  postacc_code = '', base_class = 'MemoryDisp32',
5494871SN/A                  decode_template = BasicDecode, exec_template_base = ''):
5508833Sdam.sunwoo@arm.com    # Make sure flags are in lists (convert to lists if not).
5518833Sdam.sunwoo@arm.com    mem_flags = makeList(mem_flags)
5528833Sdam.sunwoo@arm.com    inst_flags = makeList(inst_flags)
5534626SN/A
5544626SN/A    # add hook to get effective addresses into execution trace output.
5554626SN/A    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5564626SN/A
5574626SN/A    # generate code block objects
5584626SN/A    ea_cblk = CodeBlock(ea_code)
5594626SN/A    memacc_cblk = CodeBlock(memacc_code)
5608833Sdam.sunwoo@arm.com    postacc_cblk = CodeBlock(postacc_code)
5614626SN/A
5624626SN/A    # Some CPU models execute the memory operation as an atomic unit,
5634626SN/A    # while others want to separate them into an effective address
5644626SN/A    # computation and a memory access operation.  As a result, we need
5658833Sdam.sunwoo@arm.com    # to generate three StaticInst objects.  Note that the latter two
5668833Sdam.sunwoo@arm.com    # are nested inside the larger "atomic" one.
5678833Sdam.sunwoo@arm.com
5684626SN/A    # generate InstObjParams for EAComp object
5694626SN/A    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
5704626SN/A
5714626SN/A    # generate InstObjParams for MemAcc object
5724626SN/A    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
5738833Sdam.sunwoo@arm.com    # in the split execution model, the MemAcc portion is responsible
5744626SN/A    # for the post-access code.
5754871SN/A    memacc_iop.postacc_code = postacc_cblk.code
5764871SN/A
5774871SN/A    # generate InstObjParams for InitiateAcc, CompleteAcc object
5788833Sdam.sunwoo@arm.com    # The code used depends on the template being used
5798833Sdam.sunwoo@arm.com    if (exec_template_base == 'Load'):
5808833Sdam.sunwoo@arm.com        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
5814626SN/A        completeacc_cblk = CodeBlock(memacc_code + postacc_code)
5824626SN/A    elif (exec_template_base == 'Store'):
5834626SN/A        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
5844626SN/A        completeacc_cblk = CodeBlock(postacc_code)
5854626SN/A    else:
5864626SN/A        initiateacc_cblk = ''
5874626SN/A        completeacc_cblk = ''
5884626SN/A
5894626SN/A    initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
5904626SN/A                                    inst_flags)
5914626SN/A
5924626SN/A    completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
5934626SN/A                                    inst_flags)
5944626SN/A
5954626SN/A    if (exec_template_base == 'Load'):
5964626SN/A        initiateacc_iop.ea_code = ea_cblk.code
5974626SN/A        initiateacc_iop.memacc_code = memacc_cblk.code
5984626SN/A        completeacc_iop.memacc_code = memacc_cblk.code
5994626SN/A        completeacc_iop.postacc_code = postacc_cblk.code
6004626SN/A    elif (exec_template_base == 'Store'):
6014626SN/A        initiateacc_iop.ea_code = ea_cblk.code
6024626SN/A        initiateacc_iop.memacc_code = memacc_cblk.code
6034626SN/A        completeacc_iop.postacc_code = postacc_cblk.code
6044626SN/A
6054626SN/A    # generate InstObjParams for unified execution
6064626SN/A    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
6074626SN/A    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
6084626SN/A
6094626SN/A    iop.ea_constructor = ea_cblk.constructor
6104626SN/A    iop.ea_code = ea_cblk.code
6114626SN/A    iop.memacc_constructor = memacc_cblk.constructor
6124626SN/A    iop.memacc_code = memacc_cblk.code
6134626SN/A    iop.postacc_code = postacc_cblk.code
6144626SN/A
6154626SN/A    if mem_flags:
6164626SN/A        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
6174626SN/A        iop.constructor += s
6184626SN/A        memacc_iop.constructor += s
6194626SN/A
6204626SN/A    # select templates
6214626SN/A    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
6224626SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
6234626SN/A    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
6244626SN/A    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
6254626SN/A
6268833Sdam.sunwoo@arm.com    # (header_output, decoder_output, decode_block, exec_output)
6278833Sdam.sunwoo@arm.com    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
6288833Sdam.sunwoo@arm.com            decode_template.subst(iop),
6298833Sdam.sunwoo@arm.com            EACompExecute.subst(ea_iop)
6304626SN/A            + memAccExecTemplate.subst(memacc_iop)
6314626SN/A            + fullExecTemplate.subst(iop)
6324626SN/A            + initiateAccTemplate.subst(initiateacc_iop)
6334626SN/A            + completeAccTemplate.subst(completeacc_iop))
6344626SN/A}};
6358833Sdam.sunwoo@arm.com
6364626SN/A
6374626SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
6388833Sdam.sunwoo@arm.com                     mem_flags = [], inst_flags = []) {{
6398833Sdam.sunwoo@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
6408833Sdam.sunwoo@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6414626SN/A                      decode_template = LoadNopCheckDecode,
6424626SN/A                      exec_template_base = 'Load')
6434626SN/A}};
6444626SN/A
6458833Sdam.sunwoo@arm.com
6464626SN/A// Note that the flags passed in apply only to the prefetch version
6474626SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
6488833Sdam.sunwoo@arm.com                          mem_flags = [], pf_flags = [], inst_flags = []) {{
6498833Sdam.sunwoo@arm.com    # declare the load instruction object and generate the decode block
6508833Sdam.sunwoo@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
6514626SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6524626SN/A                      decode_template = LoadPrefetchCheckDecode,
6534626SN/A                      exec_template_base = 'Load')
6544626SN/A
6554626SN/A    # Declare the prefetch instruction object.
6564626SN/A
6574626SN/A    # Make sure flag args are lists so we can mess with them.
6584626SN/A    mem_flags = makeList(mem_flags)
6594626SN/A    pf_flags = makeList(pf_flags)
6604626SN/A    inst_flags = makeList(inst_flags)
6614626SN/A
6624626SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
6634626SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
6648833Sdam.sunwoo@arm.com                                  'IsDataPrefetch', 'MemReadOp']
6658833Sdam.sunwoo@arm.com
6668833Sdam.sunwoo@arm.com    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
6678833Sdam.sunwoo@arm.com        LoadStoreBase(name, Name + 'Prefetch', ea_code,
6684626SN/A                      'xc->prefetch(EA, memAccessFlags);',
6694626SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
6704626SN/A
6714626SN/A    header_output += pf_header_output
6724626SN/A    decoder_output += pf_decoder_output
6738833Sdam.sunwoo@arm.com    exec_output += pf_exec_output
6744626SN/A}};
6754626SN/A
6768833Sdam.sunwoo@arm.com
6778833Sdam.sunwoo@arm.comdef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
6788833Sdam.sunwoo@arm.com                 mem_flags = [], inst_flags = []) {{
6794626SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6804626SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6814626SN/A                      exec_template_base = 'Store')
6824626SN/A}};
6838833Sdam.sunwoo@arm.com
6844626SN/A
6854626SN/Adef format StoreCond(memacc_code, postacc_code,
6868833Sdam.sunwoo@arm.com                     ea_code = {{ EA = Rb + disp; }},
6878833Sdam.sunwoo@arm.com                     mem_flags = [], inst_flags = []) {{
6888833Sdam.sunwoo@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
6894626SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6904626SN/A                      postacc_code, exec_template_base = 'Store')
6914626SN/A}};
6924626SN/A
6934626SN/A
6944626SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
6954626SN/Adef format MiscPrefetch(ea_code, memacc_code,
6964626SN/A                        mem_flags = [], inst_flags = []) {{
6974626SN/A    (header_output, decoder_output, decode_block, exec_output) = \
6984626SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
6994626SN/A                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
7004626SN/A}};
7014626SN/A
7028833Sdam.sunwoo@arm.com
7038833Sdam.sunwoo@arm.com