util.isa revision 3931
13931Ssaidi@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan
23388Sgblack@eecs.umich.edu// All rights reserved.
33388Sgblack@eecs.umich.edu//
43388Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
53388Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
63388Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
73388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
83388Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
93388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
103388Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
113388Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
123388Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
133388Sgblack@eecs.umich.edu// this software without specific prior written permission.
143388Sgblack@eecs.umich.edu//
153388Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
163388Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
173388Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
183388Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
193388Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
203388Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
213388Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223388Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
233388Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
243388Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
253388Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
263388Sgblack@eecs.umich.edu//
273388Sgblack@eecs.umich.edu// Authors: Ali Saidi
283388Sgblack@eecs.umich.edu//          Gabe Black
293388Sgblack@eecs.umich.edu//          Steve Reinhardt
303388Sgblack@eecs.umich.edu
313388Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
323388Sgblack@eecs.umich.edu//
333388Sgblack@eecs.umich.edu// Mem utility templates and functions
343388Sgblack@eecs.umich.edu//
353388Sgblack@eecs.umich.edu
363441Sgblack@eecs.umich.eduoutput header {{
373441Sgblack@eecs.umich.edu        /**
383441Sgblack@eecs.umich.edu         * Base class for memory operations.
393441Sgblack@eecs.umich.edu         */
403441Sgblack@eecs.umich.edu        class Mem : public SparcStaticInst
413441Sgblack@eecs.umich.edu        {
423441Sgblack@eecs.umich.edu          protected:
433441Sgblack@eecs.umich.edu
443441Sgblack@eecs.umich.edu            // Constructor
453441Sgblack@eecs.umich.edu            Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
463441Sgblack@eecs.umich.edu                SparcStaticInst(mnem, _machInst, __opClass)
473441Sgblack@eecs.umich.edu            {
483441Sgblack@eecs.umich.edu            }
493441Sgblack@eecs.umich.edu
503441Sgblack@eecs.umich.edu            std::string generateDisassembly(Addr pc,
513441Sgblack@eecs.umich.edu                    const SymbolTable *symtab) const;
523441Sgblack@eecs.umich.edu        };
533441Sgblack@eecs.umich.edu
543441Sgblack@eecs.umich.edu        /**
553441Sgblack@eecs.umich.edu         * Class for memory operations which use an immediate offset.
563441Sgblack@eecs.umich.edu         */
573441Sgblack@eecs.umich.edu        class MemImm : public Mem
583441Sgblack@eecs.umich.edu        {
593441Sgblack@eecs.umich.edu          protected:
603441Sgblack@eecs.umich.edu
613441Sgblack@eecs.umich.edu            // Constructor
623441Sgblack@eecs.umich.edu            MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
633441Sgblack@eecs.umich.edu                Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
643441Sgblack@eecs.umich.edu            {}
653441Sgblack@eecs.umich.edu
663441Sgblack@eecs.umich.edu            std::string generateDisassembly(Addr pc,
673441Sgblack@eecs.umich.edu                    const SymbolTable *symtab) const;
683441Sgblack@eecs.umich.edu
693441Sgblack@eecs.umich.edu            const int32_t imm;
703441Sgblack@eecs.umich.edu        };
713441Sgblack@eecs.umich.edu}};
723441Sgblack@eecs.umich.edu
733441Sgblack@eecs.umich.eduoutput decoder {{
743441Sgblack@eecs.umich.edu        std::string Mem::generateDisassembly(Addr pc,
753441Sgblack@eecs.umich.edu                const SymbolTable *symtab) const
763441Sgblack@eecs.umich.edu        {
773441Sgblack@eecs.umich.edu            std::stringstream response;
783441Sgblack@eecs.umich.edu            bool load = flags[IsLoad];
793627Sgblack@eecs.umich.edu            bool store = flags[IsStore];
803441Sgblack@eecs.umich.edu
813441Sgblack@eecs.umich.edu            printMnemonic(response, mnemonic);
823627Sgblack@eecs.umich.edu            if(store)
833441Sgblack@eecs.umich.edu            {
843627Sgblack@eecs.umich.edu                printReg(response, _srcRegIdx[0]);
853441Sgblack@eecs.umich.edu                ccprintf(response, ", ");
863441Sgblack@eecs.umich.edu            }
873627Sgblack@eecs.umich.edu            ccprintf(response, "[");
883627Sgblack@eecs.umich.edu            if(_srcRegIdx[!store ? 0 : 1] != 0)
893627Sgblack@eecs.umich.edu            {
903627Sgblack@eecs.umich.edu                printSrcReg(response, !store ? 0 : 1);
913627Sgblack@eecs.umich.edu                ccprintf(response, " + ");
923627Sgblack@eecs.umich.edu            }
933627Sgblack@eecs.umich.edu            printSrcReg(response, !store ? 1 : 2);
943627Sgblack@eecs.umich.edu            ccprintf(response, "]");
953441Sgblack@eecs.umich.edu            if(load)
963441Sgblack@eecs.umich.edu            {
973441Sgblack@eecs.umich.edu                ccprintf(response, ", ");
983627Sgblack@eecs.umich.edu                printReg(response, _destRegIdx[0]);
993441Sgblack@eecs.umich.edu            }
1003441Sgblack@eecs.umich.edu
1013441Sgblack@eecs.umich.edu            return response.str();
1023441Sgblack@eecs.umich.edu        }
1033441Sgblack@eecs.umich.edu
1043441Sgblack@eecs.umich.edu        std::string MemImm::generateDisassembly(Addr pc,
1053441Sgblack@eecs.umich.edu                const SymbolTable *symtab) const
1063441Sgblack@eecs.umich.edu        {
1073441Sgblack@eecs.umich.edu            std::stringstream response;
1083441Sgblack@eecs.umich.edu            bool load = flags[IsLoad];
1093441Sgblack@eecs.umich.edu            bool save = flags[IsStore];
1103441Sgblack@eecs.umich.edu
1113441Sgblack@eecs.umich.edu            printMnemonic(response, mnemonic);
1123441Sgblack@eecs.umich.edu            if(save)
1133441Sgblack@eecs.umich.edu            {
1143627Sgblack@eecs.umich.edu                printReg(response, _srcRegIdx[0]);
1153441Sgblack@eecs.umich.edu                ccprintf(response, ", ");
1163441Sgblack@eecs.umich.edu            }
1173627Sgblack@eecs.umich.edu            ccprintf(response, "[");
1183627Sgblack@eecs.umich.edu            if(_srcRegIdx[!save ? 0 : 1] != 0)
1193627Sgblack@eecs.umich.edu            {
1203627Sgblack@eecs.umich.edu                printReg(response, _srcRegIdx[!save ? 0 : 1]);
1213627Sgblack@eecs.umich.edu                ccprintf(response, " + ");
1223627Sgblack@eecs.umich.edu            }
1233441Sgblack@eecs.umich.edu            if(imm >= 0)
1243627Sgblack@eecs.umich.edu                ccprintf(response, "0x%x]", imm);
1253441Sgblack@eecs.umich.edu            else
1263627Sgblack@eecs.umich.edu                ccprintf(response, "-0x%x]", -imm);
1273441Sgblack@eecs.umich.edu            if(load)
1283441Sgblack@eecs.umich.edu            {
1293441Sgblack@eecs.umich.edu                ccprintf(response, ", ");
1303627Sgblack@eecs.umich.edu                printReg(response, _destRegIdx[0]);
1313441Sgblack@eecs.umich.edu            }
1323441Sgblack@eecs.umich.edu
1333441Sgblack@eecs.umich.edu            return response.str();
1343441Sgblack@eecs.umich.edu        }
1353441Sgblack@eecs.umich.edu}};
1363441Sgblack@eecs.umich.edu
1373388Sgblack@eecs.umich.edu//This template provides the execute functions for a load
1383388Sgblack@eecs.umich.edudef template LoadExecute {{
1393388Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1403388Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
1413388Sgblack@eecs.umich.edu        {
1423388Sgblack@eecs.umich.edu            Fault fault = NoFault;
1433388Sgblack@eecs.umich.edu            Addr EA;
1443931Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
1453388Sgblack@eecs.umich.edu            %(op_decl)s;
1463388Sgblack@eecs.umich.edu            %(op_rd)s;
1473388Sgblack@eecs.umich.edu            %(ea_code)s;
1483388Sgblack@eecs.umich.edu            DPRINTF(Sparc, "The address is 0x%x\n", EA);
1493391Sgblack@eecs.umich.edu            %(fault_check)s;
1503391Sgblack@eecs.umich.edu            if(fault == NoFault)
1513391Sgblack@eecs.umich.edu            {
1523823Ssaidi@eecs.umich.edu                fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s);
1533391Sgblack@eecs.umich.edu            }
1543391Sgblack@eecs.umich.edu            if(fault == NoFault)
1553391Sgblack@eecs.umich.edu            {
1563391Sgblack@eecs.umich.edu                %(code)s;
1573391Sgblack@eecs.umich.edu            }
1583388Sgblack@eecs.umich.edu            if(fault == NoFault)
1593388Sgblack@eecs.umich.edu            {
1603616Sgblack@eecs.umich.edu                    //Write the resulting state to the execution context
1613616Sgblack@eecs.umich.edu                    %(op_wb)s;
1623388Sgblack@eecs.umich.edu            }
1633388Sgblack@eecs.umich.edu
1643388Sgblack@eecs.umich.edu            return fault;
1653388Sgblack@eecs.umich.edu        }
1663388Sgblack@eecs.umich.edu
1673388Sgblack@eecs.umich.edu        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
1683388Sgblack@eecs.umich.edu                Trace::InstRecord * traceData) const
1693388Sgblack@eecs.umich.edu        {
1703388Sgblack@eecs.umich.edu            Fault fault = NoFault;
1713388Sgblack@eecs.umich.edu            Addr EA;
1723388Sgblack@eecs.umich.edu            uint%(mem_acc_size)s_t Mem;
1733931Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
1743388Sgblack@eecs.umich.edu            %(ea_decl)s;
1753388Sgblack@eecs.umich.edu            %(ea_rd)s;
1763388Sgblack@eecs.umich.edu            %(ea_code)s;
1773391Sgblack@eecs.umich.edu            %(fault_check)s;
1783391Sgblack@eecs.umich.edu            if(fault == NoFault)
1793391Sgblack@eecs.umich.edu            {
1803823Ssaidi@eecs.umich.edu                fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s);
1813391Sgblack@eecs.umich.edu            }
1823388Sgblack@eecs.umich.edu            return fault;
1833388Sgblack@eecs.umich.edu        }
1843388Sgblack@eecs.umich.edu
1853388Sgblack@eecs.umich.edu        Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
1863388Sgblack@eecs.umich.edu                Trace::InstRecord * traceData) const
1873388Sgblack@eecs.umich.edu        {
1883388Sgblack@eecs.umich.edu            Fault fault = NoFault;
1893388Sgblack@eecs.umich.edu            %(code_decl)s;
1903388Sgblack@eecs.umich.edu            %(code_rd)s;
1913388Sgblack@eecs.umich.edu            Mem = pkt->get<typeof(Mem)>();
1923388Sgblack@eecs.umich.edu            %(code)s;
1933388Sgblack@eecs.umich.edu            if(fault == NoFault)
1943388Sgblack@eecs.umich.edu            {
1953388Sgblack@eecs.umich.edu                %(code_wb)s;
1963388Sgblack@eecs.umich.edu            }
1973388Sgblack@eecs.umich.edu            return fault;
1983388Sgblack@eecs.umich.edu        }
1993388Sgblack@eecs.umich.edu}};
2003388Sgblack@eecs.umich.edu
2013388Sgblack@eecs.umich.edu//This template provides the execute functions for a store
2023388Sgblack@eecs.umich.edudef template StoreExecute {{
2033388Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2043388Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
2053388Sgblack@eecs.umich.edu        {
2063388Sgblack@eecs.umich.edu            Fault fault = NoFault;
2073439Sgblack@eecs.umich.edu            //This is to support the conditional store in cas instructions.
2083439Sgblack@eecs.umich.edu            //It should be optomized out in all the others
2093439Sgblack@eecs.umich.edu            bool storeCond = true;
2103388Sgblack@eecs.umich.edu            Addr EA;
2113931Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
2123388Sgblack@eecs.umich.edu            %(op_decl)s;
2133388Sgblack@eecs.umich.edu            %(op_rd)s;
2143388Sgblack@eecs.umich.edu            %(ea_code)s;
2153388Sgblack@eecs.umich.edu            DPRINTF(Sparc, "The address is 0x%x\n", EA);
2163391Sgblack@eecs.umich.edu            %(fault_check)s;
2173391Sgblack@eecs.umich.edu            if(fault == NoFault)
2183391Sgblack@eecs.umich.edu            {
2193391Sgblack@eecs.umich.edu                %(code)s;
2203391Sgblack@eecs.umich.edu            }
2213439Sgblack@eecs.umich.edu            if(storeCond && fault == NoFault)
2223388Sgblack@eecs.umich.edu            {
2233810Sgblack@eecs.umich.edu                fault = xc->write((uint%(mem_acc_size)s_t)Mem,
2243810Sgblack@eecs.umich.edu                        EA, %(asi_val)s, 0);
2253388Sgblack@eecs.umich.edu            }
2263388Sgblack@eecs.umich.edu            if(fault == NoFault)
2273388Sgblack@eecs.umich.edu            {
2283616Sgblack@eecs.umich.edu                    //Write the resulting state to the execution context
2293616Sgblack@eecs.umich.edu                    %(op_wb)s;
2303388Sgblack@eecs.umich.edu            }
2313388Sgblack@eecs.umich.edu
2323388Sgblack@eecs.umich.edu            return fault;
2333388Sgblack@eecs.umich.edu        }
2343388Sgblack@eecs.umich.edu
2353388Sgblack@eecs.umich.edu        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
2363388Sgblack@eecs.umich.edu                Trace::InstRecord * traceData) const
2373388Sgblack@eecs.umich.edu        {
2383388Sgblack@eecs.umich.edu            Fault fault = NoFault;
2393439Sgblack@eecs.umich.edu            bool storeCond = true;
2403388Sgblack@eecs.umich.edu            Addr EA;
2413931Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
2423388Sgblack@eecs.umich.edu            %(op_decl)s;
2433388Sgblack@eecs.umich.edu            %(op_rd)s;
2443388Sgblack@eecs.umich.edu            %(ea_code)s;
2453388Sgblack@eecs.umich.edu            DPRINTF(Sparc, "The address is 0x%x\n", EA);
2463391Sgblack@eecs.umich.edu            %(fault_check)s;
2473391Sgblack@eecs.umich.edu            if(fault == NoFault)
2483391Sgblack@eecs.umich.edu            {
2493391Sgblack@eecs.umich.edu                %(code)s;
2503391Sgblack@eecs.umich.edu            }
2513439Sgblack@eecs.umich.edu            if(storeCond && fault == NoFault)
2523388Sgblack@eecs.umich.edu            {
2533810Sgblack@eecs.umich.edu                fault = xc->write((uint%(mem_acc_size)s_t)Mem,
2543810Sgblack@eecs.umich.edu                        EA, %(asi_val)s, 0);
2553388Sgblack@eecs.umich.edu            }
2563388Sgblack@eecs.umich.edu            if(fault == NoFault)
2573388Sgblack@eecs.umich.edu            {
2583616Sgblack@eecs.umich.edu                    //Write the resulting state to the execution context
2593388Sgblack@eecs.umich.edu                %(op_wb)s;
2603388Sgblack@eecs.umich.edu            }
2613388Sgblack@eecs.umich.edu            return fault;
2623388Sgblack@eecs.umich.edu        }
2633388Sgblack@eecs.umich.edu
2643388Sgblack@eecs.umich.edu        Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
2653388Sgblack@eecs.umich.edu                Trace::InstRecord * traceData) const
2663388Sgblack@eecs.umich.edu        {
2673388Sgblack@eecs.umich.edu            return NoFault;
2683388Sgblack@eecs.umich.edu        }
2693388Sgblack@eecs.umich.edu}};
2703388Sgblack@eecs.umich.edu
2713388Sgblack@eecs.umich.edu//This delcares the initiateAcc function in memory operations
2723388Sgblack@eecs.umich.edudef template InitiateAccDeclare {{
2733388Sgblack@eecs.umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
2743388Sgblack@eecs.umich.edu}};
2753388Sgblack@eecs.umich.edu
2763388Sgblack@eecs.umich.edu//This declares the completeAcc function in memory operations
2773388Sgblack@eecs.umich.edudef template CompleteAccDeclare {{
2783388Sgblack@eecs.umich.edu    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
2793388Sgblack@eecs.umich.edu}};
2803388Sgblack@eecs.umich.edu
2813391Sgblack@eecs.umich.edu//Here are some code snippets which check for various fault conditions
2823391Sgblack@eecs.umich.edulet {{
2833391Sgblack@eecs.umich.edu    # The LSB can be zero, since it's really the MSB in doubles and quads
2843391Sgblack@eecs.umich.edu    # and we're dealing with doubles
2853391Sgblack@eecs.umich.edu    BlockAlignmentFaultCheck = '''
2863391Sgblack@eecs.umich.edu        if(RD & 0xe)
2873391Sgblack@eecs.umich.edu            fault = new IllegalInstruction;
2883391Sgblack@eecs.umich.edu        else if(EA & 0x3f)
2893391Sgblack@eecs.umich.edu            fault = new MemAddressNotAligned;
2903391Sgblack@eecs.umich.edu    '''
2913835Sgblack@eecs.umich.edu    TwinAlignmentFaultCheck = '''
2923863Ssaidi@eecs.umich.edu        if(RD & 0x1)
2933835Sgblack@eecs.umich.edu            fault = new IllegalInstruction;
2943863Ssaidi@eecs.umich.edu        else if(EA & 0xf)
2953835Sgblack@eecs.umich.edu            fault = new MemAddressNotAligned;
2963835Sgblack@eecs.umich.edu    '''
2973391Sgblack@eecs.umich.edu    # XXX Need to take care of pstate.hpriv as well. The lower ASIs
2983391Sgblack@eecs.umich.edu    # are split into ones that are available in priv and hpriv, and
2993391Sgblack@eecs.umich.edu    # those that are only available in hpriv
3003391Sgblack@eecs.umich.edu    AlternateASIPrivFaultCheck = '''
3013823Ssaidi@eecs.umich.edu        if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) ||
3023823Ssaidi@eecs.umich.edu                             !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI))
3033823Ssaidi@eecs.umich.edu                fault = new PrivilegedAction;
3043391Sgblack@eecs.umich.edu        else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
3053391Sgblack@eecs.umich.edu            fault = new PrivilegedAction;
3063391Sgblack@eecs.umich.edu    '''
3073391Sgblack@eecs.umich.edu
3083391Sgblack@eecs.umich.edu}};
3093391Sgblack@eecs.umich.edu
3103391Sgblack@eecs.umich.edu//A simple function to generate the name of the macro op of a certain
3113391Sgblack@eecs.umich.edu//instruction at a certain micropc
3123391Sgblack@eecs.umich.edulet {{
3133391Sgblack@eecs.umich.edu    def makeMicroName(name, microPc):
3143616Sgblack@eecs.umich.edu            return name + "::" + name + "_" + str(microPc)
3153391Sgblack@eecs.umich.edu}};
3163391Sgblack@eecs.umich.edu
3173388Sgblack@eecs.umich.edu//This function properly generates the execute functions for one of the
3183388Sgblack@eecs.umich.edu//templates above. This is needed because in one case, ea computation,
3193391Sgblack@eecs.umich.edu//fault checks and the actual code all occur in the same function,
3203388Sgblack@eecs.umich.edu//and in the other they're distributed across two. Also note that for
3213388Sgblack@eecs.umich.edu//execute functions, the name of the base class doesn't matter.
3223388Sgblack@eecs.umich.edulet {{
3233810Sgblack@eecs.umich.edu    def doSplitExecute(code, execute, name, Name, asi, opt_flags, microParam):
3243810Sgblack@eecs.umich.edu        microParam["asi_val"] = asi;
3253616Sgblack@eecs.umich.edu        codeParam = microParam.copy()
3263616Sgblack@eecs.umich.edu        codeParam["ea_code"] = ''
3273616Sgblack@eecs.umich.edu        codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam)
3283616Sgblack@eecs.umich.edu        eaIop = InstObjParams(name, Name, '', microParam["ea_code"],
3293616Sgblack@eecs.umich.edu                opt_flags, microParam)
3303616Sgblack@eecs.umich.edu        iop = InstObjParams(name, Name, '', code, opt_flags, microParam)
3313439Sgblack@eecs.umich.edu        (iop.ea_decl,
3323439Sgblack@eecs.umich.edu         iop.ea_rd,
3333439Sgblack@eecs.umich.edu         iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
3343439Sgblack@eecs.umich.edu        (iop.code_decl,
3353439Sgblack@eecs.umich.edu         iop.code_rd,
3363439Sgblack@eecs.umich.edu         iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
3373439Sgblack@eecs.umich.edu        return execute.subst(iop)
3383439Sgblack@eecs.umich.edu
3393439Sgblack@eecs.umich.edu
3403439Sgblack@eecs.umich.edu    def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
3413810Sgblack@eecs.umich.edu            faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags):
3423388Sgblack@eecs.umich.edu        executeCode = ''
3433388Sgblack@eecs.umich.edu        for (eaCode, name, Name) in (
3443388Sgblack@eecs.umich.edu                (eaRegCode, nameReg, NameReg),
3453388Sgblack@eecs.umich.edu                (eaImmCode, nameImm, NameImm)):
3463616Sgblack@eecs.umich.edu            microParams = {"ea_code" : eaCode, "fault_check": faultCode}
3473616Sgblack@eecs.umich.edu            executeCode += doSplitExecute(code, execute, name, Name,
3483810Sgblack@eecs.umich.edu                    asi, opt_flags, microParams)
3493388Sgblack@eecs.umich.edu        return executeCode
3503388Sgblack@eecs.umich.edu}};
351