util.isa revision 10474
13569Sgblack@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan
23569Sgblack@eecs.umich.edu// All rights reserved.
33569Sgblack@eecs.umich.edu//
43569Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
53569Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
63569Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
73569Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
83569Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
93569Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
103569Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
113569Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
123569Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
133569Sgblack@eecs.umich.edu// this software without specific prior written permission.
143569Sgblack@eecs.umich.edu//
153569Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
163569Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
173569Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
183569Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
193569Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
203569Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
213569Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223569Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
233569Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
243569Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
253569Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
263569Sgblack@eecs.umich.edu//
273569Sgblack@eecs.umich.edu// Authors: Ali Saidi
283804Ssaidi@eecs.umich.edu//          Gabe Black
293569Sgblack@eecs.umich.edu//          Steve Reinhardt
303569Sgblack@eecs.umich.edu
313918Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
323918Ssaidi@eecs.umich.edu//
333804Ssaidi@eecs.umich.edu// Mem utility templates and functions
343811Ssaidi@eecs.umich.edu//
353569Sgblack@eecs.umich.edu
363824Ssaidi@eecs.umich.eduoutput header {{
373811Ssaidi@eecs.umich.edu        /**
383811Ssaidi@eecs.umich.edu         * Base class for memory operations.
393823Ssaidi@eecs.umich.edu         */
403823Ssaidi@eecs.umich.edu        class Mem : public SparcStaticInst
413823Ssaidi@eecs.umich.edu        {
423569Sgblack@eecs.umich.edu          protected:
434103Ssaidi@eecs.umich.edu
443569Sgblack@eecs.umich.edu            // Constructor
453804Ssaidi@eecs.umich.edu            Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
463804Ssaidi@eecs.umich.edu                SparcStaticInst(mnem, _machInst, __opClass)
474088Sbinkertn@umich.edu            {
483569Sgblack@eecs.umich.edu            }
493804Ssaidi@eecs.umich.edu
503881Ssaidi@eecs.umich.edu            std::string generateDisassembly(Addr pc,
513881Ssaidi@eecs.umich.edu                    const SymbolTable *symtab) const;
523804Ssaidi@eecs.umich.edu        };
533804Ssaidi@eecs.umich.edu
543804Ssaidi@eecs.umich.edu        /**
553804Ssaidi@eecs.umich.edu         * Class for memory operations which use an immediate offset.
563569Sgblack@eecs.umich.edu         */
573804Ssaidi@eecs.umich.edu        class MemImm : public Mem
583918Ssaidi@eecs.umich.edu        {
593881Ssaidi@eecs.umich.edu          protected:
603881Ssaidi@eecs.umich.edu
613881Ssaidi@eecs.umich.edu            // Constructor
623804Ssaidi@eecs.umich.edu            MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
633569Sgblack@eecs.umich.edu                Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
643804Ssaidi@eecs.umich.edu            {}
653804Ssaidi@eecs.umich.edu
663804Ssaidi@eecs.umich.edu            std::string generateDisassembly(Addr pc,
673804Ssaidi@eecs.umich.edu                    const SymbolTable *symtab) const;
683881Ssaidi@eecs.umich.edu
693804Ssaidi@eecs.umich.edu            const int32_t imm;
703804Ssaidi@eecs.umich.edu        };
713804Ssaidi@eecs.umich.edu}};
723804Ssaidi@eecs.umich.edu
733804Ssaidi@eecs.umich.eduoutput decoder {{
743804Ssaidi@eecs.umich.edu        std::string Mem::generateDisassembly(Addr pc,
753804Ssaidi@eecs.umich.edu                const SymbolTable *symtab) const
763569Sgblack@eecs.umich.edu        {
773569Sgblack@eecs.umich.edu            std::stringstream response;
783804Ssaidi@eecs.umich.edu            bool load = flags[IsLoad];
793804Ssaidi@eecs.umich.edu            bool store = flags[IsStore];
803826Ssaidi@eecs.umich.edu
813804Ssaidi@eecs.umich.edu            printMnemonic(response, mnemonic);
823569Sgblack@eecs.umich.edu            if (store) {
833569Sgblack@eecs.umich.edu                printReg(response, _srcRegIdx[0]);
843804Ssaidi@eecs.umich.edu                ccprintf(response, ", ");
853826Ssaidi@eecs.umich.edu            }
863907Ssaidi@eecs.umich.edu            ccprintf(response, "[");
873826Ssaidi@eecs.umich.edu            if (_srcRegIdx[!store ? 0 : 1] != 0) {
883811Ssaidi@eecs.umich.edu                printSrcReg(response, !store ? 0 : 1);
893836Ssaidi@eecs.umich.edu                ccprintf(response, " + ");
903915Ssaidi@eecs.umich.edu            }
913907Ssaidi@eecs.umich.edu            printSrcReg(response, !store ? 1 : 2);
923881Ssaidi@eecs.umich.edu            ccprintf(response, "]");
933881Ssaidi@eecs.umich.edu            if (load) {
943881Ssaidi@eecs.umich.edu                ccprintf(response, ", ");
953881Ssaidi@eecs.umich.edu                printReg(response, _destRegIdx[0]);
963907Ssaidi@eecs.umich.edu            }
973881Ssaidi@eecs.umich.edu
983881Ssaidi@eecs.umich.edu            return response.str();
993881Ssaidi@eecs.umich.edu        }
1003881Ssaidi@eecs.umich.edu
1013881Ssaidi@eecs.umich.edu        std::string MemImm::generateDisassembly(Addr pc,
1023907Ssaidi@eecs.umich.edu                const SymbolTable *symtab) const
1033907Ssaidi@eecs.umich.edu        {
1043907Ssaidi@eecs.umich.edu            std::stringstream response;
1053907Ssaidi@eecs.umich.edu            bool load = flags[IsLoad];
1063907Ssaidi@eecs.umich.edu            bool save = flags[IsStore];
1073907Ssaidi@eecs.umich.edu
1083907Ssaidi@eecs.umich.edu            printMnemonic(response, mnemonic);
1093907Ssaidi@eecs.umich.edu            if (save) {
1103907Ssaidi@eecs.umich.edu                printReg(response, _srcRegIdx[0]);
1113907Ssaidi@eecs.umich.edu                ccprintf(response, ", ");
1123907Ssaidi@eecs.umich.edu            }
1133907Ssaidi@eecs.umich.edu            ccprintf(response, "[");
1143907Ssaidi@eecs.umich.edu            if (_srcRegIdx[!save ? 0 : 1] != 0) {
1153907Ssaidi@eecs.umich.edu                printReg(response, _srcRegIdx[!save ? 0 : 1]);
1163907Ssaidi@eecs.umich.edu                ccprintf(response, " + ");
1173907Ssaidi@eecs.umich.edu            }
1183907Ssaidi@eecs.umich.edu            if (imm >= 0)
1193907Ssaidi@eecs.umich.edu                ccprintf(response, "0x%x]", imm);
1203907Ssaidi@eecs.umich.edu            else
1213907Ssaidi@eecs.umich.edu                ccprintf(response, "-0x%x]", -imm);
1223907Ssaidi@eecs.umich.edu            if (load) {
1233907Ssaidi@eecs.umich.edu                ccprintf(response, ", ");
1243907Ssaidi@eecs.umich.edu                printReg(response, _destRegIdx[0]);
1253881Ssaidi@eecs.umich.edu            }
1263881Ssaidi@eecs.umich.edu
1273881Ssaidi@eecs.umich.edu            return response.str();
1283881Ssaidi@eecs.umich.edu        }
1293881Ssaidi@eecs.umich.edu}};
1303881Ssaidi@eecs.umich.edu
1313881Ssaidi@eecs.umich.edu// This template provides the execute functions for a load
1323881Ssaidi@eecs.umich.edudef template LoadExecute {{
1333881Ssaidi@eecs.umich.edu        Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
1343881Ssaidi@eecs.umich.edu                Trace::InstRecord *traceData) const
1353881Ssaidi@eecs.umich.edu        {
1363881Ssaidi@eecs.umich.edu            Fault fault = NoFault;
1373907Ssaidi@eecs.umich.edu            Addr EA;
1383811Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
1393826Ssaidi@eecs.umich.edu            %(op_decl)s;
1403826Ssaidi@eecs.umich.edu            %(op_rd)s;
1413826Ssaidi@eecs.umich.edu            %(ea_code)s;
1423826Ssaidi@eecs.umich.edu            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
1433881Ssaidi@eecs.umich.edu            %(fault_check)s;
1443881Ssaidi@eecs.umich.edu            if (fault == NoFault) {
1453881Ssaidi@eecs.umich.edu                %(EA_trunc)s
1463881Ssaidi@eecs.umich.edu                fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s);
1473881Ssaidi@eecs.umich.edu            }
1483881Ssaidi@eecs.umich.edu            if (fault == NoFault) {
1493881Ssaidi@eecs.umich.edu                %(code)s;
1503881Ssaidi@eecs.umich.edu            }
1513881Ssaidi@eecs.umich.edu            if (fault == NoFault) {
1523881Ssaidi@eecs.umich.edu                // Write the resulting state to the execution context
1533881Ssaidi@eecs.umich.edu                %(op_wb)s;
1543881Ssaidi@eecs.umich.edu            }
1553881Ssaidi@eecs.umich.edu
1563881Ssaidi@eecs.umich.edu            return fault;
1573881Ssaidi@eecs.umich.edu        }
1583826Ssaidi@eecs.umich.edu}};
1593826Ssaidi@eecs.umich.edu
1603826Ssaidi@eecs.umich.edudef template LoadInitiateAcc {{
1613826Ssaidi@eecs.umich.edu        Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
1623826Ssaidi@eecs.umich.edu                Trace::InstRecord * traceData) const
1633881Ssaidi@eecs.umich.edu        {
1643569Sgblack@eecs.umich.edu            Fault fault = NoFault;
1653569Sgblack@eecs.umich.edu            Addr EA;
1663881Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
1673804Ssaidi@eecs.umich.edu            %(op_decl)s;
1683881Ssaidi@eecs.umich.edu            %(op_rd)s;
1693826Ssaidi@eecs.umich.edu            %(ea_code)s;
1703881Ssaidi@eecs.umich.edu            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
1713881Ssaidi@eecs.umich.edu            %(fault_check)s;
1723881Ssaidi@eecs.umich.edu            if (fault == NoFault) {
1733907Ssaidi@eecs.umich.edu                %(EA_trunc)s
1743907Ssaidi@eecs.umich.edu                fault = readMemTiming(xc, traceData, EA, Mem, %(asi_val)s);
1753929Ssaidi@eecs.umich.edu            }
1763929Ssaidi@eecs.umich.edu            return fault;
1773907Ssaidi@eecs.umich.edu        }
1783907Ssaidi@eecs.umich.edu}};
1793804Ssaidi@eecs.umich.edu
1803804Ssaidi@eecs.umich.edudef template LoadCompleteAcc {{
1813881Ssaidi@eecs.umich.edu        Fault %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT * xc,
1823804Ssaidi@eecs.umich.edu                Trace::InstRecord * traceData) const
1833804Ssaidi@eecs.umich.edu        {
1843804Ssaidi@eecs.umich.edu            Fault fault = NoFault;
1853804Ssaidi@eecs.umich.edu            %(op_decl)s;
1863804Ssaidi@eecs.umich.edu            %(op_rd)s;
1873804Ssaidi@eecs.umich.edu            getMem(pkt, Mem, traceData);
1883804Ssaidi@eecs.umich.edu            %(code)s;
1893569Sgblack@eecs.umich.edu            if (fault == NoFault) {
1903569Sgblack@eecs.umich.edu                %(op_wb)s;
1913569Sgblack@eecs.umich.edu            }
1923863Ssaidi@eecs.umich.edu            return fault;
1933863Ssaidi@eecs.umich.edu        }
1943804Ssaidi@eecs.umich.edu}};
1953804Ssaidi@eecs.umich.edu
1963804Ssaidi@eecs.umich.edu// This template provides the execute functions for a store
1973804Ssaidi@eecs.umich.edudef template StoreExecute {{
1983804Ssaidi@eecs.umich.edu        Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
1993804Ssaidi@eecs.umich.edu                Trace::InstRecord *traceData) const
2003804Ssaidi@eecs.umich.edu        {
2013804Ssaidi@eecs.umich.edu            Fault fault = NoFault;
2023804Ssaidi@eecs.umich.edu            // This is to support the conditional store in cas instructions.
2033569Sgblack@eecs.umich.edu            // It should be optomized out in all the others
2043804Ssaidi@eecs.umich.edu            bool storeCond = true;
2053804Ssaidi@eecs.umich.edu            Addr EA;
2063804Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
2074070Ssaidi@eecs.umich.edu            %(op_decl)s;
2084070Ssaidi@eecs.umich.edu            %(op_rd)s;
2093804Ssaidi@eecs.umich.edu            %(ea_code)s;
2103804Ssaidi@eecs.umich.edu            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
2113804Ssaidi@eecs.umich.edu            %(fault_check)s;
2123804Ssaidi@eecs.umich.edu            if (fault == NoFault) {
2133804Ssaidi@eecs.umich.edu                %(code)s;
2143811Ssaidi@eecs.umich.edu            }
2153811Ssaidi@eecs.umich.edu            if (storeCond && fault == NoFault) {
2163804Ssaidi@eecs.umich.edu                %(EA_trunc)s
2173804Ssaidi@eecs.umich.edu                fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0);
2183863Ssaidi@eecs.umich.edu            }
2193804Ssaidi@eecs.umich.edu            if (fault == NoFault) {
2203804Ssaidi@eecs.umich.edu                // Write the resulting state to the execution context
2213804Ssaidi@eecs.umich.edu                %(op_wb)s;
2223804Ssaidi@eecs.umich.edu            }
2233804Ssaidi@eecs.umich.edu
2243804Ssaidi@eecs.umich.edu            return fault;
2253804Ssaidi@eecs.umich.edu        }
2263811Ssaidi@eecs.umich.edu}};
2273804Ssaidi@eecs.umich.edu
2283804Ssaidi@eecs.umich.edudef template StoreInitiateAcc {{
2293804Ssaidi@eecs.umich.edu        Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
2303804Ssaidi@eecs.umich.edu                Trace::InstRecord * traceData) const
2313804Ssaidi@eecs.umich.edu        {
2323826Ssaidi@eecs.umich.edu            Fault fault = NoFault;
2333826Ssaidi@eecs.umich.edu            bool storeCond = true;
2344070Ssaidi@eecs.umich.edu            Addr EA;
2354070Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
2364070Ssaidi@eecs.umich.edu            %(op_decl)s;
2374070Ssaidi@eecs.umich.edu
2383804Ssaidi@eecs.umich.edu            %(op_rd)s;
2393804Ssaidi@eecs.umich.edu            %(ea_code)s;
2403804Ssaidi@eecs.umich.edu            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
2413804Ssaidi@eecs.umich.edu            %(fault_check)s;
2423804Ssaidi@eecs.umich.edu            if (fault == NoFault) {
2433804Ssaidi@eecs.umich.edu                %(code)s;
2443804Ssaidi@eecs.umich.edu            }
2453804Ssaidi@eecs.umich.edu            if (storeCond && fault == NoFault) {
2463804Ssaidi@eecs.umich.edu                %(EA_trunc)s
2473804Ssaidi@eecs.umich.edu                fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0);
2483804Ssaidi@eecs.umich.edu            }
2493804Ssaidi@eecs.umich.edu            return fault;
2503826Ssaidi@eecs.umich.edu        }
2513826Ssaidi@eecs.umich.edu}};
2523826Ssaidi@eecs.umich.edu
2533863Ssaidi@eecs.umich.edudef template StoreCompleteAcc {{
2543826Ssaidi@eecs.umich.edu        Fault %(class_name)s::completeAcc(PacketPtr, CPU_EXEC_CONTEXT * xc,
2553826Ssaidi@eecs.umich.edu                Trace::InstRecord * traceData) const
2563826Ssaidi@eecs.umich.edu        {
2573826Ssaidi@eecs.umich.edu            return NoFault;
2583826Ssaidi@eecs.umich.edu        }
2593826Ssaidi@eecs.umich.edu}};
2603826Ssaidi@eecs.umich.edu
2613826Ssaidi@eecs.umich.edudef template EACompExecute {{
2623826Ssaidi@eecs.umich.edu    Fault
2633804Ssaidi@eecs.umich.edu    %(class_name)s::eaComp(CPU_EXEC_CONTEXT *xc,
2643804Ssaidi@eecs.umich.edu                                   Trace::InstRecord *traceData) const
2653804Ssaidi@eecs.umich.edu    {
2663804Ssaidi@eecs.umich.edu        Addr EA;
2673804Ssaidi@eecs.umich.edu        Fault fault = NoFault;
2683804Ssaidi@eecs.umich.edu        %(op_decl)s;
2693804Ssaidi@eecs.umich.edu        %(op_rd)s;
2703863Ssaidi@eecs.umich.edu        %(ea_code)s;
2713863Ssaidi@eecs.umich.edu        %(fault_check)s;
2723863Ssaidi@eecs.umich.edu
2733836Ssaidi@eecs.umich.edu        // NOTE: Trace Data is written using execute or completeAcc templates
2743836Ssaidi@eecs.umich.edu        if (fault == NoFault) {
2753804Ssaidi@eecs.umich.edu            %(EA_trunc)s
2763804Ssaidi@eecs.umich.edu            xc->setEA(EA);
2773863Ssaidi@eecs.umich.edu        }
2783804Ssaidi@eecs.umich.edu
2793804Ssaidi@eecs.umich.edu        return fault;
2803804Ssaidi@eecs.umich.edu    }
2813804Ssaidi@eecs.umich.edu}};
2823804Ssaidi@eecs.umich.edu
2833804Ssaidi@eecs.umich.edudef template EACompDeclare {{
2843804Ssaidi@eecs.umich.edu    Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
2853863Ssaidi@eecs.umich.edu}};
2863804Ssaidi@eecs.umich.edu
2873804Ssaidi@eecs.umich.edu// This delcares the initiateAcc function in memory operations
2883804Ssaidi@eecs.umich.edudef template InitiateAccDeclare {{
2893804Ssaidi@eecs.umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
2903804Ssaidi@eecs.umich.edu}};
2913881Ssaidi@eecs.umich.edu
2923804Ssaidi@eecs.umich.edu// This declares the completeAcc function in memory operations
2933804Ssaidi@eecs.umich.edudef template CompleteAccDeclare {{
2943804Ssaidi@eecs.umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
2953804Ssaidi@eecs.umich.edu}};
2963804Ssaidi@eecs.umich.edu
2973804Ssaidi@eecs.umich.edu// Here are some code snippets which check for various fault conditions
2983804Ssaidi@eecs.umich.edulet {{
2993804Ssaidi@eecs.umich.edu    LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
3003863Ssaidi@eecs.umich.edu    StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
3013863Ssaidi@eecs.umich.edu
3023836Ssaidi@eecs.umich.edu    # The LSB can be zero, since it's really the MSB in doubles and quads
3033804Ssaidi@eecs.umich.edu    # and we're dealing with doubles
3043804Ssaidi@eecs.umich.edu    BlockAlignmentFaultCheck = '''
3053804Ssaidi@eecs.umich.edu        if (RD & 0xe)
3063881Ssaidi@eecs.umich.edu            fault = std::make_shared<IllegalInstruction>();
3073881Ssaidi@eecs.umich.edu        else if (EA & 0x3f)
3083881Ssaidi@eecs.umich.edu            fault = std::make_shared<MemAddressNotAligned>();
3093804Ssaidi@eecs.umich.edu    '''
3103804Ssaidi@eecs.umich.edu    TwinAlignmentFaultCheck = '''
3113804Ssaidi@eecs.umich.edu        if (RD & 0x1)
3123804Ssaidi@eecs.umich.edu            fault = std::make_shared<IllegalInstruction>();
3133804Ssaidi@eecs.umich.edu        else if (EA & 0xf)
3143804Ssaidi@eecs.umich.edu            fault = std::make_shared<MemAddressNotAligned>();
3153804Ssaidi@eecs.umich.edu    '''
3163804Ssaidi@eecs.umich.edu    # XXX Need to take care of pstate.hpriv as well. The lower ASIs
3173804Ssaidi@eecs.umich.edu    # are split into ones that are available in priv and hpriv, and
3183804Ssaidi@eecs.umich.edu    # those that are only available in hpriv
3193804Ssaidi@eecs.umich.edu    AlternateASIPrivFaultCheck = '''
3203804Ssaidi@eecs.umich.edu        if ((!Pstate.priv && !Hpstate.hpriv &&
3213804Ssaidi@eecs.umich.edu             !asiIsUnPriv((ASI)EXT_ASI)) ||
3223804Ssaidi@eecs.umich.edu            (!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI)))
3233863Ssaidi@eecs.umich.edu            fault = std::make_shared<PrivilegedAction>();
3243836Ssaidi@eecs.umich.edu        else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv)
3253804Ssaidi@eecs.umich.edu            fault = std::make_shared<PrivilegedAction>();
3263804Ssaidi@eecs.umich.edu    '''
3273881Ssaidi@eecs.umich.edu
3283881Ssaidi@eecs.umich.edu    TruncateEA = '''
3293881Ssaidi@eecs.umich.edu        if (!FullSystem)
3303804Ssaidi@eecs.umich.edu            EA = Pstate.am ? EA<31:0> : EA;
3313804Ssaidi@eecs.umich.edu    '''
3323804Ssaidi@eecs.umich.edu}};
3333804Ssaidi@eecs.umich.edu
3343804Ssaidi@eecs.umich.edu// A simple function to generate the name of the macro op of a certain
3353804Ssaidi@eecs.umich.edu// instruction at a certain micropc
3363804Ssaidi@eecs.umich.edulet {{
3373804Ssaidi@eecs.umich.edu    def makeMicroName(name, microPc):
3383804Ssaidi@eecs.umich.edu            return name + "::" + name + "_" + str(microPc)
3393804Ssaidi@eecs.umich.edu}};
3403804Ssaidi@eecs.umich.edu
3413804Ssaidi@eecs.umich.edu// This function properly generates the execute functions for one of the
3423804Ssaidi@eecs.umich.edu// templates above. This is needed because in one case, ea computation,
3433804Ssaidi@eecs.umich.edu// fault checks and the actual code all occur in the same function,
3443836Ssaidi@eecs.umich.edu// and in the other they're distributed across two. Also note that for
3453836Ssaidi@eecs.umich.edu// execute functions, the name of the base class doesn't matter.
3463881Ssaidi@eecs.umich.edulet {{
3473907Ssaidi@eecs.umich.edu    def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
3483804Ssaidi@eecs.umich.edu        microParam["asi_val"] = asi;
3493881Ssaidi@eecs.umich.edu        iop = InstObjParams(name, Name, '', microParam, opt_flags)
3503881Ssaidi@eecs.umich.edu        (execf, initf, compf) = execute
3513804Ssaidi@eecs.umich.edu        return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
3523907Ssaidi@eecs.umich.edu
3533804Ssaidi@eecs.umich.edu
3543804Ssaidi@eecs.umich.edu    def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute,
3553804Ssaidi@eecs.umich.edu            faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags):
3563804Ssaidi@eecs.umich.edu        executeCode = ''
3573804Ssaidi@eecs.umich.edu        for (eaCode, name, Name) in (
3583804Ssaidi@eecs.umich.edu                (eaRegCode, nameReg, NameReg),
3593881Ssaidi@eecs.umich.edu                (eaImmCode, nameImm, NameImm)):
3603881Ssaidi@eecs.umich.edu            microParams = {"code": code, "postacc_code" : postacc_code,
3613881Ssaidi@eecs.umich.edu                "ea_code": eaCode, "fault_check": faultCode,
3623804Ssaidi@eecs.umich.edu                "EA_trunc" : TruncateEA}
3633881Ssaidi@eecs.umich.edu            executeCode += doSplitExecute(execute, name, Name,
3643881Ssaidi@eecs.umich.edu                    asi, opt_flags, microParams)
3653881Ssaidi@eecs.umich.edu        return executeCode
3663881Ssaidi@eecs.umich.edu}};
3673804Ssaidi@eecs.umich.edu