mem.isa revision 6179
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 /// Pointer to EAComp object. 482107SN/A const StaticInstPtr eaCompPtr; 492068SN/A /// Pointer to MemAcc object. 502107SN/A const StaticInstPtr memAccPtr; 512068SN/A 522068SN/A /// Constructor 532227SN/A Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 542107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 552107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 562068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 575736Snate@binkert.org eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 582068SN/A { 592068SN/A } 602068SN/A 612068SN/A std::string 622068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 632068SN/A 642068SN/A public: 652068SN/A 662107SN/A const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 672107SN/A const StaticInstPtr &memAccInst() const { return memAccPtr; } 686179Sksewell@umich.edu 696179Sksewell@umich.edu Request::Flags memAccFlags() { return memAccessFlags; } 702068SN/A }; 712068SN/A 722068SN/A /** 732068SN/A * Base class for memory-format instructions using a 32-bit 742068SN/A * displacement (i.e. most of them). 752068SN/A */ 762068SN/A class MemoryDisp32 : public Memory 772068SN/A { 782068SN/A protected: 792068SN/A /// Displacement for EA calculation (signed). 802068SN/A int32_t disp; 812068SN/A 822068SN/A /// Constructor. 832227SN/A MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 842107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 852107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 862068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 872068SN/A disp(MEMDISP) 882068SN/A { 892068SN/A } 902068SN/A }; 912068SN/A 922068SN/A 932068SN/A /** 942068SN/A * Base class for a few miscellaneous memory-format insts 952068SN/A * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 962068SN/A * None of these instructions has a destination register either. 972068SN/A */ 982068SN/A class MemoryNoDisp : public Memory 992068SN/A { 1002068SN/A protected: 1012068SN/A /// Constructor 1022227SN/A MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1032107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1042107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 1052068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 1062068SN/A { 1072068SN/A } 1082068SN/A 1092068SN/A std::string 1102068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1112068SN/A }; 1122068SN/A}}; 1132068SN/A 1142068SN/A 1152068SN/Aoutput decoder {{ 1162068SN/A std::string 1172068SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1182068SN/A { 1192068SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1202068SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1212068SN/A } 1222068SN/A 1232068SN/A std::string 1242068SN/A MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1252068SN/A { 1262068SN/A return csprintf("%-10s (r%d)", mnemonic, RB); 1272068SN/A } 1282068SN/A}}; 1292068SN/A 1302068SN/Adef format LoadAddress(code) {{ 1313953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'MemoryDisp32', code) 1322068SN/A header_output = BasicDeclare.subst(iop) 1332068SN/A decoder_output = BasicConstructor.subst(iop) 1342068SN/A decode_block = BasicDecode.subst(iop) 1352068SN/A exec_output = BasicExecute.subst(iop) 1362068SN/A}}; 1372068SN/A 1382068SN/A 1392068SN/Adef template LoadStoreDeclare {{ 1402068SN/A /** 1412068SN/A * Static instruction class for "%(mnemonic)s". 1422068SN/A */ 1432068SN/A class %(class_name)s : public %(base_class)s 1442068SN/A { 1452068SN/A protected: 1462068SN/A 1472068SN/A /** 1482068SN/A * "Fake" effective address computation class for "%(mnemonic)s". 1492068SN/A */ 1502068SN/A class EAComp : public %(base_class)s 1512068SN/A { 1522068SN/A public: 1532068SN/A /// Constructor 1542227SN/A EAComp(ExtMachInst machInst); 1552068SN/A 1562068SN/A %(BasicExecDeclare)s 1572068SN/A }; 1582068SN/A 1592068SN/A /** 1602068SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 1612068SN/A */ 1622068SN/A class MemAcc : public %(base_class)s 1632068SN/A { 1642068SN/A public: 1652068SN/A /// Constructor 1662227SN/A MemAcc(ExtMachInst machInst); 1672068SN/A 1682068SN/A %(BasicExecDeclare)s 1692068SN/A }; 1702068SN/A 1712068SN/A public: 1722068SN/A 1732068SN/A /// Constructor. 1742227SN/A %(class_name)s(ExtMachInst machInst); 1752068SN/A 1762068SN/A %(BasicExecDeclare)s 1772095SN/A 1782095SN/A %(InitiateAccDeclare)s 1792095SN/A 1802095SN/A %(CompleteAccDeclare)s 1816179Sksewell@umich.edu 1826179Sksewell@umich.edu %(MemAccSizeDeclare)s 1832068SN/A }; 1842068SN/A}}; 1852068SN/A 1862095SN/A 1872095SN/Adef template InitiateAccDeclare {{ 1882132SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1892095SN/A}}; 1902095SN/A 1912095SN/A 1922095SN/Adef template CompleteAccDeclare {{ 1933349Sbinkertn@umich.edu Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 1942623SN/A Trace::InstRecord *) const; 1952095SN/A}}; 1962095SN/A 1976179Sksewell@umich.edudef template MemAccSizeDeclare {{ 1986179Sksewell@umich.edu int memAccSize(%(CPU_exec_context)s *xc); 1996179Sksewell@umich.edu}}; 2006179Sksewell@umich.edu 2016179Sksewell@umich.edudef template MiscMemAccSize {{ 2026179Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 2036179Sksewell@umich.edu { 2046179Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 2056179Sksewell@umich.edu return 0; 2066179Sksewell@umich.edu } 2076179Sksewell@umich.edu}}; 2086179Sksewell@umich.edu 2096179Sksewell@umich.edudef template LoadStoreMemAccSize {{ 2106179Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 2116179Sksewell@umich.edu { 2126179Sksewell@umich.edu // Return the memory access size in bytes 2136179Sksewell@umich.edu return (%(mem_acc_size)d / 8); 2146179Sksewell@umich.edu } 2156179Sksewell@umich.edu}}; 2162095SN/A 2173953Sstever@eecs.umich.edudef template EACompConstructor {{ 2182068SN/A /** TODO: change op_class to AddrGenOp or something (requires 2192068SN/A * creating new member of OpClass enum in op_class.hh, updating 2202068SN/A * config files, etc.). */ 2212227SN/A inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 2222068SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 2232068SN/A { 2243953Sstever@eecs.umich.edu %(constructor)s; 2252068SN/A } 2263953Sstever@eecs.umich.edu}}; 2272068SN/A 2283953Sstever@eecs.umich.edu 2293953Sstever@eecs.umich.edudef template MemAccConstructor {{ 2302227SN/A inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2312068SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2322068SN/A { 2333953Sstever@eecs.umich.edu %(constructor)s; 2342068SN/A } 2353953Sstever@eecs.umich.edu}}; 2362068SN/A 2373953Sstever@eecs.umich.edu 2383953Sstever@eecs.umich.edudef template LoadStoreConstructor {{ 2392227SN/A inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2402068SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2412068SN/A new EAComp(machInst), new MemAcc(machInst)) 2422068SN/A { 2432068SN/A %(constructor)s; 2442068SN/A } 2452068SN/A}}; 2462068SN/A 2472068SN/A 2482068SN/Adef template EACompExecute {{ 2492132SN/A Fault 2502068SN/A %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2512068SN/A Trace::InstRecord *traceData) const 2522068SN/A { 2532068SN/A Addr EA; 2542132SN/A Fault fault = NoFault; 2552068SN/A 2562068SN/A %(fp_enable_check)s; 2572068SN/A %(op_decl)s; 2582068SN/A %(op_rd)s; 2593953Sstever@eecs.umich.edu %(ea_code)s; 2602068SN/A 2612090SN/A if (fault == NoFault) { 2622068SN/A %(op_wb)s; 2632068SN/A xc->setEA(EA); 2642068SN/A } 2652068SN/A 2662068SN/A return fault; 2672068SN/A } 2682068SN/A}}; 2692068SN/A 2702069SN/Adef template LoadMemAccExecute {{ 2712132SN/A Fault 2722068SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2732068SN/A Trace::InstRecord *traceData) const 2742068SN/A { 2752068SN/A Addr EA; 2762132SN/A Fault fault = NoFault; 2772068SN/A 2782068SN/A %(fp_enable_check)s; 2792068SN/A %(op_decl)s; 2802069SN/A %(op_rd)s; 2812068SN/A EA = xc->getEA(); 2822068SN/A 2832090SN/A if (fault == NoFault) { 2842069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2853953Sstever@eecs.umich.edu %(memacc_code)s; 2862068SN/A } 2872068SN/A 2882090SN/A if (fault == NoFault) { 2892069SN/A %(op_wb)s; 2902068SN/A } 2912068SN/A 2922068SN/A return fault; 2932068SN/A } 2942068SN/A}}; 2952068SN/A 2962068SN/A 2972069SN/Adef template LoadExecute {{ 2982132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2992068SN/A Trace::InstRecord *traceData) const 3002068SN/A { 3012068SN/A Addr EA; 3022132SN/A Fault fault = NoFault; 3032068SN/A 3042068SN/A %(fp_enable_check)s; 3052068SN/A %(op_decl)s; 3062069SN/A %(op_rd)s; 3072068SN/A %(ea_code)s; 3082068SN/A 3092090SN/A if (fault == NoFault) { 3102069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 3112068SN/A %(memacc_code)s; 3122068SN/A } 3132068SN/A 3142090SN/A if (fault == NoFault) { 3152069SN/A %(op_wb)s; 3162069SN/A } 3172069SN/A 3182069SN/A return fault; 3192069SN/A } 3202069SN/A}}; 3212069SN/A 3222069SN/A 3232095SN/Adef template LoadInitiateAcc {{ 3242132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 3252095SN/A Trace::InstRecord *traceData) const 3262095SN/A { 3272095SN/A Addr EA; 3282132SN/A Fault fault = NoFault; 3292095SN/A 3302095SN/A %(fp_enable_check)s; 3312095SN/A %(op_src_decl)s; 3322095SN/A %(op_rd)s; 3332095SN/A %(ea_code)s; 3342095SN/A 3352098SN/A if (fault == NoFault) { 3362095SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3372095SN/A } 3382095SN/A 3392095SN/A return fault; 3402095SN/A } 3412095SN/A}}; 3422095SN/A 3432095SN/A 3442095SN/Adef template LoadCompleteAcc {{ 3453349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 3462095SN/A %(CPU_exec_context)s *xc, 3472095SN/A Trace::InstRecord *traceData) const 3482095SN/A { 3492132SN/A Fault fault = NoFault; 3502095SN/A 3512095SN/A %(fp_enable_check)s; 3522506SN/A %(op_decl)s; 3532095SN/A 3542623SN/A Mem = pkt->get<typeof(Mem)>(); 3552095SN/A 3562098SN/A if (fault == NoFault) { 3572095SN/A %(memacc_code)s; 3582095SN/A } 3592095SN/A 3602098SN/A if (fault == NoFault) { 3612095SN/A %(op_wb)s; 3622095SN/A } 3632095SN/A 3642095SN/A return fault; 3652095SN/A } 3662095SN/A}}; 3672095SN/A 3682095SN/A 3692069SN/Adef template StoreMemAccExecute {{ 3702132SN/A Fault 3712069SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3722069SN/A Trace::InstRecord *traceData) const 3732069SN/A { 3742069SN/A Addr EA; 3752132SN/A Fault fault = NoFault; 3764027Sstever@eecs.umich.edu 3774027Sstever@eecs.umich.edu %(fp_enable_check)s; 3784027Sstever@eecs.umich.edu %(op_decl)s; 3794027Sstever@eecs.umich.edu %(op_rd)s; 3804027Sstever@eecs.umich.edu EA = xc->getEA(); 3814027Sstever@eecs.umich.edu 3824027Sstever@eecs.umich.edu if (fault == NoFault) { 3834027Sstever@eecs.umich.edu %(memacc_code)s; 3844027Sstever@eecs.umich.edu } 3854027Sstever@eecs.umich.edu 3864027Sstever@eecs.umich.edu if (fault == NoFault) { 3874027Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3884027Sstever@eecs.umich.edu memAccessFlags, NULL); 3894027Sstever@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 3904027Sstever@eecs.umich.edu } 3914027Sstever@eecs.umich.edu 3924027Sstever@eecs.umich.edu if (fault == NoFault) { 3934027Sstever@eecs.umich.edu %(postacc_code)s; 3944027Sstever@eecs.umich.edu } 3954027Sstever@eecs.umich.edu 3964027Sstever@eecs.umich.edu if (fault == NoFault) { 3974027Sstever@eecs.umich.edu %(op_wb)s; 3984027Sstever@eecs.umich.edu } 3994027Sstever@eecs.umich.edu 4004027Sstever@eecs.umich.edu return fault; 4014027Sstever@eecs.umich.edu } 4024027Sstever@eecs.umich.edu}}; 4034027Sstever@eecs.umich.edu 4044027Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{ 4054027Sstever@eecs.umich.edu Fault 4064027Sstever@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 4074027Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 4084027Sstever@eecs.umich.edu { 4094027Sstever@eecs.umich.edu Addr EA; 4104027Sstever@eecs.umich.edu Fault fault = NoFault; 4112069SN/A uint64_t write_result = 0; 4122069SN/A 4132069SN/A %(fp_enable_check)s; 4142069SN/A %(op_decl)s; 4152069SN/A %(op_rd)s; 4162069SN/A EA = xc->getEA(); 4172069SN/A 4182090SN/A if (fault == NoFault) { 4193953Sstever@eecs.umich.edu %(memacc_code)s; 4202069SN/A } 4212069SN/A 4222090SN/A if (fault == NoFault) { 4232069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4242069SN/A memAccessFlags, &write_result); 4252069SN/A if (traceData) { traceData->setData(Mem); } 4262068SN/A } 4272068SN/A 4282090SN/A if (fault == NoFault) { 4292068SN/A %(postacc_code)s; 4302068SN/A } 4312068SN/A 4322090SN/A if (fault == NoFault) { 4332069SN/A %(op_wb)s; 4342068SN/A } 4352068SN/A 4362068SN/A return fault; 4372068SN/A } 4382068SN/A}}; 4392068SN/A 4402068SN/A 4412069SN/Adef template StoreExecute {{ 4422132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4432069SN/A Trace::InstRecord *traceData) const 4442069SN/A { 4452069SN/A Addr EA; 4462132SN/A Fault fault = NoFault; 4474027Sstever@eecs.umich.edu 4484027Sstever@eecs.umich.edu %(fp_enable_check)s; 4494027Sstever@eecs.umich.edu %(op_decl)s; 4504027Sstever@eecs.umich.edu %(op_rd)s; 4514027Sstever@eecs.umich.edu %(ea_code)s; 4524027Sstever@eecs.umich.edu 4534027Sstever@eecs.umich.edu if (fault == NoFault) { 4544027Sstever@eecs.umich.edu %(memacc_code)s; 4554027Sstever@eecs.umich.edu } 4564027Sstever@eecs.umich.edu 4574027Sstever@eecs.umich.edu if (fault == NoFault) { 4584027Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4594027Sstever@eecs.umich.edu memAccessFlags, NULL); 4604027Sstever@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 4614027Sstever@eecs.umich.edu } 4624027Sstever@eecs.umich.edu 4634027Sstever@eecs.umich.edu if (fault == NoFault) { 4644027Sstever@eecs.umich.edu %(postacc_code)s; 4654027Sstever@eecs.umich.edu } 4664027Sstever@eecs.umich.edu 4674027Sstever@eecs.umich.edu if (fault == NoFault) { 4684027Sstever@eecs.umich.edu %(op_wb)s; 4694027Sstever@eecs.umich.edu } 4704027Sstever@eecs.umich.edu 4714027Sstever@eecs.umich.edu return fault; 4724027Sstever@eecs.umich.edu } 4734027Sstever@eecs.umich.edu}}; 4744027Sstever@eecs.umich.edu 4754027Sstever@eecs.umich.edudef template StoreCondExecute {{ 4764027Sstever@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4774027Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 4784027Sstever@eecs.umich.edu { 4794027Sstever@eecs.umich.edu Addr EA; 4804027Sstever@eecs.umich.edu Fault fault = NoFault; 4812069SN/A uint64_t write_result = 0; 4822069SN/A 4832069SN/A %(fp_enable_check)s; 4842069SN/A %(op_decl)s; 4852069SN/A %(op_rd)s; 4862069SN/A %(ea_code)s; 4872069SN/A 4882090SN/A if (fault == NoFault) { 4892069SN/A %(memacc_code)s; 4902069SN/A } 4912069SN/A 4922090SN/A if (fault == NoFault) { 4932069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4942069SN/A memAccessFlags, &write_result); 4952069SN/A if (traceData) { traceData->setData(Mem); } 4962069SN/A } 4972069SN/A 4982090SN/A if (fault == NoFault) { 4992069SN/A %(postacc_code)s; 5002069SN/A } 5012069SN/A 5022090SN/A if (fault == NoFault) { 5032069SN/A %(op_wb)s; 5042069SN/A } 5052069SN/A 5062069SN/A return fault; 5072069SN/A } 5082069SN/A}}; 5092069SN/A 5102095SN/Adef template StoreInitiateAcc {{ 5112132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 5122095SN/A Trace::InstRecord *traceData) const 5132095SN/A { 5142095SN/A Addr EA; 5152132SN/A Fault fault = NoFault; 5162095SN/A 5172095SN/A %(fp_enable_check)s; 5182506SN/A %(op_decl)s; 5192095SN/A %(op_rd)s; 5202095SN/A %(ea_code)s; 5212095SN/A 5222098SN/A if (fault == NoFault) { 5232095SN/A %(memacc_code)s; 5242095SN/A } 5252095SN/A 5262098SN/A if (fault == NoFault) { 5272095SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 5282623SN/A memAccessFlags, NULL); 5292095SN/A if (traceData) { traceData->setData(Mem); } 5302095SN/A } 5312095SN/A 5322095SN/A return fault; 5332095SN/A } 5342095SN/A}}; 5352095SN/A 5362095SN/A 5372095SN/Adef template StoreCompleteAcc {{ 5383349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 5392095SN/A %(CPU_exec_context)s *xc, 5402095SN/A Trace::InstRecord *traceData) const 5412095SN/A { 5422132SN/A Fault fault = NoFault; 5432095SN/A 5442095SN/A %(fp_enable_check)s; 5452095SN/A %(op_dest_decl)s; 5462095SN/A 5472623SN/A if (fault == NoFault) { 5482623SN/A %(postacc_code)s; 5492623SN/A } 5502623SN/A 5512623SN/A if (fault == NoFault) { 5522623SN/A %(op_wb)s; 5532623SN/A } 5542623SN/A 5552623SN/A return fault; 5562623SN/A } 5572623SN/A}}; 5582623SN/A 5592623SN/A 5602623SN/Adef template StoreCondCompleteAcc {{ 5613349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 5622623SN/A %(CPU_exec_context)s *xc, 5632623SN/A Trace::InstRecord *traceData) const 5642623SN/A { 5652623SN/A Fault fault = NoFault; 5662623SN/A 5672623SN/A %(fp_enable_check)s; 5682623SN/A %(op_dest_decl)s; 5692623SN/A 5704040Ssaidi@eecs.umich.edu uint64_t write_result = pkt->req->getExtraData(); 5712095SN/A 5722098SN/A if (fault == NoFault) { 5732095SN/A %(postacc_code)s; 5742095SN/A } 5752095SN/A 5762098SN/A if (fault == NoFault) { 5772095SN/A %(op_wb)s; 5782095SN/A } 5792095SN/A 5802095SN/A return fault; 5812095SN/A } 5822095SN/A}}; 5832095SN/A 5842069SN/A 5852069SN/Adef template MiscMemAccExecute {{ 5862132SN/A Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 5872069SN/A Trace::InstRecord *traceData) const 5882069SN/A { 5892069SN/A Addr EA; 5902132SN/A Fault fault = NoFault; 5912069SN/A 5922069SN/A %(fp_enable_check)s; 5932069SN/A %(op_decl)s; 5942069SN/A %(op_rd)s; 5952069SN/A EA = xc->getEA(); 5962069SN/A 5972090SN/A if (fault == NoFault) { 5983953Sstever@eecs.umich.edu %(memacc_code)s; 5992069SN/A } 6002069SN/A 6012090SN/A return NoFault; 6022069SN/A } 6032069SN/A}}; 6042069SN/A 6052069SN/Adef template MiscExecute {{ 6062132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 6072068SN/A Trace::InstRecord *traceData) const 6082068SN/A { 6092068SN/A Addr EA; 6102132SN/A Fault fault = NoFault; 6112068SN/A 6122068SN/A %(fp_enable_check)s; 6132068SN/A %(op_decl)s; 6142069SN/A %(op_rd)s; 6152068SN/A %(ea_code)s; 6162068SN/A 6172090SN/A if (fault == NoFault) { 6182069SN/A %(memacc_code)s; 6192068SN/A } 6202068SN/A 6212090SN/A return NoFault; 6222068SN/A } 6232068SN/A}}; 6242068SN/A 6252095SN/Adef template MiscInitiateAcc {{ 6262132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 6272095SN/A Trace::InstRecord *traceData) const 6282095SN/A { 6292355SN/A warn("Misc instruction does not support split access method!"); 6302098SN/A return NoFault; 6312095SN/A } 6322095SN/A}}; 6332095SN/A 6342095SN/A 6352095SN/Adef template MiscCompleteAcc {{ 6363349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 6372095SN/A %(CPU_exec_context)s *xc, 6382095SN/A Trace::InstRecord *traceData) const 6392095SN/A { 6402355SN/A warn("Misc instruction does not support split access method!"); 6412110SN/A 6422098SN/A return NoFault; 6432095SN/A } 6442095SN/A}}; 6452095SN/A 6466179Sksewell@umich.edudef template MiscMemAccSize {{ 6476179Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 6486179Sksewell@umich.edu { 6496179Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 6506179Sksewell@umich.edu return 0; 6516179Sksewell@umich.edu } 6526179Sksewell@umich.edu}}; 6536179Sksewell@umich.edu 6542068SN/A// load instructions use Ra as dest, so check for 6552068SN/A// Ra == 31 to detect nops 6562068SN/Adef template LoadNopCheckDecode {{ 6572068SN/A { 6582068SN/A AlphaStaticInst *i = new %(class_name)s(machInst); 6592068SN/A if (RA == 31) { 6602068SN/A i = makeNop(i); 6612068SN/A } 6622068SN/A return i; 6632068SN/A } 6642068SN/A}}; 6652068SN/A 6662068SN/A 6672068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 6682068SN/Adef template LoadPrefetchCheckDecode {{ 6692068SN/A { 6702068SN/A if (RA != 31) { 6712068SN/A return new %(class_name)s(machInst); 6722068SN/A } 6732068SN/A else { 6742068SN/A return new %(class_name)sPrefetch(machInst); 6752068SN/A } 6762068SN/A } 6772068SN/A}}; 6782068SN/A 6792068SN/A 6802068SN/Alet {{ 6812075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6822075SN/A postacc_code = '', base_class = 'MemoryDisp32', 6832069SN/A decode_template = BasicDecode, exec_template_base = ''): 6842075SN/A # Make sure flags are in lists (convert to lists if not). 6852075SN/A mem_flags = makeList(mem_flags) 6862075SN/A inst_flags = makeList(inst_flags) 6872068SN/A 6882068SN/A # add hook to get effective addresses into execution trace output. 6892068SN/A ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 6902068SN/A 6912068SN/A # Some CPU models execute the memory operation as an atomic unit, 6922068SN/A # while others want to separate them into an effective address 6932068SN/A # computation and a memory access operation. As a result, we need 6942068SN/A # to generate three StaticInst objects. Note that the latter two 6952068SN/A # are nested inside the larger "atomic" one. 6962068SN/A 6973953Sstever@eecs.umich.edu # Generate InstObjParams for each of the three objects. Note that 6983953Sstever@eecs.umich.edu # they differ only in the set of code objects contained (which in 6993953Sstever@eecs.umich.edu # turn affects the object's overall operand list). 7003953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, base_class, 7013953Sstever@eecs.umich.edu { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 7023953Sstever@eecs.umich.edu inst_flags) 7033953Sstever@eecs.umich.edu ea_iop = InstObjParams(name, Name, base_class, 7043953Sstever@eecs.umich.edu { 'ea_code':ea_code }, 7053953Sstever@eecs.umich.edu inst_flags) 7063953Sstever@eecs.umich.edu memacc_iop = InstObjParams(name, Name, base_class, 7073953Sstever@eecs.umich.edu { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 7083953Sstever@eecs.umich.edu inst_flags) 7092068SN/A 7102068SN/A if mem_flags: 7115736Snate@binkert.org mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 7125745Snate@binkert.org s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 7132068SN/A iop.constructor += s 7142068SN/A memacc_iop.constructor += s 7152068SN/A 7162069SN/A # select templates 7172623SN/A 7184027Sstever@eecs.umich.edu # The InitiateAcc template is the same for StoreCond templates as the 7194027Sstever@eecs.umich.edu # corresponding Store template.. 7202623SN/A StoreCondInitiateAcc = StoreInitiateAcc 7212623SN/A 7222069SN/A memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 7232069SN/A fullExecTemplate = eval(exec_template_base + 'Execute') 7242095SN/A initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 7252095SN/A completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 7262069SN/A 7276179Sksewell@umich.edu if (exec_template_base == 'Load' or exec_template_base == 'Store'): 7286179Sksewell@umich.edu memAccSizeTemplate = eval('LoadStoreMemAccSize') 7296179Sksewell@umich.edu else: 7306179Sksewell@umich.edu memAccSizeTemplate = eval('MiscMemAccSize') 7316179Sksewell@umich.edu 7322068SN/A # (header_output, decoder_output, decode_block, exec_output) 7333953Sstever@eecs.umich.edu return (LoadStoreDeclare.subst(iop), 7343953Sstever@eecs.umich.edu EACompConstructor.subst(ea_iop) 7353953Sstever@eecs.umich.edu + MemAccConstructor.subst(memacc_iop) 7363953Sstever@eecs.umich.edu + LoadStoreConstructor.subst(iop), 7372068SN/A decode_template.subst(iop), 7382068SN/A EACompExecute.subst(ea_iop) 7392069SN/A + memAccExecTemplate.subst(memacc_iop) 7402095SN/A + fullExecTemplate.subst(iop) 7413953Sstever@eecs.umich.edu + initiateAccTemplate.subst(iop) 7426179Sksewell@umich.edu + completeAccTemplate.subst(iop) 7436179Sksewell@umich.edu + memAccSizeTemplate.subst(memacc_iop)) 7442068SN/A}}; 7452068SN/A 7462075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7472075SN/A mem_flags = [], inst_flags = []) {{ 7482068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7492075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7502069SN/A decode_template = LoadNopCheckDecode, 7512069SN/A exec_template_base = 'Load') 7522068SN/A}}; 7532068SN/A 7542068SN/A 7552068SN/A// Note that the flags passed in apply only to the prefetch version 7562075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7572075SN/A mem_flags = [], pf_flags = [], inst_flags = []) {{ 7582068SN/A # declare the load instruction object and generate the decode block 7592068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7602075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7612069SN/A decode_template = LoadPrefetchCheckDecode, 7622069SN/A exec_template_base = 'Load') 7632068SN/A 7642068SN/A # Declare the prefetch instruction object. 7652068SN/A 7662075SN/A # Make sure flag args are lists so we can mess with them. 7672075SN/A mem_flags = makeList(mem_flags) 7682075SN/A pf_flags = makeList(pf_flags) 7692075SN/A inst_flags = makeList(inst_flags) 7702075SN/A 7712075SN/A pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 7722075SN/A pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 7732075SN/A 'IsDataPrefetch', 'MemReadOp'] 7742068SN/A 7752068SN/A (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 7762069SN/A LoadStoreBase(name, Name + 'Prefetch', ea_code, 7772069SN/A 'xc->prefetch(EA, memAccessFlags);', 7782075SN/A pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 7792068SN/A 7802068SN/A header_output += pf_header_output 7812068SN/A decoder_output += pf_decoder_output 7822068SN/A exec_output += pf_exec_output 7832068SN/A}}; 7842068SN/A 7852068SN/A 7862075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7872075SN/A mem_flags = [], inst_flags = []) {{ 7882068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7892075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7902069SN/A exec_template_base = 'Store') 7912068SN/A}}; 7922068SN/A 7932068SN/A 7942075SN/Adef format StoreCond(memacc_code, postacc_code, 7952075SN/A ea_code = {{ EA = Rb + disp; }}, 7962075SN/A mem_flags = [], inst_flags = []) {{ 7972068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7982075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7992623SN/A postacc_code, exec_template_base = 'StoreCond') 8002068SN/A}}; 8012068SN/A 8022068SN/A 8032068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 8042075SN/Adef format MiscPrefetch(ea_code, memacc_code, 8052075SN/A mem_flags = [], inst_flags = []) {{ 8062068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 8072075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8082069SN/A base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 8092068SN/A}}; 8102068SN/A 8112068SN/A 812