mem.isa revision 5222
12124SN/A// -*- mode:c++ -*- 22124SN/A 35222Sksewell@umich.edu// Copyright .AN) 2007 MIPS Technologies, Inc. All Rights Reserved 45222Sksewell@umich.edu 55222Sksewell@umich.edu// This software is part of the M5 simulator. 65222Sksewell@umich.edu 75222Sksewell@umich.edu// THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING 85222Sksewell@umich.edu// DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING 95222Sksewell@umich.edu// TO THESE TERMS AND CONDITIONS. 105222Sksewell@umich.edu 115222Sksewell@umich.edu// Permission is granted to use, copy, create derivative works and 125222Sksewell@umich.edu// distribute this software and such derivative works for any purpose, 135222Sksewell@umich.edu// so long as (1) the copyright notice above, this grant of permission, 145222Sksewell@umich.edu// and the disclaimer below appear in all copies and derivative works 155222Sksewell@umich.edu// made, (2) the copyright notice above is augmented as appropriate to 165222Sksewell@umich.edu// reflect the addition of any new copyrightable work in a derivative 175222Sksewell@umich.edu// work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3) 185222Sksewell@umich.edu// the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any 195222Sksewell@umich.edu// advertising or publicity pertaining to the use or distribution of 205222Sksewell@umich.edu// this software without specific, written prior authorization. 215222Sksewell@umich.edu 225222Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B MIPS MAKES NO WARRANTIES AND 235222Sksewell@umich.edu// DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR 245222Sksewell@umich.edu// OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 255222Sksewell@umich.edu// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 265222Sksewell@umich.edu// NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. 275222Sksewell@umich.edu// IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, 285222Sksewell@umich.edu// INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF 295222Sksewell@umich.edu// ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, 305222Sksewell@umich.edu// THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY 315222Sksewell@umich.edu// IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR 325222Sksewell@umich.edu// STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE 335222Sksewell@umich.edu// POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. 345222Sksewell@umich.edu 355222Sksewell@umich.edu//Authors: Steve Reinhardt 365222Sksewell@umich.edu// Korey L. Sewell 372022SN/A 382649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 392649Ssaidi@eecs.umich.edu// 402706Sksewell@umich.edu// Memory-format instructions 412649Ssaidi@eecs.umich.edu// 422649Ssaidi@eecs.umich.edu 432022SN/Aoutput header {{ 442124SN/A /** 452124SN/A * Base class for general Mips memory-format instructions. 462124SN/A */ 472124SN/A class Memory : public MipsStaticInst 482124SN/A { 492124SN/A protected: 502124SN/A 512124SN/A /// Memory request flags. See mem_req_base.hh. 522124SN/A unsigned memAccessFlags; 532124SN/A /// Pointer to EAComp object. 542124SN/A const StaticInstPtr eaCompPtr; 552124SN/A /// Pointer to MemAcc object. 562124SN/A const StaticInstPtr memAccPtr; 572239SN/A 582124SN/A /// Displacement for EA calculation (signed). 592124SN/A int32_t disp; 602124SN/A 612124SN/A /// Constructor 622124SN/A Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 632124SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 642124SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 652124SN/A : MipsStaticInst(mnem, _machInst, __opClass), 662124SN/A memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), 672742Sksewell@umich.edu disp(sext<16>(OFFSET)) 682022SN/A { 692124SN/A } 702022SN/A 712124SN/A std::string 722124SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 732022SN/A 742124SN/A public: 752124SN/A 762124SN/A const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 772124SN/A const StaticInstPtr &memAccInst() const { return memAccPtr; } 784661Sksewell@umich.edu 794661Sksewell@umich.edu unsigned memAccFlags() { return memAccessFlags; } 802124SN/A }; 812124SN/A 822742Sksewell@umich.edu /** 832742Sksewell@umich.edu * Base class for a few miscellaneous memory-format insts 842742Sksewell@umich.edu * that don't interpret the disp field 852742Sksewell@umich.edu */ 862742Sksewell@umich.edu class MemoryNoDisp : public Memory 872742Sksewell@umich.edu { 882742Sksewell@umich.edu protected: 892742Sksewell@umich.edu /// Constructor 902742Sksewell@umich.edu MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 912742Sksewell@umich.edu StaticInstPtr _eaCompPtr = nullStaticInstPtr, 922742Sksewell@umich.edu StaticInstPtr _memAccPtr = nullStaticInstPtr) 932742Sksewell@umich.edu : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 942742Sksewell@umich.edu { 952742Sksewell@umich.edu } 962742Sksewell@umich.edu 972742Sksewell@umich.edu std::string 982742Sksewell@umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 992742Sksewell@umich.edu }; 1002022SN/A}}; 1012022SN/A 1022124SN/A 1032022SN/Aoutput decoder {{ 1042124SN/A std::string 1052124SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1062124SN/A { 1072742Sksewell@umich.edu return csprintf("%-10s %c%d, %d(r%d)", mnemonic, 1082239SN/A flags[IsFloating] ? 'f' : 'r', RT, disp, RS); 1092124SN/A } 1102124SN/A 1112742Sksewell@umich.edu std::string 1122742Sksewell@umich.edu MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1132742Sksewell@umich.edu { 1142742Sksewell@umich.edu return csprintf("%-10s %c%d, r%d(r%d)", mnemonic, 1152742Sksewell@umich.edu flags[IsFloating] ? 'f' : 'r', 1162742Sksewell@umich.edu flags[IsFloating] ? FD : RD, 1172742Sksewell@umich.edu RS, RT); 1182742Sksewell@umich.edu } 1194661Sksewell@umich.edu 1204661Sksewell@umich.edu}}; 1214661Sksewell@umich.edu 1224661Sksewell@umich.eduoutput exec {{ 1234661Sksewell@umich.edu /** return data in cases where there the size of data is only 1244661Sksewell@umich.edu known in the packet 1254661Sksewell@umich.edu */ 1265222Sksewell@umich.edu uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) { 1274661Sksewell@umich.edu switch (packet->getSize()) 1284661Sksewell@umich.edu { 1295222Sksewell@umich.edu case 1: 1304661Sksewell@umich.edu return packet->get<uint8_t>(); 1314661Sksewell@umich.edu 1325222Sksewell@umich.edu case 2: 1334661Sksewell@umich.edu return packet->get<uint16_t>(); 1344661Sksewell@umich.edu 1355222Sksewell@umich.edu case 4: 1364661Sksewell@umich.edu return packet->get<uint32_t>(); 1374661Sksewell@umich.edu 1385222Sksewell@umich.edu case 8: 1394661Sksewell@umich.edu return packet->get<uint64_t>(); 1404661Sksewell@umich.edu 1414661Sksewell@umich.edu default: 1424661Sksewell@umich.edu std::cerr << "bad store data size = " << packet->getSize() << std::endl; 1434661Sksewell@umich.edu 1444661Sksewell@umich.edu assert(0); 1454661Sksewell@umich.edu return 0; 1464661Sksewell@umich.edu } 1474661Sksewell@umich.edu } 1484661Sksewell@umich.edu 1494661Sksewell@umich.edu 1502022SN/A}}; 1512022SN/A 1522124SN/Adef template LoadStoreDeclare {{ 1532124SN/A /** 1542124SN/A * Static instruction class for "%(mnemonic)s". 1552124SN/A */ 1562124SN/A class %(class_name)s : public %(base_class)s 1572124SN/A { 1582124SN/A protected: 1592124SN/A 1602124SN/A /** 1612124SN/A * "Fake" effective address computation class for "%(mnemonic)s". 1622124SN/A */ 1632124SN/A class EAComp : public %(base_class)s 1642124SN/A { 1652124SN/A public: 1662124SN/A /// Constructor 1674661Sksewell@umich.edu EAComp(ExtMachInst machInst); 1682124SN/A 1692124SN/A %(BasicExecDeclare)s 1702124SN/A }; 1712124SN/A 1722124SN/A /** 1732124SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 1742124SN/A */ 1752124SN/A class MemAcc : public %(base_class)s 1762124SN/A { 1772124SN/A public: 1782124SN/A /// Constructor 1794661Sksewell@umich.edu MemAcc(ExtMachInst machInst); 1802124SN/A 1812124SN/A %(BasicExecDeclare)s 1822124SN/A }; 1832124SN/A 1842124SN/A public: 1852124SN/A 1862124SN/A /// Constructor. 1874661Sksewell@umich.edu %(class_name)s(ExtMachInst machInst); 1882124SN/A 1892124SN/A %(BasicExecDeclare)s 1902124SN/A 1912124SN/A %(InitiateAccDeclare)s 1922124SN/A 1932124SN/A %(CompleteAccDeclare)s 1944661Sksewell@umich.edu 1954661Sksewell@umich.edu %(MemAccSizeDeclare)s 1962124SN/A }; 1972022SN/A}}; 1982022SN/A 1992124SN/A 2002124SN/Adef template InitiateAccDeclare {{ 2012132SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 2022022SN/A}}; 2032124SN/A 2042124SN/A 2052124SN/Adef template CompleteAccDeclare {{ 2064661Sksewell@umich.edu Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const; 2072124SN/A}}; 2082124SN/A 2094661Sksewell@umich.edudef template MemAccSizeDeclare {{ 2104661Sksewell@umich.edu int memAccSize(%(CPU_exec_context)s *xc); 2114661Sksewell@umich.edu}}; 2122124SN/A 2135222Sksewell@umich.edu 2145222Sksewell@umich.edudef template MiscMemAccSize {{ 2155222Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 2165222Sksewell@umich.edu { 2175222Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 2185222Sksewell@umich.edu return 0; 2195222Sksewell@umich.edu } 2205222Sksewell@umich.edu}}; 2215222Sksewell@umich.edu 2223953Sstever@eecs.umich.edudef template EACompConstructor {{ 2232124SN/A /** TODO: change op_class to AddrGenOp or something (requires 2242124SN/A * creating new member of OpClass enum in op_class.hh, updating 2252124SN/A * config files, etc.). */ 2264661Sksewell@umich.edu inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 2272124SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 2282124SN/A { 2293953Sstever@eecs.umich.edu %(constructor)s; 2302124SN/A } 2313953Sstever@eecs.umich.edu}}; 2322124SN/A 2333953Sstever@eecs.umich.edu 2343953Sstever@eecs.umich.edudef template MemAccConstructor {{ 2354661Sksewell@umich.edu inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2362124SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2372124SN/A { 2383953Sstever@eecs.umich.edu %(constructor)s; 2392124SN/A } 2403953Sstever@eecs.umich.edu}}; 2412124SN/A 2423953Sstever@eecs.umich.edu 2433953Sstever@eecs.umich.edudef template LoadStoreConstructor {{ 2444661Sksewell@umich.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2452124SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2462124SN/A new EAComp(machInst), new MemAcc(machInst)) 2472124SN/A { 2482124SN/A %(constructor)s; 2492124SN/A } 2502124SN/A}}; 2512124SN/A 2522124SN/A 2532124SN/Adef template EACompExecute {{ 2542132SN/A Fault 2552124SN/A %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2562124SN/A Trace::InstRecord *traceData) const 2572124SN/A { 2582124SN/A Addr EA; 2592132SN/A Fault fault = NoFault; 2602124SN/A 2615222Sksewell@umich.edu if (this->isFloating()) { 2625222Sksewell@umich.edu %(fp_enable_check)s; 2635222Sksewell@umich.edu 2645222Sksewell@umich.edu if(fault != NoFault) 2655222Sksewell@umich.edu return fault; 2665222Sksewell@umich.edu } 2675222Sksewell@umich.edu 2682124SN/A %(op_decl)s; 2692124SN/A %(op_rd)s; 2703953Sstever@eecs.umich.edu %(ea_code)s; 2712124SN/A 2724661Sksewell@umich.edu // NOTE: Trace Data is written using execute or completeAcc templates 2732124SN/A if (fault == NoFault) { 2742124SN/A xc->setEA(EA); 2752124SN/A } 2762124SN/A 2772124SN/A return fault; 2782124SN/A } 2792124SN/A}}; 2802124SN/A 2815222Sksewell@umich.edudef template LoadStoreFPEACompExecute {{ 2825222Sksewell@umich.edu Fault 2835222Sksewell@umich.edu %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2845222Sksewell@umich.edu Trace::InstRecord *traceData) const 2855222Sksewell@umich.edu { 2865222Sksewell@umich.edu Addr EA; 2875222Sksewell@umich.edu Fault fault = NoFault; 2885222Sksewell@umich.edu 2895222Sksewell@umich.edu %(fp_enable_check)s; 2905222Sksewell@umich.edu if(fault != NoFault) 2915222Sksewell@umich.edu return fault; 2925222Sksewell@umich.edu %(op_decl)s; 2935222Sksewell@umich.edu %(op_rd)s; 2945222Sksewell@umich.edu %(ea_code)s; 2955222Sksewell@umich.edu 2965222Sksewell@umich.edu // NOTE: Trace Data is written using execute or completeAcc templates 2975222Sksewell@umich.edu if (fault == NoFault) { 2985222Sksewell@umich.edu xc->setEA(EA); 2995222Sksewell@umich.edu } 3005222Sksewell@umich.edu 3015222Sksewell@umich.edu return fault; 3025222Sksewell@umich.edu } 3035222Sksewell@umich.edu}}; 3045222Sksewell@umich.edu 3055222Sksewell@umich.edu 3062124SN/Adef template LoadMemAccExecute {{ 3072132SN/A Fault 3082124SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3092124SN/A Trace::InstRecord *traceData) const 3102124SN/A { 3112239SN/A Addr EA; 3125222Sksewell@umich.edu 3132132SN/A Fault fault = NoFault; 3142239SN/A 3155222Sksewell@umich.edu if (this->isFloating()) { 3165222Sksewell@umich.edu %(fp_enable_check)s; 3175222Sksewell@umich.edu 3185222Sksewell@umich.edu if(fault != NoFault) 3195222Sksewell@umich.edu return fault; 3205222Sksewell@umich.edu } 3215222Sksewell@umich.edu 3222239SN/A %(op_decl)s; 3232239SN/A %(op_rd)s; 3244661Sksewell@umich.edu 3252239SN/A EA = xc->getEA(); 3262239SN/A 3274661Sksewell@umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 3282239SN/A 3294661Sksewell@umich.edu %(memacc_code)s; 3304661Sksewell@umich.edu 3314661Sksewell@umich.edu // NOTE: Write back data using execute or completeAcc templates 3322239SN/A 3332124SN/A return fault; 3342124SN/A } 3352124SN/A}}; 3362124SN/A 3372124SN/A 3382124SN/Adef template LoadExecute {{ 3392132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 3402124SN/A Trace::InstRecord *traceData) const 3412124SN/A { 3422124SN/A Addr EA; 3432132SN/A Fault fault = NoFault; 3442124SN/A 3455222Sksewell@umich.edu if (this->isFloating()) { 3465222Sksewell@umich.edu %(fp_enable_check)s; 3475222Sksewell@umich.edu 3485222Sksewell@umich.edu if(fault != NoFault) 3495222Sksewell@umich.edu return fault; 3505222Sksewell@umich.edu } 3515222Sksewell@umich.edu 3522124SN/A %(op_decl)s; 3532124SN/A %(op_rd)s; 3542124SN/A %(ea_code)s; 3552124SN/A 3562124SN/A if (fault == NoFault) { 3572124SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 3582124SN/A %(memacc_code)s; 3592124SN/A } 3602124SN/A 3612124SN/A if (fault == NoFault) { 3622124SN/A %(op_wb)s; 3632124SN/A } 3642124SN/A 3652124SN/A return fault; 3662124SN/A } 3672124SN/A}}; 3682124SN/A 3692124SN/A 3702124SN/Adef template LoadInitiateAcc {{ 3712132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 3722124SN/A Trace::InstRecord *traceData) const 3732124SN/A { 3742239SN/A Addr EA; 3752132SN/A Fault fault = NoFault; 3762239SN/A 3775222Sksewell@umich.edu if (this->isFloating()) { 3785222Sksewell@umich.edu %(fp_enable_check)s; 3795222Sksewell@umich.edu 3805222Sksewell@umich.edu if(fault != NoFault) 3815222Sksewell@umich.edu return fault; 3825222Sksewell@umich.edu } 3835222Sksewell@umich.edu 3842239SN/A %(op_src_decl)s; 3852239SN/A %(op_rd)s; 3862239SN/A %(ea_code)s; 3872239SN/A 3882239SN/A if (fault == NoFault) { 3892239SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3902239SN/A } 3912239SN/A 3922124SN/A return fault; 3932124SN/A } 3942124SN/A}}; 3952124SN/A 3962124SN/Adef template LoadCompleteAcc {{ 3974661Sksewell@umich.edu Fault %(class_name)s::completeAcc(Packet *pkt, 3982124SN/A %(CPU_exec_context)s *xc, 3992124SN/A Trace::InstRecord *traceData) const 4002124SN/A { 4012132SN/A Fault fault = NoFault; 4022239SN/A 4035222Sksewell@umich.edu if (this->isFloating()) { 4045222Sksewell@umich.edu %(fp_enable_check)s; 4055222Sksewell@umich.edu 4065222Sksewell@umich.edu if(fault != NoFault) 4075222Sksewell@umich.edu return fault; 4085222Sksewell@umich.edu } 4095222Sksewell@umich.edu 4102506SN/A %(op_decl)s; 4114661Sksewell@umich.edu %(op_rd)s; 4122239SN/A 4132935Sksewell@umich.edu Mem = pkt->get<typeof(Mem)>(); 4142239SN/A 4152239SN/A if (fault == NoFault) { 4162239SN/A %(memacc_code)s; 4172239SN/A } 4182239SN/A 4192239SN/A if (fault == NoFault) { 4202239SN/A %(op_wb)s; 4212239SN/A } 4222239SN/A 4232124SN/A return fault; 4242124SN/A } 4252124SN/A}}; 4262124SN/A 4272124SN/A 4284661Sksewell@umich.edudef template LoadStoreMemAccSize {{ 4294661Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 4304661Sksewell@umich.edu { 4314661Sksewell@umich.edu // Return the memory access size in bytes 4324661Sksewell@umich.edu return (%(mem_acc_size)d / 8); 4334661Sksewell@umich.edu } 4344661Sksewell@umich.edu}}; 4354661Sksewell@umich.edu 4362124SN/Adef template StoreMemAccExecute {{ 4372132SN/A Fault 4382124SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 4392124SN/A Trace::InstRecord *traceData) const 4402124SN/A { 4412239SN/A Addr EA; 4422132SN/A Fault fault = NoFault; 4434056Sstever@eecs.umich.edu 4444056Sstever@eecs.umich.edu %(fp_enable_check)s; 4454056Sstever@eecs.umich.edu %(op_decl)s; 4464056Sstever@eecs.umich.edu %(op_rd)s; 4474661Sksewell@umich.edu 4484056Sstever@eecs.umich.edu EA = xc->getEA(); 4494056Sstever@eecs.umich.edu 4504056Sstever@eecs.umich.edu if (fault == NoFault) { 4514056Sstever@eecs.umich.edu %(memacc_code)s; 4524056Sstever@eecs.umich.edu } 4534056Sstever@eecs.umich.edu 4544056Sstever@eecs.umich.edu if (fault == NoFault) { 4554056Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4564675Sksewell@umich.edu memAccessFlags, NULL); 4574661Sksewell@umich.edu // @NOTE: Need to Call Complete Access to Set Trace Data 4584661Sksewell@umich.edu //if (traceData) { traceData->setData(Mem); } 4594056Sstever@eecs.umich.edu } 4604056Sstever@eecs.umich.edu 4614056Sstever@eecs.umich.edu return fault; 4624056Sstever@eecs.umich.edu } 4634056Sstever@eecs.umich.edu}}; 4644056Sstever@eecs.umich.edu 4654056Sstever@eecs.umich.edudef template StoreCondMemAccExecute {{ 4664056Sstever@eecs.umich.edu Fault 4674056Sstever@eecs.umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 4684056Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 4694056Sstever@eecs.umich.edu { 4704056Sstever@eecs.umich.edu Addr EA; 4714056Sstever@eecs.umich.edu Fault fault = NoFault; 4722239SN/A uint64_t write_result = 0; 4732239SN/A 4742239SN/A %(fp_enable_check)s; 4752239SN/A %(op_decl)s; 4762239SN/A %(op_rd)s; 4772239SN/A EA = xc->getEA(); 4782239SN/A 4792239SN/A if (fault == NoFault) { 4803953Sstever@eecs.umich.edu %(memacc_code)s; 4812239SN/A } 4822239SN/A 4832239SN/A if (fault == NoFault) { 4842239SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4852239SN/A memAccessFlags, &write_result); 4862239SN/A if (traceData) { traceData->setData(Mem); } 4872239SN/A } 4882239SN/A 4892239SN/A if (fault == NoFault) { 4902239SN/A %(postacc_code)s; 4912239SN/A } 4922239SN/A 4932239SN/A if (fault == NoFault) { 4942239SN/A %(op_wb)s; 4952239SN/A } 4962239SN/A 4972124SN/A return fault; 4982124SN/A } 4992124SN/A}}; 5002124SN/A 5012124SN/Adef template StoreExecute {{ 5022132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 5032124SN/A Trace::InstRecord *traceData) const 5042124SN/A { 5052124SN/A Addr EA; 5062132SN/A Fault fault = NoFault; 5074056Sstever@eecs.umich.edu 5084056Sstever@eecs.umich.edu %(fp_enable_check)s; 5094056Sstever@eecs.umich.edu %(op_decl)s; 5104056Sstever@eecs.umich.edu %(op_rd)s; 5114056Sstever@eecs.umich.edu %(ea_code)s; 5124056Sstever@eecs.umich.edu 5134056Sstever@eecs.umich.edu if (fault == NoFault) { 5144056Sstever@eecs.umich.edu %(memacc_code)s; 5154056Sstever@eecs.umich.edu } 5164056Sstever@eecs.umich.edu 5174056Sstever@eecs.umich.edu if (fault == NoFault) { 5184056Sstever@eecs.umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 5194675Sksewell@umich.edu memAccessFlags, NULL); 5204056Sstever@eecs.umich.edu if (traceData) { traceData->setData(Mem); } 5214056Sstever@eecs.umich.edu } 5224056Sstever@eecs.umich.edu 5234056Sstever@eecs.umich.edu if (fault == NoFault) { 5244056Sstever@eecs.umich.edu %(postacc_code)s; 5254056Sstever@eecs.umich.edu } 5264056Sstever@eecs.umich.edu 5274056Sstever@eecs.umich.edu if (fault == NoFault) { 5284056Sstever@eecs.umich.edu %(op_wb)s; 5294056Sstever@eecs.umich.edu } 5304056Sstever@eecs.umich.edu 5314056Sstever@eecs.umich.edu return fault; 5324056Sstever@eecs.umich.edu } 5334056Sstever@eecs.umich.edu}}; 5344056Sstever@eecs.umich.edu 5355222Sksewell@umich.edu 5365222Sksewell@umich.edudef template StoreFPExecute {{ 5375222Sksewell@umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 5385222Sksewell@umich.edu Trace::InstRecord *traceData) const 5395222Sksewell@umich.edu { 5405222Sksewell@umich.edu Addr EA; 5415222Sksewell@umich.edu Fault fault = NoFault; 5425222Sksewell@umich.edu 5435222Sksewell@umich.edu %(fp_enable_check)s; 5445222Sksewell@umich.edu if(fault != NoFault) 5455222Sksewell@umich.edu return fault; 5465222Sksewell@umich.edu %(op_decl)s; 5475222Sksewell@umich.edu %(op_rd)s; 5485222Sksewell@umich.edu %(ea_code)s; 5495222Sksewell@umich.edu 5505222Sksewell@umich.edu if (fault == NoFault) { 5515222Sksewell@umich.edu %(memacc_code)s; 5525222Sksewell@umich.edu } 5535222Sksewell@umich.edu 5545222Sksewell@umich.edu if (fault == NoFault) { 5555222Sksewell@umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 5565222Sksewell@umich.edu memAccessFlags, NULL); 5575222Sksewell@umich.edu if (traceData) { traceData->setData(Mem); } 5585222Sksewell@umich.edu } 5595222Sksewell@umich.edu 5605222Sksewell@umich.edu if (fault == NoFault) { 5615222Sksewell@umich.edu %(postacc_code)s; 5625222Sksewell@umich.edu } 5635222Sksewell@umich.edu 5645222Sksewell@umich.edu if (fault == NoFault) { 5655222Sksewell@umich.edu %(op_wb)s; 5665222Sksewell@umich.edu } 5675222Sksewell@umich.edu 5685222Sksewell@umich.edu return fault; 5695222Sksewell@umich.edu } 5705222Sksewell@umich.edu}}; 5715222Sksewell@umich.edu 5724056Sstever@eecs.umich.edudef template StoreCondExecute {{ 5734056Sstever@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 5744056Sstever@eecs.umich.edu Trace::InstRecord *traceData) const 5754056Sstever@eecs.umich.edu { 5764056Sstever@eecs.umich.edu Addr EA; 5774056Sstever@eecs.umich.edu Fault fault = NoFault; 5782124SN/A uint64_t write_result = 0; 5792124SN/A 5802124SN/A %(fp_enable_check)s; 5812124SN/A %(op_decl)s; 5822124SN/A %(op_rd)s; 5832124SN/A %(ea_code)s; 5842124SN/A 5852124SN/A if (fault == NoFault) { 5862124SN/A %(memacc_code)s; 5872124SN/A } 5882124SN/A 5892124SN/A if (fault == NoFault) { 5902124SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 5912124SN/A memAccessFlags, &write_result); 5922124SN/A if (traceData) { traceData->setData(Mem); } 5932124SN/A } 5942124SN/A 5952124SN/A if (fault == NoFault) { 5962124SN/A %(postacc_code)s; 5972124SN/A } 5982124SN/A 5992124SN/A if (fault == NoFault) { 6002124SN/A %(op_wb)s; 6012124SN/A } 6022124SN/A 6032124SN/A return fault; 6042124SN/A } 6052124SN/A}}; 6062124SN/A 6072124SN/Adef template StoreInitiateAcc {{ 6082132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 6092124SN/A Trace::InstRecord *traceData) const 6102124SN/A { 6112239SN/A Addr EA; 6122132SN/A Fault fault = NoFault; 6132239SN/A 6142239SN/A %(fp_enable_check)s; 6152506SN/A %(op_decl)s; 6162239SN/A %(op_rd)s; 6172239SN/A %(ea_code)s; 6182239SN/A 6192239SN/A if (fault == NoFault) { 6202239SN/A %(memacc_code)s; 6212239SN/A } 6222239SN/A 6232239SN/A if (fault == NoFault) { 6242239SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 6252935Sksewell@umich.edu memAccessFlags, NULL); 6262239SN/A if (traceData) { traceData->setData(Mem); } 6272239SN/A } 6282239SN/A 6292124SN/A return fault; 6302124SN/A } 6312124SN/A}}; 6322124SN/A 6332124SN/A 6342124SN/Adef template StoreCompleteAcc {{ 6354661Sksewell@umich.edu Fault %(class_name)s::completeAcc(Packet *pkt, 6362124SN/A %(CPU_exec_context)s *xc, 6372124SN/A Trace::InstRecord *traceData) const 6382124SN/A { 6392132SN/A Fault fault = NoFault; 6402239SN/A 6412239SN/A %(fp_enable_check)s; 6422239SN/A %(op_dest_decl)s; 6432239SN/A 6442935Sksewell@umich.edu if (fault == NoFault) { 6452935Sksewell@umich.edu %(postacc_code)s; 6462935Sksewell@umich.edu } 6472935Sksewell@umich.edu 6482935Sksewell@umich.edu if (fault == NoFault) { 6492935Sksewell@umich.edu %(op_wb)s; 6504661Sksewell@umich.edu 6515222Sksewell@umich.edu if (traceData) { traceData->setData(getMemData(xc, pkt)); } 6525222Sksewell@umich.edu } 6535222Sksewell@umich.edu 6545222Sksewell@umich.edu return fault; 6555222Sksewell@umich.edu } 6565222Sksewell@umich.edu}}; 6575222Sksewell@umich.edu 6585222Sksewell@umich.edu 6595222Sksewell@umich.edudef template StoreCompleteAcc {{ 6605222Sksewell@umich.edu Fault %(class_name)s::completeAcc(Packet *pkt, 6615222Sksewell@umich.edu %(CPU_exec_context)s *xc, 6625222Sksewell@umich.edu Trace::InstRecord *traceData) const 6635222Sksewell@umich.edu { 6645222Sksewell@umich.edu Fault fault = NoFault; 6655222Sksewell@umich.edu 6665222Sksewell@umich.edu %(op_dest_decl)s; 6675222Sksewell@umich.edu 6685222Sksewell@umich.edu if (fault == NoFault) { 6695222Sksewell@umich.edu %(postacc_code)s; 6705222Sksewell@umich.edu } 6715222Sksewell@umich.edu 6725222Sksewell@umich.edu if (fault == NoFault) { 6735222Sksewell@umich.edu %(op_wb)s; 6745222Sksewell@umich.edu 6755222Sksewell@umich.edu if (traceData) { traceData->setData(getMemData(xc, pkt)); } 6762935Sksewell@umich.edu } 6772935Sksewell@umich.edu 6782935Sksewell@umich.edu return fault; 6792935Sksewell@umich.edu } 6802935Sksewell@umich.edu}}; 6812935Sksewell@umich.edu 6822935Sksewell@umich.edudef template StoreCondCompleteAcc {{ 6834661Sksewell@umich.edu Fault %(class_name)s::completeAcc(Packet *pkt, 6842935Sksewell@umich.edu %(CPU_exec_context)s *xc, 6852935Sksewell@umich.edu Trace::InstRecord *traceData) const 6862935Sksewell@umich.edu { 6872935Sksewell@umich.edu Fault fault = NoFault; 6882935Sksewell@umich.edu 6892935Sksewell@umich.edu %(fp_enable_check)s; 6902935Sksewell@umich.edu %(op_dest_decl)s; 6912935Sksewell@umich.edu 6924055Ssaidi@eecs.umich.edu uint64_t write_result = pkt->req->getExtraData(); 6932239SN/A 6942239SN/A if (fault == NoFault) { 6952239SN/A %(postacc_code)s; 6962239SN/A } 6972239SN/A 6982239SN/A if (fault == NoFault) { 6992239SN/A %(op_wb)s; 7002239SN/A } 7012239SN/A 7022124SN/A return fault; 7032124SN/A } 7042124SN/A}}; 7052124SN/A 7062686Sksewell@umich.edu 7072686Sksewell@umich.edudef template MiscMemAccExecute {{ 7082686Sksewell@umich.edu Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 7092686Sksewell@umich.edu Trace::InstRecord *traceData) const 7102686Sksewell@umich.edu { 7112686Sksewell@umich.edu Addr EA; 7122686Sksewell@umich.edu Fault fault = NoFault; 7132686Sksewell@umich.edu 7142686Sksewell@umich.edu %(fp_enable_check)s; 7152686Sksewell@umich.edu %(op_decl)s; 7162686Sksewell@umich.edu %(op_rd)s; 7172686Sksewell@umich.edu EA = xc->getEA(); 7182686Sksewell@umich.edu 7192686Sksewell@umich.edu if (fault == NoFault) { 7203953Sstever@eecs.umich.edu %(memacc_code)s; 7212686Sksewell@umich.edu } 7222686Sksewell@umich.edu 7232686Sksewell@umich.edu return NoFault; 7242686Sksewell@umich.edu } 7252686Sksewell@umich.edu}}; 7262686Sksewell@umich.edu 7272686Sksewell@umich.edudef template MiscExecute {{ 7282686Sksewell@umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 7292686Sksewell@umich.edu Trace::InstRecord *traceData) const 7302686Sksewell@umich.edu { 7312686Sksewell@umich.edu Addr EA; 7322686Sksewell@umich.edu Fault fault = NoFault; 7332686Sksewell@umich.edu 7342686Sksewell@umich.edu %(fp_enable_check)s; 7352686Sksewell@umich.edu %(op_decl)s; 7362686Sksewell@umich.edu %(op_rd)s; 7372686Sksewell@umich.edu %(ea_code)s; 7382686Sksewell@umich.edu 7392686Sksewell@umich.edu if (fault == NoFault) { 7402686Sksewell@umich.edu %(memacc_code)s; 7412686Sksewell@umich.edu } 7422686Sksewell@umich.edu 7432686Sksewell@umich.edu return NoFault; 7442686Sksewell@umich.edu } 7452686Sksewell@umich.edu}}; 7462686Sksewell@umich.edu 7472686Sksewell@umich.edudef template MiscInitiateAcc {{ 7482686Sksewell@umich.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 7492686Sksewell@umich.edu Trace::InstRecord *traceData) const 7502686Sksewell@umich.edu { 7512686Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 7522686Sksewell@umich.edu return NoFault; 7532686Sksewell@umich.edu } 7542686Sksewell@umich.edu}}; 7552686Sksewell@umich.edu 7562686Sksewell@umich.edu 7572686Sksewell@umich.edudef template MiscCompleteAcc {{ 7584661Sksewell@umich.edu Fault %(class_name)s::completeAcc(Packet *pkt, 7592686Sksewell@umich.edu %(CPU_exec_context)s *xc, 7602686Sksewell@umich.edu Trace::InstRecord *traceData) const 7612686Sksewell@umich.edu { 7622686Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 7632686Sksewell@umich.edu 7642686Sksewell@umich.edu return NoFault; 7652686Sksewell@umich.edu } 7662686Sksewell@umich.edu}}; 7672686Sksewell@umich.edu 7684661Sksewell@umich.edu 7694661Sksewell@umich.edudef template MiscMemAccSize {{ 7704661Sksewell@umich.edu int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 7714661Sksewell@umich.edu { 7724661Sksewell@umich.edu panic("Misc instruction does not support split access method!"); 7734661Sksewell@umich.edu return 0; 7744661Sksewell@umich.edu } 7754661Sksewell@umich.edu}}; 7764661Sksewell@umich.edu 7772124SN/Adef format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 7782124SN/A mem_flags = [], inst_flags = []) {{ 7792124SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7802124SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7812750Sksewell@umich.edu decode_template = ImmNopCheckDecode, 7822124SN/A exec_template_base = 'Load') 7832124SN/A}}; 7842124SN/A 7855222Sksewell@umich.edu 7862124SN/Adef format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 7872124SN/A mem_flags = [], inst_flags = []) {{ 7882124SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7892124SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7902124SN/A exec_template_base = 'Store') 7912124SN/A}}; 7922124SN/A 7932686Sksewell@umich.edudef format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 7942573SN/A mem_flags = [], inst_flags = []) {{ 7955222Sksewell@umich.edu inst_flags += ['IsIndexed'] 7962573SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7972573SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7982750Sksewell@umich.edu decode_template = ImmNopCheckDecode, 7992573SN/A exec_template_base = 'Load') 8002573SN/A}}; 8012573SN/A 8022686Sksewell@umich.edudef format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 8032573SN/A mem_flags = [], inst_flags = []) {{ 8045222Sksewell@umich.edu inst_flags += ['IsIndexed'] 8052573SN/A (header_output, decoder_output, decode_block, exec_output) = \ 8062573SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8072573SN/A exec_template_base = 'Store') 8082573SN/A}}; 8092573SN/A 8105222Sksewell@umich.edudef format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 8115222Sksewell@umich.edu mem_flags = [], inst_flags = []) {{ 8125222Sksewell@umich.edu inst_flags += ['IsIndexed', 'IsFloating'] 8135222Sksewell@umich.edu (header_output, decoder_output, decode_block, exec_output) = \ 8145222Sksewell@umich.edu LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8155222Sksewell@umich.edu decode_template = ImmNopCheckDecode, 8165222Sksewell@umich.edu exec_template_base = 'Load') 8175222Sksewell@umich.edu}}; 8185222Sksewell@umich.edu 8195222Sksewell@umich.edudef format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 8205222Sksewell@umich.edu mem_flags = [], inst_flags = []) {{ 8215222Sksewell@umich.edu inst_flags += ['IsIndexed', 'IsFloating'] 8225222Sksewell@umich.edu (header_output, decoder_output, decode_block, exec_output) = \ 8235222Sksewell@umich.edu LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8245222Sksewell@umich.edu exec_template_base = 'Store') 8255222Sksewell@umich.edu}}; 8265222Sksewell@umich.edu 8275222Sksewell@umich.edu 8282686Sksewell@umich.edudef format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, 8292686Sksewell@umich.edu mem_flags = [], inst_flags = []) {{ 8302686Sksewell@umich.edu decl_code = 'uint32_t mem_word = Mem.uw;\n' 8312686Sksewell@umich.edu decl_code += 'uint32_t unalign_addr = Rs + disp;\n' 8322686Sksewell@umich.edu decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n' 8332686Sksewell@umich.edu decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' 8342686Sksewell@umich.edu decl_code += '\tbyte_offset ^= 3;\n' 8352686Sksewell@umich.edu decl_code += '#endif\n' 8362573SN/A 8372686Sksewell@umich.edu memacc_code = decl_code + memacc_code 8382686Sksewell@umich.edu 8392686Sksewell@umich.edu (header_output, decoder_output, decode_block, exec_output) = \ 8402686Sksewell@umich.edu LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8412750Sksewell@umich.edu decode_template = ImmNopCheckDecode, 8422686Sksewell@umich.edu exec_template_base = 'Load') 8432686Sksewell@umich.edu}}; 8442686Sksewell@umich.edu 8452686Sksewell@umich.edudef format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, 8462686Sksewell@umich.edu mem_flags = [], inst_flags = []) {{ 8472686Sksewell@umich.edu decl_code = 'uint32_t mem_word = 0;\n' 8482686Sksewell@umich.edu decl_code += 'uint32_t unaligned_addr = Rs + disp;\n' 8492686Sksewell@umich.edu decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n' 8502686Sksewell@umich.edu decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' 8512686Sksewell@umich.edu decl_code += '\tbyte_offset ^= 3;\n' 8522686Sksewell@umich.edu decl_code += '#endif\n' 8532686Sksewell@umich.edu decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n' 8544661Sksewell@umich.edu #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);' 8552686Sksewell@umich.edu memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' 8562686Sksewell@umich.edu 8572686Sksewell@umich.edu (header_output, decoder_output, decode_block, exec_output) = \ 8582686Sksewell@umich.edu LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8592686Sksewell@umich.edu exec_template_base = 'Store') 8602686Sksewell@umich.edu}}; 8612686Sksewell@umich.edu 8622686Sksewell@umich.edudef format Prefetch(ea_code = {{ EA = Rs + disp; }}, 8632686Sksewell@umich.edu mem_flags = [], pf_flags = [], inst_flags = []) {{ 8642686Sksewell@umich.edu pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 8652686Sksewell@umich.edu pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 8662686Sksewell@umich.edu 'IsDataPrefetch', 'MemReadOp'] 8672686Sksewell@umich.edu 8682686Sksewell@umich.edu (header_output, decoder_output, decode_block, exec_output) = \ 8692686Sksewell@umich.edu LoadStoreBase(name, Name, ea_code, 8702686Sksewell@umich.edu 'xc->prefetch(EA, memAccessFlags);', 8712686Sksewell@umich.edu pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 8722686Sksewell@umich.edu 8732686Sksewell@umich.edu}}; 8742686Sksewell@umich.edu 8752686Sksewell@umich.edudef format StoreCond(memacc_code, postacc_code, 8762686Sksewell@umich.edu ea_code = {{ EA = Rs + disp; }}, 8772495SN/A mem_flags = [], inst_flags = []) {{ 8782495SN/A (header_output, decoder_output, decode_block, exec_output) = \ 8792495SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 8802935Sksewell@umich.edu postacc_code, exec_template_base = 'StoreCond') 8812495SN/A}}; 882