mem.isa revision 2495
12292SN/A// -*- mode:c++ -*-
213590Srekai.gonzalezalberquilla@arm.com
39444SAndreas.Sandberg@ARM.com// Copyright (c) 2003-2005 The Regents of The University of Michigan
49444SAndreas.Sandberg@ARM.com// All rights reserved.
59444SAndreas.Sandberg@ARM.com//
69444SAndreas.Sandberg@ARM.com// Redistribution and use in source and binary forms, with or without
79444SAndreas.Sandberg@ARM.com// modification, are permitted provided that the following conditions are
89444SAndreas.Sandberg@ARM.com// met: redistributions of source code must retain the above copyright
99444SAndreas.Sandberg@ARM.com// notice, this list of conditions and the following disclaimer;
109444SAndreas.Sandberg@ARM.com// redistributions in binary form must reproduce the above copyright
119444SAndreas.Sandberg@ARM.com// notice, this list of conditions and the following disclaimer in the
129444SAndreas.Sandberg@ARM.com// documentation and/or other materials provided with the distribution;
139444SAndreas.Sandberg@ARM.com// neither the name of the copyright holders nor the names of its
142329SN/A// contributors may be used to endorse or promote products derived from
1510239Sbinhpham@cs.rutgers.edu// this software without specific prior written permission.
162292SN/A//
172292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192292SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202292SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212292SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242292SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262292SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272292SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282292SN/A
292292SN/Aoutput header {{
302292SN/A    /**
312292SN/A     * Base class for general Alpha memory-format instructions.
322292SN/A     */
332292SN/A    class Memory : public AlphaStaticInst
342292SN/A    {
352292SN/A      protected:
362292SN/A
372292SN/A        /// Memory request flags.  See mem_req_base.hh.
382292SN/A        unsigned memAccessFlags;
392292SN/A        /// Pointer to EAComp object.
402689Sktlim@umich.edu        const StaticInstPtr eaCompPtr;
412689Sktlim@umich.edu        /// Pointer to MemAcc object.
422689Sktlim@umich.edu        const StaticInstPtr memAccPtr;
432292SN/A
442292SN/A        /// Constructor
452292SN/A        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
462292SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
472292SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
482329SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
494395Ssaidi@eecs.umich.edu              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
502292SN/A        {
512292SN/A        }
522292SN/A
538591Sgblack@eecs.umich.edu        std::string
5414030Sgabor.dozsa@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
558506Sgblack@eecs.umich.edu
563326Sktlim@umich.edu      public:
578481Sgblack@eecs.umich.edu
586658Snate@binkert.org        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
592292SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
608230Snate@binkert.org    };
618232Snate@binkert.org
623348Sbinkertn@umich.edu    /**
632669Sktlim@umich.edu     * Base class for memory-format instructions using a 32-bit
642292SN/A     * displacement (i.e. most of them).
658737Skoansin.tan@gmail.com     */
6613590Srekai.gonzalezalberquilla@arm.com    class MemoryDisp32 : public Memory
675529Snate@binkert.org    {
682292SN/A      protected:
692329SN/A        /// Displacement for EA calculation (signed).
702329SN/A        int32_t disp;
712329SN/A
722329SN/A        /// Constructor.
732329SN/A        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
742329SN/A                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
752329SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
762329SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
772329SN/A              disp(MEMDISP)
782329SN/A        {
792292SN/A        }
802292SN/A    };
8113590Srekai.gonzalezalberquilla@arm.com
8213590Srekai.gonzalezalberquilla@arm.com
832292SN/A    /**
8414030Sgabor.dozsa@arm.com     * Base class for a few miscellaneous memory-format insts
8514030Sgabor.dozsa@arm.com     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
862733Sktlim@umich.edu     * None of these instructions has a destination register either.
872292SN/A     */
882292SN/A    class MemoryNoDisp : public Memory
892907Sktlim@umich.edu    {
902292SN/A      protected:
912292SN/A        /// Constructor
9213590Srekai.gonzalezalberquilla@arm.com        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
9313590Srekai.gonzalezalberquilla@arm.com                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
9413590Srekai.gonzalezalberquilla@arm.com                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
9513590Srekai.gonzalezalberquilla@arm.com            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
9613590Srekai.gonzalezalberquilla@arm.com        {
9713590Srekai.gonzalezalberquilla@arm.com        }
9813590Srekai.gonzalezalberquilla@arm.com
9913590Srekai.gonzalezalberquilla@arm.com        std::string
10013590Srekai.gonzalezalberquilla@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
10113590Srekai.gonzalezalberquilla@arm.com    };
10213590Srekai.gonzalezalberquilla@arm.com}};
10314030Sgabor.dozsa@arm.com
10413590Srekai.gonzalezalberquilla@arm.com
10513590Srekai.gonzalezalberquilla@arm.comoutput decoder {{
10613590Srekai.gonzalezalberquilla@arm.com    std::string
10713590Srekai.gonzalezalberquilla@arm.com    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
10813590Srekai.gonzalezalberquilla@arm.com    {
10913590Srekai.gonzalezalberquilla@arm.com        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
11013590Srekai.gonzalezalberquilla@arm.com                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
11113590Srekai.gonzalezalberquilla@arm.com    }
11213590Srekai.gonzalezalberquilla@arm.com
11313590Srekai.gonzalezalberquilla@arm.com    std::string
11413590Srekai.gonzalezalberquilla@arm.com    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
11513590Srekai.gonzalezalberquilla@arm.com    {
11613590Srekai.gonzalezalberquilla@arm.com        return csprintf("%-10s (r%d)", mnemonic, RB);
11713590Srekai.gonzalezalberquilla@arm.com    }
11813590Srekai.gonzalezalberquilla@arm.com}};
11913590Srekai.gonzalezalberquilla@arm.com
12013590Srekai.gonzalezalberquilla@arm.comdef format LoadAddress(code) {{
12113590Srekai.gonzalezalberquilla@arm.com    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
12213590Srekai.gonzalezalberquilla@arm.com    header_output = BasicDeclare.subst(iop)
12313590Srekai.gonzalezalberquilla@arm.com    decoder_output = BasicConstructor.subst(iop)
12413590Srekai.gonzalezalberquilla@arm.com    decode_block = BasicDecode.subst(iop)
12513590Srekai.gonzalezalberquilla@arm.com    exec_output = BasicExecute.subst(iop)
12613590Srekai.gonzalezalberquilla@arm.com}};
12713590Srekai.gonzalezalberquilla@arm.com
12813590Srekai.gonzalezalberquilla@arm.com
12913590Srekai.gonzalezalberquilla@arm.comdef template LoadStoreDeclare {{
13013590Srekai.gonzalezalberquilla@arm.com    /**
13113590Srekai.gonzalezalberquilla@arm.com     * Static instruction class for "%(mnemonic)s".
13213590Srekai.gonzalezalberquilla@arm.com     */
13313590Srekai.gonzalezalberquilla@arm.com    class %(class_name)s : public %(base_class)s
13413590Srekai.gonzalezalberquilla@arm.com    {
13513590Srekai.gonzalezalberquilla@arm.com      protected:
13613590Srekai.gonzalezalberquilla@arm.com
13713590Srekai.gonzalezalberquilla@arm.com        /**
13813590Srekai.gonzalezalberquilla@arm.com         * "Fake" effective address computation class for "%(mnemonic)s".
13913590Srekai.gonzalezalberquilla@arm.com         */
14013590Srekai.gonzalezalberquilla@arm.com        class EAComp : public %(base_class)s
14113590Srekai.gonzalezalberquilla@arm.com        {
14213590Srekai.gonzalezalberquilla@arm.com          public:
14313590Srekai.gonzalezalberquilla@arm.com            /// Constructor
14413590Srekai.gonzalezalberquilla@arm.com            EAComp(ExtMachInst machInst);
14513590Srekai.gonzalezalberquilla@arm.com
14613590Srekai.gonzalezalberquilla@arm.com            %(BasicExecDeclare)s
14713590Srekai.gonzalezalberquilla@arm.com        };
14814030Sgabor.dozsa@arm.com
14914030Sgabor.dozsa@arm.com        /**
15013590Srekai.gonzalezalberquilla@arm.com         * "Fake" memory access instruction class for "%(mnemonic)s".
15113590Srekai.gonzalezalberquilla@arm.com         */
15213590Srekai.gonzalezalberquilla@arm.com        class MemAcc : public %(base_class)s
15313590Srekai.gonzalezalberquilla@arm.com        {
15413590Srekai.gonzalezalberquilla@arm.com          public:
15513590Srekai.gonzalezalberquilla@arm.com            /// Constructor
15613590Srekai.gonzalezalberquilla@arm.com            MemAcc(ExtMachInst machInst);
15713590Srekai.gonzalezalberquilla@arm.com
15814030Sgabor.dozsa@arm.com            %(BasicExecDeclare)s
15913590Srekai.gonzalezalberquilla@arm.com        };
16013590Srekai.gonzalezalberquilla@arm.com
16113590Srekai.gonzalezalberquilla@arm.com      public:
16213590Srekai.gonzalezalberquilla@arm.com
16313590Srekai.gonzalezalberquilla@arm.com        /// Constructor.
16413590Srekai.gonzalezalberquilla@arm.com        %(class_name)s(ExtMachInst machInst);
16513590Srekai.gonzalezalberquilla@arm.com
16613590Srekai.gonzalezalberquilla@arm.com        %(BasicExecDeclare)s
16713590Srekai.gonzalezalberquilla@arm.com
16813590Srekai.gonzalezalberquilla@arm.com        %(InitiateAccDeclare)s
16913590Srekai.gonzalezalberquilla@arm.com
17013590Srekai.gonzalezalberquilla@arm.com        %(CompleteAccDeclare)s
17113590Srekai.gonzalezalberquilla@arm.com    };
17213590Srekai.gonzalezalberquilla@arm.com}};
17313590Srekai.gonzalezalberquilla@arm.com
17413590Srekai.gonzalezalberquilla@arm.com
17513590Srekai.gonzalezalberquilla@arm.comdef template InitiateAccDeclare {{
17613590Srekai.gonzalezalberquilla@arm.com    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
17713590Srekai.gonzalezalberquilla@arm.com}};
17813590Srekai.gonzalezalberquilla@arm.com
17913590Srekai.gonzalezalberquilla@arm.com
18013590Srekai.gonzalezalberquilla@arm.comdef template CompleteAccDeclare {{
18113590Srekai.gonzalezalberquilla@arm.com    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
18213590Srekai.gonzalezalberquilla@arm.com}};
18313590Srekai.gonzalezalberquilla@arm.com
18413590Srekai.gonzalezalberquilla@arm.com
18513590Srekai.gonzalezalberquilla@arm.comdef template LoadStoreConstructor {{
18613590Srekai.gonzalezalberquilla@arm.com    /** TODO: change op_class to AddrGenOp or something (requires
18713590Srekai.gonzalezalberquilla@arm.com     * creating new member of OpClass enum in op_class.hh, updating
18813590Srekai.gonzalezalberquilla@arm.com     * config files, etc.). */
18913590Srekai.gonzalezalberquilla@arm.com    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
19013590Srekai.gonzalezalberquilla@arm.com        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
19113590Srekai.gonzalezalberquilla@arm.com    {
19213590Srekai.gonzalezalberquilla@arm.com        %(ea_constructor)s;
19313590Srekai.gonzalezalberquilla@arm.com    }
19413590Srekai.gonzalezalberquilla@arm.com
19513590Srekai.gonzalezalberquilla@arm.com    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
19613590Srekai.gonzalezalberquilla@arm.com        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
19713590Srekai.gonzalezalberquilla@arm.com    {
19813590Srekai.gonzalezalberquilla@arm.com        %(memacc_constructor)s;
19913590Srekai.gonzalezalberquilla@arm.com    }
20013590Srekai.gonzalezalberquilla@arm.com
20113590Srekai.gonzalezalberquilla@arm.com    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
20213590Srekai.gonzalezalberquilla@arm.com         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
20313590Srekai.gonzalezalberquilla@arm.com                          new EAComp(machInst), new MemAcc(machInst))
20413590Srekai.gonzalezalberquilla@arm.com    {
20513590Srekai.gonzalezalberquilla@arm.com        %(constructor)s;
20613590Srekai.gonzalezalberquilla@arm.com    }
20713590Srekai.gonzalezalberquilla@arm.com}};
20813590Srekai.gonzalezalberquilla@arm.com
20913590Srekai.gonzalezalberquilla@arm.com
21013590Srekai.gonzalezalberquilla@arm.comdef template EACompExecute {{
21113590Srekai.gonzalezalberquilla@arm.com    Fault
21213590Srekai.gonzalezalberquilla@arm.com    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
21313590Srekai.gonzalezalberquilla@arm.com                                   Trace::InstRecord *traceData) const
21413590Srekai.gonzalezalberquilla@arm.com    {
21513590Srekai.gonzalezalberquilla@arm.com        Addr EA;
2162292SN/A        Fault fault = NoFault;
2172292SN/A
21813472Srekai.gonzalezalberquilla@arm.com        %(fp_enable_check)s;
21913472Srekai.gonzalezalberquilla@arm.com        %(op_decl)s;
22013472Srekai.gonzalezalberquilla@arm.com        %(op_rd)s;
22113472Srekai.gonzalezalberquilla@arm.com        %(code)s;
22213472Srekai.gonzalezalberquilla@arm.com
22313472Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
22413472Srekai.gonzalezalberquilla@arm.com            %(op_wb)s;
2252292SN/A            xc->setEA(EA);
2262292SN/A        }
2275529Snate@binkert.org
22813472Srekai.gonzalezalberquilla@arm.com        return fault;
2292292SN/A    }
2302292SN/A}};
2312292SN/A
2322292SN/Adef template LoadMemAccExecute {{
2332727Sktlim@umich.edu    Fault
2342727Sktlim@umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2352727Sktlim@umich.edu                                   Trace::InstRecord *traceData) const
2362907Sktlim@umich.edu    {
2378922Swilliam.wang@arm.com        Addr EA;
2382907Sktlim@umich.edu        Fault fault = NoFault;
2399444SAndreas.Sandberg@ARM.com
2409444SAndreas.Sandberg@ARM.com        %(fp_enable_check)s;
2412307SN/A        %(op_decl)s;
2422348SN/A        %(op_rd)s;
2432307SN/A        EA = xc->getEA();
2442307SN/A
2452292SN/A        if (fault == NoFault) {
24613429Srekai.gonzalezalberquilla@arm.com            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2472292SN/A            %(code)s;
24813429Srekai.gonzalezalberquilla@arm.com        }
2492292SN/A
25013429Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
2512292SN/A            %(op_wb)s;
2528545Ssaidi@eecs.umich.edu        }
2538545Ssaidi@eecs.umich.edu
2548545Ssaidi@eecs.umich.edu        return fault;
2558199SAli.Saidi@ARM.com    }
2568199SAli.Saidi@ARM.com}};
2578199SAli.Saidi@ARM.com
25813590Srekai.gonzalezalberquilla@arm.com
25913590Srekai.gonzalezalberquilla@arm.comdef template LoadExecute {{
2608199SAli.Saidi@ARM.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2618545Ssaidi@eecs.umich.edu                                  Trace::InstRecord *traceData) const
2628545Ssaidi@eecs.umich.edu    {
2638545Ssaidi@eecs.umich.edu        Addr EA;
2648545Ssaidi@eecs.umich.edu        Fault fault = NoFault;
2658545Ssaidi@eecs.umich.edu
2668545Ssaidi@eecs.umich.edu        %(fp_enable_check)s;
2672292SN/A        %(op_decl)s;
26813429Srekai.gonzalezalberquilla@arm.com        %(op_rd)s;
2692292SN/A        %(ea_code)s;
2702329SN/A
2712292SN/A        if (fault == NoFault) {
27213429Srekai.gonzalezalberquilla@arm.com            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2732292SN/A            %(memacc_code)s;
2742292SN/A        }
2752292SN/A
2762292SN/A        if (fault == NoFault) {
2772292SN/A            %(op_wb)s;
2782292SN/A        }
2792292SN/A
2802292SN/A        return fault;
2812292SN/A    }
2822292SN/A}};
2832292SN/A
2842292SN/A
2852790Sktlim@umich.edudef template LoadInitiateAcc {{
2862790Sktlim@umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2872669Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
2882669Sktlim@umich.edu    {
2892292SN/A        Addr EA;
2902292SN/A        Fault fault = NoFault;
2912292SN/A
2922292SN/A        %(fp_enable_check)s;
2932292SN/A        %(op_src_decl)s;
2942292SN/A        %(op_rd)s;
2952292SN/A        %(ea_code)s;
2962292SN/A
2972292SN/A        if (fault == NoFault) {
2982292SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2992292SN/A        }
30010239Sbinhpham@cs.rutgers.edu
30110239Sbinhpham@cs.rutgers.edu        return fault;
30210239Sbinhpham@cs.rutgers.edu    }
30310239Sbinhpham@cs.rutgers.edu}};
30410239Sbinhpham@cs.rutgers.edu
3052292SN/A
3062292SN/Adef template LoadCompleteAcc {{
3072292SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
3082292SN/A                                      %(CPU_exec_context)s *xc,
3092292SN/A                                      Trace::InstRecord *traceData) const
3102292SN/A    {
3112292SN/A        Fault fault = NoFault;
3122292SN/A
3132292SN/A        %(fp_enable_check)s;
3142292SN/A        %(op_src_decl)s;
3159444SAndreas.Sandberg@ARM.com        %(op_dest_decl)s;
3169444SAndreas.Sandberg@ARM.com
3179444SAndreas.Sandberg@ARM.com        memcpy(&Mem, data, sizeof(Mem));
3182292SN/A
31913590Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
3202292SN/A            %(memacc_code)s;
3212292SN/A        }
32213590Srekai.gonzalezalberquilla@arm.com
3232292SN/A        if (fault == NoFault) {
3249444SAndreas.Sandberg@ARM.com            %(op_wb)s;
3259444SAndreas.Sandberg@ARM.com        }
3269444SAndreas.Sandberg@ARM.com
3279444SAndreas.Sandberg@ARM.com        return fault;
3289444SAndreas.Sandberg@ARM.com    }
3299444SAndreas.Sandberg@ARM.com}};
3302292SN/A
3312292SN/A
3322292SN/Adef template StoreMemAccExecute {{
3332292SN/A    Fault
3342292SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3352292SN/A                                   Trace::InstRecord *traceData) const
3362292SN/A    {
3372292SN/A        Addr EA;
3382292SN/A        Fault fault = NoFault;
3392292SN/A        uint64_t write_result = 0;
34013590Srekai.gonzalezalberquilla@arm.com
34113590Srekai.gonzalezalberquilla@arm.com        %(fp_enable_check)s;
34213590Srekai.gonzalezalberquilla@arm.com        %(op_decl)s;
34313590Srekai.gonzalezalberquilla@arm.com        %(op_rd)s;
34413590Srekai.gonzalezalberquilla@arm.com        EA = xc->getEA();
34513590Srekai.gonzalezalberquilla@arm.com
34613590Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
34713590Srekai.gonzalezalberquilla@arm.com            %(code)s;
34813590Srekai.gonzalezalberquilla@arm.com        }
3492292SN/A
3502907Sktlim@umich.edu        if (fault == NoFault) {
3512907Sktlim@umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3522907Sktlim@umich.edu                              memAccessFlags, &write_result);
35313590Srekai.gonzalezalberquilla@arm.com            if (traceData) { traceData->setData(Mem); }
3542292SN/A        }
3559444SAndreas.Sandberg@ARM.com
3569444SAndreas.Sandberg@ARM.com        if (fault == NoFault) {
3579444SAndreas.Sandberg@ARM.com            %(postacc_code)s;
3582698Sktlim@umich.edu        }
35913429Srekai.gonzalezalberquilla@arm.com
3602678Sktlim@umich.edu        if (fault == NoFault) {
36113590Srekai.gonzalezalberquilla@arm.com            %(op_wb)s;
36213590Srekai.gonzalezalberquilla@arm.com        }
36313590Srekai.gonzalezalberquilla@arm.com
36413590Srekai.gonzalezalberquilla@arm.com        return fault;
36513590Srekai.gonzalezalberquilla@arm.com    }
3666974Stjones1@inf.ed.ac.uk}};
3672698Sktlim@umich.edu
36813590Srekai.gonzalezalberquilla@arm.com
3692292SN/Adef template StoreExecute {{
3702329SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
37113590Srekai.gonzalezalberquilla@arm.com                                  Trace::InstRecord *traceData) const
37213590Srekai.gonzalezalberquilla@arm.com    {
37313590Srekai.gonzalezalberquilla@arm.com        Addr EA;
37413590Srekai.gonzalezalberquilla@arm.com        Fault fault = NoFault;
37513590Srekai.gonzalezalberquilla@arm.com        uint64_t write_result = 0;
37613590Srekai.gonzalezalberquilla@arm.com
37713590Srekai.gonzalezalberquilla@arm.com        %(fp_enable_check)s;
3782329SN/A        %(op_decl)s;
3799440SAndreas.Sandberg@ARM.com        %(op_rd)s;
3802329SN/A        %(ea_code)s;
38113590Srekai.gonzalezalberquilla@arm.com
38213590Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
38313590Srekai.gonzalezalberquilla@arm.com            %(memacc_code)s;
38413590Srekai.gonzalezalberquilla@arm.com        }
38513590Srekai.gonzalezalberquilla@arm.com
3862292SN/A        if (fault == NoFault) {
3872292SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3882733Sktlim@umich.edu                              memAccessFlags, &write_result);
3892292SN/A            if (traceData) { traceData->setData(Mem); }
3902292SN/A        }
3912292SN/A
3922292SN/A        if (fault == NoFault) {
3932907Sktlim@umich.edu            %(postacc_code)s;
3942907Sktlim@umich.edu        }
3952669Sktlim@umich.edu
3962907Sktlim@umich.edu        if (fault == NoFault) {
3978922Swilliam.wang@arm.com            %(op_wb)s;
3982292SN/A        }
39913590Srekai.gonzalezalberquilla@arm.com
40013590Srekai.gonzalezalberquilla@arm.com        return fault;
4012678Sktlim@umich.edu    }
40213590Srekai.gonzalezalberquilla@arm.com}};
4032678Sktlim@umich.edu
40413590Srekai.gonzalezalberquilla@arm.comdef template StoreInitiateAcc {{
40513590Srekai.gonzalezalberquilla@arm.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4062678Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
40713590Srekai.gonzalezalberquilla@arm.com    {
40813590Srekai.gonzalezalberquilla@arm.com        Addr EA;
40913590Srekai.gonzalezalberquilla@arm.com        Fault fault = NoFault;
41013590Srekai.gonzalezalberquilla@arm.com        uint64_t write_result = 0;
41113590Srekai.gonzalezalberquilla@arm.com
41213590Srekai.gonzalezalberquilla@arm.com        %(fp_enable_check)s;
41313590Srekai.gonzalezalberquilla@arm.com        %(op_src_decl)s;
41413590Srekai.gonzalezalberquilla@arm.com        %(op_dest_decl)s;
41513590Srekai.gonzalezalberquilla@arm.com        %(op_rd)s;
41613590Srekai.gonzalezalberquilla@arm.com        %(ea_code)s;
4176974Stjones1@inf.ed.ac.uk
41813590Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
41913590Srekai.gonzalezalberquilla@arm.com            %(memacc_code)s;
42013590Srekai.gonzalezalberquilla@arm.com        }
42113590Srekai.gonzalezalberquilla@arm.com
42213590Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
42313590Srekai.gonzalezalberquilla@arm.com            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
42413590Srekai.gonzalezalberquilla@arm.com                              memAccessFlags, &write_result);
42513590Srekai.gonzalezalberquilla@arm.com            if (traceData) { traceData->setData(Mem); }
42613590Srekai.gonzalezalberquilla@arm.com        }
42713590Srekai.gonzalezalberquilla@arm.com
42813590Srekai.gonzalezalberquilla@arm.com        return fault;
42913590Srekai.gonzalezalberquilla@arm.com    }
43013590Srekai.gonzalezalberquilla@arm.com}};
43113590Srekai.gonzalezalberquilla@arm.com
43213590Srekai.gonzalezalberquilla@arm.com
43313590Srekai.gonzalezalberquilla@arm.comdef template StoreCompleteAcc {{
4342678Sktlim@umich.edu    Fault %(class_name)s::completeAcc(uint8_t *data,
4352678Sktlim@umich.edu                                      %(CPU_exec_context)s *xc,
4362698Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
43713590Srekai.gonzalezalberquilla@arm.com    {
43813590Srekai.gonzalezalberquilla@arm.com        Fault fault = NoFault;
4392678Sktlim@umich.edu        uint64_t write_result = 0;
4402678Sktlim@umich.edu
44113429Srekai.gonzalezalberquilla@arm.com        %(fp_enable_check)s;
44213429Srekai.gonzalezalberquilla@arm.com        %(op_dest_decl)s;
4432678Sktlim@umich.edu
4442678Sktlim@umich.edu        memcpy(&write_result, data, sizeof(write_result));
4452678Sktlim@umich.edu
4462678Sktlim@umich.edu        if (fault == NoFault) {
4472678Sktlim@umich.edu            %(postacc_code)s;
4485336Shines@cs.fsu.edu        }
4492678Sktlim@umich.edu
4502678Sktlim@umich.edu        if (fault == NoFault) {
4512698Sktlim@umich.edu            %(op_wb)s;
4522678Sktlim@umich.edu        }
4532678Sktlim@umich.edu
4542698Sktlim@umich.edu        return fault;
4552678Sktlim@umich.edu    }
4562678Sktlim@umich.edu}};
4572678Sktlim@umich.edu
4582678Sktlim@umich.edu
4592678Sktlim@umich.edudef template MiscMemAccExecute {{
4602678Sktlim@umich.edu    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
4612292SN/A                                          Trace::InstRecord *traceData) const
46213590Srekai.gonzalezalberquilla@arm.com    {
46313590Srekai.gonzalezalberquilla@arm.com        Addr EA;
46413590Srekai.gonzalezalberquilla@arm.com        Fault fault = NoFault;
46513590Srekai.gonzalezalberquilla@arm.com
46613590Srekai.gonzalezalberquilla@arm.com        %(fp_enable_check)s;
46713590Srekai.gonzalezalberquilla@arm.com        %(op_decl)s;
46813590Srekai.gonzalezalberquilla@arm.com        %(op_rd)s;
4692329SN/A        EA = xc->getEA();
4702292SN/A
4712292SN/A        if (fault == NoFault) {
4726221Snate@binkert.org            %(code)s;
47313590Srekai.gonzalezalberquilla@arm.com        }
4742292SN/A
47513590Srekai.gonzalezalberquilla@arm.com        return NoFault;
4762292SN/A    }
4772292SN/A}};
47813590Srekai.gonzalezalberquilla@arm.com
4792292SN/Adef template MiscExecute {{
48013590Srekai.gonzalezalberquilla@arm.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4818199SAli.Saidi@ARM.com                                  Trace::InstRecord *traceData) const
4828199SAli.Saidi@ARM.com    {
4838199SAli.Saidi@ARM.com        Addr EA;
4848199SAli.Saidi@ARM.com        Fault fault = NoFault;
4858199SAli.Saidi@ARM.com
4868199SAli.Saidi@ARM.com        %(fp_enable_check)s;
4878199SAli.Saidi@ARM.com        %(op_decl)s;
4888199SAli.Saidi@ARM.com        %(op_rd)s;
4892292SN/A        %(ea_code)s;
4902292SN/A
4912329SN/A        if (fault == NoFault) {
4922292SN/A            %(memacc_code)s;
4932292SN/A        }
4942292SN/A
4952292SN/A        return NoFault;
4962329SN/A    }
4972329SN/A}};
4982292SN/A
49913590Srekai.gonzalezalberquilla@arm.comdef template MiscInitiateAcc {{
5002292SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5018545Ssaidi@eecs.umich.edu                                      Trace::InstRecord *traceData) const
5028545Ssaidi@eecs.umich.edu    {
5038545Ssaidi@eecs.umich.edu        panic("Misc instruction does not support split access method!");
5042292SN/A        return NoFault;
5052292SN/A    }
5062292SN/A}};
5072292SN/A
5082292SN/A
5092292SN/Adef template MiscCompleteAcc {{
5102292SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
5112292SN/A                                      %(CPU_exec_context)s *xc,
5122292SN/A                                      Trace::InstRecord *traceData) const
5132292SN/A    {
5142292SN/A        panic("Misc instruction does not support split access method!");
5152292SN/A
5162698Sktlim@umich.edu        return NoFault;
5172698Sktlim@umich.edu    }
5182693Sktlim@umich.edu}};
5192698Sktlim@umich.edu
5202678Sktlim@umich.edu// load instructions use Ra as dest, so check for
5212678Sktlim@umich.edu// Ra == 31 to detect nops
5228727Snilay@cs.wisc.edudef template LoadNopCheckDecode {{
5238727Snilay@cs.wisc.edu {
5248727Snilay@cs.wisc.edu     AlphaStaticInst *i = new %(class_name)s(machInst);
5252292SN/A     if (RA == 31) {
5262292SN/A         i = makeNop(i);
5272292SN/A     }
5286974Stjones1@inf.ed.ac.uk     return i;
5296974Stjones1@inf.ed.ac.uk }
53013590Srekai.gonzalezalberquilla@arm.com}};
5316974Stjones1@inf.ed.ac.uk
5326974Stjones1@inf.ed.ac.uk
53313590Srekai.gonzalezalberquilla@arm.com// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
5346974Stjones1@inf.ed.ac.ukdef template LoadPrefetchCheckDecode {{
5358727Snilay@cs.wisc.edu {
5368727Snilay@cs.wisc.edu     if (RA != 31) {
5378727Snilay@cs.wisc.edu         return new %(class_name)s(machInst);
5382292SN/A     }
5392292SN/A     else {
5402292SN/A         return new %(class_name)sPrefetch(machInst);
5412727Sktlim@umich.edu     }
5425999Snate@binkert.org }
5432307SN/A}};
5443126Sktlim@umich.edu
5455999Snate@binkert.org
5463126Sktlim@umich.edulet {{
5473126Sktlim@umich.edudef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5485999Snate@binkert.org                  postacc_code = '', base_class = 'MemoryDisp32',
5493126Sktlim@umich.edu                  decode_template = BasicDecode, exec_template_base = ''):
5503126Sktlim@umich.edu    # Make sure flags are in lists (convert to lists if not).
5513126Sktlim@umich.edu    mem_flags = makeList(mem_flags)
5525999Snate@binkert.org    inst_flags = makeList(inst_flags)
5533126Sktlim@umich.edu
5543126Sktlim@umich.edu    # add hook to get effective addresses into execution trace output.
5555999Snate@binkert.org    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
5563126Sktlim@umich.edu
5572727Sktlim@umich.edu    # generate code block objects
5585999Snate@binkert.org    ea_cblk = CodeBlock(ea_code)
5592727Sktlim@umich.edu    memacc_cblk = CodeBlock(memacc_code)
5602727Sktlim@umich.edu    postacc_cblk = CodeBlock(postacc_code)
5615999Snate@binkert.org
5622727Sktlim@umich.edu    # Some CPU models execute the memory operation as an atomic unit,
5632727Sktlim@umich.edu    # while others want to separate them into an effective address
5645999Snate@binkert.org    # computation and a memory access operation.  As a result, we need
5652727Sktlim@umich.edu    # to generate three StaticInst objects.  Note that the latter two
5662727Sktlim@umich.edu    # are nested inside the larger "atomic" one.
5675999Snate@binkert.org
5682727Sktlim@umich.edu    # generate InstObjParams for EAComp object
5692727Sktlim@umich.edu    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
5705999Snate@binkert.org
5712727Sktlim@umich.edu    # generate InstObjParams for MemAcc object
5722292SN/A    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
5732292SN/A    # in the split execution model, the MemAcc portion is responsible
57413590Srekai.gonzalezalberquilla@arm.com    # for the post-access code.
5752292SN/A    memacc_iop.postacc_code = postacc_cblk.code
5762292SN/A
57713590Srekai.gonzalezalberquilla@arm.com    # generate InstObjParams for InitiateAcc, CompleteAcc object
5782292SN/A    # The code used depends on the template being used
5792292SN/A    if (exec_template_base == 'Load'):
58013590Srekai.gonzalezalberquilla@arm.com        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
58113590Srekai.gonzalezalberquilla@arm.com        completeacc_cblk = CodeBlock(memacc_code + postacc_code)
5822292SN/A    elif (exec_template_base == 'Store'):
58313590Srekai.gonzalezalberquilla@arm.com        initiateacc_cblk = CodeBlock(ea_code + memacc_code)
58413590Srekai.gonzalezalberquilla@arm.com        completeacc_cblk = CodeBlock(postacc_code)
5852292SN/A    else:
58613590Srekai.gonzalezalberquilla@arm.com        initiateacc_cblk = ''
58713590Srekai.gonzalezalberquilla@arm.com        completeacc_cblk = ''
58813590Srekai.gonzalezalberquilla@arm.com
5892292SN/A    initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
5902292SN/A                                    inst_flags)
5912292SN/A
59213590Srekai.gonzalezalberquilla@arm.com    completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
5932292SN/A                                    inst_flags)
59413590Srekai.gonzalezalberquilla@arm.com
59513590Srekai.gonzalezalberquilla@arm.com    if (exec_template_base == 'Load'):
5962292SN/A        initiateacc_iop.ea_code = ea_cblk.code
59713590Srekai.gonzalezalberquilla@arm.com        initiateacc_iop.memacc_code = memacc_cblk.code
59813590Srekai.gonzalezalberquilla@arm.com        completeacc_iop.memacc_code = memacc_cblk.code
59913590Srekai.gonzalezalberquilla@arm.com        completeacc_iop.postacc_code = postacc_cblk.code
6002292SN/A    elif (exec_template_base == 'Store'):
6012292SN/A        initiateacc_iop.ea_code = ea_cblk.code
6022292SN/A        initiateacc_iop.memacc_code = memacc_cblk.code
6032292SN/A        completeacc_iop.postacc_code = postacc_cblk.code
60413590Srekai.gonzalezalberquilla@arm.com
60513590Srekai.gonzalezalberquilla@arm.com    # generate InstObjParams for unified execution
60613590Srekai.gonzalezalberquilla@arm.com    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
60713590Srekai.gonzalezalberquilla@arm.com    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
60813590Srekai.gonzalezalberquilla@arm.com
6092292SN/A    iop.ea_constructor = ea_cblk.constructor
6102292SN/A    iop.ea_code = ea_cblk.code
6112292SN/A    iop.memacc_constructor = memacc_cblk.constructor
6122292SN/A    iop.memacc_code = memacc_cblk.code
61313590Srekai.gonzalezalberquilla@arm.com    iop.postacc_code = postacc_cblk.code
6142292SN/A
61513590Srekai.gonzalezalberquilla@arm.com    if mem_flags:
61613590Srekai.gonzalezalberquilla@arm.com        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
6172292SN/A        iop.constructor += s
61813590Srekai.gonzalezalberquilla@arm.com        memacc_iop.constructor += s
6192669Sktlim@umich.edu
6202669Sktlim@umich.edu    # select templates
6212669Sktlim@umich.edu    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
6222292SN/A    fullExecTemplate = eval(exec_template_base + 'Execute')
62310824SAndreas.Sandberg@ARM.com    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
62410824SAndreas.Sandberg@ARM.com    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
62510824SAndreas.Sandberg@ARM.com
62610824SAndreas.Sandberg@ARM.com    # (header_output, decoder_output, decode_block, exec_output)
62713590Srekai.gonzalezalberquilla@arm.com    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
62813590Srekai.gonzalezalberquilla@arm.com            decode_template.subst(iop),
62913590Srekai.gonzalezalberquilla@arm.com            EACompExecute.subst(ea_iop)
63013590Srekai.gonzalezalberquilla@arm.com            + memAccExecTemplate.subst(memacc_iop)
63113590Srekai.gonzalezalberquilla@arm.com            + fullExecTemplate.subst(iop)
6322669Sktlim@umich.edu            + initiateAccTemplate.subst(initiateacc_iop)
63313590Srekai.gonzalezalberquilla@arm.com            + completeAccTemplate.subst(completeacc_iop))
63413590Srekai.gonzalezalberquilla@arm.com}};
6352727Sktlim@umich.edu
63610824SAndreas.Sandberg@ARM.com
6377720Sgblack@eecs.umich.edudef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
6384032Sktlim@umich.edu                     mem_flags = [], inst_flags = []) {{
63913590Srekai.gonzalezalberquilla@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
64013590Srekai.gonzalezalberquilla@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
64113590Srekai.gonzalezalberquilla@arm.com                      decode_template = LoadNopCheckDecode,
64213590Srekai.gonzalezalberquilla@arm.com                      exec_template_base = 'Load')
64313590Srekai.gonzalezalberquilla@arm.com}};
64410474Sandreas.hansson@arm.com
64510824SAndreas.Sandberg@ARM.com
64610474Sandreas.hansson@arm.com// Note that the flags passed in apply only to the prefetch version
6472292SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
6482292SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
6492292SN/A    # declare the load instruction object and generate the decode block
6506974Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
65113590Srekai.gonzalezalberquilla@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
65213590Srekai.gonzalezalberquilla@arm.com                      decode_template = LoadPrefetchCheckDecode,
6532292SN/A                      exec_template_base = 'Load')
65413590Srekai.gonzalezalberquilla@arm.com
6553326Sktlim@umich.edu    # Declare the prefetch instruction object.
6563326Sktlim@umich.edu
6573326Sktlim@umich.edu    # Make sure flag args are lists so we can mess with them.
6589046SAli.Saidi@ARM.com    mem_flags = makeList(mem_flags)
65913590Srekai.gonzalezalberquilla@arm.com    pf_flags = makeList(pf_flags)
6609046SAli.Saidi@ARM.com    inst_flags = makeList(inst_flags)
6612292SN/A
6622292SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
66313590Srekai.gonzalezalberquilla@arm.com    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
6648481Sgblack@eecs.umich.edu                                  'IsDataPrefetch', 'MemReadOp']
66514030Sgabor.dozsa@arm.com
6668481Sgblack@eecs.umich.edu    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
6678481Sgblack@eecs.umich.edu        LoadStoreBase(name, Name + 'Prefetch', ea_code,
66813590Srekai.gonzalezalberquilla@arm.com                      'xc->prefetch(EA, memAccessFlags);',
6698481Sgblack@eecs.umich.edu                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
67014083SPouya.Fotouhi@amd.com
67114083SPouya.Fotouhi@amd.com    header_output += pf_header_output
67213590Srekai.gonzalezalberquilla@arm.com    decoder_output += pf_decoder_output
6738481Sgblack@eecs.umich.edu    exec_output += pf_exec_output
67413590Srekai.gonzalezalberquilla@arm.com}};
6759179Sandreas.hansson@arm.com
6768481Sgblack@eecs.umich.edu
6778481Sgblack@eecs.umich.edudef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
6788481Sgblack@eecs.umich.edu                 mem_flags = [], inst_flags = []) {{
67913590Srekai.gonzalezalberquilla@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
68013590Srekai.gonzalezalberquilla@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
68113590Srekai.gonzalezalberquilla@arm.com                      exec_template_base = 'Store')
68213590Srekai.gonzalezalberquilla@arm.com}};
68313590Srekai.gonzalezalberquilla@arm.com
68413590Srekai.gonzalezalberquilla@arm.com
68513590Srekai.gonzalezalberquilla@arm.comdef format StoreCond(memacc_code, postacc_code,
68613590Srekai.gonzalezalberquilla@arm.com                     ea_code = {{ EA = Rb + disp; }},
68713590Srekai.gonzalezalberquilla@arm.com                     mem_flags = [], inst_flags = []) {{
68813590Srekai.gonzalezalberquilla@arm.com    (header_output, decoder_output, decode_block, exec_output) = \
6892292SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
69013590Srekai.gonzalezalberquilla@arm.com                      postacc_code, exec_template_base = 'Store')
69113590Srekai.gonzalezalberquilla@arm.com}};
69213590Srekai.gonzalezalberquilla@arm.com
69313590Srekai.gonzalezalberquilla@arm.com
69413590Srekai.gonzalezalberquilla@arm.com// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
69513590Srekai.gonzalezalberquilla@arm.comdef format MiscPrefetch(ea_code, memacc_code,
69613590Srekai.gonzalezalberquilla@arm.com                        mem_flags = [], inst_flags = []) {{
6972292SN/A    (header_output, decoder_output, decode_block, exec_output) = \
69813590Srekai.gonzalezalberquilla@arm.com        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
69913590Srekai.gonzalezalberquilla@arm.com                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
70013590Srekai.gonzalezalberquilla@arm.com}};
70113590Srekai.gonzalezalberquilla@arm.com
70213590Srekai.gonzalezalberquilla@arm.com
70313590Srekai.gonzalezalberquilla@arm.com