mem.isa revision 2075
14876Sstever@eecs.umich.edu// -*- mode:c++ -*-
23646Srdreslin@umich.edu
33646Srdreslin@umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
43646Srdreslin@umich.edu// All rights reserved.
53646Srdreslin@umich.edu//
63646Srdreslin@umich.edu// Redistribution and use in source and binary forms, with or without
73646Srdreslin@umich.edu// modification, are permitted provided that the following conditions are
83646Srdreslin@umich.edu// met: redistributions of source code must retain the above copyright
93646Srdreslin@umich.edu// notice, this list of conditions and the following disclaimer;
103646Srdreslin@umich.edu// redistributions in binary form must reproduce the above copyright
113646Srdreslin@umich.edu// notice, this list of conditions and the following disclaimer in the
123646Srdreslin@umich.edu// documentation and/or other materials provided with the distribution;
133646Srdreslin@umich.edu// neither the name of the copyright holders nor the names of its
143646Srdreslin@umich.edu// contributors may be used to endorse or promote products derived from
153646Srdreslin@umich.edu// this software without specific prior written permission.
163646Srdreslin@umich.edu//
173646Srdreslin@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
183646Srdreslin@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
193646Srdreslin@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
203646Srdreslin@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
213646Srdreslin@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
223646Srdreslin@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
233646Srdreslin@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
243646Srdreslin@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
253646Srdreslin@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
263646Srdreslin@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
273646Srdreslin@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
283646Srdreslin@umich.edu
293646Srdreslin@umich.eduoutput header {{
303646Srdreslin@umich.edu    /**
313646Srdreslin@umich.edu     * Base class for general Alpha memory-format instructions.
323646Srdreslin@umich.edu     */
336654Snate@binkert.org    class Memory : public AlphaStaticInst
346654Snate@binkert.org    {
356654Snate@binkert.org      protected:
366654Snate@binkert.org
373646Srdreslin@umich.edu        /// Memory request flags.  See mem_req_base.hh.
383646Srdreslin@umich.edu        unsigned memAccessFlags;
396654Snate@binkert.org        /// Pointer to EAComp object.
406654Snate@binkert.org        const StaticInstPtr<AlphaISA> eaCompPtr;
413646Srdreslin@umich.edu        /// Pointer to MemAcc object.
423646Srdreslin@umich.edu        const StaticInstPtr<AlphaISA> memAccPtr;
433646Srdreslin@umich.edu
443646Srdreslin@umich.edu        /// Constructor
453646Srdreslin@umich.edu        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
463646Srdreslin@umich.edu               StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
473646Srdreslin@umich.edu               StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
483646Srdreslin@umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass),
493646Srdreslin@umich.edu              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
503646Srdreslin@umich.edu        {
513646Srdreslin@umich.edu        }
523646Srdreslin@umich.edu
533646Srdreslin@umich.edu        std::string
543646Srdreslin@umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
553646Srdreslin@umich.edu
563646Srdreslin@umich.edu      public:
573646Srdreslin@umich.edu
583646Srdreslin@umich.edu        const StaticInstPtr<AlphaISA> &eaCompInst() const { return eaCompPtr; }
593646Srdreslin@umich.edu        const StaticInstPtr<AlphaISA> &memAccInst() const { return memAccPtr; }
603646Srdreslin@umich.edu    };
613646Srdreslin@umich.edu
623646Srdreslin@umich.edu    /**
633646Srdreslin@umich.edu     * Base class for memory-format instructions using a 32-bit
643646Srdreslin@umich.edu     * displacement (i.e. most of them).
653646Srdreslin@umich.edu     */
663646Srdreslin@umich.edu    class MemoryDisp32 : public Memory
673646Srdreslin@umich.edu    {
683646Srdreslin@umich.edu      protected:
693646Srdreslin@umich.edu        /// Displacement for EA calculation (signed).
703646Srdreslin@umich.edu        int32_t disp;
713646Srdreslin@umich.edu
723646Srdreslin@umich.edu        /// Constructor.
733646Srdreslin@umich.edu        MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass,
743646Srdreslin@umich.edu                     StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
753646Srdreslin@umich.edu                     StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
763646Srdreslin@umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
773646Srdreslin@umich.edu              disp(MEMDISP)
783646Srdreslin@umich.edu        {
793646Srdreslin@umich.edu        }
803646Srdreslin@umich.edu    };
813646Srdreslin@umich.edu
823646Srdreslin@umich.edu
833646Srdreslin@umich.edu    /**
843646Srdreslin@umich.edu     * Base class for a few miscellaneous memory-format insts
853646Srdreslin@umich.edu     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
863646Srdreslin@umich.edu     * None of these instructions has a destination register either.
873646Srdreslin@umich.edu     */
883646Srdreslin@umich.edu    class MemoryNoDisp : public Memory
893646Srdreslin@umich.edu    {
903646Srdreslin@umich.edu      protected:
913646Srdreslin@umich.edu        /// Constructor
923646Srdreslin@umich.edu        MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass,
933646Srdreslin@umich.edu                     StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
943646Srdreslin@umich.edu                     StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
953646Srdreslin@umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
963646Srdreslin@umich.edu        {
973646Srdreslin@umich.edu        }
983646Srdreslin@umich.edu
993646Srdreslin@umich.edu        std::string
1003646Srdreslin@umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1013646Srdreslin@umich.edu    };
1023646Srdreslin@umich.edu}};
1033646Srdreslin@umich.edu
1043646Srdreslin@umich.edu
1053646Srdreslin@umich.eduoutput decoder {{
1063646Srdreslin@umich.edu    std::string
1073646Srdreslin@umich.edu    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1083646Srdreslin@umich.edu    {
1093646Srdreslin@umich.edu        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1103646Srdreslin@umich.edu                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1113646Srdreslin@umich.edu    }
1123646Srdreslin@umich.edu
1133646Srdreslin@umich.edu    std::string
1143646Srdreslin@umich.edu    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1153646Srdreslin@umich.edu    {
1163646Srdreslin@umich.edu        return csprintf("%-10s (r%d)", mnemonic, RB);
1173646Srdreslin@umich.edu    }
1183646Srdreslin@umich.edu}};
1193646Srdreslin@umich.edu
1203646Srdreslin@umich.edudef format LoadAddress(code) {{
1213646Srdreslin@umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
1223646Srdreslin@umich.edu    header_output = BasicDeclare.subst(iop)
1233646Srdreslin@umich.edu    decoder_output = BasicConstructor.subst(iop)
1243646Srdreslin@umich.edu    decode_block = BasicDecode.subst(iop)
1253646Srdreslin@umich.edu    exec_output = BasicExecute.subst(iop)
1263646Srdreslin@umich.edu}};
1273646Srdreslin@umich.edu
1283646Srdreslin@umich.edu
1293646Srdreslin@umich.edudef template LoadStoreDeclare {{
1303646Srdreslin@umich.edu    /**
1313646Srdreslin@umich.edu     * Static instruction class for "%(mnemonic)s".
1323646Srdreslin@umich.edu     */
1333646Srdreslin@umich.edu    class %(class_name)s : public %(base_class)s
1343646Srdreslin@umich.edu    {
1353646Srdreslin@umich.edu      protected:
1363646Srdreslin@umich.edu
1373646Srdreslin@umich.edu        /**
1383646Srdreslin@umich.edu         * "Fake" effective address computation class for "%(mnemonic)s".
1393646Srdreslin@umich.edu         */
14011053Sandreas.hansson@arm.com        class EAComp : public %(base_class)s
1413646Srdreslin@umich.edu        {
1423646Srdreslin@umich.edu          public:
1433646Srdreslin@umich.edu            /// Constructor
1443646Srdreslin@umich.edu            EAComp(MachInst machInst);
1453646Srdreslin@umich.edu
1463646Srdreslin@umich.edu            %(BasicExecDeclare)s
1473646Srdreslin@umich.edu        };
1483646Srdreslin@umich.edu
14911053Sandreas.hansson@arm.com        /**
1503646Srdreslin@umich.edu         * "Fake" memory access instruction class for "%(mnemonic)s".
1513646Srdreslin@umich.edu         */
1523646Srdreslin@umich.edu        class MemAcc : public %(base_class)s
1533646Srdreslin@umich.edu        {
1543646Srdreslin@umich.edu          public:
1553646Srdreslin@umich.edu            /// Constructor
1563646Srdreslin@umich.edu            MemAcc(MachInst machInst);
1573646Srdreslin@umich.edu
1583646Srdreslin@umich.edu            %(BasicExecDeclare)s
1593646Srdreslin@umich.edu        };
1603646Srdreslin@umich.edu
1613646Srdreslin@umich.edu      public:
1623646Srdreslin@umich.edu
1633646Srdreslin@umich.edu        /// Constructor.
1643646Srdreslin@umich.edu        %(class_name)s(MachInst machInst);
1653646Srdreslin@umich.edu
1663646Srdreslin@umich.edu        %(BasicExecDeclare)s
1673646Srdreslin@umich.edu    };
1683646Srdreslin@umich.edu}};
1693646Srdreslin@umich.edu
1703646Srdreslin@umich.edudef template LoadStoreConstructor {{
1713646Srdreslin@umich.edu    /** TODO: change op_class to AddrGenOp or something (requires
1723646Srdreslin@umich.edu     * creating new member of OpClass enum in op_class.hh, updating
1733646Srdreslin@umich.edu     * config files, etc.). */
17410720Sandreas.hansson@arm.com    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1753646Srdreslin@umich.edu        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
1763646Srdreslin@umich.edu    {
1773646Srdreslin@umich.edu        %(ea_constructor)s;
1783646Srdreslin@umich.edu    }
1793646Srdreslin@umich.edu
1803646Srdreslin@umich.edu    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
1813646Srdreslin@umich.edu        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
1823646Srdreslin@umich.edu    {
1833646Srdreslin@umich.edu        %(memacc_constructor)s;
1843646Srdreslin@umich.edu    }
1853646Srdreslin@umich.edu
1863646Srdreslin@umich.edu    inline %(class_name)s::%(class_name)s(MachInst machInst)
18710720Sandreas.hansson@arm.com         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1883646Srdreslin@umich.edu                          new EAComp(machInst), new MemAcc(machInst))
1893646Srdreslin@umich.edu    {
1903646Srdreslin@umich.edu        %(constructor)s;
1913646Srdreslin@umich.edu    }
1923646Srdreslin@umich.edu}};
1933646Srdreslin@umich.edu
1943646Srdreslin@umich.edu
1953646Srdreslin@umich.edudef template EACompExecute {{
1963646Srdreslin@umich.edu    Fault
1973646Srdreslin@umich.edu    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
1983646Srdreslin@umich.edu                                   Trace::InstRecord *traceData) const
1993646Srdreslin@umich.edu    {
20010720Sandreas.hansson@arm.com        Addr EA;
2013646Srdreslin@umich.edu        Fault fault = No_Fault;
2023646Srdreslin@umich.edu
2033646Srdreslin@umich.edu        %(fp_enable_check)s;
2043646Srdreslin@umich.edu        %(op_decl)s;
2053646Srdreslin@umich.edu        %(op_rd)s;
2063646Srdreslin@umich.edu        %(code)s;
2073646Srdreslin@umich.edu
2083646Srdreslin@umich.edu        if (fault == No_Fault) {
2093646Srdreslin@umich.edu            %(op_wb)s;
2103646Srdreslin@umich.edu            xc->setEA(EA);
2113646Srdreslin@umich.edu        }
2128931Sandreas.hansson@arm.com
2139036Sandreas.hansson@arm.com        return fault;
21410720Sandreas.hansson@arm.com    }
2159790Sakash.bagdia@arm.com}};
2163646Srdreslin@umich.edu
21710720Sandreas.hansson@arm.comdef template LoadMemAccExecute {{
2183646Srdreslin@umich.edu    Fault
2193646Srdreslin@umich.edu    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2203646Srdreslin@umich.edu                                   Trace::InstRecord *traceData) const
2213646Srdreslin@umich.edu    {
2223646Srdreslin@umich.edu        Addr EA;
2233646Srdreslin@umich.edu        Fault fault = No_Fault;
2248847Sandreas.hansson@arm.com
2258847Sandreas.hansson@arm.com        %(fp_enable_check)s;
2268847Sandreas.hansson@arm.com        %(op_decl)s;
2273646Srdreslin@umich.edu        %(op_rd)s;
2283646Srdreslin@umich.edu        EA = xc->getEA();
2293646Srdreslin@umich.edu
2303646Srdreslin@umich.edu        if (fault == No_Fault) {
2313646Srdreslin@umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2328847Sandreas.hansson@arm.com            %(code)s;
2338847Sandreas.hansson@arm.com        }
2343646Srdreslin@umich.edu
2358847Sandreas.hansson@arm.com        if (fault == No_Fault) {
2368847Sandreas.hansson@arm.com            %(op_wb)s;
2373646Srdreslin@umich.edu        }
2383646Srdreslin@umich.edu
2393646Srdreslin@umich.edu        return fault;
2403646Srdreslin@umich.edu    }
2413646Srdreslin@umich.edu}};
2428801Sgblack@eecs.umich.edu
2433646Srdreslin@umich.edu
2443646Srdreslin@umich.edudef template LoadExecute {{
2453646Srdreslin@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2463646Srdreslin@umich.edu                                  Trace::InstRecord *traceData) const
2473646Srdreslin@umich.edu    {
2483646Srdreslin@umich.edu        Addr EA;
2493646Srdreslin@umich.edu        Fault fault = No_Fault;
2503646Srdreslin@umich.edu
2513646Srdreslin@umich.edu        %(fp_enable_check)s;
2523646Srdreslin@umich.edu        %(op_decl)s;
2533646Srdreslin@umich.edu        %(op_rd)s;
2543646Srdreslin@umich.edu        %(ea_code)s;
2553646Srdreslin@umich.edu
2563646Srdreslin@umich.edu        if (fault == No_Fault) {
2573646Srdreslin@umich.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
2583646Srdreslin@umich.edu            %(memacc_code)s;
2593646Srdreslin@umich.edu        }
2603646Srdreslin@umich.edu
2613646Srdreslin@umich.edu        if (fault == No_Fault) {
2623646Srdreslin@umich.edu            %(op_wb)s;
2633646Srdreslin@umich.edu        }
2643646Srdreslin@umich.edu
2653646Srdreslin@umich.edu        return fault;
2663646Srdreslin@umich.edu    }
2673646Srdreslin@umich.edu}};
2683646Srdreslin@umich.edu
2693646Srdreslin@umich.edu
2703646Srdreslin@umich.edudef template StoreMemAccExecute {{
2713646Srdreslin@umich.edu    Fault
2726654Snate@binkert.org    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
2736654Snate@binkert.org                                   Trace::InstRecord *traceData) const
2746654Snate@binkert.org    {
2756654Snate@binkert.org        Addr EA;
2766654Snate@binkert.org        Fault fault = No_Fault;
2773646Srdreslin@umich.edu        uint64_t write_result = 0;
2783646Srdreslin@umich.edu
2793646Srdreslin@umich.edu        %(fp_enable_check)s;
2803646Srdreslin@umich.edu        %(op_decl)s;
2813646Srdreslin@umich.edu        %(op_rd)s;
2823646Srdreslin@umich.edu        EA = xc->getEA();
2833646Srdreslin@umich.edu
2843646Srdreslin@umich.edu        if (fault == No_Fault) {
2853646Srdreslin@umich.edu            %(code)s;
2863646Srdreslin@umich.edu        }
2873646Srdreslin@umich.edu
2883646Srdreslin@umich.edu        if (fault == No_Fault) {
2893646Srdreslin@umich.edu            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
2903646Srdreslin@umich.edu                              memAccessFlags, &write_result);
2913646Srdreslin@umich.edu            if (traceData) { traceData->setData(Mem); }
2923646Srdreslin@umich.edu        }
2933646Srdreslin@umich.edu
2947525Ssteve.reinhardt@amd.com        if (fault == No_Fault) {
2953646Srdreslin@umich.edu            %(postacc_code)s;
2963646Srdreslin@umich.edu        }
2973646Srdreslin@umich.edu
2983646Srdreslin@umich.edu        if (fault == No_Fault) {
2993646Srdreslin@umich.edu            %(op_wb)s;
3003646Srdreslin@umich.edu        }
3013646Srdreslin@umich.edu
3023646Srdreslin@umich.edu        return fault;
3033646Srdreslin@umich.edu    }
304}};
305
306
307def template StoreExecute {{
308    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
309                                  Trace::InstRecord *traceData) const
310    {
311        Addr EA;
312        Fault fault = No_Fault;
313        uint64_t write_result = 0;
314
315        %(fp_enable_check)s;
316        %(op_decl)s;
317        %(op_rd)s;
318        %(ea_code)s;
319
320        if (fault == No_Fault) {
321            %(memacc_code)s;
322        }
323
324        if (fault == No_Fault) {
325            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
326                              memAccessFlags, &write_result);
327            if (traceData) { traceData->setData(Mem); }
328        }
329
330        if (fault == No_Fault) {
331            %(postacc_code)s;
332        }
333
334        if (fault == No_Fault) {
335            %(op_wb)s;
336        }
337
338        return fault;
339    }
340}};
341
342
343def template MiscMemAccExecute {{
344    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
345                                          Trace::InstRecord *traceData) const
346    {
347        Addr EA;
348        Fault fault = No_Fault;
349
350        %(fp_enable_check)s;
351        %(op_decl)s;
352        %(op_rd)s;
353        EA = xc->getEA();
354
355        if (fault == No_Fault) {
356            %(code)s;
357        }
358
359        return No_Fault;
360    }
361}};
362
363def template MiscExecute {{
364    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
365                                  Trace::InstRecord *traceData) const
366    {
367        Addr EA;
368        Fault fault = No_Fault;
369
370        %(fp_enable_check)s;
371        %(op_decl)s;
372        %(op_rd)s;
373        %(ea_code)s;
374
375        if (fault == No_Fault) {
376            %(memacc_code)s;
377        }
378
379        return No_Fault;
380    }
381}};
382
383// load instructions use Ra as dest, so check for
384// Ra == 31 to detect nops
385def template LoadNopCheckDecode {{
386 {
387     AlphaStaticInst *i = new %(class_name)s(machInst);
388     if (RA == 31) {
389         i = makeNop(i);
390     }
391     return i;
392 }
393}};
394
395
396// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
397def template LoadPrefetchCheckDecode {{
398 {
399     if (RA != 31) {
400         return new %(class_name)s(machInst);
401     }
402     else {
403         return new %(class_name)sPrefetch(machInst);
404     }
405 }
406}};
407
408
409let {{
410def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
411                  postacc_code = '', base_class = 'MemoryDisp32',
412                  decode_template = BasicDecode, exec_template_base = ''):
413    # Make sure flags are in lists (convert to lists if not).
414    mem_flags = makeList(mem_flags)
415    inst_flags = makeList(inst_flags)
416
417    # add hook to get effective addresses into execution trace output.
418    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
419
420    # generate code block objects
421    ea_cblk = CodeBlock(ea_code)
422    memacc_cblk = CodeBlock(memacc_code)
423    postacc_cblk = CodeBlock(postacc_code)
424
425    # Some CPU models execute the memory operation as an atomic unit,
426    # while others want to separate them into an effective address
427    # computation and a memory access operation.  As a result, we need
428    # to generate three StaticInst objects.  Note that the latter two
429    # are nested inside the larger "atomic" one.
430
431    # generate InstObjParams for EAComp object
432    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
433
434    # generate InstObjParams for MemAcc object
435    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
436    # in the split execution model, the MemAcc portion is responsible
437    # for the post-access code.
438    memacc_iop.postacc_code = postacc_cblk.code
439
440    # generate InstObjParams for unified execution
441    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
442    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
443
444    iop.ea_constructor = ea_cblk.constructor
445    iop.ea_code = ea_cblk.code
446    iop.memacc_constructor = memacc_cblk.constructor
447    iop.memacc_code = memacc_cblk.code
448    iop.postacc_code = postacc_cblk.code
449
450    if mem_flags:
451        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
452        iop.constructor += s
453        memacc_iop.constructor += s
454
455    # select templates
456    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
457    fullExecTemplate = eval(exec_template_base + 'Execute')
458
459    # (header_output, decoder_output, decode_block, exec_output)
460    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
461            decode_template.subst(iop),
462            EACompExecute.subst(ea_iop)
463            + memAccExecTemplate.subst(memacc_iop)
464            + fullExecTemplate.subst(iop))
465}};
466
467
468def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
469                     mem_flags = [], inst_flags = []) {{
470    (header_output, decoder_output, decode_block, exec_output) = \
471        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
472                      decode_template = LoadNopCheckDecode,
473                      exec_template_base = 'Load')
474}};
475
476
477// Note that the flags passed in apply only to the prefetch version
478def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
479                          mem_flags = [], pf_flags = [], inst_flags = []) {{
480    # declare the load instruction object and generate the decode block
481    (header_output, decoder_output, decode_block, exec_output) = \
482        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
483                      decode_template = LoadPrefetchCheckDecode,
484                      exec_template_base = 'Load')
485
486    # Declare the prefetch instruction object.
487
488    # Make sure flag args are lists so we can mess with them.
489    mem_flags = makeList(mem_flags)
490    pf_flags = makeList(pf_flags)
491    inst_flags = makeList(inst_flags)
492
493    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
494    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
495                                  'IsDataPrefetch', 'MemReadOp']
496
497    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
498        LoadStoreBase(name, Name + 'Prefetch', ea_code,
499                      'xc->prefetch(EA, memAccessFlags);',
500                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
501
502    header_output += pf_header_output
503    decoder_output += pf_decoder_output
504    exec_output += pf_exec_output
505}};
506
507
508def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
509                 mem_flags = [], inst_flags = []) {{
510    (header_output, decoder_output, decode_block, exec_output) = \
511        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
512                      exec_template_base = 'Store')
513}};
514
515
516def format StoreCond(memacc_code, postacc_code,
517                     ea_code = {{ EA = Rb + disp; }},
518                     mem_flags = [], inst_flags = []) {{
519    (header_output, decoder_output, decode_block, exec_output) = \
520        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
521                      postacc_code, exec_template_base = 'Store')
522}};
523
524
525// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
526def format MiscPrefetch(ea_code, memacc_code,
527                        mem_flags = [], inst_flags = []) {{
528    (header_output, decoder_output, decode_block, exec_output) = \
529        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
530                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
531}};
532
533
534