mem.isa revision 8564
12889Sbinkertn@umich.edu// -*- mode:c++ -*-
22889Sbinkertn@umich.edu
32889Sbinkertn@umich.edu// Copyright (c) 2007 MIPS Technologies, Inc.
42889Sbinkertn@umich.edu// All rights reserved.
52889Sbinkertn@umich.edu//
62889Sbinkertn@umich.edu// Redistribution and use in source and binary forms, with or without
72889Sbinkertn@umich.edu// modification, are permitted provided that the following conditions are
82889Sbinkertn@umich.edu// met: redistributions of source code must retain the above copyright
92889Sbinkertn@umich.edu// notice, this list of conditions and the following disclaimer;
102889Sbinkertn@umich.edu// redistributions in binary form must reproduce the above copyright
112889Sbinkertn@umich.edu// notice, this list of conditions and the following disclaimer in the
122889Sbinkertn@umich.edu// documentation and/or other materials provided with the distribution;
132889Sbinkertn@umich.edu// neither the name of the copyright holders nor the names of its
142889Sbinkertn@umich.edu// contributors may be used to endorse or promote products derived from
152889Sbinkertn@umich.edu// this software without specific prior written permission.
162889Sbinkertn@umich.edu//
172889Sbinkertn@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182889Sbinkertn@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192889Sbinkertn@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202889Sbinkertn@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212889Sbinkertn@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222889Sbinkertn@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232889Sbinkertn@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242889Sbinkertn@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252889Sbinkertn@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262889Sbinkertn@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272889Sbinkertn@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282889Sbinkertn@umich.edu//
294850Snate@binkert.org// Authors: Steve Reinhardt
304850Snate@binkert.org//          Korey Sewell
314850Snate@binkert.org
324850Snate@binkert.org////////////////////////////////////////////////////////////////////
334850Snate@binkert.org//
344850Snate@binkert.org// Memory-format instructions
352889Sbinkertn@umich.edu//
362889Sbinkertn@umich.edu
378327Sgblack@eecs.umich.eduoutput header {{
385470Snate@binkert.org    /**
398333Snate@binkert.org     * Base class for general Mips memory-format instructions.
408333Snate@binkert.org     */
412889Sbinkertn@umich.edu    class Memory : public MipsStaticInst
428234Snate@binkert.org    {
438234Snate@binkert.org      protected:
448234Snate@binkert.org        /// Memory request flags.  See mem_req_base.hh.
452889Sbinkertn@umich.edu        Request::Flags memAccessFlags;
468234Snate@binkert.org
478234Snate@binkert.org        /// Displacement for EA calculation (signed).
488234Snate@binkert.org        int32_t disp;
498234Snate@binkert.org
502889Sbinkertn@umich.edu        /// Constructor
518234Snate@binkert.org        Memory(const char *mnem, MachInst _machInst, OpClass __opClass)
528234Snate@binkert.org            : MipsStaticInst(mnem, _machInst, __opClass),
538234Snate@binkert.org              disp(sext<16>(OFFSET))
548234Snate@binkert.org        {
558234Snate@binkert.org        }
568234Snate@binkert.org
578234Snate@binkert.org        std::string
582889Sbinkertn@umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
598234Snate@binkert.org    };
608234Snate@binkert.org
618234Snate@binkert.org     /**
628234Snate@binkert.org     * Base class for a few miscellaneous memory-format insts
638234Snate@binkert.org     * that don't interpret the disp field
648234Snate@binkert.org     */
658234Snate@binkert.org    class MemoryNoDisp : public Memory
668234Snate@binkert.org    {
678234Snate@binkert.org      protected:
688234Snate@binkert.org        /// Constructor
698234Snate@binkert.org        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
708234Snate@binkert.org            : Memory(mnem, _machInst, __opClass)
718234Snate@binkert.org        {
728234Snate@binkert.org        }
738234Snate@binkert.org
748234Snate@binkert.org        std::string
758234Snate@binkert.org        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
768234Snate@binkert.org    };
778234Snate@binkert.org}};
788234Snate@binkert.org
798234Snate@binkert.org
802889Sbinkertn@umich.eduoutput decoder {{
818234Snate@binkert.org    std::string
828234Snate@binkert.org    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
838234Snate@binkert.org    {
848234Snate@binkert.org        return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
855773Snate@binkert.org                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
868234Snate@binkert.org    }
878234Snate@binkert.org
888234Snate@binkert.org    std::string
898234Snate@binkert.org    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
908664SAli.Saidi@ARM.com    {
918664SAli.Saidi@ARM.com        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
928998Suri.wiener@arm.com                        flags[IsFloating] ? 'f' : 'r',
938998Suri.wiener@arm.com                        flags[IsFloating] ? FD : RD,
942889Sbinkertn@umich.edu                        RS, RT);
958234Snate@binkert.org    }
968234Snate@binkert.org
9711299Ssteve.reinhardt@amd.com}};
9811299Ssteve.reinhardt@amd.com
9911299Ssteve.reinhardt@amd.comoutput exec {{
1008234Snate@binkert.org    /** return data in cases where there the size of data is only
1019960Sandreas.hansson@arm.com        known in the packet
1028234Snate@binkert.org    */
1039960Sandreas.hansson@arm.com    uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) {
10411299Ssteve.reinhardt@amd.com        switch (packet->getSize())
10511304Ssteve.reinhardt@amd.com        {
10611338SMichael.Lebeane@amd.com          case 1:
10711338SMichael.Lebeane@amd.com            return packet->get<uint8_t>();
1089960Sandreas.hansson@arm.com
1099960Sandreas.hansson@arm.com          case 2:
1109960Sandreas.hansson@arm.com            return packet->get<uint16_t>();
1119960Sandreas.hansson@arm.com
1128234Snate@binkert.org          case 4:
1138234Snate@binkert.org            return packet->get<uint32_t>();
1142889Sbinkertn@umich.edu
1158234Snate@binkert.org          case 8:
1168234Snate@binkert.org            return packet->get<uint64_t>();
1178234Snate@binkert.org
1188234Snate@binkert.org          default:
1196171Snate@binkert.org            std::cerr << "bad store data size = " << packet->getSize() << std::endl;
1208234Snate@binkert.org
1218234Snate@binkert.org            assert(0);
1228234Snate@binkert.org            return 0;
1238234Snate@binkert.org        }
1248234Snate@binkert.org    }
1258234Snate@binkert.org
1268234Snate@binkert.org
1278234Snate@binkert.org}};
1288234Snate@binkert.org
1296171Snate@binkert.orgdef template LoadStoreDeclare {{
1308219Snate@binkert.org    /**
1318327Sgblack@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
1329512Sandreas@sandberg.pp.se     */
1339512Sandreas@sandberg.pp.se    class %(class_name)s : public %(base_class)s
1349512Sandreas@sandberg.pp.se    {
1359512Sandreas@sandberg.pp.se      public:
1369512Sandreas@sandberg.pp.se
1379512Sandreas@sandberg.pp.se        /// Constructor.
1388219Snate@binkert.org        %(class_name)s(ExtMachInst machInst);
1398219Snate@binkert.org
1409512Sandreas@sandberg.pp.se        %(BasicExecDeclare)s
1419512Sandreas@sandberg.pp.se
1429512Sandreas@sandberg.pp.se        %(EACompDeclare)s
1439512Sandreas@sandberg.pp.se
1449512Sandreas@sandberg.pp.se        %(InitiateAccDeclare)s
1459512Sandreas@sandberg.pp.se
1469512Sandreas@sandberg.pp.se        %(CompleteAccDeclare)s
1479512Sandreas@sandberg.pp.se    };
1489512Sandreas@sandberg.pp.se}};
1499512Sandreas@sandberg.pp.se
1509512Sandreas@sandberg.pp.sedef template EACompDeclare {{
1519512Sandreas@sandberg.pp.se    Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1529512Sandreas@sandberg.pp.se}};
1539512Sandreas@sandberg.pp.se
1549512Sandreas@sandberg.pp.sedef template InitiateAccDeclare {{
1559512Sandreas@sandberg.pp.se    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
1569512Sandreas@sandberg.pp.se}};
1579512Sandreas@sandberg.pp.se
1589512Sandreas@sandberg.pp.se
1599512Sandreas@sandberg.pp.sedef template CompleteAccDeclare {{
1609512Sandreas@sandberg.pp.se    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
1619512Sandreas@sandberg.pp.se}};
1628219Snate@binkert.org
1639512Sandreas@sandberg.pp.sedef template LoadStoreConstructor {{
1649512Sandreas@sandberg.pp.se    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
1659512Sandreas@sandberg.pp.se         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
1668219Snate@binkert.org    {
1678219Snate@binkert.org        %(constructor)s;
1688234Snate@binkert.org    }
1698245Snate@binkert.org}};
1708245Snate@binkert.org
1715801Snate@binkert.org
1725801Snate@binkert.orgdef template EACompExecute {{
1735801Snate@binkert.org    Fault
1744167Sbinkertn@umich.edu    %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
1754042Sbinkertn@umich.edu                                   Trace::InstRecord *traceData) const
1765801Snate@binkert.org    {
1775799Snate@binkert.org        Addr EA;
1785799Snate@binkert.org        Fault fault = NoFault;
1798234Snate@binkert.org
1808234Snate@binkert.org        if (this->isFloating()) {
1818234Snate@binkert.org            %(fp_enable_check)s;
1828234Snate@binkert.org
1838234Snate@binkert.org            if(fault != NoFault)
1848234Snate@binkert.org                return fault;
1858234Snate@binkert.org        }
1868234Snate@binkert.org
1878234Snate@binkert.org        %(op_decl)s;
1888245Snate@binkert.org        %(op_rd)s;
1898245Snate@binkert.org        %(ea_code)s;
1905799Snate@binkert.org
1915799Snate@binkert.org        // NOTE: Trace Data is written using execute or completeAcc templates
1925799Snate@binkert.org        if (fault == NoFault) {
1935799Snate@binkert.org            xc->setEA(EA);
1945802Snate@binkert.org        }
1952889Sbinkertn@umich.edu
1969983Sstever@gmail.com        return fault;
1979983Sstever@gmail.com    }
1989983Sstever@gmail.com}};
1999983Sstever@gmail.com
2005524Sstever@gmail.comdef template LoadExecute {{
2015524Sstever@gmail.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2025524Sstever@gmail.com                                  Trace::InstRecord *traceData) const
2035524Sstever@gmail.com    {
2045524Sstever@gmail.com        Addr EA;
2055524Sstever@gmail.com        Fault fault = NoFault;
2065524Sstever@gmail.com
2075524Sstever@gmail.com        if (this->isFloating()) {
2085524Sstever@gmail.com            %(fp_enable_check)s;
2095524Sstever@gmail.com
2105524Sstever@gmail.com            if(fault != NoFault)
2115524Sstever@gmail.com                return fault;
2125524Sstever@gmail.com        }
2135524Sstever@gmail.com
2145524Sstever@gmail.com        %(op_decl)s;
2155524Sstever@gmail.com        %(op_rd)s;
2165524Sstever@gmail.com        %(ea_code)s;
2175524Sstever@gmail.com
2185524Sstever@gmail.com        if (fault == NoFault) {
2195524Sstever@gmail.com            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
2205524Sstever@gmail.com            %(memacc_code)s;
2215524Sstever@gmail.com        }
2225524Sstever@gmail.com
2235524Sstever@gmail.com        if (fault == NoFault) {
2245524Sstever@gmail.com            %(op_wb)s;
2255524Sstever@gmail.com        }
2265524Sstever@gmail.com
2272889Sbinkertn@umich.edu        return fault;
2284850Snate@binkert.org    }
2294850Snate@binkert.org}};
2304850Snate@binkert.org
2314850Snate@binkert.org
2324850Snate@binkert.orgdef template LoadInitiateAcc {{
2335801Snate@binkert.org    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
2344850Snate@binkert.org                                      Trace::InstRecord *traceData) const
2355801Snate@binkert.org    {
2364850Snate@binkert.org        Addr EA;
2374850Snate@binkert.org        Fault fault = NoFault;
2385801Snate@binkert.org
2394850Snate@binkert.org        if (this->isFloating()) {
2404850Snate@binkert.org            %(fp_enable_check)s;
2414850Snate@binkert.org
2422889Sbinkertn@umich.edu            if(fault != NoFault)
2432889Sbinkertn@umich.edu                return fault;
2448333Snate@binkert.org        }
2452889Sbinkertn@umich.edu
2462889Sbinkertn@umich.edu        %(op_src_decl)s;
2472889Sbinkertn@umich.edu        %(op_rd)s;
2482889Sbinkertn@umich.edu        %(ea_code)s;
2492889Sbinkertn@umich.edu
2502889Sbinkertn@umich.edu        if (fault == NoFault) {
2512889Sbinkertn@umich.edu            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
2522889Sbinkertn@umich.edu        }
2532889Sbinkertn@umich.edu
2548232Snate@binkert.org        return fault;
2554053Sbinkertn@umich.edu    }
2565799Snate@binkert.org}};
2578232Snate@binkert.org
2584053Sbinkertn@umich.edudef template LoadCompleteAcc {{
2595473Snate@binkert.org    Fault %(class_name)s::completeAcc(Packet *pkt,
2605473Snate@binkert.org                                      %(CPU_exec_context)s *xc,
2615473Snate@binkert.org                                      Trace::InstRecord *traceData) const
2625473Snate@binkert.org    {
2635473Snate@binkert.org        Fault fault = NoFault;
2645473Snate@binkert.org
2655473Snate@binkert.org        if (this->isFloating()) {
2665473Snate@binkert.org            %(fp_enable_check)s;
2675473Snate@binkert.org
2685473Snate@binkert.org            if(fault != NoFault)
2695473Snate@binkert.org                return fault;
2705473Snate@binkert.org        }
2715473Snate@binkert.org
2725473Snate@binkert.org        %(op_decl)s;
2735473Snate@binkert.org        %(op_rd)s;
2745473Snate@binkert.org
2755473Snate@binkert.org        getMem(pkt, Mem, traceData);
2765473Snate@binkert.org
2775473Snate@binkert.org        if (fault == NoFault) {
2785473Snate@binkert.org            %(memacc_code)s;
2795473Snate@binkert.org        }
2802889Sbinkertn@umich.edu
2812889Sbinkertn@umich.edu        if (fault == NoFault) {
2822889Sbinkertn@umich.edu            %(op_wb)s;
2835470Snate@binkert.org        }
2845470Snate@binkert.org
2855470Snate@binkert.org        return fault;
2865470Snate@binkert.org    }
2875470Snate@binkert.org}};
28810134Sstan.czerniawski@arm.com
2898333Snate@binkert.orgdef template StoreExecute {{
2902889Sbinkertn@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2912889Sbinkertn@umich.edu                                  Trace::InstRecord *traceData) const
2925801Snate@binkert.org    {
2938327Sgblack@eecs.umich.edu        Addr EA;
2945456Ssaidi@eecs.umich.edu        Fault fault = NoFault;
2958327Sgblack@eecs.umich.edu
2968327Sgblack@eecs.umich.edu        %(fp_enable_check)s;
29711161Ssteve.reinhardt@amd.com        %(op_decl)s;
29811161Ssteve.reinhardt@amd.com        %(op_rd)s;
2995528Sstever@gmail.com        %(ea_code)s;
30010758Ssteve.reinhardt@amd.com
30110758Ssteve.reinhardt@amd.com        if (fault == NoFault) {
30210758Ssteve.reinhardt@amd.com            %(memacc_code)s;
3032967Sktlim@umich.edu        }
3042889Sbinkertn@umich.edu
3052889Sbinkertn@umich.edu        if (fault == NoFault) {
3062889Sbinkertn@umich.edu            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
3072922Sktlim@umich.edu                    NULL);
3082922Sktlim@umich.edu        }
3094053Sbinkertn@umich.edu
3105470Snate@binkert.org        if (fault == NoFault) {
3112889Sbinkertn@umich.edu            %(postacc_code)s;
3122889Sbinkertn@umich.edu        }
3135801Snate@binkert.org
3142889Sbinkertn@umich.edu        if (fault == NoFault) {
3152889Sbinkertn@umich.edu            %(op_wb)s;
3162889Sbinkertn@umich.edu        }
3172889Sbinkertn@umich.edu
3182889Sbinkertn@umich.edu        return fault;
3195801Snate@binkert.org    }
3202889Sbinkertn@umich.edu}};
3212889Sbinkertn@umich.edu
3225801Snate@binkert.org
3233645Sbinkertn@umich.edudef template StoreFPExecute {{
3249960Sandreas.hansson@arm.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3252889Sbinkertn@umich.edu                                  Trace::InstRecord *traceData) const
3268232Snate@binkert.org    {
3275799Snate@binkert.org        Addr EA;
3284053Sbinkertn@umich.edu        Fault fault = NoFault;
3295586Snate@binkert.org
3305586Snate@binkert.org        %(fp_enable_check)s;
3318232Snate@binkert.org        if(fault != NoFault)
3325586Snate@binkert.org          return fault;
3335586Snate@binkert.org        %(op_decl)s;
3345586Snate@binkert.org        %(op_rd)s;
3355586Snate@binkert.org        %(ea_code)s;
3368232Snate@binkert.org
3378232Snate@binkert.org        if (fault == NoFault) {
3388232Snate@binkert.org            %(memacc_code)s;
3395586Snate@binkert.org        }
3404053Sbinkertn@umich.edu
3415586Snate@binkert.org        if (fault == NoFault) {
3428232Snate@binkert.org            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
3435586Snate@binkert.org                    NULL);
3448232Snate@binkert.org        }
3454053Sbinkertn@umich.edu
3469960Sandreas.hansson@arm.com        if (fault == NoFault) {
3475799Snate@binkert.org            %(postacc_code)s;
3489960Sandreas.hansson@arm.com        }
3499960Sandreas.hansson@arm.com
3504074Sbinkertn@umich.edu        if (fault == NoFault) {
3515799Snate@binkert.org            %(op_wb)s;
3524042Sbinkertn@umich.edu        }
35311338SMichael.Lebeane@amd.com
35411338SMichael.Lebeane@amd.com        return fault;
35511338SMichael.Lebeane@amd.com    }
35611338SMichael.Lebeane@amd.com}};
35711338SMichael.Lebeane@amd.com
3589960Sandreas.hansson@arm.comdef template StoreCondExecute {{
3594042Sbinkertn@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3609960Sandreas.hansson@arm.com                                  Trace::InstRecord *traceData) const
3615799Snate@binkert.org    {
3625799Snate@binkert.org        Addr EA;
3632889Sbinkertn@umich.edu        Fault fault = NoFault;
3642889Sbinkertn@umich.edu        uint64_t write_result = 0;
3652889Sbinkertn@umich.edu
3662891Sbinkertn@umich.edu        %(fp_enable_check)s;
3675604Snate@binkert.org        %(op_decl)s;
3685604Snate@binkert.org        %(op_rd)s;
3695604Snate@binkert.org        %(ea_code)s;
3705604Snate@binkert.org
3713887Sbinkertn@umich.edu        if (fault == NoFault) {
3722899Sbinkertn@umich.edu            %(memacc_code)s;
3732899Sbinkertn@umich.edu        }
3742899Sbinkertn@umich.edu
3754042Sbinkertn@umich.edu        if (fault == NoFault) {
3762899Sbinkertn@umich.edu            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
3772899Sbinkertn@umich.edu                    &write_result);
3782899Sbinkertn@umich.edu        }
3792899Sbinkertn@umich.edu
3805604Snate@binkert.org        if (fault == NoFault) {
3815604Snate@binkert.org            %(postacc_code)s;
3825604Snate@binkert.org        }
3835604Snate@binkert.org
3845604Snate@binkert.org        if (fault == NoFault) {
3855604Snate@binkert.org            %(op_wb)s;
3865604Snate@binkert.org        }
3875604Snate@binkert.org
3885604Snate@binkert.org        return fault;
3895604Snate@binkert.org    }
3905604Snate@binkert.org}};
3915604Snate@binkert.org
3925604Snate@binkert.orgdef template StoreInitiateAcc {{
3935604Snate@binkert.org    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3945604Snate@binkert.org                                      Trace::InstRecord *traceData) const
3955604Snate@binkert.org    {
3962899Sbinkertn@umich.edu        Addr EA;
3975604Snate@binkert.org        Fault fault = NoFault;
3982889Sbinkertn@umich.edu
3992889Sbinkertn@umich.edu        %(fp_enable_check)s;
4002889Sbinkertn@umich.edu        %(op_decl)s;
4018219Snate@binkert.org        %(op_rd)s;
4022889Sbinkertn@umich.edu        %(ea_code)s;
4032889Sbinkertn@umich.edu
4042889Sbinkertn@umich.edu        if (fault == NoFault) {
4052889Sbinkertn@umich.edu            %(memacc_code)s;
4068234Snate@binkert.org        }
4078234Snate@binkert.org
4082889Sbinkertn@umich.edu        if (fault == NoFault) {
4092889Sbinkertn@umich.edu            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
4102889Sbinkertn@umich.edu                    NULL);
4112889Sbinkertn@umich.edu        }
4122889Sbinkertn@umich.edu
4132889Sbinkertn@umich.edu        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 = '''
546        uint32_t mem_word = Mem.uw;
547        uint32_t unalign_addr = Rs + disp;
548        uint32_t byte_offset = unalign_addr & 3;
549        if (GuestByteOrder == BigEndianByteOrder)
550            byte_offset ^= 3;
551    '''
552
553    memacc_code = decl_code + memacc_code
554
555    (header_output, decoder_output, decode_block, exec_output) = \
556        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
557                      decode_template = ImmNopCheckDecode,
558                      exec_template_base = 'Load')
559}};
560
561def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
562                     mem_flags = [], inst_flags = []) {{
563    decl_code = '''
564        uint32_t mem_word = 0;
565        uint32_t unaligned_addr = Rs + disp;
566        uint32_t byte_offset = unaligned_addr & 3;
567        if (GuestByteOrder == BigEndianByteOrder)
568            byte_offset ^= 3;
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