mem.isa revision 6181
12068SN/A// -*- mode:c++ -*- 22068SN/A 32068SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan 42068SN/A// All rights reserved. 52068SN/A// 62068SN/A// Redistribution and use in source and binary forms, with or without 72068SN/A// modification, are permitted provided that the following conditions are 82068SN/A// met: redistributions of source code must retain the above copyright 92068SN/A// notice, this list of conditions and the following disclaimer; 102068SN/A// redistributions in binary form must reproduce the above copyright 112068SN/A// notice, this list of conditions and the following disclaimer in the 122068SN/A// documentation and/or other materials provided with the distribution; 132068SN/A// neither the name of the copyright holders nor the names of its 142068SN/A// contributors may be used to endorse or promote products derived from 152068SN/A// this software without specific prior written permission. 162068SN/A// 172068SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182068SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192068SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202068SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212068SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222068SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232068SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242068SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252068SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262068SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272068SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu// 292665Ssaidi@eecs.umich.edu// Authors: Steve Reinhardt 302665Ssaidi@eecs.umich.edu// Kevin Lim 312068SN/A 322649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 332649Ssaidi@eecs.umich.edu// 342649Ssaidi@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store 352649Ssaidi@eecs.umich.edu// 362649Ssaidi@eecs.umich.edu 372068SN/Aoutput header {{ 382068SN/A /** 392068SN/A * Base class for general Alpha memory-format instructions. 402068SN/A */ 412068SN/A class Memory : public AlphaStaticInst 422068SN/A { 432068SN/A protected: 442068SN/A 452068SN/A /// Memory request flags. See mem_req_base.hh. 465736Snate@binkert.org Request::Flags memAccessFlags; 472068SN/A 482068SN/A /// Constructor 496181Sksewell@umich.edu Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 506181Sksewell@umich.edu : AlphaStaticInst(mnem, _machInst, __opClass) 512068SN/A { 522068SN/A } 532068SN/A 542068SN/A std::string 552068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 562068SN/A 576181Sksewell@umich.edu public: 586179Sksewell@umich.edu 596179Sksewell@umich.edu Request::Flags memAccFlags() { return memAccessFlags; } 602068SN/A }; 612068SN/A 622068SN/A /** 632068SN/A * Base class for memory-format instructions using a 32-bit 642068SN/A * displacement (i.e. most of them). 652068SN/A */ 662068SN/A class MemoryDisp32 : public Memory 672068SN/A { 682068SN/A protected: 692068SN/A /// Displacement for EA calculation (signed). 702068SN/A int32_t disp; 712068SN/A 722068SN/A /// Constructor. 736181Sksewell@umich.edu MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 746181Sksewell@umich.edu : Memory(mnem, _machInst, __opClass), 752068SN/A disp(MEMDISP) 762068SN/A { 772068SN/A } 782068SN/A }; 792068SN/A 802068SN/A 812068SN/A /** 822068SN/A * Base class for a few miscellaneous memory-format insts 832068SN/A * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 842068SN/A * None of these instructions has a destination register either. 852068SN/A */ 862068SN/A class MemoryNoDisp : public Memory 872068SN/A { 882068SN/A protected: 892068SN/A /// Constructor 906181Sksewell@umich.edu MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 916181Sksewell@umich.edu : Memory(mnem, _machInst, __opClass) 922068SN/A { 932068SN/A } 942068SN/A 952068SN/A std::string 962068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 972068SN/A }; 982068SN/A}}; 992068SN/A 1002068SN/A 1012068SN/Aoutput decoder {{ 1022068SN/A std::string 1032068SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1042068SN/A { 1052068SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1062068SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1072068SN/A } 1082068SN/A 1092068SN/A std::string 1102068SN/A MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1112068SN/A { 1122068SN/A return csprintf("%-10s (r%d)", mnemonic, RB); 1132068SN/A } 1142068SN/A}}; 1152068SN/A 1162068SN/Adef format LoadAddress(code) {{ 1173953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'MemoryDisp32', code) 1182068SN/A header_output = BasicDeclare.subst(iop) 1192068SN/A decoder_output = BasicConstructor.subst(iop) 1202068SN/A decode_block = BasicDecode.subst(iop) 1212068SN/A exec_output = BasicExecute.subst(iop) 1222068SN/A}}; 1232068SN/A 1242068SN/A 1252068SN/Adef template LoadStoreDeclare {{ 1262068SN/A /** 1272068SN/A * Static instruction class for "%(mnemonic)s". 1282068SN/A */ 1292068SN/A class %(class_name)s : public %(base_class)s 1302068SN/A { 1312068SN/A public: 1322068SN/A 1332068SN/A /// Constructor. 1342227SN/A %(class_name)s(ExtMachInst machInst); 1352068SN/A 1362068SN/A %(BasicExecDeclare)s 1372095SN/A 1386181Sksewell@umich.edu %(EACompDeclare)s 1396181Sksewell@umich.edu 1402095SN/A %(InitiateAccDeclare)s 1412095SN/A 1422095SN/A %(CompleteAccDeclare)s 1436179Sksewell@umich.edu 1446179Sksewell@umich.edu %(MemAccSizeDeclare)s 1452068SN/A }; 1462068SN/A}}; 1472068SN/A 1482095SN/A 1496181Sksewell@umich.edudef template EACompDeclare {{ 1506181Sksewell@umich.edu Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1516181Sksewell@umich.edu}}; 1526181Sksewell@umich.edu 1532095SN/Adef template InitiateAccDeclare {{ 1542132SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1552095SN/A}}; 1562095SN/A 1572095SN/A 1582095SN/Adef template CompleteAccDeclare {{ 1593349Sbinkertn@umich.edu Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 1602623SN/A Trace::InstRecord *) const; 1612095SN/A}}; 1622095SN/A 1636179Sksewell@umich.edudef template MemAccSizeDeclare {{ 1646179Sksewell@umich.edu int memAccSize(%(CPU_exec_context)s *xc); 1656179Sksewell@umich.edu}}; 1666179Sksewell@umich.edu 1676179Sksewell@umich.edudef template MiscMemAccSize {{ 1686179Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 1696179Sksewell@umich.edu { 1706179Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 1716179Sksewell@umich.edu return 0; 1726179Sksewell@umich.edu } 1736179Sksewell@umich.edu}}; 1746179Sksewell@umich.edu 1756179Sksewell@umich.edudef template LoadStoreMemAccSize {{ 1766179Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 1776179Sksewell@umich.edu { 1786179Sksewell@umich.edu // Return the memory access size in bytes 1796179Sksewell@umich.edu return (%(mem_acc_size)d / 8); 1806179Sksewell@umich.edu } 1816179Sksewell@umich.edu}}; 1822095SN/A 1836181Sksewell@umich.edu 1846181Sksewell@umich.edudef template LoadStoreConstructor {{ 1856181Sksewell@umich.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 1866181Sksewell@umich.edu : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 1872068SN/A { 1883953Sstever@eecs.umich.edu %(constructor)s; 1892068SN/A } 1903953Sstever@eecs.umich.edu}}; 1912068SN/A 1922068SN/Adef template EACompExecute {{ 1936181Sksewell@umich.edu Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc, 1946181Sksewell@umich.edu Trace::InstRecord *traceData) const 1952068SN/A { 1962068SN/A Addr EA; 1972132SN/A Fault fault = NoFault; 1982068SN/A 1992068SN/A %(fp_enable_check)s; 2002068SN/A %(op_decl)s; 2012068SN/A %(op_rd)s; 2023953Sstever@eecs.umich.edu %(ea_code)s; 2032068SN/A 2042090SN/A if (fault == NoFault) { 2052068SN/A %(op_wb)s; 2062068SN/A xc->setEA(EA); 2072068SN/A } 2082068SN/A 2092068SN/A return fault; 2102068SN/A } 2112068SN/A}}; 2122068SN/A 2132068SN/A 2142069SN/Adef template LoadExecute {{ 2152132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2162068SN/A Trace::InstRecord *traceData) const 2172068SN/A { 2182068SN/A Addr EA; 2192132SN/A Fault fault = NoFault; 2202068SN/A 2212068SN/A %(fp_enable_check)s; 2222068SN/A %(op_decl)s; 2232069SN/A %(op_rd)s; 2242068SN/A %(ea_code)s; 2252068SN/A 2262090SN/A if (fault == NoFault) { 2272069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2282068SN/A %(memacc_code)s; 2292068SN/A } 2302068SN/A 2312090SN/A if (fault == NoFault) { 2322069SN/A %(op_wb)s; 2332069SN/A } 2342069SN/A 2352069SN/A return fault; 2362069SN/A } 2372069SN/A}}; 2382069SN/A 2392069SN/A 2402095SN/Adef template LoadInitiateAcc {{ 2412132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 2422095SN/A Trace::InstRecord *traceData) const 2432095SN/A { 2442095SN/A Addr EA; 2452132SN/A Fault fault = NoFault; 2462095SN/A 2472095SN/A %(fp_enable_check)s; 2482095SN/A %(op_src_decl)s; 2492095SN/A %(op_rd)s; 2502095SN/A %(ea_code)s; 2512095SN/A 2522098SN/A if (fault == NoFault) { 2532095SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 2542095SN/A } 2552095SN/A 2562095SN/A return fault; 2572095SN/A } 2582095SN/A}}; 2592095SN/A 2602095SN/A 2612095SN/Adef template LoadCompleteAcc {{ 2623349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 2632095SN/A %(CPU_exec_context)s *xc, 2642095SN/A Trace::InstRecord *traceData) const 2652095SN/A { 2662132SN/A Fault fault = NoFault; 2672095SN/A 2682095SN/A %(fp_enable_check)s; 2692506SN/A %(op_decl)s; 2702095SN/A 2712623SN/A Mem = pkt->get<typeof(Mem)>(); 2722095SN/A 2732098SN/A if (fault == NoFault) { 2742095SN/A %(memacc_code)s; 2752095SN/A } 2762095SN/A 2772098SN/A if (fault == NoFault) { 2782095SN/A %(op_wb)s; 2792095SN/A } 2802095SN/A 2812095SN/A return fault; 2822095SN/A } 2832095SN/A}}; 2842095SN/A 2852095SN/A 2862069SN/Adef template StoreExecute {{ 2872132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2882069SN/A Trace::InstRecord *traceData) const 2892069SN/A { 2902069SN/A Addr EA; 2912132SN/A Fault fault = NoFault; 2924027Sstever@eecs.umich.edu 2934027Sstever@eecs.umich.edu %(fp_enable_check)s; 2944027Sstever@eecs.umich.edu %(op_decl)s; 2954027Sstever@eecs.umich.edu %(op_rd)s; 2964027Sstever@eecs.umich.edu %(ea_code)s; 2974027Sstever@eecs.umich.edu 2984027Sstever@eecs.umich.edu if (fault == NoFault) { 2994027Sstever@eecs.umich.edu %(memacc_code)s; 3004027Sstever@eecs.umich.edu } 3014027Sstever@eecs.umich.edu 3024027Sstever@eecs.umich.edu if (fault == NoFault) { 3034027Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3044027Sstever@eecs.umich.edu memAccessFlags, NULL); 3054027Sstever@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 3064027Sstever@eecs.umich.edu } 3074027Sstever@eecs.umich.edu 3084027Sstever@eecs.umich.edu if (fault == NoFault) { 3094027Sstever@eecs.umich.edu %(postacc_code)s; 3104027Sstever@eecs.umich.edu } 3114027Sstever@eecs.umich.edu 3124027Sstever@eecs.umich.edu if (fault == NoFault) { 3134027Sstever@eecs.umich.edu %(op_wb)s; 3144027Sstever@eecs.umich.edu } 3154027Sstever@eecs.umich.edu 3164027Sstever@eecs.umich.edu return fault; 3174027Sstever@eecs.umich.edu } 3184027Sstever@eecs.umich.edu}}; 3194027Sstever@eecs.umich.edu 3204027Sstever@eecs.umich.edudef template StoreCondExecute {{ 3214027Sstever@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 3224027Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 3234027Sstever@eecs.umich.edu { 3244027Sstever@eecs.umich.edu Addr EA; 3254027Sstever@eecs.umich.edu Fault fault = NoFault; 3262069SN/A uint64_t write_result = 0; 3272069SN/A 3282069SN/A %(fp_enable_check)s; 3292069SN/A %(op_decl)s; 3302069SN/A %(op_rd)s; 3312069SN/A %(ea_code)s; 3322069SN/A 3332090SN/A if (fault == NoFault) { 3342069SN/A %(memacc_code)s; 3352069SN/A } 3362069SN/A 3372090SN/A if (fault == NoFault) { 3382069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3392069SN/A memAccessFlags, &write_result); 3402069SN/A if (traceData) { traceData->setData(Mem); } 3412069SN/A } 3422069SN/A 3432090SN/A if (fault == NoFault) { 3442069SN/A %(postacc_code)s; 3452069SN/A } 3462069SN/A 3472090SN/A if (fault == NoFault) { 3482069SN/A %(op_wb)s; 3492069SN/A } 3502069SN/A 3512069SN/A return fault; 3522069SN/A } 3532069SN/A}}; 3542069SN/A 3552095SN/Adef template StoreInitiateAcc {{ 3562132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 3572095SN/A Trace::InstRecord *traceData) const 3582095SN/A { 3592095SN/A Addr EA; 3602132SN/A Fault fault = NoFault; 3612095SN/A 3622095SN/A %(fp_enable_check)s; 3632506SN/A %(op_decl)s; 3642095SN/A %(op_rd)s; 3652095SN/A %(ea_code)s; 3662095SN/A 3672098SN/A if (fault == NoFault) { 3682095SN/A %(memacc_code)s; 3692095SN/A } 3702095SN/A 3712098SN/A if (fault == NoFault) { 3722095SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3732623SN/A memAccessFlags, NULL); 3742095SN/A if (traceData) { traceData->setData(Mem); } 3752095SN/A } 3762095SN/A 3772095SN/A return fault; 3782095SN/A } 3792095SN/A}}; 3802095SN/A 3812095SN/A 3822095SN/Adef template StoreCompleteAcc {{ 3833349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 3842095SN/A %(CPU_exec_context)s *xc, 3852095SN/A Trace::InstRecord *traceData) const 3862095SN/A { 3872132SN/A Fault fault = NoFault; 3882095SN/A 3892095SN/A %(fp_enable_check)s; 3902095SN/A %(op_dest_decl)s; 3912095SN/A 3922623SN/A if (fault == NoFault) { 3932623SN/A %(postacc_code)s; 3942623SN/A } 3952623SN/A 3962623SN/A if (fault == NoFault) { 3972623SN/A %(op_wb)s; 3982623SN/A } 3992623SN/A 4002623SN/A return fault; 4012623SN/A } 4022623SN/A}}; 4032623SN/A 4042623SN/A 4052623SN/Adef template StoreCondCompleteAcc {{ 4063349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 4072623SN/A %(CPU_exec_context)s *xc, 4082623SN/A Trace::InstRecord *traceData) const 4092623SN/A { 4102623SN/A Fault fault = NoFault; 4112623SN/A 4122623SN/A %(fp_enable_check)s; 4132623SN/A %(op_dest_decl)s; 4142623SN/A 4154040Ssaidi@eecs.umich.edu uint64_t write_result = pkt->req->getExtraData(); 4162095SN/A 4172098SN/A if (fault == NoFault) { 4182095SN/A %(postacc_code)s; 4192095SN/A } 4202095SN/A 4212098SN/A if (fault == NoFault) { 4222095SN/A %(op_wb)s; 4232095SN/A } 4242095SN/A 4252095SN/A return fault; 4262095SN/A } 4272095SN/A}}; 4282095SN/A 4292069SN/A 4302069SN/Adef template MiscExecute {{ 4312132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4322068SN/A Trace::InstRecord *traceData) const 4332068SN/A { 4342068SN/A Addr EA; 4352132SN/A Fault fault = NoFault; 4362068SN/A 4372068SN/A %(fp_enable_check)s; 4382068SN/A %(op_decl)s; 4392069SN/A %(op_rd)s; 4402068SN/A %(ea_code)s; 4412068SN/A 4422090SN/A if (fault == NoFault) { 4432069SN/A %(memacc_code)s; 4442068SN/A } 4452068SN/A 4462090SN/A return NoFault; 4472068SN/A } 4482068SN/A}}; 4492068SN/A 4502095SN/Adef template MiscInitiateAcc {{ 4512132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 4522095SN/A Trace::InstRecord *traceData) const 4532095SN/A { 4542355SN/A warn("Misc instruction does not support split access method!"); 4552098SN/A return NoFault; 4562095SN/A } 4572095SN/A}}; 4582095SN/A 4592095SN/A 4602095SN/Adef template MiscCompleteAcc {{ 4613349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 4622095SN/A %(CPU_exec_context)s *xc, 4632095SN/A Trace::InstRecord *traceData) const 4642095SN/A { 4652355SN/A warn("Misc instruction does not support split access method!"); 4662110SN/A 4672098SN/A return NoFault; 4682095SN/A } 4692095SN/A}}; 4702095SN/A 4716179Sksewell@umich.edudef template MiscMemAccSize {{ 4726179Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 4736179Sksewell@umich.edu { 4746179Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 4756179Sksewell@umich.edu return 0; 4766179Sksewell@umich.edu } 4776179Sksewell@umich.edu}}; 4786179Sksewell@umich.edu 4792068SN/A// load instructions use Ra as dest, so check for 4802068SN/A// Ra == 31 to detect nops 4812068SN/Adef template LoadNopCheckDecode {{ 4822068SN/A { 4832068SN/A AlphaStaticInst *i = new %(class_name)s(machInst); 4842068SN/A if (RA == 31) { 4852068SN/A i = makeNop(i); 4862068SN/A } 4872068SN/A return i; 4882068SN/A } 4892068SN/A}}; 4902068SN/A 4912068SN/A 4922068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 4932068SN/Adef template LoadPrefetchCheckDecode {{ 4942068SN/A { 4952068SN/A if (RA != 31) { 4962068SN/A return new %(class_name)s(machInst); 4972068SN/A } 4982068SN/A else { 4992068SN/A return new %(class_name)sPrefetch(machInst); 5002068SN/A } 5012068SN/A } 5022068SN/A}}; 5032068SN/A 5042068SN/A 5052068SN/Alet {{ 5062075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 5072075SN/A postacc_code = '', base_class = 'MemoryDisp32', 5082069SN/A decode_template = BasicDecode, exec_template_base = ''): 5092075SN/A # Make sure flags are in lists (convert to lists if not). 5102075SN/A mem_flags = makeList(mem_flags) 5112075SN/A inst_flags = makeList(inst_flags) 5122068SN/A 5132068SN/A # add hook to get effective addresses into execution trace output. 5142068SN/A ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 5152068SN/A 5162068SN/A # Some CPU models execute the memory operation as an atomic unit, 5172068SN/A # while others want to separate them into an effective address 5182068SN/A # computation and a memory access operation. As a result, we need 5192068SN/A # to generate three StaticInst objects. Note that the latter two 5202068SN/A # are nested inside the larger "atomic" one. 5212068SN/A 5223953Sstever@eecs.umich.edu # Generate InstObjParams for each of the three objects. Note that 5233953Sstever@eecs.umich.edu # they differ only in the set of code objects contained (which in 5243953Sstever@eecs.umich.edu # turn affects the object's overall operand list). 5253953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, base_class, 5263953Sstever@eecs.umich.edu { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 5273953Sstever@eecs.umich.edu inst_flags) 5283953Sstever@eecs.umich.edu memacc_iop = InstObjParams(name, Name, base_class, 5293953Sstever@eecs.umich.edu { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 5303953Sstever@eecs.umich.edu inst_flags) 5312068SN/A 5322068SN/A if mem_flags: 5335736Snate@binkert.org mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 5345745Snate@binkert.org s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 5352068SN/A iop.constructor += s 5362068SN/A memacc_iop.constructor += s 5372068SN/A 5382069SN/A # select templates 5392623SN/A 5404027Sstever@eecs.umich.edu # The InitiateAcc template is the same for StoreCond templates as the 5414027Sstever@eecs.umich.edu # corresponding Store template.. 5422623SN/A StoreCondInitiateAcc = StoreInitiateAcc 5432623SN/A 5442069SN/A fullExecTemplate = eval(exec_template_base + 'Execute') 5452095SN/A initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 5462095SN/A completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 5472069SN/A 5486179Sksewell@umich.edu if (exec_template_base == 'Load' or exec_template_base == 'Store'): 5496179Sksewell@umich.edu memAccSizeTemplate = eval('LoadStoreMemAccSize') 5506179Sksewell@umich.edu else: 5516179Sksewell@umich.edu memAccSizeTemplate = eval('MiscMemAccSize') 5526179Sksewell@umich.edu 5532068SN/A # (header_output, decoder_output, decode_block, exec_output) 5543953Sstever@eecs.umich.edu return (LoadStoreDeclare.subst(iop), 5556181Sksewell@umich.edu LoadStoreConstructor.subst(iop), 5562068SN/A decode_template.subst(iop), 5576181Sksewell@umich.edu fullExecTemplate.subst(iop) 5586181Sksewell@umich.edu + EACompExecute.subst(iop) 5593953Sstever@eecs.umich.edu + initiateAccTemplate.subst(iop) 5606179Sksewell@umich.edu + completeAccTemplate.subst(iop) 5616179Sksewell@umich.edu + memAccSizeTemplate.subst(memacc_iop)) 5622068SN/A}}; 5632068SN/A 5642075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 5652075SN/A mem_flags = [], inst_flags = []) {{ 5662068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 5672075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 5682069SN/A decode_template = LoadNopCheckDecode, 5692069SN/A exec_template_base = 'Load') 5702068SN/A}}; 5712068SN/A 5722068SN/A 5732068SN/A// Note that the flags passed in apply only to the prefetch version 5742075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 5752075SN/A mem_flags = [], pf_flags = [], inst_flags = []) {{ 5762068SN/A # declare the load instruction object and generate the decode block 5772068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 5782075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 5792069SN/A decode_template = LoadPrefetchCheckDecode, 5802069SN/A exec_template_base = 'Load') 5812068SN/A 5822068SN/A # Declare the prefetch instruction object. 5832068SN/A 5842075SN/A # Make sure flag args are lists so we can mess with them. 5852075SN/A mem_flags = makeList(mem_flags) 5862075SN/A pf_flags = makeList(pf_flags) 5872075SN/A inst_flags = makeList(inst_flags) 5882075SN/A 5892075SN/A pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 5902075SN/A pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 5912075SN/A 'IsDataPrefetch', 'MemReadOp'] 5922068SN/A 5932068SN/A (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 5942069SN/A LoadStoreBase(name, Name + 'Prefetch', ea_code, 5952069SN/A 'xc->prefetch(EA, memAccessFlags);', 5962075SN/A pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 5972068SN/A 5982068SN/A header_output += pf_header_output 5992068SN/A decoder_output += pf_decoder_output 6002068SN/A exec_output += pf_exec_output 6012068SN/A}}; 6022068SN/A 6032068SN/A 6042075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6052075SN/A mem_flags = [], inst_flags = []) {{ 6062068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6072075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6082069SN/A exec_template_base = 'Store') 6092068SN/A}}; 6102068SN/A 6112068SN/A 6122075SN/Adef format StoreCond(memacc_code, postacc_code, 6132075SN/A ea_code = {{ EA = Rb + disp; }}, 6142075SN/A mem_flags = [], inst_flags = []) {{ 6152068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6162075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6172623SN/A postacc_code, exec_template_base = 'StoreCond') 6182068SN/A}}; 6192068SN/A 6202068SN/A 6212068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 6222075SN/Adef format MiscPrefetch(ea_code, memacc_code, 6232075SN/A mem_flags = [], inst_flags = []) {{ 6242068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6252075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6262069SN/A base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 6272068SN/A}}; 6282068SN/A 6292068SN/A 630