mem.isa revision 2742:47e405ea4da8
1360SN/A// -*- mode:c++ -*-
21458SN/A
3360SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
4360SN/A// All rights reserved.
5360SN/A//
6360SN/A// Redistribution and use in source and binary forms, with or without
7360SN/A// modification, are permitted provided that the following conditions are
8360SN/A// met: redistributions of source code must retain the above copyright
9360SN/A// notice, this list of conditions and the following disclaimer;
10360SN/A// redistributions in binary form must reproduce the above copyright
11360SN/A// notice, this list of conditions and the following disclaimer in the
12360SN/A// documentation and/or other materials provided with the distribution;
13360SN/A// neither the name of the copyright holders nor the names of its
14360SN/A// contributors may be used to endorse or promote products derived from
15360SN/A// this software without specific prior written permission.
16360SN/A//
17360SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18360SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19360SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20360SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21360SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22360SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23360SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24360SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25360SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26360SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292665Ssaidi@eecs.umich.edu// Authors: Gabe Black
30360SN/A//          Korey Sewell
31360SN/A
321354SN/A////////////////////////////////////////////////////////////////////
331354SN/A//
34360SN/A// Memory-format instructions
352764Sstever@eecs.umich.edu//
362764Sstever@eecs.umich.edu
372064SN/Aoutput header {{
38360SN/A    /**
39360SN/A     * Base class for general Mips memory-format instructions.
40360SN/A     */
41360SN/A    class Memory : public MipsStaticInst
42360SN/A    {
43360SN/A      protected:
441354SN/A
45360SN/A        /// Memory request flags.  See mem_req_base.hh.
461809SN/A        unsigned memAccessFlags;
471809SN/A        /// Pointer to EAComp object.
481809SN/A        const StaticInstPtr eaCompPtr;
493113Sgblack@eecs.umich.edu        /// Pointer to MemAcc object.
503113Sgblack@eecs.umich.edu        const StaticInstPtr memAccPtr;
511999SN/A
52360SN/A        /// Displacement for EA calculation (signed).
533113Sgblack@eecs.umich.edu        int32_t disp;
542474SN/A
55360SN/A        /// Constructor
562462SN/A        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
571354SN/A               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
582474SN/A               StaticInstPtr _memAccPtr = nullStaticInstPtr)
592680Sktlim@umich.edu            : MipsStaticInst(mnem, _machInst, __opClass),
602474SN/A              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
612474SN/A              disp(sext<16>(OFFSET))
621354SN/A        {
63360SN/A        }
64360SN/A
65360SN/A        std::string
66360SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
67360SN/A
68360SN/A      public:
69360SN/A
70360SN/A        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
71378SN/A        const StaticInstPtr &memAccInst() const { return memAccPtr; }
721450SN/A    };
733114Sgblack@eecs.umich.edu
74360SN/A     /**
75360SN/A     * Base class for a few miscellaneous memory-format insts
76360SN/A     * that don't interpret the disp field
77360SN/A     */
78360SN/A    class MemoryNoDisp : public Memory
79360SN/A    {
80360SN/A      protected:
81360SN/A        /// Constructor
82360SN/A        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
832680Sktlim@umich.edu                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
84360SN/A                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
85360SN/A            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
86360SN/A        {
87360SN/A        }
88360SN/A
89360SN/A        std::string
90360SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
91360SN/A    };
92360SN/A}};
93360SN/A
94360SN/A
953114Sgblack@eecs.umich.eduoutput decoder {{
96360SN/A    std::string
97360SN/A    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
98360SN/A    {
99360SN/A        return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
100360SN/A                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
101360SN/A    }
102360SN/A
103360SN/A    std::string
104360SN/A    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
105360SN/A    {
106360SN/A        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
107360SN/A                        flags[IsFloating] ? 'f' : 'r',
108360SN/A                        flags[IsFloating] ? FD : RD,
109360SN/A                        RS, RT);
110360SN/A    }
111360SN/A}};
112360SN/A
113360SN/Adef template LoadStoreDeclare {{
114360SN/A    /**
115360SN/A     * Static instruction class for "%(mnemonic)s".
116360SN/A     */
1172400SN/A    class %(class_name)s : public %(base_class)s
118360SN/A    {
1192461SN/A      protected:
120360SN/A
121360SN/A        /**
122360SN/A         * "Fake" effective address computation class for "%(mnemonic)s".
123360SN/A         */
124360SN/A        class EAComp : public %(base_class)s
125360SN/A        {
1262400SN/A          public:
127360SN/A            /// Constructor
1282461SN/A            EAComp(MachInst machInst);
129360SN/A
130360SN/A            %(BasicExecDeclare)s
131360SN/A        };
132360SN/A
133360SN/A        /**
134360SN/A         * "Fake" memory access instruction class for "%(mnemonic)s".
135360SN/A         */
136360SN/A        class MemAcc : public %(base_class)s
137360SN/A        {
138360SN/A          public:
139360SN/A            /// Constructor
140360SN/A            MemAcc(MachInst machInst);
141360SN/A
142360SN/A            %(BasicExecDeclare)s
143360SN/A        };
144360SN/A
145360SN/A      public:
146360SN/A
147360SN/A        /// Constructor.
148360SN/A        %(class_name)s(MachInst machInst);
149360SN/A
150360SN/A        %(BasicExecDeclare)s
151360SN/A
152360SN/A        %(InitiateAccDeclare)s
153360SN/A
154360SN/A        %(CompleteAccDeclare)s
155360SN/A    };
156360SN/A}};
157360SN/A
158360SN/A
159360SN/Adef template InitiateAccDeclare {{
160360SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
161502SN/A}};
162360SN/A
163502SN/A
164360SN/Adef template CompleteAccDeclare {{
165360SN/A    Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
166360SN/A}};
167360SN/A
168360SN/A
169360SN/Adef template LoadStoreConstructor {{
170360SN/A    /** TODO: change op_class to AddrGenOp or something (requires
171360SN/A     * creating new member of OpClass enum in op_class.hh, updating
172360SN/A     * config files, etc.). */
173360SN/A    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
174360SN/A        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
175378SN/A    {
1761706SN/A        %(ea_constructor)s;
1773114Sgblack@eecs.umich.edu    }
178378SN/A
179378SN/A    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
180378SN/A        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
181378SN/A    {
182378SN/A        %(memacc_constructor)s;
1831706SN/A    }
1843114Sgblack@eecs.umich.edu
185360SN/A    inline %(class_name)s::%(class_name)s(MachInst machInst)
186378SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1871706SN/A                          new EAComp(machInst), new MemAcc(machInst))
1883114Sgblack@eecs.umich.edu    {
189378SN/A        %(constructor)s;
190378SN/A    }
1911706SN/A}};
1923114Sgblack@eecs.umich.edu
193378SN/A
194378SN/Adef template EACompExecute {{
1951706SN/A    Fault
1963114Sgblack@eecs.umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
197378SN/A                                   Trace::InstRecord *traceData) const
198378SN/A    {
1991706SN/A        Addr EA;
2003114Sgblack@eecs.umich.edu        Fault fault = NoFault;
201378SN/A
202378SN/A        %(fp_enable_check)s;
2031706SN/A        %(op_decl)s;
2043114Sgblack@eecs.umich.edu        %(op_rd)s;
205378SN/A        %(code)s;
206378SN/A
2071706SN/A        if (fault == NoFault) {
2083114Sgblack@eecs.umich.edu            %(op_wb)s;
209378SN/A            xc->setEA(EA);
210378SN/A        }
2111706SN/A
2123114Sgblack@eecs.umich.edu        return fault;
213378SN/A    }
2144118Sgblack@eecs.umich.edu}};
2154118Sgblack@eecs.umich.edu
2164118Sgblack@eecs.umich.edudef template LoadMemAccExecute {{
2174118Sgblack@eecs.umich.edu    Fault
218378SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2191706SN/A                                   Trace::InstRecord *traceData) const
2203114Sgblack@eecs.umich.edu    {
221378SN/A        Addr EA;
222378SN/A        Fault fault = NoFault;
2231706SN/A
2243114Sgblack@eecs.umich.edu        %(fp_enable_check)s;
225360SN/A        %(op_decl)s;
226511SN/A        %(op_rd)s;
2271706SN/A        EA = xc->getEA();
2283114Sgblack@eecs.umich.edu
229511SN/A        if (fault == NoFault) {
230511SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2311706SN/A            %(code)s;
2323114Sgblack@eecs.umich.edu        }
2331706SN/A
2341706SN/A        if (fault == NoFault) {
2351706SN/A            %(op_wb)s;
2361706SN/A        }
2373114Sgblack@eecs.umich.edu
2381706SN/A        return fault;
2391706SN/A    }
2401706SN/A}};
2411706SN/A
2423114Sgblack@eecs.umich.edu
2431706SN/Adef template LoadExecute {{
244511SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2451999SN/A                                  Trace::InstRecord *traceData) const
2461999SN/A    {
2473114Sgblack@eecs.umich.edu        Addr EA;
2481999SN/A        Fault fault = NoFault;
2491999SN/A
2501999SN/A        %(fp_enable_check)s;
2511999SN/A        %(op_decl)s;
2523114Sgblack@eecs.umich.edu        %(op_rd)s;
2531999SN/A        %(ea_code)s;
2543079Sstever@eecs.umich.edu
2553079Sstever@eecs.umich.edu        if (fault == NoFault) {
2563114Sgblack@eecs.umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2573079Sstever@eecs.umich.edu            %(memacc_code)s;
2582093SN/A        }
2592093SN/A
2603114Sgblack@eecs.umich.edu        if (fault == NoFault) {
2612093SN/A            %(op_wb)s;
2622687Sksewell@umich.edu        }
2632687Sksewell@umich.edu
2643114Sgblack@eecs.umich.edu        return fault;
2652687Sksewell@umich.edu    }
2662238SN/A}};
2672238SN/A
2683114Sgblack@eecs.umich.edu
2692238SN/Adef template LoadInitiateAcc {{
2702238SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2712238SN/A                                      Trace::InstRecord *traceData) const
2723114Sgblack@eecs.umich.edu    {
2732238SN/A        Addr EA;
2742238SN/A        Fault fault = NoFault;
2752238SN/A
2763114Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2772238SN/A        %(op_src_decl)s;
2782238SN/A        %(op_rd)s;
2792238SN/A        %(ea_code)s;
2803114Sgblack@eecs.umich.edu
2812238SN/A        if (fault == NoFault) {
2822238SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
2832238SN/A        }
2843114Sgblack@eecs.umich.edu
2852238SN/A        return fault;
2862238SN/A    }
2872238SN/A}};
2883114Sgblack@eecs.umich.edu
2892238SN/A
2902238SN/Adef template LoadCompleteAcc {{
2912238SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
2923114Sgblack@eecs.umich.edu                                      %(CPU_exec_context)s *xc,
2932238SN/A                                      Trace::InstRecord *traceData) const
2942238SN/A    {
2952238SN/A        Fault fault = NoFault;
2962238SN/A
2972238SN/A        %(fp_enable_check)s;
2982238SN/A        %(op_decl)s;
2993114Sgblack@eecs.umich.edu
3002238SN/A        memcpy(&Mem, data, sizeof(Mem));
3012238SN/A
3022238SN/A        if (fault == NoFault) {
3033114Sgblack@eecs.umich.edu            %(memacc_code)s;
3042238SN/A        }
3052238SN/A
3062238SN/A        if (fault == NoFault) {
3073114Sgblack@eecs.umich.edu            %(op_wb)s;
3082238SN/A        }
3092238SN/A
3102238SN/A        return fault;
3113114Sgblack@eecs.umich.edu    }
3122238SN/A}};
3132238SN/A
3141354SN/A
3151354SN/Adef template StoreMemAccExecute {{
3161354SN/A    Fault
3171354SN/A    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
3181354SN/A                                   Trace::InstRecord *traceData) const
3191354SN/A    {
3201354SN/A        Addr EA;
3211354SN/A        Fault fault = NoFault;
3221354SN/A        uint64_t write_result = 0;
3231354SN/A
3241354SN/A        %(fp_enable_check)s;
3251354SN/A        %(op_decl)s;
3261354SN/A        %(op_rd)s;
3271354SN/A        EA = xc->getEA();
3281609SN/A
3291354SN/A        if (fault == NoFault) {
3301354SN/A            %(code)s;
3311354SN/A        }
3321354SN/A
333360SN/A        if (fault == NoFault) {
334360SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
335360SN/A                              memAccessFlags, &write_result);
336360SN/A            if (traceData) { traceData->setData(Mem); }
337360SN/A        }
338360SN/A
339360SN/A        if (fault == NoFault) {
3403113Sgblack@eecs.umich.edu            %(postacc_code)s;
3413113Sgblack@eecs.umich.edu        }
3423113Sgblack@eecs.umich.edu
3433113Sgblack@eecs.umich.edu        if (fault == NoFault) {
3443113Sgblack@eecs.umich.edu            %(op_wb)s;
3453113Sgblack@eecs.umich.edu        }
3463113Sgblack@eecs.umich.edu
3473113Sgblack@eecs.umich.edu        return fault;
3483113Sgblack@eecs.umich.edu    }
3493113Sgblack@eecs.umich.edu}};
3503113Sgblack@eecs.umich.edu
3513113Sgblack@eecs.umich.edu
3523113Sgblack@eecs.umich.edudef template StoreExecute {{
3533113Sgblack@eecs.umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3543113Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
3553113Sgblack@eecs.umich.edu    {
3564189Sgblack@eecs.umich.edu        Addr EA;
3574189Sgblack@eecs.umich.edu        Fault fault = NoFault;
3583113Sgblack@eecs.umich.edu        uint64_t write_result = 0;
3593113Sgblack@eecs.umich.edu
3603113Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3613113Sgblack@eecs.umich.edu        %(op_decl)s;
3623113Sgblack@eecs.umich.edu        %(op_rd)s;
3633113Sgblack@eecs.umich.edu        %(ea_code)s;
3643113Sgblack@eecs.umich.edu
3653277Sgblack@eecs.umich.edu        if (fault == NoFault) {
3663277Sgblack@eecs.umich.edu            %(memacc_code)s;
3673277Sgblack@eecs.umich.edu        }
3683277Sgblack@eecs.umich.edu
3693277Sgblack@eecs.umich.edu        if (fault == NoFault) {
3703277Sgblack@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
3713277Sgblack@eecs.umich.edu                              memAccessFlags, &write_result);
3723277Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
3733113Sgblack@eecs.umich.edu        }
3743113Sgblack@eecs.umich.edu
3753113Sgblack@eecs.umich.edu        if (fault == NoFault) {
3763113Sgblack@eecs.umich.edu            %(postacc_code)s;
3773113Sgblack@eecs.umich.edu        }
3783113Sgblack@eecs.umich.edu
3793113Sgblack@eecs.umich.edu        if (fault == NoFault) {
3803114Sgblack@eecs.umich.edu            %(op_wb)s;
3813113Sgblack@eecs.umich.edu        }
3823114Sgblack@eecs.umich.edu
3833113Sgblack@eecs.umich.edu        return fault;
3843114Sgblack@eecs.umich.edu    }
3853113Sgblack@eecs.umich.edu}};
3864061Sgblack@eecs.umich.edu
3874061Sgblack@eecs.umich.edudef template StoreInitiateAcc {{
3884061Sgblack@eecs.umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3893113Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
3903113Sgblack@eecs.umich.edu    {
3913113Sgblack@eecs.umich.edu        Addr EA;
3923113Sgblack@eecs.umich.edu        Fault fault = NoFault;
3933113Sgblack@eecs.umich.edu        uint64_t write_result = 0;
3943113Sgblack@eecs.umich.edu
3953113Sgblack@eecs.umich.edu        %(fp_enable_check)s;
3963113Sgblack@eecs.umich.edu        %(op_decl)s;
3973113Sgblack@eecs.umich.edu        %(op_rd)s;
3983113Sgblack@eecs.umich.edu        %(ea_code)s;
3993113Sgblack@eecs.umich.edu
4004189Sgblack@eecs.umich.edu        if (fault == NoFault) {
4014189Sgblack@eecs.umich.edu            %(memacc_code)s;
4023113Sgblack@eecs.umich.edu        }
4033113Sgblack@eecs.umich.edu
4043113Sgblack@eecs.umich.edu        if (fault == NoFault) {
4053113Sgblack@eecs.umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
4063113Sgblack@eecs.umich.edu                              memAccessFlags, &write_result);
4073113Sgblack@eecs.umich.edu            if (traceData) { traceData->setData(Mem); }
4083113Sgblack@eecs.umich.edu        }
4093113Sgblack@eecs.umich.edu
4103113Sgblack@eecs.umich.edu        return fault;
4113113Sgblack@eecs.umich.edu    }
4123113Sgblack@eecs.umich.edu}};
4133113Sgblack@eecs.umich.edu
4143113Sgblack@eecs.umich.edu
4153113Sgblack@eecs.umich.edudef template StoreCompleteAcc {{
4163113Sgblack@eecs.umich.edu    Fault %(class_name)s::completeAcc(uint8_t *data,
4173113Sgblack@eecs.umich.edu                                      %(CPU_exec_context)s *xc,
4183113Sgblack@eecs.umich.edu                                      Trace::InstRecord *traceData) const
4193113Sgblack@eecs.umich.edu    {
4203113Sgblack@eecs.umich.edu        Fault fault = NoFault;
4213113Sgblack@eecs.umich.edu        uint64_t write_result = 0;
4223113Sgblack@eecs.umich.edu
4233113Sgblack@eecs.umich.edu        %(fp_enable_check)s;
4243113Sgblack@eecs.umich.edu        %(op_dest_decl)s;
4253113Sgblack@eecs.umich.edu
4263113Sgblack@eecs.umich.edu        memcpy(&write_result, data, sizeof(write_result));
4273113Sgblack@eecs.umich.edu
4283113Sgblack@eecs.umich.edu        if (fault == NoFault) {
4293113Sgblack@eecs.umich.edu            %(postacc_code)s;
4303113Sgblack@eecs.umich.edu        }
4313113Sgblack@eecs.umich.edu
4323113Sgblack@eecs.umich.edu        if (fault == NoFault) {
4333113Sgblack@eecs.umich.edu            %(op_wb)s;
4343113Sgblack@eecs.umich.edu        }
4353113Sgblack@eecs.umich.edu
4363113Sgblack@eecs.umich.edu        return fault;
4373113Sgblack@eecs.umich.edu    }
4383113Sgblack@eecs.umich.edu}};
4393113Sgblack@eecs.umich.edu
440378SN/A
441378SN/Adef template MiscMemAccExecute {{
442378SN/A    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
443360SN/A                                          Trace::InstRecord *traceData) const
4441450SN/A    {
4453114Sgblack@eecs.umich.edu        Addr EA;
4462680Sktlim@umich.edu        Fault fault = NoFault;
447360SN/A
4482680Sktlim@umich.edu        %(fp_enable_check)s;
4492680Sktlim@umich.edu        %(op_decl)s;
450360SN/A        %(op_rd)s;
4511969SN/A        EA = xc->getEA();
452360SN/A
453360SN/A        if (fault == NoFault) {
454360SN/A            %(code)s;
4551458SN/A        }
456360SN/A
457360SN/A        return NoFault;
458360SN/A    }
4594131Sbinkertn@umich.edu}};
4604131Sbinkertn@umich.edu
4614131Sbinkertn@umich.edudef template MiscExecute {{
4624131Sbinkertn@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4634131Sbinkertn@umich.edu                                  Trace::InstRecord *traceData) const
4644131Sbinkertn@umich.edu    {
4654131Sbinkertn@umich.edu        Addr EA;
4664131Sbinkertn@umich.edu        Fault fault = NoFault;
4671458SN/A
468360SN/A        %(fp_enable_check)s;
469360SN/A        %(op_decl)s;
4701706SN/A        %(op_rd)s;
4712680Sktlim@umich.edu        %(ea_code)s;
472360SN/A
473360SN/A        if (fault == NoFault) {
474360SN/A            %(memacc_code)s;
475378SN/A        }
476360SN/A
4771450SN/A        return NoFault;
4783114Sgblack@eecs.umich.edu    }
4792680Sktlim@umich.edu}};
480360SN/A
481360SN/Adef template MiscInitiateAcc {{
482360SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4832680Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
4841458SN/A    {
485360SN/A        panic("Misc instruction does not support split access method!");
486360SN/A        return NoFault;
487360SN/A    }
488360SN/A}};
4891706SN/A
4901458SN/A
491360SN/Adef template MiscCompleteAcc {{
492360SN/A    Fault %(class_name)s::completeAcc(uint8_t *data,
4932680Sktlim@umich.edu                                      %(CPU_exec_context)s *xc,
4942680Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
495360SN/A    {
496360SN/A        panic("Misc instruction does not support split access method!");
497360SN/A
498360SN/A        return NoFault;
499360SN/A    }
500360SN/A}};
501360SN/A
502360SN/A// load instructions use Rt as dest, so check for
503360SN/A// Rt == 0 to detect nops
504360SN/Adef template LoadNopCheckDecode {{
505360SN/A {
506360SN/A     MipsStaticInst *i = new %(class_name)s(machInst);
5071706SN/A     if (RT == 0) {
508360SN/A         i = makeNop(i);
509360SN/A     }
510360SN/A     return i;
511360SN/A }
512360SN/A}};
5133669Sbinkertn@umich.edu
5143669Sbinkertn@umich.edudef format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
5153669Sbinkertn@umich.edu                     mem_flags = [], inst_flags = []) {{
5161706SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5171706SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
518360SN/A                      decode_template = LoadNopCheckDecode,
519360SN/A                      exec_template_base = 'Load')
520360SN/A}};
5211970SN/A
522360SN/Adef format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
523360SN/A                     mem_flags = [], inst_flags = []) {{
524360SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5251999SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5261999SN/A                      exec_template_base = 'Store')
5271999SN/A}};
5283114Sgblack@eecs.umich.edu
5292680Sktlim@umich.edudef format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
5301999SN/A                     mem_flags = [], inst_flags = []) {{
5311999SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5321999SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5332680Sktlim@umich.edu                      decode_template = LoadNopCheckDecode,
5341999SN/A                      exec_template_base = 'Load')
5351999SN/A}};
5362680Sktlim@umich.edu
5371999SN/Adef format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
5381999SN/A                     mem_flags = [], inst_flags = []) {{
5391999SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5401999SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5411999SN/A                      exec_template_base = 'Store')
5423669Sbinkertn@umich.edu}};
5433669Sbinkertn@umich.edu
5443669Sbinkertn@umich.edudef format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
5451999SN/A                     mem_flags = [], inst_flags = []) {{
5461999SN/A    decl_code = 'uint32_t mem_word = Mem.uw;\n'
5471999SN/A    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
5482218SN/A    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
5491999SN/A    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
5501999SN/A    decl_code += '\tbyte_offset ^= 3;\n'
5511999SN/A    decl_code += '#endif\n'
5521999SN/A
5531999SN/A    memacc_code = decl_code + memacc_code
5541999SN/A
5551999SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5561999SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5573114Sgblack@eecs.umich.edu                      decode_template = LoadNopCheckDecode,
5582680Sktlim@umich.edu                      exec_template_base = 'Load')
5591999SN/A}};
5602680Sktlim@umich.edu
5611999SN/Adef format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
5621999SN/A                     mem_flags = [], inst_flags = []) {{
5631999SN/A    decl_code = 'uint32_t mem_word = 0;\n'
5641999SN/A    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
5651999SN/A    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
5662680Sktlim@umich.edu    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
5671999SN/A    decl_code += '\tbyte_offset ^= 3;\n'
5681999SN/A    decl_code += '#endif\n'
5691999SN/A    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
5701999SN/A    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
5711999SN/A
5721999SN/A    (header_output, decoder_output, decode_block, exec_output) = \
5731999SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
5741999SN/A                      decode_template = LoadNopCheckDecode,
5752218SN/A                      exec_template_base = 'Store')
5761999SN/A}};
5771999SN/A
5781999SN/Adef format Prefetch(ea_code = {{ EA = Rs + disp; }},
5791999SN/A                          mem_flags = [], pf_flags = [], inst_flags = []) {{
5801999SN/A    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
581378SN/A    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
582360SN/A                                  'IsDataPrefetch', 'MemReadOp']
5831450SN/A
5843114Sgblack@eecs.umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
5852680Sktlim@umich.edu        LoadStoreBase(name, Name, ea_code,
586360SN/A                      'xc->prefetch(EA, memAccessFlags);',
587360SN/A                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
588360SN/A
5892680Sktlim@umich.edu}};
5902400SN/A
591360SN/Adef format StoreCond(memacc_code, postacc_code,
5923669Sbinkertn@umich.edu                     ea_code = {{ EA = Rs + disp; }},
5933669Sbinkertn@umich.edu                     mem_flags = [], inst_flags = []) {{
5943669Sbinkertn@umich.edu    (header_output, decoder_output, decode_block, exec_output) = \
595360SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
596360SN/A                      postacc_code, exec_template_base = 'Store')
597360SN/A}};
598360SN/A