mem.isa revision 8607
111308Santhony.gutierrez@amd.com// -*- mode:c++ -*-
211308Santhony.gutierrez@amd.com
311308Santhony.gutierrez@amd.com// Copyright (c) 2003-2005 The Regents of The University of Michigan
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//          Kevin Lim
3111308Santhony.gutierrez@amd.com
3211308Santhony.gutierrez@amd.com////////////////////////////////////////////////////////////////////
3311308Santhony.gutierrez@amd.com//
3411308Santhony.gutierrez@amd.com// Memory-format instructions: LoadAddress, Load, Store
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 Alpha memory-format instructions.
4011308Santhony.gutierrez@amd.com     */
4111308Santhony.gutierrez@amd.com    class Memory : public AlphaStaticInst
4211308Santhony.gutierrez@amd.com    {
4311670Sandreas.hansson@arm.com      protected:
4411670Sandreas.hansson@arm.com
4511308Santhony.gutierrez@amd.com        /// Memory request flags.  See mem_req_base.hh.
4611308Santhony.gutierrez@amd.com        Request::Flags memAccessFlags;
4711308Santhony.gutierrez@amd.com
4811308Santhony.gutierrez@amd.com        /// Constructor
4911308Santhony.gutierrez@amd.com        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
5011308Santhony.gutierrez@amd.com            : AlphaStaticInst(mnem, _machInst, __opClass)
5111308Santhony.gutierrez@amd.com        {
5211308Santhony.gutierrez@amd.com        }
5311308Santhony.gutierrez@amd.com
5411308Santhony.gutierrez@amd.com        std::string
5511308Santhony.gutierrez@amd.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
5611308Santhony.gutierrez@amd.com    };
5711308Santhony.gutierrez@amd.com
5811308Santhony.gutierrez@amd.com    /**
5911308Santhony.gutierrez@amd.com     * Base class for memory-format instructions using a 32-bit
6011308Santhony.gutierrez@amd.com     * displacement (i.e. most of them).
6111308Santhony.gutierrez@amd.com     */
6211308Santhony.gutierrez@amd.com    class MemoryDisp32 : public Memory
6311308Santhony.gutierrez@amd.com    {
6411308Santhony.gutierrez@amd.com      protected:
6511308Santhony.gutierrez@amd.com        /// Displacement for EA calculation (signed).
6611308Santhony.gutierrez@amd.com        int32_t disp;
6711308Santhony.gutierrez@amd.com
6811308Santhony.gutierrez@amd.com        /// Constructor.
6911308Santhony.gutierrez@amd.com        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
7011308Santhony.gutierrez@amd.com            : Memory(mnem, _machInst, __opClass),
7111308Santhony.gutierrez@amd.com              disp(MEMDISP)
7211308Santhony.gutierrez@amd.com        {
7311308Santhony.gutierrez@amd.com        }
7411308Santhony.gutierrez@amd.com    };
7511308Santhony.gutierrez@amd.com
7611308Santhony.gutierrez@amd.com
7711308Santhony.gutierrez@amd.com    /**
7811308Santhony.gutierrez@amd.com     * Base class for a few miscellaneous memory-format insts
7911308Santhony.gutierrez@amd.com     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
8011308Santhony.gutierrez@amd.com     * None of these instructions has a destination register either.
8111308Santhony.gutierrez@amd.com     */
8211308Santhony.gutierrez@amd.com    class MemoryNoDisp : public Memory
8311308Santhony.gutierrez@amd.com    {
8411308Santhony.gutierrez@amd.com      protected:
8511308Santhony.gutierrez@amd.com        /// Constructor
8611308Santhony.gutierrez@amd.com        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
8711308Santhony.gutierrez@amd.com            : Memory(mnem, _machInst, __opClass)
8811308Santhony.gutierrez@amd.com        {
8911308Santhony.gutierrez@amd.com        }
9011308Santhony.gutierrez@amd.com
9111308Santhony.gutierrez@amd.com        std::string
9211308Santhony.gutierrez@amd.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
9311308Santhony.gutierrez@amd.com    };
9411308Santhony.gutierrez@amd.com}};
9511308Santhony.gutierrez@amd.com
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.comoutput decoder {{
9811308Santhony.gutierrez@amd.com    std::string
9911308Santhony.gutierrez@amd.com    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
10011308Santhony.gutierrez@amd.com    {
10111308Santhony.gutierrez@amd.com        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
10211308Santhony.gutierrez@amd.com                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
10311308Santhony.gutierrez@amd.com    }
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.com    std::string
10611308Santhony.gutierrez@amd.com    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
10711308Santhony.gutierrez@amd.com    {
10811308Santhony.gutierrez@amd.com        return csprintf("%-10s (r%d)", mnemonic, RB);
10911308Santhony.gutierrez@amd.com    }
11011308Santhony.gutierrez@amd.com}};
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.comdef format LoadAddress(code) {{
11311308Santhony.gutierrez@amd.com    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
11411308Santhony.gutierrez@amd.com    header_output = BasicDeclare.subst(iop)
11511308Santhony.gutierrez@amd.com    decoder_output = BasicConstructor.subst(iop)
11611308Santhony.gutierrez@amd.com    decode_block = BasicDecode.subst(iop)
11711308Santhony.gutierrez@amd.com    exec_output = BasicExecute.subst(iop)
11811308Santhony.gutierrez@amd.com}};
11911308Santhony.gutierrez@amd.com
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.comdef template LoadStoreDeclare {{
12211308Santhony.gutierrez@amd.com    /**
12311308Santhony.gutierrez@amd.com     * Static instruction class for "%(mnemonic)s".
12411308Santhony.gutierrez@amd.com     */
12511308Santhony.gutierrez@amd.com    class %(class_name)s : public %(base_class)s
12611308Santhony.gutierrez@amd.com    {
12711308Santhony.gutierrez@amd.com      public:
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.com        /// Constructor.
13011308Santhony.gutierrez@amd.com        %(class_name)s(ExtMachInst machInst);
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.com        %(BasicExecDeclare)s
13311308Santhony.gutierrez@amd.com
13411308Santhony.gutierrez@amd.com        %(EACompDeclare)s
13511308Santhony.gutierrez@amd.com
13611308Santhony.gutierrez@amd.com        %(InitiateAccDeclare)s
13711308Santhony.gutierrez@amd.com
13811308Santhony.gutierrez@amd.com        %(CompleteAccDeclare)s
13911308Santhony.gutierrez@amd.com    };
14011308Santhony.gutierrez@amd.com}};
14111308Santhony.gutierrez@amd.com
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.comdef template EACompDeclare {{
14411308Santhony.gutierrez@amd.com    Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
14511308Santhony.gutierrez@amd.com}};
14611308Santhony.gutierrez@amd.com
14711308Santhony.gutierrez@amd.comdef template InitiateAccDeclare {{
14811308Santhony.gutierrez@amd.com    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
14911308Santhony.gutierrez@amd.com}};
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com
15211308Santhony.gutierrez@amd.comdef template CompleteAccDeclare {{
15311308Santhony.gutierrez@amd.com    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
15411308Santhony.gutierrez@amd.com                      Trace::InstRecord *) const;
15511308Santhony.gutierrez@amd.com}};
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.comdef template LoadStoreConstructor {{
15811308Santhony.gutierrez@amd.com    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
15911308Santhony.gutierrez@amd.com         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
16011308Santhony.gutierrez@amd.com    {
16111308Santhony.gutierrez@amd.com        %(constructor)s;
16211308Santhony.gutierrez@amd.com    }
16311308Santhony.gutierrez@amd.com}};
16411308Santhony.gutierrez@amd.com
16511308Santhony.gutierrez@amd.comdef template EACompExecute {{
16611308Santhony.gutierrez@amd.com    Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
16711308Santhony.gutierrez@amd.com                                  Trace::InstRecord *traceData) const
16811308Santhony.gutierrez@amd.com    {
16911308Santhony.gutierrez@amd.com        Addr EA;
17012065Snikos.nikoleris@arm.com        Fault fault = NoFault;
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
17311308Santhony.gutierrez@amd.com        %(op_decl)s;
17411308Santhony.gutierrez@amd.com        %(op_rd)s;
17512065Snikos.nikoleris@arm.com        %(ea_code)s;
17612065Snikos.nikoleris@arm.com
17711308Santhony.gutierrez@amd.com        if (fault == NoFault) {
17811308Santhony.gutierrez@amd.com            %(op_wb)s;
17911308Santhony.gutierrez@amd.com            xc->setEA(EA);
18011308Santhony.gutierrez@amd.com        }
18111308Santhony.gutierrez@amd.com
18211308Santhony.gutierrez@amd.com        return fault;
18311308Santhony.gutierrez@amd.com    }
18411308Santhony.gutierrez@amd.com}};
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com
18711308Santhony.gutierrez@amd.comdef template LoadExecute {{
18811308Santhony.gutierrez@amd.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
18911308Santhony.gutierrez@amd.com                                  Trace::InstRecord *traceData) const
19011308Santhony.gutierrez@amd.com    {
19111308Santhony.gutierrez@amd.com        Addr EA;
19211308Santhony.gutierrez@amd.com        Fault fault = NoFault;
19311308Santhony.gutierrez@amd.com
19411308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
19511308Santhony.gutierrez@amd.com        %(op_decl)s;
19611308Santhony.gutierrez@amd.com        %(op_rd)s;
19711308Santhony.gutierrez@amd.com        %(ea_code)s;
19811308Santhony.gutierrez@amd.com
19911308Santhony.gutierrez@amd.com        if (fault == NoFault) {
20011308Santhony.gutierrez@amd.com            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
20111308Santhony.gutierrez@amd.com            %(memacc_code)s;
20211308Santhony.gutierrez@amd.com        }
20311308Santhony.gutierrez@amd.com
20411308Santhony.gutierrez@amd.com        if (fault == NoFault) {
20511308Santhony.gutierrez@amd.com            %(op_wb)s;
20611308Santhony.gutierrez@amd.com        }
20711308Santhony.gutierrez@amd.com
20811308Santhony.gutierrez@amd.com        return fault;
20911308Santhony.gutierrez@amd.com    }
21011308Santhony.gutierrez@amd.com}};
21111308Santhony.gutierrez@amd.com
21212598Snikos.nikoleris@arm.com
21312598Snikos.nikoleris@arm.comdef template LoadInitiateAcc {{
21411308Santhony.gutierrez@amd.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
21511308Santhony.gutierrez@amd.com                                      Trace::InstRecord *traceData) const
21611308Santhony.gutierrez@amd.com    {
21711308Santhony.gutierrez@amd.com        Addr EA;
21811308Santhony.gutierrez@amd.com        Fault fault = NoFault;
21911308Santhony.gutierrez@amd.com
22011308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
22111308Santhony.gutierrez@amd.com        %(op_src_decl)s;
22211308Santhony.gutierrez@amd.com        %(op_rd)s;
22311308Santhony.gutierrez@amd.com        %(ea_code)s;
22411308Santhony.gutierrez@amd.com
22511308Santhony.gutierrez@amd.com        if (fault == NoFault) {
22611308Santhony.gutierrez@amd.com            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
22711308Santhony.gutierrez@amd.com        }
22811308Santhony.gutierrez@amd.com
22911308Santhony.gutierrez@amd.com        return fault;
23011308Santhony.gutierrez@amd.com    }
23111308Santhony.gutierrez@amd.com}};
23211308Santhony.gutierrez@amd.com
23311308Santhony.gutierrez@amd.com
23411308Santhony.gutierrez@amd.comdef template LoadCompleteAcc {{
23511308Santhony.gutierrez@amd.com    Fault %(class_name)s::completeAcc(PacketPtr pkt,
23611308Santhony.gutierrez@amd.com                                      %(CPU_exec_context)s *xc,
23711308Santhony.gutierrez@amd.com                                      Trace::InstRecord *traceData) const
23811308Santhony.gutierrez@amd.com    {
23912065Snikos.nikoleris@arm.com        Fault fault = NoFault;
24012065Snikos.nikoleris@arm.com
24112065Snikos.nikoleris@arm.com        %(fp_enable_check)s;
24212065Snikos.nikoleris@arm.com        %(op_decl)s;
24312065Snikos.nikoleris@arm.com
24412065Snikos.nikoleris@arm.com        getMem(pkt, Mem, traceData);
24512065Snikos.nikoleris@arm.com
24612065Snikos.nikoleris@arm.com        if (fault == NoFault) {
24712065Snikos.nikoleris@arm.com            %(memacc_code)s;
24812065Snikos.nikoleris@arm.com        }
24912065Snikos.nikoleris@arm.com
25011308Santhony.gutierrez@amd.com        if (fault == NoFault) {
25112065Snikos.nikoleris@arm.com            %(op_wb)s;
25212065Snikos.nikoleris@arm.com        }
25312065Snikos.nikoleris@arm.com
25412065Snikos.nikoleris@arm.com        return fault;
25512065Snikos.nikoleris@arm.com    }
25612065Snikos.nikoleris@arm.com}};
25712065Snikos.nikoleris@arm.com
25812065Snikos.nikoleris@arm.com
25911308Santhony.gutierrez@amd.comdef template StoreExecute {{
26011308Santhony.gutierrez@amd.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
26112065Snikos.nikoleris@arm.com                                  Trace::InstRecord *traceData) const
26211308Santhony.gutierrez@amd.com    {
26311308Santhony.gutierrez@amd.com        Addr EA;
26411308Santhony.gutierrez@amd.com        Fault fault = NoFault;
26511308Santhony.gutierrez@amd.com
26611308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
26711308Santhony.gutierrez@amd.com        %(op_decl)s;
26811308Santhony.gutierrez@amd.com        %(op_rd)s;
26911308Santhony.gutierrez@amd.com        %(ea_code)s;
27011308Santhony.gutierrez@amd.com
27111308Santhony.gutierrez@amd.com        if (fault == NoFault) {
27211308Santhony.gutierrez@amd.com            %(memacc_code)s;
27311308Santhony.gutierrez@amd.com        }
27411308Santhony.gutierrez@amd.com
27511308Santhony.gutierrez@amd.com        if (fault == NoFault) {
27611308Santhony.gutierrez@amd.com            fault = writeMemAtomic(xc, traceData, Mem, EA,
27711308Santhony.gutierrez@amd.com                    memAccessFlags, NULL);
27811308Santhony.gutierrez@amd.com        }
27911308Santhony.gutierrez@amd.com
28011308Santhony.gutierrez@amd.com        if (fault == NoFault) {
28111308Santhony.gutierrez@amd.com            %(postacc_code)s;
28211308Santhony.gutierrez@amd.com        }
28311308Santhony.gutierrez@amd.com
28411308Santhony.gutierrez@amd.com        if (fault == NoFault) {
28511308Santhony.gutierrez@amd.com            %(op_wb)s;
28611308Santhony.gutierrez@amd.com        }
28711308Santhony.gutierrez@amd.com
28811308Santhony.gutierrez@amd.com        return fault;
28911308Santhony.gutierrez@amd.com    }
29011308Santhony.gutierrez@amd.com}};
29111308Santhony.gutierrez@amd.com
29211308Santhony.gutierrez@amd.comdef template StoreCondExecute {{
29311308Santhony.gutierrez@amd.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
29411308Santhony.gutierrez@amd.com                                  Trace::InstRecord *traceData) const
29511308Santhony.gutierrez@amd.com    {
29611308Santhony.gutierrez@amd.com        Addr EA;
29711308Santhony.gutierrez@amd.com        Fault fault = NoFault;
29811308Santhony.gutierrez@amd.com        uint64_t write_result = 0;
29911308Santhony.gutierrez@amd.com
30011308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
30111308Santhony.gutierrez@amd.com        %(op_decl)s;
30211308Santhony.gutierrez@amd.com        %(op_rd)s;
30311308Santhony.gutierrez@amd.com        %(ea_code)s;
30411308Santhony.gutierrez@amd.com
30511308Santhony.gutierrez@amd.com        if (fault == NoFault) {
30611308Santhony.gutierrez@amd.com            %(memacc_code)s;
30711308Santhony.gutierrez@amd.com        }
30811308Santhony.gutierrez@amd.com
30911308Santhony.gutierrez@amd.com        if (fault == NoFault) {
31011308Santhony.gutierrez@amd.com            fault = writeMemAtomic(xc, traceData, Mem, EA,
31111308Santhony.gutierrez@amd.com                    memAccessFlags, &write_result);
31211308Santhony.gutierrez@amd.com        }
31311308Santhony.gutierrez@amd.com
31411308Santhony.gutierrez@amd.com        if (fault == NoFault) {
31511308Santhony.gutierrez@amd.com            %(postacc_code)s;
31611308Santhony.gutierrez@amd.com        }
31711308Santhony.gutierrez@amd.com
31811308Santhony.gutierrez@amd.com        if (fault == NoFault) {
31911308Santhony.gutierrez@amd.com            %(op_wb)s;
32011308Santhony.gutierrez@amd.com        }
32111308Santhony.gutierrez@amd.com
32211308Santhony.gutierrez@amd.com        return fault;
32311308Santhony.gutierrez@amd.com    }
32411308Santhony.gutierrez@amd.com}};
32511308Santhony.gutierrez@amd.com
32611308Santhony.gutierrez@amd.comdef template StoreInitiateAcc {{
32711308Santhony.gutierrez@amd.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
32811308Santhony.gutierrez@amd.com                                      Trace::InstRecord *traceData) const
32911308Santhony.gutierrez@amd.com    {
33011308Santhony.gutierrez@amd.com        Addr EA;
33111308Santhony.gutierrez@amd.com        Fault fault = NoFault;
33211308Santhony.gutierrez@amd.com
33311308Santhony.gutierrez@amd.com        %(fp_enable_check)s;
33411308Santhony.gutierrez@amd.com        %(op_decl)s;
33511308Santhony.gutierrez@amd.com        %(op_rd)s;
33611308Santhony.gutierrez@amd.com        %(ea_code)s;
337
338        if (fault == NoFault) {
339            %(memacc_code)s;
340        }
341
342        if (fault == NoFault) {
343            fault = writeMemTiming(xc, traceData, Mem, EA,
344                    memAccessFlags, NULL);
345        }
346
347        return fault;
348    }
349}};
350
351
352def template StoreCompleteAcc {{
353    Fault %(class_name)s::completeAcc(PacketPtr pkt,
354                                      %(CPU_exec_context)s *xc,
355                                      Trace::InstRecord *traceData) const
356    {
357        return NoFault;
358    }
359}};
360
361
362def template StoreCondCompleteAcc {{
363    Fault %(class_name)s::completeAcc(PacketPtr pkt,
364                                      %(CPU_exec_context)s *xc,
365                                      Trace::InstRecord *traceData) const
366    {
367        Fault fault = NoFault;
368
369        %(fp_enable_check)s;
370        %(op_dest_decl)s;
371
372        uint64_t write_result = pkt->req->getExtraData();
373
374        if (fault == NoFault) {
375            %(postacc_code)s;
376        }
377
378        if (fault == NoFault) {
379            %(op_wb)s;
380        }
381
382        return fault;
383    }
384}};
385
386
387def template MiscExecute {{
388    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
389                                  Trace::InstRecord *traceData) const
390    {
391        Addr EA M5_VAR_USED;
392        Fault fault = NoFault;
393
394        %(fp_enable_check)s;
395        %(op_decl)s;
396        %(op_rd)s;
397        %(ea_code)s;
398
399        warn_once("Prefetch instructions in Alpha do not do anything\n");
400        if (fault == NoFault) {
401            %(memacc_code)s;
402        }
403
404        return NoFault;
405    }
406}};
407
408// Prefetches in Alpha don't actually do anything
409// They just build an effective address and complete
410def template MiscInitiateAcc {{
411    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
412                                      Trace::InstRecord *traceData) const
413    {
414        warn("initiateAcc undefined: Misc instruction does not support split "
415             "access method!");
416        return NoFault;
417    }
418}};
419
420
421def template MiscCompleteAcc {{
422    Fault %(class_name)s::completeAcc(PacketPtr pkt,
423                                      %(CPU_exec_context)s *xc,
424                                      Trace::InstRecord *traceData) const
425    {
426        warn("completeAcc undefined: Misc instruction does not support split "
427             "access method!");
428
429        return NoFault;
430    }
431}};
432
433
434// load instructions use Ra as dest, so check for
435// Ra == 31 to detect nops
436def template LoadNopCheckDecode {{
437 {
438     AlphaStaticInst *i = new %(class_name)s(machInst);
439     if (RA == 31) {
440         i = makeNop(i);
441     }
442     return i;
443 }
444}};
445
446
447// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
448def template LoadPrefetchCheckDecode {{
449 {
450     if (RA != 31) {
451         return new %(class_name)s(machInst);
452     }
453     else {
454         return new %(class_name)sPrefetch(machInst);
455     }
456 }
457}};
458
459
460let {{
461def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
462                  postacc_code = '', base_class = 'MemoryDisp32',
463                  decode_template = BasicDecode, exec_template_base = ''):
464    # Make sure flags are in lists (convert to lists if not).
465    mem_flags = makeList(mem_flags)
466    inst_flags = makeList(inst_flags)
467
468    # Some CPU models execute the memory operation as an atomic unit,
469    # while others want to separate them into an effective address
470    # computation and a memory access operation.  As a result, we need
471    # to generate three StaticInst objects.  Note that the latter two
472    # are nested inside the larger "atomic" one.
473
474    # Generate InstObjParams for each of the three objects.  Note that
475    # they differ only in the set of code objects contained (which in
476    # turn affects the object's overall operand list).
477    iop = InstObjParams(name, Name, base_class,
478                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
479                        inst_flags)
480    memacc_iop = InstObjParams(name, Name, base_class,
481                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
482                        inst_flags)
483
484    if mem_flags:
485        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
486        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
487        iop.constructor += s
488        memacc_iop.constructor += s
489
490    # select templates
491
492    # The InitiateAcc template is the same for StoreCond templates as the
493    # corresponding Store template..
494    StoreCondInitiateAcc = StoreInitiateAcc
495
496    fullExecTemplate = eval(exec_template_base + 'Execute')
497    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
498    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
499
500    # (header_output, decoder_output, decode_block, exec_output)
501    return (LoadStoreDeclare.subst(iop),
502            LoadStoreConstructor.subst(iop),
503            decode_template.subst(iop),
504            fullExecTemplate.subst(iop)
505            + EACompExecute.subst(iop)
506            + initiateAccTemplate.subst(iop)
507            + completeAccTemplate.subst(iop))
508}};
509
510def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
511                     mem_flags = [], inst_flags = []) {{
512    (header_output, decoder_output, decode_block, exec_output) = \
513        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
514                      decode_template = LoadNopCheckDecode,
515                      exec_template_base = 'Load')
516}};
517
518
519// Note that the flags passed in apply only to the prefetch version
520def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
521                          mem_flags = [], pf_flags = [], inst_flags = []) {{
522    # declare the load instruction object and generate the decode block
523    (header_output, decoder_output, decode_block, exec_output) = \
524        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
525                      decode_template = LoadPrefetchCheckDecode,
526                      exec_template_base = 'Load')
527
528    # Declare the prefetch instruction object.
529
530    # Make sure flag args are lists so we can mess with them.
531    mem_flags = makeList(mem_flags)
532    pf_flags = makeList(pf_flags)
533    inst_flags = makeList(inst_flags)
534
535    pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
536    pf_inst_flags = inst_flags
537
538    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
539        LoadStoreBase(name, Name + 'Prefetch', ea_code, ';',
540                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
541
542    header_output += pf_header_output
543    decoder_output += pf_decoder_output
544    exec_output += pf_exec_output
545}};
546
547
548def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
549                 mem_flags = [], inst_flags = []) {{
550    (header_output, decoder_output, decode_block, exec_output) = \
551        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
552                      exec_template_base = 'Store')
553}};
554
555
556def format StoreCond(memacc_code, postacc_code,
557                     ea_code = {{ EA = Rb + disp; }},
558                     mem_flags = [], inst_flags = []) {{
559    (header_output, decoder_output, decode_block, exec_output) = \
560        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
561                      postacc_code, exec_template_base = 'StoreCond')
562}};
563
564
565// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
566def format MiscPrefetch(ea_code, memacc_code,
567                        mem_flags = [], inst_flags = []) {{
568    (header_output, decoder_output, decode_block, exec_output) = \
569        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
570                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
571}};
572
573
574