mem.isa revision 8442
111308Santhony.gutierrez@amd.com// -*- mode:c++ -*-
211308Santhony.gutierrez@amd.com
311308Santhony.gutierrez@amd.com// Copyright (c) 2007 MIPS Technologies, Inc.
411308Santhony.gutierrez@amd.com// All rights reserved.
511308Santhony.gutierrez@amd.com//
611308Santhony.gutierrez@amd.com// Redistribution and use in source and binary forms, with or without
711308Santhony.gutierrez@amd.com// modification, are permitted provided that the following conditions are
811308Santhony.gutierrez@amd.com// met: redistributions of source code must retain the above copyright
911308Santhony.gutierrez@amd.com// notice, this list of conditions and the following disclaimer;
1011308Santhony.gutierrez@amd.com// redistributions in binary form must reproduce the above copyright
1111308Santhony.gutierrez@amd.com// notice, this list of conditions and the following disclaimer in the
1211308Santhony.gutierrez@amd.com// documentation and/or other materials provided with the distribution;
1311308Santhony.gutierrez@amd.com// neither the name of the copyright holders nor the names of its
1411308Santhony.gutierrez@amd.com// contributors may be used to endorse or promote products derived from
1511308Santhony.gutierrez@amd.com// this software without specific prior written permission.
1611308Santhony.gutierrez@amd.com//
1711308Santhony.gutierrez@amd.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1811308Santhony.gutierrez@amd.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1911308Santhony.gutierrez@amd.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2011308Santhony.gutierrez@amd.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2111308Santhony.gutierrez@amd.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2211308Santhony.gutierrez@amd.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2311308Santhony.gutierrez@amd.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2411308Santhony.gutierrez@amd.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2511308Santhony.gutierrez@amd.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2611308Santhony.gutierrez@amd.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2711308Santhony.gutierrez@amd.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2811308Santhony.gutierrez@amd.com//
2911308Santhony.gutierrez@amd.com// Authors: Steve Reinhardt
3011308Santhony.gutierrez@amd.com//          Korey Sewell
3111308Santhony.gutierrez@amd.com
3211308Santhony.gutierrez@amd.com////////////////////////////////////////////////////////////////////
3311308Santhony.gutierrez@amd.com//
3411308Santhony.gutierrez@amd.com// Memory-format instructions
3511308Santhony.gutierrez@amd.com//
3611308Santhony.gutierrez@amd.com
3711308Santhony.gutierrez@amd.comoutput header {{
3811308Santhony.gutierrez@amd.com    /**
3911308Santhony.gutierrez@amd.com     * Base class for general Mips memory-format instructions.
4011308Santhony.gutierrez@amd.com     */
4111308Santhony.gutierrez@amd.com    class Memory : public MipsStaticInst
4211308Santhony.gutierrez@amd.com    {
4311670Sandreas.hansson@arm.com      protected:
4411670Sandreas.hansson@arm.com        /// Memory request flags.  See mem_req_base.hh.
4511308Santhony.gutierrez@amd.com        Request::Flags memAccessFlags;
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.com        /// Displacement for EA calculation (signed).
4811308Santhony.gutierrez@amd.com        int32_t disp;
4911308Santhony.gutierrez@amd.com
5011308Santhony.gutierrez@amd.com        /// Constructor
5111308Santhony.gutierrez@amd.com        Memory(const char *mnem, MachInst _machInst, OpClass __opClass)
5211308Santhony.gutierrez@amd.com            : MipsStaticInst(mnem, _machInst, __opClass),
5311308Santhony.gutierrez@amd.com              disp(sext<16>(OFFSET))
5411308Santhony.gutierrez@amd.com        {
5511308Santhony.gutierrez@amd.com        }
5611308Santhony.gutierrez@amd.com
5711308Santhony.gutierrez@amd.com        std::string
5811308Santhony.gutierrez@amd.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
5911308Santhony.gutierrez@amd.com    };
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.com     /**
6211308Santhony.gutierrez@amd.com     * Base class for a few miscellaneous memory-format insts
6311308Santhony.gutierrez@amd.com     * that don't interpret the disp field
6411308Santhony.gutierrez@amd.com     */
6511308Santhony.gutierrez@amd.com    class MemoryNoDisp : public Memory
6611308Santhony.gutierrez@amd.com    {
6711308Santhony.gutierrez@amd.com      protected:
6811308Santhony.gutierrez@amd.com        /// Constructor
6911308Santhony.gutierrez@amd.com        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
7011308Santhony.gutierrez@amd.com            : Memory(mnem, _machInst, __opClass)
7111308Santhony.gutierrez@amd.com        {
7211308Santhony.gutierrez@amd.com        }
7311308Santhony.gutierrez@amd.com
7411308Santhony.gutierrez@amd.com        std::string
7511308Santhony.gutierrez@amd.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
7611308Santhony.gutierrez@amd.com    };
7711308Santhony.gutierrez@amd.com}};
7811308Santhony.gutierrez@amd.com
7911308Santhony.gutierrez@amd.com
8011308Santhony.gutierrez@amd.comoutput decoder {{
8111308Santhony.gutierrez@amd.com    std::string
8211308Santhony.gutierrez@amd.com    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
8311308Santhony.gutierrez@amd.com    {
8411308Santhony.gutierrez@amd.com        return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
8511308Santhony.gutierrez@amd.com                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
8611308Santhony.gutierrez@amd.com    }
8711308Santhony.gutierrez@amd.com
8811308Santhony.gutierrez@amd.com    std::string
8911308Santhony.gutierrez@amd.com    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
9011308Santhony.gutierrez@amd.com    {
9111308Santhony.gutierrez@amd.com        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
9211308Santhony.gutierrez@amd.com                        flags[IsFloating] ? 'f' : 'r',
9311308Santhony.gutierrez@amd.com                        flags[IsFloating] ? FD : RD,
9411308Santhony.gutierrez@amd.com                        RS, RT);
9511308Santhony.gutierrez@amd.com    }
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.com}};
9811308Santhony.gutierrez@amd.com
9911308Santhony.gutierrez@amd.comoutput exec {{
10011308Santhony.gutierrez@amd.com    /** return data in cases where there the size of data is only
10111308Santhony.gutierrez@amd.com        known in the packet
10211308Santhony.gutierrez@amd.com    */
10311308Santhony.gutierrez@amd.com    uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) {
10411308Santhony.gutierrez@amd.com        switch (packet->getSize())
10511308Santhony.gutierrez@amd.com        {
10611308Santhony.gutierrez@amd.com          case 1:
10711308Santhony.gutierrez@amd.com            return packet->get<uint8_t>();
10811308Santhony.gutierrez@amd.com
10911308Santhony.gutierrez@amd.com          case 2:
11011308Santhony.gutierrez@amd.com            return packet->get<uint16_t>();
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com          case 4:
11311308Santhony.gutierrez@amd.com            return packet->get<uint32_t>();
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.com          case 8:
11611308Santhony.gutierrez@amd.com            return packet->get<uint64_t>();
11711308Santhony.gutierrez@amd.com
11811308Santhony.gutierrez@amd.com          default:
11911308Santhony.gutierrez@amd.com            std::cerr << "bad store data size = " << packet->getSize() << std::endl;
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.com            assert(0);
12211308Santhony.gutierrez@amd.com            return 0;
12311308Santhony.gutierrez@amd.com        }
12411308Santhony.gutierrez@amd.com    }
12511308Santhony.gutierrez@amd.com
12611308Santhony.gutierrez@amd.com
12711308Santhony.gutierrez@amd.com}};
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.comdef template LoadStoreDeclare {{
13011308Santhony.gutierrez@amd.com    /**
13111308Santhony.gutierrez@amd.com     * Static instruction class for "%(mnemonic)s".
13211308Santhony.gutierrez@amd.com     */
13311308Santhony.gutierrez@amd.com    class %(class_name)s : public %(base_class)s
13411308Santhony.gutierrez@amd.com    {
13511308Santhony.gutierrez@amd.com      public:
13611308Santhony.gutierrez@amd.com
13711308Santhony.gutierrez@amd.com        /// Constructor.
13811308Santhony.gutierrez@amd.com        %(class_name)s(ExtMachInst machInst);
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.com        %(BasicExecDeclare)s
14111308Santhony.gutierrez@amd.com
14211308Santhony.gutierrez@amd.com        %(EACompDeclare)s
14311308Santhony.gutierrez@amd.com
14411308Santhony.gutierrez@amd.com        %(InitiateAccDeclare)s
14511308Santhony.gutierrez@amd.com
14611308Santhony.gutierrez@amd.com        %(CompleteAccDeclare)s
14711308Santhony.gutierrez@amd.com    };
14811308Santhony.gutierrez@amd.com}};
14911308Santhony.gutierrez@amd.com
15011308Santhony.gutierrez@amd.comdef template EACompDeclare {{
15111308Santhony.gutierrez@amd.com    Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
15211308Santhony.gutierrez@amd.com}};
15311308Santhony.gutierrez@amd.com
15411308Santhony.gutierrez@amd.comdef template InitiateAccDeclare {{
15511308Santhony.gutierrez@amd.com    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
15611308Santhony.gutierrez@amd.com}};
15711308Santhony.gutierrez@amd.com
15811308Santhony.gutierrez@amd.com
15911308Santhony.gutierrez@amd.comdef template CompleteAccDeclare {{
16011308Santhony.gutierrez@amd.com    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
16111308Santhony.gutierrez@amd.com}};
16211308Santhony.gutierrez@amd.com
16311308Santhony.gutierrez@amd.comdef template LoadStoreConstructor {{
16411308Santhony.gutierrez@amd.com    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
16511308Santhony.gutierrez@amd.com         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
16611308Santhony.gutierrez@amd.com    {
16711308Santhony.gutierrez@amd.com        %(constructor)s;
16811308Santhony.gutierrez@amd.com    }
16911308Santhony.gutierrez@amd.com}};
17011308Santhony.gutierrez@amd.com
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.comdef template EACompExecute {{
17311308Santhony.gutierrez@amd.com    Fault
17411308Santhony.gutierrez@amd.com    %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
17511308Santhony.gutierrez@amd.com                                   Trace::InstRecord *traceData) const
17611308Santhony.gutierrez@amd.com    {
17711308Santhony.gutierrez@amd.com        Addr EA;
17811308Santhony.gutierrez@amd.com        Fault fault = NoFault;
17911308Santhony.gutierrez@amd.com
18011308Santhony.gutierrez@amd.com        if (this->isFloating()) {
18111308Santhony.gutierrez@amd.com            %(fp_enable_check)s;
18211308Santhony.gutierrez@amd.com
18311308Santhony.gutierrez@amd.com            if(fault != NoFault)
18411308Santhony.gutierrez@amd.com                return fault;
18511308Santhony.gutierrez@amd.com        }
18611308Santhony.gutierrez@amd.com
18711308Santhony.gutierrez@amd.com        %(op_decl)s;
18811308Santhony.gutierrez@amd.com        %(op_rd)s;
18911308Santhony.gutierrez@amd.com        %(ea_code)s;
19011308Santhony.gutierrez@amd.com
19111308Santhony.gutierrez@amd.com        // NOTE: Trace Data is written using execute or completeAcc templates
19211308Santhony.gutierrez@amd.com        if (fault == NoFault) {
19311308Santhony.gutierrez@amd.com            xc->setEA(EA);
19411308Santhony.gutierrez@amd.com        }
19511308Santhony.gutierrez@amd.com
19611308Santhony.gutierrez@amd.com        return fault;
19711308Santhony.gutierrez@amd.com    }
19811308Santhony.gutierrez@amd.com}};
19911308Santhony.gutierrez@amd.com
20011308Santhony.gutierrez@amd.comdef template LoadExecute {{
20111308Santhony.gutierrez@amd.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
20211308Santhony.gutierrez@amd.com                                  Trace::InstRecord *traceData) const
20311308Santhony.gutierrez@amd.com    {
20411308Santhony.gutierrez@amd.com        Addr EA;
20511308Santhony.gutierrez@amd.com        Fault fault = NoFault;
20611308Santhony.gutierrez@amd.com
20711308Santhony.gutierrez@amd.com        if (this->isFloating()) {
20811308Santhony.gutierrez@amd.com            %(fp_enable_check)s;
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com            if(fault != NoFault)
21111308Santhony.gutierrez@amd.com                return fault;
21211308Santhony.gutierrez@amd.com        }
21311308Santhony.gutierrez@amd.com
21411308Santhony.gutierrez@amd.com        %(op_decl)s;
21511308Santhony.gutierrez@amd.com        %(op_rd)s;
21611308Santhony.gutierrez@amd.com        %(ea_code)s;
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com        if (fault == NoFault) {
21911308Santhony.gutierrez@amd.com            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
22011308Santhony.gutierrez@amd.com            %(memacc_code)s;
22111308Santhony.gutierrez@amd.com        }
22211308Santhony.gutierrez@amd.com
22311308Santhony.gutierrez@amd.com        if (fault == NoFault) {
22411308Santhony.gutierrez@amd.com            %(op_wb)s;
22511308Santhony.gutierrez@amd.com        }
22611308Santhony.gutierrez@amd.com
22711308Santhony.gutierrez@amd.com        return fault;
22811308Santhony.gutierrez@amd.com    }
22911308Santhony.gutierrez@amd.com}};
23011308Santhony.gutierrez@amd.com
23111308Santhony.gutierrez@amd.com
23211308Santhony.gutierrez@amd.comdef template LoadInitiateAcc {{
23311308Santhony.gutierrez@amd.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
23411308Santhony.gutierrez@amd.com                                      Trace::InstRecord *traceData) const
23511308Santhony.gutierrez@amd.com    {
23611308Santhony.gutierrez@amd.com        Addr EA;
23711308Santhony.gutierrez@amd.com        Fault fault = NoFault;
23811308Santhony.gutierrez@amd.com
23911308Santhony.gutierrez@amd.com        if (this->isFloating()) {
24011308Santhony.gutierrez@amd.com            %(fp_enable_check)s;
24111308Santhony.gutierrez@amd.com
24211308Santhony.gutierrez@amd.com            if(fault != NoFault)
24311308Santhony.gutierrez@amd.com                return fault;
24411308Santhony.gutierrez@amd.com        }
24511308Santhony.gutierrez@amd.com
24611308Santhony.gutierrez@amd.com        %(op_src_decl)s;
24711308Santhony.gutierrez@amd.com        %(op_rd)s;
24811308Santhony.gutierrez@amd.com        %(ea_code)s;
24911308Santhony.gutierrez@amd.com
25011308Santhony.gutierrez@amd.com        if (fault == NoFault) {
25111308Santhony.gutierrez@amd.com            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
25211308Santhony.gutierrez@amd.com        }
25311308Santhony.gutierrez@amd.com
25411308Santhony.gutierrez@amd.com        return fault;
25511308Santhony.gutierrez@amd.com    }
25611308Santhony.gutierrez@amd.com}};
25711308Santhony.gutierrez@amd.com
25811308Santhony.gutierrez@amd.comdef template LoadCompleteAcc {{
25911308Santhony.gutierrez@amd.com    Fault %(class_name)s::completeAcc(Packet *pkt,
26011308Santhony.gutierrez@amd.com                                      %(CPU_exec_context)s *xc,
26111308Santhony.gutierrez@amd.com                                      Trace::InstRecord *traceData) const
26211308Santhony.gutierrez@amd.com    {
26311308Santhony.gutierrez@amd.com        Fault fault = NoFault;
26411308Santhony.gutierrez@amd.com
26511308Santhony.gutierrez@amd.com        if (this->isFloating()) {
26611308Santhony.gutierrez@amd.com            %(fp_enable_check)s;
26711308Santhony.gutierrez@amd.com
26811308Santhony.gutierrez@amd.com            if(fault != NoFault)
26911308Santhony.gutierrez@amd.com                return fault;
27011308Santhony.gutierrez@amd.com        }
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.com        %(op_decl)s;
27311308Santhony.gutierrez@amd.com        %(op_rd)s;
27411308Santhony.gutierrez@amd.com
27511308Santhony.gutierrez@amd.com        getMem(pkt, Mem, traceData);
27611308Santhony.gutierrez@amd.com
27711308Santhony.gutierrez@amd.com        if (fault == NoFault) {
27811308Santhony.gutierrez@amd.com            %(memacc_code)s;
27911308Santhony.gutierrez@amd.com        }
28011308Santhony.gutierrez@amd.com
28111308Santhony.gutierrez@amd.com        if (fault == NoFault) {
28211308Santhony.gutierrez@amd.com            %(op_wb)s;
28311308Santhony.gutierrez@amd.com        }
28411308Santhony.gutierrez@amd.com
28511308Santhony.gutierrez@amd.com        return fault;
28611308Santhony.gutierrez@amd.com    }
28711308Santhony.gutierrez@amd.com}};
28811308Santhony.gutierrez@amd.com
28911308Santhony.gutierrez@amd.comdef template StoreExecute {{
29011308Santhony.gutierrez@amd.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
29111308Santhony.gutierrez@amd.com                                  Trace::InstRecord *traceData) const
29211308Santhony.gutierrez@amd.com    {
29311308Santhony.gutierrez@amd.com        Addr EA;
29411308Santhony.gutierrez@amd.com        Fault fault = NoFault;
29511308Santhony.gutierrez@amd.com
29611308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
29711308Santhony.gutierrez@amd.com        %(op_decl)s;
29811308Santhony.gutierrez@amd.com        %(op_rd)s;
29911308Santhony.gutierrez@amd.com        %(ea_code)s;
30011308Santhony.gutierrez@amd.com
30111308Santhony.gutierrez@amd.com        if (fault == NoFault) {
30211308Santhony.gutierrez@amd.com            %(memacc_code)s;
30311308Santhony.gutierrez@amd.com        }
30411308Santhony.gutierrez@amd.com
30511308Santhony.gutierrez@amd.com        if (fault == NoFault) {
30611308Santhony.gutierrez@amd.com            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
30711308Santhony.gutierrez@amd.com                    NULL);
30811308Santhony.gutierrez@amd.com        }
30911308Santhony.gutierrez@amd.com
31011308Santhony.gutierrez@amd.com        if (fault == NoFault) {
31111308Santhony.gutierrez@amd.com            %(postacc_code)s;
31211308Santhony.gutierrez@amd.com        }
31311308Santhony.gutierrez@amd.com
31411308Santhony.gutierrez@amd.com        if (fault == NoFault) {
31511308Santhony.gutierrez@amd.com            %(op_wb)s;
31611308Santhony.gutierrez@amd.com        }
31711308Santhony.gutierrez@amd.com
31811308Santhony.gutierrez@amd.com        return fault;
31911308Santhony.gutierrez@amd.com    }
32011308Santhony.gutierrez@amd.com}};
32111308Santhony.gutierrez@amd.com
32211308Santhony.gutierrez@amd.com
32311308Santhony.gutierrez@amd.comdef template StoreFPExecute {{
32411308Santhony.gutierrez@amd.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
32511308Santhony.gutierrez@amd.com                                  Trace::InstRecord *traceData) const
32611308Santhony.gutierrez@amd.com    {
327        Addr EA;
328        Fault fault = NoFault;
329
330        %(fp_enable_check)s;
331        if(fault != NoFault)
332          return fault;
333        %(op_decl)s;
334        %(op_rd)s;
335        %(ea_code)s;
336
337        if (fault == NoFault) {
338            %(memacc_code)s;
339        }
340
341        if (fault == NoFault) {
342            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
343                    NULL);
344        }
345
346        if (fault == NoFault) {
347            %(postacc_code)s;
348        }
349
350        if (fault == NoFault) {
351            %(op_wb)s;
352        }
353
354        return fault;
355    }
356}};
357
358def template StoreCondExecute {{
359    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
360                                  Trace::InstRecord *traceData) const
361    {
362        Addr EA;
363        Fault fault = NoFault;
364        uint64_t write_result = 0;
365
366        %(fp_enable_check)s;
367        %(op_decl)s;
368        %(op_rd)s;
369        %(ea_code)s;
370
371        if (fault == NoFault) {
372            %(memacc_code)s;
373        }
374
375        if (fault == NoFault) {
376            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
377                    &write_result);
378        }
379
380        if (fault == NoFault) {
381            %(postacc_code)s;
382        }
383
384        if (fault == NoFault) {
385            %(op_wb)s;
386        }
387
388        return fault;
389    }
390}};
391
392def template StoreInitiateAcc {{
393    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
394                                      Trace::InstRecord *traceData) const
395    {
396        Addr EA;
397        Fault fault = NoFault;
398
399        %(fp_enable_check)s;
400        %(op_decl)s;
401        %(op_rd)s;
402        %(ea_code)s;
403
404        if (fault == NoFault) {
405            %(memacc_code)s;
406        }
407
408        if (fault == NoFault) {
409            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
410                    NULL);
411        }
412
413        return fault;
414    }
415}};
416
417
418def template StoreCompleteAcc {{
419    Fault %(class_name)s::completeAcc(Packet *pkt,
420                                      %(CPU_exec_context)s *xc,
421                                      Trace::InstRecord *traceData) const
422    {
423        return NoFault;
424    }
425}};
426
427def template StoreCondCompleteAcc {{
428    Fault %(class_name)s::completeAcc(Packet *pkt,
429                                      %(CPU_exec_context)s *xc,
430                                      Trace::InstRecord *traceData) const
431    {
432        Fault fault = NoFault;
433
434        %(fp_enable_check)s;
435        %(op_dest_decl)s;
436
437        uint64_t write_result = pkt->req->getExtraData();
438
439        if (fault == NoFault) {
440            %(postacc_code)s;
441        }
442
443        if (fault == NoFault) {
444            %(op_wb)s;
445        }
446
447        return fault;
448    }
449}};
450
451def template MiscExecute {{
452    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
453                                  Trace::InstRecord *traceData) const
454    {
455        Addr EA M5_VAR_USED = 0;
456        Fault fault = NoFault;
457
458        %(fp_enable_check)s;
459        %(op_decl)s;
460        %(op_rd)s;
461        %(ea_code)s;
462
463        if (fault == NoFault) {
464            %(memacc_code)s;
465        }
466
467        return NoFault;
468    }
469}};
470
471def template MiscInitiateAcc {{
472    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
473                                      Trace::InstRecord *traceData) const
474    {
475        panic("Misc instruction does not support split access method!");
476        return NoFault;
477    }
478}};
479
480
481def template MiscCompleteAcc {{
482    Fault %(class_name)s::completeAcc(Packet *pkt,
483                                      %(CPU_exec_context)s *xc,
484                                      Trace::InstRecord *traceData) const
485    {
486        panic("Misc instruction does not support split access method!");
487
488        return NoFault;
489    }
490}};
491
492def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
493                     mem_flags = [], inst_flags = []) {{
494    (header_output, decoder_output, decode_block, exec_output) = \
495        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
496                      decode_template = ImmNopCheckDecode,
497                      exec_template_base = 'Load')
498}};
499
500
501def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
502                     mem_flags = [], inst_flags = []) {{
503    (header_output, decoder_output, decode_block, exec_output) = \
504        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
505                      exec_template_base = 'Store')
506}};
507
508def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
509                     mem_flags = [], inst_flags = []) {{
510    inst_flags += ['IsIndexed']
511    (header_output, decoder_output, decode_block, exec_output) = \
512        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
513                      decode_template = ImmNopCheckDecode,
514                      exec_template_base = 'Load')
515}};
516
517def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
518                     mem_flags = [], inst_flags = []) {{
519    inst_flags += ['IsIndexed']
520    (header_output, decoder_output, decode_block, exec_output) = \
521        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
522                      exec_template_base = 'Store')
523}};
524
525def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
526                     mem_flags = [], inst_flags = []) {{
527    inst_flags += ['IsIndexed', 'IsFloating']
528    (header_output, decoder_output, decode_block, exec_output) = \
529        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
530                      decode_template = ImmNopCheckDecode,
531                      exec_template_base = 'Load')
532}};
533
534def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
535                     mem_flags = [], inst_flags = []) {{
536    inst_flags += ['IsIndexed', 'IsFloating']
537    (header_output, decoder_output, decode_block, exec_output) = \
538        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
539                      exec_template_base = 'Store')
540}};
541
542
543def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
544                     mem_flags = [], inst_flags = []) {{
545    decl_code = 'uint32_t mem_word = Mem.uw;\n'
546    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
547    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
548    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
549    decl_code += '\tbyte_offset ^= 3;\n'
550    decl_code += '#endif\n'
551
552    memacc_code = decl_code + memacc_code
553
554    (header_output, decoder_output, decode_block, exec_output) = \
555        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
556                      decode_template = ImmNopCheckDecode,
557                      exec_template_base = 'Load')
558}};
559
560def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
561                     mem_flags = [], inst_flags = []) {{
562    decl_code = '''
563        uint32_t mem_word = 0;
564        uint32_t unaligned_addr = Rs + disp;
565        uint32_t byte_offset = unaligned_addr & 3;
566        #if BYTE_ORDER == BIG_ENDIAN
567            byte_offset ^= 3;
568        #endif
569        fault = readMemAtomic(xc, traceData, EA, mem_word, memAccessFlags);
570    '''
571    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
572
573    (header_output, decoder_output, decode_block, exec_output) = \
574        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
575                      exec_template_base = 'Store')
576}};
577
578def format Prefetch(ea_code = {{ EA = Rs + disp; }},
579                          mem_flags = [], pf_flags = [], inst_flags = []) {{
580    pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
581    pf_inst_flags = inst_flags
582
583    (header_output, decoder_output, decode_block, exec_output) = \
584        LoadStoreBase(name, Name, ea_code,
585                      'warn_once("Prefetching not implemented for MIPS\\n");',
586                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
587
588}};
589
590def format StoreCond(memacc_code, postacc_code,
591                     ea_code = {{ EA = Rs + disp; }},
592                     mem_flags = [], inst_flags = []) {{
593    (header_output, decoder_output, decode_block, exec_output) = \
594        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
595                      postacc_code, exec_template_base = 'StoreCond')
596}};
597