mem.isa revision 4056
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. 462068SN/A unsigned 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), 572068SN/A memAccessFlags(0), 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; } 682068SN/A }; 692068SN/A 702068SN/A /** 712068SN/A * Base class for memory-format instructions using a 32-bit 722068SN/A * displacement (i.e. most of them). 732068SN/A */ 742068SN/A class MemoryDisp32 : public Memory 752068SN/A { 762068SN/A protected: 772068SN/A /// Displacement for EA calculation (signed). 782068SN/A int32_t disp; 792068SN/A 802068SN/A /// Constructor. 812227SN/A MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 822107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 832107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 842068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 852068SN/A disp(MEMDISP) 862068SN/A { 872068SN/A } 882068SN/A }; 892068SN/A 902068SN/A 912068SN/A /** 922068SN/A * Base class for a few miscellaneous memory-format insts 932068SN/A * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 942068SN/A * None of these instructions has a destination register either. 952068SN/A */ 962068SN/A class MemoryNoDisp : public Memory 972068SN/A { 982068SN/A protected: 992068SN/A /// Constructor 1002227SN/A MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1012107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1022107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 1032068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 1042068SN/A { 1052068SN/A } 1062068SN/A 1072068SN/A std::string 1082068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1092068SN/A }; 1102068SN/A}}; 1112068SN/A 1122068SN/A 1132068SN/Aoutput decoder {{ 1142068SN/A std::string 1152068SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1162068SN/A { 1172068SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1182068SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1192068SN/A } 1202068SN/A 1212068SN/A std::string 1222068SN/A MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1232068SN/A { 1242068SN/A return csprintf("%-10s (r%d)", mnemonic, RB); 1252068SN/A } 1262068SN/A}}; 1272068SN/A 1282068SN/Adef format LoadAddress(code) {{ 1293953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'MemoryDisp32', code) 1302068SN/A header_output = BasicDeclare.subst(iop) 1312068SN/A decoder_output = BasicConstructor.subst(iop) 1322068SN/A decode_block = BasicDecode.subst(iop) 1332068SN/A exec_output = BasicExecute.subst(iop) 1342068SN/A}}; 1352068SN/A 1362068SN/A 1372068SN/Adef template LoadStoreDeclare {{ 1382068SN/A /** 1392068SN/A * Static instruction class for "%(mnemonic)s". 1402068SN/A */ 1412068SN/A class %(class_name)s : public %(base_class)s 1422068SN/A { 1432068SN/A protected: 1442068SN/A 1452068SN/A /** 1462068SN/A * "Fake" effective address computation class for "%(mnemonic)s". 1472068SN/A */ 1482068SN/A class EAComp : public %(base_class)s 1492068SN/A { 1502068SN/A public: 1512068SN/A /// Constructor 1522227SN/A EAComp(ExtMachInst machInst); 1532068SN/A 1542068SN/A %(BasicExecDeclare)s 1552068SN/A }; 1562068SN/A 1572068SN/A /** 1582068SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 1592068SN/A */ 1602068SN/A class MemAcc : public %(base_class)s 1612068SN/A { 1622068SN/A public: 1632068SN/A /// Constructor 1642227SN/A MemAcc(ExtMachInst machInst); 1652068SN/A 1662068SN/A %(BasicExecDeclare)s 1672068SN/A }; 1682068SN/A 1692068SN/A public: 1702068SN/A 1712068SN/A /// Constructor. 1722227SN/A %(class_name)s(ExtMachInst machInst); 1732068SN/A 1742068SN/A %(BasicExecDeclare)s 1752095SN/A 1762095SN/A %(InitiateAccDeclare)s 1772095SN/A 1782095SN/A %(CompleteAccDeclare)s 1792068SN/A }; 1802068SN/A}}; 1812068SN/A 1822095SN/A 1832095SN/Adef template InitiateAccDeclare {{ 1842132SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1852095SN/A}}; 1862095SN/A 1872095SN/A 1882095SN/Adef template CompleteAccDeclare {{ 1893349Sbinkertn@umich.edu Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 1902623SN/A Trace::InstRecord *) const; 1912095SN/A}}; 1922095SN/A 1932095SN/A 1943953Sstever@eecs.umich.edudef template EACompConstructor {{ 1952068SN/A /** TODO: change op_class to AddrGenOp or something (requires 1962068SN/A * creating new member of OpClass enum in op_class.hh, updating 1972068SN/A * config files, etc.). */ 1982227SN/A inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 1992068SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 2002068SN/A { 2013953Sstever@eecs.umich.edu %(constructor)s; 2022068SN/A } 2033953Sstever@eecs.umich.edu}}; 2042068SN/A 2053953Sstever@eecs.umich.edu 2063953Sstever@eecs.umich.edudef template MemAccConstructor {{ 2072227SN/A inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2082068SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2092068SN/A { 2103953Sstever@eecs.umich.edu %(constructor)s; 2112068SN/A } 2123953Sstever@eecs.umich.edu}}; 2132068SN/A 2143953Sstever@eecs.umich.edu 2153953Sstever@eecs.umich.edudef template LoadStoreConstructor {{ 2162227SN/A inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2172068SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2182068SN/A new EAComp(machInst), new MemAcc(machInst)) 2192068SN/A { 2202068SN/A %(constructor)s; 2212068SN/A } 2222068SN/A}}; 2232068SN/A 2242068SN/A 2252068SN/Adef template EACompExecute {{ 2262132SN/A Fault 2272068SN/A %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2282068SN/A Trace::InstRecord *traceData) const 2292068SN/A { 2302068SN/A Addr EA; 2312132SN/A Fault fault = NoFault; 2322068SN/A 2332068SN/A %(fp_enable_check)s; 2342068SN/A %(op_decl)s; 2352068SN/A %(op_rd)s; 2363953Sstever@eecs.umich.edu %(ea_code)s; 2372068SN/A 2382090SN/A if (fault == NoFault) { 2392068SN/A %(op_wb)s; 2402068SN/A xc->setEA(EA); 2412068SN/A } 2422068SN/A 2432068SN/A return fault; 2442068SN/A } 2452068SN/A}}; 2462068SN/A 2472069SN/Adef template LoadMemAccExecute {{ 2482132SN/A Fault 2492068SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2502068SN/A Trace::InstRecord *traceData) const 2512068SN/A { 2522068SN/A Addr EA; 2532132SN/A Fault fault = NoFault; 2542068SN/A 2552068SN/A %(fp_enable_check)s; 2562068SN/A %(op_decl)s; 2572069SN/A %(op_rd)s; 2582068SN/A EA = xc->getEA(); 2592068SN/A 2602090SN/A if (fault == NoFault) { 2612069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2623953Sstever@eecs.umich.edu %(memacc_code)s; 2632068SN/A } 2642068SN/A 2652090SN/A if (fault == NoFault) { 2662069SN/A %(op_wb)s; 2672068SN/A } 2682068SN/A 2692068SN/A return fault; 2702068SN/A } 2712068SN/A}}; 2722068SN/A 2732068SN/A 2742069SN/Adef template LoadExecute {{ 2752132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2762068SN/A Trace::InstRecord *traceData) const 2772068SN/A { 2782068SN/A Addr EA; 2792132SN/A Fault fault = NoFault; 2802068SN/A 2812068SN/A %(fp_enable_check)s; 2822068SN/A %(op_decl)s; 2832069SN/A %(op_rd)s; 2842068SN/A %(ea_code)s; 2852068SN/A 2862090SN/A if (fault == NoFault) { 2872069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2882068SN/A %(memacc_code)s; 2892068SN/A } 2902068SN/A 2912090SN/A if (fault == NoFault) { 2922069SN/A %(op_wb)s; 2932069SN/A } 2942069SN/A 2952069SN/A return fault; 2962069SN/A } 2972069SN/A}}; 2982069SN/A 2992069SN/A 3002095SN/Adef template LoadInitiateAcc {{ 3012132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 3022095SN/A Trace::InstRecord *traceData) const 3032095SN/A { 3042095SN/A Addr EA; 3052132SN/A Fault fault = NoFault; 3062095SN/A 3072095SN/A %(fp_enable_check)s; 3082095SN/A %(op_src_decl)s; 3092095SN/A %(op_rd)s; 3102095SN/A %(ea_code)s; 3112095SN/A 3122098SN/A if (fault == NoFault) { 3132095SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3142095SN/A } 3152095SN/A 3162095SN/A return fault; 3172095SN/A } 3182095SN/A}}; 3192095SN/A 3202095SN/A 3212095SN/Adef template LoadCompleteAcc {{ 3223349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 3232095SN/A %(CPU_exec_context)s *xc, 3242095SN/A Trace::InstRecord *traceData) const 3252095SN/A { 3262132SN/A Fault fault = NoFault; 3272095SN/A 3282095SN/A %(fp_enable_check)s; 3292506SN/A %(op_decl)s; 3302095SN/A 3312623SN/A Mem = pkt->get<typeof(Mem)>(); 3322095SN/A 3332098SN/A if (fault == NoFault) { 3342095SN/A %(memacc_code)s; 3352095SN/A } 3362095SN/A 3372098SN/A if (fault == NoFault) { 3382095SN/A %(op_wb)s; 3392095SN/A } 3402095SN/A 3412095SN/A return fault; 3422095SN/A } 3432095SN/A}}; 3442095SN/A 3452095SN/A 3462069SN/Adef template StoreMemAccExecute {{ 3472132SN/A Fault 3482069SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3492069SN/A Trace::InstRecord *traceData) const 3502069SN/A { 3512069SN/A Addr EA; 3522132SN/A Fault fault = NoFault; 3534027Sstever@eecs.umich.edu 3544027Sstever@eecs.umich.edu %(fp_enable_check)s; 3554027Sstever@eecs.umich.edu %(op_decl)s; 3564027Sstever@eecs.umich.edu %(op_rd)s; 3574027Sstever@eecs.umich.edu EA = xc->getEA(); 3584027Sstever@eecs.umich.edu 3594027Sstever@eecs.umich.edu if (fault == NoFault) { 3604027Sstever@eecs.umich.edu %(memacc_code)s; 3614027Sstever@eecs.umich.edu } 3624027Sstever@eecs.umich.edu 3634027Sstever@eecs.umich.edu if (fault == NoFault) { 3644027Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3654027Sstever@eecs.umich.edu memAccessFlags, NULL); 3664027Sstever@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 3674027Sstever@eecs.umich.edu } 3684027Sstever@eecs.umich.edu 3694027Sstever@eecs.umich.edu if (fault == NoFault) { 3704027Sstever@eecs.umich.edu %(postacc_code)s; 3714027Sstever@eecs.umich.edu } 3724027Sstever@eecs.umich.edu 3734027Sstever@eecs.umich.edu if (fault == NoFault) { 3744027Sstever@eecs.umich.edu %(op_wb)s; 3754027Sstever@eecs.umich.edu } 3764027Sstever@eecs.umich.edu 3774027Sstever@eecs.umich.edu return fault; 3784027Sstever@eecs.umich.edu } 3794027Sstever@eecs.umich.edu}}; 3804027Sstever@eecs.umich.edu 3814027Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{ 3824027Sstever@eecs.umich.edu Fault 3834027Sstever@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3844027Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 3854027Sstever@eecs.umich.edu { 3864027Sstever@eecs.umich.edu Addr EA; 3874027Sstever@eecs.umich.edu Fault fault = NoFault; 3882069SN/A uint64_t write_result = 0; 3892069SN/A 3902069SN/A %(fp_enable_check)s; 3912069SN/A %(op_decl)s; 3922069SN/A %(op_rd)s; 3932069SN/A EA = xc->getEA(); 3942069SN/A 3952090SN/A if (fault == NoFault) { 3963953Sstever@eecs.umich.edu %(memacc_code)s; 3972069SN/A } 3982069SN/A 3992090SN/A if (fault == NoFault) { 4002069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4012069SN/A memAccessFlags, &write_result); 4022069SN/A if (traceData) { traceData->setData(Mem); } 4032068SN/A } 4042068SN/A 4052090SN/A if (fault == NoFault) { 4062068SN/A %(postacc_code)s; 4072068SN/A } 4082068SN/A 4092090SN/A if (fault == NoFault) { 4102069SN/A %(op_wb)s; 4112068SN/A } 4122068SN/A 4132068SN/A return fault; 4142068SN/A } 4152068SN/A}}; 4162068SN/A 4172068SN/A 4182069SN/Adef template StoreExecute {{ 4192132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4202069SN/A Trace::InstRecord *traceData) const 4212069SN/A { 4222069SN/A Addr EA; 4232132SN/A Fault fault = NoFault; 4244027Sstever@eecs.umich.edu 4254027Sstever@eecs.umich.edu %(fp_enable_check)s; 4264027Sstever@eecs.umich.edu %(op_decl)s; 4274027Sstever@eecs.umich.edu %(op_rd)s; 4284027Sstever@eecs.umich.edu %(ea_code)s; 4294027Sstever@eecs.umich.edu 4304027Sstever@eecs.umich.edu if (fault == NoFault) { 4314027Sstever@eecs.umich.edu %(memacc_code)s; 4324027Sstever@eecs.umich.edu } 4334027Sstever@eecs.umich.edu 4344027Sstever@eecs.umich.edu if (fault == NoFault) { 4354027Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4364027Sstever@eecs.umich.edu memAccessFlags, NULL); 4374027Sstever@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 4384027Sstever@eecs.umich.edu } 4394027Sstever@eecs.umich.edu 4404027Sstever@eecs.umich.edu if (fault == NoFault) { 4414027Sstever@eecs.umich.edu %(postacc_code)s; 4424027Sstever@eecs.umich.edu } 4434027Sstever@eecs.umich.edu 4444027Sstever@eecs.umich.edu if (fault == NoFault) { 4454027Sstever@eecs.umich.edu %(op_wb)s; 4464027Sstever@eecs.umich.edu } 4474027Sstever@eecs.umich.edu 4484027Sstever@eecs.umich.edu return fault; 4494027Sstever@eecs.umich.edu } 4504027Sstever@eecs.umich.edu}}; 4514027Sstever@eecs.umich.edu 4524027Sstever@eecs.umich.edudef template StoreCondExecute {{ 4534027Sstever@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 4544027Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 4554027Sstever@eecs.umich.edu { 4564027Sstever@eecs.umich.edu Addr EA; 4574027Sstever@eecs.umich.edu Fault fault = NoFault; 4582069SN/A uint64_t write_result = 0; 4592069SN/A 4602069SN/A %(fp_enable_check)s; 4612069SN/A %(op_decl)s; 4622069SN/A %(op_rd)s; 4632069SN/A %(ea_code)s; 4642069SN/A 4652090SN/A if (fault == NoFault) { 4662069SN/A %(memacc_code)s; 4672069SN/A } 4682069SN/A 4692090SN/A if (fault == NoFault) { 4702069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4712069SN/A memAccessFlags, &write_result); 4722069SN/A if (traceData) { traceData->setData(Mem); } 4732069SN/A } 4742069SN/A 4752090SN/A if (fault == NoFault) { 4762069SN/A %(postacc_code)s; 4772069SN/A } 4782069SN/A 4792090SN/A if (fault == NoFault) { 4802069SN/A %(op_wb)s; 4812069SN/A } 4822069SN/A 4832069SN/A return fault; 4842069SN/A } 4852069SN/A}}; 4862069SN/A 4872095SN/Adef template StoreInitiateAcc {{ 4882132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 4892095SN/A Trace::InstRecord *traceData) const 4902095SN/A { 4912095SN/A Addr EA; 4922132SN/A Fault fault = NoFault; 4932095SN/A 4942095SN/A %(fp_enable_check)s; 4952506SN/A %(op_decl)s; 4962095SN/A %(op_rd)s; 4972095SN/A %(ea_code)s; 4982095SN/A 4992098SN/A if (fault == NoFault) { 5002095SN/A %(memacc_code)s; 5012095SN/A } 5022095SN/A 5032098SN/A if (fault == NoFault) { 5042095SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 5052623SN/A memAccessFlags, NULL); 5062095SN/A if (traceData) { traceData->setData(Mem); } 5072095SN/A } 5082095SN/A 5092095SN/A return fault; 5102095SN/A } 5112095SN/A}}; 5122095SN/A 5132095SN/A 5142095SN/Adef template StoreCompleteAcc {{ 5153349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 5162095SN/A %(CPU_exec_context)s *xc, 5172095SN/A Trace::InstRecord *traceData) const 5182095SN/A { 5192132SN/A Fault fault = NoFault; 5202095SN/A 5212095SN/A %(fp_enable_check)s; 5222095SN/A %(op_dest_decl)s; 5232095SN/A 5242623SN/A if (fault == NoFault) { 5252623SN/A %(postacc_code)s; 5262623SN/A } 5272623SN/A 5282623SN/A if (fault == NoFault) { 5292623SN/A %(op_wb)s; 5302623SN/A } 5312623SN/A 5322623SN/A return fault; 5332623SN/A } 5342623SN/A}}; 5352623SN/A 5362623SN/A 5372623SN/Adef template StoreCondCompleteAcc {{ 5383349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 5392623SN/A %(CPU_exec_context)s *xc, 5402623SN/A Trace::InstRecord *traceData) const 5412623SN/A { 5422623SN/A Fault fault = NoFault; 5432623SN/A 5442623SN/A %(fp_enable_check)s; 5452623SN/A %(op_dest_decl)s; 5462623SN/A 5474040Ssaidi@eecs.umich.edu uint64_t write_result = pkt->req->getExtraData(); 5482095SN/A 5492098SN/A if (fault == NoFault) { 5502095SN/A %(postacc_code)s; 5512095SN/A } 5522095SN/A 5532098SN/A if (fault == NoFault) { 5542095SN/A %(op_wb)s; 5552095SN/A } 5562095SN/A 5572095SN/A return fault; 5582095SN/A } 5592095SN/A}}; 5602095SN/A 5612069SN/A 5622069SN/Adef template MiscMemAccExecute {{ 5632132SN/A Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 5642069SN/A Trace::InstRecord *traceData) const 5652069SN/A { 5662069SN/A Addr EA; 5672132SN/A Fault fault = NoFault; 5682069SN/A 5692069SN/A %(fp_enable_check)s; 5702069SN/A %(op_decl)s; 5712069SN/A %(op_rd)s; 5722069SN/A EA = xc->getEA(); 5732069SN/A 5742090SN/A if (fault == NoFault) { 5753953Sstever@eecs.umich.edu %(memacc_code)s; 5762069SN/A } 5772069SN/A 5782090SN/A return NoFault; 5792069SN/A } 5802069SN/A}}; 5812069SN/A 5822069SN/Adef template MiscExecute {{ 5832132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 5842068SN/A Trace::InstRecord *traceData) const 5852068SN/A { 5862068SN/A Addr EA; 5872132SN/A Fault fault = NoFault; 5882068SN/A 5892068SN/A %(fp_enable_check)s; 5902068SN/A %(op_decl)s; 5912069SN/A %(op_rd)s; 5922068SN/A %(ea_code)s; 5932068SN/A 5942090SN/A if (fault == NoFault) { 5952069SN/A %(memacc_code)s; 5962068SN/A } 5972068SN/A 5982090SN/A return NoFault; 5992068SN/A } 6002068SN/A}}; 6012068SN/A 6022095SN/Adef template MiscInitiateAcc {{ 6032132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 6042095SN/A Trace::InstRecord *traceData) const 6052095SN/A { 6062355SN/A warn("Misc instruction does not support split access method!"); 6072098SN/A return NoFault; 6082095SN/A } 6092095SN/A}}; 6102095SN/A 6112095SN/A 6122095SN/Adef template MiscCompleteAcc {{ 6133349Sbinkertn@umich.edu Fault %(class_name)s::completeAcc(PacketPtr pkt, 6142095SN/A %(CPU_exec_context)s *xc, 6152095SN/A Trace::InstRecord *traceData) const 6162095SN/A { 6172355SN/A warn("Misc instruction does not support split access method!"); 6182110SN/A 6192098SN/A return NoFault; 6202095SN/A } 6212095SN/A}}; 6222095SN/A 6232068SN/A// load instructions use Ra as dest, so check for 6242068SN/A// Ra == 31 to detect nops 6252068SN/Adef template LoadNopCheckDecode {{ 6262068SN/A { 6272068SN/A AlphaStaticInst *i = new %(class_name)s(machInst); 6282068SN/A if (RA == 31) { 6292068SN/A i = makeNop(i); 6302068SN/A } 6312068SN/A return i; 6322068SN/A } 6332068SN/A}}; 6342068SN/A 6352068SN/A 6362068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 6372068SN/Adef template LoadPrefetchCheckDecode {{ 6382068SN/A { 6392068SN/A if (RA != 31) { 6402068SN/A return new %(class_name)s(machInst); 6412068SN/A } 6422068SN/A else { 6432068SN/A return new %(class_name)sPrefetch(machInst); 6442068SN/A } 6452068SN/A } 6462068SN/A}}; 6472068SN/A 6482068SN/A 6492068SN/Alet {{ 6502075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6512075SN/A postacc_code = '', base_class = 'MemoryDisp32', 6522069SN/A decode_template = BasicDecode, exec_template_base = ''): 6532075SN/A # Make sure flags are in lists (convert to lists if not). 6542075SN/A mem_flags = makeList(mem_flags) 6552075SN/A inst_flags = makeList(inst_flags) 6562068SN/A 6572068SN/A # add hook to get effective addresses into execution trace output. 6582068SN/A ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 6592068SN/A 6602068SN/A # Some CPU models execute the memory operation as an atomic unit, 6612068SN/A # while others want to separate them into an effective address 6622068SN/A # computation and a memory access operation. As a result, we need 6632068SN/A # to generate three StaticInst objects. Note that the latter two 6642068SN/A # are nested inside the larger "atomic" one. 6652068SN/A 6663953Sstever@eecs.umich.edu # Generate InstObjParams for each of the three objects. Note that 6673953Sstever@eecs.umich.edu # they differ only in the set of code objects contained (which in 6683953Sstever@eecs.umich.edu # turn affects the object's overall operand list). 6693953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, base_class, 6703953Sstever@eecs.umich.edu { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 6713953Sstever@eecs.umich.edu inst_flags) 6723953Sstever@eecs.umich.edu ea_iop = InstObjParams(name, Name, base_class, 6733953Sstever@eecs.umich.edu { 'ea_code':ea_code }, 6743953Sstever@eecs.umich.edu inst_flags) 6753953Sstever@eecs.umich.edu memacc_iop = InstObjParams(name, Name, base_class, 6763953Sstever@eecs.umich.edu { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 6773953Sstever@eecs.umich.edu inst_flags) 6782068SN/A 6792068SN/A if mem_flags: 6802068SN/A s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 6812068SN/A iop.constructor += s 6822068SN/A memacc_iop.constructor += s 6832068SN/A 6842069SN/A # select templates 6852623SN/A 6864027Sstever@eecs.umich.edu # The InitiateAcc template is the same for StoreCond templates as the 6874027Sstever@eecs.umich.edu # corresponding Store template.. 6882623SN/A StoreCondInitiateAcc = StoreInitiateAcc 6892623SN/A 6902069SN/A memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 6912069SN/A fullExecTemplate = eval(exec_template_base + 'Execute') 6922095SN/A initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 6932095SN/A completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 6942069SN/A 6952068SN/A # (header_output, decoder_output, decode_block, exec_output) 6963953Sstever@eecs.umich.edu return (LoadStoreDeclare.subst(iop), 6973953Sstever@eecs.umich.edu EACompConstructor.subst(ea_iop) 6983953Sstever@eecs.umich.edu + MemAccConstructor.subst(memacc_iop) 6993953Sstever@eecs.umich.edu + LoadStoreConstructor.subst(iop), 7002068SN/A decode_template.subst(iop), 7012068SN/A EACompExecute.subst(ea_iop) 7022069SN/A + memAccExecTemplate.subst(memacc_iop) 7032095SN/A + fullExecTemplate.subst(iop) 7043953Sstever@eecs.umich.edu + initiateAccTemplate.subst(iop) 7053953Sstever@eecs.umich.edu + completeAccTemplate.subst(iop)) 7062068SN/A}}; 7072068SN/A 7082075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7092075SN/A mem_flags = [], inst_flags = []) {{ 7102068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7112075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7122069SN/A decode_template = LoadNopCheckDecode, 7132069SN/A exec_template_base = 'Load') 7142068SN/A}}; 7152068SN/A 7162068SN/A 7172068SN/A// Note that the flags passed in apply only to the prefetch version 7182075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7192075SN/A mem_flags = [], pf_flags = [], inst_flags = []) {{ 7202068SN/A # declare the load instruction object and generate the decode block 7212068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7222075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7232069SN/A decode_template = LoadPrefetchCheckDecode, 7242069SN/A exec_template_base = 'Load') 7252068SN/A 7262068SN/A # Declare the prefetch instruction object. 7272068SN/A 7282075SN/A # Make sure flag args are lists so we can mess with them. 7292075SN/A mem_flags = makeList(mem_flags) 7302075SN/A pf_flags = makeList(pf_flags) 7312075SN/A inst_flags = makeList(inst_flags) 7322075SN/A 7332075SN/A pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 7342075SN/A pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 7352075SN/A 'IsDataPrefetch', 'MemReadOp'] 7362068SN/A 7372068SN/A (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 7382069SN/A LoadStoreBase(name, Name + 'Prefetch', ea_code, 7392069SN/A 'xc->prefetch(EA, memAccessFlags);', 7402075SN/A pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 7412068SN/A 7422068SN/A header_output += pf_header_output 7432068SN/A decoder_output += pf_decoder_output 7442068SN/A exec_output += pf_exec_output 7452068SN/A}}; 7462068SN/A 7472068SN/A 7482075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7492075SN/A mem_flags = [], inst_flags = []) {{ 7502068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7512075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7522069SN/A exec_template_base = 'Store') 7532068SN/A}}; 7542068SN/A 7552068SN/A 7562075SN/Adef format StoreCond(memacc_code, postacc_code, 7572075SN/A ea_code = {{ EA = Rb + disp; }}, 7582075SN/A mem_flags = [], inst_flags = []) {{ 7592068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7602075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7612623SN/A postacc_code, exec_template_base = 'StoreCond') 7622068SN/A}}; 7632068SN/A 7642068SN/A 7652068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 7662075SN/Adef format MiscPrefetch(ea_code, memacc_code, 7672075SN/A mem_flags = [], inst_flags = []) {{ 7682068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7692075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7702069SN/A base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 7712068SN/A}}; 7722068SN/A 7732068SN/A 774